src/pyams_skin/resources/js/ext/tinymce/dev/jquery.tinymce.js
changeset 557 bca7a7e058a3
equal deleted inserted replaced
-1:000000000000 557:bca7a7e058a3
       
     1 /**
       
     2  * jquery.tinymce.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  */
       
    10 
       
    11 /*global tinymce:true, jQuery */
       
    12 
       
    13 (function($) {
       
    14 	var undef,
       
    15 		lazyLoading,
       
    16 		patchApplied,
       
    17 		delayedInits = [],
       
    18 		win = window;
       
    19 
       
    20 	$.fn.tinymce = function(settings) {
       
    21 		var self = this, url, base, lang, suffix = "";
       
    22 
       
    23 		// No match then just ignore the call
       
    24 		if (!self.length) {
       
    25 			return self;
       
    26 		}
       
    27 
       
    28 		// Get editor instance
       
    29 		if (!settings) {
       
    30 			return window.tinymce ? tinymce.get(self[0].id) : null;
       
    31 		}
       
    32 
       
    33 		self.css('visibility', 'hidden'); // Hide textarea to avoid flicker
       
    34 
       
    35 		function init() {
       
    36 			var editors = [], initCount = 0;
       
    37 
       
    38 			// Apply patches to the jQuery object, only once
       
    39 			if (!patchApplied) {
       
    40 				applyPatch();
       
    41 				patchApplied = true;
       
    42 			}
       
    43 
       
    44 			// Create an editor instance for each matched node
       
    45 			self.each(function(i, node) {
       
    46 				var ed, id = node.id, oninit = settings.oninit;
       
    47 
       
    48 				// Generate unique id for target element if needed
       
    49 				if (!id) {
       
    50 					node.id = id = tinymce.DOM.uniqueId();
       
    51 				}
       
    52 
       
    53 				// Only init the editor once
       
    54 				if (tinymce.get(id)) {
       
    55 					return;
       
    56 				}
       
    57 
       
    58 				// Create editor instance and render it
       
    59 				ed = new tinymce.Editor(id, settings, tinymce.EditorManager);
       
    60 				editors.push(ed);
       
    61 
       
    62 				ed.on('init', function() {
       
    63 					var scope, func = oninit;
       
    64 
       
    65 					self.css('visibility', '');
       
    66 
       
    67 					// Run this if the oninit setting is defined
       
    68 					// this logic will fire the oninit callback ones each
       
    69 					// matched editor instance is initialized
       
    70 					if (oninit) {
       
    71 						// Fire the oninit event ones each editor instance is initialized
       
    72 						if (++initCount == editors.length) {
       
    73 							if (typeof func === "string") {
       
    74 								scope = (func.indexOf(".") === -1) ? null : tinymce.resolve(func.replace(/\.\w+$/, ""));
       
    75 								func = tinymce.resolve(func);
       
    76 							}
       
    77 
       
    78 							// Call the oninit function with the object
       
    79 							func.apply(scope || tinymce, editors);
       
    80 						}
       
    81 					}
       
    82 				});
       
    83 			});
       
    84 
       
    85 			// Render the editor instances in a separate loop since we
       
    86 			// need to have the full editors array used in the onInit calls
       
    87 			$.each(editors, function(i, ed) {
       
    88 				ed.render();
       
    89 			});
       
    90 		}
       
    91 
       
    92 		// Load TinyMCE on demand, if we need to
       
    93 		if (!win.tinymce && !lazyLoading && (url = settings.script_url)) {
       
    94 			lazyLoading = 1;
       
    95 			base = url.substring(0, url.lastIndexOf("/"));
       
    96 
       
    97 			// Check if it's a dev/src version they want to load then
       
    98 			// make sure that all plugins, themes etc are loaded in source mode as well
       
    99 			if (url.indexOf('.min') != -1) {
       
   100 				suffix = ".min";
       
   101 			}
       
   102 
       
   103 			// Setup tinyMCEPreInit object this will later be used by the TinyMCE
       
   104 			// core script to locate other resources like CSS files, dialogs etc
       
   105 			// You can also predefined a tinyMCEPreInit object and then it will use that instead
       
   106 			win.tinymce = win.tinyMCEPreInit || {
       
   107 				base: base,
       
   108 				suffix: suffix
       
   109 			};
       
   110 
       
   111 			// url contains gzip then we assume it's a compressor
       
   112 			if (url.indexOf('gzip') != -1) {
       
   113 				lang = settings.language || "en";
       
   114 				url = url + (/\?/.test(url) ? '&' : '?') + "js=true&core=true&suffix=" + escape(suffix) +
       
   115 					"&themes=" + escape(settings.theme || 'modern') + "&plugins=" +
       
   116 					escape(settings.plugins || '') + "&languages=" + (lang || '');
       
   117 
       
   118 				// Check if compressor script is already loaded otherwise setup a basic one
       
   119 				if (!win.tinyMCE_GZ) {
       
   120 					win.tinyMCE_GZ = {
       
   121 						start: function() {
       
   122 							function load(url) {
       
   123 								tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(url));
       
   124 							}
       
   125 
       
   126 							// Add core languages
       
   127 							load("langs/" + lang + ".js");
       
   128 
       
   129 							// Add themes with languages
       
   130 							load("themes/" + settings.theme + "/theme" + suffix + ".js");
       
   131 							load("themes/" + settings.theme + "/langs/" + lang + ".js");
       
   132 
       
   133 							// Add plugins with languages
       
   134 							$.each(settings.plugins.split(","), function(i, name) {
       
   135 								if (name) {
       
   136 									load("plugins/" + name + "/plugin" + suffix + ".js");
       
   137 									load("plugins/" + name + "/langs/" + lang + ".js");
       
   138 								}
       
   139 							});
       
   140 						},
       
   141 
       
   142 						end: function() {
       
   143 						}
       
   144 					};
       
   145 				}
       
   146 			}
       
   147 
       
   148 			var script = document.createElement('script');
       
   149 			script.type = 'text/javascript';
       
   150 			script.onload = script.onreadystatechange = function(e) {
       
   151 				e = e || window.event;
       
   152 
       
   153 				if (lazyLoading !== 2 && (e.type == 'load' || /complete|loaded/.test(script.readyState))) {
       
   154 					tinymce.dom.Event.domLoaded = 1;
       
   155 					lazyLoading = 2;
       
   156 
       
   157 					// Execute callback after mainscript has been loaded and before the initialization occurs
       
   158 					if (settings.script_loaded) {
       
   159 						settings.script_loaded();
       
   160 					}
       
   161 
       
   162 					init();
       
   163 
       
   164 					$.each(delayedInits, function(i, init) {
       
   165 						init();
       
   166 					});
       
   167 				}
       
   168 			};
       
   169 			script.src = url;
       
   170 			document.body.appendChild(script);
       
   171 		} else {
       
   172 			// Delay the init call until tinymce is loaded
       
   173 			if (lazyLoading === 1) {
       
   174 				delayedInits.push(init);
       
   175 			} else {
       
   176 				init();
       
   177 			}
       
   178 		}
       
   179 
       
   180 		return self;
       
   181 	};
       
   182 
       
   183 	// Add :tinymce psuedo selector this will select elements that has been converted into editor instances
       
   184 	// it's now possible to use things like $('*:tinymce') to get all TinyMCE bound elements.
       
   185 	$.extend($.expr[":"], {
       
   186 		tinymce: function(e) {
       
   187 			var editor;
       
   188 
       
   189 			if (e.id && "tinymce" in window) {
       
   190 				editor = tinymce.get(e.id);
       
   191 
       
   192 				if (editor && editor.editorManager === tinymce) {
       
   193 					return true;
       
   194 				}
       
   195 			}
       
   196 
       
   197 			return false;
       
   198 		}
       
   199 	});
       
   200 
       
   201 	// This function patches internal jQuery functions so that if
       
   202 	// you for example remove an div element containing an editor it's
       
   203 	// automatically destroyed by the TinyMCE API
       
   204 	function applyPatch() {
       
   205 		// Removes any child editor instances by looking for editor wrapper elements
       
   206 		function removeEditors(name) {
       
   207 			// If the function is remove
       
   208 			if (name === "remove") {
       
   209 				this.each(function(i, node) {
       
   210 					var ed = tinyMCEInstance(node);
       
   211 
       
   212 					if (ed) {
       
   213 						ed.remove();
       
   214 					}
       
   215 				});
       
   216 			}
       
   217 
       
   218 			this.find("span.mceEditor,div.mceEditor").each(function(i, node) {
       
   219 				var ed = tinymce.get(node.id.replace(/_parent$/, ""));
       
   220 
       
   221 				if (ed) {
       
   222 					ed.remove();
       
   223 				}
       
   224 			});
       
   225 		}
       
   226 
       
   227 		// Loads or saves contents from/to textarea if the value
       
   228 		// argument is defined it will set the TinyMCE internal contents
       
   229 		function loadOrSave(value) {
       
   230 			var self = this, ed;
       
   231 
       
   232 			// Handle set value
       
   233 			/*jshint eqnull:true */
       
   234 			if (value != null) {
       
   235 				removeEditors.call(self);
       
   236 
       
   237 				// Saves the contents before get/set value of textarea/div
       
   238 				self.each(function(i, node) {
       
   239 					var ed;
       
   240 
       
   241 					if ((ed = tinymce.get(node.id))) {
       
   242 						ed.setContent(value);
       
   243 					}
       
   244 				});
       
   245 			} else if (self.length > 0) {
       
   246 				// Handle get value
       
   247 				if ((ed = tinymce.get(self[0].id))) {
       
   248 					return ed.getContent();
       
   249 				}
       
   250 			}
       
   251 		}
       
   252 
       
   253 		// Returns tinymce instance for the specified element or null if it wasn't found
       
   254 		function tinyMCEInstance(element) {
       
   255 			var ed = null;
       
   256 
       
   257 			if (element && element.id && win.tinymce) {
       
   258 				ed = tinymce.get(element.id);
       
   259 			}
       
   260 
       
   261 			return ed;
       
   262 		}
       
   263 
       
   264 		// Checks if the specified set contains tinymce instances
       
   265 		function containsTinyMCE(matchedSet) {
       
   266 			return !!((matchedSet) && (matchedSet.length) && (win.tinymce) && (matchedSet.is(":tinymce")));
       
   267 		}
       
   268 
       
   269 		// Patch various jQuery functions
       
   270 		var jQueryFn = {};
       
   271 
       
   272 		// Patch some setter/getter functions these will
       
   273 		// now be able to set/get the contents of editor instances for
       
   274 		// example $('#editorid').html('Content'); will update the TinyMCE iframe instance
       
   275 		$.each(["text", "html", "val"], function(i, name) {
       
   276 			var origFn = jQueryFn[name] = $.fn[name],
       
   277 				textProc = (name === "text");
       
   278 
       
   279 			$.fn[name] = function(value) {
       
   280 				var self = this;
       
   281 
       
   282 				if (!containsTinyMCE(self)) {
       
   283 					return origFn.apply(self, arguments);
       
   284 				}
       
   285 
       
   286 				if (value !== undef) {
       
   287 					loadOrSave.call(self.filter(":tinymce"), value);
       
   288 					origFn.apply(self.not(":tinymce"), arguments);
       
   289 
       
   290 					return self; // return original set for chaining
       
   291 				} else {
       
   292 					var ret = "";
       
   293 					var args = arguments;
       
   294 
       
   295 					(textProc ? self : self.eq(0)).each(function(i, node) {
       
   296 						var ed = tinyMCEInstance(node);
       
   297 
       
   298 						if (ed) {
       
   299 							ret += textProc ? ed.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g, "") : ed.getContent({save: true});
       
   300 						} else {
       
   301 							ret += origFn.apply($(node), args);
       
   302 						}
       
   303 					});
       
   304 
       
   305 					return ret;
       
   306 				}
       
   307 			};
       
   308 		});
       
   309 
       
   310 		// Makes it possible to use $('#id').append("content"); to append contents to the TinyMCE editor iframe
       
   311 		$.each(["append", "prepend"], function(i, name) {
       
   312 			var origFn = jQueryFn[name] = $.fn[name],
       
   313 				prepend = (name === "prepend");
       
   314 
       
   315 			$.fn[name] = function(value) {
       
   316 				var self = this;
       
   317 
       
   318 				if (!containsTinyMCE(self)) {
       
   319 					return origFn.apply(self, arguments);
       
   320 				}
       
   321 
       
   322 				if (value !== undef) {
       
   323 					if (typeof value === "string") {
       
   324 						self.filter(":tinymce").each(function(i, node) {
       
   325 							var ed = tinyMCEInstance(node);
       
   326 
       
   327 							if (ed) {
       
   328 								ed.setContent(prepend ? value + ed.getContent() : ed.getContent() + value);
       
   329 							}
       
   330 						});
       
   331 					}
       
   332 
       
   333 					origFn.apply(self.not(":tinymce"), arguments);
       
   334 
       
   335 					return self; // return original set for chaining
       
   336 				}
       
   337 			};
       
   338 		});
       
   339 
       
   340 		// Makes sure that the editor instance gets properly destroyed when the parent element is removed
       
   341 		$.each(["remove", "replaceWith", "replaceAll", "empty"], function(i, name) {
       
   342 			var origFn = jQueryFn[name] = $.fn[name];
       
   343 
       
   344 			$.fn[name] = function() {
       
   345 				removeEditors.call(this, name);
       
   346 
       
   347 				return origFn.apply(this, arguments);
       
   348 			};
       
   349 		});
       
   350 
       
   351 		jQueryFn.attr = $.fn.attr;
       
   352 
       
   353 		// Makes sure that $('#tinymce_id').attr('value') gets the editors current HTML contents
       
   354 		$.fn.attr = function(name, value) {
       
   355 			var self = this, args = arguments;
       
   356 
       
   357 			if ((!name) || (name !== "value") || (!containsTinyMCE(self))) {
       
   358 				if (value !== undef) {
       
   359 					return jQueryFn.attr.apply(self, args);
       
   360 				} else {
       
   361 					return jQueryFn.attr.apply(self, args);
       
   362 				}
       
   363 			}
       
   364 
       
   365 			if (value !== undef) {
       
   366 				loadOrSave.call(self.filter(":tinymce"), value);
       
   367 				jQueryFn.attr.apply(self.not(":tinymce"), args);
       
   368 
       
   369 				return self; // return original set for chaining
       
   370 			} else {
       
   371 				var node = self[0], ed = tinyMCEInstance(node);
       
   372 
       
   373 				return ed ? ed.getContent({save: true}) : jQueryFn.attr.apply($(node), args);
       
   374 			}
       
   375 		};
       
   376 	}
       
   377 })(jQuery);