@notelix/web-marker
Version:
a web page highlighter
2 lines • 17.6 kB
JavaScript
!function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t():"function"===typeof define&&define.amd?define([],t):"object"===typeof exports?exports["web-marker"]=t():e["web-marker"]=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function i(e){if("undefined"===typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(e=function(e,t){if(e){if("string"===typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}(e))){var t=0,n=function(){};return{s:n,n:function(){return t>=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o,l=!0,a=!1;return{s:function(){i=e[Symbol.iterator]()},n:function(){var e=i.next();return l=e.done,e},e:function(e){a=!0,o=e},f:function(){try{l||null==i.return||i.return()}finally{if(a)throw o}}}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function l(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var a;n.r(t),n.d(t,"Marker",(function(){return R})),n.d(t,"Errors",(function(){return I}));var u=new Uint8Array(16);function f(){if(!a&&!(a="undefined"!==typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!==typeof msCrypto&&"function"===typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return a(u)}var s=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;for(var d=function(e){return"string"===typeof e&&s.test(e)},h=[],c=0;c<256;++c)h.push((c+256).toString(16).substr(1));var v=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(h[e[t+0]]+h[e[t+1]]+h[e[t+2]]+h[e[t+3]]+"-"+h[e[t+4]]+h[e[t+5]]+"-"+h[e[t+6]]+h[e[t+7]]+"-"+h[e[t+8]]+h[e[t+9]]+"-"+h[e[t+10]]+h[e[t+11]]+h[e[t+12]]+h[e[t+13]]+h[e[t+14]]+h[e[t+15]]).toLowerCase();if(!d(n))throw TypeError("Stringified UUID is invalid");return n};var g=function(e,t,n){var r=(e=e||{}).random||(e.rng||f)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(var i=0;i<16;++i)t[n+i]=r[i];return t}return v(r)};function m(){return g()}function p(e,t){return(p=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function y(e){return(y=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function x(){if("undefined"===typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"===typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function b(e){return(b="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function T(e,t){return!t||"object"!==b(t)&&"function"!==typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function E(e,t,n){return(E=x()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var i=new(Function.bind.apply(e,r));return n&&p(i,n.prototype),i}).apply(null,arguments)}function N(e){var t="function"===typeof Map?new Map:void 0;return(N=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!==typeof e)throw new TypeError("Super expression must either be null or a function");if("undefined"!==typeof t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return E(e,arguments,y(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),p(r,e)})(e)}var k=function(e){!function(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&p(e,t)}(r,e);var t,n=(t=r,function(){var e,n=y(t);if(x()){var r=y(this).constructor;e=Reflect.construct(n,arguments,r)}else e=n.apply(this,arguments);return T(this,e)});function r(){return o(this,r),n.apply(this,arguments)}return r}(N(Error));var S=document.createElement("style");S.innerText=".".concat("web-marker-black-listed-element",", .MJX_Assistive_MathML>math>*, math>semantics>* {display:none!important;};");var C={paintHighlight:function(e,t){console.log("paintHighlight",e,t),t.style.textDecoration="underline",t.style.textDecorationColor="orange"}},O={onHighlightClick:function(e,t){console.log("onHighlightClick",e,t)},onHighlightHoverStateChange:function(e,t,n){console.log("onHighlightHoverStateChange",e,t),t.style.backgroundColor=n?"#FFE49C":""}},w=function(){function e(t){var n=this,r=t.rootElement,i=t.highlightPainter,l=t.eventHandler;o(this,e),this.rootElement=void 0,this.eventHandler=void 0,this.highlightPainter=void 0,this.state={lastHoverId:"",uidToSerializedRange:{}},this.clickListener=function(e){if(e.target&&e.target instanceof HTMLElement){var t=e.target,r=t.getAttribute("highlight-id");r&&n.eventHandler.onHighlightClick&&n.eventHandler.onHighlightClick(n.buildContext(r),t,e)}},this.mouseoverListener=function(e){if(e.target&&e.target instanceof HTMLElement){var t=e.target,r=null===t||void 0===t?void 0:t.getAttribute("highlight-id");if(n.state.lastHoverId!==r){var i=n.state.lastHoverId;n.state.lastHoverId=r,r&&n.highlightHovering(r,!0,e),i&&n.highlightHovering(i,!1,e)}}},this.rootElement=r||document.body,this.highlightPainter=i||C,this.eventHandler=l||O}var t,n,r;return t=e,r=[{key:"clearSelection",value:function(){var e=window.getSelection();e&&(e.empty?e.empty():e.removeAllRanges&&e.removeAllRanges())}},{key:"resolveHighlightElements",value:function(e){for(var t=[],n=0,r=Array.from(document.getElementsByTagName("web-marker-highlight"));n<r.length;n++){var i=r[n];i.getAttribute("highlight-id")===e&&t.push(i)}return t}},{key:"normalizeText",value:function(t){return e.normalizeTextCache[t]||(e.normalizeTextCache[t]=t.replace(/\s/g,"").toLowerCase()),e.normalizeTextCache[t]}},{key:"isBlackListedElementNode",value:function(e){if(!e)return!1;if(e.nodeType!==Node.ELEMENT_NODE)return!1;var t=getComputedStyle(e);if("none"===t.display)return!0;if("hidden"===t.visibility)return!0;var n=e.className;if(n&&n.indexOf&&n.indexOf("web-marker-black-listed-element")>=0)return!0;var r=e.tagName;return"STYLE"===r||"SCRIPT"===r||"TITLE"===r||"NOSCRIPT"===r}},{key:"getRealOffset",value:function(t,n){for(var r=t.textContent||"",i=0,o=0;o<r.length;o++){for(;o<r.length&&!e.normalizeText(r.substr(o,1));)o++;if(i===n)return o;i++}if(i===n)return r.length;throw new Error("failed to get real offset")}},{key:"unpaintElement",value:function(e){for(var t,n=Array.from(e.childNodes),r=0;r<n.length;r++){var i;null===(i=e.parentNode)||void 0===i||i.insertBefore(n[r],e)}null===(t=e.parentNode)||void 0===t||t.removeChild(e)}},{key:"convertRangeToSelection",value:function(e){var t=window.getSelection();return t.removeAllRanges(),t.addRange(e),t}}],(n=[{key:"serializeRange",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{uid:void 0,charsToKeepForTextBeforeAndTextAfter:128};document.head.appendChild(S);try{this.adjustRangeAroundBlackListedElement(t);var r=(null===n||void 0===n?void 0:n.uid)||m(),i=(null===n||void 0===n?void 0:n.charsToKeepForTextBeforeAndTextAfter)||128,o=e.convertRangeToSelection(t),l=o.toString(),a=e.normalizeText(l);if(a){var u="",f="";u+=this.getInnerText(t.startContainer).substr(0,t.startOffset);for(var s=t.startContainer;u.length<i&&(s=this.findPreviousTextNodeInDomTree(s));)u=s.textContent+u;u.length>i&&(u=u.substr(u.length-i)),f+=this.getInnerText(t.endContainer).substr(t.endOffset);for(var d=t.endContainer;f.length<i&&(d=this.findNextTextNodeInDomTree(d));)f+=d.textContent;return f.length>i&&(f=f.substr(0,i)),this.state.uidToSerializedRange[r]={uid:r,textBefore:u,text:l,textAfter:f},this.state.uidToSerializedRange[r]}return null}finally{document.head.removeChild(S)}}},{key:"batchPaint",value:function(e){for(var t=this,n={},r=this.batchDeserializeRange(e),i=r.results,o=r.errors,l=function(r){if(o[r])return n[r]=o[r],"continue";var l=e[r].uid,a=i[r];if(!a.collapsed){var u=function(e){e.setAttribute("highlight-id",l)};try{!function(){if(a.startContainer===a.endContainer){if(a.startOffset===a.endOffset)return;var e=a.startContainer.splitText(a.startOffset);return e.splitText(a.endOffset),void u(t.convertTextNodeToHighlightElement(e))}var n=[],r=a.startContainer.splitText(a.startOffset);for(n.push(r);(r=t.findNextTextNodeInDomTree(r))!==a.endContainer;)n.push(r);a.endContainer.splitText(a.endOffset),n.push(a.endContainer),n.forEach((function(e){if(e){var n,r,i=t.convertTextNodeToHighlightElement(e);u(i),i.innerText||(null===(n=i.parentElement)||void 0===n||n.insertBefore(e,i.nextSibling),null===(r=i.parentElement)||void 0===r||r.removeChild(i))}}))}(),t.paintHighlights(l)}catch(f){n[r]=f}}},a=0;a<e.length;a++)l(a);return{errors:n}}},{key:"paint",value:function(e){if(e){var t=this.batchPaint([e]).errors;if(t[0])throw t[0]}}},{key:"unpaint",value:function(t){var n,r=t.uid,o=i(e.resolveHighlightElements(r));try{for(o.s();!(n=o.n()).done;){var l=n.value;e.unpaintElement(l)}}catch(a){o.e(a)}finally{o.f()}}},{key:"batchDeserializeRange",value:function(t){document.head.appendChild(S);for(var n={},r={},i=this.getNormalizedInnerText(this.rootElement),o=0;o<t.length;o++)try{this.state.uidToSerializedRange[t[o].uid]=t[o];var l=this.resolveSerializedRangeOffsetInText(i,t[o]),a=this.findElementAtOffset(this.rootElement,l),u=this.findElementAtOffset(this.rootElement,l+e.normalizeText(t[o].text).length),f=document.createRange();f.setStart(a.element,e.getRealOffset(a.element,a.offset)),f.setEnd(u.element,e.getRealOffset(u.element,u.offset)),this.trimRangeSpaces(f),n[o]=f}catch(s){r[o]=s}return document.head.removeChild(S),{results:n,errors:r}}},{key:"deserializeRange",value:function(e){var t=this.batchDeserializeRange([e]),n=t.results,r=t.errors;if(r[0])throw r[0];return n[0]}},{key:"addEventListeners",value:function(){this.rootElement.addEventListener("click",this.clickListener,!0),this.rootElement.addEventListener("mouseover",this.mouseoverListener,!0)}},{key:"removeEventListeners",value:function(){this.rootElement.removeEventListener("click",this.clickListener,!0),this.rootElement.removeEventListener("mouseover",this.mouseoverListener,!0)}},{key:"paintHighlights",value:function(t){var n=this.buildContext(t);this.highlightPainter.beforePaintHighlight&&this.highlightPainter.beforePaintHighlight(n);var r,o=i(e.resolveHighlightElements(t));try{for(o.s();!(r=o.n()).done;){var l=r.value;this.highlightPainter.paintHighlight(n,l)}}catch(a){o.e(a)}finally{o.f()}this.highlightPainter.afterPaintHighlight&&this.highlightPainter.afterPaintHighlight(n)}},{key:"highlightHovering",value:function(t,n,r){var o,l=i(e.resolveHighlightElements(t));try{for(l.s();!(o=l.n()).done;){var a=o.value;this.eventHandler.onHighlightHoverStateChange&&this.eventHandler.onHighlightHoverStateChange(this.buildContext(t),a,n,r)}}catch(u){l.e(u)}finally{l.f()}}},{key:"getInnerText",value:function(t){if(e.isBlackListedElementNode(t))return"";if(t.nodeType===Node.TEXT_NODE)return t.textContent;if("undefined"===typeof t.innerText){for(var n="",r=0;r<t.childNodes.length;r++)n+=this.getInnerText(t.childNodes[r]);return n}return t.innerText}},{key:"getNormalizedInnerText",value:function(t){return e.normalizeText(this.getInnerText(t))}},{key:"findLastChildTextNode",value:function(t){if(!t)return null;if(t.nodeType===Node.TEXT_NODE)return t;if(t.childNodes)for(var n=t.childNodes.length-1;n>=0;n--)if(!e.isBlackListedElementNode(t.childNodes[n])){var r=this.findLastChildTextNode(t.childNodes[n]);if(null!==r)return r}return null}},{key:"findFirstChildTextNode",value:function(t){if(t.nodeType===Node.TEXT_NODE)return t;if(t.childNodes)for(var n=0;n<t.childNodes.length;n++)if(!e.isBlackListedElementNode(t.childNodes[n])){var r=this.findFirstChildTextNode(t.childNodes[n]);if(null!==r)return r}return null}},{key:"findPreviousTextNodeInDomTree",value:function(t){for(;t;){for(var n;e.isBlackListedElementNode((null===(r=t)||void 0===r?void 0:r.previousSibling)||null);){var r,i;t=(null===(i=t)||void 0===i?void 0:i.previousSibling)||null}for(;null===(o=t)||void 0===o?void 0:o.previousSibling;){var o,l,a=this.findLastChildTextNode((null===(l=t)||void 0===l?void 0:l.previousSibling)||null);if(a)return a;t=t.previousSibling}t=(null===(n=t)||void 0===n?void 0:n.parentElement)||null}return null}},{key:"findNextTextNodeInDomTree",value:function(t){for(;t;){for(var n;e.isBlackListedElementNode((null===(r=t)||void 0===r?void 0:r.nextSibling)||null);){var r,i;t=(null===(i=t)||void 0===i?void 0:i.nextSibling)||null}for(;null===(o=t)||void 0===o?void 0:o.nextSibling;){var o,l;if(e.isBlackListedElementNode(null===(l=t)||void 0===l?void 0:l.nextSibling))t=t.nextSibling;else{var a=this.findFirstChildTextNode(t.nextSibling);if(a)return a;t=t.nextSibling}}t=(null===(n=t)||void 0===n?void 0:n.parentElement)||null}return null}},{key:"forwardOffset",value:function(e,t){var n=e.element,r=e.offset,i=this.getNormalizedInnerText(n);if(i.length>t+r)return{element:n,offset:r+=t};var o=this.findNextTextNodeInDomTree(n);return o?this.forwardOffset({element:o,offset:0},t-(i.length-r)):{element:n,offset:r=this.getInnerText(n)}}},{key:"backwardOffset",value:function(e,t){var n=e.element,r=e.offset;if(r>=t)return{element:n,offset:r-=t};var i=this.findPreviousTextNodeInDomTree(n);return i?this.backwardOffset({element:i,offset:this.getNormalizedInnerText(i).length},t-r):{element:n,offset:r=0}}},{key:"findElementAtOffset",value:function(t,n){if(t.nodeType===Node.TEXT_NODE)return{element:t,offset:n};for(var r=0,i=0;i<t.childNodes.length;i++)if(!e.isBlackListedElementNode(t.childNodes[i])){var o=this.getNormalizedInnerText(t.childNodes[i]).length;if(!((r+=o)<n))return this.findElementAtOffset(t.childNodes[i],n-(r-o))}throw new Error("failed to findElementAtOffset")}},{key:"trimRangeSpaces",value:function(e){var t=this.getInnerText(e.startContainer).substr(e.startOffset),n=t.trimStart();e.setStart(e.startContainer,e.startOffset+(t.length-n.length));var r=this.getInnerText(e.endContainer).substr(0,e.endOffset),i=r.trimEnd();e.setEnd(e.endContainer,e.endOffset-(r.length-i.length))}},{key:"convertTextNodeToHighlightElement",value:function(e){var t,n,r=document.createElement("web-marker-highlight");return null===(t=e.parentElement)||void 0===t||t.insertBefore(r,e.nextSibling),null===(n=e.parentElement)||void 0===n||n.removeChild(e),r.appendChild(e),r}},{key:"buildContext",value:function(e){return{serializedRange:this.state.uidToSerializedRange[e],marker:this}}},{key:"adjustRangeAroundBlackListedElement",value:function(t){for(var n=t.startContainer,r=null;n;)e.isBlackListedElementNode(n)&&(r=n),n=n.parentElement;n=t.endContainer;for(var i=null;n;)e.isBlackListedElementNode(n)&&(i=n),n=n.parentElement;if(r&&i&&r===i)throw new Error("cannot highlight blacklisted element");if(r&&t.setStart(this.findNextTextNodeInDomTree(r),0),i){var o=this.findPreviousTextNodeInDomTree(i);t.setEnd(o,this.getInnerText(o).length)}}},{key:"getSerializedRangeFromUid",value:function(e){return this.state.uidToSerializedRange[e]||null}},{key:"resolveSerializedRangeOffsetInText",value:function(t,n){var r,o=e.normalizeText(n.textBefore),l=e.normalizeText(n.textAfter),a=e.normalizeText(n.text),u=i(H);try{for(u.s();!(r=u.n()).done;){var f=r.value,s=(f.textBefore?o:"")+a+(f.textAfter?l:""),d=t.indexOf(s);if(d>=0)return d+(f.textBefore?o.length:0)}}catch(h){u.e(h)}finally{u.f()}throw new k("failed to deserialize range")}}])&&l(t.prototype,n),r&&l(t,r),e}();w.normalizeTextCache={};var H=[{textBefore:!0,textAfter:!0},{textBefore:!1,textAfter:!0},{textBefore:!0,textAfter:!1},{textBefore:!1,textAfter:!1}],R=w,I={isDeserializationError:function(e){return e instanceof k}}}])}));
//# sourceMappingURL=web-marker.js.map