JavaScript : Cross browser colour calculations

Just what the heck is “Cross browser colour calculations”?  Well, few weeks ago, I had to implement the function to convert any legal CSS colour value (rgb, named colours, etc) to the hex equivalent. And it has to work in all the browsers, of course.

I knew of implementations that use IE specific queryCommandValue(). For this and other MSIE internals, I suggest Geoff Chapels excellent site.
So, at least this is sorted, but what about other browsers? After a short googling session it was clear that getComputedStyle(), was made to do the job. Here is the final solution:

 

/*
MIT (c) 2018 by dbj.org
*/
(function() {
dbj.color = { toString: function() { return "DBJs*Color" } };

function v2h(value) {
value = parseInt(value).toString(16);
return value.length < 2 ? value + "0" : value;
}
dbj.color.rgb2hex = function(rgb) {
if (rgb.match(/^rgb/) == null) return rgb;
var arr = rgb.match(/\d+/g);
return "#" + v2h(arr[0]) + v2h(arr[1]) + v2h(arr[2]);
}
//
// none of the following is safe to script before DOM is ready
// we use the button, since it has createTextRange() method, 
// which we need in IE
// for various color computations
//
var btn_ = null;
function btn() {
if (btn_ == null) {
btn_ = document.createElement("button");
btn_.id = "dbjs_private_" + (new Date()).getTime();
if (dbj.browser.support.css_on_newborns === false)
document.getElementsByTagName("head")[0].appendChild(btn_);
//
// for browser who do not allow CSS on new and detached elements
// we attach to head, which should not provoke document re-flow
//
}
return btn_;
}
//
// Convert any *valid* colour value (rgb, named colours, etc)
// to the hex equivalent
//
dbj.color.toHex = window.getComputedStyle ? function(color) 
{
// For browsers who support it, we use getComputedStyle()
//
btn().style.color = color;
return retval = dbj.color.rgb2hex(
window.getComputedStyle(btn(), null).getPropertyValue("color")
);
}
: dbj.color.toHex = function(color) 
{
// for IE we use queryCommandValue()
// http://www.geoffchappell.com/viewer.htm?doc=studies/windows/ie/mshtml/methods/basemso/querycommandvalue.htm
//
btn().style.color = color;
var value = btn().createTextRange().queryCommandValue("ForeColor");
value = ((value & 0x0000ff) << 16) 
        | (value & 0x00ff00) 
        | ((value & 0xff0000) >>> 16);
value = value.toString(16);
return "#000000".slice(0, 7 - value.length) + value;
};

})();
/*
MIT (c) 2018 by dbj.org
*/

 

I use the “BUTTON” element since it has createTextRange() which I need for IE queryCommandValue(). All of his works quite nicely and quickly.

For browsers that need newborns to be attached to the document, to work, I attach to the “HEAD”, which, it seems, does not provoke a re-flow and thus does not slow down the dbj.color.toHex() function.
For dbj.browser.support.css_on_newborns, please see : https://dbj.org/does-your-browser-support-css-on-newborns/