includes/clientside/tinymce/plugins/noneditable/editor_plugin_src.js
changeset 335 67bd3121a12e
parent 1 fe660c52c48f
child 395 fa4c5ecb7c9a
equal deleted inserted replaced
334:c72b545f1304 335:67bd3121a12e
     1 /**
     1 /**
     2  * $Id: editor_plugin_src.js 205 2007-02-12 18:58:29Z spocke $
     2  * $Id: editor_plugin_src.js 372 2007-11-11 18:38:50Z spocke $
     3  *
     3  *
     4  * @author Moxiecode
     4  * @author Moxiecode
     5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
     6  */
     6  */
     7 
     7 
     8 var TinyMCE_NonEditablePlugin = {
     8 (function() {
     9 	getInfo : function() {
     9 	var Event = tinymce.dom.Event;
    10 		return {
       
    11 			longname : 'Non editable elements',
       
    12 			author : 'Moxiecode Systems AB',
       
    13 			authorurl : 'http://tinymce.moxiecode.com',
       
    14 			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',
       
    15 			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
       
    16 		};
       
    17 	},
       
    18 
    10 
    19 	initInstance : function(inst) {
    11 	tinymce.create('tinymce.plugins.NonEditablePlugin', {
    20 		tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/noneditable/css/noneditable.css");
    12 		init : function(ed, url) {
       
    13 			var t = this, editClass, nonEditClass;
    21 
    14 
    22 		// Ugly hack
    15 			t.editor = ed;
    23 		if (tinyMCE.isMSIE5_0)
    16 			editClass = ed.getParam("noneditable_editable_class", "mceEditable");
    24 			tinyMCE.settings['plugins'] = tinyMCE.settings['plugins'].replace(/noneditable/gi, 'Noneditable');
    17 			nonEditClass = ed.getParam("noneditable_noneditable_class", "mceNonEditable");
    25 	},
       
    26 
    18 
    27 	handleEvent : function(e) {
    19 			ed.onNodeChange.addToTop(function(ed, cm, n) {
    28 		return this._moveSelection(e, tinyMCE.selectedInstance);
    20 				var sc, ec;
    29 	},
       
    30 
    21 
    31 	cleanup : function(type, content, inst) {
    22 				// Block if start or end is inside a non editable element
    32 		switch (type) {
    23 				sc = ed.dom.getParent(ed.selection.getStart(), function(n) {
    33 			case "insert_to_editor_dom":
    24 					return ed.dom.hasClass(n, nonEditClass);
    34 				var nodes, i, editClass, nonEditClass, editable, elm;
    25 				});
    35 
    26 
    36 				// Pass through Gecko
    27 				ec = ed.dom.getParent(ed.selection.getEnd(), function(n) {
    37 				if (tinyMCE.isGecko)
    28 					return ed.dom.hasClass(n, nonEditClass);
    38 					return content;
    29 				});
    39 
    30 
    40 				nodes = tinyMCE.getNodeTree(content, [], 1);
    31 				// Block or unblock
       
    32 				if (sc || ec) {
       
    33 					t._setDisabled(1);
       
    34 					return false;
       
    35 				} else
       
    36 					t._setDisabled(0);
       
    37 			});
       
    38 		},
    41 
    39 
    42 				editClass = tinyMCE.getParam("noneditable_editable_class", "mceEditable");
    40 		getInfo : function() {
    43 				nonEditClass = tinyMCE.getParam("noneditable_noneditable_class", "mceNonEditable");
    41 			return {
       
    42 				longname : 'Non editable elements',
       
    43 				author : 'Moxiecode Systems AB',
       
    44 				authorurl : 'http://tinymce.moxiecode.com',
       
    45 				infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',
       
    46 				version : tinymce.majorVersion + "." + tinymce.minorVersion
       
    47 			};
       
    48 		},
    44 
    49 
    45 				for (i=0; i<nodes.length; i++) {
    50 		_block : function(ed, e) {
    46 					elm = nodes[i];
    51 			return Event.cancel(e);
       
    52 		},
    47 
    53 
    48 					// Convert contenteditable to classes
    54 		_setDisabled : function(s) {
    49 					editable = tinyMCE.getAttrib(elm, "contenteditable");
    55 			var t = this, ed = t.editor;
    50 					if (new RegExp("true|false","gi").test(editable))
       
    51 						TinyMCE_NonEditablePlugin._setEditable(elm, editable == "true");
       
    52 
    56 
    53 					if (tinyMCE.isIE) {
    57 			tinymce.each(ed.controlManager.controls, function(c) {
    54 						if (tinyMCE.hasCSSClass(elm, editClass))
    58 				c.setDisabled(s);
    55 							elm.contentEditable = true;
    59 			});
    56 
    60 
    57 						if (tinyMCE.hasCSSClass(elm, nonEditClass))
    61 			if (s !== t.disabled) {
    58 							elm.contentEditable = false;
    62 				if (s) {
    59 					}
    63 					ed.onKeyDown.addToTop(t._block);
       
    64 					ed.onKeyPress.addToTop(t._block);
       
    65 					ed.onKeyUp.addToTop(t._block);
       
    66 					ed.onPaste.addToTop(t._block);
       
    67 				} else {
       
    68 					ed.onKeyDown.remove(t._block);
       
    69 					ed.onKeyPress.remove(t._block);
       
    70 					ed.onKeyUp.remove(t._block);
       
    71 					ed.onPaste.remove(t._block);
    60 				}
    72 				}
    61 
    73 
    62 				break;
    74 				t.disabled = s;
    63 
       
    64 			case "insert_to_editor":
       
    65 				var editClass = tinyMCE.getParam("noneditable_editable_class", "mceEditable");
       
    66 				var nonEditClass = tinyMCE.getParam("noneditable_noneditable_class", "mceNonEditable");
       
    67 
       
    68 				// Replace mceItem to new school
       
    69 				content = content.replace(/mceItemEditable/g, editClass);
       
    70 				content = content.replace(/mceItemNonEditable/g, nonEditClass);
       
    71 
       
    72 				if (tinyMCE.isIE && (content.indexOf(editClass) != -1 || content.indexOf(nonEditClass) != -1)) {
       
    73 					content = content.replace(new RegExp("class=\"(.+)(" + editClass + ")\"", "gi"), 'class="$1$2" contenteditable="true"');
       
    74 					content = content.replace(new RegExp("class=\"(.+)(" + nonEditClass + ")\"", "gi"), 'class="$1$2" contenteditable="false"');
       
    75 					content = content.replace(new RegExp("class=\"(" + editClass + ")([^\"]*)\"", "gi"), 'class="$1$2" contenteditable="true"');
       
    76 					content = content.replace(new RegExp("class=\"(" + nonEditClass + ")([^\"]*)\"", "gi"), 'class="$1$2" contenteditable="false"');
       
    77 					content = content.replace(new RegExp("class=\"(.+)(" + editClass + ")([^\"]*)\"", "gi"), 'class="$1$2$3" contenteditable="true"');
       
    78 					content = content.replace(new RegExp("class=\"(.+)(" + nonEditClass + ")([^\"]*)\"", "gi"), 'class="$1$2$3" contenteditable="false"');
       
    79 				}
       
    80 
       
    81 				break;
       
    82 
       
    83 			case "get_from_editor_dom":
       
    84 				// Pass through Gecko
       
    85 				if (tinyMCE.isGecko)
       
    86 					return content;
       
    87 
       
    88 				if (tinyMCE.getParam("noneditable_leave_contenteditable", false)) {
       
    89 					var nodes = tinyMCE.getNodeTree(content, new Array(), 1);
       
    90 
       
    91 					for (var i=0; i<nodes.length; i++)
       
    92 						nodes[i].removeAttribute("contenteditable");
       
    93 				}
       
    94 
       
    95 				break;
       
    96 		}
       
    97 
       
    98 		return content;
       
    99 	},
       
   100 
       
   101 	_moveSelection : function(e, inst) {
       
   102 		var s, r, sc, ec, el, c = tinyMCE.getParam('noneditable_editable_class', 'mceNonEditable');
       
   103 
       
   104 		if (!inst)
       
   105 			return true;
       
   106 
       
   107 		// Always select whole element
       
   108 		if (tinyMCE.isGecko) {
       
   109 			s = inst.selection.getSel();
       
   110 			r = s.getRangeAt(0);
       
   111 			sc = tinyMCE.getParentNode(r.startContainer, function (n) {return tinyMCE.hasCSSClass(n, c);});
       
   112 			ec = tinyMCE.getParentNode(r.endContainer, function (n) {return tinyMCE.hasCSSClass(n, c);});
       
   113 
       
   114 			sc && r.setStartBefore(sc);
       
   115 			ec && r.setEndAfter(ec);
       
   116 
       
   117 			if (sc || ec) {
       
   118 				if (e.type == 'keypress' && e.keyCode == 39) {
       
   119 					el = sc || ec;
       
   120 
       
   121 					// Try!!
       
   122 				}
       
   123 
       
   124 				s.removeAllRanges();
       
   125 				s.addRange(r);
       
   126 
       
   127 				return tinyMCE.cancelEvent(e);
       
   128 			}
    75 			}
   129 		}
    76 		}
       
    77 	});
   130 
    78 
   131 		return true;
    79 	// Register plugin
   132 	},
    80 	tinymce.PluginManager.add('noneditable', tinymce.plugins.NonEditablePlugin);
   133 
    81 })();
   134 	_setEditable : function(elm, state) {
       
   135 		var editClass = tinyMCE.getParam("noneditable_editable_class", "mceEditable");
       
   136 		var nonEditClass = tinyMCE.getParam("noneditable_noneditable_class", "mceNonEditable");
       
   137 
       
   138 		var className = elm.className ? elm.className : "";
       
   139 
       
   140 		if (className.indexOf(editClass) != -1 || className.indexOf(nonEditClass) != -1)
       
   141 			return;
       
   142 
       
   143 		if ((className = tinyMCE.getAttrib(elm, "class")) != "")
       
   144 			className += " ";
       
   145 
       
   146 		className += state ? editClass : nonEditClass;
       
   147 
       
   148 		elm.setAttribute("class", className);
       
   149 		elm.className = className;
       
   150 	}
       
   151 };
       
   152 
       
   153 tinyMCE.addPlugin("noneditable", TinyMCE_NonEditablePlugin);