summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector/front-end')
-rw-r--r--WebCore/inspector/front-end/DOMAgent.js11
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js59
-rw-r--r--WebCore/inspector/front-end/ElementsTreeOutline.js239
-rw-r--r--WebCore/inspector/front-end/EventListenersSidebarPane.js2
-rw-r--r--WebCore/inspector/front-end/Images/gearButtonGlyph.pngbin0 -> 323 bytes
-rw-r--r--WebCore/inspector/front-end/Images/popoverArrows.pngbin0 -> 784 bytes
-rw-r--r--WebCore/inspector/front-end/Images/popoverBackground.pngbin0 -> 2233 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbActiveHoriz.pngbin0 -> 647 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbActiveVert.pngbin0 -> 599 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbHoriz.pngbin0 -> 657 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbHoverHoriz.pngbin0 -> 667 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbHoverVert.pngbin0 -> 583 bytes
-rw-r--r--WebCore/inspector/front-end/Images/thumbVert.pngbin0 -> 568 bytes
-rw-r--r--WebCore/inspector/front-end/Images/trackHoriz.pngbin0 -> 520 bytes
-rw-r--r--WebCore/inspector/front-end/Images/trackVert.pngbin0 -> 523 bytes
-rw-r--r--WebCore/inspector/front-end/InjectedScript.js78
-rw-r--r--WebCore/inspector/front-end/ObjectPropertiesSection.js11
-rw-r--r--WebCore/inspector/front-end/ObjectProxy.js3
-rw-r--r--WebCore/inspector/front-end/Panel.js30
-rw-r--r--WebCore/inspector/front-end/Popover.js147
-rw-r--r--WebCore/inspector/front-end/Popup.js168
-rw-r--r--WebCore/inspector/front-end/PropertiesSidebarPane.js4
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js5
-rw-r--r--WebCore/inspector/front-end/Section.js1
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js181
-rw-r--r--WebCore/inspector/front-end/SourceHTMLTokenizer.js8
-rw-r--r--WebCore/inspector/front-end/SourceHTMLTokenizer.re2js6
-rw-r--r--WebCore/inspector/front-end/SourceJavaScriptTokenizer.js2
-rw-r--r--WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js2
-rw-r--r--WebCore/inspector/front-end/SourceTokenizer.js14
-rw-r--r--WebCore/inspector/front-end/TextEditorHighlighter.js34
-rw-r--r--WebCore/inspector/front-end/TextViewer.js200
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc14
-rw-r--r--WebCore/inspector/front-end/inspector.css43
-rw-r--r--WebCore/inspector/front-end/inspector.html5
-rw-r--r--WebCore/inspector/front-end/inspector.js13
-rw-r--r--WebCore/inspector/front-end/inspectorSyntaxHighlight.css38
-rw-r--r--WebCore/inspector/front-end/popover.css200
-rw-r--r--WebCore/inspector/front-end/textViewer.css17
-rw-r--r--WebCore/inspector/front-end/utilities.js61
40 files changed, 1129 insertions, 467 deletions
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 6889408..834f527 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -153,10 +153,13 @@ WebInspector.DOMNode.prototype = {
_insertChild: function(prev, payload)
{
var node = new WebInspector.DOMNode(this.ownerDocument, payload);
- if (!prev)
- // First node
- this.children = [ node ];
- else
+ if (!prev) {
+ if (!this.children) {
+ // First node
+ this.children = [ node ];
+ } else
+ this.children.unshift(node);
+ } else
this.children.splice(this.children.indexOf(prev) + 1, 0, node);
this._renumber();
return node;
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index e839a60..897fdd1 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -245,13 +245,8 @@ WebInspector.ElementsPanel.prototype = {
searchCanceled: function()
{
- if (this._searchResults) {
- for (var i = 0; i < this._searchResults.length; ++i) {
- var treeElement = this.treeOutline.findTreeElement(this._searchResults[i]);
- if (treeElement)
- treeElement.highlighted = false;
- }
- }
+ delete this._searchQuery;
+ this._hideSearchHighlights();
WebInspector.updateSearchMatchesCount(0, this);
@@ -271,6 +266,7 @@ WebInspector.ElementsPanel.prototype = {
this._updatedMatchCountOnce = false;
this._matchesCountUpdateTimeout = null;
+ this._searchQuery = query;
InjectedScriptAccess.getDefault().performSearch(whitespaceTrimmedQuery, function() {});
},
@@ -304,25 +300,10 @@ WebInspector.ElementsPanel.prototype = {
if (!node)
continue;
- if (!this._searchResults.length) {
- this._currentSearchResultIndex = 0;
-
- // Only change the focusedDOMNode if the search was manually performed, because
- // the search may have been performed programmatically and we wouldn't want to
- // change the current focusedDOMNode.
- if (WebInspector.currentFocusElement === document.getElementById("search"))
- this.focusedDOMNode = node;
- }
-
+ this._currentSearchResultIndex = 0;
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._highlightCurrentSearchResult();
this._updateMatchesCountSoon();
},
@@ -330,18 +311,41 @@ WebInspector.ElementsPanel.prototype = {
{
if (!this._searchResults || !this._searchResults.length)
return;
+
if (++this._currentSearchResultIndex >= this._searchResults.length)
this._currentSearchResultIndex = 0;
- this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex];
+ this._highlightCurrentSearchResult();
},
jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
+
if (--this._currentSearchResultIndex < 0)
this._currentSearchResultIndex = (this._searchResults.length - 1);
- this.focusedDOMNode = this._searchResults[this._currentSearchResultIndex];
+ this._highlightCurrentSearchResult();
+ },
+
+ _highlightCurrentSearchResult: function()
+ {
+ this._hideSearchHighlights();
+ var node = this._searchResults[this._currentSearchResultIndex];
+ var treeElement = this.treeOutline.findTreeElement(node);
+ if (treeElement) {
+ treeElement.highlightSearchResults(this._searchQuery);
+ treeElement.reveal();
+ }
+ },
+
+ _hideSearchHighlights: function(node)
+ {
+ for (var i = 0; this._searchResults && i < this._searchResults.length; ++i) {
+ var node = this._searchResults[i];
+ var treeElement = this.treeOutline.findTreeElement(node);
+ if (treeElement)
+ treeElement.highlightSearchResults(null);
+ }
},
renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelector)
@@ -523,7 +527,8 @@ WebInspector.ElementsPanel.prototype = {
if (this.recentlyModifiedNodes[i].updated) {
var nodeItem = this.treeOutline.findTreeElement(node);
- nodeItem.updateTitle();
+ if (nodeItem)
+ nodeItem.updateTitle();
continue;
}
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index 4a8dae0..fe7ae53 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -59,9 +59,16 @@ WebInspector.ElementsTreeOutline.prototype = {
this._rootDOMNode = x;
+ this._isXMLMimeType = !!(WebInspector.mainResource && WebInspector.mainResource.mimeType && WebInspector.mainResource.mimeType.match(/x(?:ht)?ml/i));
+
this.update();
},
+ get isXMLMimeType()
+ {
+ return this._isXMLMimeType;
+ },
+
get focusedDOMNode()
{
return this._focusedDOMNode;
@@ -155,12 +162,27 @@ WebInspector.ElementsTreeOutline.prototype = {
return treeElement;
},
+ createTreeElementFor: function(node)
+ {
+ var treeElement = this.findTreeElement(node);
+ if (treeElement)
+ return treeElement;
+ if (!node.parentNode)
+ return null;
+
+ var treeElement = this.createTreeElementFor(node.parentNode);
+ if (treeElement && treeElement.showChild(node.index))
+ return treeElement.children[node.index];
+
+ return null;
+ },
+
revealAndSelectNode: function(node)
{
if (!node)
return;
- var treeElement = this.findTreeElement(node);
+ var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;
@@ -277,9 +299,9 @@ WebInspector.ElementsTreeOutline.prototype = {
var tag = event.target.enclosingNodeOrSelfWithClass("webkit-html-tag");
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
- if (tag)
+ if (tag && listItem.treeElement._populateTagContextMenu)
listItem.treeElement._populateTagContextMenu(contextMenu, event);
- else if (textNode)
+ else if (textNode && listItem.treeElement._populateTextContextMenu)
listItem.treeElement._populateTextContextMenu(contextMenu, textNode);
contextMenu.show(event);
}
@@ -296,27 +318,28 @@ WebInspector.ElementsTreeElement = function(node)
if (this.representedObject.nodeType == Node.ELEMENT_NODE)
this._canAddAttributes = true;
+ this._searchQuery = null;
+ this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
}
-WebInspector.ElementsTreeElement.prototype = {
- get highlighted()
- {
- return this._highlighted;
- },
+WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
+
+// A union of HTML4 and HTML5-Draft elements that explicitly
+// or implicitly (for HTML5) forbid the closing tag.
+// FIXME: Revise once HTML5 Final is published.
+WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
+ "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
+ "hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
+].keySet();
- set highlighted(x)
+WebInspector.ElementsTreeElement.prototype = {
+ highlightSearchResults: function(searchQuery)
{
- if (this._highlighted === x)
+ if (this._searchQuery === searchQuery)
return;
- this._highlighted = x;
-
- if (this.listItemElement) {
- if (x)
- this.listItemElement.addStyleClass("highlighted");
- else
- this.listItemElement.removeStyleClass("highlighted");
- }
+ this._searchQuery = searchQuery;
+ this.updateTitle();
},
get hovered()
@@ -341,6 +364,42 @@ WebInspector.ElementsTreeElement.prototype = {
}
},
+ get expandedChildrenLimit()
+ {
+ return this._expandedChildrenLimit;
+ },
+
+ set expandedChildrenLimit(x)
+ {
+ if (this._expandedChildrenLimit === x)
+ return;
+
+ this._expandedChildrenLimit = x;
+ if (this.treeOutline && !this._updateChildrenInProgress)
+ this._updateChildren(true);
+ },
+
+ get expandedChildCount()
+ {
+ var count = this.children.length;
+ if (count && this.children[count - 1].elementCloseTag)
+ count--;
+ if (count && this.children[count - 1].expandAllButton)
+ count--;
+ return count;
+ },
+
+ showChild: function(index)
+ {
+ if (index >= this.expandedChildrenLimit) {
+ this._expandedChildrenLimit = index + 1;
+ this._updateChildren(true);
+ }
+
+ // Whether index-th child is visible in the children tree
+ return this.expandedChildCount > index;
+ },
+
createTooltipForImageNode: function(node, callback)
{
function createTooltipThenCallback(properties)
@@ -386,9 +445,6 @@ WebInspector.ElementsTreeElement.prototype = {
{
this.listItemElement.addEventListener("mousedown", this.onmousedown.bind(this), false);
- if (this._highlighted)
- this.listItemElement.addStyleClass("highlighted");
-
if (this._hovered) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
@@ -422,9 +478,34 @@ WebInspector.ElementsTreeElement.prototype = {
WebInspector.domAgent.getChildNodesAsync(this.representedObject, this._updateChildren.bind(this, fullRefresh));
},
+ insertChildElement: function(child, index)
+ {
+ var newElement = new WebInspector.ElementsTreeElement(child);
+ newElement.selectable = this.treeOutline.selectEnabled;
+ this.insertChild(newElement, index);
+ return newElement;
+ },
+
+ moveChild: function(child, targetIndex)
+ {
+ var wasSelected = child.selected;
+ treeElement.removeChild(child);
+ treeElement.insertChild(child, targetIndex);
+ if (wasSelected)
+ existingTreeElement.select();
+ },
+
_updateChildren: function(fullRefresh)
{
+ if (this._updateChildrenInProgress)
+ return;
+
+ this._updateChildrenInProgress = true;
+ var focusedNode = this.treeOutline.focusedDOMNode;
+ var originalScrollTop;
if (fullRefresh) {
+ var treeOutlineContainerElement = this.treeOutline.element.parentNode;
+ originalScrollTop = treeOutlineContainerElement.scrollTop;
var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
this.select();
@@ -433,6 +514,7 @@ WebInspector.ElementsTreeElement.prototype = {
var treeElement = this;
var treeChildIndex = 0;
+ var elementToSelect;
function updateChildrenOfNode(node)
{
@@ -443,7 +525,7 @@ WebInspector.ElementsTreeElement.prototype = {
if (!currentTreeElement || currentTreeElement.representedObject !== child) {
// Find any existing element that is later in the children list.
var existingTreeElement = null;
- for (var i = (treeChildIndex + 1); i < treeElement.children.length; ++i) {
+ for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
if (treeElement.children[i].representedObject === child) {
existingTreeElement = treeElement.children[i];
break;
@@ -452,16 +534,16 @@ WebInspector.ElementsTreeElement.prototype = {
if (existingTreeElement && existingTreeElement.parent === treeElement) {
// If an existing element was found and it has the same parent, just move it.
- var wasSelected = existingTreeElement.selected;
- treeElement.removeChild(existingTreeElement);
- treeElement.insertChild(existingTreeElement, treeChildIndex);
- if (wasSelected)
- existingTreeElement.select();
+ treeElement.moveChild(existingTreeElement, treeChildIndex);
} else {
// No existing element found, insert a new element.
- var newElement = new WebInspector.ElementsTreeElement(child);
- newElement.selectable = treeOutline.selectEnabled;
- treeElement.insertChild(newElement, treeChildIndex);
+ if (treeChildIndex < treeElement.expandedChildrenLimit) {
+ var newElement = treeElement.insertChildElement(child, treeChildIndex);
+ if (child === focusedNode)
+ elementToSelect = newElement;
+ if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
+ treeElement.expandedChildrenLimit++;
+ }
}
}
@@ -490,6 +572,7 @@ WebInspector.ElementsTreeElement.prototype = {
}
updateChildrenOfNode(this.representedObject);
+ this.adjustCollapsedRange(false);
var lastChild = this.children[this.children.length - 1];
if (this.representedObject.nodeType == Node.ELEMENT_NODE && (!lastChild || !lastChild.elementCloseTag)) {
@@ -499,15 +582,66 @@ WebInspector.ElementsTreeElement.prototype = {
item.elementCloseTag = true;
this.appendChild(item);
}
+
+ // We want to restore the original selection and tree scroll position after a full refresh, if possible.
+ if (fullRefresh && elementToSelect) {
+ elementToSelect.select();
+ if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
+ treeOutlineContainerElement.scrollTop = originalScrollTop;
+ }
+
+ delete this._updateChildrenInProgress;
+ },
+
+ adjustCollapsedRange: function()
+ {
+ // Ensure precondition: only the tree elements for node children are found in the tree
+ // (not the Expand All button or the closing tag).
+ if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
+ this.removeChild(this.expandAllButtonElement.__treeElement);
+
+ const node = this.representedObject;
+ if (!node.children)
+ return;
+ const childNodeCount = node.children.length;
+
+ // In case some nodes from the expanded range were removed, pull some nodes from the collapsed range into the expanded range at the bottom.
+ for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
+ this.insertChildElement(node.children[i], i);
+
+ const expandedChildCount = this.expandedChildCount;
+ if (childNodeCount > this.expandedChildCount) {
+ var targetButtonIndex = expandedChildCount;
+ if (!this.expandAllButtonElement) {
+ var title = "<button class=\"show-all-nodes\" value=\"\" />";
+ var item = new TreeElement(title, null, false);
+ item.selectable = false;
+ item.expandAllButton = true;
+ this.insertChild(item, targetButtonIndex);
+ this.expandAllButtonElement = item.listItemElement.firstChild;
+ this.expandAllButtonElement.__treeElement = item;
+ this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
+ } else if (!this.expandAllButtonElement.__treeElement.parent)
+ this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
+ this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
+ } else if (this.expandAllButtonElement)
+ delete this.expandAllButtonElement;
+ },
+
+ handleLoadAllChildren: function()
+ {
+ this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
},
onexpand: function()
{
+ this.updateTitle();
this.treeOutline.updateSelection();
},
oncollapse: function()
{
+ this.updateTitle();
this.treeOutline.updateSelection();
},
@@ -879,11 +1013,12 @@ WebInspector.ElementsTreeElement.prototype = {
var self = this;
function callback(tooltipText)
{
- var title = self._nodeTitleInfo(self.representedObject, self.hasChildren, WebInspector.linkifyURL, tooltipText).title;
+ var title = self._nodeTitleInfo(WebInspector.linkifyURL, tooltipText).title;
self.title = "<span class=\"highlight\">" + title + "</span>";
delete self.selectionElement;
self.updateSelection();
self._preventFollowingLinksOnDoubleClick();
+ self._highlightSearchResults();
};
// TODO: Replace with InjectedScriptAccess.getBasicProperties(obj, [names]).
@@ -916,9 +1051,10 @@ WebInspector.ElementsTreeElement.prototype = {
return hrefValue;
},
- _nodeTitleInfo: function(node, hasChildren, linkify, tooltipText)
+ _nodeTitleInfo: function(linkify, tooltipText)
{
- var info = {title: "", hasChildren: hasChildren};
+ var node = this.representedObject;
+ var info = {title: "", hasChildren: this.hasChildren};
switch (node.nodeType) {
case Node.DOCUMENT_NODE:
@@ -930,7 +1066,8 @@ WebInspector.ElementsTreeElement.prototype = {
break;
case Node.ELEMENT_NODE:
- info.title = "<span class=\"webkit-html-tag\">&lt;" + node.nodeName.toLowerCase().escapeHTML();
+ var tagName = node.nodeName.toLowerCase().escapeHTML();
+ info.title = "<span class=\"webkit-html-tag\">&lt;" + tagName;
if (node.hasAttributes()) {
for (var i = 0; i < node.attributes.length; ++i) {
@@ -951,15 +1088,21 @@ WebInspector.ElementsTreeElement.prototype = {
}
info.title += "&gt;</span>&#8203;";
+ const closingTagHTML = "<span class=\"webkit-html-tag\">&lt;/" + tagName + "&gt;</span>&#8203;";
+ var textChild = onlyTextChild.call(node);
+ var showInlineText = textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength;
+
+ if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
+ if (this.hasChildren)
+ info.title += "<span class=\"webkit-html-text-node\">&#8230;</span>&#8203;";
+ info.title += closingTagHTML;
+ }
+
// If this element only has a single child that is a text node,
// just show that text and the closing tag inline rather than
// create a subtree for them
-
- var textChild = onlyTextChild.call(node);
- var showInlineText = textChild && textChild.textContent.length < Preferences.maxInlineTextChildLength;
-
if (showInlineText) {
- info.title += "<span class=\"webkit-html-text-node\">" + textChild.nodeValue.escapeHTML() + "</span>&#8203;<span class=\"webkit-html-tag\">&lt;/" + node.nodeName.toLowerCase().escapeHTML() + "&gt;</span>";
+ info.title += "<span class=\"webkit-html-text-node\">" + textChild.nodeValue.escapeHTML() + "</span>&#8203;" + closingTagHTML;
info.hasChildren = false;
}
break;
@@ -1038,6 +1181,7 @@ WebInspector.ElementsTreeElement.prototype = {
return;
parentElement.removeChild(self);
+ parentElement.adjustCollapsedRange(true);
}
var callId = WebInspector.Callback.wrap(removeNodeCallback);
@@ -1077,6 +1221,23 @@ WebInspector.ElementsTreeElement.prototype = {
_copyHTML: function()
{
InspectorBackend.copyNode(this.representedObject.id);
+ },
+
+ _highlightSearchResults: function()
+ {
+ if (!this._searchQuery)
+ return;
+ var text = this.listItemElement.textContent;
+ var regexObject = createSearchRegex(this._searchQuery);
+
+ var offset = 0;
+ var match = regexObject.exec(text);
+ while (match) {
+ highlightSearchResult(this.listItemElement, offset + match.index, match[0].length);
+ offset += match.index + 1;
+ text = text.substring(match.index + 1);
+ match = regexObject.exec(text);
+ }
}
}
diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js
index 649eea8..e454256 100644
--- a/WebCore/inspector/front-end/EventListenersSidebarPane.js
+++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js
@@ -191,7 +191,7 @@ WebInspector.EventListenerBar.prototype = {
// Just build properties in place - no need to reach out for injected script.
var value = this.eventListener[propertyName];
if (value instanceof WebInspector.DOMNode)
- value = new WebInspector.ObjectProxy(value.injectedScriptId, value.id, [], 0, appropriateSelectorForNode(value), true);
+ value = new WebInspector.ObjectProxy(value.injectedScriptId, value.id, [], appropriateSelectorForNode(value), true);
else
value = WebInspector.ObjectProxy.wrapPrimitiveValue(value);
properties.push(new WebInspector.ObjectPropertyProxy(propertyName, value));
diff --git a/WebCore/inspector/front-end/Images/gearButtonGlyph.png b/WebCore/inspector/front-end/Images/gearButtonGlyph.png
new file mode 100644
index 0000000..19659c9
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/gearButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/popoverArrows.png b/WebCore/inspector/front-end/Images/popoverArrows.png
new file mode 100644
index 0000000..ccefa16
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/popoverArrows.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/popoverBackground.png b/WebCore/inspector/front-end/Images/popoverBackground.png
new file mode 100644
index 0000000..f20c988
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/popoverBackground.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbActiveHoriz.png b/WebCore/inspector/front-end/Images/thumbActiveHoriz.png
new file mode 100644
index 0000000..a6ee561
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbActiveHoriz.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbActiveVert.png b/WebCore/inspector/front-end/Images/thumbActiveVert.png
new file mode 100644
index 0000000..a3eabe8
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbActiveVert.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbHoriz.png b/WebCore/inspector/front-end/Images/thumbHoriz.png
new file mode 100644
index 0000000..c16559a
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbHoriz.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbHoverHoriz.png b/WebCore/inspector/front-end/Images/thumbHoverHoriz.png
new file mode 100644
index 0000000..0fe8d6a
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbHoverHoriz.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbHoverVert.png b/WebCore/inspector/front-end/Images/thumbHoverVert.png
new file mode 100644
index 0000000..30e315a
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbHoverVert.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/thumbVert.png b/WebCore/inspector/front-end/Images/thumbVert.png
new file mode 100644
index 0000000..61fbc06
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/thumbVert.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/trackHoriz.png b/WebCore/inspector/front-end/Images/trackHoriz.png
new file mode 100644
index 0000000..517d306
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/trackHoriz.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/trackVert.png b/WebCore/inspector/front-end/Images/trackVert.png
new file mode 100644
index 0000000..d49620d
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/trackVert.png
Binary files differ
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
index 95867c4..8d8fa88 100644
--- a/WebCore/inspector/front-end/InjectedScript.js
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -485,25 +485,30 @@ InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty, abbre
var object = InjectedScript._resolveObject(objectProxy);
if (!InjectedScript._isDefined(object))
return false;
-
var properties = [];
+ var propertyNames = ignoreHasOwnProperty ? InjectedScript._getPropertyNames(object) : Object.getOwnPropertyNames(object);
+ if (!ignoreHasOwnProperty && object.__proto__)
+ propertyNames.push("__proto__");
// Go over properties, prepare results.
- for (var propertyName in object) {
- if (!ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
- continue;
+ for (var i = 0; i < propertyNames.length; ++i) {
+ var propertyName = propertyNames[i];
var property = {};
- property.name = propertyName;
+ property.name = propertyName + "";
property.parentObjectProxy = objectProxy;
var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
if (!property.isGetter) {
- var childObject = object[propertyName];
- var childObjectProxy = new InjectedScript.createProxyObject(childObject, objectProxy.objectId, abbreviate);
- childObjectProxy.path = objectProxy.path ? objectProxy.path.slice() : [];
- childObjectProxy.path.push(propertyName);
- childObjectProxy.protoDepth = objectProxy.protoDepth || 0;
- property.value = childObjectProxy;
+ try {
+ var childObject = object[propertyName];
+ var childObjectProxy = new InjectedScript.createProxyObject(childObject, objectProxy.objectId, abbreviate);
+ childObjectProxy.path = objectProxy.path ? objectProxy.path.slice() : [];
+ childObjectProxy.path.push(propertyName);
+ property.value = childObjectProxy;
+ } catch(e) {
+ property.value = { description: e.toString() };
+ property.isError = true;
+ }
} else {
// FIXME: this should show something like "getter" (bug 16734).
property.value = { description: "\u2014" }; // em dash
@@ -571,24 +576,25 @@ InjectedScript.setOuterHTML = function(nodeId, value, expanded)
return InjectedScriptHost.pushNodePathToFrontend(newNode, expanded, false);
}
-InjectedScript._getPropertyNames = function(object, resultSet)
+InjectedScript._populatePropertyNames = function(object, resultSet)
{
- if (Object.getOwnPropertyNames) {
- for (var o = object; o; o = o.__proto__) {
- try {
- var names = Object.getOwnPropertyNames(o);
- for (var i = 0; i < names.length; ++i)
- resultSet[names[i]] = true;
- } catch (e) {
- }
+ for (var o = object; o; o = o.__proto__) {
+ try {
+ var names = Object.getOwnPropertyNames(o);
+ for (var i = 0; i < names.length; ++i)
+ resultSet[names[i] + ""] = true;
+ } catch (e) {
}
- } else {
- // Chromium doesn't support getOwnPropertyNames yet.
- for (var name in object)
- resultSet[name] = true;
}
}
+InjectedScript._getPropertyNames = function(object, resultSet)
+{
+ var propertyNameSet = {};
+ InjectedScript._populatePropertyNames(object, propertyNameSet);
+ return Object.keys(propertyNameSet);
+}
+
InjectedScript.getCompletions = function(expression, includeInspectorCommandLineAPI, callFrameId)
{
var props = {};
@@ -605,7 +611,7 @@ InjectedScript.getCompletions = function(expression, includeInspectorCommandLine
// Evaluate into properties in scope of the selected call frame.
var scopeChain = callFrame.scopeChain;
for (var i = 0; i < scopeChain.length; ++i)
- InjectedScript._getPropertyNames(scopeChain[i], props);
+ InjectedScript._populatePropertyNames(scopeChain[i], props);
}
} else {
if (!expression)
@@ -613,7 +619,7 @@ InjectedScript.getCompletions = function(expression, includeInspectorCommandLine
expressionResult = InjectedScript._evaluateOn(InjectedScript._window().eval, InjectedScript._window(), expression);
}
if (typeof expressionResult == "object")
- InjectedScript._getPropertyNames(expressionResult, props);
+ InjectedScript._populatePropertyNames(expressionResult, props);
if (includeInspectorCommandLineAPI)
for (var prop in InjectedScript._window().console._inspectorCommandLineAPI)
if (prop.charAt(0) !== '_')
@@ -677,6 +683,12 @@ InjectedScript.addInspectedNode = function(nodeId)
InjectedScript.performSearch = function(whitespaceTrimmedQuery)
{
+ // FIXME: Few things are missing here:
+ // 1) Search works with node granularity - number of matches within node is not calculated.
+ // 2) Search does not work outside main documents' domain - we need to use specific InjectedScript instances
+ // for other domains.
+ // 3) There is no need to push all search results to the front-end at a time, pushing next / previous result
+ // is sufficient.
var tagNameQuery = whitespaceTrimmedQuery;
var attributeNameQuery = whitespaceTrimmedQuery;
var startTagFound = (tagNameQuery.indexOf("<") === 0);
@@ -1073,10 +1085,6 @@ InjectedScript._resolveObject = function(objectProxy)
for (var i = 0; InjectedScript._isDefined(object) && path && i < path.length; ++i)
object = object[path[i]];
- // Get to the necessary proto layer.
- for (var i = 0; InjectedScript._isDefined(object) && protoDepth && i < protoDepth; ++i)
- object = object.__proto__;
-
return object;
}
@@ -1136,14 +1144,12 @@ InjectedScript.createProxyObject = function(object, objectId, abbreviate)
result.injectedScriptId = injectedScriptId;
result.objectId = objectId;
result.type = InjectedScript._type(object);
+ if (result.type === "array")
+ result.propertyLength = object.length;
var type = typeof object;
- if ((type === "object" && object !== null) || type === "function") {
- for (var subPropertyName in object) {
- result.hasChildren = true;
- break;
- }
- }
+
+ result.hasChildren = (type === "object" && object !== null && (Object.getOwnPropertyNames(object).length || object.__proto__)) || type === "function";
try {
result.description = InjectedScript._describe(object, abbreviate);
} catch (e) {
diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js
index 6d71090..a32e799 100644
--- a/WebCore/inspector/front-end/ObjectPropertiesSection.js
+++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js
@@ -77,6 +77,7 @@ WebInspector.ObjectPropertiesSection.prototype = {
var infoElement = new TreeElement(title, null, false);
this.propertiesTreeOutline.appendChild(infoElement);
}
+ this.propertiesForTest = properties;
}
}
@@ -86,6 +87,10 @@ WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, pro
{
var a = propertyA.name;
var b = propertyB.name;
+ if (a === "__proto__")
+ return 1;
+ if (b === "__proto__")
+ return -1;
// if used elsewhere make sure to
// - convert a and b to strings (not needed here, properties are all strings)
@@ -173,8 +178,12 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.valueElement = document.createElement("span");
this.valueElement.className = "value";
this.valueElement.textContent = this.property.value.description;
+ if (typeof this.property.value.propertyLength !== "undefined")
+ this.valueElement.textContent += " (" + this.property.value.propertyLength + ")";
if (this.property.isGetter)
- this.valueElement.addStyleClass("dimmed");
+ this.valueElement.addStyleClass("dimmed");
+ if (this.property.isError)
+ this.valueElement.addStyleClass("error");
this.listItemElement.removeChildren();
diff --git a/WebCore/inspector/front-end/ObjectProxy.js b/WebCore/inspector/front-end/ObjectProxy.js
index 62517b8..ef139c6 100644
--- a/WebCore/inspector/front-end/ObjectProxy.js
+++ b/WebCore/inspector/front-end/ObjectProxy.js
@@ -28,12 +28,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.ObjectProxy = function(injectedScriptId, objectId, path, protoDepth, description, hasChildren)
+WebInspector.ObjectProxy = function(injectedScriptId, objectId, path, description, hasChildren)
{
this.objectId = objectId;
this.injectedScriptId = injectedScriptId;
this.path = path || [];
- this.protoDepth = protoDepth || 0;
this.description = description;
this.hasChildren = hasChildren;
}
diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js
index 5e81e2d..5b01191 100644
--- a/WebCore/inspector/front-end/Panel.js
+++ b/WebCore/inspector/front-end/Panel.js
@@ -230,16 +230,17 @@ WebInspector.Panel.prototype = {
var currentView = this._searchResults[this._currentSearchResultIndex];
if (currentView.showingLastSearchResult()) {
- if (++this._currentSearchResultIndex >= this._searchResults.length)
- this._currentSearchResultIndex = 0;
- currentView = this._searchResults[this._currentSearchResultIndex];
+ if (this.searchIteratesOverViews()) {
+ if (++this._currentSearchResultIndex >= this._searchResults.length)
+ this._currentSearchResultIndex = 0;
+ currentView = this._searchResults[this._currentSearchResultIndex];
+ }
showFirstResult = true;
}
if (currentView !== this.visibleView) {
- currentView = this.visibleView;
- this._currentSearchResultIndex = 0;
- showFirstResult = true;
+ this.showView(currentView);
+ WebInspector.focusSearchField();
}
if (showFirstResult)
@@ -264,14 +265,18 @@ WebInspector.Panel.prototype = {
var currentView = this._searchResults[this._currentSearchResultIndex];
if (currentView.showingFirstSearchResult()) {
- if (--this._currentSearchResultIndex < 0)
- this._currentSearchResultIndex = (this._searchResults.length - 1);
- currentView = this._searchResults[this._currentSearchResultIndex];
+ if (this.searchIteratesOverViews()) {
+ if (--this._currentSearchResultIndex < 0)
+ this._currentSearchResultIndex = (this._searchResults.length - 1);
+ currentView = this._searchResults[this._currentSearchResultIndex];
+ }
showLastResult = true;
}
- if (currentView !== this.visibleView)
+ if (currentView !== this.visibleView) {
this.showView(currentView);
+ WebInspector.focusSearchField();
+ }
if (showLastResult)
currentView.jumpToLastSearchResult();
@@ -376,6 +381,11 @@ WebInspector.Panel.prototype = {
showSourceLineForURL: function(url, line)
{
return false;
+ },
+
+ searchIteratesOverViews: function()
+ {
+ return false;
}
}
diff --git a/WebCore/inspector/front-end/Popover.js b/WebCore/inspector/front-end/Popover.js
new file mode 100644
index 0000000..70e4ac9
--- /dev/null
+++ b/WebCore/inspector/front-end/Popover.js
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Popover = function(contentElement)
+{
+ this.element = document.createElement("div");
+ this.element.className = "popover";
+
+ this._popupArrowElement = document.createElement("div");
+ this._popupArrowElement.className = "arrow";
+ this.element.appendChild(this._popupArrowElement);
+
+ this.contentElement = contentElement;
+}
+
+WebInspector.Popover.prototype = {
+ show: function(anchor, preferredWidth, preferredHeight)
+ {
+ // This should not happen, but we hide previous popup to be on the safe side.
+ if (WebInspector.Popover._popoverElement)
+ document.body.removeChild(WebInspector.Popover._popoverElement);
+ WebInspector.Popover._popoverElement = this.element;
+
+ // Temporarily attach in order to measure preferred dimensions.
+ this.contentElement.positionAt(0, 0);
+ document.body.appendChild(this.contentElement);
+ var preferredWidth = preferredWidth || this.contentElement.offsetWidth;
+ var preferredHeight = preferredHeight || this.contentElement.offsetHeight;
+
+ this.contentElement.addStyleClass("content");
+ this.element.appendChild(this.contentElement);
+ document.body.appendChild(this.element);
+ this._positionElement(anchor, preferredWidth, preferredHeight);
+ },
+
+ hide: function()
+ {
+ delete WebInspector.Popover._popoverElement;
+ document.body.removeChild(this.element);
+ },
+
+ _positionElement: function(anchorElement, preferredWidth, preferredHeight)
+ {
+ const borderWidth = 25;
+ const scrollerWidth = 11;
+ const arrowHeight = 10;
+ const arrowOffset = 15;
+
+ // Skinny tooltips are not pretty, their arrow location is not nice.
+ preferredWidth = Math.max(preferredWidth, 50);
+ const totalWidth = window.innerWidth;
+ const totalHeight = window.innerHeight;
+
+ var anchorBox = {x: anchorElement.totalOffsetLeft, y: anchorElement.totalOffsetTop, width: anchorElement.offsetWidth, height: anchorElement.offsetHeight};
+ while (anchorElement !== document.body) {
+ if (anchorElement.scrollLeft)
+ anchorBox.x -= anchorElement.scrollLeft;
+ if (anchorElement.scrollTop)
+ anchorBox.y -= anchorElement.scrollTop;
+ anchorElement = anchorElement.parentElement;
+ }
+
+ var newElementPosition = { x: 0, y: 0, width: preferredWidth + borderWidth * 2, height: preferredHeight + borderWidth * 2 };
+
+ var verticalAlignment;
+ var roomAbove = anchorBox.y;
+ var roomBelow = totalHeight - anchorBox.y - anchorBox.height;
+
+ if (roomAbove > roomBelow) {
+ // Positioning above the anchor.
+ if (anchorBox.y > newElementPosition.height)
+ newElementPosition.y = anchorBox.y - newElementPosition.height;
+ else {
+ newElementPosition.y = 0;
+ newElementPosition.height = anchorBox.y - newElementPosition.y;
+ // Reserve room for vertical scroller anyways.
+ newElementPosition.width += scrollerWidth;
+ }
+ verticalAlignment = "bottom";
+ } else {
+ // Positioning below the anchor.
+ newElementPosition.y = anchorBox.y + anchorBox.height;
+ if (newElementPosition.y + newElementPosition.height >= totalHeight) {
+ newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height;
+ // Reserve room for vertical scroller.
+ newElementPosition.width += scrollerWidth;
+ }
+ // Align arrow.
+ newElementPosition.y -= arrowHeight;
+ verticalAlignment = "top";
+ }
+
+ var horizontalAlignment;
+ if (anchorBox.x + newElementPosition.width < totalWidth) {
+ newElementPosition.x = Math.max(0, anchorBox.x) - borderWidth - arrowOffset;
+ horizontalAlignment = "left";
+ } else if (newElementPosition.width < totalWidth) {
+ newElementPosition.x = totalWidth - newElementPosition.width;
+ horizontalAlignment = "right";
+ // Position arrow accurately.
+ this._popupArrowElement.style.right = totalWidth - anchorBox.x - borderWidth - anchorBox.width + "px";
+ } else {
+ newElementPosition.x = 0;
+ newElementPosition.width = totalWidth;
+ horizontalAlignment = "left";
+ if (verticalAlignment === "bottom")
+ newElementPosition.y -= scrollerWidth;
+ // Position arrow accurately.
+ this._popupArrowElement.style.left = anchorBox.x - borderWidth + "px";
+ }
+
+ // Reserve room for horizontal scroller.
+ newElementPosition.height += scrollerWidth;
+
+ this.element.className = "popover " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
+ this.element.positionAt(newElementPosition.x, newElementPosition.y);
+ this.element.style.width = newElementPosition.width + "px";
+ this.element.style.height = newElementPosition.height + "px";
+ }
+}
diff --git a/WebCore/inspector/front-end/Popup.js b/WebCore/inspector/front-end/Popup.js
deleted file mode 100644
index 9c8ef24..0000000
--- a/WebCore/inspector/front-end/Popup.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * This class provides a popup that can be shown relative to an anchor element
- * or at an arbitrary absolute position.
- * Points are Objects: {x: xValue, y: yValue}.
- * Rectangles are Objects: {x: xValue, y: yValue, width: widthValue, height: heightValue}.
- *
- * element is an optional unparented visible element (style.display != "none" AND style.visibility != "hidden").
- * If the element is absent/undefined, it must have been set with the element(x) setter before the show() method invocation.
- */
-WebInspector.Popup = function(element)
-{
- if (element)
- this.element = element;
- this._keyHandler = this._keyEventHandler.bind(this);
- this._mouseDownHandler = this._mouseDownEventHandler.bind(this);
- this._visible = false;
- this._autoHide = true;
-}
-
-WebInspector.Popup.prototype = {
- show: function()
- {
- if (this.visible)
- return;
- var ownerDocument = this._contentElement.ownerDocument;
- if (!ownerDocument)
- return;
-
- this._glasspaneElement = ownerDocument.createElement("div");
- this._glasspaneElement.className = "popup-glasspane";
- ownerDocument.body.appendChild(this._glasspaneElement);
-
- this._contentElement.positionAt(0, 0);
- this._contentElement.removeStyleClass("hidden");
- ownerDocument.body.appendChild(this._contentElement);
-
- this.positionElement();
- this._visible = true;
- ownerDocument.addEventListener("keydown", this._keyHandler, false);
- ownerDocument.addEventListener("mousedown", this._mouseDownHandler, false);
- },
-
- hide: function()
- {
- if (this.visible) {
- this._visible = false;
- this._contentElement.ownerDocument.removeEventListener("keydown", this._keyHandler, false);
- this._contentElement.ownerDocument.removeEventListener("mousedown", this._mouseDownHandler, false);
- this._glasspaneElement.parentElement.removeChild(this._glasspaneElement);
- this._contentElement.parentElement.removeChild(this._contentElement);
- }
- },
-
- get visible()
- {
- return this._visible;
- },
-
- set element(x)
- {
- this._checkNotVisible();
- this._contentElement = x;
- this._contentElement.addStyleClass("hidden");
- },
-
- get element()
- {
- return this._contentElement;
- },
-
- positionElement: function()
- {
- var element = this._contentElement;
- var anchorElement = this._anchorElement;
-
- var targetDocument = element.ownerDocument;
- var targetDocumentBody = targetDocument.body;
- var targetDocumentElement = targetDocument.documentElement;
- var clippingBox = {x: 0, y: 0, width: targetDocumentElement.clientWidth, height: targetDocumentElement.clientHeight};
- var parentElement = element.offsetParent || element.parentElement;
-
- var anchorPosition = {x: anchorElement.totalOffsetLeft, y: anchorElement.totalOffsetTop};
-
- // FIXME(apavlov@chromium.org): Translate anchorPosition to the element.ownerDocument frame when https://bugs.webkit.org/show_bug.cgi?id=28913 is fixed.
- var anchorBox = {x: anchorPosition.x, y: anchorPosition.y, width: anchorElement.offsetWidth, height: anchorElement.offsetHeight};
- var elementBox = {x: element.totalOffsetLeft, y: element.totalOffsetTop, width: element.offsetWidth, height: element.offsetHeight};
- var newElementPosition = {x: 0, y: 0};
-
- if (anchorBox.y - elementBox.height >= clippingBox.y)
- newElementPosition.y = anchorBox.y - elementBox.height;
- else
- newElementPosition.y = Math.min(anchorBox.y + anchorBox.height, Math.max(clippingBox.y, clippingBox.y + clippingBox.height - elementBox.height));
-
- if (anchorBox.x + elementBox.height <= clippingBox.x + clippingBox.height)
- newElementPosition.x = anchorBox.x;
- else
- newElementPosition.x = Math.max(clippingBox.x, clippingBox.x + clippingBox.height - elementBox.height);
- element.positionAt(newElementPosition.x, newElementPosition.y);
- },
-
- set anchor(x)
- {
- this._checkNotVisible();
- this._anchorElement = x;
- },
-
- get anchor()
- {
- return this._anchorElement;
- },
-
- set autoHide(x)
- {
- this._autoHide = x;
- },
-
- _checkNotVisible: function()
- {
- if (this.visible)
- throw new Error("The popup must not be visible.");
- },
-
- _keyEventHandler: function(event)
- {
- // Escape hides the popup.
- if (event.keyIdentifier == "U+001B") {
- this.hide();
- event.preventDefault();
- event.handled = true;
- }
- },
-
- _mouseDownEventHandler: function(event)
- {
- if (this._autoHide && event.originalTarget === this._glasspaneElement)
- this.hide();
- }
-}
diff --git a/WebCore/inspector/front-end/PropertiesSidebarPane.js b/WebCore/inspector/front-end/PropertiesSidebarPane.js
index 857d9a7..9df6448 100644
--- a/WebCore/inspector/front-end/PropertiesSidebarPane.js
+++ b/WebCore/inspector/front-end/PropertiesSidebarPane.js
@@ -48,12 +48,14 @@ WebInspector.PropertiesSidebarPane.prototype = {
body.removeChildren();
self.sections = [];
+ var path = [];
// Get array of prototype user-friendly names.
for (var i = 0; i < prototypes.length; ++i) {
- var prototype = new WebInspector.ObjectProxy(node.injectedScriptId, node.id, [], i);
+ var prototype = new WebInspector.ObjectProxy(node.injectedScriptId, node.id, path.slice());
var section = new WebInspector.ObjectPropertiesSection(prototype, prototypes[i], WebInspector.UIString("Prototype"));
self.sections.push(section);
body.appendChild(section.element);
+ path.push("__proto__");
}
};
InjectedScriptAccess.get(node.injectedScriptId).getPrototypes(node.id, callback);
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index 40a380c..19325bb 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -706,6 +706,11 @@ WebInspector.ResourcesPanel.prototype = {
get _resources()
{
return this.items;
+ },
+
+ searchIteratesOverViews: function()
+ {
+ return true;
}
}
diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js
index 394f86d..7710192 100644
--- a/WebCore/inspector/front-end/Section.js
+++ b/WebCore/inspector/front-end/Section.js
@@ -31,6 +31,7 @@ WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
+ this.element.sectionForTest = this;
this.headerElement = document.createElement("div");
this.headerElement.className = "header";
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 0f90700..799628e 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -45,6 +45,7 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, remove
this._addBreakpointDelegate = addBreakpointDelegate;
this._removeBreakpointDelegate = removeBreakpointDelegate;
+ this._popoverObjectGroup = "popover";
}
WebInspector.SourceFrame.prototype = {
@@ -53,6 +54,9 @@ WebInspector.SourceFrame.prototype = {
{
this._visible = visible;
this._createViewerIfNeeded();
+ if (!visible && this._textViewer)
+ this._textViewer.freeCachedElements();
+
},
get executionLine()
@@ -157,6 +161,8 @@ WebInspector.SourceFrame.prototype = {
element.addEventListener("keydown", this._keyDown.bind(this), true);
element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
element.addEventListener("mousedown", this._mouseDown.bind(this), true);
+ element.addEventListener("mousemove", this._mouseMove.bind(this), true);
+ element.addEventListener("scroll", this._scroll.bind(this), true);
this._parentElement.appendChild(element);
this._needsProgramCounterImage = true;
@@ -193,14 +199,7 @@ WebInspector.SourceFrame.prototype = {
var ranges = [];
// First do case-insensitive search.
- var regex = "";
- for (var i = 0; i < query.length; ++i) {
- var char = query.charAt(i);
- if (char === "]")
- char = "\\]";
- regex += "[" + char + "]";
- }
- var regexObject = new RegExp(regex, "i");
+ var regexObject = createSearchRegex(query);
this._collectRegexMatches(regexObject, ranges);
// Then try regex search if user knows the / / hint.
@@ -427,8 +426,15 @@ WebInspector.SourceFrame.prototype = {
contextMenu.show(event);
},
+ _scroll: function(event)
+ {
+ this._hidePopup();
+ },
+
_mouseDown: function(event)
{
+ this._resetHoverTimer();
+ this._hidePopup();
if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)
return;
if (event.target.className !== "webkit-line-number")
@@ -445,6 +451,164 @@ WebInspector.SourceFrame.prototype = {
event.preventDefault();
},
+ _mouseMove: function(event)
+ {
+ // Pretend that nothing has happened.
+ if (this._hoverElement === event.target)
+ return;
+
+ this._resetHoverTimer();
+
+ // User has 500ms to reach the popup.
+ if (this._popup) {
+ var self = this;
+ function doHide()
+ {
+ self._hidePopup();
+ delete self._hidePopupTimer;
+ }
+ this._hidePopupTimer = setTimeout(doHide, 500);
+ }
+
+ this._hoverElement = event.target;
+
+ // Now that cleanup routines are set up above, leave this in case we are not on a break.
+ if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
+ return;
+
+ // We are interested in identifiers and "this" keyword.
+ if (this._hoverElement.hasStyleClass("webkit-javascript-keyword")) {
+ if (this._hoverElement.textContent !== "this")
+ return;
+ } else if (!this._hoverElement.hasStyleClass("webkit-javascript-ident"))
+ return;
+
+ const toolTipDelay = 1500;
+ this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
+ },
+
+ _resetHoverTimer: function()
+ {
+ if (this._hoverTimer) {
+ clearTimeout(this._hoverTimer);
+ delete this._hoverTimer;
+ }
+ },
+
+ _hidePopup: function()
+ {
+ if (this._popup) {
+ this._popup.hide();
+ delete this._popup;
+ InspectorBackend.releaseWrapperObjectGroup(0, this._popoverObjectGroup);
+ }
+ },
+
+ _mouseHover: function(element)
+ {
+ delete this._hoverTimer;
+
+ if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
+ return;
+
+ var lineRow = element.enclosingNodeOrSelfWithNodeName("tr");
+ if (!lineRow)
+ return;
+
+ // Find text offset of the hovered node (iterate over text nodes until we hit ours).
+ var offset = 0;
+ var node = lineRow.lastChild.traverseNextTextNode(lineRow.lastChild);
+ while (node && node !== element.firstChild) {
+ offset += node.nodeValue.length;
+ node = node.traverseNextTextNode(lineRow.lastChild);
+ }
+
+ // Imagine that the line is "foo(A.B.C.D)" and we hit C. Following code goes through following steps:
+ // "foo(A.B.C" -> "C.B.A(oof" -> "C.B.A" -> "A.B.C" (target eval expression).
+ var lineNumber = lineRow.lineNumber;
+ var prefix = this._textModel.line(lineNumber).substring(0, offset + element.textContent.length);
+ var reversedPrefix = prefix.split("").reverse().join("");
+ var match = /[a-zA-Z\x80-\xFF\_$0-9.]+/.exec(reversedPrefix);
+ if (!match)
+ return;
+ var expression = match[0].split("").reverse().join("");
+ this._showPopup(element, expression);
+ },
+
+ _showPopup: function(element, expression)
+ {
+ function killHidePopupTimer()
+ {
+ if (this._hidePopupTimer) {
+ clearTimeout(this._hidePopupTimer);
+ delete this._hidePopupTimer;
+
+ // We know that we reached the popup, but we might have moved over other elements.
+ // Discard pending command.
+ this._resetHoverTimer();
+ }
+ }
+
+ function showTextPopup(text)
+ {
+ if (!WebInspector.panels.scripts.paused)
+ return;
+
+ var popupContentElement = document.createElement("span");
+ popupContentElement.className = "monospace";
+ popupContentElement.style.whiteSpace = "pre";
+ popupContentElement.textContent = text;
+ this._popup = new WebInspector.Popover(popupContentElement);
+ this._popup.show(element);
+ popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true);
+ }
+
+ function showObjectPopup(result)
+ {
+ if (!WebInspector.panels.scripts.paused)
+ return;
+
+ var popupContentElement = null;
+ if (result.type !== "object" && result.type !== "node" && result.type !== "array") {
+ popupContentElement = document.createElement("span");
+ popupContentElement.className = "monospace";
+ popupContentElement.style.whiteSpace = "pre";
+ popupContentElement.textContent = result.description;
+ this._popup = new WebInspector.Popover(popupContentElement);
+ this._popup.show(element);
+ } else {
+ var popupContentElement = document.createElement("div");
+
+ var titleElement = document.createElement("div");
+ titleElement.className = "source-frame-popover-title monospace";
+ titleElement.textContent = result.description;
+ popupContentElement.appendChild(titleElement);
+
+ var section = new WebInspector.ObjectPropertiesSection(result, "", null, false);
+ section.expanded = true;
+ section.element.addStyleClass("source-frame-popover-tree");
+ section.headerElement.addStyleClass("hidden");
+ popupContentElement.appendChild(section.element);
+
+ this._popup = new WebInspector.Popover(popupContentElement);
+ const popupWidth = 300;
+ const popupHeight = 250;
+ this._popup.show(element, popupWidth, popupHeight);
+ }
+ popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true);
+ }
+
+ function evaluateCallback(result, exception)
+ {
+ if (exception)
+ return;
+ if (!WebInspector.panels.scripts.paused)
+ return;
+ showObjectPopup.call(this, result);
+ }
+ WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, this._popoverObjectGroup, evaluateCallback.bind(this));
+ },
+
_editBreakpointCondition: function(breakpoint)
{
this._showBreakpointConditionPopup(breakpoint.line);
@@ -662,4 +826,5 @@ WebInspector.SourceFrame.prototype = {
}
}
+
WebInspector.SourceFrame.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/WebCore/inspector/front-end/SourceHTMLTokenizer.js b/WebCore/inspector/front-end/SourceHTMLTokenizer.js
index 8856ff5..3c9bd8c 100644
--- a/WebCore/inspector/front-end/SourceHTMLTokenizer.js
+++ b/WebCore/inspector/front-end/SourceHTMLTokenizer.js
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Tue Feb 2 00:44:38 2010 */
+/* Generated by re2c 0.13.5 on Mon Feb 15 19:30:21 2010 */
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
@@ -413,6 +413,12 @@ case 66:
++cursor;
this.setLexCondition(this._lexConditions.TAG);
{
+ if (this._parseCondition & this._parseConditions.SCRIPT) {
+ // Do not tokenize script tag contents, keep lexer state although processing "<".
+ this.setLexCondition(this._lexConditions.INITIAL);
+ this.tokenType = null;
+ return cursor;
+ }
this.tokenType = "html-tag";
this._parseCondition = this._parseConditions.SCRIPT;
this._setExpectingAttribute();
diff --git a/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js b/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js
index 89c535a..cfa8834 100644
--- a/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js
+++ b/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js
@@ -174,6 +174,12 @@ WebInspector.SourceHTMLTokenizer.prototype = {
<INITIAL> ScriptStart => TAG
{
+ if (this._parseCondition & this._parseConditions.SCRIPT) {
+ // Do not tokenize script tag contents, keep lexer state although processing "<".
+ this.setLexCondition(this._lexConditions.INITIAL);
+ this.tokenType = null;
+ return cursor;
+ }
this.tokenType = "html-tag";
this._parseCondition = this._parseConditions.SCRIPT;
this._setExpectingAttribute();
diff --git a/WebCore/inspector/front-end/SourceJavaScriptTokenizer.js b/WebCore/inspector/front-end/SourceJavaScriptTokenizer.js
index 816023f..75abeee 100644
--- a/WebCore/inspector/front-end/SourceJavaScriptTokenizer.js
+++ b/WebCore/inspector/front-end/SourceJavaScriptTokenizer.js
@@ -49,7 +49,7 @@ WebInspector.SourceJavaScriptTokenizer = function()
"null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for",
"instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if",
"this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger",
- "class", "enum", "export", "extends", "import", "super", "get", "set"
+ "class", "enum", "export", "extends", "import", "super", "get", "set", "with"
].keySet();
this._lexConditions = {
diff --git a/WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js b/WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js
index 8630ccb..053c82f 100644
--- a/WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js
+++ b/WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js
@@ -48,7 +48,7 @@ WebInspector.SourceJavaScriptTokenizer = function()
"null", "true", "false", "break", "case", "catch", "const", "default", "finally", "for",
"instanceof", "new", "var", "continue", "function", "return", "void", "delete", "if",
"this", "do", "while", "else", "in", "switch", "throw", "try", "typeof", "debugger",
- "class", "enum", "export", "extends", "import", "super", "get", "set"
+ "class", "enum", "export", "extends", "import", "super", "get", "set", "with"
].keySet();
this._lexConditions = {
diff --git a/WebCore/inspector/front-end/SourceTokenizer.js b/WebCore/inspector/front-end/SourceTokenizer.js
index 1192383..d498028 100644
--- a/WebCore/inspector/front-end/SourceTokenizer.js
+++ b/WebCore/inspector/front-end/SourceTokenizer.js
@@ -74,10 +74,11 @@ WebInspector.SourceTokenizer.prototype = {
WebInspector.SourceTokenizer.Registry = function() {
this._tokenizers = {};
this._tokenizerConstructors = {
- "text/css": WebInspector.SourceCSSTokenizer,
- "text/html": WebInspector.SourceHTMLTokenizer,
- "text/javascript": WebInspector.SourceJavaScriptTokenizer,
- "application/x-javascript": WebInspector.SourceJavaScriptTokenizer
+ "text/css": "SourceCSSTokenizer",
+ "text/html": "SourceHTMLTokenizer",
+ "text/javascript": "SourceJavaScriptTokenizer",
+ "application/javascript": "SourceJavaScriptTokenizer",
+ "application/x-javascript": "SourceJavaScriptTokenizer"
};
}
@@ -93,9 +94,10 @@ WebInspector.SourceTokenizer.Registry.prototype = {
{
if (!this._tokenizerConstructors[mimeType])
return null;
- var tokenizer = this._tokenizers[mimeType];
+ var tokenizerClass = this._tokenizerConstructors[mimeType];
+ var tokenizer = this._tokenizers[tokenizerClass];
if (!tokenizer) {
- tokenizer = new this._tokenizerConstructors[mimeType]();
+ tokenizer = new WebInspector[tokenizerClass]();
this._tokenizers[mimeType] = tokenizer;
}
return tokenizer;
diff --git a/WebCore/inspector/front-end/TextEditorHighlighter.js b/WebCore/inspector/front-end/TextEditorHighlighter.js
index c73e036..cf0b590 100644
--- a/WebCore/inspector/front-end/TextEditorHighlighter.js
+++ b/WebCore/inspector/front-end/TextEditorHighlighter.js
@@ -32,36 +32,8 @@
WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
{
this._textModel = textModel;
-
- this._styles = [];
-
- this._styles["css-comment"] = "rgb(0, 116, 0)";
- this._styles["css-params"] = "rgb(7, 144, 154)";
- this._styles["css-string"] = "rgb(7, 144, 154)";
- this._styles["css-keyword"] = "rgb(7, 144, 154)";
- this._styles["css-number"] = "rgb(50, 0, 255)";
- this._styles["css-property"] = "rgb(200, 0, 0)";
- this._styles["css-at-rule"] = "rgb(200, 0, 0)";
- this._styles["css-selector"] = "rgb(0, 0, 0)";
- this._styles["css-important"] = "rgb(200, 0, 180)";
-
- /* Keep this in sync with inspector.css and view-source.css */
- this._styles["html-tag"] = "rgb(136, 18, 128)";
- this._styles["html-attribute-name"] = "rgb(153, 69, 0)";
- this._styles["html-attribute-value"] = "rgb(26, 26, 166)";
- this._styles["html-comment"] = "rgb(35, 110, 37)";
- this._styles["html-doctype"] = "rgb(192, 192, 192)";
- this._styles["html-external-link"] = "#00e";
- this._styles["html-resource-link"] = "#00e";
-
- this._styles["javascript-comment"] = "rgb(0, 116, 0)";
- this._styles["javascript-string"] = "rgb(196, 26, 22)";
- this._styles["javascript-regexp"] = "rgb(196, 26, 22)";
- this._styles["javascript-keyword"] = "rgb(170, 13, 145)";
- this._styles["javascript-number"] = "rgb(28, 0, 207)";
-
- this.mimeType = "text/html";
- this._damageCallback = damageCallback;
+ this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
+ this._damageCallback = damageCallback;
}
WebInspector.TextEditorHighlighter.prototype = {
@@ -190,7 +162,7 @@ WebInspector.TextEditorHighlighter.prototype = {
var newColumn = this._tokenizer.nextToken(column);
var tokenType = this._tokenizer.tokenType;
if (tokenType)
- attributes[column] = { length: newColumn - column, tokenType: tokenType, style: this._styles[tokenType] };
+ attributes[column] = { length: newColumn - column, tokenType: tokenType };
column = newColumn;
} while (column < line.length)
}
diff --git a/WebCore/inspector/front-end/TextViewer.js b/WebCore/inspector/front-end/TextViewer.js
index 096464f..9be6a00 100644
--- a/WebCore/inspector/front-end/TextViewer.js
+++ b/WebCore/inspector/front-end/TextViewer.js
@@ -50,6 +50,9 @@ WebInspector.TextViewer = function(textModel, platform, url)
this._defaultChunkSize = 50;
this._paintCoalescingLevel = 0;
+
+ this.freeCachedElements();
+ this._buildChunks();
}
WebInspector.TextViewer.prototype = {
@@ -96,7 +99,10 @@ WebInspector.TextViewer.prototype = {
this._rangeToMark = range;
this.revealLine(range.startLine);
this._paintLines(range.startLine, range.startLine + 1);
+ if (this._markedRangeElement)
+ this._markedRangeElement.scrollIntoViewIfNeeded();
}
+ delete this._markedRangeElement;
},
highlightLine: function(lineNumber)
@@ -111,14 +117,20 @@ WebInspector.TextViewer.prototype = {
chunk.addDecoration("webkit-highlighted-line");
},
+ freeCachedElements: function()
+ {
+ this._cachedSpans = [];
+ this._cachedTextNodes = [];
+ this._cachedRows = [];
+ },
+
_buildChunks: function()
{
this._linesContainerElement.removeChildren();
- var paintLinesCallback = this._paintLines.bind(this);
this._textChunks = [];
for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
- var chunk = new WebInspector.TextChunk(this._textModel, i, i + this._defaultChunkSize, paintLinesCallback);
+ var chunk = new WebInspector.TextChunk(this, i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._linesContainerElement.appendChild(chunk.element);
}
@@ -140,23 +152,22 @@ WebInspector.TextViewer.prototype = {
oldChunk.expanded = false;
var insertIndex = oldChunk.chunkNumber + 1;
- var paintLinesCallback = this._paintLines.bind(this);
// Prefix chunk.
if (lineNumber > oldChunk.startLine) {
- var prefixChunk = new WebInspector.TextChunk(this._textModel, oldChunk.startLine, lineNumber, paintLinesCallback);
+ var prefixChunk = new WebInspector.TextChunk(this, oldChunk.startLine, lineNumber);
this._textChunks.splice(insertIndex++, 0, prefixChunk);
this._linesContainerElement.insertBefore(prefixChunk.element, oldChunk.element);
}
// Line chunk.
- var lineChunk = new WebInspector.TextChunk(this._textModel, lineNumber, lineNumber + 1, paintLinesCallback);
+ var lineChunk = new WebInspector.TextChunk(this, lineNumber, lineNumber + 1);
this._textChunks.splice(insertIndex++, 0, lineChunk);
this._linesContainerElement.insertBefore(lineChunk.element, oldChunk.element);
// Suffix chunk.
if (oldChunk.startLine + oldChunk.linesCount > lineNumber + 1) {
- var suffixChunk = new WebInspector.TextChunk(this._textModel, lineNumber + 1, oldChunk.startLine + oldChunk.linesCount, paintLinesCallback);
+ var suffixChunk = new WebInspector.TextChunk(this, lineNumber + 1, oldChunk.startLine + oldChunk.linesCount);
this._textChunks.splice(insertIndex, 0, suffixChunk);
this._linesContainerElement.insertBefore(suffixChunk.element, oldChunk.element);
}
@@ -185,7 +196,11 @@ WebInspector.TextViewer.prototype = {
_scroll: function()
{
- this._repaintAll();
+ var scrollTop = this.element.scrollTop;
+ setTimeout(function() {
+ if (scrollTop === this.element.scrollTop)
+ this._repaintAll();
+ }.bind(this), 50);
},
beginUpdates: function(enabled)
@@ -320,7 +335,7 @@ WebInspector.TextViewer.prototype = {
if (!highlighterState) {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
- this._markRange(element, line, this._rangeToMark.startColumn, this._rangeToMark.endColumn);
+ this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
return;
}
@@ -330,30 +345,53 @@ WebInspector.TextViewer.prototype = {
for (var j = 0; j < line.length;) {
if (j > 1000) {
// This line is too long - do not waste cycles on minified js highlighting.
+ plainTextStart = j;
break;
}
var attribute = highlighterState && highlighterState.attributes[j];
- if (!attribute || !attribute.style) {
+ if (!attribute || !attribute.tokenType) {
if (plainTextStart === -1)
plainTextStart = j;
j++;
} else {
if (plainTextStart !== -1) {
- element.appendChild(document.createTextNode(line.substring(plainTextStart, j)));
+ this._appendTextNode(element, line.substring(plainTextStart, j));
plainTextStart = -1;
}
- element.appendChild(this._createSpan(line.substring(j, j + attribute.length), attribute.tokenType));
+ this._appendSpan(element, line.substring(j, j + attribute.length), attribute.tokenType);
j += attribute.length;
}
}
if (plainTextStart !== -1)
- element.appendChild(document.createTextNode(line.substring(plainTextStart, line.length)));
+ this._appendTextNode(element, line.substring(plainTextStart, line.length));
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
- this._markRange(element, line, this._rangeToMark.startColumn, this._rangeToMark.endColumn);
+ this._markedRangeElement = highlightSearchResult(element, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
if (lineRow.decorationsElement)
element.appendChild(lineRow.decorationsElement);
},
+ _releaseLinesHighlight: function(fromLine, toLine)
+ {
+ for (var i = fromLine; i < toLine; ++i) {
+ var lineRow = this._textModel.getAttribute(i, "line-row");
+ if (!lineRow)
+ continue;
+ var element = lineRow.lastChild;
+ if ("spans" in element) {
+ var spans = element.spans;
+ for (var j = 0; j < spans.length; ++j)
+ this._cachedSpans.push(spans[j]);
+ delete element.spans;
+ }
+ if ("textNodes" in element) {
+ var textNodes = element.textNodes;
+ for (var j = 0; j < textNodes.length; ++j)
+ this._cachedTextNodes.push(textNodes[j]);
+ delete element.textNodes;
+ }
+ }
+ },
+
_getSelection: function()
{
var selection = window.getSelection();
@@ -447,15 +485,33 @@ WebInspector.TextViewer.prototype = {
return { line: lineRow.lineNumber, column: column };
},
- _createSpan: function(content, className)
+ _appendSpan: function(element, content, className)
{
- if (className === "html-resource-link" || className === "html-external-link")
- return this._createLink(content, className === "html-external-link");
+ if (className === "html-resource-link" || className === "html-external-link") {
+ element.appendChild(this._createLink(content, className === "html-external-link"));
+ return;
+ }
- var span = document.createElement("span");
+ var span = this._cachedSpans.pop() || document.createElement("span");
span.className = "webkit-" + className;
- span.appendChild(document.createTextNode(content));
- return span;
+ span.textContent = content;
+ element.appendChild(span);
+ if (!("spans" in element))
+ element.spans = [];
+ element.spans.push(span);
+ },
+
+ _appendTextNode: function(element, text)
+ {
+ var textNode = this._cachedTextNodes.pop();
+ if (textNode) {
+ textNode.nodeValue = text;
+ } else
+ textNode = document.createTextNode(text);
+ element.appendChild(textNode);
+ if (!("textNodes" in element))
+ element.textNodes = [];
+ element.textNodes.push(textNode);
},
_createLink: function(content, isExternal)
@@ -484,58 +540,19 @@ WebInspector.TextViewer.prototype = {
return WebInspector.completeURL(this._url, hrefValue);
},
- _markRange: function(element, lineText, startOffset, endOffset)
- {
- var markNode = document.createElement("span");
- markNode.className = "webkit-markup";
- markNode.textContent = lineText.substring(startOffset, endOffset);
-
- var markLength = endOffset - startOffset;
- var boundary = element.rangeBoundaryForOffset(startOffset);
- var textNode = boundary.container;
- var text = textNode.textContent;
-
- if (boundary.offset + markLength < text.length) {
- // Selection belong to a single split mode.
- textNode.textContent = text.substring(boundary.offset + markLength);
- textNode.parentElement.insertBefore(markNode, textNode);
- var prefixNode = document.createTextNode(text.substring(0, boundary.offset));
- textNode.parentElement.insertBefore(prefixNode, markNode);
- return;
- }
-
- var parentElement = textNode.parentElement;
- var anchorElement = textNode.nextSibling;
-
- markLength -= text.length - boundary.offset;
- textNode.textContent = text.substring(0, boundary.offset);
- textNode = textNode.traverseNextTextNode(element);
-
- while (textNode) {
- var text = textNode.textContent;
- if (markLength < text.length) {
- textNode.textContent = text.substring(markLength);
- break;
- }
-
- markLength -= text.length;
- textNode.textContent = "";
- textNode = textNode.traverseNextTextNode(element);
- }
-
- parentElement.insertBefore(markNode, anchorElement);
- },
-
resize: function()
{
this._repaintAll();
}
}
-WebInspector.TextChunk = function(textModel, startLine, endLine, paintLinesCallback)
+var cachedSpans = [];
+
+WebInspector.TextChunk = function(textViewer, startLine, endLine)
{
+ this._textViewer = textViewer;
this.element = document.createElement("tr");
- this._textModel = textModel;
+ this._textModel = textViewer._textModel;
this.element.chunk = this;
this.element.lineNumber = startLine;
@@ -545,7 +562,6 @@ WebInspector.TextChunk = function(textModel, startLine, endLine, paintLinesCallb
this._lineNumberElement = document.createElement("td");
this._lineNumberElement.className = "webkit-line-number";
- this._lineNumberElement.textContent = this._lineNumberText(this.startLine);
this.element.appendChild(this._lineNumberElement);
this._lineContentElement = document.createElement("td");
@@ -554,11 +570,14 @@ WebInspector.TextChunk = function(textModel, startLine, endLine, paintLinesCallb
this._expanded = false;
+ var lineNumbers = [];
var lines = [];
- for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
+ for (var i = startLine; i < endLine; ++i) {
+ lineNumbers.push(i + 1);
lines.push(this._textModel.line(i));
+ }
+ this._lineNumberElement.textContent = lineNumbers.join("\n");
this._lineContentElement.textContent = lines.join("\n");
- this._paintLines = paintLinesCallback;
}
WebInspector.TextChunk.prototype = {
@@ -601,40 +620,30 @@ WebInspector.TextChunk.prototype = {
if (this.linesCount === 1) {
this._textModel.setAttribute(this.startLine, "line-row", this.element);
if (expanded)
- this._paintLines(this.startLine, this.startLine + 1);
+ this._textViewer._paintLines(this.startLine, this.startLine + 1);
return;
}
if (expanded) {
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
- var lineRow = document.createElement("tr");
- lineRow.lineNumber = i;
-
- var lineNumberElement = document.createElement("td");
- lineNumberElement.className = "webkit-line-number";
- lineNumberElement.textContent = this._lineNumberText(i);
- lineRow.appendChild(lineNumberElement);
-
- var lineContentElement = document.createElement("td");
- lineContentElement.className = "webkit-line-content";
- lineContentElement.textContent = this._textModel.line(i);
- lineRow.appendChild(lineContentElement);
-
+ var lineRow = this._createRow(i);
this._textModel.setAttribute(i, "line-row", lineRow);
parentElement.insertBefore(lineRow, this.element);
}
parentElement.removeChild(this.element);
- this._paintLines(this.startLine, this.startLine + this.linesCount);
+ this._textViewer._paintLines(this.startLine, this.startLine + this.linesCount);
} else {
var firstLine = this._textModel.getAttribute(this.startLine, "line-row");
var parentElement = firstLine.parentElement;
+ this._textViewer._releaseLinesHighlight(this.startLine, this.startLine + this.linesCount);
parentElement.insertBefore(this.element, firstLine);
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._textModel.getAttribute(i, "line-row");
this._textModel.removeAttribute(i, "line-row");
+ this._textViewer._cachedRows.push(lineRow);
parentElement.removeChild(lineRow);
}
}
@@ -652,15 +661,28 @@ WebInspector.TextChunk.prototype = {
return result;
},
- _lineNumberText: function(lineNumber)
+ _createRow: function(lineNumber)
{
- var totalDigits = Math.ceil(Math.log(this._textModel.linesCount + 1) / Math.log(10));
- var digits = Math.ceil(Math.log(lineNumber + 2) / Math.log(10));
+ var cachedRows = this._textViewer._cachedRows;
+ if (cachedRows.length) {
+ var lineRow = cachedRows[cachedRows.length - 1];
+ cachedRows.length--;
+ var lineNumberElement = lineRow.firstChild;
+ var lineContentElement = lineRow.lastChild;
+ } else {
+ var lineRow = document.createElement("tr");
- var text = "";
- for (var i = digits; i < totalDigits; ++i)
- text += " ";
- text += lineNumber + 1;
- return text;
+ var lineNumberElement = document.createElement("td");
+ lineNumberElement.className = "webkit-line-number";
+ lineRow.appendChild(lineNumberElement);
+
+ var lineContentElement = document.createElement("td");
+ lineContentElement.className = "webkit-line-content";
+ lineRow.appendChild(lineContentElement);
+ }
+ lineRow.lineNumber = lineNumber;
+ lineNumberElement.textContent = lineNumber + 1;
+ lineContentElement.textContent = this._textModel.line(lineNumber);
+ return lineRow;
}
}
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index efa2bfc..73309d1 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -45,7 +45,7 @@
<file>Panel.js</file>
<file>PanelEnablerView.js</file>
<file>Placard.js</file>
- <file>Popup.js</file>
+ <file>Popover.js</file>
<file>ProfileDataGridTree.js</file>
<file>ProfilesPanel.js</file>
<file>ProfileView.js</file>
@@ -91,6 +91,7 @@
<file>audits.css</file>
<file>inspector.css</file>
<file>inspectorSyntaxHighlight.css</file>
+ <file>popover.css</file>
<file>textViewer.css</file>
<file>Images/back.png</file>
<file>Images/checker.png</file>
@@ -125,6 +126,7 @@
<file>Images/excludeButtonGlyph.png</file>
<file>Images/focusButtonGlyph.png</file>
<file>Images/forward.png</file>
+ <file>Images/gearButtonGlyph.png</file>
<file>Images/glossyHeader.png</file>
<file>Images/glossyHeaderPressed.png</file>
<file>Images/glossyHeaderSelected.png</file>
@@ -142,6 +144,8 @@
<file>Images/paneSettingsButtons.png</file>
<file>Images/pauseOnExceptionButtonGlyph.png</file>
<file>Images/percentButtonGlyph.png</file>
+ <file>Images/popoverArrows.png</file>
+ <file>Images/popoverBackground.png</file>
<file>Images/profileGroupIcon.png</file>
<file>Images/profileIcon.png</file>
<file>Images/profilesIcon.png</file>
@@ -185,6 +189,12 @@
<file>Images/statusbarResizerVertical.png</file>
<file>Images/storageIcon.png</file>
<file>Images/successGreenDot.png</file>
+ <file>Images/thumbActiveHoriz.png</file>
+ <file>Images/thumbActiveVert.png</file>
+ <file>Images/thumbHoriz.png</file>
+ <file>Images/thumbVert.png</file>
+ <file>Images/thumbHoverHoriz.png</file>
+ <file>Images/thumbHoverVert.png</file>
<file>Images/timelineBarBlue.png</file>
<file>Images/timelineBarGray.png</file>
<file>Images/timelineBarGreen.png</file>
@@ -210,6 +220,8 @@
<file>Images/timelinePillRed.png</file>
<file>Images/timelinePillYellow.png</file>
<file>Images/toolbarItemSelected.png</file>
+ <file>Images/trackHoriz.png</file>
+ <file>Images/trackVert.png</file>
<file>Images/treeDownTriangleBlack.png</file>
<file>Images/treeDownTriangleWhite.png</file>
<file>Images/treeRightTriangleBlack.png</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 53f1e4b..76b31fc 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -29,8 +29,11 @@
body {
cursor: default;
- height: 100%;
- width: 100%;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
overflow: hidden;
font-family: Lucida Grande, sans-serif;
font-size: 10px;
@@ -1348,7 +1351,6 @@ body.inactive .placard.selected {
margin: 0;
padding: 2px 6px 3px;
list-style: none;
- background-color: white;
min-height: 18px;
}
@@ -1577,6 +1579,10 @@ li.editing .swatch, li.editing .enabled-button, li.editing-sub-part .delete-but
color: rgb(100, 100, 100);
}
+.section .properties .value.error {
+ color: red;
+}
+
.section .properties .number, .event-properties .number {
color: blue;
}
@@ -2245,7 +2251,7 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
margin: 0 0 5px 20px;
}
-.panel-enabler-view button:not(.status-bar-item), .pane button {
+.panel-enabler-view button:not(.status-bar-item), .pane button, button.show-all-nodes {
color: rgb(6, 6, 6);
background-color: transparent;
border: 1px solid rgb(165, 165, 165);
@@ -2262,6 +2268,13 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
height: 24px;
}
+button.show-all-nodes {
+ font-size: 13px;
+ margin: 0;
+ padding: 0 20px;
+ height: 20px;
+}
+
.panel-enabler-view.welcome {
z-index: auto;
}
@@ -2293,12 +2306,12 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
padding: 2px 9px;
}
-.panel-enabler-view button:active:not(.status-bar-item), .pane button:active {
+.panel-enabler-view button:active:not(.status-bar-item), .pane button:active, button.show-all-nodes:active {
background-color: rgb(215, 215, 215);
background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
}
-body.inactive .panel-enabler-view button:not(.status-bar-item), .panel-enabler-view button:disabled:not(.status-bar-item), body.inactive .pane button, .pane button:disabled {
+body.inactive .panel-enabler-view button:not(.status-bar-item), .panel-enabler-view button:disabled:not(.status-bar-item), body.inactive .pane button, .pane button:disabled, body.inactive button.show-all-nodes {
color: rgb(130, 130, 130);
border-color: rgb(212, 212, 212);
background-color: rgb(239, 239, 239);
@@ -3801,3 +3814,21 @@ ol.breakpoint-list {
outline: none !important;
-webkit-user-modify: read-write;
}
+
+.source-frame-popover-title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ font-weight: bold;
+ padding-left: 18px;
+}
+
+.source-frame-popover-tree {
+ border-top: 1px solid rgb(190, 190, 190);
+ overflow: auto;
+ position: absolute;
+ top: 15px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 4ddd10e..85633b5 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -30,9 +30,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="audits.css">
- <link rel="stylesheet" type="text/css" href="textViewer.css">
<link rel="stylesheet" type="text/css" href="inspector.css">
<link rel="stylesheet" type="text/css" href="inspectorSyntaxHighlight.css">
+ <link rel="stylesheet" type="text/css" href="popover.css">
+ <link rel="stylesheet" type="text/css" href="textViewer.css">
<script type="text/javascript" src="utilities.js"></script>
<script type="text/javascript" src="treeoutline.js"></script>
<script type="text/javascript" src="inspector.js"></script>
@@ -43,7 +44,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="ContextMenu.js"></script>
<script type="text/javascript" src="KeyboardShortcut.js"></script>
<script type="text/javascript" src="TextPrompt.js"></script>
- <script type="text/javascript" src="Popup.js"></script>
+ <script type="text/javascript" src="Popover.js"></script>
<script type="text/javascript" src="Placard.js"></script>
<script type="text/javascript" src="View.js"></script>
<script type="text/javascript" src="Callback.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 77d3f42..8bcdf63 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -686,9 +686,7 @@ WebInspector.documentKeyDown = function(event)
var isFindKey = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey;
if (isFindKey) {
- var searchField = document.getElementById("search");
- searchField.focus();
- searchField.select();
+ WebInspector.focusSearchField();
event.preventDefault();
}
@@ -878,6 +876,13 @@ WebInspector.updateSearchLabel = function()
}
}
+WebInspector.focusSearchField = function()
+{
+ var searchField = document.getElementById("search");
+ searchField.focus();
+ searchField.select();
+}
+
WebInspector.toggleAttach = function()
{
this.attached = !this.attached;
@@ -1337,7 +1342,7 @@ WebInspector.log = function(message)
WebInspector.log.repeatCount = repeatCount;
// ConsoleMessage expects a proxy object
- message = new WebInspector.ObjectProxy(null, null, [], 0, message, false);
+ message = new WebInspector.ObjectProxy(null, null, [], message, false);
// post the message
var msg = new WebInspector.ConsoleMessage(
diff --git a/WebCore/inspector/front-end/inspectorSyntaxHighlight.css b/WebCore/inspector/front-end/inspectorSyntaxHighlight.css
index 1292f00..0965a5c 100644
--- a/WebCore/inspector/front-end/inspectorSyntaxHighlight.css
+++ b/WebCore/inspector/front-end/inspectorSyntaxHighlight.css
@@ -26,29 +26,29 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- .webkit-css-comment {
- color: rgb(0, 116, 0);
- }
+.webkit-css-comment {
+ color: rgb(0, 116, 0);
+}
- .webkit-css-url, .webkit-css-color, .webkit-css-string, .webkit-css-keyword {
- color: rgb(7, 144, 154);
+.webkit-css-url, .webkit-css-color, .webkit-css-string, .webkit-css-keyword {
+ color: rgb(7, 144, 154);
}
- .webkit-css-number {
- color: rgb(50, 0, 255);
- }
+.webkit-css-number {
+ color: rgb(50, 0, 255);
+}
- .webkit-css-property, .webkit-css-at-rule {
- color: rgb(200, 0, 0);
- }
+.webkit-css-property, .webkit-css-at-rule {
+ color: rgb(200, 0, 0);
+}
- .webkit-css-selector {
- rgb(0, 0, 0);
- }
+.webkit-css-selector {
+ color: black;
+}
- .webkit-css-important {
- color: rgb(200, 0, 180);
- }
+.webkit-css-important {
+ color: rgb(200, 0, 180);
+}
.webkit-javascript-comment {
color: rgb(0, 116, 0);
@@ -66,6 +66,10 @@
color: rgb(196, 26, 22);
}
+.webkit-javascript-ident {
+ color: black;
+}
+
.webkit-html-comment {
/* Keep this in sync with view-source.css (.webkit-html-comment) */
color: rgb(35, 110, 37);
diff --git a/WebCore/inspector/front-end/popover.css b/WebCore/inspector/front-end/popover.css
new file mode 100644
index 0000000..ae6f610
--- /dev/null
+++ b/WebCore/inspector/front-end/popover.css
@@ -0,0 +1,200 @@
+.popover {
+ position: absolute;
+ -webkit-border-image: url(Images/popoverBackground.png) 25 25 25 25;
+ border-width: 25px;
+ z-index: 100;
+ pointer-events: none;
+}
+
+.popover .content {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ pointer-events: auto;
+ overflow: auto;
+}
+
+.popover .arrow {
+ position: absolute;
+ background-image: url(Images/popoverArrows.png);
+ width: 19px;
+ height: 19px;
+ margin-left: 15px;
+ margin-top: -25px;
+ top: 0;
+ left: 0;
+}
+
+.popover.top-left-arrow .arrow {
+ /* The default is top-left, no styles needed. */
+}
+
+.popover.top-right-arrow .arrow {
+ right: 25px;
+ left: auto;
+}
+
+.popover.bottom-left-arrow .arrow {
+ top: auto;
+ bottom: 0;
+ margin-top: 0;
+ margin-bottom: -25px;
+ background-position: 0 -19px;
+}
+
+.popover.bottom-right-arrow .arrow {
+ right: 15px;
+ left: auto;
+ top: auto;
+ bottom: 0;
+ margin-top: 0;
+ margin-bottom: -25px;
+ background-position: 0 -19px;
+}
+
+.popover.left-top-arrow .arrow {
+ top: 0;
+ margin-top: 15px;
+ margin-left: -25px;
+ background-position: 0 -38px;
+}
+
+.popover.left-bottom-arrow .arrow {
+ top: auto;
+ bottom: 0;
+ margin-bottom: 15px;
+ margin-left: -25px;
+ background-position: 0 -38px;
+}
+
+.popover.right-top-arrow .arrow {
+ right: 0;
+ left: auto;
+ top: 0;
+ margin-top: 15px;
+ margin-right: -25px;
+ background-position: 0 -57px;
+}
+
+.popover.right-bottom-arrow .arrow {
+ right: 0;
+ left: auto;
+ top: auto;
+ bottom: 0;
+ margin-bottom: 15px;
+ margin-right: -25px;
+ background-position: 0 -57px;
+}
+
+.popover ::-webkit-scrollbar {
+ width: 11px;
+ height: 11px;
+}
+
+.popover ::-webkit-scrollbar-corner {
+ display: none;
+}
+
+.popover ::-webkit-resizer {
+ display: none;
+}
+
+/* Horizontal Scrollbar Styles */
+
+.popover ::-webkit-scrollbar:horizontal:corner-present {
+ border-right-width: 0;
+}
+
+.popover ::-webkit-scrollbar-thumb:horizontal {
+ -webkit-border-image: url(Images/thumbHoriz.png) 0 11 0 11;
+ border-color: transparent;
+ border-width: 0 11px;
+ min-width: 20px;
+}
+
+.popover ::-webkit-scrollbar-thumb:horizontal:hover {
+ -webkit-border-image: url(Images/thumbHoverHoriz.png) 0 11 0 11;
+}
+
+.popover ::-webkit-scrollbar-thumb:horizontal:active {
+ -webkit-border-image: url(Images/thumbActiveHoriz.png) 0 11 0 11;
+}
+
+.popover ::-webkit-scrollbar-track-piece:horizontal:start {
+ margin-left: 5px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:horizontal:end {
+ margin-right: 5px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:horizontal:end:corner-present {
+ margin-right: 4px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:horizontal:decrement {
+ -webkit-border-image: url(Images/trackHoriz.png) 0 11 0 11;
+ border-color: transparent;
+ border-width: 0 0 0 11px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:horizontal:increment {
+ -webkit-border-image: url(Images/trackHoriz.png) 0 11 0 11;
+ border-color: transparent;
+ border-width: 0 11px 0 0;
+}
+
+/* Vertical Scrollbar Styles */
+
+
+.popover ::-webkit-scrollbar:vertical:corner-present {
+ border-bottom-width: 0;
+}
+
+.popover ::-webkit-scrollbar-thumb:vertical {
+ -webkit-border-image: url(Images/thumbVert.png) 11 0 11 0;
+ border-color: transparent;
+ border-width: 11px 0;
+ min-height: 20px;
+}
+
+.popover ::-webkit-scrollbar-thumb:vertical:hover {
+ -webkit-border-image: url(Images/thumbHoverVert.png) 11 0 11 0;
+}
+
+.popover ::-webkit-scrollbar-thumb:vertical:active {
+ -webkit-border-image: url(Images/thumbActiveVert.png) 11 0 11 0;
+}
+
+
+.popover ::-webkit-scrollbar-track-piece:vertical:start {
+ margin-top: 5px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:vertical:end {
+ margin-bottom: 5px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:vertical:end:corner-present {
+ margin-bottom: 4px;
+}
+
+.popover ::-webkit-scrollbar-track-piece:vertical:decrement {
+ -webkit-border-image: url(Images/trackVert.png) 11 0 11 0;
+ border-color: transparent;
+ border-width: 11px 0 0 0;
+}
+
+.popover ::-webkit-scrollbar-track-piece:vertical:increment {
+ -webkit-border-image: url(Images/trackVert.png) 11 0 11 0;
+ border-color: transparent;
+ border-width: 0 0 11px 0;
+}
+
+/* Forced Scrollbar Mode Styles */
+
+.popover ::-webkit-scrollbar-button {
+ display: none;
+}
diff --git a/WebCore/inspector/front-end/textViewer.css b/WebCore/inspector/front-end/textViewer.css
index af079bc..1447dfd 100644
--- a/WebCore/inspector/front-end/textViewer.css
+++ b/WebCore/inspector/front-end/textViewer.css
@@ -4,14 +4,13 @@
left:0;
right:0;
bottom:0;
- white-space: pre-wrap;
+ white-space: pre;
overflow: auto;
}
.text-editor-lines {
border: 0;
width: 100%;
- vertical-align: baseline;
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
-webkit-user-select: text;
@@ -63,21 +62,20 @@
.webkit-line-number {
color: rgb(128, 128, 128);
text-align: right;
- white-space: pre;
word-break: normal;
-webkit-user-select: none;
background-color: rgb(240, 240, 240);
border-right: 1px solid rgb(187, 187, 187) !important;
padding-left: 2px;
padding-right: 2px;
- vertical-align: top;
background-repeat: no-repeat;
background-position: right 1px;
+ vertical-align: top;
}
.webkit-line-content {
- white-space: pre-wrap;
padding-left: 2px;
+ vertical-align: top;
}
.webkit-execution-line .webkit-line-number {
@@ -130,13 +128,14 @@
outline: 1px solid rgb(64, 115, 244);
}
-.webkit-markup {
+.webkit-search-result {
-webkit-border-radius: 4px;
- padding: 2px 1px 2px 3px;
- margin-left: -4px;
- margin-top: -2px;
+ padding: 2px 2px 2px 3px;
+ margin: -2px -2px -2px -3px;
+ opacity: 0.8;
-webkit-box-shadow: rgba(0, 0, 0, .5) 3px 3px 4px;
background-color: rgb(241, 234, 0);
+ color: black;
}
.webkit-highlighted-line .webkit-line-content {
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 60d3b45..f30ab9f 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -271,7 +271,7 @@ Element.prototype.__defineGetter__("totalOffsetLeft", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
- total += element.offsetLeft;
+ total += element.offsetLeft + (this !== element ? element.clientLeft : 0);
return total;
});
@@ -279,7 +279,7 @@ Element.prototype.__defineGetter__("totalOffsetTop", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
- total += element.offsetTop;
+ total += element.offsetTop + (this !== element ? element.clientTop : 0);
return total;
});
@@ -850,3 +850,60 @@ function isEnterKey(event) {
// Check if in IME.
return event.keyCode !== 229 && event.keyIdentifier === "Enter";
}
+
+
+function highlightSearchResult(element, offset, length)
+{
+ var lineText = element.textContent;
+ var endOffset = offset + length;
+ var highlightNode = document.createElement("span");
+ highlightNode.className = "webkit-search-result";
+ highlightNode.textContent = lineText.substring(offset, endOffset);
+
+ var boundary = element.rangeBoundaryForOffset(offset);
+ var textNode = boundary.container;
+ var text = textNode.textContent;
+
+ if (boundary.offset + length < text.length) {
+ // Selection belong to a single split mode.
+ textNode.textContent = text.substring(boundary.offset + length);
+ textNode.parentElement.insertBefore(highlightNode, textNode);
+ var prefixNode = document.createTextNode(text.substring(0, boundary.offset));
+ textNode.parentElement.insertBefore(prefixNode, highlightNode);
+ return highlightNode;
+ }
+
+ var parentElement = textNode.parentElement;
+ var anchorElement = textNode.nextSibling;
+
+ length -= text.length - boundary.offset;
+ textNode.textContent = text.substring(0, boundary.offset);
+ textNode = textNode.traverseNextTextNode(element);
+
+ while (textNode) {
+ var text = textNode.textContent;
+ if (length < text.length) {
+ textNode.textContent = text.substring(length);
+ break;
+ }
+
+ length -= text.length;
+ textNode.textContent = "";
+ textNode = textNode.traverseNextTextNode(element);
+ }
+
+ parentElement.insertBefore(highlightNode, anchorElement);
+ return highlightNode;
+}
+
+function createSearchRegex(query)
+{
+ var regex = "";
+ for (var i = 0; i < query.length; ++i) {
+ var char = query.charAt(i);
+ if (char === "]")
+ char = "\\]";
+ regex += "[" + char + "]";
+ }
+ return new RegExp(regex, "i");
+}