Skip to content

html_dart2js: cloned StyleElements on IE are not always applied. #23173

Open
@rakudrama

Description

At first it seems like we could override Node.clone() with StyleElement.clone() that does the extra appendText for IE.

THIS IS A BAD IDEA.

Currently Node.clone() is a simple alias for the DOM's Node.cloneNode().
This allows us to generate nice idiomatic JavaScript code like the following:

    greenClone = green.cloneNode(true);

If we override the function we need a dispatch to find the method and we lose the ability to generate such zero-overhead code. Almost every clone operation in the program will suffer to fix StyleElements.

Considering the damage to the rest of the program, it is probably best to work around this problem in user code, where we usually know when we are cloning a StyleElement.

---------- html
<!DOCTYPE html>
<html>
<head>
  <title>IE Style Bug Demo</title>
  <script type="text/javascript" src="out.js"></script>
</head>
<body>
  <div class="red">This text should be red. (Style is not cloned)</div>
  <div class="green">This text should be green, but it's black in IE. (Style is cloned)</div>
  <div class="blue">This text should be blue, and it's blue in IE. (Style is cloned, and fixed)</div>
  <hr/>
  <pre>
import 'dart:html';

void main() {
  var red = document.createElement('style')..appendText('.red {color: red;}');
  var green = document.createElement('style')..appendText('.green {color: green;}');
  var blue = document.createElement('style')..appendText('.blue {color: blue;}');

  // Cloning causes a bug in IE, and the styles are not applied.
  var greenClone = green.clone(true);
  var blueClone = blue.clone(true);

  // But it can be fixed by adding an empty text node.
  blueClone.appendText("");

  document.head.append(red); // applied in IE
  document.head.append(greenClone); // not applied in IE
  document.head.append(blueClone); // applied in IE
}
  </pre>
</body>
</html>

---------- screenshot
This text should be red. (Style is not cloned)
This text should be green, but it's black in IE. (Style is cloned)
This text should be blue, and it's blue in IE. (Style is cloned, and fixed)

import 'dart:html';

void main() {
  var red = document.createElement('style')..appendText('.red {color: red;}');
  var green = document.createElement('style')..appendText('.green {color: green;}');
  var blue = document.createElement('style')..appendText('.blue {color: blue;}');

  // Cloning causes a bug in IE, and the styles are not applied.
  var greenClone = green.clone(true);
  var blueClone = blue.clone(true);

  // But it can be fixed by adding an empty text node.
  blueClone.appendText("");

  document.head.append(red); // applied in IE
  document.head.append(greenClone); // not applied in IE
  document.head.append(blueClone); // applied in IE
}


Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-webUse area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop.library-htmllibrary-web-audiotype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)web-librariesIssues impacting dart:html, etc., libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions