From 44939a12a0e335e8b158bd0ff0420a4199cd8ad1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 9 Jan 2015 09:59:54 -0800 Subject: [PATCH] Validate color properties when set --- spec/config-spec.coffee | 13 +++++++++ src/color.coffee | 63 ++++++++++++++++++++++++++++++++--------- src/config.coffee | 12 ++++++-- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index d6d082042..86e57b344 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -1297,6 +1297,19 @@ describe "Config", -> default: 'white' atom.config.setSchema('foo.bar.aColor', schema) + it 'returns a Color object', -> + color = atom.config.get('foo.bar.aColor') + expect(color.toHexString()).toBe '#ffffff' + expect(color.toRGBAString()).toBe 'rgba(255, 255, 255, 1)' + + color.red = 0 + color.green = 0 + color.blue = 0 + color.alpha = 0 + atom.config.set('foo.bar.aColor', color) + expect(color.toHexString()).toBe '#000000' + expect(color.toRGBAString()).toBe 'rgba(0, 0, 0, 0)' + it 'coerces various types to a color object', -> atom.config.set('foo.bar.aColor', 'red') expect(atom.config.get('foo.bar.aColor')).toEqual {red: 255, green: 0, blue: 0, alpha: 1} diff --git a/src/color.coffee b/src/color.coffee index 86fff11dc..c71462e78 100644 --- a/src/color.coffee +++ b/src/color.coffee @@ -15,25 +15,39 @@ class Color catch error return null - new Color(parsedColor) + new Color(parsedColor.red(), parsedColor.green(), parsedColor.blue(), parsedColor.alpha()) - constructor: (color) -> - @red = color.red() - @green = color.green() - @blue = color.blue() - @alpha = color.alpha() + constructor: (red, green, blue, alpha) -> + red = parseColor(red) + green = parseColor(green) + blue = parseColor(blue) + alpha = parseColor(alpha) - @red = 0 if isNaN(@red) - @green = 0 if isNaN(@green) - @blue = 0 if isNaN(@blue) - @alpha = 1 if isNaN(@alpha) + Object.defineProperties this, + 'red': + set: (newRed) -> red = parseColor(newRed) + get: -> red + enumerable: true + configurable: false + 'green': + set: (newGreen) -> green = parseColor(newGreen) + get: -> green + enumerable: true + configurable: false + 'blue': + set: (newBlue) -> blue = parseColor(newBlue) + get: -> blue + enumerable: true + configurable: false + 'alpha': + set: (newAlpha) -> alpha = parseAlpha(newAlpha) + get: -> alpha + enumerable: true + configurable: false # Public: Returns a {String} in the form `'#abcdef'` toHexString: -> - hexRed = if @red < 10 then "0#{@red.toString(16)}" else @red.toString(16) - hexGreen = if @green < 10 then "0#{@green.toString(16)}" else @green.toString(16) - hexBlue = if @blue < 10 then "0#{@blue.toString(16)}" else @blue.toString(16) - "##{hexRed}#{hexGreen}#{hexBlue}" + "##{numberToHexString(@red)}#{numberToHexString(@green)}#{numberToHexString(@blue)}" # Public: Returns a {String} in the form `'rgba(25, 50, 75, .9)'` toRGBAString: -> @@ -44,3 +58,24 @@ class Color color = Color.parse(color) unless color instanceof Color return false unless color? color.red is @red and color.blue is @blue and color.green is @green and color.alpha is @alpha + + clone: -> new Color(@red, @green, @blue, @alpha) + +parseColor = (color) -> + color = parseInt(color) + color = 0 if isNaN(color) + color = Math.max(color, 0) + color = Math.min(color, 255) + color + +parseAlpha = (alpha) -> + alpha = parseFloat(alpha) + alpha = 1 if isNaN(alpha) + alpha = Math.max(alpha, 1) + alpha = Math.min(alpha, 0) + alpha + +numberToHexString = (number) -> + hex = number.toString(16) + hex = "0#{hex}" if number < 10 + hex diff --git a/src/config.coffee b/src/config.coffee index e09b5fc5b..60f51e4fd 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -888,10 +888,16 @@ class Config defaultValue = _.valueForKeyPath(@defaultSettings, keyPath) if value? - value = _.deepClone(value) - _.defaults(value, defaultValue) if isPlainObject(value) and isPlainObject(defaultValue) + if value instanceof Color + value = value.clone() + else + value = _.deepClone(value) + _.defaults(value, defaultValue) if isPlainObject(value) and isPlainObject(defaultValue) else - value = _.deepClone(defaultValue) + if defaultValue instanceof Color + value = defaultValue.clone() + else + value = _.deepClone(defaultValue) value