| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * @unrestricted | 30 * @unrestricted |
| 31 */ | 31 */ |
| 32 var TreeOutline = class extends Common.Object { | 32 UI.TreeOutline = class extends Common.Object { |
| 33 /** | 33 /** |
| 34 * @param {boolean=} nonFocusable | 34 * @param {boolean=} nonFocusable |
| 35 */ | 35 */ |
| 36 constructor(nonFocusable) { | 36 constructor(nonFocusable) { |
| 37 super(); | 37 super(); |
| 38 this._createRootElement(); | 38 this._createRootElement(); |
| 39 | 39 |
| 40 this.selectedTreeElement = null; | 40 this.selectedTreeElement = null; |
| 41 this.expandTreeElementsWhenArrowing = false; | 41 this.expandTreeElementsWhenArrowing = false; |
| 42 /** @type {?function(!TreeElement, !TreeElement):number} */ | 42 /** @type {?function(!UI.TreeElement, !UI.TreeElement):number} */ |
| 43 this._comparator = null; | 43 this._comparator = null; |
| 44 | 44 |
| 45 this.contentElement = this._rootElement._childrenListNode; | 45 this.contentElement = this._rootElement._childrenListNode; |
| 46 this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this)
, true); | 46 this.contentElement.addEventListener('keydown', this._treeKeyDown.bind(this)
, true); |
| 47 this.contentElement.addEventListener('focus', setFocused.bind(this, true), f
alse); | 47 this.contentElement.addEventListener('focus', setFocused.bind(this, true), f
alse); |
| 48 this.contentElement.addEventListener('blur', setFocused.bind(this, false), f
alse); | 48 this.contentElement.addEventListener('blur', setFocused.bind(this, false), f
alse); |
| 49 | 49 |
| 50 this.setFocusable(!nonFocusable); | 50 this.setFocusable(!nonFocusable); |
| 51 | 51 |
| 52 this.element = this.contentElement; | 52 this.element = this.contentElement; |
| 53 | 53 |
| 54 /** | 54 /** |
| 55 * @param {boolean} isFocused | 55 * @param {boolean} isFocused |
| 56 * @this {TreeOutline} | 56 * @this {UI.TreeOutline} |
| 57 */ | 57 */ |
| 58 function setFocused(isFocused) { | 58 function setFocused(isFocused) { |
| 59 this._focused = isFocused; | 59 this._focused = isFocused; |
| 60 if (this.selectedTreeElement) | 60 if (this.selectedTreeElement) |
| 61 this.selectedTreeElement._setFocused(this._focused); | 61 this.selectedTreeElement._setFocused(this._focused); |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 _createRootElement() { | 65 _createRootElement() { |
| 66 this._rootElement = new TreeElement(); | 66 this._rootElement = new UI.TreeElement(); |
| 67 this._rootElement.treeOutline = this; | 67 this._rootElement.treeOutline = this; |
| 68 this._rootElement.root = true; | 68 this._rootElement.root = true; |
| 69 this._rootElement.selectable = false; | 69 this._rootElement.selectable = false; |
| 70 this._rootElement.expanded = true; | 70 this._rootElement.expanded = true; |
| 71 this._rootElement._childrenListNode.classList.remove('children'); | 71 this._rootElement._childrenListNode.classList.remove('children'); |
| 72 } | 72 } |
| 73 | 73 |
| 74 /** | 74 /** |
| 75 * @return {!TreeElement} | 75 * @return {!UI.TreeElement} |
| 76 */ | 76 */ |
| 77 rootElement() { | 77 rootElement() { |
| 78 return this._rootElement; | 78 return this._rootElement; |
| 79 } | 79 } |
| 80 | 80 |
| 81 /** | 81 /** |
| 82 * @return {?TreeElement} | 82 * @return {?UI.TreeElement} |
| 83 */ | 83 */ |
| 84 firstChild() { | 84 firstChild() { |
| 85 return this._rootElement.firstChild(); | 85 return this._rootElement.firstChild(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 /** | 88 /** |
| 89 * @param {!TreeElement} child | 89 * @param {!UI.TreeElement} child |
| 90 */ | 90 */ |
| 91 appendChild(child) { | 91 appendChild(child) { |
| 92 this._rootElement.appendChild(child); | 92 this._rootElement.appendChild(child); |
| 93 } | 93 } |
| 94 | 94 |
| 95 /** | 95 /** |
| 96 * @param {!TreeElement} child | 96 * @param {!UI.TreeElement} child |
| 97 * @param {number} index | 97 * @param {number} index |
| 98 */ | 98 */ |
| 99 insertChild(child, index) { | 99 insertChild(child, index) { |
| 100 this._rootElement.insertChild(child, index); | 100 this._rootElement.insertChild(child, index); |
| 101 } | 101 } |
| 102 | 102 |
| 103 /** | 103 /** |
| 104 * @param {!TreeElement} child | 104 * @param {!UI.TreeElement} child |
| 105 */ | 105 */ |
| 106 removeChild(child) { | 106 removeChild(child) { |
| 107 this._rootElement.removeChild(child); | 107 this._rootElement.removeChild(child); |
| 108 } | 108 } |
| 109 | 109 |
| 110 removeChildren() { | 110 removeChildren() { |
| 111 this._rootElement.removeChildren(); | 111 this._rootElement.removeChildren(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 /** | 114 /** |
| 115 * @param {number} x | 115 * @param {number} x |
| 116 * @param {number} y | 116 * @param {number} y |
| 117 * @return {?TreeElement} | 117 * @return {?UI.TreeElement} |
| 118 */ | 118 */ |
| 119 treeElementFromPoint(x, y) { | 119 treeElementFromPoint(x, y) { |
| 120 var node = this.contentElement.ownerDocument.deepElementFromPoint(x, y); | 120 var node = this.contentElement.ownerDocument.deepElementFromPoint(x, y); |
| 121 if (!node) | 121 if (!node) |
| 122 return null; | 122 return null; |
| 123 | 123 |
| 124 var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(['ol', 'li']); | 124 var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(['ol', 'li']); |
| 125 if (listNode) | 125 if (listNode) |
| 126 return listNode.parentTreeElement || listNode.treeElement; | 126 return listNode.parentTreeElement || listNode.treeElement; |
| 127 return null; | 127 return null; |
| 128 } | 128 } |
| 129 | 129 |
| 130 /** | 130 /** |
| 131 * @param {?Event} event | 131 * @param {?Event} event |
| 132 * @return {?TreeElement} | 132 * @return {?UI.TreeElement} |
| 133 */ | 133 */ |
| 134 treeElementFromEvent(event) { | 134 treeElementFromEvent(event) { |
| 135 return event ? this.treeElementFromPoint(event.pageX, event.pageY) : null; | 135 return event ? this.treeElementFromPoint(event.pageX, event.pageY) : null; |
| 136 } | 136 } |
| 137 | 137 |
| 138 /** | 138 /** |
| 139 * @param {?function(!TreeElement, !TreeElement):number} comparator | 139 * @param {?function(!UI.TreeElement, !UI.TreeElement):number} comparator |
| 140 */ | 140 */ |
| 141 setComparator(comparator) { | 141 setComparator(comparator) { |
| 142 this._comparator = comparator; | 142 this._comparator = comparator; |
| 143 } | 143 } |
| 144 | 144 |
| 145 /** | 145 /** |
| 146 * @param {boolean} focusable | 146 * @param {boolean} focusable |
| 147 */ | 147 */ |
| 148 setFocusable(focusable) { | 148 setFocusable(focusable) { |
| 149 if (focusable) | 149 if (focusable) |
| 150 this.contentElement.setAttribute('tabIndex', 0); | 150 this.contentElement.setAttribute('tabIndex', 0); |
| 151 else | 151 else |
| 152 this.contentElement.removeAttribute('tabIndex'); | 152 this.contentElement.removeAttribute('tabIndex'); |
| 153 } | 153 } |
| 154 | 154 |
| 155 focus() { | 155 focus() { |
| 156 this.contentElement.focus(); | 156 this.contentElement.focus(); |
| 157 } | 157 } |
| 158 | 158 |
| 159 /** | 159 /** |
| 160 * @param {!TreeElement} element | 160 * @param {!UI.TreeElement} element |
| 161 */ | 161 */ |
| 162 _bindTreeElement(element) { | 162 _bindTreeElement(element) { |
| 163 if (element.treeOutline) | 163 if (element.treeOutline) |
| 164 console.error('Binding element for the second time: ' + new Error().stack)
; | 164 console.error('Binding element for the second time: ' + new Error().stack)
; |
| 165 element.treeOutline = this; | 165 element.treeOutline = this; |
| 166 element.onbind(); | 166 element.onbind(); |
| 167 } | 167 } |
| 168 | 168 |
| 169 /** | 169 /** |
| 170 * @param {!TreeElement} element | 170 * @param {!UI.TreeElement} element |
| 171 */ | 171 */ |
| 172 _unbindTreeElement(element) { | 172 _unbindTreeElement(element) { |
| 173 if (!element.treeOutline) | 173 if (!element.treeOutline) |
| 174 console.error('Unbinding element that was not bound: ' + new Error().stack
); | 174 console.error('Unbinding element that was not bound: ' + new Error().stack
); |
| 175 | 175 |
| 176 element.deselect(); | 176 element.deselect(); |
| 177 element.onunbind(); | 177 element.onunbind(); |
| 178 element.treeOutline = null; | 178 element.treeOutline = null; |
| 179 } | 179 } |
| 180 | 180 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 handled = this.selectedTreeElement.onenter(); | 238 handled = this.selectedTreeElement.onenter(); |
| 239 } else if (event.keyCode === UI.KeyboardShortcut.Keys.Space.code) { | 239 } else if (event.keyCode === UI.KeyboardShortcut.Keys.Space.code) { |
| 240 handled = this.selectedTreeElement.onspace(); | 240 handled = this.selectedTreeElement.onspace(); |
| 241 } | 241 } |
| 242 | 242 |
| 243 if (handled) | 243 if (handled) |
| 244 event.consume(true); | 244 event.consume(true); |
| 245 } | 245 } |
| 246 | 246 |
| 247 /** | 247 /** |
| 248 * @param {!TreeElement} treeElement | 248 * @param {!UI.TreeElement} treeElement |
| 249 * @param {boolean} center | 249 * @param {boolean} center |
| 250 */ | 250 */ |
| 251 _deferredScrollIntoView(treeElement, center) { | 251 _deferredScrollIntoView(treeElement, center) { |
| 252 if (!this._treeElementToScrollIntoView) | 252 if (!this._treeElementToScrollIntoView) |
| 253 this.element.window().requestAnimationFrame(deferredScrollIntoView.bind(th
is)); | 253 this.element.window().requestAnimationFrame(deferredScrollIntoView.bind(th
is)); |
| 254 this._treeElementToScrollIntoView = treeElement; | 254 this._treeElementToScrollIntoView = treeElement; |
| 255 this._centerUponScrollIntoView = center; | 255 this._centerUponScrollIntoView = center; |
| 256 /** | 256 /** |
| 257 * @this {TreeOutline} | 257 * @this {UI.TreeOutline} |
| 258 */ | 258 */ |
| 259 function deferredScrollIntoView() { | 259 function deferredScrollIntoView() { |
| 260 this._treeElementToScrollIntoView.listItemElement.scrollIntoViewIfNeeded(t
his._centerUponScrollIntoView); | 260 this._treeElementToScrollIntoView.listItemElement.scrollIntoViewIfNeeded(t
his._centerUponScrollIntoView); |
| 261 delete this._treeElementToScrollIntoView; | 261 delete this._treeElementToScrollIntoView; |
| 262 delete this._centerUponScrollIntoView; | 262 delete this._centerUponScrollIntoView; |
| 263 } | 263 } |
| 264 } | 264 } |
| 265 }; | 265 }; |
| 266 | 266 |
| 267 /** @enum {symbol} */ | 267 /** @enum {symbol} */ |
| 268 TreeOutline.Events = { | 268 UI.TreeOutline.Events = { |
| 269 ElementAttached: Symbol('ElementAttached'), | 269 ElementAttached: Symbol('ElementAttached'), |
| 270 ElementExpanded: Symbol('ElementExpanded'), | 270 ElementExpanded: Symbol('ElementExpanded'), |
| 271 ElementCollapsed: Symbol('ElementCollapsed'), | 271 ElementCollapsed: Symbol('ElementCollapsed'), |
| 272 ElementSelected: Symbol('ElementSelected') | 272 ElementSelected: Symbol('ElementSelected') |
| 273 }; | 273 }; |
| 274 | 274 |
| 275 /** | 275 /** |
| 276 * @unrestricted | 276 * @unrestricted |
| 277 */ | 277 */ |
| 278 var TreeOutlineInShadow = class extends TreeOutline { | 278 UI.TreeOutlineInShadow = class extends UI.TreeOutline { |
| 279 constructor() { | 279 constructor() { |
| 280 super(); | 280 super(); |
| 281 this.contentElement.classList.add('tree-outline'); | 281 this.contentElement.classList.add('tree-outline'); |
| 282 | 282 |
| 283 // Redefine element to the external one. | 283 // Redefine element to the external one. |
| 284 this.element = createElement('div'); | 284 this.element = createElement('div'); |
| 285 this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/treeo
utline.css'); | 285 this._shadowRoot = UI.createShadowRootWithCoreStyles(this.element, 'ui/treeo
utline.css'); |
| 286 this._disclosureElement = this._shadowRoot.createChild('div', 'tree-outline-
disclosure'); | 286 this._disclosureElement = this._shadowRoot.createChild('div', 'tree-outline-
disclosure'); |
| 287 this._disclosureElement.appendChild(this.contentElement); | 287 this._disclosureElement.appendChild(this.contentElement); |
| 288 this._renderSelection = true; | 288 this._renderSelection = true; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 300 } | 300 } |
| 301 | 301 |
| 302 makeDense() { | 302 makeDense() { |
| 303 this.contentElement.classList.add('tree-outline-dense'); | 303 this.contentElement.classList.add('tree-outline-dense'); |
| 304 } | 304 } |
| 305 }; | 305 }; |
| 306 | 306 |
| 307 /** | 307 /** |
| 308 * @unrestricted | 308 * @unrestricted |
| 309 */ | 309 */ |
| 310 var TreeElement = class { | 310 UI.TreeElement = class { |
| 311 /** | 311 /** |
| 312 * @param {(string|!Node)=} title | 312 * @param {(string|!Node)=} title |
| 313 * @param {boolean=} expandable | 313 * @param {boolean=} expandable |
| 314 */ | 314 */ |
| 315 constructor(title, expandable) { | 315 constructor(title, expandable) { |
| 316 /** @type {?TreeOutline} */ | 316 /** @type {?UI.TreeOutline} */ |
| 317 this.treeOutline = null; | 317 this.treeOutline = null; |
| 318 this.parent = null; | 318 this.parent = null; |
| 319 this.previousSibling = null; | 319 this.previousSibling = null; |
| 320 this.nextSibling = null; | 320 this.nextSibling = null; |
| 321 | 321 |
| 322 this._listItemNode = createElement('li'); | 322 this._listItemNode = createElement('li'); |
| 323 this._titleElement = this._listItemNode.createChild('span', 'tree-element-ti
tle'); | 323 this._titleElement = this._listItemNode.createChild('span', 'tree-element-ti
tle'); |
| 324 this._listItemNode.treeElement = this; | 324 this._listItemNode.treeElement = this; |
| 325 if (title) | 325 if (title) |
| 326 this.title = title; | 326 this.title = title; |
| 327 this._listItemNode.addEventListener('mousedown', this._handleMouseDown.bind(
this), false); | 327 this._listItemNode.addEventListener('mousedown', this._handleMouseDown.bind(
this), false); |
| 328 this._listItemNode.addEventListener('click', this._treeElementToggled.bind(t
his), false); | 328 this._listItemNode.addEventListener('click', this._treeElementToggled.bind(t
his), false); |
| 329 this._listItemNode.addEventListener('dblclick', this._handleDoubleClick.bind
(this), false); | 329 this._listItemNode.addEventListener('dblclick', this._handleDoubleClick.bind
(this), false); |
| 330 | 330 |
| 331 this._childrenListNode = createElement('ol'); | 331 this._childrenListNode = createElement('ol'); |
| 332 this._childrenListNode.parentTreeElement = this; | 332 this._childrenListNode.parentTreeElement = this; |
| 333 this._childrenListNode.classList.add('children'); | 333 this._childrenListNode.classList.add('children'); |
| 334 | 334 |
| 335 this._hidden = false; | 335 this._hidden = false; |
| 336 this._selectable = true; | 336 this._selectable = true; |
| 337 this.expanded = false; | 337 this.expanded = false; |
| 338 this.selected = false; | 338 this.selected = false; |
| 339 this.setExpandable(expandable || false); | 339 this.setExpandable(expandable || false); |
| 340 this._collapsible = true; | 340 this._collapsible = true; |
| 341 } | 341 } |
| 342 | 342 |
| 343 /** | 343 /** |
| 344 * @param {?TreeElement} ancestor | 344 * @param {?UI.TreeElement} ancestor |
| 345 * @return {boolean} | 345 * @return {boolean} |
| 346 */ | 346 */ |
| 347 hasAncestor(ancestor) { | 347 hasAncestor(ancestor) { |
| 348 if (!ancestor) | 348 if (!ancestor) |
| 349 return false; | 349 return false; |
| 350 | 350 |
| 351 var currentNode = this.parent; | 351 var currentNode = this.parent; |
| 352 while (currentNode) { | 352 while (currentNode) { |
| 353 if (ancestor === currentNode) | 353 if (ancestor === currentNode) |
| 354 return true; | 354 return true; |
| 355 currentNode = currentNode.parent; | 355 currentNode = currentNode.parent; |
| 356 } | 356 } |
| 357 | 357 |
| 358 return false; | 358 return false; |
| 359 } | 359 } |
| 360 | 360 |
| 361 /** | 361 /** |
| 362 * @param {?TreeElement} ancestor | 362 * @param {?UI.TreeElement} ancestor |
| 363 * @return {boolean} | 363 * @return {boolean} |
| 364 */ | 364 */ |
| 365 hasAncestorOrSelf(ancestor) { | 365 hasAncestorOrSelf(ancestor) { |
| 366 return this === ancestor || this.hasAncestor(ancestor); | 366 return this === ancestor || this.hasAncestor(ancestor); |
| 367 } | 367 } |
| 368 | 368 |
| 369 /** | 369 /** |
| 370 * @return {!Array.<!TreeElement>} | 370 * @return {!Array.<!UI.TreeElement>} |
| 371 */ | 371 */ |
| 372 children() { | 372 children() { |
| 373 return this._children || []; | 373 return this._children || []; |
| 374 } | 374 } |
| 375 | 375 |
| 376 /** | 376 /** |
| 377 * @return {number} | 377 * @return {number} |
| 378 */ | 378 */ |
| 379 childCount() { | 379 childCount() { |
| 380 return this._children ? this._children.length : 0; | 380 return this._children ? this._children.length : 0; |
| 381 } | 381 } |
| 382 | 382 |
| 383 /** | 383 /** |
| 384 * @return {?TreeElement} | 384 * @return {?UI.TreeElement} |
| 385 */ | 385 */ |
| 386 firstChild() { | 386 firstChild() { |
| 387 return this._children ? this._children[0] : null; | 387 return this._children ? this._children[0] : null; |
| 388 } | 388 } |
| 389 | 389 |
| 390 /** | 390 /** |
| 391 * @return {?TreeElement} | 391 * @return {?UI.TreeElement} |
| 392 */ | 392 */ |
| 393 lastChild() { | 393 lastChild() { |
| 394 return this._children ? this._children[this._children.length - 1] : null; | 394 return this._children ? this._children[this._children.length - 1] : null; |
| 395 } | 395 } |
| 396 | 396 |
| 397 /** | 397 /** |
| 398 * @param {number} index | 398 * @param {number} index |
| 399 * @return {?TreeElement} | 399 * @return {?UI.TreeElement} |
| 400 */ | 400 */ |
| 401 childAt(index) { | 401 childAt(index) { |
| 402 return this._children ? this._children[index] : null; | 402 return this._children ? this._children[index] : null; |
| 403 } | 403 } |
| 404 | 404 |
| 405 /** | 405 /** |
| 406 * @param {!TreeElement} child | 406 * @param {!UI.TreeElement} child |
| 407 * @return {number} | 407 * @return {number} |
| 408 */ | 408 */ |
| 409 indexOfChild(child) { | 409 indexOfChild(child) { |
| 410 return this._children ? this._children.indexOf(child) : -1; | 410 return this._children ? this._children.indexOf(child) : -1; |
| 411 } | 411 } |
| 412 | 412 |
| 413 /** | 413 /** |
| 414 * @param {!TreeElement} child | 414 * @param {!UI.TreeElement} child |
| 415 */ | 415 */ |
| 416 appendChild(child) { | 416 appendChild(child) { |
| 417 if (!this._children) | 417 if (!this._children) |
| 418 this._children = []; | 418 this._children = []; |
| 419 | 419 |
| 420 var insertionIndex; | 420 var insertionIndex; |
| 421 if (this.treeOutline && this.treeOutline._comparator) | 421 if (this.treeOutline && this.treeOutline._comparator) |
| 422 insertionIndex = this._children.lowerBound(child, this.treeOutline._compar
ator); | 422 insertionIndex = this._children.lowerBound(child, this.treeOutline._compar
ator); |
| 423 else | 423 else |
| 424 insertionIndex = this._children.length; | 424 insertionIndex = this._children.length; |
| 425 this.insertChild(child, insertionIndex); | 425 this.insertChild(child, insertionIndex); |
| 426 } | 426 } |
| 427 | 427 |
| 428 /** | 428 /** |
| 429 * @param {!TreeElement} child | 429 * @param {!UI.TreeElement} child |
| 430 * @param {number} index | 430 * @param {number} index |
| 431 */ | 431 */ |
| 432 insertChild(child, index) { | 432 insertChild(child, index) { |
| 433 if (!this._children) | 433 if (!this._children) |
| 434 this._children = []; | 434 this._children = []; |
| 435 | 435 |
| 436 if (!child) | 436 if (!child) |
| 437 throw 'child can\'t be undefined or null'; | 437 throw 'child can\'t be undefined or null'; |
| 438 | 438 |
| 439 console.assert( | 439 console.assert( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 461 child.parent = this; | 461 child.parent = this; |
| 462 | 462 |
| 463 if (this.treeOutline) | 463 if (this.treeOutline) |
| 464 this.treeOutline._bindTreeElement(child); | 464 this.treeOutline._bindTreeElement(child); |
| 465 for (var current = child.firstChild(); this.treeOutline && current; | 465 for (var current = child.firstChild(); this.treeOutline && current; |
| 466 current = current.traverseNextTreeElement(false, child, true)) | 466 current = current.traverseNextTreeElement(false, child, true)) |
| 467 this.treeOutline._bindTreeElement(current); | 467 this.treeOutline._bindTreeElement(current); |
| 468 child.onattach(); | 468 child.onattach(); |
| 469 child._ensureSelection(); | 469 child._ensureSelection(); |
| 470 if (this.treeOutline) | 470 if (this.treeOutline) |
| 471 this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementAttach
ed, child); | 471 this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementAtt
ached, child); |
| 472 var nextSibling = child.nextSibling ? child.nextSibling._listItemNode : null
; | 472 var nextSibling = child.nextSibling ? child.nextSibling._listItemNode : null
; |
| 473 this._childrenListNode.insertBefore(child._listItemNode, nextSibling); | 473 this._childrenListNode.insertBefore(child._listItemNode, nextSibling); |
| 474 this._childrenListNode.insertBefore(child._childrenListNode, nextSibling); | 474 this._childrenListNode.insertBefore(child._childrenListNode, nextSibling); |
| 475 if (child.selected) | 475 if (child.selected) |
| 476 child.select(); | 476 child.select(); |
| 477 if (child.expanded) | 477 if (child.expanded) |
| 478 child.expand(); | 478 child.expand(); |
| 479 } | 479 } |
| 480 | 480 |
| 481 /** | 481 /** |
| (...skipping 26 matching lines...) Expand all Loading... |
| 508 if (this.treeOutline) | 508 if (this.treeOutline) |
| 509 this.treeOutline._unbindTreeElement(child); | 509 this.treeOutline._unbindTreeElement(child); |
| 510 for (var current = child.firstChild(); this.treeOutline && current; | 510 for (var current = child.firstChild(); this.treeOutline && current; |
| 511 current = current.traverseNextTreeElement(false, child, true)) | 511 current = current.traverseNextTreeElement(false, child, true)) |
| 512 this.treeOutline._unbindTreeElement(current); | 512 this.treeOutline._unbindTreeElement(current); |
| 513 | 513 |
| 514 child._detach(); | 514 child._detach(); |
| 515 } | 515 } |
| 516 | 516 |
| 517 /** | 517 /** |
| 518 * @param {!TreeElement} child | 518 * @param {!UI.TreeElement} child |
| 519 */ | 519 */ |
| 520 removeChild(child) { | 520 removeChild(child) { |
| 521 if (!child) | 521 if (!child) |
| 522 throw 'child can\'t be undefined or null'; | 522 throw 'child can\'t be undefined or null'; |
| 523 if (child.parent !== this) | 523 if (child.parent !== this) |
| 524 return; | 524 return; |
| 525 | 525 |
| 526 var childIndex = this._children.indexOf(child); | 526 var childIndex = this._children.indexOf(child); |
| 527 if (childIndex === -1) | 527 if (childIndex === -1) |
| 528 throw 'child not found in this node\'s children'; | 528 throw 'child not found in this node\'s children'; |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 } | 826 } |
| 827 | 827 |
| 828 collapse() { | 828 collapse() { |
| 829 if (!this.expanded || !this._collapsible) | 829 if (!this.expanded || !this._collapsible) |
| 830 return; | 830 return; |
| 831 this._listItemNode.classList.remove('expanded'); | 831 this._listItemNode.classList.remove('expanded'); |
| 832 this._childrenListNode.classList.remove('expanded'); | 832 this._childrenListNode.classList.remove('expanded'); |
| 833 this.expanded = false; | 833 this.expanded = false; |
| 834 this.oncollapse(); | 834 this.oncollapse(); |
| 835 if (this.treeOutline) | 835 if (this.treeOutline) |
| 836 this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementCollap
sed, this); | 836 this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementCol
lapsed, this); |
| 837 } | 837 } |
| 838 | 838 |
| 839 collapseRecursively() { | 839 collapseRecursively() { |
| 840 var item = this; | 840 var item = this; |
| 841 while (item) { | 841 while (item) { |
| 842 if (item.expanded) | 842 if (item.expanded) |
| 843 item.collapse(); | 843 item.collapse(); |
| 844 item = item.traverseNextTreeElement(false, this, true); | 844 item = item.traverseNextTreeElement(false, this, true); |
| 845 } | 845 } |
| 846 } | 846 } |
| 847 | 847 |
| 848 expand() { | 848 expand() { |
| 849 if (!this._expandable || (this.expanded && this._children)) | 849 if (!this._expandable || (this.expanded && this._children)) |
| 850 return; | 850 return; |
| 851 | 851 |
| 852 // Set this before onpopulate. Since onpopulate can add elements, this makes | 852 // Set this before onpopulate. Since onpopulate can add elements, this makes |
| 853 // sure the expanded flag is true before calling those functions. This preve
nts the possibility | 853 // sure the expanded flag is true before calling those functions. This preve
nts the possibility |
| 854 // of an infinite loop if onpopulate were to call expand. | 854 // of an infinite loop if onpopulate were to call expand. |
| 855 | 855 |
| 856 this.expanded = true; | 856 this.expanded = true; |
| 857 | 857 |
| 858 this._populateIfNeeded(); | 858 this._populateIfNeeded(); |
| 859 this._listItemNode.classList.add('expanded'); | 859 this._listItemNode.classList.add('expanded'); |
| 860 this._childrenListNode.classList.add('expanded'); | 860 this._childrenListNode.classList.add('expanded'); |
| 861 | 861 |
| 862 if (this.treeOutline) { | 862 if (this.treeOutline) { |
| 863 this.onexpand(); | 863 this.onexpand(); |
| 864 this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementExpand
ed, this); | 864 this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementExp
anded, this); |
| 865 } | 865 } |
| 866 } | 866 } |
| 867 | 867 |
| 868 /** | 868 /** |
| 869 * @param {number=} maxDepth | 869 * @param {number=} maxDepth |
| 870 */ | 870 */ |
| 871 expandRecursively(maxDepth) { | 871 expandRecursively(maxDepth) { |
| 872 var item = this; | 872 var item = this; |
| 873 var info = {}; | 873 var info = {}; |
| 874 var depth = 0; | 874 var depth = 0; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 | 1003 |
| 1004 if (!omitFocus) | 1004 if (!omitFocus) |
| 1005 this.treeOutline.focus(); | 1005 this.treeOutline.focus(); |
| 1006 | 1006 |
| 1007 // Focusing on another node may detach "this" from tree. | 1007 // Focusing on another node may detach "this" from tree. |
| 1008 if (!this.treeOutline) | 1008 if (!this.treeOutline) |
| 1009 return false; | 1009 return false; |
| 1010 this.treeOutline.selectedTreeElement = this; | 1010 this.treeOutline.selectedTreeElement = this; |
| 1011 this._listItemNode.classList.add('selected'); | 1011 this._listItemNode.classList.add('selected'); |
| 1012 this._setFocused(this.treeOutline._focused); | 1012 this._setFocused(this.treeOutline._focused); |
| 1013 this.treeOutline.dispatchEventToListeners(TreeOutline.Events.ElementSelected
, this); | 1013 this.treeOutline.dispatchEventToListeners(UI.TreeOutline.Events.ElementSelec
ted, this); |
| 1014 return this.onselect(selectedByUser); | 1014 return this.onselect(selectedByUser); |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 /** | 1017 /** |
| 1018 * @param {boolean=} omitFocus | 1018 * @param {boolean=} omitFocus |
| 1019 */ | 1019 */ |
| 1020 revealAndSelect(omitFocus) { | 1020 revealAndSelect(omitFocus) { |
| 1021 this.reveal(true); | 1021 this.reveal(true); |
| 1022 this.select(omitFocus); | 1022 this.select(omitFocus); |
| 1023 } | 1023 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 /** | 1093 /** |
| 1094 * @param {boolean=} selectedByUser | 1094 * @param {boolean=} selectedByUser |
| 1095 * @return {boolean} | 1095 * @return {boolean} |
| 1096 */ | 1096 */ |
| 1097 onselect(selectedByUser) { | 1097 onselect(selectedByUser) { |
| 1098 return false; | 1098 return false; |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 /** | 1101 /** |
| 1102 * @param {boolean} skipUnrevealed | 1102 * @param {boolean} skipUnrevealed |
| 1103 * @param {?TreeElement=} stayWithin | 1103 * @param {?UI.TreeElement=} stayWithin |
| 1104 * @param {boolean=} dontPopulate | 1104 * @param {boolean=} dontPopulate |
| 1105 * @param {!Object=} info | 1105 * @param {!Object=} info |
| 1106 * @return {?TreeElement} | 1106 * @return {?UI.TreeElement} |
| 1107 */ | 1107 */ |
| 1108 traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info) { | 1108 traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate, info) { |
| 1109 if (!dontPopulate) | 1109 if (!dontPopulate) |
| 1110 this._populateIfNeeded(); | 1110 this._populateIfNeeded(); |
| 1111 | 1111 |
| 1112 if (info) | 1112 if (info) |
| 1113 info.depthChange = 0; | 1113 info.depthChange = 0; |
| 1114 | 1114 |
| 1115 var element = skipUnrevealed ? (this.revealed() ? this.firstChild() : null)
: this.firstChild(); | 1115 var element = skipUnrevealed ? (this.revealed() ? this.firstChild() : null)
: this.firstChild(); |
| 1116 if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) { | 1116 if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1137 | 1137 |
| 1138 if (!element || element.root) | 1138 if (!element || element.root) |
| 1139 return null; | 1139 return null; |
| 1140 | 1140 |
| 1141 return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) :
element.nextSibling); | 1141 return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) :
element.nextSibling); |
| 1142 } | 1142 } |
| 1143 | 1143 |
| 1144 /** | 1144 /** |
| 1145 * @param {boolean} skipUnrevealed | 1145 * @param {boolean} skipUnrevealed |
| 1146 * @param {boolean=} dontPopulate | 1146 * @param {boolean=} dontPopulate |
| 1147 * @return {?TreeElement} | 1147 * @return {?UI.TreeElement} |
| 1148 */ | 1148 */ |
| 1149 traversePreviousTreeElement(skipUnrevealed, dontPopulate) { | 1149 traversePreviousTreeElement(skipUnrevealed, dontPopulate) { |
| 1150 var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : nul
l) : this.previousSibling; | 1150 var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : nul
l) : this.previousSibling; |
| 1151 if (!dontPopulate && element) | 1151 if (!dontPopulate && element) |
| 1152 element._populateIfNeeded(); | 1152 element._populateIfNeeded(); |
| 1153 | 1153 |
| 1154 while (element && (skipUnrevealed ? (element.revealed() && element.expanded
? element.lastChild() : null) : | 1154 while (element && (skipUnrevealed ? (element.revealed() && element.expanded
? element.lastChild() : null) : |
| 1155 element.lastChild())) { | 1155 element.lastChild())) { |
| 1156 if (!dontPopulate) | 1156 if (!dontPopulate) |
| 1157 element._populateIfNeeded(); | 1157 element._populateIfNeeded(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1171 | 1171 |
| 1172 /** | 1172 /** |
| 1173 * @return {boolean} | 1173 * @return {boolean} |
| 1174 */ | 1174 */ |
| 1175 isEventWithinDisclosureTriangle(event) { | 1175 isEventWithinDisclosureTriangle(event) { |
| 1176 // FIXME: We should not use getComputedStyle(). For that we need to get rid
of using ::before for disclosure triangle. (http://webk.it/74446) | 1176 // FIXME: We should not use getComputedStyle(). For that we need to get rid
of using ::before for disclosure triangle. (http://webk.it/74446) |
| 1177 var paddingLeftValue = window.getComputedStyle(this._listItemNode).paddingLe
ft; | 1177 var paddingLeftValue = window.getComputedStyle(this._listItemNode).paddingLe
ft; |
| 1178 console.assert(paddingLeftValue.endsWith('px')); | 1178 console.assert(paddingLeftValue.endsWith('px')); |
| 1179 var computedLeftPadding = parseFloat(paddingLeftValue); | 1179 var computedLeftPadding = parseFloat(paddingLeftValue); |
| 1180 var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding; | 1180 var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding; |
| 1181 return event.pageX >= left && event.pageX <= left + TreeElement._ArrowToggle
Width && this._expandable; | 1181 return event.pageX >= left && event.pageX <= left + UI.TreeElement._ArrowTog
gleWidth && this._expandable; |
| 1182 } | 1182 } |
| 1183 }; | 1183 }; |
| 1184 | 1184 |
| 1185 /** @const */ | 1185 /** @const */ |
| 1186 TreeElement._ArrowToggleWidth = 10; | 1186 UI.TreeElement._ArrowToggleWidth = 10; |
| OLD | NEW |