summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-11 17:01:47 +0100
committerBen Murdoch <benm@google.com>2009-08-11 18:21:02 +0100
commit0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch)
tree2943df35f62d885c89d01063cc528dd73b480fea /WebCore/inspector/front-end
parent7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff)
downloadexternal_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2
Merge in WebKit r47029.
Diffstat (limited to 'WebCore/inspector/front-end')
-rw-r--r--WebCore/inspector/front-end/Breakpoint.js23
-rw-r--r--WebCore/inspector/front-end/BreakpointsSidebarPane.js94
-rw-r--r--WebCore/inspector/front-end/CallStackSidebarPane.js57
-rw-r--r--WebCore/inspector/front-end/Callback.js56
-rw-r--r--WebCore/inspector/front-end/ChangesView.js80
-rw-r--r--WebCore/inspector/front-end/Color.js671
-rw-r--r--WebCore/inspector/front-end/ConsoleView.js (renamed from WebCore/inspector/front-end/Console.js)380
-rw-r--r--WebCore/inspector/front-end/DOMAgent.js724
-rw-r--r--WebCore/inspector/front-end/DOMStorageDataGrid.js92
-rw-r--r--WebCore/inspector/front-end/DOMStorageItemsView.js7
-rw-r--r--WebCore/inspector/front-end/DataGrid.js153
-rw-r--r--WebCore/inspector/front-end/DatabaseQueryView.js6
-rw-r--r--WebCore/inspector/front-end/DatabasesPanel.js86
-rw-r--r--WebCore/inspector/front-end/Drawer.js196
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js126
-rw-r--r--WebCore/inspector/front-end/ElementsTreeOutline.js146
-rw-r--r--WebCore/inspector/front-end/Images/clearConsoleButtonGlyph.pngbin0 -> 396 bytes
-rw-r--r--WebCore/inspector/front-end/Images/clearConsoleButtons.pngbin5224 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/consoleButtonGlyph.pngbin0 -> 183 bytes
-rw-r--r--WebCore/inspector/front-end/Images/consoleButtons.pngbin5197 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/dockButtonGlyph.pngbin0 -> 164 bytes
-rw-r--r--WebCore/inspector/front-end/Images/dockButtons.pngbin1274 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/enableButtons.pngbin5543 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/enableOutlineButtonGlyph.pngbin0 -> 363 bytes
-rw-r--r--WebCore/inspector/front-end/Images/enableSolidButtonGlyph.pngbin0 -> 302 bytes
-rw-r--r--WebCore/inspector/front-end/Images/excludeButtonGlyph.pngbin0 -> 212 bytes
-rw-r--r--WebCore/inspector/front-end/Images/excludeButtons.pngbin4562 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/focusButtonGlyph.pngbin0 -> 285 bytes
-rw-r--r--WebCore/inspector/front-end/Images/focusButtons.pngbin4919 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/largerResourcesButtonGlyph.pngbin0 -> 192 bytes
-rw-r--r--WebCore/inspector/front-end/Images/largerResourcesButtons.pngbin1596 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/nodeSearchButtonGlyph.pngbin0 -> 283 bytes
-rw-r--r--WebCore/inspector/front-end/Images/nodeSearchButtons.pngbin5708 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/pauseOnExceptionButtonGlyph.pngbin0 -> 331 bytes
-rw-r--r--WebCore/inspector/front-end/Images/pauseOnExceptionButtons.pngbin2305 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/percentButtonGlyph.pngbin0 -> 357 bytes
-rw-r--r--WebCore/inspector/front-end/Images/percentButtons.pngbin5771 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/recordButtonGlyph.pngbin0 -> 213 bytes
-rw-r--r--WebCore/inspector/front-end/Images/recordButtons.pngbin5716 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/recordToggledButtonGlyph.pngbin0 -> 510 bytes
-rw-r--r--WebCore/inspector/front-end/Images/reloadButtonGlyph.pngbin0 -> 267 bytes
-rw-r--r--WebCore/inspector/front-end/Images/reloadButtons.pngbin4544 -> 0 bytes
-rw-r--r--WebCore/inspector/front-end/Images/resourcesSilhouette.pngbin0 -> 42925 bytes
-rw-r--r--WebCore/inspector/front-end/Images/undockButtonGlyph.pngbin0 -> 179 bytes
-rw-r--r--WebCore/inspector/front-end/InjectedScript.js516
-rw-r--r--WebCore/inspector/front-end/KeyboardShortcut.js108
-rw-r--r--WebCore/inspector/front-end/MetricsSidebarPane.js38
-rw-r--r--WebCore/inspector/front-end/ObjectPropertiesSection.js202
-rw-r--r--WebCore/inspector/front-end/ObjectProxy.js45
-rw-r--r--WebCore/inspector/front-end/Panel.js12
-rw-r--r--WebCore/inspector/front-end/ProfileView.js86
-rw-r--r--WebCore/inspector/front-end/ProfilesPanel.js21
-rw-r--r--WebCore/inspector/front-end/PropertiesSidebarPane.js20
-rw-r--r--WebCore/inspector/front-end/Resource.js10
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js71
-rw-r--r--WebCore/inspector/front-end/ScopeChainSidebarPane.js10
-rw-r--r--WebCore/inspector/front-end/Script.js13
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js108
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js41
-rw-r--r--WebCore/inspector/front-end/SourceView.js7
-rw-r--r--WebCore/inspector/front-end/StylesSidebarPane.js600
-rw-r--r--WebCore/inspector/front-end/TextPrompt.js17
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc38
-rw-r--r--WebCore/inspector/front-end/inspector.css381
-rw-r--r--WebCore/inspector/front-end/inspector.html20
-rw-r--r--WebCore/inspector/front-end/inspector.js174
-rw-r--r--WebCore/inspector/front-end/utilities.js117
67 files changed, 4658 insertions, 894 deletions
diff --git a/WebCore/inspector/front-end/Breakpoint.js b/WebCore/inspector/front-end/Breakpoint.js
index 8611cf5..347df60 100644
--- a/WebCore/inspector/front-end/Breakpoint.js
+++ b/WebCore/inspector/front-end/Breakpoint.js
@@ -29,6 +29,7 @@ WebInspector.Breakpoint = function(url, line, sourceID)
this.line = line;
this.sourceID = sourceID;
this._enabled = true;
+ this._sourceText = "";
}
WebInspector.Breakpoint.prototype = {
@@ -48,6 +49,28 @@ WebInspector.Breakpoint.prototype = {
this.dispatchEventToListeners("enabled");
else
this.dispatchEventToListeners("disabled");
+ },
+
+ get sourceText()
+ {
+ return this._sourceText;
+ },
+
+ set sourceText(text)
+ {
+ this._sourceText = text;
+ this.dispatchEventToListeners("text-changed");
+ },
+
+ get label()
+ {
+ var displayName = (this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)"));
+ return displayName + ":" + this.line;
+ },
+
+ get id()
+ {
+ return this.sourceID + ":" + this.line;
}
}
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 2b8f3cd..14f8c06 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -27,7 +27,10 @@ WebInspector.BreakpointsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
- this.breakpoints = [];
+ this.breakpoints = {};
+
+ this.listElement = document.createElement("ol");
+ this.listElement.className = "breakpoint-list";
this.emptyElement = document.createElement("div");
this.emptyElement.className = "info";
@@ -39,11 +42,21 @@ WebInspector.BreakpointsSidebarPane = function()
WebInspector.BreakpointsSidebarPane.prototype = {
addBreakpoint: function(breakpoint)
{
- this.breakpoints.push(breakpoint);
+ if (this.breakpoints[breakpoint.id])
+ return;
+
+ this.breakpoints[breakpoint.id] = breakpoint;
+
breakpoint.addEventListener("enabled", this._breakpointEnableChanged, this);
breakpoint.addEventListener("disabled", this._breakpointEnableChanged, this);
+ breakpoint.addEventListener("text-changed", this._breakpointTextChanged, this);
- // FIXME: add to the breakpoints UI.
+ this._appendBreakpointElement(breakpoint);
+
+ if (this.emptyElement.parentElement) {
+ this.bodyElement.removeChild(this.emptyElement);
+ this.bodyElement.appendChild(this.listElement);
+ }
if (!InspectorController.debuggerEnabled() || !breakpoint.sourceID)
return;
@@ -52,13 +65,73 @@ WebInspector.BreakpointsSidebarPane.prototype = {
InspectorController.addBreakpoint(breakpoint.sourceID, breakpoint.line);
},
+ _appendBreakpointElement: function(breakpoint)
+ {
+ function checkboxClicked()
+ {
+ breakpoint.enabled = !breakpoint.enabled;
+ }
+
+ function labelClicked()
+ {
+ var script = WebInspector.panels.scripts.scriptOrResourceForID(breakpoint.sourceID);
+ if (script)
+ WebInspector.panels.scripts.showScript(script, breakpoint.line);
+ }
+
+ var breakpointElement = document.createElement("li");
+ breakpoint._breakpointListElement = breakpointElement;
+ breakpointElement._breakpointObject = breakpoint;
+
+ var checkboxElement = document.createElement("input");
+ checkboxElement.className = "checkbox-elem";
+ checkboxElement.type = "checkbox";
+ checkboxElement.checked = breakpoint.enabled;
+ checkboxElement.addEventListener("click", checkboxClicked, false);
+ breakpointElement.appendChild(checkboxElement);
+
+ var labelElement = document.createElement("a");
+ labelElement.textContent = breakpoint.label;
+ labelElement.addEventListener("click", labelClicked, false);
+ breakpointElement.appendChild(labelElement);
+
+ var sourceTextElement = document.createElement("div");
+ sourceTextElement.textContent = breakpoint.sourceText;
+ sourceTextElement.className = "source-text";
+ breakpointElement.appendChild(sourceTextElement);
+
+ var currentElement = this.listElement.firstChild;
+ while (currentElement) {
+ var currentBreak = currentElement._breakpointObject;
+ if (currentBreak.url > breakpoint.url) {
+ this.listElement.insertBefore(breakpointElement, currentElement);
+ return;
+ } else if (currentBreak.url == breakpoint.url && currentBreak.line > breakpoint.line) {
+ this.listElement.insertBefore(breakpointElement, currentElement);
+ return;
+ }
+ currentElement = currentElement.nextSibling;
+ }
+ this.listElement.appendChild(breakpointElement);
+ },
+
removeBreakpoint: function(breakpoint)
{
- this.breakpoints.remove(breakpoint);
+ if (!this.breakpoints[breakpoint.id])
+ return;
+ delete this.breakpoints[breakpoint.id];
+
breakpoint.removeEventListener("enabled", null, this);
breakpoint.removeEventListener("disabled", null, this);
+ breakpoint.removeEventListener("text-changed", null, this);
- // FIXME: remove from the breakpoints UI.
+ var element = breakpoint._breakpointListElement;
+ element.parentElement.removeChild(element);
+
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
+ }
if (!InspectorController.debuggerEnabled() || !breakpoint.sourceID)
return;
@@ -70,7 +143,8 @@ WebInspector.BreakpointsSidebarPane.prototype = {
{
var breakpoint = event.target;
- // FIXME: change the breakpoint checkbox state in the UI.
+ var checkbox = breakpoint._breakpointListElement.firstChild;
+ checkbox.checked = breakpoint.enabled;
if (!InspectorController.debuggerEnabled() || !breakpoint.sourceID)
return;
@@ -79,6 +153,14 @@ WebInspector.BreakpointsSidebarPane.prototype = {
InspectorController.addBreakpoint(breakpoint.sourceID, breakpoint.line);
else
InspectorController.removeBreakpoint(breakpoint.sourceID, breakpoint.line);
+ },
+
+ _breakpointTextChanged: function(event)
+ {
+ var breakpoint = event.target;
+
+ var sourceTextElement = breakpoint._breakpointListElement.firstChild.nextSibling.nextSibling;
+ sourceTextElement.textContent = breakpoint.sourceText;
}
}
diff --git a/WebCore/inspector/front-end/CallStackSidebarPane.js b/WebCore/inspector/front-end/CallStackSidebarPane.js
index a2c8bed..c08cc7a 100644
--- a/WebCore/inspector/front-end/CallStackSidebarPane.js
+++ b/WebCore/inspector/front-end/CallStackSidebarPane.js
@@ -26,6 +26,16 @@
WebInspector.CallStackSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Call Stack"));
+
+ this._shortcuts = {};
+
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.Period,
+ WebInspector.KeyboardShortcut.Modifiers.Ctrl);
+ this._shortcuts[shortcut] = this._selectNextCallFrameOnStack.bind(this);
+
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.Comma,
+ WebInspector.KeyboardShortcut.Modifiers.Ctrl);
+ this._shortcuts[shortcut] = this._selectPreviousCallFrameOnStack.bind(this);
}
WebInspector.CallStackSidebarPane.prototype = {
@@ -100,6 +110,53 @@ WebInspector.CallStackSidebarPane.prototype = {
this.dispatchEventToListeners("call frame selected");
},
+ handleKeyEvent: function(event)
+ {
+ var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var handler = this._shortcuts[shortcut];
+ if (handler) {
+ handler(event);
+ event.preventDefault();
+ event.handled = true;
+ }
+ },
+
+ _selectNextCallFrameOnStack: function()
+ {
+ var index = this._selectedCallFrameIndex();
+ if (index == -1)
+ return;
+ this._selectedPlacardByIndex(index + 1);
+ },
+
+ _selectPreviousCallFrameOnStack: function()
+ {
+ var index = this._selectedCallFrameIndex();
+ if (index == -1)
+ return;
+ this._selectedPlacardByIndex(index - 1);
+ },
+
+ _selectedPlacardByIndex: function(index)
+ {
+ if (index < 0 || index >= this.placards.length)
+ return;
+ var placard = this.placards[index];
+ this.selectedCallFrame = placard.callFrame
+ },
+
+ _selectedCallFrameIndex: function()
+ {
+ if (!this._selectedCallFrame)
+ return -1;
+ for (var i = 0; i < this.placards.length; ++i) {
+ var placard = this.placards[i];
+ if (placard.callFrame === this._selectedCallFrame)
+ return i;
+ }
+ return -1;
+ },
+
_placardSelected: function(event)
{
var placardElement = event.target.enclosingNodeOrSelfWithClass("placard");
diff --git a/WebCore/inspector/front-end/Callback.js b/WebCore/inspector/front-end/Callback.js
new file mode 100644
index 0000000..8ae7f95
--- /dev/null
+++ b/WebCore/inspector/front-end/Callback.js
@@ -0,0 +1,56 @@
+/*
+ * 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.Callback = function()
+{
+ this._lastCallbackId = 1;
+ this._callbacks = {};
+}
+
+WebInspector.Callback.prototype = {
+ wrap: function(callback)
+ {
+ var callbackId = this._lastCallbackId++;
+ this._callbacks[callbackId] = callback || function() {};
+ return callbackId;
+ },
+
+ processCallback: function(callbackId, opt_vararg)
+ {
+ var args = Array.prototype.slice.call(arguments, 1);
+ var callback = this._callbacks[callbackId];
+ callback.apply(null, args);
+ delete this._callbacks[callbackId];
+ }
+}
+
+WebInspector.Callback._INSTANCE = new WebInspector.Callback();
+WebInspector.Callback.wrap = WebInspector.Callback._INSTANCE.wrap.bind(WebInspector.Callback._INSTANCE);
+WebInspector.Callback.processCallback = WebInspector.Callback._INSTANCE.processCallback.bind(WebInspector.Callback._INSTANCE);
diff --git a/WebCore/inspector/front-end/ChangesView.js b/WebCore/inspector/front-end/ChangesView.js
new file mode 100644
index 0000000..802fdba
--- /dev/null
+++ b/WebCore/inspector/front-end/ChangesView.js
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.ChangesView = function(drawer)
+{
+ WebInspector.View.call(this);
+ this.element.innerHTML = "<div style=\"bottom:25%;color:rgb(192,192,192);font-size:12px;height:65px;left:0px;margin:auto;position:absolute;right:0px;text-align:center;top:0px;\"><h1>Not Implemented Yet</h1></div>";
+
+ this.drawer = drawer;
+
+ this.clearButton = document.createElement("button");
+ this.clearButton.id = "clear-changes-status-bar-item";
+ this.clearButton.title = WebInspector.UIString("Clear changes log.");
+ this.clearButton.className = "status-bar-item";
+ this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
+
+ this.toggleChangesButton = document.getElementById("changes-status-bar-item");
+ this.toggleChangesButton.title = WebInspector.UIString("Show changes view.");
+ this.toggleChangesButton.addEventListener("click", this._toggleChangesButtonClicked.bind(this), false);
+ var anchoredStatusBar = document.getElementById("anchored-status-bar-items");
+ anchoredStatusBar.appendChild(this.toggleChangesButton);
+}
+
+WebInspector.ChangesView.prototype = {
+ _clearButtonClicked: function()
+ {
+ // Not Implemented Yet
+ },
+
+ _toggleChangesButtonClicked: function()
+ {
+ this.drawer.visibleView = this;
+ },
+
+ attach: function(mainElement, statusBarElement)
+ {
+ mainElement.appendChild(this.element);
+ statusBarElement.appendChild(this.clearButton);
+ },
+
+ show: function()
+ {
+ this.toggleChangesButton.addStyleClass("toggled-on");
+ this.toggleChangesButton.title = WebInspector.UIString("Hide changes view.");
+ },
+
+ hide: function()
+ {
+ this.toggleChangesButton.removeStyleClass("toggled-on");
+ this.toggleChangesButton.title = WebInspector.UIString("Show changes view.");
+ }
+}
+
+WebInspector.ChangesView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/Color.js b/WebCore/inspector/front-end/Color.js
new file mode 100644
index 0000000..7968ee4
--- /dev/null
+++ b/WebCore/inspector/front-end/Color.js
@@ -0,0 +1,671 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.Color = function(str)
+{
+ this.value = str;
+ this.parse();
+}
+
+WebInspector.Color.prototype = {
+ get shorthex()
+ {
+ if ("_short" in this)
+ return this._short;
+
+ if (!this.simple)
+ return null;
+
+ var hex = this.hex;
+ if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5))
+ this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
+ else
+ this._short = hex;
+
+ return this._short;
+ },
+
+ get hex()
+ {
+ if (!this.simple)
+ return null;
+
+ return this._hex;
+ },
+
+ set hex(x)
+ {
+ this._hex = x;
+ },
+
+ get rgb()
+ {
+ if ("_rgb" in this)
+ return this._rgb;
+
+ if (this.simple)
+ this._rgb = this.hexToRgb(this.hex);
+ else {
+ var rgba = this.rgba;
+ this._rgb = [rgba[0], rgba[1], rgba[2]];
+ }
+
+ return this._rgb;
+ },
+
+ set rgb(x)
+ {
+ this._rgb = x;
+ },
+
+ get hsl()
+ {
+ if ("_hsl" in this)
+ return this._hsl;
+
+ this._hsl = this.rgbToHsl(this.rgb);
+ return this._hsl;
+ },
+
+ set hsl(x)
+ {
+ this._hsl = x;
+ },
+
+ get nickname()
+ {
+ if (typeof this._nickname !== "undefined") // would be set on parse if there was a nickname
+ return this._nickname;
+ else
+ return null;
+ },
+
+ set nickname(x)
+ {
+ this._nickname = x;
+ },
+
+ get rgba()
+ {
+ return this._rgba;
+ },
+
+ set rgba(x)
+ {
+ this._rgba = x;
+ },
+
+ get hsla()
+ {
+ return this._hsla;
+ },
+
+ set hsla(x)
+ {
+ this._hsla = x;
+ },
+
+ hasShortHex: function()
+ {
+ var shorthex = this.shorthex;
+ return (shorthex && shorthex.length === 3);
+ },
+
+ toRgb: function()
+ {
+ return "rgb(" + this.rgb.join(", ") + ")";
+ },
+
+ toHsl: function()
+ {
+ var hsl = this.hsl;
+ return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)";
+ },
+
+ toShortHex: function()
+ {
+ return "#" + this.shorthex;
+ },
+
+ toHex: function()
+ {
+ return "#" + this.hex;
+ },
+
+ toRgba: function()
+ {
+ return "rgba(" + this.rgba.join(", ") + ")";
+ },
+
+ toHsla: function()
+ {
+ var hsla = this.hsla;
+ return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
+ },
+
+ toNickname: function()
+ {
+ return this.nickname;
+ },
+
+ rgbToHex: function(rgb)
+ {
+ var r = parseInt(rgb[0]).toString(16);
+ var g = parseInt(rgb[1]).toString(16);
+ var b = parseInt(rgb[2]).toString(16);
+ if (r.length === 1)
+ r = "0" + r;
+ if (g.length === 1)
+ g = "0" + g;
+ if (b.length === 1)
+ b = "0" + b;
+
+ return (r + g + b).toUpperCase();
+ },
+
+ hexToRgb: function(hex)
+ {
+ var r = parseInt(hex.substring(0,2), 16);
+ var g = parseInt(hex.substring(2,4), 16);
+ var b = parseInt(hex.substring(4,6), 16);
+
+ return [r, g, b];
+ },
+
+ rgbToHsl: function(rgb)
+ {
+ var r = parseInt(rgb[0]) / 255;
+ var g = parseInt(rgb[1]) / 255;
+ var b = parseInt(rgb[2]) / 255;
+ var max = Math.max(r, g, b);
+ var min = Math.min(r, g, b);
+ var diff = max - min;
+ var add = max + min;
+
+ if (min === max)
+ var h = 0;
+ else if (r === max)
+ var h = ((60 * (g - b) / diff) + 360) % 360;
+ else if (g === max)
+ var h = (60 * (b - r) / diff) + 120;
+ else
+ var h = (60 * (r - g) / diff) + 240;
+
+ var l = 0.5 * add;
+
+ if (l === 0)
+ var s = 0;
+ else if (l === 1)
+ var s = 1;
+ else if (l <= 0.5)
+ var s = diff / add;
+ else
+ var s = diff / (2 - add);
+
+ h = Math.round(h);
+ s = Math.round(s*100);
+ l = Math.round(l*100);
+
+ return [h, s, l];
+ },
+
+ hslToRgb: function(hsl)
+ {
+ var h = parseFloat(hsl[0]) / 360;
+ var s = parseFloat(hsl[1]) / 100;
+ var l = parseFloat(hsl[2]) / 100;
+
+ if (l <= 0.5)
+ var q = l * (1 + s);
+ else
+ var q = l + s - (l * s);
+
+ var p = 2 * l - q;
+
+ var tr = h + (1 / 3);
+ var tg = h;
+ var tb = h - (1 / 3);
+
+ var r = Math.round(hueToRgb(p, q, tr) * 255);
+ var g = Math.round(hueToRgb(p, q, tg) * 255);
+ var b = Math.round(hueToRgb(p, q, tb) * 255);
+ return [r, g, b];
+
+ function hueToRgb(p, q, h) {
+ if (h < 0)
+ h += 1;
+ else if (h > 1)
+ h -= 1;
+
+ if ((h * 6) < 1)
+ return p + (q - p) * h * 6;
+ else if ((h * 2) < 1)
+ return q;
+ else if ((h * 3) < 2)
+ return p + (q - p) * ((2 / 3) - h) * 6;
+ else
+ return p;
+ }
+ },
+
+ rgbaToHsla: function(rgba)
+ {
+ var alpha = rgba[3];
+ var hsl = this.rgbToHsl(rgba)
+ hsl.push(alpha);
+ return hsl;
+ },
+
+ hslaToRgba: function(hsla)
+ {
+ var alpha = hsla[3];
+ var rgb = this.hslToRgb(hsla);
+ rgb.push(alpha);
+ return rgb;
+ },
+
+ parse: function()
+ {
+ // Special Values - Advanced but Must Be Parsed First - transparent
+ var value = this.value.toLowerCase().replace(/%|\s+/g, "");
+ if (value in WebInspector.Color.AdvancedNickNames) {
+ this.mode = "nickname";
+ var set = WebInspector.Color.AdvancedNickNames[value];
+ this.simple = false;
+ this.rgba = set[0];
+ this.hsla = set[1];
+ this.nickname = set[2];
+ this.alpha = set[0][3];
+ return;
+ }
+
+ // Simple - #hex, rgb(), nickname, hsl()
+ var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
+ var match = this.value.match(simple);
+ if (match) {
+ this.simple = true;
+
+ if (match[1]) { // hex
+ var hex = match[1].toUpperCase();
+ if (hex.length === 3) {
+ this.mode = "shorthex";
+ this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
+ } else {
+ this.mode = "hex";
+ this.hex = hex;
+ }
+ } else if (match[2]) { // rgb
+ this.mode = "rgb";
+ var rgb = match[2].split(/\s*,\s*/);
+ this.rgb = rgb;
+ this.hex = this.rgbToHex(rgb);
+ } else if (match[3]) { // nickname
+ var nickname = match[3].toLowerCase();
+ if (nickname in WebInspector.Color.Nicknames) {
+ this.mode = "nickname";
+ this.hex = WebInspector.Color.Nicknames[nickname];
+ } else // unknown name
+ throw("unknown color name");
+ } else if (match[4]) { // hsl
+ this.mode = "hsl";
+ var hsl = match[4].replace(/%g/, "").split(/\s*,\s*/);
+ this.hsl = hsl;
+ this.rgb = this.hslToRgb(hsl);
+ this.hex = this.rgbToHex(this.rgb);
+ }
+
+ // Fill in the values if this is a known hex color
+ var hex = this.hex;
+ if (hex && hex in WebInspector.Color.HexTable) {
+ var set = WebInspector.Color.HexTable[hex];
+ this.rgb = set[0];
+ this.hsl = set[1];
+ this.nickname = set[2];
+ }
+
+ return;
+ }
+
+ // Advanced - rgba(), hsla()
+ var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
+ match = this.value.match(advanced);
+ if (match) {
+ this.simple = false;
+ if (match[1]) { // rgba
+ this.mode = "rgba";
+ this.rgba = match[1].split(/\s*,\s*/);
+ this.hsla = this.rgbaToHsla(this.rgba);
+ this.alpha = this.rgba[3];
+ } else if (match[2]) { // hsla
+ this.mode = "hsla";
+ this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/);
+ this.rgba = this.hslaToRgba(this.hsla);
+ this.alpha = this.hsla[3];
+ }
+
+ return;
+ }
+
+ // Could not parse as a valid color
+ throw("could not parse color");
+ }
+}
+
+// Simple Values: [rgb, hsl, nickname]
+WebInspector.Color.HexTable = {
+ "000000": [[0, 0, 0], [0, 0, 0], "black"],
+ "000080": [[0, 0, 128], [240, 100, 25], "navy"],
+ "00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"],
+ "0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"],
+ "0000FF": [[0, 0, 255], [240, 100, 50], "blue"],
+ "006400": [[0, 100, 0], [120, 100, 20], "darkGreen"],
+ "008000": [[0, 128, 0], [120, 100, 25], "green"],
+ "008080": [[0, 128, 128], [180, 100, 25], "teal"],
+ "008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"],
+ "00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"],
+ "00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"],
+ "00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"],
+ "00FF00": [[0, 255, 0], [120, 100, 50], "lime"],
+ "00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"],
+ "00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"],
+ "191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"],
+ "1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"],
+ "20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"],
+ "228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"],
+ "2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"],
+ "2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"],
+ "32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"],
+ "3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"],
+ "40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"],
+ "4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"],
+ "4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"],
+ "483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"],
+ "48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"],
+ "4B0082": [[75, 0, 130], [275, 100, 25], "indigo"],
+ "556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"],
+ "5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"],
+ "6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"],
+ "66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"],
+ "696969": [[105, 105, 105], [0, 0, 41], "dimGray"],
+ "6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"],
+ "6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"],
+ "708090": [[112, 128, 144], [210, 13, 50], "slateGray"],
+ "778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"],
+ "7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"],
+ "7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"],
+ "7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"],
+ "7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"],
+ "800000": [[128, 0, 0], [0, 100, 25], "maroon"],
+ "800080": [[128, 0, 128], [300, 100, 25], "purple"],
+ "808000": [[128, 128, 0], [60, 100, 25], "olive"],
+ "808080": [[128, 128, 128], [0, 0, 50], "gray"],
+ "87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"],
+ "87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"],
+ "8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"],
+ "8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"],
+ "8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"],
+ "8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"],
+ "8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"],
+ "90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"],
+ "9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"],
+ "9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"],
+ "98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"],
+ "9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"],
+ "9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"],
+ "A0522D": [[160, 82, 45], [19, 56, 40], "sienna"],
+ "A52A2A": [[165, 42, 42], [0, 59, 41], "brown"],
+ "A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"],
+ "ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"],
+ "ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"],
+ "AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"],
+ "B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"],
+ "B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"],
+ "B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"],
+ "B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenRod"],
+ "BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"],
+ "BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"],
+ "BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"],
+ "C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"],
+ "C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"],
+ "CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"],
+ "CD853F": [[205, 133, 63], [30, 59, 53], "peru"],
+ "D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"],
+ "D2B48C": [[210, 180, 140], [34, 44, 69], "tan"],
+ "D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"],
+ "D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"],
+ "D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"],
+ "DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"],
+ "DAA520": [[218, 165, 32], [43, 74, 49], "goldenRod"],
+ "DC143C": [[237, 164, 61], [35, 83, 58], "crimson"],
+ "DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"],
+ "DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"],
+ "DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"],
+ "E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"],
+ "E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"],
+ "E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"],
+ "EE82EE": [[238, 130, 238], [300, 76, 72], "violet"],
+ "EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenRod"],
+ "F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"],
+ "F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"],
+ "F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"],
+ "F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"],
+ "F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"],
+ "F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"],
+ "F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"],
+ "F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"],
+ "F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"],
+ "F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"],
+ "F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"],
+ "FA8072": [[250, 128, 114], [6, 93, 71], "salmon"],
+ "FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"],
+ "FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"],
+ "FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenRodYellow"],
+ "FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"],
+ "FF0000": [[255, 0, 0], [0, 100, 50], "red"],
+ "FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"],
+ "FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"],
+ "FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"],
+ "FF6347": [[255, 99, 71], [9, 100, 64], "tomato"],
+ "FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"],
+ "FF7F50": [[255, 127, 80], [16, 100, 66], "coral"],
+ "FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"],
+ "FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"],
+ "FFA500": [[255, 165, 0], [39, 100, 50], "orange"],
+ "FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"],
+ "FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"],
+ "FFD700": [[255, 215, 0], [51, 100, 50], "gold"],
+ "FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"],
+ "FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"],
+ "FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"],
+ "FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"],
+ "FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"],
+ "FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"],
+ "FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"],
+ "FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"],
+ "FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"],
+ "FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"],
+ "FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"],
+ "FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"],
+ "FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"],
+ "FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"],
+ "FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"],
+ "FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"],
+ "FFFFFF": [[255, 255, 255], [0, 100, 100], "white"]
+};
+
+// Simple Values
+WebInspector.Color.Nicknames = {
+ "aliceblue": "F0F8FF",
+ "antiquewhite": "FAEBD7",
+ "aqua": "00FFFF",
+ "aquamarine": "7FFFD4",
+ "azure": "F0FFFF",
+ "beige": "F5F5DC",
+ "bisque": "FFE4C4",
+ "black": "000000",
+ "blanchedalmond": "FFEBCD",
+ "blue": "0000FF",
+ "blueviolet": "8A2BE2",
+ "brown": "A52A2A",
+ "burlywood": "DEB887",
+ "cadetblue": "5F9EA0",
+ "chartreuse": "7FFF00",
+ "chocolate": "D2691E",
+ "coral": "FF7F50",
+ "cornflowerblue": "6495ED",
+ "cornsilk": "FFF8DC",
+ "crimson": "DC143C",
+ "cyan": "00FFFF",
+ "darkblue": "00008B",
+ "darkcyan": "008B8B",
+ "darkgoldenrod": "B8860B",
+ "darkgray": "A9A9A9",
+ "darkgreen": "006400",
+ "darkkhaki": "BDB76B",
+ "darkmagenta": "8B008B",
+ "darkolivegreen": "556B2F",
+ "darkorange": "FF8C00",
+ "darkorchid": "9932CC",
+ "darkred": "8B0000",
+ "darksalmon": "E9967A",
+ "darkseagreen": "8FBC8F",
+ "darkslateblue": "483D8B",
+ "darkslategray": "2F4F4F",
+ "darkturquoise": "00CED1",
+ "darkviolet": "9400D3",
+ "deeppink": "FF1493",
+ "deepskyblue": "00BFFF",
+ "dimgray": "696969",
+ "dodgerblue": "1E90FF",
+ "firebrick": "B22222",
+ "floralwhite": "FFFAF0",
+ "forestgreen": "228B22",
+ "fuchsia": "FF00FF",
+ "gainsboro": "DCDCDC",
+ "ghostwhite": "F8F8FF",
+ "gold": "FFD700",
+ "goldenrod": "DAA520",
+ "gray": "808080",
+ "green": "008000",
+ "greenyellow": "ADFF2F",
+ "honeydew": "F0FFF0",
+ "hotpink": "FF69B4",
+ "indianred": "CD5C5C",
+ "indigo": "4B0082",
+ "ivory": "FFFFF0",
+ "khaki": "F0E68C",
+ "lavender": "E6E6FA",
+ "lavenderblush": "FFF0F5",
+ "lawngreen": "7CFC00",
+ "lemonchiffon": "FFFACD",
+ "lightblue": "ADD8E6",
+ "lightcoral": "F08080",
+ "lightcyan": "E0FFFF",
+ "lightgoldenrodyellow": "FAFAD2",
+ "lightgreen": "90EE90",
+ "lightgrey": "D3D3D3",
+ "lightpink": "FFB6C1",
+ "lightsalmon": "FFA07A",
+ "lightseagreen": "20B2AA",
+ "lightskyblue": "87CEFA",
+ "lightslategray": "778899",
+ "lightsteelblue": "B0C4DE",
+ "lightyellow": "FFFFE0",
+ "lime": "00FF00",
+ "limegreen": "32CD32",
+ "linen": "FAF0E6",
+ "magenta": "FF00FF",
+ "maroon": "800000",
+ "mediumaquamarine": "66CDAA",
+ "mediumblue": "0000CD",
+ "mediumorchid": "BA55D3",
+ "mediumpurple": "9370D8",
+ "mediumseagreen": "3CB371",
+ "mediumslateblue": "7B68EE",
+ "mediumspringgreen": "00FA9A",
+ "mediumturquoise": "48D1CC",
+ "mediumvioletred": "C71585",
+ "midnightblue": "191970",
+ "mintcream": "F5FFFA",
+ "mistyrose": "FFE4E1",
+ "moccasin": "FFE4B5",
+ "navajowhite": "FFDEAD",
+ "navy": "000080",
+ "oldlace": "FDF5E6",
+ "olive": "808000",
+ "olivedrab": "6B8E23",
+ "orange": "FFA500",
+ "orangered": "FF4500",
+ "orchid": "DA70D6",
+ "palegoldenrod": "EEE8AA",
+ "palegreen": "98FB98",
+ "paleturquoise": "AFEEEE",
+ "palevioletred": "D87093",
+ "papayawhip": "FFEFD5",
+ "peachpuff": "FFDAB9",
+ "peru": "CD853F",
+ "pink": "FFC0CB",
+ "plum": "DDA0DD",
+ "powderblue": "B0E0E6",
+ "purple": "800080",
+ "red": "FF0000",
+ "rosybrown": "BC8F8F",
+ "royalblue": "4169E1",
+ "saddlebrown": "8B4513",
+ "salmon": "FA8072",
+ "sandybrown": "F4A460",
+ "seagreen": "2E8B57",
+ "seashell": "FFF5EE",
+ "sienna": "A0522D",
+ "silver": "C0C0C0",
+ "skyblue": "87CEEB",
+ "slateblue": "6A5ACD",
+ "slategray": "708090",
+ "snow": "FFFAFA",
+ "springgreen": "00FF7F",
+ "steelblue": "4682B4",
+ "tan": "D2B48C",
+ "teal": "008080",
+ "thistle": "D8BFD8",
+ "tomato": "FF6347",
+ "turquoise": "40E0D0",
+ "violet": "EE82EE",
+ "wheat": "F5DEB3",
+ "white": "FFFFFF",
+ "whitesmoke": "F5F5F5",
+ "yellow": "FFFF00",
+ "yellowgreen": "9ACD32"
+};
+
+// Advanced Values [rgba, hsla, nickname]
+WebInspector.Color.AdvancedNickNames = {
+ "transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
+ "rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
+ "hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
+};
diff --git a/WebCore/inspector/front-end/Console.js b/WebCore/inspector/front-end/ConsoleView.js
index 65cc7d0..6851eea 100644
--- a/WebCore/inspector/front-end/Console.js
+++ b/WebCore/inspector/front-end/ConsoleView.js
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,11 +27,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Console = function()
+WebInspector.ConsoleView = function(drawer)
{
+ WebInspector.View.call(this, document.getElementById("console-view"));
+
this.messages = [];
+ this.drawer = drawer;
- WebInspector.View.call(this, document.getElementById("console"));
+ this.clearButton = document.getElementById("clear-console-status-bar-item");
+ this.clearButton.title = WebInspector.UIString("Clear console log.");
+ this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
this.messagesElement = document.getElementById("console-messages");
this.messagesElement.addEventListener("selectstart", this._messagesSelectStart.bind(this), false);
@@ -40,103 +46,49 @@ WebInspector.Console = function()
this.promptElement.handleKeyEvent = this._promptKeyDown.bind(this);
this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), " .=:[({;");
- this.toggleButton = document.getElementById("console-status-bar-item");
- this.toggleButton.title = WebInspector.UIString("Show console.");
- this.toggleButton.addEventListener("click", this._toggleButtonClicked.bind(this), false);
-
- this.clearButton = document.getElementById("clear-console-status-bar-item");
- this.clearButton.title = WebInspector.UIString("Clear console log.");
- this.clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
-
this.topGroup = new WebInspector.ConsoleGroup(null, 0);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.groupLevel = 0;
this.currentGroup = this.topGroup;
- document.getElementById("main-status-bar").addEventListener("mousedown", this._startStatusBarDragging.bind(this), true);
-}
-
-WebInspector.Console.prototype = {
- show: function()
- {
- if (this._animating || this.visible)
- return;
-
- WebInspector.View.prototype.show.call(this);
+ this.toggleConsoleButton = document.getElementById("console-status-bar-item");
+ this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
+ this.toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
- this._animating = true;
+ var anchoredStatusBar = document.getElementById("anchored-status-bar-items");
+ anchoredStatusBar.appendChild(this.toggleConsoleButton);
- this.toggleButton.addStyleClass("toggled-on");
- this.toggleButton.title = WebInspector.UIString("Hide console.");
-
- document.body.addStyleClass("console-visible");
-
- var anchoredItems = document.getElementById("anchored-status-bar-items");
-
- var animations = [
- {element: document.getElementById("main"), end: {bottom: this.element.offsetHeight}},
- {element: document.getElementById("main-status-bar"), start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}},
- {element: document.getElementById("other-console-status-bar-items"), start: {opacity: 0}, end: {opacity: 1}}
- ];
-
- var consoleStatusBar = document.getElementById("console-status-bar");
- consoleStatusBar.insertBefore(anchoredItems, consoleStatusBar.firstChild);
+}
- function animationFinished()
- {
- if ("updateStatusBarItems" in WebInspector.currentPanel)
- WebInspector.currentPanel.updateStatusBarItems();
- WebInspector.currentFocusElement = this.promptElement;
- delete this._animating;
- }
+WebInspector.ConsoleView.prototype = {
+ _toggleConsoleButtonClicked: function()
+ {
+ this.drawer.visibleView = this;
+ },
- WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this));
+ attach: function(mainElement, statusBarElement)
+ {
+ mainElement.appendChild(this.element);
+ statusBarElement.appendChild(this.clearButton);
+ },
+ show: function()
+ {
+ this.toggleConsoleButton.addStyleClass("toggled-on");
+ this.toggleConsoleButton.title = WebInspector.UIString("Hide console.");
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},
- hide: function()
+ afterShow: function()
{
- if (this._animating || !this.visible)
- return;
-
- WebInspector.View.prototype.hide.call(this);
-
- this._animating = true;
-
- this.toggleButton.removeStyleClass("toggled-on");
- this.toggleButton.title = WebInspector.UIString("Show console.");
-
- if (this.element === WebInspector.currentFocusElement || this.element.isAncestor(WebInspector.currentFocusElement))
- WebInspector.currentFocusElement = WebInspector.previousFocusElement;
-
- var anchoredItems = document.getElementById("anchored-status-bar-items");
-
- // Temporally set properties and classes to mimic the post-animation values so panels
- // like Elements in their updateStatusBarItems call will size things to fit the final location.
- document.getElementById("main-status-bar").style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px");
- document.body.removeStyleClass("console-visible");
- if ("updateStatusBarItems" in WebInspector.currentPanel)
- WebInspector.currentPanel.updateStatusBarItems();
- document.body.addStyleClass("console-visible");
-
- var animations = [
- {element: document.getElementById("main"), end: {bottom: 0}},
- {element: document.getElementById("main-status-bar"), start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}},
- {element: document.getElementById("other-console-status-bar-items"), start: {opacity: 1}, end: {opacity: 0}}
- ];
-
- function animationFinished()
- {
- var mainStatusBar = document.getElementById("main-status-bar");
- mainStatusBar.insertBefore(anchoredItems, mainStatusBar.firstChild);
- mainStatusBar.style.removeProperty("padding-left");
- document.body.removeStyleClass("console-visible");
- delete this._animating;
- }
+ WebInspector.currentFocusElement = this.promptElement;
+ },
- WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this));
+ hide: function()
+ {
+ this.toggleConsoleButton.removeStyleClass("toggled-on");
+ this.toggleConsoleButton.title = WebInspector.UIString("Show console.");
},
addMessage: function(msg)
@@ -198,7 +150,7 @@ WebInspector.Console.prototype = {
this.messages.push(msg);
- if (msg.level === WebInspector.ConsoleMessage.MessageLevel.EndGroup) {
+ if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
if (this.groupLevel < 1)
return;
@@ -206,7 +158,7 @@ WebInspector.Console.prototype = {
this.currentGroup = this.currentGroup.parentGroup;
} else {
- if (msg.level === WebInspector.ConsoleMessage.MessageLevel.StartGroup) {
+ if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup) {
this.groupLevel++;
var group = new WebInspector.ConsoleGroup(this.currentGroup, this.groupLevel);
@@ -241,7 +193,7 @@ WebInspector.Console.prototype = {
delete this.previousMessage;
},
- completions: function(wordRange, bestMatchOnly)
+ completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
{
// Pass less stop characters to rangeOfWord so the range will be a more complete expression.
const expressionStopCharacters = " =:{;";
@@ -259,22 +211,11 @@ WebInspector.Console.prototype = {
if (!expressionString && !prefix)
return;
- var result;
- if (expressionString) {
- try {
- result = this._evalInInspectedWindow(expressionString);
- } catch(e) {
- // Do nothing, the prefix will be considered a window property.
- }
- } else {
- // There is no expressionString, so the completion should happen against global properties.
- // Or if the debugger is paused, against properties in scope of the selected call frame.
- if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
- result = WebInspector.panels.scripts.variablesInScopeForSelectedCallFrame();
- else
- result = InspectorController.inspectedWindow();
- }
+ var reportCompletions = this._reportCompletions.bind(this, bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix);
+ this._evalInInspectedWindow(expressionString, reportCompletions);
+ },
+ _reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
@@ -283,7 +224,17 @@ WebInspector.Console.prototype = {
}
var results = [];
- var properties = Object.sortedProperties(result);
+ var properties = Object.properties(result);
+ if (!dotNotation && !bracketNotation && result._inspectorCommandLineAPI) {
+ var commandLineAPI = Object.properties(result._inspectorCommandLineAPI);
+ for (var i = 0; i < commandLineAPI.length; ++i) {
+ var property = commandLineAPI[i];
+ if (property.charAt(0) !== "_")
+ properties.push(property);
+ }
+ }
+ properties.sort();
+
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
@@ -305,13 +256,7 @@ WebInspector.Console.prototype = {
if (bestMatchOnly)
break;
}
-
- return results;
- },
-
- _toggleButtonClicked: function()
- {
- this.visible = !this.visible;
+ setTimeout(completionsReadyCallback, 0, results);
},
_clearButtonClicked: function()
@@ -359,47 +304,17 @@ WebInspector.Console.prototype = {
this.prompt.handleKeyEvent(event);
},
- _startStatusBarDragging: function(event)
+ _evalInInspectedWindow: function(expression, callback)
{
- if (!this.visible || event.target !== document.getElementById("main-status-bar"))
+ if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
+ WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, callback);
return;
-
- WebInspector.elementDragStart(document.getElementById("main-status-bar"), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), event, "row-resize");
-
- this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop;
-
- event.stopPropagation();
- },
-
- _statusBarDragging: function(event)
- {
- var mainElement = document.getElementById("main");
-
- var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
- height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight);
-
- mainElement.style.bottom = height + "px";
- this.element.style.height = height + "px";
-
- event.preventDefault();
- event.stopPropagation();
- },
-
- _endStatusBarDragging: function(event)
- {
- WebInspector.elementDragEnd(event);
-
- delete this._statusBarDragOffset;
-
- event.stopPropagation();
+ }
+ this.doEvalInWindow(expression, callback);
},
- _evalInInspectedWindow: function(expression)
+ _ensureCommandLineAPIInstalled: function(inspectedWindow)
{
- if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
- return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression);
-
- var inspectedWindow = InspectorController.inspectedWindow();
if (!inspectedWindow._inspectorCommandLineAPI) {
inspectedWindow.eval("window._inspectorCommandLineAPI = { \
$: function() { return document.getElementById.apply(document, arguments) }, \
@@ -416,20 +331,79 @@ WebInspector.Console.prototype = {
}, \
dir: function() { return console.dir.apply(console, arguments) }, \
dirxml: function() { return console.dirxml.apply(console, arguments) }, \
- keys: function(o) { var a = []; for (k in o) a.push(k); return a; }, \
- values: function(o) { var a = []; for (k in o) a.push(o[k]); return a; }, \
+ keys: function(o) { var a = []; for (var k in o) a.push(k); return a; }, \
+ values: function(o) { var a = []; for (var k in o) a.push(o[k]); return a; }, \
profile: function() { return console.profile.apply(console, arguments) }, \
- profileEnd: function() { return console.profileEnd.apply(console, arguments) } \
+ profileEnd: function() { return console.profileEnd.apply(console, arguments) }, \
+ _inspectedNodes: [], \
+ get $0() { return _inspectorCommandLineAPI._inspectedNodes[0] }, \
+ get $1() { return _inspectorCommandLineAPI._inspectedNodes[1] }, \
+ get $2() { return _inspectorCommandLineAPI._inspectedNodes[2] }, \
+ get $3() { return _inspectorCommandLineAPI._inspectedNodes[3] }, \
+ get $4() { return _inspectorCommandLineAPI._inspectedNodes[4] } \
};");
inspectedWindow._inspectorCommandLineAPI.clear = InspectorController.wrapCallback(this.clearMessages.bind(this));
+ inspectedWindow._inspectorCommandLineAPI.inspect = InspectorController.wrapCallback(inspectObject.bind(this));
+
+ function inspectObject(o)
+ {
+ if (arguments.length === 0)
+ return;
+
+ InspectorController.inspectedWindow().console.log(o);
+ if (Object.type(o, InspectorController.inspectedWindow()) === "node") {
+ WebInspector.showElementsPanel();
+ WebInspector.panels.elements.treeOutline.revealAndSelectNode(o);
+ } else {
+ switch (Object.describe(o)) {
+ case "Database":
+ WebInspector.showDatabasesPanel();
+ WebInspector.panels.databases.selectDatabase(o);
+ break;
+ case "Storage":
+ WebInspector.showDatabasesPanel();
+ WebInspector.panels.databases.selectDOMStorage(o);
+ break;
+ }
+ }
+ }
+ }
+ },
+
+ addInspectedNode: function(node)
+ {
+ var inspectedWindow = InspectorController.inspectedWindow();
+ this._ensureCommandLineAPIInstalled(inspectedWindow);
+ var inspectedNodes = inspectedWindow._inspectorCommandLineAPI._inspectedNodes;
+ inspectedNodes.unshift(node);
+ if (inspectedNodes.length >= 5)
+ inspectedNodes.pop();
+ },
+
+ doEvalInWindow: function(expression, callback)
+ {
+ if (!expression) {
+ // There is no expression, so the completion should happen against global properties.
+ expression = "this";
}
// Surround the expression in with statements to inject our command line API so that
// the window object properties still take more precedent than our API functions.
expression = "with (window._inspectorCommandLineAPI) { with (window) { " + expression + " } }";
- return inspectedWindow.eval(expression);
+ var self = this;
+ function delayedEvaluation()
+ {
+ var inspectedWindow = InspectorController.inspectedWindow();
+ self._ensureCommandLineAPIInstalled(inspectedWindow);
+ try {
+ callback(inspectedWindow.eval(expression));
+ } catch (e) {
+ callback(e, true);
+ }
+ }
+ setTimeout(delayedEvaluation, 0);
},
_enterKeyPressed: function(event)
@@ -449,25 +423,26 @@ WebInspector.Console.prototype = {
var commandMessage = new WebInspector.ConsoleCommand(str);
this.addMessage(commandMessage);
- var result;
- var exception = false;
- try {
- result = this._evalInInspectedWindow(str);
- } catch(e) {
- result = e;
- exception = true;
+ var self = this;
+ function printResult(result, exception)
+ {
+ self.prompt.history.push(str);
+ self.prompt.historyOffset = 0;
+ self.prompt.text = "";
+ self.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
}
-
- this.prompt.history.push(str);
- this.prompt.historyOffset = 0;
- this.prompt.text = "";
-
- this.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
+ this._evalInInspectedWindow(str, printResult);
},
_format: function(output, forceObjectFormat)
{
- var type = (forceObjectFormat ? "object" : Object.type(output, InspectorController.inspectedWindow()));
+ var inspectedWindow = InspectorController.inspectedWindow();
+ if (forceObjectFormat)
+ var type = "object";
+ else if (output instanceof inspectedWindow.NodeList)
+ var type = "array";
+ else
+ var type = Object.type(output, inspectedWindow);
// We don't perform any special formatting on these types, so we just
// pass them through the simple _formatvalue function.
@@ -538,7 +513,7 @@ WebInspector.Console.prototype = {
_formatobject: function(obj, elem)
{
- elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, null, null, null, true).element);
+ elem.appendChild(new WebInspector.ObjectPropertiesSection(new WebInspector.ObjectProxy(obj), Object.describe(obj, true), null, null, true).element);
},
_formaterror: function(obj, elem)
@@ -564,28 +539,29 @@ WebInspector.Console.prototype = {
elem.appendChild(urlElement);
elem.appendChild(document.createTextNode(")"));
}
- },
+ }
}
-WebInspector.Console.prototype.__proto__ = WebInspector.View.prototype;
+WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;
-WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, repeatCount)
+WebInspector.ConsoleMessage = function(source, type, level, line, url, groupLevel, repeatCount)
{
this.source = source;
+ this.type = type;
this.level = level;
this.line = line;
this.url = url;
this.groupLevel = groupLevel;
this.repeatCount = repeatCount;
- if (arguments.length > 6)
- this.setMessageBody(Array.prototype.slice.call(arguments, 6));
+ if (arguments.length > 7)
+ this.setMessageBody(Array.prototype.slice.call(arguments, 7));
}
WebInspector.ConsoleMessage.prototype = {
setMessageBody: function(args)
{
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Trace:
+ switch (this.type) {
+ case WebInspector.ConsoleMessage.MessageType.Trace:
var span = document.createElement("span");
span.addStyleClass("console-formatted-trace");
var stack = Array.prototype.slice.call(args);
@@ -595,7 +571,7 @@ WebInspector.ConsoleMessage.prototype = {
span.appendChild(document.createTextNode(funcNames.join("\n")));
this.formattedMessage = span;
break;
- case WebInspector.ConsoleMessage.MessageLevel.Object:
+ case WebInspector.ConsoleMessage.MessageType.Object:
this.formattedMessage = this._format(["%O", args[0]]);
break;
default:
@@ -713,8 +689,10 @@ WebInspector.ConsoleMessage.prototype = {
case WebInspector.ConsoleMessage.MessageLevel.Error:
element.addStyleClass("console-error-level");
break;
- case WebInspector.ConsoleMessage.MessageLevel.StartGroup:
- element.addStyleClass("console-group-title-level");
+ }
+
+ if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup) {
+ element.addStyleClass("console-group-title");
}
if (this.elementsTreeOutline) {
@@ -781,6 +759,25 @@ WebInspector.ConsoleMessage.prototype = {
break;
}
+ var typeString;
+ switch (this.type) {
+ case WebInspector.ConsoleMessage.MessageType.Log:
+ typeString = "Log";
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Object:
+ typeString = "Object";
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Trace:
+ typeString = "Trace";
+ break;
+ case WebInspector.ConsoleMessage.MessageType.StartGroup:
+ typeString = "Start Group";
+ break;
+ case WebInspector.ConsoleMessage.MessageType.EndGroup:
+ typeString = "End Group";
+ break;
+ }
+
var levelString;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
@@ -795,21 +792,9 @@ WebInspector.ConsoleMessage.prototype = {
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
- case WebInspector.ConsoleMessage.MessageLevel.Object:
- levelString = "Object";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Trace:
- levelString = "Trace";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.StartGroup:
- levelString = "Start Group";
- break;
- case WebInspector.ConsoleMessage.MessageLevel.EndGroup:
- levelString = "End Group";
- break;
}
- return sourceString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
+ return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},
isEqual: function(msg, disreguardGroup)
@@ -818,6 +803,7 @@ WebInspector.ConsoleMessage.prototype = {
return false;
var ret = (this.source == msg.source)
+ && (this.type == msg.type)
&& (this.level == msg.level)
&& (this.line == msg.line)
&& (this.url == msg.url)
@@ -837,15 +823,19 @@ WebInspector.ConsoleMessage.MessageSource = {
Other: 5
}
+WebInspector.ConsoleMessage.MessageType = {
+ Log: 0,
+ Object: 1,
+ Trace: 2,
+ StartGroup: 3,
+ EndGroup: 4
+}
+
WebInspector.ConsoleMessage.MessageLevel = {
Tip: 0,
Log: 1,
Warning: 2,
- Error: 3,
- Object: 4,
- Trace: 5,
- StartGroup: 6,
- EndGroup: 7
+ Error: 3
}
WebInspector.ConsoleCommand = function(command)
@@ -876,7 +866,7 @@ WebInspector.ConsoleCommandResult = function(result, exception, originatingComma
var line = (exception ? result.line : -1);
var url = (exception ? result.sourceURL : null);
- WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, line, url, null, 1, message);
+ WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageType.Log, level, line, url, null, 1, message);
this.originatingCommand = originatingCommand;
}
@@ -913,7 +903,7 @@ WebInspector.ConsoleGroup.prototype = {
{
var element = msg.toMessageElement();
- if (msg.level === WebInspector.ConsoleMessage.MessageLevel.StartGroup) {
+ if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup) {
this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
element.addEventListener("click", this._titleClicked.bind(this), true);
} else
@@ -925,7 +915,7 @@ WebInspector.ConsoleGroup.prototype = {
_titleClicked: function(event)
{
- var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title-level");
+ var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (groupTitleElement) {
var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
if (groupElement)
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
new file mode 100644
index 0000000..5aacd41
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -0,0 +1,724 @@
+/*
+ * 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.DOMNode = function(doc, payload) {
+ this.ownerDocument = doc;
+
+ this._id = payload.id;
+ this.nodeType = payload.nodeType;
+ this.nodeName = payload.nodeName;
+ this._nodeValue = payload.nodeValue;
+ this.textContent = this.nodeValue;
+
+ this.attributes = [];
+ this._attributesMap = {};
+ if (payload.attributes)
+ this._setAttributesPayload(payload.attributes);
+
+ this._childNodeCount = payload.childNodeCount;
+ this.children = null;
+
+ this.nextSibling = null;
+ this.prevSibling = null;
+ this.firstChild = null;
+ this.parentNode = null;
+
+ if (payload.childNodes)
+ this._setChildrenPayload(payload.childNodes);
+
+ this._computedStyle = null;
+ this.style = null;
+ this._matchedCSSRules = [];
+}
+
+WebInspector.DOMNode.prototype = {
+ hasAttributes: function()
+ {
+ return this.attributes.length > 0;
+ },
+
+ hasChildNodes: function() {
+ return this._childNodeCount > 0;
+ },
+
+ get nodeValue() {
+ return this._nodeValue;
+ },
+
+ set nodeValue(value) {
+ if (this.nodeType != Node.TEXT_NODE)
+ return;
+ var self = this;
+ var callback = function()
+ {
+ self._nodeValue = value;
+ self.textContent = value;
+ };
+ this.ownerDocument._domAgent.setTextNodeValueAsync(this, value, callback);
+ },
+
+ getAttribute: function(name)
+ {
+ var attr = this._attributesMap[name];
+ return attr ? attr.value : undefined;
+ },
+
+ setAttribute: function(name, value)
+ {
+ var self = this;
+ var callback = function()
+ {
+ var attr = self._attributesMap[name];
+ if (attr)
+ attr.value = value;
+ else
+ attr = self._addAttribute(name, value);
+ };
+ this.ownerDocument._domAgent.setAttributeAsync(this, name, value, callback);
+ },
+
+ removeAttribute: function(name)
+ {
+ var self = this;
+ var callback = function()
+ {
+ delete self._attributesMap[name];
+ for (var i = 0; i < self.attributes.length; ++i) {
+ if (self.attributes[i].name == name) {
+ self.attributes.splice(i, 1);
+ break;
+ }
+ }
+ };
+ this.ownerDocument._domAgent.removeAttributeAsync(this, name, callback);
+ },
+
+ _setAttributesPayload: function(attrs)
+ {
+ for (var i = 0; i < attrs.length; i += 2)
+ this._addAttribute(attrs[i], attrs[i + 1]);
+ },
+
+ _insertChild: function(prev, payload)
+ {
+ var node = new WebInspector.DOMNode(this.ownerDocument, payload);
+ if (!prev)
+ // First node
+ this.children = [ node ];
+ else
+ this.children.splice(this.children.indexOf(prev) + 1, 0, node);
+ this._renumber();
+ return node;
+ },
+
+ removeChild_: function(node)
+ {
+ this.children.splice(this.children.indexOf(node), 1);
+ node.parentNode = null;
+ this._renumber();
+ },
+
+ _setChildrenPayload: function(payloads)
+ {
+ this.children = [];
+ for (var i = 0; i < payloads.length; ++i) {
+ var payload = payloads[i];
+ var node = new WebInspector.DOMNode(this.ownerDocument, payload);
+ this.children.push(node);
+ }
+ this._renumber();
+ },
+
+ _renumber: function()
+ {
+ this._childNodeCount = this.children.length;
+ if (this._childNodeCount == 0) {
+ this.firstChild = null;
+ return;
+ }
+ this.firstChild = this.children[0];
+ for (var i = 0; i < this._childNodeCount; ++i) {
+ var child = this.children[i];
+ child.nextSibling = i + 1 < this._childNodeCount ? this.children[i + 1] : null;
+ child.prevSibling = i - 1 >= 0 ? this.children[i - 1] : null;
+ child.parentNode = this;
+ }
+ },
+
+ _addAttribute: function(name, value)
+ {
+ var attr = {
+ "name": name,
+ "value": value,
+ "_node": this
+ };
+ this._attributesMap[name] = attr;
+ this.attributes.push(attr);
+ },
+
+ _setStyles: function(computedStyle, inlineStyle, styleAttributes, matchedCSSRules)
+ {
+ this._computedStyle = new WebInspector.CSSStyleDeclaration(computedStyle);
+ this.style = new WebInspector.CSSStyleDeclaration(inlineStyle);
+
+ for (var name in styleAttributes) {
+ if (this._attributesMap[name])
+ this._attributesMap[name].style = new WebInspector.CSSStyleDeclaration(styleAttributes[name]);
+ }
+
+ this._matchedCSSRules = [];
+ for (var i = 0; i < matchedCSSRules.length; i++)
+ this._matchedCSSRules.push(WebInspector.CSSStyleDeclaration.parseRule(matchedCSSRules[i]));
+ },
+
+ _clearStyles: function()
+ {
+ this.computedStyle = null;
+ this.style = null;
+ for (var name in this._attributesMap)
+ this._attributesMap[name].style = null;
+ this._matchedCSSRules = null;
+ }
+}
+
+WebInspector.DOMDocument = function(domAgent, defaultView)
+{
+ WebInspector.DOMNode.call(this, null,
+ {
+ id: 0,
+ nodeType: Node.DOCUMENT_NODE,
+ nodeName: "",
+ nodeValue: "",
+ attributes: [],
+ childNodeCount: 0
+ });
+ this._listeners = {};
+ this._domAgent = domAgent;
+ this.defaultView = defaultView;
+}
+
+WebInspector.DOMDocument.prototype = {
+
+ addEventListener: function(name, callback, useCapture)
+ {
+ var listeners = this._listeners[name];
+ if (!listeners) {
+ listeners = [];
+ this._listeners[name] = listeners;
+ }
+ listeners.push(callback);
+ },
+
+ removeEventListener: function(name, callback, useCapture)
+ {
+ var listeners = this._listeners[name];
+ if (!listeners)
+ return;
+
+ var index = listeners.indexOf(callback);
+ if (index != -1)
+ listeners.splice(index, 1);
+ },
+
+ _fireDomEvent: function(name, event)
+ {
+ var listeners = this._listeners[name];
+ if (!listeners)
+ return;
+
+ for (var i = 0; i < listeners.length; ++i)
+ listeners[i](event);
+ }
+}
+
+WebInspector.DOMDocument.prototype.__proto__ = WebInspector.DOMNode.prototype;
+
+
+WebInspector.DOMWindow = function(domAgent)
+{
+ this._domAgent = domAgent;
+}
+
+WebInspector.DOMWindow.prototype = {
+ get document()
+ {
+ return this._domAgent.document;
+ },
+
+ get Node()
+ {
+ return WebInspector.DOMNode;
+ },
+
+ get Element()
+ {
+ return WebInspector.DOMNode;
+ },
+
+ Object: function()
+ {
+ },
+
+ getComputedStyle: function(node)
+ {
+ return node._computedStyle;
+ },
+
+ getMatchedCSSRules: function(node, pseudoElement, authorOnly)
+ {
+ return node._matchedCSSRules;
+ }
+}
+
+WebInspector.DOMAgent = function() {
+ this._window = new WebInspector.DOMWindow(this);
+ this._idToDOMNode = null;
+ this.document = null;
+
+ // Install onpopulate handler. This is a temporary measure.
+ // TODO: add this code into the original updateChildren once domAgent
+ // becomes primary source of DOM information.
+ // TODO2: update ElementsPanel to not track embedded iframes - it is already being handled
+ // in the agent backend.
+ var domAgent = this;
+ var originalUpdateChildren = WebInspector.ElementsTreeElement.prototype.updateChildren;
+ WebInspector.ElementsTreeElement.prototype.updateChildren = function()
+ {
+ domAgent.getChildNodesAsync(this.representedObject, originalUpdateChildren.bind(this));
+ };
+
+ // Mute console handle to avoid crash on selection change.
+ // TODO: Re-implement inspectorConsoleAPI to work in a serialized way and remove this workaround.
+ WebInspector.Console.prototype.addInspectedNode = function()
+ {
+ };
+
+ // Whitespace is ignored in InspectorDOMAgent already -> no need to filter.
+ // TODO: Either remove all of its usages or push value into the agent backend.
+ Preferences.ignoreWhitespace = false;
+}
+
+WebInspector.DOMAgent.prototype = {
+ get inspectedWindow()
+ {
+ return this._window;
+ },
+
+ getChildNodesAsync: function(parent, opt_callback)
+ {
+ var children = parent.children;
+ if (children && opt_callback) {
+ opt_callback(children);
+ return;
+ }
+ var mycallback = function() {
+ if (opt_callback) {
+ opt_callback(parent.children);
+ }
+ };
+ var callId = WebInspector.Callback.wrap(mycallback);
+ InspectorController.getChildNodes(callId, parent._id);
+ },
+
+ setAttributeAsync: function(node, name, value, callback)
+ {
+ var mycallback = this._didApplyDomChange.bind(this, node, callback);
+ InspectorController.setAttribute(WebInspector.Callback.wrap(mycallback), node._id, name, value);
+ },
+
+ removeAttributeAsync: function(node, name, callback)
+ {
+ var mycallback = this._didApplyDomChange.bind(this, node, callback);
+ InspectorController.removeAttribute(WebInspector.Callback.wrap(mycallback), node._id, name);
+ },
+
+ setTextNodeValueAsync: function(node, text, callback)
+ {
+ var mycallback = this._didApplyDomChange.bind(this, node, callback);
+ InspectorController.setTextNodeValue(WebInspector.Callback.wrap(mycallback), node._id, text);
+ },
+
+ _didApplyDomChange: function(node, callback, success)
+ {
+ if (!success)
+ return;
+ callback();
+ // TODO(pfeldman): Fix this hack.
+ var elem = WebInspector.panels.elements.treeOutline.findTreeElement(node);
+ if (elem) {
+ elem._updateTitle();
+ }
+ },
+
+ _attributesUpdated: function(nodeId, attrsArray)
+ {
+ var node = this._idToDOMNode[nodeId];
+ node._setAttributesPayload(attrsArray);
+ },
+
+ getNodeForId: function(nodeId) {
+ return this._idToDOMNode[nodeId];
+ },
+
+ _setDocumentElement: function(payload)
+ {
+ this.document = new WebInspector.DOMDocument(this, this._window);
+ this._idToDOMNode = { 0 : this.document };
+ this._setChildNodes(0, [payload]);
+ this.document.documentElement = this.document.firstChild;
+ this.document.documentElement.ownerDocument = this.document;
+ WebInspector.panels.elements.reset();
+ },
+
+ _setChildNodes: function(parentId, payloads)
+ {
+ var parent = this._idToDOMNode[parentId];
+ if (parent.children) {
+ return;
+ }
+ parent._setChildrenPayload(payloads);
+ this._bindNodes(parent.children);
+ },
+
+ _bindNodes: function(children)
+ {
+ for (var i = 0; i < children.length; ++i) {
+ var child = children[i];
+ this._idToDOMNode[child._id] = child;
+ if (child.children)
+ this._bindNodes(child.children);
+ }
+ },
+
+ _hasChildrenUpdated: function(nodeId, newValue)
+ {
+ var node = this._idToDOMNode[nodeId];
+ var outline = WebInspector.panels.elements.treeOutline;
+ var treeElement = outline.findTreeElement(node);
+ if (treeElement) {
+ treeElement.hasChildren = newValue;
+ treeElement.whitespaceIgnored = Preferences.ignoreWhitespace;
+ }
+ },
+
+ _childNodeInserted: function(parentId, prevId, payload)
+ {
+ var parent = this._idToDOMNode[parentId];
+ var prev = this._idToDOMNode[prevId];
+ var node = parent._insertChild(prev, payload);
+ this._idToDOMNode[node._id] = node;
+ var event = { target : node, relatedNode : parent };
+ this.document._fireDomEvent("DOMNodeInserted", event);
+ },
+
+ _childNodeRemoved: function(parentId, nodeId)
+ {
+ var parent = this._idToDOMNode[parentId];
+ var node = this._idToDOMNode[nodeId];
+ parent.removeChild_(node);
+ var event = { target : node, relatedNode : parent };
+ this.document._fireDomEvent("DOMNodeRemoved", event);
+ delete this._idToDOMNode[nodeId];
+ }
+}
+
+WebInspector.CSSStyleDeclaration = function(payload) {
+ this._id = payload.id;
+ this.width = payload.width;
+ this.height = payload.height;
+ this.__disabledProperties = payload.__disabledProperties;
+ this.__disabledPropertyValues = payload.__disabledPropertyValues;
+ this.__disabledPropertyPriorities = payload.__disabledPropertyPriorities;
+ this.uniqueStyleProperties = payload.uniqueStyleProperties;
+ this._shorthandValues = payload.shorthandValues;
+ this._propertyMap = {};
+ this._longhandProperties = {};
+ this.length = payload.properties.length;
+
+ for (var i = 0; i < this.length; ++i) {
+ var property = payload.properties[i];
+ var name = property.name;
+ this[i] = name;
+ this._propertyMap[name] = property;
+ }
+
+ // Index longhand properties.
+ for (var i = 0; i < this.uniqueStyleProperties.length; ++i) {
+ var name = this.uniqueStyleProperties[i];
+ var property = this._propertyMap[name];
+ if (property.shorthand) {
+ var longhands = this._longhandProperties[property.shorthand];
+ if (!longhands) {
+ longhands = [];
+ this._longhandProperties[property.shorthand] = longhands;
+ }
+ longhands.push(name);
+ }
+ }
+}
+
+WebInspector.CSSStyleDeclaration.parseStyle = function(payload)
+{
+ return new WebInspector.CSSStyleDeclaration(payload);
+}
+
+WebInspector.CSSStyleDeclaration.parseRule = function(payload)
+{
+ var rule = {};
+ rule._id = payload.id;
+ rule.selectorText = payload.selectorText;
+ rule.style = new WebInspector.CSSStyleDeclaration(payload.style);
+ rule.style.parentRule = rule;
+ rule.isUserAgent = payload.isUserAgent;
+ rule.isUser = payload.isUser;
+ if (payload.parentStyleSheet)
+ rule.parentStyleSheet = { href: payload.parentStyleSheet.href };
+
+ return rule;
+}
+
+WebInspector.CSSStyleDeclaration.prototype = {
+ getPropertyValue: function(name)
+ {
+ var property = this._propertyMap[name];
+ return property ? property.value : "";
+ },
+
+ getPropertyPriority: function(name)
+ {
+ var property = this._propertyMap[name];
+ return property ? property.priority : "";
+ },
+
+ getPropertyShorthand: function(name)
+ {
+ var property = this._propertyMap[name];
+ return property ? property.shorthand : "";
+ },
+
+ isPropertyImplicit: function(name)
+ {
+ var property = this._propertyMap[name];
+ return property ? property.implicit : "";
+ },
+
+ styleTextWithShorthands: function()
+ {
+ var cssText = "";
+ var foundProperties = {};
+ for (var i = 0; i < this.length; ++i) {
+ var individualProperty = this[i];
+ var shorthandProperty = this.getPropertyShorthand(individualProperty);
+ var propertyName = (shorthandProperty || individualProperty);
+
+ if (propertyName in foundProperties)
+ continue;
+
+ if (shorthandProperty) {
+ var value = this.getPropertyValue(shorthandProperty);
+ var priority = this.getShorthandPriority(shorthandProperty);
+ } else {
+ var value = this.getPropertyValue(individualProperty);
+ var priority = this.getPropertyPriority(individualProperty);
+ }
+
+ foundProperties[propertyName] = true;
+
+ cssText += propertyName + ": " + value;
+ if (priority)
+ cssText += " !" + priority;
+ cssText += "; ";
+ }
+
+ return cssText;
+ },
+
+ getLonghandProperties: function(name)
+ {
+ return this._longhandProperties[name] || [];
+ },
+
+ getShorthandValue: function(shorthandProperty)
+ {
+ return this._shorthandValues[shorthandProperty];
+ },
+
+ getShorthandPriority: function(shorthandProperty)
+ {
+ var priority = this.getPropertyPriority(shorthandProperty);
+ if (priority)
+ return priority;
+
+ var longhands = this._longhandProperties[shorthandProperty];
+ return longhands ? this.getPropertyPriority(longhands[0]) : null;
+ }
+}
+
+WebInspector.attributesUpdated = function()
+{
+ this.domAgent._attributesUpdated.apply(this.domAgent, arguments);
+}
+
+WebInspector.setDocumentElement = function()
+{
+ this.domAgent._setDocumentElement.apply(this.domAgent, arguments);
+}
+
+WebInspector.setChildNodes = function()
+{
+ this.domAgent._setChildNodes.apply(this.domAgent, arguments);
+}
+
+WebInspector.hasChildrenUpdated = function()
+{
+ this.domAgent._hasChildrenUpdated.apply(this.domAgent, arguments);
+}
+
+WebInspector.childNodeInserted = function()
+{
+ this.domAgent._childNodeInserted.apply(this.domAgent, arguments);
+ this._childNodeInserted.bind(this);
+}
+
+WebInspector.childNodeRemoved = function()
+{
+ this.domAgent._childNodeRemoved.apply(this.domAgent, arguments);
+ this._childNodeRemoved.bind(this);
+}
+
+WebInspector.didGetChildNodes = WebInspector.Callback.processCallback;
+WebInspector.didPerformSearch = WebInspector.Callback.processCallback;
+WebInspector.didApplyDomChange = WebInspector.Callback.processCallback;
+WebInspector.didRemoveAttribute = WebInspector.Callback.processCallback;
+WebInspector.didSetTextNodeValue = WebInspector.Callback.processCallback;
+
+// Temporary methods for DOMAgent migration.
+WebInspector.wrapNodeWithStyles = function(node, styles)
+{
+ var windowStub = new WebInspector.DOMWindow(null);
+ var docStub = new WebInspector.DOMDocument(null, windowStub);
+ var payload = {};
+ payload.nodeType = node.nodeType;
+ payload.nodeName = node.nodeName;
+ payload.nodeValue = node.nodeValue;
+ payload.attributes = [];
+ payload.childNodeCount = 0;
+
+ for (var i = 0; i < node.attributes.length; ++i) {
+ var attr = node.attributes[i];
+ payload.attributes.push(attr.name);
+ payload.attributes.push(attr.value);
+ }
+ var nodeStub = new WebInspector.DOMNode(docStub, payload);
+ nodeStub._setStyles(styles.computedStyle, styles.inlineStyle, styles.styleAttributes, styles.matchedCSSRules);
+ return nodeStub;
+}
+
+// Temporary methods that will be dispatched via InspectorController into the injected context.
+InspectorController.getStyles = function(nodeId, authorOnly, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.getStyles(nodeId, authorOnly));
+ }, 0)
+}
+
+InspectorController.getComputedStyle = function(nodeId, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.getComputedStyle(nodeId));
+ }, 0)
+}
+
+InspectorController.getInlineStyle = function(nodeId, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.getInlineStyle(nodeId));
+ }, 0)
+}
+
+InspectorController.applyStyleText = function(styleId, styleText, propertyName, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.applyStyleText(styleId, styleText, propertyName));
+ }, 0)
+}
+
+InspectorController.setStyleText = function(style, cssText, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.setStyleText(style, cssText));
+ }, 0)
+}
+
+InspectorController.toggleStyleEnabled = function(styleId, propertyName, disabled, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.toggleStyleEnabled(styleId, propertyName, disabled));
+ }, 0)
+}
+
+InspectorController.applyStyleRuleText = function(ruleId, newContent, selectedNode, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.applyStyleRuleText(ruleId, newContent, selectedNode));
+ }, 0)
+}
+
+InspectorController.addStyleSelector = function(newContent, callback)
+{
+ setTimeout(function() {
+ callback(InjectedScript.addStyleSelector(newContent));
+ }, 0)
+}
+
+InspectorController.setStyleProperty = function(styleId, name, value, callback) {
+ setTimeout(function() {
+ callback(InjectedScript.setStyleProperty(styleId, name, value));
+ }, 0)
+}
+
+InspectorController.getPrototypes = function(objectProxy, callback) {
+ setTimeout(function() {
+ callback(InjectedScript.getPrototypes(objectProxy));
+ }, 0)
+}
+
+InspectorController.getProperties = function(objectProxy, ignoreHasOwnProperty, callback) {
+ setTimeout(function() {
+ callback(InjectedScript.getProperties(objectProxy, ignoreHasOwnProperty));
+ }, 0)
+}
+
+InspectorController.setPropertyValue = function(objectProxy, propertyName, expression, callback) {
+ setTimeout(function() {
+ callback(InjectedScript.setPropertyValue(objectProxy, propertyName, expression));
+ }, 0)
+}
+
diff --git a/WebCore/inspector/front-end/DOMStorageDataGrid.js b/WebCore/inspector/front-end/DOMStorageDataGrid.js
index 9946415..0326bc7 100644
--- a/WebCore/inspector/front-end/DOMStorageDataGrid.js
+++ b/WebCore/inspector/front-end/DOMStorageDataGrid.js
@@ -38,39 +38,93 @@ WebInspector.DOMStorageDataGrid.prototype = {
return;
this._startEditing(event);
},
-
+
+ _startEditingColumnOfDataGridNode: function(node, column)
+ {
+ this._editing = true;
+ this._editingNode = node;
+ this._editingNode.select();
+ WebInspector.panels.databases._unregisterStorageEventListener();
+
+ var element = this._editingNode._element.children[column];
+ WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ window.getSelection().setBaseAndExtent(element, 0, element, 1);
+ },
+
_startEditing: function(event)
{
var element = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!element)
return;
+
this._editingNode = this.dataGridNodeFromEvent(event);
- if (!this._editingNode)
- return;
+ if (!this._editingNode) {
+ if (!this.creationNode)
+ return;
+ this._editingNode = this.creationNode;
+ }
+
+ // Force editing the "Key" column when editing the creation node
+ if (this._editingNode.isCreationNode)
+ return this._startEditingColumnOfDataGridNode(this._editingNode, 0);
+
this._editing = true;
-
+ WebInspector.panels.databases._unregisterStorageEventListener();
WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
-
- _editingCommitted: function(element, newText)
+
+ _editingCommitted: function(element, newText, oldText, context, moveDirection)
{
- if (element.hasStyleClass("0-column"))
- columnIdentifier = 0;
- else
- columnIdentifier = 1;
- textBeforeEditing = this._editingNode.data[columnIdentifier];
+ var columnIdentifier = (element.hasStyleClass("0-column") ? 0 : 1);
+ var textBeforeEditing = this._editingNode.data[columnIdentifier];
+ var currentEditingNode = this._editingNode;
+
+ function moveToNextIfNeeded(wasChange) {
+ if (!moveDirection)
+ return;
+
+ if (moveDirection === "forward") {
+ if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange)
+ return;
+
+ if (columnIdentifier === 0)
+ return this._startEditingColumnOfDataGridNode(currentEditingNode, 1);
+
+ var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
+ if (nextDataGridNode)
+ return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0);
+ if (currentEditingNode.isCreationNode && wasChange) {
+ addCreationNode(false);
+ return this._startEditingColumnOfDataGridNode(this.creationNode, 0);
+ }
+ return;
+ }
+
+ if (moveDirection === "backward") {
+ if (columnIdentifier === 1)
+ return this._startEditingColumnOfDataGridNode(currentEditingNode, 0);
+ var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true);
+
+ if (nextDataGridNode)
+ return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1);
+ return;
+ }
+ }
+
if (textBeforeEditing == newText) {
this._editingCancelled(element);
+ moveToNextIfNeeded.call(this, false);
return;
}
-
+
var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
if (domStorage) {
if (columnIdentifier == 0) {
if (domStorage.getItem(newText) != null) {
element.textContent = this._editingNode.data[0];
this._editingCancelled(element);
+ moveToNextIfNeeded.call(this, false);
return;
}
domStorage.removeItem(this._editingNode.data[0]);
@@ -81,19 +135,27 @@ WebInspector.DOMStorageDataGrid.prototype = {
this._editingNode.data[1] = newText;
}
}
-
+
+ if (this._editingNode.isCreationNode)
+ this.addCreationNode(false);
+
this._editingCancelled(element);
+ moveToNextIfNeeded.call(this, true);
},
-
+
_editingCancelled: function(element, context)
{
delete this._editing;
this._editingNode = null;
+ WebInspector.panels.databases._registerStorageEventListener();
},
-
+
deleteSelectedRow: function()
{
var node = this.selectedNode;
+ if (this.selectedNode.isCreationNode)
+ return;
+
var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
if (node && domStorage)
domStorage.removeItem(node.data[0]);
diff --git a/WebCore/inspector/front-end/DOMStorageItemsView.js b/WebCore/inspector/front-end/DOMStorageItemsView.js
index 912573e..fad6e3c 100644
--- a/WebCore/inspector/front-end/DOMStorageItemsView.js
+++ b/WebCore/inspector/front-end/DOMStorageItemsView.js
@@ -75,6 +75,7 @@ WebInspector.DOMStorageItemsView.prototype = {
else {
this._dataGrid = dataGrid;
this.element.appendChild(dataGrid.element);
+ this._dataGrid.updateWidths();
this.deleteButton.removeStyleClass("hidden");
}
}
@@ -89,6 +90,12 @@ WebInspector.DOMStorageItemsView.prototype = {
this.deleteButton.addStyleClass("hidden");
}
},
+
+ resize: function()
+ {
+ if (this._dataGrid)
+ this._dataGrid.updateWidths();
+ },
_deleteButtonClicked: function(event)
{
diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js
index 2fcb08c..42e001c 100644
--- a/WebCore/inspector/front-end/DataGrid.js
+++ b/WebCore/inspector/front-end/DataGrid.js
@@ -89,7 +89,8 @@ WebInspector.DataGrid = function(columns)
cell.className = "corner";
headerRow.appendChild(cell);
- this._headerTable.appendChild(columnGroup);
+ this._headerTableColumnGroup = columnGroup;
+ this._headerTable.appendChild(this._headerTableColumnGroup);
this.headerTableBody.appendChild(headerRow);
var fillerRow = document.createElement("tr");
@@ -99,8 +100,9 @@ WebInspector.DataGrid = function(columns)
var cell = document.createElement("td");
fillerRow.appendChild(cell);
}
-
- this._dataTable.appendChild(columnGroup.cloneNode(true));
+
+ this._dataTableColumnGroup = columnGroup.cloneNode(true);
+ this._dataTable.appendChild(this._dataTableColumnGroup);
this.dataTableBody.appendChild(fillerRow);
this.columns = columns || {};
@@ -114,6 +116,8 @@ WebInspector.DataGrid = function(columns)
this.selected = false;
this.dataGrid = this;
this.indentWidth = 15;
+ this.resizers = [];
+ this.columnWidthsInitialized = false;
}
WebInspector.DataGrid.prototype = {
@@ -160,6 +164,75 @@ WebInspector.DataGrid.prototype = {
return this._dataTableBody;
},
+
+ // Updates the widths of the table, including the positions of the column
+ // resizers.
+ //
+ // IMPORTANT: This function MUST be called once after the element of the
+ // DataGrid is attached to its parent element and every subsequent time the
+ // width of the parent element is changed in order to make it possible to
+ // resize the columns.
+ //
+ // If this function is not called after the DataGrid is attached to its
+ // parent element, then the DataGrid's columns will not be resizable.
+ updateWidths: function()
+ {
+ var headerTableColumns = this._headerTableColumnGroup.children;
+
+ var left = 0;
+ var tableWidth = this._dataTable.offsetWidth;
+ var numColumns = headerTableColumns.length;
+
+ if (!this.columnWidthsInitialized) {
+ // Give all the columns initial widths now so that during a resize,
+ // when the two columns that get resized get a percent value for
+ // their widths, all the other columns already have percent values
+ // for their widths.
+ for (var i = 0; i < numColumns; i++) {
+ var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
+ var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
+ this._headerTableColumnGroup.children[i].style.width = percentWidth;
+ this._dataTableColumnGroup.children[i].style.width = percentWidth;
+ }
+ this.columnWidthsInitialized = true;
+ }
+
+ // Make n - 1 resizers for n columns.
+ for (var i = 0; i < numColumns - 1; i++) {
+ var resizer = this.resizers[i];
+
+ if (!resizer) {
+ // This is the first call to updateWidth, so the resizers need
+ // to be created.
+ resizer = document.createElement("div");
+ resizer.addStyleClass("data-grid-resizer");
+ // This resizer is associated with the column to its right.
+ resizer.rightNeighboringColumnID = i + 1;
+ resizer.addEventListener("mousedown", this._startResizerDragging.bind(this), false);
+ this.element.appendChild(resizer);
+ this.resizers[i] = resizer;
+ }
+
+ // Get the width of the cell in the first (and only) row of the
+ // header table in order to determine the width of the column, since
+ // it is not possible to query a column for its width.
+ left += this.headerTableBody.rows[0].cells[i].offsetWidth;
+
+ resizer.style.left = left + "px";
+ }
+ },
+
+ addCreationNode: function(hasChildren)
+ {
+ if (this.creationNode)
+ this.creationNode.makeNormal();
+
+ var emptyData = {};
+ for (var column in this.columns)
+ emptyData[column] = '';
+ this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
+ this.appendChild(this.creationNode);
+ },
appendChild: function(child)
{
@@ -429,7 +502,63 @@ WebInspector.DataGrid.prototype = {
else
gridNode.expand();
}
- }
+ },
+
+ _startResizerDragging: function(event)
+ {
+ this.currentResizer = event.target;
+ if (!this.currentResizer.rightNeighboringColumnID)
+ return;
+ WebInspector.elementDragStart(this.lastResizer, this._resizerDragging.bind(this),
+ this._endResizerDragging.bind(this), event, "col-resize");
+ },
+
+ _resizerDragging: function(event)
+ {
+ var resizer = this.currentResizer;
+ if (!resizer)
+ return;
+
+ // Constrain the dragpoint to be within the containing div of the
+ // datagrid.
+ var dragPoint = event.clientX - this.element.totalOffsetLeft;
+ // Constrain the dragpoint to be within the space made up by the
+ // column directly to the left and the column directly to the right.
+ var leftEdgeOfPreviousColumn = 0;
+ var firstRowCells = this.headerTableBody.rows[0].cells;
+ for (var i = 0; i < resizer.rightNeighboringColumnID - 1; i++)
+ leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
+
+ var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[resizer.rightNeighboringColumnID - 1].offsetWidth + firstRowCells[resizer.rightNeighboringColumnID].offsetWidth;
+
+ // Give each column some padding so that they don't disappear.
+ var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
+ var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;
+
+ dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
+
+ resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";
+
+ var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%";
+ this._headerTableColumnGroup.children[resizer.rightNeighboringColumnID - 1].style.width = percentLeftColumn;
+ this._dataTableColumnGroup.children[resizer.rightNeighboringColumnID - 1].style.width = percentLeftColumn;
+
+ var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%";
+ this._headerTableColumnGroup.children[resizer.rightNeighboringColumnID].style.width = percentRightColumn;
+ this._dataTableColumnGroup.children[resizer.rightNeighboringColumnID].style.width = percentRightColumn;
+
+ event.preventDefault();
+ },
+
+ _endResizerDragging: function(event)
+ {
+ WebInspector.elementDragEnd(event);
+ this.currentResizer = null;
+ },
+
+ ColumnResizePadding: 10,
+
+ CenterResizerOverBorderAdjustment: 3,
}
WebInspector.DataGrid.prototype.__proto__ = WebInspector.Object.prototype;
@@ -883,3 +1012,19 @@ WebInspector.DataGridNode.prototype = {
}
WebInspector.DataGridNode.prototype.__proto__ = WebInspector.Object.prototype;
+
+WebInspector.CreationDataGridNode = function(data, hasChildren)
+{
+ WebInspector.DataGridNode.call(this, data, hasChildren);
+ this.isCreationNode = true;
+}
+
+WebInspector.CreationDataGridNode.prototype = {
+ makeNormal: function()
+ {
+ delete this.isCreationNode;
+ delete this.makeNormal;
+ }
+}
+
+WebInspector.CreationDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
diff --git a/WebCore/inspector/front-end/DatabaseQueryView.js b/WebCore/inspector/front-end/DatabaseQueryView.js
index 122707f..429c2c3 100644
--- a/WebCore/inspector/front-end/DatabaseQueryView.js
+++ b/WebCore/inspector/front-end/DatabaseQueryView.js
@@ -58,7 +58,7 @@ WebInspector.DatabaseQueryView.prototype = {
setTimeout(moveBackIfOutside.bind(this), 0);
},
- completions: function(wordRange, bestMatchOnly)
+ completions: function(wordRange, bestMatchOnly, completionsReadyCallback)
{
var prefix = wordRange.toString().toLowerCase();
if (!prefix.length)
@@ -85,7 +85,7 @@ WebInspector.DatabaseQueryView.prototype = {
accumulateMatches(this.database.tableNames.map(function(name) { return name + " " }));
accumulateMatches(["SELECT ", "FROM ", "WHERE ", "LIMIT ", "DELETE FROM ", "CREATE ", "DROP ", "TABLE ", "INDEX ", "UPDATE ", "INSERT INTO ", "VALUES ("]);
- return results;
+ completionsReadyCallback(results);
},
_promptKeyDown: function(event)
@@ -157,7 +157,7 @@ WebInspector.DatabaseQueryView.prototype = {
else if (error.code == 2)
var message = WebInspector.UIString("Database no longer has expected version.");
else
- var message = WebInspector.UIString("An unexpected error %s occured.", error.code);
+ var message = WebInspector.UIString("An unexpected error %s occurred.", error.code);
this._appendQueryResult(query, message, "error");
},
diff --git a/WebCore/inspector/front-end/DatabasesPanel.js b/WebCore/inspector/front-end/DatabasesPanel.js
index 4644b3b..a31e3ff 100644
--- a/WebCore/inspector/front-end/DatabasesPanel.js
+++ b/WebCore/inspector/front-end/DatabasesPanel.js
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -85,6 +86,7 @@ WebInspector.DatabasesPanel.prototype = {
{
WebInspector.Panel.prototype.show.call(this);
this._updateSidebarWidth();
+ this._registerStorageEventListener();
},
reset: function()
@@ -101,6 +103,8 @@ WebInspector.DatabasesPanel.prototype = {
this._databases = [];
+ this._unregisterStorageEventListener();
+
if (this._domStorage) {
var domStorageLength = this._domStorage.length;
for (var i = 0; i < domStorageLength; ++i) {
@@ -145,6 +149,32 @@ WebInspector.DatabasesPanel.prototype = {
this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
},
+ selectDatabase: function(db)
+ {
+ var database;
+ for (var i = 0, len = this._databases.length; i < len; ++i) {
+ database = this._databases[i];
+ if ( db === database.database ) {
+ this.showDatabase(database);
+ database._databasesTreeElement.select();
+ return;
+ }
+ }
+ },
+
+ selectDOMStorage: function(s)
+ {
+ var isLocalStorage = (s === InspectorController.inspectedWindow().localStorage);
+ for (var i = 0, len = this._domStorage.length; i < len; ++i) {
+ var storage = this._domStorage[i];
+ if ( isLocalStorage === storage.isLocalStorage ) {
+ this.showDOMStorage(storage);
+ storage._domStorageTreeElement.select();
+ return;
+ }
+ }
+ },
+
showDatabase: function(database, tableName)
{
if (!database)
@@ -175,7 +205,7 @@ WebInspector.DatabasesPanel.prototype = {
this.visibleView = view;
this.storageViewStatusBarItemsContainer.removeChildren();
- var statusBarItems = view.statusBarItems;
+ var statusBarItems = view.statusBarItems || [];
for (var i = 0; i < statusBarItems.length; ++i)
this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},
@@ -332,7 +362,7 @@ WebInspector.DatabasesPanel.prototype = {
var nodes = [];
var length = domStorage.length;
- for (index = 0; index < domStorage.length; index++) {
+ for (var index = 0; index < domStorage.length; index++) {
var data = {};
var key = String(domStorage.key(index));
@@ -365,10 +395,58 @@ WebInspector.DatabasesPanel.prototype = {
var length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.appendChild(nodes[i]);
+ dataGrid.addCreationNode(false);
if (length > 0)
nodes[0].selected = true;
return dataGrid;
},
+
+ resize: function()
+ {
+ var visibleView = this.visibleView;
+ if (visibleView && "resize" in visibleView)
+ visibleView.resize();
+ },
+
+ _registerStorageEventListener: function()
+ {
+ var inspectedWindow = InspectorController.inspectedWindow();
+ if (!inspectedWindow || !inspectedWindow.document)
+ return;
+
+ this._storageEventListener = InspectorController.wrapCallback(this._storageEvent.bind(this));
+ inspectedWindow.addEventListener("storage", this._storageEventListener, true);
+ },
+
+ _unregisterStorageEventListener: function()
+ {
+ if (!this._storageEventListener)
+ return;
+
+ var inspectedWindow = InspectorController.inspectedWindow();
+ if (!inspectedWindow || !inspectedWindow.document)
+ return;
+
+ inspectedWindow.removeEventListener("storage", this._storageEventListener, true);
+ delete this._storageEventListener;
+ },
+
+ _storageEvent: function(event)
+ {
+ if (!this._domStorage)
+ return;
+
+ var isLocalStorage = (event.storageArea === InspectorController.inspectedWindow().localStorage);
+ var domStorageLength = this._domStorage.length;
+ for (var i = 0; i < domStorageLength; ++i) {
+ var domStorage = this._domStorage[i];
+ if (isLocalStorage === domStorage.isLocalStorage) {
+ var view = domStorage._domStorageView;
+ if (this.visibleView && view === this.visibleView)
+ domStorage._domStorageView.update();
+ }
+ }
+ },
_startSidebarDragging: function(event)
{
@@ -409,6 +487,10 @@ WebInspector.DatabasesPanel.prototype = {
this.storageViews.style.left = width + "px";
this.storageViewStatusBarItemsContainer.style.left = width + "px";
this.sidebarResizeElement.style.left = (width - 3) + "px";
+
+ var visibleView = this.visibleView;
+ if (visibleView && "resize" in visibleView)
+ visibleView.resize();
}
}
diff --git a/WebCore/inspector/front-end/Drawer.js b/WebCore/inspector/front-end/Drawer.js
new file mode 100644
index 0000000..23dc483
--- /dev/null
+++ b/WebCore/inspector/front-end/Drawer.js
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.Drawer = function()
+{
+ WebInspector.View.call(this, document.getElementById("drawer"));
+
+ this.mainStatusBar = document.getElementById("main-status-bar");
+ this.mainStatusBar.addEventListener("mousedown", this._startStatusBarDragging.bind(this), true);
+ this.viewStatusBar = document.getElementById("other-drawer-status-bar-items");
+}
+
+WebInspector.Drawer.prototype = {
+ get visibleView()
+ {
+ return this._visibleView;
+ },
+
+ set visibleView(x)
+ {
+ if (this._visibleView === x) {
+ this.visible = !this.visible;
+ return;
+ }
+
+ var firstTime = !this._visibleView;
+ if (this._visibleView)
+ this._visibleView.hide();
+
+ this._visibleView = x;
+
+ if (x && !firstTime) {
+ this._safelyRemoveChildren();
+ this.viewStatusBar.removeChildren(); // optimize this? call old.detach()
+ x.attach(this.element, this.viewStatusBar);
+ x.show();
+ this.visible = true;
+ }
+ },
+
+ show: function()
+ {
+ if (this._animating || this.visible)
+ return;
+
+ if (this.visibleView)
+ this.visibleView.show();
+
+ WebInspector.View.prototype.show.call(this);
+
+ this._animating = true;
+
+ document.body.addStyleClass("drawer-visible");
+
+ var anchoredItems = document.getElementById("anchored-status-bar-items");
+
+ var animations = [
+ {element: document.getElementById("main"), end: {bottom: this.element.offsetHeight}},
+ {element: document.getElementById("main-status-bar"), start: {"padding-left": anchoredItems.offsetWidth - 1}, end: {"padding-left": 0}},
+ {element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 0}, end: {opacity: 1}}
+ ];
+
+ var consoleStatusBar = document.getElementById("drawer-status-bar");
+ consoleStatusBar.insertBefore(anchoredItems, consoleStatusBar.firstChild);
+
+ function animationFinished()
+ {
+ if ("updateStatusBarItems" in WebInspector.currentPanel)
+ WebInspector.currentPanel.updateStatusBarItems();
+ if (this.visibleView.afterShow)
+ this.visibleView.afterShow();
+ delete this._animating;
+ }
+
+ WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this));
+ },
+
+ hide: function()
+ {
+ if (this._animating || !this.visible)
+ return;
+
+ WebInspector.View.prototype.hide.call(this);
+
+ if (this.visibleView)
+ this.visibleView.hide();
+
+ this._animating = true;
+
+ if (this.element === WebInspector.currentFocusElement || this.element.isAncestor(WebInspector.currentFocusElement))
+ WebInspector.currentFocusElement = WebInspector.previousFocusElement;
+
+ var anchoredItems = document.getElementById("anchored-status-bar-items");
+
+ // Temporally set properties and classes to mimic the post-animation values so panels
+ // like Elements in their updateStatusBarItems call will size things to fit the final location.
+ document.getElementById("main-status-bar").style.setProperty("padding-left", (anchoredItems.offsetWidth - 1) + "px");
+ document.body.removeStyleClass("drawer-visible");
+ if ("updateStatusBarItems" in WebInspector.currentPanel)
+ WebInspector.currentPanel.updateStatusBarItems();
+ document.body.addStyleClass("drawer-visible");
+
+ var animations = [
+ {element: document.getElementById("main"), end: {bottom: 0}},
+ {element: document.getElementById("main-status-bar"), start: {"padding-left": 0}, end: {"padding-left": anchoredItems.offsetWidth - 1}},
+ {element: document.getElementById("other-drawer-status-bar-items"), start: {opacity: 1}, end: {opacity: 0}}
+ ];
+
+ function animationFinished()
+ {
+ var mainStatusBar = document.getElementById("main-status-bar");
+ mainStatusBar.insertBefore(anchoredItems, mainStatusBar.firstChild);
+ mainStatusBar.style.removeProperty("padding-left");
+ document.body.removeStyleClass("drawer-visible");
+ delete this._animating;
+ }
+
+ WebInspector.animateStyle(animations, window.event && window.event.shiftKey ? 2000 : 250, animationFinished.bind(this));
+ },
+
+ _safelyRemoveChildren: function()
+ {
+ var child = this.element.firstChild;
+ while (child) {
+ if (child.id !== "drawer-status-bar") {
+ var moveTo = child.nextSibling;
+ this.element.removeChild(child);
+ child = moveTo;
+ } else
+ child = child.nextSibling;
+ }
+ },
+
+ _startStatusBarDragging: function(event)
+ {
+ if (!this.visible || event.target !== document.getElementById("main-status-bar"))
+ return;
+
+ WebInspector.elementDragStart(document.getElementById("main-status-bar"), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), event, "row-resize");
+
+ this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop;
+
+ event.stopPropagation();
+ },
+
+ _statusBarDragging: function(event)
+ {
+ var mainElement = document.getElementById("main");
+
+ var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
+ height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - mainElement.totalOffsetTop - Preferences.minConsoleHeight);
+
+ mainElement.style.bottom = height + "px";
+ this.element.style.height = height + "px";
+
+ event.preventDefault();
+ event.stopPropagation();
+ },
+
+ _endStatusBarDragging: function(event)
+ {
+ WebInspector.elementDragEnd(event);
+
+ delete this._statusBarDragOffset;
+
+ event.stopPropagation();
+ }
+}
+
+WebInspector.Drawer.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index 3c9be54..ffa0000 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,6 +61,7 @@ WebInspector.ElementsPanel = function()
InspectorController.toggleNodeSearch();
this.panel.nodeSearchButton.removeStyleClass("toggled-on");
}
+ WebInspector.console.addInspectedNode(this._focusedDOMNode);
};
this.contentElement.appendChild(this.treeOutline.element);
@@ -95,7 +97,7 @@ WebInspector.ElementsPanel = function()
this.sidebarResizeElement.className = "sidebar-resizer-vertical";
this.sidebarResizeElement.addEventListener("mousedown", this.rightSidebarResizerDragStart.bind(this), false);
- this.nodeSearchButton = document.createElement("button");
+ this.nodeSearchButton = this.createStatusBarButton();
this.nodeSearchButton.title = WebInspector.UIString("Select an element in the page to inspect it.");
this.nodeSearchButton.id = "node-search-status-bar-item";
this.nodeSearchButton.className = "status-bar-item";
@@ -112,6 +114,9 @@ WebInspector.ElementsPanel = function()
this._nodeRemovedEventListener = InspectorController.wrapCallback(this._nodeRemoved.bind(this));
this._contentLoadedEventListener = InspectorController.wrapCallback(this._contentLoaded.bind(this));
+ this.stylesheet = null;
+ this.styles = {};
+
this.reset();
}
@@ -179,7 +184,7 @@ WebInspector.ElementsPanel.prototype = {
delete this.currentQuery;
this.searchCanceled();
- var inspectedWindow = InspectorController.inspectedWindow();
+ var inspectedWindow = Preferences.useDOMAgent ? WebInspector.domAgent.inspectedWindow : InspectorController.inspectedWindow();
if (!inspectedWindow || !inspectedWindow.document)
return;
@@ -516,6 +521,121 @@ WebInspector.ElementsPanel.prototype = {
this.updateMutationEventListeners(window);
},
+ renameSelector: function(oldIdentifier, newIdentifier, oldSelector, newSelector)
+ {
+ // TODO: Implement Shifting the oldSelector, and its contents to a newSelector
+ },
+
+ addStyleChange: function(identifier, style, property)
+ {
+ if (!style.parentRule)
+ return;
+
+ var selector = style.parentRule.selectorText;
+ if (!this.styles[identifier])
+ this.styles[identifier] = {};
+
+ if (!this.styles[identifier][selector])
+ this.styles[identifier][selector] = {};
+
+ if (!this.styles[identifier][selector][property])
+ WebInspector.styleChanges += 1;
+
+ this.styles[identifier][selector][property] = style.getPropertyValue(property);
+ },
+
+ removeStyleChange: function(identifier, style, property)
+ {
+ if (!style.parentRule)
+ return;
+
+ var selector = style.parentRule.selectorText;
+ if (!this.styles[identifier] || !this.styles[identifier][selector])
+ return;
+
+ if (this.styles[identifier][selector][property]) {
+ delete this.styles[identifier][selector][property];
+ WebInspector.styleChanges -= 1;
+ }
+ },
+
+ generateStylesheet: function()
+ {
+ if (!WebInspector.styleChanges)
+ return;
+
+ // Merge Down to Just Selectors
+ var mergedSelectors = {};
+ for (var identifier in this.styles) {
+ for (var selector in this.styles[identifier]) {
+ if (!mergedSelectors[selector])
+ mergedSelectors[selector] = this.styles[identifier][selector];
+ else { // merge on selector
+ var merge = {};
+ for (var property in mergedSelectors[selector])
+ merge[property] = mergedSelectors[selector][property];
+ for (var property in this.styles[identifier][selector]) {
+ if (!merge[property])
+ merge[property] = this.styles[identifier][selector][property];
+ else { // merge on property within a selector, include comment to notify user
+ var value1 = merge[property];
+ var value2 = this.styles[identifier][selector][property];
+
+ if (value1 === value2)
+ merge[property] = [value1];
+ else if (Object.type(value1) === "array")
+ merge[property].push(value2);
+ else
+ merge[property] = [value1, value2];
+ }
+ }
+ mergedSelectors[selector] = merge;
+ }
+ }
+ }
+
+ var builder = [];
+ builder.push("/**");
+ builder.push(" * Inspector Generated Stylesheet"); // UIString?
+ builder.push(" */\n");
+
+ var indent = " ";
+ function displayProperty(property, value, comment) {
+ if (comment)
+ return indent + "/* " + property + ": " + value + "; */";
+ else
+ return indent + property + ": " + value + ";";
+ }
+
+ for (var selector in mergedSelectors) {
+ var psuedoStyle = mergedSelectors[selector];
+ var properties = Object.properties(psuedoStyle);
+ if (properties.length) {
+ builder.push(selector + " {");
+ for (var i = 0; i < properties.length; ++i) {
+ var property = properties[i];
+ var value = psuedoStyle[property];
+ if (Object.type(value) !== "array")
+ builder.push(displayProperty(property, value));
+ else {
+ if (value.length === 1)
+ builder.push(displayProperty(property, value) + " /* merged from equivalent edits */"); // UIString?
+ else {
+ builder.push(indent + "/* There was a Conflict... There were Multiple Edits for '" + property + "' */"); // UIString?
+ for (var j = 0; j < value.length; ++j)
+ builder.push(displayProperty(property, value, true));
+ }
+ }
+ }
+ builder.push("}\n");
+ }
+ }
+
+ WebInspector.showConsole();
+ var result = builder.join("\n");
+ InspectorController.inspectedWindow().console.log(result);
+ },
+
_addMutationEventListeners: function(monitoredWindow)
{
monitoredWindow.document.addEventListener("DOMNodeInserted", this._nodeInsertedEventListener, true);
@@ -913,7 +1033,7 @@ WebInspector.ElementsPanel.prototype = {
{
var rightPadding = 20;
var errorWarningElement = document.getElementById("error-warning-count");
- if (!WebInspector.console.visible && errorWarningElement)
+ if (!WebInspector.drawer.visible && errorWarningElement)
rightPadding += errorWarningElement.offsetWidth;
return ((crumbs.totalOffsetLeft + crumbs.offsetWidth + rightPadding) < window.innerWidth);
}
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index 2da2f10..ef53209 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -255,6 +256,9 @@ WebInspector.ElementsTreeElement = function(node)
// The title will be updated in onattach.
TreeElement.call(this, "", node, titleInfo.hasChildren);
+
+ if (this.representedObject.nodeType == Node.ELEMENT_NODE)
+ this._canAddAttributes = true;
}
WebInspector.ElementsTreeElement.prototype = {
@@ -296,9 +300,36 @@ WebInspector.ElementsTreeElement.prototype = {
this.listItemElement.addStyleClass("hovered");
} else
this.listItemElement.removeStyleClass("hovered");
+ if (this._canAddAttributes)
+ this.toggleNewAttributeButton();
}
},
+ toggleNewAttributeButton: function()
+ {
+ function removeWhenEditing(event)
+ {
+ if (this._addAttributeElement && this._addAttributeElement.parentNode)
+ this._addAttributeElement.parentNode.removeChild(this._addAttributeElement);
+ delete this._addAttributeElement;
+ }
+
+ if (!this._addAttributeElement && this._hovered && !this._editing) {
+ var span = document.createElement("span");
+ span.className = "add-attribute";
+ span.textContent = "\u2026";
+ span.addEventListener("dblclick", removeWhenEditing.bind(this), false);
+ this._addAttributeElement = span;
+
+ var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
+ this._insertInLastAttributePosition(tag, span);
+ } else if (!this._hovered && this._addAttributeElement) {
+ if (this._addAttributeElement.parentNode)
+ this._addAttributeElement.parentNode.removeChild(this._addAttributeElement);
+ delete this._addAttributeElement;
+ }
+ },
+
updateSelection: function()
{
var listItemElement = this.listItemElement;
@@ -483,7 +514,7 @@ WebInspector.ElementsTreeElement.prototype = {
if (this._editing)
return;
- if (this._startEditing(event))
+ if (this._startEditing(event, treeElement))
return;
if (this.treeOutline.panel) {
@@ -495,7 +526,20 @@ WebInspector.ElementsTreeElement.prototype = {
this.expand();
},
- _startEditing: function(event)
+ _insertInLastAttributePosition: function(tag, node)
+ {
+ if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
+ tag.insertBefore(node, tag.lastChild);
+ else {
+ var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
+ tag.textContent = '';
+ tag.appendChild(document.createTextNode('<'+nodeName));
+ tag.appendChild(node);
+ tag.appendChild(document.createTextNode('>'));
+ }
+ },
+
+ _startEditing: function(event, treeElement)
{
if (this.treeOutline.focusedDOMNode != this.representedObject)
return;
@@ -509,12 +553,51 @@ WebInspector.ElementsTreeElement.prototype = {
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
if (attribute)
- return this._startEditingAttribute(attribute, event);
+ return this._startEditingAttribute(attribute, event.target);
+
+ var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
+ if (newAttribute)
+ return this._addNewAttribute(treeElement.listItemElement);
return false;
},
- _startEditingAttribute: function(attribute, event)
+ _addNewAttribute: function(listItemElement)
+ {
+ var attr = document.createElement("span");
+ attr.className = "webkit-html-attribute";
+ attr.style.marginLeft = "2px"; // overrides the .editing margin rule
+ attr.style.marginRight = "2px"; // overrides the .editing margin rule
+ var name = document.createElement("span");
+ name.className = "webkit-html-attribute-name new-attribute";
+ name.textContent = " ";
+ var value = document.createElement("span");
+ value.className = "webkit-html-attribute-value";
+ attr.appendChild(name);
+ attr.appendChild(value);
+
+ var tag = listItemElement.getElementsByClassName("webkit-html-tag")[0];
+ this._insertInLastAttributePosition(tag, attr);
+ return this._startEditingAttribute(attr, attr);
+ },
+
+ _triggerEditAttribute: function(attributeName)
+ {
+ var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
+ for (var i = 0, len = attributeElements.length; i < len; ++i) {
+ if (attributeElements[i].textContent === attributeName) {
+ for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
+ if (elem.nodeType !== Node.ELEMENT_NODE)
+ continue;
+
+ if (elem.hasStyleClass("webkit-html-attribute-value"))
+ return this._startEditingAttribute(attributeElements[i].parentNode, elem);
+ }
+ }
+ }
+ },
+
+ _startEditingAttribute: function(attribute, elementForSelection)
{
if (WebInspector.isBeingEdited(attribute))
return true;
@@ -545,7 +628,7 @@ WebInspector.ElementsTreeElement.prototype = {
this._editing = true;
WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
- window.getSelection().setBaseAndExtent(event.target, 0, event.target, 1);
+ window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
return true;
},
@@ -563,15 +646,56 @@ WebInspector.ElementsTreeElement.prototype = {
return true;
},
- _attributeEditingCommitted: function(element, newText, oldText, attributeName)
+ _attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
delete this._editing;
+ // Before we do anything, determine where we should move
+ // next based on the current element's settings
+ var moveToAttribute;
+ var newAttribute;
+ if (moveDirection) {
+ var found = false;
+ var attributes = this.representedObject.attributes;
+ for (var i = 0, len = attributes.length; i < len; ++i) {
+ if (attributes[i].name === attributeName) {
+ found = true;
+ if (moveDirection === "backward" && i > 0)
+ moveToAttribute = attributes[i - 1].name;
+ else if (moveDirection === "forward" && i < attributes.length - 1)
+ moveToAttribute = attributes[i + 1].name;
+ else if (moveDirection === "forward" && i === attributes.length - 1)
+ newAttribute = true;
+ }
+ }
+
+ if (!found && moveDirection === "backward")
+ moveToAttribute = attributes[attributes.length - 1].name;
+ else if (!found && moveDirection === "forward" && !/^\s*$/.test(newText))
+ newAttribute = true;
+ }
+
+ function moveToNextAttributeIfNeeded() {
+ if (moveToAttribute)
+ this._triggerEditAttribute(moveToAttribute);
+ else if (newAttribute)
+ this._addNewAttribute(this.listItemElement);
+ }
+
var parseContainerElement = document.createElement("span");
parseContainerElement.innerHTML = "<span " + newText + "></span>";
var parseElement = parseContainerElement.firstChild;
- if (!parseElement || !parseElement.hasAttributes()) {
- this._editingCancelled(element, context);
+
+ if (!parseElement) {
+ this._editingCancelled(element, attributeName);
+ moveToNextAttributeIfNeeded.call(this);
+ return;
+ }
+
+ if (!parseElement.hasAttributes()) {
+ InspectorController.inspectedWindow().Element.prototype.removeAttribute.call(this.representedObject, attributeName);
+ this._updateTitle();
+ moveToNextAttributeIfNeeded.call(this);
return;
}
@@ -579,7 +703,9 @@ WebInspector.ElementsTreeElement.prototype = {
for (var i = 0; i < parseElement.attributes.length; ++i) {
var attr = parseElement.attributes[i];
foundOriginalAttribute = foundOriginalAttribute || attr.name === attributeName;
- InspectorController.inspectedWindow().Element.prototype.setAttribute.call(this.representedObject, attr.name, attr.value);
+ try {
+ InspectorController.inspectedWindow().Element.prototype.setAttribute.call(this.representedObject, attr.name, attr.value);
+ } catch(e) {} // ignore invalid attribute (innerHTML doesn't throw errors, but this can)
}
if (!foundOriginalAttribute)
@@ -588,6 +714,8 @@ WebInspector.ElementsTreeElement.prototype = {
this._updateTitle();
this.treeOutline.focusedNodeChanged(true);
+
+ moveToNextAttributeIfNeeded.call(this);
},
_textNodeEditingCommitted: function(element, newText)
diff --git a/WebCore/inspector/front-end/Images/clearConsoleButtonGlyph.png b/WebCore/inspector/front-end/Images/clearConsoleButtonGlyph.png
new file mode 100644
index 0000000..b1f9465
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/clearConsoleButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/clearConsoleButtons.png b/WebCore/inspector/front-end/Images/clearConsoleButtons.png
deleted file mode 100644
index 140a4fb..0000000
--- a/WebCore/inspector/front-end/Images/clearConsoleButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/consoleButtonGlyph.png b/WebCore/inspector/front-end/Images/consoleButtonGlyph.png
new file mode 100644
index 0000000..d10d43c
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/consoleButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/consoleButtons.png b/WebCore/inspector/front-end/Images/consoleButtons.png
deleted file mode 100644
index fb5f089..0000000
--- a/WebCore/inspector/front-end/Images/consoleButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/dockButtonGlyph.png b/WebCore/inspector/front-end/Images/dockButtonGlyph.png
new file mode 100644
index 0000000..7052f4b
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/dockButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/dockButtons.png b/WebCore/inspector/front-end/Images/dockButtons.png
deleted file mode 100644
index 4b01d66..0000000
--- a/WebCore/inspector/front-end/Images/dockButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/enableButtons.png b/WebCore/inspector/front-end/Images/enableButtons.png
deleted file mode 100644
index facee60..0000000
--- a/WebCore/inspector/front-end/Images/enableButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/enableOutlineButtonGlyph.png b/WebCore/inspector/front-end/Images/enableOutlineButtonGlyph.png
new file mode 100644
index 0000000..85e0bd6
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/enableOutlineButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/enableSolidButtonGlyph.png b/WebCore/inspector/front-end/Images/enableSolidButtonGlyph.png
new file mode 100644
index 0000000..25b2e96
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/enableSolidButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/excludeButtonGlyph.png b/WebCore/inspector/front-end/Images/excludeButtonGlyph.png
new file mode 100644
index 0000000..5128576
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/excludeButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/excludeButtons.png b/WebCore/inspector/front-end/Images/excludeButtons.png
deleted file mode 100644
index f1c53a9..0000000
--- a/WebCore/inspector/front-end/Images/excludeButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/focusButtonGlyph.png b/WebCore/inspector/front-end/Images/focusButtonGlyph.png
new file mode 100644
index 0000000..b71807c
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/focusButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/focusButtons.png b/WebCore/inspector/front-end/Images/focusButtons.png
deleted file mode 100644
index 47eaa04..0000000
--- a/WebCore/inspector/front-end/Images/focusButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/largerResourcesButtonGlyph.png b/WebCore/inspector/front-end/Images/largerResourcesButtonGlyph.png
new file mode 100644
index 0000000..71256d6
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/largerResourcesButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/largerResourcesButtons.png b/WebCore/inspector/front-end/Images/largerResourcesButtons.png
deleted file mode 100644
index caf3f14..0000000
--- a/WebCore/inspector/front-end/Images/largerResourcesButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/nodeSearchButtonGlyph.png b/WebCore/inspector/front-end/Images/nodeSearchButtonGlyph.png
new file mode 100644
index 0000000..faf5df2
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/nodeSearchButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/nodeSearchButtons.png b/WebCore/inspector/front-end/Images/nodeSearchButtons.png
deleted file mode 100644
index 0599bd4..0000000
--- a/WebCore/inspector/front-end/Images/nodeSearchButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/pauseOnExceptionButtonGlyph.png b/WebCore/inspector/front-end/Images/pauseOnExceptionButtonGlyph.png
new file mode 100644
index 0000000..c3cec5f
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/pauseOnExceptionButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/pauseOnExceptionButtons.png b/WebCore/inspector/front-end/Images/pauseOnExceptionButtons.png
deleted file mode 100644
index a4dd33a..0000000
--- a/WebCore/inspector/front-end/Images/pauseOnExceptionButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/percentButtonGlyph.png b/WebCore/inspector/front-end/Images/percentButtonGlyph.png
new file mode 100644
index 0000000..0ace3b7
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/percentButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/percentButtons.png b/WebCore/inspector/front-end/Images/percentButtons.png
deleted file mode 100644
index 2635b24..0000000
--- a/WebCore/inspector/front-end/Images/percentButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/recordButtonGlyph.png b/WebCore/inspector/front-end/Images/recordButtonGlyph.png
new file mode 100644
index 0000000..bfdad1a
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/recordButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/recordButtons.png b/WebCore/inspector/front-end/Images/recordButtons.png
deleted file mode 100644
index 3676154..0000000
--- a/WebCore/inspector/front-end/Images/recordButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/recordToggledButtonGlyph.png b/WebCore/inspector/front-end/Images/recordToggledButtonGlyph.png
new file mode 100644
index 0000000..2c22f87
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/recordToggledButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/reloadButtonGlyph.png b/WebCore/inspector/front-end/Images/reloadButtonGlyph.png
new file mode 100644
index 0000000..28e047a
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/reloadButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/reloadButtons.png b/WebCore/inspector/front-end/Images/reloadButtons.png
deleted file mode 100644
index 1e45671..0000000
--- a/WebCore/inspector/front-end/Images/reloadButtons.png
+++ /dev/null
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/resourcesSilhouette.png b/WebCore/inspector/front-end/Images/resourcesSilhouette.png
new file mode 100644
index 0000000..9c8bb53
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/resourcesSilhouette.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/undockButtonGlyph.png b/WebCore/inspector/front-end/Images/undockButtonGlyph.png
new file mode 100644
index 0000000..eed2b65
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/undockButtonGlyph.png
Binary files differ
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
new file mode 100644
index 0000000..4611b48
--- /dev/null
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.
+ */
+
+var InjectedScript = {
+ _styles: {},
+ _styleRules: {},
+ _lastStyleId: 0,
+ _lastStyleRuleId: 0
+};
+
+InjectedScript.getStyles = function(nodeId, authorOnly)
+{
+ var node = InjectedScript._nodeForId(nodeId);
+ if (!node)
+ return false;
+ var matchedRules = InjectedScript._window().getMatchedCSSRules(node, "", authorOnly);
+ var matchedCSSRules = [];
+ for (var i = 0; matchedRules && i < matchedRules.length; ++i)
+ matchedCSSRules.push(InjectedScript._serializeRule(matchedRules[i]));
+
+ var styleAttributes = {};
+ var attributes = node.attributes;
+ for (var i = 0; attributes && i < attributes.length; ++i) {
+ if (attributes[i].style)
+ styleAttributes[attributes[i].name] = InjectedScript._serializeStyle(attributes[i].style, true);
+ }
+ var result = {};
+ result.inlineStyle = InjectedScript._serializeStyle(node.style, true);
+ result.computedStyle = InjectedScript._serializeStyle(InjectedScript._window().getComputedStyle(node));
+ result.matchedCSSRules = matchedCSSRules;
+ result.styleAttributes = styleAttributes;
+ return result;
+}
+
+InjectedScript.getComputedStyle = function(nodeId)
+{
+ var node = InjectedScript._nodeForId(nodeId);
+ if (!node)
+ return false;
+ return InjectedScript._serializeStyle(InjectedScript._window().getComputedStyle(node));
+}
+
+InjectedScript.getInlineStyle = function(nodeId)
+{
+ var node = InjectedScript._nodeForId(nodeId);
+ if (!node)
+ return false;
+ return InjectedScript._serializeStyle(node.style, true);
+}
+
+InjectedScript.applyStyleText = function(styleId, styleText, propertyName)
+{
+ var style = InjectedScript._styles[styleId];
+ if (!style)
+ return false;
+
+ var styleTextLength = styleText.length;
+
+ // Create a new element to parse the user input CSS.
+ var parseElement = document.createElement("span");
+ parseElement.setAttribute("style", styleText);
+
+ var tempStyle = parseElement.style;
+ if (tempStyle.length || !styleTextLength) {
+ // The input was parsable or the user deleted everything, so remove the
+ // original property from the real style declaration. If this represents
+ // a shorthand remove all the longhand properties.
+ if (style.getPropertyShorthand(propertyName)) {
+ var longhandProperties = InjectedScript._getLonghandProperties(style, propertyName);
+ for (var i = 0; i < longhandProperties.length; ++i)
+ style.removeProperty(longhandProperties[i]);
+ } else
+ style.removeProperty(propertyName);
+ }
+
+ if (!tempStyle.length)
+ return false;
+
+ // Iterate of the properties on the test element's style declaration and
+ // add them to the real style declaration. We take care to move shorthands.
+ var foundShorthands = {};
+ var changedProperties = [];
+ var uniqueProperties = InjectedScript._getUniqueStyleProperties(tempStyle);
+ for (var i = 0; i < uniqueProperties.length; ++i) {
+ var name = uniqueProperties[i];
+ var shorthand = tempStyle.getPropertyShorthand(name);
+
+ if (shorthand && shorthand in foundShorthands)
+ continue;
+
+ if (shorthand) {
+ var value = InjectedScript._getShorthandValue(tempStyle, shorthand);
+ var priority = InjectedScript._getShorthandPriority(tempStyle, shorthand);
+ foundShorthands[shorthand] = true;
+ } else {
+ var value = tempStyle.getPropertyValue(name);
+ var priority = tempStyle.getPropertyPriority(name);
+ }
+
+ // Set the property on the real style declaration.
+ style.setProperty((shorthand || name), value, priority);
+ changedProperties.push(shorthand || name);
+ }
+ return [InjectedScript._serializeStyle(style, true), changedProperties];
+}
+
+InjectedScript.setStyleText = function(style, cssText)
+{
+ style.cssText = cssText;
+}
+
+InjectedScript.toggleStyleEnabled = function(styleId, propertyName, disabled)
+{
+ var style = InjectedScript._styles[styleId];
+ if (!style)
+ return false;
+
+ if (disabled) {
+ if (!style.__disabledPropertyValues || !style.__disabledPropertyPriorities) {
+ var inspectedWindow = InjectedScript._window();
+ style.__disabledProperties = new inspectedWindow.Object;
+ style.__disabledPropertyValues = new inspectedWindow.Object;
+ style.__disabledPropertyPriorities = new inspectedWindow.Object;
+ }
+
+ style.__disabledPropertyValues[propertyName] = style.getPropertyValue(propertyName);
+ style.__disabledPropertyPriorities[propertyName] = style.getPropertyPriority(propertyName);
+
+ if (style.getPropertyShorthand(propertyName)) {
+ var longhandProperties = InjectedScript._getLonghandProperties(style, propertyName);
+ for (var i = 0; i < longhandProperties.length; ++i) {
+ style.__disabledProperties[longhandProperties[i]] = true;
+ style.removeProperty(longhandProperties[i]);
+ }
+ } else {
+ style.__disabledProperties[propertyName] = true;
+ style.removeProperty(propertyName);
+ }
+ } else if (style.__disabledProperties && style.__disabledProperties[propertyName]) {
+ var value = style.__disabledPropertyValues[propertyName];
+ var priority = style.__disabledPropertyPriorities[propertyName];
+
+ style.setProperty(propertyName, value, priority);
+ delete style.__disabledProperties[propertyName];
+ delete style.__disabledPropertyValues[propertyName];
+ delete style.__disabledPropertyPriorities[propertyName];
+ }
+ return InjectedScript._serializeStyle(style, true);
+}
+
+InjectedScript.applyStyleRuleText = function(ruleId, newContent, selectedNode)
+{
+ var rule = InjectedScript._styleRules[ruleId];
+ if (!rule)
+ return false;
+
+ try {
+ var stylesheet = rule.parentStyleSheet;
+ stylesheet.addRule(newContent);
+ var newRule = stylesheet.cssRules[stylesheet.cssRules.length - 1];
+ newRule.style.cssText = rule.style.cssText;
+
+ var parentRules = stylesheet.cssRules;
+ for (var i = 0; i < parentRules.length; ++i) {
+ if (parentRules[i] === rule) {
+ rule.parentStyleSheet.removeRule(i);
+ break;
+ }
+ }
+
+ var nodes = selectedNode.ownerDocument.querySelectorAll(newContent);
+ for (var i = 0; i < nodes.length; ++i) {
+ if (nodes[i] === selectedNode) {
+ return [InjectedScript._serializeRule(newRule), true];
+ }
+ }
+ return [InjectedScript._serializeRule(newRule), false];
+ } catch(e) {
+ // Report invalid syntax.
+ return false;
+ }
+}
+
+InjectedScript.addStyleSelector = function(newContent)
+{
+ var stylesheet = InjectedScript.stylesheet;
+ if (!stylesheet) {
+ var inspectedDocument = InjectedScript._window().document;
+ var head = inspectedDocument.getElementsByTagName("head")[0];
+ var styleElement = inspectedDocument.createElement("style");
+ styleElement.type = "text/css";
+ head.appendChild(styleElement);
+ stylesheet = inspectedDocument.styleSheets[inspectedDocument.styleSheets.length - 1];
+ InjectedScript.stylesheet = stylesheet;
+ }
+
+ try {
+ stylesheet.addRule(newContent);
+ } catch (e) {
+ // Invalid Syntax for a Selector
+ return false;
+ }
+
+ return InjectedScript._serializeRule(stylesheet.cssRules[stylesheet.cssRules.length - 1]);
+}
+
+InjectedScript.setStyleProperty = function(styleId, name, value) {
+ var style = InjectedScript._styles[styleId];
+ if (!style)
+ return false;
+
+ style.setProperty(name, value, "");
+ return true;
+}
+
+InjectedScript._serializeRule = function(rule)
+{
+ var parentStyleSheet = rule.parentStyleSheet;
+
+ var ruleValue = {};
+ ruleValue.selectorText = rule.selectorText;
+ if (parentStyleSheet) {
+ ruleValue.parentStyleSheet = {};
+ ruleValue.parentStyleSheet.href = parentStyleSheet.href;
+ }
+ ruleValue.isUserAgent = parentStyleSheet && !parentStyleSheet.ownerNode && !parentStyleSheet.href;
+ ruleValue.isUser = parentStyleSheet && parentStyleSheet.ownerNode && parentStyleSheet.ownerNode.nodeName == "#document";
+
+ // Bind editable scripts only.
+ var doBind = !ruleValue.isUserAgent && !ruleValue.isUser;
+ ruleValue.style = InjectedScript._serializeStyle(rule.style, doBind);
+
+ if (doBind) {
+ if (!rule._id) {
+ rule._id = InjectedScript._lastStyleRuleId++;
+ InjectedScript._styleRules[rule._id] = rule;
+ }
+ ruleValue.id = rule._id;
+ }
+ return ruleValue;
+}
+
+InjectedScript._serializeStyle = function(style, doBind)
+{
+ var result = {};
+ result.width = style.width;
+ result.height = style.height;
+ result.__disabledProperties = style.__disabledProperties;
+ result.__disabledPropertyValues = style.__disabledPropertyValues;
+ result.__disabledPropertyPriorities = style.__disabledPropertyPriorities;
+ result.properties = [];
+ result.shorthandValues = {};
+ var foundShorthands = {};
+ for (var i = 0; i < style.length; ++i) {
+ var property = {};
+ var name = style[i];
+ property.name = name;
+ property.priority = style.getPropertyPriority(name);
+ property.implicit = style.isPropertyImplicit(name);
+ var shorthand = style.getPropertyShorthand(name);
+ property.shorthand = shorthand;
+ if (shorthand && !(shorthand in foundShorthands)) {
+ foundShorthands[shorthand] = true;
+ result.shorthandValues[shorthand] = InjectedScript._getShorthandValue(style, shorthand);
+ }
+ property.value = style.getPropertyValue(name);
+ result.properties.push(property);
+ }
+ result.uniqueStyleProperties = InjectedScript._getUniqueStyleProperties(style);
+
+ if (doBind) {
+ if (!style._id) {
+ style._id = InjectedScript._lastStyleId++;
+ InjectedScript._styles[style._id] = style;
+ }
+ result.id = style._id;
+ }
+ return result;
+}
+
+InjectedScript._getUniqueStyleProperties = function(style)
+{
+ var properties = [];
+ var foundProperties = {};
+
+ for (var i = 0; i < style.length; ++i) {
+ var property = style[i];
+ if (property in foundProperties)
+ continue;
+ foundProperties[property] = true;
+ properties.push(property);
+ }
+
+ return properties;
+}
+
+
+InjectedScript._getLonghandProperties = function(style, shorthandProperty)
+{
+ var properties = [];
+ var foundProperties = {};
+
+ for (var i = 0; i < style.length; ++i) {
+ var individualProperty = style[i];
+ if (individualProperty in foundProperties || style.getPropertyShorthand(individualProperty) !== shorthandProperty)
+ continue;
+ foundProperties[individualProperty] = true;
+ properties.push(individualProperty);
+ }
+
+ return properties;
+}
+
+InjectedScript._getShorthandValue = function(style, shorthandProperty)
+{
+ var value = style.getPropertyValue(shorthandProperty);
+ if (!value) {
+ // Some shorthands (like border) return a null value, so compute a shorthand value.
+ // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 is fixed.
+
+ var foundProperties = {};
+ for (var i = 0; i < style.length; ++i) {
+ var individualProperty = style[i];
+ if (individualProperty in foundProperties || style.getPropertyShorthand(individualProperty) !== shorthandProperty)
+ continue;
+
+ var individualValue = style.getPropertyValue(individualProperty);
+ if (style.isPropertyImplicit(individualProperty) || individualValue === "initial")
+ continue;
+
+ foundProperties[individualProperty] = true;
+
+ if (!value)
+ value = "";
+ else if (value.length)
+ value += " ";
+ value += individualValue;
+ }
+ }
+ return value;
+}
+
+InjectedScript._getShorthandPriority = function(style, shorthandProperty)
+{
+ var priority = style.getPropertyPriority(shorthandProperty);
+ if (!priority) {
+ for (var i = 0; i < style.length; ++i) {
+ var individualProperty = style[i];
+ if (style.getPropertyShorthand(individualProperty) !== shorthandProperty)
+ continue;
+ priority = style.getPropertyPriority(individualProperty);
+ break;
+ }
+ }
+ return priority;
+}
+
+InjectedScript.getPrototypes = function(nodeId)
+{
+ var node = InjectedScript._nodeForId(nodeId);
+ if (!node)
+ return false;
+
+ var result = [];
+ for (var prototype = node; prototype; prototype = prototype.__proto__) {
+ var title = Object.describe(prototype);
+ if (title.match(/Prototype$/)) {
+ title = title.replace(/Prototype$/, "");
+ }
+ result.push(title);
+ }
+ return result;
+}
+
+InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty)
+{
+ var object = InjectedScript._resolveObject(objectProxy);
+ if (!object)
+ return false;
+
+ var properties = [];
+ // Go over properties, prepare results.
+ for (var propertyName in object) {
+ if (!ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
+ continue;
+
+ //TODO: remove this once object becomes really remote.
+ if (propertyName === "__treeElementIdentifier")
+ continue;
+ var property = {};
+ property.name = propertyName;
+ var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
+ if (!property.isGetter) {
+ var childObject = object[propertyName];
+ property.type = typeof childObject;
+ property.textContent = Object.describe(childObject, true);
+ property.parentObjectProxy = objectProxy;
+ var parentPath = objectProxy.path.slice();
+ property.childObjectProxy = {
+ objectId : objectProxy.objectId,
+ path : parentPath.splice(parentPath.length, 0, propertyName),
+ protoDepth : objectProxy.protoDepth
+ };
+ if (childObject && (property.type === "object" || property.type === "function")) {
+ for (var subPropertyName in childObject) {
+ if (propertyName === "__treeElementIdentifier")
+ continue;
+ property.hasChildren = true;
+ break;
+ }
+ }
+ } else {
+ // FIXME: this should show something like "getter" (bug 16734).
+ property.textContent = "\u2014"; // em dash
+ property.isGetter = true;
+ }
+ properties.push(property);
+ }
+ return properties;
+}
+
+InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression)
+{
+ var object = InjectedScript._resolveObject(objectProxy);
+ if (!object)
+ return false;
+
+ var expressionLength = expression.length;
+ if (!expressionLength) {
+ delete object[propertyName];
+ return !(propertyName in object);
+ }
+
+ try {
+ // Surround the expression in parenthesis so the result of the eval is the result
+ // of the whole expression not the last potential sub-expression.
+
+ // There is a regression introduced here: eval is now happening against global object,
+ // not call frame while on a breakpoint.
+ // TODO: bring evaluation against call frame back.
+ var result = InjectedScript._window().eval("(" + expression + ")");
+ // Store the result in the property.
+ object[propertyName] = result;
+ return true;
+ } catch(e) {
+ try {
+ var result = InjectedScript._window().eval("\"" + expression.escapeCharacters("\"") + "\"");
+ object[propertyName] = result;
+ return true;
+ } catch(e) {
+ return false;
+ }
+ }
+}
+
+InjectedScript._resolveObject = function(objectProxy)
+{
+ var object = InjectedScript._objectForId(objectProxy.objectId);
+ var path = objectProxy.path;
+ var protoDepth = objectProxy.protoDepth;
+
+ // Follow the property path.
+ for (var i = 0; object && i < path.length; ++i)
+ object = object[path[i]];
+
+ // Get to the necessary proto layer.
+ for (var i = 0; object && i < protoDepth; ++i)
+ object = object.__proto__;
+
+ return object;
+}
+
+InjectedScript._window = function()
+{
+ // TODO: replace with 'return window;' once this script is injected into
+ // the page's context.
+ return InspectorController.inspectedWindow();
+}
+
+InjectedScript._nodeForId = function(nodeId)
+{
+ // TODO: replace with node lookup in the InspectorDOMAgent once DOMAgent nodes are used.
+ return nodeId;
+}
+
+InjectedScript._objectForId = function(objectId)
+{
+ // TODO: replace with node lookups for node ids and evaluation result lookups for the rest of ids.
+ return objectId;
+}
diff --git a/WebCore/inspector/front-end/KeyboardShortcut.js b/WebCore/inspector/front-end/KeyboardShortcut.js
new file mode 100644
index 0000000..ed28a48
--- /dev/null
+++ b/WebCore/inspector/front-end/KeyboardShortcut.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.KeyboardShortcut = function()
+{
+};
+
+/**
+ * Constants for encoding modifier key set as a bit mask.
+ * @see #_makeKeyFromCodeAndModifiers
+ */
+WebInspector.KeyboardShortcut.Modifiers = {
+ None: 0, // Constant for empty modifiers set.
+ Shift: 1,
+ Ctrl: 2,
+ Alt: 4,
+ Meta: 8 // Command key on Mac, Win key on other platforms.
+};
+
+WebInspector.KeyboardShortcut.KeyCodes = {
+ Esc: 27,
+ Space: 32,
+ PageUp: 33, // also NUM_NORTH_EAST
+ PageDown: 34, // also NUM_SOUTH_EAST
+ End: 35, // also NUM_SOUTH_WEST
+ Home: 36, // also NUM_NORTH_WEST
+ Left: 37, // also NUM_WEST
+ Up: 38, // also NUM_NORTH
+ Right: 39, // also NUM_EAST
+ Down: 40, // also NUM_SOUTH
+ F1: 112,
+ F2: 113,
+ F3: 114,
+ F4: 115,
+ F5: 116,
+ F6: 117,
+ F7: 118,
+ F8: 119,
+ F9: 120,
+ F10: 121,
+ F11: 122,
+ F12: 123,
+ Semicolon: 186, // ;
+ Comma: 188, // ,
+ Period: 190, // .
+ Slash: 191, // /
+ Apostrophe: 192, // `
+ SingleQuote: 222, // '
+};
+
+/**
+ * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
+ * It is usefull for matching pressed keys.
+ * @param {number} keyCode Code of the key.
+ * @param {number} optModifiers Optional list of modifiers passed as additional paramerters.
+ */
+WebInspector.KeyboardShortcut.makeKey = function(keyCode, optModifiers)
+{
+ var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
+ for (var i = 1; i < arguments.length; i++)
+ modifiers |= arguments[i];
+ return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
+};
+
+WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
+{
+ var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
+ if (keyboardEvent.shiftKey)
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
+ if (keyboardEvent.ctrlKey)
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
+ if (keyboardEvent.altKey)
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
+ if (keyboardEvent.metaKey)
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
+ return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
+};
+
+WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
+{
+ return (keyCode & 255) | (modifiers << 8);
+};
diff --git a/WebCore/inspector/front-end/MetricsSidebarPane.js b/WebCore/inspector/front-end/MetricsSidebarPane.js
index a22a000..8712dcd 100644
--- a/WebCore/inspector/front-end/MetricsSidebarPane.js
+++ b/WebCore/inspector/front-end/MetricsSidebarPane.js
@@ -29,6 +29,7 @@
WebInspector.MetricsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Metrics"));
+ this._inlineStyleId = null;
}
WebInspector.MetricsSidebarPane.prototype = {
@@ -46,12 +47,28 @@ WebInspector.MetricsSidebarPane.prototype = {
if (!node || !node.ownerDocument.defaultView)
return;
- var style;
- if (node.nodeType === Node.ELEMENT_NODE)
- style = node.ownerDocument.defaultView.getComputedStyle(node);
- if (!style)
+ if (node.nodeType !== Node.ELEMENT_NODE)
return;
+ var self = this;
+ var callback = function(stylePayload) {
+ if (!stylePayload)
+ return;
+ var style = WebInspector.CSSStyleDeclaration.parseStyle(stylePayload);
+ self._update(node, body, style);
+ };
+ InspectorController.getComputedStyle(node, callback);
+
+ var inlineStyleCallback = function(stylePayload) {
+ if (!stylePayload)
+ return;
+ self._inlineStyleId = stylePayload.id;
+ };
+ InspectorController.getInlineStyle(node, inlineStyleCallback);
+ },
+
+ _update: function(node, body, style)
+ {
var metricsElement = document.createElement("div");
metricsElement.className = "metrics";
@@ -184,11 +201,14 @@ WebInspector.MetricsSidebarPane.prototype = {
if (/^\d+$/.test(userInput))
userInput += "px";
- this.node.style.setProperty(context.styleProperty, userInput, "");
-
- this.dispatchEventToListeners("metrics edited");
-
- this.update();
+ var self = this;
+ var callback = function(success) {
+ if (!success)
+ return;
+ self.dispatchEventToListeners("metrics edited");
+ self.update();
+ };
+ InspectorController.setStyleProperty(this._inlineStyleId, context.styleProperty, userInput, callback);
}
}
diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js
index ab6ac55..9b03940 100644
--- a/WebCore/inspector/front-end/ObjectPropertiesSection.js
+++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,15 +26,6 @@
WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
{
- if (!title) {
- title = Object.describe(object);
- if (title.match(/Prototype$/)) {
- title = title.replace(/Prototype$/, "");
- if (!subtitle)
- subtitle = WebInspector.UIString("Prototype");
- }
- }
-
this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
this.object = object;
this.ignoreHasOwnProperty = ignoreHasOwnProperty;
@@ -52,42 +44,80 @@ WebInspector.ObjectPropertiesSection.prototype = {
update: function()
{
- var properties = [];
- for (var prop in this.object)
- properties.push(prop);
+ var self = this;
+ var callback = function(properties) {
+ if (!properties)
+ return;
+ self._update(properties);
+ };
+ InspectorController.getProperties(this.object, this.ignoreHasOwnProperty, callback);
+ },
+
+ _update: function(properties)
+ {
if (this.extraProperties)
for (var prop in this.extraProperties)
- properties.push(prop);
- properties.sort();
+ properties.push(new WebInspector.ObjectPropertyProxy(prop, this.extraProperties[prop]));
+ properties.sort(this._displaySort);
this.propertiesTreeOutline.removeChildren();
- for (var i = 0; i < properties.length; ++i) {
- var object = this.object;
- var propertyName = properties[i];
- if (this.extraProperties && propertyName in this.extraProperties)
- object = this.extraProperties;
- if (propertyName === "__treeElementIdentifier")
- continue;
- if (!this.ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName))
- continue;
- this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(object, propertyName));
- }
+ for (var i = 0; i < properties.length; ++i)
+ this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(properties[i]));
if (!this.propertiesTreeOutline.children.length) {
var title = "<div class=\"info\">" + this.emptyPlaceholder + "</div>";
var infoElement = new TreeElement(title, null, false);
this.propertiesTreeOutline.appendChild(infoElement);
}
+ },
+
+ _displaySort: function(propertyA, propertyB) {
+ var a = propertyA.name;
+ var b = propertyB.name;
+
+ // if used elsewhere make sure to
+ // - convert a and b to strings (not needed here, properties are all strings)
+ // - check if a == b (not needed here, no two properties can be the same)
+
+ var diff = 0;
+ var chunk = /^\d+|^\D+/;
+ var chunka, chunkb, anum, bnum;
+ while (diff === 0) {
+ if (!a && b)
+ return -1;
+ if (!b && a)
+ return 1;
+ chunka = a.match(chunk)[0];
+ chunkb = b.match(chunk)[0];
+ anum = !isNaN(chunka);
+ bnum = !isNaN(chunkb);
+ if (anum && !bnum)
+ return -1;
+ if (bnum && !anum)
+ return 1;
+ if (anum && bnum) {
+ diff = chunka - chunkb;
+ if (diff === 0 && chunka.length !== chunkb.length) {
+ if (!+chunka && !+chunkb) // chunks are strings of all 0s (special case)
+ return chunka.length - chunkb.length;
+ else
+ return chunkb.length - chunka.length;
+ }
+ } else if (chunka !== chunkb)
+ return (chunka < chunkb) ? -1 : 1;
+ a = a.substring(chunka.length);
+ b = b.substring(chunkb.length);
+ }
+ return diff;
}
}
WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
-WebInspector.ObjectPropertyTreeElement = function(parentObject, propertyName)
+WebInspector.ObjectPropertyTreeElement = function(property)
{
- this.parentObject = parentObject;
- this.propertyName = propertyName;
+ this.property = property;
// Pass an empty title, the title gets made later in onattach.
TreeElement.call(this, "", null, false);
@@ -106,16 +136,18 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
if (this.children.length && !this.shouldRefreshChildren)
return;
- this.removeChildren();
+ var self = this;
+ var callback = function(properties) {
+ self.removeChildren();
+ if (!properties)
+ return;
- var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
- var properties = Object.sortedProperties(childObject);
- for (var i = 0; i < properties.length; ++i) {
- var propertyName = properties[i];
- if (propertyName === "__treeElementIdentifier")
- continue;
- this.appendChild(new this.treeOutline.section.treeElementConstructor(childObject, propertyName));
- }
+ properties.sort(self._displaySort);
+ for (var i = 0; i < properties.length; ++i) {
+ self.appendChild(new self.treeOutline.section.treeElementConstructor(properties[i]));
+ }
+ };
+ InspectorController.getProperties(this.property.childObjectProxy, false, callback);
},
ondblclick: function(element, event)
@@ -130,41 +162,22 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
update: function()
{
- var childObject = this.safePropertyValue(this.parentObject, this.propertyName);
- var isGetter = ("__lookupGetter__" in this.parentObject && this.parentObject.__lookupGetter__(this.propertyName));
-
var nameElement = document.createElement("span");
nameElement.className = "name";
- nameElement.textContent = this.propertyName;
+ nameElement.textContent = this.property.name;
this.valueElement = document.createElement("span");
this.valueElement.className = "value";
- if (!isGetter) {
- this.valueElement.textContent = Object.describe(childObject, true);
- } else {
- // FIXME: this should show something like "getter" (bug 16734).
- this.valueElement.textContent = "\u2014"; // em dash
- this.valueElement.addStyleClass("dimmed");
- }
+ this.valueElement.textContent = this.property.textContent;
+ if (this.property.isGetter)
+ this.valueElement.addStyleClass("dimmed");
this.listItemElement.removeChildren();
this.listItemElement.appendChild(nameElement);
this.listItemElement.appendChild(document.createTextNode(": "));
this.listItemElement.appendChild(this.valueElement);
-
- var hasSubProperties = false;
- var type = typeof childObject;
- if (childObject && (type === "object" || type === "function")) {
- for (subPropertyName in childObject) {
- if (subPropertyName === "__treeElementIdentifier")
- continue;
- hasSubProperties = true;
- break;
- }
- }
-
- this.hasChildren = hasSubProperties;
+ this.hasChildren = this.property.hasChildren;
},
updateSiblings: function()
@@ -214,62 +227,27 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.editingEnded(context);
},
- evaluateExpression: function(expression)
- {
- // Evaluate in the currently selected call frame if the debugger is paused.
- // Otherwise evaluate in against the inspected window.
- if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused && this.treeOutline.section.editInSelectedCallFrameWhenPaused)
- return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false);
- return InspectorController.inspectedWindow().eval(expression);
- },
-
applyExpression: function(expression, updateInterface)
{
- var expressionLength = expression.trimWhitespace().length;
-
- if (!expressionLength) {
- // The user deleted everything, so try to delete the property.
- delete this.parentObject[this.propertyName];
-
- if (updateInterface) {
- if (this.propertyName in this.parentObject) {
- // The property was not deleted, so update.
- this.update();
- } else {
- // The property was deleted, so remove this tree element.
- this.parent.removeChild(this);
- }
- }
+ expression = expression.trimWhitespace();
+ var expressionLength = expression.length;
+ var self = this;
+ var callback = function(success) {
+ if (!updateInterface)
+ return;
- return;
- }
+ if (!success)
+ self.update();
- try {
- // Surround the expression in parenthesis so the result of the eval is the result
- // of the whole expression not the last potential sub-expression.
- var result = this.evaluateExpression("(" + expression + ")");
-
- // Store the result in the property.
- this.parentObject[this.propertyName] = result;
- } catch(e) {
- try {
- // Try to update as a string
- var result = this.evaluateExpression("\"" + expression.escapeCharacters("\"") + "\"");
-
- // Store the result in the property.
- this.parentObject[this.propertyName] = result;
- } catch(e) {
- // The expression failed so don't change the value. So just update and return.
- if (updateInterface)
- this.update();
- return;
+ if (!expressionLength) {
+ // The property was deleted, so remove this tree element.
+ self.parent.removeChild(this);
+ } else {
+ // Call updateSiblings since their value might be based on the value that just changed.
+ self.updateSiblings();
}
- }
-
- if (updateInterface) {
- // Call updateSiblings since their value might be based on the value that just changed.
- this.updateSiblings();
- }
+ };
+ InspectorController.setPropertyValue(this.property.parentObjectProxy, this.property.name, expression.trimWhitespace(), callback);
}
}
diff --git a/WebCore/inspector/front-end/ObjectProxy.js b/WebCore/inspector/front-end/ObjectProxy.js
new file mode 100644
index 0000000..fa7816e
--- /dev/null
+++ b/WebCore/inspector/front-end/ObjectProxy.js
@@ -0,0 +1,45 @@
+/*
+ * 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.ObjectProxy = function(objectId, path, protoDepth)
+{
+ this.objectId = objectId;
+ this.path = path || [];
+ this.protoDepth = protoDepth || 0;
+}
+
+WebInspector.ObjectPropertyProxy = function(name, object)
+{
+ this.name = name;
+ this.type = "object";
+ this.hasChildren = true;
+ this.textContent = Object.describe(object, true);
+ this.childObjectProxy = new WebInspector.ObjectProxy(object);
+}
diff --git a/WebCore/inspector/front-end/Panel.js b/WebCore/inspector/front-end/Panel.js
index 5046f6b..3e2212c 100644
--- a/WebCore/inspector/front-end/Panel.js
+++ b/WebCore/inspector/front-end/Panel.js
@@ -66,6 +66,18 @@ WebInspector.Panel.prototype = {
return this._toolbarItem;
},
+ createStatusBarButton: function()
+ {
+ var button = document.createElement("button");
+ var glyph = document.createElement("div");
+ glyph.className = "glyph";
+ button.appendChild(glyph);
+ var glyphShadow = document.createElement("div");
+ glyphShadow.className = "glyph shadow";
+ button.appendChild(glyphShadow);
+ return button;
+ },
+
show: function()
{
WebInspector.View.prototype.show.call(this);
diff --git a/WebCore/inspector/front-end/ProfileView.js b/WebCore/inspector/front-end/ProfileView.js
index d00733c..2517bd2 100644
--- a/WebCore/inspector/front-end/ProfileView.js
+++ b/WebCore/inspector/front-end/ProfileView.js
@@ -148,11 +148,23 @@ WebInspector.ProfileView.prototype = {
return this._bottomUpTree;
},
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this.dataGrid.updateWidths();
+ },
+
hide: function()
{
WebInspector.View.prototype.hide.call(this);
this._currentSearchResultIndex = -1;
},
+
+ resize: function()
+ {
+ if (this.dataGrid)
+ this.dataGrid.updateWidths();
+ },
refresh: function()
{
@@ -166,8 +178,8 @@ WebInspector.ProfileView.prototype = {
for (var index = 0; index < count; ++index)
this.dataGrid.appendChild(children[index]);
- if (selectedProfileNode && selectedProfileNode._dataGridNode)
- selectedProfileNode._dataGridNode.selected = true;
+ if (selectedProfileNode)
+ selectedProfileNode.selected = true;
},
refreshVisibleData: function()
@@ -196,8 +208,7 @@ WebInspector.ProfileView.prototype = {
delete profileNode._searchMatchedCallsColumn;
delete profileNode._searchMatchedFunctionColumn;
- if (profileNode._dataGridNode)
- profileNode._dataGridNode.refresh();
+ profileNode.refresh();
}
}
@@ -313,7 +324,7 @@ WebInspector.ProfileView.prototype = {
profileDataGridNode._searchMatchedTotalColumn ||
profileDataGridNode._searchMatchedAverageColumn ||
profileDataGridNode._searchMatchedCallsColumn ||
- profileDataGridNode._searchMatchedFunctionColumn);
+ profileDataGridNode._searchMatchedFunctionColumn)
{
profileDataGridNode.refresh();
return true;
@@ -322,48 +333,14 @@ WebInspector.ProfileView.prototype = {
return false;
}
- var current = this.dataGrid;
- var ancestors = [];
- var nextIndexes = [];
- var startIndex = 0;
+ var current = this.profileDataGridTree.children[0];
while (current) {
- var children = current.children;
- var childrenLength = children.length;
-
- if (startIndex >= childrenLength) {
- current = ancestors.pop();
- startIndex = nextIndexes.pop();
- continue;
+ if (matchesQuery(current)) {
+ this._searchResults.push({ profileNode: current });
}
- for (var i = startIndex; i < childrenLength; ++i) {
- var child = children[i];
-
- if (matchesQuery(child)) {
- if (child._dataGridNode) {
- // The child has a data grid node already, no need to remember the ancestors.
- this._searchResults.push({ profileNode: child });
- } else {
- var ancestorsCopy = [].concat(ancestors);
- ancestorsCopy.push(current);
- this._searchResults.push({ profileNode: child, ancestors: ancestorsCopy });
- }
- }
-
- if (child.children.length) {
- ancestors.push(current);
- nextIndexes.push(i + 1);
- current = child;
- startIndex = 0;
- break;
- }
-
- if (i === (childrenLength - 1)) {
- current = ancestors.pop();
- startIndex = nextIndexes.pop();
- }
- }
+ current = current.traverseNextNode(false, null, false);
}
finishedCallback(this, this._searchResults.length);
@@ -419,26 +396,9 @@ WebInspector.ProfileView.prototype = {
if (!searchResult)
return;
- var profileNode = this._searchResults[index].profileNode;
- if (!profileNode._dataGridNode && searchResult.ancestors) {
- var ancestors = searchResult.ancestors;
- for (var i = 0; i < ancestors.length; ++i) {
- var ancestorProfileNode = ancestors[i];
- var gridNode = ancestorProfileNode._dataGridNode;
- if (gridNode)
- gridNode.expand();
- }
-
- // No need to keep the ancestors around.
- delete searchResult.ancestors;
- }
-
- gridNode = profileNode._dataGridNode;
- if (!gridNode)
- return;
-
- gridNode.reveal();
- gridNode.select();
+ var profileNode = searchResult.profileNode;
+ profileNode.reveal();
+ profileNode.select();
},
_changeView: function(event)
diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js
index aafc306..c8b948a 100644
--- a/WebCore/inspector/front-end/ProfilesPanel.js
+++ b/WebCore/inspector/front-end/ProfilesPanel.js
@@ -59,11 +59,11 @@ WebInspector.ProfilesPanel = function()
this.profileViews.id = "profile-views";
this.element.appendChild(this.profileViews);
- this.enableToggleButton = document.createElement("button");
+ this.enableToggleButton = this.createStatusBarButton();
this.enableToggleButton.className = "enable-toggle-status-bar-item status-bar-item";
this.enableToggleButton.addEventListener("click", this._toggleProfiling.bind(this), false);
- this.recordButton = document.createElement("button");
+ this.recordButton = this.createStatusBarButton();
this.recordButton.title = WebInspector.UIString("Start profiling.");
this.recordButton.id = "record-profile-status-bar-item";
this.recordButton.className = "status-bar-item";
@@ -266,8 +266,10 @@ WebInspector.ProfilesPanel.prototype = {
groupNumber = ++this._profileGroupsForLinks[title];
- if (groupNumber >= 2)
- title += " " + WebInspector.UIString("Run %d", groupNumber);
+ if (groupNumber > 2)
+ // The title is used in the console message announcing that a profile has started so it gets
+ // incremented twice as often as it's displayed
+ title += " " + WebInspector.UIString("Run %d", groupNumber / 2);
}
return title;
@@ -322,6 +324,13 @@ WebInspector.ProfilesPanel.prototype = {
this.recordButton.title = WebInspector.UIString("Start profiling.");
}
},
+
+ resize: function()
+ {
+ var visibleView = this.visibleView;
+ if (visibleView && "resize" in visibleView)
+ visibleView.resize();
+ },
_updateInterface: function()
{
@@ -422,6 +431,10 @@ WebInspector.ProfilesPanel.prototype = {
this.profileViews.style.left = width + "px";
this.profileViewStatusBarItemsContainer.style.left = width + "px";
this.sidebarResizeElement.style.left = (width - 3) + "px";
+
+ var visibleView = this.visibleView;
+ if (visibleView && "resize" in visibleView)
+ visibleView.resize();
}
}
diff --git a/WebCore/inspector/front-end/PropertiesSidebarPane.js b/WebCore/inspector/front-end/PropertiesSidebarPane.js
index 70db805..2d32137 100644
--- a/WebCore/inspector/front-end/PropertiesSidebarPane.js
+++ b/WebCore/inspector/front-end/PropertiesSidebarPane.js
@@ -43,11 +43,21 @@ WebInspector.PropertiesSidebarPane.prototype = {
if (!object)
return;
- for (var prototype = object; prototype; prototype = prototype.__proto__) {
- var section = new WebInspector.ObjectPropertiesSection(prototype);
- this.sections.push(section);
- body.appendChild(section.element);
- }
+ var self = this;
+ var callback = function(prototypes) {
+ var body = self.bodyElement;
+ body.removeChildren();
+ self.sections = [];
+
+ // Get array of prototype user-friendly names.
+ for (var i = 0; i < prototypes.length; ++i) {
+ var prototype = new WebInspector.ObjectProxy(object, [], i);
+ var section = new WebInspector.ObjectPropertiesSection(prototype, prototypes[i], WebInspector.UIString("Prototype"));
+ self.sections.push(section);
+ body.appendChild(section.element);
+ }
+ };
+ InspectorController.getPrototypes(object, callback);
}
}
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index 058f232..bcb7b2a 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -341,12 +341,6 @@ WebInspector.Resource.prototype = {
}
},
- get documentNode() {
- if ("identifier" in this)
- return InspectorController.getResourceDocumentNode(this.identifier);
- return null;
- },
-
get requestHeaders()
{
if (this._requestHeaders === undefined)
@@ -489,7 +483,8 @@ WebInspector.Resource.prototype = {
// Otherwise, we flood the Console with too many tips.
/*
var msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
- WebInspector.ConsoleMessage.MessageLevel.Tip, -1, this.url, null, 1, tip.message);
+ WebInspector.ConsoleMessage.MessageType.Log, WebInspector.ConsoleMessage.MessageLevel.Tip,
+ -1, this.url, null, 1, tip.message);
WebInspector.console.addMessage(msg);
*/
},
@@ -549,6 +544,7 @@ WebInspector.Resource.prototype = {
case WebInspector.Warnings.IncorrectMIMEType.id:
if (!this._mimeTypeIsConsistentWithType())
msg = new WebInspector.ConsoleMessage(WebInspector.ConsoleMessage.MessageSource.Other,
+ WebInspector.ConsoleMessage.MessageType.Log,
WebInspector.ConsoleMessage.MessageLevel.Warning, -1, this.url, null, 1,
String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message,
WebInspector.Resource.Type.toString(this.type), this.mimeType));
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index 04d998e..fb43551 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Anthony Ricaud (rik24d@gmail.com)
+ * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,10 @@ WebInspector.ResourcesPanel = function()
this.element.addStyleClass("resources");
+ this.filterBarElement = document.createElement("div");
+ this.filterBarElement.id = "resources-filter";
+ this.element.appendChild(this.filterBarElement);
+
this.viewsContainerElement = document.createElement("div");
this.viewsContainerElement.id = "resource-views";
this.element.appendChild(this.viewsContainerElement);
@@ -126,7 +130,7 @@ WebInspector.ResourcesPanel = function()
this.resourcesTreeElement.expand();
- var panelEnablerHeading = WebInspector.UIString("You need to enable resource tracking to use the this panel.");
+ var panelEnablerHeading = WebInspector.UIString("You need to enable resource tracking to use this panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling resource tracking will reload the page and make page loading slower.");
var panelEnablerButton = WebInspector.UIString("Enable resource tracking");
@@ -135,11 +139,11 @@ WebInspector.ResourcesPanel = function()
this.element.appendChild(this.panelEnablerView.element);
- this.enableToggleButton = document.createElement("button");
+ this.enableToggleButton = this.createStatusBarButton();
this.enableToggleButton.className = "enable-toggle-status-bar-item status-bar-item";
this.enableToggleButton.addEventListener("click", this._toggleResourceTracking.bind(this), false);
- this.largerResourcesButton = document.createElement("button");
+ this.largerResourcesButton = this.createStatusBarButton();
this.largerResourcesButton.id = "resources-larger-resources-status-bar-item";
this.largerResourcesButton.className = "status-bar-item toggled-on";
this.largerResourcesButton.title = WebInspector.UIString("Use small resource rows.");
@@ -149,6 +153,24 @@ WebInspector.ResourcesPanel = function()
this.sortingSelectElement.className = "status-bar-item";
this.sortingSelectElement.addEventListener("change", this._changeSortingFunction.bind(this), false);
+ var createFilterElement = function (category) {
+ var categoryElement = document.createElement("li");
+ categoryElement.category = category;
+ categoryElement.addStyleClass(category);
+ var label = WebInspector.UIString("All");
+ if (WebInspector.resourceCategories[category])
+ label = WebInspector.resourceCategories[category].title;
+ categoryElement.appendChild(document.createTextNode(label));
+ categoryElement.addEventListener("click", this._updateFilter.bind(this), false);
+ this.filterBarElement.appendChild(categoryElement);
+ return categoryElement;
+ };
+
+ var allElement = createFilterElement.call(this, "all");
+ this.filter(allElement.category);
+ for (var i = 0; i < this.categoryOrder.length; i++)
+ createFilterElement.call(this, this.categoryOrder[i]);
+
this.reset();
timeGraphItem.select();
@@ -157,6 +179,31 @@ WebInspector.ResourcesPanel = function()
WebInspector.ResourcesPanel.prototype = {
toolbarItemClass: "resources",
+ categoryOrder: ["documents", "stylesheets", "images", "scripts", "xhr", "fonts", "other"],
+
+ filter: function (category) {
+ if (this._filterCategory && this._filterCategory === category)
+ return;
+
+ if (this._filterCategory) {
+ var filterElement = this.filterBarElement.getElementsByClassName(this._filterCategory)[0];
+ filterElement.removeStyleClass("selected");
+ var oldClass = "filter-" + this._filterCategory;
+ this.resourcesTreeElement.childrenListElement.removeStyleClass(oldClass);
+ this.resourcesGraphsElement.removeStyleClass(oldClass);
+ }
+ this._filterCategory = category;
+ var filterElement = this.filterBarElement.getElementsByClassName(this._filterCategory)[0];
+ filterElement.addStyleClass("selected");
+ var newClass = "filter-" + this._filterCategory;
+ this.resourcesTreeElement.childrenListElement.addStyleClass(newClass);
+ this.resourcesGraphsElement.addStyleClass(newClass);
+ },
+
+ _updateFilter: function (e) {
+ this.filter(e.target.category);
+ },
+
get toolbarItemLabel()
{
return WebInspector.UIString("Resources");
@@ -957,14 +1004,13 @@ WebInspector.ResourcesPanel.prototype = {
{
var graphInfo = this.calculator.computeSummaryValues(this._resources);
- var categoryOrder = ["documents", "stylesheets", "images", "scripts", "xhr", "fonts", "other"];
var categoryColors = {documents: {r: 47, g: 102, b: 236}, stylesheets: {r: 157, g: 231, b: 119}, images: {r: 164, g: 60, b: 255}, scripts: {r: 255, g: 121, b: 0}, xhr: {r: 231, g: 231, b: 10}, fonts: {r: 255, g: 82, b: 62}, other: {r: 186, g: 186, b: 186}};
var fillSegments = [];
this.legendElement.removeChildren();
- for (var i = 0; i < categoryOrder.length; ++i) {
- var category = categoryOrder[i];
+ for (var i = 0; i < this.categoryOrder.length; ++i) {
+ var category = this.categoryOrder[i];
var size = graphInfo.categoryValues[category];
if (!size)
continue;
@@ -1453,6 +1499,12 @@ WebInspector.ResourceSidebarTreeElement.prototype = {
{
WebInspector.SidebarTreeElement.prototype.onattach.call(this);
+ var link = document.createElement("a");
+ link.href = this.resource.url;
+ link.className = "invisible";
+ while (this._listItemNode.firstChild)
+ link.appendChild(this._listItemNode.firstChild);
+ this._listItemNode.appendChild(link);
this._listItemNode.addStyleClass("resources-category-" + this.resource.category.name);
},
@@ -1460,6 +1512,11 @@ WebInspector.ResourceSidebarTreeElement.prototype = {
{
WebInspector.panels.resources.showResource(this.resource);
},
+
+ ondblclick: function(treeElement, event)
+ {
+ InspectorController.inspectedWindow().open(this.resource.url);
+ },
get mainTitle()
{
diff --git a/WebCore/inspector/front-end/ScopeChainSidebarPane.js b/WebCore/inspector/front-end/ScopeChainSidebarPane.js
index 157cee9..a293fa0 100644
--- a/WebCore/inspector/front-end/ScopeChainSidebarPane.js
+++ b/WebCore/inspector/front-end/ScopeChainSidebarPane.js
@@ -85,7 +85,7 @@ WebInspector.ScopeChainSidebarPane.prototype = {
if (!title || title === subtitle)
subtitle = null;
- var section = new WebInspector.ObjectPropertiesSection(scopeObject, title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
+ var section = new WebInspector.ObjectPropertiesSection(new WebInspector.ObjectProxy(scopeObject), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
section.editInSelectedCallFrameWhenPaused = true;
section.pane = this;
@@ -100,9 +100,9 @@ WebInspector.ScopeChainSidebarPane.prototype = {
WebInspector.ScopeChainSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
-WebInspector.ScopeVariableTreeElement = function(parentObject, propertyName)
+WebInspector.ScopeVariableTreeElement = function(property)
{
- WebInspector.ObjectPropertyTreeElement.call(this, parentObject, propertyName);
+ WebInspector.ObjectPropertyTreeElement.call(this, property);
}
WebInspector.ScopeVariableTreeElement.prototype = {
@@ -142,9 +142,9 @@ WebInspector.ScopeVariableTreeElement.prototype = {
do {
if (result)
- result = current.propertyName + "." + result;
+ result = current.property.name + "." + result;
else
- result = current.propertyName;
+ result = current.property.name;
current = current.parent;
} while (current && !current.root);
diff --git a/WebCore/inspector/front-end/Script.js b/WebCore/inspector/front-end/Script.js
index 46502a6..e6413a9 100644
--- a/WebCore/inspector/front-end/Script.js
+++ b/WebCore/inspector/front-end/Script.js
@@ -31,6 +31,19 @@ WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorL
this.startingLine = startingLine;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
+
+ // if no URL, look for "//@ sourceURL=" decorator
+ // note that this sourceURL comment decorator is behavior that FireBug added
+ // in it's 1.1 release as noted in the release notes:
+ // http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
+ if (!sourceURL) {
+ // use of [ \t] rather than \s is to prevent \n from matching
+ var pattern = /^\s*\/\/[ \t]*@[ \t]*sourceURL[ \t]*=[ \t]*(\S+).*$/m;
+ var match = pattern.exec(source);
+
+ if (match)
+ this.sourceURL = WebInspector.UIString("(program): %s", match[1]);
+ }
}
WebInspector.Script.prototype = {
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 7af9292..0058374 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -56,6 +56,7 @@ WebInspector.ScriptsPanel = function()
this.filesSelectElement.className = "status-bar-item";
this.filesSelectElement.id = "scripts-files";
this.filesSelectElement.addEventListener("change", this._changeVisibleFile.bind(this), false);
+ this.filesSelectElement.handleKeyEvent = this.handleKeyEvent.bind(this);
this.topStatusBar.appendChild(this.filesSelectElement);
this.functionsSelectElement = document.createElement("select");
@@ -132,13 +133,11 @@ WebInspector.ScriptsPanel = function()
for (var pane in this.sidebarPanes)
this.sidebarElement.appendChild(this.sidebarPanes[pane].element);
- // FIXME: remove the following line of code when the Breakpoints pane has content.
- this.sidebarElement.removeChild(this.sidebarPanes.breakpoints.element);
-
this.sidebarPanes.callstack.expanded = true;
this.sidebarPanes.callstack.addEventListener("call frame selected", this._callFrameSelected, this);
this.sidebarPanes.scopechain.expanded = true;
+ this.sidebarPanes.breakpoints.expanded = true;
var panelEnablerHeading = WebInspector.UIString("You need to enable debugging before you can use the Scripts panel.");
var panelEnablerDisclaimer = WebInspector.UIString("Enabling debugging will make scripts run slower.");
@@ -152,17 +151,50 @@ WebInspector.ScriptsPanel = function()
this.element.appendChild(this.sidebarElement);
this.element.appendChild(this.sidebarResizeElement);
- this.enableToggleButton = document.createElement("button");
+ this.enableToggleButton = this.createStatusBarButton();
this.enableToggleButton.className = "enable-toggle-status-bar-item status-bar-item";
this.enableToggleButton.addEventListener("click", this._toggleDebugging.bind(this), false);
- this.pauseOnExceptionButton = document.createElement("button");
+ this.pauseOnExceptionButton = this.createStatusBarButton();
this.pauseOnExceptionButton.id = "scripts-pause-on-exceptions-status-bar-item";
this.pauseOnExceptionButton.className = "status-bar-item";
this.pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions.bind(this), false);
this._breakpointsURLMap = {};
+ this._shortcuts = {};
+
+ var isMac = InspectorController.platform().indexOf("mac-") === 0;
+ var platformSpecificModifier = isMac ? WebInspector.KeyboardShortcut.Modifiers.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl;
+
+ // Continue.
+ var handler = this.pauseButton.click.bind(this.pauseButton);
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.F8);
+ this._shortcuts[shortcut] = handler;
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.Slash, platformSpecificModifier);
+ this._shortcuts[shortcut] = handler;
+
+ // Step over.
+ var handler = this.stepOverButton.click.bind(this.stepOverButton);
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.F10);
+ this._shortcuts[shortcut] = handler;
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.SingleQuote, platformSpecificModifier);
+ this._shortcuts[shortcut] = handler;
+
+ // Step into.
+ var handler = this.stepIntoButton.click.bind(this.stepIntoButton);
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.F11);
+ this._shortcuts[shortcut] = handler;
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.Semicolon, platformSpecificModifier);
+ this._shortcuts[shortcut] = handler;
+
+ // Step out.
+ var handler = this.stepOutButton.click.bind(this.stepOutButton);
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.F11, WebInspector.KeyboardShortcut.Modifiers.Shift);
+ this._shortcuts[shortcut] = handler;
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(WebInspector.KeyboardShortcut.KeyCodes.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift, platformSpecificModifier);
+ this._shortcuts[shortcut] = handler;
+
this.reset();
}
@@ -206,7 +238,7 @@ WebInspector.ScriptsPanel.prototype = {
view.visible = false;
}
if (this._attachDebuggerWhenShown) {
- InspectorController.enableDebuggerFromFrontend(false);
+ InspectorController.enableDebugger(false);
delete this._attachDebuggerWhenShown;
}
},
@@ -265,6 +297,11 @@ WebInspector.ScriptsPanel.prototype = {
this._addScriptToFilesMenu(script);
},
+ scriptOrResourceForID: function(id)
+ {
+ return this._sourceIDMap[id];
+ },
+
addBreakpoint: function(breakpoint)
{
this.sidebarPanes.breakpoints.addBreakpoint(breakpoint);
@@ -316,33 +353,53 @@ WebInspector.ScriptsPanel.prototype = {
sourceFrame.removeBreakpoint(breakpoint);
},
- evaluateInSelectedCallFrame: function(code, updateInterface)
+ evaluateInSelectedCallFrame: function(code, updateInterface, callback)
{
var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
if (!this._paused || !selectedCallFrame)
return;
+
if (typeof updateInterface === "undefined")
updateInterface = true;
- var result = selectedCallFrame.evaluate(code);
- if (updateInterface)
- this.sidebarPanes.scopechain.update(selectedCallFrame);
- return result;
+
+ var self = this;
+ function updatingCallbackWrapper(result, exception)
+ {
+ callback(result, exception);
+ if (updateInterface)
+ self.sidebarPanes.scopechain.update(selectedCallFrame);
+ }
+ this.doEvalInCallFrame(selectedCallFrame, code, updatingCallbackWrapper);
},
- variablesInScopeForSelectedCallFrame: function()
+ doEvalInCallFrame: function(callFrame, code, callback)
{
- var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
- if (!this._paused || !selectedCallFrame)
- return {};
+ var panel = this;
+ function delayedEvaluation()
+ {
+ if (!code) {
+ // Evaluate into properties in scope of the selected call frame.
+ callback(panel._variablesInScope(callFrame));
+ return;
+ }
+ try {
+ callback(callFrame.evaluate(code));
+ } catch (e) {
+ callback(e, true);
+ }
+ }
+ setTimeout(delayedEvaluation, 0);
+ },
+ _variablesInScope: function(callFrame)
+ {
var result = {};
- var scopeChain = selectedCallFrame.scopeChain;
+ var scopeChain = callFrame.scopeChain;
for (var i = 0; i < scopeChain.length; ++i) {
var scopeObject = scopeChain[i];
for (var property in scopeObject)
result[property] = true;
}
-
return result;
},
@@ -375,7 +432,7 @@ WebInspector.ScriptsPanel.prototype = {
attachDebuggerWhenShown: function()
{
if (this.element.parentElement) {
- InspectorController.enableDebuggerFromFrontend(false);
+ InspectorController.enableDebugger(false);
} else {
this._attachDebuggerWhenShown = true;
}
@@ -467,6 +524,19 @@ WebInspector.ScriptsPanel.prototype = {
this._showScriptOrResource((view.resource || view.script));
},
+ handleKeyEvent: function(event)
+ {
+ var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var handler = this._shortcuts[shortcut];
+ if (handler) {
+ handler(event);
+ event.preventDefault();
+ event.handled = true;
+ } else {
+ this.sidebarPanes.callstack.handleKeyEvent(event);
+ }
+ },
+
scriptViewForScript: function(script)
{
if (!script)
@@ -796,7 +866,7 @@ WebInspector.ScriptsPanel.prototype = {
if (InspectorController.debuggerEnabled())
InspectorController.disableDebugger(true);
else
- InspectorController.enableDebuggerFromFrontend(!!optionalAlways);
+ InspectorController.enableDebugger(!!optionalAlways);
},
_togglePauseOnExceptions: function()
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 18d9073..930eb16 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -27,6 +27,7 @@ WebInspector.SourceFrame = function(element, addBreakpointDelegate)
{
this.messages = [];
this.breakpoints = [];
+ this._shortcuts = {};
this.addBreakpointDelegate = addBreakpointDelegate;
@@ -199,8 +200,16 @@ WebInspector.SourceFrame.prototype = {
{
WebInspector.addMainEventListeners(this.element.contentDocument);
this.element.contentDocument.addEventListener("mousedown", this._documentMouseDown.bind(this), true);
+ this.element.contentDocument.addEventListener("keydown", this._documentKeyDown.bind(this), true);
+ this.element.contentDocument.addEventListener("keyup", WebInspector.documentKeyUp.bind(WebInspector), true);
this.element.contentDocument.addEventListener("webkitAnimationEnd", this._highlightLineEnds.bind(this), false);
+ // Register 'eval' shortcut.
+ var isMac = InspectorController.platform().indexOf("mac-") === 0;
+ var platformSpecificModifier = isMac ? WebInspector.KeyboardShortcut.Modifiers.Meta : WebInspector.KeyboardShortcut.Modifiers.Ctrl;
+ var shortcut = WebInspector.KeyboardShortcut.makeKey(69 /* 'E' */, platformSpecificModifier | WebInspector.KeyboardShortcut.Modifiers.Shift);
+ this._shortcuts[shortcut] = this._evalSelectionInCallFrame.bind(this);
+
var headElement = this.element.contentDocument.getElementsByTagName("head")[0];
if (!headElement) {
headElement = this.element.contentDocument.createElement("head");
@@ -286,6 +295,36 @@ WebInspector.SourceFrame.prototype = {
this.addBreakpointDelegate(this.lineNumberForSourceRow(sourceRow));
},
+ _documentKeyDown: function(event)
+ {
+ var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var handler = this._shortcuts[shortcut];
+ if (handler) {
+ handler(event);
+ event.preventDefault();
+ } else {
+ WebInspector.documentKeyDown(event);
+ }
+ },
+
+ _evalSelectionInCallFrame: function(event)
+ {
+ if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
+ return;
+
+ var selection = this.element.contentWindow.getSelection();
+ if (!selection.rangeCount)
+ return;
+
+ var expression = selection.getRangeAt(0).toString().trimWhitespace();
+ WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, function(result, exception) {
+ WebInspector.showConsole();
+ var commandMessage = new WebInspector.ConsoleCommand(expression);
+ WebInspector.console.addMessage(commandMessage);
+ WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
+ });
+ },
+
_breakpointEnableChanged: function(event)
{
var breakpoint = event.target;
@@ -332,6 +371,8 @@ WebInspector.SourceFrame.prototype = {
if (!sourceRow)
return;
+ breakpoint.sourceText = sourceRow.getElementsByClassName('webkit-line-content')[0].textContent;
+
this._drawBreakpointImagesIfNeeded();
sourceRow._breakpointObject = breakpoint;
diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js
index 7510c8c..97a5bd5 100644
--- a/WebCore/inspector/front-end/SourceView.js
+++ b/WebCore/inspector/front-end/SourceView.js
@@ -104,8 +104,11 @@ WebInspector.SourceView.prototype = {
{
delete this._frameNeedsSetup;
this.sourceFrame.removeEventListener("content loaded", this._contentLoaded, this);
-
- if (this.resource.type === WebInspector.Resource.Type.Script) {
+
+ if (this.resource.type === WebInspector.Resource.Type.Script
+ || this.resource.mimeType === 'application/json'
+ || this.resource.mimeType === 'application/javascript'
+ || /\.js(on)?$/.test(this.resource.lastPathComponent) ) {
this.sourceFrame.addEventListener("syntax highlighting complete", this._syntaxHighlightingComplete, this);
this.sourceFrame.syntaxHighlightJavascript();
} else
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index c30444b..8a3a67f 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -62,14 +63,33 @@ WebInspector.StylesSidebarPane.prototype = {
if (!node)
return;
+ var self = this;
+ var callback = function(styles) {
+ if (!styles)
+ return;
+ var nodeWrapper = WebInspector.wrapNodeWithStyles(node, styles);
+ self._update(refresh, body, nodeWrapper, editedSection, forceUpdate);
+ };
+ InspectorController.getStyles(node, !Preferences.showUserAgentStyles, callback);
+ },
+
+ _update: function(refresh, body, node, editedSection, forceUpdate)
+ {
+ if (!refresh) {
+ body.removeChildren();
+ this.sections = [];
+ }
+
var styleRules = [];
if (refresh) {
for (var i = 0; i < this.sections.length; ++i) {
var section = this.sections[i];
+ if (section._blank)
+ continue;
if (section.computedStyle)
section.styleRule.style = node.ownerDocument.defaultView.getComputedStyle(node);
- var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle };
+ var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule };
styleRules.push(styleRule);
}
} else {
@@ -90,8 +110,9 @@ WebInspector.StylesSidebarPane.prototype = {
}
}
- if (node.style && (node.style.length || Object.hasProperties(node.style.__disabledProperties))) {
- var inlineStyle = { selectorText: WebInspector.UIString("Inline Style Attribute"), style: node.style };
+ // Always Show element's Style Attributes
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: node.style, isAttribute: true };
inlineStyle.subtitle = WebInspector.UIString("element’s “%s” attribute", "style");
styleRules.push(inlineStyle);
}
@@ -101,7 +122,7 @@ WebInspector.StylesSidebarPane.prototype = {
// Add rules in reverse order to match the cascade order.
for (var i = (matchedStyleRules.length - 1); i >= 0; --i) {
var rule = matchedStyleRules[i];
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, parentStyleSheet: rule.parentStyleSheet, rule: rule });
}
}
}
@@ -127,6 +148,8 @@ WebInspector.StylesSidebarPane.prototype = {
var styleRule = styleRules[i];
if (styleRule.computedStyle)
continue;
+ if (styleRule.section && styleRule.section.noAffect)
+ continue;
styleRule.usedProperties = {};
@@ -181,7 +204,7 @@ WebInspector.StylesSidebarPane.prototype = {
continue;
var style = styleRules[i].style;
- var uniqueProperties = getUniqueStyleProperties(style);
+ var uniqueProperties = style.uniqueStyleProperties;
for (var j = 0; j < uniqueProperties.length; ++j) {
var name = uniqueProperties[j];
if (style.getPropertyPriority(name).length) {
@@ -222,6 +245,9 @@ WebInspector.StylesSidebarPane.prototype = {
var editable = styleRule.editable;
delete styleRule.editable;
+ var isAttribute = styleRule.isAttribute;
+ delete styleRule.isAttribute;
+
// Default editable to true if it was omitted.
if (typeof editable === "undefined")
editable = true;
@@ -235,13 +261,49 @@ WebInspector.StylesSidebarPane.prototype = {
section.expanded = Preferences.styleRulesExpandedState[section.identifier];
else if (computedStyle)
section.collapse(true);
+ else if (isAttribute && styleRule.style.length === 0)
+ section.collapse(true);
else
section.expand(true);
body.appendChild(section.element);
this.sections.push(section);
}
+
+ this.addBlankSection();
}
+ },
+
+ addBlankSection: function()
+ {
+ var blankSection = new WebInspector.BlankStylePropertiesSection();
+ blankSection.pane = this;
+
+ this.bodyElement.insertBefore(blankSection.element, this.bodyElement.firstChild.nextSibling.nextSibling); // 0 is computed, 1 is element.style
+ var computed = this.sections.shift();
+ var elementStyle = this.sections.shift();
+ this.sections.unshift(blankSection);
+ this.sections.unshift(elementStyle);
+ this.sections.unshift(computed);
+ },
+
+ appropriateSelectorForNode: function()
+ {
+ var node = this.node;
+ if (!node)
+ return;
+
+ if (node.id)
+ return "#" + node.id;
+
+ if (node.className)
+ return "." + node.className.replace(/\s+/, ".");
+
+ var nodeName = node.nodeName.toLowerCase();
+ if (nodeName === "input" && node.type)
+ return nodeName + "[type=\"" + node.type + "\"]";
+
+ return nodeName;
}
}
@@ -250,14 +312,19 @@ WebInspector.StylesSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.pr
WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyle, usedProperties, editable)
{
WebInspector.PropertiesSection.call(this, styleRule.selectorText);
+ this.titleElement.addEventListener("click", function(e) { e.stopPropagation(); }, false);
+ this.titleElement.addEventListener("dblclick", this._dblclickSelector.bind(this), false);
+ this.element.addEventListener("dblclick", this._dblclickEmptySpace.bind(this), false);
this.styleRule = styleRule;
+ this.rule = this.styleRule.rule;
this.computedStyle = computedStyle;
this.editable = (editable && !computedStyle);
// Prevent editing the user agent and user rules.
- var isUserAgent = this.styleRule.parentStyleSheet && !this.styleRule.parentStyleSheet.ownerNode && !this.styleRule.parentStyleSheet.href;
- var isUser = this.styleRule.parentStyleSheet && this.styleRule.parentStyleSheet.ownerNode && this.styleRule.parentStyleSheet.ownerNode.nodeName == '#document';
+ var isUserAgent = this.styleRule.isUserAgent;
+ var isUser = this.styleRule.isUser;
+
if (isUserAgent || isUser)
this.editable = false;
@@ -299,6 +366,8 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl
subtitle = WebInspector.UIString("user agent stylesheet");
else if (isUser)
subtitle = WebInspector.UIString("user stylesheet");
+ else if (this.styleRule.parentStyleSheet === WebInspector.panels.elements.stylesheet)
+ subtitle = WebInspector.UIString("via inspector");
else
subtitle = WebInspector.UIString("inline stylesheet");
}
@@ -308,7 +377,7 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl
this.identifier = styleRule.selectorText;
if (this.subtitle)
- this.identifier += ":" + this.subtitleElement.textContent;
+ this.identifier += ":" + this.subtitleElement.textContent;
}
WebInspector.StylePropertiesSection.prototype = {
@@ -325,6 +394,9 @@ WebInspector.StylePropertiesSection.prototype = {
expand: function(dontRememberState)
{
+ if (this._blank)
+ return;
+
WebInspector.PropertiesSection.prototype.expand.call(this);
if (dontRememberState)
return;
@@ -347,7 +419,7 @@ WebInspector.StylePropertiesSection.prototype = {
isPropertyInherited: function(property)
{
- if (!this.computedStyle || !this._usedProperties)
+ if (!this.computedStyle || !this._usedProperties || this.noAffect)
return false;
// These properties should always show for Computed Style.
var alwaysShowComputedProperties = { "display": true, "height": true, "width": true };
@@ -356,7 +428,7 @@ WebInspector.StylePropertiesSection.prototype = {
isPropertyOverloaded: function(property, shorthand)
{
- if (this.computedStyle || !this._usedProperties)
+ if (this.computedStyle || !this._usedProperties || this.noAffect)
return false;
var used = (property in this.usedProperties);
@@ -365,7 +437,7 @@ WebInspector.StylePropertiesSection.prototype = {
// Find out if any of the individual longhand properties of the shorthand
// are used, if none are then the shorthand is overloaded too.
- var longhandProperties = getLonghandProperties(this.styleRule.style, property);
+ var longhandProperties = this.styleRule.style.getLonghandProperties(property);
for (var j = 0; j < longhandProperties.length; ++j) {
var individualProperty = longhandProperties[j];
if (individualProperty in this.usedProperties)
@@ -375,6 +447,11 @@ WebInspector.StylePropertiesSection.prototype = {
return true;
},
+ isInspectorStylesheet: function()
+ {
+ return (this.styleRule.parentStyleSheet === WebInspector.panels.elements.stylesheet);
+ },
+
update: function(full)
{
if (full || this.computedStyle) {
@@ -387,6 +464,11 @@ WebInspector.StylePropertiesSection.prototype = {
child = child.traverseNextTreeElement(false, null, true);
}
}
+
+ if (this._afterUpdate) {
+ this._afterUpdate(this);
+ delete this._afterUpdate;
+ }
},
onpopulate: function()
@@ -394,7 +476,7 @@ WebInspector.StylePropertiesSection.prototype = {
var style = this.styleRule.style;
var foundShorthands = {};
- var uniqueProperties = getUniqueStyleProperties(style);
+ var uniqueProperties = style.uniqueStyleProperties;
var disabledProperties = style.__disabledPropertyValues || {};
for (var name in disabledProperties)
@@ -422,16 +504,224 @@ WebInspector.StylePropertiesSection.prototype = {
var inherited = this.isPropertyInherited(name);
var overloaded = this.isPropertyOverloaded(name, isShorthand);
- var item = new WebInspector.StylePropertyTreeElement(style, name, isShorthand, inherited, overloaded, disabled);
+ var item = new WebInspector.StylePropertyTreeElement(this.styleRule, style, name, isShorthand, inherited, overloaded, disabled);
this.propertiesTreeOutline.appendChild(item);
}
+ },
+
+ findTreeElementWithName: function(name)
+ {
+ var treeElement = this.propertiesTreeOutline.children[0];
+ while (treeElement) {
+ if (treeElement.name === name)
+ return treeElement;
+ treeElement = treeElement.traverseNextTreeElement(true, null, true);
+ }
+ return null;
+ },
+
+ addNewBlankProperty: function()
+ {
+ var item = new WebInspector.StylePropertyTreeElement(this.styleRule, this.styleRule.style, "", false, false, false, false);
+ this.propertiesTreeOutline.appendChild(item);
+ item.listItemElement.textContent = "";
+ item._newProperty = true;
+ return item;
+ },
+
+ _dblclickEmptySpace: function(event)
+ {
+ this.expand();
+ this.addNewBlankProperty().startEditing();
+ },
+
+ _dblclickSelector: function(event)
+ {
+ if (!this.editable)
+ return;
+
+ if (!this.rule && this.propertiesTreeOutline.children.length === 0) {
+ this.expand();
+ this.addNewBlankProperty().startEditing();
+ return;
+ }
+
+ if (!this.rule)
+ return;
+
+ this.startEditingSelector();
+ event.stopPropagation();
+ },
+
+ startEditingSelector: function()
+ {
+ var element = this.titleElement;
+ if (WebInspector.isBeingEdited(element))
+ return;
+
+ var context = this.styleRule.selectorText;
+ WebInspector.startEditing(this.titleElement, this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), context);
+ window.getSelection().setBaseAndExtent(element, 0, element, 1);
+ },
+
+ editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection)
+ {
+ function moveToNextIfNeeded() {
+ if (!moveDirection || moveDirection !== "forward")
+ return;
+
+ this.expand();
+ if (this.propertiesTreeOutline.children.length === 0)
+ this.addNewBlankProperty().startEditing();
+ else {
+ var item = this.propertiesTreeOutline.children[0]
+ item.startEditing(item.valueElement);
+ }
+ }
+
+ if (newContent === oldContent)
+ return moveToNextIfNeeded.call(this);
+
+ var self = this;
+ var callback = function(result) {
+ if (!result) {
+ // Invalid Syntax for a Selector
+ self.editingSelectorCancelled(element, context);
+ moveToNextIfNeeded.call(self);
+ return;
+ }
+
+ var newRulePayload = result[0];
+ var doesAffectSelectedNode = result[1];
+ if (!doesAffectSelectedNode) {
+ self.noAffect = true;
+ self.element.addStyleClass("no-affect");
+ } else {
+ delete self.noAffect;
+ self.element.removeStyleClass("no-affect");
+ }
+
+ var newRule = WebInspector.CSSStyleDeclaration.parseRule(newRulePayload);
+ self.rule = newRule;
+ self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, parentStyleSheet: newRule.parentStyleSheet, rule: newRule };
+ var oldIdentifier = this.identifier;
+ self.identifier = newRule.selectorText + ":" + self.subtitleElement.textContent;
+ self.pane.update(null, true);
+ WebInspector.panels.elements.renameSelector(oldIdentifier, this.identifier, oldContent, newContent);
+ moveToNextIfNeeded.call(self);
+ };
+
+ InspectorController.applyStyleRuleText(this.rule._id, newContent, this.pane.node, callback);
+ },
+
+ editingSelectorCancelled: function(element, context)
+ {
+ element.textContent = context;
+ },
+
+ _doesSelectorAffectSelectedNode: function(selector)
+ {
+ var selectedNode = this.pane.node;
+ var nodes = selectedNode.ownerDocument.querySelectorAll(selector);
+ for (var i = 0; i < nodes.length; ++i) {
+ if (nodes[i] === selectedNode)
+ return true;
+ }
+
+ return false;
}
}
WebInspector.StylePropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
-WebInspector.StylePropertyTreeElement = function(style, name, shorthand, inherited, overloaded, disabled)
+WebInspector.BlankStylePropertiesSection = function()
{
+ WebInspector.PropertiesSection.call(this, WebInspector.UIString("Double-Click to Add"), null);
+
+ this._blank = true;
+ this._dblclickListener = this._dblclick.bind(this);
+ this.element.addStyleClass("blank-section");
+ this.titleElement.addStyleClass("blank-title");
+ this.titleElement.addEventListener("click", function(e) { e.stopPropagation(); }, false);
+ this.titleElement.addEventListener("dblclick", this._dblclickListener, false);
+}
+
+WebInspector.BlankStylePropertiesSection.prototype = {
+ _dblclick: function(event)
+ {
+ this.startEditing();
+ },
+
+ startEditing: function()
+ {
+ var element = this.titleElement;
+ if (WebInspector.isBeingEdited(element))
+ return;
+
+ this.titleElement.textContent = this.pane.appropriateSelectorForNode();
+ this.titleElement.removeStyleClass("blank-title");
+ WebInspector.startEditing(this.titleElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), "");
+ window.getSelection().setBaseAndExtent(element, 0, element, 1);
+ },
+
+ editingCancelled: function()
+ {
+ this.titleElement.textContent = WebInspector.UIString("Double-Click to Add");
+ this.titleElement.addStyleClass("blank-title");
+ },
+
+ editingCommitted: function(element, newContent, oldContent, context)
+ {
+ var self = this;
+ var callback = function(styleRule) {
+ if (!styleRule) {
+ // Invalid Syntax for a Selector
+ self.editingCancelled();
+ return;
+ }
+ self.makeNormal(WebInspector.CSSStyleDeclaration.parseRule(styleRule));
+
+ if (!self._doesSelectorAffectSelectedNode(newContent)) {
+ self.noAffect = true;
+ self.element.addStyleClass("no-affect");
+ }
+
+ self.subtitleElement.textContent = WebInspector.UIString("via inspector");
+ self.expand();
+
+ self.pane.addBlankSection();
+ self.addNewBlankProperty().startEditing();
+ };
+ InspectorController.addStyleSelector(newContent, callback);
+ },
+
+ makeNormal: function(styleRule)
+ {
+ this.titleElement.removeEventListener("dblclick", this._dblclickListener, false);
+ this.titleElement.addEventListener("dblclick", this._dblclickSelector.bind(this), false);
+ this.element.addEventListener("dblclick", this._dblclickEmptySpace.bind(this), false);
+ this.element.removeStyleClass("blank-section");
+ delete this._blank;
+ delete this._dblclick;
+ delete this.startEditing;
+ delete this.editingCancelled;
+ delete this.editingCommitted;
+ delete this._dblclickListener;
+ delete this.makeNormal;
+ this.styleRule = styleRule;
+ this.rule = styleRule.rule;
+ this.computedStyle = false;
+ this.editable = true;
+ this.identifier = styleRule.selectorText + ":inspector";
+ // leftovers are: this.noAffect if applicable
+ }
+}
+
+WebInspector.BlankStylePropertiesSection.prototype.__proto__ = WebInspector.StylePropertiesSection.prototype;
+
+WebInspector.StylePropertyTreeElement = function(styleRule, style, name, shorthand, inherited, overloaded, disabled)
+{
+ this._styleRule = styleRule;
this.style = style;
this.name = name;
this.shorthand = shorthand;
@@ -487,14 +777,14 @@ WebInspector.StylePropertyTreeElement.prototype = {
{
if (this.disabled && this.style.__disabledPropertyPriorities && this.name in this.style.__disabledPropertyPriorities)
return this.style.__disabledPropertyPriorities[this.name];
- return (this.shorthand ? getShorthandPriority(this.style, this.name) : this.style.getPropertyPriority(this.name));
+ return (this.shorthand ? this.style.getShorthandPriority(this.name) : this.style.getPropertyPriority(this.name));
},
get value()
{
if (this.disabled && this.style.__disabledPropertyValues && this.name in this.style.__disabledPropertyValues)
return this.style.__disabledPropertyValues[this.name];
- return (this.shorthand ? getShorthandValue(this.style, this.name) : this.style.getPropertyValue(this.name));
+ return (this.shorthand ? this.style.getShorthandValue(this.name) : this.style.getPropertyValue(this.name));
},
onattach: function()
@@ -558,10 +848,12 @@ WebInspector.StylePropertyTreeElement.prototype = {
var nameElement = document.createElement("span");
nameElement.className = "name";
nameElement.textContent = this.name;
+ this.nameElement = nameElement;
var valueElement = document.createElement("span");
valueElement.className = "value";
valueElement.innerHTML = htmlValue;
+ this.valueElement = valueElement;
if (priority) {
var priorityElement = document.createElement("span");
@@ -587,7 +879,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (value) {
// FIXME: this only covers W3C and CSS 16 valid color names
- var colors = value.match(/((rgb|hsl)a?\([^)]+\))|(#[0-9a-fA-F]{6})|(#[0-9a-fA-F]{3})|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow/g);
+ var colors = value.match(/((rgb|hsl)a?\([^)]+\))|(#[0-9a-fA-F]{6})|(#[0-9a-fA-F]{3})|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow|transparent/g);
+ var swatch;
if (colors) {
var colorsLength = colors.length;
for (var i = 0; i < colorsLength; ++i) {
@@ -595,6 +888,72 @@ WebInspector.StylePropertyTreeElement.prototype = {
swatchElement.className = "swatch";
swatchElement.style.setProperty("background-color", colors[i]);
this.listItemElement.appendChild(swatchElement);
+ swatch = swatchElement;
+ }
+ }
+
+ // Rotate through Color Representations by Clicking on the Swatch
+ // Simple: rgb -> hsl -> nickname? -> shorthex? -> hex -> ...
+ // Advanced: rgba -> hsla -> nickname? -> ...
+ if (colors && colors.length === 1) {
+ var color = new WebInspector.Color(htmlValue);
+ swatch.addEventListener("click", changeColorDisplay, false);
+ swatch.addEventListener("dblclick", function(event) {
+ event.stopPropagation();
+ }, false);
+
+ var mode = color.mode;
+ var valueElement = this.valueElement;
+ function changeColorDisplay(event) {
+
+ function changeTo(newMode, content) {
+ mode = newMode;
+ valueElement.textContent = content;
+ }
+
+ switch (mode) {
+ case "rgb":
+ changeTo("hsl", color.toHsl());
+ break;
+
+ case "shorthex":
+ changeTo("hex", color.toHex());
+ break;
+
+ case "hex":
+ changeTo("rgb", color.toRgb());
+ break;
+
+ case "nickname":
+ if (color.simple) {
+ if (color.hasShortHex())
+ changeTo("shorthex", color.toShortHex());
+ else
+ changeTo("hex", color.toHex());
+ } else
+ changeTo("rgba", color.toRgba());
+ break;
+
+ case "hsl":
+ if (color.nickname)
+ changeTo("nickname", color.toNickname());
+ else if (color.hasShortHex())
+ changeTo("shorthex", color.toShortHex());
+ else
+ changeTo("hex", color.toHex());
+ break;
+
+ case "rgba":
+ changeTo("hsla", color.toHsla());
+ break;
+
+ case "hsla":
+ if (color.nickname)
+ changeTo("nickname", color.toNickname());
+ else
+ changeTo("rgba", color.toRgba());
+ break;
+ }
}
}
}
@@ -616,42 +975,24 @@ WebInspector.StylePropertyTreeElement.prototype = {
{
var disabled = !event.target.checked;
- if (disabled) {
- if (!this.style.__disabledPropertyValues || !this.style.__disabledPropertyPriorities) {
- var inspectedWindow = InspectorController.inspectedWindow();
- this.style.__disabledProperties = new inspectedWindow.Object;
- this.style.__disabledPropertyValues = new inspectedWindow.Object;
- this.style.__disabledPropertyPriorities = new inspectedWindow.Object;
- }
-
- this.style.__disabledPropertyValues[this.name] = this.value;
- this.style.__disabledPropertyPriorities[this.name] = this.priority;
+ var self = this;
+ var callback = function(newPayload) {
+ if (!newPayload)
+ return;
- if (this.shorthand) {
- var longhandProperties = getLonghandProperties(this.style, this.name);
- for (var i = 0; i < longhandProperties.length; ++i) {
- this.style.__disabledProperties[longhandProperties[i]] = true;
- this.style.removeProperty(longhandProperties[i]);
- }
- } else {
- this.style.__disabledProperties[this.name] = true;
- this.style.removeProperty(this.name);
- }
- } else {
- this.style.setProperty(this.name, this.value, this.priority);
- delete this.style.__disabledProperties[this.name];
- delete this.style.__disabledPropertyValues[this.name];
- delete this.style.__disabledPropertyPriorities[this.name];
- }
+ self.style = WebInspector.CSSStyleDeclaration.parseStyle(newPayload);
+ self._styleRule.style = self.style;
- // Set the disabled property here, since the code above replies on it not changing
- // until after the value and priority are retrieved.
- this.disabled = disabled;
+ // Set the disabled property here, since the code above replies on it not changing
+ // until after the value and priority are retrieved.
+ self.disabled = disabled;
- if (this.treeOutline.section && this.treeOutline.section.pane)
- this.treeOutline.section.pane.dispatchEventToListeners("style property toggled");
+ if (self.treeOutline.section && self.treeOutline.section.pane)
+ self.treeOutline.section.pane.dispatchEventToListeners("style property toggled");
- this.updateAll(true);
+ self.updateAll(true);
+ };
+ InspectorController.toggleStyleEnabled(this.style._id, this.name, disabled, callback);
},
updateState: function()
@@ -686,7 +1027,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (this.children.length || !this.shorthand)
return;
- var longhandProperties = getLonghandProperties(this.style, this.name);
+ var longhandProperties = this.style.getLonghandProperties(this.name);
for (var i = 0; i < longhandProperties.length; ++i) {
var name = longhandProperties[i];
@@ -695,7 +1036,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
var overloaded = this.treeOutline.section.isPropertyOverloaded(name);
}
- var item = new WebInspector.StylePropertyTreeElement(this.style, name, false, inherited, overloaded);
+ var item = new WebInspector.StylePropertyTreeElement(this._styleRule, this.style, name, false, inherited, overloaded);
this.appendChild(item);
}
},
@@ -703,6 +1044,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
ondblclick: function(element, event)
{
this.startEditing(event.target);
+ event.stopPropagation();
},
startEditing: function(selectElement)
@@ -809,11 +1151,11 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (!this.originalCSSText) {
// Remember the rule's original CSS text, so it can be restored
// if the editing is canceled and before each apply.
- this.originalCSSText = getStyleTextWithShorthands(this.style);
+ this.originalCSSText = this.style.styleTextWithShorthands();
} else {
// Restore the original CSS text before applying user changes. This is needed to prevent
// new properties from sticking around if the user adds one, then removes it.
- this.style.cssText = this.originalCSSText;
+ InspectorController.setStyleText(this.style, this.originalCSSText);
}
this.applyStyleText(this.listItemElement.textContent);
@@ -830,8 +1172,10 @@ WebInspector.StylePropertyTreeElement.prototype = {
editingCancelled: function(element, context)
{
- if (this.originalCSSText) {
- this.style.cssText = this.originalCSSText;
+ if (this._newProperty)
+ this.treeOutline.removeChild(this);
+ else if (this.originalCSSText) {
+ InspectorController.setStyleText(this.style, this.originalCSSText);
if (this.treeOutline.section && this.treeOutline.section.pane)
this.treeOutline.section.pane.dispatchEventToListeners("style edited");
@@ -843,84 +1187,114 @@ WebInspector.StylePropertyTreeElement.prototype = {
this.editingEnded(context);
},
- editingCommitted: function(element, userInput, previousContent, context)
+ editingCommitted: function(element, userInput, previousContent, context, moveDirection)
{
this.editingEnded(context);
- if (userInput === previousContent)
- return; // nothing changed, so do nothing else
+ // Determine where to move to before making changes
+ var newProperty, moveToPropertyName, moveToSelector;
+ var moveTo = (moveDirection === "forward" ? this.nextSibling : this.previousSibling);
+ if (moveTo)
+ moveToPropertyName = moveTo.name;
+ else if (moveDirection === "forward")
+ newProperty = true;
+ else if (moveDirection === "backward" && this.treeOutline.section.rule)
+ moveToSelector = true;
+
+ // Make the Changes and trigger the moveToNextCallback after updating
+ var blankInput = /^\s*$/.test(userInput);
+ if (userInput !== previousContent || (this._newProperty && blankInput)) { // only if something changed, or adding a new style and it was blank
+ this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput);
+ this.applyStyleText(userInput, true);
+ } else
+ moveToNextCallback(this._newProperty, false, this.treeOutline.section, false);
- this.applyStyleText(userInput, true);
+ // The Callback to start editing the next property
+ function moveToNextCallback(alreadyNew, valueChanged, section) {
+ if (!moveDirection)
+ return;
+
+ // User just tabbed through without changes
+ if (moveTo && moveTo.parent) {
+ moveTo.startEditing(moveTo.valueElement);
+ return;
+ }
+
+ // User has made a change then tabbed, wiping all the original treeElements,
+ // recalculate the new treeElement for the same property we were going to edit next
+ if (moveTo && !moveTo.parent) {
+ var treeElement = section.findTreeElementWithName(moveToPropertyName);
+ if (treeElement)
+ treeElement.startEditing(treeElement.valueElement);
+ return;
+ }
+
+ // Create a new attribute in this section
+ if (newProperty) {
+ if (alreadyNew && !valueChanged)
+ return;
+
+ var item = section.addNewBlankProperty();
+ item.startEditing();
+ return;
+ }
+
+ if (moveToSelector)
+ section.startEditingSelector();
+ }
},
applyStyleText: function(styleText, updateInterface)
{
+ var section = this.treeOutline.section;
+ var elementsPanel = WebInspector.panels.elements;
var styleTextLength = styleText.trimWhitespace().length;
-
- // Create a new element to parse the user input CSS.
- var parseElement = document.createElement("span");
- parseElement.setAttribute("style", styleText);
-
- var tempStyle = parseElement.style;
- if (tempStyle.length || !styleTextLength) {
- // The input was parsable or the user deleted everything, so remove the
- // original property from the real style declaration. If this represents
- // a shorthand remove all the longhand properties.
- if (this.shorthand) {
- var longhandProperties = getLonghandProperties(this.style, this.name);
- for (var i = 0; i < longhandProperties.length; ++i)
- this.style.removeProperty(longhandProperties[i]);
- } else
- this.style.removeProperty(this.name);
- }
-
if (!styleTextLength) {
if (updateInterface) {
- // The user deleted the everything, so remove the tree element and update.
- if (this.treeOutline.section && this.treeOutline.section.pane)
- this.treeOutline.section.pane.update();
+ // The user deleted everything, so remove the tree element and update.
+ if (!this._newProperty)
+ delete section._afterUpdate;
+ if (section && section.pane)
+ section.pane.update();
this.parent.removeChild(this);
+ elementsPanel.removeStyleChange(section.identifier, this.style, this.name);
}
return;
}
- if (!tempStyle.length) {
- // The user typed something, but it didn't parse. Just abort and restore
- // the original title for this property.
- if (updateInterface)
- this.updateTitle();
- return;
- }
-
- // Iterate of the properties on the test element's style declaration and
- // add them to the real style declaration. We take care to move shorthands.
- var foundShorthands = {};
- var uniqueProperties = getUniqueStyleProperties(tempStyle);
- for (var i = 0; i < uniqueProperties.length; ++i) {
- var name = uniqueProperties[i];
- var shorthand = tempStyle.getPropertyShorthand(name);
-
- if (shorthand && shorthand in foundShorthands)
- continue;
-
- if (shorthand) {
- var value = getShorthandValue(tempStyle, shorthand);
- var priority = getShorthandPriority(tempStyle, shorthand);
- foundShorthands[shorthand] = true;
- } else {
- var value = tempStyle.getPropertyValue(name);
- var priority = tempStyle.getPropertyPriority(name);
+ var self = this;
+ var callback = function(result) {
+ if (!result) {
+ // The user typed something, but it didn't parse. Just abort and restore
+ // the original title for this property. If this was a new attribute and
+ // we couldn't parse, then just remove it.
+ if (self._newProperty) {
+ self.parent.removeChild(self);
+ return;
+ }
+ if (updateInterface)
+ self.updateTitle();
+ return;
}
- // Set the property on the real style declaration.
- this.style.setProperty((shorthand || name), value, priority);
- }
+ var newPayload = result[0];
+ var changedProperties = result[1];
+ elementsPanel.removeStyleChange(section.identifier, self.style, self.name);
- if (this.treeOutline.section && this.treeOutline.section.pane)
- this.treeOutline.section.pane.dispatchEventToListeners("style edited");
+ self.style = WebInspector.CSSStyleDeclaration.parseStyle(newPayload);
+ for (var i = 0; i < changedProperties.length; ++i)
+ elementsPanel.addStyleChange(section.identifier, self.style, changedProperties[i]);
+ self._styleRule.style = self.style;
+ if (section && section.pane)
+ section.pane.dispatchEventToListeners("style edited");
- if (updateInterface)
- this.updateAll(true);
+ if (updateInterface)
+ self.updateAll(true);
+
+ if (!self.rule)
+ WebInspector.panels.elements.treeOutline.update();
+ };
+ InspectorController.applyStyleText(this.style._id, styleText.trimWhitespace(), this.name, callback);
}
}
diff --git a/WebCore/inspector/front-end/TextPrompt.js b/WebCore/inspector/front-end/TextPrompt.js
index 61e1b52..5ff774f 100644
--- a/WebCore/inspector/front-end/TextPrompt.js
+++ b/WebCore/inspector/front-end/TextPrompt.js
@@ -66,6 +66,7 @@ WebInspector.TextPrompt.prototype = {
this._tabKeyPressed(event);
break;
case "Right":
+ case "End":
if (!this.acceptAutoComplete())
this.autoCompleteSoon();
break;
@@ -140,7 +141,6 @@ WebInspector.TextPrompt.prototype = {
complete: function(auto)
{
this.clearAutoComplete(true);
-
var selection = window.getSelection();
if (!selection.rangeCount)
return;
@@ -150,17 +150,24 @@ WebInspector.TextPrompt.prototype = {
return;
if (auto && !this.isCaretAtEndOfPrompt())
return;
-
var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this.completionStopCharacters, this.element, "backward");
- var completions = this.completions(wordPrefixRange, auto);
+ this.completions(wordPrefixRange, auto, this._completionsReady.bind(this, selection, auto, wordPrefixRange));
+ },
+ _completionsReady: function(selection, auto, originalWordPrefixRange, completions)
+ {
if (!completions || !completions.length)
return;
+ var selectionRange = selection.getRangeAt(0);
+
var fullWordRange = document.createRange();
- fullWordRange.setStart(wordPrefixRange.startContainer, wordPrefixRange.startOffset);
+ fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
+ if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
+ return;
+
if (completions.length === 1 || selection.isCollapsed || auto) {
var completionText = completions[0];
} else {
@@ -178,7 +185,7 @@ WebInspector.TextPrompt.prototype = {
var completionText = completions[foundIndex + 1];
}
- var wordPrefixLength = wordPrefixRange.toString().length;
+ var wordPrefixLength = originalWordPrefixRange.toString().length;
this._userEnteredRange = fullWordRange;
this._userEnteredText = fullWordRange.toString();
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 76a925b..c39c95b 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -4,24 +4,32 @@
<file>BottomUpProfileDataGridTree.js</file>
<file>Breakpoint.js</file>
<file>BreakpointsSidebarPane.js</file>
+ <file>Callback.js</file>
<file>CallStackSidebarPane.js</file>
- <file>Console.js</file>
+ <file>ChangesView.js</file>
+ <file>Color.js</file>
+ <file>ConsoleView.js</file>
<file>Database.js</file>
<file>DatabaseQueryView.js</file>
<file>DatabasesPanel.js</file>
<file>DatabaseTableView.js</file>
<file>DataGrid.js</file>
+ <file>DOMAgent.js</file>
<file>DOMStorage.js</file>
<file>DOMStorageDataGrid.js</file>
<file>DOMStorageItemsView.js</file>
+ <file>Drawer.js</file>
<file>ElementsPanel.js</file>
<file>ElementsTreeOutline.js</file>
<file>FontView.js</file>
<file>ImageView.js</file>
+ <file>InjectedScript.js</file>
<file>inspector.js</file>
+ <file>KeyboardShortcut.js</file>
<file>MetricsSidebarPane.js</file>
<file>Object.js</file>
<file>ObjectPropertiesSection.js</file>
+ <file>ObjectProxy.js</file>
<file>Panel.js</file>
<file>PanelEnablerView.js</file>
<file>Placard.js</file>
@@ -51,9 +59,9 @@
<file>inspector.css</file>
<file>Images/back.png</file>
<file>Images/checker.png</file>
- <file>Images/clearConsoleButtons.png</file>
+ <file>Images/clearConsoleButtonGlyph.png</file>
<file>Images/closeButtons.png</file>
- <file>Images/consoleButtons.png</file>
+ <file>Images/consoleButtonGlyph.png</file>
<file>Images/database.png</file>
<file>Images/databasesIcon.png</file>
<file>Images/databaseTable.png</file>
@@ -71,14 +79,15 @@
<file>Images/disclosureTriangleSmallRightDownBlack.png</file>
<file>Images/disclosureTriangleSmallRightDownWhite.png</file>
<file>Images/disclosureTriangleSmallRightWhite.png</file>
- <file>Images/dockButtons.png</file>
+ <file>Images/dockButtonGlyph.png</file>
<file>Images/domStorage.png</file>
<file>Images/elementsIcon.png</file>
- <file>Images/enableButtons.png</file>
+ <file>Images/enableOutlineButtonGlyph.png</file>
+ <file>Images/enableSolidButtonGlyph.png</file>
<file>Images/errorIcon.png</file>
<file>Images/errorMediumIcon.png</file>
- <file>Images/excludeButtons.png</file>
- <file>Images/focusButtons.png</file>
+ <file>Images/excludeButtonGlyph.png</file>
+ <file>Images/focusButtonGlyph.png</file>
<file>Images/forward.png</file>
<file>Images/glossyHeader.png</file>
<file>Images/glossyHeaderPressed.png</file>
@@ -87,21 +96,22 @@
<file>Images/goArrow.png</file>
<file>Images/graphLabelCalloutLeft.png</file>
<file>Images/graphLabelCalloutRight.png</file>
- <file>Images/largerResourcesButtons.png</file>
- <file>Images/nodeSearchButtons.png</file>
+ <file>Images/largerResourcesButtonGlyph.png</file>
+ <file>Images/nodeSearchButtonGlyph.png</file>
<file>Images/paneBottomGrow.png</file>
<file>Images/paneBottomGrowActive.png</file>
<file>Images/paneGrowHandleLine.png</file>
- <file>Images/pauseOnExceptionButtons.png</file>
- <file>Images/percentButtons.png</file>
+ <file>Images/pauseOnExceptionButtonGlyph.png</file>
+ <file>Images/percentButtonGlyph.png</file>
<file>Images/profileGroupIcon.png</file>
<file>Images/profileIcon.png</file>
<file>Images/profilesIcon.png</file>
<file>Images/profileSmallIcon.png</file>
<file>Images/profilesSilhouette.png</file>
<file>Images/radioDot.png</file>
- <file>Images/recordButtons.png</file>
- <file>Images/reloadButtons.png</file>
+ <file>Images/recordButtonGlyph.png</file>
+ <file>Images/recordToggledButtonGlyph.png</file>
+ <file>Images/reloadButtonGlyph.png</file>
<file>Images/resourceCSSIcon.png</file>
<file>Images/resourceDocumentIcon.png</file>
<file>Images/resourceDocumentIconSmall.png</file>
@@ -109,6 +119,7 @@
<file>Images/resourcePlainIcon.png</file>
<file>Images/resourcePlainIconSmall.png</file>
<file>Images/resourcesIcon.png</file>
+ <file>Images/resourcesSilhouette.png</file>
<file>Images/resourcesSizeGraphIcon.png</file>
<file>Images/resourcesTimeGraphIcon.png</file>
<file>Images/scriptsIcon.png</file>
@@ -157,6 +168,7 @@
<file>Images/treeRightTriangleWhite.png</file>
<file>Images/treeUpTriangleBlack.png</file>
<file>Images/treeUpTriangleWhite.png</file>
+ <file>Images/undockButtonGlyph.png</file>
<file>Images/userInputIcon.png</file>
<file>Images/userInputPreviousIcon.png</file>
<file>Images/userInputResultIcon.png</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 2653781..51d626a 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Anthony Ricaud <rik@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -259,7 +260,7 @@ body.attached #main {
right: 0;
}
-body.console-visible #main-status-bar {
+body.drawer-visible #main-status-bar {
height: 24px;
background-image: url(Images/statusbarResizerVertical.png), url(Images/statusbarBackground.png);
background-repeat: no-repeat, repeat-x;
@@ -267,11 +268,11 @@ body.console-visible #main-status-bar {
cursor: row-resize;
}
-body.console-visible #main-status-bar * {
+body.drawer-visible #main-status-bar * {
cursor: default;
}
-body.console-visible #main-panels {
+body.drawer-visible #main-panels {
bottom: 24px;
}
@@ -306,14 +307,39 @@ body.console-visible #main-panels {
z-index: 200;
}
+.glyph {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.75);
+ z-index: 1;
+}
+
+.glyph.shadow {
+ top: 1px;
+ background-color: white !important;
+ z-index: 0;
+}
+
button.status-bar-item {
+ position: relative;
width: 32px;
background-image: url(Images/statusbarButtons.png);
background-position: 0 0;
}
button.status-bar-item:active {
- background-position: 32px 0;
+ background-position: 32px 0 !important;
+}
+
+button.status-bar-item .glyph.shadow {
+ background-color: rgba(255, 255, 255, 0.33) !important;
+}
+
+button.status-bar-item.toggled-on .glyph {
+ background-color: rgb(66, 129, 235);
}
button.status-bar-item:disabled {
@@ -338,47 +364,31 @@ select.status-bar-item:active {
-webkit-border-image: url(Images/statusbarMenuButtonSelected.png) 0 17 0 2;
}
-#dock-status-bar-item {
- background-image: url(Images/dockButtons.png);
-}
-
-body.attached #dock-status-bar-item:active {
- background-position: 32px 0;
-}
-
-body.detached #dock-status-bar-item {
- background-position: 0 24px;
+#dock-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/undockButtonGlyph.png);
}
-body.detached #dock-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+body.detached #dock-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/dockButtonGlyph.png);
}
-#console-status-bar-item {
- background-image: url(Images/consoleButtons.png);
+#console-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/consoleButtonGlyph.png);
}
-#console-status-bar-item:active {
- background-position: 32px 0;
+#clear-console-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/clearConsoleButtonGlyph.png);
}
-#console-status-bar-item.toggled-on {
- background-position: 0 24px;
+#changes-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/consoleButtonGlyph.png); /* TODO: Needs Image for Changes Toggle Button */
}
-#console-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+#clear-changes-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/clearConsoleButtonGlyph.png);
}
-#clear-console-status-bar-item {
- background-image: url(Images/clearConsoleButtons.png);
-}
-
-#clear-console-status-bar-item:active {
- background-position: 32px 0;
-}
-
-#error-warning-count {
+#count-items {
position: absolute;
right: 16px;
top: 0;
@@ -388,10 +398,22 @@ body.detached #dock-status-bar-item.toggled-on:active {
height: 19px;
}
-#error-warning-count:hover {
+#changes-count, #error-warning-count {
+ display: inline;
+}
+
+#error-warning-count:hover, #changes-count:hover {
border-bottom: 1px solid rgb(96, 96, 96);
}
+#style-changes-count::before {
+ content: url(Images/styleIcon.png); /* TODO: Needs Image for Style Changes Icon */
+ width: 10px;
+ height: 10px;
+ vertical-align: -1px;
+ margin-right: 2px;
+}
+
#error-count::before {
content: url(Images/errorIcon.png);
width: 10px;
@@ -399,8 +421,8 @@ body.detached #dock-status-bar-item.toggled-on:active {
vertical-align: -1px;
margin-right: 2px;
}
-
-#error-count + #warning-count {
+
+#changes-count + #error-warning-count, #error-count + #warning-count {
margin-left: 6px;
}
@@ -412,7 +434,7 @@ body.detached #dock-status-bar-item.toggled-on:active {
margin-right: 2px;
}
-#console {
+#drawer {
display: none;
position: absolute;
bottom: 0;
@@ -425,11 +447,11 @@ body.detached #dock-status-bar-item.toggled-on:active {
background-position: bottom;
}
-body.console-visible #console {
+body.drawer-visible #drawer {
display: block;
}
-#console-status-bar {
+#drawer-status-bar {
position: absolute;
bottom: 0;
left: 0;
@@ -444,8 +466,8 @@ body.console-visible #console {
left: 0;
right: 0;
bottom: 23px;
- font-size: 10px;
- font-family: Monaco, Lucida Console, monospace;
+ font-size: initial;
+ font-family: monospace;
padding: 2px 0;
overflow-y: overlay;
-webkit-user-select: text;
@@ -483,7 +505,7 @@ body.console-visible #console {
background-image: none;
}
-.console-message::before, .console-user-command::before, #console-prompt::before, .console-group-title-level::before {
+.console-message::before, .console-user-command::before, #console-prompt::before, .console-group-title::before {
position: absolute;
display: block;
content: "";
@@ -529,18 +551,18 @@ body.console-visible #console {
margin-left: 16px;
}
-.console-group-title-level {
+.console-group-title {
font-weight: bold;
}
-.console-group-title-level::before {
+.console-group-title::before {
background-image: url(Images/disclosureTriangleSmallDown.png);
top: 0.6em;
width: 11px;
height: 12px;
}
-.console-group.collapsed .console-group-title-level::before {
+.console-group.collapsed .console-group-title::before {
background-image: url(Images/disclosureTriangleSmallRight.png);
}
@@ -644,6 +666,10 @@ body.console-visible #console {
margin-right: -6px;
}
+.console-group-messages .add-attribute {
+ display: none;
+}
+
.console-formatted-object, .console-formatted-node {
position: relative;
display: inline-block;
@@ -768,6 +794,11 @@ body.console-visible #console {
vertical-align: top;
}
+.invisible {
+ color: inherit;
+ text-decoration: none;
+}
+
.webkit-line-gutter-backdrop {
/* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */
width: 31px;
@@ -1090,6 +1121,11 @@ body.console-visible #console {
text-decoration: underline;
}
+.add-attribute {
+ margin-left: 1px;
+ margin-right: 1px;
+}
+
.placard {
position: relative;
margin-top: 1px;
@@ -1168,6 +1204,10 @@ body.inactive .placard.selected {
-webkit-background-clip: padding;
}
+.section.no-affect .header {
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(167, 167, 167)), to(rgb(123, 123, 123)))
+}
+
.section .header::before {
position: absolute;
top: 4px;
@@ -1177,6 +1217,10 @@ body.inactive .placard.selected {
content: url(Images/treeRightTriangleWhite.png);
}
+.section.blank-section .header::before {
+ display: none;
+}
+
.section.expanded .header::before {
content: url(Images/treeDownTriangleWhite.png);
}
@@ -1188,6 +1232,10 @@ body.inactive .placard.selected {
white-space: normal;
}
+.section .header .title.blank-title {
+ font-style: italic;
+}
+
.section .header label {
display: none;
}
@@ -1225,6 +1273,15 @@ body.inactive .placard.selected {
padding: 2px 6px 3px;
list-style: none;
background-color: white;
+ min-height: 18px;
+}
+
+.section.no-affect .properties li {
+ opacity: 0.5;
+}
+
+.section.no-affect .properties li.editing {
+ opacity: 1.0;
}
.section.expanded .properties {
@@ -1810,9 +1867,18 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
text-indent: 10px;
}
+.data-grid-resizer {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 5px;
+ z-index: 500;
+ cursor: col-resize;
+}
+
.storage-view.query {
- font-size: 10px;
- font-family: Monaco, Lucida Console, monospace;
+ font-size: initial;
+ font-family: monospace;
padding: 2px 0;
overflow-y: overlay;
overflow-x: hidden;
@@ -2006,7 +2072,7 @@ body.inactive .panel-enabler-view button, .panel-enabler-view button:disabled {
}
.panel-enabler-view.resources img {
- content: url(Images/scriptsSilhouette.png);
+ content: url(Images/resourcesSilhouette.png);
}
.panel-enabler-view.scripts img {
@@ -2017,36 +2083,16 @@ body.inactive .panel-enabler-view button, .panel-enabler-view button:disabled {
content: url(Images/profilesSilhouette.png);
}
-button.enable-toggle-status-bar-item {
- background-image: url(Images/enableButtons.png);
-}
-
-button.enable-toggle-status-bar-item:active {
- background-position: 32px 0;
-}
-
-button.enable-toggle-status-bar-item.toggled-on {
- background-position: 0 24px;
-}
-
-button.enable-toggle-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
-}
-
-#scripts-pause-on-exceptions-status-bar-item {
- background-image: url(Images/pauseOnExceptionButtons.png);
+button.enable-toggle-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/enableOutlineButtonGlyph.png);
}
-#scripts-pause-on-exceptions-status-bar-item:active {
- background-position: 32px 0;
-}
-
-#scripts-pause-on-exceptions-status-bar-item.toggled-on {
- background-position: 0 24px;
+button.enable-toggle-status-bar-item.toggled-on .glyph {
+ -webkit-mask-image: url(Images/enableSolidButtonGlyph.png);
}
-#scripts-pause-on-exceptions-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+#scripts-pause-on-exceptions-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/pauseOnExceptionButtonGlyph.png);
}
#scripts-status-bar {
@@ -2163,25 +2209,54 @@ button.enable-toggle-status-bar-item.toggled-on:active {
overflow: auto;
}
-#resources-larger-resources-status-bar-item {
- background-image: url(Images/largerResourcesButtons.png);
+#resources-larger-resources-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/largerResourcesButtonGlyph.png);
}
-#resources-larger-resources-status-bar-item:active {
- background-position: 32px 0;
+#resources-filter {
+ height: 24px;
+ padding: 2px 10px 0;
+ background: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(207, 207, 207)));
+ border-bottom: 1px solid rgb(177, 177, 177);
+ overflow: hidden;
}
-#resources-larger-resources-status-bar-item.toggled-on {
- background-position: 0 24px;
+#resources-filter li {
+ display: inline-block;
+ margin: 1px 1px 0 0;
+ padding: 0 6px 3px;
+ font-size: 12px;
+ line-height: 12px;
+ font-weight: bold;
+ color: rgb(40, 40, 40);
+ border: 1px solid transparent;
+ border-bottom: 0;
+ background: transparent;
+ -webkit-border-radius: 8px;
+ text-shadow: rgba(255, 255, 255, 0.5) 1px 1px 0;
+}
+
+#resources-filter li.selected, #resources-filter li:hover, #resources-filter li:active {
+ color: white;
+ text-shadow: rgb(80, 80, 80) 1px 1px 1px;
+ background: rgba(20, 20, 20, 0.4);
+ border-color: rgba(20, 20, 20, 0.2);
+ -webkit-box-shadow: 0 1px 0px rgba(255, 255, 255, 0.5);
}
-#resources-larger-resources-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+#resources-filter li:hover {
+ background: rgba(20, 20, 20, 0.4);
+ border-color: transparent;
+ -webkit-box-shadow: none;
+}
+
+#resources-filter li:active {
+ background: rgba(20, 20, 20, 0.6);
}
#resources-container {
position: absolute;
- top: 0;
+ top: 24px;
left: 0;
bottom: 0;
right: 0;
@@ -2386,6 +2461,22 @@ button.enable-toggle-status-bar-item.toggled-on:active {
-webkit-border-image: url(Images/timelinePillGray.png) 6 7 6 7;
}
+.resources-category-documents, .resources-category-stylesheets, .resources-category-images,
+.resources-category-scripts, .resources-category-xhr, .resources-category-fonts, .resources-category-other {
+ display: none;
+}
+
+.filter-all .resources-category-documents, .filter-documents .resources-category-documents,
+.filter-all .resources-category-stylesheets, .filter-stylesheets .resources-category-stylesheets,
+.filter-all .resources-category-images, .filter-images .resources-category-images,
+.filter-all .resources-category-scripts, .filter-scripts .resources-category-scripts,
+.filter-all .resources-category-xhr, .filter-xhr .resources-category-xhr,
+.filter-all .resources-category-fonts, .filter-fonts .resources-category-fonts,
+.filter-all .resources-category-other, .filter-other .resources-category-other,
+.resource-sidebar-tree-item.selected {
+ display: list-item;
+}
+
.resources-graph-bar.waiting {
opacity: 0.35;
}
@@ -2489,7 +2580,7 @@ button.enable-toggle-status-bar-item.toggled-on:active {
#resource-views {
position: absolute;
- top: 0;
+ top: 24px;
right: 0;
left: 200px;
bottom: 0;
@@ -2509,6 +2600,10 @@ button.enable-toggle-status-bar-item.toggled-on:active {
cursor: col-resize;
}
+.resources .sidebar-resizer-vertical {
+ top: 24px;
+}
+
.sidebar-tree, .sidebar-tree .children {
position: relative;
padding: 0;
@@ -2995,84 +3090,40 @@ body.inactive .sidebar-tree-item.selected .bubble.search-matches {
color: white;
}
-#record-profile-status-bar-item {
- background-image: url(Images/recordButtons.png);
-}
-
-#record-profile-status-bar-item:active {
- background-position: 32px 0;
-}
-
-#record-profile-status-bar-item.toggled-on {
- background-position: 0 24px;
-}
-
-#record-profile-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+button.enable-toggle-status-bar-item .glyph {
}
-#node-search-status-bar-item {
- background-image: url(Images/nodeSearchButtons.png);
+#record-profile-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/recordButtonGlyph.png);
}
-#node-search-status-bar-item:active {
- background-position: 32px 0;
+#record-profile-status-bar-item.toggled-on .glyph {
+ -webkit-mask-image: url(Images/recordToggledButtonGlyph.png);
+ background-color: rgb(216, 0, 0);
}
-#node-search-status-bar-item.toggled-on {
- background-position: 0 24px;
+#node-search-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/nodeSearchButtonGlyph.png);
}
-#node-search-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
+.percent-time-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/percentButtonGlyph.png);
}
-.percent-time-status-bar-item {
- background-image: url(Images/percentButtons.png) !important;
+.focus-profile-node-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/focusButtonGlyph.png);
}
-.percent-time-status-bar-item:active {
- background-position: 32px 0;
+.exclude-profile-node-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/excludeButtonGlyph.png);
}
-.percent-time-status-bar-item.toggled-on {
- background-position: 0 24px;
+.reset-profile-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/reloadButtonGlyph.png);
}
-.percent-time-status-bar-item.toggled-on:active {
- background-position: 32px 24px;
-}
-
-.focus-profile-node-status-bar-item {
- background-image: url(Images/focusButtons.png) !important;
-}
-
-.focus-profile-node-status-bar-item:active {
- background-position: 32px 0;
-}
-
-.exclude-profile-node-status-bar-item {
- background-image: url(Images/excludeButtons.png) !important;
-}
-
-.exclude-profile-node-status-bar-item:active {
- background-position: 32px 0;
-}
-
-.reset-profile-status-bar-item {
- background-image: url(Images/reloadButtons.png) !important;
-}
-
-.reset-profile-status-bar-item:active {
- background-position: 32px 0;
-}
-
-.delete-storage-status-bar-item {
- background-image: url(Images/excludeButtons.png) !important;
-}
-
-.delete-storage-status-bar-item:active {
- background-position: 32px 0;
+.delete-storage-status-bar-item .glyph {
+ -webkit-mask-image: url(Images/excludeButtonGlyph.png);
}
#storage-view-status-bar-items {
@@ -3102,3 +3153,41 @@ body.inactive .sidebar-tree-item.selected .bubble.search-matches {
border-left: 1px solid rgb(184, 184, 184);
margin-left: -1px;
}
+
+ol.breakpoint-list {
+ -webkit-padding-start: 2px;
+ list-style: none;
+ margin: 0;
+}
+
+.breakpoint-list li {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ margin: 4px 0;
+}
+
+.breakpoint-list .checkbox-elem {
+ font-size: 10px;
+ margin: 0 4px;
+ vertical-align: top;
+ position: relative;
+ z-index: 1;
+}
+
+.breakpoint-list .source-text {
+ font-family: monospace;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ margin: 2px 0 0px 20px;
+}
+
+.breakpoint-list a {
+ color: rgb(33%, 33%, 33%);
+ cursor: pointer;
+}
+
+.breakpoint-list a:hover {
+ color: rgb(15%, 15%, 15%);
+}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 184bb45..a3dc407 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -34,10 +34,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="treeoutline.js"></script>
<script type="text/javascript" src="inspector.js"></script>
<script type="text/javascript" src="Object.js"></script>
+ <script type="text/javascript" src="KeyboardShortcut.js"></script>
<script type="text/javascript" src="TextPrompt.js"></script>
<script type="text/javascript" src="Placard.js"></script>
<script type="text/javascript" src="View.js"></script>
- <script type="text/javascript" src="Console.js"></script>
+ <script type="text/javascript" src="Callback.js"></script>
+ <script type="text/javascript" src="Drawer.js"></script>
+ <script type="text/javascript" src="ChangesView.js"></script>
+ <script type="text/javascript" src="ConsoleView.js"></script>
<script type="text/javascript" src="Resource.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="Database.js"></script>
@@ -51,12 +55,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="ElementsTreeOutline.js"></script>
<script type="text/javascript" src="SidebarTreeElement.js"></script>
<script type="text/javascript" src="PropertiesSection.js"></script>
+ <script type="text/javascript" src="ObjectProxy.js"></script>
<script type="text/javascript" src="ObjectPropertiesSection.js"></script>
<script type="text/javascript" src="BreakpointsSidebarPane.js"></script>
<script type="text/javascript" src="CallStackSidebarPane.js"></script>
<script type="text/javascript" src="ScopeChainSidebarPane.js"></script>
<script type="text/javascript" src="MetricsSidebarPane.js"></script>
<script type="text/javascript" src="PropertiesSidebarPane.js"></script>
+ <script type="text/javascript" src="Color.js"></script>
<script type="text/javascript" src="StylesSidebarPane.js"></script>
<script type="text/javascript" src="Panel.js"></script>
<script type="text/javascript" src="PanelEnablerView.js"></script>
@@ -77,6 +83,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="BottomUpProfileDataGridTree.js"></script>
<script type="text/javascript" src="TopDownProfileDataGridTree.js"></script>
<script type="text/javascript" src="ProfileView.js"></script>
+ <script type="text/javascript" src="DOMAgent.js"></script>
+ <script type="text/javascript" src="InjectedScript.js"></script>
</head>
<body class="detached">
<div id="toolbar">
@@ -86,12 +94,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<div class="toolbar-item"><input id="search" type="search" incremental results="0"><div id="search-toolbar-label" class="toolbar-label"></div></div>
</div>
<div id="main">
- <div id="main-panels" tabindex="0"></div>
- <div id="main-status-bar" class="status-bar"><div id="anchored-status-bar-items"><button id="dock-status-bar-item" class="status-bar-item toggled"></button><button id="console-status-bar-item" class="status-bar-item"></button><div id="error-warning-count" class="hidden"></div></div></div>
+ <div id="main-panels" tabindex="0" spellcheck="false"></div>
+ <div id="main-status-bar" class="status-bar"><div id="anchored-status-bar-items"><button id="dock-status-bar-item" class="status-bar-item toggled"><div class="glyph"></div><div class="glyph shadow"></div></button><button id="console-status-bar-item" class="status-bar-item"><div class="glyph"></div><div class="glyph shadow"></div></button><button id="changes-status-bar-item" class="status-bar-item hidden"></button><div id="count-items"><div id="changes-count" class="hidden"></div><div id="error-warning-count" class="hidden"></div></div></div></div>
</div>
- <div id="console">
- <div id="console-messages"><div id="console-prompt"><br></div></div>
- <div id="console-status-bar" class="status-bar"><div id="other-console-status-bar-items"><button id="clear-console-status-bar-item" class="status-bar-item"></button></div></div>
+ <div id="drawer">
+ <div id="console-view"><div id="console-messages"><div id="console-prompt" spellcheck="false"><br></div></div></div>
+ <div id="drawer-status-bar" class="status-bar"><div id="other-drawer-status-bar-items"><button id="clear-console-status-bar-item" class="status-bar-item"><div class="glyph"></div><div class="glyph shadow"></div></button></div></div>
</div>
</body>
</html>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 9d5bac0..aa21a86 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
+ * Copyright (C) 2009 Joseph Pecoraro
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +38,8 @@ var Preferences = {
minScriptsSidebarWidth: 200,
showInheritedComputedStyleProperties: false,
styleRulesExpandedState: {},
- showMissingLocalizedStrings: false
+ showMissingLocalizedStrings: false,
+ useDOMAgent: false
}
var WebInspector = {
@@ -117,6 +119,26 @@ var WebInspector = {
}
}
}
+
+ for (var panelName in WebInspector.panels) {
+ if (WebInspector.panels[panelName] == x)
+ InspectorController.storeLastActivePanel(panelName);
+ }
+ },
+
+ _createPanels: function()
+ {
+ var hiddenPanels = (InspectorController.hiddenPanels() || "").split(',');
+ if (hiddenPanels.indexOf("elements") === -1)
+ this.panels.elements = new WebInspector.ElementsPanel();
+ if (hiddenPanels.indexOf("resources") === -1)
+ this.panels.resources = new WebInspector.ResourcesPanel();
+ if (hiddenPanels.indexOf("scripts") === -1)
+ this.panels.scripts = new WebInspector.ScriptsPanel();
+ if (hiddenPanels.indexOf("profiles") === -1)
+ this.panels.profiles = new WebInspector.ProfilesPanel();
+ if (hiddenPanels.indexOf("databases") === -1)
+ this.panels.databases = new WebInspector.DatabasesPanel();
},
get attached()
@@ -231,6 +253,53 @@ var WebInspector = {
errorWarningElement.title = null;
},
+ get styleChanges()
+ {
+ return this._styleChanges;
+ },
+
+ set styleChanges(x)
+ {
+ x = Math.max(x, 0);
+
+ if (this._styleChanges === x)
+ return;
+ this._styleChanges = x;
+ this._updateChangesCount();
+ },
+
+ _updateChangesCount: function()
+ {
+ // TODO: Remove immediate return when enabling the Changes Panel
+ return;
+
+ var changesElement = document.getElementById("changes-count");
+ if (!changesElement)
+ return;
+
+ if (!this.styleChanges) {
+ changesElement.addStyleClass("hidden");
+ return;
+ }
+
+ changesElement.removeStyleClass("hidden");
+ changesElement.removeChildren();
+
+ if (this.styleChanges) {
+ var styleChangesElement = document.createElement("span");
+ styleChangesElement.id = "style-changes-count";
+ styleChangesElement.textContent = this.styleChanges;
+ changesElement.appendChild(styleChangesElement);
+ }
+
+ if (this.styleChanges) {
+ if (this.styleChanges === 1)
+ changesElement.title = WebInspector.UIString("%d style change", this.styleChanges);
+ else
+ changesElement.title = WebInspector.UIString("%d style changes", this.styleChanges);
+ }
+ },
+
get hoveredDOMNode()
{
return this._hoveredDOMNode;
@@ -278,27 +347,37 @@ WebInspector.loaded = function()
var platform = InspectorController.platform();
document.body.addStyleClass("platform-" + platform);
- this.console = new WebInspector.Console();
+ this.drawer = new WebInspector.Drawer();
+ this.console = new WebInspector.ConsoleView(this.drawer);
+ // TODO: Uncomment when enabling the Changes Panel
+ // this.changes = new WebInspector.ChangesView(this.drawer);
+ // TODO: Remove class="hidden" from inspector.html on button#changes-status-bar-item
+ this.drawer.visibleView = this.console;
+
+ if (Preferences.useDOMAgent)
+ this.domAgent = new WebInspector.DOMAgent();
+
+ this.resourceCategories = {
+ documents: new WebInspector.ResourceCategory(WebInspector.UIString("Documents"), "documents"),
+ stylesheets: new WebInspector.ResourceCategory(WebInspector.UIString("Stylesheets"), "stylesheets"),
+ images: new WebInspector.ResourceCategory(WebInspector.UIString("Images"), "images"),
+ scripts: new WebInspector.ResourceCategory(WebInspector.UIString("Scripts"), "scripts"),
+ xhr: new WebInspector.ResourceCategory(WebInspector.UIString("XHR"), "xhr"),
+ fonts: new WebInspector.ResourceCategory(WebInspector.UIString("Fonts"), "fonts"),
+ other: new WebInspector.ResourceCategory(WebInspector.UIString("Other"), "other")
+ };
this.panels = {};
- var hiddenPanels = (InspectorController.hiddenPanels() || "").split(',');
- if (hiddenPanels.indexOf("elements") === -1)
- this.panels.elements = new WebInspector.ElementsPanel();
- if (hiddenPanels.indexOf("resources") === -1)
- this.panels.resources = new WebInspector.ResourcesPanel();
- if (hiddenPanels.indexOf("scripts") === -1)
- this.panels.scripts = new WebInspector.ScriptsPanel();
- if (hiddenPanels.indexOf("profiles") === -1)
- this.panels.profiles = new WebInspector.ProfilesPanel();
- if (hiddenPanels.indexOf("databases") === -1)
- this.panels.databases = new WebInspector.DatabasesPanel();
+ this._createPanels();
var toolbarElement = document.getElementById("toolbar");
var previousToolbarItem = toolbarElement.children[0];
+ this.panelOrder = [];
for (var panelName in this.panels) {
var panel = this.panels[panelName];
var panelToolbarItem = panel.toolbarItem;
+ this.panelOrder.push(panel);
panelToolbarItem.addEventListener("click", this._toolbarItemClicked.bind(this));
if (previousToolbarItem)
toolbarElement.insertBefore(panelToolbarItem, previousToolbarItem.nextSibling);
@@ -307,18 +386,6 @@ WebInspector.loaded = function()
previousToolbarItem = panelToolbarItem;
}
- this.currentPanel = this.panels.elements;
-
- this.resourceCategories = {
- documents: new WebInspector.ResourceCategory(WebInspector.UIString("Documents"), "documents"),
- stylesheets: new WebInspector.ResourceCategory(WebInspector.UIString("Stylesheets"), "stylesheets"),
- images: new WebInspector.ResourceCategory(WebInspector.UIString("Images"), "images"),
- scripts: new WebInspector.ResourceCategory(WebInspector.UIString("Scripts"), "scripts"),
- xhr: new WebInspector.ResourceCategory(WebInspector.UIString("XHR"), "xhr"),
- fonts: new WebInspector.ResourceCategory(WebInspector.UIString("Fonts"), "fonts"),
- other: new WebInspector.ResourceCategory(WebInspector.UIString("Other"), "other")
- };
-
this.Tips = {
ResourceNotCompressed: {id: 0, message: WebInspector.UIString("You could save bandwidth by having your web server compress this transfer with gzip or zlib.")}
};
@@ -357,9 +424,15 @@ WebInspector.loaded = function()
dockToggleButton.title = WebInspector.UIString("Dock to main window.");
var errorWarningCount = document.getElementById("error-warning-count");
- errorWarningCount.addEventListener("click", this.console.show.bind(this.console), false);
+ errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
this._updateErrorAndWarningCounts();
+ this.styleChanges = 0;
+ // TODO: Uncomment when enabling the Changes Panel
+ // var changesElement = document.getElementById("changes-count");
+ // changesElement.addEventListener("click", this.showChanges.bind(this), false);
+ // this._updateErrorAndWarningCounts();
+
var searchField = document.getElementById("search");
searchField.addEventListener("keydown", this.searchKeyDown.bind(this), false);
searchField.addEventListener("keyup", this.searchKeyUp.bind(this), false);
@@ -368,7 +441,7 @@ WebInspector.loaded = function()
document.getElementById("toolbar").addEventListener("mousedown", this.toolbarDragStart, true);
document.getElementById("close-button").addEventListener("click", this.close, true);
- InspectorController.loaded();
+ InspectorController.loaded(Preferences.useDOMAgent);
}
var windowLoaded = function()
@@ -488,7 +561,7 @@ WebInspector.documentKeyDown = function(event)
switch (event.keyIdentifier) {
case "U+001B": // Escape key
- this.console.visible = !this.console.visible;
+ this.drawer.visible = !this.drawer.visible;
event.preventDefault();
break;
@@ -523,6 +596,36 @@ WebInspector.documentKeyDown = function(event)
}
break;
+
+ case "U+005B": // [ key
+ if (isMac)
+ var isRotateLeft = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
+ else
+ var isRotateLeft = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+
+ if (isRotateLeft) {
+ var index = this.panelOrder.indexOf(this.currentPanel);
+ index = (index === 0) ? this.panelOrder.length - 1 : index - 1;
+ this.panelOrder[index].toolbarItem.click();
+ event.preventDefault();
+ }
+
+ break;
+
+ case "U+005D": // ] key
+ if (isMac)
+ var isRotateRight = event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey;
+ else
+ var isRotateRight = event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+
+ if (isRotateRight) {
+ var index = this.panelOrder.indexOf(this.currentPanel);
+ index = (index + 1) % this.panelOrder.length;
+ this.panelOrder[index].toolbarItem.click();
+ event.preventDefault();
+ }
+
+ break;
}
}
}
@@ -588,6 +691,7 @@ WebInspector.animateStyle = function(animations, duration, callback, complete)
var start = null;
var current = null;
var end = null;
+ var key = null;
for (key in animation) {
if (key === "element")
element = animation[key];
@@ -749,7 +853,12 @@ WebInspector.elementDragEnd = function(event)
WebInspector.showConsole = function()
{
- this.console.show();
+ this.drawer.visibleView = this.console;
+}
+
+WebInspector.showChanges = function()
+{
+ this.drawer.visibleView = this.changes;
}
WebInspector.showElementsPanel = function()
@@ -979,6 +1088,7 @@ WebInspector.addMessageToConsole = function(payload)
{
var consoleMessage = new WebInspector.ConsoleMessage(
payload.source,
+ payload.type,
payload.level,
payload.line,
payload.url,
@@ -1277,6 +1387,7 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba
var oldText = element.textContent;
var oldHandleKeyEvent = element.handleKeyEvent;
+ var moveDirection = "";
element.addStyleClass("editing");
@@ -1314,7 +1425,7 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba
function editingCommitted() {
cleanUpAfterEditing.call(this);
- committedCallback(this, this.textContent, oldText, context);
+ committedCallback(this, this.textContent, oldText, context, moveDirection);
}
element.handleKeyEvent = function(event) {
@@ -1330,7 +1441,8 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba
editingCancelled.call(element);
event.preventDefault();
event.handled = true;
- }
+ } else if (event.keyIdentifier === "U+0009") // Tab key
+ moveDirection = (event.shiftKey ? "backward" : "forward");
}
element.addEventListener("blur", blurEventListener, false);
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 8fb50e2..eec0b87 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -38,7 +38,7 @@ Object.type = function(obj, win)
win = win || window;
if (obj instanceof win.Node)
- return "node";
+ return (obj.nodeType === undefined ? type : "node");
if (obj instanceof win.String)
return "string";
if (obj instanceof win.Array)
@@ -94,15 +94,19 @@ Object.describe = function(obj, abbreviated)
}
}
-Object.sortedProperties = function(obj)
+Object.properties = function(obj)
{
var properties = [];
for (var prop in obj)
properties.push(prop);
- properties.sort();
return properties;
}
+Object.sortedProperties = function(obj, sortFunc)
+{
+ return Object.properties(obj).sort(sortFunc);
+}
+
Function.prototype.bind = function(thisObject)
{
var func = this;
@@ -381,113 +385,6 @@ String.prototype.trimURL = function(baseURLDomain)
return result;
}
-function getStyleTextWithShorthands(style)
-{
- var cssText = "";
- var foundProperties = {};
- for (var i = 0; i < style.length; ++i) {
- var individualProperty = style[i];
- var shorthandProperty = style.getPropertyShorthand(individualProperty);
- var propertyName = (shorthandProperty || individualProperty);
-
- if (propertyName in foundProperties)
- continue;
-
- if (shorthandProperty) {
- var value = getShorthandValue(style, shorthandProperty);
- var priority = getShorthandPriority(style, shorthandProperty);
- } else {
- var value = style.getPropertyValue(individualProperty);
- var priority = style.getPropertyPriority(individualProperty);
- }
-
- foundProperties[propertyName] = true;
-
- cssText += propertyName + ": " + value;
- if (priority)
- cssText += " !" + priority;
- cssText += "; ";
- }
-
- return cssText;
-}
-
-function getShorthandValue(style, shorthandProperty)
-{
- var value = style.getPropertyValue(shorthandProperty);
- if (!value) {
- // Some shorthands (like border) return a null value, so compute a shorthand value.
- // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 is fixed.
-
- var foundProperties = {};
- for (var i = 0; i < style.length; ++i) {
- var individualProperty = style[i];
- if (individualProperty in foundProperties || style.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
-
- var individualValue = style.getPropertyValue(individualProperty);
- if (style.isPropertyImplicit(individualProperty) || individualValue === "initial")
- continue;
-
- foundProperties[individualProperty] = true;
-
- if (!value)
- value = "";
- else if (value.length)
- value += " ";
- value += individualValue;
- }
- }
- return value;
-}
-
-function getShorthandPriority(style, shorthandProperty)
-{
- var priority = style.getPropertyPriority(shorthandProperty);
- if (!priority) {
- for (var i = 0; i < style.length; ++i) {
- var individualProperty = style[i];
- if (style.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
- priority = style.getPropertyPriority(individualProperty);
- break;
- }
- }
- return priority;
-}
-
-function getLonghandProperties(style, shorthandProperty)
-{
- var properties = [];
- var foundProperties = {};
-
- for (var i = 0; i < style.length; ++i) {
- var individualProperty = style[i];
- if (individualProperty in foundProperties || style.getPropertyShorthand(individualProperty) !== shorthandProperty)
- continue;
- foundProperties[individualProperty] = true;
- properties.push(individualProperty);
- }
-
- return properties;
-}
-
-function getUniqueStyleProperties(style)
-{
- var properties = [];
- var foundProperties = {};
-
- for (var i = 0; i < style.length; ++i) {
- var property = style[i];
- if (property in foundProperties)
- continue;
- foundProperties[property] = true;
- properties.push(property);
- }
-
- return properties;
-}
-
function isNodeWhitespace()
{
if (!this || this.nodeType !== Node.TEXT_NODE)