diff --git a/changelog.html b/changelog.html index 2196ca83..2c70c01b 100644 --- a/changelog.html +++ b/changelog.html @@ -1,3 +1,15 @@ +
Deprecated
and not Depreciated
.Default: 4.5", - old_val, - function(new_val) { - if ( new_val === null || new_val === undefined ) - return; + utils.prompt( + "Luv Adjustment Minimum Contrast Ratio", + "Please enter a new value for the minimum contrast ratio required between username colors and the background.
Default: 4.5", + old_val, + function(new_val) { + if ( new_val === null || new_val === undefined ) + return; - var parsed = parseFloat(new_val); - if ( Number.isNaN(parsed) || ! Number.isFinite(parsed) ) - parsed = 4.5; + var parsed = parseFloat(new_val); + if ( Number.isNaN(parsed) || ! Number.isFinite(parsed) ) + parsed = 4.5; - f.settings.set("luv_contrast", parsed); - }); - }, + f.settings.set("luv_contrast", parsed); + }); + }, on_update: function(val) { - this._rebuild_contrast(); - this._rebuild_filter_styles(); + this._rebuild_contrast(); + this._rebuild_filter_styles(); - if ( ! this.has_bttv && this.settings.fix_color === 1 ) - this._rebuild_colors(); - } - }; + if ( ! this.has_bttv && this.settings.fix_color === 1 ) + this._rebuild_colors(); + } +}; FFZ.settings_info.color_blind = { @@ -115,10 +138,10 @@ FFZ.settings_info.color_blind = { help: "Adjust username colors in an attempt to make them more distinct for people with color blindness.", on_update: function(val) { - if ( ! this.has_bttv && this.settings.fix_color !== -1 ) + if ( ! this.has_bttv && this.settings.fix_color !== -1 ) this._rebuild_colors(); - } - }; + } +}; // -------------------- @@ -313,9 +336,9 @@ RGBAColor.fromXYZA = function(x, y, z, a) { // Make sure we end up in a real color space return new RGBAColor( - Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(R))), - Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(G))), - Math.max(0, Math.min(255, 255 * XYZAColor.channelConverter(B))), + Math.max(0, Math.min(255, 255 * linear2bit(R))), + Math.max(0, Math.min(255, 255 * linear2bit(G))), + Math.max(0, Math.min(255, 255 * linear2bit(B))), a === undefined ? 1 : a ); } @@ -349,16 +372,17 @@ RGBAColor.prototype.toHex = function() { } +RGBAColor.prototype.get_Y = function() { + return ((0.299 * this.r) + ( 0.587 * this.g) + ( 0.114 * this.b)) / 255; +} + + RGBAColor.prototype.luminance = function() { - var rgb = [this.r / 255, this.g / 255, this.b / 255]; - for (var i =0, l = rgb.length; i < l; i++) { - if (rgb[i] <= 0.03928) { - rgb[i] = rgb[i] / 12.92; - } else { - rgb[i] = Math.pow( ((rgb[i]+0.055)/1.055), 2.4 ); - } - } - return (0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2]); + var r = bit2linear(this.r / 255), + g = bit2linear(this.g / 255), + b = bit2linear(this.b / 255); + + return (0.2126 * r) + (0.7152 * g) + (0.0722 * b); } @@ -464,7 +488,7 @@ HSLAColor.fromRGBA = function(r, g, b, a) { HSLAColor.prototype.targetLuminance = function (target) { var s = this.s; s *= Math.pow(this.l > 0.5 ? -this.l : this.l - 1, 7) + 1; - + var min = 0, max = 1, d = (max - min) / 2, mid = min + d; for (; d > 1/65536; d /= 2, mid = min + d) { var luminance = RGBAColor.fromHSLA(this.h, s, mid, 1).luminance() @@ -474,7 +498,7 @@ HSLAColor.prototype.targetLuminance = function (target) { min = mid; } } - + return new HSLAColor(this.h, s, mid, this.a); } @@ -540,30 +564,12 @@ HSVAColor.prototype._a = function(a) { return new HSVAColor(this.h, this.s, this // XYZ Colors -RGBAColor.channelConverter = function (channel) { - // http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html - // This converts rgb 8bit to rgb linear, lazy because the other algorithm is really really dumb - return Math.pow(channel, 2.2); - - // CSS Colors Level 4 says 0.03928, Bruce Lindbloom who cared to write all algos says 0.04045, used bruce because whynawt - return (channel <= 0.04045) ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4); -}; - -XYZAColor.channelConverter = function (channel) { - // Using lazy conversion in the other direction as well - return Math.pow(channel, 1/2.2); - - // I'm honestly not sure about 0.0031308, I've only seen it referenced on Bruce Lindbloom's site - return (channel <= 0.0031308) ? channel * 12.92 : Math.pow(1.055 * channel, 1/2.4) - 0.055; -}; - - XYZAColor.prototype.eq = function(xyz) { return xyz.x === this.x && xyz.y === this.y && xyz.z === this.z; } XYZAColor.fromRGBA = function(r, g, b, a) { - var R = RGBAColor.channelConverter(r / 255), - G = RGBAColor.channelConverter(g / 255), - B = RGBAColor.channelConverter(b / 255); + var R = bit2linear(r / 255), + G = bit2linear(g / 255), + B = bit2linear(b / 255); return new XYZAColor( 0.412453 * R + 0.357580 * G + 0.180423 * B, @@ -661,7 +667,7 @@ FFZ.prototype._rebuild_contrast = function() { this._luv_background_bright = new XYZAColor(0, (this.settings.luv_contrast * (RGBAColor.fromCSS("#3c3a41").toXYZA().y + 0.05) - 0.05), 0, 1).toLUVA().l; this._luv_background_dark = new XYZAColor(0, ((RGBAColor.fromCSS("#acacbf").toXYZA().y + 0.05) / this.settings.luv_contrast - 0.05), 0, 1).toLUVA().l; - + this._hslluma_required_bright = this.settings.luv_contrast * (RGBAColor.fromCSS("#17141f").luminance() + 0.05) - 0.05; this._hslluma_required_dark = (RGBAColor.fromCSS("#efeef1").luminance() + 0.05) / this.settings.luv_contrast - 0.05; } @@ -746,7 +752,44 @@ FFZ.prototype._handle_color = function(color) { } - // Color Processing - RGB + // Color Processing - LUV + if ( this.settings.fix_color === 1 ) { + var luv = rgb.toLUVA(); + + if ( luv.l > this._luv_required_dark ) + light_color = luv._l(this._luv_required_dark).toRGBA(); + + if ( luv.l < this._luv_required_bright ) + dark_color = luv._l(this._luv_required_bright).toRGBA(); + } + + + // Color Processing - HSL (Deprecated) + if ( this.settings.fix_color === 2 ) { + var hsl = rgb.toHSLA(); + + light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toRGBA(); + dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toRGBA(); + } + + + // Color Processing - HSV (Deprecated) + if ( this.settings.fix_color === 3 ) { + var hsv = rgb.toHSVA(); + + if ( hsv.s === 0 ) { + // Black and White + light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGBA(); + dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGBA(); + + } else { + light_color = RGBAColor.fromHSVA(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v), hsv.a); + dark_color = RGBAColor.fromHSVA(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1), hsv.a); + } + } + + + // Color Processing - RGB (Deprecated) if ( this.settings.fix_color === 4 ) { var lum = rgb.luminance(); @@ -775,56 +818,31 @@ FFZ.prototype._handle_color = function(color) { // Color Processing - HSL BTTV-Like - /*if ( this.settings.fix_color === 5 ) { - var hsl = rgb.toHSLA(); + if ( this.settings.fix_color === 5 ) { + // BetterTTV adjusts its colors by converting them to the YIQ color space and then + // checking the value of Y. If it isn't past the half-way threshold, it then either + // brightens or darkens the luminosity, in HSL color space and checks again. Repeat + // until the color is acceptible. - light_color = hsl._l(Math.min(Math.max(0, .9 * (1 - hsl.l)), 1)).toRGBA(); - dark_color = hsl._l(Math.min(Math.max(0, 1 - .9 * (1 - hsl.l)), 1)).toRGBA(); - }*/ + while ( light_color.get_Y() >= 0.5 ) { + var hsl = light_color.toHSLA(); + light_color = hsl._l(Math.min(Math.max(0, 0.9 * hsl.l), 1)).toRGBA(); + } - - // Color Processing - HSL - if ( this.settings.fix_color === 2 ) { - var hsl = rgb.toHSLA(); - - light_color = hsl._l(Math.min(Math.max(0, 0.7 * hsl.l), 1)).toRGBA(); - dark_color = hsl._l(Math.min(Math.max(0, 0.3 + (0.7 * hsl.l)), 1)).toRGBA(); - } - - - // Color Processing - HSV - if ( this.settings.fix_color === 3 ) { - var hsv = rgb.toHSVA(); - - if ( hsv.s === 0 ) { - // Black and White - light_color = hsv._v(Math.min(Math.max(0.5, 0.5 * hsv.v), 1)).toRGBA(); - dark_color = hsv._v(Math.min(Math.max(0.5, 0.5 + (0.5 * hsv.v)), 1)).toRGBA(); - - } else { - light_color = RGBAColor.fromHSVA(hsv.h, Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.s)), 1), Math.min(0.7, hsv.v), hsv.a); - dark_color = RGBAColor.fromHSVA(hsv.h, Math.min(0.7, hsv.s), Math.min(Math.max(0.7, 0.7 + (0.3 * hsv.v)), 1), hsv.a); + while ( dark_color.get_Y() < 0.5 ) { + var hsl = dark_color.toHSLA(); + dark_color = hsl._l(Math.min(Math.max(0, 0.1 + 0.9 * hsl.l), 1)).toRGBA(); } } - // Color Processing - LUV - if ( this.settings.fix_color === 1 ) { - var luv = rgb.toLUVA(); - if ( luv.l > this._luv_required_dark ) - light_color = luv._l(this._luv_required_dark).toRGBA(); - - if ( luv.l < this._luv_required_bright ) - dark_color = luv._l(this._luv_required_bright).toRGBA(); - } - // Color Processing - HSL Luma if ( this.settings.fix_color === 6 ) { var lum = rgb.luminance(); - + if ( lum > this._hslluma_required_dark ) light_color = rgb.toHSLA().targetLuminance(this._hslluma_required_dark).toRGBA(); - + if ( lum < this._hslluma_required_bright ) dark_color = rgb.toHSLA().targetLuminance(this._hslluma_required_bright).toRGBA(); } diff --git a/src/main.js b/src/main.js index 706ba4b1..338f9ce1 100644 --- a/src/main.js +++ b/src/main.js @@ -34,7 +34,7 @@ FFZ.msg_commands = {}; // Version var VER = FFZ.version_info = { - major: 3, minor: 5, revision: 266, + major: 3, minor: 5, revision: 268, toString: function() { return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || ""); } diff --git a/src/settings.js b/src/settings.js index e63b8fc9..f34440fe 100644 --- a/src/settings.js +++ b/src/settings.js @@ -354,12 +354,14 @@ var is_android = navigator.userAgent.indexOf('Android') !== -1, var t = this; if ( ! t.classList.contains('collapsable') ) return; + else if ( ! t.classList.contains('collapsed') ) { if ( e.target.classList.contains('heading') ) { t.classList.add('collapsed'); if ( collapsed_key ) f[collapsed_key] = true; - } + } else + return; } else { jQuery(".chat-menu-content:not(.collapsed)", container).addClass("collapsed"); @@ -442,15 +444,31 @@ var is_android = navigator.userAgent.indexOf('Android') !== -1, label.className = 'option-label'; label.innerHTML = info.name; + var op_list = []; + for(var ok in info.options) { - var op = createElement('option'); + var op = createElement('option'), + desc = info.options[ok], + sort_key = 0; + op.value = JSON.stringify(ok); if ( val == ok ) op.setAttribute('selected', true); - op.innerHTML = info.options[ok]; - select.appendChild(op); + + if ( typeof desc === "object" ) { + op.innerHTML = desc[0]; + sort_key = desc[1]; + } else + op.innerHTML = desc; + + op_list.push([sort_key, op]); } + op_list.sort(function(a,b) {return a[0] - b[0]}); + + for(var op_i=0; op_i < op_list.length; op_i++) + select.appendChild(op_list[op_i][1]); + select.addEventListener('change', option_setting.bind(this, select, key, info)); if ( show_pin )