Browse Source

Add border-top,right,bottom,left as a default border output.

Maciej Gołaszewski 6 years ago
parent
commit
daf28a2b3a

+ 61 - 4
packages/ckeditor5-engine/src/view/styles.js

@@ -85,8 +85,14 @@ export default class Styles {
 		this.normalizers.set( 'margin', getPositionShorthandNormalizer( 'margin' ) );
 		this.normalizers.set( 'padding', getPositionShorthandNormalizer( 'padding' ) );
 
+		this.extractors = new Map();
+		this.extractors.set( 'border-top', borderPositionExtractor( 'top' ) );
+		this.extractors.set( 'border-right', borderPositionExtractor( 'right' ) );
+		this.extractors.set( 'border-bottom', borderPositionExtractor( 'bottom' ) );
+		this.extractors.set( 'border-left', borderPositionExtractor( 'left' ) );
+
 		/**
-		 * Holds style normalize object reducrs.
+		 * Holds style normalize object reducers.
 		 *
 		 * An style inliner takes normalized object of style property and outputs array of normalized property-value pairs that can
 		 * be later used to inline a style.
@@ -123,6 +129,10 @@ export default class Styles {
 		this.reducers.set( 'border-color', getTopRightBottomLeftValueReducer( 'border-color' ) );
 		this.reducers.set( 'border-style', getTopRightBottomLeftValueReducer( 'border-style' ) );
 		this.reducers.set( 'border-width', getTopRightBottomLeftValueReducer( 'border-width' ) );
+		this.reducers.set( 'border-top', getBorderPositionReducer( 'top' ) );
+		this.reducers.set( 'border-right', getBorderPositionReducer( 'right' ) );
+		this.reducers.set( 'border-bottom', getBorderPositionReducer( 'bottom' ) );
+		this.reducers.set( 'border-left', getBorderPositionReducer( 'left' ) );
 		this.reducers.set( 'border', getBorderReducer );
 
 		this.reducers.set( 'margin', getTopRightBottomLeftValueReducer( 'margin' ) );
@@ -240,6 +250,10 @@ export default class Styles {
 			return merge( {}, this._styles );
 		}
 
+		if ( this.extractors.has( name ) ) {
+			return this.extractors.get( name )( this );
+		}
+
 		const path = toPath( name );
 
 		if ( has( this._styles, path ) ) {
@@ -445,6 +459,28 @@ function getBorderPropertyNormalizer( propertyName ) {
 	return value => ( { border: toBorderPropertyShorthand( value, propertyName ) } );
 }
 
+function borderPositionExtractor( which ) {
+	return styles => {
+		const border = styles.getNormalized( 'border' );
+
+		const value = [];
+
+		if ( border.width && border.width[ which ] ) {
+			value.push( border.width[ which ] );
+		}
+
+		if ( border.style && border.style[ which ] ) {
+			value.push( border.style[ which ] );
+		}
+
+		if ( border.color && border.color[ which ] ) {
+			value.push( border.color[ which ] );
+		}
+
+		return value.join( ' ' );
+	};
+}
+
 function normalizeBorderShorthand( string ) {
 	const result = {};
 
@@ -520,9 +556,10 @@ function isURL( string ) {
 function getBorderReducer( value ) {
 	const ret = [];
 
-	ret.push( ...getTopRightBottomLeftValueReducer( 'border-color' )( value.color ) );
-	ret.push( ...getTopRightBottomLeftValueReducer( 'border-style' )( value.style ) );
-	ret.push( ...getTopRightBottomLeftValueReducer( 'border-width' )( value.width ) );
+	ret.push( ...getBorderPositionReducer( 'top' )( value ) );
+	ret.push( ...getBorderPositionReducer( 'right' )( value ) );
+	ret.push( ...getBorderPositionReducer( 'bottom' )( value ) );
+	ret.push( ...getBorderPositionReducer( 'left' )( value ) );
 
 	return ret;
 }
@@ -557,6 +594,26 @@ function getTopRightBottomLeftValueReducer( styleShorthand ) {
 	};
 }
 
+function getBorderPositionReducer( which ) {
+	return value => {
+		const reduced = [];
+
+		if ( value && value.width && value.width[ which ] !== undefined ) {
+			reduced.push( value.width[ which ] );
+		}
+
+		if ( value && value.style && value.style[ which ] !== undefined ) {
+			reduced.push( value.style[ which ] );
+		}
+
+		if ( value && value.color && value.color[ which ] !== undefined ) {
+			reduced.push( value.color[ which ] );
+		}
+
+		return [ [ 'border-' + which, reduced.join( ' ' ) ] ];
+	};
+}
+
 function getTopRightBottomLeftShorthandValue( { left, right, top, bottom } ) {
 	const out = [];
 

+ 67 - 6
packages/ckeditor5-engine/tests/view/styles.js

@@ -260,7 +260,9 @@ describe( 'Styles', () => {
 			it( 'should output inline shorthand rules #1', () => {
 				styles.setStyle( 'border:1px solid blue;' );
 
-				expect( styles.getInlineStyle() ).to.equal( 'border-color:blue;border-style:solid;border-width:1px;' );
+				expect( styles.getInlineStyle() ).to.equal(
+					'border-top:1px solid blue;border-right:1px solid blue;border-bottom:1px solid blue;border-left:1px solid blue;'
+				);
 				expect( styles.getInlineProperty( 'border-color' ) ).to.equal( 'blue' );
 				expect( styles.getInlineProperty( 'border-style' ) ).to.equal( 'solid' );
 				expect( styles.getInlineProperty( 'border-width' ) ).to.equal( '1px' );
@@ -270,7 +272,7 @@ describe( 'Styles', () => {
 				styles.setStyle( 'border:1px solid blue;border-left:#665511 dashed 2.7em;border-top:7px dotted #ccc;' );
 
 				expect( styles.getInlineStyle() ).to.equal(
-					'border-color:#ccc blue blue #665511;border-style:dotted solid solid dashed;border-width:7px 1px 1px 2.7em;'
+					'border-top:7px dotted #ccc;border-right:1px solid blue;border-bottom:1px solid blue;border-left:2.7em dashed #665511;'
 				);
 
 				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
@@ -315,7 +317,7 @@ describe( 'Styles', () => {
 				styles.insertProperty( 'border-top', '7px dotted #ccc' );
 
 				expect( styles.getInlineStyle() ).to.equal(
-					'border-color:#ccc blue blue #665511;border-style:dotted solid solid dashed;border-width:7px 1px 1px 2.7em;'
+					'border-top:7px dotted #ccc;border-right:1px solid blue;border-bottom:1px solid blue;border-left:2.7em dashed #665511;'
 				);
 				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
 				expect( styles.getInlineProperty( 'border-color' ) ).to.equal( '#ccc blue blue #665511' );
@@ -328,19 +330,59 @@ describe( 'Styles', () => {
 				styles.removeProperty( 'border-color' );
 
 				expect( styles.getInlineStyle() ).to.equal(
-					'border-style:solid;border-width:1px;'
+					'border-top:1px solid;border-right:1px solid;border-bottom:1px solid;border-left:1px solid;'
 				);
 
 				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
 				expect( styles.getInlineProperty( 'border-color' ) ).to.be.undefined;
 				expect( styles.getInlineProperty( 'border-style' ) ).to.equal( 'solid' );
 				expect( styles.getInlineProperty( 'border-width' ) ).to.equal( '1px' );
+				expect( styles.getInlineProperty( 'border-top' ) ).to.equal( '1px solid' );
+				expect( styles.getInlineProperty( 'border-right' ) ).to.equal( '1px solid' );
+				expect( styles.getInlineProperty( 'border-bottom' ) ).to.equal( '1px solid' );
+				expect( styles.getInlineProperty( 'border-left' ) ).to.equal( '1px solid' );
 			} );
 
-			it( 'should output border with only style shorthand', () => {
+			it( 'should output border with only style shorthand (style)', () => {
 				styles.setStyle( 'border:solid;' );
 
-				expect( styles.getInlineStyle() ).to.equal( 'border-style:solid;' );
+				expect( styles.getInlineStyle() ).to.equal( 'border-top:solid;border-right:solid;border-bottom:solid;border-left:solid;' );
+				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-color' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-style' ) ).to.equal( 'solid' );
+				expect( styles.getInlineProperty( 'border-width' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-top' ) ).to.equal( 'solid' );
+				expect( styles.getInlineProperty( 'border-right' ) ).to.equal( 'solid' );
+				expect( styles.getInlineProperty( 'border-bottom' ) ).to.equal( 'solid' );
+				expect( styles.getInlineProperty( 'border-left' ) ).to.equal( 'solid' );
+			} );
+
+			it( 'should output border with only style shorthand (color)', () => {
+				styles.setStyle( 'border:#f00;' );
+
+				expect( styles.getInlineStyle() ).to.equal( 'border-top:#f00;border-right:#f00;border-bottom:#f00;border-left:#f00;' );
+				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-color' ) ).to.equal( '#f00' );
+				expect( styles.getInlineProperty( 'border-style' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-width' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-top' ) ).to.equal( '#f00' );
+				expect( styles.getInlineProperty( 'border-right' ) ).to.equal( '#f00' );
+				expect( styles.getInlineProperty( 'border-bottom' ) ).to.equal( '#f00' );
+				expect( styles.getInlineProperty( 'border-left' ) ).to.equal( '#f00' );
+			} );
+
+			it( 'should output border with only style shorthand (width)', () => {
+				styles.setStyle( 'border:1px;' );
+
+				expect( styles.getInlineStyle() ).to.equal( 'border-top:1px;border-right:1px;border-bottom:1px;border-left:1px;' );
+				expect( styles.getInlineProperty( 'border' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-color' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-style' ) ).to.be.undefined;
+				expect( styles.getInlineProperty( 'border-width' ) ).to.equal( '1px' );
+				expect( styles.getInlineProperty( 'border-top' ) ).to.equal( '1px' );
+				expect( styles.getInlineProperty( 'border-right' ) ).to.equal( '1px' );
+				expect( styles.getInlineProperty( 'border-bottom' ) ).to.equal( '1px' );
+				expect( styles.getInlineProperty( 'border-left' ) ).to.equal( '1px' );
 			} );
 
 			describe( 'border-color', () => {
@@ -514,6 +556,25 @@ describe( 'Styles', () => {
 					} );
 				} );
 			} );
+
+			describe( 'border-* position', () => {
+				it( 'should output all positions', () => {
+					styles.setStyle(
+						'border-top:none;' +
+						'border-left:none;' +
+						'border-bottom:dotted #FFC000 3.0pt;' +
+						'border-right:dotted #FFC000 3.0pt;'
+					);
+
+					expect( styles.getInlineStyle() ).to.equal(
+						'border-top:none;border-right:3.0pt dotted #FFC000;border-bottom:3.0pt dotted #FFC000;border-left:none;'
+					);
+					expect( styles.getInlineProperty( 'border-top' ) ).to.equal( 'none' );
+					expect( styles.getInlineProperty( 'border-right' ) ).to.equal( '3.0pt dotted #FFC000' );
+					expect( styles.getInlineProperty( 'border-bottom' ) ).to.equal( '3.0pt dotted #FFC000' );
+					expect( styles.getInlineProperty( 'border-left' ) ).to.equal( 'none' );
+				} );
+			} );
 		} );
 
 		describe( 'margin', () => {