The web-application is available here. It serves as a proof of concept, that without any Browser extension- or app- installations, tab-views can be restored (as opposed to just pop-ups and modal-views created by the parent-window). Provided below are implementation details.
Introduction:
Google's haphazard implementation and handling of browser-tab-sessions - in regards to the user interface - is a long standing problem. In 2009, Google's Chrome team posted a video showing how users could initiate auto-restoring of tab-windows.
Two years further into Google's Browser Project, the situation improved, but is still not quite on-par to the competition such as Opera and Firefox, in regards to session handling.
General considerations:
The option of restoring previously opened windows is a convenient feature for almost all Multi-Document-Interface(MDI) applications. After all, crashes happen. Yet users tend to be more forgiving if they can quickly resume their work. This generally means restoring the previous application state as complete and quick as possible. During the implementation of an Auto-Restore feature for an application two considerations are important:
During a recent crash-event, Chrome >14 proved once more it's disability to restore the previously opened tabs, with all tab vanished from the tab restore-menu. For me this is a problem, because I generally tend to have a large number of tabs open, dwelling on some tabs and backlogging others.
To autorestore all tabs, you apparently have to specifically set, this option:
The Session Saver File(s):
The majority of these are SQLite database files, with plenty of programs and restore options. Of these files, important to us will be Last Tabs. It is a binary file with some resemblance to uncompressed binary-serialization containers, using unicode for string-data. (Unicode sticks out because normal ASCII characters are followed by a binary zero \x00.) By reasoning that the file holds mostly urls, tab names and tab-session data, we would expect somewhat uniform entropy with some hills and furrows, - or appletrees and creeks to put it into a more professional-parlance.
Ent (see my previous post) fully confirmed my expectation:
The file header of Chrome's tab-session files starts with SNSS (Session Saver)
So what does this file contain. Primarily in Unicode the url, the title of the file, some flags for the tab, and if the tab was selected, which is as straightforward as 'tab-selected'. Additionally form data of tabs is stored in JSON. Entries are delimited by \x00\x00\x00.
As already mentioned, many files (almost all other files in your profiles folder) you will come accross in Chrome's user-profile-directory are actually SQLite databases - well aligned with the format used by HTML5 web-browser databases (websql). And by the way, the file Bookmarks is straightforward JSON data. Nice.
Motivation:
Besides, writing a quick parser for extracting the relevant session data from whatever binary file I would have come across (which turned out to be very 'mild' format), my secondary goal was more adventurous:
An exploration into how to handle unicode in JavaScript's native functions - something I have admittedly never done intentionally.
Javascript and unicode:
Javascript supports unicode for many years, actually unicode-support is nearing a decade.
Take this example:
"�".charCodeAt(0)
65533
d2h //function from islib
"fffd"
Putting it all together we get the original unicode character like this:
(You can get islib here. )
Using JavaScript's native FileReader, text is automatically converted to an encoding which is estimated to yield the best match. Usually this will work fine. For more information on text encoding in JS look up google 'javascript text encoding'
Applying the traditional regular expression functions to binary unicode strings is a mixed bag. Whilst it works, it tends to have problems if non-text characters are in the immediate vicinity of the search-string.
Since many urls contain themselves urls, a simple match based on the url separator pattern '://' will come up short. Rather than implementing proper matching via (at least computationally) complicated regex lookbehinds, it is usually faster by applying a map-reduce mindset to the problem.
Following is a JavaScript code excerpt of the url filter-routine:
Result:
Drag and Drop your Tabs file onto the Chrome-footer bar. This is an emulation of Chrome's version 12+ Tab Opener shown when adding a new blank tab e.g. via CTRL+T . To be precise it is an Chrome-emulation with some artistic license.
One major part of this project, is the ability to open tabs, rather than popup. This can be done by the Browser's recognition that an url was clicked by the user, as opposed to the unsupervised creation of DOMWindow instances in pure JavaScript. Even though the onclick event is overridden to capture and extend the action, tabs should be opened. Chrome's UI handles tabs via chrome.send for instance
chrome.send('reopenTab', [String(data.sessionId)]);
Problematic has been the resource-utilization of the Chrome browser, with the initial idea of using the stored favicons accessible under chrome://favicon/http://google.com/ (try clicking it; Note the RESTful accessibility). This won't even work with embedded iframes set to this url anymore due to revised XSS policies)
PS: If your file isn't corrupt you can simply overwrite the current-tabs file with your last-tabs file and restart the Browser. Get the code on github.
Introduction:
Google's haphazard implementation and handling of browser-tab-sessions - in regards to the user interface - is a long standing problem. In 2009, Google's Chrome team posted a video showing how users could initiate auto-restoring of tab-windows.
Two years further into Google's Browser Project, the situation improved, but is still not quite on-par to the competition such as Opera and Firefox, in regards to session handling.
General considerations:
The option of restoring previously opened windows is a convenient feature for almost all Multi-Document-Interface(MDI) applications. After all, crashes happen. Yet users tend to be more forgiving if they can quickly resume their work. This generally means restoring the previous application state as complete and quick as possible. During the implementation of an Auto-Restore feature for an application two considerations are important:
- Firstly, a window/document which could have potentially killed the browser or application could be restored, resulting in an unwelcoming user-problem of revisiting the same problem over and over again. This is often handled by a flag, which counts repetitive crashes, and then prevents restoring. Application termination most often occurs either through an action that led the OS Kernel to terminate the running application-thread and with it, the entire application stack, or a Kernel exception or a physical action such as a Harddrive failure or power outage.
- Secondly, without proper thread management, the application - especially when multithreaded (now often the case for MDIs) could take up all processing resources, bringing user-interactions with the desktop to grinding speeds. A simple solution is to change the application's process priority to a lower priority than the process-priority of the application once all windows are loaded.
Fig1. Chrome no longer showing the previous tabs, after a crash. |
During a recent crash-event, Chrome >14 proved once more it's disability to restore the previously opened tabs, with all tab vanished from the tab restore-menu. For me this is a problem, because I generally tend to have a large number of tabs open, dwelling on some tabs and backlogging others.
To autorestore all tabs, you apparently have to specifically set, this option:
Fig2 autorestore option in Chrome |
Setting this option, will however not change what Chrome saves in its session files. Rather, the only difference is that now you won't be given the chance to open the last tab-session yourself, but all tabs will be loaded as soon as you start Chrome, - something that kept me from using this option.
Notwithstanding Google's choice of tab-configuration implementations, the good news is that no data is lost. This cannot be understated: all tab data is saved. In fact have a look right now into your Chrome's Application Data folder (on Windows: c:\Users\%USER%\AppData\Local\Google\Chrome\User Data\, on Linux: ~/.config/google-chrome/Default) and sort by last modifications (Linux: ls -tr)
There, you will find listed a bunch of files, lacking any extension:
- Cookies
- Current Session
- Last Session
- Current Tabs
- Last Tabs
The Session Saver File(s):
The majority of these are SQLite database files, with plenty of programs and restore options. Of these files, important to us will be Last Tabs. It is a binary file with some resemblance to uncompressed binary-serialization containers, using unicode for string-data. (Unicode sticks out because normal ASCII characters are followed by a binary zero \x00.) By reasoning that the file holds mostly urls, tab names and tab-session data, we would expect somewhat uniform entropy with some hills and furrows, - or appletrees and creeks to put it into a more professional-parlance.
Ent (see my previous post) fully confirmed my expectation:
Entropy of the file 'Last Session'(1062045 By) is: 00,48
The total length is: 1062045 By; Accumulative entropy is: 00,48
Shannon Index of the data(1062045By) is: 02,68
Shannon's equitability (EH) is:00,55
The maximum segmental-entropy (17700By) is: 0,5388829
0,50 | ▓▓
0,45 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓ ▓▓▓
0,40 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓
0,35 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,30 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,25 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,20 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,15 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,10 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,05 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
0,00 | ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
------------------------------------------------------------------
0% 16% 33% 50% 66% 83%
The file header of Chrome's tab-session files starts with SNSS (Session Saver)
Fig3. Showing Chrome's Session Saver file header |
As already mentioned, many files (almost all other files in your profiles folder) you will come accross in Chrome's user-profile-directory are actually SQLite databases - well aligned with the format used by HTML5 web-browser databases (websql). And by the way, the file Bookmarks is straightforward JSON data. Nice.
Motivation:
Besides, writing a quick parser for extracting the relevant session data from whatever binary file I would have come across (which turned out to be very 'mild' format), my secondary goal was more adventurous:
An exploration into how to handle unicode in JavaScript's native functions - something I have admittedly never done intentionally.
Javascript and unicode:
Javascript supports unicode for many years, actually unicode-support is nearing a decade.
Take this example:
"�".charCodeAt(0)
65533
d2h //function from islib
"fffd"
Putting it all together we get the original unicode character like this:
(You can get islib here. )
Using JavaScript's native FileReader, text is automatically converted to an encoding which is estimated to yield the best match. Usually this will work fine. For more information on text encoding in JS look up google 'javascript text encoding'
Applying the traditional regular expression functions to binary unicode strings is a mixed bag. Whilst it works, it tends to have problems if non-text characters are in the immediate vicinity of the search-string.
Since many urls contain themselves urls, a simple match based on the url separator pattern '://' will come up short. Rather than implementing proper matching via (at least computationally) complicated regex lookbehinds, it is usually faster by applying a map-reduce mindset to the problem.
Following is a JavaScript code excerpt of the url filter-routine:
An interesting find whilst browsing the url contained in the session file, was that Google-Docs comes close to the 1600 character limit that can be transmitted by an url via GET. In my instance, I have seen a google-docs url stretching over 1400 characters. (These are iframe-urls, which normally escape one's attention. )
Result:
Drag and Drop your Tabs file onto the Chrome-footer bar. This is an emulation of Chrome's version 12+ Tab Opener shown when adding a new blank tab e.g. via CTRL+T . To be precise it is an Chrome-emulation with some artistic license.
One major part of this project, is the ability to open tabs, rather than popup. This can be done by the Browser's recognition that an url was clicked by the user, as opposed to the unsupervised creation of DOMWindow instances in pure JavaScript. Even though the onclick event is overridden to capture and extend the action, tabs should be opened. Chrome's UI handles tabs via chrome.send for instance
chrome.send('reopenTab', [String(data.sessionId)]);
Problematic has been the resource-utilization of the Chrome browser, with the initial idea of using the stored favicons accessible under chrome://favicon/http://google.com/ (try clicking it; Note the RESTful accessibility). This won't even work with embedded iframes set to this url anymore due to revised XSS policies)
PS: If your file isn't corrupt you can simply overwrite the current-tabs file with your last-tabs file and restart the Browser. Get the code on github.