зеркало из https://github.com/mozilla/gecko-dev.git
71 строка
3.2 KiB
Markdown
71 строка
3.2 KiB
Markdown
|
# Responsive Design Mode Architecture
|
||
|
|
||
|
## Context
|
||
|
|
||
|
You have a single browser tab that has visited several pages, and now has a
|
||
|
history that looks like, in oldest to newest order:
|
||
|
|
||
|
1. https://newsblur.com
|
||
|
2. https://mozilla.org (← current page)
|
||
|
3. https://convolv.es
|
||
|
|
||
|
## Opening RDM During Current Firefox Session
|
||
|
|
||
|
When opening RDM, the browser tab's history must preserved. Additionally, we
|
||
|
strive to preserve the exact state of the currently displayed page (effectively
|
||
|
any in-page state, which is important for single page apps where data can be
|
||
|
lost if they are reloaded).
|
||
|
|
||
|
This seems a bit convoluted, but one advantage of this technique is that it
|
||
|
preserves tab state since the same tab is reused. This helps to maintain any
|
||
|
extra state that may be set on tab by add-ons or others.
|
||
|
|
||
|
1. Create a temporary, hidden tab to load the tool UI.
|
||
|
2. Mark the tool tab browser's docshell as active so the viewport frame is
|
||
|
created eagerly and will be ready to swap.
|
||
|
3. Create the initial viewport inside the tool UI.
|
||
|
4. Swap tab content from the regular browser tab to the browser within the
|
||
|
viewport in the tool UI, preserving all state via
|
||
|
`gBrowser._swapBrowserDocShells`.
|
||
|
5. Force the original browser tab to be non-remote since the tool UI must be
|
||
|
loaded in the parent process, and we're about to swap the tool UI into
|
||
|
this tab.
|
||
|
6. Swap the tool UI (with viewport showing the content) into the original
|
||
|
browser tab and close the temporary tab used to load the tool via
|
||
|
`swapBrowsersAndCloseOther`.
|
||
|
7. Start a tunnel from the tool tab's browser to the viewport browser
|
||
|
so that some browser UI functions, like navigation, are connected to
|
||
|
the content in the viewport, instead of the tool page.
|
||
|
|
||
|
## Closing RDM During Current Firefox Session
|
||
|
|
||
|
To close RDM, we follow a similar process to the one from opening RDM so we can
|
||
|
restore the content back to a normal tab.
|
||
|
|
||
|
1. Stop the tunnel between outer and inner browsers.
|
||
|
2. Create a temporary, hidden tab to hold the content.
|
||
|
3. Mark the content tab browser's docshell as active so the frame is created
|
||
|
eagerly and will be ready to swap.
|
||
|
4. Swap tab content from the browser within the viewport in the tool UI to the
|
||
|
regular browser tab, preserving all state via
|
||
|
`gBrowser._swapBrowserDocShells`.
|
||
|
5. Force the original browser tab to be remote since web content is loaded in
|
||
|
the child process, and we're about to swap the content into this tab.
|
||
|
6. Swap the content into the original browser tab and close the temporary tab
|
||
|
used to hold the content via `swapBrowsersAndCloseOther`.
|
||
|
|
||
|
## Session Restore
|
||
|
|
||
|
When restarting Firefox and restoring a user's browsing session, we must
|
||
|
correctly restore the tab history. If the RDM tool was opened when the session
|
||
|
was captured, then it would be acceptable to either:
|
||
|
|
||
|
* A: Restore the tab content without any RDM tool displayed **OR**
|
||
|
* B: Restore the RDM tool the tab content inside, just as before the restart
|
||
|
|
||
|
We currently follow path A (no RDM after session restore), which seems more in
|
||
|
line with how the rest of DevTools currently functions after restore. To do so,
|
||
|
we watch for `beforeunload` events on the tab at shutdown and quickly exit RDM
|
||
|
so that session restore records only the original page content during its final
|
||
|
write at shutdown.
|