1(function ( $ ) { 2 'use strict'; 3 4 //Instantiate PUSH_AUTOCOLOR object if not already instantiated 5 if (typeof window.PUSH_AUTOCOLOR == 'undefined') { 6 window.PUSH_AUTOCOLOR = {}; 7 } 8 9 PUSH_AUTOCOLOR.init = function () { 10 if (typeof PUSH_AUTOCOLOR.elementSelectors !== 'undefined') { 11 for (let i in PUSH_AUTOCOLOR.elementSelectors) { 12 let elementSelector = PUSH_AUTOCOLOR.elementSelectors[i] 13 let elements = $(elementSelector) 14 15 if (elements.length) { 16 PUSH_AUTOCOLOR.setAutoColor(elements) 17 } else { 18 PUSH_AUTOCOLOR.onDomInsertListener(elementSelector, function () { 19 elements = $(elementSelector) 20 PUSH_AUTOCOLOR.setAutoColor(elements) 21 }) 22 } 23 } 24 } 25 } 26 27 PUSH_AUTOCOLOR.observers = [] 28 29 PUSH_AUTOCOLOR.onDomInsertListener = function (elementSelector, _callback) { 30 const cleanSelector = elementSelector.replace(/#|\./g, "") 31 32 const mutationCallback = function (mutationsList, observer) { 33 for (let mutation of mutationsList) { 34 if (mutation.type === 'childList') { 35 for (let addedNode of mutation.addedNodes) { 36 if (addedNode.id === cleanSelector || addedNode.className === cleanSelector) { 37 if (typeof PUSH_AUTOCOLOR.observers[elementSelector] !== 'undefined') { 38 PUSH_AUTOCOLOR.observers[elementSelector].disconnect() 39 } 40 _callback() 41 } 42 } 43 } 44 } 45 } 46 47 PUSH_AUTOCOLOR.observers[elementSelector] = new MutationObserver(mutationCallback) 48 49 const targetNode = document.querySelector('body') 50 51 PUSH_AUTOCOLOR.observers[elementSelector].observe(targetNode, { 52 attributes: true, 53 childList: true, 54 subtree: true, 55 }) 56 } 57 58 PUSH_AUTOCOLOR.changeObservers = [] 59 60 PUSH_AUTOCOLOR.onDomChangeListener = function (targetNode, _callback) { 61 const cleanSelector = targetNode.id.replace(/#|\./g, "") 62 63 const mutationCallback = function (mutationsList, observer) { 64 for (let mutation of mutationsList) { 65 if (typeof PUSH_AUTOCOLOR.changeObservers[cleanSelector] !== 'undefined') { 66 PUSH_AUTOCOLOR.changeObservers[cleanSelector].disconnect() 67 } 68 _callback() 69 } 70 } 71 72 PUSH_AUTOCOLOR.changeObservers[cleanSelector] = new MutationObserver(mutationCallback) 73 74 PUSH_AUTOCOLOR.changeObservers[cleanSelector].observe(targetNode, { 75 attributes: true, 76 childList: true, 77 subtree: true, 78 }) 79 } 80 81 PUSH_AUTOCOLOR.setAutoColor = function (element) { 82 if (typeof element !== "undefined" && element.length) { 83 //if there are multiple elements then run this function recursively 84 if (element.length > 1) { 85 jQuery(element).each(function () { 86 PUSH_AUTOCOLOR.setAutoColor(jQuery(this)); 87 }); 88 } else { 89 //work out the current element brightness 90 91 var foregroundBrightness = PUSH_AUTOCOLOR.getBrightnessLevel(element, 'color'); 92 var backgroundBrightness = PUSH_AUTOCOLOR.getBrightnessLevel(element, 'background-color'); 93 94 var isBackgroundBright = backgroundBrightness > 120; 95 var isForegroundBright = foregroundBrightness > 120; 96 97 //set link color to white or black to match background brightness 98 let setColor = null 99 if (isBackgroundBright && isForegroundBright) { 100 setColor = 'black' 101 } else if (!isBackgroundBright && !isForegroundBright) { 102 setColor = 'white' 103 } 104 105 if (setColor) { 106 PUSH_AUTOCOLOR.setCssProperty(element, 'color', setColor) 107 108 let htmlElement = element.get(0) 109 PUSH_AUTOCOLOR.onDomChangeListener(htmlElement, function () { 110 PUSH_AUTOCOLOR.setAutoColor(element) 111 }) 112 } 113 } 114 } 115 } 116 117 /** 118 * Get brightness level of a given element font or background color 119 * 120 * 0 = lowest level (i.e. black), 255 = highest level (i.e. white) 121 * 122 * @param element 123 * @param property (color or background-color) 124 * @returns {number} 125 */ 126 PUSH_AUTOCOLOR.getBrightnessLevel = function (element, property) { 127 128 //if element contains background image then return false
129 var elementBackgroundImg = jQuery(element).css('background-image'); 130 if (typeof elementBackgroundImg !== 'undefined' && elementBackgroundImg.length && elementBackgroundImg !== "none") { 131 return false; 132 } 133 134 var elementColor = jQuery(element).css(property); 135 if (typeof elementColor !== 'undefined') { 136 //get array of rgb/a values 137 var colors = PUSH_AUTOCOLOR.getRgbValues(elementColor); 138 139 if (colors) { 140 //check if opacity is defined - zero opacity means background is transparent 141 if (typeof colors.opacity !== 'undefined') { 142 var opacity = parseFloat(colors.opacity); 143 if (opacity === 0) { 144 /** 145 * Check if we are checking background color, if that is the case then get background 146 * brightness of parent instead. Do not try and get parent of <HTML> 147 */ 148 if (property === 'background-color' && jQuery(element).prop('tagName') !== "HTML") { 149 var parent = jQuery(element).parent(); 150 if (parent && parent.length) { 151 return PUSH_AUTOCOLOR.getBrightnessLevel(parent, property) 152 } 153 } 154 //opacity is zero so return highest brightness level 155 return 255; 156 } 157 } 158 159 //contrast calculation based on W3C https://www.w3.org/TR/AERT/#color-contrast 160 var brightness = Math.round(((parseInt(colors.red) * 299) + 161 (parseInt(colors.green) * 587) + 162 (parseInt(colors.blue) * 114)) / 1000); 163 164 return brightness; 165 } 166 } 167 168 return false; 169 } 170 171 PUSH_AUTOCOLOR.setCssProperty = function (element, propertyName, value) { 172 let searchPattern = new RegExp(propertyName + ":(.*?);", "ig") 173 let replaceWith = propertyName + ": " + value + " !important;"; 174 175 let currentStyle = $(element).attr("style") 176 if (currentStyle.search(searchPattern) !== -1) { 177 $(element).attr("style", currentStyle.replace(searchPattern, replaceWith)) 178 } else { 179 if (!currentStyle.endsWith(';')) { 180 currentStyle = currentStyle + ';'; 181 } 182 $(element).attr("style", currentStyle + ' ' + replaceWith) 183 } 184 } 185 186 PUSH_AUTOCOLOR.getRgbValues = function (color) { 187 188 var match = color.match(/rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d(?:\.?\d?))\))?/); 189 190 return match ? { 191 red: match[1], 192 green: match[2], 193 blue: match[3], 194 opacity: match[4] 195 } : false; 196 } 197 198 $(document).ready(function () { 199 PUSH_AUTOCOLOR.init(); 200 }); 201 202})(jQuery);
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.