Closed Bug 1947667 Opened 8 months ago Closed 7 months ago

Custom Formatters (devtoolsFormatters) break the "Copy Object" context menu item, causing it to copy (portions of) the displayed text content and not the actual logged object

Categories

(DevTools :: Console, defect, P3)

Firefox 135
defect

Tracking

(firefox138 fixed)

RESOLVED FIXED
138 Branch
Tracking Status
firefox138 --- fixed

People

(Reporter: cob.bzmoz, Assigned: cob.bzmoz)

Details

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0

Steps to reproduce:

Implement a basic Custom Formatter via the Custom Formatters API (devtoolsFormatters). Log an object to the console which is affected by the custom formatter. Right-click on the logged message and select "Copy Object." Go to any text editor (e.g. Notepad) and paste into it to see what you copied.

The attached file contains a simplified test-case: a custom formatter is installed, and a simple object literal is logged when the page loads. You can right-click on any part of the logged message (whether you expand it first doesn't matter) and click "Copy Object."

Actual results:

You will copy the textContent of whatever DOM node, within the custom-formatted output, you right-clicked on. Using the attached file as an example, if you right-clicked on the green "World!" text, then you will copy "World!" to the clipboard.

Expected results:

You should copy the exact same text as would be copied if the logged object didn't use a custom formatter, e.g. a JSON serialization of the logged object, because the context menu item that you clicked was labeled "Copy Object," not "Copy Message," much less "Copy This One Specific Portion Of The Logged Message."

The code which sets up the context menu is createContextMenu in /devtools/client/webconsole/utils/context-menu.js. On line 65 we see that the variableText variable is set to the textContent of whatever specific DOM node you right-clicked on. On line 73, we see that console log messages are associated with "actors" (logged objects) based on whether the messages have a data-link-actor-id attribute.

The "Copy Object" context menu item is enabled if there exists variableText or an "actor", with the item coded to copy the actor if one exists or the variableText otherwise (the choice between the two is implemented here). Looking upward a bit, we also see that "Store as global variable" is only enabled if there exists an actor, and sure enough, custom-formatted messages also disable the "Store as global variable" option in addition to causing "Copy Object" to malfunction. (In essence, I think "Copy Object" being broken and "Store as global variable" being unavailable are the same bug.)

You can also observe, by using the Browser Toolbox to run devtools on the devtools, that the data-link-actor-id attribute isn't present anywhere within the custom-formatted log message.

Unfortunately, I couldn't find where the actor ID gets lost -- where the devtools forget to write it into their DOM.

From what I can understand after digging around the devtools source (both now and in the past), "rep" objects define the visual representation of some object within the devtools console (or debugger, or anywhere else that JS values may be displayed I guess). Per the comments on getRep (defined here), a "grip" is a "handle to a remote debuggee object," e.g. JavaScript objects and DOM nodes in the page being debugged.

The default GripRep is one of the few places that actually uses the data-link-actor-id within Firefox's source code. The CustomFormatter rep, by contrast, does not.

When the devtools want to log an object, they start by choosing between the reps and noGripReps lists of possible reps to use. (CustomFormatter is only added to reps when custom formatting is enabled, in which case it goes at the very start of that list.) After choosing one of those lists, getRep loops through it and chooses the first rep that claims to support the to-be-displayed entity. CustomFormatter supports any entity that opts into custom formatting and has a custom-formatted header.

It seems to me like fixing this would have something to do with having CustomFormatter.prototype.render check this.props.object.actor and log the actor ID. However, I'm not familiar enough with the overall architecture of the devtools to know if that would work (e.g. if the object in question has an actor ID at the time that that function would run, versus if an actor ID has to be given to it somehow).

(It sucks not to have an edit button.)

To hopefully make my last comment clearer: I believe the render method on CustomFormatter needs to be updated to set the data-link-actor-id in the same manner that GripRep does. GripRep acts on the assumption that the object already has an actor ID. If the object would also have an actor ID when run through CustomFormatter, then the fix for this bug might be as simple as adding the following line after both line 103 and line 120 of the CustomFormatter source file, if I'm properly understanding the minutiae of how these reps are implemented:

"data-link-actor-id": this.props.object.actor,
Component: Untriaged → Console
Product: Firefox → DevTools
Severity: -- → S3
Priority: -- → P3

Cob, since you ran an extensive investigation here, would you try to fix the bug yourself?
We have some documentation on how to get started: https://firefox-source-docs.mozilla.org/devtools/index.html

If you don't want or don't have the time, that's fine, I'll look at the bug myself

Flags: needinfo?(cob.bzmoz)

Wish I could, but no time right now, sorry. Ran into this while working on something for another programming project, which I'm still actively dealing with.

Thanks for the link, though; I'll keep it open in Firefox along with the instructions for building on Windows. If I find time to set up a Firefox dev environment down the road, and this bug is still open by then, I'll see what I can do about it at that time.

Flags: needinfo?(cob.bzmoz)
Assignee: nobody → cob.bzmoz
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Pushed by nchevobbe@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/b69a4de1e95b CustomFormatter component now uses "data-link-actor-id" attribute. r=devtools-reviewers,nchevobbe
Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 138 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: