Skip to content

Commit

Permalink
Fixed #6307, offline export issues with styled mode in IE and Edge.
Browse files Browse the repository at this point in the history
  • Loading branch information
oysteinmoseng authored and TorsteinHonsi committed May 9, 2017
1 parent e66b305 commit 0be4889
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 36 deletions.
93 changes: 57 additions & 36 deletions js/modules/exporting.src.js
Expand Up @@ -32,7 +32,8 @@ var defaultOptions = H.defaultOptions,
win = H.win,
SVGRenderer = H.SVGRenderer;

var symbols = H.Renderer.prototype.symbols;
var symbols = H.Renderer.prototype.symbols,
isMSBrowser = /Edge\/|Trident\/|MSIE /.test(win.navigator.userAgent);

// Add language
extend(defaultOptions.lang, {
Expand Down Expand Up @@ -867,6 +868,7 @@ Chart.prototype.inlineStyles = function () {
var renderer = this.renderer,
inlineToAttributes = renderer.inlineToAttributes,
blacklist = renderer.inlineBlacklist,
whitelist = renderer.inlineWhitelist, // For IE
unstyledElements = renderer.unstyledElements,
defaultStyles = {},
dummySVG;
Expand All @@ -893,9 +895,49 @@ Chart.prototype.inlineStyles = function () {
dummy,
styleAttr,
blacklisted,
i,
prop;

whitelisted,
i;

// Check computed styles and whether they are in the white/blacklist for
// styles or atttributes
function filterStyles(val, prop) {

// Check against whitelist & blacklist
blacklisted = whitelisted = false;
if (whitelist) {
// Styled mode in IE has a whitelist instead.
// Exclude all props not in this list.
i = whitelist.length;
while (i-- && !whitelisted) {
whitelisted = whitelist[i].test(prop);
}
blacklisted = !whitelisted;
}

// Explicitly remove empty transforms
if (prop === 'transform' && val === 'none') {
blacklisted = true;
}

i = blacklist.length;
while (i-- && !blacklisted) {
blacklisted = blacklist[i].test(prop) || typeof val === 'function';
}

if (!blacklisted) {
// If parent node has the same style, it gets inherited, no need to inline it
if (parentStyles[prop] !== val && defaultStyles[node.nodeName][prop] !== val) {
// Attributes
if (inlineToAttributes.indexOf(prop) !== -1) {
node.setAttribute(hyphenate(prop), val);
// Styles
} else {
cssText += hyphenate(prop) + ':' + val + ';';
}
}
}
}

if (node.nodeType === 1 && unstyledElements.indexOf(node.nodeName) === -1) {
styles = win.getComputedStyle(node, null);
parentStyles = node.nodeName === 'svg' ? {} : win.getComputedStyle(node.parentNode, null);
Expand All @@ -913,39 +955,13 @@ Chart.prototype.inlineStyles = function () {
dummySVG.removeChild(dummy);
}

// Loop over all the computed styles and check whether they are in
// the white list for styles or atttributes. Use a plain for-in loop
// because the styles object also contains numerically indexed
// pointers to its keys, and objectEach will fail in Firefox.
for (prop in styles) {
// Check against blacklist
blacklisted = false;
i = blacklist.length;
while (i-- && !blacklisted) {
blacklisted = blacklist[i].test(prop) ||
typeof styles[prop] === 'function';
}

if (!blacklisted) {

// If parent node has the same style, it gets inherited, no
// need to inline it
if (
parentStyles[prop] !== styles[prop] &&
defaultStyles[node.nodeName][prop] !== styles[prop]
) {

// Attributes
if (inlineToAttributes.indexOf(prop) !== -1) {
node.setAttribute(hyphenate(prop), styles[prop]);

// Styles
} else {
cssText += hyphenate(prop) + ':' +
styles[prop] + ';';
}
}
// Loop through all styles and add them inline if they are ok
if (isMSBrowser) { // MS browsers put lots of styles on the prototype
for (var p in styles) {
filterStyles(styles[p], p);
}
} else {
objectEach(styles, filterStyles);
}

// Apply styles
Expand All @@ -954,6 +970,11 @@ Chart.prototype.inlineStyles = function () {
node.setAttribute('style', (styleAttr ? styleAttr + ';' : '') + cssText);
}

// Set default stroke width (needed at least for IE)
if (node.nodeName === 'svg') {
node.setAttribute('stroke-width', '1px');
}

if (node.nodeName === 'text') {
return;
}
Expand Down
38 changes: 38 additions & 0 deletions js/modules/offline-exporting.src.js
Expand Up @@ -459,6 +459,44 @@ Highcharts.Chart.prototype.exportChartLocal = function (exportingOptions, chartO
}
};

// If we are on IE and in styled mode, add a whitelist to the renderer
// for inline styles that we want to pass through. There are so many
// styles by default in IE that we don't want to blacklist them all.
/*= if (!build.classic) { =*/
if (isMSBrowser) {
Highcharts.SVGRenderer.prototype.inlineWhitelist = [
/^blockSize/,
/^border/,
/^caretColor/,
/^color/,
/^columnRule/,
/^columnRuleColor/,
/^cssFloat/,
/^cursor/,
/^fill$/,
/^fillOpacity/,
/^font/,
/^inlineSize/,
/^length/,
/^lineHeight/,
/^opacity/,
/^outline/,
/^parentRule/,
/^rx$/,
/^ry$/,
/^stroke/,
/^textAlign/,
/^textAnchor/,
/^textDecoration/,
/^transform/,
/^vectorEffect/,
/^visibility/,
/^x$/,
/^y$/
];
}
/*= } =*/

// Always fall back on:
// - MS browsers: Embedded images JPEG/PNG, or any PDF
// - Edge: PNG/JPEG all cases
Expand Down

0 comments on commit 0be4889

Please sign in to comment.