|
1 | 1 |
|
2 | 2 | (async function () { |
3 | | - |
4 | | - /* Utility */ |
5 | | - const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); |
6 | | - |
7 | 3 | /* For folder sorting */ |
8 | 4 |
|
9 | 5 | const Cc = Components.classes; |
|
161 | 157 | }; |
162 | 158 | myPrefObserver.register(); |
163 | 159 |
|
164 | | - /* Refresh pane */ |
165 | | - let refreshCount = 0; |
166 | | - for (let win of Services.wm.getEnumerator("mail:3pane")) { |
167 | | - ++refreshCount; |
| 160 | + /* Startup folder */ |
| 161 | + let startup_folder = tbsf_prefs.getStringPref("startup_folder"); |
| 162 | + if (startup_folder) { |
| 163 | + tblog.debug("startup folder: "+startup_folder); |
| 164 | + } else { |
| 165 | + tblog.debug("No startup folder specified"); |
168 | 166 | } |
169 | | - tblog.debug("Refresh pane ("+refreshCount+")"); |
170 | | - function refreshPane(win) { |
171 | | - try { |
172 | | - win.gFolderTreeView._rebuild(); |
173 | | - --refreshCount; |
174 | | - } catch (e) { |
175 | | - setTimeout(refreshPane, 5, win); |
| 167 | + |
| 168 | + if (startup_folder && ThunderbirdMajorVersion < 98) { |
| 169 | + /* |
| 170 | + On Thunderbird 97 and earlier, it was possible for add-ons to intervene in |
| 171 | + the startup behavior of Thunderbird. |
| 172 | + */ |
| 173 | + const oldRestoreTab = mailTabType.modes.folder.restoreTab; |
| 174 | + let inRestoreTab = false; |
| 175 | + mailTabType.modes.folder.restoreTab = function (x, y) { |
| 176 | + tblog.debug("restoreTab"); |
| 177 | + inRestoreTab = true; |
| 178 | + oldRestoreTab.call(this, x, y); |
| 179 | + inRestoreTab = false; |
| 180 | + }; |
| 181 | + const oldSelectFolder = gFolderTreeView.selectFolder; |
| 182 | + const change_folder = startup_folder; |
| 183 | + let firstRun = true; |
| 184 | + gFolderTreeView.selectFolder = function (x, y) { |
| 185 | + tblog.debug("selectFolder firstRun:"+firstRun.toString()+" inRestoreTab:"+inRestoreTab.toString()); |
| 186 | + if (firstRun && inRestoreTab) { |
| 187 | + const folder = MailUtils.getExistingFolder(change_folder); |
| 188 | + if (folder) { |
| 189 | + oldSelectFolder.call(this, folder, true); |
| 190 | + /* Ensures that the selected folder is on the screen. */ |
| 191 | + const selected = gFolderTreeView.getSelectedFolders()[0]; |
| 192 | + if (selected) { |
| 193 | + gFolderTreeView._treeElement.ensureRowIsVisible(gFolderTreeView.getIndexOfFolder(selected)); |
| 194 | + } |
| 195 | + } else { |
| 196 | + oldSelectFolder.call(this, x, y); |
| 197 | + } |
| 198 | + firstRun = false; |
| 199 | + } else { |
| 200 | + oldSelectFolder.call(this, x, y); |
| 201 | + } |
176 | 202 | } |
| 203 | + tblog.debug("Overriding selectFolder"); |
| 204 | + startup_folder = null; |
177 | 205 | } |
178 | | - for (let win of Services.wm.getEnumerator("mail:3pane")) { |
179 | | - refreshPane(win); |
| 206 | + |
| 207 | + /* |
| 208 | + Refresh pane and select folder |
| 209 | +
|
| 210 | + The start of this add-on may be too early to call gFolderTreeView._rebuild() |
| 211 | + and MailUtils.getExistingFolder(). |
| 212 | +
|
| 213 | + So I structured a 10-times retry loop to counter any exceptions or failures |
| 214 | + that may occur due to that. |
| 215 | + */ |
| 216 | + async function selectFolder(win, startup_folder) { |
| 217 | + let tries = 0; |
| 218 | + let ms = 100; |
| 219 | + |
| 220 | + // Stop after 10 tries. Or use other break condition, like total time spend. |
| 221 | + while (tries < 10) { |
| 222 | + try { |
| 223 | + /* |
| 224 | + Refresh pane -- possible exception. |
| 225 | + */ |
| 226 | + win.gFolderTreeView._rebuild(); |
| 227 | + if (startup_folder) { |
| 228 | + /* |
| 229 | + Select folder |
| 230 | + Since Thunderbird 98, add-on startup has been delayed until |
| 231 | + Thunderbird is mostly done. So there is no way other than |
| 232 | + immediately selecting the folder. However, there is a report of a |
| 233 | + case where getExistingFolder returns null for the existing folder. |
| 234 | + */ |
| 235 | + let folder = MailUtils.getExistingFolder(startup_folder); |
| 236 | + if (folder && gFolderTreeView.selectFolder(folder, true)) { |
| 237 | + return true; |
| 238 | + } |
| 239 | + } else { |
| 240 | + return true; |
| 241 | + } |
| 242 | + } catch (e) { |
| 243 | + // Nothing. |
| 244 | + } |
| 245 | + tries++; |
| 246 | + await new Promise(resolve => setTimeout(resolve, ms)); |
| 247 | + } |
| 248 | + return false; |
180 | 249 | } |
181 | | - while (refreshCount > 0) { |
182 | | - await sleep(10); |
| 250 | + |
| 251 | + let selectPromises = []; |
| 252 | + for (let win of Services.wm.getEnumerator("mail:3pane")) { |
| 253 | + selectPromises.push(selectFolder(win, startup_folder)); |
183 | 254 | } |
184 | 255 |
|
| 256 | + let results = await Promise.all(selectPromises); |
| 257 | + tblog.debug("Refreshing the pane" |
| 258 | + + (startup_folder ? " and selecting folder" : "") |
| 259 | + + ": " |
| 260 | + + (results ? "Success" : "Failure")); |
| 261 | + |
185 | 262 | /* Ensures that the selected folder is on the screen. */ |
186 | 263 | { |
187 | 264 | const selected = gFolderTreeView.getSelectedFolders()[0]; |
|
190 | 267 | } |
191 | 268 | } |
192 | 269 |
|
193 | | - /* For default startup folder */ |
194 | | - const startup_folder = tbsf_prefs.getStringPref("startup_folder"); |
195 | | - if (startup_folder) { |
196 | | - tblog.debug("startup folder: "+startup_folder); |
197 | | - if (ThunderbirdMajorVersion < 98) { |
198 | | - /* |
199 | | - On Thunderbird 97 or older, it was possible for add-ons |
200 | | - to intervene in the startup behavior of Thunderbird. |
201 | | - */ |
202 | | - const oldRestoreTab = mailTabType.modes.folder.restoreTab; |
203 | | - let inRestoreTab = false; |
204 | | - mailTabType.modes.folder.restoreTab = function (x, y) { |
205 | | - tblog.debug("restoreTab"); |
206 | | - inRestoreTab = true; |
207 | | - oldRestoreTab.call(this, x, y); |
208 | | - inRestoreTab = false; |
209 | | - }; |
210 | | - const oldSelectFolder = gFolderTreeView.selectFolder; |
211 | | - let firstRun = true; |
212 | | - gFolderTreeView.selectFolder = function (x, y) { |
213 | | - tblog.debug("selectFolder firstRun:"+firstRun.toString()+" inRestoreTab:"+inRestoreTab.toString()); |
214 | | - if (firstRun && inRestoreTab) { |
215 | | - const folder = MailUtils.getExistingFolder(startup_folder); |
216 | | - if (folder) |
217 | | - oldSelectFolder.call(this, folder, true); |
218 | | - else |
219 | | - oldSelectFolder.call(this, x, y); |
220 | | - firstRun = false; |
221 | | - } else { |
222 | | - oldSelectFolder.call(this, x, y); |
223 | | - } |
224 | | - } |
225 | | - } else { |
226 | | - /* |
227 | | - Since Thunderbird 98, add-on startup has been delayed until Thunderbird is mostly done. |
228 | | - So there is no way other than immediately selecting the folder. |
229 | | - */ |
230 | | - const retryMax = 10; |
231 | | - for (let retry = 1; retry <= retryMax; retry++) { |
232 | | - let folder = MailUtils.getExistingFolder(startup_folder); |
233 | | - if (folder) { |
234 | | - if (gFolderTreeView.selectFolder(folder, true)) { |
235 | | - tblog.debug("selectFolder succeeded"); |
236 | | - } else { |
237 | | - tblog.debug("selectFolder failed"); |
238 | | - } |
239 | | - break; |
240 | | - } else { |
241 | | - if (retry < retryMax) { |
242 | | - tblog.debug(startup_folder+" not found ("+retry+") ..retry"); |
243 | | - await sleep(200); |
244 | | - } else { |
245 | | - tblog.debug(startup_folder+" not found ("+retry+") ..giving up"); |
246 | | - } |
247 | | - } |
248 | | - } |
249 | | - } |
250 | | - } else { |
251 | | - tblog.debug("No startup folder specified"); |
252 | | - } |
253 | | - |
254 | 270 | tblog.debug("Init done"); |
255 | 271 |
|
256 | 272 | })() |
0 commit comments