diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/data/parse/properties.dat | 8 | ||||
-rw-r--r-- | test/data/parse2/INDEX | 2 | ||||
-rw-r--r-- | test/data/parse2/dodgy-media-block.dat | 2 | ||||
-rw-r--r-- | test/data/parse2/eof.dat | 30 | ||||
-rw-r--r-- | test/data/parse2/mq.dat | 83 | ||||
-rw-r--r-- | test/data/parse2/svg.dat | 79 | ||||
-rw-r--r-- | test/data/select/INDEX | 1 | ||||
-rw-r--r-- | test/data/select/defaulting.dat | 1478 | ||||
-rw-r--r-- | test/data/select/tests1.dat | 474 | ||||
-rw-r--r-- | test/dump.h | 36 | ||||
-rw-r--r-- | test/dump_computed.h | 57 | ||||
-rw-r--r-- | test/select.c | 1702 |
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(¶ms, &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(¶ms, &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; +} |