Skip to content

Commit

Permalink
Restore extension tab after reload
Browse files Browse the repository at this point in the history
Work-around for https://crbug.com/511670
  • Loading branch information
Rob--W committed Aug 14, 2015
1 parent cf1d398 commit 4ac8863
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
22 changes: 22 additions & 0 deletions extensions/chromium/extension-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ limitations under the License.

// When session restore is used, viewer pages may be loaded before the
// webRequest event listener is attached (= page not found).
// Or the extension could have been crashed (OOM), leaving a sad tab behind.
// Reload these tabs.
chrome.tabs.query({
url: CRX_BASE_URL + '*:*'
Expand All @@ -92,4 +93,25 @@ limitations under the License.
}
});
console.log('Set up extension URL router.');

Object.keys(localStorage).forEach(function(key) {
// The localStorage item is set upon unload by chromecom.js.
var parsedKey = /^unload-(\d+)-(true|false)-(.+)/.exec(key);
if (parsedKey) {
var timeStart = parseInt(parsedKey[1], 10);
var isHidden = parsedKey[2] === 'true';
var url = parsedKey[3];
if (Date.now() - timeStart < 3000) {
// Is it a new item (younger than 3 seconds)? Assume that the extension
// just reloaded, so restore the tab (work-around for crbug.com/511670).
chrome.tabs.create({
url: chrome.runtime.getURL('restoretab.html') +
'?' + encodeURIComponent(url) +
'#' + encodeURIComponent(localStorage.getItem(key)),
active: !isHidden
});
}
localStorage.removeItem(key);
}
});
})();
17 changes: 17 additions & 0 deletions extensions/chromium/restoretab.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<!--
Copyright 2015 Mozilla Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script src="restoretab.js"></script>
33 changes: 33 additions & 0 deletions extensions/chromium/restoretab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/*
Copyright 2015 Mozilla Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
* This is part of the work-around for crbug.com/511670.
* - chromecom.js sets the URL and history state upon unload.
* - extension-router.js retrieves the saved state and opens restoretab.html
* - restoretab.html (this script) restores the URL and history state.
*/
'use strict';

var url = decodeURIComponent(location.search.slice(1));
var historyState = decodeURIComponent(location.hash.slice(1));

historyState = historyState === 'undefined' ? null : JSON.parse(historyState);

history.replaceState(historyState, null, url);
location.reload();
17 changes: 17 additions & 0 deletions web/chromecom.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,23 @@ var ChromeCom = (function ChromeComClosure() {
});
}

if (window === top) {
// Chrome closes all extension tabs (crbug.com/511670) when the extension
// reloads. To counter this, the tab URL and history state is saved to
// localStorage and restored by extension-router.js.
// Unfortunately, the window and tab index are not restored. And if it was
// the only tab in an incognito window, then the tab is not restored either.
addEventListener('unload', function() {
// If the runtime is still available, the unload is most likely a normal
// tab closure. Otherwise it is most likely an extension reload.
if (!isRuntimeAvailable()) {
localStorage.setItem(
'unload-' + Date.now() + '-' + document.hidden + '-' + location.href,
JSON.stringify(history.state));
}
});
}

// This port is used for several purposes:
// 1. When disconnected, the background page knows that the frame has unload.
// 2. When the referrer was saved in history.state.chromecomState, it is sent
Expand Down

0 comments on commit 4ac8863

Please sign in to comment.