Simplify rendered SVGs slightly and add support for Safari

This commit is contained in:
David Evans 2017-11-09 20:09:16 +00:00
parent 121830f69c
commit 01e43fd3eb
8 changed files with 39 additions and 27 deletions

View File

@ -4,14 +4,7 @@
<meta http-equiv="content-security-policy" content=" <meta http-equiv="content-security-policy" content="
base-uri 'self'; base-uri 'self';
default-src 'none'; default-src 'none';
script-src script-src 'self' https://cdnjs.cloudflare.com;
'self'
'sha256-0SGl1PJNDyJwcV5T+weg2zpEMrh7xvlwO4oXgvZCeZk='
'sha256-eue5ceZRwKVQ1OXOZSyU7MXCTZMlqsPi/TOIqh1Vlzo='
'sha256-OvxDPyq6KQAoWh11DLJdBVlHHLkYYiy4EzqTjIEJbb4='
'sha256-vnm8bzrI+krtz5228JDC2DoTv0e+sfnfTCiUnO2EBAM='
'sha256-HYX1RusN7a369vYuOd1mGvxLcNL4z/MihkahAI2CH8k='
;
style-src 'self' https://cdnjs.cloudflare.com; style-src 'self' https://cdnjs.cloudflare.com;
img-src 'self' blob:; img-src 'self' blob:;
form-action 'none'; form-action 'none';

View File

@ -4,10 +4,7 @@
<meta http-equiv="content-security-policy" content=" <meta http-equiv="content-security-policy" content="
base-uri 'self'; base-uri 'self';
default-src 'none'; default-src 'none';
script-src script-src 'self' https://cdnjs.cloudflare.com;
'self'
'sha256-0SGl1PJNDyJwcV5T+weg2zpEMrh7xvlwO4oXgvZCeZk='
;
style-src 'self'; style-src 'self';
connect-src 'self'; connect-src 'self';
img-src 'self' blob:; img-src 'self' blob:;

View File

@ -1,6 +1,9 @@
define(() => { define(() => {
'use strict'; 'use strict';
// Thanks, https://stackoverflow.com/a/23522755/1180785
const safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
return class Exporter { return class Exporter {
constructor() { constructor() {
this.latestSVG = null; this.latestSVG = null;
@ -41,11 +44,27 @@ define(() => {
const width = renderer.width * resolution; const width = renderer.width * resolution;
const height = renderer.height * resolution; const height = renderer.height * resolution;
const img = new Image(width, height); const img = new Image(width, height);
let safariHackaround = null;
if(safari) {
// Safari fails to resize SVG images unless they are displayed
// on the page somewhere, so we must add it before drawing the
// image. For some reason, doing this inside the load listener
// is too late, so we do it here and do our best to ensure it
// doesn't change the page rendering (display:none fails too)
safariHackaround = document.createElement('div');
safariHackaround.style.position = 'absolute';
safariHackaround.style.visibility = 'hidden';
safariHackaround.appendChild(img);
document.body.appendChild(safariHackaround);
}
img.addEventListener('load', () => { img.addEventListener('load', () => {
this.canvas.width = width; this.canvas.width = width;
this.canvas.height = height; this.canvas.height = height;
this.context.drawImage(img, 0, 0); this.context.drawImage(img, 0, 0);
if(safariHackaround) {
document.body.removeChild(safariHackaround);
}
this.canvas.toBlob(callback, 'image/png'); this.canvas.toBlob(callback, 'image/png');
}, {once: true}); }, {once: true});

View File

@ -1,6 +1,9 @@
defineDescribe('Interface', ['./Interface'], (Interface) => { defineDescribe('Interface', ['./Interface'], (Interface) => {
'use strict'; 'use strict';
// Thanks, https://stackoverflow.com/a/23522755/1180785
const safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
let parser = null; let parser = null;
let generator = null; let generator = null;
let renderer = null; let renderer = null;
@ -61,6 +64,11 @@ defineDescribe('Interface', ['./Interface'], (Interface) => {
ui.build(container); ui.build(container);
expect(ui.downloadSVG.getAttribute('href')).toEqual('#'); expect(ui.downloadSVG.getAttribute('href')).toEqual('#');
if(safari) {
// Safari actually starts a download if we do this, which
// doesn't seem to fit its usual security vibe
return;
}
ui.downloadSVG.dispatchEvent(new Event('click')); ui.downloadSVG.dispatchEvent(new Event('click'));
expect(ui.downloadSVG.getAttribute('href')).toEqual('mySVGURL'); expect(ui.downloadSVG.getAttribute('href')).toEqual('mySVGURL');
}); });

View File

@ -126,10 +126,7 @@ define([
} }
buildStaticElements() { buildStaticElements() {
this.base = svg.makeContainer({ this.base = svg.makeContainer();
'width': '100%',
'height': '100%',
});
this.defs = svg.make('defs'); this.defs = svg.make('defs');
this.mask = svg.make('mask', { this.mask = svg.make('mask', {

View File

@ -47,7 +47,7 @@ defineDescribe('Sequence Integration', [
const sequence = generator.generate(parsed); const sequence = generator.generate(parsed);
renderer.render(sequence); renderer.render(sequence);
expect(getSimplifiedContent(renderer)).toEqual( expect(getSimplifiedContent(renderer)).toEqual(
'<svg width="100%" height="100%" viewBox="-5 -5 10 10">' + '<svg viewBox="-5 -5 10 10">' +
'<defs>' + '<defs>' +
'<mask id="LineMask" maskUnits="userSpaceOnUse">' + '<mask id="LineMask" maskUnits="userSpaceOnUse">' +
'<rect fill="#FFFFFF" x="-5" y="-5" width="10" height="10">' + '<rect fill="#FFFFFF" x="-5" y="-5" width="10" height="10">' +
@ -65,7 +65,7 @@ defineDescribe('Sequence Integration', [
renderer.render(sequence); renderer.render(sequence);
expect(getSimplifiedContent(renderer)).toEqual( expect(getSimplifiedContent(renderer)).toEqual(
'<svg width="100%" height="100%" viewBox="-11.5 -16 23 21">' + '<svg viewBox="-11.5 -16 23 21">' +
'<defs>' + '<defs>' +
'<mask id="LineMask" maskUnits="userSpaceOnUse">' + '<mask id="LineMask" maskUnits="userSpaceOnUse">' +
'<rect fill="#FFFFFF" x="-11.5" y="-16" width="23" height="21">' + '<rect fill="#FFFFFF" x="-11.5" y="-16" width="23" height="21">' +
@ -92,7 +92,7 @@ defineDescribe('Sequence Integration', [
const content = getSimplifiedContent(renderer); const content = getSimplifiedContent(renderer);
expect(content).toContain( expect(content).toContain(
'<svg width="100%" height="100%" viewBox="-5 -5 82 47">' '<svg viewBox="-5 -5 82 47">'
); );
// Agent 1 // Agent 1

View File

@ -58,6 +58,11 @@ html, body {
.pane-view-inner { .pane-view-inner {
} }
.pane-view svg {
width: 100%;
height: 100%;
}
.pane-error { .pane-error {
position: absolute; position: absolute;
left: 0; left: 0;

View File

@ -4,14 +4,7 @@
<meta http-equiv="content-security-policy" content=" <meta http-equiv="content-security-policy" content="
base-uri 'self'; base-uri 'self';
default-src 'none'; default-src 'none';
script-src script-src 'self' https://cdnjs.cloudflare.com;
'self'
'sha256-0SGl1PJNDyJwcV5T+weg2zpEMrh7xvlwO4oXgvZCeZk='
'sha256-nbDuV0lauU6Rzhc3T39vSmQ64+K0R8Kp556x6W5Xxg4='
'sha256-3t+j0EiiLhROsCHCLF+g/h4gPsyH5agBoZeAcOrydRM='
'sha256-Re9XxIL3x1flvE6WD58jWPdDzKYQLXwxS2HAVfmM6Z8='
'sha256-SYY59VkHlf1wmU3zhsnII/kb51ODoHy6ub8qaq0eAcY='
;
connect-src 'self'; connect-src 'self';
style-src 'self' https://cdnjs.cloudflare.com; style-src 'self' https://cdnjs.cloudflare.com;
img-src 'self' data: blob:; img-src 'self' data: blob:;