src/pyams_skin/resources/js/ext/tinymce/dev/plugins/searchreplace/plugin.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
--- a/src/pyams_skin/resources/js/ext/tinymce/dev/plugins/searchreplace/plugin.js	Sun Jul 19 02:02:20 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,594 +0,0 @@
-/**
- * plugin.js
- *
- * Copyright, Moxiecode Systems AB
- * Released under LGPL License.
- *
- * License: http://www.tinymce.com/license
- * Contributing: http://www.tinymce.com/contributing
- */
-
-/*jshint smarttabs:true, undef:true, unused:true, latedef:true, curly:true, bitwise:true */
-/*eslint no-labels:0, no-constant-condition: 0 */
-/*global tinymce:true */
-
-(function() {
-	// Based on work developed by: James Padolsey http://james.padolsey.com
-	// released under UNLICENSE that is compatible with LGPL
-	// TODO: Handle contentEditable edgecase:
-	// <p>text<span contentEditable="false">text<span contentEditable="true">text</span>text</span>text</p>
-	function findAndReplaceDOMText(regex, node, replacementNode, captureGroup, schema) {
-		var m, matches = [], text, count = 0, doc;
-		var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap;
-
-		doc = node.ownerDocument;
-		blockElementsMap = schema.getBlockElements(); // H1-H6, P, TD etc
-		hiddenTextElementsMap = schema.getWhiteSpaceElements(); // TEXTAREA, PRE, STYLE, SCRIPT
-		shortEndedElementsMap = schema.getShortEndedElements(); // BR, IMG, INPUT
-
-		function getMatchIndexes(m, captureGroup) {
-			captureGroup = captureGroup || 0;
-
-			if (!m[0]) {
-				throw 'findAndReplaceDOMText cannot handle zero-length matches';
-			}
-
-			var index = m.index;
-
-			if (captureGroup > 0) {
-				var cg = m[captureGroup];
-
-				if (!cg) {
-					throw 'Invalid capture group';
-				}
-
-				index += m[0].indexOf(cg);
-				m[0] = cg;
-			}
-
-			return [index, index + m[0].length, [m[0]]];
-		}
-
-		function getText(node) {
-			var txt;
-
-			if (node.nodeType === 3) {
-				return node.data;
-			}
-
-			if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) {
-				return '';
-			}
-
-			txt = '';
-
-			if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) {
-				txt += '\n';
-			}
-
-			if ((node = node.firstChild)) {
-				do {
-					txt += getText(node);
-				} while ((node = node.nextSibling));
-			}
-
-			return txt;
-		}
-
-		function stepThroughMatches(node, matches, replaceFn) {
-			var startNode, endNode, startNodeIndex,
-				endNodeIndex, innerNodes = [], atIndex = 0, curNode = node,
-				matchLocation = matches.shift(), matchIndex = 0;
-
-			out: while (true) {
-				if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName]) {
-					atIndex++;
-				}
-
-				if (curNode.nodeType === 3) {
-					if (!endNode && curNode.length + atIndex >= matchLocation[1]) {
-						// We've found the ending
-						endNode = curNode;
-						endNodeIndex = matchLocation[1] - atIndex;
-					} else if (startNode) {
-						// Intersecting node
-						innerNodes.push(curNode);
-					}
-
-					if (!startNode && curNode.length + atIndex > matchLocation[0]) {
-						// We've found the match start
-						startNode = curNode;
-						startNodeIndex = matchLocation[0] - atIndex;
-					}
-
-					atIndex += curNode.length;
-				}
-
-				if (startNode && endNode) {
-					curNode = replaceFn({
-						startNode: startNode,
-						startNodeIndex: startNodeIndex,
-						endNode: endNode,
-						endNodeIndex: endNodeIndex,
-						innerNodes: innerNodes,
-						match: matchLocation[2],
-						matchIndex: matchIndex
-					});
-
-					// replaceFn has to return the node that replaced the endNode
-					// and then we step back so we can continue from the end of the
-					// match:
-					atIndex -= (endNode.length - endNodeIndex);
-					startNode = null;
-					endNode = null;
-					innerNodes = [];
-					matchLocation = matches.shift();
-					matchIndex++;
-
-					if (!matchLocation) {
-						break; // no more matches
-					}
-				} else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) {
-					// Move down
-					curNode = curNode.firstChild;
-					continue;
-				} else if (curNode.nextSibling) {
-					// Move forward:
-					curNode = curNode.nextSibling;
-					continue;
-				}
-
-				// Move forward or up:
-				while (true) {
-					if (curNode.nextSibling) {
-						curNode = curNode.nextSibling;
-						break;
-					} else if (curNode.parentNode !== node) {
-						curNode = curNode.parentNode;
-					} else {
-						break out;
-					}
-				}
-			}
-		}
-
-		/**
-		* Generates the actual replaceFn which splits up text nodes
-		* and inserts the replacement element.
-		*/
-		function genReplacer(nodeName) {
-			var makeReplacementNode;
-
-			if (typeof nodeName != 'function') {
-				var stencilNode = nodeName.nodeType ? nodeName : doc.createElement(nodeName);
-
-				makeReplacementNode = function(fill, matchIndex) {
-					var clone = stencilNode.cloneNode(false);
-
-					clone.setAttribute('data-mce-index', matchIndex);
-
-					if (fill) {
-						clone.appendChild(doc.createTextNode(fill));
-					}
-
-					return clone;
-				};
-			} else {
-				makeReplacementNode = nodeName;
-			}
-
-			return function(range) {
-				var before, after, parentNode, startNode = range.startNode,
-					endNode = range.endNode, matchIndex = range.matchIndex;
-
-				if (startNode === endNode) {
-					var node = startNode;
-
-					parentNode = node.parentNode;
-					if (range.startNodeIndex > 0) {
-						// Add `before` text node (before the match)
-						before = doc.createTextNode(node.data.substring(0, range.startNodeIndex));
-						parentNode.insertBefore(before, node);
-					}
-
-					// Create the replacement node:
-					var el = makeReplacementNode(range.match[0], matchIndex);
-					parentNode.insertBefore(el, node);
-					if (range.endNodeIndex < node.length) {
-						// Add `after` text node (after the match)
-						after = doc.createTextNode(node.data.substring(range.endNodeIndex));
-						parentNode.insertBefore(after, node);
-					}
-
-					node.parentNode.removeChild(node);
-
-					return el;
-				} else {
-					// Replace startNode -> [innerNodes...] -> endNode (in that order)
-					before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex));
-					after = doc.createTextNode(endNode.data.substring(range.endNodeIndex));
-					var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex);
-					var innerEls = [];
-
-					for (var i = 0, l = range.innerNodes.length; i < l; ++i) {
-						var innerNode = range.innerNodes[i];
-						var innerEl = makeReplacementNode(innerNode.data, matchIndex);
-						innerNode.parentNode.replaceChild(innerEl, innerNode);
-						innerEls.push(innerEl);
-					}
-
-					var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex);
-
-					parentNode = startNode.parentNode;
-					parentNode.insertBefore(before, startNode);
-					parentNode.insertBefore(elA, startNode);
-					parentNode.removeChild(startNode);
-
-					parentNode = endNode.parentNode;
-					parentNode.insertBefore(elB, endNode);
-					parentNode.insertBefore(after, endNode);
-					parentNode.removeChild(endNode);
-
-					return elB;
-				}
-			};
-		}
-
-		text = getText(node);
-		if (!text) {
-			return;
-		}
-
-		if (regex.global) {
-			while ((m = regex.exec(text))) {
-				matches.push(getMatchIndexes(m, captureGroup));
-			}
-		} else {
-			m = text.match(regex);
-			matches.push(getMatchIndexes(m, captureGroup));
-		}
-
-		if (matches.length) {
-			count = matches.length;
-			stepThroughMatches(node, matches, genReplacer(replacementNode));
-		}
-
-		return count;
-	}
-
-	function Plugin(editor) {
-		var self = this, currentIndex = -1;
-
-		function showDialog() {
-			var last = {};
-
-			function updateButtonStates() {
-				win.statusbar.find('#next').disabled(!findSpansByIndex(currentIndex + 1).length);
-				win.statusbar.find('#prev').disabled(!findSpansByIndex(currentIndex - 1).length);
-			}
-
-			function notFoundAlert() {
-				tinymce.ui.MessageBox.alert('Could not find the specified string.', function() {
-					win.find('#find')[0].focus();
-				});
-			}
-
-			var win = tinymce.ui.Factory.create({
-				type: 'window',
-				layout: "flex",
-				pack: "center",
-				align: "center",
-				onClose: function() {
-					editor.focus();
-					self.done();
-				},
-				onSubmit: function(e) {
-					var count, caseState, text, wholeWord;
-
-					e.preventDefault();
-
-					caseState = win.find('#case').checked();
-					wholeWord = win.find('#words').checked();
-
-					text = win.find('#find').value();
-					if (!text.length) {
-						self.done(false);
-						win.statusbar.items().slice(1).disabled(true);
-						return;
-					}
-
-					if (last.text == text && last.caseState == caseState && last.wholeWord == wholeWord) {
-						if (findSpansByIndex(currentIndex + 1).length === 0) {
-							notFoundAlert();
-							return;
-						}
-
-						self.next();
-						updateButtonStates();
-						return;
-					}
-
-					count = self.find(text, caseState, wholeWord);
-					if (!count) {
-						notFoundAlert();
-					}
-
-					win.statusbar.items().slice(1).disabled(count === 0);
-					updateButtonStates();
-
-					last = {
-						text: text,
-						caseState: caseState,
-						wholeWord: wholeWord
-					};
-				},
-				buttons: [
-					{text: "Find", onclick: function() {
-						win.submit();
-					}},
-					{text: "Replace", disabled: true, onclick: function() {
-						if (!self.replace(win.find('#replace').value())) {
-							win.statusbar.items().slice(1).disabled(true);
-							currentIndex = -1;
-							last = {};
-						}
-					}},
-					{text: "Replace all", disabled: true, onclick: function() {
-						self.replace(win.find('#replace').value(), true, true);
-						win.statusbar.items().slice(1).disabled(true);
-						last = {};
-					}},
-					{type: "spacer", flex: 1},
-					{text: "Prev", name: 'prev', disabled: true, onclick: function() {
-						self.prev();
-						updateButtonStates();
-					}},
-					{text: "Next", name: 'next', disabled: true, onclick: function() {
-						self.next();
-						updateButtonStates();
-					}}
-				],
-				title: "Find and replace",
-				items: {
-					type: "form",
-					padding: 20,
-					labelGap: 30,
-					spacing: 10,
-					items: [
-						{type: 'textbox', name: 'find', size: 40, label: 'Find', value: editor.selection.getNode().src},
-						{type: 'textbox', name: 'replace', size: 40, label: 'Replace with'},
-						{type: 'checkbox', name: 'case', text: 'Match case', label: ' '},
-						{type: 'checkbox', name: 'words', text: 'Whole words', label: ' '}
-					]
-				}
-			}).renderTo().reflow();
-		}
-
-		self.init = function(ed) {
-			ed.addMenuItem('searchreplace', {
-				text: 'Find and replace',
-				shortcut: 'Meta+F',
-				onclick: showDialog,
-				separator: 'before',
-				context: 'edit'
-			});
-
-			ed.addButton('searchreplace', {
-				tooltip: 'Find and replace',
-				shortcut: 'Meta+F',
-				onclick: showDialog
-			});
-
-			ed.addCommand("SearchReplace", showDialog);
-			ed.shortcuts.add('Meta+F', '', showDialog);
-		};
-
-		function getElmIndex(elm) {
-			var value = elm.getAttribute('data-mce-index');
-
-			if (typeof value == "number") {
-				return "" + value;
-			}
-
-			return value;
-		}
-
-		function markAllMatches(regex) {
-			var node, marker;
-
-			marker = editor.dom.create('span', {
-				"data-mce-bogus": 1
-			});
-
-			marker.className = 'mce-match-marker'; // IE 7 adds class="mce-match-marker" and class=mce-match-marker
-			node = editor.getBody();
-
-			self.done(false);
-
-			return findAndReplaceDOMText(regex, node, marker, false, editor.schema);
-		}
-
-		function unwrap(node) {
-			var parentNode = node.parentNode;
-
-			if (node.firstChild) {
-				parentNode.insertBefore(node.firstChild, node);
-			}
-
-			node.parentNode.removeChild(node);
-		}
-
-		function findSpansByIndex(index) {
-			var nodes, spans = [];
-
-			nodes = tinymce.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;
-		}
-
-		function moveSelection(forward) {
-			var testIndex = currentIndex, dom = editor.dom;
-
-			forward = forward !== false;
-
-			if (forward) {
-				testIndex++;
-			} else {
-				testIndex--;
-			}
-
-			dom.removeClass(findSpansByIndex(currentIndex), 'mce-match-marker-selected');
-
-			var spans = findSpansByIndex(testIndex);
-			if (spans.length) {
-				dom.addClass(findSpansByIndex(testIndex), 'mce-match-marker-selected');
-				editor.selection.scrollIntoView(spans[0]);
-				return testIndex;
-			}
-
-			return -1;
-		}
-
-		function removeNode(node) {
-			node.parentNode.removeChild(node);
-		}
-
-		self.find = function(text, matchCase, wholeWord) {
-			text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
-			text = wholeWord ? '\\b' + text + '\\b' : text;
-
-			var count = markAllMatches(new RegExp(text, matchCase ? 'g' : 'gi'));
-
-			if (count) {
-				currentIndex = -1;
-				currentIndex = moveSelection(true);
-			}
-
-			return count;
-		};
-
-		self.next = function() {
-			var index = moveSelection(true);
-
-			if (index !== -1) {
-				currentIndex = index;
-			}
-		};
-
-		self.prev = function() {
-			var index = moveSelection(false);
-
-			if (index !== -1) {
-				currentIndex = index;
-			}
-		};
-
-		self.replace = function(text, forward, all) {
-			var i, nodes, node, matchIndex, currentMatchIndex, nextIndex = currentIndex, hasMore;
-
-			forward = forward !== false;
-
-			node = editor.getBody();
-			nodes = tinymce.toArray(node.getElementsByTagName('span'));
-			for (i = 0; i < nodes.length; i++) {
-				var nodeIndex = getElmIndex(nodes[i]);
-
-				if (nodeIndex === null || !nodeIndex.length) {
-					continue;
-				}
-
-				matchIndex = currentMatchIndex = parseInt(nodeIndex, 10);
-				if (all || matchIndex === currentIndex) {
-					if (text.length) {
-						nodes[i].firstChild.nodeValue = text;
-						unwrap(nodes[i]);
-					} else {
-						removeNode(nodes[i]);
-					}
-
-					while (nodes[++i]) {
-						matchIndex = getElmIndex(nodes[i]);
-
-						if (nodeIndex === null || !nodeIndex.length) {
-							continue;
-						}
-
-						if (matchIndex === currentMatchIndex) {
-							removeNode(nodes[i]);
-						} else {
-							i--;
-							break;
-						}
-					}
-
-					if (forward) {
-						nextIndex--;
-					}
-				} else if (currentMatchIndex > currentIndex) {
-					nodes[i].setAttribute('data-mce-index', currentMatchIndex - 1);
-				}
-			}
-
-			editor.undoManager.add();
-			currentIndex = nextIndex;
-
-			if (forward) {
-				hasMore = findSpansByIndex(nextIndex + 1).length > 0;
-				self.next();
-			} else {
-				hasMore = findSpansByIndex(nextIndex - 1).length > 0;
-				self.prev();
-			}
-
-			return !all && hasMore;
-		};
-
-		self.done = function(keepEditorSelection) {
-			var i, nodes, startContainer, endContainer;
-
-			nodes = tinymce.toArray(editor.getBody().getElementsByTagName('span'));
-			for (i = 0; i < nodes.length; i++) {
-				var nodeIndex = getElmIndex(nodes[i]);
-
-				if (nodeIndex !== null && nodeIndex.length) {
-					if (nodeIndex === currentIndex.toString()) {
-						if (!startContainer) {
-							startContainer = nodes[i].firstChild;
-						}
-
-						endContainer = nodes[i].firstChild;
-					}
-
-					unwrap(nodes[i]);
-				}
-			}
-
-			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;
-			}
-		};
-	}
-
-	tinymce.PluginManager.add('searchreplace', Plugin);
-})();