appendHtml() doesn't append the full HTML - Da

2019-07-16 02:15发布

问题:

The following code works as expected in DartPad, demonstrated below:

void main() {
  Element e = querySelector('table');

  String someValue = 'hello, world';
  int anotherValue = 23958;

  Element row = new Element.tr()
    ..appendHtml('''
      <td>$someValue</td>
      <td>$anotherValue</td>
    ''');

  e.append(row);
}

DartPad

However, when I compile the same code using dart2js (dart2js -c -o app.js app.dart) and run it on the same page, the created <td>'s are completely removed, and I end up with:

<table>
  <tr>hello, world 23958</tr>
</table>

The same issue occurs when the actual .dart file is used in <script src="..."> with Dartium (v39.0.2171.0 x64). I'm on Dart v1.11.1.


Some testing:

..appendHtml('''
  <td></td>
  <td>hi</td>
''');

Yields:

<table>
  <tr>hi</tr>
</table>

This gives the same as above:

..appendHtml('<td>hi</td>');

The only way I could get it to give me what I want is:

..append(new Element.td()..text = someValue)
..append(new Element.td()..text = anotherValue.toString());

回答1:

Dart 1.11 made a change to appendHTML to sanitize the HTML input.

To avoid this, you can pass a sanitizer that does nothing.

class MySanitizer implements NodeTreeSanitizer {
  void sanitizeTree(Node node) {}
}

document.body.appendHtml('<td>fish</td>', treeSanitizer: new MySanitizer());


回答2:

It's a bug. Should be fixed in bleeding edge very shortly, fix is in review. Basically, sanitization creates a document fragment to sanitize. It wasn't correctly using the context, so it tried to create it as it it was under body, and table elements don't work there.



回答3:

This is because JS does not support multiline strings, you would need to structure it like this:

'<td>TEXT</td>' +
'<td>TEXT2</td>'

OR:

'<td>TEXT</td><td>TEXT2</td>'