Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
/*** TinyMCE version 6.8.3 (2024-02-08)*/(function () {'use strict';var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');const eq = t => a => t === a;const isNull = eq(null);const isUndefined = eq(undefined);const isNullable = a => a === null || a === undefined;const isNonNullable = a => !isNullable(a);const noop = () => {};const constant = value => {return () => {return value;};};const never = constant(false);class Optional {constructor(tag, value) {this.tag = tag;this.value = value;}static some(value) {return new Optional(true, value);}static none() {return Optional.singletonNone;}fold(onNone, onSome) {if (this.tag) {return onSome(this.value);} else {return onNone();}}isSome() {return this.tag;}isNone() {return !this.tag;}map(mapper) {if (this.tag) {return Optional.some(mapper(this.value));} else {return Optional.none();}}bind(binder) {if (this.tag) {return binder(this.value);} else {return Optional.none();}}exists(predicate) {return this.tag && predicate(this.value);}forall(predicate) {return !this.tag || predicate(this.value);}filter(predicate) {if (!this.tag || predicate(this.value)) {return this;} else {return Optional.none();}}getOr(replacement) {return this.tag ? this.value : replacement;}or(replacement) {return this.tag ? this : replacement;}getOrThunk(thunk) {return this.tag ? this.value : thunk();}orThunk(thunk) {return this.tag ? this : thunk();}getOrDie(message) {if (!this.tag) {throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');} else {return this.value;}}static from(value) {return isNonNullable(value) ? Optional.some(value) : Optional.none();}getOrNull() {return this.tag ? this.value : null;}getOrUndefined() {return this.value;}each(worker) {if (this.tag) {worker(this.value);}}toArray() {return this.tag ? [this.value] : [];}toString() {return this.tag ? `some(${ this.value })` : 'none()';}}Optional.singletonNone = new Optional(false);const exists = (xs, pred) => {for (let i = 0, len = xs.length; i < len; i++) {const x = xs[i];if (pred(x, i)) {return true;}}return false;};const map$1 = (xs, f) => {const len = xs.length;const r = new Array(len);for (let i = 0; i < len; i++) {const x = xs[i];r[i] = f(x, i);}return r;};const each$1 = (xs, f) => {for (let i = 0, len = xs.length; i < len; i++) {const x = xs[i];f(x, i);}};const Cell = initial => {let value = initial;const get = () => {return value;};const set = v => {value = v;};return {get,set};};const last = (fn, rate) => {let timer = null;const cancel = () => {if (!isNull(timer)) {clearTimeout(timer);timer = null;}};const throttle = (...args) => {cancel();timer = setTimeout(() => {timer = null;fn.apply(null, args);}, rate);};return {cancel,throttle};};const insertEmoticon = (editor, ch) => {editor.insertContent(ch);};const keys = Object.keys;const hasOwnProperty = Object.hasOwnProperty;const each = (obj, f) => {const props = keys(obj);for (let k = 0, len = props.length; k < len; k++) {const i = props[k];const x = obj[i];f(x, i);}};const map = (obj, f) => {return tupleMap(obj, (x, i) => ({k: i,v: f(x, i)}));};const tupleMap = (obj, f) => {const r = {};each(obj, (x, i) => {const tuple = f(x, i);r[tuple.k] = tuple.v;});return r;};const has = (obj, key) => hasOwnProperty.call(obj, key);const shallow = (old, nu) => {return nu;};const baseMerge = merger => {return (...objects) => {if (objects.length === 0) {throw new Error(`Can't merge zero objects`);}const ret = {};for (let j = 0; j < objects.length; j++) {const curObject = objects[j];for (const key in curObject) {if (has(curObject, key)) {ret[key] = merger(ret[key], curObject[key]);}}}return ret;};};const merge = baseMerge(shallow);const singleton = doRevoke => {const subject = Cell(Optional.none());const revoke = () => subject.get().each(doRevoke);const clear = () => {revoke();subject.set(Optional.none());};const isSet = () => subject.get().isSome();const get = () => subject.get();const set = s => {revoke();subject.set(Optional.some(s));};return {clear,isSet,get,set};};const value = () => {const subject = singleton(noop);const on = f => subject.get().each(f);return {...subject,on};};const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;const contains = (str, substr, start = 0, end) => {const idx = str.indexOf(substr, start);if (idx !== -1) {return isUndefined(end) ? true : idx + substr.length <= end;} else {return false;}};const startsWith = (str, prefix) => {return checkRange(str, prefix, 0);};var global = tinymce.util.Tools.resolve('tinymce.Resource');const DEFAULT_ID = 'tinymce.plugins.emoticons';const option = name => editor => editor.options.get(name);const register$2 = (editor, pluginUrl) => {const registerOption = editor.options.register;registerOption('emoticons_database', {processor: 'string',default: 'emojis'});registerOption('emoticons_database_url', {processor: 'string',default: `${ pluginUrl }/js/${ getEmojiDatabase(editor) }${ editor.suffix }.js`});registerOption('emoticons_database_id', {processor: 'string',default: DEFAULT_ID});registerOption('emoticons_append', {processor: 'object',default: {}});registerOption('emoticons_images_url', {processor: 'string',default: 'https://twemoji.maxcdn.com/v/13.0.1/72x72/'});};const getEmojiDatabase = option('emoticons_database');const getEmojiDatabaseUrl = option('emoticons_database_url');const getEmojiDatabaseId = option('emoticons_database_id');const getAppendedEmoji = option('emoticons_append');const getEmojiImageUrl = option('emoticons_images_url');const ALL_CATEGORY = 'All';const categoryNameMap = {symbols: 'Symbols',people: 'People',animals_and_nature: 'Animals and Nature',food_and_drink: 'Food and Drink',activity: 'Activity',travel_and_places: 'Travel and Places',objects: 'Objects',flags: 'Flags',user: 'User Defined'};const translateCategory = (categories, name) => has(categories, name) ? categories[name] : name;const getUserDefinedEmoji = editor => {const userDefinedEmoticons = getAppendedEmoji(editor);return map(userDefinedEmoticons, value => ({keywords: [],category: 'user',...value}));};const initDatabase = (editor, databaseUrl, databaseId) => {const categories = value();const all = value();const emojiImagesUrl = getEmojiImageUrl(editor);const getEmoji = lib => {if (startsWith(lib.char, '<img')) {return lib.char.replace(/src="([^"]+)"/, (match, url) => `src="${ emojiImagesUrl }${ url }"`);} else {return lib.char;}};const processEmojis = emojis => {const cats = {};const everything = [];each(emojis, (lib, title) => {const entry = {title,keywords: lib.keywords,char: getEmoji(lib),category: translateCategory(categoryNameMap, lib.category)};const current = cats[entry.category] !== undefined ? cats[entry.category] : [];cats[entry.category] = current.concat([entry]);everything.push(entry);});categories.set(cats);all.set(everything);};editor.on('init', () => {global.load(databaseId, databaseUrl).then(emojis => {const userEmojis = getUserDefinedEmoji(editor);processEmojis(merge(emojis, userEmojis));}, err => {console.log(`Failed to load emojis: ${ err }`);categories.set({});all.set([]);});});const listCategory = category => {if (category === ALL_CATEGORY) {return listAll();}return categories.get().bind(cats => Optional.from(cats[category])).getOr([]);};const listAll = () => all.get().getOr([]);const listCategories = () => [ALL_CATEGORY].concat(keys(categories.get().getOr({})));const waitForLoad = () => {if (hasLoaded()) {return Promise.resolve(true);} else {return new Promise((resolve, reject) => {let numRetries = 15;const interval = setInterval(() => {if (hasLoaded()) {clearInterval(interval);resolve(true);} else {numRetries--;if (numRetries < 0) {console.log('Could not load emojis from url: ' + databaseUrl);clearInterval(interval);reject(false);}}}, 100);});}};const hasLoaded = () => categories.isSet() && all.isSet();return {listCategories,hasLoaded,waitForLoad,listAll,listCategory};};const emojiMatches = (emoji, lowerCasePattern) => contains(emoji.title.toLowerCase(), lowerCasePattern) || exists(emoji.keywords, k => contains(k.toLowerCase(), lowerCasePattern));const emojisFrom = (list, pattern, maxResults) => {const matches = [];const lowerCasePattern = pattern.toLowerCase();const reachedLimit = maxResults.fold(() => never, max => size => size >= max);for (let i = 0; i < list.length; i++) {if (pattern.length === 0 || emojiMatches(list[i], lowerCasePattern)) {matches.push({value: list[i].char,text: list[i].title,icon: list[i].char});if (reachedLimit(matches.length)) {break;}}}return matches;};const patternName = 'pattern';const open = (editor, database) => {const initialState = {pattern: '',results: emojisFrom(database.listAll(), '', Optional.some(300))};const currentTab = Cell(ALL_CATEGORY);const scan = dialogApi => {const dialogData = dialogApi.getData();const category = currentTab.get();const candidates = database.listCategory(category);const results = emojisFrom(candidates, dialogData[patternName], category === ALL_CATEGORY ? Optional.some(300) : Optional.none());dialogApi.setData({ results });};const updateFilter = last(dialogApi => {scan(dialogApi);}, 200);const searchField = {label: 'Search',type: 'input',name: patternName};const resultsField = {type: 'collection',name: 'results'};const getInitialState = () => {const body = {type: 'tabpanel',tabs: map$1(database.listCategories(), cat => ({title: cat,name: cat,items: [searchField,resultsField]}))};return {title: 'Emojis',size: 'normal',body,initialData: initialState,onTabChange: (dialogApi, details) => {currentTab.set(details.newTabName);updateFilter.throttle(dialogApi);},onChange: updateFilter.throttle,onAction: (dialogApi, actionData) => {if (actionData.name === 'results') {insertEmoticon(editor, actionData.value);dialogApi.close();}},buttons: [{type: 'cancel',text: 'Close',primary: true}]};};const dialogApi = editor.windowManager.open(getInitialState());dialogApi.focus(patternName);if (!database.hasLoaded()) {dialogApi.block('Loading emojis...');database.waitForLoad().then(() => {dialogApi.redial(getInitialState());updateFilter.throttle(dialogApi);dialogApi.focus(patternName);dialogApi.unblock();}).catch(_err => {dialogApi.redial({title: 'Emojis',body: {type: 'panel',items: [{type: 'alertbanner',level: 'error',icon: 'warning',text: 'Could not load emojis'}]},buttons: [{type: 'cancel',text: 'Close',primary: true}],initialData: {pattern: '',results: []}});dialogApi.focus(patternName);dialogApi.unblock();});}};const register$1 = (editor, database) => {editor.addCommand('mceEmoticons', () => open(editor, database));};const setup = editor => {editor.on('PreInit', () => {editor.parser.addAttributeFilter('data-emoticon', nodes => {each$1(nodes, node => {node.attr('data-mce-resize', 'false');node.attr('data-mce-placeholder', '1');});});});};const init = (editor, database) => {editor.ui.registry.addAutocompleter('emoticons', {trigger: ':',columns: 'auto',minChars: 2,fetch: (pattern, maxResults) => database.waitForLoad().then(() => {const candidates = database.listAll();return emojisFrom(candidates, pattern, Optional.some(maxResults));}),onAction: (autocompleteApi, rng, value) => {editor.selection.setRng(rng);editor.insertContent(value);autocompleteApi.hide();}});};const onSetupEditable = editor => api => {const nodeChanged = () => {api.setEnabled(editor.selection.isEditable());};editor.on('NodeChange', nodeChanged);nodeChanged();return () => {editor.off('NodeChange', nodeChanged);};};const register = editor => {const onAction = () => editor.execCommand('mceEmoticons');editor.ui.registry.addButton('emoticons', {tooltip: 'Emojis',icon: 'emoji',onAction,onSetup: onSetupEditable(editor)});editor.ui.registry.addMenuItem('emoticons', {text: 'Emojis...',icon: 'emoji',onAction,onSetup: onSetupEditable(editor)});};var Plugin = () => {global$1.add('emoticons', (editor, pluginUrl) => {register$2(editor, pluginUrl);const databaseUrl = getEmojiDatabaseUrl(editor);const databaseId = getEmojiDatabaseId(editor);const database = initDatabase(editor, databaseUrl, databaseId);register$1(editor, database);register(editor);init(editor, database);setup(editor);});};Plugin();})();