PageSourceSearch

https://www.ipaustralia.gov.au/-/media/Base-Themes/SVG-Inject/scripts/svg-inject.js

js ipaustralia.gov.au collected 2026-10-01 08:38:33 UTC 26,509 bytes, 697 lines download raw bytes

1/**
2 * SVGInject - Version 1.2.3
3 * A tiny, intuitive, robust, caching solution for injecting SVG files inline into the DOM.
4 *
5 * https://github.com/iconfu/svg-inject
6 *
7 * Copyright (c) 2018 INCORS, the creators of iconfu.com
8 * @license MIT License - https://github.com/iconfu/svg-inject/blob/master/LICENSE
9 */
10
11(function(window, document) {
12  // constants for better minification
13  var _CREATE_ELEMENT_ = 'createElement';
14  var _GET_ELEMENTS_BY_TAG_NAME_ = 'getElementsByTagName';
15  var _LENGTH_ = 'length';
16  var _STYLE_ = 'style';
17  var _TITLE_ = 'title';
18  var _UNDEFINED_ = 'undefined';
19  var _SET_ATTRIBUTE_ = 'setAttribute';
20  var _GET_ATTRIBUTE_ = 'getAttribute';
21
22  var NULL = null;
23
24  // constants
25  var __SVGINJECT = '__svgInject';
26  var ID_SUFFIX = '--inject-';
27  var ID_SUFFIX_REGEX = new RegExp(ID_SUFFIX + '\\d+', "g");
28  var LOAD_FAIL = 'LOAD_FAIL';
29  var SVG_NOT_SUPPORTED = 'SVG_NOT_SUPPORTED';
30  var SVG_INVALID = 'SVG_INVALID';
31  var ATTRIBUTE_EXCLUSION_NAMES = ['src', 'alt', 'onload', 'onerror'];
32  var A_ELEMENT = document[_CREATE_ELEMENT_]('a');
33  var IS_SVG_SUPPORTED = typeof SVGRect != _UNDEFINED_;
34  var DEFAULT_OPTIONS = {
35    useCache: true,
36    copyAttributes: true,
37    makeIdsUnique: true
38  };
39  // Map of IRI referenceable tag names to properties that can reference them. This is defined in
40  // https://www.w3.org/TR/SVG11/linking.html#processingIRI
41  var IRI_TAG_PROPERTIES_MAP = {
42    clipPath: ['clip-path'],
43    'color-profile': NULL,
44    cursor: NULL,
45    filter: NULL,
46    linearGradient: ['fill', 'stroke'],
47    marker: ['marker', 'marker-end', 'marker-mid', 'marker-start'],
48    mask: NULL,
49    pattern: ['fill', 'stroke'],
50    radialGradient: ['fill', 'stroke']
51  };
52  var INJECTED = 1;
53  var FAIL = 2;
54
55  var uniqueIdCounter = 1;
56  var xmlSerializer;
57  var domParser;
58
59
60  // creates an SVG document from an SVG string
61  function svgStringToSvgDoc(svgStr) {
62    domParser = domParser || new DOMParser();
63    return domParser.parseFromString(svgStr, 'text/xml');
64  }
65
66
67  // searializes an SVG element to an SVG string
68  function svgElemToSvgString(svgElement) {
69    xmlSerializer = xmlSerializer || new XMLSerializer();
70    return xmlSerializer.serializeToString(svgElement);
71  }
72
73
74  // Returns the absolute url for the specified url
75  function getAbsoluteUrl(url) {
76    A_ELEMENT.href = url;
77    return A_ELEMENT.href;
78  }
79
80
81  // Load svg with an XHR request
82  function loadSvg(url, callback, errorCallback) {
83    if (url) {
84      var req = new XMLHttpRequest();
85      req.onreadystatechange = function() {
86        if (req.readyState == 4) {
87          // readyState is DONE
88          var status = req.status;
89          if (status == 200) {
90            // request status is OK
91            callback(req.responseXML, req.responseText.trim());
92          } else if (status >= 400) {
93            // request status is error (4xx or 5xx)
94            errorCallback();
95          } else if (status == 0) {
96            // request status 0 can indicate a failed cross-domain call
97            errorCallback();
98          }
99        }
100      };
101      req.open('GET', url, true);
102      req.send();
103    }
104  }
105
106
107  // Copy attributes from img element to svg element
108  function copyAttributes(imgElem, svgElem) {
109    var attribute;
110    var attributeName;
111    var attributeValue;
112    var attributes = imgElem.attributes;
113    for (var i = 0; i < attributes[_LENGTH_]; i++) {
114      attribute = attributes[i];
115      attributeName = attribute.name;
116      // Only copy attributes not explicitly excluded from copying
117      if (ATTRIBUTE_EXCLUSION_NAMES.indexOf(attributeName) == -1) {
118        attributeValue = attribute.value;
119        // If img attribute is "title", insert a title element into SVG element
120        if (attributeName == _TITLE_) {
121          var titleElem;
122          var firstElementChild = svgElem.firstElementChild;
123          if (firstElementChild && firstElementChild.localName.toLowerCase() == _TITLE_) {
124            // If the SVG element's first child is a title element, keep it as the title element
125            titleElem = firstElementChild;
126          } else {
127            // If the SVG element's first child element is not a t
127itle element, create a new title
128            // ele,emt and set it as the first child
129            titleElem = document[_CREATE_ELEMENT_ + 'NS']('http://www.w3.org/2000/svg', _TITLE_);
130            svgElem.insertBefore(titleElem, firstElementChild);
131          }
132          // Set new title content
133          titleElem.textContent = attributeValue;
134        } else {
135          // Set img attribute to svg element
136          svgElem[_SET_ATTRIBUTE_](attributeName, attributeValue);
137        }
138      }
139    }
140  }
141
142
143  // This function appends a suffix to IDs of referenced elements in the <defs> in order to  to avoid ID collision
144  // between multiple injected SVGs. The suffix has the form "--inject-X", where X is a running number which is
145  // incremented with each injection. References to the IDs are adjusted accordingly.
146  // We assume tha all IDs within the injected SVG are unique, therefore the same suffix can be used for all IDs of one
147  // injected SVG.
148  // If the onlyReferenced argument is set to true, only those IDs will be made unique that are referenced from within the SVG
149  function makeIdsUnique(svgElem, onlyReferenced) {
150    var idSuffix = ID_SUFFIX + uniqueIdCounter++;
151    // Regular expression for functional notations of an IRI references. This will find occurences in the form
152    // url(#anyId) or url("#anyId") (for Internet Explorer) and capture the referenced ID
153    var funcIriRegex = /url\("?#([a-zA-Z][\w:.-]*)"?\)/g;
154    // Get all elements with an ID. The SVG spec recommends to put referenced elements inside <defs> elements, but
155    // this is not a requirement, therefore we have to search for IDs in the whole SVG.
156    var idElements = svgElem.querySelectorAll('[id]');
157    var idElem;
158    // An object containing referenced IDs  as keys is used if only referenced IDs should be uniquified.
159    // If this object does not exist, all IDs will be uniquified.
160    var referencedIds = onlyReferenced ? [] : NULL;
161    var tagName;
162    var iriTagNames = {};
163    var iriProperties = [];
164    var changed = false;
165    var i, j;
166
167    if (idElements[_LENGTH_]) {
168      // Make all IDs unique by adding the ID suffix and collect all encountered tag names
169      // that are IRI referenceable from properities.
170      for (i = 0; i < idElements[_LENGTH_]; i++) {
171        tagName = idElements[i].localName; // Use non-namespaced tag name
172        // Make ID unique if tag name is IRI referenceable
173        if (tagName in IRI_TAG_PROPERTIES_MAP) {
174          iriTagNames[tagName] = 1;
175        }
176      }
177      // Get all properties that are mapped to the found IRI referenceable tags
178      for (tagName in iriTagNames) {
179        (IRI_TAG_PROPERTIES_MAP[tagName] || [tagName]).forEach(function (mappedProperty) {
180          // Add mapped properties to array of iri referencing properties.
181          // Use linear search here because the number of possible entries is very small (maximum 11)
182          if (iriProperties.indexOf(mappedProperty) < 0) {
183            iriProperties.push(mappedProperty);
184          }
185        });
186      }
187      if (iriProperties[_LENGTH_]) {
188        // Add "style" to properties, because it may contain references in the form 'style="fill:url(#myFill)"'
189        iriProperties.push(_STYLE_);
190      }
191      // Run through all elements of the SVG and replace IDs in references.
192      // To get all descending elements, getElementsByTagName('*') seems to perform faster than querySelectorAll('*').
193      // Since svgElem.getElementsByTagName('*') does not return the svg element itself, we have to handle it separately.
194      var descElements = svgElem[_GET_ELEMENTS_BY_TAG_NAME_]('*');
195      var element = svgElem;
196      var propertyName;
197      var value;
198      var newValue;
199      for (i = -1; element != NULL;) {
200        if (element.localName == _STYLE_) {
201          // If element is a style element, replace IDs in all occurences of "url(#anyId)" in text content
202          value = element.textContent;
203          newValue = value && value.replace(funcIriRegex, function(match, id) {
204            if (referencedIds) {
205              referencedIds[id] = 1;
206            }
207            return 'url(#' + id + idSuffix + ')';
208          });
209          if (newValue !== value) {
210            element.textContent = newValue;
211          }
212        } else if (element.hasAttributes()) {
213          // Run through all property names for which IDs were found
214          for (j = 0; j < iriProperties[_LENGTH_]; j++) {
215            propertyName = iriProperties[j];
216            value = element[_GET_ATTRIBUTE_](propertyName);
217            newValue = value && value.replace(funcIriRegex, function(match, id) {
218              if (referencedIds) {
219                referencedIds[id] = 1;
220              }
221                return 'url(#' + id + idSuffix + ')';
222            });
223            if (newValue !== value) {
224              element[_SET_ATTRIBUTE_](propertyName, newValue);
225            }
226          }
227          // Replace IDs in xlink:ref and href attributes
228          ['xlink:href', 'href'].forEach(function(refAttrName) {
229            var iri = element[_GET_ATTRIBUTE_](refAttrName);
230            if (/^\s*#/.test(iri)) { // Check if iri is non-null and internal reference
231              iri = iri.trim();
232              element[_SET_ATTRIBUTE_](refAttrName, iri + idSuffix);
233              if (referencedIds) {
234                // Add ID to referenced IDs
235                referencedIds[iri.substring(1)] = 1;
236              }
237            }
238          });
239        }
240        element = descElements[++i];
241      }
242      for (i = 0; i < idElements[_LENGTH_]; i++) {
243        idElem = idElements[i];
244        // If set of referenced IDs exists, make only referenced IDs unique,
245        // otherwise make all IDs unique.
246        if (!referencedIds || referencedIds[idElem.id]) {
247          // Add suffix to element's ID
248          idElem.id += idSuffix;
249          changed = true;
250        }
251      }
252    }
253    // return true if SVG element has changed
254    return changed;
255  }
256
257
258  // For cached SVGs the IDs are made unique by simply replacing the already inserted unique IDs 
258with a
259  // higher ID counter. This is much more performant than a call to makeIdsUnique().
260  function makeIdsUniqueCached(svgString) {
261    return svgString.replace(ID_SUFFIX_REGEX, ID_SUFFIX + uniqueIdCounter++);
262  }
263
264
265  // Inject SVG by replacing the img element with the SVG element in the DOM
266  function inject(imgElem, svgElem, absUrl, options) {
267    if (svgElem) {
268      svgElem[_SET_ATTRIBUTE_]('data-inject-url', absUrl);
269      var parentNode = imgElem.parentNode;
270      if (parentNode) {
271        if (options.copyAttributes) {
272          copyAttributes(imgElem, svgElem);
273        }
274        // Invoke beforeInject hook if set
275        var beforeInject = options.beforeInject;
276        var injectElem = (beforeInject && beforeInject(imgElem, svgElem)) || svgElem;
277        // Replace img element with new element. This is the actual injection.
278        parentNode.replaceChild(injectElem, imgElem);
279        // Mark img element as injected
280        imgElem[__SVGINJECT] = INJECTED;
281        removeOnLoadAttribute(imgElem);
282        // Invoke afterInject hook if set
283        var afterInject = options.afterInject;
284        if (afterInject) {
285          afterInject(imgElem, injectElem);
286        }
287      }
288    } else {
289      svgInvalid(imgElem, options);
290    }
291  }
292
293
294  // Merges any number of options objects into a new object
295  function mergeOptions() {
296    var mergedOptions = {};
297    var args = arguments;
298    // Iterate over all specified options objects and add all properties to the new options object
299    for (var i = 0; i < args[_LENGTH_]; i++) {
300      var argument = args[i];
301        for (var key in argument) {
302          if (argument.hasOwnProperty(key)) {
303            mergedOptions[key] = argument[key];
304          }
305        }
306      }
307    return mergedOptions;
308  }
309
310
311  // Adds the specified CSS to the document's <head> element
312  function addStyleToHead(css) {
313    var head = document[_GET_ELEMENTS_BY_TAG_NAME_]('head')[0];
314    if (head) {
315      var style = document[_CREATE_ELEMENT_](_STYLE_);
316      style.type = 'text/css';
317      style.appendChild(document.createTextNode(css));
318      head.appendChild(style);
319    }
320  }
321
322
323  // Builds an SVG element from the specified SVG string
324  function buildSvgElement(svgStr, verify) {
325    if (verify) {
326      var svgDoc;
327      try {
328        // Parse the SVG string with DOMParser
329        svgDoc = svgStringToSvgDoc(svgStr);
330      } catch(e) {
331        return NULL;
332      }
333      if (svgDoc[_GET_ELEMENTS_BY_TAG_NAME_]('parsererror')[_LENGTH_]) {
334        // DOMParser does not throw an exception, but instead puts parsererror tags in the document
335        return NULL;
336      }
337      return svgDoc.documentElement;
338    } else {
339      var div = document.createElement('div');
340      div.innerHTML = svgStr;
341      return div.firstElementChild;
342    }
343  }
344
345
346  function removeOnLoadAttribute(imgElem) {
347    // Remove the onload attribute. Should only be used to remove the unstyled image flash protection and
348    // make the element visible, not for removing the event listener.
349    imgElem.removeAttribute('onload');
350  }
351
352
353  function errorMessage(msg) {
354    console.error('SVGInject: ' + msg);
355  }
356
357
358  function fail(imgElem, status, options) {
359    imgElem[__SVGINJECT] = FAIL;
360    if (options.onFail) {
361      options.onFail(imgElem, status);
362    } else {
363      errorMessage(status);
364    }
365  }
366
367
368  function svgInvalid(imgElem, options) {
369    removeOnLoadAttribute(imgElem);
370    fail(imgElem, SVG_INVALID, options);
371  }
372
373
374  function svgNotSupported(imgElem, options) {
375    removeOnLoadAttribute(imgElem);
376    fail(imgElem, SVG_NOT_SUPPORTED, options);
377  }
378
379
380  function loadFail(imgElem, options) {
381    fail(imgElem, LOAD_FAIL, options);
382  }
383
384
385  function removeEventListeners(imgElem) {
386    imgElem.onload = NULL;
387    imgElem.onerror = NULL;
388  }
389
390
391  function imgNotSet(msg) {
392    errorMessage('no img element');
393  }
394
395
396  function createSVGInject(globalName, options) {
397    var defaultOptions = mergeOptions(DEFAULT_OPTIONS, options);
398    var svgLoadCache = {};
399
400    if (IS_SVG_SUPPORTED) {
401      // If the browser supports SVG, add a small stylesheet that hides the <img> elements until
402      // injection is finished. This avoids showing the unstyled SVGs before style is applied.
403      addStyleToHead('img[onload^="' + globalName + '("]{visibility:hidden;}');
404    }
405
406
407    /**
408     * SVGInject
409     *
410     * Injects the SVG specified in the `src` attribute of the specified `img` element or array of `img`
411     * elements. Returns a Promise object which resolves if all passed in `img` elements have either been
412     * injected or failed to inject (Only if a global Promise object is available like in all modern browsers
413     * or through a polyfill).
414     *
415     * Options:
416     * useCache: If set to `true` the SVG will be cached using the absolute URL. Default value is `true`.
417     * copyAttributes: If set to `true` the attributes will be copied from `img` to `svg`. Dfault value
418     *     is `true`.
419     * makeIdsUnique: If set to `true` the ID of elements in the `<defs>` element that can be references by
420     *     property values (for example 'clipPath') are made unique by appending "--inject-X", where X is a
421     *     running number which increases with each injection. This is done to avoid duplicate IDs in the DOM.
422     * beforeLoad: Hook before SVG is loaded. The `img` element is passed as a parameter. If the hook returns
423     *     a string it is used as the URL instead of the `img` element's `src` attribute.
424     * afterLoad: Hook after SVG is loaded. The loaded `svg` element and `svg` string are passed as a
425     *     parameters. If caching is active this hook will only get called once for injected SVGs with the
426     *     same absolute path. Changes to the `svg` element in this hook will be applied to all injected SVGs
427     *     with the same absolute path. It's also possible to return an `svg` string or `svg` element which
428     *     will then be used for the injection.
429     * beforeInject: Hook before SVG is injected. The `img` and `svg` elements are passed as parameters. If
430     *     any html element is returned it gets injected instead of applying the default SVG injection.
431     * afterInject: Hook after SVG is injected. The `img` and `svg` elements are passed as parameters.
432     * onAllFinish: Hook after all `img` elements passed to an SVGInject() call have either been injected or
433     *     failed to inject.
434     * onFail: Hook after injection fails. The `img` element and a `status` string are passed as an parameter.
435     *     The `status` can be either `'SVG_NOT_SUPPORTED'` (the browser does not support SVG),
436     *     `'SVG_INVALID'` (the SVG is not in a valid format) or `'LOAD_FAILED'` (loading of the SVG failed).
437     *
438     * @param {HTMLImageElement} img - an img element or an array of img elements
439     * @param {Object} [options] - optional parameter with [options](#options) for this injection.
440     */
441    function SVGInject(img, options) {
442      options = mergeOptions(defaultOptions, options);
443
444      var run = function(resolve) {
445        var allFinish = function() {
446          var onAllFinish = options.onAllFinish;
447          if (onAllFinish) {
448            onAllFinish();
449          }
450          resolve && resolve();
451        };
452
453        if (img && typeof img[_LENGTH_] != _UNDEFINED_) {
454          // an array like structure of img elements
455          var injectIndex = 0;
456          var injectCount = img[_LENGTH_];
457
458          if (injectCount == 0) {
459            allFinish();
460          } else {
461            var finish = function() {
462              if (++injectIndex == injectCount) {
463                allFinish();
464              }
465            };
466
467            for (var i = 0; i < injectCount; i++) {
468              SVGInjectElement(img[i], options, finish);
469            }
470          }
471        } else {
472          // only one img element
473          SVGInjectElement(img, options, allFinish);
474        }
475      };
476
477      // return a Promise object if globally available
478      return typeof Promise == _UNDEFINED_ ? run() : new Promise(run);
479    }
480
481
482    // Injects a single svg element. Options must be already merged with the default options.
483    function SVGInjectElement(imgElem, options, callback) {
484      if (imgElem) {
485        var svgInjectAttributeValue = imgElem[__SVGINJECT];
486        if (!svgInjectAttributeValue) {
487          removeEventListeners(imgElem);
488
489          if (!IS_SVG_SUPPORTED) {
490            svgNotSupported(imgElem, options);
491            callback();
492            return;
493          }
494          // Invoke beforeLoad hook if set. If the beforeLoad returns a value use it as the src for the load
495          // URL path. Else use the imgElem's src attribute value.
496          var beforeLoad = options.beforeLoad;
497          var src = (beforeLoad && beforeLoad(imgElem)) || imgElem[_GET_ATTRIBUTE_]('src');
498
499          if (!src) {
500            // If no image src attribute is set do no injection. This can only be reached by using javascript
501            // because if no src attribute is set the onload and onerror events do not get called
502            if (src === '') {
503              loadFail(imgElem, options);
504            }
505            callback();
506            return;
507          }
508
509          // set array so later calls can register callbacks
510          var onFinishCallbacks = [];
511          imgElem[__SVGINJECT] = onFinishCallbacks;
512
513          var onFinish = function() {
514            callback();
515            onFinishCallbacks.forEach(function(onFinishCallback) {
516              onFinishCallback();
517            });
518          };
519
520          var absUrl = getAbsoluteUrl(src);
521          var useCacheOption = options.useCache;
522          var makeIdsUniqueOption = options.makeIdsUnique;
523          
524          var setSvgLoadCacheValue = function(val) {
525            if (useCacheOption) {
526              svgLoadCache[absUrl].forEach(function(svgLoad) {
527                svgLoad(val);
528              });
529              svgLoadCache[absUrl] = val;
530            }
531          };
532
533          if (useCacheOption) {
534            var svgLoad = svgLoadCache[absUrl];
535
536            var handleLoadValue = function(loadValue) {
537              if (loadValue === LOAD_FAIL) {
538                loadFail(imgElem, options);
539              } else if (loadValue === SVG_INVALID) {
540                svgInvalid(imgElem, options);
541              } else {
542                var hasUniqueIds = loadValue[0];
543                var svgString = loadValue[1];
544                var uniqueIdsSvgString = loadValue[2];
545                var svgElem;
546
547                if (makeIdsUniqueOption) {
548                  if (hasUniqueIds === NULL) {
549                    // IDs for the SVG string have not been made unique before. This may happen if previous
550                    // injection of a cached SVG have been run with the option makedIdsUnique set to false
551                    svgElem = buildSvgElement(svgString, false);
552                    hasUniqueIds = makeIdsUnique(svgElem, false);
553
554                    loadValue[0] = hasUniqueIds;
555                    loadValue[2] = hasUniqueIds && svgElemToSvgString(svgElem);
556                  } else if (hasUniqueIds) {
557                    // Make IDs unique for already cached SVGs with better performance
558                    svgString = makeIdsUniqueCached(uniqueIdsSvgString);
559                  }
560                }
561
562                svgElem = svgElem || buildSvgElement(svgString, false);
563
564                inject(imgElem, svgElem, absUrl, options);
565              }
566              onFinish();
567            };
568
569            if (typeof svgLoad != _UNDEFINED_) {
570              // Value for url exists in cache
571              if (svgLoad.isCallbackQueue) {
572                // Same url has been cached, but value has not been loaded yet, so add to callbacks
573                svgLoad.push(handleLoadValue);
574              } else {
575                handleLoadValue(svgLoad);
576              }
577              return;
578            } else {
579              var svgLoad = [];
580              // set property isCallbackQueue to Array to differentiate from array with cached loaded values
581              svgLoad.isCallbackQueue = true;
582              svgLoadCache[absUrl] = svgLoad;
583            }
584          }
585
586          // Load the SVG because it is not cached or caching is disabled
587          loadSvg(absUrl, function(svgXml, svgString) {
588            // Use the XML from the XHR request if it is an instance of Document. Otherwise
589            // (for example of IE9), create the svg document from the svg string.
590            var svgElem = svgXml instanceof Document ? svgXml.documentElement : buildSvgElement(svgString, true);
591
592            var afterLoad = options.afterLoad;
593            if (afterLoad) {
594              // Invoke afterLoad hook which may modify the SVG element. After load may also return a new
595              // svg element or svg string
596              var svgElemOrSvgString = afterLoad(svgElem, svgString) || svgElem;
597              if (svgElemOrSvgString) {
598                // Update svgElem and svgString because of modifications to the SVG element or SVG string in
599                // the afterLoad hook, so the modified SVG is also used for all later cached injections
600                var isString = typeof svgElemOrSvgString == 'string';
601                svgString = isString ? svgElemOrSvgString : svgElemToSvgString(svgElem);
602                svgElem = isString ? buildSvgElement(svgElemOrSvgString, true) : svgElemOrSvgString;
603              }
604            }
605
606            if (svgElem instanceof SVGElement) {
607              var hasUniqueIds = NULL;
608              if (makeIdsUniqueOption) {
609                hasUniqueIds = makeIdsUnique(svgElem, false);
610              }
611
612              if (useCacheOption) {
613                var uniqueIdsSvgString = hasUniqueIds && svgElemToSvgString(svgElem);
614                // set an array with three entries to the load cache
615                setSvgLoadCacheValue([hasUniqueIds, svgString, uniqueIdsSvgString]);
616              }
617
618              inject(imgElem, svgElem, absUrl, options);
619            } else {
620              svgInvalid(imgElem, options);
621              setSvgLoadCacheValue(SVG_INVALID);
622            }
623            onFinish();
624          }, function() {
625            loadFail(imgElem, options);
626            setSvgLoadCacheValue(LOAD_FAIL);
627            onFinish();
628          });
629        } else {
630          if (Array.isArray(svgInjectAttributeValue)) {
631            // svgInjectAttributeValue is an array. Injection is not complete so register callback
632            svgInjectAttributeValue.push(callback);
633          } else {
634            callback();
635          }
636        }
637      } else {
638        imgNotSet();
639      }
640    }
641
642
643    /**
644     * Sets the default [options](#options) for SVGInject.
645     *
646     * @param {Object} [options] - default [options](#options) for an injection.
647     */
648    SVGInject.setOptions = function(options) {
649      defaultOptions = mergeOptions(defaultOptions, options);
650    };
651
652
653    // Create a new instance of SVGInject
654    SVGInject.create = createSVGInject;
655
656
657    /**
658     * Used in onerror Event of an `<img>` element to handle cases when the loading the original src fails
659     * (for example if file is not found or if the browser does not support SVG). This triggers a call to the
660     * options onFail hook if available. The optional second parameter will be set as the new src attribute
661     * for the img element.
662     *
663     * @param {HTMLImageElement} img - an img element
664     * @param {String} [fallbackSrc] - optional parameter fallback src
665     */
666    SVGInject.err = function(img, fallbackSrc) {
667      if (img) {
668        if (img[__SVGINJECT] != FAIL) {
669          removeEventListeners(img);
670
671          if (!IS_SVG_SUPPORTED) {
672            svgNotSupported(img, defaultOptions);
673          } else {
674            removeOnLoadAttribute(img);
675            loadFail(img, defaultOptions);
676          }
677          if (fallbackSrc) {
678            removeOnLoadAttribute(img);
679            img.src = fallbackSrc;
680          }
681        }
682      } else {
683        imgNotSet();
684      }
685    };
686
687    window[globalName] = SVGInject;
688
689    return SVGInject;
690  }
691
692  var SVGInjectInstance = createSVGInject('SVGInject');
693
694  if (typeof module == 'object' && typeof module.exports == 'object') {
695    module.exports = SVGInjectInstance;
696  }
697})(window, document);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.