| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved. | 
|  | 3  * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> | 
|  | 4  * Copyright (C) 2009 Joseph Pecoraro | 
|  | 5  * | 
|  | 6  * Redistribution and use in source and binary forms, with or without | 
|  | 7  * modification, are permitted provided that the following conditions | 
|  | 8  * are met: | 
|  | 9  * | 
|  | 10  * 1.  Redistributions of source code must retain the above copyright | 
|  | 11  *     notice, this list of conditions and the following disclaimer. | 
|  | 12  * 2.  Redistributions in binary form must reproduce the above copyright | 
|  | 13  *     notice, this list of conditions and the following disclaimer in the | 
|  | 14  *     documentation and/or other materials provided with the distribution. | 
|  | 15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 
|  | 16  *     its contributors may be used to endorse or promote products derived | 
|  | 17  *     from this software without specific prior written permission. | 
|  | 18  * | 
|  | 19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 
|  | 20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
|  | 21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
|  | 22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 
|  | 23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
|  | 24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
|  | 25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
|  | 26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | 27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
|  | 28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 29  */ | 
|  | 30 | 
|  | 31 WebInspector.ElementsPanel = function() | 
|  | 32 { | 
|  | 33     WebInspector.Panel.call(this); | 
|  | 34 | 
|  | 35     this.element.addStyleClass("elements"); | 
|  | 36 | 
|  | 37     this.contentElement = document.createElement("div"); | 
|  | 38     this.contentElement.id = "elements-content"; | 
|  | 39     this.contentElement.className = "outline-disclosure"; | 
|  | 40 | 
|  | 41     this.treeOutline = new WebInspector.ElementsTreeOutline(); | 
|  | 42     this.treeOutline.panel = this; | 
|  | 43     this.treeOutline.includeRootDOMNode = false; | 
|  | 44     this.treeOutline.selectEnabled = true; | 
|  | 45 | 
|  | 46     this.treeOutline.focusedNodeChanged = function(forceUpdate) | 
|  | 47     { | 
|  | 48         if (this.panel.visible && WebInspector.currentFocusElement !== document.
      getElementById("search")) | 
|  | 49             WebInspector.currentFocusElement = document.getElementById("main-pan
      els"); | 
|  | 50 | 
|  | 51         this.panel.updateBreadcrumb(forceUpdate); | 
|  | 52 | 
|  | 53         for (var pane in this.panel.sidebarPanes) | 
|  | 54            this.panel.sidebarPanes[pane].needsUpdate = true; | 
|  | 55 | 
|  | 56         this.panel.updateStyles(true); | 
|  | 57         this.panel.updateMetrics(); | 
|  | 58         this.panel.updateProperties(); | 
|  | 59 | 
|  | 60         if (InspectorController.searchingForNode()) { | 
|  | 61             InspectorController.toggleNodeSearch(); | 
|  | 62             this.panel.nodeSearchButton.removeStyleClass("toggled-on"); | 
|  | 63         } | 
|  | 64         if (this._focusedDOMNode) | 
|  | 65             InjectedScriptAccess.addInspectedNode(this._focusedDOMNode.id, funct
      ion() {}); | 
|  | 66     }; | 
|  | 67 | 
|  | 68     this.contentElement.appendChild(this.treeOutline.element); | 
|  | 69 | 
|  | 70     this.crumbsElement = document.createElement("div"); | 
|  | 71     this.crumbsElement.className = "crumbs"; | 
|  | 72     this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bi
      nd(this), false); | 
|  | 73     this.crumbsElement.addEventListener("mouseout", this._mouseMovedOutOfCrumbs.
      bind(this), false); | 
|  | 74 | 
|  | 75     this.sidebarPanes = {}; | 
|  | 76     this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(); | 
|  | 77     this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane(); | 
|  | 78     this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane(); | 
|  | 79 | 
|  | 80     this.sidebarPanes.styles.onexpand = this.updateStyles.bind(this); | 
|  | 81     this.sidebarPanes.metrics.onexpand = this.updateMetrics.bind(this); | 
|  | 82     this.sidebarPanes.properties.onexpand = this.updateProperties.bind(this); | 
|  | 83 | 
|  | 84     this.sidebarPanes.styles.expanded = true; | 
|  | 85 | 
|  | 86     this.sidebarPanes.styles.addEventListener("style edited", this._stylesPaneEd
      ited, this); | 
|  | 87     this.sidebarPanes.styles.addEventListener("style property toggled", this._st
      ylesPaneEdited, this); | 
|  | 88     this.sidebarPanes.metrics.addEventListener("metrics edited", this._metricsPa
      neEdited, this); | 
|  | 89 | 
|  | 90     this.sidebarElement = document.createElement("div"); | 
|  | 91     this.sidebarElement.id = "elements-sidebar"; | 
|  | 92 | 
|  | 93     this.sidebarElement.appendChild(this.sidebarPanes.styles.element); | 
|  | 94     this.sidebarElement.appendChild(this.sidebarPanes.metrics.element); | 
|  | 95     this.sidebarElement.appendChild(this.sidebarPanes.properties.element); | 
|  | 96 | 
|  | 97     this.sidebarResizeElement = document.createElement("div"); | 
|  | 98     this.sidebarResizeElement.className = "sidebar-resizer-vertical"; | 
|  | 99     this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarRes
      izerDragStart.bind(this), false); | 
|  | 100 | 
|  | 101     this.nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIStri
      ng("Select an element in the page to inspect it."), "node-search-status-bar-item
      "); | 
|  | 102     this.nodeSearchButton.addEventListener("click", this._nodeSearchButtonClicke
      d.bind(this), false); | 
|  | 103 | 
|  | 104     this.searchingForNode = false; | 
|  | 105 | 
|  | 106     this.element.appendChild(this.contentElement); | 
|  | 107     this.element.appendChild(this.sidebarElement); | 
|  | 108     this.element.appendChild(this.sidebarResizeElement); | 
|  | 109 | 
|  | 110     this._changedStyles = {}; | 
|  | 111 | 
|  | 112     this.reset(); | 
|  | 113 } | 
|  | 114 | 
|  | 115 WebInspector.ElementsPanel.prototype = { | 
|  | 116     toolbarItemClass: "elements", | 
|  | 117 | 
|  | 118     get toolbarItemLabel() | 
|  | 119     { | 
|  | 120         return WebInspector.UIString("Elements"); | 
|  | 121     }, | 
|  | 122 | 
|  | 123     get statusBarItems() | 
|  | 124     { | 
|  | 125         return [this.nodeSearchButton.element, this.crumbsElement]; | 
|  | 126     }, | 
|  | 127 | 
|  | 128     updateStatusBarItems: function() | 
|  | 129     { | 
|  | 130         this.updateBreadcrumbSizes(); | 
|  | 131     }, | 
|  | 132 | 
|  | 133     show: function() | 
|  | 134     { | 
|  | 135         WebInspector.Panel.prototype.show.call(this); | 
|  | 136         this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth
       - 3) + "px"; | 
|  | 137         this.updateBreadcrumb(); | 
|  | 138         this.treeOutline.updateSelection(); | 
|  | 139         if (this.recentlyModifiedNodes.length) | 
|  | 140             this._updateModifiedNodes(); | 
|  | 141     }, | 
|  | 142 | 
|  | 143     hide: function() | 
|  | 144     { | 
|  | 145         WebInspector.Panel.prototype.hide.call(this); | 
|  | 146 | 
|  | 147         WebInspector.hoveredDOMNode = null; | 
|  | 148 | 
|  | 149         if (InspectorController.searchingForNode()) { | 
|  | 150             InspectorController.toggleNodeSearch(); | 
|  | 151             this.nodeSearchButton.toggled = false; | 
|  | 152         } | 
|  | 153     }, | 
|  | 154 | 
|  | 155     resize: function() | 
|  | 156     { | 
|  | 157         this.treeOutline.updateSelection(); | 
|  | 158         this.updateBreadcrumbSizes(); | 
|  | 159     }, | 
|  | 160 | 
|  | 161     reset: function() | 
|  | 162     { | 
|  | 163         this.rootDOMNode = null; | 
|  | 164         this.focusedDOMNode = null; | 
|  | 165 | 
|  | 166         WebInspector.hoveredDOMNode = null; | 
|  | 167 | 
|  | 168         if (InspectorController.searchingForNode()) { | 
|  | 169             InspectorController.toggleNodeSearch(); | 
|  | 170             this.nodeSearchButton.toggled = false; | 
|  | 171         } | 
|  | 172 | 
|  | 173         this.recentlyModifiedNodes = []; | 
|  | 174 | 
|  | 175         delete this.currentQuery; | 
|  | 176         this.searchCanceled(); | 
|  | 177 | 
|  | 178         var domWindow = WebInspector.domAgent.domWindow; | 
|  | 179         if (!domWindow || !domWindow.document || !domWindow.document.firstChild) | 
|  | 180             return; | 
|  | 181 | 
|  | 182         // If the window isn't visible, return early so the DOM tree isn't built | 
|  | 183         // and mutation event listeners are not added. | 
|  | 184         if (!InspectorController.isWindowVisible()) | 
|  | 185             return; | 
|  | 186 | 
|  | 187         var inspectedRootDocument = domWindow.document; | 
|  | 188         inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInse
      rted.bind(this)); | 
|  | 189         inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemov
      ed.bind(this)); | 
|  | 190 | 
|  | 191         this.rootDOMNode = inspectedRootDocument; | 
|  | 192 | 
|  | 193         var canidateFocusNode = inspectedRootDocument.body || inspectedRootDocum
      ent.documentElement; | 
|  | 194         if (canidateFocusNode) { | 
|  | 195             this.treeOutline.suppressSelectHighlight = true; | 
|  | 196             this.focusedDOMNode = canidateFocusNode; | 
|  | 197             this.treeOutline.suppressSelectHighlight = false; | 
|  | 198 | 
|  | 199             if (this.treeOutline.selectedTreeElement) | 
|  | 200                 this.treeOutline.selectedTreeElement.expand(); | 
|  | 201         } | 
|  | 202     }, | 
|  | 203 | 
|  | 204     searchCanceled: function() | 
|  | 205     { | 
|  | 206         if (this._searchResults) { | 
|  | 207             for (var i = 0; i < this._searchResults.length; ++i) { | 
|  | 208                 var treeElement = this.treeOutline.findTreeElement(this._searchR
      esults[i]); | 
|  | 209                 if (treeElement) | 
|  | 210                     treeElement.highlighted = false; | 
|  | 211             } | 
|  | 212         } | 
|  | 213 | 
|  | 214         WebInspector.updateSearchMatchesCount(0, this); | 
|  | 215 | 
|  | 216         this._currentSearchResultIndex = 0; | 
|  | 217         this._searchResults = []; | 
|  | 218         InjectedScriptAccess.searchCanceled(function() {}); | 
|  | 219     }, | 
|  | 220 | 
|  | 221     performSearch: function(query) | 
|  | 222     { | 
|  | 223         // Call searchCanceled since it will reset everything we need before doi
      ng a new search. | 
|  | 224         this.searchCanceled(); | 
|  | 225 | 
|  | 226         const whitespaceTrimmedQuery = query.trimWhitespace(); | 
|  | 227         if (!whitespaceTrimmedQuery.length) | 
|  | 228             return; | 
|  | 229 | 
|  | 230         this._updatedMatchCountOnce = false; | 
|  | 231         this._matchesCountUpdateTimeout = null; | 
|  | 232 | 
|  | 233         InjectedScriptAccess.performSearch(whitespaceTrimmedQuery, function() {}
      ); | 
|  | 234     }, | 
|  | 235 | 
|  | 236     _updateMatchesCount: function() | 
|  | 237     { | 
|  | 238         WebInspector.updateSearchMatchesCount(this._searchResults.length, this); | 
|  | 239         this._matchesCountUpdateTimeout = null; | 
|  | 240         this._updatedMatchCountOnce = true; | 
|  | 241     }, | 
|  | 242 | 
|  | 243     _updateMatchesCountSoon: function() | 
|  | 244     { | 
|  | 245         if (!this._updatedMatchCountOnce) | 
|  | 246             return this._updateMatchesCount(); | 
|  | 247         if (this._matchesCountUpdateTimeout) | 
|  | 248             return; | 
|  | 249         // Update the matches count every half-second so it doesn't feel twitchy
      . | 
|  | 250         this._matchesCountUpdateTimeout = setTimeout(this._updateMatchesCount.bi
      nd(this), 500); | 
|  | 251     }, | 
|  | 252 | 
|  | 253     addNodesToSearchResult: function(nodeIds) | 
|  | 254     { | 
|  | 255         if (!nodeIds) | 
|  | 256             return; | 
|  | 257 | 
|  | 258         var nodeIdsArray = nodeIds.split(","); | 
|  | 259         for (var i = 0; i < nodeIdsArray.length; ++i) { | 
|  | 260             var nodeId = nodeIdsArray[i]; | 
|  | 261             var node = WebInspector.domAgent.nodeForId(nodeId); | 
|  | 262             if (!node) | 
|  | 263                 continue; | 
|  | 264 | 
|  | 265             if (!this._searchResults.length) { | 
|  | 266                 this._currentSearchResultIndex = 0; | 
|  | 267                 this.focusedDOMNode = node; | 
|  | 268             } | 
|  | 269 | 
|  | 270             this._searchResults.push(node); | 
|  | 271 | 
|  | 272             // Highlight the tree element to show it matched the search. | 
|  | 273             // FIXME: highlight the substrings in text nodes and attributes. | 
|  | 274             var treeElement = this.treeOutline.findTreeElement(node); | 
|  | 275             if (treeElement) | 
|  | 276                 treeElement.highlighted = true; | 
|  | 277         } | 
|  | 278 | 
|  | 279         this._updateMatchesCountSoon(); | 
|  | 280     }, | 
|  | 281 | 
|  | 282     jumpToNextSearchResult: function() | 
|  | 283     { | 
|  | 284         if (!this._searchResults || !this._searchResults.length) | 
|  | 285             return; | 
|  | 286         if (++this._currentSearchResultIndex >= this._searchResults.length) | 
|  | 287             this._currentSearchResultIndex = 0; | 
|  | 288         this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
      ]; | 
|  | 289     }, | 
|  | 290 | 
|  | 291     jumpToPreviousSearchResult: function() | 
|  | 292     { | 
|  | 293         if (!this._searchResults || !this._searchResults.length) | 
|  | 294             return; | 
|  | 295         if (--this._currentSearchResultIndex < 0) | 
|  | 296             this._currentSearchResultIndex = (this._searchResults.length - 1); | 
|  | 297         this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
      ]; | 
|  | 298     }, | 
|  | 299 | 
|  | 300     renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelec
      tor) | 
|  | 301     { | 
|  | 302         // TODO: Implement Shifting the oldSelector, and its contents to a newSe
      lector | 
|  | 303     }, | 
|  | 304 | 
|  | 305     addStyleChange: function(identifier, style, property) | 
|  | 306     { | 
|  | 307         if (!style.parentRule) | 
|  | 308             return; | 
|  | 309 | 
|  | 310         var selector = style.parentRule.selectorText; | 
|  | 311         if (!this._changedStyles[identifier]) | 
|  | 312             this._changedStyles[identifier] = {}; | 
|  | 313 | 
|  | 314         if (!this._changedStyles[identifier][selector]) | 
|  | 315             this._changedStyles[identifier][selector] = {}; | 
|  | 316 | 
|  | 317         if (!this._changedStyles[identifier][selector][property]) | 
|  | 318             WebInspector.styleChanges += 1; | 
|  | 319 | 
|  | 320         this._changedStyles[identifier][selector][property] = style.getPropertyV
      alue(property); | 
|  | 321     }, | 
|  | 322 | 
|  | 323     removeStyleChange: function(identifier, style, property) | 
|  | 324     { | 
|  | 325         if (!style.parentRule) | 
|  | 326             return; | 
|  | 327 | 
|  | 328         var selector = style.parentRule.selectorText; | 
|  | 329         if (!this._changedStyles[identifier] || !this._changedStyles[identifier]
      [selector]) | 
|  | 330             return; | 
|  | 331 | 
|  | 332         if (this._changedStyles[identifier][selector][property]) { | 
|  | 333             delete this._changedStyles[identifier][selector][property]; | 
|  | 334             WebInspector.styleChanges -= 1; | 
|  | 335         } | 
|  | 336     }, | 
|  | 337 | 
|  | 338     generateStylesheet: function() | 
|  | 339     { | 
|  | 340         if (!WebInspector.styleChanges) | 
|  | 341             return; | 
|  | 342 | 
|  | 343         // Merge Down to Just Selectors | 
|  | 344         var mergedSelectors = {}; | 
|  | 345         for (var identifier in this._changedStyles) { | 
|  | 346             for (var selector in this._changedStyles[identifier]) { | 
|  | 347                 if (!mergedSelectors[selector]) | 
|  | 348                     mergedSelectors[selector] = this._changedStyles[identifier][
      selector]; | 
|  | 349                 else { // merge on selector | 
|  | 350                     var merge = {}; | 
|  | 351                     for (var property in mergedSelectors[selector]) | 
|  | 352                         merge[property] = mergedSelectors[selector][property]; | 
|  | 353                     for (var property in this._changedStyles[identifier][selecto
      r]) { | 
|  | 354                         if (!merge[property]) | 
|  | 355                             merge[property] = this._changedStyles[identifier][se
      lector][property]; | 
|  | 356                         else { // merge on property within a selector, include c
      omment to notify user | 
|  | 357                             var value1 = merge[property]; | 
|  | 358                             var value2 = this._changedStyles[identifier][selecto
      r][property]; | 
|  | 359 | 
|  | 360                             if (value1 === value2) | 
|  | 361                                 merge[property] = [value1]; | 
|  | 362                             else if (value1 instanceof Array) | 
|  | 363                                 merge[property].push(value2); | 
|  | 364                             else | 
|  | 365                                 merge[property] = [value1, value2]; | 
|  | 366                         } | 
|  | 367                     } | 
|  | 368                     mergedSelectors[selector] = merge; | 
|  | 369                 } | 
|  | 370             } | 
|  | 371         } | 
|  | 372 | 
|  | 373         var builder = []; | 
|  | 374         builder.push("/**"); | 
|  | 375         builder.push(" * Inspector Generated Stylesheet"); // UIString? | 
|  | 376         builder.push(" */\n"); | 
|  | 377 | 
|  | 378         var indent = "  "; | 
|  | 379         function displayProperty(property, value, comment) { | 
|  | 380             if (comment) | 
|  | 381                 return indent + "/* " + property + ": " + value + "; */"; | 
|  | 382             else | 
|  | 383                 return indent + property + ": " + value + ";"; | 
|  | 384         } | 
|  | 385 | 
|  | 386         for (var selector in mergedSelectors) { | 
|  | 387             var psuedoStyle = mergedSelectors[selector]; | 
|  | 388             var properties = Object.properties(psuedoStyle); | 
|  | 389             if (properties.length) { | 
|  | 390                 builder.push(selector + " {"); | 
|  | 391                 for (var i = 0; i < properties.length; ++i) { | 
|  | 392                     var property = properties[i]; | 
|  | 393                     var value = psuedoStyle[property]; | 
|  | 394                     if (!(value instanceof Array)) | 
|  | 395                         builder.push(displayProperty(property, value)); | 
|  | 396                     else { | 
|  | 397                         if (value.length === 1) | 
|  | 398                             builder.push(displayProperty(property, value) + " /*
       merged from equivalent edits */"); // UIString? | 
|  | 399                         else { | 
|  | 400                             builder.push(indent + "/* There was a Conflict... Th
      ere were Multiple Edits for '" + property + "' */"); // UIString? | 
|  | 401                             for (var j = 0; j < value.length; ++j) | 
|  | 402                                 builder.push(displayProperty(property, value, tr
      ue)); | 
|  | 403                         } | 
|  | 404                     } | 
|  | 405                 } | 
|  | 406                 builder.push("}\n"); | 
|  | 407             } | 
|  | 408         } | 
|  | 409 | 
|  | 410         WebInspector.showConsole(); | 
|  | 411         WebInspector.console.addMessage(new WebInspector.ConsoleTextMessage(buil
      der.join("\n"))); | 
|  | 412     }, | 
|  | 413 | 
|  | 414     get rootDOMNode() | 
|  | 415     { | 
|  | 416         return this.treeOutline.rootDOMNode; | 
|  | 417     }, | 
|  | 418 | 
|  | 419     set rootDOMNode(x) | 
|  | 420     { | 
|  | 421         this.treeOutline.rootDOMNode = x; | 
|  | 422     }, | 
|  | 423 | 
|  | 424     get focusedDOMNode() | 
|  | 425     { | 
|  | 426         return this.treeOutline.focusedDOMNode; | 
|  | 427     }, | 
|  | 428 | 
|  | 429     set focusedDOMNode(x) | 
|  | 430     { | 
|  | 431         this.treeOutline.focusedDOMNode = x; | 
|  | 432     }, | 
|  | 433 | 
|  | 434     _nodeInserted: function(event) | 
|  | 435     { | 
|  | 436         this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
      edNode, inserted: true}); | 
|  | 437         if (this.visible) | 
|  | 438             this._updateModifiedNodesSoon(); | 
|  | 439     }, | 
|  | 440 | 
|  | 441     _nodeRemoved: function(event) | 
|  | 442     { | 
|  | 443         this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
      edNode, removed: true}); | 
|  | 444         if (this.visible) | 
|  | 445             this._updateModifiedNodesSoon(); | 
|  | 446     }, | 
|  | 447 | 
|  | 448     _updateModifiedNodesSoon: function() | 
|  | 449     { | 
|  | 450         if ("_updateModifiedNodesTimeout" in this) | 
|  | 451             return; | 
|  | 452         this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.
      bind(this), 0); | 
|  | 453     }, | 
|  | 454 | 
|  | 455     _updateModifiedNodes: function() | 
|  | 456     { | 
|  | 457         if ("_updateModifiedNodesTimeout" in this) { | 
|  | 458             clearTimeout(this._updateModifiedNodesTimeout); | 
|  | 459             delete this._updateModifiedNodesTimeout; | 
|  | 460         } | 
|  | 461 | 
|  | 462         var updatedParentTreeElements = []; | 
|  | 463         var updateBreadcrumbs = false; | 
|  | 464 | 
|  | 465         for (var i = 0; i < this.recentlyModifiedNodes.length; ++i) { | 
|  | 466             var replaced = this.recentlyModifiedNodes[i].replaced; | 
|  | 467             var parent = this.recentlyModifiedNodes[i].parent; | 
|  | 468             if (!parent) | 
|  | 469                 continue; | 
|  | 470 | 
|  | 471             var parentNodeItem = this.treeOutline.findTreeElement(parent); | 
|  | 472             if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) { | 
|  | 473                 parentNodeItem.updateChildren(replaced); | 
|  | 474                 parentNodeItem.alreadyUpdatedChildren = true; | 
|  | 475                 updatedParentTreeElements.push(parentNodeItem); | 
|  | 476             } | 
|  | 477 | 
|  | 478             if (!updateBreadcrumbs && (this.focusedDOMNode === parent || isAnces
      tor(this.focusedDOMNode, parent))) | 
|  | 479                 updateBreadcrumbs = true; | 
|  | 480         } | 
|  | 481 | 
|  | 482         for (var i = 0; i < updatedParentTreeElements.length; ++i) | 
|  | 483             delete updatedParentTreeElements[i].alreadyUpdatedChildren; | 
|  | 484 | 
|  | 485         this.recentlyModifiedNodes = []; | 
|  | 486 | 
|  | 487         if (updateBreadcrumbs) | 
|  | 488             this.updateBreadcrumb(true); | 
|  | 489     }, | 
|  | 490 | 
|  | 491     _stylesPaneEdited: function() | 
|  | 492     { | 
|  | 493         this.sidebarPanes.metrics.needsUpdate = true; | 
|  | 494         this.updateMetrics(); | 
|  | 495     }, | 
|  | 496 | 
|  | 497     _metricsPaneEdited: function() | 
|  | 498     { | 
|  | 499         this.sidebarPanes.styles.needsUpdate = true; | 
|  | 500         this.updateStyles(true); | 
|  | 501     }, | 
|  | 502 | 
|  | 503     _mouseMovedInCrumbs: function(event) | 
|  | 504     { | 
|  | 505         var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY)
      ; | 
|  | 506         var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb"); | 
|  | 507 | 
|  | 508         WebInspector.hoveredDOMNode = (crumbElement ? crumbElement.representedOb
      ject : null); | 
|  | 509 | 
|  | 510         if ("_mouseOutOfCrumbsTimeout" in this) { | 
|  | 511             clearTimeout(this._mouseOutOfCrumbsTimeout); | 
|  | 512             delete this._mouseOutOfCrumbsTimeout; | 
|  | 513         } | 
|  | 514     }, | 
|  | 515 | 
|  | 516     _mouseMovedOutOfCrumbs: function(event) | 
|  | 517     { | 
|  | 518         var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY)
      ; | 
|  | 519         if (nodeUnderMouse.isDescendant(this.crumbsElement)) | 
|  | 520             return; | 
|  | 521 | 
|  | 522         WebInspector.hoveredDOMNode = null; | 
|  | 523 | 
|  | 524         this._mouseOutOfCrumbsTimeout = setTimeout(this.updateBreadcrumbSizes.bi
      nd(this), 1000); | 
|  | 525     }, | 
|  | 526 | 
|  | 527     updateBreadcrumb: function(forceUpdate) | 
|  | 528     { | 
|  | 529         if (!this.visible) | 
|  | 530             return; | 
|  | 531 | 
|  | 532         var crumbs = this.crumbsElement; | 
|  | 533 | 
|  | 534         var handled = false; | 
|  | 535         var foundRoot = false; | 
|  | 536         var crumb = crumbs.firstChild; | 
|  | 537         while (crumb) { | 
|  | 538             if (crumb.representedObject === this.rootDOMNode) | 
|  | 539                 foundRoot = true; | 
|  | 540 | 
|  | 541             if (foundRoot) | 
|  | 542                 crumb.addStyleClass("dimmed"); | 
|  | 543             else | 
|  | 544                 crumb.removeStyleClass("dimmed"); | 
|  | 545 | 
|  | 546             if (crumb.representedObject === this.focusedDOMNode) { | 
|  | 547                 crumb.addStyleClass("selected"); | 
|  | 548                 handled = true; | 
|  | 549             } else { | 
|  | 550                 crumb.removeStyleClass("selected"); | 
|  | 551             } | 
|  | 552 | 
|  | 553             crumb = crumb.nextSibling; | 
|  | 554         } | 
|  | 555 | 
|  | 556         if (handled && !forceUpdate) { | 
|  | 557             // We don't need to rebuild the crumbs, but we need to adjust sizes | 
|  | 558             // to reflect the new focused or root node. | 
|  | 559             this.updateBreadcrumbSizes(); | 
|  | 560             return; | 
|  | 561         } | 
|  | 562 | 
|  | 563         crumbs.removeChildren(); | 
|  | 564 | 
|  | 565         var panel = this; | 
|  | 566 | 
|  | 567         function selectCrumbFunction(event) | 
|  | 568         { | 
|  | 569             var crumb = event.currentTarget; | 
|  | 570             if (crumb.hasStyleClass("collapsed")) { | 
|  | 571                 // Clicking a collapsed crumb will expose the hidden crumbs. | 
|  | 572                 if (crumb === panel.crumbsElement.firstChild) { | 
|  | 573                     // If the focused crumb is the first child, pick the farthes
      t crumb | 
|  | 574                     // that is still hidden. This allows the user to expose ever
      y crumb. | 
|  | 575                     var currentCrumb = crumb; | 
|  | 576                     while (currentCrumb) { | 
|  | 577                         var hidden = currentCrumb.hasStyleClass("hidden"); | 
|  | 578                         var collapsed = currentCrumb.hasStyleClass("collapsed"); | 
|  | 579                         if (!hidden && !collapsed) | 
|  | 580                             break; | 
|  | 581                         crumb = currentCrumb; | 
|  | 582                         currentCrumb = currentCrumb.nextSibling; | 
|  | 583                     } | 
|  | 584                 } | 
|  | 585 | 
|  | 586                 panel.updateBreadcrumbSizes(crumb); | 
|  | 587             } else { | 
|  | 588                 // Clicking a dimmed crumb or double clicking (event.detail >= 2
      ) | 
|  | 589                 // will change the root node in addition to the focused node. | 
|  | 590                 if (event.detail >= 2 || crumb.hasStyleClass("dimmed")) | 
|  | 591                     panel.rootDOMNode = crumb.representedObject.parentNode; | 
|  | 592                 panel.focusedDOMNode = crumb.representedObject; | 
|  | 593             } | 
|  | 594 | 
|  | 595             event.preventDefault(); | 
|  | 596         } | 
|  | 597 | 
|  | 598         foundRoot = false; | 
|  | 599         for (var current = this.focusedDOMNode; current; current = current.paren
      tNode) { | 
|  | 600             if (current.nodeType === Node.DOCUMENT_NODE) | 
|  | 601                 continue; | 
|  | 602 | 
|  | 603             if (current === this.rootDOMNode) | 
|  | 604                 foundRoot = true; | 
|  | 605 | 
|  | 606             var crumb = document.createElement("span"); | 
|  | 607             crumb.className = "crumb"; | 
|  | 608             crumb.representedObject = current; | 
|  | 609             crumb.addEventListener("mousedown", selectCrumbFunction, false); | 
|  | 610 | 
|  | 611             var crumbTitle; | 
|  | 612             switch (current.nodeType) { | 
|  | 613                 case Node.ELEMENT_NODE: | 
|  | 614                     crumbTitle = current.nodeName.toLowerCase(); | 
|  | 615 | 
|  | 616                     var nameElement = document.createElement("span"); | 
|  | 617                     nameElement.textContent = crumbTitle; | 
|  | 618                     crumb.appendChild(nameElement); | 
|  | 619 | 
|  | 620                     var idAttribute = current.getAttribute("id"); | 
|  | 621                     if (idAttribute) { | 
|  | 622                         var idElement = document.createElement("span"); | 
|  | 623                         crumb.appendChild(idElement); | 
|  | 624 | 
|  | 625                         var part = "#" + idAttribute; | 
|  | 626                         crumbTitle += part; | 
|  | 627                         idElement.appendChild(document.createTextNode(part)); | 
|  | 628 | 
|  | 629                         // Mark the name as extra, since the ID is more importan
      t. | 
|  | 630                         nameElement.className = "extra"; | 
|  | 631                     } | 
|  | 632 | 
|  | 633                     var classAttribute = current.getAttribute("class"); | 
|  | 634                     if (classAttribute) { | 
|  | 635                         var classes = classAttribute.split(/\s+/); | 
|  | 636                         var foundClasses = {}; | 
|  | 637 | 
|  | 638                         if (classes.length) { | 
|  | 639                             var classesElement = document.createElement("span"); | 
|  | 640                             classesElement.className = "extra"; | 
|  | 641                             crumb.appendChild(classesElement); | 
|  | 642 | 
|  | 643                             for (var i = 0; i < classes.length; ++i) { | 
|  | 644                                 var className = classes[i]; | 
|  | 645                                 if (className && !(className in foundClasses)) { | 
|  | 646                                     var part = "." + className; | 
|  | 647                                     crumbTitle += part; | 
|  | 648                                     classesElement.appendChild(document.createTe
      xtNode(part)); | 
|  | 649                                     foundClasses[className] = true; | 
|  | 650                                 } | 
|  | 651                             } | 
|  | 652                         } | 
|  | 653                     } | 
|  | 654 | 
|  | 655                     break; | 
|  | 656 | 
|  | 657                 case Node.TEXT_NODE: | 
|  | 658                     if (isNodeWhitespace.call(current)) | 
|  | 659                         crumbTitle = WebInspector.UIString("(whitespace)"); | 
|  | 660                     else | 
|  | 661                         crumbTitle = WebInspector.UIString("(text)"); | 
|  | 662                     break | 
|  | 663 | 
|  | 664                 case Node.COMMENT_NODE: | 
|  | 665                     crumbTitle = "<!-->"; | 
|  | 666                     break; | 
|  | 667 | 
|  | 668                 case Node.DOCUMENT_TYPE_NODE: | 
|  | 669                     crumbTitle = "<!DOCTYPE>"; | 
|  | 670                     break; | 
|  | 671 | 
|  | 672                 default: | 
|  | 673                     crumbTitle = current.nodeName.toLowerCase(); | 
|  | 674             } | 
|  | 675 | 
|  | 676             if (!crumb.childNodes.length) { | 
|  | 677                 var nameElement = document.createElement("span"); | 
|  | 678                 nameElement.textContent = crumbTitle; | 
|  | 679                 crumb.appendChild(nameElement); | 
|  | 680             } | 
|  | 681 | 
|  | 682             crumb.title = crumbTitle; | 
|  | 683 | 
|  | 684             if (foundRoot) | 
|  | 685                 crumb.addStyleClass("dimmed"); | 
|  | 686             if (current === this.focusedDOMNode) | 
|  | 687                 crumb.addStyleClass("selected"); | 
|  | 688             if (!crumbs.childNodes.length) | 
|  | 689                 crumb.addStyleClass("end"); | 
|  | 690 | 
|  | 691             crumbs.appendChild(crumb); | 
|  | 692         } | 
|  | 693 | 
|  | 694         if (crumbs.hasChildNodes()) | 
|  | 695             crumbs.lastChild.addStyleClass("start"); | 
|  | 696 | 
|  | 697         this.updateBreadcrumbSizes(); | 
|  | 698     }, | 
|  | 699 | 
|  | 700     updateBreadcrumbSizes: function(focusedCrumb) | 
|  | 701     { | 
|  | 702         if (!this.visible) | 
|  | 703             return; | 
|  | 704 | 
|  | 705         if (document.body.offsetWidth <= 0) { | 
|  | 706             // The stylesheet hasn't loaded yet or the window is closed, | 
|  | 707             // so we can't calculate what is need. Return early. | 
|  | 708             return; | 
|  | 709         } | 
|  | 710 | 
|  | 711         var crumbs = this.crumbsElement; | 
|  | 712         if (!crumbs.childNodes.length || crumbs.offsetWidth <= 0) | 
|  | 713             return; // No crumbs, do nothing. | 
|  | 714 | 
|  | 715         // A Zero index is the right most child crumb in the breadcrumb. | 
|  | 716         var selectedIndex = 0; | 
|  | 717         var focusedIndex = 0; | 
|  | 718         var selectedCrumb; | 
|  | 719 | 
|  | 720         var i = 0; | 
|  | 721         var crumb = crumbs.firstChild; | 
|  | 722         while (crumb) { | 
|  | 723             // Find the selected crumb and index. | 
|  | 724             if (!selectedCrumb && crumb.hasStyleClass("selected")) { | 
|  | 725                 selectedCrumb = crumb; | 
|  | 726                 selectedIndex = i; | 
|  | 727             } | 
|  | 728 | 
|  | 729             // Find the focused crumb index. | 
|  | 730             if (crumb === focusedCrumb) | 
|  | 731                 focusedIndex = i; | 
|  | 732 | 
|  | 733             // Remove any styles that affect size before | 
|  | 734             // deciding to shorten any crumbs. | 
|  | 735             if (crumb !== crumbs.lastChild) | 
|  | 736                 crumb.removeStyleClass("start"); | 
|  | 737             if (crumb !== crumbs.firstChild) | 
|  | 738                 crumb.removeStyleClass("end"); | 
|  | 739 | 
|  | 740             crumb.removeStyleClass("compact"); | 
|  | 741             crumb.removeStyleClass("collapsed"); | 
|  | 742             crumb.removeStyleClass("hidden"); | 
|  | 743 | 
|  | 744             crumb = crumb.nextSibling; | 
|  | 745             ++i; | 
|  | 746         } | 
|  | 747 | 
|  | 748         // Restore the start and end crumb classes in case they got removed in c
      oalesceCollapsedCrumbs(). | 
|  | 749         // The order of the crumbs in the document is opposite of the visual ord
      er. | 
|  | 750         crumbs.firstChild.addStyleClass("end"); | 
|  | 751         crumbs.lastChild.addStyleClass("start"); | 
|  | 752 | 
|  | 753         function crumbsAreSmallerThanContainer() | 
|  | 754         { | 
|  | 755             var rightPadding = 20; | 
|  | 756             var errorWarningElement = document.getElementById("error-warning-cou
      nt"); | 
|  | 757             if (!WebInspector.drawer.visible && errorWarningElement) | 
|  | 758                 rightPadding += errorWarningElement.offsetWidth; | 
|  | 759             return ((crumbs.totalOffsetLeft + crumbs.offsetWidth + rightPadding)
       < window.innerWidth); | 
|  | 760         } | 
|  | 761 | 
|  | 762         if (crumbsAreSmallerThanContainer()) | 
|  | 763             return; // No need to compact the crumbs, they all fit at full size. | 
|  | 764 | 
|  | 765         var BothSides = 0; | 
|  | 766         var AncestorSide = -1; | 
|  | 767         var ChildSide = 1; | 
|  | 768 | 
|  | 769         function makeCrumbsSmaller(shrinkingFunction, direction, significantCrum
      b) | 
|  | 770         { | 
|  | 771             if (!significantCrumb) | 
|  | 772                 significantCrumb = (focusedCrumb || selectedCrumb); | 
|  | 773 | 
|  | 774             if (significantCrumb === selectedCrumb) | 
|  | 775                 var significantIndex = selectedIndex; | 
|  | 776             else if (significantCrumb === focusedCrumb) | 
|  | 777                 var significantIndex = focusedIndex; | 
|  | 778             else { | 
|  | 779                 var significantIndex = 0; | 
|  | 780                 for (var i = 0; i < crumbs.childNodes.length; ++i) { | 
|  | 781                     if (crumbs.childNodes[i] === significantCrumb) { | 
|  | 782                         significantIndex = i; | 
|  | 783                         break; | 
|  | 784                     } | 
|  | 785                 } | 
|  | 786             } | 
|  | 787 | 
|  | 788             function shrinkCrumbAtIndex(index) | 
|  | 789             { | 
|  | 790                 var shrinkCrumb = crumbs.childNodes[index]; | 
|  | 791                 if (shrinkCrumb && shrinkCrumb !== significantCrumb) | 
|  | 792                     shrinkingFunction(shrinkCrumb); | 
|  | 793                 if (crumbsAreSmallerThanContainer()) | 
|  | 794                     return true; // No need to compact the crumbs more. | 
|  | 795                 return false; | 
|  | 796             } | 
|  | 797 | 
|  | 798             // Shrink crumbs one at a time by applying the shrinkingFunction unt
      il the crumbs | 
|  | 799             // fit in the container or we run out of crumbs to shrink. | 
|  | 800             if (direction) { | 
|  | 801                 // Crumbs are shrunk on only one side (based on direction) of th
      e signifcant crumb. | 
|  | 802                 var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1); | 
|  | 803                 while (index !== significantIndex) { | 
|  | 804                     if (shrinkCrumbAtIndex(index)) | 
|  | 805                         return true; | 
|  | 806                     index += (direction > 0 ? 1 : -1); | 
|  | 807                 } | 
|  | 808             } else { | 
|  | 809                 // Crumbs are shrunk in order of descending distance from the si
      gnifcant crumb, | 
|  | 810                 // with a tie going to child crumbs. | 
|  | 811                 var startIndex = 0; | 
|  | 812                 var endIndex = crumbs.childNodes.length - 1; | 
|  | 813                 while (startIndex != significantIndex || endIndex != significant
      Index) { | 
|  | 814                     var startDistance = significantIndex - startIndex; | 
|  | 815                     var endDistance = endIndex - significantIndex; | 
|  | 816                     if (startDistance >= endDistance) | 
|  | 817                         var index = startIndex++; | 
|  | 818                     else | 
|  | 819                         var index = endIndex--; | 
|  | 820                     if (shrinkCrumbAtIndex(index)) | 
|  | 821                         return true; | 
|  | 822                 } | 
|  | 823             } | 
|  | 824 | 
|  | 825             // We are not small enough yet, return false so the caller knows. | 
|  | 826             return false; | 
|  | 827         } | 
|  | 828 | 
|  | 829         function coalesceCollapsedCrumbs() | 
|  | 830         { | 
|  | 831             var crumb = crumbs.firstChild; | 
|  | 832             var collapsedRun = false; | 
|  | 833             var newStartNeeded = false; | 
|  | 834             var newEndNeeded = false; | 
|  | 835             while (crumb) { | 
|  | 836                 var hidden = crumb.hasStyleClass("hidden"); | 
|  | 837                 if (!hidden) { | 
|  | 838                     var collapsed = crumb.hasStyleClass("collapsed"); | 
|  | 839                     if (collapsedRun && collapsed) { | 
|  | 840                         crumb.addStyleClass("hidden"); | 
|  | 841                         crumb.removeStyleClass("compact"); | 
|  | 842                         crumb.removeStyleClass("collapsed"); | 
|  | 843 | 
|  | 844                         if (crumb.hasStyleClass("start")) { | 
|  | 845                             crumb.removeStyleClass("start"); | 
|  | 846                             newStartNeeded = true; | 
|  | 847                         } | 
|  | 848 | 
|  | 849                         if (crumb.hasStyleClass("end")) { | 
|  | 850                             crumb.removeStyleClass("end"); | 
|  | 851                             newEndNeeded = true; | 
|  | 852                         } | 
|  | 853 | 
|  | 854                         continue; | 
|  | 855                     } | 
|  | 856 | 
|  | 857                     collapsedRun = collapsed; | 
|  | 858 | 
|  | 859                     if (newEndNeeded) { | 
|  | 860                         newEndNeeded = false; | 
|  | 861                         crumb.addStyleClass("end"); | 
|  | 862                     } | 
|  | 863                 } else | 
|  | 864                     collapsedRun = true; | 
|  | 865                 crumb = crumb.nextSibling; | 
|  | 866             } | 
|  | 867 | 
|  | 868             if (newStartNeeded) { | 
|  | 869                 crumb = crumbs.lastChild; | 
|  | 870                 while (crumb) { | 
|  | 871                     if (!crumb.hasStyleClass("hidden")) { | 
|  | 872                         crumb.addStyleClass("start"); | 
|  | 873                         break; | 
|  | 874                     } | 
|  | 875                     crumb = crumb.previousSibling; | 
|  | 876                 } | 
|  | 877             } | 
|  | 878         } | 
|  | 879 | 
|  | 880         function compact(crumb) | 
|  | 881         { | 
|  | 882             if (crumb.hasStyleClass("hidden")) | 
|  | 883                 return; | 
|  | 884             crumb.addStyleClass("compact"); | 
|  | 885         } | 
|  | 886 | 
|  | 887         function collapse(crumb, dontCoalesce) | 
|  | 888         { | 
|  | 889             if (crumb.hasStyleClass("hidden")) | 
|  | 890                 return; | 
|  | 891             crumb.addStyleClass("collapsed"); | 
|  | 892             crumb.removeStyleClass("compact"); | 
|  | 893             if (!dontCoalesce) | 
|  | 894                 coalesceCollapsedCrumbs(); | 
|  | 895         } | 
|  | 896 | 
|  | 897         function compactDimmed(crumb) | 
|  | 898         { | 
|  | 899             if (crumb.hasStyleClass("dimmed")) | 
|  | 900                 compact(crumb); | 
|  | 901         } | 
|  | 902 | 
|  | 903         function collapseDimmed(crumb) | 
|  | 904         { | 
|  | 905             if (crumb.hasStyleClass("dimmed")) | 
|  | 906                 collapse(crumb); | 
|  | 907         } | 
|  | 908 | 
|  | 909         if (!focusedCrumb) { | 
|  | 910             // When not focused on a crumb we can be biased and collapse less im
      portant | 
|  | 911             // crumbs that the user might not care much about. | 
|  | 912 | 
|  | 913             // Compact child crumbs. | 
|  | 914             if (makeCrumbsSmaller(compact, ChildSide)) | 
|  | 915                 return; | 
|  | 916 | 
|  | 917             // Collapse child crumbs. | 
|  | 918             if (makeCrumbsSmaller(collapse, ChildSide)) | 
|  | 919                 return; | 
|  | 920 | 
|  | 921             // Compact dimmed ancestor crumbs. | 
|  | 922             if (makeCrumbsSmaller(compactDimmed, AncestorSide)) | 
|  | 923                 return; | 
|  | 924 | 
|  | 925             // Collapse dimmed ancestor crumbs. | 
|  | 926             if (makeCrumbsSmaller(collapseDimmed, AncestorSide)) | 
|  | 927                 return; | 
|  | 928         } | 
|  | 929 | 
|  | 930         // Compact ancestor crumbs, or from both sides if focused. | 
|  | 931         if (makeCrumbsSmaller(compact, (focusedCrumb ? BothSides : AncestorSide)
      )) | 
|  | 932             return; | 
|  | 933 | 
|  | 934         // Collapse ancestor crumbs, or from both sides if focused. | 
|  | 935         if (makeCrumbsSmaller(collapse, (focusedCrumb ? BothSides : AncestorSide
      ))) | 
|  | 936             return; | 
|  | 937 | 
|  | 938         if (!selectedCrumb) | 
|  | 939             return; | 
|  | 940 | 
|  | 941         // Compact the selected crumb. | 
|  | 942         compact(selectedCrumb); | 
|  | 943         if (crumbsAreSmallerThanContainer()) | 
|  | 944             return; | 
|  | 945 | 
|  | 946         // Collapse the selected crumb as a last resort. Pass true to prevent co
      alescing. | 
|  | 947         collapse(selectedCrumb, true); | 
|  | 948     }, | 
|  | 949 | 
|  | 950     updateStyles: function(forceUpdate) | 
|  | 951     { | 
|  | 952         var stylesSidebarPane = this.sidebarPanes.styles; | 
|  | 953         if (!stylesSidebarPane.expanded || !stylesSidebarPane.needsUpdate) | 
|  | 954             return; | 
|  | 955 | 
|  | 956         stylesSidebarPane.update(this.focusedDOMNode, null, forceUpdate); | 
|  | 957         stylesSidebarPane.needsUpdate = false; | 
|  | 958     }, | 
|  | 959 | 
|  | 960     updateMetrics: function() | 
|  | 961     { | 
|  | 962         var metricsSidebarPane = this.sidebarPanes.metrics; | 
|  | 963         if (!metricsSidebarPane.expanded || !metricsSidebarPane.needsUpdate) | 
|  | 964             return; | 
|  | 965 | 
|  | 966         metricsSidebarPane.update(this.focusedDOMNode); | 
|  | 967         metricsSidebarPane.needsUpdate = false; | 
|  | 968     }, | 
|  | 969 | 
|  | 970     updateProperties: function() | 
|  | 971     { | 
|  | 972         var propertiesSidebarPane = this.sidebarPanes.properties; | 
|  | 973         if (!propertiesSidebarPane.expanded || !propertiesSidebarPane.needsUpdat
      e) | 
|  | 974             return; | 
|  | 975 | 
|  | 976         propertiesSidebarPane.update(this.focusedDOMNode); | 
|  | 977         propertiesSidebarPane.needsUpdate = false; | 
|  | 978     }, | 
|  | 979 | 
|  | 980     handleKeyEvent: function(event) | 
|  | 981     { | 
|  | 982         this.treeOutline.handleKeyEvent(event); | 
|  | 983     }, | 
|  | 984 | 
|  | 985     handleCopyEvent: function(event) | 
|  | 986     { | 
|  | 987         // Don't prevent the normal copy if the user has a selection. | 
|  | 988         if (!window.getSelection().isCollapsed) | 
|  | 989             return; | 
|  | 990 | 
|  | 991         switch (this.focusedDOMNode.nodeType) { | 
|  | 992             case Node.ELEMENT_NODE: | 
|  | 993                 // TODO: Introduce InspectorController.copyEvent that pushes app
      ropriate markup into the clipboard. | 
|  | 994                 var data = null; | 
|  | 995                 break; | 
|  | 996 | 
|  | 997             case Node.COMMENT_NODE: | 
|  | 998                 var data = "<!--" + this.focusedDOMNode.nodeValue + "-->"; | 
|  | 999                 break; | 
|  | 1000 | 
|  | 1001             default: | 
|  | 1002             case Node.TEXT_NODE: | 
|  | 1003                 var data = this.focusedDOMNode.nodeValue; | 
|  | 1004         } | 
|  | 1005 | 
|  | 1006         event.clipboardData.clearData(); | 
|  | 1007         event.preventDefault(); | 
|  | 1008 | 
|  | 1009         if (data) | 
|  | 1010             event.clipboardData.setData("text/plain", data); | 
|  | 1011     }, | 
|  | 1012 | 
|  | 1013     rightSidebarResizerDragStart: function(event) | 
|  | 1014     { | 
|  | 1015         WebInspector.elementDragStart(this.sidebarElement, this.rightSidebarResi
      zerDrag.bind(this), this.rightSidebarResizerDragEnd.bind(this), event, "col-resi
      ze"); | 
|  | 1016     }, | 
|  | 1017 | 
|  | 1018     rightSidebarResizerDragEnd: function(event) | 
|  | 1019     { | 
|  | 1020         WebInspector.elementDragEnd(event); | 
|  | 1021     }, | 
|  | 1022 | 
|  | 1023     rightSidebarResizerDrag: function(event) | 
|  | 1024     { | 
|  | 1025         var x = event.pageX; | 
|  | 1026         var newWidth = Number.constrain(window.innerWidth - x, Preferences.minEl
      ementsSidebarWidth, window.innerWidth * 0.66); | 
|  | 1027 | 
|  | 1028         this.sidebarElement.style.width = newWidth + "px"; | 
|  | 1029         this.contentElement.style.right = newWidth + "px"; | 
|  | 1030         this.sidebarResizeElement.style.right = (newWidth - 3) + "px"; | 
|  | 1031 | 
|  | 1032         this.treeOutline.updateSelection(); | 
|  | 1033 | 
|  | 1034         event.preventDefault(); | 
|  | 1035     }, | 
|  | 1036 | 
|  | 1037     _nodeSearchButtonClicked: function(event) | 
|  | 1038     { | 
|  | 1039         InspectorController.toggleNodeSearch(); | 
|  | 1040 | 
|  | 1041         this.nodeSearchButton.toggled = InspectorController.searchingForNode(); | 
|  | 1042     } | 
|  | 1043 } | 
|  | 1044 | 
|  | 1045 WebInspector.ElementsPanel.prototype.__proto__ = WebInspector.Panel.prototype; | 
| OLD | NEW | 
|---|