Tests: Import WPT CSSOM tests about serialization

This is an area we're lacking in, so let's bring these in-tree to track
them more easily. :^)
This commit is contained in:
Sam Atkins 2024-11-28 15:34:26 +00:00 committed by Andreas Kling
commit 2fc164c0b6
Notes: github-actions[bot] 2024-11-30 10:03:37 +00:00
35 changed files with 2945 additions and 0 deletions

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 3 tests
3 Fail
Details
Result Test Name MessageFail Declaration with border longhands is not serialized to a border shorthand declaration.
Fail Declaration with border longhands and border-image is not serialized to a border shorthand declaration.
Fail Border shorthand is serialized correctly if all border-image-* are set to their initial specified values.

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass CSSStyleDeclaration cssText serializes declaration blocks.

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 5 tests
1 Pass
4 Fail
Details
Result Test Name MessagePass Single value flex with CSS-wide keyword should serialize correctly.
Fail Single value flex with non-CSS-wide value should serialize correctly.
Fail Multiple values flex with CSS-wide keyword should serialize correctly.
Fail Multiple values flex with CSS-wide keywords and non-CSS-wide value should serialize correctly.
Fail Multiple values flex with CSS-wide and two non-CSS-wide-keyword values should serialize correctly.

View file

@ -0,0 +1,14 @@
Summary
Harness status: OK
Rerun
Found 4 tests
4 Pass
Details
Result Test Name MessagePass Serialization of <generic-family>
Pass Serialization of quoted "<generic-family>"
Pass Serialization of prefixed -webkit-<generic-family>
Pass Serialization of NonGenericFontFamilyName,-webkit-body,-webkit-standard,-webkit-pictograph,BlinkMacSystemFont

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail The font shorthand should be serialized just like any other shorthand.

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 7 tests
4 Pass
3 Fail
Details
Result Test Name MessagePass font-variant: normal serialization
Fail font-variant: none serialization
Pass font-variant-ligatures: none serialization with non-default value for another longhand
Pass font-variant: normal with non-default longhands
Fail CSS-wide keyword in one longhand
Pass CSS-wide keyword in shorthand
Fail font: menu serialization

View file

@ -0,0 +1,21 @@
Summary
Harness status: OK
Rerun
Found 10 tests
2 Pass
8 Fail
Details
Result Test Name MessagePass Single value overflow with CSS-wide keyword should serialize correctly.
Fail Single value overflow with non-CSS-wide keyword should serialize correctly.
Fail Overflow-x/y longhands with same CSS-wide keyword should serialize correctly.
Fail Overflow-x/y longhands with same non-CSS-wide keyword should serialize correctly.
Fail Overflow-x/y longhands with different keywords should serialize correctly.
Fail Single value overflow on element with CSS-wide keyword should serialize correctly.
Fail Single value overflow on element with non-CSS-wide keyword should serialize correctly.
Fail Overflow-x/y longhands on element with same CSS-wide keyword should serialize correctly.
Fail Overflow-x/y longhands on element with same non-CSS-wide keyword should serialize correctly.
Pass Overflow-x/y longhands on element with different keywords should serialize correctly.

View file

@ -0,0 +1,34 @@
Summary
Harness status: OK
Rerun
Found 23 tests
19 Pass
4 Fail
Details
Result Test Name MessagePass :nth-child serialization produces canonical form
Pass single universal selector shows '*' when serialized.
Pass single type (simple) selector in the sequence of simple selectors that is not a universal selector
Pass single class (simple) selector in the sequence of simple selectors that is not a universal selector
Pass single id (simple) selector in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector which does not accept arguments in the sequence of simple selectors that is not a universal selector
Fail single pseudo (simple) selector "lang" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector "nth-child" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector "nth-last-child" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector "nth-of-child" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector ":nth-last-of-type" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass single pseudo (simple) selector ":not" which accepts arguments in the sequence of simple selectors that is not a universal selector
Pass escaped character in attribute name
Fail escaped character as code point in attribute name
Pass escaped character (@) in attribute name
Fail escaped character in attribute name with any namespace
Pass escaped character in attribute prefix
Pass escaped character in both attribute prefix and name
Pass escaped character (\) in element name
Pass escaped character (\) in element name with any namespace without default
Fail escaped character (\) in element name with any namespace with default
Pass escaped character (\) in element name with no namespace
Pass escaped character (*) in element prefix

View file

@ -0,0 +1,14 @@
Summary
Harness status: OK
Rerun
Found 4 tests
4 Pass
Details
Result Test Name MessagePass Inline style declaration without whitespace between '!' and 'important'.
Pass Inline style declaration with whitespace between '!' and 'important'.
Pass Style set dynamically via cssText without whitespace between '!' and 'important'.
Pass Style set dynamically via cssText with whitespace between '!' and 'important'.

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 2 tests
1 Pass
1 Fail
Details
Result Test Name MessageFail Specified style
Pass Computed style

View file

@ -0,0 +1,31 @@
Summary
Harness status: OK
Rerun
Found 20 tests
18 Pass
2 Fail
Details
Result Test Name MessagePass z-index can take a 4-digit integer
Pass An unregistered custom prop can take a 4-digit integer
Pass An <integer> custom prop can take a 4-digit integer
Pass z-index can take a custom property set to a 4-digit integer
Pass z-index can take a 6-digit integer
Pass An unregistered custom prop can take a 6-digit integer
Pass An <integer> custom prop can take a 6-digit integer
Pass z-index can take a custom property set to a 6-digit integer
Pass z-index can take a 8-digit integer
Pass An unregistered custom prop can take a 8-digit integer
Pass An <integer> custom prop can take a 8-digit integer
Pass z-index can take a custom property set to a 8-digit integer
Pass z-index can take a 12-digit integer
Pass An unregistered custom prop can take a 12-digit integer
Pass An <integer> custom prop can take a 12-digit integer
Pass z-index can take a custom property set to a 12-digit integer
Pass z-index can take a 25-digit integer
Fail An unregistered custom prop can take a 25-digit integer
Fail An <integer> custom prop can take a 25-digit integer
Pass z-index can take a custom property set to a 25-digit integer

View file

@ -0,0 +1,23 @@
Summary
Harness status: OK
Rerun
Found 12 tests
10 Pass
2 Fail
Details
Result Test Name MessagePass empty media query list
Pass type - no features
Pass type - no features - negation
Pass type - no features - character case normalization
Pass type - omission of all
Pass type - inclusion of negated all
Pass features - character case normalization
Fail features - preservation of overspecified features
Fail features - no lexicographical sorting
Pass media query list
Pass one rule
Pass many rules

View file

@ -0,0 +1,71 @@
Summary
Harness status: OK
Rerun
Found 60 tests
36 Pass
24 Fail
Details
Result Test Name MessagePass Simple type selector
Pass Type selector without a namespace
Fail Type selector with any namespace
Pass Universal selector
Pass Universal selector without a namespace
Fail Universal selector in any namespace
Pass Type selector with namespace
Pass Universal selector with namespace
Pass Simple type selector followed by class
Pass Simple type selector followed by id
Pass Simple type selector followed by pseudo class
Pass Simple type selector followed by pseudo element
Pass Simple type selector followed by atttribute selector
Pass Type selector without a namespace followed by class
Pass Type selector without a namespace followed by id
Pass Type selector without a namespace followed by pseudo class
Pass Type selector without a namespace followed by pseudo element
Pass Type selector without a namespace followed by attribute selector
Fail Type selector with any namespace followed by class
Fail Type selector with any namespace followed by id
Fail Type selector with any namespace followed by pseudo class
Fail Type selector with any namespace followed by pseudo element
Fail Type selector with any namespace followed by attribute selector
Pass Universal selector followed by class
Pass Universal selector followed by id
Pass Universal selector followed by pseudo class
Pass Universal selector followed by pseudo element
Pass Universal selector followed by attribute selector
Pass Universal selector without a namespace followed by class
Pass Universal selector without a namespace followed by id
Pass Universal selector without a namespace followed by pseudo class
Pass Universal selector without a namespace followed by pseudo element
Pass Universal selector without a namespace followed by attribute selector
Fail Universal selector in any namespace followed by class
Fail Universal selector in any namespace followed by id
Fail Universal selector in any namespace followed by pseudo class
Fail Universal selector in any namespace followed by pseudo element
Fail Universal selector in any namespace followed by attribute selector
Pass Type selector with namespace followed by class
Pass Type selector with namespace followed by id
Pass Type selector with namespace followed by pseudo class
Pass Type selector with namespace followed by pseudo element
Pass Type selector with namespace followed by attribute selector
Pass Universal selector with namespace followed by class
Pass Universal selector with namespace followed by id
Pass Universal selector with namespace followed by pseudo class
Pass Universal selector with namespace followed by pseudo element
Pass Universal selector with namespace followed by attribute selector
Fail Type selector with namespace equal to default namespace
Fail Universal selector with namespace equal to default namespace
Fail Type selector with namespace equal to default namespace followed by class
Fail Type selector with namespace equal to default namespace followed by id
Fail Type selector with namespace equal to default namespace followed by pseudo class
Fail Type selector with namespace equal to default namespace followed by pseudo element
Fail Type selector with namespace equal to default namespace followed by attribute selector
Fail Universal selector with namespace equal to default namespace followed by class
Fail Universal selector with namespace equal to default namespace followed by id
Fail Universal selector with namespace equal to default namespace followed by pseudo class
Fail Universal selector with namespace equal to default namespace followed by pseudo element
Fail Universal selector with namespace equal to default namespace followed by attribute selector

View file

@ -0,0 +1,698 @@
Summary
Harness status: OK
Rerun
Found 687 tests
458 Pass
229 Fail
Details
Result Test Name MessagePass background-attachment: scroll
Pass background-attachment: fixed
Pass background-attachment: inherit
Pass background-color: black
Pass background-color: red
Pass background-color: rgb(50, 75, 100)
Fail background-color: rgba(5, 7, 10, 0.5)
Pass background-color: transparent
Pass background-color: inherit
Pass background-image: url("http://localhost/")
Pass background-image: url(http://localhost/)
Pass background-image: none
Pass background-image: inherit
Fail background-position: 5% 5%
Fail background-position: 5% .5%
Fail background-position: 5% -5%
Fail background-position: 5% -.5%
Fail background-position: 5% 0px
Fail background-position: 5% 1px
Fail background-position: 5% .1em
Fail background-position: 5% -0px
Fail background-position: 5% -1px
Fail background-position: 5% -.1em
Fail background-position: 5% top
Fail background-position: 5% center
Fail background-position: 5% bottom
Fail background-position: .5% 5%
Fail background-position: .5% .5%
Fail background-position: .5% -5%
Fail background-position: .5% -.5%
Fail background-position: .5% 0px
Fail background-position: .5% 1px
Fail background-position: .5% .1em
Fail background-position: .5% -0px
Fail background-position: .5% -1px
Fail background-position: .5% -.1em
Fail background-position: .5% top
Fail background-position: .5% center
Fail background-position: .5% bottom
Fail background-position: -5% 5%
Fail background-position: -5% .5%
Fail background-position: -5% -5%
Fail background-position: -5% -.5%
Fail background-position: -5% 0px
Fail background-position: -5% 1px
Fail background-position: -5% .1em
Fail background-position: -5% -0px
Fail background-position: -5% -1px
Fail background-position: -5% -.1em
Fail background-position: -5% top
Fail background-position: -5% center
Fail background-position: -5% bottom
Fail background-position: -.5% 5%
Fail background-position: -.5% .5%
Fail background-position: -.5% -5%
Fail background-position: -.5% -.5%
Fail background-position: -.5% 0px
Fail background-position: -.5% 1px
Fail background-position: -.5% .1em
Fail background-position: -.5% -0px
Fail background-position: -.5% -1px
Fail background-position: -.5% -.1em
Fail background-position: -.5% top
Fail background-position: -.5% center
Fail background-position: -.5% bottom
Fail background-position: 0px 5%
Fail background-position: 0px .5%
Fail background-position: 0px -5%
Fail background-position: 0px -.5%
Fail background-position: 0px 0px
Fail background-position: 0px 1px
Fail background-position: 0px .1em
Fail background-position: 0px -0px
Fail background-position: 0px -1px
Fail background-position: 0px -.1em
Fail background-position: 0px top
Fail background-position: 0px center
Fail background-position: 0px bottom
Fail background-position: 1px 5%
Fail background-position: 1px .5%
Fail background-position: 1px -5%
Fail background-position: 1px -.5%
Fail background-position: 1px 0px
Fail background-position: 1px 1px
Fail background-position: 1px .1em
Fail background-position: 1px -0px
Fail background-position: 1px -1px
Fail background-position: 1px -.1em
Fail background-position: 1px top
Fail background-position: 1px center
Fail background-position: 1px bottom
Fail background-position: .1em 5%
Fail background-position: .1em .5%
Fail background-position: .1em -5%
Fail background-position: .1em -.5%
Fail background-position: .1em 0px
Fail background-position: .1em 1px
Fail background-position: .1em .1em
Fail background-position: .1em -0px
Fail background-position: .1em -1px
Fail background-position: .1em -.1em
Fail background-position: .1em top
Fail background-position: .1em center
Fail background-position: .1em bottom
Fail background-position: -0px 5%
Fail background-position: -0px .5%
Fail background-position: -0px -5%
Fail background-position: -0px -.5%
Fail background-position: -0px 0px
Fail background-position: -0px 1px
Fail background-position: -0px .1em
Fail background-position: -0px -0px
Fail background-position: -0px -1px
Fail background-position: -0px -.1em
Fail background-position: -0px top
Fail background-position: -0px center
Fail background-position: -0px bottom
Fail background-position: -1px 5%
Fail background-position: -1px .5%
Fail background-position: -1px -5%
Fail background-position: -1px -.5%
Fail background-position: -1px 0px
Fail background-position: -1px 1px
Fail background-position: -1px .1em
Fail background-position: -1px -0px
Fail background-position: -1px -1px
Fail background-position: -1px -.1em
Fail background-position: -1px top
Fail background-position: -1px center
Fail background-position: -1px bottom
Fail background-position: -.1em 5%
Fail background-position: -.1em .5%
Fail background-position: -.1em -5%
Fail background-position: -.1em -.5%
Fail background-position: -.1em 0px
Fail background-position: -.1em 1px
Fail background-position: -.1em .1em
Fail background-position: -.1em -0px
Fail background-position: -.1em -1px
Fail background-position: -.1em -.1em
Fail background-position: -.1em top
Fail background-position: -.1em center
Fail background-position: -.1em bottom
Fail background-position: left 5%
Fail background-position: left .5%
Fail background-position: left -5%
Fail background-position: left -.5%
Fail background-position: left 0px
Fail background-position: left 1px
Fail background-position: left .1em
Fail background-position: left -0px
Fail background-position: left -1px
Fail background-position: left -.1em
Fail background-position: left top
Fail background-position: left center
Fail background-position: left bottom
Fail background-position: center 5%
Fail background-position: center .5%
Fail background-position: center -5%
Fail background-position: center -.5%
Fail background-position: center 0px
Fail background-position: center 1px
Fail background-position: center .1em
Fail background-position: center -0px
Fail background-position: center -1px
Fail background-position: center -.1em
Fail background-position: center top
Fail background-position: center center
Fail background-position: center bottom
Fail background-position: right 5%
Fail background-position: right .5%
Fail background-position: right -5%
Fail background-position: right -.5%
Fail background-position: right 0px
Fail background-position: right 1px
Fail background-position: right .1em
Fail background-position: right -0px
Fail background-position: right -1px
Fail background-position: right -.1em
Fail background-position: right top
Fail background-position: right center
Fail background-position: right bottom
Fail background-position: inherit
Fail background-repeat: repeat
Fail background-repeat: repeat-x
Fail background-repeat: repeat-y
Fail background-repeat: no-repeat
Pass background-repeat: inherit
Pass border-collapse: collapse
Pass border-collapse: separate
Pass border-collapse: inherit
Pass border-spacing: 0px
Pass border-spacing: 1px
Pass border-spacing: .1em
Pass border-spacing: inherit
Pass border-top-color: black
Pass border-top-color: red
Pass border-top-color: rgb(50, 75, 100)
Fail border-top-color: rgba(5, 7, 10, 0.5)
Pass border-top-color: transparent
Pass border-top-color: inherit
Pass border-right-color: black
Pass border-right-color: red
Pass border-right-color: rgb(50, 75, 100)
Fail border-right-color: rgba(5, 7, 10, 0.5)
Pass border-right-color: transparent
Pass border-right-color: inherit
Pass border-bottom-color: black
Pass border-bottom-color: red
Pass border-bottom-color: rgb(50, 75, 100)
Fail border-bottom-color: rgba(5, 7, 10, 0.5)
Pass border-bottom-color: transparent
Pass border-bottom-color: inherit
Pass border-left-color: black
Pass border-left-color: red
Pass border-left-color: rgb(50, 75, 100)
Fail border-left-color: rgba(5, 7, 10, 0.5)
Pass border-left-color: transparent
Pass border-left-color: inherit
Pass border-top-style: none
Pass border-top-style: hidden
Pass border-top-style: dotted
Pass border-top-style: dashed
Pass border-top-style: solid
Pass border-top-style: double
Pass border-top-style: groove
Pass border-top-style: ridge
Pass border-top-style: inset
Pass border-top-style: outset
Pass border-top-style: inherit
Pass border-right-style: none
Pass border-right-style: hidden
Pass border-right-style: dotted
Pass border-right-style: dashed
Pass border-right-style: solid
Pass border-right-style: double
Pass border-right-style: groove
Pass border-right-style: ridge
Pass border-right-style: inset
Pass border-right-style: outset
Pass border-right-style: inherit
Pass border-bottom-style: none
Pass border-bottom-style: hidden
Pass border-bottom-style: dotted
Pass border-bottom-style: dashed
Pass border-bottom-style: solid
Pass border-bottom-style: double
Pass border-bottom-style: groove
Pass border-bottom-style: ridge
Pass border-bottom-style: inset
Pass border-bottom-style: outset
Pass border-bottom-style: inherit
Pass border-left-style: none
Pass border-left-style: hidden
Pass border-left-style: dotted
Pass border-left-style: dashed
Pass border-left-style: solid
Pass border-left-style: double
Pass border-left-style: groove
Pass border-left-style: ridge
Pass border-left-style: inset
Pass border-left-style: outset
Pass border-left-style: inherit
Pass border-top-width: thin
Pass border-top-width: medium
Pass border-top-width: thick
Pass border-top-width: 0px
Pass border-top-width: 1px
Pass border-top-width: .1em
Pass border-top-width: inherit
Pass border-right-width: thin
Pass border-right-width: medium
Pass border-right-width: thick
Pass border-right-width: 0px
Pass border-right-width: 1px
Pass border-right-width: .1em
Pass border-right-width: inherit
Pass border-bottom-width: thin
Pass border-bottom-width: medium
Pass border-bottom-width: thick
Pass border-bottom-width: 0px
Pass border-bottom-width: 1px
Pass border-bottom-width: .1em
Pass border-bottom-width: inherit
Pass border-left-width: thin
Pass border-left-width: medium
Pass border-left-width: thick
Pass border-left-width: 0px
Pass border-left-width: 1px
Pass border-left-width: .1em
Pass border-left-width: inherit
Pass bottom: 0px
Pass bottom: 1px
Pass bottom: .1em
Pass bottom: 5%
Pass bottom: .5%
Pass bottom: auto
Pass bottom: inherit
Pass caption-side: top
Pass caption-side: bottom
Pass caption-side: inherit
Pass clear: none
Pass clear: left
Pass clear: right
Pass clear: both
Pass clear: inherit
Fail clip: rect(1em, auto, 0.5px, 2000em)
Pass clip: auto
Pass clip: inherit
Pass color: black
Pass color: red
Pass color: rgb(50, 75, 100)
Fail color: rgba(5, 7, 10, 0.5)
Pass color: inherit
Pass content: normal
Pass content: none
Pass content: "string"
Pass content: 'string'
Fail content: url("http://localhost/")
Fail content: url(http://localhost/)
Fail content: counter(par-num)
Fail content: counter(par-num, decimal)
Fail content: counter(par-num, upper-roman)
Pass content: attr(foo-bar)
Pass content: attr(foo_bar)
Fail content: attr(|bar)
Fail content: attr( |bar )
Pass content: attr(foo-bar, "fallback")
Pass content: attr(foo_bar, "fallback")
Fail content: attr(|bar, "fallback")
Fail content: attr(foo, "")
Fail content: attr( |foo , "" )
Pass content: inherit
Pass cursor: auto
Pass cursor: crosshair
Pass cursor: default
Pass cursor: pointer
Pass cursor: move
Pass cursor: e-resize
Pass cursor: ne-resize
Pass cursor: nw-resize
Pass cursor: n-resize
Pass cursor: se-resize
Pass cursor: sw-resize
Pass cursor: s-resize
Pass cursor: w-resize
Pass cursor: text
Pass cursor: wait
Pass cursor: help
Pass cursor: progress
Pass cursor: inherit
Pass direction: ltr
Pass direction: rtl
Pass direction: inherit
Pass display: inline
Pass display: block
Pass display: list-item
Pass display: inline-block
Pass display: table
Pass display: inline-table
Pass display: table-row-group
Pass display: table-header-group
Pass display: table-footer-group
Pass display: table-row
Pass display: table-column-group
Pass display: table-column
Pass display: table-cell
Pass display: table-caption
Pass display: none
Pass display: inherit
Fail empty-cells: show
Fail empty-cells: hide
Fail empty-cells: inherit
Pass float: left
Pass float: right
Pass float: none
Pass float: inherit
Pass font-family: Arial
Pass font-family: 'Lucida Grande'
Pass font-family: serif
Pass font-family: sans-serif
Pass font-family: inherit
Pass font-size: xx-small
Pass font-size: x-small
Pass font-size: small
Pass font-size: medium
Pass font-size: large
Pass font-size: x-large
Pass font-size: xx-large
Pass font-size: larger
Pass font-size: smaller
Pass font-size: 0px
Pass font-size: 1px
Pass font-size: .1em
Pass font-size: 5%
Pass font-size: .5%
Pass font-size: inherit
Pass font-style: normal
Pass font-style: italic
Pass font-style: oblique
Pass font-style: inherit
Pass font-variant: normal
Pass font-variant: small-caps
Pass font-variant: inherit
Pass font-weight: normal
Pass font-weight: bold
Pass font-weight: bolder
Pass font-weight: lighter
Pass font-weight: 100
Pass font-weight: 200
Pass font-weight: 300
Pass font-weight: 400
Pass font-weight: 500
Pass font-weight: 600
Pass font-weight: 700
Pass font-weight: 800
Pass font-weight: 900
Pass font-weight: inherit
Pass height: 0px
Pass height: 1px
Pass height: .1em
Pass height: 5%
Pass height: .5%
Pass height: auto
Pass height: inherit
Pass left: 0px
Pass left: 1px
Pass left: .1em
Pass left: 5%
Pass left: .5%
Pass left: auto
Pass left: inherit
Pass letter-spacing: normal
Pass letter-spacing: 0px
Pass letter-spacing: 1px
Pass letter-spacing: .1em
Pass letter-spacing: inherit
Pass line-height: normal
Pass line-height: 0
Pass line-height: -0
Pass line-height: 1000
Pass line-height: 0.9
Pass line-height: 0px
Pass line-height: 1px
Pass line-height: .1em
Pass line-height: 5%
Pass line-height: .5%
Pass line-height: inherit
Pass list-style-image: url("http://localhost/")
Pass list-style-image: url(http://localhost/)
Pass list-style-image: none
Pass list-style-image: inherit
Pass list-style-position: inside
Pass list-style-position: outside
Pass list-style-position: inherit
Pass list-style-type: disc
Pass list-style-type: circle
Pass list-style-type: square
Pass list-style-type: disclosure-open
Pass list-style-type: disclosure-closed
Pass list-style-type: decimal
Pass list-style-type: decimal-leading-zero
Pass list-style-type: lower-roman
Pass list-style-type: upper-roman
Fail list-style-type: lower-greek
Pass list-style-type: lower-latin
Pass list-style-type: upper-latin
Fail list-style-type: armenian
Fail list-style-type: georgian
Pass list-style-type: lower-alpha
Pass list-style-type: upper-alpha
Pass list-style-type: none
Pass list-style-type: inherit
Pass margin-right: 0px
Pass margin-right: 1px
Pass margin-right: .1em
Pass margin-right: 5%
Pass margin-right: .5%
Pass margin-right: auto
Pass margin-right: inherit
Pass margin-left: 0px
Pass margin-left: 1px
Pass margin-left: .1em
Pass margin-left: 5%
Pass margin-left: .5%
Pass margin-left: auto
Pass margin-left: inherit
Pass margin-top: 0px
Pass margin-top: 1px
Pass margin-top: .1em
Pass margin-top: 5%
Pass margin-top: .5%
Pass margin-top: auto
Pass margin-top: inherit
Pass margin-bottom: 0px
Pass margin-bottom: 1px
Pass margin-bottom: .1em
Pass margin-bottom: 5%
Pass margin-bottom: .5%
Pass margin-bottom: auto
Pass margin-bottom: inherit
Pass max-height: 0px
Pass max-height: 1px
Pass max-height: .1em
Pass max-height: 5%
Pass max-height: .5%
Pass max-height: none
Pass max-height: inherit
Pass max-width: 0px
Pass max-width: 1px
Pass max-width: .1em
Pass max-width: 5%
Pass max-width: .5%
Pass max-width: none
Pass max-width: inherit
Pass min-height: 0px
Pass min-height: 1px
Pass min-height: .1em
Pass min-height: 5%
Pass min-height: .5%
Pass min-height: inherit
Pass min-width: 0px
Pass min-width: 1px
Pass min-width: .1em
Pass min-width: 5%
Pass min-width: .5%
Pass min-width: inherit
Fail orphans: 101
Fail orphans: inherit
Pass outline-color: black
Pass outline-color: red
Pass outline-color: rgb(50, 75, 100)
Fail outline-color: rgba(5, 7, 10, 0.5)
Fail outline-color: invert
Pass outline-color: inherit
Pass outline-style: none
Pass outline-style: dotted
Pass outline-style: dashed
Pass outline-style: solid
Pass outline-style: double
Pass outline-style: groove
Pass outline-style: ridge
Pass outline-style: inset
Pass outline-style: outset
Pass outline-style: inherit
Pass outline-width: thin
Pass outline-width: medium
Pass outline-width: thick
Pass outline-width: 0px
Pass outline-width: 1px
Pass outline-width: .1em
Pass outline-width: inherit
Fail overflow: visible
Fail overflow: hidden
Fail overflow: scroll
Fail overflow: auto
Fail overflow: inherit
Pass padding-top: 0px
Pass padding-top: 1px
Pass padding-top: .1em
Pass padding-top: 5%
Pass padding-top: .5%
Pass padding-top: inherit
Pass padding-right: 0px
Pass padding-right: 1px
Pass padding-right: .1em
Pass padding-right: 5%
Pass padding-right: .5%
Pass padding-right: inherit
Pass padding-bottom: 0px
Pass padding-bottom: 1px
Pass padding-bottom: .1em
Pass padding-bottom: 5%
Pass padding-bottom: .5%
Pass padding-bottom: inherit
Pass padding-left: 0px
Pass padding-left: 1px
Pass padding-left: .1em
Pass padding-left: 5%
Pass padding-left: .5%
Pass padding-left: inherit
Fail page-break-after: auto
Fail page-break-after: always
Fail page-break-after: avoid
Fail page-break-after: left
Fail page-break-after: right
Fail page-break-after: inherit
Fail page-break-before: auto
Fail page-break-before: always
Fail page-break-before: avoid
Fail page-break-before: left
Fail page-break-before: right
Fail page-break-before: inherit
Fail page-break-inside: avoid
Fail page-break-inside: auto
Fail page-break-inside: inherit
Pass position: static
Pass position: relative
Pass position: absolute
Pass position: fixed
Pass position: inherit
Pass right: 0px
Pass right: 1px
Pass right: .1em
Pass right: 5%
Pass right: .5%
Pass right: auto
Pass right: inherit
Pass table-layout: auto
Pass table-layout: fixed
Pass table-layout: inherit
Pass text-align: left
Pass text-align: right
Pass text-align: center
Pass text-align: justify
Pass text-align: inherit
Fail text-decoration: none
Fail text-decoration: underline
Fail text-decoration: overline
Fail text-decoration: line-through
Fail text-decoration: blink
Fail text-decoration: inherit
Pass text-indent: 0px
Pass text-indent: 1px
Pass text-indent: .1em
Pass text-indent: 5%
Pass text-indent: .5%
Pass text-indent: inherit
Pass text-transform: capitalize
Pass text-transform: uppercase
Pass text-transform: lowercase
Pass text-transform: none
Pass text-transform: inherit
Pass top: 0px
Pass top: 1px
Pass top: .1em
Pass top: 5%
Pass top: .5%
Pass top: auto
Pass top: inherit
Pass unicode-bidi: normal
Pass unicode-bidi: embed
Pass unicode-bidi: bidi-override
Pass unicode-bidi: inherit
Pass vertical-align: baseline
Pass vertical-align: sub
Pass vertical-align: super
Pass vertical-align: top
Pass vertical-align: text-top
Pass vertical-align: middle
Pass vertical-align: bottom
Pass vertical-align: text-bottom
Pass vertical-align: 5%
Pass vertical-align: .5%
Pass vertical-align: 0px
Pass vertical-align: 1px
Pass vertical-align: .1em
Pass vertical-align: inherit
Pass visibility: visible
Pass visibility: hidden
Pass visibility: collapse
Pass visibility: inherit
Pass white-space: normal
Pass white-space: pre
Pass white-space: nowrap
Pass white-space: pre-wrap
Pass white-space: pre-line
Pass white-space: inherit
Fail widows: 101
Fail widows: inherit
Pass width: 0px
Pass width: 1px
Pass width: .1em
Pass width: 5%
Pass width: .5%
Pass width: auto
Pass width: inherit
Pass word-spacing: normal
Pass word-spacing: 0px
Pass word-spacing: 1px
Pass word-spacing: .1em
Pass word-spacing: inherit
Pass z-index: auto
Pass z-index: 0
Pass z-index: 101
Pass z-index: -51
Pass z-index: inherit

View file

@ -0,0 +1,15 @@
Summary
Harness status: OK
Rerun
Found 4 tests
2 Pass
2 Fail
Details
Result Test Name MessagePass Longhand with variable preserves original serialization: with whitespace
Fail Shorthand with variable preserves original serialization: with whitespace
Pass Longhand with variable preserves original serialization but trims whitespace: without whitespace
Fail Shorthand with variable preserves original serialization but trims whitespace: without whitespace

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 7 tests
3 Pass
4 Fail
Details
Result Test Name MessagePass Shorthand serialization with shorthand and longhands mixed.
Fail Shorthand serialization with just longhands.
Fail Shorthand serialization with variable and variable from other shorthand.
Fail Shorthand serialization after setting
Fail Shorthand serialization with 'initial' value.
Pass Shorthand serialization with 'initial' value, one longhand with important flag.
Pass Shorthand serialization with 'initial' value, longhands set individually, one with important flag.

View file

@ -0,0 +1,31 @@
Summary
Harness status: OK
Rerun
Found 20 tests
2 Pass
18 Fail
Details
Result Test Name MessageFail The serialization of border: 1px; border-top: 1px; should be canonical.
Fail The serialization of border: 1px solid red; should be canonical.
Fail The serialization of border: 1px red; should be canonical.
Fail The serialization of border: red; should be canonical.
Fail The serialization of border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px; border-image: none; should be canonical.
Fail The serialization of border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px; should be canonical.
Fail The serialization of border-top: 1px; border-right: 2px; border-bottom: 3px; border-left: 4px; should be canonical.
Fail The serialization of border: 1px; border-top: 2px; should be canonical.
Fail The serialization of border: 1px; border-top: 1px !important; should be canonical.
Fail The serialization of border: 1px; border-top-color: red; should be canonical.
Fail The serialization of border: solid; border-style: dotted should be canonical.
Fail The serialization of border-width: 1px; should be canonical.
Fail The serialization of overflow-x: scroll; overflow-y: hidden; should be canonical.
Fail The serialization of overflow-x: scroll; overflow-y: scroll; should be canonical.
Fail The serialization of outline-width: 2px; outline-style: dotted; outline-color: blue; should be canonical.
Fail The serialization of margin-top: 1px; margin-right: 2px; margin-bottom: 3px; margin-left: 4px; should be canonical.
Fail The serialization of list-style-type: circle; list-style-position: inside; list-style-image: none; should be canonical.
Pass The serialization of list-style-type: lower-alpha; should be canonical.
Pass The serialization of font-family: sans-serif; line-height: 2em; font-size: 3em; font-style: italic; font-weight: bold; should be canonical.
Fail The serialization of padding-top: 1px; padding-right: 2px; padding-bottom: 3px; padding-left: 4px; should be canonical.

View file

@ -0,0 +1,27 @@
// <generic-family> keywords, as specified in
// https://drafts.csswg.org/css-fonts/#generic-family-value
var kGenericFontFamilyKeywords = [
"serif",
"sans-serif",
"cursive",
"fantasy",
"monospace",
"system-ui",
"emoji",
"math",
"fangsong",
"ui-serif",
"ui-sans-serif",
"ui-monospace",
"ui-rounded",
];
// <family-name> values that had/have web-exposed behavior in some browsers, but
// are not defined in the specification.
var kNonGenericFontFamilyKeywords = [
"NonGenericFontFamilyName",
"-webkit-body",
"-webkit-standard",
"-webkit-pictograph",
"BlinkMacSystemFont",
];

View file

@ -0,0 +1,42 @@
<!doctype html>
<html>
<link rel="author" title="Erik Nordin" href="mailto:enordin@mozilla.com">
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#propdef-border">
<link rel="help" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1594241">
<meta charset="utf-8">
<title>serialization of border shorthand</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style id="target">
.a {
border-width: 1px;
border-style: solid;
border-color: black;
}
.b {
border-width: 1px;
border-style: solid;
border-color: black;
border-image: linear-gradient(white,black);
}
.c {
border: 1px solid black;
}
</style>
<script>
test(function() {
let rule = document.getElementById('target').sheet.cssRules[0];
assert_equals(rule.style.border, "", "border shorthand isn't serialized if border-image longhands are not initial");
}, "Declaration with border longhands is not serialized to a border shorthand declaration.");
test(function() {
let rule = document.getElementById('target').sheet.cssRules[1];
assert_equals(rule.style.border, "", "border shorthand isn't serialized if border-image longhands are not initial");
}, "Declaration with border longhands and border-image is not serialized to a border shorthand declaration.");
test(function() {
let rule = document.getElementById('target').sheet.cssRules[2];
assert_not_equals(rule.style.border, "", "border shorthand ");
assert_equals(rule.cssText, ".c { border: 1px solid black; }");
}, "Border shorthand is serialized correctly if all border-image-* are set to their initial specified values.");
</script>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM Parsing Test: getting cssText must return the result of serializing the CSS declaration blocks.</title>
<link rel="author" title="Paul Irish" href="mailto:paul.irish@gmail.com">
<link rel="help" href="http://www.w3.org/TR/cssom-1/#the-cssstyledeclaration-interface">
<link rel="source" href="http://trac.webkit.org/export/120528/trunk/LayoutTests/fast/css/cssText-cache.html">
<meta name="flags" content="dom">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<div id="box"></div>
<script>
test(function() {
var style = document.getElementById('box').style;
style.left = "10px";
assert_equals(style.cssText, "left: 10px;");
style.right = "20px";
assert_equals(style.cssText, "left: 10px; right: 20px;");
}, 'CSSStyleDeclaration cssText serializes declaration blocks.');
</script>
</body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - Flex serialization</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-value">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
div { flex: initial; }
div { flex: 0; }
div { flex: initial; flex-basis: initial; flex-shrink: initial; }
div { flex: initial; flex-shrink: 0; }
div { flex: initial; flex-basis: 0; flex-shrink: 2;}
</style>
<script>
var styleSheet = document.styleSheets[0]
test(function () {
assert_equals(styleSheet.cssRules[0].style.cssText, "flex: initial;")
}, "Single value flex with CSS-wide keyword should serialize correctly.")
test(function () {
assert_in_array(styleSheet.cssRules[1].style.cssText, ["flex: 0px;", "flex: 0 1 0px;"])
}, "Single value flex with non-CSS-wide value should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[2].style.cssText, "flex: initial;")
}, "Multiple values flex with CSS-wide keyword should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[3].style.cssText, "flex-grow: initial; flex-basis: initial; flex-shrink: 0;")
}, "Multiple values flex with CSS-wide keywords and non-CSS-wide value should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[4].style.cssText, "flex-grow: initial; flex-basis: 0px; flex-shrink: 2;")
}, "Multiple values flex with CSS-wide and two non-CSS-wide-keyword values should serialize correctly.")
</script>
</head>
</html>

View file

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
<title>Serialization of font-family</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block">
<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-family-prop">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../css/css-fonts/support/font-family-keywords.js"></script>
<div id="target"></div>
<script>
function SetFontFamilyAndSerialize(fontFamilyValue) {
var target = document.getElementById('target');
target.setAttribute("style", `font-family: ${fontFamilyValue}`);
return window.getComputedStyle(target).getPropertyValue('font-family');
}
test(function() {
kGenericFontFamilyKeywords.forEach(keyword => {
assert_equals(SetFontFamilyAndSerialize(keyword), keyword);
});
}, "Serialization of <generic-family>");
test(function() {
kGenericFontFamilyKeywords.forEach(keyword => {
var quoted_keyword = `"${keyword}"`;
assert_equals(SetFontFamilyAndSerialize(quoted_keyword), quoted_keyword);
});
}, "Serialization of quoted \"<generic-family>\"");
test(function() {
kGenericFontFamilyKeywords.forEach(keyword => {
var prefixed_keyword = `-webkit-${keyword}`;
assert_equals(SetFontFamilyAndSerialize(prefixed_keyword), prefixed_keyword);
});
}, "Serialization of prefixed -webkit-<generic-family>");
test(function() {
kNonGenericFontFamilyKeywords.forEach(keyword => {
assert_equals(SetFontFamilyAndSerialize(keyword), keyword);
});
}, `Serialization of ${kNonGenericFontFamilyKeywords}`);
</script>
</html>

View file

@ -0,0 +1,17 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Serialization of font shorthand</title>
<link rel="help" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<link rel="stylesheet" type="text/css" href="../../fonts/ahem.css" />
<div id="target" style="font: 10px/1 Ahem;"></div>
<script>
test(function() {
var target = document.getElementById('target');
assert_equals(target.style.cssText, 'font: 10px / 1 Ahem;');
assert_equals(target.style.font, '10px / 1 Ahem');
}, "The font shorthand should be serialized just like any other shorthand.");
</script>
</html>

View file

@ -0,0 +1,131 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Serialization of font-variant shorthand</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<link rel="stylesheet" type="text/css" href="../../fonts/ahem.css" />
<div id="target"></div>
<script>
const cssWideKeywords = ["initial", "inherit", "unset", "revert", "revert-layer"];
function test_serialization_set(expected) {
for (const [property, value] of Object.entries(expected)) {
if (!CSS.supports(`${property}: initial`))
continue;
assert_equals(target.style[property], value, `${property} was set`);
}
}
function setWithValue(value) {
return {
"font-variant-ligatures": value,
"font-variant-caps": value,
"font-variant-alternates": value,
"font-variant-numeric": value,
"font-variant-east-asian": value,
"font-variant-position": value,
"font-variant-emoji": value,
"font-variant": value
};
}
const emptySet = setWithValue("");
const normalSet = setWithValue("normal");
const nonDefaultValues = {
"font-variant-ligatures": "common-ligatures discretionary-ligatures",
"font-variant-caps": "small-caps",
"font-variant-alternates": "historical-forms",
"font-variant-numeric": "oldstyle-nums stacked-fractions",
"font-variant-east-asian": "ruby",
"font-variant-position": "sub",
"font-variant-emoji": "emoji",
};
test(function(t) {
target.style.fontVariant = "normal";
t.add_cleanup(() => target.removeAttribute("style"));
test_serialization_set(normalSet);
}, "font-variant: normal serialization");
test(function(t) {
target.style.fontVariant = "normal";
target.style.fontVariantLigatures = "none";
t.add_cleanup(() => target.removeAttribute("style"));
const expected = Object.assign({}, normalSet);
expected["font-variant-ligatures"] = "none";
expected["font-variant"] = "none";
test_serialization_set(expected);
}, "font-variant: none serialization");
test(function(t) {
t.add_cleanup(() => target.removeAttribute("style"));
for (const [property, value] of Object.entries(nonDefaultValues)) {
if (property == "font-variant-ligatures" || !CSS.supports(`${property}: initial`))
continue;
target.style.fontVariant = "normal";
target.style.fontVariantLigatures = "none";
target.style[property] = value;
const expected = Object.assign({}, normalSet);
expected["font-variant-ligatures"] = "none";
expected["font-variant"] = "";
expected[property] = value;
test_serialization_set(expected);
target.removeAttribute("style");
}
}, "font-variant-ligatures: none serialization with non-default value for another longhand");
test(function(t) {
t.add_cleanup(() => target.removeAttribute("style"));
for (const [property, value] of Object.entries(nonDefaultValues)) {
if (!CSS.supports(`${property}: initial`))
continue;
target.style.fontVariant = "normal";
target.style[property] = value;
const expected = Object.assign({}, normalSet);
expected[property] = value;
expected["font-variant"] = value;
test_serialization_set(expected);
target.removeAttribute("style");
}
}, "font-variant: normal with non-default longhands");
test(function(t) {
t.add_cleanup(() => target.removeAttribute("style"));
for (const keyword of cssWideKeywords) {
target.style.fontVariant = "normal";
target.style.fontVariantLigatures = keyword;
const expected = Object.assign({}, normalSet);
expected["font-variant-ligatures"] = keyword;
expected["font-variant"] = "";
test_serialization_set(expected);
target.removeAttribute("style");
}
}, "CSS-wide keyword in one longhand");
test(function(t) {
t.add_cleanup(() => target.removeAttribute("style"));
for (const keyword of cssWideKeywords) {
target.style.fontVariant = keyword;
test_serialization_set(setWithValue(keyword));
target.removeAttribute("style");
}
}, "CSS-wide keyword in shorthand");
test(function(t) {
target.style.fontVariant = "normal";
target.style.font = "menu";
t.add_cleanup(() => target.removeAttribute("style"));
test_serialization_set(emptySet);
}, "font: menu serialization");
</script>
</html>

View file

@ -0,0 +1,61 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - Overflow shorthand serialization</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-value">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
div { overflow: inherit; }
div { overflow: hidden; }
div { overflow-x: initial; overflow-y: initial; }
div { overflow-x: scroll; overflow-y: scroll; }
div { overflow-x: scroll; overflow-y: hidden; }
</style>
<script>
var styleSheet = document.styleSheets[0]
var div = document.createElement('div')
test(function () {
assert_equals(styleSheet.cssRules[0].style.cssText, "overflow: inherit;")
}, "Single value overflow with CSS-wide keyword should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[1].style.cssText, "overflow: hidden;")
}, "Single value overflow with non-CSS-wide keyword should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[2].style.cssText, "overflow: initial;")
}, "Overflow-x/y longhands with same CSS-wide keyword should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[3].style.cssText, "overflow: scroll;")
}, "Overflow-x/y longhands with same non-CSS-wide keyword should serialize correctly.")
test(function () {
assert_equals(styleSheet.cssRules[4].style.cssText, "overflow: scroll hidden;")
}, "Overflow-x/y longhands with different keywords should serialize correctly.")
test(function () {
div.style.overflow = "inherit"
assert_equals(div.style.overflow, "inherit")
}, "Single value overflow on element with CSS-wide keyword should serialize correctly.")
test(function () {
div.style.overflow = "hidden"
assert_equals(div.style.overflow, "hidden")
}, "Single value overflow on element with non-CSS-wide keyword should serialize correctly.")
test(function () {
div.style.overflow = ""
div.style.overflowX = "initial"
div.style.overflowY = "initial"
assert_equals(div.style.overflow, "initial")
}, "Overflow-x/y longhands on element with same CSS-wide keyword should serialize correctly.")
test(function () {
div.style.overflowX = "scroll"
div.style.overflowY = "scroll"
assert_equals(div.style.overflow, "scroll")
}, "Overflow-x/y longhands on element with same non-CSS-wide keyword should serialize correctly.")
test(function () {
div.style.overflowX = "scroll"
div.style.overflowY = "hidden"
assert_equals(div.style.overflow, "scroll hidden")
}, "Overflow-x/y longhands on element with different keywords should serialize correctly.")
</script>
</head>
</html>

View file

@ -0,0 +1,141 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM Test: test serialized selector which is only one simple selector in the sequence of simple selectors</title>
<link rel="author" title="T.Nishitani" href="mailto:lequinharay@gmail.com">
<link rel="reviewer" title="L. David Baron" href="https://dbaron.org/">
<link rel="help" href="https://drafts.csswg.org/cssom-1/#serializing-selectors">
<meta name="flags" content="dom">
<meta charset="utf-8">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style id="teststyles">
</style>
</head>
<body>
<div id="log"></div>
<script>
function assert_selector_serializes_to(source, expected_result) {
var style_element = document.getElementById("teststyles");
style_element.firstChild.data = source + "{ font-size: 1em; }";
var sheet = style_element.sheet;
assert_equals(sheet.cssRules[sheet.cssRules.length - 1].selectorText, expected_result);
}
function run_tests_on_anplusb_selector(source) {
assert_selector_serializes_to(source + '( even )', source + '(2n)');
assert_selector_serializes_to(source + '( odd )', source + '(2n+1)');
assert_selector_serializes_to(source + '( +10 )', source + '(10)');
assert_selector_serializes_to(source + '( -10 )', source + '(-10)');
assert_selector_serializes_to(source + '( +4n )', source + '(4n)');
assert_selector_serializes_to(source + '( -3n )', source + '(-3n)');
assert_selector_serializes_to(source + '( 1n + 5 )', source + '(n+5)');
assert_selector_serializes_to(source + '( -1n + 5 )', source + '(-n+5)');
assert_selector_serializes_to(source + '( -1n - 5 )', source + '(-n-5)');
}
test(function() {
assert_selector_serializes_to(":nth-child( 3n - 0)", ":nth-child(3n)");
assert_selector_serializes_to(":nth-child( 1n - 0)", ":nth-child(n)");
}, ":nth-child serialization produces canonical form");
/* for universal selecter with default namespace */
test(function(){
/* this is single universal selector */
assert_selector_serializes_to('*', '*');
assert_selector_serializes_to(' * ', '*');
}, 'single universal selector shows \'*\' when serialized.')
test(function(){
assert_selector_serializes_to('div', 'div');
assert_selector_serializes_to(' div ', 'div');
}, 'single type (simple) selector in the sequence of simple selectors that is not a universal selector')
test(function(){
assert_selector_serializes_to('.class', '.class');
assert_selector_serializes_to(' .class ', '.class');
}, 'single class (simple) selector in the sequence of simple selectors that is not a universal selector')
test(function(){
assert_selector_serializes_to('#id', '#id');
assert_selector_serializes_to(' #id ', '#id');
}, 'single id (simple) selector in the sequence of simple selectors that is not a universal selector')
test(function(){
assert_selector_serializes_to(':hover', ':hover');
assert_selector_serializes_to(' :hover ', ':hover');
}, 'single pseudo (simple) selector which does not accept arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
assert_selector_serializes_to(':lang(ja)', ':lang(ja)');
assert_selector_serializes_to(':lang( ja )', ':lang(ja)');
assert_selector_serializes_to(':lang( j\\ a )', ':lang(j\\ a)');
}, 'single pseudo (simple) selector "lang" which accepts arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
run_tests_on_anplusb_selector(':nth-child');
}, 'single pseudo (simple) selector "nth-child" which accepts arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
run_tests_on_anplusb_selector(':nth-last-child');
}, 'single pseudo (simple) selector "nth-last-child" which accepts arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
run_tests_on_anplusb_selector(':nth-of-type');
}, 'single pseudo (simple) selector "nth-of-child" which accepts arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
run_tests_on_anplusb_selector(':nth-last-of-type');
}, 'single pseudo (simple) selector ":nth-last-of-type" which accepts arguments in the sequence of simple selectors that is not a universal selector')
test(function(){
assert_selector_serializes_to(' :not( abc ) ', ':not(abc)');
assert_selector_serializes_to(' :not( .head ) ', ':not(.head)');
assert_selector_serializes_to(' :not( #head ) ', ':not(#head)');
assert_selector_serializes_to(' :not( :hover ) ', ':not(:hover)');
}, 'single pseudo (simple) selector ":not" which accepts arguments in the sequence of simple selectors that is not a universal selector')
const escaped_ns_rule = "@namespace ns\\:odd url(ns);";
test(function() {
assert_selector_serializes_to("[ns\\:foo]", "[ns\\:foo]");
}, "escaped character in attribute name");
test(function() {
assert_selector_serializes_to("[\\30zonk]", "[\\30 zonk]");
}, "escaped character as code point in attribute name");
test(function() {
assert_selector_serializes_to("[\\@]", "[\\@]");
}, "escaped character (@) in attribute name");
test(function() {
assert_selector_serializes_to("[*|ns\\:foo]", "[*|ns\\:foo]");
}, "escaped character in attribute name with any namespace");
test(function() {
assert_selector_serializes_to(escaped_ns_rule + "[ns\\:odd|foo]", "[ns\\:odd|foo]");
}, "escaped character in attribute prefix");
test(function() {
assert_selector_serializes_to(escaped_ns_rule + "[ns\\:odd|odd\\:name]", "[ns\\:odd|odd\\:name]");
}, "escaped character in both attribute prefix and name");
test(() => {
assert_selector_serializes_to("\\\\", "\\\\");
}, "escaped character (\\) in element name");
test(() => {
assert_selector_serializes_to("*|\\\\", "\\\\");
}, "escaped character (\\) in element name with any namespace without default");
test(() => {
assert_selector_serializes_to("@namespace 'blah'; *|\\\\", "*|\\\\");
}, "escaped character (\\) in element name with any namespace with default");
test(() => {
assert_selector_serializes_to("|\\\\", "|\\\\");
}, "escaped character (\\) in element name with no namespace");
const element_escaped_ns_rule = "@namespace x\\* 'blah';";
test(() => {
assert_selector_serializes_to(element_escaped_ns_rule + "x\\*|test", "x\\*|test");
}, "escaped character (*) in element prefix");
// TODO: https://github.com/w3c/csswg-drafts/issues/8911
</script>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!doctype html>
<meta charset=utf-8>
<title>cssom - Serialization of CSS declaration with "important" flag</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-declaration">
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<div id="noWhitespace" style="display: inline !important;"></div>
<div id="whitespace" style="background-color: blue !important; color: red ! important;"></div>
<div id="dinamicallyStyle"></div>
<script>
test(function () {
var css_style = document.querySelector('#noWhitespace').style.cssText;
assert_equals(css_style, "display: inline !important;");
}, "Inline style declaration without whitespace between '!' and 'important'.");
test(function () {
var css_style = document.querySelector('#whitespace').style.cssText;
assert_equals(css_style, "background-color: blue !important; color: red !important;");
}, "Inline style declaration with whitespace between '!' and 'important'.");
test(function () {
document.querySelector('#dinamicallyStyle').style.cssText = "color: black !important;";
var css_style = document.querySelector('#dinamicallyStyle').style.cssText;
assert_equals(css_style, "color: black !important;");
}, "Style set dynamically via cssText without whitespace between '!' and 'important'.");
test(function () {
document.querySelector('#dinamicallyStyle').style.cssText = "color: black ! important;";
var css_style = document.querySelector('#dinamicallyStyle').style.cssText;
assert_equals(css_style, "color: black !important;");
}, "Style set dynamically via cssText with whitespace between '!' and 'important'.");
</script>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Serialize all longhands</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" />
<link rel="help" href="https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue">
<meta name="assert" content="Checks that all longhands indexed in a CSSStyleDeclaration can be serialized to a non-empty string when set to their initial value.">
<div id="target"></div>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
function nonSerializableProperties(style) {
const result = [];
assert_greater_than(style.length, 0, "Should have longhands");
for (let property of style) {
if (!style.getPropertyValue(property)) {
result.push(property);
}
}
return result;
}
const target = document.getElementById("target");
target.style.cssText = "all: initial; direction: initial; unicode-bidi: initial;";
test(function() {
const props = nonSerializableProperties(target.style);
assert_array_equals(props, []);
}, "Specified style");
test(function() {
const props = nonSerializableProperties(getComputedStyle(target));
assert_array_equals(props, []);
}, "Computed style");
</script>

View file

@ -0,0 +1,69 @@
<link rel=author title="Tab Atkins-Bittner" href="https://www.xanthir.com/contact/">
<link rel="help" href="https://drafts.csswg.org/css-values/#calc-range">
<body><!doctype html>
<title>Serializing Integers Never Uses Scinot</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<link rel=author title="Tab Atkins-Bittner" href="https://www.xanthir.com/contact/">
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-component-value">
<!--
Per CSSOM, integers always serialize all their digits out.
They never serialize to scinot, regardless of size,
because that makes them stop being an integer.
This applies to custom properties as well.
-->
<body>
<script>
try {
CSS.registerProperty({
name: "--two",
value: "<integer>",
inherits: true,
initial: -1
});
}catch(e){}
testIntLength(4);
testIntLength(6);
testIntLength(8);
testIntLength(12);
// JS starts serializing with scinot at 22 digits...
testIntLength(25);
function testIntLength(len) {
let el = document.body;
const val = "1".repeat(len);
test(()=>{
el.removeAttribute("style");
const nullVal = getComputedStyle(el).zIndex;
el.style.zIndex=val;
assert_not_equals(getComputedStyle(el).zIndex, nullVal)
}, `z-index can take a ${len}-digit integer`);
test(()=>{
el.removeAttribute("style");
el.style.setProperty("--one", val);
assert_equals(getComputedStyle(el).getPropertyValue("--one"), val);
}, `An unregistered custom prop can take a ${len}-digit integer`);
test(()=>{
el.removeAttribute("style");
el.style.setProperty("--two", val);
assert_equals(getComputedStyle(el).getPropertyValue("--two"), val);
}, `An <integer> custom prop can take a ${len}-digit integer`);
test(()=>{
el.removeAttribute("style");
el.style.zIndex = val;
const standardVal = getComputedStyle(el).zIndex;
el.removeAttribute("style");
el.style.setProperty("--three", val);
el.style.zIndex = "var(--three)";
assert_equals(getComputedStyle(el).zIndex, standardVal);
}, `z-index can take a custom property set to a ${len}-digit integer`);
}
</script>

View file

@ -0,0 +1,185 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSSOM - Serialization of CSSMediaRule</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-rule">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
function makeSheet(t) {
var style = document.createElement('style');
document.body.appendChild(style);
t.add_cleanup(function() {
document.body.removeChild(style);
});
return style.sheet;
}
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media {}', 0);
assert_equals(sheet.cssRules.length, 1);
assert_equals(sheet.cssRules[0].cssText, '@media {\n}');
}, 'empty media query list');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media all {}');
sheet.insertRule('@media print {}');
sheet.insertRule('@media screen {}');
sheet.insertRule('@media speech {}');
assert_equals(sheet.cssRules.length, 4);
assert_equals(sheet.cssRules[0].cssText, '@media speech {\n}');
assert_equals(sheet.cssRules[1].cssText, '@media screen {\n}');
assert_equals(sheet.cssRules[2].cssText, '@media print {\n}');
assert_equals(sheet.cssRules[3].cssText, '@media all {\n}');
}, 'type - no features');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media not all {}');
sheet.insertRule('@media not print {}');
sheet.insertRule('@media not screen {}');
sheet.insertRule('@media not speech {}');
assert_equals(sheet.cssRules.length, 4);
assert_equals(sheet.cssRules[0].cssText, '@media not speech {\n}');
assert_equals(sheet.cssRules[1].cssText, '@media not screen {\n}');
assert_equals(sheet.cssRules[2].cssText, '@media not print {\n}');
assert_equals(sheet.cssRules[3].cssText, '@media not all {\n}');
}, 'type - no features - negation');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media aLL {}');
sheet.insertRule('@media pRiNt {}');
sheet.insertRule('@media screEN {}');
sheet.insertRule('@media spEech {}');
assert_equals(sheet.cssRules.length, 4);
assert_equals(sheet.cssRules[0].cssText, '@media speech {\n}');
assert_equals(sheet.cssRules[1].cssText, '@media screen {\n}');
assert_equals(sheet.cssRules[2].cssText, '@media print {\n}');
assert_equals(sheet.cssRules[3].cssText, '@media all {\n}');
}, 'type - no features - character case normalization');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media all and (color) {}');
assert_equals(sheet.cssRules.length, 1);
assert_equals(sheet.cssRules[0].cssText, '@media (color) {\n}');
}, 'type - omission of all');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media not all and (color) {}');
assert_equals(sheet.cssRules.length, 1);
assert_equals(sheet.cssRules[0].cssText, '@media not all and (color) {\n}');
}, 'type - inclusion of negated all');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media screen and (Color) {}');
sheet.insertRule('@media screen and (cOLor) {}');
assert_equals(sheet.cssRules.length, 2);
assert_equals(sheet.cssRules[0].cssText, '@media screen and (color) {\n}');
assert_equals(sheet.cssRules[1].cssText, '@media screen and (color) {\n}');
}, 'features - character case normalization');
/**
* The following test is disabled pending clarification of the intended
* behavior: https://github.com/w3c/csswg-drafts/issues/533
*/
//test(function(t) {
// var sheet = makeSheet(t);
// sheet.insertRule('@media screen and (color) and (color) {}');
//
// assert_equals(sheet.cssRules.length, 1);
// assert_equals(
// sheet.cssRules[0].cssText,
// '@media screen and (color) {\n}'
// );
//}, 'features - de-duplication');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media print and (max-width: 23px) and (max-width: 45px) {}');
assert_equals(sheet.cssRules.length, 1);
assert_equals(
sheet.cssRules[0].cssText,
'@media print and (max-width: 23px) and (max-width: 45px) {\n}'
);
}, 'features - preservation of overspecified features');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media screen and (max-width: 0px) and (color) {}');
sheet.insertRule('@media screen and (color) and (max-width: 0px) {}');
assert_equals(sheet.cssRules.length, 2);
assert_equals(
sheet.cssRules[0].cssText,
'@media screen and (color) and (max-width: 0px) {\n}'
);
assert_equals(
sheet.cssRules[1].cssText,
'@media screen and (max-width: 0px) and (color) {\n}'
);
}, 'features - no lexicographical sorting');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media screen and (max-width: 0px), screen and (color) {}');
assert_equals(sheet.cssRules.length, 1);
assert_equals(
sheet.cssRules[0].cssText,
'@media screen and (max-width: 0px), screen and (color) {\n}'
);
}, 'media query list');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media print {}');
assert_equals(sheet.cssRules.length, 1);
sheet.cssRules[0].insertRule('#foo { z-index: 23; float: left; }', 0);
assert_equals(
sheet.cssRules[0].cssText,
[
'@media print {',
' #foo { z-index: 23; float: left; }',
'}'
].join('\n')
);
}, 'one rule');
test(function(t) {
var sheet = makeSheet(t);
sheet.insertRule('@media print {}');
assert_equals(sheet.cssRules.length, 1);
sheet.cssRules[0].insertRule('#foo { z-index: 23; float: left; }', 0);
sheet.cssRules[0].insertRule('#bar { float: none; z-index: 45; }', 0);
assert_equals(
sheet.cssRules[0].cssText,
[
'@media print {',
' #bar { float: none; z-index: 45; }',
' #foo { z-index: 23; float: left; }',
'}'
].join('\n')
);
}, 'many rules');
</script>
</body>
</html>

View file

@ -0,0 +1,257 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM Test: test serialization of type selectors and namespace prefixes</title>
<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com">
<link rel="help" href="https://drafts.csswg.org/cssom-1/#serializing-selectors">
<meta name="flags" content="dom">
<meta charset="utf-8">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style id="teststyles">
</style>
</head>
<body>
<div id="log"></div>
<script>
var ns_rule = "@namespace ns url(ns);";
var default_ns_rules = "@namespace url(default_ns); @namespace nsdefault url(default_ns);" + ns_rule;
function assert_selector_serializes_to(source, expected_result) {
var style_element = document.getElementById("teststyles");
style_element.firstChild.data = source + "{ font-size: 1em; }";
var sheet = style_element.sheet;
assert_equals(sheet.cssRules[sheet.cssRules.length - 1].selectorText, expected_result);
}
test(function() {
assert_selector_serializes_to(ns_rule + "e", "e");
assert_selector_serializes_to(default_ns_rules + "e", "e");
}, "Simple type selector");
test(function() {
assert_selector_serializes_to(ns_rule + "|e", "|e");
assert_selector_serializes_to(default_ns_rules + "|e", "|e");
}, "Type selector without a namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e", "e");
assert_selector_serializes_to(default_ns_rules + "*|e", "*|e");
}, "Type selector with any namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "*", "*");
assert_selector_serializes_to(default_ns_rules + "*", "*");
}, "Universal selector");
test(function() {
assert_selector_serializes_to(ns_rule + "|*", "|*");
assert_selector_serializes_to(default_ns_rules + "|*", "|*");
}, "Universal selector without a namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*", "*");
assert_selector_serializes_to(default_ns_rules + "*|*", "*|*");
}, "Universal selector in any namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e", "ns|e");
assert_selector_serializes_to(default_ns_rules + "ns|e", "ns|e");
}, "Type selector with namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*", "ns|*");
assert_selector_serializes_to(default_ns_rules + "ns|*", "ns|*");
}, "Universal selector with namespace");
test(function() {
assert_selector_serializes_to(ns_rule + "e.c", "e.c");
assert_selector_serializes_to(default_ns_rules + "e.c", "e.c");
}, "Simple type selector followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "e#i", "e#i");
assert_selector_serializes_to(default_ns_rules + "e#i", "e#i");
}, "Simple type selector followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "e:hover", "e:hover");
assert_selector_serializes_to(default_ns_rules + "e:hover", "e:hover");
}, "Simple type selector followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "e::before", "e::before");
assert_selector_serializes_to(default_ns_rules + "e::before", "e::before");
}, "Simple type selector followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "e[attr]", "e[attr]");
assert_selector_serializes_to(default_ns_rules + "e[attr]", "e[attr]");
}, "Simple type selector followed by atttribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "|e.c", "|e.c");
assert_selector_serializes_to(default_ns_rules + "|e.c", "|e.c");
}, "Type selector without a namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "|e#i", "|e#i");
assert_selector_serializes_to(default_ns_rules + "|e#i", "|e#i");
}, "Type selector without a namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "|e:hover", "|e:hover");
assert_selector_serializes_to(default_ns_rules + "|e:hover", "|e:hover");
}, "Type selector without a namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "|e::before", "|e::before");
assert_selector_serializes_to(default_ns_rules + "|e::before", "|e::before");
}, "Type selector without a namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "|e[attr]", "|e[attr]");
assert_selector_serializes_to(default_ns_rules + "|e[attr]", "|e[attr]");
}, "Type selector without a namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e.c", "e.c");
assert_selector_serializes_to(default_ns_rules + "*|e.c", "*|e.c");
}, "Type selector with any namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e#id", "e#id");
assert_selector_serializes_to(default_ns_rules + "*|e#id", "*|e#id");
}, "Type selector with any namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e:hover", "e:hover");
assert_selector_serializes_to(default_ns_rules + "*|e:hover", "*|e:hover");
}, "Type selector with any namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e::before", "e::before");
assert_selector_serializes_to(default_ns_rules + "*|e::before", "*|e::before");
}, "Type selector with any namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "*|e[attr]", "e[attr]");
assert_selector_serializes_to(default_ns_rules + "*|e[attr]", "*|e[attr]");
}, "Type selector with any namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "*.c", ".c");
assert_selector_serializes_to(default_ns_rules + "*.c", ".c");
}, "Universal selector followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "*#i", "#i");
assert_selector_serializes_to(default_ns_rules + "*#i", "#i");
}, "Universal selector followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "*:hover", ":hover");
assert_selector_serializes_to(default_ns_rules + "*:hover", ":hover");
}, "Universal selector followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "*::before", "::before");
assert_selector_serializes_to(default_ns_rules + "*::before", "::before");
}, "Universal selector followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "*[attr]", "[attr]");
assert_selector_serializes_to(default_ns_rules + "*[attr]", "[attr]");
}, "Universal selector followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "|*.c", "|*.c");
assert_selector_serializes_to(default_ns_rules + "|*.c", "|*.c");
}, "Universal selector without a namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "|*#i", "|*#i");
assert_selector_serializes_to(default_ns_rules + "|*#i", "|*#i");
}, "Universal selector without a namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "|*:hover", "|*:hover");
assert_selector_serializes_to(default_ns_rules + "|*:hover", "|*:hover");
}, "Universal selector without a namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "|*::before", "|*::before");
assert_selector_serializes_to(default_ns_rules + "|*::before", "|*::before");
}, "Universal selector without a namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "|*[attr]", "|*[attr]");
assert_selector_serializes_to(default_ns_rules + "|*[attr]", "|*[attr]");
}, "Universal selector without a namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*.c", ".c");
assert_selector_serializes_to(default_ns_rules + "*|*.c", "*|*.c");
}, "Universal selector in any namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*#id", "#id");
assert_selector_serializes_to(default_ns_rules + "*|*#id", "*|*#id");
}, "Universal selector in any namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*:hover", ":hover");
assert_selector_serializes_to(default_ns_rules + "*|*:hover", "*|*:hover");
}, "Universal selector in any namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*::before", "::before");
assert_selector_serializes_to(default_ns_rules + "*|*::before", "*|*::before");
}, "Universal selector in any namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "*|*[attr]", "[attr]");
assert_selector_serializes_to(default_ns_rules + "*|*[attr]", "*|*[attr]");
}, "Universal selector in any namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e.c", "ns|e.c");
assert_selector_serializes_to(default_ns_rules + "ns|e.c", "ns|e.c");
}, "Type selector with namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e#i", "ns|e#i");
assert_selector_serializes_to(default_ns_rules + "ns|e#i", "ns|e#i");
}, "Type selector with namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e:hover", "ns|e:hover");
assert_selector_serializes_to(default_ns_rules + "ns|e:hover", "ns|e:hover");
}, "Type selector with namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e::before", "ns|e::before");
assert_selector_serializes_to(default_ns_rules + "ns|e::before", "ns|e::before");
}, "Type selector with namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|e[attr]", "ns|e[attr]");
assert_selector_serializes_to(default_ns_rules + "ns|e[attr]", "ns|e[attr]");
}, "Type selector with namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*.c", "ns|*.c");
assert_selector_serializes_to(default_ns_rules + "ns|*.c", "ns|*.c");
}, "Universal selector with namespace followed by class");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*#i", "ns|*#i");
assert_selector_serializes_to(default_ns_rules + "ns|*#i", "ns|*#i");
}, "Universal selector with namespace followed by id");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*:hover", "ns|*:hover");
assert_selector_serializes_to(default_ns_rules + "ns|*:hover", "ns|*:hover");
}, "Universal selector with namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*::before", "ns|*::before");
assert_selector_serializes_to(default_ns_rules + "ns|*::before", "ns|*::before");
}, "Universal selector with namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(ns_rule + "ns|*[attr]", "ns|*[attr]");
assert_selector_serializes_to(default_ns_rules + "ns|*[attr]", "ns|*[attr]");
}, "Universal selector with namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e", "e");
}, "Type selector with namespace equal to default namespace");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*", "*");
}, "Universal selector with namespace equal to default namespace");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e.c", "e.c");
}, "Type selector with namespace equal to default namespace followed by class");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e#i", "e#i");
}, "Type selector with namespace equal to default namespace followed by id");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e:hover", "e:hover");
}, "Type selector with namespace equal to default namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e::before", "e::before");
}, "Type selector with namespace equal to default namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|e[attr]", "e[attr]");
}, "Type selector with namespace equal to default namespace followed by attribute selector");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*.c", ".c");
}, "Universal selector with namespace equal to default namespace followed by class");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*#i", "#i");
}, "Universal selector with namespace equal to default namespace followed by id");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*:hover", ":hover");
}, "Universal selector with namespace equal to default namespace followed by pseudo class");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*::before", "::before");
}, "Universal selector with namespace equal to default namespace followed by pseudo element");
test(function() {
assert_selector_serializes_to(default_ns_rules + "nsdefault|*[attr]", "[attr]");
}, "Universal selector with namespace equal to default namespace followed by attribute selector");
</script>
</body>
</html>

View file

@ -0,0 +1,614 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSSOM serialize values</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serializing-css-values">
<meta name="author" title="Josh Matthews" href="mailto:josh@joshmatthews.net">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<div id="log"></div>
<div id="parent"></div>
<script>
function iterable(values) {
var i = 0;
return function() {
if (i < values.length) {
return values[i++];
}
return null;
}
}
function color() {
var colors = ['black', 'red', 'rgb(50, 75, 100)', 'rgba(5, 7, 10, 0.5)'];
return iterable(colors);
}
function percentage() {
var values = ["5%", {actual: ".5%", serialized: "0.5%"}];
return iterable(values);
}
function negative_percentage() {
var values = ["-5%", {actual: "-.5%", serialized: "-0.5%"}];
return iterable(values);
}
function length() {
var values = ["0px", "1px", {actual: ".1em", serialized: "0.1em"}];
return iterable(values);
}
function negative_length() {
var values = [{actual: "-0px", serialized: "0px"},
"-1px", {actual: "-.1em", serialized: "-0.1em"}];
return iterable(values);
}
function degree() {
var values = ["87deg"];
return iterable(values);
}
function uri() {
var values = ["url(\"http://localhost/\")",
{actual: "url(http://localhost/)",
serialized: "url(\"http://localhost/\")"}];
return iterable(values);
}
function border_style() {
var values = ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge',
'inset', 'outset'];
return iterable(values);
}
function border_style_without_hidden() {
var values = ['none', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge',
'inset', 'outset'];
return iterable(values);
}
function integer() {
var values = ['0', '101', '-51'];
return iterable(values);
}
function nonzero_positive_integer() {
var values = ['101'];
return iterable(values);
}
function shape() {
var values = ['rect(1em, auto, 0.5px, 2000em)'];
return iterable(values);
}
function string() {
var values = ['"string"', {actual: "'string'", serialized: '"string"'}];
return iterable(values);
}
function counter() {
var values = ['counter(par-num)',
{ actual: 'counter(par-num, decimal)', serialized: 'counter(par-num)' },
'counter(par-num, upper-roman)'];
return iterable(values);
}
function attr() {
var values = ['attr(foo-bar)', 'attr(foo_bar)',
{actual: "attr(|bar)", serialized: "attr(bar)"},
{actual: "attr( |bar )", serialized: "attr(bar)"}];
return iterable(values);
}
function attr_fallback() {
var values = ['attr(foo-bar, "fallback")', 'attr(foo_bar, "fallback")',
{actual: 'attr(|bar, "fallback")', serialized: 'attr(bar, "fallback")'},
{actual: 'attr(foo, "")', serialized: 'attr(foo)'},
{actual: 'attr( |foo , "" )', serialized: 'attr(foo)'}];
return iterable(values);
}
function family_name() {
var values = ['Arial', {actual: "'Lucida Grande'", serialized: '"Lucida Grande"'}];
return iterable(values);
}
function generic_family() {
var values = ['serif', 'sans-serif'];
return iterable(values);
}
function absolute_size() {
var values = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
return iterable(values);
}
function relative_size() {
var values = ['larger', 'smaller'];
return iterable(values);
}
function number() {
var values = ['0', {'actual': '-0', serialized: '0'}, '1000', '-5123', '0.9', '-0.09'];
return iterable(values);
}
function positive_number() {
var values = ['0', {'actual': '-0', serialized: '0'}, '1000', '0.9'];
return iterable(values);
}
function generate_inline_style(name, value) {
if (value) {
return {'declaration': name + ": " + value.actual,
'value': value.actual,
'result': value.expected};
}
return null;
}
var minimal_results = {
};
function create_result(propertyName, actual, expected) {
var key = propertyName + ": " + expected
if (key in minimal_results)
expected = minimal_results[key]
return {actual: actual, expected: expected}
}
function all_values(propertyName, values) {
var results = [];
for (var i = 0; i < values.length; i++) {
var value = values[i];
if (typeof value == "function") {
var f = value();
var result;
while ((result = f()) != null) {
if (typeof result == "object" && 'serialized' in result) {
results.push(create_result(propertyName, result.actual, result.serialized));
} else {
results.push(create_result(propertyName, result, result));
}
}
} else if (typeof value == "string") {
results.push(create_result(propertyName, value, value));
} else if (value instanceof Array) {
var subresults = [];
for (var j = 0; j < value.length; j++) {
var subresult = all_values(propertyName, value[j]);
if (!(subresult instanceof Array)) {
subresult = [subresult];
}
subresults.push(subresult);
}
if (subresults.length > 1) {
function choose_slices(vecs) {
if (vecs.length == 1) {
return vecs[0].map(function(v) { return [v]; });
}
var slice_results = [];
var rest = choose_slices(vecs.slice(1, vecs.length));
for (var a = 0; a < vecs[0].length; a++) {
for (var b = 0; b < rest.length; b++) {
var result = vecs[0][a];
slice_results.push([result].concat(rest[b]));
}
}
return slice_results;
}
subresults = choose_slices(subresults).map(function (a) {
var actual = a.map(function(a) { return a.actual });
var expected = a.map(function(a) { return a.expected });
return create_result(propertyName, actual.join(' '), expected.join(' '))
});
}
for (var j = 0; j < subresults.length; j++) {
results = results.concat(subresults[j]);
}
} else if (value instanceof Object && 'serialized' in value) {
results.push(create_result(propertyName, value.actual, value.serialized));
} else if (typeof value == "number") {
results.push(create_result(propertyName, value.toString(), value.toString()));
} else {
throw "unexpected value type: " + typeof(value);
}
}
return results;
}
function create_value_generator(propertyName, property) {
var results = all_values(propertyName, property.values);
return iterable(results);
}
function to_idl(property) {
return property.replace(/-\w/g, function(x){return x[1].toUpperCase()});
}
function run_individual_test(property, generator, initial) {
var elem = document.createElement('div');
document.getElementById('parent').appendChild(elem);
var test_data = generator();
var style = generate_inline_style(property, test_data);
if (!style) {
return false;
}
var t = async_test(style.declaration);
t.add_cleanup(function() {
document.getElementById('parent').removeChild(elem);
});
t.step(function() {
elem.setAttribute('style', style.declaration);
var expected = style.result;
var serialized = elem.style[to_idl(property)];
assert_equals(serialized, expected, property + ' raw inline style declaration');
elem.setAttribute('style', '');
elem.style[to_idl(property)] = style.value;
assert_equals(elem.style[to_idl(property)], expected, property + ' style property');
});
t.done();
return true;
}
function test_property(property) {
var generator = create_value_generator(property[0], property[1]);
while (run_individual_test(property[0], generator, property[1].initial)) {
}
}
var properties = [
['background-attachment', {
'values': ['scroll', 'fixed', 'inherit'],
'initial': 'scroll',
}],
['background-color', {
'values': [color, 'transparent', 'inherit'],
'initial': 'transparent',
}],
['background-image', {
'values': [uri, 'none', 'inherit'],
'initial': 'none',
}],
['background-position', {
'values': [[[percentage, negative_percentage, length, negative_length,
'left', 'center', 'right'],
[percentage, negative_percentage, length, negative_length,
'top', 'center', 'bottom']],
'inherit'],
'initial': '0% 0%',
}],
['background-repeat', {
'values': ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'inherit'],
'initial': 'repeat',
}],
//background
['border-collapse', {
'values': ['collapse', 'separate', 'inherit'],
'initial': 'separate',
}],
//border-color
['border-spacing', {
'values': [length, 'inherit'],
'initial': '0',
}],
//border-style
//border-top, border-right, border-bottom, border-left
['border-top-color', {
'values': [color, 'transparent', 'inherit'],
'initial': 'black', //FIXME
}],
['border-right-color', {
'values': [color, 'transparent', 'inherit'],
'initial': 'black', //FIXME
}],
['border-bottom-color', {
'values': [color, 'transparent', 'inherit'],
'initial': 'black', //FIXME
}],
['border-left-color', {
'values': [color, 'transparent', 'inherit'],
'initial': 'black', //FIXME
}],
['border-top-style', {
'values': [border_style, 'inherit'],
'initial': null,
}],
['border-right-style', {
'values': [border_style, 'inherit'],
'initial': null,
}],
['border-bottom-style', {
'values': [border_style, 'inherit'],
'initial': null,
}],
['border-left-style', {
'values': [border_style, 'inherit'],
'initial': null,
}],
['border-top-width', {
'values': ['thin', 'medium', 'thick', length, 'inherit'],
'initial': 'medium',
}],
['border-right-width', {
'values': ['thin', 'medium', 'thick', length, 'inherit'],
'initial': 'medium',
}],
['border-bottom-width', {
'values': ['thin', 'medium', 'thick', length, 'inherit'],
'initial': 'medium',
}],
['border-left-width', {
'values': ['thin', 'medium', 'thick', length, 'inherit'],
'initial': 'medium',
}],
//border-width
//border
['bottom', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['caption-side', {
'values': ['top', 'bottom', 'inherit'],
'initial': 'top',
}],
['clear', {
'values': ['none', 'left', 'right', 'both', 'inherit'],
'initial': 'none',
}],
['clip', {
'values': [shape, 'auto', 'inherit'],
'initial': 'auto',
}],
['color', {
'values': [color, 'inherit'],
'initial': 'black', //FIXME depends on user agent
}],
['content', {
'values': ['normal', 'none', string, uri, counter, attr, attr_fallback, 'inherit'], //FIXME
'initial': 'normal',
}],
//counter-increment
//counter-reset
['cursor', {
'values': [ 'auto', 'crosshair', 'default', 'pointer', 'move', 'e-resize', 'ne-resize',
'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize',
'text', 'wait', 'help', 'progress', 'inherit'],
'initial': 'auto',
}],
['direction', {
'values': ['ltr', 'rtl', 'inherit'],
'initial': 'ltr',
}],
['display', {
'values': ['inline', 'block', 'list-item', 'inline-block', 'table', 'inline-table',
'table-row-group', 'table-header-group', 'table-footer-group', 'table-row',
'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none',
'inherit'],
'initial': 'inline',
}],
['empty-cells', {
'values': ['show', 'hide', 'inherit'],
'initial': 'show',
}],
['float', {
'values': ['left', 'right', 'none', 'inherit'],
'initial': 'none',
'property': 'cssFloat',
}],
['font-family', {
'values': [family_name, generic_family, 'inherit'],
'initial': 'sans-serif', //FIXME depends on user agent
}],
['font-size', {
'values': [absolute_size, relative_size, length, percentage, 'inherit'],
'initial': 'medium',
}],
['font-style', {
'values': ['normal', 'italic', 'oblique', 'inherit'],
'initial': 'normal',
}],
['font-variant', {
'values': ['normal', 'small-caps', 'inherit'],
'initial': 'normal',
}],
['font-weight', {
'values': ['normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600,
700, 800, 900, 'inherit'],
'initial': 'normal',
}],
//font
['height', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['left', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['letter-spacing', {
'values': ['normal', length, 'inherit'],
'initial': 'normal',
}],
['line-height', {
'values': ['normal', positive_number, length, percentage, 'inherit'],
'initial': 'normal',
}],
['list-style-image', {
'values': [uri, 'none', 'inherit'],
'initial': 'none',
}],
['list-style-position', {
'values': ['inside', 'outside', 'inherit'],
'initial': 'outside',
}],
['list-style-type', {
'values': ['disc', 'circle', 'square', 'disclosure-open', 'disclosure-closed',
'decimal', 'decimal-leading-zero', 'lower-roman',
'upper-roman', 'lower-greek', 'lower-latin', 'upper-latin', 'armenian', 'georgian',
'lower-alpha', 'upper-alpha', 'none', 'inherit'],
'initial': 'disc',
}],
//list-style
['margin-right', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 0,
}],
['margin-left', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 0,
}],
['margin-top', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 0,
}],
['margin-bottom', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 0,
}],
//margin
['max-height', {
'values': [length, percentage, 'none', 'inherit'],
'initial': 'none',
}],
['max-width', {
'values': [length, percentage, 'none', 'inherit'],
'initial': 'none',
}],
['min-height', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['min-width', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['orphans', {
'values': [nonzero_positive_integer, 'inherit'],
'initial': 2,
}],
['outline-color', {
'values': [color, 'invert', 'inherit'],
'initial': 'invert',
}],
['outline-style', {
'values': [border_style_without_hidden, 'inherit'],
'initial': 'none',
}],
['outline-width', {
'values': ['thin', 'medium', 'thick', length, 'inherit'],
'initial': 'medium',
}],
//outline
['overflow', {
'values': ['visible', 'hidden', 'scroll', 'auto', 'inherit'],
'initial': 'visible',
}],
['padding-top', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['padding-right', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['padding-bottom', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['padding-left', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
//padding
['page-break-after', {
'values': ['auto', 'always', 'avoid', 'left', 'right', 'inherit'],
'initial': 'auto',
}],
['page-break-before', {
'values': ['auto', 'always', 'avoid', 'left', 'right', 'inherit'],
'initial': 'auto',
}],
['page-break-inside', {
'values': ['avoid', 'auto', 'inherit'],
'initial': 'auto',
}],
['position', {
'values': ['static', 'relative', 'absolute', 'fixed', 'inherit'],
'initial': 'static',
}],
//FIXME quotes
['right', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['table-layout', {
'values': ['auto', 'fixed', 'inherit'],
'initial': 'auto',
}],
['text-align', {
'values': ['left', 'right', 'center', 'justify', 'inherit'],
'initial': null,
}],
['text-decoration', {
'values': ['none', 'underline', 'overline', 'line-through', 'blink', 'inherit'],
'initial': 'none',
}],
['text-indent', {
'values': [length, percentage, 'inherit'],
'initial': 0,
}],
['text-transform', {
'values': ['capitalize', 'uppercase', 'lowercase', 'none', 'inherit'],
'initial': 'none',
}],
['top', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['unicode-bidi', {
'values': ['normal', 'embed', 'bidi-override', 'inherit'],
'initial': 'normal',
}],
['vertical-align', {
'values': ['baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom',
percentage, length, 'inherit'],
'initial': 'baseline',
}],
['visibility', {
'values': ['visible', 'hidden', 'collapse', 'inherit'],
'initial': 'visible',
}],
['white-space', {
'values': ['normal', 'pre', 'nowrap', 'pre-wrap', 'pre-line', 'inherit'],
'initial': 'normal',
}],
['widows', {
'values': [nonzero_positive_integer, 'inherit'],
'initial': 2,
}],
['width', {
'values': [length, percentage, 'auto', 'inherit'],
'initial': 'auto',
}],
['word-spacing', {
'values': ['normal', length, 'inherit'],
'initial': 'normal',
}],
['z-index', {
'values': ['auto', integer, 'inherit'],
'initial': 'auto',
}],
]
for (var index = 0; index < properties.length; index++) {
test_property(properties[index]);
}
</script>
</body>

View file

@ -0,0 +1,36 @@
<!doctype html>
<meta charset="utf-8">
<title>CSSOM - Serialization with variable preserves original serialization.</title>
<link rel="help" href="https://drafts.csswg.org/css-variables/#serializing-custom-props">
<link rel="help" href="https://drafts.csswg.org/css-variables/#variables-in-shorthands">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="longhand-whitespace" style="font-size: var(--a);"></div>
<div id="shorthand-whitespace" style="font: var(--a);"></div>
<div id="longhand" style="font-size:var(--a);"></div>
<div id="shorthand" style="font:var(--a);"></div>
<script>
test(function() {
var elem = document.getElementById('longhand-whitespace');
assert_equals(elem.style.cssText, 'font-size: var(--a);');
}, 'Longhand with variable preserves original serialization: with whitespace')
test(function() {
var elem = document.getElementById('shorthand-whitespace');
assert_equals(elem.style.cssText, 'font: var(--a);');
}, 'Shorthand with variable preserves original serialization: with whitespace')
test(function() {
var elem = document.getElementById('longhand');
assert_equals(elem.style.cssText, 'font-size: var(--a);');
}, 'Longhand with variable preserves original serialization but trims whitespace: without whitespace')
test(function() {
var elem = document.getElementById('shorthand');
assert_equals(elem.style.cssText, 'font: var(--a);');
}, 'Shorthand with variable preserves original serialization but trims whitespace: without whitespace')
</script>

View file

@ -0,0 +1,86 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Shorthand serialization should be done correctly.</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block">
<link rel="help" href="https://drafts.csswg.org/css-variables/#variables-in-shorthands">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="foo1" style="background: red;">foo</div>
<div id="foo2" style="background-color: blue; background: red !important; background-color: green;">foo</div>
<div id="foo3" style="background-color: blue; background: red; background-color: green !important;">foo</div>
<div id="foo4" style="margin-right: 10px; margin-left: 10px; margin-top: 10px; margin-bottom: 10px;">foo</div>
<div id="foo5" style="margin-right: 10px; margin-left: 10px; margin-top: 10px; margin-bottom: 10px!important;">foo</div>
<div id="foo6" style="margin-right: 10px !important; margin-left: 10px !important; margin-top: 10px !important; margin-bottom: 10px!important;">foo</div>
<div id="foo7" style="background:var(--a);">foo</div>
<div id="test"></div>
<script>
test(function() {
var elem1 = document.getElementById('foo1');
var elem2 = document.getElementById('foo2');
var elem3 = document.getElementById('foo3');
assert_false(elem1.style.cssText.endsWith('!important;'));
assert_true(elem2.style.cssText.endsWith('!important;'));
assert_false(elem3.style.background.endsWith('!important'));
}, "Shorthand serialization with shorthand and longhands mixed.");
test(function() {
var elem4 = document.getElementById('foo4');
var elem5 = document.getElementById('foo5');
var elem6 = document.getElementById('foo6');
assert_equals(elem4.style.cssText, 'margin: 10px;');
assert_equals(elem4.style.margin, '10px');
assert_equals(elem5.style.cssText, 'margin-right: 10px; margin-left: 10px; margin-top: 10px; margin-bottom: 10px !important;');
assert_equals(elem5.style.margin, '');
assert_equals(elem6.style.cssText, 'margin: 10px !important;');
assert_equals(elem6.style.margin, '10px');
}, "Shorthand serialization with just longhands.");
test(function() {
var elem7 = document.getElementById('foo7');
assert_equals(elem7.style.background, 'var(--a)');
assert_equals(elem7.style.backgroundPosition, '');
}, "Shorthand serialization with variable and variable from other shorthand.");
test(function() {
var testElem = document.getElementById("test");
testElem.style.margin = "20px 20px 20px 20px";
assert_equals(testElem.style.margin, "20px");
assert_equals(testElem.style.cssText, "margin: 20px;")
}, "Shorthand serialization after setting");
test(function() {
const testElem = document.getElementById("test");
testElem.style.cssText = "margin: initial;";
assert_equals(testElem.style.margin, "initial");
assert_equals(testElem.style.cssText, "margin: initial;");
}, "Shorthand serialization with 'initial' value.");
test(function() {
const testElem = document.getElementById("test");
testElem.style.setProperty("margin-top", "initial", "important");
assert_equals(testElem.style.margin, "");
}, "Shorthand serialization with 'initial' value, one longhand with important flag.");
test(function() {
const testElem = document.getElementById("test");
testElem.style.cssText = "";
testElem.style.setProperty("margin-top", "initial");
testElem.style.setProperty("margin-right", "initial");
testElem.style.setProperty("margin-bottom", "initial");
testElem.style.setProperty("margin-left", "initial", "important");
assert_equals(testElem.style.margin, "");
}, "Shorthand serialization with 'initial' value, longhands set individually, one with important flag.");
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!doctype html>
<head>
<title>CSS OM: CSS Values</title>
<link rel="author" title="Divya Manian" href="mailto:manian@adobe.com">
<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block">
<meta name="flags" content="dom">
<meta name="assert" content="Testing Serialization of Shorthand Values">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="test"></div>
<script>
function test_shorthand_serialization(value, expected) {
test(function() {
const div = document.getElementById("test");
div.style.cssText = value;
assert_equals(div.style.cssText, expected);
}, "The serialization of " + value + " should be canonical.");
}
var tests = {
// specified -> expected
'border: 1px; border-top: 1px;': 'border: 1px;',
'border: 1px solid red;': 'border: 1px solid red;',
'border: 1px red;': 'border: 1px red;',
'border: red;': 'border: red;',
'border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px; border-image: none;': 'border: 1px;',
'border-top: 1px; border-right: 1px; border-bottom: 1px; border-left: 1px;': 'border-width: 1px; border-style: none; border-color: currentcolor;',
'border-top: 1px; border-right: 2px; border-bottom: 3px; border-left: 4px;': 'border-width: 1px 2px 3px 4px; border-style: none; border-color: currentcolor;',
'border: 1px; border-top: 2px;': 'border-width: 2px 1px 1px; border-style: none; border-color: currentcolor; border-image: none;',
'border: 1px; border-top: 1px !important;': 'border-right: 1px; border-bottom: 1px; border-left: 1px; border-image: none; border-top: 1px !important;',
'border: 1px; border-top-color: red;': 'border-width: 1px; border-style: none; border-color: red currentcolor currentcolor; border-image: none;',
'border: solid; border-style: dotted': 'border: dotted;',
'border-width: 1px;': 'border-width: 1px;',
'overflow-x: scroll; overflow-y: hidden;': 'overflow: scroll hidden;',
'overflow-x: scroll; overflow-y: scroll;': 'overflow: scroll;',
'outline-width: 2px; outline-style: dotted; outline-color: blue;': 'outline: blue dotted 2px;',
'margin-top: 1px; margin-right: 2px; margin-bottom: 3px; margin-left: 4px;': 'margin: 1px 2px 3px 4px;',
'list-style-type: circle; list-style-position: inside; list-style-image: none;': 'list-style: inside circle;',
'list-style-type: lower-alpha;': 'list-style-type: lower-alpha;',
'font-family: sans-serif; line-height: 2em; font-size: 3em; font-style: italic; font-weight: bold;': 'font-family: sans-serif; line-height: 2em; font-size: 3em; font-style: italic; font-weight: bold;',
'padding-top: 1px; padding-right: 2px; padding-bottom: 3px; padding-left: 4px;': 'padding: 1px 2px 3px 4px;'
}
for (let test in tests) {
test_shorthand_serialization(test, tests[test]);
}
</script>
</body>
</html>