diff --git a/src/mixins/object.svg_export.js b/src/mixins/object.svg_export.js index bde97bcddf4..786a80818d3 100644 --- a/src/mixins/object.svg_export.js +++ b/src/mixins/object.svg_export.js @@ -23,7 +23,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', visibility = this.visible ? '' : ' visibility: hidden;', - filter = this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; + filter = this.getSvgFilter(); return [ 'stroke: ', stroke, '; ', @@ -40,6 +40,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ].join(''); }, + /** + * Returns filter for svg shadow + * @return {String} + */ + getSvgFilter: function() { + return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; + }, + /** * Returns transform-string for svg-export * @return {String} diff --git a/src/parser.js b/src/parser.js index 6fde58ce1ee..96c333b9e0c 100644 --- a/src/parser.js +++ b/src/parser.js @@ -647,15 +647,15 @@ function _createSVGPattern(markup, canvas, property) { if (canvas[property] && canvas[property].toSVG) { markup.push( - '', - '\n', + '\t\t' + '">\n\t\n' ); } } @@ -1018,7 +1018,7 @@ '@font-face {', 'font-family: ', objects[i].fontFamily, '; ', 'src: url(\'', objects[i].path, '\')', - '}' + '}\n' //jscs:enable validateIndentation ].join(''); } @@ -1026,11 +1026,11 @@ if (markup) { markup = [ //jscs:disable validateIndentation - '' + '\n' //jscs:enable validateIndentation ].join(''); } diff --git a/src/shapes/group.class.js b/src/shapes/group.class.js index 461048a66de..512782b9dfa 100644 --- a/src/shapes/group.class.js +++ b/src/shapes/group.class.js @@ -266,6 +266,7 @@ ctx.transform.apply(ctx, this.transformMatrix); } this.transform(ctx); + this._setShadow(ctx); this.clipTo && fabric.util.clipContext(this, ctx); // the array is now sorted in order of highest first, so start from end for (var i = 0, len = this._objects.length; i < len; i++) { @@ -531,16 +532,19 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = [ - //jscs:disable validateIndentation - '\n' - //jscs:enable validateIndentation - ]; + ); for (var i = 0, len = this._objects.length; i < len; i++) { - markup.push(this._objects[i].toSVG(reviver)); + markup.push('\t', this._objects[i].toSVG(reviver)); } markup.push('\n'); diff --git a/src/shapes/image.class.js b/src/shapes/image.class.js index cc2107cf448..6749b452210 100644 --- a/src/shapes/image.class.js +++ b/src/shapes/image.class.js @@ -227,7 +227,7 @@ * @return {String} svg representation of an instance */ toSVG: function(reviver) { - var markup = [], x = -this.width / 2, y = -this.height / 2, + var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = 'none'; if (this.group && this.group.type === 'path-group') { x = this.left; diff --git a/src/shapes/path_group.class.js b/src/shapes/path_group.class.js index b794412076e..a0cdfc9fd4e 100644 --- a/src/shapes/path_group.class.js +++ b/src/shapes/path_group.class.js @@ -175,17 +175,16 @@ var objects = this.getObjects(), p = this.getPointByOrigin('left', 'top'), translatePart = 'translate(' + p.x + ' ' + p.y + ')', - markup = [ - //jscs:disable validateIndentation - '\n' - //jscs:enable validateIndentation - ]; + markup = this._createBaseSVGMarkup(); + markup.push( + '\n' + ); for (var i = 0, len = objects.length; i < len; i++) { - markup.push(objects[i].toSVG(reviver)); + markup.push('\t', objects[i].toSVG(reviver)); } markup.push('\n'); @@ -207,9 +206,14 @@ * @return {Boolean} true if all paths are of the same color (`fill`) */ isSameColor: function() { - var firstPathFill = (this.getObjects()[0].get('fill') || '').toLowerCase(); + var firstPathFill = this.getObjects()[0].get('fill') || ''; + if (typeof firstPathFill !== 'string') { + return false; + } + firstPathFill = firstPathFill.toLowerCase(); return this.getObjects().every(function(path) { - return (path.get('fill') || '').toLowerCase() === firstPathFill; + var pathFill = path.get('fill') || ''; + return typeof pathFill === 'string' && (pathFill).toLowerCase() === firstPathFill; }); }, diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index 7be2bdc0f83..65b46841a3a 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -1280,7 +1280,7 @@ _setSVGPreamble: function(markup, options) { if (!options.suppressPreamble) { markup.push( - '', + '\n', '\n' ); @@ -1324,12 +1324,12 @@ options.viewBox.width + ' ' + options.viewBox.height + '" ' : null), - 'xml:space="preserve">', - 'Created with Fabric.js ', fabric.version, '', + 'xml:space="preserve">\n', + 'Created with Fabric.js ', fabric.version, '\n', '', fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), - '' + '\n' ); }, @@ -1372,7 +1372,7 @@ ? this[property].source.height : this.height), '" fill="url(#' + property + 'Pattern)"', - '>' + '>\n' ); } else if (this[property] && property === 'overlayColor') { @@ -1381,7 +1381,7 @@ 'width="', this.width, '" height="', this.height, '" fill="', this[property], '"', - '>' + '>\n' ); } }, diff --git a/test/unit/canvas_static.js b/test/unit/canvas_static.js index c11f084cd9d..8e6716c6ba7 100644 --- a/test/unit/canvas_static.js +++ b/test/unit/canvas_static.js @@ -2,11 +2,11 @@ // var emptyImageCanvasData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAH7ElEQVR4nO3VMQ0AMAzAsPInvYHoMS2yEeTLHADge/M6AADYM3QACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIuMjH4b7osLFBAAAAAElFTkSuQmCC"; - var CANVAS_SVG = '\n'+ - 'Created with Fabric.js ' + fabric.version + ''; + var CANVAS_SVG = '\n\n'+ + '\nCreated with Fabric.js ' + fabric.version + '\n\n'; - var CANVAS_SVG_VIEWBOX = '\n'+ - 'Created with Fabric.js ' + fabric.version + ''; + var CANVAS_SVG_VIEWBOX = '\n\n'+ + '\nCreated with Fabric.js ' + fabric.version + '\n\n'; var PATH_JSON = '{"objects": [{"type": "path", "originX": "left", "originY": "top", "left": 268, "top": 266, "width": 51, "height": 49,'+ ' "fill": "rgb(0,0,0)", "stroke": null, "strokeWidth": 1, "scaleX": 1, "scaleY": 1, '+ diff --git a/test/unit/group.js b/test/unit/group.js index 96ab19bd033..51818176f20 100644 --- a/test/unit/group.js +++ b/test/unit/group.js @@ -400,7 +400,7 @@ test('toObject without default values', function() { var group = makeGroupWith2Objects(); ok(typeof group.toSVG == 'function'); - var expectedSVG = '\n\n\n\n'; + var expectedSVG = '\n\t\n\t\n\n'; equal(group.toSVG(), expectedSVG); }); diff --git a/test/unit/path_group.js b/test/unit/path_group.js index 75203cacac3..1234e5b3379 100644 --- a/test/unit/path_group.js +++ b/test/unit/path_group.js @@ -32,13 +32,13 @@ }; var REFERENCE_PATH_GROUP_SVG = '\n' + - '\n' + - '\n' + + '\t\n' + + '\t\n' + '\n'; var REFERENCE_PATH_GROUP_SVG_WITH_MATRIX = '\n' + - '\n' + - '\n' + + '\t\n' + + '\t\n' + '\n'; function getPathElement(path) {