home *** CD-ROM | disk | FTP | other *** search
- (function() {
- const FTAB_CHROME_URL = "chrome://yasearch/content/ftab/ftab.xul";
- const ENABLED_PREF_NAME = "yasearch.general.ftab.enabled";
-
- var TabHooks = {
- _hooked: null,
-
- _currentBrowserOpenTab: window.BrowserOpenTab,
- _prevBrowserOpenTab: window.BrowserOpenTab,
-
- _browserOpenTabWatcher: function (id, oldval, newval) {
- TabHooks._current = newval;
- TabHooks._prev = oldval;
-
- if (!YaFTabGlobal.enabled)
- return newval;
-
- TabHooks._hooked.BrowserOpenTab = null;
-
- let hookedFn;
- if (oldval && TabHooks._getHBrowserOpenTab(newval)) {
- hookedFn = function() {
- if (YaFTabGlobal && YaFTabGlobal.enabled)
- oldval.apply(this.arguments);
- else
- newval.apply(this.arguments);
- }
-
- TabHooks._hooked.BrowserOpenTab = newval;
- }
-
- return hookedFn || newval;
- },
-
- _getHBrowserOpenTab: function(aFunction) {
- return (typeof aFunction == "function" &&
- "boundFn_" in aFunction &&
- typeof aFunction.boundFn_ == "function" &&
- aFunction.boundFn_.toSource().indexOf("PREF_NEWTAB") > -1) ? aFunction : null;
- },
-
- startWatch: function() {
- window.watch("BrowserOpenTab", this._browserOpenTabWatcher);
- },
-
- stopWatch: function() {
- window.unwatch("BrowserOpenTab", this._browserOpenTabWatcher);
- },
-
- init: function() {
- this.hookBrowser();
- },
-
- destroy: function() {
- this.unhookBrowser();
- },
-
- hookURLBarSetURI: function() {
- if (!(YaFTabGlobal.loaded && window.URLBarSetURI && this._hooked && !this._hooked.URLBarSetURI))
- return;
-
- function makeURI(aURLSpec) {
- let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- try {
- return ios.newURI(aURLSpec, null, null);
- } catch(e) {}
-
- return null;
- }
-
- let FTAB_CHROME_FILE_URI = Cc["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Ci.nsIChromeRegistry)
- .convertChromeURL(makeURI(FTAB_CHROME_URL));
-
- let FTAB_CHROME_FILE_URL = FTAB_CHROME_FILE_URI && FTAB_CHROME_FILE_URI.spec ? FTAB_CHROME_FILE_URI.spec : FTAB_CHROME_URL;
-
- if ("gInitialPages" in window && window.gInitialPages instanceof Array) {
- this._hooked.URLBarSetURI = true;
-
- window.gInitialPages.push(FTAB_CHROME_URL);
- window.gInitialPages.push(FTAB_CHROME_FILE_URL);
-
- } else {
- this._hooked.URLBarSetURI = window.URLBarSetURI;
-
- let originalURLBarSetURI = window.URLBarSetURI;
-
- window.URLBarSetURI = function(aURI, aValid) {
- let value = gBrowser.userTypedValue;
- if (!value && aURI && (aURI.spec == FTAB_CHROME_URL || aURI.spec == FTAB_CHROME_FILE_URL)) {
- arguments[0] = makeURI("about:blank");
- }
-
- return originalURLBarSetURI.apply(this, arguments);
- }
- }
- },
-
- hookBrowser: function() {
- if (this._hooked)
- return;
-
- this._hooked = {};
-
- if (this._getHBrowserOpenTab(window.BrowserOpenTab) && this._prevBrowserOpenTab) {
- this._hooked.BrowserOpenTab = window.BrowserOpenTab;
- window.BrowserOpenTab = this._prevBrowserOpenTab;
- }
-
- if (gHomeButton && gHomeButton.getHomePage) {
- let originalGetHomePage = gHomeButton.getHomePage;
- this._hooked.getHomePage = originalGetHomePage;
-
- gHomeButton.getHomePage = function() {
- let res = originalGetHomePage.apply(this, arguments);
-
- if (res === "about:blank")
- res = FTAB_CHROME_URL;
-
- return res;
- };
- }
-
- this.setTabsListener();
- },
-
- unhookBrowser: function() {
- if (!this._hooked)
- return;
-
- this.removeTabsListener();
-
- if (this._hooked.getHomePage && gHomeButton)
- gHomeButton.getHomePage = this._hooked.getHomePage;
-
- if (this._hooked.URLBarSetURI && typeof(this._hooked.URLBarSetURI) == "function")
- window.URLBarSetURI = this._hooked.URLBarSetURI;
-
- if (this._hooked.BrowserOpenTab && this._hooked.BrowserOpenTab === this._prevBrowserOpenTab)
- window.BrowserOpenTab = this._prevBrowserOpenTab;
-
- this._hooked = null;
- },
-
- _tabListenersSet: null,
-
- setTabsListener: function(aSetListeners) {
- this.hookURLBarSetURI();
-
- if (this._tabListenersSet)
- return;
-
- let tabContainer;
- if (window.__lookupGetter__("gBrowser") || !(gBrowser && (tabContainer = gBrowser.tabContainer)))
- return;
-
- tabContainer.addEventListener("TabOpen", this, false);
- tabContainer.addEventListener("TabClose", this, false);
-
- this._tabListenersSet = true;
- },
-
- removeTabsListener: function() {
- let tabContainer;
-
- if (!(gBrowser && (tabContainer = gBrowser.tabContainer)))
- return;
-
- tabContainer.removeEventListener("TabOpen", this, false);
- tabContainer.removeEventListener("TabClose", this, false);
-
- this._tabListenersSet = false;
- },
-
- compatibilityMode: Ya.nsIYa.yaFTab.compatibilityMode,
-
- _isBlankBrowser: function(aBrowser) {
- if (aBrowser.currentURI.spec != "about:blank")
- return false;
-
- let wp = aBrowser.webProgress;
- if (!this.compatibilityMode && !(wp.busyFlags === 3 && wp.loadType === 1))
- return false;
-
- if ((aBrowser.userTypedValue || "") !== "")
- return false;
-
- let userTypedClear = aBrowser.userTypedClear;
- if (userTypedClear > 0 && !this.compatibilityMode && typeof(aBrowser.feeds) != "undefined")
- return false;
-
- if (!(userTypedClear == 0 || userTypedClear == 1))
- return false;
-
- if (this.compatibilityMode &&
- aBrowser.contentDocument &&
- aBrowser.contentDocument.body &&
- aBrowser.contentDocument.body.hasChildNodes())
- return false;
-
- return true;
- },
-
- _timedLoad: function(aBrowser) {
- setTimeout(function(me, browser) {
- me._loadFTabURI(browser);
- }, 150, this, aBrowser);
- },
-
- _loadFTabURI: function(aBrowser) {
- if (this._isBlankBrowser(aBrowser) && !aBrowser.webProgress.isLoadingDocument)
- aBrowser.loadURI(FTAB_CHROME_URL, null, null, false);
- },
-
- handleEvent: function(aEvent) {
- if (!aEvent.isTrusted)
- return;
-
- switch (aEvent.type) {
- case "load":
- let browser = aEvent.target.linkedBrowser;
-
- if (this.compatibilityMode) {
- if (browser.webProgress.busyFlags >= 3) {
- if (this._isBlankBrowser(browser))
- this._timedLoad(browser);
- } else if (browser.webProgress.isLoadingDocument == true) {
- return;
- }
- } else {
- if (this._isBlankBrowser(browser)) {
- browser.loadURI(FTAB_CHROME_URL, null, null, false);
- } else if (browser.webProgress.isLoadingDocument == true) {
- return;
- }
- }
-
- aEvent.target.removeEventListener("load", this, true);
-
- break;
-
- case "TabOpen":
- aEvent.target.addEventListener("load", this, true);
- break;
-
- case "TabClose":
- aEvent.target.removeEventListener("load", this, true);
- break;
-
- default:
- break;
- }
- }
- };
-
- var YaFTabGlobal = {
- enabled: false,
-
- get prefBranch() {
- return Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranchInternal);
- },
-
- onBeforeLoad: function() {
- this._checkEnabled();
- this.prefBranch.addObserver(ENABLED_PREF_NAME, this, false);
- },
-
- loaded: false,
-
- onLoad: function() {
- this.loaded = true;
-
- if (this.enabled !== true)
- return;
-
- TabHooks.setTabsListener();
-
- let tabs = gBrowser.tabContainer.childNodes;
- if (tabs.length != 1)
- return;
-
- let browser = tabs[0].linkedBrowser;
- if (browser && browser.currentURI
- && browser.currentURI.spec == "about:blank"
- && browser.webProgress.isLoadingDocument == false
- && !browser.userTypedValue) {
- browser.loadURI(FTAB_CHROME_URL, null, null, false);
- }
- },
-
- onUnload: function() {
- this.loaded = false;
- this.prefBranch.removeObserver(ENABLED_PREF_NAME, this, false);
- this._checkEnabled(false);
- },
-
- _checkEnabled: function(aEnabledState) {
- let enabled = typeof aEnabledState === "boolean" ? aEnabledState : Ya.nsIYa.getBoolPref(ENABLED_PREF_NAME);
-
- if (enabled === this.enabled)
- return;
-
- this.enabled = enabled;
-
- if (enabled) {
- TabHooks.init();
- window.addEventListener("keydown", this, false);
- window.addEventListener("keypress", this, false);
- } else {
- TabHooks.destroy();
- window.removeEventListener("keydown", this, false);
- window.removeEventListener("keypress", this, false);
- }
- },
-
- observe: function(aSubject, aTopic, aData) {
- if (aTopic == "nsPref:changed" && aData == ENABLED_PREF_NAME)
- this._checkEnabled();
- },
-
- __lastKey: 0,
-
- get __keyModifier() {
- delete this.__keyModifier;
-
- let isLinux = Ya.nsIYa.AppInfo.OS.isLinux;
-
- let incl = isLinux ? "ctrlKey" : "altKey",
- excl = isLinux ? "altKey" : "ctrlKey";
-
- return this.__keyModifier = {include: incl, exclude: excl};
- },
-
- handleEvent: function(aEvent) {
- if (aEvent.shiftKey || aEvent.metaKey || aEvent[this.__keyModifier.exclude])
- return;
-
- if (!aEvent[this.__keyModifier.include]) {
- if (this.__lastKey) {
- this.__lastKey = 0;
- if (aEvent.type == "keypress" && !aEvent.keyCode) {
- aEvent.preventDefault();
- aEvent.stopPropagation();
- }
- }
- return;
- }
-
- if (!this.isYaFTabVisible)
- return;
-
- switch (aEvent.type) {
- case "keydown":
- this.__lastKey = 0;
-
- let key = aEvent.keyCode ? aEvent.keyCode - (aEvent.keyCode > 96 ? 48 : 0) : 0;
- let page = key - 48;
-
- if (page >= 1 && page <= 9) {
- this.__lastKey = key;
-
- let doc = gBrowser.selectedBrowser.docShell.document;
-
- let event = doc.createEvent("KeyboardEvent");
- event.initKeyEvent("keypress",false,true,null,false,true,false,false,key,0);
- doc.defaultView.dispatchEvent(event);
-
- aEvent.stopPropagation();
- aEvent.preventDefault();
- }
- break;
-
- case "keypress":
- break;
-
- default:
- break;
- }
- },
-
- get isYaFTabVisible() {
- try {
- return gBrowser.selectedBrowser.webNavigation.currentURI.spec === FTAB_CHROME_URL;
- } catch(e) {}
-
- return false;
- }
- };
-
- window.addEventListener("load", function(aLoadEvent) {
- aLoadEvent.currentTarget.removeEventListener("load", arguments.callee, false);
-
- let chromeHidden = window.document.documentElement.getAttribute("chromehidden");
- if (chromeHidden && chromeHidden.indexOf("toolbar") != -1) {
- YaFTabGlobal.onUnload();
- TabHooks.stopWatch();
- } else {
- aLoadEvent.currentTarget.addEventListener("unload", function(aUnloadEvent) {
- aUnloadEvent.currentTarget.removeEventListener("unload", arguments.callee, false);
- YaFTabGlobal.onUnload();
- TabHooks.stopWatch();
- }, false);
-
- YaFTabGlobal.onLoad();
- }
- }, false);
-
- TabHooks.startWatch();
- YaFTabGlobal.onBeforeLoad();
- })();