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 () {