|
|
/*!***************************************************
|
|
|
* mark.js v6.1.0
|
|
|
* https://github.com/julmot/mark.js
|
|
|
* Copyright (c) 2014–2016, Julian Motz
|
|
|
* Released under the MIT license https://git.io/vwTVl
|
|
|
*****************************************************/
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
|
|
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
|
|
(function (factory, window, document) {
|
|
|
if (typeof define === "function" && define.amd) {
|
|
|
define(["jquery"], function (jQuery) {
|
|
|
return factory(window, document, jQuery);
|
|
|
});
|
|
|
} else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object") {
|
|
|
factory(window, document, require("jquery"));
|
|
|
} else {
|
|
|
factory(window, document, jQuery);
|
|
|
}
|
|
|
})(function (window, document, $) {
|
|
|
var Mark = function () {
|
|
|
function Mark(ctx) {
|
|
|
_classCallCheck(this, Mark);
|
|
|
|
|
|
this.ctx = ctx;
|
|
|
}
|
|
|
|
|
|
_createClass(Mark, [{
|
|
|
key: "log",
|
|
|
value: function log(msg) {
|
|
|
var level = arguments.length <= 1 || arguments[1] === undefined ? "debug" : arguments[1];
|
|
|
|
|
|
var log = this.opt.log;
|
|
|
if (!this.opt.debug) {
|
|
|
return;
|
|
|
}
|
|
|
if ((typeof log === "undefined" ? "undefined" : _typeof(log)) === "object" && typeof log[level] === "function") {
|
|
|
log[level]("mark.js: " + msg);
|
|
|
}
|
|
|
}
|
|
|
}, {
|
|
|
key: "escapeStr",
|
|
|
value: function escapeStr(str) {
|
|
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
|
|
}
|
|
|
}, {
|
|
|
key: "createRegExp",
|
|
|
value: function createRegExp(str) {
|
|
|
str = this.escapeStr(str);
|
|
|
if (Object.keys(this.opt.synonyms).length) {
|
|
|
str = this.createSynonymsRegExp(str);
|
|
|
}
|
|
|
if (this.opt.diacritics) {
|
|
|
str = this.createDiacriticsRegExp(str);
|
|
|
}
|
|
|
str = this.createAccuracyRegExp(str);
|
|
|
return str;
|
|
|
}
|
|
|
}, {
|
|
|
key: "createSynonymsRegExp",
|
|
|
value: function createSynonymsRegExp(str) {
|
|
|
var syn = this.opt.synonyms;
|
|
|
for (var index in syn) {
|
|
|
if (syn.hasOwnProperty(index)) {
|
|
|
var value = syn[index],
|
|
|
k1 = this.escapeStr(index),
|
|
|
k2 = this.escapeStr(value);
|
|
|
str = str.replace(new RegExp("(" + k1 + "|" + k2 + ")", "gmi"), "(" + k1 + "|" + k2 + ")");
|
|
|
}
|
|
|
}
|
|
|
return str;
|
|
|
}
|
|
|
}, {
|
|
|
key: "createDiacriticsRegExp",
|
|
|
value: function createDiacriticsRegExp(str) {
|
|
|
var dct = ["aÀÁÂÃÄÅàáâãäåĀāąĄ", "cÇçćĆčČ", "dđĐďĎ", "eÈÉÊËèéêëěĚĒēęĘ", "iÌÍÎÏìíîïĪī", "lłŁ", "nÑñňŇńŃ", "oÒÓÔÕÕÖØòóôõöøŌō", "rřŘ", "sŠšśŚ", "tťŤ", "uÙÚÛÜùúûüůŮŪū", "yŸÿýÝ", "zŽžżŻźŹ"];
|
|
|
var handled = [];
|
|
|
str.split("").forEach(function (ch) {
|
|
|
dct.every(function (dct) {
|
|
|
if (dct.indexOf(ch) !== -1) {
|
|
|
if (handled.indexOf(dct) > -1) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
str = str.replace(new RegExp("[" + dct + "]", "gmi"), "[" + dct + "]");
|
|
|
handled.push(dct);
|
|
|
}
|
|
|
return true;
|
|
|
});
|
|
|
});
|
|
|
return str;
|
|
|
}
|
|
|
}, {
|
|
|
key: "createAccuracyRegExp",
|
|
|
value: function createAccuracyRegExp(str) {
|
|
|
switch (this.opt.accuracy) {
|
|
|
case "partially":
|
|
|
return "()(" + str + ")";
|
|
|
case "complementary":
|
|
|
return "()(\\S*" + str + "\\S*)";
|
|
|
case "exactly":
|
|
|
return "(^|\\s)(" + str + ")(?=\\s|$)";
|
|
|
}
|
|
|
}
|
|
|
}, {
|
|
|
key: "getSeparatedKeywords",
|
|
|
value: function getSeparatedKeywords(sv) {
|
|
|
var _this = this;
|
|
|
|
|
|
var stack = [];
|
|
|
sv.forEach(function (kw) {
|
|
|
if (!_this.opt.separateWordSearch) {
|
|
|
if (kw.trim()) {
|
|
|
stack.push(kw);
|
|
|
}
|
|
|
} else {
|
|
|
kw.split(" ").forEach(function (kwSplitted) {
|
|
|
if (kwSplitted.trim()) {
|
|
|
stack.push(kwSplitted);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
return {
|
|
|
"keywords": stack,
|
|
|
"length": stack.length
|
|
|
};
|
|
|
}
|
|
|
}, {
|
|
|
key: "getElements",
|
|
|
value: function getElements() {
|
|
|
var ctx = void 0,
|
|
|
stack = [];
|
|
|
if (typeof this.ctx === "undefined") {
|
|
|
ctx = [];
|
|
|
} else if (this.ctx instanceof HTMLElement) {
|
|
|
ctx = [this.ctx];
|
|
|
} else if (Array.isArray(this.ctx)) {
|
|
|
ctx = this.ctx;
|
|
|
} else {
|
|
|
ctx = Array.prototype.slice.call(this.ctx);
|
|
|
}
|
|
|
ctx.forEach(function (ctx) {
|
|
|
stack.push(ctx);
|
|
|
var childs = ctx.querySelectorAll("*");
|
|
|
if (childs.length) {
|
|
|
stack = stack.concat(Array.prototype.slice.call(childs));
|
|
|
}
|
|
|
});
|
|
|
if (!ctx.length) {
|
|
|
this.log("Empty context", "warn");
|
|
|
}
|
|
|
return {
|
|
|
"elements": stack,
|
|
|
"length": stack.length
|
|
|
};
|
|
|
}
|
|
|
}, {
|
|
|
key: "matches",
|
|
|
value: function matches(el, selector) {
|
|
|
return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
|
|
|
}
|
|
|
}, {
|
|
|
key: "matchesFilter",
|
|
|
value: function matchesFilter(el, exclM) {
|
|
|
var _this2 = this;
|
|
|
|
|
|
var remain = true;
|
|
|
var fltr = this.opt.filter.concat(["script", "style", "title"]);
|
|
|
if (!this.opt.iframes) {
|
|
|
fltr = fltr.concat(["iframe"]);
|
|
|
}
|
|
|
if (exclM) {
|
|
|
fltr = fltr.concat(["*[data-markjs='true']"]);
|
|
|
}
|
|
|
fltr.every(function (filter) {
|
|
|
if (_this2.matches(el, filter)) {
|
|
|
return remain = false;
|
|
|
}
|
|
|
return true;
|
|
|
});
|
|
|
return !remain;
|
|
|
}
|
|
|
}, {
|
|
|
key: "onIframeReady",
|
|
|
value: function onIframeReady(ifr, successFn, errorFn) {
|
|
|
try {
|
|
|
(function () {
|
|
|
var ifrWin = ifr.contentWindow,
|
|
|
bl = "about:blank",
|
|
|
compl = "complete";
|
|
|
var callCallback = function callCallback() {
|
|
|
try {
|
|
|
if (ifrWin.document === null) {
|
|
|
throw new Error("iframe inaccessible");
|
|
|
}
|
|
|
successFn(ifrWin.document);
|
|
|
} catch (e) {
|
|
|
errorFn();
|
|
|
}
|
|
|
};
|
|
|
var isBlank = function isBlank() {
|
|
|
var src = ifr.getAttribute("src").trim(),
|
|
|
href = ifrWin.location.href;
|
|
|
return href === bl && src !== bl && src;
|
|
|
};
|
|
|
var observeOnload = function observeOnload() {
|
|
|
var listener = function listener() {
|
|
|
try {
|
|
|
if (!isBlank()) {
|
|
|
ifr.removeEventListener("load", listener);
|
|
|
callCallback();
|
|
|
}
|
|
|
} catch (e) {
|
|
|
errorFn();
|
|
|
}
|
|
|
};
|
|
|
ifr.addEventListener("load", listener);
|
|
|
};
|
|
|
if (ifrWin.document.readyState === compl) {
|
|
|
if (isBlank()) {
|
|
|
observeOnload();
|
|
|
} else {
|
|
|
callCallback();
|
|
|
}
|
|
|
} else {
|
|
|
observeOnload();
|
|
|
}
|
|
|
})();
|
|
|
} catch (e) {
|
|
|
errorFn();
|
|
|
}
|
|
|
}
|
|
|
}, {
|
|
|
key: "forEachElementInIframe",
|
|
|
value: function forEachElementInIframe(ifr, cb) {
|
|
|
var _this3 = this;
|
|
|
|
|
|
var end = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2];
|
|
|
|
|
|
var open = 0;
|
|
|
var checkEnd = function checkEnd() {
|
|
|
if (--open < 1) {
|
|
|
end();
|
|
|
}
|
|
|
};
|
|
|
this.onIframeReady(ifr, function (con) {
|
|
|
var stack = Array.prototype.slice.call(con.querySelectorAll("*"));
|
|
|
if ((open = stack.length) === 0) {
|
|
|
checkEnd();
|
|
|
}
|
|
|
stack.forEach(function (el) {
|
|
|
if (el.tagName.toLowerCase() === "iframe") {
|
|
|
(function () {
|
|
|
var j = 0;
|
|
|
_this3.forEachElementInIframe(el, function (iel, len) {
|
|
|
cb(iel, len);
|
|
|
if (len - 1 === j) {
|
|
|
checkEnd();
|
|
|
}
|
|
|
j++;
|
|
|
}, checkEnd);
|
|
|
})();
|
|
|
} else {
|
|
|
cb(el, stack.length);
|
|
|
checkEnd();
|
|
|
}
|
|
|
});
|
|
|
}, function () {
|
|
|
var src = ifr.getAttribute("src");
|
|
|
_this3.log("iframe '" + src + "' could not be accessed", "warn");
|
|
|
checkEnd();
|
|
|
});
|
|
|
}
|
|
|
}, {
|
|
|
key: "forEachElement",
|
|
|
value: function forEachElement(cb) {
|
|
|
var _this4 = this;
|
|
|
|
|
|
var end = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];
|
|
|
var exclM = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
|
|
|
|
|
|
var _getElements = this.getElements();
|
|
|
|
|
|
var stack = _getElements.elements;
|
|
|
var open = _getElements.length;
|
|
|
|
|
|
var checkEnd = function checkEnd() {
|
|
|
if (--open === 0) {
|
|
|
end();
|
|
|
}
|
|
|
};
|
|
|
checkEnd(++open);
|
|
|
stack.forEach(function (el) {
|
|
|
if (!_this4.matchesFilter(el, exclM)) {
|
|
|
if (el.tagName.toLowerCase() === "iframe") {
|
|
|
_this4.forEachElementInIframe(el, function (iel) {
|
|
|
if (!_this4.matchesFilter(iel, exclM)) {
|
|
|
cb(iel);
|
|
|
}
|
|
|
}, checkEnd);
|
|
|
return;
|
|
|
} else {
|
|
|
cb(el);
|
|
|
}
|
|
|
}
|
|
|
checkEnd();
|
|
|
});
|
|
|
}
|
|
|
}, {
|
|
|
key: "forEachNode",
|
|
|
value: function forEachNode(cb) {
|
|
|
var end = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];
|
|
|
|
|
|
this.forEachElement(function (n) {
|
|
|
for (n = n.firstChild; n; n = n.nextSibling) {
|
|
|
if (n.nodeType === 3 && n.textContent.trim()) {
|
|
|
cb(n);
|
|
|
}
|
|
|
}
|
|
|
}, end);
|
|
|
}
|
|
|
}, {
|
|
|
key: "wrapMatches",
|
|
|
value: function wrapMatches(node, regex, custom, cb) {
|
|
|
var hEl = !this.opt.element ? "mark" : this.opt.element,
|
|
|
index = custom ? 0 : 2;
|
|
|
var match = void 0;
|
|
|
while ((match = regex.exec(node.textContent)) !== null) {
|
|
|
var pos = match.index;
|
|
|
if (!custom) {
|
|
|
pos += match[index - 1].length;
|
|
|
}
|
|
|
var startNode = node.splitText(pos);
|
|
|
|
|
|
node = startNode.splitText(match[index].length);
|
|
|
if (startNode.parentNode !== null) {
|
|
|
var repl = document.createElement(hEl);
|
|
|
repl.setAttribute("data-markjs", "true");
|
|
|
if (this.opt.className) {
|
|
|
repl.setAttribute("class", this.opt.className);
|
|
|
}
|
|
|
repl.textContent = match[index];
|
|
|
startNode.parentNode.replaceChild(repl, startNode);
|
|
|
cb(repl);
|
|
|
}
|
|
|
regex.lastIndex = 0;
|
|
|
}
|
|
|
}
|
|
|
}, {
|
|
|
key: "unwrapMatches",
|
|
|
value: function unwrapMatches(node) {
|
|
|
var parent = node.parentNode;
|
|
|
var docFrag = document.createDocumentFragment();
|
|
|
while (node.firstChild) {
|
|
|
docFrag.appendChild(node.removeChild(node.firstChild));
|
|
|
}
|
|
|
parent.replaceChild(docFrag, node);
|
|
|
parent.normalize();
|
|
|
}
|
|
|
}, {
|
|
|
key: "markRegExp",
|
|
|
value: function markRegExp(regexp, opt) {
|
|
|
var _this5 = this;
|
|
|
|
|
|
this.opt = opt;
|
|
|
this.log("Searching with expression \"" + regexp + "\"");
|
|
|
var found = false;
|
|
|
var eachCb = function eachCb(element) {
|
|
|
found = true;
|
|
|
_this5.opt.each(element);
|
|
|
};
|
|
|
this.forEachNode(function (node) {
|
|
|
_this5.wrapMatches(node, regexp, true, eachCb);
|
|
|
}, function () {
|
|
|
if (!found) {
|
|
|
_this5.opt.noMatch(regexp);
|
|
|
}
|
|
|
_this5.opt.complete();
|
|
|
_this5.opt.done();
|
|
|
});
|
|
|
}
|
|
|
}, {
|
|
|
key: "mark",
|
|
|
value: function mark(sv, opt) {
|
|
|
var _this6 = this;
|
|
|
|
|
|
this.opt = opt;
|
|
|
sv = typeof sv === "string" ? [sv] : sv;
|
|
|
|
|
|
var _getSeparatedKeywords = this.getSeparatedKeywords(sv);
|
|
|
|
|
|
var kwArr = _getSeparatedKeywords.keywords;
|
|
|
var kwArrLen = _getSeparatedKeywords.length;
|
|
|
|
|
|
if (kwArrLen === 0) {
|
|
|
this.opt.complete();
|
|
|
this.opt.done();
|
|
|
}
|
|
|
kwArr.forEach(function (kw) {
|
|
|
var regex = new RegExp(_this6.createRegExp(kw), "gmi"),
|
|
|
found = false;
|
|
|
var eachCb = function eachCb(element) {
|
|
|
found = true;
|
|
|
_this6.opt.each(element);
|
|
|
};
|
|
|
_this6.log("Searching with expression \"" + regex + "\"");
|
|
|
_this6.forEachNode(function (node) {
|
|
|
_this6.wrapMatches(node, regex, false, eachCb);
|
|
|
}, function () {
|
|
|
if (!found) {
|
|
|
_this6.opt.noMatch(kw);
|
|
|
}
|
|
|
if (kwArr[kwArrLen - 1] === kw) {
|
|
|
_this6.opt.complete();
|
|
|
_this6.opt.done();
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
}, {
|
|
|
key: "unmark",
|
|
|
value: function unmark(opt) {
|
|
|
var _this7 = this;
|
|
|
|
|
|
this.opt = opt;
|
|
|
var sel = this.opt.element ? this.opt.element : "*";
|
|
|
sel += "[data-markjs]";
|
|
|
if (this.opt.className) {
|
|
|
sel += "." + this.opt.className;
|
|
|
}
|
|
|
this.log("Removal selector \"" + sel + "\"");
|
|
|
this.forEachElement(function (el) {
|
|
|
if (_this7.matches(el, sel)) {
|
|
|
_this7.unwrapMatches(el);
|
|
|
}
|
|
|
}, function () {
|
|
|
_this7.opt.complete();
|
|
|
_this7.opt.done();
|
|
|
}, false);
|
|
|
}
|
|
|
}, {
|
|
|
key: "opt",
|
|
|
set: function set(val) {
|
|
|
this._opt = _extends({}, {
|
|
|
"element": "",
|
|
|
"className": "",
|
|
|
"filter": [],
|
|
|
"iframes": false,
|
|
|
"separateWordSearch": true,
|
|
|
"diacritics": true,
|
|
|
"synonyms": {},
|
|
|
"accuracy": "partially",
|
|
|
"each": function each() {},
|
|
|
"noMatch": function noMatch() {},
|
|
|
"done": function done() {},
|
|
|
"complete": function complete() {},
|
|
|
"debug": false,
|
|
|
"log": window.console
|
|
|
}, val);
|
|
|
},
|
|
|
get: function get() {
|
|
|
return this._opt;
|
|
|
}
|
|
|
}]);
|
|
|
|
|
|
return Mark;
|
|
|
}();
|
|
|
|
|
|
$.fn.mark = function (sv, opt) {
|
|
|
new Mark(this).mark(sv, opt);
|
|
|
return this;
|
|
|
};
|
|
|
$.fn.markRegExp = function (regexp, opt) {
|
|
|
new Mark(this).markRegExp(regexp, opt);
|
|
|
return this;
|
|
|
};
|
|
|
$.fn.unmark = function (opt) {
|
|
|
new Mark(this).unmark(opt);
|
|
|
return this;
|
|
|
};
|
|
|
}, window, document);
|
|
|
|