Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import deepmerge from "npm:deepmerge@4";
import { fromHtml } from "npm:hast-util-from-html@2";
import { defaultSchema, sanitize, type Schema } from "npm:hast-util-sanitize@5";
import { toDom } from "npm:hast-util-to-dom@4";
import type { Nodes } from "npm:hast@1";
import parseStyle from "npm:style-to-object@1";
import { visit } from "npm:unist-util-visit@5";
type AgeRuleset = {
schema: Schema;
additionalVisitor: (hast: Nodes) => void;
};
const SECOND_AGE: AgeRuleset = {
schema: deepmerge(defaultSchema, {
attributes: {
"*": ["style"],
},
tagNames: ["video", "audio", "aside"], // consistency with current rules,
}),
additionalVisitor(hast) {
visit(hast, "element", (node, index, parent) => {
if (parent === null || index === null) return;
if (
node.properties?.style
&& typeof node.properties.style === "string"
) {
try {
let changed = false;
const parsed = parseStyle(node.properties.style);
if (
parsed
&& parsed["position"]
&& [
// every valid value of `position` _except_ `fixed`
// (https://developer.mozilla.org/en-US/docs/Web/CSS/position),
// which we disallow
"static",
"relative",
"absolute",
"sticky",
"inherit",
"initial",
"revert",
"revert-layer",
"unset",
].indexOf(parsed["position"].toLowerCase()) === -1
) {
parsed.position = "static";
changed = true;
}
if (parsed && changed) {
node.properties.style = Object.entries(parsed)
.map(([k, v]) => `${k}:${v}`)
.join(";");
}
} catch (e) {
// couldn't parse, don't worry about it
return;
}
}
});
},
};
const THIRD_AGE: AgeRuleset = {
schema: deepmerge(defaultSchema, {
attributes: {
"*": ["style"],
},
tagNames: ["video", "audio", "aside"], // consistency with current rules,
}),
additionalVisitor(hast) {
// run the previous age's visitor first
SECOND_AGE.additionalVisitor(hast);
visit(hast, "element", (node, index, parent) => {
if (parent === null || index === null) return;
if (
node.properties?.style
&& typeof node.properties.style === "string"
) {
try {
let changed = false;
const parsed = parseStyle(node.properties.style);
if (parsed) {
for (const key in parsed) {
// drop all CSS variables
if (key.startsWith("--")) {
delete parsed[key];
changed = true;
}
}
}
if (parsed && changed) {
September 12, 2024