tinymce_plugins_searchreplace.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. import {
  2. __commonJS
  3. } from "./chunk-2LSFTFF7.js";
  4. // node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/searchreplace/plugin.js
  5. var require_plugin = __commonJS({
  6. "node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/searchreplace/plugin.js"() {
  7. (function() {
  8. "use strict";
  9. var Cell = function(initial) {
  10. var value2 = initial;
  11. var get2 = function() {
  12. return value2;
  13. };
  14. var set2 = function(v) {
  15. value2 = v;
  16. };
  17. return {
  18. get: get2,
  19. set: set2
  20. };
  21. };
  22. var global$3 = tinymce.util.Tools.resolve("tinymce.PluginManager");
  23. var __assign = function() {
  24. __assign = Object.assign || function __assign2(t) {
  25. for (var s, i = 1, n = arguments.length; i < n; i++) {
  26. s = arguments[i];
  27. for (var p in s)
  28. if (Object.prototype.hasOwnProperty.call(s, p))
  29. t[p] = s[p];
  30. }
  31. return t;
  32. };
  33. return __assign.apply(this, arguments);
  34. };
  35. var typeOf = function(x) {
  36. var t = typeof x;
  37. if (x === null) {
  38. return "null";
  39. } else if (t === "object" && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === "Array")) {
  40. return "array";
  41. } else if (t === "object" && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === "String")) {
  42. return "string";
  43. } else {
  44. return t;
  45. }
  46. };
  47. var isType$1 = function(type2) {
  48. return function(value2) {
  49. return typeOf(value2) === type2;
  50. };
  51. };
  52. var isSimpleType = function(type2) {
  53. return function(value2) {
  54. return typeof value2 === type2;
  55. };
  56. };
  57. var isString = isType$1("string");
  58. var isArray = isType$1("array");
  59. var isBoolean = isSimpleType("boolean");
  60. var isNumber = isSimpleType("number");
  61. var noop = function() {
  62. };
  63. var constant = function(value2) {
  64. return function() {
  65. return value2;
  66. };
  67. };
  68. var identity = function(x) {
  69. return x;
  70. };
  71. var never = constant(false);
  72. var always = constant(true);
  73. var punctuationStr = "[!-#%-*,-\\/:;?@\\[-\\]_{}¡«·»¿;·՚-՟։֊־׀׃׆׳״؉؊،؍؛؞؟٪-٭۔܀-܍߷-߹࠰-࠾࡞।॥॰෴๏๚๛༄-༒༺-༽྅࿐-࿔࿙࿚၊-၏჻፡-፨᐀᙭᙮᚛᚜᛫-᛭᜵᜶។-៖៘-៚᠀-᠊᥄᥅᨞᨟᪠-᪦᪨-᪭᭚-᭠᯼-᯿᰻-᰿᱾᱿᳓‐-‧‰-⁃⁅-⁑⁓-⁞⁽⁾₍₎〈〉❨-❵⟅⟆⟦-⟯⦃-⦘⧘-⧛⧼⧽⳹-⳼⳾⳿⵰⸀-⸮⸰⸱、-〃〈-】〔-〟〰〽゠・꓾꓿꘍-꘏꙳꙾꛲-꛷꡴-꡷꣎꣏꣸-꣺꤮꤯꥟꧁-꧍꧞꧟꩜-꩟꫞꫟꯫﴾﴿︐-︙︰-﹒﹔-﹡﹣﹨﹪﹫!-#%-*,-/:;?@[-]_{}⦅-・]";
  74. var punctuation$1 = constant(punctuationStr);
  75. var none = function() {
  76. return NONE;
  77. };
  78. var NONE = function() {
  79. var call = function(thunk) {
  80. return thunk();
  81. };
  82. var id = identity;
  83. var me = {
  84. fold: function(n, _s) {
  85. return n();
  86. },
  87. isSome: never,
  88. isNone: always,
  89. getOr: id,
  90. getOrThunk: call,
  91. getOrDie: function(msg) {
  92. throw new Error(msg || "error: getOrDie called on none.");
  93. },
  94. getOrNull: constant(null),
  95. getOrUndefined: constant(void 0),
  96. or: id,
  97. orThunk: call,
  98. map: none,
  99. each: noop,
  100. bind: none,
  101. exists: never,
  102. forall: always,
  103. filter: function() {
  104. return none();
  105. },
  106. toArray: function() {
  107. return [];
  108. },
  109. toString: constant("none()")
  110. };
  111. return me;
  112. }();
  113. var some = function(a) {
  114. var constant_a = constant(a);
  115. var self = function() {
  116. return me;
  117. };
  118. var bind2 = function(f) {
  119. return f(a);
  120. };
  121. var me = {
  122. fold: function(n, s) {
  123. return s(a);
  124. },
  125. isSome: always,
  126. isNone: never,
  127. getOr: constant_a,
  128. getOrThunk: constant_a,
  129. getOrDie: constant_a,
  130. getOrNull: constant_a,
  131. getOrUndefined: constant_a,
  132. or: self,
  133. orThunk: self,
  134. map: function(f) {
  135. return some(f(a));
  136. },
  137. each: function(f) {
  138. f(a);
  139. },
  140. bind: bind2,
  141. exists: bind2,
  142. forall: bind2,
  143. filter: function(f) {
  144. return f(a) ? me : NONE;
  145. },
  146. toArray: function() {
  147. return [a];
  148. },
  149. toString: function() {
  150. return "some(" + a + ")";
  151. }
  152. };
  153. return me;
  154. };
  155. var from = function(value2) {
  156. return value2 === null || value2 === void 0 ? NONE : some(value2);
  157. };
  158. var Optional = {
  159. some,
  160. none,
  161. from
  162. };
  163. var punctuation = punctuation$1;
  164. var global$2 = tinymce.util.Tools.resolve("tinymce.Env");
  165. var global$1 = tinymce.util.Tools.resolve("tinymce.util.Tools");
  166. var nativeSlice = Array.prototype.slice;
  167. var nativePush = Array.prototype.push;
  168. var map = function(xs, f) {
  169. var len = xs.length;
  170. var r = new Array(len);
  171. for (var i = 0; i < len; i++) {
  172. var x = xs[i];
  173. r[i] = f(x, i);
  174. }
  175. return r;
  176. };
  177. var each = function(xs, f) {
  178. for (var i = 0, len = xs.length; i < len; i++) {
  179. var x = xs[i];
  180. f(x, i);
  181. }
  182. };
  183. var eachr = function(xs, f) {
  184. for (var i = xs.length - 1; i >= 0; i--) {
  185. var x = xs[i];
  186. f(x, i);
  187. }
  188. };
  189. var groupBy = function(xs, f) {
  190. if (xs.length === 0) {
  191. return [];
  192. } else {
  193. var wasType = f(xs[0]);
  194. var r = [];
  195. var group = [];
  196. for (var i = 0, len = xs.length; i < len; i++) {
  197. var x = xs[i];
  198. var type2 = f(x);
  199. if (type2 !== wasType) {
  200. r.push(group);
  201. group = [];
  202. }
  203. wasType = type2;
  204. group.push(x);
  205. }
  206. if (group.length !== 0) {
  207. r.push(group);
  208. }
  209. return r;
  210. }
  211. };
  212. var foldl = function(xs, f, acc) {
  213. each(xs, function(x, i) {
  214. acc = f(acc, x, i);
  215. });
  216. return acc;
  217. };
  218. var flatten = function(xs) {
  219. var r = [];
  220. for (var i = 0, len = xs.length; i < len; ++i) {
  221. if (!isArray(xs[i])) {
  222. throw new Error("Arr.flatten item " + i + " was not an array, input: " + xs);
  223. }
  224. nativePush.apply(r, xs[i]);
  225. }
  226. return r;
  227. };
  228. var bind = function(xs, f) {
  229. return flatten(map(xs, f));
  230. };
  231. var sort = function(xs, comparator) {
  232. var copy = nativeSlice.call(xs, 0);
  233. copy.sort(comparator);
  234. return copy;
  235. };
  236. var hasOwnProperty = Object.hasOwnProperty;
  237. var has = function(obj, key) {
  238. return hasOwnProperty.call(obj, key);
  239. };
  240. typeof window !== "undefined" ? window : Function("return this;")();
  241. var DOCUMENT = 9;
  242. var DOCUMENT_FRAGMENT = 11;
  243. var ELEMENT = 1;
  244. var TEXT = 3;
  245. var type = function(element) {
  246. return element.dom.nodeType;
  247. };
  248. var isType = function(t) {
  249. return function(element) {
  250. return type(element) === t;
  251. };
  252. };
  253. var isText$1 = isType(TEXT);
  254. var rawSet = function(dom, key, value2) {
  255. if (isString(value2) || isBoolean(value2) || isNumber(value2)) {
  256. dom.setAttribute(key, value2 + "");
  257. } else {
  258. console.error("Invalid call to Attribute.set. Key ", key, ":: Value ", value2, ":: Element ", dom);
  259. throw new Error("Attribute value was not simple");
  260. }
  261. };
  262. var set = function(element, key, value2) {
  263. rawSet(element.dom, key, value2);
  264. };
  265. var compareDocumentPosition = function(a, b, match) {
  266. return (a.compareDocumentPosition(b) & match) !== 0;
  267. };
  268. var documentPositionPreceding = function(a, b) {
  269. return compareDocumentPosition(a, b, Node.DOCUMENT_POSITION_PRECEDING);
  270. };
  271. var fromHtml = function(html, scope) {
  272. var doc = scope || document;
  273. var div = doc.createElement("div");
  274. div.innerHTML = html;
  275. if (!div.hasChildNodes() || div.childNodes.length > 1) {
  276. console.error("HTML does not have a single root node", html);
  277. throw new Error("HTML must have a single root node");
  278. }
  279. return fromDom(div.childNodes[0]);
  280. };
  281. var fromTag = function(tag, scope) {
  282. var doc = scope || document;
  283. var node = doc.createElement(tag);
  284. return fromDom(node);
  285. };
  286. var fromText = function(text, scope) {
  287. var doc = scope || document;
  288. var node = doc.createTextNode(text);
  289. return fromDom(node);
  290. };
  291. var fromDom = function(node) {
  292. if (node === null || node === void 0) {
  293. throw new Error("Node cannot be null or undefined");
  294. }
  295. return { dom: node };
  296. };
  297. var fromPoint = function(docElm, x, y) {
  298. return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
  299. };
  300. var SugarElement = {
  301. fromHtml,
  302. fromTag,
  303. fromText,
  304. fromDom,
  305. fromPoint
  306. };
  307. var bypassSelector = function(dom) {
  308. return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
  309. };
  310. var all = function(selector, scope) {
  311. var base = scope === void 0 ? document : scope.dom;
  312. return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), SugarElement.fromDom);
  313. };
  314. var parent = function(element) {
  315. return Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
  316. };
  317. var children = function(element) {
  318. return map(element.dom.childNodes, SugarElement.fromDom);
  319. };
  320. var spot = function(element, offset) {
  321. return {
  322. element,
  323. offset
  324. };
  325. };
  326. var leaf = function(element, offset) {
  327. var cs = children(element);
  328. return cs.length > 0 && offset < cs.length ? spot(cs[offset], 0) : spot(element, offset);
  329. };
  330. var before = function(marker, element) {
  331. var parent$1 = parent(marker);
  332. parent$1.each(function(v) {
  333. v.dom.insertBefore(element.dom, marker.dom);
  334. });
  335. };
  336. var append = function(parent2, element) {
  337. parent2.dom.appendChild(element.dom);
  338. };
  339. var wrap = function(element, wrapper) {
  340. before(element, wrapper);
  341. append(wrapper, element);
  342. };
  343. var NodeValue = function(is, name) {
  344. var get2 = function(element) {
  345. if (!is(element)) {
  346. throw new Error("Can only get " + name + " value of a " + name + " node");
  347. }
  348. return getOption(element).getOr("");
  349. };
  350. var getOption = function(element) {
  351. return is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();
  352. };
  353. var set2 = function(element, value2) {
  354. if (!is(element)) {
  355. throw new Error("Can only set raw " + name + " value of a " + name + " node");
  356. }
  357. element.dom.nodeValue = value2;
  358. };
  359. return {
  360. get: get2,
  361. getOption,
  362. set: set2
  363. };
  364. };
  365. var api = NodeValue(isText$1, "text");
  366. var get$1 = function(element) {
  367. return api.get(element);
  368. };
  369. var descendants = function(scope, selector) {
  370. return all(selector, scope);
  371. };
  372. var global = tinymce.util.Tools.resolve("tinymce.dom.TreeWalker");
  373. var isSimpleBoundary = function(dom, node) {
  374. return dom.isBlock(node) || has(dom.schema.getShortEndedElements(), node.nodeName);
  375. };
  376. var isContentEditableFalse = function(dom, node) {
  377. return dom.getContentEditable(node) === "false";
  378. };
  379. var isContentEditableTrueInCef = function(dom, node) {
  380. return dom.getContentEditable(node) === "true" && dom.getContentEditableParent(node.parentNode) === "false";
  381. };
  382. var isHidden = function(dom, node) {
  383. return !dom.isBlock(node) && has(dom.schema.getWhiteSpaceElements(), node.nodeName);
  384. };
  385. var isBoundary = function(dom, node) {
  386. return isSimpleBoundary(dom, node) || isContentEditableFalse(dom, node) || isHidden(dom, node) || isContentEditableTrueInCef(dom, node);
  387. };
  388. var isText = function(node) {
  389. return node.nodeType === 3;
  390. };
  391. var nuSection = function() {
  392. return {
  393. sOffset: 0,
  394. fOffset: 0,
  395. elements: []
  396. };
  397. };
  398. var toLeaf = function(node, offset) {
  399. return leaf(SugarElement.fromDom(node), offset);
  400. };
  401. var walk = function(dom, walkerFn, startNode, callbacks, endNode, skipStart) {
  402. if (skipStart === void 0) {
  403. skipStart = true;
  404. }
  405. var next2 = skipStart ? walkerFn(false) : startNode;
  406. while (next2) {
  407. var isCefNode = isContentEditableFalse(dom, next2);
  408. if (isCefNode || isHidden(dom, next2)) {
  409. var stopWalking = isCefNode ? callbacks.cef(next2) : callbacks.boundary(next2);
  410. if (stopWalking) {
  411. break;
  412. } else {
  413. next2 = walkerFn(true);
  414. continue;
  415. }
  416. } else if (isSimpleBoundary(dom, next2)) {
  417. if (callbacks.boundary(next2)) {
  418. break;
  419. }
  420. } else if (isText(next2)) {
  421. callbacks.text(next2);
  422. }
  423. if (next2 === endNode) {
  424. break;
  425. } else {
  426. next2 = walkerFn(false);
  427. }
  428. }
  429. };
  430. var collectTextToBoundary = function(dom, section, node, rootNode, forwards) {
  431. if (isBoundary(dom, node)) {
  432. return;
  433. }
  434. var rootBlock = dom.getParent(rootNode, dom.isBlock);
  435. var walker = new global(node, rootBlock);
  436. var walkerFn = forwards ? walker.next.bind(walker) : walker.prev.bind(walker);
  437. walk(dom, walkerFn, node, {
  438. boundary: always,
  439. cef: always,
  440. text: function(next2) {
  441. if (forwards) {
  442. section.fOffset += next2.length;
  443. } else {
  444. section.sOffset += next2.length;
  445. }
  446. section.elements.push(SugarElement.fromDom(next2));
  447. }
  448. });
  449. };
  450. var collect = function(dom, rootNode, startNode, endNode, callbacks, skipStart) {
  451. if (skipStart === void 0) {
  452. skipStart = true;
  453. }
  454. var walker = new global(startNode, rootNode);
  455. var sections = [];
  456. var current = nuSection();
  457. collectTextToBoundary(dom, current, startNode, rootNode, false);
  458. var finishSection = function() {
  459. if (current.elements.length > 0) {
  460. sections.push(current);
  461. current = nuSection();
  462. }
  463. return false;
  464. };
  465. walk(dom, walker.next.bind(walker), startNode, {
  466. boundary: finishSection,
  467. cef: function(node) {
  468. finishSection();
  469. if (callbacks) {
  470. sections.push.apply(sections, callbacks.cef(node));
  471. }
  472. return false;
  473. },
  474. text: function(next2) {
  475. current.elements.push(SugarElement.fromDom(next2));
  476. if (callbacks) {
  477. callbacks.text(next2, current);
  478. }
  479. }
  480. }, endNode, skipStart);
  481. if (endNode) {
  482. collectTextToBoundary(dom, current, endNode, rootNode, true);
  483. }
  484. finishSection();
  485. return sections;
  486. };
  487. var collectRangeSections = function(dom, rng) {
  488. var start = toLeaf(rng.startContainer, rng.startOffset);
  489. var startNode = start.element.dom;
  490. var end = toLeaf(rng.endContainer, rng.endOffset);
  491. var endNode = end.element.dom;
  492. return collect(dom, rng.commonAncestorContainer, startNode, endNode, {
  493. text: function(node, section) {
  494. if (node === endNode) {
  495. section.fOffset += node.length - end.offset;
  496. } else if (node === startNode) {
  497. section.sOffset += start.offset;
  498. }
  499. },
  500. cef: function(node) {
  501. var sections = bind(descendants(SugarElement.fromDom(node), "*[contenteditable=true]"), function(e) {
  502. var ceTrueNode = e.dom;
  503. return collect(dom, ceTrueNode, ceTrueNode);
  504. });
  505. return sort(sections, function(a, b) {
  506. return documentPositionPreceding(a.elements[0].dom, b.elements[0].dom) ? 1 : -1;
  507. });
  508. }
  509. }, false);
  510. };
  511. var fromRng = function(dom, rng) {
  512. return rng.collapsed ? [] : collectRangeSections(dom, rng);
  513. };
  514. var fromNode = function(dom, node) {
  515. var rng = dom.createRng();
  516. rng.selectNode(node);
  517. return fromRng(dom, rng);
  518. };
  519. var fromNodes = function(dom, nodes) {
  520. return bind(nodes, function(node) {
  521. return fromNode(dom, node);
  522. });
  523. };
  524. var find$2 = function(text, pattern, start, finish) {
  525. if (start === void 0) {
  526. start = 0;
  527. }
  528. if (finish === void 0) {
  529. finish = text.length;
  530. }
  531. var regex = pattern.regex;
  532. regex.lastIndex = start;
  533. var results = [];
  534. var match;
  535. while (match = regex.exec(text)) {
  536. var matchedText = match[pattern.matchIndex];
  537. var matchStart = match.index + match[0].indexOf(matchedText);
  538. var matchFinish = matchStart + matchedText.length;
  539. if (matchFinish > finish) {
  540. break;
  541. }
  542. results.push({
  543. start: matchStart,
  544. finish: matchFinish
  545. });
  546. regex.lastIndex = matchFinish;
  547. }
  548. return results;
  549. };
  550. var extract = function(elements, matches) {
  551. var nodePositions = foldl(elements, function(acc, element) {
  552. var content = get$1(element);
  553. var start = acc.last;
  554. var finish = start + content.length;
  555. var positions = bind(matches, function(match, matchIdx) {
  556. if (match.start < finish && match.finish > start) {
  557. return [{
  558. element,
  559. start: Math.max(start, match.start) - start,
  560. finish: Math.min(finish, match.finish) - start,
  561. matchId: matchIdx
  562. }];
  563. } else {
  564. return [];
  565. }
  566. });
  567. return {
  568. results: acc.results.concat(positions),
  569. last: finish
  570. };
  571. }, {
  572. results: [],
  573. last: 0
  574. }).results;
  575. return groupBy(nodePositions, function(position) {
  576. return position.matchId;
  577. });
  578. };
  579. var find$1 = function(pattern, sections) {
  580. return bind(sections, function(section) {
  581. var elements = section.elements;
  582. var content = map(elements, get$1).join("");
  583. var positions = find$2(content, pattern, section.sOffset, content.length - section.fOffset);
  584. return extract(elements, positions);
  585. });
  586. };
  587. var mark = function(matches, replacementNode) {
  588. eachr(matches, function(match, idx) {
  589. eachr(match, function(pos) {
  590. var wrapper = SugarElement.fromDom(replacementNode.cloneNode(false));
  591. set(wrapper, "data-mce-index", idx);
  592. var textNode = pos.element.dom;
  593. if (textNode.length === pos.finish && pos.start === 0) {
  594. wrap(pos.element, wrapper);
  595. } else {
  596. if (textNode.length !== pos.finish) {
  597. textNode.splitText(pos.finish);
  598. }
  599. var matchNode = textNode.splitText(pos.start);
  600. wrap(SugarElement.fromDom(matchNode), wrapper);
  601. }
  602. });
  603. });
  604. };
  605. var findAndMark = function(dom, pattern, node, replacementNode) {
  606. var textSections = fromNode(dom, node);
  607. var matches = find$1(pattern, textSections);
  608. mark(matches, replacementNode);
  609. return matches.length;
  610. };
  611. var findAndMarkInSelection = function(dom, pattern, selection, replacementNode) {
  612. var bookmark = selection.getBookmark();
  613. var nodes = dom.select("td[data-mce-selected],th[data-mce-selected]");
  614. var textSections = nodes.length > 0 ? fromNodes(dom, nodes) : fromRng(dom, selection.getRng());
  615. var matches = find$1(pattern, textSections);
  616. mark(matches, replacementNode);
  617. selection.moveToBookmark(bookmark);
  618. return matches.length;
  619. };
  620. var getElmIndex = function(elm) {
  621. var value2 = elm.getAttribute("data-mce-index");
  622. if (typeof value2 === "number") {
  623. return "" + value2;
  624. }
  625. return value2;
  626. };
  627. var markAllMatches = function(editor, currentSearchState, pattern, inSelection) {
  628. var marker = editor.dom.create("span", { "data-mce-bogus": 1 });
  629. marker.className = "mce-match-marker";
  630. var node = editor.getBody();
  631. done(editor, currentSearchState, false);
  632. if (inSelection) {
  633. return findAndMarkInSelection(editor.dom, pattern, editor.selection, marker);
  634. } else {
  635. return findAndMark(editor.dom, pattern, node, marker);
  636. }
  637. };
  638. var unwrap = function(node) {
  639. var parentNode = node.parentNode;
  640. if (node.firstChild) {
  641. parentNode.insertBefore(node.firstChild, node);
  642. }
  643. node.parentNode.removeChild(node);
  644. };
  645. var findSpansByIndex = function(editor, index) {
  646. var spans = [];
  647. var nodes = global$1.toArray(editor.getBody().getElementsByTagName("span"));
  648. if (nodes.length) {
  649. for (var i = 0; i < nodes.length; i++) {
  650. var nodeIndex = getElmIndex(nodes[i]);
  651. if (nodeIndex === null || !nodeIndex.length) {
  652. continue;
  653. }
  654. if (nodeIndex === index.toString()) {
  655. spans.push(nodes[i]);
  656. }
  657. }
  658. }
  659. return spans;
  660. };
  661. var moveSelection = function(editor, currentSearchState, forward) {
  662. var searchState = currentSearchState.get();
  663. var testIndex = searchState.index;
  664. var dom = editor.dom;
  665. forward = forward !== false;
  666. if (forward) {
  667. if (testIndex + 1 === searchState.count) {
  668. testIndex = 0;
  669. } else {
  670. testIndex++;
  671. }
  672. } else {
  673. if (testIndex - 1 === -1) {
  674. testIndex = searchState.count - 1;
  675. } else {
  676. testIndex--;
  677. }
  678. }
  679. dom.removeClass(findSpansByIndex(editor, searchState.index), "mce-match-marker-selected");
  680. var spans = findSpansByIndex(editor, testIndex);
  681. if (spans.length) {
  682. dom.addClass(findSpansByIndex(editor, testIndex), "mce-match-marker-selected");
  683. editor.selection.scrollIntoView(spans[0]);
  684. return testIndex;
  685. }
  686. return -1;
  687. };
  688. var removeNode = function(dom, node) {
  689. var parent2 = node.parentNode;
  690. dom.remove(node);
  691. if (dom.isEmpty(parent2)) {
  692. dom.remove(parent2);
  693. }
  694. };
  695. var escapeSearchText = function(text, wholeWord) {
  696. var escapedText = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&").replace(/\s/g, "[^\\S\\r\\n\\uFEFF]");
  697. var wordRegex = "(" + escapedText + ")";
  698. return wholeWord ? "(?:^|\\s|" + punctuation() + ")" + wordRegex + ("(?=$|\\s|" + punctuation() + ")") : wordRegex;
  699. };
  700. var find = function(editor, currentSearchState, text, matchCase, wholeWord, inSelection) {
  701. var selection = editor.selection;
  702. var escapedText = escapeSearchText(text, wholeWord);
  703. var isForwardSelection = selection.isForward();
  704. var pattern = {
  705. regex: new RegExp(escapedText, matchCase ? "g" : "gi"),
  706. matchIndex: 1
  707. };
  708. var count = markAllMatches(editor, currentSearchState, pattern, inSelection);
  709. if (global$2.browser.isSafari()) {
  710. selection.setRng(selection.getRng(), isForwardSelection);
  711. }
  712. if (count) {
  713. var newIndex = moveSelection(editor, currentSearchState, true);
  714. currentSearchState.set({
  715. index: newIndex,
  716. count,
  717. text,
  718. matchCase,
  719. wholeWord,
  720. inSelection
  721. });
  722. }
  723. return count;
  724. };
  725. var next = function(editor, currentSearchState) {
  726. var index = moveSelection(editor, currentSearchState, true);
  727. currentSearchState.set(__assign(__assign({}, currentSearchState.get()), { index }));
  728. };
  729. var prev = function(editor, currentSearchState) {
  730. var index = moveSelection(editor, currentSearchState, false);
  731. currentSearchState.set(__assign(__assign({}, currentSearchState.get()), { index }));
  732. };
  733. var isMatchSpan = function(node) {
  734. var matchIndex = getElmIndex(node);
  735. return matchIndex !== null && matchIndex.length > 0;
  736. };
  737. var replace = function(editor, currentSearchState, text, forward, all2) {
  738. var searchState = currentSearchState.get();
  739. var currentIndex = searchState.index;
  740. var currentMatchIndex, nextIndex = currentIndex;
  741. forward = forward !== false;
  742. var node = editor.getBody();
  743. var nodes = global$1.grep(global$1.toArray(node.getElementsByTagName("span")), isMatchSpan);
  744. for (var i = 0; i < nodes.length; i++) {
  745. var nodeIndex = getElmIndex(nodes[i]);
  746. var matchIndex = currentMatchIndex = parseInt(nodeIndex, 10);
  747. if (all2 || matchIndex === searchState.index) {
  748. if (text.length) {
  749. nodes[i].firstChild.nodeValue = text;
  750. unwrap(nodes[i]);
  751. } else {
  752. removeNode(editor.dom, nodes[i]);
  753. }
  754. while (nodes[++i]) {
  755. matchIndex = parseInt(getElmIndex(nodes[i]), 10);
  756. if (matchIndex === currentMatchIndex) {
  757. removeNode(editor.dom, nodes[i]);
  758. } else {
  759. i--;
  760. break;
  761. }
  762. }
  763. if (forward) {
  764. nextIndex--;
  765. }
  766. } else if (currentMatchIndex > currentIndex) {
  767. nodes[i].setAttribute("data-mce-index", String(currentMatchIndex - 1));
  768. }
  769. }
  770. currentSearchState.set(__assign(__assign({}, searchState), {
  771. count: all2 ? 0 : searchState.count - 1,
  772. index: nextIndex
  773. }));
  774. if (forward) {
  775. next(editor, currentSearchState);
  776. } else {
  777. prev(editor, currentSearchState);
  778. }
  779. return !all2 && currentSearchState.get().count > 0;
  780. };
  781. var done = function(editor, currentSearchState, keepEditorSelection) {
  782. var startContainer, endContainer;
  783. var searchState = currentSearchState.get();
  784. var nodes = global$1.toArray(editor.getBody().getElementsByTagName("span"));
  785. for (var i = 0; i < nodes.length; i++) {
  786. var nodeIndex = getElmIndex(nodes[i]);
  787. if (nodeIndex !== null && nodeIndex.length) {
  788. if (nodeIndex === searchState.index.toString()) {
  789. if (!startContainer) {
  790. startContainer = nodes[i].firstChild;
  791. }
  792. endContainer = nodes[i].firstChild;
  793. }
  794. unwrap(nodes[i]);
  795. }
  796. }
  797. currentSearchState.set(__assign(__assign({}, searchState), {
  798. index: -1,
  799. count: 0,
  800. text: ""
  801. }));
  802. if (startContainer && endContainer) {
  803. var rng = editor.dom.createRng();
  804. rng.setStart(startContainer, 0);
  805. rng.setEnd(endContainer, endContainer.data.length);
  806. if (keepEditorSelection !== false) {
  807. editor.selection.setRng(rng);
  808. }
  809. return rng;
  810. }
  811. };
  812. var hasNext = function(editor, currentSearchState) {
  813. return currentSearchState.get().count > 1;
  814. };
  815. var hasPrev = function(editor, currentSearchState) {
  816. return currentSearchState.get().count > 1;
  817. };
  818. var get = function(editor, currentState) {
  819. var done$1 = function(keepEditorSelection) {
  820. return done(editor, currentState, keepEditorSelection);
  821. };
  822. var find$12 = function(text, matchCase, wholeWord, inSelection) {
  823. if (inSelection === void 0) {
  824. inSelection = false;
  825. }
  826. return find(editor, currentState, text, matchCase, wholeWord, inSelection);
  827. };
  828. var next$1 = function() {
  829. return next(editor, currentState);
  830. };
  831. var prev$1 = function() {
  832. return prev(editor, currentState);
  833. };
  834. var replace$1 = function(text, forward, all2) {
  835. return replace(editor, currentState, text, forward, all2);
  836. };
  837. return {
  838. done: done$1,
  839. find: find$12,
  840. next: next$1,
  841. prev: prev$1,
  842. replace: replace$1
  843. };
  844. };
  845. var singleton = function(doRevoke) {
  846. var subject = Cell(Optional.none());
  847. var revoke = function() {
  848. return subject.get().each(doRevoke);
  849. };
  850. var clear = function() {
  851. revoke();
  852. subject.set(Optional.none());
  853. };
  854. var isSet = function() {
  855. return subject.get().isSome();
  856. };
  857. var get2 = function() {
  858. return subject.get();
  859. };
  860. var set2 = function(s) {
  861. revoke();
  862. subject.set(Optional.some(s));
  863. };
  864. return {
  865. clear,
  866. isSet,
  867. get: get2,
  868. set: set2
  869. };
  870. };
  871. var value = function() {
  872. var subject = singleton(noop);
  873. var on = function(f) {
  874. return subject.get().each(f);
  875. };
  876. return __assign(__assign({}, subject), { on });
  877. };
  878. var open = function(editor, currentSearchState) {
  879. var dialogApi = value();
  880. editor.undoManager.add();
  881. var selectedText = global$1.trim(editor.selection.getContent({ format: "text" }));
  882. var updateButtonStates = function(api2) {
  883. var updateNext = hasNext(editor, currentSearchState) ? api2.enable : api2.disable;
  884. updateNext("next");
  885. var updatePrev = hasPrev(editor, currentSearchState) ? api2.enable : api2.disable;
  886. updatePrev("prev");
  887. };
  888. var updateSearchState = function(api2) {
  889. var data = api2.getData();
  890. var current = currentSearchState.get();
  891. currentSearchState.set(__assign(__assign({}, current), {
  892. matchCase: data.matchcase,
  893. wholeWord: data.wholewords,
  894. inSelection: data.inselection
  895. }));
  896. };
  897. var disableAll = function(api2, disable) {
  898. var buttons = [
  899. "replace",
  900. "replaceall",
  901. "prev",
  902. "next"
  903. ];
  904. var toggle = disable ? api2.disable : api2.enable;
  905. each(buttons, toggle);
  906. };
  907. var notFoundAlert = function(api2) {
  908. editor.windowManager.alert("Could not find the specified string.", function() {
  909. api2.focus("findtext");
  910. });
  911. };
  912. var focusButtonIfRequired = function(api2, name) {
  913. if (global$2.browser.isSafari() && global$2.deviceType.isTouch() && (name === "find" || name === "replace" || name === "replaceall")) {
  914. api2.focus(name);
  915. }
  916. };
  917. var reset = function(api2) {
  918. done(editor, currentSearchState, false);
  919. disableAll(api2, true);
  920. updateButtonStates(api2);
  921. };
  922. var doFind = function(api2) {
  923. var data = api2.getData();
  924. var last = currentSearchState.get();
  925. if (!data.findtext.length) {
  926. reset(api2);
  927. return;
  928. }
  929. if (last.text === data.findtext && last.matchCase === data.matchcase && last.wholeWord === data.wholewords) {
  930. next(editor, currentSearchState);
  931. } else {
  932. var count = find(editor, currentSearchState, data.findtext, data.matchcase, data.wholewords, data.inselection);
  933. if (count <= 0) {
  934. notFoundAlert(api2);
  935. }
  936. disableAll(api2, count === 0);
  937. }
  938. updateButtonStates(api2);
  939. };
  940. var initialState = currentSearchState.get();
  941. var initialData = {
  942. findtext: selectedText,
  943. replacetext: "",
  944. wholewords: initialState.wholeWord,
  945. matchcase: initialState.matchCase,
  946. inselection: initialState.inSelection
  947. };
  948. var spec = {
  949. title: "Find and Replace",
  950. size: "normal",
  951. body: {
  952. type: "panel",
  953. items: [
  954. {
  955. type: "bar",
  956. items: [
  957. {
  958. type: "input",
  959. name: "findtext",
  960. placeholder: "Find",
  961. maximized: true,
  962. inputMode: "search"
  963. },
  964. {
  965. type: "button",
  966. name: "prev",
  967. text: "Previous",
  968. icon: "action-prev",
  969. disabled: true,
  970. borderless: true
  971. },
  972. {
  973. type: "button",
  974. name: "next",
  975. text: "Next",
  976. icon: "action-next",
  977. disabled: true,
  978. borderless: true
  979. }
  980. ]
  981. },
  982. {
  983. type: "input",
  984. name: "replacetext",
  985. placeholder: "Replace with",
  986. inputMode: "search"
  987. }
  988. ]
  989. },
  990. buttons: [
  991. {
  992. type: "menu",
  993. name: "options",
  994. icon: "preferences",
  995. tooltip: "Preferences",
  996. align: "start",
  997. items: [
  998. {
  999. type: "togglemenuitem",
  1000. name: "matchcase",
  1001. text: "Match case"
  1002. },
  1003. {
  1004. type: "togglemenuitem",
  1005. name: "wholewords",
  1006. text: "Find whole words only"
  1007. },
  1008. {
  1009. type: "togglemenuitem",
  1010. name: "inselection",
  1011. text: "Find in selection"
  1012. }
  1013. ]
  1014. },
  1015. {
  1016. type: "custom",
  1017. name: "find",
  1018. text: "Find",
  1019. primary: true
  1020. },
  1021. {
  1022. type: "custom",
  1023. name: "replace",
  1024. text: "Replace",
  1025. disabled: true
  1026. },
  1027. {
  1028. type: "custom",
  1029. name: "replaceall",
  1030. text: "Replace all",
  1031. disabled: true
  1032. }
  1033. ],
  1034. initialData,
  1035. onChange: function(api2, details) {
  1036. if (details.name === "findtext" && currentSearchState.get().count > 0) {
  1037. reset(api2);
  1038. }
  1039. },
  1040. onAction: function(api2, details) {
  1041. var data = api2.getData();
  1042. switch (details.name) {
  1043. case "find":
  1044. doFind(api2);
  1045. break;
  1046. case "replace":
  1047. if (!replace(editor, currentSearchState, data.replacetext)) {
  1048. reset(api2);
  1049. } else {
  1050. updateButtonStates(api2);
  1051. }
  1052. break;
  1053. case "replaceall":
  1054. replace(editor, currentSearchState, data.replacetext, true, true);
  1055. reset(api2);
  1056. break;
  1057. case "prev":
  1058. prev(editor, currentSearchState);
  1059. updateButtonStates(api2);
  1060. break;
  1061. case "next":
  1062. next(editor, currentSearchState);
  1063. updateButtonStates(api2);
  1064. break;
  1065. case "matchcase":
  1066. case "wholewords":
  1067. case "inselection":
  1068. updateSearchState(api2);
  1069. reset(api2);
  1070. break;
  1071. }
  1072. focusButtonIfRequired(api2, details.name);
  1073. },
  1074. onSubmit: function(api2) {
  1075. doFind(api2);
  1076. focusButtonIfRequired(api2, "find");
  1077. },
  1078. onClose: function() {
  1079. editor.focus();
  1080. done(editor, currentSearchState);
  1081. editor.undoManager.add();
  1082. }
  1083. };
  1084. dialogApi.set(editor.windowManager.open(spec, { inline: "toolbar" }));
  1085. };
  1086. var register$1 = function(editor, currentSearchState) {
  1087. editor.addCommand("SearchReplace", function() {
  1088. open(editor, currentSearchState);
  1089. });
  1090. };
  1091. var showDialog = function(editor, currentSearchState) {
  1092. return function() {
  1093. open(editor, currentSearchState);
  1094. };
  1095. };
  1096. var register = function(editor, currentSearchState) {
  1097. editor.ui.registry.addMenuItem("searchreplace", {
  1098. text: "Find and replace...",
  1099. shortcut: "Meta+F",
  1100. onAction: showDialog(editor, currentSearchState),
  1101. icon: "search"
  1102. });
  1103. editor.ui.registry.addButton("searchreplace", {
  1104. tooltip: "Find and replace",
  1105. onAction: showDialog(editor, currentSearchState),
  1106. icon: "search"
  1107. });
  1108. editor.shortcuts.add("Meta+F", "", showDialog(editor, currentSearchState));
  1109. };
  1110. function Plugin() {
  1111. global$3.add("searchreplace", function(editor) {
  1112. var currentSearchState = Cell({
  1113. index: -1,
  1114. count: 0,
  1115. text: "",
  1116. matchCase: false,
  1117. wholeWord: false,
  1118. inSelection: false
  1119. });
  1120. register$1(editor, currentSearchState);
  1121. register(editor, currentSearchState);
  1122. return get(editor, currentSearchState);
  1123. });
  1124. }
  1125. Plugin();
  1126. })();
  1127. }
  1128. });
  1129. // node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/searchreplace/index.js
  1130. require_plugin();
  1131. //# sourceMappingURL=tinymce_plugins_searchreplace.js.map