added types, and plan to add vite

This commit is contained in:
Lalle 2023-04-21 00:23:32 +02:00
parent f3b9ecdae9
commit b2b7d2a383
No known key found for this signature in database
GPG Key ID: A6583D207A8F6B0D
12 changed files with 2615 additions and 147 deletions

1578
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -122,8 +122,11 @@
"markdown-it-anchor": "^7.1.0",
"request": "^2.88.2",
"rollup": "^3.17.2",
"rollup-plugin-typescript2": "^0.34.1",
"tslib": "^2.5.0",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"vite": "^4.2.2",
"vite-plugin-monkey": "^3.1.3"
},
"repository": {
"type": "git",
@ -151,6 +154,7 @@
},
"dependencies": {
"@types/jquery": "^3.5.16",
"@vitejs/plugin-react": "^3.1.0",
"jquery": "^3.6.4"
}
}

932
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,6 @@
import { Conf, doc } from '../globals/globals'
import $ from '../platform/$'
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const Anonymize = {
init() {
if (!Conf['Anonymize']) {

View File

@ -1,37 +0,0 @@
import $ from '../platform/$'
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const Polyfill = {
init() {
this.toBlob()
$.global(this.toBlob)
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.mozMatchesSelector ||
Element.prototype.webkitMatchesSelector
}
},
// This function is converted to a string and then put in a script tag.
// Do NOT shorten to `toBlob() {`.
toBlob: function () {
if (HTMLCanvasElement.prototype.toBlob) {
return
}
HTMLCanvasElement.prototype.toBlob = function (cb, type, encoderOptions) {
const url = this.toDataURL(type, encoderOptions)
const data = atob(url.slice(url.indexOf(',') + 1))
// DataUrl to Binary code from Aeosynth's 4chan X repo
const l = data.length
const ui8a = new Uint8Array(l)
for (let i = 0, end = l; i < end; i++) {
ui8a[i] = data.charCodeAt(i)
}
return cb(new Blob([ui8a], { type: type || 'image/png' }))
}
},
}
export default Polyfill

35
src/General/Polyfill.ts Normal file
View File

@ -0,0 +1,35 @@
import $ from '../platform/$'
interface ElementWithMatches {
mozMatchesSelector?: (selector: string) => boolean;
webkitMatchesSelector?: (selector: string) => boolean;
}
const Polyfill = {
init(): void {
this.toBlob()
$.global(this.toBlob)
if (!Element.prototype.matches) {
Element.prototype.matches =
(Element.prototype as Element & ElementWithMatches).mozMatchesSelector ||
(Element.prototype as Element & ElementWithMatches).webkitMatchesSelector
}
},
toBlob(): void {
if (HTMLCanvasElement.prototype.toBlob) {
return
}
HTMLCanvasElement.prototype.toBlob = function (cb: (blob: Blob) => void, type?: string, encoderOptions?: any): void {
const url = this.toDataURL(type, encoderOptions)
const data = atob(url.slice(url.indexOf(',') + 1))
const l = data.length
const ui8a = new Uint8Array(l)
for (let i = 0; i < l; i++) {
ui8a[i] = data.charCodeAt(i)
}
cb(new Blob([ui8a], { type: type || 'image/png' }))
}
},
}
export default Polyfill

View File

@ -21,18 +21,20 @@ import UI from '../General/UI'
import Get from '../General/Get'
import { dict, HOUR, MINUTE } from '../platform/helpers'
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS104: Avoid inline assignments
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
var ThreadWatcher = {
db: null as DataBoard,
dbLM: null as DataBoard,
dialog: null as HTMLDivElement,
enabled: false,
list: null as HTMLDivElement,
refreshButton: null as HTMLButtonElement,
closeButton: null as HTMLButtonElement,
shortcut: null as HTMLAnchorElement,
status: null as HTMLDivElement,
unreadEnabled: false,
unreaddb: null as DataBoard,
init() {
let sc
let sc: HTMLAnchorElement
if (!(this.enabled = Conf['Thread Watcher'])) {
return
}
@ -139,14 +141,14 @@ var ThreadWatcher = {
})
},
isWatched(thread) {
isWatched(thread: Thread) {
return !!ThreadWatcher.db?.get({
boardID: thread.board.ID,
threadID: thread.ID,
})
},
isWatchedRaw(boardID, threadID) {
isWatchedRaw(boardID: string, threadID: string) {
return !!ThreadWatcher.db?.get({ boardID, threadID })
},
@ -156,7 +158,7 @@ var ThreadWatcher = {
},
node() {
let toggler
let toggler: HTMLAnchorElement
if (this.isReply) {
return
}

View File

@ -1,59 +0,0 @@
import Main from '../main/Main'
export default class Callbacks {
static initClass() {
this.Post = new Callbacks('Post')
this.Thread = new Callbacks('Thread')
this.CatalogThread = new Callbacks('Catalog Thread')
this.CatalogThreadNative = new Callbacks('Catalog Thread')
}
constructor(type) {
this.type = type
this.keys = []
}
push({ name, cb }) {
if (!this[name]) {
this.keys.push(name)
}
return (this[name] = cb)
}
execute(node, keys = this.keys, force = false) {
let errors
if (node.callbacksExecuted && !force) {
return
}
node.callbacksExecuted = true
for (var name of keys) {
try {
this[name]?.call(node)
} catch (err) {
if (!errors) {
errors = []
}
errors.push({
message: [
'"',
name,
'" crashed on node ',
this.type,
' No.',
node.ID,
' (',
node.board,
').',
].join(''),
error: err,
html: node.nodes?.root?.outerHTML,
})
}
}
if (errors) {
return Main.handleErrors(errors)
}
}
}
Callbacks.initClass()

67
src/classes/Callbacks.ts Normal file
View File

@ -0,0 +1,67 @@
import Main from '../main/Main';
class Callbacks {
private keys: string[];
static Post: Callbacks;
static Thread: Callbacks;
static CatalogThread: Callbacks;
static CatalogThreadNative: Callbacks;
constructor(private type: string) {
this.keys = [];
}
static initClass(): void {
this.Post = new Callbacks('Post');
this.Thread = new Callbacks('Thread');
this.CatalogThread = new Callbacks('Catalog Thread');
this.CatalogThreadNative = new Callbacks('Catalog Thread');
}
push({ name, cb }: { name: string; cb: VoidFunction }): void {
if (!this[name as keyof Callbacks]) {
this.keys.push(name);
}
this[name as keyof Callbacks] = cb;
}
execute(node: any, keys: string[] = this.keys, force: boolean = false): void {
let errors: any[];
if (node.callbacksExecuted && !force) {
return;
}
node.callbacksExecuted = true;
for (const name of keys) {
try {
(this[name as keyof Callbacks] as Function)?.call(node);
} catch (err) {
if (!errors) {
errors = [];
}
errors.push({
message: [
'"',
name,
'" crashed on node ',
this.type,
' No.',
node.ID,
' (',
node.board,
').',
].join(''),
error: err,
html: node.nodes?.root?.outerHTML,
});
}
}
if (errors) {
Main.handleErrors(errors);
}
}
}
Callbacks.initClass();
export default Callbacks;

View File

@ -44,6 +44,12 @@ export interface Board {
config: BoardConfig
posts: SimpleDict<Post>
threads: SimpleDict<Thread>
threadsByBumpTime: Thread[]
threadsByReplyTime: Thread[]
threadsByImageCount: Thread[]
threadsByReplyCount: Thread[]
threadsByCreationTime: Thread[]
threadsByLastModifiedTime: Thread[]
}
export const Conf = Object.create(null)
@ -59,6 +65,7 @@ export const g: {
SITE?: typeof SWTinyboard
BOARD?: Board
VIEW?: string
xpath?: HTMLElement
} = {
VERSION: version.version,
NAMESPACE: meta.name,

View File

@ -1,4 +1,4 @@
import { d } from '../globals/globals';
const $$ = (selector: string, root = d.body) => [...Array.from(root.querySelectorAll(selector))];
function $$(selector: string, root: HTMLElement = document.body): HTMLElement[] {
return Array.from(root.querySelectorAll(selector));
}
export default $$;

View File

@ -15,7 +15,7 @@
"types": [
"@violentmonkey/types",
"@types/chrome",
"@types/jquery"
"@types/jquery",
],
"lib": [
"DOM",