PK
6 content/PK
6 content/tabmixplus/PK
t5pHE E content/tabmixplus/about.xul
%aboutDTD;
%miscDTD;
]>
PK
3+w00
content/tabmixplus/contents.rdf
chrome://tabmixplus/content/pref/preferencesOverlay.xul
chrome://tabmixplus/content/tabmix.xul
chrome://tabmixplus/content/links/links.xul
chrome://tabmixplus/content/bookmarks/bookmarks.xul
chrome://tabmixplus/content/bookmarks/bookmarksManager.xul
chrome://tabmixplus/content/links/links.xul
chrome://tabmixplus/content/links/links.xul
chrome://tabmixplus/content/history/history-panel.xul
PK
}d6zۺ}O O content/tabmixplus/tabmix.js/*
* tabmix.js
*
* original code by Hemiola SUN, further developed by onemen and CPU
*/
var gPref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var gIsOldBrowser = typeof(Components.interfaces.nsIXULAppInfo) == "undefined";
var gIsFirefox2 = typeof(BrowserOpenAddonsMgr) == "function";
var gIsPlaces = typeof(PlacesController) == "function" && typeof(BookmarksCommand) != "object";
var gChromeDir;
function TM_init()
{
// move this to TMP_Places.init() when places will land
if (typeof(PlacesController) == "function")
document.getElementById("goPopup").addEventListener("popupshowing", setHistoryMenuItemsTitle, false);
var historyMenu = document.getElementById("goPopup").parentNode;
if (gIsPlaces) {
TMP_Places.init();
// history menu open in new tab if the curren tab is locked
if (historyMenu)
historyMenu.setAttribute("oncommand", "TMP_Places.historyMenu(event);");
}
else {
Click2TabLoadBookmark.init();
if (historyMenu)
historyMenu.setAttribute("oncommand", "var url = event.target.getAttribute('statustext'); if (url) {openUILinkIn(url, whereToOpenLinkTabmix(event, prefStringTMHistory)); content.focus();}");
}
// disable the "Open New Window action in Single Window Mode...
var cmdNewWindow = document.getElementById("cmd_newNavigator");
var originalNewNavigator = cmdNewWindow.getAttribute("oncommand");
cmdNewWindow.setAttribute("oncommand","if (gSingleWindowMode) BrowserOpenTab(); else {" + originalNewNavigator + "}");
// replace browser handlers with ours so it recognizes when tabs are acted on
gBrowser.onTabBarDblClick = TM_onTabBarDblClick;
gBrowser.onTabClick = TM_checkClick;
if (gIsOldBrowser)
gBrowser.updateContextTab = TMupdateContextTab;
gBrowser.mTabBox.insertBefore(document.getElementById('vide-bar'), gBrowser.mTabBox.firstChild);
gBrowser.closedTabs = [];
document.getElementById("content").onresize = tabBarWidthChange;
document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", TM_checkContentMenu, false);
var tabContextMenu = gBrowser.mStrip.firstChild.nextSibling;
tabContextMenu.setAttribute("onpopuphidden", tabContextMenu.getAttribute("onpopuphidden") + "if (event.target == this) TM_hidePopup();");
tabContextMenu.addEventListener("popupshowing", Tm_checkTabClick, false);
tabContextMenu.addEventListener("popupshown", TMP_tabContextMenuShown, false);
// override some of All-in-One Gestures function
// override the duplicate tab function
if (typeof aioDupTab == 'function')
aioDupTab = function() { gBrowser.duplicateTab(gBrowser.mCurrentTab); };
//override the duplicate in new window function
if (typeof aioDupWindow == 'function')
aioDupWindow = function() { gBrowser.duplicateInWindow(gBrowser.mCurrentTab); };
//override the aioCloseWindow function
if (typeof aioCloseWindow == 'function')
aioCloseWindow = BrowserTryToCloseWindow;
// for session manager
window.setTimeout( function () {
SessionManager.init();
gBrowser.mTabContainer.nextTab = 1;
if (gIsFirefox2)
getClosedTabs(); // XXX temp -- get closed-tabs from nsSessionStore
var aTab = gBrowser.mTabContainer.firstChild;
if (aTab != gBrowser.mCurrentTab) {
aTab.removeAttribute("selected");
aTab.removeAttribute("flst_id");
};
}, 0 );
//Browser:Home open in new tab if the curren tab is locked
window.BrowserHome = TM_BrowserHome;
// add tooltip to close tab button on tab for firefox 1.5 +
if (typeof(Components.interfaces.nsIXULAppInfo) != "undefined")
gBrowser.mStrip.firstChild.setAttribute("onpopupshowing","return this.parentNode.parentNode.parentNode.TMP_createTooltip(event);");
//fix Typo: extensions.tabmix.cloesedWinToolsMenu should be extensions.tabmix.closedWinToolsMenu.
//version tabmix 0.3 befor 2005-11-28
var oldPref = "extensions.tabmix.cloesedWinToolsMenu";
var newPref = "extensions.tabmix.closedWinToolsMenu";
if (gPref.prefHasUserValue(oldPref)) {
gPref.setBoolPref(newPref, false); // default is true
gPref.clearUserPref(oldPref)
}
// add call to TMP_Sanitizer
// nsBrowserGlue.js use loadSubScript to load Sanitizer so we need to add this here
var cmd = document.getElementById("Tools:Sanitize");
if (cmd)
cmd.setAttribute("oncommand", cmd.getAttribute("oncommand") + " TMP_Sanitizer.tryToSanitize();");
// if sessionStore disabled use TMP command
cmd = document.getElementById("History:UndoCloseTab");
if (cmd)
cmd.setAttribute("oncommand", "TMP_ClosedTabs.undoCloseTab();");
// Look for RSS/Atom News Reader
TMP_LookForRSS();
}
function TM_deinit ()
{
if (!gBrowser.mStrip.hasAttribute("ondraggesture")) {
gBrowser.mStrip.removeEventListener("draggesture", TMP_TabDragGesture, true);
gBrowser.mStrip.removeEventListener("dragover", TMP_TabDragOver, true);
gBrowser.mStrip.removeEventListener("dragdrop", TMP_TabDragDrop, true);
gBrowser.mStrip.removeEventListener("dragexit", TMP_TabDragExit, true);
}
if ("mTabDropIndicatorBar" in gBrowser) {
gBrowser.mTabDropIndicatorBar.removeEventListener('dragover', TMP_TabDragOver, true);
gBrowser.mTabDropIndicatorBar.removeEventListener('dragdrop', TMP_TabDragDrop, true);
}
if (typeof(PlacesController) == "function")
document.getElementById("goPopup").removeEventListener("popupshowing", setHistoryMenuItemsTitle, false);
SessionManager.deinit(numberOfWindows() == 0, false);
document.getElementById("contentAreaContextMenu").removeEventListener("popupshowing", TM_checkContentMenu, false);
var tabContextMenu = gBrowser.mStrip.firstChild.nextSibling;
tabContextMenu.removeEventListener("popupshowing", Tm_checkTabClick, false);
tabContextMenu.removeEventListener("popupshown", TMP_tabContextMenuShown, false);
TMP_LastTab.deinit();
tabxOnClose();
TMP_TBP_exit();
tabxPrefObserver.removeObserver();
window.removeEventListener("unload", TM_deinit, false);
}
// Create new items in the context menu of tab bar
var newMenuItems = ["tm-duplicateTab","tm-duplicateinWin","tm-detachTab","tm-mergeWindowsTab","tm-renameTab",
"tm-copyTabUrl", "tm-autoreloadTab_menu", "tm-reloadOther","tm-reloadLeft","tm-reloadRight","tm-separator",
"tm-undoCloseTab","tm-undoCloseList","tm-separator-2",
"tm-closeAllTabs","tm-closeSimilar","tm-closeLeftTabs","tm-closeRightTabs",
"tm-docShell","tm-freezeTab","tm-protectTab","tm-lockTab"];
var newMenuOrders = [ 1, 2, 3, 4, 5, 6,
9, 11, 12, 13, 14,
15, 16, 17,
19, 20, 22, 23,
25, 26, 27, 28];
function TM_creatMenuItems () {
var tabContextMenu = window.getBrowser().mStrip.firstChild.nextSibling;
tabContextMenu.setAttribute("id", "menuedit-tabContextMenu");
var menuItems = tabContextMenu.childNodes;
var i, separator = 0;
for ( i = 0; i < menuItems.length; i++ ) {
if (menuItems[i].hasAttribute("id"))
continue;
else if (menuItems[i].localName == "menuseparator")
menuItems[i].setAttribute("id", "original-separator-" + separator++);
else if (menuItems[i].hasAttribute("xbl:inherits")) {
if (menuItems[i].getAttribute("xbl:inherits") == "oncommand=onnewtab") {
menuItems[i].setAttribute("id", "tm-newtab");
// menuItems[i].setAttribute("oncommand", "var tabbrowser = this.parentNode.parentNode.parentNode.parentNode; TMP_BrowserOpenTab(tabbrowser.mContextTab);");
menuItems[i].setAttribute("oncommand", "TMP_BrowserOpenTab();");
menuItems[i].setAttribute("_newtab", menuItems[i].getAttribute("label"));
menuItems[i].setAttribute("_afterthis", document.getElementById("tm-separator").getAttribute("_afterthis"));
menuItems[i].removeAttribute("xbl:inherits");
}
}
else {
var aCommand = menuItems[i].getAttribute("oncommand");
if (aCommand.indexOf("reloadTab") != -1 ) menuItems[i].setAttribute("id", "tm-reloadTab");
else if (aCommand.indexOf("reloadAllTabs") != -1 ) menuItems[i].setAttribute("id", "tm-reloadAllTabs");
else if (aCommand.indexOf("removeAllTabsBut") != -1 ) menuItems[i].setAttribute("id", "tm-removeAllTabsBut");
else if (aCommand.indexOf("removeTab") != -1 ) menuItems[i].setAttribute("id", "tm-removeTab");
else if (aCommand.indexOf("BookmarkThisTab") != -1 ) menuItems[i].setAttribute("id", "tm-addBookmarkAs");
else if (menuItems[i].hasAttribute("command"))
if (menuItems[i].getAttribute("command") == "Browser:BookmarkAllTabs") menuItems[i].setAttribute("id", "tm-bookmarkAllTabs");
}
}
// group the close-tab options together
var closeTab = document.getElementById("tm-removeTab");
var closeOther = document.getElementById("tm-removeAllTabsBut");
tabContextMenu.insertBefore( closeTab, closeOther );
// insert new menuitems and separators
for ( i = 0; i < newMenuItems.length; i++ ) {
var newMenuItem = document.getElementById(newMenuItems[i]);
var item;
if (tabContextMenu.childNodes.length < newMenuOrders[i]+1) item = null;
else item = tabContextMenu.childNodes[newMenuOrders[i]];
tabContextMenu.insertBefore( newMenuItem, item);
}
// restore original-separator-2 to its original position
var origSep2 = document.getElementById("original-separator-2");
var addBookmark = document.getElementById("tm-addBookmarkAs");
if (origSep2 && addBookmark)
tabContextMenu.insertBefore(origSep2, addBookmark);
// insret IE Tab menu-items befor Bookmakrs menu-items or at the end if origSep2 is null
if (window.gIeTab) {
var aFunction = "createTabbarMenu" in IeTab.prototype ? "createTabbarMenu" : "init";
if (aFunction in IeTab.prototype) {
eval("IeTab.prototype." + aFunction +" ="+IeTab.prototype[aFunction].toString().replace(
'tabbarMenu.insertBefore(document.getElementById("ietab-tabbar-sep"), separator);',
'separator = document.getElementById("original-separator-2"); $&'
));
}
}
}
function TMP_openDialog(panel)
{
var WindowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
.getService(Components.interfaces.nsIWindowMediator);
var tabmixOptionsWin = WindowManager.getMostRecentWindow("mozilla:tabmixopt");
if (tabmixOptionsWin) {
var appearanceWin = WindowManager.getMostRecentWindow("mozilla:tabmixopt-appearance");
var filetypeWin = WindowManager.getMostRecentWindow("mozilla:tabmixopt-filetype");
if (!appearanceWin && !filetypeWin && panel > -1)
tabmixOptionsWin.TM_selectTab(panel);
var incompatibleBox = tabmixOptionsWin.document.getElementById("incompatible");
var incompatibleStatus = incompatibleBox.collapsed;
incompatibleBox.collapsed = getExtensions().length == 0;
if (incompatibleStatus != incompatibleBox.collapsed)
tabmixOptionsWin.sizeToContent();
(appearanceWin || filetypeWin || tabmixOptionsWin).focus();
}
else {
if(panel > -1)
gPref.setIntPref('extensions.tabmix.selected_tab', panel);
window.openDialog("chrome://tabmixplus/content/pref/pref-tabmix.xul", "Tab Mix Plus", "chrome,titlebar,toolbar,close,dialog=no");
}
}
/*
functions to disable incompatible extensions
original code by mrtech local_install.js , code modified by onemen 2006-01-13
*/
function disableExtensions(aWindow) {
var warning_list = getExtensions();
if (warning_list.length == 0) {
return true;
}
try {
warning_list.sort();
} catch(ex) { }
var outStr = "";
for (var w in warning_list) {
outStr += " - " + warning_list[w]._name + " " + warning_list[w]._version + "\n";
}
var defaultButton = gIsOldBrowser ? BUTTON_OK : BUTTON_EXTRA1;
var showatStart = gPref.getBoolPref("extensions.tabmix.disableIncompatible")
var chkBoxState = showatStart ? CHECKBOX_CHECKED : CHECKBOX_UNCHECKED;
var bundleID = "tmp-string-bundle"
var _stingBundle = document.getElementById(bundleID);
var title = _stingBundle.getString("incompatible.title");
var msg = _stingBundle.getString("incompatible.msg0") + "\n"
+ _stingBundle.getString("incompatible.msg1") + "\n\n" + outStr + "\n\n";
var chkBoxLabel = _stingBundle.getString("incompatible.chkbox.label");
var buttons = [SessionManager.setLabel("incompatible.button0", bundleID),
SessionManager.setLabel("incompatible.button1", bundleID)];
if (!gIsOldBrowser)
buttons.push(SessionManager.setLabel("incompatible.button2", bundleID));
var result = TM_PromptService([defaultButton, HIDE_MENUANDTEXT, chkBoxState],[title, msg, "", chkBoxLabel, buttons.join("\n")], aWindow);
if (result.checked != showatStart) {
gPref.setBoolPref("extensions.tabmix.disableIncompatible", result.checked);
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
}
if (result.button != BUTTON_CANCEL) {
var extensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
var _Function = gIsOldBrowser ? "disableExtension" : "disableItem";
for (w in warning_list) {
try{
extensionManager[_Function](warning_list[w]._guid);
} catch(e) {
tmLog("error while disabled " + warning_list[w]._name)
}
}
var dataSource = extensionManager.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
if (dataSource)
dataSource.Flush();
if (!gIsOldBrowser && result.button == BUTTON_EXTRA1 && canQuitApplication()) {
var appStartup = Components.interfaces.nsIAppStartup;
Components.classes["@mozilla.org/toolkit/app-startup;1"]
.getService(appStartup).quit(appStartup.eRestart | appStartup.eAttemptQuit);
}
else {
msg = _stingBundle.getString("incompatible.msg2");
buttons = ["", SessionManager.setLabel("sm.button.continue")].join("\n");
TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],[title, msg, "", "", buttons], aWindow);
}
return true;
}
return false;
}
function getExtensions() {
var guid_list = {};
/*
The following extensions are integrated or incompatible with Tab Mix Plus
add extensions ID in lowercase.
*/
guid_list['{00bdd586-51fb-4b06-9c23-af2fb7609bf3}'] = true; // Basics
guid_list['{b98719b3-76d6-4bec-aeed-3ab542b23bd7}'] = true; // BlankLast
guid_list['{47921160-3085-4023-a145-8ec466babfba}'] = true; // Click2Tab
guid_list['{b0f9cad2-ebae-4685-b518-d3d9b41ea183}'] = true; // Close Tab On Double Click
guid_list['ctc@clav.mozdev.org'] = true; // CTC
guid_list['{61ed2a9a-39eb-4aaf-bd14-06dfbe8880c3}'] = true; // Duplicate Tab
guid_list['flowtabs'] = true; // Flowing Tabs
guid_list['{cd2b821e-19f9-40a7-ac5c-08d6c197fc43}'] = true; // FLST
guid_list['{68e5dd30-a659-4987-99f9-eaf21f9d4140}'] = true; // LastTab
guid_list['minit@dorando'] = true; // MiniT
guid_list['minit-drag'] = true; // miniT-drag
guid_list['minit-tabscroll@dorando'] = true; // miniT-tabscroll
guid_list['new-tab-button-on-tab-bar@mikegoodspeed.com'] = true; // new tab button on tab bar
guid_list['{66E978CD-981F-47DF-AC42-E3CF417C1467}'] = true; // new tab homepage
guid_list['newtaburl@sogame.cat'] = true; // NewTabURL
guid_list['{4b2867d9-2973-42f3-bd9b-5ad30127c444}'] = true; // Petite Tabbrowser Extensions
guid_list['{888d99e7-e8b5-46a3-851e-1ec45da1e644}'] = true; // ReloadEvery
guid_list['{aede9b05-c23c-479b-a90e-9146ed62d377}'] = true; // Reload Tab On Double-Click
guid_list['{492aa940-beaa-11d8-9669-0800200c9a66}'] = true; // Scrollable Tabs
guid_list['{eb922232-fd76-4eb0-bd5a-c1cba4238343}'] = true; // Single Window
guid_list['{149C6CC6-EC62-4ebd-B719-3C2E867930C7}'] = true; // Stack style tabs
guid_list['supert@studio17.wordpress.com'] = true; // superT
guid_list['tabbin'] = true; // Tab Bin
guid_list['{43520b8f-4107-4351-ac64-9bcc5eea24b9}'] = true; // Tab Clicking Options
guid_list['{bea6d1a7-882d-425f-bc75-944e0063ff3b}'] = true; // Tab Mix [original one]
guid_list['tabtowindow@sogame.cat'] = true; // Tab to window
guid_list['tabx@clav.mozdev.org'] = true; // Tab X
guid_list['{0b0b0da8-08ba-4bc6-987c-6bc9f4d8a81e}'] = true; // Tabbrowser Extensions
guid_list['{9b9d2aaa-ae26-4447-a7a1-633a32b19ddd}'] = true; // Tabbrowser Preferences
guid_list['tabdrag'] = true; // tabdrag-for-tablib
guid_list['tabfx@chaosware.net'] = true; // TabFX
guid_list['tabsopenrelative@jomel.me.uk'] = true; // Tabs open ralative
guid_list['tablib'] = true; // tablib
guid_list['{328bbe91-cb86-40b0-a3fd-2b39969f9faa}'] = true; // Undo Close Tab
guid_list['undoclosetab@dorando'] = true; // Undo Close Tab
guid_list['{99ec6690-8bb1-11da-a72b-0800200c9a66}'] = true; // Unread Tabs
function prop(elm, str) {
var arc = RDFService.GetResource("http://www.mozilla.org/2004/em-rdf#" + str);
var target = extensionDS.GetTarget(elm, arc, true);
if (target instanceof Components.interfaces.nsIRDFLiteral ||
target instanceof Components.interfaces.nsIRDFInt)
return target.Value;
return null;
}
var RDFService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
var Container = Components.classes["@mozilla.org/rdf/container;1"]
.getService(Components.interfaces.nsIRDFContainer);
var extensionDS = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager).datasource;
var root = gIsOldBrowser ? "urn:mozilla:extension:" : "urn:mozilla:item:";
var disabledString = gIsOldBrowser ? "disabled" : "userDisabled";
try { // in ff 1.0.x we can get error at startup
Container.Init(extensionDS, RDFService.GetResource(root + "root"));
} catch (e) {
tmLog("error in getExtensions " + e);
return [];
}
var elements = Container.GetElements();
var extensionsArray = [];
while (elements.hasMoreElements()) {
var element=elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = element.Value.replace(root, "");
if (typeof guid_list[id.toLowerCase()] != "undefined") {
var opType = prop(element, "opType");
var disabled = prop(element, disabledString);
if ((!disabled && opType != "needs-disable" && opType != "needs-uninstall") ||
( disabled && opType == "needs-enable")) {
var name = prop(element, "name");
name = name.charAt(0).toUpperCase() + name.substr(1);
extensionsArray.push({_name: name, _guid: id, _version:prop(element, "version")});
}
}
}
return extensionsArray;
}
PK
~6qNX X content/tabmixplus/tabmix.xul
%tabmixDTD;
%tabBrowserDTD;
]>
PK
6 content/tabmixplus/tab/PK
86@ʧ ʧ content/tabmixplus/tab/tab.js// code based on Tab X 0.5 enhanced version by Morac, modified by Hemiola SUN, later CPU & onemen
var nsIPrefServiceObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
var tabxBranch = "extensions.tabmix.";
var tabxPrefs = nsIPrefServiceObj.getBranch(tabxBranch);
var tabBarWidth = -1;
var tabx;
var addtabx;
var tabxleft;
var tabscroll;
var hidebutton;
var max_width;
var min_width;
var flexTabs;
var gTabbarPosition;
var gSingleWindowMode;
var progress;
var tabBarSpace;
var unreadTab;
var optionsToolsMenu;
var alwaysNewTab;
var showIcons;
var showNewTabButton;
var noprogress;
var boldUnread;
var italicUnread;
var underlineUnread;
var useUnreadColor;
var useCurrentColor;
var useProgressColor;
var boldCurrent;
var italicCurrent;
var underlineCurrent;
var gFirefox2DefaultTheme;
function TMupdateSettings(start)
{
var _Browser = getBrowser();
if (!_Browser || tabxPrefs.prefHasUserValue("setDefault")) return;
var i;
tabx = TMP_getBoolPref(tabxBranch, "tabXMode.enable", true);
addtabx = TMP_getIntPref (tabxBranch, "tabXMode", 1);
// in old version we use tabXMode = 0 to disable the button
if (tabx && (addtabx < 1 || addtabx > 5)) {
addtabx = 1;
tabxPrefs.setIntPref("tabXMode", 1);
return;
}
tabxleft = TMP_getBoolPref(tabxBranch, "tabXLeft", false);
tabscroll = TMP_getIntPref (tabxBranch, "tabBarMode", 2);
hidebutton = TMP_getBoolPref(tabxBranch, "hideTabBarButton", true);
max_width = TMP_getIntPref (tabxBranch, "maxWidth", 250);
min_width = TMP_getIntPref (tabxBranch, "minWidth", 30);
flexTabs = TMP_getBoolPref(tabxBranch, "flexTabs", false);
progress = TMP_getBoolPref(tabxBranch, "progressMeter", true);
tabBarSpace = TMP_getBoolPref(tabxBranch, "tabBarSpace", false);
unreadTab = TMP_getBoolPref(tabxBranch, "unreadTab", false);
currentTab = TMP_getBoolPref(tabxBranch, "currentTab", false);
noprogress = TMP_getBoolPref(tabxBranch, "noprogress", false);
optionsToolsMenu = TMP_getBoolPref(tabxBranch, "optionsToolMenu", true);
alwaysNewTab = TMP_getIntPref (tabxBranch, "speLink", 0);
showIcons = TMP_getBoolPref(tabxBranch, "extraIcons", true);
showNewTabButton = TMP_getBoolPref(tabxBranch, "newTabButton", true);
boldUnread = TMP_getBoolPref(tabxBranch, "boldUnread", true);
italicUnread = TMP_getBoolPref(tabxBranch, "italicUnread", true);
underlineUnread = TMP_getBoolPref(tabxBranch, "underlineUnread", true);
boldCurrent = TMP_getBoolPref(tabxBranch, "boldCurrent", true);
italicCurrent = TMP_getBoolPref(tabxBranch, "italicCurrent", true);
underlineCurrent = TMP_getBoolPref(tabxBranch, "underlineCurrent", true);
useCurrentColor = TMP_getBoolPref(tabxBranch, "useCurrentColor", true);
useUnreadColor = TMP_getBoolPref(tabxBranch, "useUnreadColor", true);
useProgressColor = TMP_getBoolPref(tabxBranch, "useProgressColor", false);
var allTabs = _Browser.mTabContainer.childNodes;
var tabBar = _Browser.mTabContainer;
var tabBox = _Browser.mTabBox;
var currentVisible = tabBar.isTabVisible(_Browser.mCurrentTab._tPos);
tabBox.setAttribute("dir", gTabbarPosition == 1 ? "rtl" : "ltr");
if (gIsFirefox2)
tabBar.mAllTabsPopup.setAttribute("position", gTabbarPosition == 1 ? "before_start" : "after_end");
switch ( tabscroll ) {
case 0:
tabBar.setAttribute("flowing", "singlebar");
break;
case 1:
if (tabBar.getAttribute("flowing") != "scrollbutton")
tabBar.setAttribute("flowing", "scrollbutton");
break;
case 2:
if (tabBar.getAttribute("flowing") != "multibar") {
tabBar.setAttribute("flowing", "multibar");
tabBar.collapsedTabs = 0;
}
break;
}
if (!flexTabs)
tabBar.collapsedTabs = 0;
var tabxOptions = ["no-button","always","showhover","current","current_hover","always"];
for (i = 0; i < allTabs.length; i++) {
var aTab = allTabs[i];
aTab.maxWidth = max_width;
aTab.minWidth = min_width;
if (flexTabs && min_width != max_width) {
if (aTab.hasAttribute("width")) aTab.removeAttribute("width");
if (aTab.hasAttribute("flex")) aTab.removeAttribute("flex");
} else {
aTab.setAttribute("width", "0");
aTab.setAttribute("flex", "100");
}
if ( alwaysNewTab == 1 )
aTab.setAttribute("locked", "true");
else if ( tabBar.getAttribute("lockAllTab") == "true" )
aTab.removeAttribute("locked");
SessionManager.updateTabProp(aTab);
if (tabx) aTab.setAttribute("tabx", tabxOptions[addtabx]);
else aTab.removeAttribute("tabx");
if (tabxleft) aTab.setAttribute("tabxleft", "on");
else aTab.removeAttribute("tabxleft");
}
tabBar.setAttribute("closebutton", !hidebutton);
tabBar.setAttribute("hideAllTabsButton", TMP_getBoolPref(tabxBranch, "hideAllTabsButton", false));
tabBar.setAttribute("progressMeter", progress);
tabBar.setAttribute("tabBarSpace", tabBarSpace);
tabBar.setAttribute("unreadTab", unreadTab);
tabBar.setAttribute("extraIcons", showIcons );
tabBar.setAttribute("lockAllTab", alwaysNewTab == 1 );
tabBar.setAttribute("newTabButton", showNewTabButton );
tabBar.setAttribute("boldUnread", boldUnread);
tabBar.setAttribute("italicUnread", italicUnread);
tabBar.setAttribute("underlineUnread", underlineUnread);
tabBar.setAttribute("boldCurrent", boldCurrent);
tabBar.setAttribute("italicCurrent", italicCurrent);
tabBar.setAttribute("underlineCurrent", underlineCurrent);
tabBar.setAttribute("currentTab", currentTab);
tabBar.setAttribute("useCurrentColor", useCurrentColor);
tabBar.setAttribute("useUnreadColor", useUnreadColor);
tabBar.setAttribute("useProgressColor", useProgressColor);
document.getElementById("statusbar-progresspanel").setAttribute("hidden", noprogress && progress);
var tabhbox = document.getElementById("scroll-tabs-frame");
if (tabhbox.style.maxHeight != "none" && !gBrowser.mStrip.collapsed && tabBar.childNodes[0].collapsed) {
var currentMaxRow = tabhbox.style.maxHeight.replace("px", "") / getRowHeight();
var rowDiff = tabBar.maxRow - currentMaxRow;
while (tabBar.childNodes[0].collapsed && rowDiff > 0) {
tabBar.rowScroll(-1);
rowDiff--;
}
}
if (start && "isLoadHomePage" in window) {
window.setTimeout(tabBarScrollStatus, 0);
delete window.isLoadHomePage;
}
else
tabBarScrollStatus();
tabBar.canScrollTabsLeft = tabBar.childNodes[0].collapsed;
window.setTimeout( function() {
if (currentVisible)
tabBar.ensureTabIsVisible( _Browser.mCurrentTab._tPos );
tabBar.canScrollTabsRight = !tabBar.rightEnd;
checkBeforeAndAfter();
}, 50 );
if ( tabBarWidth == -1 ) // initialize the value of "tabBarWidth"
window.setTimeout( function () {
tabBarWidth = gBrowser.mTabContainer.boxObject.width;
}, 100 );
// if the current Browser has SafeBrowsing problem and message is showing we need to
// repaint the "safebrowsing-dim-area-canvas"
window.setTimeout(adjustSafebrowsingDimArea, 0);
// set some items
document.getElementById("tabmix-menu").hidden = !optionsToolsMenu;
var undocloseButton = document.getElementById("btn_undoclose");
if (undocloseButton) closedTabBtnType(undocloseButton);
TMP_LastTab.ReadPreferences();
SessionManager.updateSettings(); // this update all open windows, if we fix here we need to change in SessionManager
}
// make btn_undoclose single-functionality or dual-functionality
function closedTabBtnType(undocloseButton)
{
var menuOnly = TMP_getBoolPref(tabxBranch, "undoCloseButton.menuonly", false);
if (!menuOnly)
undocloseButton.removeAttribute("orient");
else if (!undocloseButton.hasAttribute("orient"))
undocloseButton.setAttribute("orient", "vertical");
var buttonType = menuOnly ? "menu" : "menu-button";
if (undocloseButton.getAttribute("type") != buttonType)
undocloseButton.setAttribute("type", buttonType);
}
//overlay BrowserToolboxCustomizeDone
function TMP_BrowserToolboxCustomizeDone()
{
var undocloseButton = document.getElementById("btn_undoclose");
if (undocloseButton) {
closedTabBtnType(undocloseButton);
undocloseButton.setAttribute("disabled",gBrowser.closedTabs.length < 1);
}
var managerButten = document.getElementById("btn_sessionmanager");
if (managerButten) {
managerButten.setAttribute("disabled", !tabxPrefs.getBoolPref("sessions.manager"));
var hiddenPref = document.getElementById("btn_closedwindows") ? true : false;
document.getElementById("tm-sm-closedwindows1").hidden = hiddenPref;
}
fixTabmixButtons();
}
// fix Tabmix toolbarbutton in Firefox 2.0+ theme
//(check to see if they change this)
function fixTabmixButtons()
{
function setAttrib(id, attrib) {
var button = document.getElementById(id);
if (button && (!button.hasAttribute(attrib) || !button.getAttribute(attrib)))
button.setAttribute(attrib,true);
}
var buttons = ["tabslist","closedwindows","undoclose","sessionmanager"];
if (gIsFirefox2)
Array.forEach(buttons, function(id) {setAttrib("btn_"+id, "firefox2");});
}
function TMP_SSTabRestoring(event){
var aTab = event.target;
if (aTab.hasAttribute("_locked")) {
if (aTab.getAttribute("_locked") == "true")
aTab.setAttribute("locked", "true");
else
aTab.removeAttribute("locked");
}
// this function ren befor tab load, so onTabReloaded will run at onStateChange get STATE_STOP
var reloadData = aTab.getAttribute("reload-data");
if (reloadData) {
reloadData = reloadData.split(" ");
gBrowser.setupAutoReload(aTab);
aTab.autoReloadEnabled = true;
aTab.autoReloadURI = reloadData[0];
aTab.autoReloadTime = reloadData[1];
}
}
// Function to catch when a new window is created and update icons if needed
//
function tabxOnLoad(event)
{
var tabBar = getBrowser().mTabContainer;
if (gIsFirefox2) {
tabBar.setAttribute("firefox2", "true");
if (/^Mac/.test(navigator.platform))
tabBar.setAttribute("firefox2Mac", "true");
else
tabBar.setAttribute("firefox2notMac", "true");
var skin = gPref.getCharPref("general.skins.selectedSkin");
if (skin=="classic/1.0") {
gFirefox2DefaultTheme = true;
if (/^Mac/.test(navigator.platform))
tabBar.setAttribute("firefox2MacDefaultTheme", "true");
else
tabBar.setAttribute("firefox2DefaultTheme", "true");
}
}
// add event for update tab when restoring from nsSessionStore
tabBar.addEventListener("SSTabRestoring", TMP_SSTabRestoring, true);
// add event for creating a new tab
tabBar.addEventListener("DOMNodeInserted", tabxTabAdded, true);
// call tabxTabClosed from gBrowser.removeTab (eval) untile we will use "TabClose" event
// tabBar.addEventListener("DOMNodeRemoved", tabxTabClosed, true);
// don't show close tab button if there is only one blank tab or we keep last tab
adjustCloseButtons(1);
// add event for mouse scrolling on tab bar, necessary for linux
tabBar.addEventListener("DOMMouseScroll", TMtabBarScroll, false);
if (window.navigator.platform.search("Linux") != -1)
document.getElementById("navigator-toolbox").addEventListener("DOMMouseScroll", TMtabBarScroll, false);
if (gSingleWindowMode)
tabxPrefObserver.setSingleWindowUI();
tabxPrefObserver.setMenuIcons();
tabxPrefObserver.toggleKey("key_tm_slideShow", "extensions.tabmix.disableF8Key");
tabxPrefObserver.toggleKey("key_tm_toggleFLST", "extensions.tabmix.disableF9Key");
tabxPrefObserver.setNewColorCode("currentTab", "extensions.tabmix.currentColor", "#000000");
tabxPrefObserver.setNewColorCode("unreadTab", "extensions.tabmix.unreadColor", "#CC0000");
tabxPrefObserver.setNewColorCode("progress", "extensions.tabmix.progressColor", "#AAAAFF");
tabxPrefObserver.tabCloseButton();
tabxPrefObserver.maxTabsUndo();
// disable/enable tabmix buttons at startup
var managerButten = document.getElementById("btn_sessionmanager");
if (managerButten) {
var hiddenPref = document.getElementById("btn_closedwindows") ? true : false;
document.getElementById("tm-sm-closedwindows1").hidden = hiddenPref;
}
// fix Tabmix toolbarbutton in Firefox 2.0+ theme
fixTabmixButtons();
gTabbarPosition = TMP_getIntPref (tabxBranch, "tabBarPosition", 0);
// update icons if needed
TMupdateSettings(true); // xxx we need diff function that call one on new window(s) and one for pref changed
}
function tabxOnClose()
{
var tabBar = getBrowser().mTabContainer;
tabBar.removeEventListener("SSTabRestoring", TMP_SSTabRestoring, true);
tabBar.removeEventListener("DOMNodeInserted", tabxTabAdded, true);
tabBar.removeEventListener("DOMMouseScroll", TMtabBarScroll, false);
if (window.navigator.platform.search("Linux") != -1)
document.getElementById("navigator-toolbox").removeEventListener("DOMMouseScroll", TMtabBarScroll, false);
}
function tabxTabClosed(aTab)
{
var tabs = getBrowser().mTabContainer.childNodes;
var tabBar = getBrowser().mTabContainer;
var firstTab = tabs[0];
// don't show close tab button if there is only one blank tab or we keep last tab
adjustCloseButtons(2, aTab);
if ( tabscroll != 2 ) {
tabBar.collapsedTabs--;
tabBar.canScrollTabsLeft = firstTab.collapsed;
window.setTimeout( function() {
tabBar.canScrollTabsRight = !tabBar.rightEnd;
setTabBarHeight();
}, 50 );
}
else {
window.setTimeout( function() {
if ( tabBar.getAttribute("multibar") == "scrollbar" && firstTab.collapsed ) {
if ((tabBar.lastChild.baseY + tabBar.lastChild.boxObject.height/2) < (tabBar.boxObject.y + tabBar.boxObject.height)) {
tabBar.rowScroll(-1);
}
}
tabBarScrollStatus();
checkBeforeAndAfter();
}, 0);
}
// if the current Browser has SafeBrowsing problem and message is showing we need to
// repaint the "safebrowsing-dim-area-canvas"
window.setTimeout(adjustSafebrowsingDimArea, 0);
}
// Function to catch when new tabs are created and update tab icons if needed
// In addition clicks and doubleclick events are trapped.
//
function tabxTabAdded(event)
{
if (event.target.localName != "tab" || event.target.hasAttribute("tabmoved"))
return;
var aTab = event.target;
// XXX splice, appendChild, insertBefore from gBrowser.moveTabTo
// trigger tabxTabClosed and tabxTabAdded
if (aTab._added) {
delete aTab._added;
return;
}
aTab._added = true;
//XXX when we drop support for Fx 1.0 - 1.5 add chromedir="&locale.dir;" to tab content binding
if (gIsFirefox2)
aTab.setAttribute("chromedir", gChromeDir);
// don't show close tab button if there is only one blank tab or we keep last tab
adjustCloseButtons(1);
var tabxOptions = ["no-button","always","showhover","current","current_hover","always"];
if (tabx) aTab.setAttribute("tabx", tabxOptions[addtabx]);
else aTab.removeAttribute("tabx");
if (tabxleft) aTab.setAttribute("tabxleft", "on");
else aTab.removeAttribute("tabxleft");
aTab.maxWidth = max_width;
aTab.minWidth = min_width;
if (flexTabs && min_width != max_width) {
if (aTab.hasAttribute("width")) aTab.removeAttribute("width");
if (aTab.hasAttribute("flex")) aTab.removeAttribute("flex");
} else {
aTab.setAttribute("width", "0");
aTab.setAttribute("flex", "100");
}
if ( alwaysNewTab == 1 )
aTab.setAttribute("locked", "true");
// XXX SessionManager.updateTabProp(aTab); // tab is blank at this stage
tabBarScrollStatus();
// if the current Browser has SafeBrowsing problem and message is showing we need to
// repaint the "safebrowsing-dim-area-canvas"
adjustSafebrowsingDimArea();
}
function tabBarScrollStatus ()
{
var allTabs = getBrowser().mTabContainer.childNodes;
var tabBar = getBrowser().mTabContainer;
tabBar.canScrollTabsLeft = allTabs[0].collapsed;
if ( tabscroll == 2 ) {
tabBar.setAttribute("multibar", "true");
setMultibarAttribute();
}
else
tabBar.removeAttribute("multibar");
setTabBarHeight();
tabBar.canScrollTabsRight = !tabBar.rightEnd;
}
function setMultibarAttribute ()
{
var tabBar = getBrowser().mTabContainer;
if (tabBar.collapsedTabs > 0)
tabBar.setAttribute("multibar", "scrollbar");
else if (gBrowser.mStrip.collapsed || inSameRow(tabBar.firstChild, tabBar.lastChild))
tabBar.removeAttribute("multibar");
else {
var tabhbox = document.getElementById("scroll-tabs-frame");
var maxY = tabhbox.boxObject.y + getRowHeight() * tabBar.maxRow;
// if the top of the last tab is on or below the max line then enter scrollbar
var lastTabY = tabBar.lastChild.boxObject.y;
if (lastTabY >= maxY)
tabBar.setAttribute("multibar", "scrollbar");
else if (tabBar.getAttribute("multibar") != "true")
tabBar.setAttribute("multibar", "true");
}
}
function checkBeforeAndAfter()
{
var tab = getBrowser().mTabContainer.selectedItem;
var prev = tab.previousSibling, next = tab.nextSibling;
if (prev) {
if ( !inSameRow(prev, tab) ) prev.removeAttribute("beforeselected");
else prev.setAttribute("beforeselected", "true");
}
if (next) {
if ( !inSameRow(next, tab) ) next.removeAttribute("afterselected");
else next.setAttribute("afterselected", "true");
}
}
function getRowHeight ()
{
var tabBar = getBrowser().mTabContainer;
var tabs = getBrowser().mTabContainer.childNodes;
var i, j;
i = j = tabBar.collapsedTabs;
if ( tabs[j] && tabs[j].getAttribute("selected") == "true" )
j++;
while ( inSameRow( tabs.item(i), tabs.item(j) ) )
i++;
if ( !tabs[i] ) // only one row
if ( tabs[j] )
return tabs[j].baseY - tabs[j].boxObject.y;
else
return tabs[0].baseY - tabs[0].boxObject.y;
if ( tabs[i].getAttribute("selected") == "true" )
i++;
if ( !tabs[i] )
return tabs[i-1].baseY - tabs[i-1].boxObject.y;
return tabs[i].baseY - tabs[j].baseY;
}
function setTabBarHeight () {
var tabBar = getBrowser().mTabContainer;
var tabhbox = document.getElementById("scroll-tabs-frame");
if ( tabBar.getAttribute("flowing") == "multibar" && tabBar.getAttribute("multibar") == "scrollbar" ) {
tabhbox.style.maxHeight = tabhbox.style.height = getRowHeight() * tabBar.maxRow + "px";
document.getElementById("tabmix-tabs-closebutton-box").pack = "start";
}
else {
if ( tabBar.getAttribute("flowing") == "multibar" && tabBar.getAttribute("multibar") == "true")
document.getElementById("tabmix-tabs-closebutton-box").pack = "start";
else
document.getElementById("tabmix-tabs-closebutton-box").pack = "center";
tabhbox.style.maxHeight = "none";
tabhbox.style.height = "auto";
}
}
function inSameRow (tab1, tab2)
{
if ( !tab1 || !tab2 )
return false;
if ( !tabscroll || tabscroll != 2 )
return true;
var top1 = tab1.boxObject.y, top2 = tab2.boxObject.y;
var base1 = tab1.baseY, base2 = tab2.baseY;
var topH = Math.min(top1, top2), topL = Math.max(top1, top2);
var baseH = Math.min(base1, base2), baseL = Math.max(base1, base2);
if ( topH == topL || baseH == baseL )
return true;
return ( baseH > (top1+base1)/2 && baseH > (top2+base2)/2 && topL < (top1+base1)/2 && topL < (top2+base2)/2 ) ?
true : false;
}
function tabBarWidthChange () {
var tabBar = getBrowser().mTabContainer;
var tabhbox = document.getElementById("scroll-tabs-frame");
var tabs = getBrowser().mTabContainer.childNodes;
if (addtabx == 5 && !flexTabs)
adjustCloseButtons(1);
if ( tabBarWidth == tabBar.boxObject.width )
return;
var oldCollapsed = tabBar.collapsedTabs;
var i = 0;
if ( tabscroll != 2 && tabBarWidth < tabBar.boxObject.width ) {
while ( tabs[ oldCollapsed + i ] &&
tabs[ oldCollapsed + i ].boxObject.x + tabs[ oldCollapsed + i ].boxObject.width <
tabhbox.boxObject.x + tabhbox.boxObject.width )
i++;
tabBar.collapsedTabs = 0;
tabBar.ensureTabIsVisible( oldCollapsed + i - 1 );
tabBarScrollStatus();
}
else if ( tabscroll == 2 ) {
tabBar.collapsedTabs = 0;
tabBarScrollStatus();
tabBar.ensureTabIsVisible( tabs.length - 1);
tabBar.ensureTabIsVisible( oldCollapsed );
checkBeforeAndAfter();
}
else
tabBarScrollStatus();
tabBarWidth = tabBar.boxObject.width;
}
// Function to catch changes to Tab Mix preferences and update existing windows and tabs
//
function tabxPrefObserver() {
var pref = "setDefault"
if (tabxPrefs.prefHasUserValue(pref)) tabxPrefs.clearUserPref(pref)
pref = "PrefObserver.error";
if (tabxPrefs.prefHasUserValue(pref)) tabxPrefs.clearUserPref(pref)
try {
var prefSvc = nsIPrefServiceObj.getBranch(null);
this.tabxBranch = tabxBranch;
if (!Components.interfaces.nsIPrefBranch2)
this.pbi = prefSvc.QueryInterface(Components.interfaces.nsIPrefBranchInternal); // for 1.0.7
else
this.pbi = prefSvc.QueryInterface(Components.interfaces.nsIPrefBranch2);
// add Observer
for (var i = 0; i < this.OBSERVING.length; ++i)
this.pbi.addObserver(this.OBSERVING[i], this, true);
}
catch(e) {
tmLog("prefs-Observer failed to attach:" + "\n" + e);
tabxPrefs.setBoolPref(pref, true);
}
}
tabxPrefObserver.prototype = {
tabxBranch: null,
// nsISupports interface implementation -- for weak-reference by pref-observer service
QueryInterface: function(iid) {
if (!iid.equals(Components.interfaces.nsISupports)
&& !iid.equals(Components.interfaces.nsISupportsWeakReference)
&& !iid.equals(Components.interfaces.nsIObserver)) {
dump("Tab Mix Plus pref-observer factory object: QI unknown interface: " + iid + "\n");
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
OBSERVING: ["extensions.tabmix.",
"browser.tabs.tabClipWidth", "browser.sessionstore.max_tabs_undo",
"browser.sessionstore.enabled", "browser.link.open_external",
"browser.link.open_newwindow.restriction", "browser.link.open_newwindow"],
// removes the observer-object from service -- called when the window is no longer open
removeObserver: function() {
for (var i = 0; i < this.OBSERVING.length; ++i)
this.pbi.removeObserver(this.OBSERVING[i], this);
this.pbi = null;
},
/* Observer-function */
/* subject: [wrapped nsISupports :: nsIPrefBranch], nsIPrefBranch Internal
topic: "changed"*/
observe: function TMP_pref_observer(subject, topic, prefName) {
// if we don't have a valid window (closed)
if ( !(typeof(document) == 'object' && document) ) {
this.removeObserver(); // remove the observer..
return; // ..and don't continue
}
switch (prefName) {
case "extensions.tabmix.warnAboutClosingTabs.timeout":
case "extensions.tabmix.sessions.crashed":
case "extensions.tabmix.disableIncompatible":
case "extensions.tabmix.selected_tab":
case "extensions.tabmix.selected_sub_tab1":
case "extensions.tabmix.selected_sub_tab2":
case "extensions.tabmix.selected_sub_tab3":
case "extensions.tabmix.selected_sub_tab4":
case "extensions.tabmix.selected_sub_tab5":
case "extensions.tabmix.selected_sub_tab6":
case "extensions.tabmix.reload_time":
case "extensions.tabmix.custom_reload_time":
case "extensions.tabmix.resume_session_once":
break;
case "extensions.tabmix.focusTab":
if (gIsFirefox2)
gPref.setBoolPref("browser.tabs.selectOwnerOnClose", gPref.getIntPref(prefName) == 2);
break;
case "extensions.tabmix.disableF9Key":
this.toggleKey("key_tm_toggleFLST", prefName);
break;
case "extensions.tabmix.disableF8Key":
this.toggleKey("key_tm_slideShow", prefName);
break;
case "extensions.tabmix.hideIcons":
this.setMenuIcons();
break;
case "extensions.tabmix.currentColorCode":
this.setColor("currentTab", prefName, "#009900");
break;
case "extensions.tabmix.unreadColorCode":
this.setColor("unreadTab", prefName, "#FF0000");
break;
case "extensions.tabmix.progressColorCode":
this.setColor("progress", prefName, "#AAAAFF");
break;
case "extensions.tabmix.flexTabs":
case "extensions.tabmix.tabXMode":
TMupdateSettings(false);
case "extensions.tabmix.keepLastTab":
case "browser.tabs.tabClipWidth":
// don't show close tab button if there is only one blank tab or we keep last tab
// or if tab width is smaller then pref and not in flexTabs mode.
adjustCloseButtons(1);
break;
case "extensions.tabmix.tabBarPosition":
gTabbarPosition = TMP_getIntPref (tabxBranch, "tabBarPosition", 0);
adjustSafebrowsingDimArea();
break;
case "extensions.tabmix.useGreyCloseButton":
this.tabCloseButton();
break;
case "extensions.tabmix.undoClose":
if (!tabxPrefs.getBoolPref("undoClose")) {
gPref.setIntPref("browser.sessionstore.max_tabs_undo", 0);
tabxPrefs.setIntPref("undoCloseCache", 0);
}
break;
case "extensions.tabmix.undoCloseCache":
var cache = gPref.getIntPref(prefName);
if (cache > 0 && !tabxPrefs.getBoolPref("undoClose"))
tabxPrefs.setBoolPref("undoClose", true);
gPref.setIntPref("browser.sessionstore.max_tabs_undo", cache);
SessionManager.updateSettings();
break;
case "browser.sessionstore.max_tabs_undo":
var cache = gPref.getIntPref(prefName);
if (cache > 0 && !tabxPrefs.getBoolPref("undoClose"))
tabxPrefs.setBoolPref("undoClose", true);
tabxPrefs.setIntPref("undoCloseCache", cache);
break;
case "browser.sessionstore.enabled":
TMP_SessionStore.setService(1, false);
// initialize nsISessionStore if necessary
if (gIsFirefox2 && TMP_getBoolPref("", prefName, true) && !window.__SSi) {
TMP_SessionStore.init(true);
}
break;
case "extensions.tabmix.sessions.manager":
case "extensions.tabmix.sessions.crashRecovery":
TMP_SessionStore.setService(2, false);
SessionManager.updateSettings();
break;
case "browser.link.open_external":
case "browser.link.open_newwindow.restriction":
case "browser.link.open_newwindow":
this.setLink_openPrefs();
break;
case "extensions.tabmix.singleWindow":
this.setSingleWindowUI();
break;
default:
TMupdateSettings(false);
}
},
tabCloseButton: function() {
var useNewCloseIcon;
try {
useNewCloseIcon = tabxPrefs.getBoolPref("useGreyCloseButton");
}
catch(er) { useNewCloseIcon = true; }
if (useNewCloseIcon && !(/^Mac/.test(navigator.platform)) )
getBrowser().mTabContainer.removeAttribute("dontUseNewCloseIcon");
else
getBrowser().mTabContainer.setAttribute("dontUseNewCloseIcon", "true");
},
toggleKey: function(keiID, prefName) {
var key = document.getElementById(keiID);
if (TMP_getBoolPref("", prefName, false)) {
if (key.hasAttribute("oncommand"))
key.removeAttribute("oncommand");
} else
key.setAttribute("oncommand", key.getAttribute("TM_oncommand"));
},
// in 0.3.0.605 we changed tab color from old pref to new pref
// old pref "extensions.tabmix.currentColor" type integer
// new pref "extensions.tabmix.currentColorCode" type string
setNewColorCode: function(colorType, OldprefName, defaultPref) {
var prefName = OldprefName + "Code";
if (gPref.prefHasUserValue(OldprefName)) {
var colorCodes = ["#CF1919", "#0E36EF", "#DDDF0D", "#3F8F3E", "#E066FF", "#86E7EF",
"#FFFFFF", "#7F7F7F", "#000000", "#EF952C", "#FF82AB", "#7F4C0F", "#AAAAFF"];
var colorCode = colorCodes[gPref.getIntPref(OldprefName)];
gPref.clearUserPref(OldprefName);
if (gPref.getCharPref(prefName) != colorCode) {
gPref.setCharPref(prefName , colorCode); // this trigger call to setColor for this prefName
return;
}
}
this.setColor(colorType, prefName, defaultPref);
},
colorRules: {},
setColor: function(colorType, prefName, defaultPref) {
var colorCode = TMP_getCharPref("", prefName, defaultPref);
var colorRule, _style;
switch (colorType) {
case "currentTab":
_style = "color";
colorRule = 'tabs[currentTab=true][useCurrentColor=true] tab[selected="true"] .tab-text { color:' + colorCode + '}';
break;
case "unreadTab":
_style = "color";
colorRule = 'tabs[unreadTab=true][useUnreadColor=true] tab:not([selected]) .tab-text { color:' + colorCode + '}';
break;
case "progress":
_style = "backgroundColor";
colorRule = 'tabs[useProgressColor=true] tab .progress-bar { background-color:' + colorCode + '}';
break;
}
var ss = document.styleSheets[0];
if (this.colorRules[colorType])
this.colorRules[colorType].style[_style] = colorCode;
else
{
var index = ss.insertRule(colorRule, ss.cssRules.length);
this.colorRules[colorType] = ss.cssRules[index];
}
},
// sync between "browser.sessionstore.max_tabs_undo"
// and "extensions.tabmix.undoCloseCache"
maxTabsUndo: function() {
var TMP_cache = tabxPrefs.getIntPref("undoCloseCache");
var max_tabs_undo = "browser.sessionstore.max_tabs_undo";
var Fx_cache = 0;
if (gIsFirefox2)
Fx_cache = gPref.getIntPref(max_tabs_undo);
var cache = Math.max(TMP_cache, Fx_cache);
if (cache != TMP_cache)
tabxPrefs.setIntPref("undoCloseCache", cache)
if (gIsFirefox2 && cache != Fx_cache)
gPref.setIntPref(max_tabs_undo, cache);
if (cache > 0 && !tabxPrefs.getBoolPref("undoClose"))
tabxPrefs.setBoolPref("undoClose", true);
},
setLink_openPrefs: function() {
if (!gSingleWindowMode)
return;
function updateStatus(pref, testVal, test, newVal) {
try {
var prefValue = gPref.getIntPref(pref);
test = test ? prefValue == testVal : prefValue != testVal
}
catch(e){ test = true; }
if (test)
gPref.setIntPref(pref, newVal);
}
updateStatus("browser.link.open_external", 2, true, 3);
updateStatus("browser.link.open_newwindow.restriction", 0, false, 0);
updateStatus("browser.link.open_newwindow", 2, true, 3);
},
// code for Single Window Mode...
// disable the "Open New Window action
//disable & hides some menuitem
setSingleWindowUI: function() {
gSingleWindowMode = TMP_getBoolPref(tabxBranch, "singleWindow", false);
var newWindowButton = document.getElementById("new-window-button");
if (newWindowButton)
newWindowButton.setAttribute("disabled", gSingleWindowMode);
var openLink = document.getElementById("context-openlink");
if (openLink)
openLink.setAttribute("disabled", gSingleWindowMode);
var menuItem;
var menuFile = document.getElementById("menu_FilePopup");
if (menuFile) {
menuItem = menuFile.getElementsByAttribute("command", "cmd_newNavigator")[0];
if (menuItem)
menuItem.setAttribute("hidden", gSingleWindowMode);
}
var frameMenu = document.getElementById("frame");
if (frameMenu) {
menuItem = frameMenu.getElementsByAttribute("oncommand", "gContextMenu.openFrame();")[0];
if (menuItem)
menuItem.setAttribute("hidden", gSingleWindowMode);
}
document.getElementById("tmOpenInNewWindow").hidden = gSingleWindowMode;
},
setMenuIcons: function() {
function setClass(items, hideIcons) {
if (hideIcons)
for (var i = 0; i < items.length; ++i)
items[i].removeAttribute("class");
else
for ( i = 0; i < items.length; ++i)
items[i].setAttribute("class", items[i].getAttribute("tmp_iconic"));
}
var hideIcons = TMP_getBoolPref(tabxBranch, "hideIcons", false);
var iconicItems = document.getElementsByAttribute("tmp_iconic", "*");
setClass(iconicItems, hideIcons);
iconicItems = document.getElementById("menuedit-tabContextMenu").getElementsByAttribute("tmp_iconic", "*");
setClass(iconicItems, hideIcons);
}
}
function TMtabBarScroll (event)
{
var tabs = getBrowser().mTabContainer.childNodes;
var tabBar = getBrowser().mTabContainer;
for (var i = 0; i < tabs.length; i++)
tabs[i].setAttribute("showbutton","off");
var ScrollDirection = event.detail > 0 ? 1 : -1;
if (gPref.getBoolPref("extensions.tabmix.reversedScroll"))
ScrollDirection = -1 * ScrollDirection;
var shouldMoveFocus = gPref.getBoolPref("extensions.tabmix.enableScrollSwitch");
if (shouldMoveFocus)
tabBar.advanceSelectedTab(ScrollDirection, true);
else if ( gPref.getIntPref("extensions.tabmix.tabBarMode") != 2 )
tabBar.collapsedTabs += ScrollDirection;
else if ( gPref.getIntPref("extensions.tabmix.tabBarMode") == 2 )
tabBar.rowScroll(ScrollDirection);
}
function adjustCloseButtons (aNumTabs, oldTab)
{
// don't show close tab button if there is only one blank tab or we keep last tab
var tabBar = getBrowser().mTabContainer;
var tabs = tabBar.childNodes;
var aTab = aNumTabs == 2 && tabs[0] == oldTab ? tabs[1] : tabs[0];
if (tabs.length == aNumTabs &&
(TMP_getBoolPref(tabxBranch, "keepLastTab", false) || getBrowser().isBlankTab(aTab)))
tabBar.setAttribute("hidebutton", "true");
else if (tabBar.hasAttribute("hidebutton"))
tabBar.removeAttribute("hidebutton");
// don't show close tab button if tab width is smaller then pref and not in flexTabs mode
setTimeout( function(tabBar) {
// make sure not to check collapsed tab for width
var width = tabBar.lastChild.boxObject.width;
// 0 width is an invalid value and indicates an item without display,
// so ignore.
var tabClipWidth = TMP_getIntPref("", "browser.tabs.tabClipWidth", 140);
var attributeChanged = false;
if (addtabx != 5 || flexTabs || width > tabClipWidth || width == 0) {
if (tabBar.hasAttribute("tinywidth")) {
tabBar.removeAttribute("tinywidth");
attributeChanged = true;
}
}
else if (!tabBar.hasAttribute("tinywidth")) {
tabBar.setAttribute("tinywidth", "true");
attributeChanged = true;
}
if (attributeChanged) {
tabBarScrollStatus();
checkBeforeAndAfter();
}
}, 0, tabBar);
}
// in Firefox 2.0 + with safebrowsing
// if the current Browser has problem and message is showing we need to
// repaint the "safebrowsing-dim-area-canvas" if we add or remove tabs and
// if we change tabbar position
function adjustSafebrowsingDimArea() {
if (!gIsFirefox2)
return;
var sbC = safebrowsing.controller;
if (sbC == null)
return;
var browser = getBrowser().selectedBrowser;
if (sbC.browserView_.hasProblem(browser)) {
var displayer = sbC.browserView_.getCurrentProblem_(browser).displayer_;
if (displayer.messageShowing_) {
displayer.hideMessage_();
displayer.showMessage_();
}
}
}
function TMP_getBoolPref(branch, prefname, def )
{
try {
if (!gPref)
gPref = getPref();
return gPref.getBoolPref(branch+prefname);
}
catch(er) {
gPref.setBoolPref(branch+prefname, def);
return def;
}
}
function TMP_getIntPref(branch, prefname, def )
{
try {
if (!gPref)
gPref = getPref();
return gPref.getIntPref(branch+prefname);
}
catch(er) {
gPref.setIntPref(branch+prefname, def);
return def;
}
}
function TMP_getCharPref(branch, prefname, def )
{
try {
if (!gPref)
gPref = getPref();
return gPref.getCharPref(branch+prefname);
}
catch(er) {
gPref.setCharPref(branch+prefname, def);
return def;
}
}
function getPref()
{
return Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
}
var TMP_ProgressListener = {
init: function TMP_PL_init(progressListener) {
var _this = "TMP_ProgressListener."
/*
// XXX this is not working in firefox 1.0.x ???
eval("progressListener.onProgressChange = " + progressListener.onProgressChange.toString()
.replace(/}$/,
'this.onStateChange(aWebProgress, aRequest);' +
_this + 'setTabProgress(this.mTab, aMaxTotalProgress, aCurTotalProgress); \ $&'));
*/
function addToTheEnd(fnName, newString) {
var fnString = progressListener[fnName].toString();
fnString = fnString.substr(0, fnString.length - 2) + newString + "}";
eval("progressListener." + fnName + " = " + fnString);
}
addToTheEnd('onProgressChange',
'this.onStateChange(aWebProgress, aRequest);' +
_this + 'setTabProgress(this.mTab, aMaxTotalProgress, aCurTotalProgress);');
// we need to be compatible with XHTML Ruby Support
var fnName = "onStateChange";
var ruby = "__rubysupport__" + fnName;
if (ruby in progressListener)
fnName = ruby;
eval("progressListener." + fnName + " = " + progressListener[fnName].toString().replace(
'this.mTab.setAttribute("busy", "true");',
'$&' + _this + "setTabWidth(this.mTab, this.mBrowser);"
).replace(
'var location = aRequest.QueryInterface(nsIChannel).URI;',
_this + 'setUnreadTab(this.mTab); \ $&'));
addToTheEnd(fnName,
_this + 'setAutoReload(this.mTab, this.mBrowser, aStateFlags);');
// XXX how to do this with Regexp and replace ?
var string = "if (this.mTabBrowser.mCurrentTab == this.mTab)";
var split_fn = progressListener[fnName].toString().split(string);
split_fn[1] += _this + 'updateSessionManager(this.mTab);'
eval("progressListener." + fnName + " = " + split_fn.join(string));
addToTheEnd('onLocationChange',
_this + 'adjustCloseButtons(this.mTab, aLocation.spec);' +
(gIsFirefox2 ? _this + 'fixBug355253(this.mBrowser);' : ''));
return progressListener;
},
setTabProgress: function TMP_PL_setTabProgress(aTab, aMaxTotalProgress, aCurTotalProgress) {
if (aMaxTotalProgress < 1)
return;
var percentage = parseInt((aCurTotalProgress * 100) / aMaxTotalProgress);
if (percentage > 0 && percentage < 100) {
aTab.setAttribute("tab-progress", percentage);
this.adjustCloseButtons(aTab);
}
},
setTabWidth: function TMP_PL_setTabWidth(aTab, aBrowser) {
if (flexTabs && max_width != min_width && !aTab.hasAttribute("width") &&
aTab.label != gBrowser.mStringBundle.getString("tabs.untitled")) {
var uri = aBrowser.currentURI;
if (uri && uri.spec != aTab.label && uri.spec != "about:blank")
aTab.setAttribute("width", aTab.boxObject.width);
}
},
setUnreadTab: function TMP_PL_setUnreadTab(aTab) {
aTab.removeAttribute("tab-progress");
if (gPref.getBoolPref("extensions.tabmix.unreadTab") &&
aTab.hasAttribute("selected") &&
gPref.getBoolPref("extensions.tabmix.unreadTabreload") &&
aTab.getAttribute("selected") == "false")
aTab.removeAttribute("selected");
},
updateSessionManager: function TMP_PL_updateSessionManager(aTab) {
if (aTab.label != gBrowser.mStringBundle.getString("tabs.loading"))
SessionManager.tabLoaded(aTab);
},
setAutoReload: function TMP_PL_setAutoReload(aTab, aBrowser, aStateFlags) {
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
if ((aStateFlags & nsIWebProgressListener.STATE_IS_WINDOW) &&
(aStateFlags & nsIWebProgressListener.STATE_STOP)) {
if (aTab.autoReloadURI)
gBrowser.onTabReloaded(aTab, aBrowser);
// disabled name for locked tab, so locked tab don't get reuse
if (aTab.getAttribute("locked") && aBrowser.contentWindow.name)
aBrowser.contentWindow.name = "";
}
},
adjustCloseButtons: function TMP_PL_adjustCloseButtons(aTab, aUri) {
if (typeof(aUri) == "undefined")
aUri = aTab.parentNode.parentNode.parentNode.parentNode.getBrowserForTab(aTab).currentURI.spec;
if (aUri == "about:blank")
return;
var tabBar = aTab.parentNode;
if (tabBar.childNodes.length == 1 &&
!TMP_getBoolPref(tabxBranch, "keepLastTab", false) && tabBar.hasAttribute("hidebutton"))
tabBar.removeAttribute("hidebutton");
},
// XXX temp fix to bug 355253
// recently closed tabs doesn't saved closed tab if it have "about:blank" first in history.
fixBug355253: function TMP_PL_fixBug355253(aBrowser) {
var history = aBrowser.webNavigation.sessionHistory;
if (history && history.count == 2 && history.index == 1 &&
history.getEntryAtIndex(0, false).URI.spec == "about:blank") {
aBrowser.observe(null, "browser:purge-session-history", null);
var backCommand = document.getElementById("Browser:Back");
if (backCommand)
backCommand.setAttribute("disabled", "true");
}
}
}
PK
{6OKX KX ! content/tabmixplus/tab/tabmix.xml
%identityDTD;
%tabmixDTD;
]>
false
false
0
0
0
0
0
this._collapsedTabs && this.rightEnd ) {
this.canScrollTabsRight = false;
val = this._collapsedTabs;
return val;
}
if ( val < 0 ) val = 0;
for(i = 0; i < val; i++) tabs[i].collapsed = true;
for(i = val; i < tabs.length; i++) tabs[i].collapsed = false;
this._collapsedTabs = val;
this.canScrollTabsLeft = (val != 0);
this.canScrollTabsRight = !this.rightEnd;
return val;
]]>
tabs.length - 1)
return false;
var tab = tabs[aIndex];
var tabhbox = document.getElementById("scroll-tabs-frame");
if (this.collapsedTabs > aIndex)
return false;
if ( gPref.getIntPref("extensions.tabmix.tabBarMode") != 2 ) {
if (tab.boxObject.x + tab.boxObject.width > tabhbox.boxObject.x + tabhbox.boxObject.width)
return false;
} else if ( this.getAttribute("multibar") == "scrollbar" ) {
if ( tab.baseY > this.parentNode.boxObject.y + this.parentNode.boxObject.height + 2)
return false;
}
return true;
]]>
tabs.length - 1)
return;
var tab = tabs[aIndex];
var amount, i, j;
var tabhbox = document.getElementById("scroll-tabs-frame");
if ( tabhbox.boxObject.width < 250 )
return;
if ( gPref.getIntPref("extensions.tabmix.tabBarMode") != 2 ) {
if(aIndex < this.collapsedTabs)
this.collapsedTabs = aIndex;
else {
var amountToCollapse = tab.boxObject.x + tab.boxObject.width - tabhbox.boxObject.x - tabhbox.boxObject.width;
if(amountToCollapse > 0) {
amount = 0;
i = this.collapsedTabs;
while(amount < amountToCollapse) {
amount += tabs[i].boxObject.width;
i++;
}
this.collapsedTabs = i;
}
}
}
else if ( this.getAttribute("multibar") == "scrollbar" ) {
if (aIndex < this.collapsedTabs) {
while (aIndex < this.collapsedTabs)
this.rowScroll(-1);
}
else {
var bottom = this.parentNode.boxObject.y + this.parentNode.boxObject.height + 2;
while (tab.baseY > bottom )
this.rowScroll(+1);
}
}
]]>
0 && inSameRow(tabs[i], tabs[j]) )
tabs[--i].collapsed = false;
}
else {
while ( inSameRow(tabs[i], tabs[j]) )
i++;
}
if (i != j)
this.collapsedTabs = i;
]]>
PK
=6Oba0 0 % content/tabmixplus/tab/tabmix_old.xml
%identityDTD;
%tabmixDTD;
]>
0
this._collapsedTabs && this.rightEnd ) {
this.canScrollTabsRight = false;
val = this._collapsedTabs;
return val;
}
if ( val < 0 ) val = 0;
for(i = 0; i < val; i++) tabs[i].collapsed = true;
for(i = val; i < tabs.length; i++) tabs[i].collapsed = false;
this._collapsedTabs = val;
this.canScrollTabsLeft = (val != 0);
this.canScrollTabsRight = !this.rightEnd;
return val;
]]>
tabs.length - 1)
return false;
var tab = tabs[aIndex];
var tabhbox = document.getElementById("scroll-tabs-frame");
if (this.collapsedTabs > aIndex)
return false;
if ( gPref.getIntPref("extensions.tabmix.tabBarMode") != 2 ) {
if (tab.boxObject.x + tab.boxObject.width > tabhbox.boxObject.x + tabhbox.boxObject.width)
return false;
} else if ( this.getAttribute("multibar") == "scrollbar" ) {
if ( tab.baseY > this.parentNode.boxObject.y + this.parentNode.boxObject.height + 2)
return false;
}
return true;
]]>
tabs.length - 1)
return;
var tab = tabs[aIndex];
var amount, i, j;
var tabhbox = document.getElementById("scroll-tabs-frame");
if ( tabhbox.boxObject.width < 250 )
return;
if ( gPref.getIntPref("extensions.tabmix.tabBarMode") != 2 ) {
if(aIndex < this.collapsedTabs)
this.collapsedTabs = aIndex;
else {
var amountToCollapse = tab.boxObject.x + tab.boxObject.width - tabhbox.boxObject.x - tabhbox.boxObject.width;
if(amountToCollapse > 0) {
amount = 0;
i = this.collapsedTabs;
while(amount < amountToCollapse) {
amount += tabs[i].boxObject.width;
i++;
}
this.collapsedTabs = i;
}
}
}
else if ( this.getAttribute("multibar") == "scrollbar" ) {
if (aIndex < this.collapsedTabs) {
while (aIndex < this.collapsedTabs)
this.rowScroll(-1);
}
else {
var bottom = this.parentNode.boxObject.y + this.parentNode.boxObject.height + 2;
while (tab.baseY > bottom )
this.rowScroll(+1);
}
}
]]>
0 && inSameRow(tabs[i], tabs[j]) )
tabs[--i].collapsed = false;
}
else {
while ( inSameRow(tabs[i], tabs[j]) )
i++;
}
if (i != j)
this.collapsedTabs = i;
]]>
PK
6 content/tabmixplus/session/PK
35R7# # + content/tabmixplus/session/promptservice.js var dialogParams, gHideElmParam, gSavedName, gCancelLabel, gOrigName;
function prompt_init() {
dialogParams = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
document.title = dialogParams.GetString(0);
// display the main text
var i, messageText = dialogParams.GetString(1);
var messageParent = document.getElementById("tm_info");
var messageParagraphs = messageText.split("\n");
gHideElmParam = dialogParams.GetInt(1);
for (i = 0; i < messageParagraphs.length; i++) {
var descriptionNode = document.createElement("description");
var text = document.createTextNode(messageParagraphs[i]);
descriptionNode.appendChild(text);
messageParent.appendChild(descriptionNode);
}
// display the menulist
gHideElmParam = dialogParams.GetInt(1);
var menuList = document.getElementById("tm_prompt");
if (gHideElmParam == SHOW_MENULIST) {
var index, isDisabled, popup = document.getElementById("tm_prompt_menu");
SessionManager.createMenuForDialog(popup, dialogParams.GetInt(3));
switch ( dialogParams.GetInt(3) ) {
case SELECT_CRASH: index = popup.childNodes.length - 1;
break;
case SHOW_CLOSED_WINDOW_LIST: index = 1; // 0 is menuseparator
break;
default:
index = menuList.defaultIndex;
if (index >= popup.childNodes.length || index < 0) index = 1;
isDisabled = popup.childNodes[index].getAttribute("disabled") == "true";
// select the first entry that isn't menuseparator and not "disabled"
if (!isDisabled) break;
var item;
for (i = 1; i < popup.childNodes.length; ++i) {
item = popup.childNodes[i];
if (item.localName == "menuseparator") continue;
if (item.getAttribute("disabled") != "true") {
index = i;
break;
}
}
}
menuList.selectedIndex = index;
} else menuList.hidden = true;
// display the textBox
var textBox = document.getElementById("tm_textbox");
if (gHideElmParam == SHOW_TEXTBOX) {
messageParent.lastChild.setAttribute("style","height:3em");
gSavedName = dialogParams.GetString(2).split("\n");
textBox.value = gSavedName.shift();
gOrigName = textBox.value.toLowerCase();
}
else textBox.hidden = true;
// display the checkbox
var checkBox = document.getElementById("tm_checkbox");
var check = dialogParams.GetInt(2);
if (check != HIDE_CHECKBOX) {
document.getElementById("checkboxContainer").removeAttribute("collapsed");
checkBox.checked = check == CHECKBOX_CHECKED;
setLabelForNode(checkBox, dialogParams.GetString(3));
}
// display the command buttons
var aButtons, buttons = ["accept", "cancel", "extra1"];
var btnLabels = dialogParams.GetString(4).split("\n");
var maxWidth = 0;
for (i = 0; i < buttons.length; ++i) {
aButtons = document.documentElement.getButton(buttons[i]);
if (i < btnLabels.length && btnLabels[i] != "") {
setLabelForNode(aButtons, btnLabels[i]);
}
else aButtons.hidden = true; // hide extra button
}
// Set and focus default button
var dButton = buttons[dialogParams.GetInt(0)];
var dialog = document.documentElement;
dialog.defaultButton = dButton;
if (gHideElmParam == HIDE_MENUANDTEXT) { // hide menulist & text box and set focus to default Button
document.getElementById("space_befor_checkbox").hidden = true;
dialog.getButton(dButton).focus();
}
if (gHideElmParam == SHOW_TEXTBOX) {
dialog.getButton("extra1").hidden = true;
gCancelLabel = dialog.getButton("cancel").label;
inputText(textBox);
}
}
function prompt_deinit(button) {
dialogParams.SetInt(4, button); // ok = 0; cancel = 1; extra1 = 2;
dialogParams.SetInt(5, document.getElementById("tm_checkbox").checked);
if (gHideElmParam < HIDE_MENUANDTEXT) {
if (gHideElmParam == SHOW_MENULIST) {
var item = document.getElementById("tm_prompt").selectedItem;
dialogParams.SetString(5, item.session);
dialogParams.SetInt(6, item.getAttribute("value"));
}
else dialogParams.SetString(5, document.getElementById("tm_textbox").value);
}
}
function prompt_extra1(button) {
prompt_deinit(button);
window.close();
}
function inputText(textBox) {
var btnOK = document.documentElement.getButton("accept");
var btnCancel = document.documentElement.getButton("cancel");
var btnExt = document.documentElement.getButton("extra1");
var msg = [];
var bundle_session = document.getElementById("bundle_session_manager");
msg[0] = "";
/*
var msg1 = "Name must be at least one letter or number."
var msg2 = "This name already in use!"
var msg3 = "Are you sure you want to replace the session?"
var cLabel = "&Don't Replace";
*/
msg[1] = bundle_session.getString("sm.sessionName.msg1");
msg[2] = bundle_session.getString("sm.sessionName.msg2");
msg[3] = msg[2] + ", " + bundle_session.getString("sm.sessionName.msg3");
var cLabel = SessionManager.setLabel("sm.replaceStartup.button1");
var description = document.getElementById("tm_info").lastChild.firstChild;
textBox.value = textBox.value.replace(/^[\s]+/g,"");
var name = textBox.value.toLowerCase();
var msgReplace, validName = 0;
if (name == "") validName = 1;
if (validName==0) {
for (var i = 0; i < gSavedName.length; i++) {
if (name == gSavedName[i].toLowerCase() && gSavedName[i] != "" ) {
if (dialogParams.GetInt(3) == DLG_RENAME) {
if (gOrigName != name) validName = 2;
continue;
}
validName = 3;
dialogParams.SetInt(6, i);
break;
}
}
}
switch ( validName ) {
case 0:
if (btnOK.disabled) btnOK.disabled = false;
if (btnOK.hidden) btnOK.hidden = false;
if (!btnExt.hidden) {
btnExt.hidden = true;
if (dialogParams.GetInt(3) == DLG_SAVE) setLabelForNode(btnCancel,gCancelLabel);
}
description.replaceData(0,description.length, "");
document.documentElement.defaultButton = "accept";
break;
case 1:
case 2:
if (btnOK.hidden) btnOK.hidden = false;
if (!btnOK.disabled) btnOK.disabled = true;
if (!btnExt.hidden) {
btnExt.hidden = true;
if (dialogParams.GetInt(3) == DLG_SAVE) setLabelForNode(btnCancel,gCancelLabel);
}
document.documentElement.defaultButton = "cancel";
break;
case 3:
if (!btnOK.hidden) btnOK.hidden = true;
btnExt.hidden = false;
if (dialogParams.GetInt(3) == DLG_SAVE) setLabelForNode(btnCancel,cLabel);
document.documentElement.defaultButton = "cancel";
break;
}
description.replaceData(0,description.length, msg[validName]);
}
function TM_PromptService(intParam, strParam, aWindow) {
var dpb = Components.classes["@mozilla.org/embedcomp/dialogparam;1"]
.createInstance(Components.interfaces.nsIDialogParamBlock);
// intParam[0] - default button accept=0, cancel=1, extra1=2
// intParam[1] - show menuList= 1 , show textBox= 0, hide_both= 2
// intParam[2] - set checkbox checked true=1 , false=0, hide=2
// intParam[3] - flag - for menuList contents: flag to set menu selected item
// - for textBox rename: 1 , save: 0
var i;
for (i = 0; i < intParam.length; i++)
dpb.SetInt(i, intParam[i]);
// strParam labels for: title, msg, testbox.value, checkbox.label, buttons[]
// buttons[]: labels array for each button
for (i = 0; i < strParam.length; i++)
dpb.SetString(i, strParam[i]);
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
if (typeof(aWindow) == "undefined") {
try { aWindow = window;
}
catch (e) { aWindow = null;
}
}
ww.openWindow(aWindow,
"chrome://tabmixplus/content/session/promptservice.xul","",'centerscreen,modal',dpb);
return {button: dpb.GetInt(4), checked: (dpb.GetInt(5) == CHECKBOX_CHECKED), label: dpb.GetString(5), value: dpb.GetInt(6)};
}
PK
!4V V , content/tabmixplus/session/promptservice.xul
PK
沼6~+= = % content/tabmixplus/session/session.jsconst gRDFRoot = "rdf://tabmix";
const HSitems = 3; // in history we have title, url, scrollpos
var NC_TM = [];
var gSessionPath = ["", "", "", ""];
var nsIPrefServiceObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
var SessionPref = nsIPrefServiceObj.getBranch("extensions.tabmix.sessions.");
var gThisWin = null;
var gThisWinTabs = null;
var gThisWinClosedtabs = null;
var tmSHEntry = Components.interfaces.nsISHEntry;
var tmSHistory = Components.interfaces.nsISHistory;
var tmRDFResource = Components.interfaces.nsIRDFResource;
const BUTTON_OK = 0;
const BUTTON_CANCEL = 1;
const BUTTON_EXTRA1 = 2;
const SHOW_MENULIST = 1;
const SHOW_TEXTBOX = 0;
const HIDE_MENUANDTEXT = 2;
const CHECKBOX_UNCHECKED = 0;
const CHECKBOX_CHECKED = 1;
const HIDE_CHECKBOX = 2;
const SELECT_DEFAULT = 0;
const SELECT_LASTSESSION = 1;
const SELECT_CRASH = 2;
const SHOW_CLOSED_WINDOW_LIST = 3;
const DLG_SAVE = 0;
const DLG_RENAME = 1;
const NO_NEED_TO_REPLACE = -1;
function tmLog(aMessage) {
var tmConsoleService = Components.classes['@mozilla.org/consoleservice;1']
.getService(Components.interfaces.nsIConsoleService);
tmConsoleService.logStringMessage('TabMix: \n' + aMessage);
}
function object2String(_obj, aMessage) {
aMessage = aMessage ? aMessage : "";
var _objS = _obj.toString() + ":\n";
for (var item in _obj)
try {
_objS += item + " = " + _obj[item] + "\n";
} catch (er) { _objS += item + " = " + "error in this item" + "\n";}
tmLog(aMessage + "\n=============== object to string ===============\n" + _objS);
return _objS;
}
/*
sanitize privte data by delete the files session.rdf session.old
*/
var TMP_Sanitizer = {
addSanitizeItem: function ()
{
window.removeEventListener('load', TMP_Sanitizer.addSanitizeItem, true);
if (typeof Sanitizer != 'function')
return;
// Sanitizer will execute this
Sanitizer.prototype.items['extensions-tabmix'] = {
clear : function() {
try {
TMP_Sanitizer.sanitize();
} catch (ex) {
try { Components.utils.reportError(ex); } catch(ex) {}
}
},
get canClear() {
return true;
}
}
},
addMenuItem: function ()
{
var prefs = document.getElementsByTagName('preferences')[0];
var firstCheckbox = document.getElementsByTagName('checkbox')[0];
if (prefs && firstCheckbox) // if this isn't true we are lost :)
{
var pref = document.createElement('preference');
pref.setAttribute('id', 'privacy.item.extensions-tabmix');
pref.setAttribute('name', 'privacy.item.extensions-tabmix');
pref.setAttribute('type', 'bool');
prefs.appendChild(pref);
var check = document.createElement('checkbox');
check.setAttribute('label', tabmixSanitize.label);
check.setAttribute('accesskey', tabmixSanitize.accesskey);
check.setAttribute('preference', 'privacy.item.extensions-tabmix');
firstCheckbox.parentNode.insertBefore(check, firstCheckbox);
if (typeof(gSanitizePromptDialog) == 'object')
{
pref.setAttribute('readonly', 'true');
check.setAttribute('onsyncfrompreference', 'return gSanitizePromptDialog.onReadGeneric();');
}
}
},
tryToSanitize: function ()
{
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
try {
var promptOnSanitize = prefService.getBoolPref("privacy.sanitize.promptOnSanitize");
} catch (e) { promptOnSanitize = true;}
// if promptOnSanitize is true we call TMP_Sanitizer.sanitize from Firefox Sanitizer
if (promptOnSanitize)
return false;
try {
var sanitizeTabmix = prefService.getBoolPref("privacy.item.extensions-tabmix");
} catch (e) { sanitizeTabmix = false;}
if (!sanitizeTabmix)
return false;
this.sanitize();
return true;
},
// XXX need to add test if we fail to delete then alert the user or ....?
sanitize: function ()
{
// get file references
var dirService = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var sessionFile = dirService.get("ProfD", Components.interfaces.nsILocalFile);
var sessionFileBackup = sessionFile.clone();
sessionFile.append("session.rdf");
sessionFileBackup.append("session.old");
// remove the files from the disk
this.clearDisk(sessionFile);
this.clearDisk(sessionFileBackup);
// init new DATASource for all open window
var enumerator = windowEnumerator();
var wnd, _sessionManager, broadcaster, btn;
while ( enumerator.hasMoreElements() ) {
wnd = enumerator.getNext();
// clear DATASource
delete wnd.gBrowser.windowID;
_sessionManager = wnd.SessionManager;
_sessionManager.corruptedFile = false;
_sessionManager.RDFService.UnregisterDataSource(_sessionManager.DATASource);
// init new DATASource
_sessionManager.initDATASource();
// disable closed window list button
broadcaster = wnd.document.getElementById("tmp_closedwindows");
if (broadcaster)
broadcaster.setAttribute("disabled",true);
// clear closed tabs and disable the button
wnd.gBrowser.closedTabs = [];
btn = wnd.document.getElementById("btn_undoclose");
if (btn)
btn.setAttribute("disabled", true);
}
},
clearDisk: function (file)
{
if (file.exists()) {
try {
file.remove(false);
}
catch (ex) { dump(ex + '\n'); } // couldn't remove the file - what now?
}
}
}
var SessionData = {
docShellItems: ["allowImages","allowSubframes","allowMetaRedirects","allowPlugins","allowJavascript"],
tabAttribute: ["protected","locked"],
getTabProperties: function(aTab, checkPref) {
if (typeof(checkPref) == "undefined") checkPref = false; // pref check is only for session manager
var tabProperties = "", temp;
for ( var j = 0; j < this.tabAttribute.length; j++ ){
temp = aTab.hasAttribute(this.tabAttribute[j]) ? aTab.getAttribute(this.tabAttribute[j]) : "false";
tabProperties += (temp=="true") ? "1" : "0";
}
// if save.permissions is false we save all Permissions as on, so if we change this pref after session
// was saved, the session will load with Permissions as on.
if (checkPref && !SessionPref.getBoolPref("save.permissions")) return tabProperties + "11111";
var aTabDocShell = gBrowser.getBrowserForTab(aTab).docShell;
for ( j = 0; j < this.docShellItems.length; j++ ){
tabProperties += aTabDocShell[this.docShellItems[j]] ? "1" : "0";
}
return tabProperties;
},
setTabProperties: function(aTab, tabProperties, checkPref) {
if (typeof(checkPref) == "undefined") checkPref = false; // pref check is only for session manager
var aPermission;
var k = this.tabAttribute.length;
for ( var j = 0; j < k; j++ ){
//extensions.tabmix.sessions.save.protected && extensions.tabmix.sessions.save.locked
if (!checkPref || SessionPref.getBoolPref("save." + this.tabAttribute[j])) {
if (tabProperties.charAt(j) == "1") aTab.setAttribute(this.tabAttribute[j], "true");
else if (aTab.hasAttribute(this.tabAttribute[j])) aTab.removeAttribute(this.tabAttribute[j]);
}
}
if (checkPref && !SessionPref.getBoolPref("save.permissions")) return;
var aTabDocShell = gBrowser.getBrowserForTab(aTab).docShell;
for ( j = 0; j < this.docShellItems.length; j++ ) {
aPermission = tabProperties.charAt(j + k) == "1";
if (aTabDocShell[this.docShellItems[j]] != aPermission)
aTabDocShell[this.docShellItems[j]] = aPermission;
}
}
}
function windowEnumerator() {
var WindowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
.getService(Components.interfaces.nsIWindowMediator);
return WindowManager.getEnumerator("navigator:browser");
}
function numberOfWindows(all) {
var enumerator = windowEnumerator();
var count = 0;
while ( enumerator.hasMoreElements() ) {
var win = enumerator.getNext();
if (win.SessionManager.windowClosed)
continue;
count++;
if (!all && count == 2)
break;
}
return count;
}
var SessionManager = {
RDFService: null,
CONUtils: null,
DATASource: null,
IOService: null,
overwriteWindow: false,
saveThisWindow: true,
NC_NS : "http://home.netscape.com/NC-rdf#",
enableBackup: null,
enableManager: null,
enableSaveHistory: null,
saveClosedtabs: null,
corruptedFile: false,
// call by TM_init
init: function SM_init() {
this.enableManager = SessionPref.getBoolPref("manager");
this.enableBackup = SessionPref.getBoolPref("crashRecovery");
this.enableSaveHistory = SessionPref.getBoolPref("save.history");
this.saveClosedtabs = SessionPref.getBoolPref("save.closedtabs") &&
tabxPrefs.getBoolPref("undoClose");
if (!this.DATASource) this.initService();
var isFirstWindow = numberOfWindows() == 1 && !window.duplicat;
var path, status, caller, crashed;
if (isFirstWindow) {
path = gRDFRoot + "/closedSession/thisSession";
status = this.getLiteralValue(path, "status");
crashed = status.indexOf("crash") != -1;
// if this isn't delete on exit, we know next time that firefox crash
SessionPref.setBoolPref("crashed" , true); // we use this in setup.js;
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
this.setLiteral(path, "status", "crash");
// check if we after restart
var afterRestart = false;
if (tabxPrefs.prefHasUserValue("resume_session_once")) {
afterRestart = tabxPrefs.getBoolPref("resume_session_once");
tabxPrefs.clearUserPref("resume_session_once");
}
if (!this.enableManager && (!this.enableBackup || !crashed)) {
// we not after crash and session manager not enabled ...
// we delete previous closed session
this.removeAllClosedSession();
this.dataFlush();
return;
}
if (crashed)
this.openAfterCrash(status);
else if (this.enableManager)
// this.openFirstWindow(false, afterRestart);
// XXX don't do auto restore after restart until we fix some bugs....
this.openFirstWindow(false, false);
if (tabxPrefs.prefHasUserValue("warnAboutClosingTabs.timeout"))
tabxPrefs.clearUserPref("warnAboutClosingTabs.timeout")
} else if (this.enableManager && "tabmixdata" in window) {
path = window.tabmixdata.path;
caller = window.tabmixdata.caller;
if (caller == "concatenatewindows")
this.loadSession(path, caller, false);
else
this.loadOneWindow(path, "windowopenebytabmix");
}
if (this.enableManager)
this.updateClosedWindowsMenu("check");
this.dataFlush();
},
// call by TM_deinit
deinit: function SM_deinit(isLastWindow, askBeforSave, startTime) {
// When Exit Firefox:
// pref "extensions.tabmix.sessions.onClose"
// 0 - Save
// 1 - Ask me Befor Save
// 2 (or else) - Don't Save
// we check this when last window is about to close for all other window the session is saved
// in closed window list.
// in the last window if the user pref in not to save we delete the closed window list.
if (this.windowClosed)
return;
this.windowClosed = true;
// check if we need to sanitize on exit without prompt to user
try {
if (!gIsOldBrowser && isLastWindow && gPref.getBoolPref("privacy.sanitize.sanitizeOnShutdown")) {
// if tryToSanitize is false and privacy.sanitize.promptOnSanitize is true
// we call TMP_Sanitizer.sanitize from Firefox Sanitizer
if (TMP_Sanitizer.tryToSanitize())
return;
}
} catch (err) {}
var closedWinList = document.getElementById("tmp_closedwindows").getAttribute("disabled");
if (this.enableManager && this.saveThisWindow) {
for (var i = 0; i < gBrowser.mTabs.length; i++)
gBrowser.mTabs[i].removeAttribute("inrestore");
this.saveOneWindow(gSessionPath[0], "windowclosed");
}
if (isLastWindow) {
if ( this.enableManager ) {
var result = {}, saveClosedTabs;
result.button = SessionPref.getIntPref("onClose");
result.checked = saveClosedTabs = this.saveClosedtabs;
// firefox closed by restart, always save the session
// XXX don't do auto restore after restart until we fix some bugs....
// if (!askBeforSave) {
// tabxPrefs.setBoolPref("resume_session_once", true);
if (result.button == 1 && !askBeforSave) {
result.button = BUTTON_OK;
}
// delete closed windows
var pref = "extensions.tabmix.warnAboutClosingTabs.timeout";
var delay = gPref.prefHasUserValue(pref) ? gPref.getCharPref(pref)*1 : 0;
var curTime = !startTime ? new Date().valueOf() - delay : startTime - delay;
var rdfNodeClosedWindows = this.RDFService.GetResource(gSessionPath[0]);
var sessionContainer = this.initContainer(rdfNodeClosedWindows);
this.checkTime(sessionContainer, curTime);
this.deleteWithProp(sessionContainer, "dontLoad");
// count windows and tabs in this session
var count = this.countWinsAndTabs(sessionContainer);
if (count.win > 0 && count.tab > 0 &&
result.button == 1) { // Ask me Befor Save
document.getElementById("tmp_closedwindows").setAttribute("disabled", closedWinList);
window.focus();
var bundle_session = document.getElementById("bundle_session_manager");
var title = bundle_session.getString("sm.askBeforSave.title");
var msg = bundle_session.getString("sm.askBeforSave.msg0") + "\n\n"
+ bundle_session.getString("sm.askBeforSave.msg1");
var chkBoxLabel = bundle_session.getString("sm.saveClosedTab.chkbox.label");
var chkBoxState = saveClosedTabs ? CHECKBOX_CHECKED : HIDE_CHECKBOX;
var buttons = [this.setLabel("sm.askBeforSave.button0"),
this.setLabel("sm.askBeforSave.button1")].join("\n");
result = TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, chkBoxState],
[title, msg, "", chkBoxLabel, buttons]);
}
if (result.button == BUTTON_OK) {
this.setLiteral(rdfNodeClosedWindows, "nameExt",
this.getNameData(count.win, count.tab));
// delete closed tab list for this session
if (saveClosedTabs && !result.checked)
this.deleteAllClosedtabs(sessionContainer);
}
else
// delete the closed window list.
this.deleteSubtree(gSessionPath[0]);
}
if (this.enableBackup) this.deleteSession(gSessionPath[3]);
if (tabxPrefs.prefHasUserValue("warnAboutClosingTabs.timeout"))
tabxPrefs.clearUserPref("warnAboutClosingTabs.timeout");
if (SessionPref.prefHasUserValue("crashed"))
SessionPref.clearUserPref("crashed"); // we use this in setup.js;
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
this.setLiteral(gRDFRoot + "/closedSession/thisSession", "status", "");
if (!this.enableManager && !this.enableBackup)
this.deleteSession(gSessionPath[0]);
this.dataFlush();
}
},
// XXX split this for each pref that has change
// XXX need to update after permissions, locked, locked
updateSettings: function() {
// list of session manager pref
// sessions.manager - ok
// sessions.crashRecovery - ok
// sessions.save.closedtabs - ok
// sessions.save.history - ok
// sessions.save.permissions - ok (update evry time this function run because lock is change)
// sessions.save.locked - ok (update evry time this function run because lock is change)
// sessions.save.protected - ok (update evry time this function run because lock is change)
// sessions.save.selectedtab - ok
// xxx sessions.save.scrollposition - ok (update with history) // xxx need to divide it
// undoClose -
// undoCloseCache -
//
var sessionManager = tabxPrefs.getBoolPref("sessions.manager");
var crashRecovery = tabxPrefs.getBoolPref("sessions.crashRecovery");
var enableClosedtabs = tabxPrefs.getBoolPref("sessions.save.closedtabs");
var enableSaveHistory = tabxPrefs.getBoolPref("sessions.save.history");
var undoClose = tabxPrefs.getBoolPref("undoClose");
var cache = tabxPrefs.getIntPref("undoCloseCache");
// hide or show session manager buttons & menus
document.getElementById("tm-sessionmanager").hidden = !sessionManager || !tabxPrefs.getBoolPref("sessionToolsMenu");
var hiddenPref = !sessionManager || !tabxPrefs.getBoolPref("closedWinToolsMenu");
document.getElementById("tm-sm-closedwindows").hidden = hiddenPref;
document.getElementById("tm-sm-closedwindows2").hidden = !hiddenPref;
var button = document.getElementById("btn_sessionmanager");
if (button)
button.setAttribute("disabled",!sessionManager);
// we dont need this function to run befor sessionmanager init
// this.enableBackup=null so we dont past the next if
if (!this.DATASource) return;
var windowSaved = false, closedTabSaved = false;
if (this.enableBackup != crashRecovery) {
if (crashRecovery) { // save all open window and tab
this.saveAllWindows(gSessionPath[0], "windowbackup");
windowSaved = true;
} else { // remove all backup
this.deleteSession(gSessionPath[0], "status", "backup");
this.deleteSession(gSessionPath[3]);
this.initSession(gSessionPath[0], gThisWin);
this.dataFlush();
}
this.enableBackup = crashRecovery;
}
var winPath = gThisWin;
if (crashRecovery)
this.tabSelected(); // this is fast so we dont check if the pref is changed ( just for now)
if (this.enableManager != sessionManager) {
this.enableManager = sessionManager;
}
if (undoClose) {
while ( gBrowser.closedTabs.length > cache ) getClosedTab('delete', 0); // delete extra closedTabs from closedtabs list and session.RDF
} else if (gBrowser.closedTabs.length > 0) delayRestoreTab("original", -1); // flush closedtabs list and session.RDF
if (this.saveClosedtabs != enableClosedtabs && undoClose) {
this.saveClosedtabs = enableClosedtabs && undoClose;
if (enableClosedtabs) {
// save if gBrowser.closedTabs.length > 0 and we save backup and save closedtab backup
if (crashRecovery && gBrowser.closedTabs.length > 0 && undoClose) {
this.initSession(gSessionPath[0], winPath);
this.copyClosedTabsToRDF(winPath);
}
closedTabSaved = true;
} else {
// if undoClose = false we delete all above
if (undoClose) this.deleteWinClosedtabs(winPath); // flush only closedTabs list in session.RDF
}
}
if (this.enableSaveHistory != enableSaveHistory) {
this.enableSaveHistory = enableSaveHistory;
if (crashRecovery) {
if (!windowSaved) this.saveAllTab(winPath, 0);
if (!closedTabSaved && enableClosedtabs && gBrowser.closedTabs.length > 0 && undoClose) {
this.initSession(gSessionPath[0], winPath);
this.deleteWinClosedtabs(winPath);
this.copyClosedTabsToRDF(winPath);
closedTabSaved = true;
}
}
}
if (closedTabSaved) {
this.initSession(gSessionPath[0], gThisWin);
this.dataFlush();
}
},
loadHomePage: function() {
var homePage = gHomeButton.getHomePage();
if (homePage == window.arguments[0]) {
this.setStripVisibility(homePage.split("|").length);
BrowserHome();
if (!gBrowser.isBlankBrowser(gBrowser.mCurrentBrowser))
content.focus();
}
else if (gBrowser.mCurrentTab.loadOnStartup)
for (var i = 0; i < gBrowser.mTabs.length ; i++)
delete gBrowser.mTabs[i].loadOnStartup;
else
gBrowser.mCurrentBrowser.reload();
},
// init common services
initService: function() {
this.RDFService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
this.CONUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]
.getService(Components.interfaces.nsIRDFContainerUtils);
this.IOService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
this.setNC_TM();
this.initDATASource();
},
initDATASource: function SM_initDATASource() {
var file = this.profileDir;
file.append("session.rdf");
var uri = this.IOService.newFileURI(file).spec;
try {
this.DATASource = this.RDFService.GetDataSourceBlocking(uri);
} catch (e) { // corrupted session.rdf
var bundle_session = document.getElementById("bundle_session_manager");
var title = bundle_session.getString("sm.corrupted.title");
var msg = bundle_session.getString("sm.corrupted.msg0") + "\n"
+ bundle_session.getString("sm.corrupted.msg1");
var buttons = ["", this.setLabel("sm.button.continue")].join("\n");
TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],[title, msg, "", "", buttons]);
tmLog(e);
file.moveTo(this.profileDir, "session.old");
this.DATASource = this.RDFService.GetDataSourceBlocking(uri);
this.corruptedFile = true;
}
// set path to session type
var path = gRDFRoot + "/closedSession/";
var sessionType = ["thisSession", "lastSession", "previoustolastSession", "crashedsession"];
var closedSession = this.initContainer(path);
var i, aEntry;
if (closedSession.GetCount()==0) { // create the list
for (i = 0; i < sessionType.length; i++) {
aEntry = this.RDFService.GetResource(path + sessionType[i]);
this.setResource(aEntry, "session", gRDFRoot + "/closed" + i + "/window");
closedSession.AppendElement(aEntry);
}
}
for (i = 0; i < sessionType.length; i++) {
gSessionPath[i] = this.getResourceValue(path + sessionType[i], "session");
}
if (typeof(gBrowser) == "object" && !gBrowser.windowID) {
gBrowser.windowID = this.RDFService.GetAnonymousResource().Value.split("rdf:")[1];
gThisWin = gSessionPath[0] + "/" + gBrowser.windowID;
gThisWinTabs = gThisWin + "/tabs";
gThisWinClosedtabs = gThisWin + "/closedtabs";
}
},
get profileDir() {
return Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsILocalFile);
},
setNC_TM: function() {
var rdfLabels = ["tabs","closedtabs","index","history","properties","selectedIndex",
"timestamp","title","url","dontLoad","reOpened","name","nameExt","session",
"status","tabPos","image","scroll","winFeatures"];
for (var i = 0; i < rdfLabels.length; i++) {
NC_TM[rdfLabels[i]] = this.RDFService.GetResource(this.NC_NS + rdfLabels[i]);
}
},
setLabel: function(property, bundleID) {
var strimgBundle = bundleID ? document.getElementById(bundleID) :
document.getElementById("bundle_session_manager");
var label = strimgBundle.getString(property + ".label");
var key = strimgBundle.getString(property + ".accesskey");
var accessKeyIndex = label.toLowerCase().indexOf(key.toLowerCase());
if (accessKeyIndex > -1)
label = label.substr(0, accessKeyIndex) + "&" + label.substr(accessKeyIndex);
return label;
},
deleteNode: function(rdfNode) {
var arcOut = this.DATASource.ArcLabelsOut(rdfNode);
while (arcOut.hasMoreElements()) {
var aLabel = arcOut.getNext();
if (aLabel instanceof tmRDFResource) {
var aTarget = this.DATASource.GetTarget(rdfNode, aLabel, true);
this.DATASource.Unassert(rdfNode, aLabel, aTarget);
}
}
},
deleteSubtree: function(labelRoot) {
var allElements = this.DATASource.GetAllResources();
while (allElements.hasMoreElements()) {
var aResource = allElements.getNext();
if ((aResource instanceof tmRDFResource) && (aResource.Value.indexOf(labelRoot) == 0))
this.deleteNode(aResource);
}
},
initContainer: function(node) {
var pNode = node;
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
try{
return this.CONUtils.MakeSeq(this.DATASource, node);
} catch (e) {
tmLog("Error in initContainer" + "\n" + "node = " + pNode + "\n\n" + "caller " + this.initContainer.caller.name);
return "error"
}
},
// return true if node is empty container or node is not container
containerEmpty: function(node) {
var pNode = node;
try{
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
if (!this.CONUtils.IsContainer(this.DATASource, node)) return true;
return this.CONUtils.IsEmpty(this.DATASource, node);
} catch (e) {
tmLog("Error in containerEmpty" + "\n" + "node = " + pNode + "\n\n" + "caller " + this.containerEmpty.caller.toString().split(";")[0]);
return "error"
}
},
wrapContainer: function SM_wrapContainer(path, prop) {
var root = this.getResource(path, prop);
var container = this.initContainer(root);
if (container == "error") { tmLog("wrapContainer error path " + path + "\n" + "prop " + prop); return "error"}
return {
Root: root,
Container: container,
Enum: container.GetElements(),
Count: container.GetCount()
}
},
getValue: function(node, label, typeID, def) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
label = NC_TM[label];
var rdfNode = this.DATASource.GetTarget(node, label, true);
return (rdfNode instanceof Components.interfaces[typeID]) ? rdfNode.Value : def;
},
getLiteralValue: function(node, arc, def) {
if (typeof(def) == "undefined") def = "";
return this.getValue(node, arc, "nsIRDFLiteral", def);
},
getIntValue: function(node, arc, def) {
if (typeof(def) == "undefined") def = 0;
return this.getValue(node, arc, "nsIRDFInt", def);
},
getResourceValue: function(node, arc, def) {
if (typeof(def) == "undefined") def = null;
return this.getValue(node, arc, "nsIRDFResource", def);
},
getResource: function(node, arc) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
arc = NC_TM[arc];
return this.DATASource.GetTarget(node, arc, true);
},
nodeHasArc: function(node, arc) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
arc = NC_TM[arc];
return this.DATASource.hasArcOut(node, arc);
},
setLiteral: function SM_setLiteral(node, arc, value) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
arc = NC_TM[arc];
value = this.RDFService.GetLiteral(value);
this.changeValue(node, arc, value);
},
setIntLiteral: function(node, arc, value) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
arc = NC_TM[arc];
value = this.RDFService.GetIntLiteral(value);
this.changeValue(node, arc, value);
},
setResource: function(node, arc, value) {
if (typeof(node) == "string") node = this.RDFService.GetResource(node);
arc = NC_TM[arc];
if (typeof(value) == "string") value = this.RDFService.GetResource(value);
this.changeValue(node, arc, value);
},
changeValue: function(node, arc, newValue) {
if (this.DATASource.hasArcOut(node, arc)) {
var oldValue = this.DATASource.GetTarget(node, arc, true);
if (newValue != oldValue) this.DATASource.Change(node, arc, oldValue, newValue);
} else this.DATASource.Assert(node, arc, newValue, true);
},
dataFlush: function() {
this.DATASource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush();
},
promptReplaceStartup: function(caller, path) {
var loadsession = SessionPref.getIntPref("onStart.loadsession");
var sessionpath = SessionPref.getCharPref("onStart.sessionpath");
var result = {button: NO_NEED_TO_REPLACE};
if (loadsession < 0 || sessionpath != path) return result;
var label = this.getLiteralValue(path, "name");
var selectionFlag = SELECT_DEFAULT;
var title, msg, buttons;
var bundle_session = document.getElementById("bundle_session_manager");
var areYouSure = bundle_session.getString("sm.areYouSure.msg");
var chooseStartup = bundle_session.getString("sm.canChooseStartup.msg");
switch ( caller ) {
case "addWinToSession":
title = bundle_session.getString("sm.addtoStartup.title");
var msgType = caller=="addWinToSession" ? "windows" : "tabs";
msg = bundle_session.getString("sm.addtoStartup.msg." + msgType) + "\n" + label
+ "\n" + areYouSure + "\n\n" + chooseStartup;
buttons = [this.setLabel("sm.addtoStartup.button0"),
this.setLabel("sm.addtoStartup.button1")].join("\n");
break;
case "replaceSession":
title = bundle_session.getString("sm.replaceStartup.title");
msg = bundle_session.getString("sm.replaceStartup.msg") + "\n" + label
+ "\n" + areYouSure + "\n\n" + chooseStartup;
buttons = [this.setLabel("sm.replaceStartup.button0"),
this.setLabel("sm.replaceStartup.button1")].join("\n");
break;
case "removeSavedSession":
title = bundle_session.getString("sm.removeStartup.title");
msg = bundle_session.getString("sm.removeStartup.msg0") + "\n" + label
+ "\n" + areYouSure + "\n\n" + bundle_session.getString("sm.removeStartup.msg1");
buttons = [this.setLabel("sm.removeStartup.button0"),
this.setLabel("sm.removeStartup.button1")].join("\n");
selectionFlag = SELECT_LASTSESSION;
break;
}
return TM_PromptService([BUTTON_OK, SHOW_MENULIST, HIDE_CHECKBOX, selectionFlag],
[title, msg, "", "", buttons]);
},
addWinToSession: function SM_addWinToSession(action) {
if (!this.isValidtoSave()) return;
var path = document.popupNode.session;
var result = this.promptReplaceStartup("addWinToSession", path);
if (result.button == BUTTON_CANCEL) return;
else if (result.button == BUTTON_OK) this.replaceStartupPref(result, "");
var saveClosedTabs = this.saveClosedtabs;
var rdfNodeSession = this.RDFService.GetResource(path);
var sessionContainer = this.initContainer(rdfNodeSession);
var oldCount = this.countWinsAndTabs(sessionContainer);
var newCount = this.saveOneOrAll(action, path, saveClosedTabs);
if (newCount) {
var numTabs = oldCount.tab + newCount.tab;
var numWindows = oldCount.win + newCount.win;
this.setLiteral(rdfNodeSession, "nameExt", this.getNameData(numWindows, numTabs));
this.dataFlush();
}
},
saveClosedSession: function SM_saveClosedSession() {
var oldPath = document.popupNode.session;
var id = this.RDFService.GetAnonymousResource().Value.split("rdf:")[1];
var path = gRDFRoot + "/saved/" + id + "/window";
var pathToReplace = "";
var session = this.getSessionName("saveprevious", this.getLiteralValue(oldPath, "name"));
if (session.button == BUTTON_CANCEL) return; // user cancel
else if (session.button == BUTTON_EXTRA1) { // we replace exist session, BUTTON_OK - save new session
var result = this.promptReplaceStartup("replaceSession", session.path);
if (result.button == BUTTON_CANCEL) return; // user cancel
else if (result.button == BUTTON_OK) { // we replace startup session
this.replaceStartupPref(result, path);
}
pathToReplace = session.path;
}
container = this.initContainer(path)
var pathNode, container, extID = "";
var node = document.popupNode.parentNode.parentNode;
if (node.id.indexOf("tm-sm-closedwindows")==0 || node.id == "btn_closedwindows")
extID = "/" + id;
this.copySubtree(oldPath, path + extID);
if (node.id.indexOf("tm-sm-closedwindows")==0 || node.id == "btn_closedwindows") {
node = this.RDFService.GetResource(path + extID);
container.InsertElementAt(node, 1, true);
this.DATASource.Unassert(node, NC_TM["dontLoad"], this.RDFService.GetLiteral("true"));
}
var count = this.countWinsAndTabs(container); // we need it just to fix the date
if (!session.saveClosedTabs)
this.deleteAllClosedtabs(container);
if (count)
this.insertSession(count, session.name, path, pathToReplace);
else
tmLog("Error in saveClosedSession");
},
copyNode: function(oldNode, newNode, oldRoot, newRoot) {
var newTarget;
var arcOut = this.DATASource.ArcLabelsOut(oldNode);
while (arcOut.hasMoreElements()) {
var aLabel = arcOut.getNext();
if (aLabel instanceof tmRDFResource) {
var aTarget = this.DATASource.GetTarget(oldNode, aLabel, true);
if (aTarget instanceof tmRDFResource) {
newTarget = aTarget.Value.replace(oldRoot, newRoot);
aTarget = this.RDFService.GetResource(newTarget);
}
this.DATASource.Assert(newNode, aLabel, aTarget, true);
}
}
},
copySubtree: function (oldRoot, newRoot) {
var allElements = this.DATASource.GetAllResources();
while (allElements.hasMoreElements()) {
var aResource = allElements.getNext();
if ((aResource instanceof tmRDFResource) && (aResource.Value.indexOf(oldRoot) == 0)) {
var newNodeLabel = aResource.Value.replace(oldRoot, newRoot);
this.copyNode(aResource, this.RDFService.GetResource(newNodeLabel), oldRoot, newRoot);
}
}
},
replaceStartupPref: function(result, newPath) {
var sessionpath = !newPath ? "--" : SessionPref.getCharPref("onStart.sessionpath");
SessionPref.setIntPref("onStart.loadsession", result.value);
if (result.value > -1) {
if (result.label == sessionpath ) SessionPref.setCharPref("onStart.sessionpath", newPath);
else SessionPref.setCharPref("onStart.sessionpath", result.label);
}
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
},
sessionUtil: function(action, what) {
// action = save , replace
// type = thiswindow , allwindows
if (!this.isValidtoSave()) return;
if (numberOfWindows() == 1) what = "thiswindow";
var oldPath = "", name, saveClosedTabs;
var id = this.RDFService.GetAnonymousResource().Value.split("rdf:")[1];
var newPath = gRDFRoot + "/saved/" + id + "/window";
if (action == "save") {
// ask the user for new name or for exist name if the user want to replace
var session = this.getSessionName("save"+what);
if (session.button == BUTTON_CANCEL) return; // user cancel
else if (session.button == BUTTON_EXTRA1) oldPath = session.path;
name = session.name;
saveClosedTabs = session.saveClosedTabs;
} else {
oldPath = document.popupNode.session;
name = this.getLiteralValue(oldPath, "name");
saveClosedTabs = this.saveClosedtabs;
}
if (oldPath != "") { // oldPath is "" if we save to a new name
// check if the user want to replace startup session
var result = this.promptReplaceStartup("replaceSession", oldPath);
if (result.button == BUTTON_CANCEL) return; // user cancel
else if (result.button == BUTTON_OK) this.replaceStartupPref(result, newPath);
}
var count = this.saveOneOrAll("save"+what, newPath, saveClosedTabs);
if (count) this.insertSession(count, name, newPath, oldPath);
else tmLog("Error in " + action + " " + what);
},
isValidtoSave: function() {
if ( !this.enableManager ) return false;
var bundle_session = document.getElementById("bundle_session_manager");
if (gBrowser.isBlankWindow()) {
var title = bundle_session.getString("sm.title");
var msg = bundle_session.getString("sm.dontSaveBlank.msg");
var buttons = ["", this.setLabel("sm.button.continue")].join("\n");
TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],[title, msg, "", "", buttons]);
return false;
}
return true;
},
saveOneOrAll: function(action, path, saveClosedTabs) {
var numTabs, numWindows;
switch ( action ) {
case "savethiswindow":
numTabs = this.saveOneWindow(path, "", false, saveClosedTabs);
numWindows = 1;
break;
case "saveallwindows":
var didSaved = this.saveAllWindows(path, "", saveClosedTabs);
numTabs = didSaved.tab;
numWindows = didSaved.win;
break;
default: return false;
}
if (numTabs > 0) return {win: numWindows, tab: numTabs};
bundle_session = document.getElementById("bundle_session_manager");
alert(bundle_session.getString("sm.sessoinSave.error"));
return false;
},
insertSession: function SM_insertSession(count, name, path, oldPath) {
var container = this.initContainer(gRDFRoot + "/windows");
var index = 0;
if (oldPath != "") index = container.IndexOf(this.RDFService.GetResource(oldPath));
var node = this.RDFService.GetResource(path);
container.InsertElementAt(node, index+1, true);
if (oldPath != "") { // remove the session we replace
container.RemoveElementAt(index, true);
this.removeSession(oldPath, gRDFRoot+'/windows');
}
this.setLiteral(node, "name", name);
this.setLiteral(node, "nameExt", this.getNameData(count.win, count.tab));
this.dataFlush();
return true;
},
getSessionName: function(action, old) {
var bundle_session = document.getElementById("bundle_session_manager");
var showChebox, closedtabMsg, saveClosedTabs = this.saveClosedtabs;
if (action != "rename" && saveClosedTabs) {
closedtabMsg = bundle_session.getString("sm.saveClosedTab.chkbox.label");
showChebox = CHECKBOX_CHECKED;
} else showChebox = HIDE_CHECKBOX;
var msg = bundle_session.getString("sm.sessionName.msg0") + "\n";
var title = bundle_session.getString("sm.sessionName.title." + action);
var label, buttons, actionFlag;
var sessionList = this.getSessionList("saved");
if (action=="rename") {
label = old;
buttons = [this.setLabel("sm.sessionName.button0"),
this.setLabel("sm.sessionName.button1")].join("\n");
actionFlag = DLG_RENAME;
} else {
label = action == "saveprevious" ? old : gBrowser.mCurrentTab.label;
buttons = [this.setLabel("sm.askBeforSave.button0"),
this.setLabel("sm.askBeforSave.button1"),
this.setLabel("sm.replaceStartup.button0")+"..."].join("\n");
actionFlag = DLG_SAVE;
for (var i = 0; i < sessionList.list.length; i++) {
if (label == sessionList.list[i]) {
label = "";
break;
}
}
}
label = unescape(label + "\n" + sessionList.list.join("\n"));
var result = TM_PromptService([BUTTON_OK, SHOW_TEXTBOX, showChebox, actionFlag],[title, msg, label, closedtabMsg, buttons]);
switch (result.button) {
case BUTTON_CANCEL: return {button: result.button};
case BUTTON_OK:
case BUTTON_EXTRA1 :
var trimResult = result.label.replace(/^[\s]+/g,"").replace(/[\s]+$/g,"");
return {button: result.button, name: escape(trimResult), path: sessionList.path[result.value], saveClosedTabs: result.checked};
}
return {};
},
countWinsAndTabs: function SM_countWinsAndTabs(container) {
// count windows and tabs in this session
var numTabs = 0, numWindows = 0;
var windowEnum = container.GetElements();
while (windowEnum.hasMoreElements()) {
var rdfNodeWindow = windowEnum.getNext();
numWindows += 1;
var rdfNodeTabs = this.getResource(rdfNodeWindow, "tabs");
if (rdfNodeTabs instanceof tmRDFResource) {
var tabContainer = this.initContainer(rdfNodeTabs);
numTabs += tabContainer.GetCount();
}
}
return {win: numWindows, tab: numTabs};
},
getNameData: function(numWindows, numTabs) {
var d = new Date();
var date = [d.getFullYear(), '/', d.getMonth()<9 ? "0":"", d.getMonth()+1, '/', d.getDate()<10 ? "0":"", d.getDate()].join('');
var time = [d.getHours()<10 ? "0":"", d.getHours(), ':', d.getMinutes()<10 ? "0":"", d.getMinutes(), ':', d.getSeconds()<10 ? "0":"", d.getSeconds()].join('');
var bundle_session = document.getElementById("bundle_session_manager");
var empty = bundle_session.getString("sm.session.empty");
var T = bundle_session.getString("sm.session.tabs");
var W = bundle_session.getString("sm.session.windows");
if (numWindows == 0) return ", (" + empty + ") (" + date + " " + time + ")";
else if (numWindows < 2) return ", (" + numTabs + " "+ T + ") (" + date + " " + time + ")";
return ", (" + numWindows + " " + W + ", " + numTabs + " " + T + ") (" + date + " " + time + ")";
},
updateSessionMenu: function(menu) {
var overwriteWindows = SessionPref.getBoolPref("restore.overwritewindows") || gSingleWindowMode;
document.getElementById("tm-sm-OpenInCurrenWindow").setAttribute("default",overwriteWindows);
document.getElementById("tm-sm-OpenInNewWindow").setAttribute("default",!overwriteWindows);
document.getElementById("tm-sm-OpenInNewWindow").hidden = gSingleWindowMode;
var mValue = document.popupNode.getAttribute("value");
if (mValue <= -1)
document.getElementById("tm-sm-Rename").setAttribute("disabled",true);
else
document.getElementById("tm-sm-Rename").removeAttribute("disabled");
var node = document.popupNode.parentNode.parentNode;
var mItem = document.getElementById("tm-sm-SetAsStartup");
if (node.id == "tm-sessionmanager" || node.id == "btn_sessionmanager") {
mItem.removeAttribute("disabled");
if (document.popupNode.hasAttribute("default"))
mItem.setAttribute("checked", "true");
else
mItem.removeAttribute("checked");
} else {
mItem.removeAttribute("checked");
mItem.setAttribute("disabled",true);
}
var mShowext = document.getElementById("tm-sm-showext");
var showext = SessionPref.getBoolPref("menu.showext");
if (!showext && mShowext.hasAttribute("checked"))
mShowext.removeAttribute("checked");
else if (showext && !mShowext.hasAttribute("checked"))
mShowext.setAttribute("checked", "true");
var obsAll = document.getElementById("tmp_contextmenu_AllWindows");
var obsThis = document.getElementById("tmp_contextmenu_ThisWindow");
var mSave = document.getElementById("tm-sm-Save");
if (node.id.indexOf("tm-sm-closedwindows")==0 || node.id == "btn_closedwindows" || mValue <= -1) {
if (obsAll.hidden != true)
obsAll.hidden = true;
if (obsThis.hidden != true)
obsThis.hidden = true;
if (mSave.hidden != false)
mSave.hidden = false;
if (document.popupNode.hasAttribute("disabled"))
mSave.setAttribute("disabled", true);
else
mSave.removeAttribute("disabled");
} else {
var isOneWindow = (numberOfWindows() == 1);
if (obsAll.hidden != isOneWindow)
obsAll.hidden = isOneWindow;
if (obsThis.hidden != false)
obsThis.hidden = false;
if (mSave.hidden != true)
mSave.hidden = true;
}
return typeof(document.popupNode.session) != "undefined";
},
restoreSession: function(node, overwriteWindows) {
// call restoreSession after delay to let the popup menu time to hide
window.setTimeout( function () { SessionManager.delayRestoreSession(node, overwriteWindows); }, 0 );
},
delayRestoreSession: function(node, overwriteWindows) {
var path = node.session;
var id = node.parentNode.parentNode.id;
if (id == "tm-sessionmanager" || id == "btn_sessionmanager")
this.loadSession(path,'sessionrestore', overwriteWindows);
else if (id.indexOf("tm-sm-closedwindows")==0 || id == "btn_closedwindows")
this.openclosedwindow(path, overwriteWindows);
},
setSessionAsStartup: function(popup) {
if (popup.getAttribute("checked")) {
var aValue = document.popupNode.getAttribute("value"); // -1, -2 for for closed session, 1,2.... for saved session
var loadsession = aValue && aValue <= -1 ? aValue : 0;
SessionPref.setIntPref("onStart.loadsession", loadsession);
if (loadsession > -1)
SessionPref.setCharPref("onStart.sessionpath", document.popupNode.session);
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
}
},
setShowNameExt: function() {
SessionPref.setBoolPref("menu.showext", !SessionPref.getBoolPref("menu.showext"));
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
},
renameSession: function SM_renameSession() {
var thisSession = document.popupNode.session;
var node = this.RDFService.GetResource(thisSession);
var oldName = this.getLiteralValue(node, "name");
var result = this.getSessionName("rename", oldName);
if (result.button == BUTTON_OK) {
this.setLiteral(node, "name", result.name);
this.dataFlush();
}
},
removeFromMenu: function(event, popup, root) {
if (!tabxPrefs.getBoolPref("middleclickDelete")) return;
if ( event.button == 1 && ("session" in event.target)) {
document.popupNode = event.target;
SessionManager.removeSavedSession();
if (root == gSessionPath[0] && this.isClosedWindowsEmpty()) popup.hidePopup();
else SessionManager.createMenu(popup, root);
}
},
removeSavedSession: function() {
var node = document.popupNode.parentNode.parentNode;
var path = document.popupNode.session;
if (node.id == "tm-sessionmanager" || node.id == "btn_sessionmanager") {
// befor we remove this session check if it is the startup session
// and let the user cancel the delete or choose diffrent startup session
var result = this.promptReplaceStartup("removeSavedSession", path);
switch (result.button) {
case BUTTON_CANCEL: return;
case BUTTON_OK: this.replaceStartupPref(result, "");
case NO_NEED_TO_REPLACE : this.removeSession(path, gRDFRoot+'/windows');
}
} else if (node.id.indexOf("tm-sm-closedwindows")==0 || node.id == "btn_closedwindows") {
this.removeSession(path, gSessionPath[0]);
this.updateClosedWindowsMenu("check");
}
},
removeAllSavedSession: function SM_removeAllSavedSession() {
var node = document.popupNode.parentNode.parentNode;
var result, title, msg;
var bundle_session = document.getElementById("bundle_session_manager");
var buttons = [this.setLabel("sm.removeStartup.button0"),
this.setLabel("sm.removeStartup.button1")].join("\n");
if (node.id == "tm-sessionmanager" || node.id == "btn_sessionmanager") {
title = bundle_session.getString("sm.removeAll.title.session");
msg = bundle_session.getString("sm.removeAll.msg0") + "\n\n";
if (SessionPref.getIntPref("onStart.loadsession") > -1)
msg += bundle_session.getString("sm.removeAll.msg1");
result = TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],
[title, msg, "", "", buttons]);
if (result.button == BUTTON_OK) {
this.deleteSubtree(gSessionPath[1]);
this.deleteSubtree(gSessionPath[2]);
this.deleteSubtree(gSessionPath[3]);
this.deleteSubtree(gRDFRoot+'/saved');
this.deleteSubtree(gRDFRoot+'/windows');
this.dataFlush();
SessionPref.setIntPref("onStart.loadsession", -1);
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
}
} else if (node.id.indexOf("tm-sm-closedwindows")==0 || node.id == "btn_closedwindows") {
title = bundle_session.getString("sm.removeAll.title.closedwindow");
msg = bundle_session.getString("sm.removeAll.msg2");
result = TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, HIDE_CHECKBOX],
[title, msg, "", "", buttons]);
if (result.button == BUTTON_OK) {
var sessionContainer = this.initContainer(gSessionPath[0]);
this.deleteWithProp(sessionContainer, "status", "saved");
this.updateClosedWindowsMenu(true);
this.dataFlush();
}
}
},
// xxx need to check if we need all this functions
removeSession: function SM_removeSession(value, container) {
if (value==null) return;
var node = this.RDFService.GetResource(value);
var rdfNodeWindows = this.RDFService.GetResource(container);
var windowsContainer = this.initContainer(rdfNodeWindows);
this.deleteSubtree(value);
windowsContainer.RemoveElement(node, true);
if (!windowsContainer.GetCount()) this.deleteNode(rdfNodeWindows);
this.dataFlush();
},
removeAllClosedSession: function SM_removeAllClosedSession() {
for (var i = 0; i < gSessionPath.length; i++) {
var rdfNode = this.RDFService.GetResource(gSessionPath[i]);
var container = this.initContainer(rdfNode);
if (!this.containerEmpty(gSessionPath[i])) this.deleteWithProp(container);
if (!container.GetCount()) this.deleteNode(rdfNode);
}
},
deleteSession: function SM_deleteSession(nodLabel, prop, value) {
var rdfNode = this.RDFService.GetResource(nodLabel);
var container = this.initContainer(rdfNode);
if (!this.containerEmpty(nodLabel)) this.deleteWithProp(container, prop, value);
if (!container.GetCount()) this.deleteNode(rdfNode);
},
deleteWithProp: function(container, prop, value) {
var containerEnum = container.GetElements();
var nodeToDelete = [];
var noProp = typeof(prop) == "undefined";
var valueExist = typeof(value) == "string";
while(containerEnum.hasMoreElements()) {
var node = containerEnum.getNext();
var propExist = noProp ? true : this.nodeHasArc(node, prop);
if (valueExist && !noProp && propExist && this.getLiteralValue(node, prop) != value) propExist = false;
if (propExist) nodeToDelete.push(node);
}
this.deleteArrayNodes(container, nodeToDelete, true);
},
deleteArrayNodes: function(container, nodeToDelete, deleteSubTree) {
for (var i = 0; i < nodeToDelete.length; i++) {
var nodeValue = nodeToDelete[i].QueryInterface(tmRDFResource).Value
if (deleteSubTree) this.deleteSubtree(nodeValue);
container.RemoveElement(nodeToDelete[i], true);
}
},
destroyMenuItems: function(menu) {
// Destroy the items.
var destroy = false, endSeparator;
for (var i = 0; i < menu.childNodes.length; i++) {
var item = menu.childNodes[i];
if (item.id.indexOf("-endSeparator") != -1) {
endSeparator = item
if (menu.parentNode.id != "tm-sessionmanager" &&
menu.parentNode.id != "btn_sessionmanager") break;
else continue;
}
if (destroy) {
i--;
menu.removeChild(item);
} else if (item.id.indexOf("-startSeparator") != -1) destroy = true;
}
return endSeparator;
},
createMenuForDialog: function(popup, contents) {
if (contents == SHOW_CLOSED_WINDOW_LIST) {
// create closed window list popup menu
this.createMenu(popup, window.opener.gSessionPath[0], contents);
} else {
// create saved Session popup menu
this.createMenu(popup, gRDFRoot+'/windows', contents);
// check if sessionpath and loadsessions valid for saved session
var loadsession = SessionPref.getIntPref("onStart.loadsession");
if (loadsession > -1 && contents != 1 && loadsession != popup.parentNode.sessionIndex) {
SessionPref.setIntPref("onStart.loadsession", popup.parentNode.sessionIndex);
var pref = "onStart.sessionpath";
if (popup.parentNode.sessionIndex < 0 && SessionPref.prefHasUserValue(pref))
SessionPref.clearUserPref(pref);
}
}
},
createMenu: function SM_createMenu(popup, container, contents) {
if (!this.DATASource) this.initService(); // initService if we call from pref dialog
if (typeof(contents) == "undefined") contents = 0;
var endSeparator = this.destroyMenuItems(popup); // Remove any existing menu items
var parentId = popup.parentNode.id
if (parentId == "btn_sessionmanager" || parentId == "btn_closedwindows")
popup.parentNode.removeAttribute("tooltiptext");
var parentID = (contents != SHOW_CLOSED_WINDOW_LIST) ? popup.parentNode.id : "";
var aContainer = this.initContainer(container);
var containerEnum = aContainer.GetElements();
var mi, i = -1, node, name, nameExt, accessKey;
var showNameExt = SessionPref.getBoolPref("menu.showext");
var loadsession = SessionPref.getIntPref("onStart.loadsession");
var sessionpath = SessionPref.getCharPref("onStart.sessionpath");
var showTooltip = parentId == "btn_sessionmanager" || parentId == "tm-sessionmanager" || parentId.indexOf("tm-sm-closedwindows")==0 || parentId == "btn_closedwindows";
while(containerEnum.hasMoreElements()) {
node = containerEnum.getNext();
if (this.nodeHasArc(node, "status") &&
this.getLiteralValue(node, "status") != "saved") continue;
name = unescape(this.getLiteralValue(node, "name"));
nameExt = this.getLiteralValue(node, "nameExt");
// Insert a menu item for session in the container
mi = document.createElement("menuitem");
mi.session = node.QueryInterface(tmRDFResource).Value;
mi.setAttribute("session", mi.session);
if (contents == 1 && loadsession > -1 && mi.session && mi.session == sessionpath) continue;
++i;
mi.setAttribute("value", i);
mi.value = i;
if (parentID != "onStart.loadsession") {
accessKey = (i > 26) ? "" : String.fromCharCode(65+i) + " " ;
mi.setAttribute("accesskey", accessKey);
mi.setAttribute("label", accessKey + name + (showNameExt ? nameExt : ""));
if (showTooltip) mi.setAttribute("tooltiptext", accessKey + name + nameExt);
} else {
mi.setAttribute("label", name);
}
popup.insertBefore(mi, endSeparator);
}
switch ( parentID ) {
case "tm-sessionmanager":
case "btn_sessionmanager":
var observer = document.getElementById("tmp_menu_AllWindows");
var isOneWindow = (numberOfWindows() == 1);
if (observer.hidden != isOneWindow) observer.hidden = isOneWindow;
case "tm_prompt":
endSeparator.hidden = endSeparator.previousSibling.localName == "menuseparator";
var sessionLabel;
var afterCrash = !this.containerEmpty(gSessionPath[3]);
// if Crashed is empty don't show 'Crashed Session' menu item
var bundle_session = document.getElementById("bundle_session_manager");
if (afterCrash && contents != 1)
sessionLabel = [bundle_session.getString("sm.sessionMenu.lastgood"),
bundle_session.getString("sm.sessionMenu.previous"),
bundle_session.getString("sm.sessionMenu.crashed")];
else
sessionLabel = [bundle_session.getString("sm.sessionMenu.last"),
bundle_session.getString("sm.sessionMenu.previous")];
var menu;
var empty = ", (" + bundle_session.getString("sm.session.empty") + ")";
for (i = 0; i < sessionLabel.length; i++ ){
menu = document.createElement("menuitem");
menu.session = gSessionPath[i+1];
if (this.containerEmpty(menu.session) && contents != 1) menu.setAttribute("disabled", "true");
nameExt = this.getLiteralValue(menu.session, "nameExt", empty);
menu.setAttribute("label", sessionLabel[i] + (showNameExt && contents != 1 ? nameExt : ""));
if (showTooltip) menu.setAttribute("tooltiptext", sessionLabel[i] + nameExt);
menu.setAttribute("value", (-1 - i));
popup.appendChild (menu);
}
if (afterCrash && contents != 1) { // add separator befor Crashed menu item
menu = document.createElement("menuseparator");
popup.insertBefore(menu, popup.lastChild);
}
if (contents == 1) loadsession = -1; //set "Last Sessoin" as default in the list
this.setDefaultIndex(popup, loadsession, sessionpath);
break;
case "onStart.loadsession":
endSeparator.hidden = this.containerEmpty(container);
this.setDefaultIndex(popup, loadsession, sessionpath);
break;
default:
endSeparator.hidden = true;
break;
}
},
// set defaultIndex, sessionIndex and default Attribute
setDefaultIndex : function(popup, loadsession, sessionpath) {
popup.parentNode.defaultIndex = -1; // index with menuseparator
popup.parentNode.sessionIndex = -1; // index without menuseparator
var i, item, value, checked;
for (i = 0; i < popup.childNodes.length; i++) {
item = popup.childNodes[i];
if (item.localName == "menuseparator") continue;
value = item.getAttribute("value");
checked = ((loadsession > -1 && item.session && item.session == sessionpath) ||
(loadsession <= -1 && value && value == loadsession));
if (checked) {
item.setAttribute("default", "true");
popup.parentNode.defaultIndex = i;
popup.parentNode.sessionIndex = value;
} else item.removeAttribute("default");
}
},
// update disable/enable to closed window list in tool menu and toolbar
updateClosedWindowsMenu: function(action) {
var disabled = (action == "check") ? this.isClosedWindowsEmpty(): action;
var wnd, enumerator = windowEnumerator();
while ( enumerator.hasMoreElements() ) {
wnd = enumerator.getNext();
var broadcaster = wnd.document.getElementById("tmp_closedwindows");
if (broadcaster)
broadcaster.setAttribute("disabled",disabled);
}
},
isClosedWindowsEmpty: function SM_isClosedWindowsEmpty() {
if ( !this.enableManager )
return true;
var node, disabled = true;
var aContainer = this.initContainer(gSessionPath[0]);
var containerEnum = aContainer.GetElements();
while(containerEnum.hasMoreElements()) {
node = containerEnum.getNext();
if (this.getLiteralValue(node, "status") == "saved") {
disabled = false;
break;
}
}
return disabled;
},
// call by init on first window load after crash
openAfterCrash: function SM_openAfterCrash(status) {
var sessionContainer = this.initContainer(gSessionPath[0]);
if (this.enableBackup) {
var path = gRDFRoot + "/closedSession/thisSession";
this.setLiteral(path, "status", "crash2");
// restore to were we was befor the crash
var crashedContainer = this.initContainer(gSessionPath[3]);
if (status != "crash2") {
// delete old crash data
if (!this.containerEmpty(gSessionPath[3])) this.deleteWithProp(crashedContainer);
var windowEnum = sessionContainer.GetElements();
var nodeToDelete = [];
while (windowEnum.hasMoreElements()) {
var rdfNodeWindow = windowEnum.getNext();
if (this.getLiteralValue(rdfNodeWindow, "status") == "backup") {
var tabs = this.getResource(rdfNodeWindow, "tabs");
var subTree = rdfNodeWindow.QueryInterface(tmRDFResource).Value;
if (!this.containerEmpty(tabs)) { // copy "backup" subtree to crashed session if it not empty
var newSubTree = subTree.replace(gSessionPath[0], gSessionPath[3]);
this.copySubtree(subTree, newSubTree);
crashedContainer.AppendElement(this.RDFService.GetResource(newSubTree));
}
this.deleteSubtree(subTree); // delete the crashed subtree
nodeToDelete.push(rdfNodeWindow);// remove the window from the crash session
} else this.setLiteral(rdfNodeWindow, "dontLoad", "true"); // we can see this session in the close window list
}
this.deleteArrayNodes(sessionContainer, nodeToDelete, false);
} // if firefox was crashed in middle of crash Recovery try again to restore the same data
else if (!this.containerEmpty(gSessionPath[0]))
this.deleteWithProp(sessionContainer);
var bundle_session = document.getElementById("bundle_session_manager");
var title = bundle_session.getString("sm.afterCrash.title");
var msg;
if (status != "crash2")
msg = bundle_session.getString("sm.afterCrash.msg0");
else
msg = bundle_session.getString("sm.afterCrash.msg0.again");
var chkBoxLabel = !this.enableManager ? bundle_session.getString("sm.afterCrash.chkbox.label") : "";
var buttons, result, whattoLoad = "session";
var chkBoxState = !this.enableManager ? CHECKBOX_UNCHECKED : HIDE_CHECKBOX;
var closedWinList = this.initContainer(gSessionPath[0]).GetCount();
var lastSession = this.containerEmpty(gSessionPath[1]) // last session
var prevtoLast = this.containerEmpty(gSessionPath[2]) // previous to last
var savedSession = this.containerEmpty(gRDFRoot+'/windows') // saved session
var isAllEmpty = lastSession && prevtoLast && savedSession;
if (!this.containerEmpty(gSessionPath[3])) { // if Crashed Session is not empty
var count = this.countWinsAndTabs(crashedContainer);
this.setLiteral(gSessionPath[3], "nameExt", this.getNameData(count.win, count.tab));
if (this.enableManager && !isAllEmpty) {
msg += "\n\n" + bundle_session.getString("sm.afterCrash.msg1");
buttons = [this.setLabel("sm.afterCrash.button0"),
this.setLabel("sm.afterCrash.button1")].join("\n");
result = TM_PromptService([BUTTON_OK, SHOW_MENULIST, HIDE_CHECKBOX, SELECT_CRASH],
[title, msg, "", "", buttons]);
} else {
msg += " " + bundle_session.getString("sm.afterCrash.msg2") + ".....";
if (!this.enableManager)
msg += "\n" + bundle_session.getString("sm.afterCrash.msg3");
else
msg += "\n" + bundle_session.getString("sm.afterCrash.msg4");
buttons = [this.setLabel("sm.afterCrash.button0.crashed"),
this.setLabel("sm.afterCrash.button1")].join("\n");
result = TM_PromptService([BUTTON_OK, HIDE_MENUANDTEXT, chkBoxState],
[title, msg, "", chkBoxLabel, buttons]);
result.label = gSessionPath[3];
}
} else {
if (this.enableManager && !isAllEmpty) {
msg += " " + bundle_session.getString("sm.afterCrash.msg5") + "\n\n"
+ bundle_session.getString("sm.afterCrash.msg1");
buttons = [this.setLabel("sm.afterCrash.button0"),
this.setLabel("sm.afterCrash.button1")].join("\n");
result = TM_PromptService([BUTTON_OK, SHOW_MENULIST, HIDE_CHECKBOX, SELECT_DEFAULT],
[title, msg, "", "", buttons]);
} else if (closedWinList != 0) {
msg += " " + bundle_session.getString("sm.afterCrash.msg6");
if (!this.enableManager)
msg += "\n" + bundle_session.getString("sm.afterCrash.msg3") + "\n\n"
+ bundle_session.getString("sm.afterCrash.msg7") + ":";
else
msg += "\n\n" + bundle_session.getString("sm.afterCrash.msg7") + " "
+ bundle_session.getString("sm.afterCrash.msg8") + ":";
buttons = [this.setLabel("sm.afterCrash.button0"),
this.setLabel("sm.afterCrash.button1")].join("\n");
result = TM_PromptService([BUTTON_OK, SHOW_MENULIST, chkBoxState, SHOW_CLOSED_WINDOW_LIST],
[title, msg, "", chkBoxLabel, buttons]);
whattoLoad = "closedwindow";
} else {// nothing to restore
msg = bundle_session.getString("sm.afterCrash.msg9") + "\n" + bundle_session.getString("sm.afterCrash.msg10");
if (!this.enableManager)
msg += "\n\n" + bundle_session.getString("sm.afterCrash.msg3");
buttons = ["", this.setLabel("sm.button.continue")].join("\n");
result = TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, chkBoxState],
[title, msg, "", chkBoxLabel, buttons]);
}
}
if (result.checked && !this.enableManager) {
SessionPref.setBoolPref("manager", true); // enable session manager
try {
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
} catch(ex) { }
}
if (result.button == BUTTON_OK) {
switch ( whattoLoad ) {
case "session": this.loadSession(result.label, "firstwindowopen");
break;
case "closedwindow": this.openclosedwindow(result.label, true);
break;
default:
}
} else
this.loadHomePage();
} else { // crash recovery is off, delete any remains from the crashed session
if (!this.containerEmpty(gSessionPath[0])) this.deleteWithProp(sessionContainer);
if (this.enableManager) this.openFirstWindow(true, false); // openFirstWindow with flag openAfterCrash
// else BrowserHome(); // we never get to here...
}
},
// call by init or by openAfterCrash on first window load
openFirstWindow: function SM_openFirstWindow(afterCrash, afterRestart) {
var path = gRDFRoot + "/closedSession/";
var sessionType = ["thisSession", "lastSession", "previoustolastSession", "crashedsession"];
// swap 0 --> 1 --> 2 --> 0
var i;
var sessions = [], subTree, aSession;
for (i = 0; i < sessionType.length-1; i++) {
sessions.push(this.getResource(path + sessionType[i], "session"));
}
for (i = 0; i < sessionType.length-1; i++) {
if (i == 0) { // delete oldest session subtree
aSession = sessions[sessionType.length-2];
subTree = aSession.QueryInterface(tmRDFResource).Value;
this.deleteSubtree(subTree);
} else aSession = sessions[i-1];
this.setResource(path + sessionType[i], "session", aSession)
}
for (i = 0; i < sessionType.length; i++) {
gSessionPath[i] = this.getResourceValue(path + sessionType[i], "session");
}
gThisWin = gSessionPath[0] + "/" + gBrowser.windowID;
gThisWinTabs = gThisWin + "/tabs";
gThisWinClosedtabs = gThisWin + "/closedtabs";
// When Firefox Starts:
// pref "onStart"
// 0 - Restore
// 1 - Ask me Befor Restore
// 2 (or else) - Don't Restore
//
// pref "onStart.loadsession"
// 0 , 1 , 2 ..... index of saved sessions
// -1, -2 ........ index of previous sessions
//
// if loadsession >= 0 the session path is saved in pref "onStart.sessionpath"
// else if loadsession < 0 the session path is saved in gSessionPath
var restoreFlag = SessionPref.getIntPref("onStart");
if (restoreFlag > 1 && !afterRestart) {
return; // Don't Restore
}
var loadSession = SessionPref.getIntPref("onStart.loadsession");
// after last session end with restart load the last session without any prompt
// unless we are after crash
var askifempty = restoreFlag > 1 ? false : SessionPref.getBoolPref("onStart.askifempty");
var startupEmpty = false, savePref = false ;
var result = {}, title, msg = "", buttons;
var bundle_session = document.getElementById("bundle_session_manager");
if (afterCrash)
title = bundle_session.getString("sm.afterCrash.title");
else
title = bundle_session.getString("sm.start.title");
var chkBoxLabel = afterCrash ? bundle_session.getString("sm.start.chkbox.label") : "";
var chkBoxState = afterCrash ? CHECKBOX_UNCHECKED : HIDE_CHECKBOX;
// get saved session list
var sessionList = this.getSessionList();
if (sessionList == null) {
if ((askifempty || restoreFlag == 1) && !this.corruptedFile) {
msg = bundle_session.getString("sm.start.msg0") + "\n"
+ bundle_session.getString("sm.afterCrash.msg10");
if (afterCrash)
msg += "\n\n" + bundle_session.getString("sm.start.msg1");
buttons = ["", this.setLabel("sm.button.continue")].join("\n");
result = TM_PromptService([BUTTON_CANCEL, HIDE_MENUANDTEXT, chkBoxState],
[title, msg, "", chkBoxLabel, buttons]);
if (result.checked && afterCrash) {
SessionPref.setBoolPref("crashRecovery", true); // enable Crash Recovery
nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
}
}
this.loadHomePage();
return;
}
if (afterRestart) {
restoreFlag = 0;
loadSession = -1;
}
var aList = sessionList.list;
var sessionPath = sessionList.path;
var loadSessionIsValid = true, sessionIndex, thisPath;
switch ( (loadSession > 0) ? 0 : loadSession ) {
case 0:
sessionIndex = null;
if (SessionPref.prefHasUserValue("onStart.sessionpath")) {
thisPath = SessionPref.getCharPref("onStart.sessionpath");
// check if sessionpath is valid
for (i = 0; i < aList.length; i++) {
if (sessionPath[i] == thisPath) {
sessionIndex = i;
break;
}
}
}
if ((thisPath && this.containerEmpty(thisPath)) || sessionIndex == null) {
// error in pref.js or in session.rdf ask the user what to do
loadSessionIsValid = false;
thisPath = gSessionPath[1]; // load last session
SessionPref.setIntPref("onStart.loadsession", -1);
savePref = true;
}
break;
default: // just in case that somehow onStart.loadsession is invalid
loadSession = -1;
SessionPref.setIntPref("onStart.loadsession", -1);
savePref = true;
case -2:
case -1:
var indx = -1 * loadSession;
thisPath = gSessionPath[indx];
if (this.containerEmpty(gSessionPath[indx])) startupEmpty = true;
sessionIndex = aList.length + indx - 3;
break;
}
if (restoreFlag > 0 || afterCrash || (startupEmpty && askifempty) || !loadSessionIsValid) {
try{
if (afterCrash)
msg += bundle_session.getString("sm.afterCrash.msg0") + " "
+ bundle_session.getString("sm.start.msg1");
if (startupEmpty) msg += bundle_session.getString("sm.start.msg0");
if (!loadSessionIsValid) msg += bundle_session.getString("sm.start.msg2");
msg += "\n\n" + bundle_session.getString("sm.afterCrash.msg1");
buttons = [this.setLabel("sm.afterCrash.button0"),
this.setLabel("sm.afterCrash.button1")].join("\n");
result = TM_PromptService([BUTTON_OK, SHOW_MENULIST, chkBoxState, SELECT_DEFAULT],
[title, msg, "", chkBoxLabel, buttons]);
if (result.checked && afterCrash) {
SessionPref.setBoolPref("crashRecovery", true); // enable Crash Recovery
savePref = true;
}
} catch (e) {tmLog("error " + e);}
}
else {
result.button = startupEmpty ? BUTTON_CANCEL : BUTTON_OK;
result.label = thisPath;
}
if (savePref) nsIPrefServiceObj.savePrefFile(null); // store the pref immediately
if (result.button == BUTTON_OK)
this.loadSession(result.label, "firstwindowopen");
else
this.loadHomePage();
},
getSessionList: function SM_getSessionList(flag) {
var aList = [], sessionPath = [];
var aContainer = this.initContainer(gRDFRoot+'/windows');
var containerEnum = aContainer.GetElements();
var node, aName;
while(containerEnum.hasMoreElements()) {
node = containerEnum.getNext();
aName = this.getLiteralValue(node, "name");
aList.push(aName);
sessionPath.push(node.QueryInterface(tmRDFResource).Value);
}
var bundle_session = document.getElementById("bundle_session_manager");
if (flag == "saved") return {list: aList, path: sessionPath};
else if (flag == "replace") {
aList.push(bundle_session.getString("sm.sessionMenu.lastDefault"));
aList.push(bundle_session.getString("sm.sessionMenu.previous"));
} else {
var empty = ", (" + bundle_session.getString("sm.session.empty") + ")";
var empty1 = this.containerEmpty(gSessionPath[1]);
var empty2 = this.containerEmpty(gSessionPath[2]);
if (empty1 && empty2 && aList.length == 0) return null;
if (flag == "afterCrash") aList.push(bundle_session.getString("sm.sessionMenu.lastgood") + (empty1 ? empty : ""));
else aList.push(bundle_session.getString("sm.sessionMenu.last") + (empty1 ? empty : ""));
aList.push(bundle_session.getString("sm.sessionMenu.previous") + (empty2 ? empty : ""));
}
sessionPath.push(gSessionPath[1]);
sessionPath.push(gSessionPath[2]);
return {list: aList, path: sessionPath};
},
saveAllWindows: function(path, caller, saveClosedTabs) {
var enumerator = windowEnumerator();
var wnd, savedTabs = 0 , savedWin = 0, thisWin;
while ( enumerator.hasMoreElements() ) {
wnd = enumerator.getNext();
thisWin = wnd.SessionManager.saveOneWindow(path, caller, false, saveClosedTabs);
savedTabs += thisWin;
if (thisWin > 0) savedWin += 1;
}
return {win: savedWin, tab: savedTabs};
},
checkTime: function SM_checkTime(container, curTime) {
// check the timestamp for each saved window
// if the time diff is more than 10sec set dontLoad=true to the saved window
var windowEnum = container.GetElements();
while (windowEnum.hasMoreElements()) {
var rdfNodeLastWindow = windowEnum.getNext();
var lastSaved = this.getLiteralValue(rdfNodeLastWindow, "timestamp", 0);
if ((curTime - lastSaved) > 10000) {
if (!this.nodeHasArc(rdfNodeLastWindow, "dontLoad"))
this.setLiteral(rdfNodeLastWindow, "dontLoad", "true");
}
}
},
saveOneWindow: function SM_saveOneWindow(path, caller, overwriteWindow, saveClosedTabs) {
if (gBrowser.isBlankWindow()) return 0; // dont save window without any tab
if (!path) path = gSessionPath[0];
if (!caller) caller = "";
if (!overwriteWindow) overwriteWindow = false;
if (typeof(saveClosedTabs) == "undefined") saveClosedTabs = this.saveClosedtabs;
// if we going to delete close window from the list we can't use GetCount as ID,
// we need to save unink ID
var winID;
if (caller == "windowclosed" || caller == "windowbackup") winID = gBrowser.windowID;
else winID = this.RDFService.GetAnonymousResource().Value.split("rdf:")[1];
var winPath = path + "/" + winID;
this.initSession(path, winPath);
var savedTabs;
if (caller == "windowclosed" && this.enableBackup) {
var tabContainer = this.initContainer(gThisWinTabs);
// save busy tabs
this.saveAllTab(winPath, 0, true);
savedTabs = tabContainer.GetCount() > 0 ? tabContainer.GetCount() : this.saveAllTab(winPath, 0);
this.setTabsScroll();
} else {
savedTabs = this.saveAllTab(winPath, 0);
if (((gThisWin == winPath && !this.enableBackup) || gThisWin != winPath) && saveClosedTabs)
this.copyClosedTabsToRDF(winPath);
}
var rdfNodeThisWindow = this.RDFService.GetResource(winPath);
if (SessionPref.getBoolPref("save.selectedtab")) // save selected tab index
this.setIntLiteral(rdfNodeThisWindow, "selectedIndex", this.getTabPosition());
if (caller == "windowbackup") {
this.dataFlush();
return savedTabs;
}
if (path == gSessionPath[0]) {
// save current tab title. we will use it later in closed windows list as menu entry label
// if current tab is blank get label from first saved tab that isn't blank
var label;
if (gBrowser.isBlankTab(gBrowser.mCurrentTab)) {
for (var i = 0; i < gBrowser.mTabs.length; i++) {
var aTab = gBrowser.mTabs[i];
if (!gBrowser.isBlankTab(aTab)) {
label = aTab.label;
break;
}
}
} else label = gBrowser.mCurrentTab.label;
this.setLiteral(rdfNodeThisWindow, "name", escape(label));
this.setLiteral(rdfNodeThisWindow, "nameExt", this.getNameData(-1, savedTabs));
var pref = "extensions.tabmix.warnAboutClosingTabs.timeout";
var delay = gPref.prefHasUserValue(pref) ? gPref.getCharPref(pref)*1 : 0;
var newTime = new Date().valueOf() - delay;
this.setLiteral(rdfNodeThisWindow, "timestamp", newTime);
// if we overwrite window we don't load it again on restart
if (this.overwriteWindow || overwriteWindow) this.setLiteral(rdfNodeThisWindow, "dontLoad", "true");
this.setLiteral(rdfNodeThisWindow, "status", "saved");
this.updateClosedWindowsMenu(false);
} else this.setLiteral(rdfNodeThisWindow, "status", "");
this.dataFlush();
return savedTabs;
}, // end of "saveOneWindow : function ()"
// if this session is not in the container add it to the last place and init prop
// else move it to the last place
initSession: function SM_initSession(path, winPath) {
var container = this.initContainer(path);
var rdfNode = this.RDFService.GetResource(winPath);
var index = container.IndexOf(rdfNode);
if (index == -1) {
container.AppendElement(rdfNode);
this.setLiteral(rdfNode, "status", "backup");
this.setResource(rdfNode, "tabs", winPath + "/tabs");
this.setResource(rdfNode, "closedtabs", winPath + "/closedtabs");
} else if (index != container.GetCount()) {
container.RemoveElementAt(index, true);
container.AppendElement(rdfNode);
}
},
// xxx need to fix this to save only history, image and history index
// and save the rest when tab added
tabLoaded: function SM_tabLoaded(aTab) {
if (!this.enableBackup || aTab.hasAttribute("inrestore")) return;
if (gBrowser.isBlankTab(aTab)) return;
// if this window is not in the container add it to the last place
this.initSession(gSessionPath[0], gThisWin);
var tabContainer = this.initContainer(gThisWinTabs);
var result = this.saveTab(aTab, gThisWinTabs, tabContainer, true, 0);
if (result) this.dataFlush();
},
updateTabPos: function(aTab, label, add0_1) {
var tab, node;
if (!add0_1) add0_1 = 0;
for (var i = aTab._tPos + add0_1; i < gBrowser.mTabs.length; i++) {
tab = gBrowser.mTabs[i];
node = (typeof(label) == "undefined") ? this.getNodeForTab(tab) : label + "/" + tab.linkedPanel;
this.setIntLiteral(node, "tabPos", tab._tPos);
}
},
tabClosed: function SM_tabClosed(aTab) { // delete tab from container and save to closed tab list backup
// we don't check aTab.hasAttribute("inrestore") , in case tab is closed befor
// its finish to restore.
if (!this.enableBackup) return;
this.initSession(gSessionPath[0], gThisWin);
var tabContainer = this.initContainer(gThisWinTabs);
var panelPath = this.getNodeForTab(aTab);
var nodeToClose = this.RDFService.GetResource(panelPath);
this.updateTabPos(aTab); // update _tPos for the tab right to the deleted tab
if (this.saveClosedtabs) {
// move closedtabs to closedtabs container
var closedTabContainer = this.initContainer(gThisWinClosedtabs);
var tabExist = true;
if (tabContainer.IndexOf(nodeToClose) == -1) {
tabExist = this.saveTab(aTab, gThisWinTabs, closedTabContainer, false, 0);
} else tabContainer.RemoveElement(nodeToClose, true);
if (tabExist) {
closedTabContainer.AppendElement(nodeToClose);
if (closedTabContainer.GetCount() > tabxPrefs.getIntPref("undoCloseCache"))
this.deleteClosedtabAt(1, gThisWin);
}
} else if (tabContainer.IndexOf(nodeToClose) > -1) {
// xxx try to use deleteSession ????
this.deleteSubtree(panelPath);
tabContainer.RemoveElement(nodeToClose, true);
// xxx is it necessary to delete this ???
if (!tabContainer.GetCount()) { // if no tab in the container remove it from the tree
var winContainer = this.initContainer(gSessionPath[0]);
var rdfNode = this.RDFService.GetResource(gThisWin);
winContainer.RemoveElement(rdfNode, true);
this.deleteSubtree(gThisWin);
}
}
this.dataFlush();
},
updateTabProp: function SM_updateTabProp(aTab, needFlush) {
// we dont need this function to run befor sessionmanager init
// this.enableBackup=null so we dont past the next if
if (!this.enableBackup || aTab.hasAttribute("inrestore")) return;
if (gBrowser.isBlankTab(aTab)) return; // dont write blank tab to the file
this.initSession(gSessionPath[0], gThisWin);
this.setLiteral(this.getNodeForTab(aTab), "properties", SessionData.getTabProperties(aTab, true));
if (needFlush)
this.dataFlush();
},
tabMoved: function SM_tabMoved(aTab, oldPos, newPos) {
if (!this.enableBackup || aTab.hasAttribute("inrestore")) return;
this.initSession(gSessionPath[0], gThisWin);
// can't use aTab._tPos after group of tab delete
// we pass old position and new position from TMmoveTabTo
// we need to fix tabPos for all tab between old position and new position
var first = Math.min(oldPos, newPos);
var last = Math.max(oldPos, newPos);
for (var i = first; i < last + 1; i++) {
var tab = gBrowser.mTabs[i];
if (!gBrowser.isBlankTab(tab))
this.setIntLiteral(this.getNodeForTab(tab), "tabPos", i);
}
this.dataFlush();
},
setTabsScroll: function() {
if (SessionPref.getBoolPref("save.scrollposition"))
for (var i = 0; i < gBrowser.mTabs.length; i++)
this.tabScrolled(gBrowser.mTabs[i]);
},
// xxx need to find the right event to trigger this function..
tabScrolled: function SM_tabScrolled(aTab) {
if (!this.enableBackup || aTab.hasAttribute("inrestore")) return;
var aBrowser = gBrowser.getBrowserForTab(aTab);
if (gBrowser.isBlankBrowser(aBrowser)) return;
var bContent = aBrowser.contentWindow;
var zoomFactor = aBrowser.docShell.contentViewer ? aBrowser.markupDocumentViewer.textZoom : 1;
this.setLiteral(this.getNodeForTab(aTab), "scroll", bContent.scrollX + "," + bContent.scrollY + "," + zoomFactor);
},
tabSelected: function(needFlush) {
if (!this.enableBackup || gBrowser.mCurrentTab.hasAttribute("inrestore")) return;
if (typeof(needFlush) == "undefined") needFlush = false;
this.initSession(gSessionPath[0], gThisWin);
this.setTabsScroll(); // until i find proper event to update tab scroll do it from here
if (SessionPref.getBoolPref("save.selectedtab")) {
this.setIntLiteral(gThisWin, "selectedIndex", this.getTabPosition());
}
if (needFlush) this.dataFlush();
},
getTabPosition: function() { // calc selected tab position if blank tab not restore
if (gBrowser.isBlankTab(gBrowser.mCurrentTab)) return 0; // if the current tab is blank we don't resore the index
var blankTab = 0;
for (var i = 0; i < gBrowser.mCurrentTab._tPos; i++) {
if (gBrowser.isBlankTab(gBrowser.mTabs[i])) blankTab++;
}
return gBrowser.mCurrentTab._tPos - blankTab;
},
getNodeForTab: function(aTab) {
return gThisWinTabs + "/" + aTab.linkedPanel;
},
saveAllTab: function SM_saveAllTab(winPath, offset, saveBusy) {
var savedTabs = 0 ;
var rdfNodeTabs = this.getResource(winPath, "tabs");
var rdfLabelTabs = rdfNodeTabs.QueryInterface(tmRDFResource).Value;
var tabContainer = this.initContainer(rdfNodeTabs);
for (var i = 0; i < gBrowser.mTabs.length; i++) {
var aTab = gBrowser.mTabs[i];
if (saveBusy && !aTab.hasAttribute("busy")) continue; // save only busy tabs
if (this.saveTab(aTab, rdfLabelTabs, tabContainer, true, offset)) savedTabs ++;
}
return savedTabs;
},
// call from tabloaded, tabClosed, saveAllTab
// xxx add flag what to save : all, history, property, scrollPosition
saveTab: function(aTab, rdfLabelTabs, tabContainer, needToAppend, offset) {
var aBrowser = gBrowser.getBrowserForTab(aTab);
if (gBrowser.isBlankBrowser(aBrowser)) return false;
var sessionHistory = aBrowser.webNavigation.sessionHistory;
var rdfLabelTab = rdfLabelTabs + "/" + aTab.linkedPanel;
var index = sessionHistory.index < 0 ? 0 : sessionHistory.index;
var historyIndex = this.enableSaveHistory ? index : 0;
var rdfNodeTab = this.RDFService.GetResource(rdfLabelTab);
var bContent = aBrowser.contentWindow;
var zoomFactor = aBrowser.docShell.contentViewer ? aBrowser.markupDocumentViewer.textZoom : 1;
var scrollPos = bContent.scrollX + "," + bContent.scrollY + "," + zoomFactor;
try {
var curHistory = sessionHistory.getEntryAtIndex(index, false);
curHistory.QueryInterface(tmSHEntry).setScrollPosition(bContent.scrollX, bContent.scrollY);
} catch (e) {tmLog("saveTab error index " + sessionHistory.index + "\n" + e); }
this.saveTabData(rdfNodeTab, historyIndex, aTab._tPos + offset,
aTab.getAttribute("image"),
SessionData.getTabProperties(aTab, true),
this.saveTabHistory(sessionHistory),
scrollPos);
// dont append if we call from tabClosed function
//XXX move this to the caller function
if (tabContainer.IndexOf(rdfNodeTab) == -1 && needToAppend) {
tabContainer.AppendElement(rdfNodeTab);
this.updateTabPos(aTab, rdfLabelTabs, 1); // update _tPos for the tab right to the new tab
}
return true;
},
saveTabData: function SM_saveTabData(node, index, tabPos, image, properties, history, scroll) {
this.setIntLiteral(node, "index", index);
this.setIntLiteral(node, "tabPos", tabPos);
this.setLiteral (node, "image", image || ""); // for use in closed tab list
this.setLiteral (node, "properties", properties);
this.setLiteral (node, "history", history);
this.setLiteral (node, "scroll", scroll);
},
// xxx save text size (zoom), char type ?
saveTabHistory: function(sessionHistory) {
var historyStart = this.enableSaveHistory ? 0 : sessionHistory.index;
var historyEnd = this.enableSaveHistory ? sessionHistory.count : sessionHistory.index+1;
var j, historyEntry, history = [];
for (j = historyStart; j < historyEnd; j++) {
try {
historyEntry = sessionHistory.getEntryAtIndex(j, false).QueryInterface(tmSHEntry);
history.push(escape(historyEntry.title));
history.push(historyEntry.URI.spec);
history.push(this.getScrollPosHs(historyEntry)); // not in use yet
} catch (e) {tmLog("saveTabHistory error index " + j + "\n" + e); }
}
// generate unique separator and combine the array to one string
var separator = "][", extraSeparator = "@";
for (var i = 0; i < history.length; ++i) {
while (history[i].indexOf(separator) > -1)
separator += extraSeparator;
}
// insert the separator to history so we can extract it in loadTabHistory
return separator + "|-|" + history.join(separator);
},
getScrollPosHs: function(historyEntry) {
if (SessionPref.getBoolPref("save.scrollposition")) {
var x={}, y={};
historyEntry.getScrollPosition(x, y);
return x.value + "," + y.value;
} return "0,0";
},
loadSession: function SM_loadSession(path, caller, overwriteWindows) {
var sessionContainer = this.initContainer(path);
var sessionEnum = sessionContainer.GetElements();
var sessionCount = 0, concatenate;
var windowEnum = windowEnumerator();
if (typeof(overwriteWindows) == "undefined")
overwriteWindows = SessionPref.getBoolPref("restore.overwritewindows");
// don't concatenate window after crash
if (caller == "firstwindowopen" && this.getLiteralValue(gSessionPath[0], "status") == "crash2")
concatenate = false;
else
concatenate = SessionPref.getBoolPref("restore.concatenate");
var saveBeforOverwrite = SessionPref.getBoolPref("restore.saveoverwrite");
var overwriteTabs = SessionPref.getBoolPref("restore.overwritetabs");
// in single window mode we restore ALL window into this window
if (gSingleWindowMode)
concatenate = true;
// if this window is blank use it when reload session
var wnd, blankWindow;
if (!gSingleWindowMode && concatenate && !overwriteWindows && !gBrowser.isBlankWindow() && caller != "firstwindowopen" && caller != "concatenatewindows") {
this.openNewWindow(path, "concatenatewindows");
return;
}
// if we join all window to one window
// call the same window for all saved window with overwritewindows=false and overwritetabs=false if this not the first saved
// for first saved window overwritetabs determined by user pref
while (sessionEnum.hasMoreElements()) {
sessionCount++;
var rdfNodeSession = sessionEnum.getNext();
if (rdfNodeSession instanceof tmRDFResource) {
var windowPath = rdfNodeSession.QueryInterface(tmRDFResource).Value;
if (this.nodeHasArc(windowPath, "dontLoad")) continue;
if (concatenate) {
if (caller != "concatenatewindows" && caller != "firstwindowopen" && sessionCount == 1
&& saveBeforOverwrite && overwriteTabs) this.saveOneWindow(gSessionPath[0], "", true);
var newCaller = (sessionCount != 1) ? caller+"-concatenate" : caller;
this.loadOneWindow(windowPath, newCaller);
} else {
wnd = null;
blankWindow = false;
if (windowEnum.hasMoreElements()) {
wnd = windowEnum.getNext();
blankWindow = wnd.gBrowser.isBlankWindow();
}
if (wnd != null && (overwriteWindows || blankWindow || (caller == "firstwindowopen" && sessionCount == 1 ))) {
// if we save overwrite windows in the closed windows list don't forget to set dontLoad==true
if (caller != "firstwindowopen" && saveBeforOverwrite && overwriteTabs)
wnd.SessionManager.saveOneWindow(gSessionPath[0], "", true);
wnd.SessionManager.loadOneWindow(windowPath, caller);
} else
this.openNewWindow(windowPath, caller);
}
}
}
// cloes extra windows if we overwrite open windows and set dontLoad==true
if (numberOfWindows() > 1 && overwriteWindows) {
while (windowEnum.hasMoreElements()) {
wnd = windowEnum.getNext();
if (concatenate && wnd == window) continue;
if (saveBeforOverwrite) wnd.SessionManager.overwriteWindow = true;
else wnd.SessionManager.saveThisWindow = false;
wnd.close();
}
}
},
openclosedwindow: function SM_openclosedwindow(path, overwriteWindows) {
// 1. check if to overwrite the opener window
// if 1 is true call loadOneWindow
// if 1 is false open new window and pass the path
// 2. delete the window from closedwindow list (after new window is opend and load)
var rdfNodeClosedWindow = this.RDFService.GetResource(path);
// don't reopen same window again. the window removed from closed window list after it finish to load
if (this.nodeHasArc(rdfNodeClosedWindow, "reOpened")) return;
this.setLiteral(rdfNodeClosedWindow, "reOpened", "true");
if (typeof(overwriteWindows) == "undefined") overwriteWindows = SessionPref.getBoolPref("restore.overwritewindows");
var saveBeforOverwrite = SessionPref.getBoolPref("restore.saveoverwrite");
var overwriteTabs = SessionPref.getBoolPref("restore.overwritetabs");
if (overwriteWindows || gBrowser.isBlankWindow() || gSingleWindowMode) {
if (saveBeforOverwrite && overwriteTabs)
this.saveOneWindow(gSessionPath[0], "", true);
this.loadOneWindow(path, "openclosedwindow");
} else
this.openNewWindow(path, "openclosedwindow");
this.dataFlush();
},
openNewWindow: function SM_openNewWindow(path, caller) {
var newWindow = window.openDialog( getBrowserURL(), "_blank", "chrome,all,dialog=no", null);
newWindow.tabmixdata = { path: path, caller: caller };
},
loadOneWindow: function SM_loadOneWindow(path, caller) {
var overwrite = true, restoreSelect = SessionPref.getBoolPref("save.selectedtab");
switch ( caller ) {
case "firstwindowopen":
if (window.arguments && window.arguments.length > 0) {
overwrite = window.arguments[0] == gHomeButton.getHomePage() ? true : false ;
if (!overwrite && window.arguments[0] != "about:blank") restoreSelect = false;
} else overwrite = false;
break;
case "windowopenebytabmix":
case "concatenatewindows":
overwrite = true;
break;
case "openclosedwindow":
case "sessionrestore":
overwrite = SessionPref.getBoolPref("restore.overwritetabs");
break;
case "firstwindowopen-concatenate":
case "openclosedwindow-concatenate":
case "sessionrestore-concatenate":
case "concatenatewindows-concatenate":
overwrite = false;
break;
default: tmLog("SessionManager \n error unidentifid caller " + caller);
}
/*
1. when open first windows overwrite tab only if they are home page, if firefox open from link or with
pages that are not the home page append the new tab to the end.
simple solution is to set browser.startup.page = 0 , when we activate session manager, in this case if we
have any tabs in the first window we don't overwrite.
2. when open window by session manager other than the first window (caller = "windowopenebytabmix" and tabmix in the name) overwrite=true
3. when loadOneWindow call by openclosedwindow or loadSession we reuse window check user pref for overwrite.
4. if we open all closed windows to one window append tab to the end and select the selected tab from first window
in the session.
*/
var cTab = gBrowser.mCurrentTab;
var concatenate = caller.indexOf("-concatenate") != -1 || (caller == "firstwindowopen" && gBrowser.mTabContainer.childNodes.length > 1);
var rdfNodeWindow = this.RDFService.GetResource(path);
var rdfNodeTabs = this.getResource(rdfNodeWindow, "tabs");
if (!(rdfNodeTabs instanceof tmRDFResource) || this.containerEmpty(rdfNodeTabs)) {
var bundle_session = document.getElementById("bundle_session_manager");
alert(bundle_session.getString("sm.restoreError.msg0") + "\n" + bundle_session.getString("sm.restoreError.msg1"));
var stringBundle = document.getElementById("tmp-string-bundle");
var tabmix_loading = stringBundle.getString("session.loading.label") + "...";
if (gBrowser.mCurrentTab.label == tabmix_loading)
gBrowser.mCurrentBrowser.reload();
return;
}
var tabContainer = this.initContainer(rdfNodeTabs);
var newtabsCount = tabContainer.GetCount();
gBrowser.tabsToLoad = newtabsCount;
this.setStripVisibility(newtabsCount);
var lastSelectedIndex = restoreSelect ? this.getIntValue(rdfNodeWindow, "selectedIndex") : 0;
if (lastSelectedIndex < 0 || lastSelectedIndex >= newtabsCount) lastSelectedIndex = 0;
var i, newIndex, aTab, tabPos;
if (overwrite) {
gBrowser.mTabContainer.collapsedTabs = 0;
for ( i = 0; i < gBrowser.mTabContainer.childNodes.length; i++) {
aTab = gBrowser.mTabContainer.childNodes[i];
var aBrowser = gBrowser.getBrowserForTab(aTab);
// reset old history
aBrowser.webNavigation.sessionHistory =
Components.classes["@mozilla.org/browser/shistory;1"]
.createInstance(tmSHistory);
// reset old text zoom
setTextZoom(aBrowser, 1);
// remove selected and flst_id from all tabs but the current
if (aTab != cTab) {
aTab.removeAttribute("selected");
aTab.removeAttribute("flst_id");
}
}
while (newtabsCount > gBrowser.mTabContainer.childNodes.length) {
gBrowser.addTab();
}
// move selected tab to place
gBrowser.TMmoveTabTo(cTab, lastSelectedIndex);
// remove extra tab
while (newtabsCount < gBrowser.mTabContainer.childNodes.length) {
gBrowser.removeTab(gBrowser.mTabContainer.lastChild);
}
newIndex = 0;
} else {
// reuse blank tabs and move tabs to the right place
var openTabNext = gPref.getBoolPref("extensions.tabmix.openTabNext");
// catch blank tab for reuse
var blankTabs = [], blankTabsCount = 0, currentTabIsBalnk = false;
for (i = 0; i < gBrowser.mTabContainer.childNodes.length ; i++) {
aTab = gBrowser.mTabContainer.childNodes[i];
if (!aTab.loadOnStartup) { // make sure we not overwrite tab that loads from apps
if (gBrowser.isBlankTab(aTab) && (aTab.hasAttribute("tabmix_busy") || !aTab.hasAttribute("busy"))) {
aTab.removeAttribute("tabmix_busy");
if (aTab != cTab) {
blankTabs.push(aTab);
aTab.removeAttribute("selected");
aTab.removeAttribute("flst_id");
} else {
blankTabs.unshift(aTab);
currentTabIsBalnk = true;
}
}
} else delete aTab.loadOnStartup;
}
// remove extra tabs
var blankTab;
while (blankTabs.length > newtabsCount) {
blankTab = blankTabs.pop();
if (blankTab) gBrowser.removeTab(blankTab);
}
var newPos = (openTabNext && cTab._tPos < gBrowser.mTabContainer.childNodes.length - 1 && !concatenate) ? cTab._tPos + 1 : gBrowser.mTabContainer.childNodes.length - 1;
// move blank tabs to new position
blankTabsCount = blankTabs.length;
while (blankTabs.length > 0) {
blankTab = blankTabs.shift();
tabPos = (blankTab._tPos < newPos && newPos < gBrowser.mTabContainer.childNodes.length - 1) ? newPos - 1 : newPos;
gBrowser.TMmoveTabTo(blankTab, tabPos);
}
var tabsCount = gBrowser.mTabContainer.childNodes.length;
var newTotalTabsCount = tabsCount - blankTabsCount + newtabsCount;
while (newTotalTabsCount > gBrowser.mTabContainer.childNodes.length) {
var newTab = gBrowser.addTab();
// in concatenate mode move tab to the end of the list
if (concatenate && openTabNext) {
gBrowser.TMmoveTabTo(newTab, gBrowser.mTabContainer.childNodes.length-1);
}
}
if (tabsCount == blankTabsCount) newPos = 0;
else newPos = (openTabNext && cTab._tPos < gBrowser.mTabContainer.childNodes.length - 1 && !concatenate) ? cTab._tPos + 1 : tabsCount - blankTabsCount;
if (!concatenate && restoreSelect) { // in concatenate mode we select tab only from first window
if (currentTabIsBalnk) { // if the current tab is not blank select new tab
if (openTabNext && newPos > 0) newPos--;
// move selected tab to place
gBrowser.TMmoveTabTo(cTab, newPos + lastSelectedIndex);
} else {
// Set newly selected tab after quick timeout, like in firefox code
function TM_selectNewTab(browser, tabs, newIndex, oldIndex, updateSelected) {
browser.selectedTab = tabs[newIndex];
if (updateSelected) {
tabs[oldIndex].removeAttribute("selected");
tabs[oldIndex].removeAttribute("flst_id");
}
}
var cIndex = gBrowser.mTabContainer.selectedIndex;
if ((newPos + lastSelectedIndex) != cIndex) {
var updateSelected = (caller=="firstwindowopen" || caller=="windowopenebytabmix") ;
setTimeout(TM_selectNewTab, 0, gBrowser, gBrowser.mTabContainer.childNodes, newPos + lastSelectedIndex, cIndex, updateSelected);
}
}
}
newIndex = newPos;
}
// call ensureTabIsVisible befor and after we reload the tab
gBrowser.mTabContainer.ensureTabIsVisible(gBrowser.mTabContainer.selectedIndex);
var tabsEnum = tabContainer.GetElements();
// sort the tab by "tabPos"
var rdfTabs = [], rdfNodeTab;
while (tabsEnum.hasMoreElements()) {
rdfNodeTab = tabsEnum.getNext();
if (rdfNodeTab instanceof tmRDFResource) {
tabPos = this.getIntValue(rdfNodeTab, "tabPos");
rdfTabs.push([tabPos, rdfNodeTab]);
}
}
rdfTabs.sort(this.sortByColumn(0 ,true));
this.initSession(gSessionPath[0], gThisWin); // init the new container befor we start to load data
// restore the selected tab first
var selectedTabLoaded;
if (restoreSelect && lastSelectedIndex in rdfTabs) {
selectedTabLoaded = true;
aTab = gBrowser.mTabContainer.childNodes[newIndex + lastSelectedIndex];
this.loadOneTab(rdfTabs[lastSelectedIndex][1], aTab);
}
for (i = 0; i < rdfTabs.length ; i++) {
if (selectedTabLoaded && lastSelectedIndex == i)
continue;
aTab = gBrowser.mTabContainer.childNodes[newIndex + i];
this.loadOneTab(rdfTabs[i][1], aTab);
}
if (this.saveClosedtabs)
this.saveClosedTabs(path, gThisWin, "closedtabs", true); // load prev saved closed tabs and save to current backup
gBrowser.mTabContainer.nextTab = 1;
// if we open closed window delete this window from closed window list
var caller1;
if ("tabmixdata" in window) {
caller1 = window.tabmixdata.caller;
delete window.tabmixdata;
}
if (caller == "openclosedwindow" || caller1 == "openclosedwindow"){
if (this.nodeHasArc(rdfNodeWindow, "reOpened")) {
this.removeSession(path, gSessionPath[0]);
this.updateClosedWindowsMenu("check");
}
}
},
setStripVisibility: function(tabCount) {
if (tabCount > 1 && gPref.getBoolPref("browser.tabs.autoHide") && gBrowser.mStrip.collapsed) {
// unhide the tab bar
gBrowser.setStripVisibilityTo(true);
gPref.setBoolPref("browser.tabs.forceHide", false);
}
},
sortByColumn: function(nCol, bDescending) {
var c = nCol;
var d = bDescending;
return function (n1, n2) {
if (n1[c] < n2[c]) return (d) ? -1 : +1;
if (n1[c] > n2[c]) return (d) ? +1 : -1;
return 0;
}
},
saveClosedTabs: function(fromPath, toPath, conPath, updateClosedTabsList) {
var isClosedTabs = conPath == "closedtabs";
if (isClosedTabs && !(this.saveClosedtabs))
return;
var fromOld = this.wrapContainer(fromPath, conPath);
if (!(fromOld.Root instanceof tmRDFResource)) return;
var toNew = this.wrapContainer(toPath, conPath);
var rdfNodeTabs = this.getResource(toPath, "tabs");
var rdfLabelTabs = rdfNodeTabs.QueryInterface(tmRDFResource).Value;
var newIndex = -1;
while (fromOld.Enum.hasMoreElements()) {
var rdfNodeSession = fromOld.Enum.getNext();
if (!(rdfNodeSession instanceof tmRDFResource)) continue;
newIndex++;
if (isClosedTabs && (fromOld.Count - newIndex > gPref.getIntPref("extensions.tabmix.undoCloseCache"))) continue;
var uniqueId = "panel" + Date.now() + newIndex;
var rdfLabelSession = rdfLabelTabs + "/" + uniqueId;
var newNode = this.RDFService.GetResource(rdfLabelSession);
var tabPos = this.getIntValue(rdfNodeSession, "tabPos");
var image = this.getLiteralValue(rdfNodeSession, "image");
var prop = this.getLiteralValue(rdfNodeSession, "properties");
var history = this.getLiteralValue(rdfNodeSession, "history");
var index = this.getIntValue(rdfNodeSession, "index");
var scrollPos = this.getLiteralValue(rdfNodeSession, "scroll"); // including zoom factor
var maxCache = gPref.getIntPref("extensions.tabmix.undoCloseCache");
if (this.enableBackup) { // save only if backup enabled
toNew.Container.AppendElement(newNode);
this.saveTabData(newNode, index, tabPos, image, prop, history, scrollPos);
// delete old entry if closedTabs container wasn't empty
if (isClosedTabs && (toNew.Container.GetCount() > maxCache))
this.deleteClosedtabAt(1, toPath);
}
if(updateClosedTabsList) {
var savedHistory = this.loadTabHistory(rdfNodeSession);
if (savedHistory == null) {
tmLog("closed tab at index " + newIndex + " failed to load data from the saved session");
continue;
}
try {
var title = savedHistory.history.getEntryAtIndex(savedHistory.index, true).title;
if (!SessionPref.getBoolPref("save.scrollposition"))
scrollPos = "0,0,1";
else if (scrollPos.split(",").length < 3) // version befor 0.3.0.603 don't include zoomfactor
scrollPos += ",1"
gBrowser.closedTabs.push([tabPos, savedHistory.history, title, image, prop, scrollPos]);
} catch (e) {tmLog("saveClosedTabs error index " + savedHistory.index + "\n" + e); }
// delete old entry if gBrowser.closedTabs wasn't empty
if (gBrowser.closedTabs.length > maxCache)
gBrowser.closedTabs.shift();
}
}
if (updateClosedTabsList && gBrowser.closedTabs.length > 0 && document.getElementById("btn_undoclose"))
document.getElementById("btn_undoclose").setAttribute("disabled", "false");
},
copyClosedTabsToRDF: function SM_copyClosedTabsToRDF(winPath) {
var rdfNodeTo = this.getResource(winPath, "closedtabs");
var toContainer = this.initContainer(rdfNodeTo);
var rdfNodeTabs = this.getResource(winPath, "tabs");
var rdfLabelTabs = rdfNodeTabs.QueryInterface(tmRDFResource).Value;
var ctabs = gBrowser.closedTabs;
var tabCount = ctabs.length;
var maxCache = gPref.getIntPref("extensions.tabmix.undoCloseCache");
var aTab, uniqueId, rdfLabelSession, newNode, historyEntry, scrollPos, history;
for (var i = 0; i < tabCount; i++) {
aTab = ctabs[i];
if (tabCount - i <= maxCache) {
uniqueId = "panel" + Date.now() + i;
rdfLabelSession = rdfLabelTabs + "/" + uniqueId;
newNode = this.RDFService.GetResource(rdfLabelSession);
toContainer.AppendElement(newNode);
history = this.saveTabHistory(aTab[1])
scrollPos = SessionPref.getBoolPref("save.scrollposition") ? aTab[5] : "0,0,1";
this.saveTabData(newNode, aTab[1].index, aTab[0], aTab[3], aTab[4], history, scrollPos);
// delete old entry if closedTabs container wasn't empty
if (toContainer.GetCount() > maxCache)
this.deleteClosedtabAt(1, winPath);
}
}
this.dataFlush();
},
fixClosedtabTabPos: function(aPos) {
if (!(this.saveClosedtabs))
return;
var closedTabs = this.wrapContainer(gThisWin, "closedtabs");
while (closedTabs.Enum.hasMoreElements()) {
var node = closedTabs.Enum.getNext();
var tabPos = this.getIntValue(node, "tabPos");
if (tabPos >= aPos) this.setIntLiteral(node, "tabPos", tabPos++);
}
this.dataFlush();
},
deleteAllClosedtabs: function(sessionContainer) { // delete all closed tabs in this session
var windowEnum = sessionContainer.GetElements();
while (windowEnum.hasMoreElements()) {
var rdfNodeWindow = windowEnum.getNext();
this.deleteWinClosedtabs(rdfNodeWindow.QueryInterface(tmRDFResource).Value);
}
},
deleteWinClosedtabs: function SM_deleteWinClosedtabs(winPath) {
var rdfNodeTabs = this.getResource(winPath, "closedtabs");
var container = this.initContainer(rdfNodeTabs);
this.deleteWithProp(container);
this.dataFlush();
},
deleteClosedtabAt: function SM_deleteClosedtabAt(index, winPath) {
if (!SessionPref.getBoolPref("save.closedtabs"))
return;
if (typeof(winPath) == 'undefined') winPath = gThisWin;
var rdfNodeTabs = this.getResource(winPath, "closedtabs");
var container = this.initContainer(rdfNodeTabs);
if (index == "last") index = container.GetCount();
if (index < 1 || index > container.GetCount()) return;
var nodeToDelete = container.RemoveElementAt(index, true);
var nodeValue = nodeToDelete.QueryInterface(tmRDFResource).Value
this.deleteSubtree(nodeValue);
if (!container.GetCount()) this.deleteNode(rdfNodeTabs);
this.dataFlush();
},
loadOneTab: function SM_loadOneTab(rdfNodeSession, aTab) {
aTab.setAttribute("inrestore", "true"); // flag. dont save tab that are in restore phase
// load Properties befor we load History
var tabProperties = this.getLiteralValue(rdfNodeSession, "properties");
if (tabProperties != "") SessionData.setTabProperties(aTab, tabProperties, true);
var aBrowser = gBrowser.getBrowserForTab(aTab);
var webNav = aBrowser.webNavigation;
var savedHistory = this.loadTabHistory(rdfNodeSession, webNav.sessionHistory);
if (savedHistory == null) {
tmLog("loadOneTab() - tab at index " + aTab._tPos + " failed to load data from the saved session");
gBrowser.removeTab(aTab);
return;
}
aBrowser._sessionData = {
tabPos: aTab._tPos,
node: rdfNodeSession
};
try {
// if url is file and file don't exist it throws an exception, we don't need to reload loacl file
var url = webNav.sessionHistory.getEntryAtIndex(savedHistory.index, false).URI.spec;
var needToReload = SessionPref.getBoolPref("restore.reloadall") && url.indexOf("file:")!=0;
if (needToReload) {
window.setTimeout( function (browser) {
browser.addEventListener('load', SessionManager.afterTabLoad, true);
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
var _webNav = browser.webNavigation;
try {
var sh = _webNav.sessionHistory;
if (sh)
_webNav = sh.QueryInterface(nsIWebNavigation);
} catch (e) { }
try {
const flags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
_webNav.reload(flags);
} catch (e) { }
}, 0, aBrowser);
}
else
aBrowser.addEventListener('load', SessionManager.afterTabLoad, true);
webNav.gotoIndex(savedHistory.index);
} catch (e) {tmLog("error in loadOneTab gotoIndex ? ")}
}, // end of "loadOneTab : function(...............)"
afterTabLoad: function SM_afterTabLoad(event) {
var aBrowser = this;
var data = aBrowser._sessionData;
// restore scroll position
if (SessionPref.getBoolPref("save.scrollposition")) {
var XYZ = SessionManager.getLiteralValue(data.node, "scroll", "0,0,1");
if (XYZ != "0,0,1") {
XYZ = XYZ.split(",");
try {
var sHistory = aBrowser.webNavigation.sessionHistory;
var curHistory = sHistory.getEntryAtIndex(sHistory.index, false);
curHistory.QueryInterface(tmSHEntry).setScrollPosition(XYZ[0], XYZ[1]);
} catch (e) {tmLog("loadOneTab error index " + sHistory.index + "\n" + e); }
var zoomFactor = XYZ.length == 3 ? XYZ[2] : 1;
SessionManager.setScrollPosition(data.tabPos, XYZ[0], XYZ[1], 15, null, zoomFactor);
}
}
gBrowser.mTabs[data.tabPos].removeAttribute("inrestore");
aBrowser.removeEventListener('load', SessionManager.afterTabLoad, true);
delete aBrowser._sessionData;
// call ensureTabIsVisible for the current tab
gBrowser.mTabContainer.ensureTabIsVisible(gBrowser.mTabContainer.selectedIndex);
if (aBrowser == gBrowser.mCurrentBrowser && !gBrowser.isBlankBrowser(aBrowser))
window.content.focus();
// check if we restore all tabs
if (--gBrowser.tabsToLoad == 0) {
delete gBrowser.tabsToLoad;
checkBeforeAndAfter(); // just in case (we do it also in setTabTitle
if (SessionManager.enableBackup){
var result = SessionManager.saveOneWindow(gSessionPath[0], "windowbackup");
if (result > 0) SessionManager.dataFlush();
}
SessionManager.setLiteral(gRDFRoot + "/closedSession/thisSession", "status", "crash");
}
},
setScrollPosition: function SM_setScrollPosition(tabPos, x, y, attempts, href, zoom) {
// xxx only work for the current index in history.
// need to find way to make it work for all pages in history
var tab = gBrowser.mTabs[tabPos];
var aBrowser = gBrowser.getBrowserForTab(tab);
var bContent = aBrowser.contentWindow;
var docViewer;
if (aBrowser.docShell.contentViewer)
docViewer = aBrowser.markupDocumentViewer;
if (!tab.hasAttribute("busy")) {
if (bContent.scrollX != x || bContent.scrollY != y)
bContent.scrollTo(x, y);
if (zoom && docViewer && docViewer.textZoom != zoom)
docViewer.textZoom = zoom;
}
if (attempts && ( bContent.scrollX != x || bContent.scrollY != y || (zoom && docViewer && docViewer.textZoom != zoom) )) {
window.setTimeout(SessionManager.setScrollPosition, 25, tabPos, x, y, --attempts, href, zoom);
return;
} else {
// if we save this befor timeout sometimes scroll is not ready yet
if (SessionManager.enableBackup)
SessionManager.setLiteral(SessionManager.getNodeForTab(tab), "scroll", x + "," + y + "," + zoom);
// call by openLinkWithHistory
if (href)
window.setTimeout( function(aBrowser, aURI) {
aBrowser.loadURI(aURI, null, null);
}, 0, aBrowser, href);
}
},
loadTabHistory: function(rdfNodeSession, sHistoryInternal) {
var history = this.getLiteralValue(rdfNodeSession, "history");
var tmpData = history.split("|-|");
var sep = tmpData.shift(); // remove seperator from data
var historyData = tmpData.join("|-|").split(sep);
if (historyData.length < HSitems) {
tmLog("error in loadTabHistory" + "\n" + "historyData.length " + historyData.length + "\n" + "historyData " + historyData + "\n" + "history " + history);
return null; // if it les then 3 no data !!
}
if (typeof(sHistoryInternal) == "undefined")
sHistoryInternal = Components.classes["@mozilla.org/browser/shistory;1"]
.createInstance(tmSHistory);
sHistoryInternal = sHistoryInternal.QueryInterface(Components.interfaces.nsISHistoryInternal);
var sessionIndex = this.getIntValue(rdfNodeSession, "index");
var historyCount = historyData.length/HSitems;
if ( sessionIndex < 0 || sessionIndex >= historyCount ) sessionIndex = historyCount - 1;
var index, historyEntry, entryTitle, uriStr, newURI, XY;
for ( var i = 0; i < historyCount; i++ ){
index = i * HSitems;
if (!this.enableSaveHistory && sessionIndex != i) continue;
historyEntry = Components.classes["@mozilla.org/browser/session-history-entry;1"]
.createInstance(tmSHEntry);
entryTitle = unescape(historyData[index]);
uriStr = historyData[index + 1];
if (uriStr == "") uriStr = "about:blank";
newURI = this.IOService.newURI(uriStr, null, null);
("setTitle" in historyEntry) ? historyEntry.setTitle(entryTitle) : historyEntry.SetTitle(entryTitle);
("setURI" in historyEntry) ? historyEntry.setURI(newURI) : historyEntry.SetURI(newURI);
historyEntry.saveLayoutStateFlag = true;
// xxx check if we can use this to reload tab not from Cache;
// is it good to reload ALL the history ???
/*
var needToReload = SessionPref.getBoolPref("restore.reloadall") && uriStr.indexOf("file:")!=0;
historyEntry.loadType = needToReload ? Components.interfaces.nsIDocShellLoadInfo.loadReloadBypassCache // http://lxr.mozilla.org/seamonkey/source/docshell/base/nsIDocShellLoadInfo.idl#73
: Components.interfaces.nsIDocShellLoadInfo.loadHistory;
*/
if (SessionPref.getBoolPref("save.scrollposition")) {
if (historyData[index + 2] != "0,0") {
XY = historyData[index + 2].split(",");
historyEntry.setScrollPosition(XY[0], XY[1]); // XY is array [x,y]
}
}
sHistoryInternal.addEntry(historyEntry, true);
}
if (!this.enableSaveHistory) sessionIndex = 0;
return {history: sHistoryInternal, index: sessionIndex};
}
};
PK
أ6`$ $ * content/tabmixplus/session/sessionStore.js/*
* chrome://tabmixplus/content/session/sessionStore.js
*
* original code by onemen
*
*/
/*
XUL Tab attributes to (re)store
Restored in nsSessionStore restoreHistory()
*/
const _xulAttributes = ["image", "protected", "_locked", "fixed-label", "label-uri", "reload-data"];
var TMP_SessionStore = {
/**
* @brief - Init nsISessionStore if user enable browser.sessionstore.enabled from about:config
* or from Tabmix Options > session.
* - Add attribute to nsSessionStore persistTabAttribute.
*
* @param doInit a Boolean value - true when we need to init nsISessionStore.
*
* @returns Nothing.
*/
init: function TMP_ss_init(doInit) {
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if(doInit) {
try {
ss.init(window);
} catch(ex) {
dump("nsSessionStore could not be initialized: " + ex + "\n");
return;
}
}
try {
_xulAttributes.forEach(function(aAttr) {
ss.persistTabAttribute(aAttr);
});
} catch(ex) {
dump("nsSessionStore could not add Attribute to persistTabAttribute: " + ex + "\n");
}
},
/**
* @brief make sure that we don't enable both sessionStore and session manager
*
* @param msgNo a Integer value - msg no. to show.
*
* @param start a Boolean value - true if we call this function befor startup.
*
* @returns Nothing.
*/
setService: function TMP_ss_setSessionService(msgNo, start, win) {
if (!gIsFirefox2)
return;
if(window.setSession || gPref.prefHasUserValue("extensions.tabmix.setDefault"))
return;
window.setSession = true;
var sessionStore = TMP_getBoolPref("", "browser.sessionstore.enabled", true);
var sessionManager = gPref.getBoolPref("extensions.tabmix.sessions.manager");
var crashRecovery = gPref.getBoolPref("extensions.tabmix.sessions.crashRecovery");
if (sessionStore && (sessionManager || crashRecovery)) {
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService);
var bundle_session = document.getElementById("bundle_session_manager");
var msg = start ? bundle_session.getString("sm.disable.msg") + "\n\n" : "";
msg += bundle_session.getString("sm.disable.msg" + msgNo)
var buttonPressed = promptService.confirmEx(win || window,
"TabMix " + bundle_session.getString("sm.title"),
msg,
(promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0)
+ (promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1),
null, null, null, null, {});
if ((msgNo == 1 && buttonPressed == 1) || ((msgNo == 2 && buttonPressed == 0)))
gPref.setBoolPref("browser.sessionstore.enabled", false);
else {
gPref.setBoolPref("extensions.tabmix.sessions.manager", false);
gPref.setBoolPref("extensions.tabmix.sessions.crashRecovery", false);
}
}
delete window.setSession;
},
/**
* @brief remove closed tab from sessionStore list without restore
*
* @param aIndex a Integer value - 0 or grater index to remove
* other value empty the list.
*
* @returns Nothing.
*/
removeClosedTab: function TMP_ss_removeClosedTab(aIndex) {
if (!gIsFirefox2 || !window.__SSi)
return;
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
var state = { windows: [], _firstTabs: true };
state.windows[0] = { _closedTabs: [] };
if (aIndex >= 0) {
// get closed-tabs from nsSessionStore
var closedTabs = eval("(" + ss.getClosedTabData(window) + ")");
// purge closed tab at aIndex
closedTabs.splice(aIndex, 1);
state.windows[0]._closedTabs = closedTabs;
}
// replace existing _closedTabs
ss.setWindowState(window, state.toSource(), false);
},
/**
* @brief get imange url from tab xultab data
*
* @param xultab an object value - xultab from nsSessionStore
*
* @returns image url or empty string.
*/
getImage: function TMP_ss_getImage(xultab) {
var image;
if (xultab) {
xultab.split(" ").forEach(function(aAttr) {
if (/^([^\s=]+)=(.*)/.test(aAttr) && RegExp.$1 == "image") {
image = decodeURI(RegExp.$2);
}
});
}
return image || "";
}
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::: */
// get closed-tabs from nsSessionStore
function getClosedTabs() {
var ssEnabled = true;
try {
ssEnabled = gPref.getBoolPref("browser.sessionstore.enabled");
} catch (ex) {}
if (!ssEnabled)
return;
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if (ss.getClosedTabCount(window) == 0)
return;
var undoItems = eval("(" + ss.getClosedTabData(window) + ")");
var tab, tabData;
for (var i = undoItems.length - 1; i >= 0 ; i--) {
tab = undoItems[i];
tabData = tab.state;
var history = Components.classes["@mozilla.org/browser/shistory;1"]
.createInstance(tmSHistory);
history = history.QueryInterface(Components.interfaces.nsISHistoryInternal);
var aIdMap = { used: {} };
for (var j in tabData.entries)
history.addEntry(TMP_deserializeHistoryEntry(tabData.entries[j], aIdMap), true);
// set history index
var activeIndex = (tabData.index || tabData.entries.length) - 1;
var _blank = history.getEntryAtIndex(activeIndex, true);
var scrollPos = (tabData.entries[activeIndex].scroll || "0,0").split(",");
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
gBrowser.closedTabs.push([tab.pos,
history,
tab.title,
TMP_SessionStore.getImage(tabData.xultab),
"0011111",
scrollPos[0] + "," + scrollPos[1] + "," + parseFloat(tabData.zoom || 1)
]);
if (gBrowser.closedTabs.length > tabxPrefs.getIntPref("undoCloseCache"))
gBrowser.closedTabs.shift();
}
if (gBrowser.closedTabs.length > 0 && document.getElementById("btn_undoclose"))
document.getElementById("btn_undoclose").setAttribute("disabled", "false");
}
function TMP_deserializeHistoryEntry(aEntry, aIdMap) {
var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].
createInstance(Ci.nsISHEntry);
var ioService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
shEntry.setURI(ioService.newURI(aEntry.url, null, null));
shEntry.setTitle(aEntry.title || aEntry.url);
shEntry.setIsSubFrame(aEntry.subframe || false);
shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
if (aEntry.cacheKey) {
var cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].
createInstance(Ci.nsISupportsPRUint32);
cacheKey.data = aEntry.cacheKey;
shEntry.cacheKey = cacheKey;
}
if (aEntry.ID) {
// get a new unique ID for this frame (since the one from the last
// start might already be in use)
var id = aIdMap[aEntry.ID] || 0;
if (!id) {
for (id = Date.now(); aIdMap.used[id]; id++);
aIdMap[aEntry.ID] = id;
aIdMap.used[id] = true;
}
shEntry.ID = id;
}
var scrollPos = (aEntry.scroll || "0,0").split(",");
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
if (aEntry.postdata) {
var stream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
stream.setData(aEntry.postdata, -1);
shEntry.postData = stream;
}
if (aEntry.children && shEntry instanceof Ci.nsISHContainer) {
for (var i in aEntry.children) {
shEntry.AddChild(TMP_deserializeHistoryEntry(aEntry.children[i], aIdMap), i);
}
}
return shEntry;
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::: */
var TMP_ClosedTabs = {
/**
* check to see if nsISessionStore is initialized
*/
get ssIsON() {
return gIsFirefox2 && "__SSi" in window;
},
setButtonState: function ct_setButtonState(value) {
var btn = document.getElementById("btn_undoclose");
if (!btn)
return;
if (!value)
btn.removeAttribute("disabled");
else if (btn.getAttribute("disabled") != "true")
btn.setAttribute("disabled", "true");
},
undoCloseTab: function ct_undoCloseTab() {
if (this.ssIsON)
undoCloseTab();
else
gBrowser.undoRemoveTab();
}
}
PK
6 content/tabmixplus/pref/PK
ܔf5H - content/tabmixplus/pref/overlaySanitizeUI.xul
%tabmixDTD;
]>
PK
x4+Z Z * content/tabmixplus/pref/pref-appearance.jsvar gPref = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
var WindowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
var mainOptions = WindowManager.getMostRecentWindow("mozilla:tabmixopt");
function Appearance_Init()
{
var allColorPickers = document.getElementsByTagName("colorpicker");
for (var i = 0; i < allColorPickers.length; i++) {
var prefstring = allColorPickers[i].getAttribute("prefstring");
allColorPickers[i].color = gPref.getCharPref(allColorPickers[i].getAttribute("prefstring"));
}
var allCheckboxes = document.getElementsByTagName("checkbox");
for (i = 0; i < allCheckboxes.length; i++) {
allCheckboxes[i].checked = gPref.getBoolPref(allCheckboxes[i].getAttribute("prefstring"));
}
setDisabled("currentTab");
setDisabled("unreadTab");
setDisabled("progressMeter");
}
function Appearance_Save()
{
var allColorPickers = document.getElementsByTagName("colorpicker");
for (var i = 0; i < allColorPickers.length; i++) {
gPref.setCharPref(allColorPickers[i].getAttribute("prefstring"), allColorPickers[i].color);
}
var allCheckboxes = document.getElementsByTagName("checkbox");
for (i = 0; i < allCheckboxes.length; i++) {
gPref.setBoolPref(allCheckboxes[i].getAttribute("prefstring"), allCheckboxes[i].checked);
}
}
function setDisabled(id)
{
if (mainOptions.document.getElementById(id).checked)
document.getElementById(id).removeAttribute("disabled");
else
setColorpicker(id, false);
}
function setColorpicker(id, checked)
{
var cP = document.getElementById(id+"-colorpicker");
cP.disabled = !checked;
cP.setAttribute("style", checked ? "opacity: 1.0" : "opacity: 0.5");
}
PK
v4+y + content/tabmixplus/pref/pref-appearance.xul
PK
`3/& & ( content/tabmixplus/pref/pref-filetype.jsvar gPref = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
var list, entry, edit, del, add;
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
}
function Init()
{
// set these once and refer to them later
list = document.getElementById('filetypeList');
entry = document.getElementById('filetypeEntry');
edit = document.getElementById('filetypeEdit');
del = document.getElementById('filetypeDelete');
add = document.getElementById('filetypeAdd');
FillData();
}
function FillData()
{
//remove all the item from the list
while(list.hasChildNodes()) {
list.removeChild(list.lastChild);
}
var data, items, item;
try {
data = gPref.getCharPref(list.getAttribute('prefstring'));
}
catch (e) {}
if (!data.length) {
setButtonDisable(del, true);
return true;
}
items = data.split(' ');
for (var i = 0; i < items.length; ++i) {
if (items[i] == "") continue;
item = items[i].trim();
list.appendItem(item, item.toLowerCase());
}
list.selectedIndex = 0;
list.focus();
return true;
}
function Save()
{
var filetype = [];
for (var i = 0; i < list.getRowCount(); ++i)
filetype.push(list.getItemAtIndex(i).getAttribute("label").trim());
try {
gPref.setCharPref(list.getAttribute('prefstring'), filetype.join(" "));
}
catch (e) {tmLog("error in Save" + "\n" + filetype + "\n\n" + e);}
return true;
}
// sets the textbox to the currently selected item, if any
function Select()
{
setButtonDisable(add, true);
setButtonDisable(edit, true);
if (!list.selectedItem) {
setButtonDisable(del, true);
return false;
}
entry.value = list.selectedItem.getAttribute("label");
setButtonDisable(del, false);
return true;
}
function Add()
{
// check for data in the textbox
if (!entry.value) return false;
var item = list.appendItem(entry.value, entry.value.toLowerCase());
SelectItemAt(list.getRowCount()-1, true);
setButtonDisable(del, false);
return true;
}
function Mod()
{
// check for data in the textbox
if (!entry.value) return false;
// make sure an item is selected, else create a new item
if (!list.selectedItem) return Add();
// change the text
list.selectedItem.setAttribute("label", entry.value);
list.selectedItem.setAttribute("value", entry.value.toLowerCase());
SelectItemAt(list.getIndexOfItem(list.selectedItem), false);
setButtonDisable(add, true);
setButtonDisable(edit, true);
return true;
}
function Input()
{
if (!entry.value) {
setButtonDisable(edit ,true);
setButtonDisable(add ,true);
} else {
// chack if the input value is in the list
var items = list.getElementsByAttribute("value", entry.value.toLowerCase());
if (items.length > 0) {
SelectItemAt(list.getIndexOfItem(items[0]), false);
setButtonDisable(edit ,true);
setButtonDisable(add ,true);
} else {
if (list.selectedItem) setButtonDisable(edit ,false);
setButtonDisable(add ,false);
}
}
}
function Del()
{
var item = list.selectedItem;
if (!item) return;
var index = list.getIndexOfItem(item);
// if the list is not empty select next item or if we at the end the last item
if (list.getRowCount() > 1)
SelectItemAt(index == list.getRowCount() - 1 ? index - 1 : index + 1, true)
else
entry.value = null;
list.removeChild(item);
}
function Restore()
{
Save();
var pref = "extensions.tabmix.filetype";
if (gPref.prefHasUserValue(pref)) gPref.clearUserPref(pref);
FillData();
}
// select new item and focus the list
function SelectItemAt(index, focus)
{
list.ensureIndexIsVisible(index);
list.selectedIndex = index;
if (focus) list.focus();
}
function setButtonDisable(button, set)
{
if (set) {
button.setAttribute("disabled",true);
} else {
button.removeAttribute("disabled");
}
}PK
4u< < ) content/tabmixplus/pref/pref-filetype.xul
%dialogDTD;
%filetypeDTD;
]>
PK
r6wJWe e &