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$4 = tinymce.util.Tools.resolve('tinymce.PluginManager');const getPrototypeOf = Object.getPrototypeOf;const hasProto = (v, constructor, predicate) => {var _a;if (predicate(v, constructor.prototype)) {return true;} else {return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;}};const typeOf = x => {const t = typeof x;if (x === null) {return 'null';} else if (t === 'object' && Array.isArray(x)) {return 'array';} else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {return 'string';} else {return t;}};const isType = type => value => typeOf(value) === type;const isSimpleType = type => value => typeof value === type;const eq = t => a => t === a;const is = (value, constructor) => isObject(value) && hasProto(value, constructor, (o, proto) => getPrototypeOf(o) === proto);const isString = isType('string');const isObject = isType('object');const isPlainObject = value => is(value, Object);const isArray = isType('array');const isNull = eq(null);const isBoolean = isSimpleType('boolean');const isNullable = a => a === null || a === undefined;const isNonNullable = a => !isNullable(a);const isFunction = isSimpleType('function');const isNumber = isSimpleType('number');const isArrayOf = (value, pred) => {if (isArray(value)) {for (let i = 0, len = value.length; i < len; ++i) {if (!pred(value[i])) {return false;}}return true;}return false;};const noop = () => {};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 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 objAcc = r => (x, i) => {r[i] = x;};const internalFilter = (obj, pred, onTrue, onFalse) => {each(obj, (x, i) => {(pred(x, i) ? onTrue : onFalse)(x, i);});};const filter = (obj, pred) => {const t = {};internalFilter(obj, pred, objAcc(t), noop);return t;};const has = (obj, key) => hasOwnProperty.call(obj, key);const hasNonNullableKey = (obj, key) => has(obj, key) && obj[key] !== undefined && obj[key] !== null;const nativePush = Array.prototype.push;const flatten = xs => {const r = [];for (let i = 0, len = xs.length; i < len; ++i) {if (!isArray(xs[i])) {throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);}nativePush.apply(r, xs[i]);}return r;};const get = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();const head = xs => get(xs, 0);const findMap = (arr, f) => {for (let i = 0; i < arr.length; i++) {const r = f(arr[i], i);if (r.isSome()) {return r;}}return Optional.none();};typeof window !== 'undefined' ? window : Function('return this;')();const rawSet = (dom, key, value) => {if (isString(value) || isBoolean(value) || isNumber(value)) {dom.setAttribute(key, value + '');} else {console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);throw new Error('Attribute value was not simple');}};const set = (element, key, value) => {rawSet(element.dom, key, value);};const remove = (element, key) => {element.dom.removeAttribute(key);};const fromHtml = (html, scope) => {const doc = scope || document;const div = doc.createElement('div');div.innerHTML = html;if (!div.hasChildNodes() || div.childNodes.length > 1) {const message = 'HTML does not have a single root node';console.error(message, html);throw new Error(message);}return fromDom(div.childNodes[0]);};const fromTag = (tag, scope) => {const doc = scope || document;const node = doc.createElement(tag);return fromDom(node);};const fromText = (text, scope) => {const doc = scope || document;const node = doc.createTextNode(text);return fromDom(node);};const fromDom = node => {if (node === null || node === undefined) {throw new Error('Node cannot be null or undefined');}return { dom: node };};const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);const SugarElement = {fromHtml,fromTag,fromText,fromDom,fromPoint};var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');var global$2 = tinymce.util.Tools.resolve('tinymce.util.URI');const isNotEmpty = s => s.length > 0;const option = name => editor => editor.options.get(name);const register$2 = editor => {const registerOption = editor.options.register;registerOption('image_dimensions', {processor: 'boolean',default: true});registerOption('image_advtab', {processor: 'boolean',default: false});registerOption('image_uploadtab', {processor: 'boolean',default: true});registerOption('image_prepend_url', {processor: 'string',default: ''});registerOption('image_class_list', { processor: 'object[]' });registerOption('image_description', {processor: 'boolean',default: true});registerOption('image_title', {processor: 'boolean',default: false});registerOption('image_caption', {processor: 'boolean',default: false});registerOption('image_list', {processor: value => {const valid = value === false || isString(value) || isArrayOf(value, isObject) || isFunction(value);return valid ? {value,valid} : {valid: false,message: 'Must be false, a string, an array or a function.'};},default: false});};const hasDimensions = option('image_dimensions');const hasAdvTab = option('image_advtab');const hasUploadTab = option('image_uploadtab');const getPrependUrl = option('image_prepend_url');const getClassList = option('image_class_list');const hasDescription = option('image_description');const hasImageTitle = option('image_title');const hasImageCaption = option('image_caption');const getImageList = option('image_list');const showAccessibilityOptions = option('a11y_advanced_options');const isAutomaticUploadsEnabled = option('automatic_uploads');const hasUploadUrl = editor => isNotEmpty(editor.options.get('images_upload_url'));const hasUploadHandler = editor => isNonNullable(editor.options.get('images_upload_handler'));const parseIntAndGetMax = (val1, val2) => Math.max(parseInt(val1, 10), parseInt(val2, 10));const getImageSize = url => new Promise(callback => {const img = document.createElement('img');const done = dimensions => {img.onload = img.onerror = null;if (img.parentNode) {img.parentNode.removeChild(img);}callback(dimensions);};img.onload = () => {const width = parseIntAndGetMax(img.width, img.clientWidth);const height = parseIntAndGetMax(img.height, img.clientHeight);const dimensions = {width,height};done(Promise.resolve(dimensions));};img.onerror = () => {done(Promise.reject(`Failed to get image dimensions for: ${ url }`));};const style = img.style;style.visibility = 'hidden';style.position = 'fixed';style.bottom = style.left = '0px';style.width = style.height = 'auto';document.body.appendChild(img);img.src = url;});const removePixelSuffix = value => {if (value) {value = value.replace(/px$/, '');}return value;};const addPixelSuffix = value => {if (value.length > 0 && /^[0-9]+$/.test(value)) {value += 'px';}return value;};const mergeMargins = css => {if (css.margin) {const splitMargin = String(css.margin).split(' ');switch (splitMargin.length) {case 1:css['margin-top'] = css['margin-top'] || splitMargin[0];css['margin-right'] = css['margin-right'] || splitMargin[0];css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];css['margin-left'] = css['margin-left'] || splitMargin[0];break;case 2:css['margin-top'] = css['margin-top'] || splitMargin[0];css['margin-right'] = css['margin-right'] || splitMargin[1];css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];css['margin-left'] = css['margin-left'] || splitMargin[1];break;case 3:css['margin-top'] = css['margin-top'] || splitMargin[0];css['margin-right'] = css['margin-right'] || splitMargin[1];css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];css['margin-left'] = css['margin-left'] || splitMargin[1];break;case 4:css['margin-top'] = css['margin-top'] || splitMargin[0];css['margin-right'] = css['margin-right'] || splitMargin[1];css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];css['margin-left'] = css['margin-left'] || splitMargin[3];}delete css.margin;}return css;};const createImageList = (editor, callback) => {const imageList = getImageList(editor);if (isString(imageList)) {fetch(imageList).then(res => {if (res.ok) {res.json().then(callback);}});} else if (isFunction(imageList)) {imageList(callback);} else {callback(imageList);}};const waitLoadImage = (editor, data, imgElm) => {const selectImage = () => {imgElm.onload = imgElm.onerror = null;if (editor.selection) {editor.selection.select(imgElm);editor.nodeChanged();}};imgElm.onload = () => {if (!data.width && !data.height && hasDimensions(editor)) {editor.dom.setAttribs(imgElm, {width: String(imgElm.clientWidth),height: String(imgElm.clientHeight)});}selectImage();};imgElm.onerror = selectImage;};const blobToDataUri = blob => new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {resolve(reader.result);};reader.onerror = () => {var _a;reject((_a = reader.error) === null || _a === void 0 ? void 0 : _a.message);};reader.readAsDataURL(blob);});const isPlaceholderImage = imgElm => imgElm.nodeName === 'IMG' && (imgElm.hasAttribute('data-mce-object') || imgElm.hasAttribute('data-mce-placeholder'));const isSafeImageUrl = (editor, src) => {const getOption = editor.options.get;return global$2.isDomSafe(src, 'img', {allow_html_data_urls: getOption('allow_html_data_urls'),allow_script_urls: getOption('allow_script_urls'),allow_svg_data_urls: getOption('allow_svg_data_urls')});};const DOM = global$3.DOM;const getHspace = image => {if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) {return removePixelSuffix(image.style.marginLeft);} else {return '';}};const getVspace = image => {if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) {return removePixelSuffix(image.style.marginTop);} else {return '';}};const getBorder = image => {if (image.style.borderWidth) {return removePixelSuffix(image.style.borderWidth);} else {return '';}};const getAttrib = (image, name) => {var _a;if (image.hasAttribute(name)) {return (_a = image.getAttribute(name)) !== null && _a !== void 0 ? _a : '';} else {return '';}};const hasCaption = image => image.parentNode !== null && image.parentNode.nodeName === 'FIGURE';const updateAttrib = (image, name, value) => {if (value === '' || value === null) {image.removeAttribute(name);} else {image.setAttribute(name, value);}};const wrapInFigure = image => {const figureElm = DOM.create('figure', { class: 'image' });DOM.insertAfter(figureElm, image);figureElm.appendChild(image);figureElm.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));figureElm.contentEditable = 'false';};const removeFigure = image => {const figureElm = image.parentNode;if (isNonNullable(figureElm)) {DOM.insertAfter(image, figureElm);DOM.remove(figureElm);}};const toggleCaption = image => {if (hasCaption(image)) {removeFigure(image);} else {wrapInFigure(image);}};const normalizeStyle = (image, normalizeCss) => {const attrValue = image.getAttribute('style');const value = normalizeCss(attrValue !== null ? attrValue : '');if (value.length > 0) {image.setAttribute('style', value);image.setAttribute('data-mce-style', value);} else {image.removeAttribute('style');}};const setSize = (name, normalizeCss) => (image, name, value) => {const styles = image.style;if (styles[name]) {styles[name] = addPixelSuffix(value);normalizeStyle(image, normalizeCss);} else {updateAttrib(image, name, value);}};const getSize = (image, name) => {if (image.style[name]) {return removePixelSuffix(image.style[name]);} else {return getAttrib(image, name);}};const setHspace = (image, value) => {const pxValue = addPixelSuffix(value);image.style.marginLeft = pxValue;image.style.marginRight = pxValue;};const setVspace = (image, value) => {const pxValue = addPixelSuffix(value);image.style.marginTop = pxValue;image.style.marginBottom = pxValue;};const setBorder = (image, value) => {const pxValue = addPixelSuffix(value);image.style.borderWidth = pxValue;};const setBorderStyle = (image, value) => {image.style.borderStyle = value;};const getBorderStyle = image => {var _a;return (_a = image.style.borderStyle) !== null && _a !== void 0 ? _a : '';};const isFigure = elm => isNonNullable(elm) && elm.nodeName === 'FIGURE';const isImage = elm => elm.nodeName === 'IMG';const getIsDecorative = image => DOM.getAttrib(image, 'alt').length === 0 && DOM.getAttrib(image, 'role') === 'presentation';const getAlt = image => {if (getIsDecorative(image)) {return '';} else {return getAttrib(image, 'alt');}};const defaultData = () => ({src: '',alt: '',title: '',width: '',height: '',class: '',style: '',caption: false,hspace: '',vspace: '',border: '',borderStyle: '',isDecorative: false});const getStyleValue = (normalizeCss, data) => {var _a;const image = document.createElement('img');updateAttrib(image, 'style', data.style);if (getHspace(image) || data.hspace !== '') {setHspace(image, data.hspace);}if (getVspace(image) || data.vspace !== '') {setVspace(image, data.vspace);}if (getBorder(image) || data.border !== '') {setBorder(image, data.border);}if (getBorderStyle(image) || data.borderStyle !== '') {setBorderStyle(image, data.borderStyle);}return normalizeCss((_a = image.getAttribute('style')) !== null && _a !== void 0 ? _a : '');};const create = (normalizeCss, data) => {const image = document.createElement('img');write(normalizeCss, {...data,caption: false}, image);setAlt(image, data.alt, data.isDecorative);if (data.caption) {const figure = DOM.create('figure', { class: 'image' });figure.appendChild(image);figure.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));figure.contentEditable = 'false';return figure;} else {return image;}};const read = (normalizeCss, image) => ({src: getAttrib(image, 'src'),alt: getAlt(image),title: getAttrib(image, 'title'),width: getSize(image, 'width'),height: getSize(image, 'height'),class: getAttrib(image, 'class'),style: normalizeCss(getAttrib(image, 'style')),caption: hasCaption(image),hspace: getHspace(image),vspace: getVspace(image),border: getBorder(image),borderStyle: getBorderStyle(image),isDecorative: getIsDecorative(image)});const updateProp = (image, oldData, newData, name, set) => {if (newData[name] !== oldData[name]) {set(image, name, String(newData[name]));}};const setAlt = (image, alt, isDecorative) => {if (isDecorative) {DOM.setAttrib(image, 'role', 'presentation');const sugarImage = SugarElement.fromDom(image);set(sugarImage, 'alt', '');} else {if (isNull(alt)) {const sugarImage = SugarElement.fromDom(image);remove(sugarImage, 'alt');} else {const sugarImage = SugarElement.fromDom(image);set(sugarImage, 'alt', alt);}if (DOM.getAttrib(image, 'role') === 'presentation') {DOM.setAttrib(image, 'role', '');}}};const updateAlt = (image, oldData, newData) => {if (newData.alt !== oldData.alt || newData.isDecorative !== oldData.isDecorative) {setAlt(image, newData.alt, newData.isDecorative);}};const normalized = (set, normalizeCss) => (image, name, value) => {set(image, value);normalizeStyle(image, normalizeCss);};const write = (normalizeCss, newData, image) => {const oldData = read(normalizeCss, image);updateProp(image, oldData, newData, 'caption', (image, _name, _value) => toggleCaption(image));updateProp(image, oldData, newData, 'src', updateAttrib);updateProp(image, oldData, newData, 'title', updateAttrib);updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss));updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss));updateProp(image, oldData, newData, 'class', updateAttrib);updateProp(image, oldData, newData, 'style', normalized((image, value) => updateAttrib(image, 'style', value), normalizeCss));updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss));updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss));updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss));updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss));updateAlt(image, oldData, newData);};const normalizeCss$1 = (editor, cssText) => {const css = editor.dom.styles.parse(cssText);const mergedCss = mergeMargins(css);const compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss));return editor.dom.styles.serialize(compressed);};const getSelectedImage = editor => {const imgElm = editor.selection.getNode();const figureElm = editor.dom.getParent(imgElm, 'figure.image');if (figureElm) {return editor.dom.select('img', figureElm)[0];}if (imgElm && (imgElm.nodeName !== 'IMG' || isPlaceholderImage(imgElm))) {return null;}return imgElm;};const splitTextBlock = (editor, figure) => {var _a;const dom = editor.dom;const textBlockElements = filter(editor.schema.getTextBlockElements(), (_, parentElm) => !editor.schema.isValidChild(parentElm, 'figure'));const textBlock = dom.getParent(figure.parentNode, node => hasNonNullableKey(textBlockElements, node.nodeName), editor.getBody());if (textBlock) {return (_a = dom.split(textBlock, figure)) !== null && _a !== void 0 ? _a : figure;} else {return figure;}};const readImageDataFromSelection = editor => {const image = getSelectedImage(editor);return image ? read(css => normalizeCss$1(editor, css), image) : defaultData();};const insertImageAtCaret = (editor, data) => {const elm = create(css => normalizeCss$1(editor, css), data);editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew');editor.focus();editor.selection.setContent(elm.outerHTML);const insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0];editor.dom.setAttrib(insertedElm, 'data-mce-id', null);if (isFigure(insertedElm)) {const figure = splitTextBlock(editor, insertedElm);editor.selection.select(figure);} else {editor.selection.select(insertedElm);}};const syncSrcAttr = (editor, image) => {editor.dom.setAttrib(image, 'src', image.getAttribute('src'));};const deleteImage = (editor, image) => {if (image) {const elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image;editor.dom.remove(elm);editor.focus();editor.nodeChanged();if (editor.dom.isEmpty(editor.getBody())) {editor.setContent('');editor.selection.setCursorLocation();}}};const writeImageDataToSelection = (editor, data) => {const image = getSelectedImage(editor);if (image) {write(css => normalizeCss$1(editor, css), data, image);syncSrcAttr(editor, image);if (isFigure(image.parentNode)) {const figure = image.parentNode;splitTextBlock(editor, figure);editor.selection.select(image.parentNode);} else {editor.selection.select(image);waitLoadImage(editor, data, image);}}};const sanitizeImageData = (editor, data) => {const src = data.src;return {...data,src: isSafeImageUrl(editor, src) ? src : ''};};const insertOrUpdateImage = (editor, partialData) => {const image = getSelectedImage(editor);if (image) {const selectedImageData = read(css => normalizeCss$1(editor, css), image);const data = {...selectedImageData,...partialData};const sanitizedData = sanitizeImageData(editor, data);if (data.src) {writeImageDataToSelection(editor, sanitizedData);} else {deleteImage(editor, image);}} else if (partialData.src) {insertImageAtCaret(editor, {...defaultData(),...partialData});}};const deep = (old, nu) => {const bothObjects = isPlainObject(old) && isPlainObject(nu);return bothObjects ? deepMerge(old, nu) : 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 deepMerge = baseMerge(deep);var global$1 = tinymce.util.Tools.resolve('tinymce.util.ImageUploader');var global = tinymce.util.Tools.resolve('tinymce.util.Tools');const getValue = item => isString(item.value) ? item.value : '';const getText = item => {if (isString(item.text)) {return item.text;} else if (isString(item.title)) {return item.title;} else {return '';}};const sanitizeList = (list, extractValue) => {const out = [];global.each(list, item => {const text = getText(item);if (item.menu !== undefined) {const items = sanitizeList(item.menu, extractValue);out.push({text,items});} else {const value = extractValue(item);out.push({text,value});}});return out;};const sanitizer = (extractor = getValue) => list => {if (list) {return Optional.from(list).map(list => sanitizeList(list, extractor));} else {return Optional.none();}};const sanitize = list => sanitizer(getValue)(list);const isGroup = item => has(item, 'items');const findEntryDelegate = (list, value) => findMap(list, item => {if (isGroup(item)) {return findEntryDelegate(item.items, value);} else if (item.value === value) {return Optional.some(item);} else {return Optional.none();}});const findEntry = (optList, value) => optList.bind(list => findEntryDelegate(list, value));const ListUtils = {sanitizer,sanitize,findEntry};const makeTab$2 = _info => ({title: 'Advanced',name: 'advanced',items: [{type: 'grid',columns: 2,items: [{type: 'input',label: 'Vertical space',name: 'vspace',inputMode: 'numeric'},{type: 'input',label: 'Horizontal space',name: 'hspace',inputMode: 'numeric'},{type: 'input',label: 'Border width',name: 'border',inputMode: 'numeric'},{type: 'listbox',name: 'borderstyle',label: 'Border style',items: [{text: 'Select...',value: ''},{text: 'Solid',value: 'solid'},{text: 'Dotted',value: 'dotted'},{text: 'Dashed',value: 'dashed'},{text: 'Double',value: 'double'},{text: 'Groove',value: 'groove'},{text: 'Ridge',value: 'ridge'},{text: 'Inset',value: 'inset'},{text: 'Outset',value: 'outset'},{text: 'None',value: 'none'},{text: 'Hidden',value: 'hidden'}]}]}]});const AdvTab = { makeTab: makeTab$2 };const collect = editor => {const urlListSanitizer = ListUtils.sanitizer(item => editor.convertURL(item.value || item.url || '', 'src'));const futureImageList = new Promise(completer => {createImageList(editor, imageList => {completer(urlListSanitizer(imageList).map(items => flatten([[{text: 'None',value: ''}],items])));});});const classList = ListUtils.sanitize(getClassList(editor));const hasAdvTab$1 = hasAdvTab(editor);const hasUploadTab$1 = hasUploadTab(editor);const hasUploadUrl$1 = hasUploadUrl(editor);const hasUploadHandler$1 = hasUploadHandler(editor);const image = readImageDataFromSelection(editor);const hasDescription$1 = hasDescription(editor);const hasImageTitle$1 = hasImageTitle(editor);const hasDimensions$1 = hasDimensions(editor);const hasImageCaption$1 = hasImageCaption(editor);const hasAccessibilityOptions = showAccessibilityOptions(editor);const automaticUploads = isAutomaticUploadsEnabled(editor);const prependURL = Optional.some(getPrependUrl(editor)).filter(preUrl => isString(preUrl) && preUrl.length > 0);return futureImageList.then(imageList => ({image,imageList,classList,hasAdvTab: hasAdvTab$1,hasUploadTab: hasUploadTab$1,hasUploadUrl: hasUploadUrl$1,hasUploadHandler: hasUploadHandler$1,hasDescription: hasDescription$1,hasImageTitle: hasImageTitle$1,hasDimensions: hasDimensions$1,hasImageCaption: hasImageCaption$1,prependURL,hasAccessibilityOptions,automaticUploads}));};const makeItems = info => {const imageUrl = {name: 'src',type: 'urlinput',filetype: 'image',label: 'Source',picker_text: 'Browse files'};const imageList = info.imageList.map(items => ({name: 'images',type: 'listbox',label: 'Image list',items}));const imageDescription = {name: 'alt',type: 'input',label: 'Alternative description',enabled: !(info.hasAccessibilityOptions && info.image.isDecorative)};const imageTitle = {name: 'title',type: 'input',label: 'Image title'};const imageDimensions = {name: 'dimensions',type: 'sizeinput'};const isDecorative = {type: 'label',label: 'Accessibility',items: [{name: 'isDecorative',type: 'checkbox',label: 'Image is decorative'}]};const classList = info.classList.map(items => ({name: 'classes',type: 'listbox',label: 'Class',items}));const caption = {type: 'label',label: 'Caption',items: [{type: 'checkbox',name: 'caption',label: 'Show caption'}]};const getDialogContainerType = useColumns => useColumns ? {type: 'grid',columns: 2} : { type: 'panel' };return flatten([[imageUrl],imageList.toArray(),info.hasAccessibilityOptions && info.hasDescription ? [isDecorative] : [],info.hasDescription ? [imageDescription] : [],info.hasImageTitle ? [imageTitle] : [],info.hasDimensions ? [imageDimensions] : [],[{...getDialogContainerType(info.classList.isSome() && info.hasImageCaption),items: flatten([classList.toArray(),info.hasImageCaption ? [caption] : []])}]]);};const makeTab$1 = info => ({title: 'General',name: 'general',items: makeItems(info)});const MainTab = {makeTab: makeTab$1,makeItems};const makeTab = _info => {const items = [{type: 'dropzone',name: 'fileinput'}];return {title: 'Upload',name: 'upload',items};};const UploadTab = { makeTab };const createState = info => ({prevImage: ListUtils.findEntry(info.imageList, info.image.src),prevAlt: info.image.alt,open: true});const fromImageData = image => ({src: {value: image.src,meta: {}},images: image.src,alt: image.alt,title: image.title,dimensions: {width: image.width,height: image.height},classes: image.class,caption: image.caption,style: image.style,vspace: image.vspace,border: image.border,hspace: image.hspace,borderstyle: image.borderStyle,fileinput: [],isDecorative: image.isDecorative});const toImageData = (data, removeEmptyAlt) => ({src: data.src.value,alt: (data.alt === null || data.alt.length === 0) && removeEmptyAlt ? null : data.alt,title: data.title,width: data.dimensions.width,height: data.dimensions.height,class: data.classes,style: data.style,caption: data.caption,hspace: data.hspace,vspace: data.vspace,border: data.border,borderStyle: data.borderstyle,isDecorative: data.isDecorative});const addPrependUrl2 = (info, srcURL) => {if (!/^(?:[a-zA-Z]+:)?\/\//.test(srcURL)) {return info.prependURL.bind(prependUrl => {if (srcURL.substring(0, prependUrl.length) !== prependUrl) {return Optional.some(prependUrl + srcURL);}return Optional.none();});}return Optional.none();};const addPrependUrl = (info, api) => {const data = api.getData();addPrependUrl2(info, data.src.value).each(srcURL => {api.setData({src: {value: srcURL,meta: data.src.meta}});});};const formFillFromMeta2 = (info, data, meta) => {if (info.hasDescription && isString(meta.alt)) {data.alt = meta.alt;}if (info.hasAccessibilityOptions) {data.isDecorative = meta.isDecorative || data.isDecorative || false;}if (info.hasImageTitle && isString(meta.title)) {data.title = meta.title;}if (info.hasDimensions) {if (isString(meta.width)) {data.dimensions.width = meta.width;}if (isString(meta.height)) {data.dimensions.height = meta.height;}}if (isString(meta.class)) {ListUtils.findEntry(info.classList, meta.class).each(entry => {data.classes = entry.value;});}if (info.hasImageCaption) {if (isBoolean(meta.caption)) {data.caption = meta.caption;}}if (info.hasAdvTab) {if (isString(meta.style)) {data.style = meta.style;}if (isString(meta.vspace)) {data.vspace = meta.vspace;}if (isString(meta.border)) {data.border = meta.border;}if (isString(meta.hspace)) {data.hspace = meta.hspace;}if (isString(meta.borderstyle)) {data.borderstyle = meta.borderstyle;}}};const formFillFromMeta = (info, api) => {const data = api.getData();const meta = data.src.meta;if (meta !== undefined) {const newData = deepMerge({}, data);formFillFromMeta2(info, newData, meta);api.setData(newData);}};const calculateImageSize = (helpers, info, state, api) => {const data = api.getData();const url = data.src.value;const meta = data.src.meta || {};if (!meta.width && !meta.height && info.hasDimensions) {if (isNotEmpty(url)) {helpers.imageSize(url).then(size => {if (state.open) {api.setData({ dimensions: size });}}).catch(e => console.error(e));} else {api.setData({dimensions: {width: '',height: ''}});}}};const updateImagesDropdown = (info, state, api) => {const data = api.getData();const image = ListUtils.findEntry(info.imageList, data.src.value);state.prevImage = image;api.setData({ images: image.map(entry => entry.value).getOr('') });};const changeSrc = (helpers, info, state, api) => {addPrependUrl(info, api);formFillFromMeta(info, api);calculateImageSize(helpers, info, state, api);updateImagesDropdown(info, state, api);};const changeImages = (helpers, info, state, api) => {const data = api.getData();const image = ListUtils.findEntry(info.imageList, data.images);image.each(img => {const updateAlt = data.alt === '' || state.prevImage.map(image => image.text === data.alt).getOr(false);if (updateAlt) {if (img.value === '') {api.setData({src: img,alt: state.prevAlt});} else {api.setData({src: img,alt: img.text});}} else {api.setData({ src: img });}});state.prevImage = image;changeSrc(helpers, info, state, api);};const changeFileInput = (helpers, info, state, api) => {const data = api.getData();api.block('Uploading image');head(data.fileinput).fold(() => {api.unblock();}, file => {const blobUri = URL.createObjectURL(file);const finalize = () => {api.unblock();URL.revokeObjectURL(blobUri);};const updateSrcAndSwitchTab = url => {api.setData({src: {value: url,meta: {}}});api.showTab('general');changeSrc(helpers, info, state, api);};blobToDataUri(file).then(dataUrl => {const blobInfo = helpers.createBlobCache(file, blobUri, dataUrl);if (info.automaticUploads) {helpers.uploadImage(blobInfo).then(result => {updateSrcAndSwitchTab(result.url);finalize();}).catch(err => {finalize();helpers.alertErr(err);});} else {helpers.addToBlobCache(blobInfo);updateSrcAndSwitchTab(blobInfo.blobUri());api.unblock();}});});};const changeHandler = (helpers, info, state) => (api, evt) => {if (evt.name === 'src') {changeSrc(helpers, info, state, api);} else if (evt.name === 'images') {changeImages(helpers, info, state, api);} else if (evt.name === 'alt') {state.prevAlt = api.getData().alt;} else if (evt.name === 'fileinput') {changeFileInput(helpers, info, state, api);} else if (evt.name === 'isDecorative') {api.setEnabled('alt', !api.getData().isDecorative);}};const closeHandler = state => () => {state.open = false;};const makeDialogBody = info => {if (info.hasAdvTab || info.hasUploadUrl || info.hasUploadHandler) {const tabPanel = {type: 'tabpanel',tabs: flatten([[MainTab.makeTab(info)],info.hasAdvTab ? [AdvTab.makeTab(info)] : [],info.hasUploadTab && (info.hasUploadUrl || info.hasUploadHandler) ? [UploadTab.makeTab(info)] : []])};return tabPanel;} else {const panel = {type: 'panel',items: MainTab.makeItems(info)};return panel;}};const submitHandler = (editor, info, helpers) => api => {const data = deepMerge(fromImageData(info.image), api.getData());const finalData = {...data,style: getStyleValue(helpers.normalizeCss, toImageData(data, false))};editor.execCommand('mceUpdateImage', false, toImageData(finalData, info.hasAccessibilityOptions));editor.editorUpload.uploadImagesAuto();api.close();};const imageSize = editor => url => {if (!isSafeImageUrl(editor, url)) {return Promise.resolve({width: '',height: ''});} else {return getImageSize(editor.documentBaseURI.toAbsolute(url)).then(dimensions => ({width: String(dimensions.width),height: String(dimensions.height)}));}};const createBlobCache = editor => (file, blobUri, dataUrl) => {var _a;return editor.editorUpload.blobCache.create({blob: file,blobUri,name: (_a = file.name) === null || _a === void 0 ? void 0 : _a.replace(/\.[^\.]+$/, ''),filename: file.name,base64: dataUrl.split(',')[1]});};const addToBlobCache = editor => blobInfo => {editor.editorUpload.blobCache.add(blobInfo);};const alertErr = editor => message => {editor.windowManager.alert(message);};const normalizeCss = editor => cssText => normalizeCss$1(editor, cssText);const parseStyle = editor => cssText => editor.dom.parseStyle(cssText);const serializeStyle = editor => (stylesArg, name) => editor.dom.serializeStyle(stylesArg, name);const uploadImage = editor => blobInfo => global$1(editor).upload([blobInfo], false).then(results => {var _a;if (results.length === 0) {return Promise.reject('Failed to upload image');} else if (results[0].status === false) {return Promise.reject((_a = results[0].error) === null || _a === void 0 ? void 0 : _a.message);} else {return results[0];}});const Dialog = editor => {const helpers = {imageSize: imageSize(editor),addToBlobCache: addToBlobCache(editor),createBlobCache: createBlobCache(editor),alertErr: alertErr(editor),normalizeCss: normalizeCss(editor),parseStyle: parseStyle(editor),serializeStyle: serializeStyle(editor),uploadImage: uploadImage(editor)};const open = () => {collect(editor).then(info => {const state = createState(info);return {title: 'Insert/Edit Image',size: 'normal',body: makeDialogBody(info),buttons: [{type: 'cancel',name: 'cancel',text: 'Cancel'},{type: 'submit',name: 'save',text: 'Save',primary: true}],initialData: fromImageData(info.image),onSubmit: submitHandler(editor, info, helpers),onChange: changeHandler(helpers, info, state),onClose: closeHandler(state)};}).then(editor.windowManager.open);};return { open };};const register$1 = editor => {editor.addCommand('mceImage', Dialog(editor).open);editor.addCommand('mceUpdateImage', (_ui, data) => {editor.undoManager.transact(() => insertOrUpdateImage(editor, data));});};const hasImageClass = node => {const className = node.attr('class');return isNonNullable(className) && /\bimage\b/.test(className);};const toggleContentEditableState = state => nodes => {let i = nodes.length;const toggleContentEditable = node => {node.attr('contenteditable', state ? 'true' : null);};while (i--) {const node = nodes[i];if (hasImageClass(node)) {node.attr('contenteditable', state ? 'false' : null);global.each(node.getAll('figcaption'), toggleContentEditable);}}};const setup = editor => {editor.on('PreInit', () => {editor.parser.addNodeFilter('figure', toggleContentEditableState(true));editor.serializer.addNodeFilter('figure', toggleContentEditableState(false));});};const onSetupEditable = editor => api => {const nodeChanged = () => {api.setEnabled(editor.selection.isEditable());};editor.on('NodeChange', nodeChanged);nodeChanged();return () => {editor.off('NodeChange', nodeChanged);};};const register = editor => {editor.ui.registry.addToggleButton('image', {icon: 'image',tooltip: 'Insert/edit image',onAction: Dialog(editor).open,onSetup: buttonApi => {buttonApi.setActive(isNonNullable(getSelectedImage(editor)));const unbindSelectorChanged = editor.selection.selectorChangedWithUnbind('img:not([data-mce-object]):not([data-mce-placeholder]),figure.image', buttonApi.setActive).unbind;const unbindEditable = onSetupEditable(editor)(buttonApi);return () => {unbindSelectorChanged();unbindEditable();};}});editor.ui.registry.addMenuItem('image', {icon: 'image',text: 'Image...',onAction: Dialog(editor).open,onSetup: onSetupEditable(editor)});editor.ui.registry.addContextMenu('image', { update: element => editor.selection.isEditable() && (isFigure(element) || isImage(element) && !isPlaceholderImage(element)) ? ['image'] : [] });};var Plugin = () => {global$4.add('image', editor => {register$2(editor);setup(editor);register(editor);register$1(editor);});};Plugin();})();