summaryrefslogtreecommitdiffstats
path: root/devtools/client/responsive.html/docs/browser-swap.md
blob: 75055ad4ef42a1992e5a8e89638ca18e4e928ce5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Overview

The RDM tool uses several forms of tab and browser swapping to integrate the
tool UI cleanly into the browser UI.  The high level steps of this process are
documented at `/devtools/docs/responsive-design-mode.md`.

This document contains a random assortment of low level notes about the steps
the browser goes through when swapping browsers between tabs.

# Connections between Browsers and Tabs

Link between tab and browser (`gBrowser._linkBrowserToTab`):

```
aTab.linkedBrowser = browser;
gBrowser._tabForBrowser.set(browser, aTab);
```

# Swapping Browsers between Tabs

## Legend

* (R): remote browsers only
* (!R): non-remote browsers only

## Functions Called

When you call `gBrowser.swapBrowsersAndCloseOther` to move tab content from a
browser in one tab to a browser in another tab, here are all the code paths
involved:

* `gBrowser.swapBrowsersAndCloseOther`
  * `gBrowser._beginRemoveTab`
    * `gBrowser.tabContainer.updateVisibility`
    * Emit `TabClose`
    * `browser.webProgress.removeProgressListener`
    * `filter.removeProgressListener`
    * `listener.destroy`
  * `gBrowser._swapBrowserDocShells`
    * `ourBrowser.webProgress.removeProgressListener`
    * `filter.removeProgressListener`
    * `gBrowser._swapRegisteredOpenURIs`
    * `ourBrowser.swapDocShells(aOtherBrowser)`
      * Emit `SwapDocShells`
      * `PopupNotifications._swapBrowserNotifications`
      * `browser.detachFormFill` (!R)
      * `browser.swapFrameLoaders`
      * `browser.attachFormFill` (!R)
      * `browser._remoteWebNavigationImpl.swapBrowser(browser)` (R)
      * `browser._remoteWebProgressManager.swapBrowser(browser)` (R)
      * `browser._remoteFinder.swapBrowser(browser)` (R)
      * Emit `EndSwapDocShells`
    * `gBrowser.mTabProgressListener`
    * `filter.addProgressListener`
    * `ourBrowser.webProgress.addProgressListener`
  * `gBrowser._endRemoveTab`
    * `gBrowser.tabContainer._fillTrailingGap`
    * `gBrowser._blurTab`
    * `gBrowser._tabFilters.delete`
    * `gBrowser._tabListeners.delete`
    * `gBrowser._outerWindowIDBrowserMap.delete`
    * `browser.destroy`
    * `gBrowser.tabContainer.removeChild`
    * `gBrowser.tabContainer.adjustTabstrip`
    * `gBrowser.tabContainer._setPositionalAttributes`
    * `browser.parentNode.removeChild(browser)`
    * `gBrowser._tabForBrowser.delete`
    * `gBrowser.mPanelContainer.removeChild`
  * `gBrowser.setTabTitle` / `gBrowser.setTabTitleLoading`
    * `browser.currentURI.spec`
    * `gBrowser._tabAttrModified`
    * `gBrowser.updateTitlebar`
  * `gBrowser.updateCurrentBrowser`
    * `browser.docShellIsActive` (!R)
    * `gBrowser.showTab`
    * `gBrowser._appendStatusPanel`
    * `gBrowser._callProgressListeners` with `onLocationChange`
    * `gBrowser._callProgressListeners` with `onSecurityChange`
    * `gBrowser._callProgressListeners` with `onUpdateCurrentBrowser`
    * `gBrowser._recordTabAccess`
    * `gBrowser.updateTitlebar`
    * `gBrowser._callProgressListeners` with `onStateChange`
    * `gBrowser._setCloseKeyState`
    * Emit `TabSelect`
    * `gBrowser._tabAttrModified`
    * `browser.getInPermitUnload`
    * `gBrowser.tabContainer._setPositionalAttributes`
  * `gBrowser._tabAttrModified`

## Browser State

When calling `gBrowser.swapBrowsersAndCloseOther`, the browser is not actually
moved from one tab to the other.  Instead, various properties _on_ each of the
browsers are swapped.

Browser attributes `gBrowser.swapBrowsersAndCloseOther` transfers between
browsers:

* `usercontextid`

Tab attributes `gBrowser.swapBrowsersAndCloseOther` transfers between tabs:

* `usercontextid`
* `muted`
* `soundplaying`
* `busy`

Browser properties `gBrowser.swapBrowsersAndCloseOther` transfers between
browsers:

* `mIconURL`
* `getFindBar(aOurTab)._findField.value`

Browser properties `gBrowser._swapBrowserDocShells` transfers between browsers:

* `outerWindowID` in `gBrowser._outerWindowIDBrowserMap`
* `_outerWindowID` on the browser (R)
* `docShellIsActive`
* `permanentKey`
* `registeredOpenURI`

Browser properties `browser.swapDocShells` transfers between browsers:

* `_docShell`
* `_webBrowserFind`
* `_contentWindow`
* `_webNavigation`
* `_remoteWebNavigation` (R)
* `_remoteWebNavigationImpl` (R)
* `_remoteWebProgressManager` (R)
* `_remoteWebProgress` (R)
* `_remoteFinder` (R)
* `_securityUI` (R)
* `_documentURI` (R)
* `_documentContentType` (R)
* `_contentTitle` (R)
* `_characterSet` (R)
* `_contentPrincipal` (R)
* `_imageDocument` (R)
* `_fullZoom` (R)
* `_textZoom` (R)
* `_isSyntheticDocument` (R)
* `_innerWindowID` (R)
* `_manifestURI` (R)

`browser.swapFrameLoaders` swaps the actual page content.