Last active
February 10, 2020 07:54
-
-
Save amadeuszblanik/e4f30ece49d7b3bce2a1688b36bc16d4 to your computer and use it in GitHub Desktop.
[TypeScript][JavaScript] Inline SVG using Fetch API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// inlineSVG.ts | |
// Works with React | |
// | |
// Created by Amadeusz Blanik on 24/05/2019. | |
// Copyright © 2019 Amadeusz Blanik. All rights reserved. | |
// | |
interface SVGResponse extends Response { | |
parsedBody?: string; | |
} | |
export class InlineSVG { | |
private refNode: HTMLElement; | |
private source: string; | |
constructor(target: HTMLElement, source: string) { | |
this.refNode = target; | |
this.source = source; | |
if (typeof window !== "object") { | |
console.error("Window is not an object. SSR is not supported."); | |
} else { | |
if ("fetch" in window) { | |
this.render(); | |
} else { | |
console.error("Your browser does not supports Fetch API"); | |
} | |
} | |
} | |
http = async (request: RequestInfo): Promise<any> => { | |
return new Promise((resolve, reject) => { | |
let response: SVGResponse; | |
if (this.refNode.nodeName !== "IMG") { | |
reject("refNode is not HTMLImageElement"); | |
} | |
fetch(request) | |
.then(res => { | |
response = res; | |
return res.text(); | |
}) | |
.then(body => { | |
if (response.ok) { | |
const contentType: string | null = response.headers.get("content-type"); | |
if (contentType && !contentType.startsWith("image/svg+xml")) { | |
throw `XSS Preventing:: Received data is not SVG. Content-type is: "${response.headers.get( | |
"content-type", | |
)}"`; | |
} else { | |
response.parsedBody = body; | |
resolve(response); | |
} | |
} else { | |
reject(response); | |
} | |
}) | |
.catch(err => { | |
reject(err); | |
}); | |
}); | |
}; | |
async render() { | |
try { | |
const svgCode = await this.http(this.source); | |
this.refNode.outerHTML = svgCode; | |
} catch (err) { | |
console.error("Error during fetching svgCode", err); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// | |
// inlineSVG.ts | |
// Works with React | |
// | |
// Created by Amadeusz Blanik on 24/05/2019. | |
// Copyright © 2019 Amadeusz Blanik. All rights reserved. | |
// | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
class InlineSVG { | |
constructor(target, source) { | |
this.http = (request) => __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve, reject) => { | |
let response; | |
if (this.refNode.nodeName !== "IMG") { | |
reject("refNode is not HTMLImageElement"); | |
} | |
fetch(request) | |
.then(res => { | |
response = res; | |
return res.text(); | |
}) | |
.then(body => { | |
if (response.ok) { | |
const contentType = response.headers.get("content-type"); | |
if (contentType && !contentType.startsWith("image/svg+xml")) { | |
throw `XSS Preventing:: Received data is not SVG. Content-type is: "${response.headers.get("content-type")}"`; | |
} | |
else { | |
response.parsedBody = body; | |
resolve(response); | |
} | |
} | |
else { | |
reject(response); | |
} | |
}) | |
.catch(err => { | |
reject(err); | |
}); | |
}); | |
}); | |
this.refNode = target; | |
this.source = source; | |
if (typeof window !== "object") { | |
console.error("Window is not an object. SSR is not supported."); | |
} | |
else { | |
if ("fetch" in window) { | |
this.render(); | |
} | |
else { | |
console.error("Your browser does not supports Fetch API"); | |
} | |
} | |
} | |
render() { | |
return __awaiter(this, void 0, void 0, function* () { | |
try { | |
const svgCode = yield this.http(this.source); | |
this.refNode.outerHTML = svgCode; | |
} | |
catch (err) { | |
console.error("Error during fetching svgCode", err); | |
} | |
}); | |
} | |
} | |
exports.InlineSVG = InlineSVG; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment