src/pyams_skin/resources/js/ext/tinymce/dev/classes/EditorManager.js
changeset 69 a361355b55c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_skin/resources/js/ext/tinymce/dev/classes/EditorManager.js	Wed Jun 17 10:00:10 2015 +0200
@@ -0,0 +1,654 @@
+/**
+ * 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/DomQuery",
+	"tinymce/dom/DOMUtils",
+	"tinymce/util/URI",
+	"tinymce/Env",
+	"tinymce/util/Tools",
+	"tinymce/util/Observable",
+	"tinymce/util/I18n",
+	"tinymce/FocusManager"
+], function(Editor, DomQuery, 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.unbindAllNativeEvents();
+			editor.destroy(true);
+			editor = null;
+		}
+
+		return editor;
+	}
+
+	EditorManager = {
+		/**
+		 * 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.
+		 *
+		 * @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;
+
+			// 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
+					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 = [];
+
+			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, targetElm) {
+				if (!purgeDestroyedEditor(self.get(id))) {
+					var editor = new Editor(id, settings, self);
+
+					editor.targetElm = editor.targetElm || targetElm;
+					editors.push(editor);
+					editor.render();
+				}
+			}
+
+			function execCallback(name) {
+				var callback = settings[name];
+
+				if (!callback) {
+					return;
+				}
+
+				return callback.apply(self, Array.prototype.slice.call(arguments, 2));
+			}
+
+			function hasClass(elm, className) {
+				return className.constructor === RegExp ? className.test(elm.className) : DOM.hasClass(elm, className);
+			}
+
+			function readyHandler() {
+				var l, co;
+
+				DOM.unbind(window, 'ready', readyHandler);
+
+				execCallback('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), elm);
+						});
+					});
+
+					return;
+				} else if (settings.selector) {
+					// Process global selector
+					each(DOM.select(settings.selector), function(elm) {
+						createEditor(createId(elm), settings, elm);
+					});
+
+					return;
+				} else if (settings.target) {
+					createEditor(createId(settings.target), settings);
+				}
+
+				// 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))) {
+									createEditor(id, settings, 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);
+												createEditor(id, settings, 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)) {
+								createEditor(createId(elm), settings, elm);
+							}
+						});
+						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('oninit');
+								}
+							});
+						} else {
+							l++;
+						}
+
+						// All done
+						if (l == co) {
+							execCallback('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);
+
+			// Doesn't call setActive method since we don't want
+			// to fire a bunch of activate/deactivate calls while initializing
+			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) {
+					editor = editors[elm.id];
+
+					if (editor) {
+						self.remove(editor);
+					}
+				});
+
+				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);
+		},
+
+		/**
+		 * 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();
+
+	// Export EditorManager as tinymce/tinymce in global namespace
+	window.tinymce = window.tinyMCE = EditorManager;
+
+	return EditorManager;
+});