mirror of
https://github.com/LalleSX/4chan-XZ.git
synced 2026-01-30 09:48:12 +01:00
Added types and bug fixes
This commit is contained in:
parent
f65fbc4fed
commit
241ff1eb7a
@ -874,8 +874,9 @@ var Embedding = {
|
||||
{
|
||||
key: 'YouTube',
|
||||
regExp:
|
||||
/^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/))([\w\-]{11})(.*)/,
|
||||
/^\w+:\/\/(?:www\.)?youtube\.com\/(?:watch\?v=|embed\/|v\/)?(\w+)/,
|
||||
el(a) {
|
||||
const isShort = a.href.includes('youtube.com/shorts/')
|
||||
let start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/)
|
||||
if (start) {
|
||||
start = start[1]
|
||||
@ -888,11 +889,15 @@ var Embedding = {
|
||||
1 * start.match(/(\d+)s/)[1]
|
||||
}
|
||||
const el = $.el('iframe', {
|
||||
src: `//www.youtube.com/embed/${a.dataset.uid}?rel=0&wmode=opaque${
|
||||
start ? '&start=' + start : ''
|
||||
}`,
|
||||
src: `//www.youtube.com/embed/${a.dataset.uid}${isShort ? '?t=0s&enablejsapi=1&controls=0&loop=1&mute=1&playsinline=1' : `?rel=0&wmode=opaque${start ? '&start=' + start : ''}`}`,
|
||||
})
|
||||
el.setAttribute('allowfullscreen', 'true')
|
||||
if (isShort) {
|
||||
el.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share')
|
||||
el.setAttribute('allowfullscreen', '')
|
||||
el.setAttribute('loading', 'lazy')
|
||||
el.setAttribute('class', 'youtube-short')
|
||||
}
|
||||
return el
|
||||
},
|
||||
title: {
|
||||
@ -907,17 +912,18 @@ var Embedding = {
|
||||
const m = _.error.match(/^(\d*)\s*(.*)/)
|
||||
return [+m[1], m[2]]
|
||||
} else {
|
||||
return [200, 'OK']
|
||||
return [200, null]
|
||||
}
|
||||
},
|
||||
},
|
||||
preview: {
|
||||
url(uid) {
|
||||
return `https://img.youtube.com/vi/${uid}/0.jpg`
|
||||
const isShort = uid.includes('shorts')
|
||||
return `https://img.youtube.com/vi/${uid}${isShort ? '/mqdefault.jpg' : '/0.jpg'}`
|
||||
},
|
||||
height: 360,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
export default Embedding
|
||||
|
||||
@ -4,11 +4,6 @@ import Filter from '../Filtering/Filter'
|
||||
import { g, Conf } from '../globals/globals'
|
||||
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 ArchiveLink = {
|
||||
init() {
|
||||
if (
|
||||
|
||||
@ -2,12 +2,14 @@ import { g, Conf, d } from '../globals/globals'
|
||||
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
|
||||
*/
|
||||
var CopyTextLink = {
|
||||
interface CopyTextLink {
|
||||
text: string
|
||||
init(): VoidFunction
|
||||
copy(): VoidFunction
|
||||
}
|
||||
|
||||
const CopyTextLink: CopyTextLink = {
|
||||
text: '',
|
||||
init() {
|
||||
if (
|
||||
!['index', 'thread'].includes(g.VIEW) ||
|
||||
@ -3,13 +3,9 @@ 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() {
|
||||
init(): VoidFunction {
|
||||
if (
|
||||
!['index', 'thread'].includes(g.VIEW) ||
|
||||
!Conf['Menu'] ||
|
||||
@ -18,7 +14,7 @@ const DownloadLink = {
|
||||
return
|
||||
}
|
||||
|
||||
const a = $.el('a', {
|
||||
const a: HTMLAnchorElement = $.el('a', {
|
||||
className: 'download-link',
|
||||
textContent: 'Download file',
|
||||
})
|
||||
@ -37,7 +33,7 @@ const DownloadLink = {
|
||||
a.download = file.name
|
||||
return true
|
||||
},
|
||||
})
|
||||
}) as VoidFunction
|
||||
},
|
||||
}
|
||||
export default DownloadLink
|
||||
@ -2,14 +2,10 @@ import Callbacks from '../classes/Callbacks'
|
||||
import UI from '../General/UI'
|
||||
import { g, Conf } from '../globals/globals'
|
||||
import $ from '../platform/$'
|
||||
import Post from '../classes/Post'
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
var Menu = {
|
||||
init() {
|
||||
var Menu: any = {
|
||||
init(): VoidFunction {
|
||||
if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) {
|
||||
return
|
||||
}
|
||||
@ -33,7 +29,7 @@ var Menu = {
|
||||
})
|
||||
},
|
||||
|
||||
node() {
|
||||
node(): HTMLElement {
|
||||
if (this.isClone) {
|
||||
const button = $('.menu-button', this.nodes.info)
|
||||
$.rmClass(button, 'active')
|
||||
@ -44,15 +40,15 @@ var Menu = {
|
||||
return $.add(this.nodes.info, Menu.makeButton(this))
|
||||
},
|
||||
|
||||
catalogNode() {
|
||||
catalogNode(): HTMLElement {
|
||||
return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP))
|
||||
},
|
||||
|
||||
makeButton(post, button) {
|
||||
makeButton(post: Post, button?: HTMLElement): HTMLElement {
|
||||
if (!button) {
|
||||
button = Menu.button.cloneNode(true)
|
||||
}
|
||||
$.on(button, 'click', function (e) {
|
||||
$.on(button, 'click', (e: Event) => {
|
||||
return Menu.menu.toggle(e, this, post)
|
||||
})
|
||||
return button
|
||||
@ -1,23 +1,24 @@
|
||||
import { g, Conf, d } from '../globals/globals'
|
||||
import $ from '../platform/$'
|
||||
import Menu from './Menu'
|
||||
import Post from '../classes/Post'
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
var ReportLink = {
|
||||
type ReportLinkType = {
|
||||
init: () => void
|
||||
report: () => void
|
||||
url: string
|
||||
dims: string
|
||||
}
|
||||
|
||||
const ReportLink: ReportLinkType = {
|
||||
init() {
|
||||
if (
|
||||
!['index', 'thread'].includes(g.VIEW) ||
|
||||
if (!['index', 'thread'].includes(g.VIEW) ||
|
||||
!Conf['Menu'] ||
|
||||
!Conf['Report Link']
|
||||
) {
|
||||
!Conf['Report Link']) {
|
||||
return
|
||||
}
|
||||
|
||||
const a = $.el('a', {
|
||||
const a: HTMLAnchorElement = $.el('a', {
|
||||
className: 'report-link',
|
||||
href: 'javascript:;',
|
||||
textContent: 'Report',
|
||||
@ -27,10 +28,8 @@ var ReportLink = {
|
||||
return Menu.menu.addEntry({
|
||||
el: a,
|
||||
order: 10,
|
||||
open(post) {
|
||||
ReportLink.url = `//sys.${location.hostname.split('.')[1]}.org/${
|
||||
post.board
|
||||
}/imgboard.php?mode=report&no=${post}`
|
||||
open(post: Post) {
|
||||
ReportLink.url = `//sys.${location.hostname.split('.')[1]}.org/${post.board}/imgboard.php?mode=report&no=${post}`
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
ReportLink.dims = 'width=350,height=275'
|
||||
} else {
|
||||
@ -47,5 +46,7 @@ var ReportLink = {
|
||||
const set = `toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,${dims}`
|
||||
return window.open(url, `report${id}`, set)
|
||||
},
|
||||
url: '',
|
||||
dims: ''
|
||||
}
|
||||
export default ReportLink
|
||||
@ -2,20 +2,16 @@ import $ from '../platform/$'
|
||||
import CSS from '../css/CSS'
|
||||
import { Conf } from '../globals/globals'
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
|
||||
const CustomCSS = {
|
||||
init() {
|
||||
init(): void {
|
||||
if (!Conf['Custom CSS']) {
|
||||
return
|
||||
}
|
||||
return this.addStyle()
|
||||
},
|
||||
|
||||
addStyle() {
|
||||
addStyle(): HTMLStyleElement {
|
||||
return (this.style = $.addStyle(
|
||||
CSS.sub(Conf['usercss']),
|
||||
'custom-css',
|
||||
@ -23,18 +19,18 @@ const CustomCSS = {
|
||||
))
|
||||
},
|
||||
|
||||
rmStyle() {
|
||||
rmStyle(): boolean {
|
||||
if (this.style) {
|
||||
$.rm(this.style)
|
||||
return delete this.style
|
||||
}
|
||||
},
|
||||
|
||||
update() {
|
||||
if (!this.style) {
|
||||
return this.addStyle()
|
||||
update(): void {
|
||||
if (this.style) {
|
||||
this.rmStyle()
|
||||
this.addStyle()
|
||||
}
|
||||
return (this.style.textContent = CSS.sub(Conf['usercss']))
|
||||
},
|
||||
}
|
||||
}
|
||||
export default CustomCSS
|
||||
@ -1,10 +1,10 @@
|
||||
import Callbacks from '../classes/Callbacks'
|
||||
import BoardConfig from '../General/BoardConfig'
|
||||
import { d, doc, g } from '../globals/globals'
|
||||
import Main from '../main/Main'
|
||||
import $ from '../platform/$'
|
||||
import $$ from '../platform/$$'
|
||||
import ExpandComment from './ExpandComment'
|
||||
import Callbacks from "../classes/Callbacks";
|
||||
import BoardConfig from "../General/BoardConfig";
|
||||
import { d, doc, g } from "../globals/globals";
|
||||
import Main from "../main/Main";
|
||||
import $ from "../platform/$";
|
||||
import $$ from "../platform/$$";
|
||||
import ExpandComment from "./ExpandComment";
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
@ -13,161 +13,110 @@ import ExpandComment from './ExpandComment'
|
||||
*/
|
||||
var Fourchan = {
|
||||
init() {
|
||||
if (
|
||||
g.SITE.software !== 'yotsuba' ||
|
||||
!['index', 'thread', 'archive'].includes(g.VIEW)
|
||||
) {
|
||||
return
|
||||
}
|
||||
BoardConfig.ready(this.initBoard)
|
||||
return Main.ready(this.initReady)
|
||||
if ((g.SITE.software !== 'yotsuba') || !['index', 'thread', 'archive'].includes(g.VIEW)) { return; }
|
||||
BoardConfig.ready(this.initBoard);
|
||||
return Main.ready(this.initReady);
|
||||
},
|
||||
|
||||
initBoard() {
|
||||
if (g.BOARD.config.code_tags) {
|
||||
$.on(window, 'prettyprint:cb', function (e) {
|
||||
let post, pre
|
||||
if (!(post = g.posts.get(e.detail.ID))) {
|
||||
return
|
||||
}
|
||||
if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) {
|
||||
return
|
||||
}
|
||||
let post, pre;
|
||||
if (!(post = g.posts.get(e.detail.ID))) { return; }
|
||||
if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { return; }
|
||||
if (!$.hasClass(pre, 'prettyprinted')) {
|
||||
pre.innerHTML = e.detail.html
|
||||
return $.addClass(pre, 'prettyprinted')
|
||||
pre.innerHTML = e.detail.html;
|
||||
return $.addClass(pre, 'prettyprinted');
|
||||
}
|
||||
})
|
||||
$.global(() =>
|
||||
window.addEventListener(
|
||||
'prettyprint',
|
||||
(e) =>
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('prettyprint:cb', {
|
||||
detail: {
|
||||
ID: e.detail.ID,
|
||||
i: e.detail.i,
|
||||
html: window.prettyPrintOne(e.detail.html),
|
||||
},
|
||||
}),
|
||||
),
|
||||
false,
|
||||
),
|
||||
)
|
||||
});
|
||||
$.global(() => window.addEventListener('prettyprint', e => window.dispatchEvent(new CustomEvent('prettyprint:cb', {
|
||||
detail: {
|
||||
ID: e.detail.ID,
|
||||
i: e.detail.i,
|
||||
html: window.prettyPrintOne(e.detail.html)
|
||||
}
|
||||
}))
|
||||
, false));
|
||||
Callbacks.Post.push({
|
||||
name: 'Parse [code] tags',
|
||||
cb: Fourchan.code,
|
||||
})
|
||||
cb: Fourchan.code
|
||||
});
|
||||
g.posts.forEach(function (post) {
|
||||
if (post.callbacksExecuted) {
|
||||
return Callbacks.Post.execute(post, ['Parse [code] tags'], true)
|
||||
return Callbacks.Post.execute(post, ['Parse [code] tags'], true);
|
||||
}
|
||||
})
|
||||
ExpandComment.callbacks.push(Fourchan.code)
|
||||
});
|
||||
ExpandComment.callbacks.push(Fourchan.code);
|
||||
}
|
||||
|
||||
if (g.BOARD.config.math_tags) {
|
||||
$.global(() =>
|
||||
window.addEventListener(
|
||||
'mathjax',
|
||||
function (e) {
|
||||
if (window.MathJax) {
|
||||
return window.MathJax.Hub.Queue([
|
||||
'Typeset',
|
||||
window.MathJax.Hub,
|
||||
e.target,
|
||||
])
|
||||
} else {
|
||||
if (
|
||||
!document.querySelector('script[src^="//cdn.mathjax.org/"]')
|
||||
) {
|
||||
// don't load MathJax if already loading
|
||||
window.loadMathJax()
|
||||
window.loadMathJax = function () {}
|
||||
}
|
||||
// 4chan only handles post comments on MathJax load; anything else (e.g. the QR preview) must be queued explicitly.
|
||||
if (!e.target.classList.contains('postMessage')) {
|
||||
return document
|
||||
.querySelector('script[src^="//cdn.mathjax.org/"]')
|
||||
.addEventListener(
|
||||
'load',
|
||||
() =>
|
||||
window.MathJax.Hub.Queue([
|
||||
'Typeset',
|
||||
window.MathJax.Hub,
|
||||
e.target,
|
||||
]),
|
||||
false,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
false,
|
||||
),
|
||||
)
|
||||
$.global(() => window.addEventListener('mathjax', function (e) {
|
||||
if (window.MathJax) {
|
||||
return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]);
|
||||
} else {
|
||||
if (!document.querySelector('script[src^="//cdn.mathjax.org/"]')) { // don't load MathJax if already loading
|
||||
window.loadMathJax();
|
||||
window.loadMathJax = function () { };
|
||||
}
|
||||
// 4chan only handles post comments on MathJax load; anything else (e.g. the QR preview) must be queued explicitly.
|
||||
if (!e.target.classList.contains('postMessage')) {
|
||||
return document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener('load', () => window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target])
|
||||
, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
, false));
|
||||
Callbacks.Post.push({
|
||||
name: 'Parse [math] tags',
|
||||
cb: Fourchan.math,
|
||||
})
|
||||
cb: Fourchan.math
|
||||
});
|
||||
g.posts.forEach(function (post) {
|
||||
if (post.callbacksExecuted) {
|
||||
return Callbacks.Post.execute(post, ['Parse [math] tags'], true)
|
||||
return Callbacks.Post.execute(post, ['Parse [math] tags'], true);
|
||||
}
|
||||
})
|
||||
return ExpandComment.callbacks.push(Fourchan.math)
|
||||
});
|
||||
return ExpandComment.callbacks.push(Fourchan.math);
|
||||
}
|
||||
},
|
||||
|
||||
// Disable 4chan's ID highlighting (replaced by IDHighlight) and reported post hiding.
|
||||
initReady() {
|
||||
return $.global(function () {
|
||||
window.clickable_ids = false
|
||||
window.clickable_ids = false;
|
||||
for (var node of document.querySelectorAll('.posteruid, .capcode')) {
|
||||
node.removeEventListener('click', window.idClick, false)
|
||||
node.removeEventListener('click', window.idClick, false);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
code() {
|
||||
if (this.isClone) {
|
||||
return
|
||||
}
|
||||
if (this.isClone) { return; }
|
||||
return $.ready(() => {
|
||||
const iterable = $$('.prettyprint', this.nodes.comment)
|
||||
const iterable = $$('.prettyprint', this.nodes.comment);
|
||||
for (let i = 0; i < iterable.length; i++) {
|
||||
var pre = iterable[i]
|
||||
var pre = iterable[i];
|
||||
if (!$.hasClass(pre, 'prettyprinted')) {
|
||||
$.event(
|
||||
'prettyprint',
|
||||
{ ID: this.fullID, i, html: pre.innerHTML },
|
||||
window,
|
||||
)
|
||||
$.event('prettyprint', { ID: this.fullID, i, html: pre.innerHTML }, window);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
math() {
|
||||
let wbrs
|
||||
if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) {
|
||||
return
|
||||
}
|
||||
let wbrs;
|
||||
if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { return; }
|
||||
// XXX <wbr> tags frequently break MathJax; remove them.
|
||||
if ((wbrs = $$('wbr', this.nodes.comment)).length) {
|
||||
for (var wbr of wbrs) {
|
||||
$.rm(wbr)
|
||||
}
|
||||
this.nodes.comment.normalize()
|
||||
for (var wbr of wbrs) { $.rm(wbr); }
|
||||
this.nodes.comment.normalize();
|
||||
}
|
||||
var cb = () => {
|
||||
if (!doc.contains(this.nodes.comment)) {
|
||||
return
|
||||
}
|
||||
$.off(d, 'PostsInserted', cb)
|
||||
return $.event('mathjax', null, this.nodes.comment)
|
||||
}
|
||||
$.on(d, 'PostsInserted', cb)
|
||||
return cb()
|
||||
},
|
||||
}
|
||||
export default Fourchan
|
||||
if (!doc.contains(this.nodes.comment)) { return; }
|
||||
$.off(d, 'PostsInserted', cb);
|
||||
return $.event('mathjax', null, this.nodes.comment);
|
||||
};
|
||||
$.on(d, 'PostsInserted', cb);
|
||||
return cb();
|
||||
}
|
||||
};
|
||||
export default Fourchan;
|
||||
|
||||
@ -1,70 +1,55 @@
|
||||
import Callbacks from '../classes/Callbacks'
|
||||
import { g, Conf } from '../globals/globals'
|
||||
import $ from '../platform/$'
|
||||
import { dict } from '../platform/helpers'
|
||||
import Callbacks from "../classes/Callbacks";
|
||||
import { g, Conf } from "../globals/globals";
|
||||
import $ from "../platform/$";
|
||||
import { dict } from "../platform/helpers";
|
||||
|
||||
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
var IDColor = {
|
||||
init() {
|
||||
if (!['index', 'thread'].includes(g.VIEW) || !Conf['Color User IDs']) {
|
||||
return
|
||||
}
|
||||
this.ids = dict()
|
||||
this.ids['Heaven'] = [0, 0, 0, '#fff']
|
||||
if (!['index', 'thread'].includes(g.VIEW) || !Conf['Color User IDs']) { return; }
|
||||
this.ids = dict();
|
||||
this.ids['Heaven'] = [0, 0, 0, '#fff'];
|
||||
|
||||
return Callbacks.Post.push({
|
||||
name: 'Color User IDs',
|
||||
cb: this.node,
|
||||
})
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
|
||||
node() {
|
||||
let span, uid
|
||||
if (
|
||||
this.isClone ||
|
||||
!((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))
|
||||
) {
|
||||
return
|
||||
}
|
||||
let span, uid;
|
||||
if (this.isClone || !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))) { return; }
|
||||
|
||||
const rgb = IDColor.ids[uid] || IDColor.compute(uid)
|
||||
const rgb = IDColor.ids[uid] || IDColor.compute(uid);
|
||||
|
||||
// Style the damn node.
|
||||
const { style } = span
|
||||
style.color = rgb[3]
|
||||
style.backgroundColor = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`
|
||||
return $.addClass(span, 'painted')
|
||||
const { style } = span;
|
||||
style.color = rgb[3];
|
||||
style.backgroundColor = `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`;
|
||||
return $.addClass(span, 'painted');
|
||||
},
|
||||
|
||||
compute(uid) {
|
||||
// Convert chars to integers, bitshift and math to create a larger integer
|
||||
// Create a nice string of binary
|
||||
let hash;
|
||||
if (typeof g !== 'undefined' && g.SITE && g.SITE.uidColor) {
|
||||
hash = g.SITE.uidColor(uid);
|
||||
} else {
|
||||
hash = parseInt(uid, 16);
|
||||
}
|
||||
|
||||
const hash = g.SITE.uidColor ? g.SITE.uidColor(uid) : parseInt(uid, 16);
|
||||
|
||||
// Convert binary string to numerical values with bitshift and '&' truncation.
|
||||
const rgb = [(hash >> 16) & 0xff, (hash >> 8) & 0xff, hash & 0xff];
|
||||
|
||||
// Weight color luminance values, assign a font color that should be readable.
|
||||
const fontColor = $.luma ? ($.luma(rgb) > 125 ? '#000' : '#fff') : '#000';
|
||||
|
||||
// Cache color and font color.
|
||||
const colorCode = `rgb(${rgb.join(',')})`;
|
||||
this.ids[uid] = {
|
||||
color: colorCode,
|
||||
fontColor: fontColor
|
||||
};
|
||||
|
||||
// Return only the color.
|
||||
return colorCode;
|
||||
},
|
||||
}
|
||||
export default IDColor
|
||||
const rgb = [
|
||||
(hash >> 16) & 0xFF,
|
||||
(hash >> 8) & 0xFF,
|
||||
hash & 0xFF
|
||||
];
|
||||
|
||||
// Weight color luminance values, assign a font color that should be readable.
|
||||
rgb.push($.luma(rgb) > 125 ?
|
||||
'#000'
|
||||
:
|
||||
'#fff'
|
||||
);
|
||||
|
||||
// Cache.
|
||||
return this.ids[uid] = rgb;
|
||||
}
|
||||
};
|
||||
export default IDColor;
|
||||
|
||||
@ -1,50 +1,37 @@
|
||||
import Callbacks from '../classes/Callbacks'
|
||||
import { g } from '../globals/globals'
|
||||
import $ from '../platform/$'
|
||||
import Callbacks from "../classes/Callbacks";
|
||||
import { g } 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
|
||||
*/
|
||||
var IDHighlight = {
|
||||
init() {
|
||||
if (!['index', 'thread'].includes(g.VIEW)) {
|
||||
return
|
||||
}
|
||||
if (!['index', 'thread'].includes(g.VIEW)) { return; }
|
||||
|
||||
return Callbacks.Post.push({
|
||||
name: 'Highlight by User ID',
|
||||
cb: this.node,
|
||||
})
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
|
||||
uniqueID: null,
|
||||
|
||||
node() {
|
||||
if (this.nodes.uniqueIDRoot) {
|
||||
$.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this))
|
||||
}
|
||||
if (this.nodes.capcode) {
|
||||
$.on(this.nodes.capcode, 'click', IDHighlight.click(this))
|
||||
}
|
||||
if (!this.isClone) {
|
||||
return IDHighlight.set(this)
|
||||
}
|
||||
if (this.nodes.uniqueIDRoot) { $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)); }
|
||||
if (this.nodes.capcode) { $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); }
|
||||
if (!this.isClone) { return IDHighlight.set(this); }
|
||||
},
|
||||
|
||||
set(post) {
|
||||
const match =
|
||||
(post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID
|
||||
return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight')
|
||||
const match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID;
|
||||
return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight');
|
||||
},
|
||||
|
||||
click(post) {
|
||||
return function () {
|
||||
const uniqueID = post.info.uniqueID || post.info.capcode
|
||||
IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID
|
||||
return g.posts.forEach(IDHighlight.set)
|
||||
}
|
||||
},
|
||||
}
|
||||
export default IDHighlight
|
||||
const uniqueID = post.info.uniqueID || post.info.capcode;
|
||||
IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID;
|
||||
return g.posts.forEach(IDHighlight.set);
|
||||
};
|
||||
}
|
||||
};
|
||||
export default IDHighlight;
|
||||
|
||||
@ -4,15 +4,15 @@ import Main from '../main/Main'
|
||||
import $ from '../platform/$'
|
||||
|
||||
const PSA = {
|
||||
init() {
|
||||
let el
|
||||
init(): void {
|
||||
let el: HTMLElement
|
||||
if (g.SITE.software === 'yotsuba' && g.BOARD.ID === 'qa') {
|
||||
const announcement = {
|
||||
innerHTML:
|
||||
'Stay in touch with your <a href="https://www.4chan-x.net/qa_friends.html" target="_blank" rel="noopener">/qa/ friends</a>!',
|
||||
}
|
||||
el = $.el('div', { className: 'fcx-announcement' }, announcement)
|
||||
$.onExists(doc, '.boardBanner', (banner) => $.after(banner, el))
|
||||
el = $.el('span', announcement) as HTMLElement
|
||||
$.onExists(doc, '.boardBanner', (banner: HTMLElement) => $.after(banner, el))
|
||||
}
|
||||
if (
|
||||
'samachan.org' in Conf['siteProperties'] &&
|
||||
@ -8,7 +8,7 @@ import { g, Conf } from '../globals/globals'
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||
*/
|
||||
var Time = {
|
||||
init() {
|
||||
init(): VoidFunction {
|
||||
if (
|
||||
!['index', 'thread', 'archive'].includes(g.VIEW) ||
|
||||
!Conf['Time Formatting']
|
||||
@ -22,18 +22,15 @@ var Time = {
|
||||
})
|
||||
},
|
||||
|
||||
node() {
|
||||
if (!this.info.date || this.isClone) {
|
||||
return
|
||||
node(): any {
|
||||
if (!this.info.date || this.isClone) {
|
||||
return;
|
||||
}
|
||||
const { textContent } = this.nodes.date
|
||||
return (this.nodes.date.textContent =
|
||||
textContent.match(/^\s*/)[0] +
|
||||
Time.format(Conf['time'], this.info.date) +
|
||||
textContent.match(/\s*$/)[0])
|
||||
const { textContent } = this.nodes.date;
|
||||
return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0];
|
||||
},
|
||||
|
||||
format(formatString, date) {
|
||||
format(formatString: string, date: Date): string {
|
||||
return formatString.replace(/%(.)/g, function (s, c) {
|
||||
if ($.hasOwn(Time.formatters, c)) {
|
||||
return Time.formatters[c].call(date)
|
||||
@ -68,16 +65,16 @@ var Time = {
|
||||
'December',
|
||||
],
|
||||
|
||||
localeFormat(date, options, defaultValue) {
|
||||
localeFormat(date: Date, options: any, defaultValue: string): string {
|
||||
if (Conf['timeLocale']) {
|
||||
try {
|
||||
return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date)
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
}
|
||||
return defaultValue
|
||||
},
|
||||
|
||||
localeFormatPart(date, options, part, defaultValue) {
|
||||
localeFormatPart(date: Date, options: any, part: string, defaultValue: string): string {
|
||||
if (Conf['timeLocale']) {
|
||||
try {
|
||||
const parts = Intl.DateTimeFormat(
|
||||
@ -93,12 +90,12 @@ var Time = {
|
||||
}
|
||||
})
|
||||
.join('')
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
}
|
||||
return defaultValue
|
||||
},
|
||||
|
||||
zeroPad(n) {
|
||||
zeroPad(n: number): number | string {
|
||||
if (n < 10) {
|
||||
return `0${n}`
|
||||
} else {
|
||||
@ -107,59 +104,59 @@ var Time = {
|
||||
},
|
||||
|
||||
formatters: {
|
||||
a() {
|
||||
a(): string {
|
||||
return Time.localeFormat(
|
||||
this,
|
||||
{ weekday: 'short' },
|
||||
Time.day[this.getDay()].slice(0, 3),
|
||||
)
|
||||
},
|
||||
A() {
|
||||
A(): string {
|
||||
return Time.localeFormat(
|
||||
this,
|
||||
{ weekday: 'long' },
|
||||
Time.day[this.getDay()],
|
||||
)
|
||||
},
|
||||
b() {
|
||||
b(): string {
|
||||
return Time.localeFormat(
|
||||
this,
|
||||
{ month: 'short' },
|
||||
Time.month[this.getMonth()].slice(0, 3),
|
||||
)
|
||||
},
|
||||
B() {
|
||||
B(): string {
|
||||
return Time.localeFormat(
|
||||
this,
|
||||
{ month: 'long' },
|
||||
Time.month[this.getMonth()],
|
||||
)
|
||||
},
|
||||
d() {
|
||||
d(): string | number {
|
||||
return Time.zeroPad(this.getDate())
|
||||
},
|
||||
e() {
|
||||
e(): number {
|
||||
return this.getDate()
|
||||
},
|
||||
H() {
|
||||
H(): string | number {
|
||||
return Time.zeroPad(this.getHours())
|
||||
},
|
||||
I() {
|
||||
I(): string | number {
|
||||
return Time.zeroPad(this.getHours() % 12 || 12)
|
||||
},
|
||||
k() {
|
||||
k(): number {
|
||||
return this.getHours()
|
||||
},
|
||||
l() {
|
||||
l(): number {
|
||||
return this.getHours() % 12 || 12
|
||||
},
|
||||
m() {
|
||||
m(): string | number {
|
||||
return Time.zeroPad(this.getMonth() + 1)
|
||||
},
|
||||
M() {
|
||||
M(): string | number {
|
||||
return Time.zeroPad(this.getMinutes())
|
||||
},
|
||||
p() {
|
||||
p(): string {
|
||||
return Time.localeFormatPart(
|
||||
this,
|
||||
{ hour: 'numeric', hour12: true },
|
||||
@ -167,19 +164,19 @@ var Time = {
|
||||
this.getHours() < 12 ? 'AM' : 'PM',
|
||||
)
|
||||
},
|
||||
P() {
|
||||
P(): string {
|
||||
return Time.formatters.p.call(this).toLowerCase()
|
||||
},
|
||||
S() {
|
||||
S(): string | number {
|
||||
return Time.zeroPad(this.getSeconds())
|
||||
},
|
||||
y() {
|
||||
y(): string {
|
||||
return this.getFullYear().toString().slice(2)
|
||||
},
|
||||
Y() {
|
||||
Y(): number {
|
||||
return this.getFullYear()
|
||||
},
|
||||
'%'() {
|
||||
'%'(): string {
|
||||
return '%'
|
||||
},
|
||||
},
|
||||
@ -1,5 +1,5 @@
|
||||
import SWTinyboard from './SW.tinyboard'
|
||||
import SWYotsuba from './SW.yotsuba'
|
||||
|
||||
const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba }
|
||||
const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba } as const
|
||||
export default SW
|
||||
@ -19,7 +19,7 @@ var Site = {
|
||||
'smug.nepu.moe': { canonical: 'smuglo.li' },
|
||||
},
|
||||
|
||||
init(cb) {
|
||||
init(cb: () => void): void {
|
||||
$.extend(Conf['siteProperties'], Site.defaultProperties)
|
||||
let hostname = Site.resolve()
|
||||
if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) {
|
||||
@ -28,7 +28,7 @@ var Site = {
|
||||
}
|
||||
return $.onExists(doc, 'body', () => {
|
||||
for (var software in SW) {
|
||||
var changes
|
||||
var changes: { [key: string]: string }
|
||||
if ((changes = SW[software].detect?.())) {
|
||||
changes.software = software
|
||||
hostname = location.hostname.replace(/^www\./, '')
|
||||
@ -55,7 +55,7 @@ var Site = {
|
||||
})
|
||||
},
|
||||
|
||||
resolve(url = location) {
|
||||
resolve(url = location): string {
|
||||
let { hostname } = url
|
||||
while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) {
|
||||
hostname = hostname.replace(/^[^.]*\.?/, '')
|
||||
@ -69,14 +69,14 @@ var Site = {
|
||||
return hostname
|
||||
},
|
||||
|
||||
parseURL(url) {
|
||||
const siteID = Site.resolve(url)
|
||||
return Main.parseURL(g.sites[siteID], url)
|
||||
parseURL(url: Location): ReturnType<typeof Main.parseURL> {
|
||||
var siteID = Site.resolve(url)
|
||||
return siteID ? g.sites[siteID].parseURL(url) : null
|
||||
},
|
||||
|
||||
set(hostname) {
|
||||
set(hostname: string): typeof g.SITE {
|
||||
for (var ID in Conf['siteProperties']) {
|
||||
var site
|
||||
var site: typeof g.SITE
|
||||
var properties = Conf['siteProperties'][ID]
|
||||
if (properties.canonical) {
|
||||
continue
|
||||
Loading…
x
Reference in New Issue
Block a user