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