Cloning node for Range APIs should be in tree order

Differential Revision: https://phabricator.services.mozilla.com/D3216

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1480618
gecko-commit: 8fdd88cea1887c403c09a486cff98313bd191f13
gecko-integration-branch: autoland
gecko-reviewers: smaug
diff --git a/custom-elements/range-and-constructors.html b/custom-elements/range-and-constructors.html
new file mode 100644
index 0000000..d17c3b7
--- /dev/null
+++ b/custom-elements/range-and-constructors.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom elements: Range APIs should invoke constructor in tree order</title>
+<meta name="author" title="Edgar Chen" href="mailto:echen@mozilla.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-element">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
+<line rel="help" href="https://dom.spec.whatwg.org/#concept-range-extract">
+<line rel="help" href="https://dom.spec.whatwg.org/#concept-range-clone">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+
+<c-e data-index="root">
+  <c-e data-index="root-0">
+    <c-e data-index="root-0-0">
+      <c-e data-index="root-0-0-0"></c-e>
+      <span id="start"></span>
+    </c-e>
+  </c-e>
+  <c-e data-index="root-1"></c-e>
+  <span id="end"></span>
+</c-e>
+
+<script>
+
+var logs = [];
+class CE extends HTMLElement {
+  constructor() {
+    super();
+    logs.push(this.dataset.index);
+  }
+}
+customElements.define('c-e', CE);
+
+function getRange() {
+  const range = new Range();
+  range.setStart(document.getElementById('start'), 0);
+  range.setEnd(document.getElementById('end'), 0);
+  return range;
+}
+
+test(function () {
+  // Clear log for testing.
+  logs = [];
+  getRange().cloneContents();
+  assert_array_equals(logs, ['root-0', 'root-0-0', 'root-1']);
+}, 'Range.cloneContents should invoke constructor in tree order');
+
+test(function () {
+  // Clear log for testing.
+  logs = [];
+  getRange().extractContents();
+  assert_array_equals(logs, ['root-0', 'root-0-0']);
+}, 'Range.extractContents should invoke constructor in tree order');
+
+</script>
+</body>
+</html>