summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/inspector/front-end
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/inspector/front-end')
-rw-r--r--Source/WebCore/inspector/front-end/AuditLauncherView.js58
-rw-r--r--Source/WebCore/inspector/front-end/AuditRules.js8
-rw-r--r--Source/WebCore/inspector/front-end/AuditsPanel.js15
-rw-r--r--Source/WebCore/inspector/front-end/Breakpoint.js43
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointManager.js4
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js218
-rw-r--r--Source/WebCore/inspector/front-end/CSSCompletions.js2
-rwxr-xr-xSource/WebCore/inspector/front-end/CSSKeywordCompletions.js438
-rw-r--r--Source/WebCore/inspector/front-end/ConsoleView.js51
-rw-r--r--Source/WebCore/inspector/front-end/DebuggerModel.js87
-rw-r--r--Source/WebCore/inspector/front-end/ElementsTreeOutline.js3
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionAPI.js3
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionPanel.js2
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionServer.js18
-rw-r--r--Source/WebCore/inspector/front-end/InjectedScriptAccess.js96
-rw-r--r--Source/WebCore/inspector/front-end/NetworkManager.js42
-rw-r--r--Source/WebCore/inspector/front-end/NetworkPanel.js27
-rw-r--r--Source/WebCore/inspector/front-end/PropertiesSidebarPane.js14
-rw-r--r--Source/WebCore/inspector/front-end/RemoteObject.js8
-rw-r--r--Source/WebCore/inspector/front-end/Resource.js12
-rw-r--r--Source/WebCore/inspector/front-end/ResourcesPanel.js5
-rw-r--r--Source/WebCore/inspector/front-end/Script.js6
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatter.js134
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatterWorker.js64
-rw-r--r--Source/WebCore/inspector/front-end/ScriptView.js2
-rw-r--r--Source/WebCore/inspector/front-end/ScriptsPanel.js121
-rw-r--r--Source/WebCore/inspector/front-end/Settings.js1
-rw-r--r--Source/WebCore/inspector/front-end/SourceFrame.js203
-rw-r--r--Source/WebCore/inspector/front-end/SourceView.js4
-rw-r--r--Source/WebCore/inspector/front-end/StylesSidebarPane.js184
-rw-r--r--Source/WebCore/inspector/front-end/TextPrompt.js55
-rw-r--r--Source/WebCore/inspector/front-end/TextViewer.js57
-rw-r--r--Source/WebCore/inspector/front-end/UglifyJS/parse-js.js1233
-rwxr-xr-xSource/WebCore/inspector/front-end/UglifyJS/process.js1560
-rw-r--r--Source/WebCore/inspector/front-end/WebKit.qrc6
-rw-r--r--Source/WebCore/inspector/front-end/inspector.css4
-rw-r--r--Source/WebCore/inspector/front-end/inspector.html3
-rw-r--r--Source/WebCore/inspector/front-end/inspector.js23
-rw-r--r--Source/WebCore/inspector/front-end/utilities.js16
39 files changed, 4188 insertions, 642 deletions
diff --git a/Source/WebCore/inspector/front-end/AuditLauncherView.js b/Source/WebCore/inspector/front-end/AuditLauncherView.js
index c140589..df16a41 100644
--- a/Source/WebCore/inspector/front-end/AuditLauncherView.js
+++ b/Source/WebCore/inspector/front-end/AuditLauncherView.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2011 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
@@ -50,60 +50,38 @@ WebInspector.AuditLauncherView = function(runnerCallback)
this._headerElement.className = "no-audits";
this._headerElement.textContent = WebInspector.UIString("No audits to run");
this._contentElement.appendChild(this._headerElement);
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceFinished, this);
}
WebInspector.AuditLauncherView.prototype = {
- get totalResources()
+ _resetResourceCount: function()
{
- return this._totalResources;
+ this._loadedResources = 0;
+ this._totalResources = 0;
},
- set totalResources(x)
+ _onResourceStarted: function(event)
{
- if (this._totalResources === x)
+ var resource = event.data;
+ // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
+ if (resource.type === WebInspector.Resource.Type.WebSocket)
return;
- this._totalResources = x;
+ ++this._totalResources;
this._updateResourceProgress();
},
- get loadedResources()
- {
- return this._loadedResources;
- },
-
- set loadedResources(x)
+ _onResourceFinished: function(event)
{
- if (this._loadedResources === x)
+ var resource = event.data;
+ // See resorceStarted for details.
+ if (resource.type === WebInspector.Resource.Type.WebSocket)
return;
- this._loadedResources = x;
+ ++this._loadedResources;
this._updateResourceProgress();
},
- _resetResourceCount: function()
- {
- this.loadedResources = 0;
- this.totalResources = 0;
- },
-
- resourceStarted: function(resource)
- {
- // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
- if (resource.type !== WebInspector.Resource.Type.WebSocket)
- ++this.totalResources;
- },
-
- resourceFinished: function(resource)
- {
- // See resorceStarted for details.
- if (resource.type !== WebInspector.Resource.Type.WebSocket)
- ++this.loadedResources;
- },
-
- reset: function()
- {
- this._resetResourceCount();
- },
-
addCategory: function(category)
{
if (!this._sortedCategories.length)
@@ -264,7 +242,7 @@ WebInspector.AuditLauncherView.prototype = {
this._resourceProgressContainer.addStyleClass("hidden");
} else
this._resourceProgressContainer.removeStyleClass("hidden");
- this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this.loadedResources, this.totalResources);
+ this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources);
},
_updateButton: function()
diff --git a/Source/WebCore/inspector/front-end/AuditRules.js b/Source/WebCore/inspector/front-end/AuditRules.js
index 7aa891f..c2bbcbb 100644
--- a/Source/WebCore/inspector/front-end/AuditRules.js
+++ b/Source/WebCore/inspector/front-end/AuditRules.js
@@ -65,7 +65,7 @@ WebInspector.AuditRules.getDomainToResourcesMap = function(resources, types, nee
WebInspector.AuditRules.evaluateInTargetWindow = function(func, args, callback)
{
- InjectedScriptAccess.getDefault().evaluateOnSelf(func.toString(), args, callback);
+ InspectorBackend.evaluateOnSelf(func.toString(), args, callback);
}
@@ -721,7 +721,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
return nodeIds;
}
- WebInspector.AuditRules.evaluateInTargetWindow(pushImageNodes, null, receivedImages);
+ WebInspector.AuditRules.evaluateInTargetWindow(pushImageNodes, [], receivedImages);
}
}
@@ -797,7 +797,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
return found ? urlToViolationsArray : null;
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback);
+ WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback);
}
}
@@ -844,7 +844,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
return [ lateStyleUrls, cssBeforeInlineCount ];
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback.bind(this));
+ WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback.bind(this));
}
}
diff --git a/Source/WebCore/inspector/front-end/AuditsPanel.js b/Source/WebCore/inspector/front-end/AuditsPanel.js
index c639f47..f3cbfa7 100644
--- a/Source/WebCore/inspector/front-end/AuditsPanel.js
+++ b/Source/WebCore/inspector/front-end/AuditsPanel.js
@@ -96,16 +96,6 @@ WebInspector.AuditsPanel.prototype = {
return this._auditCategoriesById;
},
- resourceStarted: function(resource)
- {
- this._launcherView.resourceStarted(resource);
- },
-
- resourceFinished: function(resource)
- {
- this._launcherView.resourceFinished(resource);
- },
-
addCategory: function(category)
{
this.categoriesById[category.id] = category;
@@ -246,11 +236,6 @@ WebInspector.AuditsPanel.prototype = {
x.show(this.viewsContainerElement);
},
- reset: function()
- {
- this._launcherView.reset();
- },
-
attach: function()
{
WebInspector.Panel.prototype.attach.call(this);
diff --git a/Source/WebCore/inspector/front-end/Breakpoint.js b/Source/WebCore/inspector/front-end/Breakpoint.js
index e5e1768..aa600a7 100644
--- a/Source/WebCore/inspector/front-end/Breakpoint.js
+++ b/Source/WebCore/inspector/front-end/Breakpoint.js
@@ -37,7 +37,6 @@ WebInspector.Breakpoint = function(debuggerModel, breakpointId, sourceID, url, l
this.sourceID = sourceID;
this._enabled = enabled;
this._condition = condition || "";
- this._hit = false;
this._debuggerModel = debuggerModel;
}
@@ -60,52 +59,14 @@ WebInspector.Breakpoint.prototype = {
return this._condition;
},
- get hit()
+ get data()
{
- return this._hit;
- },
-
- set hit(hit)
- {
- this._hit = hit;
- this.dispatchEventToListeners("hit-state-changed");
- },
-
- click: function(event)
- {
- WebInspector.panels.scripts.showSourceLine(this.url, this.line);
- },
-
- compareTo: function(other)
- {
- if (this.url != other.url)
- return this.url < other.url ? -1 : 1;
- if (this.line != other.line)
- return this.line < other.line ? -1 : 1;
- return 0;
- },
-
- populateLabelElement: function(element)
- {
- function didGetSourceLine(text)
- {
- var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)");
- var labelElement = document.createTextNode(displayName + ":" + this.line);
- element.appendChild(labelElement);
-
- var sourceTextElement = document.createElement("div");
- sourceTextElement.textContent = text;
- sourceTextElement.className = "source-text monospace";
- element.appendChild(sourceTextElement);
- }
- var script = this._debuggerModel.scriptForSourceID(this.sourceID);
- script.sourceLine(this.line, didGetSourceLine.bind(this));
+ return { id: this.id, url: this.url, sourceID: this.sourceID, lineNumber: this.line, condition: this.condition };
},
remove: function()
{
this._debuggerModel.removeBreakpoint(this.id);
- this.dispatchEventToListeners("removed");
this.removeAllListeners();
delete this._debuggerModel;
}
diff --git a/Source/WebCore/inspector/front-end/BreakpointManager.js b/Source/WebCore/inspector/front-end/BreakpointManager.js
index 67ef112..d943d5b 100644
--- a/Source/WebCore/inspector/front-end/BreakpointManager.js
+++ b/Source/WebCore/inspector/front-end/BreakpointManager.js
@@ -34,7 +34,7 @@ WebInspector.BreakpointManager = function()
var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints");
for (var projectId in breakpoints)
this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]);
- InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints);
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
this._breakpoints = {};
this._domBreakpointsRestored = false;
@@ -303,7 +303,7 @@ WebInspector.BreakpointManager.prototype = {
WebInspector.settings.nativeBreakpoints = breakpoints;
this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints;
- InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints);
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
},
_validateBreakpoints: function(persistentBreakpoints)
diff --git a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 408c5ba..b237ca2 100644
--- a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -23,7 +23,213 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.BreakpointsSidebarPane = function(title)
+WebInspector.JavaScriptBreakpointsSidebarPane = function(title)
+{
+ WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
+
+ this.listElement = document.createElement("ol");
+ this.listElement.className = "breakpoint-list";
+
+ this.emptyElement = document.createElement("div");
+ this.emptyElement.className = "info";
+ this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
+
+ this.bodyElement.appendChild(this.emptyElement);
+
+ this._items = {};
+
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
+ WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
+}
+
+WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
+ _breakpointAdded: function(event)
+ {
+ var breakpoint = event.data;
+ var breakpointId = breakpoint.id;
+ var data = breakpoint.data;
+
+ var element = document.createElement("li");
+
+ var checkbox = document.createElement("input");
+ checkbox.className = "checkbox-elem";
+ checkbox.type = "checkbox";
+ checkbox.checked = breakpoint.enabled;
+ checkbox.addEventListener("click", this._breakpointItemCheckboxClicked.bind(this, breakpointId), false);
+ element.appendChild(checkbox);
+
+ var label = document.createElement("span");
+ element.appendChild(label);
+
+ element._data = data;
+ var currentElement = this.listElement.firstChild;
+ while (currentElement) {
+ if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0)
+ break;
+ currentElement = currentElement.nextSibling;
+ }
+ this._addListElement(element, currentElement);
+
+ element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointId), true);
+
+ this._setupBreakpointElement(data, element);
+
+ var breakpointItem = {};
+ breakpointItem.data = data;
+ breakpointItem.element = element;
+ breakpointItem.checkbox = checkbox;
+ this._items[breakpointId] = breakpointItem;
+
+ if (!this.expanded)
+ this.expanded = true;
+ },
+
+ _breakpointRemoved: function(event)
+ {
+ var breakpointId = event.data;
+ var breakpointItem = this._items[breakpointId];
+ if (breakpointItem) {
+ delete this._items[breakpointId];
+ this._removeListElement(breakpointItem.element);
+ }
+ },
+
+ _breakpointEnableChanged: function(enabled, event)
+ {
+ var breakpointId = event.data;
+ var breakpointItem = this._items[breakpointId];
+ if (breakpointItem)
+ breakpointItem.checkbox.checked = enabled;
+ },
+
+ _breakpointItemCheckboxClicked: function(breakpointId, event)
+ {
+ this._setBreakpointEnabled(breakpointId, event.target.checked);
+
+ // Breakpoint element may have it's own click handler.
+ event.stopPropagation();
+ },
+
+ _contextMenuEventFired: function(breakpointId, event)
+ {
+ var contextMenu = new WebInspector.ContextMenu();
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), this._removeBreakpoint.bind(this, breakpointId));
+ contextMenu.show(event);
+ },
+
+ _debuggerPaused: function(event)
+ {
+ var breakpointId = this._breakpointIdForDebuggerPausedEvent(event.data);
+ if (!breakpointId)
+ return;
+ var breakpointItem = this._items[breakpointId];
+ if (!breakpointItem)
+ return;
+ breakpointItem.element.addStyleClass("breakpoint-hit");
+ this._lastHitBreakpointItem = breakpointItem;
+ },
+
+ _debuggerResumed: function()
+ {
+ if (this._lastHitBreakpointItem) {
+ this._lastHitBreakpointItem.element.removeStyleClass("breakpoint-hit");
+ delete this._lastHitBreakpointItem;
+ }
+ },
+
+ _addListElement: function(element, beforeElement)
+ {
+ if (beforeElement)
+ this.listElement.insertBefore(element, beforeElement);
+ else {
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.emptyElement);
+ this.bodyElement.appendChild(this.listElement);
+ }
+ this.listElement.appendChild(element);
+ }
+ },
+
+ _removeListElement: function(element)
+ {
+ this.listElement.removeChild(element);
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
+ }
+ },
+
+ _projectChanged: function()
+ {
+ this.listElement.removeChildren();
+ if (this.listElement.parentElement) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
+ }
+ this._items = {};
+ },
+
+ _compare: function(x, y)
+ {
+ if (x !== y)
+ return x < y ? -1 : 1;
+ return 0;
+ },
+
+ _compareBreakpoints: function(b1, b2)
+ {
+ return this._compare(b1.url, b2.url) || this._compare(b1.lineNumber, b2.lineNumber);
+ },
+
+ _setupBreakpointElement: function(data, element)
+ {
+ var displayName = data.url ? WebInspector.displayNameForURL(data.url) : WebInspector.UIString("(program)");
+ var labelElement = document.createTextNode(displayName + ":" + data.lineNumber);
+ element.appendChild(labelElement);
+
+ var sourceTextElement = document.createElement("div");
+ sourceTextElement.className = "source-text monospace";
+ element.appendChild(sourceTextElement);
+
+ function didGetSourceLine(text)
+ {
+ sourceTextElement.textContent = text;
+ }
+ var script = WebInspector.debuggerModel.scriptForSourceID(data.sourceID);
+ script.sourceLine(data.lineNumber, didGetSourceLine.bind(this));
+
+ element.addStyleClass("cursor-pointer");
+ var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, data.lineNumber);
+ element.addEventListener("click", clickHandler, false);
+ },
+
+ _breakpointIdForDebuggerPausedEvent: function(details)
+ {
+ var callFrame = details.callFrames[0];
+ var breakpoint = WebInspector.debuggerModel.findBreakpoint(callFrame.sourceID, callFrame.line);
+ if (breakpoint)
+ return breakpoint.id;
+ },
+
+ _setBreakpointEnabled: function(breakpointId, enabled)
+ {
+ var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId);
+ WebInspector.debuggerModel.removeBreakpoint(breakpointId);
+ WebInspector.debuggerModel.setBreakpoint(breakpoint.sourceID, breakpoint.line, enabled, breakpoint.condition);
+ },
+
+ _removeBreakpoint: function(breakpointId)
+ {
+ WebInspector.debuggerModel.removeBreakpoint(breakpointId);
+ }
+}
+
+WebInspector.JavaScriptBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+
+WebInspector.NativeBreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);
@@ -39,7 +245,7 @@ WebInspector.BreakpointsSidebarPane = function(title)
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
}
-WebInspector.BreakpointsSidebarPane.prototype = {
+WebInspector.NativeBreakpointsSidebarPane.prototype = {
addBreakpointItem: function(breakpointItem)
{
var element = breakpointItem.element;
@@ -102,11 +308,11 @@ WebInspector.BreakpointsSidebarPane.prototype = {
}
}
-WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+WebInspector.NativeBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
WebInspector.XHRBreakpointsSidebarPane = function()
{
- WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
+ WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
function addButtonClicked(event)
{
@@ -123,7 +329,7 @@ WebInspector.XHRBreakpointsSidebarPane = function()
WebInspector.XHRBreakpointsSidebarPane.prototype = {
addBreakpointItem: function(breakpointItem)
{
- WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
+ WebInspector.NativeBreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
breakpointItem._labelElement.addEventListener("dblclick", this._startEditingBreakpoint.bind(this, breakpointItem), false);
},
@@ -166,7 +372,7 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
}
}
-WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.BreakpointsSidebarPane.prototype;
+WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;
WebInspector.BreakpointItem = function(breakpoint)
{
diff --git a/Source/WebCore/inspector/front-end/CSSCompletions.js b/Source/WebCore/inspector/front-end/CSSCompletions.js
index e8d7556..f60c297 100644
--- a/Source/WebCore/inspector/front-end/CSSCompletions.js
+++ b/Source/WebCore/inspector/front-end/CSSCompletions.js
@@ -44,7 +44,7 @@ WebInspector.CSSCompletions.prototype = {
return [];
var results = [];
- while (this._values[firstIndex].indexOf(prefix) === 0)
+ while (firstIndex < this._values.length && this._values[firstIndex].indexOf(prefix) === 0)
results.push(this._values[firstIndex++]);
return results;
},
diff --git a/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js
new file mode 100755
index 0000000..ac62aff
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2011 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.CSSKeywordCompletions = {
+ forProperty: function(propertyName)
+ {
+ var acceptedKeywords = ["initial"];
+ if (propertyName in this._propertyKeywordMap)
+ acceptedKeywords = acceptedKeywords.concat(this._propertyKeywordMap[propertyName]);
+ if (propertyName in this._colorAwareProperties)
+ acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors);
+ if (propertyName in WebInspector.StylesSidebarPane.InheritedProperties)
+ acceptedKeywords.push("inherit");
+ return new WebInspector.CSSCompletions(acceptedKeywords);
+ }
+};
+
+WebInspector.CSSKeywordCompletions._colors = [
+ "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
+ "silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
+ "aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
+ "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
+ "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
+ "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
+ "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
+ "floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
+ "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
+ "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
+ "limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
+ "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
+ "mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
+ "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
+ "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
+ "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
+ "wheat", "whitesmoke", "yellowgreen"
+],
+
+WebInspector.CSSKeywordCompletions._colorAwareProperties = [
+ "background", "background-color", "border", "border-color", "border-top", "border-right", "border-bottom",
+ "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "color",
+ "outline", "outline-color", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
+ "text-shadow", "text-underline", "text-underline-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
+].keySet();
+
+WebInspector.CSSKeywordCompletions._propertyKeywordMap = {
+ "table-layout": [
+ "auto", "fixed"
+ ],
+ "visibility": [
+ "hidden", "visible", "collapse"
+ ],
+ "background-repeat": [
+ "repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
+ ],
+ "text-underline": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "content": [
+ "list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
+ ],
+ "list-style-image": [
+ "none"
+ ],
+ "clear": [
+ "none", "left", "right", "both"
+ ],
+ "text-underline-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "overflow-x": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "stroke-linejoin": [
+ "round", "miter", "bevel"
+ ],
+ "baseline-shift": [
+ "baseline", "sub", "super"
+ ],
+ "border-bottom-width": [
+ "medium", "thick", "thin"
+ ],
+ "marquee-speed": [
+ "normal", "slow", "fast"
+ ],
+ "margin-top-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "max-height": [
+ "none"
+ ],
+ "box-orient": [
+ "horizontal", "vertical", "inline-axis", "block-axis"
+ ],
+ "font-stretch": [
+ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
+ "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
+ ],
+ "-webkit-color-correction": [
+ "default", "srgb"
+ ],
+ "text-underline-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "text-overline-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "-webkit-background-composite": [
+ "highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
+ "destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
+ ],
+ "border-left-width": [
+ "medium", "thick", "thin"
+ ],
+ "-webkit-writing-mode": [
+ "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
+ ],
+ "text-line-through-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "border-collapse": [
+ "collapse", "separate"
+ ],
+ "page-break-inside": [
+ "auto", "avoid"
+ ],
+ "border-top-width": [
+ "medium", "thick", "thin"
+ ],
+ "outline-color": [
+ "invert"
+ ],
+ "text-line-through-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "outline-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "cursor": [
+ "none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
+ "alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
+ "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
+ "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
+ "-webkit-grabbing"
+ ],
+ "border-width": [
+ "medium", "thick", "thin"
+ ],
+ "size": [
+ "a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
+ ],
+ "background-size": [
+ "contain", "cover"
+ ],
+ "direction": [
+ "ltr", "rtl"
+ ],
+ "marquee-direction": [
+ "left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
+ ],
+ "enable-background": [
+ "accumulate", "new"
+ ],
+ "float": [
+ "none", "left", "right"
+ ],
+ "overflow-y": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "margin-bottom-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "box-reflect": [
+ "left", "right", "above", "below"
+ ],
+ "overflow": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "text-rendering": [
+ "auto", "optimizespeed", "optimizelegibility", "geometricprecision"
+ ],
+ "text-align": [
+ "-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
+ ],
+ "list-style-position": [
+ "outside", "inside"
+ ],
+ "margin-bottom": [
+ "auto"
+ ],
+ "color-interpolation": [
+ "linearrgb"
+ ],
+ "background-origin": [
+ "border-box", "content-box", "padding-box"
+ ],
+ "word-wrap": [
+ "normal", "break-word"
+ ],
+ "font-weight": [
+ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
+ ],
+ "margin-before-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "text-overline-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "text-transform": [
+ "none", "capitalize", "uppercase", "lowercase"
+ ],
+ "border-right-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "border-left-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "-webkit-text-emphasis": [
+ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
+ ],
+ "font-style": [
+ "italic", "oblique", "normal"
+ ],
+ "speak": [
+ "none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
+ ],
+ "text-line-through": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
+ "skip-white-space"
+ ],
+ "color-rendering": [
+ "auto", "optimizespeed", "optimizequality"
+ ],
+ "list-style-type": [
+ "none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
+ "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
+ "mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
+ "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
+ "ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
+ "ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
+ "ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
+ "ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
+ "ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
+ "ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
+ "ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
+ "lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
+ "katakana-iroha"
+ ],
+ "-webkit-text-combine": [
+ "none", "horizontal"
+ ],
+ "outline": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "font": [
+ "caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
+ "-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
+ "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
+ "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
+ "fantasy", "monospace", "-webkit-body"
+ ],
+ "dominant-baseline": [
+ "middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
+ "mathematical", "use-script", "no-change", "reset-size"
+ ],
+ "display": [
+ "none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
+ "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
+ "table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
+ ],
+ "-webkit-text-emphasis-position": [
+ "over", "under"
+ ],
+ "image-rendering": [
+ "auto", "optimizespeed", "optimizequality"
+ ],
+ "alignment-baseline": [
+ "baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
+ "ideographic", "alphabetic", "hanging", "mathematical"
+ ],
+ "outline-width": [
+ "medium", "thick", "thin"
+ ],
+ "text-line-through-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "box-align": [
+ "baseline", "center", "stretch", "start", "end"
+ ],
+ "border-right-width": [
+ "medium", "thick", "thin"
+ ],
+ "border-top-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "line-height": [
+ "normal"
+ ],
+ "text-overflow": [
+ "clip", "ellipsis"
+ ],
+ "box-direction": [
+ "normal", "reverse"
+ ],
+ "margin-after-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "page-break-before": [
+ "left", "right", "auto", "always", "avoid"
+ ],
+ "-webkit-hyphens": [
+ "none", "auto", "manual"
+ ],
+ "border-image": [
+ "repeat", "stretch"
+ ],
+ "text-decoration": [
+ "blink", "line-through", "overline", "underline"
+ ],
+ "position": [
+ "absolute", "fixed", "relative", "static"
+ ],
+ "font-family": [
+ "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body"
+ ],
+ "text-overflow-mode": [
+ "clip", "ellipsis"
+ ],
+ "border-bottom-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "unicode-bidi": [
+ "normal", "bidi-override", "embed"
+ ],
+ "clip-rule": [
+ "nonzero", "evenodd"
+ ],
+ "margin-left": [
+ "auto"
+ ],
+ "margin-top": [
+ "auto"
+ ],
+ "zoom": [
+ "document", "reset"
+ ],
+ "text-overline-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "max-width": [
+ "none"
+ ],
+ "empty-cells": [
+ "hide", "show"
+ ],
+ "pointer-events": [
+ "none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
+ ],
+ "letter-spacing": [
+ "normal"
+ ],
+ "background-clip": [
+ "border-box", "content-box", "padding-box"
+ ],
+ "-webkit-font-smoothing": [
+ "none", "auto", "antialiased", "subpixel-antialiased"
+ ],
+ "border": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "font-size": [
+ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
+ "larger"
+ ],
+ "font-variant": [
+ "small-caps", "normal"
+ ],
+ "vertical-align": [
+ "baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
+ ],
+ "marquee-style": [
+ "none", "scroll", "slide", "alternate"
+ ],
+ "white-space": [
+ "normal", "nowrap", "pre", "pre-line", "pre-wrap"
+ ],
+ "text-underline-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "box-lines": [
+ "single", "multiple"
+ ],
+ "page-break-after": [
+ "left", "right", "auto", "always", "avoid"
+ ],
+ "clip-path": [
+ "none"
+ ],
+ "margin": [
+ "auto"
+ ],
+ "marquee-repetition": [
+ "infinite"
+ ],
+ "margin-right": [
+ "auto"
+ ],
+ "-webkit-text-emphasis-style": [
+ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
+ ]
+}
diff --git a/Source/WebCore/inspector/front-end/ConsoleView.js b/Source/WebCore/inspector/front-end/ConsoleView.js
index a40030e..bd08e60 100644
--- a/Source/WebCore/inspector/front-end/ConsoleView.js
+++ b/Source/WebCore/inspector/front-end/ConsoleView.js
@@ -149,6 +149,11 @@ WebInspector.ConsoleView.prototype = {
consoleMessagesCleared: function()
{
console.clearMessages();
+ },
+
+ monitoringXHRStateChanged: function(enabled)
+ {
+ console._monitoringXHREnabled = enabled;
}
}
InspectorBackend.registerDomainDispatcher("Console", dispatcher);
@@ -355,14 +360,11 @@ WebInspector.ConsoleView.prototype = {
// Collect comma separated object properties for the completion.
var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation);
- var callFrameId = WebInspector.panels.scripts.selectedCallFrameId();
var injectedScriptAccess;
- if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
- var selectedCallFrame = WebInspector.panels.scripts.sidebarPanes.callstack.selectedCallFrame;
- injectedScriptAccess = InjectedScriptAccess.get(selectedCallFrame.worldId);
- } else
- injectedScriptAccess = InjectedScriptAccess.getDefault();
- injectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions);
+ if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
+ InspectorBackend.getCompletionsOnCallFrame(WebInspector.panels.scripts.selectedCallFrameId(), expressionString, includeInspectorCommandLineAPI, reportCompletions);
+ else
+ InspectorBackend.getCompletions(expressionString, includeInspectorCommandLineAPI, reportCompletions);
},
_reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
@@ -416,14 +418,9 @@ WebInspector.ConsoleView.prototype = {
return;
}
+ var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !this._monitoringXHREnabled);
var contextMenu = new WebInspector.ContextMenu();
-
- function monitoringXHRWasChanged(newState)
- {
- WebInspector.monitoringXHREnabled = newState;
- }
- var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !WebInspector.monitoringXHREnabled, monitoringXHRWasChanged);
- contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.monitoringXHREnabled);
+ contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, this._monitoringXHREnabled);
contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this));
contextMenu.show(event);
},
@@ -532,8 +529,8 @@ WebInspector.ConsoleView.prototype = {
function evalCallback(result)
{
callback(WebInspector.RemoteObject.fromPayload(result));
- };
- InjectedScriptAccess.getDefault().evaluate(expression, objectGroup, evalCallback);
+ }
+ InspectorBackend.evaluate(expression, objectGroup, evalCallback);
},
_enterKeyPressed: function(event)
@@ -681,6 +678,15 @@ WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCou
this._parameters = parameters;
this._stackTrace = stackTrace;
this._requestId = requestId;
+
+ if (stackTrace && stackTrace.length) {
+ var topCallFrame = stackTrace[0];
+ if (!this.url)
+ this.url = topCallFrame.scriptName;
+ if (!this.line)
+ this.line = topCallFrame.lineNumber;
+ }
+
this._formatMessage();
}
@@ -737,17 +743,8 @@ WebInspector.ConsoleMessage.prototype = {
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";
- if (stackTrace && stackTrace.length) {
- var topCallFrame = stackTrace[0];
- var sourceName = topCallFrame.scriptName;
- var sourceLine = topCallFrame.lineNumber;
- } else {
- var sourceName = this.url;
- var sourceLine = this.line;
- }
-
- if (sourceName && sourceName !== "undefined") {
- var urlElement = WebInspector.linkifyResourceAsNode(sourceName, "scripts", sourceLine, "console-message-url");
+ if (this.url && this.url !== "undefined") {
+ var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url");
this._formattedMessage.appendChild(urlElement);
}
diff --git a/Source/WebCore/inspector/front-end/DebuggerModel.js b/Source/WebCore/inspector/front-end/DebuggerModel.js
index 8f5bcf7..717486c 100644
--- a/Source/WebCore/inspector/front-end/DebuggerModel.js
+++ b/Source/WebCore/inspector/front-end/DebuggerModel.js
@@ -31,6 +31,7 @@
WebInspector.DebuggerModel = function()
{
this._paused = false;
+ this._callFrames = [];
this._breakpoints = {};
this._sourceIDAndLineToBreakpointId = {};
this._scripts = {};
@@ -43,6 +44,7 @@ WebInspector.DebuggerModel.Events = {
DebuggerResumed: "debugger-resumed",
ParsedScriptSource: "parsed-script-source",
FailedToParseScriptSource: "failed-to-parse-script-source",
+ ScriptSourceChanged: "script-source-changed",
BreakpointAdded: "breakpoint-added",
BreakpointRemoved: "breakpoint-removed"
}
@@ -84,6 +86,7 @@ WebInspector.DebuggerModel.prototype = {
delete this._breakpoints[breakpointId];
delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)];
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId);
+ breakpoint.dispatchEventToListeners("removed");
},
_breakpointSetOnBackend: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, restored)
@@ -103,6 +106,11 @@ WebInspector.DebuggerModel.prototype = {
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint);
},
+ breakpointForId: function(breakpointId)
+ {
+ return this._breakpoints[breakpointId];
+ },
+
queryBreakpoints: function(filter)
{
var breakpoints = [];
@@ -129,6 +137,7 @@ WebInspector.DebuggerModel.prototype = {
reset: function()
{
this._paused = false;
+ this._callFrames = [];
this._breakpoints = {};
delete this._oneTimeBreakpoint;
this._sourceIDAndLineToBreakpointId = {};
@@ -156,39 +165,81 @@ WebInspector.DebuggerModel.prototype = {
return scripts;
},
+ editScriptSource: function(sourceID, scriptSource)
+ {
+ function didEditScriptSource(success, newBodyOrErrorMessage, callFrames)
+ {
+ if (success) {
+ if (callFrames && callFrames.length)
+ this._callFrames = callFrames;
+ this._updateScriptSource(sourceID, newBodyOrErrorMessage);
+ } else
+ WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
+ }
+ InspectorBackend.editScriptSource(sourceID, scriptSource, didEditScriptSource.bind(this));
+ },
+
+ _updateScriptSource: function(sourceID, scriptSource)
+ {
+ var script = this._scripts[sourceID];
+ var oldSource = script.source;
+ script.source = scriptSource;
+
+ // Clear and re-create breakpoints according to text diff.
+ var diff = Array.diff(oldSource.split("\n"), script.source.split("\n"));
+ for (var id in this._breakpoints) {
+ var breakpoint = this._breakpoints[id];
+ if (breakpoint.sourceID !== sourceID)
+ continue;
+ breakpoint.remove();
+ var lineNumber = breakpoint.line - 1;
+ var newLineNumber = diff.left[lineNumber].row;
+ if (newLineNumber === undefined) {
+ for (var i = lineNumber - 1; i >= 0; --i) {
+ if (diff.left[i].row === undefined)
+ continue;
+ var shiftedLineNumber = diff.left[i].row + lineNumber - i;
+ if (shiftedLineNumber < diff.right.length) {
+ var originalLineNumber = diff.right[shiftedLineNumber].row;
+ if (originalLineNumber === lineNumber || originalLineNumber === undefined)
+ newLineNumber = shiftedLineNumber;
+ }
+ break;
+ }
+ }
+ if (newLineNumber !== undefined)
+ this.setBreakpoint(sourceID, newLineNumber + 1, breakpoint.enabled, breakpoint.condition);
+ }
+
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ScriptSourceChanged, { sourceID: sourceID, oldSource: oldSource });
+ },
+
+ get callFrames()
+ {
+ return this._callFrames;
+ },
+
_pausedScript: function(details)
{
this._paused = true;
+ this._callFrames = details.callFrames;
if ("_continueToLineBreakpointId" in this) {
InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId);
delete this._continueToLineBreakpointId;
}
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details);
-
- if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause || details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint)
- return;
-
- var breakpoint = this.findBreakpoint(details.callFrames[0].sourceID, details.callFrames[0].line);
- if (!breakpoint)
- return;
- breakpoint.hit = true;
- this._lastHitBreakpoint = breakpoint;
},
_resumedScript: function()
{
this._paused = false;
+ this._callFrames = [];
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
-
- if (!this._lastHitBreakpoint)
- return;
- this._lastHitBreakpoint.hit = false;
- delete this._lastHitBreakpoint;
},
- _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType)
+ _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
{
- var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, undefined, undefined, scriptWorldType);
+ var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, length, undefined, undefined, scriptWorldType);
this._scripts[sourceID] = script;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, sourceID);
},
@@ -234,9 +285,9 @@ WebInspector.DebuggerDispatcher.prototype = {
WebInspector.panels.scripts.debuggerWasDisabled();
},
- parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType)
+ parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
{
- this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType);
+ this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType);
},
failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage)
diff --git a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
index 67d34b2..722c028 100644
--- a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -411,8 +411,7 @@ WebInspector.ElementsTreeElement.prototype = {
else
this.tooltip = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight);
}
-
- InjectedScriptAccess.getForNode(node).getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
+ InspectorBackend.getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
},
updateSelection: function()
diff --git a/Source/WebCore/inspector/front-end/ExtensionAPI.js b/Source/WebCore/inspector/front-end/ExtensionAPI.js
index a9a2423..b10452d 100644
--- a/Source/WebCore/inspector/front-end/ExtensionAPI.js
+++ b/Source/WebCore/inspector/front-end/ExtensionAPI.js
@@ -450,8 +450,9 @@ ExtensionServerClient.prototype = {
_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
- this._callbacks[request.requestId](request.result);
+ var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
+ callback(request.result);
}
},
diff --git a/Source/WebCore/inspector/front-end/ExtensionPanel.js b/Source/WebCore/inspector/front-end/ExtensionPanel.js
index 4b42e68..fb98350 100644
--- a/Source/WebCore/inspector/front-end/ExtensionPanel.js
+++ b/Source/WebCore/inspector/front-end/ExtensionPanel.js
@@ -95,7 +95,7 @@ WebInspector.ExtensionWatchSidebarPane.prototype = {
setExpression: function(expression, title)
{
- InjectedScriptAccess.getDefault().evaluate(expression, this._onEvaluate.bind(this, title));
+ InspectorBackend.evaluate(expression, "extension-watch", this._onEvaluate.bind(this, title));
},
_onEvaluate: function(title, result)
diff --git a/Source/WebCore/inspector/front-end/ExtensionServer.js b/Source/WebCore/inspector/front-end/ExtensionServer.js
index 1320efb..0924106 100644
--- a/Source/WebCore/inspector/front-end/ExtensionServer.js
+++ b/Source/WebCore/inspector/front-end/ExtensionServer.js
@@ -53,7 +53,6 @@ WebInspector.ExtensionServer = function()
this._registerHandler("subscribe", this._onSubscribe.bind(this));
this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
-
window.addEventListener("message", this._onWindowMessage.bind(this), false);
}
@@ -68,11 +67,6 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("panel-objectSelected-" + panelId, objectId);
},
- notifyResourceFinished: function(resource)
- {
- this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
- },
-
notifySearchAction: function(panelId, action, searchString)
{
this._postNotification("panel-search-" + panelId, action, searchString);
@@ -114,6 +108,12 @@ WebInspector.ExtensionServer.prototype = {
delete this._clientObjects[auditRun.id];
},
+ _notifyResourceFinished: function(event)
+ {
+ var resource = event.data;
+ this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
+ },
+
_postNotification: function(type, details)
{
var subscribers = this._subscribers[type];
@@ -272,7 +272,7 @@ WebInspector.ExtensionServer.prototype = {
var evalExpression = "JSON.stringify(eval('" +
"with (window.console._commandLineAPI) with (window) {' + unescape('" + escape(message.expression) +
"') + '}'));";
- InjectedScriptAccess.getDefault().evaluate(evalExpression, callback.bind(this));
+ InspectorBackend.evaluate(evalExpression, "none", callback.bind(this));
},
_onRevealAndSelect: function(message)
@@ -356,6 +356,9 @@ WebInspector.ExtensionServer.prototype = {
initExtensions: function()
{
+ // The networkManager is normally created after the ExtensionServer is constructed, but before initExtensions() is called.
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._notifyResourceFinished, this);
+
InspectorExtensionRegistry.getExtensionsAsync();
},
@@ -393,7 +396,6 @@ WebInspector.ExtensionServer.prototype = {
"var apiPrivate = {};" +
"(" + WebInspector.commonExtensionSymbols.toString() + ")(apiPrivate);" +
"(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
- "webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
platformAPI +
"})";
},
diff --git a/Source/WebCore/inspector/front-end/InjectedScriptAccess.js b/Source/WebCore/inspector/front-end/InjectedScriptAccess.js
deleted file mode 100644
index cb3c2b8..0000000
--- a/Source/WebCore/inspector/front-end/InjectedScriptAccess.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2009 Google 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:
- *
- * * 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.
- */
-
-function InjectedScriptAccess(worldId) {
- this._worldId = worldId;
-}
-
-InjectedScriptAccess.get = function(worldId)
-{
- if (typeof worldId === "number")
- return new InjectedScriptAccess(worldId);
-
- console.assert(false, "Access to injected script with no id");
-}
-
-InjectedScriptAccess.getForNode = function(node)
-{
- // FIXME: do something.
- return InjectedScriptAccess.get(-node.id);
-}
-
-InjectedScriptAccess.getForObjectId = function(objectId)
-{
- // FIXME: move to native layer.
- var tokens = objectId.split(":");
- return InjectedScriptAccess.get(parseInt(tokens[0]));
-}
-
-InjectedScriptAccess.getDefault = function()
-{
- return InjectedScriptAccess.get(0);
-}
-
-InjectedScriptAccess.prototype = {};
-
-InjectedScriptAccess._installHandler = function(methodName, async)
-{
- InjectedScriptAccess.prototype[methodName] = function()
- {
- var allArgs = Array.prototype.slice.call(arguments);
- var callback = allArgs[allArgs.length - 1];
- var argsString = JSON.stringify(Array.prototype.slice.call(allArgs, 0, allArgs.length - 1));
-
- function myCallback(result, isException)
- {
- if (!isException)
- callback(result);
- else
- WebInspector.console.addMessage(WebInspector.ConsoleMessage.createTextMessage("Error dispatching: " + methodName));
- }
- InspectorBackend.dispatchOnInjectedScript(this._worldId, methodName, argsString, myCallback);
- };
-}
-
-// InjectedScriptAccess message forwarding puts some constraints on the way methods are implemented and called:
-// - Make sure corresponding methods in InjectedScript return non-null and non-undefined values,
-// - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function.
-// We keep these sorted.
-InjectedScriptAccess._installHandler("evaluate");
-InjectedScriptAccess._installHandler("evaluateInCallFrame");
-InjectedScriptAccess._installHandler("evaluateOnSelf");
-InjectedScriptAccess._installHandler("getCompletions");
-InjectedScriptAccess._installHandler("getProperties");
-InjectedScriptAccess._installHandler("getPrototypes");
-InjectedScriptAccess._installHandler("pushNodeToFrontend");
-InjectedScriptAccess._installHandler("resolveNode");
-InjectedScriptAccess._installHandler("getNodeProperties");
-InjectedScriptAccess._installHandler("setPropertyValue");
diff --git a/Source/WebCore/inspector/front-end/NetworkManager.js b/Source/WebCore/inspector/front-end/NetworkManager.js
index a657377..ed4309e 100644
--- a/Source/WebCore/inspector/front-end/NetworkManager.js
+++ b/Source/WebCore/inspector/front-end/NetworkManager.js
@@ -30,6 +30,8 @@
WebInspector.NetworkManager = function(resourceTreeModel)
{
+ WebInspector.Object.call(this);
+
this._inflightResources = {};
this._resourceTreeModel = resourceTreeModel;
this._lastIdentifierForCachedResource = 0;
@@ -86,6 +88,13 @@ WebInspector.NetworkManager.updateResourceWithCachedResource = function(resource
WebInspector.NetworkManager.updateResourceWithResponse(resource, cachedResource.response);
}
+WebInspector.NetworkManager.EventTypes = {
+ ResourceStarted: "ResourceStarted",
+ ResourceUpdated: "ResourceUpdated",
+ ResourceFinished: "ResourceFinished",
+ MainResourceCommitLoad: "MainResourceCommitLoad"
+}
+
WebInspector.NetworkManager.prototype = {
reset: function()
{
@@ -119,7 +128,7 @@ WebInspector.NetworkManager.prototype = {
if (isRedirect)
this._startResource(resource);
else
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
markResourceAsCached: function(identifier)
@@ -129,7 +138,7 @@ WebInspector.NetworkManager.prototype = {
return;
resource.cached = true;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didReceiveResponse: function(identifier, time, resourceType, response)
@@ -143,7 +152,7 @@ WebInspector.NetworkManager.prototype = {
WebInspector.NetworkManager.updateResourceWithResponse(resource, response);
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource);
},
@@ -156,7 +165,7 @@ WebInspector.NetworkManager.prototype = {
resource.resourceSize += lengthReceived;
resource.endTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didFinishLoading: function(identifier, finishTime)
@@ -204,8 +213,7 @@ WebInspector.NetworkManager.prototype = {
resource.type = WebInspector.Resource.Type[type];
resource.setInitialContent(sourceString);
- WebInspector.panels.resources.refreshResource(resource);
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didCommitLoadForFrame: function(frame, loader)
@@ -216,7 +224,7 @@ WebInspector.NetworkManager.prototype = {
if (mainResource) {
WebInspector.mainResource = mainResource;
mainResource.isMainResource = true;
- WebInspector.panels.network.mainResourceChanged();
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, mainResource);
}
}
},
@@ -239,7 +247,7 @@ WebInspector.NetworkManager.prototype = {
resource.webSocketRequestKey3 = request.webSocketRequestKey3;
resource.startTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didReceiveWebSocketHandshakeResponse: function(identifier, time, response)
@@ -254,7 +262,7 @@ WebInspector.NetworkManager.prototype = {
resource.webSocketChallengeResponse = response.webSocketChallengeResponse;
resource.responseReceivedTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didCloseWebSocket: function(identifier, time)
@@ -283,20 +291,24 @@ WebInspector.NetworkManager.prototype = {
return newResource;
},
- _startResource: function(resource, skipRefresh)
+ _startResource: function(resource)
{
this._inflightResources[resource.identifier] = resource;
- WebInspector.panels.network.appendResource(resource, skipRefresh);
- WebInspector.panels.audits.resourceStarted(resource);
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceStarted, resource);
+ },
+
+ _updateResource: function(resource)
+ {
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceUpdated, resource);
},
_finishResource: function(resource, finishTime)
{
resource.endTime = finishTime;
resource.finished = true;
- WebInspector.panels.network.refreshResource(resource);
- WebInspector.panels.audits.resourceFinished(resource);
- WebInspector.extensionServer.notifyResourceFinished(resource);
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceFinished, resource);
delete this._inflightResources[resource.identifier];
}
}
+
+WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/Source/WebCore/inspector/front-end/NetworkPanel.js b/Source/WebCore/inspector/front-end/NetworkPanel.js
index 28cbd36..943ee7f 100644
--- a/Source/WebCore/inspector/front-end/NetworkPanel.js
+++ b/Source/WebCore/inspector/front-end/NetworkPanel.js
@@ -78,6 +78,11 @@ WebInspector.NetworkPanel = function()
this._filter(this._filterAllElement, false);
this._toggleGridMode();
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, this._onMainResourceCommitLoad, this);
}
WebInspector.NetworkPanel.prototype = {
@@ -772,7 +777,12 @@ WebInspector.NetworkPanel.prototype = {
return this._resourcesById[id];
},
- appendResource: function(resource)
+ _onResourceStarted: function(event)
+ {
+ this._appendResource(event.data);
+ },
+
+ _appendResource: function(resource)
{
this._resources.push(resource);
this._resourcesById[resource.identifier] = resource;
@@ -781,13 +791,18 @@ WebInspector.NetworkPanel.prototype = {
// Pull all the redirects of the main resource upon commit load.
if (resource.redirects) {
for (var i = 0; i < resource.redirects.length; ++i)
- this.refreshResource(resource.redirects[i]);
+ this._refreshResource(resource.redirects[i]);
}
- this.refreshResource(resource);
+ this._refreshResource(resource);
+ },
+
+ _onResourceUpdated: function(event)
+ {
+ this._refreshResource(event.data);
},
- refreshResource: function(resource)
+ _refreshResource: function(resource)
{
this._staleResources.push(resource);
this._scheduleRefresh();
@@ -811,7 +826,7 @@ WebInspector.NetworkPanel.prototype = {
this._reset();
},
- mainResourceChanged: function()
+ _onMainResourceCommitLoad: function()
{
if (this._preserveLogToggle.toggled)
return;
@@ -819,7 +834,7 @@ WebInspector.NetworkPanel.prototype = {
this._reset();
// Now resurrect the main resource along with all redirects that lead to it.
var resourcesToAppend = (WebInspector.mainResource.redirects || []).concat(WebInspector.mainResource);
- resourcesToAppend.forEach(this.appendResource, this);
+ resourcesToAppend.forEach(this._appendResource, this);
},
canShowSourceLine: function(url, line)
diff --git a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
index b9c212a..a1e37bc 100644
--- a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
@@ -42,11 +42,11 @@ WebInspector.PropertiesSidebarPane.prototype = {
return;
}
- var self = this;
- var callback = function(prototypes) {
- var body = self.bodyElement;
+ function callback(prototypes)
+ {
+ var body = this.bodyElement;
body.removeChildren();
- self.sections = [];
+ this.sections = [];
// Get array of prototype user-friendly names.
for (var i = 0; i < prototypes.length; ++i) {
@@ -55,11 +55,11 @@ WebInspector.PropertiesSidebarPane.prototype = {
if (title.match(/Prototype$/))
title = title.replace(/Prototype$/, "");
var section = new WebInspector.ObjectPropertiesSection(prototype, title);
- self.sections.push(section);
+ this.sections.push(section);
body.appendChild(section.element);
}
- };
- InjectedScriptAccess.getForNode(node).getPrototypes(node.id, callback);
+ }
+ InspectorBackend.getNodePrototypes(node.id, callback.bind(this));
}
}
diff --git a/Source/WebCore/inspector/front-end/RemoteObject.js b/Source/WebCore/inspector/front-end/RemoteObject.js
index 4d6736c..10af2e3 100644
--- a/Source/WebCore/inspector/front-end/RemoteObject.js
+++ b/Source/WebCore/inspector/front-end/RemoteObject.js
@@ -52,7 +52,7 @@ WebInspector.RemoteObject.resolveNode = function(node, callback)
{
callback(object ? WebInspector.RemoteObject.fromPayload(object) : null);
}
- InjectedScriptAccess.getForNode(node).resolveNode(node.id, mycallback);
+ InspectorBackend.resolveNode(node.id, mycallback);
}
WebInspector.RemoteObject.fromPayload = function(payload)
@@ -118,7 +118,7 @@ WebInspector.RemoteObject.prototype = {
properties[i].value = WebInspector.RemoteObject.fromPayload(properties[i].value);
callback(properties);
}
- InjectedScriptAccess.getForObjectId(this._objectId).getProperties(this._objectId, ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
+ InspectorBackend.getProperties(this._objectId, !!ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
},
setPropertyValue: function(name, value, callback)
@@ -127,12 +127,12 @@ WebInspector.RemoteObject.prototype = {
callback(false);
return;
}
- InjectedScriptAccess.getForObjectId(this._objectId).setPropertyValue(this._objectId, name, value, callback);
+ InspectorBackend.setPropertyValue(this._objectId, name, value, callback);
},
pushNodeToFrontend: function(callback)
{
- InjectedScriptAccess.getForObjectId(this._objectId).pushNodeToFrontend(this._objectId, callback);
+ InspectorBackend.pushNodeToFrontend(this._objectId, callback);
}
}
diff --git a/Source/WebCore/inspector/front-end/Resource.js b/Source/WebCore/inspector/front-end/Resource.js
index 7340645..00c1fb9 100644
--- a/Source/WebCore/inspector/front-end/Resource.js
+++ b/Source/WebCore/inspector/front-end/Resource.js
@@ -44,7 +44,6 @@ WebInspector.Resource.Type = {
Font: 3,
Script: 4,
XHR: 5,
- Media: 6,
WebSocket: 7,
Other: 8,
@@ -68,8 +67,6 @@ WebInspector.Resource.Type = {
return WebInspector.UIString("Script");
case this.XHR:
return WebInspector.UIString("XHR");
- case this.Media:
- return WebInspector.UIString("Media");
case this.WebSocket:
return WebInspector.UIString("WebSocket");
case this.Other:
@@ -95,8 +92,6 @@ WebInspector.Resource.Type = {
return "script";
case this.XHR:
return "xhr";
- case this.Media:
- return "media";
case this.WebSocket:
return "websocket";
case this.Other:
@@ -669,6 +664,13 @@ WebInspector.Resource.prototype = {
requestContent: function(callback)
{
+ // We do not support content retrieval for WebSockets at the moment.
+ // Since WebSockets are potentially long-living, fail requests immediately
+ // to prevent caller blocking until resource is marked as finished.
+ if (this.type === WebInspector.Resource.Type.WebSocket) {
+ callback(null, null);
+ return;
+ }
if (this._content) {
callback(this._content, this._contentEncoded);
return;
diff --git a/Source/WebCore/inspector/front-end/ResourcesPanel.js b/Source/WebCore/inspector/front-end/ResourcesPanel.js
index d96989b..7e1fcc0 100644
--- a/Source/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/Source/WebCore/inspector/front-end/ResourcesPanel.js
@@ -78,6 +78,8 @@ WebInspector.ResourcesPanel = function(database)
this.sidebarElement.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.sidebarElement.addEventListener("mouseout", this._onmouseout.bind(this), false);
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._refreshResource, this);
}
WebInspector.ResourcesPanel.prototype = {
@@ -253,8 +255,9 @@ WebInspector.ResourcesPanel.prototype = {
frameTreeElement.removeChildren();
},
- refreshResource: function(resource)
+ _refreshResource: function(event)
{
+ var resource = event.data;
// FIXME: do not add XHR in the first place based on the native instrumentation.
if (resource.type === WebInspector.Resource.Type.XHR) {
var resourceTreeElement = this._findTreeElementForResource(resource);
diff --git a/Source/WebCore/inspector/front-end/Script.js b/Source/WebCore/inspector/front-end/Script.js
index 89b2121..6e3b18d 100644
--- a/Source/WebCore/inspector/front-end/Script.js
+++ b/Source/WebCore/inspector/front-end/Script.js
@@ -23,13 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Script = function(sourceID, sourceURL, source, lineOffset, columnOffset, errorLine, errorMessage, worldType)
+WebInspector.Script = function(sourceID, sourceURL, source, lineOffset, columnOffset, length, errorLine, errorMessage, worldType)
{
this.sourceID = sourceID;
this.sourceURL = sourceURL;
this._source = source;
this.lineOffset = lineOffset;
this.columnOffset = columnOffset;
+ this.length = length;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
this.worldType = worldType;
@@ -96,12 +97,15 @@ WebInspector.Script.prototype = {
get source()
{
+ if (!this._source && this.resource)
+ this._source = this.resource.content;
return this._source;
},
set source(source)
{
this._source = source;
+ delete this._lineEndings;
},
requestSource: function(callback)
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatter.js b/Source/WebCore/inspector/front-end/ScriptFormatter.js
new file mode 100644
index 0000000..69ffb74
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/ScriptFormatter.js
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 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.ScriptFormatter = function(source)
+{
+ this._originalSource = source;
+ this._originalLineEndings = source.findAll("\n");
+ this._originalLineEndings.push(source.length);
+}
+
+WebInspector.ScriptFormatter.locationToPosition = function(lineEndings, location)
+{
+ var position = location.line ? lineEndings[location.line - 1] + 1 : 0;
+ return position + location.column;
+}
+
+WebInspector.ScriptFormatter.positionToLocation = function(lineEndings, position)
+{
+ var location = {};
+ location.line = lineEndings.upperBound(position - 1);
+ if (!location.line)
+ location.column = position;
+ else
+ location.column = position - lineEndings[location.line - 1] - 1;
+ return location;
+}
+
+WebInspector.ScriptFormatter.prototype = {
+ format: function(callback)
+ {
+ var worker = new Worker("scriptFormatterWorker.js");
+ function messageHandler(event)
+ {
+ var formattedSource = event.data;
+ this._formatted = true;
+ this._formattedSource = formattedSource;
+ this._formattedLineEndings = formattedSource.findAll("\n");
+ this._formattedLineEndings.push(formattedSource.length);
+ this._buildMapping();
+ callback(formattedSource);
+ }
+ worker.onmessage = messageHandler.bind(this);
+ worker.postMessage(this._originalSource);
+ },
+
+ _buildMapping: function()
+ {
+ this._originalSymbolPositions = [];
+ this._formattedSymbolPositions = [];
+ var lastCodePosition = 0;
+ var regexp = /[\$\.\w]+|{|}|;/g;
+ while (true) {
+ var match = regexp.exec(this._formattedSource);
+ if (!match)
+ break;
+ var position = this._originalSource.indexOf(match[0], lastCodePosition);
+ if (position === -1)
+ continue;
+ this._originalSymbolPositions.push(position);
+ this._formattedSymbolPositions.push(match.index);
+ lastCodePosition = position + match[0].length;
+ }
+ this._originalSymbolPositions.push(this._originalSource.length);
+ this._formattedSymbolPositions.push(this._formattedSource.length);
+ },
+
+ originalLineNumberToFormattedLineNumber: function(originalLineNumber)
+ {
+ if (!this._formatted)
+ return originalLineNumber;
+ var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, { line: originalLineNumber, column: 0 });
+ return this.originalPositionToFormattedLineNumber(originalPosition);
+ },
+
+ formattedLineNumberToOriginalLineNumber: function(formattedLineNumber)
+ {
+ if (!this._formatted)
+ return formattedLineNumber;
+ var originalPosition = this.formattedLineNumberToOriginalPosition(formattedLineNumber);
+ return WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, originalPosition).line;
+ },
+
+ originalPositionToFormattedLineNumber: function(originalPosition)
+ {
+ var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings;
+ if (this._formatted)
+ formattedPosition = this._convertPosition(this._originalSymbolPositions, this._formattedSymbolPositions, originalPosition);
+ return WebInspector.ScriptFormatter.positionToLocation(lineEndings, formattedPosition).line;
+ },
+
+ formattedLineNumberToOriginalPosition: function(formattedLineNumber)
+ {
+ var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings;
+ var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(lineEndings, { line: formattedLineNumber, column: 0 });
+ if (!this._formatted)
+ return formattedPosition;
+ return this._convertPosition(this._formattedSymbolPositions, this._originalSymbolPositions, formattedPosition);
+ },
+
+ _convertPosition: function(symbolPositions1, symbolPositions2, position)
+ {
+ var index = symbolPositions1.upperBound(position);
+ if (index === symbolPositions2.length - 1)
+ return symbolPositions2[index] - 1;
+ return symbolPositions2[index];
+ }
+}
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
new file mode 100644
index 0000000..e900317
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+var parse = loadModule("parse-js.js");
+var process = loadModule("process.js");
+
+onmessage = function(event) {
+ postMessage(beautify(event.data));
+};
+
+function beautify(source)
+{
+ var ast = parse.parse(source);
+ var beautifyOptions = {
+ indent_level: 4,
+ indent_start: 0,
+ quote_keys: false,
+ space_colon: false
+ };
+ return process.gen_code(ast, beautifyOptions);
+}
+
+function loadModule(src)
+{
+ var request = new XMLHttpRequest();
+ request.open("GET", src, false);
+ request.send();
+
+ var exports = {};
+ eval(request.responseText);
+ return exports;
+}
+
+function require()
+{
+ return parse;
+}
diff --git a/Source/WebCore/inspector/front-end/ScriptView.js b/Source/WebCore/inspector/front-end/ScriptView.js
index d6c1c59..f631fcc 100644
--- a/Source/WebCore/inspector/front-end/ScriptView.js
+++ b/Source/WebCore/inspector/front-end/ScriptView.js
@@ -30,7 +30,7 @@ WebInspector.ScriptView = function(script)
this.element.addStyleClass("script-view");
var contentProvider = new WebInspector.SourceFrameContentProviderForScript(script);
- this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", WebInspector.panels.scripts.canEditScripts());
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", true);
}
WebInspector.ScriptView.prototype = {
diff --git a/Source/WebCore/inspector/front-end/ScriptsPanel.js b/Source/WebCore/inspector/front-end/ScriptsPanel.js
index 32212d4..a74f80d 100644
--- a/Source/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/Source/WebCore/inspector/front-end/ScriptsPanel.js
@@ -63,6 +63,15 @@ WebInspector.ScriptsPanel = function()
// FIXME: append the functions select element to the top status bar when it is implemented.
// this.topStatusBar.appendChild(this.functionsSelectElement);
+ this.formatButton = document.createElement("button");
+ this.formatButton.className = "status-bar-item";
+ this.formatButton.id = "format-script";
+ this.formatButton.title = WebInspector.UIString("Format script.");
+ this.formatButton.appendChild(document.createElement("img"));
+ this.formatButton.addEventListener("click", this._formatScript.bind(this), false);
+ if (Preferences.debugMode)
+ this.topStatusBar.appendChild(this.formatButton);
+
this.sidebarButtonsElement = document.createElement("div");
this.sidebarButtonsElement.id = "scripts-sidebar-buttons";
this.topStatusBar.appendChild(this.sidebarButtonsElement);
@@ -131,7 +140,7 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
- this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane();
+ this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane();
if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.xhrBreakpoints = WebInspector.createXHRBreakpointsSidebarPane();
@@ -168,8 +177,6 @@ WebInspector.ScriptsPanel = function()
this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions.bind(this), false);
- this._pauseOnExceptionButton.state = WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions;
- this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
this._registerShortcuts();
@@ -179,6 +186,7 @@ WebInspector.ScriptsPanel = function()
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ScriptSourceChanged, this._scriptSourceChanged, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
}
@@ -244,6 +252,27 @@ WebInspector.ScriptsPanel.prototype = {
this._addScript(event.data);
},
+ _scriptSourceChanged: function(event)
+ {
+ var sourceID = event.data.sourceID;
+ var oldSource = event.data.oldSource;
+
+ var script = WebInspector.debuggerModel.scriptForSourceID(sourceID);
+ var oldView = script._scriptView;
+ if (oldView) {
+ script._scriptView = new WebInspector.ScriptView(script);
+ this.viewRecreated(oldView, script._scriptView);
+ }
+ if (script.resource) {
+ var revertHandle = WebInspector.debuggerModel.editScriptSource.bind(WebInspector.debuggerModel, sourceID, oldSource);
+ script.resource.setContent(script.source, revertHandle);
+ }
+
+ var callFrames = WebInspector.debuggerModel.callFrames;
+ if (callFrames.length)
+ this._debuggerPaused({ data: { callFrames: callFrames } });
+ },
+
_addScript: function(script)
{
var resource = WebInspector.resourceForURL(script.sourceURL);
@@ -279,52 +308,6 @@ WebInspector.ScriptsPanel.prototype = {
delete resource._scriptsPendingResourceLoad;
},
- canEditScripts: function()
- {
- return Preferences.canEditScriptSource;
- },
-
- editScriptSource: function(editData, revertEditingCallback, cancelEditingCallback)
- {
- if (!this.canEditScripts())
- return;
-
- // Need to clear breakpoints and re-create them later when editing source.
- var breakpoints = WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID === editData.sourceID });
- for (var i = 0; i < breakpoints.length; ++i)
- breakpoints[i].remove();
-
- function mycallback(success, newBodyOrErrorMessage, callFrames)
- {
- if (success) {
- var script = WebInspector.debuggerModel.scriptForSourceID(editData.sourceID);
- script.source = newBodyOrErrorMessage;
- var oldView = script._scriptView
- if (oldView) {
- script._scriptView = new WebInspector.ScriptView(script);
- this.viewRecreated(oldView, script._scriptView);
- }
- if (script.resource)
- script.resource.setContent(newBodyOrErrorMessage, revertEditingCallback);
-
- if (callFrames && callFrames.length)
- this._debuggerPaused({ data: { callFrames: callFrames } });
- } else {
- if (cancelEditingCallback)
- cancelEditingCallback();
- WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
- }
- for (var i = 0; i < breakpoints.length; ++i) {
- var breakpoint = breakpoints[i];
- var newLine = breakpoint.line;
- if (success && breakpoint.line >= editData.line)
- newLine += editData.linesCountToShift;
- WebInspector.debuggerModel.setBreakpoint(editData.sourceID, newLine, breakpoint.enabled, breakpoint.condition);
- }
- };
- InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this));
- },
-
selectedCallFrameId: function()
{
var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
@@ -359,7 +342,7 @@ WebInspector.ScriptsPanel.prototype = {
if (result)
callback(WebInspector.RemoteObject.fromPayload(result));
}
- InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback);
+ InspectorBackend.evaluateOnCallFrame(callFrame.id, code, objectGroup, evalCallback);
},
_debuggerPaused: function(event)
@@ -392,9 +375,10 @@ WebInspector.ScriptsPanel.prototype = {
debuggerWasEnabled: function()
{
+ this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionState);
+
if (this._debuggerEnabled)
return;
-
this._debuggerEnabled = true;
this.reset(true);
},
@@ -677,7 +661,7 @@ WebInspector.ScriptsPanel.prototype = {
_clearCurrentExecutionLine: function()
{
if (this._executionSourceFrame)
- this._executionSourceFrame.executionLine = 0;
+ this._executionSourceFrame.clearExecutionLine();
delete this._executionSourceFrame;
},
@@ -699,7 +683,7 @@ WebInspector.ScriptsPanel.prototype = {
this._executionSourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource);
if (this._executionSourceFrame)
- this._executionSourceFrame.executionLine = currentFrame.line;
+ this._executionSourceFrame.setExecutionLine(currentFrame.line);
},
_changeVisibleFile: function(event)
@@ -744,16 +728,21 @@ WebInspector.ScriptsPanel.prototype = {
this.resize();
},
- updatePauseOnExceptionsState: function(pauseOnExceptionsState)
+ _setPauseOnExceptions: function(pauseOnExceptionsState)
{
- if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
- else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
- else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
-
- this._pauseOnExceptionButton.state = pauseOnExceptionsState;
+ function callback(pauseOnExceptionsState)
+ {
+ if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
+ else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
+ else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
+
+ this._pauseOnExceptionButton.state = pauseOnExceptionsState;
+ WebInspector.settings.pauseOnExceptionState = pauseOnExceptionsState;
+ }
+ InspectorBackend.setPauseOnExceptionsState(pauseOnExceptionsState, callback.bind(this));
},
_updateDebuggerButtons: function()
@@ -833,6 +822,12 @@ WebInspector.ScriptsPanel.prototype = {
this._updateBackAndForwardButtons();
},
+ _formatScript: function()
+ {
+ if (this.visibleView && this.visibleView.sourceFrame)
+ this.visibleView.sourceFrame.formatSource();
+ },
+
_enableDebugging: function()
{
if (this._debuggerEnabled)
@@ -854,7 +849,7 @@ WebInspector.ScriptsPanel.prototype = {
_togglePauseOnExceptions: function()
{
- InspectorBackend.setPauseOnExceptionsState((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states, this.updatePauseOnExceptionsState.bind(this));
+ this._setPauseOnExceptions((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states);
},
_togglePause: function()
diff --git a/Source/WebCore/inspector/front-end/Settings.js b/Source/WebCore/inspector/front-end/Settings.js
index bc50ce9..e26b1d7 100644
--- a/Source/WebCore/inspector/front-end/Settings.js
+++ b/Source/WebCore/inspector/front-end/Settings.js
@@ -65,6 +65,7 @@ WebInspector.Settings = function()
this.installApplicationSetting("showUserAgentStyles", true);
this.installApplicationSetting("watchExpressions", []);
this.installApplicationSetting("lastActivePanel", "elements");
+ this.installApplicationSetting("pauseOnExceptionState", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions);
this.installProjectSetting("breakpoints", {});
this.installProjectSetting("nativeBreakpoints", []);
diff --git a/Source/WebCore/inspector/front-end/SourceFrame.js b/Source/WebCore/inspector/front-end/SourceFrame.js
index af10f1e..eb89f24 100644
--- a/Source/WebCore/inspector/front-end/SourceFrame.js
+++ b/Source/WebCore/inspector/front-end/SourceFrame.js
@@ -28,12 +28,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.SourceFrame = function(parentElement, contentProvider, url, canEditScripts)
+WebInspector.SourceFrame = function(parentElement, contentProvider, url, isScript)
{
this._parentElement = parentElement;
this._contentProvider = contentProvider;
this._url = url;
- this._canEditScripts = canEditScripts;
+ this._isScript = isScript;
+
this._textModel = new WebInspector.TextEditorModel();
this._textModel.replaceTabsWithSpaces = true;
@@ -71,23 +72,6 @@ WebInspector.SourceFrame.prototype = {
}
},
- get executionLine()
- {
- return this._executionLine;
- },
-
- set executionLine(x)
- {
- if (this._executionLine === x)
- return;
-
- var previousLine = this._executionLine;
- this._executionLine = x;
-
- if (this._textViewer)
- this._updateExecutionLine(previousLine);
- },
-
markDiff: function(diffData)
{
if (this._diffLines && this._textViewer)
@@ -172,6 +156,7 @@ WebInspector.SourceFrame.prototype = {
{
this._content = content;
this._textModel.setText(null, content);
+ this._formatter = new WebInspector.ScriptFormatter(content);
this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
var element = this._textViewer.element;
@@ -179,15 +164,13 @@ WebInspector.SourceFrame.prototype = {
element.addEventListener("mousedown", this._mouseDown.bind(this), true);
element.addEventListener("mousemove", this._mouseMove.bind(this), true);
element.addEventListener("scroll", this._scroll.bind(this), true);
+ element.addEventListener("dblclick", this._doubleClick.bind(this), true);
this._parentElement.appendChild(element);
this._textViewer.beginUpdates();
this._textViewer.mimeType = mimeType;
- this._addExistingMessagesToSource();
- this._updateExecutionLine();
- this._updateDiffDecorations();
- this._textViewer.resize();
+ this._setTextViewerDecorations();
if (this._lineNumberToReveal) {
this.revealLine(this._lineNumberToReveal);
@@ -210,15 +193,34 @@ WebInspector.SourceFrame.prototype = {
delete this._delayedFindSearchMatches;
}
+ this._textViewer.endUpdates();
+
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
+
+ if (this._canEditScripts)
+ this._textViewer.editCallback = this._editLine.bind(this);
+ },
+
+ _setTextViewerDecorations: function()
+ {
+ this._rowMessages = {};
+ this._messageBubbles = {};
+
+ this._textViewer.beginUpdates();
+
+ this._addExistingMessagesToSource();
+ this._updateDiffDecorations();
+
+ if (this._executionLine)
+ this.setExecutionLine(this._executionLine);
+
var breakpoints = this._breakpoints();
for (var i = 0; i < breakpoints.length; ++i)
this._addBreakpoint(breakpoints[i]);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
- this._textViewer.endUpdates();
+ this._textViewer.resize();
- if (this._canEditScripts)
- this._textViewer.editCallback = this._editLine.bind(this);
+ this._textViewer.endUpdates();
},
findSearchMatches: function(query, finishedCallback)
@@ -300,18 +302,22 @@ WebInspector.SourceFrame.prototype = {
msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
},
- _updateExecutionLine: function(previousLine)
+ setExecutionLine: function(lineNumber)
{
- if (previousLine) {
- if (previousLine - 1 < this._textModel.linesCount)
- this._textViewer.removeDecoration(previousLine - 1, "webkit-execution-line");
- }
-
- if (!this._executionLine)
+ this._executionLine = lineNumber;
+ if (!this._textViewer)
return;
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1);
+ this._textViewer.addDecoration(textViewerLineNumber, "webkit-execution-line");
+ },
- if (this._executionLine < this._textModel.linesCount)
- this._textViewer.addDecoration(this._executionLine - 1, "webkit-execution-line");
+ clearExecutionLine: function()
+ {
+ if (!this._textViewer)
+ return;
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1);
+ this._textViewer.removeDecoration(textViewerLineNumber, "webkit-execution-line");
+ delete this._executionLine;
},
_updateDiffDecorations: function()
@@ -412,14 +418,15 @@ WebInspector.SourceFrame.prototype = {
_addBreakpoint: function(breakpoint)
{
- if (breakpoint.line > this._textModel.linesCount)
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ if (textViewerLineNumber >= this._textModel.linesCount)
return;
breakpoint.addEventListener("enable-changed", this._breakpointChanged, this);
breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
breakpoint.addEventListener("removed", this._breakpointRemoved, this);
- this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition);
+ this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
},
_breakpointRemoved: function(event)
@@ -430,18 +437,19 @@ WebInspector.SourceFrame.prototype = {
breakpoint.removeEventListener("condition-changed", null, this);
breakpoint.removeEventListener("removed", null, this);
- this._removeBreakpointDecoration(breakpoint.line);
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ this._removeBreakpointDecoration(textViewerLineNumber);
},
_breakpointChanged: function(event)
{
var breakpoint = event.target;
- this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition);
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
},
_setBreakpointDecoration: function(lineNumber, enabled, hasCondition)
{
- lineNumber -= 1;
this._textViewer.beginUpdates();
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
if (enabled)
@@ -457,7 +465,6 @@ WebInspector.SourceFrame.prototype = {
_removeBreakpointDecoration: function(lineNumber)
{
- lineNumber -= 1;
this._textViewer.beginUpdates();
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
@@ -473,27 +480,28 @@ WebInspector.SourceFrame.prototype = {
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
- var lineNumber = target.parentElement.lineNumber + 1;
+ var textViewerLineNumber = target.parentElement.lineNumber;
+ var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(textViewerLineNumber);
var contextMenu = new WebInspector.ContextMenu();
- contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, lineNumber));
+ contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, originalLineNumber));
- var breakpoint = this._findBreakpoint(lineNumber);
+ var breakpoint = this._findBreakpoint(originalLineNumber);
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
- contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, "", true));
+ contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, originalLineNumber, "", true));
function addConditionalBreakpoint()
{
- this._setBreakpointDecoration(lineNumber, true, true);
+ this._setBreakpointDecoration(textViewerLineNumber, true, true);
function didEditBreakpointCondition(committed, condition)
{
- this._removeBreakpointDecoration(lineNumber);
+ this._removeBreakpointDecoration(textViewerLineNumber);
if (committed)
- this._setBreakpoint(lineNumber, true, condition);
+ this._setBreakpoint(originalLineNumber, true, condition);
}
- this._editBreakpointCondition(lineNumber, "", didEditBreakpointCondition.bind(this));
+ this._editBreakpointCondition(textViewerLineNumber, "", didEditBreakpointCondition.bind(this));
}
contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
} else {
@@ -505,16 +513,16 @@ WebInspector.SourceFrame.prototype = {
{
if (committed) {
breakpoint.remove();
- this._setBreakpoint(breakpoint.line, breakpoint.enabled, condition);
+ this._setBreakpoint(originalLineNumber, breakpoint.enabled, condition);
}
}
- this._editBreakpointCondition(lineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
+ this._editBreakpointCondition(textViewerLineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
}
contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this));
function setBreakpointEnabled(enabled)
{
breakpoint.remove();
- this._setBreakpoint(breakpoint.line, enabled, breakpoint.condition);
+ this._setBreakpoint(originalLineNumber, enabled, breakpoint.condition);
}
if (breakpoint.enabled)
contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false));
@@ -538,15 +546,15 @@ WebInspector.SourceFrame.prototype = {
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
- var lineNumber = target.parentElement.lineNumber + 1;
+ var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(target.parentElement.lineNumber);
- var breakpoint = this._findBreakpoint(lineNumber);
+ var breakpoint = this._findBreakpoint(originalLineNumber);
if (breakpoint) {
breakpoint.remove();
if (event.shiftKey)
- this._setBreakpoint(breakpoint.line, !breakpoint.enabled, breakpoint.condition);
+ this._setBreakpoint(originalLineNumber, !breakpoint.enabled, breakpoint.condition);
} else
- this._setBreakpoint(lineNumber, true, "");
+ this._setBreakpoint(originalLineNumber, true, "");
event.preventDefault();
},
@@ -710,7 +718,6 @@ WebInspector.SourceFrame.prototype = {
_editBreakpointCondition: function(lineNumber, condition, callback)
{
- lineNumber -= 1;
this._conditionElement = this._createConditionElement(lineNumber);
this._textViewer.addDecoration(lineNumber, this._conditionElement);
@@ -776,49 +783,55 @@ WebInspector.SourceFrame.prototype = {
this._textViewer.resize();
},
+ formatSource: function()
+ {
+ if (!this._formatter)
+ return;
+
+ function didFormat(source)
+ {
+ this._textModel.setText(null, source);
+ this._setTextViewerDecorations();
+ }
+ this._formatter.format(didFormat.bind(this));
+ },
+
_continueToLine: function(lineNumber)
{
var sourceID = this._sourceIDForLine(lineNumber);
if (!sourceID)
return;
- WebInspector.debuggerModel.continueToLine(sourceID, lineNumber);
+ WebInspector.debuggerModel.continueToLine(sourceID, lineNumber + 1);
},
- _editLine: function(lineNumber, newContent, cancelEditingCallback)
+ _doubleClick: function(event)
{
- lineNumber += 1;
-
- var lines = [];
- var oldLines = this._content.split('\n');
- for (var i = 0; i < oldLines.length; ++i) {
- if (i === lineNumber - 1)
- lines.push(newContent);
- else
- lines.push(oldLines[i]);
- }
+ if (!Preferences.canEditScriptSource || !this._isScript)
+ return;
- var editData = {};
- editData.sourceID = this._sourceIDForLine(lineNumber);
- editData.content = lines.join("\n");
- editData.line = lineNumber;
- editData.linesCountToShift = newContent.split("\n").length - 1;
- this._doEditLine(editData, cancelEditingCallback);
- },
+ var target = event.target.enclosingNodeOrSelfWithNodeName("TD");
+ if (!target || target.parentElement.firstChild === target)
+ return; // Do not trigger editing from line numbers.
- _revertEditLine: function(editData, contentToRevertTo)
- {
- var newEditData = {};
- newEditData.sourceID = editData.sourceID;
- newEditData.content = contentToRevertTo;
- newEditData.line = editData.line;
- newEditData.linesCountToShift = -editData.linesCountToShift;
- this._doEditLine(newEditData);
- },
+ var lineRow = target.parentElement;
+ var lineNumber = lineRow.lineNumber;
+ var sourceID = this._sourceIDForLine(lineNumber);
+ if (!sourceID)
+ return;
- _doEditLine: function(editData, cancelEditingCallback)
- {
- var revertEditingCallback = this._revertEditLine.bind(this, editData);
- WebInspector.panels.scripts.editScriptSource(editData, revertEditingCallback, cancelEditingCallback);
+ function didEditLine(newContent)
+ {
+ var lines = [];
+ var oldLines = this._content.split('\n');
+ for (var i = 0; i < oldLines.length; ++i) {
+ if (i === lineNumber)
+ lines.push(newContent);
+ else
+ lines.push(oldLines[i]);
+ }
+ WebInspector.debuggerModel.editScriptSource(sourceID, lines.join("\n"));
+ }
+ this._textViewer.editLine(lineRow, didEditLine.bind(this));
},
_setBreakpoint: function(lineNumber, enabled, condition)
@@ -826,7 +839,7 @@ WebInspector.SourceFrame.prototype = {
var sourceID = this._sourceIDForLine(lineNumber);
if (!sourceID)
return;
- WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber, enabled, condition);
+ WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber + 1, enabled, condition);
if (!WebInspector.panels.scripts.breakpointsActivated)
WebInspector.panels.scripts.toggleBreakpointsClicked();
},
@@ -840,7 +853,7 @@ WebInspector.SourceFrame.prototype = {
_findBreakpoint: function(lineNumber)
{
var sourceID = this._sourceIDForLine(lineNumber);
- return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber);
+ return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber + 1);
},
_sourceIDForLine: function(lineNumber)
@@ -849,9 +862,9 @@ WebInspector.SourceFrame.prototype = {
var closestStartingLine = 0;
var scripts = this._contentProvider.scripts();
for (var i = 0; i < scripts.length; ++i) {
- var startingLine = scripts[i].startingLine;
- if (startingLine <= lineNumber && startingLine >= closestStartingLine) {
- closestStartingLine = startingLine;
+ var lineOffset = scripts[i].lineOffset;
+ if (lineOffset <= lineNumber && lineOffset >= closestStartingLine) {
+ closestStartingLine = lineOffset;
sourceIDForLine = scripts[i].sourceID;
}
}
diff --git a/Source/WebCore/inspector/front-end/SourceView.js b/Source/WebCore/inspector/front-end/SourceView.js
index e78ff94..37caabb 100644
--- a/Source/WebCore/inspector/front-end/SourceView.js
+++ b/Source/WebCore/inspector/front-end/SourceView.js
@@ -33,8 +33,8 @@ WebInspector.SourceView = function(resource)
this.element.addStyleClass("source");
var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource);
- var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
- this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, canEditScripts);
+ var isScript = resource.type === WebInspector.Resource.Type.Script;
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, isScript);
}
WebInspector.SourceView.prototype = {
diff --git a/Source/WebCore/inspector/front-end/StylesSidebarPane.js b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
index d646829..9880adc 100644
--- a/Source/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -81,6 +81,8 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
}
+WebInspector.StylesSidebarPane.StyleValueDelimiters = " \t\n\"':;,/()";
+
// Taken from http://www.w3.org/TR/CSS21/propidx.html.
WebInspector.StylesSidebarPane.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
@@ -1379,6 +1381,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
this.listItemElement.removeChildren();
+ nameElement.normalize();
+ valueElement.normalize();
if (!this.treeOutline)
return;
@@ -1529,16 +1533,15 @@ WebInspector.StylePropertyTreeElement.prototype = {
var context = {
expanded: this.expanded,
hasChildren: this.hasChildren,
- keyDownListener: isEditingName ? this.editingNameKeyDown.bind(this) : this.editingValueKeyDown.bind(this),
- keyPressListener: isEditingName ? this.editingNameKeyPress.bind(this) : this.editingValueKeyPress.bind(this),
+ keyDownListener: isEditingName ? null : this.editingValueKeyDown.bind(this),
isEditingName: isEditingName,
};
// Lie about our children to prevent expanding on double click and to collapse shorthands.
this.hasChildren = false;
- selectElement.addEventListener("keydown", context.keyDownListener, false);
- selectElement.addEventListener("keypress", context.keyPressListener, false);
+ if (!isEditingName)
+ selectElement.addEventListener("keydown", context.keyDownListener, false);
if (selectElement.parentElement)
selectElement.parentElement.addStyleClass("child-editing");
selectElement.textContent = selectElement.textContent; // remove color swatch and the like
@@ -1613,76 +1616,15 @@ WebInspector.StylePropertyTreeElement.prototype = {
customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName),
pasteHandler: isEditingName ? pasteHandler.bind(this, context) : null
});
- window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
- },
-
- editingNameKeyPress: function(event)
- {
- // Complete property names.
- var character = event.data.toLowerCase();
- if (character && /[a-z-]/.test(character)) {
- var selection = window.getSelection();
- var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
- var property = WebInspector.cssNameCompletions.firstStartsWith(prefix + character);
- if (!selection.isCollapsed)
- selection.deleteFromDocument();
-
- this.restoreNameElement();
-
- if (property) {
- if (property !== this.nameElement.textContent)
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(prefix.length + 1);
- event.preventDefault();
- }
- }
- },
-
- editingValueKeyPress: function(event)
- {
- // FIXME: This should complete property values.
- },
-
- editingNameKeyDown: function(event)
- {
- var showNext;
- if (event.keyIdentifier === "Up")
- showNext = false;
- else if (event.keyIdentifier === "Down")
- showNext = true;
- else
- return;
-
- var selection = window.getSelection();
- if (!selection.rangeCount)
- return;
-
- var selectionRange = selection.getRangeAt(0);
- if (selectionRange.commonAncestorContainer !== this.nameElement && !selectionRange.commonAncestorContainer.isDescendant(this.nameElement))
- return;
-
- const styleValueDelimeters = " \t\n\"':;,/()";
- var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.nameElement);
- var wordString = wordRange.toString();
- var cursorPosition = selectionRange.startOffset != selectionRange.endOffset ? selectionRange.startOffset : 0;
- var prefix = selectionRange.startContainer.textContent.substring(0, cursorPosition);
- var property;
-
- if (showNext)
- property = WebInspector.cssNameCompletions.next(wordString, prefix);
- else
- property = WebInspector.cssNameCompletions.previous(wordString, prefix);
-
- if (property) {
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(cursorPosition);
- }
- event.preventDefault();
+ this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(selectElement, isEditingName ? WebInspector.cssNameCompletions : WebInspector.CSSKeywordCompletions.forProperty(this.nameElement.textContent));
+ window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
},
editingValueKeyDown: function(event)
{
+ if (event.handled)
+ return;
var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyPressed && !pageKeyPressed)
@@ -1696,8 +1638,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement))
return;
- const styleValueDelimeters = " \t\n\"':;,/()";
- var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.valueElement);
+ var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.valueElement);
var wordString = wordRange.toString();
var replacementString = wordString;
@@ -1739,42 +1680,45 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
replacementString = prefix + number + suffix;
- } else {
- // FIXME: this should cycle through known keywords for the current property value.
- }
- var replacementTextNode = document.createTextNode(replacementString);
+ var replacementTextNode = document.createTextNode(replacementString);
- wordRange.deleteContents();
- wordRange.insertNode(replacementTextNode);
+ wordRange.deleteContents();
+ wordRange.insertNode(replacementTextNode);
- var finalSelectionRange = document.createRange();
- finalSelectionRange.setStart(replacementTextNode, 0);
- finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
+ var finalSelectionRange = document.createRange();
+ finalSelectionRange.setStart(replacementTextNode, 0);
+ finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
- selection.removeAllRanges();
- selection.addRange(finalSelectionRange);
+ selection.removeAllRanges();
+ selection.addRange(finalSelectionRange);
- event.preventDefault();
+ event.handled = true;
+ event.preventDefault();
- if (!("originalPropertyText" in this)) {
- // Remember the rule's original CSS text on [Page](Up|Down), so it can be restored
- // if the editing is canceled.
- this.originalPropertyText = this.property.propertyText;
- }
+ if (!("originalPropertyText" in this)) {
+ // Remember the rule's original CSS text on [Page](Up|Down), so it can be restored
+ // if the editing is canceled.
+ this.originalPropertyText = this.property.propertyText;
+ }
- // Synthesize property text disregarding any comments, custom whitespace etc.
- this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
+ // Synthesize property text disregarding any comments, custom whitespace etc.
+ this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
+ }
},
editingEnded: function(context)
{
+ if (this._prompt) {
+ this._prompt.removeFromElement();
+ delete this._prompt;
+ }
this.hasChildren = context.hasChildren;
if (context.expanded)
this.expand();
var editedElement = context.isEditingName ? this.nameElement : this.valueElement;
- editedElement.removeEventListener("keydown", context.keyDownListener, false);
- editedElement.removeEventListener("keypress", context.keyPressListener, false);
+ if (!context.isEditingName)
+ editedElement.removeEventListener("keydown", context.keyDownListener, false);
if (editedElement.parentElement)
editedElement.parentElement.removeStyleClass("child-editing");
@@ -1791,6 +1735,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
else
this.updateTitle();
}
+
+ // This should happen last, as it clears the info necessary to restore the property value after [Page]Up/Down changes.
this.editingEnded(context);
},
@@ -1948,3 +1894,57 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
WebInspector.StylePropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(element, cssCompletions)
+{
+ WebInspector.TextPrompt.call(this, element, this._buildPropertyCompletions.bind(this), WebInspector.StylesSidebarPane.StyleValueDelimiters, true);
+ this._cssCompletions = cssCompletions;
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
+ upKeyPressed: function(event)
+ {
+ this._handleNameOrValueUpDown(event);
+ },
+
+ downKeyPressed: function(event)
+ {
+ this._handleNameOrValueUpDown(event);
+ },
+
+ tabKeyPressed: function(event)
+ {
+ this.acceptAutoComplete();
+ },
+
+ _handleNameOrValueUpDown: function(event)
+ {
+ var reverse = event.keyIdentifier === "Up";
+ if (this.autoCompleteElement)
+ this.complete(false, reverse); // Accept the current suggestion, if any.
+ this.complete(false, reverse); // Actually increment/decrement the suggestion.
+ event.handled = true;
+ },
+
+ _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback)
+ {
+ var prefix = wordRange.toString().toLowerCase();
+ if (!prefix.length)
+ return;
+
+ var results;
+ if (bestMatchOnly) {
+ results = [];
+ var firstMatch = this._cssCompletions.firstStartsWith(prefix);
+ if (firstMatch)
+ results.push(firstMatch);
+ return completionsReadyCallback(results);
+ }
+
+ results = this._cssCompletions.startsWith(prefix);
+ if (results)
+ completionsReadyCallback(results);
+ }
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;
diff --git a/Source/WebCore/inspector/front-end/TextPrompt.js b/Source/WebCore/inspector/front-end/TextPrompt.js
index 21a5bde..ac54d8c 100644
--- a/Source/WebCore/inspector/front-end/TextPrompt.js
+++ b/Source/WebCore/inspector/front-end/TextPrompt.js
@@ -26,15 +26,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.TextPrompt = function(element, completions, stopCharacters)
+WebInspector.TextPrompt = function(element, completions, stopCharacters, omitHistory)
{
this.element = element;
this.element.addStyleClass("text-prompt");
this.completions = completions;
this.completionStopCharacters = stopCharacters;
- this.history = [];
- this.historyOffset = 0;
- this.element.addEventListener("keydown", this._onKeyDown.bind(this), true);
+ if (!omitHistory) {
+ this.history = [];
+ this.historyOffset = 0;
+ }
+ this._boundOnKeyDown = this._onKeyDown.bind(this);
+ this.element.addEventListener("keydown", this._boundOnKeyDown, true);
}
WebInspector.TextPrompt.prototype = {
@@ -55,6 +58,12 @@ WebInspector.TextPrompt.prototype = {
this.moveCaretToEndOfPrompt();
},
+ removeFromElement: function()
+ {
+ this.clearAutoComplete(true);
+ this.element.removeEventListener("keydown", this._boundOnKeyDown, true);
+ },
+
_onKeyDown: function(event)
{
function defaultAction()
@@ -63,16 +72,20 @@ WebInspector.TextPrompt.prototype = {
this.autoCompleteSoon();
}
+ if (event.handled)
+ return;
+
var handled = false;
+
switch (event.keyIdentifier) {
case "Up":
- this._upKeyPressed(event);
+ this.upKeyPressed(event);
break;
case "Down":
- this._downKeyPressed(event);
+ this.downKeyPressed(event);
break;
case "U+0009": // Tab
- this._tabKeyPressed(event);
+ this.tabKeyPressed(event);
break;
case "Right":
case "End":
@@ -85,7 +98,7 @@ WebInspector.TextPrompt.prototype = {
case "Control":
break;
case "U+0050": // Ctrl+P = Previous
- if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+ if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveBackInHistory();
break;
@@ -93,7 +106,7 @@ WebInspector.TextPrompt.prototype = {
defaultAction.call(this);
break;
case "U+004E": // Ctrl+N = Next
- if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+ if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveForwardInHistory();
break;
@@ -105,7 +118,9 @@ WebInspector.TextPrompt.prototype = {
break;
}
+ handled |= event.handled;
if (handled) {
+ event.handled = true;
event.preventDefault();
event.stopPropagation();
}
@@ -376,39 +391,33 @@ WebInspector.TextPrompt.prototype = {
selection.addRange(selectionRange);
},
- _tabKeyPressed: function(event)
+ tabKeyPressed: function(event)
{
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this.complete(false, event.shiftKey);
},
- _upKeyPressed: function(event)
+ upKeyPressed: function(event)
{
if (!this.isCaretOnFirstLine())
return;
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this._moveBackInHistory();
},
- _downKeyPressed: function(event)
+ downKeyPressed: function(event)
{
if (!this.isCaretOnLastLine())
return;
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this._moveForwardInHistory();
},
_moveBackInHistory: function()
{
- if (this.historyOffset == this.history.length)
+ if (!this.history || this.historyOffset == this.history.length)
return;
this.clearAutoComplete(true);
@@ -437,7 +446,7 @@ WebInspector.TextPrompt.prototype = {
_moveForwardInHistory: function()
{
- if (this.historyOffset === 0)
+ if (!this.history || this.historyOffset === 0)
return;
this.clearAutoComplete(true);
diff --git a/Source/WebCore/inspector/front-end/TextViewer.js b/Source/WebCore/inspector/front-end/TextViewer.js
index f116dea..ea36513 100644
--- a/Source/WebCore/inspector/front-end/TextViewer.js
+++ b/Source/WebCore/inspector/front-end/TextViewer.js
@@ -43,7 +43,6 @@ WebInspector.TextViewer = function(textModel, platform, url)
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false);
this.element.addEventListener("copy", this._copy.bind(this), false);
- this.element.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);
this._url = url;
@@ -80,11 +79,6 @@ WebInspector.TextViewer.prototype = {
chunk.element.scrollIntoViewIfNeeded();
},
- set editCallback(editCallback)
- {
- this._editCallback = editCallback;
- },
-
addDecoration: function(lineNumber, decoration)
{
var chunk = this._makeLineAChunk(lineNumber);
@@ -231,20 +225,20 @@ WebInspector.TextViewer.prototype = {
scrollValue = -1;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Down.code)
scrollValue = 1;
-
+
if (scrollValue) {
event.preventDefault();
event.stopPropagation();
this.element.scrollByLines(scrollValue);
return;
}
-
+
scrollValue = 0;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Left.code)
scrollValue = -40;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Right.code)
scrollValue = 40;
-
+
if (scrollValue) {
event.preventDefault();
event.stopPropagation();
@@ -252,42 +246,25 @@ WebInspector.TextViewer.prototype = {
}
},
- _handleDoubleClick: function(e)
+ editLine: function(lineRow, callback)
{
- if (!this._editCallback)
- return;
-
- var cell = e.target.enclosingNodeOrSelfWithNodeName("TD");
- if (!cell)
- return;
-
- var lineRow = cell.parentElement;
- if (lineRow.firstChild === cell)
- return; // Do not trigger editing from line numbers.
-
- var oldContent = lineRow.lastChild.innerHTML;
- var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent);
- var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback);
- this._editingLine = WebInspector.startEditing(lineRow.lastChild, {
+ var element = lineRow.lastChild;
+ var oldContent = element.innerHTML;
+ function finishEditing(committed, e, newContent)
+ {
+ if (committed)
+ callback(newContent);
+ element.innerHTML = oldContent;
+ delete this._editingLine;
+ }
+ this._editingLine = WebInspector.startEditing(element, {
context: null,
- commitHandler: commitEditingCallback,
- cancelHandler: cancelEditingCallback,
+ commitHandler: finishEditing.bind(this, true),
+ cancelHandler: finishEditing.bind(this, false),
multiline: true
});
},
- _commitEditingLine: function(lineNumber, element, cancelEditingCallback)
- {
- this._editCallback(lineNumber, element.textContent, cancelEditingCallback);
- delete this._editingLine;
- },
-
- _cancelEditingLine: function(element, oldContent, e)
- {
- element.innerHTML = oldContent;
- delete this._editingLine;
- },
-
_beforeCopy: function(e)
{
e.preventDefault();
@@ -786,7 +763,7 @@ WebInspector.TextChunk.prototype = {
var lineContentElement = document.createElement("td");
lineContentElement.className = "webkit-line-content";
- lineRow.appendChild(lineContentElement);
+ lineRow.appendChild(lineContentElement);
}
lineRow.lineNumber = lineNumber;
lineNumberElement.textContent = lineNumber + 1;
diff --git a/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js
new file mode 100644
index 0000000..a218c01
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js
@@ -0,0 +1,1233 @@
+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file contains the tokenizer/parser. It is a port to JavaScript
+ of parse-js [1], a JavaScript parser library written in Common Lisp
+ by Marijn Haverbeke. Thank you Marijn!
+
+ [1] http://marijn.haverbeke.nl/parse-js/
+
+ Exported functions:
+
+ - tokenizer(code) -- returns a function. Call the returned
+ function to fetch the next token.
+
+ - parse(code) -- returns an AST of the given JavaScript code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+ Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
+
+ 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “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 HOLDER 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.
+
+ ***********************************************************************/
+
+/* -----[ Tokenizer (constants) ]----- */
+
+var KEYWORDS = array_to_hash([
+ "break",
+ "case",
+ "catch",
+ "const",
+ "continue",
+ "default",
+ "delete",
+ "do",
+ "else",
+ "finally",
+ "for",
+ "function",
+ "if",
+ "in",
+ "instanceof",
+ "new",
+ "return",
+ "switch",
+ "throw",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "while",
+ "with"
+]);
+
+var RESERVED_WORDS = array_to_hash([
+ "abstract",
+ "boolean",
+ "byte",
+ "char",
+ "class",
+ "debugger",
+ "double",
+ "enum",
+ "export",
+ "extends",
+ "final",
+ "float",
+ "goto",
+ "implements",
+ "import",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "short",
+ "static",
+ "super",
+ "synchronized",
+ "throws",
+ "transient",
+ "volatile"
+]);
+
+var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
+ "return",
+ "new",
+ "delete",
+ "throw",
+ "else",
+ "case"
+]);
+
+var KEYWORDS_ATOM = array_to_hash([
+ "false",
+ "null",
+ "true",
+ "undefined"
+]);
+
+var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
+
+var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
+var RE_OCT_NUMBER = /^0[0-7]+$/;
+var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
+
+var OPERATORS = array_to_hash([
+ "in",
+ "instanceof",
+ "typeof",
+ "new",
+ "void",
+ "delete",
+ "++",
+ "--",
+ "+",
+ "-",
+ "!",
+ "~",
+ "&",
+ "|",
+ "^",
+ "*",
+ "/",
+ "%",
+ ">>",
+ "<<",
+ ">>>",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "===",
+ "!=",
+ "!==",
+ "?",
+ "=",
+ "+=",
+ "-=",
+ "/=",
+ "*=",
+ "%=",
+ ">>=",
+ "<<=",
+ ">>>=",
+ "~=",
+ "%=",
+ "|=",
+ "^=",
+ "&=",
+ "&&",
+ "||"
+]);
+
+var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t"));
+
+var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
+
+var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
+
+var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
+
+/* -----[ Tokenizer ]----- */
+
+function is_alphanumeric_char(ch) {
+ ch = ch.charCodeAt(0);
+ return (ch >= 48 && ch <= 57) ||
+ (ch >= 65 && ch <= 90) ||
+ (ch >= 97 && ch <= 122);
+};
+
+function is_identifier_char(ch) {
+ return is_alphanumeric_char(ch) || ch == "$" || ch == "_";
+};
+
+function is_digit(ch) {
+ ch = ch.charCodeAt(0);
+ return ch >= 48 && ch <= 57;
+};
+
+function parse_js_number(num) {
+ if (RE_HEX_NUMBER.test(num)) {
+ return parseInt(num.substr(2), 16);
+ } else if (RE_OCT_NUMBER.test(num)) {
+ return parseInt(num.substr(1), 8);
+ } else if (RE_DEC_NUMBER.test(num)) {
+ return parseFloat(num);
+ }
+};
+
+function JS_Parse_Error(message, line, col, pos) {
+ this.message = message;
+ this.line = line;
+ this.col = col;
+ this.pos = pos;
+ try {
+ ({})();
+ } catch(ex) {
+ this.stack = ex.stack;
+ };
+};
+
+JS_Parse_Error.prototype.toString = function() {
+ return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
+};
+
+function js_error(message, line, col, pos) {
+ throw new JS_Parse_Error(message, line, col, pos);
+};
+
+function is_token(token, type, val) {
+ return token.type == type && (val == null || token.value == val);
+};
+
+var EX_EOF = {};
+
+function tokenizer($TEXT, skip_comments) {
+
+ var S = {
+ text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
+ pos : 0,
+ tokpos : 0,
+ line : 0,
+ tokline : 0,
+ col : 0,
+ tokcol : 0,
+ newline_before : false,
+ regex_allowed : false
+ };
+
+ function peek() { return S.text.charAt(S.pos); };
+
+ function next(signal_eof) {
+ var ch = S.text.charAt(S.pos++);
+ if (signal_eof && !ch)
+ throw EX_EOF;
+ if (ch == "\n") {
+ S.newline_before = true;
+ ++S.line;
+ S.col = 0;
+ } else {
+ ++S.col;
+ }
+ return ch;
+ };
+
+ function eof() {
+ return !S.peek();
+ };
+
+ function find(what, signal_eof) {
+ var pos = S.text.indexOf(what, S.pos);
+ if (signal_eof && pos == -1) throw EX_EOF;
+ return pos;
+ };
+
+ function start_token() {
+ S.tokline = S.line;
+ S.tokcol = S.col;
+ S.tokpos = S.pos;
+ };
+
+ function token(type, value) {
+ S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
+ (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
+ (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
+ var ret = {
+ type : type,
+ value : value,
+ line : S.tokline,
+ col : S.tokcol,
+ pos : S.tokpos,
+ nlb : S.newline_before
+ };
+ S.newline_before = false;
+ return ret;
+ };
+
+ function skip_whitespace() {
+ while (HOP(WHITESPACE_CHARS, peek()))
+ next();
+ };
+
+ function read_while(pred) {
+ var ret = "", ch = peek(), i = 0;
+ while (ch && pred(ch, i++)) {
+ ret += next();
+ ch = peek();
+ }
+ return ret;
+ };
+
+ function parse_error(err) {
+ js_error(err, S.tokline, S.tokcol, S.tokpos);
+ };
+
+ function read_num(prefix) {
+ var has_e = false, after_e = false, has_x = false;
+ var num = read_while(function(ch, i){
+ if (ch == "x" || ch == "X") {
+ if (has_x) return false;
+ return has_x = true;
+ }
+ if (!has_x && (ch == "E" || ch == "e")) {
+ if (has_e) return false;
+ return has_e = after_e = true;
+ }
+ if (ch == "-") {
+ if (after_e || (i == 0 && !prefix)) return true;
+ return false;
+ }
+ if (ch == "+") return after_e;
+ after_e = false;
+ return is_alphanumeric_char(ch) || ch == ".";
+ });
+ if (prefix)
+ num = prefix + num;
+ var valid = parse_js_number(num);
+ if (!isNaN(valid)) {
+ return token("num", valid);
+ } else {
+ parse_error("Invalid syntax: " + num);
+ }
+ };
+
+ function read_escaped_char() {
+ var ch = next(true);
+ switch (ch) {
+ case "n" : return "\n";
+ case "r" : return "\r";
+ case "t" : return "\t";
+ case "b" : return "\b";
+ case "v" : return "\v";
+ case "f" : return "\f";
+ case "0" : return "\0";
+ case "x" : return String.fromCharCode(hex_bytes(2));
+ case "u" : return String.fromCharCode(hex_bytes(4));
+ default : return ch;
+ }
+ };
+
+ function hex_bytes(n) {
+ var num = 0;
+ for (; n > 0; --n) {
+ var digit = parseInt(next(true), 16);
+ if (isNaN(digit))
+ parse_error("Invalid hex-character pattern in string");
+ num = (num << 4) | digit;
+ }
+ return num;
+ };
+
+ function read_string() {
+ return with_eof_error("Unterminated string constant", function(){
+ var quote = next(), ret = "";
+ for (;;) {
+ var ch = next(true);
+ if (ch == "\\") ch = read_escaped_char();
+ else if (ch == quote) break;
+ ret += ch;
+ }
+ return token("string", ret);
+ });
+ };
+
+ function read_line_comment() {
+ next();
+ var i = find("\n"), ret;
+ if (i == -1) {
+ ret = S.text.substr(S.pos);
+ S.pos = S.text.length;
+ } else {
+ ret = S.text.substring(S.pos, i);
+ S.pos = i;
+ }
+ return token("comment1", ret);
+ };
+
+ function read_multiline_comment() {
+ next();
+ return with_eof_error("Unterminated multiline comment", function(){
+ var i = find("*/", true),
+ text = S.text.substring(S.pos, i),
+ tok = token("comment2", text);
+ S.pos = i + 2;
+ S.newline_before = text.indexOf("\n") >= 0;
+ return tok;
+ });
+ };
+
+ function read_regexp() {
+ return with_eof_error("Unterminated regular expression", function(){
+ var prev_backslash = false, regexp = "", ch, in_class = false;
+ while ((ch = next(true))) if (prev_backslash) {
+ regexp += "\\" + ch;
+ prev_backslash = false;
+ } else if (ch == "[") {
+ in_class = true;
+ regexp += ch;
+ } else if (ch == "]" && in_class) {
+ in_class = false;
+ regexp += ch;
+ } else if (ch == "/" && !in_class) {
+ break;
+ } else if (ch == "\\") {
+ prev_backslash = true;
+ } else {
+ regexp += ch;
+ }
+ var mods = read_while(function(ch){
+ return HOP(REGEXP_MODIFIERS, ch);
+ });
+ return token("regexp", [ regexp, mods ]);
+ });
+ };
+
+ function read_operator(prefix) {
+ function grow(op) {
+ var bigger = op + peek();
+ if (HOP(OPERATORS, bigger)) {
+ next();
+ return grow(bigger);
+ } else {
+ return op;
+ }
+ };
+ return token("operator", grow(prefix || next()));
+ };
+
+ var handle_slash = skip_comments ? function() {
+ next();
+ var regex_allowed = S.regex_allowed;
+ switch (peek()) {
+ case "/": read_line_comment(); S.regex_allowed = regex_allowed; return next_token();
+ case "*": read_multiline_comment(); S.regex_allowed = regex_allowed; return next_token();
+ }
+ return S.regex_allowed ? read_regexp() : read_operator("/");
+ } : function() {
+ next();
+ switch (peek()) {
+ case "/": return read_line_comment();
+ case "*": return read_multiline_comment();
+ }
+ return S.regex_allowed ? read_regexp() : read_operator("/");
+ };
+
+ function handle_dot() {
+ next();
+ return is_digit(peek())
+ ? read_num(".")
+ : token("punc", ".");
+ };
+
+ function read_word() {
+ var word = read_while(is_identifier_char);
+ return !HOP(KEYWORDS, word)
+ ? token("name", word)
+ : HOP(OPERATORS, word)
+ ? token("operator", word)
+ : HOP(KEYWORDS_ATOM, word)
+ ? token("atom", word)
+ : token("keyword", word);
+ };
+
+ function with_eof_error(eof_error, cont) {
+ try {
+ return cont();
+ } catch(ex) {
+ if (ex === EX_EOF) parse_error(eof_error);
+ else throw ex;
+ }
+ };
+
+ function next_token(force_regexp) {
+ if (force_regexp)
+ return read_regexp();
+ skip_whitespace();
+ start_token();
+ var ch = peek();
+ if (!ch) return token("eof");
+ if (is_digit(ch)) return read_num();
+ if (ch == '"' || ch == "'") return read_string();
+ if (HOP(PUNC_CHARS, ch)) return token("punc", next());
+ if (ch == ".") return handle_dot();
+ if (ch == "/") return handle_slash();
+ if (HOP(OPERATOR_CHARS, ch)) return read_operator();
+ if (is_identifier_char(ch)) return read_word();
+ parse_error("Unexpected character '" + ch + "'");
+ };
+
+ next_token.context = function(nc) {
+ if (nc) S = nc;
+ return S;
+ };
+
+ return next_token;
+
+};
+
+/* -----[ Parser (constants) ]----- */
+
+var UNARY_PREFIX = array_to_hash([
+ "typeof",
+ "void",
+ "delete",
+ "--",
+ "++",
+ "!",
+ "~",
+ "-",
+ "+"
+]);
+
+var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
+
+var ASSIGNMENT = (function(a, ret, i){
+ while (i < a.length) {
+ ret[a[i]] = a[i].substr(0, a[i].length - 1);
+ i++;
+ }
+ return ret;
+})(
+ ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "~=", "%=", "|=", "^=", "&="],
+ { "=": true },
+ 0
+);
+
+var PRECEDENCE = (function(a, ret){
+ for (var i = 0, n = 1; i < a.length; ++i, ++n) {
+ var b = a[i];
+ for (var j = 0; j < b.length; ++j) {
+ ret[b[j]] = n;
+ }
+ }
+ return ret;
+})(
+ [
+ ["||"],
+ ["&&"],
+ ["|"],
+ ["^"],
+ ["&"],
+ ["==", "===", "!=", "!=="],
+ ["<", ">", "<=", ">=", "in", "instanceof"],
+ [">>", "<<", ">>>"],
+ ["+", "-"],
+ ["*", "/", "%"]
+ ],
+ {}
+);
+
+var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
+
+var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
+
+/* -----[ Parser ]----- */
+
+function NodeWithToken(str, start, end) {
+ this.name = str;
+ this.start = start;
+ this.end = end;
+};
+
+NodeWithToken.prototype.toString = function() { return this.name; };
+
+function parse($TEXT, strict_mode, embed_tokens) {
+
+ var S = {
+ input: tokenizer($TEXT, true),
+ token: null,
+ prev: null,
+ peeked: null,
+ in_function: 0,
+ in_loop: 0,
+ labels: []
+ };
+
+ S.token = next();
+
+ function is(type, value) {
+ return is_token(S.token, type, value);
+ };
+
+ function peek() { return S.peeked || (S.peeked = S.input()); };
+
+ function next() {
+ S.prev = S.token;
+ if (S.peeked) {
+ S.token = S.peeked;
+ S.peeked = null;
+ } else {
+ S.token = S.input();
+ }
+ return S.token;
+ };
+
+ function prev() {
+ return S.prev;
+ };
+
+ function croak(msg, line, col, pos) {
+ var ctx = S.input.context();
+ js_error(msg,
+ line != null ? line : ctx.tokline,
+ col != null ? col : ctx.tokcol,
+ pos != null ? pos : ctx.tokpos);
+ };
+
+ function token_error(token, msg) {
+ croak(msg, token.line, token.col);
+ };
+
+ function unexpected(token) {
+ if (token == null)
+ token = S.token;
+ token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
+ };
+
+ function expect_token(type, val) {
+ if (is(type, val)) {
+ return next();
+ }
+ token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
+ };
+
+ function expect(punc) { return expect_token("punc", punc); };
+
+ function can_insert_semicolon() {
+ return !strict_mode && (
+ S.token.nlb || is("eof") || is("punc", "}")
+ );
+ };
+
+ function semicolon() {
+ if (is("punc", ";")) next();
+ else if (!can_insert_semicolon()) unexpected();
+ };
+
+ function as() {
+ return slice(arguments);
+ };
+
+ function parenthesised() {
+ expect("(");
+ var ex = expression();
+ expect(")");
+ return ex;
+ };
+
+ function add_tokens(str, start, end) {
+ return new NodeWithToken(str, start, end);
+ };
+
+ var statement = embed_tokens ? function() {
+ var start = S.token;
+ var stmt = $statement();
+ stmt[0] = add_tokens(stmt[0], start, prev());
+ return stmt;
+ } : $statement;
+
+ function $statement() {
+ if (is("operator", "/")) {
+ S.peeked = null;
+ S.token = S.input(true); // force regexp
+ }
+ switch (S.token.type) {
+ case "num":
+ case "string":
+ case "regexp":
+ case "operator":
+ case "atom":
+ return simple_statement();
+
+ case "name":
+ return is_token(peek(), "punc", ":")
+ ? labeled_statement(prog1(S.token.value, next, next))
+ : simple_statement();
+
+ case "punc":
+ switch (S.token.value) {
+ case "{":
+ return as("block", block_());
+ case "[":
+ case "(":
+ return simple_statement();
+ case ";":
+ next();
+ return as("block");
+ default:
+ unexpected();
+ }
+
+ case "keyword":
+ switch (prog1(S.token.value, next)) {
+ case "break":
+ return break_cont("break");
+
+ case "continue":
+ return break_cont("continue");
+
+ case "debugger":
+ semicolon();
+ return as("debugger");
+
+ case "do":
+ return (function(body){
+ expect_token("keyword", "while");
+ return as("do", prog1(parenthesised, semicolon), body);
+ })(in_loop(statement));
+
+ case "for":
+ return for_();
+
+ case "function":
+ return function_(true);
+
+ case "if":
+ return if_();
+
+ case "return":
+ if (S.in_function == 0)
+ croak("'return' outside of function");
+ return as("return",
+ is("punc", ";")
+ ? (next(), null)
+ : can_insert_semicolon()
+ ? null
+ : prog1(expression, semicolon));
+
+ case "switch":
+ return as("switch", parenthesised(), switch_block_());
+
+ case "throw":
+ return as("throw", prog1(expression, semicolon));
+
+ case "try":
+ return try_();
+
+ case "var":
+ return prog1(var_, semicolon);
+
+ case "const":
+ return prog1(const_, semicolon);
+
+ case "while":
+ return as("while", parenthesised(), in_loop(statement));
+
+ case "with":
+ return as("with", parenthesised(), statement());
+
+ default:
+ unexpected();
+ }
+ }
+ };
+
+ function labeled_statement(label) {
+ S.labels.push(label);
+ var start = S.token, stat = statement();
+ if (strict_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
+ unexpected(start);
+ S.labels.pop();
+ return as("label", label, stat);
+ };
+
+ function simple_statement() {
+ return as("stat", prog1(expression, semicolon));
+ };
+
+ function break_cont(type) {
+ var name = is("name") ? S.token.value : null;
+ if (name != null) {
+ next();
+ if (!member(name, S.labels))
+ croak("Label " + name + " without matching loop or statement");
+ }
+ else if (S.in_loop == 0)
+ croak(type + " not inside a loop or switch");
+ semicolon();
+ return as(type, name);
+ };
+
+ function for_() {
+ expect("(");
+ var has_var = is("keyword", "var");
+ if (has_var)
+ next();
+ if (is("name") && is_token(peek(), "operator", "in")) {
+ // for (i in foo)
+ var name = S.token.value;
+ next(); next();
+ var obj = expression();
+ expect(")");
+ return as("for-in", has_var, name, obj, in_loop(statement));
+ } else {
+ // classic for
+ var init = is("punc", ";") ? null : has_var ? var_() : expression();
+ expect(";");
+ var test = is("punc", ";") ? null : expression();
+ expect(";");
+ var step = is("punc", ")") ? null : expression();
+ expect(")");
+ return as("for", init, test, step, in_loop(statement));
+ }
+ };
+
+ function function_(in_statement) {
+ var name = is("name") ? prog1(S.token.value, next) : null;
+ if (in_statement && !name)
+ unexpected();
+ expect("(");
+ return as(in_statement ? "defun" : "function",
+ name,
+ // arguments
+ (function(first, a){
+ while (!is("punc", ")")) {
+ if (first) first = false; else expect(",");
+ if (!is("name")) unexpected();
+ a.push(S.token.value);
+ next();
+ }
+ next();
+ return a;
+ })(true, []),
+ // body
+ (function(){
+ ++S.in_function;
+ var loop = S.in_loop;
+ S.in_loop = 0;
+ var a = block_();
+ --S.in_function;
+ S.in_loop = loop;
+ return a;
+ })());
+ };
+
+ function if_() {
+ var cond = parenthesised(), body = statement(), belse;
+ if (is("keyword", "else")) {
+ next();
+ belse = statement();
+ }
+ return as("if", cond, body, belse);
+ };
+
+ function block_() {
+ expect("{");
+ var a = [];
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ a.push(statement());
+ }
+ next();
+ return a;
+ };
+
+ var switch_block_ = curry(in_loop, function(){
+ expect("{");
+ var a = [], cur = null;
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ if (is("keyword", "case")) {
+ next();
+ cur = [];
+ a.push([ expression(), cur ]);
+ expect(":");
+ }
+ else if (is("keyword", "default")) {
+ next();
+ expect(":");
+ cur = [];
+ a.push([ null, cur ]);
+ }
+ else {
+ if (!cur) unexpected();
+ cur.push(statement());
+ }
+ }
+ next();
+ return a;
+ });
+
+ function try_() {
+ var body = block_(), bcatch, bfinally;
+ if (is("keyword", "catch")) {
+ next();
+ expect("(");
+ if (!is("name"))
+ croak("Name expected");
+ var name = S.token.value;
+ next();
+ expect(")");
+ bcatch = [ name, block_() ];
+ }
+ if (is("keyword", "finally")) {
+ next();
+ bfinally = block_();
+ }
+ if (!bcatch && !bfinally)
+ croak("Missing catch/finally blocks");
+ return as("try", body, bcatch, bfinally);
+ };
+
+ function vardefs() {
+ var a = [];
+ for (;;) {
+ if (!is("name"))
+ unexpected();
+ var name = S.token.value;
+ next();
+ if (is("operator", "=")) {
+ next();
+ a.push([ name, expression(false) ]);
+ } else {
+ a.push([ name ]);
+ }
+ if (!is("punc", ","))
+ break;
+ next();
+ }
+ return a;
+ };
+
+ function var_() {
+ return as("var", vardefs());
+ };
+
+ function const_() {
+ return as("const", vardefs());
+ };
+
+ function new_() {
+ var newexp = expr_atom(false), args;
+ if (is("punc", "(")) {
+ next();
+ args = expr_list(")");
+ } else {
+ args = [];
+ }
+ return subscripts(as("new", newexp, args), true);
+ };
+
+ function expr_atom(allow_calls) {
+ if (is("operator", "new")) {
+ next();
+ return new_();
+ }
+ if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
+ return make_unary("unary-prefix",
+ prog1(S.token.value, next),
+ expr_atom(allow_calls));
+ }
+ if (is("punc")) {
+ switch (S.token.value) {
+ case "(":
+ next();
+ return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
+ case "[":
+ next();
+ return subscripts(array_(), allow_calls);
+ case "{":
+ next();
+ return subscripts(object_(), allow_calls);
+ }
+ unexpected();
+ }
+ if (is("keyword", "function")) {
+ next();
+ return subscripts(function_(false), allow_calls);
+ }
+ if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
+ var atom = S.token.type == "regexp"
+ ? as("regexp", S.token.value[0], S.token.value[1])
+ : as(S.token.type, S.token.value);
+ return subscripts(prog1(atom, next), allow_calls);
+ }
+ unexpected();
+ };
+
+ function expr_list(closing, allow_trailing_comma) {
+ var first = true, a = [];
+ while (!is("punc", closing)) {
+ if (first) first = false; else expect(",");
+ if (allow_trailing_comma && is("punc", closing))
+ break;
+ a.push(expression(false));
+ }
+ next();
+ return a;
+ };
+
+ function array_() {
+ return as("array", expr_list("]", !strict_mode));
+ };
+
+ function object_() {
+ var first = true, a = [];
+ while (!is("punc", "}")) {
+ if (first) first = false; else expect(",");
+ if (!strict_mode && is("punc", "}"))
+ // allow trailing comma
+ break;
+ var type = S.token.type;
+ var name = as_property_name();
+ if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
+ a.push([ as_name(), function_(false), name ]);
+ } else {
+ expect(":");
+ a.push([ name, expression(false) ]);
+ }
+ }
+ next();
+ return as("object", a);
+ };
+
+ function as_property_name() {
+ switch (S.token.type) {
+ case "num":
+ case "string":
+ return prog1(S.token.value, next);
+ }
+ return as_name();
+ };
+
+ function as_name() {
+ switch (S.token.type) {
+ case "name":
+ case "operator":
+ case "keyword":
+ case "atom":
+ return prog1(S.token.value, next);
+ default:
+ unexpected();
+ }
+ };
+
+ function subscripts(expr, allow_calls) {
+ if (is("punc", ".")) {
+ next();
+ return subscripts(as("dot", expr, as_name()), allow_calls);
+ }
+ if (is("punc", "[")) {
+ next();
+ return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
+ }
+ if (allow_calls && is("punc", "(")) {
+ next();
+ return subscripts(as("call", expr, expr_list(")")), true);
+ }
+ if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
+ return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
+ next);
+ }
+ return expr;
+ };
+
+ function make_unary(tag, op, expr) {
+ if ((op == "++" || op == "--") && !is_assignable(expr))
+ croak("Invalid use of " + op + " operator");
+ return as(tag, op, expr);
+ };
+
+ function expr_op(left, min_prec) {
+ var op = is("operator") ? S.token.value : null;
+ var prec = op != null ? PRECEDENCE[op] : null;
+ if (prec != null && prec > min_prec) {
+ next();
+ var right = expr_op(expr_atom(true), prec);
+ return expr_op(as("binary", op, left, right), min_prec);
+ }
+ return left;
+ };
+
+ function expr_ops() {
+ return expr_op(expr_atom(true), 0);
+ };
+
+ function maybe_conditional() {
+ var expr = expr_ops();
+ if (is("operator", "?")) {
+ next();
+ var yes = expression(false);
+ expect(":");
+ return as("conditional", expr, yes, expression(false));
+ }
+ return expr;
+ };
+
+ function is_assignable(expr) {
+ switch (expr[0]) {
+ case "dot":
+ case "sub":
+ return true;
+ case "name":
+ return expr[1] != "this";
+ }
+ };
+
+ function maybe_assign() {
+ var left = maybe_conditional(), val = S.token.value;
+ if (is("operator") && HOP(ASSIGNMENT, val)) {
+ if (is_assignable(left)) {
+ next();
+ return as("assign", ASSIGNMENT[val], left, maybe_assign());
+ }
+ croak("Invalid assignment");
+ }
+ return left;
+ };
+
+ function expression(commas) {
+ if (arguments.length == 0)
+ commas = true;
+ var expr = maybe_assign();
+ if (commas && is("punc", ",")) {
+ next();
+ return as("seq", expr, expression());
+ }
+ return expr;
+ };
+
+ function in_loop(cont) {
+ try {
+ ++S.in_loop;
+ return cont();
+ } finally {
+ --S.in_loop;
+ }
+ };
+
+ return as("toplevel", (function(a){
+ while (!is("eof"))
+ a.push(statement());
+ return a;
+ })([]));
+
+};
+
+/* -----[ Utilities ]----- */
+
+function curry(f) {
+ var args = slice(arguments, 1);
+ return function() { return f.apply(this, args.concat(slice(arguments))); };
+};
+
+function prog1(ret) {
+ if (ret instanceof Function)
+ ret = ret();
+ for (var i = 1, n = arguments.length; --n > 0; ++i)
+ arguments[i]();
+ return ret;
+};
+
+function array_to_hash(a) {
+ var ret = {};
+ for (var i = 0; i < a.length; ++i)
+ ret[a[i]] = true;
+ return ret;
+};
+
+function slice(a, start) {
+ return Array.prototype.slice.call(a, start == null ? 0 : start);
+};
+
+function characters(str) {
+ return str.split("");
+};
+
+function member(name, array) {
+ for (var i = array.length; --i >= 0;)
+ if (array[i] === name)
+ return true;
+ return false;
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+/* -----[ Exports ]----- */
+
+exports.tokenizer = tokenizer;
+exports.parse = parse;
+exports.slice = slice;
+exports.curry = curry;
+exports.member = member;
+exports.array_to_hash = array_to_hash;
+exports.PRECEDENCE = PRECEDENCE;
+exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
+exports.RESERVED_WORDS = RESERVED_WORDS;
+exports.KEYWORDS = KEYWORDS;
+exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
+exports.OPERATORS = OPERATORS;
+exports.is_alphanumeric_char = is_alphanumeric_char;
diff --git a/Source/WebCore/inspector/front-end/UglifyJS/process.js b/Source/WebCore/inspector/front-end/UglifyJS/process.js
new file mode 100755
index 0000000..65dbc0e
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/UglifyJS/process.js
@@ -0,0 +1,1560 @@
+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file implements some AST processors. They work on data built
+ by parse-js.
+
+ Exported functions:
+
+ - ast_mangle(ast, include_toplevel) -- mangles the
+ variable/function names in the AST. Returns an AST. Pass true
+ as second argument to mangle toplevel names too.
+
+ - ast_squeeze(ast) -- employs various optimizations to make the
+ final generated code even smaller. Returns an AST.
+
+ - gen_code(ast, beautify) -- generates JS code from the AST. Pass
+ true (or an object, see the code for some options) as second
+ argument to get "pretty" (indented) code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+
+ 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “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 HOLDER 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 jsp = require("./parse-js"),
+ slice = jsp.slice,
+ member = jsp.member,
+ PRECEDENCE = jsp.PRECEDENCE,
+ OPERATORS = jsp.OPERATORS;
+
+/* -----[ helper for AST traversal ]----- */
+
+function ast_walker(ast) {
+ function _vardefs(defs) {
+ return MAP(defs, function(def){
+ var a = [ def[0] ];
+ if (def.length > 1)
+ a[1] = walk(def[1]);
+ return a;
+ });
+ };
+ var walkers = {
+ "string": function(str) {
+ return [ "string", str ];
+ },
+ "num": function(num) {
+ return [ "num", num ];
+ },
+ "name": function(name) {
+ return [ "name", name ];
+ },
+ "toplevel": function(statements) {
+ return [ "toplevel", MAP(statements, walk) ];
+ },
+ "block": function(statements) {
+ var out = [ "block" ];
+ if (statements != null)
+ out.push(MAP(statements, walk));
+ return out;
+ },
+ "var": function(defs) {
+ return [ "var", _vardefs(defs) ];
+ },
+ "const": function(defs) {
+ return [ "const", _vardefs(defs) ];
+ },
+ "try": function(t, c, f) {
+ return [
+ "try",
+ MAP(t, walk),
+ c != null ? [ c[0], MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "throw": function(expr) {
+ return [ "throw", walk(expr) ];
+ },
+ "new": function(ctor, args) {
+ return [ "new", walk(ctor), MAP(args, walk) ];
+ },
+ "switch": function(expr, body) {
+ return [ "switch", walk(expr), MAP(body, function(branch){
+ return [ branch[0] ? walk(branch[0]) : null,
+ MAP(branch[1], walk) ];
+ }) ];
+ },
+ "break": function(label) {
+ return [ "break", label ];
+ },
+ "continue": function(label) {
+ return [ "continue", label ];
+ },
+ "conditional": function(cond, t, e) {
+ return [ "conditional", walk(cond), walk(t), walk(e) ];
+ },
+ "assign": function(op, lvalue, rvalue) {
+ return [ "assign", op, walk(lvalue), walk(rvalue) ];
+ },
+ "dot": function(expr) {
+ return [ "dot", walk(expr) ].concat(slice(arguments, 1));
+ },
+ "call": function(expr, args) {
+ return [ "call", walk(expr), MAP(args, walk) ];
+ },
+ "function": function(name, args, body) {
+ return [ "function", name, args.slice(), MAP(body, walk) ];
+ },
+ "defun": function(name, args, body) {
+ return [ "defun", name, args.slice(), MAP(body, walk) ];
+ },
+ "if": function(conditional, t, e) {
+ return [ "if", walk(conditional), walk(t), walk(e) ];
+ },
+ "for": function(init, cond, step, block) {
+ return [ "for", walk(init), walk(cond), walk(step), walk(block) ];
+ },
+ "for-in": function(has_var, key, hash, block) {
+ return [ "for-in", has_var, key, walk(hash), walk(block) ];
+ },
+ "while": function(cond, block) {
+ return [ "while", walk(cond), walk(block) ];
+ },
+ "do": function(cond, block) {
+ return [ "do", walk(cond), walk(block) ];
+ },
+ "return": function(expr) {
+ return [ "return", walk(expr) ];
+ },
+ "binary": function(op, left, right) {
+ return [ "binary", op, walk(left), walk(right) ];
+ },
+ "unary-prefix": function(op, expr) {
+ return [ "unary-prefix", op, walk(expr) ];
+ },
+ "unary-postfix": function(op, expr) {
+ return [ "unary-postfix", op, walk(expr) ];
+ },
+ "sub": function(expr, subscript) {
+ return [ "sub", walk(expr), walk(subscript) ];
+ },
+ "object": function(props) {
+ return [ "object", MAP(props, function(p){
+ return p.length == 2
+ ? [ p[0], walk(p[1]) ]
+ : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
+ }) ];
+ },
+ "regexp": function(rx, mods) {
+ return [ "regexp", rx, mods ];
+ },
+ "array": function(elements) {
+ return [ "array", MAP(elements, walk) ];
+ },
+ "stat": function(stat) {
+ return [ "stat", walk(stat) ];
+ },
+ "seq": function() {
+ return [ "seq" ].concat(MAP(slice(arguments), walk));
+ },
+ "label": function(name, block) {
+ return [ "label", name, walk(block) ];
+ },
+ "with": function(expr, block) {
+ return [ "with", walk(expr), walk(block) ];
+ },
+ "atom": function(name) {
+ return [ "atom", name ];
+ }
+ };
+
+ var user = {};
+ var stack = [];
+ function walk(ast) {
+ if (ast == null)
+ return null;
+ try {
+ stack.push(ast);
+ var type = ast[0];
+ var gen = user[type];
+ if (gen) {
+ var ret = gen.apply(ast, ast.slice(1));
+ if (ret != null)
+ return ret;
+ }
+ gen = walkers[type];
+ return gen.apply(ast, ast.slice(1));
+ } finally {
+ stack.pop();
+ }
+ };
+
+ function with_walkers(walkers, cont){
+ var save = {}, i;
+ for (i in walkers) if (HOP(walkers, i)) {
+ save[i] = user[i];
+ user[i] = walkers[i];
+ }
+ var ret = cont();
+ for (i in save) if (HOP(save, i)) {
+ if (!save[i]) delete user[i];
+ else user[i] = save[i];
+ }
+ return ret;
+ };
+
+ return {
+ walk: walk,
+ with_walkers: with_walkers,
+ parent: function() {
+ return stack[stack.length - 2]; // last one is current node
+ },
+ stack: function() {
+ return stack;
+ }
+ };
+};
+
+/* -----[ Scope and mangling ]----- */
+
+function Scope(parent) {
+ this.names = {}; // names defined in this scope
+ this.mangled = {}; // mangled names (orig.name => mangled)
+ this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
+ this.cname = -1; // current mangled name
+ this.refs = {}; // names referenced from this scope
+ this.uses_with = false; // will become TRUE if eval() is detected in this or any subscopes
+ this.uses_eval = false; // will become TRUE if with() is detected in this or any subscopes
+ this.parent = parent; // parent scope
+ this.children = []; // sub-scopes
+ if (parent) {
+ this.level = parent.level + 1;
+ parent.children.push(this);
+ } else {
+ this.level = 0;
+ }
+};
+
+var base54 = (function(){
+ var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
+ return function(num) {
+ var ret = "";
+ do {
+ ret = DIGITS.charAt(num % 54) + ret;
+ num = Math.floor(num / 54);
+ } while (num > 0);
+ return ret;
+ };
+})();
+
+Scope.prototype = {
+ has: function(name) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.names, name))
+ return s;
+ },
+ has_mangled: function(mname) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.rev_mangled, mname))
+ return s;
+ },
+ toJSON: function() {
+ return {
+ names: this.names,
+ uses_eval: this.uses_eval,
+ uses_with: this.uses_with
+ };
+ },
+
+ next_mangled: function() {
+ // we must be careful that the new mangled name:
+ //
+ // 1. doesn't shadow a mangled name from a parent
+ // scope, unless we don't reference the original
+ // name from this scope OR from any sub-scopes!
+ // This will get slow.
+ //
+ // 2. doesn't shadow an original name from a parent
+ // scope, in the event that the name is not mangled
+ // in the parent scope and we reference that name
+ // here OR IN ANY SUBSCOPES!
+ //
+ // 3. doesn't shadow a name that is referenced but not
+ // defined (possibly global defined elsewhere).
+ for (;;) {
+ var m = base54(++this.cname), prior;
+
+ // case 1.
+ prior = this.has_mangled(m);
+ if (prior && this.refs[prior.rev_mangled[m]] === prior)
+ continue;
+
+ // case 2.
+ prior = this.has(m);
+ if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
+ continue;
+
+ // case 3.
+ if (HOP(this.refs, m) && this.refs[m] == null)
+ continue;
+
+ // I got "do" once. :-/
+ if (!is_identifier(m))
+ continue;
+
+ return m;
+ }
+ },
+ get_mangled: function(name, newMangle) {
+ if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
+ var s = this.has(name);
+ if (!s) return name; // not in visible scope, no mangle
+ if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
+ if (!newMangle) return name; // not found and no mangling requested
+
+ var m = s.next_mangled();
+ s.rev_mangled[m] = name;
+ return s.mangled[name] = m;
+ },
+ define: function(name) {
+ if (name != null)
+ return this.names[name] = name;
+ }
+};
+
+function ast_add_scope(ast) {
+
+ var current_scope = null;
+ var w = ast_walker(), walk = w.walk;
+ var having_eval = [];
+
+ function with_new_scope(cont) {
+ current_scope = new Scope(current_scope);
+ var ret = current_scope.body = cont();
+ ret.scope = current_scope;
+ current_scope = current_scope.parent;
+ return ret;
+ };
+
+ function define(name) {
+ return current_scope.define(name);
+ };
+
+ function reference(name) {
+ current_scope.refs[name] = true;
+ };
+
+ function _lambda(name, args, body) {
+ return [ this[0], define(name), args, with_new_scope(function(){
+ MAP(args, define);
+ return MAP(body, walk);
+ })];
+ };
+
+ return with_new_scope(function(){
+ // process AST
+ var ret = w.with_walkers({
+ "function": _lambda,
+ "defun": _lambda,
+ "with": function(expr, block) {
+ for (var s = current_scope; s; s = s.parent)
+ s.uses_with = true;
+ },
+ "var": function(defs) {
+ MAP(defs, function(d){ define(d[0]) });
+ },
+ "const": function(defs) {
+ MAP(defs, function(d){ define(d[0]) });
+ },
+ "try": function(t, c, f) {
+ if (c != null) return [
+ "try",
+ MAP(t, walk),
+ [ define(c[0]), MAP(c[1], walk) ],
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "name": function(name) {
+ if (name == "eval")
+ having_eval.push(current_scope);
+ reference(name);
+ },
+ "for-in": function(has_var, name) {
+ if (has_var) define(name);
+ else reference(name);
+ }
+ }, function(){
+ return walk(ast);
+ });
+
+ // the reason why we need an additional pass here is
+ // that names can be used prior to their definition.
+
+ // scopes where eval was detected and their parents
+ // are marked with uses_eval, unless they define the
+ // "eval" name.
+ MAP(having_eval, function(scope){
+ if (!scope.has("eval")) while (scope) {
+ scope.uses_eval = true;
+ scope = scope.parent;
+ }
+ });
+
+ // for referenced names it might be useful to know
+ // their origin scope. current_scope here is the
+ // toplevel one.
+ function fixrefs(scope, i) {
+ // do children first; order shouldn't matter
+ for (i = scope.children.length; --i >= 0;)
+ fixrefs(scope.children[i]);
+ for (i in scope.refs) if (HOP(scope.refs, i)) {
+ // find origin scope and propagate the reference to origin
+ for (var origin = scope.has(i), s = scope; s; s = s.parent) {
+ s.refs[i] = origin;
+ if (s === origin) break;
+ }
+ }
+ };
+ fixrefs(current_scope);
+
+ return ret;
+ });
+
+};
+
+/* -----[ mangle names ]----- */
+
+function ast_mangle(ast, do_toplevel) {
+ var w = ast_walker(), walk = w.walk, scope;
+
+ function get_mangled(name, newMangle) {
+ if (!do_toplevel && !scope.parent) return name; // don't mangle toplevel
+ return scope.get_mangled(name, newMangle);
+ };
+
+ function _lambda(name, args, body) {
+ if (name) name = get_mangled(name);
+ body = with_scope(body.scope, function(){
+ args = MAP(args, function(name){ return get_mangled(name) });
+ return MAP(body, walk);
+ });
+ return [ this[0], name, args, body ];
+ };
+
+ function with_scope(s, cont) {
+ var _scope = scope;
+ scope = s;
+ for (var i in s.names) if (HOP(s.names, i)) {
+ get_mangled(i, true);
+ }
+ var ret = cont();
+ ret.scope = s;
+ scope = _scope;
+ return ret;
+ };
+
+ function _vardefs(defs) {
+ return MAP(defs, function(d){
+ return [ get_mangled(d[0]), walk(d[1]) ];
+ });
+ };
+
+ return w.with_walkers({
+ "function": _lambda,
+ "defun": function() {
+ // move function declarations to the top when
+ // they are not in some block.
+ var ast = _lambda.apply(this, arguments);
+ switch (w.parent()[0]) {
+ case "toplevel":
+ case "function":
+ case "defun":
+ return MAP.at_top(ast);
+ }
+ return ast;
+ },
+ "var": function(defs) {
+ return [ "var", _vardefs(defs) ];
+ },
+ "const": function(defs) {
+ return [ "const", _vardefs(defs) ];
+ },
+ "name": function(name) {
+ return [ "name", get_mangled(name) ];
+ },
+ "try": function(t, c, f) {
+ return [ "try",
+ MAP(t, walk),
+ c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null ];
+ },
+ "toplevel": function(body) {
+ return with_scope(this.scope, function(){
+ return [ "toplevel", MAP(body, walk) ];
+ });
+ },
+ "for-in": function(has_var, name, obj, stat) {
+ return [ "for-in", has_var, get_mangled(name), walk(obj), walk(stat) ];
+ }
+ }, function() {
+ return walk(ast_add_scope(ast));
+ });
+};
+
+/* -----[
+ - compress foo["bar"] into foo.bar,
+ - remove block brackets {} where possible
+ - join consecutive var declarations
+ - various optimizations for IFs:
+ - if (cond) foo(); else bar(); ==> cond?foo():bar();
+ - if (cond) foo(); ==> cond&&foo();
+ - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
+ - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
+ ]----- */
+
+var warn = function(){};
+
+function best_of(ast1, ast2) {
+ return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
+};
+
+function last_stat(b) {
+ if (b[0] == "block" && b[1] && b[1].length > 0)
+ return b[1][b[1].length - 1];
+ return b;
+}
+
+function aborts(t) {
+ if (t) {
+ t = last_stat(t);
+ if (t[0] == "return" || t[0] == "break" || t[0] == "continue" || t[0] == "throw")
+ return true;
+ }
+};
+
+function negate(c) {
+ var not_c = [ "unary-prefix", "!", c ];
+ switch (c[0]) {
+ case "unary-prefix":
+ return c[1] == "!" ? c[2] : not_c;
+ case "binary":
+ var op = c[1], left = c[2], right = c[3];
+ switch (op) {
+ case "<=": return [ "binary", ">", left, right ];
+ case "<": return [ "binary", ">=", left, right ];
+ case ">=": return [ "binary", "<", left, right ];
+ case ">": return [ "binary", "<=", left, right ];
+ case "==": return [ "binary", "!=", left, right ];
+ case "!=": return [ "binary", "==", left, right ];
+ case "===": return [ "binary", "!==", left, right ];
+ case "!==": return [ "binary", "===", left, right ];
+ case "&&": return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
+ case "||": return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
+ }
+ break;
+ }
+ return not_c;
+};
+
+function make_conditional(c, t, e) {
+ if (c[0] == "unary-prefix" && c[1] == "!") {
+ return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
+ } else {
+ return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
+ }
+};
+
+function empty(b) {
+ return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
+};
+
+function ast_squeeze(ast, options) {
+ options = defaults(options, {
+ make_seqs : true,
+ dead_code : true,
+ no_warnings : false,
+ extra : false
+ });
+
+ var w = ast_walker(), walk = w.walk, scope;
+
+ function with_scope(s, cont) {
+ var _scope = scope;
+ scope = s;
+ var ret = cont();
+ ret.scope = s;
+ scope = _scope;
+ return ret;
+ };
+
+ function is_constant(node) {
+ return node[0] == "string" || node[0] == "num";
+ };
+
+ function find_first_execute(node) {
+ if (!node)
+ return false;
+
+ switch (node[0]) {
+ case "num":
+ case "string":
+ case "name":
+ return node;
+ case "call":
+ case "conditional":
+ case "for":
+ case "if":
+ case "new":
+ case "return":
+ case "stat":
+ case "switch":
+ case "throw":
+ return find_first_execute(node[1]);
+ case "binary":
+ return find_first_execute(node[2]);
+ case "assign":
+ if (node[1] === true)
+ return find_first_execute(node[3]);
+ break;
+ case "var":
+ if (node[1][0].length > 1)
+ return find_first_execute(node[1][0][1]);
+ break;
+ }
+ return null;
+ }
+
+ function find_assign_recursive(p, v) {
+ if (p[0] == "assign" && p[1] != true || p[0] == "unary-prefix") {
+ if (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1])
+ return true;
+ return false;
+ }
+
+ if (p[0] != "assign" || p[1] !== true)
+ return false;
+
+ if ((is_constant(p[3]) && p[3][0] == v[0] && p[3][1] == v[1]) ||
+ (p[3][0] == "name" && v[0] == "name" && p[3][1] == v[1]) ||
+ (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1]))
+ return true;
+
+ return find_assign_recursive(p[3], v);
+ };
+
+ function rmblock(block) {
+ if (block != null && block[0] == "block" && block[1] && block[1].length == 1)
+ block = block[1][0];
+ return block;
+ };
+
+ function clone(obj) {
+ if (obj && obj.constructor == Array)
+ return MAP(obj, clone);
+ return obj;
+ };
+
+ function make_seq_to_statements(node) {
+ if (node[0] != "seq") {
+ switch (node[0]) {
+ case "var":
+ case "const":
+ return [ node ];
+ default:
+ return [ [ "stat", node ] ];
+ }
+ }
+
+ var ret = [];
+ for (var i = 1; i < node.length; i++)
+ ret.push.apply(ret, make_seq_to_statements(node[i]));
+
+ return ret;
+ };
+
+ function _lambda(name, args, body) {
+ return [ this[0], name, args, with_scope(body.scope, function(){
+ return tighten(MAP(body, walk), "lambda");
+ }) ];
+ };
+
+ // we get here for blocks that have been already transformed.
+ // this function does a few things:
+ // 1. discard useless blocks
+ // 2. join consecutive var declarations
+ // 3. remove obviously dead code
+ // 4. transform consecutive statements using the comma operator
+ // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
+ function tighten(statements, block_type) {
+ statements = statements.reduce(function(a, stat){
+ if (stat[0] == "block") {
+ if (stat[1]) {
+ a.push.apply(a, stat[1]);
+ }
+ } else {
+ a.push(stat);
+ }
+ return a;
+ }, []);
+
+ if (options.extra) {
+ // Detightening things. We do this because then we can assume that the
+ // statements are structured in a specific way.
+ statements = (function(a, prev) {
+ statements.forEach(function(cur) {
+ switch (cur[0]) {
+ case "for":
+ if (cur[1] != null) {
+ a.push.apply(a, make_seq_to_statements(cur[1]));
+ cur[1] = null;
+ }
+ a.push(cur);
+ break;
+ case "stat":
+ var stats = make_seq_to_statements(cur[1]);
+ stats.forEach(function(s) {
+ if (s[1][0] == "unary-postfix")
+ s[1][0] = "unary-prefix";
+ });
+ a.push.apply(a, stats);
+ break;
+ default:
+ a.push(cur);
+ }
+ });
+ return a;
+ })([]);
+
+ statements = (function(a, prev) {
+ statements.forEach(function(cur) {
+ if (!(prev && prev[0] == "stat")) {
+ a.push(cur);
+ prev = cur;
+ return;
+ }
+
+ var p = prev[1];
+ var c = find_first_execute(cur);
+ if (c && find_assign_recursive(p, c)) {
+ var old_cur = clone(cur);
+ c.splice(0, c.length);
+ c.push.apply(c, p);
+ var tmp_cur = best_of(cur, [ "toplevel", [ prev, old_cur ] ]);
+ if (tmp_cur == cur) {
+ a[a.length -1] = cur;
+ } else {
+ cur = old_cur;
+ a.push(cur);
+ }
+ } else {
+ a.push(cur);
+ }
+ prev = cur;
+ });
+ return a;
+ })([]);
+ }
+
+ statements = (function(a, prev){
+ statements.forEach(function(cur){
+ if (prev && ((cur[0] == "var" && prev[0] == "var") ||
+ (cur[0] == "const" && prev[0] == "const"))) {
+ prev[1] = prev[1].concat(cur[1]);
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.dead_code) statements = (function(a, has_quit){
+ statements.forEach(function(st){
+ if (has_quit) {
+ if (member(st[0], [ "function", "defun" , "var", "const" ])) {
+ a.push(st);
+ }
+ else if (!options.no_warnings)
+ warn("Removing unreachable code: " + gen_code(st, true));
+ }
+ else {
+ a.push(st);
+ if (member(st[0], [ "return", "throw", "break", "continue" ]))
+ has_quit = true;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.make_seqs) statements = (function(a, prev) {
+ statements.forEach(function(cur){
+ if (prev && prev[0] == "stat" && cur[0] == "stat") {
+ prev[1] = [ "seq", prev[1], cur[1] ];
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.extra) {
+ statements = (function(a, prev){
+ statements.forEach(function(cur){
+ var replaced = false;
+ if (prev && cur[0] == "for" && cur[1] == null && (prev[0] == "var" || prev[0] == "const" || prev[0] == "stat")) {
+ cur[1] = prev;
+ a[a.length - 1] = cur;
+ } else {
+ a.push(cur);
+ }
+ prev = cur;
+ });
+ return a;
+ })([]);
+ }
+
+ if (block_type == "lambda") statements = (function(i, a, stat){
+ while (i < statements.length) {
+ stat = statements[i++];
+ if (stat[0] == "if" && !stat[3]) {
+ if (stat[2][0] == "return" && stat[2][1] == null) {
+ a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
+ break;
+ }
+ var last = last_stat(stat[2]);
+ if (last[0] == "return" && last[1] == null) {
+ a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
+ break;
+ }
+ }
+ a.push(stat);
+ }
+ return a;
+ })(0, []);
+
+ return statements;
+ };
+
+ function make_if(c, t, e) {
+ c = walk(c);
+ t = walk(t);
+ e = walk(e);
+
+ if (empty(t)) {
+ c = negate(c);
+ t = e;
+ e = null;
+ } else if (empty(e)) {
+ e = null;
+ } else {
+ // if we have both else and then, maybe it makes sense to switch them?
+ (function(){
+ var a = gen_code(c);
+ var n = negate(c);
+ var b = gen_code(n);
+ if (b.length < a.length) {
+ var tmp = t;
+ t = e;
+ e = tmp;
+ c = n;
+ }
+ })();
+ }
+ if (empty(e) && empty(t))
+ return [ "stat", c ];
+ var ret = [ "if", c, t, e ];
+ if (t[0] == "stat") {
+ if (e) {
+ if (e[0] == "stat") {
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
+ }
+ }
+ else {
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
+ }
+ }
+ else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw")) {
+ ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
+ }
+ else if (e && aborts(t)) {
+ ret = [ [ "if", c, t ] ];
+ if (e[0] == "block") {
+ if (e[1]) ret = ret.concat(e[1]);
+ }
+ else {
+ ret.push(e);
+ }
+ ret = walk([ "block", ret ]);
+ }
+ else if (t && aborts(e)) {
+ ret = [ [ "if", negate(c), e ] ];
+ if (t[0] == "block") {
+ if (t[1]) ret = ret.concat(t[1]);
+ } else {
+ ret.push(t);
+ }
+ ret = walk([ "block", ret ]);
+ }
+ return ret;
+ };
+
+ return w.with_walkers({
+ "sub": function(expr, subscript) {
+ if (subscript[0] == "string") {
+ var name = subscript[1];
+ if (is_identifier(name)) {
+ return [ "dot", walk(expr), name ];
+ }
+ }
+ },
+ "if": make_if,
+ "toplevel": function(body) {
+ return [ "toplevel", with_scope(this.scope, function(){
+ return tighten(MAP(body, walk));
+ }) ];
+ },
+ "switch": function(expr, body) {
+ var last = body.length - 1;
+ return [ "switch", walk(expr), MAP(body, function(branch, i){
+ var block = tighten(MAP(branch[1], walk));
+ if (i == last && block.length > 0) {
+ var node = block[block.length - 1];
+ if (node[0] == "break" && !node[1])
+ block.pop();
+ }
+ return [ branch[0] ? walk(branch[0]) : null, block ];
+ }) ];
+ },
+ "function": _lambda,
+ "defun": _lambda,
+ "block": function(body) {
+ if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]);
+ },
+ "binary": function(op, left, right) {
+ left = walk(left);
+ right = walk(right);
+ var best = [ "binary", op, left, right ];
+ if (is_constant(right)) {
+ if (is_constant(left)) {
+ var val = null;
+ switch (op) {
+ case "+": val = left[1] + right[1]; break;
+ case "*": val = left[1] * right[1]; break;
+ case "/": val = left[1] / right[1]; break;
+ case "-": val = left[1] - right[1]; break;
+ case "<<": val = left[1] << right[1]; break;
+ case ">>": val = left[1] >> right[1]; break;
+ case ">>>": val = left[1] >>> right[1]; break;
+ }
+ if (val != null) {
+ best = best_of(best, [ typeof val == "string" ? "string" : "num", val ]);
+ }
+ } else if (left[0] == "binary" && left[1] == "+" && left[3][0] == "string") {
+ best = best_of(best, [ "binary", "+", left[2], [ "string", left[3][1] + right[1] ] ]);
+ }
+ }
+ return best;
+ },
+ "conditional": function(c, t, e) {
+ return make_conditional(walk(c), walk(t), walk(e));
+ },
+ "try": function(t, c, f) {
+ return [
+ "try",
+ tighten(MAP(t, walk)),
+ c != null ? [ c[0], tighten(MAP(c[1], walk)) ] : null,
+ f != null ? tighten(MAP(f, walk)) : null
+ ];
+ },
+ "unary-prefix": function(op, cond) {
+ if (op == "!") {
+ cond = walk(cond);
+ if (cond[0] == "unary-prefix" && cond[1] == "!") {
+ var p = w.parent();
+ if (p[0] == "unary-prefix" && p[1] == "!")
+ return cond[2];
+ return [ "unary-prefix", "!", cond ];
+ }
+ return best_of(this, negate(cond));
+ }
+ },
+ "name": function(name) {
+ switch (name) {
+ case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
+ case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
+ }
+ },
+ "new": function(ctor, args) {
+ if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) {
+ if (args.length != 1) {
+ return [ "array", args ];
+ } else {
+ return [ "call", [ "name", "Array" ], args ];
+ }
+ }
+ },
+ "call": function(expr, args) {
+ if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
+ return [ "array", args ];
+ }
+ }
+ }, function() {
+ return walk(ast_add_scope(ast));
+ });
+};
+
+/* -----[ re-generate code from the AST ]----- */
+
+var DOT_CALL_NO_PARENS = jsp.array_to_hash([
+ "name",
+ "array",
+ "string",
+ "dot",
+ "sub",
+ "call",
+ "regexp"
+]);
+
+function make_string(str) {
+ var dq = 0, sq = 0;
+ str = str.replace(/[\\\b\f\n\r\t\x22\x27]/g, function(s){
+ switch (s) {
+ case "\\": return "\\\\";
+ case "\b": return "\\b";
+ case "\f": return "\\f";
+ case "\n": return "\\n";
+ case "\r": return "\\r";
+ case "\t": return "\\t";
+ case '"': ++dq; return '"';
+ case "'": ++sq; return "'";
+ }
+ return s;
+ });
+ if (dq > sq) {
+ return "'" + str.replace(/\x27/g, "\\'") + "'";
+ } else {
+ return '"' + str.replace(/\x22/g, '\\"') + '"';
+ }
+};
+
+function gen_code(ast, beautify) {
+ if (beautify) beautify = defaults(beautify, {
+ indent_start : 0,
+ indent_level : 4,
+ quote_keys : false,
+ space_colon : false
+ });
+ var indentation = 0,
+ newline = beautify ? "\n" : "",
+ space = beautify ? " " : "";
+
+ function indent(line) {
+ if (line == null)
+ line = "";
+ if (beautify)
+ line = repeat_string(" ", beautify.indent_start + indentation * beautify.indent_level) + line;
+ return line;
+ };
+
+ function with_indent(cont, incr) {
+ if (incr == null) incr = 1;
+ indentation += incr;
+ try { return cont.apply(null, slice(arguments, 1)); }
+ finally { indentation -= incr; }
+ };
+
+ function add_spaces(a) {
+ if (beautify)
+ return a.join(" ");
+ var b = [];
+ for (var i = 0; i < a.length; ++i) {
+ var next = a[i + 1];
+ b.push(a[i]);
+ if (next &&
+ ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
+ (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
+ b.push(" ");
+ }
+ }
+ return b.join("");
+ };
+
+ function add_commas(a) {
+ return a.join("," + space);
+ };
+
+ function parenthesize(expr) {
+ var gen = make(expr);
+ for (var i = 1; i < arguments.length; ++i) {
+ var el = arguments[i];
+ if ((el instanceof Function && el(expr)) || expr[0] == el)
+ return "(" + gen + ")";
+ }
+ return gen;
+ };
+
+ function best_of(a) {
+ if (a.length == 1) {
+ return a[0];
+ }
+ if (a.length == 2) {
+ var b = a[1];
+ a = a[0];
+ return a.length <= b.length ? a : b;
+ }
+ return best_of([ a[0], best_of(a.slice(1)) ]);
+ };
+
+ function needs_parens(expr) {
+ if (expr[0] == "function") {
+ // dot/call on a literal function requires the
+ // function literal itself to be parenthesized
+ // only if it's the first "thing" in a
+ // statement. This means that the parent is
+ // "stat", but it could also be a "seq" and
+ // we're the first in this "seq" and the
+ // parent is "stat", and so on. Messy stuff,
+ // but it worths the trouble.
+ var a = slice($stack), self = a.pop(), p = a.pop();
+ while (p) {
+ if (p[0] == "stat") return true;
+ if ((p[0] == "seq" && p[1] === self) ||
+ (p[0] == "call" && p[1] === self) ||
+ (p[0] == "binary" && p[2] === self)) {
+ self = p;
+ p = a.pop();
+ } else {
+ return false;
+ }
+ }
+ }
+ return !HOP(DOT_CALL_NO_PARENS, expr[0]);
+ };
+
+ function make_num(num) {
+ var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
+ if (Math.floor(num) === num) {
+ a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
+ "0" + num.toString(8)); // same.
+ if ((m = /^(.*?)(0+)$/.exec(num))) {
+ a.push(m[1] + "e" + m[2].length);
+ }
+ } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
+ a.push(m[2] + "e-" + (m[1].length + m[2].length),
+ str.substr(str.indexOf(".")));
+ }
+ return best_of(a);
+ };
+
+ var generators = {
+ "string": make_string,
+ "num": make_num,
+ "name": make_name,
+ "toplevel": function(statements) {
+ return make_block_statements(statements)
+ .join(newline + newline);
+ },
+ "block": make_block,
+ "var": function(defs) {
+ return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "const": function(defs) {
+ return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "try": function(tr, ca, fi) {
+ var out = [ "try", make_block(tr) ];
+ if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
+ if (fi) out.push("finally", make_block(fi));
+ return add_spaces(out);
+ },
+ "throw": function(expr) {
+ return add_spaces([ "throw", make(expr) ]) + ";";
+ },
+ "new": function(ctor, args) {
+ args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
+ return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
+ var w = ast_walker(), has_call = {};
+ try {
+ w.with_walkers({
+ "call": function() { throw has_call },
+ "function": function() { return this }
+ }, function(){
+ w.walk(expr);
+ });
+ } catch(ex) {
+ if (ex === has_call)
+ return true;
+ throw ex;
+ }
+ }) + args ]);
+ },
+ "switch": function(expr, body) {
+ return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
+ },
+ "break": function(label) {
+ var out = "break";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "continue": function(label) {
+ var out = "continue";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "conditional": function(co, th, el) {
+ return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
+ parenthesize(th, "seq"), ":",
+ parenthesize(el, "seq") ]);
+ },
+ "assign": function(op, lvalue, rvalue) {
+ if (op && op !== true) op += "=";
+ else op = "=";
+ return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
+ },
+ "dot": function(expr) {
+ var out = make(expr), i = 1;
+ if (needs_parens(expr))
+ out = "(" + out + ")";
+ while (i < arguments.length)
+ out += "." + make_name(arguments[i++]);
+ return out;
+ },
+ "call": function(func, args) {
+ var f = make(func);
+ if (needs_parens(func))
+ f = "(" + f + ")";
+ return f + "(" + add_commas(MAP(args, function(expr){
+ return parenthesize(expr, "seq");
+ })) + ")";
+ },
+ "function": make_function,
+ "defun": make_function,
+ "if": function(co, th, el) {
+ var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
+ if (el) {
+ out.push("else", make(el));
+ }
+ return add_spaces(out);
+ },
+ "for": function(init, cond, step, block) {
+ var out = [ "for" ];
+ init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
+ cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
+ step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
+ var args = init + cond + step;
+ if (args == "; ; ") args = ";;";
+ out.push("(" + args + ")", make(block));
+ return add_spaces(out);
+ },
+ "for-in": function(has_var, key, hash, block) {
+ var out = add_spaces([ "for", "(" ]);
+ if (has_var)
+ out += "var ";
+ out += add_spaces([ make_name(key) + " in " + make(hash) + ")", make(block) ]);
+ return out;
+ },
+ "while": function(condition, block) {
+ return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
+ },
+ "do": function(condition, block) {
+ return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
+ },
+ "return": function(expr) {
+ var out = [ "return" ];
+ if (expr != null) out.push(make(expr));
+ return add_spaces(out) + ";";
+ },
+ "binary": function(operator, lvalue, rvalue) {
+ var left = make(lvalue), right = make(rvalue);
+ // XXX: I'm pretty sure other cases will bite here.
+ // we need to be smarter.
+ // adding parens all the time is the safest bet.
+ if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
+ lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
+ left = "(" + left + ")";
+ }
+ if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
+ rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]]) {
+ right = "(" + right + ")";
+ }
+ return add_spaces([ left, operator, right ]);
+ },
+ "unary-prefix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
+ },
+ "unary-postfix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return val + operator;
+ },
+ "sub": function(expr, subscript) {
+ var hash = make(expr);
+ if (needs_parens(expr))
+ hash = "(" + hash + ")";
+ return hash + "[" + make(subscript) + "]";
+ },
+ "object": function(props) {
+ if (props.length == 0)
+ return "{}";
+ return "{" + newline + with_indent(function(){
+ return MAP(props, function(p){
+ if (p.length == 3) {
+ // getter/setter. The name is in p[0], the arg.list in p[1][2], the
+ // body in p[1][3] and type ("get" / "set") in p[2].
+ return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
+ }
+ var key = p[0], val = make(p[1]);
+ if (beautify && beautify.quote_keys) {
+ key = make_string(key);
+ } else if (typeof key == "number" || !beautify && +key + "" == key) {
+ key = make_num(+key);
+ } else if (!is_identifier(key)) {
+ key = make_string(key);
+ }
+ return indent(add_spaces(beautify && beautify.space_colon
+ ? [ key, ":", val ]
+ : [ key + ":", val ]));
+ }).join("," + newline);
+ }) + newline + indent("}");
+ },
+ "regexp": function(rx, mods) {
+ return "/" + rx + "/" + mods;
+ },
+ "array": function(elements) {
+ if (elements.length == 0) return "[]";
+ return add_spaces([ "[", add_commas(MAP(elements, function(el){
+ return parenthesize(el, "seq");
+ })), "]" ]);
+ },
+ "stat": function(stmt) {
+ return make(stmt).replace(/;*\s*$/, ";");
+ },
+ "seq": function() {
+ return add_commas(MAP(slice(arguments), make));
+ },
+ "label": function(name, block) {
+ return add_spaces([ make_name(name), ":", make(block) ]);
+ },
+ "with": function(expr, block) {
+ return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
+ },
+ "atom": function(name) {
+ return make_name(name);
+ },
+ "comment1": function(text) {
+ return "//" + text + "\n";
+ },
+ "comment2": function(text) {
+ return "/*" + text + "*/";
+ }
+ };
+
+ // The squeezer replaces "block"-s that contain only a single
+ // statement with the statement itself; technically, the AST
+ // is correct, but this can create problems when we output an
+ // IF having an ELSE clause where the THEN clause ends in an
+ // IF *without* an ELSE block (then the outer ELSE would refer
+ // to the inner IF). This function checks for this case and
+ // adds the block brackets if needed.
+ function make_then(th) {
+ if (th[0] == "do") {
+ // https://github.com/mishoo/UglifyJS/issues/#issue/57
+ // IE croaks with "syntax error" on code like this:
+ // if (foo) do ... while(cond); else ...
+ // we need block brackets around do/while
+ return make([ "block", [ th ]]);
+ }
+ var b = th;
+ while (true) {
+ var type = b[0];
+ if (type == "if") {
+ if (!b[3])
+ // no else, we must add the block
+ return make([ "block", [ th ]]);
+ b = b[3];
+ }
+ else if (type == "while" || type == "do") b = b[2];
+ else if (type == "for" || type == "for-in") b = b[4];
+ else break;
+ }
+ return make(th);
+ };
+
+ function make_function(name, args, body, keyword) {
+ var out = keyword || "function";
+ if (name) {
+ out += " " + make_name(name);
+ }
+ out += "(" + add_commas(MAP(args, make_name)) + ")";
+ return add_spaces([ out, make_block(body) ]);
+ };
+
+ function make_name(name) {
+ return name.toString();
+ };
+
+ function make_block_statements(statements) {
+ for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
+ var stat = statements[i];
+ var code = make(stat);
+ if (code != ";") {
+ if (!beautify && i == last)
+ code = code.replace(/;+\s*$/, "");
+ a.push(code);
+ }
+ }
+ return MAP(a, indent);
+ };
+
+ function make_switch_block(body) {
+ var n = body.length;
+ if (n == 0) return "{}";
+ return "{" + newline + MAP(body, function(branch, i){
+ var has_body = branch[1].length > 0, code = with_indent(function(){
+ return indent(branch[0]
+ ? add_spaces([ "case", make(branch[0]) + ":" ])
+ : "default:");
+ }, 0.5) + (has_body ? newline + with_indent(function(){
+ return make_block_statements(branch[1]).join(newline);
+ }) : "");
+ if (!beautify && has_body && i < n - 1)
+ code += ";";
+ return code;
+ }).join(newline) + newline + indent("}");
+ };
+
+ function make_block(statements) {
+ if (!statements) return ";";
+ if (statements.length == 0) return "{}";
+ return "{" + newline + with_indent(function(){
+ return make_block_statements(statements).join(newline);
+ }) + newline + indent("}");
+ };
+
+ function make_1vardef(def) {
+ var name = def[0], val = def[1];
+ if (val != null)
+ name = add_spaces([ name, "=", make(val) ]);
+ return name;
+ };
+
+ var $stack = [];
+
+ function make(node) {
+ var type = node[0];
+ var gen = generators[type];
+ if (!gen)
+ throw new Error("Can't find generator for \"" + type + "\"");
+ $stack.push(node);
+ var ret = gen.apply(type, node.slice(1));
+ $stack.pop();
+ return ret;
+ };
+
+ return make(ast);
+};
+
+/* -----[ Utilities ]----- */
+
+function repeat_string(str, i) {
+ if (i <= 0) return "";
+ if (i == 1) return str;
+ var d = repeat_string(str, i >> 1);
+ d += d;
+ if (i & 1) d += str;
+ return d;
+};
+
+function defaults(args, defs) {
+ var ret = {};
+ if (args === true)
+ args = {};
+ for (var i in defs) if (HOP(defs, i)) {
+ ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
+ }
+ return ret;
+};
+
+function is_identifier(name) {
+ return /^[a-z_$][a-z0-9_$]*$/i.test(name)
+ && name != "this"
+ && !HOP(jsp.KEYWORDS_ATOM, name)
+ && !HOP(jsp.RESERVED_WORDS, name)
+ && !HOP(jsp.KEYWORDS, name);
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+// some utilities
+
+var MAP;
+
+(function(){
+ MAP = function(a, f, o) {
+ var ret = [];
+ for (var i = 0; i < a.length; ++i) {
+ var val = f.call(o, a[i], i);
+ if (val instanceof AtTop) ret.unshift(val.v);
+ else ret.push(val);
+ }
+ return ret;
+ };
+ MAP.at_top = function(val) { return new AtTop(val) };
+ function AtTop(val) { this.v = val };
+})();
+
+/* -----[ Exports ]----- */
+
+exports.ast_walker = ast_walker;
+exports.ast_mangle = ast_mangle;
+exports.ast_squeeze = ast_squeeze;
+exports.gen_code = gen_code;
+exports.ast_add_scope = ast_add_scope;
+exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
+exports.set_logger = function(logger) { warn = logger };
diff --git a/Source/WebCore/inspector/front-end/WebKit.qrc b/Source/WebCore/inspector/front-end/WebKit.qrc
index 80a6533..edc1861 100644
--- a/Source/WebCore/inspector/front-end/WebKit.qrc
+++ b/Source/WebCore/inspector/front-end/WebKit.qrc
@@ -23,6 +23,7 @@
<file>CookieParser.js</file>
<file>CookiesTable.js</file>
<file>CSSCompletions.js</file>
+ <file>CSSKeywordCompletions.js</file>
<file>CSSStyleModel.js</file>
<file>Database.js</file>
<file>DatabaseQueryView.js</file>
@@ -51,7 +52,6 @@
<file>HelpScreen.js</file>
<file>ImageView.js</file>
<file>InjectedFakeWorker.js</file>
- <file>InjectedScriptAccess.js</file>
<file>inspector.js</file>
<file>InspectorFrontendHostStub.js</file>
<file>KeyboardShortcut.js</file>
@@ -81,6 +81,8 @@
<file>ResourcesPanel.js</file>
<file>ScopeChainSidebarPane.js</file>
<file>Script.js</file>
+ <file>ScriptFormatter.js</file>
+ <file>ScriptFormatterWorker.js</file>
<file>ScriptsPanel.js</file>
<file>ScriptView.js</file>
<file>Section.js</file>
@@ -114,6 +116,8 @@
<file>WatchExpressionsSidebarPane.js</file>
<file>WelcomeView.js</file>
<file>WorkersSidebarPane.js</file>
+ <file>UglifyJS/parse-js.js</file>
+ <file>UglifyJS/process.js</file>
<file>audits.css</file>
<file>goToLineDialog.css</file>
<file>heapProfiler.css</file>
diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css
index c908427..f629d12 100644
--- a/Source/WebCore/inspector/front-end/inspector.css
+++ b/Source/WebCore/inspector/front-end/inspector.css
@@ -778,8 +778,8 @@ body.platform-linux .monospace, body.platform-linux .source-code {
color: red;
}
-.auto-complete-text {
- color: rgb(128, 128, 128);
+.auto-complete-text, .editing .auto-complete-text {
+ color: rgb(128, 128, 128) !important;
-webkit-user-select: none;
-webkit-user-modify: read-only;
}
diff --git a/Source/WebCore/inspector/front-end/inspector.html b/Source/WebCore/inspector/front-end/inspector.html
index 44f096f..0e0b9e9 100644
--- a/Source/WebCore/inspector/front-end/inspector.html
+++ b/Source/WebCore/inspector/front-end/inspector.html
@@ -92,6 +92,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="EventListenersSidebarPane.js"></script>
<script type="text/javascript" src="Color.js"></script>
<script type="text/javascript" src="CSSCompletions.js"></script>
+ <script type="text/javascript" src="CSSKeywordCompletions.js"></script>
<script type="text/javascript" src="StylesSidebarPane.js"></script>
<script type="text/javascript" src="PanelEnablerView.js"></script>
<script type="text/javascript" src="WelcomeView.js"></script>
@@ -121,6 +122,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="NetworkItemView.js"></script>
<script type="text/javascript" src="ResourceView.js"></script>
<script type="text/javascript" src="SourceFrame.js"></script>
+ <script type="text/javascript" src="ScriptFormatter.js"></script>
<script type="text/javascript" src="DOMSyntaxHighlighter.js"></script>
<script type="text/javascript" src="TextEditorModel.js"></script>
<script type="text/javascript" src="TextEditorHighlighter.js"></script>
@@ -142,7 +144,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="HeapSnapshotView.js"></script>
<script type="text/javascript" src="DebuggerModel.js"></script>
<script type="text/javascript" src="DOMAgent.js"></script>
- <script type="text/javascript" src="InjectedScriptAccess.js"></script>
<script type="text/javascript" src="TimelineAgent.js"></script>
<script type="text/javascript" src="TimelinePanel.js"></script>
<script type="text/javascript" src="TimelineOverviewPane.js"></script>
diff --git a/Source/WebCore/inspector/front-end/inspector.js b/Source/WebCore/inspector/front-end/inspector.js
index d8a93b1..77abe78 100644
--- a/Source/WebCore/inspector/front-end/inspector.js
+++ b/Source/WebCore/inspector/front-end/inspector.js
@@ -185,20 +185,9 @@ var WebInspector = {
}
},
- createJSBreakpointsSidebarPane: function()
- {
- var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints"));
- function breakpointAdded(event)
- {
- pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
- }
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpointAdded);
- return pane;
- },
-
createDOMBreakpointsSidebarPane: function()
{
- var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
+ var pane = new WebInspector.NativeBreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
function breakpointAdded(event)
{
pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
@@ -534,7 +523,7 @@ WebInspector.doLoadedDone = function()
scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"),
xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"),
fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"),
- websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color.
+ websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSockets"), "rgb(186,186,186)"), // FIXME: Decide the color.
other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
};
@@ -601,14 +590,6 @@ WebInspector.doLoadedDone = function()
this.extensionServer.initExtensions();
- function populateInspectorState(inspectorState)
- {
- WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled;
- if ("pauseOnExceptionsState" in inspectorState)
- WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState);
- }
- InspectorBackend.getInspectorState(populateInspectorState);
-
function onPopulateScriptObjects()
{
if (!WebInspector.currentPanel)
diff --git a/Source/WebCore/inspector/front-end/utilities.js b/Source/WebCore/inspector/front-end/utilities.js
index 4320ba8..5ed9a8c 100644
--- a/Source/WebCore/inspector/front-end/utilities.js
+++ b/Source/WebCore/inspector/front-end/utilities.js
@@ -745,6 +745,22 @@ Object.defineProperty(Array.prototype, "keySet", { value: function()
return keys;
}});
+Object.defineProperty(Array.prototype, "upperBound", { value: function(value)
+{
+ var first = 0;
+ var count = this.length;
+ while (count > 0) {
+ var step = count >> 1;
+ var middle = first + step;
+ if (value >= this[middle]) {
+ first = middle + 1;
+ count -= step + 1;
+ } else
+ count = step;
+ }
+ return first;
+}});
+
Array.diff = function(left, right)
{
var o = left;