PHP Classes

File: public/js/tinymce/src/core/src/main/js/EditorManager.js

Recommend this page to a friend!
  Classes of Abed Nego Ragil Putra   GoLavaCMS   public/js/tinymce/src/core/src/main/js/EditorManager.js   Download  
File: public/js/tinymce/src/core/src/main/js/EditorManager.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: GoLavaCMS
Publish content on Web pages with SEO support
Author: By
Last change:
Date: 6 years ago
Size: 23,547 bytes
 

Contents

Class file image Download
/** * EditorManager.js * * Released under LGPL License. * Copyright (c) 1999-2017 Ephox Corp. All rights reserved * * 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.core.EditorManager', [ 'ephox.katamari.api.Arr', 'ephox.katamari.api.Type', 'global!document', 'global!window', 'tinymce.core.AddOnManager', 'tinymce.core.Editor', 'tinymce.core.Env', 'tinymce.core.ErrorReporter', 'tinymce.core.dom.DOMUtils', 'tinymce.core.dom.DomQuery', 'tinymce.core.focus.FocusController', 'tinymce.core.util.I18n', 'tinymce.core.util.Observable', 'tinymce.core.util.Promise', 'tinymce.core.util.Tools', 'tinymce.core.util.URI' ], function (Arr, Type, document, window, AddOnManager, Editor, Env, ErrorReporter, DOMUtils, DomQuery, FocusController, I18n, Observable, Promise, Tools, URI) { var DOM = DOMUtils.DOM; var explode = Tools.explode, each = Tools.each, extend = Tools.extend; var instanceCounter = 0, beforeUnloadDelegate, EditorManager, boundGlobalEvents = false; var legacyEditors = [], editors = []; var isValidLegacyKey = function (id) { // In theory we could filter out any editor id:s that clash // with array prototype items but that could break existing integrations return id !== 'length'; }; var globalEventDelegate = function (e) { each(EditorManager.get(), function (editor) { if (e.type === 'scroll') { editor.fire('ScrollWindow', e); } else { editor.fire('ResizeWindow', e); } }); }; var toggleGlobalEvents = function (state) { if (state !== boundGlobalEvents) { if (state) { DomQuery(window).on('resize scroll', globalEventDelegate); } else { DomQuery(window).off('resize scroll', globalEventDelegate); } boundGlobalEvents = state; } }; var removeEditorFromList = function (targetEditor) { var oldEditors = editors; delete legacyEditors[targetEditor.id]; for (var i = 0; i < legacyEditors.length; i++) { if (legacyEditors[i] === targetEditor) { legacyEditors.splice(i, 1); break; } } editors = Arr.filter(editors, function (editor) { return targetEditor !== editor; }); // Select another editor since the active one was removed if (EditorManager.activeEditor === targetEditor) { EditorManager.activeEditor = editors.length > 0 ? editors[0] : null; } // Clear focusedEditor if necessary, so that we don't try to blur the destroyed editor if (EditorManager.focusedEditor === targetEditor) { EditorManager.focusedEditor = null; } return oldEditors.length !== editors.length; }; var purgeDestroyedEditor = function (editor) { // User has manually destroyed the editor lets clean up the mess if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) { removeEditorFromList(editor); editor.unbindAllNativeEvents(); editor.destroy(true); editor.removed = true; editor = null; } return editor; }; EditorManager = { defaultSettings: {}, /** * Dom query instance. * * @property $ * @type tinymce.dom.DomQuery */ $: DomQuery, /** * 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. Deprecated use tinymce.get() instead. * * @property editors * @type Object */ editors: legacyEditors, /** * 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, settings: {}, setup: function () { var self = this, baseURL, documentBaseURL, suffix = "", preInit, src; // Get base URL for the current document documentBaseURL = URI.getDocumentBaseUrl(document.location); // Check if the URL is a document based format like: http://site/dir/file and file:/// // leave other formats like applewebdata://... intact if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) { documentBaseURL = documentBaseURL.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 var srcScript = src.substring(src.lastIndexOf('/')); if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) { if (srcScript.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; FocusController.setup(self); }, /** * Overrides the default settings for editor instances. * * @method overrideDefaults * @param {Object} defaultSettings Defaults settings object. */ overrideDefaults: function (defaultSettings) { var baseUrl, suffix; baseUrl = defaultSettings.base_url; if (baseUrl) { this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, '')); this.baseURI = new URI(this.baseURL); } suffix = defaultSettings.suffix; if (defaultSettings.suffix) { this.suffix = suffix; } this.defaultSettings = defaultSettings; var pluginBaseUrls = defaultSettings.plugin_base_urls; for (var name in pluginBaseUrls) { AddOnManager.PluginManager.urls[name] = pluginBaseUrls[name]; } }, /** * 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. * @return {tinymce.util.Promise} Promise that gets resolved with an array of editors when all editor instances are initialized. * @example * // Initializes a editor using the longer method * tinymce.EditorManager.init({ * some_settings : 'some value' * }); * * // Initializes a editor instance using the shorter version and with a promise * tinymce.init({ * some_settings : 'some value' * }).then(function(editors) { * ... * }); */ init: function (settings) { var self = this, result, invalidInlineTargets; invalidInlineTargets = Tools.makeMap( 'area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option tbody tfoot thead tr script noscript style textarea video audio iframe object menu', ' ' ); var isInvalidInlineTarget = function (settings, elm) { return settings.inline && elm.tagName.toLowerCase() in invalidInlineTargets; }; var createId = function (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; }; var execCallback = function (name) { var callback = settings[name]; if (!callback) { return; } return callback.apply(self, Array.prototype.slice.call(arguments, 2)); }; var hasClass = function (elm, className) { return className.constructor === RegExp ? className.test(elm.className) : DOM.hasClass(elm, className); }; var findTargets = function (settings) { var l, targets = []; if (Env.ie && Env.ie < 11) { ErrorReporter.initError( 'TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/' ); return []; } if (settings.types) { each(settings.types, function (type) { targets = targets.concat(DOM.select(type.selector)); }); return targets; } else if (settings.selector) { return DOM.select(settings.selector); } else if (settings.target) { return [settings.target]; } // Fallback to old setting switch (settings.mode) { case "exact": l = settings.elements || ''; if (l.length > 0) { each(explode(l), function (id) { var elm; if ((elm = DOM.get(id))) { targets.push(elm); } else { each(document.forms, function (f) { each(f.elements, function (e) { if (e.name === id) { id = 'mce_editor_' + instanceCounter++; DOM.setAttrib(e, 'id', id); targets.push(e); } }); }); } }); } 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)) { targets.push(elm); } }); break; } return targets; }; var provideResults = function (editors) { result = editors; }; var initEditors = function () { var initCount = 0, editors = [], targets; var createEditor = function (id, settings, targetElm) { var editor = new Editor(id, settings, self); editors.push(editor); editor.on('init', function () { if (++initCount === targets.length) { provideResults(editors); } }); editor.targetElm = editor.targetElm || targetElm; editor.render(); }; DOM.unbind(window, 'ready', initEditors); execCallback('onpageload'); targets = DomQuery.unique(findTargets(settings)); // TODO: Deprecate this one if (settings.types) { each(settings.types, function (type) { Tools.each(targets, function (elm) { if (DOM.is(elm, type.selector)) { createEditor(createId(elm), extend({}, settings, type), elm); return false; } return true; }); }); return; } Tools.each(targets, function (elm) { purgeDestroyedEditor(self.get(elm.id)); }); targets = Tools.grep(targets, function (elm) { return !self.get(elm.id); }); if (targets.length === 0) { provideResults([]); } else { each(targets, function (elm) { if (isInvalidInlineTarget(settings, elm)) { ErrorReporter.initError('Could not initialize inline editor on invalid inline target element', elm); } else { createEditor(createId(elm), settings, elm); } }); } }; self.settings = settings; DOM.bind(window, 'ready', initEditors); return new Promise(function (resolve) { if (result) { resolve(result); } else { provideResults = function (editors) { resolve(editors); }; } }); }, /** * Returns a editor instance by id. * * @method get * @param {String/Number} id Editor instance id or index to return. * @return {tinymce.Editor/Array} Editor instance to return or array of editor instances. * @example * // Adds an onclick event to an editor by id * tinymce.get('mytextbox').on('click', function(e) { * ed.windowManager.alert('Hello world!'); * }); * * // Adds an onclick event to an editor by index * tinymce.get(0).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 === 0) { return editors.slice(0); } else if (Type.isString(id)) { return Arr.find(editors, function (editor) { return editor.id === id; }).getOr(null); } else if (Type.isNumber(id)) { return editors[id] ? editors[id] : null; } else { return 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, existingEditor; // Prevent existing editors from beeing added again this could happen // if a user calls createEditor then render or add multiple times. existingEditor = legacyEditors[editor.id]; if (existingEditor === editor) { return editor; } if (self.get(editor.id) === null) { // Add to legacy editors array, this is what breaks in HTML5 where ID:s with numbers are valid // We can't get rid of this strange object and array at the same time since it seems to be used all over the web if (isValidLegacyKey(editor.id)) { legacyEditors[editor.id] = editor; } legacyEditors.push(editor); editors.push(editor); } toggleGlobalEvents(true); // Doesn't call setActive method since we don't want // to fire a bunch of activate/deactivate calls while initializing self.activeEditor = editor; 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, editor; // Remove all editors if (!selector) { for (i = editors.length - 1; i >= 0; i--) { self.remove(editors[i]); } return; } // Remove editors by selector if (Type.isString(selector)) { selector = selector.selector || selector; each(DOM.select(selector), function (elm) { editor = self.get(elm.id); if (editor) { self.remove(editor); } }); return; } // Remove specific editor editor = selector; // Not in the collection if (Type.isNull(self.get(editor.id))) { return null; } if (removeEditorFromList(editor)) { self.fire('RemoveEditor', { editor: editor }); } if (editors.length === 0) { DOM.unbind(window, 'beforeunload', beforeUnloadDelegate); } editor.remove(); toggleGlobalEvents(editors.length > 0); return editor; }, /** * Executes a specific command on the currently active editor. * * @method execCommand * @param {String} cmd Command to perform for example Bold. * @param {Boolean} ui Optional boolean state if a UI should be presented for the command or not. * @param {String} value 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(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); }, /** * Sets the active editor instance and fires the deactivate/activate events. * * @method setActive * @param {tinymce.Editor} editor Editor instance to set as the active instance. */ setActive: function (editor) { var activeEditor = this.activeEditor; if (this.activeEditor != editor) { if (activeEditor) { activeEditor.fire('deactivate', { relatedTarget: editor }); } editor.fire('activate', { relatedTarget: activeEditor }); } this.activeEditor = editor; } }; extend(EditorManager, Observable); EditorManager.setup(); return EditorManager; } );