mirror of
https://github.com/captn3m0/news.git
synced 2024-09-20 00:57:02 +00:00
Nemo
61f3d25deb
mark.js Source is at https://github.com/captn3m0/minimal-mark.js With license attribution
2 lines
16 KiB
JavaScript
2 lines
16 KiB
JavaScript
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):global.Mark=factory()})(this,function(){"use strict";function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof(obj)}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a 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,_toPropertyKey(descriptor.key),descriptor)}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor}function _extends(){_extends=Object.assign?Object.assign.bind():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};return _extends.apply(this,arguments)}function _toPrimitive(input,hint){if(typeof input!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(typeof res!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.")}return(hint==="string"?String:Number)(input)}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return typeof key==="symbol"?key:String(key)}var DOMIterator=function(){function DOMIterator(ctx){_classCallCheck(this,DOMIterator);this.ctx=ctx}_createClass(DOMIterator,[{key:"getContexts",value:function getContexts(){var ctx,filteredCtx=[];if(typeof this.ctx==="undefined"||!this.ctx){ctx=[]}else if(NodeList.prototype.isPrototypeOf(this.ctx)){ctx=Array.prototype.slice.call(this.ctx)}else if(Array.isArray(this.ctx)){ctx=this.ctx}else if(typeof this.ctx==="string"){ctx=Array.prototype.slice.call(document.querySelectorAll(this.ctx))}else{ctx=[this.ctx]}ctx.forEach(function(ctx){var isDescendant=filteredCtx.filter(function(contexts){return contexts.contains(ctx)}).length>0;if(filteredCtx.indexOf(ctx)===-1&&!isDescendant){filteredCtx.push(ctx)}});return filteredCtx}},{key:"createIterator",value:function createIterator(ctx,whatToShow,filter){return document.createNodeIterator(ctx,whatToShow,filter,false)}},{key:"getIteratorNode",value:function getIteratorNode(itr){var prevNode=itr.previousNode();var node;if(prevNode===null){node=itr.nextNode()}else{node=itr.nextNode()&&itr.nextNode()}return{prevNode:prevNode,node:node}}},{key:"iterateThroughNodes",value:function iterateThroughNodes(whatToShow,ctx,eachCb,filterCb,doneCb){var _this=this;var itr=this.createIterator(ctx,whatToShow,filterCb);var elements=[],node,prevNode,retrieveNodes=function retrieveNodes(){var _this$getIteratorNode=_this.getIteratorNode(itr);prevNode=_this$getIteratorNode.prevNode;node=_this$getIteratorNode.node;return node};while(retrieveNodes()){elements.push(node)}elements.forEach(function(node){eachCb(node)});doneCb()}},{key:"forEachNode",value:function forEachNode(whatToShow,each,filter){var _this2=this;var done=arguments.length>3&&arguments[3]!==undefined?arguments[3]:function(){};var contexts=this.getContexts();var open=contexts.length;if(!open){done()}contexts.forEach(function(ctx){var ready=function ready(){_this2.iterateThroughNodes(whatToShow,ctx,each,filter,function(){if(--open<=0){done()}})};ready()})}}],[{key:"matches",value:function matches(element,selector){var selectors=typeof selector==="string"?[selector]:selector,fn=element.matches||element.matchesSelector||element.msMatchesSelector||element.mozMatchesSelector||element.oMatchesSelector||element.webkitMatchesSelector;if(fn){var match=false;selectors.every(function(sel){if(fn.call(element,sel)){match=true;return false}return true});return match}else{return false}}}]);return DOMIterator}();var RegExpCreator=function(){function RegExpCreator(options){_classCallCheck(this,RegExpCreator);this.opt=_extends({},{accuracy:"complementary",caseSensitive:false,ignorePunctuation:":;.,-–—‒_(){}[]!'\"+=".split("")},options)}_createClass(RegExpCreator,[{key:"create",value:function create(str){str=this.escapeStr(str);str=this.createMergedBlanksRegExp(str);str=this.createAccuracyRegExp(str);return new RegExp(str,"gm".concat(this.opt.caseSensitive?"":"i"))}},{key:"sortByLength",value:function sortByLength(arry){return arry.sort(function(a,b){return a.length===b.length?a>b?1:-1:b.length-a.length})}},{key:"escapeStr",value:function escapeStr(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createMergedBlanksRegExp",value:function createMergedBlanksRegExp(str){return str.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function createAccuracyRegExp(str){var chars="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";var lsJoin="\\s"+this.escapeStr(chars);return"()([^".concat(lsJoin,"]*").concat(str,"[^").concat(lsJoin,"]*)")}}]);return RegExpCreator}();var Mark=function(){function Mark(ctx){_classCallCheck(this,Mark);this.ctx=ctx;this.ie=false;var ua=window.navigator.userAgent;if(ua.indexOf("MSIE")>-1||ua.indexOf("Trident")>-1){this.ie=true}}_createClass(Mark,[{key:"opt",get:function get(){return this._opt},set:function set(val){this._opt=_extends({},{element:"",className:"",exclude:[],iframes:false,iframesTimeout:5e3,separateWordSearch:true,acrossElements:false,ignoreGroups:0,each:function each(){},noMatch:function noMatch(){},filter:function filter(){return true},done:function done(){},debug:false,log:window.console},val)}},{key:"iterator",get:function get(){return new DOMIterator(this.ctx)}},{key:"log",value:function log(msg){var level=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"debug";var log=this.opt.log;if(!this.opt.debug){return}if(_typeof(log)==="object"&&typeof log[level]==="function"){log[level]("mark.js: ".concat(msg))}}},{key:"getSeparatedKeywords",value:function getSeparatedKeywords(sv){var _this=this;var stack=[];sv.forEach(function(kw){if(!_this.opt.separateWordSearch){if(kw.trim()&&stack.indexOf(kw)===-1){stack.push(kw)}}else{kw.split(" ").forEach(function(kwSplitted){if(kwSplitted.trim()&&stack.indexOf(kwSplitted)===-1){stack.push(kwSplitted)}})}});return{keywords:stack.sort(function(a,b){return b.length-a.length}),length:stack.length}}},{key:"isNumeric",value:function isNumeric(value){return Number(parseFloat(value))==value}},{key:"checkRanges",value:function checkRanges(array){var _this2=this;if(!Array.isArray(array)||Object.prototype.toString.call(array[0])!=="[object Object]"){this.log("markRanges() will only accept an array of objects");this.opt.noMatch(array);return[]}var stack=[];var last=0;array.sort(function(a,b){return a.start-b.start}).forEach(function(item){var _this2$callNoMatchOnI=_this2.callNoMatchOnInvalidRanges(item,last),start=_this2$callNoMatchOnI.start,end=_this2$callNoMatchOnI.end,valid=_this2$callNoMatchOnI.valid;if(valid){item.start=start;item.length=end-start;stack.push(item);last=end}});return stack}},{key:"callNoMatchOnInvalidRanges",value:function callNoMatchOnInvalidRanges(range,last){var start,end,valid=false;if(range&&typeof range.start!=="undefined"){start=parseInt(range.start,10);end=start+parseInt(range.length,10);if(this.isNumeric(range.start)&&this.isNumeric(range.length)&&end-last>0&&end-start>0){valid=true}else{this.log("Ignoring invalid or overlapping range: "+"".concat(JSON.stringify(range)));this.opt.noMatch(range)}}else{this.log("Ignoring invalid range: ".concat(JSON.stringify(range)));this.opt.noMatch(range)}return{start:start,end:end,valid:valid}}},{key:"checkWhitespaceRanges",value:function checkWhitespaceRanges(range,originalLength,string){var end,valid=true,max=string.length,offset=originalLength-max,start=parseInt(range.start,10)-offset;start=start>max?max:start;end=start+parseInt(range.length,10);if(end>max){end=max;this.log("End range automatically set to the max value of ".concat(max))}if(start<0||end-start<0||start>max||end>max){valid=false;this.log("Invalid range: ".concat(JSON.stringify(range)));this.opt.noMatch(range)}else if(string.substring(start,end).replace(/\s+/g,"")===""){valid=false;this.log("Skipping whitespace only range: "+JSON.stringify(range));this.opt.noMatch(range)}return{start:start,end:end,valid:valid}}},{key:"getTextNodes",value:function getTextNodes(cb){var _this3=this;var val="",nodes=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(node){nodes.push({start:val.length,end:(val+=node.textContent).length,node:node})},function(node){if(_this3.matchesExclude(node.parentNode)){return NodeFilter.FILTER_REJECT}else{return NodeFilter.FILTER_ACCEPT}},function(){cb({value:val,nodes:nodes})})}},{key:"matchesExclude",value:function matchesExclude(el){return DOMIterator.matches(el,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function wrapRangeInTextNode(node,start,end){var hEl=!this.opt.element?"mark":this.opt.element,startNode=node.splitText(start),ret=startNode.splitText(end-start);var repl=document.createElement(hEl);repl.setAttribute("data-markjs","true");if(this.opt.className){repl.setAttribute("class",this.opt.className)}repl.textContent=startNode.textContent;startNode.parentNode.replaceChild(repl,startNode);return ret}},{key:"wrapRangeInMappedTextNode",value:function wrapRangeInMappedTextNode(dict,start,end,filterCb,eachCb){var _this4=this;dict.nodes.every(function(n,i){var sibl=dict.nodes[i+1];if(typeof sibl==="undefined"||sibl.start>start){if(!filterCb(n.node)){return false}var s=start-n.start,e=(end>n.end?n.end:end)-n.start,startStr=dict.value.substr(0,n.start),endStr=dict.value.substr(e+n.start);n.node=_this4.wrapRangeInTextNode(n.node,s,e);dict.value=startStr+endStr;dict.nodes.forEach(function(k,j){if(j>=i){if(dict.nodes[j].start>0&&j!==i){dict.nodes[j].start-=e}dict.nodes[j].end-=e}});end-=e;eachCb(n.node.previousSibling,n.start);if(end>n.end){start=n.end}else{return false}}return true})}},{key:"wrapGroups",value:function wrapGroups(node,pos,len,eachCb){node=this.wrapRangeInTextNode(node,pos,pos+len);eachCb(node.previousSibling);return node}},{key:"separateGroups",value:function separateGroups(node,match,matchIdx,filterCb,eachCb){var matchLen=match.length;for(var i=1;i<matchLen;i++){var pos=node.textContent.indexOf(match[i]);if(match[i]&&pos>-1&&filterCb(match[i],node)){node=this.wrapGroups(node,pos,match[i].length,eachCb)}}return node}},{key:"wrapMatches",value:function wrapMatches(regex,ignoreGroups,filterCb,eachCb,endCb){var _this5=this;var matchIdx=ignoreGroups===0?0:ignoreGroups+1;this.getTextNodes(function(dict){dict.nodes.forEach(function(node){node=node.node;var match;while((match=regex.exec(node.textContent))!==null&&match[matchIdx]!==""){if(_this5.opt.separateGroups&&match.length!==1){node=_this5.separateGroups(node,match,matchIdx,filterCb,eachCb)}else{if(!filterCb(match[matchIdx],node)){continue}var pos=match.index;if(matchIdx!==0){for(var i=1;i<matchIdx;i++){pos+=match[i].length}}node=_this5.wrapGroups(node,pos,match[matchIdx].length,eachCb)}regex.lastIndex=0}});endCb()})}},{key:"wrapMatchesAcrossElements",value:function wrapMatchesAcrossElements(regex,ignoreGroups,filterCb,eachCb,endCb){var _this6=this;var matchIdx=ignoreGroups===0?0:ignoreGroups+1;this.getTextNodes(function(dict){var match;while((match=regex.exec(dict.value))!==null&&match[matchIdx]!==""){var start=match.index;if(matchIdx!==0){for(var i=1;i<matchIdx;i++){start+=match[i].length}}var end=start+match[matchIdx].length;_this6.wrapRangeInMappedTextNode(dict,start,end,function(node){return filterCb(match[matchIdx],node)},function(node,lastIndex){regex.lastIndex=lastIndex;eachCb(node)})}endCb()})}},{key:"wrapRangeFromIndex",value:function wrapRangeFromIndex(ranges,filterCb,eachCb,endCb){var _this7=this;this.getTextNodes(function(dict){var originalLength=dict.value.length;ranges.forEach(function(range,counter){var _this7$checkWhitespac=_this7.checkWhitespaceRanges(range,originalLength,dict.value),start=_this7$checkWhitespac.start,end=_this7$checkWhitespac.end,valid=_this7$checkWhitespac.valid;if(valid){_this7.wrapRangeInMappedTextNode(dict,start,end,function(node){return filterCb(node,range,dict.value.substring(start,end),counter)},function(node){eachCb(node,range)})}});endCb()})}},{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);if(!this.ie){parent.normalize()}else{this.normalizeTextNode(parent)}}},{key:"normalizeTextNode",value:function normalizeTextNode(node){if(!node){return}if(node.nodeType===3){while(node.nextSibling&&node.nextSibling.nodeType===3){node.nodeValue+=node.nextSibling.nodeValue;node.parentNode.removeChild(node.nextSibling)}}else{this.normalizeTextNode(node.firstChild)}this.normalizeTextNode(node.nextSibling)}},{key:"markRegExp",value:function markRegExp(regexp,opt){var _this8=this;this.opt=opt;this.log('Searching with expression "'.concat(regexp,'"'));var totalMatches=0,fn="wrapMatches";var eachCb=function eachCb(element){totalMatches++;_this8.opt.each(element)};if(this.opt.acrossElements){fn="wrapMatchesAcrossElements"}this[fn](regexp,this.opt.ignoreGroups,function(match,node){return _this8.opt.filter(node,match,totalMatches)},eachCb,function(){if(totalMatches===0){_this8.opt.noMatch(regexp)}_this8.opt.done(totalMatches)})}},{key:"mark",value:function mark(sv,opt){var _this9=this;this.opt=opt;var totalMatches=0,fn="wrapMatches";var _this$getSeparatedKey=this.getSeparatedKeywords(typeof sv==="string"?[sv]:sv),kwArr=_this$getSeparatedKey.keywords,kwArrLen=_this$getSeparatedKey.length,handler=function handler(kw){var regex=new RegExpCreator(_this9.opt).create(kw);var matches=0;_this9.log('Searching with expression "'.concat(regex,'"'));_this9[fn](regex,1,function(term,node){return _this9.opt.filter(node,kw,totalMatches,matches)},function(element){matches++;totalMatches++;_this9.opt.each(element)},function(){if(matches===0){_this9.opt.noMatch(kw)}if(kwArr[kwArrLen-1]===kw){_this9.opt.done(totalMatches)}else{handler(kwArr[kwArr.indexOf(kw)+1])}})};if(this.opt.acrossElements){fn="wrapMatchesAcrossElements"}if(kwArrLen===0){this.opt.done(totalMatches)}else{handler(kwArr[0])}}},{key:"markRanges",value:function markRanges(rawRanges,opt){var _this10=this;this.opt=opt;var totalMatches=0,ranges=this.checkRanges(rawRanges);if(ranges&&ranges.length){this.log("Starting to mark with the following ranges: "+JSON.stringify(ranges));this.wrapRangeFromIndex(ranges,function(node,range,match,counter){return _this10.opt.filter(node,range,match,counter)},function(element,range){totalMatches++;_this10.opt.each(element,range)},function(){_this10.opt.done(totalMatches)})}else{this.opt.done(totalMatches)}}},{key:"unmark",value:function unmark(opt){var _this11=this;this.opt=opt;var sel=this.opt.element?this.opt.element:"*";sel+="[data-markjs]";if(this.opt.className){sel+=".".concat(this.opt.className)}this.log('Removal selector "'.concat(sel,'"'));this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,function(node){_this11.unwrapMatches(node)},function(node){var matchesSel=DOMIterator.matches(node,sel),matchesExclude=_this11.matchesExclude(node);if(!matchesSel||matchesExclude){return NodeFilter.FILTER_REJECT}else{return NodeFilter.FILTER_ACCEPT}},this.opt.done)}}]);return Mark}();function Mark$1(ctx){var _this=this;var instance=new Mark(ctx);this.mark=function(sv,opt){instance.mark(sv,opt);return _this};this.unmark=function(opt){instance.unmark(opt);return _this};return this}return Mark$1});
|