Spaces:
Sleeping
Sleeping
/** | |
* plugin.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 | |
*/ | |
/*global tinymce:true, console:true */ | |
/*eslint no-console:0, new-cap:0 */ | |
/** | |
* This plugin adds missing events form the 4.x API back. Not every event is | |
* properly supported but most things should work. | |
* | |
* Unsupported things: | |
* - No editor.onEvent | |
* - Can't cancel execCommands with beforeExecCommand | |
*/ | |
(function (tinymce) { | |
var reported; | |
function noop() { | |
} | |
function log(apiCall) { | |
if (!reported && window && window.console) { | |
reported = true; | |
console.log("Deprecated TinyMCE API call: " + apiCall); | |
} | |
} | |
function Dispatcher(target, newEventName, argsMap, defaultScope) { | |
target = target || this; | |
var cbs = []; | |
if (!newEventName) { | |
this.add = this.addToTop = this.remove = this.dispatch = noop; | |
return; | |
} | |
this.add = function (callback, scope, prepend) { | |
log('<target>.on' + newEventName + ".add(..)"); | |
// Convert callback({arg1:x, arg2:x}) -> callback(arg1, arg2) | |
function patchedEventCallback(e) { | |
var callbackArgs = []; | |
if (typeof argsMap == "string") { | |
argsMap = argsMap.split(" "); | |
} | |
if (argsMap && typeof argsMap !== "function") { | |
for (var i = 0; i < argsMap.length; i++) { | |
callbackArgs.push(e[argsMap[i]]); | |
} | |
} | |
if (typeof argsMap == "function") { | |
callbackArgs = argsMap(newEventName, e, target); | |
if (!callbackArgs) { | |
return; | |
} | |
} | |
if (!argsMap) { | |
callbackArgs = [e]; | |
} | |
callbackArgs.unshift(defaultScope || target); | |
if (callback.apply(scope || defaultScope || target, callbackArgs) === false) { | |
e.stopImmediatePropagation(); | |
} | |
} | |
target.on(newEventName, patchedEventCallback, prepend); | |
var handlers = { | |
original: callback, | |
patched: patchedEventCallback | |
}; | |
cbs.push(handlers); | |
return patchedEventCallback; | |
}; | |
this.addToTop = function (callback, scope) { | |
this.add(callback, scope, true); | |
}; | |
this.remove = function (callback) { | |
cbs.forEach(function (item, i) { | |
if (item.original === callback) { | |
cbs.splice(i, 1); | |
return target.off(newEventName, item.patched); | |
} | |
}); | |
return target.off(newEventName, callback); | |
}; | |
this.dispatch = function () { | |
target.fire(newEventName); | |
return true; | |
}; | |
} | |
tinymce.util.Dispatcher = Dispatcher; | |
tinymce.onBeforeUnload = new Dispatcher(tinymce, "BeforeUnload"); | |
tinymce.onAddEditor = new Dispatcher(tinymce, "AddEditor", "editor"); | |
tinymce.onRemoveEditor = new Dispatcher(tinymce, "RemoveEditor", "editor"); | |
tinymce.util.Cookie = { | |
get: noop, getHash: noop, remove: noop, set: noop, setHash: noop | |
}; | |
function patchEditor(editor) { | |
function translate(str) { | |
var prefix = editor.settings.language || "en"; | |
var prefixedStr = [prefix, str].join('.'); | |
var translatedStr = tinymce.i18n.translate(prefixedStr); | |
return prefixedStr !== translatedStr ? translatedStr : tinymce.i18n.translate(str); | |
} | |
function patchEditorEvents(oldEventNames, argsMap) { | |
tinymce.each(oldEventNames.split(" "), function (oldName) { | |
editor["on" + oldName] = new Dispatcher(editor, oldName, argsMap); | |
}); | |
} | |
function convertUndoEventArgs(type, event, target) { | |
return [ | |
event.level, | |
target | |
]; | |
} | |
function filterSelectionEvents(needsSelection) { | |
return function (type, e) { | |
if ((!e.selection && !needsSelection) || e.selection == needsSelection) { | |
return [e]; | |
} | |
}; | |
} | |
if (editor.controlManager) { | |
return; | |
} | |
function cmNoop() { | |
var obj = {}, methods = 'add addMenu addSeparator collapse createMenu destroy displayColor expand focus ' + | |
'getLength hasMenus hideMenu isActive isCollapsed isDisabled isRendered isSelected mark ' + | |
'postRender remove removeAll renderHTML renderMenu renderNode renderTo select selectByIndex ' + | |
'setActive setAriaProperty setColor setDisabled setSelected setState showMenu update'; | |
log('editor.controlManager.*'); | |
function _noop() { | |
return cmNoop(); | |
} | |
tinymce.each(methods.split(' '), function (method) { | |
obj[method] = _noop; | |
}); | |
return obj; | |
} | |
editor.controlManager = { | |
buttons: {}, | |
setDisabled: function (name, state) { | |
log("controlManager.setDisabled(..)"); | |
if (this.buttons[name]) { | |
this.buttons[name].disabled(state); | |
} | |
}, | |
setActive: function (name, state) { | |
log("controlManager.setActive(..)"); | |
if (this.buttons[name]) { | |
this.buttons[name].active(state); | |
} | |
}, | |
onAdd: new Dispatcher(), | |
onPostRender: new Dispatcher(), | |
add: function (obj) { | |
return obj; | |
}, | |
createButton: cmNoop, | |
createColorSplitButton: cmNoop, | |
createControl: cmNoop, | |
createDropMenu: cmNoop, | |
createListBox: cmNoop, | |
createMenuButton: cmNoop, | |
createSeparator: cmNoop, | |
createSplitButton: cmNoop, | |
createToolbar: cmNoop, | |
createToolbarGroup: cmNoop, | |
destroy: noop, | |
get: noop, | |
setControlType: cmNoop | |
}; | |
patchEditorEvents("PreInit BeforeRenderUI PostRender Load Init Remove Activate Deactivate", "editor"); | |
patchEditorEvents("Click MouseUp MouseDown DblClick KeyDown KeyUp KeyPress ContextMenu Paste Submit Reset"); | |
patchEditorEvents("BeforeExecCommand ExecCommand", "command ui value args"); // args.terminate not supported | |
patchEditorEvents("PreProcess PostProcess LoadContent SaveContent Change"); | |
patchEditorEvents("BeforeSetContent BeforeGetContent SetContent GetContent", filterSelectionEvents(false)); | |
patchEditorEvents("SetProgressState", "state time"); | |
patchEditorEvents("VisualAid", "element hasVisual"); | |
patchEditorEvents("Undo Redo", convertUndoEventArgs); | |
patchEditorEvents("NodeChange", function (type, e) { | |
return [ | |
editor.controlManager, | |
e.element, | |
editor.selection.isCollapsed(), | |
e | |
]; | |
}); | |
var originalAddButton = editor.addButton; | |
editor.addButton = function (name, settings) { | |
var originalOnPostRender; | |
function patchedPostRender() { | |
editor.controlManager.buttons[name] = this; | |
if (originalOnPostRender) { | |
return originalOnPostRender.apply(this, arguments); | |
} | |
} | |
for (var key in settings) { | |
if (key.toLowerCase() === "onpostrender") { | |
originalOnPostRender = settings[key]; | |
settings.onPostRender = patchedPostRender; | |
} | |
} | |
if (!originalOnPostRender) { | |
settings.onPostRender = patchedPostRender; | |
} | |
if (settings.title) { | |
settings.title = translate(settings.title); | |
} | |
return originalAddButton.call(this, name, settings); | |
}; | |
editor.on('init', function () { | |
var undoManager = editor.undoManager, selection = editor.selection; | |
undoManager.onUndo = new Dispatcher(editor, "Undo", convertUndoEventArgs, null, undoManager); | |
undoManager.onRedo = new Dispatcher(editor, "Redo", convertUndoEventArgs, null, undoManager); | |
undoManager.onBeforeAdd = new Dispatcher(editor, "BeforeAddUndo", null, undoManager); | |
undoManager.onAdd = new Dispatcher(editor, "AddUndo", null, undoManager); | |
selection.onBeforeGetContent = new Dispatcher(editor, "BeforeGetContent", filterSelectionEvents(true), selection); | |
selection.onGetContent = new Dispatcher(editor, "GetContent", filterSelectionEvents(true), selection); | |
selection.onBeforeSetContent = new Dispatcher(editor, "BeforeSetContent", filterSelectionEvents(true), selection); | |
selection.onSetContent = new Dispatcher(editor, "SetContent", filterSelectionEvents(true), selection); | |
}); | |
editor.on('BeforeRenderUI', function () { | |
var windowManager = editor.windowManager; | |
windowManager.onOpen = new Dispatcher(); | |
windowManager.onClose = new Dispatcher(); | |
windowManager.createInstance = function (className, a, b, c, d, e) { | |
log("windowManager.createInstance(..)"); | |
var constr = tinymce.resolve(className); | |
return new constr(a, b, c, d, e); | |
}; | |
}); | |
} | |
tinymce.on('SetupEditor', function (e) { | |
patchEditor(e.editor); | |
}); | |
tinymce.PluginManager.add("compat3x", patchEditor); | |
tinymce.addI18n = function (prefix, o) { | |
var I18n = tinymce.util.I18n, each = tinymce.each; | |
if (typeof prefix == "string" && prefix.indexOf('.') === -1) { | |
I18n.add(prefix, o); | |
return; | |
} | |
if (!tinymce.is(prefix, 'string')) { | |
each(prefix, function (o, lc) { | |
each(o, function (o, g) { | |
each(o, function (o, k) { | |
if (g === 'common') { | |
I18n.data[lc + '.' + k] = o; | |
} else { | |
I18n.data[lc + '.' + g + '.' + k] = o; | |
} | |
}); | |
}); | |
}); | |
} else { | |
each(o, function (o, k) { | |
I18n.data[prefix + '.' + k] = o; | |
}); | |
} | |
}; | |
})(tinymce); | |