|  |  | 
 |  |  |  | 
 |  |  | 1. Create the SVG master file that includes all icons: | 
 |  |  |  | 
 |  |  | The master SVG icon-containing file is an SVG file that contains  | 
 |  |  | The master SVG icon-containing file is an SVG file that contains | 
 |  |  | <g> elements. Each <g> element should contain the markup of an SVG | 
 |  |  | icon. The <g> element has an ID that should  | 
 |  |  | correspond with the ID of the HTML element used on the page that should contain  | 
 |  |  | icon. The <g> element has an ID that should | 
 |  |  | correspond with the ID of the HTML element used on the page that should contain | 
 |  |  | or optionally be replaced by the icon. Additionally, one empty element should be | 
 |  |  | added at the end with id "svg_eof". | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  | - 'fallback (object literal)': List of raster images with each | 
 |  |  |   key being the SVG icon ID to replace, and the value the image file name. | 
 |  |  |    | 
 |  |  |  | 
 |  |  | - 'fallback_path (string)': The path to use for all images | 
 |  |  |   listed under "fallback" | 
 |  |  |    | 
 |  |  |  | 
 |  |  | - 'replace (boolean)': If set to true, HTML elements will be replaced by, | 
 |  |  |   rather than include the SVG icon. | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  | - 'resize (object literal)': List with selectors for keys and numbers | 
 |  |  |   as values. This allows an easy way to resize specific icons. | 
 |  |  |    | 
 |  |  | - 'callback (function)': A function to call when all icons have been loaded.  | 
 |  |  |   Includes an object literal as its argument with as keys all icon IDs and the  | 
 |  |  |  | 
 |  |  | - 'callback (function)': A function to call when all icons have been loaded. | 
 |  |  |   Includes an object literal as its argument with as keys all icon IDs and the | 
 |  |  |   icon as a jQuery object as its value. | 
 |  |  |  | 
 |  |  | - 'id_match (boolean)': Automatically attempt to match SVG icon ids with | 
 |  |  |   corresponding HTML id (default: true) | 
 |  |  |    | 
 |  |  |  | 
 |  |  | - 'no_img (boolean)': Prevent attempting to convert the icon into an <img> | 
 |  |  |   element (may be faster, help for browser consistency) | 
 |  |  |  | 
 |  |  | 
 |  |  |   $.getSvgIcon(id (string)); | 
 |  |  |  | 
 |  |  | This will return the icon (as jQuery object) with a given ID. | 
 |  |  |    | 
 |  |  |  | 
 |  |  | 6. To resize icons at a later point without using the callback, use this: | 
 |  |  |   $.resizeSvgIcons(resizeOptions) (use the same way as the "resize" parameter) | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  | $(function() { | 
 |  |  |   $.svgIcons('my_icon_set.svg'); // The SVG file that contains all icons | 
 |  |  |   // No options have been set, so all icons will automatically be inserted  | 
 |  |  |   // into HTML elements that match the same IDs.  | 
 |  |  |   // No options have been set, so all icons will automatically be inserted | 
 |  |  |   // into HTML elements that match the same IDs. | 
 |  |  | }); | 
 |  |  |  | 
 |  |  | Example usage #2: | 
 |  |  | 
 |  |  |     resize: function() { | 
 |  |  |       '#save_icon .svg_icon': 64  // The "save" icon will be resized to 64 x 64px | 
 |  |  |     }, | 
 |  |  |      | 
 |  |  |     callback: function(icons) { // Sets background color for "close" icon  | 
 |  |  |  | 
 |  |  |     callback: function(icons) { // Sets background color for "close" icon | 
 |  |  |       icons['close'].css('background','red'); | 
 |  |  |     }, | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     svgz: true // Indicates that an SVGZ file is being used | 
 |  |  |      | 
 |  |  |  | 
 |  |  |   }) | 
 |  |  | }); | 
 |  |  |  | 
 |  |  | 
 |  |  |       icons_made = false, data_loaded = false, load_attempts = 0, | 
 |  |  |       ua = navigator.userAgent, isOpera = !!window.opera, isSafari = (ua.indexOf('Safari/') > -1 && ua.indexOf('Chrome/')==-1), | 
 |  |  |       data_pre = 'data:image/svg+xml;charset=utf-8;base64,'; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(opts.svgz) { | 
 |  |  |         var data_el = $('<object data="' + file + '" type=image/svg+xml>').appendTo('body').hide(); | 
 |  |  |         try { | 
 |  |  | 
 |  |  |               if(err.responseText) { | 
 |  |  |                 svgdoc = parser.parseFromString(err.responseText, "text/xml"); | 
 |  |  |                 if(!svgdoc.childNodes.length) { | 
 |  |  |                   $(useFallback);                  | 
 |  |  |                   $(useFallback); | 
 |  |  |                 } | 
 |  |  |                 $(function() { | 
 |  |  |                   getIcons('ajax'); | 
 |  |  |                 });              | 
 |  |  |                 }); | 
 |  |  |               } else { | 
 |  |  |                 $(useFallback); | 
 |  |  |               } | 
 |  |  | 
 |  |  |           } | 
 |  |  |         }); | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |     function getIcons(evt, no_wait) { | 
 |  |  |       if(evt !== 'ajax') { | 
 |  |  |         if(data_loaded) return; | 
 |  |  |         // Webkit sometimes says svgdoc is undefined, other times | 
 |  |  |         // it fails to load all nodes. Thus we must make sure the "eof"  | 
 |  |  |         // it fails to load all nodes. Thus we must make sure the "eof" | 
 |  |  |         // element is loaded. | 
 |  |  |         svgdoc = data_el[0].contentDocument; // Needed again for Webkit | 
 |  |  |         var isReady = (svgdoc && svgdoc.getElementById('svg_eof')); | 
 |  |  | 
 |  |  |         } | 
 |  |  |         data_loaded = true; | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       elems = $(svgdoc.firstChild).children(); //.getElementsByTagName('foreignContent'); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(!opts.no_img) { | 
 |  |  |         var testSrc = data_pre + 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzUiIGhlaWdodD0iMjc1Ij48L3N2Zz4%3D'; | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         testImg = $(new Image()).attr({ | 
 |  |  |           src: testSrc, | 
 |  |  |           width: 0, | 
 |  |  | 
 |  |  |         },500); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     var setIcon = function(target, icon, id, setID) { | 
 |  |  |       if(isOpera) icon.css('visibility','hidden'); | 
 |  |  |       if(opts.replace) { | 
 |  |  | 
 |  |  |         if(cl) icon.attr('class','svg_icon '+cl); | 
 |  |  |         target.replaceWith(icon); | 
 |  |  |       } else { | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         target.append(icon); | 
 |  |  |       } | 
 |  |  |       if(isOpera) { | 
 |  |  | 
 |  |  |         },1); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     var addIcon = function(icon, id) { | 
 |  |  |       if(opts.id_match === undefined || opts.id_match !== false) { | 
 |  |  |         setIcon(holder, icon, id, true); | 
 |  |  |       } | 
 |  |  |       svg_icons[id] = icon; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     function makeIcons(toImage, fallback) { | 
 |  |  |       if(icons_made) return; | 
 |  |  |       if(opts.no_img) toImage = false; | 
 |  |  |       var holder; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(toImage) { | 
 |  |  |         var temp_holder = $(document.createElement('div')); | 
 |  |  |         temp_holder.hide().appendTo('body'); | 
 |  |  |       }  | 
 |  |  |       } | 
 |  |  |       if(fallback) { | 
 |  |  |         var path = opts.fallback_path?opts.fallback_path:''; | 
 |  |  |         $.each(fallback, function(id, imgsrc) { | 
 |  |  | 
 |  |  |               'height': icon_h, | 
 |  |  |               'alt': 'icon' | 
 |  |  |             }); | 
 |  |  |            | 
 |  |  |  | 
 |  |  |           addIcon(icon, id); | 
 |  |  |         }); | 
 |  |  |       } else { | 
 |  |  | 
 |  |  |           var h = svg.getAttribute('height'); | 
 |  |  |           svg.removeAttribute('width'); | 
 |  |  |           svg.removeAttribute('height'); | 
 |  |  |            | 
 |  |  |  | 
 |  |  |           var vb = svg.getAttribute('viewBox'); | 
 |  |  |           if(!vb) { | 
 |  |  |             svg.setAttribute('viewBox', [0,0,w,h].join(' ')); | 
 |  |  |           } | 
 |  |  |            | 
 |  |  |  | 
 |  |  |           // Not using jQuery to be a bit faster | 
 |  |  |           svgroot.setAttribute('xmlns', svgns); | 
 |  |  |           svgroot.setAttribute('width', icon_w); | 
 |  |  | 
 |  |  |           // Without cloning, Firefox will make another GET request. | 
 |  |  |           // With cloning, causes issue in Opera/Win/Non-EN | 
 |  |  |           if(!isOpera) svg = svg.cloneNode(true); | 
 |  |  |            | 
 |  |  |  | 
 |  |  |           svgroot.appendChild(svg); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |           if(toImage) { | 
 |  |  |             // Without cloning, Safari will crash | 
 |  |  |             // With cloning, causes issue in Opera/Win/Non-EN | 
 |  |  | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(opts.placement) { | 
 |  |  |         $.each(opts.placement, function(sel, id) { | 
 |  |  |           if(!svg_icons[id]) return; | 
 |  |  | 
 |  |  |  | 
 |  |  |       if(opts.callback) opts.callback(svg_icons); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     fixIDs = function(svg_el, svg_num, force) { | 
 |  |  |       var defs = svg_el.find('defs'); | 
 |  |  |       if(!defs.length) return svg_el; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(isOpera) { | 
 |  |  |         var id_elems = defs.find('*').filter(function() { | 
 |  |  |           return !!this.id; | 
 |  |  | 
 |  |  |       } else { | 
 |  |  |         var id_elems = defs.find('[id]'); | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var all_elems = svg_el[0].getElementsByTagName('*'), len = all_elems.length; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       id_elems.each(function(i) { | 
 |  |  |         var id = this.id; | 
 |  |  |         var no_dupes = ($(svgdoc).find('#' + id).length <= 1); | 
 |  |  | 
 |  |  |         // if(!force && no_dupes) return; | 
 |  |  |         var new_id = 'x' + id + svg_num + i; | 
 |  |  |         this.id = new_id; | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         var old_val = 'url(#' + id + ')'; | 
 |  |  |         var new_val = 'url(#' + new_id + ')'; | 
 |  |  |  | 
 |  |  | 
 |  |  |       }); | 
 |  |  |       return svg_el; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     function useFallback() { | 
 |  |  |       if(file.indexOf('.svgz') != -1) { | 
 |  |  |         var reg_file = file.replace('.svgz','.svg'); | 
 |  |  | 
 |  |  |         makeIcons(false, opts.fallback); | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |          | 
 |  |  |  | 
 |  |  |     function encode64(input) { | 
 |  |  |       // base64 strings are 4/3 larger than the original string | 
 |  |  |       if(window.btoa) return window.btoa(input); | 
 |  |  | 
 |  |  |       var chr1, chr2, chr3; | 
 |  |  |       var enc1, enc2, enc3, enc4; | 
 |  |  |       var i = 0, p = 0; | 
 |  |  |      | 
 |  |  |  | 
 |  |  |       do { | 
 |  |  |         chr1 = input.charCodeAt(i++); | 
 |  |  |         chr2 = input.charCodeAt(i++); | 
 |  |  |         chr3 = input.charCodeAt(i++); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |         enc1 = chr1 >> 2; | 
 |  |  |         enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | 
 |  |  |         enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | 
 |  |  |         enc4 = chr3 & 63; | 
 |  |  |      | 
 |  |  |  | 
 |  |  |         if (isNaN(chr2)) { | 
 |  |  |           enc3 = enc4 = 64; | 
 |  |  |         } else if (isNaN(chr3)) { | 
 |  |  |           enc4 = 64; | 
 |  |  |         } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |         output[p++] = _keyStr.charAt(enc1); | 
 |  |  |         output[p++] = _keyStr.charAt(enc2); | 
 |  |  |         output[p++] = _keyStr.charAt(enc3); | 
 |  |  |         output[p++] = _keyStr.charAt(enc4); | 
 |  |  |       } while (i < input.length); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |       return output.join(''); | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  |    | 
 |  |  |   $.getSvgIcon = function(id, uniqueClone) {  | 
 |  |  |  | 
 |  |  |   $.getSvgIcon = function(id, uniqueClone) { | 
 |  |  |     var icon = svg_icons[id]; | 
 |  |  |     if(uniqueClone && icon) { | 
 |  |  |       icon = fixIDs(icon, 0, true).clone(true); | 
 |  |  |     } | 
 |  |  |     return icon;  | 
 |  |  |     return icon; | 
 |  |  |   } | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   $.resizeSvgIcons = function(obj) { | 
 |  |  |     // FF2 and older don't detect .svg_icon, so we change it detect svg elems instead | 
 |  |  |     var change_sel = !$('.svg_icon:first').length; | 
 |  |  | 
 |  |  |       }); | 
 |  |  |     }); | 
 |  |  |   } | 
 |  |  |    | 
 |  |  | })(jQuery); | 
 |  |  |  | 
 |  |  | })(jQuery); |