/** * Copyright (c) Tiny Technologies, Inc. All rights reserved. * Licensed under the LGPL or a commercial license. * For LGPL see License.txt in the project root for license information. * For commercial licenses see https://www.tiny.cloud/ * * Version: 5.9.2 (2021-09-08) */ (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; return { get: get, set: set }; }; var global$3 = tinymce.util.Tools.resolve('tinymce.PluginManager'); var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var typeOf = function (x) { var t = typeof x; if (x === null) { return 'null'; } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) { return 'array'; } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) { return 'string'; } else { return t; } }; var isType$1 = function (type) { return function (value) { return typeOf(value) === type; }; }; var isSimpleType = function (type) { return function (value) { return typeof value === type; }; }; var isString = isType$1('string'); var isArray = isType$1('array'); var isBoolean = isSimpleType('boolean'); var isNumber = isSimpleType('number'); var noop = function () { }; var constant = function (value) { return function () { return value; }; }; var identity = function (x) { return x; }; var never = constant(false); var always = constant(true); var punctuationStr = '[!-#%-*,-\\/:;?@\\[-\\]_{}\xA1\xAB\xB7\xBB\xBF;\xB7\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1361-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u3008\u3009\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30\u2E31\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uff3f\uFF5B\uFF5D\uFF5F-\uFF65]'; var punctuation$1 = constant(punctuationStr); var none = function () { return NONE; }; var NONE = function () { var call = function (thunk) { return thunk(); }; var id = identity; var me = { fold: function (n, _s) { return n(); }, isSome: never, isNone: always, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: constant(null), getOrUndefined: constant(undefined), or: id, orThunk: call, map: none, each: noop, bind: none, exists: never, forall: always, filter: function () { return none(); }, toArray: function () { return []; }, toString: constant('none()') }; return me; }(); var some = function (a) { var constant_a = constant(a); var self = function () { return me; }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, isSome: always, isNone: never, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: function (f) { return some(f(a)); }, each: function (f) { f(a); }, bind: bind, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Optional = { some: some, none: none, from: from }; var punctuation = punctuation$1; var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var nativeSlice = Array.prototype.slice; var nativePush = Array.prototype.push; var map = function (xs, f) { var len = xs.length; var r = new Array(len); for (var i = 0; i < len; i++) { var x = xs[i]; r[i] = f(x, i); } return r; }; var each = function (xs, f) { for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; f(x, i); } }; var eachr = function (xs, f) { for (var i = xs.length - 1; i >= 0; i--) { var x = xs[i]; f(x, i); } }; var groupBy = function (xs, f) { if (xs.length === 0) { return []; } else { var wasType = f(xs[0]); var r = []; var group = []; for (var i = 0, len = xs.length; i < len; i++) { var x = xs[i]; var type = f(x); if (type !== wasType) { r.push(group); group = []; } wasType = type; group.push(x); } if (group.length !== 0) { r.push(group); } return r; } }; var foldl = function (xs, f, acc) { each(xs, function (x, i) { acc = f(acc, x, i); }); return acc; }; var flatten = function (xs) { var r = []; for (var 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; }; var bind = function (xs, f) { return flatten(map(xs, f)); }; var sort = function (xs, comparator) { var copy = nativeSlice.call(xs, 0); copy.sort(comparator); return copy; }; var hasOwnProperty = Object.hasOwnProperty; var has = function (obj, key) { return hasOwnProperty.call(obj, key); }; typeof window !== 'undefined' ? window : Function('return this;')(); var DOCUMENT = 9; var DOCUMENT_FRAGMENT = 11; var ELEMENT = 1; var TEXT = 3; var type = function (element) { return element.dom.nodeType; }; var isType = function (t) { return function (element) { return type(element) === t; }; }; var isText$1 = isType(TEXT); var rawSet = function (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'); } }; var set = function (element, key, value) { rawSet(element.dom, key, value); }; var compareDocumentPosition = function (a, b, match) { return (a.compareDocumentPosition(b) & match) !== 0; }; var documentPositionPreceding = function (a, b) { return compareDocumentPosition(a, b, Node.DOCUMENT_POSITION_PRECEDING); }; var fromHtml = function (html, scope) { var doc = scope || document; var div = doc.createElement('div'); div.innerHTML = html; if (!div.hasChildNodes() || div.childNodes.length > 1) { console.error('HTML does not have a single root node', html); throw new Error('HTML must have a single root node'); } return fromDom(div.childNodes[0]); }; var fromTag = function (tag, scope) { var doc = scope || document; var node = doc.createElement(tag); return fromDom(node); }; var fromText = function (text, scope) { var doc = scope || document; var node = doc.createTextNode(text); return fromDom(node); }; var fromDom = function (node) { if (node === null || node === undefined) { throw new Error('Node cannot be null or undefined'); } return { dom: node }; }; var fromPoint = function (docElm, x, y) { return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom); }; var SugarElement = { fromHtml: fromHtml, fromTag: fromTag, fromText: fromText, fromDom: fromDom, fromPoint: fromPoint }; var bypassSelector = function (dom) { return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0; }; var all = function (selector, scope) { var base = scope === undefined ? document : scope.dom; return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), SugarElement.fromDom); }; var parent = function (element) { return Optional.from(element.dom.parentNode).map(SugarElement.fromDom); }; var children = function (element) { return map(element.dom.childNodes, SugarElement.fromDom); }; var spot = function (element, offset) { return { element: element, offset: offset }; }; var leaf = function (element, offset) { var cs = children(element); return cs.length > 0 && offset < cs.length ? spot(cs[offset], 0) : spot(element, offset); }; var before = function (marker, element) { var parent$1 = parent(marker); parent$1.each(function (v) { v.dom.insertBefore(element.dom, marker.dom); }); }; var append = function (parent, element) { parent.dom.appendChild(element.dom); }; var wrap = function (element, wrapper) { before(element, wrapper); append(wrapper, element); }; var NodeValue = function (is, name) { var get = function (element) { if (!is(element)) { throw new Error('Can only get ' + name + ' value of a ' + name + ' node'); } return getOption(element).getOr(''); }; var getOption = function (element) { return is(element) ? Optional.from(element.dom.nodeValue) : Optional.none(); }; var set = function (element, value) { if (!is(element)) { throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node'); } element.dom.nodeValue = value; }; return { get: get, getOption: getOption, set: set }; }; var api = NodeValue(isText$1, 'text'); var get$1 = function (element) { return api.get(element); }; var descendants = function (scope, selector) { return all(selector, scope); }; var global$1 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker'); var isSimpleBoundary = function (dom, node) { return dom.isBlock(node) || has(dom.schema.getShortEndedElements(), node.nodeName); }; var isContentEditableFalse = function (dom, node) { return dom.getContentEditable(node) === 'false'; }; var isContentEditableTrueInCef = function (dom, node) { return dom.getContentEditable(node) === 'true' && dom.getContentEditableParent(node.parentNode) === 'false'; }; var isHidden = function (dom, node) { return !dom.isBlock(node) && has(dom.schema.getWhiteSpaceElements(), node.nodeName); }; var isBoundary = function (dom, node) { return isSimpleBoundary(dom, node) || isContentEditableFalse(dom, node) || isHidden(dom, node) || isContentEditableTrueInCef(dom, node); }; var isText = function (node) { return node.nodeType === 3; }; var nuSection = function () { return { sOffset: 0, fOffset: 0, elements: [] }; }; var toLeaf = function (node, offset) { return leaf(SugarElement.fromDom(node), offset); }; var walk = function (dom, walkerFn, startNode, callbacks, endNode, skipStart) { if (skipStart === void 0) { skipStart = true; } var next = skipStart ? walkerFn(false) : startNode; while (next) { var isCefNode = isContentEditableFalse(dom, next); if (isCefNode || isHidden(dom, next)) { var stopWalking = isCefNode ? callbacks.cef(next) : callbacks.boundary(next); if (stopWalking) { break; } else { next = walkerFn(true); continue; } } else if (isSimpleBoundary(dom, next)) { if (callbacks.boundary(next)) { break; } } else if (isText(next)) { callbacks.text(next); } if (next === endNode) { break; } else { next = walkerFn(false); } } }; var collectTextToBoundary = function (dom, section, node, rootNode, forwards) { if (isBoundary(dom, node)) { return; } var rootBlock = dom.getParent(rootNode, dom.isBlock); var walker = new global$1(node, rootBlock); var walkerFn = forwards ? walker.next.bind(walker) : walker.prev.bind(walker); walk(dom, walkerFn, node, { boundary: always, cef: always, text: function (next) { if (forwards) { section.fOffset += next.length; } else { section.sOffset += next.length; } section.elements.push(SugarElement.fromDom(next)); } }); }; var collect = function (dom, rootNode, startNode, endNode, callbacks, skipStart) { if (skipStart === void 0) { skipStart = true; } var walker = new global$1(startNode, rootNode); var sections = []; var current = nuSection(); collectTextToBoundary(dom, current, startNode, rootNode, false); var finishSection = function () { if (current.elements.length > 0) { sections.push(current); current = nuSection(); } return false; }; walk(dom, walker.next.bind(walker), startNode, { boundary: finishSection, cef: function (node) { finishSection(); if (callbacks) { sections.push.apply(sections, callbacks.cef(node)); } return false; }, text: function (next) { current.elements.push(SugarElement.fromDom(next)); if (callbacks) { callbacks.text(next, current); } } }, endNode, skipStart); if (endNode) { collectTextToBoundary(dom, current, endNode, rootNode, true); } finishSection(); return sections; }; var collectRangeSections = function (dom, rng) { var start = toLeaf(rng.startContainer, rng.startOffset); var startNode = start.element.dom; var end = toLeaf(rng.endContainer, rng.endOffset); var endNode = end.element.dom; return collect(dom, rng.commonAncestorContainer, startNode, endNode, { text: function (node, section) { if (node === endNode) { section.fOffset += node.length - end.offset; } else if (node === startNode) { section.sOffset += start.offset; } }, cef: function (node) { var sections = bind(descendants(SugarElement.fromDom(node), '*[contenteditable=true]'), function (e) { var ceTrueNode = e.dom; return collect(dom, ceTrueNode, ceTrueNode); }); return sort(sections, function (a, b) { return documentPositionPreceding(a.elements[0].dom, b.elements[0].dom) ? 1 : -1; }); } }, false); }; var fromRng = function (dom, rng) { return rng.collapsed ? [] : collectRangeSections(dom, rng); }; var fromNode = function (dom, node) { var rng = dom.createRng(); rng.selectNode(node); return fromRng(dom, rng); }; var fromNodes = function (dom, nodes) { return bind(nodes, function (node) { return fromNode(dom, node); }); }; var find$2 = function (text, pattern, start, finish) { if (start === void 0) { start = 0; } if (finish === void 0) { finish = text.length; } var regex = pattern.regex; regex.lastIndex = start; var results = []; var match; while (match = regex.exec(text)) { var matchedText = match[pattern.matchIndex]; var matchStart = match.index + match[0].indexOf(matchedText); var matchFinish = matchStart + matchedText.length; if (matchFinish > finish) { break; } results.push({ start: matchStart, finish: matchFinish }); regex.lastIndex = matchFinish; } return results; }; var extract = function (elements, matches) { var nodePositions = foldl(elements, function (acc, element) { var content = get$1(element); var start = acc.last; var finish = start + content.length; var positions = bind(matches, function (match, matchIdx) { if (match.start < finish && match.finish > start) { return [{ element: element, start: Math.max(start, match.start) - start, finish: Math.min(finish, match.finish) - start, matchId: matchIdx }]; } else { return []; } }); return { results: acc.results.concat(positions), last: finish }; }, { results: [], last: 0 }).results; return groupBy(nodePositions, function (position) { return position.matchId; }); }; var find$1 = function (pattern, sections) { return bind(sections, function (section) { var elements = section.elements; var content = map(elements, get$1).join(''); var positions = find$2(content, pattern, section.sOffset, content.length - section.fOffset); return extract(elements, positions); }); }; var mark = function (matches, replacementNode) { eachr(matches, function (match, idx) { eachr(match, function (pos) { var wrapper = SugarElement.fromDom(replacementNode.cloneNode(false)); set(wrapper, 'data-mce-index', idx); var textNode = pos.element.dom; if (textNode.length === pos.finish && pos.start === 0) { wrap(pos.element, wrapper); } else { if (textNode.length !== pos.finish) { textNode.splitText(pos.finish); } var matchNode = textNode.splitText(pos.start); wrap(SugarElement.fromDom(matchNode), wrapper); } }); }); }; var findAndMark = function (dom, pattern, node, replacementNode) { var textSections = fromNode(dom, node); var matches = find$1(pattern, textSections); mark(matches, replacementNode); return matches.length; }; var findAndMarkInSelection = function (dom, pattern, selection, replacementNode) { var bookmark = selection.getBookmark(); var nodes = dom.select('td[data-mce-selected],th[data-mce-selected]'); var textSections = nodes.length > 0 ? fromNodes(dom, nodes) : fromRng(dom, selection.getRng()); var matches = find$1(pattern, textSections); mark(matches, replacementNode); selection.moveToBookmark(bookmark); return matches.length; }; var getElmIndex = function (elm) { var value = elm.getAttribute('data-mce-index'); if (typeof value === 'number') { return '' + value; } return value; }; var markAllMatches = function (editor, currentSearchState, pattern, inSelection) { var marker = editor.dom.create('span', { 'data-mce-bogus': 1 }); marker.className = 'mce-match-marker'; var node = editor.getBody(); done(editor, currentSearchState, false); if (inSelection) { return findAndMarkInSelection(editor.dom, pattern, editor.selection, marker); } else { return findAndMark(editor.dom, pattern, node, marker); } }; var unwrap = function (node) { var parentNode = node.parentNode; if (node.firstChild) { parentNode.insertBefore(node.firstChild, node); } node.parentNode.removeChild(node); }; var findSpansByIndex = function (editor, index) { var spans = []; var nodes = global$2.toArray(editor.getBody().getElementsByTagName('span')); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex === null || !nodeIndex.length) { continue; } if (nodeIndex === index.toString()) { spans.push(nodes[i]); } } } return spans; }; var moveSelection = function (editor, currentSearchState, forward) { var searchState = currentSearchState.get(); var testIndex = searchState.index; var dom = editor.dom; forward = forward !== false; if (forward) { if (testIndex + 1 === searchState.count) { testIndex = 0; } else { testIndex++; } } else { if (testIndex - 1 === -1) { testIndex = searchState.count - 1; } else { testIndex--; } } dom.removeClass(findSpansByIndex(editor, searchState.index), 'mce-match-marker-selected'); var spans = findSpansByIndex(editor, testIndex); if (spans.length) { dom.addClass(findSpansByIndex(editor, testIndex), 'mce-match-marker-selected'); editor.selection.scrollIntoView(spans[0]); return testIndex; } return -1; }; var removeNode = function (dom, node) { var parent = node.parentNode; dom.remove(node); if (dom.isEmpty(parent)) { dom.remove(parent); } }; var escapeSearchText = function (text, wholeWord) { var escapedText = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&').replace(/\s/g, '[^\\S\\r\\n\\uFEFF]'); var wordRegex = '(' + escapedText + ')'; return wholeWord ? '(?:^|\\s|' + punctuation() + ')' + wordRegex + ('(?=$|\\s|' + punctuation() + ')') : wordRegex; }; var find = function (editor, currentSearchState, text, matchCase, wholeWord, inSelection) { var escapedText = escapeSearchText(text, wholeWord); var pattern = { regex: new RegExp(escapedText, matchCase ? 'g' : 'gi'), matchIndex: 1 }; var count = markAllMatches(editor, currentSearchState, pattern, inSelection); if (count) { var newIndex = moveSelection(editor, currentSearchState, true); currentSearchState.set({ index: newIndex, count: count, text: text, matchCase: matchCase, wholeWord: wholeWord, inSelection: inSelection }); } return count; }; var next = function (editor, currentSearchState) { var index = moveSelection(editor, currentSearchState, true); currentSearchState.set(__assign(__assign({}, currentSearchState.get()), { index: index })); }; var prev = function (editor, currentSearchState) { var index = moveSelection(editor, currentSearchState, false); currentSearchState.set(__assign(__assign({}, currentSearchState.get()), { index: index })); }; var isMatchSpan = function (node) { var matchIndex = getElmIndex(node); return matchIndex !== null && matchIndex.length > 0; }; var replace = function (editor, currentSearchState, text, forward, all) { var searchState = currentSearchState.get(); var currentIndex = searchState.index; var currentMatchIndex, nextIndex = currentIndex; forward = forward !== false; var node = editor.getBody(); var nodes = global$2.grep(global$2.toArray(node.getElementsByTagName('span')), isMatchSpan); for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); var matchIndex = currentMatchIndex = parseInt(nodeIndex, 10); if (all || matchIndex === searchState.index) { if (text.length) { nodes[i].firstChild.nodeValue = text; unwrap(nodes[i]); } else { removeNode(editor.dom, nodes[i]); } while (nodes[++i]) { matchIndex = parseInt(getElmIndex(nodes[i]), 10); if (matchIndex === currentMatchIndex) { removeNode(editor.dom, nodes[i]); } else { i--; break; } } if (forward) { nextIndex--; } } else if (currentMatchIndex > currentIndex) { nodes[i].setAttribute('data-mce-index', String(currentMatchIndex - 1)); } } currentSearchState.set(__assign(__assign({}, searchState), { count: all ? 0 : searchState.count - 1, index: nextIndex })); if (forward) { next(editor, currentSearchState); } else { prev(editor, currentSearchState); } return !all && currentSearchState.get().count > 0; }; var done = function (editor, currentSearchState, keepEditorSelection) { var startContainer, endContainer; var searchState = currentSearchState.get(); var nodes = global$2.toArray(editor.getBody().getElementsByTagName('span')); for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex !== null && nodeIndex.length) { if (nodeIndex === searchState.index.toString()) { if (!startContainer) { startContainer = nodes[i].firstChild; } endContainer = nodes[i].firstChild; } unwrap(nodes[i]); } } currentSearchState.set(__assign(__assign({}, searchState), { index: -1, count: 0, text: '' })); if (startContainer && endContainer) { var rng = editor.dom.createRng(); rng.setStart(startContainer, 0); rng.setEnd(endContainer, endContainer.data.length); if (keepEditorSelection !== false) { editor.selection.setRng(rng); } return rng; } }; var hasNext = function (editor, currentSearchState) { return currentSearchState.get().count > 1; }; var hasPrev = function (editor, currentSearchState) { return currentSearchState.get().count > 1; }; var get = function (editor, currentState) { var done$1 = function (keepEditorSelection) { return done(editor, currentState, keepEditorSelection); }; var find$1 = function (text, matchCase, wholeWord, inSelection) { if (inSelection === void 0) { inSelection = false; } return find(editor, currentState, text, matchCase, wholeWord, inSelection); }; var next$1 = function () { return next(editor, currentState); }; var prev$1 = function () { return prev(editor, currentState); }; var replace$1 = function (text, forward, all) { return replace(editor, currentState, text, forward, all); }; return { done: done$1, find: find$1, next: next$1, prev: prev$1, replace: replace$1 }; }; var singleton = function (doRevoke) { var subject = Cell(Optional.none()); var revoke = function () { return subject.get().each(doRevoke); }; var clear = function () { revoke(); subject.set(Optional.none()); }; var isSet = function () { return subject.get().isSome(); }; var get = function () { return subject.get(); }; var set = function (s) { revoke(); subject.set(Optional.some(s)); }; return { clear: clear, isSet: isSet, get: get, set: set }; }; var value = function () { var subject = singleton(noop); var on = function (f) { return subject.get().each(f); }; return __assign(__assign({}, subject), { on: on }); }; var global = tinymce.util.Tools.resolve('tinymce.Env'); var open = function (editor, currentSearchState) { var dialogApi = value(); editor.undoManager.add(); var selectedText = global$2.trim(editor.selection.getContent({ format: 'text' })); var updateButtonStates = function (api) { var updateNext = hasNext(editor, currentSearchState) ? api.enable : api.disable; updateNext('next'); var updatePrev = hasPrev(editor, currentSearchState) ? api.enable : api.disable; updatePrev('prev'); }; var updateSearchState = function (api) { var data = api.getData(); var current = currentSearchState.get(); currentSearchState.set(__assign(__assign({}, current), { matchCase: data.matchcase, wholeWord: data.wholewords, inSelection: data.inselection })); }; var disableAll = function (api, disable) { var buttons = [ 'replace', 'replaceall', 'prev', 'next' ]; var toggle = disable ? api.disable : api.enable; each(buttons, toggle); }; var notFoundAlert = function (api) { editor.windowManager.alert('Could not find the specified string.', function () { api.focus('findtext'); }); }; var focusButtonIfRequired = function (api, name) { if (global.browser.isSafari() && global.deviceType.isTouch() && (name === 'find' || name === 'replace' || name === 'replaceall')) { api.focus(name); } }; var reset = function (api) { done(editor, currentSearchState, false); disableAll(api, true); updateButtonStates(api); }; var doFind = function (api) { var data = api.getData(); var last = currentSearchState.get(); if (!data.findtext.length) { reset(api); return; } if (last.text === data.findtext && last.matchCase === data.matchcase && last.wholeWord === data.wholewords) { next(editor, currentSearchState); } else { var count = find(editor, currentSearchState, data.findtext, data.matchcase, data.wholewords, data.inselection); if (count <= 0) { notFoundAlert(api); } disableAll(api, count === 0); } updateButtonStates(api); }; var initialState = currentSearchState.get(); var initialData = { findtext: selectedText, replacetext: '', wholewords: initialState.wholeWord, matchcase: initialState.matchCase, inselection: initialState.inSelection }; var spec = { title: 'Find and Replace', size: 'normal', body: { type: 'panel', items: [ { type: 'bar', items: [ { type: 'input', name: 'findtext', placeholder: 'Find', maximized: true, inputMode: 'search' }, { type: 'button', name: 'prev', text: 'Previous', icon: 'action-prev', disabled: true, borderless: true }, { type: 'button', name: 'next', text: 'Next', icon: 'action-next', disabled: true, borderless: true } ] }, { type: 'input', name: 'replacetext', placeholder: 'Replace with', inputMode: 'search' } ] }, buttons: [ { type: 'menu', name: 'options', icon: 'preferences', tooltip: 'Preferences', align: 'start', items: [ { type: 'togglemenuitem', name: 'matchcase', text: 'Match case' }, { type: 'togglemenuitem', name: 'wholewords', text: 'Find whole words only' }, { type: 'togglemenuitem', name: 'inselection', text: 'Find in selection' } ] }, { type: 'custom', name: 'find', text: 'Find', primary: true }, { type: 'custom', name: 'replace', text: 'Replace', disabled: true }, { type: 'custom', name: 'replaceall', text: 'Replace all', disabled: true } ], initialData: initialData, onChange: function (api, details) { if (details.name === 'findtext' && currentSearchState.get().count > 0) { reset(api); } }, onAction: function (api, details) { var data = api.getData(); switch (details.name) { case 'find': doFind(api); break; case 'replace': if (!replace(editor, currentSearchState, data.replacetext)) { reset(api); } else { updateButtonStates(api); } break; case 'replaceall': replace(editor, currentSearchState, data.replacetext, true, true); reset(api); break; case 'prev': prev(editor, currentSearchState); updateButtonStates(api); break; case 'next': next(editor, currentSearchState); updateButtonStates(api); break; case 'matchcase': case 'wholewords': case 'inselection': updateSearchState(api); reset(api); break; } focusButtonIfRequired(api, details.name); }, onSubmit: function (api) { doFind(api); focusButtonIfRequired(api, 'find'); }, onClose: function () { editor.focus(); done(editor, currentSearchState); editor.undoManager.add(); } }; dialogApi.set(editor.windowManager.open(spec, { inline: 'toolbar' })); }; var register$1 = function (editor, currentSearchState) { editor.addCommand('SearchReplace', function () { open(editor, currentSearchState); }); }; var showDialog = function (editor, currentSearchState) { return function () { open(editor, currentSearchState); }; }; var register = function (editor, currentSearchState) { editor.ui.registry.addMenuItem('searchreplace', { text: 'Find and replace...', shortcut: 'Meta+F', onAction: showDialog(editor, currentSearchState), icon: 'search' }); editor.ui.registry.addButton('searchreplace', { tooltip: 'Find and replace', onAction: showDialog(editor, currentSearchState), icon: 'search' }); editor.shortcuts.add('Meta+F', '', showDialog(editor, currentSearchState)); }; function Plugin () { global$3.add('searchreplace', function (editor) { var currentSearchState = Cell({ index: -1, count: 0, text: '', matchCase: false, wholeWord: false, inSelection: false }); register$1(editor, currentSearchState); register(editor, currentSearchState); return get(editor, currentSearchState); }); } Plugin(); }());