From 4ebf7b72bec6ead5a13455f5dee08cba133e7595 Mon Sep 17 00:00:00 2001 From: David Ortner Date: Fri, 9 Sep 2022 16:21:45 +0200 Subject: [PATCH] #344@trivial: Continues on CSSStyleDeclaration. --- .../CSSStyleDeclarationPropertyManager.ts | 11 +- .../CSSStyleDeclarationPropertySetParser.ts | 64 +-- .../CSSStyleDeclarationValueParser.ts | 28 +- .../declaration/CSSStyleDeclaration.test.ts | 420 ++++++++++++++++++ 4 files changed, 486 insertions(+), 37 deletions(-) diff --git a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertyManager.ts b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertyManager.ts index 04f54e6f2..ea645febe 100644 --- a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertyManager.ts +++ b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertyManager.ts @@ -242,6 +242,11 @@ export default class CSSStyleDeclarationPropertyManager { * @param important Important. */ public set(name: string, value: string, important: boolean): void { + if (value === null) { + this.remove(name); + return; + } + let properties = null; switch (name) { @@ -356,15 +361,15 @@ export default class CSSStyleDeclarationPropertyManager { case 'css-float': properties = CSSStyleDeclarationPropertySetParser.getCSSFloat(value, important); break; + case 'float': + properties = CSSStyleDeclarationPropertySetParser.getFloat(value, important); + break; case 'display': properties = CSSStyleDeclarationPropertySetParser.getDisplay(value, important); break; case 'direction': properties = CSSStyleDeclarationPropertySetParser.getDirection(value, important); break; - case 'float': - properties = CSSStyleDeclarationPropertySetParser.getFloat(value, important); - break; case 'flex': properties = CSSStyleDeclarationPropertySetParser.getFlex(value, important); break; diff --git a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.ts b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.ts index 50a16d156..5d140c1a8 100644 --- a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.ts +++ b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationPropertySetParser.ts @@ -22,7 +22,7 @@ const BACKGROUND_CLIP = ['border-box', 'padding-box', 'content-box']; const BACKGROUND_ATTACHMENT = ['scroll', 'fixed']; const FLEX_BASIS = ['auto', 'fill', 'max-content', 'min-content', 'fit-content', 'content']; const CLEAR = ['none', 'left', 'right', 'both']; -const FLOAT = ['none', 'left', 'right']; +const FLOAT = ['none', 'left', 'right', 'inline-start', 'inline-end']; const SYSTEM_FONT = ['caption', 'icon', 'menu', 'message-box', 'small-caption', 'status-bar']; const FONT_WEIGHT = ['normal', 'bold', 'bolder', 'lighter']; const FONT_STYLE = ['normal', 'italic', 'oblique']; @@ -168,7 +168,7 @@ export default class CSSStyleDeclarationPropertySetParser { } { const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return parsedValue ? { top: { value: parsedValue, important } } : null; } @@ -187,7 +187,7 @@ export default class CSSStyleDeclarationPropertySetParser { } { const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return parsedValue ? { right: { value: parsedValue, important } } : null; } @@ -206,7 +206,7 @@ export default class CSSStyleDeclarationPropertySetParser { } { const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return parsedValue ? { bottom: { value: parsedValue, important } } : null; } @@ -225,7 +225,7 @@ export default class CSSStyleDeclarationPropertySetParser { } { const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return parsedValue ? { left: { value: parsedValue, important } } : null; } @@ -318,8 +318,7 @@ export default class CSSStyleDeclarationPropertySetParser { ): { [key: string]: ICSSStyleDeclarationPropertyValue; } { - const float = - CSSStyleDeclarationValueParser.getGlobal(value) || this.getFloat(value, important); + const float = this.getFloat(value, important); return float ? { 'css-float': float['float'] } : null; } @@ -715,7 +714,7 @@ export default class CSSStyleDeclarationPropertySetParser { for (const part of parts) { if ( !CSSStyleDeclarationValueParser.getInteger(part) && - !CSSStyleDeclarationValueParser.getMeasurementOrAuto(part) + !CSSStyleDeclarationValueParser.getContentMeasurement(part) ) { return null; } @@ -1121,8 +1120,8 @@ export default class CSSStyleDeclarationPropertySetParser { return { ...this.getBorderTopLeftRadius(globalValue, important), ...this.getBorderTopRightRadius(globalValue, important), - ...this.getBorderTopRightRadius(globalValue, important), - ...this.getBorderTopRightRadius(globalValue, important) + ...this.getBorderBottomRightRadius(globalValue, important), + ...this.getBorderBottomLeftRadius(globalValue, important) }; } @@ -1548,7 +1547,7 @@ export default class CSSStyleDeclarationPropertySetParser { ): { [key: string]: ICSSStyleDeclarationPropertyValue } { const margin = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return margin ? { 'margin-top': { value: margin, important } } : null; } @@ -1565,7 +1564,7 @@ export default class CSSStyleDeclarationPropertySetParser { ): { [key: string]: ICSSStyleDeclarationPropertyValue } { const margin = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return margin ? { 'margin-right': { value: margin, important } } : null; } @@ -1582,7 +1581,7 @@ export default class CSSStyleDeclarationPropertySetParser { ): { [key: string]: ICSSStyleDeclarationPropertyValue } { const margin = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return margin ? { 'margin-bottom': { value: margin, important } } : null; } @@ -1599,7 +1598,7 @@ export default class CSSStyleDeclarationPropertySetParser { ): { [key: string]: ICSSStyleDeclarationPropertyValue } { const margin = CSSStyleDeclarationValueParser.getGlobal(value) || - CSSStyleDeclarationValueParser.getMeasurementOrAuto(value); + CSSStyleDeclarationValueParser.getContentMeasurement(value); return margin ? { 'margin-left': { value: margin, important } } : null; } @@ -1640,20 +1639,30 @@ export default class CSSStyleDeclarationPropertySetParser { }; } - const parts = value.split(/ +/); - const flexGrow = parts[0] && this.getFlexGrow(parts[0], important); - const flexShrink = parts[1] && this.getFlexShrink(parts[1], important); - const flexBasis = parts[2] && this.getFlexBasis(parts[2], important); + const measurement = CSSStyleDeclarationValueParser.getContentMeasurement(lowerValue); - if (flexGrow && flexShrink && flexBasis) { + if (measurement) { return { - ...flexBasis, - ...flexGrow, - ...flexBasis + ...this.getFlexGrow('1', important), + ...this.getFlexShrink('1', important), + ...this.getFlexBasis(measurement, important) }; } - return null; + const parts = value.split(/ +/); + const flexGrow = this.getFlexGrow(parts[0], important); + const flexShrink = this.getFlexShrink(parts[1] || '1', important); + const flexBasis = this.getFlexBasis(parts[2] || '0%', important); + + if (!flexGrow || !flexShrink || !flexBasis) { + return null; + } + + return { + ...flexGrow, + ...flexShrink, + ...flexBasis + }; } /** @@ -1673,7 +1682,8 @@ export default class CSSStyleDeclarationPropertySetParser { if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FLEX_BASIS.includes(lowerValue)) { return { 'flex-basis': { value: lowerValue, important } }; } - return { 'flex-basis': { value: CSSStyleDeclarationValueParser.getLength(value), important } }; + const measurement = CSSStyleDeclarationValueParser.getContentMeasurement(value); + return measurement ? { 'flex-basis': { value: measurement, important } } : null; } /** @@ -1828,15 +1838,15 @@ export default class CSSStyleDeclarationPropertySetParser { if ( parts[0] !== 'cover' && parts[0] !== 'contain' && - !CSSStyleDeclarationValueParser.getMeasurementOrAuto(parts[0]) + !CSSStyleDeclarationValueParser.getContentMeasurement(parts[0]) ) { return null; } parsed.push(parts[0]); } else { if ( - !CSSStyleDeclarationValueParser.getMeasurementOrAuto(parts[0]) || - !CSSStyleDeclarationValueParser.getMeasurementOrAuto(parts[1]) + !CSSStyleDeclarationValueParser.getContentMeasurement(parts[0]) || + !CSSStyleDeclarationValueParser.getContentMeasurement(parts[1]) ) { return null; } diff --git a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationValueParser.ts b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationValueParser.ts index 3f77e2128..746fd7bc0 100644 --- a/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationValueParser.ts +++ b/packages/happy-dom/src/css/declaration/utilities/CSSStyleDeclarationValueParser.ts @@ -8,6 +8,7 @@ const URL_REGEXP = /^url\(\s*([^)]*)\s*\)$/; const INTEGER_REGEXP = /^[0-9]+$/; const FLOAT_REGEXP = /^[0-9.]+$/; const CALC_REGEXP = /^calc\([^^)]+\)$/; +const FIT_CONTENT_REGEXP = /^fit-content\([^^)]+\)$/; const GRADIENT_REGEXP = /^(repeating-linear|linear|radial|repeating-radial|conic|repeating-conic)-gradient\([^)]+\)$/; const GLOBALS = ['inherit', 'initial', 'unset', 'revert']; @@ -223,6 +224,23 @@ export default class CSSStyleDeclarationValueParser { return null; } + /** + * Returns fit content. + * + * @param value Value. + * @returns Parsed value. + */ + public static getFitContent(value: string): string { + const lowerValue = value.toLowerCase(); + if (lowerValue === 'auto' || lowerValue === 'max-content' || lowerValue === 'min-content') { + return lowerValue; + } + if (FIT_CONTENT_REGEXP.test(lowerValue)) { + return lowerValue; + } + return null; + } + /** * Returns measurement. * @@ -234,17 +252,13 @@ export default class CSSStyleDeclarationValueParser { } /** - * Returns measurement or auto. + * Returns measurement or auto, min-content, max-content or fit-content. * * @param value Value. * @returns Parsed value. */ - public static getMeasurementOrAuto(value: string): string { - const lowerValue = value.toLowerCase(); - if (lowerValue === 'auto') { - return lowerValue; - } - return this.getMeasurement(value); + public static getContentMeasurement(value: string): string { + return this.getFitContent(value) || this.getMeasurement(value); } /** diff --git a/packages/happy-dom/test/css/declaration/CSSStyleDeclaration.test.ts b/packages/happy-dom/test/css/declaration/CSSStyleDeclaration.test.ts index db6777aee..bf6f9113c 100644 --- a/packages/happy-dom/test/css/declaration/CSSStyleDeclaration.test.ts +++ b/packages/happy-dom/test/css/declaration/CSSStyleDeclaration.test.ts @@ -83,6 +83,32 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border: inherit'); + + expect(declaration.border).toBe('inherit'); + expect(declaration.borderTop).toBe('inherit'); + expect(declaration.borderRight).toBe('inherit'); + expect(declaration.borderBottom).toBe('inherit'); + expect(declaration.borderLeft).toBe('inherit'); + expect(declaration.borderTopColor).toBe('inherit'); + expect(declaration.borderRightColor).toBe('inherit'); + expect(declaration.borderBottomColor).toBe('inherit'); + expect(declaration.borderLeftColor).toBe('inherit'); + expect(declaration.borderTopWidth).toBe('inherit'); + expect(declaration.borderRightWidth).toBe('inherit'); + expect(declaration.borderBottomWidth).toBe('inherit'); + expect(declaration.borderLeftWidth).toBe('inherit'); + expect(declaration.borderTopStyle).toBe('inherit'); + expect(declaration.borderRightStyle).toBe('inherit'); + expect(declaration.borderBottomStyle).toBe('inherit'); + expect(declaration.borderLeftStyle).toBe('inherit'); + expect(declaration.borderImage).toBe('inherit'); + expect(declaration.borderImageOutset).toBe('inherit'); + expect(declaration.borderImageRepeat).toBe('inherit'); + expect(declaration.borderImageSlice).toBe('inherit'); + expect(declaration.borderImageSource).toBe('inherit'); + expect(declaration.borderImageWidth).toBe('inherit'); + element.setAttribute('style', 'border: 2px solid green'); expect(declaration.border).toBe('2px solid green'); @@ -141,6 +167,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-top: inherit'); + + expect(declaration.borderTop).toBe('inherit'); + expect(declaration.borderTopColor).toBe('inherit'); + expect(declaration.borderTopWidth).toBe('inherit'); + expect(declaration.borderTopStyle).toBe('inherit'); + element.setAttribute('style', 'border-top: green 2px solid'); expect(declaration.border).toBe(''); @@ -160,6 +193,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-right: inherit'); + + expect(declaration.borderRight).toBe('inherit'); + expect(declaration.borderRightColor).toBe('inherit'); + expect(declaration.borderRightWidth).toBe('inherit'); + expect(declaration.borderRightStyle).toBe('inherit'); + element.setAttribute('style', 'border-right: green solid 2px'); expect(declaration.border).toBe(''); @@ -179,6 +219,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-bottom: inherit'); + + expect(declaration.borderBottom).toBe('inherit'); + expect(declaration.borderBottomColor).toBe('inherit'); + expect(declaration.borderBottomWidth).toBe('inherit'); + expect(declaration.borderBottomStyle).toBe('inherit'); + element.setAttribute('style', 'border-bottom: green solid 2px'); expect(declaration.border).toBe(''); @@ -198,6 +245,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-left: inherit'); + + expect(declaration.borderLeft).toBe('inherit'); + expect(declaration.borderLeftColor).toBe('inherit'); + expect(declaration.borderLeftWidth).toBe('inherit'); + expect(declaration.borderLeftStyle).toBe('inherit'); + element.setAttribute('style', 'border-left: green solid 2px'); expect(declaration.border).toBe(''); @@ -217,6 +271,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-width: inherit'); + + expect(declaration.borderTopWidth).toBe('inherit'); + expect(declaration.borderRightWidth).toBe('inherit'); + expect(declaration.borderBottomWidth).toBe('inherit'); + expect(declaration.borderLeftWidth).toBe('inherit'); + element.setAttribute('style', 'border-width: 1px 2px 3px 4px'); expect(declaration.borderTopWidth).toBe('1px'); @@ -237,6 +298,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-style: inherit'); + + expect(declaration.borderTopStyle).toBe('inherit'); + expect(declaration.borderRightStyle).toBe('inherit'); + expect(declaration.borderBottomStyle).toBe('inherit'); + expect(declaration.borderLeftStyle).toBe('inherit'); + element.setAttribute('style', 'border-style: none hidden dotted dashed'); expect(declaration.borderTopStyle).toBe('none'); @@ -257,6 +325,13 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-color: inherit'); + + expect(declaration.borderTopColor).toBe('inherit'); + expect(declaration.borderRightColor).toBe('inherit'); + expect(declaration.borderBottomColor).toBe('inherit'); + expect(declaration.borderLeftColor).toBe('inherit'); + element.setAttribute('style', 'border-color: #000 #ffffff rgba(135,200,150,0.5) blue'); expect(declaration.borderTopColor).toBe('#000'); @@ -277,6 +352,14 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-image: inherit'); + expect(declaration.borderImage).toBe('inherit'); + expect(declaration.borderImageSource).toBe('inherit'); + expect(declaration.borderImageOutset).toBe('inherit'); + expect(declaration.borderImageRepeat).toBe('inherit'); + expect(declaration.borderImageSlice).toBe('inherit'); + expect(declaration.borderImageWidth).toBe('inherit'); + element.setAttribute( 'style', 'border-image: repeating-linear-gradient(30deg, #4d9f0c, #9198e5, #4d9f0c 20px) 60' @@ -309,6 +392,7 @@ describe('CSSStyleDeclaration', () => { expect(declaration.borderImage).toBe( `url('/media/examples/border-diamonds.png') 10 fill / 20px / 30px space` ); + expect(declaration.borderImageSource).toBe(`url('/media/examples/border-diamonds.png')`); expect(declaration.borderImageOutset).toBe('30px'); expect(declaration.borderImageRepeat).toBe('space'); expect(declaration.borderImageSlice).toBe('10 fill'); @@ -324,6 +408,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', `border-image-source: inherit`); + + expect(declaration.borderImageSource).toBe('inherit'); + element.setAttribute( 'style', `border-image-source: url('/media/examples/border-diamonds.png')` @@ -350,6 +438,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-image-slice: inherit'); + + expect(declaration.borderImageSlice).toBe('inherit'); + element.setAttribute('style', 'border-image-slice: 30'); expect(declaration.borderImageSlice).toBe('30'); @@ -371,6 +463,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-image-width: inherit'); + + expect(declaration.borderImageWidth).toBe('inherit'); + element.setAttribute('style', 'border-image-width: auto'); expect(declaration.borderImageWidth).toBe('auto'); @@ -389,6 +485,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-image-outset: inherit'); + + expect(declaration.borderImageOutset).toBe('inherit'); + element.setAttribute('style', 'border-image-outset: 1rem'); expect(declaration.borderImageOutset).toBe('1rem'); @@ -407,6 +507,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-image-repeat: inherit'); + + expect(declaration.borderImageRepeat).toBe('inherit'); + element.setAttribute('style', 'border-image-repeat: stretch'); expect(declaration.borderImageRepeat).toBe('stretch'); @@ -425,6 +529,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-top-width: inherit'); + + expect(declaration.borderTopWidth).toBe('inherit'); + element.setAttribute('style', 'border-top-width: thick'); expect(declaration.borderTopWidth).toBe('thick'); @@ -439,6 +547,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-right-width: inherit'); + + expect(declaration.borderRightWidth).toBe('inherit'); + element.setAttribute('style', 'border-right-width: thick'); expect(declaration.borderRightWidth).toBe('thick'); @@ -453,6 +565,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-bottom-width: inherit'); + + expect(declaration.borderBottomWidth).toBe('inherit'); + element.setAttribute('style', 'border-bottom-width: thick'); expect(declaration.borderBottomWidth).toBe('thick'); @@ -467,6 +583,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-left-width: inherit'); + + expect(declaration.borderLeftWidth).toBe('inherit'); + element.setAttribute('style', 'border-left-width: thick'); expect(declaration.borderLeftWidth).toBe('thick'); @@ -481,6 +601,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-top-color: inherit'); + + expect(declaration.borderTopColor).toBe('inherit'); + element.setAttribute('style', 'border-top-color: red'); expect(declaration.borderTopColor).toBe('red'); @@ -495,6 +619,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-right-color: inherit'); + + expect(declaration.borderRightColor).toBe('inherit'); + element.setAttribute('style', 'border-right-color: red'); expect(declaration.borderRightColor).toBe('red'); @@ -509,6 +637,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-bottom-color: inherit'); + + expect(declaration.borderBottomColor).toBe('inherit'); + element.setAttribute('style', 'border-bottom-color: red'); expect(declaration.borderBottomColor).toBe('red'); @@ -523,6 +655,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-left-color: inherit'); + + expect(declaration.borderLeftColor).toBe('inherit'); + element.setAttribute('style', 'border-left-color: red'); expect(declaration.borderLeftColor).toBe('red'); @@ -537,6 +673,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-top-style: inherit'); + + expect(declaration.borderTopStyle).toBe('inherit'); + element.setAttribute('style', 'border-top-style: dotted'); expect(declaration.borderTopStyle).toBe('dotted'); @@ -551,6 +691,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-right-style: inherit'); + + expect(declaration.borderRightStyle).toBe('inherit'); + element.setAttribute('style', 'border-right-style: dotted'); expect(declaration.borderRightStyle).toBe('dotted'); @@ -565,6 +709,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-bottom-style: inherit'); + + expect(declaration.borderBottomStyle).toBe('inherit'); + element.setAttribute('style', 'border-bottom-style: dotted'); expect(declaration.borderBottomStyle).toBe('dotted'); @@ -579,6 +727,10 @@ describe('CSSStyleDeclaration', () => { it('Returns style property.', () => { const declaration = new CSSStyleDeclaration(element); + element.setAttribute('style', 'border-left-style: inherit'); + + expect(declaration.borderLeftStyle).toBe('inherit'); + element.setAttribute('style', 'border-left-style: dotted'); expect(declaration.borderLeftStyle).toBe('dotted'); @@ -589,6 +741,274 @@ describe('CSSStyleDeclaration', () => { }); }); + describe('get borderRadius()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'border-radius: inherit'); + + expect(declaration.borderRadius).toBe('inherit'); + expect(declaration.borderTopLeftRadius).toBe('inherit'); + expect(declaration.borderTopRightRadius).toBe('inherit'); + expect(declaration.borderBottomRightRadius).toBe('inherit'); + expect(declaration.borderBottomLeftRadius).toBe('inherit'); + + element.setAttribute('style', 'border-radius: 1px 2px 3px 4px'); + + expect(declaration.borderRadius).toBe('1px 2px 3px 4px'); + expect(declaration.borderTopLeftRadius).toBe('1px'); + expect(declaration.borderTopRightRadius).toBe('2px'); + expect(declaration.borderBottomRightRadius).toBe('3px'); + expect(declaration.borderBottomLeftRadius).toBe('4px'); + + element.setAttribute('style', 'border-radius: 1px 2px 3px'); + + expect(declaration.borderRadius).toBe('1px 2px 3px'); + + element.setAttribute('style', 'border-radius: 1px 2px'); + + expect(declaration.borderRadius).toBe('1px 2px'); + + element.setAttribute('style', 'border-radius: 1px'); + + expect(declaration.borderRadius).toBe('1px'); + }); + }); + + describe('get borderTopLeftRadius()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'border-top-left-radius: inherit'); + + expect(declaration.borderTopLeftRadius).toBe('inherit'); + + element.setAttribute('style', 'border-top-left-radius: 1rem'); + + expect(declaration.borderTopLeftRadius).toBe('1rem'); + }); + }); + + describe('get borderTopRightRadius()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'border-top-right-radius: inherit'); + + expect(declaration.borderTopRightRadius).toBe('inherit'); + + element.setAttribute('style', 'border-top-right-radius: 1rem'); + + expect(declaration.borderTopRightRadius).toBe('1rem'); + }); + }); + + describe('get borderBottomRightRadius()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'border-bottom-right-radius: inherit'); + + expect(declaration.borderBottomRightRadius).toBe('inherit'); + + element.setAttribute('style', 'border-bottom-right-radius: 1rem'); + + expect(declaration.borderBottomRightRadius).toBe('1rem'); + }); + }); + + describe('get borderBottomLeftRadius()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'border-bottom-left-radius: inherit'); + + expect(declaration.borderBottomLeftRadius).toBe('inherit'); + + element.setAttribute('style', 'border-bottom-left-radius: 1rem'); + + expect(declaration.borderBottomLeftRadius).toBe('1rem'); + }); + }); + + describe('get borderCollapse()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of ['collapse', 'separate', 'inherit']) { + element.setAttribute('style', `border-collapse: ${value}`); + + expect(declaration.borderCollapse).toBe(value); + } + }); + }); + + describe('get clear()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of ['inherit', 'none', 'left', 'right', 'both']) { + element.setAttribute('style', `clear: ${value}`); + + expect(declaration.clear).toBe(value); + } + }); + }); + + describe('get clip()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'clip: inherit'); + + expect(declaration.clip).toBe('inherit'); + + element.setAttribute('style', 'clip: auto'); + + expect(declaration.clip).toBe('auto'); + + element.setAttribute('style', 'clip: rect(1px, 10em, 3rem, 2ch)'); + + expect(declaration.clip).toBe('rect(1px, 10em, 3rem, 2ch)'); + }); + }); + + describe('get cssFloat()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of ['inherit', 'none', 'left', 'right', 'inline-start', 'inline-end']) { + element.setAttribute('style', `css-float: ${value}`); + + expect(declaration.cssFloat).toBe(value); + } + }); + }); + + describe('get float()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of ['inherit', 'none', 'left', 'right', 'inline-start', 'inline-end']) { + element.setAttribute('style', `float: ${value}`); + + expect(declaration.float).toBe(value); + } + }); + }); + + describe('get display()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of [ + 'inherit', + 'initial', + 'revert', + 'unset', + 'block', + 'inline', + 'inline-block', + 'flex', + 'inline-flex', + 'grid', + 'inline-grid', + 'flow-root', + 'none', + 'contents', + 'block flow', + 'inline flow', + 'inline flow-root', + 'block flex', + 'inline flex', + 'block grid', + 'inline grid', + 'block flow-root', + 'table', + 'table-row', + 'list-item' + ]) { + element.setAttribute('style', `display: ${value}`); + + expect(declaration.display).toBe(value); + } + }); + }); + + describe('get direction()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + for (const value of ['inherit', 'initial', 'revert', 'unset', 'ltr', 'rtl']) { + element.setAttribute('style', `direction: ${value}`); + + expect(declaration.direction).toBe(value); + } + }); + }); + + describe('get flex()', () => { + it('Returns style property.', () => { + const declaration = new CSSStyleDeclaration(element); + + element.setAttribute('style', 'flex: inherit'); + + expect(declaration.flex).toBe('inherit'); + expect(declaration.flexGrow).toBe('inherit'); + expect(declaration.flexShrink).toBe('inherit'); + expect(declaration.flexBasis).toBe('inherit'); + + element.setAttribute('style', 'flex: none'); + + expect(declaration.flex).toBe('0 0 auto'); + expect(declaration.flexGrow).toBe('0'); + expect(declaration.flexShrink).toBe('0'); + expect(declaration.flexBasis).toBe('auto'); + + element.setAttribute('style', 'flex: auto'); + + expect(declaration.flex).toBe('1 1 auto'); + expect(declaration.flexGrow).toBe('1'); + expect(declaration.flexShrink).toBe('1'); + expect(declaration.flexBasis).toBe('auto'); + + element.setAttribute('style', 'flex: fit-content(10px)'); + + expect(declaration.flex).toBe('1 1 fit-content(10px)'); + expect(declaration.flexGrow).toBe('1'); + expect(declaration.flexShrink).toBe('1'); + expect(declaration.flexBasis).toBe('fit-content(10px)'); + + element.setAttribute('style', 'flex: 3'); + + expect(declaration.flex).toBe('3 1 0%'); + expect(declaration.flexGrow).toBe('3'); + expect(declaration.flexShrink).toBe('1'); + expect(declaration.flexBasis).toBe('0%'); + + element.setAttribute('style', 'flex: 3 2'); + + expect(declaration.flex).toBe('3 2 0%'); + expect(declaration.flexGrow).toBe('3'); + expect(declaration.flexShrink).toBe('2'); + expect(declaration.flexBasis).toBe('0%'); + + element.setAttribute('style', 'flex: 3 2 min-content'); + + expect(declaration.flex).toBe('3 2 min-content'); + expect(declaration.flexGrow).toBe('3'); + expect(declaration.flexShrink).toBe('2'); + expect(declaration.flexBasis).toBe('min-content'); + + element.setAttribute('style', 'flex: 3 2 50rem'); + + expect(declaration.flex).toBe('3 2 50rem'); + expect(declaration.flexGrow).toBe('3'); + expect(declaration.flexShrink).toBe('2'); + expect(declaration.flexBasis).toBe('50rem'); + }); + }); + describe('get length()', () => { it('Returns length when of styles on element.', () => { const declaration = new CSSStyleDeclaration(element);