home *** CD-ROM | disk | FTP | other *** search
- var gYaFTab = {
- _compatibilityMode: null,
-
- get compatibilityMode() {
- if (this._compatibilityMode === null) {
- // ftab.compatibility pref:
- // 0 - always false
- // 1 - depends (default)
- // 2 - always true
- let compatibilityMode = gYaSearchService.getIntPref("yasearch.general.ftab.compatibility");
-
- switch (compatibilityMode) {
- case 1:
- const COMPATIBILITY_LIST = ["{c45c406e-ab73-11d8-be73-000a95be3b12}",//webdeveloper
- "{dc572301-7619-498c-a57d-39143191b318}"//tmp
- ];
-
- const ExtensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
- const PREFIX_ITEM_URI = "urn:mozilla:item:";
- const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
- const RdfService = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService)
- const nsIRDFLiteral = Ci.nsIRDFLiteral;
-
- function isExtEnabled(aExtID) {
- let enabled = true;
- let itemResource = RdfService.GetResource(PREFIX_ITEM_URI + aExtID);
- if (itemResource) {
- let ds = ExtensionManager.datasource;
- let target = ds.GetTarget(itemResource, RdfService.GetResource(PREFIX_NS_EM + "isDisabled"), true);
- if (target && target instanceof nsIRDFLiteral)
- enabled = (target.Value != "true");
- }
- return enabled;
- }
-
- let extItems = ExtensionManager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {});
- this._compatibilityMode = !!extItems.some(function(item) {
- return COMPATIBILITY_LIST.indexOf(item.id) > -1 && isExtEnabled(item.id);
- });
-
- break;
-
- case 2:
- this._compatibilityMode = true;
- break;
-
- case 0:
- default:
- this._compatibilityMode = false;
- break;
- }
- }
-
- return this._compatibilityMode;
- },
-
- _init: function() {
- OBSERVER_SERVICE.addObserver(this, "quit-application", false);
- this.ProtocolHandler.addHandler(this.barProtocolHandler);
- },
-
- _uninit: function() {
- this.ProtocolHandler.removeHandler(this.barProtocolHandler);
- OBSERVER_SERVICE.removeObserver(this, "quit-application");
- this._stop();
- },
-
- observe: function(aSubject, aTopic, aData) {
- if (aTopic === "quit-application") {
- this._uninit();
- }
- },
-
- barProtocolHandler: {
- canHandleSpec: function(aSpec) {
- return (aSpec && aSpec.toLowerCase() === "tabs");
- },
-
- newURI: function(aSpec, aOriginalCharset, aBaseURI) {
- if (!this.canHandleSpec(aSpec))
- return null;
-
- return "chrome://yasearch/content/ftab/ftab.xul";
- },
-
- newChannel: function(aURI) {
- return null;
- }
- },
-
- // exp
- get settings() {
- delete this.settings;
-
- Cu.import("resource://yasearch/JSON.jsm");
-
- const kFactor = 0.75;
- const kMaxRows = 8;
- const kMaxCols = 8;
-
- let thumbsInRow = 3,
- thumbsInCol = 3;
-
- let settingsStr = gYaSearchService.getCharPref("yasearch.general.ftab.settings");//{"rows":3,"cols":3}
-
- if (settingsStr) {
- let settings;
- try {
- settings = JSON.parse(settingsStr);
- } catch(e) {}
-
- if (settings && settings.rows && settings.cols) {
- thumbsInRow = Math.min(kMaxCols, Math.max(2, parseInt(settings.cols, 10)));
- thumbsInCol = Math.min(kMaxRows, Math.max(2, parseInt(settings.rows, 10)));
- }
- }
-
- return this.settings = {
- MAX_THUMBS: kMaxRows * kMaxCols,
- thumbsInRow: thumbsInRow,
- thumbsInCol: thumbsInCol,
- thumbsNmb: thumbsInRow * thumbsInCol,
- screenFactor: kFactor * (thumbsInCol / thumbsInRow)
- };
- },
-
- PAGES_DATA_VERSION: 1,
-
- _pagesData: null,
-
- get _pagesDataFile() {
- delete this._pagesDataFile;
-
- let fileName = "ftab.data.xml";
-
- let file = gYaSearchService.getYandexDir();
- file.append(fileName);
-
- if (!file.exists() || !file.isFile()) {
- try {
- file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0755);
- } catch(e) {}
- }
-
- return this._pagesDataFile = (file.exists() && file.isFile() && file.isReadable()) ? file : null;
- },
-
- _loadPagesDataXML: function() {
- let dataFile = this._pagesDataFile;
- let data = dataFile ? gYaSearchService.readFile(dataFile) : "";
-
- let userData = gYaSearchService.safeE4Xml(data,
- '<data version="' + this.PAGES_DATA_VERSION + '"><pages/></data>', 'data');
-
- return userData;
- },
-
- _stringToURI: function(aString) {
- var uri = null;
- var URIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
- .getService(Components.interfaces.nsIURIFixup);
- try {
- uri = URIFixup.createFixupURI(aString, URIFixup.FIXUP_FLAG_NONE);
- } catch(e) {}
-
- return uri;
- },
-
- getURLFromString: function(aString) {
- let uri = this._stringToURI(aString);
-
- if (uri && uri.spec && (uri.scheme == "file" || (uri.host && /^https?$/.test(uri.scheme))))
- return uri.spec.split("#")[0];
-
- return null;
- },
-
- _loadPagesData: function() {
- if (this._pagesData)
- return;
-
- let pagesData = this._loadPagesDataXML();
-
- for each (let page in pagesData.pages.page) {
- page.@status = "restore";
-
- let url = this.getURLFromString(page.@url.toString());
-
- if (!url)
- delete page.@url;
-
- page.@index = parseInt(page.@index,10);
- }
-
- let maxIndex = this.settings.MAX_THUMBS;
- let notValidPages = pagesData.pages.page.(function::attribute("url").toString() == "" ||
- function::attribute("index") > maxIndex ||
- function::attribute("index") < 1);
- while (notValidPages[0])
- delete notValidPages[0];
-
- this._pagesData = pagesData;
-
- let thumbsNmb = this.settings.thumbsNmb;
-
- for each (let page in pagesData.pages.page) {
- if (page.@index <= thumbsNmb)
- this.getURLDataForPage(page);
- }
- },
-
- __savePagesDataTimer: null,
-
- _savePagesDataTimed: function() {
- if (this.__savePagesDataTimer)
- this.__savePagesDataTimer.cancel();
-
- let me = this;
- this.__savePagesDataTimer = new G_Timer(function() {
- me._savePagesData();
- }, 10 * 1000);
- },
-
- _savePagesData: function() {
- if (!this._pagesData)
- return;
-
- let data = <data version={this.PAGES_DATA_VERSION}><pages/></data>;
-
- for each (let page in this._pagesData.pages.page) {
- let _page = <page url={page.@url} index={page.@index}/>
-
- for each (var aAttrName in ["custom_title"]) {
- if (page.attribute(aAttrName).length()) {
- _page.@[aAttrName] = page.@[aAttrName].toString();
- }
- }
-
- data.pages.page += _page;
- }
-
- let dataFile = this._pagesDataFile;
- if (dataFile)
- gYaSearchService.writeFile(dataFile, data);
- },
-
- _destroyPagesData: function() {
- this._savePagesData();
- this.__pagesDataDOM = null;
- this.__pagesDataDOMCloned = null;
- this._pagesData = null;
- },
-
- _getPageByIndex: function(aPageIndex) {
- let pages = this._getPagesByAttribute("index", aPageIndex);
- return pages && pages.length() ? pages[0] : null;
- },
-
- _getPagesByAttribute: function(aAttrName, aAttrValue) {
- if (!this._pagesData)
- return;
-
- return this._pagesData.pages.page.(function::attribute(aAttrName) == aAttrValue);
- },
-
- _deletePageByIndex: function(aPageIndex) {
- let existedPages = this._getPagesByAttribute("index", aPageIndex);
- if (!existedPages.length())
- return;
-
- while (existedPages[0])
- delete existedPages[0];
-
- return true;
- },
-
- addPage: function(aPageIndex, aURL, aTitle, aRefreshConditions) {
- if (!this._pagesData)
- return;
-
- this._deletePageByIndex(aPageIndex);
-
- let page = <page url={aURL} index={aPageIndex}/>;
- if (typeof aTitle === "string")
- page.@custom_title = aTitle;
-
- this.getURLDataForPage(page, aRefreshConditions);
- this._pagesData.pages.page += page;
-
- this.__pagesDataDOM = null;
- this.notifyTabClients("UPDATE_PROPS", {pageIndex: aPageIndex, url: aURL});
- },
-
- removePage: function(aPageIndex) {
- if (!this._pagesData)
- return;
-
- if (this._deletePageByIndex(aPageIndex)) {
- this.__pagesDataDOM = null;
- this.notifyTabClients("UPDATE_PROPS", {pageIndex: aPageIndex});
- }
- },
-
- swapPages: function(aPageIndexFrom, aPageIndexTo) {
- if (!(aPageIndexFrom && aPageIndexTo))
- return;
-
- let fromPage = this._getPageByIndex(aPageIndexFrom);
- let toPage = this._getPageByIndex(aPageIndexTo);
-
- if (fromPage)
- fromPage.@index = aPageIndexTo;
-
- if (toPage)
- toPage.@index = aPageIndexFrom;
-
- this.__pagesDataDOM = null;
- this.notifyTabClients("UPDATE_PROPS", {pageIndex: aPageIndexFrom});
- this.notifyTabClients("UPDATE_PROPS", {pageIndex: aPageIndexTo});
- },
-
- updatePageProps: function(aData) {
- if (!aData || !this._pagesData)
- return;
-
- let url = aData.url;
-
- for each (let page in this._getPagesByAttribute("url", url))
- for (let [propName, propValue] in Iterator(aData))
- page.@[propName] = propValue || "";
-
- this.__pagesDataDOM = null;
- this.notifyTabClients("UPDATE_PROPS", {url: url});
- },
-
- setPageProps: function(aPageIndex, aData, aRefreshConditions) {
- if (!this._pagesData)
- return;
-
- if (("title" in aData) && !("custom_title" in aData)) {
- aData.custom_title = aData.title;
- aData.title = "";
- }
-
- let safeUnicode = gYaSearchService.safeUnicode;
- for (let [propName, propValue] in Iterator(aData))
- aData[propName] = safeUnicode(propValue);
-
- aPageIndex = aPageIndex.toString();
-
- let page = this._getPageByIndex(aPageIndex);
-
- if (!page)
- return this.addPage(aPageIndex, aData.url, aData.custom_title, aRefreshConditions);
-
- let prevURL = page.@url.toString();
-
- for (let [propName, propValue] in Iterator(aData))
- page.@[propName] = propValue || "";
-
- this.getURLDataForPage(page, aRefreshConditions);
-
- this.__pagesDataDOM = null;
- this.notifyTabClients("UPDATE_PROPS", {pageIndex: aPageIndex, url: aData.url || null});
- },
-
- getPageProps: function(aPageIndex) {
- if (!this._pagesData)
- return;
-
- aPageIndex = aPageIndex.toString();
-
- let result;
- let page = this._getPageByIndex(aPageIndex);
-
- if (page) {
- result = {
- index: aPageIndex,
- title: (page.@custom_title.toString() || page.@title.toString()),
- url: page.@url.toString(),
- state: page.@state.toString()
- };
-
- result.img = this.getAboutImgURL(result.url);
-
- } else {
- result = {
- index: aPageIndex,
- title: "",
- url: "",
- img: "",
- state: ""
- };
- }
-
- return result;
- },
-
- getPropsForURL: function(aURL) {
- let page = <page url={aURL}/>;
- this.getURLDataForPage(page);
-
- let props = {};
- ["url", "title", "img", "state"].forEach(function(attr) {
- props[attr] = page.@[attr].toString() || "";
- });
-
- return props;
- },
-
- getImageForURL: function(aURL) {
- return gYaStorage.getImageForURL(aURL);
- },
-
- get secURLParam() {
- delete this.secURLParam;
- return this.secURLParam = (gYaSearchService.generateGUID.toString()).replace(/\{|\}|\-/g, "");
- },
-
- __pagesDataDOM: null,
- __pagesDataDOMCloned: null,
-
- get _pagesDataDOM() {
- if (!this.__pagesDataDOM) {
- this.__pagesDataDOMCloned = null;
-
- this.__pagesDataDOM = gYaSearchService.getDOMDocContent2("ftab/xsl-thumbs-template.xsl",
- gYaSearchService.domParser.parseFromString(this._pagesData.toSource(), "text/xml"),
- { secURLParam: this.secURLParam,
- thumbsInRow: this.settings.thumbsInRow,
- thumbsInCol: this.settings.thumbsInCol });
- }
-
- var me = this;
- new G_Timer(function() {
- me.__pagesDataDOMCloned = me.__pagesDataDOM ? me.__pagesDataDOM.cloneNode(true) : null;
- }, 2000);
-
- let res = this.__pagesDataDOMCloned || this.__pagesDataDOM.cloneNode(true);
- this.__pagesDataDOMCloned = null;
-
- return res;
- },
-
- _cleanUpTimer: null,
-
- _cleanUp: function() {
- if (!this._pagesData)
- return;
-
- let urls = [];
- for each (let page in this._pagesData.pages.page) {
- let url = page.@url.toString();
- if (url && urls.indexOf(url) === -1) {
- urls.push(url);
- }
- }
-
- gYaStorage._dbCleanupOldURLData(urls);
- },
-
- _isRunned: false,
-
- _run: function() {
- if (this._isRunned)
- return;
-
- this._loadPagesData();
-
- var me = this;
- this._cleanUpTimer = new G_Timer(function() { me._cleanUp(); }, 60*60*1000, true);
-
- this._isRunned = true;
- },
-
- _stop: function() {
- if (!this._isRunned)
- return;
-
- if (this._SShotGrabber) {
- this._SShotGrabber.destroy();
- this._SShotGrabber = null;
- }
-
- this._tabClients = [];
- this._destroyPagesData();
-
- if (this._cleanUpTimer) {
- this._cleanUpTimer.cancel();
- this._cleanUpTimer = null;
- }
-
- this._isRunned = false;
- },
-
- _checkCanStop: function() {
- },
-
- _tabClients: [],
-
- createTabClient: function(aYaFTabObject) {
- if (this._tabClients.some(function(aTabClient) { return aTabClient === aYaFTabObject; }))
- return;
-
- this._tabClients.push(aYaFTabObject);
-
- this._run();
-
- return this._pagesDataDOM;
- },
-
- destroyTabClient: function(aYaFTabObject) {
- this._tabClients = this._tabClients.filter(function(aTabClient) { return aTabClient !== aYaFTabObject; });
- this._checkCanStop();
- },
-
- notifyTabClients: function(aTopic, aData, aTabClient) {
- (aTabClient ? [aTabClient] : this._tabClients)
- .forEach(function(aTabClient) {
- aTabClient.observe(aTopic, aData);
- });
-
- if (aTopic == "UPDATE_PROPS") {
- this._savePagesDataTimed();
- }
- },
-
- getURLData: function(aURL, aRefreshConditions) {
- let url = this.getURLFromString(aURL);
- if (!url)
- return;
-
- let urlData = gYaStorage.getURLData(url);
-
- if (urlData && urlData.img)
- urlData.img = this.getAboutImgURL(url);
-
- if (this._isScreenExpired(url, urlData, aRefreshConditions))
- this.getSShotForURL(url);
-
- return urlData;
- },
-
- getURLDataForPage: function(aPage, aRefreshConditions) {
- let url = this.getURLFromString(aPage.@url.toString());
- if (!url)
- return;
-
- let urlData = this.getURLData(url, aRefreshConditions) || {};
-
- if (this.SShotGrabber.isURLInQueue(url))
- urlData.state = "busy";
-
- for (let [propName, propValue] in Iterator(urlData))
- aPage.@[propName] = propValue || "";
-
- return urlData;
- },
-
- getURLsData: function(aURLs) {},
-
- _SShotGrabber: null,
- get SShotGrabber() {
- return this._SShotGrabber || (this._SShotGrabber = new YaSShotGrabber(this));
- },
-
- _isScreenExpired: function(aURL, aURLData, aRefreshConditions) {
- let url = this.getURLFromString(aURL);
- if (!url)
- return false;
-
- if (this.SShotGrabber.isURLInQueue(url))
- return false;
-
- let urlData = (typeof aURLData === "undefined") ? this.getURLData(url) : aURLData;
- if (!urlData)
- return true;
-
- let checkTimeDiff = Math.abs(Date.now() - urlData.checkTime);
-
- if (aRefreshConditions) {
- if ("forcedRefresh" in aRefreshConditions && aRefreshConditions.forcedRefresh === true)
- return true;
-
- if ("checkedTimeMin" in aRefreshConditions && aRefreshConditions.checkedTimeMin > urlData.checkTime)
- return true;
-
- if ("olderThan" in aRefreshConditions && checkTimeDiff > aRefreshConditions.olderThan)
- return true;
- }
-
- if ((checkTimeDiff > (7 * DAY_SECS)) || (urlData.httpStatus == 404 && checkTimeDiff > (3 * DAY_SECS))) {
- return true;
- }
-
- return false;
- },
-
- getSShotForURL: function(aURL) {
- if (this.SShotGrabber.getCanvasForURL(aURL)) {
- this.updatePageProps({url: aURL, state: "busy"});
- }
- },
-
- getAboutImgURL: function(aURL) {
- return aURL ? ("about:yandex-tabs?sec=" + this.secURLParam + "&image=" + aURL) : null;
- },
-
- _removeImgURLFromCache: function(aURL) {
- let uri = gYaSearchService.makeURI(aURL);
- if (uri) {
- try {
- const imageCache = Cc["@mozilla.org/image/cache;1"].getService(Ci.imgICache);
- imageCache.removeEntry(uri);
- } catch(e) {}
- }
- },
-
- onSShotCreated: function(aPageData) {
- gYaStorage.setURLData(aPageData);
-
- if (aPageData) {
- let imgURL = this.getAboutImgURL(aPageData.url);
- this._removeImgURLFromCache(imgURL);
- aPageData.img = imgURL;
- }
-
- this.updatePageProps(gYaStorage.getURLData(aPageData.url));
- },
-
- getSitesFromHistory: function(aMaxResults, aOnComplete) {
- if (!aOnComplete)
- return;
-
- let me = this;
- new G_Timer(function() {
- me._getSitesFromHistory(aMaxResults, aOnComplete);
- }, 0);
- },
-
- _getSitesFromHistory: function(aMaxResults, aOnComplete) {
- let maxResults = aMaxResults || 10;
-
- let historyService = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
-
- let query = historyService.getNewQuery();
-
- let options = historyService.getNewQueryOptions();
- options.maxResults = maxResults * 2;
- options.sortingMode = options.SORT_BY_DATE_DESCENDING;
-
- let result = (historyService.executeQuery(query, options)).root;
- result.containerOpen = true;
-
- let faviconService = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
- let ioservice = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-
- const nsIURI = Ci.nsIURI;
-
- let sites = [];
- for (let i = 0, count = result.childCount; i < count && i < maxResults; i++) {
- let node = result.getChild(i);
-
- let nodeURI = ioservice.newURI(node.uri, null, null);
-
- if (!/^https?|file$/.test(nodeURI.scheme))
- continue;
-
- if (/\.swf$/.test(nodeURI.spec))
- continue;
-
- let title = node.title;
- let icon = node.icon ?
- (node.icon instanceof nsIURI ? node.icon.spec : node.icon) :
- faviconService.getFaviconImageForPage(nodeURI).spec;
-
- let pathForTitle = nodeURI.path.split("?")[0].split("/").pop();
-
- if (title == nodeURI.path || title == pathForTitle) {
- if (!node.icon)
- continue;
-
- title = nodeURI.spec;
- }
-
- sites.push({
- title: title,
- url: node.uri,
- icon: icon
- });
- }
-
- result.containerOpen = false;
-
- if (aOnComplete) {
- aOnComplete(sites);
- aOnComplete = null;
- }
- },
-
- findSites: function(aSearchString, aOnComplete) {
- if (!aOnComplete)
- return;
-
- let me = this;
- new G_Timer(function() {
- me._findSites(aSearchString, aOnComplete);
- }, 0);
- },
-
- _findSites: function(aSearchString, aOnComplete) {
- let acomplete = Cc["@mozilla.org/autocomplete/search;1?name=history"]
- .getService(Ci.nsIAutoCompleteSearch);
-
- let callback = function(aResult) {
- if (aOnComplete) {
- aOnComplete(aResult);
- aOnComplete = null;
- }
- };
-
- acomplete.startSearch(aSearchString, "", null, ({
- onSearchResult: function(search, result) {
- switch (result.searchResult) {
- case result.RESULT_NOMATCH:
- return callback();
-
- case result.RESULT_SUCCESS:
- case result.RESULT_SUCCESS_ONGOING:
- acomplete.stopSearch();
-
- let sites = [];
- for (let i = 0, count = result.matchCount; i < count; i++) {
- sites.push({
- title: result.getCommentAt(i),
- url: result.getValueAt(i),
- icon: result.getImageAt(i)
- });
- }
- callback(sites);
- break;
-
- default:
- break;
- }
- }
- }));
- }
- };
-
- Components.utils.import("resource://yasearch/bar.protocol.jsm", gYaFTab);
-
- gYaFTab._init();