fix(color): support web standard #rrggbbaa format

original pr credit to @farfromrefug
https://github.com/NativeScript/NativeScript/pull/8519

BREAKING CHANGE

Long standing inconsistency with color handling here.

BEFORE:

```
// #aarrggbb

const color = new Color('#ff00ff00');

Label {
    background-color: #ff00ff00;
}
```

AFTER:

```
// #rrggbbaa

const color = new Color('#00ff00ff');

Label {
    background-color: #00ff00ff;
}
```
This commit is contained in:
Nathan Walker
2021-03-06 20:27:29 -08:00
parent e9b5eb934d
commit aaeab990c8
10 changed files with 36 additions and 28 deletions

View File

@@ -39,7 +39,7 @@ describe('css', () => {
describe('color', () => {
test(parseColor, ' #369 ', { start: 0, end: 7, value: 0xff336699 });
test(parseColor, ' #456789 ', { start: 0, end: 10, value: 0xff456789 });
test(parseColor, ' #85456789 ', { start: 0, end: 12, value: 0x85456789 });
test(parseColor, ' #45678985 ', { start: 0, end: 12, value: 0x45678985 });
test(parseColor, ' rgb(255, 8, 128) ', { start: 0, end: 18, value: 0xffff0880 });
test(parseColor, ' rgba(255, 8, 128, 0.5) ', { start: 0, end: 24, value: 0x80ff0880 });
test(parseColor, ' hsl(330.9, 100%, 51.6%) ', { start: 0, end: 25, value: 0xffff0880 });

View File

@@ -26,8 +26,10 @@ export class Color implements definition.Color {
const argb = knownColors.getKnownColor(arg);
this._name = arg;
this._argb = argb;
} else if (HEX_REGEX.test(arg)) {
// The parameter is a "#AARRGGBB" formatted string
} else if (arg[0].charAt(0) === SHARP && (arg.length === 4 || arg.length === 7 || arg.length === 9)) {
// we dont use the regexp as it is quite slow. Instead we expect it to be a valid hex format
// strange that it would not be. And if it is not a thrown error seems best
// The parameter is a "#RRGGBBAA" formatted string
const hex = this._normalizeHex(arg);
this._argb = this._argbFromString(hex);
} else {
@@ -73,7 +75,7 @@ export class Color implements definition.Color {
if (this.a === 0xff) {
return ('#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b)).toUpperCase();
} else {
return ('#' + this._componentToHex(this.a) + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b)).toUpperCase();
return ('#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b) + this._componentToHex(this.a)).toUpperCase();
}
}
@@ -104,6 +106,11 @@ export class Color implements definition.Color {
if (hex.length === 6) {
// add the alpha component since the provided string is RRGGBB
intVal = (intVal & 0x00ffffff) + 0xff000000;
} else {
// the new format is #RRGGBBAA
// we need to shift the alpha value to 0x01000000 position
const a = (intVal / 0x00000001) & 0xff;
intVal = (intVal >>> 8) + (a & 0xff) * 0x01000000;
}
return intVal;
@@ -157,7 +164,8 @@ export class Color implements definition.Color {
}
private _normalizeHex(hexStr: string): string {
if (hexStr.charAt(0) === SHARP && hexStr.length === 4) {
// we expect this to already has a # as first char as it is supposed to be tested before
if (hexStr.length === 4) {
// Duplicate each char after the #, so "#123" becomes "#112233"
hexStr = hexStr.charAt(0) + hexStr.charAt(1) + hexStr.charAt(1) + hexStr.charAt(2) + hexStr.charAt(2) + hexStr.charAt(3) + hexStr.charAt(3);
}