New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

text-annotator

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

text-annotator - npm Package Compare versions

Comparing version 0.7.2 to 0.7.3

143

build/text-annotator.js

@@ -14,2 +14,3 @@ "use strict";

const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
const blockElements = ['address', 'article', 'aside', 'blockquote', 'canvas', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'main', 'nav', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', 'tfoot', 'ul', 'video'];

@@ -138,4 +139,7 @@ class TextAnnotator {

for (let i = 0; i < highlightIndexes.length; i++) {
options.content = newContent;
newContent = this.highlight(highlightIndexes[i], options);
const newOptions = Object.assign({}, options);
delete newOptions.containerId;
newOptions.content = newContent;
newOptions.returnContent = true;
newContent = this.highlight(highlightIndexes[i], newOptions);
}

@@ -302,2 +306,3 @@

let sbThreshold = fuzzySearchOptions.sbThreshold || 0.85;
const maxLengthDiff = fuzzySearchOptions.maxLengthDiff || 0.1;
const lenRatio = fuzzySearchOptions.lenRatio || 2;

@@ -454,5 +459,5 @@ const processSentence = fuzzySearchOptions.processSentence;

const newSentenceRaw = sentence.raw + filteredSentences[i + 1].raw;
const lengthDiff = Math.abs(newSentenceRaw.length - str.length) / str.length; // whether allowing the customization of length diff threshold***
const lengthDiff = Math.abs(newSentenceRaw.length - str.length) / str.length;
if (lengthDiff <= 0.1) {
if (lengthDiff <= maxLengthDiff) {
const newSimilarity = TextAnnotator.getSimilarity(newSentenceRaw, str, caseSensitive);

@@ -485,74 +490,98 @@

return highlightIndex;
} // improve later***
} // further improvement when one annotation binds with more than one highlight***
// block elements are only used to check in the = condition for now
includeRequiredTag(i, highlightLoc, tag) {
const isCloseTag = tag.startsWith('</');
const tagType = isCloseTag ? tag.split('</')[1].split('>')[0] : tag.split(' ')[0].split('<')[1].split('>')[0];
let included = false;
let requiredTagNumber = 1;
let requiredTagCount = 0; // outer
if (isCloseTag) {
for (let i2 = i - 1; i2 >= 0; i2--) {
const tagLoc2 = this.tagLocations[i2];
if (highlightLoc[0] > tagLoc2[0]) {
break;
} else {
const tag2 = this.originalContent.substring(tagLoc2[0] + tagLoc2[2], tagLoc2[0] + tagLoc2[2] + tagLoc2[1]);
if (tag2.startsWith('</' + tagType)) {
requiredTagNumber++;
} else if (tag2.startsWith('<' + tagType)) {
requiredTagCount++;
}
if (requiredTagNumber === requiredTagCount) {
included = true;
break;
}
}
}
} else {
for (let i2 = i + 1; i2 < this.tagLocations.length; i2++) {
const tagLoc2 = this.tagLocations[i2];
if (highlightLoc[1] < tagLoc2[0]) {
break;
} else {
const tag2 = this.originalContent.substring(tagLoc2[0] + tagLoc2[2], tagLoc2[0] + tagLoc2[2] + tagLoc2[1]);
if (tag2.startsWith('<' + tagType)) {
requiredTagNumber++;
} else if (tag2.startsWith('</' + tagType)) {
requiredTagCount++;
}
if (requiredTagNumber === requiredTagCount) {
included = true;
break;
}
}
}
}
return included;
}
adjustLoc(highlightIdPattern, highlightIndex, highlightClass) {
const {
highlights
} = this;
const highlightLoc = highlights[highlightIndex].loc;
const highlightLoc = this.highlights[highlightIndex].loc;
const locInc = [0, 0]; // step 1: check locations of tags
const tagLocations = this.tagLocations;
const length = tagLocations.length;
const length = this.tagLocations.length;
for (let i = 0; i < length; i++) {
const tagLoc = tagLocations[i];
const tagLoc = this.tagLocations[i]; // start end tag
if (highlightLoc[1] < tagLoc[0]) {
break;
} else if (highlightLoc[1] === tagLoc[0]) {
const tag = this.originalContent.substring(tagLoc[0] + tagLoc[2], tagLoc[0] + tagLoc[2] + tagLoc[1]);
if (tag.startsWith('</')) {
locInc[1] += tagLoc[1];
}
} else if (highlightLoc[1] > tagLoc[0]) {
locInc[1] += tagLoc[1];
if (highlightLoc[0] === tagLoc[0]) {
} // start end&tag
else if (highlightLoc[1] === tagLoc[0]) {
const tag = this.originalContent.substring(tagLoc[0] + tagLoc[2], tagLoc[0] + tagLoc[2] + tagLoc[1]);
if (tag.startsWith('</')) {
locInc[0] += tagLoc[1];
} else {
let included = false;
let requiredCloseTagNumber = 1;
let closeTagCount = 0;
if (!tag.endsWith('/>') && tag.startsWith('</') && !blockElements.includes(tag.split('</')[1].split('>')[0]) && this.includeRequiredTag(i, highlightLoc, tag)) {
locInc[1] += tagLoc[1];
}
} // start tag end
else if (highlightLoc[1] > tagLoc[0]) {
locInc[1] += tagLoc[1]; // start&tag end
for (let i2 = i + 1; i2 < tagLocations.length; i2++) {
const tagLoc2 = tagLocations[i2];
if (highlightLoc[0] === tagLoc[0]) {
const tag = this.originalContent.substring(tagLoc[0] + tagLoc[2], tagLoc[0] + tagLoc[2] + tagLoc[1]);
if (highlightLoc[1] <= tagLoc2[0]) {
break;
} else {
const tag2 = this.originalContent.substring(tagLoc2[0] + tagLoc2[2], tagLoc2[0] + tagLoc2[2] + tagLoc2[1]);
const tagType = tag.split(' ')[0].split('<')[1].split('>')[0];
if (tag2.startsWith('<' + tagType)) {
requiredCloseTagNumber++;
} else if (tag2.startsWith('</' + tagType)) {
closeTagCount++;
}
if (requiredCloseTagNumber === closeTagCount) {
included = true;
break;
}
if (tag.startsWith('</') || tag.endsWith('/>') || blockElements.includes(tag.split(' ')[0].split('<')[1].split('>')[0]) || !this.includeRequiredTag(i, highlightLoc, tag)) {
locInc[0] += tagLoc[1];
}
}
if (!included) {
locInc[0] += tagLoc[1];
}
} // tag start end
else if (highlightLoc[0] > tagLoc[0]) {
locInc[0] += tagLoc[1];
}
}
} else if (highlightLoc[0] > tagLoc[0]) {
locInc[0] += tagLoc[1];
}
}
} // step 2: check locations of other highlights
for (let i = 0; i < highlights.length; i++) {
const highlight = highlights[i];
for (let i = 0; i < this.highlights.length; i++) {
const highlight = this.highlights[i];

@@ -559,0 +588,0 @@ if (highlight.highlighted) {

{
"name": "text-annotator",
"version": "0.7.2",
"version": "0.7.3",
"description": "A JavaScript library for locating and annotating plain text in HTML",

@@ -5,0 +5,0 @@ "main": "build/text-annotator.js",

@@ -1,1 +0,1 @@

var TextAnnotator=function(t){var e={};function n(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)n.d(i,s,function(e){return t[e]}.bind(null,s));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){t.exports=n(1).default},function(t,e,n){"use strict";n.r(e);let i=[];const s=["al","adj","assn","Ave","BSc","MSc","Cell","Ch","Co","cc","Corp","Dem","Dept","ed","eg","Eq","Eqs","est","est","etc","Ex","ext","Fig","fig","Figs","figs","i.e","ie","Inc","inc","Jan","Feb","Mar","Apr","Jun","Jul","Aug","Sep","Sept","Oct","Nov","Dec","jr","mi","Miss","Mrs","Mr","Ms","Mol","mt","mts","no","Nos","PhD","MD","BA","MA","MM","pl","pop","pp","Prof","Dr","pt","Ref","Refs","Rep","repr","rev","Sec","Secs","Sgt","Col","Gen","Rep","Sen","Gov","Lt","Maj","Capt","St","Sr","sr","Jr","jr","Rev","Sun","Mon","Tu","Tue","Tues","Wed","Th","Thu","Thur","Thurs","Fri","Sat","trans","Univ","Viz","Vol","vs","v"],r=t=>/^[A-Z][a-z].*/.test(t)||g(t),o=t=>r(t)||/``|"|'/.test(t.substring(0,2)),l=(t,e)=>{if("a.m."===t||"p.m."===t){if("day"===e.replace(/\W+/g,"").slice(-3).toLowerCase())return!0}return!1},c=t=>{const e=t.replace(/[()[\]{}]/g,"").match(/(.\.)*/);return e&&e[0].length>0},h=t=>t.length<=3||r(t),a=(t,e)=>{if(e.length>0){if(t<5&&e[0].length<6&&r(e[0]))return!0;return e.filter(t=>/[A-Z]/.test(t.charAt(0))).length>=3}return!1},g=(t,e)=>(e&&(t=t.slice(e-1,e+2)),!isNaN(t)),u=t=>t.match(/^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/),f=t=>t.match(/[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/),d=t=>{let e=0;if((e=t.indexOf("."))>-1||(e=t.indexOf("!"))>-1||(e=t.indexOf("?"))>-1){if(t.charAt(e+1).match(/[a-zA-Z].*/))return[t.slice(0,e+1),t.slice(e+1)]}return!1},p=(t,e)=>e.length>1?e.indexOf(t.slice(-1))>-1:t.slice(-1)===e,m=(t,e)=>t.slice(t.length-e.length)===e;function b(t,e){const n=" @~@ ".trim(),r=new RegExp("\\S",""),b=new RegExp("\\n+|[-#=_+*]{4,}","g"),T=new RegExp("\\S+|\\n","g");if(!t||"string"!=typeof t||!t.length)return[];if(!r.test(t))return[];const x={newline_boundaries:!1,html_boundaries:!1,html_boundaries_tags:["p","div","ul","ol"],sanitize:!1,allowed_tags:!1,preserve_whitespace:!1,abbreviations:null};if("boolean"==typeof e)x.newline_boundaries=!0;else for(let t in e)x[t]=e[t];var S;if(S=x.abbreviations,i=S||s,x.newline_boundaries&&(t=t.replace(b," @~@ ")),x.html_boundaries){const e="(<br\\s*\\/?>|<\\/("+x.html_boundaries_tags.join("|")+")>)",n=new RegExp(e,"g");t=t.replace(n,"$1 @~@ ")}let y,L;(x.sanitize||x.allowed_tags)&&(x.allowed_tags||(x.allowed_tags=[""]),t=(t=>{if(("string"==typeof t||t instanceof String)&&"undefined"!=typeof document){const e=document.createElement("DIV");e.innerHTML=t,t=(e.textContent||"").trim()}else"object"==typeof t&&t.textContent&&(t=(t.textContent||"").trim());return t})(t,x.allowed_tags)),x.preserve_whitespace?(L=t.split(/(<br\s*\/?>|\S+|\n+)/),y=L.filter((t,e)=>e%2)):y=t.trim().match(T);let M=0,w=0,v=[],C=[],O=[];if(!y||!y.length)return[];let _=0;for(let t=0,e=y.length;t<e;t++){if(M++,O.push(y[t]),~y[t].indexOf(",")&&(M=0),"."===(j=y[t])||"!"===j||"?"===j||p(y[t],"?!")||y[t]===n){(x.newline_boundaries||x.html_boundaries)&&y[t]===n&&O.pop(),C.push(O),M=0,O=[];continue}if((p(y[t],'"')||p(y[t],"”"))&&(y[t]=y[t].slice(0,-1),w=2*t+1),p(y[t],".")){if(t+1<e){if(2===y[t].length&&isNaN(y[t].charAt(0)))continue;if(H=y[t],~i.indexOf(H.replace(/\W+/g,"")))continue;if(o(y[t+1])){if(l(y[t],y[t+1]))continue;if(a(M,y.slice(t,6)))continue;if(g(y[t+1])&&h(y[t]))continue}else{if(m(y[t],".."))continue;if(c(y[t]))continue;if(a(M,y.slice(t,5)))continue}}C.push(O),O=[],M=0;continue}if((w=y[t].indexOf("."))>-1){if(g(y[t],w))continue;if(c(y[t]))continue;if(f(y[t])||u(y[t]))continue}const s=d(y[t]);s&&(v=s,O.pop(),O.push(v[0]),C.push(O),x.preserve_whitespace&&(L.splice(2*t+1+_,1,v[0],"",v[1]),_+=2),O=[],M=0,O.push(v[1]))}var H,j;O.length&&C.push(O);const A=[];let E="";C=C.filter((function(t){return t.length>0}));for(let t=0;t<C.length;t++){if(!x.preserve_whitespace||x.newline_boundaries||x.html_boundaries)E=C[t].join(" ");else{let e=2*C[t].length;0===t&&(e+=1),E=L.splice(0,e).join("")}1===C[t].length&&C[t][0].length<4&&C[t][0].indexOf(".")>-1&&C[t+1]&&C[t+1][0].indexOf(".")<0&&(E+=" "+C[t+1].join(" "),t++),A.push(E)}return A}const T="undefined"!=typeof window&&void 0!==window.document;class x{constructor(t={}){const e=t.containerId,n=t.content,i=void 0===t.isHTML||t.isHTML;this.originalContent=T&&e?document.getElementById(e).innerHTML:n,this.isHTML=i,this.stripedHTML="",this.tagLocations=[],this.sentences=[],this.highlights=[],i&&this.stripAndStoreHTMLTags()}search(t,e={},n){let i=e.prefix||"",s=e.postfix||"";const r=e.directSearchOptions,o=e.fuzzySearchOptions,l=e.eagerSearchOptions;if(void 0===e.trim||e.trim){const e=x.trim(i,t,s);i=e.prefix,t=e.str,s=e.postfix}let c=-1;return c=this.directSearch(i,t,s,r,n),-1!==c||o&&(c=this.fuzzySearch(i,t,s,o),-1!==c)||T&&l&&(c=this.eagerSearch(i,t,s,l)),c}searchAll(t,e={}){const n=[],i=(t,e,s)=>{const r=this.search(t,e,s);-1!==r&&(n.push(r),i(t,e,r))};return i(t,e),n}highlight(t,e={}){const n=e.containerId;let i=e.content;const s=e.highlightClass||"highlight",r=e.highlightIdPattern||"highlight-",o=e.returnContent;T&&n&&(i=document.getElementById(n).innerHTML);const l=x.createOpenTag(r,t,s),c=this.adjustLoc(r,t,s);let h=x.insert(i,l,c[0]);if(h=x.insert(h,x.createCloseTag(),c[1]+l.length),this.highlights[t].highlighted=!0,!T||!n||o)return h;document.getElementById(n).innerHTML=h}highlightAll(t,e={}){const{containerId:n,content:i,returnContent:s}=e;let r=T&&n?document.getElementById(n).innerHTML:i;if(t.forEach(t=>{e.content=r,r=this.highlight(t,e)}),!T||!n||s)return r}searchAndHighlight(t,e){const n=this.search(t,e.searchOptions);if(-1!==n)return{highlightIndex:n,content:this.highlight(n,e.highlightOptions)}}unhighlight(t,e={}){const n=e.byStringOperation,i=e.containerId;let s=e.content;const r=e.highlightClass||"highlight",o=e.highlightIdPattern||"highlight-",l=e.returnContent;if(this.highlights[t].highlighted=!1,n){T&&i&&(s=document.getElementById(i).innerHTML);let e=s;const n=this.adjustLoc(o,t,r),c=x.getOpenTagLength(o,t,r),h=e.substring(n[0],n[1]+c+x.getCloseTagLength()),a=e.substring(n[0]+c,n[1]+c);if(e=e.replace(h,a),l)return e;document.getElementById(i).innerHTML=e}else if(T){const e=o+t;if(document.getElementById(e).outerHTML=document.getElementById(e).innerHTML,l)return document.getElementById(i).innerHTML}}stripAndStoreHTMLTags(){let t;this.stripedHTML=this.originalContent;const e=/<[^>]+>/;let n=0;for(;t=this.stripedHTML.match(e);){this.stripedHTML=this.stripedHTML.replace(t,"");const e=t[0].length;this.tagLocations.push([t.index,e,n]),n+=e}}directSearch(t,e,n,i={},s){const r=void 0===i.caseSensitive||i.caseSensitive;let o=t+e+n,l=this.isHTML?this.stripedHTML:this.originalContent;r||(o=o.toLowerCase(),l=l.toLowerCase());let c=0;void 0!==s&&(c=this.highlights[s].loc[1]+1);let h=-1;const a=l.indexOf(o,c);if(-1!==a){const n=[];n[0]=a+t.length,n[1]=n[0]+e.length,h=this.highlights.push({loc:n})-1}return h}eagerSearch(t,e,n,i={}){const s=i.caseSensitive,r=i.containerId,o=i.threshold||.74,l=t+e+n;let c=-1;if(window.find){document.designMode="on";const t=window.getSelection();for(t.collapse(document.body,0);window.find(l,s);){document.execCommand("hiliteColor",!0,"rgba(255, 255, 255, 0)"),t.collapseToEnd();const n=document.querySelector("#"+r+' [style="background-color: rgba(255, 255, 255, 0);"]');if(n){const t=n.innerHTML.replace(/<[^>]*>/g,""),i=x.getBestSubstring(t,e,o);if(i.similarity){const e=(this.isHTML?this.stripedHTML:this.originalContent).indexOf(t);-1!==e&&(c=this.highlights.push({loc:[e+i.loc[0],e+i.loc[1]]})-1)}break}}document.execCommand("undo"),document.designMode="off"}return c}fuzzySearch(t,e,n,i={}){const s=i.caseSensitive;let r=i.tbThreshold||.68;const o=i.tokenBased;let l=i.sbThreshold||.85;const c=i.lenRatio||1.2,h=i.processSentence,a=void 0===i.sentenceBased||i.sentenceBased;let g=-1;const u=this.isHTML?this.stripedHTML:this.originalContent;if(o||t||n){const i=[];let o=-1;for(;-1!==(o=u.indexOf(e,o+1));)i.push(o);let l=-1;const c=t+e+n;for(const o of i){const i=u.substring(o-t.length,o)+e+u.substring(o+e.length,o+e.length+n.length),h=x.getSimilarity(i,c,s);h>=r&&(r=h,l=o)}-1!==l&&(g=this.highlights.push({loc:[l,l+e.length]})-1)}else if(a){let t=[];t=this.sentences.length?this.sentences:this.sentences=x.sentenize(u);const n=e.split(/\s/),i=[];for(const e of t)for(const t of n)if(e.raw.includes(t)){i.push(e);break}if(h){const t=this.tagLocations,e=t.length;if(e){let n=0;for(const s of i){let i=s.raw;const r=[s.index,s.index+i.length];let o=0;for(let s=n;s<e;s++){const e=t[s];if(e[0]>=r[0]&&e[0]<=r[1]){const t=this.originalContent.substring(e[0]+e[2],e[0]+e[2]+e[1]),n=e[0]+o-r[0];i=i.slice(0,n)+t+i.slice(n),o+=e[1]}else if(e[0]>r[1]){n=s-1;break}}i=h(i),i=i.replace(/(<([^>]+)>)/gi,"");const l=s.raw;l!==i&&(s.raw=i,s.index=s.index+l.indexOf(i))}}}let r=null,o=null;if(i.forEach((t,n)=>{let h=x.getBestSubstring(t.raw,e,l,c,s);h.similarity?(l=h.similarity,r=h,o=t):n!==i.length-1&&(h=x.getBestSubstring(t.raw+i[n+1].raw,e,l,c,s),h.similarity&&(l=h.similarity,r=h,o=i[n]))}),r){let t=o.index;g=this.highlights.push({loc:[t+r.loc[0],t+r.loc[1]]})-1}}return g}adjustLoc(t,e,n){const i=this.highlights[e].loc,s=[0,0],r=this.tagLocations,o=r.length;for(let t=0;t<o;t++){const e=r[t];if(i[1]<e[0])break;if(i[1]===e[0]){this.originalContent.substring(e[0]+e[2],e[0]+e[2]+e[1]).startsWith("</")&&(s[1]+=e[1])}else if(i[1]>e[0])if(s[1]+=e[1],i[0]===e[0]){const n=this.originalContent.substring(e[0]+e[2],e[0]+e[2]+e[1]);if(n.startsWith("</"))s[0]+=e[1];else{let o=!1,l=1,c=0;for(let e=t+1;e<r.length;e++){const t=r[e];if(i[1]<=t[0])break;{const e=this.originalContent.substring(t[0]+t[2],t[0]+t[2]+t[1]),i=n.split(" ")[0].split("<")[1].split(">")[0];if(e.startsWith("<"+i)?l++:e.startsWith("</"+i)&&c++,l===c){o=!0;break}}}o||(s[0]+=e[1])}}else i[0]>e[0]&&(s[0]+=e[1])}return this.highlights.forEach((e,r)=>{if(e.highlighted){const o=x.getOpenTagLength(t,r,n),l=x.getCloseTagLength(),c=e.loc;i[0]>=c[1]?(s[0]+=o+l,s[1]+=o+l):i[0]<c[1]&&i[0]>c[0]&&i[1]>c[1]?(s[0]+=o,s[1]+=o+l):i[0]<=c[0]&&i[1]>=c[1]?s[1]+=o+l:i[0]<c[0]&&i[1]>c[0]&&i[1]<c[1]?s[1]+=o:i[0]>=c[0]&&i[1]<=c[1]&&(s[0]+=o,s[1]+=o)}}),[i[0]+s[0],i[1]+s[1]]}static createOpenTag(t,e,n){return`<span id="${t+e}" class="${n}">`}static createCloseTag(){return"</span>"}static getOpenTagLength(t,e,n){return x.createOpenTag(t,e,n).length}static getCloseTagLength(){return x.createCloseTag().length}static trim(t,e,n){return t=t.replace(/^\s+/,""),n=n.replace(/\s+$/,""),t||(e=e.replace(/^\s+/,"")),n||(e=e.replace(/\s+$/,"")),{prefix:t,str:e,postfix:n}}static insert(t,e,n){return t.slice(0,n)+e+t.slice(n)}static sentenize(t){return b(t,{newline_boundaries:!1,html_boundaries:!1,sanitize:!1,allowed_tags:!1,preserve_whitespace:!0,abbreviations:null}).map(e=>({raw:e,index:t.indexOf(e)}))}static getBestSubstring(t,e,n,i,s){let r={},o=x.getSimilarity(t,e,s);if(o>=n){const n=t.split(" ");for(;n.length;){const t=n.shift(),i=n.join(" ");let r=x.getSimilarity(i,e,s);if(r<o){n.unshift(t);const i=n.pop();if(r=x.getSimilarity(n.join(" "),e,s),r<o){n.push(i);break}o=r}else o=r}const l=n.join(" ");if(!i||l.length/e.length<=i){const e=[];e[0]=t.indexOf(l),e[1]=e[0]+l.length,r={similarity:o,loc:e}}}return r}static getSimilarity(t,e,n){return n||(t=t.toLowerCase(),e=e.toLowerCase()),t===e?1:x.lcsLength(t,e)/e.length}static lcsLength(t,e){const n=t.length,i=e.length,s=t.split(""),r=e.split(""),o=Array(n+1).fill(Array(i+1).fill(0));for(let t=1;t<=n;t++)for(let e=1;e<=i;e++)o[t][e]=s[t-1]===r[e-1]?o[t-1][e-1]+1:Math.max(o[t][e-1],o[t-1][e]);return o[n][i]}}e.default=x}]);
var TextAnnotator=function(t){var e={};function n(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)n.d(i,s,function(e){return t[e]}.bind(null,s));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){t.exports=n(1).default},function(t,e,n){"use strict";n.r(e);let i=[];const s=["al","adj","assn","Ave","BSc","MSc","Cell","Ch","Co","cc","Corp","Dem","Dept","ed","eg","Eq","Eqs","est","est","etc","Ex","ext","Fig","fig","Figs","figs","i.e","ie","Inc","inc","Jan","Feb","Mar","Apr","Jun","Jul","Aug","Sep","Sept","Oct","Nov","Dec","jr","mi","Miss","Mrs","Mr","Ms","Mol","mt","mts","no","Nos","PhD","MD","BA","MA","MM","pl","pop","pp","Prof","Dr","pt","Ref","Refs","Rep","repr","rev","Sec","Secs","Sgt","Col","Gen","Rep","Sen","Gov","Lt","Maj","Capt","St","Sr","sr","Jr","jr","Rev","Sun","Mon","Tu","Tue","Tues","Wed","Th","Thu","Thur","Thurs","Fri","Sat","trans","Univ","Viz","Vol","vs","v"],r=t=>/^[A-Z][a-z].*/.test(t)||g(t),o=t=>r(t)||/``|"|'/.test(t.substring(0,2)),l=(t,e)=>{if("a.m."===t||"p.m."===t){if("day"===e.replace(/\W+/g,"").slice(-3).toLowerCase())return!0}return!1},h=t=>{const e=t.replace(/[()[\]{}]/g,"").match(/(.\.)*/);return e&&e[0].length>0},c=t=>t.length<=3||r(t),a=(t,e)=>{if(e.length>0){if(t<5&&e[0].length<6&&r(e[0]))return!0;return e.filter(t=>/[A-Z]/.test(t.charAt(0))).length>=3}return!1},g=(t,e)=>(e&&(t=t.slice(e-1,e+2)),!isNaN(t)),u=t=>t.match(/^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/),d=t=>t.match(/[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/),f=t=>{let e=0;if((e=t.indexOf("."))>-1||(e=t.indexOf("!"))>-1||(e=t.indexOf("?"))>-1){if(t.charAt(e+1).match(/[a-zA-Z].*/))return[t.slice(0,e+1),t.slice(e+1)]}return!1},p=(t,e)=>e.length>1?e.indexOf(t.slice(-1))>-1:t.slice(-1)===e,m=(t,e)=>t.slice(t.length-e.length)===e;function b(t,e){const n=" @~@ ".trim(),r=new RegExp("\\S",""),b=new RegExp("\\n+|[-#=_+*]{4,}","g"),T=new RegExp("\\S+|\\n","g");if(!t||"string"!=typeof t||!t.length)return[];if(!r.test(t))return[];const L={newline_boundaries:!1,html_boundaries:!1,html_boundaries_tags:["p","div","ul","ol"],sanitize:!1,allowed_tags:!1,preserve_whitespace:!1,abbreviations:null};if("boolean"==typeof e)L.newline_boundaries=!0;else for(let t in e)L[t]=e[t];var x;if(x=L.abbreviations,i=x||s,L.newline_boundaries&&(t=t.replace(b," @~@ ")),L.html_boundaries){const e="(<br\\s*\\/?>|<\\/("+L.html_boundaries_tags.join("|")+")>)",n=new RegExp(e,"g");t=t.replace(n,"$1 @~@ ")}let M,w;(L.sanitize||L.allowed_tags)&&(L.allowed_tags||(L.allowed_tags=[""]),t=(t=>{if(("string"==typeof t||t instanceof String)&&"undefined"!=typeof document){const e=document.createElement("DIV");e.innerHTML=t,t=(e.textContent||"").trim()}else"object"==typeof t&&t.textContent&&(t=(t.textContent||"").trim());return t})(t,L.allowed_tags)),L.preserve_whitespace?(w=t.split(/(<br\s*\/?>|\S+|\n+)/),M=w.filter((t,e)=>e%2)):M=t.trim().match(T);let S=0,y=0,v=[],C=[],O=[];if(!M||!M.length)return[];let _=0;for(let t=0,e=M.length;t<e;t++){if(S++,O.push(M[t]),~M[t].indexOf(",")&&(S=0),"."===(j=M[t])||"!"===j||"?"===j||p(M[t],"?!")||M[t]===n){(L.newline_boundaries||L.html_boundaries)&&M[t]===n&&O.pop(),C.push(O),S=0,O=[];continue}if((p(M[t],'"')||p(M[t],"”"))&&(M[t]=M[t].slice(0,-1),y=2*t+1),p(M[t],".")){if(t+1<e){if(2===M[t].length&&isNaN(M[t].charAt(0)))continue;if(H=M[t],~i.indexOf(H.replace(/\W+/g,"")))continue;if(o(M[t+1])){if(l(M[t],M[t+1]))continue;if(a(S,M.slice(t,6)))continue;if(g(M[t+1])&&c(M[t]))continue}else{if(m(M[t],".."))continue;if(h(M[t]))continue;if(a(S,M.slice(t,5)))continue}}C.push(O),O=[],S=0;continue}if((y=M[t].indexOf("."))>-1){if(g(M[t],y))continue;if(h(M[t]))continue;if(d(M[t])||u(M[t]))continue}const s=f(M[t]);s&&(v=s,O.pop(),O.push(v[0]),C.push(O),L.preserve_whitespace&&(w.splice(2*t+1+_,1,v[0],"",v[1]),_+=2),O=[],S=0,O.push(v[1]))}var H,j;O.length&&C.push(O);const I=[];let A="";C=C.filter((function(t){return t.length>0}));for(let t=0;t<C.length;t++){if(!L.preserve_whitespace||L.newline_boundaries||L.html_boundaries)A=C[t].join(" ");else{let e=2*C[t].length;0===t&&(e+=1),A=w.splice(0,e).join("")}1===C[t].length&&C[t][0].length<4&&C[t][0].indexOf(".")>-1&&C[t+1]&&C[t+1][0].indexOf(".")<0&&(A+=" "+C[t+1].join(" "),t++),I.push(A)}return I}const T="undefined"!=typeof window&&void 0!==window.document,L=["address","article","aside","blockquote","canvas","dd","div","dl","dt","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","li","main","nav","noscript","ol","output","p","pre","section","table","tfoot","ul","video"];class x{constructor(t={}){const e=t.containerId,n=t.content,i=void 0===t.isHTML||t.isHTML;this.originalContent=T&&e?document.getElementById(e).innerHTML:n,this.isHTML=i,this.stripedHTML="",this.tagLocations=[],this.sentences=[],this.highlights=[],i&&this.stripAndStoreHTMLTags()}search(t,e={},n){let i=e.prefix||"",s=e.postfix||"";const r=e.directSearchOptions,o=e.fuzzySearchOptions,l=e.eagerSearchOptions;if(void 0===e.trim||e.trim){const e=x.trim(i,t,s);i=e.prefix,t=e.str,s=e.postfix}let h=-1;return h=this.directSearch(i,t,s,r,n),-1!==h||o&&(h=this.fuzzySearch(i,t,s,o),-1!==h)||T&&l&&(h=this.eagerSearch(i,t,s,l)),h}searchAll(t,e={}){const n=[],i=(t,e,s)=>{const r=this.search(t,e,s);-1!==r&&(n.push(r),i(t,e,r))};return i(t,e),n}highlight(t,e={}){const n=e.containerId;let i=e.content;const s=e.highlightClass||"highlight",r=e.highlightIdPattern||"highlight-",o=e.returnContent;T&&n&&(i=document.getElementById(n).innerHTML);const l=x.createOpenTag(r,t,s),h=this.adjustLoc(r,t,s);let c=x.insert(i,l,h[0]);if(c=x.insert(c,x.createCloseTag(),h[1]+l.length),this.highlights[t].highlighted=!0,!T||!n||o)return c;document.getElementById(n).innerHTML=c}highlightAll(t,e={}){const{containerId:n,content:i,returnContent:s}=e;let r=T&&n?document.getElementById(n).innerHTML:i;for(let n=0;n<t.length;n++){const i=Object.assign({},e);delete i.containerId,i.content=r,i.returnContent=!0,r=this.highlight(t[n],i)}if(!T||!n||s)return r;document.getElementById(n).innerHTML=r}searchAndHighlight(t,e){const n=this.search(t,e.searchOptions);if(-1!==n)return{highlightIndex:n,content:this.highlight(n,e.highlightOptions)}}unhighlight(t,e={}){const n=e.byStringOperation,i=e.containerId;let s=e.content;const r=e.highlightClass||"highlight",o=e.highlightIdPattern||"highlight-",l=e.returnContent;if(this.highlights[t].highlighted=!1,n){T&&i&&(s=document.getElementById(i).innerHTML);let e=s;const n=this.adjustLoc(o,t,r),h=x.getOpenTagLength(o,t,r),c=e.substring(n[0],n[1]+h+x.getCloseTagLength()),a=e.substring(n[0]+h,n[1]+h);if(e=e.replace(c,a),l)return e;document.getElementById(i).innerHTML=e}else if(T){const e=o+t;if(document.getElementById(e).outerHTML=document.getElementById(e).innerHTML,l)return document.getElementById(i).innerHTML}}stripAndStoreHTMLTags(){let t;this.stripedHTML=this.originalContent;const e=/<[^>]+>/;let n=0;for(;t=this.stripedHTML.match(e);){this.stripedHTML=this.stripedHTML.replace(t,"");const e=t[0].length;this.tagLocations.push([t.index,e,n]),n+=e}}directSearch(t,e,n,i={},s){const r=i.caseSensitive;let o=t+e+n,l=this.isHTML?this.stripedHTML:this.originalContent;r||(o=o.toLowerCase(),l=l.toLowerCase());let h=0;void 0!==s&&(h=this.highlights[s].loc[1]+1);let c=-1;const a=l.indexOf(o,h);if(-1!==a){const n=[];n[0]=a+t.length,n[1]=n[0]+e.length,c=this.highlights.push({loc:n})-1}return c}eagerSearch(t,e,n,i={}){const s=i.caseSensitive,r=i.containerId,o=i.threshold||.74,l=t+e+n;let h=-1;if(window.find){document.designMode="on";const t=window.getSelection();for(t.collapse(document.body,0);window.find(l,s);){document.execCommand("hiliteColor",!0,"rgba(255, 255, 255, 0)"),t.collapseToEnd();const n=document.querySelector("#"+r+' [style="background-color: rgba(255, 255, 255, 0);"]');if(n){const t=n.innerHTML.replace(/<[^>]*>/g,""),i=x.getBestSubstring(t,e,o);if(i.similarity){const e=(this.isHTML?this.stripedHTML:this.originalContent).indexOf(t);-1!==e&&(h=this.highlights.push({loc:[e+i.loc[0],e+i.loc[1]]})-1)}break}}document.execCommand("undo"),document.designMode="off"}return h}fuzzySearch(t,e,n,i={}){const s=i.caseSensitive,r=i.tokenBased;let o=i.tbThreshold||.68;const l=void 0===i.sentenceBased||i.sentenceBased;let h=i.sbThreshold||.85;const c=i.maxLengthDiff||.1,a=i.lenRatio||2,g=i.processSentence;let u=-1;const d=this.isHTML?this.stripedHTML:this.originalContent;if(r||t||n){const i=[];let r=-1;for(;-1!==(r=d.indexOf(e,r+1));)i.push(r);let l=-1;const h=t+e+n;for(let r=0;r<i.length;r++){const c=i[r],a=d.substring(c-t.length,c)+e+d.substring(c+e.length,c+e.length+n.length),g=x.getSimilarity(a,h,s);g>=o&&(o=g,l=c)}-1!==l&&(u=this.highlights.push({loc:[l,l+e.length]})-1)}else if(l){let t=[];t=this.sentences.length?this.sentences:this.sentences=x.sentenize(d);const n=e.split(/\s/),i=[];for(let e=0;e<t.length;e++)for(let s=0;s<n.length;s++)if(t[e].raw.includes(n[s])){i.push(t[e]);break}if(g){let t=0;for(let e=0;e<i.length;e++){const n=i[e];let s=n.raw;const r=[n.index,n.index+s.length];let o=0;const l=this.tagLocations;for(let e=t;e<l.length;e++){const n=l[e];if(n[0]>=r[0]&&n[0]<=r[1]){const t=this.originalContent.substring(n[0]+n[2],n[0]+n[2]+n[1]),e=n[0]+o-r[0];s=s.slice(0,e)+t+s.slice(e),o+=n[1]}else if(n[0]>r[1]){t=e;break}}s=g(s),s=s.replace(/(<([^>]+)>)/gi,"");const h=n.raw;h!==s&&(n.raw=s,n.index=n.index+h.indexOf(s))}}let r=null;for(let t=0;t<i.length;t++){const n=i[t],o=x.getSimilarity(n.raw,e,s);if(o>=h)h=o,r=n;else if(t!==i.length-1){const o=n.raw+i[t+1].raw;if(Math.abs(o.length-e.length)/e.length<=c){const t=x.getSimilarity(o,e,s);t>=h&&(h=t,r={raw:o,index:n.index})}}}if(r){const t=x.getBestSubstring(r.raw,e,h,a,s,!0);if(t.loc){let e=r.index;u=this.highlights.push({loc:[e+t.loc[0],e+t.loc[1]]})-1}}}return u}includeRequiredTag(t,e,n){const i=n.startsWith("</"),s=i?n.split("</")[1].split(">")[0]:n.split(" ")[0].split("<")[1].split(">")[0];let r=!1,o=1,l=0;if(i)for(let n=t-1;n>=0;n--){const t=this.tagLocations[n];if(e[0]>t[0])break;{const e=this.originalContent.substring(t[0]+t[2],t[0]+t[2]+t[1]);if(e.startsWith("</"+s)?o++:e.startsWith("<"+s)&&l++,o===l){r=!0;break}}}else for(let n=t+1;n<this.tagLocations.length;n++){const t=this.tagLocations[n];if(e[1]<t[0])break;{const e=this.originalContent.substring(t[0]+t[2],t[0]+t[2]+t[1]);if(e.startsWith("<"+s)?o++:e.startsWith("</"+s)&&l++,o===l){r=!0;break}}}return r}adjustLoc(t,e,n){const i=this.highlights[e].loc,s=[0,0],r=this.tagLocations.length;for(let t=0;t<r;t++){const e=this.tagLocations[t];if(i[1]<e[0])break;if(i[1]===e[0]){const n=this.originalContent.substring(e[0]+e[2],e[0]+e[2]+e[1]);!n.endsWith("/>")&&n.startsWith("</")&&!L.includes(n.split("</")[1].split(">")[0])&&this.includeRequiredTag(t,i,n)&&(s[1]+=e[1])}else if(i[1]>e[0])if(s[1]+=e[1],i[0]===e[0]){const n=this.originalContent.substring(e[0]+e[2],e[0]+e[2]+e[1]);(n.startsWith("</")||n.endsWith("/>")||L.includes(n.split(" ")[0].split("<")[1].split(">")[0])||!this.includeRequiredTag(t,i,n))&&(s[0]+=e[1])}else i[0]>e[0]&&(s[0]+=e[1])}for(let e=0;e<this.highlights.length;e++){const r=this.highlights[e];if(r.highlighted){const o=x.getOpenTagLength(t,e,n),l=x.getCloseTagLength(),h=r.loc;i[0]>=h[1]?(s[0]+=o+l,s[1]+=o+l):i[0]<h[1]&&i[0]>h[0]&&i[1]>h[1]?(s[0]+=o,s[1]+=o+l):i[0]<=h[0]&&i[1]>=h[1]?s[1]+=o+l:i[0]<h[0]&&i[1]>h[0]&&i[1]<h[1]?s[1]+=o:i[0]>=h[0]&&i[1]<=h[1]&&(s[0]+=o,s[1]+=o)}}return[i[0]+s[0],i[1]+s[1]]}static createOpenTag(t,e,n){return`<span id="${t+e}" class="${n}">`}static createCloseTag(){return"</span>"}static getOpenTagLength(t,e,n){return x.createOpenTag(t,e,n).length}static getCloseTagLength(){return x.createCloseTag().length}static trim(t,e,n){return t=t.replace(/^\s+/,""),n=n.replace(/\s+$/,""),t||(e=e.replace(/^\s+/,"")),n||(e=e.replace(/\s+$/,"")),{prefix:t,str:e,postfix:n}}static insert(t,e,n){return t.slice(0,n)+e+t.slice(n)}static sentenize(t){return b(t,{newline_boundaries:!1,html_boundaries:!1,sanitize:!1,allowed_tags:!1,preserve_whitespace:!0,abbreviations:null}).map(e=>({raw:e,index:t.indexOf(e)}))}static getBestSubstring(t,e,n,i,s,r){let o={},l=r?n:x.getSimilarity(t,e,s);if(l>=n){const n=t.split(" ");for(;n.length;){const t=n.shift(),i=n.join(" ");let r=x.getSimilarity(i,e,s);if(r<l){n.unshift(t);const i=n.pop();if(r=x.getSimilarity(n.join(" "),e,s),r<l){n.push(i);break}l=r}else l=r}const r=n.join(" ");if(!i||r.length/e.length<=i){const e=[];e[0]=t.indexOf(r),e[1]=e[0]+r.length,o={similarity:l,loc:e}}}return o}static getSimilarity(t,e,n){return n||(t=t.toLowerCase(),e=e.toLowerCase()),t===e?1:x.lcsLength(t,e)/e.length}static lcsLength(t,e,n){var i=n?t:t.toLowerCase(),s=n?e:e.toLowerCase();if(i===s)return i;if(""===(i||s))return"";var r,o,l=i.length,h=s.length,c=function(t){for(var e=[],n=0;n<t;n++)e[n]=[];return e}(h+1);for(r=0;r<=l;r++)c[0][r]=0;for(r=0;r<=h;r++)c[r][0]=0;for(r=1;r<=h;r++)for(o=1;o<=l;o++)i[o-1]===s[r-1]?c[r][o]=c[r-1][o-1]+1:c[r][o]=Math.max(c[r-1][o],c[r][o-1]);var a="";for(r=h,o=l;r>0&&o>0;)i[o-1]===s[r-1]?(a=i[o-1]+a,r--,o--):Math.max(c[r-1][o],c[r][o-1])===c[r-1][o]?r--:o--;return a.length}}e.default=x}]);

@@ -7,2 +7,41 @@ import getSentences from './ext/sbd'

const blockElements = [
'address',
'article',
'aside',
'blockquote',
'canvas',
'dd',
'div',
'dl',
'dt',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'header',
'hgroup',
'hr',
'li',
'main',
'nav',
'noscript',
'ol',
'output',
'p',
'pre',
'section',
'table',
'tfoot',
'ul',
'video'
]
class TextAnnotator {

@@ -160,4 +199,7 @@ constructor(options = {}) {

for (let i = 0; i < highlightIndexes.length; i++) {
options.content = newContent
newContent = this.highlight(highlightIndexes[i], options)
const newOptions = Object.assign({}, options)
delete newOptions.containerId
newOptions.content = newContent
newOptions.returnContent = true
newContent = this.highlight(highlightIndexes[i], newOptions)
}

@@ -350,2 +392,3 @@

let sbThreshold = fuzzySearchOptions.sbThreshold || 0.85
const maxLengthDiff = fuzzySearchOptions.maxLengthDiff || 0.1
const lenRatio = fuzzySearchOptions.lenRatio || 2

@@ -513,4 +556,3 @@ const processSentence = fuzzySearchOptions.processSentence

Math.abs(newSentenceRaw.length - str.length) / str.length
// whether allowing the customization of length diff threshold***
if (lengthDiff <= 0.1) {
if (lengthDiff <= maxLengthDiff) {
const newSimilarity = TextAnnotator.getSimilarity(

@@ -554,16 +596,79 @@ newSentenceRaw,

// improve later***
// further improvement when one annotation binds with more than one highlight***
// block elements are only used to check in the = condition for now
includeRequiredTag(i, highlightLoc, tag) {
const isCloseTag = tag.startsWith('</')
const tagType = isCloseTag
? tag.split('</')[1].split('>')[0]
: tag
.split(' ')[0]
.split('<')[1]
.split('>')[0]
let included = false
let requiredTagNumber = 1
let requiredTagCount = 0
// outer
if (isCloseTag) {
for (let i2 = i - 1; i2 >= 0; i2--) {
const tagLoc2 = this.tagLocations[i2]
if (highlightLoc[0] > tagLoc2[0]) {
break
} else {
const tag2 = this.originalContent.substring(
tagLoc2[0] + tagLoc2[2],
tagLoc2[0] + tagLoc2[2] + tagLoc2[1]
)
if (tag2.startsWith('</' + tagType)) {
requiredTagNumber++
} else if (tag2.startsWith('<' + tagType)) {
requiredTagCount++
}
if (requiredTagNumber === requiredTagCount) {
included = true
break
}
}
}
} else {
for (let i2 = i + 1; i2 < this.tagLocations.length; i2++) {
const tagLoc2 = this.tagLocations[i2]
if (highlightLoc[1] < tagLoc2[0]) {
break
} else {
const tag2 = this.originalContent.substring(
tagLoc2[0] + tagLoc2[2],
tagLoc2[0] + tagLoc2[2] + tagLoc2[1]
)
if (tag2.startsWith('<' + tagType)) {
requiredTagNumber++
} else if (tag2.startsWith('</' + tagType)) {
requiredTagCount++
}
if (requiredTagNumber === requiredTagCount) {
included = true
break
}
}
}
}
return included
}
adjustLoc(highlightIdPattern, highlightIndex, highlightClass) {
const { highlights } = this
const highlightLoc = highlights[highlightIndex].loc
const highlightLoc = this.highlights[highlightIndex].loc
const locInc = [0, 0]
// step 1: check locations of tags
const tagLocations = this.tagLocations
const length = tagLocations.length
const length = this.tagLocations.length
for (let i = 0; i < length; i++) {
const tagLoc = tagLocations[i]
const tagLoc = this.tagLocations[i]
// start end tag
if (highlightLoc[1] < tagLoc[0]) {
break
} else if (highlightLoc[1] === tagLoc[0]) {
}
// start end&tag
else if (highlightLoc[1] === tagLoc[0]) {
const tag = this.originalContent.substring(

@@ -573,7 +678,15 @@ tagLoc[0] + tagLoc[2],

)
if (tag.startsWith('</')) {
if (
!tag.endsWith('/>') &&
tag.startsWith('</') &&
!blockElements.includes(tag.split('</')[1].split('>')[0]) &&
this.includeRequiredTag(i, highlightLoc, tag)
) {
locInc[1] += tagLoc[1]
}
} else if (highlightLoc[1] > tagLoc[0]) {
}
// start tag end
else if (highlightLoc[1] > tagLoc[0]) {
locInc[1] += tagLoc[1]
// start&tag end
if (highlightLoc[0] === tagLoc[0]) {

@@ -584,39 +697,18 @@ const tag = this.originalContent.substring(

)
if (tag.startsWith('</')) {
if (
tag.startsWith('</') ||
tag.endsWith('/>') ||
blockElements.includes(
tag
.split(' ')[0]
.split('<')[1]
.split('>')[0]
) ||
!this.includeRequiredTag(i, highlightLoc, tag)
) {
locInc[0] += tagLoc[1]
} else {
let included = false
let requiredCloseTagNumber = 1
let closeTagCount = 0
for (let i2 = i + 1; i2 < tagLocations.length; i2++) {
const tagLoc2 = tagLocations[i2]
if (highlightLoc[1] <= tagLoc2[0]) {
break
} else {
const tag2 = this.originalContent.substring(
tagLoc2[0] + tagLoc2[2],
tagLoc2[0] + tagLoc2[2] + tagLoc2[1]
)
const tagType = tag
.split(' ')[0]
.split('<')[1]
.split('>')[0]
if (tag2.startsWith('<' + tagType)) {
requiredCloseTagNumber++
} else if (tag2.startsWith('</' + tagType)) {
closeTagCount++
}
if (requiredCloseTagNumber === closeTagCount) {
included = true
break
}
}
}
if (!included) {
locInc[0] += tagLoc[1]
}
}
} else if (highlightLoc[0] > tagLoc[0]) {
}
// tag start end
else if (highlightLoc[0] > tagLoc[0]) {
locInc[0] += tagLoc[1]

@@ -628,4 +720,4 @@ }

// step 2: check locations of other highlights
for (let i = 0; i < highlights.length; i++) {
const highlight = highlights[i]
for (let i = 0; i < this.highlights.length; i++) {
const highlight = this.highlights[i]
if (highlight.highlighted) {

@@ -632,0 +724,0 @@ const openTagLength = TextAnnotator.getOpenTagLength(

@@ -11,102 +11,136 @@ import TextAnnotator from '../src/text-annotator'

test('test direct search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('I')
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"${openTag}I${closeTag} am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
describe('test main scenarios', () => {
test('test direct search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('I')
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"${openTag}I${closeTag} am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
test('test search all', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndexes = annotator.searchAll('Zhan Huang')
const newContent = annotator.highlightAll(highlightIndexes, options)
const openTag1 = TextAnnotator.createOpenTag(
'highlight-',
highlightIndexes[0],
'highlight'
)
const openTag2 = TextAnnotator.createOpenTag(
'highlight-',
highlightIndexes[1],
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>${openTag1}Zhan Huang</i></b>${closeTag}, a <b>frontend developer</b> in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - ${openTag2}Zhan Huang${closeTag}`
)
})
test('test search all', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndexes = annotator.searchAll('Zhan Huang')
const newContent = annotator.highlightAll(highlightIndexes, options)
const openTag1 = TextAnnotator.createOpenTag(
'highlight-',
highlightIndexes[0],
'highlight'
)
const openTag2 = TextAnnotator.createOpenTag(
'highlight-',
highlightIndexes[1],
'highlight'
)
expect(newContent).toBe(
`"I am ${openTag1}<b><i>Zhan Huang</i></b>${closeTag}, a <b>frontend developer</b> in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - ${openTag2}Zhan Huang${closeTag}`
)
})
test('test token-based fuzzy search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('frontend developer', {
prefix: 'a ',
postfix: ' in EMBLEBI',
fuzzySearchOptions: {}
test('test token-based fuzzy search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('frontend developer', {
prefix: 'a ',
postfix: ' in EMBLEBI',
fuzzySearchOptions: {}
})
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>Zhan Huang</i></b>, a ${openTag}<b>frontend developer</b>${closeTag} in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>Zhan Huang</i></b>, a <b>${openTag}frontend developer</b>${closeTag} in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
test('test sentence-based fuzzy search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('I like fool', {
fuzzySearchOptions: {}
test('test sentence-based fuzzy search', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('I like fool', {
fuzzySearchOptions: {}
})
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. ${openTag}I like food${closeTag} and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. ${openTag}I like food${closeTag} and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
test('test combination of searching and highlighting', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const result = annotator.searchAndHighlight('sports', {
highlightOptions: options
test('test combination of searching and highlighting', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const result = annotator.searchAndHighlight('sports', {
highlightOptions: options
})
const openTag = TextAnnotator.createOpenTag(
'highlight-',
result.highlightIndex,
'highlight'
)
expect(result.content).toBe(
`"I am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. I like food and ${openTag}sports${closeTag}. My favourite food is udon noodles." - Zhan Huang`
)
})
const openTag = TextAnnotator.createOpenTag(
'highlight-',
result.highlightIndex,
'highlight'
)
expect(result.content).toBe(
`"I am <b><i>Zhan Huang</i></b>, a <b>frontend developer</b> in EMBL-EBI. I like food and ${openTag}sports${closeTag}. My favourite food is udon noodles." - Zhan Huang`
)
test('test removal of a highlight', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const result = annotator.searchAndHighlight('udon noodles', {
highlightOptions: options
})
expect(
annotator.unhighlight(result.highlightIndex, {
byStringOperation: true,
content: result.content,
returnContent: true
})
).toBe(content)
})
})
test('test removal of a highlight', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const result = annotator.searchAndHighlight('udon noodles', {
highlightOptions: options
describe('test edge cases', () => {
test('ec1', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('I am Zhan Huang')
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"${openTag}I am <b><i>Zhan Huang</i></b>${closeTag}, a <b>frontend developer</b> in EMBL-EBI. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
expect(
annotator.unhighlight(result.highlightIndex, {
byStringOperation: true,
content: result.content,
returnContent: true
})
).toBe(content)
test('ec2', () => {
const options = contentObj()
const annotator = new TextAnnotator(options)
const highlightIndex = annotator.search('frontend developer in EMBL-EBI')
const newContent = annotator.highlight(highlightIndex, options)
const openTag = TextAnnotator.createOpenTag(
'highlight-',
highlightIndex,
'highlight'
)
expect(newContent).toBe(
`"I am <b><i>Zhan Huang</i></b>, a ${openTag}<b>frontend developer</b> in EMBL-EBI${closeTag}. I like food and sports. My favourite food is udon noodles." - Zhan Huang`
)
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc