Просмотр исходного кода

better handling of svg "sprites"

Gildas 7 лет назад
Родитель
Сommit
ab51b383c0
1 измененных файлов с 34 добавлено и 1 удалено
  1. 34 1
      lib/single-file/single-file-core.js

+ 34 - 1
lib/single-file/single-file-core.js

@@ -499,7 +499,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[src], input[src][type=image], object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"], embed[src*=\".svg\"]"), "src", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[src], input[src][type=image], object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"], embed[src*=\".svg\"]"), "src", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", this.baseURI),
 				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", this.baseURI),
-				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image, use"), "xlink:href", this.baseURI),
+				DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image"), "xlink:href", this.baseURI),
+				DomProcessorHelper.processSVGImages(this.doc.querySelectorAll("use"), "xlink:href", this.baseURI),
 				DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI)
 				DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI)
 			];
 			];
 			if (!this.options.removeAudioSrc) {
 			if (!this.options.removeAudioSrc) {
@@ -774,6 +775,38 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}));
 			}));
 		}
 		}
 
 
+		static async processSVGImages(resourceElements, baseURI) {
+			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
+				const originalResourceURL = resourceElement.getAttribute("xlink:href");
+				if (originalResourceURL) {
+					const resourceURL = DomUtil.normalizeURL(originalResourceURL);
+					if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
+						try {
+							const content = await batchRequest.addURL(new URL(resourceURL, baseURI).href, false);
+							const DOMParser = DOM.getParser();
+							if (DOMParser) {
+								const svgDoc = new DOMParser().parseFromString(content, "image/svg+xml");
+								const hashMatch = originalResourceURL.match(/(#.+?)$/);
+								if (hashMatch && hashMatch[0]) {
+									const symbolElement = svgDoc.querySelector(hashMatch[0]);
+									if (symbolElement) {
+										resourceElement.setAttribute("xlink:href", hashMatch[0]);
+										resourceElement.parentElement.appendChild(symbolElement);
+									}
+								} else {
+									resourceElement.setAttribute("xlink:href", "data:image/svg+xml," + content);
+								}
+							} else {
+								resourceElement.setAttribute("xlink:href", "data:image/svg+xml," + content);
+							}
+						} catch (error) {
+							/* ignored */
+						}
+					}
+				}
+			}));
+		}
+
 		static async processSrcset(resourceElements, attributeName, baseURI) {
 		static async processSrcset(resourceElements, attributeName, baseURI) {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
 				const srcset = DOM.parseSrcset(resourceElement.getAttribute(attributeName));
 				const srcset = DOM.parseSrcset(resourceElement.getAttribute(attributeName));