diff --git a/index.html b/index.html index 5d82bab8..4bd3e984 100644 --- a/index.html +++ b/index.html @@ -4176,6 +4176,7 @@ + diff --git a/modules/fonts.js b/modules/fonts.js new file mode 100644 index 00000000..d2082929 --- /dev/null +++ b/modules/fonts.js @@ -0,0 +1,63 @@ +// helper finction to work with fonts + +function loadUsedFonts() { + const fontsInUse = getFontsList(svg); + const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font)); + if (fontsToLoad) { + const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); + addFonts(url); + } +} + +function getFontsList(svg) { + const fontsInUse = []; + + svg.selectAll("#labels > g").each(function () { + if (!this.hasChildNodes()) return; + const font = this.dataset.font; + if (font) fontsInUse.push(font); + }); + if (legend.node().hasChildNodes()) fontsInUse.push(legend.attr("data-font")); + + return [...new Set(fontsInUse)]; +} + +// code from Kaiido's answer https://stackoverflow.com/questions/42402584/how-to-use-google-fonts-in-canvas-when-drawing-dom-objects-in-svg +function GFontToDataURI(url) { + if (!url) return Promise.resolve(); + return fetch(url) // first fecth the embed stylesheet page + .then(resp => resp.text()) // we only need the text of it + .then(text => { + let s = document.createElement("style"); + s.innerHTML = text; + document.head.appendChild(s); + const styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; + + const FontRule = rule => { + const src = rule.style.getPropertyValue("src"); + const url = src ? src.split("url(")[1].split(")")[0] : ""; + return {rule, src, url: url.substring(url.length - 1, 1)}; + }; + const fontProms = []; + + for (const r of styleSheet.cssRules) { + let fR = FontRule(r); + if (!fR.url) continue; + + fontProms.push( + fetch(fR.url) // fetch the actual font-file (.woff) + .then(resp => resp.blob()) + .then(blob => { + return new Promise(resolve => { + let f = new FileReader(); + f.onload = e => resolve(f.result); + f.readAsDataURL(blob); + }); + }) + .then(dataURL => fR.rule.cssText.replace(fR.url, dataURL)) + ); + } + document.head.removeChild(s); // clean up + return Promise.all(fontProms); // wait for all this has been done + }); +} diff --git a/modules/load.js b/modules/load.js index cec66434..04a7a01b 100644 --- a/modules/load.js +++ b/modules/load.js @@ -221,14 +221,7 @@ function parseLoadedData(data) { burgLabels = labels.select("#burgLabels"); })(); - void (function loadUsedFonts() { - const fontsInUse = getFontsList(svg); - const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font)); - if (fontsToLoad) { - const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); - addFonts(url); - } - })(); + loadUsedFonts(); void (function parseGridData() { grid = JSON.parse(data[6]); diff --git a/modules/save.js b/modules/save.js index c0ac85ea..24fa55dc 100644 --- a/modules/save.js +++ b/modules/save.js @@ -359,59 +359,6 @@ function inlineStyle(clone) { emptyG.remove(); } -function getFontsList(svg) { - const fontsInUse = []; - - svg.selectAll("#labels > g").each(function () { - if (!this.hasChildNodes()) return; - const font = this.dataset.font; - if (font) fontsInUse.push(font); - }); - if (legend.node().hasChildNodes()) fontsInUse.push(legend.attr("data-font")); - - return [...new Set(fontsInUse)]; -} - -// code from Kaiido's answer https://stackoverflow.com/questions/42402584/how-to-use-google-fonts-in-canvas-when-drawing-dom-objects-in-svg -function GFontToDataURI(url) { - if (!url) return Promise.resolve(); - return fetch(url) // first fecth the embed stylesheet page - .then(resp => resp.text()) // we only need the text of it - .then(text => { - let s = document.createElement("style"); - s.innerHTML = text; - document.head.appendChild(s); - const styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; - - const FontRule = rule => { - const src = rule.style.getPropertyValue("src"); - const url = src ? src.split("url(")[1].split(")")[0] : ""; - return {rule, src, url: url.substring(url.length - 1, 1)}; - }; - const fontProms = []; - - for (const r of styleSheet.cssRules) { - let fR = FontRule(r); - if (!fR.url) continue; - - fontProms.push( - fetch(fR.url) // fetch the actual font-file (.woff) - .then(resp => resp.blob()) - .then(blob => { - return new Promise(resolve => { - let f = new FileReader(); - f.onload = e => resolve(f.result); - f.readAsDataURL(blob); - }); - }) - .then(dataURL => fR.rule.cssText.replace(fR.url, dataURL)) - ); - } - document.head.removeChild(s); // clean up - return Promise.all(fontProms); // wait for all this has been done - }); -} - // prepare map data for saving function getMapData() { TIME && console.time("createMapDataBlob"); diff --git a/modules/ui/style.js b/modules/ui/style.js index 6b9eb7d6..58029969 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -879,10 +879,8 @@ function applyStyle(style) { // change current style preset to another saved one function changeStylePreset(preset) { - if (customization) { - tip("Please exit the customization mode first", false, "error"); - return; - } + if (customization) return tip("Please exit the customization mode first", false, "error"); + alertMessage.innerHTML = "Are you sure you want to change the style preset? All unsaved style changes will be lost"; $("#alert").dialog({ resizable: false, @@ -899,6 +897,7 @@ function changeStylePreset(preset) { } } else if (defaultStyles[preset]) applyStyle(JSON.parse(defaultStyles[preset])); else applyDefaultStyle(); + loadUsedFonts(); removeStyleButton.style.display = stylePreset.selectedOptions[0].dataset.system ? "none" : "inline-block"; updateElements(); // change elements