Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Unified Diff: LayoutTests/fast/dom/custom/processing-stack-recursion.html

Issue 18167006: Implement Custom Elements' entered and left document callbacks. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Move callbacks reference into invocation. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: LayoutTests/fast/dom/custom/processing-stack-recursion.html
diff --git a/LayoutTests/fast/dom/custom/processing-stack-recursion.html b/LayoutTests/fast/dom/custom/processing-stack-recursion.html
new file mode 100644
index 0000000000000000000000000000000000000000..1fc70d6a4bed21940ffa4642378d54c0ef0d5316
--- /dev/null
+++ b/LayoutTests/fast/dom/custom/processing-stack-recursion.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<body>
+<template id="expected">A entered
+A removing parent node
+ A left
+ A inserting parent node
+ A entered
+ A removing parent node
+ A left
+ A inserting parent node
+ A entered
+ B entered
+ B left
+ B entered
+ B setting attribute on C
+ C entered
+ C left
+ C entered
+ C left
+ C entered
+ C@by null->b
+ C setting attribute on B
+ B left
+ B entered
+ B@by null->c
+ B setting attribute on A
+ A@by null->b
+ B set attribute on A
+ C set attribute on B
+ B set attribute on C
+ A inserted parent node
+ A removed parent node
+ A inserted parent node
+A removed parent node</template>
+<script>
+test(function () {
+ // Helpers for logging
+ var buffer = [];
+ var indentation = '';
+ function log(msg) {
+ buffer.push(indentation + msg);
+ }
+ function indent() {
+ indentation += ' ';
+ }
+ function unindent() {
+ indentation = indentation.substring(3);
+ }
+
+ // This tests recursion and the processing stack. Specifically:
+ //
+ // (1) Scheduling callbacks for an element that has callbacks
+ // scheduled at an outer level of recursion, but that have not
+ // begun to be processed yet.
+ //
+ // (2) Scheduling callbacks for an element that is in the middle
+ // of processing callbacks at an outer level of recursion.
+ //
+ // (3) Scheduling callbacks for an element that exhaustively
+ // processed callbacks at an outer level of recursion.
+ //
+ // appendChild and remove are used on a subtree containing
+ // multiple custom elements. In this way it is possible to
+ // schedule callbacks for multiple custom elements with one DOM
+ // call.
+ //
+ // The test creates this tree:
+ //
+ // <div>
+ // <x-a></x-a>
+ // <x-b></x-b>
+ // <x-c></x-c>
+ // </div>
+ //
+ // x-a pushes its parent in and out of the document, thus scheduling
+ // work for x-b and x-c at every level of recursion.
+ //
+ // Then x-b processes half its queue before setting an attribute
+ // on x-c. This tests case (1) because x-c has not begun its queue
+ // yet.
+ //
+ // x-c turns around and sets and attribute on x-b. This tests case
+ // (2) because x-b is half way through processing its queue.
+ //
+ // x-b turns around and sets an attribute on x-a. This tests case
+ // (3) because x-a has finished processing its queue.
+
+ var protoA = Object.create(HTMLElement.prototype);
+ var n = 0;
+ protoA.enteredDocumentCallback = function () {
+ log('A entered');
+ n++;
+ if (n < 3) {
+ log('A removing parent node'); indent();
+ this.parentNode.remove();
+ unindent(); log('A removed parent node');
+ }
+ };
+ protoA.leftDocumentCallback = function () {
+ log('A left');
+ log('A inserting parent node'); indent();
+ document.body.appendChild(this.parentNode);
+ unindent(); log('A inserted parent node');
+ };
+ protoA.attributeChangedCallback = function (name, oldValue, newValue) {
+ log('A@' + name + ' ' + oldValue + '->' + newValue);
+ };
+ var A = document.register('x-a', {prototype: protoA});
+
+ var protoB = Object.create(HTMLElement.prototype);
+ var m = 0;
+ protoB.enteredDocumentCallback = function () {
+ log('B entered');
+ m++;
+ if (m == 2) {
+ log('B setting attribute on C'); indent();
+ this.parentNode.querySelector('x-c').setAttribute('by', 'b');
+ unindent(); log('B set attribute on C');
+ }
+ };
+ protoB.leftDocumentCallback = function () {
+ log('B left');
+ };
+ protoB.attributeChangedCallback = function (name, oldValue, newValue) {
+ log('B@' + name + ' ' + oldValue + '->' + newValue);
+ log('B setting attribute on A'); indent();
+ this.parentNode.querySelector('x-a').setAttribute('by', 'b');
+ unindent(); log('B set attribute on A');
+ };
+ var B = document.register('x-b', {prototype: protoB});
+
+ var protoC = Object.create(HTMLElement.prototype);
+ protoC.enteredDocumentCallback = function () {
+ log('C entered');
+ };
+ protoC.leftDocumentCallback = function () {
+ log('C left');
+ };
+ protoC.attributeChangedCallback = function (name, oldValue, newValue) {
+ log('C@' + name + ' ' + oldValue + '->' + newValue);
+ log('C setting attribute on B'); indent();
+ this.parentNode.querySelector('x-b').setAttribute('by', 'c');
+ unindent(); log('C set attribute on B');
+ };
+ var C = document.register('x-c', {prototype: protoC});
+
+ var div = document.createElement('div');
+ div.innerHTML = '<div><x-a></x-a><x-b></x-b><x-c></x-c></div>';
+ document.body.appendChild(div);
+
+ assert_equals(buffer.join('\n'), expected.content.textContent, 'should have generated an identical log');
+}, 'recursively scheduled callbacks');
+</script>

Powered by Google App Engine
This is Rietveld 408576698