@ohos-ports/advanced-mark.js 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ /*!***************************************************
2
+ * advanced-mark.js v3.0.0
3
+ * https://github.com/angezid/advanced-mark.js
4
+ * MIT licensed
5
+ * Copyright (c) 2022–2026, angezid
6
+ * Based on 'mark.js', license https://git.io/vwTVl
7
+ *****************************************************/
8
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Mark=e()}(this,(function(){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(o=r.key,i=void 0,"symbol"==typeof(i=function(t,e){if("object"!=typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(o,"string"))?i:String(i)),r)}var o,i}function r(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function o(){return o=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},o.apply(this,arguments)}var i=function(){function t(n,r){e(this,t),this.ctx=n,this.opt=r,this.map=new Map}return r(t,[{key:"getContexts",value:function(){var t=this.ctx,e=this.opt.window,n=!1;if(!t)return[];Array.isArray(t)?n=!0:"string"==typeof t?t=e.document.querySelectorAll(t):void 0===t.length&&(t=[t]);for(var r=[],o=function(e){r.includes(t[e])||r.some((function(n){return n.contains(t[e])}))||r.push(t[e])},i=0;i<t.length;i++)o(i);return n&&r.sort((function(t,n){return(t.compareDocumentPosition(n)&e.Node.DOCUMENT_POSITION_FOLLOWING)>0?-1:1})),r}},{key:"getIframeContents",value:function(t,e,n){try{var r=t.contentWindow.document;r&&(this.map.set(t,"ready"),e({iframe:t,context:r}))}catch(e){n({iframe:t,error:e})}}},{key:"observeIframeLoad",value:function(t,e,n){var r=this;if(!this.map.has(t)){var o=null,i=function i(){clearTimeout(o),t.removeEventListener("load",i),r.getIframeContents(t,e,n)};t.addEventListener("load",i),this.map.set(t,!0),o=setTimeout(i,this.opt.iframesTimeout)}}},{key:"onIframeReady",value:function(t,e,n){var r="about:blank",o=t.getAttribute("src"),i=t.contentWindow;try{"complete"!==i.document.readyState||o&&o.trim()!==r&&i.location.href===r?this.observeIframeLoad(t,e,n):this.getIframeContents(t,e,n)}catch(t){n(t)}}},{key:"waitForIframes",value:function(t,e){var n,r,o=this,i=this.opt.shadowDOM,a=0,s=0,c=function t(e){for(var a=o.createIterator(e,o.opt.window.NodeFilter.SHOW_ELEMENT);r=a.nextNode();)o.isIframe(r)&&!o.map.has(r)&&(n.push(r),s++),i&&r.shadowRoot&&"open"===r.shadowRoot.mode&&t(r.shadowRoot)};!function t(r){n=[],r.iframe&&"about:blank"===r.context.location.href||(c(r.context),r.iframe||n.length)?n.length?n.forEach((function(n){o.onIframeReady(n,(function(e){a++,t(e)}),(function(t){o.opt.debug&&console.log(t.error||t),++a===s&&e()}))})):a===s&&e():e()}({context:t})}},{key:"createIterator",value:function(t,e){var n=this.opt.window;return n.document.createNodeIterator(t,e,(function(){return n.NodeFilter.FILTER_ACCEPT}),!1)}},{key:"addRemoveStyle",value:function(t,e,n){if(!n||e){var r=t.querySelector("style[data-markjs]");n?(r||((r=this.opt.window.document.createElement("style")).setAttribute("data-markjs","true"),t.appendChild(r)),r.textContent=e):r&&t.removeChild(r)}}},{key:"isIframe",value:function(e){return"IFRAME"===e.tagName&&!t.matches(e,this.opt.exclude)}},{key:"iterateThroughNodes",value:function(t,e,n,r,o){var i=this,a=this.opt.window.NodeFilter,s=this.opt.shadowDOM,c=this.opt.iframes;if(c||s){var u=(e&a.SHOW_ELEMENT)>0,h=(e&a.SHOW_TEXT)>0;!function t(o){for(var l,f=i.createIterator(o,e|a.SHOW_ELEMENT);o=f.nextNode();)if(1===o.nodeType){if(u&&n(o)&&r(o),c&&i.isIframe(o)&&"ready"===i.map.get(o)){var d=o.contentWindow.document;d&&(i.opt.highlight&&h&&o.contentWindow.CSS.highlights.set(i.opt.highlightName,i.opt.highlight),i.addRemoveStyle(d.head,c.style,h),t(d))}s&&(l=o.shadowRoot)&&"open"===l.mode&&(i.addRemoveStyle(l,s.style,h),t(l))}else h&&3===o.nodeType&&n(o)&&r(o)}(t)}else for(var l,f=this.createIterator(t,e);l=f.nextNode();)n(l)&&r(l);o()}},{key:"forEachNode",value:function(t,e,n){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=this.getContexts(),a=i.length;a||o();var s=function(){i.forEach((function(i){r.iterateThroughNodes(i,t,n,e,(function(){--a<=0&&o()}))}))};if(this.opt.iframes){var c=a;i.forEach((function(t){r.waitForIframes(t,(function(){--c<=0&&s()}))}))}else s()}}],[{key:"matches",value:function(t,e){if(!e||!e.length)return!1;var n="string"==typeof e?[e]:e,r=t.matches;return r&&n.some((function(e){return r.call(t,e)}))}}]),t}(),a=function(){function t(n){e(this,t),this.opt=o({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},n)}return r(t,[{key:"chars",get:function(){var t=this;return this._chars||(this._chars=[],["aàáảãạăằắẳẵặâầấẩẫậäåāą","cçćč","dđď","eèéẻẽẹêềếểễệëěēę","iìíỉĩịîïī","lł","nñňń","oòóỏõọôồốổỗộơởỡớờợöøōő","rř","sšśșş","tťțţ","uùúủũụưừứửữựûüůūű","yýỳỷỹỵÿ","zžżź"].forEach((function(e){t._chars.push(e,e.toUpperCase())}))),this._chars}},{key:"create",value:function(t){var e=this,n="g".concat(this.opt.caseSensitive?"":"i");t=t.map((function(t){return"("+e.createPattern(t,n)+")"}));var r=this.createAccuracy(t.join("|"));return new RegExp("".concat(r.lookbehind,"(").concat(r.pattern,")").concat(r.lookahead),n)}},{key:"createPattern",value:function(t,e){t=this.checkWildcardsEscape(t),t=this.createSynonyms(t,e);var n=this.getJoinersPunctuation();return n&&(t=this.setupIgnoreJoiners(t)),this.opt.diacritics&&(t=this.createDiacritics(t)),t=t.replace(/\s+/g,"[\\s]+"),n&&(t=this.createJoiners(t,n)),"disabled"!==this.opt.wildcards&&(t=this.createWildcards(t)),t}},{key:"escape",value:function(t){return t.replace(/[[\]/{}()*+?.\\^$|]/g,"\\$&")}},{key:"preprocess",value:function(t){return t&&t.length?this.distinct("string"==typeof t?t.split(""):t).join("").replace(/[-^\]\\]/g,"\\$&"):""}},{key:"distinct",value:function(t){var e=[];return t.forEach((function(t){t.trim()&&!e.includes(t)&&e.push(t)})),e}},{key:"createSynonyms",value:function(t,e){var n=this,r=this.opt.synonyms;for(var o in r)if(r.hasOwnProperty(o)){var i=Array.isArray(r[o])?r[o]:[r[o]];if(i.unshift(o),(i=this.distinct(i)).length>1){i.sort((function(t,e){return e.length-t.length}));var a=(i=i.map((function(t){return n.checkWildcardsEscape(t)}))).map((function(t){return n.escape(t)})).join("|");t=t.replace(new RegExp(a,e),"(?:".concat(i.join("|"),")"))}}return t}},{key:"checkWildcardsEscape",value:function(t){return"disabled"!==this.opt.wildcards&&(t=t.replace(/(\\.)+|[?*]/g,(function(t,e){return e?t:"?"===t?"":""})).replace(/\\(?=[?*\x01\x02])/g,"")),this.escape(t)}},{key:"createWildcards",value:function(t){var e="withSpaces"===this.opt.wildcards,n=this.opt.blockElementsBoundary,r="[^".concat(e&&n?"":"","]*?");return t.replace(/\x01/g,e?"[^]?":"\\S?").replace(/\x02/g,e?r:"\\S*")}},{key:"setupIgnoreJoiners",value:function(t){return t.replace(/((?:\\\\)+|\x02|\(\?:|\|)|\\?(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|.)(?=([|)\x02]|$)|.)/g,(function(t,e,n){return e||void 0!==n?t:t+"\0"}))}},{key:"createJoiners",value:function(t,e){return t.split(/\x00+/).join("[".concat(e,"]*"))}},{key:"getJoinersPunctuation",value:function(){var t=this.preprocess(this.opt.ignorePunctuation),e=t||"";return this.opt.ignoreJoiners&&(e+="\\u00ad\\u200b\\u200c\\u200d"),e}},{key:"createDiacritics",value:function(t){var e=this,n=this.chars;return t.split("").map((function(t){for(var r=0;r<n.length;r+=2){var o=n[r].includes(t);if(e.opt.caseSensitive){if(o)return"["+n[r]+"]";if(n[r+1].includes(t))return"["+n[r+1]+"]"}else if(o||n[r+1].includes(t))return"["+n[r]+n[r+1]+"]"}return t})).join("")}},{key:"createAccuracy",value:function(t){var e,n=this.opt.accuracy,r="()",o=t,i="";if("partially"!==n)if("string"!=typeof n&&(e=this.preprocess(n.limiters),n=n.value),"exactly"===n){var a=e?"[\\s"+e+"]":"\\s";r="(^|".concat(a,")"),i="(?=$|".concat(a,")")}else{var s=e||"!-/:-@[-`{-~¡¿",c="[^\\s".concat(s,"]*");o="(?:".concat(t,")"),"complementary"===n?o=c+o+c:"startsWith"===n&&(r="(^|[\\s".concat(s,"])"),o=o.split(/\[\\s\]\+/).join(c+"[\\s]+")+c)}return{lookbehind:r,pattern:o,lookahead:i}}}]),t}(),s=function(){function n(t){e(this,n),this.ctx=t,this.nodeNames=["script","style","title","head","html"]}return r(n,[{key:"opt",get:function(){return this._opt},set:function(t){if(!(t&&t.window&&t.window.document)&&"undefined"==typeof window)throw new Error("Mark.js: please provide a window object as an option.");var e=t&&t.window||window,n=t&&t.highlight&&t.highlight instanceof Highlight;this._opt=o({},{window:e,element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,staticRanges:!0,rangeAcrossElements:!0,acrossElements:!1,ignoreGroups:0,each:function(){},noMatch:function(){},filter:function(){return!0},done:function(){},debug:!1,log:e.console},t),this._opt.element||(this._opt.element="mark"),this.filter=e.NodeFilter,this.empty=e.document.createTextNode(""),this._opt.highlightName||(this._opt.highlightName="advanced-markjs"),n?this.rangeArray=[]:this._opt.highlight=null}},{key:"iterator",get:function(){return new i(this.ctx,this.opt)}},{key:"log",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug";if(this.opt.debug){var r=this.opt.log;"object"===t(r)&&"function"==typeof r[n]&&r[n]("mark.js: ".concat(e))}}},{key:"report",value:function(t){var e=this;t.forEach((function(t){e.log("".concat(t.text," ").concat(JSON.stringify(t.obj)),t.level||"debug"),t.skip||e.opt.noMatch(t.obj)}))}},{key:"getSeachTerms",value:function(t){var e="string"==typeof t?[t]:t,n=this.opt.separateWordSearch,r=[],o={},i=function(t){t.split(/ +/).forEach((function(t){return a(t)}))},a=function(t){t.trim()&&!r.includes(t)&&(r.push(t),o[t]=0)};return e.forEach((function(t){n?"preserveTerms"===n?t.split(/"("*[^"]+"*)"/).forEach((function(t,e){e%2>0?a(t):i(t)})):i(t):a(t)})),r.sort((function(t,e){return e.length-t.length})),{terms:r,termStats:o}}},{key:"isNumeric",value:function(t){return Number(parseFloat(t))==t}},{key:"checkRanges",value:function(t,e,n,r){var o=this,i="error",a=t.filter((function(t){return!!(o.isNumeric(t.start)&&o.isNumeric(t.length)&&(t.start=parseInt(t.start),t.length=parseInt(t.length),t.start>=n&&t.start<r&&t.length>0))||(e.push({text:"Invalid range: ",obj:t,level:i}),!1)})).sort((function(t,e){return t.start-e.start}));if(this.opt.wrapAllRanges)return a;var s,c=0;return a.filter((function(t){return s=t.start+t.length,t.start>=c?(c=s,!0):(e.push({text:(s<c?"Nest":"Overlapp")+"ing range: ",obj:t,level:i}),!1)}))}},{key:"setType",value:function(t,e){var n=Array.isArray(e.tagNames)&&e.tagNames.length;if(n&&e.tagNames.forEach((function(e){return t[e.toLowerCase()]=2})),!n||e.extend)for(var r in t)t[r]=2;t.br=3}},{key:"getTextNodesAcross",value:function(t){var e,n,r,o=this,i={div:1,p:1,li:1,td:1,tr:1,th:1,ul:1,ol:1,dd:1,dl:1,dt:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,blockquote:1,figcaption:1,figure:1,pre:1,table:1,thead:1,tbody:1,tfoot:1,input:1,img:1,nav:1,details:1,label:1,form:1,select:1,menu:1,br:3,menuitem:1,main:1,section:1,article:1,aside:1,picture:1,output:1,button:1,header:1,footer:1,address:1,area:1,canvas:1,map:1,fieldset:1,textarea:1,track:1,video:1,audio:1,body:1,iframe:1,meter:1,object:1,svg:1},a=[],s=this.opt.blockElementsBoundary,c=s?2:1,u="";s&&(this.setType(i,s),s.char&&(u=s.char.charAt(0)));var h={text:"",regex:/\s/,tags:i,boundary:s,str:"",ch:u};this.iterator.forEachNode(this.filter.SHOW_ELEMENT|this.filter.SHOW_TEXT,(function(t){r&&a.push(o.getNodeInfo(r,t,n,h)),n=null,r=t}),(function(t){return 1===t.nodeType?(3===(e=i[t.nodeName.toLowerCase()])&&(h.str+="\n"),n&&e!==c||(n=e),!1):!o.excluded(t.parentNode)}),(function(){r&&a.push(o.getNodeInfo(r,null,n,h)),t({text:h.text,nodes:a,lastIndex:0})}))}},{key:"getNodeInfo",value:function(t,e,n,r){var o=r.text.length,i=r.ch,a=0,s=r.str,c=t.textContent;if(e){var u=r.regex.test(e.textContent[0]),h=u&&r.regex.test(c[c.length-1]);if(r.boundary||!h){var l=n;if(!n)for(var f=t.parentNode;f;){if(n=r.tags[f.nodeName.toLowerCase()]){l=!(f===e.parentNode||f.contains(e));break}f=f.parentNode}l&&(h?2===n&&(s+=h?i:u?" "+i:i+" "):s+=1===n?" ":2===n?" "+i+" ":"")}}return s&&(c+=s,a=s.length,r.str=""),r.text+=c,this.createInfo(t,o,r.text.length-a,a)}},{key:"getRangesTextNodes",value:function(t,e){var n,r=this,o=[],i=/\n/g,a=[0],s=this.filter.SHOW_TEXT|(e?this.filter.SHOW_ELEMENT:0),c="",u=0;this.iterator.forEachNode(s,(function(t){if(e)for(;null!==(n=i.exec(t.textContent));)a.push(u+n.index);c+=t.textContent,o.push({start:u,end:u=c.length,offset:0,node:t})}),(function(t){return e&&1===t.nodeType?("br"===t.tagName.toLowerCase()&&a.push(u),!1):!r.excluded(t.parentNode)}),(function(){var n={text:c,nodes:o,lastIndex:0};e&&(a.push(u),n.newLines=a),t(n)}))}},{key:"getTextNodes",value:function(t){var e=this,n=[],r=0;this.iterator.forEachNode(this.filter.SHOW_TEXT,(function(t){n.push({node:t,start:r}),r+=t.textContent.length}),(function(t){return!e.excluded(t.parentNode)}),(function(){t({nodes:n,lastIndex:0})}))}},{key:"excluded",value:function(t){return this.nodeNames.includes(t.nodeName.toLowerCase())||i.matches(t,this.opt.exclude)}},{key:"wrapRangeInsert",value:function(t,e,n,r,o,i){var a=r===e.node.textContent.length,s=e.end,c=1,u=r,h=e.node;0!==n?(h=h.splitText(n),u=r-n,c=a?2:3):a&&(c=0);var l=a?this.empty:h.splitText(u),f=this.createElement(h),d=f.childNodes[0],p=this.createInfo(l,0===c||2===c?s:e.start+r,s,e.offset);if(0===c)return e.node=d,{mark:f,nodeInfo:p,increment:0};var g=this.createInfo(d,1===c?e.start:o,e.start+r,0);return 1===c?t.nodes.splice(i,1,g,p):(2===c?t.nodes.splice(i+1,0,g):t.nodes.splice(i+1,0,g,p),e.end=o,e.offset=0),{mark:f,nodeInfo:p,increment:c<3?1:2}}},{key:"createInfo",value:function(t,e,n,r){return{node:t,start:e,end:n,offset:r}}},{key:"wrapRange",value:function(t,e,n,r){var o,i=t.node;if(this.rangeArray)this.createRange(i,e,i,n,t.start+e,r),o=i;else{var a=n===i.textContent.length,s=n;0!==e&&(i=i.splitText(e),s=n-e),o=a?this.empty:i.splitText(s),r(this.createElement(i))}return o}},{key:"createRange",value:function(t,e,n,r,o,i){var a;this.opt.staticRanges?a=new StaticRange({startContainer:t,startOffset:e,endContainer:n,endOffset:r}):((a=new Range).setStart(t,e),a.setEnd(n,r)),a.absoluteOffset=o,i(a,!0),a&&this.rangeArray.push(a)}},{key:"createElement",value:function(t){var e=this.opt.window.document.createElement(this.opt.element);return e.setAttribute("data-markjs","true"),this.opt.className&&e.setAttribute("class",this.opt.className),e.textContent=t.textContent,t.parentNode.replaceChild(e,t),e}},{key:"wrapRangeAcross",value:function(t,e,n,r,o){var i,a,s=t.lastIndex,c=!0,u=[],h=this.opt.wrapAllRanges,l=!!this.opt.highlight,f=l&&this.opt.rangeAcrossElements;if(h)for(;s>0&&t.nodes[s].start>e;)s--;for(;s<t.nodes.length;s++)if(s+1===t.nodes.length||t.nodes[s+1].start>e){var d=t.nodes[s];if(f)u.push(d.node);else if(!r(d.node))break;var p=e-d.start;if(a=(n>d.end?d.end:n)-d.start,p>=0&&a>p){if(f)c&&(i=[d.node,p,d.start+p]);else if(!l&&h){var g=this.wrapRangeInsert(t,d,p,a,e,s);d=g.nodeInfo,o(g.mark,c)}else d.node=this.wrapRange(d,p,a,(function(t){o(t,c)})),l||(d.start+=a);c=!1}if(!(n>d.end)){i&&r(u)&&this.createRange(i[0],i[1],d.node,a,i[2],o);break}e=d.end+d.offset}t.lastIndex=s}},{key:"wrapGroups",value:function(t,e,n,r,o){for(var i,a,s=0,c=0,u=0,h=this.opt.highlight,l=!1,f=0;++u<e.length;)(i=e[u])&&(a=e.indices[u][0])>=s&&(f=e.indices[u][1],r(t.node,i,u)&&(t.node=this.wrapRange(t,a-c,f-c,(function(t){o(t)})),f>s&&(s=f),h||(c=f),l=!0));l?h||(n.lastIndex=0):0===e[0].length&&this.setLastIndex(n,f)}},{key:"wrapGroupsAcross",value:function(t,e,n,r,o){for(var i,a,s,c=0,u=0,h=0;++u<e.length;)(a=e[u])&&(i=e.indices[u][0],(this.opt.wrapAllRanges||i>=c)&&(h=e.indices[u][1],s=!1,this.wrapRangeAcross(t,i,h,(function(t){return r(t,a,u)}),(function(t,e){s=!0,o(t,e)})),s&&h>c&&(c=h)));0===e[0].length&&this.setLastIndex(n,h)}},{key:"setLastIndex",value:function(t,e){var n=t.lastIndex;t.lastIndex=e>n?e:e>0?n+1:1/0}},{key:"processGroups",value:function(t,e,n,r,o,i){var a,s,c,u=this,h=n.count;this.getTextNodes((function(e){e.nodes.every((function(e){for(;null!==(a=t.exec(e.node.textContent))&&(n.match=a,s=c=!0,u.wrapGroups(e,a,t,(function(t,e,o){return n.matchStart=s,n.groupIndex=o,s=!1,r(t,e,n)}),(function(t){c&&h++,n.count=h,n.matchStart=c,c=!1,o(t,n)})),!n.abort););return!n.abort})),i(h)}))}},{key:"processGroupsAcross",value:function(t,e,n,r,o,i){var a,s,c,u=this,h=n.count;this.getTextNodesAcross((function(e){for(;null!==(a=t.exec(e.text))&&(n.match=a,s=c=!0,u.wrapGroupsAcross(e,a,t,(function(t,e,o){return n.groupStart=void 0,n.matchStart=s,n.groupIndex=o,s=!1,r(t,e,n)}),(function(t,e){c&&h++,n.count=h,n.matchStart=c,n.groupStart=e,o(t,n),c=!1})),!n.abort););i(h)}))}},{key:"processMatches",value:function(t,e,n,r,o,i){var a,s,c=this,u=0===e?0:e+1,h=n.count;this.getTextNodes((function(e){e.nodes.every((function(e){for(;null!==(a=t.exec(e.node.textContent));)if(""!==(s=a[u])){if(n.match=a,r(e.node,s,n)){for(var i=0,l=a.index;++i<u;)a[i]&&(l+=a[i].length);if(e.node=c.wrapRange(e,l,l+s.length,(function(t){n.count=++h,o(t,n)})),c.opt.highlight||(t.lastIndex=0),n.abort)break}}else t.lastIndex++;return!n.abort})),i(h)}))}},{key:"processMatchesAcross",value:function(t,e,n,r,o,i){var a,s,c,u=this,h=0===e?0:e+1,l=n.count;this.getTextNodesAcross((function(e){for(;null!==(a=t.exec(e.text));)if(""!==(s=a[h])){n.match=a,c=!0;for(var f=0,d=a.index;++f<h;)a[f]&&(d+=a[f].length);if(u.wrapRangeAcross(e,d,d+s.length,(function(t){return n.matchStart=c,c=!1,r(t,s,n)}),(function(t,e){e&&l++,n.count=l,n.matchStart=e,o(t,n)})),n.abort)break}else t.lastIndex++;i(l)}))}},{key:"processRanges",value:function(t,e,n,r){var o=this,i=this.opt.markLines,a=[],s=[],c="warn",u=0;this.getRangesTextNodes((function(h){var l=i?h.newLines.length:h.text.length,f=o.checkRanges(t,a,i?1:0,l);f.forEach((function(t,r){var f=t.start,d=f+t.length;d>l&&(a.push({text:"Range was limited to: ".concat(l),obj:t,skip:!0,level:c}),d=l),i&&(f=h.newLines[f-1],"\n"===h.text[f]&&f++,d=h.newLines[d-1]);var p=h.text.slice(f,d);p.trim()?o.wrapRangeAcross(h,f,d,(function(n){return e(n,t,p,r)}),(function(e,r){r&&u++,n(e,t,{matchStart:r,count:u})})):(a.push({text:"Skipping whitespace only range: ",obj:t,level:c}),s.push(t))})),o.log("Valid ranges: ".concat(JSON.stringify(f.filter((function(t){return!s.includes(t)}))))),r(u,a)}),i)}},{key:"unwrapMatches",value:function(t){var e=t.parentNode,n=t.firstChild;if(1===t.childNodes.length)if(3===n.nodeType){var r=t.previousSibling,o=t.nextSibling;if(r&&3===r.nodeType)o&&3===o.nodeType?(r.nodeValue+=n.nodeValue+o.nodeValue,e.removeChild(o)):r.nodeValue+=n.nodeValue;else{if(!o||3!==o.nodeType)return void e.replaceChild(t.firstChild,t);o.nodeValue=n.nodeValue+o.nodeValue}e.removeChild(t)}else e.replaceChild(t.firstChild,t);else{if(n){for(var i=this.opt.window.document.createDocumentFragment();t.firstChild;)i.appendChild(t.removeChild(t.firstChild));e.replaceChild(i,t)}else e.removeChild(t);e.normalize()}}},{key:"markRegExp",value:function(t,e){var n=this;this.opt=e;var r=0,o=0,i=this.opt.acrossElements,a="processMatches";if(this.opt.separateGroups){if(!t.hasIndices)throw new Error("Mark.js: RegExp must have a `d` flag");a=i?"processGroupsAcross":"processGroups"}else i&&(a="processMatchesAcross");if(!t.global&&!t.sticky){var s=t.toString().split("/");t=new RegExp(t.source,"g"+s[s.length-1]),this.log("RegExp is recompiled - it must have a `g` flag","warn")}this.log('RegExp "'.concat(t,'"')),this[a](t,this.opt.ignoreGroups,{count:0,abort:!1},(function(t,e,r){return n.opt.filter(t,e,o,r)}),(function(t,e){o=e.count,r++,n.opt.each(t,e)}),(function(e){0===e&&n.opt.noMatch(t),n.registerHighlight(),n.opt.done(r,e)}))}},{key:"mark",value:function(t,e){var n=this;this.opt=e;var r=this.getSeachTerms(t),o=r.terms,i=r.termStats;if(o.length){var a,s=0,c=0,u=0,h=this.opt.acrossElements,l=h?"processMatchesAcross":"processMatches",f=this.getRegExps(o),d={count:0,abort:!1};!function t(e){var r=e.regex,o=e.regTerms;n.log("RegExp ".concat(r)),n[l](r,1,d,(function(t,e,r){return h&&!r.matchStart||(a=n.getCurrentTerm(r.match,o)),n.opt.filter(t,a,u,i[a],r)}),(function(t,e){c++,u=e.count,h&&!e.matchStart||(i[a]+=1),n.opt.each(t,e)}),(function(e){var r=o.filter((function(t){return 0===i[t]}));r.length&&n.opt.noMatch(r),!d.abort&&++s<f.length?t(f[s]):(n.registerHighlight(),n.opt.done(c,e,i))}))}(f[0])}else this.opt.done(0,0,i)}},{key:"getCurrentTerm",value:function(t,e){for(var n=t.length;--n>2;)if(t[n])return e[n-3];return" "}},{key:"getRegExps",value:function(t){var e,n=new a(this.opt),r=this.opt.combineBy||this.opt.combinePatterns,o=t.length,i=[],s=100;r===1/0?s=o:!isNaN(+r)&&(e=parseInt(r))>0&&(s=e);for(var c=0;c<o;c+=s){var u=t.slice(c,Math.min(c+s,o));i.push({regex:n.create(u),regTerms:u})}return i}},{key:"markRanges",value:function(t,e){var n=this;if(this.opt=e,Array.isArray(t)){var r=0;this.processRanges(t,(function(t,e,r,o){return n.opt.filter(t,e,r,o)}),(function(t,e,o){r++,n.opt.each(t,e,o)}),(function(t,e){n.report(e),n.registerHighlight(),n.opt.done(r,t)}))}else this.report([{text:"markRanges() accept an array of objects: ",obj:t,level:"error"}]),this.opt.done(0,0)}},{key:"unmark",value:function(t){var e=this;this.opt=t;var n=CSS.highlights,r=this.opt.exclude&&this.opt.exclude.length;if(n){var o,a=this.opt.highlightName;"string"==typeof a&&(a=[a]),a.forEach((function(t){(o=n.get(t))&&o.size&&(n.delete(t),r?o.forEach((function(t){var n=t.startContainer;3===n.nodeType&&(n=n.parentNode),e.excluded(n)||o.delete(t)})):o.clear(),o.size&&n.set(t,o))}))}if(this.opt.highlight)this.opt.done();else{var s=this.opt.element+"[data-markjs]";this.opt.className&&(s+=".".concat(this.opt.className)),this.log('Removal selector "'.concat(s,'"')),this.iterator.forEachNode(this.filter.SHOW_ELEMENT,(function(t){e.unwrapMatches(t)}),(function(t){return i.matches(t,s)&&!(r&&e.excluded(t))}),this.opt.done)}}},{key:"registerHighlight",value:function(){var t=this,e=this.opt.highlight;if(e){var n=this.opt.highlightName,r=CSS.highlights;this.rangeArray.length&&(r.delete(n),e.size&&(e.forEach((function(e){t.rangeArray.push(e)})),e.clear()),this.rangeArray.sort((function(t,e){return t.absoluteOffset-e.absoluteOffset})),this.rangeArray.forEach((function(t){e.add(t)})),this.rangeArray=[]),e.size&&r.set(n,e)}}}]),n}();return function(t){var e=this,n=new s(t);return this.mark=function(t,r){return n.mark(t,r),e},this.markRegExp=function(t,r){return n.markRegExp(t,r),e},this.markRanges=function(t,r){return n.markRanges(t,r),e},this.unmark=function(t){return n.unmark(t),e},this.getVersion=function(){return"3.0.0"},this}}));
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@ohos-ports/advanced-mark.js",
3
+ "version": "3.0.0-beta.0",
4
+ "keywords": [
5
+ "highlight",
6
+ "highlight-text",
7
+ "highlight-words",
8
+ "highlight-lines",
9
+ "search",
10
+ "jsdom",
11
+ "jquery",
12
+ "javascript",
13
+ "advanced-mark.js",
14
+ "mark.js"
15
+ ],
16
+ "license": "MIT",
17
+ "author": {
18
+ "name": "angezid",
19
+ "url": "https://github.com/angezid"
20
+ },
21
+ "description": "A fast JavaScript library to highlight any text on a browser page. It has support for CSS Custom Highlight API and virtual DOMs like JSDOM.",
22
+ "main": "dist/mark.js",
23
+ "types": "dist/mark.es6.d.ts",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/ohos-ports/ohos-ports.git",
27
+ "directory": "ports/advanced-mark.js/3.0.0"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/angezid/advanced-mark.js/issues"
31
+ },
32
+ "homepage": "https://github.com/angezid/advanced-mark.js",
33
+ "scripts": {
34
+ "eslint": "eslint src/ test/",
35
+ "karma": "karma start build/karma.config.js",
36
+ "copy-files": "node scripts/copy-types-files.js",
37
+ "build-performance": "node scripts/build-performance.js",
38
+ "test-jsdom": "node jsdom-tests/test.js",
39
+ "jsdoc": "jsdoc src/lib/ -d build/doc -R README.md -P package.json -r",
40
+ "compile": "rollup -c build/rollup.config.js",
41
+ "build": "npm run test && npm run copy-files && npm run build-performance && npm run jsdoc",
42
+ "dev": "nodemon --exec \"npm run eslint && npm run compile\" --watch src/ --watch test/ -e js,html",
43
+ "test": "npm run eslint && npm run compile && npm run karma && npm run test-jsdom"
44
+ },
45
+ "devDependencies": {
46
+ "@babel/core": "^7.26.10",
47
+ "@babel/plugin-transform-object-assign": "^7.22.5",
48
+ "@babel/preset-env": "^7.26.9",
49
+ "@metahub/karma-jasmine-jquery": "^4.0.1",
50
+ "@rollup/plugin-babel": "^6.0.4",
51
+ "@rollup/plugin-commonjs": "^28.0.3",
52
+ "@rollup/plugin-node-resolve": "^16.0.1",
53
+ "@rollup/plugin-terser": "^1.0.0",
54
+ "eslint": "8.56.0",
55
+ "eslint-plugin-jasmine-jquery": "^1.0.0",
56
+ "jasmine-core": "^4.5.0",
57
+ "jquery": "^3.2.1",
58
+ "jsdoc": "^4.0.0",
59
+ "jsdom": "^26.1.0",
60
+ "karma": "^6.4.4",
61
+ "karma-chrome-launcher": "^3.2.0",
62
+ "karma-cli": "^2.0.0",
63
+ "karma-coverage": "^2.1.1",
64
+ "karma-jasmine": "^5.1.0",
65
+ "karma-spec-reporter": "^0.0.36",
66
+ "karma-summary-reporter": "^4.0.1",
67
+ "puppeteer": "^25.6.0-beta.0",
68
+ "rollup": "^4.62.2-beta.0",
69
+ "rollup-plugin-cleanup": "^3.2.1",
70
+ "rollup-plugin-version-injector": "^1.3.3"
71
+ }
72
+ }
package/src/jquery.js ADDED
@@ -0,0 +1,24 @@
1
+ import Mark from './lib/mark';
2
+ import $ from 'jquery';
3
+
4
+ $.fn.mark = function(sv, opt) {
5
+ new Mark(this.get()).mark(sv, opt);
6
+ return this;
7
+ };
8
+ $.fn.markRegExp = function(regexp, opt) {
9
+ new Mark(this.get()).markRegExp(regexp, opt);
10
+ return this;
11
+ };
12
+ $.fn.markRanges = function(ranges, opt) {
13
+ new Mark(this.get()).markRanges(ranges, opt);
14
+ return this;
15
+ };
16
+ $.fn.unmark = function(opt) {
17
+ new Mark(this.get()).unmark(opt);
18
+ return this;
19
+ };
20
+ $.fn.getVersion = function() {
21
+ return '[VI]{version}[/VI]';
22
+ };
23
+
24
+ export default $;
@@ -0,0 +1,23 @@
1
+ import Mark from './lib/mark';
2
+
3
+ $.fn.mark = function(sv, opt) {
4
+ new Mark(this.get()).mark(sv, opt);
5
+ return this;
6
+ };
7
+ $.fn.markRegExp = function(regexp, opt) {
8
+ new Mark(this.get()).markRegExp(regexp, opt);
9
+ return this;
10
+ };
11
+ $.fn.markRanges = function(ranges, opt) {
12
+ new Mark(this.get()).markRanges(ranges, opt);
13
+ return this;
14
+ };
15
+ $.fn.unmark = function(opt) {
16
+ new Mark(this.get()).unmark(opt);
17
+ return this;
18
+ };
19
+ $.fn.getVersion = function() {
20
+ return '[VI]{version}[/VI]';
21
+ };
22
+
23
+ export default $;
@@ -0,0 +1,419 @@
1
+ /**
2
+ * A NodeIterator with iframes support and a method to check if an element is
3
+ * matching a specified selector
4
+ * @example
5
+ * const iterator = new DOMIterator("selector", opt);
6
+ * iterator.forEachNode(NodeFilter.SHOW_TEXT, node => { // each
7
+ * console.log(node);
8
+ * }, node => { // filter
9
+ * return !DOMIterator.matches(node.parentNode, ".ignore");
10
+ * }, () => { // done
11
+ * console.log("DONE");
12
+ * });
13
+ */
14
+ class DOMIterator {
15
+
16
+ /**
17
+ * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM
18
+ * element, an array of DOM elements, a NodeList or a selector
19
+ * @param {object} opt - Options object
20
+ */
21
+ constructor(ctx, opt) {
22
+ /**
23
+ * The context of the instance. Either a DOM element, an array of DOM
24
+ * elements, a NodeList or a selector
25
+ * @type {HTMLElement|HTMLElement[]|NodeList|string}
26
+ * @access protected
27
+ */
28
+ this.ctx = ctx;
29
+ /**
30
+ * The object containing Mark options
31
+ * @type {object}
32
+ * @access protected
33
+ */
34
+ this.opt = opt;
35
+ /**
36
+ * The map to truck iframes states
37
+ * @type {Map}
38
+ * @access protected
39
+ */
40
+ this.map = new Map();
41
+ }
42
+
43
+ /**
44
+ * Checks if the specified DOM element matches the selector
45
+ * @param {HTMLElement} element - The DOM element
46
+ * @param {string|string[]} selector - The selector or an array with
47
+ * selectors
48
+ * @return {boolean}
49
+ * @access public
50
+ */
51
+ static matches(element, selector) {
52
+ if ( !selector || !selector.length) {
53
+ return false;
54
+ }
55
+ const selectors = typeof selector === 'string' ? [selector] : selector,
56
+ fn = element.matches;
57
+ return fn && selectors.some(sel => fn.call(element, sel));
58
+ }
59
+
60
+ /**
61
+ * Returns all contexts filtered by duplicates or nested elements
62
+ * @return {HTMLElement[]} - An array containing DOM contexts
63
+ * @access protected
64
+ */
65
+ getContexts() {
66
+ let ctx = this.ctx,
67
+ win = this.opt.window,
68
+ sort = false;
69
+
70
+ if ( !ctx) return [];
71
+
72
+ if (Array.isArray(ctx)) {
73
+ sort = true;
74
+ } else if (typeof ctx === 'string') {
75
+ ctx = win.document.querySelectorAll(ctx);
76
+ } else if (typeof ctx.length === 'undefined') {
77
+ ctx = [ctx];
78
+ }
79
+
80
+ // filters out duplicate/nested elements
81
+ const array = [];
82
+ for (let i = 0; i < ctx.length; i++) {
83
+ if ( !array.includes(ctx[i]) && !array.some(node => node.contains(ctx[i]))) {
84
+ array.push(ctx[i]);
85
+ }
86
+ }
87
+ // elements in the custom array can be in any order
88
+ // sorts elements by the DOM order
89
+ if (sort) {
90
+ array.sort((a, b) => {
91
+ return (a.compareDocumentPosition(b) & win.Node.DOCUMENT_POSITION_FOLLOWING) > 0 ? -1 : 1;
92
+ });
93
+ }
94
+ return array;
95
+ }
96
+
97
+ /**
98
+ * @callback DOMIterator~getIframeContentsSuccessCallback
99
+ * @param {HTMLDocument} contents - The contentDocument of the iframe
100
+ */
101
+ /**
102
+ * Calls the success callback function with the iframe document. If it can't
103
+ * be accessed it calls the error callback function
104
+ * @param {HTMLElement} ifr - The iframe DOM element
105
+ * @param {DOMIterator~getIframeContentsSuccessCallback} successFn
106
+ * @param {function} [errorFn]
107
+ * @access protected
108
+ */
109
+ getIframeContents(iframe, successFn, errorFn) {
110
+ try {
111
+ const doc = iframe.contentWindow.document;
112
+ if (doc) {
113
+ this.map.set(iframe, 'ready');
114
+ successFn({ iframe: iframe, context: doc });
115
+ }
116
+ } catch (e) {
117
+ errorFn({ iframe: iframe, error: e });
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Observes the onload event of an iframe and calls the success callback or
123
+ * the error callback if the iframe is inaccessible. If the event isn't
124
+ * fired within the specified {@link DOMIterator#iframesTimeout}, then it'll
125
+ * call the error callback too
126
+ * @param {HTMLElement} ifr - The iframe DOM element
127
+ * @param {DOMIterator~getIframeContentsSuccessCallback} successFn
128
+ * @param {function} errorFn
129
+ * @access protected
130
+ */
131
+ observeIframeLoad(ifr, successFn, errorFn) {
132
+ // an event listener is already added to the iframe
133
+ if (this.map.has(ifr)) return;
134
+
135
+ let id = null;
136
+
137
+ const listener = () => {
138
+ clearTimeout(id);
139
+ ifr.removeEventListener('load', listener);
140
+ this.getIframeContents(ifr, successFn, errorFn);
141
+ };
142
+
143
+ ifr.addEventListener('load', listener);
144
+ this.map.set(ifr, true);
145
+ id = setTimeout(listener, this.opt.iframesTimeout);
146
+ }
147
+
148
+ /**
149
+ * Callback when the iframe is ready
150
+ * @callback DOMIterator~onIframeReadySuccessCallback
151
+ * @param {HTMLDocument} contents - The contentDocument of the iframe
152
+ */
153
+ /**
154
+ * Callback if the iframe can't be accessed
155
+ * @callback DOMIterator~onIframeReadyErrorCallback
156
+ */
157
+ /**
158
+ * Calls the callback if the specified iframe is ready for DOM access
159
+ * @param {HTMLElement} ifr - The iframe DOM element
160
+ * @param {DOMIterator~onIframeReadySuccessCallback} successFn - Success
161
+ * callback
162
+ * @param {DOMIterator~onIframeReadyErrorCallback} errorFn - Error callback
163
+ * @see {@link http://stackoverflow.com/a/36155560/3894981} for
164
+ * background information
165
+ * @access protected
166
+ */
167
+ onIframeReady(ifr, successFn, errorFn) {
168
+ const bl = 'about:blank',
169
+ src = ifr.getAttribute('src'),
170
+ win = ifr.contentWindow;
171
+
172
+ try {
173
+ if (win.document.readyState !== 'complete' || src && src.trim() !== bl && win.location.href === bl) {
174
+ this.observeIframeLoad(ifr, successFn, errorFn);
175
+ } else {
176
+ this.getIframeContents(ifr, successFn, errorFn);
177
+ }
178
+ } catch (e) { // accessing document failed
179
+ errorFn(e);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Callback when all context iframes are ready for DOM access
185
+ * @callback DOMIterator~waitForIframesDoneCallback
186
+ */
187
+ /**
188
+ * Iterates over all context iframes and calls the done callback when all of them
189
+ * are ready for DOM access (including nested ones)
190
+ * @param {HTMLElement} ctx - The context DOM element
191
+ * @param {DOMIterator~waitForIframesDoneCallback} done - Done callback
192
+ */
193
+ waitForIframes(ctx, doneCb) {
194
+ const shadow = this.opt.shadowDOM;
195
+ let count = 0,
196
+ iframes = 0,
197
+ array,
198
+ node;
199
+
200
+ const collect = context => {
201
+ const iterator = this.createIterator(context, this.opt.window.NodeFilter.SHOW_ELEMENT);
202
+
203
+ while ((node = iterator.nextNode())) {
204
+ if (this.isIframe(node) && !this.map.has(node)) {
205
+ array.push(node);
206
+ iframes++;
207
+ }
208
+
209
+ if (shadow && node.shadowRoot && node.shadowRoot.mode === 'open') {
210
+ collect(node.shadowRoot);
211
+ }
212
+ }
213
+ };
214
+
215
+ const loop = (obj) => {
216
+ array = [];
217
+
218
+ if ( !obj.iframe || obj.context.location.href !== 'about:blank') {
219
+ collect(obj.context);
220
+
221
+ if ( !obj.iframe && !array.length) {
222
+ doneCb();
223
+ return;
224
+ }
225
+ }
226
+
227
+ if (array.length) {
228
+ array.forEach(iframe => {
229
+ this.onIframeReady(iframe, obj => { // success
230
+ count++;
231
+ loop(obj);
232
+ }, obj => { // error
233
+ if (this.opt.debug) {
234
+ console.log(obj.error || obj);
235
+ }
236
+ if (++count === iframes) doneCb();
237
+ });
238
+ });
239
+ } else if (count === iframes) {
240
+ doneCb();
241
+ }
242
+ };
243
+
244
+ loop({ context: ctx });
245
+ }
246
+
247
+ /**
248
+ * Creates a NodeIterator on the specified context
249
+ * @see {@link https://developer.mozilla.org/en/docs/Web/API/NodeIterator}
250
+ * @param {HTMLElement} ctx - The context DOM element
251
+ * @param {DOMIterator~whatToShow} whatToShow
252
+ * @return {NodeIterator}
253
+ * @access protected
254
+ */
255
+ createIterator(ctx, whatToShow) {
256
+ const win = this.opt.window;
257
+ return win.document.createNodeIterator(ctx, whatToShow, () => win.NodeFilter.FILTER_ACCEPT, false);
258
+ }
259
+
260
+ /**
261
+ * Adds custom style to shadow root when marking, removes when unmark
262
+ * There is no possibility to check whether a shadow root has any matches though
263
+ * @param {HTMLElement} node - The shadow root node
264
+ * @param {HTMLElement} style - The custom style element
265
+ * @param {boolean} add - A boolean indicating add or remove a style element
266
+ */
267
+ addRemoveStyle(root, style, add) {
268
+ if (add && !style) return;
269
+
270
+ let elem = root.querySelector('style[data-markjs]');
271
+
272
+ if (add) {
273
+ if ( !elem) {
274
+ elem = this.opt.window.document.createElement('style');
275
+ elem.setAttribute('data-markjs', 'true');
276
+ root.appendChild(elem);
277
+ }
278
+ elem.textContent = style;
279
+
280
+ } else if (elem) {
281
+ root.removeChild(elem);
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Checks if the DOM element is an iframe and is not excluded from search
287
+ * @param {HTMLElement} element - The DOM element
288
+ * @return {boolean}
289
+ */
290
+ isIframe(node) {
291
+ return node.tagName === 'IFRAME' && !DOMIterator.matches(node, this.opt.exclude);
292
+ }
293
+
294
+ /**
295
+ * Iterates through all nodes, including shadow DOM nodes, in the specified context
296
+ * @param {HTMLElement} ctx - The context
297
+ * @param {DOMIterator~whatToShow} whatToShow
298
+ * @param {DOMIterator~filterCb} filterCb - Filter callback
299
+ * @param {DOMIterator~forEachNodeCallback} eachCb - Each callback
300
+ * @param {DOMIterator~forEachNodeEndCallback} doneCb - End callback
301
+ * @access protected
302
+ */
303
+ iterateThroughNodes(ctx, whatToShow, filterCb, eachCb, doneCb) {
304
+ const filter = this.opt.window.NodeFilter,
305
+ shadow = this.opt.shadowDOM,
306
+ iframe = this.opt.iframes;
307
+
308
+ if (iframe || shadow) {
309
+ const showElement = (whatToShow & filter.SHOW_ELEMENT) > 0,
310
+ showText = (whatToShow & filter.SHOW_TEXT) > 0;
311
+
312
+ const traverse = node => {
313
+ let iterator = this.createIterator(node, whatToShow | filter.SHOW_ELEMENT),
314
+ root;
315
+
316
+ while ((node = iterator.nextNode())) {
317
+ if (node.nodeType === 1) { // element
318
+ if (showElement && filterCb(node)) {
319
+ eachCb(node);
320
+ }
321
+
322
+ if (iframe && this.isIframe(node) && this.map.get(node) === 'ready') {
323
+ const doc = node.contentWindow.document;
324
+ if (doc) {
325
+ if (this.opt.highlight && showText) {
326
+ node.contentWindow.CSS.highlights.set(this.opt.highlightName, this.opt.highlight);
327
+ }
328
+ this.addRemoveStyle(doc.head, iframe.style, showText);
329
+ traverse(doc);
330
+ }
331
+ }
332
+ // there is no possibility to filter a whole shadow DOM, because the 'DOMIterator.matches()'
333
+ // is not working neither for 'shadowRoot' no for the element itself
334
+ if (shadow && (root = node.shadowRoot) && root.mode === 'open') {
335
+ this.addRemoveStyle(root, shadow.style, showText);
336
+ traverse(root);
337
+ }
338
+
339
+ } else if (showText && node.nodeType === 3 && filterCb(node)) { // text node
340
+ eachCb(node);
341
+ }
342
+ }
343
+ };
344
+
345
+ traverse(ctx);
346
+
347
+ } else {
348
+ const iterator = this.createIterator(ctx, whatToShow);
349
+ let node;
350
+
351
+ while ((node = iterator.nextNode())) {
352
+ if (filterCb(node)) {
353
+ eachCb(node);
354
+ }
355
+ }
356
+ }
357
+
358
+ doneCb();
359
+ }
360
+
361
+ /**
362
+ * @typedef DOMIterator~whatToShow
363
+ * @see {@link http://tinyurl.com/zfqqkx2}
364
+ * @type {number}
365
+ */
366
+ /**
367
+ * Callback to filter nodes. Can return either true to accept node or false to reject node.
368
+ * @see {@link http://tinyurl.com/zdczmm2}
369
+ * @callback DOMIterator~filterCb
370
+ * @param {Text|HTMLElement} node - The node to filter
371
+ */
372
+ /**
373
+ * Callback for each node
374
+ * @callback DOMIterator~forEachNodeCallback
375
+ * @param {Text|HTMLElement} node - The node node to process
376
+ */
377
+ /**
378
+ * Callback if all contexts were handled
379
+ * @callback DOMIterator~forEachNodeEndCallback
380
+ */
381
+ /**
382
+ * Iterates over all contexts
383
+ * @param {DOMIterator~whatToShow} whatToShow
384
+ * @param {DOMIterator~forEachNodeCallback} each - Each callback
385
+ * @param {DOMIterator~filterCb} filter - Filter callback
386
+ * @param {DOMIterator~forEachNodeEndCallback} done - End callback
387
+ * @access public
388
+ */
389
+ forEachNode(whatToShow, each, filter, done = () => {}) {
390
+ const contexts = this.getContexts();
391
+ let open = contexts.length;
392
+
393
+ if ( !open) done();
394
+
395
+ const ready = () => {
396
+ contexts.forEach(ctx => {
397
+ this.iterateThroughNodes(ctx, whatToShow, filter, each, () => {
398
+ if (--open <= 0) done(); // calls end when all contexts were handled
399
+ });
400
+ });
401
+ };
402
+
403
+ if (this.opt.iframes) {
404
+ let count = open;
405
+
406
+ // waits for all iframes to be ready for DOM access or timeout
407
+ contexts.forEach(ctx => {
408
+ this.waitForIframes(ctx, () => {
409
+ if (--count <= 0) ready();
410
+ });
411
+ });
412
+
413
+ } else {
414
+ ready();
415
+ }
416
+ }
417
+ }
418
+
419
+ export default DOMIterator;