1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/event.html">
9<link rel="import" href="/tracing/ui/base/ui.html">
10
11<script>
12'use strict';
13
14/**
15 * @fileoverview Container that decorates its children.
16 */
17tr.exportTo('tr.ui.b', function() {
18  /**
19   * @constructor
20   */
21  var ContainerThatDecoratesItsChildren = tr.ui.b.define('div');
22
23  ContainerThatDecoratesItsChildren.prototype = {
24    __proto__: HTMLUnknownElement.prototype,
25
26    decorate: function() {
27      this.observer_ = new WebKitMutationObserver(this.didMutate_.bind(this));
28      this.observer_.observe(this, { childList: true });
29
30      // textContent is a variable on regular HTMLElements. However, we want to
31      // hook and prevent writes to it.
32      Object.defineProperty(
33          this, 'textContent',
34          { get: undefined, set: this.onSetTextContent_});
35    },
36
37    appendChild: function(x) {
38      HTMLUnknownElement.prototype.appendChild.call(this, x);
39      this.didMutate_(this.observer_.takeRecords());
40    },
41
42    insertBefore: function(x, y) {
43      HTMLUnknownElement.prototype.insertBefore.call(this, x, y);
44      this.didMutate_(this.observer_.takeRecords());
45    },
46
47    removeChild: function(x) {
48      HTMLUnknownElement.prototype.removeChild.call(this, x);
49      this.didMutate_(this.observer_.takeRecords());
50    },
51
52    replaceChild: function(x, y) {
53      HTMLUnknownElement.prototype.replaceChild.call(this, x, y);
54      this.didMutate_(this.observer_.takeRecords());
55    },
56
57    onSetTextContent_: function(textContent) {
58      if (textContent != '')
59        throw new Error('textContent can only be set to \'\'.');
60      this.clear();
61    },
62
63    clear: function() {
64      while (this.lastChild)
65        HTMLUnknownElement.prototype.removeChild.call(this, this.lastChild);
66      this.didMutate_(this.observer_.takeRecords());
67    },
68
69    didMutate_: function(records) {
70      this.beginDecorating_();
71      for (var i = 0; i < records.length; i++) {
72        var addedNodes = records[i].addedNodes;
73        if (addedNodes) {
74          for (var j = 0; j < addedNodes.length; j++)
75            this.decorateChild_(addedNodes[j]);
76        }
77        var removedNodes = records[i].removedNodes;
78        if (removedNodes) {
79          for (var j = 0; j < removedNodes.length; j++) {
80            this.undecorateChild_(removedNodes[j]);
81          }
82        }
83      }
84      this.doneDecoratingForNow_();
85    },
86
87    decorateChild_: function(child) {
88      throw new Error('Not implemented');
89    },
90
91    undecorateChild_: function(child) {
92      throw new Error('Not implemented');
93    },
94
95    beginDecorating_: function() {
96    },
97
98    doneDecoratingForNow_: function() {
99    }
100  };
101
102  return {
103    ContainerThatDecoratesItsChildren: ContainerThatDecoratesItsChildren
104  };
105
106});
107</script>
108