1/* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/** 31 * @constructor 32 * @param {string|!Element} title 33 * @param {string=} subtitle 34 */ 35WebInspector.Section = function(title, subtitle) 36{ 37 this.element = document.createElement("div"); 38 this.element.className = "section"; 39 this.element._section = this; 40 41 this.headerElement = document.createElement("div"); 42 this.headerElement.className = "header"; 43 44 this.titleElement = document.createElement("div"); 45 this.titleElement.className = "title"; 46 47 this.subtitleElement = document.createElement("div"); 48 this.subtitleElement.className = "subtitle"; 49 50 this.headerElement.appendChild(this.subtitleElement); 51 this.headerElement.appendChild(this.titleElement); 52 53 this.headerElement.addEventListener("click", this.handleClick.bind(this), false); 54 this.element.appendChild(this.headerElement); 55 56 this.title = title; 57 this.subtitle = subtitle; 58 this._expanded = false; 59} 60 61WebInspector.Section.prototype = { 62 get title() 63 { 64 return this._title; 65 }, 66 67 set title(x) 68 { 69 if (this._title === x) 70 return; 71 this._title = x; 72 73 if (x instanceof Node) { 74 this.titleElement.removeChildren(); 75 this.titleElement.appendChild(x); 76 } else 77 this.titleElement.textContent = x; 78 }, 79 80 get subtitle() 81 { 82 return this._subtitle; 83 }, 84 85 set subtitle(x) 86 { 87 if (this._subtitle === x) 88 return; 89 this._subtitle = x; 90 this.subtitleElement.textContent = x; 91 }, 92 93 get subtitleAsTextForTest() 94 { 95 var result = this.subtitleElement.textContent; 96 var child = this.subtitleElement.querySelector("[data-uncopyable]"); 97 if (child) { 98 var linkData = child.getAttribute("data-uncopyable"); 99 if (linkData) 100 result += linkData; 101 } 102 return result; 103 }, 104 105 get expanded() 106 { 107 return this._expanded; 108 }, 109 110 set expanded(x) 111 { 112 if (x) 113 this.expand(); 114 else 115 this.collapse(); 116 }, 117 118 get populated() 119 { 120 return this._populated; 121 }, 122 123 set populated(x) 124 { 125 this._populated = x; 126 if (!x && this._expanded) { 127 this.onpopulate(); 128 this._populated = true; 129 } 130 }, 131 132 onpopulate: function() 133 { 134 // Overriden by subclasses. 135 }, 136 137 get firstSibling() 138 { 139 var parent = this.element.parentElement; 140 if (!parent) 141 return null; 142 143 var childElement = parent.firstChild; 144 while (childElement) { 145 if (childElement._section) 146 return childElement._section; 147 childElement = childElement.nextSibling; 148 } 149 150 return null; 151 }, 152 153 get lastSibling() 154 { 155 var parent = this.element.parentElement; 156 if (!parent) 157 return null; 158 159 var childElement = parent.lastChild; 160 while (childElement) { 161 if (childElement._section) 162 return childElement._section; 163 childElement = childElement.previousSibling; 164 } 165 166 return null; 167 }, 168 169 get nextSibling() 170 { 171 var curElement = this.element; 172 do { 173 curElement = curElement.nextSibling; 174 } while (curElement && !curElement._section); 175 176 return curElement ? curElement._section : null; 177 }, 178 179 get previousSibling() 180 { 181 var curElement = this.element; 182 do { 183 curElement = curElement.previousSibling; 184 } while (curElement && !curElement._section); 185 186 return curElement ? curElement._section : null; 187 }, 188 189 expand: function() 190 { 191 if (this._expanded) 192 return; 193 this._expanded = true; 194 this.element.classList.add("expanded"); 195 196 if (!this._populated) { 197 this.onpopulate(); 198 this._populated = true; 199 } 200 }, 201 202 collapse: function() 203 { 204 if (!this._expanded) 205 return; 206 this._expanded = false; 207 this.element.classList.remove("expanded"); 208 }, 209 210 toggleExpanded: function() 211 { 212 this.expanded = !this.expanded; 213 }, 214 215 handleClick: function(event) 216 { 217 this.toggleExpanded(); 218 event.consume(); 219 } 220} 221