Move to pkg:lints (#169)
diff --git a/CHANGELOG.md b/CHANGELOG.md index b5c2c93..60c7daf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,3 +1,5 @@ +## 0.15.1-dev + ## 0.15.0 - Migrate to null safety.
diff --git a/analysis_options.yaml b/analysis_options.yaml index 87e8300..4133550 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml
@@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: strong-mode: implicit-casts: false
diff --git a/lib/dom.dart b/lib/dom.dart index 87ef15d..69ac436 100644 --- a/lib/dom.dart +++ b/lib/dom.dart
@@ -2,6 +2,8 @@ /// with dart:html, but it is missing many types and APIs. library dom; +// ignore_for_file: constant_identifier_names + // TODO(jmesserly): lots to do here. Originally I wanted to generate this using // our Blink IDL generator, but another idea is to directly use the excellent // http://dom.spec.whatwg.org/ and http://html.spec.whatwg.org/ and just @@ -66,10 +68,11 @@ } @override - bool operator ==(x) { - if (x is! AttributeName) return false; - return prefix == x.prefix && name == x.name && namespace == x.namespace; - } + bool operator ==(Object other) => + other is AttributeName && + prefix == other.prefix && + name == other.name && + namespace == other.namespace; } // http://dom.spec.whatwg.org/#parentnode @@ -214,6 +217,7 @@ // Implemented per: http://dom.spec.whatwg.org/#dom-node-textcontent String? get text => null; + set text(String? value) {} void append(Node node) => nodes.add(node); @@ -311,6 +315,7 @@ class Document extends Node with _ParentNode, _NonElementParentNode, _ElementAndDocument { Document() : super._(); + factory Document.html(String html) => parse(html); @override @@ -318,7 +323,9 @@ // TODO(jmesserly): optmize this if needed Element? get documentElement => querySelector('html'); + Element? get head => documentElement?.querySelector('head'); + Element? get body => documentElement?.querySelector('body'); /// Returns a fragment of HTML or XML that represents the element and its @@ -352,6 +359,7 @@ class DocumentFragment extends Node with _ParentNode, _NonElementParentNode { DocumentFragment() : super._(); + factory DocumentFragment.html(String html) => parseFragment(html); @override @@ -376,6 +384,7 @@ @override String? get text => _getText(this); + @override set text(String? value) => _setText(this, value); } @@ -426,6 +435,7 @@ int get nodeType => Node.TEXT_NODE; String get data => _data = _data.toString(); + set data(String value) { // Handle unsound null values. _data = identical(value, null) ? '' : value; @@ -448,6 +458,7 @@ @override String get text => data; + @override // Text has a non-nullable `text` field, while Node has a nullable field. set text(covariant String value) { @@ -561,6 +572,7 @@ @override String get text => _getText(this); + @override set text(String? value) => _setText(this, value); @@ -572,6 +584,7 @@ /// Can be set, to replace the contents of the element with nodes parsed from /// the given string. String get innerHtml => _innerHtml; + // TODO(jmesserly): deprecate in favor of: // <https://api.dartlang.org/apidocs/channels/stable/#dart-dom-html.Element@id_setInnerHtml> set innerHtml(String value) { @@ -650,7 +663,7 @@ } set id(String value) { - attributes['id'] = '$value'; + attributes['id'] = value; } // http://dom.spec.whatwg.org/#dom-element-classname @@ -660,7 +673,7 @@ } set className(String value) { - attributes['class'] = '$value'; + attributes['class'] = value; } /// The set of CSS classes applied to this element. @@ -695,6 +708,7 @@ @override String? get text => data; + @override set text(String? value) { data = value; @@ -718,18 +732,18 @@ } @override - void add(Node value) { - if (value is DocumentFragment) { - addAll(value.nodes); + void add(Node element) { + if (element is DocumentFragment) { + addAll(element.nodes); } else { - super.add(_setParent(value)); + super.add(_setParent(element)); } } void addLast(Node value) => add(value); @override - void addAll(Iterable<Node> collection) { + void addAll(Iterable<Node> iterable) { // Note: we need to be careful if collection is another NodeList. // In particular: // 1. we need to copy the items before updating their parent pointers, @@ -737,7 +751,7 @@ // 2. we should update parent pointers in reverse order. That way they // are removed from the original NodeList (if any) from the end, which // is faster. - final list = _flattenDocFragments(collection); + final list = _flattenDocFragments(iterable); for (var node in list.reversed) { _setParent(node); } @@ -745,11 +759,11 @@ } @override - void insert(int index, Node value) { - if (value is DocumentFragment) { - insertAll(index, value.nodes); + void insert(int index, Node element) { + if (element is DocumentFragment) { + insertAll(index, element.nodes); } else { - super.insert(index, _setParent(value)); + super.insert(index, _setParent(element)); } } @@ -757,7 +771,7 @@ Node removeLast() => super.removeLast()..parentNode = null; @override - Node removeAt(int i) => super.removeAt(i)..parentNode = null; + Node removeAt(int index) => super.removeAt(index)..parentNode = null; @override void clear() { @@ -781,17 +795,17 @@ // TODO(jmesserly): These aren't implemented in DOM _NodeListImpl, see // http://code.google.com/p/dart/issues/detail?id=5371 @override - void setRange(int start, int rangeLength, Iterable<Node> from, - [int startFrom = 0]) { - var fromVar = from as List<Node>; + void setRange(int start, int end, Iterable<Node> iterable, + [int skipCount = 0]) { + var fromVar = iterable as List<Node>; if (fromVar is NodeList) { // Note: this is presumed to make a copy - fromVar = fromVar.sublist(startFrom, startFrom + rangeLength); + fromVar = fromVar.sublist(skipCount, skipCount + end); } // Note: see comment in [addAll]. We need to be careful about the order of // operations if [from] is also a NodeList. - for (var i = rangeLength - 1; i >= 0; i--) { - this[start + i] = fromVar[startFrom + i]; + for (var i = end - 1; i >= 0; i--) { + this[start + i] = fromVar[skipCount + i]; } } @@ -802,11 +816,11 @@ } @override - void removeRange(int start, int rangeLength) { - for (var i = start; i < rangeLength; i++) { + void removeRange(int start, int end) { + for (var i = start; i < end; i++) { this[i].parentNode = null; } - super.removeRange(start, rangeLength); + super.removeRange(start, end); } @override @@ -826,9 +840,9 @@ } @override - void insertAll(int index, Iterable<Node> collection) { + void insertAll(int index, Iterable<Node> iterable) { // Note: we need to be careful how we copy nodes. See note in addAll. - final list = _flattenDocFragments(collection); + final list = _flattenDocFragments(iterable); for (var node in list.reversed) { _setParent(node); } @@ -876,8 +890,8 @@ List<Element> get _filtered => _childNodes.whereType<Element>().toList(); @override - void forEach(void Function(Element) f) { - _filtered.forEach(f); + void forEach(void Function(Element) action) { + _filtered.forEach(action); } @override @@ -901,8 +915,8 @@ String join([String separator = '']) => _filtered.join(separator); @override - void add(Element value) { - _childNodes.add(value); + void add(Element element) { + _childNodes.add(element); } @override @@ -932,12 +946,12 @@ } @override - void fillRange(int start, int end, [Element? fillValue]) { + void fillRange(int start, int end, [Element? fill]) { throw UnimplementedError(); } @override - void replaceRange(int start, int end, Iterable<Element> iterable) { + void replaceRange(int start, int end, Iterable<Element> newContents) { throw UnimplementedError(); } @@ -960,14 +974,16 @@ @override Iterable<T> map<T>(T Function(Element) f) => _filtered.map(f); + @override - Iterable<Element> where(bool Function(Element) f) => _filtered.where(f); + Iterable<Element> where(bool Function(Element) test) => _filtered.where(test); + @override Iterable<T> expand<T>(Iterable<T> Function(Element) f) => _filtered.expand(f); @override - void insert(int index, Element value) { - _childNodes.insert(index, value); + void insert(int index, Element element) { + _childNodes.insert(index, element); } @override @@ -1007,14 +1023,18 @@ } @override - bool every(bool Function(Element) f) => _filtered.every(f); + bool every(bool Function(Element) test) => _filtered.every(test); + @override - bool any(bool Function(Element) f) => _filtered.any(f); + bool any(bool Function(Element) test) => _filtered.any(test); + @override List<Element> toList({bool growable = true}) => List<Element>.from(this, growable: growable); + @override Set<Element> toSet() => Set<Element>.from(this); + @override Element firstWhere(bool Function(Element) test, {Element Function()? orElse}) { @@ -1040,17 +1060,23 @@ @override bool get isEmpty => _filtered.isEmpty; + @override int get length => _filtered.length; + @override Element operator [](int index) => _filtered[index]; + @override Iterator<Element> get iterator => _filtered.iterator; + @override List<Element> sublist(int start, [int? end]) => _filtered.sublist(start, end); + @override Iterable<Element> getRange(int start, int end) => _filtered.getRange(start, end); + @override int indexOf(Object? element, [int start = 0]) => // Cast forced by ListMixin https://github.com/dart-lang/sdk/issues/31311
diff --git a/lib/src/constants.dart b/lib/src/constants.dart index 2c013d4..e32e037 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart
@@ -75,7 +75,7 @@ 'unexpected-character-after-attribute-value': 'Unexpected character after attribute value.', 'eof-in-attribute-value-double-quote': - 'Unexpected end of file in attribute value (\".', + 'Unexpected end of file in attribute value (".', 'eof-in-attribute-value-single-quote': "Unexpected end of file in attribute value (').", 'eof-in-attribute-value-no-quotes': @@ -402,8 +402,8 @@ const spaceCharacters = ' \n\r\t\u000C'; -const int NEWLINE = 10; -const int RETURN = 13; +const int newLine = 10; +const int returnCode = 13; bool isWhitespace(String? char) { if (char == null) return false; @@ -413,9 +413,9 @@ bool isWhitespaceCC(int charCode) { switch (charCode) { case 9: // '\t' - case NEWLINE: // '\n' + case newLine: // '\n' case 12: // '\f' - case RETURN: // '\r' + case returnCode: // '\r' case 32: // ' ' return true; } @@ -433,11 +433,11 @@ // TODO(jmesserly): remove these in favor of the test functions const asciiLetters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; -const ZERO = 48; -const LOWER_A = 97; -const LOWER_Z = 122; -const UPPER_A = 65; -const UPPER_Z = 90; +const _zeroCode = 48; +const _lowerACode = 97; +const _lowerZCode = 122; +const _upperACode = 65; +const _upperZCode = 90; bool isLetterOrDigit(String? char) => isLetter(char) || isDigit(char); @@ -445,13 +445,14 @@ bool isLetter(String? char) { if (char == null) return false; final cc = char.codeUnitAt(0); - return cc >= LOWER_A && cc <= LOWER_Z || cc >= UPPER_A && cc <= UPPER_Z; + return cc >= _lowerACode && cc <= _lowerZCode || + cc >= _upperACode && cc <= _upperZCode; } bool isDigit(String? char) { if (char == null) return false; final cc = char.codeUnitAt(0); - return cc >= ZERO && cc < ZERO + 10; + return cc >= _zeroCode && cc < _zeroCode + 10; } bool isHexDigit(String? char) { @@ -491,8 +492,9 @@ String toAsciiLowerCase() => String.fromCharCodes(codeUnits.map(_asciiToLower)); - static int _asciiToLower(int c) => - (c >= UPPER_A && c <= UPPER_Z) ? c + LOWER_A - UPPER_A : c; + static int _asciiToLower(int c) => (c >= _upperACode && c <= _upperZCode) + ? c + _lowerACode - _upperACode + : c; } // Heading elements need to be ordered
diff --git a/lib/src/html_input_stream.dart b/lib/src/html_input_stream.dart index 60bf8f8..a0e490f 100644 --- a/lib/src/html_input_stream.dart +++ b/lib/src/html_input_stream.dart
@@ -96,7 +96,7 @@ var c = rawChars[i]; if (skipNewline) { skipNewline = false; - if (c == NEWLINE) continue; + if (c == newLine) continue; } final isSurrogatePair = _isSurrogatePair(rawChars, i); @@ -111,9 +111,9 @@ } wasSurrogatePair = isSurrogatePair; - if (c == RETURN) { + if (c == returnCode) { skipNewline = true; - c = NEWLINE; + c = newLine; } _chars.add(c);
diff --git a/lib/src/list_proxy.dart b/lib/src/list_proxy.dart index 61784c7..05086fa 100644 --- a/lib/src/list_proxy.dart +++ b/lib/src/list_proxy.dart
@@ -8,7 +8,7 @@ final List<E> _list = <E>[]; @override - bool remove(Object? item) => _list.remove(item); + bool remove(Object? element) => _list.remove(element); @override int get length => _list.length; @@ -32,16 +32,16 @@ } @override - void add(E value) { - _list.add(value); + void add(E element) { + _list.add(element); } @override - void insert(int index, E item) => _list.insert(index, item); + void insert(int index, E element) => _list.insert(index, element); @override - void addAll(Iterable<E> collection) { - _list.addAll(collection); + void addAll(Iterable<E> iterable) { + _list.addAll(iterable); } @override @@ -53,7 +53,7 @@ E removeAt(int index) => _list.removeAt(index); @override - void removeRange(int start, int length) { - _list.removeRange(start, length); + void removeRange(int start, int end) { + _list.removeRange(start, end); } }
diff --git a/lib/src/query_selector.dart b/lib/src/query_selector.dart index 8880cfe..b596745 100644 --- a/lib/src/query_selector.dart +++ b/lib/src/query_selector.dart
@@ -57,17 +57,17 @@ } @override - bool visitSelectorGroup(SelectorGroup group) => - group.selectors.any(visitSelector); + bool visitSelectorGroup(SelectorGroup node) => + node.selectors.any(visitSelector); @override - bool visitSelector(Selector selector) { + bool visitSelector(Selector node) { final old = _element; var result = true; // Note: evaluate selectors right-to-left as it's more efficient. int? combinator; - for (var s in selector.simpleSelectorSequences.reversed) { + for (var s in node.simpleSelectorSequences.reversed) { if (combinator == null) { result = s.simpleSelector.visit(this) as bool; } else if (combinator == TokenKind.COMBINATOR_DESCENDANT) { @@ -110,7 +110,7 @@ case TokenKind.COMBINATOR_NONE: break; default: - throw _unsupported(selector); + throw _unsupported(node); } if (_element == null) { @@ -131,8 +131,8 @@ FormatException("'$selector' is not a valid selector"); @override - bool visitPseudoClassSelector(PseudoClassSelector selector) { - switch (selector.name) { + bool visitPseudoClassSelector(PseudoClassSelector node) { + switch (node.name) { // http://dev.w3.org/csswg/selectors-4/#structural-pseudos // http://dev.w3.org/csswg/selectors-4/#the-root-pseudo @@ -175,17 +175,17 @@ } // :before, :after, :first-letter/line can't match DOM elements. - if (_isLegacyPsuedoClass(selector.name)) return false; + if (_isLegacyPsuedoClass(node.name)) return false; - throw _unimplemented(selector); + throw _unimplemented(node); } @override - bool visitPseudoElementSelector(PseudoElementSelector selector) { + bool visitPseudoElementSelector(PseudoElementSelector node) { // :before, :after, :first-letter/line can't match DOM elements. - if (_isLegacyPsuedoClass(selector.name)) return false; + if (_isLegacyPsuedoClass(node.name)) return false; - throw _unimplemented(selector); + throw _unimplemented(node); } static bool _isLegacyPsuedoClass(String name) { @@ -201,18 +201,18 @@ } @override - bool visitPseudoElementFunctionSelector(PseudoElementFunctionSelector s) => - throw _unimplemented(s); + bool visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) => + throw _unimplemented(node); @override - bool visitPseudoClassFunctionSelector(PseudoClassFunctionSelector selector) { - switch (selector.name) { + bool visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) { + switch (node.name) { // http://dev.w3.org/csswg/selectors-4/#child-index // http://dev.w3.org/csswg/selectors-4/#the-nth-child-pseudo case 'nth-child': // TODO(jmesserly): support An+B syntax too. - final exprs = selector.expression.expressions; + final exprs = node.expression.expressions; if (exprs.length == 1 && exprs[0] is LiteralTerm) { final literal = exprs[0] as LiteralTerm; final parent = _element!.parentNode; @@ -226,12 +226,12 @@ case 'lang': // TODO(jmesserly): shouldn't need to get the raw text here, but csslib // gets confused by the "-" in the expression, such as in "es-AR". - final toMatch = selector.expression.span.text; + final toMatch = node.expression.span.text; final lang = _getInheritedLanguage(_element); // TODO(jmesserly): implement wildcards in level 4 return lang != null && lang.startsWith(toMatch); } - throw _unimplemented(selector); + throw _unimplemented(node); } static String? _getInheritedLanguage(Node? node) { @@ -244,45 +244,45 @@ } @override - bool visitNamespaceSelector(NamespaceSelector selector) { + bool visitNamespaceSelector(NamespaceSelector node) { // Match element tag name - if (!(selector.nameAsSimpleSelector!.visit(this) as bool)) return false; + if (!(node.nameAsSimpleSelector!.visit(this) as bool)) return false; - if (selector.isNamespaceWildcard) return true; + if (node.isNamespaceWildcard) return true; - if (selector.namespace == '') return _element!.namespaceUri == null; + if (node.namespace == '') return _element!.namespaceUri == null; - throw _unimplemented(selector); + throw _unimplemented(node); } @override - bool visitElementSelector(ElementSelector selector) => - selector.isWildcard || _element!.localName == selector.name.toLowerCase(); + bool visitElementSelector(ElementSelector node) => + node.isWildcard || _element!.localName == node.name.toLowerCase(); @override - bool visitIdSelector(IdSelector selector) => _element!.id == selector.name; + bool visitIdSelector(IdSelector node) => _element!.id == node.name; @override - bool visitClassSelector(ClassSelector selector) => - _element!.classes.contains(selector.name); + bool visitClassSelector(ClassSelector node) => + _element!.classes.contains(node.name); // TODO(jmesserly): negation should support any selectors in level 4, // not just simple selectors. // http://dev.w3.org/csswg/selectors-4/#negation @override - bool visitNegationSelector(NegationSelector selector) => - !(selector.negationArg!.visit(this) as bool); + bool visitNegationSelector(NegationSelector node) => + !(node.negationArg!.visit(this) as bool); @override - bool visitAttributeSelector(AttributeSelector selector) { + bool visitAttributeSelector(AttributeSelector node) { // Match name first - final value = _element!.attributes[selector.name.toLowerCase()]; + final value = _element!.attributes[node.name.toLowerCase()]; if (value == null) return false; - if (selector.operatorKind == TokenKind.NO_MATCH) return true; + if (node.operatorKind == TokenKind.NO_MATCH) return true; - final select = '${selector.value}'; - switch (selector.operatorKind) { + final select = '${node.value}'; + switch (node.operatorKind) { case TokenKind.EQUALS: return value == select; case TokenKind.INCLUDES: @@ -297,7 +297,7 @@ case TokenKind.SUBSTRING_MATCH: return value.contains(select); default: - throw _unsupported(selector); + throw _unsupported(node); } } }
diff --git a/lib/src/tokenizer.dart b/lib/src/tokenizer.dart index 4ee70fc..3defd4e 100644 --- a/lib/src/tokenizer.dart +++ b/lib/src/tokenizer.dart
@@ -1200,7 +1200,7 @@ state = dataState; } else { _attributeValue.write(data); - _attributeValue.write(stream.charsUntil("\'&")); + _attributeValue.write(stream.charsUntil("'&")); } return true; } @@ -1228,7 +1228,7 @@ _attributeValue.write('\uFFFD'); } else { _attributeValue.write(data); - _attributeValue.write(stream.charsUntil("&>\"\'=<`$spaceCharacters")); + _attributeValue.write(stream.charsUntil("&>\"'=<`$spaceCharacters")); } return true; }
diff --git a/pubspec.yaml b/pubspec.yaml index f5f932a..734c33e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -1,17 +1,17 @@ name: html -version: 0.15.0 +version: 0.15.1-dev description: APIs for parsing and manipulating HTML content outside the browser. repository: https://github.com/dart-lang/html environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: csslib: ^0.17.0 source_span: ^1.8.0 dev_dependencies: + lints: ^1.0.0 path: ^1.8.0 - pedantic: ^1.10.0 test: ^1.16.0
diff --git a/test/selectors/selectors.dart b/test/selectors/selectors.dart index e18f264..289cfda 100644 --- a/test/selectors/selectors.dart +++ b/test/selectors/selectors.dart
@@ -255,7 +255,7 @@ // - value [att=val] { 'name': 'Attribute value selector, matching align attribute with value', - 'selector': '#attr-value [align=\"center\"]', + 'selector': '#attr-value [align="center"]', 'expect': ['attr-value-div1'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -263,7 +263,7 @@ { 'name': 'Attribute value selector, matching align attribute with empty value', - 'selector': '#attr-value [align=\"\"]', + 'selector': '#attr-value [align=""]', 'expect': ['attr-value-div2'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -271,7 +271,7 @@ { 'name': 'Attribute value selector, not matching align attribute with partial value', - 'selector': '#attr-value [align=\"c\"]', + 'selector': '#attr-value [align="c"]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -279,7 +279,7 @@ { 'name': 'Attribute value selector, not matching align attribute with incorrect value', - 'selector': '#attr-value [align=\"centera\"]', + 'selector': '#attr-value [align="centera"]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -287,7 +287,7 @@ { 'name': 'Attribute value selector, matching custom data-* attribute with unicode escaped value', - 'selector': '[data-attr-value=\"\\e9\"]', + 'selector': '[data-attr-value="\\e9"]', 'expect': ['attr-value-div3'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -295,7 +295,7 @@ { 'name': 'Attribute value selector, matching custom data-* attribute with escaped character', - 'selector': '[data-attr-value\_foo=\"\\e9\"]', + 'selector': '[data-attr-value_foo="\\e9"]', 'expect': ['attr-value-div4'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -357,7 +357,7 @@ { 'name': 'Attribute whitespace-separated list selector, matching class attribute with value', - 'selector': '#attr-whitespace [class~=\"div1\"]', + 'selector': '#attr-whitespace [class~="div1"]', 'expect': ['attr-whitespace-div1'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -365,7 +365,7 @@ { 'name': 'Attribute whitespace-separated list selector, not matching class attribute with empty value', - 'selector': '#attr-whitespace [class~=\"\"]', + 'selector': '#attr-whitespace [class~=""]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -373,7 +373,7 @@ { 'name': 'Attribute whitespace-separated list selector, not matching class attribute with partial value', - 'selector': '[data-attr-whitespace~=\"div\"]', + 'selector': '[data-attr-whitespace~="div"]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -381,7 +381,7 @@ { 'name': 'Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value', - 'selector': '[data-attr-whitespace~=\"\\0000e9\"]', + 'selector': '[data-attr-whitespace~="\\0000e9"]', 'expect': ['attr-whitespace-div4'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -389,7 +389,7 @@ { 'name': 'Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character', - 'selector': '[data-attr-whitespace\_foo~=\"\\e9\"]', + 'selector': '[data-attr-whitespace_foo~="\\e9"]', 'expect': ['attr-whitespace-div5'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -442,7 +442,7 @@ { 'name': 'Attribute whitespace-separated list selector with double-quoted value, not matching value with space', - 'selector': '#attr-whitespace a[rel~=\"book mark\"]', + 'selector': '#attr-whitespace a[rel~="book mark"]', 'expect': [] /* no matches */, 'level': 2, 'testType': testQsaBaseline @@ -460,7 +460,7 @@ { 'name': 'Attribute hyphen-separated list selector, not matching unspecified lang attribute', - 'selector': '#attr-hyphen-div1[lang|=\"en\"]', + 'selector': '#attr-hyphen-div1[lang|="en"]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -468,7 +468,7 @@ { 'name': 'Attribute hyphen-separated list selector, matching lang attribute with exact value', - 'selector': '#attr-hyphen-div2[lang|=\"fr\"]', + 'selector': '#attr-hyphen-div2[lang|="fr"]', 'expect': ['attr-hyphen-div2'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -476,7 +476,7 @@ { 'name': 'Attribute hyphen-separated list selector, matching lang attribute with partial value', - 'selector': '#attr-hyphen-div3[lang|=\"en\"]', + 'selector': '#attr-hyphen-div3[lang|="en"]', 'expect': ['attr-hyphen-div3'], 'level': 2, 'testType': testQsaBaseline | testMatchBaseline @@ -484,7 +484,7 @@ { 'name': 'Attribute hyphen-separated list selector, not matching incorrect value', - 'selector': '#attr-hyphen-div4[lang|=\"es-AR\"]', + 'selector': '#attr-hyphen-div4[lang|="es-AR"]', 'expect': [] /*no matches*/, 'level': 2, 'testType': testQsaBaseline @@ -494,7 +494,7 @@ { 'name': 'Attribute begins with selector, matching href attributes beginning with specified substring', - 'selector': '#attr-begins a[href^=\"http://www\"]', + 'selector': '#attr-begins a[href^="http://www"]', 'expect': ['attr-begins-a1', 'attr-begins-a3'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -502,7 +502,7 @@ { 'name': 'Attribute begins with selector, matching lang attributes beginning with specified substring, ', - 'selector': '#attr-begins [lang^=\"en-\"]', + 'selector': '#attr-begins [lang^="en-"]', 'expect': ['attr-begins-div2', 'attr-begins-div4'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -526,7 +526,7 @@ { 'name': 'Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring', - 'selector': '#attr-begins [class^=\" apple\"]', + 'selector': '#attr-begins [class^=" apple"]', 'expect': ['attr-begins-p1'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -544,7 +544,7 @@ { 'name': 'Attribute ends with selector, matching href attributes ending with specified substring', - 'selector': '#attr-ends a[href\$=\".org\"]', + 'selector': '#attr-ends a[href\$=".org"]', 'expect': ['attr-ends-a1', 'attr-ends-a3'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -552,7 +552,7 @@ { 'name': 'Attribute ends with selector, matching lang attributes ending with specified substring, ', - 'selector': '#attr-ends [lang\$=\"-CH\"]', + 'selector': '#attr-ends [lang\$="-CH"]', 'expect': ['attr-ends-div2', 'attr-ends-div4'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -576,7 +576,7 @@ { 'name': 'Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring', - 'selector': '#attr-ends [class\$=\"apple \"]', + 'selector': '#attr-ends [class\$="apple "]', 'expect': ['attr-ends-p1'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -594,7 +594,7 @@ { 'name': 'Attribute contains selector, matching href attributes beginning with specified substring', - 'selector': '#attr-contains a[href*=\"http://www\"]', + 'selector': '#attr-contains a[href*="http://www"]', 'expect': ['attr-contains-a1', 'attr-contains-a3'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -602,7 +602,7 @@ { 'name': 'Attribute contains selector, matching href attributes ending with specified substring', - 'selector': '#attr-contains a[href*=\".org\"]', + 'selector': '#attr-contains a[href*=".org"]', 'expect': ['attr-contains-a1', 'attr-contains-a2'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -610,7 +610,7 @@ { 'name': 'Attribute contains selector, matching href attributes containing specified substring', - 'selector': '#attr-contains a[href*=\".example.\"]', + 'selector': '#attr-contains a[href*=".example."]', 'expect': ['attr-contains-a1', 'attr-contains-a3'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -618,7 +618,7 @@ { 'name': 'Attribute contains selector, matching lang attributes beginning with specified substring, ', - 'selector': '#attr-contains [lang*=\"en-\"]', + 'selector': '#attr-contains [lang*="en-"]', 'expect': ['attr-contains-div2', 'attr-contains-div6'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -626,7 +626,7 @@ { 'name': 'Attribute contains selector, matching lang attributes ending with specified substring, ', - 'selector': '#attr-contains [lang*=\"-CH\"]', + 'selector': '#attr-contains [lang*="-CH"]', 'expect': ['attr-contains-div3', 'attr-contains-div5'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -658,7 +658,7 @@ { 'name': 'Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring', - 'selector': '#attr-contains [class*=\" apple\"]', + 'selector': '#attr-contains [class*=" apple"]', 'expect': ['attr-contains-p1'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -666,7 +666,7 @@ { 'name': 'Attribute contains selector with double-quoted value, matching class attribute ending with specified substring', - 'selector': '#attr-contains [class*=\"orange \"]', + 'selector': '#attr-contains [class*="orange "]', 'expect': ['attr-contains-p1'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline @@ -674,7 +674,7 @@ { 'name': 'Attribute contains selector with double-quoted value, matching class attribute containing specified substring', - 'selector': '#attr-contains [class*=\"ple banana ora\"]', + 'selector': '#attr-contains [class*="ple banana ora"]', 'expect': ['attr-contains-p1'], 'level': 3, 'testType': testQsaAdditional | testMatchBaseline