[dart:html] Use TreatNullAs attribute in nullability

Closes https://github.com/dart-lang/sdk/issues/41419

Uses the external attribute TreatNullAs to allow nullable setters
and parameters.

Change-Id: I5182ac6dcfdcf78e84f204079a782aebbf128a78
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143185
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Srujan Gaddam 2020-04-14 00:37:41 +00:00 committed by commit-bot@chromium.org
parent 09e47b6177
commit 2bd4858d40
8 changed files with 35 additions and 28 deletions

View file

@ -4049,7 +4049,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
String get cssFloat native;
set cssFloat(String value) native;
set cssFloat(String? value) native;
String get cssText native;
@ -13737,7 +13737,7 @@ class Element extends Node
* This uses the default sanitization behavior to sanitize the HTML fragment,
* use [setInnerHtml] to override the default behavior.
*/
set innerHtml(String html) {
set innerHtml(String? html) {
this.setInnerHtml(html);
}
@ -13762,13 +13762,13 @@ class Element extends Node
* * [NodeValidator]
* * [NodeTreeSanitizer]
*/
void setInnerHtml(String html,
void setInnerHtml(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
text = null;
if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
_innerHtml = html;
} else {
append(createFragment(html,
append(createFragment(html!,
validator: validator, treeSanitizer: treeSanitizer));
}
}
@ -14562,7 +14562,7 @@ class Element extends Node
String get _innerHtml native;
@JSName('innerHTML')
set _innerHtml(String value) native;
set _innerHtml(String? value) native;
@JSName('localName')
String get _localName native;
@ -19196,7 +19196,7 @@ class InputElement extends HtmlElement
String get value native;
set value(String value) native;
set value(String? value) native;
DateTime get valueAsDate =>
convertNativeToDart_DateTime(this._get_valueAsDate);
@ -19277,7 +19277,7 @@ abstract class InputElementBase implements Element {
set name(String value);
String get value;
set value(String value);
set value(String? value);
List<Node> get labels;
@ -27858,7 +27858,7 @@ class ShadowRoot extends DocumentFragment implements DocumentOrShadowRoot {
String get innerHtml native;
@JSName('innerHTML')
set innerHtml(String value) native;
set innerHtml(String? value) native;
String get mode native;
@ -29266,7 +29266,7 @@ class TableCellElement extends HtmlElement {
String get headers native;
set headers(String value) native;
set headers(String? value) native;
int get rowSpan native;
@ -29581,11 +29581,11 @@ class TemplateElement extends HtmlElement {
*
* * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
*/
void setInnerHtml(String html,
void setInnerHtml(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
text = null;
content.nodes.clear();
var fragment = createFragment(html,
var fragment = createFragment(html!,
validator: validator, treeSanitizer: treeSanitizer);
content.append(fragment);
@ -29723,7 +29723,7 @@ class TextAreaElement extends HtmlElement {
String get value native;
set value(String value) native;
set value(String? value) native;
bool get willValidate native;

View file

@ -3037,7 +3037,7 @@ class SvgElement extends Element implements GlobalEventHandlers, NoncedElement {
return container.innerHtml;
}
set innerHtml(String value) {
set innerHtml(String? value) {
this.setInnerHtml(value);
}

View file

@ -490,7 +490,10 @@ def _BuildArguments(args, interface, constructor=False):
if len(set(DartType(arg.type.id) for arg in args)) == 1:
nullable = False
for arg in args:
nullable = nullable or getattr(arg.type, 'nullable', False)
# If the 'TreatNullAs' attribute exists, the param technically
# is nullable. The conversion happens in the browser.
nullable = nullable or getattr(arg.type, 'nullable', False) or \
'TreatNullAs' in arg.ext_attrs
return (type_ids[0], nullable)
else:
return (None, False)

View file

@ -1413,13 +1413,17 @@ class Dart2JSBackend(HtmlDartGenerator):
self._members_emitter.Emit(
'\n'
' // Use implementation from $SUPER.\n'
' // $TYPE get $NAME native;\n'
' // void set $NAME($TYPE value) native;\n',
' // $GET_TYPE get $NAME native;\n'
' // void set $NAME($SET_TYPE value) native;\n',
SUPER=super_attribute_interface,
NAME=html_name,
TYPE=self.SecureOutputType(attribute.type.id,
GET_TYPE=self.SecureOutputType(attribute.type.id,
can_narrow_type=read_only,
nullable=attribute.type.nullable))
nullable=attribute.type.nullable),
SET_TYPE=self.SecureOutputType(attribute.type.id,
can_narrow_type=read_only,
nullable=attribute.type.nullable or \
'TreatNullAs' in attribute.ext_attrs))
return
self._members_emitter.Emit('\n // Shadowing definition.')
self._AddAttributeUsingProperties(attribute, html_name, read_only)
@ -1548,7 +1552,7 @@ class Dart2JSBackend(HtmlDartGenerator):
conversion = self._InputConversion(attr.type.id, attr.id)
if conversion:
return self._AddConvertingSetter(attr, html_name, conversion)
nullable_type = attr.type.nullable
nullable_type = attr.type.nullable or 'TreatNullAs' in attr.ext_attrs
# If this attr has an output conversion, it is possible that there is a
# converting getter. We need to make sure the setter type matches the
# getter type.
@ -1592,8 +1596,8 @@ class Dart2JSBackend(HtmlDartGenerator):
def _AddConvertingSetter(self, attr, html_name, conversion):
# If the attribute is nullable, the setter should be nullable.
nullable_in = attr.type.nullable and \
not conversion.input_type == 'dynamic'
nullable_in = (attr.type.nullable or 'TreatNullAs' in attr.ext_attrs) \
and not conversion.input_type == 'dynamic'
nullable_out = conversion.nullable_output and \
not conversion.output_type == 'dynamic'
self._members_emitter.Emit(

View file

@ -1418,7 +1418,7 @@ $endif
* This uses the default sanitization behavior to sanitize the HTML fragment,
* use [setInnerHtml] to override the default behavior.
*/
set innerHtml(String html) {
set innerHtml(String$NULLABLE html) {
this.setInnerHtml(html);
}
@ -1443,7 +1443,7 @@ $endif
* * [NodeValidator]
* * [NodeTreeSanitizer]
*/
void setInnerHtml(String html,
void setInnerHtml(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
text = null;
@ -1451,7 +1451,7 @@ $endif
_innerHtml = html;
} else {
append(createFragment(
html, validator: validator, treeSanitizer: treeSanitizer));
html$NULLASSERT, validator: validator, treeSanitizer: treeSanitizer));
}
}
String get innerHtml => _innerHtml;

View file

@ -66,7 +66,7 @@ abstract class InputElementBase implements Element {
set name(String value);
String get value;
set value(String value);
set value(String$NULLABLE value);
List<Node> get labels;

View file

@ -16,13 +16,13 @@ $!MEMBERS
*
* * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
*/
void setInnerHtml(String html,
void setInnerHtml(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
text = null;
content.nodes.clear();
var fragment = createFragment(
html, validator: validator, treeSanitizer: treeSanitizer);
html$NULLASSERT, validator: validator, treeSanitizer: treeSanitizer);
content.append(fragment);
}

View file

@ -82,7 +82,7 @@ $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS
return container.innerHtml;
}
set innerHtml(String value) {
set innerHtml(String$NULLABLE value) {
this.setInnerHtml(value);
}