Rewrite asciiUpper2Lower as an extension (#132)
- Switch to an extension method which will work nicer with `?.` instead
of needing to handle a null argument and has nicer looking usage.
- Rename to `toAsciiLowerCase` for consistency with the similar method
in the SDK.
- Use `Iterable.map` to avoid needing to create a fixed size list which
will not work well with the null safety migration.
This method is an internal detail and this is not breaking.
diff --git a/.travis.yml b/.travis.yml
index 3f5bcfb..497fe68 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
dart:
- dev
- - 2.3.0
+ - 2.8.1
dart_task:
- test: -p vm
@@ -15,7 +15,7 @@
- dart: dev
dart_task:
dartanalyzer: --fatal-warnings --fatal-infos .
- - dart: 2.3.0
+ - dart: 2.8.1
dart_task:
dartanalyzer: --fatal-warnings .
diff --git a/lib/parser.dart b/lib/parser.dart
index 5cfd53d..ac3d304 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -260,8 +260,7 @@
bool isHTMLIntegrationPoint(Element element) {
if (element.localName == 'annotation-xml' &&
element.namespaceUri == Namespaces.mathml) {
- var enc = element.attributes['encoding'];
- if (enc != null) enc = asciiUpper2Lower(enc);
+ final enc = element.attributes['encoding']?.toAsciiLowerCase();
return enc == 'text/html' || enc == 'application/xhtml+xml';
} else {
return htmlIntegrationPointElements
@@ -683,7 +682,7 @@
@override
Token processDoctype(DoctypeToken token) {
final name = token.name;
- var publicId = token.publicId;
+ var publicId = token.publicId?.toAsciiLowerCase();
final systemId = token.systemId;
final correct = token.correct;
@@ -697,10 +696,6 @@
tree.insertDoctype(token);
- if (publicId != '') {
- publicId = asciiUpper2Lower(publicId);
- }
-
if (!correct ||
token.name != 'html' ||
startsWithAny(publicId, const [
@@ -1783,7 +1778,7 @@
void startTagInput(StartTagToken token) {
final savedFramesetOK = parser.framesetOK;
startTagVoidFormatting(token);
- if (asciiUpper2Lower(token.data['type']) == 'hidden') {
+ if (token.data['type']?.toAsciiLowerCase() == 'hidden') {
//input type=hidden doesn't change framesetOK
parser.framesetOK = savedFramesetOK;
}
@@ -2486,7 +2481,7 @@
}
void startTagInput(StartTagToken token) {
- if (asciiUpper2Lower(token.data['type']) == 'hidden') {
+ if (token.data['type']?.toAsciiLowerCase() == 'hidden') {
parser.parseError(token.span, 'unexpected-hidden-input-in-table');
tree.insertElement(token);
// XXX associate with form
@@ -3621,13 +3616,13 @@
Token processEndTag(EndTagToken token) {
var nodeIndex = tree.openElements.length - 1;
var node = tree.openElements.last;
- if (asciiUpper2Lower(node.localName) != token.name) {
+ if (node.localName?.toAsciiLowerCase() != token.name) {
parser.parseError(token.span, 'unexpected-end-tag', {'name': token.name});
}
Token newToken;
while (true) {
- if (asciiUpper2Lower(node.localName) == token.name) {
+ if (node.localName?.toAsciiLowerCase() == token.name) {
//XXX this isn't in the spec but it seems necessary
if (parser.phase == parser._inTableTextPhase) {
final inTableText = parser.phase as InTableTextPhase;
diff --git a/lib/src/constants.dart b/lib/src/constants.dart
index b09fc48..e1fad5a 100644
--- a/lib/src/constants.dart
+++ b/lib/src/constants.dart
@@ -482,19 +482,15 @@
return false;
}
-// Note: based on the original Python code, I assume we only want to convert
-// ASCII chars to.toLowerCase() case, unlike Dart's toLowerCase function.
-String asciiUpper2Lower(String text) {
- if (text == null) return null;
- final result = List<int>(text.length);
- for (var i = 0; i < text.length; i++) {
- var c = text.codeUnitAt(i);
- if (c >= UPPER_A && c <= UPPER_Z) {
- c += LOWER_A - UPPER_A;
- }
- result[i] = c;
- }
- return String.fromCharCodes(result);
+extension AsciiUpperToLower on String {
+ /// Converts ASCII characters to lowercase.
+ ///
+ /// Unlike [String.toLowerCase] does not touch non-ASCII characters.
+ String toAsciiLowerCase() =>
+ String.fromCharCodes(codeUnits.map(_asciiToLower));
+
+ static int _asciiToLower(int c) =>
+ (c >= UPPER_A && c <= UPPER_Z) ? c + LOWER_A - UPPER_A : c;
}
// Heading elements need to be ordered
diff --git a/lib/src/tokenizer.dart b/lib/src/tokenizer.dart
index 7af9648..2737a7e 100644
--- a/lib/src/tokenizer.dart
+++ b/lib/src/tokenizer.dart
@@ -370,7 +370,7 @@
// Add token to the queue to be yielded
if (token is TagToken) {
if (lowercaseElementName) {
- token.name = asciiUpper2Lower(token.name);
+ token.name = token.name?.toAsciiLowerCase();
}
if (token is EndTagToken) {
if (_attributes != null) {
@@ -1074,7 +1074,7 @@
// to attributes, but we do want to report the parse error in time.
var attrName = _attributeName.toString();
if (lowercaseAttrName) {
- attrName = asciiUpper2Lower(attrName);
+ attrName = attrName.toAsciiLowerCase();
}
_attributes.last.name = attrName;
_attributeNames ??= {};
@@ -1515,10 +1515,10 @@
bool doctypeNameState() {
final data = stream.char();
if (isWhitespace(data)) {
- currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+ currentDoctypeToken.name = currentDoctypeToken.name?.toAsciiLowerCase();
state = afterDoctypeNameState;
} else if (data == '>') {
- currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+ currentDoctypeToken.name = currentDoctypeToken.name?.toAsciiLowerCase();
_addToken(currentToken);
state = dataState;
} else if (data == '\u0000') {
@@ -1528,7 +1528,7 @@
} else if (data == eof) {
_addToken(ParseErrorToken('eof-in-doctype-name'));
currentDoctypeToken.correct = false;
- currentDoctypeToken.name = asciiUpper2Lower(currentDoctypeToken.name);
+ currentDoctypeToken.name = currentDoctypeToken.name?.toAsciiLowerCase();
_addToken(currentToken);
state = dataState;
} else {
diff --git a/pubspec.yaml b/pubspec.yaml
index 2576b05..a8fcab3 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -5,7 +5,7 @@
homepage: https://github.com/dart-lang/html
environment:
- sdk: '>=2.3.0 <3.0.0'
+ sdk: '>=2.8.0 <3.0.0'
dependencies:
csslib: '>=0.13.2 <0.17.0'