Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

svgsaver

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svgsaver - npm Package Compare versions

Comparing version 0.3.3 to 0.4.0

55

browser.js

@@ -55,3 +55,3 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SvgSaver = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

'overflow': 'visible',
'paint-order': 'normal',
'paint-order': 'fill',
'pointer-events': 'auto',

@@ -79,5 +79,5 @@ 'shape-rendering': 'auto',

var svgAttrs = [// white list of attributes
'id', 'xml:base', 'xml:lang', 'xml:space', // Core
'id', 'xml: base', 'xml: lang', 'xml: space', // Core
'height', 'result', 'width', 'x', 'y', // Primitive
'xlink:href', // Xlink attribute
'xlink: href', // Xlink attribute
'style', 'class', 'd', 'pathLength', // Path

@@ -104,7 +104,6 @@ 'x', 'y', 'dx', 'dy', 'glyphRef', 'format', 'x1', 'y1', 'x2', 'y2', 'rotate', 'textLength', 'cx', 'cy', 'r', 'rx', 'ry', 'fx', 'fy', 'width', 'height', 'refX', 'refY', 'orient', 'markerUnits', 'markerWidth', 'markerHeight', 'maskUnits', 'transform', 'viewBox', 'version', // Container

//detection
// detection
var DownloadAttributeSupport = typeof document !== 'undefined' && 'download' in document.createElement('a');
function saveUri(uri, name) {
if (DownloadAttributeSupport) {

@@ -152,3 +151,3 @@ var dl = document.createElement('a');

};
var isObject = function isObject(a) {
var _isObject = function _isObject(a) {
return a !== null && typeof a === 'object';

@@ -159,4 +158,4 @@ };

function isNode(val) {
if (!isObject(val)) return false;
if (_isDefined(window) && isObject(window.Node)) return val instanceof window.Node;
if (!_isObject(val)) return false;
if (_isDefined(window) && _isObject(window.Node)) return val instanceof window.Node;
return 'number' == typeof val.nodeType && 'string' == typeof val.nodeName;

@@ -241,15 +240,35 @@ }

// Clones an SVGElement, copyies approprate atttributes and styles.
function cleanStyle(tgt, parentStyles) {
if (tgt.style) {
inheritableAttrs.forEach(function (key) {
if (tgt.style[key] === parentStyles[key]) {
tgt.style.removeProperty(key);
}
});
}
}
function walker(attrs, defaultStyles) {
return function walk(src, tgt) {
if (!tgt.style) return;
computedStyles(src, tgt.style, defaultStyles);
var children = src.childNodes;
for (var i = 0; i < children.length; i++) {
walk(children[i], tgt.childNodes[i]);
cleanStyle(tgt.childNodes[i], tgt.style);
}
if (tgt.attributes) {
cleanAttrs(tgt, attrs, defaultStyles);
}
};
}
// Clones an SVGElement, copies approprate atttributes and styles.
function cloneSvg(src, attrs, styles) {
var clonedSvg = src.cloneNode(true);
var srcChildren = src.querySelectorAll('*');
walker(attrs, styles)(src, clonedSvg);
computedStyles(src, clonedSvg.style, styles);
cleanAttrs(clonedSvg, attrs, styles);
Array.prototype.slice.call(clonedSvg.querySelectorAll('*')).forEach(function (target, index) {
computedStyles(srcChildren[index], target.style, styles);
cleanAttrs(target, attrs, styles);
});
return clonedSvg;

@@ -256,0 +275,0 @@ }

@@ -1,1 +0,1 @@

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SvgSaver=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var svgStyles={"alignment-baseline":"auto","baseline-shift":"baseline",clip:"auto","clip-path":"none","clip-rule":"nonzero",color:"rgb(51, 51, 51)","color-interpolation":"srgb","color-interpolation-filters":"linearrgb","color-profile":"auto","color-rendering":"auto",cursor:"auto",direction:"ltr",display:"inline","dominant-baseline":"auto","enable-background":"",fill:"rgb(0, 0, 0)","fill-opacity":"1","fill-rule":"nonzero",filter:"none","flood-color":"rgb(0, 0, 0)","flood-opacity":"1",font:"","font-family":"normal","font-size":"medium","font-size-adjust":"auto","font-stretch":"normal","font-style":"normal","font-variant":"normal","font-weight":"400","glyph-orientation-horizontal":"0deg","glyph-orientation-vertical":"auto","image-rendering":"auto",kerning:"auto","letter-spacing":"0","lighting-color":"rgb(255, 255, 255)",marker:"","marker-end":"none","marker-mid":"none","marker-start":"none",mask:"none",opacity:"1",overflow:"visible","paint-order":"normal","pointer-events":"auto","shape-rendering":"auto","stop-color":"rgb(0, 0, 0)","stop-opacity":"1",stroke:"none","stroke-dasharray":"none","stroke-dashoffset":"0","stroke-linecap":"butt","stroke-linejoin":"miter","stroke-miterlimit":"4","stroke-opacity":"1","stroke-width":"1","text-anchor":"start","text-decoration":"none","text-rendering":"auto","unicode-bidi":"normal",visibility:"visible","word-spacing":"0px","writing-mode":"lr-tb"};var svgAttrs=["id","xml:base","xml:lang","xml:space","height","result","width","x","y","xlink:href","style","class","d","pathLength","x","y","dx","dy","glyphRef","format","x1","y1","x2","y2","rotate","textLength","cx","cy","r","rx","ry","fx","fy","width","height","refX","refY","orient","markerUnits","markerWidth","markerHeight","maskUnits","transform","viewBox","version","preserveAspectRatio","xmlns","points","offset"];var inheritableAttrs=["clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cursor","direction","fill","fill-opacity","fill-rule","font","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","glyph-orientation-horizontal","glyph-orientation-vertical","image-rendering","kerning","letter-spacing","marker","marker-end","marker-mid","marker-start","pointer-events","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-rendering","transform","visibility","white-space","word-spacing","writing-mode"];var isFunction=function isFunction(a){return typeof a==="function"};var isDefined=function isDefined(a){return typeof a!=="undefined"};var isUndefined=function isUndefined(a){return typeof a==="undefined"};var DownloadAttributeSupport=typeof document!=="undefined"&&"download"in document.createElement("a");function saveUri(uri,name){if(DownloadAttributeSupport){var dl=document.createElement("a");dl.setAttribute("href",uri);dl.setAttribute("download",name);dl.click();return true}else if(typeof window!=="undefined"){window.open(uri,"_blank","");return true}return false}function savePng(uri,name){var canvas=document.createElement("canvas");var context=canvas.getContext("2d");var image=new Image;image.onload=function(){canvas.width=image.width;canvas.height=image.height;context.drawImage(image,0,0);if(isDefined(window.saveAs)&&isDefined(canvas.toBlob)){canvas.toBlob(function(blob){saveAs(blob,name)})}else{saveUri(canvas.toDataURL("image/png"),name)}};image.src=uri;return true}var _isDefined=function _isDefined(a){return typeof a!=="undefined"};var _isUndefined=function _isUndefined(a){return typeof a==="undefined"};var isObject=function isObject(a){return a!==null&&typeof a==="object"};function isNode(val){if(!isObject(val))return false;if(_isDefined(window)&&isObject(window.Node))return val instanceof window.Node;return"number"==typeof val.nodeType&&"string"==typeof val.nodeName}var useComputedStyles=_isDefined(window)&&_isDefined(window.getComputedStyle);function getComputedStyles(node){if(useComputedStyles){var view=node.ownerDocument.defaultView;if(!view.opener)view=window;return view.getComputedStyle(node,null)}else{return node.currentStyle||node.style}}function computedStyles(node){var target=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];var styleList=arguments.length<=2||arguments[2]===undefined?true:arguments[2];if(!isNode(node)){throw new Error("parameter 1 is not of type 'Element'")}if(styleList===false)return target;var computed=getComputedStyles(node);if(styleList===true){var keysArray=useComputedStyles?computed:Object.keys(computed)}else{var keysArray=Object.keys(styleList)}for(var i=0,l=keysArray.length;i<l;i++){var key=keysArray[i];var def=styleList===true||styleList[key];if(def===false||_isUndefined(def))continue;var value=computed[key];if(typeof value!=="string"||value==="")continue;if(def===true||value!==def){target[key]=value}}return target}function cleanAttrs(el,attrs,styles){if(attrs===true){return}Array.prototype.slice.call(el.attributes).forEach(function(attr){if(attr.specified){if(attrs===""||attrs===false||isUndefined(styles[attr.name])&&attrs.indexOf(attr.name)<0){el.removeAttribute(attr.name)}}})}function cloneSvg(src,attrs,styles){var clonedSvg=src.cloneNode(true);var srcChildren=src.querySelectorAll("*");computedStyles(src,clonedSvg.style,styles);cleanAttrs(clonedSvg,attrs,styles);Array.prototype.slice.call(clonedSvg.querySelectorAll("*")).forEach(function(target,index){computedStyles(srcChildren[index],target.style,styles);cleanAttrs(target,attrs,styles)});return clonedSvg}inheritableAttrs.forEach(function(k){if(k in svgStyles){svgStyles[k]=true}});var SvgSaver=function(){function SvgSaver(){var _ref=arguments.length<=0||arguments[0]===undefined?{}:arguments[0];var attrs=_ref.attrs;var styles=_ref.styles;_classCallCheck(this,SvgSaver);this.attrs=attrs===undefined?svgAttrs:attrs;this.styles=styles===undefined?svgStyles:styles}_createClass(SvgSaver,[{key:"getHTML",value:function getHTML(el){var svg=cloneSvg(el,this.attrs,this.styles);svg.setAttribute("xmlns","http://www.w3.org/2000/svg");svg.setAttribute("version",1.1);svg.setAttribute("width",svg.getAttribute("width")||"500");svg.setAttribute("height",svg.getAttribute("height")||"900");return svg.outerHTML||(new window.XMLSerializer).serializeToString(svg)}},{key:"getBlob",value:function getBlob(el){var html=this.getHTML(el);return new Blob([html],{type:"text/xml"})}},{key:"getUri",value:function getUri(el){var html=this.getHTML(el);if(isDefined(window.btoa)){return"data:image/svg+xml;base64,"+window.btoa(html)}return"data:image/svg+xml,"+encodeURIComponent(html)}},{key:"asSvg",value:function asSvg(el,filename){if(!filename||filename===""){filename=el.getAttribute("title");filename=(filename||"untitled")+".svg"}if(isDefined(window.saveAs)&&isFunction(Blob)){return saveAs(this.getBlob(el),filename)}else{return saveUri(this.getUri(el),filename)}}},{key:"asPng",value:function asPng(el,filename){if(!filename||filename===""){filename=el.getAttribute("title");filename=(filename||"untitled")+".png"}return savePng(this.getUri(el),filename)}}]);return SvgSaver}();exports["default"]=SvgSaver;module.exports=exports["default"]},{}]},{},[1])(1)});
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SvgSaver=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var svgStyles={"alignment-baseline":"auto","baseline-shift":"baseline",clip:"auto","clip-path":"none","clip-rule":"nonzero",color:"rgb(51, 51, 51)","color-interpolation":"srgb","color-interpolation-filters":"linearrgb","color-profile":"auto","color-rendering":"auto",cursor:"auto",direction:"ltr",display:"inline","dominant-baseline":"auto","enable-background":"",fill:"rgb(0, 0, 0)","fill-opacity":"1","fill-rule":"nonzero",filter:"none","flood-color":"rgb(0, 0, 0)","flood-opacity":"1",font:"","font-family":"normal","font-size":"medium","font-size-adjust":"auto","font-stretch":"normal","font-style":"normal","font-variant":"normal","font-weight":"400","glyph-orientation-horizontal":"0deg","glyph-orientation-vertical":"auto","image-rendering":"auto",kerning:"auto","letter-spacing":"0","lighting-color":"rgb(255, 255, 255)",marker:"","marker-end":"none","marker-mid":"none","marker-start":"none",mask:"none",opacity:"1",overflow:"visible","paint-order":"fill","pointer-events":"auto","shape-rendering":"auto","stop-color":"rgb(0, 0, 0)","stop-opacity":"1",stroke:"none","stroke-dasharray":"none","stroke-dashoffset":"0","stroke-linecap":"butt","stroke-linejoin":"miter","stroke-miterlimit":"4","stroke-opacity":"1","stroke-width":"1","text-anchor":"start","text-decoration":"none","text-rendering":"auto","unicode-bidi":"normal",visibility:"visible","word-spacing":"0px","writing-mode":"lr-tb"};var svgAttrs=["id","xml: base","xml: lang","xml: space","height","result","width","x","y","xlink: href","style","class","d","pathLength","x","y","dx","dy","glyphRef","format","x1","y1","x2","y2","rotate","textLength","cx","cy","r","rx","ry","fx","fy","width","height","refX","refY","orient","markerUnits","markerWidth","markerHeight","maskUnits","transform","viewBox","version","preserveAspectRatio","xmlns","points","offset"];var inheritableAttrs=["clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cursor","direction","fill","fill-opacity","fill-rule","font","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","glyph-orientation-horizontal","glyph-orientation-vertical","image-rendering","kerning","letter-spacing","marker","marker-end","marker-mid","marker-start","pointer-events","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-rendering","transform","visibility","white-space","word-spacing","writing-mode"];var isFunction=function isFunction(a){return typeof a==="function"};var isDefined=function isDefined(a){return typeof a!=="undefined"};var isUndefined=function isUndefined(a){return typeof a==="undefined"};var DownloadAttributeSupport=typeof document!=="undefined"&&"download"in document.createElement("a");function saveUri(uri,name){if(DownloadAttributeSupport){var dl=document.createElement("a");dl.setAttribute("href",uri);dl.setAttribute("download",name);dl.click();return true}else if(typeof window!=="undefined"){window.open(uri,"_blank","");return true}return false}function savePng(uri,name){var canvas=document.createElement("canvas");var context=canvas.getContext("2d");var image=new Image;image.onload=function(){canvas.width=image.width;canvas.height=image.height;context.drawImage(image,0,0);if(isDefined(window.saveAs)&&isDefined(canvas.toBlob)){canvas.toBlob(function(blob){saveAs(blob,name)})}else{saveUri(canvas.toDataURL("image/png"),name)}};image.src=uri;return true}var _isDefined=function _isDefined(a){return typeof a!=="undefined"};var _isUndefined=function _isUndefined(a){return typeof a==="undefined"};var _isObject=function _isObject(a){return a!==null&&typeof a==="object"};function isNode(val){if(!_isObject(val))return false;if(_isDefined(window)&&_isObject(window.Node))return val instanceof window.Node;return"number"==typeof val.nodeType&&"string"==typeof val.nodeName}var useComputedStyles=_isDefined(window)&&_isDefined(window.getComputedStyle);function getComputedStyles(node){if(useComputedStyles){var view=node.ownerDocument.defaultView;if(!view.opener)view=window;return view.getComputedStyle(node,null)}else{return node.currentStyle||node.style}}function computedStyles(node){var target=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];var styleList=arguments.length<=2||arguments[2]===undefined?true:arguments[2];if(!isNode(node)){throw new Error("parameter 1 is not of type 'Element'")}if(styleList===false)return target;var computed=getComputedStyles(node);if(styleList===true){var keysArray=useComputedStyles?computed:Object.keys(computed)}else{var keysArray=Object.keys(styleList)}for(var i=0,l=keysArray.length;i<l;i++){var key=keysArray[i];var def=styleList===true||styleList[key];if(def===false||_isUndefined(def))continue;var value=computed[key];if(typeof value!=="string"||value==="")continue;if(def===true||value!==def){target[key]=value}}return target}function cleanAttrs(el,attrs,styles){if(attrs===true){return}Array.prototype.slice.call(el.attributes).forEach(function(attr){if(attr.specified){if(attrs===""||attrs===false||isUndefined(styles[attr.name])&&attrs.indexOf(attr.name)<0){el.removeAttribute(attr.name)}}})}function cleanStyle(tgt,parentStyles){if(tgt.style){inheritableAttrs.forEach(function(key){if(tgt.style[key]===parentStyles[key]){tgt.style.removeProperty(key)}})}}function walker(attrs,defaultStyles){return function walk(src,tgt){if(!tgt.style)return;computedStyles(src,tgt.style,defaultStyles);var children=src.childNodes;for(var i=0;i<children.length;i++){walk(children[i],tgt.childNodes[i]);cleanStyle(tgt.childNodes[i],tgt.style)}if(tgt.attributes){cleanAttrs(tgt,attrs,defaultStyles)}}}function cloneSvg(src,attrs,styles){var clonedSvg=src.cloneNode(true);walker(attrs,styles)(src,clonedSvg);return clonedSvg}inheritableAttrs.forEach(function(k){if(k in svgStyles){svgStyles[k]=true}});var SvgSaver=function(){function SvgSaver(){var _ref=arguments.length<=0||arguments[0]===undefined?{}:arguments[0];var attrs=_ref.attrs;var styles=_ref.styles;_classCallCheck(this,SvgSaver);this.attrs=attrs===undefined?svgAttrs:attrs;this.styles=styles===undefined?svgStyles:styles}_createClass(SvgSaver,[{key:"getHTML",value:function getHTML(el){var svg=cloneSvg(el,this.attrs,this.styles);svg.setAttribute("xmlns","http://www.w3.org/2000/svg");svg.setAttribute("version",1.1);svg.setAttribute("width",svg.getAttribute("width")||"500");svg.setAttribute("height",svg.getAttribute("height")||"900");return svg.outerHTML||(new window.XMLSerializer).serializeToString(svg)}},{key:"getBlob",value:function getBlob(el){var html=this.getHTML(el);return new Blob([html],{type:"text/xml"})}},{key:"getUri",value:function getUri(el){var html=this.getHTML(el);if(isDefined(window.btoa)){return"data:image/svg+xml;base64,"+window.btoa(html)}return"data:image/svg+xml,"+encodeURIComponent(html)}},{key:"asSvg",value:function asSvg(el,filename){if(!filename||filename===""){filename=el.getAttribute("title");filename=(filename||"untitled")+".svg"}if(isDefined(window.saveAs)&&isFunction(Blob)){return saveAs(this.getBlob(el),filename)}else{return saveUri(this.getUri(el),filename)}}},{key:"asPng",value:function asPng(el,filename){if(!filename||filename===""){filename=el.getAttribute("title");filename=(filename||"untitled")+".png"}return savePng(this.getUri(el),filename)}}]);return SvgSaver}();exports["default"]=SvgSaver;module.exports=exports["default"]},{}]},{},[1])(1)});

@@ -9,2 +9,5 @@ CHANGELOG

## 0.4.0 (2015-11-05)
* Clean superfluous inheritable styles
## 0.3.3 (2015-10-28)

@@ -22,2 +25,1 @@ * Use latest computed-styles, fixes IE11

* No longer removes styles from elements that match parent styles (not all styles are inheritable)

@@ -54,3 +54,3 @@ 'use strict';

'overflow': 'visible',
'paint-order': 'normal',
'paint-order': 'fill',
'pointer-events': 'auto',

@@ -78,5 +78,5 @@ 'shape-rendering': 'auto',

var svgAttrs = [// white list of attributes
'id', 'xml:base', 'xml:lang', 'xml:space', // Core
'id', 'xml: base', 'xml: lang', 'xml: space', // Core
'height', 'result', 'width', 'x', 'y', // Primitive
'xlink:href', // Xlink attribute
'xlink: href', // Xlink attribute
'style', 'class', 'd', 'pathLength', // Path

@@ -103,7 +103,6 @@ 'x', 'y', 'dx', 'dy', 'glyphRef', 'format', 'x1', 'y1', 'x2', 'y2', 'rotate', 'textLength', 'cx', 'cy', 'r', 'rx', 'ry', 'fx', 'fy', 'width', 'height', 'refX', 'refY', 'orient', 'markerUnits', 'markerWidth', 'markerHeight', 'maskUnits', 'transform', 'viewBox', 'version', // Container

//detection
// detection
var DownloadAttributeSupport = typeof document !== 'undefined' && 'download' in document.createElement('a');
function saveUri(uri, name) {
if (DownloadAttributeSupport) {

@@ -151,3 +150,3 @@ var dl = document.createElement('a');

};
var isObject = function isObject(a) {
var _isObject = function _isObject(a) {
return a !== null && typeof a === 'object';

@@ -158,4 +157,4 @@ };

function isNode(val) {
if (!isObject(val)) return false;
if (_isDefined(window) && isObject(window.Node)) return val instanceof window.Node;
if (!_isObject(val)) return false;
if (_isDefined(window) && _isObject(window.Node)) return val instanceof window.Node;
return 'number' == typeof val.nodeType && 'string' == typeof val.nodeName;

@@ -240,15 +239,35 @@ }

// Clones an SVGElement, copyies approprate atttributes and styles.
function cleanStyle(tgt, parentStyles) {
if (tgt.style) {
inheritableAttrs.forEach(function (key) {
if (tgt.style[key] === parentStyles[key]) {
tgt.style.removeProperty(key);
}
});
}
}
function walker(attrs, defaultStyles) {
return function walk(src, tgt) {
if (!tgt.style) return;
computedStyles(src, tgt.style, defaultStyles);
var children = src.childNodes;
for (var i = 0; i < children.length; i++) {
walk(children[i], tgt.childNodes[i]);
cleanStyle(tgt.childNodes[i], tgt.style);
}
if (tgt.attributes) {
cleanAttrs(tgt, attrs, defaultStyles);
}
};
}
// Clones an SVGElement, copies approprate atttributes and styles.
function cloneSvg(src, attrs, styles) {
var clonedSvg = src.cloneNode(true);
var srcChildren = src.querySelectorAll('*');
walker(attrs, styles)(src, clonedSvg);
computedStyles(src, clonedSvg.style, styles);
cleanAttrs(clonedSvg, attrs, styles);
Array.prototype.slice.call(clonedSvg.querySelectorAll('*')).forEach(function (target, index) {
computedStyles(srcChildren[index], target.style, styles);
cleanAttrs(target, attrs, styles);
});
return clonedSvg;

@@ -255,0 +274,0 @@ }

{
"name": "svgsaver",
"version": "0.3.3",
"version": "0.4.0",
"description": "download an SVG element with css styles",

@@ -10,12 +10,15 @@ "main": "lib/svgsaver.js",

"uglify": "uglifyjs browser.js -o browser.min.js",
"test": "npm run compile && karma start",
"test": "npm run zuul:phantom",
"compile": "npm run rollup && npm run browserify && npm run uglify",
"build": "npm run compile && npm run jsdoc2md",
"lint": "eslint src/ test/",
"lint": "semistandard test/*.js src/*.js",
"check": "npm run lint -s && dependency-check package.json --entry src",
"watch": "watch \"npm run build\" src/",
"watch:test": "watch \"npm test\" src/ test/",
"demo": "live-server --open=demo --ignore=src",
"start": "npm run demo & npm run watch",
"jsdoc2md": "jsdoc-parse ./src/svgsaver.js | dmd > API.md",
"version": "chg release -y && git add -A CHANGELOG.md"
"version": "chg release -y && git add -A CHANGELOG.md",
"zuul:server": "zuul --local 9966 --ui tape -- test/svgsaver-spec.js",
"zuul:phantom": "zuul --phantom --ui tape -- test/svgsaver-spec.js | tap-spec"
},

@@ -33,19 +36,16 @@ "keywords": [

"babel": "^5.8.23",
"babelify": "^6.4.0",
"browserify": "^11.2.0",
"dependency-check": "^2.5.1",
"dmd": "^1.2.0",
"eslint": "^1.4.3",
"jasmine-core": "^2.3.4",
"jsdoc-parse": "^1.1.0",
"karma": "^0.13.9",
"karma-chrome-launcher": "^0.2.0",
"karma-firefox-launcher": "^0.1.6",
"karma-ie-launcher": "^0.2.0",
"karma-jasmine": "^0.3.6",
"karma-phantomjs-launcher": "^0.2.1",
"live-server": "^0.8.1",
"phantomjs": "^1.9.18",
"rollup": "^0.16.4",
"semistandard": "^7.0.2",
"tap-spec": "^4.1.0",
"tape": "^4.2.2",
"uglifyjs": "^2.4.10",
"watch": "^0.16.0"
"watch": "^0.16.0",
"zuul": "^3.6.0"
},

@@ -52,0 +52,0 @@ "dependencies": {

@@ -5,5 +5,12 @@ # svgsaver

[![NPM version][npm-image]][npm-url]
[![Downloads][download-badge]][npm-url]
[![NPM version][npm-badge]][npm]
[![Downloads][download-badge]][npm]
![Downloads][bower-badge]
[![Build Status][travis-image]][travis-url]
[![Codacy Badge][codacy-badge]][Codacy]
[![js-semistandard-style][standard-badge]][semistandard]
[![License][license-badge]][MIT License]
## Features

@@ -60,7 +67,17 @@ - Download `<svg>` by element object.

## License
[MIT License](http://en.wikipedia.org/wiki/MIT_License)
[MIT License]
[npm-url]: https://npmjs.org/package/svgsaver
[npm-image]: https://img.shields.io/npm/v/svgsaver.svg?style=flat-square
[npm]: https://npmjs.org/package/svgsaver
[bower]: https://npmjs.org/package/svgsaver
[semistandard]: https://github.com/Flet/semistandard
[Codacy]: https://www.codacy.com/app/hypercubed/svgsaver
[MIT License]: http://en.wikipedia.org/wiki/MIT_License
[travis-url]: https://travis-ci.org/Hypercubed/svgsaver
[download-badge]: http://img.shields.io/npm/dm/svgsaver.svg?style=flat-squar
[travis-image]: https://img.shields.io/travis/Hypercubed/svgsaver.svg
[npm-badge]: https://img.shields.io/npm/v/svgsaver.svg
[bower-badge]: https://img.shields.io/bower/v/svgsaver.svg
[standard-badge]: https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg
[download-badge]: http://img.shields.io/npm/dm/svgsaver.svg
[codacy-badge]: https://api.codacy.com/project/badge/6fe47dae30b34d2da78572b3ea36cfe0
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg
/* Some utilities for cloning SVGs with inline styles */
import computedStyles from 'computed-styles';
import {isUndefined} from './utils';
import {isUndefined, isObject, clone} from './utils';
import {inheritableAttrs} from './collection';
// Removes attributes that are not valid for SVGs
function cleanAttrs(el, attrs, styles) { // attrs === false - remove all, attrs === true - allow all
function cleanAttrs (el, attrs, styles) { // attrs === false - remove all, attrs === true - allow all
if (attrs === true) { return; }
Array.prototype.slice.call(el.attributes)
.forEach(function(attr) {
.forEach(function (attr) {
// remove if it is not style nor on attrs whitelist
// keeping attributes that are also styles because attributes override
if (attr.specified) {
if(attrs ==='' || attrs === false || (isUndefined(styles[attr.name]) && attrs.indexOf(attr.name) < 0)) {
if (attrs === '' || attrs === false || (isUndefined(styles[attr.name]) && attrs.indexOf(attr.name) < 0)) {
el.removeAttribute(attr.name);

@@ -21,17 +22,36 @@ }

// Clones an SVGElement, copyies approprate atttributes and styles.
export function cloneSvg(src, attrs, styles) {
var clonedSvg = src.cloneNode(true);
var srcChildren = src.querySelectorAll('*');
function cleanStyle (tgt, parentStyles) {
if (tgt.style) {
inheritableAttrs.forEach(function (key) {
if (tgt.style[key] === parentStyles[key]) {
tgt.style.removeProperty(key);
}
});
}
}
computedStyles(src, clonedSvg.style, styles);
cleanAttrs(clonedSvg, attrs, styles);
function walker (attrs, defaultStyles) {
return function walk (src, tgt) {
if (!tgt.style) return;
Array.prototype.slice.call(clonedSvg.querySelectorAll('*'))
.forEach(function( target, index ) {
computedStyles(srcChildren[index], target.style, styles);
cleanAttrs(target, attrs, styles);
});
computedStyles(src, tgt.style, defaultStyles);
const children = src.childNodes;
for (var i = 0; i < children.length; i++) {
walk(children[i], tgt.childNodes[i]);
cleanStyle(tgt.childNodes[i], tgt.style);
}
if (tgt.attributes) {
cleanAttrs(tgt, attrs, defaultStyles);
}
};
}
// Clones an SVGElement, copies approprate atttributes and styles.
export function cloneSvg (src, attrs, styles) {
const clonedSvg = src.cloneNode(true);
walker(attrs, styles)(src, clonedSvg);
return clonedSvg;
}
export const svgStyles = { // Whitelist of CSS styles and default values
'alignment-baseline':'auto',
'baseline-shift':'baseline',
'clip':'auto',
'clip-path':'none',
'clip-rule':'nonzero',
'color':'rgb(51, 51, 51)',
'color-interpolation':'srgb',
'color-interpolation-filters':'linearrgb',
'color-profile':'auto',
'color-rendering':'auto',
'cursor':'auto',
'direction':'ltr',
'display':'inline',
'dominant-baseline':'auto',
'enable-background':'',
'fill':'rgb(0, 0, 0)',
'fill-opacity':'1',
'fill-rule':'nonzero',
'filter':'none',
'flood-color':'rgb(0, 0, 0)',
'flood-opacity':'1',
'font':'',
'font-family':'normal',
'font-size':'medium',
'font-size-adjust':'auto',
'font-stretch':'normal',
'font-style':'normal',
'font-variant':'normal',
'font-weight':'400',
'glyph-orientation-horizontal':'0deg',
'glyph-orientation-vertical':'auto',
'image-rendering':'auto',
'kerning':'auto',
'letter-spacing':'0',
'lighting-color':'rgb(255, 255, 255)',
'marker':'',
'marker-end':'none',
'marker-mid':'none',
'marker-start':'none',
'mask':'none',
'opacity':'1',
'overflow':'visible',
'paint-order': 'normal',
'pointer-events':'auto',
'shape-rendering':'auto',
'stop-color':'rgb(0, 0, 0)',
'stop-opacity':'1',
'stroke':'none',
'stroke-dasharray':'none',
'stroke-dashoffset':'0',
'stroke-linecap':'butt',
'stroke-linejoin':'miter',
'stroke-miterlimit':'4',
'stroke-opacity':'1',
'stroke-width':'1',
'text-anchor':'start',
'text-decoration':'none',
'text-rendering':'auto',
'unicode-bidi':'normal',
'visibility':'visible',
'word-spacing':'0px',
'writing-mode':'lr-tb'
'alignment-baseline': 'auto',
'baseline-shift': 'baseline',
'clip': 'auto',
'clip-path': 'none',
'clip-rule': 'nonzero',
'color': 'rgb(51, 51, 51)',
'color-interpolation': 'srgb',
'color-interpolation-filters': 'linearrgb',
'color-profile': 'auto',
'color-rendering': 'auto',
'cursor': 'auto',
'direction': 'ltr',
'display': 'inline',
'dominant-baseline': 'auto',
'enable-background': '',
'fill': 'rgb(0, 0, 0)',
'fill-opacity': '1',
'fill-rule': 'nonzero',
'filter': 'none',
'flood-color': 'rgb(0, 0, 0)',
'flood-opacity': '1',
'font': '',
'font-family': 'normal',
'font-size': 'medium',
'font-size-adjust': 'auto',
'font-stretch': 'normal',
'font-style': 'normal',
'font-variant': 'normal',
'font-weight': '400',
'glyph-orientation-horizontal': '0deg',
'glyph-orientation-vertical': 'auto',
'image-rendering': 'auto',
'kerning': 'auto',
'letter-spacing': '0',
'lighting-color': 'rgb(255, 255, 255)',
'marker': '',
'marker-end': 'none',
'marker-mid': 'none',
'marker-start': 'none',
'mask': 'none',
'opacity': '1',
'overflow': 'visible',
'paint-order': 'fill',
'pointer-events': 'auto',
'shape-rendering': 'auto',
'stop-color': 'rgb(0, 0, 0)',
'stop-opacity': '1',
'stroke': 'none',
'stroke-dasharray': 'none',
'stroke-dashoffset': '0',
'stroke-linecap': 'butt',
'stroke-linejoin': 'miter',
'stroke-miterlimit': '4',
'stroke-opacity': '1',
'stroke-width': '1',
'text-anchor': 'start',
'text-decoration': 'none',
'text-rendering': 'auto',
'unicode-bidi': 'normal',
'visibility': 'visible',
'word-spacing': '0px',
'writing-mode': 'lr-tb'
};
export const svgAttrs = [ // white list of attributes
'id', 'xml:base', 'xml:lang', 'xml:space', // Core
'id', 'xml: base', 'xml: lang', 'xml: space', // Core
'height', 'result', 'width', 'x', 'y', // Primitive
'xlink:href', // Xlink attribute
'style','class',
'd','pathLength', // Path
'x','y','dx','dy','glyphRef','format',
'x1','y1','x2','y2',
'rotate','textLength',
'cx','cy','r',
'rx','ry',
'fx','fy',
'width','height',
'refX','refY','orient',
'markerUnits','markerWidth','markerHeight',
'xlink: href', // Xlink attribute
'style', 'class',
'd', 'pathLength', // Path
'x', 'y', 'dx', 'dy', 'glyphRef', 'format',
'x1', 'y1', 'x2', 'y2',
'rotate', 'textLength',
'cx', 'cy', 'r',
'rx', 'ry',
'fx', 'fy',
'width', 'height',
'refX', 'refY', 'orient',
'markerUnits', 'markerWidth', 'markerHeight',
'maskUnits',
'transform',
'viewBox','version', // Container
'preserveAspectRatio','xmlns',
'viewBox', 'version', // Container
'preserveAspectRatio', 'xmlns',
'points', // Polygons

@@ -86,0 +86,0 @@ 'offset'

@@ -1,2 +0,2 @@

/* global saveAs:true */
/* global saveAs Image */

@@ -7,7 +7,6 @@ /* Some simple utilities for saving SVGs, including an alternative to saveAs */

//detection
// detection
const DownloadAttributeSupport = (typeof document !== 'undefined') && ('download' in document.createElement('a'));
export function saveUri(uri, name){
export function saveUri (uri, name) {
if (DownloadAttributeSupport) {

@@ -27,3 +26,3 @@ const dl = document.createElement('a');

export function savePng(uri, name){
export function savePng (uri, name) {
const canvas = document.createElement('canvas');

@@ -33,3 +32,3 @@ const context = canvas.getContext('2d');

const image = new Image();
image.onload = function() {
image.onload = function () {
canvas.width = image.width;

@@ -40,3 +39,3 @@ canvas.height = image.height;

if (isDefined(window.saveAs) && isDefined(canvas.toBlob)) {
canvas.toBlob(function(blob) {
canvas.toBlob(function (blob) {
saveAs(blob, name);

@@ -47,3 +46,2 @@ });

}
};

@@ -50,0 +48,0 @@ image.src = uri;

@@ -1,2 +0,2 @@

/* global saveAs:true */
/* global saveAs Blob */

@@ -9,3 +9,3 @@ import {svgAttrs, svgStyles, inheritableAttrs} from './collection';

// inheritable styles may be overridden by parent, always copy for now
inheritableAttrs.forEach(function(k) {
inheritableAttrs.forEach(function (k) {
if (k in svgStyles) {

@@ -28,3 +28,3 @@ svgStyles[k] = true;

*/
constructor({ attrs, styles } = {}) {
constructor ({ attrs, styles } = {}) {
this.attrs = (attrs === undefined) ? svgAttrs : attrs;

@@ -41,3 +41,3 @@ this.styles = (styles === undefined) ? svgStyles : styles;

*/
getHTML(el) {
getHTML (el) {
const svg = cloneSvg(el, this.attrs, this.styles);

@@ -62,3 +62,3 @@

*/
getBlob(el) {
getBlob (el) {
const html = this.getHTML(el);

@@ -75,3 +75,3 @@ return new Blob([html], { type: 'text/xml' });

*/
getUri(el) {
getUri (el) {
const html = this.getHTML(el);

@@ -92,6 +92,6 @@ if (isDefined(window.btoa)) {

*/
asSvg(el, filename) {
asSvg (el, filename) {
if (!filename || filename === '') {
filename = el.getAttribute('title');
filename = (filename || 'untitled')+'.svg';
filename = (filename || 'untitled') + '.svg';
}

@@ -113,6 +113,6 @@ if (isDefined(window.saveAs) && isFunction(Blob)) {

*/
asPng(el, filename) {
asPng (el, filename) {
if (!filename || filename === '') {
filename = el.getAttribute('title');
filename = (filename || 'untitled')+'.png';
filename = (filename || 'untitled') + '.png';
}

@@ -119,0 +119,0 @@ return savePng(this.getUri(el), filename);

@@ -6,1 +6,11 @@ /* Some simple utilities */

export const isUndefined = (a) => typeof a === 'undefined';
export const isObject = (a) => (a !== null && typeof a === 'object');
export function clone (obj) {
if (obj == null || typeof obj !== 'object') return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc