From dba4eb371d702fe1c1f4f6edcb077d02f7d18dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sun, 14 Feb 2016 22:51:50 +0100 Subject: [PATCH] SvgImport: Implement options.insert to control insertion. Also use settings.insertItems for faster import. Closes #763 --- src/path/PathItem.js | 2 +- src/svg/SvgImport.js | 25 +++++++++++++++++++------ test/helpers.js | 20 +++++++------------- test/tests/SvgImport.js | 14 +++++++++++++- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/path/PathItem.js b/src/path/PathItem.js index e8c84beb..b84a1e3c 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -47,7 +47,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{ // First split the path data into parts of command-coordinates pairs // Commands are any of these characters: mzlhvcsqta - var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), + var parts = data && data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), coords, relative = false, previous, diff --git a/src/svg/SvgImport.js b/src/svg/SvgImport.js index 84ba1369..1c6271a9 100644 --- a/src/svg/SvgImport.js +++ b/src/svg/SvgImport.js @@ -141,7 +141,8 @@ new function() { param = { pathData: data }; // If there are multiple moveTo commands or a closePath command followed // by other commands, we have a CompoundPath: - return (data.match(/m/gi) || []).length > 1 || /z\S+/i.test(data) + // TODO: PathItem.create()? + return (data && data.match(/m/gi) || []).length > 1 || /z\b/i.test(data) ? new CompoundPath(param) : new Path(param); } @@ -184,7 +185,7 @@ new function() { destination = getPoint(node, 'x2', 'y2', false, scaleToBounds); } var color = applyAttributes( - new Color(gradient, origin, destination, highlight), node); + new Color(gradient, origin, destination, highlight), node); // TODO: Consider adding support for _scaleToBounds to Color instead? color._scaleToBounds = scaleToBounds; // We don't return the gradient, since we only need a reference to it in @@ -588,12 +589,16 @@ new function() { } // Have items imported from SVG not bake in all transformations to their // content and children, as this is how SVG works too, but preserve the - // current setting so we can restore it after. + // current setting so we can restore it after. Also don't insert them + // into the scene graph automatically, as we do so by hand. var settings = paper.settings, - applyMatrix = settings.applyMatrix; + applyMatrix = settings.applyMatrix, + insertItems = settings.insertItems; settings.applyMatrix = false; + settings.insertItems = false; var importer = importers[type], item = importer && importer(node, type, options, isRoot) || null; + settings.insertItems = insertItems; settings.applyMatrix = applyMatrix; if (item) { // Do not apply attributes if this is a #document node. @@ -709,7 +714,10 @@ new function() { // NOTE: Documentation is in Item#importSVG() Item.inject({ importSVG: function(node, options) { - return this.addChild(importSVG(node, options)); + var res = importSVG(node, options); + if (!options || options.insert !== false) + this.addChild(res); + return res; } }); @@ -717,7 +725,12 @@ new function() { Project.inject({ importSVG: function(node, options) { this.activate(); - return importSVG(node, options); + var res = importSVG(node, options); + if (!options || options.insert !== false) { + // TODO: Implement support for Layer parsing / insertion. + this.getActiveLayer().addChild(res); + } + return res; } }); }; diff --git a/test/helpers.js b/test/helpers.js index 358a819b..732b71b7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -462,19 +462,13 @@ var compareBoolean = function(actual, expected, message, options) { }; var createSVG = function(str, attrs) { - if (attrs) { - // Similar to SvgElement.create(): - var node = document.createElementNS('http://www.w3.org/2000/svg', str); - for (var key in attrs) - node.setAttribute(key, attrs[key]); - // Paper.js paths do not have a fill by default, SVG does. - node.setAttribute('fill', 'none'); - return node; - } else { - return new window.DOMParser().parseFromString( - '' + str + '', - 'text/xml'); - } + // Similar to SvgElement.create(): + var node = document.createElementNS('http://www.w3.org/2000/svg', str); + for (var key in attrs) + node.setAttribute(key, attrs[key]); + // Paper.js paths do not have a fill by default, SVG does. + node.setAttribute('fill', 'none'); + return node; }; var compareSVG = function(done, actual, expected, message, options) { diff --git a/test/tests/SvgImport.js b/test/tests/SvgImport.js index c851ad0d..933c4bc9 100644 --- a/test/tests/SvgImport.js +++ b/test/tests/SvgImport.js @@ -115,11 +115,23 @@ test('Import SVG polyline', function() { }); test('Import complex CompoundPath and clone', function() { - var svg = createSVG(''); + var svg = ''; var item = paper.project.importSVG(svg); equals(item.clone(), item, null, { cloned: true }); }); +test('Import SVG without insertion', function() { + var svg = createSVG('path', { d: '' }); + var imported = paper.project.importSVG(svg, { insert: true }); + equals(function() { + return imported.parent === project.activeLayer; + }, true); + var imported = paper.project.importSVG(svg, { insert: false }); + equals(function() { + return imported.parent === null; + }, true); +}); + function importSVG(assert, url, message, options) { var done = assert.async(); project.importSVG(url, {