diff --git a/index.css b/index.css
index 534a54ec..f1a53210 100644
--- a/index.css
+++ b/index.css
@@ -430,8 +430,7 @@ input[type="color"]::-webkit-color-swatch-wrapper {
#options input[type="range"] {
height: 8px;
background: 0;
- -moz-appearance: none;
- -webkit-appearance: none;
+ appearance: none;
margin-left: 0;
border: 0;
padding: 0;
@@ -605,18 +604,18 @@ input[type="color"]::-webkit-color-swatch-wrapper {
}
.glow {
- animation: glowing 3s infinite;
+ animation: glowing 3s infinite ease-in-out;
}
@keyframes glowing {
0% {
- box-shadow: 0 0 -4px #ded2d8;
+ box-shadow: 0 0 1px #f44336;
}
50% {
- box-shadow: 0 0 8px #f44336;
+ box-shadow: 0 0 10px #f44336;
}
100% {
- box-shadow: 0 0 -4px #ded2d8;
+ box-shadow: 0 0 1px #f44336;
}
}
@@ -986,7 +985,7 @@ body button.noicon {
#controlCells {
pointer-events: none;
fill: #82c8ff80;
- stroke: "none";
+ stroke: none;
}
#vertices > circle {
@@ -1195,14 +1194,6 @@ i.resetButton:active {
opacity: 0.2;
}
-.ui-dialog .disabled::slider-thumb {
- opacity: 0.2;
-}
-
-.ui-dialog .disabled::-moz-range-thumb {
- opacity: 0.2;
-}
-
.ui-dialog:disabled {
cursor: default;
}
@@ -1976,7 +1967,6 @@ div.textual span,
#markers {
cursor: pointer;
font-family: monospace;
- -moz-user-select: none;
user-select: none;
text-anchor: middle;
}
@@ -2071,7 +2061,6 @@ svg.button {
}
#alertMessage {
- -moz-user-select: text;
user-select: text;
max-height: 70vh;
max-width: 75vw;
@@ -2199,7 +2188,6 @@ svg.button {
#legend {
cursor: move;
- -moz-user-select: none;
user-select: none;
}
diff --git a/index.html b/index.html
index 44869737..e72655d0 100644
--- a/index.html
+++ b/index.html
@@ -666,8 +666,8 @@
Font |
-
-
+
+
|
diff --git a/modules/fonts.js b/modules/fonts.js
index 3892f6ab..f86d69d3 100644
--- a/modules/fonts.js
+++ b/modules/fonts.js
@@ -17,107 +17,107 @@ const fonts = [
{
family: "Amatic SC",
src: "url(https://fonts.gstatic.com/s/amaticsc/v11/TUZ3zwprpvBS1izr_vOMscGKfrUC.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Architects Daughter",
src: "url(https://fonts.gstatic.com/s/architectsdaughter/v8/RXTgOOQ9AAtaVOHxx0IUBM3t7GjCYufj5TXV5VnA2p8.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Bitter",
src: "url(https://fonts.gstatic.com/s/bitter/v12/zfs6I-5mjWQ3nxqccMoL2A.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Caesar Dressing",
src: "url(https://fonts.gstatic.com/s/caesardressing/v6/yYLx0hLa3vawqtwdswbotmK4vrRHdrz7.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Cinzel",
src: "url(https://fonts.gstatic.com/s/cinzel/v7/zOdksD_UUTk1LJF9z4tURA.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Dancing Script",
src: "url(https://fonts.gstatic.com/s/dancingscript/v9/KGBfwabt0ZRLA5W1ywjowUHdOuSHeh0r6jGTOGdAKHA.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Fredericka the Great",
src: "url(https://fonts.gstatic.com/s/frederickathegreat/v6/9Bt33CxNwt7aOctW2xjbCstzwVKsIBVV--Sjxbc.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Gloria Hallelujah",
src: "url(https://fonts.gstatic.com/s/gloriahallelujah/v9/CA1k7SlXcY5kvI81M_R28cNDay8z-hHR7F16xrcXsJw.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Great Vibes",
src: "url(https://fonts.gstatic.com/s/greatvibes/v5/6q1c0ofG6NKsEhAc2eh-3Y4P5ICox8Kq3LLUNMylGO4.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "IM Fell English",
src: "url(https://fonts.gstatic.com/s/imfellenglish/v7/xwIisCqGFi8pff-oa9uSVAkYLEKE0CJQa8tfZYc_plY.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Kaushan Script",
src: "url(https://fonts.gstatic.com/s/kaushanscript/v6/qx1LSqts-NtiKcLw4N03IEd0sm1ffa_JvZxsF_BEwQk.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "MedievalSharp",
src: "url(https://fonts.gstatic.com/s/medievalsharp/v9/EvOJzAlL3oU5AQl2mP5KdgptMqhwMg.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Metamorphous",
src: "url(https://fonts.gstatic.com/s/metamorphous/v7/Wnz8HA03aAXcC39ZEX5y133EOyqs.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Montez",
src: "url(https://fonts.gstatic.com/s/montez/v8/aq8el3-0osHIcFK6bXAPkw.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Nova Script",
src: "url(https://fonts.gstatic.com/s/novascript/v10/7Au7p_IpkSWSTWaFWkumvlQKGFw.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Orbitron",
src: "url(https://fonts.gstatic.com/s/orbitron/v9/HmnHiRzvcnQr8CjBje6GQvesZW2xOQ-xsNqO47m55DA.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Satisfy",
src: "url(https://fonts.gstatic.com/s/satisfy/v8/2OzALGYfHwQjkPYWELy-cw.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Shadows Into Light",
src: "url(https://fonts.gstatic.com/s/shadowsintolight/v7/clhLqOv7MXn459PTh0gXYFK2TSYBz0eNcHnp4YqE4Ts.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
},
{
family: "Uncial Antiqua",
src: "url(https://fonts.gstatic.com/s/uncialantiqua/v5/N0bM2S5WOex4OUbESzoESK-i-MfWQZQ.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Underdog",
src: "url(https://fonts.gstatic.com/s/underdog/v6/CHygV-jCElj7diMroWSlWV8.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD"
},
{
family: "Yellowtail",
src: "url(https://fonts.gstatic.com/s/yellowtail/v8/GcIHC9QEwVkrA19LJU1qlPk_vArhqVIZ0nv9q090hN8.woff2)",
- range: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
+ unicodeRange: "U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215"
}
];
@@ -131,7 +131,6 @@ function declareFont(font) {
if (isAdded) return;
document.fonts.add(fontFace);
- fontFace.loaded.then(font => console.log("loaded font", font));
addFontOption(font.family);
}
@@ -171,46 +170,29 @@ function addWebsafeFontOptions() {
localFonts.forEach(font => addFontOption(font.family));
}
-function tryToFindGoogleFont(family) {
- return null;
-}
-
-function addUsedGoogleFonts() {
- const fontsInUse = getUsedFonts(svg.node());
- const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font));
- if (fontsToLoad?.length) {
- const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|");
- addGoogleFonts(url);
- }
-}
-
-async function addGoogleFonts(url) {
- $("head").append('');
+async function fetchGoogleFont(family) {
+ const url = `https://fonts.googleapis.com/css2?family=${family.replace(/ /g, "+")}`;
try {
const resp = await fetch(url);
const text = await resp.text();
- let s = document.createElement("style");
- s.innerHTML = text;
- document.head.appendChild(s);
- let styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0];
- let FontRule = rule_1 => {
- let family = rule_1.style.getPropertyValue("font-family");
- let font = family.replace(/['"]+/g, "").replace(/ /g, "+");
- let weight = rule_1.style.getPropertyValue("font-weight");
- if (weight && weight !== "400") font += ":" + weight;
- if (fonts.indexOf(font) == -1) {
- fonts.push(font);
- fetched++;
- }
- };
- let fetched = 0;
- for (let r of styleSheet.cssRules) {
- FontRule(r);
- }
- document.head.removeChild(s);
- return fetched;
+
+ const fontFaceRules = text.match(/font-face\s*{[^}]+}/g);
+ const fonts = fontFaceRules.map(fontFace => {
+ const srcURL = fontFace.match(/url\(['"]?(.+?)['"]?\)/)[1];
+ const src = `url(${srcURL})`;
+ const unicodeRange = fontFace.match(/unicode-range: (.*?);/)?.[1];
+ const variant = fontFace.match(/font-style: (.*?);/)?.[1];
+
+ const font = {family, src};
+ if (unicodeRange) font.unicodeRange = unicodeRange;
+ if (variant && variant !== "normal") font.variant = variant;
+ return font;
+ });
+
+ return fonts;
} catch (err) {
- return ERROR && console.error(err);
+ ERROR && console.error(err);
+ return null;
}
}
@@ -254,27 +236,3 @@ function convertFontToDataURI(url) {
return Promise.all(fontProms); // wait for all this has been done
});
}
-
-function fetchFonts(url) {
- return new Promise((resolve, reject) => {
- if (url === "") return tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts");
-
- if (url.indexOf("http") === -1) {
- url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(" ").join("+");
- url = "https://fonts.googleapis.com/css?family=" + url;
- }
-
- addGoogleFonts(url).then(fetched => {
- if (fetched === undefined) return tip("Cannot fetch font for this value!", false, "error");
- if (fetched === 0) return tip("Already in the fonts list!", false, "error");
-
- // addFontOption();
- if (fetched === 1) {
- tip("Font " + fonts[fonts.length - 1] + " is fetched");
- } else if (fetched > 1) {
- tip(fetched + " fonts are added to the list");
- }
- resolve(fetched);
- });
- });
-}
diff --git a/modules/ui/style.js b/modules/ui/style.js
index 2248e096..af02c216 100644
--- a/modules/ui/style.js
+++ b/modules/ui/style.js
@@ -549,19 +549,39 @@ styleFontAdd.addEventListener("click", function () {
}
});
-styleInputFont.addEventListener("change", function () {
- if (!this.value) {
- tip("Please provide a valid Google font name or link to a @font-face declaration");
- return;
- }
- fetchFonts(this.value).then(fetched => {
- if (!fetched) return;
- styleFontAdd.click();
- styleInputFont.value = "";
- if (fetched !== 1) return;
- styleSelectFont.value = fonts.length - 1;
- changeFont(); // auto-change font if 1 font is fetched
+styleInputFont.addEventListener("change", async function () {
+ const family = this.value;
+ if (!family) return tip("Please provide a Google font name", false, "error");
+ const existingFont = fonts.find(font => font.family === family);
+ if (existingFont) return tip("The font already exists in the list", false, "error");
+
+ document.getElementById("styleFontAdd").click();
+ document.getElementById("styleInputFont").value = "";
+
+ const fontRanges = await fetchGoogleFont(family);
+ if (!fontRanges) return tip("Cannot fetch Google font for this value", true, "error", 4000);
+
+ tip(`Google font ${family} is loading...`, true, "warn", 4000);
+
+ const promises = fontRanges.map(range => {
+ const {src, unicodeRange, variant} = range;
+ const fontFace = new FontFace(family, src, {unicodeRange, variant, display: "block"});
+ return fontFace.load();
});
+
+ Promise.all(promises)
+ .then(fontFaces => {
+ fontFaces.forEach(fontFace => document.fonts.add(fontFace));
+ fonts.push(fontRanges[0]); // add the first font rule
+ tip(`Google font ${family} is added`, true, "success", 4000);
+ addFontOption(family);
+ document.getElementById("styleSelectFont").value = family;
+ changeFont();
+ })
+ .catch(err => {
+ tip(`Failed to load Google font ${family}`, true, "error", 4000);
+ console.error(err);
+ });
});
styleFontSize.addEventListener("change", function () {