Skip to content

Commit

Permalink
Web Inspector: add support for console snippets
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=245161

Reviewed by Patrick Angle.

Console Snippets can be very useful for developers that frequently run the same JS over and over.

Previously, the developer would have to either repeatedly type the same thing, use the up arrow to
find the JS in the Console history, or even use the pasteboard (likely from another app/file).

With Console Snippets, the developer can rely on Web Inspector to organize and maintain the "library"
of JS that the developer might want to invoke, as well as having quick ways to actually do so.

* Source/WebInspectorUI/UserInterface/Models/ConsoleSnippet.js: Added.
(WI.ConsoleSnippet):
(WI.ConsoleSnippet.createDefaultWithTitle):
(WI.ConsoleSnippet.prototype.get title):
(WI.ConsoleSnippet.prototype.run):
(WI.ConsoleSnippet.fromJSON):
(WI.ConsoleSnippet.prototype.toJSON):
* Source/WebInspectorUI/UserInterface/Controllers/ConsoleManager.js:
(WI.ConsoleManager):
(WI.ConsoleManager.prototype.get snippets): Added.
(WI.ConsoleManager.prototype.addSnippet): Added.
(WI.ConsoleManager.prototype.removeSnippet): Added.
(WI.ConsoleManager.prototype._handleSnippetContentChanged): Added.

* Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css:
(:is(.anonymous-script-icon, .resource-icon.resource-type-script.console-snippet) .icon): Renamed from `.anonymous-script-icon .icon`.
(@media (prefers-color-scheme: dark) :is(.anonymous-script-icon, .resource-icon.resource-type-script.console-snippet) .icon): Renamed from `@media (prefers-color-scheme: dark) .anonymous-script-icon .icon`.
Force Console Snippets to use the JS clipping icon.

* Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.js: Added.
(WI.ConsoleSnippetTreeElement):
(WI.ConsoleSnippetTreeElement.prototype.onattach):
(WI.ConsoleSnippetTreeElement.prototype.ondelete):
(WI.ConsoleSnippetTreeElement.prototype.onspace):
(WI.ConsoleSnippetTreeElement.prototype.canSelectOnMouseDown):
(WI.ConsoleSnippetTreeElement.prototype.updateStatus):
* Source/WebInspectorUI/UserInterface/Views/ConsoleSnippetTreeElement.css: Added.
(.tree-outline .item.console-snippet > .status):
(.tree-outline .item.console-snippet > .status > img):
(.tree-outline .item.console-snippet:not(:hover) > .status > img):
(body:not(.window-inactive, .window-docked-inactive) .tree-outline:focus-within .item.console-snippet.selected:hover > .status > img):
(@media (prefers-color-scheme: dark) .tree-outline .item.console-snippet:hover > .status > img):
* Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js:
(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype.closed):
(WI.SourcesNavigationSidebarPanel.prototype.createContentTreeOutline):
(WI.SourcesNavigationSidebarPanel.prototype.willDismissPopover):
(WI.SourcesNavigationSidebarPanel.prototype._willDismissConsoleSnippetPopover): Added.
(WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
(WI.SourcesNavigationSidebarPanel.prototype._addConsoleSnippet): Added.
(WI.SourcesNavigationSidebarPanel.prototype._removeConsoleSnippet): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleCreateConsoleSnippetButtonClicked): Added.
(WI.SourcesNavigationSidebarPanel.prototype.async _populateCreateResourceContextMenu):
(WI.SourcesNavigationSidebarPanel.prototype._handleConsoleSnippetAdded): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleConsoleSnippetRemoved): Added.
* Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.css:
(.sidebar > .panel.navigation.sources > .content > :matches(.pause-reason-container, .call-stack-container, .breakpoints-container, .local-overrides-container, .console-snippets-container)): Renamed from `.sidebar > .panel.navigation.sources > .content > :matches(.pause-reason-container, .call-stack-container, .breakpoints-container, .local-overrides-container)`.
(@media (min-height: 650px) .sidebar > .panel.navigation.sources > .content > :matches(.call-stack-container, .breakpoints-container, .resources-container, .local-overrides-container, .console-snippets-container)): Renamed from `@media (min-height: 650px) .sidebar > .panel.navigation.sources > .content > :matches(.call-stack-container, .breakpoints-container, .resources-container, .local-overrides-container)`.
(@media (min-height: 650px) .sidebar > .panel.navigation.sources > .content > .console-snippets-container): Added.
(@media (min-height: 650px) .sidebar > .panel.navigation.sources > .content > .console-snippets-container > .details-section): Added.
(@media (min-height: 650px) .sidebar > .panel.navigation.sources > .content > .console-snippets-container > .details-section > .content): Added.
(.sidebar > .panel.navigation.sources > .content > .local-overrides): Deleted.
Add a "Console Snippets" section to the navigation sidebar in the Sources Tab.

* Source/WebInspectorUI/UserInterface/Views/LogContentView.js:
(WI.LogContentView):
(WI.LogContentView.prototype.get navigationItems):
(WI.LogContentView.prototype.willDismissPopover):
(WI.LogContentView.prototype._handleDrop):
(WI.LogContentView.prototype._handleSnippetsNavigationItemContextMenu): Added.
* Source/WebInspectorUI/UserInterface/Views/LogContentView.css:
(.navigation-bar > .item.console-snippets > img): Added.
(.console-user-command:not(:hover) > .console-snippet-options): Added.
(.create-snippet-popover > .label): Added.
(@media (prefers-color-scheme: dark) .navigation-bar > .item.console-snippets > img):
Add a snippets button navigation item to the Console for quick access when not in the Sources Tab.

* Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js:
(WI.OpenResourceDialog.prototype.didDismissDialog):
(WI.OpenResourceDialog.prototype.didPresentDialog):
(WI.OpenResourceDialog.prototype._handleConsoleSnippetAdded): Added.
(WI.OpenResourceDialog.prototype._handleConsoleSnippetRemoved): Added.
* Source/WebInspectorUI/UserInterface/Views/SearchSidebarPanel.js:
(WI.SearchSidebarPanel.prototype.performSearch):
Support jumping to Console Snippets.

* Source/WebInspectorUI/UserInterface/Base/ObjectStore.js:
(WI.ObjectStore._open):
Bump the version for the new `console-snippets` store.

* Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:
(WI.ButtonNavigationItem):
(WI.ButtonNavigationItem.prototype._update):
Wait to set the `title` until we know we know what `buttonStyle` we're using.

* Source/WebInspectorUI/UserInterface/Views/ConsoleCommandView.js:
(WI.ConsoleCommandView):
(WI.ConsoleCommandView.prototype.render):
Add a way for clients to add a `"click"` event listener after the command has `render()`.

* Source/WebInspectorUI/UserInterface/Views/ConsoleDrawer.css:
(.console-drawer > .navigation-bar > .item > :is(.glyph, img), .console-drawer > .navigation-bar > .log-scope-bar > li): Renamed from `.console-drawer > .navigation-bar > .item > .glyph, .console-drawer > .navigation-bar > .log-scope-bar > li`.
Allow `WI.ButtonNavigationItem.ImageType.IMG` to be clickable.

* Source/WebInspectorUI/UserInterface/Views/InputPopover.js:
(WI.InputPopover):
(WI.InputPopover.prototype.get identifier): Added.
(WI.InputPopover.prototype.get value):
(WI.InputPopover.prototype.show):
(WI.InputPopover.prototype.get result): Deleted.
It should be possible to get the `value` even if the developer has not hit enter/return.

* Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js:
(WI.ScriptContentView.prototype._handleTextEditorContentDidChange):
Debounce how often we save the current contents after modifications (to prevent swamping IndexedDB).

* Source/WebInspectorUI/UserInterface/Base/Utilities.js:
(Set.prototype.some): Added.
Add utility function that behaves just like `Array.prototype.some`.

* Source/WebInspectorUI/UserInterface/Controllers/JavaScriptLogViewController.js:
(WI.JavaScriptLogViewController):
(WI.JavaScriptLogViewController.prototype.startNewSession):
(WI.JavaScriptLogViewController.prototype.appendImmediateExecutionWithResult):
(WI.JavaScriptLogViewController.prototype.consolePromptTextCommitted):
(WI.JavaScriptLogViewController.prototype._appendConsoleMessageView):
* Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js:
(WI.DOMManager.prototype.inspectNodeObject.nodeAvailable):
* Source/WebInspectorUI/UserInterface/Views/AnimationContentView.js:
(WI.AnimationContentView.prototype._populateAnimationTargetButtonContextMenu):
* Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js:
(WI.CanvasContentView.prototype._populateCanvasElementButtonContextMenu):
* Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js:
(WI.CanvasTreeElement.prototype.populateContextMenu):
* Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js:
* Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js:
(WI.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode.node.shortestGCRootPath.):
(WI.HeapSnapshotInstanceDataGridNode.logHeapSnapshotNode):
* Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js:
(WI.ObjectPreviewView.prototype._contextMenuHandler):
* Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js:
(WI.ObjectTreeBaseTreeElement.prototype._logSymbolProperty):
(WI.ObjectTreeBaseTreeElement.prototype._logValue):
* Source/WebInspectorUI/UserInterface/Views/QuickConsole.js:
(WI.QuickConsole.prototype._handleDrop):
* Source/WebInspectorUI/UserInterface/Views/WebSocketDataGridNode.js:
(WI.WebSocketDataGridNode.prototype.appendContextMenuItems):
* Source/WebInspectorUI/UserInterface/Views/WebSocketResourceTreeElement.js:
(WI.WebSocketResourceTreeElement.prototype.populateContextMenu):
Drive-by: Rework parameters of `appendImmediateExecutionWithResult` to use an `options = {}`.

* Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js:
* Source/WebInspectorUI/UserInterface/Images/Start.svg: Added.
* Source/WebInspectorUI/UserInterface/Main.html:
* Source/WebInspectorUI/UserInterface/Test.html:

Canonical link: https://commits.webkit.org/254636@main
  • Loading branch information
dcrousso committed Sep 19, 2022
1 parent 58854f9 commit 23c03d7
Show file tree
Hide file tree
Showing 36 changed files with 679 additions and 77 deletions.
7 changes: 7 additions & 0 deletions LayoutTests/inspector/unit-tests/set-utilities-expected.txt
Expand Up @@ -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"]
Expand Down
18 changes: 18 additions & 0 deletions LayoutTests/inspector/unit-tests/set-utilities.html
Expand Up @@ -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() {
Expand Down
13 changes: 13 additions & 0 deletions Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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 <https://webkit.org/web-inspector/console-snippets/>."] = "More information is available at <https://webkit.org/web-inspector/console-snippets/>.";
localizedStrings["More information is available at <https://webkit.org/web-inspector/inspector-bootstrap-script/>."] = "More information is available at <https://webkit.org/web-inspector/inspector-bootstrap-script/>.";
localizedStrings["Multi-Entry"] = "Multi-Entry";
localizedStrings["Name"] = "Name";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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 <https://webkit.org/web-inspector/console-command-line-api/>."] = "This means all of the Console Command Line API is available <https://webkit.org/web-inspector/console-command-line-api/>.";
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";
Expand Down
5 changes: 4 additions & 1 deletion Source/WebInspectorUI/UserInterface/Base/ObjectStore.js
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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"}),
};
12 changes: 12 additions & 0 deletions Source/WebInspectorUI/UserInterface/Base/Utilities.js
Expand Up @@ -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)
Expand Down
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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",
};
Expand Up @@ -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});
});
}

Expand Down
Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions Source/WebInspectorUI/UserInterface/Images/Start.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Source/WebInspectorUI/UserInterface/Main.html
Expand Up @@ -85,6 +85,7 @@
<link rel="stylesheet" href="Views/ConsoleDrawer.css">
<link rel="stylesheet" href="Views/ConsoleMessageView.css">
<link rel="stylesheet" href="Views/ConsolePrompt.css">
<link rel="stylesheet" href="Views/ConsoleSnippetTreeElement.css">
<link rel="stylesheet" href="Views/ContentBrowser.css">
<link rel="stylesheet" href="Views/ContentBrowserTabContentView.css">
<link rel="stylesheet" href="Views/ContentView.css">
Expand Down Expand Up @@ -423,6 +424,7 @@
<script src="Models/CollectionTypes.js"></script>
<script src="Models/Color.js"></script>
<script src="Models/ConsoleCommandResultMessage.js"></script>
<script src="Models/ConsoleSnippet.js"></script>
<script src="Models/Cookie.js"></script>
<script src="Models/CookieStorageObject.js"></script>
<script src="Models/DOMBreakpoint.js"></script>
Expand Down Expand Up @@ -698,6 +700,7 @@
<script src="Views/ConsoleGroup.js"></script>
<script src="Views/ConsolePrompt.js"></script>
<script src="Views/ConsoleSession.js"></script>
<script src="Views/ConsoleSnippetTreeElement.js"></script>
<script src="Views/ContentViewContainer.js"></script>
<script src="Views/ContextMenu.js"></script>
<script src="Views/ContextMenuUtilities.js"></script>
Expand Down

0 comments on commit 23c03d7

Please sign in to comment.