123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- /**
- * EditorManager.js
- *
- * Copyright 2009, Moxiecode Systems AB
- * Released under LGPL License.
- *
- * License: http://tinymce.moxiecode.com/license
- * Contributing: http://tinymce.moxiecode.com/contributing
- */
- (function(tinymce) {
- /**
- * @class tinymce
- */
- // Shorten names
- var each = tinymce.each, extend = tinymce.extend,
- DOM = tinymce.DOM, Event = tinymce.dom.Event,
- ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
- explode = tinymce.explode,
- Dispatcher = tinymce.util.Dispatcher, undefined, instanceCounter = 0;
- // Setup some URLs where the editor API is located and where the document is
- tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
- if (!/[\/\\]$/.test(tinymce.documentBaseURL))
- tinymce.documentBaseURL += '/';
- tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);
- /**
- * Absolute baseURI for the installation path of TinyMCE.
- *
- * @property baseURI
- * @type tinymce.util.URI
- */
- tinymce.baseURI = new tinymce.util.URI(tinymce.baseURL);
- // Add before unload listener
- // This was required since IE was leaking memory if you added and removed beforeunload listeners
- // with attachEvent/detatchEvent so this only adds one listener and instances can the attach to the onBeforeUnload event
- tinymce.onBeforeUnload = new Dispatcher(tinymce);
- // Must be on window or IE will leak if the editor is placed in frame or iframe
- Event.add(window, 'beforeunload', function(e) {
- tinymce.onBeforeUnload.dispatch(tinymce, e);
- });
- /**
- * Fires when a new editor instance is added to the tinymce collection.
- *
- * @event onAddEditor
- * @param {tinymce} sender TinyMCE root class/namespace.
- * @param {tinymce.Editor} editor Editor instance.
- * @example
- * tinyMCE.execCommand("mceAddControl", false, "some_textarea");
- * tinyMCE.onAddEditor.add(function(mgr,ed) {
- * console.debug('A new editor is available' + ed.id);
- * });
- */
- tinymce.onAddEditor = new Dispatcher(tinymce);
- /**
- * Fires when an editor instance is removed from the tinymce collection.
- *
- * @event onRemoveEditor
- * @param {tinymce} sender TinyMCE root class/namespace.
- * @param {tinymce.Editor} editor Editor instance.
- */
- tinymce.onRemoveEditor = new Dispatcher(tinymce);
- tinymce.EditorManager = extend(tinymce, {
- /**
- * Collection of editor instances.
- *
- * @property editors
- * @type Object
- * @example
- * for (edId in tinyMCE.editors)
- * tinyMCE.editors[edId].save();
- */
- editors : [],
- /**
- * Collection of language pack data.
- *
- * @property i18n
- * @type Object
- */
- i18n : {},
- /**
- * Currently active editor instance.
- *
- * @property activeEditor
- * @type tinymce.Editor
- * @example
- * tinyMCE.activeEditor.selection.getContent();
- * tinymce.EditorManager.activeEditor.selection.getContent();
- */
- activeEditor : null,
- /**
- * Initializes a set of editors. This method will create a bunch of editors based in the input.
- *
- * @method init
- * @param {Object} s Settings object to be passed to each editor instance.
- * @example
- * // Initializes a editor using the longer method
- * tinymce.EditorManager.init({
- * some_settings : 'some value'
- * });
- *
- * // Initializes a editor instance using the shorter version
- * tinyMCE.init({
- * some_settings : 'some value'
- * });
- */
- init : function(s) {
- var t = this, pl, sl = tinymce.ScriptLoader, e, el = [], ed;
- function execCallback(se, n, s) {
- var f = se[n];
- if (!f)
- return;
- if (tinymce.is(f, 'string')) {
- s = f.replace(/\.\w+$/, '');
- s = s ? tinymce.resolve(s) : 0;
- f = tinymce.resolve(f);
- }
- return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
- };
- s = extend({
- theme : "simple",
- language : "en"
- }, s);
- t.settings = s;
- // Legacy call
- Event.add(document, 'init', function() {
- var l, co;
- execCallback(s, 'onpageload');
- switch (s.mode) {
- case "exact":
- l = s.elements || '';
- if(l.length > 0) {
- each(explode(l), function(v) {
- if (DOM.get(v)) {
- ed = new tinymce.Editor(v, s);
- el.push(ed);
- ed.render(1);
- } else {
- each(document.forms, function(f) {
- each(f.elements, function(e) {
- if (e.name === v) {
- v = 'mce_editor_' + instanceCounter++;
- DOM.setAttrib(e, 'id', v);
- ed = new tinymce.Editor(v, s);
- el.push(ed);
- ed.render(1);
- }
- });
- });
- }
- });
- }
- break;
- case "textareas":
- case "specific_textareas":
- function hasClass(n, c) {
- return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
- };
- each(DOM.select('textarea'), function(v) {
- if (s.editor_deselector && hasClass(v, s.editor_deselector))
- return;
- if (!s.editor_selector || hasClass(v, s.editor_selector)) {
- // Can we use the name
- e = DOM.get(v.name);
- if (!v.id && !e)
- v.id = v.name;
- // Generate unique name if missing or already exists
- if (!v.id || t.get(v.id))
- v.id = DOM.uniqueId();
- ed = new tinymce.Editor(v.id, s);
- el.push(ed);
- ed.render(1);
- }
- });
- break;
- }
- // Call onInit when all editors are initialized
- if (s.oninit) {
- l = co = 0;
- each(el, function(ed) {
- co++;
- if (!ed.initialized) {
- // Wait for it
- ed.onInit.add(function() {
- l++;
- // All done
- if (l == co)
- execCallback(s, 'oninit');
- });
- } else
- l++;
- // All done
- if (l == co)
- execCallback(s, 'oninit');
- });
- }
- });
- },
- /**
- * Returns a editor instance by id.
- *
- * @method get
- * @param {String/Number} id Editor instance id or index to return.
- * @return {tinymce.Editor} Editor instance to return.
- * @example
- * // Adds an onclick event to an editor by id (shorter version)
- * tinyMCE.get('mytextbox').onClick.add(function(ed, e) {
- * ed.windowManager.alert('Hello world!');
- * });
- *
- * // Adds an onclick event to an editor by id (longer version)
- * tinymce.EditorManager.get('mytextbox').onClick.add(function(ed, e) {
- * ed.windowManager.alert('Hello world!');
- * });
- */
- get : function(id) {
- if (id === undefined)
- return this.editors;
- return this.editors[id];
- },
- /**
- * Returns a editor instance by id. This method was added for compatibility with the 2.x branch.
- *
- * @method getInstanceById
- * @param {String} id Editor instance id to return.
- * @return {tinymce.Editor} Editor instance to return.
- * @deprecated Use get method instead.
- * @see #get
- */
- getInstanceById : function(id) {
- return this.get(id);
- },
- /**
- * Adds an editor instance to the editor collection. This will also set it as the active editor.
- *
- * @method add
- * @param {tinymce.Editor} editor Editor instance to add to the collection.
- * @return {tinymce.Editor} The same instance that got passed in.
- */
- add : function(editor) {
- var self = this, editors = self.editors;
- // Add named and index editor instance
- editors[editor.id] = editor;
- editors.push(editor);
- self._setActive(editor);
- self.onAddEditor.dispatch(self, editor);
- // #ifdef jquery
- // Patch the tinymce.Editor instance with jQuery adapter logic
- if (tinymce.adapter)
- tinymce.adapter.patchEditor(editor);
- // #endif
- return editor;
- },
- /**
- * Removes a editor instance from the collection.
- *
- * @method remove
- * @param {tinymce.Editor} e Editor instance to remove.
- * @return {tinymce.Editor} The editor that got passed in will be return if it was found otherwise null.
- */
- remove : function(editor) {
- var t = this, i, editors = t.editors;
- // Not in the collection
- if (!editors[editor.id])
- return null;
- delete editors[editor.id];
- for (i = 0; i < editors.length; i++) {
- if (editors[i] == editor) {
- editors.splice(i, 1);
- break;
- }
- }
- // Select another editor since the active one was removed
- if (t.activeEditor == editor)
- t._setActive(editors[0]);
- editor.destroy();
- t.onRemoveEditor.dispatch(t, editor);
- return editor;
- },
- /**
- * Executes a specific command on the currently active editor.
- *
- * @method execCommand
- * @param {String} c Command to perform for example Bold.
- * @param {Boolean} u Optional boolean state if a UI should be presented for the command or not.
- * @param {String} v Optional value parameter like for example an URL to a link.
- * @return {Boolean} true/false if the command was executed or not.
- */
- execCommand : function(c, u, v) {
- var t = this, ed = t.get(v), w;
- // Manager commands
- switch (c) {
- case "mceFocus":
- ed.focus();
- return true;
- case "mceAddEditor":
- case "mceAddControl":
- if (!t.get(v))
- new tinymce.Editor(v, t.settings).render();
- return true;
- case "mceAddFrameControl":
- w = v.window;
- // Add tinyMCE global instance and tinymce namespace to specified window
- w.tinyMCE = tinyMCE;
- w.tinymce = tinymce;
- tinymce.DOM.doc = w.document;
- tinymce.DOM.win = w;
- ed = new tinymce.Editor(v.element_id, v);
- ed.render();
- // Fix IE memory leaks
- if (tinymce.isIE) {
- function clr() {
- ed.destroy();
- w.detachEvent('onunload', clr);
- w = w.tinyMCE = w.tinymce = null; // IE leak
- };
- w.attachEvent('onunload', clr);
- }
- v.page_window = null;
- return true;
- case "mceRemoveEditor":
- case "mceRemoveControl":
- if (ed)
- ed.remove();
- return true;
- case 'mceToggleEditor':
- if (!ed) {
- t.execCommand('mceAddControl', 0, v);
- return true;
- }
- if (ed.isHidden())
- ed.show();
- else
- ed.hide();
- return true;
- }
- // Run command on active editor
- if (t.activeEditor)
- return t.activeEditor.execCommand(c, u, v);
- return false;
- },
- /**
- * Executes a command on a specific editor by id. This method was added for compatibility with the 2.x branch.
- *
- * @deprecated Use the execCommand method of a editor instance instead.
- * @method execInstanceCommand
- * @param {String} id Editor id to perform the command on.
- * @param {String} c Command to perform for example Bold.
- * @param {Boolean} u Optional boolean state if a UI should be presented for the command or not.
- * @param {String} v Optional value parameter like for example an URL to a link.
- * @return {Boolean} true/false if the command was executed or not.
- */
- execInstanceCommand : function(id, c, u, v) {
- var ed = this.get(id);
- if (ed)
- return ed.execCommand(c, u, v);
- return false;
- },
- /**
- * Calls the save method on all editor instances in the collection. This can be useful when a form is to be submitted.
- *
- * @method triggerSave
- * @example
- * // Saves all contents
- * tinyMCE.triggerSave();
- */
- triggerSave : function() {
- each(this.editors, function(e) {
- e.save();
- });
- },
- /**
- * Adds a language pack, this gets called by the loaded language files like en.js.
- *
- * @method addI18n
- * @param {String} p Prefix for the language items. For example en.myplugin
- * @param {Object} o Name/Value collection with items to add to the language group.
- */
- addI18n : function(p, o) {
- var lo, i18n = this.i18n;
- if (!tinymce.is(p, 'string')) {
- each(p, function(o, lc) {
- each(o, function(o, g) {
- each(o, function(o, k) {
- if (g === 'common')
- i18n[lc + '.' + k] = o;
- else
- i18n[lc + '.' + g + '.' + k] = o;
- });
- });
- });
- } else {
- each(o, function(o, k) {
- i18n[p + '.' + k] = o;
- });
- }
- },
- // Private methods
- _setActive : function(editor) {
- this.selectedInstance = this.activeEditor = editor;
- }
- });
- })(tinymce);
- /**
- * Alternative name for tinymce added for 2.x compatibility.
- *
- * @member
- * @property tinyMCE
- * @type tinymce
- * @example
- * // To initialize editor instances
- * tinyMCE.init({
- * ...
- * });
- */
- /**
- * Alternative name for tinymce added for compatibility.
- *
- * @member tinymce
- * @property EditorManager
- * @type tinymce
- * @example
- * // To initialize editor instances
- * tinymce.EditorManager.get('editor');
- */
|