diff --git a/LICENSE b/LICENSE index d877de8..d05b645 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Jonny Haynes +Copyright (c) 2015 Jonny Haynes & Oliver Farrell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index ebbbf2c..bf74ffd 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,15 @@ For a live demo check out this [example on CodePen](http://codepen.io/jonnyhayne ## Bower -If you're using [Bower](bower.io) to manage your front-end dependencies you can include this plugin as a component. Include `"inline-svg": "2.0.1"` in your `bower.json` file and run `bower install`. +If you're using [Bower](bower.io) to manage your front-end dependencies you can include this plugin as a component. Include `"inline-svg": "2.1.0"` in your `bower.json` file and run `bower install`. ## NPM If you're using NPM to manage your dependencies you can include this plugin as a module. Just run `npm install inline-svg`. ## Changelog -- **21/07/15:** 2.0.1 - Major upgrade. Added AMD support and fixed a long standing issue that would result in a warning in Google Chrome as we weren't handling the GET requests asynchronously. +- **31/07/15:** 2.1.0 – Added localStorage support to avoid making fresh HTTP request on every page load. When the contents of the SVG is loaded it is added to localStorage and then on repeat page loads the source is grabbed from localStorage. +- **31/07/15:** 2.0.1 - Major upgrade. Added AMD support and fixed a long standing issue that would result in a warning in Google Chrome as we weren't handling the GET requests asynchronously. - **18/06/15:** 1.2.0 – Converted to a Node.js module - **19/03/15:** 1.0.5 – Cleaning code to comply with Code Climate - **16/12/14:** 1.0.4 – Updated README with new CodePen demo and added an extra line regarding browser support. Changed `aria-label` to `aria-labelledby` and also added `role="img"` for better accessibility. diff --git a/bower.json b/bower.json index a90acfc..4114712 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "inline-svg", - "version": "2.0.1", + "version": "2.1.0", "homepage": "https://github.com/jonnyhaynes/inline-svg", "authors": [ "Jonny Haynes ", diff --git a/demo/index.html b/demo/index.html index 15d008c..59d8ad5 100644 --- a/demo/index.html +++ b/demo/index.html @@ -14,7 +14,7 @@ Twitter Icon Facebook Icon - + diff --git a/dist/inlineSVG.min.js b/dist/inlineSVG.min.js index dbfffef..67d5f7c 100644 --- a/dist/inlineSVG.min.js +++ b/dist/inlineSVG.min.js @@ -1 +1 @@ -!function(a,b){"function"==typeof define&&define.amd?define([],b(a)):"object"==typeof exports?module.exports=b(a):a.inlineSVG=b(a)}("undefined"!=typeof global?global:this.window||this.global,function(a){"use strict";var b,c={},d=!!document.querySelector&&!!a.addEventListener,e={initClass:"js-inlinesvg",svgSelector:"img.svg"},f=function(a){var b={},c=!1,d=0,e=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(c=arguments[0],d++);for(var f=function(a){for(var d in a)Object.prototype.hasOwnProperty.call(a,d)&&(c&&"[object Object]"===Object.prototype.toString.call(a[d])?b[d]=buoy.extend(!0,b[d],a[d]):b[d]=a[d])};e>d;d++){var g=arguments[d];f(g)}return b};return c.getAll=function(){var a=document.querySelectorAll(b.svgSelector);return a},c.inliner=function(){var a=c.getAll();Array.prototype.forEach.call(a,function(a,b){var c=a.src,d=a.attributes,e=new XMLHttpRequest;e.open("GET",c,!0),e.onload=function(){if(e.status>=200&&e.status<400){var b=new DOMParser,c=b.parseFromString(e.responseText,"text/xml"),f=c.getElementsByTagName("svg")[0];if(f.removeAttribute("xmlns:a"),f.removeAttribute("width"),f.removeAttribute("height"),f.removeAttribute("x"),f.removeAttribute("y"),f.removeAttribute("enable-background"),f.removeAttribute("xmlns:xlink"),f.removeAttribute("xml:space"),f.removeAttribute("version"),Array.prototype.slice.call(d).forEach(function(a){"src"!==a.name&&"alt"!==a.name&&f.setAttribute(a.name,a.value)}),f.classList?f.classList.add("inlined-svg"):f.className+=" inlined-svg",f.setAttribute("role","img"),d.longdesc){var g=document.createElementNS("http://www.w3.org/2000/svg","desc"),h=document.createTextNode(d.longdesc.value);g.appendChild(h),f.insertBefore(g,f.firstChild)}if(d.alt){f.setAttribute("aria-labelledby","title");var i=document.createElementNS("http://www.w3.org/2000/svg","title"),j=document.createTextNode(d.alt.value);i.appendChild(j),f.insertBefore(i,f.firstChild)}a.parentNode.replaceChild(f,a)}else console.error("There was an error retrieving the source of the SVG.")},e.onerror=function(){console.error("There was an error connecting to the origin server.")},e.send()})},c.init=function(a){d&&(b=f(e,a||{}),c.inliner(),document.documentElement.className+=" "+b.initClass)},c}); \ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define([],b(a)):"object"==typeof exports?module.exports=b(a):a.inlineSVG=b(a)}("undefined"!=typeof global?global:this.window||this.global,function(a){"use strict";var b,c={},d=!!document.querySelector&&!!a.addEventListener,e={initClass:"js-inlinesvg",svgSelector:"img.svg"},f=function(a){var b={},c=!1,d=0,e=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(c=arguments[0],d++);for(var f=function(a){for(var d in a)Object.prototype.hasOwnProperty.call(a,d)&&(c&&"[object Object]"===Object.prototype.toString.call(a[d])?b[d]=buoy.extend(!0,b[d],a[d]):b[d]=a[d])};e>d;d++){var g=arguments[d];f(g)}return b};return c.getAll=function(){var a=document.querySelectorAll(b.svgSelector);return a},c.inliner=function(){var a=c.getAll();Array.prototype.forEach.call(a,function(a,b){var c=a.src,d=a.attributes;if(localStorage.getItem(c)){var e=new DOMParser,f=e.parseFromString(localStorage.getItem(c),"text/xml"),g=f.getElementsByTagName("svg")[0];a.parentNode.replaceChild(g,a)}else{var h=new XMLHttpRequest;h.open("GET",c,!0),h.onload=function(){if(h.status>=200&&h.status<400){var b=new DOMParser,e=b.parseFromString(h.responseText,"text/xml"),f=e.getElementsByTagName("svg")[0];if(f.removeAttribute("xmlns:a"),f.removeAttribute("width"),f.removeAttribute("height"),f.removeAttribute("x"),f.removeAttribute("y"),f.removeAttribute("enable-background"),f.removeAttribute("xmlns:xlink"),f.removeAttribute("xml:space"),f.removeAttribute("version"),Array.prototype.slice.call(d).forEach(function(a){"src"!==a.name&&"alt"!==a.name&&f.setAttribute(a.name,a.value)}),f.classList?f.classList.add("inlined-svg"):f.className+=" inlined-svg",f.setAttribute("role","img"),d.longdesc){var g=document.createElementNS("http://www.w3.org/2000/svg","desc"),i=document.createTextNode(d.longdesc.value);g.appendChild(i),f.insertBefore(g,f.firstChild)}if(d.alt){f.setAttribute("aria-labelledby","title");var j=document.createElementNS("http://www.w3.org/2000/svg","title"),k=document.createTextNode(d.alt.value);j.appendChild(k),f.insertBefore(j,f.firstChild)}var l=document.createElement("div");l.appendChild(f),localStorage.setItem(c,l.innerHTML),a.parentNode.replaceChild(f,a)}else console.error("There was an error retrieving the source of the SVG.")},h.onerror=function(){console.error("There was an error connecting to the origin server.")},h.send()}})},c.init=function(a){d&&(b=f(e,a||{}),c.inliner(),document.documentElement.className+=" "+b.initClass)},c}); \ No newline at end of file diff --git a/package.json b/package.json index c17f3dd..fbd0c35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "inline-svg", - "version": "2.0.1", + "version": "2.1.0", "devDependencies": { "grunt": "0.4.5", "grunt-cli": "0.1.13", diff --git a/src/inlineSVG.js b/src/inlineSVG.js index 9adb795..59bfb8f 100755 --- a/src/inlineSVG.js +++ b/src/inlineSVG.js @@ -23,6 +23,12 @@ svgSelector: 'img.svg' }; + + /** + * Merge two objects together + * @private + * @param {Function} fn + */ var extend = function (fn) { // Variables @@ -88,82 +94,99 @@ var src = svg.src, attributes = svg.attributes; - // Get the contents of the SVG - var request = new XMLHttpRequest(); - request.open('GET', src, true); + if(!localStorage.getItem(src)) { + + // Get the contents of the SVG + var request = new XMLHttpRequest(); + request.open('GET', src, true); - request.onload = function () { - - if(request.status >= 200 && request.status < 400) { + request.onload = function () { - // Setup a parser to convert the response to text/xml in order for it - // to be manipulated and changed - var parser = new DOMParser(), - result = parser.parseFromString(request.responseText, "text/xml"), - inlinedSVG = result.getElementsByTagName('svg')[0]; - - // Remove some of the attributes that aren't needed - inlinedSVG.removeAttribute('xmlns:a'); - inlinedSVG.removeAttribute('width'); - inlinedSVG.removeAttribute('height'); - inlinedSVG.removeAttribute('x'); - inlinedSVG.removeAttribute('y'); - inlinedSVG.removeAttribute('enable-background'); - inlinedSVG.removeAttribute('xmlns:xlink'); - inlinedSVG.removeAttribute('xml:space'); - inlinedSVG.removeAttribute('version'); - - // Add in the attributes from the original except 'src' or - // 'alt', we don't need either - Array.prototype.slice.call(attributes).forEach(function(attribute) { - if(attribute.name !== 'src' && attribute.name !== 'alt') { - inlinedSVG.setAttribute(attribute.name, attribute.value); + if(request.status >= 200 && request.status < 400) { + + // Setup a parser to convert the response to text/xml in order for it + // to be manipulated and changed + var parser = new DOMParser(), + result = parser.parseFromString(request.responseText, 'text/xml'), + inlinedSVG = result.getElementsByTagName('svg')[0]; + + // Remove some of the attributes that aren't needed + inlinedSVG.removeAttribute('xmlns:a'); + inlinedSVG.removeAttribute('width'); + inlinedSVG.removeAttribute('height'); + inlinedSVG.removeAttribute('x'); + inlinedSVG.removeAttribute('y'); + inlinedSVG.removeAttribute('enable-background'); + inlinedSVG.removeAttribute('xmlns:xlink'); + inlinedSVG.removeAttribute('xml:space'); + inlinedSVG.removeAttribute('version'); + + // Add in the attributes from the original except 'src' or + // 'alt', we don't need either + Array.prototype.slice.call(attributes).forEach(function(attribute) { + if(attribute.name !== 'src' && attribute.name !== 'alt') { + inlinedSVG.setAttribute(attribute.name, attribute.value); + } + }); + + // Add an additional class the the inlined SVG to imply it was + // infact inlined, might be useful to know + if (inlinedSVG.classList) { + inlinedSVG.classList.add('inlined-svg'); + } else { + inlinedSVG.className += ' ' + 'inlined-svg'; } - }); - // Add an additional class the the inlined SVG to imply it was - // infact inlined, might be useful to know - if (inlinedSVG.classList) { - inlinedSVG.classList.add('inlined-svg'); - } else { - inlinedSVG.className += ' ' + 'inlined-svg'; - } + // Add in some accessibility quick wins + inlinedSVG.setAttribute('role', 'img'); - // Add in some accessibility quick wins - inlinedSVG.setAttribute('role', 'img'); + if(attributes.longdesc) { + var description = document.createElementNS('http://www.w3.org/2000/svg', 'desc'), + descriptionText = document.createTextNode(attributes.longdesc.value); - if(attributes.longdesc) { - var description = document.createElementNS('http://www.w3.org/2000/svg', 'desc'), - descriptionText = document.createTextNode(attributes.longdesc.value); + description.appendChild(descriptionText); + inlinedSVG.insertBefore(description, inlinedSVG.firstChild); + } - description.appendChild(descriptionText); - inlinedSVG.insertBefore(description, inlinedSVG.firstChild); - } + if(attributes.alt) { + inlinedSVG.setAttribute('aria-labelledby', 'title'); - if(attributes.alt) { - inlinedSVG.setAttribute('aria-labelledby', 'title'); + var title = document.createElementNS('http://www.w3.org/2000/svg', 'title'), + titleText = document.createTextNode(attributes.alt.value); - var title = document.createElementNS('http://www.w3.org/2000/svg', 'title'), - titleText = document.createTextNode(attributes.alt.value); + title.appendChild(titleText); + inlinedSVG.insertBefore(title, inlinedSVG.firstChild); + } + + // Store the source in localStorage to avoid making requests every time + var tempContainer = document.createElement('div'); + tempContainer.appendChild(inlinedSVG); + + localStorage.setItem(src, tempContainer.innerHTML); + + // Replace the image with the SVG + svg.parentNode.replaceChild(inlinedSVG, svg); - title.appendChild(titleText); - inlinedSVG.insertBefore(title, inlinedSVG.firstChild); + } else { + console.error('There was an error retrieving the source of the SVG.'); } - svg.parentNode.replaceChild(inlinedSVG, svg); + }; - } else { - console.error('There was an error retrieving the source of the SVG.'); - } + request.onerror = function () { + console.error('There was an error connecting to the origin server.'); + }; - }; + request.send(); + + } else { + var parse = new DOMParser(), + result = parse.parseFromString(localStorage.getItem(src), 'text/xml'), + inlinedSVG = result.getElementsByTagName('svg')[0]; - request.onerror = function () { - console.error('There was an error connecting to the origin server.'); - }; + svg.parentNode.replaceChild(inlinedSVG, svg); + } - request.send(); - }); };