| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- /**
- * EditorManager.js
- *
- * Copyright, Moxiecode Systems AB
- * Released under LGPL License.
- *
- * License: http://www.tinymce.com/license
- * Contributing: http://www.tinymce.com/contributing
- */
- /**
- * This class used as a factory for manager for tinymce.Editor instances.
- *
- * @example
- * tinymce.EditorManager.init({});
- *
- * @class tinymce.EditorManager
- * @mixes tinymce.util.Observable
- * @static
- */
- define("tinymce/EditorManager", [
- "tinymce/Editor",
- "tinymce/dom/DOMUtils",
- "tinymce/util/URI",
- "tinymce/Env",
- "tinymce/util/Tools",
- "tinymce/util/Observable",
- "tinymce/util/I18n",
- "tinymce/FocusManager"
- ], function(Editor, DOMUtils, URI, Env, Tools, Observable, I18n, FocusManager) {
- var DOM = DOMUtils.DOM;
- var explode = Tools.explode, each = Tools.each, extend = Tools.extend;
- var instanceCounter = 0, beforeUnloadDelegate, EditorManager;
- function removeEditorFromList(editor) {
- var editors = EditorManager.editors, removedFromList;
- delete editors[editor.id];
- for (var i = 0; i < editors.length; i++) {
- if (editors[i] == editor) {
- editors.splice(i, 1);
- removedFromList = true;
- break;
- }
- }
- // Select another editor since the active one was removed
- if (EditorManager.activeEditor == editor) {
- EditorManager.activeEditor = editors[0];
- }
- // Clear focusedEditor if necessary, so that we don't try to blur the destroyed editor
- if (EditorManager.focusedEditor == editor) {
- EditorManager.focusedEditor = null;
- }
- return removedFromList;
- }
- function purgeDestroyedEditor(editor) {
- // User has manually destroyed the editor lets clean up the mess
- if (editor && !(editor.getContainer() || editor.getBody()).parentNode) {
- removeEditorFromList(editor);
- editor.destroy(true);
- editor = null;
- }
- return editor;
- }
- EditorManager = {
- /**
- * Major version of TinyMCE build.
- *
- * @property majorVersion
- * @type String
- */
- majorVersion : '@@majorVersion@@',
- /**
- * Minor version of TinyMCE build.
- *
- * @property minorVersion
- * @type String
- */
- minorVersion : '@@minorVersion@@',
- /**
- * Release date of TinyMCE build.
- *
- * @property releaseDate
- * @type String
- */
- releaseDate: '@@releaseDate@@',
- /**
- * 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: I18n,
- /**
- * Currently active editor instance.
- *
- * @property activeEditor
- * @type tinymce.Editor
- * @example
- * tinyMCE.activeEditor.selection.getContent();
- * tinymce.EditorManager.activeEditor.selection.getContent();
- */
- activeEditor: null,
- setup: function() {
- var self = this, baseURL, documentBaseURL, suffix = "", preInit, src;
- // Get base URL for the current document
- documentBaseURL = document.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
- if (!/[\/\\]$/.test(documentBaseURL)) {
- documentBaseURL += '/';
- }
- // If tinymce is defined and has a base use that or use the old tinyMCEPreInit
- preInit = window.tinymce || window.tinyMCEPreInit;
- if (preInit) {
- baseURL = preInit.base || preInit.baseURL;
- suffix = preInit.suffix;
- } else {
- // Get base where the tinymce script is located
- var scripts = document.getElementsByTagName('script');
- for (var i = 0; i < scripts.length; i++) {
- src = scripts[i].src;
- // Script types supported:
- // tinymce.js tinymce.min.js tinymce.dev.js
- // tinymce.jquery.js tinymce.jquery.min.js tinymce.jquery.dev.js
- // tinymce.full.js tinymce.full.min.js tinymce.full.dev.js
- if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) {
- if (src.indexOf('.min') != -1) {
- suffix = '.min';
- }
- baseURL = src.substring(0, src.lastIndexOf('/'));
- break;
- }
- }
- // We didn't find any baseURL by looking at the script elements
- // Try to use the document.currentScript as a fallback
- if (!baseURL && document.currentScript) {
- src = document.currentScript.src;
- if (src.indexOf('.min') != -1) {
- suffix = '.min';
- }
- baseURL = src.substring(0, src.lastIndexOf('/'));
- }
- }
- /**
- * Base URL where the root directory if TinyMCE is located.
- *
- * @property baseURL
- * @type String
- */
- self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);
- /**
- * Document base URL where the current document is located.
- *
- * @property documentBaseURL
- * @type String
- */
- self.documentBaseURL = documentBaseURL;
- /**
- * Absolute baseURI for the installation path of TinyMCE.
- *
- * @property baseURI
- * @type tinymce.util.URI
- */
- self.baseURI = new URI(self.baseURL);
- /**
- * Current suffix to add to each plugin/theme that gets loaded for example ".min".
- *
- * @property suffix
- * @type String
- */
- self.suffix = suffix;
- self.focusManager = new FocusManager(self);
- },
- /**
- * Initializes a set of editors. This method will create editors based on various settings.
- *
- * @method init
- * @param {Object} settings 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(settings) {
- var self = this, editors = [], editor;
- function createId(elm) {
- var id = elm.id;
- // Use element id, or unique name or generate a unique id
- if (!id) {
- id = elm.name;
- if (id && !DOM.get(id)) {
- id = elm.name;
- } else {
- // Generate unique name
- id = DOM.uniqueId();
- }
- elm.setAttribute('id', id);
- }
- return id;
- }
- function createEditor(id, settings) {
- if (!purgeDestroyedEditor(self.get(id))) {
- var editor = new Editor(id, settings, self);
- editors.push(editor);
- editor.render();
- }
- }
- function execCallback(se, n, s) {
- var f = se[n];
- if (!f) {
- return;
- }
- return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
- }
- function hasClass(n, c) {
- return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
- }
- function readyHandler() {
- var l, co;
- DOM.unbind(window, 'ready', readyHandler);
- execCallback(settings, 'onpageload');
- if (settings.types) {
- // Process type specific selector
- each(settings.types, function(type) {
- each(DOM.select(type.selector), function(elm) {
- createEditor(createId(elm), extend({}, settings, type));
- });
- });
- return;
- } else if (settings.selector) {
- // Process global selector
- each(DOM.select(settings.selector), function(elm) {
- createEditor(createId(elm), settings);
- });
- return;
- }
- // Fallback to old setting
- switch (settings.mode) {
- case "exact":
- l = settings.elements || '';
- if (l.length > 0) {
- each(explode(l), function(v) {
- if (DOM.get(v)) {
- editor = new Editor(v, settings, self);
- editors.push(editor);
- editor.render();
- } else {
- each(document.forms, function(f) {
- each(f.elements, function(e) {
- if (e.name === v) {
- v = 'mce_editor_' + instanceCounter++;
- DOM.setAttrib(e, 'id', v);
- createEditor(v, settings);
- }
- });
- });
- }
- });
- }
- break;
- case "textareas":
- case "specific_textareas":
- each(DOM.select('textarea'), function(elm) {
- if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {
- return;
- }
- if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
- createEditor(createId(elm), settings);
- }
- });
- break;
- }
- // Call onInit when all editors are initialized
- if (settings.oninit) {
- l = co = 0;
- each(editors, function(ed) {
- co++;
- if (!ed.initialized) {
- // Wait for it
- ed.on('init', function() {
- l++;
- // All done
- if (l == co) {
- execCallback(settings, 'oninit');
- }
- });
- } else {
- l++;
- }
- // All done
- if (l == co) {
- execCallback(settings, 'oninit');
- }
- });
- }
- }
- self.settings = settings;
- DOM.bind(window, 'ready', readyHandler);
- },
- /**
- * 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').on('click', function(e) {
- * ed.windowManager.alert('Hello world!');
- * });
- *
- * // Adds an onclick event to an editor by id (longer version)
- * tinymce.EditorManager.get('mytextbox').on('click', function(e) {
- * ed.windowManager.alert('Hello world!');
- * });
- */
- get: function(id) {
- if (!arguments.length) {
- return this.editors;
- }
- return id in this.editors ? this.editors[id] : null;
- },
- /**
- * 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.activeEditor = editor;
- /**
- * Fires when an editor is added to the EditorManager collection.
- *
- * @event AddEditor
- * @param {Object} e Event arguments.
- */
- self.fire('AddEditor', {editor: editor});
- if (!beforeUnloadDelegate) {
- beforeUnloadDelegate = function() {
- self.fire('BeforeUnload');
- };
- DOM.bind(window, 'beforeunload', beforeUnloadDelegate);
- }
- return editor;
- },
- /**
- * Creates an editor instance and adds it to the EditorManager collection.
- *
- * @method createEditor
- * @param {String} id Instance id to use for editor.
- * @param {Object} settings Editor instance settings.
- * @return {tinymce.Editor} Editor instance that got created.
- */
- createEditor: function(id, settings) {
- return this.add(new Editor(id, settings, this));
- },
- /**
- * Removes a editor or editors form page.
- *
- * @example
- * // Remove all editors bound to divs
- * tinymce.remove('div');
- *
- * // Remove all editors bound to textareas
- * tinymce.remove('textarea');
- *
- * // Remove all editors
- * tinymce.remove();
- *
- * // Remove specific instance by id
- * tinymce.remove('#id');
- *
- * @method remove
- * @param {tinymce.Editor/String/Object} [selector] CSS selector or editor instance to remove.
- * @return {tinymce.Editor} The editor that got passed in will be return if it was found otherwise null.
- */
- remove: function(selector) {
- var self = this, i, editors = self.editors, editor;
- // Remove all editors
- if (!selector) {
- for (i = editors.length - 1; i >= 0; i--) {
- self.remove(editors[i]);
- }
- return;
- }
- // Remove editors by selector
- if (typeof(selector) == "string") {
- selector = selector.selector || selector;
- each(DOM.select(selector), function(elm) {
- self.remove(editors[elm.id]);
- });
- return;
- }
- // Remove specific editor
- editor = selector;
- // Not in the collection
- if (!editors[editor.id]) {
- return null;
- }
- /**
- * Fires when an editor is removed from EditorManager collection.
- *
- * @event RemoveEditor
- * @param {Object} e Event arguments.
- */
- if (removeEditorFromList(editor)) {
- self.fire('RemoveEditor', {editor: editor});
- }
- if (!editors.length) {
- DOM.unbind(window, 'beforeunload', beforeUnloadDelegate);
- }
- editor.remove();
- 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(cmd, ui, value) {
- var self = this, editor = self.get(value);
- // Manager commands
- switch (cmd) {
- case "mceAddEditor":
- if (!self.get(value)) {
- new Editor(value, self.settings, self).render();
- }
- return true;
- case "mceRemoveEditor":
- if (editor) {
- editor.remove();
- }
- return true;
- case 'mceToggleEditor':
- if (!editor) {
- self.execCommand('mceAddEditor', 0, value);
- return true;
- }
- if (editor.isHidden()) {
- editor.show();
- } else {
- editor.hide();
- }
- return true;
- }
- // Run command on active editor
- if (self.activeEditor) {
- return self.activeEditor.execCommand(cmd, ui, value);
- }
- 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(editor) {
- editor.save();
- });
- },
- /**
- * Adds a language pack, this gets called by the loaded language files like en.js.
- *
- * @method addI18n
- * @param {String} code Optional language code.
- * @param {Object} items Name/value object with translations.
- */
- addI18n: function(code, items) {
- I18n.add(code, items);
- },
- /**
- * Translates the specified string using the language pack items.
- *
- * @method translate
- * @param {String/Array/Object} text String to translate
- * @return {String} Translated string.
- */
- translate: function(text) {
- return I18n.translate(text);
- }
- };
- extend(EditorManager, Observable);
- EditorManager.setup();
- // Export EditorManager as tinymce/tinymce in global namespace
- window.tinymce = window.tinyMCE = EditorManager;
- return EditorManager;
- });
|