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.