mirror of
https://github.com/eigilnikolajsen/commit-mono.git
synced 2024-10-03 21:27:53 +03:00
run prettier
This commit is contained in:
parent
78de709b28
commit
a915cbdcb4
@ -1,5 +1,5 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 3,
|
||||
"semi": false
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4,
|
||||
"semi": false
|
||||
}
|
||||
|
112
404.html
112
404.html
@ -1,62 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Website for Commit Mono - a neutral programming font." />
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Website for Commit Mono - a neutral programming font." />
|
||||
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="src/favicon/icon.svg" type="image/svg+xml" id="dynamic-favicon" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<!-- favicon -->
|
||||
<link rel="icon" href="src/favicon/icon.svg" type="image/svg+xml" id="dynamic-favicon" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
|
||||
<!-- title -->
|
||||
<title>Commit Mono. Neutral programming typeface.</title>
|
||||
<!-- title -->
|
||||
<title>Commit Mono. Neutral programming typeface.</title>
|
||||
|
||||
<!-- CSS -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/src/fonts/CommitMonoV118-VF.woff2");
|
||||
font-style: normal;
|
||||
font-weight: 450;
|
||||
font-display: swap;
|
||||
}
|
||||
body {
|
||||
background-color: #aaa;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
}
|
||||
p,
|
||||
a {
|
||||
font-family: "CommitMono";
|
||||
font-size: 0.75rem;
|
||||
color: #111;
|
||||
line-height: 1rem;
|
||||
margin: 0;
|
||||
width: fit-content;
|
||||
text-decoration: none;
|
||||
}
|
||||
a {
|
||||
background-color: #111;
|
||||
color: #aaa;
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>404</p>
|
||||
<p>page not found</p>
|
||||
<br />
|
||||
<a href="/">Press ENTER to go to home page.</a>
|
||||
<script>
|
||||
const a = document.querySelector("a")
|
||||
a.focus()
|
||||
a.addEventListener("blur", () => a.focus())
|
||||
</script>
|
||||
</body>
|
||||
<!-- CSS -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/src/fonts/CommitMonoV118-VF.woff2");
|
||||
font-style: normal;
|
||||
font-weight: 450;
|
||||
font-display: swap;
|
||||
}
|
||||
body {
|
||||
background-color: #aaa;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
}
|
||||
p,
|
||||
a {
|
||||
font-family: "CommitMono";
|
||||
font-size: 0.75rem;
|
||||
color: #111;
|
||||
line-height: 1rem;
|
||||
margin: 0;
|
||||
width: fit-content;
|
||||
text-decoration: none;
|
||||
}
|
||||
a {
|
||||
background-color: #111;
|
||||
color: #aaa;
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>404</p>
|
||||
<p>page not found</p>
|
||||
<br />
|
||||
<a href="/">Press ENTER to go to home page.</a>
|
||||
<script>
|
||||
const a = document.querySelector("a")
|
||||
a.focus()
|
||||
a.addEventListener("blur", () => a.focus())
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
60
calt.js
60
calt.js
@ -2,48 +2,48 @@ const fs = require("fs")
|
||||
const readline = require("readline")
|
||||
|
||||
function pbcopy(data) {
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
}
|
||||
|
||||
async function featuresToCalt() {
|
||||
const features = ["ss01_arrows", "ss02_less_equal", "ss03_case", "ss04_ellipsis", "ss05_smartkerning"]
|
||||
const features = ["ss01_arrows", "ss02_less_equal", "ss03_case", "ss04_ellipsis", "ss05_smartkerning"]
|
||||
|
||||
let calt = []
|
||||
let calt = []
|
||||
|
||||
for await (const feature of features) {
|
||||
const fileStream = fs.createReadStream(`features/${feature}.fea`)
|
||||
for await (const feature of features) {
|
||||
const fileStream = fs.createReadStream(`features/${feature}.fea`)
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
})
|
||||
// Note: we use the crlfDelay option to recognize all instances of CR LF
|
||||
// ('\r\n') in input.txt as a single line break.
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
})
|
||||
// Note: we use the crlfDelay option to recognize all instances of CR LF
|
||||
// ('\r\n') in input.txt as a single line break.
|
||||
|
||||
const lines = []
|
||||
const lines = []
|
||||
|
||||
lines.push(`### feature ${feature} ###`)
|
||||
lines.push(`### feature ${feature} ###`)
|
||||
|
||||
for await (const line of rl) {
|
||||
// Each line in input.txt will be successively available here as `line`.
|
||||
// console.log(`Line from file: ${line}`)
|
||||
lines.push(line)
|
||||
}
|
||||
for await (const line of rl) {
|
||||
// Each line in input.txt will be successively available here as `line`.
|
||||
// console.log(`Line from file: ${line}`)
|
||||
lines.push(line)
|
||||
}
|
||||
|
||||
calt.push(lines)
|
||||
}
|
||||
calt.push(lines)
|
||||
}
|
||||
|
||||
calt = calt.flat().filter((ln) => !ln.includes("feature") && !ln.includes("} ss"))
|
||||
calt = calt.map((ln) => {
|
||||
if (ln.includes("lookup")) return ln.split("lookup ").join("lookup _")
|
||||
if (ln.includes("} ")) return ln.split("} ").join("} _")
|
||||
return ln
|
||||
})
|
||||
calt = calt.flat().filter((ln) => !ln.includes("feature") && !ln.includes("} ss"))
|
||||
calt = calt.map((ln) => {
|
||||
if (ln.includes("lookup")) return ln.split("lookup ").join("lookup _")
|
||||
if (ln.includes("} ")) return ln.split("} ").join("} _")
|
||||
return ln
|
||||
})
|
||||
|
||||
// calt.forEach((ln) => console.log(ln))
|
||||
pbcopy(`
|
||||
// calt.forEach((ln) => console.log(ln))
|
||||
pbcopy(`
|
||||
feature calt {
|
||||
# Contextual Alternates
|
||||
# Contains all 'cxxx' features
|
||||
|
54
classes.html
54
classes.html
@ -1,30 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
</head>
|
||||
<body>
|
||||
<br />
|
||||
<label for="classes">Classes</label>
|
||||
<br />
|
||||
<br />
|
||||
<textarea id="classes" name="classes" rows="20" cols="60"></textarea>
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p style="user-select: all" id="result"></p>
|
||||
<script>
|
||||
const classes = document.querySelector("#classes")
|
||||
const result = document.querySelector("#result")
|
||||
const submit = document.querySelector("#submit")
|
||||
submit.addEventListener("click", () => {
|
||||
result.textContent = [...new Set(classes.value.split(" "))].join(" ")
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
</head>
|
||||
<body>
|
||||
<br />
|
||||
<label for="classes">Classes</label>
|
||||
<br />
|
||||
<br />
|
||||
<textarea id="classes" name="classes" rows="20" cols="60"></textarea>
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p style="user-select: all" id="result"></p>
|
||||
<script>
|
||||
const classes = document.querySelector("#classes")
|
||||
const result = document.querySelector("#result")
|
||||
const submit = document.querySelector("#submit")
|
||||
submit.addEventListener("click", () => {
|
||||
result.textContent = [...new Set(classes.value.split(" "))].join(" ")
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
22
f.js
22
f.js
@ -6,10 +6,10 @@
|
||||
// @c3_3 = [exclam.c3_3 comma.c3_3 period.c3_3 slash.c3_3 colon.c3_3 semicolon.c3_3 question.c3_3 backslash.c3_3 bar.c3_3];
|
||||
|
||||
const input =
|
||||
"exclam exclam.square comma period period.square slash slash.case colon colon.square colon.case colon.case.square semicolon semicolon.square semicolon.case semicolon.case.square question question.square backslash backslash.case bar bar.case less less.case greater greater.case asterisk asterisk.case plus plus.case hyphen hyphen.case equal equal.case asciitilde asciitilde.case"
|
||||
"exclam exclam.square comma period period.square slash slash.case colon colon.square colon.case colon.case.square semicolon semicolon.square semicolon.case semicolon.case.square question question.square backslash backslash.case bar bar.case less less.case greater greater.case asterisk asterisk.case plus plus.case hyphen hyphen.case equal equal.case asciitilde asciitilde.case"
|
||||
function c002(input) {
|
||||
const s = input.split(" ")
|
||||
return `
|
||||
const s = input.split(" ")
|
||||
return `
|
||||
@dflt = [${input}];
|
||||
@c2_1 = [${s.join(".c2_1 ")}.c2_1];
|
||||
@c2_2 = [${s.join(".c2_2 ")}.c2_2];
|
||||
@ -19,20 +19,20 @@ function c002(input) {
|
||||
}
|
||||
|
||||
function classExcess(c) {
|
||||
return [...new Set(c.split(" "))].join(" ")
|
||||
return [...new Set(c.split(" "))].join(" ")
|
||||
}
|
||||
|
||||
function buildGlyphs(g) {
|
||||
return g
|
||||
.split(", ")
|
||||
.map((gl) => gl.split("=")[0])
|
||||
.join(", ")
|
||||
return g
|
||||
.split(", ")
|
||||
.map((gl) => gl.split("=")[0])
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
function pbcopy(data) {
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
}
|
||||
|
||||
pbcopy(c002(input))
|
||||
|
1457
index.html
1457
index.html
File diff suppressed because it is too large
Load Diff
@ -1,53 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
<style>
|
||||
#resultButton {
|
||||
user-select: all;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<label for="start">Start value</label>
|
||||
<input type="text" name="start" id="start" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="end">End value</label>
|
||||
<input type="text" name="end" id="end" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="precision">Precision</label>
|
||||
<input type="text" name="precision" id="precision" />
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p id="resultButton"></p>
|
||||
<script>
|
||||
const submit = document.querySelector("#submit")
|
||||
const start = document.querySelector("#start")
|
||||
const end = document.querySelector("#end")
|
||||
const precision = document.querySelector("#precision")
|
||||
const resultButton = document.querySelector("#resultButton")
|
||||
submit.addEventListener("click", () => {
|
||||
const result = generateAxisValue([+start.value, +end.value], +precision.value)
|
||||
resultButton.textContent = result
|
||||
navigator.clipboard.writeText(result)
|
||||
})
|
||||
const generateAxisValue = ([start, end], precision) => {
|
||||
let value = start
|
||||
let result = ""
|
||||
while (value <= end) {
|
||||
result += `"${value}"=${value}, `
|
||||
value += precision
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
<style>
|
||||
#resultButton {
|
||||
user-select: all;
|
||||
}
|
||||
return result.slice(0, -2)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<label for="start">Start value</label>
|
||||
<input type="text" name="start" id="start" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="end">End value</label>
|
||||
<input type="text" name="end" id="end" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="precision">Precision</label>
|
||||
<input type="text" name="precision" id="precision" />
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p id="resultButton"></p>
|
||||
<script>
|
||||
const submit = document.querySelector("#submit")
|
||||
const start = document.querySelector("#start")
|
||||
const end = document.querySelector("#end")
|
||||
const precision = document.querySelector("#precision")
|
||||
const resultButton = document.querySelector("#resultButton")
|
||||
submit.addEventListener("click", () => {
|
||||
const result = generateAxisValue([+start.value, +end.value], +precision.value)
|
||||
resultButton.textContent = result
|
||||
navigator.clipboard.writeText(result)
|
||||
})
|
||||
const generateAxisValue = ([start, end], precision) => {
|
||||
let value = start
|
||||
let result = ""
|
||||
while (value <= end) {
|
||||
result += `"${value}"=${value}, `
|
||||
value += precision
|
||||
}
|
||||
return result.slice(0, -2)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,27 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/fonts/CommitMono.woff2");
|
||||
font-weight: 450;
|
||||
}
|
||||
:root {
|
||||
--grey: #aaa;
|
||||
}
|
||||
button#grey::before {
|
||||
content: "01";
|
||||
font-style: italic;
|
||||
font-size: 2rem;
|
||||
color: var(--grey);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="grey">Commit Mono</button>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/fonts/CommitMono.woff2");
|
||||
font-weight: 450;
|
||||
}
|
||||
:root {
|
||||
--grey: #aaa;
|
||||
}
|
||||
button#grey::before {
|
||||
content: "01";
|
||||
font-style: italic;
|
||||
font-size: 2rem;
|
||||
color: var(--grey);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="grey">Commit Mono</button>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,56 +6,56 @@
|
||||
*/
|
||||
|
||||
function lcs(arr1, arr2) {
|
||||
let matrix = [...Array(arr1.length + 1)].fill(0).map(() => Array(arr2.length + 1).fill(0))
|
||||
let matrix = [...Array(arr1.length + 1)].fill(0).map(() => Array(arr2.length + 1).fill(0))
|
||||
|
||||
for (let rowIndex = 1; rowIndex <= arr1.length; rowIndex++) {
|
||||
for (let columnIndex = 1; columnIndex <= arr2.length; columnIndex++) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
matrix[rowIndex][columnIndex] = 1 + matrix[rowIndex - 1][columnIndex - 1]
|
||||
} else {
|
||||
matrix[rowIndex][columnIndex] = Math.max(
|
||||
matrix[rowIndex - 1][columnIndex],
|
||||
matrix[rowIndex][columnIndex - 1]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
//If there is no match, printing empty string
|
||||
if (matrix[arr1.length][arr2.index] === 0) {
|
||||
console.log("")
|
||||
return
|
||||
}
|
||||
for (let rowIndex = 1; rowIndex <= arr1.length; rowIndex++) {
|
||||
for (let columnIndex = 1; columnIndex <= arr2.length; columnIndex++) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
matrix[rowIndex][columnIndex] = 1 + matrix[rowIndex - 1][columnIndex - 1]
|
||||
} else {
|
||||
matrix[rowIndex][columnIndex] = Math.max(
|
||||
matrix[rowIndex - 1][columnIndex],
|
||||
matrix[rowIndex][columnIndex - 1]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
//If there is no match, printing empty string
|
||||
if (matrix[arr1.length][arr2.index] === 0) {
|
||||
console.log("")
|
||||
return
|
||||
}
|
||||
|
||||
let result = []
|
||||
let rowIndex = arr1.length
|
||||
let columnIndex = arr2.length
|
||||
let result = []
|
||||
let rowIndex = arr1.length
|
||||
let columnIndex = arr2.length
|
||||
|
||||
while (rowIndex > 0 && columnIndex > 0) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
//Prepending everytime a new character is matched in both strings
|
||||
result.unshift(arr1[rowIndex - 1])
|
||||
rowIndex--
|
||||
columnIndex--
|
||||
} else if (matrix[rowIndex - 1][columnIndex] === matrix[rowIndex][columnIndex]) {
|
||||
rowIndex--
|
||||
} else {
|
||||
columnIndex--
|
||||
}
|
||||
}
|
||||
//Converting the LCS array into a comma separated string
|
||||
console.log(result.join(", "))
|
||||
while (rowIndex > 0 && columnIndex > 0) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
//Prepending everytime a new character is matched in both strings
|
||||
result.unshift(arr1[rowIndex - 1])
|
||||
rowIndex--
|
||||
columnIndex--
|
||||
} else if (matrix[rowIndex - 1][columnIndex] === matrix[rowIndex][columnIndex]) {
|
||||
rowIndex--
|
||||
} else {
|
||||
columnIndex--
|
||||
}
|
||||
}
|
||||
//Converting the LCS array into a comma separated string
|
||||
console.log(result.join(", "))
|
||||
}
|
||||
|
||||
//Usage Text
|
||||
const usage = 'Usage: please provide two lists in the format "1, 2, 3, 4, 5"'
|
||||
if (process.argv.length < 4 || process.argv[2] == "" || process.argv[3] == "") {
|
||||
console.log(usage)
|
||||
return
|
||||
console.log(usage)
|
||||
return
|
||||
} else {
|
||||
const input1 = process.argv[2]
|
||||
const input2 = process.argv[3]
|
||||
//Parsing into integers after trimming extra blank spaces
|
||||
const array1 = input1.split(",").map((x) => parseInt(x.trim(), 10))
|
||||
const array2 = input2.split(",").map((y) => parseInt(y.trim(), 10))
|
||||
lcs(array1, array2)
|
||||
const input1 = process.argv[2]
|
||||
const input2 = process.argv[3]
|
||||
//Parsing into integers after trimming extra blank spaces
|
||||
const array1 = input1.split(",").map((x) => parseInt(x.trim(), 10))
|
||||
const array2 = input2.split(",").map((y) => parseInt(y.trim(), 10))
|
||||
lcs(array1, array2)
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
function fibonacci(num: number) {
|
||||
let n = Number(num)
|
||||
let elementOne: number = 0
|
||||
let elementTwo: number = 1
|
||||
let result: number = 0
|
||||
let n = Number(num)
|
||||
let elementOne: number = 0
|
||||
let elementTwo: number = 1
|
||||
let result: number = 0
|
||||
|
||||
for (let i: number = 1; i <= n; i++) {
|
||||
result = elementOne + elementTwo
|
||||
elementOne = elementTwo
|
||||
elementTwo = result
|
||||
console.log(`${i}: ${elementOne}`)
|
||||
}
|
||||
for (let i: number = 1; i <= n; i++) {
|
||||
result = elementOne + elementTwo
|
||||
elementOne = elementTwo
|
||||
elementTwo = result
|
||||
console.log(`${i}: ${elementOne}`)
|
||||
}
|
||||
}
|
||||
|
||||
let num_str = process.argv.length >= 3 ? process.argv[2] : ""
|
||||
let num: number = parseInt(num_str)
|
||||
if (isNaN(num)) {
|
||||
console.log("Usage: please input the count of fibonacci numbers to output")
|
||||
process.exit(0)
|
||||
console.log("Usage: please input the count of fibonacci numbers to output")
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
fibonacci(num)
|
||||
|
5760
letter_group_test.js
5760
letter_group_test.js
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"icons": [
|
||||
{ "src": "/src/favicon/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "/src/favicon/icon-512.png", "type": "image/png", "sizes": "512x512" }
|
||||
]
|
||||
"icons": [
|
||||
{ "src": "/src/favicon/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "/src/favicon/icon-512.png", "type": "image/png", "sizes": "512x512" }
|
||||
]
|
||||
}
|
||||
|
1772
package-lock.json
generated
1772
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "commit-webtests",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.1.1"
|
||||
}
|
||||
"name": "commit-webtests",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.1.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,69 @@
|
||||
@font-face {
|
||||
font-family: "CommitMonoLoading";
|
||||
src: url("data:font/woff2;charset=url-8;base64,d09GMk9UVE8AAAVoAAoAAAAACRAAAAUgAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYcqGhYGYACCcgE2AiQDIgQGBYQhByAbVAgRZJPTIvuRkLnpo1niWFGcZNnEK1FCUU4/x8PT2u/PnZ3dh6g3CJGQRBORpJVGg67f6q9Ns3ed4+/dNQeGD6Q1Nv+/r3HXBE48osgCyvt7NvUTYnINZZJwUNelEzGpqkxUH92fDB0zXaUP82xFMJQsXXOHVdpANttEIhM32xM/y6P+MHZhAh4hJxTKBbrhm89nfEyZeMKSimREp600nifplvNJJ34a/VkBz5F8L+EFZeCFSvKWUsig+NR/R0ZgyZDGIvDSwGSjyt9iLXIEIdUwnqN2Eiag0Go3YpZ2uyOTcHUKJe4KKRInfhZA3BH3KPTa1jUwMjW34E8oZC3tOm14RybSiV8CM8EswZ2BYK7G3WoT1eM4OBCww4CQ/0grvTR5bXZ2cnJ2ztqkpUvXrlvCqo+2rtrF72jXPnwM5x5SebwLrKI9x4/tO2lFSnl5RkqXP9vhF3Ul/HqgT++reCFN7bm85urm6zukd8WH8k80PNbBHMnbfi1Ygsk+Ewyn2MfivKuFiQ361vzVM1du3zn/BDf0iAjL9o2Z7Kaj8lzaxn2+WZ1am9An5uYS0pab2kJMyaNISGuk3cc/AwUa3/jsxbNaA1Zj1eQ+7hzYJknff3H9xQ2X10rviU83nGku0fFVXjj3lKRp3YzUkXqsdcIK7MlRebjPGywHbWdlRmsSq8ar2qD/nYftsKFtQpe269bK+0M6YduD7Q+pd0egDK7T4xblNzXn5TU15i0a6//gheO5RryXpn4MaUzfumjq+JV2jhNSy3PSk4u5wcn0rF1rF8/Uub+bADqw+Nr59fHICkywWC+mvh7ZsjskJtw/ONybOxYRfSpWD8SDuz8zjqTsjuUeteER4r7GX9u189IOPSYHDDabGjkvYx1XZeXVe3auX6lbE7Q5dh+rPn+TZ25+ASst7DVeZPWQegNkD97hJjbwq/CJoeD2h8EGMfUF5N3G9PKkdZlZiUm69/rEZcvXrV+2kBPb+W83Cdj1iIR6GEvzleUvdf2zV4KN6saCJDP1ekAs2yY5sGnDiY364WsyHnLqsB33IgA9hIPie6f1gCbJx/L2Ow0ZC4aw+PcjnpAAOfam9ahZa6dsYk8/GvQnTaw+eot3ukU0PYKqxySUHaWB+QwyMKhka5BhRmuDLakBSj/BFsBwt4SuEx+DCnLUP375st6AVedNNLhy6qPe3VO8n5zHhd5ivMo7ylty1Js/4w3T4gopc6PsthzOKW7fViozCyOr7ihV/Adj6KaLIAu6KMJTL+80vZKGuIJqm/Gc4ARBye4ep2gcIxAk2uHOt6z2oeI+AnMMHrwKfRBX1Yn/XgiqV+jDEvAAaUpQVMbhQqVPiQYFmGITYUPjK626Tk2Kq04ULit/PgOKGsEbWgtt27SjQ6fsHBgRZstv321OjERlQLEZl0IalH5zlJ/leblVov5H/A/7H/o/GFkrVe6Hj7cN3r2/07C4d8BPVfUG4UvYu0B7XoTTKBQvTgILkkKgWl1ZeII95O98bdJy+6Y6fmDlb51Xaocv2hU3QDqOGmDnfJm6PNe1hP6x6pJWSEiBbFwE1Lptypq0/jU2kWUoLNhDkPS4AZUzL5Bt+YHaRHDSBhKjb+N2c7H+U0jpsxD/Imn8NZKvzdrGzuo09DDFCJvgDVwXEcOKxvB0IrnZ0UzDHZbzF5JiEhhaTrOlQlHaWpaS0GVp19ozUcDlJtuojBhThsdj6sLDGy/MoCNODT2409BVrVsWGh9kAA==");
|
||||
font-style: normal;
|
||||
font-weight: 450;
|
||||
font-display: swap;
|
||||
font-family: "CommitMonoLoading";
|
||||
src: url("data:font/woff2;charset=url-8;base64,d09GMk9UVE8AAAVoAAoAAAAACRAAAAUgAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYcqGhYGYACCcgE2AiQDIgQGBYQhByAbVAgRZJPTIvuRkLnpo1niWFGcZNnEK1FCUU4/x8PT2u/PnZ3dh6g3CJGQRBORpJVGg67f6q9Ns3ed4+/dNQeGD6Q1Nv+/r3HXBE48osgCyvt7NvUTYnINZZJwUNelEzGpqkxUH92fDB0zXaUP82xFMJQsXXOHVdpANttEIhM32xM/y6P+MHZhAh4hJxTKBbrhm89nfEyZeMKSimREp600nifplvNJJ34a/VkBz5F8L+EFZeCFSvKWUsig+NR/R0ZgyZDGIvDSwGSjyt9iLXIEIdUwnqN2Eiag0Go3YpZ2uyOTcHUKJe4KKRInfhZA3BH3KPTa1jUwMjW34E8oZC3tOm14RybSiV8CM8EswZ2BYK7G3WoT1eM4OBCww4CQ/0grvTR5bXZ2cnJ2ztqkpUvXrlvCqo+2rtrF72jXPnwM5x5SebwLrKI9x4/tO2lFSnl5RkqXP9vhF3Ul/HqgT++reCFN7bm85urm6zukd8WH8k80PNbBHMnbfi1Ygsk+Ewyn2MfivKuFiQ361vzVM1du3zn/BDf0iAjL9o2Z7Kaj8lzaxn2+WZ1am9An5uYS0pab2kJMyaNISGuk3cc/AwUa3/jsxbNaA1Zj1eQ+7hzYJknff3H9xQ2X10rviU83nGku0fFVXjj3lKRp3YzUkXqsdcIK7MlRebjPGywHbWdlRmsSq8ar2qD/nYftsKFtQpe269bK+0M6YduD7Q+pd0egDK7T4xblNzXn5TU15i0a6//gheO5RryXpn4MaUzfumjq+JV2jhNSy3PSk4u5wcn0rF1rF8/Uub+bADqw+Nr59fHICkywWC+mvh7ZsjskJtw/ONybOxYRfSpWD8SDuz8zjqTsjuUeteER4r7GX9u189IOPSYHDDabGjkvYx1XZeXVe3auX6lbE7Q5dh+rPn+TZ25+ASst7DVeZPWQegNkD97hJjbwq/CJoeD2h8EGMfUF5N3G9PKkdZlZiUm69/rEZcvXrV+2kBPb+W83Cdj1iIR6GEvzleUvdf2zV4KN6saCJDP1ekAs2yY5sGnDiY364WsyHnLqsB33IgA9hIPie6f1gCbJx/L2Ow0ZC4aw+PcjnpAAOfam9ahZa6dsYk8/GvQnTaw+eot3ukU0PYKqxySUHaWB+QwyMKhka5BhRmuDLakBSj/BFsBwt4SuEx+DCnLUP375st6AVedNNLhy6qPe3VO8n5zHhd5ivMo7ylty1Js/4w3T4gopc6PsthzOKW7fViozCyOr7ihV/Adj6KaLIAu6KMJTL+80vZKGuIJqm/Gc4ARBye4ep2gcIxAk2uHOt6z2oeI+AnMMHrwKfRBX1Yn/XgiqV+jDEvAAaUpQVMbhQqVPiQYFmGITYUPjK626Tk2Kq04ULit/PgOKGsEbWgtt27SjQ6fsHBgRZstv321OjERlQLEZl0IalH5zlJ/leblVov5H/A/7H/o/GFkrVe6Hj7cN3r2/07C4d8BPVfUG4UvYu0B7XoTTKBQvTgILkkKgWl1ZeII95O98bdJy+6Y6fmDlb51Xaocv2hU3QDqOGmDnfJm6PNe1hP6x6pJWSEiBbFwE1Lptypq0/jU2kWUoLNhDkPS4AZUzL5Bt+YHaRHDSBhKjb+N2c7H+U0jpsxD/Imn8NZKvzdrGzuo09DDFCJvgDVwXEcOKxvB0IrnZ0UzDHZbzF5JiEhhaTrOlQlHaWpaS0GVp19ozUcDlJtuojBhThsdj6sLDGy/MoCNODT2409BVrVsWGh9kAA==");
|
||||
font-style: normal;
|
||||
font-weight: 450;
|
||||
font-display: swap;
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
:root {
|
||||
--text: #111;
|
||||
--middle: #555;
|
||||
--bg: #aaa;
|
||||
--max-width: 54ch;
|
||||
font-size: 16px;
|
||||
--text: #111;
|
||||
--middle: #555;
|
||||
--bg: #aaa;
|
||||
--max-width: 54ch;
|
||||
font-size: 16px;
|
||||
}
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: "CommitMono", monospace;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-feature-settings: "ss01", "ss03", "ss04", "ss05";
|
||||
overflow: hidden;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-family: "CommitMono", monospace;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-feature-settings: "ss01", "ss03", "ss04", "ss05";
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
background-color: var(--bg);
|
||||
z-index: 200;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
background-color: var(--bg);
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
#loading p {
|
||||
width: 10ch;
|
||||
font-family: "CommitMonoLoading";
|
||||
width: 10ch;
|
||||
font-family: "CommitMonoLoading";
|
||||
}
|
||||
|
||||
#loading p::after {
|
||||
content: "...";
|
||||
animation: 500ms forwards infinite loading_animation;
|
||||
content: "...";
|
||||
animation: 500ms forwards infinite loading_animation;
|
||||
}
|
||||
|
||||
@keyframes loading_animation {
|
||||
0% {
|
||||
content: "";
|
||||
}
|
||||
25% {
|
||||
content: ".";
|
||||
}
|
||||
50% {
|
||||
content: "..";
|
||||
}
|
||||
75% {
|
||||
content: "...";
|
||||
}
|
||||
100% {
|
||||
content: "";
|
||||
}
|
||||
0% {
|
||||
content: "";
|
||||
}
|
||||
25% {
|
||||
content: ".";
|
||||
}
|
||||
50% {
|
||||
content: "..";
|
||||
}
|
||||
75% {
|
||||
content: "...";
|
||||
}
|
||||
100% {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
@media (pointer: coarse) and (max-width: 1000px) {
|
||||
body {
|
||||
overflow: visible;
|
||||
}
|
||||
#main_scale,
|
||||
main {
|
||||
position: relative;
|
||||
}
|
||||
header #keyboard_section,
|
||||
#safari {
|
||||
visibility: hidden;
|
||||
}
|
||||
#footer_hint {
|
||||
display: none;
|
||||
}
|
||||
#footer_hint_mobile {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
overflow: visible;
|
||||
}
|
||||
#main_scale,
|
||||
main {
|
||||
position: relative;
|
||||
}
|
||||
header #keyboard_section,
|
||||
#safari {
|
||||
visibility: hidden;
|
||||
}
|
||||
#footer_hint {
|
||||
display: none;
|
||||
}
|
||||
#footer_hint_mobile {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
@ -1,159 +1,159 @@
|
||||
button {
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: 0.75rem;
|
||||
font-variation-settings: inherit;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-feature-settings: inherit;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: 0.75rem;
|
||||
font-variation-settings: inherit;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-feature-settings: inherit;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background: var(--bg75);
|
||||
background: var(--bg75);
|
||||
}
|
||||
|
||||
#app_root.no_focus {
|
||||
opacity: 0.5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
:focus,
|
||||
input:focus + label {
|
||||
animation: flicker 60ms 2;
|
||||
animation: flicker 60ms 2;
|
||||
}
|
||||
|
||||
[contenteditable="true"]:focus {
|
||||
animation: flicker 200ms 2;
|
||||
animation: flicker 200ms 2;
|
||||
}
|
||||
|
||||
@keyframes flicker {
|
||||
0%,
|
||||
49% {
|
||||
opacity: 0;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
0%,
|
||||
49% {
|
||||
opacity: 0;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flicker_reverse {
|
||||
0%,
|
||||
49% {
|
||||
opacity: 1;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
0%,
|
||||
49% {
|
||||
opacity: 1;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.top_container p {
|
||||
white-space: pre-wrap;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.line-through {
|
||||
text-decoration: line-through;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
p:focus a,
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#click_focus,
|
||||
#change_setting {
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#safari {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#safari.safari_visible {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#safari:focus p:first-of-type {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#safari {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
width: max-content;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#safari:focus p,
|
||||
#safari:focus ul {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari:focus a,
|
||||
#safari a:focus {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari:has(*:focus) * {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari #safari_not_working:focus {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
opacity: 1;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari #safari_not_working {
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari a:focus + #safari_not_working {
|
||||
visibility: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.span_key.pressed_key {
|
||||
position: relative;
|
||||
background: var(--bg25);
|
||||
position: relative;
|
||||
background: var(--bg25);
|
||||
}
|
||||
|
||||
ul:focus .span_key.pressed_key {
|
||||
background: var(--bg25-i);
|
||||
background: var(--bg25-i);
|
||||
}
|
||||
|
||||
.span_key.pressed_key::after {
|
||||
content: " ✓";
|
||||
position: absolute;
|
||||
right: -1ch;
|
||||
top: -0.5rem;
|
||||
content: " ✓";
|
||||
position: absolute;
|
||||
right: -1ch;
|
||||
top: -0.5rem;
|
||||
}
|
||||
|
||||
#keyboard_container.use_keyboard_animation {
|
||||
animation: flicker 140ms 8;
|
||||
animation: flicker 140ms 8;
|
||||
}
|
||||
|
@ -1,74 +1,74 @@
|
||||
#keyboard_container {
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
width: max-content;
|
||||
gap: 4ch;
|
||||
align-items: end;
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
width: max-content;
|
||||
gap: 4ch;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.key_group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.keys {
|
||||
display: flex;
|
||||
gap: 0.375ch;
|
||||
margin-bottom: 0.125rem;
|
||||
display: flex;
|
||||
gap: 0.375ch;
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.key {
|
||||
line-height: 0.85rem;
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
user-select: none;
|
||||
line-height: 0.85rem;
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.key:hover {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.key[data-noclick="true"]:hover {
|
||||
cursor: not-allowed;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.key.active_key,
|
||||
.key:active {
|
||||
background: var(--text);
|
||||
color: var(--bg);
|
||||
line-height: 0.75rem;
|
||||
margin-top: 0.1rem;
|
||||
background: var(--text);
|
||||
color: var(--bg);
|
||||
line-height: 0.75rem;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
#safari p,
|
||||
#safari ul {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
opacity: 0;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari a {
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari p:first-of-type {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#tutorial li {
|
||||
margin-top: 0.3rem;
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.span_key {
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
}
|
||||
|
||||
*:focus .span_key {
|
||||
border: 0.0625rem solid var(--bg);
|
||||
border-bottom: 0.125rem solid var(--bg);
|
||||
border: 0.0625rem solid var(--bg);
|
||||
border-bottom: 0.125rem solid var(--bg);
|
||||
}
|
||||
|
@ -1,79 +1,79 @@
|
||||
table {
|
||||
margin: 4rem 0 2rem 0;
|
||||
border-collapse: collapse;
|
||||
margin: 4rem 0 2rem 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th > div > p,
|
||||
td > div > p {
|
||||
font-size: 0.5rem;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
font-size: 0.5rem;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th > div,
|
||||
td > div {
|
||||
width: 6rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
width: 6rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
tr:first-of-type th > div {
|
||||
width: 6rem;
|
||||
aspect-ratio: 3 / 1;
|
||||
width: 6rem;
|
||||
aspect-ratio: 3 / 1;
|
||||
}
|
||||
|
||||
td > div > input,
|
||||
td > div > label,
|
||||
td > div > p {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
white-space: pre;
|
||||
text-align: center;
|
||||
line-height: 1.1;
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
white-space: pre;
|
||||
text-align: center;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
tr th:first-of-type > div {
|
||||
font-size: 0.5rem;
|
||||
width: 2rem;
|
||||
justify-content: start;
|
||||
font-size: 0.5rem;
|
||||
width: 2rem;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
tr th:first-of-type > div > p {
|
||||
font-size: 0.5rem;
|
||||
text-align: start;
|
||||
font-size: 0.5rem;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
td > div > input + label {
|
||||
font-size: 4rem;
|
||||
height: auto;
|
||||
font-size: 4rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#section_2 fieldset {
|
||||
border: none;
|
||||
display: block;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#section_2 input {
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#section_2 input:focus:checked + label {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
transform: scale(4);
|
||||
z-index: 2;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
transform: scale(4);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#section_2 input:checked + label::before {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#section_2 input:checked + label:hover::before {
|
||||
display: block;
|
||||
background: var(--bg50);
|
||||
display: block;
|
||||
background: var(--bg50);
|
||||
}
|
||||
|
@ -1,110 +1,110 @@
|
||||
#familiar_form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#familiar_form fieldset::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 0.0625rem;
|
||||
bottom: 0.125rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
background-color: var(--text);
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 0.0625rem;
|
||||
bottom: 0.125rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#familiar_form fieldset div {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"] {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
|
||||
display: block;
|
||||
width: 0.375rem;
|
||||
height: 0.375rem;
|
||||
display: block;
|
||||
width: 0.375rem;
|
||||
height: 0.375rem;
|
||||
|
||||
/* display: grid; */
|
||||
/* place-content: center; */
|
||||
/* display: grid; */
|
||||
/* place-content: center; */
|
||||
}
|
||||
|
||||
#familiar_form label {
|
||||
display: inline;
|
||||
height: auto;
|
||||
display: inline;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"]:checked {
|
||||
transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"]:focus {
|
||||
transform: scale(2);
|
||||
transform: scale(2);
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(2) {
|
||||
margin-left: 16rem;
|
||||
margin-left: 16rem;
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(3) {
|
||||
margin-left: 15rem;
|
||||
margin-left: 15rem;
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(5) {
|
||||
margin-left: 1rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
cite {
|
||||
font-style: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
figure {
|
||||
width: max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
blockquote ~ * {
|
||||
font-size: 0.75rem;
|
||||
padding-left: 2ch;
|
||||
position: relative;
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
max-width: var(--max-width);
|
||||
font-size: 0.75rem;
|
||||
padding-left: 2ch;
|
||||
position: relative;
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
max-width: var(--max-width);
|
||||
}
|
||||
|
||||
blockquote::before {
|
||||
content: "“";
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
content: "“";
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
#familiar_container svg {
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
}
|
||||
|
||||
#familiar_container svg {
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
}
|
||||
|
||||
.svg_container {
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
}
|
||||
|
||||
#familiar_container svg path {
|
||||
fill: var(--text);
|
||||
fill: var(--text);
|
||||
}
|
||||
|
||||
#familiar_container .svg_container:focus svg path {
|
||||
fill: var(--bg);
|
||||
fill: var(--bg);
|
||||
}
|
||||
|
@ -1,126 +1,126 @@
|
||||
#original figure > div,
|
||||
#smart_kerning figure > div {
|
||||
display: flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#original p,
|
||||
#smart_kerning p {
|
||||
font-size: 24rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
border-right: 0.0625rem solid var(--text);
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
margin-left: -0.0625rem;
|
||||
font-size: 24rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
border-right: 0.0625rem solid var(--text);
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
margin-left: -0.0625rem;
|
||||
}
|
||||
|
||||
#original p::after,
|
||||
#smart_kerning p::after {
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#original p:nth-child(1)::after,
|
||||
#smart_kerning p:nth-child(1)::after {
|
||||
content: "Wide letter";
|
||||
content: "Wide letter";
|
||||
}
|
||||
|
||||
#original p:nth-child(2)::after {
|
||||
content: "Smart kerning OFF";
|
||||
content: "Smart kerning OFF";
|
||||
}
|
||||
|
||||
#smart_kerning p:nth-child(2)::after {
|
||||
content: "Smart kerning ON";
|
||||
content: "Smart kerning ON";
|
||||
}
|
||||
|
||||
#original p:nth-child(3)::after,
|
||||
#smart_kerning p:nth-child(3)::after {
|
||||
content: "Narrow letter";
|
||||
content: "Narrow letter";
|
||||
}
|
||||
|
||||
#smart_kerning p:nth-child(2)::before {
|
||||
content: "o";
|
||||
position: absolute;
|
||||
transform: translateX(calc(24rem / 1000 * 40));
|
||||
color: var(--middle);
|
||||
z-index: -1;
|
||||
content: "o";
|
||||
position: absolute;
|
||||
transform: translateX(calc(24rem / 1000 * 40));
|
||||
color: var(--middle);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#before p,
|
||||
#after p {
|
||||
font-size: 8rem;
|
||||
line-height: 1;
|
||||
max-width: none;
|
||||
white-space: nowrap;
|
||||
font-size: 8rem;
|
||||
line-height: 1;
|
||||
max-width: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#before p {
|
||||
font-feature-settings: "ss05" 0;
|
||||
font-feature-settings: "ss05" 0;
|
||||
}
|
||||
|
||||
#after p {
|
||||
font-feature-settings: "ss05" 1;
|
||||
font-feature-settings: "ss05" 1;
|
||||
}
|
||||
|
||||
#intelligent_form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#intelligent_form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#intelligent_form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#intelligent_form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#intelligent_form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#intelligent_form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#intelligent_form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#intelligent_form input:checked + label::before {
|
||||
background: var(--bg25);
|
||||
background: var(--bg25);
|
||||
}
|
||||
|
||||
#intelligent_form input:checked + label {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
@ -1,75 +1,75 @@
|
||||
#code_form fieldset {
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.65rem;
|
||||
gap: 1ch;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.65rem;
|
||||
gap: 1ch;
|
||||
}
|
||||
|
||||
form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
form input:checked + label::before {
|
||||
background: var(--bg25);
|
||||
background-position: 1px 0.5px;
|
||||
background: var(--bg25);
|
||||
background-position: 1px 0.5px;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
#code_description {
|
||||
height: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
@ -1,136 +1,136 @@
|
||||
#waterfall {
|
||||
display: flex;
|
||||
width: min-content;
|
||||
gap: 2rem;
|
||||
display: flex;
|
||||
width: min-content;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.waterfall_texts_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
height: 10rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.waterfall_texts_container > div {
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.waterfall_text {
|
||||
line-height: 0.6;
|
||||
white-space: pre;
|
||||
line-height: 0.6;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.waterfall_desc {
|
||||
width: max-content;
|
||||
white-space: pre;
|
||||
width: max-content;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.question_container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
gap: 2ch;
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
gap: 2ch;
|
||||
position: relative;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.question_character.hide_character {
|
||||
opacity: 1;
|
||||
animation: 0ms 0s 3 forwards flicker_reverse;
|
||||
opacity: 1;
|
||||
animation: 0ms 0s 3 forwards flicker_reverse;
|
||||
}
|
||||
|
||||
.question_character.show_character {
|
||||
opacity: 0;
|
||||
animation: 100ms 0s 3 forwards flicker;
|
||||
opacity: 0;
|
||||
animation: 100ms 0s 3 forwards flicker;
|
||||
}
|
||||
|
||||
.button_container button {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:root {
|
||||
--question-character-size: 6rem;
|
||||
--question-character-size: 6rem;
|
||||
}
|
||||
|
||||
.question_character {
|
||||
font-size: var(--question-character-size);
|
||||
line-height: var(--question-character-size);
|
||||
border: 0.0625rem solid var(--text);
|
||||
position: relative;
|
||||
font-size: var(--question-character-size);
|
||||
line-height: var(--question-character-size);
|
||||
border: 0.0625rem solid var(--text);
|
||||
position: relative;
|
||||
}
|
||||
.question_character::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 15%;
|
||||
/* height: 0.0625rem; */
|
||||
background-color: var(--text);
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 15%;
|
||||
/* height: 0.0625rem; */
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#score_points {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
#score_points.view_score {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.question_button:focus::before,
|
||||
.question_button:hover::before {
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button:hover {
|
||||
background: var(--bg50);
|
||||
color: var(--bg);
|
||||
background: var(--bg50);
|
||||
color: var(--bg);
|
||||
}
|
||||
.question_button.right_button::before {
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button.wrong_button::before {
|
||||
content: "->";
|
||||
position: absolute;
|
||||
left: auto;
|
||||
right: -2ch;
|
||||
color: var(--text);
|
||||
content: "->";
|
||||
position: absolute;
|
||||
left: auto;
|
||||
right: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.question_button.button_choice {
|
||||
background: var(--bg25);
|
||||
color: var(--text);
|
||||
background: var(--bg25);
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button.button_choice:focus {
|
||||
background: var(--bg75);
|
||||
color: var(--bg);
|
||||
background: var(--bg75);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
.answer_feedback {
|
||||
position: relative;
|
||||
font-size: 0.75rem;
|
||||
top: calc(var(--question-character-size) * 0.5);
|
||||
top: 40%;
|
||||
width: 0;
|
||||
margin-left: -2ch;
|
||||
left: 0;
|
||||
position: relative;
|
||||
font-size: 0.75rem;
|
||||
top: calc(var(--question-character-size) * 0.5);
|
||||
top: 40%;
|
||||
width: 0;
|
||||
margin-left: -2ch;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.question_container.active_question ~ .question_container.active_question {
|
||||
pointer-events: auto;
|
||||
display: flex;
|
||||
pointer-events: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.question_container.active_question ~ .question_container {
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.question_container.active_question ~ br {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,97 +1,97 @@
|
||||
#section_7 #alternates_container fieldset,
|
||||
#section_7 #features_container fieldset {
|
||||
display: grid;
|
||||
grid-template-columns: 21ch 3ch 3ch;
|
||||
gap: 2ch;
|
||||
display: grid;
|
||||
grid-template-columns: 21ch 3ch 3ch;
|
||||
gap: 2ch;
|
||||
}
|
||||
|
||||
#section_7 #examplesettings_form fieldset p {
|
||||
white-space: pre;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
|
||||
fieldset.alternates > div {
|
||||
width: 4ch;
|
||||
width: 4ch;
|
||||
}
|
||||
|
||||
#section_7 form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#examples_container {
|
||||
width: fit-content;
|
||||
max-height: 20.6rem;
|
||||
margin-bottom: 0.4rem;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
width: fit-content;
|
||||
max-height: 20.6rem;
|
||||
margin-bottom: 0.4rem;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
#examples_container::-webkit-scrollbar {
|
||||
display: none; /* Safari and Chrome */
|
||||
display: none; /* Safari and Chrome */
|
||||
}
|
||||
|
||||
p#code_example {
|
||||
white-space: pre;
|
||||
max-width: none;
|
||||
min-width: 102ch;
|
||||
padding-left: 5ch;
|
||||
position: relative;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
max-width: none;
|
||||
min-width: 102ch;
|
||||
padding-left: 5ch;
|
||||
position: relative;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
p#code_example::before {
|
||||
content: attr(data-before);
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
content: attr(data-before);
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button:focus a {
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.download_button {
|
||||
display: block;
|
||||
width: max-content;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: max-content;
|
||||
position: relative;
|
||||
}
|
||||
.download_button:hover {
|
||||
background: var(--bg50);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
background: var(--bg50);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
.download_button:focus {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
.download_button::after {
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
top: 0;
|
||||
}
|
||||
.download_button.loading::after {
|
||||
content: ".";
|
||||
animation: 800ms 0ms steps(4, jump-none) infinite loading;
|
||||
content: ".";
|
||||
animation: 800ms 0ms steps(4, jump-none) infinite loading;
|
||||
}
|
||||
.download_button.loaded::after {
|
||||
content: "✓";
|
||||
animation: none;
|
||||
content: "✓";
|
||||
animation: none;
|
||||
}
|
||||
.download_button.error::after {
|
||||
content: "✕";
|
||||
animation: none;
|
||||
content: "✕";
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2ch);
|
||||
}
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2ch);
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,77 @@
|
||||
ol {
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0;
|
||||
max-width: max-content;
|
||||
counter-reset: install;
|
||||
list-style: none;
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0;
|
||||
max-width: max-content;
|
||||
counter-reset: install;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ol > li {
|
||||
margin-left: 3ch;
|
||||
max-width: calc(var(--max-width) - 3ch);
|
||||
counter-increment: install;
|
||||
position: relative;
|
||||
margin-left: 3ch;
|
||||
max-width: calc(var(--max-width) - 3ch);
|
||||
counter-increment: install;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ol > li p::before {
|
||||
content: "#" counter(install) " ";
|
||||
position: absolute;
|
||||
left: -3ch;
|
||||
content: "#" counter(install) " ";
|
||||
position: absolute;
|
||||
left: -3ch;
|
||||
}
|
||||
|
||||
ol li p {
|
||||
max-width: calc(var(--max-width) - 6ch);
|
||||
max-width: calc(var(--max-width) - 6ch);
|
||||
}
|
||||
|
||||
ol:focus li p {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
ol li ul li p {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ol li ul li p::before {
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
}
|
||||
|
||||
details > summary {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
width: fit-content;
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin-left: 4ch;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
width: fit-content;
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin-left: 4ch;
|
||||
position: relative;
|
||||
}
|
||||
details > p {
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin: 0 0 1rem 4ch;
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin: 0 0 1rem 4ch;
|
||||
}
|
||||
details > ol {
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin: 0 0 1rem 4ch;
|
||||
counter-reset: reinstall;
|
||||
max-width: calc(var(--max-width) - 4ch);
|
||||
margin: 0 0 1rem 4ch;
|
||||
counter-reset: reinstall;
|
||||
}
|
||||
details > ol li::before {
|
||||
display: block;
|
||||
counter-increment: reinstall;
|
||||
content: "#" counter(reinstall) " ";
|
||||
position: absolute;
|
||||
left: -3ch;
|
||||
display: block;
|
||||
counter-increment: reinstall;
|
||||
content: "#" counter(reinstall) " ";
|
||||
position: absolute;
|
||||
left: -3ch;
|
||||
}
|
||||
details > ol li {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
details > summary::before {
|
||||
content: "[+]";
|
||||
position: absolute;
|
||||
left: -4ch;
|
||||
content: "[+]";
|
||||
position: absolute;
|
||||
left: -4ch;
|
||||
}
|
||||
details[open] > summary::before {
|
||||
content: "[-]";
|
||||
content: "[-]";
|
||||
}
|
||||
details > summary:focus::before {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
.documentation_example {
|
||||
width: max-content;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
font-feature-settings: normal;
|
||||
.docs_example {
|
||||
width: max-content;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
font-feature-settings: normal;
|
||||
}
|
||||
|
||||
.span_off,
|
||||
.span_on {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.active_feature {
|
||||
cursor: pointer;
|
||||
background: var(--bg25);
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
background: var(--bg25);
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h2:focus .active_feature {
|
||||
background: var(--bg25-i);
|
||||
background: var(--bg25-i);
|
||||
}
|
||||
|
||||
#features_docu h2 {
|
||||
max-width: var(--max-width);
|
||||
max-width: var(--max-width);
|
||||
}
|
||||
|
||||
.documentation_alternate {
|
||||
margin-right: 2rem;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
.docs_alternate {
|
||||
margin-right: 2rem;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
#features_docu > div {
|
||||
width: max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#charset {
|
||||
width: var(--max-width);
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre-wrap;
|
||||
font-size: 3rem;
|
||||
line-height: 4rem;
|
||||
width: var(--max-width);
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre-wrap;
|
||||
font-size: 3rem;
|
||||
line-height: 4rem;
|
||||
}
|
||||
|
@ -1,244 +1,244 @@
|
||||
:root {
|
||||
--bg25: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg50: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, var(--text) 0% 75%, transparent 0% 100%) 1px
|
||||
0.5px / 2px 2px;
|
||||
--bg75: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg25-i: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg50-i: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 50%, var(--bg) 0% 75%, transparent 0% 100%) 1px
|
||||
0.5px / 2px 2px;
|
||||
--bg75-i: repeating-conic-gradient(transparent 0% 25%, var(--bg) 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg25: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg50: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, var(--text) 0% 75%, transparent 0% 100%)
|
||||
1px 0.5px / 2px 2px;
|
||||
--bg75: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg25-i: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 100%) 1px 0.5px / 2px 2px;
|
||||
--bg50-i: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 50%, var(--bg) 0% 75%, transparent 0% 100%) 1px
|
||||
0.5px / 2px 2px;
|
||||
--bg75-i: repeating-conic-gradient(transparent 0% 25%, var(--bg) 0% 100%) 1px 0.5px / 2px 2px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: var(--text);
|
||||
background-color: var(--middle);
|
||||
color: var(--text);
|
||||
background-color: var(--middle);
|
||||
}
|
||||
|
||||
#block_tab_start,
|
||||
#block_tab_end {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#main_scale {
|
||||
inset: 0;
|
||||
overflow: scroll;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
padding-bottom: 10rem;
|
||||
inset: 0;
|
||||
overflow: scroll;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
padding-bottom: 10rem;
|
||||
}
|
||||
#main_scale::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
main {
|
||||
min-width: 100vw;
|
||||
width: fit-content;
|
||||
padding: 4rem 2ch 0 4ch;
|
||||
min-width: 100vw;
|
||||
width: fit-content;
|
||||
padding: 4rem 2ch 0 4ch;
|
||||
}
|
||||
|
||||
header nav {
|
||||
width: 100vw;
|
||||
padding: 1rem 4ch 0 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
padding: 1rem 4ch 0 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
header #keyboard_section {
|
||||
width: 100%;
|
||||
padding: 0.25rem 4ch 1rem 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 0.25rem 4ch 1rem 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
header #keyboard_section,
|
||||
header nav {
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
header #keyboard_section::-webkit-scrollbar,
|
||||
header nav::-webkit-scrollbar {
|
||||
display: none; /* Safari and Chrome */
|
||||
display: none; /* Safari and Chrome */
|
||||
}
|
||||
|
||||
#keyboard_section.hidden {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav_form {
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#nav_form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#nav_form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#nav_form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#nav_form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#nav_form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#section_container {
|
||||
inset: 1rem 2rem;
|
||||
inset: 1rem 2rem;
|
||||
}
|
||||
|
||||
p,
|
||||
a,
|
||||
figcaption,
|
||||
button {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
max-width: var(--max-width);
|
||||
width: fit-content;
|
||||
vertical-align: top;
|
||||
color: inherit;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
max-width: var(--max-width);
|
||||
width: fit-content;
|
||||
vertical-align: top;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a,
|
||||
.download_button {
|
||||
text-decoration: underline;
|
||||
text-decoration-skip-ink: none;
|
||||
text-underline-offset: 0.24ch;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-decoration-skip-ink: none;
|
||||
text-underline-offset: 0.24ch;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:focus,
|
||||
.download_button:focus {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#change_setting p {
|
||||
padding: 0 1ch;
|
||||
background-color: var(--bg);
|
||||
padding: 0 1ch;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
.faded {
|
||||
opacity: 0.33;
|
||||
opacity: 0.33;
|
||||
}
|
||||
|
||||
#mobile {
|
||||
visibility: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
:focus {
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
form input:hover + label {
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
form input:hover + label::before {
|
||||
background: var(--bg50);
|
||||
background: var(--bg50);
|
||||
}
|
||||
|
||||
form input:checked:hover + label::before {
|
||||
background: var(--bg75);
|
||||
background: var(--bg75);
|
||||
}
|
||||
|
||||
ul li,
|
||||
ol li {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
margin-left: 2ch;
|
||||
max-width: 54ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
margin-left: 2ch;
|
||||
max-width: 54ch;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
max-width: max-content;
|
||||
list-style-type: none;
|
||||
max-width: max-content;
|
||||
}
|
||||
|
||||
ol li::before {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul li::before {
|
||||
content: "• ";
|
||||
position: absolute;
|
||||
margin-left: -2ch;
|
||||
content: "• ";
|
||||
position: absolute;
|
||||
margin-left: -2ch;
|
||||
}
|
||||
|
||||
ul li:focus::before {
|
||||
background-color: transparent;
|
||||
color: var(--text);
|
||||
background-color: transparent;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
#page_animation {
|
||||
width: 200vw;
|
||||
height: 200vh;
|
||||
height: 200dvh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-color: var(--bg);
|
||||
pointer-events: none;
|
||||
width: 200vw;
|
||||
height: 200vh;
|
||||
height: 200dvh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-color: var(--bg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#page_animation.page_animation {
|
||||
animation: 440ms steps(10, jump-start) forwards page_animation;
|
||||
animation: 440ms steps(10, jump-start) forwards page_animation;
|
||||
}
|
||||
|
||||
@keyframes page_animation {
|
||||
0% {
|
||||
transform: translateY(0vh);
|
||||
}
|
||||
99.9% {
|
||||
visibility: visible;
|
||||
}
|
||||
100% {
|
||||
visibility: hidden;
|
||||
transform: translateY(200vh);
|
||||
}
|
||||
0% {
|
||||
transform: translateY(0vh);
|
||||
}
|
||||
99.9% {
|
||||
visibility: visible;
|
||||
}
|
||||
100% {
|
||||
visibility: hidden;
|
||||
transform: translateY(200vh);
|
||||
}
|
||||
}
|
||||
|
||||
#focus_check {
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#footer_hint_mobile {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
@ -3,349 +3,349 @@ const codeFieldset = document.querySelector("#code_form fieldset")
|
||||
const codeDescription = document.querySelector("#code_description")
|
||||
|
||||
function buildCode() {
|
||||
console.log("buildCode")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "code"
|
||||
input.id = character.name
|
||||
input.classList.add("code_character")
|
||||
input.value = character.name
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = character.value
|
||||
label.setAttribute("for", character.name)
|
||||
div.append(input, label)
|
||||
codeFieldset.append(div)
|
||||
console.log("buildCode")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "code"
|
||||
input.id = character.name
|
||||
input.classList.add("code_character")
|
||||
input.value = character.name
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = character.value
|
||||
label.setAttribute("for", character.name)
|
||||
div.append(input, label)
|
||||
codeFieldset.append(div)
|
||||
|
||||
const p = document.createElement("p")
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
p.classList.add("code_char")
|
||||
p.dataset.char = character.name
|
||||
p.textContent = character.description
|
||||
p.style.display = "none"
|
||||
codeDescription.append(p)
|
||||
})
|
||||
}
|
||||
})
|
||||
const p = document.createElement("p")
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
p.classList.add("code_char")
|
||||
p.dataset.char = character.name
|
||||
p.textContent = character.description
|
||||
p.style.display = "none"
|
||||
codeDescription.append(p)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateCode(event, form) {
|
||||
console.log("updateCode")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
console.log("updateCode")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
|
||||
let displayCharacter = ""
|
||||
let displayName = ""
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
if (character.name == output) {
|
||||
displayCharacter = character.value
|
||||
displayName = character.name
|
||||
const ps = document.querySelectorAll(".code_char")
|
||||
ps.forEach((p) =>
|
||||
p.dataset.char == character.name ? (p.style.display = "block") : (p.style.display = "none")
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
let displayCharacter = ""
|
||||
let displayName = ""
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
if (character.name == output) {
|
||||
displayCharacter = character.value
|
||||
displayName = character.name
|
||||
const ps = document.querySelectorAll(".code_char")
|
||||
ps.forEach((p) =>
|
||||
p.dataset.char == character.name ? (p.style.display = "block") : (p.style.display = "none")
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let selectedGlyphData
|
||||
if (commitMonoFont) {
|
||||
Object.values(commitMonoFont.glyphs.glyphs).forEach((glyph) => {
|
||||
if (glyph.name == output) selectedGlyphData = glyph
|
||||
})
|
||||
updateCanvas(selectedGlyphData, commitMonoFont, displayCharacter, displayName)
|
||||
}
|
||||
let selectedGlyphData
|
||||
if (commitMonoFont) {
|
||||
Object.values(commitMonoFont.glyphs.glyphs).forEach((glyph) => {
|
||||
if (glyph.name == output) selectedGlyphData = glyph
|
||||
})
|
||||
updateCanvas(selectedGlyphData, commitMonoFont, displayCharacter, displayName)
|
||||
}
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
const canvasScale = 16
|
||||
|
||||
const drawFontLine = (GLYPH_SCALE, ctx, upem, width, name, value, yOffset) => {
|
||||
let scaledValue = mapRange(value, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue = width - scaledValue + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue = mapRange(value, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue = width - scaledValue + (yOffset * GLYPH_SCALE * width) / upem
|
||||
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7 * canvasScale, scaledValue)
|
||||
ctx.lineTo(width - 7 * canvasScale, scaledValue)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7 * canvasScale, scaledValue)
|
||||
ctx.lineTo(width - 7 * canvasScale, scaledValue)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "CommitMono"`
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(name, 0, scaledValue + 0.25 * canvasScale)
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(value, width - 4 * canvasScale, scaledValue + 0.25 * canvasScale)
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "CommitMono"`
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(name, 0, scaledValue + 0.25 * canvasScale)
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(value, width - 4 * canvasScale, scaledValue + 0.25 * canvasScale)
|
||||
}
|
||||
const drawFontLineVertical = (GLYPH_SCALE, ctx, upem, width, value, yOffset, ascender, descender) => {
|
||||
let scaledValue1 = mapRange(ascender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue1 = width - scaledValue1 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue2 = mapRange(descender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue2 = width - scaledValue2 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue1 = mapRange(ascender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue1 = width - scaledValue1 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue2 = mapRange(descender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue2 = width - scaledValue2 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(value, scaledValue1)
|
||||
ctx.lineTo(value, scaledValue2)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(value, scaledValue1)
|
||||
ctx.lineTo(value, scaledValue2)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function updateCanvas(selectedGlyphData, selectedFont, displayCharacter, displayName) {
|
||||
// initialize canvas
|
||||
let CANVAS_SCALE = window.devicePixelRatio
|
||||
const canvas = document.querySelector("#canvas")
|
||||
let canvasWidth = 60 * canvasScale
|
||||
let canvasHeight = 42 * canvasScale
|
||||
canvas.style.width = `${canvasWidth}px`
|
||||
canvas.style.height = `${canvasHeight}px`
|
||||
canvas.width = canvasWidth * CANVAS_SCALE
|
||||
canvas.height = canvasHeight * CANVAS_SCALE
|
||||
const ctx = canvas.getContext("2d")
|
||||
ctx.scale(CANVAS_SCALE, CANVAS_SCALE)
|
||||
// initialize canvas
|
||||
let CANVAS_SCALE = window.devicePixelRatio
|
||||
const canvas = document.querySelector("#canvas")
|
||||
let canvasWidth = 60 * canvasScale
|
||||
let canvasHeight = 42 * canvasScale
|
||||
canvas.style.width = `${canvasWidth}px`
|
||||
canvas.style.height = `${canvasHeight}px`
|
||||
canvas.width = canvasWidth * CANVAS_SCALE
|
||||
canvas.height = canvasHeight * CANVAS_SCALE
|
||||
const ctx = canvas.getContext("2d")
|
||||
ctx.scale(CANVAS_SCALE, CANVAS_SCALE)
|
||||
|
||||
let GLYPH_SCALE = 0.6
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
let GLYPH_SCALE = 0.6
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
|
||||
if (selectedGlyphData.path) {
|
||||
const CANVAS_GLYPH_COMPOSITION_FILL = [
|
||||
{
|
||||
type: "outline",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
]
|
||||
const CANVAS_GLYPH_COMPOSITION_BEZIER = [
|
||||
// {
|
||||
// type: "outline",
|
||||
// fill: true,
|
||||
// color: "rgba(0, 0, 0, 0.1)",
|
||||
// pointSize: undefined,
|
||||
// },
|
||||
{
|
||||
type: "handles",
|
||||
fill: false,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "outline",
|
||||
fill: false,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "points",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: 10, // size of point on bezier glyph
|
||||
},
|
||||
{
|
||||
type: "handle points",
|
||||
fill: true,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: 10, // size of handles on bezier glyph
|
||||
},
|
||||
]
|
||||
if (selectedGlyphData.path) {
|
||||
const CANVAS_GLYPH_COMPOSITION_FILL = [
|
||||
{
|
||||
type: "outline",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
]
|
||||
const CANVAS_GLYPH_COMPOSITION_BEZIER = [
|
||||
// {
|
||||
// type: "outline",
|
||||
// fill: true,
|
||||
// color: "rgba(0, 0, 0, 0.1)",
|
||||
// pointSize: undefined,
|
||||
// },
|
||||
{
|
||||
type: "handles",
|
||||
fill: false,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "outline",
|
||||
fill: false,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "points",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: 10, // size of point on bezier glyph
|
||||
},
|
||||
{
|
||||
type: "handle points",
|
||||
fill: true,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: 10, // size of handles on bezier glyph
|
||||
},
|
||||
]
|
||||
|
||||
const upem = selectedFont?.unitsPerEm || 1000
|
||||
const width = 60 * canvasScale
|
||||
const upem = selectedFont?.unitsPerEm || 1000
|
||||
const width = 60 * canvasScale
|
||||
|
||||
const yOffset = -45 * canvasScale
|
||||
const xOffset = 20 * canvasScale
|
||||
const ascender = selectedFont?.tables.os2?.sTypoAscender || 750
|
||||
const capHeight = selectedFont?.tables.os2?.sCapHeight || 700
|
||||
const xHeight = selectedFont?.tables.os2?.sxHeight
|
||||
const baseline = 0
|
||||
const descender = selectedFont?.tables.os2?.sTypoDescender || -200
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Ascender", ascender, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Cap Height", capHeight, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "X-height", xHeight || 500, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Baseline", baseline, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Descender", descender, yOffset)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 7 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 30 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 53 * canvasScale, yOffset, ascender, descender)
|
||||
const yOffset = -45 * canvasScale
|
||||
const xOffset = 20 * canvasScale
|
||||
const ascender = selectedFont?.tables.os2?.sTypoAscender || 750
|
||||
const capHeight = selectedFont?.tables.os2?.sCapHeight || 700
|
||||
const xHeight = selectedFont?.tables.os2?.sxHeight
|
||||
const baseline = 0
|
||||
const descender = selectedFont?.tables.os2?.sTypoDescender || -200
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Ascender", ascender, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Cap Height", capHeight, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "X-height", xHeight || 500, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Baseline", baseline, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Descender", descender, yOffset)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 7 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 30 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 53 * canvasScale, yOffset, ascender, descender)
|
||||
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "CommitMono"`
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillText(displayName, (30 - 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillText(displayName, (30 + 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "CommitMono"`
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillText(displayName, (30 - 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillText(displayName, (30 + 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
|
||||
// make ready transformation matrixes for manipulating paths
|
||||
let firstMatrix = new DOMMatrix()
|
||||
firstMatrix = firstMatrix.scaleSelf(width / upem)
|
||||
let secondMatrix = new DOMMatrix()
|
||||
secondMatrix = secondMatrix.scaleSelf(GLYPH_SCALE)
|
||||
secondMatrix = secondMatrix.translateSelf(-width * 0.5, -width) // translate to left edge, top
|
||||
secondMatrix = secondMatrix.translateSelf((width * 0.5) / GLYPH_SCALE, width / GLYPH_SCALE) // translate to center, baseline
|
||||
secondMatrix = secondMatrix.translateSelf(0, (yOffset * width) / upem) // translate yOffset
|
||||
secondMatrix = secondMatrix.translateSelf((xOffset * width) / upem, 0) // translate xOffset
|
||||
// make ready transformation matrixes for manipulating paths
|
||||
let firstMatrix = new DOMMatrix()
|
||||
firstMatrix = firstMatrix.scaleSelf(width / upem)
|
||||
let secondMatrix = new DOMMatrix()
|
||||
secondMatrix = secondMatrix.scaleSelf(GLYPH_SCALE)
|
||||
secondMatrix = secondMatrix.translateSelf(-width * 0.5, -width) // translate to left edge, top
|
||||
secondMatrix = secondMatrix.translateSelf((width * 0.5) / GLYPH_SCALE, width / GLYPH_SCALE) // translate to center, baseline
|
||||
secondMatrix = secondMatrix.translateSelf(0, (yOffset * width) / upem) // translate yOffset
|
||||
secondMatrix = secondMatrix.translateSelf((xOffset * width) / upem, 0) // translate xOffset
|
||||
|
||||
// set initial value for glyph composition based on if bezier is switched on or off
|
||||
// let canvasGlyphComposition = bezier ? CANVAS_GLYPH_COMPOSITION_BEZIER : CANVAS_GLYPH_COMPOSITION_FILL
|
||||
// set initial value for glyph composition based on if bezier is switched on or off
|
||||
// let canvasGlyphComposition = bezier ? CANVAS_GLYPH_COMPOSITION_BEZIER : CANVAS_GLYPH_COMPOSITION_FILL
|
||||
|
||||
CANVAS_GLYPH_COMPOSITION_BEZIER.forEach((composite) => {
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
CANVAS_GLYPH_COMPOSITION_BEZIER.forEach((composite) => {
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
CANVAS_GLYPH_COMPOSITION_FILL.forEach((composite) => {
|
||||
secondMatrix = secondMatrix.translateSelf((-2 * xOffset * width) / upem, 0) // translate xOffset
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
CANVAS_GLYPH_COMPOSITION_FILL.forEach((composite) => {
|
||||
secondMatrix = secondMatrix.translateSelf((-2 * xOffset * width) / upem, 0) // translate xOffset
|
||||
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function glyphBezier(glyph, upem, typeOfOutline, pointSize) {
|
||||
let ps = pointSize
|
||||
let offsetX = (upem - glyph.advanceWidth) * 0.5
|
||||
let path2d = new Path2D()
|
||||
let ps = pointSize
|
||||
let offsetX = (upem - glyph.advanceWidth) * 0.5
|
||||
let path2d = new Path2D()
|
||||
|
||||
if (typeOfOutline == "outline") {
|
||||
let commandString = ""
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "L":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "C":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x2 + offsetX} ${upem - command.y2}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Q":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Z":
|
||||
commandString += `${command.type} `
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(new Path2D(commandString))
|
||||
}
|
||||
if (typeOfOutline == "outline") {
|
||||
let commandString = ""
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "L":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "C":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x2 + offsetX} ${upem - command.y2}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Q":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Z":
|
||||
commandString += `${command.type} `
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(new Path2D(commandString))
|
||||
}
|
||||
|
||||
if (typeOfOutline == "points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x = command.x + offsetX
|
||||
const y = upem - command.y
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "L":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "C":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
if (typeOfOutline == "points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x = command.x + offsetX
|
||||
const y = upem - command.y
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "L":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "C":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
|
||||
if (typeOfOutline == "handles") {
|
||||
let p = new Path2D()
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "L":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "C":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
p.lineTo(command.x2 + offsetX, upem - command.y2)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Q":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.lineTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Z":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(p)
|
||||
}
|
||||
if (typeOfOutline == "handles") {
|
||||
let p = new Path2D()
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "L":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "C":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
p.lineTo(command.x2 + offsetX, upem - command.y2)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Q":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.lineTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Z":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(p)
|
||||
}
|
||||
|
||||
if (typeOfOutline == "handle points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x1 = command.x1 + offsetX
|
||||
const x2 = command.x2 + offsetX
|
||||
const y1 = upem - command.y1
|
||||
const y2 = upem - command.y2
|
||||
switch (command.type) {
|
||||
case "C":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
p.rect(x2 - ps * 0.5, y2 - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
if (typeOfOutline == "handle points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x1 = command.x1 + offsetX
|
||||
const x2 = command.x2 + offsetX
|
||||
const y1 = upem - command.y1
|
||||
const y2 = upem - command.y2
|
||||
switch (command.type) {
|
||||
case "C":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
p.rect(x2 - ps * 0.5, y2 - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
|
||||
return path2d
|
||||
return path2d
|
||||
}
|
||||
|
@ -1,86 +1,86 @@
|
||||
let waterfall, gtc
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
waterfall = section.content.waterfall
|
||||
gtc = section.content.gtc
|
||||
}
|
||||
if (section.name == "distinction") {
|
||||
waterfall = section.content.waterfall
|
||||
gtc = section.content.gtc
|
||||
}
|
||||
})
|
||||
|
||||
function updateWaterfall() {
|
||||
console.log("updateWaterfall")
|
||||
const waterfallContainer = document.querySelector("#waterfall")
|
||||
waterfallContainer.innerHTML = ""
|
||||
waterfall.sizes.forEach((size) => {
|
||||
const div = document.createElement("div")
|
||||
div.id = `size_${size}`
|
||||
console.log("updateWaterfall")
|
||||
const waterfallContainer = document.querySelector("#waterfall")
|
||||
waterfallContainer.innerHTML = ""
|
||||
waterfall.sizes.forEach((size) => {
|
||||
const div = document.createElement("div")
|
||||
div.id = `size_${size}`
|
||||
|
||||
const desc = document.createElement("p")
|
||||
desc.classList.add("waterfall_desc")
|
||||
desc.textContent = `${size}rem\n${Math.round(size * rem * 100) / 100}px`
|
||||
const desc = document.createElement("p")
|
||||
desc.classList.add("waterfall_desc")
|
||||
desc.textContent = `${size}rem\n${Math.round(size * rem * 100) / 100}px`
|
||||
|
||||
const textsContainer = document.createElement("div")
|
||||
textsContainer.classList.add("waterfall_texts_container")
|
||||
waterfall.texts.forEach((text) => {
|
||||
const div2 = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("waterfall_text")
|
||||
p.style.fontSize = `${Math.round(size * rem * 100) / 100}px`
|
||||
p.textContent = text
|
||||
div2.append(p)
|
||||
textsContainer.append(div2)
|
||||
})
|
||||
div.append(desc, textsContainer)
|
||||
const textsContainer = document.createElement("div")
|
||||
textsContainer.classList.add("waterfall_texts_container")
|
||||
waterfall.texts.forEach((text) => {
|
||||
const div2 = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("waterfall_text")
|
||||
p.style.fontSize = `${Math.round(size * rem * 100) / 100}px`
|
||||
p.textContent = text
|
||||
div2.append(p)
|
||||
textsContainer.append(div2)
|
||||
})
|
||||
div.append(desc, textsContainer)
|
||||
|
||||
waterfallContainer.append(div)
|
||||
})
|
||||
waterfallContainer.append(div)
|
||||
})
|
||||
}
|
||||
|
||||
const gtcForm = document.querySelector("#gtc_form")
|
||||
const gtcFieldset = document.querySelector("#gtc_form fieldset")
|
||||
|
||||
function buildDistinction() {
|
||||
console.log("buildDistinction")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "difficulty"
|
||||
input.id = `difficulty_${difficulty.name}`
|
||||
input.classList.add("gtc_difficulty")
|
||||
input.value = difficulty.name
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = difficulty.name
|
||||
label.setAttribute("for", `difficulty_${difficulty.name}`)
|
||||
div.append(input, label)
|
||||
gtcFieldset.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log("buildDistinction")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "difficulty"
|
||||
input.id = `difficulty_${difficulty.name}`
|
||||
input.classList.add("gtc_difficulty")
|
||||
input.value = difficulty.name
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = difficulty.name
|
||||
label.setAttribute("for", `difficulty_${difficulty.name}`)
|
||||
div.append(input, label)
|
||||
gtcFieldset.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateGTC(event, form) {
|
||||
console.log("updateGTC")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty) => {
|
||||
if (difficulty.name == output) {
|
||||
setCssVar(["--question-character-size", `${difficulty.size}rem`])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log("updateGTC")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty) => {
|
||||
if (difficulty.name == output) {
|
||||
setCssVar(["--question-character-size", `${difficulty.size}rem`])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
let answers = []
|
||||
@ -88,103 +88,105 @@ let score = -1
|
||||
let currentQuestion = -1
|
||||
let firstButtons = []
|
||||
function buildGTC() {
|
||||
console.log("buildGTC")
|
||||
const gtcContainer = document.querySelector("#gtc_questions_container")
|
||||
gtcContainer.innerHTML = ""
|
||||
answers = []
|
||||
firstButtons = []
|
||||
gtc.forEach((question, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.classList.add("question_container")
|
||||
div.dataset.index = index
|
||||
console.log("buildGTC")
|
||||
const gtcContainer = document.querySelector("#gtc_questions_container")
|
||||
gtcContainer.innerHTML = ""
|
||||
answers = []
|
||||
firstButtons = []
|
||||
gtc.forEach((question, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.classList.add("question_container")
|
||||
div.dataset.index = index
|
||||
|
||||
const answer = Math.round(Math.random())
|
||||
const wrongAnswer = (answer + 1) % 2
|
||||
answers.push(answer)
|
||||
const answer = Math.round(Math.random())
|
||||
const wrongAnswer = (answer + 1) % 2
|
||||
answers.push(answer)
|
||||
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("question_character")
|
||||
p.textContent = question.value[answer]
|
||||
const pWrong = document.createElement("p")
|
||||
pWrong.classList.add("question_character", "wrong_character", "hide_character")
|
||||
pWrong.textContent = question.value[wrongAnswer]
|
||||
const buttonContainer = document.createElement("div")
|
||||
buttonContainer.classList.add("button_container")
|
||||
const option0 = document.createElement("button")
|
||||
option0.classList.add("question_button")
|
||||
option0.textContent = question.options[0]
|
||||
option0.dataset.questionIndex = index
|
||||
option0.tabIndex = -1
|
||||
firstButtons.push(option0)
|
||||
const option1 = document.createElement("button")
|
||||
option1.classList.add("question_button")
|
||||
option1.textContent = question.options[1]
|
||||
option1.dataset.questionIndex = index
|
||||
option1.tabIndex = -1
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("question_character")
|
||||
p.textContent = question.value[answer]
|
||||
const pWrong = document.createElement("p")
|
||||
pWrong.classList.add("question_character", "wrong_character", "hide_character")
|
||||
pWrong.textContent = question.value[wrongAnswer]
|
||||
const buttonContainer = document.createElement("div")
|
||||
buttonContainer.classList.add("button_container")
|
||||
const option0 = document.createElement("button")
|
||||
option0.classList.add("question_button")
|
||||
option0.textContent = question.options[0]
|
||||
option0.dataset.questionIndex = index
|
||||
option0.tabIndex = -1
|
||||
firstButtons.push(option0)
|
||||
const option1 = document.createElement("button")
|
||||
option1.classList.add("question_button")
|
||||
option1.textContent = question.options[1]
|
||||
option1.dataset.questionIndex = index
|
||||
option1.tabIndex = -1
|
||||
|
||||
const options = [option0, option1]
|
||||
options[answer].addEventListener("click", (e) => nextQuestion(true, answer, wrongAnswer, e.pointerType))
|
||||
options[wrongAnswer].addEventListener("click", (e) => nextQuestion(false, answer, wrongAnswer, e.pointerType))
|
||||
const options = [option0, option1]
|
||||
options[answer].addEventListener("click", (e) => nextQuestion(true, answer, wrongAnswer, e.pointerType))
|
||||
options[wrongAnswer].addEventListener("click", (e) => nextQuestion(false, answer, wrongAnswer, e.pointerType))
|
||||
|
||||
const answerFeedback = document.createElement("p")
|
||||
answerFeedback.classList.add("answer_feedback")
|
||||
const answerFeedback = document.createElement("p")
|
||||
answerFeedback.classList.add("answer_feedback")
|
||||
|
||||
buttonContainer.append(option0, option1)
|
||||
const br = document.createElement("br")
|
||||
div.append(answerFeedback, p, buttonContainer, pWrong)
|
||||
gtcContainer.append(div)
|
||||
})
|
||||
const scorePoints = document.createElement("p")
|
||||
scorePoints.id = "score_points"
|
||||
scorePoints.textContent = `You scored ${score} out of ${gtc.length}`
|
||||
gtcContainer.append(scorePoints)
|
||||
nextQuestion(true, 0, 1)
|
||||
buttonContainer.append(option0, option1)
|
||||
const br = document.createElement("br")
|
||||
div.append(answerFeedback, p, buttonContainer, pWrong)
|
||||
gtcContainer.append(div)
|
||||
})
|
||||
const scorePoints = document.createElement("p")
|
||||
scorePoints.id = "score_points"
|
||||
scorePoints.textContent = `You scored ${score} out of ${gtc.length}`
|
||||
gtcContainer.append(scorePoints)
|
||||
nextQuestion(true, 0, 1)
|
||||
}
|
||||
|
||||
function nextQuestion(correct, answer, wrongAnswer, pointerType) {
|
||||
console.log(pointerType)
|
||||
const scoreTally = document.querySelector("#score_tally")
|
||||
const allQuestions = document.querySelectorAll(".question_container")
|
||||
let answerFeedback
|
||||
console.log(pointerType)
|
||||
const scoreTally = document.querySelector("#score_tally")
|
||||
const allQuestions = document.querySelectorAll(".question_container")
|
||||
let answerFeedback
|
||||
|
||||
if (correct) score++
|
||||
if (correct) score++
|
||||
|
||||
allQuestions.forEach((question, index) => {
|
||||
const wrongCharacter = question.querySelector(".wrong_character")
|
||||
allQuestions.forEach((question, index) => {
|
||||
const wrongCharacter = question.querySelector(".wrong_character")
|
||||
|
||||
if (index == currentQuestion) {
|
||||
question.classList.add("active_question")
|
||||
const rightButton = question.querySelector(`.button_container .question_button:nth-child(${answer + 1})`)
|
||||
const wrongButton = question.querySelector(`.button_container .question_button:nth-child(${wrongAnswer + 1})`)
|
||||
correct ? rightButton.classList.add("button_choice") : wrongButton.classList.add("button_choice")
|
||||
rightButton.classList.add("right_button")
|
||||
wrongButton.classList.add("wrong_button")
|
||||
if (index == currentQuestion) {
|
||||
question.classList.add("active_question")
|
||||
const rightButton = question.querySelector(`.button_container .question_button:nth-child(${answer + 1})`)
|
||||
const wrongButton = question.querySelector(
|
||||
`.button_container .question_button:nth-child(${wrongAnswer + 1})`
|
||||
)
|
||||
correct ? rightButton.classList.add("button_choice") : wrongButton.classList.add("button_choice")
|
||||
rightButton.classList.add("right_button")
|
||||
wrongButton.classList.add("wrong_button")
|
||||
|
||||
answerFeedback = question.querySelector(".answer_feedback")
|
||||
answerFeedback.textContent = correct ? "✓" : "✕"
|
||||
answerFeedback = question.querySelector(".answer_feedback")
|
||||
answerFeedback.textContent = correct ? "✓" : "✕"
|
||||
|
||||
wrongCharacter.classList.remove("hide_character")
|
||||
wrongCharacter.classList.add("show_character")
|
||||
} else if (index == currentQuestion + 1) {
|
||||
question.classList.add("active_question")
|
||||
} else {
|
||||
question.classList.remove("active_question")
|
||||
}
|
||||
})
|
||||
wrongCharacter.classList.remove("hide_character")
|
||||
wrongCharacter.classList.add("show_character")
|
||||
} else if (index == currentQuestion + 1) {
|
||||
question.classList.add("active_question")
|
||||
} else {
|
||||
question.classList.remove("active_question")
|
||||
}
|
||||
})
|
||||
|
||||
currentQuestion++
|
||||
currentQuestion++
|
||||
|
||||
allQuestions.forEach((question, index) => {
|
||||
if (index == currentQuestion) {
|
||||
question.querySelectorAll(".question_button").forEach((button) => (button.tabIndex = 0))
|
||||
}
|
||||
})
|
||||
scoreTally.textContent = `Score: ${score}/${gtc.length}`
|
||||
allQuestions.forEach((question, index) => {
|
||||
if (index == currentQuestion) {
|
||||
question.querySelectorAll(".question_button").forEach((button) => (button.tabIndex = 0))
|
||||
}
|
||||
})
|
||||
scoreTally.textContent = `Score: ${score}/${gtc.length}`
|
||||
|
||||
if (currentQuestion < gtc.length) {
|
||||
if (!isMobile && pointerType === "") setTimeout(() => firstButtons[currentQuestion]?.focus(), 10)
|
||||
} else {
|
||||
scoreTally.tabIndex = 0
|
||||
setTimeout(() => scoreTally.focus(), 10)
|
||||
}
|
||||
if (currentQuestion < gtc.length) {
|
||||
if (!isMobile && pointerType === "") setTimeout(() => firstButtons[currentQuestion]?.focus(), 10)
|
||||
} else {
|
||||
scoreTally.tabIndex = 0
|
||||
setTimeout(() => scoreTally.focus(), 10)
|
||||
}
|
||||
}
|
||||
|
97
src/js/docs_section.js
Normal file
97
src/js/docs_section.js
Normal file
@ -0,0 +1,97 @@
|
||||
const featuresDocu = document.querySelector("#features_docu")
|
||||
|
||||
let customizeContent
|
||||
let docsContent
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") customizeContent = section.content
|
||||
if (section.name == "docs") docsContent = section.content
|
||||
})
|
||||
|
||||
function buildDocs() {
|
||||
console.log("buildDocs")
|
||||
customizeContent.features.forEach((feature) => {
|
||||
const sizes = [
|
||||
[3, 4],
|
||||
[2, 2.5],
|
||||
[1, 1.5],
|
||||
[0.75, 1],
|
||||
[0.5, 1],
|
||||
]
|
||||
const container = document.createElement("div")
|
||||
const h2 = document.createElement("h2")
|
||||
const featureDescriptionWithSpan = feature.description
|
||||
.split("|")
|
||||
.map((l) =>
|
||||
l == "OFF"
|
||||
? `<span class="span_off${
|
||||
!feature.on ? " active_feature" : ""
|
||||
}" onclick="changeFeatureDocs('disable')">[OFF]</span>`
|
||||
: l == "ON"
|
||||
? `<span class="span_on${
|
||||
feature.on ? " active_feature" : ""
|
||||
}" onclick="changeFeatureDocs('enable')">[ON]</span>`
|
||||
: l
|
||||
)
|
||||
.join("")
|
||||
h2.innerHTML = featureDescriptionWithSpan
|
||||
h2.tabIndex = 0
|
||||
h2.dataset.edit = "true"
|
||||
const p = document.createElement("p")
|
||||
p.textContent = `Default: ${feature.on ? "ON" : "OFF"}`
|
||||
const br1 = document.createElement("br")
|
||||
const br2 = document.createElement("br")
|
||||
const br3 = document.createElement("br")
|
||||
container.append(br1, br2, h2, p)
|
||||
sizes.forEach((size) => {
|
||||
const exampleText = document.createElement("p")
|
||||
exampleText.textContent = feature.docsExample
|
||||
exampleText.classList.add("docs_example", `docs_${feature.type}`)
|
||||
exampleText.dataset.feature = feature.feature
|
||||
exampleText.style.fontSize = `${size[0]}rem`
|
||||
exampleText.style.lineHeight = `${size[1]}rem`
|
||||
container.append(exampleText)
|
||||
})
|
||||
featuresDocu.append(container)
|
||||
})
|
||||
const charH2 = document.createElement("h2")
|
||||
charH2.textContent = "Full characterset without alternates. Support for Greek and Cyrillic coming soon."
|
||||
const charset = document.createElement("p")
|
||||
const tunedCharset = websiteData.charset.split("").join(" ")
|
||||
charset.textContent = tunedCharset
|
||||
charset.id = "charset"
|
||||
charset.tabIndex = 0
|
||||
charset.dataset.edit = "true"
|
||||
const br1 = document.createElement("br")
|
||||
const br2 = document.createElement("br")
|
||||
const br3 = document.createElement("br")
|
||||
const br4 = document.createElement("br")
|
||||
const end = document.createElement("p")
|
||||
end.textContent = "End of line."
|
||||
end.tabIndex = 0
|
||||
featuresDocu.append(br1, br2, br3, charH2, br4, charset, end)
|
||||
}
|
||||
|
||||
function changeFeatureDocs(enable) {
|
||||
console.log("changeFeatureDocs")
|
||||
if (enable == "enable") {
|
||||
websiteData.enableFeaturesInDocs = true
|
||||
} else if (enable == "disable") {
|
||||
websiteData.enableFeaturesInDocs = false
|
||||
} else if (enable == "switch") {
|
||||
websiteData.enableFeaturesInDocs = !websiteData.enableFeaturesInDocs
|
||||
}
|
||||
const enabled = websiteData.enableFeaturesInDocs
|
||||
const allExampleTexts = document.querySelectorAll(".docs_example")
|
||||
allExampleTexts.forEach((text) => {
|
||||
text.style.fontFeatureSettings = `"${text.dataset.feature}" ${enabled ? 1 : 0}`
|
||||
})
|
||||
const allSpanOff = document.querySelectorAll(".span_off")
|
||||
const allSpanOn = document.querySelectorAll(".span_on")
|
||||
if (enabled) {
|
||||
allSpanOff.forEach((span) => span.classList.remove("active_feature"))
|
||||
allSpanOn.forEach((span) => span.classList.add("active_feature"))
|
||||
} else {
|
||||
allSpanOff.forEach((span) => span.classList.add("active_feature"))
|
||||
allSpanOn.forEach((span) => span.classList.remove("active_feature"))
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
const featuresDocu = document.querySelector("#features_docu")
|
||||
|
||||
let customizeContent
|
||||
let documentationContent
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") customizeContent = section.content
|
||||
if (section.name == "documentation") documentationContent = section.content
|
||||
})
|
||||
|
||||
function buildDocumentation() {
|
||||
console.log("buildDocumentation")
|
||||
customizeContent.features.forEach((feature) => {
|
||||
const sizes = [
|
||||
[3, 4],
|
||||
[2, 2.5],
|
||||
[1, 1.5],
|
||||
[0.75, 1],
|
||||
[0.5, 1],
|
||||
]
|
||||
const container = document.createElement("div")
|
||||
const h2 = document.createElement("h2")
|
||||
const featureDescriptionWithSpan = feature.description
|
||||
.split("|")
|
||||
.map((l) =>
|
||||
l == "OFF"
|
||||
? `<span class="span_off${
|
||||
!feature.on ? " active_feature" : ""
|
||||
}" onclick="changeFeatureDocumentation('disable')">[OFF]</span>`
|
||||
: l == "ON"
|
||||
? `<span class="span_on${
|
||||
feature.on ? " active_feature" : ""
|
||||
}" onclick="changeFeatureDocumentation('enable')">[ON]</span>`
|
||||
: l
|
||||
)
|
||||
.join("")
|
||||
h2.innerHTML = featureDescriptionWithSpan
|
||||
h2.tabIndex = 0
|
||||
h2.dataset.edit = "true"
|
||||
const p = document.createElement("p")
|
||||
p.textContent = `Default: ${feature.on ? "ON" : "OFF"}`
|
||||
const br1 = document.createElement("br")
|
||||
const br2 = document.createElement("br")
|
||||
const br3 = document.createElement("br")
|
||||
container.append(br1, br2, h2, p)
|
||||
sizes.forEach((size) => {
|
||||
const exampleText = document.createElement("p")
|
||||
exampleText.textContent = feature.documentationExample
|
||||
exampleText.classList.add("documentation_example", `documentation_${feature.type}`)
|
||||
exampleText.dataset.feature = feature.feature
|
||||
exampleText.style.fontSize = `${size[0]}rem`
|
||||
exampleText.style.lineHeight = `${size[1]}rem`
|
||||
container.append(exampleText)
|
||||
})
|
||||
featuresDocu.append(container)
|
||||
})
|
||||
const charH2 = document.createElement("h2")
|
||||
charH2.textContent = "Full characterset without alternates. Support for Greek and Cyrillic coming soon."
|
||||
const charset = document.createElement("p")
|
||||
const tunedCharset = websiteData.charset.split("").join(" ")
|
||||
charset.textContent = tunedCharset
|
||||
charset.id = "charset"
|
||||
charset.tabIndex = 0
|
||||
charset.dataset.edit = "true"
|
||||
const br1 = document.createElement("br")
|
||||
const br2 = document.createElement("br")
|
||||
const br3 = document.createElement("br")
|
||||
const br4 = document.createElement("br")
|
||||
const end = document.createElement("p")
|
||||
end.textContent = "End of line."
|
||||
end.tabIndex = 0
|
||||
featuresDocu.append(br1, br2, br3, charH2, br4, charset, end)
|
||||
}
|
||||
|
||||
function changeFeatureDocumentation(enable) {
|
||||
console.log("changeFeatureDocumentation")
|
||||
if (enable == "enable") {
|
||||
websiteData.enableFeaturesInDocumentation = true
|
||||
} else if (enable == "disable") {
|
||||
websiteData.enableFeaturesInDocumentation = false
|
||||
} else if (enable == "switch") {
|
||||
websiteData.enableFeaturesInDocumentation = !websiteData.enableFeaturesInDocumentation
|
||||
}
|
||||
const enabled = websiteData.enableFeaturesInDocumentation
|
||||
const allExampleTexts = document.querySelectorAll(".documentation_example")
|
||||
allExampleTexts.forEach((text) => {
|
||||
text.style.fontFeatureSettings = `"${text.dataset.feature}" ${enabled ? 1 : 0}`
|
||||
})
|
||||
const allSpanOff = document.querySelectorAll(".span_off")
|
||||
const allSpanOn = document.querySelectorAll(".span_on")
|
||||
if (enabled) {
|
||||
allSpanOff.forEach((span) => span.classList.remove("active_feature"))
|
||||
allSpanOn.forEach((span) => span.classList.add("active_feature"))
|
||||
} else {
|
||||
allSpanOff.forEach((span) => span.classList.add("active_feature"))
|
||||
allSpanOn.forEach((span) => span.classList.remove("active_feature"))
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
document.onvisibilitychange = () => {
|
||||
// dynamicFavicon()
|
||||
if (document.visibilityState === "visible") changeFavicon(true)
|
||||
else changeFavicon(false)
|
||||
// dynamicFavicon()
|
||||
if (document.visibilityState === "visible") changeFavicon(true)
|
||||
else changeFavicon(false)
|
||||
}
|
||||
|
||||
let faviconIntervalID
|
||||
@ -32,15 +32,15 @@ let faviconCounter = 0
|
||||
// }
|
||||
|
||||
function changeFavicon(hasFocus) {
|
||||
console.log("changeFavicon")
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
console.log("changeFavicon")
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = hasFocus ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = hasFocus ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
}
|
||||
|
@ -8,187 +8,187 @@ const alternatesContainer = document.querySelector("#alternates_container")
|
||||
const featuresContainer = document.querySelector("#features_container")
|
||||
|
||||
function buildExample() {
|
||||
console.log("buildExample")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
fontsFieldset.innerHTML = ""
|
||||
section.content.fonts.forEach((font, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "font"
|
||||
input.id = font.id
|
||||
input.classList.add("example_font")
|
||||
input.value = font.cssName
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = font.name
|
||||
label.setAttribute("for", font.id)
|
||||
div.append(input, label)
|
||||
fontsFieldset.append(div)
|
||||
})
|
||||
|
||||
exampleFieldset.innerHTML = ""
|
||||
section.content.languages.forEach((language, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "language"
|
||||
input.id = language.languageName
|
||||
input.classList.add("example_language")
|
||||
input.value = language.languageName
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = language.languageName
|
||||
label.setAttribute("for", language.languageName)
|
||||
div.append(input, label)
|
||||
exampleFieldset.append(div)
|
||||
})
|
||||
|
||||
weightFieldset.innerHTML = ""
|
||||
section.content.weights.forEach((weight, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "weight"
|
||||
input.id = `weight_${weight}`
|
||||
input.classList.add("example_weight")
|
||||
input.value = weight
|
||||
if (index == 6) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = weight
|
||||
label.setAttribute("for", `weight_${weight}`)
|
||||
div.append(input, label)
|
||||
weightFieldset.append(div)
|
||||
})
|
||||
|
||||
featuresContainer.innerHTML = ""
|
||||
alternatesContainer.innerHTML = ""
|
||||
section.content.features.forEach((feature, index) => {
|
||||
const fieldset = document.createElement("fieldset")
|
||||
const duo = [0, 0]
|
||||
const p = document.createElement("p")
|
||||
p.textContent = feature.label
|
||||
p.id = `alt_${feature.name}`
|
||||
fieldset.append(p)
|
||||
duo.forEach((_, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = feature.name
|
||||
input.id = `${feature.name}${index}`
|
||||
input.value = `'${feature.feature}' ${index == 0 ? "off" : "on"}`
|
||||
if (!feature.on && index == 0) input.setAttribute("checked", "true")
|
||||
if (feature.on && index == 1) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = index == 0 ? "OFF" : "ON"
|
||||
label.setAttribute("for", `${feature.name}${index}`)
|
||||
div.append(input, label)
|
||||
fieldset.append(div)
|
||||
console.log("buildExample")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
fontsFieldset.innerHTML = ""
|
||||
section.content.fonts.forEach((font, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "font"
|
||||
input.id = font.id
|
||||
input.classList.add("example_font")
|
||||
input.value = font.cssName
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = font.name
|
||||
label.setAttribute("for", font.id)
|
||||
div.append(input, label)
|
||||
fontsFieldset.append(div)
|
||||
})
|
||||
if (feature.type == "feature") featuresContainer.append(fieldset)
|
||||
else alternatesContainer.append(fieldset)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
updateExamples(null, exampleForm)
|
||||
updateExampleSettings(null, exampleSettingsForm, true)
|
||||
exampleFieldset.innerHTML = ""
|
||||
section.content.languages.forEach((language, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "language"
|
||||
input.id = language.languageName
|
||||
input.classList.add("example_language")
|
||||
input.value = language.languageName
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = language.languageName
|
||||
label.setAttribute("for", language.languageName)
|
||||
div.append(input, label)
|
||||
exampleFieldset.append(div)
|
||||
})
|
||||
|
||||
weightFieldset.innerHTML = ""
|
||||
section.content.weights.forEach((weight, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "weight"
|
||||
input.id = `weight_${weight}`
|
||||
input.classList.add("example_weight")
|
||||
input.value = weight
|
||||
if (index == 6) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.textContent = weight
|
||||
label.setAttribute("for", `weight_${weight}`)
|
||||
div.append(input, label)
|
||||
weightFieldset.append(div)
|
||||
})
|
||||
|
||||
featuresContainer.innerHTML = ""
|
||||
alternatesContainer.innerHTML = ""
|
||||
section.content.features.forEach((feature, index) => {
|
||||
const fieldset = document.createElement("fieldset")
|
||||
const duo = [0, 0]
|
||||
const p = document.createElement("p")
|
||||
p.textContent = feature.label
|
||||
p.id = `alt_${feature.name}`
|
||||
fieldset.append(p)
|
||||
duo.forEach((_, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = feature.name
|
||||
input.id = `${feature.name}${index}`
|
||||
input.value = `'${feature.feature}' ${index == 0 ? "off" : "on"}`
|
||||
if (!feature.on && index == 0) input.setAttribute("checked", "true")
|
||||
if (feature.on && index == 1) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = index == 0 ? "OFF" : "ON"
|
||||
label.setAttribute("for", `${feature.name}${index}`)
|
||||
div.append(input, label)
|
||||
fieldset.append(div)
|
||||
})
|
||||
if (feature.type == "feature") featuresContainer.append(fieldset)
|
||||
else alternatesContainer.append(fieldset)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
updateExamples(null, exampleForm)
|
||||
updateExampleSettings(null, exampleSettingsForm, true)
|
||||
}
|
||||
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
function updateExamples(event, form) {
|
||||
console.log("updateExamples")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
console.log("updateExamples")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
section.content.languages.forEach((language, index) => {
|
||||
if (language.languageName == output) {
|
||||
codeExample.textContent = language.codeExample
|
||||
let nums = Array.from(new Array(1000), (x, i) => i + 1).join("\n")
|
||||
codeExample.setAttribute("data-before", nums)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
section.content.languages.forEach((language, index) => {
|
||||
if (language.languageName == output) {
|
||||
codeExample.textContent = language.codeExample
|
||||
let nums = Array.from(new Array(1000), (x, i) => i + 1).join("\n")
|
||||
codeExample.setAttribute("data-before", nums)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function updateFont(event, form) {
|
||||
console.log("updateFont")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
codeExample.style.fontFamily = output
|
||||
console.log("updateFont")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
codeExample.style.fontFamily = output
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function updateWeight(event, form) {
|
||||
console.log("updateWeight")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = +entry[1]
|
||||
}
|
||||
console.log("updateWeight")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = +entry[1]
|
||||
}
|
||||
|
||||
fontDownloadSettings.weight = output
|
||||
websiteData.weight = output
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
downloadButton.textContent = areObjectsIdentical(fontDownloadSettings, fontDownloadSettingsDefault)
|
||||
? "Download default CommitMono"
|
||||
: "Download custom CommitMono"
|
||||
fontDownloadSettings.weight = output
|
||||
websiteData.weight = output
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
downloadButton.textContent = areObjectsIdentical(fontDownloadSettings, fontDownloadSettingsDefault)
|
||||
? "Download default CommitMono"
|
||||
: "Download custom CommitMono"
|
||||
|
||||
console.log(fontDownloadSettings)
|
||||
console.log(fontDownloadSettings)
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function updateExampleSettings(event, form, isDefault) {
|
||||
console.log("updateExampleSettings")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
function updateDownloadSettings(type, feature) {
|
||||
const key = feature.split("' ")[0].slice(1)
|
||||
const value = feature.split("' ")[1] == "on"
|
||||
fontDownloadSettings[type][key] = value
|
||||
if (isDefault) fontDownloadSettingsDefault[type][key] = value
|
||||
}
|
||||
for (const entry of data) {
|
||||
output += `${entry[1]}, `
|
||||
if (entry[1].includes("cv")) updateDownloadSettings("alternates", entry[1])
|
||||
if (entry[1].includes("ss")) updateDownloadSettings("features", entry[1])
|
||||
console.log("updateExampleSettings")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
function updateDownloadSettings(type, feature) {
|
||||
const key = feature.split("' ")[0].slice(1)
|
||||
const value = feature.split("' ")[1] == "on"
|
||||
fontDownloadSettings[type][key] = value
|
||||
if (isDefault) fontDownloadSettingsDefault[type][key] = value
|
||||
}
|
||||
for (const entry of data) {
|
||||
output += `${entry[1]}, `
|
||||
if (entry[1].includes("cv")) updateDownloadSettings("alternates", entry[1])
|
||||
if (entry[1].includes("ss")) updateDownloadSettings("features", entry[1])
|
||||
|
||||
const label = document.querySelector(`#alt_${entry[0]}`)
|
||||
if (label) label.style.fontFeatureSettings = entry[1]
|
||||
}
|
||||
console.log(fontDownloadSettings)
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
codeExample.style.fontFeatureSettings = output.slice(0, -2)
|
||||
const label = document.querySelector(`#alt_${entry[0]}`)
|
||||
if (label) label.style.fontFeatureSettings = entry[1]
|
||||
}
|
||||
console.log(fontDownloadSettings)
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
codeExample.style.fontFeatureSettings = output.slice(0, -2)
|
||||
|
||||
downloadButton.textContent = areObjectsIdentical(fontDownloadSettings, fontDownloadSettingsDefault)
|
||||
? "Download default CommitMono"
|
||||
: "Download custom CommitMono"
|
||||
downloadButton.textContent = areObjectsIdentical(fontDownloadSettings, fontDownloadSettingsDefault)
|
||||
? "Download default CommitMono"
|
||||
: "Download custom CommitMono"
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function areObjectsIdentical(obj1, obj2) {
|
||||
return JSON.stringify(obj1) === JSON.stringify(obj2)
|
||||
return JSON.stringify(obj1) === JSON.stringify(obj2)
|
||||
}
|
||||
|
@ -1,53 +1,53 @@
|
||||
const familiarContainer = document.querySelector("#familiar_container")
|
||||
|
||||
function buildFamiliar() {
|
||||
console.log("buildFamiliar")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "familiar") {
|
||||
familiarContainer.innerHTML = ""
|
||||
section.content.timeline.forEach((example, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.style.display = index != 0 ? "none" : "block"
|
||||
div.id = example.name
|
||||
div.dataset.name = example.name
|
||||
const svgContainer = document.createElement("div")
|
||||
svgContainer.innerHTML = section.content.svgs[example.name]
|
||||
svgContainer.tabIndex = 0
|
||||
svgContainer.classList.add("svg_container")
|
||||
const img = document.createElement("img")
|
||||
img.src = `/src/img/familiar/${example.src}`
|
||||
const p = document.createElement("p")
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
example.description.forEach((description) => (p.textContent += description + " "))
|
||||
div.append(p)
|
||||
const br = document.createElement("br")
|
||||
div.append(br, svgContainer)
|
||||
familiarContainer.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log("buildFamiliar")
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "familiar") {
|
||||
familiarContainer.innerHTML = ""
|
||||
section.content.timeline.forEach((example, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.style.display = index != 0 ? "none" : "block"
|
||||
div.id = example.name
|
||||
div.dataset.name = example.name
|
||||
const svgContainer = document.createElement("div")
|
||||
svgContainer.innerHTML = section.content.svgs[example.name]
|
||||
svgContainer.tabIndex = 0
|
||||
svgContainer.classList.add("svg_container")
|
||||
const img = document.createElement("img")
|
||||
img.src = `/src/img/familiar/${example.src}`
|
||||
const p = document.createElement("p")
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
example.description.forEach((description) => (p.textContent += description + " "))
|
||||
div.append(p)
|
||||
const br = document.createElement("br")
|
||||
div.append(br, svgContainer)
|
||||
familiarContainer.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateFamiliar(event, form) {
|
||||
console.log("updateFamiliar")
|
||||
buildFamiliar()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = entry[1]
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "familiar") {
|
||||
section.content.timeline.forEach((example) => {
|
||||
const exampleContainer = familiarContainer.querySelector(`#${example.name}`)
|
||||
if (exampleContainer.dataset.name == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
console.log("updateFamiliar")
|
||||
buildFamiliar()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = entry[1]
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "familiar") {
|
||||
section.content.timeline.forEach((example) => {
|
||||
const exampleContainer = familiarContainer.querySelector(`#${example.name}`)
|
||||
if (exampleContainer.dataset.name == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
function updateIntelligent(event, form) {
|
||||
console.log("updateIntelligent")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
const examples = ["original", "smart_kerning", "before", "after"]
|
||||
examples.forEach((example) => {
|
||||
const exampleContainer = document.querySelector(`#${example}`)
|
||||
if (exampleContainer.id == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
console.log("updateIntelligent")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
const examples = ["original", "smart_kerning", "before", "after"]
|
||||
examples.forEach((example) => {
|
||||
const exampleContainer = document.querySelector(`#${example}`)
|
||||
if (exampleContainer.id == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
|
675
src/js/nav.js
675
src/js/nav.js
@ -13,428 +13,431 @@ let rem = +document.documentElement.style.fontSize.split("px")[0]
|
||||
const downloadButton = document.querySelector("#download")
|
||||
|
||||
function buildNav() {
|
||||
console.log("buildNav")
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "nav"
|
||||
input.id = section.name
|
||||
input.classList.add("nav_section_input")
|
||||
input.value = `section_${index + 1}`
|
||||
input.tabIndex = 0
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.for = section.name
|
||||
label.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
label.classList.add("nav_element")
|
||||
label.dataset.sectionIndex = index + 1
|
||||
label.setAttribute("for", section.name)
|
||||
div.append(input, label)
|
||||
navForm.append(div)
|
||||
})
|
||||
console.log("buildNav")
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "nav"
|
||||
input.id = section.name
|
||||
input.classList.add("nav_section_input")
|
||||
input.value = `section_${index + 1}`
|
||||
input.tabIndex = 0
|
||||
if (index == 0) {
|
||||
input.setAttribute("checked", "true")
|
||||
}
|
||||
const label = document.createElement("label")
|
||||
label.for = section.name
|
||||
label.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
label.classList.add("nav_element")
|
||||
label.dataset.sectionIndex = index + 1
|
||||
label.setAttribute("for", section.name)
|
||||
div.append(input, label)
|
||||
navForm.append(div)
|
||||
})
|
||||
}
|
||||
|
||||
function updateNav(event, form) {
|
||||
console.log("updateNav")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
sectionNavigation(output.split("section_")[1] - 1)
|
||||
console.log("updateNav")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
sectionNavigation(output.split("section_")[1] - 1)
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function pageAnimation() {
|
||||
console.log("pageAnimation")
|
||||
const element = document.querySelector("#page_animation")
|
||||
element.classList.remove("page_animation")
|
||||
setTimeout(() => element.classList.add("page_animation"), 10)
|
||||
console.log("pageAnimation")
|
||||
const element = document.querySelector("#page_animation")
|
||||
element.classList.remove("page_animation")
|
||||
setTimeout(() => element.classList.add("page_animation"), 10)
|
||||
}
|
||||
|
||||
let currentSection = 1
|
||||
let insideTextField = false
|
||||
function enterTextField() {
|
||||
console.log("enterTextField")
|
||||
active = document.activeElement
|
||||
setTimeout(() => {
|
||||
active.setAttribute("contenteditable", "true")
|
||||
active.blur()
|
||||
active.focus()
|
||||
}, 40)
|
||||
insideTextField = true
|
||||
console.log("enterTextField")
|
||||
active = document.activeElement
|
||||
setTimeout(() => {
|
||||
active.setAttribute("contenteditable", "true")
|
||||
active.blur()
|
||||
active.focus()
|
||||
}, 40)
|
||||
insideTextField = true
|
||||
}
|
||||
function exitTextField() {
|
||||
console.log("exitTextField")
|
||||
document.activeElement.setAttribute("contenteditable", "false")
|
||||
insideTextField = false
|
||||
console.log("exitTextField")
|
||||
document.activeElement.setAttribute("contenteditable", "false")
|
||||
insideTextField = false
|
||||
}
|
||||
|
||||
let timesClicked = 0
|
||||
function onClick(e) {
|
||||
if (e.pointerType !== "" && !isMobile) {
|
||||
focusUsingTab = false
|
||||
timesClicked++
|
||||
if (timesClicked == 10) {
|
||||
document.querySelector("#keyboard_container").classList.add("use_keyboard_animation")
|
||||
showHideChangeSettings("Use keyboard to navigate!", 2400, true)
|
||||
}
|
||||
}
|
||||
if (e.pointerType !== "" && !isMobile) {
|
||||
focusUsingTab = false
|
||||
timesClicked++
|
||||
if (timesClicked == 10) {
|
||||
document.querySelector("#keyboard_container").classList.add("use_keyboard_animation")
|
||||
showHideChangeSettings("Use keyboard to navigate!", 2400, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
document.addEventListener("click", onClick)
|
||||
|
||||
const keys = document.querySelectorAll(".key")
|
||||
keys.forEach((key) => {
|
||||
key.addEventListener("click", () => {
|
||||
if (key.dataset.noclick != "true") {
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
}
|
||||
})
|
||||
key.addEventListener("click", () => {
|
||||
if (key.dataset.noclick != "true") {
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let changeSettingTimeoutID
|
||||
let focusUsingTab = false
|
||||
function keyDown(e) {
|
||||
focusUsingTab = true
|
||||
if (e.code == "Enter" && document.activeElement.dataset.edit == "true" && !insideTextField) enterTextField()
|
||||
focusUsingTab = true
|
||||
if (e.code == "Enter" && document.activeElement.dataset.edit == "true" && !insideTextField) enterTextField()
|
||||
|
||||
if (!insideTextField || e.code == "Enter") {
|
||||
const activeKey = !e.shiftKey
|
||||
? document.querySelector(`.key[data-key-code="${e.code}"]`)
|
||||
: document.querySelector(`.key[data-key-code="Shift${e.code}"]`)
|
||||
activeKey?.classList.add("active_key")
|
||||
if (!insideTextField || e.code == "Enter") {
|
||||
const activeKey = !e.shiftKey
|
||||
? document.querySelector(`.key[data-key-code="${e.code}"]`)
|
||||
: document.querySelector(`.key[data-key-code="Shift${e.code}"]`)
|
||||
activeKey?.classList.add("active_key")
|
||||
|
||||
if (e.code.includes("Digit")) {
|
||||
const digitNumber = e.code.split("Digit")[1] - 1
|
||||
sectionNavigation(digitNumber == -1 ? 9 : digitNumber)
|
||||
}
|
||||
if (e.code.includes("Digit")) {
|
||||
const digitNumber = e.code.split("Digit")[1] - 1
|
||||
sectionNavigation(digitNumber == -1 ? 9 : digitNumber)
|
||||
}
|
||||
|
||||
if (e.code == "KeyO") {
|
||||
changeFeatureDocumentation("switch")
|
||||
}
|
||||
if (e.code == "KeyO") {
|
||||
changeFeatureDocs("switch")
|
||||
}
|
||||
|
||||
// push page
|
||||
if (
|
||||
(e.code == "KeyW" ||
|
||||
e.code == "KeyA" ||
|
||||
e.code == "KeyS" ||
|
||||
e.code == "KeyD" ||
|
||||
e.code == "KeyR" ||
|
||||
e.code == "Minus" ||
|
||||
e.code == "Slash") &&
|
||||
!e.ctrlKey &&
|
||||
!e.metaKey
|
||||
) {
|
||||
pushPage(e.code)
|
||||
}
|
||||
// push page
|
||||
if (
|
||||
(e.code == "KeyW" ||
|
||||
e.code == "KeyA" ||
|
||||
e.code == "KeyS" ||
|
||||
e.code == "KeyD" ||
|
||||
e.code == "KeyR" ||
|
||||
e.code == "Minus" ||
|
||||
e.code == "Slash") &&
|
||||
!e.ctrlKey &&
|
||||
!e.metaKey
|
||||
) {
|
||||
pushPage(e.code)
|
||||
}
|
||||
|
||||
if (e.code == "KeyH") {
|
||||
document.querySelector("#keyboard_section").classList.toggle("hidden")
|
||||
}
|
||||
if (e.code == "KeyH") {
|
||||
document.querySelector("#keyboard_section").classList.toggle("hidden")
|
||||
}
|
||||
|
||||
if (e.code == "KeyB" || e.code == "KeyL") {
|
||||
if (e.code == "KeyB") websiteData.weight = websiteData.weight == 700 ? 700 : websiteData.weight + 25
|
||||
if (e.code == "KeyL") websiteData.weight = websiteData.weight == 300 ? 300 : websiteData.weight - 25
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
showHideChangeSettings(`Weight: ${websiteData.weight}. Def: 450, Min: 300, Max: 700.`)
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
updateWeight(null, weightForm)
|
||||
}
|
||||
if (e.code == "KeyB" || e.code == "KeyL") {
|
||||
if (e.code == "KeyB") websiteData.weight = websiteData.weight == 700 ? 700 : websiteData.weight + 25
|
||||
if (e.code == "KeyL") websiteData.weight = websiteData.weight == 300 ? 300 : websiteData.weight - 25
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
showHideChangeSettings(`Weight: ${websiteData.weight}. Def: 450, Min: 300, Max: 700.`)
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
updateWeight(null, weightForm)
|
||||
}
|
||||
|
||||
if (e.code == "KeyI") {
|
||||
websiteData.italic = !websiteData.italic
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
showHideChangeSettings(`Italic: ${websiteData.italic}.`)
|
||||
}
|
||||
if (e.code == "KeyI") {
|
||||
websiteData.italic = !websiteData.italic
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}, "ital" ${
|
||||
websiteData.italic ? "1" : "0"
|
||||
}`
|
||||
showHideChangeSettings(`Italic: ${websiteData.italic}.`)
|
||||
}
|
||||
|
||||
if (e.code == "KeyM") {
|
||||
if (websiteData.invert) {
|
||||
setCssVar(["--bg", "#aaa"])
|
||||
setCssVar(["--text", "#111"])
|
||||
} else {
|
||||
setCssVar(["--bg", "#111"])
|
||||
setCssVar(["--text", "#aaa"])
|
||||
}
|
||||
updateCode(null, codeForm)
|
||||
websiteData.invert = !websiteData.invert
|
||||
}
|
||||
} else if (e.code == "Escape" && insideTextField) {
|
||||
console.log(insideTextField)
|
||||
document.querySelector(".key_code_Escape")?.classList.add("pressed_key")
|
||||
}
|
||||
if (e.code == "KeyM") {
|
||||
if (websiteData.invert) {
|
||||
setCssVar(["--bg", "#aaa"])
|
||||
setCssVar(["--text", "#111"])
|
||||
} else {
|
||||
setCssVar(["--bg", "#111"])
|
||||
setCssVar(["--text", "#aaa"])
|
||||
}
|
||||
updateCode(null, codeForm)
|
||||
websiteData.invert = !websiteData.invert
|
||||
}
|
||||
} else if (e.code == "Escape" && insideTextField) {
|
||||
console.log(insideTextField)
|
||||
document.querySelector(".key_code_Escape")?.classList.add("pressed_key")
|
||||
}
|
||||
|
||||
if (e.code == "Escape") exitTextField()
|
||||
if (e.code == "Escape") exitTextField()
|
||||
|
||||
checkTutorialKeys(e)
|
||||
checkTutorialKeys(e)
|
||||
}
|
||||
function keyUp(e) {
|
||||
const activeKey = document.querySelectorAll(".active_key")
|
||||
activeKey?.forEach((key) => key.classList.remove("active_key"))
|
||||
const activeKey = document.querySelectorAll(".active_key")
|
||||
activeKey?.forEach((key) => key.classList.remove("active_key"))
|
||||
|
||||
if (e.code == "Tab" && document.activeElement.id.includes("block_tab")) {
|
||||
console.log("active nav section then tab")
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
if (e.code == "Tab" && document.activeElement.id.includes("block_tab")) {
|
||||
console.log("active nav section then tab")
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
document.addEventListener("keydown", keyDown)
|
||||
document.addEventListener("keyup", keyUp)
|
||||
|
||||
function pushPage(keyCode) {
|
||||
console.log("push page", keyCode)
|
||||
const x = websiteData.pushPage.coordinates.x
|
||||
const y = websiteData.pushPage.coordinates.y
|
||||
const scale = websiteData.pushPage.scale
|
||||
const dist = websiteData.pushPage.distance
|
||||
console.log("push page", keyCode)
|
||||
const x = websiteData.pushPage.coordinates.x
|
||||
const y = websiteData.pushPage.coordinates.y
|
||||
const scale = websiteData.pushPage.scale
|
||||
const dist = websiteData.pushPage.distance
|
||||
|
||||
// move left
|
||||
if (keyCode == "KeyW") {
|
||||
main.style.transform = `translate(${x}px, ${y + dist}px)`
|
||||
websiteData.pushPage.coordinates.y += dist
|
||||
}
|
||||
// move left
|
||||
if (keyCode == "KeyW") {
|
||||
main.style.transform = `translate(${x}px, ${y + dist}px)`
|
||||
websiteData.pushPage.coordinates.y += dist
|
||||
}
|
||||
|
||||
// move left
|
||||
else if (keyCode == "KeyA") {
|
||||
main.style.transform = `translate(${x + dist}px, ${y}px)`
|
||||
websiteData.pushPage.coordinates.x += dist
|
||||
}
|
||||
// move left
|
||||
else if (keyCode == "KeyA") {
|
||||
main.style.transform = `translate(${x + dist}px, ${y}px)`
|
||||
websiteData.pushPage.coordinates.x += dist
|
||||
}
|
||||
|
||||
// move down
|
||||
else if (keyCode == "KeyS") {
|
||||
main.style.transform = `translate(${x}px, ${y - dist}px)`
|
||||
websiteData.pushPage.coordinates.y -= dist
|
||||
}
|
||||
// move down
|
||||
else if (keyCode == "KeyS") {
|
||||
main.style.transform = `translate(${x}px, ${y - dist}px)`
|
||||
websiteData.pushPage.coordinates.y -= dist
|
||||
}
|
||||
|
||||
// move right
|
||||
else if (keyCode == "KeyD") {
|
||||
main.style.transform = `translate(${x - dist}px, ${y}px)`
|
||||
websiteData.pushPage.coordinates.x -= dist
|
||||
}
|
||||
// move right
|
||||
else if (keyCode == "KeyD") {
|
||||
main.style.transform = `translate(${x - dist}px, ${y}px)`
|
||||
websiteData.pushPage.coordinates.x -= dist
|
||||
}
|
||||
|
||||
// zoom in ("Minus" is the plus key, very confusing)
|
||||
else if (keyCode == "Minus") {
|
||||
rem = (+rem * 0.75 + 1) / 0.75
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
showHideChangeSettings(`Base font size: ${rem * 0.75}px`)
|
||||
}
|
||||
// zoom in ("Minus" is the plus key, very confusing)
|
||||
else if (keyCode == "Minus") {
|
||||
rem = (+rem * 0.75 + 1) / 0.75
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
showHideChangeSettings(`Base font size: ${rem * 0.75}px`)
|
||||
}
|
||||
|
||||
// zoom out
|
||||
else if (keyCode == "Slash") {
|
||||
rem = (+rem * 0.75 - 1) / 0.75
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
showHideChangeSettings(`Base font size: ${rem * 0.75}px`)
|
||||
}
|
||||
// zoom out
|
||||
else if (keyCode == "Slash") {
|
||||
rem = (+rem * 0.75 - 1) / 0.75
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
showHideChangeSettings(`Base font size: ${rem * 0.75}px`)
|
||||
}
|
||||
|
||||
// reset transforms
|
||||
else if (keyCode == "KeyR") {
|
||||
main.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
document.querySelector("#canvas").style.transform = "scale(1)"
|
||||
rem = 16
|
||||
document.documentElement.style.fontSize = "16px"
|
||||
websiteData.weight = 450
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" 450`
|
||||
document.querySelector(
|
||||
"#download"
|
||||
).textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
if (typeof updateCodeFont === "function") updateCodeFont()
|
||||
if (typeof updateWaterfall === "function") updateWaterfall()
|
||||
if (typeof buildExample === "function") buildExample()
|
||||
if (typeof updateWeight === "function") updateWeight(null, weightForm)
|
||||
}
|
||||
// reset transforms
|
||||
else if (keyCode == "KeyR") {
|
||||
main.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
document.querySelector("#canvas").style.transform = "scale(1)"
|
||||
rem = 16
|
||||
document.documentElement.style.fontSize = "16px"
|
||||
websiteData.weight = 450
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" 450`
|
||||
document.querySelector(
|
||||
"#download"
|
||||
).textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
if (typeof updateCodeFont === "function") updateCodeFont()
|
||||
if (typeof updateWaterfall === "function") updateWaterfall()
|
||||
if (typeof buildExample === "function") buildExample()
|
||||
if (typeof updateWeight === "function") updateWeight(null, weightForm)
|
||||
}
|
||||
}
|
||||
|
||||
let isSafari = 0
|
||||
let active // saves what DOM element is currently active
|
||||
let focusTimeOutID // to be able to use clearTimeout()
|
||||
function onFocusIn(e) {
|
||||
// console.log("focusin", document.activeElement)
|
||||
// console.log("focusin", document.activeElement)
|
||||
|
||||
// new focus: exit text field
|
||||
if (document.activeElement != active) exitTextField()
|
||||
// new focus: exit text field
|
||||
if (document.activeElement != active) exitTextField()
|
||||
|
||||
const prevActive = active
|
||||
const prevActive = active
|
||||
|
||||
// save current focused element
|
||||
active = document.activeElement
|
||||
// save current focused element
|
||||
active = document.activeElement
|
||||
|
||||
if (focusUsingTab) {
|
||||
if (prevActive?.id == "navigate_description" && active.id == "tutorial" && isSafari == 0) {
|
||||
console.log("safari")
|
||||
isSafari = 1
|
||||
document.querySelector("#safari").classList.add("safari_visible")
|
||||
}
|
||||
if (focusUsingTab) {
|
||||
if (prevActive?.id == "navigate_description" && active.id == "tutorial" && isSafari == 0) {
|
||||
console.log("safari")
|
||||
isSafari = 1
|
||||
document.querySelector("#safari").classList.add("safari_visible")
|
||||
}
|
||||
|
||||
if (active.id == "focus_check") {
|
||||
console.log("not safari")
|
||||
isSafari = -1
|
||||
if (prevActive.id == "navigate_description") {
|
||||
document.querySelector("#tutorial").focus()
|
||||
}
|
||||
if (prevActive.id == "tutorial") {
|
||||
document.querySelector("#navigate_description").focus()
|
||||
}
|
||||
document.querySelector("#focus_check")?.remove()
|
||||
}
|
||||
}
|
||||
// // when current focused element is blurred, start a timer of 100ms.
|
||||
// active.addEventListener("blur", onBlurIn)
|
||||
|
||||
// // clear timeout when a new element is focused
|
||||
// clearTimeout(focusTimeOutID)
|
||||
// focusTimeOutID = null
|
||||
|
||||
if (active.id.includes("block_tab")) {
|
||||
console.log("BLOCK TAB")
|
||||
if (prevActive.className.includes("question_button")) {
|
||||
prevActive.parentElement.querySelector(".question_button").focus()
|
||||
} else {
|
||||
prevActive.focus()
|
||||
// const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
// checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
|
||||
// if focus using tab, scroll page, if focus reaches bottom or top
|
||||
if (focusUsingTab) {
|
||||
const bounds = active.getBoundingClientRect()
|
||||
const paddingOffsetBottom = 200
|
||||
if (bounds.top > window.innerHeight - paddingOffsetBottom) {
|
||||
const numberOfMoves = Math.floor(
|
||||
(bounds.top - (window.innerHeight - paddingOffsetBottom)) / websiteData.pushPage.distance
|
||||
)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyS")
|
||||
}
|
||||
}
|
||||
const paddingOffsetTop = 24
|
||||
if (!document.activeElement.className.includes("nav")) {
|
||||
if (bounds.top < paddingOffsetTop) {
|
||||
const numberOfMoves = Math.ceil(
|
||||
Math.abs(bounds.top - paddingOffsetTop - 32) / websiteData.pushPage.distance
|
||||
)
|
||||
console.log("num of moves:", numberOfMoves, "bounds.top:", bounds.top)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyW")
|
||||
if (active.id == "focus_check") {
|
||||
console.log("not safari")
|
||||
isSafari = -1
|
||||
if (prevActive.id == "navigate_description") {
|
||||
document.querySelector("#tutorial").focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prevActive.id == "tutorial") {
|
||||
document.querySelector("#navigate_description").focus()
|
||||
}
|
||||
document.querySelector("#focus_check")?.remove()
|
||||
}
|
||||
}
|
||||
// // when current focused element is blurred, start a timer of 100ms.
|
||||
// active.addEventListener("blur", onBlurIn)
|
||||
|
||||
// // clear timeout when a new element is focused
|
||||
// clearTimeout(focusTimeOutID)
|
||||
// focusTimeOutID = null
|
||||
|
||||
if (active.id.includes("block_tab")) {
|
||||
console.log("BLOCK TAB")
|
||||
if (prevActive.className.includes("question_button")) {
|
||||
prevActive.parentElement.querySelector(".question_button").focus()
|
||||
} else {
|
||||
prevActive.focus()
|
||||
// const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
// checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
|
||||
// if focus using tab, scroll page, if focus reaches bottom or top
|
||||
if (focusUsingTab) {
|
||||
const bounds = active.getBoundingClientRect()
|
||||
const paddingOffsetBottom = 200
|
||||
if (bounds.top > window.innerHeight - paddingOffsetBottom) {
|
||||
const numberOfMoves = Math.floor(
|
||||
(bounds.top - (window.innerHeight - paddingOffsetBottom)) / websiteData.pushPage.distance
|
||||
)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyS")
|
||||
}
|
||||
}
|
||||
const paddingOffsetTop = 24
|
||||
if (!document.activeElement.className.includes("nav")) {
|
||||
if (bounds.top < paddingOffsetTop) {
|
||||
const numberOfMoves = Math.ceil(
|
||||
Math.abs(bounds.top - paddingOffsetTop - 32) / websiteData.pushPage.distance
|
||||
)
|
||||
console.log("num of moves:", numberOfMoves, "bounds.top:", bounds.top)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyW")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
document.addEventListener("focusin", onFocusIn)
|
||||
|
||||
let prevHasFocus = true
|
||||
function checkDocumentFocus() {
|
||||
if (!isMobile) {
|
||||
if (prevHasFocus != document.hasFocus()) {
|
||||
changedFocus(document.hasFocus())
|
||||
}
|
||||
prevHasFocus = document.hasFocus()
|
||||
}
|
||||
if (!isMobile) {
|
||||
if (prevHasFocus != document.hasFocus()) {
|
||||
changedFocus(document.hasFocus())
|
||||
}
|
||||
prevHasFocus = document.hasFocus()
|
||||
}
|
||||
}
|
||||
|
||||
function changedFocus(hasFocus) {
|
||||
if (hasFocus && active) active.focus()
|
||||
changeFavicon(hasFocus)
|
||||
hasFocus ? contentRoot.classList.remove("faded") : contentRoot.classList.add("faded")
|
||||
clickFocus.style.visibility = hasFocus ? "hidden" : "visible"
|
||||
// updateCode(null, codeForm)
|
||||
if (hasFocus && active) active.focus()
|
||||
changeFavicon(hasFocus)
|
||||
hasFocus ? contentRoot.classList.remove("faded") : contentRoot.classList.add("faded")
|
||||
clickFocus.style.visibility = hasFocus ? "hidden" : "visible"
|
||||
// updateCode(null, codeForm)
|
||||
}
|
||||
|
||||
function onBlurIn(e) {
|
||||
// remove event listener from so they don't stack
|
||||
e.target.removeEventListener("blur", onBlurIn)
|
||||
// remove event listener from so they don't stack
|
||||
e.target.removeEventListener("blur", onBlurIn)
|
||||
|
||||
// if this timer runs out before a new element is focused, refocus same element
|
||||
if (!isMobile) focusTimeOutID = setTimeout(() => active.focus(), 100)
|
||||
// if this timer runs out before a new element is focused, refocus same element
|
||||
if (!isMobile) focusTimeOutID = setTimeout(() => active.focus(), 100)
|
||||
}
|
||||
|
||||
let tutorialFinished = false
|
||||
function checkTutorialKeys(e) {
|
||||
if (!tutorialFinished) {
|
||||
websiteData.tutorial.forEach((key) => {
|
||||
if (e.code == key) {
|
||||
if (e.code.includes("Arrow")) {
|
||||
if (document.activeElement.nodeName == "INPUT") {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode?.classList.add("pressed_key")
|
||||
}
|
||||
} else if (e.code == "Enter") {
|
||||
if (document.activeElement.dataset.edit == "true") {
|
||||
document.querySelector(".key_code_Enter")?.classList.add("pressed_key")
|
||||
}
|
||||
} else if (e.code != "Escape") {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode?.classList.add("pressed_key")
|
||||
if (!tutorialFinished) {
|
||||
websiteData.tutorial.forEach((key) => {
|
||||
if (e.code == key && e.code != "Tab") {
|
||||
if (e.code.includes("Arrow")) {
|
||||
if (document.activeElement.nodeName == "INPUT") {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode?.classList.add("pressed_key")
|
||||
}
|
||||
} else if (e.code == "Enter") {
|
||||
if (document.activeElement.dataset.edit == "true") {
|
||||
document.querySelector(".key_code_Enter")?.classList.add("pressed_key")
|
||||
}
|
||||
} else if (e.code != "Escape") {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode?.classList.add("pressed_key")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key == "ShiftTab" && e.code == "Tab" && e.shiftKey) {
|
||||
document.querySelector(".key_code_ShiftTab1").classList.add("pressed_key")
|
||||
document.querySelector(".key_code_ShiftTab2").classList.add("pressed_key")
|
||||
}
|
||||
})
|
||||
const numnerOfTutorialKeys = document.querySelectorAll(".tutorial_key").length
|
||||
const numberOfPressedKeys = document.querySelectorAll(".tutorial_key.pressed_key").length
|
||||
if (e.code == "Tab" && !e.shiftKey) {
|
||||
document.querySelector(".key_code_Tab").classList.add("pressed_key")
|
||||
}
|
||||
if (key == "ShiftTab" && e.code == "Tab" && e.shiftKey) {
|
||||
document.querySelector(".key_code_ShiftTab1").classList.add("pressed_key")
|
||||
document.querySelector(".key_code_ShiftTab2").classList.add("pressed_key")
|
||||
}
|
||||
})
|
||||
const numnerOfTutorialKeys = document.querySelectorAll(".tutorial_key").length
|
||||
const numberOfPressedKeys = document.querySelectorAll(".tutorial_key.pressed_key").length
|
||||
|
||||
if (numnerOfTutorialKeys === numberOfPressedKeys) {
|
||||
console.log("TUTORIAL FINISHED!!")
|
||||
tutorialFinished = true
|
||||
const tutorialContainer = document.querySelector("#tutorial_complete")
|
||||
tutorialContainer.innerHTML = `<p>Tutorial complete! Your present is the variable version of Commit Mono:</p>
|
||||
if (numnerOfTutorialKeys === numberOfPressedKeys) {
|
||||
console.log("TUTORIAL FINISHED!!")
|
||||
tutorialFinished = true
|
||||
const tutorialContainer = document.querySelector("#tutorial_complete")
|
||||
tutorialContainer.innerHTML = `<p>Tutorial complete! Your present is the variable version of Commit Mono:</p>
|
||||
<p><a href="/src/fonts/CommitMonoV120-VF.ttf">Download CommitMono-VF.ttf</a></p>
|
||||
<p><a href="/src/fonts/CommitMonoV120-VF.woff2">Download CommitMono-VF.woff2</a></p>
|
||||
<br />`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sectionNavigation(sectionIndex) {
|
||||
const sectionName = websiteData.sections[sectionIndex]?.name
|
||||
const sectionName = websiteData.sections[sectionIndex]?.name
|
||||
|
||||
pageAnimation()
|
||||
pageAnimation()
|
||||
|
||||
const attemptedSection = document.querySelector(`[value="section_${sectionIndex + 1}"]`)
|
||||
if (attemptedSection && sectionName) {
|
||||
attemptedSection.focus()
|
||||
document.forms["nav_form"][sectionName].checked = true
|
||||
}
|
||||
const attemptedSection = document.querySelector(`[value="section_${sectionIndex + 1}"]`)
|
||||
if (attemptedSection && sectionName) {
|
||||
attemptedSection.focus()
|
||||
document.forms["nav_form"][sectionName].checked = true
|
||||
}
|
||||
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const sectionContainer = document.querySelector(`#section_${index + 1}`)
|
||||
if (index == sectionIndex) {
|
||||
sectionContainer.style.display = "block"
|
||||
} else {
|
||||
sectionContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
main.style.transform = `translate(0)`
|
||||
navForm.style.transform = `translate(0)`
|
||||
keySection.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const sectionContainer = document.querySelector(`#section_${index + 1}`)
|
||||
if (index == sectionIndex) {
|
||||
sectionContainer.style.display = "block"
|
||||
} else {
|
||||
sectionContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
main.style.transform = `translate(0)`
|
||||
navForm.style.transform = `translate(0)`
|
||||
keySection.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
}
|
||||
|
||||
// when the user has scrolled manually using the keyboard the page is offset
|
||||
@ -442,10 +445,10 @@ function sectionNavigation(sectionIndex) {
|
||||
// this little script combats that
|
||||
mainScale.addEventListener("scroll", onScroll)
|
||||
function onScroll(e) {
|
||||
const { x, y } = websiteData.pushPage.coordinates
|
||||
if (x != 0 || y != 0) {
|
||||
main.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates = { x: 0, y: 0 }
|
||||
mainScale.scrollBy(-x, -y)
|
||||
}
|
||||
const { x, y } = websiteData.pushPage.coordinates
|
||||
if (x != 0 || y != 0) {
|
||||
main.style.transform = `translate(0)`
|
||||
websiteData.pushPage.coordinates = { x: 0, y: 0 }
|
||||
mainScale.scrollBy(-x, -y)
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
const updateOptions = (event, form) => {
|
||||
console.log("updateOptions")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${output}${entry[0]}=${entry[1]}\n`
|
||||
}
|
||||
event.preventDefault()
|
||||
console.log("updateOptions")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${output}${entry[0]}=${entry[1]}\n`
|
||||
}
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
let commitMonoFont
|
||||
@ -13,255 +13,255 @@ let fontDownloadSettings = { weight: 450, italic: false, alternates: {}, feature
|
||||
let fontDownloadSettingsDefault = { weight: 450, italic: false, alternates: {}, features: {} }
|
||||
|
||||
async function updateCodeFont() {
|
||||
console.log("updateCodeFont")
|
||||
opentype
|
||||
.load(
|
||||
`/src/fonts/CommitMono${versionOfCommitMono}-${websiteData.weight}${
|
||||
websiteData.italic ? "Italic" : "Regular"
|
||||
}.otf`
|
||||
)
|
||||
.then((font) => {
|
||||
// console.log(font)
|
||||
commitMonoFont = font
|
||||
updateCode(null, codeForm)
|
||||
})
|
||||
.catch((err) => console.log(err))
|
||||
console.log("updateCodeFont")
|
||||
opentype
|
||||
.load(
|
||||
`/src/fonts/CommitMono${versionOfCommitMono}-${websiteData.weight}${
|
||||
websiteData.italic ? "Italic" : "Regular"
|
||||
}.otf`
|
||||
)
|
||||
.then((font) => {
|
||||
// console.log(font)
|
||||
commitMonoFont = font
|
||||
updateCode(null, codeForm)
|
||||
})
|
||||
.catch((err) => console.log(err))
|
||||
|
||||
// opentype
|
||||
// .load("src/fonts/CommitMonoV117-BoldItalic.otf")
|
||||
// .then((font) => {
|
||||
// console.log(font)
|
||||
// // font.download()
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
// opentype
|
||||
// .load("src/fonts/CommitMonoV117-Light.otf")
|
||||
// .then((font) => {
|
||||
// console.log(font)
|
||||
// // font.download()
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
// opentype
|
||||
// .load("src/fonts/CommitMonoV117-BoldItalic.otf")
|
||||
// .then((font) => {
|
||||
// console.log(font)
|
||||
// // font.download()
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
// opentype
|
||||
// .load("src/fonts/CommitMonoV117-Light.otf")
|
||||
// .then((font) => {
|
||||
// console.log(font)
|
||||
// // font.download()
|
||||
// })
|
||||
// .catch((err) => console.log(err))
|
||||
}
|
||||
|
||||
let downloadStarted = false
|
||||
async function downloadFont(button, isDefault) {
|
||||
console.log("downloadFont")
|
||||
if (!downloadStarted) {
|
||||
downloadStarted = true
|
||||
button.classList.remove("loaded")
|
||||
button.classList.remove("error")
|
||||
button.classList.add("loading")
|
||||
console.log("downloadFont")
|
||||
if (!downloadStarted) {
|
||||
downloadStarted = true
|
||||
button.classList.remove("loaded")
|
||||
button.classList.remove("error")
|
||||
button.classList.add("loading")
|
||||
|
||||
const allSettings = !isDefault
|
||||
? {
|
||||
regular: { ...fontDownloadSettings, style: "Regular" },
|
||||
italic: { ...fontDownloadSettings, style: "Italic", italic: true },
|
||||
bold: { ...fontDownloadSettings, style: "Bold", weight: 700 },
|
||||
bolditalic: { ...fontDownloadSettings, style: "Bold Italic", italic: true, weight: 700 },
|
||||
}
|
||||
: {
|
||||
regular: { ...fontDownloadSettingsDefault, style: "Regular" },
|
||||
italic: { ...fontDownloadSettingsDefault, style: "Italic", italic: true },
|
||||
bold: { ...fontDownloadSettingsDefault, style: "Bold", weight: 700 },
|
||||
bolditalic: { ...fontDownloadSettingsDefault, style: "Bold Italic", italic: true, weight: 700 },
|
||||
}
|
||||
const allSettings = !isDefault
|
||||
? {
|
||||
regular: { ...fontDownloadSettings, style: "Regular" },
|
||||
italic: { ...fontDownloadSettings, style: "Italic", italic: true },
|
||||
bold: { ...fontDownloadSettings, style: "Bold", weight: 700 },
|
||||
bolditalic: { ...fontDownloadSettings, style: "Bold Italic", italic: true, weight: 700 },
|
||||
}
|
||||
: {
|
||||
regular: { ...fontDownloadSettingsDefault, style: "Regular" },
|
||||
italic: { ...fontDownloadSettingsDefault, style: "Italic", italic: true },
|
||||
bold: { ...fontDownloadSettingsDefault, style: "Bold", weight: 700 },
|
||||
bolditalic: { ...fontDownloadSettingsDefault, style: "Bold Italic", italic: true, weight: 700 },
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
getFontBlob(allSettings.regular),
|
||||
getFontBlob(allSettings.italic),
|
||||
getFontBlob(allSettings.bold),
|
||||
getFontBlob(allSettings.bolditalic),
|
||||
])
|
||||
.then((resolve) => {
|
||||
const [regular, italic, bold, bolditalic] = resolve
|
||||
fontFileBlobs.regular = regular
|
||||
fontFileBlobs.italic = italic
|
||||
fontFileBlobs.bold = bold
|
||||
fontFileBlobs.bolditalic = bolditalic
|
||||
return getZipFileBlob()
|
||||
})
|
||||
.then((resolve) => {
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("loaded")
|
||||
downloadFile(resolve)
|
||||
})
|
||||
.catch((err) => {
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("error")
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
Promise.all([
|
||||
getFontBlob(allSettings.regular),
|
||||
getFontBlob(allSettings.italic),
|
||||
getFontBlob(allSettings.bold),
|
||||
getFontBlob(allSettings.bolditalic),
|
||||
])
|
||||
.then((resolve) => {
|
||||
const [regular, italic, bold, bolditalic] = resolve
|
||||
fontFileBlobs.regular = regular
|
||||
fontFileBlobs.italic = italic
|
||||
fontFileBlobs.bold = bold
|
||||
fontFileBlobs.bolditalic = bolditalic
|
||||
return getZipFileBlob()
|
||||
})
|
||||
.then((resolve) => {
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("loaded")
|
||||
downloadFile(resolve)
|
||||
})
|
||||
.catch((err) => {
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("error")
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const fontFileBlobs = { regular: null, italic: null, bold: null, bolditalic: null }
|
||||
function getFontBlob(settings) {
|
||||
console.log("getFontBlob")
|
||||
console.log("getFontBlob")
|
||||
|
||||
const fontFilePath = `/src/fonts/CommitMono${versionOfCommitMono}-${settings.weight}${
|
||||
settings.italic ? "Italic" : "Regular"
|
||||
}.otf`
|
||||
const fontFilePath = `/src/fonts/CommitMono${versionOfCommitMono}-${settings.weight}${
|
||||
settings.italic ? "Italic" : "Regular"
|
||||
}.otf`
|
||||
|
||||
return opentype
|
||||
.load(fontFilePath)
|
||||
.then((font) => {
|
||||
//
|
||||
// #1 change alternates by switching their paths
|
||||
// the below loop does this
|
||||
|
||||
// loop through the alternate settings
|
||||
Object.entries(settings.alternates).forEach(([alternate, active]) => {
|
||||
return opentype
|
||||
.load(fontFilePath)
|
||||
.then((font) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
// console.log("alternate", alternate, "active", active)
|
||||
// #1 change alternates by switching their paths
|
||||
// the below loop does this
|
||||
|
||||
// look at all the fonts features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// if the feature matches the alternate we're currently on
|
||||
if (feature.tag == alternate) {
|
||||
// console.log("feature", feature)
|
||||
// loop through the alternate settings
|
||||
Object.entries(settings.alternates).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
// console.log("alternate", alternate, "active", active)
|
||||
|
||||
// then loop through the list of lookup indexes of that feature
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => {
|
||||
// console.log("lookupIndex", lookupIndex)
|
||||
// look at all the fonts features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// if the feature matches the alternate we're currently on
|
||||
if (feature.tag == alternate) {
|
||||
// console.log("feature", feature)
|
||||
|
||||
// loop through the subtable of each lookup at the lookup index
|
||||
font.tables.gsub.lookups[lookupIndex].subtables.forEach((subtable) => {
|
||||
// console.log("subtable", subtable)
|
||||
// then loop through the list of lookup indexes of that feature
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => {
|
||||
// console.log("lookupIndex", lookupIndex)
|
||||
|
||||
// loop through the glyphs of the subtable
|
||||
subtable.coverage.glyphs.forEach((glyphIndexOriginal, index) => {
|
||||
//
|
||||
// glyphIndexOriginal is the index of the original glyph
|
||||
// glyphIndexSubstitute is the index of the glyph to substitute the original with
|
||||
const glyphIndexSubstitute = subtable.substitute[index]
|
||||
// console.log(
|
||||
// "glyphIndexOriginal",
|
||||
// glyphIndexOriginal,
|
||||
// "glyphIndexSubstitute",
|
||||
// glyphIndexSubstitute
|
||||
// )
|
||||
// loop through the subtable of each lookup at the lookup index
|
||||
font.tables.gsub.lookups[lookupIndex].subtables.forEach((subtable) => {
|
||||
// console.log("subtable", subtable)
|
||||
|
||||
// get the paths for the original and the substitute glyph
|
||||
const glyphPathOriginal = font.glyphs.glyphs[glyphIndexOriginal].path
|
||||
const glyphPathSubstitute = font.glyphs.glyphs[glyphIndexSubstitute].path
|
||||
// loop through the glyphs of the subtable
|
||||
subtable.coverage.glyphs.forEach((glyphIndexOriginal, index) => {
|
||||
//
|
||||
// glyphIndexOriginal is the index of the original glyph
|
||||
// glyphIndexSubstitute is the index of the glyph to substitute the original with
|
||||
const glyphIndexSubstitute = subtable.substitute[index]
|
||||
// console.log(
|
||||
// "glyphIndexOriginal",
|
||||
// glyphIndexOriginal,
|
||||
// "glyphIndexSubstitute",
|
||||
// glyphIndexSubstitute
|
||||
// )
|
||||
|
||||
// swap the paths, so the original glyph gets the path of the substitute and vice versa
|
||||
font.glyphs.glyphs[glyphIndexOriginal].path = glyphPathSubstitute
|
||||
font.glyphs.glyphs[glyphIndexSubstitute].path = glyphPathOriginal
|
||||
// get the paths for the original and the substitute glyph
|
||||
const glyphPathOriginal = font.glyphs.glyphs[glyphIndexOriginal].path
|
||||
const glyphPathSubstitute = font.glyphs.glyphs[glyphIndexSubstitute].path
|
||||
|
||||
// swap the paths, so the original glyph gets the path of the substitute and vice versa
|
||||
font.glyphs.glyphs[glyphIndexOriginal].path = glyphPathSubstitute
|
||||
font.glyphs.glyphs[glyphIndexSubstitute].path = glyphPathOriginal
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// "2 put active features into calt
|
||||
// create empty "calt" feature to store the feature
|
||||
const emptyCalt = { tag: "calt", feature: { featureParams: 0, lookupListIndexes: [] } }
|
||||
font.tables.gsub.features.push(emptyCalt)
|
||||
|
||||
// garbage code that adds a single number to a specific array in the gsub table
|
||||
// like this [0, 1, 2, 3, 4] => [0, 1, 2, 3, 4, 5]
|
||||
font.tables.gsub.scripts.forEach((script) =>
|
||||
script.script.defaultLangSys.featureIndexes.push(script.script.defaultLangSys.featureIndexes.length)
|
||||
)
|
||||
|
||||
// create the empty array that is to be the lookup indexes for the calt feature
|
||||
const caltLookupIndexes = []
|
||||
|
||||
// once again, loop through the alternate settings (feature settings)
|
||||
Object.entries(settings.features).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
// console.log("alternate", alternate, "active", active)
|
||||
// "2 put active features into calt
|
||||
// create empty "calt" feature to store the feature
|
||||
const emptyCalt = { tag: "calt", feature: { featureParams: 0, lookupListIndexes: [] } }
|
||||
font.tables.gsub.features.push(emptyCalt)
|
||||
|
||||
// then loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// and find the ones that match the active tags
|
||||
if (feature.tag == alternate) {
|
||||
// console.log("feature", feature)
|
||||
// garbage code that adds a single number to a specific array in the gsub table
|
||||
// like this [0, 1, 2, 3, 4] => [0, 1, 2, 3, 4, 5]
|
||||
font.tables.gsub.scripts.forEach((script) =>
|
||||
script.script.defaultLangSys.featureIndexes.push(script.script.defaultLangSys.featureIndexes.length)
|
||||
)
|
||||
|
||||
// push the lookup indexes into the empty caltLookupIndexes variable
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => caltLookupIndexes.push(lookupIndex))
|
||||
}
|
||||
// create the empty array that is to be the lookup indexes for the calt feature
|
||||
const caltLookupIndexes = []
|
||||
|
||||
// once again, loop through the alternate settings (feature settings)
|
||||
Object.entries(settings.features).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
// console.log("alternate", alternate, "active", active)
|
||||
|
||||
// then loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// and find the ones that match the active tags
|
||||
if (feature.tag == alternate) {
|
||||
// console.log("feature", feature)
|
||||
|
||||
// push the lookup indexes into the empty caltLookupIndexes variable
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => caltLookupIndexes.push(lookupIndex))
|
||||
}
|
||||
})
|
||||
|
||||
// once more loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// when the calt feature is reached (it's the last one)
|
||||
if (feature.tag === "calt") {
|
||||
//
|
||||
// set its lookup indexes to the variable
|
||||
feature.feature.lookupListIndexes = caltLookupIndexes
|
||||
// console.log("caltLookupIndexes", caltLookupIndexes)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// once more loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// when the calt feature is reached (it's the last one)
|
||||
if (feature.tag === "calt") {
|
||||
//
|
||||
// set its lookup indexes to the variable
|
||||
feature.feature.lookupListIndexes = caltLookupIndexes
|
||||
// console.log("caltLookupIndexes", caltLookupIndexes)
|
||||
}
|
||||
})
|
||||
})
|
||||
//
|
||||
// #3 change the names
|
||||
// give custom names to each member of the style group
|
||||
font.names.fontFamily.en = "CommitMono"
|
||||
font.names.fontSubfamily.en = settings.style
|
||||
font.names.fullName.en = `CommitMono ${settings.style}`
|
||||
font.names.postScriptName.en = `CommitMono-${settings.style.split(" ").join("")}`
|
||||
delete font.names.preferredFamily
|
||||
delete font.names.preferredSubfamily
|
||||
font.names.uniqueID.en = `Version 0.900;;CommitMono-${settings.style.split(" ").join("")};2023;FL801`
|
||||
|
||||
//
|
||||
// #3 change the names
|
||||
// give custom names to each member of the style group
|
||||
font.names.fontFamily.en = "CommitMono"
|
||||
font.names.fontSubfamily.en = settings.style
|
||||
font.names.fullName.en = `CommitMono ${settings.style}`
|
||||
font.names.postScriptName.en = `CommitMono-${settings.style.split(" ").join("")}`
|
||||
delete font.names.preferredFamily
|
||||
delete font.names.preferredSubfamily
|
||||
font.names.uniqueID.en = `Version 0.900;;CommitMono-${settings.style.split(" ").join("")};2023;FL801`
|
||||
font.tables.cff.topDict.familyName = font.names.fontFamily.en
|
||||
font.tables.cff.topDict.fullName = font.names.fullName.en
|
||||
font.tables.cff.topDict.weight = settings.weight == 700 ? "Bold" : "Regular"
|
||||
|
||||
font.tables.cff.topDict.familyName = font.names.fontFamily.en
|
||||
font.tables.cff.topDict.fullName = font.names.fullName.en
|
||||
font.tables.cff.topDict.weight = settings.weight == 700 ? "Bold" : "Regular"
|
||||
const macStyles = ["Regular", "Italic", "Bold", "Bold Italic"]
|
||||
font.tables.head.macStyle = macStyles.indexOf(settings.style)
|
||||
|
||||
const macStyles = ["Regular", "Italic", "Bold", "Bold Italic"]
|
||||
font.tables.head.macStyle = macStyles.indexOf(settings.style)
|
||||
// make the font.tables.name equal to that of font.names
|
||||
font.tables.name = font.names
|
||||
|
||||
// make the font.tables.name equal to that of font.names
|
||||
font.tables.name = font.names
|
||||
// set the correct weight
|
||||
font.tables.os2.usWeightClass = settings.weight
|
||||
|
||||
// set the correct weight
|
||||
font.tables.os2.usWeightClass = settings.weight
|
||||
console.log(font)
|
||||
const fontAB = font.toArrayBuffer()
|
||||
const fontBlob = new Blob([fontAB], { type: "font/otf" })
|
||||
|
||||
console.log(font)
|
||||
const fontAB = font.toArrayBuffer()
|
||||
const fontBlob = new Blob([fontAB], { type: "font/otf" })
|
||||
console.log(fontBlob)
|
||||
|
||||
console.log(fontBlob)
|
||||
|
||||
return fontBlob
|
||||
})
|
||||
.catch((err) => {
|
||||
return err
|
||||
})
|
||||
return fontBlob
|
||||
})
|
||||
.catch((err) => {
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
async function getZipFileBlob() {
|
||||
console.log(fontFileBlobs)
|
||||
const { BlobWriter, BlobReader, HttpReader, TextReader, ZipWriter } = zip
|
||||
const installationTextURL = "/src/txt/installation.txt"
|
||||
const zipWriter = new ZipWriter(new BlobWriter("application/zip"))
|
||||
const { regular, italic, bold, bolditalic } = fontFileBlobs
|
||||
await Promise.all([
|
||||
zipWriter.add("installation.txt", new HttpReader(installationTextURL)),
|
||||
zipWriter.add("CommitMono-Regular.otf", new BlobReader(regular)),
|
||||
zipWriter.add("CommitMono-Italic.otf", new BlobReader(italic)),
|
||||
zipWriter.add("CommitMono-Bold.otf", new BlobReader(bold)),
|
||||
zipWriter.add("CommitMono-BoldItalic.otf", new BlobReader(bolditalic)),
|
||||
])
|
||||
return zipWriter.close()
|
||||
console.log(fontFileBlobs)
|
||||
const { BlobWriter, BlobReader, HttpReader, TextReader, ZipWriter } = zip
|
||||
const installationTextURL = "/src/txt/installation.txt"
|
||||
const zipWriter = new ZipWriter(new BlobWriter("application/zip"))
|
||||
const { regular, italic, bold, bolditalic } = fontFileBlobs
|
||||
await Promise.all([
|
||||
zipWriter.add("installation.txt", new HttpReader(installationTextURL)),
|
||||
zipWriter.add("CommitMono-Regular.otf", new BlobReader(regular)),
|
||||
zipWriter.add("CommitMono-Italic.otf", new BlobReader(italic)),
|
||||
zipWriter.add("CommitMono-Bold.otf", new BlobReader(bold)),
|
||||
zipWriter.add("CommitMono-BoldItalic.otf", new BlobReader(bolditalic)),
|
||||
])
|
||||
return zipWriter.close()
|
||||
}
|
||||
|
||||
function downloadFile(blob) {
|
||||
const a = document.createElement("a")
|
||||
a.download = `CommitMono-${Date.now()}.zip`
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.click()
|
||||
const a = document.createElement("a")
|
||||
a.download = `CommitMono-${Date.now()}.zip`
|
||||
a.href = URL.createObjectURL(blob)
|
||||
a.click()
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
function fillSectionData() {
|
||||
console.log("fillSectionData")
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const topContainer = document.querySelector(`#section_${index + 1} .top_container`)
|
||||
if (topContainer) {
|
||||
const h1 = document.createElement("h1")
|
||||
h1.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
h1.tabIndex = 0
|
||||
h1.dataset.edit = "true"
|
||||
const br = document.createElement("br")
|
||||
const p = document.createElement("p")
|
||||
p.innerHTML = section.description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
topContainer.append(h1, br, p)
|
||||
}
|
||||
})
|
||||
console.log("fillSectionData")
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const topContainer = document.querySelector(`#section_${index + 1} .top_container`)
|
||||
if (topContainer) {
|
||||
const h1 = document.createElement("h1")
|
||||
h1.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
h1.tabIndex = 0
|
||||
h1.dataset.edit = "true"
|
||||
const br = document.createElement("br")
|
||||
const p = document.createElement("p")
|
||||
p.innerHTML = section.description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
topContainer.append(h1, br, p)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,49 +1,49 @@
|
||||
let waitingForLoadIntervalID = null
|
||||
let allCssLoaded = false
|
||||
function startAll() {
|
||||
console.log("startAll")
|
||||
console.log("startAll")
|
||||
|
||||
appendStyleSheets()
|
||||
appendStyleSheets()
|
||||
|
||||
waitingForLoadIntervalID = setInterval(() => {
|
||||
if (allCssLoaded) {
|
||||
document.querySelector("#navigate_description").focus()
|
||||
document.querySelector("#loading").style.display = "none"
|
||||
clearInterval(waitingForLoadIntervalID)
|
||||
waitingForLoadIntervalID = null
|
||||
}
|
||||
}, 100)
|
||||
waitingForLoadIntervalID = setInterval(() => {
|
||||
if (allCssLoaded) {
|
||||
document.querySelector("#navigate_description").focus()
|
||||
document.querySelector("#loading").style.display = "none"
|
||||
clearInterval(waitingForLoadIntervalID)
|
||||
waitingForLoadIntervalID = null
|
||||
}
|
||||
}, 100)
|
||||
|
||||
fillSectionData()
|
||||
fillSectionData()
|
||||
|
||||
buildNav()
|
||||
buildNav()
|
||||
|
||||
buildTable()
|
||||
buildTable()
|
||||
|
||||
buildFamiliar()
|
||||
buildFamiliar()
|
||||
|
||||
buildCode()
|
||||
buildCode()
|
||||
|
||||
buildDistinction()
|
||||
buildDistinction()
|
||||
|
||||
buildGTC()
|
||||
buildGTC()
|
||||
|
||||
buildExample()
|
||||
buildExample()
|
||||
|
||||
buildDocumentation()
|
||||
buildDocs()
|
||||
|
||||
updateCodeFont()
|
||||
updateCodeFont()
|
||||
|
||||
updateWaterfall()
|
||||
updateWaterfall()
|
||||
|
||||
changeFavicon(true)
|
||||
changeFavicon(true)
|
||||
|
||||
sectionNavigation(0)
|
||||
sectionNavigation(0)
|
||||
|
||||
setInterval(checkDocumentFocus, 100)
|
||||
setInterval(checkDocumentFocus, 100)
|
||||
}
|
||||
|
||||
if (fontsLoaded) {
|
||||
console.log("fontsLoaded startAll()")
|
||||
startAll()
|
||||
console.log("fontsLoaded startAll()")
|
||||
startAll()
|
||||
}
|
||||
|
@ -1,68 +1,68 @@
|
||||
function buildTable() {
|
||||
console.log("buildTable")
|
||||
const table = document.querySelector("#section_2 .content_container table")
|
||||
console.log("buildTable")
|
||||
const table = document.querySelector("#section_2 .content_container table")
|
||||
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const tr = document.createElement("tr")
|
||||
const fieldset = document.createElement("fieldset")
|
||||
tr.append(fieldset)
|
||||
for (let j = 0; j <= 16; j++) {
|
||||
if (i == 0 || j == 0) {
|
||||
const th = document.createElement("th")
|
||||
const div = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
if (i != 0 && j == 0) {
|
||||
p.textContent = createBinaryString(i + 1, 3)
|
||||
} else if (i == 0 && j != 0) {
|
||||
p.textContent = createBinaryString(j - 1, 4)
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const tr = document.createElement("tr")
|
||||
const fieldset = document.createElement("fieldset")
|
||||
tr.append(fieldset)
|
||||
for (let j = 0; j <= 16; j++) {
|
||||
if (i == 0 || j == 0) {
|
||||
const th = document.createElement("th")
|
||||
const div = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
if (i != 0 && j == 0) {
|
||||
p.textContent = createBinaryString(i + 1, 3)
|
||||
} else if (i == 0 && j != 0) {
|
||||
p.textContent = createBinaryString(j - 1, 4)
|
||||
} else {
|
||||
p.textContent = ""
|
||||
}
|
||||
div.append(p)
|
||||
th.append(div)
|
||||
fieldset.append(th)
|
||||
} else {
|
||||
p.textContent = ""
|
||||
}
|
||||
div.append(p)
|
||||
th.append(div)
|
||||
fieldset.append(th)
|
||||
} else {
|
||||
const charCode = (i - 1) * 16 + j + 31
|
||||
const charCode = (i - 1) * 16 + j + 31
|
||||
|
||||
const td = document.createElement("td")
|
||||
td.id = `td_${charCode}`
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.id = `char_${charCode}`
|
||||
input.name = `row_${i}`
|
||||
input.value = charCode
|
||||
if (j == 2) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = i == 6 && j == 16 ? "" : String.fromCharCode(charCode)
|
||||
label.setAttribute("for", `char_${charCode}`)
|
||||
label.dataset.edit = "true"
|
||||
div.append(input, label)
|
||||
td.append(div)
|
||||
fieldset.append(td)
|
||||
}
|
||||
}
|
||||
table.append(tr)
|
||||
}
|
||||
const td = document.createElement("td")
|
||||
td.id = `td_${charCode}`
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.id = `char_${charCode}`
|
||||
input.name = `row_${i}`
|
||||
input.value = charCode
|
||||
if (j == 2) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = i == 6 && j == 16 ? "" : String.fromCharCode(charCode)
|
||||
label.setAttribute("for", `char_${charCode}`)
|
||||
label.dataset.edit = "true"
|
||||
div.append(input, label)
|
||||
td.append(div)
|
||||
fieldset.append(td)
|
||||
}
|
||||
}
|
||||
table.append(tr)
|
||||
}
|
||||
}
|
||||
const createBinaryString = (number, length) => parseInt(number, 10).toString(2).padStart(length, "0")
|
||||
|
||||
let previousOutput = [33, 49, 65, 81, 97, 113]
|
||||
function updateTable(event, form) {
|
||||
console.log("updateTable")
|
||||
const data = new FormData(form)
|
||||
let output = []
|
||||
for (const entry of data) output.push(+entry[1])
|
||||
let indexOfChange = 0
|
||||
let offset = 0
|
||||
output.forEach((row, index) => (row != previousOutput[index] ? (indexOfChange = index) : null))
|
||||
output.forEach((row, index) => (index == indexOfChange ? (offset = row - previousOutput[index]) : null))
|
||||
output.forEach((row, index) => {
|
||||
if (index != indexOfChange) {
|
||||
document.forms["table_form"][`char_${row + offset}`].checked = true
|
||||
output[index] += offset
|
||||
}
|
||||
})
|
||||
previousOutput = [...output]
|
||||
event.preventDefault()
|
||||
console.log("updateTable")
|
||||
const data = new FormData(form)
|
||||
let output = []
|
||||
for (const entry of data) output.push(+entry[1])
|
||||
let indexOfChange = 0
|
||||
let offset = 0
|
||||
output.forEach((row, index) => (row != previousOutput[index] ? (indexOfChange = index) : null))
|
||||
output.forEach((row, index) => (index == indexOfChange ? (offset = row - previousOutput[index]) : null))
|
||||
output.forEach((row, index) => {
|
||||
if (index != indexOfChange) {
|
||||
document.forms["table_form"][`char_${row + offset}`].checked = true
|
||||
output[index] += offset
|
||||
}
|
||||
})
|
||||
previousOutput = [...output]
|
||||
event.preventDefault()
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// takes a string and returns a string, where the first letter is uppercase
|
||||
function capitalize(string) {
|
||||
const stringArray = string.split("")
|
||||
return stringArray.shift().toUpperCase() + stringArray.join("")
|
||||
const stringArray = string.split("")
|
||||
return stringArray.shift().toUpperCase() + stringArray.join("")
|
||||
}
|
||||
|
||||
const mapRange = (value, x1, y1, x2, y2) => ((value - x1) * (y2 - x2)) / (y1 - x1) + x2
|
||||
@ -10,79 +10,79 @@ const getCssVar = (property) => getComputedStyle(document.documentElement).getPr
|
||||
const setCssVar = ([property, value]) => document.documentElement.style.setProperty(property, value)
|
||||
|
||||
const isMobileTest = () => {
|
||||
if (window.matchMedia("(pointer: coarse) and (max-width: 1000px").matches) {
|
||||
console.log("(pointer: coarse) and (max-width: 1000px)")
|
||||
return true
|
||||
} else return false
|
||||
if (window.matchMedia("(pointer: coarse) and (max-width: 1000px").matches) {
|
||||
console.log("(pointer: coarse) and (max-width: 1000px)")
|
||||
return true
|
||||
} else return false
|
||||
}
|
||||
|
||||
const mobileMediaQuery = "(pointer: coarse) and (max-width: 1000px)"
|
||||
const mql = window.matchMedia(mobileMediaQuery)
|
||||
let isMobile = mql.matches
|
||||
mql.addEventListener("change", (e) => {
|
||||
isMobile = e.matches
|
||||
changedFocus(true)
|
||||
isMobile = e.matches
|
||||
changedFocus(true)
|
||||
})
|
||||
|
||||
function wait(milliseconds) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, milliseconds)
|
||||
})
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, milliseconds)
|
||||
})
|
||||
}
|
||||
|
||||
let checkCssLoadIntervalIDs = []
|
||||
function appendStyleSheets() {
|
||||
console.log("appendStyleSheets")
|
||||
const stylesheetIndexes = [
|
||||
"style",
|
||||
"mobile",
|
||||
"non_essential",
|
||||
"section_1",
|
||||
"section_2",
|
||||
"section_3",
|
||||
"section_4",
|
||||
"section_5",
|
||||
"section_6",
|
||||
"section_7",
|
||||
"section_8",
|
||||
"section_9",
|
||||
"section_10",
|
||||
]
|
||||
const head = document.querySelector("head")
|
||||
stylesheetIndexes.forEach((stylesheet, index) => {
|
||||
const link = document.createElement("link")
|
||||
link.setAttribute("rel", "stylesheet")
|
||||
link.setAttribute("href", `src/css/${stylesheet}.css`)
|
||||
head.append(link)
|
||||
checkCssLoadIntervalIDs[index] = setInterval(() => {
|
||||
const cssLoaded = Boolean(link.sheet)
|
||||
if (cssLoaded) {
|
||||
console.log(`${stylesheet} CSS loaded`)
|
||||
clearInterval(checkCssLoadIntervalIDs[index])
|
||||
checkCssLoadIntervalIDs[index] = null
|
||||
if (index == 3) {
|
||||
allCssLoaded = true
|
||||
console.log("ALL CSS LOADED")
|
||||
console.log("appendStyleSheets")
|
||||
const stylesheetIndexes = [
|
||||
"style",
|
||||
"mobile",
|
||||
"non_essential",
|
||||
"section_1",
|
||||
"section_2",
|
||||
"section_3",
|
||||
"section_4",
|
||||
"section_5",
|
||||
"section_6",
|
||||
"section_7",
|
||||
"section_8",
|
||||
"section_9",
|
||||
"section_10",
|
||||
]
|
||||
const head = document.querySelector("head")
|
||||
stylesheetIndexes.forEach((stylesheet, index) => {
|
||||
const link = document.createElement("link")
|
||||
link.setAttribute("rel", "stylesheet")
|
||||
link.setAttribute("href", `src/css/${stylesheet}.css`)
|
||||
head.append(link)
|
||||
checkCssLoadIntervalIDs[index] = setInterval(() => {
|
||||
const cssLoaded = Boolean(link.sheet)
|
||||
if (cssLoaded) {
|
||||
console.log(`${stylesheet} CSS loaded`)
|
||||
clearInterval(checkCssLoadIntervalIDs[index])
|
||||
checkCssLoadIntervalIDs[index] = null
|
||||
if (index == 3) {
|
||||
allCssLoaded = true
|
||||
console.log("ALL CSS LOADED")
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
|
||||
function showHideChangeSettings(text, ms, dim) {
|
||||
const changeSetting = document.querySelector("#change_setting p")
|
||||
changeSetting.textContent = text
|
||||
changeSetting.style.visibility = "visible"
|
||||
if (dim) {
|
||||
document.querySelector("#nav_form").classList.add("faded")
|
||||
document.querySelector("#main_scale").classList.add("faded")
|
||||
}
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => {
|
||||
changeSetting.style.visibility = "hidden"
|
||||
if (dim) {
|
||||
document.querySelector("#nav_form").classList.remove("faded")
|
||||
document.querySelector("#main_scale").classList.remove("faded")
|
||||
}
|
||||
}, ms ?? 500)
|
||||
const changeSetting = document.querySelector("#change_setting p")
|
||||
changeSetting.textContent = text
|
||||
changeSetting.style.visibility = "visible"
|
||||
if (dim) {
|
||||
document.querySelector("#nav_form").classList.add("faded")
|
||||
document.querySelector("#main_scale").classList.add("faded")
|
||||
}
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => {
|
||||
changeSetting.style.visibility = "hidden"
|
||||
if (dim) {
|
||||
document.querySelector("#nav_form").classList.remove("faded")
|
||||
document.querySelector("#main_scale").classList.remove("faded")
|
||||
}
|
||||
}, ms ?? 500)
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
164
tables.html
164
tables.html
@ -1,90 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>School timetable</title>
|
||||
<style>
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>School timetable</title>
|
||||
<style>
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 0.125rem solid rgb(200, 200, 200);
|
||||
letter-spacing: 0.0625rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 0.125rem solid rgb(200, 200, 200);
|
||||
letter-spacing: 0.0625rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 0.0625rem solid rgb(190, 190, 190);
|
||||
padding: 10px 20px;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
border: 0.0625rem solid rgb(190, 190, 190);
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>School timetable</h1>
|
||||
caption {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>School timetable</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th>Mon</th>
|
||||
<th>Tues</th>
|
||||
<th>Wed</th>
|
||||
<th>Thurs</th>
|
||||
<th>Fri</th>
|
||||
<th>Sat</th>
|
||||
<th>Sun</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>1st period</th>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2nd period</th>
|
||||
<td>English</td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3rd period</th>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>4th period</th>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th>Mon</th>
|
||||
<th>Tues</th>
|
||||
<th>Wed</th>
|
||||
<th>Thurs</th>
|
||||
<th>Fri</th>
|
||||
<th>Sat</th>
|
||||
<th>Sun</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>1st period</th>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2nd period</th>
|
||||
<td>English</td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3rd period</th>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>4th period</th>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user