Skip to content

Commit

Permalink
Modularize and new NamuWiki UI (#25)
Browse files Browse the repository at this point in the history
* build: modularize

* fix: wrong output path

* feat: rewrite

* feat: prevent powerlink

* feat: hide leftovers

* fix: leftover in android mobile

* fix: leftover in android mobile

* fix: breakage

* fix: line break exists in powerlink adverts
  • Loading branch information
piquark6046 authored Jan 26, 2024
1 parent 6dd8456 commit 70f8084
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 284 deletions.
131 changes: 4 additions & 127 deletions NamuLink.user.js

Large diffs are not rendered by default.

156 changes: 0 additions & 156 deletions NamuLink.user.ts

This file was deleted.

40 changes: 39 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
{
"type": "module"
"name": "namulink",
"version": "3.0.0",
"description": "",
"type": "module",
"scripts": {
"build": "pnpm bundle",
"bundle": "esbuild sources/src/index.ts --bundle --minify --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2022,chrome109,safari16,firefox115 --outfile=./NamuLink.user.js",
"debug": "esbuild sources/src/index.ts --bundle --define:global=window --inject:./sources/esbuild.inject.ts --banner:js=\"$(cat ./sources/banner.txt)\" --target=es2022,chrome109,safari16,firefox115 --outfile=./NamuLink-debug.user.js"
},
"keywords": [],
"author": {
"name": "PiQuark6046",
"email": "piquark6046@proton.me",
"url": "https://github.com/PiQuark6046"
},
"contributors": [
{
"name": "green1052",
"url": "https://github.com/green1052"
},
{
"name": "gaeulbyul",
"url": "https://github.com/gaeulbyul"
}
],
"license": "MIT",
"dependencies": {
"@types/node": "^20.10.6",
"superstruct": "^1.0.3"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"esbuild": "^0.19.11",
"eslint": "^8.54.0",
"eslint-config-xo": "^0.43.1",
"eslint-config-xo-typescript": "^1.0.1",
"typescript": "^5.3.2"
}
}
3 changes: 3 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
packages:
# all packages in direct subdirs of packages/
- 'sources/*'
38 changes: 38 additions & 0 deletions sources/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = {
env: {
es2022: true
},
extends: [
'xo'
],
overrides: [
{
extends: [
'xo-typescript',
],
files: [
'**/**.ts',
],
rules:
{
'@typescript-eslint/naming-convention': ['error', {
selector: ['variableLike', 'parameterProperty', 'classProperty', 'typeProperty'],
format: ['PascalCase']
}],
'@typescript-eslint/semi': ['error', 'never'],
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'new-cap': 'off'
}
}
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
'no-var': 'off',
'comma-dangle': 'off',
indent: ['off', 'tab'],
semi: 'off'
}
}
24 changes: 24 additions & 0 deletions sources/banner.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// ==UserScript==
// @name NamuLink
// @encoding utf-8
// @namespace https://github.com/List-KR/NamuLink
// @homepageURL https://github.com/List-KR/NamuLink
// @supportURL https://github.com/List-KR/NamuLink/issues
// @updateURL https://cdn.jsdelivr.net/gh/List-KR/NamuLink@latest/NamuLink.user.js
// @downloadURL https://cdn.jsdelivr.net/gh/List-KR/NamuLink@latest/NamuLink.user.js
// @license MIT
//
// @version 3.0.0
// @author PiQuark6046 and contributors
//
// @match https://namu.wiki/*
//
// @description NamuLink blocks the license-abused PowerLink advertisement on NamuWiki.
// @description:ko NamuLink는 나무위키에 있는 라이선스를 위반한 파워링크 광고를 차단합니다.
//
// @grant unsafeWindow
// @run-at document-start
// @inject-into page
// ==/UserScript==
// Used libraries:
// - Superstruct https://github.com/ianstormtaylor/superstruct
3 changes: 3 additions & 0 deletions sources/esbuild.inject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as Superstruct from 'superstruct'

export {Superstruct}
100 changes: 100 additions & 0 deletions sources/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {Superstruct} from '../esbuild.inject.js'

type unsafeWindow = typeof window
// eslint-disable-next-line @typescript-eslint/no-redeclare, @typescript-eslint/naming-convention
declare const unsafeWindow: unsafeWindow

// eslint-disable-next-line no-negated-condition
const Win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window

const NagivationEvent = new Event('namuwikinavigation')
const FristVisitEvent = new Event('namuwikifristvisit')

const CheckEableAdsAdsMetadata = (AdsMetadata: unknown) => {
if (Array.isArray(AdsMetadata)) {
if (AdsMetadata.toString().includes('//adcr.naver.com/adcr?')) {
return true
}
} else {
for (const Key of Object.keys(AdsMetadata)) {
try {
if (typeof AdsMetadata[Key] === 'string' && (AdsMetadata[Key] as string).includes('//adcr.naver.com/adcr?')) {
return true
}
} catch (error) {}
}
}

return false
}

const IsFakeNumber = (Args: string) => !Number.isNaN(Number(Args))

const EableAdsAdsFlagObj = Superstruct.object({
enable_ads: Superstruct.define('IsFakeNumber', IsFakeNumber),
})

const IsEableAdsObject = (Args: unknown) => typeof Args[0] !== 'undefined' && typeof Args[0] === 'object' && Superstruct.validate(Args, EableAdsAdsFlagObj) && CheckEableAdsAdsMetadata(Args[0])

Win.Object.defineProperty = new Proxy(Win.Object.defineProperty, {
apply(Target, ThisArg, Args) {
if (IsEableAdsObject(Args)) {
console.debug('[NamuLink:index]: Object.defineProperty:', [Target, ThisArg, Args])
} else {
Reflect.apply(Target, ThisArg, Args)
}
},
})

Win.TextDecoder.prototype.decode = new Proxy(Win.TextDecoder.prototype.decode, {
apply(Target, ThisArg, Args) {
const Decoded = Reflect.apply(Target, ThisArg, Args) as string
if (Decoded.includes('//adcr.naver.com/adcr?')) {
console.debug('[NamuLink:index]: TextDecoder.prototype.decode:', [Target, ThisArg, Args])
Win.dispatchEvent(NagivationEvent)
return new Error()
}

return Decoded
},
})

Win.Array.prototype.push = new Proxy(Win.Array.prototype.push, {
apply(Target, ThisArg, Args) {
if (Args.toString().includes('//adcr.naver.com/adcr?')) {
console.debug('[NamuLink:index]: Array.prototype.push:', [Target, ThisArg, Args])
Win.dispatchEvent(FristVisitEvent)
} else {
Reflect.apply(Target, ThisArg, Args)
}
},
})

const HideElements = (TargetElements: HTMLElement[]) => {
TargetElements.forEach(TargetElement => {
TargetElement.style.setProperty('display', 'none', 'important')
})
}

const HideLeftoverElement = () => {
const ElementsInArticle = Array.from(Win.document.querySelectorAll('article div[class*=" "]:has(> span + ul) ~ div * ~ div[class]'))
ElementsInArticle.push(...Array.from(Win.document.querySelectorAll('article div:not([class*=" "]):has(h1) ~ *')))
const HTMLElementsInArticle = ElementsInArticle.filter(ElementInArticle => ElementInArticle instanceof HTMLElement) as HTMLElement[]
var TargetElements: HTMLElement[] = []
TargetElements = HTMLElementsInArticle.filter(HTMLElementInArticle => HTMLElementInArticle.innerText.length < 25)
TargetElements = TargetElements.filter(HTMLElementInArticle => {
const ParentElements = Array.from(HTMLElementInArticle.querySelectorAll('*'))
const ParentHTMLElements = ParentElements.filter(ParentElement => ParentElement instanceof HTMLElement) as HTMLElement[]
return ParentHTMLElements.some(ParentElement => Number(getComputedStyle(ParentElement).getPropertyValue('margin-bottom').replace(/px$/, '')) >= 4)
})
TargetElements = TargetElements.filter(HTMLElementInArticle => {
const ParentElements = Array.from(HTMLElementInArticle.querySelectorAll('*'))
const ParentHTMLElements = ParentElements.filter(ParentElement => ParentElement instanceof HTMLElement) as HTMLElement[]
return ParentHTMLElements.filter(ParentElement => getComputedStyle(ParentElement).getPropertyValue('animation-iteration-count') === 'infinite').length >= 6
})
console.debug('[NamuLink:index]: HideLeftoverElement:', TargetElements)
HideElements(TargetElements)
}

Win.addEventListener('namuwikinavigation', HideLeftoverElement)
Win.addEventListener('namuwikifristvisit', HideLeftoverElement)

0 comments on commit 70f8084

Please sign in to comment.