hyper-html-api 0.5.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/conformance/MANIFEST.json +6 -0
- package/conformance/cases/basic-scalar-and-list.expected.json +7 -0
- package/conformance/cases/basic-scalar-and-list.html +4 -0
- package/conformance/cases/basic-scalar-and-list.meta +4 -0
- package/conformance/cases/basic-scalar-and-list.parsed.json +4 -0
- package/conformance/cases/basic-scalar-and-list.rules +1 -0
- package/conformance/cases/cms-template-skipped-by-default.expected.json +7 -0
- package/conformance/cases/cms-template-skipped-by-default.html +7 -0
- package/conformance/cases/cms-template-skipped-by-default.meta +7 -0
- package/conformance/cases/cms-template-skipped-by-default.parsed.json +5 -0
- package/conformance/cases/cms-template-skipped-by-default.rules +1 -0
- package/conformance/cases/depth-at-limit-ok.expected.json +41 -0
- package/conformance/cases/depth-at-limit-ok.html +3 -0
- package/conformance/cases/depth-at-limit-ok.meta +6 -0
- package/conformance/cases/depth-at-limit-ok.parsed.json +41 -0
- package/conformance/cases/depth-at-limit-ok.rules +1 -0
- package/conformance/cases/depth-exceeded-path-contains-selector.error.json +5 -0
- package/conformance/cases/depth-exceeded-path-contains-selector.html +3 -0
- package/conformance/cases/depth-exceeded-path-contains-selector.meta +9 -0
- package/conformance/cases/depth-exceeded-path-contains-selector.parsed.json +43 -0
- package/conformance/cases/depth-exceeded-path-contains-selector.rules +1 -0
- package/conformance/cases/depth-exceeded.error.json +5 -0
- package/conformance/cases/depth-exceeded.html +3 -0
- package/conformance/cases/depth-exceeded.meta +6 -0
- package/conformance/cases/depth-exceeded.parsed.json +43 -0
- package/conformance/cases/depth-exceeded.rules +1 -0
- package/conformance/cases/props-boolean-on-any-element.expected.json +5 -0
- package/conformance/cases/props-boolean-on-any-element.html +3 -0
- package/conformance/cases/props-boolean-on-any-element.meta +7 -0
- package/conformance/cases/props-boolean-on-any-element.parsed.json +5 -0
- package/conformance/cases/props-boolean-on-any-element.rules +1 -0
- package/conformance/cases/props-empty-attr-vs-empty-prop.expected.json +4 -0
- package/conformance/cases/props-empty-attr-vs-empty-prop.html +3 -0
- package/conformance/cases/props-empty-attr-vs-empty-prop.meta +6 -0
- package/conformance/cases/props-empty-attr-vs-empty-prop.parsed.json +4 -0
- package/conformance/cases/props-empty-attr-vs-empty-prop.rules +1 -0
- package/conformance/cases/props-null-set.expected.json +9 -0
- package/conformance/cases/props-null-set.html +3 -0
- package/conformance/cases/props-null-set.meta +7 -0
- package/conformance/cases/props-null-set.parsed.json +9 -0
- package/conformance/cases/props-null-set.rules +1 -0
- package/conformance/cases/props-readonly-always-false.expected.json +4 -0
- package/conformance/cases/props-readonly-always-false.html +4 -0
- package/conformance/cases/props-readonly-always-false.meta +11 -0
- package/conformance/cases/props-readonly-always-false.parsed.json +4 -0
- package/conformance/cases/props-readonly-always-false.rules +1 -0
- package/conformance/cases/props-select-textarea-value-null.expected.json +5 -0
- package/conformance/cases/props-select-textarea-value-null.html +5 -0
- package/conformance/cases/props-select-textarea-value-null.meta +8 -0
- package/conformance/cases/props-select-textarea-value-null.parsed.json +5 -0
- package/conformance/cases/props-select-textarea-value-null.rules +1 -0
- package/conformance/cases/props-tagname-and-nodetype.expected.json +5 -0
- package/conformance/cases/props-tagname-and-nodetype.html +3 -0
- package/conformance/cases/props-tagname-and-nodetype.meta +6 -0
- package/conformance/cases/props-tagname-and-nodetype.parsed.json +5 -0
- package/conformance/cases/props-tagname-and-nodetype.rules +1 -0
- package/conformance/cases/props-type-is-node-type.expected.json +5 -0
- package/conformance/cases/props-type-is-node-type.html +5 -0
- package/conformance/cases/props-type-is-node-type.meta +11 -0
- package/conformance/cases/props-type-is-node-type.parsed.json +5 -0
- package/conformance/cases/props-type-is-node-type.rules +1 -0
- package/conformance/cases/rules-duplicate-keys-last-wins.expected.json +3 -0
- package/conformance/cases/rules-duplicate-keys-last-wins.html +4 -0
- package/conformance/cases/rules-duplicate-keys-last-wins.meta +5 -0
- package/conformance/cases/rules-duplicate-keys-last-wins.parsed.json +3 -0
- package/conformance/cases/rules-duplicate-keys-last-wins.rules +1 -0
- package/conformance/cases/rules-iterate-dot-leading-works.expected.json +10 -0
- package/conformance/cases/rules-iterate-dot-leading-works.html +3 -0
- package/conformance/cases/rules-iterate-dot-leading-works.meta +6 -0
- package/conformance/cases/rules-iterate-dot-leading-works.parsed.json +8 -0
- package/conformance/cases/rules-iterate-dot-leading-works.rules +1 -0
- package/conformance/cases/rules-iterate-lookahead-quoted.error.json +5 -0
- package/conformance/cases/rules-iterate-lookahead-quoted.html +3 -0
- package/conformance/cases/rules-iterate-lookahead-quoted.meta +7 -0
- package/conformance/cases/rules-iterate-lookahead-quoted.rules +1 -0
- package/conformance/cases/rules-iterate-lookahead-unquoted.error.json +5 -0
- package/conformance/cases/rules-iterate-lookahead-unquoted.html +3 -0
- package/conformance/cases/rules-iterate-lookahead-unquoted.meta +8 -0
- package/conformance/cases/rules-iterate-lookahead-unquoted.parsed.json +3 -0
- package/conformance/cases/rules-iterate-lookahead-unquoted.rules +1 -0
- package/conformance/cases/rules-lastindexof-at-split.expected.json +3 -0
- package/conformance/cases/rules-lastindexof-at-split.html +3 -0
- package/conformance/cases/rules-lastindexof-at-split.meta +11 -0
- package/conformance/cases/rules-lastindexof-at-split.parsed.json +3 -0
- package/conformance/cases/rules-lastindexof-at-split.rules +1 -0
- package/conformance/cases/rules-primitives-extract-null.expected.json +5 -0
- package/conformance/cases/rules-primitives-extract-null.html +3 -0
- package/conformance/cases/rules-primitives-extract-null.meta +6 -0
- package/conformance/cases/rules-primitives-extract-null.parsed.json +5 -0
- package/conformance/cases/rules-primitives-extract-null.rules +1 -0
- package/conformance/cases/rules-proto-key-omitted.expected.json +3 -0
- package/conformance/cases/rules-proto-key-omitted.html +3 -0
- package/conformance/cases/rules-proto-key-omitted.meta +7 -0
- package/conformance/cases/rules-proto-key-omitted.parsed.json +6 -0
- package/conformance/cases/rules-proto-key-omitted.rules +1 -0
- package/conformance/cases/rules-quoted-attr-in-unquoted-selector.error.json +5 -0
- package/conformance/cases/rules-quoted-attr-in-unquoted-selector.html +4 -0
- package/conformance/cases/rules-quoted-attr-in-unquoted-selector.meta +5 -0
- package/conformance/cases/rules-quoted-attr-in-unquoted-selector.rules +1 -0
- package/conformance/cases/rules-trailing-comma-dropped.expected.json +3 -0
- package/conformance/cases/rules-trailing-comma-dropped.html +3 -0
- package/conformance/cases/rules-trailing-comma-dropped.meta +5 -0
- package/conformance/cases/rules-trailing-comma-dropped.parsed.json +3 -0
- package/conformance/cases/rules-trailing-comma-dropped.rules +1 -0
- package/conformance/cases/rules-unwhitelisted-pseudo-breaks-tokenizer.error.json +5 -0
- package/conformance/cases/rules-unwhitelisted-pseudo-breaks-tokenizer.html +3 -0
- package/conformance/cases/rules-unwhitelisted-pseudo-breaks-tokenizer.meta +7 -0
- package/conformance/cases/rules-unwhitelisted-pseudo-breaks-tokenizer.rules +1 -0
- package/conformance/cases/rules-whitespace-clings.expected.json +4 -0
- package/conformance/cases/rules-whitespace-clings.html +4 -0
- package/conformance/cases/rules-whitespace-clings.meta +6 -0
- package/conformance/cases/rules-whitespace-clings.parsed.json +4 -0
- package/conformance/cases/rules-whitespace-clings.rules +1 -0
- package/conformance/cases/selector-unknown-pseudo-is-500.error.json +5 -0
- package/conformance/cases/selector-unknown-pseudo-is-500.html +4 -0
- package/conformance/cases/selector-unknown-pseudo-is-500.meta +7 -0
- package/conformance/cases/selector-unknown-pseudo-is-500.parsed.json +3 -0
- package/conformance/cases/selector-unknown-pseudo-is-500.rules +1 -0
- package/conformance/cases/tag-basic.expected.json +7 -0
- package/conformance/cases/tag-basic.html +5 -0
- package/conformance/cases/tag-basic.meta +6 -0
- package/conformance/cases/tag-basic.parsed.json +4 -0
- package/conformance/cases/tag-duplicate-names-first-wins.expected.json +3 -0
- package/conformance/cases/tag-duplicate-names-first-wins.html +6 -0
- package/conformance/cases/tag-duplicate-names-first-wins.meta +7 -0
- package/conformance/cases/tag-duplicate-names-first-wins.parsed.json +3 -0
- package/conformance/cases/tag-missing.error.json +5 -0
- package/conformance/cases/tag-missing.html +4 -0
- package/conformance/cases/tag-missing.meta +8 -0
- package/conformance/cases/tag-name-is-space-separated.expected.json +3 -0
- package/conformance/cases/tag-name-is-space-separated.html +4 -0
- package/conformance/cases/tag-name-is-space-separated.meta +6 -0
- package/conformance/cases/tag-name-is-space-separated.parsed.json +3 -0
- package/conformance/cases/tag-relaxed-body.expected.json +7 -0
- package/conformance/cases/tag-relaxed-body.html +5 -0
- package/conformance/cases/tag-relaxed-body.meta +7 -0
- package/conformance/cases/tag-relaxed-body.parsed.json +4 -0
- package/conformance/cases/tag-wrong-version.error.json +5 -0
- package/conformance/cases/tag-wrong-version.html +4 -0
- package/conformance/cases/tag-wrong-version.meta +6 -0
- package/conformance/cases/template-simple-vs-combinator.expected.json +7 -0
- package/conformance/cases/template-simple-vs-combinator.html +4 -0
- package/conformance/cases/template-simple-vs-combinator.meta +8 -0
- package/conformance/cases/template-simple-vs-combinator.parsed.json +4 -0
- package/conformance/cases/template-simple-vs-combinator.rules +1 -0
- package/conformance/cases/text-root-leaks-rules-tag.expected.json +4 -0
- package/conformance/cases/text-root-leaks-rules-tag.html +4 -0
- package/conformance/cases/text-root-leaks-rules-tag.meta +7 -0
- package/conformance/cases/text-root-leaks-rules-tag.parsed.json +4 -0
- package/conformance/cases/text-root-leaks-rules-tag.rules +1 -0
- package/conformance/cases/text-trim-asymmetry.expected.json +5 -0
- package/conformance/cases/text-trim-asymmetry.html +5 -0
- package/conformance/cases/text-trim-asymmetry.meta +6 -0
- package/conformance/cases/text-trim-asymmetry.parsed.json +5 -0
- package/conformance/cases/text-trim-asymmetry.rules +1 -0
- package/dist/hyper-html-api.engine.min.js +1 -1
- package/dist/hyper-html-api.min.js +4 -4
- package/dist/hyper-html-api.upgrade.min.js +2 -2
- package/package.json +7 -4
- package/src/cms/form-builder.js +3 -2
- package/src/dom-api.js +5 -0
- package/src/engine/apply.js +6 -3
- package/src/engine/diff.js +70 -13
- package/src/engine/extract.js +3 -2
- package/src/engine/index.js +1 -0
- package/src/engine/rule-syntax.js +43 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{title:"h1",items:".i[]"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: [cms-template] is excluded from find() BY DEFAULT, no opt-in, because a seed row is not
|
|
5
|
+
note: data for any consumer. The test is closest(), so it is ancestor-or-self: the marked li
|
|
6
|
+
note: drops out and so does a plain span nested inside a marked li. That is wider than the
|
|
7
|
+
note: rules-tag filter, which only ever tests the matched node itself.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"plain":".plain[]","self":".self[]","descendant":".descendant[]"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"a": {
|
|
3
|
+
"a": {
|
|
4
|
+
"a": {
|
|
5
|
+
"a": {
|
|
6
|
+
"a": {
|
|
7
|
+
"a": {
|
|
8
|
+
"a": {
|
|
9
|
+
"a": {
|
|
10
|
+
"a": {
|
|
11
|
+
"a": {
|
|
12
|
+
"a": {
|
|
13
|
+
"a": {
|
|
14
|
+
"a": {
|
|
15
|
+
"a": {
|
|
16
|
+
"a": {
|
|
17
|
+
"a": {
|
|
18
|
+
"a": {
|
|
19
|
+
"a": {
|
|
20
|
+
"a": {
|
|
21
|
+
"a": "Hello"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: The limit is exact. MAX_RULE_DEPTH is 20 and the guard is `depth > 20`, and the root rule
|
|
5
|
+
note: is visited at depth 0, so 20 nested objects put the leaf string at depth 20 and it still
|
|
6
|
+
note: extracts. One more object throws; see depth-exceeded.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"a": {
|
|
3
|
+
"a": {
|
|
4
|
+
"a": {
|
|
5
|
+
"a": {
|
|
6
|
+
"a": {
|
|
7
|
+
"a": {
|
|
8
|
+
"a": {
|
|
9
|
+
"a": {
|
|
10
|
+
"a": {
|
|
11
|
+
"a": {
|
|
12
|
+
"a": {
|
|
13
|
+
"a": {
|
|
14
|
+
"a": {
|
|
15
|
+
"a": {
|
|
16
|
+
"a": {
|
|
17
|
+
"a": {
|
|
18
|
+
"a": {
|
|
19
|
+
"a": {
|
|
20
|
+
"a": {
|
|
21
|
+
"a": "h1"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:"h1"}}}}}}}}}}}}}}}}}}}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "MaxRuleDepthExceeded",
|
|
3
|
+
"message": "rule depth exceeded 20 at path: selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector.selector",
|
|
4
|
+
"status": 400
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
tier: 3
|
|
2
|
+
face: query
|
|
3
|
+
expect: error
|
|
4
|
+
note: DIVERGENCE. Byte-for-byte the same MaxRuleDepthExceeded as depth-exceeded, at the same
|
|
5
|
+
note: depth, differing only in that the rule key is named `selector`, which puts the word into
|
|
6
|
+
note: the message path. The JS hosts classify by sniffing the message, so this answers 400 while
|
|
7
|
+
note: depth-exceeded answers 500. A host that maps by error TYPE gives both cases one status,
|
|
8
|
+
note: so it must differ from the JS reference on one of the pair: 500 here, or 400 there.
|
|
9
|
+
note: Direction: the data in the rule keys is steering the HTTP status.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"selector": {
|
|
3
|
+
"selector": {
|
|
4
|
+
"selector": {
|
|
5
|
+
"selector": {
|
|
6
|
+
"selector": {
|
|
7
|
+
"selector": {
|
|
8
|
+
"selector": {
|
|
9
|
+
"selector": {
|
|
10
|
+
"selector": {
|
|
11
|
+
"selector": {
|
|
12
|
+
"selector": {
|
|
13
|
+
"selector": {
|
|
14
|
+
"selector": {
|
|
15
|
+
"selector": {
|
|
16
|
+
"selector": {
|
|
17
|
+
"selector": {
|
|
18
|
+
"selector": {
|
|
19
|
+
"selector": {
|
|
20
|
+
"selector": {
|
|
21
|
+
"selector": {
|
|
22
|
+
"selector": "h1"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:{selector:"h1"}}}}}}}}}}}}}}}}}}}}}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: error
|
|
4
|
+
note: 21 nested objects put the leaf at depth 21 and MaxRuleDepthExceeded throws, one level past
|
|
5
|
+
note: depth-at-limit-ok. The message carries the full key path. It contains neither "JSON" nor
|
|
6
|
+
note: "selector", so the reference host answers 500 for what is really a malformed request.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"a": {
|
|
3
|
+
"a": {
|
|
4
|
+
"a": {
|
|
5
|
+
"a": {
|
|
6
|
+
"a": {
|
|
7
|
+
"a": {
|
|
8
|
+
"a": {
|
|
9
|
+
"a": {
|
|
10
|
+
"a": {
|
|
11
|
+
"a": {
|
|
12
|
+
"a": {
|
|
13
|
+
"a": {
|
|
14
|
+
"a": {
|
|
15
|
+
"a": {
|
|
16
|
+
"a": {
|
|
17
|
+
"a": {
|
|
18
|
+
"a": {
|
|
19
|
+
"a": {
|
|
20
|
+
"a": {
|
|
21
|
+
"a": {
|
|
22
|
+
"a": "h1"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:{a:"h1"}}}}}}}}}}}}}}}}}}}}}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: The boolean-attribute names answer "false" on ANY element, not null. cheerio's prop()
|
|
5
|
+
note: recognizes checked/selected/disabled by name alone, with no check that the element could
|
|
6
|
+
note: carry them, so a plain div reports a definite "false" where every other absent property
|
|
7
|
+
note: reports null. The absent-vs-false distinction is lost.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"checked":"#d@checked","selected":"#d@selected","disabled":"#d@disabled"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: Empty reads split by route. An ordinary attribute goes through `return v ? v : null`, so
|
|
5
|
+
note: an empty attribute is indistinguishable from a missing one and reads null. A whitelisted
|
|
6
|
+
note: property goes through `v == null ? null : String(v)`, so class="" survives as "".
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"emptyAttr":"#d@data-empty","emptyProp":"#d@className"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: Seven whitelisted names that cheerio cannot answer. They are on the DOM property list, so
|
|
5
|
+
note: the read never falls back to attr(); cheerio's prop() has no value for them and returns
|
|
6
|
+
note: undefined, which readPropOrAttr turns into null. Layout and document metadata are all in
|
|
7
|
+
note: this set, so they read null on any server host, never 0 and never "".
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"dataset":"#d@dataset","classList":"#d@classList","childElementCount":"#d@childElementCount","baseURI":"#d@baseURI","offsetWidth":"#d@offsetWidth","documentURI":"#d@documentURI","contentType":"#d@contentType"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
tier: 3
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
skip: htmlclay=ships @readOnly fixed; fixed behavior asserted in htmlclay dataapi/props_test.go
|
|
5
|
+
note: @readOnly is always the string "false". The name is whitelisted, so the read goes through
|
|
6
|
+
note: prop(), which looks the name up in the attribs map, where the parser has already lowercased
|
|
7
|
+
note: it to `readonly`. The whitelist spelling can never match, so the boolean-attribute fallback
|
|
8
|
+
note: reports absent. Set and unset inputs are indistinguishable.
|
|
9
|
+
note: DIVERGENCE, direction JS-only. This case pins the WART so an upstream fix gets noticed.
|
|
10
|
+
note: htmlclay deliberately does not reproduce it and folds the name for the presence test, so a
|
|
11
|
+
note: readonly input reports "true".
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"set":"#t@readOnly","unset":"#u@readOnly"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
tier: 3
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: DIVERGENCE. cheerio reads @value out of the attribs map, and neither a select nor a
|
|
5
|
+
note: textarea has a value ATTRIBUTE, so both read null on this host. In a browser the DOM
|
|
6
|
+
note: adapter reads live properties: select@value is the selected option's value ("b") and
|
|
7
|
+
note: textarea@value is its text ("hello"). Direction: server null, browser a real string.
|
|
8
|
+
note: An input, whose value IS an attribute, agrees on both sides and is included as the control.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"select":"#s@value","textarea":"#ta@value","input":"#in@value"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: @tagName and @nodeName both uppercase, matching the DOM. @nodeType is the string "1", not
|
|
5
|
+
note: the number 1: readPropOrAttr String()s every property read, so the numeric node type
|
|
6
|
+
note: arrives as text and a consumer comparing it to 1 fails.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"tagName":"#d@tagName","nodeName":"#d@nodeName","nodeType":"#d@nodeType"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
tier: 3
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
skip: htmlclay=ships @type fixed; fixed behavior asserted in htmlclay dataapi/props_test.go
|
|
5
|
+
note: @type is NOT the type attribute. `type` is on the DOM property whitelist, and domhandler
|
|
6
|
+
note: nodes already carry a `type` field naming the node kind, so cheerio's prop() returns that
|
|
7
|
+
note: instead: "tag" for a normal element, "script" for a script, "style" for a style. Three
|
|
8
|
+
note: values, none of them the author's type="text".
|
|
9
|
+
note: DIVERGENCE, direction JS-only. This case pins the WART so an upstream fix gets noticed.
|
|
10
|
+
note: htmlclay deliberately does not reproduce it and returns the type attribute, because that API
|
|
11
|
+
note: has no existing htmlclay users and preserving the bug would buy nothing.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"input":"#t@type","script":"#s@type","style":"#y@type"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{a:"h1",a:".i"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tier: 1
|
|
2
|
+
face: query
|
|
3
|
+
expect: ok
|
|
4
|
+
note: The contrast case for the two rules-iterate-lookahead-* bugs. `.` is not in /[a-zA-Z_]/,
|
|
5
|
+
note: so the lookahead pushes a real BRACKET_OPEN and the iterate form parses as the pair it
|
|
6
|
+
note: looks like. Whether iteration works at all depends on the first character of its selector.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{nav:[.nav-item,{t:.}]}
|