summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/data/parse/properties.dat8
-rw-r--r--test/data/parse2/INDEX2
-rw-r--r--test/data/parse2/dodgy-media-block.dat2
-rw-r--r--test/data/parse2/eof.dat30
-rw-r--r--test/data/parse2/mq.dat83
-rw-r--r--test/data/parse2/svg.dat79
-rw-r--r--test/data/select/INDEX1
-rw-r--r--test/data/select/defaulting.dat1478
-rw-r--r--test/data/select/tests1.dat474
-rw-r--r--test/dump.h36
-rw-r--r--test/dump_computed.h57
-rw-r--r--test/select.c1702
12 files changed, 3034 insertions, 918 deletions
diff --git a/test/data/parse/properties.dat b/test/data/parse/properties.dat
index 302b2dc..b6a0715 100644
--- a/test/data/parse/properties.dat
+++ b/test/data/parse/properties.dat
@@ -3289,6 +3289,14 @@ p:before { content: open-quote url('http://picodrive.acornarcade.com/') " : " at
| 0x000c0049
#reset
+#data
+* { position: sticky; }
+#errors
+#expected
+| 1 *
+| 0x00100049
+#reset
+
##
## 4a - quotes
##
diff --git a/test/data/parse2/INDEX b/test/data/parse2/INDEX
index 331cf5c..95534f6 100644
--- a/test/data/parse2/INDEX
+++ b/test/data/parse2/INDEX
@@ -16,6 +16,7 @@ border.dat Border property tests
font.dat Font property tests
list.dat List property tests
margin.dat Margin property tests
+mq.dat Media queries
outline.dat Outline property tests
overflow.dat Overflow property tests
padding.dat Padding property tests
@@ -23,3 +24,4 @@ multicol.dat Multi-column layout property tests
flexbox.dat Flexbox properties and shorthands tests
units.dat Length unit tests
dodgy-media-block.dat Media block with incomplete ruleset
+svg.dat SVG property tests
diff --git a/test/data/parse2/dodgy-media-block.dat b/test/data/parse2/dodgy-media-block.dat
index 61179c3..4b6c220 100644
--- a/test/data/parse2/dodgy-media-block.dat
+++ b/test/data/parse2/dodgy-media-block.dat
@@ -2,7 +2,7 @@
@media only screen { dodgy } .outer { top: 0px }
#errors
#expected
-| @media
+| @media 040
| dodgy
| .outer
| top: 0px
diff --git a/test/data/parse2/eof.dat b/test/data/parse2/eof.dat
index 2f238d7..7fc4ab7 100644
--- a/test/data/parse2/eof.dat
+++ b/test/data/parse2/eof.dat
@@ -180,49 +180,49 @@ f{clear:both}
@media screen
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen{
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen{
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen{{
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen{;
#errors
#expected
-| @media
+| @media 040
#reset
#data
@media screen{f
#errors
#expected
-| @media
+| @media 040
| f
#reset
@@ -230,7 +230,7 @@ f{clear:both}
@media screen{f{
#errors
#expected
-| @media
+| @media 040
| f
#reset
@@ -238,7 +238,7 @@ f{clear:both}
@media screen{f{color
#errors
#expected
-| @media
+| @media 040
| f
#reset
@@ -246,7 +246,7 @@ f{clear:both}
@media screen{f{color:
#errors
#expected
-| @media
+| @media 040
| f
#reset
@@ -254,7 +254,7 @@ f{clear:both}
@media screen{f{color:blue
#errors
#expected
-| @media
+| @media 040
| f
| color: #ff0000ff
#reset
@@ -263,7 +263,7 @@ f{clear:both}
@media screen{f{color:blue;
#errors
#expected
-| @media
+| @media 040
| f
| color: #ff0000ff
#reset
@@ -272,7 +272,7 @@ f{clear:both}
@media screen{f{color:blue}
#errors
#expected
-| @media
+| @media 040
| f
| color: #ff0000ff
#reset
@@ -281,7 +281,7 @@ f{clear:both}
@media screen{f{color:blue;}
#errors
#expected
-| @media
+| @media 040
| f
| color: #ff0000ff
#reset
@@ -290,7 +290,7 @@ f{clear:both}
@media screen{f{color:blue;}}
#errors
#expected
-| @media
+| @media 040
| f
| color: #ff0000ff
#reset
diff --git a/test/data/parse2/mq.dat b/test/data/parse2/mq.dat
new file mode 100644
index 0000000..5119d35
--- /dev/null
+++ b/test/data/parse2/mq.dat
@@ -0,0 +1,83 @@
+#data
+@media not
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media and
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media or
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media only
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media only not
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media only only
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media not not
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media not only
+#errors
+#expected
+| @media not 3ff
+#reset
+
+#data
+@media screen
+#errors
+#expected
+| @media 040
+#reset
+
+#data
+@media unknown
+#errors
+#expected
+| @media 000
+#reset
+
+#data
+@media not unknown
+#errors
+#expected
+| @media not 000
+#reset
+
+#data
+@media (color)
+#errors
+#expected
+| @media 3ff
+#reset
diff --git a/test/data/parse2/svg.dat b/test/data/parse2/svg.dat
new file mode 100644
index 0000000..e5ee2a3
--- /dev/null
+++ b/test/data/parse2/svg.dat
@@ -0,0 +1,79 @@
+#data
+* { fill-opacity: inherit; }
+#errors
+#expected
+| *
+| fill-opacity: inherit
+#reset
+
+#data
+* { fill-opacity: revert; }
+#errors
+#expected
+| *
+| fill-opacity: revert
+#reset
+
+#data
+* { fill-opacity: 0.867; }
+#errors
+#expected
+| *
+| fill-opacity: 0.867
+#reset
+
+#data
+* { fill-opacity: -0.5; }
+#errors
+#expected
+| *
+| fill-opacity: 0
+#reset
+
+#data
+* { fill-opacity: 5; }
+#errors
+#expected
+| *
+| fill-opacity: 1
+#reset
+
+#data
+* { stroke-opacity: inherit; }
+#errors
+#expected
+| *
+| stroke-opacity: inherit
+#reset
+
+#data
+* { stroke-opacity: revert; }
+#errors
+#expected
+| *
+| stroke-opacity: revert
+#reset
+
+#data
+* { stroke-opacity: 0.00000; }
+#errors
+#expected
+| *
+| stroke-opacity: 0
+#reset
+
+#data
+* { stroke-opacity: -0.5; }
+#errors
+#expected
+| *
+| stroke-opacity: 0
+#reset
+
+#data
+* { stroke-opacity: 5; }
+#errors
+#expected
+| *
+| stroke-opacity: 1
+#reset
diff --git a/test/data/select/INDEX b/test/data/select/INDEX
index fb15ad4..c05567a 100644
--- a/test/data/select/INDEX
+++ b/test/data/select/INDEX
@@ -3,3 +3,4 @@
# Test Description
tests1.dat Basic tests
+defaulting.dat Explicit defaulting tests
diff --git a/test/data/select/defaulting.dat b/test/data/select/defaulting.dat
new file mode 100644
index 0000000..9548ae8
--- /dev/null
+++ b/test/data/select/defaulting.dat
@@ -0,0 +1,1478 @@
+#tree screen
+| div*
+#ua
+div { display: block; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: block
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: block; }
+#user
+div { display: initial; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div
+| p*
+#ua
+div { display: block; }
+#user
+p { display: inherit; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: block
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div
+| p*
+#ua
+div { display: block; }
+#user
+p { display: table-cell; }
+p { display: unset; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { font-style: italic; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: italic
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div
+| p*
+#ua
+div { font-style: italic; }
+#user
+p { font-style: oblique; }
+p { font-style: unset; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: italic
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: block; }
+#user
+div { display: inline-block; }
+div { display: table-cell; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: table-cell
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div
+| p*
+#ua
+div { font-style: italic; }
+p { font-style: oblique; }
+p { font-style: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: italic
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div
+| p*
+#ua
+div { display: block; }
+p { display: table-cell; }
+p { display: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: block; }
+#user
+div { display: inline-block; }
+div { display: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: block
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: block; }
+#user
+div { display: inline-block; }
+#author
+div { display: table-cell; }
+div { display: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline-block
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: block; }
+#user
+div { display: revert; }
+#author
+div { display: table-cell; }
+div { display: revert; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: block
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
diff --git a/test/data/select/tests1.dat b/test/data/select/tests1.dat
index 295ab2e..9240ed6 100644
--- a/test/data/select/tests1.dat
+++ b/test/data/select/tests1.dat
@@ -52,6 +52,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -93,6 +94,120 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { display: grid; }
+#user
+div { display: inline-grid; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline-grid
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: static
+quotes: none
+right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -166,6 +281,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -207,6 +323,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -284,6 +401,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -325,6 +443,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -403,6 +522,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -444,6 +564,7 @@ padding-left: 0px
position: absolute
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -522,6 +643,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -563,6 +685,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -641,6 +764,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -682,6 +806,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -750,6 +875,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -791,6 +917,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -860,6 +987,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -901,6 +1029,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -970,6 +1099,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1011,6 +1141,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1079,6 +1210,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1120,6 +1252,7 @@ padding-left: 0px
position: static
quotes: "a" "b"
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1193,6 +1326,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1234,6 +1368,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1307,6 +1442,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1348,6 +1484,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1422,6 +1559,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1463,6 +1601,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1540,6 +1679,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1581,6 +1721,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1657,6 +1798,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1698,6 +1840,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1780,6 +1923,7 @@ cursor: auto
direction: ltr
display: table-row
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1821,6 +1965,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -1903,6 +2048,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -1944,6 +2090,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2026,6 +2173,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2067,6 +2215,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2153,6 +2302,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2194,6 +2344,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2279,6 +2430,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2320,6 +2472,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2403,6 +2556,7 @@ cursor: auto
direction: ltr
display: table-cell
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2444,6 +2598,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2526,6 +2681,7 @@ cursor: auto
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2567,6 +2723,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2649,6 +2806,7 @@ cursor: auto
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2690,6 +2848,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2772,6 +2931,7 @@ cursor: auto
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2813,6 +2973,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -2895,6 +3056,7 @@ cursor: crosshair
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -2936,6 +3098,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3018,6 +3181,7 @@ cursor: default
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3059,6 +3223,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3141,6 +3306,7 @@ cursor: pointer
direction: ltr
display: table
empty-cells: hide
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3182,6 +3348,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3264,6 +3431,7 @@ cursor: move
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3305,6 +3473,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3387,6 +3556,7 @@ cursor: e-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3428,6 +3598,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3510,6 +3681,7 @@ cursor: ne-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3551,6 +3723,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3633,6 +3806,7 @@ cursor: nw-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3674,6 +3848,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3756,6 +3931,7 @@ cursor: n-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3797,6 +3973,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -3879,6 +4056,7 @@ cursor: se-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -3920,6 +4098,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4002,6 +4181,7 @@ cursor: sw-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4043,6 +4223,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4125,6 +4306,7 @@ cursor: s-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4166,6 +4348,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4248,6 +4431,7 @@ cursor: w-resize
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4289,6 +4473,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4371,6 +4556,7 @@ cursor: text
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4412,6 +4598,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4494,6 +4681,7 @@ cursor: wait
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4535,6 +4723,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4617,6 +4806,7 @@ cursor: help
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4658,6 +4848,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4740,6 +4931,7 @@ cursor: progress
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4781,6 +4973,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4863,6 +5056,7 @@ cursor: url('sonic-team.png') pointer
direction: ltr
display: table
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -4904,6 +5098,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -4979,6 +5174,7 @@ cursor: auto
direction: ltr
display: none
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5020,6 +5216,7 @@ padding-left: 0px
position: absolute
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5095,6 +5292,7 @@ cursor: auto
direction: ltr
display: none
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5136,6 +5334,7 @@ padding-left: 0px
position: absolute
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5211,6 +5410,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5252,6 +5452,7 @@ padding-left: 0px
position: absolute
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5324,6 +5525,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5365,6 +5567,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5438,6 +5641,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5479,6 +5683,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5552,6 +5757,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5593,6 +5799,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5666,6 +5873,7 @@ cursor: auto
direction: ltr
display: block
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5707,6 +5915,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5776,6 +5985,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5817,6 +6027,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5887,6 +6098,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -5928,6 +6140,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -5997,6 +6210,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6038,6 +6252,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6107,6 +6322,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6148,6 +6364,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6217,6 +6434,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6258,6 +6476,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6327,6 +6546,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6368,6 +6588,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6437,6 +6658,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6478,6 +6700,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6549,6 +6772,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6590,6 +6814,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6659,6 +6884,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6700,6 +6926,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6769,6 +6996,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6810,6 +7038,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6880,6 +7109,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -6921,6 +7151,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -6990,6 +7221,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 10px
flex-direction: row
flex-grow: 2.000
@@ -7031,6 +7263,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7100,6 +7333,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 1.000
@@ -7141,6 +7375,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7210,6 +7445,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -7251,6 +7487,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7320,6 +7557,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 0.000
@@ -7361,6 +7599,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7430,6 +7669,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 0.000
@@ -7471,6 +7711,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7540,6 +7781,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 0.000
@@ -7581,6 +7823,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7650,6 +7893,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 3.000
@@ -7691,6 +7935,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7759,6 +8004,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 3px
flex-direction: row
flex-grow: 0.000
@@ -7800,6 +8046,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7868,6 +8115,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 3em
flex-direction: row
flex-grow: 2.000
@@ -7909,6 +8157,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -7977,6 +8226,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 20.000
@@ -8018,6 +8268,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8088,6 +8339,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 3.000
@@ -8129,6 +8381,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8199,6 +8452,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 3px
flex-direction: row
flex-grow: 3.000
@@ -8240,6 +8494,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8308,6 +8563,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 0px
flex-direction: row
flex-grow: 0.000
@@ -8349,6 +8605,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8419,6 +8676,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -8460,6 +8718,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8530,6 +8789,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 3%
flex-direction: row
flex-grow: 3.000
@@ -8571,6 +8831,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8641,6 +8902,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 3%
flex-direction: row
flex-grow: 3.000
@@ -8682,6 +8944,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8750,6 +9013,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -8791,6 +9055,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8859,6 +9124,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -8900,6 +9166,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -8968,6 +9235,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -9009,6 +9277,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9077,6 +9346,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -9118,6 +9388,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9186,6 +9457,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: column
flex-grow: 0.000
@@ -9227,6 +9499,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9295,6 +9568,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row-reverse
flex-grow: 0.000
@@ -9336,6 +9610,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9404,6 +9679,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: column-reverse
flex-grow: 0.000
@@ -9445,6 +9721,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9513,6 +9790,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: column-reverse
flex-grow: 0.000
@@ -9554,6 +9832,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9624,6 +9903,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: column
flex-grow: 0.000
@@ -9665,6 +9945,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9735,6 +10016,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row-reverse
flex-grow: 0.000
@@ -9776,6 +10058,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9844,6 +10127,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 4.500em
flex-direction: row
flex-grow: 2.370
@@ -9885,6 +10169,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -9953,6 +10238,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -9994,6 +10280,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10062,6 +10349,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10103,6 +10391,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10171,6 +10460,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10212,6 +10502,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10280,6 +10571,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10321,6 +10613,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10389,6 +10682,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10430,6 +10724,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10498,6 +10793,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10539,6 +10835,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10609,6 +10906,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10650,6 +10948,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10720,6 +11019,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10761,6 +11061,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10829,6 +11130,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10870,6 +11172,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -10938,6 +11241,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -10979,6 +11283,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11047,6 +11352,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11088,6 +11394,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11158,6 +11465,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11199,6 +11507,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11267,6 +11576,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 4.500em
flex-direction: column
flex-grow: 2.300
@@ -11308,6 +11618,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11378,6 +11689,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: 4.500em
flex-direction: column
flex-grow: 2.300
@@ -11419,6 +11731,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11487,6 +11800,7 @@ cursor: auto
direction: ltr
display: flex
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11528,6 +11842,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11596,6 +11911,7 @@ cursor: auto
direction: ltr
display: inline-flex
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11637,6 +11953,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11705,6 +12022,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11746,6 +12064,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11814,6 +12133,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11855,6 +12175,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -11923,6 +12244,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -11964,6 +12286,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12032,6 +12355,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12073,6 +12397,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12141,6 +12466,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12182,6 +12508,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12250,6 +12577,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12291,6 +12619,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12359,6 +12688,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12400,6 +12730,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12468,6 +12799,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12509,6 +12841,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12577,6 +12910,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12618,6 +12952,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12686,6 +13021,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12727,6 +13063,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12795,6 +13132,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12836,6 +13174,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -12904,6 +13243,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -12945,6 +13285,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13013,6 +13354,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13054,6 +13396,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13122,6 +13465,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13163,6 +13507,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13231,6 +13576,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13272,6 +13618,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13340,6 +13687,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13381,6 +13729,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13449,6 +13798,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13490,6 +13840,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13558,6 +13909,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13599,6 +13951,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13667,6 +14020,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13708,6 +14062,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13776,6 +14131,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13817,6 +14173,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -13885,6 +14242,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -13926,6 +14284,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -14013,6 +14372,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -14054,6 +14414,7 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
@@ -14122,6 +14483,7 @@ cursor: auto
direction: ltr
display: inline
empty-cells: show
+fill-opacity: 1.000
flex-basis: auto
flex-direction: row
flex-grow: 0.000
@@ -14163,6 +14525,118 @@ padding-left: 0px
position: static
quotes: none
right: auto
+stroke-opacity: 1.000
+table-layout: auto
+text-align: default
+text-decoration: none
+text-indent: 0px
+text-transform: none
+top: auto
+unicode-bidi: normal
+vertical-align: baseline
+visibility: visible
+white-space: normal
+width: auto
+word-spacing: normal
+writing-mode: horizontal-tb
+z-index: auto
+#reset
+
+#tree screen
+| div*
+#ua
+div { position: sticky; }
+#errors
+#expected
+align-content: stretch
+align-items: stretch
+align-self: auto
+background-attachment: scroll
+background-color: #00000000
+background-image: none
+background-position: 0% 0%
+background-repeat: repeat
+border-collapse: separate
+border-spacing: 0px 0px
+border-top-color: #ff000000
+border-right-color: #ff000000
+border-bottom-color: #ff000000
+border-left-color: #ff000000
+border-top-style: none
+border-right-style: none
+border-bottom-style: none
+border-left-style: none
+border-top-width: 2px
+border-right-width: 2px
+border-bottom-width: 2px
+border-left-width: 2px
+bottom: auto
+box-sizing: content-box
+break-after: auto
+break-before: auto
+break-inside: auto
+caption-side: top
+clear: none
+clip: auto
+color: #ff000000
+column-count: auto
+column-fill: balance
+column-gap: normal
+column-rule-color: #ff000000
+column-rule-style: none
+column-rule-width: 2px
+column-span: none
+column-width: auto
+content: normal
+counter-increment: none
+counter-reset: none
+cursor: auto
+direction: ltr
+display: inline
+empty-cells: show
+fill-opacity: 1.000
+flex-basis: auto
+flex-direction: row
+flex-grow: 0.000
+flex-shrink: 1.000
+flex-wrap: nowrap
+float: none
+font-family: sans-serif
+font-size: 16px
+font-style: normal
+font-variant: normal
+font-weight: normal
+height: auto
+justify-content: flex-start
+left: auto
+letter-spacing: normal
+line-height: normal
+list-style-image: none
+list-style-position: outside
+list-style-type: disc
+margin-top: 0px
+margin-right: 0px
+margin-bottom: 0px
+margin-left: 0px
+max-height: none
+max-width: none
+min-height: 0px
+min-width: 0px
+opacity: 1.000
+order: 0
+outline-color: invert
+outline-style: none
+outline-width: 2px
+overflow-x: visible
+overflow-y: visible
+padding-top: 0px
+padding-right: 0px
+padding-bottom: 0px
+padding-left: 0px
+position: sticky
+quotes: none
+right: auto
+stroke-opacity: 1.000
table-layout: auto
text-align: default
text-decoration: none
diff --git a/test/dump.h b/test/dump.h
index 79819e0..09a35b0 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -131,7 +131,9 @@ void dump_rule_media(css_rule_media *s, char **buf, size_t *buflen)
char *ptr = *buf;
css_rule *rule;
- ptr += sprintf(ptr, "| @media ");
+ ptr += sprintf(ptr, "| @media %s%03lx",
+ s->media->negate_type ? "not " : "",
+ s->media->type);
/* \todo media list */
@@ -489,6 +491,8 @@ static const char *opcode_names[] = {
"flex-wrap",
"justify-content",
"order",
+ "fill-opacity",
+ "stroke-opacity",
};
static void dump_css_fixed(css_fixed f, char **ptr)
@@ -786,8 +790,14 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t depth)
*((*ptr)++) = ' ';
*ptr += sprintf(*ptr, "%s: ", opcode_names[op]);
- if (isInherit(opv)) {
+ if (getFlagValue(opv) == FLAG_VALUE_INHERIT) {
*ptr += sprintf(*ptr, "inherit");
+ } else if (getFlagValue(opv) == FLAG_VALUE_INITIAL) {
+ *ptr += sprintf(*ptr, "initial");
+ } else if (getFlagValue(opv) == FLAG_VALUE_REVERT) {
+ *ptr += sprintf(*ptr, "revert");
+ } else if (getFlagValue(opv) == FLAG_VALUE_UNSET) {
+ *ptr += sprintf(*ptr, "unset");
} else {
value = getValue(opv);
@@ -1811,6 +1821,28 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t depth)
break;
}
break;
+ case CSS_PROP_FILL_OPACITY:
+ switch (value) {
+ case FILL_OPACITY_SET:
+ {
+ css_fixed val = *((css_fixed *) bytecode);
+ ADVANCE(sizeof(val));
+ dump_number(val, ptr);
+ }
+ break;
+ }
+ break;
+ case CSS_PROP_STROKE_OPACITY:
+ switch (value) {
+ case STROKE_OPACITY_SET:
+ {
+ css_fixed val = *((css_fixed *) bytecode);
+ ADVANCE(sizeof(val));
+ dump_number(val, ptr);
+ }
+ break;
+ }
+ break;
case CSS_PROP_FLEX_BASIS:
switch (value) {
case FLEX_BASIS_AUTO:
diff --git a/test/dump_computed.h b/test/dump_computed.h
index 8ac6424..f769075 100644
--- a/test/dump_computed.h
+++ b/test/dump_computed.h
@@ -1603,6 +1603,12 @@ static void dump_computed_style(const css_computed_style *style, char *buf,
case CSS_DISPLAY_INLINE_FLEX:
wrote = snprintf(ptr, *len, "display: inline-flex\n");
break;
+ case CSS_DISPLAY_GRID:
+ wrote = snprintf(ptr, *len, "display: grid\n");
+ break;
+ case CSS_DISPLAY_INLINE_GRID:
+ wrote = snprintf(ptr, *len, "display: inline-grid\n");
+ break;
default:
wrote = 0;
break;
@@ -1629,6 +1635,30 @@ static void dump_computed_style(const css_computed_style *style, char *buf,
ptr += wrote;
*len -= wrote;
+ /* fill-opacity */
+ val = css_computed_fill_opacity(style, &len1);
+ switch (val) {
+ case CSS_FILL_OPACITY_INHERIT:
+ wrote = snprintf(ptr, *len, "fill-opacity: inherit\n");
+ break;
+ case CSS_FILL_OPACITY_SET:
+ wrote = snprintf(ptr, *len, "fill-opacity: ");
+ ptr += wrote;
+ *len -= wrote;
+
+ wrote = dump_css_fixed(len1, ptr, *len);
+ ptr += wrote;
+ *len -= wrote;
+
+ wrote = snprintf(ptr, *len, "\n");
+ break;
+ default:
+ wrote = 0;
+ break;
+ }
+ ptr += wrote;
+ *len -= wrote;
+
/* flex-basis */
val = css_computed_flex_basis(style, &len1, &unit1);
switch (val) {
@@ -2719,6 +2749,9 @@ static void dump_computed_style(const css_computed_style *style, char *buf,
case CSS_POSITION_FIXED:
wrote = snprintf(ptr, *len, "position: fixed\n");
break;
+ case CSS_POSITION_STICKY:
+ wrote = snprintf(ptr, *len, "position: sticky\n");
+ break;
default:
wrote = 0;
break;
@@ -2787,6 +2820,30 @@ static void dump_computed_style(const css_computed_style *style, char *buf,
ptr += wrote;
*len -= wrote;
+ /* stroke-opacity */
+ val = css_computed_stroke_opacity(style, &len1);
+ switch (val) {
+ case CSS_STROKE_OPACITY_INHERIT:
+ wrote = snprintf(ptr, *len, "stroke-opacity: inherit\n");
+ break;
+ case CSS_STROKE_OPACITY_SET:
+ wrote = snprintf(ptr, *len, "stroke-opacity: ");
+ ptr += wrote;
+ *len -= wrote;
+
+ wrote = dump_css_fixed(len1, ptr, *len);
+ ptr += wrote;
+ *len -= wrote;
+
+ wrote = snprintf(ptr, *len, "\n");
+ break;
+ default:
+ wrote = 0;
+ break;
+ }
+ ptr += wrote;
+ *len -= wrote;
+
/* table-layout */
val = css_computed_table_layout(style);
switch (val) {
diff --git a/test/select.c b/test/select.c
index c104b38..5bc7856 100644
--- a/test/select.c
+++ b/test/select.c
@@ -70,874 +70,7 @@ typedef struct line_ctx {
lwc_string *attr_id;
} line_ctx;
-
-
-
-static bool handle_line(const char *data, size_t datalen, void *pw);
-static void css__parse_tree(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_media_list(const char **data, size_t *len, css_media *media);
-static void css__parse_pseudo_list(const char **data, size_t *len,
- uint32_t *element);
-static void css__parse_expected(line_ctx *ctx, const char *data, size_t len);
-static void run_test(line_ctx *ctx, const char *exp, size_t explen);
-static void destroy_tree(node *root);
-
-static css_error node_name(void *pw, void *node,
- css_qname *qname);
-static css_error node_classes(void *pw, void *n,
- lwc_string ***classes, uint32_t *n_classes);
-static css_error node_id(void *pw, void *node,
- lwc_string **id);
-static css_error named_ancestor_node(void *pw, void *node,
- const css_qname *qname,
- void **ancestor);
-static css_error named_parent_node(void *pw, void *node,
- const css_qname *qname,
- void **parent);
-static css_error named_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error named_generic_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error parent_node(void *pw, void *node, void **parent);
-static css_error sibling_node(void *pw, void *node, void **sibling);
-static css_error node_has_name(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_class(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_id(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_attribute(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_attribute_equal(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_dashmatch(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_includes(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_prefix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_suffix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_substring(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_is_root(void *pw, void *node, bool *match);
-static css_error node_count_siblings(void *pw, void *node,
- bool same_name, bool after, int32_t *count);
-static css_error node_is_empty(void *pw, void *node, bool *match);
-static css_error node_is_link(void *pw, void *node, bool *match);
-static css_error node_is_visited(void *pw, void *node, bool *match);
-static css_error node_is_hover(void *pw, void *node, bool *match);
-static css_error node_is_active(void *pw, void *node, bool *match);
-static css_error node_is_focus(void *pw, void *node, bool *match);
-static css_error node_is_enabled(void *pw, void *node, bool *match);
-static css_error node_is_disabled(void *pw, void *node, bool *match);
-static css_error node_is_checked(void *pw, void *node, bool *match);
-static css_error node_is_target(void *pw, void *node, bool *match);
-static css_error node_is_lang(void *pw, void *node,
- lwc_string *lang, bool *match);
-static css_error node_presentational_hint(void *pw, void *node,
- uint32_t *nhints, css_hint **hints);
-static css_error ua_default_for_property(void *pw, uint32_t property,
- css_hint *hints);
-static css_error set_libcss_node_data(void *pw, void *n,
- void *libcss_node_data);
-static css_error get_libcss_node_data(void *pw, void *n,
- void **libcss_node_data);
-
-static css_unit_ctx unit_ctx = {
- .font_size_default = 16 * (1 << CSS_RADIX_POINT),
-};
-
-static css_select_handler select_handler = {
- CSS_SELECT_HANDLER_VERSION_1,
-
- node_name,
- node_classes,
- node_id,
- named_ancestor_node,
- named_parent_node,
- named_sibling_node,
- named_generic_sibling_node,
- parent_node,
- sibling_node,
- node_has_name,
- node_has_class,
- node_has_id,
- node_has_attribute,
- node_has_attribute_equal,
- node_has_attribute_dashmatch,
- node_has_attribute_includes,
- node_has_attribute_prefix,
- node_has_attribute_suffix,
- node_has_attribute_substring,
- node_is_root,
- node_count_siblings,
- node_is_empty,
- node_is_link,
- node_is_visited,
- node_is_hover,
- node_is_active,
- node_is_focus,
- node_is_enabled,
- node_is_disabled,
- node_is_checked,
- node_is_target,
- node_is_lang,
- node_presentational_hint,
- ua_default_for_property,
-
- set_libcss_node_data,
- get_libcss_node_data,
-};
-
-static css_error resolve_url(void *pw,
- const char *base, lwc_string *rel, lwc_string **abs)
-{
- UNUSED(pw);
- UNUSED(base);
-
- /* About as useless as possible */
- *abs = lwc_string_ref(rel);
-
- return CSS_OK;
-}
-
-static bool fail_because_lwc_leaked = false;
-
-static void
-printing_lwc_iterator(lwc_string *str, void *pw)
-{
- UNUSED(pw);
-
- printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
- fail_because_lwc_leaked = true;
-}
-
-int main(int argc, char **argv)
-{
- line_ctx ctx;
-
- if (argc != 2) {
- printf("Usage: %s <filename>\n", argv[0]);
- return 1;
- }
-
- memset(&ctx, 0, sizeof(ctx));
-
-
- lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
- lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
-
- assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
-
- /* and run final test */
- if (ctx.tree != NULL)
- run_test(&ctx, ctx.exp, ctx.expused);
-
- free(ctx.exp);
-
- lwc_string_unref(ctx.attr_class);
- lwc_string_unref(ctx.attr_id);
-
- lwc_iterate_strings(printing_lwc_iterator, NULL);
-
- assert(fail_because_lwc_leaked == false);
-
- printf("PASS\n");
- return 0;
-}
-
-bool handle_line(const char *data, size_t datalen, void *pw)
-{
- line_ctx *ctx = (line_ctx *) pw;
- css_error error;
-
- if (data[0] == '#') {
- if (ctx->intree) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else {
- /* Assume start of stylesheet */
- css__parse_sheet(ctx, data + 1, datalen - 1);
-
- ctx->intree = false;
- ctx->insheet = true;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- } else if (ctx->insheet) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
-
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else if (strncasecmp(data+1, "ua", 2) == 0 ||
- strncasecmp(data+1, "user", 4) == 0 ||
- strncasecmp(data+1, "author", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
-
- css__parse_sheet(ctx, data + 1, datalen - 1);
- } else {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data,
- datalen);
- assert(error == CSS_OK ||
- error == CSS_NEEDDATA);
- }
- } else if (ctx->inerrors) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = true;
- } else if (ctx->inexp) {
- /* This marks end of testcase, so run it */
- run_test(ctx, ctx->exp, ctx->expused);
-
- ctx->expused = 0;
-
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- } else {
- /* Start state */
- if (strncasecmp(data+1, "tree", 4) == 0) {
- css__parse_tree(ctx, data + 5, datalen - 5);
-
- ctx->intree = true;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- }
- } else {
- if (ctx->intree) {
- /* Not interested in the '|' */
- css__parse_tree_data(ctx, data + 1, datalen - 1);
- } else if (ctx->insheet) {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data, datalen);
- assert(error == CSS_OK || error == CSS_NEEDDATA);
- } else if (ctx->inexp) {
- css__parse_expected(ctx, data, datalen);
- }
- }
-
- return true;
-}
-
-void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
-{
- const char *p = data;
- const char *end = data + len;
- size_t left;
-
- /* [ <media_list> <pseudo>? ] ? */
-
- ctx->media.type = CSS_MEDIA_ALL;
- ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
-
- /* Consume any leading whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end) {
- left = end - p;
-
- css__parse_media_list(&p, &left, &ctx->media);
-
- end = p + left;
- }
-
- if (p < end) {
- left = end - p;
-
- css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
- }
-}
-
-void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
-{
- const char *p = data;
- const char *end = data + len;
- const char *name = NULL;
- const char *value = NULL;
- size_t namelen = 0;
- size_t valuelen = 0;
- uint32_t depth = 0;
- bool target = false;
-
- /* ' '{depth+1} [ <element> '*'? | <attr> ]
- *
- * <element> ::= [^=*[:space:]]+
- * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
- */
-
- while (p < end && isspace(*p)) {
- depth++;
- p++;
- }
- depth--;
-
- /* Get element/attribute name */
- name = p;
- while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
- namelen++;
- p++;
- }
-
- /* Skip whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end && *p == '=') {
- /* Attribute value */
- p++;
-
- value = p;
-
- while (p < end && isspace(*p) == false) {
- valuelen++;
- p++;
- }
- } else if (p < end && *p == '*') {
- /* Element is target node */
- target = true;
- }
-
- if (value == NULL) {
- /* We have an element, so create it */
- node *n = malloc(sizeof(node));
- assert(n != NULL);
-
- memset(n, 0, sizeof(node));
-
- lwc_intern_string(name, namelen, &n->name);
-
- /* Insert it into tree */
- if (ctx->tree == NULL) {
- ctx->tree = n;
- } else {
- assert(depth > 0);
- assert(depth <= ctx->depth + 1);
-
- /* Find node to insert into */
- while (depth <= ctx->depth) {
- ctx->depth--;
- ctx->current = ctx->current->parent;
- }
-
- /* Insert into current node */
- if (ctx->current->children == NULL) {
- ctx->current->children = n;
- ctx->current->last_child = n;
- } else {
- ctx->current->last_child->next = n;
- n->prev = ctx->current->last_child;
-
- ctx->current->last_child = n;
- }
- n->parent = ctx->current;
- }
-
- ctx->current = n;
- ctx->depth = depth;
-
- /* Mark the target, if it's us */
- if (target)
- ctx->target = n;
- } else {
- /* New attribute */
- bool amatch = false;
- attribute *attr;
- node *n = ctx->current;
-
- attribute *temp = realloc(n->attrs,
- (n->n_attrs + 1) * sizeof(attribute));
- assert(temp != NULL);
-
- n->attrs = temp;
-
- attr = &n->attrs[n->n_attrs];
-
- lwc_intern_string(name, namelen, &attr->name);
- lwc_intern_string(value, valuelen, &attr->value);
-
- assert(lwc_string_caseless_isequal(
- n->attrs[n->n_attrs].name,
- ctx->attr_class, &amatch) == lwc_error_ok);
- if (amatch == true) {
- n->classes = realloc(NULL, sizeof(lwc_string **));
- assert(n->classes != NULL);
-
- n->classes[0] = lwc_string_ref(
- n->attrs[n->n_attrs].
- value);
- n->n_classes = 1;
- }
-
- n->n_attrs++;
- }
-}
-
-static css_error css_font_resolution_func(void *pw, lwc_string *name,
- css_system_font *system_font)
-{
- lwc_error err;
-
- if (system_font == NULL) {
- return CSS_BADPARM;
- }
-
- (void)(pw);
-
- if (strncmp(lwc_string_data(name), "special-system-font",
- lwc_string_length(name)) != 0) {
- return CSS_INVALID;
- }
-
- system_font->style = CSS_FONT_STYLE_NORMAL;
- system_font->variant = CSS_FONT_VARIANT_NORMAL;
- system_font->weight = CSS_FONT_WEIGHT_NORMAL;
- system_font->size.size = INTTOFIX(22);
- system_font->size.unit = CSS_UNIT_PT;
- system_font->line_height.size = INTTOFIX(33);
- system_font->line_height.unit = CSS_UNIT_EM;
- err = lwc_intern_string("special-system-font",
- strlen("special-system-font"),
- &system_font->family);
- if (err != lwc_error_ok) {
- return CSS_NOMEM;
- }
-
- return CSS_OK;
-}
-
-void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
-{
- css_stylesheet_params params;
- const char *p;
- const char *end = data + len;
- css_origin origin = CSS_ORIGIN_AUTHOR;
- css_stylesheet *sheet;
- sheet_ctx *temp;
- char *media = NULL;
-
- /* <origin> <media_list>? */
-
- /* Find end of origin */
- for (p = data; p < end; p++) {
- if (isspace(*p))
- break;
- }
-
- if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
- origin = CSS_ORIGIN_AUTHOR;
- else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
- origin = CSS_ORIGIN_USER;
- else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
- origin = CSS_ORIGIN_UA;
- else
- assert(0 && "Unknown stylesheet origin");
-
- /* Skip any whitespace */
- while (p < end && isspace(*p))
- p++;
-
- assert(end >= p);
- media = malloc(end - p + 1);
- assert(media != NULL);
- memcpy(media, p, end - p);
- media[end - p] = '\0';
-
- params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
- params.level = CSS_LEVEL_21;
- params.charset = "UTF-8";
- params.url = "foo";
- params.title = "foo";
- params.allow_quirks = false;
- params.inline_style = false;
- params.resolve = resolve_url;
- params.resolve_pw = NULL;
- params.import = NULL;
- params.import_pw = NULL;
- params.color = NULL;
- params.color_pw = NULL;
- params.font = css_font_resolution_func;
- params.font_pw = NULL;
-
- /** \todo How are we going to handle @import? */
- assert(css_stylesheet_create(&params, &sheet) == CSS_OK);
-
- /* Extend array of sheets and append new sheet to it */
- temp = realloc(ctx->sheets,
- (ctx->n_sheets + 1) * sizeof(sheet_ctx));
- assert(temp != NULL);
-
- ctx->sheets = temp;
-
- ctx->sheets[ctx->n_sheets].sheet = sheet;
- ctx->sheets[ctx->n_sheets].origin = origin;
- ctx->sheets[ctx->n_sheets].media = media;
-
- ctx->n_sheets++;
-}
-
-void css__parse_media_list(const char **data, size_t *len, css_media *media)
-{
- const char *p = *data;
- const char *end = p + *len;
- uint64_t result = 0;
-
- /* <medium> [ ',' <medium> ]* */
-
- while (p < end) {
- const char *start = p;
-
- /* consume a medium */
- while (isspace(*p) == false && *p != ',')
- p++;
-
- if (p - start == 10 &&
- strncasecmp(start, "projection", 10) == 0)
- result |= CSS_MEDIA_PROJECTION;
- else if (p - start == 8 &&
- strncasecmp(start, "handheld", 8) == 0)
- result |= CSS_MEDIA_HANDHELD;
- else if (p - start == 8 &&
- strncasecmp(start, "embossed", 8) == 0)
- result |= CSS_MEDIA_EMBOSSED;
- else if (p - start == 7 &&
- strncasecmp(start, "braille", 7) == 0)
- result |= CSS_MEDIA_BRAILLE;
- else if (p - start == 6 &&
- strncasecmp(start, "speech", 6) == 0)
- result |= CSS_MEDIA_SPEECH;
- else if (p - start == 6 &&
- strncasecmp(start, "screen", 6) == 0)
- result |= CSS_MEDIA_SCREEN;
- else if (p - start == 5 &&
- strncasecmp(start, "print", 5) == 0)
- result |= CSS_MEDIA_PRINT;
- else if (p - start == 5 &&
- strncasecmp(start, "aural", 5) == 0)
- result |= CSS_MEDIA_AURAL;
- else if (p - start == 3 &&
- strncasecmp(start, "tty", 3) == 0)
- result |= CSS_MEDIA_TTY;
- else if (p - start == 3 &&
- strncasecmp(start, "all", 3) == 0)
- result |= CSS_MEDIA_ALL;
- else if (p - start == 2 &&
- strncasecmp(start, "tv", 2) == 0)
- result |= CSS_MEDIA_TV;
- else
- assert(0 && "Unknown media type");
-
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
-
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
- break;
-
- /* Consume comma */
- p++;
-
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
- }
-
- media->type = result;
-
- *data = p;
- *len = end - p;
-}
-
-void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
-{
- const char *p = *data;
- const char *end = p + *len;
-
- /* <pseudo> [ ',' <pseudo> ]* */
-
- *element = CSS_PSEUDO_ELEMENT_NONE;
-
- while (p < end) {
- const char *start = p;
-
- /* consume a pseudo */
- while (isspace(*p) == false && *p != ',')
- p++;
-
- /* Pseudo elements */
- if (p - start == 12 &&
- strncasecmp(start, "first-letter", 12) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
- else if (p - start == 10 &&
- strncasecmp(start, "first-line", 10) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
- else if (p - start == 6 &&
- strncasecmp(start, "before", 6) == 0)
- *element = CSS_PSEUDO_ELEMENT_BEFORE;
- else if (p - start == 5 &&
- strncasecmp(start, "after", 5) == 0)
- *element = CSS_PSEUDO_ELEMENT_AFTER;
- else
- assert(0 && "Unknown pseudo");
-
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
-
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
- break;
-
- /* Consume comma */
- p++;
-
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
- }
-
- *data = p;
- *len = end - p;
-}
-
-void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
-{
- while (ctx->expused + len >= ctx->explen) {
- size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
- char *temp = realloc(ctx->exp, required);
- if (temp == NULL) {
- assert(0 && "No memory for expected output");
- }
-
- ctx->exp = temp;
- ctx->explen = required;
- }
-
- memcpy(ctx->exp + ctx->expused, data, len);
-
- ctx->expused += len;
-}
-
-static void show_differences(size_t len, const char *exp, const char *res)
-{
- const char *pos_exp, *opos_exp;
- const char *pos_res, *opos_res;
-
- opos_exp = pos_exp = exp;
- opos_res = pos_res = res;
-
- printf("Line differences:\n");
- while (pos_exp < exp + len && pos_res < res + len) {
- if (*pos_exp == '\n' && *pos_res == '\n') {
- if (pos_exp - opos_exp != pos_res - opos_res ||
- memcmp(opos_exp, opos_res,
- pos_exp - opos_exp) != 0) {
- printf("Expected:\t%.*s\n",
- (int)(pos_exp - opos_exp),
- opos_exp);
- printf(" Result:\t%.*s\n",
- (int)(pos_res - opos_res),
- opos_res);
- printf("\n");
- }
- opos_exp = ++pos_exp;
- opos_res = ++pos_res;
- } else if (*pos_exp == '\n') {
- pos_res++;
- } else if (*pos_res == '\n') {
- pos_exp++;
- } else {
- pos_exp++;
- pos_res++;
- }
- }
-}
-
-
-static void run_test_select_tree(css_select_ctx *select,
- node *node, line_ctx *ctx,
- char *buf, size_t *buflen)
-{
- css_select_results *sr;
- struct node *n = NULL;
-
- if (node->parent == NULL) {
- unit_ctx.root_style = NULL;
- }
-
-
- assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
- &select_handler, ctx, &sr) == CSS_OK);
-
- if (node->parent != NULL) {
- css_computed_style *composed;
- assert(css_computed_style_compose(
- node->parent->sr->styles[ctx->pseudo_element],
- sr->styles[ctx->pseudo_element],
- &unit_ctx,
- &composed) == CSS_OK);
- css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
- sr->styles[ctx->pseudo_element] = composed;
- }
-
- node->sr = sr;
-
- if (node == ctx->target) {
- dump_computed_style(sr->styles[ctx->pseudo_element],
- buf, buflen);
- }
-
- if (node->parent == NULL) {
- unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
- }
-
- for (n = node->children; n != NULL; n = n->next) {
- run_test_select_tree(select, n, ctx, buf, buflen);
- }
-}
-
-
-void run_test(line_ctx *ctx, const char *exp, size_t explen)
-{
- css_select_ctx *select;
- css_select_results *results;
- uint32_t i;
- char *buf;
- size_t buflen;
- static int testnum;
-
- UNUSED(exp);
-
- buf = malloc(8192);
- if (buf == NULL) {
- assert(0 && "No memory for result data");
- }
- buflen = 8192;
-
- assert(css_select_ctx_create(&select) == CSS_OK);
-
- for (i = 0; i < ctx->n_sheets; i++) {
- assert(css_select_ctx_append_sheet(select,
- ctx->sheets[i].sheet, ctx->sheets[i].origin,
- ctx->sheets[i].media) == CSS_OK);
- }
-
- testnum++;
-
- run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
-
- results = ctx->target->sr;
- assert(results->styles[ctx->pseudo_element] != NULL);
-
- if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
- size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
- printf("Expected (%u):\n%.*s\n",
- (int) explen, (int) explen, exp);
- printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
- (int) (8192 - buflen), buf);
-
- show_differences(len, exp, buf);
- assert(0 && "Result doesn't match expected");
- }
-
- /* Clean up */
- css_select_ctx_destroy(select);
- destroy_tree(ctx->tree);
-
- for (i = 0; i < ctx->n_sheets; i++) {
- css_stylesheet_destroy(ctx->sheets[i].sheet);
- free(ctx->sheets[i].media);
- }
-
- ctx->tree = NULL;
- ctx->current = NULL;
- ctx->depth = 0;
- ctx->n_sheets = 0;
- free(ctx->sheets);
- ctx->sheets = NULL;
- ctx->target = NULL;
-
- free(buf);
-
- printf("Test %d: PASS\n", testnum);
-}
-
-void destroy_tree(node *root)
-{
- node *n, *p;
- uint32_t i;
-
- for (n = root->children; n != NULL; n = p) {
- p = n->next;
-
- destroy_tree(n);
- }
-
- css_select_results_destroy(root->sr);
-
- for (i = 0; i < root->n_attrs; ++i) {
- lwc_string_unref(root->attrs[i].name);
- lwc_string_unref(root->attrs[i].value);
- }
- free(root->attrs);
-
- if (root->classes != NULL) {
- for (i = 0; i < root->n_classes; ++i) {
- lwc_string_unref(root->classes[i]);
- }
- free(root->classes);
- }
-
- if (root->libcss_node_data != NULL) {
- css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
- NULL, root, NULL, root->libcss_node_data);
- }
-
- lwc_string_unref(root->name);
- free(root);
-}
-
-
-css_error node_name(void *pw, void *n, css_qname *qname)
+static css_error node_name(void *pw, void *n, css_qname *qname)
{
node *node = n;
@@ -965,7 +98,7 @@ static css_error node_classes(void *pw, void *n,
}
-css_error node_id(void *pw, void *n,
+static css_error node_id(void *pw, void *n,
lwc_string **id)
{
node *node = n;
@@ -989,7 +122,7 @@ css_error node_id(void *pw, void *n,
return CSS_OK;
}
-css_error named_ancestor_node(void *pw, void *n,
+static css_error named_ancestor_node(void *pw, void *n,
const css_qname *qname,
void **ancestor)
{
@@ -1010,7 +143,7 @@ css_error named_ancestor_node(void *pw, void *n,
return CSS_OK;
}
-css_error named_parent_node(void *pw, void *n,
+static css_error named_parent_node(void *pw, void *n,
const css_qname *qname,
void **parent)
{
@@ -1030,7 +163,7 @@ css_error named_parent_node(void *pw, void *n,
return CSS_OK;
}
-css_error named_sibling_node(void *pw, void *n,
+static css_error named_sibling_node(void *pw, void *n,
const css_qname *qname,
void **sibling)
{
@@ -1050,7 +183,7 @@ css_error named_sibling_node(void *pw, void *n,
return CSS_OK;
}
-css_error named_generic_sibling_node(void *pw, void *n,
+static css_error named_generic_sibling_node(void *pw, void *n,
const css_qname *qname,
void **sibling)
{
@@ -1071,7 +204,7 @@ css_error named_generic_sibling_node(void *pw, void *n,
return CSS_OK;
}
-css_error parent_node(void *pw, void *n, void **parent)
+static css_error parent_node(void *pw, void *n, void **parent)
{
node *node = n;
@@ -1082,7 +215,7 @@ css_error parent_node(void *pw, void *n, void **parent)
return CSS_OK;
}
-css_error sibling_node(void *pw, void *n, void **sibling)
+static css_error sibling_node(void *pw, void *n, void **sibling)
{
node *node = n;
@@ -1093,7 +226,7 @@ css_error sibling_node(void *pw, void *n, void **sibling)
return CSS_OK;
}
-css_error node_has_name(void *pw, void *n,
+static css_error node_has_name(void *pw, void *n,
const css_qname *qname,
bool *match)
{
@@ -1110,7 +243,7 @@ css_error node_has_name(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_class(void *pw, void *n,
+static css_error node_has_class(void *pw, void *n,
lwc_string *name,
bool *match)
{
@@ -1136,7 +269,7 @@ css_error node_has_class(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_id(void *pw, void *n,
+static css_error node_has_id(void *pw, void *n,
lwc_string *name,
bool *match)
{
@@ -1162,7 +295,7 @@ css_error node_has_id(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute(void *pw, void *n,
+static css_error node_has_attribute(void *pw, void *n,
const css_qname *qname,
bool *match)
{
@@ -1182,7 +315,7 @@ css_error node_has_attribute(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_equal(void *pw, void *n,
+static css_error node_has_attribute_equal(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1210,7 +343,7 @@ css_error node_has_attribute_equal(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_includes(void *pw, void *n,
+static css_error node_has_attribute_includes(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1256,7 +389,7 @@ css_error node_has_attribute_includes(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_dashmatch(void *pw, void *n,
+static css_error node_has_attribute_dashmatch(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1302,7 +435,7 @@ css_error node_has_attribute_dashmatch(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_prefix(void *pw, void *n,
+static css_error node_has_attribute_prefix(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1337,7 +470,7 @@ css_error node_has_attribute_prefix(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_suffix(void *pw, void *n,
+static css_error node_has_attribute_suffix(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1376,7 +509,7 @@ css_error node_has_attribute_suffix(void *pw, void *n,
return CSS_OK;
}
-css_error node_has_attribute_substring(void *pw, void *n,
+static css_error node_has_attribute_substring(void *pw, void *n,
const css_qname *qname,
lwc_string *value,
bool *match)
@@ -1424,7 +557,7 @@ css_error node_has_attribute_substring(void *pw, void *n,
return CSS_OK;
}
-css_error node_is_root(void *pw, void *n, bool *match)
+static css_error node_is_root(void *pw, void *n, bool *match)
{
node *node = n;
UNUSED(pw);
@@ -1434,7 +567,7 @@ css_error node_is_root(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_count_siblings(void *pw, void *n,
+static css_error node_count_siblings(void *pw, void *n,
bool same_name, bool after, int32_t *count)
{
int32_t cnt = 0;
@@ -1480,7 +613,7 @@ css_error node_count_siblings(void *pw, void *n,
return CSS_OK;
}
-css_error node_is_empty(void *pw, void *n, bool *match)
+static css_error node_is_empty(void *pw, void *n, bool *match)
{
node *node = n;
UNUSED(pw);
@@ -1490,7 +623,7 @@ css_error node_is_empty(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_link(void *pw, void *n, bool *match)
+static css_error node_is_link(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1502,7 +635,7 @@ css_error node_is_link(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_visited(void *pw, void *n, bool *match)
+static css_error node_is_visited(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1514,7 +647,7 @@ css_error node_is_visited(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_hover(void *pw, void *n, bool *match)
+static css_error node_is_hover(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1526,7 +659,7 @@ css_error node_is_hover(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_active(void *pw, void *n, bool *match)
+static css_error node_is_active(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1538,7 +671,7 @@ css_error node_is_active(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_focus(void *pw, void *n, bool *match)
+static css_error node_is_focus(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1550,7 +683,7 @@ css_error node_is_focus(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_enabled(void *pw, void *n, bool *match)
+static css_error node_is_enabled(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1562,7 +695,7 @@ css_error node_is_enabled(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_disabled(void *pw, void *n, bool *match)
+static css_error node_is_disabled(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1574,7 +707,7 @@ css_error node_is_disabled(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_checked(void *pw, void *n, bool *match)
+static css_error node_is_checked(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1586,7 +719,7 @@ css_error node_is_checked(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_target(void *pw, void *n, bool *match)
+static css_error node_is_target(void *pw, void *n, bool *match)
{
node *node = n;
@@ -1598,7 +731,7 @@ css_error node_is_target(void *pw, void *n, bool *match)
return CSS_OK;
}
-css_error node_is_lang(void *pw, void *n,
+static css_error node_is_lang(void *pw, void *n,
lwc_string *lang,
bool *match)
{
@@ -1613,7 +746,7 @@ css_error node_is_lang(void *pw, void *n,
return CSS_OK;
}
-css_error node_presentational_hint(void *pw, void *node,
+static css_error node_presentational_hint(void *pw, void *node,
uint32_t *nhints, css_hint **hints)
{
UNUSED(pw);
@@ -1625,7 +758,7 @@ css_error node_presentational_hint(void *pw, void *node,
return CSS_OK;
}
-css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
+static css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
{
UNUSED(pw);
@@ -1673,4 +806,773 @@ static css_error get_libcss_node_data(void *pw, void *n,
return CSS_OK;
}
+static css_unit_ctx unit_ctx = {
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+};
+
+static css_select_handler select_handler = {
+ CSS_SELECT_HANDLER_VERSION_1,
+
+ node_name,
+ node_classes,
+ node_id,
+ named_ancestor_node,
+ named_parent_node,
+ named_sibling_node,
+ named_generic_sibling_node,
+ parent_node,
+ sibling_node,
+ node_has_name,
+ node_has_class,
+ node_has_id,
+ node_has_attribute,
+ node_has_attribute_equal,
+ node_has_attribute_dashmatch,
+ node_has_attribute_includes,
+ node_has_attribute_prefix,
+ node_has_attribute_suffix,
+ node_has_attribute_substring,
+ node_is_root,
+ node_count_siblings,
+ node_is_empty,
+ node_is_link,
+ node_is_visited,
+ node_is_hover,
+ node_is_active,
+ node_is_focus,
+ node_is_enabled,
+ node_is_disabled,
+ node_is_checked,
+ node_is_target,
+ node_is_lang,
+ node_presentational_hint,
+ ua_default_for_property,
+
+ set_libcss_node_data,
+ get_libcss_node_data,
+};
+
+static css_error resolve_url(void *pw,
+ const char *base, lwc_string *rel, lwc_string **abs)
+{
+ UNUSED(pw);
+ UNUSED(base);
+
+ /* About as useless as possible */
+ *abs = lwc_string_ref(rel);
+
+ return CSS_OK;
+}
+
+static bool fail_because_lwc_leaked = false;
+
+static void
+printing_lwc_iterator(lwc_string *str, void *pw)
+{
+ UNUSED(pw);
+
+ printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
+ fail_because_lwc_leaked = true;
+}
+
+static css_error css_font_resolution_func(void *pw, lwc_string *name,
+ css_system_font *system_font)
+{
+ lwc_error err;
+
+ if (system_font == NULL) {
+ return CSS_BADPARM;
+ }
+
+ (void)(pw);
+
+ if (strncmp(lwc_string_data(name), "special-system-font",
+ lwc_string_length(name)) != 0) {
+ return CSS_INVALID;
+ }
+
+ system_font->style = CSS_FONT_STYLE_NORMAL;
+ system_font->variant = CSS_FONT_VARIANT_NORMAL;
+ system_font->weight = CSS_FONT_WEIGHT_NORMAL;
+ system_font->size.size = INTTOFIX(22);
+ system_font->size.unit = CSS_UNIT_PT;
+ system_font->line_height.size = INTTOFIX(33);
+ system_font->line_height.unit = CSS_UNIT_EM;
+ err = lwc_intern_string("special-system-font",
+ strlen("special-system-font"),
+ &system_font->family);
+ if (err != lwc_error_ok) {
+ return CSS_NOMEM;
+ }
+
+ return CSS_OK;
+}
+
+static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
+{
+ css_stylesheet_params params;
+ const char *p;
+ const char *end = data + len;
+ css_origin origin = CSS_ORIGIN_AUTHOR;
+ css_stylesheet *sheet;
+ sheet_ctx *temp;
+ char *media = NULL;
+
+ /* <origin> <media_list>? */
+
+ /* Find end of origin */
+ for (p = data; p < end; p++) {
+ if (isspace(*p))
+ break;
+ }
+
+ if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
+ origin = CSS_ORIGIN_AUTHOR;
+ else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
+ origin = CSS_ORIGIN_USER;
+ else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
+ origin = CSS_ORIGIN_UA;
+ else
+ assert(0 && "Unknown stylesheet origin");
+
+ /* Skip any whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ assert(end >= p);
+ media = malloc(end - p + 1);
+ assert(media != NULL);
+ memcpy(media, p, end - p);
+ media[end - p] = '\0';
+
+ params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
+ params.level = CSS_LEVEL_21;
+ params.charset = "UTF-8";
+ params.url = "foo";
+ params.title = "foo";
+ params.allow_quirks = false;
+ params.inline_style = false;
+ params.resolve = resolve_url;
+ params.resolve_pw = NULL;
+ params.import = NULL;
+ params.import_pw = NULL;
+ params.color = NULL;
+ params.color_pw = NULL;
+ params.font = css_font_resolution_func;
+ params.font_pw = NULL;
+
+ /** \todo How are we going to handle @import? */
+ assert(css_stylesheet_create(&params, &sheet) == CSS_OK);
+
+ /* Extend array of sheets and append new sheet to it */
+ temp = realloc(ctx->sheets,
+ (ctx->n_sheets + 1) * sizeof(sheet_ctx));
+ assert(temp != NULL);
+
+ ctx->sheets = temp;
+
+ ctx->sheets[ctx->n_sheets].sheet = sheet;
+ ctx->sheets[ctx->n_sheets].origin = origin;
+ ctx->sheets[ctx->n_sheets].media = media;
+
+ ctx->n_sheets++;
+}
+
+static void css__parse_media_list(const char **data, size_t *len, css_media *media)
+{
+ const char *p = *data;
+ const char *end = p + *len;
+ uint64_t result = 0;
+
+ /* <medium> [ ',' <medium> ]* */
+
+ while (p < end) {
+ const char *start = p;
+
+ /* consume a medium */
+ while (isspace(*p) == false && *p != ',')
+ p++;
+
+ if (p - start == 10 &&
+ strncasecmp(start, "projection", 10) == 0)
+ result |= CSS_MEDIA_PROJECTION;
+ else if (p - start == 8 &&
+ strncasecmp(start, "handheld", 8) == 0)
+ result |= CSS_MEDIA_HANDHELD;
+ else if (p - start == 8 &&
+ strncasecmp(start, "embossed", 8) == 0)
+ result |= CSS_MEDIA_EMBOSSED;
+ else if (p - start == 7 &&
+ strncasecmp(start, "braille", 7) == 0)
+ result |= CSS_MEDIA_BRAILLE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "speech", 6) == 0)
+ result |= CSS_MEDIA_SPEECH;
+ else if (p - start == 6 &&
+ strncasecmp(start, "screen", 6) == 0)
+ result |= CSS_MEDIA_SCREEN;
+ else if (p - start == 5 &&
+ strncasecmp(start, "print", 5) == 0)
+ result |= CSS_MEDIA_PRINT;
+ else if (p - start == 5 &&
+ strncasecmp(start, "aural", 5) == 0)
+ result |= CSS_MEDIA_AURAL;
+ else if (p - start == 3 &&
+ strncasecmp(start, "tty", 3) == 0)
+ result |= CSS_MEDIA_TTY;
+ else if (p - start == 3 &&
+ strncasecmp(start, "all", 3) == 0)
+ result |= CSS_MEDIA_ALL;
+ else if (p - start == 2 &&
+ strncasecmp(start, "tv", 2) == 0)
+ result |= CSS_MEDIA_TV;
+ else
+ assert(0 && "Unknown media type");
+
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
+ break;
+
+ /* Consume comma */
+ p++;
+
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
+ }
+
+ media->type = result;
+
+ *data = p;
+ *len = end - p;
+}
+
+static void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
+{
+ const char *p = *data;
+ const char *end = p + *len;
+
+ /* <pseudo> [ ',' <pseudo> ]* */
+
+ *element = CSS_PSEUDO_ELEMENT_NONE;
+
+ while (p < end) {
+ const char *start = p;
+
+ /* consume a pseudo */
+ while (isspace(*p) == false && *p != ',')
+ p++;
+
+ /* Pseudo elements */
+ if (p - start == 12 &&
+ strncasecmp(start, "first-letter", 12) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
+ else if (p - start == 10 &&
+ strncasecmp(start, "first-line", 10) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "before", 6) == 0)
+ *element = CSS_PSEUDO_ELEMENT_BEFORE;
+ else if (p - start == 5 &&
+ strncasecmp(start, "after", 5) == 0)
+ *element = CSS_PSEUDO_ELEMENT_AFTER;
+ else
+ assert(0 && "Unknown pseudo");
+
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
+ break;
+
+ /* Consume comma */
+ p++;
+
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
+ }
+
+ *data = p;
+ *len = end - p;
+}
+
+static void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
+{
+ const char *p = data;
+ const char *end = data + len;
+ size_t left;
+
+ /* [ <media_list> <pseudo>? ] ? */
+
+ ctx->media.type = CSS_MEDIA_ALL;
+ ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
+
+ /* Consume any leading whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ if (p < end) {
+ left = end - p;
+
+ css__parse_media_list(&p, &left, &ctx->media);
+
+ end = p + left;
+ }
+
+ if (p < end) {
+ left = end - p;
+
+ css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
+ }
+}
+
+static void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
+{
+ while (ctx->expused + len >= ctx->explen) {
+ size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
+ char *temp = realloc(ctx->exp, required);
+ if (temp == NULL) {
+ assert(0 && "No memory for expected output");
+ }
+
+ ctx->exp = temp;
+ ctx->explen = required;
+ }
+
+ memcpy(ctx->exp + ctx->expused, data, len);
+
+ ctx->expused += len;
+}
+
+static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
+{
+ const char *p = data;
+ const char *end = data + len;
+ const char *name = NULL;
+ const char *value = NULL;
+ size_t namelen = 0;
+ size_t valuelen = 0;
+ uint32_t depth = 0;
+ bool target = false;
+
+ /* ' '{depth+1} [ <element> '*'? | <attr> ]
+ *
+ * <element> ::= [^=*[:space:]]+
+ * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
+ */
+
+ while (p < end && isspace(*p)) {
+ depth++;
+ p++;
+ }
+ depth--;
+
+ /* Get element/attribute name */
+ name = p;
+ while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
+ namelen++;
+ p++;
+ }
+
+ /* Skip whitespace */
+ while (p < end && isspace(*p))
+ p++;
+ if (p < end && *p == '=') {
+ /* Attribute value */
+ p++;
+
+ value = p;
+
+ while (p < end && isspace(*p) == false) {
+ valuelen++;
+ p++;
+ }
+ } else if (p < end && *p == '*') {
+ /* Element is target node */
+ target = true;
+ }
+
+ if (value == NULL) {
+ /* We have an element, so create it */
+ node *n = malloc(sizeof(node));
+ assert(n != NULL);
+
+ memset(n, 0, sizeof(node));
+
+ lwc_intern_string(name, namelen, &n->name);
+
+ /* Insert it into tree */
+ if (ctx->tree == NULL) {
+ ctx->tree = n;
+ } else {
+ assert(depth > 0);
+ assert(depth <= ctx->depth + 1);
+
+ /* Find node to insert into */
+ while (depth <= ctx->depth) {
+ ctx->depth--;
+ ctx->current = ctx->current->parent;
+ }
+
+ /* Insert into current node */
+ if (ctx->current->children == NULL) {
+ ctx->current->children = n;
+ ctx->current->last_child = n;
+ } else {
+ ctx->current->last_child->next = n;
+ n->prev = ctx->current->last_child;
+
+ ctx->current->last_child = n;
+ }
+ n->parent = ctx->current;
+ }
+
+ ctx->current = n;
+ ctx->depth = depth;
+
+ /* Mark the target, if it's us */
+ if (target)
+ ctx->target = n;
+ } else {
+ /* New attribute */
+ bool amatch = false;
+ attribute *attr;
+ node *n = ctx->current;
+
+ attribute *temp = realloc(n->attrs,
+ (n->n_attrs + 1) * sizeof(attribute));
+ assert(temp != NULL);
+
+ n->attrs = temp;
+
+ attr = &n->attrs[n->n_attrs];
+
+ lwc_intern_string(name, namelen, &attr->name);
+ lwc_intern_string(value, valuelen, &attr->value);
+
+ assert(lwc_string_caseless_isequal(
+ n->attrs[n->n_attrs].name,
+ ctx->attr_class, &amatch) == lwc_error_ok);
+ if (amatch == true) {
+ n->classes = realloc(NULL, sizeof(lwc_string **));
+ assert(n->classes != NULL);
+
+ n->classes[0] = lwc_string_ref(
+ n->attrs[n->n_attrs].
+ value);
+ n->n_classes = 1;
+ }
+
+ n->n_attrs++;
+ }
+}
+
+
+static void run_test_select_tree(css_select_ctx *select,
+ node *node, line_ctx *ctx,
+ char *buf, size_t *buflen)
+{
+ css_select_results *sr;
+ struct node *n = NULL;
+
+ if (node->parent == NULL) {
+ unit_ctx.root_style = NULL;
+ }
+
+
+ assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
+ &select_handler, ctx, &sr) == CSS_OK);
+
+ if (node->parent != NULL) {
+ css_computed_style *composed;
+ assert(css_computed_style_compose(
+ node->parent->sr->styles[ctx->pseudo_element],
+ sr->styles[ctx->pseudo_element],
+ &unit_ctx,
+ &composed) == CSS_OK);
+ css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
+ sr->styles[ctx->pseudo_element] = composed;
+ }
+
+ node->sr = sr;
+
+ if (node == ctx->target) {
+ dump_computed_style(sr->styles[ctx->pseudo_element],
+ buf, buflen);
+ }
+
+ if (node->parent == NULL) {
+ unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
+ }
+
+ for (n = node->children; n != NULL; n = n->next) {
+ run_test_select_tree(select, n, ctx, buf, buflen);
+ }
+}
+
+static void show_differences(size_t len, const char *exp, const char *res)
+{
+ const char *pos_exp, *opos_exp;
+ const char *pos_res, *opos_res;
+
+ opos_exp = pos_exp = exp;
+ opos_res = pos_res = res;
+
+ printf("Line differences:\n");
+ while (pos_exp < exp + len && pos_res < res + len) {
+ if (*pos_exp == '\n' && *pos_res == '\n') {
+ if (pos_exp - opos_exp != pos_res - opos_res ||
+ memcmp(opos_exp, opos_res,
+ pos_exp - opos_exp) != 0) {
+ printf("Expected:\t%.*s\n",
+ (int)(pos_exp - opos_exp),
+ opos_exp);
+ printf(" Result:\t%.*s\n",
+ (int)(pos_res - opos_res),
+ opos_res);
+ printf("\n");
+ }
+ opos_exp = ++pos_exp;
+ opos_res = ++pos_res;
+ } else if (*pos_exp == '\n') {
+ pos_res++;
+ } else if (*pos_res == '\n') {
+ pos_exp++;
+ } else {
+ pos_exp++;
+ pos_res++;
+ }
+ }
+}
+
+static void destroy_tree(node *root)
+{
+ node *n, *p;
+ uint32_t i;
+
+ for (n = root->children; n != NULL; n = p) {
+ p = n->next;
+
+ destroy_tree(n);
+ }
+
+ css_select_results_destroy(root->sr);
+
+ for (i = 0; i < root->n_attrs; ++i) {
+ lwc_string_unref(root->attrs[i].name);
+ lwc_string_unref(root->attrs[i].value);
+ }
+ free(root->attrs);
+
+ if (root->classes != NULL) {
+ for (i = 0; i < root->n_classes; ++i) {
+ lwc_string_unref(root->classes[i]);
+ }
+ free(root->classes);
+ }
+
+ if (root->libcss_node_data != NULL) {
+ css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
+ NULL, root, NULL, root->libcss_node_data);
+ }
+
+ lwc_string_unref(root->name);
+ free(root);
+}
+
+static void run_test(line_ctx *ctx, const char *exp, size_t explen)
+{
+ css_select_ctx *select;
+ css_select_results *results;
+ uint32_t i;
+ char *buf;
+ size_t buflen;
+ static int testnum;
+
+ UNUSED(exp);
+
+ buf = malloc(8192);
+ if (buf == NULL) {
+ assert(0 && "No memory for result data");
+ }
+ buflen = 8192;
+
+ assert(css_select_ctx_create(&select) == CSS_OK);
+
+ for (i = 0; i < ctx->n_sheets; i++) {
+ assert(css_select_ctx_append_sheet(select,
+ ctx->sheets[i].sheet, ctx->sheets[i].origin,
+ ctx->sheets[i].media) == CSS_OK);
+ }
+
+ testnum++;
+
+ run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
+
+ results = ctx->target->sr;
+ assert(results->styles[ctx->pseudo_element] != NULL);
+
+ if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
+ size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
+ printf("Expected (%u):\n%.*s\n",
+ (int) explen, (int) explen, exp);
+ printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
+ (int) (8192 - buflen), buf);
+
+ show_differences(len, exp, buf);
+ assert(0 && "Result doesn't match expected");
+ }
+
+ /* Clean up */
+ css_select_ctx_destroy(select);
+ destroy_tree(ctx->tree);
+
+ for (i = 0; i < ctx->n_sheets; i++) {
+ css_stylesheet_destroy(ctx->sheets[i].sheet);
+ free(ctx->sheets[i].media);
+ }
+
+ ctx->tree = NULL;
+ ctx->current = NULL;
+ ctx->depth = 0;
+ ctx->n_sheets = 0;
+ free(ctx->sheets);
+ ctx->sheets = NULL;
+ ctx->target = NULL;
+
+ free(buf);
+
+ printf("Test %d: PASS\n", testnum);
+}
+
+static bool handle_line(const char *data, size_t datalen, void *pw)
+{
+ line_ctx *ctx = (line_ctx *) pw;
+ css_error error;
+
+ if (data[0] == '#') {
+ if (ctx->intree) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else {
+ /* Assume start of stylesheet */
+ css__parse_sheet(ctx, data + 1, datalen - 1);
+
+ ctx->intree = false;
+ ctx->insheet = true;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ } else if (ctx->insheet) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
+
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else if (strncasecmp(data+1, "ua", 2) == 0 ||
+ strncasecmp(data+1, "user", 4) == 0 ||
+ strncasecmp(data+1, "author", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
+
+ css__parse_sheet(ctx, data + 1, datalen - 1);
+ } else {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data,
+ datalen);
+ assert(error == CSS_OK ||
+ error == CSS_NEEDDATA);
+ }
+ } else if (ctx->inerrors) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = true;
+ } else if (ctx->inexp) {
+ /* This marks end of testcase, so run it */
+ run_test(ctx, ctx->exp, ctx->expused);
+
+ ctx->expused = 0;
+
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ } else {
+ /* Start state */
+ if (strncasecmp(data+1, "tree", 4) == 0) {
+ css__parse_tree(ctx, data + 5, datalen - 5);
+
+ ctx->intree = true;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ }
+ } else {
+ if (ctx->intree) {
+ /* Not interested in the '|' */
+ css__parse_tree_data(ctx, data + 1, datalen - 1);
+ } else if (ctx->insheet) {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data, datalen);
+ assert(error == CSS_OK || error == CSS_NEEDDATA);
+ } else if (ctx->inexp) {
+ css__parse_expected(ctx, data, datalen);
+ }
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ line_ctx ctx;
+
+ if (argc != 2) {
+ printf("Usage: %s <filename>\n", argv[0]);
+ return 1;
+ }
+
+ memset(&ctx, 0, sizeof(ctx));
+
+
+ lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
+ lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
+
+ assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
+
+ /* and run final test */
+ if (ctx.tree != NULL)
+ run_test(&ctx, ctx.exp, ctx.expused);
+
+ free(ctx.exp);
+
+ lwc_string_unref(ctx.attr_class);
+ lwc_string_unref(ctx.attr_id);
+
+ lwc_iterate_strings(printing_lwc_iterator, NULL);
+
+ assert(fail_because_lwc_leaked == false);
+
+ printf("PASS\n");
+ return 0;
+}