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