= 0; --i) {
parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));
}
}
}
_forceRemove(currentNode);
return true;
}
if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
_forceRemove(currentNode);
return true;
}
if ((tagName === 'noscript' || tagName === 'noembed') && regExpTest(/<\/no(script|embed)/i, currentNode.innerHTML)) {
_forceRemove(currentNode);
return true;
}
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
content = currentNode.textContent;
content = stringReplace(content, MUSTACHE_EXPR$1, ' ');
content = stringReplace(content, ERB_EXPR$1, ' ');
if (currentNode.textContent !== content) {
arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
currentNode.textContent = content;
}
}
_executeHook('afterSanitizeElements', currentNode, null);
return false;
};
var _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
return false;
}
if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR$1, lcName));
else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName));
else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
if (_basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value)));
else {
return false;
}
} else if (URI_SAFE_ATTRIBUTES[lcName]);
else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, '')));
else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]);
else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, '')));
else if (!value);
else {
return false;
}
return true;
};
var _basicCustomElementTest = function _basicCustomElementTest(tagName) {
return tagName.indexOf('-') > 0;
};
var _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
var attr;
var value;
var lcName;
var l;
_executeHook('beforeSanitizeAttributes', currentNode, null);
var attributes = currentNode.attributes;
if (!attributes) {
return;
}
var hookEvent = {
attrName: '',
attrValue: '',
keepAttr: true,
allowedAttributes: ALLOWED_ATTR
};
l = attributes.length;
while (l--) {
attr = attributes[l];
var _attr = attr, name = _attr.name, namespaceURI = _attr.namespaceURI;
value = name === 'value' ? attr.value : stringTrim(attr.value);
lcName = transformCaseFunc(name);
var initValue = value;
hookEvent.attrName = lcName;
hookEvent.attrValue = value;
hookEvent.keepAttr = true;
hookEvent.forceKeepAttr = undefined;
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
value = hookEvent.attrValue;
if (hookEvent.forceKeepAttr) {
continue;
}
if (!hookEvent.keepAttr) {
_removeAttribute(name, currentNode);
continue;
}
if (regExpTest(/\/>/i, value)) {
_removeAttribute(name, currentNode);
continue;
}
if (SAFE_FOR_TEMPLATES) {
value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
value = stringReplace(value, ERB_EXPR$1, ' ');
}
var lcTag = transformCaseFunc(currentNode.nodeName);
if (!_isValidAttribute(lcTag, lcName, value)) {
_removeAttribute(name, currentNode);
continue;
}
if (value !== initValue) {
try {
if (namespaceURI) {
currentNode.setAttributeNS(namespaceURI, name, value);
} else {
currentNode.setAttribute(name, value);
}
} catch (_) {
_removeAttribute(name, currentNode);
}
}
}
_executeHook('afterSanitizeAttributes', currentNode, null);
};
var _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
var shadowNode;
var shadowIterator = _createIterator(fragment);
_executeHook('beforeSanitizeShadowDOM', fragment, null);
while (shadowNode = shadowIterator.nextNode()) {
_executeHook('uponSanitizeShadowNode', shadowNode, null);
if (_sanitizeElements(shadowNode)) {
continue;
}
if (shadowNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(shadowNode.content);
}
_sanitizeAttributes(shadowNode);
}
_executeHook('afterSanitizeShadowDOM', fragment, null);
};
DOMPurify.sanitize = function (dirty, cfg) {
var body;
var importedNode;
var currentNode;
var oldNode;
var returnNode;
IS_EMPTY_INPUT = !dirty;
if (IS_EMPTY_INPUT) {
dirty = '';
}
if (typeof dirty !== 'string' && !_isNode(dirty)) {
if (typeof dirty.toString !== 'function') {
throw typeErrorCreate('toString is not a function');
} else {
dirty = dirty.toString();
if (typeof dirty !== 'string') {
throw typeErrorCreate('dirty is not a string, aborting');
}
}
}
if (!DOMPurify.isSupported) {
if (_typeof(window.toStaticHTML) === 'object' || typeof window.toStaticHTML === 'function') {
if (typeof dirty === 'string') {
return window.toStaticHTML(dirty);
}
if (_isNode(dirty)) {
return window.toStaticHTML(dirty.outerHTML);
}
}
return dirty;
}
if (!SET_CONFIG) {
_parseConfig(cfg);
}
DOMPurify.removed = [];
if (typeof dirty === 'string') {
IN_PLACE = false;
}
if (IN_PLACE) {
if (dirty.nodeName) {
var tagName = transformCaseFunc(dirty.nodeName);
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
}
}
} else if (dirty instanceof Node) {
body = _initDocument('');
importedNode = body.ownerDocument.importNode(dirty, true);
if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {
body = importedNode;
} else if (importedNode.nodeName === 'HTML') {
body = importedNode;
} else {
body.appendChild(importedNode);
}
} else {
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && dirty.indexOf('<') === -1) {
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
}
body = _initDocument(dirty);
if (!body) {
return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
}
}
if (body && FORCE_BODY) {
_forceRemove(body.firstChild);
}
var nodeIterator = _createIterator(IN_PLACE ? dirty : body);
while (currentNode = nodeIterator.nextNode()) {
if (currentNode.nodeType === 3 && currentNode === oldNode) {
continue;
}
if (_sanitizeElements(currentNode)) {
continue;
}
if (currentNode.content instanceof DocumentFragment) {
_sanitizeShadowDOM(currentNode.content);
}
_sanitizeAttributes(currentNode);
oldNode = currentNode;
}
oldNode = null;
if (IN_PLACE) {
return dirty;
}
if (RETURN_DOM) {
if (RETURN_DOM_FRAGMENT) {
returnNode = createDocumentFragment.call(body.ownerDocument);
while (body.firstChild) {
returnNode.appendChild(body.firstChild);
}
} else {
returnNode = body;
}
if (ALLOWED_ATTR.shadowroot) {
returnNode = importNode.call(originalDocument, returnNode, true);
}
return returnNode;
}
var serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
serializedHTML = '\n' + serializedHTML;
}
if (SAFE_FOR_TEMPLATES) {
serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$1, ' ');
serializedHTML = stringReplace(serializedHTML, ERB_EXPR$1, ' ');
}
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
};
DOMPurify.setConfig = function (cfg) {
_parseConfig(cfg);
SET_CONFIG = true;
};
DOMPurify.clearConfig = function () {
CONFIG = null;
SET_CONFIG = false;
};
DOMPurify.isValidAttribute = function (tag, attr, value) {
if (!CONFIG) {
_parseConfig({});
}
var lcTag = transformCaseFunc(tag);
var lcName = transformCaseFunc(attr);
return _isValidAttribute(lcTag, lcName, value);
};
DOMPurify.addHook = function (entryPoint, hookFunction) {
if (typeof hookFunction !== 'function') {
return;
}
hooks[entryPoint] = hooks[entryPoint] || [];
arrayPush(hooks[entryPoint], hookFunction);
};
DOMPurify.removeHook = function (entryPoint) {
if (hooks[entryPoint]) {
return arrayPop(hooks[entryPoint]);
}
};
DOMPurify.removeHooks = function (entryPoint) {
if (hooks[entryPoint]) {
hooks[entryPoint] = [];
}
};
DOMPurify.removeAllHooks = function () {
hooks = {};
};
return DOMPurify;
}
var purify = createDOMPurify();
const sanitizeHtmlString = html => purify().sanitize(html);
const isTouch = global$5.deviceType.isTouch();
const hiddenHeader = (title, close) => ({
dom: {
tag: 'div',
styles: { display: 'none' },
classes: ['tox-dialog__header']
},
components: [
title,
close
]
});
const pClose = (onClose, providersBackstage) => ModalDialog.parts.close(Button.sketch({
dom: {
tag: 'button',
classes: [
'tox-button',
'tox-button--icon',
'tox-button--naked'
],
attributes: {
'type': 'button',
'aria-label': providersBackstage.translate('Close')
}
},
action: onClose,
buttonBehaviours: derive$1([Tabstopping.config({})])
}));
const pUntitled = () => ModalDialog.parts.title({
dom: {
tag: 'div',
classes: ['tox-dialog__title'],
innerHtml: '',
styles: { display: 'none' }
}
});
const pBodyMessage = (message, providersBackstage) => ModalDialog.parts.body({
dom: {
tag: 'div',
classes: ['tox-dialog__body']
},
components: [{
dom: {
tag: 'div',
classes: ['tox-dialog__body-content']
},
components: [{ dom: fromHtml(`${ sanitizeHtmlString(providersBackstage.translate(message)) }
`) }]
}]
});
const pFooter = buttons => ModalDialog.parts.footer({
dom: {
tag: 'div',
classes: ['tox-dialog__footer']
},
components: buttons
});
const pFooterGroup = (startButtons, endButtons) => [
Container.sketch({
dom: {
tag: 'div',
classes: ['tox-dialog__footer-start']
},
components: startButtons
}),
Container.sketch({
dom: {
tag: 'div',
classes: ['tox-dialog__footer-end']
},
components: endButtons
})
];
const renderDialog$1 = spec => {
const dialogClass = 'tox-dialog';
const blockerClass = dialogClass + '-wrap';
const blockerBackdropClass = blockerClass + '__backdrop';
const scrollLockClass = dialogClass + '__disable-scroll';
return ModalDialog.sketch({
lazySink: spec.lazySink,
onEscape: comp => {
spec.onEscape(comp);
return Optional.some(true);
},
useTabstopAt: elem => !isPseudoStop(elem),
firstTabstop: spec.firstTabstop,
dom: {
tag: 'div',
classes: [dialogClass].concat(spec.extraClasses),
styles: {
position: 'relative',
...spec.extraStyles
}
},
components: [
spec.header,
spec.body,
...spec.footer.toArray()
],
parts: {
blocker: {
dom: fromHtml(``),
components: [{
dom: {
tag: 'div',
classes: isTouch ? [
blockerBackdropClass,
blockerBackdropClass + '--opaque'
] : [blockerBackdropClass]
}
}]
}
},
dragBlockClass: blockerClass,
modalBehaviours: derive$1([
Focusing.config({}),
config('dialog-events', spec.dialogEvents.concat([runOnSource(focusin(), (comp, _se) => {
Keying.focusIn(comp);
})])),
config('scroll-lock', [
runOnAttached(() => {
add$2(body(), scrollLockClass);
}),
runOnDetached(() => {
remove$2(body(), scrollLockClass);
})
]),
...spec.extraBehaviours
]),
eventOrder: {
[execute$5()]: ['dialog-events'],
[attachedToDom()]: [
'scroll-lock',
'dialog-events',
'alloy.base.behaviour'
],
[detachedFromDom()]: [
'alloy.base.behaviour',
'dialog-events',
'scroll-lock'
],
...spec.eventOrder
}
});
};
const renderClose = providersBackstage => Button.sketch({
dom: {
tag: 'button',
classes: [
'tox-button',
'tox-button--icon',
'tox-button--naked'
],
attributes: {
'type': 'button',
'aria-label': providersBackstage.translate('Close'),
'title': providersBackstage.translate('Close')
}
},
buttonBehaviours: derive$1([Tabstopping.config({})]),
components: [render$3('close', {
tag: 'div',
classes: ['tox-icon']
}, providersBackstage.icons)],
action: comp => {
emit(comp, formCancelEvent);
}
});
const renderTitle = (spec, dialogId, titleId, providersBackstage) => {
const renderComponents = data => [text$2(providersBackstage.translate(data.title))];
return {
dom: {
tag: 'div',
classes: ['tox-dialog__title'],
attributes: { ...titleId.map(x => ({ id: x })).getOr({}) }
},
components: [],
behaviours: derive$1([Reflecting.config({
channel: `${ titleChannel }-${ dialogId }`,
initialData: spec,
renderComponents
})])
};
};
const renderDragHandle = () => ({ dom: fromHtml('') });
const renderInlineHeader = (spec, dialogId, titleId, providersBackstage) => Container.sketch({
dom: fromHtml(''),
components: [
renderTitle(spec, dialogId, Optional.some(titleId), providersBackstage),
renderDragHandle(),
renderClose(providersBackstage)
],
containerBehaviours: derive$1([Dragging.config({
mode: 'mouse',
blockerClass: 'blocker',
getTarget: handle => {
return closest$1(handle, '[role="dialog"]').getOrDie();
},
snaps: {
getSnapPoints: () => [],
leftAttr: 'data-drag-left',
topAttr: 'data-drag-top'
}
})])
});
const renderModalHeader = (spec, dialogId, providersBackstage) => {
const pTitle = ModalDialog.parts.title(renderTitle(spec, dialogId, Optional.none(), providersBackstage));
const pHandle = ModalDialog.parts.draghandle(renderDragHandle());
const pClose = ModalDialog.parts.close(renderClose(providersBackstage));
const components = [pTitle].concat(spec.draggable ? [pHandle] : []).concat([pClose]);
return Container.sketch({
dom: fromHtml(''),
components
});
};
const getHeader = (title, dialogId, backstage) => renderModalHeader({
title: backstage.shared.providers.translate(title),
draggable: backstage.dialog.isDraggableModal()
}, dialogId, backstage.shared.providers);
const getBusySpec = (message, bs, providers) => ({
dom: {
tag: 'div',
classes: ['tox-dialog__busy-spinner'],
attributes: { 'aria-label': providers.translate(message) },
styles: {
left: '0px',
right: '0px',
bottom: '0px',
top: '0px',
position: 'absolute'
}
},
behaviours: bs,
components: [{ dom: fromHtml('') }]
});
const getEventExtras = (lazyDialog, providers, extra) => ({
onClose: () => extra.closeWindow(),
onBlock: blockEvent => {
ModalDialog.setBusy(lazyDialog(), (_comp, bs) => getBusySpec(blockEvent.message, bs, providers));
},
onUnblock: () => {
ModalDialog.setIdle(lazyDialog());
}
});
const renderModalDialog = (spec, initialData, dialogEvents, backstage) => {
const updateState = (_comp, incoming) => Optional.some(incoming);
return build$1(renderDialog$1({
...spec,
firstTabstop: 1,
lazySink: backstage.shared.getSink,
extraBehaviours: [
Reflecting.config({
channel: `${ dialogChannel }-${ spec.id }`,
updateState,
initialData
}),
RepresentingConfigs.memory({}),
...spec.extraBehaviours
],
onEscape: comp => {
emit(comp, formCancelEvent);
},
dialogEvents,
eventOrder: {
[receive()]: [
Reflecting.name(),
Receiving.name()
],
[attachedToDom()]: [
'scroll-lock',
Reflecting.name(),
'messages',
'dialog-events',
'alloy.base.behaviour'
],
[detachedFromDom()]: [
'alloy.base.behaviour',
'dialog-events',
'messages',
Reflecting.name(),
'scroll-lock'
]
}
}));
};
const mapMenuButtons = (buttons, menuItemStates = {}) => {
const mapItems = button => {
const items = map$2(button.items, item => {
const cell = get$g(menuItemStates, item.name).getOr(Cell(false));
return {
...item,
storage: cell
};
});
return {
...button,
items
};
};
return map$2(buttons, button => {
return button.type === 'menu' ? mapItems(button) : button;
});
};
const extractCellsToObject = buttons => foldl(buttons, (acc, button) => {
if (button.type === 'menu') {
const menuButton = button;
return foldl(menuButton.items, (innerAcc, item) => {
innerAcc[item.name] = item.storage;
return innerAcc;
}, acc);
}
return acc;
}, {});
const initCommonEvents = (fireApiEvent, extras) => [
runWithTarget(focusin(), onFocus),
fireApiEvent(formCloseEvent, (_api, spec, _event, self) => {
active$1(getRootNode(self.element)).fold(noop, blur$1);
extras.onClose();
spec.onClose();
}),
fireApiEvent(formCancelEvent, (api, spec, _event, self) => {
spec.onCancel(api);
emit(self, formCloseEvent);
}),
run$1(formUnblockEvent, (_c, _se) => extras.onUnblock()),
run$1(formBlockEvent, (_c, se) => extras.onBlock(se.event))
];
const initUrlDialog = (getInstanceApi, extras) => {
const fireApiEvent = (eventName, f) => run$1(eventName, (c, se) => {
withSpec(c, (spec, _c) => {
f(getInstanceApi(), spec, se.event, c);
});
});
const withSpec = (c, f) => {
Reflecting.getState(c).get().each(currentDialog => {
f(currentDialog, c);
});
};
return [
...initCommonEvents(fireApiEvent, extras),
fireApiEvent(formActionEvent, (api, spec, event) => {
spec.onAction(api, { name: event.name });
})
];
};
const initDialog = (getInstanceApi, extras, getSink) => {
const fireApiEvent = (eventName, f) => run$1(eventName, (c, se) => {
withSpec(c, (spec, _c) => {
f(getInstanceApi(), spec, se.event, c);
});
});
const withSpec = (c, f) => {
Reflecting.getState(c).get().each(currentDialogInit => {
f(currentDialogInit.internalDialog, c);
});
};
return [
...initCommonEvents(fireApiEvent, extras),
fireApiEvent(formSubmitEvent, (api, spec) => spec.onSubmit(api)),
fireApiEvent(formChangeEvent, (api, spec, event) => {
spec.onChange(api, { name: event.name });
}),
fireApiEvent(formActionEvent, (api, spec, event, component) => {
const focusIn = () => Keying.focusIn(component);
const isDisabled = focused => has$1(focused, 'disabled') || getOpt(focused, 'aria-disabled').exists(val => val === 'true');
const rootNode = getRootNode(component.element);
const current = active$1(rootNode);
spec.onAction(api, {
name: event.name,
value: event.value
});
active$1(rootNode).fold(focusIn, focused => {
if (isDisabled(focused)) {
focusIn();
} else if (current.exists(cur => contains(focused, cur) && isDisabled(cur))) {
focusIn();
} else {
getSink().toOptional().filter(sink => !contains(sink.element, focused)).each(focusIn);
}
});
}),
fireApiEvent(formTabChangeEvent, (api, spec, event) => {
spec.onTabChange(api, {
newTabName: event.name,
oldTabName: event.oldName
});
}),
runOnDetached(component => {
const api = getInstanceApi();
Representing.setValue(component, api.getData());
})
];
};
const SilverDialogEvents = {
initUrlDialog,
initDialog
};
const makeButton = (button, backstage) => renderFooterButton(button, button.type, backstage);
const lookup = (compInSystem, footerButtons, buttonName) => find$5(footerButtons, button => button.name === buttonName).bind(memButton => memButton.memento.getOpt(compInSystem));
const renderComponents = (_data, state) => {
const footerButtons = state.map(s => s.footerButtons).getOr([]);
const buttonGroups = partition$3(footerButtons, button => button.align === 'start');
const makeGroup = (edge, buttons) => Container.sketch({
dom: {
tag: 'div',
classes: [`tox-dialog__footer-${ edge }`]
},
components: map$2(buttons, button => button.memento.asSpec())
});
const startButtons = makeGroup('start', buttonGroups.pass);
const endButtons = makeGroup('end', buttonGroups.fail);
return [
startButtons,
endButtons
];
};
const renderFooter = (initSpec, dialogId, backstage) => {
const updateState = (comp, data) => {
const footerButtons = map$2(data.buttons, button => {
const memButton = record(makeButton(button, backstage));
return {
name: button.name,
align: button.align,
memento: memButton
};
});
const lookupByName = buttonName => lookup(comp, footerButtons, buttonName);
return Optional.some({
lookupByName,
footerButtons
});
};
return {
dom: fromHtml(''),
components: [],
behaviours: derive$1([Reflecting.config({
channel: `${ footerChannel }-${ dialogId }`,
initialData: initSpec,
updateState,
renderComponents
})])
};
};
const renderInlineFooter = (initSpec, dialogId, backstage) => renderFooter(initSpec, dialogId, backstage);
const renderModalFooter = (initSpec, dialogId, backstage) => ModalDialog.parts.footer(renderFooter(initSpec, dialogId, backstage));
const getCompByName = (access, name) => {
const root = access.getRoot();
if (root.getSystem().isConnected()) {
const form = Composing.getCurrent(access.getFormWrapper()).getOr(access.getFormWrapper());
return Form.getField(form, name).orThunk(() => {
const footer = access.getFooter();
const footerState = Reflecting.getState(footer).get();
return footerState.bind(f => f.lookupByName(name));
});
} else {
return Optional.none();
}
};
const validateData$1 = (access, data) => {
const root = access.getRoot();
return Reflecting.getState(root).get().map(dialogState => getOrDie(asRaw('data', dialogState.dataValidator, data))).getOr(data);
};
const getDialogApi = (access, doRedial, menuItemStates) => {
const withRoot = f => {
const root = access.getRoot();
if (root.getSystem().isConnected()) {
f(root);
}
};
const getData = () => {
const root = access.getRoot();
const valueComp = root.getSystem().isConnected() ? access.getFormWrapper() : root;
const representedValues = Representing.getValue(valueComp);
const menuItemCurrentState = map$1(menuItemStates, cell => cell.get());
return {
...representedValues,
...menuItemCurrentState
};
};
const setData = newData => {
withRoot(_ => {
const prevData = instanceApi.getData();
const mergedData = deepMerge(prevData, newData);
const newInternalData = validateData$1(access, mergedData);
const form = access.getFormWrapper();
Representing.setValue(form, newInternalData);
each(menuItemStates, (v, k) => {
if (has$2(mergedData, k)) {
v.set(mergedData[k]);
}
});
});
};
const setEnabled = (name, state) => {
getCompByName(access, name).each(state ? Disabling.enable : Disabling.disable);
};
const focus = name => {
getCompByName(access, name).each(Focusing.focus);
};
const block = message => {
if (!isString(message)) {
throw new Error('The dialogInstanceAPI.block function should be passed a blocking message of type string as an argument');
}
withRoot(root => {
emitWith(root, formBlockEvent, { message });
});
};
const unblock = () => {
withRoot(root => {
emit(root, formUnblockEvent);
});
};
const showTab = name => {
withRoot(_ => {
const body = access.getBody();
const bodyState = Reflecting.getState(body);
if (bodyState.get().exists(b => b.isTabPanel())) {
Composing.getCurrent(body).each(tabSection => {
TabSection.showTab(tabSection, name);
});
}
});
};
const redial = d => {
withRoot(root => {
const id = access.getId();
const dialogInit = doRedial(d);
const storedMenuButtons = mapMenuButtons(dialogInit.internalDialog.buttons, menuItemStates);
root.getSystem().broadcastOn([`${ dialogChannel }-${ id }`], dialogInit);
root.getSystem().broadcastOn([`${ titleChannel }-${ id }`], dialogInit.internalDialog);
root.getSystem().broadcastOn([`${ bodyChannel }-${ id }`], dialogInit.internalDialog);
root.getSystem().broadcastOn([`${ footerChannel }-${ id }`], {
...dialogInit.internalDialog,
buttons: storedMenuButtons
});
instanceApi.setData(dialogInit.initialData);
});
};
const close = () => {
withRoot(root => {
emit(root, formCloseEvent);
});
};
const instanceApi = {
getData,
setData,
setEnabled,
focus,
block,
unblock,
showTab,
redial,
close,
toggleFullscreen: access.toggleFullscreen
};
return instanceApi;
};
const getDialogSizeClasses = size => {
switch (size) {
case 'large':
return ['tox-dialog--width-lg'];
case 'medium':
return ['tox-dialog--width-md'];
default:
return [];
}
};
const renderDialog = (dialogInit, extra, backstage) => {
const dialogId = generate$6('dialog');
const internalDialog = dialogInit.internalDialog;
const header = getHeader(internalDialog.title, dialogId, backstage);
const body = renderModalBody({
body: internalDialog.body,
initialData: internalDialog.initialData
}, dialogId, backstage);
const storedMenuButtons = mapMenuButtons(internalDialog.buttons);
const objOfCells = extractCellsToObject(storedMenuButtons);
const footer = renderModalFooter({ buttons: storedMenuButtons }, dialogId, backstage);
const dialogEvents = SilverDialogEvents.initDialog(() => instanceApi, getEventExtras(() => dialog, backstage.shared.providers, extra), backstage.shared.getSink);
const dialogSize = getDialogSizeClasses(internalDialog.size);
const spec = {
id: dialogId,
header,
body,
footer: Optional.some(footer),
extraClasses: dialogSize,
extraBehaviours: [],
extraStyles: {}
};
const dialog = renderModalDialog(spec, dialogInit, dialogEvents, backstage);
const modalAccess = (() => {
const getForm = () => {
const outerForm = ModalDialog.getBody(dialog);
return Composing.getCurrent(outerForm).getOr(outerForm);
};
const toggleFullscreen = () => {
const fullscreenClass = 'tox-dialog--fullscreen';
const sugarBody = SugarElement.fromDom(dialog.element.dom);
if (!has(sugarBody, fullscreenClass)) {
remove$1(sugarBody, dialogSize);
add$2(sugarBody, fullscreenClass);
} else {
remove$2(sugarBody, fullscreenClass);
add$1(sugarBody, dialogSize);
}
};
return {
getId: constant$1(dialogId),
getRoot: constant$1(dialog),
getBody: () => ModalDialog.getBody(dialog),
getFooter: () => ModalDialog.getFooter(dialog),
getFormWrapper: getForm,
toggleFullscreen
};
})();
const instanceApi = getDialogApi(modalAccess, extra.redial, objOfCells);
return {
dialog,
instanceApi
};
};
const renderInlineDialog = (dialogInit, extra, backstage, ariaAttrs) => {
const dialogId = generate$6('dialog');
const dialogLabelId = generate$6('dialog-label');
const dialogContentId = generate$6('dialog-content');
const internalDialog = dialogInit.internalDialog;
const updateState = (_comp, incoming) => Optional.some(incoming);
const memHeader = record(renderInlineHeader({
title: internalDialog.title,
draggable: true
}, dialogId, dialogLabelId, backstage.shared.providers));
const memBody = record(renderInlineBody({
body: internalDialog.body,
initialData: internalDialog.initialData
}, dialogId, dialogContentId, backstage, ariaAttrs));
const storagedMenuButtons = mapMenuButtons(internalDialog.buttons);
const objOfCells = extractCellsToObject(storagedMenuButtons);
const memFooter = record(renderInlineFooter({ buttons: storagedMenuButtons }, dialogId, backstage));
const dialogEvents = SilverDialogEvents.initDialog(() => instanceApi, {
onBlock: event => {
Blocking.block(dialog, (_comp, bs) => getBusySpec(event.message, bs, backstage.shared.providers));
},
onUnblock: () => {
Blocking.unblock(dialog);
},
onClose: () => extra.closeWindow()
}, backstage.shared.getSink);
const inlineClass = 'tox-dialog-inline';
const dialog = build$1({
dom: {
tag: 'div',
classes: [
'tox-dialog',
inlineClass
],
attributes: {
role: 'dialog',
['aria-labelledby']: dialogLabelId,
['aria-describedby']: dialogContentId
}
},
eventOrder: {
[receive()]: [
Reflecting.name(),
Receiving.name()
],
[execute$5()]: ['execute-on-form'],
[attachedToDom()]: [
'reflecting',
'execute-on-form'
]
},
behaviours: derive$1([
Keying.config({
mode: 'cyclic',
onEscape: c => {
emit(c, formCloseEvent);
return Optional.some(true);
},
useTabstopAt: elem => !isPseudoStop(elem) && (name$3(elem) !== 'button' || get$f(elem, 'disabled') !== 'disabled'),
firstTabstop: 1
}),
Reflecting.config({
channel: `${ dialogChannel }-${ dialogId }`,
updateState,
initialData: dialogInit
}),
Focusing.config({}),
config('execute-on-form', dialogEvents.concat([runOnSource(focusin(), (comp, _se) => {
Keying.focusIn(comp);
})])),
Blocking.config({ getRoot: () => Optional.some(dialog) }),
Replacing.config({}),
RepresentingConfigs.memory({})
]),
components: [
memHeader.asSpec(),
memBody.asSpec(),
memFooter.asSpec()
]
});
const toggleFullscreen = () => {
const fullscreenClass = 'tox-dialog--fullscreen';
const sugarBody = SugarElement.fromDom(dialog.element.dom);
if (!hasAll(sugarBody, [fullscreenClass])) {
remove$1(sugarBody, [inlineClass]);
add$1(sugarBody, [fullscreenClass]);
} else {
remove$1(sugarBody, [fullscreenClass]);
add$1(sugarBody, [inlineClass]);
}
};
const instanceApi = getDialogApi({
getId: constant$1(dialogId),
getRoot: constant$1(dialog),
getFooter: () => memFooter.get(dialog),
getBody: () => memBody.get(dialog),
getFormWrapper: () => {
const body = memBody.get(dialog);
return Composing.getCurrent(body).getOr(body);
},
toggleFullscreen
}, extra.redial, objOfCells);
return {
dialog,
instanceApi
};
};
var global = tinymce.util.Tools.resolve('tinymce.util.URI');
const getUrlDialogApi = root => {
const withRoot = f => {
if (root.getSystem().isConnected()) {
f(root);
}
};
const block = message => {
if (!isString(message)) {
throw new Error('The urlDialogInstanceAPI.block function should be passed a blocking message of type string as an argument');
}
withRoot(root => {
emitWith(root, formBlockEvent, { message });
});
};
const unblock = () => {
withRoot(root => {
emit(root, formUnblockEvent);
});
};
const close = () => {
withRoot(root => {
emit(root, formCloseEvent);
});
};
const sendMessage = data => {
withRoot(root => {
root.getSystem().broadcastOn([bodySendMessageChannel], data);
});
};
return {
block,
unblock,
close,
sendMessage
};
};
const SUPPORTED_MESSAGE_ACTIONS = [
'insertContent',
'setContent',
'execCommand',
'close',
'block',
'unblock'
];
const isSupportedMessage = data => isObject(data) && SUPPORTED_MESSAGE_ACTIONS.indexOf(data.mceAction) !== -1;
const isCustomMessage = data => !isSupportedMessage(data) && isObject(data) && has$2(data, 'mceAction');
const handleMessage = (editor, api, data) => {
switch (data.mceAction) {
case 'insertContent':
editor.insertContent(data.content);
break;
case 'setContent':
editor.setContent(data.content);
break;
case 'execCommand':
const ui = isBoolean(data.ui) ? data.ui : false;
editor.execCommand(data.cmd, ui, data.value);
break;
case 'close':
api.close();
break;
case 'block':
api.block(data.message);
break;
case 'unblock':
api.unblock();
break;
}
};
const renderUrlDialog = (internalDialog, extra, editor, backstage) => {
const dialogId = generate$6('dialog');
const header = getHeader(internalDialog.title, dialogId, backstage);
const body = renderIframeBody(internalDialog);
const footer = internalDialog.buttons.bind(buttons => {
if (buttons.length === 0) {
return Optional.none();
} else {
return Optional.some(renderModalFooter({ buttons }, dialogId, backstage));
}
});
const dialogEvents = SilverDialogEvents.initUrlDialog(() => instanceApi, getEventExtras(() => dialog, backstage.shared.providers, extra));
const styles = {
...internalDialog.height.fold(() => ({}), height => ({
'height': height + 'px',
'max-height': height + 'px'
})),
...internalDialog.width.fold(() => ({}), width => ({
'width': width + 'px',
'max-width': width + 'px'
}))
};
const classes = internalDialog.width.isNone() && internalDialog.height.isNone() ? ['tox-dialog--width-lg'] : [];
const iframeUri = new global(internalDialog.url, { base_uri: new global(window.location.href) });
const iframeDomain = `${ iframeUri.protocol }://${ iframeUri.host }${ iframeUri.port ? ':' + iframeUri.port : '' }`;
const messageHandlerUnbinder = unbindable();
const extraBehaviours = [
config('messages', [
runOnAttached(() => {
const unbind = bind(SugarElement.fromDom(window), 'message', e => {
if (iframeUri.isSameOrigin(new global(e.raw.origin))) {
const data = e.raw.data;
if (isSupportedMessage(data)) {
handleMessage(editor, instanceApi, data);
} else if (isCustomMessage(data)) {
internalDialog.onMessage(instanceApi, data);
}
}
});
messageHandlerUnbinder.set(unbind);
}),
runOnDetached(messageHandlerUnbinder.clear)
]),
Receiving.config({
channels: {
[bodySendMessageChannel]: {
onReceive: (comp, data) => {
descendant(comp.element, 'iframe').each(iframeEle => {
const iframeWin = iframeEle.dom.contentWindow;
if (isNonNullable(iframeWin)) {
iframeWin.postMessage(data, iframeDomain);
}
});
}
}
}
})
];
const spec = {
id: dialogId,
header,
body,
footer,
extraClasses: classes,
extraBehaviours,
extraStyles: styles
};
const dialog = renderModalDialog(spec, internalDialog, dialogEvents, backstage);
const instanceApi = getUrlDialogApi(dialog);
return {
dialog,
instanceApi
};
};
const setup$2 = backstage => {
const sharedBackstage = backstage.shared;
const open = (message, callback) => {
const closeDialog = () => {
ModalDialog.hide(alertDialog);
callback();
};
const memFooterClose = record(renderFooterButton({
name: 'close-alert',
text: 'OK',
primary: true,
buttonType: Optional.some('primary'),
align: 'end',
enabled: true,
icon: Optional.none()
}, 'cancel', backstage));
const titleSpec = pUntitled();
const closeSpec = pClose(closeDialog, sharedBackstage.providers);
const alertDialog = build$1(renderDialog$1({
lazySink: () => sharedBackstage.getSink(),
header: hiddenHeader(titleSpec, closeSpec),
body: pBodyMessage(message, sharedBackstage.providers),
footer: Optional.some(pFooter(pFooterGroup([], [memFooterClose.asSpec()]))),
onEscape: closeDialog,
extraClasses: ['tox-alert-dialog'],
extraBehaviours: [],
extraStyles: {},
dialogEvents: [run$1(formCancelEvent, closeDialog)],
eventOrder: {}
}));
ModalDialog.show(alertDialog);
const footerCloseButton = memFooterClose.get(alertDialog);
Focusing.focus(footerCloseButton);
};
return { open };
};
const setup$1 = backstage => {
const sharedBackstage = backstage.shared;
const open = (message, callback) => {
const closeDialog = state => {
ModalDialog.hide(confirmDialog);
callback(state);
};
const memFooterYes = record(renderFooterButton({
name: 'yes',
text: 'Yes',
primary: true,
buttonType: Optional.some('primary'),
align: 'end',
enabled: true,
icon: Optional.none()
}, 'submit', backstage));
const footerNo = renderFooterButton({
name: 'no',
text: 'No',
primary: false,
buttonType: Optional.some('secondary'),
align: 'end',
enabled: true,
icon: Optional.none()
}, 'cancel', backstage);
const titleSpec = pUntitled();
const closeSpec = pClose(() => closeDialog(false), sharedBackstage.providers);
const confirmDialog = build$1(renderDialog$1({
lazySink: () => sharedBackstage.getSink(),
header: hiddenHeader(titleSpec, closeSpec),
body: pBodyMessage(message, sharedBackstage.providers),
footer: Optional.some(pFooter(pFooterGroup([], [
footerNo,
memFooterYes.asSpec()
]))),
onEscape: () => closeDialog(false),
extraClasses: ['tox-confirm-dialog'],
extraBehaviours: [],
extraStyles: {},
dialogEvents: [
run$1(formCancelEvent, () => closeDialog(false)),
run$1(formSubmitEvent, () => closeDialog(true))
],
eventOrder: {}
}));
ModalDialog.show(confirmDialog);
const footerYesButton = memFooterYes.get(confirmDialog);
Focusing.focus(footerYesButton);
};
return { open };
};
const validateData = (data, validator) => getOrDie(asRaw('data', validator, data));
const isAlertOrConfirmDialog = target => closest(target, '.tox-alert-dialog') || closest(target, '.tox-confirm-dialog');
const inlineAdditionalBehaviours = (editor, isStickyToolbar, isToolbarLocationTop) => {
if (isStickyToolbar && isToolbarLocationTop) {
return [];
} else {
return [Docking.config({
contextual: {
lazyContext: () => Optional.some(box$1(SugarElement.fromDom(editor.getContentAreaContainer()))),
fadeInClass: 'tox-dialog-dock-fadein',
fadeOutClass: 'tox-dialog-dock-fadeout',
transitionClass: 'tox-dialog-dock-transition'
},
modes: ['top'],
lazyViewport: comp => {
const optScrollingContext = detectWhenSplitUiMode(editor, comp.element);
return optScrollingContext.map(sc => {
const combinedBounds = getBoundsFrom(sc);
return {
bounds: combinedBounds,
optScrollEnv: Optional.some({
currentScrollTop: sc.element.dom.scrollTop,
scrollElmTop: absolute$3(sc.element).top
})
};
}).getOrThunk(() => ({
bounds: win(),
optScrollEnv: Optional.none()
}));
}
})];
}
};
const setup = extras => {
const editor = extras.editor;
const isStickyToolbar$1 = isStickyToolbar(editor);
const alertDialog = setup$2(extras.backstages.dialog);
const confirmDialog = setup$1(extras.backstages.dialog);
const open = (config, params, closeWindow) => {
if (params !== undefined && params.inline === 'toolbar') {
return openInlineDialog(config, extras.backstages.popup.shared.anchors.inlineDialog(), closeWindow, params.ariaAttrs);
} else if (params !== undefined && params.inline === 'cursor') {
return openInlineDialog(config, extras.backstages.popup.shared.anchors.cursor(), closeWindow, params.ariaAttrs);
} else {
return openModalDialog(config, closeWindow);
}
};
const openUrl = (config, closeWindow) => openModalUrlDialog(config, closeWindow);
const openModalUrlDialog = (config, closeWindow) => {
const factory = contents => {
const dialog = renderUrlDialog(contents, {
closeWindow: () => {
ModalDialog.hide(dialog.dialog);
closeWindow(dialog.instanceApi);
}
}, editor, extras.backstages.dialog);
ModalDialog.show(dialog.dialog);
return dialog.instanceApi;
};
return DialogManager.openUrl(factory, config);
};
const openModalDialog = (config, closeWindow) => {
const factory = (contents, internalInitialData, dataValidator) => {
const initialData = internalInitialData;
const dialogInit = {
dataValidator,
initialData,
internalDialog: contents
};
const dialog = renderDialog(dialogInit, {
redial: DialogManager.redial,
closeWindow: () => {
ModalDialog.hide(dialog.dialog);
closeWindow(dialog.instanceApi);
}
}, extras.backstages.dialog);
ModalDialog.show(dialog.dialog);
dialog.instanceApi.setData(initialData);
return dialog.instanceApi;
};
return DialogManager.open(factory, config);
};
const openInlineDialog = (config$1, anchor, closeWindow, ariaAttrs = false) => {
const factory = (contents, internalInitialData, dataValidator) => {
const initialData = validateData(internalInitialData, dataValidator);
const inlineDialog = value$2();
const isToolbarLocationTop = extras.backstages.popup.shared.header.isPositionedAtTop();
const dialogInit = {
dataValidator,
initialData,
internalDialog: contents
};
const refreshDocking = () => inlineDialog.on(dialog => {
InlineView.reposition(dialog);
Docking.refresh(dialog);
});
const dialogUi = renderInlineDialog(dialogInit, {
redial: DialogManager.redial,
closeWindow: () => {
inlineDialog.on(InlineView.hide);
editor.off('ResizeEditor', refreshDocking);
inlineDialog.clear();
closeWindow(dialogUi.instanceApi);
}
}, extras.backstages.popup, ariaAttrs);
const inlineDialogComp = build$1(InlineView.sketch({
lazySink: extras.backstages.popup.shared.getSink,
dom: {
tag: 'div',
classes: []
},
fireDismissalEventInstead: {},
...isToolbarLocationTop ? {} : { fireRepositionEventInstead: {} },
inlineBehaviours: derive$1([
config('window-manager-inline-events', [run$1(dismissRequested(), (_comp, _se) => {
emit(dialogUi.dialog, formCancelEvent);
})]),
...inlineAdditionalBehaviours(editor, isStickyToolbar$1, isToolbarLocationTop)
]),
isExtraPart: (_comp, target) => isAlertOrConfirmDialog(target)
}));
inlineDialog.set(inlineDialogComp);
const getInlineDialogBounds = () => {
const elem = editor.inline ? body() : SugarElement.fromDom(editor.getContainer());
const bounds = box$1(elem);
return Optional.some(bounds);
};
InlineView.showWithinBounds(inlineDialogComp, premade(dialogUi.dialog), { anchor }, getInlineDialogBounds);
if (!isStickyToolbar$1 || !isToolbarLocationTop) {
Docking.refresh(inlineDialogComp);
editor.on('ResizeEditor', refreshDocking);
}
dialogUi.instanceApi.setData(initialData);
Keying.focusIn(dialogUi.dialog);
return dialogUi.instanceApi;
};
return DialogManager.open(factory, config$1);
};
const confirm = (message, callback) => {
confirmDialog.open(message, callback);
};
const alert = (message, callback) => {
alertDialog.open(message, callback);
};
const close = instanceApi => {
instanceApi.close();
};
return {
open,
openUrl,
alert,
close,
confirm
};
};
const registerOptions = editor => {
register$e(editor);
register$d(editor);
register(editor);
};
var Theme = () => {
global$a.add('silver', editor => {
registerOptions(editor);
let popupSinkBounds = () => win();
const {
dialogs,
popups,
renderUI: renderModeUI
} = setup$3(editor, { getPopupSinkBounds: () => popupSinkBounds() });
const renderUI = async () => {
const renderResult = await renderModeUI();
const optScrollingContext = detectWhenSplitUiMode(editor, popups.getMothership().element);
optScrollingContext.each(sc => {
popupSinkBounds = () => {
return getBoundsFrom(sc);
};
});
return renderResult;
};
Autocompleter.register(editor, popups.backstage.shared);
const windowMgr = setup({
editor,
backstages: {
popup: popups.backstage,
dialog: dialogs.backstage
}
});
const getNotificationManagerImpl = () => NotificationManagerImpl(editor, { backstage: popups.backstage }, popups.getMothership());
return {
renderUI,
getWindowManagerImpl: constant$1(windowMgr),
getNotificationManagerImpl
};
});
};
Theme();
})();