Fix inlining/previewing of archive links like quote links. #5
This commit is contained in:
parent
3f34c5fb75
commit
144143e2b0
@ -3,6 +3,10 @@
|
|||||||
4chan XT uses a different user script namespace, so to migrate you need to export settings from 4chan X, and import them
|
4chan XT uses a different user script namespace, so to migrate you need to export settings from 4chan X, and import them
|
||||||
in XT.
|
in XT.
|
||||||
|
|
||||||
|
### XT v2.1.2 (2023-07-22)
|
||||||
|
|
||||||
|
- Fix inlining/previewing of archive links like quote links. [#5](https://github.com/TuxedoTako/4chan-xt/issues/5)
|
||||||
|
|
||||||
### XT v2.1.1 (2023-07-16)
|
### XT v2.1.1 (2023-07-16)
|
||||||
|
|
||||||
- Time formatting now falls back to browser locale instead of giving an error when the locale is not set.
|
- Time formatting now falls back to browser locale instead of giving an error when the locale is not set.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan XT
|
// @name 4chan XT
|
||||||
// @version XT 2.1.1
|
// @version XT 2.1.2
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 74
|
// @minFFVer 74
|
||||||
// @namespace 4chan-XT
|
// @namespace 4chan-XT
|
||||||
@ -190,8 +190,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var version = {
|
var version = {
|
||||||
"version": "XT 2.1.1",
|
"version": "XT 2.1.2",
|
||||||
"date": "2023-07-16T08:49:02.722Z"
|
"date": "2023-07-22T15:46:24.103Z"
|
||||||
};
|
};
|
||||||
|
|
||||||
var meta = {
|
var meta = {
|
||||||
@ -6938,6 +6938,61 @@ https://*.hcaptcha.com
|
|||||||
};
|
};
|
||||||
var ThreadWatcher$1 = ThreadWatcher;
|
var ThreadWatcher$1 = ThreadWatcher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file has the code for the jsx to { innerHTML: "safe string" }
|
||||||
|
*
|
||||||
|
* Usage: import h from this file.
|
||||||
|
* Attributes are stringified raw, so the names must be like html text: eg class and not className.
|
||||||
|
* Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted.
|
||||||
|
* Strings bound to attributes and children will be escaped automatically.
|
||||||
|
* It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true }
|
||||||
|
*
|
||||||
|
* For strings that don't have a parent element you can use fragments: <></>.
|
||||||
|
* Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports"
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The symbol indicating that a string is safely escaped.
|
||||||
|
* This is a symbol so it can't be faked by a json blob from the internet.
|
||||||
|
*/
|
||||||
|
const isEscaped = Symbol('isEscaped');
|
||||||
|
const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]);
|
||||||
|
const hFragment = Symbol('hFragment');
|
||||||
|
/** Function that jsx/tsx will be compiled to. */
|
||||||
|
function h(tag, attributes, ...children) {
|
||||||
|
let innerHTML = tag === hFragment ? '' : `<${tag}`;
|
||||||
|
if (attributes) {
|
||||||
|
for (const [attribute, value] of Object.entries(attributes)) {
|
||||||
|
if (!value && value !== 0)
|
||||||
|
continue;
|
||||||
|
innerHTML += ` ${attribute}`;
|
||||||
|
if (value === true)
|
||||||
|
continue;
|
||||||
|
innerHTML += `="${E(value.toString())}"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tag !== hFragment)
|
||||||
|
innerHTML += '>';
|
||||||
|
const isVoid = tag !== hFragment && voidElements.has(tag);
|
||||||
|
if (isVoid) {
|
||||||
|
if (children.length)
|
||||||
|
throw new TypeError(`${tag} is a void html element and can't have child elements`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (const child of children) {
|
||||||
|
if (child === null || child === undefined || child === '')
|
||||||
|
continue;
|
||||||
|
if (child instanceof Object && "innerHTML" in child && child[isEscaped]) {
|
||||||
|
innerHTML += child.innerHTML;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
innerHTML += E(child.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isVoid && tag !== hFragment)
|
||||||
|
innerHTML += `</${tag}>`;
|
||||||
|
return { innerHTML, [isEscaped]: true };
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
* DS102: Remove unnecessary code created because of implicit returns
|
||||||
@ -6947,32 +7002,30 @@ https://*.hcaptcha.com
|
|||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||||
*/
|
*/
|
||||||
class Fetcher {
|
class Fetcher {
|
||||||
static initClass() {
|
static archiveTags = {
|
||||||
|
'\n': {innerHTML: "<br>"},
|
||||||
|
'[b]': {innerHTML: "<b>"},
|
||||||
|
'[/b]': {innerHTML: "</b>"},
|
||||||
|
'[spoiler]': {innerHTML: "<s>"},
|
||||||
|
'[/spoiler]': {innerHTML: "</s>"},
|
||||||
|
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
||||||
|
'[/code]': {innerHTML: "</pre>"},
|
||||||
|
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
||||||
|
'[/moot]': {innerHTML: "</div>"},
|
||||||
|
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
||||||
|
'[/banned]': {innerHTML: "</strong>"},
|
||||||
|
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
||||||
|
'[/fortune]': {innerHTML: "</b></span>"},
|
||||||
|
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
||||||
|
'[/i]': {innerHTML: "</span>"},
|
||||||
|
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
||||||
|
'[/red]': {innerHTML: "</span>"},
|
||||||
|
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
||||||
|
'[/green]': {innerHTML: "</span>"},
|
||||||
|
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
||||||
|
'[/blue]': {innerHTML: "</span>"}
|
||||||
|
};
|
||||||
|
|
||||||
this.prototype.archiveTags = {
|
|
||||||
'\n': {innerHTML: "<br>"},
|
|
||||||
'[b]': {innerHTML: "<b>"},
|
|
||||||
'[/b]': {innerHTML: "</b>"},
|
|
||||||
'[spoiler]': {innerHTML: "<s>"},
|
|
||||||
'[/spoiler]': {innerHTML: "</s>"},
|
|
||||||
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
|
||||||
'[/code]': {innerHTML: "</pre>"},
|
|
||||||
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
|
||||||
'[/moot]': {innerHTML: "</div>"},
|
|
||||||
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
|
||||||
'[/banned]': {innerHTML: "</strong>"},
|
|
||||||
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
|
||||||
'[/fortune]': {innerHTML: "</b></span>"},
|
|
||||||
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
|
||||||
'[/i]': {innerHTML: "</span>"},
|
|
||||||
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
|
||||||
'[/red]': {innerHTML: "</span>"},
|
|
||||||
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
|
||||||
'[/green]': {innerHTML: "</span>"},
|
|
||||||
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
|
||||||
'[/blue]': {innerHTML: "</span>"}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
constructor(boardID, threadID, postID, root, quoter) {
|
constructor(boardID, threadID, postID, root, quoter) {
|
||||||
let post, thread;
|
let post, thread;
|
||||||
this.boardID = boardID;
|
this.boardID = boardID;
|
||||||
@ -7153,25 +7206,21 @@ https://*.hcaptcha.com
|
|||||||
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
||||||
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
||||||
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
||||||
comment = (() => {
|
comment = comment.map((text, i) => {
|
||||||
const result = [];
|
if ((i % 2) === 1) {
|
||||||
for (let i = 0; i < comment.length; i++) {
|
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
||||||
var text = comment[i];
|
return (typeof tag === 'function') ? tag(text) : tag;
|
||||||
if ((i % 2) === 1) {
|
} else {
|
||||||
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
var greentext = text[0] === '>';
|
||||||
if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); }
|
text = text
|
||||||
} else {
|
.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2')
|
||||||
var greentext = text[0] === '>';
|
.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g)
|
||||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
.map((text2, j) => ((j % 2) ? `<span class="deadlink">${E(text2)}</span>`: E(text2)))
|
||||||
text = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map((text2, j) =>
|
.join('');
|
||||||
{((j % 2) ? "<span class=\"deadlink\">" + E(text2) + "</span>" : E(text2));});
|
return {innerHTML: (greentext ? `<span class="quote">${text}</span>` : text)};
|
||||||
text = {innerHTML: ((greentext) ? "<span class=\"quote\">" + E.cat(text) + "</span>" : E.cat(text))};
|
|
||||||
result.push(text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
});
|
||||||
})();
|
comment = { innerHTML: E.cat(comment), [isEscaped]: true };
|
||||||
comment = {innerHTML: E.cat(comment)};
|
|
||||||
|
|
||||||
this.threadID = +data.thread_num;
|
this.threadID = +data.thread_num;
|
||||||
const o = {
|
const o = {
|
||||||
@ -7244,7 +7293,6 @@ https://*.hcaptcha.com
|
|||||||
return this.insert(post);
|
return this.insert(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fetcher.initClass();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
@ -7283,7 +7331,7 @@ https://*.hcaptcha.com
|
|||||||
|
|
||||||
mouseover(e) {
|
mouseover(e) {
|
||||||
let origin;
|
let origin;
|
||||||
if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc, 'catalog-mode')) || !d$1.contains(this)) { return; }
|
if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc$1, 'catalog-mode')) || !d$1.contains(this)) { return; }
|
||||||
|
|
||||||
const {boardID, threadID, postID} = Get$1.postDataFromLink(this);
|
const {boardID, threadID, postID} = Get$1.postDataFromLink(this);
|
||||||
|
|
||||||
@ -8868,61 +8916,6 @@ https://*.hcaptcha.com
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* This file has the code for the jsx to { innerHTML: "safe string" }
|
|
||||||
*
|
|
||||||
* Usage: import h from this file.
|
|
||||||
* Attributes are stringified raw, so the names must be like html text: eg class and not className.
|
|
||||||
* Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted.
|
|
||||||
* Strings bound to attributes and children will be escaped automatically.
|
|
||||||
* It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true }
|
|
||||||
*
|
|
||||||
* For strings that don't have a parent element you can use fragments: <></>.
|
|
||||||
* Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports"
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* The symbol indicating that a string is safely escaped.
|
|
||||||
* This is a symbol so it can't be faked by a json blob from the internet.
|
|
||||||
*/
|
|
||||||
const isEscaped = Symbol('isEscaped');
|
|
||||||
const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]);
|
|
||||||
const hFragment = Symbol('hFragment');
|
|
||||||
/** Function that jsx/tsx will be compiled to. */
|
|
||||||
function h(tag, attributes, ...children) {
|
|
||||||
let innerHTML = tag === hFragment ? '' : `<${tag}`;
|
|
||||||
if (attributes) {
|
|
||||||
for (const [attribute, value] of Object.entries(attributes)) {
|
|
||||||
if (!value && value !== 0)
|
|
||||||
continue;
|
|
||||||
innerHTML += ` ${attribute}`;
|
|
||||||
if (value === true)
|
|
||||||
continue;
|
|
||||||
innerHTML += `="${E(value.toString())}"`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tag !== hFragment)
|
|
||||||
innerHTML += '>';
|
|
||||||
const isVoid = tag !== hFragment && voidElements.has(tag);
|
|
||||||
if (isVoid) {
|
|
||||||
if (children.length)
|
|
||||||
throw new TypeError(`${tag} is a void html element and can't have child elements`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (const child of children) {
|
|
||||||
if (child === null || child === undefined || child === '')
|
|
||||||
continue;
|
|
||||||
if (child instanceof Object && "innerHTML" in child && child[isEscaped]) {
|
|
||||||
innerHTML += child.innerHTML;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
innerHTML += E(child.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isVoid && tag !== hFragment)
|
|
||||||
innerHTML += `</${tag}>`;
|
|
||||||
return { innerHTML, [isEscaped]: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
// \u00A0 is non breaking space
|
// \u00A0 is non breaking space
|
||||||
const separator = '\u00A0|\u00A0';
|
const separator = '\u00A0|\u00A0';
|
||||||
const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" },
|
const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" },
|
||||||
|
|||||||
144
builds/4chan-XT-noupdate.user.min.js
vendored
144
builds/4chan-XT-noupdate.user.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan XT",
|
"name": "4chan XT",
|
||||||
"version": "XT 2.1.1",
|
"version": "XT 2.1.2",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "4chan XT is a script that adds various features to anonymous imageboards.",
|
"description": "4chan XT is a script that adds various features to anonymous imageboards.",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
|||||||
@ -79,8 +79,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var version = {
|
var version = {
|
||||||
"version": "XT 2.1.1",
|
"version": "XT 2.1.2",
|
||||||
"date": "2023-07-16T08:49:02.722Z"
|
"date": "2023-07-22T15:46:24.103Z"
|
||||||
};
|
};
|
||||||
|
|
||||||
var meta = {
|
var meta = {
|
||||||
@ -6827,6 +6827,61 @@ https://*.hcaptcha.com
|
|||||||
};
|
};
|
||||||
var ThreadWatcher$1 = ThreadWatcher;
|
var ThreadWatcher$1 = ThreadWatcher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file has the code for the jsx to { innerHTML: "safe string" }
|
||||||
|
*
|
||||||
|
* Usage: import h from this file.
|
||||||
|
* Attributes are stringified raw, so the names must be like html text: eg class and not className.
|
||||||
|
* Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted.
|
||||||
|
* Strings bound to attributes and children will be escaped automatically.
|
||||||
|
* It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true }
|
||||||
|
*
|
||||||
|
* For strings that don't have a parent element you can use fragments: <></>.
|
||||||
|
* Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports"
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* The symbol indicating that a string is safely escaped.
|
||||||
|
* This is a symbol so it can't be faked by a json blob from the internet.
|
||||||
|
*/
|
||||||
|
const isEscaped = Symbol('isEscaped');
|
||||||
|
const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]);
|
||||||
|
const hFragment = Symbol('hFragment');
|
||||||
|
/** Function that jsx/tsx will be compiled to. */
|
||||||
|
function h(tag, attributes, ...children) {
|
||||||
|
let innerHTML = tag === hFragment ? '' : `<${tag}`;
|
||||||
|
if (attributes) {
|
||||||
|
for (const [attribute, value] of Object.entries(attributes)) {
|
||||||
|
if (!value && value !== 0)
|
||||||
|
continue;
|
||||||
|
innerHTML += ` ${attribute}`;
|
||||||
|
if (value === true)
|
||||||
|
continue;
|
||||||
|
innerHTML += `="${E(value.toString())}"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tag !== hFragment)
|
||||||
|
innerHTML += '>';
|
||||||
|
const isVoid = tag !== hFragment && voidElements.has(tag);
|
||||||
|
if (isVoid) {
|
||||||
|
if (children.length)
|
||||||
|
throw new TypeError(`${tag} is a void html element and can't have child elements`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (const child of children) {
|
||||||
|
if (child === null || child === undefined || child === '')
|
||||||
|
continue;
|
||||||
|
if (child instanceof Object && "innerHTML" in child && child[isEscaped]) {
|
||||||
|
innerHTML += child.innerHTML;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
innerHTML += E(child.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isVoid && tag !== hFragment)
|
||||||
|
innerHTML += `</${tag}>`;
|
||||||
|
return { innerHTML, [isEscaped]: true };
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
* DS102: Remove unnecessary code created because of implicit returns
|
||||||
@ -6836,32 +6891,30 @@ https://*.hcaptcha.com
|
|||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||||
*/
|
*/
|
||||||
class Fetcher {
|
class Fetcher {
|
||||||
static initClass() {
|
static archiveTags = {
|
||||||
|
'\n': {innerHTML: "<br>"},
|
||||||
|
'[b]': {innerHTML: "<b>"},
|
||||||
|
'[/b]': {innerHTML: "</b>"},
|
||||||
|
'[spoiler]': {innerHTML: "<s>"},
|
||||||
|
'[/spoiler]': {innerHTML: "</s>"},
|
||||||
|
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
||||||
|
'[/code]': {innerHTML: "</pre>"},
|
||||||
|
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
||||||
|
'[/moot]': {innerHTML: "</div>"},
|
||||||
|
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
||||||
|
'[/banned]': {innerHTML: "</strong>"},
|
||||||
|
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
||||||
|
'[/fortune]': {innerHTML: "</b></span>"},
|
||||||
|
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
||||||
|
'[/i]': {innerHTML: "</span>"},
|
||||||
|
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
||||||
|
'[/red]': {innerHTML: "</span>"},
|
||||||
|
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
||||||
|
'[/green]': {innerHTML: "</span>"},
|
||||||
|
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
||||||
|
'[/blue]': {innerHTML: "</span>"}
|
||||||
|
};
|
||||||
|
|
||||||
this.prototype.archiveTags = {
|
|
||||||
'\n': {innerHTML: "<br>"},
|
|
||||||
'[b]': {innerHTML: "<b>"},
|
|
||||||
'[/b]': {innerHTML: "</b>"},
|
|
||||||
'[spoiler]': {innerHTML: "<s>"},
|
|
||||||
'[/spoiler]': {innerHTML: "</s>"},
|
|
||||||
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
|
||||||
'[/code]': {innerHTML: "</pre>"},
|
|
||||||
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
|
||||||
'[/moot]': {innerHTML: "</div>"},
|
|
||||||
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
|
||||||
'[/banned]': {innerHTML: "</strong>"},
|
|
||||||
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
|
||||||
'[/fortune]': {innerHTML: "</b></span>"},
|
|
||||||
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
|
||||||
'[/i]': {innerHTML: "</span>"},
|
|
||||||
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
|
||||||
'[/red]': {innerHTML: "</span>"},
|
|
||||||
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
|
||||||
'[/green]': {innerHTML: "</span>"},
|
|
||||||
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
|
||||||
'[/blue]': {innerHTML: "</span>"}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
constructor(boardID, threadID, postID, root, quoter) {
|
constructor(boardID, threadID, postID, root, quoter) {
|
||||||
let post, thread;
|
let post, thread;
|
||||||
this.boardID = boardID;
|
this.boardID = boardID;
|
||||||
@ -7042,25 +7095,21 @@ https://*.hcaptcha.com
|
|||||||
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
||||||
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
||||||
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
||||||
comment = (() => {
|
comment = comment.map((text, i) => {
|
||||||
const result = [];
|
if ((i % 2) === 1) {
|
||||||
for (let i = 0; i < comment.length; i++) {
|
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
||||||
var text = comment[i];
|
return (typeof tag === 'function') ? tag(text) : tag;
|
||||||
if ((i % 2) === 1) {
|
} else {
|
||||||
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
var greentext = text[0] === '>';
|
||||||
if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); }
|
text = text
|
||||||
} else {
|
.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2')
|
||||||
var greentext = text[0] === '>';
|
.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g)
|
||||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
.map((text2, j) => ((j % 2) ? `<span class="deadlink">${E(text2)}</span>`: E(text2)))
|
||||||
text = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map((text2, j) =>
|
.join('');
|
||||||
{((j % 2) ? "<span class=\"deadlink\">" + E(text2) + "</span>" : E(text2));});
|
return {innerHTML: (greentext ? `<span class="quote">${text}</span>` : text)};
|
||||||
text = {innerHTML: ((greentext) ? "<span class=\"quote\">" + E.cat(text) + "</span>" : E.cat(text))};
|
|
||||||
result.push(text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
});
|
||||||
})();
|
comment = { innerHTML: E.cat(comment), [isEscaped]: true };
|
||||||
comment = {innerHTML: E.cat(comment)};
|
|
||||||
|
|
||||||
this.threadID = +data.thread_num;
|
this.threadID = +data.thread_num;
|
||||||
const o = {
|
const o = {
|
||||||
@ -7133,7 +7182,6 @@ https://*.hcaptcha.com
|
|||||||
return this.insert(post);
|
return this.insert(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fetcher.initClass();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
@ -7172,7 +7220,7 @@ https://*.hcaptcha.com
|
|||||||
|
|
||||||
mouseover(e) {
|
mouseover(e) {
|
||||||
let origin;
|
let origin;
|
||||||
if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc, 'catalog-mode')) || !d$1.contains(this)) { return; }
|
if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc$1, 'catalog-mode')) || !d$1.contains(this)) { return; }
|
||||||
|
|
||||||
const {boardID, threadID, postID} = Get$1.postDataFromLink(this);
|
const {boardID, threadID, postID} = Get$1.postDataFromLink(this);
|
||||||
|
|
||||||
@ -8757,61 +8805,6 @@ https://*.hcaptcha.com
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* This file has the code for the jsx to { innerHTML: "safe string" }
|
|
||||||
*
|
|
||||||
* Usage: import h from this file.
|
|
||||||
* Attributes are stringified raw, so the names must be like html text: eg class and not className.
|
|
||||||
* Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted.
|
|
||||||
* Strings bound to attributes and children will be escaped automatically.
|
|
||||||
* It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true }
|
|
||||||
*
|
|
||||||
* For strings that don't have a parent element you can use fragments: <></>.
|
|
||||||
* Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports"
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* The symbol indicating that a string is safely escaped.
|
|
||||||
* This is a symbol so it can't be faked by a json blob from the internet.
|
|
||||||
*/
|
|
||||||
const isEscaped = Symbol('isEscaped');
|
|
||||||
const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]);
|
|
||||||
const hFragment = Symbol('hFragment');
|
|
||||||
/** Function that jsx/tsx will be compiled to. */
|
|
||||||
function h(tag, attributes, ...children) {
|
|
||||||
let innerHTML = tag === hFragment ? '' : `<${tag}`;
|
|
||||||
if (attributes) {
|
|
||||||
for (const [attribute, value] of Object.entries(attributes)) {
|
|
||||||
if (!value && value !== 0)
|
|
||||||
continue;
|
|
||||||
innerHTML += ` ${attribute}`;
|
|
||||||
if (value === true)
|
|
||||||
continue;
|
|
||||||
innerHTML += `="${E(value.toString())}"`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tag !== hFragment)
|
|
||||||
innerHTML += '>';
|
|
||||||
const isVoid = tag !== hFragment && voidElements.has(tag);
|
|
||||||
if (isVoid) {
|
|
||||||
if (children.length)
|
|
||||||
throw new TypeError(`${tag} is a void html element and can't have child elements`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (const child of children) {
|
|
||||||
if (child === null || child === undefined || child === '')
|
|
||||||
continue;
|
|
||||||
if (child instanceof Object && "innerHTML" in child && child[isEscaped]) {
|
|
||||||
innerHTML += child.innerHTML;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
innerHTML += E(child.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isVoid && tag !== hFragment)
|
|
||||||
innerHTML += `</${tag}>`;
|
|
||||||
return { innerHTML, [isEscaped]: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
// \u00A0 is non breaking space
|
// \u00A0 is non breaking space
|
||||||
const separator = '\u00A0|\u00A0';
|
const separator = '\u00A0|\u00A0';
|
||||||
const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" },
|
const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" },
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Fetcher from "../classes/Fetcher";
|
|||||||
import Get from "../General/Get";
|
import Get from "../General/Get";
|
||||||
import Header from "../General/Header";
|
import Header from "../General/Header";
|
||||||
import UI from "../General/UI";
|
import UI from "../General/UI";
|
||||||
import { Conf, d, g } from "../globals/globals";
|
import { Conf, d, doc, g } from "../globals/globals";
|
||||||
import ExpandComment from "../Miscellaneous/ExpandComment";
|
import ExpandComment from "../Miscellaneous/ExpandComment";
|
||||||
import $ from "../platform/$";
|
import $ from "../platform/$";
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import ImageHost from "../Images/ImageHost";
|
|||||||
import CrossOrigin from "../platform/CrossOrigin";
|
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";
|
||||||
|
import { isEscaped } from "../globals/jsx";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
@ -20,32 +21,30 @@ import { dict } from "../platform/helpers";
|
|||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||||
*/
|
*/
|
||||||
export default class Fetcher {
|
export default class Fetcher {
|
||||||
static initClass() {
|
static archiveTags = {
|
||||||
|
'\n': {innerHTML: "<br>"},
|
||||||
|
'[b]': {innerHTML: "<b>"},
|
||||||
|
'[/b]': {innerHTML: "</b>"},
|
||||||
|
'[spoiler]': {innerHTML: "<s>"},
|
||||||
|
'[/spoiler]': {innerHTML: "</s>"},
|
||||||
|
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
||||||
|
'[/code]': {innerHTML: "</pre>"},
|
||||||
|
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
||||||
|
'[/moot]': {innerHTML: "</div>"},
|
||||||
|
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
||||||
|
'[/banned]': {innerHTML: "</strong>"},
|
||||||
|
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
||||||
|
'[/fortune]': {innerHTML: "</b></span>"},
|
||||||
|
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
||||||
|
'[/i]': {innerHTML: "</span>"},
|
||||||
|
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
||||||
|
'[/red]': {innerHTML: "</span>"},
|
||||||
|
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
||||||
|
'[/green]': {innerHTML: "</span>"},
|
||||||
|
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
||||||
|
'[/blue]': {innerHTML: "</span>"}
|
||||||
|
};
|
||||||
|
|
||||||
this.prototype.archiveTags = {
|
|
||||||
'\n': {innerHTML: "<br>"},
|
|
||||||
'[b]': {innerHTML: "<b>"},
|
|
||||||
'[/b]': {innerHTML: "</b>"},
|
|
||||||
'[spoiler]': {innerHTML: "<s>"},
|
|
||||||
'[/spoiler]': {innerHTML: "</s>"},
|
|
||||||
'[code]': {innerHTML: "<pre class=\"prettyprint\">"},
|
|
||||||
'[/code]': {innerHTML: "</pre>"},
|
|
||||||
'[moot]': {innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"},
|
|
||||||
'[/moot]': {innerHTML: "</div>"},
|
|
||||||
'[banned]': {innerHTML: "<strong style=\"color: red;\">"},
|
|
||||||
'[/banned]': {innerHTML: "</strong>"},
|
|
||||||
'[fortune]'(text) { return {innerHTML: "<span class=\"fortune\" style=\"color:" + E(text.match(/#\w+|$/)[0]) + "\"><b>"}; },
|
|
||||||
'[/fortune]': {innerHTML: "</b></span>"},
|
|
||||||
'[i]': {innerHTML: "<span class=\"mu-i\">"},
|
|
||||||
'[/i]': {innerHTML: "</span>"},
|
|
||||||
'[red]': {innerHTML: "<span class=\"mu-r\">"},
|
|
||||||
'[/red]': {innerHTML: "</span>"},
|
|
||||||
'[green]': {innerHTML: "<span class=\"mu-g\">"},
|
|
||||||
'[/green]': {innerHTML: "</span>"},
|
|
||||||
'[blue]': {innerHTML: "<span class=\"mu-b\">"},
|
|
||||||
'[/blue]': {innerHTML: "</span>"}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
constructor(boardID, threadID, postID, root, quoter) {
|
constructor(boardID, threadID, postID, root, quoter) {
|
||||||
let post, thread;
|
let post, thread;
|
||||||
this.boardID = boardID;
|
this.boardID = boardID;
|
||||||
@ -226,25 +225,21 @@ export default class Fetcher {
|
|||||||
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
// https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428
|
||||||
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
// https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168
|
||||||
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);
|
||||||
comment = (() => {
|
comment = comment.map((text, i) => {
|
||||||
const result = [];
|
if ((i % 2) === 1) {
|
||||||
for (let i = 0; i < comment.length; i++) {
|
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
||||||
var text = comment[i];
|
return (typeof tag === 'function') ? tag(text) : tag;
|
||||||
if ((i % 2) === 1) {
|
} else {
|
||||||
var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')];
|
var greentext = text[0] === '>';
|
||||||
if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); }
|
text = text
|
||||||
} else {
|
.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2')
|
||||||
var greentext = text[0] === '>';
|
.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g)
|
||||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
.map((text2, j) => ((j % 2) ? `<span class="deadlink">${E(text2)}</span>`: E(text2)))
|
||||||
text = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map((text2, j) =>
|
.join('');
|
||||||
{innerHTML: ((j % 2) ? "<span class=\"deadlink\">" + E(text2) + "</span>" : E(text2));});
|
return {innerHTML: (greentext ? `<span class="quote">${text}</span>` : text)};
|
||||||
text = {innerHTML: ((greentext) ? "<span class=\"quote\">" + E.cat(text) + "</span>" : E.cat(text))};
|
|
||||||
result.push(text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
});
|
||||||
})();
|
comment = { innerHTML: E.cat(comment), [isEscaped]: true };
|
||||||
comment = {innerHTML: E.cat(comment)};
|
|
||||||
|
|
||||||
this.threadID = +data.thread_num;
|
this.threadID = +data.thread_num;
|
||||||
const o = {
|
const o = {
|
||||||
@ -317,4 +312,3 @@ export default class Fetcher {
|
|||||||
return this.insert(post);
|
return this.insert(post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fetcher.initClass();
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"version": "XT 2.1.1",
|
"version": "XT 2.1.2",
|
||||||
"date": "2023-07-16T08:49:02.722Z"
|
"date": "2023-07-22T15:46:24.103Z"
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user