diff --git a/_includes/app.js b/_includes/app.js index 9bf88ee..66a7e94 100644 --- a/_includes/app.js +++ b/_includes/app.js @@ -40,4 +40,30 @@ document.addEventListener('DOMContentLoaded', function () { detailsElement.classList.add('viewed'); } }); + + // Set highlight words + if(hw = document.getElementById('highlight-words')) { + hw.value = (JSON.parse(localStorage.getItem("highlightWords"))||[]).join("\n"); + } + + // Save settings + if(document.getElementById('btn-settings-save')) { + document.getElementById('btn-settings-save').addEventListener('click', function (e) { + val = document.getElementById('highlight-words').value.split("\n").map(function(x){return x.trim()}); + localStorage.setItem('highlightWords', JSON.stringify(val)); + return false; + }); + } + + // Enable highlighting + if(words = localStorage.getItem('highlightWords')) { + var scriptTag = document.createElement('script'); + scriptTag.setAttribute('src','/assets/mark.min.js'); + scriptTag.async=scriptTag.defer = true; + document.body.appendChild(scriptTag); + scriptTag.onload = function() { + var markInstance = new Mark(document.querySelector("main")); + markInstance.mark(JSON.parse(words), {}); + } + } }); diff --git a/_includes/footer.html b/_includes/footer.html index f0bf875..5de6762 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -13,6 +13,7 @@ diff --git a/_includes/style.css b/_includes/style.css index 9f463e1..337baeb 100644 --- a/_includes/style.css +++ b/_includes/style.css @@ -9,7 +9,6 @@ body { max-width: 550px; margin: 0 auto; font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; - } main { @@ -76,7 +75,7 @@ h2 { } .button:link, -.button:visited { +.button:visited, button, input[type=button] { background-color: #660033; color: white; border: 1px solid #660033; @@ -127,4 +126,10 @@ details .trigger-warning { } details[open] .trigger-warning { display: none; +} + +mark { + background: #ff0; + padding: 0px 2px; + color: #000; } \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html index ea75113..784e563 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -10,7 +10,7 @@

Text-Only iOS Android - Web + Web

@@ -20,6 +20,6 @@
{% include_cached footer.html %} - + diff --git a/assets/mark.min.js b/assets/mark.min.js new file mode 100644 index 0000000..0ed5f56 --- /dev/null +++ b/assets/mark.min.js @@ -0,0 +1 @@ +(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;i0;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-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 +
+
+ +
+ + \ No newline at end of file