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