OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * Copyright (C) 2011 Google Inc. All Rights Reserved. | 3 * Copyright (C) 2011 Google Inc. All Rights Reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
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 23 matching lines...) Expand all Loading... |
34 this.contentElement = createElementWithClass("div", "widget"); | 34 this.contentElement = createElementWithClass("div", "widget"); |
35 if (isWebComponent) { | 35 if (isWebComponent) { |
36 this.element = createElementWithClass("div", "vbox flex-auto"); | 36 this.element = createElementWithClass("div", "vbox flex-auto"); |
37 this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.elem
ent); | 37 this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.elem
ent); |
38 this._shadowRoot.appendChild(this.contentElement); | 38 this._shadowRoot.appendChild(this.contentElement); |
39 } else { | 39 } else { |
40 this.element = this.contentElement; | 40 this.element = this.contentElement; |
41 } | 41 } |
42 this._isWebComponent = isWebComponent; | 42 this._isWebComponent = isWebComponent; |
43 this.element.__widget = this; | 43 this.element.__widget = this; |
44 this._visible = false; | 44 this._visible = true; |
45 this._isRoot = false; | 45 this._isRoot = false; |
46 this._isShowing = false; | 46 this._isShowing = false; |
47 this._children = []; | 47 this._children = []; |
48 this._hideOnDetach = false; | 48 this._hideOnDetach = false; |
49 this._notificationDepth = 0; | 49 this._notificationDepth = 0; |
50 this._invalidationsSuspended = 0; | |
51 } | 50 } |
52 | 51 |
53 WebInspector.Widget.prototype = { | 52 WebInspector.Widget.prototype = { |
54 markAsRoot: function() | 53 markAsRoot: function() |
55 { | 54 { |
56 WebInspector.Widget.__assert(!this.element.parentElement, "Attempt to ma
rk as root attached node"); | 55 WebInspector.Widget.__assert(!this.element.parentElement, "Attempt to ma
rk as root attached node"); |
57 this._isRoot = true; | 56 this._isRoot = true; |
58 }, | 57 }, |
59 | 58 |
60 /** | 59 /** |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 */ | 112 */ |
114 _inNotification: function() | 113 _inNotification: function() |
115 { | 114 { |
116 return !!this._notificationDepth || (this._parentWidget && this._parentW
idget._inNotification()); | 115 return !!this._notificationDepth || (this._parentWidget && this._parentW
idget._inNotification()); |
117 }, | 116 }, |
118 | 117 |
119 _parentIsShowing: function() | 118 _parentIsShowing: function() |
120 { | 119 { |
121 if (this._isRoot) | 120 if (this._isRoot) |
122 return true; | 121 return true; |
123 return !!this._parentWidget && this._parentWidget.isShowing(); | 122 return this._parentWidget && this._parentWidget.isShowing(); |
124 }, | 123 }, |
125 | 124 |
126 /** | 125 /** |
127 * @param {function(this:WebInspector.Widget)} method | 126 * @param {function(this:WebInspector.Widget)} method |
128 */ | 127 */ |
129 _callOnVisibleChildren: function(method) | 128 _callOnVisibleChildren: function(method) |
130 { | 129 { |
131 var copy = this._children.slice(); | 130 var copy = this._children.slice(); |
132 for (var i = 0; i < copy.length; ++i) { | 131 for (var i = 0; i < copy.length; ++i) { |
133 if (copy[i]._parentWidget === this && copy[i]._visible) | 132 if (copy[i]._parentWidget === this && copy[i]._visible) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 198 |
200 onResize: function() | 199 onResize: function() |
201 { | 200 { |
202 }, | 201 }, |
203 | 202 |
204 onLayout: function() | 203 onLayout: function() |
205 { | 204 { |
206 }, | 205 }, |
207 | 206 |
208 /** | 207 /** |
209 * @param {!Element} parentElement | 208 * @param {?Element} parentElement |
210 * @param {?Element=} insertBefore | 209 * @param {?Element=} insertBefore |
211 */ | 210 */ |
212 show: function(parentElement, insertBefore) | 211 show: function(parentElement, insertBefore) |
213 { | 212 { |
214 this.attach(parentElement, insertBefore); | |
215 this.showWidget(); | |
216 }, | |
217 | |
218 /** | |
219 * @param {!Element} parentElement | |
220 * @param {?Element=} insertBefore | |
221 */ | |
222 attach: function(parentElement, insertBefore) | |
223 { | |
224 WebInspector.Widget.__assert(parentElement, "Attempt to attach widget wi
th no parent element"); | 213 WebInspector.Widget.__assert(parentElement, "Attempt to attach widget wi
th no parent element"); |
225 | 214 |
226 // Update widget hierarchy. | 215 // Update widget hierarchy. |
227 var currentParent = parentElement; | 216 if (this.element.parentElement !== parentElement) { |
228 while (currentParent && !currentParent.__widget) | 217 if (this.element.parentElement) |
229 currentParent = currentParent.parentElementOrShadowHost(); | 218 this.detach(); |
230 var newParentWidget = currentParent ? currentParent.__widget : null; | |
231 | 219 |
232 if (this._parentWidget && newParentWidget !== this._parentWidget) { | 220 var currentParent = parentElement; |
233 // Reparent. | 221 while (currentParent && !currentParent.__widget) |
234 this.detach(); | 222 currentParent = currentParent.parentElementOrShadowHost(); |
| 223 |
| 224 if (currentParent) { |
| 225 this._parentWidget = currentParent.__widget; |
| 226 this._parentWidget._children.push(this); |
| 227 this._isRoot = false; |
| 228 } else |
| 229 WebInspector.Widget.__assert(this._isRoot, "Attempt to attach wi
dget to orphan node"); |
| 230 } else if (this._visible) { |
| 231 return; |
235 } | 232 } |
236 | 233 |
237 if (newParentWidget) { | |
238 if (this._parentWidget !== newParentWidget) { | |
239 this._parentWidget = newParentWidget; | |
240 this._parentWidget._children.push(this); | |
241 } | |
242 this._isRoot = false; | |
243 } else { | |
244 WebInspector.Widget.__assert(this._isRoot, "Attempt to attach widget
to orphan node"); | |
245 } | |
246 | |
247 this._parentElement = parentElement; | |
248 this._insertBeforeElement = insertBefore; | |
249 }, | |
250 | |
251 showWidget: function() | |
252 { | |
253 WebInspector.Widget.__assert(this._parentElement, "Attempt to show detac
hed widget"); | |
254 if (this._visible) | |
255 return; | |
256 this._visible = true; | 234 this._visible = true; |
257 | 235 |
258 if (this._parentIsShowing()) | 236 if (this._parentIsShowing()) |
259 this._processWillShow(); | 237 this._processWillShow(); |
260 | 238 |
261 this.element.classList.remove("hidden"); | 239 this.element.classList.remove("hidden"); |
262 | 240 |
263 // Reparent | 241 // Reparent |
264 if (this.element.parentElement !== this._parentElement) { | 242 if (this.element.parentElement !== parentElement) { |
265 WebInspector.Widget._incrementWidgetCounter(this._parentElement, thi
s.element); | 243 WebInspector.Widget._incrementWidgetCounter(parentElement, this.elem
ent); |
266 if (this._insertBeforeElement) | 244 if (insertBefore) |
267 WebInspector.Widget._originalInsertBefore.call(this._parentEleme
nt, this.element, this._insertBeforeElement); | 245 WebInspector.Widget._originalInsertBefore.call(parentElement, th
is.element, insertBefore); |
268 else | 246 else |
269 WebInspector.Widget._originalAppendChild.call(this._parentElemen
t, this.element); | 247 WebInspector.Widget._originalAppendChild.call(parentElement, thi
s.element); |
270 } | 248 } |
271 | 249 |
272 if (this._parentIsShowing()) | 250 if (this._parentIsShowing()) |
273 this._processWasShown(); | 251 this._processWasShown(); |
274 | 252 |
275 if (this._parentWidget && this._hasNonZeroConstraints()) | 253 if (this._parentWidget && this._hasNonZeroConstraints()) |
276 this._parentWidget.invalidateConstraints(); | 254 this._parentWidget.invalidateConstraints(); |
277 else | 255 else |
278 this._processOnResize(); | 256 this._processOnResize(); |
279 }, | 257 }, |
280 | 258 |
281 hideWidget: function() | |
282 { | |
283 if (!this._parentWidget) | |
284 return; | |
285 this._hideWidget(); | |
286 }, | |
287 | |
288 /** | 259 /** |
289 * @param {boolean=} overrideHideOnDetach | 260 * @param {boolean=} overrideHideOnDetach |
290 */ | 261 */ |
291 _hideWidget: function(overrideHideOnDetach) | 262 detach: function(overrideHideOnDetach) |
292 { | 263 { |
293 WebInspector.Widget.__assert(this._parentElement, "Attempt to hide detac
hed widget"); | 264 var parentElement = this.element.parentElement; |
294 if (!this._visible) | 265 if (!parentElement) |
295 return; | 266 return; |
296 this._visible = false; | |
297 var parentElement = this._parentElement; | |
298 | 267 |
299 if (this._parentIsShowing()) | 268 if (this._parentIsShowing()) |
300 this._processWillHide(); | 269 this._processWillHide(); |
301 | 270 |
302 if (!overrideHideOnDetach && this.shouldHideOnDetach()) { | 271 if (!overrideHideOnDetach && this.shouldHideOnDetach()) { |
303 this.element.classList.add("hidden"); | 272 this.element.classList.add("hidden"); |
304 } else { | 273 this._visible = false; |
305 // Force legal removal | 274 if (this._parentIsShowing()) |
306 WebInspector.Widget._decrementWidgetCounter(parentElement, this.elem
ent); | 275 this._processWasHidden(); |
307 WebInspector.Widget._originalRemoveChild.call(parentElement, this.el
ement); | 276 if (this._parentWidget && this._hasNonZeroConstraints()) |
| 277 this._parentWidget.invalidateConstraints(); |
| 278 return; |
308 } | 279 } |
309 | 280 |
| 281 // Force legal removal |
| 282 WebInspector.Widget._decrementWidgetCounter(parentElement, this.element)
; |
| 283 WebInspector.Widget._originalRemoveChild.call(parentElement, this.elemen
t); |
| 284 |
| 285 this._visible = false; |
310 if (this._parentIsShowing()) | 286 if (this._parentIsShowing()) |
311 this._processWasHidden(); | 287 this._processWasHidden(); |
312 if (this._hasNonZeroConstraints()) | |
313 this._parentWidget.invalidateConstraints(); | |
314 }, | |
315 | |
316 detach: function() | |
317 { | |
318 if (!this._parentWidget) | |
319 return; | |
320 | |
321 if (this._visible) | |
322 this._hideWidget(true); | |
323 | 288 |
324 // Update widget hierarchy. | 289 // Update widget hierarchy. |
325 if (this._parentWidget) { | 290 if (this._parentWidget) { |
326 var childIndex = this._parentWidget._children.indexOf(this); | 291 var childIndex = this._parentWidget._children.indexOf(this); |
327 WebInspector.Widget.__assert(childIndex >= 0, "Attempt to remove non
-child widget"); | 292 WebInspector.Widget.__assert(childIndex >= 0, "Attempt to remove non
-child widget"); |
328 this._parentWidget._children.splice(childIndex, 1); | 293 this._parentWidget._children.splice(childIndex, 1); |
329 this._parentWidget.childWasDetached(this); | 294 this._parentWidget.childWasDetached(this); |
330 var parent = this._parentWidget; | 295 var parent = this._parentWidget; |
331 this._parentWidget = null; | 296 this._parentWidget = null; |
332 this._parentElement = null; | 297 if (this._hasNonZeroConstraints()) |
333 this._insertBeforeElement = null; | 298 parent.invalidateConstraints(); |
334 } else { | 299 } else |
335 WebInspector.Widget.__assert(this._isRoot, "Removing non-root widget
from DOM"); | 300 WebInspector.Widget.__assert(this._isRoot, "Removing non-root widget
from DOM"); |
336 } | |
337 }, | 301 }, |
338 | 302 |
339 detachChildWidgets: function() | 303 detachChildWidgets: function() |
340 { | 304 { |
341 var children = this._children.slice(); | 305 var children = this._children.slice(); |
342 for (var i = 0; i < children.length; ++i) | 306 for (var i = 0; i < children.length; ++i) |
343 children[i].detach(); | 307 children[i].detach(); |
344 }, | 308 }, |
345 | 309 |
346 /** | 310 /** |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 | 472 |
509 /** | 473 /** |
510 * @return {boolean} | 474 * @return {boolean} |
511 */ | 475 */ |
512 _hasNonZeroConstraints: function() | 476 _hasNonZeroConstraints: function() |
513 { | 477 { |
514 var constraints = this.constraints(); | 478 var constraints = this.constraints(); |
515 return !!(constraints.minimum.width || constraints.minimum.height || con
straints.preferred.width || constraints.preferred.height); | 479 return !!(constraints.minimum.width || constraints.minimum.height || con
straints.preferred.width || constraints.preferred.height); |
516 }, | 480 }, |
517 | 481 |
518 suspendInvalidations() | |
519 { | |
520 ++this._invalidationsSuspended; | |
521 }, | |
522 | |
523 resumeInvalidations() | |
524 { | |
525 --this._invalidationsSuspended; | |
526 if (!this._invalidationsSuspended && this._invalidationsRequested) | |
527 this.invalidateConstraints(); | |
528 }, | |
529 | |
530 invalidateConstraints: function() | 482 invalidateConstraints: function() |
531 { | 483 { |
532 if (this._invalidationsSuspended) { | |
533 this._invalidationsRequested = true; | |
534 return; | |
535 } | |
536 this._invalidationsRequested = false; | |
537 var cached = this._cachedConstraints; | 484 var cached = this._cachedConstraints; |
538 delete this._cachedConstraints; | 485 delete this._cachedConstraints; |
539 var actual = this.constraints(); | 486 var actual = this.constraints(); |
540 if (!actual.isEqual(cached) && this._parentWidget) | 487 if (!actual.isEqual(cached) && this._parentWidget) |
541 this._parentWidget.invalidateConstraints(); | 488 this._parentWidget.invalidateConstraints(); |
542 else | 489 else |
543 this.doLayout(); | 490 this.doLayout(); |
544 }, | 491 }, |
545 | 492 |
546 invalidateSize: function() | 493 invalidateSize: function() |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 { | 752 { |
806 WebInspector.Widget.__assert(!child.__widgetCounter && !child.__widget, "Att
empt to remove element containing widget via regular DOM operation"); | 753 WebInspector.Widget.__assert(!child.__widgetCounter && !child.__widget, "Att
empt to remove element containing widget via regular DOM operation"); |
807 return WebInspector.Widget._originalRemoveChild.call(this, child); | 754 return WebInspector.Widget._originalRemoveChild.call(this, child); |
808 } | 755 } |
809 | 756 |
810 Element.prototype.removeChildren = function() | 757 Element.prototype.removeChildren = function() |
811 { | 758 { |
812 WebInspector.Widget.__assert(!this.__widgetCounter, "Attempt to remove eleme
nt containing widget via regular DOM operation"); | 759 WebInspector.Widget.__assert(!this.__widgetCounter, "Attempt to remove eleme
nt containing widget via regular DOM operation"); |
813 WebInspector.Widget._originalRemoveChildren.call(this); | 760 WebInspector.Widget._originalRemoveChildren.call(this); |
814 } | 761 } |
OLD | NEW |