@onesy/utils
Version:
159 lines (155 loc) • 7.68 kB
JavaScript
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;
;