@sswroom/sswr 1.6.18 → 1.6.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog +9 -0
- package/cesium.js +2 -1
- package/data.js +36 -6
- package/domtoimage/fontFaces.js +56 -0
- package/domtoimage/images.js +47 -0
- package/domtoimage/index.js +328 -0
- package/domtoimage/inliner.js +65 -0
- package/domtoimage/util.js +248 -0
- package/dummy/Cesium.d.ts +1 -0
- package/dummy/Cesium.js +1 -0
- package/exporter/XLSXExporter.js +578 -524
- package/leaflet/EasyPrint.js +731 -0
- package/package.json +1 -1
- package/web.d.ts +1 -0
- package/web.js +17 -0
package/Changelog
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
1.6.20
|
|
2
|
+
-Enhance XLSXExporter
|
|
3
|
+
-Added leaflet/EasyPrint.js
|
|
4
|
+
-Added domtoimage/index.js
|
|
5
|
+
|
|
6
|
+
1.6.19
|
|
7
|
+
-data.Timestamp.fromTicks support floating point ticks
|
|
8
|
+
-data.Duration.fromTicks support floating point ticks
|
|
9
|
+
|
|
1
10
|
1.6.18
|
|
2
11
|
-Change geometry.LinearRing.getHIntersactsCenter to getIntersactsCenter
|
|
3
12
|
-web.buildTable support StaticImage item
|
package/cesium.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as data from "./data.js";
|
|
2
|
+
import * as geometry from "./geometry.js";
|
|
2
3
|
import * as kml from "./kml.js";
|
|
3
4
|
import * as map from "./map.js";
|
|
4
5
|
import * as math from "./math.js";
|
|
5
|
-
import * as
|
|
6
|
+
import * as text from "./text.js";
|
|
6
7
|
|
|
7
8
|
export function screenToLatLon(viewer, x, y, ellipsoid)
|
|
8
9
|
{
|
package/data.js
CHANGED
|
@@ -1856,8 +1856,18 @@ export class Duration
|
|
|
1856
1856
|
{
|
|
1857
1857
|
if (ticks < 0)
|
|
1858
1858
|
{
|
|
1859
|
-
let ns
|
|
1860
|
-
let seconds
|
|
1859
|
+
let ns;
|
|
1860
|
+
let seconds;
|
|
1861
|
+
if (typeof ticks == "number")
|
|
1862
|
+
{
|
|
1863
|
+
seconds = Math.floor(ticks / 1000);
|
|
1864
|
+
ns = (ticks - seconds * 1000);
|
|
1865
|
+
}
|
|
1866
|
+
else
|
|
1867
|
+
{
|
|
1868
|
+
ns = Number(BigInt(ticks) % 1000n);
|
|
1869
|
+
seconds = BigInt(ticks) / 1000n;
|
|
1870
|
+
}
|
|
1861
1871
|
if (ns != 0)
|
|
1862
1872
|
{
|
|
1863
1873
|
ns = (-ns) * 1000000;
|
|
@@ -1867,7 +1877,15 @@ export class Duration
|
|
|
1867
1877
|
}
|
|
1868
1878
|
else
|
|
1869
1879
|
{
|
|
1870
|
-
|
|
1880
|
+
if (typeof ticks == "number")
|
|
1881
|
+
{
|
|
1882
|
+
let secs = Math.floor(ticks / 1000);
|
|
1883
|
+
return new Duration(secs, (ticks - secs * 1000) * 1000000);
|
|
1884
|
+
}
|
|
1885
|
+
else
|
|
1886
|
+
{
|
|
1887
|
+
return new Duration(BigInt(ticks) / 1000n, Number(BigInt(ticks) % 1000n) * 1000000);
|
|
1888
|
+
}
|
|
1871
1889
|
}
|
|
1872
1890
|
}
|
|
1873
1891
|
|
|
@@ -2189,14 +2207,26 @@ export class TimeInstant
|
|
|
2189
2207
|
*/
|
|
2190
2208
|
static fromTicks(ticks)
|
|
2191
2209
|
{
|
|
2192
|
-
let
|
|
2210
|
+
let secs;
|
|
2211
|
+
let ms;
|
|
2212
|
+
if (typeof ticks == "number")
|
|
2213
|
+
{
|
|
2214
|
+
secs = Math.floor(ticks / 1000);
|
|
2215
|
+
ms = (ticks - secs) * 1000;
|
|
2216
|
+
secs = BigInt(secs);
|
|
2217
|
+
}
|
|
2218
|
+
else
|
|
2219
|
+
{
|
|
2220
|
+
secs = BigInt(ticks) / 1000n;
|
|
2221
|
+
ms = Number(BigInt(ticks) % 1000n);
|
|
2222
|
+
}
|
|
2193
2223
|
if (ms < 0)
|
|
2194
2224
|
{
|
|
2195
|
-
return new TimeInstant(
|
|
2225
|
+
return new TimeInstant(secs - 1n, (ms + 1000) * 1000000);
|
|
2196
2226
|
}
|
|
2197
2227
|
else
|
|
2198
2228
|
{
|
|
2199
|
-
return new TimeInstant(
|
|
2229
|
+
return new TimeInstant(secs, ms * 1000000);
|
|
2200
2230
|
}
|
|
2201
2231
|
}
|
|
2202
2232
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as util from "./util.js";
|
|
2
|
+
import * as inliner from "./inliner.js";
|
|
3
|
+
|
|
4
|
+
export function resolveAll() {
|
|
5
|
+
return readAll()
|
|
6
|
+
.then(function (webFonts) {
|
|
7
|
+
return Promise.all(
|
|
8
|
+
webFonts.map(function (webFont) {
|
|
9
|
+
return webFont.resolve();
|
|
10
|
+
})
|
|
11
|
+
);
|
|
12
|
+
})
|
|
13
|
+
.then(function (cssStrings) {
|
|
14
|
+
return cssStrings.join('\n');
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} [implOptions]
|
|
20
|
+
*/
|
|
21
|
+
async function readAll(implOptions) {
|
|
22
|
+
let styleSheets = [];
|
|
23
|
+
for (let i = 0; i < document.styleSheets.length; i++) styleSheets.push(document.styleSheets[i]);
|
|
24
|
+
let cssRules = [];
|
|
25
|
+
styleSheets.forEach(function (sheet) {
|
|
26
|
+
try {
|
|
27
|
+
if (sheet.cssRules)
|
|
28
|
+
{
|
|
29
|
+
for (let i = 0; i < sheet.cssRules.length; i++) cssRules.push(sheet.cssRules[i]);
|
|
30
|
+
}
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.log('Error while reading CSS rules from ' + sheet.href, e.toString());
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/** @type {CSSRule[]} */
|
|
36
|
+
let rules = cssRules
|
|
37
|
+
.filter(function (rule) {
|
|
38
|
+
return rule.type === CSSRule.FONT_FACE_RULE;
|
|
39
|
+
})
|
|
40
|
+
.filter(function (rule) {
|
|
41
|
+
return inliner.shouldProcess(rule.style.getPropertyValue('src'));
|
|
42
|
+
});
|
|
43
|
+
return rules.map((webFontRule) => {
|
|
44
|
+
return {
|
|
45
|
+
resolve: function resolve() {
|
|
46
|
+
let baseUrl = (webFontRule.parentStyleSheet || {}).href;
|
|
47
|
+
return inliner.inlineAll(webFontRule.cssText, baseUrl, undefined, implOptions);
|
|
48
|
+
},
|
|
49
|
+
src: function () {
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
return webFontRule.style.getPropertyValue('src');
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as util from "./util.js";
|
|
2
|
+
import * as inliner from "./inliner.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {HTMLImageElement} element
|
|
6
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} [options]
|
|
7
|
+
* @returns {Promise<HTMLImageElement>}
|
|
8
|
+
*/
|
|
9
|
+
async function inline(element, options) {
|
|
10
|
+
if (util.isDataUrl(element.src)) return element;
|
|
11
|
+
let data = await util.getAndEncode(element.src, options);
|
|
12
|
+
let dataUrl = util.dataAsUrl(data, util.mimeType(element.src));
|
|
13
|
+
return await new Promise(function (resolve, reject) {
|
|
14
|
+
element.onload = () => {resolve(element);};
|
|
15
|
+
element.onerror = reject;
|
|
16
|
+
element.src = dataUrl;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {HTMLElement} node
|
|
22
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
|
|
23
|
+
*/
|
|
24
|
+
export async function inlineAll(node, options) {
|
|
25
|
+
if (!(node instanceof HTMLElement)) return node;
|
|
26
|
+
let background = node.style.getPropertyValue('background');
|
|
27
|
+
|
|
28
|
+
if (!background) return node;
|
|
29
|
+
|
|
30
|
+
let inlined = await inliner.inlineAll(background, undefined, undefined, options)
|
|
31
|
+
node.style.setProperty(
|
|
32
|
+
'background',
|
|
33
|
+
inlined,
|
|
34
|
+
node.style.getPropertyPriority('background'));
|
|
35
|
+
if (node instanceof HTMLImageElement)
|
|
36
|
+
return await inline(node);
|
|
37
|
+
else
|
|
38
|
+
{
|
|
39
|
+
let children = util.asArray(node.childNodes);
|
|
40
|
+
let leng = children.length;
|
|
41
|
+
for (let i = 0; i < leng; i++)
|
|
42
|
+
{
|
|
43
|
+
node.replaceChild(children[i], await inlineAll(children[i], options));
|
|
44
|
+
}
|
|
45
|
+
return node;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import * as util from "./util.js";
|
|
2
|
+
import * as images from "./images.js";
|
|
3
|
+
import * as fontFaces from "./fontFaces.js";
|
|
4
|
+
|
|
5
|
+
// Default impl options
|
|
6
|
+
const defaultOptions = {
|
|
7
|
+
// Default is to fail on error, no placeholder
|
|
8
|
+
imagePlaceholder: undefined,
|
|
9
|
+
// Default cache bust is false, it will use the cache
|
|
10
|
+
cacheBust: false
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {HTMLElement} node - The DOM Node object to render
|
|
15
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options - Rendering options
|
|
16
|
+
**/
|
|
17
|
+
export async function toSvg(node, options) {
|
|
18
|
+
options = options || {};
|
|
19
|
+
let implOptions = copyOptions(options);
|
|
20
|
+
let clone = await cloneNode(node, options.filter, true);
|
|
21
|
+
clone = await embedFonts(clone);
|
|
22
|
+
clone = await inlineImages(clone, implOptions);
|
|
23
|
+
if (options.bgcolor) clone.style.backgroundColor = options.bgcolor;
|
|
24
|
+
if (options.width) clone.style.width = options.width + 'px';
|
|
25
|
+
if (options.height) clone.style.height = options.height + 'px';
|
|
26
|
+
if (options.style)
|
|
27
|
+
{
|
|
28
|
+
Object.keys(options.style).forEach(function (property) {
|
|
29
|
+
clone.style[property] = options.style[property];
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return makeSvgDataUri(clone,
|
|
33
|
+
options.width || util.width(node),
|
|
34
|
+
options.height || util.height(node)
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {HTMLElement} node - The DOM Node object to render
|
|
40
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options - Rendering options, @see {@link toSvg}
|
|
41
|
+
* */
|
|
42
|
+
export function toPixelData(node, options) {
|
|
43
|
+
return draw(node, options || {})
|
|
44
|
+
.then(function (canvas) {
|
|
45
|
+
let ctx = canvas.getContext('2d');
|
|
46
|
+
if (ctx)
|
|
47
|
+
{
|
|
48
|
+
return ctx.getImageData(
|
|
49
|
+
0,
|
|
50
|
+
0,
|
|
51
|
+
util.width(node),
|
|
52
|
+
util.height(node)
|
|
53
|
+
).data;
|
|
54
|
+
}
|
|
55
|
+
else
|
|
56
|
+
{
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {HTMLElement} node - The DOM Node object to render
|
|
64
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options - Rendering options, @see {@link toSvg}
|
|
65
|
+
* */
|
|
66
|
+
export async function toPng(node, options) {
|
|
67
|
+
let canvas = await draw(node, options || {});
|
|
68
|
+
return canvas.toDataURL();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {HTMLElement} node - The DOM Node object to render
|
|
73
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options - Rendering options, @see {@link toSvg}
|
|
74
|
+
* */
|
|
75
|
+
export async function toJpeg(node, options) {
|
|
76
|
+
options = options || {};
|
|
77
|
+
let canvas = await draw(node, options);
|
|
78
|
+
return canvas.toDataURL('image/jpeg', options.quality || 1.0);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {HTMLElement} node - The DOM Node object to render
|
|
83
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options - Rendering options, @see {@link toSvg}
|
|
84
|
+
* */
|
|
85
|
+
export async function toBlob(node, options) {
|
|
86
|
+
let canvas = await draw(node, options || {});
|
|
87
|
+
return await util.canvasToBlob(canvas);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}} options
|
|
92
|
+
*/
|
|
93
|
+
function copyOptions(options) {
|
|
94
|
+
let implOptions = {};
|
|
95
|
+
// Copy options to impl options for use in impl
|
|
96
|
+
if(typeof(options.imagePlaceholder) === 'undefined') {
|
|
97
|
+
implOptions.imagePlaceholder = defaultOptions.imagePlaceholder;
|
|
98
|
+
} else {
|
|
99
|
+
implOptions.imagePlaceholder = options.imagePlaceholder;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if(typeof(options.cacheBust) === 'undefined') {
|
|
103
|
+
implOptions.cacheBust = defaultOptions.cacheBust;
|
|
104
|
+
} else {
|
|
105
|
+
implOptions.cacheBust = options.cacheBust;
|
|
106
|
+
}
|
|
107
|
+
return implOptions;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {HTMLElement} domNode
|
|
112
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options
|
|
113
|
+
*/
|
|
114
|
+
async function draw(domNode, options) {
|
|
115
|
+
let svgUrl = await toSvg(domNode, options);
|
|
116
|
+
let image = await util.makeImage(svgUrl);
|
|
117
|
+
await util.delay(100)();
|
|
118
|
+
let canvas = newCanvas(domNode, options);
|
|
119
|
+
let ctx = canvas.getContext('2d');
|
|
120
|
+
if (ctx) ctx.drawImage(image, 0, 0);
|
|
121
|
+
return canvas;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {HTMLElement} domNode
|
|
126
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}|null|undefined} options
|
|
127
|
+
*/
|
|
128
|
+
function newCanvas(domNode, options) {
|
|
129
|
+
let canvas = document.createElement('canvas');
|
|
130
|
+
canvas.width = options.width || domNode.offsetWidth;
|
|
131
|
+
canvas.height = options.height || domNode.offsetHeight;
|
|
132
|
+
|
|
133
|
+
if (options.bgcolor) {
|
|
134
|
+
var ctx = canvas.getContext('2d');
|
|
135
|
+
if (ctx != null)
|
|
136
|
+
{
|
|
137
|
+
ctx.fillStyle = options.bgcolor;
|
|
138
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return canvas;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @param {HTMLElement} node
|
|
148
|
+
* @param {(node:Node)=>boolean|undefined} filter
|
|
149
|
+
* @param {boolean | undefined} [root]
|
|
150
|
+
*/
|
|
151
|
+
async function cloneNode(node, filter, root) {
|
|
152
|
+
if (!root && filter && !filter(node)) return node;
|
|
153
|
+
if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL());
|
|
154
|
+
let clone = node.cloneNode(false);
|
|
155
|
+
clone = await cloneChildren(node, clone, filter);
|
|
156
|
+
// @ts-ignore
|
|
157
|
+
return await processClone(node, clone);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {Node} original
|
|
162
|
+
* @param {Node} clone
|
|
163
|
+
* @param {(node: Node) => boolean | undefined} filter
|
|
164
|
+
*/
|
|
165
|
+
async function cloneChildren(original, clone, filter) {
|
|
166
|
+
var children = original.childNodes;
|
|
167
|
+
if (children.length === 0) return clone;
|
|
168
|
+
for (let i = 0; i < children.length; i++)
|
|
169
|
+
{
|
|
170
|
+
let child = children[i];
|
|
171
|
+
// @ts-ignore
|
|
172
|
+
let childClone = await cloneNode(child, filter);
|
|
173
|
+
if (childClone) clone.appendChild(childClone);
|
|
174
|
+
}
|
|
175
|
+
return clone;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {HTMLElement} original
|
|
180
|
+
* @param {HTMLElement} clone
|
|
181
|
+
*/
|
|
182
|
+
function processClone(original, clone) {
|
|
183
|
+
if (!(clone instanceof Element)) return clone;
|
|
184
|
+
|
|
185
|
+
return Promise.resolve()
|
|
186
|
+
.then(cloneStyle)
|
|
187
|
+
.then(clonePseudoElements)
|
|
188
|
+
.then(copyUserInput)
|
|
189
|
+
.then(fixSvg)
|
|
190
|
+
.then(function () {
|
|
191
|
+
return clone;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
function cloneStyle() {
|
|
195
|
+
copyStyle(window.getComputedStyle(original), clone.style);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @param {CSSStyleDeclaration} source
|
|
199
|
+
* @param {CSSStyleDeclaration} target
|
|
200
|
+
*/
|
|
201
|
+
function copyStyle(source, target) {
|
|
202
|
+
if (source.cssText) target.cssText = source.cssText;
|
|
203
|
+
else copyProperties(source, target);
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @param {CSSStyleDeclaration} source
|
|
207
|
+
* @param {{ setProperty: (arg0: any, arg1: any, arg2: any) => void; }} target
|
|
208
|
+
*/
|
|
209
|
+
function copyProperties(source, target) {
|
|
210
|
+
for (let i = 0; i < source.length; i++)
|
|
211
|
+
{
|
|
212
|
+
let name = source[i];
|
|
213
|
+
target.setProperty(
|
|
214
|
+
name,
|
|
215
|
+
source.getPropertyValue(name),
|
|
216
|
+
source.getPropertyPriority(name)
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function clonePseudoElements() {
|
|
224
|
+
[':before', ':after'].forEach(function (element) {
|
|
225
|
+
clonePseudoElement(element);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @param {string} element
|
|
230
|
+
*/
|
|
231
|
+
function clonePseudoElement(element) {
|
|
232
|
+
var style = window.getComputedStyle(original, element);
|
|
233
|
+
var content = style.getPropertyValue('content');
|
|
234
|
+
|
|
235
|
+
if (content === '' || content === 'none') return;
|
|
236
|
+
|
|
237
|
+
var className = util.uid();
|
|
238
|
+
clone.className = clone.className + ' ' + className;
|
|
239
|
+
var styleElement = document.createElement('style');
|
|
240
|
+
styleElement.appendChild(formatPseudoElementStyle(className, element, style));
|
|
241
|
+
clone.appendChild(styleElement);
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @param {string} className
|
|
245
|
+
* @param {string} element
|
|
246
|
+
* @param {CSSStyleDeclaration} style
|
|
247
|
+
*/
|
|
248
|
+
function formatPseudoElementStyle(className, element, style) {
|
|
249
|
+
let selector = '.' + className + ':' + element;
|
|
250
|
+
let cssText = style.cssText ? formatCssText(style) : formatCssProperties(style);
|
|
251
|
+
return document.createTextNode(selector + '{' + cssText + '}');
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @param {CSSStyleDeclaration} style
|
|
255
|
+
*/
|
|
256
|
+
function formatCssText(style) {
|
|
257
|
+
let content = style.getPropertyValue('content');
|
|
258
|
+
return style.cssText + ' content: ' + content + ';';
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* @param {CSSStyleDeclaration} style
|
|
263
|
+
*/
|
|
264
|
+
function formatCssProperties(style) {
|
|
265
|
+
let css = [];
|
|
266
|
+
for (let i = 0; i < style.length; i++)
|
|
267
|
+
{
|
|
268
|
+
let name = style[i];
|
|
269
|
+
css.push(name + ': ' +
|
|
270
|
+
style.getPropertyValue(name) +
|
|
271
|
+
(style.getPropertyPriority(name) ? ' !important' : ''));
|
|
272
|
+
}
|
|
273
|
+
return css.join('; ') + ';';
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function copyUserInput() {
|
|
280
|
+
if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value;
|
|
281
|
+
if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function fixSvg() {
|
|
285
|
+
if (!(clone instanceof SVGElement)) return;
|
|
286
|
+
clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
287
|
+
|
|
288
|
+
if (!(clone instanceof SVGRectElement)) return;
|
|
289
|
+
['width', 'height'].forEach(function (attribute) {
|
|
290
|
+
var value = clone.getAttribute(attribute);
|
|
291
|
+
if (!value) return;
|
|
292
|
+
|
|
293
|
+
clone.style.setProperty(attribute, value);
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @param {HTMLElement} node
|
|
300
|
+
*/
|
|
301
|
+
async function embedFonts(node) {
|
|
302
|
+
let cssText = await fontFaces.resolveAll();
|
|
303
|
+
let styleNode = document.createElement('style');
|
|
304
|
+
node.appendChild(styleNode);
|
|
305
|
+
styleNode.appendChild(document.createTextNode(cssText));
|
|
306
|
+
return node;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @param {HTMLElement} node
|
|
311
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} implOptions
|
|
312
|
+
*/
|
|
313
|
+
async function inlineImages(node, implOptions) {
|
|
314
|
+
return await images.inlineAll(node, implOptions);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @param {Element} node
|
|
319
|
+
* @param {string | number} width
|
|
320
|
+
* @param {string | number} height
|
|
321
|
+
*/
|
|
322
|
+
function makeSvgDataUri(node, width, height) {
|
|
323
|
+
node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
|
|
324
|
+
let xhtml = util.escapeXhtml(new XMLSerializer().serializeToString(node));
|
|
325
|
+
let foreignObject = '<foreignObject x="0" y="0" width="100%" height="100%">' + xhtml + '</foreignObject>';
|
|
326
|
+
let svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' + foreignObject + '</svg>';
|
|
327
|
+
return 'data:image/svg+xml;charset=utf-8,' + svg;
|
|
328
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as util from "./util.js";
|
|
2
|
+
|
|
3
|
+
let URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} string
|
|
7
|
+
*/
|
|
8
|
+
export function shouldProcess(string) {
|
|
9
|
+
return string.search(URL_REGEX) !== -1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} string
|
|
14
|
+
*/
|
|
15
|
+
function readUrls(string) {
|
|
16
|
+
var result = [];
|
|
17
|
+
var match;
|
|
18
|
+
while ((match = URL_REGEX.exec(string)) !== null) {
|
|
19
|
+
result.push(match[1]);
|
|
20
|
+
}
|
|
21
|
+
return result.filter(function (url) {
|
|
22
|
+
return !util.isDataUrl(url);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} url
|
|
28
|
+
*/
|
|
29
|
+
function urlAsRegex(url) {
|
|
30
|
+
return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {string} string
|
|
35
|
+
* @param {string} url
|
|
36
|
+
* @param {string | null | undefined} baseUrl
|
|
37
|
+
* @param {((url: string)=>string)|undefined} get
|
|
38
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
|
|
39
|
+
*/
|
|
40
|
+
async function inline(string, url, baseUrl, get, options) {
|
|
41
|
+
url = baseUrl ? util.resolveUrl(url, baseUrl) : url;
|
|
42
|
+
let data;
|
|
43
|
+
if (get)
|
|
44
|
+
data = get(url);
|
|
45
|
+
else
|
|
46
|
+
data = await util.getAndEncode(url, options);
|
|
47
|
+
let dataUrl = util.dataAsUrl(data, util.mimeType(url));
|
|
48
|
+
return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {string} string
|
|
53
|
+
* @param {string | null | undefined} baseUrl
|
|
54
|
+
* @param {((url: string)=>string)|undefined} get
|
|
55
|
+
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
|
|
56
|
+
*/
|
|
57
|
+
export async function inlineAll(string, baseUrl, get, options) {
|
|
58
|
+
if (!shouldProcess(string)) return string;
|
|
59
|
+
let urls = readUrls(string);
|
|
60
|
+
let done = string;
|
|
61
|
+
urls.forEach(async function (url) {
|
|
62
|
+
done = await inline(done, url, baseUrl, get, options);
|
|
63
|
+
});
|
|
64
|
+
return done;
|
|
65
|
+
}
|