website-highlighter 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class M {
|
|
2
2
|
/**
|
|
3
3
|
* Calculates the Levenshtein distance for all substrings and returns their
|
|
4
4
|
* distance and insertion-deletion offset.
|
|
@@ -10,13 +10,13 @@ class y {
|
|
|
10
10
|
*/
|
|
11
11
|
getEditDistances(e, t) {
|
|
12
12
|
var n = new Array(t.length + 1).fill([0, 0]);
|
|
13
|
-
for (let
|
|
14
|
-
let
|
|
13
|
+
for (let r = 0; r < e.length; r++) {
|
|
14
|
+
let a = [[r + 1, 0]];
|
|
15
15
|
for (let o = 0; o < t.length; o++) {
|
|
16
|
-
let
|
|
17
|
-
|
|
16
|
+
let s = e[r] != t[o], l = n[o + 1][0] + 1, c = a[o][0] + 1, d = n[o][0] + s, u = Math.min(l, Math.min(c, d)), h = [u, n[o][1]];
|
|
17
|
+
l === u ? h[1] = n[o + 1][1] - 1 : c === u && (h[1] = a[o][1] + 1), a.push(h);
|
|
18
18
|
}
|
|
19
|
-
n =
|
|
19
|
+
n = a;
|
|
20
20
|
}
|
|
21
21
|
return n;
|
|
22
22
|
}
|
|
@@ -30,116 +30,134 @@ class y {
|
|
|
30
30
|
* @return {array} Array of best substring matches.
|
|
31
31
|
*/
|
|
32
32
|
getMatches(e, t) {
|
|
33
|
-
let n = this.getEditDistances(e, t),
|
|
34
|
-
for (let
|
|
35
|
-
let
|
|
36
|
-
|
|
33
|
+
let n = this.getEditDistances(e, t), r = [0], a = n[0][0];
|
|
34
|
+
for (let s = 1; s < n.length; s++) {
|
|
35
|
+
let l = n[s][0];
|
|
36
|
+
l < a ? (r = [s], a = l) : l == a && r.push(s);
|
|
37
37
|
}
|
|
38
38
|
let o = [];
|
|
39
|
-
for (let
|
|
40
|
-
let
|
|
41
|
-
distance:
|
|
42
|
-
start:
|
|
39
|
+
for (let s of r) {
|
|
40
|
+
let l = n[s], c = {
|
|
41
|
+
distance: l[0],
|
|
42
|
+
start: s - e.length - l[1],
|
|
43
43
|
//simplification of startPos = endPos − (needleLength + insertions − deletions)
|
|
44
|
-
end:
|
|
44
|
+
end: s
|
|
45
45
|
};
|
|
46
|
-
o.push(
|
|
46
|
+
o.push(c);
|
|
47
47
|
}
|
|
48
48
|
return o;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
function
|
|
52
|
-
return new
|
|
51
|
+
function T(i, e) {
|
|
52
|
+
return new M().getMatches(i, e);
|
|
53
53
|
}
|
|
54
|
-
function
|
|
55
|
-
const t =
|
|
54
|
+
function b(i, e) {
|
|
55
|
+
const t = T(i, e);
|
|
56
56
|
let n;
|
|
57
|
-
for (const
|
|
58
|
-
(n === void 0 ||
|
|
59
|
-
const
|
|
60
|
-
return { value: e.slice(
|
|
57
|
+
for (const s of t)
|
|
58
|
+
(n === void 0 || s.distance < n.distance) && (n = s);
|
|
59
|
+
const r = Math.max(n.start, 0), a = Math.min(Math.max(n.end, r), e.length);
|
|
60
|
+
return { value: e.slice(r, a), start: r, end: a, distance: n.distance };
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function I(i, e, t) {
|
|
63
63
|
const n = i.textContent ?? "";
|
|
64
64
|
if (!Number.isInteger(e) || !Number.isInteger(t) || e < 0 || e >= t || t > n.length)
|
|
65
65
|
throw new RangeError(
|
|
66
66
|
`Invalid range [${e}, ${t}) for text length ${n.length}`
|
|
67
67
|
);
|
|
68
|
-
const
|
|
68
|
+
const r = i.ownerDocument, a = r.createTreeWalker(
|
|
69
69
|
i,
|
|
70
|
-
|
|
70
|
+
r.defaultView.NodeFilter.SHOW_TEXT
|
|
71
71
|
);
|
|
72
|
-
let o = 0,
|
|
73
|
-
for (let
|
|
74
|
-
const g = o +
|
|
75
|
-
if (
|
|
72
|
+
let o = 0, s = null, l = 0, c = null, d = 0;
|
|
73
|
+
for (let h = a.nextNode(); h; h = a.nextNode()) {
|
|
74
|
+
const g = o + h.data.length;
|
|
75
|
+
if (s === null && e >= o && e < g && (s = h, l = e - o), c === null && t > o && t <= g && (c = h, d = t - o), s && c)
|
|
76
76
|
break;
|
|
77
77
|
o = g;
|
|
78
78
|
}
|
|
79
|
-
if (!
|
|
79
|
+
if (!s || !c)
|
|
80
80
|
throw new Error(
|
|
81
81
|
"Could not map offsets to the DOM. The DOM may have changed."
|
|
82
82
|
);
|
|
83
|
-
const u =
|
|
84
|
-
return u.setStart(
|
|
83
|
+
const u = r.createRange();
|
|
84
|
+
return u.setStart(s, l), u.setEnd(c, d), u;
|
|
85
85
|
}
|
|
86
86
|
const f = "website-highlighter", w = `${f}:response`, m = 500;
|
|
87
|
-
let
|
|
88
|
-
function
|
|
87
|
+
let y = 0;
|
|
88
|
+
function H(i) {
|
|
89
89
|
return new Promise((e) => globalThis.setTimeout(e, i));
|
|
90
90
|
}
|
|
91
|
-
function
|
|
91
|
+
function S(i, e) {
|
|
92
|
+
const t = i.ownerDocument?.defaultView ?? window;
|
|
93
|
+
return t.MutationObserver ? new Promise((n) => {
|
|
94
|
+
let r;
|
|
95
|
+
const a = new t.MutationObserver(() => {
|
|
96
|
+
t.clearTimeout(r), a.disconnect(), n(!0);
|
|
97
|
+
});
|
|
98
|
+
r = t.setTimeout(() => {
|
|
99
|
+
a.disconnect(), n(!1);
|
|
100
|
+
}, e), a.observe(i, {
|
|
101
|
+
childList: !0,
|
|
102
|
+
characterData: !0,
|
|
103
|
+
subtree: !0
|
|
104
|
+
});
|
|
105
|
+
}) : H(e).then(() => !1);
|
|
106
|
+
}
|
|
107
|
+
function x(i, e, t) {
|
|
92
108
|
const n = Math.max(i.length, e.length);
|
|
93
109
|
return n === 0 ? 1 : (n - t) / n;
|
|
94
110
|
}
|
|
95
111
|
function p(i, e) {
|
|
96
|
-
const t = e.textContent ?? "", { start: n, end:
|
|
97
|
-
if (!
|
|
112
|
+
const t = e.textContent ?? "", { start: n, end: r, value: a, distance: o } = b(i, t), s = e.ownerDocument?.defaultView ?? window;
|
|
113
|
+
if (!s.CSS?.highlights || !s.Highlight) throw new Error("This browser does not support the CSS Custom Highlight API.");
|
|
98
114
|
return {
|
|
99
115
|
haystack: t,
|
|
100
|
-
range: n <
|
|
101
|
-
value:
|
|
102
|
-
view:
|
|
103
|
-
score:
|
|
116
|
+
range: n < r ? I(e, n, r) : null,
|
|
117
|
+
value: a,
|
|
118
|
+
view: s,
|
|
119
|
+
score: x(i, a, o)
|
|
104
120
|
};
|
|
105
121
|
}
|
|
106
122
|
function E({ range: i, value: e, view: t }) {
|
|
107
123
|
if (!i) throw new Error("Could not find text to highlight.");
|
|
108
124
|
return t.CSS.highlights.set(f, new t.Highlight(i)), { range: i, value: e };
|
|
109
125
|
}
|
|
110
|
-
async function
|
|
111
|
-
let
|
|
126
|
+
async function v(i, e, t, n, r) {
|
|
127
|
+
let a = 0;
|
|
112
128
|
for (; ; ) {
|
|
113
129
|
const o = p(i, e);
|
|
114
130
|
if (o.score >= t) return E(o);
|
|
115
|
-
for (;
|
|
116
|
-
;
|
|
117
|
-
|
|
131
|
+
for (; a < n; ) {
|
|
132
|
+
const s = await S(e, r);
|
|
133
|
+
if (a += 1, s) break;
|
|
134
|
+
}
|
|
135
|
+
if (a >= n) throw new Error(`Could not find "${i}" with threshold ${t}. Best match was "${o.value}".`);
|
|
118
136
|
}
|
|
119
137
|
}
|
|
120
138
|
function C(i, {
|
|
121
139
|
root: e = document.body,
|
|
122
140
|
threshold: t = 0,
|
|
123
141
|
retries: n = 6,
|
|
124
|
-
retryInterval:
|
|
142
|
+
retryInterval: r = m
|
|
125
143
|
} = {}) {
|
|
126
|
-
return t > 0 ?
|
|
144
|
+
return t > 0 ? v(i, e, t, n, r) : E(p(i, e));
|
|
127
145
|
}
|
|
128
146
|
function N(i, e, t = "*") {
|
|
129
147
|
if (!i?.contentWindow) throw new TypeError("Expected an iframe with a contentWindow");
|
|
130
|
-
const n = `${Date.now()}-${
|
|
131
|
-
let
|
|
148
|
+
const n = `${Date.now()}-${y++}`, r = i.contentWindow;
|
|
149
|
+
let a;
|
|
132
150
|
function o() {
|
|
133
|
-
|
|
151
|
+
r.postMessage({
|
|
134
152
|
type: f,
|
|
135
153
|
id: n,
|
|
136
154
|
text: e
|
|
137
155
|
}, t);
|
|
138
156
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
157
|
+
function s(l) {
|
|
158
|
+
l.source === r && l.data?.type === w && l.data.id === n && (window.clearInterval(a), window.removeEventListener("message", s));
|
|
141
159
|
}
|
|
142
|
-
window.addEventListener("message",
|
|
160
|
+
window.addEventListener("message", s), o(), a = window.setInterval(o, m);
|
|
143
161
|
}
|
|
144
162
|
if (typeof window < "u") {
|
|
145
163
|
let i = function(t) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(c,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(c=typeof globalThis<"u"?globalThis:c||self,f(c.WebsiteHighlighter={}))})(this,(function(c){"use strict";class f{getEditDistances(t,e){var n=new Array(e.length+1).fill([0,0]);for(let
|
|
1
|
+
(function(c,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(c=typeof globalThis<"u"?globalThis:c||self,f(c.WebsiteHighlighter={}))})(this,(function(c){"use strict";class f{getEditDistances(t,e){var n=new Array(e.length+1).fill([0,0]);for(let o=0;o<t.length;o++){let l=[[o+1,0]];for(let r=0;r<e.length;r++){let s=t[o]!=e[r],a=n[r+1][0]+1,u=l[r][0]+1,w=n[r][0]+s,d=Math.min(a,Math.min(u,w)),h=[d,n[r][1]];a===d?h[1]=n[r+1][1]-1:u===d&&(h[1]=l[r][1]+1),l.push(h)}n=l}return n}getMatches(t,e){let n=this.getEditDistances(t,e),o=[0],l=n[0][0];for(let s=1;s<n.length;s++){let a=n[s][0];a<l?(o=[s],l=a):a==l&&o.push(s)}let r=[];for(let s of o){let a=n[s],u={distance:a[0],start:s-t.length-a[1],end:s};r.push(u)}return r}}function y(i,t){return new f().getMatches(i,t)}function I(i,t){const e=y(i,t);let n;for(const s of e)(n===void 0||s.distance<n.distance)&&(n=s);const o=Math.max(n.start,0),l=Math.min(Math.max(n.end,o),t.length);return{value:t.slice(o,l),start:o,end:l,distance:n.distance}}function S(i,t,e){const n=i.textContent??"";if(!Number.isInteger(t)||!Number.isInteger(e)||t<0||t>=e||e>n.length)throw new RangeError(`Invalid range [${t}, ${e}) for text length ${n.length}`);const o=i.ownerDocument,l=o.createTreeWalker(i,o.defaultView.NodeFilter.SHOW_TEXT);let r=0,s=null,a=0,u=null,w=0;for(let h=l.nextNode();h;h=l.nextNode()){const m=r+h.data.length;if(s===null&&t>=r&&t<m&&(s=h,a=t-r),u===null&&e>r&&e<=m&&(u=h,w=e-r),s&&u)break;r=m}if(!s||!u)throw new Error("Could not map offsets to the DOM. The DOM may have changed.");const d=o.createRange();return d.setStart(s,a),d.setEnd(u,w),d}const g="website-highlighter",p=`${g}:response`,b=500;let H=0;function v(i){return new Promise(t=>globalThis.setTimeout(t,i))}function x(i,t){const e=i.ownerDocument?.defaultView??window;return e.MutationObserver?new Promise(n=>{let o;const l=new e.MutationObserver(()=>{e.clearTimeout(o),l.disconnect(),n(!0)});o=e.setTimeout(()=>{l.disconnect(),n(!1)},t),l.observe(i,{childList:!0,characterData:!0,subtree:!0})}):v(t).then(()=>!1)}function C(i,t,e){const n=Math.max(i.length,t.length);return n===0?1:(n-e)/n}function T(i,t){const e=t.textContent??"",{start:n,end:o,value:l,distance:r}=I(i,e),s=t.ownerDocument?.defaultView??window;if(!s.CSS?.highlights||!s.Highlight)throw new Error("This browser does not support the CSS Custom Highlight API.");return{haystack:e,range:n<o?S(t,n,o):null,value:l,view:s,score:C(i,l,r)}}function M({range:i,value:t,view:e}){if(!i)throw new Error("Could not find text to highlight.");return e.CSS.highlights.set(g,new e.Highlight(i)),{range:i,value:t}}async function O(i,t,e,n,o){let l=0;for(;;){const r=T(i,t);if(r.score>=e)return M(r);for(;l<n;){const s=await x(t,o);if(l+=1,s)break}if(l>=n)throw new Error(`Could not find "${i}" with threshold ${e}. Best match was "${r.value}".`)}}function E(i,{root:t=document.body,threshold:e=0,retries:n=6,retryInterval:o=b}={}){return e>0?O(i,t,e,n,o):M(T(i,t))}function N(i,t,e="*"){if(!i?.contentWindow)throw new TypeError("Expected an iframe with a contentWindow");const n=`${Date.now()}-${H++}`,o=i.contentWindow;let l;function r(){o.postMessage({type:g,id:n,text:t},e)}function s(a){a.source===o&&a.data?.type===p&&a.data.id===n&&(window.clearInterval(l),window.removeEventListener("message",s))}window.addEventListener("message",s),r(),l=window.setInterval(r,b)}if(typeof window<"u"){let i=function(e){return e.origin==="null"?"*":e.origin},t=function(e){e.source?.postMessage({type:p,id:e.data.id},i(e))};window.addEventListener("message",e=>{e.data?.type===g&&(t(e),E(e.data.text,{threshold:.9}).catch(n=>console.error(n)))})}c.default=E,c.highlightInIframe=N,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|