UNPKG

@onesy/utils

Version:
159 lines (155 loc) 7.68 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = __importDefault(require("./is")); const isEnvironment_1 = __importDefault(require("./isEnvironment")); const fileToValue_1 = __importDefault(require("./fileToValue")); const canvasCrop_1 = __importDefault(require("./canvasCrop")); const download_1 = __importDefault(require("./download")); const unique_1 = __importDefault(require("./unique")); const serialize = (node) => new XMLSerializer().serializeToString(node); const image = (uri) => new Promise((resolve, reject) => { const img = document.createElement('img'); const method = () => resolve(img); img.onload = method; img.onerror = () => resolve(''); img.src = uri; }); const getData = async (url, version = 'datauri') => { try { const response = await fetch(url); const blob = await response.blob(); return await (0, fileToValue_1.default)(blob, version); } catch (error) { } }; const optionsDefault = { response: 'canvas', x: 0, y: 0, datauri: { type: 'image/png', quality: 1 }, download: { name: 'onesy-image.png', type: 'image/png', quality: 1 }, styleSheets: true, urls: true, images: true, links: true }; const elementToCanvas = async (element_, options_) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; const options = Object.assign(Object.assign({}, optionsDefault), options_); if ((0, isEnvironment_1.default)('browser')) { if (element_ !== undefined && (0, is_1.default)('element', element_)) { const element = element_.cloneNode(true); if ((0, is_1.default)('array', options.filter)) { options.filter.forEach(item => { const items = Array.from(element.querySelectorAll(item)); items.forEach(item_ => (0, is_1.default)('function', item_.remove) && item_.remove()); }); } let elementXML = serialize(element); let urls = []; let styles = ``; let links = ``; let css = ``; const linksAdd = {}; // Element urls if (options.urls) { urls = (elementXML.match(/url\((.*?)\)/gi) || []).map(item => item.replace(/url\(|'|"|\)/gi, '')); for (const url of (0, unique_1.default)(urls)) { const value = await getData(url); if (value) elementXML = elementXML.replaceAll(url, value); } } // Images if (options.images) { urls = (elementXML.match(/src=("|'|`)(.*?)("|'|`)/gi) || []).map(item => item.replace(/src=|'|"||`/gi, '')); for (const src of (0, unique_1.default)(urls)) { const value = await getData(src); if (value) elementXML = elementXML.replaceAll(src, value); } } // Links if (options.links) { const links_ = Array.from(window.document.querySelectorAll('link')); for (const link of links_) { if (!linksAdd[link.href] && ['stylesheet'].includes(link.rel)) { const value = await getData(link.href, 'text'); if (value) { linksAdd[link.href] = true; links += `<style>${value}</style>`; } } } } // StyleSheets for (const styleSheet of window.document.styleSheets) { if (!styleSheet.href || styleSheet.href.startsWith(window.location.origin)) { for (let { cssText } of styleSheet.cssRules) css += cssText; } } styles = ` <style> noscript { display: none; } </style> ${links} <style>${css}</style> `; // Styles urls if (options.urls) { urls = (styles.match(/url\((.*?)\)/gi) || []).map(item => item.replace(/url\(|'|"|\)/gi, '')); for (const url of (0, unique_1.default)(urls)) { const value = await getData(url); if (value) styles = styles.replaceAll(url, value); } } const width = options.width !== undefined ? options.width : element_.offsetWidth; const height = options.height !== undefined ? options.height : element_.offsetHeight; const svg = `<svg xmlns='http://www.w3.org/2000/svg' width='${((_a = options.image) === null || _a === void 0 ? void 0 : _a.width) !== undefined ? (_b = options.image) === null || _b === void 0 ? void 0 : _b.width : width}' height='${((_c = options.image) === null || _c === void 0 ? void 0 : _c.height) !== undefined ? (_d = options.image) === null || _d === void 0 ? void 0 : _d.height : height}'> ${styles} <foreignObject x='0' y='0' width='${((_e = options.image) === null || _e === void 0 ? void 0 : _e.width) !== undefined ? (_f = options.image) === null || _f === void 0 ? void 0 : _f.width : width}' height='${((_g = options.image) === null || _g === void 0 ? void 0 : _g.height) !== undefined ? (_h = options.image) === null || _h === void 0 ? void 0 : _h.height : height}'> ${elementXML} </foreignObject> </svg>`; if (options.response === 'svg') return svg; const uri = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}`; if (options.response === 'svg-datauri') return uri; const img = await image(uri); if (img) { let canvas = window.document.createElement('canvas'); canvas.width = width; canvas.height = height; const context = canvas.getContext('2d'); context.drawImage(img, options.x, options.y, ((_j = options.image) === null || _j === void 0 ? void 0 : _j.width) !== undefined ? (_k = options.image) === null || _k === void 0 ? void 0 : _k.width : img.width, ((_l = options.image) === null || _l === void 0 ? void 0 : _l.height) !== undefined ? (_m = options.image) === null || _m === void 0 ? void 0 : _m.height : img.height); if (options.crop) canvas = (0, canvasCrop_1.default)(canvas, options.crop.x, options.crop.y, options.crop.width, options.crop.height); if (options.response === 'canvas') return canvas; if (options.response === 'datauri') return canvas.toDataURL((_o = options.datauri) === null || _o === void 0 ? void 0 : _o.type, (_p = options.datauri) === null || _p === void 0 ? void 0 : _p.quality); if (options.response === 'download') { const value = canvas.toDataURL((_q = options.download) === null || _q === void 0 ? void 0 : _q.type, (_r = options.download) === null || _r === void 0 ? void 0 : _r.quality); // Image (0, download_1.default)((_s = options.download) === null || _s === void 0 ? void 0 : _s.name, value); } } } } }; exports.default = elementToCanvas;