Optimizeation

This commit is contained in:
Lalle 2023-04-16 00:08:22 +02:00
parent d136beb935
commit 23cf79092b
No known key found for this signature in database
GPG Key ID: A6583D207A8F6B0D
11 changed files with 172 additions and 131 deletions

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"search.exclude": {
"*.jst": true,
"*.md": true,
"*.yaml": true,
"package*.json": true
}
}

View File

@ -318,54 +318,52 @@ var Embedding = {
return $.toggleClass(this, 'embed-removed') return $.toggleClass(this, 'embed-removed')
} }
}, },
title(req, data) { title(req, data) {
let text const { key, uid, options, link, post } = data;
const { key, uid, options, link, post } = data const service = Embedding.types[key].title;
const service = Embedding.types[key].title
let status = req.status;
let { status } = req
if ([200, 304].includes(status) && service.status) { if ([200, 304].includes(status) && service.status) {
status = service.status(req.response)[0] status = service.status(req.response)[0];
} }
if (!status) { if (!status) {
return return;
} }
text = `[${key}] ${(() => { const getText = () => {
switch (status) { switch (status) {
case 200: case 200:
case 304: case 304:
text = service.text(req.response, uid) const text = service.text(req.response, uid);
if (typeof text === 'string') { return typeof text === 'string' ? text : link.textContent;
return text
} else {
return (text = link.textContent)
}
case 404: case 404:
return 'Not Found' return 'Not Found';
case 403: case 403:
case 401: case 401:
return 'Forbidden or Private' return 'Forbidden or Private';
default: default:
return `${status}'d` return `${status}'d`;
} }
})()}` };
link.dataset.original = link.textContent const text = `[${key}] ${getText()}`;
link.textContent = text
for (var post2 of post.clones) { link.dataset.original = link.textContent;
for (var link2 of $$('a.linkify', post2.nodes.comment)) { link.textContent = text;
for (const post2 of post.clones) {
for (const link2 of $$('a.linkify', post2.nodes.comment)) {
if (link2.href === link.href) { if (link2.href === link.href) {
if (link2.dataset.original == null) { if (link2.dataset.original == null) {
link2.dataset.original = link2.textContent link2.dataset.original = link2.textContent;
} }
link2.textContent = text link2.textContent = text;
} }
} }
} }
}, }
}, },
ordered_types: [ ordered_types: [

View File

@ -73,7 +73,7 @@ var ExpandComment = {
parse(req, a, post) { parse(req, a, post) {
let postObj, spoilerRange let postObj, spoilerRange
const { status } = req const { status } = req.status
if (![200, 304].includes(status)) { if (![200, 304].includes(status)) {
a.textContent = status a.textContent = status
? `Error ${req.statusText} (${status})` ? `Error ${req.statusText} (${status})`

View File

@ -11,15 +11,7 @@ import CrossOrigin from '../platform/CrossOrigin'
import Get from '../General/Get' import Get from '../General/Get'
import { dict } from '../platform/helpers' import { dict } from '../platform/helpers'
/*
* 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
* DS206: Consider reworking classes to avoid initClass
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
export default class Fetcher { export default class Fetcher {
static initClass() { static initClass() {
this.prototype.archiveTags = { this.prototype.archiveTags = {
@ -88,20 +80,53 @@ export default class Fetcher {
this.root.textContent = `Loading post No.${this.postID}...` this.root.textContent = `Loading post No.${this.postID}...`
if (this.threadID) { if (this.threadID) {
const that = this const that = this
$.cache( Fetcher.fetchThread(
g.SITE.urls.threadJSON({ this.boardID,
boardID: this.boardID, this.threadID,
threadID: this.threadID, function (req, isCached) {
}), that.fetchedThread(req, isCached)
function ({ isCached }) {
return that.fetchedPost(this, isCached)
}, },
true,
) )
} else { } else {
this.archivedPost() const that = this
Fetcher.fetchPost(
this.boardID,
this.postID,
function (req, isCached) {
that.fetchedPost(req, isCached)
},
true,
)
}
}
fetchedThread(req) {
const { status, response } = req
const { boardID, threadID } = this
const board = g.boards[boardID]
if (status === 404) {
this.root.textContent = `Thread No.${threadID} not found.`
return
}
if (status !== 200) {
this.root.textContent = `Error loading thread No.${threadID}.`
return
}
if (response === '') {
this.root.textContent = `Thread No.${threadID} is empty.`
return
}
const thread = new Thread(
g.SITE.Build.threadFromObject(response, boardID),board)
Main.callbackNodes('Thread', [thread])
const post = thread.posts.get(this.postID)
if (post) {
this.insert(post)
} else {
this.root.textContent = `Post No.${this.postID} not found.`
} }
} }
insert(post) { insert(post) {
// Stop here if the container has been removed while loading. // Stop here if the container has been removed while loading.
if (!this.root.parentNode) { if (!this.root.parentNode) {
@ -155,76 +180,75 @@ export default class Fetcher {
} }
fetchedPost(req, isCached) { fetchedPost(req, isCached) {
// In case of multiple callbacks for the same request, const { status, response } = req;
// don't parse the same original post more than once. const { boardID, postID, threadID } = this;
let post const postKey = `${boardID}.${postID}`;
if ((post = g.posts.get(`${this.boardID}.${this.postID}`))) {
this.insert(post) const post = g.posts.get(postKey);
return if (post) {
this.insert(post);
return;
} }
const { status } = req
if (status !== 200) { if (status !== 200) {
// The thread can die by the time we check a quote. this.handleNon200Status(status);
if (status && this.archivedPost()) { return;
return
}
$.addClass(this.root, 'warning')
this.root.textContent =
status === 404
? `Thread No.${this.threadID} 404'd.`
: !status
? 'Connection Error'
: `Error ${req.statusText} (${req.status}).`
return
} }
const { posts } = req.response const { posts } = response;
g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler g.SITE.Build.spoilerRange[boardID] = posts[0].custom_spoiler;
for (post of posts) {
if (post.no === this.postID) { const foundPost = posts.find((p) => p.no === postID);
break
} if (!foundPost) {
} // we found it! this.handlePostNotFound(isCached);
return;
if (post.no !== this.postID) {
// Cached requests can be stale and must be rechecked.
if (isCached) {
const api = g.SITE.urls.threadJSON({
boardID: this.boardID,
threadID: this.threadID,
})
$.cleanCache((url) => url === api)
const that = this
$.cache(api, function () {
return that.fetchedPost(this, false)
})
return
}
// The post can be deleted by the time we check a quote.
if (this.archivedPost()) {
return
}
$.addClass(this.root, 'warning')
this.root.textContent = `Post No.${this.postID} was not found.`
return
} }
const board = g.boards[this.boardID] || new Board(this.boardID) const board = g.boards[boardID] || new Board(boardID);
const thread = const threadKey = `${boardID}.${threadID}`;
g.threads.get(`${this.boardID}.${this.threadID}`) || const thread = g.threads.get(threadKey) || new Thread(threadID, board);
new Thread(this.threadID, board) const newPost = new Post(
post = new Post( g.SITE.Build.postFromObject(foundPost, boardID),
g.SITE.Build.postFromObject(post, this.boardID),
thread, thread,
board, board,
{ isFetchedQuote: true }, { isFetchedQuote: true },
) );
Main.callbackNodes('Post', [post]) Main.callbackNodes("Post", [newPost]);
return this.insert(post) return this.insert(newPost);
}
handleNon200Status(status, req) {
$.addClass(this.root, "warning");
this.root.textContent =
status === 404
? `Thread No.${this.threadID} 404'd.`
: !status
? "Connection Error"
: `Error ${req.statusText} (${req.status}).`;
if (status && this.archivedPost()) {
return;
}
}
handlePostNotFound(isCached) {
if (isCached) {
const api = g.SITE.urls.threadJSON({
boardID: this.boardID,
threadID: this.threadID,
});
$.cleanCache((url) => url === api);
$.cache(api, () => this.fetchedPost(this, false));
return;
}
if (this.archivedPost()) {
return;
}
$.addClass(this.root, "warning");
this.root.textContent = `Post No.${this.postID} was not found.`;
} }
archivedPost() { archivedPost() {

View File

@ -213,7 +213,7 @@ export default class Post {
parseComment() { parseComment() {
// Merge text nodes and remove empty ones. // Merge text nodes and remove empty ones.
let bq let bq: HTMLElement
this.nodes.comment.normalize() this.nodes.comment.normalize()
// Get the comment's text. // Get the comment's text.
@ -221,7 +221,7 @@ export default class Post {
// Remove: // Remove:
// 'Comment too long'... // 'Comment too long'...
// EXIF data. (/p/) // EXIF data. (/p/)
this.nodes.commentClean = bq = this.nodes.comment.cloneNode(true) this.nodes.commentClean = bq = this.nodes.comment.cloneNode(true) as HTMLElement
g.SITE.cleanComment?.(bq) g.SITE.cleanComment?.(bq)
return (this.info.comment = this.nodesToText(bq)) return (this.info.comment = this.nodesToText(bq))
} }
@ -249,8 +249,8 @@ export default class Post {
return this.nodesToText(bq) return this.nodesToText(bq)
} }
nodesToText(bq) { nodesToText(bq: HTMLElement) {
let node let node: Node
let text = '' let text = ''
const nodes = $.X('.//br|.//text()', bq) const nodes = $.X('.//br|.//text()', bq)
let i = 0 let i = 0
@ -260,7 +260,7 @@ export default class Post {
return text return text
} }
cleanSpoilers(bq) { cleanSpoilers(bq: HTMLElement) {
const spoilers = $$(g.SITE.selectors.spoiler, bq) const spoilers = $$(g.SITE.selectors.spoiler, bq)
for (var node of spoilers) { for (var node of spoilers) {
$.replace(node, $.tn('[spoiler]')) $.replace(node, $.tn('[spoiler]'))
@ -274,7 +274,7 @@ export default class Post {
} }
} }
parseQuote(quotelink) { parseQuote(quotelink: HTMLAnchorElement) {
// Only add quotes that link to posts on an imageboard. // Only add quotes that link to posts on an imageboard.
// Don't add: // Don't add:
// - board links. (>>>/b/) // - board links. (>>>/b/)
@ -470,11 +470,11 @@ export class PostClone extends Post {
static suffix = 0 static suffix = 0
constructor(origin, context, contractThumb) { constructor(origin: Post, context: any, contractThumb: boolean) {
super() super()
this.isClone = true this.isClone = true
let file, fileRoots, key let file: any, fileRoots: HTMLAnchorElement , key: string
this.origin = origin this.origin = origin
this.context = context this.context = context
for (key of [ for (key of [

View File

@ -3,6 +3,7 @@
* DS102: Remove unnecessary code created because of implicit returns * DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/ */
import $ from '../platform/$'
class ShimSet { class ShimSet {
constructor() { constructor() {
this.elements = $.dict() this.elements = $.dict()

View File

@ -681,6 +681,7 @@ http://eye.swfchan.com/search/?q=%name;types:swf
current-catalog-text:"Catalog" current-catalog-text:"Catalog"
current-expired-text:"Expired" current-expired-text:"Expired"
current-archive-text:"Archive"] current-archive-text:"Archive"]
[ g pol ]
[external-text:"FAQ","${meta.name}"]\ [external-text:"FAQ","${meta.name}"]\
`, `,

View File

@ -88,7 +88,6 @@ import Menu from '../Menu/Menu'
import BoardConfig from '../General/BoardConfig' import BoardConfig from '../General/BoardConfig'
import CaptchaReplace from '../Posting/Captcha.replace' import CaptchaReplace from '../Posting/Captcha.replace'
import Get from '../General/Get' import Get from '../General/Get'
import Captcha from '../Posting/Captcha'
import { dict, platform } from '../platform/helpers' import { dict, platform } from '../platform/helpers'
import Polyfill from '../General/Polyfill' import Polyfill from '../General/Polyfill'
// import Test from "../General/Test"; // import Test from "../General/Test";

View File

@ -1,16 +1,15 @@
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let requestID = 0;
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
const id = requestID; const id = request;
requestID++; request++;
sendResponse(id); sendResponse(id);
return handlers[request.type](request, response => chrome.tabs.sendMessage(sender.tab.id, {id, data: response}));}); const type = request.type;
if (handlers[type]) {
return handlers[type](request, response => chrome.tabs.sendMessage(sender.tab.id, {id, data: response}));
} else {
console.warn("Unknown request type", type);
return false;
}});
var handlers = { var handlers = {
permission(request, cb) { permission(request, cb) {

View File

@ -17,6 +17,7 @@ import { debounce, dict, MINUTE, platform, SECOND } from './helpers'
const $ = (selector, root = document.body) => root.querySelector(selector) const $ = (selector, root = document.body) => root.querySelector(selector)
$.id = (id) => d.getElementById(id) $.id = (id) => d.getElementById(id)
$.dict = dict
$.ajaxPage = function (url, options) { $.ajaxPage = function (url, options) {
if (options.responseType == null) { if (options.responseType == null) {
@ -1252,6 +1253,7 @@ if (platform === 'crx') {
} }
} }
$.get = $.oneItemSugar((items, cb) => $.queueTask($.getSync, items, cb)) $.get = $.oneItemSugar((items, cb) => $.queueTask($.getSync, items, cb))
$.getSync = function (items, cb) { $.getSync = function (items, cb) {

View File

@ -258,7 +258,16 @@ var CrossOrigin = {
}, },
cache(url, cb) { cache(url, cb) {
return $.cache(url, cb, { ajax: CrossOrigin.ajax }) if (platform === 'userscript') {
return CrossOrigin.file(url, cb)
}
return eventPageRequest({ type: 'cache', url }, function (result) {
if (result) {
return cb(result)
} else {
return cb(null)
}
})
}, },
permission(cb, cbFail, origins) { permission(cb, cbFail, origins) {