diff --git a/LayoutTests/inspector/unit-tests/set-utilities-expected.txt b/LayoutTests/inspector/unit-tests/set-utilities-expected.txt
index d2169d125e9f..d49b9293f180 100644
--- a/LayoutTests/inspector/unit-tests/set-utilities-expected.txt
+++ b/LayoutTests/inspector/unit-tests/set-utilities-expected.txt
@@ -12,6 +12,13 @@ PASS: Set can filter based on the set object.
PASS: Set can filter with a different this.
PASS: Set can filter based on the set object with a different this.
+-- Running test case: Set.prototype.some
+PASS: Set can 'some' based on the value.
+PASS: Set can 'some' based on the key.
+PASS: Set can 'some' based on the set object.
+PASS: Set can 'some' with a different this.
+PASS: Set can 'some' based on the set object with a different this.
+
-- Running test case: Set.prototype.pushAll
Array:
[1,2] => [1,2,"a1","a2"]
diff --git a/LayoutTests/inspector/unit-tests/set-utilities.html b/LayoutTests/inspector/unit-tests/set-utilities.html
index 830db46aeb43..6caf1ab5b910 100644
--- a/LayoutTests/inspector/unit-tests/set-utilities.html
+++ b/LayoutTests/inspector/unit-tests/set-utilities.html
@@ -35,6 +35,24 @@
},
});
+ suite.addTestCase({
+ name: "Set.prototype.some",
+ test() {
+ function test(set, callback, thisArg, expected, message) {
+ InspectorTest.expectEqual(set.some(callback, thisArg), expected, message);
+ }
+
+ const set1 = new Set([1, 2, 3, 4]);
+ const set2 = new Set([2, 4]);
+
+ test(set1, function(value) { return value % 2; }, null, true, "Set can 'some' based on the value.");
+ test(set1, function(value, key) { return key === 5; }, null, false, "Set can 'some' based on the key.");
+ test(set1, function(value, key, set) { return set === set1; }, null, true, "Set can 'some' based on the set object.");
+ test(set1, function(value, key, set) { return this.has(key); }, set2, true, "Set can 'some' with a different this.");
+ test(set1, function(value, key, set) { return this === set; }, set2, false, "Set can 'some' based on the set object with a different this.");
+ },
+ });
+
suite.addTestCase({
name: "Set.prototype.pushAll",
test() {
diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
index eb545021e768..594a3d533324 100644
--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
@@ -197,6 +197,7 @@ localizedStrings["Approximate Number"] = "~%s";
localizedStrings["Area"] = "Area";
/* Label for option to toggle the area names setting for CSS grid overlays */
localizedStrings["Area names @ Layout Panel Overlay Options"] = "Area Names";
+localizedStrings["As such, the contents will be run as though it was typed into the Console."] = "As such, the contents will be run as though it was typed into the Console.";
localizedStrings["Assertion"] = "Assertion";
localizedStrings["Assertion Failed"] = "Assertion Failed";
localizedStrings["Assertion Failed: %s"] = "Assertion Failed: %s";
@@ -397,6 +398,10 @@ localizedStrings["Console"] = "Console";
localizedStrings["Console Evaluation"] = "Console Evaluation";
localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
localizedStrings["Console Profile Recorded"] = "Console Profile Recorded";
+localizedStrings["Console Snippet..."] = "Console Snippet...";
+localizedStrings["Console Snippets"] = "Console Snippets";
+localizedStrings["Console Snippets are an easy way to save and evaluate JavaScript in the Console."] = "Console Snippets are an easy way to save and evaluate JavaScript in the Console.";
+localizedStrings["Console Snippets..."] = "Console Snippets...";
/* Name of Console Tab */
localizedStrings["Console Tab Name"] = "Console";
localizedStrings["Console cleared at %s"] = "Console cleared at %s";
@@ -434,6 +439,8 @@ localizedStrings["Create %s Rule"] = "Create %s Rule";
/* Title of button that creates a new audit. */
localizedStrings["Create @ Audit Tab Navigation Sidebar"] = "Create";
localizedStrings["Create Breakpoint"] = "Create Breakpoint";
+localizedStrings["Create Console Snippet"] = "Create Console Snippet";
+localizedStrings["Create Console Snippet..."] = "Create Console Snippet...";
localizedStrings["Create Local Override"] = "Create Local Override";
localizedStrings["Create Request Local Override"] = "Create Request Local Override";
localizedStrings["Create Resource"] = "Create Resource";
@@ -993,8 +1000,10 @@ localizedStrings["Microtask Dispatched"] = "Microtask Dispatched";
localizedStrings["Microtask Fired"] = "Microtask Fired";
localizedStrings["Missing result level"] = "Missing result level";
localizedStrings["Mixed"] = "Mixed";
+localizedStrings["Modifications are saved automatically and will apply the next time the Console Snippet is run."] = "Modifications are saved automatically and will apply the next time the Console Snippet is run.";
localizedStrings["Modifications made here will take effect on the next load of any page or sub-frame."] = "Modifications made here will take effect on the next load of any page or sub-frame.";
localizedStrings["Module Code"] = "Module Code";
+localizedStrings["More information is available at ."] = "More information is available at .";
localizedStrings["More information is available at ."] = "More information is available at .";
localizedStrings["Multi-Entry"] = "Multi-Entry";
localizedStrings["Name"] = "Name";
@@ -1027,6 +1036,7 @@ localizedStrings["No Canvas Contexts"] = "No Canvas Contexts";
localizedStrings["No Canvas Selected"] = "No Canvas Selected";
localizedStrings["No Chart Available"] = "No Chart Available";
localizedStrings["No Child Layers"] = "No Child Layers";
+localizedStrings["No Console Snippets"] = "No Console Snippets";
localizedStrings["No Data Bindings"] = "No Data Bindings";
localizedStrings["No Enabled Audits"] = "No Enabled Audits";
localizedStrings["No Entries"] = "No Entries";
@@ -1330,6 +1340,7 @@ localizedStrings["Reveal in Style Sheet"] = "Reveal in Style Sheet";
localizedStrings["Role"] = "Role";
/* Property value for `font-variant-alternates: ruby`. */
localizedStrings["Ruby Glyphs @ Font Details Sidebar Property Value"] = "Ruby Glyphs";
+localizedStrings["Run"] = "Run";
localizedStrings["Run %d"] = "Run %d";
localizedStrings["Run console commands as if inside a user gesture"] = "Run console commands as if inside a user gesture";
localizedStrings["Running the \u201C%s\u201D audit"] = "Running the \u201C%s\u201D audit";
@@ -1577,6 +1588,7 @@ localizedStrings["The \u201C%s\u201D audit resulted in a warning"] = "The \u201C
localizedStrings["The \u201C%s\u201D audit threw an error"] = "The \u201C%s\u201D audit threw an error";
localizedStrings["The \u201C%s\u201D\ntable is empty."] = "The \u201C%s\u201D\ntable is empty.";
localizedStrings["The contents and enabled state will be preserved across Web Inspector sessions."] = "The contents and enabled state will be preserved across Web Inspector sessions.";
+localizedStrings["The contents will be preserved across Web Inspector sessions."] = "The contents will be preserved across Web Inspector sessions.";
localizedStrings["The page's content has changed"] = "The page's content has changed";
localizedStrings["The resource was requested insecurely."] = "The resource was requested insecurely.";
/* Message displayed in a banner when one or more snapshots that the user has not yet seen are being filtered. */
@@ -1619,6 +1631,7 @@ localizedStrings["This is what the result of a passing test with no data looks l
localizedStrings["This is what the result of a test that threw an error with no data looks like."] = "This is what the result of a test that threw an error with no data looks like.";
localizedStrings["This is what the result of a warning test with no data looks like."] = "This is what the result of a warning test with no data looks like.";
localizedStrings["This is what the result of an unsupported test with no data looks like."] = "This is what the result of an unsupported test with no data looks like.";
+localizedStrings["This means all of the Console Command Line API is available ."] = "This means all of the Console Command Line API is available .";
localizedStrings["This object is a root"] = "This object is a root";
localizedStrings["This object is referenced by internal objects"] = "This object is referenced by internal objects";
localizedStrings["This resource came from a local override"] = "This resource came from a local override";
diff --git a/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js b/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js
index 19620428feb8..a644ca944676 100644
--- a/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js
+++ b/Source/WebInspectorUI/UserInterface/Base/ObjectStore.js
@@ -67,7 +67,7 @@ WI.ObjectStore = class ObjectStore
WI.ObjectStore._databaseCallbacks = [callback];
- const version = 7; // Increment this for every edit to `WI.objectStores`.
+ const version = 8; // Increment this for every edit to `WI.objectStores`.
let databaseRequest = window.indexedDB.open(WI.ObjectStore._databaseName, version);
databaseRequest.addEventListener("upgradeneeded", (event) => {
@@ -278,4 +278,7 @@ WI.objectStores = {
// Version 7
symbolicBreakpoints: new WI.ObjectStore("debugger-symbolic-breakpoints", {keyPath: "__id"}),
+
+ // Version 8
+ consoleSnippets: new WI.ObjectStore("console-snippets", {keyPath: "__id"}),
};
diff --git a/Source/WebInspectorUI/UserInterface/Base/Utilities.js b/Source/WebInspectorUI/UserInterface/Base/Utilities.js
index 71b3442f4e71..186b1af8a307 100644
--- a/Source/WebInspectorUI/UserInterface/Base/Utilities.js
+++ b/Source/WebInspectorUI/UserInterface/Base/Utilities.js
@@ -208,6 +208,18 @@ Object.defineProperty(Set.prototype, "filter",
},
});
+Object.defineProperty(Set.prototype, "some",
+ {
+ value(predicate, thisArg)
+ {
+ for (let item of this) {
+ if (predicate.call(thisArg, item, item, this))
+ return true;
+ }
+ return false;
+ },
+ });
+
Object.defineProperty(Set.prototype, "addAll",
{
value(iterable)
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/ConsoleManager.js b/Source/WebInspectorUI/UserInterface/Controllers/ConsoleManager.js
index 7ebebc1270f8..27e35d226afe 100644
--- a/Source/WebInspectorUI/UserInterface/Controllers/ConsoleManager.js
+++ b/Source/WebInspectorUI/UserInterface/Controllers/ConsoleManager.js
@@ -39,9 +39,29 @@ WI.ConsoleManager = class ConsoleManager extends WI.Object
this._isNewPageOrReload = false;
this._remoteObjectsToRelease = null;
+ this._customLoggingChannels = [];
+
+ this._snippets = new Set;
+ this._restoringSnippets = false;
+
+ WI.ConsoleSnippet.addEventListener(WI.SourceCode.Event.ContentDidChange, this._handleSnippetContentChanged, this);
+
WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
- this._customLoggingChannels = [];
+ WI.Target.registerInitializationPromise((async () => {
+ let serializedSnippets = await WI.objectStores.consoleSnippets.getAll();
+
+ this._restoringSnippets = true;
+ for (let serializedSnippet of serializedSnippets) {
+ let snippet = WI.ConsoleSnippet.fromJSON(serializedSnippet);
+
+ const key = null;
+ WI.objectStores.consoleSnippets.associateObject(snippet, key, serializedSnippet);
+
+ this.addSnippet(snippet);
+ }
+ this._restoringSnippets = false;
+ })());
}
// Static
@@ -66,6 +86,7 @@ WI.ConsoleManager = class ConsoleManager extends WI.Object
get warningCount() { return this._warningCount; }
get errorCount() { return this._errorCount; }
+ get snippets() { return this._snippets; }
get customLoggingChannels() { return this._customLoggingChannels; }
issuesForSourceCode(sourceCode)
@@ -88,6 +109,33 @@ WI.ConsoleManager = class ConsoleManager extends WI.Object
this._remoteObjectsToRelease.add(remoteObject);
}
+ addSnippet(snippet)
+ {
+ console.assert(snippet instanceof WI.ConsoleSnippet, snippet);
+ console.assert(!this._snippets.has(snippet), snippet);
+ console.assert(!this._snippets.some((existingSnippet) => snippet.contentIdentifier === existingSnippet.contentIdentifier), snippet);
+
+ this._snippets.add(snippet);
+
+ if (!this._restoringSnippets)
+ WI.objectStores.consoleSnippets.putObject(snippet);
+
+ this.dispatchEventToListeners(WI.ConsoleManager.Event.SnippetAdded, {snippet});
+ }
+
+ removeSnippet(snippet)
+ {
+ console.assert(snippet instanceof WI.ConsoleSnippet, snippet);
+ console.assert(this._snippets.has(snippet), snippet);
+
+ this._snippets.delete(snippet);
+
+ if (!this._restoringSnippets)
+ WI.objectStores.consoleSnippets.deleteObject(snippet);
+
+ this.dispatchEventToListeners(WI.ConsoleManager.Event.SnippetRemoved, {snippet});
+ }
+
// ConsoleObserver
messageWasAdded(target, source, level, text, type, url, line, column, repeatCount, parameters, stackTrace, requestId, timestamp)
@@ -216,6 +264,15 @@ WI.ConsoleManager = class ConsoleManager extends WI.Object
this.dispatchEventToListeners(WI.ConsoleManager.Event.Cleared);
}
+ _handleSnippetContentChanged(event)
+ {
+ let snippet = event.target;
+
+ console.assert(this._snippets.has(snippet), snippet);
+
+ WI.objectStores.consoleSnippets.putObject(snippet);
+ }
+
_mainResourceDidChange(event)
{
console.assert(event.target instanceof WI.Frame);
@@ -239,4 +296,6 @@ WI.ConsoleManager.Event = {
MessageAdded: "console-manager-message-added",
IssueAdded: "console-manager-issue-added",
PreviousMessageRepeatCountUpdated: "console-manager-previous-message-repeat-count-updated",
+ SnippetAdded: "console-manager-snippet-added",
+ SnippetRemoved: "console-manager-snippet-removed",
};
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js b/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js
index d860306d10ee..9f99194edd92 100644
--- a/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js
+++ b/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js
@@ -604,9 +604,7 @@ WI.DOMManager = class DOMManager extends WI.Object
// Re-resolve the node in the console's object group when adding to the console.
let domNode = this.nodeForId(nodeId);
WI.RemoteObject.resolveNode(domNode, WI.RuntimeManager.ConsoleObjectGroup).then((remoteObject) => {
- const specialLogStyles = true;
- const shouldRevealConsole = false;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(WI.UIString("Selected Element"), remoteObject, specialLogStyles, shouldRevealConsole);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(WI.UIString("Selected Element"), remoteObject, {addSpecialUserLogClass: true});
});
}
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptLogViewController.js b/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptLogViewController.js
index ce4242c68830..df8112fa1e83 100644
--- a/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptLogViewController.js
+++ b/Source/WebInspectorUI/UserInterface/Controllers/JavaScriptLogViewController.js
@@ -45,7 +45,7 @@ WI.JavaScriptLogViewController = class JavaScriptLogViewController extends WI.Ob
this._cleared = true;
this._previousMessageView = null;
- this._lastCommitted = "";
+ this._lastCommitted = {text: "", special: false};
this._repeatCountWasInterrupted = false;
this._sessions = [];
@@ -105,7 +105,7 @@ WI.JavaScriptLogViewController = class JavaScriptLogViewController extends WI.Ob
let consoleSession = new WI.ConsoleSession(data);
this._previousMessageView = null;
- this._lastCommitted = "";
+ this._lastCommitted = {text: "", special: false};
this._repeatCountWasInterrupted = false;
this._sessions.push(consoleSession);
@@ -117,12 +117,19 @@ WI.JavaScriptLogViewController = class JavaScriptLogViewController extends WI.Ob
consoleSession.element.scrollIntoView();
}
- appendImmediateExecutionWithResult(text, result, addSpecialUserLogClass, shouldRevealConsole)
+ appendImmediateExecutionWithResult(text, result, {addSpecialUserLogClass, shouldRevealConsole, handleClick} = {})
{
console.assert(result instanceof WI.RemoteObject);
- var commandMessageView = new WI.ConsoleCommandView(text, addSpecialUserLogClass ? "special-user-log" : null);
- this._appendConsoleMessageView(commandMessageView, true);
+ if (this._lastCommitted.text !== text || this._lastCommitted.special !== addSpecialUserLogClass) {
+ let classNames = [];
+ if (addSpecialUserLogClass)
+ classNames.push("special-user-log");
+
+ let commandMessageView = new WI.ConsoleCommandView(text, {classNames, handleClick});
+ this._appendConsoleMessageView(commandMessageView, true);
+ this._lastCommitted = {text, special: addSpecialUserLogClass};
+ }
function saveResultCallback(savedResultIndex)
{
@@ -218,10 +225,10 @@ WI.JavaScriptLogViewController = class JavaScriptLogViewController extends WI.Ob
{
console.assert(text);
- if (this._lastCommitted !== text) {
+ if (this._lastCommitted.text !== text || this._lastCommitted.special) {
let commandMessageView = new WI.ConsoleCommandView(text);
this._appendConsoleMessageView(commandMessageView, true);
- this._lastCommitted = text;
+ this._lastCommitted = {text, special: false};
}
function printResult(result, wasThrown, savedResultIndex)
@@ -277,7 +284,7 @@ WI.JavaScriptLogViewController = class JavaScriptLogViewController extends WI.Ob
this._previousMessageView = messageView;
if (messageView.message && messageView.message.source !== WI.ConsoleMessage.MessageSource.JS)
- this._lastCommitted = "";
+ this._lastCommitted = {test: "", special: false};
if (WI.consoleContentView.isAttached)
this.renderPendingMessagesSoon();
diff --git a/Source/WebInspectorUI/UserInterface/Images/Start.svg b/Source/WebInspectorUI/UserInterface/Images/Start.svg
new file mode 100644
index 000000000000..52126ecba61d
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Images/Start.svg
@@ -0,0 +1,5 @@
+
+
+
diff --git a/Source/WebInspectorUI/UserInterface/Main.html b/Source/WebInspectorUI/UserInterface/Main.html
index 23a29d79ae25..92a6e527b4de 100644
--- a/Source/WebInspectorUI/UserInterface/Main.html
+++ b/Source/WebInspectorUI/UserInterface/Main.html
@@ -85,6 +85,7 @@
+
@@ -423,6 +424,7 @@
+
@@ -698,6 +700,7 @@
+
diff --git a/Source/WebInspectorUI/UserInterface/Models/ConsoleSnippet.js b/Source/WebInspectorUI/UserInterface/Models/ConsoleSnippet.js
new file mode 100644
index 000000000000..d26c68340072
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Models/ConsoleSnippet.js
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+WI.ConsoleSnippet = class ConsoleSnippet extends WI.LocalScript
+{
+ constructor(title, source)
+ {
+ console.assert(typeof title === "string" && title.trim().length, title);
+
+ const target = null;
+ const sourceURL = null;
+ super(target, title, sourceURL, WI.Script.SourceType.Program, source, {editable: true});
+ }
+
+ // Static
+
+ static createDefaultWithTitle(title)
+ {
+ const source = `
+/*
+ * ${WI.UIString("Console Snippets are an easy way to save and evaluate JavaScript in the Console.")}
+ *
+ * ${WI.UIString("As such, the contents will be run as though it was typed into the Console.")}
+ * ${WI.UIString("This means all of the Console Command Line API is available .")}
+ *
+ * ${WI.UIString("Modifications are saved automatically and will apply the next time the Console Snippet is run.")}
+ * ${WI.UIString("The contents will be preserved across Web Inspector sessions.")}
+ *
+ * ${WI.UIString("More information is available at .")}
+ */
+
+"Hello World!"
+`.trimStart();
+ return new WI.ConsoleSnippet(title, source);
+ }
+
+ // Public
+
+ get title()
+ {
+ return this.url;
+ }
+
+ run()
+ {
+ WI.runtimeManager.evaluateInInspectedWindow(this.content, {
+ objectGroup: WI.RuntimeManager.ConsoleObjectGroup,
+ includeCommandLineAPI: true,
+ doNotPauseOnExceptionsAndMuteConsole: true,
+ generatePreview: true,
+ saveResult: true,
+ }, (result, wasThrown) => {
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(this.title, result, {
+ addSpecialUserLogClass: true,
+ shouldRevealConsole: true,
+ handleClick: (event) => {
+ if (!WI.consoleManager.snippets.has(this))
+ return;
+
+
+ const cookie = null;
+ WI.showRepresentedObject(this, cookie, {
+ ignoreNetworkTab: true,
+ ignoreSearchTab: true,
+ });
+ },
+ });
+ });
+ }
+
+ // Import / Export
+
+ static fromJSON(json)
+ {
+ return new WI.ConsoleSnippet(json.title, json.source);
+ }
+
+ toJSON(key)
+ {
+ let json = {
+ title: this.title,
+ source: this.content,
+ };
+ if (key === WI.ObjectStore.toJSONSymbol)
+ json[WI.objectStores.breakpoints.keyPath] = this.title;
+ return json;
+ }
+};
diff --git a/Source/WebInspectorUI/UserInterface/Test.html b/Source/WebInspectorUI/UserInterface/Test.html
index 808d945d4242..f289516904c3 100644
--- a/Source/WebInspectorUI/UserInterface/Test.html
+++ b/Source/WebInspectorUI/UserInterface/Test.html
@@ -149,6 +149,7 @@
+
diff --git a/Source/WebInspectorUI/UserInterface/Views/AnimationContentView.js b/Source/WebInspectorUI/UserInterface/Views/AnimationContentView.js
index 1d135e488f84..4a02006f7414 100644
--- a/Source/WebInspectorUI/UserInterface/Views/AnimationContentView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/AnimationContentView.js
@@ -397,8 +397,7 @@ WI.AnimationContentView = class AnimationContentView extends WI.ContentView
return;
const text = WI.UIString("Selected Animation", "Appears as a label when a given web animation is logged to the Console");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
});
});
diff --git a/Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js b/Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js
index b54c857d5e55..f83430093ad6 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js
@@ -59,9 +59,6 @@ WI.ButtonNavigationItem = class ButtonNavigationItem extends WI.NavigationItem
this.buttonStyle = this._image ? WI.ButtonNavigationItem.Style.Image : WI.ButtonNavigationItem.Style.Text;
this.imageType = this._image ? WI.ButtonNavigationItem.ImageType.SVG : null;
-
- if (this.buttonStyle === WI.ButtonNavigationItem.Style.Image)
- this.tooltip = toolTipOrLabel;
}
// Public
@@ -221,16 +218,19 @@ WI.ButtonNavigationItem = class ButtonNavigationItem extends WI.NavigationItem
switch (this._imageType) {
case null:
case WI.ButtonNavigationItem.ImageType.SVG: {
- let glyphElement = WI.ImageUtilities.useSVGSymbol(this._image, "glyph");
- glyphElement.style.width = this._imageWidth + "px";
- glyphElement.style.height = this._imageHeight + "px";
- this.element.appendChild(glyphElement);
+ if (this._image) {
+ let glyphElement = WI.ImageUtilities.useSVGSymbol(this._image, "glyph");
+ glyphElement.style.width = this._imageWidth + "px";
+ glyphElement.style.height = this._imageHeight + "px";
+ this.element.appendChild(glyphElement);
+ }
break;
}
case WI.ButtonNavigationItem.ImageType.IMG: {
let img = this.element.appendChild(document.createElement("img"));
- img.src = this._image;
+ if (this._image)
+ img.src = this._image;
break;
}
}
@@ -240,6 +240,9 @@ WI.ButtonNavigationItem = class ButtonNavigationItem extends WI.NavigationItem
labelElement.textContent = this._label;
}
}
+
+ if (this._buttonStyle === WI.ButtonNavigationItem.Style.Image)
+ this.tooltip ||= this._label;
}
_updateTabIndex()
diff --git a/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js b/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js
index 7d870d0872a1..de35abcc0172 100644
--- a/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js
@@ -308,8 +308,7 @@ WI.CanvasContentView = class CanvasContentView extends WI.ContentView
return;
const text = WI.UIString("Selected Canvas Context");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
});
});
diff --git a/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js
index 91f26a7c301c..613cd1450469 100644
--- a/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js
+++ b/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js
@@ -93,8 +93,7 @@ WI.CanvasTreeElement = class CanvasTreeElement extends WI.FolderizedTreeElement
return;
const text = WI.UIString("Selected Canvas Context");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
});
});
diff --git a/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js b/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js
index 8379ed7f419e..300760462b41 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js
@@ -29,10 +29,11 @@
WI.ConsoleCommandView = class ConsoleCommandView
{
- constructor(commandText, className)
+ constructor(commandText, {classNames, handleClick} = {})
{
this._commandText = commandText;
- this._className = className || "";
+ this._classNames = classNames || null;
+ this._handleClick = handleClick || null;
}
// Public
@@ -44,12 +45,14 @@ WI.ConsoleCommandView = class ConsoleCommandView
this._element.dir = "ltr";
this._element.setAttribute("data-labelprefix", WI.UIString("Input: "));
- if (this._className)
- this._element.classList.add(this._className);
+ if (this._classNames)
+ this._element.classList.add(...this._classNames);
this._formattedCommandElement = this._element.appendChild(document.createElement("span"));
this._formattedCommandElement.classList.add("console-message-body");
this._formattedCommandElement.textContent = this._commandText;
+ if (this._handleClick)
+ this._formattedCommandElement.addEventListener("click", this._handleClick);
// FIXME: Web Inspector: LogContentView should use higher level objects
this._element.__commandView = this;
diff --git a/Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.css b/Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.css
index 80583d732b77..1f9713faa125 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.css
+++ b/Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.css
@@ -44,7 +44,7 @@
pointer-events: none;
}
-.console-drawer > .navigation-bar > .item > .glyph,
+.console-drawer > .navigation-bar > .item > :is(.glyph, img),
.console-drawer > .navigation-bar > .log-scope-bar > li {
pointer-events: all;
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.css b/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.css
new file mode 100644
index 000000000000..a83058c0ff7c
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.css
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+ .tree-outline .item.console-snippet > .status {
+ display: flex;
+ align-items: center;
+ width: 16px;
+ height: 16px;
+ }
+
+ .tree-outline .item.console-snippet > .status > img {
+ width: 100%;
+ height: 100%;
+ content: url(../Images/Start.svg);
+ }
+
+.tree-outline .item.console-snippet:not(:hover) > .status > img {
+ display: none;
+}
+
+body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.console-snippet.selected:hover > .status > img {
+ filter: var(--filter-invert);
+}
+
+@media (prefers-color-scheme: dark) {
+ .tree-outline .item.console-snippet:hover > .status > img {
+ filter: var(--filter-invert) brightness(90%);
+ }
+}
diff --git a/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.js
new file mode 100644
index 000000000000..4c8de43e3078
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.js
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+WI.ConsoleSnippetTreeElement = class ConsoleSnippetTreeElement extends WI.ScriptTreeElement
+{
+ constructor(consoleSnippet)
+ {
+ console.assert(consoleSnippet instanceof WI.ConsoleSnippet, consoleSnippet);
+
+ super(consoleSnippet);
+
+ this.addClassName("console-snippet");
+ }
+
+ // Protected
+
+ onattach()
+ {
+ super.onattach();
+
+ this.status = document.createElement("img");
+ this.status.title = WI.UIString("Run");
+ this.status.addEventListener("click", (event) => {
+ this.representedObject.run();
+ });
+ }
+
+ ondelete()
+ {
+ WI.consoleManager.removeSnippet(this.representedObject);
+
+ return true;
+ }
+
+ onspace()
+ {
+ this.representedObject.run();
+
+ return true;
+ }
+
+ canSelectOnMouseDown(event)
+ {
+ if (this.status.contains(event.target))
+ return false;
+
+ return super.canSelectOnMouseDown(event);
+ }
+
+ updateStatus()
+ {
+ // Do nothing. Do not allow ScriptTreeElement / SourceCodeTreeElement to modify our status element.
+ }
+};
diff --git a/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js b/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
index c9a486e97ede..0553e52c94cd 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
@@ -363,8 +363,7 @@ WI.appendContextMenuItemsForDOMNode = function(contextMenu, domNode, options = {
contextMenu.appendItem(label, () => {
WI.RemoteObject.resolveNode(domNode, WI.RuntimeManager.ConsoleObjectGroup).then((remoteObject) => {
let text = isElement ? WI.UIString("Selected Element", "Selected DOM element") : WI.UIString("Selected Node", "Selected DOM node");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
});
});
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js b/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js
index 10185b8a0ad0..54a9d4fa666b 100644
--- a/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js
+++ b/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js
@@ -81,12 +81,12 @@ WI.HeapSnapshotInstanceDataGridNode = class HeapSnapshotInstanceDataGridNode ext
if (node.className === "string") {
WI.heapManager.getPreview(node, function(error, string, functionDetails, objectPreviewPayload) {
let remoteObject = error ? WI.RemoteObject.fromPrimitiveValue(undefined) : WI.RemoteObject.fromPrimitiveValue(string);
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass, shouldRevealConsole);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass, shouldRevealConsole});
});
} else {
WI.heapManager.getRemoteObject(node, WI.RuntimeManager.ConsoleObjectGroup, function(error, remoteObjectPayload) {
let remoteObject = error ? WI.RemoteObject.fromPrimitiveValue(undefined) : WI.RemoteObject.fromPayload(remoteObjectPayload, WI.assumingMainTarget());
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass, shouldRevealConsole);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass, shouldRevealConsole});
});
}
});
diff --git a/Source/WebInspectorUI/UserInterface/Views/InputPopover.js b/Source/WebInspectorUI/UserInterface/Views/InputPopover.js
index 01a31ee52d55..d8eb4ed5a96e 100644
--- a/Source/WebInspectorUI/UserInterface/Views/InputPopover.js
+++ b/Source/WebInspectorUI/UserInterface/Views/InputPopover.js
@@ -25,13 +25,12 @@
WI.InputPopover = class InputPopover extends WI.Popover
{
- constructor(message, delegate)
+ constructor(identifier, message, delegate)
{
super(delegate);
+ this._identifier = identifier;
this._message = message;
- this._value = null;
- this._result = WI.InputPopover.Result.None;
this._targetElement = null;
this._preferredEdges = null;
@@ -39,8 +38,11 @@ WI.InputPopover = class InputPopover extends WI.Popover
this.windowResizeHandler = this._presentOverTargetElement.bind(this);
}
- get value() { return this._value; }
- get result() { return this._result; }
+ get identifier() { return this._identifier; }
+ get value()
+ {
+ return this._inputElement?.value ?? "";
+ }
show(targetElement, preferredEdges)
{
@@ -48,7 +50,7 @@ WI.InputPopover = class InputPopover extends WI.Popover
this._preferredEdges = preferredEdges;
let contentElement = document.createElement("div");
- contentElement.classList.add("input-popover-content");
+ contentElement.classList.add("input-popover-content", this._identifier);
if (this._message) {
let label = document.createElement("div");
@@ -61,13 +63,8 @@ WI.InputPopover = class InputPopover extends WI.Popover
this._inputElement.spellcheck = false;
this._inputElement.addEventListener("keydown", (event) => {
- if (!isEnterKey(event))
- return;
-
- this._result = WI.InputPopover.Result.Committed;
- this._value = event.target.value;
-
- this.dismiss();
+ if (isEnterKey(event))
+ this.dismiss();
});
contentElement.appendChild(this._inputElement);
@@ -89,9 +86,3 @@ WI.InputPopover = class InputPopover extends WI.Popover
this._inputElement.select();
}
};
-
-WI.InputPopover.Result = {
- None: Symbol("result-none"),
- Cancelled: Symbol("result-cancelled"),
- Committed: Symbol("result-committed"),
-};
diff --git a/Source/WebInspectorUI/UserInterface/Views/LogContentView.css b/Source/WebInspectorUI/UserInterface/Views/LogContentView.css
index 31604e705ae8..44f6622f1d84 100644
--- a/Source/WebInspectorUI/UserInterface/Views/LogContentView.css
+++ b/Source/WebInspectorUI/UserInterface/Views/LogContentView.css
@@ -61,6 +61,12 @@
color: var(--glyph-color-active-pressed);
}
+.navigation-bar > .item.console-snippets > img {
+ width: 16px;
+ height: 16px;
+ content: url(../Images/ClippingIcons.svg#js-light);
+}
+
.content-view.log {
display: flex;
flex-direction: column;
@@ -267,7 +273,24 @@ body[dir=rtl] .console-group-title::before {
alt: attr(data-labelprefix);
}
+.console-user-command:not(:hover) > .console-snippet-options {
+ display: none;
+}
+
+.create-snippet-popover > .label {
+ display: inline-block;
+ margin-inline-end: 6px;
+ font-weight: bold;
+ line-height: 23px;
+ white-space: nowrap;
+ color: hsl(0, 0%, 34%);
+}
+
@media (prefers-color-scheme: dark) {
+ .navigation-bar > .item.console-snippets > img {
+ content: url(../Images/ClippingIcons.svg#js-dark);
+ }
+
.console-messages {
background-color: var(--background-color-content);
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/LogContentView.js b/Source/WebInspectorUI/UserInterface/Views/LogContentView.js
index 7bb2d5c7dc86..99cea9c5f83d 100644
--- a/Source/WebInspectorUI/UserInterface/Views/LogContentView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/LogContentView.js
@@ -116,6 +116,12 @@ WI.LogContentView = class LogContentView extends WI.ContentView
this._messageSourceBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._messageSourceBarSelectionDidChange, this);
}
+ const consoleSnippetsImage = ""; // This is set in CSS to have dark mode support.
+ this._consoleSnippetsNavigationItem = new WI.ButtonNavigationItem("console-snippets", WI.UIString("Console Snippets..."), consoleSnippetsImage);
+ this._consoleSnippetsNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.Image;
+ this._consoleSnippetsNavigationItem.imageType = WI.ButtonNavigationItem.ImageType.IMG;
+ WI.addMouseDownContextMenuHandlers(this._consoleSnippetsNavigationItem.element, this._handleSnippetsNavigationItemContextMenu.bind(this));
+
this._garbageCollectNavigationItem = new WI.ButtonNavigationItem("garbage-collect", WI.UIString("Collect garbage"), "Images/NavigationItemGarbageCollect.svg", 16, 16);
this._garbageCollectNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._garbageCollect, this);
@@ -156,6 +162,8 @@ WI.LogContentView = class LogContentView extends WI.ContentView
if (this._emulateUserGestureNavigationItemGroup)
navigationItems.push(this._emulateUserGestureNavigationItemGroup);
+ navigationItems.push(this._consoleSnippetsNavigationItem);
+
if (InspectorBackend.hasCommand("Heap.gc"))
navigationItems.push(this._garbageCollectNavigationItem);
@@ -377,6 +385,37 @@ WI.LogContentView = class LogContentView extends WI.ContentView
this.prompt.focus();
}
+ // Popover delegate
+
+ willDismissPopover(popover)
+ {
+ if (popover instanceof WI.InputPopover) {
+ let title = popover.value?.trim();
+ if (!title) {
+ InspectorFrontendHost.beep();
+ return;
+ }
+
+ // Do not conflict with an existing console snippet.
+ if (WI.consoleManager.snippets.some((consoleSnippet) => consoleSnippet.title === title)) {
+ InspectorFrontendHost.beep();
+ return;
+ }
+
+ let consoleSnippet = WI.ConsoleSnippet.createDefaultWithTitle(title);
+ WI.consoleManager.addSnippet(consoleSnippet);
+
+ const cookie = null;
+ WI.showRepresentedObject(consoleSnippet, cookie, {
+ ignoreNetworkTab: true,
+ ignoreSearchTab: true,
+ });
+ return;
+ }
+
+ console.assert(false, "not reached", popover);
+ }
+
// Private
_formatMessagesAsData(onlySelected)
@@ -668,8 +707,7 @@ WI.LogContentView = class LogContentView extends WI.ContentView
WI.RemoteObject.resolveNode(domNode, WI.RuntimeManager.ConsoleObjectGroup)
.then((remoteObject) => {
let text = domNode.nodeType() === Node.ELEMENT_NODE ? WI.UIString("Dropped Element") : WI.UIString("Dropped Node");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
this.prompt.focus();
});
@@ -926,6 +964,21 @@ WI.LogContentView = class LogContentView extends WI.ContentView
}, !WI.settings.clearLogOnNavigate.value);
}
+ _handleSnippetsNavigationItemContextMenu(contextMenu) {
+ for (let consoleSnippet of WI.consoleManager.snippets) {
+ contextMenu.appendItem(consoleSnippet.displayName, () => {
+ consoleSnippet.run();
+ });
+ }
+
+ contextMenu.appendSeparator();
+
+ contextMenu.appendItem(WI.UIString("Create Console Snippet..."), () => {
+ let popover = new WI.InputPopover("create-snippet-popover", WI.UIString("Name"), this);
+ popover.show(this._consoleSnippetsNavigationItem.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
+ });
+ }
+
_handleClearLogOnNavigateSettingChanged()
{
this._updateOtherFiltersNavigationItemState();
diff --git a/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js b/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js
index 48ff08c63856..042a23c2f47c 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js
@@ -295,7 +295,7 @@ WI.ObjectPreviewView = class ObjectPreviewView extends WI.Object
if (!isImpossible)
WI.quickConsole.prompt.pushHistoryItem(text);
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, this._remoteObject, isImpossible);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, this._remoteObject, {addSpecialUserLogClass: isImpossible});
});
}
};
diff --git a/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js
index c36d44f62380..b00f12044ff4 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js
@@ -196,7 +196,7 @@ WI.ObjectTreeBaseTreeElement = class ObjectTreeBaseTreeElement extends WI.Genera
return;
var text = WI.UIString("Selected Symbol");
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, symbol, true);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, symbol, {addSpecialUserLogClass: true});
}
_logValue(value)
@@ -212,7 +212,7 @@ WI.ObjectTreeBaseTreeElement = class ObjectTreeBaseTreeElement extends WI.Genera
if (!isImpossible)
WI.quickConsole.prompt.pushHistoryItem(text);
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue, isImpossible);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue, {addSpecialUserLogClass: isImpossible});
}
_appendMenusItemsForObject(contextMenu, resolvedValue)
diff --git a/Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js b/Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js
index c24067b467bc..52867a2d82f5 100644
--- a/Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js
+++ b/Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js
@@ -165,6 +165,8 @@ WI.OpenResourceDialog = class OpenResourceDialog extends WI.Dialog
WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._scriptRemoved, this);
WI.cssManager.removeEventListener(WI.CSSManager.Event.StyleSheetAdded, this._handleStyleSheetAdded, this);
WI.cssManager.removeEventListener(WI.CSSManager.Event.StyleSheetRemoved, this._handleStyleSheetRemoved, this);
+ WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.SnippetAdded, this._handleConsoleSnippetAdded, this);
+ WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.SnippetRemoved, this._handleConsoleSnippetRemoved, this);
this._queryController.reset();
this._updateFilterThrottler.cancel();
@@ -180,6 +182,8 @@ WI.OpenResourceDialog = class OpenResourceDialog extends WI.Dialog
WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._scriptRemoved, this);
WI.cssManager.addEventListener(WI.CSSManager.Event.StyleSheetAdded, this._handleStyleSheetAdded, this);
WI.cssManager.addEventListener(WI.CSSManager.Event.StyleSheetRemoved, this._handleStyleSheetRemoved, this);
+ WI.consoleManager.addEventListener(WI.ConsoleManager.Event.SnippetAdded, this._handleConsoleSnippetAdded, this);
+ WI.consoleManager.addEventListener(WI.ConsoleManager.Event.SnippetRemoved, this._handleConsoleSnippetRemoved, this);
if (WI.networkManager.mainFrame)
this._addResourcesForFrame(WI.networkManager.mainFrame);
@@ -206,6 +210,9 @@ WI.OpenResourceDialog = class OpenResourceDialog extends WI.Dialog
this._addResource(styleSheet);
}
+ for (let consoleSnippet of WI.consoleManager.snippets)
+ this._addResource(consoleSnippet);
+
this._updateFilterThrottler.force();
this._inputElement.focus();
@@ -469,6 +476,16 @@ WI.OpenResourceDialog = class OpenResourceDialog extends WI.Dialog
this._removeResource(styleSheet);
}
+
+ _handleConsoleSnippetAdded(event)
+ {
+ this._addResource(event.data.snippet);
+ }
+
+ _handleConsoleSnippetRemoved(event)
+ {
+ this._removeResource(event.data.snippet);
+ }
};
WI.OpenResourceDialog.ResourceMatchCookieDataSymbol = Symbol("open-resource-dialog-resource-match-cookie-data");
diff --git a/Source/WebInspectorUI/UserInterface/Views/QuickConsole.js b/Source/WebInspectorUI/UserInterface/Views/QuickConsole.js
index 5c51a3a4c0be..420d6e6bfe6f 100644
--- a/Source/WebInspectorUI/UserInterface/Views/QuickConsole.js
+++ b/Source/WebInspectorUI/UserInterface/Views/QuickConsole.js
@@ -336,8 +336,7 @@ WI.QuickConsole = class QuickConsole extends WI.View
WI.RemoteObject.resolveNode(domNode, WI.RuntimeManager.ConsoleObjectGroup)
.then((remoteObject) => {
let text = domNode.nodeType() === Node.ELEMENT_NODE ? WI.UIString("Dropped Element") : WI.UIString("Dropped Node");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
this.prompt.focus();
});
diff --git a/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css b/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css
index d5c3e2dc94ba..33453e54af4f 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css
+++ b/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css
@@ -71,7 +71,7 @@
content: url(../Images/DocumentIcons.svg#js-light-override);
}
-.anonymous-script-icon .icon {
+:is(.anonymous-script-icon, .resource-icon.resource-type-script.console-snippet) .icon {
content: url(../Images/ClippingIcons.svg#js-light);
}
@@ -162,7 +162,7 @@ body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .
content: url(../Images/DocumentIcons.svg#js-dark-override);
}
- .anonymous-script-icon .icon {
+ :is(.anonymous-script-icon, .resource-icon.resource-type-script.console-snippet) .icon {
content: url(../Images/ClippingIcons.svg#js-dark);
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js b/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js
index a8bd0f178a8d..64e10d0cb84a 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js
@@ -248,7 +248,10 @@ WI.ScriptContentView = class ScriptContentView extends WI.ContentView
_handleTextEditorContentDidChange(event)
{
- this._script.editableRevision.updateRevisionContent(this._textEditor.string);
+ this._updateRevisionContentDebouncer ||= new Debouncer(() => {
+ this._script.editableRevision.updateRevisionContent(this._textEditor.string);
+ });
+ this._updateRevisionContentDebouncer.delayForTime(250);
}
_togglePrettyPrint(event)
diff --git a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js
index a065be94f06c..aa1ef3016022 100644
--- a/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js
+++ b/Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js
@@ -343,6 +343,8 @@ WI.SearchSidebarPanel = class SearchSidebarPanel extends WI.NavigationSidebarPan
// FIXME: Resource search should work with Local Overrides if enabled.
+ // FIXME: Resource search should work with Console Snippets.
+
// FIXME: Resource search should work in JSContext inspection.
// Web Inspector: JSContext inspection Resource search does not work
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css b/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css
index 1a0c3036f51d..ecdfc510b049 100644
--- a/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css
+++ b/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css
@@ -66,14 +66,10 @@
display: none;
}
-.sidebar > .panel.navigation.sources > .content > :matches(.pause-reason-container, .call-stack-container, .breakpoints-container, .local-overrides-container) {
+.sidebar > .panel.navigation.sources > .content > :matches(.pause-reason-container, .call-stack-container, .breakpoints-container, .local-overrides-container, .console-snippets-container) {
border-bottom: 1px solid var(--border-color);
}
-.sidebar > .panel.navigation.sources > .content > .local-overrides {
- border-width: 1px !important;
-}
-
.sidebar > .panel.navigation.sources > .content .details-section {
font-size: 11px;
--details-section-border-bottom: none;
@@ -130,7 +126,7 @@
--details-section-header-top: 0;
}
- .sidebar > .panel.navigation.sources > .content > :matches(.call-stack-container, .breakpoints-container, .resources-container, .local-overrides-container) {
+ .sidebar > .panel.navigation.sources > .content > :matches(.call-stack-container, .breakpoints-container, .resources-container, .local-overrides-container, .console-snippets-container) {
height: 100%;
overflow-y: auto;
}
@@ -153,6 +149,22 @@
max-height: fit-content;
}
+ .sidebar > .panel.navigation.sources > .content > .console-snippets-container {
+ flex-grow: 0;
+ flex-shrink: 0;
+ height: auto;
+ }
+
+ .sidebar > .panel.navigation.sources > .content > .console-snippets-container > .details-section {
+ height: 100%;
+ }
+
+ .sidebar > .panel.navigation.sources > .content > .console-snippets-container > .details-section > .content {
+ height: 100%;
+ max-height: 90px;
+ overflow-y: auto;
+ }
+
.sidebar > .panel.navigation.sources > .content > .resources-container {
flex-grow: 1;
flex-shrink: 3;
diff --git a/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js b/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
index a864eb314e32..607f99a03dde 100644
--- a/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
+++ b/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js
@@ -246,6 +246,28 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
this._localOverridesContainer.hidden = true;
this._localOverridesContainer.appendChild(this._localOverridesSection.element);
+ this._consoleSnippetsTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
+ this._consoleSnippetsTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
+
+ this._consoleSnippetsRow = new WI.DetailsSectionRow(WI.UIString("No Console Snippets"));
+
+ let consoleSnippetNavigationBarWrapper = document.createElement("div");
+
+ let consoleSnippetNavigationBar = new WI.NavigationBar;
+ consoleSnippetNavigationBarWrapper.appendChild(consoleSnippetNavigationBar.element);
+
+ this._createConsoleSnippetButton = new WI.ButtonNavigationItem("create-console-snippet", WI.UIString("Create Console Snippet"), "Images/Plus13.svg", 13, 13);
+ this._createConsoleSnippetButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCreateConsoleSnippetButtonClicked, this);
+ consoleSnippetNavigationBar.addNavigationItem(this._createConsoleSnippetButton);
+
+ let consoleSnippetsGroup = new WI.DetailsSectionGroup([this._consoleSnippetsRow]);
+ this._consoleSnippetsSection = new WI.DetailsSection("console-snippets", WI.UIString("Console Snippets"), [consoleSnippetsGroup], consoleSnippetNavigationBarWrapper);
+
+ this._consoleSnippetsContainer = this.contentView.element.appendChild(document.createElement("div"));
+ this._consoleSnippetsContainer.classList.add("console-snippets-container");
+ this._consoleSnippetsContainer.hidden = true;
+ this._consoleSnippetsContainer.appendChild(this._consoleSnippetsSection.element);
+
this._resourcesNavigationBar = new WI.NavigationBar;
this.contentView.addSubview(this._resourcesNavigationBar);
@@ -344,6 +366,8 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
WI.consoleManager.addEventListener(WI.ConsoleManager.Event.IssueAdded, this._handleConsoleIssueAdded, this);
WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._handleConsoleCleared, this);
+ WI.consoleManager.addEventListener(WI.ConsoleManager.Event.SnippetAdded, this._handleConsoleSnippetAdded, this);
+ WI.consoleManager.addEventListener(WI.ConsoleManager.Event.SnippetRemoved, this._handleConsoleSnippetRemoved, this);
WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
@@ -438,6 +462,9 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
this._handleAuditManagerTestScheduled();
}
+ for (let consoleSnippet of WI.consoleManager.snippets)
+ this._addConsoleSnippet(consoleSnippet);
+
this._updateBreakpointsDisabledBanner();
}
@@ -507,6 +534,8 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.IssueAdded, this._handleConsoleIssueAdded, this);
WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.Cleared, this._handleConsoleCleared, this);
+ WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.SnippetAdded, this._handleConsoleSnippetAdded, this);
+ WI.consoleManager.removeEventListener(WI.ConsoleManager.Event.SnippetRemoved, this._handleConsoleSnippetRemoved, this);
WI.timelineManager.removeEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);
@@ -552,6 +581,9 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
if (representedObject instanceof WI.Script && representedObject === WI.networkManager.bootstrapScript)
return this._localOverridesTreeOutline.findTreeElement(representedObject);
+ if (representedObject instanceof WI.ConsoleSnippet)
+ return this._consoleSnippetsTreeOutline.findTreeElement(representedObject);
+
if (!this._mainFrameTreeElement && (representedObject instanceof WI.Resource || representedObject instanceof WI.Frame || representedObject instanceof WI.Collection)) {
// All resources are under the main frame, so we need to return early if we don't have the main frame yet.
return null;
@@ -761,7 +793,13 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
treeOutline.addEventListener(WI.TreeOutline.Event.ElementRevealed, function(event) {
let treeElement = event.data.element;
- let detailsSections = [this._pauseReasonSection, this._callStackSection, this._breakpointsSection, this._localOverridesSection];
+ let detailsSections = [
+ this._pauseReasonSection,
+ this._callStackSection,
+ this._breakpointsSection,
+ this._localOverridesSection,
+ this._consoleSnippetsSection,
+ ];
let detailsSection = detailsSections.find((detailsSection) => detailsSection.element.contains(treeElement.listItemElement));
if (!detailsSection)
return;
@@ -845,6 +883,11 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
return;
}
+ if (popover instanceof WI.InputPopover) {
+ this._willDismissConsoleSnippetPopover(popover);
+ return;
+ }
+
if (popover instanceof WI.EventBreakpointPopover) {
this._willDismissEventBreakpointPopover(popover);
return;
@@ -887,6 +930,33 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
WI.showLocalResourceOverride(localResourceOverride);
}
+ _willDismissConsoleSnippetPopover(popover)
+ {
+ let title = popover.value?.trim();
+ if (!title) {
+ if (!this._consoleSnippetsTreeOutline.children.length)
+ this._consoleSnippetsContainer.hidden = true;
+
+ InspectorFrontendHost.beep();
+ return;
+ }
+
+ // Do not conflict with an existing consoleSnippet.
+ if (WI.consoleManager.snippets.some((consoleSnippet) => consoleSnippet.title === title)) {
+ InspectorFrontendHost.beep();
+ return;
+ }
+
+ let consoleSnippet = WI.ConsoleSnippet.createDefaultWithTitle(title);
+ WI.consoleManager.addSnippet(consoleSnippet);
+
+ const cookie = null;
+ WI.showRepresentedObject(consoleSnippet, cookie, {
+ ignoreNetworkTab: true,
+ ignoreSearchTab: true,
+ });
+ }
+
_willDismissEventBreakpointPopover(popover)
{
let breakpoint = popover.breakpoint;
@@ -945,6 +1015,7 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
const rankFunctions = [
(treeElement) => treeElement instanceof WI.ScriptTreeElement && treeElement.representedObject === WI.networkManager.bootstrapScript,
(treeElement) => treeElement instanceof WI.LocalResourceOverrideTreeElement,
+ (treeElement) => treeElement instanceof WI.ScriptTreeElement && treeElement.representedObject instanceof WI.ConsoleSnippet,
(treeElement) => treeElement instanceof WI.CSSStyleSheetTreeElement && treeElement.representedObject.isInspectorStyleSheet(),
(treeElement) => treeElement === this._mainFrameTreeElement,
(treeElement) => treeElement instanceof WI.FrameTreeElement,
@@ -1547,6 +1618,46 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
}
}
+ _addConsoleSnippet(consoleSnippet)
+ {
+ console.assert(consoleSnippet instanceof WI.ConsoleSnippet, consoleSnippet);
+
+ if (this._consoleSnippetsTreeOutline.findTreeElement(consoleSnippet))
+ return;
+
+ let parentTreeElement = this._consoleSnippetsTreeOutline;
+
+ let consoleSnippetTreeElement = new WI.ConsoleSnippetTreeElement(consoleSnippet);
+
+ let index = insertionIndexForObjectInListSortedByFunction(consoleSnippetTreeElement, parentTreeElement.children, this._boundCompareTreeElements);
+ parentTreeElement.insertChild(consoleSnippetTreeElement, index);
+
+ this._consoleSnippetsRow.hideEmptyMessage();
+ this._consoleSnippetsRow.element.appendChild(this._consoleSnippetsTreeOutline.element);
+ this._consoleSnippetsContainer.hidden = false;
+ }
+
+ _removeConsoleSnippet(consoleSnippet)
+ {
+ console.assert(consoleSnippet instanceof WI.ConsoleSnippet, consoleSnippet);
+
+ let consoleSnippetTreeElement = this._consoleSnippetsTreeOutline.findTreeElement(consoleSnippet);
+ if (!consoleSnippetTreeElement)
+ return;
+
+ let wasSelected = consoleSnippetTreeElement.selected;
+
+ let parentTreeElement = this._consoleSnippetsTreeOutline;
+ parentTreeElement.removeChild(consoleSnippetTreeElement);
+
+ if (!parentTreeElement.children.length) {
+ this._consoleSnippetsContainer.hidden = true;
+
+ if (wasSelected && WI.networkManager.mainFrame && WI.networkManager.mainFrame.mainResource)
+ WI.showRepresentedObject(WI.networkManager.mainFrame.mainResource);
+ }
+ }
+
_updateTemporarilyDisabledBreakpointsButtons()
{
let breakpointsDisabledTemporarily = WI.debuggerManager.breakpointsDisabledTemporarily;
@@ -2159,6 +2270,12 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
}
}
+ _handleCreateConsoleSnippetButtonClicked(event)
+ {
+ let popover = new WI.InputPopover("create-snippet-popover", WI.UIString("Name"), this);
+ popover.show(this._createConsoleSnippetButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
+ }
+
_populateCreateResourceContextMenu(contextMenu)
{
if (WI.NetworkManager.supportsOverridingResponses()) {
@@ -2176,6 +2293,19 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
});
}
+ contextMenu.appendItem(WI.UIString("Console Snippet..."), () => {
+ if (!this._consoleSnippetsTreeOutline.children.length)
+ this._consoleSnippetsRow.showEmptyMessage();
+
+ this._consoleSnippetsContainer.hidden = false;
+
+ this._createConsoleSnippetButton.element.scrollIntoViewIfNeeded(false);
+ requestAnimationFrame(() => {
+ let popover = new WI.InputPopover("create-snippet-popover", WI.UIString("Name"), this);
+ popover.show(this._createConsoleSnippetButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
+ });
+ });
+
if (WI.NetworkManager.supportsBootstrapScript()) {
contextMenu.appendItem(WI.UIString("Inspector Bootstrap Script"), async () => {
await WI.networkManager.createBootstrapScript();
@@ -2546,6 +2676,16 @@ WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends W
issueTreeElements.forEach((treeElement) => treeElement.parent.removeChild(treeElement));
}
+ _handleConsoleSnippetAdded(event)
+ {
+ this._addConsoleSnippet(event.data.snippet);
+ }
+
+ _handleConsoleSnippetRemoved(event)
+ {
+ this._removeConsoleSnippet(event.data.snippet);
+ }
+
_handleTimelineCapturingStateChanged(event)
{
this._updateTemporarilyDisabledBreakpointsButtons();
diff --git a/Source/WebInspectorUI/UserInterface/Views/WebSocketDataGridNode.js b/Source/WebInspectorUI/UserInterface/Views/WebSocketDataGridNode.js
index 2f904c6d1892..3e6c6b192ad1 100644
--- a/Source/WebInspectorUI/UserInterface/Views/WebSocketDataGridNode.js
+++ b/Source/WebInspectorUI/UserInterface/Views/WebSocketDataGridNode.js
@@ -53,9 +53,7 @@ WI.WebSocketDataGridNode = class WebSocketDataGridNode extends WI.DataGridNode
console.assert(!wasThrown);
const title = WI.UIString("Selected Frame");
- const addSpecialUserLogClass = true;
- const shouldRevealConsole = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(title, result, addSpecialUserLogClass, shouldRevealConsole);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(title, result, {addSpecialUserLogClass: true, shouldRevealConsole: true});
};
if (this._data.isText) {
diff --git a/Source/WebInspectorUI/UserInterface/Views/WebSocketResourceTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/WebSocketResourceTreeElement.js
index c13d5090a81e..8ff00a92cc1e 100644
--- a/Source/WebInspectorUI/UserInterface/Views/WebSocketResourceTreeElement.js
+++ b/Source/WebInspectorUI/UserInterface/Views/WebSocketResourceTreeElement.js
@@ -51,8 +51,7 @@ WI.WebSocketResourceTreeElement = class WebSocketResourceTreeElement extends WI.
return;
const text = WI.UIString("Selected WebSocket");
- const addSpecialUserLogClass = true;
- WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, addSpecialUserLogClass);
+ WI.consoleLogViewController.appendImmediateExecutionWithResult(text, remoteObject, {addSpecialUserLogClass: true});
});
});