diff options
Diffstat (limited to 'application/palemoon/components')
84 files changed, 4680 insertions, 7716 deletions
diff --git a/application/palemoon/components/about/AboutRedirector.cpp b/application/palemoon/components/about/AboutRedirector.cpp index d927b7936..d52b873b9 100644 --- a/application/palemoon/components/about/AboutRedirector.cpp +++ b/application/palemoon/components/about/AboutRedirector.cpp @@ -9,8 +9,6 @@ #include "nsNetUtil.h" #include "nsIScriptSecurityManager.h" #include "mozilla/ArrayUtils.h" -#include "nsDOMString.h" - namespace mozilla { namespace browser { @@ -21,7 +19,6 @@ struct RedirEntry { const char* id; const char* url; uint32_t flags; - const char* idbOriginPostfix; }; /* @@ -33,17 +30,47 @@ struct RedirEntry { URI_SAFE_FOR_UNTRUSTED_CONTENT. */ static RedirEntry kRedirMap[] = { - { "certerror", "chrome://browser/content/certerror/aboutCertError.xhtml", + { + "certerror", "chrome://browser/content/certerror/aboutCertError.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "feeds", "chrome://browser/content/feeds/subscribe.xhtml", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "feeds", "chrome://browser/content/feeds/subscribe.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "rights", + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "home", "chrome://browser/content/abouthome/aboutHome.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::MAKE_LINKABLE | + nsIAboutModule::ALLOW_SCRIPT + }, + { + "newtab", "chrome://browser/content/newtab/newTab.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "palemoon", "chrome://global/content/memoriam.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "permissions", "chrome://browser/content/preferences/aboutPermissions.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "rights", #ifdef MOZ_OFFICIAL_BRANDING "chrome://global/content/aboutRights.xhtml", #else @@ -51,34 +78,27 @@ static RedirEntry kRedirMap[] = { #endif nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::ALLOW_SCRIPT }, - { "palemoon", "chrome://global/content/palemoon.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "robots", "chrome://browser/content/aboutRobots.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "logopage", "chrome://global/content/logopage.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "robots", "chrome://browser/content/aboutRobots.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::ALLOW_SCRIPT }, - { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, + nsIAboutModule::ALLOW_SCRIPT + }, + { + "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, #ifdef MOZ_SERVICES_SYNC - { "sync-progress", "chrome://browser/content/sync/progress.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", - nsIAboutModule::ALLOW_SCRIPT }, + { + "sync-progress", "chrome://browser/content/sync/progress.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", + nsIAboutModule::ALLOW_SCRIPT + }, #endif - { "home", "chrome://browser/content/abouthome/aboutHome.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::MAKE_LINKABLE | - nsIAboutModule::ALLOW_SCRIPT }, - { "newtab", "chrome://browser/content/newtab/newTab.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "permissions", "chrome://browser/content/preferences/aboutPermissions.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul", - nsIAboutModule::ALLOW_SCRIPT }, }; static const int kRedirTotal = ArrayLength(kRedirMap); @@ -148,30 +168,6 @@ AboutRedirector::GetURIFlags(nsIURI *aURI, uint32_t *result) return NS_ERROR_ILLEGAL_VALUE; } -NS_IMETHODIMP -AboutRedirector::GetIndexedDBOriginPostfix(nsIURI *aURI, nsAString &result) -{ - NS_ENSURE_ARG_POINTER(aURI); - - nsAutoCString name = GetAboutModuleName(aURI); - - for (int i = 0; i < kRedirTotal; i++) { - if (name.Equals(kRedirMap[i].id)) { - const char* postfix = kRedirMap[i].idbOriginPostfix; - if (!postfix) { - break; - } - - result.AssignASCII(postfix); - return NS_OK; - } - } - - SetDOMStringToNull(result); - return NS_ERROR_ILLEGAL_VALUE; -} - - nsresult AboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **result) { diff --git a/application/palemoon/components/build/moz.build b/application/palemoon/components/build/moz.build index f8073907e..c85723e16 100644 --- a/application/palemoon/components/build/moz.build +++ b/application/palemoon/components/build/moz.build @@ -18,17 +18,22 @@ LOCAL_INCLUDES += [ '../about', '../dirprovider', '../feeds', - '../migration', '../shell', ] if CONFIG['OS_ARCH'] == 'WINNT': OS_LIBS += [ + 'esent', + 'netapi32', 'ole32', 'shell32', 'shlwapi', 'version', ] + DELAYLOAD_DLLS += [ + 'esent.dll', + 'netapi32.dll', + ] # Mac: Need to link with CoreFoundation for Mac Migrators (PList reading code) # GTK2: Need to link with glib for GNOME shell service diff --git a/application/palemoon/components/build/nsBrowserCompsCID.h b/application/palemoon/components/build/nsBrowserCompsCID.h index e325e43d4..23670ae80 100644 --- a/application/palemoon/components/build/nsBrowserCompsCID.h +++ b/application/palemoon/components/build/nsBrowserCompsCID.h @@ -4,14 +4,6 @@ ///////////////////////////////////////////////////////////////////////////// -#ifdef XP_WIN -#define NS_WINIEHISTORYENUMERATOR_CID \ -{ 0x93480624, 0x806e, 0x4756, { 0xb7, 0xcb, 0x0f, 0xb7, 0xdd, 0x74, 0x6a, 0x8f } } - -#define NS_IEHISTORYENUMERATOR_CONTRACTID \ - "@mozilla.org/profile/migrator/iehistoryenumerator;1" -#endif - #define NS_SHELLSERVICE_CID \ { 0x63c7b9f4, 0xcc8, 0x43f8, { 0xb6, 0x66, 0xa, 0x66, 0x16, 0x55, 0xcb, 0x73 } } diff --git a/application/palemoon/components/build/nsModule.cpp b/application/palemoon/components/build/nsModule.cpp index d5b79b455..304280ca9 100644 --- a/application/palemoon/components/build/nsModule.cpp +++ b/application/palemoon/components/build/nsModule.cpp @@ -16,10 +16,6 @@ #include "nsGNOMEShellService.h" #endif -#if defined(XP_WIN) -#include "nsIEHistoryEnumerator.h" -#endif - #include "rdf.h" #include "nsFeedSniffer.h" #include "AboutRedirector.h" @@ -40,10 +36,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init) #endif -#if defined(XP_WIN) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator) -#endif - NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer) NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID); @@ -54,9 +46,7 @@ NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID); #endif NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID); NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID); -#if defined(XP_WIN) -NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID); -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID); #endif @@ -69,9 +59,7 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = { #endif { &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor }, { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create }, -#if defined(XP_WIN) - { &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor }, -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX { &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor }, #endif { nullptr } @@ -91,7 +79,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "palemoon", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, - { NS_ABOUT_MODULE_CONTRACTID_PREFIX "logopage", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, #ifdef MOZ_SERVICES_SYNC @@ -102,9 +89,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, -#if defined(XP_WIN) - { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID }, -#elif defined(XP_MACOSX) +#ifdef XP_MACOSX { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID }, #endif { nullptr } diff --git a/application/palemoon/components/dirprovider/DirectoryProvider.cpp b/application/palemoon/components/dirprovider/DirectoryProvider.cpp index 4d3993b7f..85728b351 100644 --- a/application/palemoon/components/dirprovider/DirectoryProvider.cpp +++ b/application/palemoon/components/dirprovider/DirectoryProvider.cpp @@ -34,57 +34,7 @@ NS_IMPL_ISUPPORTS(DirectoryProvider, NS_IMETHODIMP DirectoryProvider::GetFile(const char *aKey, bool *aPersist, nsIFile* *aResult) { - nsresult rv; - - *aResult = nullptr; - - // NOTE: This function can be reentrant through the NS_GetSpecialDirectory - // call, so be careful not to cause infinite recursion. - - nsCOMPtr<nsIFile> file; - - char const* leafName = nullptr; - - if (!strcmp(aKey, NS_APP_BOOKMARKS_50_FILE)) { - leafName = "bookmarks.html"; - - nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (prefs) { - nsCString path; - rv = prefs->GetCharPref("browser.bookmarks.file", getter_Copies(path)); - if (NS_SUCCEEDED(rv)) { - NS_NewNativeLocalFile(path, true, getter_AddRefs(file)); - } - } - } - else { - return NS_ERROR_FAILURE; - } - - nsDependentCString leafstr(leafName); - - nsCOMPtr<nsIFile> parentDir; - if (file) { - rv = file->GetParent(getter_AddRefs(parentDir)); - if (NS_FAILED(rv)) - return rv; - } - else { - rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(parentDir)); - if (NS_FAILED(rv)) - return rv; - - rv = parentDir->Clone(getter_AddRefs(file)); - if (NS_FAILED(rv)) - return rv; - - file->AppendNative(leafstr); - } - - *aPersist = true; - NS_ADDREF(*aResult = file); - - return NS_OK; + return NS_ERROR_FAILURE; } static void diff --git a/application/palemoon/components/downloads/DownloadsCommon.jsm b/application/palemoon/components/downloads/DownloadsCommon.jsm index b90baaf9c..c6614e780 100644 --- a/application/palemoon/components/downloads/DownloadsCommon.jsm +++ b/application/palemoon/components/downloads/DownloadsCommon.jsm @@ -104,7 +104,7 @@ const kPartialDownloadSuffix = ".part"; const kPrefBranch = Services.prefs.getBranch("browser.download."); -let PrefObserver = { +var PrefObserver = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), getPref: function PO_getPref(name) { @@ -867,9 +867,19 @@ DownloadsDataCtor.prototype = { // Sort backwards by start time, ensuring that the most recent // downloads are added first regardless of their state. - let loadedItemsArray = [dataItem - for each (dataItem in this.dataItems) - if (dataItem)]; + // Tycho: + //let loadedItemsArray = [dataItem + // for each (dataItem in this.dataItems) + // if (dataItem)]; + + let loadedItemsArray = []; + + for each (let dataItem in this.dataItems) { + if (dataItem) { + loadedItemsArray.push(dataItem); + } + } + loadedItemsArray.sort(function(a, b) b.startTime - a.startTime); loadedItemsArray.forEach( function (dataItem) aView.onDataItemAdded(dataItem, false) diff --git a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js index e1d0e75d4..46e867068 100644 --- a/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js +++ b/application/palemoon/components/downloads/content/allDownloadsViewOverlay.js @@ -8,9 +8,9 @@ * ON IT AS AN API. */ -let Cu = Components.utils; -let Ci = Components.interfaces; -let Cc = Components.classes; +var Cu = Components.utils; +var Ci = Components.interfaces; +var Cc = Components.classes; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -1408,7 +1408,12 @@ DownloadsPlacesView.prototype = { _copySelectedDownloadsToClipboard: function DPV__copySelectedDownloadsToClipboard() { let selectedElements = this._richlistbox.selectedItems; - let urls = [e._shell.downloadURI for each (e in selectedElements)]; + // Tycho: let urls = [e._shell.downloadURI for each (e in selectedElements)]; + let urls = []; + + for each (e in selectedElements) { + urls.push(e._shell.downloadURI); + } Cc["@mozilla.org/widget/clipboardhelper;1"]. getService(Ci.nsIClipboardHelper).copyString(urls.join("\n"), document); @@ -1471,11 +1476,11 @@ DownloadsPlacesView.prototype = { goUpdateCommand("downloadsCmd_clearDownloads"); break; default: { - // Slicing the array to get a freezed list of selected items. Otherwise, - // the selectedItems array is live and doCommand may alter the selection - // while we are trying to do one particular action, like removing items - // from history. - let selectedElements = this._richlistbox.selectedItems.slice(); + // Cloning the nodelist into an array to get a frozen list of selected items. + // Otherwise, the selectedItems nodelist is live and doCommand may alter the + // selection while we are trying to do one particular action, like removing + // items from history. + let selectedElements = [...this._richlistbox.selectedItems]; for (let element of selectedElements) { element._shell.doCommand(aCommand); } diff --git a/application/palemoon/components/downloads/content/contentAreaDownloadsView.js b/application/palemoon/components/downloads/content/contentAreaDownloadsView.js index 29e2e368c..fbb18ab04 100644 --- a/application/palemoon/components/downloads/content/contentAreaDownloadsView.js +++ b/application/palemoon/components/downloads/content/contentAreaDownloadsView.js @@ -4,7 +4,7 @@ Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); -let ContentAreaDownloadsView = { +var ContentAreaDownloadsView = { init: function CADV_init() { let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox")); // Do not display the Places downloads in private windows diff --git a/application/palemoon/components/downloads/content/downloads.js b/application/palemoon/components/downloads/content/downloads.js index 1a2288041..0412344bc 100644 --- a/application/palemoon/components/downloads/content/downloads.js +++ b/application/palemoon/components/downloads/content/downloads.js @@ -590,6 +590,8 @@ const DownloadsPanel = { } }; +XPCOMUtils.defineConstant(this, "DownloadsPanel", DownloadsPanel); + //////////////////////////////////////////////////////////////////////////////// //// DownloadsOverlayLoader @@ -677,6 +679,8 @@ const DownloadsOverlayLoader = { } }; +XPCOMUtils.defineConstant(this, "DownloadsOverlayLoader", DownloadsOverlayLoader); + //////////////////////////////////////////////////////////////////////////////// //// DownloadsView @@ -1053,6 +1057,8 @@ const DownloadsView = { } } +XPCOMUtils.defineConstant(this, "DownloadsView", DownloadsView); + //////////////////////////////////////////////////////////////////////////////// //// DownloadsViewItem @@ -1414,6 +1420,8 @@ const DownloadsViewController = { } }; +XPCOMUtils.defineConstant(this, "DownloadsViewController", DownloadsViewController); + //////////////////////////////////////////////////////////////////////////////// //// DownloadsViewItemController @@ -1754,7 +1762,9 @@ const DownloadsSummary = { delete this._detailsNode; return this._detailsNode = node; } -} +}; + +XPCOMUtils.defineConstant(this, "DownloadsSummary", DownloadsSummary); //////////////////////////////////////////////////////////////////////////////// //// DownloadsFooter @@ -1811,3 +1821,5 @@ const DownloadsFooter = { return this._footerNode = node; } }; + +XPCOMUtils.defineConstant(this, "DownloadsFooter", DownloadsFooter); diff --git a/application/palemoon/components/downloads/content/indicator.js b/application/palemoon/components/downloads/content/indicator.js index b0e3217e5..e6a5bd012 100644 --- a/application/palemoon/components/downloads/content/indicator.js +++ b/application/palemoon/components/downloads/content/indicator.js @@ -254,6 +254,12 @@ const DownloadsButton = { } }; +Object.defineProperty(this, "DownloadsButton", { + value: DownloadsButton, + enumerable: true, + writable: false +}); + //////////////////////////////////////////////////////////////////////////////// //// DownloadsIndicatorView @@ -592,3 +598,9 @@ const DownloadsIndicatorView = { document.getElementById("downloads-indicator-progress"); } }; + +Object.defineProperty(this, "DownloadsIndicatorView", { + value: DownloadsIndicatorView, + enumerable: true, + writable: false +}); diff --git a/application/palemoon/components/feeds/FeedConverter.js b/application/palemoon/components/feeds/FeedConverter.js index 75115cc94..d0f573774 100644 --- a/application/palemoon/components/feeds/FeedConverter.js +++ b/application/palemoon/components/feeds/FeedConverter.js @@ -260,7 +260,7 @@ FeedConverter.prototype = { } chromeChannel.loadGroup = this._request.loadGroup; - chromeChannel.asyncOpen(this._listener, null); + chromeChannel.asyncOpen2(this._listener); } finally { this._releaseHandles(); diff --git a/application/palemoon/components/feeds/FeedWriter.js b/application/palemoon/components/feeds/FeedWriter.js index 2afa35a5b..cbb146564 100644 --- a/application/palemoon/components/feeds/FeedWriter.js +++ b/application/palemoon/components/feeds/FeedWriter.js @@ -9,6 +9,7 @@ const Cr = Components.results; const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/NetUtil.jsm"); const FEEDWRITER_CID = Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}"); const FEEDWRITER_CONTRACTID = "@mozilla.org/browser/feeds/result-writer;1"; @@ -1137,16 +1138,14 @@ FeedWriter.prototype = { var nullPrincipal = Cc["@mozilla.org/nullprincipal;1"]. createInstance(Ci.nsIPrincipal); - var resolvedURI = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService). - newChannel2("about:feeds", - null, - null, - null, // aLoadingNode - nullPrincipal, - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_NORMAL, - Ci.nsIContentPolicy.TYPE_OTHER).URI; + // this channel is not going to be openend, use a nullPrincipal + // and the most restrctive securityFlag. + let resolvedURI = NetUtil.newChannel({ + uri: "about:feeds", + loadingPrincipal: nullPrincipal, + securityFlags: Ci.nsILoadInfo.SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, + contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER + }).URI; if (resolvedURI.equals(chan.URI)) return chan.originalURI; @@ -1395,6 +1394,8 @@ FeedWriter.prototype = { .QueryInterface(Ci.nsIDocShell) .QueryInterface(Ci.nsILoadContext) .usePrivateBrowsing; + var nullPrincipal = Cc["@mozilla.org/nullprincipal;1"] + .createInstance(Ci.nsIPrincipal); this._faviconService.setAndFetchFaviconForPage(readerURI, faviconURI, false, usePrivateBrowsing ? this._faviconService.FAVICON_LOAD_PRIVATE : this._faviconService.FAVICON_LOAD_NON_PRIVATE, @@ -1409,7 +1410,7 @@ FeedWriter.prototype = { self._contentSandbox.menuItem = null; self._contentSandbox.dataURL = null; } - }); + }, nullPrincipal); }, classID: FEEDWRITER_CID, diff --git a/application/palemoon/components/feeds/moz.build b/application/palemoon/components/feeds/moz.build index 1dea0ce77..7ae9141aa 100644 --- a/application/palemoon/components/feeds/moz.build +++ b/application/palemoon/components/feeds/moz.build @@ -35,5 +35,3 @@ for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'): LOCAL_INCLUDES += [ '../build', ] - -FAIL_ON_WARNINGS = True diff --git a/application/palemoon/components/feeds/nsFeedSniffer.cpp b/application/palemoon/components/feeds/nsFeedSniffer.cpp index 61cc77bdd..f314d3d3b 100644 --- a/application/palemoon/components/feeds/nsFeedSniffer.cpp +++ b/application/palemoon/components/feeds/nsFeedSniffer.cpp @@ -135,7 +135,7 @@ FindChar(char c, const char *begin, const char *end) * it's possible that someone embedded one of these tags inside a document of * another type, e.g. a HTML document, and we don't want to show the preview * page if the document isn't actually a feed. - * + * * @param start * The beginning of the data being sniffed * @param end @@ -331,7 +331,7 @@ nsFeedSniffer::OnStartRequest(nsIRequest* request, nsISupports* context) return NS_OK; } -NS_METHOD +nsresult nsFeedSniffer::AppendSegmentToString(nsIInputStream* inputStream, void* closure, const char* rawSegment, diff --git a/application/palemoon/components/feeds/nsFeedSniffer.h b/application/palemoon/components/feeds/nsFeedSniffer.h index 57e10d954..a0eb9862c 100644 --- a/application/palemoon/components/feeds/nsFeedSniffer.h +++ b/application/palemoon/components/feeds/nsFeedSniffer.h @@ -10,7 +10,7 @@ #include "mozilla/Attributes.h" class nsFeedSniffer final : public nsIContentSniffer, - nsIStreamListener + nsIStreamListener { public: NS_DECL_ISUPPORTS @@ -18,12 +18,12 @@ public: NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER - static NS_METHOD AppendSegmentToString(nsIInputStream* inputStream, - void* closure, - const char* rawSegment, - uint32_t toOffset, - uint32_t count, - uint32_t* writeCount); + static nsresult AppendSegmentToString(nsIInputStream* inputStream, + void* closure, + const char* rawSegment, + uint32_t toOffset, + uint32_t count, + uint32_t* writeCount); protected: ~nsFeedSniffer() {} diff --git a/application/palemoon/components/fuel/fuelApplication.js b/application/palemoon/components/fuel/fuelApplication.js index 89d568ae1..017813143 100644 --- a/application/palemoon/components/fuel/fuelApplication.js +++ b/application/palemoon/components/fuel/fuelApplication.js @@ -729,7 +729,7 @@ var ApplicationFactory = { }; -#include ../../../toolkit/components/exthelper/extApplication.js +#include ../../../../toolkit/components/exthelper/extApplication.js //================================================= // Application constructor diff --git a/application/palemoon/components/migration/BrowserProfileMigrators.manifest b/application/palemoon/components/migration/BrowserProfileMigrators.manifest deleted file mode 100644 index d7fec75e3..000000000 --- a/application/palemoon/components/migration/BrowserProfileMigrators.manifest +++ /dev/null @@ -1,14 +0,0 @@ -component {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} ProfileMigrator.js -contract @mozilla.org/toolkit/profile-migrator;1 {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} -component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26} -component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386} -#ifdef HAS_IE_MIGRATOR -component {3d2532e3-4932-4774-b7ba-968f5899d3a4} IEProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=ie {3d2532e3-4932-4774-b7ba-968f5899d3a4} -#endif -#ifdef HAS_SAFARI_MIGRATOR -component {4b609ecf-60b2-4655-9df4-dc149e474da1} SafariProfileMigrator.js -contract @mozilla.org/profile/migrator;1?app=browser&type=safari {4b609ecf-60b2-4655-9df4-dc149e474da1} -#endif diff --git a/application/palemoon/components/migration/ChromeProfileMigrator.js b/application/palemoon/components/migration/ChromeProfileMigrator.js deleted file mode 100644 index 61955fbb4..000000000 --- a/application/palemoon/components/migration/ChromeProfileMigrator.js +++ /dev/null @@ -1,463 +0,0 @@ -/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1"; - -const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000; -const S100NS_PER_MS = 10; - -const AUTH_TYPE = { - SCHEME_HTML: 0, - SCHEME_BASIC: 1, - SCHEME_DIGEST: 2 -}; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto", - "resource://gre/modules/OSCrypto.jsm"); - -/** - * Convert Chrome time format to Date object - * - * @param aTime - * Chrome time - * @return converted Date object - * @note Google Chrome uses FILETIME / 10 as time. - * FILETIME is based on same structure of Windows. - */ -function chromeTimeToDate(aTime) -{ - return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000); -} - -/** - * Insert bookmark items into specific folder. - * - * @param aFolderId - * id of folder where items will be inserted - * @param aItems - * bookmark items to be inserted - */ -function insertBookmarkItems(aFolderId, aItems) -{ - for (let i = 0; i < aItems.length; i++) { - let item = aItems[i]; - - try { - if (item.type == "url") { - PlacesUtils.bookmarks.insertBookmark(aFolderId, - NetUtil.newURI(item.url), - PlacesUtils.bookmarks.DEFAULT_INDEX, - item.name); - } else if (item.type == "folder") { - let newFolderId = - PlacesUtils.bookmarks.createFolder(aFolderId, - item.name, - PlacesUtils.bookmarks.DEFAULT_INDEX); - - insertBookmarkItems(newFolderId, item.children); - } - } catch (e) { - Cu.reportError(e); - } - } -} - - -function ChromeProfileMigrator() { - let chromeUserDataFolder = FileUtils.getDir( -#ifdef XP_WIN - "LocalAppData", ["Google", "Chrome", "User Data"] -#elifdef XP_MACOSX - "ULibDir", ["Application Support", "Google", "Chrome"] -#else - "Home", [".config", "google-chrome"] -#endif - , false); - this._chromeUserDataFolder = chromeUserDataFolder.exists() ? - chromeUserDataFolder : null; -} - -ChromeProfileMigrator.prototype = Object.create(MigratorPrototype); - -ChromeProfileMigrator.prototype.getResources = - function Chrome_getResources(aProfile) { - if (this._chromeUserDataFolder) { - let profileFolder = this._chromeUserDataFolder.clone(); - profileFolder.append(aProfile.id); - if (profileFolder.exists()) { - let possibleResources = [GetBookmarksResource(profileFolder), - GetHistoryResource(profileFolder), - GetCookiesResource(profileFolder), -#ifdef XP_WIN - GetWindowsPasswordsResource(profileFolder) -#endif - ]; - return [r for each (r in possibleResources) if (r != null)]; - } - } - return []; - }; - -Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", { - get: function Chrome_sourceProfiles() { - if ("__sourceProfiles" in this) - return this.__sourceProfiles; - - if (!this._chromeUserDataFolder) - return []; - - let profiles = []; - try { - // Local State is a JSON file that contains profile info. - let localState = this._chromeUserDataFolder.clone(); - localState.append("Local State"); - if (!localState.exists()) - throw new Error("Chrome's 'Local State' file does not exist."); - if (!localState.isReadable()) - throw new Error("Chrome's 'Local State' file could not be read."); - - let fstream = Cc[FILE_INPUT_STREAM_CID].createInstance(Ci.nsIFileInputStream); - fstream.init(localState, -1, 0, 0); - let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(), - { charset: "UTF-8" }); - let info_cache = JSON.parse(inputStream).profile.info_cache; - for (let profileFolderName in info_cache) { - let profileFolder = this._chromeUserDataFolder.clone(); - profileFolder.append(profileFolderName); - profiles.push({ - id: profileFolderName, - name: info_cache[profileFolderName].name || profileFolderName, - }); - } - } catch (e) { - Cu.reportError("Error detecting Chrome profiles: " + e); - // If we weren't able to detect any profiles above, fallback to the Default profile. - let defaultProfileFolder = this._chromeUserDataFolder.clone(); - defaultProfileFolder.append("Default"); - if (defaultProfileFolder.exists()) { - profiles = [{ - id: "Default", - name: "Default", - }]; - } - } - - // Only list profiles from which any data can be imported - return this.__sourceProfiles = profiles.filter(function(profile) { - let resources = this.getResources(profile); - return resources && resources.length > 0; - }, this); - } -}); - -Object.defineProperty(ChromeProfileMigrator.prototype, "sourceHomePageURL", { - get: function Chrome_sourceHomePageURL() { - let prefsFile = this._chromeUserDataFolder.clone(); - prefsFile.append("Preferences"); - if (prefsFile.exists()) { - // XXX reading and parsing JSON is synchronous. - let fstream = Cc[FILE_INPUT_STREAM_CID]. - createInstance(Ci.nsIFileInputStream); - fstream.init(file, -1, 0, 0); - try { - return JSON.parse( - NetUtil.readInputStreamToString(fstream, fstream.available(), - { charset: "UTF-8" }) - ).homepage; - } - catch(e) { - Cu.reportError("Error parsing Chrome's preferences file: " + e); - } - } - return ""; - } -}); - -function GetBookmarksResource(aProfileFolder) { - let bookmarksFile = aProfileFolder.clone(); - bookmarksFile.append("Bookmarks"); - if (!bookmarksFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - migrate: function(aCallback) { - NetUtil.asyncFetch(bookmarksFile, MigrationUtils.wrapMigrateFunction( - function(aInputStream, aResultCode) { - if (!Components.isSuccessCode(aResultCode)) - throw new Error("Could not read Bookmarks file"); - - // Parse Chrome bookmark file that is JSON format - let bookmarkJSON = NetUtil.readInputStreamToString( - aInputStream, aInputStream.available(), { charset : "UTF-8" }); - let roots = JSON.parse(bookmarkJSON).roots; - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: function() { - // Importing bookmark bar items - if (roots.bookmark_bar.children && - roots.bookmark_bar.children.length > 0) { - // Toolbar - let parentId = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - parentId = MigrationUtils.createImportedBookmarksFolder( - "Chrome", parentId); - } - insertBookmarkItems(parentId, roots.bookmark_bar.children); - } - - // Importing bookmark menu items - if (roots.other.children && - roots.other.children.length > 0) { - // Bookmark menu - let parentId = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - parentId = MigrationUtils.createImportedBookmarksFolder( - "Chrome", parentId); - } - insertBookmarkItems(parentId, roots.other.children); - } - } - }, null); - }, aCallback)); - } - }; -} - -function GetHistoryResource(aProfileFolder) { - let historyFile = aProfileFolder.clone(); - historyFile.append("History"); - if (!historyFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.HISTORY, - - migrate: function(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(historyFile); - let stmt = dbConn.createAsyncStatement( - "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0"); - - stmt.executeAsync({ - handleResult : function(aResults) { - let places = []; - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - try { - // if having typed_count, we changes transition type to typed. - let transType = PlacesUtils.history.TRANSITION_LINK; - if (row.getResultByName("typed_count") > 0) - transType = PlacesUtils.history.TRANSITION_TYPED; - - places.push({ - uri: NetUtil.newURI(row.getResultByName("url")), - title: row.getResultByName("title"), - visits: [{ - transitionType: transType, - visitDate: chromeTimeToDate( - row.getResultByName( - "last_visit_time")) * 1000, - }], - }); - } catch (e) { - Cu.reportError(e); - } - } - - try { - PlacesUtils.asyncHistory.updatePlaces(places); - } catch (e) { - Cu.reportError(e); - } - }, - - handleError : function(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion : function(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - } - }); - stmt.finalize(); - } - }; -} - -function GetCookiesResource(aProfileFolder) { - let cookiesFile = aProfileFolder.clone(); - cookiesFile.append("Cookies"); - if (!cookiesFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.COOKIES, - - migrate: function(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(cookiesFile); - let stmt = dbConn.createAsyncStatement( - "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies"); - - stmt.executeAsync({ - handleResult : function(aResults) { - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - let host_key = row.getResultByName("host_key"); - if (host_key.match(/^\./)) { - // 1st character of host_key may be ".", so we have to remove it - host_key = host_key.substr(1); - } - - try { - let expiresUtc = - chromeTimeToDate(row.getResultByName("expires_utc")) / 1000; - Services.cookies.add(host_key, - row.getResultByName("path"), - row.getResultByName("name"), - row.getResultByName("value"), - row.getResultByName("secure"), - row.getResultByName("httponly"), - false, - parseInt(expiresUtc)); - } catch (e) { - Cu.reportError(e); - } - } - }, - - handleError : function(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion : function(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - }, - }); - stmt.finalize(); - } - } -} - -function GetWindowsPasswordsResource(aProfileFolder) { - let loginFile = aProfileFolder.clone(); - loginFile.append("Login Data"); - if (!loginFile.exists()) - return null; - - return { - type: MigrationUtils.resourceTypes.PASSWORDS, - - migrate(aCallback) { - let dbConn = Services.storage.openUnsharedDatabase(loginFile); - let stmt = dbConn.createAsyncStatement(` - SELECT origin_url, action_url, username_element, username_value, - password_element, password_value, signon_realm, scheme, date_created, - times_used FROM logins WHERE blacklisted_by_user = 0`); - let crypto = new OSCrypto(); - let utf8Converter = Cc["@mozilla.org/intl/utf8converterservice;1"].getService(Ci.nsIUTF8ConverterService); - - stmt.executeAsync({ - _rowToLoginInfo(row) { - let loginInfo = { - username: utf8Converter.convertURISpecToUTF8(row.getResultByName("username_value"), "UTF-8"), - password: utf8Converter.convertURISpecToUTF8( - crypto.decryptData(crypto.arrayToString(row.getResultByName("password_value")), null), - "UTF-8"), - hostName: NetUtil.newURI(row.getResultByName("origin_url")).prePath, - submitURL: null, - httpRealm: null, - usernameElement: row.getResultByName("username_element"), - passwordElement: row.getResultByName("password_element"), - timeCreated: chromeTimeToDate(row.getResultByName("date_created") + 0).getTime(), - timesUsed: row.getResultByName("times_used") + 0, - }; - - switch (row.getResultByName("scheme")) { - case AUTH_TYPE.SCHEME_HTML: - loginInfo.submitURL = NetUtil.newURI(row.getResultByName("action_url")).prePath; - break; - case AUTH_TYPE.SCHEME_BASIC: - case AUTH_TYPE.SCHEME_DIGEST: - // signon_realm format is URIrealm, so we need remove URI - loginInfo.httpRealm = row.getResultByName("signon_realm") - .substring(loginInfo.hostName.length + 1); - break; - default: - throw new Error("Login data scheme type not supported: " + - row.getResultByName("scheme")); - } - - return loginInfo; - }, - - handleResult(aResults) { - for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) { - try { - let loginInfo = this._rowToLoginInfo(row); - let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo); - - login.init(loginInfo.hostName, loginInfo.submitURL, loginInfo.httpRealm, - loginInfo.username, loginInfo.password, loginInfo.usernameElement, - loginInfo.passwordElement); - login.QueryInterface(Ci.nsILoginMetaInfo); - login.timeCreated = loginInfo.timeCreated; - login.timeLastUsed = loginInfo.timeCreated; - login.timePasswordChanged = loginInfo.timeCreated; - login.timesUsed = loginInfo.timesUsed; - - // Add the login only if there's not an existing entry - let logins = Services.logins.findLogins({}, login.hostname, - login.formSubmitURL, - login.httpRealm); - - // Bug 1187190: Password changes should be propagated depending on timestamps. - if (!logins.some(l => login.matches(l, true))) { - Services.logins.addLogin(login); - } - } catch (e) { - Cu.reportError(e); - } - } - }, - - handleError(aError) { - Cu.reportError("Async statement execution returned with '" + - aError.result + "', '" + aError.message + "'"); - }, - - handleCompletion(aReason) { - dbConn.asyncClose(); - aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED); - crypto.finalize(); - }, - }); - stmt.finalize(); - } - }; -} - -ChromeProfileMigrator.prototype.classDescription = "Chrome Profile Migrator"; -ChromeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=chrome"; -ChromeProfileMigrator.prototype.classID = Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]); diff --git a/application/palemoon/components/migration/FirefoxProfileMigrator.js b/application/palemoon/components/migration/FirefoxProfileMigrator.js deleted file mode 100644 index ab4ae55fb..000000000 --- a/application/palemoon/components/migration/FirefoxProfileMigrator.js +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -/* - * Migrates from a Pale Moon profile in a lossy manner in order to clean up a - * user's profile. Data is only migrated where the benefits outweigh the - * potential problems caused by importing undesired/invalid configurations - * from the source profile. - */ - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", - "resource://gre/modules/PlacesBackups.jsm"); - -function FirefoxProfileMigrator() { } - -FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype); - -FirefoxProfileMigrator.prototype._getAllProfiles = function () { - let allProfiles = new Map(); - let profiles = - Components.classes["@mozilla.org/toolkit/profile-service;1"] - .getService(Components.interfaces.nsIToolkitProfileService) - .profiles; - while (profiles.hasMoreElements()) { - let profile = profiles.getNext().QueryInterface(Components.interfaces.nsIToolkitProfile); - let rootDir = profile.rootDir; - - if (rootDir.exists() && rootDir.isReadable() && - !rootDir.equals(MigrationUtils.profileStartup.directory)) { - allProfiles.set(profile.name, rootDir); - } - } - return allProfiles; -}; - -function sorter(a, b) { - return a.id.toLocaleLowerCase().localeCompare(b.id.toLocaleLowerCase()); -} - -Object.defineProperty(FirefoxProfileMigrator.prototype, "sourceProfiles", { - get: function() { - return [{id: x, name: x} for (x of this._getAllProfiles().keys())].sort(sorter); - } -}); - -FirefoxProfileMigrator.prototype.getResources = function(aProfile) { - let sourceProfileDir = aProfile ? this._getAllProfiles().get(aProfile.id) : - Components.classes["@mozilla.org/toolkit/profile-service;1"] - .getService(Components.interfaces.nsIToolkitProfileService) - .selectedProfile.rootDir; - if (!sourceProfileDir || !sourceProfileDir.exists() || - !sourceProfileDir.isReadable()) - return null; - - // Being a startup-only migrator, we can rely on - // MigrationUtils.profileStartup being set. - let currentProfileDir = MigrationUtils.profileStartup.directory; - - // Surely data cannot be imported from the current profile. - if (sourceProfileDir.equals(currentProfileDir)) - return null; - - let getFileResource = function(aMigrationType, aFileNames) { - let files = []; - for (let fileName of aFileNames) { - let file = sourceProfileDir.clone(); - file.append(fileName); - - if (file.exists()) { - files.push(file); - } - } - if (!files.length) { - return null; - } - return { - type: aMigrationType, - migrate: function(aCallback) { - for (let file of files) { - file.copyTo(currentProfileDir, ""); - } - aCallback(true); - } - }; - }; - - let types = MigrationUtils.resourceTypes; - let places = getFileResource(types.HISTORY, ["places.sqlite", "places.sqlite-wal"]); - let cookies = getFileResource(types.COOKIES, ["cookies.sqlite", "cookies.sqlite-wal"]); - let passwords = getFileResource(types.PASSWORDS, - ["signons.sqlite", "logins.json", "key3.db"]); - let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]); - let bookmarksBackups = getFileResource(types.OTHERDATA, - [PlacesBackups.profileRelativeFolderPath]); - let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]); - - return [r for each (r in [places, cookies, passwords, formData, - dictionary, bookmarksBackups]) if (r)]; -} - -Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", { - get: function() true -}); - - -FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator"; -FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox"; -FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]); diff --git a/application/palemoon/components/migration/IEProfileMigrator.js b/application/palemoon/components/migration/IEProfileMigrator.js deleted file mode 100644 index a46deae68..000000000 --- a/application/palemoon/components/migration/IEProfileMigrator.js +++ /dev/null @@ -1,521 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const kMainKey = "Software\\Microsoft\\Internet Explorer\\Main"; -const kRegMultiSz = 7; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "ctypes", - "resource://gre/modules/ctypes.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry", - "resource://gre/modules/WindowsRegistry.jsm"); - -Cu.importGlobalProperties(["File"]); - -//////////////////////////////////////////////////////////////////////////////// -//// Helpers. - -let CtypesHelpers = { - _structs: {}, - _functions: {}, - _libs: {}, - - /** - * Must be invoked once before first use of any of the provided helpers. - */ - initialize: function CH_initialize() { - const WORD = ctypes.uint16_t; - const DWORD = ctypes.uint32_t; - const BOOL = ctypes.int; - - this._structs.SYSTEMTIME = new ctypes.StructType('SYSTEMTIME', [ - {wYear: WORD}, - {wMonth: WORD}, - {wDayOfWeek: WORD}, - {wDay: WORD}, - {wHour: WORD}, - {wMinute: WORD}, - {wSecond: WORD}, - {wMilliseconds: WORD} - ]); - - this._structs.FILETIME = new ctypes.StructType('FILETIME', [ - {dwLowDateTime: DWORD}, - {dwHighDateTime: DWORD} - ]); - - try { - this._libs.kernel32 = ctypes.open("Kernel32"); - this._functions.FileTimeToSystemTime = - this._libs.kernel32.declare("FileTimeToSystemTime", - ctypes.default_abi, - BOOL, - this._structs.FILETIME.ptr, - this._structs.SYSTEMTIME.ptr); - } catch (ex) { - this.finalize(); - } - }, - - /** - * Must be invoked once after last use of any of the provided helpers. - */ - finalize: function CH_finalize() { - this._structs = {}; - this._functions = {}; - for each (let lib in this._libs) { - try { - lib.close(); - } catch (ex) {} - } - this._libs = {}; - }, - - /** - * Converts a FILETIME struct (2 DWORDS), to a SYSTEMTIME struct. - * - * @param aTimeHi - * Least significant DWORD. - * @param aTimeLo - * Most significant DWORD. - * @return a Date object representing the converted datetime. - */ - fileTimeToDate: function CH_fileTimeToDate(aTimeHi, aTimeLo) { - let fileTime = this._structs.FILETIME(); - fileTime.dwLowDateTime = aTimeLo; - fileTime.dwHighDateTime = aTimeHi; - let systemTime = this._structs.SYSTEMTIME(); - let result = this._functions.FileTimeToSystemTime(fileTime.address(), - systemTime.address()); - if (result == 0) - throw new Error(ctypes.winLastError); - - return new Date(systemTime.wYear, - systemTime.wMonth - 1, - systemTime.wDay, - systemTime.wHour, - systemTime.wMinute, - systemTime.wSecond, - systemTime.wMilliseconds); - } -}; - -/** - * Checks whether an host is an IP (v4 or v6) address. - * - * @param aHost - * The host to check. - * @return whether aHost is an IP address. - */ -function hostIsIPAddress(aHost) { - try { - Services.eTLD.getBaseDomainFromHost(aHost); - } catch (e if e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS) { - return true; - } catch (e) {} - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -//// Resources - -function Bookmarks() { -} - -Bookmarks.prototype = { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - get exists() !!this._favoritesFolder, - - __favoritesFolder: null, - get _favoritesFolder() { - if (!this.__favoritesFolder) { - let favoritesFolder = Services.dirsvc.get("Favs", Ci.nsIFile); - if (favoritesFolder.exists() && favoritesFolder.isReadable()) - this.__favoritesFolder = favoritesFolder; - } - return this.__favoritesFolder; - }, - - __toolbarFolderName: null, - get _toolbarFolderName() { - if (!this.__toolbarFolderName) { - // Retrieve the name of IE's favorites subfolder that holds the bookmarks - // in the toolbar. This was previously stored in the registry and changed - // in IE7 to always be called "Links". - let folderName = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\Toolbar", - "LinksFolderName"); - this.__toolbarFolderName = folderName || "Links"; - } - return this.__toolbarFolderName; - }, - - migrate: function B_migrate(aCallback) { - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: (function migrateBatched() { - // Import to the bookmarks menu. - let destFolderId = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - - this._migrateFolder(this._favoritesFolder, destFolderId); - - aCallback(true); - }).bind(this) - }, null); - }, - - _migrateFolder: function B__migrateFolder(aSourceFolder, aDestFolderId) { - // TODO (bug 741993): the favorites order is stored in the Registry, at - // HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites - // Until we support it, bookmarks are imported in alphabetical order. - let entries = aSourceFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - - // Make sure that entry.path == entry.target to not follow .lnk folder - // shortcuts which could lead to infinite cycles. - if (entry.isDirectory() && entry.path == entry.target) { - let destFolderId; - if (entry.leafName == this._toolbarFolderName && - entry.parent.equals(this._favoritesFolder)) { - // Import to the bookmarks toolbar. - destFolderId = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - } - else { - // Import to a new folder. - destFolderId = - PlacesUtils.bookmarks.createFolder(aDestFolderId, entry.leafName, - PlacesUtils.bookmarks.DEFAULT_INDEX); - } - - if (entry.isReadable()) { - // Recursively import the folder. - this._migrateFolder(entry, destFolderId); - } - } - else { - // Strip the .url extension, to both check this is a valid link file, - // and get the associated title. - let matches = entry.leafName.match(/(.+)\.url$/i); - if (matches) { - let fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"]. - getService(Ci.nsIFileProtocolHandler); - let uri = fileHandler.readURLFile(entry); - let title = matches[1]; - - PlacesUtils.bookmarks.insertBookmark(aDestFolderId, - uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, - title); - } - } - } - } -}; - -function History() { -} - -History.prototype = { - type: MigrationUtils.resourceTypes.HISTORY, - - get exists() true, - - __typedURLs: null, - get _typedURLs() { - if (!this.__typedURLs) { - // The list of typed URLs is a sort of annotation stored in the registry. - // Currently, IE stores 25 entries and this value is not configurable, - // but we just keep reading up to the first non-existing entry to support - // possible future bumps of this limit. - this.__typedURLs = {}; - let registry = Cc["@mozilla.org/windows-registry-key;1"]. - createInstance(Ci.nsIWindowsRegKey); - try { - registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\TypedURLs", - Ci.nsIWindowsRegKey.ACCESS_READ); - for (let entry = 1; registry.hasValue("url" + entry); entry++) { - let url = registry.readStringValue("url" + entry); - this.__typedURLs[url] = true; - } - } catch (ex) { - } finally { - registry.close(); - } - } - return this.__typedURLs; - }, - - migrate: function H_migrate(aCallback) { - let places = []; - let historyEnumerator = Cc["@mozilla.org/profile/migrator/iehistoryenumerator;1"]. - createInstance(Ci.nsISimpleEnumerator); - while (historyEnumerator.hasMoreElements()) { - let entry = historyEnumerator.getNext().QueryInterface(Ci.nsIPropertyBag2); - let uri = entry.get("uri").QueryInterface(Ci.nsIURI); - // MSIE stores some types of URLs in its history that we don't handle, - // like HTMLHelp and others. Since we don't properly map handling for - // all of them we just avoid importing them. - if (["http", "https", "ftp", "file"].indexOf(uri.scheme) == -1) { - continue; - } - - let title = entry.get("title"); - // Embed visits have no title and don't need to be imported. - if (title.length == 0) { - continue; - } - - // The typed urls are already fixed-up, so we can use them for comparison. - let transitionType = this._typedURLs[uri.spec] ? - Ci.nsINavHistoryService.TRANSITION_TYPED : - Ci.nsINavHistoryService.TRANSITION_LINK; - let lastVisitTime = entry.get("time"); - - places.push( - { uri: uri, - title: title, - visits: [{ transitionType: transitionType, - visitDate: lastVisitTime }] - } - ); - } - - // Check whether there is any history to import. - if (places.length == 0) { - aCallback(true); - return; - } - - PlacesUtils.asyncHistory.updatePlaces(places, { - _success: false, - handleResult: function() { - // Importing any entry is considered a successful import. - this._success = true; - }, - handleError: function() {}, - handleCompletion: function() { - aCallback(this._success); - } - }); - } -}; - -function Cookies() { -} - -Cookies.prototype = { - type: MigrationUtils.resourceTypes.COOKIES, - - get exists() !!this._cookiesFolder, - - __cookiesFolder: null, - get _cookiesFolder() { - // Cookies are stored in txt files, in a Cookies folder whose path varies - // across the different OS versions. CookD takes care of most of these - // cases, though, in Windows Vista/7, UAC makes a difference. - // If UAC is enabled, the most common destination is CookD/Low. Though, - // if the user runs the application in administrator mode or disables UAC, - // cookies are stored in the original CookD destination. Cause running the - // browser in administrator mode is unsafe and discouraged, we just care - // about the UAC state. - if (!this.__cookiesFolder) { - let cookiesFolder = Services.dirsvc.get("CookD", Ci.nsIFile); - if (cookiesFolder.exists() && cookiesFolder.isReadable()) { - // Check if UAC is enabled. - if (Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).userCanElevate) { - cookiesFolder.append("Low"); - } - this.__cookiesFolder = cookiesFolder; - } - } - return this.__cookiesFolder; - }, - - migrate: function C_migrate(aCallback) { - CtypesHelpers.initialize(); - - let cookiesGenerator = (function genCookie() { - let success = false; - let entries = this._cookiesFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - // Skip eventual bogus entries. - if (!entry.isFile() || !/\.txt$/.test(entry.leafName)) - continue; - - this._readCookieFile(entry, function(aSuccess) { - // Importing even a single cookie file is considered a success. - if (aSuccess) - success = true; - try { - cookiesGenerator.next(); - } catch (ex) {} - }); - - yield; - } - - CtypesHelpers.finalize(); - - aCallback(success); - }).apply(this); - cookiesGenerator.next(); - }, - - _readCookieFile: function C__readCookieFile(aFile, aCallback) { - let fileReader = Cc["@mozilla.org/files/filereader;1"]. - createInstance(Ci.nsIDOMFileReader); - fileReader.addEventListener("loadend", (function onLoadEnd() { - fileReader.removeEventListener("loadend", onLoadEnd, false); - - if (fileReader.readyState != fileReader.DONE) { - Cu.reportError("Could not read cookie contents: " + fileReader.error); - aCallback(false); - return; - } - - let success = true; - try { - this._parseCookieBuffer(fileReader.result); - } catch (ex) { - Components.utils.reportError("Unable to migrate cookie: " + ex); - success = false; - } finally { - aCallback(success); - } - }).bind(this), false); - fileReader.readAsText(new File(aFile)); - }, - - /** - * Parses a cookie file buffer and returns an array of the contained cookies. - * - * The cookie file format is a newline-separated-values with a "*" used as - * delimeter between multiple records. - * Each cookie has the following fields: - * - name - * - value - * - host/path - * - flags - * - Expiration time most significant integer - * - Expiration time least significant integer - * - Creation time most significant integer - * - Creation time least significant integer - * - Record delimiter "*" - * - * @note All the times are in FILETIME format. - */ - _parseCookieBuffer: function C__parseCookieBuffer(aTextBuffer) { - // Note the last record is an empty string. - let records = [r for each (r in aTextBuffer.split("*\n")) if (r)]; - for (let record of records) { - let [name, value, hostpath, flags, - expireTimeLo, expireTimeHi] = record.split("\n"); - - // IE stores deleted cookies with a zero-length value, skip them. - if (value.length == 0) - continue; - - let hostLen = hostpath.indexOf("/"); - let host = hostpath.substr(0, hostLen); - let path = hostpath.substr(hostLen); - - // For a non-null domain, assume it's what Mozilla considers - // a domain cookie. See bug 222343. - if (host.length > 0) { - // Fist delete any possible extant matching host cookie. - Services.cookies.remove(host, name, path, false); - // Now make it a domain cookie. - if (host[0] != "." && !hostIsIPAddress(host)) - host = "." + host; - } - - let expireTime = CtypesHelpers.fileTimeToDate(Number(expireTimeHi), - Number(expireTimeLo)); - Services.cookies.add(host, - path, - name, - value, - Number(flags) & 0x1, // secure - false, // httpOnly - false, // session - expireTime); - } - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -//// Migrator - -function IEProfileMigrator() -{ -} - -IEProfileMigrator.prototype = Object.create(MigratorPrototype); - -IEProfileMigrator.prototype.getResources = function IE_getResources() { - let resources = [ - new Bookmarks() - , new History() - , new Cookies() - ]; - return [r for each (r in resources) if (r.exists)]; -}; - -Object.defineProperty(IEProfileMigrator.prototype, "sourceHomePageURL", { - get: function IE_get_sourceHomePageURL() { - let defaultStartPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE, - kMainKey, "Default_Page_URL"); - let startPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Start Page"); - // If the user didn't customize the Start Page, he is still on the default - // page, that may be considered the equivalent of our about:home. There's - // no reason to retain it, since it is heavily targeted to IE. - let homepage = startPage != defaultStartPage ? startPage : ""; - - // IE7+ supports secondary home pages located in a REG_MULTI_SZ key. These - // are in addition to the Start Page, and no empty entries are possible, - // thus a Start Page is always defined if any of these exists, though it - // may be the default one. - let secondaryPages = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Secondary Start Pages"); - if (secondaryPages) { - if (homepage) - secondaryPages.unshift(homepage); - homepage = secondaryPages.join("|"); - } - - return homepage; - } -}); - -IEProfileMigrator.prototype.classDescription = "IE Profile Migrator"; -IEProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=ie"; -IEProfileMigrator.prototype.classID = Components.ID("{3d2532e3-4932-4774-b7ba-968f5899d3a4}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IEProfileMigrator]); diff --git a/application/palemoon/components/migration/MigrationUtils.jsm b/application/palemoon/components/migration/MigrationUtils.jsm deleted file mode 100644 index fcd73a798..000000000 --- a/application/palemoon/components/migration/MigrationUtils.jsm +++ /dev/null @@ -1,644 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["MigrationUtils", "MigratorPrototype"]; - -const Cu = Components.utils; -const Ci = Components.interfaces; -const Cc = Components.classes; - -const TOPIC_WILL_IMPORT_BOOKMARKS = "initial-migration-will-import-default-bookmarks"; -const TOPIC_DID_IMPORT_BOOKMARKS = "initial-migration-did-import-default-bookmarks"; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Dict", - "resource://gre/modules/Dict.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils", - "resource://gre/modules/BookmarkHTMLUtils.jsm"); - -let gMigrators = null; -let gProfileStartup = null; -let gMigrationBundle = null; - -function getMigrationBundle() { - if (!gMigrationBundle) { - gMigrationBundle = Services.strings.createBundle( - "chrome://browser/locale/migration/migration.properties"); - } - return gMigrationBundle; -} - -/** - * Figure out what is the default browser, and if there is a migrator - * for it, return that migrator's internal name. - * For the time being, the "internal name" of a migraotr is its contract-id - * trailer (e.g. ie for @mozilla.org/profile/migrator;1?app=browser&type=ie), - * but it will soon be exposed properly. - */ -function getMigratorKeyForDefaultBrowser() { - const APP_DESC_TO_KEY = { - "Internet Explorer": "ie", - "Safari": "safari", - "Pale Moon web browser": "firefox", - "Google Chrome": "chrome", // Windows, Linux - "Chrome": "chrome", // OS X - }; - - let browserDesc = ""; - try { - let browserDesc = - Cc["@mozilla.org/uriloader/external-protocol-service;1"]. - getService(Ci.nsIExternalProtocolService). - getApplicationDescription("http"); - return APP_DESC_TO_KEY[browserDesc] || ""; - } - catch(ex) { - Cu.reportError("Could not detect default browser: " + ex); - } - return ""; -} - -/** - * Shared prototype for migrators, implementing nsIBrowserProfileMigrator. - * - * To implement a migrator: - * 1. Import this module. - * 2. Create the prototype for the migrator, extending MigratorPrototype. - * Namely: MosaicMigrator.prototype = Object.create(MigratorPrototype); - * 3. Set classDescription, contractID and classID for your migrator, and set - * NSGetFactory appropriately. - * 4. If the migrator supports multiple profiles, override the sourceProfiles - * Here we default for single-profile migrator. - * 5. Implement getResources(aProfile) (see below). - * 6. If the migrator supports reading the home page of the source browser, - * override |sourceHomePageURL| getter. - * 7. For startup-only migrators, override |startupOnlyMigrator|. - */ -this.MigratorPrototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserProfileMigrator]), - - /** - * OVERRIDE IF AND ONLY IF the source supports multiple profiles. - * - * Returns array of profile objects from which data may be imported. The object - * should have the following keys: - * id - a unique string identifier for the profile - * name - a pretty name to display to the user in the UI - * - * Only profiles from which data can be imported should be listed. Otherwise - * the behavior of the migration wizard isn't well-defined. - * - * For a single-profile source (e.g. safari, ie), this returns null, - * and not an empty array. That is the default implementation. - */ - get sourceProfiles() null, - - /** - * MUST BE OVERRIDDEN. - * - * Returns an array of "migration resources" objects for the given profile, - * or for the "default" profile, if the migrator does not support multiple - * profiles. - * - * Each migration resource should provide: - * - a |type| getter, retunring any of the migration types (see - * nsIBrowserProfileMigrator). - * - * - a |migrate| method, taking a single argument, aCallback(bool success), - * for migrating the data for this resource. It may do its job - * synchronously or asynchronously. Either way, it must call - * aCallback(bool aSuccess) when it's done. In the case of an exception - * thrown from |migrate|, it's taken as if aCallback(false) is called. - * - * Note: In the case of a simple asynchronous implementation, you may find - * MigrationUtils.wrapMigrateFunction handy for handling aCallback easily. - * - * For each migration type listed in nsIBrowserProfileMigrator, multiple - * migration resources may be provided. This practice is useful when the - * data for a certain migration type is independently stored in few - * locations. For example, the mac version of Safari stores its "reading list" - * bookmarks in a separate property list. - * - * Note that the importation of a particular migration type is reported as - * successful if _any_ of its resources succeeded to import (that is, called, - * |aCallback(true)|). However, completion-status for a particular migration - * type is reported to the UI only once all of its migrators have called - * aCallback. - * - * @note The returned array should only include resources from which data - * can be imported. So, for example, before adding a resource for the - * BOOKMARKS migration type, you should check if you should check that the - * bookmarks file exists. - * - * @param aProfile - * The profile from which data may be imported, or an empty string - * in the case of a single-profile migrator. - * In the case of multiple-profiles migrator, it is guaranteed that - * aProfile is a value returned by the sourceProfiles getter (see - * above). - */ - getResources: function MP_getResources(aProfile) { - throw new Error("getResources must be overridden"); - }, - - /** - * OVERRIDE IF AND ONLY IF the migrator is a startup-only migrator (For now, - * that is just the Firefox migrator, see bug 737381). Default: false. - * - * Startup-only migrators are different in two ways: - * - they may only be used during startup. - * - the user-profile is half baked during migration. The folder exists, - * but it's only accessible through MigrationUtils.profileStartup. - * The migrator can call MigrationUtils.profileStartup.doStartup - * at any point in order to initialize the profile. - */ - get startupOnlyMigrator() false, - - /** - * OVERRIDE IF AND ONLY IF your migrator supports importing the homepage. - * @see nsIBrowserProfileMigrator - */ - get sourceHomePageURL() "", - - /** - * DO NOT OVERRIDE - After deCOMing migration, the UI will just call - * getResources. - * - * @see nsIBrowserProfileMigrator - */ - getMigrateData: function MP_getMigrateData(aProfile) { - let types = [r.type for each (r in this._getMaybeCachedResources(aProfile))]; - return types.reduce(function(a, b) a |= b, 0); - }, - - /** - * DO NOT OVERRIDE - After deCOMing migration, the UI will just call - * migrate for each resource. - * - * @see nsIBrowserProfileMigrator - */ - migrate: function MP_migrate(aItems, aStartup, aProfile) { - let resources = this._getMaybeCachedResources(aProfile); - if (resources.length == 0) - throw new Error("migrate called for a non-existent source"); - - if (aItems != Ci.nsIBrowserProfileMigrator.ALL) - resources = [r for each (r in resources) if (aItems & r.type)]; - - // Called either directly or through the bookmarks import callback. - function doMigrate() { - // TODO: use Map (for the items) and Set (for the resources) - // once they are iterable. - let resourcesGroupedByItems = new Dict(); - resources.forEach(function(resource) { - if (resourcesGroupedByItems.has(resource.type)) - resourcesGroupedByItems.get(resource.type).push(resource); - else - resourcesGroupedByItems.set(resource.type, [resource]); - }); - - if (resourcesGroupedByItems.count == 0) - throw new Error("No items to import"); - - let notify = function(aMsg, aItemType) { - Services.obs.notifyObservers(null, aMsg, aItemType); - } - - notify("Migration:Started"); - resourcesGroupedByItems.listkeys().forEach(function(migrationType) { - let migrationTypeA = migrationType; - let itemResources = resourcesGroupedByItems.get(migrationType); - notify("Migration:ItemBeforeMigrate", migrationType); - - let itemSuccess = false; - itemResources.forEach(function(resource) { - let resourceDone = function(aSuccess) { - let resourceIndex = itemResources.indexOf(resource); - if (resourceIndex != -1) { - itemResources.splice(resourceIndex, 1); - itemSuccess |= aSuccess; - if (itemResources.length == 0) { - resourcesGroupedByItems.del(migrationType); - notify(itemSuccess ? - "Migration:ItemAfterMigrate" : "Migration:ItemError", - migrationType); - if (resourcesGroupedByItems.count == 0) - notify("Migration:Ended"); - } - } - }; - - Services.tm.mainThread.dispatch(function() { - // If migrate throws, an error occurred, and the callback - // (itemMayBeDone) might haven't been called. - try { - resource.migrate(resourceDone); - } - catch(ex) { - Cu.reportError(ex); - resourceDone(false); - } - }, Ci.nsIThread.DISPATCH_NORMAL); - }); - }); - } - - if (MigrationUtils.isStartupMigration && !this.startupOnlyMigrator) { - MigrationUtils.profileStartup.doStartup(); - - // If we're about to migrate bookmarks, first import the default bookmarks. - // Note We do not need to do so for the Firefox migrator - // (=startupOnlyMigrator), as it just copies over the places database - // from another profile. - const BOOKMARKS = MigrationUtils.resourceTypes.BOOKMARKS; - let migratingBookmarks = resources.some(function(r) r.type == BOOKMARKS); - if (migratingBookmarks) { - let browserGlue = Cc["@mozilla.org/browser/browserglue;1"]. - getService(Ci.nsIObserver); - browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, ""); - - // Note doMigrate doesn't care about the success of the import. - let onImportComplete = function() { - browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, ""); - doMigrate(); - }; - BookmarkHTMLUtils.importFromURL( - "resource:///defaults/profile/bookmarks.html", true).then( - onImportComplete, onImportComplete); - return; - } - } - doMigrate(); - }, - - /** - * DO NOT OVERRIDE - After deCOMing migration, this code - * won't be part of the migrator itself. - * - * @see nsIBrowserProfileMigrator - */ - get sourceExists() { - if (this.startupOnlyMigrator && !MigrationUtils.isStartupMigration) - return false; - - // For a single-profile source, check if any data is available. - // For multiple-profiles source, make sure that at least one - // profile is available. - let exists = false; - try { - let profiles = this.sourceProfiles; - if (!profiles) { - let resources = this._getMaybeCachedResources(""); - if (resources && resources.length > 0) - exists = true; - } - else { - exists = profiles.length > 0; - } - } - catch(ex) { - Cu.reportError(ex); - } - return exists; - }, - - /*** PRIVATE STUFF - DO NOT OVERRIDE ***/ - _getMaybeCachedResources: function PMB__getMaybeCachedResources(aProfile) { - let profileKey = aProfile ? aProfile.id : ""; - if (this._resourcesByProfile) { - if (profileKey in this._resourcesByProfile) - return this._resourcesByProfile[profileKey]; - } - else { - this._resourcesByProfile = { }; - } - return this._resourcesByProfile[profileKey] = this.getResources(aProfile); - } -}; - -this.MigrationUtils = Object.freeze({ - resourceTypes: { - SETTINGS: Ci.nsIBrowserProfileMigrator.SETTINGS, - COOKIES: Ci.nsIBrowserProfileMigrator.COOKIES, - HISTORY: Ci.nsIBrowserProfileMigrator.HISTORY, - FORMDATA: Ci.nsIBrowserProfileMigrator.FORMDATA, - PASSWORDS: Ci.nsIBrowserProfileMigrator.PASSWORDS, - BOOKMARKS: Ci.nsIBrowserProfileMigrator.BOOKMARKS, - OTHERDATA: Ci.nsIBrowserProfileMigrator.OTHERDATA - }, - - /** - * Helper for implementing simple asynchronous cases of migration resources' - * |migrate(aCallback)| (see MigratorPrototype). If your |migrate| method - * just waits for some file to be read, for example, and then migrates - * everything right away, you can wrap the async-function with this helper - * and not worry about notifying the callback. - * - * For example, instead of writing: - * setTimeout(function() { - * try { - * .... - * aCallback(true); - * } - * catch() { - * aCallback(false); - * } - * }, 0); - * - * You may write: - * setTimeout(MigrationUtils.wrapMigrateFunction(function() { - * if (importingFromMosaic) - * throw Cr.NS_ERROR_UNEXPECTED; - * }, aCallback), 0); - * - * ... and aCallback will be called with aSuccess=false when importing - * from Mosaic, or with aSuccess=true otherwise. - * - * @param aFunction - * the function that will be called sometime later. If aFunction - * throws when it's called, aCallback(false) is called, otherwise - * aCallback(true) is called. - * @param aCallback - * the callback function passed to |migrate|. - * @return the wrapped function. - */ - wrapMigrateFunction: function MU_wrapMigrateFunction(aFunction, aCallback) { - return function() { - let success = false; - try { - aFunction.apply(null, arguments); - success = true; - } - catch(ex) { - Cu.reportError(ex); - } - // Do not change this to call aCallback directly in try try & catch - // blocks, because if aCallback throws, we may end up calling aCallback - // twice. - aCallback(success); - } - }, - - /** - * Gets a string from the migration bundle. Shorthand for - * nsIStringBundle.GetStringFromName, if aReplacements isn't passed, or for - * nsIStringBundle.formatStringFromName if it is. - * - * This method also takes care of "bumped" keys (See bug 737381 comment 8 for - * details). - * - * @param aKey - * The key of the string to retrieve. - * @param aReplacemts - * [optioanl] Array of replacements to run on the retrieved string. - * @return the retrieved string. - * - * @see nsIStringBundle - */ - getLocalizedString: function MU_getLocalizedString(aKey, aReplacements) { - const OVERRIDES = { - "4_firefox": "4_firefox_history_and_bookmarks", - "64_firefox": "64_firefox_other" - }; - aKey = OVERRIDES[aKey] || aKey; - - if (aReplacements === undefined) - return getMigrationBundle().GetStringFromName(aKey); - return getMigrationBundle().formatStringFromName( - aKey, aReplacements, aReplacements.length); - }, - - /** - * Helper for creating a folder for imported bookmarks from a particular - * migration source. The folder is created at the end of the given folder. - * - * @param aSourceNameStr - * the source name (first letter capitalized). This is used - * for reading the localized source name from the migration - * bundle (e.g. if aSourceNameStr is Mosaic, this will try to read - * sourceNameMosaic from the migration bundle). - * @param aParentId - * the item-id of the folder in which the new folder should be - * created. - * @return the item-id of the new folder. - */ - createImportedBookmarksFolder: - function MU_createImportedBookmarksFolder(aSourceNameStr, aParentId) { - let source = this.getLocalizedString("sourceName" + aSourceNameStr); - let label = this.getLocalizedString("importedBookmarksFolder", [source]); - return PlacesUtils.bookmarks.createFolder( - aParentId, label, PlacesUtils.bookmarks.DEFAULT_INDEX); - }, - - get _migrators() gMigrators ? gMigrators : gMigrators = new Dict(), - - /* - * Returns the migrator for the given source, if any data is available - * for this source, or null otherwise. - * - * @param aKey internal name of the migration source. - * Supported values: ie (windows), - * safari (mac/windows), - * chrome (mac/windows/linux), - * firefox. - * - * If null is returned, either no data can be imported - * for the given migrator, or aMigratorKey is invalid (e.g. ie on mac, - * or mosaic everywhere). This method should be used rather than direct - * getService for future compatibility (see bug 718280). - * - * @return profile migrator implementing nsIBrowserProfileMigrator, if it can - * import any data, null otherwise. - */ - getMigrator: function MU_getMigrator(aKey) { - let migrator = null; - if (this._migrators.has(aKey)) { - migrator = this._migrators.get(aKey); - } - else { - try { - migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=" + - aKey].createInstance(Ci.nsIBrowserProfileMigrator); - } - catch(ex) { } - this._migrators.set(aKey, migrator); - } - - return migrator && migrator.sourceExists ? migrator : null; - }, - - // Iterates the available migrators, in the most suitable - // order for the running platform. - get migrators() { - let migratorKeysOrdered = [ -#ifdef XP_WIN - "firefox", "ie", "chrome", "safari" -#elifdef XP_MACOSX - "firefox", "safari", "chrome" -#elifdef XP_UNIX - "firefox", "chrome" -#endif - ]; - - // If a supported default browser is found check it first - // so that the wizard defaults to import from that browser. - let defaultBrowserKey = getMigratorKeyForDefaultBrowser(); - if (defaultBrowserKey) - migratorKeysOrdered.sort(function (a, b) b == defaultBrowserKey ? 1 : 0); - - for (let migratorKey of migratorKeysOrdered) { - let migrator = this.getMigrator(migratorKey); - if (migrator) - yield migrator; - } - }, - - // Whether or not we're in the process of startup migration - get isStartupMigration() gProfileStartup != null, - - /** - * In the case of startup migration, this is set to the nsIProfileStartup - * instance passed to ProfileMigrator's migrate. - * - * @see showMigrationWizard - */ - get profileStartup() gProfileStartup, - - /** - * Show the migration wizard. On mac, this may just focus the wizard if it's - * already running, in which case aOpener and aParams are ignored. - * - * @param [optional] aOpener - * the window that asks to open the wizard. - * @param [optional] aParams - * arguments for the migration wizard, in the form of an nsIArray. - * This is passed as-is for the params argument of - * nsIWindowWatcher.openWindow. - */ - showMigrationWizard: - function MU_showMigrationWizard(aOpener, aParams) { - let features = "chrome,dialog,modal,centerscreen,titlebar,resizable=no"; -#ifdef XP_MACOSX - if (!this.isStartupMigration) { - let win = Services.wm.getMostRecentWindow("Browser:MigrationWizard"); - if (win) { - win.focus(); - return; - } - // On mac, the migration wiazrd should only be modal in the case of - // startup-migration. - features = "centerscreen,chrome,resizable=no"; - } -#endif - - Services.ww.openWindow(aOpener, - "chrome://browser/content/migration/migration.xul", - "_blank", - features, - aParams); - }, - - /** - * Show the migration wizard for startup-migration. This should only be - * called by ProfileMigrator (see ProfileMigrator.js), which implements - * nsIProfileMigrator. - * - * @param aProfileStartup - * the nsIProfileStartup instance provided to ProfileMigrator.migrate. - * @param [optional] aMigratorKey - * If set, the migration wizard will import from the corresponding - * migrator, bypassing the source-selection page. Otherwise, the - * source-selection page will be displayed, either with the default - * browser selected, if it could be detected and if there is a - * migrator for it, or with the first option selected as a fallback - * (The first option is hardcoded to be the most common browser for - * the OS we run on. See migration.xul). - * @param [optional] aProfileToMigrate - * If set, the migration wizard will import from the profile indicated. - * - * @throws if aMigratorKey is invalid or if it points to a non-existent - * source. - */ - startupMigration: - function MU_startupMigrator(aProfileStartup, aMigratorKey, aProfileToMigrate) { - if (!aProfileStartup) { - throw new Error("a profile-startup instance is required for startup-migration"); - } - gProfileStartup = aProfileStartup; - - let skipSourcePage = false, migrator = null, migratorKey = ""; - if (aMigratorKey) { - migrator = this.getMigrator(aMigratorKey); - if (!migrator) { - // aMigratorKey must point to a valid source, so, if it doesn't - // cleanup and throw. - this.finishMigration(); - throw new Error("startMigration was asked to open auto-migrate from " + - "a non-existent source: " + aMigratorKey); - } - migratorKey = aMigratorKey; - skipSourcePage = true; - } - else { - let defaultBrowserKey = getMigratorKeyForDefaultBrowser(); - if (defaultBrowserKey) { - migrator = this.getMigrator(defaultBrowserKey); - if (migrator) - migratorKey = defaultBrowserKey; - } - } - - if (!migrator) { - // If there's no migrator set so far, ensure that there is at least one - // migrator available before opening the wizard. - try { - this.migrators.next(); - } - catch(ex) { - this.finishMigration(); - if (!(ex instanceof StopIteration)) - throw ex; - return; - } - } - - let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); - let keyCSTR = Cc["@mozilla.org/supports-cstring;1"]. - createInstance(Ci.nsISupportsCString); - keyCSTR.data = migratorKey; - let skipImportSourcePageBool = Cc["@mozilla.org/supports-PRBool;1"]. - createInstance(Ci.nsISupportsPRBool); - skipImportSourcePageBool.data = skipSourcePage; - let profileToMigrate = null; - if (aProfileToMigrate) { - profileToMigrate = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - profileToMigrate.data = aProfileToMigrate; - } - params.appendElement(keyCSTR, false); - params.appendElement(migrator, false); - params.appendElement(aProfileStartup, false); - params.appendElement(skipImportSourcePageBool, false); - params.appendElement(profileToMigrate, false); - - this.showMigrationWizard(null, params); - }, - - /** - * Cleans up references to migrators and nsIProfileInstance instances. - */ - finishMigration: function MU_finishMigration() { - gMigrators = null; - gProfileStartup = null; - gMigrationBundle = null; - } -}); diff --git a/application/palemoon/components/migration/ProfileMigrator.js b/application/palemoon/components/migration/ProfileMigrator.js deleted file mode 100644 index f67823bae..000000000 --- a/application/palemoon/components/migration/ProfileMigrator.js +++ /dev/null @@ -1,21 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); - -function ProfileMigrator() { -} - -ProfileMigrator.prototype = { - migrate: MigrationUtils.startupMigration.bind(MigrationUtils), - QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProfileMigrator]), - classDescription: "Profile Migrator", - contractID: "@mozilla.org/toolkit/profile-migrator;1", - classID: Components.ID("6F8BB968-C14F-4D6F-9733-6C6737B35DCE") -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProfileMigrator]); diff --git a/application/palemoon/components/migration/SafariProfileMigrator.js b/application/palemoon/components/migration/SafariProfileMigrator.js deleted file mode 100644 index 70804793d..000000000 --- a/application/palemoon/components/migration/SafariProfileMigrator.js +++ /dev/null @@ -1,416 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -let Cc = Components.classes; -let Ci = Components.interfaces; -let Cu = Components.utils; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PropertyListUtils", - "resource://gre/modules/PropertyListUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", - "resource://gre/modules/FormHistory.jsm"); - -function Bookmarks(aBookmarksFile) { - this._file = aBookmarksFile; -} -Bookmarks.prototype = { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - migrate: function B_migrate(aCallback) { - PropertyListUtils.read(this._file, - MigrationUtils.wrapMigrateFunction(function migrateBookmarks(aDict) { - if (!aDict) - throw new Error("Could not read Bookmarks.plist"); - - let children = aDict.get("Children");; - if (!children) - throw new Error("Invalid Bookmarks.plist format"); - - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: function() { - let collection = aDict.get("Title") == "com.apple.ReadingList" ? - this.READING_LIST_COLLECTION : this.ROOT_COLLECTION; - this._migrateCollection(children, collection); - }.bind(this) - }, null); - }.bind(this), aCallback)); - }, - - // Bookmarks collections in Safari. Constants for migrateCollection. - ROOT_COLLECTION: 0, - MENU_COLLECTION: 1, - TOOLBAR_COLLECTION: 2, - READING_LIST_COLLECTION: 3, - - /** - * Recursively migrate a Safari collection of bookmarks. - * - * @param aEntries - * the collection's children - * @param aCollection - * one of the values above. - */ - _migrateCollection: function B__migrateCollection(aEntries, aCollection) { - // A collection of bookmarks in Safari resembles places roots. In the - // property list files (Bookmarks.plist, ReadingList.plist) they are - // stored as regular bookmarks folders, and thus can only be distinguished - // from by their names and places in the hierarchy. - - let entriesFiltered = []; - if (aCollection == this.ROOT_COLLECTION) { - for (let entry of aEntries) { - let type = entry.get("WebBookmarkType"); - if (type == "WebBookmarkTypeList" && entry.has("Children")) { - let title = entry.get("Title"); - let children = entry.get("Children"); - if (title == "BookmarksBar") - this._migrateCollection(children, this.TOOLBAR_COLLECTION); - else if (title == "BookmarksMenu") - this._migrateCollection(children, this.MENU_COLLECTION); - else if (title == "com.apple.ReadingList") - this._migrateCollection(children, this.READING_LIST_COLLECTION); - else if (entry.get("ShouldOmitFromUI") !== true) - entriesFiltered.push(entry); - } - else if (type == "WebBookmarkTypeLeaf") { - entriesFiltered.push(entry); - } - } - } - else { - entriesFiltered = aEntries; - } - - if (entriesFiltered.length == 0) - return; - - let folder = -1; - switch (aCollection) { - case this.ROOT_COLLECTION: { - // In Safari, it is possible (though quite cumbersome) to move - // bookmarks to the bookmarks root, which is the parent folder of - // all bookmarks "collections". That is somewhat in parallel with - // both the places root and the unfiled-bookmarks root. - // Because the former is only an implementation detail in our UI, - // the unfiled root seems to be the best choice. - folder = PlacesUtils.unfiledBookmarksFolderId; - break; - } - case this.MENU_COLLECTION: { - folder = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - folder = MigrationUtils.createImportedBookmarksFolder("Safari", - folder); - } - break; - } - case this.TOOLBAR_COLLECTION: { - folder = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - folder = MigrationUtils.createImportedBookmarksFolder("Safari", - folder); - } - break; - } - case this.READING_LIST_COLLECTION: { - // Reading list items are imported as regular bookmarks. - // They are imported under their own folder, created either under the - // bookmarks menu (in the case of startup migration). - folder = PlacesUtils.bookmarks.createFolder( - PlacesUtils.bookmarksMenuFolderId, - MigrationUtils.getLocalizedString("importedSafariReadingList"), - PlacesUtils.bookmarks.DEFAULT_INDEX); - break; - } - default: - throw new Error("Unexpected value for aCollection!"); - } - - this._migrateEntries(entriesFiltered, folder); - }, - - // migrate the given array of safari bookmarks to the given places - // folder. - _migrateEntries: function B__migrateEntries(aEntries, aFolderId) { - for (let entry of aEntries) { - let type = entry.get("WebBookmarkType"); - if (type == "WebBookmarkTypeList" && entry.has("Children")) { - let title = entry.get("Title"); - let folderId = PlacesUtils.bookmarks.createFolder( - aFolderId, title, PlacesUtils.bookmarks.DEFAULT_INDEX); - - // Empty folders may not have a children array. - if (entry.has("Children")) - this._migrateEntries(entry.get("Children"), folderId, false); - } - else if (type == "WebBookmarkTypeLeaf" && entry.has("URLString")) { - let title, uri; - if (entry.has("URIDictionary")) - title = entry.get("URIDictionary").get("title"); - - try { - uri = NetUtil.newURI(entry.get("URLString")); - } - catch(ex) { - Cu.reportError("Invalid uri set for Safari bookmark: " + entry.get("URLString")); - } - if (uri) { - PlacesUtils.bookmarks.insertBookmark(aFolderId, uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, title); - } - } - } - } -}; - -function History(aHistoryFile) { - this._file = aHistoryFile; -} -History.prototype = { - type: MigrationUtils.resourceTypes.HISTORY, - - // Helper method for converting the visit date property to a PRTime value. - // The visit date is stored as a string, so it's not read as a Date - // object by PropertyListUtils. - _parseCocoaDate: function H___parseCocoaDate(aCocoaDateStr) { - let asDouble = parseFloat(aCocoaDateStr); - if (!isNaN(asDouble)) { - // reference date of NSDate. - let date = new Date("1 January 2001, GMT"); - date.setMilliseconds(asDouble * 1000); - return date * 1000; - } - return 0; - }, - - migrate: function H_migrate(aCallback) { - PropertyListUtils.read(this._file, function migrateHistory(aDict) { - try { - if (!aDict) - throw new Error("Could not read history property list"); - if (!aDict.has("WebHistoryDates")) - throw new Error("Unexpected history-property list format"); - - // Safari's History file contains only top-level urls. It does not - // distinguish between typed urls and linked urls. - let transType = PlacesUtils.history.TRANSITION_LINK; - - let places = []; - let entries = aDict.get("WebHistoryDates"); - for (let entry of entries) { - if (entry.has("lastVisitedDate")) { - let visitDate = this._parseCocoaDate(entry.get("lastVisitedDate")); - places.push({ uri: NetUtil.newURI(entry.get("")), - title: entry.get("title"), - visits: [{ transitionType: transType, - visitDate: visitDate }] }); - } - } - if (places.length > 0) { - PlacesUtils.asyncHistory.updatePlaces(places, { - _success: false, - handleResult: function() { - // Importing any entry is considered a successful import. - this._success = true; - }, - handleError: function() {}, - handleCompletion: function() { - aCallback(this._success); - } - }); - } - else { - aCallback(false); - } - } - catch(ex) { - Cu.reportError(ex); - aCallback(false); - } - }.bind(this)); - } -}; - -/** - * Safari's preferences property list is independently used for three purposes: - * (a) importation of preferences - * (b) importation of search strings - * (c) retrieving the home page. - * - * So, rather than reading it three times, it's cached and managed here. - */ -function MainPreferencesPropertyList(aPreferencesFile) { - this._file = aPreferencesFile; - this._callbacks = []; -} -MainPreferencesPropertyList.prototype = { - /** - * @see PropertyListUtils.read - */ - read: function MPPL_read(aCallback) { - if ("_dict" in this) { - aCallback(this._dict); - return; - } - - let alreadyReading = this._callbacks.length > 0; - this._callbacks.push(aCallback); - if (!alreadyReading) { - PropertyListUtils.read(this._file, function readPrefs(aDict) { - this._dict = aDict; - for (let callback of this._callbacks) { - try { - callback(aDict); - } - catch(ex) { - Cu.reportError(ex); - } - } - this._callbacks.splice(0); - }.bind(this)); - } - }, - - // Workaround for nsIBrowserProfileMigrator.sourceHomePageURL until - // it's replaced with an async method. - _readSync: function MPPL__readSync() { - if ("_dict" in this) - return this._dict; - - let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - inputStream.init(this._file, -1, -1, 0); - let binaryStream = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); - binaryStream.setInputStream(inputStream); - let bytes = binaryStream.readByteArray(inputStream.available()); - this._dict = PropertyListUtils._readFromArrayBufferSync( - Uint8Array(bytes).buffer); - return this._dict; - } -}; - -function SearchStrings(aMainPreferencesPropertyListInstance) { - this._mainPreferencesPropertyList = aMainPreferencesPropertyListInstance; -} -SearchStrings.prototype = { - type: MigrationUtils.resourceTypes.OTHERDATA, - - migrate: function SS_migrate(aCallback) { - this._mainPreferencesPropertyList.read(MigrationUtils.wrapMigrateFunction( - function migrateSearchStrings(aDict) { - if (!aDict) - throw new Error("Could not get preferences dictionary"); - - if (aDict.has("RecentSearchStrings")) { - let recentSearchStrings = aDict.get("RecentSearchStrings"); - if (recentSearchStrings && recentSearchStrings.length > 0) { - let changes = [{op: "add", - fieldname: "searchbar-history", - value: searchString} - for (searchString of recentSearchStrings)]; - FormHistory.update(changes); - } - } - }.bind(this), aCallback)); - } -}; - -function SafariProfileMigrator() { -} - -SafariProfileMigrator.prototype = Object.create(MigratorPrototype); - -SafariProfileMigrator.prototype.getResources = function SM_getResources() { - let profileDir = -#ifdef XP_MACOSX - FileUtils.getDir("ULibDir", ["Safari"], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Safari"], false); -#endif - if (!profileDir.exists()) - return null; - - let resources = []; - let pushProfileFileResource = function(aFileName, aConstructor) { - let file = profileDir.clone(); - file.append(aFileName); - if (file.exists()) - resources.push(new aConstructor(file)); - }; - - pushProfileFileResource("History.plist", History); - pushProfileFileResource("Bookmarks.plist", Bookmarks); - - // The Reading List feature was introduced at the same time in Windows and - // Mac versions of Safari. Not surprisingly, they are stored in the same - // format in both versions. Surpsingly, only on Windows there is a - // separate property list for it. This isn't #ifdefed out on mac, because - // Apple may fix this at some point. - pushProfileFileResource("ReadingList.plist", Bookmarks); - - let prefsDir = -#ifdef XP_MACOSX - FileUtils.getDir("UsrPrfs", [], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false); -#endif - - let prefs = this.mainPreferencesPropertyList; - if (prefs) { - resources.push(new SearchStrings(prefs)); - } - - return resources; -}; - -Object.defineProperty(SafariProfileMigrator.prototype, "mainPreferencesPropertyList", { - get: function get_mainPreferencesPropertyList() { - if (this._mainPreferencesPropertyList === undefined) { - let file = -#ifdef XP_MACOSX - FileUtils.getDir("UsrPrfs", [], false); -#else - FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false); -#endif - if (file.exists()) { - file.append("com.apple.Safari.plist"); - if (file.exists()) { - return this._mainPreferencesPropertyList = - new MainPreferencesPropertyList(file); - } - } - return this._mainPreferencesPropertyList = null; - } - return this._mainPreferencesPropertyList; - } -}); - -Object.defineProperty(SafariProfileMigrator.prototype, "sourceHomePageURL", { - get: function get_sourceHomePageURL() { - if (this.mainPreferencesPropertyList) { - let dict = this.mainPreferencesPropertyList._readSync(); - if (dict.has("HomePage")) - return dict.get("HomePage"); - } - return ""; - } -}); - -SafariProfileMigrator.prototype.classDescription = "Safari Profile Migrator"; -SafariProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=safari"; -SafariProfileMigrator.prototype.classID = Components.ID("{4b609ecf-60b2-4655-9df4-dc149e474da1}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SafariProfileMigrator]); diff --git a/application/palemoon/components/migration/content/migration.js b/application/palemoon/components/migration/content/migration.js deleted file mode 100644 index 512197b8b..000000000 --- a/application/palemoon/components/migration/content/migration.js +++ /dev/null @@ -1,474 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -const kIMig = Ci.nsIBrowserProfileMigrator; -const kIPStartup = Ci.nsIProfileStartup; - -Cu.import("resource:///modules/MigrationUtils.jsm"); - -var MigrationWizard = { - _source: "", // Source Profile Migrator ContractID suffix - _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield) - _selectedProfile: null, // Selected Profile name to import from - _wiz: null, - _migrator: null, - _autoMigrate: null, - - init: function () - { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.addObserver(this, "Migration:Started", false); - os.addObserver(this, "Migration:ItemBeforeMigrate", false); - os.addObserver(this, "Migration:ItemAfterMigrate", false); - os.addObserver(this, "Migration:ItemError", false); - os.addObserver(this, "Migration:Ended", false); - - this._wiz = document.documentElement; - - if ("arguments" in window && window.arguments.length > 1) { - this._source = window.arguments[0]; - this._migrator = window.arguments[1] instanceof kIMig ? - window.arguments[1] : null; - this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup); - this._skipImportSourcePage = window.arguments[3]; - if (this._migrator && window.arguments[4]) { - let sourceProfiles = this._migrator.sourceProfiles; - this._selectedProfile = sourceProfiles.find(profile => profile.id == window.arguments[4]); - } - - if (this._autoMigrate) { - // Show the "nothing" option in the automigrate case to provide an - // easily identifiable way to avoid migration and create a new profile. - var nothing = document.getElementById("nothing"); - nothing.hidden = false; - } - } - - this.onImportSourcePageShow(); - }, - - uninit: function () - { - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.removeObserver(this, "Migration:Started"); - os.removeObserver(this, "Migration:ItemBeforeMigrate"); - os.removeObserver(this, "Migration:ItemAfterMigrate"); - os.removeObserver(this, "Migration:ItemError"); - os.removeObserver(this, "Migration:Ended"); - MigrationUtils.finishMigration(); - }, - - // 1 - Import Source - onImportSourcePageShow: function () - { - this._wiz.canRewind = false; - - var selectedMigrator = null; - - // Figure out what source apps are are available to import from: - var group = document.getElementById("importSourceGroup"); - for (var i = 0; i < group.childNodes.length; ++i) { - var migratorKey = group.childNodes[i].id; - if (migratorKey != "nothing") { - var migrator = MigrationUtils.getMigrator(migratorKey); - if (migrator) { - // Save this as the first selectable item, if we don't already have - // one, or if it is the migrator that was passed to us. - if (!selectedMigrator || this._source == migratorKey) - selectedMigrator = group.childNodes[i]; - } else { - // Hide this option - group.childNodes[i].hidden = true; - } - } - } - - if (selectedMigrator) - group.selectedItem = selectedMigrator; - else { - // We didn't find a migrator, notify the user - document.getElementById("noSources").hidden = false; - - this._wiz.canAdvance = false; - - document.getElementById("importBookmarks").hidden = true; - document.getElementById("importAll").hidden = true; - } - - // Advance to the next page if the caller told us to. - if (this._migrator && this._skipImportSourcePage) { - this._wiz.advance(); - this._wiz.canRewind = false; - } - }, - - onImportSourcePageAdvanced: function () - { - var newSource = document.getElementById("importSourceGroup").selectedItem.id; - - if (newSource == "nothing") { - document.documentElement.cancel(); - return false; - } - - if (!this._migrator || (newSource != this._source)) { - // Create the migrator for the selected source. - this._migrator = MigrationUtils.getMigrator(newSource); - - this._itemsFlags = kIMig.ALL; - this._selectedProfile = null; - } - this._source = newSource; - - // check for more than one source profile - var sourceProfiles = this._migrator.sourceProfiles; - if (this._skipImportSourcePage) { - this._wiz.currentPage.next = "homePageImport"; - } - else if (sourceProfiles && sourceProfiles.length > 1) { - this._wiz.currentPage.next = "selectProfile"; - } - else { - if (this._autoMigrate) - this._wiz.currentPage.next = "homePageImport"; - else - this._wiz.currentPage.next = "importItems"; - - if (sourceProfiles && sourceProfiles.length == 1) - this._selectedProfile = sourceProfiles[0]; - else - this._selectedProfile = null; - } - }, - - // 2 - [Profile Selection] - onSelectProfilePageShow: function () - { - // Disabling this for now, since we ask about import sources in automigration - // too and don't want to disable the back button - // if (this._autoMigrate) - // document.documentElement.getButton("back").disabled = true; - - var profiles = document.getElementById("profiles"); - while (profiles.hasChildNodes()) - profiles.removeChild(profiles.firstChild); - - // Note that this block is still reached even if the user chose 'From File' - // and we canceled the dialog. When that happens, _migrator will be null. - if (this._migrator) { - var sourceProfiles = this._migrator.sourceProfiles; - - for (let profile of sourceProfiles) { - var item = document.createElement("radio"); - item.id = profile.id; - item.setAttribute("label", profile.name); - profiles.appendChild(item); - } - } - - profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild; - }, - - onSelectProfilePageRewound: function () - { - var profiles = document.getElementById("profiles"); - this._selectedProfile = this._migrator.sourceProfiles.find( - profile => profile.id == profiles.selectedItem.id - ) || null; - }, - - onSelectProfilePageAdvanced: function () - { - var profiles = document.getElementById("profiles"); - this._selectedProfile = this._migrator.sourceProfiles.find( - profile => profile.id == profiles.selectedItem.id - ) || null; - - // If we're automigrating or just doing bookmarks don't show the item selection page - if (this._autoMigrate) - this._wiz.currentPage.next = "homePageImport"; - }, - - // 3 - ImportItems - onImportItemsPageShow: function () - { - var dataSources = document.getElementById("dataSources"); - while (dataSources.hasChildNodes()) - dataSources.removeChild(dataSources.firstChild); - - var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - for (var i = 0; i < 16; ++i) { - var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0; - if (itemID > 0) { - var checkbox = document.createElement("checkbox"); - checkbox.id = itemID; - checkbox.setAttribute("label", - MigrationUtils.getLocalizedString(itemID + "_" + this._source)); - dataSources.appendChild(checkbox); - if (!this._itemsFlags || this._itemsFlags & itemID) - checkbox.checked = true; - } - } - }, - - onImportItemsPageRewound: function () - { - this._wiz.canAdvance = true; - this.onImportItemsPageAdvanced(); - }, - - onImportItemsPageAdvanced: function () - { - var dataSources = document.getElementById("dataSources"); - this._itemsFlags = 0; - for (var i = 0; i < dataSources.childNodes.length; ++i) { - var checkbox = dataSources.childNodes[i]; - if (checkbox.localName == "checkbox" && checkbox.checked) - this._itemsFlags |= parseInt(checkbox.id); - } - }, - - onImportItemCommand: function (aEvent) - { - var items = document.getElementById("dataSources"); - var checkboxes = items.getElementsByTagName("checkbox"); - - var oneChecked = false; - for (var i = 0; i < checkboxes.length; ++i) { - if (checkboxes[i].checked) { - oneChecked = true; - break; - } - } - - this._wiz.canAdvance = oneChecked; - }, - - // 4 - Home Page Selection - onHomePageMigrationPageShow: function () - { - // only want this on the first run - if (!this._autoMigrate) { - this._wiz.advance(); - return; - } - - var brandBundle = document.getElementById("brandBundle"); - // These strings don't exist when not using official branding. If that's - // the case, just skip this page. - try { - var pageTitle = brandBundle.getString("homePageMigrationPageTitle"); - var pageDesc = brandBundle.getString("homePageMigrationDescription"); - var mainStr = brandBundle.getString("homePageSingleStartMain"); - } - catch (e) { - this._wiz.advance(); - return; - } - - document.getElementById("homePageImport").setAttribute("label", pageTitle); - document.getElementById("homePageImportDesc").setAttribute("value", pageDesc); - - this._wiz._adjustWizardHeader(); - - var singleStart = document.getElementById("homePageSingleStart"); - singleStart.setAttribute("label", mainStr); - singleStart.setAttribute("value", "DEFAULT"); - - var source = null; - switch (this._source) { - case "ie": - source = "sourceNameIE"; - break; - case "safari": - source = "sourceNameSafari"; - break; - case "chrome": - source = "sourceNameChrome"; - break; - case "firefox": - source = "sourceNameFirefox"; - break; - } - - // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places - this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - - var oldHomePageURL = this._migrator.sourceHomePageURL; - - if (oldHomePageURL && source) { - var appName = MigrationUtils.getLocalizedString(source); - var oldHomePageLabel = - brandBundle.getFormattedString("homePageImport", [appName]); - var oldHomePage = document.getElementById("oldHomePage"); - oldHomePage.setAttribute("label", oldHomePageLabel); - oldHomePage.setAttribute("value", oldHomePageURL); - oldHomePage.removeAttribute("hidden"); - } - else { - // if we don't have at least two options, just advance - this._wiz.advance(); - } - }, - - onHomePageMigrationPageAdvanced: function () - { - // we might not have a selectedItem if we're in fallback mode - try { - var radioGroup = document.getElementById("homePageRadiogroup"); - - this._newHomePage = radioGroup.selectedItem.value; - } catch(ex) {} - }, - - // 5 - Migrating - onMigratingPageShow: function () - { - this._wiz.getButton("cancel").disabled = true; - this._wiz.canRewind = false; - this._wiz.canAdvance = false; - - // When automigrating, show all of the data that can be received from this source. - if (this._autoMigrate) - this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate); - - this._listItems("migratingItems"); - setTimeout(this.onMigratingMigrate, 0, this); - }, - - onMigratingMigrate: function (aOuter) - { - aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile); - }, - - _listItems: function (aID) - { - var items = document.getElementById(aID); - while (items.hasChildNodes()) - items.removeChild(items.firstChild); - - var brandBundle = document.getElementById("brandBundle"); - var itemID; - for (var i = 0; i < 16; ++i) { - var itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0; - if (itemID > 0) { - var label = document.createElement("label"); - label.id = itemID + "_migrated"; - try { - label.setAttribute("value", - MigrationUtils.getLocalizedString(itemID + "_" + this._source)); - items.appendChild(label); - } - catch (e) { - // if the block above throws, we've enumerated all the import data types we - // currently support and are now just wasting time, break. - break; - } - } - } - }, - - observe: function (aSubject, aTopic, aData) - { - switch (aTopic) { - case "Migration:Started": - break; - case "Migration:ItemBeforeMigrate": - var label = document.getElementById(aData + "_migrated"); - if (label) - label.setAttribute("style", "font-weight: bold"); - break; - case "Migration:ItemAfterMigrate": - var label = document.getElementById(aData + "_migrated"); - if (label) - label.removeAttribute("style"); - break; - case "Migration:Ended": - if (this._autoMigrate) { - if (this._newHomePage) { - try { - // set homepage properly - var prefSvc = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService); - var prefBranch = prefSvc.getBranch(null); - - if (this._newHomePage == "DEFAULT") { - prefBranch.clearUserPref("browser.startup.homepage"); - } - else { - var str = Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString); - str.data = this._newHomePage; - prefBranch.setComplexValue("browser.startup.homepage", - Components.interfaces.nsISupportsString, - str); - } - - var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile); - prefFile.append("prefs.js"); - prefSvc.savePrefFile(prefFile); - } catch(ex) { - dump(ex); - } - } - - // We're done now. - this._wiz.canAdvance = true; - this._wiz.advance(); - - setTimeout(close, 5000); - } - else { - this._wiz.canAdvance = true; - var nextButton = this._wiz.getButton("next"); - nextButton.click(); - } - break; - case "Migration:ItemError": - var type = "undefined"; - switch (parseInt(aData)) { - case Ci.nsIBrowserProfileMigrator.SETTINGS: - type = "settings"; - break; - case Ci.nsIBrowserProfileMigrator.COOKIES: - type = "cookies"; - break; - case Ci.nsIBrowserProfileMigrator.HISTORY: - type = "history"; - break; - case Ci.nsIBrowserProfileMigrator.FORMDATA: - type = "form data"; - break; - case Ci.nsIBrowserProfileMigrator.PASSWORDS: - type = "passwords"; - break; - case Ci.nsIBrowserProfileMigrator.BOOKMARKS: - type = "bookmarks"; - break; - case Ci.nsIBrowserProfileMigrator.OTHERDATA: - type = "misc. data"; - break; - } - Cc["@mozilla.org/consoleservice;1"] - .getService(Ci.nsIConsoleService) - .logStringMessage("some " + type + " did not successfully migrate."); - break; - } - }, - - onDonePageShow: function () - { - this._wiz.getButton("cancel").disabled = true; - this._wiz.canRewind = false; - this._listItems("doneItems"); - } -}; diff --git a/application/palemoon/components/migration/content/migration.xul b/application/palemoon/components/migration/content/migration.xul deleted file mode 100644 index 2c8df7b3e..000000000 --- a/application/palemoon/components/migration/content/migration.xul +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0"?> -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> - -<!DOCTYPE dialog SYSTEM "chrome://browser/locale/migration/migration.dtd" > - -<wizard id="migrationWizard" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - windowtype="Browser:MigrationWizard" - title="&migrationWizard.title;" - onload="MigrationWizard.init()" - onunload="MigrationWizard.uninit()" - style="width: 40em;" - buttons="accept,cancel" - branded="true"> - - <script type="application/javascript" src="chrome://browser/content/migration/migration.js"/> - - <stringbundle id="brandBundle" src="chrome://branding/locale/brand.properties"/> - - <wizardpage id="importSource" pageid="importSource" next="selectProfile" - label="&importSource.title;" - onpageadvanced="return MigrationWizard.onImportSourcePageAdvanced();"> - <description id="importAll" control="importSourceGroup">&importFrom.label;</description> - <description id="importBookmarks" control="importSourceGroup" hidden="true">&importFromBookmarks.label;</description> - - <radiogroup id="importSourceGroup" align="start"> - <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/> -#ifdef XP_WIN - <radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/> - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> - <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> -#elifdef XP_MACOSX - <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> -#elifdef XP_UNIX - <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> -#endif - <radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/> - </radiogroup> - <label id="noSources" hidden="true">&noMigrationSources.label;</label> - </wizardpage> - - <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;" - next="importItems" - onpageshow="return MigrationWizard.onSelectProfilePageShow();" - onpagerewound="return MigrationWizard.onSelectProfilePageRewound();" - onpageadvanced="return MigrationWizard.onSelectProfilePageAdvanced();"> - <description control="profiles">&selectProfile.label;</description> - - <radiogroup id="profiles" align="left"/> - </wizardpage> - - <wizardpage id="importItems" pageid="importItems" label="&importItems.title;" - next="homePageImport" - onpageshow="return MigrationWizard.onImportItemsPageShow();" - onpagerewound="return MigrationWizard.onImportItemsPageRewound();" - onpageadvanced="return MigrationWizard.onImportItemsPageAdvanced();" - oncommand="MigrationWizard.onImportItemCommand();"> - <description control="dataSources">&importItems.label;</description> - - <vbox id="dataSources" style="overflow: auto; -moz-appearance: listbox" align="left" flex="1" role="group"/> - </wizardpage> - - <wizardpage id="homePageImport" pageid="homePageImport" - next="migrating" - onpageshow="return MigrationWizard.onHomePageMigrationPageShow();" - onpageadvanced="return MigrationWizard.onHomePageMigrationPageAdvanced();"> - - <description id="homePageImportDesc" control="homePageRadioGroup"/> - <radiogroup id="homePageRadiogroup"> - <radio id="homePageSingleStart" selected="true" /> - <radio id="oldHomePage" hidden="true" /> - </radiogroup> - </wizardpage> - - <wizardpage id="migrating" pageid="migrating" label="&migrating.title;" - next="done" - onpageshow="MigrationWizard.onMigratingPageShow();"> - <description control="migratingItems">&migrating.label;</description> - - <vbox id="migratingItems" style="overflow: auto;" align="left" role="group"/> - </wizardpage> - - <wizardpage id="done" pageid="done" label="&done.title;" - onpageshow="MigrationWizard.onDonePageShow();"> - <description control="doneItems">&done.label;</description> - - <vbox id="doneItems" style="overflow: auto;" align="left" role="group"/> - </wizardpage> - -</wizard> - diff --git a/application/palemoon/components/migration/jar.mn b/application/palemoon/components/migration/jar.mn deleted file mode 100644 index b369ee1dc..000000000 --- a/application/palemoon/components/migration/jar.mn +++ /dev/null @@ -1,7 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -browser.jar: -* content/browser/migration/migration.xul (content/migration.xul) - content/browser/migration/migration.js (content/migration.js) diff --git a/application/palemoon/components/migration/moz.build b/application/palemoon/components/migration/moz.build deleted file mode 100644 index 4cbf7b8ea..000000000 --- a/application/palemoon/components/migration/moz.build +++ /dev/null @@ -1,53 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -JAR_MANIFESTS += ['jar.mn'] - -XPIDL_SOURCES += [ - 'nsIBrowserProfileMigrator.idl', -] - -XPIDL_MODULE = 'migration' - -if CONFIG['OS_ARCH'] == 'WINNT': - SOURCES += [ - 'nsIEHistoryEnumerator.cpp', - ] - -EXTRA_COMPONENTS += [ - 'FirefoxProfileMigrator.js', - 'ProfileMigrator.js', -] - -if CONFIG['OS_ARCH'] == 'WINNT': - EXTRA_COMPONENTS += [ - 'IEProfileMigrator.js', - ] - DEFINES['HAS_IE_MIGRATOR'] = True - -EXTRA_PP_COMPONENTS += [ - 'BrowserProfileMigrators.manifest', - 'ChromeProfileMigrator.js', -] - -if CONFIG['OS_ARCH'] == 'WINNT': - EXTRA_PP_COMPONENTS += [ - 'SafariProfileMigrator.js', - ] - DEFINES['HAS_SAFARI_MIGRATOR'] = True - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': - EXTRA_PP_COMPONENTS += [ - 'SafariProfileMigrator.js', - ] - DEFINES['HAS_SAFARI_MIGRATOR'] = True - -EXTRA_PP_JS_MODULES += [ - 'MigrationUtils.jsm', -] - -FINAL_LIBRARY = 'browsercomps' - diff --git a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl b/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl deleted file mode 100644 index ebff4628c..000000000 --- a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsISupports.idl" - -interface nsIArray; -interface nsIProfileStartup; - -[scriptable, uuid(30e5a7ec-f71e-4f41-9dbd-7429c02132ec)] -interface nsIBrowserProfileMigrator : nsISupports -{ - /** - * profile items to migrate. use with migrate(). - */ - const unsigned short ALL = 0x0000; - const unsigned short SETTINGS = 0x0001; - const unsigned short COOKIES = 0x0002; - const unsigned short HISTORY = 0x0004; - const unsigned short FORMDATA = 0x0008; - const unsigned short PASSWORDS = 0x0010; - const unsigned short BOOKMARKS = 0x0020; - const unsigned short OTHERDATA = 0x0040; - - /** - * Copy user profile information to the current active profile. - * @param aItems list of data items to migrate. see above for values. - * @param aStartup helper interface which is non-null if called during startup. - * @param aProfile profile to migrate from, if there is more than one. - */ - void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in jsval aProfile); - - /** - * A bit field containing profile items that this migrator - * offers for import. - * @param aProfile the profile that we are looking for available data - * to import - * @param aDoingStartup "true" if the profile is not currently being used. - * @return bit field containing profile items (see above) - * @note a return value of 0 represents no items rather than ALL. - */ - unsigned short getMigrateData(in jsval aProfile, in boolean aDoingStartup); - - /** - * Whether or not there is any data that can be imported from this - * browser (i.e. whether or not it is installed, and there exists - * a user profile) - */ - readonly attribute boolean sourceExists; - - - /** - * An enumeration of available profiles. If the import source does - * not support profiles, this attribute is null. - */ - readonly attribute jsval sourceProfiles; - - /** - * The import source homepage. Returns null if not present/available - */ - readonly attribute AUTF8String sourceHomePageURL; -}; diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp b/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp deleted file mode 100644 index 7fe31a666..000000000 --- a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIEHistoryEnumerator.h"
-
-#include <urlhist.h>
-#include <shlguid.h>
-
-#include "nsStringAPI.h"
-#include "nsNetUtil.h"
-#include "nsIVariant.h"
-#include "nsCOMArray.h"
-#include "nsArrayEnumerator.h"
-
-namespace {
-
- PRTime FileTimeToPRTime(FILETIME* filetime)
- {
- SYSTEMTIME st;
- ::FileTimeToSystemTime(filetime, &st);
- PRExplodedTime prt;
- prt.tm_year = st.wYear;
- // SYSTEMTIME's day-of-month parameter is 1-based,
- // PRExplodedTime's is 0-based.
- prt.tm_month = st.wMonth - 1;
- prt.tm_mday = st.wDay;
- prt.tm_hour = st.wHour;
- prt.tm_min = st.wMinute;
- prt.tm_sec = st.wSecond;
- prt.tm_usec = st.wMilliseconds * 1000;
- prt.tm_wday = 0;
- prt.tm_yday = 0;
- prt.tm_params.tp_gmt_offset = 0;
- prt.tm_params.tp_dst_offset = 0;
- return PR_ImplodeTime(&prt);
- }
-
-} // Anonymous namespace.
-
-////////////////////////////////////////////////////////////////////////////////
-//// nsIEHistoryEnumerator
-
-NS_IMPL_ISUPPORTS(nsIEHistoryEnumerator, nsISimpleEnumerator)
-
-nsIEHistoryEnumerator::nsIEHistoryEnumerator()
-{
- ::CoInitialize(nullptr);
-}
-
-nsIEHistoryEnumerator::~nsIEHistoryEnumerator()
-{
- ::CoUninitialize();
-}
-
-void
-nsIEHistoryEnumerator::EnsureInitialized()
-{
- if (mURLEnumerator)
- return;
-
- HRESULT hr = ::CoCreateInstance(CLSID_CUrlHistory,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IUrlHistoryStg2,
- getter_AddRefs(mIEHistory));
- if (FAILED(hr))
- return;
-
- hr = mIEHistory->EnumUrls(getter_AddRefs(mURLEnumerator));
- if (FAILED(hr))
- return;
-}
-
-NS_IMETHODIMP
-nsIEHistoryEnumerator::HasMoreElements(bool* _retval)
-{
- *_retval = false;
-
- EnsureInitialized();
- MOZ_ASSERT(mURLEnumerator, "Should have instanced an IE History URLEnumerator");
- if (!mURLEnumerator)
- return NS_OK;
-
- STATURL statURL;
- ULONG fetched;
-
- // First argument is not implemented, so doesn't matter what we pass.
- HRESULT hr = mURLEnumerator->Next(1, &statURL, &fetched);
- if (FAILED(hr) || fetched != 1UL) {
- // Reached the last entry.
- return NS_OK;
- }
-
- nsCOMPtr<nsIURI> uri;
- if (statURL.pwcsUrl) {
- nsDependentString url(statURL.pwcsUrl);
- nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
- ::CoTaskMemFree(statURL.pwcsUrl);
- if (NS_FAILED(rv)) {
- // Got a corrupt or invalid URI, continue to the next entry.
- return HasMoreElements(_retval);
- }
- }
-
- nsDependentString title(statURL.pwcsTitle);
-
- PRTime lastVisited = FileTimeToPRTime(&(statURL.ftLastVisited));
-
- mCachedNextEntry = do_CreateInstance("@mozilla.org/hash-property-bag;1");
- MOZ_ASSERT(mCachedNextEntry, "Should have instanced a new property bag");
- if (mCachedNextEntry) {
- mCachedNextEntry->SetPropertyAsInterface(NS_LITERAL_STRING("uri"), uri);
- mCachedNextEntry->SetPropertyAsAString(NS_LITERAL_STRING("title"), title);
- mCachedNextEntry->SetPropertyAsInt64(NS_LITERAL_STRING("time"), lastVisited);
-
- *_retval = true;
- }
-
- if (statURL.pwcsTitle)
- ::CoTaskMemFree(statURL.pwcsTitle);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsIEHistoryEnumerator::GetNext(nsISupports** _retval)
-{
- *_retval = nullptr;
-
- if (!mCachedNextEntry)
- return NS_ERROR_FAILURE;
-
- NS_ADDREF(*_retval = mCachedNextEntry);
- // Release the cached entry, so it can't be returned twice.
- mCachedNextEntry = nullptr;
-
- return NS_OK;
-}
diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.h b/application/palemoon/components/migration/nsIEHistoryEnumerator.h deleted file mode 100644 index fc1419859..000000000 --- a/application/palemoon/components/migration/nsIEHistoryEnumerator.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef iehistoryenumerator___h___
-#define iehistoryenumerator___h___
-
-#include <urlhist.h>
-
-#include "mozilla/Attributes.h"
-#include "nsISimpleEnumerator.h"
-#include "nsIWritablePropertyBag2.h"
-#include "nsAutoPtr.h"
-
-class nsIEHistoryEnumerator final : public nsISimpleEnumerator
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSISIMPLEENUMERATOR
-
- nsIEHistoryEnumerator();
-
-private:
- ~nsIEHistoryEnumerator();
-
- /**
- * Initializes the history reader, if needed.
- */
- void EnsureInitialized();
-
- nsRefPtr<IUrlHistoryStg2> mIEHistory;
- nsRefPtr<IEnumSTATURL> mURLEnumerator;
-
- nsCOMPtr<nsIWritablePropertyBag2> mCachedNextEntry;
-};
-
-#endif
diff --git a/application/palemoon/components/moz.build b/application/palemoon/components/moz.build index 1c1098f0a..6e83936a9 100644 --- a/application/palemoon/components/moz.build +++ b/application/palemoon/components/moz.build @@ -17,7 +17,6 @@ DIRS += [ 'search', 'sessionstore', 'shell', - 'migration', ] if CONFIG['MOZ_BROWSER_STATUSBAR']: diff --git a/application/palemoon/components/nsBrowserContentHandler.js b/application/palemoon/components/nsBrowserContentHandler.js index 13ea9da12..6a75b40f2 100644 --- a/application/palemoon/components/nsBrowserContentHandler.js +++ b/application/palemoon/components/nsBrowserContentHandler.js @@ -518,16 +518,16 @@ nsBrowserContentHandler.prototype = { #endif }, - helpInfo : " -browser Open a browser window.\n" + - " -new-window <url> Open <url> in a new window.\n" + - " -new-tab <url> Open <url> in a new tab.\n" + - " -private-window <url> Open <url> in a new private window.\n" + + helpInfo : " --browser Open a browser window.\n" + + " --new-window <url> Open <url> in a new window.\n" + + " --new-tab <url> Open <url> in a new tab.\n" + + " --private-window <url> Open <url> in a new private window.\n" + #ifdef XP_WIN - " -preferences Open Options dialog.\n" + + " --preferences Open Options dialog.\n" + #else - " -preferences Open Preferences dialog.\n" + + " --preferences Open Preferences dialog.\n" + #endif - " -search <term> Search <term> with your default search engine.\n", + " --search <term> Search <term> with your default search engine.\n", /* nsIBrowserHandler */ diff --git a/application/palemoon/components/nsBrowserGlue.js b/application/palemoon/components/nsBrowserGlue.js index 705593b59..225cddd52 100644 --- a/application/palemoon/components/nsBrowserGlue.js +++ b/application/palemoon/components/nsBrowserGlue.js @@ -13,59 +13,31 @@ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", - "resource://gre/modules/AddonManager.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides", - "resource://gre/modules/UserAgentOverrides.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils", - "resource://gre/modules/BookmarkHTMLUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils", - "resource://gre/modules/BookmarkJSONUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", - "resource://gre/modules/PageThumbs.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", - "resource://gre/modules/NewTabUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader", - "resource:///modules/BrowserNewTabPreloader.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "webrtcUI", - "resource:///modules/webrtcUI.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", - "resource://gre/modules/PrivateBrowsingUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow", - "resource:///modules/RecentWindow.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", - "resource://gre/modules/PlacesBackups.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent", - "resource://gre/modules/LoginManagerParent.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "FormValidationHandler", - "resource:///modules/FormValidationHandler.jsm"); +// Define Lazy Module Gitters +[ + ["AddonManager", "resource://gre/modules/AddonManager.jsm"], + ["NetUtil", "resource://gre/modules/NetUtil.jsm"], + ["UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"], + ["FileUtils", "resource://gre/modules/FileUtils.jsm"], + ["PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"], + ["BookmarkHTMLUtils", "resource://gre/modules/BookmarkHTMLUtils.jsm"], + ["BookmarkJSONUtils", "resource://gre/modules/BookmarkJSONUtils.jsm"], + ["PageThumbs", "resource://gre/modules/PageThumbs.jsm"], + ["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"], + ["BrowserNewTabPreloader", "resource:///modules/BrowserNewTabPreloader.jsm"], +#ifdef MOZ_WEBRTC + ["webrtcUI", "resource:///modules/webrtcUI.jsm"], +#endif + ["PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"], + ["RecentWindow", "resource:///modules/RecentWindow.jsm"], + ["Task", "resource://gre/modules/Task.jsm"], + ["PlacesBackups", "resource://gre/modules/PlacesBackups.jsm"], + ["OS", "resource://gre/modules/osfile.jsm"], + ["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"], + ["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"], + ["AutoCompletePopup", "resource:///modules/AutoCompletePopup.jsm"], + ["DateTimePickerHelper", "resource://gre/modules/DateTimePickerHelper.jsm"], +].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource)); const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser"; const PREF_PLUGINS_UPDATEURL = "plugins.update.url"; @@ -197,6 +169,7 @@ BrowserGlue.prototype = { } catch (e) { Cu.reportError("Could not end startup crash tracking in quit-application-granted: " + e); } + DateTimePickerHelper.uninit(); break; #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS case "browser-lastwindow-close-requested": @@ -284,7 +257,8 @@ BrowserGlue.prototype = { if (!linkHandled.data) { let win = this.getMostRecentBrowserWindow(); if (win) { - win.openUILinkIn(data, "tab"); + data = JSON.parse(data); + win.openUILinkIn(data.href, "tab"); linkHandled.data = true; } } @@ -427,16 +401,15 @@ BrowserGlue.prototype = { PageThumbs.init(); NewTabUtils.init(); BrowserNewTabPreloader.init(); +#ifdef MOZ_WEBRTC webrtcUI.init(); +#endif FormValidationHandler.init(); + AutoCompletePopup.init(); + LoginManagerParent.init(); - // Make sure conflicting MSE prefs don't coexist - if (Services.prefs.getBoolPref('media.mediasource.format-reader', true)) { - Services.prefs.setBoolPref('media.mediasource.webm.enabled', false); - } - Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); }, @@ -528,6 +501,8 @@ BrowserGlue.prototype = { } #endif + DateTimePickerHelper.init(); + this._trackSlowStartup(); }, @@ -539,8 +514,11 @@ BrowserGlue.prototype = { _onProfileShutdown: function BG__onProfileShutdown() { BrowserNewTabPreloader.uninit(); UserAgentOverrides.uninit(); +#ifdef MOZ_WEBRTC webrtcUI.uninit(); +#endif FormValidationHandler.uninit(); + AutoCompletePopup.uninit(); this._dispose(); }, @@ -1213,7 +1191,7 @@ BrowserGlue.prototype = { }, _migrateUI: function BG__migrateUI() { - const UI_VERSION = 14; + const UI_VERSION = 15; const BROWSER_DOCURL = "chrome://browser/content/browser.xul#"; let currentUIVersion = 0; try { @@ -1395,7 +1373,7 @@ BrowserGlue.prototype = { } } - if (currentUIVersion < 14) { + if (currentUIVersion < 16) { // Migrate Sync from pmsync.palemoon.net to pmsync.palemoon.org try { let syncURL = Services.prefs.getCharPref("services.sync.clusterURL"); diff --git a/application/palemoon/components/places/BrowserPlaces.manifest b/application/palemoon/components/places/BrowserPlaces.manifest deleted file mode 100644 index 3b25f50f4..000000000 --- a/application/palemoon/components/places/BrowserPlaces.manifest +++ /dev/null @@ -1,2 +0,0 @@ -component {6bcb9bde-9018-4443-a071-c32653469597} PlacesProtocolHandler.js -contract @mozilla.org/network/protocol;1?name=place {6bcb9bde-9018-4443-a071-c32653469597} diff --git a/application/palemoon/components/places/PlacesProtocolHandler.js b/application/palemoon/components/places/PlacesProtocolHandler.js deleted file mode 100644 index ebffd2e28..000000000 --- a/application/palemoon/components/places/PlacesProtocolHandler.js +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 et - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; - -Components.utils.import("resource://gre/modules/NetUtil.jsm"); -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -const SCHEME = "place"; -const URL = "chrome://browser/content/places/content-ui/controller.xhtml"; - -function PlacesProtocolHandler() {} - -PlacesProtocolHandler.prototype = { - scheme: SCHEME, - defaultPort: -1, - protocolFlags: Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD | - Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE | - Ci.nsIProtocolHandler.URI_NORELATIVE | - Ci.nsIProtocolHandler.URI_NOAUTH, - - newURI: function PPH_newURI(aSpec, aOriginCharset, aBaseUri) { - let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI); - uri.spec = aSpec; - return uri; - }, - - newChannel: function PPH_newChannel(aUri) { - let chan = NetUtil.newChannel(URL); - chan.originalURI = aUri; - return chan; - }, - - allowPort: function PPH_allowPort(aPort, aScheme) { - return false; - }, - - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIProtocolHandler - ]), - - classID: Components.ID("{6bcb9bde-9018-4443-a071-c32653469597}") -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PlacesProtocolHandler]); diff --git a/application/palemoon/components/places/content/controller.js b/application/palemoon/components/places/content/controller.js index 4d3773905..e2ae2afb0 100644 --- a/application/palemoon/components/places/content/controller.js +++ b/application/palemoon/components/places/content/controller.js @@ -1603,7 +1603,7 @@ PlacesController.prototype = { * the view that the item(s) have been dropped on was not necessarily active. * Drop functions are passed the view that is being dropped on. */ -let PlacesControllerDragHelper = { +var PlacesControllerDragHelper = { /** * DOM Element currently being dragged over */ diff --git a/application/palemoon/components/places/content/editBookmarkOverlay.js b/application/palemoon/components/places/content/editBookmarkOverlay.js index 98bfcccd7..43645cc73 100644 --- a/application/palemoon/components/places/content/editBookmarkOverlay.js +++ b/application/palemoon/components/places/content/editBookmarkOverlay.js @@ -16,6 +16,7 @@ var gEditItemOverlay = { _itemType: -1, _readOnly: false, _hiddenRows: [], + _onPanelReady: false, _observersAdded: false, _staticFoldersListBuilt: false, _initialized: false, @@ -50,6 +51,7 @@ var gEditItemOverlay = { this._readOnly = aInfo && aInfo.forceReadOnly; this._titleOverride = aInfo && aInfo.titleOverride ? aInfo.titleOverride : ""; + this._onPanelReady = aInfo && aInfo.onPanelReady; }, _showHideRows: function EIO__showHideRows() { @@ -219,7 +221,15 @@ var gEditItemOverlay = { this._observersAdded = true; } - this._initialized = true; + let focusElement = () => { + this._initialized = true; + }; + + if (this._onPanelReady) { + this._onPanelReady(focusElement); + } else { + focusElement(); + } }, /** @@ -243,11 +253,7 @@ var gEditItemOverlay = { if (field.value != aValue) { field.value = aValue; - - // clear the undo stack - var editor = field.editor; - if (editor) - editor.transactionManager.clear(); + this._editorTransactionManagerClear(field); } }, @@ -352,6 +358,26 @@ var gEditItemOverlay = { return document.getElementById("editBMPanel_" + aID); }, + _editorTransactionManagerClear: function EIO__editorTransactionManagerClear(aItem) { + // Clear the editor's undo stack + let transactionManager; + try { + transactionManager = aItem.editor.transactionManager; + } catch (e) { + // When retrieving the transaction manager, editor may be null resulting + // in a TypeError. Additionally, the transaction manager may not + // exist yet, which causes access to it to throw NS_ERROR_FAILURE. + // In either event, the transaction manager doesn't exist it, so we + // don't need to worry about clearing it. + if (!(e instanceof TypeError) && e.result != Cr.NS_ERROR_FAILURE) { + throw e; + } + } + if (transactionManager) { + transactionManager.clear(); + } + }, + _getItemStaticTitle: function EIO__getItemStaticTitle() { if (this._titleOverride) return this._titleOverride; @@ -370,11 +396,7 @@ var gEditItemOverlay = { var namePicker = this._element("namePicker"); namePicker.value = this._getItemStaticTitle(); namePicker.readOnly = this._readOnly; - - // clear the undo stack - var editor = namePicker.editor; - if (editor) - editor.transactionManager.clear(); + this._editorTransactionManagerClear(namePicker); }, uninitPanel: function EIO_uninitPanel(aHideCollapsibleElements) { @@ -963,8 +985,7 @@ var gEditItemOverlay = { var namePicker = this._element("namePicker"); if (namePicker.value != aValue) { namePicker.value = aValue; - // clear undo stack - namePicker.editor.transactionManager.clear(); + this._editorTransactionManagerClear(namePicker); } break; case "uri": diff --git a/application/palemoon/components/places/content/places.js b/application/palemoon/components/places/content/places.js index af254a7fb..a94193823 100644 --- a/application/palemoon/components/places/content/places.js +++ b/application/palemoon/components/places/content/places.js @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils", @@ -335,14 +334,6 @@ var PlacesOrganizer = { }, /** - * Show the migration wizard for importing passwords, - * cookies, history, preferences, and bookmarks. - */ - importFromBrowser: function PO_importFromBrowser() { - MigrationUtils.showMigrationWizard(window); - }, - - /** * Open a file-picker and import the selected file into the bookmarks store */ importFromFile: function PO_importFromFile() { @@ -1386,7 +1377,7 @@ var ViewMenu = { } } -let ContentArea = { +var ContentArea = { _specialViews: new Map(), init: function CA_init() { @@ -1520,7 +1511,7 @@ let ContentArea = { } }; -let ContentTree = { +var ContentTree = { init: function CT_init() { this._view = document.getElementById("placeContent"); }, diff --git a/application/palemoon/components/places/content/places.xul b/application/palemoon/components/places/content/places.xul index ee1f2ff48..92e8a70e9 100644 --- a/application/palemoon/components/places/content/places.xul +++ b/application/palemoon/components/places/content/places.xul @@ -68,8 +68,6 @@ oncommand="PlacesOrganizer.exportBookmarks();"/> <command id="OrganizerCommand_import" oncommand="PlacesOrganizer.importFromFile();"/> - <command id="OrganizerCommand_browserImport" - oncommand="PlacesOrganizer.importFromBrowser();"/> <command id="OrganizerCommand_backup" oncommand="PlacesOrganizer.backupBookmarks();"/> <command id="OrganizerCommand_restoreFromFile" @@ -312,11 +310,6 @@ command="OrganizerCommand_export" label="&exportBookmarksToHTML.label;" accesskey="&exportBookmarksToHTML.accesskey;"/> - <menuseparator/> - <menuitem id="browserImport" - command="OrganizerCommand_browserImport" - label="&importOtherBrowser.label;" - accesskey="&importOtherBrowser.accesskey;"/> </menupopup> #ifdef XP_MACOSX </toolbarbutton> diff --git a/application/palemoon/components/places/content/treeView.js b/application/palemoon/components/places/content/treeView.js index c1879aacf..aba731470 100644 --- a/application/palemoon/components/places/content/treeView.js +++ b/application/palemoon/components/places/content/treeView.js @@ -144,7 +144,12 @@ PlacesTreeView.prototype = { // A node is removed form the view either if it has no parent or if its // root-ancestor is not the root node (in which case that's the node // for which nodeRemoved was called). - let ancestors = [x for (x of PlacesUtils.nodeAncestors(aNode))]; + // Tycho: let ancestors = [x for (x of PlacesUtils.nodeAncestors(aNode))]; + let ancestors = []; + for (let x of PlacesUtils.nodeAncestors(aNode)) { + ancestors.push(x); + } + if (ancestors.length == 0 || ancestors[ancestors.length - 1] != this._rootNode) { throw new Error("Removed node passed to _getRowForNode"); diff --git a/application/palemoon/components/places/moz.build b/application/palemoon/components/places/moz.build index fc69beed9..2e35e1951 100644 --- a/application/palemoon/components/places/moz.build +++ b/application/palemoon/components/places/moz.build @@ -6,9 +6,5 @@ JAR_MANIFESTS += ['jar.mn'] -EXTRA_COMPONENTS += [ - 'BrowserPlaces.manifest', - 'PlacesProtocolHandler.js', -] EXTRA_JS_MODULES += [ 'PlacesUIUtils.jsm' ] diff --git a/application/palemoon/components/preferences/aboutPermissions.js b/application/palemoon/components/preferences/aboutPermissions.js index 4d803145d..31b48f88e 100644 --- a/application/palemoon/components/preferences/aboutPermissions.js +++ b/application/palemoon/components/preferences/aboutPermissions.js @@ -2,9 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -let Ci = Components.interfaces; -let Cc = Components.classes; -let Cu = Components.utils; +var Ci = Components.interfaces; +var Cc = Components.classes; +var Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/PluralForm.jsm"); @@ -13,15 +13,15 @@ Cu.import("resource://gre/modules/AddonManager.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/ForgetAboutSite.jsm"); -let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"]. +var gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"]. getService(Ci.nsIFaviconService); -let gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"]. +var gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"]. getService(Ci.nsPIPlacesDatabase). DBConnection. clone(true); -let gSitesStmt = gPlacesDatabase.createAsyncStatement( +var gSitesStmt = gPlacesDatabase.createAsyncStatement( "SELECT get_unreversed_host(rev_host) AS host " + "FROM moz_places " + "WHERE rev_host > '.' " + @@ -30,12 +30,12 @@ let gSitesStmt = gPlacesDatabase.createAsyncStatement( "ORDER BY MAX(frecency) DESC " + "LIMIT :limit"); -let gVisitStmt = gPlacesDatabase.createAsyncStatement( +var gVisitStmt = gPlacesDatabase.createAsyncStatement( "SELECT SUM(visit_count) AS count " + "FROM moz_places " + "WHERE rev_host = :rev_host"); -let gFlash = { +var gFlash = { name: "Shockwave Flash", betterName: "Adobe Flash", type: "application/x-shockwave-flash", @@ -290,7 +290,7 @@ Site.prototype = { * * Inspired by pageinfo/permissions.js */ -let PermissionDefaults = { +var PermissionDefaults = { UNKNOWN: Ci.nsIPermissionManager.UNKNOWN_ACTION, // 0 ALLOW: Ci.nsIPermissionManager.ALLOW_ACTION, // 1 DENY: Ci.nsIPermissionManager.DENY_ACTION, // 2 @@ -449,7 +449,7 @@ let PermissionDefaults = { /** * AboutPermissions manages the about:permissions page. */ -let AboutPermissions = { +var AboutPermissions = { /** * Maximum number of sites to return from the places database. */ diff --git a/application/palemoon/components/preferences/cookies.js b/application/palemoon/components/preferences/cookies.js index 5316c106e..543aeb186 100644 --- a/application/palemoon/components/preferences/cookies.js +++ b/application/palemoon/components/preferences/cookies.js @@ -70,7 +70,9 @@ var gCookiesWindow = { _cookieEquals: function (aCookieA, aCookieB, aStrippedHost) { return aCookieA.rawHost == aStrippedHost && aCookieA.name == aCookieB.name && - aCookieA.path == aCookieB.path; + aCookieA.path == aCookieB.path && + ChromeUtils.isOriginAttributesEqual(aCookieA.originAttributes, + aCookieB.originAttributes); }, observe: function (aCookie, aTopic, aData) { @@ -275,15 +277,19 @@ var gCookiesWindow = { var item = this._getItemAtIndex(aIndex); if (!item) return; this._invalidateCache(aIndex - 1); - if (item.container) + if (item.container) { gCookiesWindow._hosts[item.rawHost] = null; - else { + } else { var parent = this._getItemAtIndex(item.parentIndex); for (var i = 0; i < parent.cookies.length; ++i) { var cookie = parent.cookies[i]; if (item.rawHost == cookie.rawHost && - item.name == cookie.name && item.path == cookie.path) + item.name == cookie.name && + item.path == cookie.path && + ChromeUtils.isOriginAttributesEqual(item.originAttributes, + cookie.originAttributes)) { parent.cookies.splice(i, removeCount); + } } } }, @@ -458,16 +464,17 @@ var gCookiesWindow = { _makeCookieObject: function (aStrippedHost, aCookie) { var host = aCookie.host; var formattedHost = host.charAt(0) == "." ? host.substring(1, host.length) : host; - var c = { name : aCookie.name, - value : aCookie.value, - isDomain : aCookie.isDomain, - host : aCookie.host, - rawHost : aStrippedHost, - path : aCookie.path, - isSecure : aCookie.isSecure, - expires : aCookie.expires, - level : 1, - container : false }; + var c = { name : aCookie.name, + value : aCookie.value, + isDomain : aCookie.isDomain, + host : aCookie.host, + rawHost : aStrippedHost, + path : aCookie.path, + isSecure : aCookie.isSecure, + expires : aCookie.expires, + level : 1, + container : false, + originAttributes: aCookie.originAttributes }; return c; }, @@ -574,7 +581,8 @@ var gCookiesWindow = { blockFutureCookies = psvc.getBoolPref("network.cookie.blockFutureCookies"); for (var i = 0; i < deleteItems.length; ++i) { var item = deleteItems[i]; - this._cm.remove(item.host, item.name, item.path, blockFutureCookies); + this._cm.remove(item.host, item.name, item.path, + blockFutureCookies, item.originAttributes); } }, diff --git a/application/palemoon/components/preferences/sanitize.js b/application/palemoon/components/preferences/sanitize.js index 893155e62..15e6f58f4 100644 --- a/application/palemoon/components/preferences/sanitize.js +++ b/application/palemoon/components/preferences/sanitize.js @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -let gSanitizeDialog = Object.freeze({ +var gSanitizeDialog = Object.freeze({ onClearHistoryChanged: function () { let downloadsPref = document.getElementById("privacy.clearOnShutdown.downloads"); let historyPref = document.getElementById("privacy.clearOnShutdown.history"); diff --git a/application/palemoon/components/preferences/security.js b/application/palemoon/components/preferences/security.js index a337f398c..56664bf66 100644 --- a/application/palemoon/components/preferences/security.js +++ b/application/palemoon/components/preferences/security.js @@ -3,6 +3,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", + "resource://gre/modules/LoginHelper.jsm"); + Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); var gSecurityPane = { @@ -141,7 +144,7 @@ var gSecurityPane = { */ _initMasterPasswordUI: function () { - var noMP = !this._masterPasswordSet(); + var noMP = !LoginHelper.isMasterPasswordSet(); var button = document.getElementById("changeMasterPassword"); button.disabled = noMP; @@ -151,26 +154,6 @@ var gSecurityPane = { }, /** - * Returns true if the user has a master password set and false otherwise. - */ - _masterPasswordSet: function () - { - const Cc = Components.classes, Ci = Components.interfaces; - var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]. - getService(Ci.nsIPKCS11ModuleDB); - var slot = secmodDB.findSlotByName(""); - if (slot) { - var status = slot.status; - var hasMP = status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED && - status != Ci.nsIPKCS11Slot.SLOT_READY; - return hasMP; - } else { - // XXX I have no bloody idea what this means - return false; - } - }, - - /** * Enables/disables the master password button depending on the state of the * "use master password" checkbox, and prompts for master password removal if * one is set. diff --git a/application/palemoon/components/preferences/sync.js b/application/palemoon/components/preferences/sync.js index 9c7f1aa1f..f29728dbf 100644 --- a/application/palemoon/components/preferences/sync.js +++ b/application/palemoon/components/preferences/sync.js @@ -9,7 +9,7 @@ const PAGE_NO_ACCOUNT = 0; const PAGE_HAS_ACCOUNT = 1; const PAGE_NEEDS_UPDATE = 2; -let gSyncPane = { +var gSyncPane = { _stringBundle: null, prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs", "engine.tabs", "engine.history"], diff --git a/application/palemoon/components/search/content/engineManager.js b/application/palemoon/components/search/content/engineManager.js index 92b6d59b7..993d48b06 100644 --- a/application/palemoon/components/search/content/engineManager.js +++ b/application/palemoon/components/search/content/engineManager.js @@ -2,7 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", + "resource://gre/modules/PlacesUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Task", + "resource://gre/modules/Task.jsm"); const Ci = Components.interfaces; const Cc = Components.classes; @@ -105,7 +110,7 @@ var gEngineManagerDialog = { document.getElementById("engineList").focus(); }, - editKeyword: function engineManager_editKeyword() { + editKeyword: Task.async(function* engineManager_editKeyword() { var selectedEngine = gEngineView.selectedEngine; if (!selectedEngine) return; @@ -121,12 +126,8 @@ var gEngineManagerDialog = { var dupName = ""; if (alias.value != "") { - try { - let bmserv = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - if (bmserv.getURIForKeyword(alias.value)) - bduplicate = true; - } catch(ex) {} + // Check for duplicates in Places keywords. + bduplicate = !!(yield PlacesUtils.keywords.fetch(alias.value)); // Check for duplicates in changes we haven't committed yet let engines = gEngineView._engineStore.engines; @@ -154,7 +155,7 @@ var gEngineManagerDialog = { break; } } - }, + }), onSelect: function engineManager_onSelect() { // Buttons only work if an engine is selected and it's not the last engine, diff --git a/application/palemoon/components/search/content/engineManager.xul b/application/palemoon/components/search/content/engineManager.xul index 50181c066..1152ef8db 100644 --- a/application/palemoon/components/search/content/engineManager.xul +++ b/application/palemoon/components/search/content/engineManager.xul @@ -36,7 +36,7 @@ oncommand="gEngineManagerDialog.bump(-1);" disabled="true"/> <command id="cmd_editkeyword" - oncommand="gEngineManagerDialog.editKeyword();" + oncommand="gEngineManagerDialog.editKeyword().catch(Components.utils.reportError);" disabled="true"/> </commandset> diff --git a/application/palemoon/components/sessionstore/SessionStorage.jsm b/application/palemoon/components/sessionstore/SessionStorage.jsm index 192352c49..64aef35a5 100644 --- a/application/palemoon/components/sessionstore/SessionStorage.jsm +++ b/application/palemoon/components/sessionstore/SessionStorage.jsm @@ -38,7 +38,7 @@ this.SessionStorage = { Object.freeze(SessionStorage); -let DomStorage = { +var DomStorage = { /** * Reads all session storage data from the given docShell. * @param aDocShell @@ -142,7 +142,7 @@ let DomStorage = { } }; -let History = { +var History = { /** * Returns a given history entry's URI. * @param aHistory diff --git a/application/palemoon/components/sessionstore/SessionStore.jsm b/application/palemoon/components/sessionstore/SessionStore.jsm index b74e68a2f..f7c495be8 100644 --- a/application/palemoon/components/sessionstore/SessionStore.jsm +++ b/application/palemoon/components/sessionstore/SessionStore.jsm @@ -88,7 +88,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gScreenManager", // retrieved from a given docShell if not already collected before. // This is made so they're automatically in sync with all nsIDocShell.allow* // properties. -let gDocShellCapabilities = (function () { +var gDocShellCapabilities = (function () { let caps; return docShell => { @@ -106,12 +106,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", #ifdef MOZ_DEVTOOLS XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager", - "resource://gre/modules/devtools/scratchpad-manager.jsm"); + "resource://devtools/client/scratchpad/scratchpad-manager.jsm"); Object.defineProperty(this, "HUDService", { get: function HUDService_getter() { - let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; - return devtools.require("devtools/webconsole/hudservice").HUDService; + let devtools = Cu.import("resource://devtools/shared/Loader.jsm", {}).devtools; + return devtools.require("devtools/client/webconsole/hudservice").HUDService; }, configurable: true, enumerable: true @@ -247,7 +247,7 @@ this.SessionStore = { // Freeze the SessionStore object. We don't want anyone to modify it. Object.freeze(SessionStore); -let SessionStoreInternal = { +var SessionStoreInternal = { QueryInterface: XPCOMUtils.generateQI([ Ci.nsIDOMEventListener, Ci.nsIObserver, @@ -2404,7 +2404,7 @@ let SessionStoreInternal = { for (var [host, isPinned] in Iterator(internalWindow.hosts)) { let list; try { - list = Services.cookies.getCookiesFromHost(host); + list = Services.cookies.getCookiesFromHost(host, {}); } catch (ex) { debug("getCookiesFromHost failed. Host: " + host); @@ -3131,7 +3131,11 @@ let SessionStoreInternal = { // Restore the tab icon. if ("image" in tabData) { - aWindow.gBrowser.setIcon(tab, tabData.image); + // Using null as the loadingPrincipal because serializing + // the principal would be overkill. Within SetIcon we + // default to the systemPrincipal if aLoadingPrincipal is + // null which will allow the favicon to load. + aWindow.gBrowser.setIcon(tab, tabData.image, null); } if (tabData.storage && browser.docShell instanceof Ci.nsIDocShell) @@ -3651,7 +3655,7 @@ let SessionStoreInternal = { try { Services.cookies.add(cookie.host, cookie.path || "", cookie.name || "", cookie.value, !!cookie.secure, !!cookie.httponly, true, - "expiry" in cookie ? cookie.expiry : MAX_EXPIRY); + "expiry" in cookie ? cookie.expiry : MAX_EXPIRY, {}); } catch (ex) { Cu.reportError(ex); } // don't let a single cookie stop recovering } @@ -4467,7 +4471,7 @@ let SessionStoreInternal = { * pinned, visible and hidden tabs in that and FIFO order. Hidden tabs are only * restored with restore_hidden_tabs=true. */ -let TabRestoreQueue = { +var TabRestoreQueue = { // The separate buckets used to store tabs. tabs: {priority: [], visible: [], hidden: []}, @@ -4604,7 +4608,7 @@ let TabRestoreQueue = { // A map storing a closed window's state data until it goes aways (is GC'ed). // This ensures that API clients can still read (but not write) states of // windows they still hold a reference to but we don't. -let DyingWindowCache = { +var DyingWindowCache = { _data: new WeakMap(), has: function (window) { @@ -4627,7 +4631,7 @@ let DyingWindowCache = { // A set of tab attributes to persist. We will read a given list of tab // attributes when collecting tab data and will re-set those attributes when // the given tab data is restored to a new tab. -let TabAttributes = { +var TabAttributes = { _attrs: new Set(), // We never want to directly read or write those attributes. @@ -4673,7 +4677,7 @@ let TabAttributes = { // This is used to help meter the number of restoring tabs. This is the control // point for telling the next tab to restore. It gets attached to each gBrowser // via gBrowser.addTabsProgressListener -let gRestoreTabsProgressListener = { +var gRestoreTabsProgressListener = { onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) { // Ignore state changes on browsers that we've already restored and state // changes that aren't applicable. diff --git a/application/palemoon/components/sessionstore/_SessionFile.jsm b/application/palemoon/components/sessionstore/_SessionFile.jsm index 7e1b05f74..62b4d1687 100644 --- a/application/palemoon/components/sessionstore/_SessionFile.jsm +++ b/application/palemoon/components/sessionstore/_SessionFile.jsm @@ -41,7 +41,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "console", - "resource://gre/modules/devtools/Console.jsm"); + "resource://gre/modules/Console.jsm"); // An encoder to UTF-8. XPCOMUtils.defineLazyGetter(this, "gEncoder", function () { @@ -130,7 +130,7 @@ const TaskUtils = { } }; -let SessionFileInternal = { +var SessionFileInternal = { /** * A promise fulfilled once initialization is complete */ @@ -156,7 +156,10 @@ let SessionFileInternal = { let text; try { let file = new FileUtils.File(aPath); - let chan = NetUtil.newChannel(file); + let chan = NetUtil.newChannel({ + uri: NetUtil.newURI(file), + loadUsingSystemPrincipal: true + }); let stream = chan.open(); text = NetUtil.readInputStreamToString(stream, stream.available(), {charset: "utf-8"}); diff --git a/application/palemoon/components/sessionstore/nsSessionStartup.js b/application/palemoon/components/sessionstore/nsSessionStartup.js index 024246619..04037c10e 100644 --- a/application/palemoon/components/sessionstore/nsSessionStartup.js +++ b/application/palemoon/components/sessionstore/nsSessionStartup.js @@ -50,7 +50,7 @@ function debug(aMsg) { Services.console.logStringMessage(aMsg); } -let gOnceInitializedDeferred = Promise.defer(); +var gOnceInitializedDeferred = Promise.defer(); /* :::::::: The Service ::::::::::::::: */ @@ -77,9 +77,14 @@ SessionStartup.prototype = { return; } - _SessionFile.read().then( - this._onSessionFileRead.bind(this) - ); + if (Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") || + Services.prefs.getIntPref("browser.startup.page") == 3) { + this._ensureInitialized(); + } else { + _SessionFile.read().then( + this._onSessionFileRead.bind(this) + ); + } }, // Wrap a string as a nsISupports diff --git a/application/palemoon/components/shell/Makefile.in b/application/palemoon/components/shell/Makefile.in deleted file mode 100644 index df084b709..000000000 --- a/application/palemoon/components/shell/Makefile.in +++ /dev/null @@ -1,11 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/rules.mk - -CXXFLAGS += $(TK_CFLAGS) - -clobber:: - rm -f $(DIST)/lib/$(LIBRARY_NAME).lib diff --git a/application/palemoon/components/shell/ShellService.jsm b/application/palemoon/components/shell/ShellService.jsm new file mode 100644 index 000000000..74632b692 --- /dev/null +++ b/application/palemoon/components/shell/ShellService.jsm @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this file, +* You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["ShellService"]; + +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; + +Cu.import("resource://gre/modules/AppConstants.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry", + "resource://gre/modules/WindowsRegistry.jsm"); + +/** + * Internal functionality to save and restore the docShell.allow* properties. + */ +var ShellServiceInternal = { + /** + * Used to determine whether or not to offer "Set as desktop background" + * functionality. Even if shell service is available it is not + * guaranteed that it is able to set the background for every desktop + * which is especially true for Linux with its many different desktop + * environments. + */ + get canSetDesktopBackground() { + if (AppConstants.platform == "win" || + AppConstants.platform == "macosx") { + return true; + } + + if (AppConstants.platform == "linux") { + if (this.shellService) { + let linuxShellService = this.shellService + .QueryInterface(Ci.nsIGNOMEShellService); + return linuxShellService.canSetDesktopBackground; + } + } + + return false; + }, + + /** + * Used to determine whether or not to show a "Set Default Browser" + * query dialog. This attribute is true if the application is starting + * up and "browser.shell.checkDefaultBrowser" is true, otherwise it + * is false. + */ + _checkedThisSession: false, + get shouldCheckDefaultBrowser() { + // If we've already checked, the browser has been started and this is a + // new window open, and we don't want to check again. + if (this._checkedThisSession) { + return false; + } + + if (!Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser")) { + return false; + } + + if (AppConstants.platform == "win") { + let optOutValue = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, + "Software\\Mozilla\\PaleMoon", + "DefaultBrowserOptOut"); + WindowsRegistry.removeRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, + "Software\\Mozilla\\PaleMoon", + "DefaultBrowserOptOut"); + if (optOutValue == "True") { + Services.prefs.setBoolPref("browser.shell.checkDefaultBrowser", false); + return false; + } + } + + return true; + }, + + set shouldCheckDefaultBrowser(shouldCheck) { + Services.prefs.setBoolPref("browser.shell.checkDefaultBrowser", !!shouldCheck); + }, + + isDefaultBrowser(startupCheck, forAllTypes) { + // If this is the first browser window, maintain internal state that we've + // checked this session (so that subsequent window opens don't show the + // default browser dialog). + if (startupCheck) { + this._checkedThisSession = true; + } + if (this.shellService) { + return this.shellService.isDefaultBrowser(startupCheck, forAllTypes); + } + return false; + } +}; + +XPCOMUtils.defineLazyServiceGetter(ShellServiceInternal, "shellService", + "@mozilla.org/browser/shell-service;1", Ci.nsIShellService); + +/** + * The external API exported by this module. + */ +this.ShellService = new Proxy(ShellServiceInternal, { + get(target, name) { + if (name in target) { + return target[name]; + } + if (target.shellService) { + return target.shellService[name]; + } + Services.console.logStringMessage(`${name} not found in ShellService: ${target.shellService}`); + return undefined; + } +}); diff --git a/application/palemoon/components/shell/content/setDesktopBackground.js b/application/palemoon/components/shell/content/setDesktopBackground.js index e90a32d03..53cc70db0 100644 --- a/application/palemoon/components/shell/content/setDesktopBackground.js +++ b/application/palemoon/components/shell/content/setDesktopBackground.js @@ -1,16 +1,14 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Components.utils.import("resource://gre/modules/AppConstants.jsm"); var Ci = Components.interfaces; var gSetBackground = { -#ifndef XP_MACOSX - _position : "", - _backgroundColor : 0, -#else - _position : "STRETCH", -#endif + _position : AppConstants.platform == "macosx" ? "STRETCH" : "", + _backgroundColor : AppConstants.platform != "macosx" ? 0 : undefined, _screenWidth : 0, _screenHeight : 0, _image : null, @@ -27,23 +25,23 @@ var gSetBackground = { this._canvas = document.getElementById("screen"); this._screenWidth = screen.width; this._screenHeight = screen.height; -#ifdef XP_MACOSX - document.documentElement.getButton("accept").hidden = true; -#endif + if (AppConstants.platform == "macosx") { + document.documentElement.getButton("accept").hidden = true; + } if (this._screenWidth / this._screenHeight >= 1.6) document.getElementById("monitor").setAttribute("aspectratio", "16:10"); -#ifdef XP_WIN - // hide fill + fit options if <win7 since don't work - var version = Components.classes["@mozilla.org/system-info;1"] - .getService(Ci.nsIPropertyBag2) - .getProperty("version"); - var isWindows7OrHigher = (parseFloat(version) >= 6.1); - if (!isWindows7OrHigher) { - document.getElementById("fillPosition").hidden = true; - document.getElementById("fitPosition").hidden = true; + if (AppConstants.platform == "win") { + // Hide fill + fit options if < Win7 since they don't work. + var version = Components.classes["@mozilla.org/system-info;1"] + .getService(Ci.nsIPropertyBag2) + .getProperty("version"); + var isWindows7OrHigher = (parseFloat(version) >= 6.1); + if (!isWindows7OrHigher) { + document.getElementById("fillPosition").hidden = true; + document.getElementById("fitPosition").hidden = true; + } } -#endif // make sure that the correct dimensions will be used setTimeout(function(self) { @@ -62,92 +60,37 @@ var gSetBackground = { var ctx = this._canvas.getContext("2d"); ctx.scale(this._canvas.clientWidth / this._screenWidth, this._canvas.clientHeight / this._screenHeight); -#ifndef XP_MACOSX - this._initColor(); -#else - // Make sure to reset the button state in case the user has already - // set an image as their desktop background. - var setDesktopBackground = document.getElementById("setDesktopBackground"); - setDesktopBackground.hidden = false; - var bundle = document.getElementById("backgroundBundle"); - setDesktopBackground.label = bundle.getString("DesktopBackgroundSet"); - setDesktopBackground.disabled = false; - - document.getElementById("showDesktopPreferences").hidden = true; -#endif + if (AppConstants.platform != "macosx") { + this._initColor(); + } else { + // Make sure to reset the button state in case the user has already + // set an image as their desktop background. + var setDesktopBackground = document.getElementById("setDesktopBackground"); + setDesktopBackground.hidden = false; + var bundle = document.getElementById("backgroundBundle"); + setDesktopBackground.label = bundle.getString("DesktopBackgroundSet"); + setDesktopBackground.disabled = false; + + document.getElementById("showDesktopPreferences").hidden = true; + } this.updatePosition(); }, -#ifndef XP_MACOSX - _initColor: function () - { - var color = this._shell.desktopBackgroundColor; - - const rMask = 4294901760; - const gMask = 65280; - const bMask = 255; - var r = (color & rMask) >> 16; - var g = (color & gMask) >> 8; - var b = (color & bMask); - this.updateColor(this._rgbToHex(r, g, b)); - - var colorpicker = document.getElementById("desktopColor"); - colorpicker.color = this._backgroundColor; - }, - - updateColor: function (aColor) - { - this._backgroundColor = aColor; - this._canvas.style.backgroundColor = aColor; - }, - - // Converts a color string in the format "#RRGGBB" to an integer. - _hexStringToLong: function (aString) - { - return parseInt(aString.substring(1,3), 16) << 16 | - parseInt(aString.substring(3,5), 16) << 8 | - parseInt(aString.substring(5,7), 16); - }, - - _rgbToHex: function (aR, aG, aB) - { - return "#" + [aR, aG, aB].map(function(aInt) aInt.toString(16).replace(/^(.)$/, "0$1")) - .join("").toUpperCase(); - }, -#else - observe: function (aSubject, aTopic, aData) + setDesktopBackground: function () { - if (aTopic == "shell:desktop-background-changed") { - document.getElementById("setDesktopBackground").hidden = true; - document.getElementById("showDesktopPreferences").hidden = false; - + if (AppConstants.platform != "macosx") { + document.persist("menuPosition", "value"); + this._shell.desktopBackgroundColor = this._hexStringToLong(this._backgroundColor); + } else { Components.classes["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService) - .removeObserver(this, "shell:desktop-background-changed"); - } - }, - - showDesktopPrefs: function() - { - this._shell.openApplication(Ci.nsIMacShellService.APPLICATION_DESKTOP); - }, -#endif + .addObserver(this, "shell:desktop-background-changed", false); - setDesktopBackground: function () - { -#ifndef XP_MACOSX - document.persist("menuPosition", "value"); - this._shell.desktopBackgroundColor = this._hexStringToLong(this._backgroundColor); -#else - Components.classes["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService) - .addObserver(this, "shell:desktop-background-changed", false); - - var bundle = document.getElementById("backgroundBundle"); - var setDesktopBackground = document.getElementById("setDesktopBackground"); - setDesktopBackground.disabled = true; - setDesktopBackground.label = bundle.getString("DesktopBackgroundDownloading"); -#endif + var bundle = document.getElementById("backgroundBundle"); + var setDesktopBackground = document.getElementById("setDesktopBackground"); + setDesktopBackground.disabled = true; + setDesktopBackground.label = bundle.getString("DesktopBackgroundDownloading"); + } this._shell.setDesktopBackground(this._image, Ci.nsIShellService["BACKGROUND_" + this._position]); }, @@ -157,9 +100,9 @@ var gSetBackground = { var ctx = this._canvas.getContext("2d"); ctx.clearRect(0, 0, this._screenWidth, this._screenHeight); -#ifndef XP_MACOSX - this._position = document.getElementById("menuPosition").value; -#endif + if (AppConstants.platform != "macosx") { + this._position = document.getElementById("menuPosition").value; + } switch (this._position) { case "TILE": @@ -171,43 +114,101 @@ var gSetBackground = { case "STRETCH": ctx.drawImage(this._image, 0, 0, this._screenWidth, this._screenHeight); break; - case "CENTER": - var x = (this._screenWidth - this._image.naturalWidth) / 2; - var y = (this._screenHeight - this._image.naturalHeight) / 2; + case "CENTER": { + let x = (this._screenWidth - this._image.naturalWidth) / 2; + let y = (this._screenHeight - this._image.naturalHeight) / 2; ctx.drawImage(this._image, x, y); break; - case "FILL": - //Try maxing width first, overflow height - var widthRatio = this._screenWidth / this._image.naturalWidth; - var width = this._image.naturalWidth * widthRatio; - var height = this._image.naturalHeight * widthRatio; + } + case "FILL": { + // Try maxing width first, overflow height. + let widthRatio = this._screenWidth / this._image.naturalWidth; + let width = this._image.naturalWidth * widthRatio; + let height = this._image.naturalHeight * widthRatio; if (height < this._screenHeight) { - //height less than screen, max height and overflow width - var heightRatio = this._screenHeight / this._image.naturalHeight; + // Height less than screen, max height and overflow width. + let heightRatio = this._screenHeight / this._image.naturalHeight; width = this._image.naturalWidth * heightRatio; height = this._image.naturalHeight * heightRatio; } - var x = (this._screenWidth - width) / 2; - var y = (this._screenHeight - height) / 2; + let x = (this._screenWidth - width) / 2; + let y = (this._screenHeight - height) / 2; ctx.drawImage(this._image, x, y, width, height); break; - case "FIT": - //Try maxing width first, top and bottom borders - var widthRatio = this._screenWidth / this._image.naturalWidth; - var width = this._image.naturalWidth * widthRatio; - var height = this._image.naturalHeight * widthRatio; - var x = 0; - var y = (this._screenHeight - height) / 2; + } + case "FIT": { + // Try maxing width first, top and bottom borders. + let widthRatio = this._screenWidth / this._image.naturalWidth; + let width = this._image.naturalWidth * widthRatio; + let height = this._image.naturalHeight * widthRatio; + let x = 0; + let y = (this._screenHeight - height) / 2; if (height > this._screenHeight) { - //height overflow, maximise height, side borders - var heightRatio = this._screenHeight / this._image.naturalHeight; + // Height overflow, maximise height, side borders. + let heightRatio = this._screenHeight / this._image.naturalHeight; width = this._image.naturalWidth * heightRatio; height = this._image.naturalHeight * heightRatio; x = (this._screenWidth - width) / 2; y = 0; } ctx.drawImage(this._image, x, y, width, height); - break; + break; + } } } }; + +if (AppConstants.platform != "macosx") { + gSetBackground["_initColor"] = function () + { + var color = this._shell.desktopBackgroundColor; + + const rMask = 4294901760; + const gMask = 65280; + const bMask = 255; + var r = (color & rMask) >> 16; + var g = (color & gMask) >> 8; + var b = (color & bMask); + this.updateColor(this._rgbToHex(r, g, b)); + + var colorpicker = document.getElementById("desktopColor"); + colorpicker.color = this._backgroundColor; + }; + + gSetBackground["updateColor"] = function (aColor) + { + this._backgroundColor = aColor; + this._canvas.style.backgroundColor = aColor; + }; + + // Converts a color string in the format "#RRGGBB" to an integer. + gSetBackground["_hexStringToLong"] = function (aString) + { + return parseInt(aString.substring(1, 3), 16) << 16 | + parseInt(aString.substring(3, 5), 16) << 8 | + parseInt(aString.substring(5, 7), 16); + }; + + gSetBackground["_rgbToHex"] = function (aR, aG, aB) + { + return "#" + [aR, aG, aB].map(aInt => aInt.toString(16).replace(/^(.)$/, "0$1")) + .join("").toUpperCase(); + }; +} else { + gSetBackground["observe"] = function (aSubject, aTopic, aData) + { + if (aTopic == "shell:desktop-background-changed") { + document.getElementById("setDesktopBackground").hidden = true; + document.getElementById("showDesktopPreferences").hidden = false; + + Components.classes["@mozilla.org/observer-service;1"] + .getService(Ci.nsIObserverService) + .removeObserver(this, "shell:desktop-background-changed"); + } + }; + + gSetBackground["showDesktopPrefs"] = function() + { + this._shell.openApplication(Ci.nsIMacShellService.APPLICATION_DESKTOP); + }; +} diff --git a/application/palemoon/components/shell/jar.mn b/application/palemoon/components/shell/jar.mn index eed15c397..1f33b5d56 100644 --- a/application/palemoon/components/shell/jar.mn +++ b/application/palemoon/components/shell/jar.mn @@ -4,4 +4,4 @@ browser.jar: * content/browser/setDesktopBackground.xul (content/setDesktopBackground.xul) -* content/browser/setDesktopBackground.js (content/setDesktopBackground.js) + content/browser/setDesktopBackground.js (content/setDesktopBackground.js) diff --git a/application/palemoon/components/shell/moz.build b/application/palemoon/components/shell/moz.build index 38965c5d7..94ec88571 100644 --- a/application/palemoon/components/shell/moz.build +++ b/application/palemoon/components/shell/moz.build @@ -1,4 +1,4 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -18,6 +18,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': XPIDL_SOURCES += [ 'nsIMacShellService.idl', ] +elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: + XPIDL_SOURCES += [ + 'nsIGNOMEShellService.idl', + ] XPIDL_MODULE = 'shellservice' @@ -29,7 +33,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': SOURCES += [ 'nsMacShellService.cpp', ] -elif CONFIG['MOZ_WIDGET_GTK']: +elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: SOURCES += [ 'nsGNOMEShellService.cpp', ] @@ -42,6 +46,10 @@ EXTRA_COMPONENTS += [ 'nsSetDefaultBrowser.manifest', ] +EXTRA_JS_MODULES += [ + 'ShellService.jsm', +] + for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION'): DEFINES[var] = '"%s"' % CONFIG[var] diff --git a/application/palemoon/components/shell/nsGNOMEShellService.cpp b/application/palemoon/components/shell/nsGNOMEShellService.cpp index 14510d111..9bc5f5913 100644 --- a/application/palemoon/components/shell/nsGNOMEShellService.cpp +++ b/application/palemoon/components/shell/nsGNOMEShellService.cpp @@ -21,12 +21,13 @@ #include "nsIStringBundle.h" #include "nsIOutputStream.h" #include "nsIProcess.h" -#include "nsNetUtil.h" +#include "nsServiceManagerUtils.h" +#include "nsComponentManagerUtils.h" #include "nsIDOMHTMLImageElement.h" #include "nsIImageLoadingContent.h" #include "imgIRequest.h" #include "imgIContainer.h" -#include "prprf.h" +#include "mozilla/Sprintf.h" #if defined(MOZ_WIDGET_GTK) #include "nsIImageToPixbuf.h" #endif @@ -116,7 +117,7 @@ nsGNOMEShellService::Init() return appPath->GetNativePath(mAppPath); } -NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIShellService) +NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIGNOMEShellService, nsIShellService) bool nsGNOMEShellService::GetAppPathFromLauncher() @@ -152,7 +153,8 @@ nsGNOMEShellService::KeyMatchesAppName(const char *aKeyValue) const gchar *commandPath; if (mUseLocaleFilenames) { - gchar *nativePath = g_filename_from_utf8(aKeyValue, -1, nullptr, nullptr, nullptr); + gchar *nativePath = g_filename_from_utf8(aKeyValue, -1, + nullptr, nullptr, nullptr); if (!nativePath) { NS_ERROR("Error converting path to filesystem encoding"); return false; @@ -199,8 +201,6 @@ nsGNOMEShellService::IsDefaultBrowser(bool aStartupCheck, bool* aIsDefaultBrowser) { *aIsDefaultBrowser = false; - if (aStartupCheck) - mCheckedThisSession = true; nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); @@ -284,7 +284,7 @@ nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes, NS_ENSURE_SUCCESS(rv, rv); nsString brandShortName; - brandBundle->GetStringFromName(MOZ_UTF16("brandShortName"), + brandBundle->GetStringFromName(u"brandShortName", getter_Copies(brandShortName)); // use brandShortName as the application id. @@ -312,41 +312,14 @@ nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes, } } - return NS_OK; -} - -NS_IMETHODIMP -nsGNOMEShellService::GetShouldCheckDefaultBrowser(bool* aResult) -{ - // If we've already checked, the browser has been started and this is a - // new window open, and we don't want to check again. - if (mCheckedThisSession) { - *aResult = false; - return NS_OK; + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + // Reset the number of times the dialog should be shown + // before it is silenced. + (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0); } - nsCOMPtr<nsIPrefBranch> prefs; - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); - - if (prefs) - prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); - - return NS_OK; -} - -NS_IMETHODIMP -nsGNOMEShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) -{ - nsCOMPtr<nsIPrefBranch> prefs; - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); - - if (prefs) - prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); - return NS_OK; } @@ -386,7 +359,7 @@ WriteImage(const nsCString& aPath, imgIContainer* aImage) return res ? NS_OK : NS_ERROR_FAILURE; #endif } - + NS_IMETHODIMP nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, int32_t aPosition) @@ -407,15 +380,15 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, // Set desktop wallpaper filling style nsAutoCString options; if (aPosition == BACKGROUND_TILE) - options.Assign("wallpaper"); + options.AssignLiteral("wallpaper"); else if (aPosition == BACKGROUND_STRETCH) - options.Assign("stretched"); + options.AssignLiteral("stretched"); else if (aPosition == BACKGROUND_FILL) - options.Assign("zoom"); + options.AssignLiteral("zoom"); else if (aPosition == BACKGROUND_FIT) - options.Assign("scaled"); + options.AssignLiteral("scaled"); else - options.Assign("centered"); + options.AssignLiteral("centered"); // Write the background file to the home directory. nsAutoCString filePath(PR_GetEnv("HOME")); @@ -429,7 +402,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle)); if (NS_SUCCEEDED(rv) && brandBundle) { - rv = brandBundle->GetStringFromName(MOZ_UTF16("brandShortName"), + rv = brandBundle->GetStringFromName(u"brandShortName", getter_Copies(brandName)); NS_ENSURE_SUCCESS(rv, rv); } @@ -438,7 +411,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, // build the file name filePath.Append('/'); filePath.Append(NS_ConvertUTF16toUTF8(brandName)); - filePath.Append("_wallpaper.png"); + filePath.AppendLiteral("_wallpaper.png"); // write the image to a file in the home dir rv = WriteImage(filePath, container); @@ -478,7 +451,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement, // Set the image to an empty string first to force a refresh // (since we could be writing a new image on top of an existing - // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) + // PaleMoon_wallpaper.png and nautilus doesn't monitor the file for changes) gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), EmptyCString()); @@ -543,7 +516,7 @@ ColorToCString(uint32_t aColor, nsCString& aResult) uint16_t green = COLOR_8_TO_16_BIT((aColor >> 8) & 0xff); uint16_t blue = COLOR_8_TO_16_BIT(aColor & 0xff); - PR_snprintf(buf, 14, "#%04x%04x%04x", red, green, blue); + snprintf(buf, 14, "#%04x%04x%04x", red, green, blue); } NS_IMETHODIMP @@ -580,9 +553,9 @@ nsGNOMEShellService::OpenApplication(int32_t aApplication) { nsAutoCString scheme; if (aApplication == APPLICATION_MAIL) - scheme.Assign("mailto"); + scheme.AssignLiteral("mailto"); else if (aApplication == APPLICATION_NEWS) - scheme.Assign("news"); + scheme.AssignLiteral("news"); else return NS_ERROR_NOT_AVAILABLE; diff --git a/application/palemoon/components/shell/nsGNOMEShellService.h b/application/palemoon/components/shell/nsGNOMEShellService.h index 36a4a0c42..a7b003802 100644 --- a/application/palemoon/components/shell/nsGNOMEShellService.h +++ b/application/palemoon/components/shell/nsGNOMEShellService.h @@ -6,28 +6,28 @@ #ifndef nsgnomeshellservice_h____ #define nsgnomeshellservice_h____ -#include "nsIShellService.h" +#include "nsIGNOMEShellService.h" #include "nsStringAPI.h" #include "mozilla/Attributes.h" -class nsGNOMEShellService final : public nsIShellService +class nsGNOMEShellService final : public nsIGNOMEShellService { public: - nsGNOMEShellService() : mCheckedThisSession(false), mAppIsInPath(false) { } + nsGNOMEShellService() : mAppIsInPath(false) { } NS_DECL_ISUPPORTS NS_DECL_NSISHELLSERVICE + NS_DECL_NSIGNOMESHELLSERVICE - nsresult Init() NS_HIDDEN; + nsresult Init(); private: ~nsGNOMEShellService() {} - NS_HIDDEN_(bool) KeyMatchesAppName(const char *aKeyValue) const; - NS_HIDDEN_(bool) CheckHandlerMatchesAppName(const nsACString& handler) const; + bool KeyMatchesAppName(const char *aKeyValue) const; + bool CheckHandlerMatchesAppName(const nsACString& handler) const; - NS_HIDDEN_(bool) GetAppPathFromLauncher(); - bool mCheckedThisSession; + bool GetAppPathFromLauncher(); bool mUseLocaleFilenames; nsCString mAppPath; bool mAppIsInPath; diff --git a/application/palemoon/components/shell/nsIGNOMEShellService.idl b/application/palemoon/components/shell/nsIGNOMEShellService.idl new file mode 100644 index 000000000..842ce5e8a --- /dev/null +++ b/application/palemoon/components/shell/nsIGNOMEShellService.idl @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIShellService.idl" + +[scriptable, uuid(2ce5c803-edcd-443d-98eb-ceba86d02d13)] +interface nsIGNOMEShellService : nsIShellService +{ + /** + * Used to determine whether or not to offer "Set as desktop background" + * functionality. Even if shell service is available it is not + * guaranteed that it is able to set the background for every desktop + * which is especially true for Linux with its many different desktop + * environments. + */ + readonly attribute boolean canSetDesktopBackground; +}; + diff --git a/application/palemoon/components/shell/nsIMacShellService.idl b/application/palemoon/components/shell/nsIMacShellService.idl index 3c2f42315..6a532bbd0 100644 --- a/application/palemoon/components/shell/nsIMacShellService.idl +++ b/application/palemoon/components/shell/nsIMacShellService.idl @@ -5,7 +5,7 @@ #include "nsIShellService.idl" -[scriptable, uuid(7f8ca08e-1df4-4735-86e9-50dedb48e5e8)] +[scriptable, uuid(387fdc80-0077-4b60-a0d9-d9e80a83ba64)] interface nsIMacShellService : nsIShellService { const long APPLICATION_KEYCHAIN_ACCESS = 2; diff --git a/application/palemoon/components/shell/nsIShellService.idl b/application/palemoon/components/shell/nsIShellService.idl index 4825741b3..3e7e94b00 100644 --- a/application/palemoon/components/shell/nsIShellService.idl +++ b/application/palemoon/components/shell/nsIShellService.idl @@ -8,7 +8,7 @@ interface nsIDOMElement; interface nsIFile; -[scriptable, uuid(99d2e9f1-3c86-40f7-81fd-3060c18489f0)] +[scriptable, uuid(2d1a95e4-5bd8-4eeb-b0a8-c1455fd2a357)] interface nsIShellService : nsISupports { /** @@ -39,23 +39,6 @@ interface nsIShellService : nsISupports void setDefaultBrowser(in boolean aClaimAllTypes, in boolean aForAllUsers); /** - * Used to determine whether or not to show a "Set Default Browser" - * query dialog. This attribute is true if the application is starting - * up and "browser.shell.checkDefaultBrowser" is true, otherwise it - * is false. - */ - attribute boolean shouldCheckDefaultBrowser; - - /** - * Used to determine whether or not to offer "Set as desktop background" - * functionality. Even if shell service is available it is not - * guaranteed that it is able to set the background for every desktop - * which is especially true for Linux with its many different desktop - * environments. - */ - readonly attribute boolean canSetDesktopBackground; - - /** * Flags for positioning/sizing of the Desktop Background image. */ const long BACKGROUND_TILE = 1; diff --git a/application/palemoon/components/shell/nsIWindowsShellService.idl b/application/palemoon/components/shell/nsIWindowsShellService.idl index 913eb4292..57ed37055 100644 --- a/application/palemoon/components/shell/nsIWindowsShellService.idl +++ b/application/palemoon/components/shell/nsIWindowsShellService.idl @@ -5,7 +5,7 @@ #include "nsIShellService.idl" -[scriptable, uuid(89b0a761-d9a0-4c39-ab83-d81566459a31)] +[scriptable, uuid(f8a26b94-49e5-4441-8fbc-315e0b4f22ef)] interface nsIWindowsShellService : nsIShellService { /** diff --git a/application/palemoon/components/shell/nsMacShellService.cpp b/application/palemoon/components/shell/nsMacShellService.cpp index 914b9ae65..d8d64039d 100644 --- a/application/palemoon/components/shell/nsMacShellService.cpp +++ b/application/palemoon/components/shell/nsMacShellService.cpp @@ -17,13 +17,13 @@ #include "nsIURL.h" #include "nsIWebBrowserPersist.h" #include "nsMacShellService.h" -#include "nsNetUtil.h" +#include "nsIProperties.h" +#include "nsServiceManagerUtils.h" #include "nsShellService.h" #include "nsStringAPI.h" #include "nsIDocShell.h" #include "nsILoadContext.h" - #include <CoreFoundation/CoreFoundation.h> #include <ApplicationServices/ApplicationServices.h> @@ -49,19 +49,14 @@ nsMacShellService::IsDefaultBrowser(bool aStartupCheck, return NS_ERROR_FAILURE; } - // Get the default http handler's bundle ID (or nullptr if it has not been explicitly set) + // Get the default http handler's bundle ID (or nullptr if it has not been + // explicitly set) CFStringRef defaultBrowserID = ::LSCopyDefaultHandlerForURLScheme(CFSTR("http")); if (defaultBrowserID) { *aIsDefaultBrowser = ::CFStringCompare(firefoxID, defaultBrowserID, 0) == kCFCompareEqualTo; ::CFRelease(defaultBrowserID); } - // If this is the first browser window, maintain internal state that we've - // checked this session (so that subsequent window opens don't show the - // default browser dialog). - if (aStartupCheck) - mCheckedThisSession = true; - return NS_OK; } @@ -90,47 +85,15 @@ nsMacShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) return NS_ERROR_FAILURE; } } - - return NS_OK; -} -NS_IMETHODIMP -nsMacShellService::GetShouldCheckDefaultBrowser(bool* aResult) -{ - // If we've already checked, the browser has been started and this is a - // new window open, and we don't want to check again. - if (mCheckedThisSession) { - *aResult = false; - return NS_OK; + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + // Reset the number of times the dialog should be shown + // before it is silenced. + (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0); } - nsCOMPtr<nsIPrefBranch> prefs; - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); - - prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); - - return NS_OK; -} - -NS_IMETHODIMP -nsMacShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) -{ - nsCOMPtr<nsIPrefBranch> prefs; - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); - - prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); - - return NS_OK; -} - -NS_IMETHODIMP -nsMacShellService::GetCanSetDesktopBackground(bool* aResult) -{ - *aResult = true; return NS_OK; } @@ -202,8 +165,10 @@ nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement, loadContext = do_QueryInterface(docShell); } - return wbp->SaveURI(imageURI, nullptr, docURI, content->OwnerDoc()->GetReferrerPolicy(), - nullptr, nullptr, mBackgroundFile, loadContext); + return wbp->SaveURI(imageURI, nullptr, + docURI, content->OwnerDoc()->GetReferrerPolicy(), + nullptr, nullptr, + mBackgroundFile, loadContext); } NS_IMETHODIMP @@ -269,7 +234,8 @@ nsMacShellService::OnStateChange(nsIWebProgress* aWebProgress, OSStatus status; // Convert the path into a FSRef - status = ::FSPathMakeRef((const UInt8*)nativePath.get(), &pictureRef, nullptr); + status = ::FSPathMakeRef((const UInt8*)nativePath.get(), &pictureRef, + nullptr); if (status == noErr) { err = ::FSNewAlias(nil, &pictureRef, &aliasHandle); if (err == noErr && aliasHandle == nil) @@ -336,8 +302,8 @@ nsMacShellService::OpenApplication(int32_t aApplication) } break; case nsIMacShellService::APPLICATION_KEYCHAIN_ACCESS: - err = ::LSGetApplicationForInfo('APPL', 'kcmr', nullptr, kLSRolesAll, nullptr, - &appURL); + err = ::LSGetApplicationForInfo('APPL', 'kcmr', nullptr, kLSRolesAll, + nullptr, &appURL); break; case nsIMacShellService::APPLICATION_NETWORK: { @@ -349,8 +315,7 @@ nsMacShellService::OpenApplication(int32_t aApplication) if (!exists) return NS_ERROR_FILE_NOT_FOUND; return lf->Launch(); - } - break; + } case nsIMacShellService::APPLICATION_DESKTOP: { nsCOMPtr<nsIFile> lf; @@ -361,8 +326,7 @@ nsMacShellService::OpenApplication(int32_t aApplication) if (!exists) return NS_ERROR_FILE_NOT_FOUND; return lf->Launch(); - } - break; + } } if (appURL && err == noErr) { diff --git a/application/palemoon/components/shell/nsMacShellService.h b/application/palemoon/components/shell/nsMacShellService.h index 7ca1c71ac..db9527809 100644 --- a/application/palemoon/components/shell/nsMacShellService.h +++ b/application/palemoon/components/shell/nsMacShellService.h @@ -15,7 +15,7 @@ class nsMacShellService : public nsIMacShellService, public nsIWebProgressListener { public: - nsMacShellService() : mCheckedThisSession(false) {}; + nsMacShellService() {}; NS_DECL_ISUPPORTS NS_DECL_NSISHELLSERVICE @@ -27,8 +27,6 @@ protected: private: nsCOMPtr<nsIFile> mBackgroundFile; - - bool mCheckedThisSession; }; #endif // nsmacshellservice_h____ diff --git a/application/palemoon/components/shell/nsSetDefaultBrowser.js b/application/palemoon/components/shell/nsSetDefaultBrowser.js index d1d1e72cb..c7a78c538 100644 --- a/application/palemoon/components/shell/nsSetDefaultBrowser.js +++ b/application/palemoon/components/shell/nsSetDefaultBrowser.js @@ -2,13 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * -setDefaultBrowser commandline handler +/* + * --setDefaultBrowser commandline handler * Makes the current executable the "default browser". */ const Cc = Components.classes; const Ci = Components.interfaces; +Components.utils.import("resource:///modules/ShellService.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); function nsSetDefaultBrowser() {} @@ -16,13 +17,11 @@ function nsSetDefaultBrowser() {} nsSetDefaultBrowser.prototype = { handle: function nsSetDefault_handle(aCmdline) { if (aCmdline.handleFlag("setDefaultBrowser", false)) { - var shell = Cc["@mozilla.org/browser/shell-service;1"]. - getService(Ci.nsIShellService); - shell.setDefaultBrowser(true, true); + ShellService.setDefaultBrowser(true, true); } }, - helpInfo: " -setDefaultBrowser Set this app as the default browser.\n", + helpInfo: " --setDefaultBrowser Set this app as the default browser.\n", classID: Components.ID("{F57899D0-4E2C-4ac6-9E29-50C736103B0C}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]), diff --git a/application/palemoon/components/shell/nsShellService.h b/application/palemoon/components/shell/nsShellService.h index d5fade37b..516a8423a 100644 --- a/application/palemoon/components/shell/nsShellService.h +++ b/application/palemoon/components/shell/nsShellService.h @@ -4,6 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #define PREF_CHECKDEFAULTBROWSER "browser.shell.checkDefaultBrowser" +#define PREF_SKIPDEFAULTBROWSERCHECK "browser.shell.skipDefaultBrowserCheck" +#define PREF_DEFAULTBROWSERCHECKCOUNT "browser.shell.defaultBrowserCheckCount" #define SHELLSERVICE_PROPERTIES "chrome://browser/locale/shellservice.properties" #define BRAND_PROPERTIES "chrome://branding/locale/brand.properties" diff --git a/application/palemoon/components/shell/nsWindowsShellService.cpp b/application/palemoon/components/shell/nsWindowsShellService.cpp index 813ec4fe1..c4039b95a 100644 --- a/application/palemoon/components/shell/nsWindowsShellService.cpp +++ b/application/palemoon/components/shell/nsWindowsShellService.cpp @@ -3,6 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsWindowsShellService.h" + #include "imgIContainer.h" #include "imgIRequest.h" #include "mozilla/gfx/2D.h" @@ -15,8 +17,8 @@ #include "nsIServiceManager.h" #include "nsIStringBundle.h" #include "nsNetUtil.h" +#include "nsServiceManagerUtils.h" #include "nsShellService.h" -#include "nsWindowsShellService.h" #include "nsIProcess.h" #include "nsICategoryManager.h" #include "nsBrowserCompsCID.h" @@ -27,6 +29,7 @@ #include "nsUnicharUtils.h" #include "nsIWinTaskbar.h" #include "nsISupportsPrimitives.h" +#include "nsIURLFormatter.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" #include "mozilla/WindowsVersion.h" @@ -47,6 +50,9 @@ #include <mbstring.h> #include <shlwapi.h> +#include <lm.h> +#undef ACCESS_READ + #ifndef MAX_BUF #define MAX_BUF 4096 #endif @@ -129,7 +135,7 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey) // The following keys are set to make PaleMoon appear in the Start Menu as the // browser: // -// HKCU\SOFTWARE\Clients\StartMenuInternet\FIREFOX.EXE\ +// HKCU\SOFTWARE\Clients\StartMenuInternet\PaleMoon.EXE\ // (default) REG_SZ <appname> // DefaultIcon (default) REG_SZ <apppath>,0 // InstallInfo HideIconsCommand REG_SZ <uninstpath> /HideShortcuts @@ -278,20 +284,15 @@ nsWindowsShellService::ShortcutMaintenance() return NS_ERROR_UNEXPECTED; NS_NAMED_LITERAL_CSTRING(prefName, "browser.taskbar.lastgroupid"); - nsCOMPtr<nsIPrefService> prefs = + nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (!prefs) return NS_ERROR_UNEXPECTED; - nsCOMPtr<nsIPrefBranch> prefBranch; - prefs->GetBranch(nullptr, getter_AddRefs(prefBranch)); - if (!prefBranch) - return NS_ERROR_UNEXPECTED; - nsCOMPtr<nsISupportsString> prefString; - rv = prefBranch->GetComplexValue(prefName.get(), - NS_GET_IID(nsISupportsString), - getter_AddRefs(prefString)); + rv = prefs->GetComplexValue(prefName.get(), + NS_GET_IID(nsISupportsString), + getter_AddRefs(prefString)); if (NS_SUCCEEDED(rv)) { nsAutoString version; prefString->GetData(version); @@ -307,9 +308,9 @@ nsWindowsShellService::ShortcutMaintenance() return rv; prefString->SetData(appId); - rv = prefBranch->SetComplexValue(prefName.get(), - NS_GET_IID(nsISupportsString), - prefString); + rv = prefs->SetComplexValue(prefName.get(), + NS_GET_IID(nsISupportsString), + prefString); if (NS_FAILED(rv)) { NS_WARNING("Couldn't set last user model id!"); return NS_ERROR_UNEXPECTED; @@ -325,38 +326,47 @@ nsWindowsShellService::ShortcutMaintenance() } static bool -IsAARDefaultHTTP(IApplicationAssociationRegistration* pAAR, - bool* aIsDefaultBrowser) +IsAARDefault(const RefPtr<IApplicationAssociationRegistration>& pAAR, + LPCWSTR aClassName) { // Make sure the Prog ID matches what we have LPWSTR registeredApp; - HRESULT hr = pAAR->QueryCurrentDefault(L"http", AT_URLPROTOCOL, AL_EFFECTIVE, + bool isProtocol = *aClassName != L'.'; + ASSOCIATIONTYPE queryType = isProtocol ? AT_URLPROTOCOL : AT_FILEEXTENSION; + HRESULT hr = pAAR->QueryCurrentDefault(aClassName, queryType, AL_EFFECTIVE, ®isteredApp); - if (SUCCEEDED(hr)) { - LPCWSTR firefoxHTTPProgID = L"PaleMoonURL"; - *aIsDefaultBrowser = !wcsicmp(registeredApp, firefoxHTTPProgID); - CoTaskMemFree(registeredApp); - } else { - *aIsDefaultBrowser = false; + if (FAILED(hr)) { + return false; } - return SUCCEEDED(hr); + + LPCWSTR progID = isProtocol ? L"PaleMoonURL" : L"PaleMoonHTML"; + bool isDefault = !wcsicmp(registeredApp, progID); + CoTaskMemFree(registeredApp); + + return isDefault; } -static bool -IsAARDefaultHTML(IApplicationAssociationRegistration* pAAR, - bool* aIsDefaultBrowser) +static void +IsDefaultBrowserWin8(bool aCheckAllTypes, bool* aIsDefaultBrowser) { - LPWSTR registeredApp; - HRESULT hr = pAAR->QueryCurrentDefault(L".html", AT_FILEEXTENSION, AL_EFFECTIVE, - ®isteredApp); - if (SUCCEEDED(hr)) { - LPCWSTR firefoxHTMLProgID = L"PaleMoonHTML"; - *aIsDefaultBrowser = !wcsicmp(registeredApp, firefoxHTMLProgID); - CoTaskMemFree(registeredApp); - } else { - *aIsDefaultBrowser = false; + RefPtr<IApplicationAssociationRegistration> pAAR; + HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, + nullptr, + CLSCTX_INPROC, + IID_IApplicationAssociationRegistration, + getter_AddRefs(pAAR)); + if (FAILED(hr)) { + return; + } + + bool res = IsAARDefault(pAAR, L"http"); + if (*aIsDefaultBrowser) { + *aIsDefaultBrowser = res; + } + res = IsAARDefault(pAAR, L".html"); + if (*aIsDefaultBrowser && aCheckAllTypes) { + *aIsDefaultBrowser = res; } - return SUCCEEDED(hr); } /* @@ -369,37 +379,27 @@ bool nsWindowsShellService::IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser) { - IApplicationAssociationRegistration* pAAR; + RefPtr<IApplicationAssociationRegistration> pAAR; HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, nullptr, CLSCTX_INPROC, IID_IApplicationAssociationRegistration, - (void**)&pAAR); - - if (SUCCEEDED(hr)) { - if (aCheckAllTypes) { - BOOL res; - hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE, - APP_REG_NAME, - &res); - *aIsDefaultBrowser = res; - - // If we have all defaults, let's make sure that our ProgID - // is explicitly returned as well. Needed only for Windows 8. - if (*aIsDefaultBrowser && IsWin8OrLater()) { - IsAARDefaultHTTP(pAAR, aIsDefaultBrowser); - if (*aIsDefaultBrowser) { - IsAARDefaultHTML(pAAR, aIsDefaultBrowser); - } - } - } else { - IsAARDefaultHTTP(pAAR, aIsDefaultBrowser); - } + getter_AddRefs(pAAR)); + if (FAILED(hr)) { + return false; + } - pAAR->Release(); - return true; + if (aCheckAllTypes) { + BOOL res; + hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE, + APP_REG_NAME, + &res); + *aIsDefaultBrowser = res; + } else if (!IsWin8OrLater()) { + *aIsDefaultBrowser = IsAARDefault(pAAR, L"http"); } - return false; + + return true; } NS_IMETHODIMP @@ -407,12 +407,6 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck, bool aForAllTypes, bool* aIsDefaultBrowser) { - // If this is the first browser window, maintain internal state that we've - // checked this session (so that subsequent window opens don't show the - // default browser dialog). - if (aStartupCheck) - mCheckedThisSession = true; - // Assume we're the default unless one of the several checks below tell us // otherwise. *aIsDefaultBrowser = true; @@ -499,6 +493,9 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck, // previous checks show that PaleMoon is the default browser. if (*aIsDefaultBrowser) { IsDefaultBrowserVista(aForAllTypes, aIsDefaultBrowser); + if (IsWin8OrLater()) { + IsDefaultBrowserWin8(aForAllTypes, aIsDefaultBrowser); + } } // To handle the case where DDE isn't disabled due for a user because there @@ -603,13 +600,6 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck, return NS_OK; } -NS_IMETHODIMP -nsWindowsShellService::GetCanSetDesktopBackground(bool* aResult) -{ - *aResult = true; - return NS_OK; -} - static nsresult DynSHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo) { @@ -628,14 +618,34 @@ DynSHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo) return NS_ERROR_FAILURE; } - nsresult rv = - SUCCEEDED(SHOpenWithDialogFn(hwndParent, poainfo)) ? NS_OK : - NS_ERROR_FAILURE; + nsresult rv; + HRESULT hr = SHOpenWithDialogFn(hwndParent, poainfo); + if (SUCCEEDED(hr) || (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))) { + rv = NS_OK; + } else { + rv = NS_ERROR_FAILURE; + } FreeLibrary(shellDLL); return rv; } nsresult +nsWindowsShellService::LaunchControlPanelDefaultsSelectionUI() +{ + IApplicationAssociationRegistrationUI* pAARUI; + HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistrationUI, + NULL, + CLSCTX_INPROC, + IID_IApplicationAssociationRegistrationUI, + (void**)&pAARUI); + if (SUCCEEDED(hr)) { + hr = pAARUI->LaunchAdvancedAssociationUI(APP_REG_NAME); + pAARUI->Release(); + } + return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; +} + +nsresult nsWindowsShellService::LaunchControlPanelDefaultPrograms() { // Build the path control.exe path safely @@ -651,7 +661,8 @@ nsWindowsShellService::LaunchControlPanelDefaultPrograms() return NS_ERROR_FAILURE; } - WCHAR params[] = L"control.exe /name Microsoft.DefaultPrograms /page pageDefaultProgram"; + WCHAR params[] = L"control.exe /name Microsoft.DefaultPrograms /page " + "pageDefaultProgram\\pageAdvancedSettings?pszAppName=" APP_REG_NAME; STARTUPINFOW si = {sizeof(si), 0}; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWDEFAULT; @@ -666,9 +677,62 @@ nsWindowsShellService::LaunchControlPanelDefaultPrograms() return NS_OK; } +static bool +IsWindowsLogonConnected() +{ + WCHAR userName[UNLEN + 1]; + DWORD size = ArrayLength(userName); + if (!GetUserNameW(userName, &size)) { + return false; + } + + LPUSER_INFO_24 info; + if (NetUserGetInfo(nullptr, userName, 24, (LPBYTE *)&info) + != NERR_Success) { + return false; + } + bool connected = info->usri24_internet_identity; + NetApiBufferFree(info); + + return connected; +} + +static bool +SettingsAppBelievesConnected() +{ + nsresult rv; + nsCOMPtr<nsIWindowsRegKey> regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + if (NS_FAILED(rv)) { + return false; + } + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\Shell\\Associations"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return false; + } + + uint32_t value; + rv = regKey->ReadIntValue(NS_LITERAL_STRING("IsConnectedAtLogon"), &value); + if (NS_FAILED(rv)) { + return false; + } + + return !!value; +} + nsresult nsWindowsShellService::LaunchModernSettingsDialogDefaultApps() { + if (!IsWindowsBuildOrLater(14965) && + !IsWindowsLogonConnected() && SettingsAppBelievesConnected()) { + // Use the classic Control Panel to work around a bug of older + // builds of Windows 10. + return LaunchControlPanelDefaultPrograms(); + } + IApplicationActivationManager* pActivator; HRESULT hr = CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, @@ -682,6 +746,15 @@ nsWindowsShellService::LaunchModernSettingsDialogDefaultApps() L"windows.immersivecontrolpanel_cw5n1h2txyewy" L"!microsoft.windows.immersivecontrolpanel", L"page=SettingsPageAppsDefaults", AO_NONE, &pid); + if (SUCCEEDED(hr)) { + // Do not check error because we could at least open + // the "Default apps" setting. + pActivator->ActivateApplication( + L"windows.immersivecontrolpanel_cw5n1h2txyewy" + L"!microsoft.windows.immersivecontrolpanel", + L"page=SettingsPageAppsDefaults" + L"&target=SystemSettings_DefaultApps_Browser", AO_NONE, &pid); + } pActivator->Release(); return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; } @@ -689,6 +762,36 @@ nsWindowsShellService::LaunchModernSettingsDialogDefaultApps() } nsresult +nsWindowsShellService::InvokeHTTPOpenAsVerb() +{ + nsCOMPtr<nsIURLFormatter> formatter( + do_GetService("@mozilla.org/toolkit/URLFormatterService;1")); + if (!formatter) { + return NS_ERROR_UNEXPECTED; + } + + nsString urlStr; + nsresult rv = formatter->FormatURLPref( + NS_LITERAL_STRING("app.support.baseURL"), urlStr); + if (NS_FAILED(rv)) { + return rv; + } + if (!StringBeginsWith(urlStr, NS_LITERAL_STRING("https://"))) { + return NS_ERROR_FAILURE; + } + urlStr.AppendLiteral("win10-default-browser"); + + SHELLEXECUTEINFOW seinfo = { sizeof(SHELLEXECUTEINFOW) }; + seinfo.lpVerb = L"openas"; + seinfo.lpFile = urlStr.get(); + seinfo.nShow = SW_SHOWNORMAL; + if (!ShellExecuteExW(&seinfo)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult nsWindowsShellService::LaunchHTTPHandlerPane() { OPENASINFO info; @@ -716,16 +819,23 @@ nsWindowsShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) nsresult rv = LaunchHelper(appHelperPath); if (NS_SUCCEEDED(rv) && IsWin8OrLater()) { if (aClaimAllTypes) { - rv = LaunchControlPanelDefaultPrograms(); + if (IsWin10OrLater()) { + rv = LaunchModernSettingsDialogDefaultApps(); + } else { + rv = LaunchControlPanelDefaultsSelectionUI(); + } // The above call should never really fail, but just in case // fall back to showing the HTTP association screen only. if (NS_FAILED(rv)) { - rv = LaunchHTTPHandlerPane(); + if (IsWin10OrLater()) { + rv = InvokeHTTPOpenAsVerb(); + } else { + rv = LaunchHTTPHandlerPane(); + } } } else { - // Windows 10 blocks attempts to load the HTTP Handler - // association dialog, so the modern Settings dialog - // is opened with the Default Apps view loaded. + // Windows 10 blocks attempts to load the + // HTTP Handler association dialog. if (IsWin10OrLater()) { rv = LaunchModernSettingsDialogDefaultApps(); } else { @@ -735,50 +845,20 @@ nsWindowsShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) // The above call should never really fail, but just in case // fall back to showing control panel for all defaults if (NS_FAILED(rv)) { - rv = LaunchControlPanelDefaultPrograms(); + rv = LaunchControlPanelDefaultsSelectionUI(); } } } - return rv; -} - -NS_IMETHODIMP -nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - - // If we've already checked, the browser has been started and this is a - // new window open, and we don't want to check again. - if (mCheckedThisSession) { - *aResult = false; - return NS_OK; + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + // Reset the number of times the dialog should be shown + // before it is silenced. + (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0); } - nsCOMPtr<nsIPrefBranch> prefs; - nsresult rv; - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = pserve->GetBranch("", getter_AddRefs(prefs)); - NS_ENSURE_SUCCESS(rv, rv); - - return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); -} - -NS_IMETHODIMP -nsWindowsShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) -{ - nsCOMPtr<nsIPrefBranch> prefs; - nsresult rv; - - nsCOMPtr<nsIPrefService> pserve(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = pserve->GetBranch("", getter_AddRefs(prefs)); - NS_ENSURE_SUCCESS(rv, rv); - - return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); + return rv; } static nsresult @@ -912,7 +992,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement, // e.g. "Desktop Background.bmp" nsString fileLeafName; rv = shellBundle->GetStringFromName - (MOZ_UTF16("desktopBackgroundLeafNameWin"), + (u"desktopBackgroundLeafNameWin", getter_Copies(fileLeafName)); NS_ENSURE_SUCCESS(rv, rv); @@ -948,24 +1028,24 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement, nsAutoString style; switch (aPosition) { case BACKGROUND_TILE: - style.AssignLiteral("0"); - tile.AssignLiteral("1"); + style.Assign('0'); + tile.Assign('1'); break; case BACKGROUND_CENTER: - style.AssignLiteral("0"); - tile.AssignLiteral("0"); + style.Assign('0'); + tile.Assign('0'); break; case BACKGROUND_STRETCH: - style.AssignLiteral("2"); - tile.AssignLiteral("0"); + style.Assign('2'); + tile.Assign('0'); break; case BACKGROUND_FILL: style.AssignLiteral("10"); - tile.AssignLiteral("0"); + tile.Assign('0'); break; case BACKGROUND_FIT: - style.AssignLiteral("6"); - tile.AssignLiteral("0"); + style.Assign('6'); + tile.Assign('0'); break; } @@ -1023,7 +1103,7 @@ nsWindowsShellService::OpenApplication(int32_t aApplication) ::RegCloseKey(theKey); // Find the "open" command - application.AppendLiteral("\\"); + application.Append('\\'); application.Append(buf); application.AppendLiteral("\\shell\\open\\command"); @@ -1122,8 +1202,7 @@ nsWindowsShellService::SetDesktopBackgroundColor(uint32_t aColor) return regKey->Close(); } -nsWindowsShellService::nsWindowsShellService() : - mCheckedThisSession(false) +nsWindowsShellService::nsWindowsShellService() { } diff --git a/application/palemoon/components/shell/nsWindowsShellService.h b/application/palemoon/components/shell/nsWindowsShellService.h index f856ffd35..06c6c3c9b 100644 --- a/application/palemoon/components/shell/nsWindowsShellService.h +++ b/application/palemoon/components/shell/nsWindowsShellService.h @@ -16,9 +16,10 @@ class nsWindowsShellService : public nsIWindowsShellService { + virtual ~nsWindowsShellService(); + public: nsWindowsShellService(); - virtual ~nsWindowsShellService(); NS_DECL_ISUPPORTS NS_DECL_NSISHELLSERVICE @@ -26,12 +27,11 @@ public: protected: bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser); + nsresult LaunchControlPanelDefaultsSelectionUI(); nsresult LaunchControlPanelDefaultPrograms(); nsresult LaunchModernSettingsDialogDefaultApps(); + nsresult InvokeHTTPOpenAsVerb(); nsresult LaunchHTTPHandlerPane(); - -private: - bool mCheckedThisSession; }; #endif // nswindowsshellservice_h____ diff --git a/application/palemoon/components/statusbar/Downloads.jsm b/application/palemoon/components/statusbar/Downloads.jsm index 74bc42144..091fdad2e 100644 --- a/application/palemoon/components/statusbar/Downloads.jsm +++ b/application/palemoon/components/statusbar/Downloads.jsm @@ -18,657 +18,657 @@ CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EDownloadService(window, gBrowser, service, getters) { - this._window = window; - this._gBrowser = gBrowser; - this._service = service; - this._getters = getters; + this._window = window; + this._gBrowser = gBrowser; + this._service = service; + this._getters = getters; - this._handler = new JSTransferHandler(this._window, this); + this._handler = new JSTransferHandler(this._window, this); } S4EDownloadService.prototype = { - _window: null, - _gBrowser: null, - _service: null, - _getters: null, - - _handler: null, - _listening: false, - - _binding: false, - _customizing: false, - - _lastTime: Infinity, - - _dlActive: false, - _dlPaused: false, - _dlFinished: false, - - _dlCountStr: null, - _dlTimeStr: null, - - _dlProgressAvg: 0, - _dlProgressMax: 0, - _dlProgressMin: 0, - _dlProgressType: "active", - - _dlNotifyTimer: 0, - _dlNotifyGlowTimer: 0, - - init: function() - { - if(!this._getters.downloadButton) - { - this.uninit(); - return; - } - - if(this._listening) - { - return; - } - - this._handler.start(); - this._listening = true; - - this._lastTime = Infinity; - - this.updateBinding(); - this.updateStatus(); - }, - - uninit: function() - { - if(!this._listening) - { - return; - } - - this._listening = false; - this._handler.stop(); - - this.releaseBinding(); - }, - - destroy: function() - { - this.uninit(); - this._handler.destroy(); - - ["_window", "_gBrowser", "_service", "_getters", "_handler"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - updateBinding: function() - { - if(!this._listening) - { - this.releaseBinding(); - return; - } - - switch(this._service.downloadButtonAction) - { - case 1: // Default - this.attachBinding(); - break; - default: - this.releaseBinding(); - break; - } - }, - - attachBinding: function() - { - if(this._binding) - { - return; - } - - let db = this._window.DownloadsButton; - - db._getAnchorS4EBackup = db.getAnchor; - db.getAnchor = this.getAnchor.bind(this); - - db._releaseAnchorS4EBackup = db.releaseAnchor; - db.releaseAnchor = function() {}; - - this._binding = true; - }, - - releaseBinding: function() - { - if(!this._binding) - { - return; - } - - let db = this._window.DownloadsButton; - - db.getAnchor = db._getAnchorS4EBackup; - db.releaseAnchor = db._releaseAnchorS4EBackup; - - this._binding = false; - }, - - customizing: function(val) - { - this._customizing = val; - }, - - updateStatus: function(lastFinished) - { - if(!this._getters.downloadButton) - { - this.uninit(); - return; - } - - let numActive = 0; - let numPaused = 0; - let activeTotalSize = 0; - let activeTransferred = 0; - let activeMaxProgress = -Infinity; - let activeMinProgress = Infinity; - let pausedTotalSize = 0; - let pausedTransferred = 0; - let pausedMaxProgress = -Infinity; - let pausedMinProgress = Infinity; - let maxTime = -Infinity; - - let dls = ((this.isPrivateWindow) ? this._handler.activePrivateEntries() : this._handler.activeEntries()); - for(let dl of dls) - { - if(dl.state == CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING) - { - numActive++; - if(dl.size > 0) - { - if(dl.speed > 0) - { - maxTime = Math.max(maxTime, (dl.size - dl.transferred) / dl.speed); - } - - activeTotalSize += dl.size; - activeTransferred += dl.transferred; - - let currentProgress = ((dl.transferred * 100) / dl.size); - activeMaxProgress = Math.max(activeMaxProgress, currentProgress); - activeMinProgress = Math.min(activeMinProgress, currentProgress); - } - } - else if(dl.state == CI.nsIDownloadManager.DOWNLOAD_PAUSED) - { - numPaused++; - if(dl.size > 0) - { - pausedTotalSize += dl.size; - pausedTransferred += dl.transferred; - - let currentProgress = ((dl.transferred * 100) / dl.size); - pausedMaxProgress = Math.max(pausedMaxProgress, currentProgress); - pausedMinProgress = Math.min(pausedMinProgress, currentProgress); - } - } - } - - if((numActive + numPaused) == 0) - { - this._dlActive = false; - this._dlFinished = lastFinished; - this.updateButton(); - this._lastTime = Infinity; - return; - } - - let dlPaused = (numActive == 0); - let dlStatus = ((dlPaused) ? this._getters.strings.getString("pausedDownloads") - : this._getters.strings.getString("activeDownloads")); - let dlCount = ((dlPaused) ? numPaused : numActive); - let dlTotalSize = ((dlPaused) ? pausedTotalSize : activeTotalSize); - let dlTransferred = ((dlPaused) ? pausedTransferred : activeTransferred); - let dlMaxProgress = ((dlPaused) ? pausedMaxProgress : activeMaxProgress); - let dlMinProgress = ((dlPaused) ? pausedMinProgress : activeMinProgress); - let dlProgressType = ((dlPaused) ? "paused" : "active"); - - [this._dlTimeStr, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime); - this._dlCountStr = PluralForm.get(dlCount, dlStatus).replace("#1", dlCount); - this._dlProgressAvg = ((dlTotalSize == 0) ? 100 : ((dlTransferred * 100) / dlTotalSize)); - this._dlProgressMax = ((dlTotalSize == 0) ? 100 : dlMaxProgress); - this._dlProgressMin = ((dlTotalSize == 0) ? 100 : dlMinProgress); - this._dlProgressType = dlProgressType + ((dlTotalSize == 0) ? "-unknown" : ""); - this._dlPaused = dlPaused; - this._dlActive = true; - this._dlFinished = false; - - this.updateButton(); - }, - - updateButton: function() - { - let download_button = this._getters.downloadButton; - let download_tooltip = this._getters.downloadButtonTooltip; - let download_progress = this._getters.downloadButtonProgress; - let download_label = this._getters.downloadButtonLabel; - if(!download_button) - { - return; - } - - if(!this._dlActive) - { - download_button.collapsed = true; - download_label.value = download_tooltip.label = this._getters.strings.getString("noDownloads"); - - download_progress.collapsed = true; - download_progress.value = 0; - - if(this._dlFinished && this._handler.hasPBAPI && !this.isUIShowing) - { - this.callAttention(download_button); - } - return; - } - - switch(this._service.downloadProgress) - { - case 2: - download_progress.value = this._dlProgressMax; - break; - case 3: - download_progress.value = this._dlProgressMin; - break; - default: - download_progress.value = this._dlProgressAvg; - break; - } - download_progress.setAttribute("pmType", this._dlProgressType); - download_progress.collapsed = (this._service.downloadProgress == 0); - - download_label.value = this.buildString(this._service.downloadLabel); - download_tooltip.label = this.buildString(this._service.downloadTooltip); - - this.clearAttention(download_button); - download_button.collapsed = false; - }, - - callAttention: function(download_button) - { - if(this._dlNotifyGlowTimer != 0) - { - this._window.clearTimeout(this._dlNotifyGlowTimer); - this._dlNotifyGlowTimer = 0; - } - - download_button.setAttribute("attention", "true"); - - if(this._service.downloadNotifyTimeout) - { - this._dlNotifyGlowTimer = this._window.setTimeout(function(self, button) - { - self._dlNotifyGlowTimer = 0; - button.removeAttribute("attention"); - }, this._service.downloadNotifyTimeout, this, download_button); - } - }, - - clearAttention: function(download_button) - { - if(this._dlNotifyGlowTimer != 0) - { - this._window.clearTimeout(this._dlNotifyGlowTimer); - this._dlNotifyGlowTimer = 0; - } - - download_button.removeAttribute("attention"); - }, - - notify: function() - { - if(this._dlNotifyTimer == 0 && this._service.downloadNotifyAnimate) - { - let download_button_anchor = this._getters.downloadButtonAnchor; - let download_notify_anchor = this._getters.downloadNotifyAnchor; - if(download_button_anchor) - { - if(!download_notify_anchor.style.transform) - { - let bAnchorRect = download_button_anchor.getBoundingClientRect(); - let nAnchorRect = download_notify_anchor.getBoundingClientRect(); - - let translateX = bAnchorRect.left - nAnchorRect.left; - translateX += .5 * (bAnchorRect.width - nAnchorRect.width); - - let translateY = bAnchorRect.top - nAnchorRect.top; - translateY += .5 * (bAnchorRect.height - nAnchorRect.height); - - download_notify_anchor.style.transform = "translate(" + translateX + "px, " + translateY + "px)"; - } - - download_notify_anchor.setAttribute("notification", "finish"); - this._dlNotifyTimer = this._window.setTimeout(function(self, anchor) - { - self._dlNotifyTimer = 0; - anchor.removeAttribute("notification"); - anchor.style.transform = ""; - }, 1000, this, download_notify_anchor); - } - } - }, - - clearFinished: function() - { - this._dlFinished = false; - let download_button = this._getters.downloadButton; - if(download_button) - { - this.clearAttention(download_button); - } - }, - - getAnchor: function(aCallback) - { - if(this._customizing) - { - aCallback(null); - return; - } - - aCallback(this._getters.downloadButtonAnchor); - }, - - openUI: function(aEvent) - { - this.clearFinished(); - - switch(this._service.downloadButtonAction) - { - case 1: // Firefox Default - this._handler.openUINative(); - break; - case 2: // Show Library - this._window.PlacesCommandHook.showPlacesOrganizer("Downloads"); - break; - case 3: // Show Tab - let found = this._gBrowser.browsers.some(function(browser, index) - { - if("about:downloads" == browser.currentURI.spec) - { - this._gBrowser.selectedTab = this._gBrowser.tabContainer.childNodes[index]; - return true; - } - }, this); - - if(!found) - { - this._window.openUILinkIn("about:downloads", "tab"); - } - break; - case 4: // External Command - let command = this._service.downloadButtonActionCommand; - if(commend) - { - this._window.goDoCommand(command); - } - break; - default: // Nothing - break; - } - - aEvent.stopPropagation(); - }, - - get isPrivateWindow() - { - return this._handler.hasPBAPI && PrivateBrowsingUtils.isWindowPrivate(this._window); - }, - - get isUIShowing() - { - switch(this._service.downloadButtonAction) - { - case 1: // Firefox Default - return this._handler.isUIShowingNative; - case 2: // Show Library - var organizer = Services.wm.getMostRecentWindow("Places:Organizer"); - if(organizer) - { - let selectedNode = organizer.PlacesOrganizer._places.selectedNode; - let downloadsItemId = organizer.PlacesUIUtils.leftPaneQueries["Downloads"]; - return selectedNode && selectedNode.itemId === downloadsItemId; - } - return false; - case 3: // Show tab - let currentURI = this._gBrowser.currentURI; - return currentURI && currentURI.spec == "about:downloads"; - default: // Nothing - return false; - } - }, - - buildString: function(mode) - { - switch(mode) - { - case 0: - return this._dlCountStr; - case 1: - return ((this._dlPaused) ? this._dlCountStr : this._dlTimeStr); - default: - let compStr = this._dlCountStr; - if(!this._dlPaused) - { - compStr += " (" + this._dlTimeStr + ")"; - } - return compStr; - } - } + _window: null, + _gBrowser: null, + _service: null, + _getters: null, + + _handler: null, + _listening: false, + + _binding: false, + _customizing: false, + + _lastTime: Infinity, + + _dlActive: false, + _dlPaused: false, + _dlFinished: false, + + _dlCountStr: null, + _dlTimeStr: null, + + _dlProgressAvg: 0, + _dlProgressMax: 0, + _dlProgressMin: 0, + _dlProgressType: "active", + + _dlNotifyTimer: 0, + _dlNotifyGlowTimer: 0, + + init: function() + { + if(!this._getters.downloadButton) + { + this.uninit(); + return; + } + + if(this._listening) + { + return; + } + + this._handler.start(); + this._listening = true; + + this._lastTime = Infinity; + + this.updateBinding(); + this.updateStatus(); + }, + + uninit: function() + { + if(!this._listening) + { + return; + } + + this._listening = false; + this._handler.stop(); + + this.releaseBinding(); + }, + + destroy: function() + { + this.uninit(); + this._handler.destroy(); + + ["_window", "_gBrowser", "_service", "_getters", "_handler"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + updateBinding: function() + { + if(!this._listening) + { + this.releaseBinding(); + return; + } + + switch(this._service.downloadButtonAction) + { + case 1: // Default + this.attachBinding(); + break; + default: + this.releaseBinding(); + break; + } + }, + + attachBinding: function() + { + if(this._binding) + { + return; + } + + let db = this._window.DownloadsButton; + + db._getAnchorS4EBackup = db.getAnchor; + db.getAnchor = this.getAnchor.bind(this); + + db._releaseAnchorS4EBackup = db.releaseAnchor; + db.releaseAnchor = function() {}; + + this._binding = true; + }, + + releaseBinding: function() + { + if(!this._binding) + { + return; + } + + let db = this._window.DownloadsButton; + + db.getAnchor = db._getAnchorS4EBackup; + db.releaseAnchor = db._releaseAnchorS4EBackup; + + this._binding = false; + }, + + customizing: function(val) + { + this._customizing = val; + }, + + updateStatus: function(lastFinished) + { + if(!this._getters.downloadButton) + { + this.uninit(); + return; + } + + let numActive = 0; + let numPaused = 0; + let activeTotalSize = 0; + let activeTransferred = 0; + let activeMaxProgress = -Infinity; + let activeMinProgress = Infinity; + let pausedTotalSize = 0; + let pausedTransferred = 0; + let pausedMaxProgress = -Infinity; + let pausedMinProgress = Infinity; + let maxTime = -Infinity; + + let dls = ((this.isPrivateWindow) ? this._handler.activePrivateEntries() : this._handler.activeEntries()); + for(let dl of dls) + { + if(dl.state == CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING) + { + numActive++; + if(dl.size > 0) + { + if(dl.speed > 0) + { + maxTime = Math.max(maxTime, (dl.size - dl.transferred) / dl.speed); + } + + activeTotalSize += dl.size; + activeTransferred += dl.transferred; + + let currentProgress = ((dl.transferred * 100) / dl.size); + activeMaxProgress = Math.max(activeMaxProgress, currentProgress); + activeMinProgress = Math.min(activeMinProgress, currentProgress); + } + } + else if(dl.state == CI.nsIDownloadManager.DOWNLOAD_PAUSED) + { + numPaused++; + if(dl.size > 0) + { + pausedTotalSize += dl.size; + pausedTransferred += dl.transferred; + + let currentProgress = ((dl.transferred * 100) / dl.size); + pausedMaxProgress = Math.max(pausedMaxProgress, currentProgress); + pausedMinProgress = Math.min(pausedMinProgress, currentProgress); + } + } + } + + if((numActive + numPaused) == 0) + { + this._dlActive = false; + this._dlFinished = lastFinished; + this.updateButton(); + this._lastTime = Infinity; + return; + } + + let dlPaused = (numActive == 0); + let dlStatus = ((dlPaused) ? this._getters.strings.getString("pausedDownloads") + : this._getters.strings.getString("activeDownloads")); + let dlCount = ((dlPaused) ? numPaused : numActive); + let dlTotalSize = ((dlPaused) ? pausedTotalSize : activeTotalSize); + let dlTransferred = ((dlPaused) ? pausedTransferred : activeTransferred); + let dlMaxProgress = ((dlPaused) ? pausedMaxProgress : activeMaxProgress); + let dlMinProgress = ((dlPaused) ? pausedMinProgress : activeMinProgress); + let dlProgressType = ((dlPaused) ? "paused" : "active"); + + [this._dlTimeStr, this._lastTime] = DownloadUtils.getTimeLeft(maxTime, this._lastTime); + this._dlCountStr = PluralForm.get(dlCount, dlStatus).replace("#1", dlCount); + this._dlProgressAvg = ((dlTotalSize == 0) ? 100 : ((dlTransferred * 100) / dlTotalSize)); + this._dlProgressMax = ((dlTotalSize == 0) ? 100 : dlMaxProgress); + this._dlProgressMin = ((dlTotalSize == 0) ? 100 : dlMinProgress); + this._dlProgressType = dlProgressType + ((dlTotalSize == 0) ? "-unknown" : ""); + this._dlPaused = dlPaused; + this._dlActive = true; + this._dlFinished = false; + + this.updateButton(); + }, + + updateButton: function() + { + let download_button = this._getters.downloadButton; + let download_tooltip = this._getters.downloadButtonTooltip; + let download_progress = this._getters.downloadButtonProgress; + let download_label = this._getters.downloadButtonLabel; + if(!download_button) + { + return; + } + + if(!this._dlActive) + { + download_button.collapsed = true; + download_label.value = download_tooltip.label = this._getters.strings.getString("noDownloads"); + + download_progress.collapsed = true; + download_progress.value = 0; + + if(this._dlFinished && this._handler.hasPBAPI && !this.isUIShowing) + { + this.callAttention(download_button); + } + return; + } + + switch(this._service.downloadProgress) + { + case 2: + download_progress.value = this._dlProgressMax; + break; + case 3: + download_progress.value = this._dlProgressMin; + break; + default: + download_progress.value = this._dlProgressAvg; + break; + } + download_progress.setAttribute("pmType", this._dlProgressType); + download_progress.collapsed = (this._service.downloadProgress == 0); + + download_label.value = this.buildString(this._service.downloadLabel); + download_tooltip.label = this.buildString(this._service.downloadTooltip); + + this.clearAttention(download_button); + download_button.collapsed = false; + }, + + callAttention: function(download_button) + { + if(this._dlNotifyGlowTimer != 0) + { + this._window.clearTimeout(this._dlNotifyGlowTimer); + this._dlNotifyGlowTimer = 0; + } + + download_button.setAttribute("attention", "true"); + + if(this._service.downloadNotifyTimeout) + { + this._dlNotifyGlowTimer = this._window.setTimeout(function(self, button) + { + self._dlNotifyGlowTimer = 0; + button.removeAttribute("attention"); + }, this._service.downloadNotifyTimeout, this, download_button); + } + }, + + clearAttention: function(download_button) + { + if(this._dlNotifyGlowTimer != 0) + { + this._window.clearTimeout(this._dlNotifyGlowTimer); + this._dlNotifyGlowTimer = 0; + } + + download_button.removeAttribute("attention"); + }, + + notify: function() + { + if(this._dlNotifyTimer == 0 && this._service.downloadNotifyAnimate) + { + let download_button_anchor = this._getters.downloadButtonAnchor; + let download_notify_anchor = this._getters.downloadNotifyAnchor; + if(download_button_anchor) + { + if(!download_notify_anchor.style.transform) + { + let bAnchorRect = download_button_anchor.getBoundingClientRect(); + let nAnchorRect = download_notify_anchor.getBoundingClientRect(); + + let translateX = bAnchorRect.left - nAnchorRect.left; + translateX += .5 * (bAnchorRect.width - nAnchorRect.width); + + let translateY = bAnchorRect.top - nAnchorRect.top; + translateY += .5 * (bAnchorRect.height - nAnchorRect.height); + + download_notify_anchor.style.transform = "translate(" + translateX + "px, " + translateY + "px)"; + } + + download_notify_anchor.setAttribute("notification", "finish"); + this._dlNotifyTimer = this._window.setTimeout(function(self, anchor) + { + self._dlNotifyTimer = 0; + anchor.removeAttribute("notification"); + anchor.style.transform = ""; + }, 1000, this, download_notify_anchor); + } + } + }, + + clearFinished: function() + { + this._dlFinished = false; + let download_button = this._getters.downloadButton; + if(download_button) + { + this.clearAttention(download_button); + } + }, + + getAnchor: function(aCallback) + { + if(this._customizing) + { + aCallback(null); + return; + } + + aCallback(this._getters.downloadButtonAnchor); + }, + + openUI: function(aEvent) + { + this.clearFinished(); + + switch(this._service.downloadButtonAction) + { + case 1: // Firefox Default + this._handler.openUINative(); + break; + case 2: // Show Library + this._window.PlacesCommandHook.showPlacesOrganizer("Downloads"); + break; + case 3: // Show Tab + let found = this._gBrowser.browsers.some(function(browser, index) + { + if("about:downloads" == browser.currentURI.spec) + { + this._gBrowser.selectedTab = this._gBrowser.tabContainer.childNodes[index]; + return true; + } + }, this); + + if(!found) + { + this._window.openUILinkIn("about:downloads", "tab"); + } + break; + case 4: // External Command + let command = this._service.downloadButtonActionCommand; + if(commend) + { + this._window.goDoCommand(command); + } + break; + default: // Nothing + break; + } + + aEvent.stopPropagation(); + }, + + get isPrivateWindow() + { + return this._handler.hasPBAPI && PrivateBrowsingUtils.isWindowPrivate(this._window); + }, + + get isUIShowing() + { + switch(this._service.downloadButtonAction) + { + case 1: // Firefox Default + return this._handler.isUIShowingNative; + case 2: // Show Library + var organizer = Services.wm.getMostRecentWindow("Places:Organizer"); + if(organizer) + { + let selectedNode = organizer.PlacesOrganizer._places.selectedNode; + let downloadsItemId = organizer.PlacesUIUtils.leftPaneQueries["Downloads"]; + return selectedNode && selectedNode.itemId === downloadsItemId; + } + return false; + case 3: // Show tab + let currentURI = this._gBrowser.currentURI; + return currentURI && currentURI.spec == "about:downloads"; + default: // Nothing + return false; + } + }, + + buildString: function(mode) + { + switch(mode) + { + case 0: + return this._dlCountStr; + case 1: + return ((this._dlPaused) ? this._dlCountStr : this._dlTimeStr); + default: + let compStr = this._dlCountStr; + if(!this._dlPaused) + { + compStr += " (" + this._dlTimeStr + ")"; + } + return compStr; + } + } }; function JSTransferHandler(window, downloadService) { - this._window = window; + this._window = window; - let api = CU.import("resource://gre/modules/Downloads.jsm", {}).Downloads; + let api = CU.import("resource://gre/modules/Downloads.jsm", {}).Downloads; - this._activePublic = new JSTransferListener(downloadService, api.getList(api.PUBLIC), false); - this._activePrivate = new JSTransferListener(downloadService, api.getList(api.PRIVATE), true); + this._activePublic = new JSTransferListener(downloadService, api.getList(api.PUBLIC), false); + this._activePrivate = new JSTransferListener(downloadService, api.getList(api.PRIVATE), true); } JSTransferHandler.prototype = { - _window: null, - _activePublic: null, - _activePrivate: null, - - destroy: function() - { - this._activePublic.destroy(); - this._activePrivate.destroy(); - - ["_window", "_activePublic", "_activePrivate"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - start: function() - { - this._activePublic.start(); - this._activePrivate.start(); - }, - - stop: function() - { - this._activePublic.stop(); - this._activePrivate.stop(); - }, - - get hasPBAPI() - { - return true; - }, - - openUINative: function() - { - this._window.DownloadsPanel.showPanel(); - }, - - get isUIShowingNative() - { - return this._window.DownloadsPanel.isPanelShowing; - }, - - activeEntries: function() - { - return this._activePublic.downloads(); - }, - - activePrivateEntries: function() - { - return this._activePrivate.downloads(); - } + _window: null, + _activePublic: null, + _activePrivate: null, + + destroy: function() + { + this._activePublic.destroy(); + this._activePrivate.destroy(); + + ["_window", "_activePublic", "_activePrivate"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + start: function() + { + this._activePublic.start(); + this._activePrivate.start(); + }, + + stop: function() + { + this._activePublic.stop(); + this._activePrivate.stop(); + }, + + get hasPBAPI() + { + return true; + }, + + openUINative: function() + { + this._window.DownloadsPanel.showPanel(); + }, + + get isUIShowingNative() + { + return this._window.DownloadsPanel.isPanelShowing; + }, + + activeEntries: function() + { + return this._activePublic.downloads(); + }, + + activePrivateEntries: function() + { + return this._activePrivate.downloads(); + } }; function JSTransferListener(downloadService, listPromise, isPrivate) { - this._downloadService = downloadService; - this._isPrivate = isPrivate; - this._downloads = new Map(); + this._downloadService = downloadService; + this._isPrivate = isPrivate; + this._downloads = new Map(); - listPromise.then(this.initList.bind(this)).then(null, CU.reportError); + listPromise.then(this.initList.bind(this)).then(null, CU.reportError); } JSTransferListener.prototype = { - _downloadService: null, - _list: null, - _downloads: null, - _isPrivate: false, - _wantsStart: false, - - initList: function(list) - { - this._list = list; - if(this._wantsStart) { - this.start(); - } - - this._list.getAll().then(this.initDownloads.bind(this)).then(null, CU.reportError); - }, - - initDownloads: function(downloads) - { - downloads.forEach(function(download) - { - this.onDownloadAdded(download); - }, this); - }, - - destroy: function() - { - this._downloads.clear(); - - ["_downloadService", "_list", "_downloads"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - start: function() - { - if(!this._list) - { - this._wantsStart = true; - return; - } - - this._list.addView(this); - }, - - stop: function() - { - if(!this._list) - { - this._wantsStart = false; - return; - } - - this._list.removeView(this); - }, - - downloads: function() - { - return this._downloads.values(); - }, - - convertToState: function(dl) - { - if(dl.succeeded) - { - return CI.nsIDownloadManager.DOWNLOAD_FINISHED; - } - if(dl.error && dl.error.becauseBlockedByParentalControls) - { - return CI.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL; - } - if(dl.error) - { - return CI.nsIDownloadManager.DOWNLOAD_FAILED; - } - if(dl.canceled && dl.hasPartialData) - { - return CI.nsIDownloadManager.DOWNLOAD_PAUSED; - } - if(dl.canceled) - { - return CI.nsIDownloadManager.DOWNLOAD_CANCELED; - } - if(dl.stopped) - { - return CI.nsIDownloadManager.DOWNLOAD_NOTSTARTED; - } - return CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING; - }, - - onDownloadAdded: function(aDownload) - { - let dl = this._downloads.get(aDownload); - if(!dl) - { - dl = {}; - this._downloads.set(aDownload, dl); - } - - dl.state = this.convertToState(aDownload); - dl.size = aDownload.totalBytes; - dl.speed = aDownload.speed; - dl.transferred = aDownload.currentBytes; - }, - - onDownloadChanged: function(aDownload) - { - this.onDownloadAdded(aDownload); - - if(this._isPrivate != this._downloadService.isPrivateWindow) - { - return; - } - - this._downloadService.updateStatus(aDownload.succeeded); - - if(aDownload.succeeded) - { - this._downloadService.notify() - } - }, - - onDownloadRemoved: function(aDownload) - { - this._downloads.delete(aDownload); - } + _downloadService: null, + _list: null, + _downloads: null, + _isPrivate: false, + _wantsStart: false, + + initList: function(list) + { + this._list = list; + if(this._wantsStart) { + this.start(); + } + + this._list.getAll().then(this.initDownloads.bind(this)).then(null, CU.reportError); + }, + + initDownloads: function(downloads) + { + downloads.forEach(function(download) + { + this.onDownloadAdded(download); + }, this); + }, + + destroy: function() + { + this._downloads.clear(); + + ["_downloadService", "_list", "_downloads"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + start: function() + { + if(!this._list) + { + this._wantsStart = true; + return; + } + + this._list.addView(this); + }, + + stop: function() + { + if(!this._list) + { + this._wantsStart = false; + return; + } + + this._list.removeView(this); + }, + + downloads: function() + { + return this._downloads.values(); + }, + + convertToState: function(dl) + { + if(dl.succeeded) + { + return CI.nsIDownloadManager.DOWNLOAD_FINISHED; + } + if(dl.error && dl.error.becauseBlockedByParentalControls) + { + return CI.nsIDownloadManager.DOWNLOAD_BLOCKED_PARENTAL; + } + if(dl.error) + { + return CI.nsIDownloadManager.DOWNLOAD_FAILED; + } + if(dl.canceled && dl.hasPartialData) + { + return CI.nsIDownloadManager.DOWNLOAD_PAUSED; + } + if(dl.canceled) + { + return CI.nsIDownloadManager.DOWNLOAD_CANCELED; + } + if(dl.stopped) + { + return CI.nsIDownloadManager.DOWNLOAD_NOTSTARTED; + } + return CI.nsIDownloadManager.DOWNLOAD_DOWNLOADING; + }, + + onDownloadAdded: function(aDownload) + { + let dl = this._downloads.get(aDownload); + if(!dl) + { + dl = {}; + this._downloads.set(aDownload, dl); + } + + dl.state = this.convertToState(aDownload); + dl.size = aDownload.totalBytes; + dl.speed = aDownload.speed; + dl.transferred = aDownload.currentBytes; + }, + + onDownloadChanged: function(aDownload) + { + this.onDownloadAdded(aDownload); + + if(this._isPrivate != this._downloadService.isPrivateWindow) + { + return; + } + + this._downloadService.updateStatus(aDownload.succeeded); + + if(aDownload.succeeded) + { + this._downloadService.notify() + } + }, + + onDownloadRemoved: function(aDownload) + { + this._downloads.delete(aDownload); + } }; diff --git a/application/palemoon/components/statusbar/Progress.jsm b/application/palemoon/components/statusbar/Progress.jsm index c03a25450..69d55db49 100644 --- a/application/palemoon/components/statusbar/Progress.jsm +++ b/application/palemoon/components/statusbar/Progress.jsm @@ -12,172 +12,172 @@ const CU = Components.utils; CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EProgressService(gBrowser, service, getters, statusService) { - this._gBrowser = gBrowser; - this._service = service; - this._getters = getters; - this._statusService = statusService; + this._gBrowser = gBrowser; + this._service = service; + this._getters = getters; + this._statusService = statusService; - this._gBrowser.addProgressListener(this); + this._gBrowser.addProgressListener(this); } S4EProgressService.prototype = { - _gBrowser: null, - _service: null, - _getters: null, - _statusService: null, - - _busyUI: false, - - set value(val) - { - let toolbar_progress = this._getters.toolbarProgress; - if(toolbar_progress) - { - toolbar_progress.value = val; - } - - let throbber_progress = this._getters.throbberProgress; - if(throbber_progress) - { - if(val) - { - throbber_progress.setAttribute("progress", val); - } - else - { - throbber_progress.removeAttribute("progress"); - } - } - }, - - set collapsed(val) - { - let toolbar_progress = this._getters.toolbarProgress; - if(toolbar_progress) - { - toolbar_progress.collapsed = val; - } - - let throbber_progress = this._getters.throbberProgress; - if(throbber_progress) - { - if(val) - { - throbber_progress.removeAttribute("busy"); - } - else - { - throbber_progress.setAttribute("busy", true); - } - } - }, - - destroy: function() - { - this._gBrowser.removeProgressListener(this); - - ["_gBrowser", "_service", "_getters", "_statusService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) - { - this._statusService.setNetworkStatus(aMessage, this._busyUI); - }, - - onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) - { - let nsIWPL = CI.nsIWebProgressListener; - - if(!this._busyUI - && aStateFlags & nsIWPL.STATE_START - && aStateFlags & nsIWPL.STATE_IS_NETWORK - && !(aStateFlags & nsIWPL.STATE_RESTORING)) - { - this._busyUI = true; - this.value = 0; - this.collapsed = false; - } - else if(aStateFlags & nsIWPL.STATE_STOP) - { - if(aRequest) - { - let msg = ""; - let location; - if(aRequest instanceof CI.nsIChannel || "URI" in aRequest) - { - location = aRequest.URI; - if(location.spec != "about:blank") - { - switch (aStatus) - { - case Components.results.NS_BINDING_ABORTED: - msg = this._getters.strings.getString("nv_stopped"); - break; - case Components.results.NS_ERROR_NET_TIMEOUT: - msg = this._getters.strings.getString("nv_timeout"); - break; - } - } - } - - if(!msg && (!location || location.spec != "about:blank")) - { - msg = this._getters.strings.getString("nv_done"); - } - - this._statusService.setDefaultStatus(msg); - this._statusService.setNetworkStatus("", this._busyUI); - } - - if(this._busyUI) - { - this._busyUI = false; - this.collapsed = true; - this.value = 0; - } - } - }, - - onUpdateCurrentBrowser: function(aStateFlags, aStatus, aMessage, aTotalProgress) - { - let nsIWPL = CI.nsIWebProgressListener; - let loadingDone = aStateFlags & nsIWPL.STATE_STOP; - - this.onStateChange( - this._gBrowser.webProgress, - { URI: this._gBrowser.currentURI }, - ((loadingDone ? nsIWPL.STATE_STOP : nsIWPL.STATE_START) | (aStateFlags & nsIWPL.STATE_IS_NETWORK)), - aStatus - ); - - if(!loadingDone) - { - this.onProgressChange(this._gBrowser.webProgress, null, 0, 0, aTotalProgress, 1); - this.onStatusChange(this._gBrowser.webProgress, null, 0, aMessage); - } - }, - - onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) - { - if (aMaxTotalProgress > 0 && this._busyUI) - { - // This is highly optimized. Don't touch this code unless - // you are intimately familiar with the cost of setting - // attrs on XUL elements. -- hyatt - let percentage = (aCurTotalProgress * 100) / aMaxTotalProgress; - this.value = percentage; - } - }, - - onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) - { - return this.onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); - }, - - QueryInterface: XPCOMUtils.generateQI([ CI.nsIWebProgressListener, CI.nsIWebProgressListener2 ]) + _gBrowser: null, + _service: null, + _getters: null, + _statusService: null, + + _busyUI: false, + + set value(val) + { + let toolbar_progress = this._getters.toolbarProgress; + if(toolbar_progress) + { + toolbar_progress.value = val; + } + + let throbber_progress = this._getters.throbberProgress; + if(throbber_progress) + { + if(val) + { + throbber_progress.setAttribute("progress", val); + } + else + { + throbber_progress.removeAttribute("progress"); + } + } + }, + + set collapsed(val) + { + let toolbar_progress = this._getters.toolbarProgress; + if(toolbar_progress) + { + toolbar_progress.collapsed = val; + } + + let throbber_progress = this._getters.throbberProgress; + if(throbber_progress) + { + if(val) + { + throbber_progress.removeAttribute("busy"); + } + else + { + throbber_progress.setAttribute("busy", true); + } + } + }, + + destroy: function() + { + this._gBrowser.removeProgressListener(this); + + ["_gBrowser", "_service", "_getters", "_statusService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) + { + this._statusService.setNetworkStatus(aMessage, this._busyUI); + }, + + onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) + { + let nsIWPL = CI.nsIWebProgressListener; + + if(!this._busyUI + && aStateFlags & nsIWPL.STATE_START + && aStateFlags & nsIWPL.STATE_IS_NETWORK + && !(aStateFlags & nsIWPL.STATE_RESTORING)) + { + this._busyUI = true; + this.value = 0; + this.collapsed = false; + } + else if(aStateFlags & nsIWPL.STATE_STOP) + { + if(aRequest) + { + let msg = ""; + let location; + if(aRequest instanceof CI.nsIChannel || "URI" in aRequest) + { + location = aRequest.URI; + if(location.spec != "about:blank") + { + switch (aStatus) + { + case Components.results.NS_BINDING_ABORTED: + msg = this._getters.strings.getString("nv_stopped"); + break; + case Components.results.NS_ERROR_NET_TIMEOUT: + msg = this._getters.strings.getString("nv_timeout"); + break; + } + } + } + + if(!msg && (!location || location.spec != "about:blank")) + { + msg = this._getters.strings.getString("nv_done"); + } + + this._statusService.setDefaultStatus(msg); + this._statusService.setNetworkStatus("", this._busyUI); + } + + if(this._busyUI) + { + this._busyUI = false; + this.collapsed = true; + this.value = 0; + } + } + }, + + onUpdateCurrentBrowser: function(aStateFlags, aStatus, aMessage, aTotalProgress) + { + let nsIWPL = CI.nsIWebProgressListener; + let loadingDone = aStateFlags & nsIWPL.STATE_STOP; + + this.onStateChange( + this._gBrowser.webProgress, + { URI: this._gBrowser.currentURI }, + ((loadingDone ? nsIWPL.STATE_STOP : nsIWPL.STATE_START) | (aStateFlags & nsIWPL.STATE_IS_NETWORK)), + aStatus + ); + + if(!loadingDone) + { + this.onProgressChange(this._gBrowser.webProgress, null, 0, 0, aTotalProgress, 1); + this.onStatusChange(this._gBrowser.webProgress, null, 0, aMessage); + } + }, + + onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) + { + if (aMaxTotalProgress > 0 && this._busyUI) + { + // This is highly optimized. Don't touch this code unless + // you are intimately familiar with the cost of setting + // attrs on XUL elements. -- hyatt + let percentage = (aCurTotalProgress * 100) / aMaxTotalProgress; + this.value = percentage; + } + }, + + onProgressChange64: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) + { + return this.onProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress); + }, + + QueryInterface: XPCOMUtils.generateQI([ CI.nsIWebProgressListener, CI.nsIWebProgressListener2 ]) }; diff --git a/application/palemoon/components/statusbar/Status.jsm b/application/palemoon/components/statusbar/Status.jsm index 3795545a3..d888c7d94 100644 --- a/application/palemoon/components/statusbar/Status.jsm +++ b/application/palemoon/components/statusbar/Status.jsm @@ -13,452 +13,452 @@ CU.import("resource://gre/modules/XPCOMUtils.jsm"); function S4EStatusService(window, service, getters) { - this._window = window; - this._service = service; - this._getters = getters; + this._window = window; + this._service = service; + this._getters = getters; - this._overLinkService = new S4EOverlinkService(this._window, this._service, this); + this._overLinkService = new S4EOverlinkService(this._window, this._service, this); } S4EStatusService.prototype = { - _window: null, - _service: null, - _getters: null, - _overLinkService: null, - - _overLink: { val: "", type: "" }, - _network: { val: "", type: "" }, - _networkXHR: { val: "", type: "" }, - _status: { val: "", type: "" }, - _jsStatus: { val: "", type: "" }, - _defaultStatus: { val: "", type: "" }, - - _isFullScreen: false, - _isFullScreenVideo: false, - - _statusText: { val: "", type: "" }, - _noUpdate: false, - _statusChromeTimeoutID: 0, - _statusContentTimeoutID: 0, - - getCompositeStatusText: function() - { - return this._statusText.val; - }, - - getStatusText: function() - { - return this._status.val; - }, - - setNetworkStatus: function(status, busy) - { - if(busy) - { - this._network = { val: status, type: "network" }; - this._networkXHR = { val: "", type: "network xhr" }; - } - else - { - this._networkXHR = { val: status, type: "network xhr" }; - } - this.updateStatusField(); - }, - - setStatusText: function(status) - { - this._status = { val: status, type: "status chrome" }; - this.updateStatusField(); - }, - - setJSStatus: function(status) - { - this._jsStatus = { val: status, type: "status content" }; - this.updateStatusField(); - }, - - setJSDefaultStatus: function(status) - { - // This was removed from Firefox in Bug 862917 - }, - - setDefaultStatus: function(status) - { - this._defaultStatus = { val: status, type: "status chrome default" }; - this.updateStatusField(); - }, - - setOverLink: function(link, aAnchor) - { - this._overLinkService.update(link, aAnchor); - }, - - setOverLinkInternal: function(link, aAnchor) - { - let status = this._service.status; - let statusLinkOver = this._service.statusLinkOver; - - if(statusLinkOver) - { - link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g, encodeURIComponent); - if(status == statusLinkOver) - { - this._overLink = { val: link, type: "overLink", anchor: aAnchor }; - this.updateStatusField(); - } - else - { - this.setStatusField(statusLinkOver, { val: link, type: "overLink", anchor: aAnchor }, true); - } - } - }, - - setNoUpdate: function(nu) - { - this._noUpdate = nu; - }, - - buildBinding: function() { - let XULBWPropHandler = function(prop, oldval, newval) { - CU.reportError("Attempt to modify XULBrowserWindow." + prop); - return oldval; - }; - - ["updateStatusField", "onStatusChange"].forEach(function(prop) - { - this._window.XULBrowserWindow.unwatch(prop); - this._window.XULBrowserWindow[prop] = function() {}; - this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); - }, this); - - ["getCompositeStatusText", "getStatusText", "setStatusText", "setJSStatus", - "setJSDefaultStatus", "setDefaultStatus", "setOverLink"].forEach(function(prop) - { - this._window.XULBrowserWindow.unwatch(prop); - this._window.XULBrowserWindow[prop] = this[prop].bind(this); - this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); - }, this); - - let XULBWHandler = function(prop, oldval, newval) { - if(!newval) - { - return newval; - } - CU.reportError("XULBrowserWindow changed. Updating S4E bindings."); - this._window.setTimeout(function(self) - { - self.buildBinding(); - }, 0, this); - return newval; - }; - - this._window.watch("XULBrowserWindow", XULBWHandler); - }, - - destroy: function() - { - // No need to unbind from the XULBrowserWindow, it's already null at this point - - this.clearTimer("_statusChromeTimeoutID"); - this.clearTimer("_statusContentTimeoutID"); - - this._overLinkService.destroy(); - - ["_overLink", "_network", "_networkXHR", "_status", "_jsStatus", "_defaultStatus", - "_statusText", "_window", "_service", "_getters", "_overLinkService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - buildTextOrder: function() - { - this.__defineGetter__("_textOrder", function() - { - let textOrder = ["_overLink"]; - if(this._service.statusNetwork) - { - textOrder.push("_network"); - if(this._service.statusNetworkXHR) - { - textOrder.push("_networkXHR"); - } - } - textOrder.push("_status", "_jsStatus"); - if(this._service.statusDefault) - { - textOrder.push("_defaultStatus"); - } - - delete this._textOrder; - return this._textOrder = textOrder; - }); - }, - - updateStatusField: function(force) - { - let text = { val: "", type: "" }; - for(let i = 0; !text.val && i < this._textOrder.length; i++) - { - text = this[this._textOrder[i]]; - } - - if(this._statusText.val != text.val || force) - { - if(this._noUpdate) - { - return; - } - - this._statusText = text; - - this.setStatusField(this._service.status, text, false); - - if(text.val && this._service.statusTimeout) - { - this.setTimer(text.type); - } - } - }, - - updateFullScreen: function() - { - this._isFullScreen = this._window.fullScreen; - this._isFullScreenVideo = false; - if(this._isFullScreen) - { - let fsEl = this._window.content.document.mozFullScreenElement; - if(fsEl && (fsEl.nodeName == "VIDEO" || fsEl.getElementsByTagName("VIDEO").length > 0)) - { - this._isFullScreenVideo = true; - } - } - - this.clearStatusField(); - this.updateStatusField(true); - }, - - setTimer: function(type) - { - let typeArgs = type.split(" ", 3); - - if(typeArgs.length < 2 || typeArgs[0] != "status") - { - return; - } - - if(typeArgs[1] == "chrome") - { - this.clearTimer("_statusChromeTimeoutID"); - this._statusChromeTimeoutID = this._window.setTimeout(function(self, isDefault) - { - self._statusChromeTimeoutID = 0; - if(isDefault) - { - self.setDefaultStatus(""); - } - else - { - self.setStatusText(""); - } - }, this._service.statusTimeout, this, (typeArgs.length == 3 && typeArgs[2] == "default")); - } - else - { - this.clearTimer("_statusContentTimeoutID"); - this._statusContentTimeoutID = this._window.setTimeout(function(self) - { - self._statusContentTimeoutID = 0; - self.setJSStatus(""); - }, this._service.statusTimeout, this); - } - }, - - clearTimer: function(timerName) - { - if(this[timerName] != 0) - { - this._window.clearTimeout(this[timerName]); - this[timerName] = 0; - } - }, - - clearStatusField: function() - { - this._getters.statusOverlay.value = ""; - - let status_label = this._getters.statusWidgetLabel; - if(status_label) - { - status_label.value = ""; - } - - }, - - setStatusField: function(location, text, allowTooltip) - { - if(!location) - { - return; - } - - let label = null; - - if(this._isFullScreen && this._service.advancedStatusDetectFullScreen) - { - switch(location) - { - case 1: // Toolbar - location = 3 - break; - case 2: // URL bar - if(Services.prefs.getBoolPref("browser.fullscreen.autohide")) - { - location = 3 - } - break; - } - } - - switch(location) - { - case 1: // Toolbar - label = this._getters.statusWidgetLabel; - break; - case 2: // URL Bar - break; - case 3: // Popup - default: - if(this._isFullScreenVideo && this._service.advancedStatusDetectVideo) - { - return; - } - label = this._getters.statusOverlay; - break; - } - - if(label) - { - label.setAttribute("previoustype", label.getAttribute("type")); - label.setAttribute("type", text.type); - label.value = text.val; - label.setAttribute("crop", text.type == "overLink" ? "center" : "end"); - } - } + _window: null, + _service: null, + _getters: null, + _overLinkService: null, + + _overLink: { val: "", type: "" }, + _network: { val: "", type: "" }, + _networkXHR: { val: "", type: "" }, + _status: { val: "", type: "" }, + _jsStatus: { val: "", type: "" }, + _defaultStatus: { val: "", type: "" }, + + _isFullScreen: false, + _isFullScreenVideo: false, + + _statusText: { val: "", type: "" }, + _noUpdate: false, + _statusChromeTimeoutID: 0, + _statusContentTimeoutID: 0, + + getCompositeStatusText: function() + { + return this._statusText.val; + }, + + getStatusText: function() + { + return this._status.val; + }, + + setNetworkStatus: function(status, busy) + { + if(busy) + { + this._network = { val: status, type: "network" }; + this._networkXHR = { val: "", type: "network xhr" }; + } + else + { + this._networkXHR = { val: status, type: "network xhr" }; + } + this.updateStatusField(); + }, + + setStatusText: function(status) + { + this._status = { val: status, type: "status chrome" }; + this.updateStatusField(); + }, + + setJSStatus: function(status) + { + this._jsStatus = { val: status, type: "status content" }; + this.updateStatusField(); + }, + + setJSDefaultStatus: function(status) + { + // This was removed from Firefox in Bug 862917 + }, + + setDefaultStatus: function(status) + { + this._defaultStatus = { val: status, type: "status chrome default" }; + this.updateStatusField(); + }, + + setOverLink: function(link, aAnchor) + { + this._overLinkService.update(link, aAnchor); + }, + + setOverLinkInternal: function(link, aAnchor) + { + let status = this._service.status; + let statusLinkOver = this._service.statusLinkOver; + + if(statusLinkOver) + { + link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g, encodeURIComponent); + if(status == statusLinkOver) + { + this._overLink = { val: link, type: "overLink", anchor: aAnchor }; + this.updateStatusField(); + } + else + { + this.setStatusField(statusLinkOver, { val: link, type: "overLink", anchor: aAnchor }, true); + } + } + }, + + setNoUpdate: function(nu) + { + this._noUpdate = nu; + }, + + buildBinding: function() { + let XULBWPropHandler = function(prop, oldval, newval) { + CU.reportError("Attempt to modify XULBrowserWindow." + prop); + return oldval; + }; + + ["updateStatusField", "onStatusChange"].forEach(function(prop) + { + this._window.XULBrowserWindow.unwatch(prop); + this._window.XULBrowserWindow[prop] = function() {}; + this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); + }, this); + + ["getCompositeStatusText", "getStatusText", "setStatusText", "setJSStatus", + "setJSDefaultStatus", "setDefaultStatus", "setOverLink"].forEach(function(prop) + { + this._window.XULBrowserWindow.unwatch(prop); + this._window.XULBrowserWindow[prop] = this[prop].bind(this); + this._window.XULBrowserWindow.watch(prop, XULBWPropHandler); + }, this); + + let XULBWHandler = function(prop, oldval, newval) { + if(!newval) + { + return newval; + } + CU.reportError("XULBrowserWindow changed. Updating S4E bindings."); + this._window.setTimeout(function(self) + { + self.buildBinding(); + }, 0, this); + return newval; + }; + + this._window.watch("XULBrowserWindow", XULBWHandler); + }, + + destroy: function() + { + // No need to unbind from the XULBrowserWindow, it's already null at this point + + this.clearTimer("_statusChromeTimeoutID"); + this.clearTimer("_statusContentTimeoutID"); + + this._overLinkService.destroy(); + + ["_overLink", "_network", "_networkXHR", "_status", "_jsStatus", "_defaultStatus", + "_statusText", "_window", "_service", "_getters", "_overLinkService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + buildTextOrder: function() + { + this.__defineGetter__("_textOrder", function() + { + let textOrder = ["_overLink"]; + if(this._service.statusNetwork) + { + textOrder.push("_network"); + if(this._service.statusNetworkXHR) + { + textOrder.push("_networkXHR"); + } + } + textOrder.push("_status", "_jsStatus"); + if(this._service.statusDefault) + { + textOrder.push("_defaultStatus"); + } + + delete this._textOrder; + return this._textOrder = textOrder; + }); + }, + + updateStatusField: function(force) + { + let text = { val: "", type: "" }; + for(let i = 0; !text.val && i < this._textOrder.length; i++) + { + text = this[this._textOrder[i]]; + } + + if(this._statusText.val != text.val || force) + { + if(this._noUpdate) + { + return; + } + + this._statusText = text; + + this.setStatusField(this._service.status, text, false); + + if(text.val && this._service.statusTimeout) + { + this.setTimer(text.type); + } + } + }, + + updateFullScreen: function() + { + this._isFullScreen = this._window.fullScreen; + this._isFullScreenVideo = false; + if(this._isFullScreen) + { + let fsEl = this._window.content.document.mozFullScreenElement; + if(fsEl && (fsEl.nodeName == "VIDEO" || fsEl.getElementsByTagName("VIDEO").length > 0)) + { + this._isFullScreenVideo = true; + } + } + + this.clearStatusField(); + this.updateStatusField(true); + }, + + setTimer: function(type) + { + let typeArgs = type.split(" ", 3); + + if(typeArgs.length < 2 || typeArgs[0] != "status") + { + return; + } + + if(typeArgs[1] == "chrome") + { + this.clearTimer("_statusChromeTimeoutID"); + this._statusChromeTimeoutID = this._window.setTimeout(function(self, isDefault) + { + self._statusChromeTimeoutID = 0; + if(isDefault) + { + self.setDefaultStatus(""); + } + else + { + self.setStatusText(""); + } + }, this._service.statusTimeout, this, (typeArgs.length == 3 && typeArgs[2] == "default")); + } + else + { + this.clearTimer("_statusContentTimeoutID"); + this._statusContentTimeoutID = this._window.setTimeout(function(self) + { + self._statusContentTimeoutID = 0; + self.setJSStatus(""); + }, this._service.statusTimeout, this); + } + }, + + clearTimer: function(timerName) + { + if(this[timerName] != 0) + { + this._window.clearTimeout(this[timerName]); + this[timerName] = 0; + } + }, + + clearStatusField: function() + { + this._getters.statusOverlay.value = ""; + + let status_label = this._getters.statusWidgetLabel; + if(status_label) + { + status_label.value = ""; + } + + }, + + setStatusField: function(location, text, allowTooltip) + { + if(!location) + { + return; + } + + let label = null; + + if(this._isFullScreen && this._service.advancedStatusDetectFullScreen) + { + switch(location) + { + case 1: // Toolbar + location = 3 + break; + case 2: // URL bar + if(Services.prefs.getBoolPref("browser.fullscreen.autohide")) + { + location = 3 + } + break; + } + } + + switch(location) + { + case 1: // Toolbar + label = this._getters.statusWidgetLabel; + break; + case 2: // URL Bar + break; + case 3: // Popup + default: + if(this._isFullScreenVideo && this._service.advancedStatusDetectVideo) + { + return; + } + label = this._getters.statusOverlay; + break; + } + + if(label) + { + label.setAttribute("previoustype", label.getAttribute("type")); + label.setAttribute("type", text.type); + label.value = text.val; + label.setAttribute("crop", text.type == "overLink" ? "center" : "end"); + } + } }; function S4EOverlinkService(window, service, statusService) { - this._window = window; - this._service = service; - this._statusService = statusService; + this._window = window; + this._service = service; + this._statusService = statusService; } S4EOverlinkService.prototype = { - _window: null, - _service: null, - _statusService: null, - - _timer: 0, - _currentLink: { link: "", anchor: null }, - _pendingLink: { link: "", anchor: null }, - _listening: false, - - update: function(aLink, aAnchor) - { - this.clearTimer(); - this.stopListen(); - this._pendingLink = { link: aLink, anchor: aAnchor }; - - if(!aLink) - { - if(this._window.XULBrowserWindow.hideOverLinkImmediately || !this._service.statusLinkOverDelayHide) - { - this._show(); - } - else - { - this._showDelayed(); - } - } - else if(this._currentLink.link || !this._service.statusLinkOverDelayShow) - { - this._show(); - } - else - { - this._showDelayed(); - this.startListen(); - } - }, - - destroy: function() - { - this.clearTimer(); - this.stopListen(); - - ["_currentLink", "_pendingLink", "_statusService", "_window"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - startListen: function() - { - if(!this._listening) - { - this._window.addEventListener("mousemove", this, true); - this._listening = true; - } - }, - - stopListen: function() - { - if(this._listening) - { - this._window.removeEventListener("mousemove", this, true); - this._listening = false; - } - }, - - clearTimer: function() - { - if(this._timer != 0) - { - this._window.clearTimeout(this._timer); - this._timer = 0; - } - }, - - handleEvent: function(event) - { - switch(event.type) - { - case "mousemove": - this.clearTimer(); - this._showDelayed(); - } - }, - - _showDelayed: function() - { - let delay = ((this._pendingLink.link) - ? this._service.statusLinkOverDelayShow - : this._service.statusLinkOverDelayHide); - - this._timer = this._window.setTimeout(function(self) - { - self._timer = 0; - self._show(); - self.stopListen(); - }, delay, this); - }, - - _show: function() - { - this._currentLink = this._pendingLink; - this._statusService.setOverLinkInternal(this._currentLink.link, this._currentLink.anchor); - } + _window: null, + _service: null, + _statusService: null, + + _timer: 0, + _currentLink: { link: "", anchor: null }, + _pendingLink: { link: "", anchor: null }, + _listening: false, + + update: function(aLink, aAnchor) + { + this.clearTimer(); + this.stopListen(); + this._pendingLink = { link: aLink, anchor: aAnchor }; + + if(!aLink) + { + if(this._window.XULBrowserWindow.hideOverLinkImmediately || !this._service.statusLinkOverDelayHide) + { + this._show(); + } + else + { + this._showDelayed(); + } + } + else if(this._currentLink.link || !this._service.statusLinkOverDelayShow) + { + this._show(); + } + else + { + this._showDelayed(); + this.startListen(); + } + }, + + destroy: function() + { + this.clearTimer(); + this.stopListen(); + + ["_currentLink", "_pendingLink", "_statusService", "_window"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + startListen: function() + { + if(!this._listening) + { + this._window.addEventListener("mousemove", this, true); + this._listening = true; + } + }, + + stopListen: function() + { + if(this._listening) + { + this._window.removeEventListener("mousemove", this, true); + this._listening = false; + } + }, + + clearTimer: function() + { + if(this._timer != 0) + { + this._window.clearTimeout(this._timer); + this._timer = 0; + } + }, + + handleEvent: function(event) + { + switch(event.type) + { + case "mousemove": + this.clearTimer(); + this._showDelayed(); + } + }, + + _showDelayed: function() + { + let delay = ((this._pendingLink.link) + ? this._service.statusLinkOverDelayShow + : this._service.statusLinkOverDelayHide); + + this._timer = this._window.setTimeout(function(self) + { + self._timer = 0; + self._show(); + self.stopListen(); + }, delay, this); + }, + + _show: function() + { + this._currentLink = this._pendingLink; + this._statusService.setOverLinkInternal(this._currentLink.link, this._currentLink.anchor); + } }; diff --git a/application/palemoon/components/statusbar/Status4Evar.jsm b/application/palemoon/components/statusbar/Status4Evar.jsm index 03e899afc..055306a88 100644 --- a/application/palemoon/components/statusbar/Status4Evar.jsm +++ b/application/palemoon/components/statusbar/Status4Evar.jsm @@ -23,257 +23,257 @@ CU.import("resource:///modules/statusbar/Toolbars.jsm"); function Status4Evar(window, gBrowser, toolbox) { - this._window = window; - this._toolbox = toolbox; + this._window = window; + this._toolbox = toolbox; - this.getters = new S4EWindowGetters(this._window); - this.toolbars = new S4EToolbars(this._window, gBrowser, this._toolbox, s4e_service, this.getters); - this.statusService = new S4EStatusService(this._window, s4e_service, this.getters); - this.progressMeter = new S4EProgressService(gBrowser, s4e_service, this.getters, this.statusService); - this.downloadStatus = new S4EDownloadService(this._window, gBrowser, s4e_service, this.getters); - this.sizeModeService = new SizeModeService(this._window, this); + this.getters = new S4EWindowGetters(this._window); + this.toolbars = new S4EToolbars(this._window, gBrowser, this._toolbox, s4e_service, this.getters); + this.statusService = new S4EStatusService(this._window, s4e_service, this.getters); + this.progressMeter = new S4EProgressService(gBrowser, s4e_service, this.getters, this.statusService); + this.downloadStatus = new S4EDownloadService(this._window, gBrowser, s4e_service, this.getters); + this.sizeModeService = new SizeModeService(this._window, this); - this._window.addEventListener("unload", this, false); + this._window.addEventListener("unload", this, false); } Status4Evar.prototype = { - _window: null, - _toolbox: null, - - getters: null, - toolbars: null, - statusService: null, - progressMeter: null, - downloadStatus: null, - sizeModeService: null, - - setup: function() - { - this._toolbox.addEventListener("beforecustomization", this, false); - this._toolbox.addEventListener("aftercustomization", this, false); - - this.toolbars.setup(); - this.updateWindow(); - - // OMFG HAX! If a page is already loading, fake a network start event - if(this._window.XULBrowserWindow._busyUI) - { - let nsIWPL = CI.nsIWebProgressListener; - this.progressMeter.onStateChange(0, null, nsIWPL.STATE_START | nsIWPL.STATE_IS_NETWORK, 0); - } - }, - - destroy: function() - { - this._window.removeEventListener("unload", this, false); - this._toolbox.removeEventListener("aftercustomization", this, false); - this._toolbox.removeEventListener("beforecustomization", this, false); - - this.getters.destroy(); - this.statusService.destroy(); - this.downloadStatus.destroy(); - this.progressMeter.destroy(); - this.toolbars.destroy(); - this.sizeModeService.destroy(); - - ["_window", "_toolbox", "getters", "statusService", "downloadStatus", - "progressMeter", "toolbars", "sizeModeService"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - handleEvent: function(aEvent) - { - switch(aEvent.type) - { - case "unload": - this.destroy(); - break; - case "beforecustomization": - this.beforeCustomization(); - break; - case "aftercustomization": - this.updateWindow(); - break; - } - }, - - beforeCustomization: function() - { - this.toolbars.updateSplitters(false); - this.toolbars.updateWindowGripper(false); - - this.statusService.setNoUpdate(true); - let status_label = this.getters.statusWidgetLabel; - if(status_label) - { - status_label.value = this.getters.strings.getString("statusText"); - } - - this.downloadStatus.customizing(true); - }, - - updateWindow: function() - { - this.statusService.setNoUpdate(false); - this.getters.resetGetters(); - this.statusService.buildTextOrder(); - this.statusService.buildBinding(); - this.downloadStatus.init(); - this.downloadStatus.customizing(false); - this.toolbars.updateSplitters(true); - - s4e_service.updateWindow(this._window); - // This also handles the following: - // * buildTextOrder() - // * updateStatusField(true) - // * updateWindowGripper(true) - }, - - launchOptions: function(currentWindow) - { - let optionsURL = "chrome://browser/content/statusbar/prefs.xul"; - let windows = Services.wm.getEnumerator(null); - while (windows.hasMoreElements()) - { - let win = windows.getNext(); - if (win.document.documentURI == optionsURL) - { - win.focus(); - return; - } - } - - let features = "chrome,titlebar,toolbar,centerscreen"; - try - { - let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); - features += instantApply ? ",dialog=no" : ",modal"; - } - catch(e) - { - features += ",modal"; - } - currentWindow.openDialog(optionsURL, "", features); - } + _window: null, + _toolbox: null, + + getters: null, + toolbars: null, + statusService: null, + progressMeter: null, + downloadStatus: null, + sizeModeService: null, + + setup: function() + { + this._toolbox.addEventListener("beforecustomization", this, false); + this._toolbox.addEventListener("aftercustomization", this, false); + + this.toolbars.setup(); + this.updateWindow(); + + // OMFG HAX! If a page is already loading, fake a network start event + if(this._window.XULBrowserWindow._busyUI) + { + let nsIWPL = CI.nsIWebProgressListener; + this.progressMeter.onStateChange(0, null, nsIWPL.STATE_START | nsIWPL.STATE_IS_NETWORK, 0); + } + }, + + destroy: function() + { + this._window.removeEventListener("unload", this, false); + this._toolbox.removeEventListener("aftercustomization", this, false); + this._toolbox.removeEventListener("beforecustomization", this, false); + + this.getters.destroy(); + this.statusService.destroy(); + this.downloadStatus.destroy(); + this.progressMeter.destroy(); + this.toolbars.destroy(); + this.sizeModeService.destroy(); + + ["_window", "_toolbox", "getters", "statusService", "downloadStatus", + "progressMeter", "toolbars", "sizeModeService"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + handleEvent: function(aEvent) + { + switch(aEvent.type) + { + case "unload": + this.destroy(); + break; + case "beforecustomization": + this.beforeCustomization(); + break; + case "aftercustomization": + this.updateWindow(); + break; + } + }, + + beforeCustomization: function() + { + this.toolbars.updateSplitters(false); + this.toolbars.updateWindowGripper(false); + + this.statusService.setNoUpdate(true); + let status_label = this.getters.statusWidgetLabel; + if(status_label) + { + status_label.value = this.getters.strings.getString("statusText"); + } + + this.downloadStatus.customizing(true); + }, + + updateWindow: function() + { + this.statusService.setNoUpdate(false); + this.getters.resetGetters(); + this.statusService.buildTextOrder(); + this.statusService.buildBinding(); + this.downloadStatus.init(); + this.downloadStatus.customizing(false); + this.toolbars.updateSplitters(true); + + s4e_service.updateWindow(this._window); + // This also handles the following: + // * buildTextOrder() + // * updateStatusField(true) + // * updateWindowGripper(true) + }, + + launchOptions: function(currentWindow) + { + let optionsURL = "chrome://browser/content/statusbar/prefs.xul"; + let windows = Services.wm.getEnumerator(null); + while (windows.hasMoreElements()) + { + let win = windows.getNext(); + if (win.document.documentURI == optionsURL) + { + win.focus(); + return; + } + } + + let features = "chrome,titlebar,toolbar,centerscreen"; + try + { + let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); + features += instantApply ? ",dialog=no" : ",modal"; + } + catch(e) + { + features += ",modal"; + } + currentWindow.openDialog(optionsURL, "", features); + } }; function S4EWindowGetters(window) { - this._window = window; + this._window = window; } S4EWindowGetters.prototype = { - _window: null, - _getterMap: - [ - ["addonbar", "addon-bar"], - ["addonbarCloseButton", "addonbar-closebutton"], - ["browserBottomBox", "browser-bottombox"], - ["downloadButton", "status4evar-download-button"], - ["downloadButtonTooltip", "status4evar-download-tooltip"], - ["downloadButtonProgress", "status4evar-download-progress-bar"], - ["downloadButtonLabel", "status4evar-download-label"], - ["downloadButtonAnchor", "status4evar-download-anchor"], - ["downloadNotifyAnchor", "status4evar-download-notification-anchor"], - ["statusBar", "status4evar-status-bar"], - ["statusWidget", "status4evar-status-widget"], - ["statusWidgetLabel", "status4evar-status-text"], - ["strings", "bundle_status4evar"], - ["throbberProgress", "status4evar-throbber-widget"], - ["toolbarProgress", "status4evar-progress-bar"] - ], - - resetGetters: function() - { - let document = this._window.document; - - this._getterMap.forEach(function(getter) - { - let [prop, id] = getter; - delete this[prop]; - this.__defineGetter__(prop, function() - { - delete this[prop]; - return this[prop] = document.getElementById(id); - }); - }, this); - - delete this.statusOverlay; - this.__defineGetter__("statusOverlay", function() - { - let so = this._window.XULBrowserWindow.statusTextField; - if(!so) - { - return null; - } - - delete this.statusOverlay; - return this.statusOverlay = so; - }); - }, - - destroy: function() - { - this._getterMap.forEach(function(getter) - { - let [prop, id] = getter; - delete this[prop]; - }, this); - - ["statusOverlay", "statusOverlay", "_window"].forEach(function(prop) - { - delete this[prop]; - }, this); - } + _window: null, + _getterMap: + [ + ["addonbar", "addon-bar"], + ["addonbarCloseButton", "addonbar-closebutton"], + ["browserBottomBox", "browser-bottombox"], + ["downloadButton", "status4evar-download-button"], + ["downloadButtonTooltip", "status4evar-download-tooltip"], + ["downloadButtonProgress", "status4evar-download-progress-bar"], + ["downloadButtonLabel", "status4evar-download-label"], + ["downloadButtonAnchor", "status4evar-download-anchor"], + ["downloadNotifyAnchor", "status4evar-download-notification-anchor"], + ["statusBar", "status4evar-status-bar"], + ["statusWidget", "status4evar-status-widget"], + ["statusWidgetLabel", "status4evar-status-text"], + ["strings", "bundle_status4evar"], + ["throbberProgress", "status4evar-throbber-widget"], + ["toolbarProgress", "status4evar-progress-bar"] + ], + + resetGetters: function() + { + let document = this._window.document; + + this._getterMap.forEach(function(getter) + { + let [prop, id] = getter; + delete this[prop]; + this.__defineGetter__(prop, function() + { + delete this[prop]; + return this[prop] = document.getElementById(id); + }); + }, this); + + delete this.statusOverlay; + this.__defineGetter__("statusOverlay", function() + { + let so = this._window.XULBrowserWindow.statusTextField; + if(!so) + { + return null; + } + + delete this.statusOverlay; + return this.statusOverlay = so; + }); + }, + + destroy: function() + { + this._getterMap.forEach(function(getter) + { + let [prop, id] = getter; + delete this[prop]; + }, this); + + ["statusOverlay", "statusOverlay", "_window"].forEach(function(prop) + { + delete this[prop]; + }, this); + } }; function SizeModeService(window, s4e) { - this._window = window; - this._s4e = s4e; + this._window = window; + this._s4e = s4e; - this.lastFullScreen = this._window.fullScreen; - this.lastwindowState = this._window.windowState; - this._window.addEventListener("sizemodechange", this, false); + this.lastFullScreen = this._window.fullScreen; + this.lastwindowState = this._window.windowState; + this._window.addEventListener("sizemodechange", this, false); } SizeModeService.prototype = { - _window: null, - _s4e: null, - - lastFullScreen: null, - lastwindowState: null, - - destroy: function() - { - this._window.removeEventListener("sizemodechange", this, false); - - ["_window", "_s4e"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - handleEvent: function(e) - { - if(this._window.fullScreen != this.lastFullScreen) - { - this.lastFullScreen = this._window.fullScreen; - this._s4e.statusService.updateFullScreen(); - } - - if(this._window.windowState != this.lastwindowState) - { - this.lastwindowState = this._window.windowState; - this._s4e.toolbars.updateWindowGripper(true); - } - }, - - QueryInterface: XPCOMUtils.generateQI([ CI.nsIDOMEventListener ]) + _window: null, + _s4e: null, + + lastFullScreen: null, + lastwindowState: null, + + destroy: function() + { + this._window.removeEventListener("sizemodechange", this, false); + + ["_window", "_s4e"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + handleEvent: function(e) + { + if(this._window.fullScreen != this.lastFullScreen) + { + this.lastFullScreen = this._window.fullScreen; + this._s4e.statusService.updateFullScreen(); + } + + if(this._window.windowState != this.lastwindowState) + { + this.lastwindowState = this._window.windowState; + this._s4e.toolbars.updateWindowGripper(true); + } + }, + + QueryInterface: XPCOMUtils.generateQI([ CI.nsIDOMEventListener ]) }; diff --git a/application/palemoon/components/statusbar/Toolbars.jsm b/application/palemoon/components/statusbar/Toolbars.jsm index dda8565fd..321efd092 100644 --- a/application/palemoon/components/statusbar/Toolbars.jsm +++ b/application/palemoon/components/statusbar/Toolbars.jsm @@ -13,209 +13,209 @@ CU.import("resource://gre/modules/Services.jsm"); function S4EToolbars(window, gBrowser, toolbox, service, getters) { - this._window = window; - this._toolbox = toolbox; - this._service = service; - this._getters = getters; - this._handler = new ClassicS4EToolbars(this._window, this._toolbox); + this._window = window; + this._toolbox = toolbox; + this._service = service; + this._getters = getters; + this._handler = new ClassicS4EToolbars(this._window, this._toolbox); } S4EToolbars.prototype = { - _window: null, - _toolbox: null, - _service: null, - _getters: null, - - _handler: null, - - setup: function() - { - this.updateSplitters(false); - this.updateWindowGripper(false); - this._handler.setup(this._service.firstRun); - }, - - destroy: function() - { - this._handler.destroy(); - - ["_window", "_toolbox", "_service", "_getters", "_handler"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - updateSplitters: function(action) - { - let document = this._window.document; - - let splitter_before = document.getElementById("status4evar-status-splitter-before"); - if(splitter_before) - { - splitter_before.parentNode.removeChild(splitter_before); - } - - let splitter_after = document.getElementById("status4evar-status-splitter-after"); - if(splitter_after) - { - splitter_after.parentNode.removeChild(splitter_after); - } - - let status = this._getters.statusWidget; - if(!action || !status) - { - return; - } - - let urlbar = document.getElementById("urlbar-container"); - let stop = document.getElementById("stop-button"); - let fullscreenflex = document.getElementById("fullscreenflex"); - - let nextSibling = status.nextSibling; - let previousSibling = status.previousSibling; - - function getSplitter(splitter, suffix) - { - if(!splitter) - { - splitter = document.createElement("splitter"); - splitter.id = "status4evar-status-splitter-" + suffix; - splitter.setAttribute("resizebefore", "flex"); - splitter.setAttribute("resizeafter", "flex"); - splitter.className = "chromeclass-toolbar-additional status4evar-status-splitter"; - } - return splitter; - } - - if((previousSibling && previousSibling.flex > 0) - || (urlbar && stop && urlbar.getAttribute("combined") && stop == previousSibling)) - { - status.parentNode.insertBefore(getSplitter(splitter_before, "before"), status); - } - - if(nextSibling && nextSibling.flex > 0 && nextSibling != fullscreenflex) - { - status.parentNode.insertBefore(getSplitter(splitter_after, "after"), nextSibling); - } - }, - - updateWindowGripper: function(action) - { - let document = this._window.document; - - let gripper = document.getElementById("status4evar-window-gripper"); - let toolbar = this._getters.statusBar || this._getters.addonbar; - - if(!action || !toolbar || !this._service.addonbarWindowGripper - || this._window.windowState != CI.nsIDOMChromeWindow.STATE_NORMAL || toolbar.toolbox.customizing) - { - if(gripper) - { - gripper.parentNode.removeChild(gripper); - } - return; - } - - gripper = this._handler.buildGripper(toolbar, gripper, "status4evar-window-gripper"); - - toolbar.appendChild(gripper); - } + _window: null, + _toolbox: null, + _service: null, + _getters: null, + + _handler: null, + + setup: function() + { + this.updateSplitters(false); + this.updateWindowGripper(false); + this._handler.setup(this._service.firstRun); + }, + + destroy: function() + { + this._handler.destroy(); + + ["_window", "_toolbox", "_service", "_getters", "_handler"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + updateSplitters: function(action) + { + let document = this._window.document; + + let splitter_before = document.getElementById("status4evar-status-splitter-before"); + if(splitter_before) + { + splitter_before.parentNode.removeChild(splitter_before); + } + + let splitter_after = document.getElementById("status4evar-status-splitter-after"); + if(splitter_after) + { + splitter_after.parentNode.removeChild(splitter_after); + } + + let status = this._getters.statusWidget; + if(!action || !status) + { + return; + } + + let urlbar = document.getElementById("urlbar-container"); + let stop = document.getElementById("stop-button"); + let fullscreenflex = document.getElementById("fullscreenflex"); + + let nextSibling = status.nextSibling; + let previousSibling = status.previousSibling; + + function getSplitter(splitter, suffix) + { + if(!splitter) + { + splitter = document.createElement("splitter"); + splitter.id = "status4evar-status-splitter-" + suffix; + splitter.setAttribute("resizebefore", "flex"); + splitter.setAttribute("resizeafter", "flex"); + splitter.className = "chromeclass-toolbar-additional status4evar-status-splitter"; + } + return splitter; + } + + if((previousSibling && previousSibling.flex > 0) + || (urlbar && stop && urlbar.getAttribute("combined") && stop == previousSibling)) + { + status.parentNode.insertBefore(getSplitter(splitter_before, "before"), status); + } + + if(nextSibling && nextSibling.flex > 0 && nextSibling != fullscreenflex) + { + status.parentNode.insertBefore(getSplitter(splitter_after, "after"), nextSibling); + } + }, + + updateWindowGripper: function(action) + { + let document = this._window.document; + + let gripper = document.getElementById("status4evar-window-gripper"); + let toolbar = this._getters.statusBar || this._getters.addonbar; + + if(!action || !toolbar || !this._service.addonbarWindowGripper + || this._window.windowState != CI.nsIDOMChromeWindow.STATE_NORMAL || toolbar.toolbox.customizing) + { + if(gripper) + { + gripper.parentNode.removeChild(gripper); + } + return; + } + + gripper = this._handler.buildGripper(toolbar, gripper, "status4evar-window-gripper"); + + toolbar.appendChild(gripper); + } }; function ClassicS4EToolbars(window, toolbox) { - this._window = window; - this._toolbox = toolbox; + this._window = window; + this._toolbox = toolbox; } ClassicS4EToolbars.prototype = { - _window: null, - _toolbox: null, - - setup: function(firstRun) - { - let document = this._window.document; - - let addon_bar = document.getElementById("addon-bar"); - if(addon_bar) - { - let baseSet = "addonbar-closebutton" - + ",status4evar-status-widget" - + ",status4evar-progress-widget"; - - // Update the defaultSet - let defaultSet = baseSet; - let defaultSetIgnore = ["addonbar-closebutton", "spring", "status-bar"]; - addon_bar.getAttribute("defaultset").split(",").forEach(function(item) - { - if(defaultSetIgnore.indexOf(item) == -1) - { - defaultSet += "," + item; - } - }); - defaultSet += ",status-bar" - addon_bar.setAttribute("defaultset", defaultSet); - - // Update the currentSet - if(firstRun) - { - let isCustomizableToolbar = function(aElt) - { - return aElt.localName == "toolbar" && aElt.getAttribute("customizable") == "true"; - } - - let isCustomizedAlready = false; - let toolbars = Array.filter(this._toolbox.childNodes, isCustomizableToolbar).concat( - Array.filter(this._toolbox.externalToolbars, isCustomizableToolbar)); - toolbars.forEach(function(toolbar) - { - if(toolbar.currentSet.indexOf("status4evar") > -1) - { - isCustomizedAlready = true; - } - }); - - if(!isCustomizedAlready) - { - let currentSet = baseSet; - let currentSetIgnore = ["addonbar-closebutton", "spring"]; - addon_bar.currentSet.split(",").forEach(function(item) - { - if(currentSetIgnore.indexOf(item) == -1) - { - currentSet += "," + item; - } - }); - addon_bar.currentSet = currentSet; - addon_bar.setAttribute("currentset", currentSet); - document.persist(addon_bar.id, "currentset"); - this._window.setToolbarVisibility(addon_bar, true); - } - } - } - }, - - destroy: function() - { - ["_window", "_toolbox"].forEach(function(prop) - { - delete this[prop]; - }, this); - }, - - buildGripper: function(toolbar, gripper, id) - { - if(!gripper) - { - let document = this._window.document; - - gripper = document.createElement("resizer"); - gripper.id = id; - gripper.dir = "bottomend"; - } - - return gripper; - } + _window: null, + _toolbox: null, + + setup: function(firstRun) + { + let document = this._window.document; + + let addon_bar = document.getElementById("addon-bar"); + if(addon_bar) + { + let baseSet = "addonbar-closebutton" + + ",status4evar-status-widget" + + ",status4evar-progress-widget"; + + // Update the defaultSet + let defaultSet = baseSet; + let defaultSetIgnore = ["addonbar-closebutton", "spring", "status-bar"]; + addon_bar.getAttribute("defaultset").split(",").forEach(function(item) + { + if(defaultSetIgnore.indexOf(item) == -1) + { + defaultSet += "," + item; + } + }); + defaultSet += ",status-bar" + addon_bar.setAttribute("defaultset", defaultSet); + + // Update the currentSet + if(firstRun) + { + let isCustomizableToolbar = function(aElt) + { + return aElt.localName == "toolbar" && aElt.getAttribute("customizable") == "true"; + } + + let isCustomizedAlready = false; + let toolbars = Array.filter(this._toolbox.childNodes, isCustomizableToolbar).concat( + Array.filter(this._toolbox.externalToolbars, isCustomizableToolbar)); + toolbars.forEach(function(toolbar) + { + if(toolbar.currentSet.indexOf("status4evar") > -1) + { + isCustomizedAlready = true; + } + }); + + if(!isCustomizedAlready) + { + let currentSet = baseSet; + let currentSetIgnore = ["addonbar-closebutton", "spring"]; + addon_bar.currentSet.split(",").forEach(function(item) + { + if(currentSetIgnore.indexOf(item) == -1) + { + currentSet += "," + item; + } + }); + addon_bar.currentSet = currentSet; + addon_bar.setAttribute("currentset", currentSet); + document.persist(addon_bar.id, "currentset"); + this._window.setToolbarVisibility(addon_bar, true); + } + } + } + }, + + destroy: function() + { + ["_window", "_toolbox"].forEach(function(prop) + { + delete this[prop]; + }, this); + }, + + buildGripper: function(toolbar, gripper, id) + { + if(!gripper) + { + let document = this._window.document; + + gripper = document.createElement("resizer"); + gripper.id = id; + gripper.dir = "bottomend"; + } + + return gripper; + } }; diff --git a/application/palemoon/components/statusbar/content/overlay.css b/application/palemoon/components/statusbar/content/overlay.css index 6375b8ef8..fd3452119 100644 --- a/application/palemoon/components/statusbar/content/overlay.css +++ b/application/palemoon/components/statusbar/content/overlay.css @@ -8,8 +8,7 @@ * Status Popup */ -statuspanel -{ - -moz-binding: url("chrome://browser/content/statusbar/tabbrowser.xml#statuspanel"); +statuspanel { + -moz-binding: url("chrome://browser/content/statusbar/tabbrowser.xml#statuspanel"); } diff --git a/application/palemoon/components/statusbar/content/overlay.js b/application/palemoon/components/statusbar/content/overlay.js index cf6cfe296..b868aaf0e 100644 --- a/application/palemoon/components/statusbar/content/overlay.js +++ b/application/palemoon/components/statusbar/content/overlay.js @@ -6,11 +6,11 @@ if(!caligon) var caligon = {}; window.addEventListener("load", function buildS4E() { - window.removeEventListener("load", buildS4E, false); + window.removeEventListener("load", buildS4E, false); - Components.utils.import("resource:///modules/statusbar/Status4Evar.jsm"); + Components.utils.import("resource:///modules/statusbar/Status4Evar.jsm"); - caligon.status4evar = new Status4Evar(window, gBrowser, gNavToolbox); - caligon.status4evar.setup(); + caligon.status4evar = new Status4Evar(window, gBrowser, gNavToolbox); + caligon.status4evar.setup(); }, false); diff --git a/application/palemoon/components/statusbar/content/overlay.xul b/application/palemoon/components/statusbar/content/overlay.xul index f9a61a92e..b9934ee65 100644 --- a/application/palemoon/components/statusbar/content/overlay.xul +++ b/application/palemoon/components/statusbar/content/overlay.xul @@ -13,23 +13,23 @@ <overlay id="status4evar-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <stringbundleset id="stringbundleset"> - <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/overlay.properties" /> - </stringbundleset> + <stringbundleset id="stringbundleset"> + <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/overlay.properties" /> + </stringbundleset> - <script type="application/javascript" src="chrome://browser/content/statusbar/overlay.js" /> + <script type="application/javascript" src="chrome://browser/content/statusbar/overlay.js" /> - <commandset> - <command id="S4E:Options" oncommand="caligon.status4evar.launchOptions(window);"/> - </commandset> + <commandset> + <command id="S4E:Options" oncommand="caligon.status4evar.launchOptions(window);"/> + </commandset> - <popupset id="mainPopupSet"> - <hbox id="status4evar-download-notification-container" mousethrough="always"> - <vbox id="status4evar-download-notification-anchor"> - <vbox id="status4evar-download-notification-icon" /> - </vbox> - </hbox> - </popupset> + <popupset id="mainPopupSet"> + <hbox id="status4evar-download-notification-container" mousethrough="always"> + <vbox id="status4evar-download-notification-anchor"> + <vbox id="status4evar-download-notification-icon" /> + </vbox> + </hbox> + </popupset> <menupopup id="menu_ToolsPopup"> <menuitem id="statusbar-options-fx" command="S4E:Options" @@ -41,41 +41,41 @@ label="&status4evar.menu.options.label;"/> </menupopup> - <toolbarpalette id="BrowserToolbarPalette"> - <toolbaritem id="status4evar-status-widget" - title="&status4evar.status.widget.title;" - removable="true" flex="1" persist="width" width="100"> - <label id="status4evar-status-text" flex="1" crop="end" value="&status4evar.status.widget.title;" /> - </toolbaritem> + <toolbarpalette id="BrowserToolbarPalette"> + <toolbaritem id="status4evar-status-widget" + title="&status4evar.status.widget.title;" + removable="true" flex="1" persist="width" width="100"> + <label id="status4evar-status-text" flex="1" crop="end" value="&status4evar.status.widget.title;" /> + </toolbaritem> - <toolbarbutton id="status4evar-download-button" - title="&status4evar.download.widget.title;" - class="toolbarbutton-1 chromeclass-toolbar-additional" - removable="true" collapsed="true" tooltip="_child" - oncommand="caligon.status4evar.downloadStatus.openUI(event)"> - <stack id="status4evar-download-anchor" class="toolbarbutton-icon"> - <vbox id="status4evar-download-icon" /> - <vbox pack="end"> - <progressmeter id="status4evar-download-progress-bar" mode="normal" value="0" collapsed="true" min="0" max="100" /> - </vbox> - </stack> - <tooltip id="status4evar-download-tooltip" /> - <label id="status4evar-download-label" value="&status4evar.download.widget.title;" class="toolbarbutton-text" crop="right" flex="1" /> - </toolbarbutton> + <toolbarbutton id="status4evar-download-button" + title="&status4evar.download.widget.title;" + class="toolbarbutton-1 chromeclass-toolbar-additional" + removable="true" collapsed="true" tooltip="_child" + oncommand="caligon.status4evar.downloadStatus.openUI(event)"> + <stack id="status4evar-download-anchor" class="toolbarbutton-icon"> + <vbox id="status4evar-download-icon" /> + <vbox pack="end"> + <progressmeter id="status4evar-download-progress-bar" mode="normal" value="0" collapsed="true" min="0" max="100" /> + </vbox> + </stack> + <tooltip id="status4evar-download-tooltip" /> + <label id="status4evar-download-label" value="&status4evar.download.widget.title;" class="toolbarbutton-text" crop="right" flex="1" /> + </toolbarbutton> - <toolbaritem id="status4evar-progress-widget" - title="&status4evar.progress.widget.title;" - removable="true"> - <progressmeter id="status4evar-progress-bar" class="progressmeter-statusbar" - mode="normal" value="0" collapsed="true" min="0" max="100" /> - </toolbaritem> + <toolbaritem id="status4evar-progress-widget" + title="&status4evar.progress.widget.title;" + removable="true"> + <progressmeter id="status4evar-progress-bar" class="progressmeter-statusbar" + mode="normal" value="0" collapsed="true" min="0" max="100" /> + </toolbaritem> - <toolbarbutton id="status4evar-options-button" - title="&status4evar.options.widget.title;" - class="toolbarbutton-1 chromeclass-toolbar-additional" - label="&status4evar.options.widget.label;" - removable="true" command="S4E:Options" tooltiptext="&status4evar.options.widget.title;" /> - </toolbarpalette> + <toolbarbutton id="status4evar-options-button" + title="&status4evar.options.widget.title;" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&status4evar.options.widget.label;" + removable="true" command="S4E:Options" tooltiptext="&status4evar.options.widget.title;" /> + </toolbarpalette> <statusbar id="status-bar" ordinal="1" /> </overlay> diff --git a/application/palemoon/components/statusbar/content/prefs.css b/application/palemoon/components/statusbar/content/prefs.css index c627f78fb..bafaa6129 100644 --- a/application/palemoon/components/statusbar/content/prefs.css +++ b/application/palemoon/components/statusbar/content/prefs.css @@ -4,8 +4,7 @@ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); -.css-bg-editor -{ - -moz-binding: url("chrome://browser/content/statusbar/prefs.xml#css-bg-editor"); +.css-bg-editor { + -moz-binding: url("chrome://browser/content/statusbar/prefs.xml#css-bg-editor"); } diff --git a/application/palemoon/components/statusbar/content/prefs.js b/application/palemoon/components/statusbar/content/prefs.js index ed81fb271..47fd4b63d 100644 --- a/application/palemoon/components/statusbar/content/prefs.js +++ b/application/palemoon/components/statusbar/content/prefs.js @@ -6,267 +6,267 @@ Components.utils.import("resource://gre/modules/Services.jsm"); var status4evarPrefs = { - get dynamicProgressStyle() - { - let styleSheets = window.document.styleSheets; - for(let i = 0; i < styleSheets.length; i++) - { - let styleSheet = styleSheets[i]; - if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") - { - delete this.dynamicProgressStyle; - return this.dynamicProgressStyle = styleSheet; - } - } - - return null; - }, + get dynamicProgressStyle() + { + let styleSheets = window.document.styleSheets; + for(let i = 0; i < styleSheets.length; i++) + { + let styleSheet = styleSheets[i]; + if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") + { + delete this.dynamicProgressStyle; + return this.dynamicProgressStyle = styleSheet; + } + } + + return null; + }, // // Status timeout management // - get statusTimeoutPref() - { - delete this.statusTimeoutPref; - return this.statusTimeoutPref = document.getElementById("status4evar-pref-status-timeout"); - }, - - get statusTimeoutCheckbox() - { - delete this.statusTimeoutCheckbox; - return this.statusTimeoutCheckbox = document.getElementById("status4evar-status-timeout-check"); - }, - - statusTimeoutChanged: function() - { - if(this.statusTimeoutPref.value > 0) - { - this.statusTimeoutPref.disabled = false; - this.statusTimeoutCheckbox.checked = true; - } - else - { - this.statusTimeoutPref.disabled = true; - this.statusTimeoutCheckbox.checked = false; - } - }, - - statusTimeoutSync: function() - { - this.statusTimeoutChanged(); - return undefined; - }, - - statusTimeoutToggle: function() - { - if(this.statusTimeoutPref.disabled == this.statusTimeoutCheckbox.checked) - { - if(this.statusTimeoutCheckbox.checked) - { - this.statusTimeoutPref.value = 10; - } - else - { - this.statusTimeoutPref.value = 0; - } - } - }, + get statusTimeoutPref() + { + delete this.statusTimeoutPref; + return this.statusTimeoutPref = document.getElementById("status4evar-pref-status-timeout"); + }, + + get statusTimeoutCheckbox() + { + delete this.statusTimeoutCheckbox; + return this.statusTimeoutCheckbox = document.getElementById("status4evar-status-timeout-check"); + }, + + statusTimeoutChanged: function() + { + if(this.statusTimeoutPref.value > 0) + { + this.statusTimeoutPref.disabled = false; + this.statusTimeoutCheckbox.checked = true; + } + else + { + this.statusTimeoutPref.disabled = true; + this.statusTimeoutCheckbox.checked = false; + } + }, + + statusTimeoutSync: function() + { + this.statusTimeoutChanged(); + return undefined; + }, + + statusTimeoutToggle: function() + { + if(this.statusTimeoutPref.disabled == this.statusTimeoutCheckbox.checked) + { + if(this.statusTimeoutCheckbox.checked) + { + this.statusTimeoutPref.value = 10; + } + else + { + this.statusTimeoutPref.value = 0; + } + } + }, // // Status network management // - get statusNetworkPref() - { - delete this.statusNetworkPref; - return this.statusNetworkPref = document.getElementById("status4evar-pref-status-network"); - }, - - get statusNetworkXHRPref() - { - delete this.statusNetworkXHRPref; - return this.statusNetworkXHRPref = document.getElementById("status4evar-pref-status-network-xhr"); - }, - - statusNetworkChanged: function() - { - this.statusNetworkXHRPref.disabled = ! this.statusNetworkPref.value; - }, - - statusNetworkSync: function() - { - this.statusNetworkChanged(); - return undefined; - }, + get statusNetworkPref() + { + delete this.statusNetworkPref; + return this.statusNetworkPref = document.getElementById("status4evar-pref-status-network"); + }, + + get statusNetworkXHRPref() + { + delete this.statusNetworkXHRPref; + return this.statusNetworkXHRPref = document.getElementById("status4evar-pref-status-network-xhr"); + }, + + statusNetworkChanged: function() + { + this.statusNetworkXHRPref.disabled = ! this.statusNetworkPref.value; + }, + + statusNetworkSync: function() + { + this.statusNetworkChanged(); + return undefined; + }, // // Status Text langth managment // - get textMaxLengthPref() - { - delete this.textMaxLengthPref; - return this.textMaxLengthPref = document.getElementById("status4evar-pref-status-toolbar-maxLength"); - }, - - get textMaxLengthCheckbox() - { - delete this.textMaxLengthCheckbox; - return this.textMaxLengthCheckbox = document.getElementById("status4evar-status-toolbar-maxLength-check"); - }, - - textLengthChanged: function() - { - if(this.textMaxLengthPref.value > 0) - { - this.textMaxLengthPref.disabled = false; - this.textMaxLengthCheckbox.checked = true; - } - else - { - this.textMaxLengthPref.disabled = true; - this.textMaxLengthCheckbox.checked = false; - } - }, - - textLengthSync: function() - { - this.textLengthChanged(); - return undefined; - }, - - textLengthToggle: function() - { - if(this.textMaxLengthPref.disabled == this.textMaxLengthCheckbox.checked) - { - if(this.textMaxLengthCheckbox.checked) - { - this.textMaxLengthPref.value = 800; - } - else - { - this.textMaxLengthPref.value = 0; - } - } - }, + get textMaxLengthPref() + { + delete this.textMaxLengthPref; + return this.textMaxLengthPref = document.getElementById("status4evar-pref-status-toolbar-maxLength"); + }, + + get textMaxLengthCheckbox() + { + delete this.textMaxLengthCheckbox; + return this.textMaxLengthCheckbox = document.getElementById("status4evar-status-toolbar-maxLength-check"); + }, + + textLengthChanged: function() + { + if(this.textMaxLengthPref.value > 0) + { + this.textMaxLengthPref.disabled = false; + this.textMaxLengthCheckbox.checked = true; + } + else + { + this.textMaxLengthPref.disabled = true; + this.textMaxLengthCheckbox.checked = false; + } + }, + + textLengthSync: function() + { + this.textLengthChanged(); + return undefined; + }, + + textLengthToggle: function() + { + if(this.textMaxLengthPref.disabled == this.textMaxLengthCheckbox.checked) + { + if(this.textMaxLengthCheckbox.checked) + { + this.textMaxLengthPref.value = 800; + } + else + { + this.textMaxLengthPref.value = 0; + } + } + }, // // Toolbar progress style management // - get progressToolbarStylePref() - { - delete this.progressToolbarStylePref; - return this.progressToolbarStylePref = document.getElementById("status4evar-pref-progress-toolbar-style"); - }, - - get progressToolbarCSSPref() - { - delete this.progressToolbarCSSPref; - return this.progressToolbarCSSPref = document.getElementById("status4evar-pref-progress-toolbar-css"); - }, - - get progressToolbarProgress() - { - delete this.progressToolbarProgress; - return this.progressToolbarProgress = document.getElementById("status4evar-progress-bar"); - }, - - progressToolbarCSSChanged: function() - { - if(!this.progressToolbarCSSPref.value) - { - this.progressToolbarCSSPref.value = "#33FF33"; - } - this.dynamicProgressStyle.cssRules[1].style.background = this.progressToolbarCSSPref.value; - }, - - progressToolbarStyleChanged: function() - { - this.progressToolbarCSSChanged(); - this.progressToolbarCSSPref.disabled = !this.progressToolbarStylePref.value; - if(this.progressToolbarStylePref.value) - { - this.progressToolbarProgress.setAttribute("s4estyle", true); - } - else - { - this.progressToolbarProgress.removeAttribute("s4estyle"); - } - }, - - progressToolbarStyleSync: function() - { - this.progressToolbarStyleChanged(); - return undefined; - }, + get progressToolbarStylePref() + { + delete this.progressToolbarStylePref; + return this.progressToolbarStylePref = document.getElementById("status4evar-pref-progress-toolbar-style"); + }, + + get progressToolbarCSSPref() + { + delete this.progressToolbarCSSPref; + return this.progressToolbarCSSPref = document.getElementById("status4evar-pref-progress-toolbar-css"); + }, + + get progressToolbarProgress() + { + delete this.progressToolbarProgress; + return this.progressToolbarProgress = document.getElementById("status4evar-progress-bar"); + }, + + progressToolbarCSSChanged: function() + { + if(!this.progressToolbarCSSPref.value) + { + this.progressToolbarCSSPref.value = "#33FF33"; + } + this.dynamicProgressStyle.cssRules[1].style.background = this.progressToolbarCSSPref.value; + }, + + progressToolbarStyleChanged: function() + { + this.progressToolbarCSSChanged(); + this.progressToolbarCSSPref.disabled = !this.progressToolbarStylePref.value; + if(this.progressToolbarStylePref.value) + { + this.progressToolbarProgress.setAttribute("s4estyle", true); + } + else + { + this.progressToolbarProgress.removeAttribute("s4estyle"); + } + }, + + progressToolbarStyleSync: function() + { + this.progressToolbarStyleChanged(); + return undefined; + }, // // Download progress management // - get downloadProgressCheck() - { - delete this.downloadProgressCheck; - return this.downloadProgressCheck = document.getElementById("status4evar-download-progress-check"); - }, - - get downloadProgressPref() - { - delete this.downloadProgressPref; - return this.downloadProgressPref = document.getElementById("status4evar-pref-download-progress"); - }, - - get downloadProgressColorActivePref() - { - delete this.downloadProgressActiveColorPref; - return this.downloadProgressActiveColorPref = document.getElementById("status4evar-pref-download-color-active"); - }, - - get downloadProgressColorPausedPref() - { - delete this.downloadProgressPausedColorPref; - return this.downloadProgressPausedColorPref = document.getElementById("status4evar-pref-download-color-paused"); - }, - - downloadProgressSync: function() - { - let val = this.downloadProgressPref.value; - this.downloadProgressColorActivePref.disabled = (val == 0); - this.downloadProgressColorPausedPref.disabled = (val == 0); - this.downloadProgressPref.disabled = (val == 0); - this.downloadProgressCheck.checked = (val != 0); - return ((val == 0) ? 1 : val); - }, - - downloadProgressToggle: function() - { - let enabled = this.downloadProgressCheck.checked; - this.downloadProgressPref.value = ((enabled) ? 1 : 0); - }, + get downloadProgressCheck() + { + delete this.downloadProgressCheck; + return this.downloadProgressCheck = document.getElementById("status4evar-download-progress-check"); + }, + + get downloadProgressPref() + { + delete this.downloadProgressPref; + return this.downloadProgressPref = document.getElementById("status4evar-pref-download-progress"); + }, + + get downloadProgressColorActivePref() + { + delete this.downloadProgressActiveColorPref; + return this.downloadProgressActiveColorPref = document.getElementById("status4evar-pref-download-color-active"); + }, + + get downloadProgressColorPausedPref() + { + delete this.downloadProgressPausedColorPref; + return this.downloadProgressPausedColorPref = document.getElementById("status4evar-pref-download-color-paused"); + }, + + downloadProgressSync: function() + { + let val = this.downloadProgressPref.value; + this.downloadProgressColorActivePref.disabled = (val == 0); + this.downloadProgressColorPausedPref.disabled = (val == 0); + this.downloadProgressPref.disabled = (val == 0); + this.downloadProgressCheck.checked = (val != 0); + return ((val == 0) ? 1 : val); + }, + + downloadProgressToggle: function() + { + let enabled = this.downloadProgressCheck.checked; + this.downloadProgressPref.value = ((enabled) ? 1 : 0); + }, // // Pref Window load // - get downloadButtonActionCommandPref() - { - delete this.downloadButtonActionCommandPref; - return this.downloadButtonActionCommandPref = document.getElementById("status4evar-pref-download-button-action-command"); - }, - - get downloadButtonActionThirdPartyItem() - { - delete this.downloadButtonActionThirdPartyItem; - return this.downloadButtonActionThirdPartyItem = document.getElementById("status4evar-download-button-action-menu-thirdparty"); - }, - - onPrefWindowLoad: function() - { - if(!this.downloadButtonActionCommandPref.value) - { - this.downloadButtonActionThirdPartyItem.disabled = true; - } - }, - - onPrefWindowUnLoad: function() - { - } + get downloadButtonActionCommandPref() + { + delete this.downloadButtonActionCommandPref; + return this.downloadButtonActionCommandPref = document.getElementById("status4evar-pref-download-button-action-command"); + }, + + get downloadButtonActionThirdPartyItem() + { + delete this.downloadButtonActionThirdPartyItem; + return this.downloadButtonActionThirdPartyItem = document.getElementById("status4evar-download-button-action-menu-thirdparty"); + }, + + onPrefWindowLoad: function() + { + if(!this.downloadButtonActionCommandPref.value) + { + this.downloadButtonActionThirdPartyItem.disabled = true; + } + }, + + onPrefWindowUnLoad: function() + { + } } var XULBrowserWindow = { diff --git a/application/palemoon/components/statusbar/content/prefs.xml b/application/palemoon/components/statusbar/content/prefs.xml index cf4a00bb8..44baab18d 100644 --- a/application/palemoon/components/statusbar/content/prefs.xml +++ b/application/palemoon/components/statusbar/content/prefs.xml @@ -11,694 +11,694 @@ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> - <binding id="css-bg-editor"> - <content sizetopopup="pref"> - <xul:vbox flex="1"> - <xul:deck anonid="css-bg-editor-deck" flex="1"> - <xul:vbox> - <xul:hbox align="center"> - <xul:label xbl:inherits="disabled">&status4evar.editor.css.color.label;</xul:label> - <xul:colorpicker anonid="css-bg-editor-color" type="button" onchange="this._editor._buildCSS();" xbl:inherits="disabled" /> - </xul:hbox> - - <xul:hbox align="center"> - <xul:label xbl:inherits="disabled">&status4evar.editor.css.image.label;</xul:label> - <xul:textbox anonid="css-bg-editor-image" readonly="true" flex="1" xbl:inherits="disabled" /> - <xul:button anonid="css-bg-editor-image-browse" label="&status4evar.option.browse;" oncommand="this._editor._imageBrowse();" xbl:inherits="disabled" /> - </xul:hbox> - <xul:hbox align="center" pack="end"> - <xul:button anonid="css-bg-editor-image-clear" label="&status4evar.option.clear;" oncommand="this._editor._imageClear();" xbl:inherits="disabled=no-image" /> - </xul:hbox> - - <xul:hbox> - <xul:groupbox pack="center"> - <xul:caption label="" /> - <xul:hbox flex="1" align="center"> - <xul:label>X</xul:label> - </xul:hbox> - <xul:separator class="groove" orient="horizontal" /> - <xul:hbox flex="1" align="center"> - <xul:label>Y</xul:label> - </xul:hbox> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.repeat;" xbl:inherits="disabled=no-image" /> - <xul:menulist anonid="css-bg-editor-image-repeat-x" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> - <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> + <binding id="css-bg-editor"> + <content sizetopopup="pref"> + <xul:vbox flex="1"> + <xul:deck anonid="css-bg-editor-deck" flex="1"> + <xul:vbox> + <xul:hbox align="center"> + <xul:label xbl:inherits="disabled">&status4evar.editor.css.color.label;</xul:label> + <xul:colorpicker anonid="css-bg-editor-color" type="button" onchange="this._editor._buildCSS();" xbl:inherits="disabled" /> + </xul:hbox> + + <xul:hbox align="center"> + <xul:label xbl:inherits="disabled">&status4evar.editor.css.image.label;</xul:label> + <xul:textbox anonid="css-bg-editor-image" readonly="true" flex="1" xbl:inherits="disabled" /> + <xul:button anonid="css-bg-editor-image-browse" label="&status4evar.option.browse;" oncommand="this._editor._imageBrowse();" xbl:inherits="disabled" /> + </xul:hbox> + <xul:hbox align="center" pack="end"> + <xul:button anonid="css-bg-editor-image-clear" label="&status4evar.option.clear;" oncommand="this._editor._imageClear();" xbl:inherits="disabled=no-image" /> + </xul:hbox> + + <xul:hbox> + <xul:groupbox pack="center"> + <xul:caption label="" /> + <xul:hbox flex="1" align="center"> + <xul:label>X</xul:label> + </xul:hbox> + <xul:separator class="groove" orient="horizontal" /> + <xul:hbox flex="1" align="center"> + <xul:label>Y</xul:label> + </xul:hbox> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.repeat;" xbl:inherits="disabled=no-image" /> + <xul:menulist anonid="css-bg-editor-image-repeat-x" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> + <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> <!-- - <xul:menuitem label="&status4evar.option.space;" value="space" /> - <xul:menuitem label="&status4evar.option.round;" value="round" /> + <xul:menuitem label="&status4evar.option.space;" value="space" /> + <xul:menuitem label="&status4evar.option.round;" value="round" /> --> - </xul:menupopup> - </xul:menulist> - <xul:separator class="groove" orient="horizontal" /> - <xul:menulist anonid="css-bg-editor-image-repeat-y" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> - <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> + </xul:menupopup> + </xul:menulist> + <xul:separator class="groove" orient="horizontal" /> + <xul:menulist anonid="css-bg-editor-image-repeat-y" sizetopopup="always" onselect="this._editor._buildCSS();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.no-repeat;" value="no-repeat" /> + <xul:menuitem label="&status4evar.option.repeat;" value="repeat" /> <!-- - <xul:menuitem label="&status4evar.option.space;" value="space" /> - <xul:menuitem label="&status4evar.option.round;" value="round" /> + <xul:menuitem label="&status4evar.option.space;" value="space" /> + <xul:menuitem label="&status4evar.option.round;" value="round" /> --> - </xul:menupopup> - </xul:menulist> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.position;" xbl:inherits="disabled=no-image" /> - <xul:menulist anonid="css-bg-editor-image-position-x" sizetopopup="always" onselect="this._editor._updatePositionX();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.left;" value="left" /> - <xul:menuitem label="&status4evar.option.center;" value="center" /> - <xul:menuitem label="&status4evar.option.right;" value="right" /> - <xul:menuitem label="&status4evar.option.offset;" value="offset" /> - </xul:menupopup> - </xul:menulist> - <xul:separator class="groove" orient="horizontal" /> - <xul:menulist anonid="css-bg-editor-image-position-y" sizetopopup="always" onselect="this._editor._updatePositionY();" xbl:inherits="disabled=no-image"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.top;" value="top" /> - <xul:menuitem label="&status4evar.option.center;" value="center" /> - <xul:menuitem label="&status4evar.option.bottom;" value="bottom" /> - <xul:menuitem label="&status4evar.option.offset;" value="offset" /> - </xul:menupopup> - </xul:menulist> - </xul:groupbox> - - <xul:groupbox> - <xul:caption label="&status4evar.editor.css.image.offset;" xbl:inherits="disabled=no-image" /> - <xul:hbox> - <xul:textbox anonid="css-bg-editor-image-offset-x" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> - <xul:menulist anonid="css-bg-editor-image-offset-unit-x" sizetopopup="always" onselect="this._editor._buildCSS();"> - <xul:menupopup> - <xul:menuitem label="%" value="%" /> - <xul:menuitem label="px" value="px" /> - <xul:menuitem label="em" value="em" /> - <xul:menuitem label="in" value="in" /> - <xul:menuitem label="cm" value="cm" /> - <xul:menuitem label="mm" value="mm" /> - <xul:menuitem label="pt" value="pt" /> - <xul:menuitem label="pc" value="pc" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - <xul:separator class="groove" orient="horizontal" /> - <xul:hbox> - <xul:textbox anonid="css-bg-editor-image-offset-y" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> - <xul:menulist anonid="css-bg-editor-image-offset-unit-y" sizetopopup="always" onselect="this._editor._buildCSS();"> - <xul:menupopup> - <xul:menuitem label="%" value="%" /> - <xul:menuitem label="px" value="px" /> - <xul:menuitem label="em" value="em" /> - <xul:menuitem label="in" value="in" /> - <xul:menuitem label="cm" value="cm" /> - <xul:menuitem label="mm" value="mm" /> - <xul:menuitem label="pt" value="pt" /> - <xul:menuitem label="pc" value="pc" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - </xul:groupbox> - </xul:hbox> - </xul:vbox> - - <xul:textbox anonid="css-bg-editor-css-text" multiline="true" rows="6" xbl:inherits="disabled" /> - </xul:deck> - </xul:vbox> - - <xul:hbox align="center" pack="end"> - <children includes="progressmeter|toolbox" /> - <xul:label xbl:inherits="disabled">&status4evar.editor.label;</xul:label> - <xul:menulist anonid="css-bg-editor-mode-menu" sizetopopup="always" onselect="this._editor._updateMode();" xbl:inherits="disabled"> - <xul:menupopup> - <xul:menuitem label="&status4evar.option.simple;" /> - <xul:menuitem label="&status4evar.option.advanced;" /> - </xul:menupopup> - </xul:menulist> - </xul:hbox> - </content> - - <implementation> - <constructor><![CDATA[ - [ - "_editorColor", - "_editorImageBrowse", - "_editorImageClear", - "_editorImageRepeatX", - "_editorImageRepeatY", - "_editorImagePositionX", - "_editorImagePositionY", - "_editorImageOffsetX", - "_editorImageOffsetY", - "_editorImageOffsetUnitX", - "_editorImageOffsetUnitY", - "_editorMode" - ].forEach(function(prop) - { - this[prop]._editor = this; - }, this); - - this.setAdvanced(true, false); - ]]></constructor> - - <destructor><![CDATA[ - ]]></destructor> - - <field name="_disableBuildCSS"><![CDATA[ - true - ]]></field> - - <field name="_editorColor" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-color"); - ]]></field> - - <field name="_editorCSS" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-css-text"); - ]]></field> - - <field name="_editorDeck" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-deck"); - ]]></field> - - <field name="_editorImage" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image"); - ]]></field> - - <field name="_editorImageBrowse" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-browse"); - ]]></field> - - <field name="_editorImageClear" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-clear"); - ]]></field> - - <field name="_editorImageRepeatX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-x"); - ]]></field> - - <field name="_editorImageRepeatY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-y"); - ]]></field> - - <field name="_editorImagePositionX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-x"); - ]]></field> - - <field name="_editorImagePositionY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-y"); - ]]></field> - - <field name="_editorImageOffsetX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-x"); - ]]></field> - - <field name="_editorImageOffsetY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-y"); - ]]></field> - - <field name="_editorImageOffsetUnitX" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-x"); - ]]></field> - - <field name="_editorImageOffsetUnitY" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-y"); - ]]></field> - - <field name="_editorMode" readonly="true"><![CDATA[ - document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-mode-menu"); - ]]></field> - - <field name="_initialized"><![CDATA[ - false - ]]></field> - - <field name="_reRGB" readonly="true"><![CDATA[ - /^rgb\((\d+), (\d+), (\d+)\)$/ - ]]></field> - - <field name="_reURL" readonly="true"><![CDATA[ - /^url\(\s*['"]?(.+?)['"]?\s*\)$/ - ]]></field> - - <field name="_reBgPosition" readonly="true"><![CDATA[ - /^(left|center|right)? ?(-?\d+[^\s\d]+)? ?(top|center|bottom)? ?(-?\d+[^\s\d]+)?$/ - ]]></field> - - <field name="_reCSSUnit" readonly="true"><![CDATA[ - /^(-?\d+)([^\s\d]+)$/ - ]]></field> - - <field name="_strings" readonly="true"><![CDATA[ - document.getElementById("bundle_status4evar"); - ]]></field> - - <property name="value"> - <getter><![CDATA[ - return this._editorCSS.value; - ]]></getter> - <setter><![CDATA[ - this._editorCSS.value = val; - - if(!this._initialized) - { - this.setAdvanced(false, false); - this._initialized = true; - } - - return val; - ]]></setter> - </property> - - <property name="disabled"> - <getter><![CDATA[ - return this.getAttribute("disabled") == "true"; - ]]></getter> - <setter><![CDATA[ - if(val) - { - this.setAttribute("disabled", "true"); - } - else - { - this.removeAttribute("disabled"); - } - - this._updateImageControllDisable(); - - return val; - ]]></setter> - </property> - - <method name="setAdvanced"> - <parameter name="aVal"/> - <parameter name="aPrompt"/> - <body><![CDATA[ - if(!aVal) - { - let success = this._parseCSS(); - if(!success) - { - let result = aPrompt && Services.prompt.confirm(window, - this._strings.getString("simpleEditorTitle"), - this._strings.getString("simpleEditorMessage")); - if(result) - { // Continue to simple mode - this._buildCSS(); - } - else - { // Stay on advanced mode - aVal = true; - } - } - } - - this._disableBuildCSS = aVal; - this._editorDeck.selectedIndex = ((aVal) ? 1 : 0); - this._editorMode.selectedIndex = ((aVal) ? 1 : 0); - ]]></body> - </method> - - <method name="_buildCSS"> - <body><![CDATA[ - if(this._disableBuildCSS) - { - return; - } - - let cssVal = this._editorColor.color; - let imgVal = this._editorImage.value; - if(imgVal) - { - cssVal += " url(\"" + imgVal + "\")"; - - // - // Print the background repeat - // - let bgRX = this._editorImageRepeatX.value; - let bgRY = this._editorImageRepeatY.value; - if(bgRX == "repeat" && bgRY == "no-repeat") - { - cssVal += " repeat-x"; - } - else if(bgRX == "no-repeat" && bgRY == "repeat") - { - cssVal += " repeat-y"; - } - else - { - cssVal += " " + bgRX; - if(bgRX != bgRY) - { - cssVal += " " + bgRY; - } - } - - // - // Print the background position - // - let bgPX = this._editorImagePositionX.value; - let bgPOX = this._editorImageOffsetX.value; - if(bgPX != "offset") - { - cssVal += " " + bgPX; - } - else - { - cssVal += " " + bgPOX + this._editorImageOffsetUnitX.value; - } - - let bgPY = this._editorImagePositionY.value; - let bgPOY = this._editorImageOffsetY.value; - if(bgPY != "offset") - { - cssVal += " " + bgPY; - } - else - { - cssVal += " " + bgPOY + this._editorImageOffsetUnitY.value; - } - } - - this._editorCSS.value = cssVal; - - let event = document.createEvent("Event"); - event.initEvent("change", true, true); - this._editorCSS.dispatchEvent(event); - ]]></body> - </method> - - <method name="_parseCSS"> - <body><![CDATA[ - let retVal = true; - - let cssParser = document.createElement("div"); - cssParser.style.background = this._editorCSS.value; - if(!cssParser.style.background) - { - Components.utils.reportError("Error parsing background CSS rule: " + this._editorCSS.value); - cssParser.style.background = "#33FF33"; - retVal = false; - } - - // - // Parse the background color - // - let bgC = cssParser.style.backgroundColor; - if(this._reRGB.test(bgC)) - { - let digits = this._reRGB.exec(bgC); - - let red = parseInt(digits[1]); - let green = parseInt(digits[2]); - let blue = parseInt(digits[3]); - - let rgb = blue | (green << 8) | (red << 16); - bgC = "#" + rgb.toString(16); - } - else - { - Components.utils.reportError("Error parsing background-color value: " + bgC); - bgC = "#33FF33"; - retVal = false; - } - - // - // Parse the background image - // - let bgI = cssParser.style.backgroundImage; - if(bgI != "none" && !this._reURL.test(bgI)) - { - Components.utils.reportError("Error parsing background-image value: " + bgI); - bgI = "none"; - retVal = false; - } - bgI = ((bgI != "none") ? this._reURL.exec(bgI)[1].trim() : ""); - - // - // Parse the background repeat - // - let bgR = cssParser.style.backgroundRepeat.split(" "); - let bgRX = bgR[0]; - if(bgRX == "repeat-x") - { - bgRX = "repeat"; - } - else if(bgRX == "repeat-y") - { - bgRX = "no-repeat"; - } - - let bgRY = bgR[bgR.length - 1]; - if(bgRY == "repeat-x") - { - bgRY = "no-repeat"; - } - else if(bgRY == "repeat-y") - { - bgRY = "repeat"; - } - - // - // Parse the background position - // - let bgP = cssParser.style.backgroundPosition; - let bgPParts = this._reBgPosition.exec(bgP); - let bgPValues = new Array(); - for(let i = 1; i <= 4; i++) - { - if(bgPParts[i]) - { - bgPValues.push({ - "value": bgPParts[i], - "group": i - }); - } - } - - if(bgPValues.length == 1) - { - bgPValues.splice(((bgPValues[0].group == 2) ? 0 : 1), 0, { - "value": "center", - "group": ((bgPValues[0].group == 2) ? 0 : 2) - }); - } - - if(bgPValues.length == 2 && bgPValues[1].group == 2) - { - bgPValues[1].group = 4; - } - - for(let i = 0; i < 4; i++) - { - let group = (i + 1); - if(bgPValues[i] != undefined && bgPValues[i].group == group) - { - continue; - } - - let tmp = "0px"; - switch(i) - { - case 0: - tmp = "offset"; - break; - case 2: - tmp = "offset"; - break; - } - - bgPValues.splice(i, 0, { - "value": tmp, - "group": group - }); - } - - let bgPOXParts = this._reCSSUnit.exec(bgPValues[1].value); - let bgPOYParts = this._reCSSUnit.exec(bgPValues[3].value); - - // - // Parse the background size - // - - // - // Initialize the UI - // - let disableBuildCSS = this._disableBuildCSS; - this._disableBuildCSS = true; - - this._editorColor.color = bgC; - this._editorImage.value = bgI; - this._editorImageOffsetX.value = bgPOXParts[1]; - this._editorImageOffsetY.value = bgPOYParts[1]; - - [ - [this._editorImageRepeatX, bgRX, "repeat", "repeat X"], - [this._editorImageRepeatY, bgRY, "repeat", "repeat Y"], - [this._editorImagePositionX, bgPValues[0].value, "left", "position X"], - [this._editorImagePositionY, bgPValues[2].value, "top", "position Y"], - [this._editorImageOffsetUnitX, bgPOXParts[2], "px", "offset X unit"], - [this._editorImageOffsetUnitY, bgPOYParts[2], "px", "offset Y unit"] - ].forEach(function(info) - { - if(!this._setSelectedItemSafe(info[0], info[1], info[2])) - { - Components.utils.reportError("Error setting " + info[3] + " to " + info[1]); - retVal = false; - } - }, this); - - this._updateImageControllDisable(); - - this._disableBuildCSS = disableBuildCSS; - - return retVal; - ]]></body> - </method> - - <method name="_imageBrowse"> - <body><![CDATA[ - let nsIFilePicker = Components.interfaces.nsIFilePicker; - let filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); - filePicker.init(window, this._strings.getString("imageSelectTitle"), nsIFilePicker.modeOpen); - filePicker.appendFilters(nsIFilePicker.filterImages); - - let res = filePicker.show(); - if(res == nsIFilePicker.returnOK) - { - this._editorImage.value = Services.io.newFileURI(filePicker.file).spec; - this._updateImageControllDisable(); - this._buildCSS(); - } - ]]></body> - </method> - - <method name="_imageClear"> - <body><![CDATA[ - this._editorImage.value = ""; - this._editorImageRepeatX.value = "repeat"; - this._editorImageRepeatY.value = "repeat"; - this._editorImagePositionX.value = "left"; - this._editorImagePositionY.value = "top"; - this._editorImageOffsetX.value = 0; - this._editorImageOffsetY.value = 0; - this._editorImageOffsetUnitX.value = "px"; - this._editorImageOffsetUnitY.value = "px"; - this._updateImageControllDisable(); - this._buildCSS(); - ]]></body> - </method> - - <method name="_processEvent"> - <parameter name="event"/> - <body><![CDATA[ - if(!("css-bg-editor-css-text" == event.originalTarget.getAttribute("anonid") - || "css-bg-editor-css-text" == document.getBindingParent(event.originalTarget).getAttribute("anonid"))) - { - event.stopPropagation(); - } - - //Components.utils.reportError("Editor event " + event.type + " on " + event.originalTarget.tagName + "::" + event.originalTarget.getAttribute("anonid")); - ]]></body> - </method> - - <method name="_setSelectedItemSafe"> - <parameter name="aElement"/> - <parameter name="aValue"/> - <parameter name="aDefault"/> - <body><![CDATA[ - aElement.value = aValue; - if(!aElement.selectedItem || aElement.selectedItem.value != aValue) - { - aElement.value = aDefault; - return false; - } - return true; - ]]></body> - </method> - - <method name="_updateImageControllDisable"> - <body><![CDATA[ - if(this.disabled || !this._editorImage.value) - { - this.setAttribute("no-image", "true"); - this._updatePositionOffsetXDisabled(true); - this._updatePositionOffsetYDisabled(true); - } - else - { - this.removeAttribute("no-image"); - this._updatePositionOffsetXDisabled(false); - this._updatePositionOffsetYDisabled(false); - } - ]]></body> - </method> - - <method name="_updateMode"> - <body><![CDATA[ - if(this._editorMode.selectedIndex == this._editorDeck.selectedIndex) - { - return; - } - - this.setAdvanced(((this._editorMode.selectedIndex == 1) ? true : false), true); - ]]></body> - </method> - - <method name="_updatePositionOffsetXDisabled"> - <parameter name="aVal"/> - <body><![CDATA[ - let bgPX = this._editorImagePositionX.value; - let disableOffsetX = aVal || (bgPX != "offset");// || bgPX == "center"); - this._editorImageOffsetX.disabled = disableOffsetX; - this._editorImageOffsetUnitX.disabled = disableOffsetX; - ]]></body> - </method> - - <method name="_updatePositionOffsetYDisabled"> - <parameter name="aVal"/> - <body><![CDATA[ - let bgPY = this._editorImagePositionY.value; - var disableOffsetY = aVal || (bgPY != "offset");// || bgPY == "center"); - this._editorImageOffsetY.disabled = disableOffsetY; - this._editorImageOffsetUnitY.disabled = disableOffsetY; - ]]></body> - </method> - - <method name="_updatePositionX"> - <body><![CDATA[ - this._updatePositionOffsetXDisabled(false); - this._buildCSS(); - ]]></body> - </method> - - <method name="_updatePositionY"> - <body><![CDATA[ - this._updatePositionOffsetYDisabled(false); - this._buildCSS(); - ]]></body> - </method> - </implementation> - - <handlers> - <handler event="command"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="change"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="input"><![CDATA[ - this._processEvent(event); - ]]></handler> - - <handler event="select"><![CDATA[ - this._processEvent(event); - ]]></handler> - </handlers> - </binding> + </xul:menupopup> + </xul:menulist> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.position;" xbl:inherits="disabled=no-image" /> + <xul:menulist anonid="css-bg-editor-image-position-x" sizetopopup="always" onselect="this._editor._updatePositionX();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.left;" value="left" /> + <xul:menuitem label="&status4evar.option.center;" value="center" /> + <xul:menuitem label="&status4evar.option.right;" value="right" /> + <xul:menuitem label="&status4evar.option.offset;" value="offset" /> + </xul:menupopup> + </xul:menulist> + <xul:separator class="groove" orient="horizontal" /> + <xul:menulist anonid="css-bg-editor-image-position-y" sizetopopup="always" onselect="this._editor._updatePositionY();" xbl:inherits="disabled=no-image"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.top;" value="top" /> + <xul:menuitem label="&status4evar.option.center;" value="center" /> + <xul:menuitem label="&status4evar.option.bottom;" value="bottom" /> + <xul:menuitem label="&status4evar.option.offset;" value="offset" /> + </xul:menupopup> + </xul:menulist> + </xul:groupbox> + + <xul:groupbox> + <xul:caption label="&status4evar.editor.css.image.offset;" xbl:inherits="disabled=no-image" /> + <xul:hbox> + <xul:textbox anonid="css-bg-editor-image-offset-x" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> + <xul:menulist anonid="css-bg-editor-image-offset-unit-x" sizetopopup="always" onselect="this._editor._buildCSS();"> + <xul:menupopup> + <xul:menuitem label="%" value="%" /> + <xul:menuitem label="px" value="px" /> + <xul:menuitem label="em" value="em" /> + <xul:menuitem label="in" value="in" /> + <xul:menuitem label="cm" value="cm" /> + <xul:menuitem label="mm" value="mm" /> + <xul:menuitem label="pt" value="pt" /> + <xul:menuitem label="pc" value="pc" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + <xul:separator class="groove" orient="horizontal" /> + <xul:hbox> + <xul:textbox anonid="css-bg-editor-image-offset-y" type="number" size="4" min="-65535" onchange="this._editor._buildCSS();" /> + <xul:menulist anonid="css-bg-editor-image-offset-unit-y" sizetopopup="always" onselect="this._editor._buildCSS();"> + <xul:menupopup> + <xul:menuitem label="%" value="%" /> + <xul:menuitem label="px" value="px" /> + <xul:menuitem label="em" value="em" /> + <xul:menuitem label="in" value="in" /> + <xul:menuitem label="cm" value="cm" /> + <xul:menuitem label="mm" value="mm" /> + <xul:menuitem label="pt" value="pt" /> + <xul:menuitem label="pc" value="pc" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + </xul:groupbox> + </xul:hbox> + </xul:vbox> + + <xul:textbox anonid="css-bg-editor-css-text" multiline="true" rows="6" xbl:inherits="disabled" /> + </xul:deck> + </xul:vbox> + + <xul:hbox align="center" pack="end"> + <children includes="progressmeter|toolbox" /> + <xul:label xbl:inherits="disabled">&status4evar.editor.label;</xul:label> + <xul:menulist anonid="css-bg-editor-mode-menu" sizetopopup="always" onselect="this._editor._updateMode();" xbl:inherits="disabled"> + <xul:menupopup> + <xul:menuitem label="&status4evar.option.simple;" /> + <xul:menuitem label="&status4evar.option.advanced;" /> + </xul:menupopup> + </xul:menulist> + </xul:hbox> + </content> + + <implementation> + <constructor><![CDATA[ + [ + "_editorColor", + "_editorImageBrowse", + "_editorImageClear", + "_editorImageRepeatX", + "_editorImageRepeatY", + "_editorImagePositionX", + "_editorImagePositionY", + "_editorImageOffsetX", + "_editorImageOffsetY", + "_editorImageOffsetUnitX", + "_editorImageOffsetUnitY", + "_editorMode" + ].forEach(function(prop) + { + this[prop]._editor = this; + }, this); + + this.setAdvanced(true, false); + ]]></constructor> + + <destructor><![CDATA[ + ]]></destructor> + + <field name="_disableBuildCSS"><![CDATA[ + true + ]]></field> + + <field name="_editorColor" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-color"); + ]]></field> + + <field name="_editorCSS" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-css-text"); + ]]></field> + + <field name="_editorDeck" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-deck"); + ]]></field> + + <field name="_editorImage" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image"); + ]]></field> + + <field name="_editorImageBrowse" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-browse"); + ]]></field> + + <field name="_editorImageClear" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-clear"); + ]]></field> + + <field name="_editorImageRepeatX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-x"); + ]]></field> + + <field name="_editorImageRepeatY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-repeat-y"); + ]]></field> + + <field name="_editorImagePositionX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-x"); + ]]></field> + + <field name="_editorImagePositionY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-position-y"); + ]]></field> + + <field name="_editorImageOffsetX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-x"); + ]]></field> + + <field name="_editorImageOffsetY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-y"); + ]]></field> + + <field name="_editorImageOffsetUnitX" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-x"); + ]]></field> + + <field name="_editorImageOffsetUnitY" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-image-offset-unit-y"); + ]]></field> + + <field name="_editorMode" readonly="true"><![CDATA[ + document.getAnonymousElementByAttribute(this, "anonid", "css-bg-editor-mode-menu"); + ]]></field> + + <field name="_initialized"><![CDATA[ + false + ]]></field> + + <field name="_reRGB" readonly="true"><![CDATA[ + /^rgb\((\d+), (\d+), (\d+)\)$/ + ]]></field> + + <field name="_reURL" readonly="true"><![CDATA[ + /^url\(\s*['"]?(.+?)['"]?\s*\)$/ + ]]></field> + + <field name="_reBgPosition" readonly="true"><![CDATA[ + /^(left|center|right)? ?(-?\d+[^\s\d]+)? ?(top|center|bottom)? ?(-?\d+[^\s\d]+)?$/ + ]]></field> + + <field name="_reCSSUnit" readonly="true"><![CDATA[ + /^(-?\d+)([^\s\d]+)$/ + ]]></field> + + <field name="_strings" readonly="true"><![CDATA[ + document.getElementById("bundle_status4evar"); + ]]></field> + + <property name="value"> + <getter><![CDATA[ + return this._editorCSS.value; + ]]></getter> + <setter><![CDATA[ + this._editorCSS.value = val; + + if(!this._initialized) + { + this.setAdvanced(false, false); + this._initialized = true; + } + + return val; + ]]></setter> + </property> + + <property name="disabled"> + <getter><![CDATA[ + return this.getAttribute("disabled") == "true"; + ]]></getter> + <setter><![CDATA[ + if(val) + { + this.setAttribute("disabled", "true"); + } + else + { + this.removeAttribute("disabled"); + } + + this._updateImageControllDisable(); + + return val; + ]]></setter> + </property> + + <method name="setAdvanced"> + <parameter name="aVal"/> + <parameter name="aPrompt"/> + <body><![CDATA[ + if(!aVal) + { + let success = this._parseCSS(); + if(!success) + { + let result = aPrompt && Services.prompt.confirm(window, + this._strings.getString("simpleEditorTitle"), + this._strings.getString("simpleEditorMessage")); + if(result) + { // Continue to simple mode + this._buildCSS(); + } + else + { // Stay on advanced mode + aVal = true; + } + } + } + + this._disableBuildCSS = aVal; + this._editorDeck.selectedIndex = ((aVal) ? 1 : 0); + this._editorMode.selectedIndex = ((aVal) ? 1 : 0); + ]]></body> + </method> + + <method name="_buildCSS"> + <body><![CDATA[ + if(this._disableBuildCSS) + { + return; + } + + let cssVal = this._editorColor.color; + let imgVal = this._editorImage.value; + if(imgVal) + { + cssVal += " url(\"" + imgVal + "\")"; + + // + // Print the background repeat + // + let bgRX = this._editorImageRepeatX.value; + let bgRY = this._editorImageRepeatY.value; + if(bgRX == "repeat" && bgRY == "no-repeat") + { + cssVal += " repeat-x"; + } + else if(bgRX == "no-repeat" && bgRY == "repeat") + { + cssVal += " repeat-y"; + } + else + { + cssVal += " " + bgRX; + if(bgRX != bgRY) + { + cssVal += " " + bgRY; + } + } + + // + // Print the background position + // + let bgPX = this._editorImagePositionX.value; + let bgPOX = this._editorImageOffsetX.value; + if(bgPX != "offset") + { + cssVal += " " + bgPX; + } + else + { + cssVal += " " + bgPOX + this._editorImageOffsetUnitX.value; + } + + let bgPY = this._editorImagePositionY.value; + let bgPOY = this._editorImageOffsetY.value; + if(bgPY != "offset") + { + cssVal += " " + bgPY; + } + else + { + cssVal += " " + bgPOY + this._editorImageOffsetUnitY.value; + } + } + + this._editorCSS.value = cssVal; + + let event = document.createEvent("Event"); + event.initEvent("change", true, true); + this._editorCSS.dispatchEvent(event); + ]]></body> + </method> + + <method name="_parseCSS"> + <body><![CDATA[ + let retVal = true; + + let cssParser = document.createElement("div"); + cssParser.style.background = this._editorCSS.value; + if(!cssParser.style.background) + { + Components.utils.reportError("Error parsing background CSS rule: " + this._editorCSS.value); + cssParser.style.background = "#33FF33"; + retVal = false; + } + + // + // Parse the background color + // + let bgC = cssParser.style.backgroundColor; + if(this._reRGB.test(bgC)) + { + let digits = this._reRGB.exec(bgC); + + let red = parseInt(digits[1]); + let green = parseInt(digits[2]); + let blue = parseInt(digits[3]); + + let rgb = blue | (green << 8) | (red << 16); + bgC = "#" + rgb.toString(16); + } + else + { + Components.utils.reportError("Error parsing background-color value: " + bgC); + bgC = "#33FF33"; + retVal = false; + } + + // + // Parse the background image + // + let bgI = cssParser.style.backgroundImage; + if(bgI != "none" && !this._reURL.test(bgI)) + { + Components.utils.reportError("Error parsing background-image value: " + bgI); + bgI = "none"; + retVal = false; + } + bgI = ((bgI != "none") ? this._reURL.exec(bgI)[1].trim() : ""); + + // + // Parse the background repeat + // + let bgR = cssParser.style.backgroundRepeat.split(" "); + let bgRX = bgR[0]; + if(bgRX == "repeat-x") + { + bgRX = "repeat"; + } + else if(bgRX == "repeat-y") + { + bgRX = "no-repeat"; + } + + let bgRY = bgR[bgR.length - 1]; + if(bgRY == "repeat-x") + { + bgRY = "no-repeat"; + } + else if(bgRY == "repeat-y") + { + bgRY = "repeat"; + } + + // + // Parse the background position + // + let bgP = cssParser.style.backgroundPosition; + let bgPParts = this._reBgPosition.exec(bgP); + let bgPValues = new Array(); + for(let i = 1; i <= 4; i++) + { + if(bgPParts[i]) + { + bgPValues.push({ + "value": bgPParts[i], + "group": i + }); + } + } + + if(bgPValues.length == 1) + { + bgPValues.splice(((bgPValues[0].group == 2) ? 0 : 1), 0, { + "value": "center", + "group": ((bgPValues[0].group == 2) ? 0 : 2) + }); + } + + if(bgPValues.length == 2 && bgPValues[1].group == 2) + { + bgPValues[1].group = 4; + } + + for(let i = 0; i < 4; i++) + { + let group = (i + 1); + if(bgPValues[i] != undefined && bgPValues[i].group == group) + { + continue; + } + + let tmp = "0px"; + switch(i) + { + case 0: + tmp = "offset"; + break; + case 2: + tmp = "offset"; + break; + } + + bgPValues.splice(i, 0, { + "value": tmp, + "group": group + }); + } + + let bgPOXParts = this._reCSSUnit.exec(bgPValues[1].value); + let bgPOYParts = this._reCSSUnit.exec(bgPValues[3].value); + + // + // Parse the background size + // + + // + // Initialize the UI + // + let disableBuildCSS = this._disableBuildCSS; + this._disableBuildCSS = true; + + this._editorColor.color = bgC; + this._editorImage.value = bgI; + this._editorImageOffsetX.value = bgPOXParts[1]; + this._editorImageOffsetY.value = bgPOYParts[1]; + + [ + [this._editorImageRepeatX, bgRX, "repeat", "repeat X"], + [this._editorImageRepeatY, bgRY, "repeat", "repeat Y"], + [this._editorImagePositionX, bgPValues[0].value, "left", "position X"], + [this._editorImagePositionY, bgPValues[2].value, "top", "position Y"], + [this._editorImageOffsetUnitX, bgPOXParts[2], "px", "offset X unit"], + [this._editorImageOffsetUnitY, bgPOYParts[2], "px", "offset Y unit"] + ].forEach(function(info) + { + if(!this._setSelectedItemSafe(info[0], info[1], info[2])) + { + Components.utils.reportError("Error setting " + info[3] + " to " + info[1]); + retVal = false; + } + }, this); + + this._updateImageControllDisable(); + + this._disableBuildCSS = disableBuildCSS; + + return retVal; + ]]></body> + </method> + + <method name="_imageBrowse"> + <body><![CDATA[ + let nsIFilePicker = Components.interfaces.nsIFilePicker; + let filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); + filePicker.init(window, this._strings.getString("imageSelectTitle"), nsIFilePicker.modeOpen); + filePicker.appendFilters(nsIFilePicker.filterImages); + + let res = filePicker.show(); + if(res == nsIFilePicker.returnOK) + { + this._editorImage.value = Services.io.newFileURI(filePicker.file).spec; + this._updateImageControllDisable(); + this._buildCSS(); + } + ]]></body> + </method> + + <method name="_imageClear"> + <body><![CDATA[ + this._editorImage.value = ""; + this._editorImageRepeatX.value = "repeat"; + this._editorImageRepeatY.value = "repeat"; + this._editorImagePositionX.value = "left"; + this._editorImagePositionY.value = "top"; + this._editorImageOffsetX.value = 0; + this._editorImageOffsetY.value = 0; + this._editorImageOffsetUnitX.value = "px"; + this._editorImageOffsetUnitY.value = "px"; + this._updateImageControllDisable(); + this._buildCSS(); + ]]></body> + </method> + + <method name="_processEvent"> + <parameter name="event"/> + <body><![CDATA[ + if(!("css-bg-editor-css-text" == event.originalTarget.getAttribute("anonid") + || "css-bg-editor-css-text" == document.getBindingParent(event.originalTarget).getAttribute("anonid"))) + { + event.stopPropagation(); + } + + //Components.utils.reportError("Editor event " + event.type + " on " + event.originalTarget.tagName + "::" + event.originalTarget.getAttribute("anonid")); + ]]></body> + </method> + + <method name="_setSelectedItemSafe"> + <parameter name="aElement"/> + <parameter name="aValue"/> + <parameter name="aDefault"/> + <body><![CDATA[ + aElement.value = aValue; + if(!aElement.selectedItem || aElement.selectedItem.value != aValue) + { + aElement.value = aDefault; + return false; + } + return true; + ]]></body> + </method> + + <method name="_updateImageControllDisable"> + <body><![CDATA[ + if(this.disabled || !this._editorImage.value) + { + this.setAttribute("no-image", "true"); + this._updatePositionOffsetXDisabled(true); + this._updatePositionOffsetYDisabled(true); + } + else + { + this.removeAttribute("no-image"); + this._updatePositionOffsetXDisabled(false); + this._updatePositionOffsetYDisabled(false); + } + ]]></body> + </method> + + <method name="_updateMode"> + <body><![CDATA[ + if(this._editorMode.selectedIndex == this._editorDeck.selectedIndex) + { + return; + } + + this.setAdvanced(((this._editorMode.selectedIndex == 1) ? true : false), true); + ]]></body> + </method> + + <method name="_updatePositionOffsetXDisabled"> + <parameter name="aVal"/> + <body><![CDATA[ + let bgPX = this._editorImagePositionX.value; + let disableOffsetX = aVal || (bgPX != "offset");// || bgPX == "center"); + this._editorImageOffsetX.disabled = disableOffsetX; + this._editorImageOffsetUnitX.disabled = disableOffsetX; + ]]></body> + </method> + + <method name="_updatePositionOffsetYDisabled"> + <parameter name="aVal"/> + <body><![CDATA[ + let bgPY = this._editorImagePositionY.value; + var disableOffsetY = aVal || (bgPY != "offset");// || bgPY == "center"); + this._editorImageOffsetY.disabled = disableOffsetY; + this._editorImageOffsetUnitY.disabled = disableOffsetY; + ]]></body> + </method> + + <method name="_updatePositionX"> + <body><![CDATA[ + this._updatePositionOffsetXDisabled(false); + this._buildCSS(); + ]]></body> + </method> + + <method name="_updatePositionY"> + <body><![CDATA[ + this._updatePositionOffsetYDisabled(false); + this._buildCSS(); + ]]></body> + </method> + </implementation> + + <handlers> + <handler event="command"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="change"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="input"><![CDATA[ + this._processEvent(event); + ]]></handler> + + <handler event="select"><![CDATA[ + this._processEvent(event); + ]]></handler> + </handlers> + </binding> </bindings> diff --git a/application/palemoon/components/statusbar/content/prefs.xul b/application/palemoon/components/statusbar/content/prefs.xul index d10dc006a..dd4158246 100644 --- a/application/palemoon/components/statusbar/content/prefs.xul +++ b/application/palemoon/components/statusbar/content/prefs.xul @@ -5,8 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <!DOCTYPE prefwindow [ - <!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/statusbar/statusbar-prefs.dtd"> - %prefsDTD; + <!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/statusbar/statusbar-prefs.dtd"> + %prefsDTD; ]> <?xml-stylesheet href="chrome://global/skin/config.css" type="text/css" ?> @@ -23,275 +23,275 @@ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="status4evarPrefs.onPrefWindowLoad();" onunload="status4evarPrefs.onPrefWindowUnLoad();"> - <stringbundleset id="stringbundleset"> - <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/prefs.properties" /> - </stringbundleset> - <script type="application/javascript" src="chrome://browser/content/statusbar/prefs.js" /> + <stringbundleset id="stringbundleset"> + <stringbundle id="bundle_status4evar" src="chrome://browser/locale/statusbar/prefs.properties" /> + </stringbundleset> + <script type="application/javascript" src="chrome://browser/content/statusbar/prefs.js" /> - <prefpane id="status4evar-pane-status" label="&status4evar.pane.status;"> - <preferences> - <preference id="status4evar-pref-status" name="status4evar.status" type="int" /> - <preference id="status4evar-pref-status-default" name="status4evar.status.default" type="bool" /> - <preference id="status4evar-pref-status-network" name="status4evar.status.network" type="bool" - onchange="status4evarPrefs.statusNetworkChanged();" /> - <preference id="status4evar-pref-status-network-xhr" name="status4evar.status.network.xhr" type="bool" /> - <preference id="status4evar-pref-status-timeout" name="status4evar.status.timeout" type="int" - onchange="status4evarPrefs.statusTimeoutChanged();" /> - <preference id="status4evar-pref-status-linkOver" name="status4evar.status.linkOver" type="int" /> - <preference id="status4evar-pref-status-linkOver-delay-show" name="status4evar.status.linkOver.delay.show" type="int" /> - <preference id="status4evar-pref-status-linkOver-delay-hide" name="status4evar.status.linkOver.delay.hide" type="int" /> - <preference id="status4evar-pref-status-toolbar-maxLength" name="status4evar.status.toolbar.maxLength" type="int" - onchange="status4evarPrefs.textLengthChanged();" /> - <preference id="status4evar-pref-status-popup-invertMirror" name="status4evar.status.popup.invertMirror" type="bool" /> - <preference id="status4evar-pref-status-popup-mouseMirror" name="status4evar.status.popup.mouseMirror" type="bool" /> - <preference id="toolkit-pref-dom-status-change" name="dom.disable_window_status_change" type="bool" inverted="true" /> - </preferences> - - <commandset id="status4evar-commandset-status"> - <command id="status4evar-command-status-timeout" oncommand="status4evarPrefs.statusTimeoutToggle();" /> - <command id="status4evar-command-status-toolbar-maxLength" oncommand="status4evarPrefs.textLengthToggle();" /> - </commandset> - - <tabbox id="status4evar-tabbox-status" flex="1"> - <tabs id="status4evar-tabs-status"> - <tab id="status4evar-tab-status-general" label="&status4evar.tab.general;" /> - <tab id="status4evar-tab-status-toolbar" label="&status4evar.tab.toolbar;" /> - <tab id="status4evar-tab-status-popup" label="&status4evar.tab.popup;" /> - </tabs> - - <tabpanels id="status4evar-tabpanels-status" flex="1"> - <tabpanel id="status4evar-tabpanel-status-general" orient="vertical"> - <groupbox id="status4evar-status-general-status"> - <caption label="&status4evar.status.general.status.caption;" /> - - <hbox align="center"> - <label id="status4evar-status-label" control="status4evar-status-menu">&status4evar.status.label;</label> - <menulist id="status4evar-status-menu" preference="status4evar-pref-status" sizetopopup="always"> - <menupopup> - <menuitem label="&status4evar.option.none;" value="0" /> - <menuitem label="&status4evar.option.toolbar;" value="1" /> - <menuitem label="&status4evar.option.popup;" value="3" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <checkbox id="status4evar-status-timeout-check" label="&status4evar.status.timeout.label;" - command="status4evar-command-status-timeout" /> - <textbox id="status4evar-status-timeout-value" preference="status4evar-pref-status-timeout" type="number" size="4" - onsyncfrompreference="return status4evarPrefs.statusTimeoutSync();" /> - <label id="status4evar-status-timeout-unit">&status4evar.unit.seconds;</label> - </hbox> - - <checkbox id="status4evar-status-default-check" preference="status4evar-pref-status-default" label="&status4evar.status.default.label;" /> - - <checkbox id="status4evar-status-network-check" preference="status4evar-pref-status-network" label="&status4evar.status.network.label;" - onsyncfrompreference="return status4evarPrefs.statusNetworkSync();" /> - - <hbox align="center" class="indent"> - <checkbox id="status4evar-status-network-xhr-check" preference="status4evar-pref-status-network-xhr" label="&status4evar.status.network.xhr.label;" /> - </hbox> - - <checkbox id="toolkit-dom-status-change-check" preference="toolkit-pref-dom-status-change" label="&toolkit.dom.status.change.label;" /> - </groupbox> - - <groupbox id="status4evar-status-general-linkOver"> - <caption label="&status4evar.status.general.linkOver.caption;" /> - - <hbox align="center"> - <label id="status4evar-status-linkOver-label" control="status4evar-status-linkOver-menu">&status4evar.status.linkOver.label;</label> - <menulist id="status4evar-status-linkOver-menu" preference="status4evar-pref-status-linkOver" sizetopopup="always"> - <menupopup> - <menuitem label="&status4evar.option.none;" value="0" /> - <menuitem label="&status4evar.option.toolbar;" value="1" /> - <menuitem label="&status4evar.option.popup;" value="3" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-status-linkOver-delay-show-label" control="status4evar-status-linkOver-delay-show-value">&status4evar.status.linkOver.delay.show.label;</label> - <textbox id="status4evar-status-linkOver-delay-show-value" preference="status4evar-pref-status-linkOver-delay-show" type="number" size="5" /> - <label id="status4evar-status-linkOver-delay-show-unit">&status4evar.unit.milliseconds;</label> - </hbox> - - <hbox align="center"> - <label id="status4evar-status-linkOver-delay-hide-label" control="status4evar-status-linkOver-delay-hide-value">&status4evar.status.linkOver.delay.hide.label;</label> - <textbox id="status4evar-status-linkOver-delay-hide-value" preference="status4evar-pref-status-linkOver-delay-hide" type="number" size="5" /> - <label id="status4evar-status-linkOver-delay-hide-unit">&status4evar.unit.milliseconds;</label> - </hbox> - </groupbox> - - </tabpanel> - - <tabpanel id="status4evar-tabpanel-status-toolbar" orient="vertical"> - <hbox align="center"> - <checkbox id="status4evar-status-toolbar-maxLength-check" label="&status4evar.status.toolbar.maxLength.label;" - command="status4evar-command-status-toolbar-maxLength" /> - <textbox id="status4evar-status-toolbar-maxLength-value" preference="status4evar-pref-status-toolbar-maxLength" type="number" size="4" - onsyncfrompreference="return status4evarPrefs.textLengthSync();" /> - <label id="status4evar-status-toolbar-maxLength-unit">&status4evar.unit.px;</label> - </hbox> - </tabpanel> - - <tabpanel id="status4evar-tabpanel-status-popup" orient="vertical"> - <checkbox id="status4evar-status-popup-invertMirror-check" preference="status4evar-pref-status-popup-invertMirror" label="&status4evar.status.popup.invertMirror.label;" /> - - <checkbox id="status4evar-status-popup-mouseMirror-check" preference="status4evar-pref-status-popup-mouseMirror" label="&status4evar.status.popup.mouseMirror.label;" /> - </tabpanel> - - </tabpanels> - </tabbox> - </prefpane> - - <prefpane id="status4evar-pane-progress" label="&status4evar.pane.progress;"> - <preferences> - <preference id="status4evar-pref-progress-toolbar-force" name="status4evar.progress.toolbar.force" type="bool" /> - <preference id="status4evar-pref-progress-toolbar-style" name="status4evar.progress.toolbar.style" type="bool" - onchange="status4evarPrefs.progressToolbarStyleChanged();" /> - <preference id="status4evar-pref-progress-toolbar-css" name="status4evar.progress.toolbar.css" type="string" - onchange="status4evarPrefs.progressToolbarCSSChanged();" /> - </preferences> - - <commandset id="status4evar-commandset-status"> - </commandset> - - <checkbox id="status4evar-progress-toolbar-force-check" preference="status4evar-pref-progress-toolbar-force" label="&status4evar.progress.toolbar.force.label;" /> - - <checkbox id="status4evar-progress-toolbar-style-check" preference="status4evar-pref-progress-toolbar-style" label="&status4evar.progress.style.label;" - onsyncfrompreference="return status4evarPrefs.progressToolbarStyleSync();" /> - - <vbox class="css-bg-editor" preference="status4evar-pref-progress-toolbar-css" preference-editable="true" flex="1"> - <progressmeter id="status4evar-progress-bar" value="75" flex="1" /> - </vbox> - </prefpane> - - <prefpane id="status4evar-pane-download" label="&status4evar.pane.download;"> - <preferences> - <preference id="status4evar-pref-download-button-action" name="status4evar.download.button.action" type="int" /> - <preference id="status4evar-pref-download-color-active" name="status4evar.download.color.active" type="string" /> - <preference id="status4evar-pref-download-color-paused" name="status4evar.download.color.paused" type="string" /> - <preference id="status4evar-pref-download-force" name="status4evar.download.force" type="bool" /> - <preference id="status4evar-pref-download-label" name="status4evar.download.label" type="int" /> - <preference id="status4evar-pref-download-label-force" name="status4evar.download.label.force" type="bool" /> - <preference id="status4evar-pref-download-notify-animate" name="status4evar.download.notify.animate" type="bool" /> - <preference id="status4evar-pref-download-notify-timeout" name="status4evar.download.notify.timeout" type="int" /> - <preference id="status4evar-pref-download-progress" name="status4evar.download.progress" type="int" /> - <preference id="status4evar-pref-download-tooltip" name="status4evar.download.tooltip" type="int" /> - - <preference id="status4evar-pref-download-button-action-command" name="status4evar.download.button.action.command" type="string"/> - </preferences> - - <commandset id="status4evar-commandset-download"> - <command id="status4evar-command-download-progress" oncommand="status4evarPrefs.downloadProgressToggle();" /> - </commandset> - - <checkbox id="status4evar-download-force-check" preference="status4evar-pref-download-force" label="&status4evar.download.force.label;" /> - - <checkbox id="status4evar-download-label-force-check" preference="status4evar-pref-download-label-force" label="&status4evar.download.label.force.label;" /> - - <hbox align="center"> - <label id="status4evar-download-label-label" control="status4evar-download-label-menu">&status4evar.download.label.label;</label> - <menulist id="status4evar-download-label-menu" preference="status4evar-pref-download-label" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.dlcount;" /> - <menuitem value="1" label="&status4evar.option.dltime;" /> - <menuitem value="2" label="&status4evar.option.both;" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-tooltip-label" control="status4evar-download-tooltip-menu">&status4evar.download.tooltip.label;</label> - <menulist id="status4evar-download-tooltip-menu" preference="status4evar-pref-download-tooltip" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.dlcount;" /> - <menuitem value="1" label="&status4evar.option.dltime;" /> - <menuitem value="2" label="&status4evar.option.both;" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-button-action-label" control="status4evar-download-button-action-menu">&status4evar.download.button.action.label;</label> - <menulist id="status4evar-download-button-action-menu" preference="status4evar-pref-download-button-action" sizetopopup="always"> - <menupopup> - <menuitem value="0" label="&status4evar.option.nothing;" /> - <menuitem value="1" label="&status4evar.option.firefoxdefault;" /> - <menuitem value="2" label="&status4evar.option.download.library;" /> - <menuitem value="3" label="&status4evar.option.download.tab;" /> - <menuitem value="4" label="&status4evar.option.download.thirdparty;" id="status4evar-download-button-action-menu-thirdparty" /> - </menupopup> - </menulist> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-notify-timeout-label" control="status4evar-download-notify-timeout-value">&status4evar.download.notify.timeout.label;</label> - <textbox id="status4evar-download-notify-timeout-value" preference="status4evar-pref-download-notify-timeout" type="number" size="3" /> - <label id="status4evar-download-notify-timeout-unit">&status4evar.unit.seconds;</label> - </hbox> - - <checkbox id="status4evar-download-notify-animate-check" preference="status4evar-pref-download-notify-animate" label="&status4evar.download.notify.animate.label;" /> - - <checkbox id="status4evar-download-progress-check" command="status4evar-command-download-progress" label="&status4evar.download.progress.label;" /> - - <vbox class="indent"> - <hbox align="center"> - <radiogroup id="status4evar-download-progress-radiogroup" preference="status4evar-pref-download-progress" - onsyncfrompreference="return status4evarPrefs.downloadProgressSync();"> - <radio value="1" label="&status4evar.download.progress.average.label;" /> - <radio value="2" label="&status4evar.download.progress.max.label;" /> - <radio value="3" label="&status4evar.download.progress.min.label;" /> - </radiogroup> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-color-active-label" control="status4evar-download-color-active-picker">&status4evar.download.color.active.label;</label> - <colorpicker id="status4evar-download-color-active-picker" preference="status4evar-pref-download-color-active" type="button" /> - </hbox> - - <hbox align="center"> - <label id="status4evar-download-color-paused-label" control="status4evar-download-color-paused-picker">&status4evar.download.color.paused.label;</label> - <colorpicker id="status4evar-download-color-paused-picker" preference="status4evar-pref-download-color-paused" type="button" /> - </hbox> - </vbox> - </prefpane> - - <prefpane id="status4evar-pane-addonbar" label="&status4evar.pane.statusbar;"> - <preferences> - <preference id="status4evar-pref-addonbar-borderStyle" name="status4evar.addonbar.borderStyle" type="bool" /> - <preference id="status4evar-pref-addonbar-closeButton" name="status4evar.addonbar.closeButton" type="bool" /> - <preference id="status4evar-pref-addonbar-windowGripper" name="status4evar.addonbar.windowGripper" type="bool" /> - </preferences> - - <checkbox id="status4evar-addonbar-borderStyle-check" preference="status4evar-pref-addonbar-borderStyle" label="&status4evar.addonbar.borderStyle;" /> - - <checkbox id="status4evar-addonbar-closeButton-check" preference="status4evar-pref-addonbar-closeButton" label="&status4evar.addonbar.closeButton;" /> - - <checkbox id="status4evar-addonbar-windowGripper-check" preference="status4evar-pref-addonbar-windowGripper" label="&status4evar.addonbar.windowGripper;" /> - </prefpane> - - <prefpane id="status4evar-pane-advanced" label="&status4evar.pane.advanced;"> - <preferences> - <preference id="status4evar-pref-advanced-status-detectFullScreen" name="status4evar.advanced.status.detectFullScreen" type="bool" /> - <preference id="status4evar-pref-advanced-status-detectVideo" name="status4evar.advanced.status.detectVideo" type="bool" /> - <preference id="browser-pref-urlbar-trimming-enabled" name="browser.urlbar.trimURLs" type="bool" /> - </preferences> - - <vbox flex="1"> - <groupbox id="status4evar-status-urlbar-builtin"> - <caption label="&status4evar.status.urlbar.firefox.builtin.caption;" /> - - <checkbox id="browser-urlbar-trimming-enabled-ckeck" preference="browser-pref-urlbar-trimming-enabled" label="&browser.urlbar.trimming.enabled.label;" /> - </groupbox> - - <groupbox id="status4evar-advanced-status"> - <caption label="&status4evar.pane.status;" /> - - <checkbox id="status4evar-advanced-status-detectFullScreen-check" preference="status4evar-pref-advanced-status-detectFullScreen" label="&status4evar.advanced.status.detectFullScreen;" /> - <checkbox id="status4evar-advanced-status-detectVideo-check" preference="status4evar-pref-advanced-status-detectVideo" label="&status4evar.advanced.status.detectVideo;" /> - </groupbox> - </vbox> - </prefpane> + <prefpane id="status4evar-pane-status" label="&status4evar.pane.status;"> + <preferences> + <preference id="status4evar-pref-status" name="status4evar.status" type="int" /> + <preference id="status4evar-pref-status-default" name="status4evar.status.default" type="bool" /> + <preference id="status4evar-pref-status-network" name="status4evar.status.network" type="bool" + onchange="status4evarPrefs.statusNetworkChanged();" /> + <preference id="status4evar-pref-status-network-xhr" name="status4evar.status.network.xhr" type="bool" /> + <preference id="status4evar-pref-status-timeout" name="status4evar.status.timeout" type="int" + onchange="status4evarPrefs.statusTimeoutChanged();" /> + <preference id="status4evar-pref-status-linkOver" name="status4evar.status.linkOver" type="int" /> + <preference id="status4evar-pref-status-linkOver-delay-show" name="status4evar.status.linkOver.delay.show" type="int" /> + <preference id="status4evar-pref-status-linkOver-delay-hide" name="status4evar.status.linkOver.delay.hide" type="int" /> + <preference id="status4evar-pref-status-toolbar-maxLength" name="status4evar.status.toolbar.maxLength" type="int" + onchange="status4evarPrefs.textLengthChanged();" /> + <preference id="status4evar-pref-status-popup-invertMirror" name="status4evar.status.popup.invertMirror" type="bool" /> + <preference id="status4evar-pref-status-popup-mouseMirror" name="status4evar.status.popup.mouseMirror" type="bool" /> + <preference id="toolkit-pref-dom-status-change" name="dom.disable_window_status_change" type="bool" inverted="true" /> + </preferences> + + <commandset id="status4evar-commandset-status"> + <command id="status4evar-command-status-timeout" oncommand="status4evarPrefs.statusTimeoutToggle();" /> + <command id="status4evar-command-status-toolbar-maxLength" oncommand="status4evarPrefs.textLengthToggle();" /> + </commandset> + + <tabbox id="status4evar-tabbox-status" flex="1"> + <tabs id="status4evar-tabs-status"> + <tab id="status4evar-tab-status-general" label="&status4evar.tab.general;" /> + <tab id="status4evar-tab-status-toolbar" label="&status4evar.tab.toolbar;" /> + <tab id="status4evar-tab-status-popup" label="&status4evar.tab.popup;" /> + </tabs> + + <tabpanels id="status4evar-tabpanels-status" flex="1"> + <tabpanel id="status4evar-tabpanel-status-general" orient="vertical"> + <groupbox id="status4evar-status-general-status"> + <caption label="&status4evar.status.general.status.caption;" /> + + <hbox align="center"> + <label id="status4evar-status-label" control="status4evar-status-menu">&status4evar.status.label;</label> + <menulist id="status4evar-status-menu" preference="status4evar-pref-status" sizetopopup="always"> + <menupopup> + <menuitem label="&status4evar.option.none;" value="0" /> + <menuitem label="&status4evar.option.toolbar;" value="1" /> + <menuitem label="&status4evar.option.popup;" value="3" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <checkbox id="status4evar-status-timeout-check" label="&status4evar.status.timeout.label;" + command="status4evar-command-status-timeout" /> + <textbox id="status4evar-status-timeout-value" preference="status4evar-pref-status-timeout" type="number" size="4" + onsyncfrompreference="return status4evarPrefs.statusTimeoutSync();" /> + <label id="status4evar-status-timeout-unit">&status4evar.unit.seconds;</label> + </hbox> + + <checkbox id="status4evar-status-default-check" preference="status4evar-pref-status-default" label="&status4evar.status.default.label;" /> + + <checkbox id="status4evar-status-network-check" preference="status4evar-pref-status-network" label="&status4evar.status.network.label;" + onsyncfrompreference="return status4evarPrefs.statusNetworkSync();" /> + + <hbox align="center" class="indent"> + <checkbox id="status4evar-status-network-xhr-check" preference="status4evar-pref-status-network-xhr" label="&status4evar.status.network.xhr.label;" /> + </hbox> + + <checkbox id="toolkit-dom-status-change-check" preference="toolkit-pref-dom-status-change" label="&toolkit.dom.status.change.label;" /> + </groupbox> + + <groupbox id="status4evar-status-general-linkOver"> + <caption label="&status4evar.status.general.linkOver.caption;" /> + + <hbox align="center"> + <label id="status4evar-status-linkOver-label" control="status4evar-status-linkOver-menu">&status4evar.status.linkOver.label;</label> + <menulist id="status4evar-status-linkOver-menu" preference="status4evar-pref-status-linkOver" sizetopopup="always"> + <menupopup> + <menuitem label="&status4evar.option.none;" value="0" /> + <menuitem label="&status4evar.option.toolbar;" value="1" /> + <menuitem label="&status4evar.option.popup;" value="3" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-status-linkOver-delay-show-label" control="status4evar-status-linkOver-delay-show-value">&status4evar.status.linkOver.delay.show.label;</label> + <textbox id="status4evar-status-linkOver-delay-show-value" preference="status4evar-pref-status-linkOver-delay-show" type="number" size="5" /> + <label id="status4evar-status-linkOver-delay-show-unit">&status4evar.unit.milliseconds;</label> + </hbox> + + <hbox align="center"> + <label id="status4evar-status-linkOver-delay-hide-label" control="status4evar-status-linkOver-delay-hide-value">&status4evar.status.linkOver.delay.hide.label;</label> + <textbox id="status4evar-status-linkOver-delay-hide-value" preference="status4evar-pref-status-linkOver-delay-hide" type="number" size="5" /> + <label id="status4evar-status-linkOver-delay-hide-unit">&status4evar.unit.milliseconds;</label> + </hbox> + </groupbox> + + </tabpanel> + + <tabpanel id="status4evar-tabpanel-status-toolbar" orient="vertical"> + <hbox align="center"> + <checkbox id="status4evar-status-toolbar-maxLength-check" label="&status4evar.status.toolbar.maxLength.label;" + command="status4evar-command-status-toolbar-maxLength" /> + <textbox id="status4evar-status-toolbar-maxLength-value" preference="status4evar-pref-status-toolbar-maxLength" type="number" size="4" + onsyncfrompreference="return status4evarPrefs.textLengthSync();" /> + <label id="status4evar-status-toolbar-maxLength-unit">&status4evar.unit.px;</label> + </hbox> + </tabpanel> + + <tabpanel id="status4evar-tabpanel-status-popup" orient="vertical"> + <checkbox id="status4evar-status-popup-invertMirror-check" preference="status4evar-pref-status-popup-invertMirror" label="&status4evar.status.popup.invertMirror.label;" /> + + <checkbox id="status4evar-status-popup-mouseMirror-check" preference="status4evar-pref-status-popup-mouseMirror" label="&status4evar.status.popup.mouseMirror.label;" /> + </tabpanel> + + </tabpanels> + </tabbox> + </prefpane> + + <prefpane id="status4evar-pane-progress" label="&status4evar.pane.progress;"> + <preferences> + <preference id="status4evar-pref-progress-toolbar-force" name="status4evar.progress.toolbar.force" type="bool" /> + <preference id="status4evar-pref-progress-toolbar-style" name="status4evar.progress.toolbar.style" type="bool" + onchange="status4evarPrefs.progressToolbarStyleChanged();" /> + <preference id="status4evar-pref-progress-toolbar-css" name="status4evar.progress.toolbar.css" type="string" + onchange="status4evarPrefs.progressToolbarCSSChanged();" /> + </preferences> + + <commandset id="status4evar-commandset-status"> + </commandset> + + <checkbox id="status4evar-progress-toolbar-force-check" preference="status4evar-pref-progress-toolbar-force" label="&status4evar.progress.toolbar.force.label;" /> + + <checkbox id="status4evar-progress-toolbar-style-check" preference="status4evar-pref-progress-toolbar-style" label="&status4evar.progress.style.label;" + onsyncfrompreference="return status4evarPrefs.progressToolbarStyleSync();" /> + + <vbox class="css-bg-editor" preference="status4evar-pref-progress-toolbar-css" preference-editable="true" flex="1"> + <progressmeter id="status4evar-progress-bar" value="75" flex="1" /> + </vbox> + </prefpane> + + <prefpane id="status4evar-pane-download" label="&status4evar.pane.download;"> + <preferences> + <preference id="status4evar-pref-download-button-action" name="status4evar.download.button.action" type="int" /> + <preference id="status4evar-pref-download-color-active" name="status4evar.download.color.active" type="string" /> + <preference id="status4evar-pref-download-color-paused" name="status4evar.download.color.paused" type="string" /> + <preference id="status4evar-pref-download-force" name="status4evar.download.force" type="bool" /> + <preference id="status4evar-pref-download-label" name="status4evar.download.label" type="int" /> + <preference id="status4evar-pref-download-label-force" name="status4evar.download.label.force" type="bool" /> + <preference id="status4evar-pref-download-notify-animate" name="status4evar.download.notify.animate" type="bool" /> + <preference id="status4evar-pref-download-notify-timeout" name="status4evar.download.notify.timeout" type="int" /> + <preference id="status4evar-pref-download-progress" name="status4evar.download.progress" type="int" /> + <preference id="status4evar-pref-download-tooltip" name="status4evar.download.tooltip" type="int" /> + + <preference id="status4evar-pref-download-button-action-command" name="status4evar.download.button.action.command" type="string"/> + </preferences> + + <commandset id="status4evar-commandset-download"> + <command id="status4evar-command-download-progress" oncommand="status4evarPrefs.downloadProgressToggle();" /> + </commandset> + + <checkbox id="status4evar-download-force-check" preference="status4evar-pref-download-force" label="&status4evar.download.force.label;" /> + + <checkbox id="status4evar-download-label-force-check" preference="status4evar-pref-download-label-force" label="&status4evar.download.label.force.label;" /> + + <hbox align="center"> + <label id="status4evar-download-label-label" control="status4evar-download-label-menu">&status4evar.download.label.label;</label> + <menulist id="status4evar-download-label-menu" preference="status4evar-pref-download-label" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.dlcount;" /> + <menuitem value="1" label="&status4evar.option.dltime;" /> + <menuitem value="2" label="&status4evar.option.both;" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-tooltip-label" control="status4evar-download-tooltip-menu">&status4evar.download.tooltip.label;</label> + <menulist id="status4evar-download-tooltip-menu" preference="status4evar-pref-download-tooltip" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.dlcount;" /> + <menuitem value="1" label="&status4evar.option.dltime;" /> + <menuitem value="2" label="&status4evar.option.both;" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-button-action-label" control="status4evar-download-button-action-menu">&status4evar.download.button.action.label;</label> + <menulist id="status4evar-download-button-action-menu" preference="status4evar-pref-download-button-action" sizetopopup="always"> + <menupopup> + <menuitem value="0" label="&status4evar.option.nothing;" /> + <menuitem value="1" label="&status4evar.option.firefoxdefault;" /> + <menuitem value="2" label="&status4evar.option.download.library;" /> + <menuitem value="3" label="&status4evar.option.download.tab;" /> + <menuitem value="4" label="&status4evar.option.download.thirdparty;" id="status4evar-download-button-action-menu-thirdparty" /> + </menupopup> + </menulist> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-notify-timeout-label" control="status4evar-download-notify-timeout-value">&status4evar.download.notify.timeout.label;</label> + <textbox id="status4evar-download-notify-timeout-value" preference="status4evar-pref-download-notify-timeout" type="number" size="3" /> + <label id="status4evar-download-notify-timeout-unit">&status4evar.unit.seconds;</label> + </hbox> + + <checkbox id="status4evar-download-notify-animate-check" preference="status4evar-pref-download-notify-animate" label="&status4evar.download.notify.animate.label;" /> + + <checkbox id="status4evar-download-progress-check" command="status4evar-command-download-progress" label="&status4evar.download.progress.label;" /> + + <vbox class="indent"> + <hbox align="center"> + <radiogroup id="status4evar-download-progress-radiogroup" preference="status4evar-pref-download-progress" + onsyncfrompreference="return status4evarPrefs.downloadProgressSync();"> + <radio value="1" label="&status4evar.download.progress.average.label;" /> + <radio value="2" label="&status4evar.download.progress.max.label;" /> + <radio value="3" label="&status4evar.download.progress.min.label;" /> + </radiogroup> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-color-active-label" control="status4evar-download-color-active-picker">&status4evar.download.color.active.label;</label> + <colorpicker id="status4evar-download-color-active-picker" preference="status4evar-pref-download-color-active" type="button" /> + </hbox> + + <hbox align="center"> + <label id="status4evar-download-color-paused-label" control="status4evar-download-color-paused-picker">&status4evar.download.color.paused.label;</label> + <colorpicker id="status4evar-download-color-paused-picker" preference="status4evar-pref-download-color-paused" type="button" /> + </hbox> + </vbox> + </prefpane> + + <prefpane id="status4evar-pane-addonbar" label="&status4evar.pane.statusbar;"> + <preferences> + <preference id="status4evar-pref-addonbar-borderStyle" name="status4evar.addonbar.borderStyle" type="bool" /> + <preference id="status4evar-pref-addonbar-closeButton" name="status4evar.addonbar.closeButton" type="bool" /> + <preference id="status4evar-pref-addonbar-windowGripper" name="status4evar.addonbar.windowGripper" type="bool" /> + </preferences> + + <checkbox id="status4evar-addonbar-borderStyle-check" preference="status4evar-pref-addonbar-borderStyle" label="&status4evar.addonbar.borderStyle;" /> + + <checkbox id="status4evar-addonbar-closeButton-check" preference="status4evar-pref-addonbar-closeButton" label="&status4evar.addonbar.closeButton;" /> + + <checkbox id="status4evar-addonbar-windowGripper-check" preference="status4evar-pref-addonbar-windowGripper" label="&status4evar.addonbar.windowGripper;" /> + </prefpane> + + <prefpane id="status4evar-pane-advanced" label="&status4evar.pane.advanced;"> + <preferences> + <preference id="status4evar-pref-advanced-status-detectFullScreen" name="status4evar.advanced.status.detectFullScreen" type="bool" /> + <preference id="status4evar-pref-advanced-status-detectVideo" name="status4evar.advanced.status.detectVideo" type="bool" /> + <preference id="browser-pref-urlbar-trimming-enabled" name="browser.urlbar.trimURLs" type="bool" /> + </preferences> + + <vbox flex="1"> + <groupbox id="status4evar-status-urlbar-builtin"> + <caption label="&status4evar.status.urlbar.firefox.builtin.caption;" /> + + <checkbox id="browser-urlbar-trimming-enabled-ckeck" preference="browser-pref-urlbar-trimming-enabled" label="&browser.urlbar.trimming.enabled.label;" /> + </groupbox> + + <groupbox id="status4evar-advanced-status"> + <caption label="&status4evar.pane.status;" /> + + <checkbox id="status4evar-advanced-status-detectFullScreen-check" preference="status4evar-pref-advanced-status-detectFullScreen" label="&status4evar.advanced.status.detectFullScreen;" /> + <checkbox id="status4evar-advanced-status-detectVideo-check" preference="status4evar-pref-advanced-status-detectVideo" label="&status4evar.advanced.status.detectVideo;" /> + </groupbox> + </vbox> + </prefpane> </prefwindow> diff --git a/application/palemoon/components/statusbar/content/tabbrowser.xml b/application/palemoon/components/statusbar/content/tabbrowser.xml index 5119fa58a..2f475771d 100644 --- a/application/palemoon/components/statusbar/content/tabbrowser.xml +++ b/application/palemoon/components/statusbar/content/tabbrowser.xml @@ -9,210 +9,210 @@ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> - <binding id="statuspanel" display="xul:hbox" extends="chrome://browser/content/tabbrowser.xml#statuspanel"> - <implementation> - <!-- --> - <!-- Inverted mirror handling --> - <!-- --> - - <field name="_invertMirror"><![CDATA[ - false - ]]></field> - - <property name="invertMirror"> - <setter><![CDATA[ - this._invertMirror = val; - this.mirror = this._isMirrored; - return val; - ]]></setter> - <getter><![CDATA[ - return this._invertMirror; - ]]></getter> - </property> - - <!-- --> - <!-- Mouse mirror handling --> - <!-- --> - - <field name="_mouseMirror"><![CDATA[ - true - ]]></field> - - <field name="_mouseMirrorListen"><![CDATA[ - false - ]]></field> - - <property name="mouseMirror"> - <setter><![CDATA[ - this._mouseMirror = val; - this.setupMouseMirror(this.value); - return val; - ]]></setter> - <getter><![CDATA[ - return this._mouseMirror; - ]]></getter> - </property> - - <method name="setupMouseMirror"> - <parameter name="val"/> - <body><![CDATA[ - if(val && this._mouseMirror) - { - this._calcMouseTargetRect(); - if(!this._mouseMirrorListen) - { - MousePosTracker.addListener(this); - this._mouseMirrorListen = true; - } - } - else - { - this.mirror = false; - if(this._mouseMirrorListen) - { - MousePosTracker.removeListener(this); - this._mouseMirrorListen = false; - } - } - ]]></body> - </method> - - <method name="_calcMouseTargetRect"> - <body><![CDATA[ - let alignRight = false; - let isRTL = (getComputedStyle(document.documentElement).direction == "rtl"); - if((this._invertMirror && !isRTL) || (!this._invertMirror && isRTL)) - { - alignRight = true; - } - - let rect = this.getBoundingClientRect(); - this._mouseTargetRect = - { - top: rect.top, - bottom: rect.bottom, - left: ((alignRight) ? window.innerWidth - rect.width : 0), - right: ((alignRight) ? window.innerWidth : rect.width) - }; - ]]></body> - </method> - - <method name="onMouseEnter"> - <body><![CDATA[ - this.mirror = true; - ]]></body> - </method> - - <method name="onMouseLeave"> - <body><![CDATA[ - this.mirror = false; - ]]></body> - </method> - - <!-- --> - <!-- Mirror handling --> - <!-- --> - - <field name="_isMirrored"><![CDATA[ - false - ]]></field> - - <property name="mirror"> - <setter><![CDATA[ - this._isMirrored = val; - if(this._invertMirror) - { - val = !val; - } - - this.setBooleanAttr("mirror", val); - ]]></setter> - <getter><![CDATA[ - return this._isMirrored; - ]]></getter> - </property> - - <method name="_mirror"> - <body><![CDATA[ - this.mirror = !this._isMirrored; - ]]></body> - </method> - - <!-- --> - <!-- Value handling --> - <!-- --> - - <property name="label"> - <setter><![CDATA[ - if(window.caligon && window.caligon.status4evar) - { - window.caligon.status4evar.statusService.setStatusText(val); - } - return undefined; - ]]></setter> - <getter><![CDATA[ - if(window.caligon && window.caligon.status4evar) - { - return window.caligon.status4evar.statusService.getStatusText(); - } - return ""; - ]]></getter> - </property> - - <property name="value"> - <setter><![CDATA[ - this.setValue(val); - this.setupMouseMirror(val); - return val; - ]]></setter> - <getter><![CDATA[ - return ((this.hasAttribute("inactive")) ? "" : this.getAttribute("label")); - ]]></getter> - </property> - - <method name="setValue"> - <parameter name="val"/> - <body><![CDATA[ - if((this.getAttribute("type") || "").indexOf("network") > -1 && (this.getAttribute("previoustype") || "").indexOf("network") > -1) - { - this.style.minWidth = getComputedStyle(this).width; - } - else - { - this.style.minWidth = ""; - } - - if(val) - { - this.setAttribute("label", val); - this.setBooleanAttr("inactive", false); - } - else - { - this.setBooleanAttr("inactive", true); - } - ]]></body> - </method> - - <!-- --> - <!-- Helpers --> - <!-- --> - - <method name="setBooleanAttr"> - <parameter name="name"/> - <parameter name="val"/> - <body><![CDATA[ - if(val) - { - this.setAttribute(name, "true"); - } - else - { - this.removeAttribute(name); - } - ]]></body> - </method> - </implementation> - </binding> + <binding id="statuspanel" display="xul:hbox" extends="chrome://browser/content/tabbrowser.xml#statuspanel"> + <implementation> + <!-- --> + <!-- Inverted mirror handling --> + <!-- --> + + <field name="_invertMirror"><![CDATA[ + false + ]]></field> + + <property name="invertMirror"> + <setter><![CDATA[ + this._invertMirror = val; + this.mirror = this._isMirrored; + return val; + ]]></setter> + <getter><![CDATA[ + return this._invertMirror; + ]]></getter> + </property> + + <!-- --> + <!-- Mouse mirror handling --> + <!-- --> + + <field name="_mouseMirror"><![CDATA[ + true + ]]></field> + + <field name="_mouseMirrorListen"><![CDATA[ + false + ]]></field> + + <property name="mouseMirror"> + <setter><![CDATA[ + this._mouseMirror = val; + this.setupMouseMirror(this.value); + return val; + ]]></setter> + <getter><![CDATA[ + return this._mouseMirror; + ]]></getter> + </property> + + <method name="setupMouseMirror"> + <parameter name="val"/> + <body><![CDATA[ + if(val && this._mouseMirror) + { + this._calcMouseTargetRect(); + if(!this._mouseMirrorListen) + { + MousePosTracker.addListener(this); + this._mouseMirrorListen = true; + } + } + else + { + this.mirror = false; + if(this._mouseMirrorListen) + { + MousePosTracker.removeListener(this); + this._mouseMirrorListen = false; + } + } + ]]></body> + </method> + + <method name="_calcMouseTargetRect"> + <body><![CDATA[ + let alignRight = false; + let isRTL = (getComputedStyle(document.documentElement).direction == "rtl"); + if((this._invertMirror && !isRTL) || (!this._invertMirror && isRTL)) + { + alignRight = true; + } + + let rect = this.getBoundingClientRect(); + this._mouseTargetRect = + { + top: rect.top, + bottom: rect.bottom, + left: ((alignRight) ? window.innerWidth - rect.width : 0), + right: ((alignRight) ? window.innerWidth : rect.width) + }; + ]]></body> + </method> + + <method name="onMouseEnter"> + <body><![CDATA[ + this.mirror = true; + ]]></body> + </method> + + <method name="onMouseLeave"> + <body><![CDATA[ + this.mirror = false; + ]]></body> + </method> + + <!-- --> + <!-- Mirror handling --> + <!-- --> + + <field name="_isMirrored"><![CDATA[ + false + ]]></field> + + <property name="mirror"> + <setter><![CDATA[ + this._isMirrored = val; + if(this._invertMirror) + { + val = !val; + } + + this.setBooleanAttr("mirror", val); + ]]></setter> + <getter><![CDATA[ + return this._isMirrored; + ]]></getter> + </property> + + <method name="_mirror"> + <body><![CDATA[ + this.mirror = !this._isMirrored; + ]]></body> + </method> + + <!-- --> + <!-- Value handling --> + <!-- --> + + <property name="label"> + <setter><![CDATA[ + if(window.caligon && window.caligon.status4evar) + { + window.caligon.status4evar.statusService.setStatusText(val); + } + return undefined; + ]]></setter> + <getter><![CDATA[ + if(window.caligon && window.caligon.status4evar) + { + return window.caligon.status4evar.statusService.getStatusText(); + } + return ""; + ]]></getter> + </property> + + <property name="value"> + <setter><![CDATA[ + this.setValue(val); + this.setupMouseMirror(val); + return val; + ]]></setter> + <getter><![CDATA[ + return ((this.hasAttribute("inactive")) ? "" : this.getAttribute("label")); + ]]></getter> + </property> + + <method name="setValue"> + <parameter name="val"/> + <body><![CDATA[ + if((this.getAttribute("type") || "").indexOf("network") > -1 && (this.getAttribute("previoustype") || "").indexOf("network") > -1) + { + this.style.minWidth = getComputedStyle(this).width; + } + else + { + this.style.minWidth = ""; + } + + if(val) + { + this.setAttribute("label", val); + this.setBooleanAttr("inactive", false); + } + else + { + this.setBooleanAttr("inactive", true); + } + ]]></body> + </method> + + <!-- --> + <!-- Helpers --> + <!-- --> + + <method name="setBooleanAttr"> + <parameter name="name"/> + <parameter name="val"/> + <body><![CDATA[ + if(val) + { + this.setAttribute(name, "true"); + } + else + { + this.removeAttribute(name); + } + ]]></body> + </method> + </implementation> + </binding> </bindings> diff --git a/application/palemoon/components/statusbar/status4evar.idl b/application/palemoon/components/statusbar/status4evar.idl index d14fcbcd1..534dea31c 100644 --- a/application/palemoon/components/statusbar/status4evar.idl +++ b/application/palemoon/components/statusbar/status4evar.idl @@ -9,49 +9,49 @@ interface nsIDOMWindow; [scriptable, uuid(33d0433d-07be-4dc4-87fd-954057310efd)] interface nsIStatus4Evar : nsISupports { - readonly attribute boolean addonbarBorderStyle; - readonly attribute boolean addonbarCloseButton; - readonly attribute boolean addonbarLegacyShim; - readonly attribute boolean addonbarWindowGripper; - - readonly attribute boolean advancedStatusDetectFullScreen; - readonly attribute boolean advancedStatusDetectVideo; - - readonly attribute long downloadButtonAction; - readonly attribute ACString downloadButtonActionCommand; - readonly attribute ACString downloadColorActive; - readonly attribute ACString downloadColorPaused; - readonly attribute boolean downloadForce; - readonly attribute long downloadLabel; - readonly attribute boolean downloadLabelForce; - readonly attribute boolean downloadNotifyAnimate; - readonly attribute long downloadNotifyTimeout; - readonly attribute long downloadProgress; - readonly attribute long downloadTooltip; - - readonly attribute boolean firstRun; - readonly attribute boolean firstRunAustralis; - - readonly attribute ACString progressToolbarCSS; - readonly attribute boolean progressToolbarForce; - readonly attribute boolean progressToolbarStyle; - readonly attribute boolean progressToolbarStyleAdvanced; - - readonly attribute long status; - readonly attribute boolean statusDefault; - readonly attribute boolean statusNetwork; - readonly attribute boolean statusNetworkXHR; - readonly attribute long statusTimeout; - readonly attribute long statusLinkOver; - readonly attribute long statusLinkOverDelayShow; - readonly attribute long statusLinkOverDelayHide; - - readonly attribute long statusToolbarMaxLength; - - readonly attribute boolean statusToolbarInvertMirror; - readonly attribute boolean statusToolbarMouseMirror; - - void resetPrefs(); - void updateWindow(in nsIDOMWindow win); + readonly attribute boolean addonbarBorderStyle; + readonly attribute boolean addonbarCloseButton; + readonly attribute boolean addonbarLegacyShim; + readonly attribute boolean addonbarWindowGripper; + + readonly attribute boolean advancedStatusDetectFullScreen; + readonly attribute boolean advancedStatusDetectVideo; + + readonly attribute long downloadButtonAction; + readonly attribute ACString downloadButtonActionCommand; + readonly attribute ACString downloadColorActive; + readonly attribute ACString downloadColorPaused; + readonly attribute boolean downloadForce; + readonly attribute long downloadLabel; + readonly attribute boolean downloadLabelForce; + readonly attribute boolean downloadNotifyAnimate; + readonly attribute long downloadNotifyTimeout; + readonly attribute long downloadProgress; + readonly attribute long downloadTooltip; + + readonly attribute boolean firstRun; + readonly attribute boolean firstRunAustralis; + + readonly attribute ACString progressToolbarCSS; + readonly attribute boolean progressToolbarForce; + readonly attribute boolean progressToolbarStyle; + readonly attribute boolean progressToolbarStyleAdvanced; + + readonly attribute long status; + readonly attribute boolean statusDefault; + readonly attribute boolean statusNetwork; + readonly attribute boolean statusNetworkXHR; + readonly attribute long statusTimeout; + readonly attribute long statusLinkOver; + readonly attribute long statusLinkOverDelayShow; + readonly attribute long statusLinkOverDelayHide; + + readonly attribute long statusToolbarMaxLength; + + readonly attribute boolean statusToolbarInvertMirror; + readonly attribute boolean statusToolbarMouseMirror; + + void resetPrefs(); + void updateWindow(in nsIDOMWindow win); }; diff --git a/application/palemoon/components/statusbar/status4evar.js b/application/palemoon/components/statusbar/status4evar.js index abc6c9175..4aa2e3e78 100644 --- a/application/palemoon/components/statusbar/status4evar.js +++ b/application/palemoon/components/statusbar/status4evar.js @@ -18,677 +18,677 @@ function Status_4_Evar(){} Status_4_Evar.prototype = { - classID: Components.ID("{33d0433d-07be-4dc4-87fd-954057310efd}"), - QueryInterface: XPCOMUtils.generateQI([ - CI.nsISupportsWeakReference, - CI.nsIObserver, - CI.nsIStatus4Evar - ]), - - prefs: null, - - addonbarBorderStyle: false, - addonbarCloseButton: false, - addonbarWindowGripper: true, - - advancedStatusDetectFullScreen: true, - advancedStatusDetectVideo: true, - - downloadButtonAction: 1, - downloadButtonActionCommand: "", - downloadColorActive: null, - downloadColorPaused: null, - downloadForce: false, - downloadLabel: 0, - downloadLabelForce: true, - downloadNotifyAnimate: true, - downloadNotifyTimeout: 60000, - downloadProgress: 1, - downloadTooltip: 1, - - firstRun: true, - - progressToolbarCSS: null, - progressToolbarForce: false, - progressToolbarStyle: false, - - status: 1, - statusDefault: true, - statusNetwork: true, - statusTimeout: 10000, - statusLinkOver: 1, - statusLinkOverDelayShow: 70, - statusLinkOverDelayHide: 150, - - statusToolbarMaxLength: 0, - - statusToolbarInvertMirror: false, - statusToolbarMouseMirror: true, - - pref_registry: - { - "addonbar.borderStyle": - { - update: function() - { - this.addonbarBorderStyle = this.prefs.getBoolPref("addonbar.borderStyle"); - }, - updateWindow: function(win) - { - let browser_bottom_box = win.caligon.status4evar.getters.browserBottomBox; - if(browser_bottom_box) - { - this.setBoolElementAttribute(browser_bottom_box, "s4eboarder", this.addonbarBorderStyle); - } - } - }, - - "addonbar.closeButton": - { - update: function() - { - this.addonbarCloseButton = this.prefs.getBoolPref("addonbar.closeButton"); - }, - updateWindow: function(win) - { - let addonbar_close_button = win.caligon.status4evar.getters.addonbarCloseButton; - if(addonbar_close_button) - { - addonbar_close_button.hidden = !this.addonbarCloseButton; - } - } - }, - - "addonbar.windowGripper": - { - update: function() - { - this.addonbarWindowGripper = this.prefs.getBoolPref("addonbar.windowGripper"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.toolbars.updateWindowGripper(true); - } - }, - - "advanced.status.detectFullScreen": - { - update: function() - { - this.advancedStatusDetectFullScreen = this.prefs.getBoolPref("advanced.status.detectFullScreen"); - } - }, - - "advanced.status.detectVideo": - { - update: function() - { - this.advancedStatusDetectVideo = this.prefs.getBoolPref("advanced.status.detectVideo"); - } - }, - - "download.button.action": - { - update: function() - { - this.downloadButtonAction = this.prefs.getIntPref("download.button.action"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateBinding(); - } - }, - - "download.button.action.command": - { - update: function() - { - this.downloadButtonActionCommand = this.prefs.getCharPref("download.button.action.command"); - } - }, - - "download.color.active": - { - update: function() - { - this.downloadColorActive = this.prefs.getCharPref("download.color.active"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[2].style.backgroundColor = this.downloadColorActive; - } - }, - - "download.color.paused": - { - update: function() - { - this.downloadColorPaused = this.prefs.getCharPref("download.color.paused"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[3].style.backgroundColor = this.downloadColorPaused; - } - }, - - "download.force": - { - update: function() - { - this.downloadForce = this.prefs.getBoolPref("download.force"); - }, - updateWindow: function(win) - { - let download_button = win.caligon.status4evar.getters.downloadButton; - if(download_button) - { - this.setBoolElementAttribute(download_button, "forcevisible", this.downloadForce); - } - - let download_notify_anchor = win.caligon.status4evar.getters.downloadNotifyAnchor; - this.setBoolElementAttribute(download_notify_anchor, "forcevisible", this.downloadForce); - } - }, - - "download.label": - { - update: function() - { - this.downloadLabel = this.prefs.getIntPref("download.label"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "download.label.force": - { - update: function() - { - this.downloadLabelForce = this.prefs.getBoolPref("download.label.force"); - }, - updateWindow: function(win) - { - let download_button = win.caligon.status4evar.getters.downloadButton; - if(download_button) - { - this.setBoolElementAttribute(download_button, "forcelabel", this.downloadLabelForce); - } - } - }, - - "download.notify.animate": - { - update: function() - { - this.downloadNotifyAnimate = this.prefs.getBoolPref("download.notify.animate"); - } - }, - - "download.notify.timeout": - { - update: function() - { - this.downloadNotifyTimeout = (this.prefs.getIntPref("download.notify.timeout") * 1000); - } - }, - - "download.progress": - { - update: function() - { - this.downloadProgress = this.prefs.getIntPref("download.progress"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "download.tooltip": - { - update: function() - { - this.downloadTooltip = this.prefs.getIntPref("download.tooltip"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.downloadStatus.updateButton(); - } - }, - - "progress.toolbar.css": - { - update: function() - { - this.progressToolbarCSS = this.prefs.getCharPref("progress.toolbar.css"); - }, - updateDynamicStyle: function(sheet) - { - sheet.cssRules[1].style.background = this.progressToolbarCSS; - } - }, - - "progress.toolbar.force": - { - update: function() - { - this.progressToolbarForce = this.prefs.getBoolPref("progress.toolbar.force"); - }, - updateWindow: function(win) - { - let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; - if(toolbar_progress) - { - this.setBoolElementAttribute(toolbar_progress, "forcevisible", this.progressToolbarForce); - } - } - }, - - "progress.toolbar.style": - { - update: function() - { - this.progressToolbarStyle = this.prefs.getBoolPref("progress.toolbar.style"); - }, - updateWindow: function(win) - { - let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; - if(toolbar_progress) - { - this.setBoolElementAttribute(toolbar_progress, "s4estyle", this.progressToolbarStyle); - } - } - }, - - "status": - { - update: function() - { - this.status = this.prefs.getIntPref("status"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.clearStatusField(); - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.default": - { - update: function() - { - this.statusDefault = this.prefs.getBoolPref("status.default"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.linkOver": - { - update: function() - { - this.statusLinkOver = this.prefs.getIntPref("status.linkOver"); - } - }, - - "status.linkOver.delay.show": - { - update: function() - { - this.statusLinkOverDelayShow = this.prefs.getIntPref("status.linkOver.delay.show"); - } - }, - - "status.linkOver.delay.hide": - { - update: function() - { - this.statusLinkOverDelayHide = this.prefs.getIntPref("status.linkOver.delay.hide"); - } - }, - - "status.network": - { - update: function() - { - this.statusNetwork = this.prefs.getBoolPref("status.network"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - } - }, - - "status.network.xhr": - { - update: function() - { - this.statusNetworkXHR = this.prefs.getBoolPref("status.network.xhr"); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.buildTextOrder(); - } - }, - - "status.timeout": - { - update: function() - { - this.statusTimeout = (this.prefs.getIntPref("status.timeout") * 1000); - }, - updateWindow: function(win) - { - win.caligon.status4evar.statusService.updateStatusField(true); - } - }, - - "status.toolbar.maxLength": - { - update: function() - { - this.statusToolbarMaxLength = this.prefs.getIntPref("status.toolbar.maxLength"); - }, - updateWindow: function(win) - { - let status_widget = win.caligon.status4evar.getters.statusWidget; - if(status_widget) - { - status_widget.maxWidth = (this.statusToolbarMaxLength || ""); - } - } - }, - - "status.popup.invertMirror": - { - update: function() - { - this.statusToolbarInvertMirror = this.prefs.getBoolPref("status.popup.invertMirror"); - }, - updateWindow: function(win) - { - let statusOverlay = win.caligon.status4evar.getters.statusOverlay; - if(statusOverlay) - { - statusOverlay.invertMirror = this.statusToolbarInvertMirror; - } - } - }, - - "status.popup.mouseMirror": - { - update: function() - { - this.statusToolbarMouseMirror = this.prefs.getBoolPref("status.popup.mouseMirror"); - }, - updateWindow: function(win) - { - let statusOverlay = win.caligon.status4evar.getters.statusOverlay; - if(statusOverlay) - { - statusOverlay.mouseMirror = this.statusToolbarMouseMirror; - } - } - } - - }, - - // nsIObserver - observe: function(subject, topic, data) - { - try - { - switch(topic) - { - case "profile-after-change": - this.startup(); - break; - case "quit-application": - this.shutdown(); - break; - case "nsPref:changed": - this.updatePref(data, true); - break; - } - } - catch(e) - { - CU.reportError(e); - } - }, - - startup: function() - { - this.prefs = Services.prefs.getBranch("status4evar.").QueryInterface(CI.nsIPrefBranch2); - - this.firstRun = this.prefs.getBoolPref("firstRun"); - if(this.firstRun) - { - this.prefs.setBoolPref("firstRun", false); - } - - this.migrate(); - - for(let pref in this.pref_registry) - { - let pro = this.pref_registry[pref]; - - pro.update = pro.update.bind(this); - if(pro.updateWindow) - { - pro.updateWindow = pro.updateWindow.bind(this); - } - if(pro.updateDynamicStyle) - { - pro.updateDynamicStyle = pro.updateDynamicStyle.bind(this); - } - - this.prefs.addObserver(pref, this, true); - - this.updatePref(pref, false); - } - - Services.obs.addObserver(this, "quit-application", true); - }, - - shutdown: function() - { - Services.obs.removeObserver(this, "quit-application"); - - for(let pref in this.pref_registry) - { - this.prefs.removeObserver(pref, this); - } - - this.prefs = null; - }, - - migrate: function() - { - if(!this.firstRun) - { - let migration = 0; - try - { - migration = this.prefs.getIntPref("migration"); - } - catch(e) {} - - switch(migration) - { - case 5: - this.migrateBoolPref("status.detectFullScreen", "advanced.status.detectFullScreen"); - case 6: - let oldDownloadAction = this.prefs.getIntPref("download.button.action"); - let newDownloadAction = 1; - switch(oldDownloadAction) - { - case 2: - newDownloadAction = 1; - break; - case 3: - newDownloadAction = 2; - break; - case 4: - newDownloadAction = 1; - break; - } - this.prefs.setIntPref("download.button.action", newDownloadAction); - case 7: - let progressLocation = this.prefs.getIntPref("status"); - if (progressLocation == 2) - this.prefs.setIntPref("status", 1); - let linkOverLocation = this.prefs.getIntPref("status.linkOver"); - if (linkOverLocation == 2) - this.prefs.setIntPref("status.linkOver", 1); - break; - case CURRENT_MIGRATION: - break; - } - } - - this.prefs.setIntPref("migration", CURRENT_MIGRATION); - }, - - migrateBoolPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setBoolPref(newPref, this.prefs.getBoolPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - migrateIntPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setIntPref(newPref, this.prefs.getIntPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - migrateCharPref: function(oldPref, newPref) - { - if(this.prefs.prefHasUserValue(oldPref)) - { - this.prefs.setCharPref(newPref, this.prefs.getCharPref(oldPref)); - this.prefs.clearUserPref(oldPref); - } - }, - - updatePref: function(pref, updateWindows) - { - if(!(pref in this.pref_registry)) - { - return; - } - let pro = this.pref_registry[pref]; - - pro.update(); - - if(updateWindows) - { - let windowsEnum = Services.wm.getEnumerator("navigator:browser"); - while(windowsEnum.hasMoreElements()) - { - this.updateWindow(windowsEnum.getNext(), pro); - } - } - - if(pro.alsoUpdate) - { - pro.alsoUpdate.forEach(function (alsoPref) - { - this.updatePref(alsoPref); - }, this); - } - }, - - // Updtate a browser window - updateWindow: function(win, pro) - { - if(!(win instanceof CI.nsIDOMWindow) - || !(win.document.documentElement.getAttribute("windowtype") == "navigator:browser")) - { - return; - } - - if(pro) - { - this.handlePro(win, pro); - } - else - { - for(let pref in this.pref_registry) - { - this.handlePro(win, this.pref_registry[pref]); - } - } - }, - - handlePro: function(win, pro) - { - if(pro.updateWindow) - { - pro.updateWindow(win); - } - - if(pro.updateDynamicStyle) - { - let styleSheets = win.document.styleSheets; - for(let i = 0; i < styleSheets.length; i++) - { - let styleSheet = styleSheets[i]; - if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") - { - pro.updateDynamicStyle(styleSheet); - break; - } - } - } - }, - - setBoolElementAttribute: function(elem, attr, val) - { - if(val) - { - elem.setAttribute(attr, "true"); - } - else - { - elem.removeAttribute(attr); - } - }, - - setStringElementAttribute: function(elem, attr, val) - { - if(val) - { - elem.setAttribute(attr, val); - } - else - { - elem.removeAttribute(attr); - } - }, - - resetPrefs: function() - { - let childPrefs = this.prefs.getChildList(""); - childPrefs.forEach(function(pref) - { - if(this.prefs.prefHasUserValue(pref)) - { - this.prefs.clearUserPref(pref); - } - }, this); - } + classID: Components.ID("{33d0433d-07be-4dc4-87fd-954057310efd}"), + QueryInterface: XPCOMUtils.generateQI([ + CI.nsISupportsWeakReference, + CI.nsIObserver, + CI.nsIStatus4Evar + ]), + + prefs: null, + + addonbarBorderStyle: false, + addonbarCloseButton: false, + addonbarWindowGripper: true, + + advancedStatusDetectFullScreen: true, + advancedStatusDetectVideo: true, + + downloadButtonAction: 1, + downloadButtonActionCommand: "", + downloadColorActive: null, + downloadColorPaused: null, + downloadForce: false, + downloadLabel: 0, + downloadLabelForce: true, + downloadNotifyAnimate: true, + downloadNotifyTimeout: 60000, + downloadProgress: 1, + downloadTooltip: 1, + + firstRun: true, + + progressToolbarCSS: null, + progressToolbarForce: false, + progressToolbarStyle: false, + + status: 1, + statusDefault: true, + statusNetwork: true, + statusTimeout: 10000, + statusLinkOver: 1, + statusLinkOverDelayShow: 70, + statusLinkOverDelayHide: 150, + + statusToolbarMaxLength: 0, + + statusToolbarInvertMirror: false, + statusToolbarMouseMirror: true, + + pref_registry: + { + "addonbar.borderStyle": + { + update: function() + { + this.addonbarBorderStyle = this.prefs.getBoolPref("addonbar.borderStyle"); + }, + updateWindow: function(win) + { + let browser_bottom_box = win.caligon.status4evar.getters.browserBottomBox; + if(browser_bottom_box) + { + this.setBoolElementAttribute(browser_bottom_box, "s4eboarder", this.addonbarBorderStyle); + } + } + }, + + "addonbar.closeButton": + { + update: function() + { + this.addonbarCloseButton = this.prefs.getBoolPref("addonbar.closeButton"); + }, + updateWindow: function(win) + { + let addonbar_close_button = win.caligon.status4evar.getters.addonbarCloseButton; + if(addonbar_close_button) + { + addonbar_close_button.hidden = !this.addonbarCloseButton; + } + } + }, + + "addonbar.windowGripper": + { + update: function() + { + this.addonbarWindowGripper = this.prefs.getBoolPref("addonbar.windowGripper"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.toolbars.updateWindowGripper(true); + } + }, + + "advanced.status.detectFullScreen": + { + update: function() + { + this.advancedStatusDetectFullScreen = this.prefs.getBoolPref("advanced.status.detectFullScreen"); + } + }, + + "advanced.status.detectVideo": + { + update: function() + { + this.advancedStatusDetectVideo = this.prefs.getBoolPref("advanced.status.detectVideo"); + } + }, + + "download.button.action": + { + update: function() + { + this.downloadButtonAction = this.prefs.getIntPref("download.button.action"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateBinding(); + } + }, + + "download.button.action.command": + { + update: function() + { + this.downloadButtonActionCommand = this.prefs.getCharPref("download.button.action.command"); + } + }, + + "download.color.active": + { + update: function() + { + this.downloadColorActive = this.prefs.getCharPref("download.color.active"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[2].style.backgroundColor = this.downloadColorActive; + } + }, + + "download.color.paused": + { + update: function() + { + this.downloadColorPaused = this.prefs.getCharPref("download.color.paused"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[3].style.backgroundColor = this.downloadColorPaused; + } + }, + + "download.force": + { + update: function() + { + this.downloadForce = this.prefs.getBoolPref("download.force"); + }, + updateWindow: function(win) + { + let download_button = win.caligon.status4evar.getters.downloadButton; + if(download_button) + { + this.setBoolElementAttribute(download_button, "forcevisible", this.downloadForce); + } + + let download_notify_anchor = win.caligon.status4evar.getters.downloadNotifyAnchor; + this.setBoolElementAttribute(download_notify_anchor, "forcevisible", this.downloadForce); + } + }, + + "download.label": + { + update: function() + { + this.downloadLabel = this.prefs.getIntPref("download.label"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "download.label.force": + { + update: function() + { + this.downloadLabelForce = this.prefs.getBoolPref("download.label.force"); + }, + updateWindow: function(win) + { + let download_button = win.caligon.status4evar.getters.downloadButton; + if(download_button) + { + this.setBoolElementAttribute(download_button, "forcelabel", this.downloadLabelForce); + } + } + }, + + "download.notify.animate": + { + update: function() + { + this.downloadNotifyAnimate = this.prefs.getBoolPref("download.notify.animate"); + } + }, + + "download.notify.timeout": + { + update: function() + { + this.downloadNotifyTimeout = (this.prefs.getIntPref("download.notify.timeout") * 1000); + } + }, + + "download.progress": + { + update: function() + { + this.downloadProgress = this.prefs.getIntPref("download.progress"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "download.tooltip": + { + update: function() + { + this.downloadTooltip = this.prefs.getIntPref("download.tooltip"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.downloadStatus.updateButton(); + } + }, + + "progress.toolbar.css": + { + update: function() + { + this.progressToolbarCSS = this.prefs.getCharPref("progress.toolbar.css"); + }, + updateDynamicStyle: function(sheet) + { + sheet.cssRules[1].style.background = this.progressToolbarCSS; + } + }, + + "progress.toolbar.force": + { + update: function() + { + this.progressToolbarForce = this.prefs.getBoolPref("progress.toolbar.force"); + }, + updateWindow: function(win) + { + let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; + if(toolbar_progress) + { + this.setBoolElementAttribute(toolbar_progress, "forcevisible", this.progressToolbarForce); + } + } + }, + + "progress.toolbar.style": + { + update: function() + { + this.progressToolbarStyle = this.prefs.getBoolPref("progress.toolbar.style"); + }, + updateWindow: function(win) + { + let toolbar_progress = win.caligon.status4evar.getters.toolbarProgress; + if(toolbar_progress) + { + this.setBoolElementAttribute(toolbar_progress, "s4estyle", this.progressToolbarStyle); + } + } + }, + + "status": + { + update: function() + { + this.status = this.prefs.getIntPref("status"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.clearStatusField(); + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.default": + { + update: function() + { + this.statusDefault = this.prefs.getBoolPref("status.default"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.linkOver": + { + update: function() + { + this.statusLinkOver = this.prefs.getIntPref("status.linkOver"); + } + }, + + "status.linkOver.delay.show": + { + update: function() + { + this.statusLinkOverDelayShow = this.prefs.getIntPref("status.linkOver.delay.show"); + } + }, + + "status.linkOver.delay.hide": + { + update: function() + { + this.statusLinkOverDelayHide = this.prefs.getIntPref("status.linkOver.delay.hide"); + } + }, + + "status.network": + { + update: function() + { + this.statusNetwork = this.prefs.getBoolPref("status.network"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + } + }, + + "status.network.xhr": + { + update: function() + { + this.statusNetworkXHR = this.prefs.getBoolPref("status.network.xhr"); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.buildTextOrder(); + } + }, + + "status.timeout": + { + update: function() + { + this.statusTimeout = (this.prefs.getIntPref("status.timeout") * 1000); + }, + updateWindow: function(win) + { + win.caligon.status4evar.statusService.updateStatusField(true); + } + }, + + "status.toolbar.maxLength": + { + update: function() + { + this.statusToolbarMaxLength = this.prefs.getIntPref("status.toolbar.maxLength"); + }, + updateWindow: function(win) + { + let status_widget = win.caligon.status4evar.getters.statusWidget; + if(status_widget) + { + status_widget.maxWidth = (this.statusToolbarMaxLength || ""); + } + } + }, + + "status.popup.invertMirror": + { + update: function() + { + this.statusToolbarInvertMirror = this.prefs.getBoolPref("status.popup.invertMirror"); + }, + updateWindow: function(win) + { + let statusOverlay = win.caligon.status4evar.getters.statusOverlay; + if(statusOverlay) + { + statusOverlay.invertMirror = this.statusToolbarInvertMirror; + } + } + }, + + "status.popup.mouseMirror": + { + update: function() + { + this.statusToolbarMouseMirror = this.prefs.getBoolPref("status.popup.mouseMirror"); + }, + updateWindow: function(win) + { + let statusOverlay = win.caligon.status4evar.getters.statusOverlay; + if(statusOverlay) + { + statusOverlay.mouseMirror = this.statusToolbarMouseMirror; + } + } + } + + }, + + // nsIObserver + observe: function(subject, topic, data) + { + try + { + switch(topic) + { + case "profile-after-change": + this.startup(); + break; + case "quit-application": + this.shutdown(); + break; + case "nsPref:changed": + this.updatePref(data, true); + break; + } + } + catch(e) + { + CU.reportError(e); + } + }, + + startup: function() + { + this.prefs = Services.prefs.getBranch("status4evar.").QueryInterface(CI.nsIPrefBranch2); + + this.firstRun = this.prefs.getBoolPref("firstRun"); + if(this.firstRun) + { + this.prefs.setBoolPref("firstRun", false); + } + + this.migrate(); + + for(let pref in this.pref_registry) + { + let pro = this.pref_registry[pref]; + + pro.update = pro.update.bind(this); + if(pro.updateWindow) + { + pro.updateWindow = pro.updateWindow.bind(this); + } + if(pro.updateDynamicStyle) + { + pro.updateDynamicStyle = pro.updateDynamicStyle.bind(this); + } + + this.prefs.addObserver(pref, this, true); + + this.updatePref(pref, false); + } + + Services.obs.addObserver(this, "quit-application", true); + }, + + shutdown: function() + { + Services.obs.removeObserver(this, "quit-application"); + + for(let pref in this.pref_registry) + { + this.prefs.removeObserver(pref, this); + } + + this.prefs = null; + }, + + migrate: function() + { + if(!this.firstRun) + { + let migration = 0; + try + { + migration = this.prefs.getIntPref("migration"); + } + catch(e) {} + + switch(migration) + { + case 5: + this.migrateBoolPref("status.detectFullScreen", "advanced.status.detectFullScreen"); + case 6: + let oldDownloadAction = this.prefs.getIntPref("download.button.action"); + let newDownloadAction = 1; + switch(oldDownloadAction) + { + case 2: + newDownloadAction = 1; + break; + case 3: + newDownloadAction = 2; + break; + case 4: + newDownloadAction = 1; + break; + } + this.prefs.setIntPref("download.button.action", newDownloadAction); + case 7: + let progressLocation = this.prefs.getIntPref("status"); + if (progressLocation == 2) + this.prefs.setIntPref("status", 1); + let linkOverLocation = this.prefs.getIntPref("status.linkOver"); + if (linkOverLocation == 2) + this.prefs.setIntPref("status.linkOver", 1); + break; + case CURRENT_MIGRATION: + break; + } + } + + this.prefs.setIntPref("migration", CURRENT_MIGRATION); + }, + + migrateBoolPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setBoolPref(newPref, this.prefs.getBoolPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + migrateIntPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setIntPref(newPref, this.prefs.getIntPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + migrateCharPref: function(oldPref, newPref) + { + if(this.prefs.prefHasUserValue(oldPref)) + { + this.prefs.setCharPref(newPref, this.prefs.getCharPref(oldPref)); + this.prefs.clearUserPref(oldPref); + } + }, + + updatePref: function(pref, updateWindows) + { + if(!(pref in this.pref_registry)) + { + return; + } + let pro = this.pref_registry[pref]; + + pro.update(); + + if(updateWindows) + { + let windowsEnum = Services.wm.getEnumerator("navigator:browser"); + while(windowsEnum.hasMoreElements()) + { + this.updateWindow(windowsEnum.getNext(), pro); + } + } + + if(pro.alsoUpdate) + { + pro.alsoUpdate.forEach(function (alsoPref) + { + this.updatePref(alsoPref); + }, this); + } + }, + + // Updtate a browser window + updateWindow: function(win, pro) + { + if(!(win instanceof CI.nsIDOMWindow) + || !(win.document.documentElement.getAttribute("windowtype") == "navigator:browser")) + { + return; + } + + if(pro) + { + this.handlePro(win, pro); + } + else + { + for(let pref in this.pref_registry) + { + this.handlePro(win, this.pref_registry[pref]); + } + } + }, + + handlePro: function(win, pro) + { + if(pro.updateWindow) + { + pro.updateWindow(win); + } + + if(pro.updateDynamicStyle) + { + let styleSheets = win.document.styleSheets; + for(let i = 0; i < styleSheets.length; i++) + { + let styleSheet = styleSheets[i]; + if(styleSheet.href == "chrome://browser/skin/statusbar/dynamic.css") + { + pro.updateDynamicStyle(styleSheet); + break; + } + } + } + }, + + setBoolElementAttribute: function(elem, attr, val) + { + if(val) + { + elem.setAttribute(attr, "true"); + } + else + { + elem.removeAttribute(attr); + } + }, + + setStringElementAttribute: function(elem, attr, val) + { + if(val) + { + elem.setAttribute(attr, val); + } + else + { + elem.removeAttribute(attr); + } + }, + + resetPrefs: function() + { + let childPrefs = this.prefs.getChildList(""); + childPrefs.forEach(function(pref) + { + if(this.prefs.prefHasUserValue(pref)) + { + this.prefs.clearUserPref(pref); + } + }, this); + } }; const NSGetFactory = XPCOMUtils.generateNSGetFactory([Status_4_Evar]); |