@@ -191,14 +191,15 @@ _global.HTMLCS.util = function() {
191191 *
192192 * @returns {Object }
193193 */
194- self . style = function ( element ) {
194+ self . style = function ( element , pseudo ) {
195195 var computedStyle = null ;
196196 var window = self . getElementWindow ( element ) ;
197+ var pseudo = pseudo || null ;
197198
198199 if ( element . currentStyle ) {
199200 computedStyle = element . currentStyle ;
200201 } else if ( window . getComputedStyle ) {
201- computedStyle = window . getComputedStyle ( element , null ) ;
202+ computedStyle = window . getComputedStyle ( element , pseudo ) ;
202203 }
203204
204205 return computedStyle ;
@@ -240,7 +241,7 @@ _global.HTMLCS.util = function() {
240241 * Returns true if the element is deliberately hidden from Accessibility APIs using ARIA hidden.
241242 *
242243 * Not: This is separate to isAccessibilityHidden() due to a need to check specifically for aria hidden.
243- *
244+ *
244245 * @param {Node } element The element to check.
245246 *
246247 * @return {Boolean }
@@ -397,7 +398,7 @@ _global.HTMLCS.util = function() {
397398 * Returns all elements that are visible to the accessibility API.
398399 *
399400 * @param {Node } element The parent element to search.
400- * @param {String } selector Optional selector to pass to
401+ * @param {String } selector Optional selector to pass to
401402 *
402403 * @return {Array }
403404 */
@@ -532,6 +533,82 @@ _global.HTMLCS.util = function() {
532533 return lum ;
533534 }
534535
536+ /**
537+ * Convert an rgba colour to rgb, by traversing the dom and mixing colors as needed.
538+ *
539+ * @param element - the element to compare the rgba color against.
540+ * @param colour - the starting rgba color to check.
541+ * @returns {Colour Object }
542+ */
543+ self . rgbaBackgroundToRgb = function ( colour , element ) {
544+ var parent = element . parentNode ;
545+ var original = self . colourStrToRGB ( colour ) ;
546+ var backgrounds = [ ] ;
547+ var solidFound = false ;
548+
549+ if ( original . alpha == 1 ) {
550+ //Return early if it is already solid.
551+ return original ;
552+ }
553+
554+ //Find all the background with transparancy until we get to a solid colour
555+ while ( solidFound == false ) {
556+ if ( ( ! parent ) || ( ! parent . ownerDocument ) ) {
557+ //No parent was found, assume a solid white background.
558+ backgrounds . push ( {
559+ red : 1 ,
560+ green : 1 ,
561+ blue : 1 ,
562+ alpha : 1
563+ } ) ;
564+ break ;
565+ }
566+
567+ var parentStyle = self . style ( parent ) ;
568+ var parentColourStr = parentStyle . backgroundColor ;
569+ var parentColour = self . colourStrToRGB ( parentColourStr ) ;
570+
571+ if ( ( parentColourStr === 'transparent' ) || ( parentColourStr === 'rgba(0, 0, 0, 0)' ) ) {
572+ //Skip totally transparent parents until we find a solid color.
573+ parent = parent . parentNode ;
574+ continue ;
575+ }
576+
577+ backgrounds . push ( parentColour ) ;
578+
579+ if ( parentColour . alpha == 1 ) {
580+ solidFound = true ;
581+ }
582+
583+ parent = parent . parentNode ;
584+ }
585+
586+ //Now we need to start with the solid color that we found, and work our way up to the original color.
587+ var solidColour = backgrounds . pop ( ) ;
588+ while ( backgrounds . length ) {
589+ solidColour = self . mixColours ( solidColour , backgrounds . pop ( ) ) ;
590+ }
591+
592+ return self . mixColours ( solidColour , original ) ;
593+ } ;
594+
595+ self . mixColours = function ( bg , fg ) {
596+ //Convert colors to int values for mixing.
597+ bg . red = Math . round ( bg . red * 255 ) ;
598+ bg . green = Math . round ( bg . green * 255 ) ;
599+ bg . blue = Math . round ( bg . blue * 255 ) ;
600+ fg . red = Math . round ( fg . red * 255 ) ;
601+ fg . green = Math . round ( fg . green * 255 ) ;
602+ fg . blue = Math . round ( fg . blue * 255 ) ;
603+
604+ return {
605+ red : Math . round ( fg . alpha * fg . red + ( 1 - fg . alpha ) * bg . red ) / 255 ,
606+ green : Math . round ( fg . alpha * fg . green + ( 1 - fg . alpha ) * bg . green ) / 255 ,
607+ blue : Math . round ( fg . alpha * fg . blue + ( 1 - fg . alpha ) * bg . blue ) / 255 ,
608+ alpha : bg . alpha
609+ }
610+ }
611+
535612 /**
536613 * Convert a colour string to a structure with red/green/blue elements.
537614 *
@@ -552,7 +629,11 @@ _global.HTMLCS.util = function() {
552629 colour = {
553630 red : ( matches [ 1 ] / 255 ) ,
554631 green : ( matches [ 2 ] / 255 ) ,
555- blue : ( matches [ 3 ] / 255 )
632+ blue : ( matches [ 3 ] / 255 ) ,
633+ alpha : 1.0
634+ } ;
635+ if ( matches [ 4 ] ) {
636+ colour . alpha = parseFloat ( / ^ , \s * ( .* ) $ / . exec ( matches [ 4 ] ) [ 1 ] ) ;
556637 }
557638 } else {
558639 // Hex digit format.
@@ -566,8 +647,9 @@ _global.HTMLCS.util = function() {
566647
567648 colour = {
568649 red : ( parseInt ( colour . substr ( 0 , 2 ) , 16 ) / 255 ) ,
569- green : ( parseInt ( colour . substr ( 2 , 2 ) , 16 ) / 255 ) ,
570- blue : ( parseInt ( colour . substr ( 4 , 2 ) , 16 ) / 255 )
650+ gsreen : ( parseInt ( colour . substr ( 2 , 2 ) , 16 ) / 255 ) ,
651+ blue : ( parseInt ( colour . substr ( 4 , 2 ) , 16 ) / 255 ) ,
652+ alpha : 1
571653 } ;
572654 }
573655
@@ -1290,4 +1372,4 @@ _global.HTMLCS.util = function() {
12901372 } ;
12911373
12921374 return self ;
1293- } ( ) ;
1375+ } ( ) ;
0 commit comments