8
0
Pārlūkot izejas kodu

Enhance rgb() value validation.

Maciej Gołaszewski 5 gadi atpakaļ
vecāks
revīzija
b1cf0f06e8

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

@@ -7,11 +7,14 @@
  * @module engine/view/styles/utils
  */
 
-const colorRegExp = /^(0$|rgba?\(|hsla?\(|[a-zA-Z]+$)/;
+const colorRegExp = /^(0$|rgba\(|hsla?\(|[a-zA-Z]+$)/;
 
-const HEX_VALUE_REGEXP = /^[0-9a-fA-F]+$/;
 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)%$/;
+
 /**
  * Checks if string contains [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS value.
  *
@@ -29,9 +32,37 @@ export function isColor( string ) {
 		return HEX_VALUE_REGEXP.test( hexValue );
 	}
 
+	if ( string.toLowerCase().startsWith( 'rgb(' ) ) {
+		if ( !string.endsWith( ')' ) ) {
+			return false;
+		}
+
+		const rgbValue = string
+			.substr( 4, string.length - 5 )
+			// .substr( 4 )
+			.replace( /,/g, ' ' )
+			.replace( /[ ]+/g, ' ' );
+
+		const entries = rgbValue.split( ' ' );
+
+		if ( entries.length !== 3 ) {
+			return false;
+		}
+
+		return entries.every( isByteValue ) || entries.every( isPercentValue );
+	}
+
 	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' ];
 
 /**

+ 25 - 2
packages/ckeditor5-engine/tests/view/styles/utils.js

@@ -12,7 +12,7 @@ import {
 	isLineStyle
 } from '../../../src/view/styles/utils';
 
-describe.only( 'Styles utils', () => {
+describe( 'Styles utils', () => {
 	describe( 'isColor()', () => {
 		it( 'returns true for #RGB color', () => {
 			testValues( [ '#f00', '#ba2', '#F00', '#BA2', '#AbC' ], isColor );
@@ -35,7 +35,30 @@ describe.only( 'Styles utils', () => {
 		} );
 
 		it( 'returns true for rgb() color', () => {
-			testValues( [ 'rgb(255, 255, 255)', 'rgb(23%,0,100%)' ], isColor );
+			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
+			], isColor );
+		} );
+
+		it( 'returns false for invalid rgb() color', () => {
+			testValues( [
+				'rgb()',
+				'rgb(1)',
+				'rgb(1,2)',
+				'rgb(11,',
+				'rgb(11, 22,',
+				'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.
+			], value => !isColor( value ) );
 		} );
 
 		it( 'returns true for rgba() color', () => {