vue-inline-svg
Advanced tools
Comparing version 3.1.0 to 3.1.1
@@ -8,5 +8,6 @@ (function (global, factory) { | ||
// peer dep is not installed during test | ||
/** @type Object{string: Promise<Element>} */ | ||
/** @type Record<string, PromiseWithState<Element>> */ | ||
var cache = {}; | ||
/** | ||
@@ -16,3 +17,2 @@ * Remove false attrs | ||
*/ | ||
function filterAttrs(attrs) { | ||
@@ -23,7 +23,5 @@ return Object.keys(attrs).reduce(function (result, key) { | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
var InlineSvg = { | ||
@@ -36,6 +34,8 @@ name: 'InlineSvg', | ||
} | ||
return vue.h('svg', Object.assign({}, // source attrs | ||
this.getSvgAttrs(this.svgElSource), // component attrs and listeners | ||
filterAttrs(this.$attrs), // content | ||
return vue.h('svg', Object.assign({}, | ||
// source attrs | ||
this.getSvgAttrs(this.svgElSource), | ||
// component attrs and listeners | ||
filterAttrs(this.$attrs), | ||
// content | ||
{ | ||
@@ -86,11 +86,8 @@ innerHTML: this.getSvgContent(this.svgElSource) | ||
var attrs = svgEl.attributes; | ||
if (!attrs) { | ||
return svgAttrs; | ||
} | ||
for (var i = attrs.length - 1; i >= 0; i--) { | ||
svgAttrs[attrs[i].name] = attrs[i].value; | ||
} | ||
return svgAttrs; | ||
@@ -101,11 +98,9 @@ }, | ||
svgEl = this.transformSource(svgEl); | ||
if (this.title) { | ||
setTitle(svgEl, this.title); | ||
} // copy inner html | ||
} | ||
// copy inner html | ||
return svgEl.innerHTML; | ||
}, | ||
/** | ||
@@ -117,3 +112,2 @@ * Get svgElSource | ||
var _this = this; | ||
// fill cache by src with promise | ||
@@ -123,14 +117,13 @@ if (!cache[src]) { | ||
cache[src] = this.download(src); | ||
} // notify svg is unloaded | ||
if (this.svgElSource && cache[src].isPending() && !this.keepDuringLoading) { | ||
} | ||
// notify svg is unloaded | ||
if (this.svgElSource && cache[src].getIsPending() && !this.keepDuringLoading) { | ||
this.svgElSource = null; | ||
this.$emit('unloaded'); | ||
} // inline svg when cached promise resolves | ||
} | ||
// inline svg when cached promise resolves | ||
cache[src].then(function (svg) { | ||
_this.svgElSource = svg; // wait to render | ||
_this.svgElSource = svg; | ||
// wait to render | ||
_this.$nextTick(function () { | ||
@@ -144,17 +137,13 @@ // notify | ||
_this.svgElSource = null; | ||
_this.$emit('unloaded'); | ||
} // remove cached rejected promise so next image can try load again | ||
} | ||
// remove cached rejected promise so next image can try load again | ||
delete cache[src]; | ||
_this.$emit('error', err); | ||
}); | ||
}, | ||
/** | ||
* Get the contents of the SVG | ||
* @param {string} url | ||
* @returns {Promise<Element>} | ||
* @returns {PromiseWithState<Element>} | ||
*/ | ||
@@ -165,3 +154,2 @@ download: function download(url) { | ||
request.open('GET', url, true); | ||
request.onload = function () { | ||
@@ -174,3 +162,2 @@ if (request.status >= 200 && request.status < 400) { | ||
var svgEl = result.getElementsByTagName('svg')[0]; | ||
if (svgEl) { | ||
@@ -189,3 +176,2 @@ // svgEl = this.transformSource(svgEl); | ||
}; | ||
request.onerror = reject; | ||
@@ -197,2 +183,3 @@ request.send(); | ||
}; | ||
/** | ||
@@ -203,6 +190,4 @@ * Create or edit the <title> element of a SVG | ||
*/ | ||
function setTitle(svg, title) { | ||
var titleTags = svg.getElementsByTagName('title'); | ||
if (titleTags.length) { | ||
@@ -215,8 +200,11 @@ // overwrite existing title | ||
titleEl.textContent = title; | ||
svg.appendChild(titleEl); | ||
// svg.prepend(titleEl); | ||
svg.insertBefore(titleEl, svg.firstChild); | ||
} | ||
} | ||
/** | ||
* @typedef {Promise} PromiseWithState | ||
* @property {Function<boolean>} isPending | ||
* @typedef {Promise & object} PromiseWithState | ||
* @property {function: boolean} getIsPending | ||
* @template T | ||
*/ | ||
@@ -226,13 +214,14 @@ | ||
* This function allow you to modify a JS Promise by adding some status properties. | ||
* @param {Promise|PromiseWithState} promise | ||
* @return {PromiseWithState} | ||
* @template {any} T | ||
* @param {Promise<T>|PromiseWithState<T>} promise | ||
* @return {PromiseWithState<T>} | ||
*/ | ||
function makePromiseState(promise) { | ||
// Don't modify any promise that has been already modified. | ||
if (promise.isPending) return promise; // Set initial state | ||
if (promise.getIsPending) return promise; | ||
var isPending = true; // Observe the promise, saving the fulfillment in a closure scope. | ||
// Set initial state | ||
var isPending = true; | ||
// Observe the promise, saving the fulfillment in a closure scope. | ||
var result = promise.then(function (v) { | ||
@@ -245,7 +234,5 @@ isPending = false; | ||
}); | ||
result.isPending = function getIsPending() { | ||
result.getIsPending = function getIsPending() { | ||
return isPending; | ||
}; | ||
return result; | ||
@@ -252,0 +239,0 @@ } |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("vue")):"function"==typeof define&&define.amd?define(["vue"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).VueInlineSvg=t(e.Vue)}(this,(function(e){"use strict";var t={};return{name:"InlineSvg",inheritAttrs:!1,render:function(){return this.svgElSource?e.h("svg",Object.assign({},this.getSvgAttrs(this.svgElSource),(t=this.$attrs,Object.keys(t).reduce((function(e,n){return!1!==t[n]&&null!==t[n]&&void 0!==t[n]&&(e[n]=t[n]),e}),{})),{innerHTML:this.getSvgContent(this.svgElSource)})):null;var t},props:{src:{type:String,required:!0},title:{type:String},transformSource:{type:Function,default:function(e){return e}},keepDuringLoading:{type:Boolean,default:!0}},emits:["loaded","unloaded","error"],data:function(){return{svgElSource:null}},watch:{src:function(e){this.getSource(e)}},mounted:function(){this.getSource(this.src)},methods:{getSvgAttrs:function(e){var t={},n=e.attributes;if(!n)return t;for(var r=n.length-1;r>=0;r--)t[n[r].name]=n[r].value;return t},getSvgContent:function(e){return e=e.cloneNode(!0),e=this.transformSource(e),this.title&&function(e,t){var n=e.getElementsByTagName("title");if(n.length)n[0].textContent=t;else{var r=document.createElementNS("http://www.w3.org/2000/svg","title");r.textContent=t,e.appendChild(r)}}(e,this.title),e.innerHTML},getSource:function(e){var n=this;t[e]||(t[e]=this.download(e)),this.svgElSource&&t[e].isPending()&&!this.keepDuringLoading&&(this.svgElSource=null,this.$emit("unloaded")),t[e].then((function(e){n.svgElSource=e,n.$nextTick((function(){n.$emit("loaded",n.$el)}))})).catch((function(r){n.svgElSource&&(n.svgElSource=null,n.$emit("unloaded")),delete t[e],n.$emit("error",r)}))},download:function(e){return function(e){if(e.isPending)return e;var t=!0,n=e.then((function(e){return t=!1,e}),(function(e){throw t=!1,e}));return n.isPending=function(){return t},n}(new Promise((function(t,n){var r=new XMLHttpRequest;r.open("GET",e,!0),r.onload=function(){if(r.status>=200&&r.status<400)try{var e=(new DOMParser).parseFromString(r.responseText,"text/xml").getElementsByTagName("svg")[0];e?t(e):n(new Error('Loaded file is not valid SVG"'))}catch(e){n(e)}else n(new Error("Error loading SVG"))},r.onerror=n,r.send()})))}}}})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("vue")):"function"==typeof define&&define.amd?define(["vue"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).VueInlineSvg=t(e.Vue)}(this,(function(e){"use strict";var t={};return{name:"InlineSvg",inheritAttrs:!1,render:function(){return this.svgElSource?e.h("svg",Object.assign({},this.getSvgAttrs(this.svgElSource),(t=this.$attrs,Object.keys(t).reduce((function(e,n){return!1!==t[n]&&null!==t[n]&&void 0!==t[n]&&(e[n]=t[n]),e}),{})),{innerHTML:this.getSvgContent(this.svgElSource)})):null;var t},props:{src:{type:String,required:!0},title:{type:String},transformSource:{type:Function,default:function(e){return e}},keepDuringLoading:{type:Boolean,default:!0}},emits:["loaded","unloaded","error"],data:function(){return{svgElSource:null}},watch:{src:function(e){this.getSource(e)}},mounted:function(){this.getSource(this.src)},methods:{getSvgAttrs:function(e){var t={},n=e.attributes;if(!n)return t;for(var r=n.length-1;r>=0;r--)t[n[r].name]=n[r].value;return t},getSvgContent:function(e){return e=e.cloneNode(!0),e=this.transformSource(e),this.title&&function(e,t){var n=e.getElementsByTagName("title");if(n.length)n[0].textContent=t;else{var r=document.createElementNS("http://www.w3.org/2000/svg","title");r.textContent=t,e.insertBefore(r,e.firstChild)}}(e,this.title),e.innerHTML},getSource:function(e){var n=this;t[e]||(t[e]=this.download(e)),this.svgElSource&&t[e].getIsPending()&&!this.keepDuringLoading&&(this.svgElSource=null,this.$emit("unloaded")),t[e].then((function(e){n.svgElSource=e,n.$nextTick((function(){n.$emit("loaded",n.$el)}))})).catch((function(r){n.svgElSource&&(n.svgElSource=null,n.$emit("unloaded")),delete t[e],n.$emit("error",r)}))},download:function(e){return function(e){if(e.getIsPending)return e;var t=!0,n=e.then((function(e){return t=!1,e}),(function(e){throw t=!1,e}));return n.getIsPending=function(){return t},n}(new Promise((function(t,n){var r=new XMLHttpRequest;r.open("GET",e,!0),r.onload=function(){if(r.status>=200&&r.status<400)try{var e=(new DOMParser).parseFromString(r.responseText,"text/xml").getElementsByTagName("svg")[0];e?t(e):n(new Error('Loaded file is not valid SVG"'))}catch(e){n(e)}else n(new Error("Error loading SVG"))},r.onerror=n,r.send()})))}}}})); |
{ | ||
"name": "vue-inline-svg", | ||
"version": "3.1.0", | ||
"version": "3.1.1", | ||
"description": "Replace SVG images with inline SVG element", | ||
"type": "module", | ||
"main": "dist/vue-inline-svg.js", | ||
@@ -17,3 +18,5 @@ "module": "src/index.js", | ||
"build": "rollup -c rollup.conf.js", | ||
"test": "npm run lint && npx npm-install-peers && check-dts test/*.ts", | ||
"test": "npm run lint && npm run test:ts", | ||
"test:ts": "tsc -p .", | ||
"test:dts": "npx npm-install-peers && check-dts test/*.ts", | ||
"lint": "eslint src/*.js", | ||
@@ -47,13 +50,14 @@ "lint:fix": "eslint src/*.js --fix", | ||
"devDependencies": { | ||
"@babel/core": "^7.15.5", | ||
"@babel/preset-env": "^7.15.6", | ||
"@rollup/plugin-babel": "^5.3.0", | ||
"check-dts": "^0.5.6", | ||
"eslint": "^7.32.0", | ||
"eslint-config-airbnb-base": "^14.2.1", | ||
"eslint-plugin-import": "^2.24.2", | ||
"@babel/core": "^7.20.12", | ||
"@babel/preset-env": "^7.20.2", | ||
"@rollup/plugin-babel": "^6.0.3", | ||
"@rollup/plugin-terser": "^0.4.0", | ||
"check-dts": "^0.6.7", | ||
"eslint": "^8.33.0", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
"eslint-plugin-import": "^2.27.5", | ||
"pre-commit": "^1.2.2", | ||
"rollup": "^2.58.0", | ||
"rollup-plugin-terser": "^7.0.2" | ||
"rollup": "^3.13.0", | ||
"typescript": "^4.9.5" | ||
} | ||
} |
@@ -18,3 +18,3 @@ # Vue Inline SVG | ||
- [CDN](#cdn) | ||
- [Vue v3](#vue-v3) | ||
- [Vue 3](#vue-v3) | ||
- [Usage](#usage) | ||
@@ -83,6 +83,7 @@ - [props](#props) | ||
Version of `vue-inline-svg` with support of Vue v3 is available under `next` tag | ||
from NPM | ||
```bash | ||
npm install vue-inline-svg@next | ||
``` | ||
or from CDN | ||
```html | ||
@@ -89,0 +90,0 @@ <script src="https://unpkg.com/vue-inline-svg@next"></script> |
@@ -5,3 +5,3 @@ // peer dep is not installed during test | ||
/** @type Object{string: Promise<Element>} */ | ||
/** @type Record<string, PromiseWithState<Element>> */ | ||
const cache = {}; | ||
@@ -110,3 +110,3 @@ | ||
// notify svg is unloaded | ||
if (this.svgElSource && cache[src].isPending() && !this.keepDuringLoading) { | ||
if (this.svgElSource && cache[src].getIsPending() && !this.keepDuringLoading) { | ||
this.svgElSource = null; | ||
@@ -141,3 +141,3 @@ this.$emit('unloaded'); | ||
* @param {string} url | ||
* @returns {Promise<Element>} | ||
* @returns {PromiseWithState<Element>} | ||
*/ | ||
@@ -189,3 +189,4 @@ download(url) { | ||
titleEl.textContent = title; | ||
svg.appendChild(titleEl); | ||
// svg.prepend(titleEl); | ||
svg.insertBefore(titleEl, svg.firstChild); | ||
} | ||
@@ -195,4 +196,5 @@ } | ||
/** | ||
* @typedef {Promise} PromiseWithState | ||
* @property {Function<boolean>} isPending | ||
* @typedef {Promise & object} PromiseWithState | ||
* @property {function: boolean} getIsPending | ||
* @template T | ||
*/ | ||
@@ -202,8 +204,9 @@ | ||
* This function allow you to modify a JS Promise by adding some status properties. | ||
* @param {Promise|PromiseWithState} promise | ||
* @return {PromiseWithState} | ||
* @template {any} T | ||
* @param {Promise<T>|PromiseWithState<T>} promise | ||
* @return {PromiseWithState<T>} | ||
*/ | ||
function makePromiseState(promise) { | ||
// Don't modify any promise that has been already modified. | ||
if (promise.isPending) return promise; | ||
if (promise.getIsPending) return promise; | ||
@@ -225,3 +228,3 @@ // Set initial state | ||
result.isPending = function getIsPending() { return isPending; }; | ||
result.getIsPending = function getIsPending() { return isPending; }; | ||
return result; | ||
@@ -228,0 +231,0 @@ } |
@@ -12,3 +12,3 @@ /* | ||
title?: string; | ||
transformSource?: (svg: string) => string; | ||
transformSource?: (svg: SVGElement) => SVGElement; | ||
keepDuringLoading?: boolean; | ||
@@ -15,0 +15,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
460
218
Yes
25709
11
7