| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> | 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> |
| 4 * Copyright (C) 2009 Joseph Pecoraro |
| 4 * | 5 * |
| 5 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 7 * are met: | 8 * are met: |
| 8 * | 9 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 11 * notice, this list of conditions and the following disclaimer. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 12 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 13 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 14 * documentation and/or other materials provided with the distribution. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 this.panel.sidebarPanes[pane].needsUpdate = true; | 54 this.panel.sidebarPanes[pane].needsUpdate = true; |
| 54 | 55 |
| 55 this.panel.updateStyles(true); | 56 this.panel.updateStyles(true); |
| 56 this.panel.updateMetrics(); | 57 this.panel.updateMetrics(); |
| 57 this.panel.updateProperties(); | 58 this.panel.updateProperties(); |
| 58 | 59 |
| 59 if (InspectorController.searchingForNode()) { | 60 if (InspectorController.searchingForNode()) { |
| 60 InspectorController.toggleNodeSearch(); | 61 InspectorController.toggleNodeSearch(); |
| 61 this.panel.nodeSearchButton.removeStyleClass("toggled-on"); | 62 this.panel.nodeSearchButton.removeStyleClass("toggled-on"); |
| 62 } | 63 } |
| 64 if (this._focusedDOMNode) |
| 65 InspectorController.addInspectedNode(this._focusedDOMNode.id, functi
on() {}); |
| 63 }; | 66 }; |
| 64 | 67 |
| 65 this.contentElement.appendChild(this.treeOutline.element); | 68 this.contentElement.appendChild(this.treeOutline.element); |
| 66 | 69 |
| 67 this.crumbsElement = document.createElement("div"); | 70 this.crumbsElement = document.createElement("div"); |
| 68 this.crumbsElement.className = "crumbs"; | 71 this.crumbsElement.className = "crumbs"; |
| 69 this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bi
nd(this), false); | 72 this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bi
nd(this), false); |
| 70 this.crumbsElement.addEventListener("mouseout", this._mouseMovedOutOfCrumbs.
bind(this), false); | 73 this.crumbsElement.addEventListener("mouseout", this._mouseMovedOutOfCrumbs.
bind(this), false); |
| 71 | 74 |
| 72 this.sidebarPanes = {}; | 75 this.sidebarPanes = {}; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 88 this.sidebarElement.id = "elements-sidebar"; | 91 this.sidebarElement.id = "elements-sidebar"; |
| 89 | 92 |
| 90 this.sidebarElement.appendChild(this.sidebarPanes.styles.element); | 93 this.sidebarElement.appendChild(this.sidebarPanes.styles.element); |
| 91 this.sidebarElement.appendChild(this.sidebarPanes.metrics.element); | 94 this.sidebarElement.appendChild(this.sidebarPanes.metrics.element); |
| 92 this.sidebarElement.appendChild(this.sidebarPanes.properties.element); | 95 this.sidebarElement.appendChild(this.sidebarPanes.properties.element); |
| 93 | 96 |
| 94 this.sidebarResizeElement = document.createElement("div"); | 97 this.sidebarResizeElement = document.createElement("div"); |
| 95 this.sidebarResizeElement.className = "sidebar-resizer-vertical"; | 98 this.sidebarResizeElement.className = "sidebar-resizer-vertical"; |
| 96 this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarRes
izerDragStart.bind(this), false); | 99 this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarRes
izerDragStart.bind(this), false); |
| 97 | 100 |
| 98 this.nodeSearchButton = document.createElement("button"); | 101 this.nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIStri
ng("Select an element in the page to inspect it."), "node-search-status-bar-item
"); |
| 99 this.nodeSearchButton.title = WebInspector.UIString("Select an element in th
e page to inspect it."); | |
| 100 this.nodeSearchButton.id = "node-search-status-bar-item"; | |
| 101 this.nodeSearchButton.className = "status-bar-item"; | |
| 102 this.nodeSearchButton.addEventListener("click", this._nodeSearchButtonClicke
d.bind(this), false); | 102 this.nodeSearchButton.addEventListener("click", this._nodeSearchButtonClicke
d.bind(this), false); |
| 103 | 103 |
| 104 this.searchingForNode = false; | 104 this.searchingForNode = false; |
| 105 | 105 |
| 106 this.element.appendChild(this.contentElement); | 106 this.element.appendChild(this.contentElement); |
| 107 this.element.appendChild(this.sidebarElement); | 107 this.element.appendChild(this.sidebarElement); |
| 108 this.element.appendChild(this.sidebarResizeElement); | 108 this.element.appendChild(this.sidebarResizeElement); |
| 109 | 109 |
| 110 this._mutationMonitoredWindows = []; | 110 this._changedStyles = {}; |
| 111 this._nodeInsertedEventListener = InspectorController.wrapCallback(this._nod
eInserted.bind(this)); | |
| 112 this._nodeRemovedEventListener = InspectorController.wrapCallback(this._node
Removed.bind(this)); | |
| 113 this._contentLoadedEventListener = InspectorController.wrapCallback(this._co
ntentLoaded.bind(this)); | |
| 114 | 111 |
| 115 this.reset(); | 112 this.reset(); |
| 116 } | 113 } |
| 117 | 114 |
| 118 WebInspector.ElementsPanel.prototype = { | 115 WebInspector.ElementsPanel.prototype = { |
| 119 toolbarItemClass: "elements", | 116 toolbarItemClass: "elements", |
| 120 | 117 |
| 121 get toolbarItemLabel() | 118 get toolbarItemLabel() |
| 122 { | 119 { |
| 123 return WebInspector.UIString("Elements"); | 120 return WebInspector.UIString("Elements"); |
| 124 }, | 121 }, |
| 125 | 122 |
| 126 get statusBarItems() | 123 get statusBarItems() |
| 127 { | 124 { |
| 128 return [this.nodeSearchButton, this.crumbsElement]; | 125 return [this.nodeSearchButton.element, this.crumbsElement]; |
| 129 }, | 126 }, |
| 130 | 127 |
| 131 updateStatusBarItems: function() | 128 updateStatusBarItems: function() |
| 132 { | 129 { |
| 133 this.updateBreadcrumbSizes(); | 130 this.updateBreadcrumbSizes(); |
| 134 }, | 131 }, |
| 135 | 132 |
| 136 show: function() | 133 show: function() |
| 137 { | 134 { |
| 138 WebInspector.Panel.prototype.show.call(this); | 135 WebInspector.Panel.prototype.show.call(this); |
| 139 this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth
- 3) + "px"; | 136 this.sidebarResizeElement.style.right = (this.sidebarElement.offsetWidth
- 3) + "px"; |
| 140 this.updateBreadcrumb(); | 137 this.updateBreadcrumb(); |
| 141 this.treeOutline.updateSelection(); | 138 this.treeOutline.updateSelection(); |
| 142 if (this.recentlyModifiedNodes.length) | 139 if (this.recentlyModifiedNodes.length) |
| 143 this._updateModifiedNodes(); | 140 this._updateModifiedNodes(); |
| 144 }, | 141 }, |
| 145 | 142 |
| 146 hide: function() | 143 hide: function() |
| 147 { | 144 { |
| 148 WebInspector.Panel.prototype.hide.call(this); | 145 WebInspector.Panel.prototype.hide.call(this); |
| 149 | 146 |
| 150 WebInspector.hoveredDOMNode = null; | 147 WebInspector.hoveredDOMNode = null; |
| 151 | 148 |
| 152 if (InspectorController.searchingForNode()) { | 149 if (InspectorController.searchingForNode()) { |
| 153 InspectorController.toggleNodeSearch(); | 150 InspectorController.toggleNodeSearch(); |
| 154 this.nodeSearchButton.removeStyleClass("toggled-on"); | 151 this.nodeSearchButton.toggled = false; |
| 155 } | 152 } |
| 156 }, | 153 }, |
| 157 | 154 |
| 158 resize: function() | 155 resize: function() |
| 159 { | 156 { |
| 160 this.treeOutline.updateSelection(); | 157 this.treeOutline.updateSelection(); |
| 161 this.updateBreadcrumbSizes(); | 158 this.updateBreadcrumbSizes(); |
| 162 }, | 159 }, |
| 163 | 160 |
| 164 reset: function() | 161 reset: function() |
| 165 { | 162 { |
| 166 this.rootDOMNode = null; | 163 this.rootDOMNode = null; |
| 167 this.focusedDOMNode = null; | 164 this.focusedDOMNode = null; |
| 168 | 165 |
| 169 WebInspector.hoveredDOMNode = null; | 166 WebInspector.hoveredDOMNode = null; |
| 170 | 167 |
| 171 if (InspectorController.searchingForNode()) { | 168 if (InspectorController.searchingForNode()) { |
| 172 InspectorController.toggleNodeSearch(); | 169 InspectorController.toggleNodeSearch(); |
| 173 this.nodeSearchButton.removeStyleClass("toggled-on"); | 170 this.nodeSearchButton.toggled = false; |
| 174 } | 171 } |
| 175 | 172 |
| 176 this.recentlyModifiedNodes = []; | 173 this.recentlyModifiedNodes = []; |
| 177 this.unregisterAllMutationEventListeners(); | |
| 178 | 174 |
| 179 delete this.currentQuery; | 175 delete this.currentQuery; |
| 180 this.searchCanceled(); | 176 this.searchCanceled(); |
| 181 | 177 |
| 182 var inspectedWindow = InspectorController.inspectedWindow(); | 178 var domWindow = WebInspector.domAgent.domWindow; |
| 183 if (!inspectedWindow || !inspectedWindow.document) | 179 if (!domWindow || !domWindow.document || !domWindow.document.firstChild) |
| 184 return; | 180 return; |
| 185 | 181 |
| 186 if (!inspectedWindow.document.firstChild) { | |
| 187 function contentLoaded() | |
| 188 { | |
| 189 inspectedWindow.document.removeEventListener("DOMContentLoaded",
contentLoadedCallback, false); | |
| 190 | |
| 191 this.reset(); | |
| 192 } | |
| 193 | |
| 194 var contentLoadedCallback = InspectorController.wrapCallback(content
Loaded.bind(this)); | |
| 195 inspectedWindow.document.addEventListener("DOMContentLoaded", conten
tLoadedCallback, false); | |
| 196 return; | |
| 197 } | |
| 198 | |
| 199 // If the window isn't visible, return early so the DOM tree isn't built | 182 // If the window isn't visible, return early so the DOM tree isn't built |
| 200 // and mutation event listeners are not added. | 183 // and mutation event listeners are not added. |
| 201 if (!InspectorController.isWindowVisible()) | 184 if (!InspectorController.isWindowVisible()) |
| 202 return; | 185 return; |
| 203 | 186 |
| 204 this.registerMutationEventListeners(inspectedWindow); | 187 var inspectedRootDocument = domWindow.document; |
| 188 inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInse
rted.bind(this)); |
| 189 inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemov
ed.bind(this)); |
| 205 | 190 |
| 206 var inspectedRootDocument = inspectedWindow.document; | |
| 207 this.rootDOMNode = inspectedRootDocument; | 191 this.rootDOMNode = inspectedRootDocument; |
| 208 | 192 |
| 209 var canidateFocusNode = inspectedRootDocument.body || inspectedRootDocum
ent.documentElement; | 193 var canidateFocusNode = inspectedRootDocument.body || inspectedRootDocum
ent.documentElement; |
| 210 if (canidateFocusNode) { | 194 if (canidateFocusNode) { |
| 211 this.treeOutline.suppressSelectHighlight = true; | 195 this.treeOutline.suppressSelectHighlight = true; |
| 212 this.focusedDOMNode = canidateFocusNode; | 196 this.focusedDOMNode = canidateFocusNode; |
| 213 this.treeOutline.suppressSelectHighlight = false; | 197 this.treeOutline.suppressSelectHighlight = false; |
| 214 | 198 |
| 215 if (this.treeOutline.selectedTreeElement) | 199 if (this.treeOutline.selectedTreeElement) |
| 216 this.treeOutline.selectedTreeElement.expand(); | 200 this.treeOutline.selectedTreeElement.expand(); |
| 217 } | 201 } |
| 218 }, | 202 }, |
| 219 | 203 |
| 220 includedInSearchResultsPropertyName: "__includedInInspectorSearchResults", | |
| 221 | |
| 222 searchCanceled: function() | 204 searchCanceled: function() |
| 223 { | 205 { |
| 224 if (this._searchResults) { | 206 if (this._searchResults) { |
| 225 const searchResultsProperty = this.includedInSearchResultsPropertyNa
me; | |
| 226 for (var i = 0; i < this._searchResults.length; ++i) { | 207 for (var i = 0; i < this._searchResults.length; ++i) { |
| 227 var node = this._searchResults[i]; | 208 var treeElement = this.treeOutline.findTreeElement(this._searchR
esults[i]); |
| 228 | |
| 229 // Remove the searchResultsProperty since there might be an unfi
nished search. | |
| 230 delete node[searchResultsProperty]; | |
| 231 | |
| 232 var treeElement = this.treeOutline.findTreeElement(node); | |
| 233 if (treeElement) | 209 if (treeElement) |
| 234 treeElement.highlighted = false; | 210 treeElement.highlighted = false; |
| 235 } | 211 } |
| 236 } | 212 } |
| 237 | 213 |
| 238 WebInspector.updateSearchMatchesCount(0, this); | 214 WebInspector.updateSearchMatchesCount(0, this); |
| 239 | 215 |
| 240 if (this._currentSearchChunkIntervalIdentifier) { | |
| 241 clearInterval(this._currentSearchChunkIntervalIdentifier); | |
| 242 delete this._currentSearchChunkIntervalIdentifier; | |
| 243 } | |
| 244 | |
| 245 this._currentSearchResultIndex = 0; | 216 this._currentSearchResultIndex = 0; |
| 246 this._searchResults = []; | 217 this._searchResults = []; |
| 218 InspectorController.searchCanceled(function() {}); |
| 247 }, | 219 }, |
| 248 | 220 |
| 249 performSearch: function(query) | 221 performSearch: function(query) |
| 250 { | 222 { |
| 251 // Call searchCanceled since it will reset everything we need before doi
ng a new search. | 223 // Call searchCanceled since it will reset everything we need before doi
ng a new search. |
| 252 this.searchCanceled(); | 224 this.searchCanceled(); |
| 253 | 225 |
| 254 const whitespaceTrimmedQuery = query.trimWhitespace(); | 226 const whitespaceTrimmedQuery = query.trimWhitespace(); |
| 255 if (!whitespaceTrimmedQuery.length) | 227 if (!whitespaceTrimmedQuery.length) |
| 256 return; | 228 return; |
| 257 | 229 |
| 258 var tagNameQuery = whitespaceTrimmedQuery; | 230 this._updatedMatchCountOnce = false; |
| 259 var attributeNameQuery = whitespaceTrimmedQuery; | 231 this._matchesCountUpdateTimeout = null; |
| 260 var startTagFound = (tagNameQuery.indexOf("<") === 0); | |
| 261 var endTagFound = (tagNameQuery.lastIndexOf(">") === (tagNameQuery.lengt
h - 1)); | |
| 262 | 232 |
| 263 if (startTagFound || endTagFound) { | 233 InspectorController.performSearch(whitespaceTrimmedQuery, function() {})
; |
| 264 var tagNameQueryLength = tagNameQuery.length; | 234 }, |
| 265 tagNameQuery = tagNameQuery.substring((startTagFound ? 1 : 0), (endT
agFound ? (tagNameQueryLength - 1) : tagNameQueryLength)); | 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; |
| 266 } | 277 } |
| 267 | 278 |
| 268 // Check the tagNameQuery is it is a possibly valid tag name. | 279 this._updateMatchesCountSoon(); |
| 269 if (!/^[a-zA-Z0-9\-_:]+$/.test(tagNameQuery)) | |
| 270 tagNameQuery = null; | |
| 271 | |
| 272 // Check the attributeNameQuery is it is a possibly valid tag name. | |
| 273 if (!/^[a-zA-Z0-9\-_:]+$/.test(attributeNameQuery)) | |
| 274 attributeNameQuery = null; | |
| 275 | |
| 276 const escapedQuery = query.escapeCharacters("'"); | |
| 277 const escapedTagNameQuery = (tagNameQuery ? tagNameQuery.escapeCharacter
s("'") : null); | |
| 278 const escapedWhitespaceTrimmedQuery = whitespaceTrimmedQuery.escapeChara
cters("'"); | |
| 279 const searchResultsProperty = this.includedInSearchResultsPropertyName; | |
| 280 | |
| 281 var updatedMatchCountOnce = false; | |
| 282 var matchesCountUpdateTimeout = null; | |
| 283 | |
| 284 function updateMatchesCount() | |
| 285 { | |
| 286 WebInspector.updateSearchMatchesCount(this._searchResults.length, th
is); | |
| 287 matchesCountUpdateTimeout = null; | |
| 288 updatedMatchCountOnce = true; | |
| 289 } | |
| 290 | |
| 291 function updateMatchesCountSoon() | |
| 292 { | |
| 293 if (!updatedMatchCountOnce) | |
| 294 return updateMatchesCount.call(this); | |
| 295 if (matchesCountUpdateTimeout) | |
| 296 return; | |
| 297 // Update the matches count every half-second so it doesn't feel twi
tchy. | |
| 298 matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this)
, 500); | |
| 299 } | |
| 300 | |
| 301 function addNodesToResults(nodes, length, getItem) | |
| 302 { | |
| 303 if (!length) | |
| 304 return; | |
| 305 | |
| 306 for (var i = 0; i < length; ++i) { | |
| 307 var node = getItem.call(nodes, i); | |
| 308 // Skip this node if it already has the property. | |
| 309 if (searchResultsProperty in node) | |
| 310 continue; | |
| 311 | |
| 312 if (!this._searchResults.length) { | |
| 313 this._currentSearchResultIndex = 0; | |
| 314 this.focusedDOMNode = node; | |
| 315 } | |
| 316 | |
| 317 node[searchResultsProperty] = true; | |
| 318 this._searchResults.push(node); | |
| 319 | |
| 320 // Highlight the tree element to show it matched the search. | |
| 321 // FIXME: highlight the substrings in text nodes and attributes. | |
| 322 var treeElement = this.treeOutline.findTreeElement(node); | |
| 323 if (treeElement) | |
| 324 treeElement.highlighted = true; | |
| 325 } | |
| 326 | |
| 327 updateMatchesCountSoon.call(this); | |
| 328 } | |
| 329 | |
| 330 function matchExactItems(doc) | |
| 331 { | |
| 332 matchExactId.call(this, doc); | |
| 333 matchExactClassNames.call(this, doc); | |
| 334 matchExactTagNames.call(this, doc); | |
| 335 matchExactAttributeNames.call(this, doc); | |
| 336 } | |
| 337 | |
| 338 function matchExactId(doc) | |
| 339 { | |
| 340 const result = doc.__proto__.getElementById.call(doc, whitespaceTrim
medQuery); | |
| 341 addNodesToResults.call(this, result, (result ? 1 : 0), function() {
return this }); | |
| 342 } | |
| 343 | |
| 344 function matchExactClassNames(doc) | |
| 345 { | |
| 346 const result = doc.__proto__.getElementsByClassName.call(doc, whites
paceTrimmedQuery); | |
| 347 addNodesToResults.call(this, result, result.length, result.item); | |
| 348 } | |
| 349 | |
| 350 function matchExactTagNames(doc) | |
| 351 { | |
| 352 if (!tagNameQuery) | |
| 353 return; | |
| 354 const result = doc.__proto__.getElementsByTagName.call(doc, tagNameQ
uery); | |
| 355 addNodesToResults.call(this, result, result.length, result.item); | |
| 356 } | |
| 357 | |
| 358 function matchExactAttributeNames(doc) | |
| 359 { | |
| 360 if (!attributeNameQuery) | |
| 361 return; | |
| 362 const result = doc.__proto__.querySelectorAll.call(doc, "[" + attrib
uteNameQuery + "]"); | |
| 363 addNodesToResults.call(this, result, result.length, result.item); | |
| 364 } | |
| 365 | |
| 366 function matchPartialTagNames(doc) | |
| 367 { | |
| 368 if (!tagNameQuery) | |
| 369 return; | |
| 370 const result = doc.__proto__.evaluate.call(doc, "//*[contains(name()
, '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT
_TYPE); | |
| 371 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 372 } | |
| 373 | |
| 374 function matchStartOfTagNames(doc) | |
| 375 { | |
| 376 if (!tagNameQuery) | |
| 377 return; | |
| 378 const result = doc.__proto__.evaluate.call(doc, "//*[starts-with(nam
e(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPS
HOT_TYPE); | |
| 379 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 380 } | |
| 381 | |
| 382 function matchPartialTagNamesAndAttributeValues(doc) | |
| 383 { | |
| 384 if (!tagNameQuery) { | |
| 385 matchPartialAttributeValues.call(this, doc); | |
| 386 return; | |
| 387 } | |
| 388 | |
| 389 const result = doc.__proto__.evaluate.call(doc, "//*[contains(name()
, '" + escapedTagNameQuery + "') or contains(@*, '" + escapedQuery + "')]", doc,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); | |
| 390 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 391 } | |
| 392 | |
| 393 function matchPartialAttributeValues(doc) | |
| 394 { | |
| 395 const result = doc.__proto__.evaluate.call(doc, "//*[contains(@*, '"
+ escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); | |
| 396 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 397 } | |
| 398 | |
| 399 function matchStyleSelector(doc) | |
| 400 { | |
| 401 const result = doc.__proto__.querySelectorAll.call(doc, whitespaceTr
immedQuery); | |
| 402 addNodesToResults.call(this, result, result.length, result.item); | |
| 403 } | |
| 404 | |
| 405 function matchPlainText(doc) | |
| 406 { | |
| 407 const result = doc.__proto__.evaluate.call(doc, "//text()[contains(.
, '" + escapedQuery + "')] | //comment()[contains(., '" + escapedQuery + "')]",
doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); | |
| 408 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 409 } | |
| 410 | |
| 411 function matchXPathQuery(doc) | |
| 412 { | |
| 413 const result = doc.__proto__.evaluate.call(doc, whitespaceTrimmedQue
ry, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE); | |
| 414 addNodesToResults.call(this, result, result.snapshotLength, result.s
napshotItem); | |
| 415 } | |
| 416 | |
| 417 function finishedSearching() | |
| 418 { | |
| 419 // Remove the searchResultsProperty now that the search is finished. | |
| 420 for (var i = 0; i < this._searchResults.length; ++i) | |
| 421 delete this._searchResults[i][searchResultsProperty]; | |
| 422 } | |
| 423 | |
| 424 const mainFrameDocument = InspectorController.inspectedWindow().document
; | |
| 425 const searchDocuments = [mainFrameDocument]; | |
| 426 | |
| 427 if (tagNameQuery && startTagFound && endTagFound) | |
| 428 const searchFunctions = [matchExactTagNames, matchPlainText]; | |
| 429 else if (tagNameQuery && startTagFound) | |
| 430 const searchFunctions = [matchStartOfTagNames, matchPlainText]; | |
| 431 else if (tagNameQuery && endTagFound) { | |
| 432 // FIXME: we should have a matchEndOfTagNames search function if end
TagFound is true but not startTagFound. | |
| 433 // This requires ends-with() support in XPath, WebKit only supports
starts-with() and contains(). | |
| 434 const searchFunctions = [matchPartialTagNames, matchPlainText]; | |
| 435 } else if (whitespaceTrimmedQuery === "//*" || whitespaceTrimmedQuery ==
= "*") { | |
| 436 // These queries will match every node. Matching everything isn't us
eful and can be slow for large pages, | |
| 437 // so limit the search functions list to plain text and attribute ma
tching. | |
| 438 const searchFunctions = [matchPartialAttributeValues, matchPlainText
]; | |
| 439 } else | |
| 440 const searchFunctions = [matchExactItems, matchStyleSelector, matchP
artialTagNamesAndAttributeValues, matchPlainText, matchXPathQuery]; | |
| 441 | |
| 442 // Find all frames, iframes and object elements to search their document
s. | |
| 443 const querySelectorAllFunction = InspectorController.inspectedWindow().D
ocument.prototype.querySelectorAll; | |
| 444 const subdocumentResult = querySelectorAllFunction.call(mainFrameDocumen
t, "iframe, frame, object"); | |
| 445 | |
| 446 for (var i = 0; i < subdocumentResult.length; ++i) { | |
| 447 var element = subdocumentResult.item(i); | |
| 448 if (element.contentDocument) | |
| 449 searchDocuments.push(element.contentDocument); | |
| 450 } | |
| 451 | |
| 452 const panel = this; | |
| 453 var documentIndex = 0; | |
| 454 var searchFunctionIndex = 0; | |
| 455 var chunkIntervalIdentifier = null; | |
| 456 | |
| 457 // Split up the work into chunks so we don't block the UI thread while p
rocessing. | |
| 458 | |
| 459 function processChunk() | |
| 460 { | |
| 461 var searchDocument = searchDocuments[documentIndex]; | |
| 462 var searchFunction = searchFunctions[searchFunctionIndex]; | |
| 463 | |
| 464 if (++searchFunctionIndex > searchFunctions.length) { | |
| 465 searchFunction = searchFunctions[0]; | |
| 466 searchFunctionIndex = 0; | |
| 467 | |
| 468 if (++documentIndex > searchDocuments.length) { | |
| 469 if (panel._currentSearchChunkIntervalIdentifier === chunkInt
ervalIdentifier) | |
| 470 delete panel._currentSearchChunkIntervalIdentifier; | |
| 471 clearInterval(chunkIntervalIdentifier); | |
| 472 finishedSearching.call(panel); | |
| 473 return; | |
| 474 } | |
| 475 | |
| 476 searchDocument = searchDocuments[documentIndex]; | |
| 477 } | |
| 478 | |
| 479 if (!searchDocument || !searchFunction) | |
| 480 return; | |
| 481 | |
| 482 try { | |
| 483 searchFunction.call(panel, searchDocument); | |
| 484 } catch(err) { | |
| 485 // ignore any exceptions. the query might be malformed, but we a
llow that. | |
| 486 } | |
| 487 } | |
| 488 | |
| 489 processChunk(); | |
| 490 | |
| 491 chunkIntervalIdentifier = setInterval(processChunk, 25); | |
| 492 this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier; | |
| 493 }, | 280 }, |
| 494 | 281 |
| 495 jumpToNextSearchResult: function() | 282 jumpToNextSearchResult: function() |
| 496 { | 283 { |
| 497 if (!this._searchResults || !this._searchResults.length) | 284 if (!this._searchResults || !this._searchResults.length) |
| 498 return; | 285 return; |
| 499 if (++this._currentSearchResultIndex >= this._searchResults.length) | 286 if (++this._currentSearchResultIndex >= this._searchResults.length) |
| 500 this._currentSearchResultIndex = 0; | 287 this._currentSearchResultIndex = 0; |
| 501 this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
]; | 288 this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
]; |
| 502 }, | 289 }, |
| 503 | 290 |
| 504 jumpToPreviousSearchResult: function() | 291 jumpToPreviousSearchResult: function() |
| 505 { | 292 { |
| 506 if (!this._searchResults || !this._searchResults.length) | 293 if (!this._searchResults || !this._searchResults.length) |
| 507 return; | 294 return; |
| 508 if (--this._currentSearchResultIndex < 0) | 295 if (--this._currentSearchResultIndex < 0) |
| 509 this._currentSearchResultIndex = (this._searchResults.length - 1); | 296 this._currentSearchResultIndex = (this._searchResults.length - 1); |
| 510 this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
]; | 297 this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex
]; |
| 511 }, | 298 }, |
| 512 | 299 |
| 513 inspectedWindowCleared: function(window) | 300 renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelec
tor) |
| 514 { | 301 { |
| 515 if (InspectorController.isWindowVisible()) | 302 // TODO: Implement Shifting the oldSelector, and its contents to a newSe
lector |
| 516 this.updateMutationEventListeners(window); | |
| 517 }, | 303 }, |
| 518 | 304 |
| 519 _addMutationEventListeners: function(monitoredWindow) | 305 addStyleChange: function(identifier, style, property) |
| 520 { | 306 { |
| 521 monitoredWindow.document.addEventListener("DOMNodeInserted", this._nodeI
nsertedEventListener, true); | 307 if (!style.parentRule) |
| 522 monitoredWindow.document.addEventListener("DOMNodeRemoved", this._nodeRe
movedEventListener, true); | 308 return; |
| 523 if (monitoredWindow.frameElement) | 309 |
| 524 monitoredWindow.addEventListener("DOMContentLoaded", this._contentLo
adedEventListener, true); | 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); |
| 525 }, | 321 }, |
| 526 | 322 |
| 527 _removeMutationEventListeners: function(monitoredWindow) | 323 removeStyleChange: function(identifier, style, property) |
| 528 { | 324 { |
| 529 if (monitoredWindow.frameElement) | 325 if (!style.parentRule) |
| 530 monitoredWindow.removeEventListener("DOMContentLoaded", this._conten
tLoadedEventListener, true); | |
| 531 if (!monitoredWindow.document) | |
| 532 return; | 326 return; |
| 533 monitoredWindow.document.removeEventListener("DOMNodeInserted", this._no
deInsertedEventListener, true); | 327 |
| 534 monitoredWindow.document.removeEventListener("DOMNodeRemoved", this._nod
eRemovedEventListener, true); | 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 } |
| 535 }, | 336 }, |
| 536 | 337 |
| 537 updateMutationEventListeners: function(monitoredWindow) | 338 generateStylesheet: function() |
| 538 { | 339 { |
| 539 this._addMutationEventListeners(monitoredWindow); | 340 if (!WebInspector.styleChanges) |
| 540 }, | 341 return; |
| 541 | 342 |
| 542 registerMutationEventListeners: function(monitoredWindow) | 343 // Merge Down to Just Selectors |
| 543 { | 344 var mergedSelectors = {}; |
| 544 if (!monitoredWindow || this._mutationMonitoredWindows.indexOf(monitored
Window) !== -1) | 345 for (var identifier in this._changedStyles) { |
| 545 return; | 346 for (var selector in this._changedStyles[identifier]) { |
| 546 this._mutationMonitoredWindows.push(monitoredWindow); | 347 if (!mergedSelectors[selector]) |
| 547 if (InspectorController.isWindowVisible()) | 348 mergedSelectors[selector] = this._changedStyles[identifier][
selector]; |
| 548 this._addMutationEventListeners(monitoredWindow); | 349 else { // merge on selector |
| 549 }, | 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]; |
| 550 | 359 |
| 551 unregisterMutationEventListeners: function(monitoredWindow) | 360 if (value1 === value2) |
| 552 { | 361 merge[property] = [value1]; |
| 553 if (!monitoredWindow || this._mutationMonitoredWindows.indexOf(monitored
Window) === -1) | 362 else if (Object.type(value1) === "array") |
| 554 return; | 363 merge[property].push(value2); |
| 555 this._mutationMonitoredWindows.remove(monitoredWindow); | 364 else |
| 556 this._removeMutationEventListeners(monitoredWindow); | 365 merge[property] = [value1, value2]; |
| 557 }, | 366 } |
| 367 } |
| 368 mergedSelectors[selector] = merge; |
| 369 } |
| 370 } |
| 371 } |
| 558 | 372 |
| 559 unregisterAllMutationEventListeners: function() | 373 var builder = []; |
| 560 { | 374 builder.push("/**"); |
| 561 for (var i = 0; i < this._mutationMonitoredWindows.length; ++i) | 375 builder.push(" * Inspector Generated Stylesheet"); // UIString? |
| 562 this._removeMutationEventListeners(this._mutationMonitoredWindows[i]
); | 376 builder.push(" */\n"); |
| 563 this._mutationMonitoredWindows = []; | 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 (Object.type(value) !== "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"))); |
| 564 }, | 412 }, |
| 565 | 413 |
| 566 get rootDOMNode() | 414 get rootDOMNode() |
| 567 { | 415 { |
| 568 return this.treeOutline.rootDOMNode; | 416 return this.treeOutline.rootDOMNode; |
| 569 }, | 417 }, |
| 570 | 418 |
| 571 set rootDOMNode(x) | 419 set rootDOMNode(x) |
| 572 { | 420 { |
| 573 this.treeOutline.rootDOMNode = x; | 421 this.treeOutline.rootDOMNode = x; |
| 574 }, | 422 }, |
| 575 | 423 |
| 576 get focusedDOMNode() | 424 get focusedDOMNode() |
| 577 { | 425 { |
| 578 return this.treeOutline.focusedDOMNode; | 426 return this.treeOutline.focusedDOMNode; |
| 579 }, | 427 }, |
| 580 | 428 |
| 581 set focusedDOMNode(x) | 429 set focusedDOMNode(x) |
| 582 { | 430 { |
| 583 this.treeOutline.focusedDOMNode = x; | 431 this.treeOutline.focusedDOMNode = x; |
| 584 }, | 432 }, |
| 585 | 433 |
| 586 _contentLoaded: function(event) | |
| 587 { | |
| 588 this.recentlyModifiedNodes.push({node: event.target, parent: event.targe
t.defaultView.frameElement, replaced: true}); | |
| 589 if (this.visible) | |
| 590 this._updateModifiedNodesSoon(); | |
| 591 }, | |
| 592 | |
| 593 _nodeInserted: function(event) | 434 _nodeInserted: function(event) |
| 594 { | 435 { |
| 595 this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
edNode, inserted: true}); | 436 this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
edNode, inserted: true}); |
| 596 if (this.visible) | 437 if (this.visible) |
| 597 this._updateModifiedNodesSoon(); | 438 this._updateModifiedNodesSoon(); |
| 598 }, | 439 }, |
| 599 | 440 |
| 600 _nodeRemoved: function(event) | 441 _nodeRemoved: function(event) |
| 601 { | 442 { |
| 602 this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
edNode, removed: true}); | 443 this.recentlyModifiedNodes.push({node: event.target, parent: event.relat
edNode, removed: true}); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 620 | 461 |
| 621 var updatedParentTreeElements = []; | 462 var updatedParentTreeElements = []; |
| 622 var updateBreadcrumbs = false; | 463 var updateBreadcrumbs = false; |
| 623 | 464 |
| 624 for (var i = 0; i < this.recentlyModifiedNodes.length; ++i) { | 465 for (var i = 0; i < this.recentlyModifiedNodes.length; ++i) { |
| 625 var replaced = this.recentlyModifiedNodes[i].replaced; | 466 var replaced = this.recentlyModifiedNodes[i].replaced; |
| 626 var parent = this.recentlyModifiedNodes[i].parent; | 467 var parent = this.recentlyModifiedNodes[i].parent; |
| 627 if (!parent) | 468 if (!parent) |
| 628 continue; | 469 continue; |
| 629 | 470 |
| 630 var parentNodeItem = this.treeOutline.findTreeElement(parent, null,
null, objectsAreSame); | 471 var parentNodeItem = this.treeOutline.findTreeElement(parent); |
| 631 if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) { | 472 if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) { |
| 632 parentNodeItem.updateChildren(replaced); | 473 parentNodeItem.updateChildren(replaced); |
| 633 parentNodeItem.alreadyUpdatedChildren = true; | 474 parentNodeItem.alreadyUpdatedChildren = true; |
| 634 updatedParentTreeElements.push(parentNodeItem); | 475 updatedParentTreeElements.push(parentNodeItem); |
| 635 } | 476 } |
| 636 | 477 |
| 637 if (!updateBreadcrumbs && (objectsAreSame(this.focusedDOMNode, paren
t) || isAncestorIncludingParentFrames(this.focusedDOMNode, parent))) | 478 if (!updateBreadcrumbs && (this.focusedDOMNode === parent || isAnces
tor(this.focusedDOMNode, parent))) |
| 638 updateBreadcrumbs = true; | 479 updateBreadcrumbs = true; |
| 639 } | 480 } |
| 640 | 481 |
| 641 for (var i = 0; i < updatedParentTreeElements.length; ++i) | 482 for (var i = 0; i < updatedParentTreeElements.length; ++i) |
| 642 delete updatedParentTreeElements[i].alreadyUpdatedChildren; | 483 delete updatedParentTreeElements[i].alreadyUpdatedChildren; |
| 643 | 484 |
| 644 this.recentlyModifiedNodes = []; | 485 this.recentlyModifiedNodes = []; |
| 645 | 486 |
| 646 if (updateBreadcrumbs) | 487 if (updateBreadcrumbs) |
| 647 this.updateBreadcrumb(true); | 488 this.updateBreadcrumb(true); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 { | 528 { |
| 688 if (!this.visible) | 529 if (!this.visible) |
| 689 return; | 530 return; |
| 690 | 531 |
| 691 var crumbs = this.crumbsElement; | 532 var crumbs = this.crumbsElement; |
| 692 | 533 |
| 693 var handled = false; | 534 var handled = false; |
| 694 var foundRoot = false; | 535 var foundRoot = false; |
| 695 var crumb = crumbs.firstChild; | 536 var crumb = crumbs.firstChild; |
| 696 while (crumb) { | 537 while (crumb) { |
| 697 if (objectsAreSame(crumb.representedObject, this.rootDOMNode)) | 538 if (crumb.representedObject === this.rootDOMNode) |
| 698 foundRoot = true; | 539 foundRoot = true; |
| 699 | 540 |
| 700 if (foundRoot) | 541 if (foundRoot) |
| 701 crumb.addStyleClass("dimmed"); | 542 crumb.addStyleClass("dimmed"); |
| 702 else | 543 else |
| 703 crumb.removeStyleClass("dimmed"); | 544 crumb.removeStyleClass("dimmed"); |
| 704 | 545 |
| 705 if (objectsAreSame(crumb.representedObject, this.focusedDOMNode)) { | 546 if (crumb.representedObject === this.focusedDOMNode) { |
| 706 crumb.addStyleClass("selected"); | 547 crumb.addStyleClass("selected"); |
| 707 handled = true; | 548 handled = true; |
| 708 } else { | 549 } else { |
| 709 crumb.removeStyleClass("selected"); | 550 crumb.removeStyleClass("selected"); |
| 710 } | 551 } |
| 711 | 552 |
| 712 crumb = crumb.nextSibling; | 553 crumb = crumb.nextSibling; |
| 713 } | 554 } |
| 714 | 555 |
| 715 if (handled && !forceUpdate) { | 556 if (handled && !forceUpdate) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 // will change the root node in addition to the focused node. | 589 // will change the root node in addition to the focused node. |
| 749 if (event.detail >= 2 || crumb.hasStyleClass("dimmed")) | 590 if (event.detail >= 2 || crumb.hasStyleClass("dimmed")) |
| 750 panel.rootDOMNode = crumb.representedObject.parentNode; | 591 panel.rootDOMNode = crumb.representedObject.parentNode; |
| 751 panel.focusedDOMNode = crumb.representedObject; | 592 panel.focusedDOMNode = crumb.representedObject; |
| 752 } | 593 } |
| 753 | 594 |
| 754 event.preventDefault(); | 595 event.preventDefault(); |
| 755 } | 596 } |
| 756 | 597 |
| 757 foundRoot = false; | 598 foundRoot = false; |
| 758 for (var current = this.focusedDOMNode; current; current = parentNodeOrF
rameElement(current)) { | 599 for (var current = this.focusedDOMNode; current; current = current.paren
tNode) { |
| 759 if (current.nodeType === Node.DOCUMENT_NODE) | 600 if (current.nodeType === Node.DOCUMENT_NODE) |
| 760 continue; | 601 continue; |
| 761 | 602 |
| 762 if (objectsAreSame(current, this.rootDOMNode)) | 603 if (current === this.rootDOMNode) |
| 763 foundRoot = true; | 604 foundRoot = true; |
| 764 | 605 |
| 765 var crumb = document.createElement("span"); | 606 var crumb = document.createElement("span"); |
| 766 crumb.className = "crumb"; | 607 crumb.className = "crumb"; |
| 767 crumb.representedObject = current; | 608 crumb.representedObject = current; |
| 768 crumb.addEventListener("mousedown", selectCrumbFunction, false); | 609 crumb.addEventListener("mousedown", selectCrumbFunction, false); |
| 769 | 610 |
| 770 var crumbTitle; | 611 var crumbTitle; |
| 771 switch (current.nodeType) { | 612 switch (current.nodeType) { |
| 772 case Node.ELEMENT_NODE: | 613 case Node.ELEMENT_NODE: |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 if (!crumb.childNodes.length) { | 676 if (!crumb.childNodes.length) { |
| 836 var nameElement = document.createElement("span"); | 677 var nameElement = document.createElement("span"); |
| 837 nameElement.textContent = crumbTitle; | 678 nameElement.textContent = crumbTitle; |
| 838 crumb.appendChild(nameElement); | 679 crumb.appendChild(nameElement); |
| 839 } | 680 } |
| 840 | 681 |
| 841 crumb.title = crumbTitle; | 682 crumb.title = crumbTitle; |
| 842 | 683 |
| 843 if (foundRoot) | 684 if (foundRoot) |
| 844 crumb.addStyleClass("dimmed"); | 685 crumb.addStyleClass("dimmed"); |
| 845 if (objectsAreSame(current, this.focusedDOMNode)) | 686 if (current === this.focusedDOMNode) |
| 846 crumb.addStyleClass("selected"); | 687 crumb.addStyleClass("selected"); |
| 847 if (!crumbs.childNodes.length) | 688 if (!crumbs.childNodes.length) |
| 848 crumb.addStyleClass("end"); | 689 crumb.addStyleClass("end"); |
| 849 | 690 |
| 850 crumbs.appendChild(crumb); | 691 crumbs.appendChild(crumb); |
| 851 } | 692 } |
| 852 | 693 |
| 853 if (crumbs.hasChildNodes()) | 694 if (crumbs.hasChildNodes()) |
| 854 crumbs.lastChild.addStyleClass("start"); | 695 crumbs.lastChild.addStyleClass("start"); |
| 855 | 696 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 | 747 |
| 907 // Restore the start and end crumb classes in case they got removed in c
oalesceCollapsedCrumbs(). | 748 // Restore the start and end crumb classes in case they got removed in c
oalesceCollapsedCrumbs(). |
| 908 // The order of the crumbs in the document is opposite of the visual ord
er. | 749 // The order of the crumbs in the document is opposite of the visual ord
er. |
| 909 crumbs.firstChild.addStyleClass("end"); | 750 crumbs.firstChild.addStyleClass("end"); |
| 910 crumbs.lastChild.addStyleClass("start"); | 751 crumbs.lastChild.addStyleClass("start"); |
| 911 | 752 |
| 912 function crumbsAreSmallerThanContainer() | 753 function crumbsAreSmallerThanContainer() |
| 913 { | 754 { |
| 914 var rightPadding = 20; | 755 var rightPadding = 20; |
| 915 var errorWarningElement = document.getElementById("error-warning-cou
nt"); | 756 var errorWarningElement = document.getElementById("error-warning-cou
nt"); |
| 916 if (!WebInspector.console.visible && errorWarningElement) | 757 if (!WebInspector.drawer.visible && errorWarningElement) |
| 917 rightPadding += errorWarningElement.offsetWidth; | 758 rightPadding += errorWarningElement.offsetWidth; |
| 918 return ((crumbs.totalOffsetLeft + crumbs.offsetWidth + rightPadding)
< window.innerWidth); | 759 return ((crumbs.totalOffsetLeft + crumbs.offsetWidth + rightPadding)
< window.innerWidth); |
| 919 } | 760 } |
| 920 | 761 |
| 921 if (crumbsAreSmallerThanContainer()) | 762 if (crumbsAreSmallerThanContainer()) |
| 922 return; // No need to compact the crumbs, they all fit at full size. | 763 return; // No need to compact the crumbs, they all fit at full size. |
| 923 | 764 |
| 924 var BothSides = 0; | 765 var BothSides = 0; |
| 925 var AncestorSide = -1; | 766 var AncestorSide = -1; |
| 926 var ChildSide = 1; | 767 var ChildSide = 1; |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 }, | 983 }, |
| 1143 | 984 |
| 1144 handleCopyEvent: function(event) | 985 handleCopyEvent: function(event) |
| 1145 { | 986 { |
| 1146 // Don't prevent the normal copy if the user has a selection. | 987 // Don't prevent the normal copy if the user has a selection. |
| 1147 if (!window.getSelection().isCollapsed) | 988 if (!window.getSelection().isCollapsed) |
| 1148 return; | 989 return; |
| 1149 | 990 |
| 1150 switch (this.focusedDOMNode.nodeType) { | 991 switch (this.focusedDOMNode.nodeType) { |
| 1151 case Node.ELEMENT_NODE: | 992 case Node.ELEMENT_NODE: |
| 1152 var data = this.focusedDOMNode.outerHTML; | 993 // TODO: Introduce InspectorController.copyEvent that pushes app
ropriate markup into the clipboard. |
| 994 var data = null; |
| 1153 break; | 995 break; |
| 1154 | 996 |
| 1155 case Node.COMMENT_NODE: | 997 case Node.COMMENT_NODE: |
| 1156 var data = "<!--" + this.focusedDOMNode.nodeValue + "-->"; | 998 var data = "<!--" + this.focusedDOMNode.nodeValue + "-->"; |
| 1157 break; | 999 break; |
| 1158 | 1000 |
| 1159 default: | 1001 default: |
| 1160 case Node.TEXT_NODE: | 1002 case Node.TEXT_NODE: |
| 1161 var data = this.focusedDOMNode.nodeValue; | 1003 var data = this.focusedDOMNode.nodeValue; |
| 1162 } | 1004 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1189 | 1031 |
| 1190 this.treeOutline.updateSelection(); | 1032 this.treeOutline.updateSelection(); |
| 1191 | 1033 |
| 1192 event.preventDefault(); | 1034 event.preventDefault(); |
| 1193 }, | 1035 }, |
| 1194 | 1036 |
| 1195 _nodeSearchButtonClicked: function(event) | 1037 _nodeSearchButtonClicked: function(event) |
| 1196 { | 1038 { |
| 1197 InspectorController.toggleNodeSearch(); | 1039 InspectorController.toggleNodeSearch(); |
| 1198 | 1040 |
| 1199 if (InspectorController.searchingForNode()) | 1041 this.nodeSearchButton.toggled = InspectorController.searchingForNode(); |
| 1200 this.nodeSearchButton.addStyleClass("toggled-on"); | |
| 1201 else | |
| 1202 this.nodeSearchButton.removeStyleClass("toggled-on"); | |
| 1203 } | 1042 } |
| 1204 } | 1043 } |
| 1205 | 1044 |
| 1206 WebInspector.ElementsPanel.prototype.__proto__ = WebInspector.Panel.prototype; | 1045 WebInspector.ElementsPanel.prototype.__proto__ = WebInspector.Panel.prototype; |
| OLD | NEW |