Subversion Repositories oidplus

Rev

Rev 1422 | View as "text/javascript" | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /**
  2.  * Copyright (c) Tiny Technologies, Inc. All rights reserved.
  3.  * Licensed under the LGPL or a commercial license.
  4.  * For LGPL see License.txt in the project root for license information.
  5.  * For commercial licenses see https://www.tiny.cloud/
  6.  *
  7.  * Version: 5.10.9 (2023-11-15)
  8.  */
  9. (function () {
  10.     'use strict';
  11.  
  12.     var global$3 = tinymce.util.Tools.resolve('tinymce.PluginManager');
  13.  
  14.     var eq = function (t) {
  15.       return function (a) {
  16.         return t === a;
  17.       };
  18.     };
  19.     var isNull = eq(null);
  20.  
  21.     var noop = function () {
  22.     };
  23.     var constant = function (value) {
  24.       return function () {
  25.         return value;
  26.       };
  27.     };
  28.     var identity = function (x) {
  29.       return x;
  30.     };
  31.     var never = constant(false);
  32.     var always = constant(true);
  33.  
  34.     var none = function () {
  35.       return NONE;
  36.     };
  37.     var NONE = function () {
  38.       var call = function (thunk) {
  39.         return thunk();
  40.       };
  41.       var id = identity;
  42.       var me = {
  43.         fold: function (n, _s) {
  44.           return n();
  45.         },
  46.         isSome: never,
  47.         isNone: always,
  48.         getOr: id,
  49.         getOrThunk: call,
  50.         getOrDie: function (msg) {
  51.           throw new Error(msg || 'error: getOrDie called on none.');
  52.         },
  53.         getOrNull: constant(null),
  54.         getOrUndefined: constant(undefined),
  55.         or: id,
  56.         orThunk: call,
  57.         map: none,
  58.         each: noop,
  59.         bind: none,
  60.         exists: never,
  61.         forall: always,
  62.         filter: function () {
  63.           return none();
  64.         },
  65.         toArray: function () {
  66.           return [];
  67.         },
  68.         toString: constant('none()')
  69.       };
  70.       return me;
  71.     }();
  72.     var some = function (a) {
  73.       var constant_a = constant(a);
  74.       var self = function () {
  75.         return me;
  76.       };
  77.       var bind = function (f) {
  78.         return f(a);
  79.       };
  80.       var me = {
  81.         fold: function (n, s) {
  82.           return s(a);
  83.         },
  84.         isSome: always,
  85.         isNone: never,
  86.         getOr: constant_a,
  87.         getOrThunk: constant_a,
  88.         getOrDie: constant_a,
  89.         getOrNull: constant_a,
  90.         getOrUndefined: constant_a,
  91.         or: self,
  92.         orThunk: self,
  93.         map: function (f) {
  94.           return some(f(a));
  95.         },
  96.         each: function (f) {
  97.           f(a);
  98.         },
  99.         bind: bind,
  100.         exists: bind,
  101.         forall: bind,
  102.         filter: function (f) {
  103.           return f(a) ? me : NONE;
  104.         },
  105.         toArray: function () {
  106.           return [a];
  107.         },
  108.         toString: function () {
  109.           return 'some(' + a + ')';
  110.         }
  111.       };
  112.       return me;
  113.     };
  114.     var from = function (value) {
  115.       return value === null || value === undefined ? NONE : some(value);
  116.     };
  117.     var Optional = {
  118.       some: some,
  119.       none: none,
  120.       from: from
  121.     };
  122.  
  123.     var exists = function (xs, pred) {
  124.       for (var i = 0, len = xs.length; i < len; i++) {
  125.         var x = xs[i];
  126.         if (pred(x, i)) {
  127.           return true;
  128.         }
  129.       }
  130.       return false;
  131.     };
  132.     var map$1 = function (xs, f) {
  133.       var len = xs.length;
  134.       var r = new Array(len);
  135.       for (var i = 0; i < len; i++) {
  136.         var x = xs[i];
  137.         r[i] = f(x, i);
  138.       }
  139.       return r;
  140.     };
  141.     var each$1 = function (xs, f) {
  142.       for (var i = 0, len = xs.length; i < len; i++) {
  143.         var x = xs[i];
  144.         f(x, i);
  145.       }
  146.     };
  147.  
  148.     var Cell = function (initial) {
  149.       var value = initial;
  150.       var get = function () {
  151.         return value;
  152.       };
  153.       var set = function (v) {
  154.         value = v;
  155.       };
  156.       return {
  157.         get: get,
  158.         set: set
  159.       };
  160.     };
  161.  
  162.     var last = function (fn, rate) {
  163.       var timer = null;
  164.       var cancel = function () {
  165.         if (!isNull(timer)) {
  166.           clearTimeout(timer);
  167.           timer = null;
  168.         }
  169.       };
  170.       var throttle = function () {
  171.         var args = [];
  172.         for (var _i = 0; _i < arguments.length; _i++) {
  173.           args[_i] = arguments[_i];
  174.         }
  175.         cancel();
  176.         timer = setTimeout(function () {
  177.           timer = null;
  178.           fn.apply(null, args);
  179.         }, rate);
  180.       };
  181.       return {
  182.         cancel: cancel,
  183.         throttle: throttle
  184.       };
  185.     };
  186.  
  187.     var insertEmoticon = function (editor, ch) {
  188.       editor.insertContent(ch);
  189.     };
  190.  
  191.     var __assign = function () {
  192.       __assign = Object.assign || function __assign(t) {
  193.         for (var s, i = 1, n = arguments.length; i < n; i++) {
  194.           s = arguments[i];
  195.           for (var p in s)
  196.             if (Object.prototype.hasOwnProperty.call(s, p))
  197.               t[p] = s[p];
  198.         }
  199.         return t;
  200.       };
  201.       return __assign.apply(this, arguments);
  202.     };
  203.  
  204.     var keys = Object.keys;
  205.     var hasOwnProperty = Object.hasOwnProperty;
  206.     var each = function (obj, f) {
  207.       var props = keys(obj);
  208.       for (var k = 0, len = props.length; k < len; k++) {
  209.         var i = props[k];
  210.         var x = obj[i];
  211.         f(x, i);
  212.       }
  213.     };
  214.     var map = function (obj, f) {
  215.       return tupleMap(obj, function (x, i) {
  216.         return {
  217.           k: i,
  218.           v: f(x, i)
  219.         };
  220.       });
  221.     };
  222.     var tupleMap = function (obj, f) {
  223.       var r = {};
  224.       each(obj, function (x, i) {
  225.         var tuple = f(x, i);
  226.         r[tuple.k] = tuple.v;
  227.       });
  228.       return r;
  229.     };
  230.     var has = function (obj, key) {
  231.       return hasOwnProperty.call(obj, key);
  232.     };
  233.  
  234.     var shallow = function (old, nu) {
  235.       return nu;
  236.     };
  237.     var baseMerge = function (merger) {
  238.       return function () {
  239.         var objects = [];
  240.         for (var _i = 0; _i < arguments.length; _i++) {
  241.           objects[_i] = arguments[_i];
  242.         }
  243.         if (objects.length === 0) {
  244.           throw new Error('Can\'t merge zero objects');
  245.         }
  246.         var ret = {};
  247.         for (var j = 0; j < objects.length; j++) {
  248.           var curObject = objects[j];
  249.           for (var key in curObject) {
  250.             if (has(curObject, key)) {
  251.               ret[key] = merger(ret[key], curObject[key]);
  252.             }
  253.           }
  254.         }
  255.         return ret;
  256.       };
  257.     };
  258.     var merge = baseMerge(shallow);
  259.  
  260.     var singleton = function (doRevoke) {
  261.       var subject = Cell(Optional.none());
  262.       var revoke = function () {
  263.         return subject.get().each(doRevoke);
  264.       };
  265.       var clear = function () {
  266.         revoke();
  267.         subject.set(Optional.none());
  268.       };
  269.       var isSet = function () {
  270.         return subject.get().isSome();
  271.       };
  272.       var get = function () {
  273.         return subject.get();
  274.       };
  275.       var set = function (s) {
  276.         revoke();
  277.         subject.set(Optional.some(s));
  278.       };
  279.       return {
  280.         clear: clear,
  281.         isSet: isSet,
  282.         get: get,
  283.         set: set
  284.       };
  285.     };
  286.     var value = function () {
  287.       var subject = singleton(noop);
  288.       var on = function (f) {
  289.         return subject.get().each(f);
  290.       };
  291.       return __assign(__assign({}, subject), { on: on });
  292.     };
  293.  
  294.     var checkRange = function (str, substr, start) {
  295.       return substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
  296.     };
  297.     var contains = function (str, substr) {
  298.       return str.indexOf(substr) !== -1;
  299.     };
  300.     var startsWith = function (str, prefix) {
  301.       return checkRange(str, prefix, 0);
  302.     };
  303.  
  304.     var global$2 = tinymce.util.Tools.resolve('tinymce.Resource');
  305.  
  306.     var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  307.  
  308.     var global = tinymce.util.Tools.resolve('tinymce.util.Promise');
  309.  
  310.     var DEFAULT_ID = 'tinymce.plugins.emoticons';
  311.     var getEmoticonDatabase = function (editor) {
  312.       return editor.getParam('emoticons_database', 'emojis', 'string');
  313.     };
  314.     var getEmoticonDatabaseUrl = function (editor, pluginUrl) {
  315.       var database = getEmoticonDatabase(editor);
  316.       return editor.getParam('emoticons_database_url', pluginUrl + '/js/' + database + editor.suffix + '.js', 'string');
  317.     };
  318.     var getEmoticonDatabaseId = function (editor) {
  319.       return editor.getParam('emoticons_database_id', DEFAULT_ID, 'string');
  320.     };
  321.     var getAppendedEmoticons = function (editor) {
  322.       return editor.getParam('emoticons_append', {}, 'object');
  323.     };
  324.     var getEmotionsImageUrl = function (editor) {
  325.       return editor.getParam('emoticons_images_url', 'https://twemoji.maxcdn.com/v/13.0.1/72x72/', 'string');
  326.     };
  327.  
  328.     var ALL_CATEGORY = 'All';
  329.     var categoryNameMap = {
  330.       symbols: 'Symbols',
  331.       people: 'People',
  332.       animals_and_nature: 'Animals and Nature',
  333.       food_and_drink: 'Food and Drink',
  334.       activity: 'Activity',
  335.       travel_and_places: 'Travel and Places',
  336.       objects: 'Objects',
  337.       flags: 'Flags',
  338.       user: 'User Defined'
  339.     };
  340.     var translateCategory = function (categories, name) {
  341.       return has(categories, name) ? categories[name] : name;
  342.     };
  343.     var getUserDefinedEmoticons = function (editor) {
  344.       var userDefinedEmoticons = getAppendedEmoticons(editor);
  345.       return map(userDefinedEmoticons, function (value) {
  346.         return __assign({
  347.           keywords: [],
  348.           category: 'user'
  349.         }, value);
  350.       });
  351.     };
  352.     var initDatabase = function (editor, databaseUrl, databaseId) {
  353.       var categories = value();
  354.       var all = value();
  355.       var emojiImagesUrl = getEmotionsImageUrl(editor);
  356.       var getEmoji = function (lib) {
  357.         if (startsWith(lib.char, '<img')) {
  358.           return lib.char.replace(/src="([^"]+)"/, function (match, url) {
  359.             return 'src="' + emojiImagesUrl + url + '"';
  360.           });
  361.         } else {
  362.           return lib.char;
  363.         }
  364.       };
  365.       var processEmojis = function (emojis) {
  366.         var cats = {};
  367.         var everything = [];
  368.         each(emojis, function (lib, title) {
  369.           var entry = {
  370.             title: title,
  371.             keywords: lib.keywords,
  372.             char: getEmoji(lib),
  373.             category: translateCategory(categoryNameMap, lib.category)
  374.           };
  375.           var current = cats[entry.category] !== undefined ? cats[entry.category] : [];
  376.           cats[entry.category] = current.concat([entry]);
  377.           everything.push(entry);
  378.         });
  379.         categories.set(cats);
  380.         all.set(everything);
  381.       };
  382.       editor.on('init', function () {
  383.         global$2.load(databaseId, databaseUrl).then(function (emojis) {
  384.           var userEmojis = getUserDefinedEmoticons(editor);
  385.           processEmojis(merge(emojis, userEmojis));
  386.         }, function (err) {
  387.           console.log('Failed to load emoticons: ' + err);
  388.           categories.set({});
  389.           all.set([]);
  390.         });
  391.       });
  392.       var listCategory = function (category) {
  393.         if (category === ALL_CATEGORY) {
  394.           return listAll();
  395.         }
  396.         return categories.get().bind(function (cats) {
  397.           return Optional.from(cats[category]);
  398.         }).getOr([]);
  399.       };
  400.       var listAll = function () {
  401.         return all.get().getOr([]);
  402.       };
  403.       var listCategories = function () {
  404.         return [ALL_CATEGORY].concat(keys(categories.get().getOr({})));
  405.       };
  406.       var waitForLoad = function () {
  407.         if (hasLoaded()) {
  408.           return global.resolve(true);
  409.         } else {
  410.           return new global(function (resolve, reject) {
  411.             var numRetries = 15;
  412.             var interval = global$1.setInterval(function () {
  413.               if (hasLoaded()) {
  414.                 global$1.clearInterval(interval);
  415.                 resolve(true);
  416.               } else {
  417.                 numRetries--;
  418.                 if (numRetries < 0) {
  419.                   console.log('Could not load emojis from url: ' + databaseUrl);
  420.                   global$1.clearInterval(interval);
  421.                   reject(false);
  422.                 }
  423.               }
  424.             }, 100);
  425.           });
  426.         }
  427.       };
  428.       var hasLoaded = function () {
  429.         return categories.isSet() && all.isSet();
  430.       };
  431.       return {
  432.         listCategories: listCategories,
  433.         hasLoaded: hasLoaded,
  434.         waitForLoad: waitForLoad,
  435.         listAll: listAll,
  436.         listCategory: listCategory
  437.       };
  438.     };
  439.  
  440.     var emojiMatches = function (emoji, lowerCasePattern) {
  441.       return contains(emoji.title.toLowerCase(), lowerCasePattern) || exists(emoji.keywords, function (k) {
  442.         return contains(k.toLowerCase(), lowerCasePattern);
  443.       });
  444.     };
  445.     var emojisFrom = function (list, pattern, maxResults) {
  446.       var matches = [];
  447.       var lowerCasePattern = pattern.toLowerCase();
  448.       var reachedLimit = maxResults.fold(function () {
  449.         return never;
  450.       }, function (max) {
  451.         return function (size) {
  452.           return size >= max;
  453.         };
  454.       });
  455.       for (var i = 0; i < list.length; i++) {
  456.         if (pattern.length === 0 || emojiMatches(list[i], lowerCasePattern)) {
  457.           matches.push({
  458.             value: list[i].char,
  459.             text: list[i].title,
  460.             icon: list[i].char
  461.           });
  462.           if (reachedLimit(matches.length)) {
  463.             break;
  464.           }
  465.         }
  466.       }
  467.       return matches;
  468.     };
  469.  
  470.     var patternName = 'pattern';
  471.     var open = function (editor, database) {
  472.       var initialState = {
  473.         pattern: '',
  474.         results: emojisFrom(database.listAll(), '', Optional.some(300))
  475.       };
  476.       var currentTab = Cell(ALL_CATEGORY);
  477.       var scan = function (dialogApi) {
  478.         var dialogData = dialogApi.getData();
  479.         var category = currentTab.get();
  480.         var candidates = database.listCategory(category);
  481.         var results = emojisFrom(candidates, dialogData[patternName], category === ALL_CATEGORY ? Optional.some(300) : Optional.none());
  482.         dialogApi.setData({ results: results });
  483.       };
  484.       var updateFilter = last(function (dialogApi) {
  485.         scan(dialogApi);
  486.       }, 200);
  487.       var searchField = {
  488.         label: 'Search',
  489.         type: 'input',
  490.         name: patternName
  491.       };
  492.       var resultsField = {
  493.         type: 'collection',
  494.         name: 'results'
  495.       };
  496.       var getInitialState = function () {
  497.         var body = {
  498.           type: 'tabpanel',
  499.           tabs: map$1(database.listCategories(), function (cat) {
  500.             return {
  501.               title: cat,
  502.               name: cat,
  503.               items: [
  504.                 searchField,
  505.                 resultsField
  506.               ]
  507.             };
  508.           })
  509.         };
  510.         return {
  511.           title: 'Emoticons',
  512.           size: 'normal',
  513.           body: body,
  514.           initialData: initialState,
  515.           onTabChange: function (dialogApi, details) {
  516.             currentTab.set(details.newTabName);
  517.             updateFilter.throttle(dialogApi);
  518.           },
  519.           onChange: updateFilter.throttle,
  520.           onAction: function (dialogApi, actionData) {
  521.             if (actionData.name === 'results') {
  522.               insertEmoticon(editor, actionData.value);
  523.               dialogApi.close();
  524.             }
  525.           },
  526.           buttons: [{
  527.               type: 'cancel',
  528.               text: 'Close',
  529.               primary: true
  530.             }]
  531.         };
  532.       };
  533.       var dialogApi = editor.windowManager.open(getInitialState());
  534.       dialogApi.focus(patternName);
  535.       if (!database.hasLoaded()) {
  536.         dialogApi.block('Loading emoticons...');
  537.         database.waitForLoad().then(function () {
  538.           dialogApi.redial(getInitialState());
  539.           updateFilter.throttle(dialogApi);
  540.           dialogApi.focus(patternName);
  541.           dialogApi.unblock();
  542.         }).catch(function (_err) {
  543.           dialogApi.redial({
  544.             title: 'Emoticons',
  545.             body: {
  546.               type: 'panel',
  547.               items: [{
  548.                   type: 'alertbanner',
  549.                   level: 'error',
  550.                   icon: 'warning',
  551.                   text: '<p>Could not load emoticons</p>'
  552.                 }]
  553.             },
  554.             buttons: [{
  555.                 type: 'cancel',
  556.                 text: 'Close',
  557.                 primary: true
  558.               }],
  559.             initialData: {
  560.               pattern: '',
  561.               results: []
  562.             }
  563.           });
  564.           dialogApi.focus(patternName);
  565.           dialogApi.unblock();
  566.         });
  567.       }
  568.     };
  569.  
  570.     var register$1 = function (editor, database) {
  571.       editor.addCommand('mceEmoticons', function () {
  572.         return open(editor, database);
  573.       });
  574.     };
  575.  
  576.     var setup = function (editor) {
  577.       editor.on('PreInit', function () {
  578.         editor.parser.addAttributeFilter('data-emoticon', function (nodes) {
  579.           each$1(nodes, function (node) {
  580.             node.attr('data-mce-resize', 'false');
  581.             node.attr('data-mce-placeholder', '1');
  582.           });
  583.         });
  584.       });
  585.     };
  586.  
  587.     var init = function (editor, database) {
  588.       editor.ui.registry.addAutocompleter('emoticons', {
  589.         ch: ':',
  590.         columns: 'auto',
  591.         minChars: 2,
  592.         fetch: function (pattern, maxResults) {
  593.           return database.waitForLoad().then(function () {
  594.             var candidates = database.listAll();
  595.             return emojisFrom(candidates, pattern, Optional.some(maxResults));
  596.           });
  597.         },
  598.         onAction: function (autocompleteApi, rng, value) {
  599.           editor.selection.setRng(rng);
  600.           editor.insertContent(value);
  601.           autocompleteApi.hide();
  602.         }
  603.       });
  604.     };
  605.  
  606.     var register = function (editor) {
  607.       var onAction = function () {
  608.         return editor.execCommand('mceEmoticons');
  609.       };
  610.       editor.ui.registry.addButton('emoticons', {
  611.         tooltip: 'Emoticons',
  612.         icon: 'emoji',
  613.         onAction: onAction
  614.       });
  615.       editor.ui.registry.addMenuItem('emoticons', {
  616.         text: 'Emoticons...',
  617.         icon: 'emoji',
  618.         onAction: onAction
  619.       });
  620.     };
  621.  
  622.     function Plugin () {
  623.       global$3.add('emoticons', function (editor, pluginUrl) {
  624.         var databaseUrl = getEmoticonDatabaseUrl(editor, pluginUrl);
  625.         var databaseId = getEmoticonDatabaseId(editor);
  626.         var database = initDatabase(editor, databaseUrl, databaseId);
  627.         register$1(editor, database);
  628.         register(editor);
  629.         init(editor, database);
  630.         setup(editor);
  631.       });
  632.     }
  633.  
  634.     Plugin();
  635.  
  636. }());
  637.