mirror of
https://github.com/LalleSX/4chan-XZ.git
synced 2026-01-30 09:48:12 +01:00
258 lines
7.5 KiB
TypeScript
258 lines
7.5 KiB
TypeScript
/*
|
|
* 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
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
|
*/
|
|
|
|
import Notice from "../classes/Notice"
|
|
import Post from "../classes/Post"
|
|
import Config from "../config/Config"
|
|
import Filter from "../Filtering/Filter"
|
|
import { c, Conf, g } from "../globals/globals"
|
|
import ImageHost from "../Images/ImageHost"
|
|
import Menu from "../Menu/Menu"
|
|
import Keybinds from "../Miscellaneous/Keybinds"
|
|
import Unread from "../Monitoring/Unread"
|
|
import $ from "../platform/$"
|
|
import $$ from "../platform/$$"
|
|
import Header from "./Header"
|
|
|
|
const Test = {
|
|
init() {
|
|
if ((g.SITE.software !== 'yotsuba') || !['index', 'thread'].includes(g.VIEW)) { return }
|
|
|
|
if (Conf['Menu']) {
|
|
const a = $.el('a',
|
|
{ textContent: 'Test HTML building' })
|
|
$.on(a, 'click', this.cb.testOne)
|
|
Menu.menu.addEntry({
|
|
el: a,
|
|
open(post) {
|
|
a.dataset.fullID = post.fullID
|
|
return true
|
|
}
|
|
})
|
|
}
|
|
|
|
const a2 = $.el('a',
|
|
{ textContent: 'Test HTML building' })
|
|
$.on(a2, 'click', this.cb.testAll)
|
|
Header.menu.addEntry({
|
|
el: a2
|
|
})
|
|
|
|
if (Unread.posts) {
|
|
const testOrderLink = $.el('a',
|
|
{ textContent: 'Test Post Order' })
|
|
$.on(testOrderLink, 'click', this.cb.testOrder)
|
|
Header.menu.addEntry({
|
|
el: testOrderLink
|
|
})
|
|
}
|
|
|
|
return $.on(d, 'keydown', this.cb.keydown)
|
|
},
|
|
|
|
assert(condition) {
|
|
if (!condition()) {
|
|
return new Notice('warning', `Assertion failed: ${condition}`, 30)
|
|
}
|
|
},
|
|
|
|
normalize(root) {
|
|
let el, i
|
|
let node
|
|
const root2 = root.cloneNode(true)
|
|
for (el of $$('.mobile', root2)) {
|
|
$.rm(el)
|
|
}
|
|
for (el of $$('a[href]', root2)) {
|
|
let {
|
|
href
|
|
} = el
|
|
href = href.replace(/(^\w+:\/\/boards\.4chan(?:nel)?\.org\/[^\/]+\/thread\/\d+)\/.*/, '$1')
|
|
el.setAttribute('href', href)
|
|
}
|
|
ImageHost.fixLinks($$('.fileText > a, a.fileThumb', root2))
|
|
for (el of $$('img[src]', root2)) {
|
|
el.src = el.src.replace(/(spoiler-\w+)\d(\.png)$/, '$11$2')
|
|
}
|
|
for (el of $$('pre.prettyprinted', root2)) {
|
|
let nodes = $.X('.//br|.//wbr|.//text()', el)
|
|
i = 0
|
|
nodes = ((() => {
|
|
const result = []
|
|
while (node = nodes.snapshotItem(i++)) {
|
|
result.push(node)
|
|
}
|
|
return result
|
|
})())
|
|
$.rmAll(el)
|
|
$.add(el, nodes)
|
|
el.normalize()
|
|
$.rmClass(el, 'prettyprinted')
|
|
}
|
|
for (el of $$('pre[style=""]', root2)) {
|
|
el.removeAttribute('style')
|
|
}
|
|
// XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1021289
|
|
$('.fileInfo[data-md5]', root2)?.removeAttribute('data-md5')
|
|
const textNodes = $.X('.//text()', root2)
|
|
i = 0
|
|
while (node = textNodes.snapshotItem(i++)) {
|
|
node.data = node.data.replace(/\ +/g, ' ')
|
|
// XXX https://a.4cdn.org/sci/thread/5942502.json, https://a.4cdn.org/news/thread/6.json, https://a.4cdn.org/wsg/thread/957536.json
|
|
if (node.previousSibling?.nodeName === 'BR') { node.data = node.data.replace(/^\n+/g, '') }
|
|
if (node.nextSibling?.nodeName === 'BR') { node.data = node.data.replace(/\n+$/g, '') }
|
|
if (node.data === '') { $.rm(node) }
|
|
}
|
|
return root2
|
|
},
|
|
|
|
firstDiff(x, y) {
|
|
let x2 = x.cloneNode(false)
|
|
let y2 = y.cloneNode(false)
|
|
if (!x2.isEqualNode(y2)) { return [x2, y2] }
|
|
let i = 0
|
|
while (true) {
|
|
x2 = x.childNodes[i]
|
|
y2 = y.childNodes[i]
|
|
if (!x2 || !y2) { return [x2, y2] }
|
|
if (!x2.isEqualNode(y2)) { return Test.firstDiff(x2, y2) }
|
|
i++
|
|
}
|
|
},
|
|
|
|
testOne(post) {
|
|
Test.postsRemaining++
|
|
return $.cache(g.SITE.urls.threadJSON({ boardID: post.boardID, threadID: post.threadID }), function () {
|
|
if (!this.response) { return }
|
|
const { posts } = this.response
|
|
g.SITE.Build.spoilerRange[post.board.ID] = posts[0].custom_spoiler
|
|
for (const postData of posts) {
|
|
if (postData.no === post.ID) {
|
|
const t1 = new Date().getTime()
|
|
const obj = g.SITE.Build.parseJSON(postData, post.board)
|
|
const root = g.SITE.Build.post(obj)
|
|
const t2 = new Date().getTime()
|
|
Test.time += t2 - t1
|
|
const post2 = new Post(root, post.thread, post.board, { forBuildTest: true })
|
|
let fail = false
|
|
|
|
const x = post.normalizedOriginal
|
|
const y = post2.normalizedOriginal
|
|
if (!x.isEqualNode(y)) {
|
|
fail = true
|
|
c.log(`${post.fullID} differs`)
|
|
const [x2, y2] = Array.from(Test.firstDiff(x, y))
|
|
c.log(x2)
|
|
c.log(y2)
|
|
c.log(x.outerHTML)
|
|
c.log(y.outerHTML)
|
|
}
|
|
|
|
for (const key in Config.filter) {
|
|
if ((!key === 'General') && !((key === 'MD5') && (post.board.ID === 'f'))) {
|
|
const val1 = Filter.values(key, obj)
|
|
const val2 = Filter.values(key, post2)
|
|
if ((val1.length !== val2.length) || !val1.every((x, i) => x === val2[i])) {
|
|
fail = true
|
|
c.log(`${post.fullID} has filter bug in ${key}`)
|
|
c.log(val1)
|
|
c.log(val2)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fail) {
|
|
Test.postsFailed++
|
|
} else {
|
|
c.log(`${post.fullID} correct`)
|
|
}
|
|
Test.postsRemaining--
|
|
if (Test.postsRemaining === 0) { Test.report() }
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
testAll() {
|
|
g.posts.forEach(function (post) {
|
|
if (!post.isClone && !post.isFetchedQuote) {
|
|
let abbr
|
|
if (!((abbr = $('.abbr', post.nodes.comment)) && /Comment too long\./.test(abbr.textContent))) {
|
|
return Test.testOne(post)
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
postsRemaining: 0,
|
|
postsFailed: 0,
|
|
time: 0,
|
|
|
|
report() {
|
|
if (Test.postsFailed) {
|
|
new Notice('warning', `${Test.postsFailed} post(s) differ (${Test.time} ms)`, 30)
|
|
} else {
|
|
new Notice('success', `All correct (${Test.time} ms)`, 5)
|
|
}
|
|
return Test.postsFailed = (Test.time = 0)
|
|
},
|
|
|
|
cb: {
|
|
testOne() {
|
|
Test.testOne(g.posts.get(this.dataset.fullID))
|
|
return Menu.menu.close()
|
|
},
|
|
|
|
testAll() {
|
|
Test.testAll()
|
|
return Header.menu.close()
|
|
},
|
|
|
|
testOrder() {
|
|
let x
|
|
const list1 = ((() => {
|
|
const result = []
|
|
for (x of Unread.order.order()) {
|
|
result.push(x.ID)
|
|
}
|
|
return result
|
|
})())
|
|
const list2 = ((() => {
|
|
const result1 = []
|
|
for (x of ($$((g.SITE.isOPContainerThread ? `${g.SITE.selectors.thread}, ` : '') + g.SITE.selectors.postContainer))) {
|
|
result1.push(+x.id.match(/\d*$/)[0])
|
|
}
|
|
return result1
|
|
})())
|
|
const pass = (function () {
|
|
if (list1.length !== list2.length) { return false }
|
|
for (let i = 0, end = list1.length; i < end; i++) {
|
|
if (list1[i] !== list2[i]) { return false }
|
|
}
|
|
return true
|
|
})()
|
|
if (pass) {
|
|
return new Notice('success', `Orders same (${list1.length} posts)`, 5)
|
|
} else {
|
|
new Notice('warning', 'Orders differ.', 30)
|
|
c.log(list1)
|
|
return c.log(list2)
|
|
}
|
|
},
|
|
|
|
keydown(e) {
|
|
if (Keybinds.keyCode(e) !== 'v') { return }
|
|
if (['INPUT', 'TEXTAREA'].includes(e.target.nodeName)) { return }
|
|
Test.testAll()
|
|
e.preventDefault()
|
|
return e.stopPropagation()
|
|
}
|
|
}
|
|
}
|
|
export default Test
|