Compare commits

..

No commits in common. "aaa196e3b7d0aa52191bae9bfe88154a7b1ec8b4" and "159b3cc760733cfa99b406c339850f8cde02bb22" have entirely different histories.

19 changed files with 2951 additions and 1690 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +0,0 @@
selectRev: 0,
selectAll: false,
selectMode: false,
showHiddenThreads: false,
changed: false,
currentPage: 0,
currentSort: '',
navLinks: null,
selectSort: null,
selectSize: null,
lastLongOptions: null,
root: null,
button: null,
inputs: null,
pagelist: null,
search: '',
pageNum: 0,
req: null,
isReply: false,
isThread: false,
isClone: false,
enabled: false,
searchInput: null,
hideLabel: null,
lastLongInputs: null,
lastLongThresholds: null,
loaded: false,
liveThreadData: null,
pagesNum: 0,
ID: 0,
thread: null,
threadPosition: 0,
threadsNumPerPage: 0,
notice: null,
nodes: null,
nTimeout: 0,
replyData: null,
replyNodes: null,
sortedThreadIDs: null,
liveThreadDict: null,
parsedThreads: null,
liveThreadIDs: null,
initFinishedFired: false,

View File

@ -79,7 +79,7 @@ const ImageCommon = {
}
}
const threadJSON = g.SITE.urls.threadJSON?.(post, fileObj)
const threadJSON = g.SITE.urls.threadJSON?.(post)
if (!threadJSON) { return }
const parseJSON = function (isArchiveURL) {
let needle, postObj

View File

@ -4,7 +4,12 @@ import $ from "../platform/$"
import { dict } from "../platform/helpers"
import QR from "../Posting/QR"
import Menu from "./Menu"
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const DeleteLink = {
auto: [dict(), dict()],
@ -114,7 +119,8 @@ const DeleteLink = {
withCredentials: true,
onloadend() { return DeleteLink.load(link, post, fileOnly, this.response) },
form: $.formData(form)
})
}
)
},
load(link, post, fileOnly, resDoc) {

View File

@ -1,8 +1,13 @@
import { Conf, g } from "../globals/globals"
import { Conf,g } from "../globals/globals"
import ImageCommon from "../Images/ImageCommon"
import $ from "../platform/$"
import Menu from "./Menu"
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const DownloadLink = {
init() {
if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || !Conf['Download Link']) { return }
@ -19,9 +24,9 @@ const DownloadLink = {
return Menu.menu.addEntry({
el: a,
order: 100,
open({ file }) {
open({file}) {
if (!file) { return false }
a.href = file.url
a.href = file.url
a.download = file.name
return true
}

View File

@ -33,7 +33,7 @@ const FileInfo = {
const oldInfo = $.el('span', {className: 'fileText-original'})
$.prepend(this.file.link.parentNode, oldInfo)
$.add(oldInfo, this.file.link)
$.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling])
const info = $.el('span', {className: 'file-info'})
FileInfo.format(Conf['fileInfo'], this, info)

View File

@ -15,12 +15,12 @@ const Flash = {
initReady() {
if ($.hasStorage) {
return $.global(function () { if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { return window.SWFEmbed.init() } }, 'SWFEmbed')
return $.global(function () { if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { return window.SWFEmbed.init() } })
} else {
if (g.VIEW === 'thread') {
$.global(() => window.Main.tid = location.pathname.split(/\/+/)[3], 'Main')
$.global(() => window.Main.tid = location.pathname.split(/\/+/)[3])
}
return $.global(() => window.SWFEmbed.init(), 'SWFEmbed')
return $.global(() => window.SWFEmbed.init())
}
}
}

View File

@ -6,7 +6,11 @@ import $ from "../platform/$"
import $$ from "../platform/$$"
import ExpandComment from "./ExpandComment"
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const Fourchan = {
init() {
if ((g.SITE.software !== 'yotsuba') || !['index', 'thread', 'archive'].includes(g.VIEW)) { return }
@ -61,7 +65,7 @@ const Fourchan = {
}
}
}
, false), 'MathJax')
, false))
Callbacks.Post.push({
name: 'Parse [math] tags',
cb: Fourchan.math

View File

@ -1,5 +1,4 @@
import Callbacks from "../classes/Callbacks"
import Post from "../classes/Post"
import { g } from "../globals/globals"
import $ from "../platform/$"
@ -26,12 +25,12 @@ const IDHighlight = {
if (!this.isClone) { return IDHighlight.set(this) }
},
set(post: Post) {
set(post) {
const match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID
return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight')
},
click(post: Post) {
click(post) {
return function () {
const uniqueID = post.info.uniqueID || post.info.capcode
IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID

View File

@ -6,7 +6,6 @@ import { Conf, g } from "../globals/globals"
import $ from "../platform/$"
const IDPostCount = {
thread: null as Thread,
init() {
if ((g.VIEW !== 'thread') || !Conf['Count Posts by ID']) { return }
Callbacks.Thread.push({

View File

@ -10,7 +10,6 @@ import CaptchaT from "./Captcha.t"
import QR from "./QR"
const Captcha = {
replace: CaptchaReplace,
cache: {
init() {
$.on(d, 'SaveCaptcha', e => {

View File

@ -80,12 +80,7 @@ const Quotify = {
// Don't (Dead) when quotifying in an archived post,
// and we know the post still exists.
a = $.el('a', {
href: g.SITE.Build.postURL({
siteID: boardID,
boardID,
threadID: post.thread.ID,
postID
}),
href: g.SITE.Build.postURL(boardID, post.thread.ID, postID),
className: 'quotelink',
textContent: quote
}
@ -93,17 +88,12 @@ const Quotify = {
} else {
// Replace the .deadlink span if we can redirect.
a = $.el('a', {
href: g.SITE.Build.postURL({
siteID: boardID,
boardID,
threadID: 0,
postID
}),
href: g.SITE.Build.postURL(boardID, post.thread.ID, postID),
className: 'quotelink deadlink',
textContent: quote
}
)
$.add(a, Post.deadMark.cloneNode(true) as Element)
$.add(a, Post.deadMark.cloneNode(true))
$.extend(a.dataset, { boardID, threadID: post.thread.ID, postID })
}
@ -118,7 +108,7 @@ const Quotify = {
textContent: quote
}
)
$.add(a, Post.deadMark.cloneNode(true) as Element)
$.add(a, Post.deadMark.cloneNode(true))
if (fetchable) {
// Make it function as a normal quote if we can fetch the post.
$.addClass(a, 'quotelink')
@ -130,7 +120,7 @@ const Quotify = {
if (!this.quotes.includes(quoteID)) { this.quotes.push(quoteID) }
if (!a) {
$.add(deadlink, Post.deadMark.cloneNode(true) as Element)
$.add(deadlink, Post.deadMark.cloneNode(true))
return
}
@ -148,11 +138,7 @@ const Quotify = {
$.before(deadlink, green)
$.add(green, deadlink)
}
return $.replace(deadlink, $.el('span', {
className: 'deadlink',
textContent: deadlink.textContent
}
))
return $.replace(deadlink, [...Array.from(deadlink.childNodes)])
}
}
export default Quotify

View File

@ -7,16 +7,9 @@ export default class CatalogThread {
ID: string | number
thread: Thread
board: Board
nodes: {
root: Post,
thumb: Element,
icons: Element,
postCount: Element,
fileCount: Element,
pageCount: Element,
replies: Element
}
nodes: { root: Post; thumb: HTMLElement; icons: any; postCount: number; fileCount: number; pageCount: number; replies: any }
toString() { return this.ID }
constructor(root: Post, thread: Thread) {
this.thread = thread
this.ID = this.thread.ID + ''

View File

@ -58,7 +58,6 @@ export default class Post {
})()
normalizedOriginal: any
indexRefreshSeen: any
callbacksExecuted: boolean
toString() { return this.ID }

23
src/classes/ShimSet.ts Normal file
View File

@ -0,0 +1,23 @@
class ShimSet {
elements: Element
size: number
constructor() {
this.elements
this.size = 0
}
has(value) {
return value in this.elements
}
add(value) {
if (this.elements[value]) { return }
this.elements[value] = true
return this.size++
}
delete(value) {
if (!this.elements[value]) { return }
delete this.elements[value]
return this.size--
}
}
if (!('Set' in window)) { window.Set = ShimSet }

View File

@ -10,12 +10,10 @@ declare global {
wrappedJSObject: any
Tegaki: any
FCX: any
Parser: any
}
}
// interfaces might be incomplete
export interface BoardConfig {
code_tags: 1 | 0,
sjis_tags: string,
math_tags: string,
forced_anon: boolean,

View File

@ -239,7 +239,7 @@ $.ajax = (function () {
pageXHR = XMLHttpRequest
}
const r = (function (url: string, options = dict(), cb?: (this: XMLHttpRequest, e: ProgressEvent) => void) {
const r = (function (url: string, options = dict(), cb: Callbacks) {
if (options.responseType == null) { options.responseType = 'json' }
if (!options.type) { options.type = (options.form && 'post') || 'get' }
url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/')

View File

@ -74,6 +74,7 @@ const SWTinyboard = {
}
return false
},
ID: 'sw-tinyboard',
parseThreadMetadata(el: HTMLElement) {
const thread = dict()
const op = el.querySelector('.op')
@ -218,9 +219,6 @@ $\
},
Build: {
postURL({ siteID, boardID, threadID, postID }) {
return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/res/${threadID}.html#${postID}`
},
parseJSON(data, board) {
const o = this.parseJSON(data, board)
if (data.ext === 'deleted') {
@ -317,7 +315,7 @@ $\
if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { return false }
const nameNode = $('.postfilename', text)
$.extend(file, {
name: nameNode ? (nameNode.textContent || '').trim() : '',
name: nameNode ? (nameNode.title || nameNode.textContent) : link.pathname.match(/[^/]*$/)[0],
size: info[2],
dimensions: info[0].match(/\d+x\d+/)?.[0]
})

View File

@ -306,19 +306,11 @@ $\
insertTags(bq) {
let node
const nodes = []
const {children} = bq
for (let i = 0; i < children.length; i++) {
if ((node = children[i]) && (node.nodeName === 'A') && (node.textContent === '>>')) {
nodes.push(node)
}
for (node of $$('s, .removed-spoiler', bq)) {
$.replace(node, [$.tn('[spoiler]'), ...Array.from(node.childNodes), $.tn('[/spoiler]')])
}
for (const node of nodes) {
const {href} = node
const {textContent} = node.nextSibling
const tag = $.el('a', {href, textContent})
$.after(node, tag)
$.rm(node)
for (node of $$('.prettyprint', bq)) {
$.replace(node, [$.tn('[code]'), ...Array.from(node.childNodes), $.tn('[/code]')])
}
},
@ -350,7 +342,7 @@ $\
},
transformBoardList() {
let node = null
let node
const nodes = []
const spacer = () => $.el('span', {className: 'spacer'})
const items = $.X('.//a|.//text()[not(ancestor::a)]', $(SWYotsuba.selectors.boardList))
@ -630,7 +622,7 @@ $\
thread(thread, data, withReplies) {
let root
if (root = thread.nodes.root) {
$.rmAll(root, thread.OP.nodes.root)
$.rmAll(root)
} else {
thread.nodes.root = (root = $.el('div', {
className: 'thread',
@ -686,7 +678,7 @@ $\
'div',
generateCatalogThreadHtml(thread, src, imgClass, data, postCount, fileCount, pageCount, staticPath, gifIcon)
)
$.before(thread.OP.nodes.info, container)
$.before(thread.OP.nodes.info, [...Array.from(container.childNodes)])
for (const br of $$('br', thread.OP.nodes.comment)) {
if (br.previousSibling && (br.previousSibling.nodeName === 'BR')) {
@ -699,7 +691,7 @@ $\
id: `t${thread}`
}
)
if (thread.OP.highlights) { $.addClass(root, 'highlight') }
if (thread.OP.highlights) { $.addClass(root, ...Array.from(thread.OP.highlights)) }
if (!thread.OP.file) { $.addClass(root, 'noFile') }
root.style.cssText = cssText || ''