Resolve applied-rule stylesheet identities through StyleSheetsActor and
include Firefox parentStyleSheet, line, and column fields on rule forms.
Firefox can then show matched rules as stylesheet rules and open the
corresponding CSS source location from the Rules panel.
Firefox keeps using the same walker after navigation and expects it to
publish the new document root.
Normal tab debugging also relies on target switching. Re-inspect the tab
when navigation finishes, replace the walker DOM data, and notify the
watcher that the previous top-level frame target was destroyed before a
fresh target becomes available.
Send target availability as a watcher event, not as the watchTargets
response, and give each navigation a new inner window id so Firefox can
associate the new target with the new document.
Firefox drops the inspector tree when a target starts navigating. Keep
navigation subscribed on the frame actor and forward the event to the
inspector so the walker can announce root-destroyed.
Clear walker DOM caches, pending mutations, picker state, and selected
node state at the same time so stale actors do not remain usable while
the new document is loading.
Firefox creates a new custom highlighter actor for each
getHighlighterByType request. Its frontend decides when to cache and
reuse those actors, while grid highlighting uses distinct actors so
multiple grids and subgrid parent overlays can remain visible at the
same time.
Match that allocation model by removing InspectorActor's server-side
highlighter cache. Also unregister highlighter actors after release or
finalize, and make each actor clear only the highlight state it owns.
Create typed highlighter actors for Firefox's highlighter requests.
The actor keeps the requested type so CssGridHighlighter can use grid
highlighting while the other highlighter types keep the existing box
model-compatible behavior.
We must reply to requests received from the client in the order they are
received. The wrench in this requirement is handling requests that must
be performed asynchronously, such as fetching the serialized DOM tree
from the WebContent process.
We currently handle this with a "block token". Async request handlers
hold a token that blocks any subsequent responses from being sent. When
that token is removed (i.e. the async request now has a response to be
sent), the async response is then sent followed by the blocked responses
in-order.
This strategy had a limitation that we could not handle an actor trying
to take 2 block tokens, meaning only one async request could be handled
at a time. This has been fine so far, but an upcoming feature (style
sheet sources) will break this limitation. The client will request N
sources at a time, which would try to take N block tokens.
The new strategy is to assign all requests an ID, and store a list of
request IDs that are awaiting a response. When the server wants to send
a reply, we match the ID of the replied-to message to this list of IDs.
If it is not the first in this list, then we are blocked waiting for an
earlier reply, and just store the response. When the earlier request(s)
receive their response, we can then send out all blocked replies (up to
the next request that has not yet received a response).
This is to prepare for an upcoming change where we will need to track
replies to messages by ID. We will be able to add parameters to this
structure without having to edit every single actor subclass header
file.
This removes some boilerplate around executing async requests, such as
calling dbgln_if on any errors, handling weak pointers to `this`, and
dealing with block tokens.
This is just to help make the message handlers a bit briefer. I had
considered adding a TRY-like macro to auto-return when the lookup fails,
but since statement expressions cannot return references, that would
result in a copy of all e.g. object and array lookups.
The "from" field is required in every response. It is the name of the
actor sending the message. This patch fills in the "from" field in the
Actor base class so that subclasses don't have to.
We will be asked for different highlighters throughout the DevTools
session, e.g. ViewportSizeOnResizeHighlighter and BoxModelHighlighter.
The latter will be responsible for rendering and overlay on DOM nodes
when the user hovers over a node in the inspector panel.
There is a lot needed all at once to actually inspect a tab's DOM tree.
It begins with requesting a "watcher" from a TabActor. It seems there
can be many types of watchers, but here we implement the "frame" watcher
only. The watcher creates an "inspector", which in turn creates a
"walker", which is the actor ultimately responsible for serializing and
inspecting the DOM tree.
In between all that, the DevTools client will send a handful of other
informational requests. If we do not reply to these, the client will not
move forward with the walker. For example, the CSSPropertiesActor will
be asked for a list of all known CSS properties.