浏览代码

Use RegExp for testing colors as it is faster than string manipulation.

Maciej Gołaszewski 5 年之前
父节点
当前提交
4e7c5295cd
共有 2 个文件被更改,包括 50 次插入40 次删除
  1. 26 33
      packages/ckeditor5-engine/src/view/styles/utils.js
  2. 24 7
      packages/ckeditor5-engine/tests/view/styles/utils.js

+ 26 - 33
packages/ckeditor5-engine/src/view/styles/utils.js

@@ -7,13 +7,13 @@
  * @module engine/view/styles/utils
  */
 
-const colorRegExp = /^(0$|rgba\(|hsla?\(|[a-zA-Z]+$)/;
+const colorRegExp = /^(0$|[a-zA-Z]+$)/;
 
-const validHexLengths = [ 3, 4, 6, 8 ];
-
-const HEX_VALUE_REGEXP = /^[0-9a-fA-F]+$/;
-const BYTE_VALUE_REGEXP = /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/;
-const PERCENTAGE_VALUE_REGEXP = /^(0?[0-9]?[0-9]|100)%$/;
+const HEX_VALUE_REGEXP = /^#[0-9a-f]+$/;
+const RGB_REG_EXP = /^rgb\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}[0-9]{1,3}[ %]?\)$/;
+const RGBA_REG_EXP = /^rgba\([ ]?([0-9]{1,3}[ %]?,[ ]?){3}(1|[0-9]+%|[0]?\.[0-9]+)\)$/;
+const HSL_REG_EXP = /^hsl\([ ]?([0-9]{1,3}[ %]?[,]?[ ]*){3}(1|[0-9]+%|[0]?\.[0-9]+)?\)$/;
+const HSLA_REG_EXP = /^hsla\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}(1|[0-9]+%|[0]?\.[0-9]+)\)$/;
 
 /**
  * Checks if string contains [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS value.
@@ -22,47 +22,40 @@ const PERCENTAGE_VALUE_REGEXP = /^(0?[0-9]?[0-9]|100)%$/;
  * @returns {Boolean}
  */
 export function isColor( string ) {
-	if ( string.startsWith( '#' ) ) {
-		const hexValue = string.substr( 1 );
+	const toCheck = string.toLowerCase();
+
+	// Avoid:
+	// - substr
+	// - string replace
+	if ( toCheck.startsWith( '#' ) ) {
+		const length = toCheck.length;
 
-		if ( !validHexLengths.includes( hexValue.length ) ) {
+		if ( !( length === 4 || length === 5 || length === 7 || length === 9 ) ) {
 			return false;
 		}
 
-		return HEX_VALUE_REGEXP.test( hexValue );
+		return HEX_VALUE_REGEXP.test( toCheck );
 	}
 
-	if ( string.toLowerCase().startsWith( 'rgb(' ) ) {
-		if ( !string.endsWith( ')' ) ) {
-			return false;
-		}
-
-		const rgbValue = string
-			.substr( 4, string.length - 5 )
-			// .substr( 4 )
-			.replace( /,/g, ' ' )
-			.replace( /[ ]+/g, ' ' );
+	if ( toCheck.startsWith( 'rgb(' ) ) {
+		return RGB_REG_EXP.test( toCheck );
+	}
 
-		const entries = rgbValue.split( ' ' );
+	if ( toCheck.startsWith( 'rgba(' ) ) {
+		return RGBA_REG_EXP.test( toCheck );
+	}
 
-		if ( entries.length !== 3 ) {
-			return false;
-		}
+	if ( toCheck.startsWith( 'hsl(' ) ) {
+		return HSL_REG_EXP.test( toCheck );
+	}
 
-		return entries.every( isByteValue ) || entries.every( isPercentValue );
+	if ( toCheck.startsWith( 'hsla(' ) ) {
+		return HSLA_REG_EXP.test( toCheck );
 	}
 
 	return colorRegExp.test( string );
 }
 
-function isByteValue( entry ) {
-	return BYTE_VALUE_REGEXP.test( entry );
-}
-
-function isPercentValue( entry ) {
-	return PERCENTAGE_VALUE_REGEXP.test( entry );
-}
-
 const lineStyleValues = [ 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset' ];
 
 /**

+ 24 - 7
packages/ckeditor5-engine/tests/view/styles/utils.js

@@ -4,9 +4,9 @@
  */
 
 import {
-	getShorthandValues,
 	getBoxSidesShorthandValue,
 	getBoxSidesValues,
+	getShorthandValues,
 	isColor,
 	isLength,
 	isLineStyle
@@ -38,10 +38,12 @@ describe( 'Styles utils', () => {
 			testValues( [
 				'rgb(255,0,153)',
 				'rgb(255, 0, 153)',
-				// 'rgb(255, 0, 153.0)', // TODO: does not validate but might be skipped
 				'rgb(100%,0%,60%)',
-				'rgb(100%, 0%, 60%)',
-				'rgb(255 0 153)' // TODO: might be skipped - adds complexity
+				'rgb(100%, 0%, 60%)'
+				// Unsupported:
+				// 'rgb(11, 22, 33, 0.1)', // rgba() is equal to rgb()
+				// 'rgb(255, 0, 153.0)', // Floats are valid
+				// 'rgb(255 0 153)', // CSS Level 4 notation
 			], isColor );
 		} );
 
@@ -55,9 +57,11 @@ describe( 'Styles utils', () => {
 				'rgb(11, 22, 33',
 				'rgb((11, 22, 33',
 				'rgb((11, 22, 33)',
-				'rgb((11, 22, 33, 44)', // TODO: valid in Level 4 CSS
 				'rgb(11, 22, 33))',
-				'rgb(100%, 0, 60%)' // Don't mix numbers and percentages. TODO: might be skipped - adds complexity.
+				'rgb(11, 22, 33, 0.1)',
+				'rgb(11, 22, 33, .153)'
+				// Unsupported:
+				// 'rgb(100%, 0, 60%)', // Mixed numbers and percentages. TODO: might be skipped - adds complexity.,
 			], value => !isColor( value ) );
 		} );
 
@@ -66,7 +70,20 @@ describe( 'Styles utils', () => {
 		} );
 
 		it( 'returns true for hsl() color', () => {
-			testValues( [ 'hsl(0, 100%, 50%)', 'hsl(340,80%,40%)' ], isColor );
+			testValues( [
+				'hsl(270,60%,70%)',
+				'hsl(270, 60%, 70%)',
+				'hsl(270, 60%, 50%, .15)',
+				'hsl(270, 60%, 50%, 0.15)',
+				'hsl(270, 60%, 50%, 15%)'
+				// Unsupported:
+				// 'hsl(270deg, 60%, 70%)', // Valid deg unit
+				// 'hsl(4.71239rad, 60%, 70%)', // Valid rad unit
+				// 'hsl(.75turn, 60%, 70%)', // Valid turn unit
+				// 'hsl(270 60% 70%)', // CSS Level 4 notation
+				// 'hsl(270 60% 50% / .15)', // CSS Level 4 notation
+				// 'hsl(270 60% 50% / 15%)' // CSS Level 4 notation
+			], isColor );
 		} );
 
 		it( 'returns true for hsla() color', () => {