Skip to content

Commit b4d56b2

Browse files
committed
Merge branch 'dev'
2 parents 23a37f6 + 68b50a8 commit b4d56b2

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,3 @@ interface Csp {
8686
Carbonite is extracted from Maps API and should be written to allow simple integration back into it. Since Maps API still supports browsers like Internet Explorer 8 and Opera 12 and browsers with ES3 only there're some quirks you should follow:
8787

8888
- Library should not produce `SyntaxError`s during parsing in IE 8 and Opera 12
89-
- Code using promises should be written in a way to be able to work with [vow 0.4.7](https://github.com/Ajaxy/vow/tree/57e1b832a69edbc15ee0e72907a45cb3389d48cc) promises

src/htmlToSvg.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {Csp} from './csp';
22
import {StyleSheet} from './StyleSheet';
33

4+
const xmlSerializer = new XMLSerializer();
5+
46
export interface Size {
57
width: number;
68
height: number;
@@ -15,7 +17,6 @@ export function wrapHtmlInSvg(
1517
size: Size,
1618
csp: Csp
1719
): string {
18-
const html = new XMLSerializer().serializeToString(node);
1920
const rootStyle = stylesheet.createClass({
2021
position: 'relative',
2122
width: '100%',
@@ -25,14 +26,18 @@ export function wrapHtmlInSvg(
2526
overflow: 'hidden'
2627
});
2728

29+
const style = document.createElement('style');
30+
if (csp.enabled && csp.styleNonce) {
31+
style.setAttribute('none', csp.styleNonce);
32+
}
33+
style.innerHTML = stylesheet.combine();
34+
2835
return `
2936
<svg xmlns="http://www.w3.org/2000/svg" width="${size.width}" height="${size.height}">
30-
<style ${csp.enabled ? `nonce="${csp.styleNonce}"` : ''}>
31-
${stylesheet.combine()}
32-
</style>
37+
${xmlSerializer.serializeToString(style)}
3338
<foreignObject width="100%" height="100%">
3439
<body xmlns="http://www.w3.org/1999/xhtml" class="${rootStyle}">
35-
${html}
40+
${xmlSerializer.serializeToString(node)}
3641
</body>
3742
</foreignObject>
3843
</svg>

src/inlineStyles.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const ignoredStyles = /^(transition|cursor|animation|userSelect)/;
1717
// Firefox doesn't build the full style, so for the example above, only borderTop will be set.
1818
const partialStyles = browser.engine !== 'webkit'
1919
? /^(?=a)b/ // Dummy regex that fails on any string.
20-
: /^(background|outline|border|webkitBorder(Before|After|End|Start))[A-Z]/;
20+
: /^(background|outline|border(?!Radius)|webkitBorder(Before|After|End|Start))[A-Z]/;
2121

2222
/**
2323
* Clone node hierarchy and inline all styles.
@@ -55,22 +55,24 @@ function inlineElementStyles(node: HTMLElement, stylesheet: StyleSheet): Promise
5555
const defaultStyle = clone(getComputedStyle(newNode));
5656
tempDom.dispose();
5757

58-
const styles: string[] = [];
59-
for (const key in desiredStyle) {
60-
if (!desiredStyle.hasOwnProperty(key)) {
61-
continue;
62-
}
58+
const styles: Record<string, string> = {};
59+
60+
// tslint:disable-next-line:prefer-for-of
61+
for (let i = 0; i < desiredStyle.length; i++) {
62+
const key = desiredStyle.item(i);
6363

6464
// Skip JavaScript stuff.
65-
if (/^(\d+|length|cssText)$|-/.test(key)) {
65+
if (/^(\d+|length|cssText)$/.test(key)) {
6666
continue;
6767
}
6868

6969
if (ignoredStyles.test(key) || partialStyles.test(key)) {
7070
continue;
7171
}
7272

73-
let value = desiredStyle[key];
73+
const desiredValue = desiredStyle.getPropertyValue(key);
74+
75+
let value = desiredValue;
7476
const type = typeof value;
7577

7678
// Skip more JavaScript stuff.
@@ -81,7 +83,7 @@ function inlineElementStyles(node: HTMLElement, stylesheet: StyleSheet): Promise
8183
const forced = forcedStyles.test(key);
8284

8385
// Skip styles that are already implicitly applied to the node.
84-
if (defaultStyle[key] === desiredStyle[key] && !forced) {
86+
if (defaultStyle[key] === desiredValue && !forced) {
8587
continue;
8688
}
8789

@@ -91,14 +93,14 @@ function inlineElementStyles(node: HTMLElement, stylesheet: StyleSheet): Promise
9193
continue;
9294
}
9395

94-
styles.push(convertCssOmKeyToCssKey(key) + ':' + value + ';');
96+
styles[key] = value;
9597
}
9698

9799
// Try to save data from canvas.
98100
if (tagName === 'canvas') {
99101
try {
100102
const dataUrl = (node as HTMLCanvasElement).toDataURL();
101-
styles.push(`background-image: url("${dataUrl}");`);
103+
styles.backgroundImage = `url("${dataUrl}")`;
102104
} catch (e) {
103105
// nop
104106
}
@@ -108,11 +110,11 @@ function inlineElementStyles(node: HTMLElement, stylesheet: StyleSheet): Promise
108110

109111
// Try to save data from image.
110112
if (tagName === 'img') {
111-
styles.push('display: block;');
113+
styles.display = 'block';
112114
done = loadImageAsDataUrl(node as HTMLImageElement)
113115
.then((dataUrl) => {
114116
if (dataUrl) {
115-
styles.push(`background-image: url("${dataUrl}");`);
117+
styles.backgroundImage = `url("${dataUrl}")`;
116118
}
117119
})
118120
.catch((e) => { /* ignore */ });
@@ -128,7 +130,7 @@ function inlineElementStyles(node: HTMLElement, stylesheet: StyleSheet): Promise
128130
// Setting CSSOM value directly makes XMLSerializer output them in style attribute.
129131
// This works in Chromiums, but Firefox fails to render foreignObject with style attributes.
130132
// https://bugzilla.mozilla.org/show_bug.cgi?id=1358106
131-
newNode.className = stylesheet.createClass(styles.join(''));
133+
newNode.className = stylesheet.createClass(styles);
132134

133135
// Create inlined versions of child nodes and append them.
134136
const childPromises = [];

0 commit comments

Comments
 (0)