summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--httemplate/edit/elements/edit.html2
-rw-r--r--httemplate/edit/msg_template.html3
-rw-r--r--httemplate/elements/ckeditor/plugins/blockprotect/plugin.js128
-rw-r--r--httemplate/elements/htmlarea.html24
4 files changed, 145 insertions, 12 deletions
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index 08408297b..ed677d7ab 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -328,7 +328,7 @@ Example:
% qw( hashref agent_virt agent_null agent_null_right ),#*-table
% qw( formatted_value ), #fixed
% qw( country ), #select-country
-% qw( width height ), #htmlarea
+% qw( width height config ), #htmlarea
% qw( alt_format ), #select-cust_location
% qw( classnum ), # select-inventory_item
% ;
diff --git a/httemplate/edit/msg_template.html b/httemplate/edit/msg_template.html
index fa375a0aa..06cac440e 100644
--- a/httemplate/edit/msg_template.html
+++ b/httemplate/edit/msg_template.html
@@ -67,7 +67,8 @@ if ( $curuser->access_right('Edit global templates')
{ field => 'subject', size=>60, },
{ field => 'body',
type => 'htmlarea',
- width => 763
+ width => 763,
+ config=> { extraPlugins => 'blockprotect' },
},
;
} else { #readonly
diff --git a/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js b/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js
new file mode 100644
index 000000000..61c993a9f
--- /dev/null
+++ b/httemplate/elements/ckeditor/plugins/blockprotect/plugin.js
@@ -0,0 +1,128 @@
+/**
+ * The "blockprotect" plugin. Adapted from the "placeholder" plugin.
+ */
+
+(function() {
+ var delim_o = '{';
+ var delim_c = '}';
+
+ var create_block = function(content) {
+ // fix nbsp's
+ content = content.replace(/ /gi, ' ');
+ // escape the content
+ var el = document.createElement('SPAN');
+ // IE8 compat
+ if( typeof(el.textContent) != 'undefined' ) {
+ el.textContent = content;
+ } else if( typeof(el.innerText) != 'undefined' ) {
+ el.innerText = content;
+ }
+ el.setAttribute('class', 'cke_blockprotect');
+ return el.outerHTML;
+ };
+ var block_writeHtml = function( element ) {
+ // to unescape the element contents, write it out as HTML,
+ // stick that into a SPAN element, and then extract the text
+ // content of that.
+ var inner_writer = new CKEDITOR.htmlParser.basicWriter;
+ element.writeChildrenHtml(inner_writer);
+
+ var el = document.createElement('SPAN');
+ el.innerHTML = inner_writer.getHtml();
+ if( typeof(el.textContent) != 'undefined' ) {
+ return el.textContent;
+ } else if( typeof(el.innerText) != 'undefined' ) {
+ return el.innerText;
+ }
+ };
+ var to_protected_html = function(data) {
+ var depth = 0;
+ var chunk = '';
+ var out = '';
+ var p = 0; // position in the string
+ while( 1 ) {
+ // find the next delimiter of either kind
+ var i = data.indexOf(delim_o, p);
+ var j = data.indexOf(delim_c, p);
+ if (i == -1 && j == -1) {
+ // then there are no more delimiters
+ break;
+ } else if ((i < j || j == -1) && i != -1) {
+ // next delimiter is an open
+ // push everything from current position to
+ // the delimiter
+ if ( i > p ) chunk += data.substr(p, i - p);
+ p = i + 1;
+ if ( depth == 0 ) {
+ // start of a protected block
+ out += chunk;
+ chunk = '';
+ }
+ chunk += delim_o;
+ depth++;
+ } else if ((j < i || i == -1) && j != -1) {
+ // next delimiter is a close
+ if ( j > p ) chunk += data.substr(p, j - p);
+ p = j + 1;
+ depth--;
+ chunk += delim_c
+ if ( depth == 0 ) {
+ // end of a protected block
+ out += create_block(chunk);
+ chunk = '';
+ } else if ( depth < 0 ) {
+ depth = 0;
+ }
+ } else {
+ // can't happen
+ }
+ }
+ // append any text after the last delimiter
+ if ( depth ) {
+ out += create_block(data.substr(p));
+ } else {
+ out += data.substr(p);
+ }
+ return out;
+ };
+
+ CKEDITOR.plugins.add( 'blockprotect', {
+ afterInit: function( editor ) {
+ CKEDITOR.addCss( '.cke_blockprotect' +
+ '{' +
+ 'background-color: #ffff88;' +
+ ( CKEDITOR.env.gecko ? 'cursor: default;' : '' ) +
+ '}'
+ );
+
+ // keep these from getting stripped out
+ editor.filter.allow('span(cke_blockprotect)',
+ 'blockprotect', true);
+
+ // add filter at the front of toHtml
+ editor.on( 'toHtml',
+ function( evt ) {
+ evt.data.dataValue =
+ to_protected_html(evt.data.dataValue);
+ return evt;
+ },
+ this, null, 0
+ );
+
+ editor.dataProcessor.htmlFilter.addRules({
+ elements: {
+ span: function( element ) {
+ if ( element.className = 'cke_blockprotect' ) {
+ // defeat HTML escaping
+ var content = block_writeHtml(element);
+ element.writeHtml = function(writer, filter) {
+ writer.text(content);
+ }
+ }
+ } // span function
+ } // elements
+ });
+ }
+ }); // plugins.add
+}) ();
+
diff --git a/httemplate/elements/htmlarea.html b/httemplate/elements/htmlarea.html
index f9dcffd3f..c98993d40 100644
--- a/httemplate/elements/htmlarea.html
+++ b/httemplate/elements/htmlarea.html
@@ -6,6 +6,7 @@ Example:
'field' => 'fieldname',
'curr_value' => $curr_value,
'height' => 800,
+ 'config' => { extraPlugins => 'blockprotect' },
);
</%doc>
@@ -19,21 +20,24 @@ Example:
<SCRIPT TYPE="text/javascript">
- CKEDITOR.replace('<% $opt{'field'} %>', {
-% if ( $opt{'width'} ) {
- width: <% $opt{'width'} %>,
-% }
- height: <% $opt{'height'} || 420 %>,
- startupFocus: true,
- toolbarCanCollapse: true,
- basePath: '<% $p %>elements/ckeditor/',
- enterMode: 2
- });
+ CKEDITOR.replace('<% $opt{'field'} %>',
+ <% encode_json($config) %>
+ );
</SCRIPT>
<%init>
my %opt = @_;
+my $config = {
+ 'height' => ($opt{height} || 420),
+ 'startupFocus' => JSON::true,
+ 'skin' => 'kama',
+ 'toolbarCanCollapse' => JSON::true,
+ 'basePath' => $p.'elements/ckeditor/',
+ 'enterMode' => 2,
+ %{ $opt{config} || {} },
+};
+$config->{width} = $opt{width} if defined($opt{width});
</%init>