/*!***************************************************
 * 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);