mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 01:58:27 +00:00
refactor: refactor util/src/lib/loader and parser
This commit is contained in:
parent
bce30da0e5
commit
b25369ae96
4 changed files with 182 additions and 47 deletions
77
packages/util/__tests__/lib/loader.test.ts
Normal file
77
packages/util/__tests__/lib/loader.test.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import './../../../../__tests__/polyfill/image'
|
||||
import {
|
||||
loadHTML, loadImage, loadSVG
|
||||
} from '../../src/lib/loader';
|
||||
import { parseHTMLToDataURL, parseSVGToDataURL } from './../../src/lib/parser';
|
||||
|
||||
describe('@idraw/util: lib/loader', () => {
|
||||
|
||||
test('loadHTML', async () => {
|
||||
const html = `
|
||||
<style>
|
||||
.btn-box {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.btn {
|
||||
line-height: 1.5715;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 2px #00000004;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
height: 32px;
|
||||
padding: 4px 15px;
|
||||
font-size: 14px;
|
||||
border-radius: 2px;
|
||||
color: #000000d9;
|
||||
background: #fff;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background: #1890ff;
|
||||
border-color: #1890ff;
|
||||
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
|
||||
box-shadow: 0 2px #0000000b;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<div class="btn-box" style="margin-top: 0;">
|
||||
<button class="btn" >
|
||||
<span>Button</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-box">
|
||||
<button class="btn btn-primary">
|
||||
<span>Button Primary</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 120,
|
||||
height: 80,
|
||||
}
|
||||
const result = await loadHTML(html, opts);
|
||||
const expectDataURL = await parseHTMLToDataURL(html, opts);
|
||||
const expectImage = await loadImage(expectDataURL);
|
||||
expect(result.src).toStrictEqual(expectImage.src);
|
||||
});
|
||||
|
||||
|
||||
test('loadSVG', async () => {
|
||||
const svg = `<svg t="1622524780663" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8365" width="200" height="200"><path d="M881 442.4H519.7v148.5h206.4c-8.9 48-35.9 88.6-76.6 115.8-34.4 23-78.3 36.6-129.9 36.6-99.9 0-184.4-67.5-214.6-158.2-7.6-23-12-47.6-12-72.9s4.4-49.9 12-72.9c30.3-90.6 114.8-158.1 214.7-158.1 56.3 0 106.8 19.4 146.6 57.4l110-110.1c-66.5-62-153.2-100-256.6-100-149.9 0-279.6 86-342.7 211.4-26 51.8-40.8 110.4-40.8 172.4S151 632.8 177 684.6C240.1 810 369.8 896 519.7 896c103.6 0 190.4-34.4 253.8-93 72.5-66.8 114.4-165.2 114.4-282.1 0-27.2-2.4-53.3-6.9-78.5z" p-id="8366" fill="#1296db"></path></svg>`;
|
||||
const result = await loadSVG(svg);
|
||||
const expectDataURL = await parseSVGToDataURL(svg);
|
||||
const expectImage = await loadImage(expectDataURL);
|
||||
expect(result.src).toStrictEqual(expectImage.src);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
51
packages/util/__tests__/lib/parser.test.ts
Normal file
51
packages/util/__tests__/lib/parser.test.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import {
|
||||
parseHTMLToDataURL, parseSVGToDataURL
|
||||
} from '../../src/lib/parser';
|
||||
|
||||
|
||||
describe('@idraw/util: lib/parser', () => {
|
||||
|
||||
test('parseHTMLToDataURL', async () => {
|
||||
const result = await parseHTMLToDataURL(`
|
||||
<style>
|
||||
.btn {
|
||||
line-height: 1.5715;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 2px #00000004;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
height: 32px;
|
||||
padding: 4px 15px;
|
||||
font-size: 14px;
|
||||
border-radius: 2px;
|
||||
color: #000000d9;
|
||||
background: #fff;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
</style>
|
||||
<button class="btn" >
|
||||
<span>Button</span>
|
||||
</button>
|
||||
`, {
|
||||
width: 120,
|
||||
height: 80,
|
||||
});
|
||||
expect(result).toStrictEqual(`data:image/svg+xml;charset=utf-8;base64,CiAgICA8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEyMCIgaGVpZ2h0ID0gIjgwIj4KICAgICAgPGZvcmVpZ25PYmplY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+CiAgICAgICAgPGRpdiB4bWxucyA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KICAgICAgICAgIAogICAgPHN0eWxlPgogICAgLmJ0biB7CiAgICAgIGxpbmUtaGVpZ2h0OiAxLjU3MTU7CiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogICAgICBmb250LXdlaWdodDogNDAwOwogICAgICB3aGl0ZS1zcGFjZTogbm93cmFwOwogICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgICAgIGJhY2tncm91bmQtaW1hZ2U6IG5vbmU7CiAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50OwogICAgICBib3gtc2hhZG93OiAwIDJweCAjMDAwMDAwMDQ7CiAgICAgIGN1cnNvcjogcG9pbnRlcjsKICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7CiAgICAgIGhlaWdodDogMzJweDsKICAgICAgcGFkZGluZzogNHB4IDE1cHg7CiAgICAgIGZvbnQtc2l6ZTogMTRweDsKICAgICAgYm9yZGVyLXJhZGl1czogMnB4OwogICAgICBjb2xvcjogIzAwMDAwMGQ5OwogICAgICBiYWNrZ3JvdW5kOiAjZmZmOwogICAgICBib3JkZXItY29sb3I6ICNkOWQ5ZDk7CiAgICB9CiAgICA8L3N0eWxlPgogICAgPGJ1dHRvbiBjbGFzcz0iYnRuIiA+CiAgICAgIDxzcGFuPkJ1dHRvbjwvc3Bhbj4KICAgIDwvYnV0dG9uPgogICAgCiAgICAgICAgPC9kaXY+CiAgICAgIDwvZm9yZWlnbk9iamVjdD4KICAgIDwvc3ZnPgogICAg`);
|
||||
});
|
||||
|
||||
|
||||
test('parseSVGToDataURL', async () => {
|
||||
const result = await parseSVGToDataURL(`<svg t="1622524780663" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8365" width="200" height="200"><path d="M881 442.4H519.7v148.5h206.4c-8.9 48-35.9 88.6-76.6 115.8-34.4 23-78.3 36.6-129.9 36.6-99.9 0-184.4-67.5-214.6-158.2-7.6-23-12-47.6-12-72.9s4.4-49.9 12-72.9c30.3-90.6 114.8-158.1 214.7-158.1 56.3 0 106.8 19.4 146.6 57.4l110-110.1c-66.5-62-153.2-100-256.6-100-149.9 0-279.6 86-342.7 211.4-26 51.8-40.8 110.4-40.8 172.4S151 632.8 177 684.6C240.1 810 369.8 896 519.7 896c103.6 0 190.4-34.4 253.8-93 72.5-66.8 114.4-165.2 114.4-282.1 0-27.2-2.4-53.3-6.9-78.5z" p-id="8366" fill="#1296db"></path></svg>`);
|
||||
|
||||
expect(result).toStrictEqual(`data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNjIyNTI0NzgwNjYzIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjgzNjUiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNODgxIDQ0Mi40SDUxOS43djE0OC41aDIwNi40Yy04LjkgNDgtMzUuOSA4OC42LTc2LjYgMTE1LjgtMzQuNCAyMy03OC4zIDM2LjYtMTI5LjkgMzYuNi05OS45IDAtMTg0LjQtNjcuNS0yMTQuNi0xNTguMi03LjYtMjMtMTItNDcuNi0xMi03Mi45czQuNC00OS45IDEyLTcyLjljMzAuMy05MC42IDExNC44LTE1OC4xIDIxNC43LTE1OC4xIDU2LjMgMCAxMDYuOCAxOS40IDE0Ni42IDU3LjRsMTEwLTExMC4xYy02Ni41LTYyLTE1My4yLTEwMC0yNTYuNi0xMDAtMTQ5LjkgMC0yNzkuNiA4Ni0zNDIuNyAyMTEuNC0yNiA1MS44LTQwLjggMTEwLjQtNDAuOCAxNzIuNFMxNTEgNjMyLjggMTc3IDY4NC42QzI0MC4xIDgxMCAzNjkuOCA4OTYgNTE5LjcgODk2YzEwMy42IDAgMTkwLjQtMzQuNCAyNTMuOC05MyA3Mi41LTY2LjggMTE0LjQtMTY1LjIgMTE0LjQtMjgyLjEgMC0yNy4yLTIuNC01My4zLTYuOS03OC41eiIgcC1pZD0iODM2NiIgZmlsbD0iIzEyOTZkYiI+PC9wYXRoPjwvc3ZnPg==`);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
const { Image, Blob, FileReader } = window;
|
||||
import { parseHTMLToDataURL, parseSVGToDataURL } from './parser';
|
||||
const { Image } = window;
|
||||
|
||||
export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
@ -13,52 +14,17 @@ export function loadImage(src: string): Promise<HTMLImageElement> {
|
|||
}
|
||||
|
||||
|
||||
export function loadSVG(svg: string): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const _svg = svg;
|
||||
const image = new Image();
|
||||
const blob = new Blob([_svg], { type: 'image/svg+xml;charset=utf-8'});
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onload = function (event: ProgressEvent<FileReader>) {
|
||||
const base64: string = event?.target?.result as string;
|
||||
image.onload = function() {
|
||||
resolve(image);
|
||||
};
|
||||
image.src = base64;
|
||||
};
|
||||
reader.onerror = function(err) {
|
||||
reject(err);
|
||||
};
|
||||
});
|
||||
export async function loadSVG(svg: string): Promise<HTMLImageElement> {
|
||||
const dataURL = await parseSVGToDataURL(svg);
|
||||
const image = await loadImage(dataURL);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
export async function loadHTML(html: string, opts: { width: number, height: number }): Promise<HTMLImageElement> {
|
||||
const dataURL = await parseHTMLToDataURL(html, opts);
|
||||
const image = await loadImage(dataURL);
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
export function loadHTML(html: string, opts: { width: number, height: number }): Promise<HTMLImageElement> {
|
||||
const { width, height } = opts;
|
||||
return new Promise((resolve, reject) => {
|
||||
const _svg = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="${width || ''}" height = "${height || ''}">
|
||||
<foreignObject width="100%" height="100%">
|
||||
<div xmlns = "http://www.w3.org/1999/xhtml">
|
||||
${html}
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
`;;
|
||||
const image = new Image();
|
||||
const blob = new Blob([_svg], { type: 'image/svg+xml;charset=utf-8'});
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onload = function (event: ProgressEvent<FileReader>) {
|
||||
const base64: string = event?.target?.result as string;
|
||||
image.onload = function() {
|
||||
resolve(image);
|
||||
};
|
||||
image.src = base64;
|
||||
};
|
||||
reader.onerror = function(err) {
|
||||
reject(err);
|
||||
};
|
||||
});
|
||||
}
|
||||
41
packages/util/src/lib/parser.ts
Normal file
41
packages/util/src/lib/parser.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
export function parseHTMLToDataURL(html: string, opts: { width: number, height: number }): Promise<string> {
|
||||
const { width, height } = opts;
|
||||
return new Promise((resolve, reject) => {
|
||||
const _svg = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="${width || ''}" height = "${height || ''}">
|
||||
<foreignObject width="100%" height="100%">
|
||||
<div xmlns = "http://www.w3.org/1999/xhtml">
|
||||
${html}
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
`;
|
||||
const blob = new Blob([_svg], { type: 'image/svg+xml;charset=utf-8'});
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onload = function (event: ProgressEvent<FileReader>) {
|
||||
const base64: string = event?.target?.result as string;
|
||||
resolve(base64)
|
||||
};
|
||||
reader.onerror = function(err) {
|
||||
reject(err);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function parseSVGToDataURL(svg: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const _svg = svg;
|
||||
const blob = new Blob([_svg], { type: 'image/svg+xml;charset=utf-8'});
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onload = function (event: ProgressEvent<FileReader>) {
|
||||
const base64: string = event?.target?.result as string;
|
||||
resolve(base64);
|
||||
};
|
||||
reader.onerror = function(err) {
|
||||
reject(err);
|
||||
};
|
||||
});
|
||||
}
|
||||
Loading…
Reference in a new issue