JAVASCRIPT 85
Plugin.js Guest on 16th June 2020 06:50:01 AM
  1. /**
  2.  * plugin.js
  3.  *
  4.  * Released under LGPL License.
  5.  * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
  6.  *
  7.  * License: http://www.tinymce.com/license
  8.  * Contributing: http://www.tinymce.com/contributing
  9.  */
  10.  
  11. /*global tinymce:true, console:true */
  12. /*eslint no-console:0, new-cap:0 */
  13.  
  14. /**
  15.  * This plugin adds missing events form the 4.x API back. Not every event is
  16.  * properly supported but most things should work.
  17.  *
  18.  * Unsupported things:
  19.  *  - No editor.onEvent
  20.  *  - Can't cancel execCommands with beforeExecCommand
  21.  */
  22. (function (tinymce) {
  23.   var reported;
  24.  
  25.   function noop() {
  26.   }
  27.  
  28.   function log(apiCall) {
  29.     if (!reported && window && window.console) {
  30.       reported = true;
  31.       console.log("Deprecated TinyMCE API call: " + apiCall);
  32.     }
  33.   }
  34.  
  35.   function Dispatcher(target, newEventName, argsMap, defaultScope) {
  36.     target = target || this;
  37.     var cbs = [];
  38.  
  39.     if (!newEventName) {
  40.       this.add = this.addToTop = this.remove = this.dispatch = noop;
  41.       return;
  42.     }
  43.  
  44.     this.add = function (callback, scope, prepend) {
  45.       log('<target>.on' + newEventName + ".add(..)");
  46.  
  47.       // Convert callback({arg1:x, arg2:x}) -> callback(arg1, arg2)
  48.       function patchedEventCallback(e) {
  49.         var callbackArgs = [];
  50.  
  51.         if (typeof argsMap == "string") {
  52.           argsMap = argsMap.split(" ");
  53.         }
  54.  
  55.         if (argsMap && typeof argsMap !== "function") {
  56.           for (var i = 0; i < argsMap.length; i++) {
  57.             callbackArgs.push(e[argsMap[i]]);
  58.           }
  59.         }
  60.  
  61.         if (typeof argsMap == "function") {
  62.           callbackArgs = argsMap(newEventName, e, target);
  63.           if (!callbackArgs) {
  64.             return;
  65.           }
  66.         }
  67.  
  68.         if (!argsMap) {
  69.           callbackArgs = [e];
  70.         }
  71.  
  72.         callbackArgs.unshift(defaultScope || target);
  73.  
  74.         if (callback.apply(scope || defaultScope || target, callbackArgs) === false) {
  75.           e.stopImmediatePropagation();
  76.         }
  77.       }
  78.  
  79.       target.on(newEventName, patchedEventCallback, prepend);
  80.  
  81.       var handlers = {
  82.         original: callback,
  83.         patched: patchedEventCallback
  84.       };
  85.  
  86.       cbs.push(handlers);
  87.       return patchedEventCallback;
  88.     };
  89.  
  90.     this.addToTop = function (callback, scope) {
  91.       this.add(callback, scope, true);
  92.     };
  93.  
  94.     this.remove = function (callback) {
  95.       cbs.forEach(function (item, i) {
  96.         if (item.original === callback) {
  97.           cbs.splice(i, 1);
  98.           return target.off(newEventName, item.patched);
  99.         }
  100.       });
  101.  
  102.       return target.off(newEventName, callback);
  103.     };
  104.  
  105.     this.dispatch = function () {
  106.       target.fire(newEventName);
  107.       return true;
  108.     };
  109.   }
  110.  
  111.   tinymce.util.Dispatcher = Dispatcher;
  112.   tinymce.onBeforeUnload = new Dispatcher(tinymce, "BeforeUnload");
  113.   tinymce.onAddEditor = new Dispatcher(tinymce, "AddEditor", "editor");
  114.   tinymce.onRemoveEditor = new Dispatcher(tinymce, "RemoveEditor", "editor");
  115.  
  116.   tinymce.util.Cookie = {
  117.     get: noop, getHash: noop, remove: noop, set: noop, setHash: noop
  118.   };
  119.  
  120.   function patchEditor(editor) {
  121.  
  122.     function translate(str) {
  123.       var prefix = editor.settings.language || "en";
  124.       var prefixedStr = [prefix, str].join('.');
  125.       var translatedStr = tinymce.i18n.translate(prefixedStr);
  126.  
  127.       return prefixedStr !== translatedStr ? translatedStr : tinymce.i18n.translate(str);
  128.     }
  129.  
  130.     function patchEditorEvents(oldEventNames, argsMap) {
  131.       tinymce.each(oldEventNames.split(" "), function (oldName) {
  132.         editor["on" + oldName] = new Dispatcher(editor, oldName, argsMap);
  133.       });
  134.     }
  135.  
  136.     function convertUndoEventArgs(type, event, target) {
  137.       return [
  138.         event.level,
  139.         target
  140.       ];
  141.     }
  142.  
  143.     function filterSelectionEvents(needsSelection) {
  144.       return function (type, e) {
  145.         if ((!e.selection && !needsSelection) || e.selection == needsSelection) {
  146.           return [e];
  147.         }
  148.       };
  149.     }
  150.  
  151.     if (editor.controlManager) {
  152.       return;
  153.     }
  154.  
  155.     function cmNoop() {
  156.       var obj = {}, methods = 'add addMenu addSeparator collapse createMenu destroy displayColor expand focus ' +
  157.         'getLength hasMenus hideMenu isActive isCollapsed isDisabled isRendered isSelected mark ' +
  158.         'postRender remove removeAll renderHTML renderMenu renderNode renderTo select selectByIndex ' +
  159.         'setActive setAriaProperty setColor setDisabled setSelected setState showMenu update';
  160.  
  161.       log('editor.controlManager.*');
  162.  
  163.       function _noop() {
  164.         return cmNoop();
  165.       }
  166.  
  167.       tinymce.each(methods.split(' '), function (method) {
  168.         obj[method] = _noop;
  169.       });
  170.  
  171.       return obj;
  172.     }
  173.  
  174.     editor.controlManager = {
  175.       buttons: {},
  176.  
  177.       setDisabled: function (name, state) {
  178.         log("controlManager.setDisabled(..)");
  179.  
  180.         if (this.buttons[name]) {
  181.           this.buttons[name].disabled(state);
  182.         }
  183.       },
  184.  
  185.       setActive: function (name, state) {
  186.         log("controlManager.setActive(..)");
  187.  
  188.         if (this.buttons[name]) {
  189.           this.buttons[name].active(state);
  190.         }
  191.       },
  192.  
  193.       onAdd: new Dispatcher(),
  194.       onPostRender: new Dispatcher(),
  195.  
  196.       add: function (obj) {
  197.         return obj;
  198.       },
  199.       createButton: cmNoop,
  200.       createColorSplitButton: cmNoop,
  201.       createControl: cmNoop,
  202.       createDropMenu: cmNoop,
  203.       createListBox: cmNoop,
  204.       createMenuButton: cmNoop,
  205.       createSeparator: cmNoop,
  206.       createSplitButton: cmNoop,
  207.       createToolbar: cmNoop,
  208.       createToolbarGroup: cmNoop,
  209.       destroy: noop,
  210.       get: noop,
  211.       setControlType: cmNoop
  212.     };
  213.  
  214.     patchEditorEvents("PreInit BeforeRenderUI PostRender Load Init Remove Activate Deactivate", "editor");
  215.     patchEditorEvents("Click MouseUp MouseDown DblClick KeyDown KeyUp KeyPress ContextMenu Paste Submit Reset");
  216.     patchEditorEvents("BeforeExecCommand ExecCommand", "command ui value args"); // args.terminate not supported
  217.     patchEditorEvents("PreProcess PostProcess LoadContent SaveContent Change");
  218.     patchEditorEvents("BeforeSetContent BeforeGetContent SetContent GetContent", filterSelectionEvents(false));
  219.     patchEditorEvents("SetProgressState", "state time");
  220.     patchEditorEvents("VisualAid", "element hasVisual");
  221.     patchEditorEvents("Undo Redo", convertUndoEventArgs);
  222.  
  223.     patchEditorEvents("NodeChange", function (type, e) {
  224.       return [
  225.         editor.controlManager,
  226.         e.element,
  227.         editor.selection.isCollapsed(),
  228.         e
  229.       ];
  230.     });
  231.  
  232.     var originalAddButton = editor.addButton;
  233.     editor.addButton = function (name, settings) {
  234.       var originalOnPostRender;
  235.  
  236.       function patchedPostRender() {
  237.         editor.controlManager.buttons[name] = this;
  238.  
  239.         if (originalOnPostRender) {
  240.           return originalOnPostRender.apply(this, arguments);
  241.         }
  242.       }
  243.  
  244.       for (var key in settings) {
  245.         if (key.toLowerCase() === "onpostrender") {
  246.           originalOnPostRender = settings[key];
  247.           settings.onPostRender = patchedPostRender;
  248.         }
  249.       }
  250.  
  251.       if (!originalOnPostRender) {
  252.         settings.onPostRender = patchedPostRender;
  253.       }
  254.  
  255.       if (settings.title) {
  256.         settings.title = translate(settings.title);
  257.       }
  258.  
  259.       return originalAddButton.call(this, name, settings);
  260.     };
  261.  
  262.     editor.on('init', function () {
  263.       var undoManager = editor.undoManager, selection = editor.selection;
  264.  
  265.       undoManager.onUndo = new Dispatcher(editor, "Undo", convertUndoEventArgs, null, undoManager);
  266.       undoManager.onRedo = new Dispatcher(editor, "Redo", convertUndoEventArgs, null, undoManager);
  267.       undoManager.onBeforeAdd = new Dispatcher(editor, "BeforeAddUndo", null, undoManager);
  268.       undoManager.onAdd = new Dispatcher(editor, "AddUndo", null, undoManager);
  269.  
  270.       selection.onBeforeGetContent = new Dispatcher(editor, "BeforeGetContent", filterSelectionEvents(true), selection);
  271.       selection.onGetContent = new Dispatcher(editor, "GetContent", filterSelectionEvents(true), selection);
  272.       selection.onBeforeSetContent = new Dispatcher(editor, "BeforeSetContent", filterSelectionEvents(true), selection);
  273.       selection.onSetContent = new Dispatcher(editor, "SetContent", filterSelectionEvents(true), selection);
  274.     });
  275.  
  276.     editor.on('BeforeRenderUI', function () {
  277.       var windowManager = editor.windowManager;
  278.  
  279.       windowManager.onOpen = new Dispatcher();
  280.       windowManager.onClose = new Dispatcher();
  281.       windowManager.createInstance = function (className, a, b, c, d, e) {
  282.         log("windowManager.createInstance(..)");
  283.  
  284.         var constr = tinymce.resolve(className);
  285.         return new constr(a, b, c, d, e);
  286.       };
  287.     });
  288.   }
  289.  
  290.   tinymce.on('SetupEditor', function (e) {
  291.     patchEditor(e.editor);
  292.   });
  293.  
  294.   tinymce.PluginManager.add("compat3x", patchEditor);
  295.  
  296.   tinymce.addI18n = function (prefix, o) {
  297.     var I18n = tinymce.util.I18n, each = tinymce.each;
  298.  
  299.     if (typeof prefix == "string" && prefix.indexOf('.') === -1) {
  300.       I18n.add(prefix, o);
  301.       return;
  302.     }
  303.  
  304.     if (!tinymce.is(prefix, 'string')) {
  305.       each(prefix, function (o, lc) {
  306.         each(o, function (o, g) {
  307.           each(o, function (o, k) {
  308.             if (g === 'common') {
  309.               I18n.data[lc + '.' + k] = o;
  310.             } else {
  311.               I18n.data[lc + '.' + g + '.' + k] = o;
  312.             }
  313.           });
  314.         });
  315.       });
  316.     } else {
  317.       each(o, function (o, k) {
  318.         I18n.data[prefix + '.' + k] = o;
  319.       });
  320.     }
  321.   };
  322. })(tinymce);

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.