44f0b4beef
Originally I changed the compiled output of TinyMCE from es2015 to es6 to try and allow our own requirejs system to serve the content. This is a change in the TinyMCE repository (or our copy of it). Unfortunately this turned out to not be possible, but I never got around to updating the configuration to stop doing so. Whilst working on this issue, I've removed this change to module compilation, which brings us closer in line to Tiny core, and simplifies the upgrade process.
396 lines
12 KiB
JavaScript
396 lines
12 KiB
JavaScript
/**
|
|
* TinyMCE version 6.6.2 (2023-08-09)
|
|
*/
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
|
|
|
|
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$1 = type => value => typeOf(value) === type;
|
|
const isSimpleType = type => value => typeof value === type;
|
|
const isString = isType$1('string');
|
|
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 compose1 = (fbc, fab) => a => fbc(fab(a));
|
|
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 map = (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 = (xs, f) => {
|
|
for (let i = 0, len = xs.length; i < len; i++) {
|
|
const x = xs[i];
|
|
f(x, i);
|
|
}
|
|
};
|
|
const filter = (xs, pred) => {
|
|
const r = [];
|
|
for (let i = 0, len = xs.length; i < len; i++) {
|
|
const x = xs[i];
|
|
if (pred(x, i)) {
|
|
r.push(x);
|
|
}
|
|
}
|
|
return r;
|
|
};
|
|
|
|
const DOCUMENT = 9;
|
|
const DOCUMENT_FRAGMENT = 11;
|
|
const ELEMENT = 1;
|
|
const TEXT = 3;
|
|
|
|
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
|
|
};
|
|
|
|
const is = (element, selector) => {
|
|
const dom = element.dom;
|
|
if (dom.nodeType !== ELEMENT) {
|
|
return false;
|
|
} else {
|
|
const elem = dom;
|
|
if (elem.matches !== undefined) {
|
|
return elem.matches(selector);
|
|
} else if (elem.msMatchesSelector !== undefined) {
|
|
return elem.msMatchesSelector(selector);
|
|
} else if (elem.webkitMatchesSelector !== undefined) {
|
|
return elem.webkitMatchesSelector(selector);
|
|
} else if (elem.mozMatchesSelector !== undefined) {
|
|
return elem.mozMatchesSelector(selector);
|
|
} else {
|
|
throw new Error('Browser lacks native selectors');
|
|
}
|
|
}
|
|
};
|
|
|
|
typeof window !== 'undefined' ? window : Function('return this;')();
|
|
|
|
const name = element => {
|
|
const r = element.dom.nodeName;
|
|
return r.toLowerCase();
|
|
};
|
|
const type = element => element.dom.nodeType;
|
|
const isType = t => element => type(element) === t;
|
|
const isElement = isType(ELEMENT);
|
|
const isText = isType(TEXT);
|
|
const isDocument = isType(DOCUMENT);
|
|
const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
|
|
const isTag = tag => e => isElement(e) && name(e) === tag;
|
|
|
|
const owner = element => SugarElement.fromDom(element.dom.ownerDocument);
|
|
const documentOrOwner = dos => isDocument(dos) ? dos : owner(dos);
|
|
const parent = element => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
|
|
const children$2 = element => map(element.dom.childNodes, SugarElement.fromDom);
|
|
|
|
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 isShadowRoot = dos => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
|
|
const supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
|
|
const getRootNode = supported ? e => SugarElement.fromDom(e.dom.getRootNode()) : documentOrOwner;
|
|
const getShadowRoot = e => {
|
|
const r = getRootNode(e);
|
|
return isShadowRoot(r) ? Optional.some(r) : Optional.none();
|
|
};
|
|
const getShadowHost = e => SugarElement.fromDom(e.dom.host);
|
|
|
|
const inBody = element => {
|
|
const dom = isText(element) ? element.dom.parentNode : element.dom;
|
|
if (dom === undefined || dom === null || dom.ownerDocument === null) {
|
|
return false;
|
|
}
|
|
const doc = dom.ownerDocument;
|
|
return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
|
|
};
|
|
|
|
const ancestor$1 = (scope, predicate, isRoot) => {
|
|
let element = scope.dom;
|
|
const stop = isFunction(isRoot) ? isRoot : never;
|
|
while (element.parentNode) {
|
|
element = element.parentNode;
|
|
const el = SugarElement.fromDom(element);
|
|
if (predicate(el)) {
|
|
return Optional.some(el);
|
|
} else if (stop(el)) {
|
|
break;
|
|
}
|
|
}
|
|
return Optional.none();
|
|
};
|
|
|
|
const ancestor = (scope, selector, isRoot) => ancestor$1(scope, e => is(e, selector), isRoot);
|
|
|
|
const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
|
|
|
|
const get = (element, property) => {
|
|
const dom = element.dom;
|
|
const styles = window.getComputedStyle(dom);
|
|
const r = styles.getPropertyValue(property);
|
|
return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
|
|
};
|
|
const getUnsafeProperty = (dom, property) => isSupported(dom) ? dom.style.getPropertyValue(property) : '';
|
|
|
|
const getDirection = element => get(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';
|
|
|
|
const children$1 = (scope, predicate) => filter(children$2(scope), predicate);
|
|
|
|
const children = (scope, selector) => children$1(scope, e => is(e, selector));
|
|
|
|
const getParentElement = element => parent(element).filter(isElement);
|
|
const getNormalizedBlock = (element, isListItem) => {
|
|
const normalizedElement = isListItem ? ancestor(element, 'ol,ul') : Optional.some(element);
|
|
return normalizedElement.getOr(element);
|
|
};
|
|
const isListItem = isTag('li');
|
|
const setDirOnElements = (dom, blocks, dir) => {
|
|
each(blocks, block => {
|
|
const blockElement = SugarElement.fromDom(block);
|
|
const isBlockElementListItem = isListItem(blockElement);
|
|
const normalizedBlock = getNormalizedBlock(blockElement, isBlockElementListItem);
|
|
const normalizedBlockParent = getParentElement(normalizedBlock);
|
|
normalizedBlockParent.each(parent => {
|
|
dom.setStyle(normalizedBlock.dom, 'direction', null);
|
|
const parentDirection = getDirection(parent);
|
|
if (parentDirection === dir) {
|
|
remove(normalizedBlock, 'dir');
|
|
} else {
|
|
set(normalizedBlock, 'dir', dir);
|
|
}
|
|
if (getDirection(normalizedBlock) !== dir) {
|
|
dom.setStyle(normalizedBlock.dom, 'direction', dir);
|
|
}
|
|
if (isBlockElementListItem) {
|
|
const listItems = children(normalizedBlock, 'li[dir],li[style]');
|
|
each(listItems, listItem => {
|
|
remove(listItem, 'dir');
|
|
dom.setStyle(listItem.dom, 'direction', null);
|
|
});
|
|
}
|
|
});
|
|
});
|
|
};
|
|
const setDir = (editor, dir) => {
|
|
if (editor.selection.isEditable()) {
|
|
setDirOnElements(editor.dom, editor.selection.getSelectedBlocks(), dir);
|
|
editor.nodeChanged();
|
|
}
|
|
};
|
|
|
|
const register$1 = editor => {
|
|
editor.addCommand('mceDirectionLTR', () => {
|
|
setDir(editor, 'ltr');
|
|
});
|
|
editor.addCommand('mceDirectionRTL', () => {
|
|
setDir(editor, 'rtl');
|
|
});
|
|
};
|
|
|
|
const getNodeChangeHandler = (editor, dir) => api => {
|
|
const nodeChangeHandler = e => {
|
|
const element = SugarElement.fromDom(e.element);
|
|
api.setActive(getDirection(element) === dir);
|
|
api.setEnabled(editor.selection.isEditable());
|
|
};
|
|
editor.on('NodeChange', nodeChangeHandler);
|
|
api.setEnabled(editor.selection.isEditable());
|
|
return () => editor.off('NodeChange', nodeChangeHandler);
|
|
};
|
|
const register = editor => {
|
|
editor.ui.registry.addToggleButton('ltr', {
|
|
tooltip: 'Left to right',
|
|
icon: 'ltr',
|
|
onAction: () => editor.execCommand('mceDirectionLTR'),
|
|
onSetup: getNodeChangeHandler(editor, 'ltr')
|
|
});
|
|
editor.ui.registry.addToggleButton('rtl', {
|
|
tooltip: 'Right to left',
|
|
icon: 'rtl',
|
|
onAction: () => editor.execCommand('mceDirectionRTL'),
|
|
onSetup: getNodeChangeHandler(editor, 'rtl')
|
|
});
|
|
};
|
|
|
|
var Plugin = () => {
|
|
global.add('directionality', editor => {
|
|
register$1(editor);
|
|
register(editor);
|
|
});
|
|
};
|
|
|
|
Plugin();
|
|
|
|
})();
|