Skip to content

Instantly share code, notes, and snippets.

@amadeuszblanik
Last active February 10, 2020 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amadeuszblanik/e4f30ece49d7b3bce2a1688b36bc16d4 to your computer and use it in GitHub Desktop.
Save amadeuszblanik/e4f30ece49d7b3bce2a1688b36bc16d4 to your computer and use it in GitHub Desktop.
[TypeScript][JavaScript] Inline SVG using Fetch API
//
// 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);
}
}
}
"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