Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (155133 => 155134)
--- trunk/Source/WebInspectorUI/ChangeLog 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/ChangeLog 2013-09-05 18:01:00 UTC (rev 155134)
@@ -5,6 +5,55 @@
Reviewed by Timothy Hatcher.
+ Give the CodeMirror editor for _javascript_ Breakpoint Actions JS Runtime
+ completions (like window, document, etc.).
+
+ The logic was inside of _javascript_LogViewController but was already
+ entirely independent. Factor it out into its own class and plug it into
+ CodeMirrorCompletionController as a "CompletionsProvider".
+
+ Because the class hooks into a global event to reset some state, make
+ it a singleton, so new instances are not leaked.
+
+ * UserInterface/Main.html:
+ * UserInterface/Main.js:
+ (WebInspector.loaded):
+ * UserInterface/RuntimeManager.js: Added.
+ (WebInspector.RuntimeManager):
+ (WebInspector.RuntimeManager.prototype.evalCallback):
+ (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow):
+ Move eval in window to new RuntimeManager. A slightly cleaner place to this
+ since it is used both by the console and JS completions provider.
+
+ * UserInterface/CodeMirrorCompletionController.js:
+ (WebInspector.CodeMirrorCompletionController):
+ (WebInspector.CodeMirrorCompletionController.prototype.setExtendedCompletionProvider):
+ (WebInspector.CodeMirrorCompletionController.prototype._completeAtCurrentPosition):
+ Allow a completions provider plugin to completions controller. If one
+ is available, this supercedes the delegate extend completions path.
+
+ * UserInterface/BreakpointActionView.js:
+ * UserInterface/ConsolePrompt.js:
+ (WebInspector.ConsolePrompt):
+ Use the new JS completions provider to get runtime JS completions.
+ NOTE: ConsolePrompt still needs the delegate path for SQL completions.
+
+ * UserInterface/_javascript_LogViewController.js:
+ (WebInspector._javascript_LogViewController):
+ (WebInspector._javascript_LogViewController.prototype.consolePromptTextCommitted):
+ * UserInterface/_javascript_RuntimeCompletionProvider.js: Added.
+ (WebInspector._javascript_RuntimeCompletionProvider):
+ (get WebInspector._javascript_RuntimeCompletionProvider.prototype.):
+ (get WebInspector._javascript_RuntimeCompletionProvider.prototype.completionControllerCompletionsNeeded):
+ Move the JS completions code to a new class. No changes needed.
+
+2013-09-05 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Breakpoint Actions
+ https://bugs.webkit.org/show_bug.cgi?id=120576
+
+ Reviewed by Timothy Hatcher.
+
* UserInterface/Breakpoint.js:
(WebInspector.Breakpoint):
(WebInspector.Breakpoint.prototype.get actions):
Modified: trunk/Source/WebInspectorUI/UserInterface/BreakpointActionView.js (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/BreakpointActionView.js 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/BreakpointActionView.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -157,6 +157,7 @@
this._codeMirror.on("blur", this._codeMirrorBlurred.bind(this));
var completionController = new WebInspector.CodeMirrorCompletionController(this._codeMirror);
+ completionController.addExtendedCompletionProvider("_javascript_", WebInspector._javascript_RuntimeCompletionProvider);
// CodeMirror needs a refresh after the popover displays, to layout, otherwise it doesn't appear.
setTimeout(function() {
Modified: trunk/Source/WebInspectorUI/UserInterface/CodeMirrorCompletionController.js (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/CodeMirrorCompletionController.js 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/CodeMirrorCompletionController.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -38,6 +38,7 @@
this._lineNumber = NaN;
this._prefix = "";
this._completions = [];
+ this._extendedCompletionProviders = {};
this._suggestionsView = new WebInspector.CompletionSuggestionsView(this);
@@ -88,6 +89,11 @@
return this._delegate;
},
+ addExtendedCompletionProvider: function(modeName, provider)
+ {
+ this._extendedCompletionProviders[modeName] = provider;
+ },
+
updateCompletions: function(completions, implicitSuffix)
{
if (isNaN(this._startOffset) || isNaN(this._endOffset) || isNaN(this._lineNumber))
@@ -498,6 +504,12 @@
break;
}
+ var extendedCompletionsProvider = this._extendedCompletionProviders[modeName];
+ if (extendedCompletionsProvider) {
+ extendedCompletionsProvider.completionControllerCompletionsNeeded(this, defaultCompletions, baseScanResult ? baseScanResult.string : null, this._prefix, suffix, force);
+ return;
+ }
+
if (this._delegate && typeof this._delegate.completionControllerCompletionsNeeded === "function")
this._delegate.completionControllerCompletionsNeeded(this, this._prefix, defaultCompletions, baseScanResult ? baseScanResult.string : null, suffix, force);
else
Modified: trunk/Source/WebInspectorUI/UserInterface/ConsolePrompt.js (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/ConsolePrompt.js 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/ConsolePrompt.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -53,6 +53,7 @@
this._codeMirror.addKeyMap(keyMap);
this._completionController = new WebInspector.CodeMirrorCompletionController(this._codeMirror, this);
+ this._completionController.addExtendedCompletionProvider("_javascript_", WebInspector._javascript_RuntimeCompletionProvider);
this._history = [{}];
this._historyIndex = 0;
Modified: trunk/Source/WebInspectorUI/UserInterface/_javascript_LogViewController.js (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/_javascript_LogViewController.js 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/_javascript_LogViewController.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -59,8 +59,6 @@
this._promptFindNextKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Command, "G", this._handleFindNextShortcut.bind(this), this._prompt.element);
this._promptFindPreviousKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Command | WebInspector.KeyboardShortcut.Modifier.Shift, "G", this._handleFindPreviousShortcut.bind(this), this._prompt.element);
- WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._clearLastProperties, this);
-
this.startNewSession();
};
@@ -234,234 +232,11 @@
text += "\n//# sourceURL=__WebInspectorConsole__\n";
- this._evaluateInInspectedWindow(text, "console", true, false, false, printResult.bind(this));
+ WebInspector.runtimeManager.evaluateInInspectedWindow(text, "console", true, false, false, printResult.bind(this));
},
- consolePromptCompletionsNeeded: function(prompt, defaultCompletions, base, prefix, suffix, forced)
- {
- // Don't allow non-forced empty prefix completions unless the base is that start of property access.
- if (!forced && !prefix && !/[.[]$/.test(base)) {
- prompt.updateCompletions(null);
- return;
- }
-
- // If the base ends with an open parentheses or open curly bracket then treat it like there is
- // no base so we get global object completions.
- if (/[({]$/.test(base))
- base = "";
-
- var lastBaseIndex = base.length - 1;
- var dotNotation = base[lastBaseIndex] === ".";
- var bracketNotation = base[lastBaseIndex] === "[";
-
- if (dotNotation || bracketNotation) {
- base = base.substring(0, lastBaseIndex);
-
- // Don't suggest anything for an empty base that is using dot notation.
- // Bracket notation with an empty base will be treated as an array.
- if (!base && dotNotation) {
- prompt.updateCompletions(defaultCompletions);
- return;
- }
-
- // Don't allow non-forced empty prefix completions if the user is entering a number, since it might be a float.
- // But allow number completions if the base already has a decimal, so "10.0." will suggest Number properties.
- if (!forced && !prefix && dotNotation && base.indexOf(".") === -1 && parseInt(base, 10) == base) {
- prompt.updateCompletions(null);
- return;
- }
-
- // An empty base with bracket notation is not property access, it is an array.
- // Clear the bracketNotation flag so completions are not quoted.
- if (!base && bracketNotation)
- bracketNotation = false;
- }
-
- // If the base is the same as the last time, we can reuse the property names we have already gathered.
- // Doing this eliminates delay caused by the async nature of the code below and it only calls getters
- // and functions once instead of repetitively. Sure, there can be difference each time the base is evaluated,
- // but this optimization gives us more of a win. We clear the cache after 30 seconds or when stepping in the
- // debugger to make sure we don't use stale properties in most cases.
- if (this._lastBase === base && this._lastPropertyNames) {
- receivedPropertyNames.call(this, this._lastPropertyNames);
- return;
- }
-
- this._lastBase = base;
- this._lastPropertyNames = null;
-
- var activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
- if (!base && activeCallFrame)
- activeCallFrame.collectScopeChainVariableNames(receivedPropertyNames.bind(this));
- else
- this._evaluateInInspectedWindow(base, "completion", true, true, false, evaluated.bind(this));
-
- function updateLastPropertyNames(propertyNames)
- {
- if (this._clearLastPropertiesTimeout)
- clearTimeout(this._clearLastPropertiesTimeout);
- this._clearLastPropertiesTimeout = setTimeout(this._clearLastProperties.bind(this), WebInspector._javascript_LogViewController.CachedPropertiesDuration);
-
- this._lastPropertyNames = propertyNames || {};
- }
-
- function evaluated(result, wasThrown)
- {
- if (wasThrown || !result || result.type === "undefined" || (result.type === "object" && result.subtype === "null")) {
- RuntimeAgent.releaseObjectGroup("completion");
-
- updateLastPropertyNames.call(this, {});
- prompt.updateCompletions(defaultCompletions);
-
- return;
- }
-
- function getCompletions(primitiveType)
- {
- var object;
- if (primitiveType === "string")
- object = new String("");
- else if (primitiveType === "number")
- object = new Number(0);
- else if (primitiveType === "boolean")
- object = new Boolean(false);
- else
- object = this;
-
- var resultSet = {};
- for (var o = object; o; o = o.__proto__) {
- try {
- var names = Object.getOwnPropertyNames(o);
- for (var i = 0; i < names.length; ++i)
- resultSet[names[i]] = true;
- } catch (e) {
- // Ignore
- }
- }
-
- return resultSet;
- }
-
- if (result.type === "object" || result.type === "function")
- result.callFunctionJSON(getCompletions, undefined, receivedPropertyNames.bind(this));
- else if (result.type === "string" || result.type === "number" || result.type === "boolean")
- this._evaluateInInspectedWindow("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, receivedPropertyNamesFromEvaluate.bind(this));
- else
- console.error("Unknown result type: " + result.type);
- }
-
- function receivedPropertyNamesFromEvaluate(object, wasThrown, result)
- {
- receivedPropertyNames.call(this, result && !wasThrown ? result.value : null);
- }
-
- function receivedPropertyNames(propertyNames)
- {
- propertyNames = propertyNames || {};
-
- updateLastPropertyNames.call(this, propertyNames);
-
- RuntimeAgent.releaseObjectGroup("completion");
-
- if (!base) {
- const commandLineAPI = ["$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear", "getEventListeners", "$0", "$1", "$2", "$3", "$4", "$_"];
- for (var i = 0; i < commandLineAPI.length; ++i)
- propertyNames[commandLineAPI[i]] = true;
- }
-
- propertyNames = Object.keys(propertyNames);
-
- var implicitSuffix = "";
- if (bracketNotation) {
- var quoteUsed = prefix[0] === "'" ? "'" : "\"";
- if (suffix !== "]" && suffix !== quoteUsed)
- implicitSuffix = "]";
- }
-
- var completions = defaultCompletions;
- var knownCompletions = completions.keySet();
-
- for (var i = 0; i < propertyNames.length; ++i) {
- var property = propertyNames[i];
-
- if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
- continue;
-
- if (bracketNotation) {
- if (parseInt(property) != property)
- property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + (suffix !== quoteUsed ? quoteUsed : "");
- }
-
- if (!property.startsWith(prefix) || property in knownCompletions)
- continue;
-
- completions.push(property);
- knownCompletions[property] = true;
- }
-
- function compare(a, b)
- {
- // Try to sort in numerical order first.
- var numericCompareResult = a - b;
- if (!isNaN(numericCompareResult))
- return numericCompareResult;
-
- // Not numbers, sort as strings.
- return a.localeCompare(b);
- }
-
- completions.sort(compare);
-
- prompt.updateCompletions(completions, implicitSuffix);
- }
- },
-
// Private
- _clearLastProperties: function()
- {
- if (this._clearLastPropertiesTimeout) {
- clearTimeout(this._clearLastPropertiesTimeout);
- delete this._clearLastPropertiesTimeout;
- }
-
- // Clear the cache of property names so any changes while stepping or sitting idle get picked up if the same
- // _expression_ is evaluated again.
- this._lastPropertyNames = null;
- },
-
- _evaluateInInspectedWindow: function(_expression_, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
- {
- if (!_expression_) {
- // There is no _expression_, so the completion should happen against global properties.
- _expression_ = "this";
- }
-
- function evalCallback(error, result, wasThrown)
- {
- if (error) {
- console.error(error);
- callback(null, false);
- return;
- }
-
- if (returnByValue)
- callback(null, wasThrown, wasThrown ? null : result);
- else
- callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
- }
-
- if (WebInspector.debuggerManager.activeCallFrame) {
- DebuggerAgent.evaluateOnCallFrame(WebInspector.debuggerManager.activeCallFrame.id, _expression_, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, evalCallback);
- return;
- }
-
- // COMPATIBILITY (iOS 6): Execution context identifiers (contextId) did not exist
- // in iOS 6. Fallback to including the frame identifier (frameId).
- var contextId = WebInspector.quickConsole.executionContextIdentifier;
- RuntimeAgent.evaluate.invoke({_expression_: _expression_, objectGroup: objectGroup, includeCommandLineAPI: includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole: doNotPauseOnExceptionsAndMuteConsole, contextId: contextId, frameId: contextId, returnByValue: returnByValue}, evalCallback);
- },
-
_handleClearShortcut: function()
{
this.clear();
Added: trunk/Source/WebInspectorUI/UserInterface/_javascript_RuntimeCompletionProvider.js (0 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/_javascript_RuntimeCompletionProvider.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/_javascript_RuntimeCompletionProvider.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector._javascript_RuntimeCompletionProvider = function()
+{
+ WebInspector.Object.call(this);
+
+ console.assert(!WebInspector._javascript_RuntimeCompletionProvider._instance);
+
+ WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._clearLastProperties, this);
+};
+
+Object.defineProperty(WebInspector, "_javascript_RuntimeCompletionProvider",
+{
+ get: function()
+ {
+ if (!WebInspector._javascript_RuntimeCompletionProvider._instance)
+ WebInspector._javascript_RuntimeCompletionProvider._instance = new WebInspector._javascript_RuntimeCompletionProvider;
+ return WebInspector._javascript_RuntimeCompletionProvider._instance;
+ }
+});
+
+WebInspector._javascript_RuntimeCompletionProvider.prototype = {
+ constructor: WebInspector._javascript_RuntimeCompletionProvider,
+
+ // Protected
+
+ completionControllerCompletionsNeeded: function(completionController, defaultCompletions, base, prefix, suffix, forced)
+ {
+ // Don't allow non-forced empty prefix completions unless the base is that start of property access.
+ if (!forced && !prefix && !/[.[]$/.test(base)) {
+ completionController.updateCompletions(null);
+ return;
+ }
+
+ // If the base ends with an open parentheses or open curly bracket then treat it like there is
+ // no base so we get global object completions.
+ if (/[({]$/.test(base))
+ base = "";
+
+ var lastBaseIndex = base.length - 1;
+ var dotNotation = base[lastBaseIndex] === ".";
+ var bracketNotation = base[lastBaseIndex] === "[";
+
+ if (dotNotation || bracketNotation) {
+ base = base.substring(0, lastBaseIndex);
+
+ // Don't suggest anything for an empty base that is using dot notation.
+ // Bracket notation with an empty base will be treated as an array.
+ if (!base && dotNotation) {
+ completionController.updateCompletions(defaultCompletions);
+ return;
+ }
+
+ // Don't allow non-forced empty prefix completions if the user is entering a number, since it might be a float.
+ // But allow number completions if the base already has a decimal, so "10.0." will suggest Number properties.
+ if (!forced && !prefix && dotNotation && base.indexOf(".") === -1 && parseInt(base, 10) == base) {
+ completionController.updateCompletions(null);
+ return;
+ }
+
+ // An empty base with bracket notation is not property access, it is an array.
+ // Clear the bracketNotation flag so completions are not quoted.
+ if (!base && bracketNotation)
+ bracketNotation = false;
+ }
+
+ // If the base is the same as the last time, we can reuse the property names we have already gathered.
+ // Doing this eliminates delay caused by the async nature of the code below and it only calls getters
+ // and functions once instead of repetitively. Sure, there can be difference each time the base is evaluated,
+ // but this optimization gives us more of a win. We clear the cache after 30 seconds or when stepping in the
+ // debugger to make sure we don't use stale properties in most cases.
+ if (this._lastBase === base && this._lastPropertyNames) {
+ receivedPropertyNames.call(this, this._lastPropertyNames);
+ return;
+ }
+
+ this._lastBase = base;
+ this._lastPropertyNames = null;
+
+ var activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
+ if (!base && activeCallFrame && !this._alwaysEvaluateInWindowContext)
+ activeCallFrame.collectScopeChainVariableNames(receivedPropertyNames.bind(this));
+ else
+ WebInspector.runtimeManager.evaluateInInspectedWindow(base, "completion", true, true, false, evaluated.bind(this));
+
+ function updateLastPropertyNames(propertyNames)
+ {
+ if (this._clearLastPropertiesTimeout)
+ clearTimeout(this._clearLastPropertiesTimeout);
+ this._clearLastPropertiesTimeout = setTimeout(this._clearLastProperties.bind(this), WebInspector._javascript_LogViewController.CachedPropertiesDuration);
+
+ this._lastPropertyNames = propertyNames || {};
+ }
+
+ function evaluated(result, wasThrown)
+ {
+ if (wasThrown || !result || result.type === "undefined" || (result.type === "object" && result.subtype === "null")) {
+ RuntimeAgent.releaseObjectGroup("completion");
+
+ updateLastPropertyNames.call(this, {});
+ completionController.updateCompletions(defaultCompletions);
+
+ return;
+ }
+
+ function getCompletions(primitiveType)
+ {
+ var object;
+ if (primitiveType === "string")
+ object = new String("");
+ else if (primitiveType === "number")
+ object = new Number(0);
+ else if (primitiveType === "boolean")
+ object = new Boolean(false);
+ else
+ object = this;
+
+ var resultSet = {};
+ for (var o = object; o; o = o.__proto__) {
+ try {
+ var names = Object.getOwnPropertyNames(o);
+ for (var i = 0; i < names.length; ++i)
+ resultSet[names[i]] = true;
+ } catch (e) {
+ // Ignore
+ }
+ }
+
+ return resultSet;
+ }
+
+ if (result.type === "object" || result.type === "function")
+ result.callFunctionJSON(getCompletions, undefined, receivedPropertyNames.bind(this));
+ else if (result.type === "string" || result.type === "number" || result.type === "boolean")
+ WebInspector.runtimeManager.evaluateInInspectedWindow("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, receivedPropertyNamesFromEvaluate.bind(this));
+ else
+ console.error("Unknown result type: " + result.type);
+ }
+
+ function receivedPropertyNamesFromEvaluate(object, wasThrown, result)
+ {
+ receivedPropertyNames.call(this, result && !wasThrown ? result.value : null);
+ }
+
+ function receivedPropertyNames(propertyNames)
+ {
+ propertyNames = propertyNames || {};
+
+ updateLastPropertyNames.call(this, propertyNames);
+
+ RuntimeAgent.releaseObjectGroup("completion");
+
+ if (!base) {
+ const commandLineAPI = ["$", "$$", "$x", "dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear", "getEventListeners", "$0", "$1", "$2", "$3", "$4", "$_"];
+ for (var i = 0; i < commandLineAPI.length; ++i)
+ propertyNames[commandLineAPI[i]] = true;
+ }
+
+ propertyNames = Object.keys(propertyNames);
+
+ var implicitSuffix = "";
+ if (bracketNotation) {
+ var quoteUsed = prefix[0] === "'" ? "'" : "\"";
+ if (suffix !== "]" && suffix !== quoteUsed)
+ implicitSuffix = "]";
+ }
+
+ var completions = defaultCompletions;
+ var knownCompletions = completions.keySet();
+
+ for (var i = 0; i < propertyNames.length; ++i) {
+ var property = propertyNames[i];
+
+ if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
+ continue;
+
+ if (bracketNotation) {
+ if (parseInt(property) != property)
+ property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + (suffix !== quoteUsed ? quoteUsed : "");
+ }
+
+ if (!property.startsWith(prefix) || property in knownCompletions)
+ continue;
+
+ completions.push(property);
+ knownCompletions[property] = true;
+ }
+
+ function compare(a, b)
+ {
+ // Try to sort in numerical order first.
+ var numericCompareResult = a - b;
+ if (!isNaN(numericCompareResult))
+ return numericCompareResult;
+
+ // Not numbers, sort as strings.
+ return a.localeCompare(b);
+ }
+
+ completions.sort(compare);
+
+ completionController.updateCompletions(completions, implicitSuffix);
+ }
+ },
+
+ // Private
+
+ _clearLastProperties: function()
+ {
+ if (this._clearLastPropertiesTimeout) {
+ clearTimeout(this._clearLastPropertiesTimeout);
+ delete this._clearLastPropertiesTimeout;
+ }
+
+ // Clear the cache of property names so any changes while stepping or sitting idle get picked up if the same
+ // _expression_ is evaluated again.
+ this._lastPropertyNames = null;
+ }
+};
+
+WebInspector._javascript_RuntimeCompletionProvider.prototype.__proto__ = WebInspector.Object.prototype;
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2013-09-05 18:01:00 UTC (rev 155134)
@@ -185,6 +185,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -384,6 +385,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.js (155133 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/Main.js 2013-09-05 18:00:56 UTC (rev 155133)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -73,6 +73,7 @@
this.cssStyleManager = new WebInspector.CSSStyleManager;
this.logManager = new WebInspector.LogManager;
this.issueManager = new WebInspector.IssueManager;
+ this.runtimeManager = new WebInspector.RuntimeManager;
this.applicationCacheManager = new WebInspector.ApplicationCacheManager;
this.timelineManager = new WebInspector.TimelineManager;
this.profileManager = new WebInspector.ProfileManager;
@@ -84,10 +85,6 @@
// Enable the Console Agent after creating the singleton managers.
ConsoleAgent.enable();
- // Enable the RuntimeAgent to receive notification of execution contexts.
- if (RuntimeAgent.enable)
- RuntimeAgent.enable();
-
// Register for events.
this.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, this._debuggerDidPause, this);
this.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.InspectModeStateChanged, this._inspectModeStateChanged, this);
Added: trunk/Source/WebInspectorUI/UserInterface/RuntimeManager.js (0 => 155134)
--- trunk/Source/WebInspectorUI/UserInterface/RuntimeManager.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/RuntimeManager.js 2013-09-05 18:01:00 UTC (rev 155134)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.RuntimeManager = function()
+{
+ WebInspector.Object.call(this);
+
+ // Enable the RuntimeAgent to receive notification of execution contexts.
+ if (RuntimeAgent.enable)
+ RuntimeAgent.enable();
+};
+
+WebInspector.RuntimeManager.prototype = {
+ constructor: WebInspector.RuntimeManager,
+
+ // Public
+
+ evaluateInInspectedWindow: function(_expression_, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
+ {
+ if (!_expression_) {
+ // There is no _expression_, so the completion should happen against global properties.
+ _expression_ = "this";
+ }
+
+ function evalCallback(error, result, wasThrown)
+ {
+ if (error) {
+ console.error(error);
+ callback(null, false);
+ return;
+ }
+
+ if (returnByValue)
+ callback(null, wasThrown, wasThrown ? null : result);
+ else
+ callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
+ }
+
+ if (WebInspector.debuggerManager.activeCallFrame) {
+ DebuggerAgent.evaluateOnCallFrame(WebInspector.debuggerManager.activeCallFrame.id, _expression_, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, evalCallback);
+ return;
+ }
+
+ // COMPATIBILITY (iOS 6): Execution context identifiers (contextId) did not exist
+ // in iOS 6. Fallback to including the frame identifier (frameId).
+ var contextId = WebInspector.quickConsole.executionContextIdentifier;
+ RuntimeAgent.evaluate.invoke({_expression_: _expression_, objectGroup: objectGroup, includeCommandLineAPI: includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole: doNotPauseOnExceptionsAndMuteConsole, contextId: contextId, frameId: contextId, returnByValue: returnByValue}, evalCallback);
+ }
+};
+
+WebInspector.RuntimeManager.prototype.__proto__ = WebInspector.Object.prototype;