types fixes etc

This commit is contained in:
Lalle 2023-04-22 04:55:27 +02:00
parent 22895eed98
commit bbcc0ec5db
No known key found for this signature in database
GPG Key ID: A6583D207A8F6B0D
6 changed files with 1200 additions and 669 deletions

View File

@ -75,14 +75,13 @@ var Filter = {
for (var line of (Conf[key] as string).split('\n')) {
let hl: string
let isstring: boolean
let regexp: RegExp | string
let regexp: RegExp | string | RegExpMatchArray
let top: boolean
let types: string[]
if (line[0] === '#') {
continue
}
if (!(regexp = line.match(/\/(.*)\/(\w*)/))) {
continue
}
@ -109,17 +108,8 @@ var Filter = {
regexp = RegExp(regexp[1], regexp[2])
} catch (err) {
// I warned you, bro.
new Notice(
'warning',
[
$.tn(`Invalid ${key} filter:`),
$.el('br'),
$.tn(line),
$.el('br'),
$.tn(err.message),
],
60,
)
// Notice(type, content, timeout, onclose)
new Notice('error', `Invalid regular expression: ${regexp[1]}`)
continue
}
}
@ -150,14 +140,8 @@ var Filter = {
// Highlight the post.
// If not specified, the highlight class will be filter-highlight.
if ((hl = /(?:^|;)\s*highlight/.test(filter))) {
hl =
filter.match(/(?:^|;)\s*highlight:([\w-]+)/)?.[1] ||
'filter-highlight'
// Put highlighted OP's thread on top of the board page or not.
// Defaults to on top.
top = filter.match(/(?:^|;)\s*top:(yes|no)/)?.[1] || 'yes'
top = top === 'yes' // Turn it into a boolean
if ((hl = filter.match(/(?:^|;)\s*highlight:([^;]+)/)?.[1])) {
hl = hl.trim()
}
// Fields that this filter applies to (for 'general' filters)
@ -383,8 +367,8 @@ var Filter = {
}
}
g.BOARD.threads.forEach(function (thread) {
if (thread.catalogViewNative) {
return Filter.catalogNode.call(thread.catalogViewNative)
if (thread.catalogView) {
return Filter.catalogNode.call(thread.catalogView)
}
})
},
@ -544,7 +528,7 @@ var Filter = {
}
const filter = files.map((f) => `/${f.MD5}/`).join('\n')
Filter.addFilter('MD5', filter)
const origin = post.origin || post
Filter.showFilters('MD5')
if (origin.isReply) {
PostHiding.hide(origin)
} else if (g.VIEW === 'index') {

View File

@ -1,11 +1,3 @@
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS205: Consider reworking code to avoid use of IIFEs
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
import SettingsPage from './Settings/SettingsHtml'
import FilterGuidePage from './Settings/Filter-guide.html'
import SaucePage from './Settings/Sauce.html'
@ -79,12 +71,12 @@ var Settings = {
value: { disableAll: true },
})
}
})
}, Object.create(null))
} else {
return $.global(() =>
Object.defineProperty(window, 'Config', {
value: { disableAll: true },
}),
}), Object.create(null)
)
}
}
@ -305,7 +297,7 @@ Enable it on boards.${
$('div[data-name="Work around CORB Bug"]', section).hidden = true
}
$.get(items, function (items) {
$.get(items, function (items: string[]) {
for (key in items) {
var val = items[key]
inputs[key].checked = val

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,8 @@ export default class Post {
declare files: ReturnType<Post['parseFile']>[]
declare info: {
commentHTML: string
comment: string
subject: string | undefined
name: string | undefined
email: string | undefined
@ -72,7 +74,6 @@ export default class Post {
this.root = root
this.thread = thread
this.board = board
$.extend(this, flags)
this.ID = +root.id.match(/\d*$/)[0]
this.postID = this.ID
this.threadID = this.thread.ID
@ -102,12 +103,13 @@ export default class Post {
const name = this.nodes.name?.textContent
const tripcode = this.nodes.tripcode?.textContent
this.info = {
commentHTML: this.nodes.comment?.innerHTML || '',
comment: this.nodes.comment?.textContent || '',
subject: this.nodes.subject?.textContent || undefined,
name,
email: this.nodes.email
? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, ''))
? decodeURIComponent(this.nodes.email.baseURI.split('mailto:')[1])
: undefined,
tripcode,
uniqueID: this.nodes.uniqueID?.textContent,
@ -256,7 +258,7 @@ export default class Post {
const nodes = $.X('.//br|.//text()', bq)
let i = 0
while ((node = nodes.snapshotItem(i++))) {
text += node.data || '\n'
text += node.nodeName === 'BR' ? '\n' : node.textContent
}
return text
}
@ -328,6 +330,12 @@ export default class Post {
parseFile(fileRoot: HTMLElement) {
interface File {
isImage: boolean
isVideo: boolean
url: string
dimensions: string
name: string
MD5: string
text: string
link: HTMLAnchorElement
thumb: HTMLElement

View File

@ -189,7 +189,7 @@ var Main = {
}
return fromCharCode0.apply(this, arguments)
})
})
}, Object.create(null))
$.asap(docSet, () => $.onExists(doc, 'iframe[srcdoc]', $.rm))
}
@ -355,7 +355,7 @@ var Main = {
$.global(function () {
document.documentElement.classList.add('js-enabled')
return (window.FCX = {})
})
}, Object.assign({}, g.SITE))
Main.jsEnabled = $.hasClass(doc, 'js-enabled')
// XXX https://bugs.chromium.org/p/chromium/issues/detail?id=920638
@ -943,8 +943,7 @@ var Main = {
}
const div = $.el('div', {
innerHTML: `${errors.length} errors occurred.${
Main.reportLink(errors).innerHTML
innerHTML: `${errors.length} errors occurred.${Main.reportLink(errors).innerHTML
} [<a href="javascript:;">show</a>]`,
})
$.on(div.lastElementChild, 'click', function () {
@ -972,8 +971,7 @@ var Main = {
innerHTML: E(data.message) + (reportLink ? reportLink.innerHTML : ''),
})
const error = $.el('div', {
textContent: `${data.error.name || 'Error'}: ${
data.error.message || 'see console for details'
textContent: `${data.error.name || 'Error'}: ${data.error.message || 'see console for details'
}`,
})
const lines =
@ -1158,7 +1156,3 @@ User agent: ${navigator.userAgent}\
}
export default Main
$.ready(() => Main.init())
// <% if (readJSON('/.tests_enabled')) { %>
// Main.features.push(['Build Test', Test]);
// <% } %>

View File

@ -6,9 +6,10 @@ import CrossOrigin from "./CrossOrigin";
import { debounce, dict, MINUTE, platform, SECOND } from "./helpers";
import { AjaxPageOptions, Dict, ElementProperties, SyncObject, WhenModifiedOptions } from "../types/$";
import Callbacks from "../classes/Callbacks";
import SimpleDict from "../classes/SimpleDict";
// not chainable
const $ = (selector, root = document.body) => root.querySelector(selector);
$.id = id => d.getElementById(id);
$.id = (id: string) => d.getElementById(id);
$.cache = dict();
$.ajaxPage = function (url: string, options: AjaxPageOptions = {}) {
if (options == null) { options = {}; }
@ -67,8 +68,8 @@ $.getOwn = function (obj: Object, key: string) { if ($.hasOwn(obj, key)) { retur
$.ajax = (function () {
let pageXHR = XMLHttpRequest;
if (window.wrappedJSObject && !XMLHttpRequest.wrappedJSObject) {
pageXHR = XPCNativeWrapper(window.wrappedJSObject.XMLHttpRequest);
if (unsafeWindow.wrappedJSObject && !XMLHttpRequest.wrappedJSObject) {
pageXHR = XPCNativeWrapper(unsafeWindow.wrappedJSObject.XMLHttpRequest);
} else {
pageXHR = XMLHttpRequest;
}
@ -80,8 +81,8 @@ $.ajax = (function () {
url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/');
if (platform === 'crx') {
// XXX https://bugs.chromium.org/p/chromium/issues/detail?id=920638
if (Conf['Work around CORB Bug'] && g.SITE.software === 'yotsuba' && !options.testCORB && FormData.prototype.entries) {
return $.ajaxPage(url, options);
if (Conf['Work around CORB Bug'] && g.SITE.software === 'yotsuba' && Date.now() - Conf['Work around CORB Bug'] < 2 * MINUTE) {
options.responseType = 'text';
}
}
const { onloadend, timeout, responseType, withCredentials, type, onprogress, form, headers } = options as AjaxPageOptions;
@ -129,7 +130,7 @@ $.ajax = (function () {
//@ts-ignore
window.FCX.requests = Object.create(null);
document.addEventListener('4chanXAjax', function (e) {
let fd, r;
let fd: FormData, r: XMLHttpRequest;
const { url, timeout, responseType, withCredentials, type, onprogress, form, headers, id } = e.detail;
//@ts-ignore
window.FCX.requests[id] = r = new pageXHR();
@ -180,7 +181,7 @@ $.ajax = (function () {
return r.abort();
}
, false);
}, 0);
}, Object.create(null));
$.on(d, '4chanXAjaxProgress', function (e: CustomEvent) {
let req: any;
@ -204,7 +205,7 @@ $.ajax = (function () {
});
};
return $.ajaxPage = function (url, options = {}) {
return $.ajaxPage = function (url: string, options: any = {}) {
let req: any;
let { onloadend, timeout, responseType, withCredentials, type, onprogress, form, headers } = options || {};
const id = requestID++;
@ -221,7 +222,7 @@ $.ajax = (function () {
}
}
}
$.event('4chanXAjax', { url, timeout, responseType, withCredentials, type, onprogress: !!onprogress, form, headers, id });
$.event('4chanXAjax', { url, timeout, responseType, withCredentials, type, onprogress, form, headers, id });
return req;
};
}
@ -298,6 +299,7 @@ $.whenModified = function (
req.callbacks = [cb];
return reqs[url] = req;
};
// very sensitive errors
return $.cleanCache = function (testf) {
for (var url in reqs) {
if (testf(url)) {
@ -358,19 +360,19 @@ $.addCSP = function (policy: string) {
return meta;
};
$.x = function (path, root) {
$.x = function (path: string, root?: HTMLElement) {
if (!root) { root = d.body; }
// XPathResult.ANY_UNORDERED_NODE_TYPE === 8
return d.evaluate(path, root, null, 8, null).singleNodeValue;
};
$.X = function (path, root) {
$.X = function (path: string, root?: HTMLElement) {
if (!root) { root = d.body; }
// XPathResult.ORDERED_NODE_SNAPSHOT_TYPE === 7
return d.evaluate(path, root, null, 7, null);
};
$.addClass = function (el, ...classNames) {
$.addClass = function (el: HTMLElement, ...classNames: string[]) {
for (var className of classNames) { el.classList.add(className); }
};
@ -378,11 +380,11 @@ $.rmClass = function (el, ...classNames) {
for (var className of classNames) { el.classList.remove(className); }
};
$.toggleClass = (el, className) => el.classList.toggle(className);
$.toggleClass = (el: HTMLElement, className: string) => el.classList.toggle(className);
$.hasClass = (el, className) => el.classList.contains(className);
$.hasClass = (el: HTMLElement, className: string) => el.classList.contains(className);
$.rm = el => el?.remove();
$.rm = (el: Element) => el?.remove();
$.rmAll = root => // https://gist.github.com/MayhemYDG/8646194
root.textContent = null;
@ -527,7 +529,7 @@ $.debounce = function (wait, fn) {
};
};
//ok
$.queueTask = function (fn) {
$.queueTask = function (fn: VoidFunction) {
if (typeof requestIdleCallback === 'function') {
return requestIdleCallback(fn);
} else {
@ -535,16 +537,14 @@ $.queueTask = function (fn) {
}
};
$.global = function (fn: Function, data: object) {
$.global = function (fn: Function, data?: object) {
if (doc) {
const script = $.el('script',
{ textContent: `(${fn}).call(document.currentScript.dataset);` });
const script = $.el('script', { textContent: `(${fn}).call(document.currentScript.dataset);` });
if (data) { $.extend(script.dataset, data); }
$.add((d.head || doc), script);
$.rm(script);
return script.dataset;
} else {
// XXX dwb
try {
fn.call(data);
} catch (error) { }
@ -612,17 +612,19 @@ $.item = function (key, val) {
return item;
};
$.oneItemSugar = fn => (function (key, val, cb) {
if (typeof key === 'string') {
return fn($.item(key, val), cb);
$.oneItemSugar = (fn: Function) => (function (key: string[], val: any, cb?: Function) {
if (typeof key === 'object') {
for (const k in key) {
fn(k, key[k], val);
}
} else {
return fn(key, val);
fn(key, val, cb);
}
});
$.syncing = dict();
$.securityCheck = function (data) {
$.securityCheck = function (data: object) {
if (location.protocol !== 'https:') {
return delete data['Redirect to HTTPS'];
}
@ -666,7 +668,7 @@ if (platform === 'crx') {
};
$.get = $.oneItemSugar(function (data, cb) {
$.get = $.oneItemSugar(function (data: object, key: string, cb: Function) {
if (!$.crxWorking()) { return; }
const results = {};
const get = function (area) {
@ -676,7 +678,7 @@ if (platform === 'crx') {
keys = null;
}
return chrome.storage[area].get(keys, function (result) {
let key;
let key: string;
result = dict.clone(result);
if (chrome.runtime.lastError) {
c.error(chrome.runtime.lastError.message);
@ -777,16 +779,14 @@ if (platform === 'crx') {
c.error(chrome.runtime.lastError.message);
}
if (err == null) { err = chrome.runtime.lastError; }
if (!--count) { return cb?.(err); }
if (!--count) { return cb?.(); }
};
chrome.storage.local.clear(done);
return chrome.storage.sync.clear(done);
};
})();
} else {
// http://wiki.greasespot.net/Main_Page
// https://tampermonkey.net/documentation.php
$.syncing = {};
if ((GM?.deleteValue != null) && window.BroadcastChannel && (typeof GM_addValueChangeListener === 'undefined' || GM_addValueChangeListener === null)) {
@ -804,9 +804,9 @@ if (platform === 'crx') {
return result;
})());
$.sync = (key, cb) => $.syncing[key] = cb;
$.sync = (key: string, cb: () => void) => $.syncing[key] = cb;
$.forceSync = function () { };
$.forceSync = function (): void { };
$.delete = function (keys, cb) {
let key;
@ -827,9 +827,9 @@ if (platform === 'crx') {
});
};
$.get = $.oneItemSugar(function (items, cb) {
const keys = Object.keys(items);
return Promise.all(keys.map((key) => GM.getValue(g.NAMESPACE + key))).then(function (values) {
$.get = $.oneItemSugar(function <T>(items: SimpleDict<T>, cb: (items: SimpleDict<T>) => void) {
const keys: string[] = Object.keys(items);
return Promise.all(keys.map((key) => GM.getValue(g.NAMESPACE + key))).then(function (values: string[]) {
for (let i = 0; i < values.length; i++) {
var val = values[i];
if (val) {
@ -840,10 +840,10 @@ if (platform === 'crx') {
});
});
$.set = $.oneItemSugar(function (items, cb) {
$.set = $.oneItemSugar(function (items: Record<string, any>, cb?: () => void) {
$.securityCheck(items);
return Promise.all((() => {
const result = [];
const result: Promise<void>[] = [];
for (var key in items) {
var val = items[key];
result.push(GM.setValue(g.NAMESPACE + key, JSON.stringify(val)));
@ -870,7 +870,6 @@ if (platform === 'crx') {
$.getValue = GM_getValue;
$.listValues = () => GM_listValues(); // error when called if missing
} else if ($.hasStorage) {
$.getValue = key => localStorage.getItem(key);
$.listValues = () => (() => {
const result = [];
for (var key in localStorage) {
@ -881,23 +880,20 @@ if (platform === 'crx') {
return result;
})();
} else {
$.getValue = function () { };
$.listValues = () => [];
}
if (typeof GM_addValueChangeListener !== 'undefined' && GM_addValueChangeListener !== null) {
$.setValue = GM_setValue;
$.deleteValue = GM_deleteValue;
} else if (typeof GM_deleteValue !== 'undefined' && GM_deleteValue !== null) {
$.oldValue = dict();
$.setValue = function (key, val) {
$.setValue = function (key: string, val: string) {
GM_setValue(key, val);
if (key in $.syncing) {
$.oldValue[key] = val;
if ($.hasStorage) { return localStorage.setItem(key, val); } // for `storage` events
}
};
$.deleteValue = function (key) {
$.deleteValue = function (key: string) {
GM_deleteValue(key);
if (key in $.syncing) {
delete $.oldValue[key];
@ -922,10 +918,14 @@ if (platform === 'crx') {
}
if (typeof GM_addValueChangeListener !== 'undefined' && GM_addValueChangeListener !== null) {
$.sync = function (key, cb) {
$.sync = function (key: string, cb: (val: any, key: string) => void) {
key = g.NAMESPACE + key;
$.syncing[key] = cb;
// if GM_addValueChangeListener was removed
if (GM_addValueChangeListener == null) { return; }
return GM_addValueChangeListener(key, function (name, oldVal, newVal) {
// if the callback was removed
if ($.syncing[key] == null) { return; }
if (newVal != null) {
if (newVal === oldVal) { return; }
return cb(dict.json(newVal), name);
@ -937,7 +937,7 @@ if (platform === 'crx') {
}); };
$.forceSync = function () { };
} else if ((typeof GM_deleteValue !== 'undefined' && GM_deleteValue !== null) || $.hasStorage) {
$.sync = function (key, cb) {
$.sync = function (key: string, cb: (val: any, key: string) => void) {
key = g.NAMESPACE + key;
$.syncing[key] = cb;
return $.oldValue[key] = $.getValue(key);
@ -945,7 +945,7 @@ if (platform === 'crx') {
(function () {
const onChange = function ({ key, newValue }) {
let cb;
let cb: (val: any, key: string) => void;
if (!(cb = $.syncing[key])) { return; }
if (newValue != null) {
if (newValue === $.oldValue[key]) { return; }
@ -959,27 +959,20 @@ if (platform === 'crx') {
};
$.on(window, 'storage', onChange);
return $.forceSync = function (key) {
// Storage events don't work across origins
// e.g. http://boards.4chan.org and https://boards.4chan.org
// so force a check for changes to avoid lost data.
key = g.NAMESPACE + key;
return onChange({ key, newValue: $.getValue(key) });
};
return $.forceSync = function () { return onChange({ key: g.NAMESPACE + 'forceSync', newValue: 1 }); };
})();
} else {
$.sync = function () { };
$.forceSync = function () { };
}
$.delete = function (keys, cb) {
$.delete = function (keys: string[], cb?: any) {
if (keys.length === 0) { return cb?.(); }
return Promise.all(keys.map(key => $.deleteValue(g.NAMESPACE + key))).then(cb);
};
$.get = $.oneItemSugar((items, cb) => $.queueTask(() => $.getSync(items, cb)));
$.get = $.oneItemSugar((items: any, cb: Function) => $.queueTask(() => $.getSync(items, cb)));
$.getSync = function (items, cb) {
$.getSync = function (items: any, cb: Function) {
for (var key in items) {
var val2;
if (val2 = $.getValue(g.NAMESPACE + key)) {
@ -995,7 +988,7 @@ if (platform === 'crx') {
return cb(items);
};
$.set = $.oneItemSugar(function (items, cb) {
$.set = $.oneItemSugar(function (items: any, cb?: Function) {
$.securityCheck(items);
return $.queueTask(function () {
for (var key in items) {
@ -1006,7 +999,7 @@ if (platform === 'crx') {
});
});
$.clear = function (cb) {
$.clear = function (cb: Function) {
// XXX https://github.com/greasemonkey/greasemonkey/issues/2033
// Also support case where GM_listValues is not defined.
$.delete(Object.keys(Conf), cb);