PageSourceSearch

https://redlineperf.com/wp-content/plugins/svg-support/js/svgs-inline-vanilla.js?ver=2.6.1

js redlineperf.com collected 2026-10-04 23:23:29 UTC 6,430 bytes, 168 lines download raw bytes

1/* eslint-env browser */
2/* global svgSettings, ForceInlineSVGActive, cssTarget, frontSanitizationEnabled, DOMPurify */
3
4document.addEventListener("DOMContentLoaded", function(event) {
5
6    let bodhisvgsReplacements = 0;
7    let target;
8
9    // Function to replace the img tag with the SVG
10    function bodhisvgsReplace(img) {
11        // Ensure it's an image
12        if (img.nodeName !== 'IMG') {
13            return;
14        }
15
16        const hasTargetClass = img.classList.contains(target);
17        const parentHasTargetClass = img.parentElement.classList.contains(target);
18        const insideTargetContainer = img.closest('.' + target) !== null;
19        
20        // First check if we should process at all
21        if (ForceInlineSVGActive !== 'true' && !hasTargetClass && !insideTargetContainer) {
22            return;
23        }
24
25        // If skip nested is enabled, only skip if:
26        // 1. Image doesn't have target class AND
27        // 2. Image's parent is not the target container but is inside one
28        if (svgSettings.skipNested && !hasTargetClass && !parentHasTargetClass && insideTargetContainer) {
29            return;
30        }
31
32        var imgID = img.id;
33        var imgClass = img.className;
34        var imgURL = img.src;
35
36        // Ensure the URL ends with .svg before proceeding
37        if (!imgURL.endsWith('svg')) {
38            return;
39        }
40
41        var xmlHttp = new XMLHttpRequest();
42        xmlHttp.onreadystatechange = function() {
43            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
44                var data = xmlHttp.responseText;
45
46                // Parse the returned data to extract the SVG
47                let parser = new DOMParser();
48                const doc = parser.parseFromString(data, 'text/html');
49
50                // Get the SVG tag from the parsed data
51                var svg = doc.getElementsByTagName('svg')[0];
52
53                var svgID = svg.id;
54
55                // Add replaced image's ID to the new SVG if necessary
56                if (typeof imgID === 'undefined' || imgID === '') {
57                    if (typeof svgID === 'undefined' || svgID === '') {
58                        imgID = 'svg-replaced-' + bodhisvgsReplacements;
59                        svg.setAttribute('id', imgID);
60                    } else {
61                        imgID = svgID;
62                    }
63                } else {
64                    svg.setAttribute('id', imgID);
65                }
66
67                // Add replaced image's classes to the new SVG
68                if (typeof imgClass !== 'undefined' && imgClass !== '') {
69                    svg.setAttribute('class', imgClass + ' replaced-svg svg-replaced-' + bodhisvgsReplacements);
70                }
71
72                // Remove any invalid XML tags as per http://validator.w3.org
73                svg.removeAttribute('xmlns:a');
74
75                // If sanitization is enabled, sanitize the SVG code
76                if (frontSanitizationEnabled === 'on' && svg.outerHTML !== "") {
77                    var sanitizedSVG = DOMPurify.sanitize(svg.outerHTML);
78                    img.outerHTML = sanitizedSVG;
79                } else {
80                    img.replaceWith(svg);
81                }
82
83                bodhisvgsReplacements++;
84
85            } else if (xmlHttp.readyState === 4 && xmlHttp.status !== 200) {
86                // Silently fail
87            }
88        };
89
90        xmlHttp.open("GET", imgURL, true);
91        xmlHttp.send(null);
92    }
93
94    // Function to iterate over nodes and replace images
95    function bodhisvgsIterator(node) {
96        if (node.childNodes.length > 0) {
97            for (var i = 0; i < node.childNodes.length; i++) {
98                if (node.childNodes[i].nodeName === 'IMG') {
99                    var img = node.childNodes[i];
100                    bodhisvgsReplace(img);
101                } else {
102                    bodhisvgsIterator(node.childNodes[i]);
103                }
104            }
105        }
106    }
107
108    // Wrap in IIFE so that it can be called again later as bodhisvgsInlineSupport();
109    (bodhisvgsInlineSupport = function() {
110        // If force inline SVG option is active then add class
111        if (ForceInlineSVGActive === 'true') {
112            var allImages = document.getElementsByTagName('img');
113            for (var i = 0; i < allImages.length; i++) {
114                if (typeof allImages[i].src !== 'undefined') {
115                    if (allImages[i].src.match(/\.(svg)/)) {
116                        if (!allImages[i].classList.contains(cssTarget.ForceInlineSVG)) {
117                            allImages[i].classList.add(cssTarget.ForceInlineSVG);
118                        }
119                    }
120                }
121            }
122        }
123
124        // Polyfill to support all older browsers
125        if (!String.prototype.endsWith) {
126            String.prototype.endsWith = function(searchString, position) {
127                var subjectString = this.toString();
128                if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
129                    position = subjectString.length;
130                }
131                position -= searchString.length;
132                var lastIndex = subjectString.lastIndexOf(searchString, position);
133                return lastIndex !== -1 && lastIndex === position;
134            };
135        }
136
137        // Another snippet to support IE11
138        String.prototype.endsWith = function(pattern) {
139            var d = this.length - pattern.length;
140            return d >= 0 && this.lastIndexOf(pattern) === d;
141        };
142
143        // Set target before we use it
144        if (ForceInlineSVGActive === 'true') {
145            target = cssTarget.Bodhi !== 'img.' ? cssTarget.ForceInlineSVG : 'style-svg';
146        } else {
147            target = cssTarget.Bodhi !== 'img.' ? cssTarget.Bodhi : 'style-svg';
148        }
149
150        // Ensure target is a string before applying replace method
151        if (typeof target === 'string') {
152            target = target.replace("img.", "");
153        } else {
154            return;
155        }
156
157        // Replace images with SVGs based on the target class
158        document.querySelectorAll('.' + target).forEach(function(element) {
159            if (element.nodeName === 'IMG') {
160                bodhisvgsReplace(element);
161            } else {
162                bodhisvgsIterator(element);
163            }
164        });
165
166    })(); // Execute immediately
167});
168

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.