summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end/ElementsPanel.js
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector/front-end/ElementsPanel.js')
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js434
1 files changed, 357 insertions, 77 deletions
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 1748159..ffa0000 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -61,8 +61,7 @@ WebInspector.ElementsPanel = function()
InspectorController.toggleNodeSearch();
this.panel.nodeSearchButton.removeStyleClass("toggled-on");
}
- if (this._focusedDOMNode)
- InspectorController.addInspectedNode(this._focusedDOMNode.id, function() {});
+ WebInspector.console.addInspectedNode(this._focusedDOMNode);
};
this.contentElement.appendChild(this.treeOutline.element);
@@ -98,7 +97,10 @@ WebInspector.ElementsPanel = function()
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarResizerDragStart.bind(this), false);
- this.nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
+ this.nodeSearchButton = this.createStatusBarButton();
+ this.nodeSearchButton.title = WebInspector.UIString("Select an element in the page to inspect it.");
+ this.nodeSearchButton.id = "node-search-status-bar-item";
+ this.nodeSearchButton.className = "status-bar-item";
this.nodeSearchButton.addEventListener("click", this._nodeSearchButtonClicked.bind(this), false);
this.searchingForNode = false;
@@ -107,7 +109,13 @@ WebInspector.ElementsPanel = function()
this.element.appendChild(this.sidebarElement);
this.element.appendChild(this.sidebarResizeElement);
- this._changedStyles = {};
+ this._mutationMonitoredWindows = [];
+ this._nodeInsertedEventListener = InspectorController.wrapCallback(this._nodeInserted.bind(this));
+ this._nodeRemovedEventListener = InspectorController.wrapCallback(this._nodeRemoved.bind(this));
+ this._contentLoadedEventListener = InspectorController.wrapCallback(this._contentLoaded.bind(this));
+
+ this.stylesheet = null;
+ this.styles = {};
this.reset();
}
@@ -122,7 +130,7 @@ WebInspector.ElementsPanel.prototype = {
get statusBarItems()
{
- return [this.nodeSearchButton.element, this.crumbsElement];
+ return [this.nodeSearchButton, this.crumbsElement];
},
updateStatusBarItems: function()
@@ -148,7 +156,7 @@ WebInspector.ElementsPanel.prototype = {
if (InspectorController.searchingForNode()) {
InspectorController.toggleNodeSearch();
- this.nodeSearchButton.toggled = false;
+ this.nodeSearchButton.removeStyleClass("toggled-on");
}
},
@@ -167,27 +175,40 @@ WebInspector.ElementsPanel.prototype = {
if (InspectorController.searchingForNode()) {
InspectorController.toggleNodeSearch();
- this.nodeSearchButton.toggled = false;
+ this.nodeSearchButton.removeStyleClass("toggled-on");
}
this.recentlyModifiedNodes = [];
+ this.unregisterAllMutationEventListeners();
delete this.currentQuery;
this.searchCanceled();
- var inspectedWindow = WebInspector.domAgent.inspectedWindow;
- if (!inspectedWindow || !inspectedWindow.document || !inspectedWindow.document.firstChild)
+ var inspectedWindow = Preferences.useDOMAgent ? WebInspector.domAgent.inspectedWindow : InspectorController.inspectedWindow();
+ if (!inspectedWindow || !inspectedWindow.document)
return;
+ if (!inspectedWindow.document.firstChild) {
+ function contentLoaded()
+ {
+ inspectedWindow.document.removeEventListener("DOMContentLoaded", contentLoadedCallback, false);
+
+ this.reset();
+ }
+
+ var contentLoadedCallback = InspectorController.wrapCallback(contentLoaded.bind(this));
+ inspectedWindow.document.addEventListener("DOMContentLoaded", contentLoadedCallback, false);
+ return;
+ }
+
// If the window isn't visible, return early so the DOM tree isn't built
// and mutation event listeners are not added.
if (!InspectorController.isWindowVisible())
return;
- var inspectedRootDocument = inspectedWindow.document;
- inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInserted.bind(this));
- inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemoved.bind(this));
+ this.registerMutationEventListeners(inspectedWindow);
+ var inspectedRootDocument = inspectedWindow.document;
this.rootDOMNode = inspectedRootDocument;
var canidateFocusNode = inspectedRootDocument.body || inspectedRootDocument.documentElement;
@@ -201,11 +222,19 @@ WebInspector.ElementsPanel.prototype = {
}
},
+ includedInSearchResultsPropertyName: "__includedInInspectorSearchResults",
+
searchCanceled: function()
{
if (this._searchResults) {
+ const searchResultsProperty = this.includedInSearchResultsPropertyName;
for (var i = 0; i < this._searchResults.length; ++i) {
- var treeElement = this.treeOutline.findTreeElement(this._searchResults[i]);
+ var node = this._searchResults[i];
+
+ // Remove the searchResultsProperty since there might be an unfinished search.
+ delete node[searchResultsProperty];
+
+ var treeElement = this.treeOutline.findTreeElement(node);
if (treeElement)
treeElement.highlighted = false;
}
@@ -213,9 +242,13 @@ WebInspector.ElementsPanel.prototype = {
WebInspector.updateSearchMatchesCount(0, this);
+ if (this._currentSearchChunkIntervalIdentifier) {
+ clearInterval(this._currentSearchChunkIntervalIdentifier);
+ delete this._currentSearchChunkIntervalIdentifier;
+ }
+
this._currentSearchResultIndex = 0;
this._searchResults = [];
- InspectorController.searchCanceled(function() {});
},
performSearch: function(query)
@@ -227,56 +260,241 @@ WebInspector.ElementsPanel.prototype = {
if (!whitespaceTrimmedQuery.length)
return;
- this._updatedMatchCountOnce = false;
- this._matchesCountUpdateTimeout = null;
+ var tagNameQuery = whitespaceTrimmedQuery;
+ var attributeNameQuery = whitespaceTrimmedQuery;
+ var startTagFound = (tagNameQuery.indexOf("<") === 0);
+ var endTagFound = (tagNameQuery.lastIndexOf(">") === (tagNameQuery.length - 1));
- InspectorController.performSearch(whitespaceTrimmedQuery, function() {});
- },
+ if (startTagFound || endTagFound) {
+ var tagNameQueryLength = tagNameQuery.length;
+ tagNameQuery = tagNameQuery.substring((startTagFound ? 1 : 0), (endTagFound ? (tagNameQueryLength - 1) : tagNameQueryLength));
+ }
- _updateMatchesCount: function()
- {
- WebInspector.updateSearchMatchesCount(this._searchResults.length, this);
- this._matchesCountUpdateTimeout = null;
- this._updatedMatchCountOnce = true;
- },
+ // Check the tagNameQuery is it is a possibly valid tag name.
+ if (!/^[a-zA-Z0-9\-_:]+$/.test(tagNameQuery))
+ tagNameQuery = null;
- _updateMatchesCountSoon: function()
- {
- if (!this._updatedMatchCountOnce)
- return this._updateMatchesCount();
- if (this._matchesCountUpdateTimeout)
- return;
- // Update the matches count every half-second so it doesn't feel twitchy.
- this._matchesCountUpdateTimeout = setTimeout(this._updateMatchesCount.bind(this), 500);
- },
+ // Check the attributeNameQuery is it is a possibly valid tag name.
+ if (!/^[a-zA-Z0-9\-_:]+$/.test(attributeNameQuery))
+ attributeNameQuery = null;
- addNodesToSearchResult: function(nodeIds)
- {
- if (!nodeIds)
- return;
+ const escapedQuery = query.escapeCharacters("'");
+ const escapedTagNameQuery = (tagNameQuery ? tagNameQuery.escapeCharacters("'") : null);
+ const escapedWhitespaceTrimmedQuery = whitespaceTrimmedQuery.escapeCharacters("'");
+ const searchResultsProperty = this.includedInSearchResultsPropertyName;
- var nodeIdsArray = nodeIds.split(",");
- for (var i = 0; i < nodeIdsArray.length; ++i) {
- var nodeId = nodeIdsArray[i];
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
- continue;
+ var updatedMatchCountOnce = false;
+ var matchesCountUpdateTimeout = null;
- if (!this._searchResults.length) {
- this._currentSearchResultIndex = 0;
- this.focusedDOMNode = node;
+ function updateMatchesCount()
+ {
+ WebInspector.updateSearchMatchesCount(this._searchResults.length, this);
+ matchesCountUpdateTimeout = null;
+ updatedMatchCountOnce = true;
+ }
+
+ function updateMatchesCountSoon()
+ {
+ if (!updatedMatchCountOnce)
+ return updateMatchesCount.call(this);
+ if (matchesCountUpdateTimeout)
+ return;
+ // Update the matches count every half-second so it doesn't feel twitchy.
+ matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
+ }
+
+ function addNodesToResults(nodes, length, getItem)
+ {
+ if (!length)
+ return;
+
+ for (var i = 0; i < length; ++i) {
+ var node = getItem.call(nodes, i);
+ // Skip this node if it already has the property.
+ if (searchResultsProperty in node)
+ continue;
+
+ if (!this._searchResults.length) {
+ this._currentSearchResultIndex = 0;
+ this.focusedDOMNode = node;
+ }
+
+ node[searchResultsProperty] = true;
+ this._searchResults.push(node);
+
+ // Highlight the tree element to show it matched the search.
+ // FIXME: highlight the substrings in text nodes and attributes.
+ var treeElement = this.treeOutline.findTreeElement(node);
+ if (treeElement)
+ treeElement.highlighted = true;
}
- this._searchResults.push(node);
+ updateMatchesCountSoon.call(this);
+ }
+
+ function matchExactItems(doc)
+ {
+ matchExactId.call(this, doc);
+ matchExactClassNames.call(this, doc);
+ matchExactTagNames.call(this, doc);
+ matchExactAttributeNames.call(this, doc);
+ }
+
+ function matchExactId(doc)
+ {
+ const result = doc.__proto__.getElementById.call(doc, whitespaceTrimmedQuery);
+ addNodesToResults.call(this, result, (result ? 1 : 0), function() { return this });
+ }
+
+ function matchExactClassNames(doc)
+ {
+ const result = doc.__proto__.getElementsByClassName.call(doc, whitespaceTrimmedQuery);
+ addNodesToResults.call(this, result, result.length, result.item);
+ }
+
+ function matchExactTagNames(doc)
+ {
+ if (!tagNameQuery)
+ return;
+ const result = doc.__proto__.getElementsByTagName.call(doc, tagNameQuery);
+ addNodesToResults.call(this, result, result.length, result.item);
+ }
+
+ function matchExactAttributeNames(doc)
+ {
+ if (!attributeNameQuery)
+ return;
+ const result = doc.__proto__.querySelectorAll.call(doc, "[" + attributeNameQuery + "]");
+ addNodesToResults.call(this, result, result.length, result.item);
+ }
+
+ function matchPartialTagNames(doc)
+ {
+ if (!tagNameQuery)
+ return;
+ const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
+ }
- // Highlight the tree element to show it matched the search.
- // FIXME: highlight the substrings in text nodes and attributes.
- var treeElement = this.treeOutline.findTreeElement(node);
- if (treeElement)
- treeElement.highlighted = true;
+ function matchStartOfTagNames(doc)
+ {
+ if (!tagNameQuery)
+ return;
+ const result = doc.__proto__.evaluate.call(doc, "//*[starts-with(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
}
- this._updateMatchesCountSoon();
+ function matchPartialTagNamesAndAttributeValues(doc)
+ {
+ if (!tagNameQuery) {
+ matchPartialAttributeValues.call(this, doc);
+ return;
+ }
+
+ const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "') or contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
+ }
+
+ function matchPartialAttributeValues(doc)
+ {
+ const result = doc.__proto__.evaluate.call(doc, "//*[contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
+ }
+
+ function matchStyleSelector(doc)
+ {
+ const result = doc.__proto__.querySelectorAll.call(doc, whitespaceTrimmedQuery);
+ addNodesToResults.call(this, result, result.length, result.item);
+ }
+
+ function matchPlainText(doc)
+ {
+ const result = doc.__proto__.evaluate.call(doc, "//text()[contains(., '" + escapedQuery + "')] | //comment()[contains(., '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
+ }
+
+ function matchXPathQuery(doc)
+ {
+ const result = doc.__proto__.evaluate.call(doc, whitespaceTrimmedQuery, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
+ }
+
+ function finishedSearching()
+ {
+ // Remove the searchResultsProperty now that the search is finished.
+ for (var i = 0; i < this._searchResults.length; ++i)
+ delete this._searchResults[i][searchResultsProperty];
+ }
+
+ const mainFrameDocument = InspectorController.inspectedWindow().document;
+ const searchDocuments = [mainFrameDocument];
+
+ if (tagNameQuery && startTagFound && endTagFound)
+ const searchFunctions = [matchExactTagNames, matchPlainText];
+ else if (tagNameQuery && startTagFound)
+ const searchFunctions = [matchStartOfTagNames, matchPlainText];
+ else if (tagNameQuery && endTagFound) {
+ // FIXME: we should have a matchEndOfTagNames search function if endTagFound is true but not startTagFound.
+ // This requires ends-with() support in XPath, WebKit only supports starts-with() and contains().
+ const searchFunctions = [matchPartialTagNames, matchPlainText];
+ } else if (whitespaceTrimmedQuery === "//*" || whitespaceTrimmedQuery === "*") {
+ // These queries will match every node. Matching everything isn't useful and can be slow for large pages,
+ // so limit the search functions list to plain text and attribute matching.
+ const searchFunctions = [matchPartialAttributeValues, matchPlainText];
+ } else
+ const searchFunctions = [matchExactItems, matchStyleSelector, matchPartialTagNamesAndAttributeValues, matchPlainText, matchXPathQuery];
+
+ // Find all frames, iframes and object elements to search their documents.
+ const querySelectorAllFunction = InspectorController.inspectedWindow().Document.prototype.querySelectorAll;
+ const subdocumentResult = querySelectorAllFunction.call(mainFrameDocument, "iframe, frame, object");
+
+ for (var i = 0; i < subdocumentResult.length; ++i) {
+ var element = subdocumentResult.item(i);
+ if (element.contentDocument)
+ searchDocuments.push(element.contentDocument);
+ }
+
+ const panel = this;
+ var documentIndex = 0;
+ var searchFunctionIndex = 0;
+ var chunkIntervalIdentifier = null;
+
+ // Split up the work into chunks so we don't block the UI thread while processing.
+
+ function processChunk()
+ {
+ var searchDocument = searchDocuments[documentIndex];
+ var searchFunction = searchFunctions[searchFunctionIndex];
+
+ if (++searchFunctionIndex > searchFunctions.length) {
+ searchFunction = searchFunctions[0];
+ searchFunctionIndex = 0;
+
+ if (++documentIndex > searchDocuments.length) {
+ if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
+ delete panel._currentSearchChunkIntervalIdentifier;
+ clearInterval(chunkIntervalIdentifier);
+ finishedSearching.call(panel);
+ return;
+ }
+
+ searchDocument = searchDocuments[documentIndex];
+ }
+
+ if (!searchDocument || !searchFunction)
+ return;
+
+ try {
+ searchFunction.call(panel, searchDocument);
+ } catch(err) {
+ // ignore any exceptions. the query might be malformed, but we allow that.
+ }
+ }
+
+ processChunk();
+
+ chunkIntervalIdentifier = setInterval(processChunk, 25);
+ this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
},
jumpToNextSearchResult: function()
@@ -297,6 +515,12 @@ WebInspector.ElementsPanel.prototype = {
this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex];
},
+ inspectedWindowCleared: function(window)
+ {
+ if (InspectorController.isWindowVisible())
+ this.updateMutationEventListeners(window);
+ },
+
renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelector)
{
// TODO: Implement Shifting the oldSelector, and its contents to a newSelector
@@ -308,16 +532,16 @@ WebInspector.ElementsPanel.prototype = {
return;
var selector = style.parentRule.selectorText;
- if (!this._changedStyles[identifier])
- this._changedStyles[identifier] = {};
+ if (!this.styles[identifier])
+ this.styles[identifier] = {};
- if (!this._changedStyles[identifier][selector])
- this._changedStyles[identifier][selector] = {};
+ if (!this.styles[identifier][selector])
+ this.styles[identifier][selector] = {};
- if (!this._changedStyles[identifier][selector][property])
+ if (!this.styles[identifier][selector][property])
WebInspector.styleChanges += 1;
- this._changedStyles[identifier][selector][property] = style.getPropertyValue(property);
+ this.styles[identifier][selector][property] = style.getPropertyValue(property);
},
removeStyleChange: function(identifier, style, property)
@@ -326,11 +550,11 @@ WebInspector.ElementsPanel.prototype = {
return;
var selector = style.parentRule.selectorText;
- if (!this._changedStyles[identifier] || !this._changedStyles[identifier][selector])
+ if (!this.styles[identifier] || !this.styles[identifier][selector])
return;
- if (this._changedStyles[identifier][selector][property]) {
- delete this._changedStyles[identifier][selector][property];
+ if (this.styles[identifier][selector][property]) {
+ delete this.styles[identifier][selector][property];
WebInspector.styleChanges -= 1;
}
},
@@ -342,20 +566,20 @@ WebInspector.ElementsPanel.prototype = {
// Merge Down to Just Selectors
var mergedSelectors = {};
- for (var identifier in this._changedStyles) {
- for (var selector in this._changedStyles[identifier]) {
+ for (var identifier in this.styles) {
+ for (var selector in this.styles[identifier]) {
if (!mergedSelectors[selector])
- mergedSelectors[selector] = this._changedStyles[identifier][selector];
+ mergedSelectors[selector] = this.styles[identifier][selector];
else { // merge on selector
var merge = {};
for (var property in mergedSelectors[selector])
merge[property] = mergedSelectors[selector][property];
- for (var property in this._changedStyles[identifier][selector]) {
+ for (var property in this.styles[identifier][selector]) {
if (!merge[property])
- merge[property] = this._changedStyles[identifier][selector][property];
+ merge[property] = this.styles[identifier][selector][property];
else { // merge on property within a selector, include comment to notify user
var value1 = merge[property];
- var value2 = this._changedStyles[identifier][selector][property];
+ var value2 = this.styles[identifier][selector][property];
if (value1 === value2)
merge[property] = [value1];
@@ -412,6 +636,53 @@ WebInspector.ElementsPanel.prototype = {
InspectorController.inspectedWindow().console.log(result);
},
+ _addMutationEventListeners: function(monitoredWindow)
+ {
+ monitoredWindow.document.addEventListener("DOMNodeInserted", this._nodeInsertedEventListener, true);
+ monitoredWindow.document.addEventListener("DOMNodeRemoved", this._nodeRemovedEventListener, true);
+ if (monitoredWindow.frameElement)
+ monitoredWindow.addEventListener("DOMContentLoaded", this._contentLoadedEventListener, true);
+ },
+
+ _removeMutationEventListeners: function(monitoredWindow)
+ {
+ if (monitoredWindow.frameElement)
+ monitoredWindow.removeEventListener("DOMContentLoaded", this._contentLoadedEventListener, true);
+ if (!monitoredWindow.document)
+ return;
+ monitoredWindow.document.removeEventListener("DOMNodeInserted", this._nodeInsertedEventListener, true);
+ monitoredWindow.document.removeEventListener("DOMNodeRemoved", this._nodeRemovedEventListener, true);
+ },
+
+ updateMutationEventListeners: function(monitoredWindow)
+ {
+ this._addMutationEventListeners(monitoredWindow);
+ },
+
+ registerMutationEventListeners: function(monitoredWindow)
+ {
+ if (!monitoredWindow || this._mutationMonitoredWindows.indexOf(monitoredWindow) !== -1)
+ return;
+ this._mutationMonitoredWindows.push(monitoredWindow);
+ if (InspectorController.isWindowVisible())
+ this._addMutationEventListeners(monitoredWindow);
+ },
+
+ unregisterMutationEventListeners: function(monitoredWindow)
+ {
+ if (!monitoredWindow || this._mutationMonitoredWindows.indexOf(monitoredWindow) === -1)
+ return;
+ this._mutationMonitoredWindows.remove(monitoredWindow);
+ this._removeMutationEventListeners(monitoredWindow);
+ },
+
+ unregisterAllMutationEventListeners: function()
+ {
+ for (var i = 0; i < this._mutationMonitoredWindows.length; ++i)
+ this._removeMutationEventListeners(this._mutationMonitoredWindows[i]);
+ this._mutationMonitoredWindows = [];
+ },
+
get rootDOMNode()
{
return this.treeOutline.rootDOMNode;
@@ -432,6 +703,13 @@ WebInspector.ElementsPanel.prototype = {
this.treeOutline.focusedDOMNode = x;
},
+ _contentLoaded: function(event)
+ {
+ this.recentlyModifiedNodes.push({node: event.target, parent: event.target.defaultView.frameElement, replaced: true});
+ if (this.visible)
+ this._updateModifiedNodesSoon();
+ },
+
_nodeInserted: function(event)
{
this.recentlyModifiedNodes.push({node: event.target, parent: event.relatedNode, inserted: true});
@@ -469,14 +747,14 @@ WebInspector.ElementsPanel.prototype = {
if (!parent)
continue;
- var parentNodeItem = this.treeOutline.findTreeElement(parent);
+ var parentNodeItem = this.treeOutline.findTreeElement(parent, null, null, objectsAreSame);
if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
parentNodeItem.updateChildren(replaced);
parentNodeItem.alreadyUpdatedChildren = true;
updatedParentTreeElements.push(parentNodeItem);
}
- if (!updateBreadcrumbs && (this.focusedDOMNode === parent || isAncestorIncludingParentFrames(this.focusedDOMNode, parent)))
+ if (!updateBreadcrumbs && (objectsAreSame(this.focusedDOMNode, parent) || isAncestorIncludingParentFrames(this.focusedDOMNode, parent)))
updateBreadcrumbs = true;
}
@@ -536,7 +814,7 @@ WebInspector.ElementsPanel.prototype = {
var foundRoot = false;
var crumb = crumbs.firstChild;
while (crumb) {
- if (crumb.representedObject === this.rootDOMNode)
+ if (objectsAreSame(crumb.representedObject, this.rootDOMNode))
foundRoot = true;
if (foundRoot)
@@ -544,7 +822,7 @@ WebInspector.ElementsPanel.prototype = {
else
crumb.removeStyleClass("dimmed");
- if (crumb.representedObject === this.focusedDOMNode) {
+ if (objectsAreSame(crumb.representedObject, this.focusedDOMNode)) {
crumb.addStyleClass("selected");
handled = true;
} else {
@@ -601,7 +879,7 @@ WebInspector.ElementsPanel.prototype = {
if (current.nodeType === Node.DOCUMENT_NODE)
continue;
- if (current === this.rootDOMNode)
+ if (objectsAreSame(current, this.rootDOMNode))
foundRoot = true;
var crumb = document.createElement("span");
@@ -684,7 +962,7 @@ WebInspector.ElementsPanel.prototype = {
if (foundRoot)
crumb.addStyleClass("dimmed");
- if (current === this.focusedDOMNode)
+ if (objectsAreSame(current, this.focusedDOMNode))
crumb.addStyleClass("selected");
if (!crumbs.childNodes.length)
crumb.addStyleClass("end");
@@ -991,8 +1269,7 @@ WebInspector.ElementsPanel.prototype = {
switch (this.focusedDOMNode.nodeType) {
case Node.ELEMENT_NODE:
- // TODO: Introduce InspectorController.copyEvent that pushes appropriate markup into the clipboard.
- var data = null;
+ var data = this.focusedDOMNode.outerHTML;
break;
case Node.COMMENT_NODE:
@@ -1039,7 +1316,10 @@ WebInspector.ElementsPanel.prototype = {
{
InspectorController.toggleNodeSearch();
- this.nodeSearchButton.toggled = InspectorController.searchingForNode();
+ if (InspectorController.searchingForNode())
+ this.nodeSearchButton.addStyleClass("toggled-on");
+ else
+ this.nodeSearchButton.removeStyleClass("toggled-on");
}
}