@filteringdev/namulink 18.2.0 → 19.0.0-build.1

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,34 +1,29 @@
1
1
  // ==UserScript==
2
2
  // @name NamuLink
3
- // @encoding utf-8
3
+ //
4
4
  // @namespace https://github.com/FilteringDev/NamuLink
5
5
  // @homepageURL https://github.com/FilteringDev/NamuLink
6
6
  // @supportURL https://github.com/FilteringDev/NamuLink/issues
7
7
  // @updateURL https://cdn.jsdelivr.net/npm/@filteringdev/namulink@latest/dist/NamuLink.user.js
8
8
  // @downloadURL https://cdn.jsdelivr.net/npm/@filteringdev/namulink@latest/dist/NamuLink.user.js
9
- // @license MIT
9
+ // @license MPL-2.0
10
10
  //
11
- // @version 18.2.0
11
+ // @version 19.0.0-build.1
12
12
  // @author PiQuark6046 and contributors
13
13
  //
14
- // @match https://namu.wiki/*
15
- //
16
- // @description NamuLink blocks the PowerLink advertisement on NamuWiki.
17
- // @description:ko NamuLink는 나무위키에 있는 파워링크 광고를 차단합니다.
18
- //
19
14
  // @grant unsafeWindow
20
15
  // @run-at document-start
16
+ //
17
+ // @description NamuLink allows AdGuard, uBlock Origin, Brave and ABP to resist against Ad-Shield quickly.
18
+ // @description:ko NamuLink는 AdGuard, uBlock Origin, Brave 와 ABP가 애드쉴드에 빠르게 저항할 수 있도록 합니다.
19
+ // @description:ja NamuLinkを使うと、AdGuard, uBlock Origin, Brave, およびABPがAd-Shieldに素早く対抗できます。
20
+ //
21
+ // @match *://namu.wiki/*
22
+ // @match *://*.namu.wiki/*
21
23
  // ==/UserScript==
22
- // Used libraries:
23
- (()=>{function w(r={}){let e=R(r),p=e.Events.Navigate,f=e.Events.Rendered,m=a=>{window.dispatchEvent(new CustomEvent(p,{detail:a}))},l=a=>{window.dispatchEvent(new CustomEvent(f,{detail:a}))},u=window.location.href,i=0,t=!1,n=a=>{if(t)return;let s=window.location.href;if(s===u)return;let c=u;u=s;let d=++i;m({Seq:d,From:c,To:s,Cause:a}),(async()=>{let y=e.Root();if(!y){if(d!==i||t)return;l({Seq:d,Url:s,Ok:!0});return}let S=await M({Root:y,StableForMs:e.StableForMs,SampleWindowMs:e.SampleWindowMs,Threshold:e.Threshold,TimeoutMs:e.TimeoutMs,Ignore:e.IgnoreMutation});d!==i||t||l({Seq:d,Url:s,Ok:S})})()},o=a=>{let s=history[a].bind(history);Object.defineProperty(history,a,{value:(...d)=>{let y=s(...d);return queueMicrotask(()=>n(a)),y},configurable:!0,writable:!0})};o("pushState"),o("replaceState");let g=()=>n("popstate");window.addEventListener("popstate",g);let h=()=>n("hashchange");return e.WatchHashChange&&window.addEventListener("hashchange",h),queueMicrotask(()=>{if(t)return;let a=++i;m({Seq:a,From:null,To:window.location.href,Cause:"init"}),(async()=>{let s=e.Root();if(!s){if(a!==i||t)return;l({Seq:a,Url:window.location.href,Ok:!0});return}let c=await M({Root:s,StableForMs:e.StableForMs,SampleWindowMs:e.SampleWindowMs,Threshold:e.Threshold,TimeoutMs:e.TimeoutMs,Ignore:e.IgnoreMutation});a!==i||t||l({Seq:a,Url:window.location.href,Ok:c})})()}),()=>{t=!0,window.removeEventListener("popstate",g),e.WatchHashChange&&window.removeEventListener("hashchange",h)}}function b(r){if(r.type==="attributes"){let e=r.attributeName??"";if(e==="class"||e==="style"||e.startsWith("aria-")||e.startsWith("data-"))return!0}return!1}function R(r){return{Root:r.Root??(()=>document.querySelector("#app")??document.body),StableForMs:r.StableForMs??900,SampleWindowMs:r.SampleWindowMs??900,Threshold:r.Threshold??3,TimeoutMs:r.TimeoutMs??12e3,IgnoreMutation:r.IgnoreMutation??b,WatchHashChange:r.WatchHashChange??!0,Events:{Navigate:r.Events?.Navigate??"SpaNavigate",Rendered:r.Events?.Rendered??"SpaRendered"}}}async function M(r){let e=[],p=performance.now(),f=!1,m=new MutationObserver(u=>{let i=performance.now();for(let o of u){if(r.Ignore?.(o))continue;let g=1;o.type==="childList"&&(g=2),e.push({T:i,Score:g})}let t=i-r.SampleWindowMs;for(;e.length&&e[0].T<t;)e.shift();e.reduce((o,g)=>o+g.Score,0)>r.Threshold&&(p=i)});m.observe(r.Root,{subtree:!0,childList:!0,attributes:!0,characterData:!0});let l=performance.now();return await new Promise(u=>{let i=()=>{if(f)return;let t=performance.now();if(t-p>=r.StableForMs){f=!0,m.disconnect(),u(!0);return}if(t-l>=r.TimeoutMs){f=!0,m.disconnect(),u(!1);return}setTimeout(i,100)};setTimeout(i,0)})}function E(){let r=`
24
- self.onmessage = (e) => {
25
- const { entries, jobId } = e.data;
26
- // entries: Array<[string, number]>
27
- // \uB0B4\uB9BC\uCC28\uC21C \uC815\uB82C
28
- entries.sort((a, b) => b[1] - a[1]);
29
- self.postMessage({ jobId, sorted: entries });
30
- };
31
- `;return URL.createObjectURL(new Blob([r],{type:"text/javascript"}))}function P(r){let e=E(),p=Array.from({length:r},()=>new Worker(e));return{Workers:p,dispose(){p.forEach(f=>f.terminate()),URL.revokeObjectURL(e)}}}function v(r=document){let e=Object.create(null),p=r.createTreeWalker(r.documentElement||r,NodeFilter.SHOW_ELEMENT),f=p.currentNode;for(;f;){if(f instanceof Element)for(let m of f.attributes){let l=m.name;l.startsWith("data-v-")&&(e[l]=(e[l]||0)+1)}f=p.nextNode()}return e}function C(r){let e=[];function p(l){e.push(l);let u=e.length-1;for(;u>0;){let i=u-1>>1;if(e[i].count>=e[u].count)break;[e[i],e[u]]=[e[u],e[i]],u=i}}function f(){let l=e[0],u=e.pop();if(e.length){e[0]=u;let i=0;for(;;){let t=i*2+1,n=t+1,o=i;if(t<e.length&&e[t].count>e[o].count&&(o=t),n<e.length&&e[n].count>e[o].count&&(o=n),o===i)break;[e[i],e[o]]=[e[o],e[i]],i=o}}return l}for(let l=0;l<r.length;l++){let u=r[l];if(u&&u.length){let[i,t]=u[0];p({Count:t,Attr:i,ChunkIndex:l,IndexInChunk:0})}}let m=[];for(;e.length;){let{Attr:l,Count:u,ChunkIndex:i,IndexInChunk:t}=f();m.push([l,u]);let n=t+1,o=r[i];if(n<o.length){let[g,h]=o[n];p({Count:h,Attr:g,ChunkIndex:i,IndexInChunk:n})}}return m}async function x(r){let e=Object.entries(r),p=Math.max(1,navigator.hardwareConcurrency||1),f=Math.min(8,Math.max(1,p-1)),l=e.length>=5e3&&f>1?f:1,u=P(l);try{let i=Array.from({length:l},()=>[]);for(let o=0;o<e.length;o++)i[o%l].push(e[o]);let t=await Promise.all(i.map((o,g)=>new Promise((h,a)=>{let s=u.Workers[g],c=g+":"+Date.now(),d=S=>{S.data?.jobId===c&&(s.removeEventListener("message",d),s.removeEventListener("error",y),h(S.data.sorted))},y=S=>{s.removeEventListener("message",d),s.removeEventListener("error",y),a(S)};s.addEventListener("message",d),s.addEventListener("error",y),s.postMessage({entries:o,jobId:c})}))),n=t.length===1?t[0]:C(t);return{Result:n,TotalKeys:n.length,WorkerCount:l,HardwareConcurrency:p}}finally{u.dispose()}}var W=typeof unsafeWindow<"u"?unsafeWindow:window;function k(r,e="NamuLink"){let p=r.Function.prototype.toString,f=[[/for *\( *; *; *\) *switch *\( *_[a-z0-9]+\[_[a-z0-9]+\([a-z0-9]+\)\] *=_[a-z0-9]+/,/_[a-z0-9]+\[('|")[A-Z]+('|")\]\)\(\[ *\]\)/,/0x[a-z0-9]+ *\) *; *case/],[/; *return *this\[_0x[a-z0-9]+\( *0x[0-9a-z]+ *\)/,/; *if *\( *_0x[a-z0-9]+ *&& *\( *_0x[a-z0-9]+ *= *_0x[a-z0-9]+/,/\) *, *void *\( *this *\[ *_0x[a-z0-9]+\( *0x[0-9a-z]+ *\) *\] *= *_0x[a-z0-9]+ *\[/]];r.Function.prototype.bind=new Proxy(r.Function.prototype.bind,{apply(t,n,o){let g=Reflect.apply(p,n,o);return f.filter(h=>h.filter(a=>a.test(g)).length>=3).length===1?(console.debug(`[${e}]: Function.prototype.bind:`,n),Reflect.apply(t,()=>{},[])):Reflect.apply(t,n,o)}});let m=[[/\( *\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\]\(\); *}/,/\( *\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\]\(\); *}/],[/\( *\) *=> *{ *var _0x[a-z0-9]+ *= *_0x[a-z0-9]+ *; *if *\( *this\[ *_0x[a-z0-9]+ *\( *0x[0-9a-f]+ *\) *\] *\) *return *clearTimeout/,/\( *0x[0-9a-f]+ *\) *\] *\) *, *void *\( *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\] *= *void *\([x0-9a-f*+-]+ *\) *\) *; *this\[_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\] *\(\) *;/]];function l(t){let n=[];for(;t.parentElement;)n.push(t.parentElement),t=t.parentElement;return n}let u=()=>{let t=[...document.querySelectorAll('div[class*=" "] div[class]')].filter(n=>n instanceof HTMLElement);t=t.filter(n=>{let o=Number(getComputedStyle(n).getPropertyValue("padding-left").replaceAll("px","")),g=Number(getComputedStyle(n).getPropertyValue("padding-right").replaceAll("px","")),h=Number(getComputedStyle(n).getPropertyValue("padding-top").replaceAll("px","")),a=Number(getComputedStyle(n).getPropertyValue("padding-bottom").replaceAll("px",""));return o>5&&g>5&&h>5&&a>5}),t=t.filter(n=>[...n.querySelectorAll("*")].filter(o=>o instanceof HTMLElement&&getComputedStyle(o).getPropertyValue("animation-timing-function")==="ease-in-out").length>=3),t=t.filter(n=>l(n).some(o=>Number(getComputedStyle(o).getPropertyValue("margin-top").replaceAll("px",""))>10)),t=t.filter(n=>n.innerText.length<1e3),t=t.filter(n=>[...n.querySelectorAll('*[href="/RecentChanges"]')].filter(o=>o instanceof HTMLElement&&getComputedStyle(o).getPropertyValue("display")!=="none").length===0),t=t.filter(n=>!n.innerText.includes((new URL(location.href).searchParams.get("from")||"")+"\uC5D0\uC11C \uB118\uC5B4\uC634")),t=t.filter(n=>!/\[[0-9]+\] .+/.test(n.innerText)),t.forEach(n=>n.setAttribute("style","display: none !important; visibility: hidden !important;"))};r.setTimeout=new Proxy(r.setTimeout,{apply(t,n,o){let g=Reflect.apply(p,o[0],o);return m.filter(h=>h.filter(a=>a.test(g)).length>=1).length===1?(console.debug(`[${e}]: setTimeout:`,o[0]),Reflect.apply(t,n,[u,1500])):Reflect.apply(t,n,o)}}),document.readyState==="loading"?window.addEventListener("DOMContentLoaded",()=>{w({Root:()=>document.getElementById("#app"),StableForMs:900,SampleWindowMs:900,Threshold:3,TimeoutMs:12e3,IgnoreMutation:b,WatchHashChange:!0})}):window.addEventListener("DOMContentLoaded",()=>{w({Root:()=>document.getElementById("#app"),StableForMs:900,SampleWindowMs:900,Threshold:3,TimeoutMs:12e3,IgnoreMutation:b,WatchHashChange:!0})});let i=async()=>{let t=v(document),{Result:n,TotalKeys:o,WorkerCount:g,HardwareConcurrency:h}=await x(t),a=[];n.filter(([,s])=>s<=30).forEach(([s,c])=>{a.push(...[...document.querySelectorAll(`[${s}]`)].filter(d=>d instanceof HTMLElement))}),a=a.filter(s=>getComputedStyle(s).getPropertyValue("display")==="flex"),a=a.filter(s=>[...s.querySelectorAll("*")].some(c=>c instanceof HTMLElement&&typeof c.click=="function")),a=a.filter(s=>[...s.querySelectorAll("*")].filter(c=>c instanceof HTMLElement&&c.getBoundingClientRect().bottom-c.getBoundingClientRect().top>100&&c.getBoundingClientRect().right-c.getBoundingClientRect().left>100).length<=50),a=a.filter(s=>{let c=[...s.querySelectorAll("*")].filter(d=>d.getBoundingClientRect().bottom-d.getBoundingClientRect().top>25&&d.getBoundingClientRect().right-d.getBoundingClientRect().left>25&&d instanceof SVGPathElement&&d.getAttribute("d")!==null||d instanceof HTMLImageElement&&d.src.includes("//i.namu.wiki/i/")).length;return 1<=c&&c<=6}),a=a.filter(s=>[...s.querySelectorAll("*")].some(c=>c instanceof HTMLElement&&getComputedStyle(c,"::after").getPropertyValue("content").includes(":")&&c.getBoundingClientRect().right-c.getBoundingClientRect().left>20)===!1),a=a.filter(s=>[...s.querySelectorAll("*")].every(c=>c instanceof HTMLElement&&!new Date(c.getHTML()).getTime())),console.debug(`[${e}]`,a),a.forEach(s=>{setInterval(()=>{s.setAttribute("style","display: none !important; visibility: hidden !important;")},250)})};window.addEventListener("SpaRendered",()=>setTimeout(i,2500)),window.addEventListener("SpaRendered",i)}k(W);})();
24
+
25
+
26
+ (()=>{var s=typeof unsafeWindow<"u"?unsafeWindow:window;function y(n,i="NamuLink"){let c=n.Function.prototype.call,o=n.Reflect.apply,u=new CustomEvent("PL2PlaceHolder"),d=[[/function *\( *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *\) *{ *var *_0x[a-f0-9]+/,/('|")td('|") *, *{ *('|")class('|") *: *\( *-? *0x[a-f0-9]+ *\+ *-? *0x[a-f0-9]+ *\+ *0x[a-f0-9]+ *, *_0x[a-f0-9]+ *\[ *_0x[a-f0-9]+ */,/\( *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\) *, *('|")onClick('|") *: *_0x[a-f0-9]+ *\[ *-? *0x[a-f0-9]+ *\* *-? *0x[a-f0-9]+/,/_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\) *, *('|")colspan('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *=== *_0x[a-f0-9]+ *\[ *_0x[a-f0-9]+ *\(/]],x=[[/new *Map *\( *Object *\[ *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\] *\( *{ *('|")pretendard('|") *: *{ *('|")fontFamily('|") *: */,/('|")fontFamily('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")styleUrl('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")isGoogleFonts/,/('|")popper--wide('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")popper__title('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *} *} *,/]],l=!1;n.Function.prototype.call=new Proxy(c,{apply(e,t,p){if(l)return o(e,t,p);l=!0;let f=String(t);return f.length<5e4&&!x.some(a=>a.every(r=>r.test(f)))&&d.filter(a=>a.filter(r=>r.test(f)).length===a.length).length===1?(console.debug(`[${i}]: Function.prototype.call called for PowerLink Skeleton:`,t),n.document.dispatchEvent(u),l=!1,o(e,()=>{},[])):(l=!1,o(e,t,p))}}),n.document.addEventListener("PL2PlaceHolder",()=>{setTimeout(()=>{let e=new Set([...n.document.querySelectorAll('div[class] div[class*=" "] div[class*=" "] ~ div[class*=" "]')]);e=new Set([...e].filter(t=>t instanceof HTMLElement)),e=new Set([...e].filter(t=>Number(getComputedStyle(t).getPropertyValue("padding-top").replaceAll(/px$/g,""))>20)),e=new Set([...e,...[...e].flatMap(t=>[...t.querySelectorAll("*")])]),e=new Set([...e].filter(t=>t instanceof HTMLElement&&t.innerText.trim().length===0)),e=new Set([...e].filter(t=>Number(getComputedStyle(t).getPropertyValue("border-bottom-width").replaceAll(/px/g,""))>=1)),e=new Set([...e].filter(t=>Number(getComputedStyle(t).getPropertyValue("border-left-width").replaceAll(/px/g,""))>=1)),e=new Set([...e].filter(t=>Number(getComputedStyle(t).getPropertyValue("border-right-width").replaceAll(/px/g,""))>=1)),e=new Set([...e].filter(t=>Number(getComputedStyle(t).getPropertyValue("border-top-width").replaceAll(/px/g,""))>=1)),console.debug(`[${i}]: Removing PowerLink Skeleton Containers:`,e),e.forEach(t=>{t.setAttribute("style","display: none !important;")})},2500)})}y(s);})();
32
27
  /*!
33
28
  * @license MPL-2.0
34
29
  * This Source Code Form is subject to the terms of the Mozilla Public
@@ -36,5 +31,5 @@ self.onmessage = (e) => {
36
31
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
37
32
  *
38
33
  * Contributors:
39
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
34
+ * - See Git history at https://github.com/FilteringDev/NamuLink for detailed authorship information.
40
35
  */
@@ -5,6 +5,6 @@
5
5
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
  *
7
7
  * Contributors:
8
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
8
+ * - See Git history at https://github.com/FilteringDev/NamuLink for detailed authorship information.
9
9
  */
10
10
  export declare function RunNamuLinkUserscript(BrowserWindow: typeof window, UserscriptName?: string): void;
package/dist/index.js ADDED
@@ -0,0 +1,65 @@
1
+ /*!
2
+ * @license MPL-2.0
3
+ * This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+ *
7
+ * Contributors:
8
+ * - See Git history at https://github.com/FilteringDev/NamuLink for detailed authorship information.
9
+ */
10
+ const Win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
11
+ export function RunNamuLinkUserscript(BrowserWindow, UserscriptName = 'NamuLink') {
12
+ const OriginalFunctionPrototypeCall = BrowserWindow.Function.prototype.call;
13
+ const OriginalReflectApply = BrowserWindow.Reflect.apply;
14
+ let PL2Event = new CustomEvent('PL2PlaceHolder');
15
+ const PL2MajorFuncCallPatterns = [[
16
+ /function *\( *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *, *_0x[a-f0-9]+ *\) *{ *var *_0x[a-f0-9]+/,
17
+ /('|")td('|") *, *{ *('|")class('|") *: *\( *-? *0x[a-f0-9]+ *\+ *-? *0x[a-f0-9]+ *\+ *0x[a-f0-9]+ *, *_0x[a-f0-9]+ *\[ *_0x[a-f0-9]+ */,
18
+ /\( *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\) *, *('|")onClick('|") *: *_0x[a-f0-9]+ *\[ *-? *0x[a-f0-9]+ *\* *-? *0x[a-f0-9]+/,
19
+ /_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\) *, *('|")colspan('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *=== *_0x[a-f0-9]+ *\[ *_0x[a-f0-9]+ *\(/
20
+ ]];
21
+ const FalsePositiveSignPatterns = [[
22
+ /new *Map *\( *Object *\[ *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *\] *\( *{ *('|")pretendard('|") *: *{ *('|")fontFamily('|") *: */,
23
+ /('|")fontFamily('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")styleUrl('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")isGoogleFonts/,
24
+ /('|")popper--wide('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *, *('|")popper__title('|") *: *_0x[a-f0-9]+ *\( *0x[a-f0-9]+ *\) *} *} *,/
25
+ ]];
26
+ let InHook = false;
27
+ BrowserWindow.Function.prototype.call = new Proxy(OriginalFunctionPrototypeCall, {
28
+ apply(Target, ThisArg, Args) {
29
+ // Prevent infinite recursion when the hook itself calls Function.prototype.call
30
+ if (InHook) {
31
+ return OriginalReflectApply(Target, ThisArg, Args);
32
+ }
33
+ InHook = true;
34
+ const Stringified = String(ThisArg);
35
+ if (Stringified.length < 50000 &&
36
+ !FalsePositiveSignPatterns.some(Patterns => Patterns.every(Pattern => Pattern.test(Stringified))) &&
37
+ PL2MajorFuncCallPatterns.filter(Patterns => Patterns.filter(Pattern => Pattern.test(Stringified)).length === Patterns.length).length === 1) {
38
+ console.debug(`[${UserscriptName}]: Function.prototype.call called for PowerLink Skeleton:`, ThisArg);
39
+ BrowserWindow.document.dispatchEvent(PL2Event);
40
+ InHook = false;
41
+ return OriginalReflectApply(Target, () => { }, []);
42
+ }
43
+ InHook = false;
44
+ return OriginalReflectApply(Target, ThisArg, Args);
45
+ }
46
+ });
47
+ BrowserWindow.document.addEventListener('PL2PlaceHolder', () => {
48
+ setTimeout(() => {
49
+ let ContainerElements = new Set([...BrowserWindow.document.querySelectorAll('div[class] div[class*=" "] div[class*=" "] ~ div[class*=" "]')]);
50
+ ContainerElements = new Set([...ContainerElements].filter(Container => Container instanceof HTMLElement));
51
+ ContainerElements = new Set([...ContainerElements].filter(Container => Number(getComputedStyle(Container).getPropertyValue('padding-top').replaceAll(/px$/g, '')) > 20));
52
+ ContainerElements = new Set([...ContainerElements, ...[...ContainerElements].flatMap(Container => [...Container.querySelectorAll('*')])]);
53
+ ContainerElements = new Set([...ContainerElements].filter(Container => Container instanceof HTMLElement && Container.innerText.trim().length === 0));
54
+ ContainerElements = new Set([...ContainerElements].filter(Container => Number(getComputedStyle(Container).getPropertyValue('border-bottom-width').replaceAll(/px/g, '')) >= 1));
55
+ ContainerElements = new Set([...ContainerElements].filter(Container => Number(getComputedStyle(Container).getPropertyValue('border-left-width').replaceAll(/px/g, '')) >= 1));
56
+ ContainerElements = new Set([...ContainerElements].filter(Container => Number(getComputedStyle(Container).getPropertyValue('border-right-width').replaceAll(/px/g, '')) >= 1));
57
+ ContainerElements = new Set([...ContainerElements].filter(Container => Number(getComputedStyle(Container).getPropertyValue('border-top-width').replaceAll(/px/g, '')) >= 1));
58
+ console.debug(`[${UserscriptName}]: Removing PowerLink Skeleton Containers:`, ContainerElements);
59
+ ContainerElements.forEach(Container => {
60
+ Container.setAttribute('style', 'display: none !important;');
61
+ });
62
+ }, 2500);
63
+ });
64
+ }
65
+ RunNamuLinkUserscript(Win);
package/package.json CHANGED
@@ -1,57 +1,41 @@
1
1
  {
2
2
  "name": "@filteringdev/namulink",
3
- "version": "18.2.0",
3
+ "version": "19.0.0-build.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build:interface": "esbuild sources/interface.ts --bundle --format=esm --splitting --sourcemap --target=es2024 --external:/node_modules --outdir=dist && tsc --outDir dist/types --declaration --emitDeclarationOnly",
8
- "build:userscript": "esbuild sources/src/index.ts --bundle --minify --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2024,chrome119,safari17,firefox121 --outfile=./dist/NamuLink.user.js",
7
+ "build:interface": "tsc -p userscript/tsconfig.json",
8
+ "build:userscript": "npm run build -w builder -- --minify true --use-cache false --build-type production --SubscriptionUrl https://cdn.jsdelivr.net/npm/@filteringdev/namulink@latest/dist/NamuLink.user.js",
9
9
  "build": "npm run build:interface && npm run build:userscript",
10
- "debug": "esbuild sources/src/index.ts --bundle --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2024,chrome119,safari17,firefox121 --outfile=./dist/NamuLink-debug.user.js",
11
- "lint": "tsc --noEmit && eslint sources --ext .ts"
12
- },
13
- "keywords": [],
14
- "author": {
15
- "name": "PiQuark6046",
16
- "email": "piquark6046@proton.me",
17
- "url": "https://github.com/PiQuark6046"
10
+ "debug": "npm run debug -w builder",
11
+ "lint": "npm run lint -w builder && npm run lint -w userscript"
18
12
  },
13
+ "keywords": [
14
+ "namu.wiki",
15
+ "NamuWiki"
16
+ ],
19
17
  "files": [
20
18
  "dist/**/*"
21
19
  ],
22
20
  "exports": {
23
21
  ".": {
24
- "import": "./dist/interface.js",
25
- "types": "./dist/types/interface.d.ts"
22
+ "import": "./dist/index.js",
23
+ "types": "./dist/index.d.ts"
26
24
  }
27
25
  },
28
- "types": "./dist/types/interface.d.ts",
29
26
  "repository": {
30
27
  "type": "git",
31
28
  "url": "git+https://github.com/FilteringDev/NamuLink.git"
32
29
  },
33
- "contributors": [
34
- {
35
- "name": "green1052",
36
- "url": "https://github.com/green1052"
37
- },
38
- {
39
- "name": "gaeulbyul",
40
- "url": "https://github.com/gaeulbyul"
41
- },
42
- {
43
- "name": "Adguard Software Ltd.",
44
- "url": "https://adguard.com/"
45
- }
30
+ "license": "MPL-2.0",
31
+ "workspaces": [
32
+ "userscript",
33
+ "builder"
46
34
  ],
47
- "license": "MIT",
48
- "dependencies": {
49
- "@types/node": "^24.10.4"
50
- },
51
35
  "devDependencies": {
52
- "esbuild": "^0.27.2",
53
- "eslint": "^9.39.2",
54
- "typescript": "^5.9.3",
55
- "typescript-eslint": "^8.50.1"
36
+ "@typescript-eslint/eslint-plugin": "^8.57.0",
37
+ "@typescript-eslint/parser": "^8.57.0",
38
+ "eslint": "^10.0.3",
39
+ "typescript-eslint": "^8.57.0"
56
40
  }
57
41
  }
package/dist/interface.js DELETED
@@ -1,429 +0,0 @@
1
- // sources/src/spa.ts
2
- function InstallSpaNavigationBridge(Options = {}) {
3
- const Opts = NormalizeOptions(Options);
4
- const EventNavigate = Opts.Events.Navigate;
5
- const EventRendered = Opts.Events.Rendered;
6
- const FireNavigate = (Detail) => {
7
- window.dispatchEvent(new CustomEvent(EventNavigate, { detail: Detail }));
8
- };
9
- const FireRendered = (Detail) => {
10
- window.dispatchEvent(new CustomEvent(EventRendered, { detail: Detail }));
11
- };
12
- let LastUrl = window.location.href;
13
- let NavSeq = 0;
14
- let Disposed = false;
15
- const OnUrlMaybeChanged = (Cause) => {
16
- if (Disposed) return;
17
- const Url = window.location.href;
18
- if (Url === LastUrl) return;
19
- const From = LastUrl;
20
- LastUrl = Url;
21
- const Seq = ++NavSeq;
22
- FireNavigate({ Seq, From, To: Url, Cause });
23
- void (async () => {
24
- const Root = Opts.Root();
25
- if (!Root) {
26
- if (Seq !== NavSeq || Disposed) return;
27
- FireRendered({ Seq, Url, Ok: true });
28
- return;
29
- }
30
- const Ok = await WaitForDomMostlyStable({
31
- Root,
32
- StableForMs: Opts.StableForMs,
33
- SampleWindowMs: Opts.SampleWindowMs,
34
- Threshold: Opts.Threshold,
35
- TimeoutMs: Opts.TimeoutMs,
36
- Ignore: Opts.IgnoreMutation
37
- });
38
- if (Seq !== NavSeq || Disposed) return;
39
- FireRendered({ Seq, Url, Ok });
40
- })();
41
- };
42
- const PatchHistory = (MethodName) => {
43
- const Original = history[MethodName].bind(history);
44
- const Patched = (...Args) => {
45
- const Ret = Original(...Args);
46
- queueMicrotask(() => OnUrlMaybeChanged(MethodName));
47
- return Ret;
48
- };
49
- Object.defineProperty(history, MethodName, {
50
- value: Patched,
51
- configurable: true,
52
- writable: true
53
- });
54
- };
55
- PatchHistory("pushState");
56
- PatchHistory("replaceState");
57
- const OnPopState = () => OnUrlMaybeChanged("popstate");
58
- window.addEventListener("popstate", OnPopState);
59
- const OnHashChange = () => OnUrlMaybeChanged("hashchange");
60
- if (Opts.WatchHashChange) window.addEventListener("hashchange", OnHashChange);
61
- queueMicrotask(() => {
62
- if (Disposed) return;
63
- const Seq = ++NavSeq;
64
- FireNavigate({ Seq, From: null, To: window.location.href, Cause: "init" });
65
- void (async () => {
66
- const Root = Opts.Root();
67
- if (!Root) {
68
- if (Seq !== NavSeq || Disposed) return;
69
- FireRendered({ Seq, Url: window.location.href, Ok: true });
70
- return;
71
- }
72
- const Ok = await WaitForDomMostlyStable({
73
- Root,
74
- StableForMs: Opts.StableForMs,
75
- SampleWindowMs: Opts.SampleWindowMs,
76
- Threshold: Opts.Threshold,
77
- TimeoutMs: Opts.TimeoutMs,
78
- Ignore: Opts.IgnoreMutation
79
- });
80
- if (Seq !== NavSeq || Disposed) return;
81
- FireRendered({ Seq, Url: window.location.href, Ok });
82
- })();
83
- });
84
- return () => {
85
- Disposed = true;
86
- window.removeEventListener("popstate", OnPopState);
87
- if (Opts.WatchHashChange) window.removeEventListener("hashchange", OnHashChange);
88
- };
89
- }
90
- function DefaultIgnoreMutation(Mutation) {
91
- if (Mutation.type === "attributes") {
92
- const Name = Mutation.attributeName ?? "";
93
- if (Name === "class" || Name === "style") return true;
94
- if (Name.startsWith("aria-") || Name.startsWith("data-")) return true;
95
- }
96
- return false;
97
- }
98
- function NormalizeOptions(Options) {
99
- return {
100
- Root: Options.Root ?? (() => document.querySelector("#app") ?? document.body),
101
- StableForMs: Options.StableForMs ?? 900,
102
- SampleWindowMs: Options.SampleWindowMs ?? 900,
103
- Threshold: Options.Threshold ?? 3,
104
- TimeoutMs: Options.TimeoutMs ?? 12e3,
105
- IgnoreMutation: Options.IgnoreMutation ?? DefaultIgnoreMutation,
106
- WatchHashChange: Options.WatchHashChange ?? true,
107
- Events: {
108
- Navigate: Options.Events?.Navigate ?? "SpaNavigate",
109
- Rendered: Options.Events?.Rendered ?? "SpaRendered"
110
- }
111
- };
112
- }
113
- async function WaitForDomMostlyStable(Opts) {
114
- const Events = [];
115
- let LastAboveAt = performance.now();
116
- let Done = false;
117
- const Observer = new MutationObserver((List) => {
118
- const Now = performance.now();
119
- for (const M of List) {
120
- if (Opts.Ignore?.(M)) continue;
121
- let Score = 1;
122
- if (M.type === "childList") Score = 2;
123
- Events.push({ T: Now, Score });
124
- }
125
- const Cutoff = Now - Opts.SampleWindowMs;
126
- while (Events.length && Events[0].T < Cutoff) Events.shift();
127
- const WindowScore = Events.reduce((Sum, E) => Sum + E.Score, 0);
128
- if (WindowScore > Opts.Threshold) LastAboveAt = Now;
129
- });
130
- Observer.observe(Opts.Root, {
131
- subtree: true,
132
- childList: true,
133
- attributes: true,
134
- characterData: true
135
- });
136
- const Start = performance.now();
137
- return await new Promise((Resolve) => {
138
- const Tick = () => {
139
- if (Done) return;
140
- const Now = performance.now();
141
- if (Now - LastAboveAt >= Opts.StableForMs) {
142
- Done = true;
143
- Observer.disconnect();
144
- Resolve(true);
145
- return;
146
- }
147
- if (Now - Start >= Opts.TimeoutMs) {
148
- Done = true;
149
- Observer.disconnect();
150
- Resolve(false);
151
- return;
152
- }
153
- setTimeout(Tick, 100);
154
- };
155
- setTimeout(Tick, 0);
156
- });
157
- }
158
-
159
- // sources/src/sort.ts
160
- function CreateSortWorkerURL() {
161
- const WorkerCode = `
162
- self.onmessage = (e) => {
163
- const { entries, jobId } = e.data;
164
- // entries: Array<[string, number]>
165
- // \uB0B4\uB9BC\uCC28\uC21C \uC815\uB82C
166
- entries.sort((a, b) => b[1] - a[1]);
167
- self.postMessage({ jobId, sorted: entries });
168
- };
169
- `;
170
- return URL.createObjectURL(new Blob([WorkerCode], { type: "text/javascript" }));
171
- }
172
- function MakeWorkerPool(Size) {
173
- const Url = CreateSortWorkerURL();
174
- const Workers = Array.from({ length: Size }, () => new Worker(Url));
175
- return {
176
- Workers,
177
- dispose() {
178
- Workers.forEach((W) => W.terminate());
179
- URL.revokeObjectURL(Url);
180
- }
181
- };
182
- }
183
- function CollectDataVAttributes(Root = document) {
184
- const Counts = /* @__PURE__ */ Object.create(null);
185
- const Walker = Root.createTreeWalker(
186
- Root.documentElement || Root,
187
- NodeFilter.SHOW_ELEMENT
188
- );
189
- let Node = Walker.currentNode;
190
- while (Node) {
191
- if (Node instanceof Element) {
192
- for (const Attr of Node.attributes) {
193
- const Name = Attr.name;
194
- if (Name.startsWith("data-v-")) {
195
- Counts[Name] = (Counts[Name] || 0) + 1;
196
- }
197
- }
198
- }
199
- Node = Walker.nextNode();
200
- }
201
- return Counts;
202
- }
203
- function MergeSortedChunks(Chunks) {
204
- const Heap = [];
205
- function Push(Item) {
206
- Heap.push(Item);
207
- let I = Heap.length - 1;
208
- while (I > 0) {
209
- const P = I - 1 >> 1;
210
- if (Heap[P].count >= Heap[I].count) break;
211
- [Heap[P], Heap[I]] = [Heap[I], Heap[P]];
212
- I = P;
213
- }
214
- }
215
- ;
216
- function Pop() {
217
- const Top = Heap[0];
218
- const Last = Heap.pop();
219
- if (Heap.length) {
220
- Heap[0] = Last;
221
- let I = 0;
222
- while (true) {
223
- const L = I * 2 + 1;
224
- const R = L + 1;
225
- let M = I;
226
- if (L < Heap.length && Heap[L].count > Heap[M].count) M = L;
227
- if (R < Heap.length && Heap[R].count > Heap[M].count) M = R;
228
- if (M === I) break;
229
- [Heap[I], Heap[M]] = [Heap[M], Heap[I]];
230
- I = M;
231
- }
232
- }
233
- return Top;
234
- }
235
- for (let C = 0; C < Chunks.length; C++) {
236
- const Arr = Chunks[C];
237
- if (Arr && Arr.length) {
238
- const [Attr, Count] = Arr[0];
239
- Push({ Count, Attr, ChunkIndex: C, IndexInChunk: 0 });
240
- }
241
- }
242
- const Out = [];
243
- while (Heap.length) {
244
- const { Attr, Count, ChunkIndex, IndexInChunk } = Pop();
245
- Out.push([Attr, Count]);
246
- const NextIndex = IndexInChunk + 1;
247
- const Arr = Chunks[ChunkIndex];
248
- if (NextIndex < Arr.length) {
249
- const [NAttr, NCount] = Arr[NextIndex];
250
- Push({ Count: NCount, Attr: NAttr, ChunkIndex, IndexInChunk: NextIndex });
251
- }
252
- }
253
- return Out;
254
- }
255
- async function RankCountsWithWorkersParallel(Counts) {
256
- const Entries = Object.entries(Counts);
257
- const Hc = Math.max(1, navigator.hardwareConcurrency || 1);
258
- const WorkerCount = Math.min(8, Math.max(1, Hc - 1));
259
- const ShouldParallel = Entries.length >= 5e3 && WorkerCount > 1;
260
- const ActualWorkers = ShouldParallel ? WorkerCount : 1;
261
- const Pool = MakeWorkerPool(ActualWorkers);
262
- try {
263
- const Chunks = Array.from({ length: ActualWorkers }, () => []);
264
- for (let I = 0; I < Entries.length; I++) {
265
- Chunks[I % ActualWorkers].push(Entries[I]);
266
- }
267
- const SortedChunks = await Promise.all(
268
- Chunks.map((ChunkEntries, Idx) => {
269
- return new Promise((Resolve, Reject) => {
270
- const Worker2 = Pool.Workers[Idx];
271
- const JobId = Idx + ":" + Date.now();
272
- const OnMsg = (E) => {
273
- if (E.data?.jobId !== JobId) return;
274
- Worker2.removeEventListener("message", OnMsg);
275
- Worker2.removeEventListener("error", OnErr);
276
- Resolve(E.data.sorted);
277
- };
278
- const OnErr = (Err) => {
279
- Worker2.removeEventListener("message", OnMsg);
280
- Worker2.removeEventListener("error", OnErr);
281
- Reject(Err);
282
- };
283
- Worker2.addEventListener("message", OnMsg);
284
- Worker2.addEventListener("error", OnErr);
285
- Worker2.postMessage({ entries: ChunkEntries, jobId: JobId });
286
- });
287
- })
288
- );
289
- const Merged = SortedChunks.length === 1 ? SortedChunks[0] : MergeSortedChunks(SortedChunks);
290
- return { Result: Merged, TotalKeys: Merged.length, WorkerCount: ActualWorkers, HardwareConcurrency: Hc };
291
- } finally {
292
- Pool.dispose();
293
- }
294
- }
295
-
296
- // sources/src/index.ts
297
- var Win = typeof unsafeWindow !== "undefined" ? unsafeWindow : window;
298
- function RunNamuLinkUserscript(BrowserWindow, UserscriptName = "NamuLink") {
299
- const ProtectedFunctionPrototypeToString = BrowserWindow.Function.prototype.toString;
300
- let PowerLinkGenerationPositiveRegExps = [[
301
- /for *\( *; *; *\) *switch *\( *_[a-z0-9]+\[_[a-z0-9]+\([a-z0-9]+\)\] *=_[a-z0-9]+/,
302
- /_[a-z0-9]+\[('|")[A-Z]+('|")\]\)\(\[ *\]\)/,
303
- /0x[a-z0-9]+ *\) *; *case/
304
- ], [
305
- /; *return *this\[_0x[a-z0-9]+\( *0x[0-9a-z]+ *\)/,
306
- /; *if *\( *_0x[a-z0-9]+ *&& *\( *_0x[a-z0-9]+ *= *_0x[a-z0-9]+/,
307
- /\) *, *void *\( *this *\[ *_0x[a-z0-9]+\( *0x[0-9a-z]+ *\) *\] *= *_0x[a-z0-9]+ *\[/
308
- ]];
309
- BrowserWindow.Function.prototype.bind = new Proxy(BrowserWindow.Function.prototype.bind, {
310
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
311
- apply(Target, ThisArg, Args) {
312
- let StringifiedFunc = Reflect.apply(ProtectedFunctionPrototypeToString, ThisArg, Args);
313
- if (PowerLinkGenerationPositiveRegExps.filter((PowerLinkGenerationPositiveRegExp) => PowerLinkGenerationPositiveRegExp.filter((Index) => Index.test(StringifiedFunc)).length >= 3).length === 1) {
314
- console.debug(`[${UserscriptName}]: Function.prototype.bind:`, ThisArg);
315
- return Reflect.apply(Target, () => {
316
- }, []);
317
- }
318
- return Reflect.apply(Target, ThisArg, Args);
319
- }
320
- });
321
- let PowerLinkGenerationSkeletionPositiveRegExps = [[
322
- /\( *\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\]\(\); *}/,
323
- /\( *\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\]\(\); *}/
324
- ], [
325
- /\( *\) *=> *{ *var _0x[a-z0-9]+ *= *_0x[a-z0-9]+ *; *if *\( *this\[ *_0x[a-z0-9]+ *\( *0x[0-9a-f]+ *\) *\] *\) *return *clearTimeout/,
326
- /\( *0x[0-9a-f]+ *\) *\] *\) *, *void *\( *this\[ *_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\] *= *void *\([x0-9a-f*+-]+ *\) *\) *; *this\[_0x[a-z0-9]+\( *0x[0-9a-f]+ *\) *\] *\(\) *;/
327
- ]];
328
- function GetParents(Ele) {
329
- let Parents = [];
330
- while (Ele.parentElement) {
331
- Parents.push(Ele.parentElement);
332
- Ele = Ele.parentElement;
333
- }
334
- return Parents;
335
- }
336
- const HidePowerLinkPlaceholderWithAccount = () => {
337
- let AdContainers = [...document.querySelectorAll('div[class*=" "] div[class]')].filter((AdContainer) => AdContainer instanceof HTMLElement);
338
- AdContainers = AdContainers.filter((AdContainer) => {
339
- let AdContainerPaddingLeft = Number(getComputedStyle(AdContainer).getPropertyValue("padding-left").replaceAll("px", ""));
340
- let AdContainerPaddingRight = Number(getComputedStyle(AdContainer).getPropertyValue("padding-right").replaceAll("px", ""));
341
- let AdContainerPaddingTop = Number(getComputedStyle(AdContainer).getPropertyValue("padding-top").replaceAll("px", ""));
342
- let AdContainerPaddingBottom = Number(getComputedStyle(AdContainer).getPropertyValue("padding-bottom").replaceAll("px", ""));
343
- return AdContainerPaddingLeft > 5 && AdContainerPaddingRight > 5 && AdContainerPaddingTop > 5 && AdContainerPaddingBottom > 5;
344
- });
345
- AdContainers = AdContainers.filter((AdContainer) => {
346
- return [...AdContainer.querySelectorAll("*")].filter((Ele) => Ele instanceof HTMLElement && getComputedStyle(Ele).getPropertyValue("animation-timing-function") === "ease-in-out").length >= 3;
347
- });
348
- AdContainers = AdContainers.filter((AdContainer) => GetParents(AdContainer).some((Parent) => Number(getComputedStyle(Parent).getPropertyValue("margin-top").replaceAll("px", "")) > 10));
349
- AdContainers = AdContainers.filter((AdContainer) => AdContainer.innerText.length < 1e3);
350
- AdContainers = AdContainers.filter((AdContainer) => [...AdContainer.querySelectorAll('*[href="/RecentChanges"]')].filter((Ele) => Ele instanceof HTMLElement && getComputedStyle(Ele).getPropertyValue("display") !== "none").length === 0);
351
- AdContainers = AdContainers.filter((AdContainer) => !AdContainer.innerText.includes((new URL(location.href).searchParams.get("from") || "") + "\uC5D0\uC11C \uB118\uC5B4\uC634"));
352
- AdContainers = AdContainers.filter((AdContainer) => !/\[[0-9]+\] .+/.test(AdContainer.innerText));
353
- AdContainers.forEach((Ele) => Ele.setAttribute("style", "display: none !important; visibility: hidden !important;"));
354
- };
355
- BrowserWindow.setTimeout = new Proxy(BrowserWindow.setTimeout, {
356
- apply(Target, ThisArg, Args) {
357
- let StringifiedFunc = Reflect.apply(ProtectedFunctionPrototypeToString, Args[0], Args);
358
- if (PowerLinkGenerationSkeletionPositiveRegExps.filter((PowerLinkGenerationSkeletionPositiveRegExp) => PowerLinkGenerationSkeletionPositiveRegExp.filter((Index) => Index.test(StringifiedFunc)).length >= 1).length === 1) {
359
- console.debug(`[${UserscriptName}]: setTimeout:`, Args[0]);
360
- return Reflect.apply(Target, ThisArg, [HidePowerLinkPlaceholderWithAccount, 1500]);
361
- }
362
- return Reflect.apply(Target, ThisArg, Args);
363
- }
364
- });
365
- if (document.readyState === "loading") {
366
- window.addEventListener("DOMContentLoaded", () => {
367
- InstallSpaNavigationBridge({
368
- Root: () => document.getElementById("#app"),
369
- StableForMs: 900,
370
- SampleWindowMs: 900,
371
- Threshold: 3,
372
- TimeoutMs: 12e3,
373
- IgnoreMutation: DefaultIgnoreMutation,
374
- WatchHashChange: true
375
- });
376
- });
377
- } else {
378
- window.addEventListener("DOMContentLoaded", () => {
379
- InstallSpaNavigationBridge({
380
- Root: () => document.getElementById("#app"),
381
- StableForMs: 900,
382
- SampleWindowMs: 900,
383
- Threshold: 3,
384
- TimeoutMs: 12e3,
385
- IgnoreMutation: DefaultIgnoreMutation,
386
- WatchHashChange: true
387
- });
388
- });
389
- }
390
- const Handler = async () => {
391
- let HTMLEle = CollectDataVAttributes(document);
392
- const { Result, TotalKeys, WorkerCount, HardwareConcurrency } = await RankCountsWithWorkersParallel(HTMLEle);
393
- let TargetedAttrsDOMs = [];
394
- Result.filter(([, Count]) => Count <= 30).forEach(([Attr, Count]) => {
395
- TargetedAttrsDOMs.push(...[...document.querySelectorAll(`[${Attr}]`)].filter((El) => El instanceof HTMLElement));
396
- });
397
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => getComputedStyle(El).getPropertyValue("display") === "flex");
398
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => [...El.querySelectorAll("*")].some((Child) => Child instanceof HTMLElement && typeof Child.click === "function"));
399
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => [...El.querySelectorAll("*")].filter((Child) => Child instanceof HTMLElement && Child.getBoundingClientRect().bottom - Child.getBoundingClientRect().top > 100 && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 100).length <= 50);
400
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => {
401
- let Count = [...El.querySelectorAll("*")].filter((Child) => Child.getBoundingClientRect().bottom - Child.getBoundingClientRect().top > 25 && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 25 && (Child instanceof SVGPathElement && Child.getAttribute("d") !== null) || Child instanceof HTMLImageElement && Child.src.includes("//i.namu.wiki/i/")).length;
402
- return 1 <= Count && Count <= 6;
403
- });
404
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => [...El.querySelectorAll("*")].some((Child) => Child instanceof HTMLElement && getComputedStyle(Child, "::after").getPropertyValue("content").includes(":") && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 20) === false);
405
- TargetedAttrsDOMs = TargetedAttrsDOMs.filter((El) => [...El.querySelectorAll("*")].every((Child) => Child instanceof HTMLElement && !new Date(Child.getHTML()).getTime()));
406
- console.debug(`[${UserscriptName}]`, TargetedAttrsDOMs);
407
- TargetedAttrsDOMs.forEach((El) => {
408
- setInterval(() => {
409
- El.setAttribute("style", "display: none !important; visibility: hidden !important;");
410
- }, 250);
411
- });
412
- };
413
- window.addEventListener("SpaRendered", () => setTimeout(Handler, 2500));
414
- window.addEventListener("SpaRendered", Handler);
415
- }
416
- RunNamuLinkUserscript(Win);
417
- export {
418
- RunNamuLinkUserscript
419
- };
420
- /*!
421
- * @license MPL-2.0
422
- * This Source Code Form is subject to the terms of the Mozilla Public
423
- * License, v. 2.0. If a copy of the MPL was not distributed with this
424
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
425
- *
426
- * Contributors:
427
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
428
- */
429
- //# sourceMappingURL=interface.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../sources/src/spa.ts", "../sources/src/sort.ts", "../sources/src/index.ts"],
4
- "sourcesContent": ["/*!\n * @license MPL-2.0\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n *\n * Contributors:\n * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.\n */\n\ntype SpaNavigateCause =\n | 'init'\n | 'pushState'\n | 'replaceState'\n | 'popstate'\n | 'hashchange'\n\nexport type SpaNavigateDetail = {\n Seq: number\n From: string | null\n To: string\n Cause: SpaNavigateCause\n}\n\nexport type SpaRenderedDetail = {\n Seq: number\n Url: string\n Ok: boolean\n}\n\nexport type IgnoreMutation = (Mutation: MutationRecord) => boolean\n\nexport type SpaBridgeOptions = {\n Root?: () => Node | null\n StableForMs?: number\n SampleWindowMs?: number\n Threshold?: number\n TimeoutMs?: number\n IgnoreMutation?: IgnoreMutation\n WatchHashChange?: boolean\n Events?: {\n Navigate?: 'SpaNavigate'\n Rendered?: 'SpaRendered'\n }\n}\n\ntype WaitStableOptions = {\n Root: Node\n StableForMs: number\n SampleWindowMs: number\n Threshold: number\n TimeoutMs: number\n Ignore?: IgnoreMutation\n}\n\n/**\n * SPA \uB77C\uC6B0\uD305(URL \uBCC0\uACBD)\uC744 \uAC10\uC9C0\uD574 \uCEE4\uC2A4\uD140 \uC774\uBCA4\uD2B8\uB97C \uBC1C\uD589\uD558\uACE0,\n * DOM\uC774 \uCDA9\uBD84\uD788 \uC548\uC815\uD654\uB418\uBA74 'Rendered' \uC774\uBCA4\uD2B8\uAE4C\uC9C0 \uBC1C\uD589\uD558\uB294 \uBE0C\uB9BF\uC9C0\n *\n * Events (PascalCase):\n * - 'SpaNavigate' => CustomEvent<SpaNavigateDetail>\n * - 'SpaRendered' => CustomEvent<SpaRenderedDetail>\n */\nexport function InstallSpaNavigationBridge(Options: SpaBridgeOptions = {}): () => void {\n\n const Opts = NormalizeOptions(Options)\n\n const EventNavigate = Opts.Events.Navigate\n const EventRendered = Opts.Events.Rendered\n\n const FireNavigate = (Detail: SpaNavigateDetail) => {\n window.dispatchEvent(new CustomEvent<SpaNavigateDetail>(EventNavigate, { detail: Detail }))\n }\n\n const FireRendered = (Detail: SpaRenderedDetail) => {\n window.dispatchEvent(new CustomEvent<SpaRenderedDetail>(EventRendered, { detail: Detail }))\n }\n\n let LastUrl = window.location.href\n let NavSeq = 0\n let Disposed = false\n\n const OnUrlMaybeChanged = (Cause: SpaNavigateCause) => {\n if (Disposed) return\n\n const Url = window.location.href\n if (Url === LastUrl) return\n\n const From = LastUrl\n LastUrl = Url\n\n const Seq = ++NavSeq\n FireNavigate({ Seq, From, To: Url, Cause })\n\n void (async () => {\n const Root = Opts.Root()\n if (!Root) {\n if (Seq !== NavSeq || Disposed) return\n FireRendered({ Seq, Url, Ok: true })\n return\n }\n\n const Ok = await WaitForDomMostlyStable({\n Root: Root,\n StableForMs: Opts.StableForMs,\n SampleWindowMs: Opts.SampleWindowMs,\n Threshold: Opts.Threshold,\n TimeoutMs: Opts.TimeoutMs,\n Ignore: Opts.IgnoreMutation,\n })\n\n if (Seq !== NavSeq || Disposed) return\n FireRendered({ Seq, Url, Ok })\n })()\n }\n\n const PatchHistory = (MethodName: 'pushState' | 'replaceState') => {\n const Original = history[MethodName].bind(history)\n\n const Patched = (...Args: Parameters<History['pushState']>): ReturnType<History['pushState']> => {\n const Ret = Original(...Args)\n queueMicrotask(() => OnUrlMaybeChanged(MethodName))\n return Ret\n }\n\n Object.defineProperty(history, MethodName, {\n value: Patched,\n configurable: true,\n writable: true,\n })\n }\n\n PatchHistory('pushState')\n PatchHistory('replaceState')\n\n const OnPopState = () => OnUrlMaybeChanged('popstate')\n window.addEventListener('popstate', OnPopState)\n\n const OnHashChange = () => OnUrlMaybeChanged('hashchange')\n if (Opts.WatchHashChange) window.addEventListener('hashchange', OnHashChange)\n\n queueMicrotask(() => {\n if (Disposed) return\n\n const Seq = ++NavSeq\n FireNavigate({ Seq, From: null, To: window.location.href, Cause: 'init' })\n\n void (async () => {\n const Root = Opts.Root()\n if (!Root) {\n if (Seq !== NavSeq || Disposed) return\n FireRendered({ Seq, Url: window.location.href, Ok: true })\n return\n }\n\n const Ok = await WaitForDomMostlyStable({\n Root: Root,\n StableForMs: Opts.StableForMs,\n SampleWindowMs: Opts.SampleWindowMs,\n Threshold: Opts.Threshold,\n TimeoutMs: Opts.TimeoutMs,\n Ignore: Opts.IgnoreMutation,\n })\n\n if (Seq !== NavSeq || Disposed) return\n FireRendered({ Seq, Url: window.location.href, Ok: Ok })\n })()\n })\n\n return () => {\n Disposed = true\n window.removeEventListener('popstate', OnPopState)\n if (Opts.WatchHashChange) window.removeEventListener('hashchange', OnHashChange)\n }\n}\n\nexport function DefaultIgnoreMutation(Mutation: MutationRecord): boolean {\n if (Mutation.type === 'attributes') {\n const Name = Mutation.attributeName ?? ''\n if (Name === 'class' || Name === 'style') return true\n if (Name.startsWith('aria-') || Name.startsWith('data-')) return true\n }\n return false\n}\n\nfunction NormalizeOptions(Options: SpaBridgeOptions) {\n return {\n Root: Options.Root ?? (() => document.querySelector('#app') ?? document.body),\n StableForMs: Options.StableForMs ?? 900,\n SampleWindowMs: Options.SampleWindowMs ?? 900,\n Threshold: Options.Threshold ?? 3,\n TimeoutMs: Options.TimeoutMs ?? 12000,\n IgnoreMutation: Options.IgnoreMutation ?? DefaultIgnoreMutation,\n WatchHashChange: Options.WatchHashChange ?? true,\n Events: {\n Navigate: Options.Events?.Navigate ?? 'SpaNavigate',\n Rendered: Options.Events?.Rendered ?? 'SpaRendered',\n },\n }\n}\n\nasync function WaitForDomMostlyStable(Opts: WaitStableOptions): Promise<boolean> {\n const Events: Array<{ T: number; Score: number }> = []\n let LastAboveAt = performance.now()\n let Done = false\n\n const Observer = new MutationObserver((List) => {\n const Now = performance.now()\n\n for (const M of List) {\n if (Opts.Ignore?.(M)) continue\n\n let Score = 1\n if (M.type === 'childList') Score = 2\n Events.push({ T: Now, Score })\n }\n\n const Cutoff = Now - Opts.SampleWindowMs\n while (Events.length && Events[0].T < Cutoff) Events.shift()\n\n const WindowScore = Events.reduce((Sum, E) => Sum + E.Score, 0)\n if (WindowScore > Opts.Threshold) LastAboveAt = Now\n })\n\n Observer.observe(Opts.Root, {\n subtree: true,\n childList: true,\n attributes: true,\n characterData: true,\n })\n\n const Start = performance.now()\n\n return await new Promise<boolean>((Resolve) => {\n const Tick = () => {\n if (Done) return\n\n const Now = performance.now()\n\n if (Now - LastAboveAt >= Opts.StableForMs) {\n Done = true\n Observer.disconnect()\n Resolve(true)\n return\n }\n\n if (Now - Start >= Opts.TimeoutMs) {\n Done = true\n Observer.disconnect()\n Resolve(false)\n return\n }\n\n setTimeout(Tick, 100)\n }\n\n setTimeout(Tick, 0)\n })\n}", "export function CreateSortWorkerURL() {\n const WorkerCode = `\nself.onmessage = (e) => {\n const { entries, jobId } = e.data;\n // entries: Array<[string, number]>\n // \uB0B4\uB9BC\uCC28\uC21C \uC815\uB82C\n entries.sort((a, b) => b[1] - a[1]);\n self.postMessage({ jobId, sorted: entries });\n};\n`\n return URL.createObjectURL(new Blob([WorkerCode], { type: 'text/javascript' }))\n}\n\nexport function MakeWorkerPool(Size: number) {\n const Url = CreateSortWorkerURL()\n const Workers = Array.from({ length: Size }, () => new Worker(Url))\n return {\n Workers,\n dispose() {\n Workers.forEach(W => W.terminate())\n URL.revokeObjectURL(Url)\n }\n }\n}\n\nexport function CollectDataVAttributes(Root = document): Record<string, number> {\n const Counts = Object.create(null)\n\n const Walker = Root.createTreeWalker(\n Root.documentElement || Root,\n NodeFilter.SHOW_ELEMENT\n )\n\n let Node = Walker.currentNode\n while (Node) {\n if (Node instanceof Element) {\n for (const Attr of Node.attributes) {\n const Name = Attr.name\n if (Name.startsWith('data-v-')) {\n Counts[Name] = (Counts[Name] || 0) + 1\n }\n }\n }\n Node = Walker.nextNode()\n }\n return Counts\n}\n\nexport function MergeSortedChunks(Chunks: Array<Array<[string, number]>>): Array<[string, number]> {\n // chunks: Array<Array<[string, number]>> \uAC01\uAC01 \uB0B4\uB9BC\uCC28\uC21C\n // \uACB0\uACFC: \uC804\uCCB4 \uB0B4\uB9BC\uCC28\uC21C\n\n // \uAC04\uB2E8\uD55C max-heap (count \uAE30\uC900)\n const Heap = []\n function Push(Item) {\n Heap.push(Item)\n let I = Heap.length - 1\n while (I > 0) {\n const P = (I - 1) >> 1\n if (Heap[P].count >= Heap[I].count) break\n [Heap[P], Heap[I]] = [Heap[I], Heap[P]]\n I = P\n }\n };\n function Pop() {\n const Top = Heap[0]\n const Last = Heap.pop()\n if (Heap.length) {\n Heap[0] = Last\n let I = 0\n while (true) {\n const L = I * 2 + 1\n const R = L + 1\n let M = I\n if (L < Heap.length && Heap[L].count > Heap[M].count) M = L\n if (R < Heap.length && Heap[R].count > Heap[M].count) M = R\n if (M === I) break\n [Heap[I], Heap[M]] = [Heap[M], Heap[I]]\n I = M\n }\n }\n return Top\n }\n\n for (let C = 0; C < Chunks.length; C++) {\n const Arr = Chunks[C]\n if (Arr && Arr.length) {\n const [Attr, Count] = Arr[0]\n Push({ Count, Attr, ChunkIndex: C, IndexInChunk: 0 })\n }\n }\n\n const Out = []\n while (Heap.length) {\n const { Attr, Count, ChunkIndex, IndexInChunk } = Pop()\n Out.push([Attr, Count])\n\n const NextIndex = IndexInChunk + 1\n const Arr = Chunks[ChunkIndex]\n if (NextIndex < Arr.length) {\n const [NAttr, NCount] = Arr[NextIndex]\n Push({ Count: NCount, Attr: NAttr, ChunkIndex, IndexInChunk: NextIndex })\n }\n }\n\n return Out\n}\n\nexport async function RankCountsWithWorkersParallel(Counts: Record<string, number>) {\n const Entries = Object.entries(Counts) // [attr, count][]\n\n // \uB17C\uB9AC \uCF54\uC5B4 \uC218 \uAE30\uBC18 \uC6CC\uCEE4 \uAC1C\uC218 \uACB0\uC815\n // - \uB108\uBB34 \uB9CE\uC774 \uB9CC\uB4E4\uBA74 \uC624\uD788\uB824 \uC5ED\uD6A8\uACFC\uB77C \uC0C1\uD55C\uC744 \uB460\n const Hc = Math.max(1, navigator.hardwareConcurrency || 1)\n const WorkerCount = Math.min(8, Math.max(1, Hc - 1))\n\n // entries\uAC00 \uC801\uC73C\uBA74 \uBCD1\uB82C\uD654 \uC774\uB4DD\uC774 \uAC70\uC758 \uC5C6\uC74C \u2192 1\uAC1C\uB85C\n const ShouldParallel = Entries.length >= 5000 && WorkerCount > 1\n const ActualWorkers = ShouldParallel ? WorkerCount : 1\n const Pool = MakeWorkerPool(ActualWorkers)\n\n try {\n // chunks \uBD84\uD560\n const Chunks = Array.from({ length: ActualWorkers }, () => [])\n for (let I = 0; I < Entries.length; I++) {\n Chunks[I % ActualWorkers].push(Entries[I])\n }\n\n // \uAC01 \uC6CC\uCEE4\uC5D0 \uC815\uB82C \uC694\uCCAD\n const SortedChunks = await Promise.all(\n Chunks.map((ChunkEntries, Idx) => {\n return new Promise<Array<[string, number]>>((Resolve, Reject) => {\n const Worker = Pool.Workers[Idx]\n const JobId = Idx + ':' + Date.now()\n\n const OnMsg = (E) => {\n if (E.data?.jobId !== JobId) return\n Worker.removeEventListener('message', OnMsg)\n Worker.removeEventListener('error', OnErr)\n Resolve(E.data.sorted)\n }\n const OnErr = (Err) => {\n Worker.removeEventListener('message', OnMsg)\n Worker.removeEventListener('error', OnErr)\n Reject(Err)\n }\n\n Worker.addEventListener('message', OnMsg)\n Worker.addEventListener('error', OnErr)\n Worker.postMessage({ entries: ChunkEntries, jobId: JobId })\n })\n })\n )\n // \uBCD1\uD569\uD574\uC11C \uC804\uCCB4 \uC21C\uC704 \uC0DD\uC131\n const Merged = (SortedChunks.length === 1)\n ? SortedChunks[0]\n : MergeSortedChunks(SortedChunks)\n\n return { Result: Merged, TotalKeys: Merged.length, WorkerCount: ActualWorkers, HardwareConcurrency: Hc }\n } finally {\n Pool.dispose()\n }\n}", "/*!\n * @license MPL-2.0\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n *\n * Contributors:\n * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.\n */\n\ntype unsafeWindow = typeof window\n// eslint-disable-next-line @typescript-eslint/naming-convention\ndeclare const unsafeWindow: unsafeWindow\nimport * as SPA from './spa.js'\nimport * as Sort from './sort.js'\n\nconst Win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window\n\nexport function RunNamuLinkUserscript(BrowserWindow: typeof window, UserscriptName: string = 'NamuLink'): void {\n const ProtectedFunctionPrototypeToString = BrowserWindow.Function.prototype.toString\n\n let PowerLinkGenerationPositiveRegExps: RegExp[][] = [[\n /for *\\( *; *; *\\) *switch *\\( *_[a-z0-9]+\\[_[a-z0-9]+\\([a-z0-9]+\\)\\] *=_[a-z0-9]+/,\n /_[a-z0-9]+\\[('|\")[A-Z]+('|\")\\]\\)\\(\\[ *\\]\\)/,\n /0x[a-z0-9]+ *\\) *; *case/\n ], [\n /; *return *this\\[_0x[a-z0-9]+\\( *0x[0-9a-z]+ *\\)/,\n /; *if *\\( *_0x[a-z0-9]+ *&& *\\( *_0x[a-z0-9]+ *= *_0x[a-z0-9]+/,\n /\\) *, *void *\\( *this *\\[ *_0x[a-z0-9]+\\( *0x[0-9a-z]+ *\\) *\\] *= *_0x[a-z0-9]+ *\\[/\n ]]\n\n BrowserWindow.Function.prototype.bind = new Proxy(BrowserWindow.Function.prototype.bind, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n apply(Target: typeof Function.prototype.bind, ThisArg: Function, Args: Parameters<typeof Function.prototype.bind>) {\n let StringifiedFunc = Reflect.apply(ProtectedFunctionPrototypeToString, ThisArg, Args) as string\n if (PowerLinkGenerationPositiveRegExps.filter(PowerLinkGenerationPositiveRegExp => PowerLinkGenerationPositiveRegExp.filter(Index => Index.test(StringifiedFunc)).length >= 3).length === 1) {\n console.debug(`[${UserscriptName}]: Function.prototype.bind:`, ThisArg)\n return Reflect.apply(Target, () => {}, [])\n }\n return Reflect.apply(Target, ThisArg, Args)\n }\n })\n\n let PowerLinkGenerationSkeletionPositiveRegExps: RegExp[][] = [[\n /\\( *\\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\\[ *_0x[a-z0-9]+\\( *0x[0-9a-f]+ *\\) *\\]\\(\\); *}/,\n /\\( *\\) *=> *{ *var *_0x[0-9a-z]+ *= *a0_0x[0-9a-f]+ *; *this\\[ *_0x[a-z0-9]+\\( *0x[0-9a-f]+ *\\) *\\]\\(\\); *}/\n ], [\n /\\( *\\) *=> *{ *var _0x[a-z0-9]+ *= *_0x[a-z0-9]+ *; *if *\\( *this\\[ *_0x[a-z0-9]+ *\\( *0x[0-9a-f]+ *\\) *\\] *\\) *return *clearTimeout/,\n /\\( *0x[0-9a-f]+ *\\) *\\] *\\) *, *void *\\( *this\\[ *_0x[a-z0-9]+\\( *0x[0-9a-f]+ *\\) *\\] *= *void *\\([x0-9a-f*+-]+ *\\) *\\) *; *this\\[_0x[a-z0-9]+\\( *0x[0-9a-f]+ *\\) *\\] *\\(\\) *;/\n ]]\n\n function GetParents(Ele: HTMLElement) {\n let Parents: HTMLElement[] = []\n while (Ele.parentElement) {\n Parents.push(Ele.parentElement)\n Ele = Ele.parentElement\n }\n return Parents\n }\n\n const HidePowerLinkPlaceholderWithAccount = () => {\n let AdContainers = [...document.querySelectorAll('div[class*=\" \"] div[class]')].filter(AdContainer => AdContainer instanceof HTMLElement)\n\n AdContainers = AdContainers.filter((AdContainer) => {\n let AdContainerPaddingLeft = Number(getComputedStyle(AdContainer).getPropertyValue('padding-left').replaceAll('px', ''))\n let AdContainerPaddingRight = Number(getComputedStyle(AdContainer).getPropertyValue('padding-right').replaceAll('px', ''))\n let AdContainerPaddingTop = Number(getComputedStyle(AdContainer).getPropertyValue('padding-top').replaceAll('px', ''))\n let AdContainerPaddingBottom = Number(getComputedStyle(AdContainer).getPropertyValue('padding-bottom').replaceAll('px', ''))\n return AdContainerPaddingLeft > 5 && AdContainerPaddingRight > 5 && AdContainerPaddingTop > 5 && AdContainerPaddingBottom > 5\n })\n\n AdContainers = AdContainers.filter(AdContainer => {\n return [...AdContainer.querySelectorAll('*')].filter(Ele => Ele instanceof HTMLElement &&\n getComputedStyle(Ele).getPropertyValue('animation-timing-function') === 'ease-in-out').length >= 3\n })\n\n AdContainers = AdContainers.filter(AdContainer => GetParents(AdContainer).some(Parent => Number(getComputedStyle(Parent).getPropertyValue('margin-top').replaceAll('px', '')) > 10 ))\n\n AdContainers = AdContainers.filter(AdContainer => AdContainer.innerText.length < 1000)\n\n AdContainers = AdContainers.filter(AdContainer => [...AdContainer.querySelectorAll('*[href=\"/RecentChanges\"]')].filter(Ele => Ele instanceof HTMLElement && getComputedStyle(Ele).getPropertyValue('display') !== 'none').length === 0)\n\n AdContainers = AdContainers.filter(AdContainer => !AdContainer.innerText.includes((new URL(location.href).searchParams.get('from') || '') + '\uC5D0\uC11C \uB118\uC5B4\uC634'))\n\n AdContainers = AdContainers.filter(AdContainer => !/\\[[0-9]+\\] .+/.test(AdContainer.innerText))\n\n AdContainers.forEach(Ele => Ele.setAttribute('style', 'display: none !important; visibility: hidden !important;'))\n }\n\n BrowserWindow.setTimeout = new Proxy(BrowserWindow.setTimeout, {\n apply(Target: typeof setTimeout, ThisArg: undefined, Args: Parameters<typeof setTimeout>) {\n let StringifiedFunc = Reflect.apply(ProtectedFunctionPrototypeToString, Args[0], Args) as string\n if (PowerLinkGenerationSkeletionPositiveRegExps.filter(PowerLinkGenerationSkeletionPositiveRegExp => PowerLinkGenerationSkeletionPositiveRegExp.filter(Index => Index.test(StringifiedFunc)).length >= 1).length === 1) {\n console.debug(`[${UserscriptName}]: setTimeout:`, Args[0])\n return Reflect.apply(Target, ThisArg, [HidePowerLinkPlaceholderWithAccount, 1500])\n }\n\n return Reflect.apply(Target, ThisArg, Args)\n }\n })\n\n if (document.readyState === 'loading') {\n window.addEventListener('DOMContentLoaded', () => {\n SPA.InstallSpaNavigationBridge({\n Root: () => document.getElementById('#app'),\n StableForMs: 900,\n SampleWindowMs: 900,\n Threshold: 3,\n TimeoutMs: 12000,\n IgnoreMutation: SPA.DefaultIgnoreMutation,\n WatchHashChange: true\n })\n })\n } else {\n // \uC774\uBBF8 DOMContentLoaded \uC774\uD6C4\n window.addEventListener('DOMContentLoaded', () => {\n SPA.InstallSpaNavigationBridge({\n Root: () => document.getElementById('#app'),\n StableForMs: 900,\n SampleWindowMs: 900,\n Threshold: 3,\n TimeoutMs: 12000,\n IgnoreMutation: SPA.DefaultIgnoreMutation,\n WatchHashChange: true\n })\n })\n }\n\n const Handler = async () => {\n let HTMLEle = Sort.CollectDataVAttributes(document)\n const { Result, TotalKeys, WorkerCount, HardwareConcurrency } = await Sort.RankCountsWithWorkersParallel(HTMLEle)\n let TargetedAttrsDOMs: HTMLElement[] = []\n Result.filter(([, Count]) => Count <= 30).forEach(([Attr, Count]) => {\n TargetedAttrsDOMs.push(...[...document.querySelectorAll(`[${Attr}]`)].filter((El) => El instanceof HTMLElement))\n })\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => getComputedStyle(El).getPropertyValue('display') === 'flex')\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => [...El.querySelectorAll('*')].some(Child => Child instanceof HTMLElement && typeof Child.click === 'function'))\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => [...El.querySelectorAll('*')].filter(Child => Child instanceof HTMLElement && Child.getBoundingClientRect().bottom - Child.getBoundingClientRect().top > 100 && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 100).length <= 50)\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => {\n let Count = [...El.querySelectorAll('*')].filter(Child => (Child.getBoundingClientRect().bottom - Child.getBoundingClientRect().top > 25 && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 25 && (Child instanceof SVGPathElement && Child.getAttribute('d') !== null) || (Child instanceof HTMLImageElement && Child.src.includes('//i.namu.wiki/i/')))).length\n return 1 <= Count && Count <= 6\n })\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => [...El.querySelectorAll('*')].some(Child => Child instanceof HTMLElement && getComputedStyle(Child, '::after').getPropertyValue('content').includes(':') && Child.getBoundingClientRect().right - Child.getBoundingClientRect().left > 20) === false)\n TargetedAttrsDOMs = TargetedAttrsDOMs.filter(El => [...El.querySelectorAll('*')].every(Child => Child instanceof HTMLElement && !new Date(Child.getHTML()).getTime()))\n console.debug(`[${UserscriptName}]`, TargetedAttrsDOMs)\n TargetedAttrsDOMs.forEach(El => {\n setInterval(() => {\n El.setAttribute('style', 'display: none !important; visibility: hidden !important;')\n }, 250)\n })\n }\n\n window.addEventListener('SpaRendered', () => setTimeout(Handler, 2500))\n window.addEventListener('SpaRendered', Handler)\n}\n\nRunNamuLinkUserscript(Win)"],
5
- "mappings": "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",
6
- "names": ["Worker"]
7
- }
@@ -1,10 +0,0 @@
1
- export {};
2
- /*!
3
- * @license MPL-2.0
4
- * This Source Code Form is subject to the terms of the Mozilla Public
5
- * License, v. 2.0. If a copy of the MPL was not distributed with this
6
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
- *
8
- * Contributors:
9
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
10
- */
@@ -1,10 +0,0 @@
1
- /*!
2
- * @license MPL-2.0
3
- * This Source Code Form is subject to the terms of the Mozilla Public
4
- * License, v. 2.0. If a copy of the MPL was not distributed with this
5
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
- *
7
- * Contributors:
8
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
9
- */
10
- export { RunNamuLinkUserscript } from './src/index.js';
@@ -1,13 +0,0 @@
1
- export declare function CreateSortWorkerURL(): string;
2
- export declare function MakeWorkerPool(Size: number): {
3
- Workers: Worker[];
4
- dispose(): void;
5
- };
6
- export declare function CollectDataVAttributes(Root?: Document): Record<string, number>;
7
- export declare function MergeSortedChunks(Chunks: Array<Array<[string, number]>>): Array<[string, number]>;
8
- export declare function RankCountsWithWorkersParallel(Counts: Record<string, number>): Promise<{
9
- Result: [string, number][];
10
- TotalKeys: number;
11
- WorkerCount: number;
12
- HardwareConcurrency: number;
13
- }>;
@@ -1,46 +0,0 @@
1
- /*!
2
- * @license MPL-2.0
3
- * This Source Code Form is subject to the terms of the Mozilla Public
4
- * License, v. 2.0. If a copy of the MPL was not distributed with this
5
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
- *
7
- * Contributors:
8
- * - See Git history at https://github.com/FilteringDev/tinyShield for detailed authorship information.
9
- */
10
- type SpaNavigateCause = 'init' | 'pushState' | 'replaceState' | 'popstate' | 'hashchange';
11
- export type SpaNavigateDetail = {
12
- Seq: number;
13
- From: string | null;
14
- To: string;
15
- Cause: SpaNavigateCause;
16
- };
17
- export type SpaRenderedDetail = {
18
- Seq: number;
19
- Url: string;
20
- Ok: boolean;
21
- };
22
- export type IgnoreMutation = (Mutation: MutationRecord) => boolean;
23
- export type SpaBridgeOptions = {
24
- Root?: () => Node | null;
25
- StableForMs?: number;
26
- SampleWindowMs?: number;
27
- Threshold?: number;
28
- TimeoutMs?: number;
29
- IgnoreMutation?: IgnoreMutation;
30
- WatchHashChange?: boolean;
31
- Events?: {
32
- Navigate?: 'SpaNavigate';
33
- Rendered?: 'SpaRendered';
34
- };
35
- };
36
- /**
37
- * SPA 라우팅(URL 변경)을 감지해 커스텀 이벤트를 발행하고,
38
- * DOM이 충분히 안정화되면 'Rendered' 이벤트까지 발행하는 브릿지
39
- *
40
- * Events (PascalCase):
41
- * - 'SpaNavigate' => CustomEvent<SpaNavigateDetail>
42
- * - 'SpaRendered' => CustomEvent<SpaRenderedDetail>
43
- */
44
- export declare function InstallSpaNavigationBridge(Options?: SpaBridgeOptions): () => void;
45
- export declare function DefaultIgnoreMutation(Mutation: MutationRecord): boolean;
46
- export {};