From 4492b5f8e774bf3b4f21e4e468fc052cbcbb468a Mon Sep 17 00:00:00 2001
From: Thomas Groman
Date: Mon, 16 Dec 2019 19:48:42 -0800
Subject: initial commit
---
LICENSE | 7 +
Makefile.in | 13 +
app-rules.mk | 1 +
app.mozbuild | 17 +
app/Makefile.in | 108 +
app/application.ini | 50 +
app/blocklist.xml | 3909 ++++++++++
app/macbuild/Contents/CodeResources | 1 +
app/macbuild/Contents/Info.plist.in | 227 +
app/macbuild/Contents/MacOS-files.in | 10 +
.../Resources/English.lproj/InfoPlist.strings.in | 5 +
app/macbuild/Contents/_CodeSignature/CodeResources | 71 +
app/macversion.py | 44 +
app/module.ver | 8 +
app/moz.build | 64 +
app/nsBrowserApp.cpp | 393 ++
app/palemoon.exe.manifest | 48 +
app/permissions | 14 +
app/profile/channel-prefs.js | 6 +
app/profile/extensions/moz.build | 7 +
.../Makefile.in | 10 +
.../install.rdf.in | 40 +
.../moz.build | 8 +
app/profile/pagethemes.rdf | 7 +
app/profile/palemoon.js | 1205 ++++
app/profile/prefs.js | 13 +
app/splash.rc | 21 +
base/content/aboutDialog.css | 74 +
base/content/aboutDialog.js | 62 +
base/content/aboutDialog.xul | 86 +
base/content/autocomplete.css | 17 +
base/content/autocomplete.xml | 2128 ++++++
base/content/autorecovery.js | 60 +
base/content/autorecovery.xul | 12 +
base/content/baseMenuOverlay.xul | 114 +
base/content/browser-addons.js | 537 ++
base/content/browser-appmenu.inc | 381 +
base/content/browser-charsetmenu.inc | 62 +
base/content/browser-context.inc | 384 +
base/content/browser-devtools-theme.js | 91 +
base/content/browser-doctype.inc | 19 +
base/content/browser-feeds.js | 224 +
base/content/browser-fullScreen.js | 462 ++
base/content/browser-fullZoom.js | 526 ++
base/content/browser-gestureSupport.js | 1059 +++
base/content/browser-menubar.inc | 564 ++
base/content/browser-menudragging.js | 340 +
base/content/browser-menudragging.xul | 13 +
base/content/browser-places.js | 1316 ++++
base/content/browser-plugins.js | 781 ++
base/content/browser-sets.inc | 357 +
base/content/browser-syncui.js | 472 ++
base/content/browser-tabPreviews.js | 1058 +++
base/content/browser-tabPreviews.xml | 78 +
base/content/browser-thumbnails.js | 203 +
base/content/browser-title.css | 204 +
base/content/browser-uacompat.js | 45 +
base/content/browser-webrtcUI.js | 55 +
base/content/browser.css | 759 ++
base/content/browser.js | 7440 ++++++++++++++++++++
base/content/browser.xul | 1046 +++
base/content/browserMountPoints.inc | 12 +
base/content/content.js | 177 +
base/content/downloadManagerOverlay.xul | 32 +
base/content/global-devtools-theme-scripts.inc | 6 +
base/content/global-scripts.inc | 13 +
base/content/hiddenWindow.xul | 19 +
base/content/highlighter.css | 105 +
base/content/jsConsoleOverlay.xul | 18 +
base/content/macBrowserOverlay.xul | 67 +
base/content/nsContextMenu.js | 1603 +++++
base/content/openLocation.js | 150 +
base/content/openLocation.xul | 57 +
base/content/overrides/app-license.html | 6 +
base/content/padlock.css | 203 +
base/content/padlock.js | 234 +
base/content/padlock.xul | 63 +
base/content/padlock_classic_broken.png | Bin 0 -> 726 bytes
base/content/padlock_classic_ev.png | Bin 0 -> 566 bytes
base/content/padlock_classic_https.png | Bin 0 -> 589 bytes
base/content/padlock_classic_low.png | Bin 0 -> 682 bytes
base/content/padlock_mod_broken.png | Bin 0 -> 728 bytes
base/content/padlock_mod_ev.png | Bin 0 -> 290 bytes
base/content/padlock_mod_https.png | Bin 0 -> 338 bytes
base/content/padlock_mod_low.png | Bin 0 -> 386 bytes
base/content/palemoon.xhtml | 66 +
base/content/popup-notifications.inc | 104 +
base/content/safeMode.css | 8 +
base/content/safeMode.js | 128 +
base/content/safeMode.xul | 55 +
base/content/sanitize.js | 534 ++
base/content/sanitize.xul | 190 +
base/content/sanitizeDialog.css | 23 +
base/content/sanitizeDialog.js | 910 +++
base/content/softwareUpdateOverlay.xul | 18 +
base/content/tabbrowser.css | 77 +
base/content/tabbrowser.xml | 5403 ++++++++++++++
base/content/test/general/audio.ogg | Bin 0 -> 47411 bytes
base/content/urlbarBindings.xml | 1800 +++++
base/content/utilityOverlay.js | 901 +++
base/content/viewSourceOverlay.xul | 26 +
base/content/web-panels.js | 102 +
base/content/web-panels.xul | 84 +
base/content/win6BrowserOverlay.xul | 12 +
base/jar.mn | 79 +
base/moz.build | 20 +
branding/official/LICENSE | 4 +
branding/official/VisualElements_150.png | Bin 0 -> 27921 bytes
branding/official/VisualElements_70.png | Bin 0 -> 7785 bytes
branding/official/appname.bmp | Bin 0 -> 35690 bytes
branding/official/branding.nsi | 16 +
branding/official/configure.sh | 6 +
branding/official/content/about-background.jpg | Bin 0 -> 111893 bytes
branding/official/content/about-logo.png | Bin 0 -> 42128 bytes
branding/official/content/about-logo@2x.png | Bin 0 -> 166292 bytes
branding/official/content/about-wordmark.png | Bin 0 -> 10178 bytes
branding/official/content/about-wordmark.svg | 133 +
branding/official/content/about.png | Bin 0 -> 47380 bytes
branding/official/content/aboutDialog.css | 53 +
branding/official/content/icon48.png | Bin 0 -> 3885 bytes
branding/official/content/icon64.png | Bin 0 -> 6176 bytes
branding/official/content/jar.mn | 16 +
branding/official/content/moz.build | 7 +
branding/official/default16.png | Bin 0 -> 811 bytes
branding/official/default22.png | Bin 0 -> 1377 bytes
branding/official/default24.png | Bin 0 -> 1534 bytes
branding/official/default256.png | Bin 0 -> 70279 bytes
branding/official/default32.png | Bin 0 -> 2273 bytes
branding/official/default48.png | Bin 0 -> 3885 bytes
branding/official/disk.icns | Bin 0 -> 164632 bytes
branding/official/document.icns | Bin 0 -> 111772 bytes
branding/official/document.ico | Bin 0 -> 54261 bytes
branding/official/dsstore | Bin 0 -> 12292 bytes
branding/official/firefox.icns | Bin 0 -> 253858 bytes
branding/official/firefox.ico | Bin 0 -> 94683 bytes
branding/official/locales/en-US/brand.dtd | 4 +
branding/official/locales/en-US/brand.properties | 5 +
branding/official/locales/jar.mn | 11 +
branding/official/locales/moz.build | 7 +
branding/official/moz.build | 13 +
branding/official/mozicon128.png | Bin 0 -> 20601 bytes
.../official/palemoon.VisualElementsManifest.xml | 8 +
branding/official/palemoon.desktop | 353 +
branding/official/pref/palemoon-branding.js | 35 +
branding/official/wizHeader.bmp | Bin 0 -> 25818 bytes
branding/official/wizHeaderRTL.bmp | Bin 0 -> 25818 bytes
branding/official/wizWatermark.bmp | Bin 0 -> 154542 bytes
branding/shared/background.png | Bin 0 -> 115 bytes
branding/shared/branding.mozbuild | 58 +
branding/shared/locales/browserconfig.properties | 2 +
branding/shared/newtab.ico | Bin 0 -> 1150 bytes
branding/shared/newwindow.ico | Bin 0 -> 1150 bytes
branding/shared/pbmode.ico | Bin 0 -> 1150 bytes
branding/shared/pref/preferences.inc | 107 +
branding/shared/pref/uaoverrides.inc | 83 +
branding/unofficial/VisualElements_150.png | Bin 0 -> 19030 bytes
branding/unofficial/VisualElements_70.png | Bin 0 -> 5861 bytes
branding/unofficial/appname.bmp | Bin 0 -> 11158 bytes
branding/unofficial/branding.nsi | 12 +
branding/unofficial/configure.sh | 5 +
branding/unofficial/content/about-background.png | Bin 0 -> 95145 bytes
branding/unofficial/content/about-logo.png | Bin 0 -> 15708 bytes
branding/unofficial/content/about-logo@2x.png | Bin 0 -> 49779 bytes
branding/unofficial/content/about.png | Bin 0 -> 13027 bytes
branding/unofficial/content/aboutDialog.css | 19 +
branding/unofficial/content/icon48.png | Bin 0 -> 2145 bytes
branding/unofficial/content/icon64.png | Bin 0 -> 3025 bytes
branding/unofficial/content/jar.mn | 15 +
branding/unofficial/content/moz.build | 7 +
branding/unofficial/default16.png | Bin 0 -> 693 bytes
branding/unofficial/default32.png | Bin 0 -> 1624 bytes
branding/unofficial/default48.png | Bin 0 -> 2771 bytes
branding/unofficial/disk.icns | Bin 0 -> 39250 bytes
branding/unofficial/document.icns | Bin 0 -> 12451 bytes
branding/unofficial/document.ico | Bin 0 -> 22486 bytes
branding/unofficial/dsstore | Bin 0 -> 6148 bytes
branding/unofficial/firefox.icns | Bin 0 -> 12079 bytes
branding/unofficial/firefox.ico | Bin 0 -> 22486 bytes
.../unofficial/locales/browserconfig.properties | 0
branding/unofficial/locales/en-US/brand.dtd | 4 +
branding/unofficial/locales/en-US/brand.properties | 5 +
branding/unofficial/locales/jar.mn | 12 +
branding/unofficial/locales/moz.build | 3 +
branding/unofficial/moz.build | 13 +
branding/unofficial/mozicon128.png | Bin 0 -> 11024 bytes
branding/unofficial/pref/palemoon-branding.js | 9 +
.../webbrowser.VisualElementsManifest.xml | 8 +
branding/unofficial/webbrowser.desktop | 353 +
branding/unofficial/wizHeader.bmp | Bin 0 -> 25818 bytes
branding/unofficial/wizHeaderRTL.bmp | Bin 0 -> 25818 bytes
branding/unofficial/wizWatermark.bmp | Bin 0 -> 154542 bytes
branding/unstable/VisualElements_150.png | Bin 0 -> 34257 bytes
branding/unstable/VisualElements_70.png | Bin 0 -> 9508 bytes
branding/unstable/appname.bmp | Bin 0 -> 11158 bytes
branding/unstable/branding.nsi | 16 +
branding/unstable/configure.sh | 6 +
branding/unstable/content/about-background.jpg | Bin 0 -> 115006 bytes
branding/unstable/content/about-logo.png | Bin 0 -> 42470 bytes
branding/unstable/content/about-logo@2x.png | Bin 0 -> 120348 bytes
branding/unstable/content/about-wordmark.png | Bin 0 -> 11708 bytes
branding/unstable/content/about.png | Bin 0 -> 55384 bytes
branding/unstable/content/aboutDialog.css | 53 +
branding/unstable/content/icon48.png | Bin 0 -> 4855 bytes
branding/unstable/content/icon64.png | Bin 0 -> 6531 bytes
branding/unstable/content/jar.mn | 16 +
branding/unstable/content/moz.build | 7 +
branding/unstable/default16.png | Bin 0 -> 872 bytes
branding/unstable/default32.png | Bin 0 -> 2499 bytes
branding/unstable/default48.png | Bin 0 -> 4855 bytes
branding/unstable/disk.icns | Bin 0 -> 39250 bytes
branding/unstable/document.icns | Bin 0 -> 12451 bytes
branding/unstable/document.ico | Bin 0 -> 19790 bytes
branding/unstable/dsstore | Bin 0 -> 6148 bytes
branding/unstable/firefox.icns | Bin 0 -> 59809 bytes
branding/unstable/firefox.ico | Bin 0 -> 100371 bytes
branding/unstable/locales/en-US/brand.dtd | 4 +
branding/unstable/locales/en-US/brand.properties | 5 +
branding/unstable/locales/jar.mn | 12 +
branding/unstable/locales/moz.build | 9 +
branding/unstable/moz.build | 13 +
branding/unstable/mozicon128.png | Bin 0 -> 24891 bytes
.../unstable/palemoon.VisualElementsManifest.xml | 8 +
branding/unstable/pref/palemoon-branding.js | 46 +
branding/unstable/wizHeader.bmp | Bin 0 -> 25818 bytes
branding/unstable/wizHeaderRTL.bmp | Bin 0 -> 25818 bytes
branding/unstable/wizWatermark.bmp | Bin 0 -> 154542 bytes
build.mk | 57 +
components/BrowserComponents.manifest | 64 +
components/abouthome/aboutHome.css | 343 +
components/abouthome/aboutHome.js | 227 +
components/abouthome/aboutHome.xhtml | 62 +
components/abouthome/addons.png | Bin 0 -> 1444 bytes
components/abouthome/addons@2x.png | Bin 0 -> 3783 bytes
components/abouthome/bookmarks.png | Bin 0 -> 1276 bytes
components/abouthome/bookmarks@2x.png | Bin 0 -> 2946 bytes
components/abouthome/downloads.png | Bin 0 -> 898 bytes
components/abouthome/downloads@2x.png | Bin 0 -> 2018 bytes
components/abouthome/history.png | Bin 0 -> 1654 bytes
components/abouthome/history@2x.png | Bin 0 -> 4629 bytes
components/abouthome/jar.mn | 33 +
components/abouthome/moz.build | 8 +
components/abouthome/noise.png | Bin 0 -> 4025 bytes
components/abouthome/restore-large.png | Bin 0 -> 2841 bytes
components/abouthome/restore-large@2x.png | Bin 0 -> 7267 bytes
components/abouthome/restore.png | Bin 0 -> 1796 bytes
components/abouthome/restore@2x.png | Bin 0 -> 4810 bytes
components/abouthome/settings.png | Bin 0 -> 1557 bytes
components/abouthome/settings@2x.png | Bin 0 -> 3836 bytes
components/abouthome/snippet1.png | Bin 0 -> 1470 bytes
components/abouthome/snippet1@2x.png | Bin 0 -> 3243 bytes
components/abouthome/snippet2.png | Bin 0 -> 3287 bytes
components/abouthome/snippet2@2x.png | Bin 0 -> 11027 bytes
components/abouthome/sync.png | Bin 0 -> 1879 bytes
components/abouthome/sync@2x.png | Bin 0 -> 4615 bytes
components/build/Makefile.in | 8 +
components/build/moz.build | 36 +
components/build/nsBrowserCompsCID.h | 31 +
components/build/nsModule.cpp | 91 +
components/certerror/content/aboutCertError.css | 17 +
components/certerror/content/aboutCertError.xhtml | 247 +
components/certerror/jar.mn | 7 +
components/certerror/moz.build | 7 +
components/dirprovider/DirectoryProvider.cpp | 268 +
components/dirprovider/DirectoryProvider.h | 51 +
components/dirprovider/moz.build | 13 +
components/distribution.js | 345 +
components/downloads/BrowserDownloads.manifest | 4 +
components/downloads/DownloadsCommon.jsm | 1920 +++++
components/downloads/DownloadsLogger.jsm | 76 +
components/downloads/DownloadsStartup.js | 278 +
components/downloads/DownloadsTaskbar.jsm | 177 +
components/downloads/DownloadsUI.js | 151 +
components/downloads/DownloadsViewUI.jsm | 250 +
.../downloads/content/allDownloadsViewOverlay.css | 56 +
.../downloads/content/allDownloadsViewOverlay.js | 1399 ++++
.../downloads/content/allDownloadsViewOverlay.xul | 119 +
.../downloads/content/contentAreaDownloadsView.css | 11 +
.../downloads/content/contentAreaDownloadsView.js | 15 +
.../downloads/content/contentAreaDownloadsView.xul | 45 +
components/downloads/content/download.css | 45 +
components/downloads/content/download.xml | 188 +
components/downloads/content/downloads.css | 132 +
components/downloads/content/downloads.js | 1614 +++++
components/downloads/content/downloadsOverlay.xul | 142 +
components/downloads/content/indicator.js | 609 ++
components/downloads/content/indicatorOverlay.xul | 60 +
components/downloads/jar.mn | 18 +
components/downloads/moz.build | 23 +
components/feeds/BrowserFeeds.manifest | 28 +
components/feeds/FeedConverter.js | 591 ++
components/feeds/FeedWriter.js | 1397 ++++
components/feeds/WebContentConverter.js | 927 +++
components/feeds/content/subscribe.css | 7 +
components/feeds/content/subscribe.js | 23 +
components/feeds/content/subscribe.xhtml | 65 +
components/feeds/content/subscribe.xml | 40 +
components/feeds/jar.mn | 9 +
components/feeds/moz.build | 33 +
components/feeds/nsFeedSniffer.cpp | 363 +
components/feeds/nsFeedSniffer.h | 37 +
components/feeds/nsIFeedResultService.idl | 66 +
.../feeds/nsIWebContentConverterRegistrar.idl | 117 +
components/fuel/fuelApplication.js | 822 +++
components/fuel/fuelApplication.manifest | 3 +
components/fuel/fuelIApplication.idl | 347 +
components/fuel/moz.build | 14 +
components/moz.build | 47 +
components/newtab/cells.js | 126 +
components/newtab/drag.js | 151 +
components/newtab/dragDataHelper.js | 22 +
components/newtab/drop.js | 150 +
components/newtab/dropPreview.js | 222 +
components/newtab/dropTargetShim.js | 232 +
components/newtab/grid.js | 175 +
components/newtab/jar.mn | 8 +
components/newtab/moz.build | 8 +
components/newtab/newTab.css | 349 +
components/newtab/newTab.js | 69 +
components/newtab/newTab.xhtml | 61 +
components/newtab/page.js | 244 +
components/newtab/search.js | 134 +
components/newtab/sites.js | 353 +
components/newtab/transformations.js | 270 +
components/newtab/undo.js | 116 +
components/newtab/updater.js | 177 +
components/nsAboutRedirector.js | 114 +
components/nsBrowserContentHandler.js | 803 +++
components/nsBrowserGlue.js | 2055 ++++++
components/nsIBrowserGlue.idl | 47 +
components/nsIBrowserHandler.idl | 20 +
components/pageinfo/feeds.js | 59 +
components/pageinfo/feeds.xml | 40 +
components/pageinfo/jar.mn | 13 +
components/pageinfo/moz.build | 8 +
components/pageinfo/pageInfo.css | 26 +
components/pageinfo/pageInfo.js | 1286 ++++
components/pageinfo/pageInfo.xml | 29 +
components/pageinfo/pageInfo.xul | 507 ++
components/pageinfo/permissions.js | 341 +
components/pageinfo/security.js | 378 +
components/permissions/aboutPermissions.css | 11 +
components/permissions/aboutPermissions.js | 1335 ++++
components/permissions/aboutPermissions.xml | 113 +
components/permissions/aboutPermissions.xul | 313 +
components/permissions/jar.mn | 9 +
components/permissions/moz.build | 7 +
components/places/PlacesUIUtils.jsm | 1373 ++++
components/places/content/bookmarkProperties.js | 675 ++
components/places/content/bookmarkProperties.xul | 43 +
components/places/content/bookmarksPanel.js | 25 +
components/places/content/bookmarksPanel.xul | 55 +
components/places/content/browserPlacesViews.js | 1754 +++++
components/places/content/controller.js | 1895 +++++
components/places/content/downloadsViewOverlay.xul | 47 +
components/places/content/editBookmarkOverlay.js | 1063 +++
components/places/content/editBookmarkOverlay.xul | 228 +
components/places/content/history-panel.js | 91 +
components/places/content/history-panel.xul | 95 +
components/places/content/menu.xml | 488 ++
components/places/content/moveBookmarks.js | 54 +
components/places/content/moveBookmarks.xul | 53 +
components/places/content/organizer.css | 7 +
components/places/content/places.css | 16 +
components/places/content/places.js | 1553 ++++
components/places/content/places.xul | 471 ++
components/places/content/placesOverlay.xul | 247 +
components/places/content/sidebarUtils.js | 108 +
components/places/content/tree.xml | 789 +++
components/places/content/treeView.js | 1770 +++++
components/places/jar.mn | 34 +
components/places/moz.build | 9 +
components/preferences/advanced.js | 755 ++
components/preferences/advanced.xul | 465 ++
components/preferences/applicationManager.js | 102 +
components/preferences/applicationManager.xul | 59 +
components/preferences/applications.js | 1890 +++++
components/preferences/applications.xul | 99 +
components/preferences/colors.xul | 102 +
components/preferences/connection.js | 200 +
components/preferences/connection.xul | 164 +
components/preferences/content.js | 187 +
components/preferences/content.xul | 171 +
components/preferences/cookies.js | 948 +++
components/preferences/cookies.xul | 106 +
components/preferences/fonts.js | 144 +
components/preferences/fonts.xul | 279 +
components/preferences/handlers.css | 25 +
components/preferences/handlers.xml | 81 +
components/preferences/jar.mn | 44 +
components/preferences/languages.js | 304 +
components/preferences/languages.xul | 98 +
components/preferences/main.js | 473 ++
components/preferences/main.xul | 188 +
components/preferences/moz.build | 14 +
components/preferences/newtaburl.js | 102 +
components/preferences/permissions.js | 463 ++
components/preferences/permissions.xul | 85 +
components/preferences/preferences.xul | 92 +
components/preferences/privacy.js | 485 ++
components/preferences/privacy.xul | 273 +
components/preferences/sanitize.js | 12 +
components/preferences/sanitize.xul | 108 +
components/preferences/security.js | 263 +
components/preferences/security.xul | 184 +
components/preferences/selectBookmark.js | 83 +
components/preferences/selectBookmark.xul | 44 +
components/preferences/sync.js | 192 +
components/preferences/sync.xul | 178 +
components/preferences/tabs.js | 90 +
components/preferences/tabs.xul | 102 +
.../content/aboutPrivateBrowsing.xhtml | 156 +
components/privatebrowsing/jar.mn | 6 +
components/privatebrowsing/moz.build | 7 +
components/search/content/engineManager.js | 492 ++
components/search/content/engineManager.xul | 93 +
components/search/content/search.xml | 837 +++
components/search/content/searchbarBindings.css | 13 +
components/search/jar.mn | 9 +
components/search/moz.build | 7 +
components/sessionstore/DocumentUtils.jsm | 230 +
components/sessionstore/SessionStorage.jsm | 165 +
components/sessionstore/SessionStore.jsm | 4786 +++++++++++++
components/sessionstore/XPathGenerator.jsm | 97 +
components/sessionstore/_SessionFile.jsm | 314 +
.../sessionstore/content/aboutSessionRestore.js | 320 +
.../sessionstore/content/aboutSessionRestore.xhtml | 94 +
.../sessionstore/content/content-sessionStore.js | 40 +
components/sessionstore/jar.mn | 8 +
components/sessionstore/moz.build | 29 +
components/sessionstore/nsISessionStartup.idl | 59 +
components/sessionstore/nsISessionStore.idl | 206 +
components/sessionstore/nsSessionStartup.js | 296 +
components/sessionstore/nsSessionStore.js | 37 +
components/sessionstore/nsSessionStore.manifest | 18 +
components/shell/ShellService.jsm | 114 +
components/shell/content/setDesktopBackground.js | 214 +
components/shell/content/setDesktopBackground.xul | 84 +
components/shell/jar.mn | 7 +
components/shell/moz.build | 40 +
components/shell/nsGNOMEShellService.cpp | 637 ++
components/shell/nsGNOMEShellService.h | 36 +
components/shell/nsIGNOMEShellService.idl | 19 +
components/shell/nsIMacShellService.idl | 15 +
components/shell/nsIShellService.idl | 95 +
components/shell/nsIWindowsShellService.idl | 17 +
components/shell/nsMacShellService.cpp | 434 ++
components/shell/nsMacShellService.h | 32 +
components/shell/nsSetDefaultBrowser.js | 30 +
components/shell/nsSetDefaultBrowser.manifest | 3 +
components/shell/nsShellService.h | 12 +
components/shell/nsWindowsShellService.cpp | 1277 ++++
components/shell/nsWindowsShellService.h | 37 +
components/statusbar/Downloads.jsm | 674 ++
components/statusbar/Progress.jsm | 183 +
components/statusbar/Status.jsm | 456 ++
components/statusbar/Status4Evar.jsm | 312 +
components/statusbar/Toolbars.jsm | 221 +
components/statusbar/content-thunk.js | 23 +
components/statusbar/content/overlay.css | 14 +
components/statusbar/content/overlay.js | 16 +
components/statusbar/content/overlay.xul | 82 +
components/statusbar/content/prefs.css | 10 +
components/statusbar/content/prefs.js | 274 +
components/statusbar/content/prefs.xml | 704 ++
components/statusbar/content/prefs.xul | 297 +
components/statusbar/content/tabbrowser.xml | 218 +
components/statusbar/jar.mn | 15 +
components/statusbar/moz.build | 25 +
components/statusbar/status4evar.idl | 57 +
components/statusbar/status4evar.js | 695 ++
components/statusbar/status4evar.manifest | 3 +
components/sync/aboutSyncTabs-bindings.xml | 46 +
components/sync/aboutSyncTabs.css | 11 +
components/sync/aboutSyncTabs.js | 313 +
components/sync/aboutSyncTabs.xul | 68 +
components/sync/addDevice.js | 157 +
components/sync/addDevice.xul | 129 +
components/sync/genericChange.js | 234 +
components/sync/genericChange.xul | 123 +
components/sync/jar.mn | 22 +
components/sync/key.xhtml | 54 +
components/sync/moz.build | 8 +
components/sync/notification.xml | 129 +
components/sync/progress.js | 71 +
components/sync/progress.xhtml | 55 +
components/sync/quota.js | 247 +
components/sync/quota.xul | 65 +
components/sync/setup.js | 1071 +++
components/sync/setup.xul | 491 ++
components/sync/utils.js | 218 +
config/mozconfig | 9 +
config/mozconfigs/common | 7 +
config/mozconfigs/linux32/beta | 7 +
config/mozconfigs/linux32/common-opt | 19 +
config/mozconfigs/linux32/debug | 22 +
config/mozconfigs/linux32/debug-asan | 20 +
config/mozconfigs/linux32/l10n-mozconfig | 12 +
config/mozconfigs/linux32/release | 13 +
config/mozconfigs/linux32/valgrind | 11 +
config/mozconfigs/linux64/beta | 7 +
config/mozconfigs/linux64/common-opt | 19 +
config/mozconfigs/linux64/debug | 22 +
config/mozconfigs/linux64/debug-asan | 20 +
.../mozconfigs/linux64/debug-static-analysis-clang | 15 +
config/mozconfigs/linux64/l10n-mozconfig | 12 +
config/mozconfigs/linux64/release | 13 +
config/mozconfigs/linux64/valgrind | 11 +
config/mozconfigs/macosx-universal/beta | 5 +
config/mozconfigs/macosx-universal/common-opt | 19 +
config/mozconfigs/macosx-universal/l10n-mozconfig | 11 +
config/mozconfigs/macosx-universal/release | 11 +
config/mozconfigs/macosx64/debug | 19 +
config/mozconfigs/macosx64/debug-asan | 16 +
config/mozconfigs/macosx64/l10n-mozconfig | 8 +
config/mozconfigs/win32/beta | 7 +
config/mozconfigs/win32/common-opt | 33 +
config/mozconfigs/win32/debug | 26 +
config/mozconfigs/win32/l10n-mozconfig | 16 +
config/mozconfigs/win32/release | 13 +
config/mozconfigs/win64/debug | 22 +
config/mozconfigs/win64/nightly | 26 +
config/tooltool-manifests/linux32/clang.manifest | 17 +
config/tooltool-manifests/linux32/releng.manifest | 1 +
config/tooltool-manifests/linux64/clang.manifest | 17 +
config/tooltool-manifests/linux64/releng.manifest | 1 +
config/tooltool-manifests/macosx64/releng.manifest | 17 +
config/version.txt | 1 +
configure.in | 37 +
confvars.sh | 104 +
defs.mk | 1 +
fonts/README.txt | 9 +
fonts/TwemojiMozilla.ttf | Bin 0 -> 1158828 bytes
fonts/moz.build | 9 +
installer/Makefile.in | 189 +
installer/moz.build | 6 +
installer/package-manifest.in | 337 +
installer/removed-files.in | 116 +
installer/windows/Makefile.in | 69 +
installer/windows/app.tag | 4 +
installer/windows/moz.build | 15 +
installer/windows/nsis/defines.nsi.in | 65 +
installer/windows/nsis/installer.nsi | 1162 +++
installer/windows/nsis/shared.nsh | 1306 ++++
installer/windows/nsis/uninstaller.nsi | 557 ++
installer/windows/nsis/updater_append.ini | 12 +
locales/Makefile.in | 222 +
locales/all-locales | 97 +
.../en-US/chrome/browser-region/region.properties | 38 +
locales/en-US/chrome/browser/aboutCertError.dtd | 40 +
locales/en-US/chrome/browser/aboutDialog.dtd | 91 +
locales/en-US/chrome/browser/aboutHome.dtd | 26 +
.../en-US/chrome/browser/aboutPrivateBrowsing.dtd | 21 +
.../en-US/chrome/browser/aboutSessionRestore.dtd | 23 +
locales/en-US/chrome/browser/aboutSyncTabs.dtd | 21 +
locales/en-US/chrome/browser/baseMenuOverlay.dtd | 45 +
locales/en-US/chrome/browser/browser.dtd | 608 ++
locales/en-US/chrome/browser/browser.properties | 420 ++
locales/en-US/chrome/browser/charsetMenu.dtd | 18 +
.../en-US/chrome/browser/charsetMenu.properties | 103 +
locales/en-US/chrome/browser/charsetOverlay.dtd | 23 +
.../en-US/chrome/browser/downloads/downloads.dtd | 96 +
.../chrome/browser/downloads/downloads.properties | 78 +
locales/en-US/chrome/browser/engineManager.dtd | 29 +
.../en-US/chrome/browser/engineManager.properties | 9 +
locales/en-US/chrome/browser/feeds/subscribe.dtd | 10 +
.../chrome/browser/feeds/subscribe.properties | 53 +
locales/en-US/chrome/browser/newTab.dtd | 11 +
locales/en-US/chrome/browser/newTab.properties | 7 +
locales/en-US/chrome/browser/openLocation.dtd | 14 +
.../en-US/chrome/browser/openLocation.properties | 5 +
locales/en-US/chrome/browser/pageInfo.dtd | 92 +
locales/en-US/chrome/browser/pageInfo.properties | 56 +
locales/en-US/chrome/browser/palemoon.dtd | 15 +
.../browser/permissions/aboutPermissions.dtd | 50 +
.../permissions/aboutPermissions.properties | 14 +
.../browser/places/bookmarkProperties.properties | 19 +
.../chrome/browser/places/editBookmarkOverlay.dtd | 28 +
.../en-US/chrome/browser/places/moveBookmarks.dtd | 9 +
locales/en-US/chrome/browser/places/places.dtd | 140 +
.../en-US/chrome/browser/places/places.properties | 95 +
.../en-US/chrome/browser/preferences/advanced.dtd | 151 +
.../browser/preferences/applicationManager.dtd | 8 +
.../preferences/applicationManager.properties | 14 +
.../chrome/browser/preferences/applications.dtd | 14 +
.../en-US/chrome/browser/preferences/colors.dtd | 30 +
.../chrome/browser/preferences/connection.dtd | 49 +
.../en-US/chrome/browser/preferences/content.dtd | 41 +
.../en-US/chrome/browser/preferences/cookies.dtd | 27 +
locales/en-US/chrome/browser/preferences/fonts.dtd | 107 +
.../en-US/chrome/browser/preferences/languages.dtd | 19 +
locales/en-US/chrome/browser/preferences/main.dtd | 44 +
.../chrome/browser/preferences/permissions.dtd | 28 +
.../chrome/browser/preferences/preferences.dtd | 23 +
.../browser/preferences/preferences.properties | 153 +
.../en-US/chrome/browser/preferences/privacy.dtd | 83 +
.../en-US/chrome/browser/preferences/security.dtd | 49 +
.../chrome/browser/preferences/selectBookmark.dtd | 9 +
locales/en-US/chrome/browser/preferences/sync.dtd | 47 +
locales/en-US/chrome/browser/preferences/tabs.dtd | 36 +
locales/en-US/chrome/browser/quitDialog.properties | 13 +
locales/en-US/chrome/browser/safeMode.dtd | 27 +
locales/en-US/chrome/browser/sanitize.dtd | 64 +
locales/en-US/chrome/browser/search.properties | 18 +
locales/en-US/chrome/browser/searchbar.dtd | 6 +
.../en-US/chrome/browser/setDesktopBackground.dtd | 15 +
.../en-US/chrome/browser/shellservice.properties | 13 +
.../en-US/chrome/browser/statusbar/meta.properties | 9 +
.../chrome/browser/statusbar/overlay.properties | 17 +
.../chrome/browser/statusbar/prefs.properties | 4 +
.../chrome/browser/statusbar/statusbar-overlay.dtd | 10 +
.../chrome/browser/statusbar/statusbar-prefs.dtd | 99 +
locales/en-US/chrome/browser/syncBrand.dtd | 6 +
.../chrome/browser/syncGenericChange.properties | 37 +
locales/en-US/chrome/browser/syncKey.dtd | 18 +
locales/en-US/chrome/browser/syncProgress.dtd | 15 +
locales/en-US/chrome/browser/syncQuota.dtd | 8 +
locales/en-US/chrome/browser/syncQuota.properties | 42 +
locales/en-US/chrome/browser/syncSetup.dtd | 116 +
locales/en-US/chrome/browser/syncSetup.properties | 51 +
locales/en-US/chrome/browser/tabbrowser.dtd | 6 +
locales/en-US/chrome/browser/tabbrowser.properties | 30 +
locales/en-US/chrome/browser/taskbar.properties | 12 +
.../en-US/chrome/overrides/appstrings.properties | 37 +
locales/en-US/chrome/overrides/netError.dtd | 254 +
locales/en-US/chrome/overrides/settingsChange.dtd | 7 +
.../en-US/crashreporter/crashreporter-override.ini | 9 +
locales/en-US/defines.inc | 12 +
locales/en-US/installer/custom.properties | 85 +
locales/en-US/installer/mui.properties | 61 +
locales/en-US/installer/override.properties | 86 +
locales/en-US/palemoon-l10n.js | 7 +
locales/en-US/profile/bookmarks.inc | 40 +
.../en-US/profile/chrome/userChrome-example.css | 50 +
.../en-US/profile/chrome/userContent-example.css | 32 +
locales/en-US/searchplugins/amazondotcom.xml | 15 +
locales/en-US/searchplugins/answers.xml | 16 +
locales/en-US/searchplugins/bing.xml | 18 +
locales/en-US/searchplugins/creativecommons.xml | 14 +
.../en-US/searchplugins/duckduckgo-palemoon.xml | 16 +
locales/en-US/searchplugins/eBay.xml | 19 +
locales/en-US/searchplugins/ecosia.xml | 12 +
locales/en-US/searchplugins/list.txt | 6 +
locales/en-US/searchplugins/twitter.xml | 15 +
locales/en-US/searchplugins/wikipedia.xml | 18 +
locales/en-US/searchplugins/yahoo.xml | 17 +
locales/en-US/updater/updater.ini | 10 +
locales/filter.py | 37 +
locales/generic/extract-bookmarks.py | 62 +
locales/generic/profile/bookmarks.html.in | 19 +
locales/generic/profile/localstore.rdf | 9 +
locales/generic/profile/mimeTypes.rdf | 17 +
locales/jar.mn | 97 +
locales/l10n.ini | 22 +
locales/moz.build | 7 +
locales/shipped-locales | 90 +
modules/AboutHomeUtils.jsm | 67 +
modules/AutoCompletePopup.jsm | 293 +
modules/BrowserNewTabPreloader.jsm | 436 ++
modules/CharsetMenu.jsm | 160 +
modules/FormSubmitObserver.jsm | 235 +
modules/FormValidationHandler.jsm | 157 +
modules/NetworkPrioritizer.jsm | 179 +
modules/PageMenu.jsm | 238 +
modules/PopupNotifications.jsm | 994 +++
modules/QuotaManager.jsm | 51 +
modules/RecentWindow.jsm | 68 +
modules/SharedFrame.jsm | 221 +
modules/Windows8WindowFrameColor.jsm | 53 +
modules/WindowsJumpLists.jsm | 581 ++
modules/WindowsPreviewPerTab.jsm | 861 +++
modules/moz.build | 42 +
modules/offlineAppCache.jsm | 20 +
modules/openLocationLastURL.jsm | 85 +
modules/webrtcUI.jsm | 292 +
moz.build | 24 +
moz.configure | 7 +
mozconfig.example | 42 +
themes/LICENSE | 2 +
themes/linux/Geolocation-16.png | Bin 0 -> 606 bytes
themes/linux/Geolocation-64.png | Bin 0 -> 8056 bytes
themes/linux/Go-arrow.png | Bin 0 -> 573 bytes
themes/linux/Info.png | Bin 0 -> 767 bytes
themes/linux/KUI-close.png | Bin 0 -> 393 bytes
themes/linux/Makefile.in | 8 +
themes/linux/Privacy-16.png | Bin 0 -> 822 bytes
themes/linux/Privacy-32.png | Bin 0 -> 2085 bytes
themes/linux/Privacy-48.png | Bin 0 -> 3422 bytes
themes/linux/Privacy-64.png | Bin 0 -> 4828 bytes
themes/linux/Secure.png | Bin 0 -> 865 bytes
themes/linux/Security-broken.png | Bin 0 -> 928 bytes
themes/linux/Toolbar-small.png | Bin 0 -> 5429 bytes
themes/linux/Toolbar.png | Bin 0 -> 8925 bytes
themes/linux/aboutCertError.css | 73 +
.../linux/aboutCertError_sectionCollapsed-rtl.png | Bin 0 -> 791 bytes
themes/linux/aboutCertError_sectionCollapsed.png | Bin 0 -> 776 bytes
themes/linux/aboutCertError_sectionExpanded.png | Bin 0 -> 767 bytes
themes/linux/aboutPrivateBrowsing.css | 47 +
themes/linux/aboutSessionRestore-window-icon.png | Bin 0 -> 405 bytes
themes/linux/aboutSessionRestore.css | 90 +
themes/linux/aboutSyncTabs.css | 101 +
themes/linux/actionicon-tab.png | Bin 0 -> 236 bytes
themes/linux/autocomplete.css | 210 +
themes/linux/browser.css | 2210 ++++++
themes/linux/click-to-play-warning-stripes.png | Bin 0 -> 1563 bytes
themes/linux/communicator/communicator.css | 6 +
themes/linux/communicator/jar.mn | 7 +
themes/linux/communicator/moz.build | 7 +
themes/linux/downloads/allDownloadsViewOverlay.css | 125 +
themes/linux/downloads/buttons.png | Bin 0 -> 5091 bytes
.../linux/downloads/contentAreaDownloadsView.css | 11 +
themes/linux/downloads/download-glow-small.png | Bin 0 -> 556 bytes
themes/linux/downloads/download-glow.png | Bin 0 -> 723 bytes
.../downloads/download-notification-finish.png | Bin 0 -> 3626 bytes
.../downloads/download-notification-start.png | Bin 0 -> 3166 bytes
themes/linux/downloads/download-summary.png | Bin 0 -> 691 bytes
themes/linux/downloads/downloads.css | 376 +
themes/linux/engineManager.css | 16 +
themes/linux/feeds/feedIcon.png | Bin 0 -> 1794 bytes
themes/linux/feeds/feedIcon16.png | Bin 0 -> 799 bytes
themes/linux/feeds/subscribe-ui.css | 29 +
themes/linux/feeds/subscribe.css | 163 +
themes/linux/icon.png | Bin 0 -> 2185 bytes
themes/linux/identity-icons-generic.png | Bin 0 -> 965 bytes
themes/linux/identity-icons-https-ev.png | Bin 0 -> 708 bytes
themes/linux/identity-icons-https-mixed-active.png | Bin 0 -> 984 bytes
themes/linux/identity-icons-https.png | Bin 0 -> 672 bytes
themes/linux/identity.png | Bin 0 -> 9690 bytes
themes/linux/imagedocument.png | Bin 0 -> 2185 bytes
themes/linux/jar.mn | 142 +
themes/linux/mixed-content-blocked-16.png | Bin 0 -> 346 bytes
themes/linux/mixed-content-blocked-64.png | Bin 0 -> 2063 bytes
themes/linux/monitor.png | Bin 0 -> 6217 bytes
themes/linux/monitor_16-10.png | Bin 0 -> 6787 bytes
themes/linux/moz.build | 9 +
themes/linux/newtab/newTab.css | 27 +
themes/linux/page-livemarks.png | Bin 0 -> 799 bytes
themes/linux/pageInfo.css | 276 +
themes/linux/pageInfo.png | Bin 0 -> 8849 bytes
themes/linux/permissions/aboutPermissions.css | 149 +
themes/linux/places/bookmarksMenu.png | Bin 0 -> 461 bytes
themes/linux/places/bookmarksToolbar.png | Bin 0 -> 508 bytes
themes/linux/places/calendar.png | Bin 0 -> 670 bytes
themes/linux/places/downloads.png | Bin 0 -> 599 bytes
themes/linux/places/editBookmarkOverlay.css | 71 +
themes/linux/places/livemark-item.png | Bin 0 -> 863 bytes
themes/linux/places/organizer.css | 107 +
themes/linux/places/organizer.xml | 21 +
themes/linux/places/pageStarred.png | Bin 0 -> 767 bytes
themes/linux/places/places.css | 221 +
themes/linux/places/query.png | Bin 0 -> 678 bytes
themes/linux/places/star-icons.png | Bin 0 -> 1106 bytes
themes/linux/places/starPage.png | Bin 0 -> 723 bytes
themes/linux/places/starred48.png | Bin 0 -> 2658 bytes
themes/linux/places/tag.png | Bin 0 -> 877 bytes
themes/linux/places/toolbarDropMarker.png | Bin 0 -> 583 bytes
themes/linux/places/unsortedBookmarks.png | Bin 0 -> 748 bytes
themes/linux/places/unstarred48.png | Bin 0 -> 2255 bytes
themes/linux/pointerLock-16.png | Bin 0 -> 249 bytes
themes/linux/pointerLock-64.png | Bin 0 -> 1119 bytes
themes/linux/preferences/Options-sync.png | Bin 0 -> 3585 bytes
themes/linux/preferences/Options.png | Bin 0 -> 12680 bytes
themes/linux/preferences/alwaysAsk.png | Bin 0 -> 575 bytes
themes/linux/preferences/applications.css | 66 +
themes/linux/preferences/mail.png | Bin 0 -> 548 bytes
themes/linux/preferences/preferences.css | 156 +
themes/linux/privatebrowsing-mask.png | Bin 0 -> 1355 bytes
themes/linux/sanitizeDialog.css | 107 +
themes/linux/searchbar.css | 72 +
themes/linux/setDesktopBackground.css | 18 +
themes/linux/slowStartup-16.png | Bin 0 -> 478 bytes
themes/linux/statusbar/overlay.css | 114 +
themes/linux/statusbar/prefs.css | 8 +
themes/linux/sync-128.png | Bin 0 -> 20229 bytes
themes/linux/sync-16-throbber.png | Bin 0 -> 10365 bytes
themes/linux/sync-16.png | Bin 0 -> 1847 bytes
themes/linux/sync-24-throbber.png | Bin 0 -> 15774 bytes
themes/linux/sync-32.png | Bin 0 -> 3384 bytes
themes/linux/sync-bg.png | Bin 0 -> 21309 bytes
themes/linux/sync-desktopIcon.png | Bin 0 -> 291 bytes
themes/linux/sync-mobileIcon.png | Bin 0 -> 352 bytes
themes/linux/syncCommon.css | 49 +
themes/linux/syncProgress.css | 46 +
themes/linux/syncQuota.css | 26 +
themes/linux/syncSetup.css | 127 +
themes/linux/tabbrowser/alltabs.png | Bin 0 -> 192 bytes
themes/linux/tabbrowser/connecting.png | Bin 0 -> 8540 bytes
themes/linux/tabbrowser/loading.png | Bin 0 -> 12184 bytes
themes/linux/tabbrowser/tab-overflow-border.png | Bin 0 -> 193 bytes
themes/linux/tabbrowser/tab.png | Bin 0 -> 353 bytes
themes/linux/tabbrowser/tabDragIndicator.png | Bin 0 -> 450 bytes
themes/linux/urlbar-arrow.png | Bin 0 -> 305 bytes
themes/linux/web-notifications-icon.svg | 15 +
themes/linux/web-notifications-tray.svg | 23 +
themes/linux/webRTC-shareDevice-16.png | Bin 0 -> 224 bytes
themes/linux/webRTC-shareDevice-64.png | Bin 0 -> 1097 bytes
themes/linux/webRTC-sharingDevice-16.png | Bin 0 -> 404 bytes
themes/moz.build | 14 +
themes/osx/Geolocation-16.png | Bin 0 -> 704 bytes
themes/osx/Geolocation-64.png | Bin 0 -> 8424 bytes
themes/osx/Info.png | Bin 0 -> 641 bytes
themes/osx/KUI-background.png | Bin 0 -> 222 bytes
themes/osx/KUI-close.png | Bin 0 -> 393 bytes
themes/osx/Makefile.in | 7 +
themes/osx/Privacy-16.png | Bin 0 -> 800 bytes
themes/osx/Privacy-32.png | Bin 0 -> 1995 bytes
themes/osx/Privacy-48.png | Bin 0 -> 3884 bytes
themes/osx/Privacy-64.png | Bin 0 -> 8140 bytes
themes/osx/Search-glass.png | Bin 0 -> 1448 bytes
themes/osx/Secure24.png | Bin 0 -> 1098 bytes
themes/osx/Toolbar-glass.png | Bin 0 -> 18355 bytes
themes/osx/Toolbar-inverted.png | Bin 0 -> 4653 bytes
themes/osx/Toolbar.png | Bin 0 -> 15505 bytes
themes/osx/aboutCertError.css | 73 +
themes/osx/aboutCertError_sectionCollapsed-rtl.png | Bin 0 -> 791 bytes
themes/osx/aboutCertError_sectionCollapsed.png | Bin 0 -> 776 bytes
themes/osx/aboutCertError_sectionExpanded.png | Bin 0 -> 767 bytes
themes/osx/aboutPrivateBrowsing.css | 47 +
themes/osx/aboutSessionRestore.css | 73 +
themes/osx/aboutSyncTabs.css | 101 +
themes/osx/actionicon-tab.png | Bin 0 -> 425 bytes
themes/osx/appmenu-dropmarker.png | Bin 0 -> 262 bytes
themes/osx/appmenu-icons.png | Bin 0 -> 2115 bytes
themes/osx/autocomplete.css | 198 +
themes/osx/browser.css | 2802 ++++++++
themes/osx/click-to-play-warning-stripes.png | Bin 0 -> 1563 bytes
themes/osx/communicator/communicator.css | 6 +
themes/osx/communicator/jar.mn | 7 +
themes/osx/communicator/moz.build | 7 +
themes/osx/downloads/allDownloadsViewOverlay.css | 146 +
themes/osx/downloads/buttons.png | Bin 0 -> 6881 bytes
themes/osx/downloads/contentAreaDownloadsView.css | 22 +
themes/osx/downloads/download-glow.png | Bin 0 -> 546 bytes
.../osx/downloads/download-notification-finish.png | Bin 0 -> 3755 bytes
.../osx/downloads/download-notification-start.png | Bin 0 -> 3166 bytes
themes/osx/downloads/download-summary.png | Bin 0 -> 741 bytes
themes/osx/downloads/downloads.css | 394 ++
themes/osx/engineManager.css | 16 +
themes/osx/feeds/feed-icons-16.png | Bin 0 -> 2187 bytes
themes/osx/feeds/feedIcon.png | Bin 0 -> 1833 bytes
themes/osx/feeds/feedIcon16.png | Bin 0 -> 791 bytes
themes/osx/feeds/subscribe-ui.css | 29 +
themes/osx/feeds/subscribe.css | 159 +
themes/osx/icon.png | Bin 0 -> 2185 bytes
themes/osx/identity-icons-generic.png | Bin 0 -> 965 bytes
themes/osx/identity-icons-https-ev.png | Bin 0 -> 708 bytes
themes/osx/identity-icons-https-mixed-active.png | Bin 0 -> 984 bytes
themes/osx/identity-icons-https.png | Bin 0 -> 672 bytes
themes/osx/identity.png | Bin 0 -> 10508 bytes
themes/osx/imagedocument.png | Bin 0 -> 2185 bytes
themes/osx/jar.mn | 181 +
themes/osx/keyhole-forward-mask.svg | 15 +
themes/osx/livemark-folder.png | Bin 0 -> 680 bytes
themes/osx/menu-back.png | Bin 0 -> 341 bytes
themes/osx/menu-forward.png | Bin 0 -> 343 bytes
themes/osx/mixed-content-blocked-16.png | Bin 0 -> 346 bytes
themes/osx/mixed-content-blocked-64.png | Bin 0 -> 2063 bytes
themes/osx/monitor.png | Bin 0 -> 6217 bytes
themes/osx/monitor_16-10.png | Bin 0 -> 6787 bytes
themes/osx/moz.build | 9 +
themes/osx/newtab/newTab.css | 29 +
themes/osx/page-livemarks.png | Bin 0 -> 683 bytes
themes/osx/page-livemarks@2x.png | Bin 0 -> 1167 bytes
themes/osx/pageInfo.css | 258 +
themes/osx/pageInfo.png | Bin 0 -> 8118 bytes
themes/osx/panel-expander-closed.png | Bin 0 -> 155 bytes
themes/osx/panel-expander-closed@2x.png | Bin 0 -> 362 bytes
themes/osx/panel-expander-open.png | Bin 0 -> 155 bytes
themes/osx/panel-expander-open@2x.png | Bin 0 -> 356 bytes
themes/osx/panel-plus-sign.png | Bin 0 -> 212 bytes
themes/osx/permissions/aboutPermissions.css | 153 +
themes/osx/places/allBookmarks.png | Bin 0 -> 673 bytes
themes/osx/places/bookmark.png | Bin 0 -> 1779 bytes
themes/osx/places/bookmarksMenu.png | Bin 0 -> 353 bytes
themes/osx/places/bookmarksToolbar.png | Bin 0 -> 524 bytes
themes/osx/places/bookmarksToolbar@2x.png | Bin 0 -> 1179 bytes
themes/osx/places/calendar.png | Bin 0 -> 614 bytes
themes/osx/places/downloads.png | Bin 0 -> 678 bytes
themes/osx/places/editBookmark.png | Bin 0 -> 1642 bytes
themes/osx/places/editBookmarkOverlay.css | 105 +
themes/osx/places/expander-closed-active.png | Bin 0 -> 1329 bytes
themes/osx/places/expander-closed.png | Bin 0 -> 837 bytes
themes/osx/places/expander-open-active.png | Bin 0 -> 1329 bytes
themes/osx/places/expander-open.png | Bin 0 -> 818 bytes
themes/osx/places/folderDropArrow.png | Bin 0 -> 201 bytes
themes/osx/places/folderDropArrow@2x.png | Bin 0 -> 443 bytes
themes/osx/places/history.png | Bin 0 -> 843 bytes
themes/osx/places/history@2x.png | Bin 0 -> 1872 bytes
themes/osx/places/libraryToolbar.png | Bin 0 -> 2217 bytes
themes/osx/places/livemark-item.png | Bin 0 -> 863 bytes
themes/osx/places/organizer.css | 134 +
themes/osx/places/places.css | 146 +
themes/osx/places/query.png | Bin 0 -> 549 bytes
themes/osx/places/query@2x.png | Bin 0 -> 1055 bytes
themes/osx/places/starred48.png | Bin 0 -> 1785 bytes
themes/osx/places/tag.png | Bin 0 -> 789 bytes
themes/osx/places/tag@2x.png | Bin 0 -> 1593 bytes
themes/osx/places/toolbarDropMarker.png | Bin 0 -> 302 bytes
themes/osx/places/unfiledBookmarks.png | Bin 0 -> 586 bytes
themes/osx/places/unfiledBookmarks@2x.png | Bin 0 -> 1289 bytes
themes/osx/places/unsortedBookmarks.png | Bin 0 -> 780 bytes
themes/osx/places/unstarred48.png | Bin 0 -> 818 bytes
themes/osx/pointerLock-16.png | Bin 0 -> 249 bytes
themes/osx/pointerLock-64.png | Bin 0 -> 1119 bytes
themes/osx/preferences/Options-sync.png | Bin 0 -> 3585 bytes
themes/osx/preferences/Options.png | Bin 0 -> 9077 bytes
themes/osx/preferences/alwaysAsk.png | Bin 0 -> 446 bytes
themes/osx/preferences/application.png | Bin 0 -> 441 bytes
themes/osx/preferences/applications.css | 64 +
themes/osx/preferences/mail.png | Bin 0 -> 630 bytes
themes/osx/preferences/preferences.css | 142 +
themes/osx/preferences/saveFile.png | Bin 0 -> 791 bytes
themes/osx/privatebrowsing-dark.png | Bin 0 -> 1355 bytes
themes/osx/privatebrowsing-light.png | Bin 0 -> 696 bytes
themes/osx/privatebrowsing-mask.png | Bin 0 -> 1074 bytes
themes/osx/privatebrowsing-mask@2x.png | Bin 0 -> 2639 bytes
themes/osx/reload-stop-go.png | Bin 0 -> 1945 bytes
themes/osx/sanitizeDialog.css | 93 +
themes/osx/searchbar-dropdown-arrow.png | Bin 0 -> 509 bytes
themes/osx/searchbar.css | 79 +
themes/osx/setDesktopBackground.css | 18 +
themes/osx/shared.inc | 6 +
themes/osx/slowStartup-16.png | Bin 0 -> 512 bytes
themes/osx/statusbar/overlay.css | 108 +
themes/osx/statusbar/prefs.css | 13 +
themes/osx/sync-128.png | Bin 0 -> 20229 bytes
themes/osx/sync-16.png | Bin 0 -> 1847 bytes
themes/osx/sync-32.png | Bin 0 -> 3384 bytes
themes/osx/sync-bg.png | Bin 0 -> 21309 bytes
themes/osx/sync-desktopIcon.png | Bin 0 -> 291 bytes
themes/osx/sync-mobileIcon.png | Bin 0 -> 352 bytes
themes/osx/sync-throbber.png | Bin 0 -> 10362 bytes
themes/osx/syncCommon.css | 49 +
themes/osx/syncProgress.css | 46 +
themes/osx/syncQuota.css | 26 +
themes/osx/syncSetup.css | 132 +
themes/osx/tabbrowser/alltabs-inverted.png | Bin 0 -> 469 bytes
themes/osx/tabbrowser/alltabs.png | Bin 0 -> 584 bytes
themes/osx/tabbrowser/connecting.png | Bin 0 -> 8540 bytes
themes/osx/tabbrowser/loading.png | Bin 0 -> 10727 bytes
themes/osx/tabbrowser/newtab-glass.png | Bin 0 -> 398 bytes
themes/osx/tabbrowser/newtab-inverted.png | Bin 0 -> 247 bytes
themes/osx/tabbrowser/newtab.png | Bin 0 -> 237 bytes
themes/osx/tabbrowser/tab-arrow-left-glass.png | Bin 0 -> 331 bytes
themes/osx/tabbrowser/tab-arrow-left-inverted.png | Bin 0 -> 250 bytes
themes/osx/tabbrowser/tab-arrow-left.png | Bin 0 -> 368 bytes
themes/osx/tabbrowser/tab-overflow-border.png | Bin 0 -> 193 bytes
themes/osx/tabbrowser/tabDragIndicator.png | Bin 0 -> 3117 bytes
.../osx/toolbarbutton-dropdown-arrow-inverted.png | Bin 0 -> 221 bytes
themes/osx/toolbarbutton-dropdown-arrow.png | Bin 0 -> 287 bytes
themes/osx/urlbar-arrow.png | Bin 0 -> 305 bytes
themes/osx/urlbar-history-dropmarker.png | Bin 0 -> 480 bytes
themes/osx/urlbar-popup-blocked.png | Bin 0 -> 745 bytes
themes/osx/web-notifications-icon.svg | 15 +
themes/osx/web-notifications-tray.svg | 23 +
themes/osx/webRTC-shareDevice-16.png | Bin 0 -> 233 bytes
themes/osx/webRTC-shareDevice-64.png | Bin 0 -> 1097 bytes
themes/osx/webRTC-sharingDevice-16.png | Bin 0 -> 404 bytes
themes/shared/browser.inc | 8 +
themes/shared/newtab/controls.png | Bin 0 -> 4180 bytes
themes/shared/newtab/newTab.css.inc | 203 +
themes/shared/newtab/noise.png | Bin 0 -> 2118 bytes
themes/shared/newtab/pinned.png | Bin 0 -> 307 bytes
themes/shared/plugin-doorhanger.inc.css | 53 +
themes/shared/plugins/notification-pluginAlert.png | Bin 0 -> 648 bytes
.../shared/plugins/notification-pluginAlert@2x.png | Bin 0 -> 1189 bytes
.../shared/plugins/notification-pluginBlocked.png | Bin 0 -> 968 bytes
.../plugins/notification-pluginBlocked@2x.png | Bin 0 -> 2067 bytes
.../shared/plugins/notification-pluginNormal.png | Bin 0 -> 340 bytes
.../plugins/notification-pluginNormal@2x.png | Bin 0 -> 469 bytes
themes/shared/statusbar/dynamic.css | 25 +
themes/shared/statusbar/overlay.css | 169 +
themes/shared/statusbar/pms16.png | Bin 0 -> 604 bytes
themes/shared/statusbar/pms24.png | Bin 0 -> 774 bytes
themes/shared/statusbar/prefs.css | 38 +
themes/shared/statusbar/pulse.png | Bin 0 -> 2775 bytes
themes/shared/statusbar/throbber-idle.png | Bin 0 -> 713 bytes
themes/shared/statusbar/throbberStatic.png | Bin 0 -> 1736 bytes
themes/shared/tabbrowser/tab-audio-small.svg | 58 +
themes/shared/tabbrowser/tab-audio.svg | 18 +
themes/windows/Geolocation-16.png | Bin 0 -> 704 bytes
themes/windows/Geolocation-64.png | Bin 0 -> 8424 bytes
themes/windows/Info.png | Bin 0 -> 615 bytes
themes/windows/KUI-background.png | Bin 0 -> 222 bytes
themes/windows/KUI-close.png | Bin 0 -> 393 bytes
themes/windows/Makefile.in | 7 +
themes/windows/Privacy-16.png | Bin 0 -> 798 bytes
themes/windows/Privacy-32.png | Bin 0 -> 1997 bytes
themes/windows/Privacy-48.png | Bin 0 -> 3912 bytes
themes/windows/Privacy-64.png | Bin 0 -> 8172 bytes
themes/windows/Push-16.png | Bin 0 -> 704 bytes
themes/windows/Push-64.png | Bin 0 -> 8388 bytes
themes/windows/Secure24.png | Bin 0 -> 1117 bytes
themes/windows/Toolbar-glass.png | Bin 0 -> 18803 bytes
themes/windows/Toolbar-glass.svg | 3218 +++++++++
themes/windows/Toolbar-inverted.png | Bin 0 -> 7101 bytes
themes/windows/Toolbar-inverted.svg | 302 +
themes/windows/Toolbar.png | Bin 0 -> 16015 bytes
themes/windows/Toolbar.svg | 1356 ++++
themes/windows/aboutCertError.css | 73 +
.../aboutCertError_sectionCollapsed-rtl.png | Bin 0 -> 791 bytes
themes/windows/aboutCertError_sectionCollapsed.png | Bin 0 -> 776 bytes
themes/windows/aboutCertError_sectionExpanded.png | Bin 0 -> 767 bytes
themes/windows/aboutPrivateBrowsing.css | 47 +
themes/windows/aboutSessionRestore-window-icon.png | Bin 0 -> 352 bytes
themes/windows/aboutSessionRestore.css | 73 +
themes/windows/aboutSyncTabs.css | 101 +
themes/windows/actionicon-tab.png | Bin 0 -> 425 bytes
themes/windows/appmenu-dropmarker.png | Bin 0 -> 262 bytes
themes/windows/appmenu-icons.png | Bin 0 -> 2115 bytes
themes/windows/autocomplete.css | 238 +
themes/windows/browser.css | 3856 ++++++++++
themes/windows/caption-buttons.svg | 121 +
themes/windows/click-to-play-warning-stripes.png | Bin 0 -> 1563 bytes
themes/windows/communicator/communicator.css | 6 +
themes/windows/communicator/jar.mn | 7 +
themes/windows/communicator/moz.build | 7 +
.../windows/downloads/allDownloadsViewOverlay.css | 178 +
themes/windows/downloads/buttons.png | Bin 0 -> 6881 bytes
.../windows/downloads/contentAreaDownloadsView.css | 22 +
.../downloads/download-notification-finish.png | Bin 0 -> 3755 bytes
.../downloads/download-notification-start.png | Bin 0 -> 3166 bytes
themes/windows/downloads/download-summary.png | Bin 0 -> 741 bytes
themes/windows/downloads/downloads.css | 487 ++
themes/windows/engineManager.css | 16 +
themes/windows/feeds/feed-icons-16.png | Bin 0 -> 2138 bytes
themes/windows/feeds/feedIcon.png | Bin 0 -> 1885 bytes
themes/windows/feeds/feedIcon16.png | Bin 0 -> 787 bytes
themes/windows/feeds/subscribe-ui.css | 29 +
themes/windows/feeds/subscribe.css | 163 +
themes/windows/icon.png | Bin 0 -> 2185 bytes
themes/windows/identity-icons-generic.png | Bin 0 -> 965 bytes
themes/windows/identity-icons-https-ev.png | Bin 0 -> 708 bytes
.../windows/identity-icons-https-mixed-active.png | Bin 0 -> 984 bytes
themes/windows/identity-icons-https.png | Bin 0 -> 672 bytes
themes/windows/identity.png | Bin 0 -> 11844 bytes
themes/windows/imagedocument.png | Bin 0 -> 2185 bytes
themes/windows/jar.mn | 168 +
themes/windows/keyhole-forward-mask.svg | 15 +
themes/windows/livemark-folder.png | Bin 0 -> 626 bytes
themes/windows/menu-back.png | Bin 0 -> 435 bytes
themes/windows/menu-forward.png | Bin 0 -> 434 bytes
themes/windows/mixed-content-blocked-16.png | Bin 0 -> 346 bytes
themes/windows/mixed-content-blocked-64.png | Bin 0 -> 2063 bytes
themes/windows/monitor.png | Bin 0 -> 6217 bytes
themes/windows/monitor_16-10.png | Bin 0 -> 6787 bytes
themes/windows/moz.build | 9 +
themes/windows/newtab/newTab.css | 29 +
themes/windows/pageInfo.css | 268 +
themes/windows/pageInfo.png | Bin 0 -> 8432 bytes
themes/windows/permissions/aboutPermissions.css | 153 +
themes/windows/places/allBookmarks.png | Bin 0 -> 612 bytes
themes/windows/places/bookmark.png | Bin 0 -> 1779 bytes
themes/windows/places/bookmarksMenu.png | Bin 0 -> 346 bytes
themes/windows/places/bookmarksToolbar.png | Bin 0 -> 380 bytes
themes/windows/places/calendar.png | Bin 0 -> 637 bytes
themes/windows/places/downloads.png | Bin 0 -> 674 bytes
themes/windows/places/editBookmark.png | Bin 0 -> 1642 bytes
themes/windows/places/editBookmarkOverlay.css | 80 +
themes/windows/places/history.png | Bin 0 -> 871 bytes
themes/windows/places/libraryToolbar.png | Bin 0 -> 1331 bytes
themes/windows/places/livemark-item.png | Bin 0 -> 863 bytes
themes/windows/places/organizer.css | 253 +
themes/windows/places/places.css | 172 +
themes/windows/places/query.png | Bin 0 -> 602 bytes
themes/windows/places/starred48.png | Bin 0 -> 1911 bytes
themes/windows/places/tag.png | Bin 0 -> 676 bytes
themes/windows/places/toolbarDropMarker.png | Bin 0 -> 223 bytes
themes/windows/places/unsortedBookmarks.png | Bin 0 -> 762 bytes
themes/windows/places/unstarred48.png | Bin 0 -> 818 bytes
themes/windows/pointerLock-16.png | Bin 0 -> 249 bytes
themes/windows/pointerLock-64.png | Bin 0 -> 1119 bytes
themes/windows/preferences/Options-sync.png | Bin 0 -> 3585 bytes
themes/windows/preferences/Options.png | Bin 0 -> 8899 bytes
themes/windows/preferences/alwaysAsk.png | Bin 0 -> 439 bytes
themes/windows/preferences/application.png | Bin 0 -> 419 bytes
themes/windows/preferences/applications.css | 64 +
themes/windows/preferences/mail.png | Bin 0 -> 549 bytes
themes/windows/preferences/preferences.css | 146 +
themes/windows/preferences/saveFile.png | Bin 0 -> 767 bytes
themes/windows/privatebrowsing-dark.png | Bin 0 -> 1355 bytes
themes/windows/privatebrowsing-light.png | Bin 0 -> 696 bytes
themes/windows/reload-stop-go.png | Bin 0 -> 1945 bytes
themes/windows/sanitize.png | Bin 0 -> 779 bytes
themes/windows/sanitizeDialog.css | 93 +
themes/windows/searchbar-dropdown-arrow.png | Bin 0 -> 517 bytes
themes/windows/searchbar.css | 81 +
themes/windows/setDesktopBackground.css | 18 +
themes/windows/slowStartup-16.png | Bin 0 -> 512 bytes
themes/windows/statusbar/overlay.css | 104 +
themes/windows/statusbar/prefs.css | 7 +
themes/windows/sync-128.png | Bin 0 -> 20229 bytes
themes/windows/sync-16.png | Bin 0 -> 1847 bytes
themes/windows/sync-32.png | Bin 0 -> 3384 bytes
themes/windows/sync-bg.png | Bin 0 -> 21309 bytes
themes/windows/sync-desktopIcon.png | Bin 0 -> 291 bytes
themes/windows/sync-mobileIcon.png | Bin 0 -> 352 bytes
themes/windows/sync-throbber.png | Bin 0 -> 10362 bytes
themes/windows/syncCommon.css | 49 +
themes/windows/syncProgress.css | 46 +
themes/windows/syncQuota.css | 26 +
themes/windows/syncSetup.css | 132 +
themes/windows/tabbrowser/alltabs-inverted.png | Bin 0 -> 469 bytes
themes/windows/tabbrowser/alltabs.png | Bin 0 -> 584 bytes
themes/windows/tabbrowser/connecting.png | Bin 0 -> 8540 bytes
themes/windows/tabbrowser/loading.png | Bin 0 -> 10727 bytes
themes/windows/tabbrowser/newtab-glass.png | Bin 0 -> 398 bytes
themes/windows/tabbrowser/newtab-inverted.png | Bin 0 -> 247 bytes
themes/windows/tabbrowser/newtab.png | Bin 0 -> 237 bytes
themes/windows/tabbrowser/tab-arrow-left-glass.png | Bin 0 -> 331 bytes
.../windows/tabbrowser/tab-arrow-left-inverted.png | Bin 0 -> 250 bytes
themes/windows/tabbrowser/tab-arrow-left.png | Bin 0 -> 368 bytes
themes/windows/tabbrowser/tab-overflow-border.png | Bin 0 -> 193 bytes
themes/windows/tabbrowser/tabDragIndicator.png | Bin 0 -> 3117 bytes
.../toolbarbutton-dropdown-arrow-inverted.png | Bin 0 -> 221 bytes
themes/windows/toolbarbutton-dropdown-arrow.png | Bin 0 -> 287 bytes
themes/windows/urlbar-arrow.png | Bin 0 -> 305 bytes
themes/windows/urlbar-history-dropmarker.png | Bin 0 -> 480 bytes
themes/windows/urlbar-popup-blocked.png | Bin 0 -> 745 bytes
themes/windows/web-notifications-icon.svg | 15 +
themes/windows/web-notifications-tray.svg | 23 +
themes/windows/webRTC-shareDevice-16.png | Bin 0 -> 233 bytes
themes/windows/webRTC-shareDevice-64.png | Bin 0 -> 1097 bytes
themes/windows/webRTC-sharingDevice-16.png | Bin 0 -> 404 bytes
1123 files changed, 147741 insertions(+)
create mode 100644 LICENSE
create mode 100644 Makefile.in
create mode 100644 app-rules.mk
create mode 100644 app.mozbuild
create mode 100644 app/Makefile.in
create mode 100644 app/application.ini
create mode 100644 app/blocklist.xml
create mode 100644 app/macbuild/Contents/CodeResources
create mode 100644 app/macbuild/Contents/Info.plist.in
create mode 100644 app/macbuild/Contents/MacOS-files.in
create mode 100644 app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
create mode 100644 app/macbuild/Contents/_CodeSignature/CodeResources
create mode 100644 app/macversion.py
create mode 100644 app/module.ver
create mode 100644 app/moz.build
create mode 100644 app/nsBrowserApp.cpp
create mode 100644 app/palemoon.exe.manifest
create mode 100644 app/permissions
create mode 100644 app/profile/channel-prefs.js
create mode 100644 app/profile/extensions/moz.build
create mode 100644 app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
create mode 100644 app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
create mode 100644 app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
create mode 100644 app/profile/pagethemes.rdf
create mode 100644 app/profile/palemoon.js
create mode 100644 app/profile/prefs.js
create mode 100644 app/splash.rc
create mode 100644 base/content/aboutDialog.css
create mode 100644 base/content/aboutDialog.js
create mode 100644 base/content/aboutDialog.xul
create mode 100644 base/content/autocomplete.css
create mode 100644 base/content/autocomplete.xml
create mode 100644 base/content/autorecovery.js
create mode 100644 base/content/autorecovery.xul
create mode 100644 base/content/baseMenuOverlay.xul
create mode 100644 base/content/browser-addons.js
create mode 100644 base/content/browser-appmenu.inc
create mode 100644 base/content/browser-charsetmenu.inc
create mode 100644 base/content/browser-context.inc
create mode 100644 base/content/browser-devtools-theme.js
create mode 100644 base/content/browser-doctype.inc
create mode 100644 base/content/browser-feeds.js
create mode 100644 base/content/browser-fullScreen.js
create mode 100644 base/content/browser-fullZoom.js
create mode 100644 base/content/browser-gestureSupport.js
create mode 100644 base/content/browser-menubar.inc
create mode 100644 base/content/browser-menudragging.js
create mode 100644 base/content/browser-menudragging.xul
create mode 100644 base/content/browser-places.js
create mode 100644 base/content/browser-plugins.js
create mode 100644 base/content/browser-sets.inc
create mode 100644 base/content/browser-syncui.js
create mode 100644 base/content/browser-tabPreviews.js
create mode 100644 base/content/browser-tabPreviews.xml
create mode 100644 base/content/browser-thumbnails.js
create mode 100644 base/content/browser-title.css
create mode 100644 base/content/browser-uacompat.js
create mode 100644 base/content/browser-webrtcUI.js
create mode 100644 base/content/browser.css
create mode 100644 base/content/browser.js
create mode 100644 base/content/browser.xul
create mode 100644 base/content/browserMountPoints.inc
create mode 100644 base/content/content.js
create mode 100644 base/content/downloadManagerOverlay.xul
create mode 100644 base/content/global-devtools-theme-scripts.inc
create mode 100644 base/content/global-scripts.inc
create mode 100644 base/content/hiddenWindow.xul
create mode 100644 base/content/highlighter.css
create mode 100644 base/content/jsConsoleOverlay.xul
create mode 100644 base/content/macBrowserOverlay.xul
create mode 100644 base/content/nsContextMenu.js
create mode 100644 base/content/openLocation.js
create mode 100644 base/content/openLocation.xul
create mode 100644 base/content/overrides/app-license.html
create mode 100644 base/content/padlock.css
create mode 100644 base/content/padlock.js
create mode 100644 base/content/padlock.xul
create mode 100644 base/content/padlock_classic_broken.png
create mode 100644 base/content/padlock_classic_ev.png
create mode 100644 base/content/padlock_classic_https.png
create mode 100644 base/content/padlock_classic_low.png
create mode 100644 base/content/padlock_mod_broken.png
create mode 100644 base/content/padlock_mod_ev.png
create mode 100644 base/content/padlock_mod_https.png
create mode 100644 base/content/padlock_mod_low.png
create mode 100644 base/content/palemoon.xhtml
create mode 100644 base/content/popup-notifications.inc
create mode 100644 base/content/safeMode.css
create mode 100644 base/content/safeMode.js
create mode 100644 base/content/safeMode.xul
create mode 100644 base/content/sanitize.js
create mode 100644 base/content/sanitize.xul
create mode 100644 base/content/sanitizeDialog.css
create mode 100644 base/content/sanitizeDialog.js
create mode 100644 base/content/softwareUpdateOverlay.xul
create mode 100644 base/content/tabbrowser.css
create mode 100644 base/content/tabbrowser.xml
create mode 100644 base/content/test/general/audio.ogg
create mode 100644 base/content/urlbarBindings.xml
create mode 100644 base/content/utilityOverlay.js
create mode 100644 base/content/viewSourceOverlay.xul
create mode 100644 base/content/web-panels.js
create mode 100644 base/content/web-panels.xul
create mode 100644 base/content/win6BrowserOverlay.xul
create mode 100644 base/jar.mn
create mode 100644 base/moz.build
create mode 100644 branding/official/LICENSE
create mode 100644 branding/official/VisualElements_150.png
create mode 100644 branding/official/VisualElements_70.png
create mode 100644 branding/official/appname.bmp
create mode 100644 branding/official/branding.nsi
create mode 100644 branding/official/configure.sh
create mode 100644 branding/official/content/about-background.jpg
create mode 100644 branding/official/content/about-logo.png
create mode 100644 branding/official/content/about-logo@2x.png
create mode 100644 branding/official/content/about-wordmark.png
create mode 100644 branding/official/content/about-wordmark.svg
create mode 100644 branding/official/content/about.png
create mode 100644 branding/official/content/aboutDialog.css
create mode 100644 branding/official/content/icon48.png
create mode 100644 branding/official/content/icon64.png
create mode 100644 branding/official/content/jar.mn
create mode 100644 branding/official/content/moz.build
create mode 100644 branding/official/default16.png
create mode 100644 branding/official/default22.png
create mode 100644 branding/official/default24.png
create mode 100644 branding/official/default256.png
create mode 100644 branding/official/default32.png
create mode 100644 branding/official/default48.png
create mode 100644 branding/official/disk.icns
create mode 100644 branding/official/document.icns
create mode 100644 branding/official/document.ico
create mode 100644 branding/official/dsstore
create mode 100644 branding/official/firefox.icns
create mode 100644 branding/official/firefox.ico
create mode 100644 branding/official/locales/en-US/brand.dtd
create mode 100644 branding/official/locales/en-US/brand.properties
create mode 100644 branding/official/locales/jar.mn
create mode 100644 branding/official/locales/moz.build
create mode 100644 branding/official/moz.build
create mode 100644 branding/official/mozicon128.png
create mode 100644 branding/official/palemoon.VisualElementsManifest.xml
create mode 100644 branding/official/palemoon.desktop
create mode 100644 branding/official/pref/palemoon-branding.js
create mode 100644 branding/official/wizHeader.bmp
create mode 100644 branding/official/wizHeaderRTL.bmp
create mode 100644 branding/official/wizWatermark.bmp
create mode 100644 branding/shared/background.png
create mode 100644 branding/shared/branding.mozbuild
create mode 100644 branding/shared/locales/browserconfig.properties
create mode 100644 branding/shared/newtab.ico
create mode 100644 branding/shared/newwindow.ico
create mode 100644 branding/shared/pbmode.ico
create mode 100644 branding/shared/pref/preferences.inc
create mode 100644 branding/shared/pref/uaoverrides.inc
create mode 100644 branding/unofficial/VisualElements_150.png
create mode 100644 branding/unofficial/VisualElements_70.png
create mode 100644 branding/unofficial/appname.bmp
create mode 100644 branding/unofficial/branding.nsi
create mode 100644 branding/unofficial/configure.sh
create mode 100644 branding/unofficial/content/about-background.png
create mode 100644 branding/unofficial/content/about-logo.png
create mode 100644 branding/unofficial/content/about-logo@2x.png
create mode 100644 branding/unofficial/content/about.png
create mode 100644 branding/unofficial/content/aboutDialog.css
create mode 100644 branding/unofficial/content/icon48.png
create mode 100644 branding/unofficial/content/icon64.png
create mode 100644 branding/unofficial/content/jar.mn
create mode 100644 branding/unofficial/content/moz.build
create mode 100644 branding/unofficial/default16.png
create mode 100644 branding/unofficial/default32.png
create mode 100644 branding/unofficial/default48.png
create mode 100644 branding/unofficial/disk.icns
create mode 100644 branding/unofficial/document.icns
create mode 100644 branding/unofficial/document.ico
create mode 100644 branding/unofficial/dsstore
create mode 100644 branding/unofficial/firefox.icns
create mode 100644 branding/unofficial/firefox.ico
create mode 100644 branding/unofficial/locales/browserconfig.properties
create mode 100644 branding/unofficial/locales/en-US/brand.dtd
create mode 100644 branding/unofficial/locales/en-US/brand.properties
create mode 100644 branding/unofficial/locales/jar.mn
create mode 100644 branding/unofficial/locales/moz.build
create mode 100644 branding/unofficial/moz.build
create mode 100644 branding/unofficial/mozicon128.png
create mode 100644 branding/unofficial/pref/palemoon-branding.js
create mode 100644 branding/unofficial/webbrowser.VisualElementsManifest.xml
create mode 100644 branding/unofficial/webbrowser.desktop
create mode 100644 branding/unofficial/wizHeader.bmp
create mode 100644 branding/unofficial/wizHeaderRTL.bmp
create mode 100644 branding/unofficial/wizWatermark.bmp
create mode 100644 branding/unstable/VisualElements_150.png
create mode 100644 branding/unstable/VisualElements_70.png
create mode 100644 branding/unstable/appname.bmp
create mode 100644 branding/unstable/branding.nsi
create mode 100644 branding/unstable/configure.sh
create mode 100644 branding/unstable/content/about-background.jpg
create mode 100644 branding/unstable/content/about-logo.png
create mode 100644 branding/unstable/content/about-logo@2x.png
create mode 100644 branding/unstable/content/about-wordmark.png
create mode 100644 branding/unstable/content/about.png
create mode 100644 branding/unstable/content/aboutDialog.css
create mode 100644 branding/unstable/content/icon48.png
create mode 100644 branding/unstable/content/icon64.png
create mode 100644 branding/unstable/content/jar.mn
create mode 100644 branding/unstable/content/moz.build
create mode 100644 branding/unstable/default16.png
create mode 100644 branding/unstable/default32.png
create mode 100644 branding/unstable/default48.png
create mode 100644 branding/unstable/disk.icns
create mode 100644 branding/unstable/document.icns
create mode 100644 branding/unstable/document.ico
create mode 100644 branding/unstable/dsstore
create mode 100644 branding/unstable/firefox.icns
create mode 100644 branding/unstable/firefox.ico
create mode 100644 branding/unstable/locales/en-US/brand.dtd
create mode 100644 branding/unstable/locales/en-US/brand.properties
create mode 100644 branding/unstable/locales/jar.mn
create mode 100644 branding/unstable/locales/moz.build
create mode 100644 branding/unstable/moz.build
create mode 100644 branding/unstable/mozicon128.png
create mode 100644 branding/unstable/palemoon.VisualElementsManifest.xml
create mode 100644 branding/unstable/pref/palemoon-branding.js
create mode 100644 branding/unstable/wizHeader.bmp
create mode 100644 branding/unstable/wizHeaderRTL.bmp
create mode 100644 branding/unstable/wizWatermark.bmp
create mode 100644 build.mk
create mode 100644 components/BrowserComponents.manifest
create mode 100644 components/abouthome/aboutHome.css
create mode 100644 components/abouthome/aboutHome.js
create mode 100644 components/abouthome/aboutHome.xhtml
create mode 100644 components/abouthome/addons.png
create mode 100644 components/abouthome/addons@2x.png
create mode 100644 components/abouthome/bookmarks.png
create mode 100644 components/abouthome/bookmarks@2x.png
create mode 100644 components/abouthome/downloads.png
create mode 100644 components/abouthome/downloads@2x.png
create mode 100644 components/abouthome/history.png
create mode 100644 components/abouthome/history@2x.png
create mode 100644 components/abouthome/jar.mn
create mode 100644 components/abouthome/moz.build
create mode 100644 components/abouthome/noise.png
create mode 100644 components/abouthome/restore-large.png
create mode 100644 components/abouthome/restore-large@2x.png
create mode 100644 components/abouthome/restore.png
create mode 100644 components/abouthome/restore@2x.png
create mode 100644 components/abouthome/settings.png
create mode 100644 components/abouthome/settings@2x.png
create mode 100644 components/abouthome/snippet1.png
create mode 100644 components/abouthome/snippet1@2x.png
create mode 100644 components/abouthome/snippet2.png
create mode 100644 components/abouthome/snippet2@2x.png
create mode 100644 components/abouthome/sync.png
create mode 100644 components/abouthome/sync@2x.png
create mode 100644 components/build/Makefile.in
create mode 100644 components/build/moz.build
create mode 100644 components/build/nsBrowserCompsCID.h
create mode 100644 components/build/nsModule.cpp
create mode 100644 components/certerror/content/aboutCertError.css
create mode 100644 components/certerror/content/aboutCertError.xhtml
create mode 100644 components/certerror/jar.mn
create mode 100644 components/certerror/moz.build
create mode 100644 components/dirprovider/DirectoryProvider.cpp
create mode 100644 components/dirprovider/DirectoryProvider.h
create mode 100644 components/dirprovider/moz.build
create mode 100644 components/distribution.js
create mode 100644 components/downloads/BrowserDownloads.manifest
create mode 100644 components/downloads/DownloadsCommon.jsm
create mode 100644 components/downloads/DownloadsLogger.jsm
create mode 100644 components/downloads/DownloadsStartup.js
create mode 100644 components/downloads/DownloadsTaskbar.jsm
create mode 100644 components/downloads/DownloadsUI.js
create mode 100644 components/downloads/DownloadsViewUI.jsm
create mode 100644 components/downloads/content/allDownloadsViewOverlay.css
create mode 100644 components/downloads/content/allDownloadsViewOverlay.js
create mode 100644 components/downloads/content/allDownloadsViewOverlay.xul
create mode 100644 components/downloads/content/contentAreaDownloadsView.css
create mode 100644 components/downloads/content/contentAreaDownloadsView.js
create mode 100644 components/downloads/content/contentAreaDownloadsView.xul
create mode 100644 components/downloads/content/download.css
create mode 100644 components/downloads/content/download.xml
create mode 100644 components/downloads/content/downloads.css
create mode 100644 components/downloads/content/downloads.js
create mode 100644 components/downloads/content/downloadsOverlay.xul
create mode 100644 components/downloads/content/indicator.js
create mode 100644 components/downloads/content/indicatorOverlay.xul
create mode 100644 components/downloads/jar.mn
create mode 100644 components/downloads/moz.build
create mode 100644 components/feeds/BrowserFeeds.manifest
create mode 100644 components/feeds/FeedConverter.js
create mode 100644 components/feeds/FeedWriter.js
create mode 100644 components/feeds/WebContentConverter.js
create mode 100644 components/feeds/content/subscribe.css
create mode 100644 components/feeds/content/subscribe.js
create mode 100644 components/feeds/content/subscribe.xhtml
create mode 100644 components/feeds/content/subscribe.xml
create mode 100644 components/feeds/jar.mn
create mode 100644 components/feeds/moz.build
create mode 100644 components/feeds/nsFeedSniffer.cpp
create mode 100644 components/feeds/nsFeedSniffer.h
create mode 100644 components/feeds/nsIFeedResultService.idl
create mode 100644 components/feeds/nsIWebContentConverterRegistrar.idl
create mode 100644 components/fuel/fuelApplication.js
create mode 100644 components/fuel/fuelApplication.manifest
create mode 100644 components/fuel/fuelIApplication.idl
create mode 100644 components/fuel/moz.build
create mode 100644 components/moz.build
create mode 100644 components/newtab/cells.js
create mode 100644 components/newtab/drag.js
create mode 100644 components/newtab/dragDataHelper.js
create mode 100644 components/newtab/drop.js
create mode 100644 components/newtab/dropPreview.js
create mode 100644 components/newtab/dropTargetShim.js
create mode 100644 components/newtab/grid.js
create mode 100644 components/newtab/jar.mn
create mode 100644 components/newtab/moz.build
create mode 100644 components/newtab/newTab.css
create mode 100644 components/newtab/newTab.js
create mode 100644 components/newtab/newTab.xhtml
create mode 100644 components/newtab/page.js
create mode 100644 components/newtab/search.js
create mode 100644 components/newtab/sites.js
create mode 100644 components/newtab/transformations.js
create mode 100644 components/newtab/undo.js
create mode 100644 components/newtab/updater.js
create mode 100644 components/nsAboutRedirector.js
create mode 100644 components/nsBrowserContentHandler.js
create mode 100644 components/nsBrowserGlue.js
create mode 100644 components/nsIBrowserGlue.idl
create mode 100644 components/nsIBrowserHandler.idl
create mode 100644 components/pageinfo/feeds.js
create mode 100644 components/pageinfo/feeds.xml
create mode 100644 components/pageinfo/jar.mn
create mode 100644 components/pageinfo/moz.build
create mode 100644 components/pageinfo/pageInfo.css
create mode 100644 components/pageinfo/pageInfo.js
create mode 100644 components/pageinfo/pageInfo.xml
create mode 100644 components/pageinfo/pageInfo.xul
create mode 100644 components/pageinfo/permissions.js
create mode 100644 components/pageinfo/security.js
create mode 100644 components/permissions/aboutPermissions.css
create mode 100644 components/permissions/aboutPermissions.js
create mode 100644 components/permissions/aboutPermissions.xml
create mode 100644 components/permissions/aboutPermissions.xul
create mode 100644 components/permissions/jar.mn
create mode 100644 components/permissions/moz.build
create mode 100644 components/places/PlacesUIUtils.jsm
create mode 100644 components/places/content/bookmarkProperties.js
create mode 100644 components/places/content/bookmarkProperties.xul
create mode 100644 components/places/content/bookmarksPanel.js
create mode 100644 components/places/content/bookmarksPanel.xul
create mode 100644 components/places/content/browserPlacesViews.js
create mode 100644 components/places/content/controller.js
create mode 100644 components/places/content/downloadsViewOverlay.xul
create mode 100644 components/places/content/editBookmarkOverlay.js
create mode 100644 components/places/content/editBookmarkOverlay.xul
create mode 100644 components/places/content/history-panel.js
create mode 100644 components/places/content/history-panel.xul
create mode 100644 components/places/content/menu.xml
create mode 100644 components/places/content/moveBookmarks.js
create mode 100644 components/places/content/moveBookmarks.xul
create mode 100644 components/places/content/organizer.css
create mode 100644 components/places/content/places.css
create mode 100644 components/places/content/places.js
create mode 100644 components/places/content/places.xul
create mode 100644 components/places/content/placesOverlay.xul
create mode 100644 components/places/content/sidebarUtils.js
create mode 100644 components/places/content/tree.xml
create mode 100644 components/places/content/treeView.js
create mode 100644 components/places/jar.mn
create mode 100644 components/places/moz.build
create mode 100644 components/preferences/advanced.js
create mode 100644 components/preferences/advanced.xul
create mode 100644 components/preferences/applicationManager.js
create mode 100644 components/preferences/applicationManager.xul
create mode 100644 components/preferences/applications.js
create mode 100644 components/preferences/applications.xul
create mode 100644 components/preferences/colors.xul
create mode 100644 components/preferences/connection.js
create mode 100644 components/preferences/connection.xul
create mode 100644 components/preferences/content.js
create mode 100644 components/preferences/content.xul
create mode 100644 components/preferences/cookies.js
create mode 100644 components/preferences/cookies.xul
create mode 100644 components/preferences/fonts.js
create mode 100644 components/preferences/fonts.xul
create mode 100644 components/preferences/handlers.css
create mode 100644 components/preferences/handlers.xml
create mode 100644 components/preferences/jar.mn
create mode 100644 components/preferences/languages.js
create mode 100644 components/preferences/languages.xul
create mode 100644 components/preferences/main.js
create mode 100644 components/preferences/main.xul
create mode 100644 components/preferences/moz.build
create mode 100644 components/preferences/newtaburl.js
create mode 100644 components/preferences/permissions.js
create mode 100644 components/preferences/permissions.xul
create mode 100644 components/preferences/preferences.xul
create mode 100644 components/preferences/privacy.js
create mode 100644 components/preferences/privacy.xul
create mode 100644 components/preferences/sanitize.js
create mode 100644 components/preferences/sanitize.xul
create mode 100644 components/preferences/security.js
create mode 100644 components/preferences/security.xul
create mode 100644 components/preferences/selectBookmark.js
create mode 100644 components/preferences/selectBookmark.xul
create mode 100644 components/preferences/sync.js
create mode 100644 components/preferences/sync.xul
create mode 100644 components/preferences/tabs.js
create mode 100644 components/preferences/tabs.xul
create mode 100644 components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
create mode 100644 components/privatebrowsing/jar.mn
create mode 100644 components/privatebrowsing/moz.build
create mode 100644 components/search/content/engineManager.js
create mode 100644 components/search/content/engineManager.xul
create mode 100644 components/search/content/search.xml
create mode 100644 components/search/content/searchbarBindings.css
create mode 100644 components/search/jar.mn
create mode 100644 components/search/moz.build
create mode 100644 components/sessionstore/DocumentUtils.jsm
create mode 100644 components/sessionstore/SessionStorage.jsm
create mode 100644 components/sessionstore/SessionStore.jsm
create mode 100644 components/sessionstore/XPathGenerator.jsm
create mode 100644 components/sessionstore/_SessionFile.jsm
create mode 100644 components/sessionstore/content/aboutSessionRestore.js
create mode 100644 components/sessionstore/content/aboutSessionRestore.xhtml
create mode 100644 components/sessionstore/content/content-sessionStore.js
create mode 100644 components/sessionstore/jar.mn
create mode 100644 components/sessionstore/moz.build
create mode 100644 components/sessionstore/nsISessionStartup.idl
create mode 100644 components/sessionstore/nsISessionStore.idl
create mode 100644 components/sessionstore/nsSessionStartup.js
create mode 100644 components/sessionstore/nsSessionStore.js
create mode 100644 components/sessionstore/nsSessionStore.manifest
create mode 100644 components/shell/ShellService.jsm
create mode 100644 components/shell/content/setDesktopBackground.js
create mode 100644 components/shell/content/setDesktopBackground.xul
create mode 100644 components/shell/jar.mn
create mode 100644 components/shell/moz.build
create mode 100644 components/shell/nsGNOMEShellService.cpp
create mode 100644 components/shell/nsGNOMEShellService.h
create mode 100644 components/shell/nsIGNOMEShellService.idl
create mode 100644 components/shell/nsIMacShellService.idl
create mode 100644 components/shell/nsIShellService.idl
create mode 100644 components/shell/nsIWindowsShellService.idl
create mode 100644 components/shell/nsMacShellService.cpp
create mode 100644 components/shell/nsMacShellService.h
create mode 100644 components/shell/nsSetDefaultBrowser.js
create mode 100644 components/shell/nsSetDefaultBrowser.manifest
create mode 100644 components/shell/nsShellService.h
create mode 100644 components/shell/nsWindowsShellService.cpp
create mode 100644 components/shell/nsWindowsShellService.h
create mode 100644 components/statusbar/Downloads.jsm
create mode 100644 components/statusbar/Progress.jsm
create mode 100644 components/statusbar/Status.jsm
create mode 100644 components/statusbar/Status4Evar.jsm
create mode 100644 components/statusbar/Toolbars.jsm
create mode 100644 components/statusbar/content-thunk.js
create mode 100644 components/statusbar/content/overlay.css
create mode 100644 components/statusbar/content/overlay.js
create mode 100644 components/statusbar/content/overlay.xul
create mode 100644 components/statusbar/content/prefs.css
create mode 100644 components/statusbar/content/prefs.js
create mode 100644 components/statusbar/content/prefs.xml
create mode 100644 components/statusbar/content/prefs.xul
create mode 100644 components/statusbar/content/tabbrowser.xml
create mode 100644 components/statusbar/jar.mn
create mode 100644 components/statusbar/moz.build
create mode 100644 components/statusbar/status4evar.idl
create mode 100644 components/statusbar/status4evar.js
create mode 100644 components/statusbar/status4evar.manifest
create mode 100644 components/sync/aboutSyncTabs-bindings.xml
create mode 100644 components/sync/aboutSyncTabs.css
create mode 100644 components/sync/aboutSyncTabs.js
create mode 100644 components/sync/aboutSyncTabs.xul
create mode 100644 components/sync/addDevice.js
create mode 100644 components/sync/addDevice.xul
create mode 100644 components/sync/genericChange.js
create mode 100644 components/sync/genericChange.xul
create mode 100644 components/sync/jar.mn
create mode 100644 components/sync/key.xhtml
create mode 100644 components/sync/moz.build
create mode 100644 components/sync/notification.xml
create mode 100644 components/sync/progress.js
create mode 100644 components/sync/progress.xhtml
create mode 100644 components/sync/quota.js
create mode 100644 components/sync/quota.xul
create mode 100644 components/sync/setup.js
create mode 100644 components/sync/setup.xul
create mode 100644 components/sync/utils.js
create mode 100644 config/mozconfig
create mode 100644 config/mozconfigs/common
create mode 100644 config/mozconfigs/linux32/beta
create mode 100644 config/mozconfigs/linux32/common-opt
create mode 100644 config/mozconfigs/linux32/debug
create mode 100644 config/mozconfigs/linux32/debug-asan
create mode 100644 config/mozconfigs/linux32/l10n-mozconfig
create mode 100644 config/mozconfigs/linux32/release
create mode 100644 config/mozconfigs/linux32/valgrind
create mode 100644 config/mozconfigs/linux64/beta
create mode 100644 config/mozconfigs/linux64/common-opt
create mode 100644 config/mozconfigs/linux64/debug
create mode 100644 config/mozconfigs/linux64/debug-asan
create mode 100644 config/mozconfigs/linux64/debug-static-analysis-clang
create mode 100644 config/mozconfigs/linux64/l10n-mozconfig
create mode 100644 config/mozconfigs/linux64/release
create mode 100644 config/mozconfigs/linux64/valgrind
create mode 100644 config/mozconfigs/macosx-universal/beta
create mode 100644 config/mozconfigs/macosx-universal/common-opt
create mode 100644 config/mozconfigs/macosx-universal/l10n-mozconfig
create mode 100644 config/mozconfigs/macosx-universal/release
create mode 100644 config/mozconfigs/macosx64/debug
create mode 100644 config/mozconfigs/macosx64/debug-asan
create mode 100644 config/mozconfigs/macosx64/l10n-mozconfig
create mode 100644 config/mozconfigs/win32/beta
create mode 100644 config/mozconfigs/win32/common-opt
create mode 100644 config/mozconfigs/win32/debug
create mode 100644 config/mozconfigs/win32/l10n-mozconfig
create mode 100644 config/mozconfigs/win32/release
create mode 100644 config/mozconfigs/win64/debug
create mode 100644 config/mozconfigs/win64/nightly
create mode 100644 config/tooltool-manifests/linux32/clang.manifest
create mode 100644 config/tooltool-manifests/linux32/releng.manifest
create mode 100644 config/tooltool-manifests/linux64/clang.manifest
create mode 100644 config/tooltool-manifests/linux64/releng.manifest
create mode 100644 config/tooltool-manifests/macosx64/releng.manifest
create mode 100644 config/version.txt
create mode 100644 configure.in
create mode 100644 confvars.sh
create mode 100644 defs.mk
create mode 100644 fonts/README.txt
create mode 100644 fonts/TwemojiMozilla.ttf
create mode 100644 fonts/moz.build
create mode 100644 installer/Makefile.in
create mode 100644 installer/moz.build
create mode 100644 installer/package-manifest.in
create mode 100644 installer/removed-files.in
create mode 100644 installer/windows/Makefile.in
create mode 100644 installer/windows/app.tag
create mode 100644 installer/windows/moz.build
create mode 100644 installer/windows/nsis/defines.nsi.in
create mode 100644 installer/windows/nsis/installer.nsi
create mode 100644 installer/windows/nsis/shared.nsh
create mode 100644 installer/windows/nsis/uninstaller.nsi
create mode 100644 installer/windows/nsis/updater_append.ini
create mode 100644 locales/Makefile.in
create mode 100644 locales/all-locales
create mode 100644 locales/en-US/chrome/browser-region/region.properties
create mode 100644 locales/en-US/chrome/browser/aboutCertError.dtd
create mode 100644 locales/en-US/chrome/browser/aboutDialog.dtd
create mode 100644 locales/en-US/chrome/browser/aboutHome.dtd
create mode 100644 locales/en-US/chrome/browser/aboutPrivateBrowsing.dtd
create mode 100644 locales/en-US/chrome/browser/aboutSessionRestore.dtd
create mode 100644 locales/en-US/chrome/browser/aboutSyncTabs.dtd
create mode 100644 locales/en-US/chrome/browser/baseMenuOverlay.dtd
create mode 100644 locales/en-US/chrome/browser/browser.dtd
create mode 100644 locales/en-US/chrome/browser/browser.properties
create mode 100644 locales/en-US/chrome/browser/charsetMenu.dtd
create mode 100644 locales/en-US/chrome/browser/charsetMenu.properties
create mode 100644 locales/en-US/chrome/browser/charsetOverlay.dtd
create mode 100644 locales/en-US/chrome/browser/downloads/downloads.dtd
create mode 100644 locales/en-US/chrome/browser/downloads/downloads.properties
create mode 100644 locales/en-US/chrome/browser/engineManager.dtd
create mode 100644 locales/en-US/chrome/browser/engineManager.properties
create mode 100644 locales/en-US/chrome/browser/feeds/subscribe.dtd
create mode 100644 locales/en-US/chrome/browser/feeds/subscribe.properties
create mode 100644 locales/en-US/chrome/browser/newTab.dtd
create mode 100644 locales/en-US/chrome/browser/newTab.properties
create mode 100644 locales/en-US/chrome/browser/openLocation.dtd
create mode 100644 locales/en-US/chrome/browser/openLocation.properties
create mode 100644 locales/en-US/chrome/browser/pageInfo.dtd
create mode 100644 locales/en-US/chrome/browser/pageInfo.properties
create mode 100644 locales/en-US/chrome/browser/palemoon.dtd
create mode 100644 locales/en-US/chrome/browser/permissions/aboutPermissions.dtd
create mode 100644 locales/en-US/chrome/browser/permissions/aboutPermissions.properties
create mode 100644 locales/en-US/chrome/browser/places/bookmarkProperties.properties
create mode 100644 locales/en-US/chrome/browser/places/editBookmarkOverlay.dtd
create mode 100644 locales/en-US/chrome/browser/places/moveBookmarks.dtd
create mode 100644 locales/en-US/chrome/browser/places/places.dtd
create mode 100644 locales/en-US/chrome/browser/places/places.properties
create mode 100644 locales/en-US/chrome/browser/preferences/advanced.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/applicationManager.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/applicationManager.properties
create mode 100644 locales/en-US/chrome/browser/preferences/applications.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/colors.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/connection.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/content.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/cookies.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/fonts.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/languages.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/main.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/permissions.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/preferences.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/preferences.properties
create mode 100644 locales/en-US/chrome/browser/preferences/privacy.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/security.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/selectBookmark.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/sync.dtd
create mode 100644 locales/en-US/chrome/browser/preferences/tabs.dtd
create mode 100644 locales/en-US/chrome/browser/quitDialog.properties
create mode 100644 locales/en-US/chrome/browser/safeMode.dtd
create mode 100644 locales/en-US/chrome/browser/sanitize.dtd
create mode 100644 locales/en-US/chrome/browser/search.properties
create mode 100644 locales/en-US/chrome/browser/searchbar.dtd
create mode 100644 locales/en-US/chrome/browser/setDesktopBackground.dtd
create mode 100644 locales/en-US/chrome/browser/shellservice.properties
create mode 100644 locales/en-US/chrome/browser/statusbar/meta.properties
create mode 100644 locales/en-US/chrome/browser/statusbar/overlay.properties
create mode 100644 locales/en-US/chrome/browser/statusbar/prefs.properties
create mode 100644 locales/en-US/chrome/browser/statusbar/statusbar-overlay.dtd
create mode 100644 locales/en-US/chrome/browser/statusbar/statusbar-prefs.dtd
create mode 100644 locales/en-US/chrome/browser/syncBrand.dtd
create mode 100644 locales/en-US/chrome/browser/syncGenericChange.properties
create mode 100644 locales/en-US/chrome/browser/syncKey.dtd
create mode 100644 locales/en-US/chrome/browser/syncProgress.dtd
create mode 100644 locales/en-US/chrome/browser/syncQuota.dtd
create mode 100644 locales/en-US/chrome/browser/syncQuota.properties
create mode 100644 locales/en-US/chrome/browser/syncSetup.dtd
create mode 100644 locales/en-US/chrome/browser/syncSetup.properties
create mode 100644 locales/en-US/chrome/browser/tabbrowser.dtd
create mode 100644 locales/en-US/chrome/browser/tabbrowser.properties
create mode 100644 locales/en-US/chrome/browser/taskbar.properties
create mode 100644 locales/en-US/chrome/overrides/appstrings.properties
create mode 100644 locales/en-US/chrome/overrides/netError.dtd
create mode 100644 locales/en-US/chrome/overrides/settingsChange.dtd
create mode 100644 locales/en-US/crashreporter/crashreporter-override.ini
create mode 100644 locales/en-US/defines.inc
create mode 100644 locales/en-US/installer/custom.properties
create mode 100644 locales/en-US/installer/mui.properties
create mode 100644 locales/en-US/installer/override.properties
create mode 100644 locales/en-US/palemoon-l10n.js
create mode 100644 locales/en-US/profile/bookmarks.inc
create mode 100644 locales/en-US/profile/chrome/userChrome-example.css
create mode 100644 locales/en-US/profile/chrome/userContent-example.css
create mode 100644 locales/en-US/searchplugins/amazondotcom.xml
create mode 100644 locales/en-US/searchplugins/answers.xml
create mode 100644 locales/en-US/searchplugins/bing.xml
create mode 100644 locales/en-US/searchplugins/creativecommons.xml
create mode 100644 locales/en-US/searchplugins/duckduckgo-palemoon.xml
create mode 100644 locales/en-US/searchplugins/eBay.xml
create mode 100644 locales/en-US/searchplugins/ecosia.xml
create mode 100644 locales/en-US/searchplugins/list.txt
create mode 100644 locales/en-US/searchplugins/twitter.xml
create mode 100644 locales/en-US/searchplugins/wikipedia.xml
create mode 100644 locales/en-US/searchplugins/yahoo.xml
create mode 100644 locales/en-US/updater/updater.ini
create mode 100644 locales/filter.py
create mode 100644 locales/generic/extract-bookmarks.py
create mode 100644 locales/generic/profile/bookmarks.html.in
create mode 100644 locales/generic/profile/localstore.rdf
create mode 100644 locales/generic/profile/mimeTypes.rdf
create mode 100644 locales/jar.mn
create mode 100644 locales/l10n.ini
create mode 100644 locales/moz.build
create mode 100644 locales/shipped-locales
create mode 100644 modules/AboutHomeUtils.jsm
create mode 100644 modules/AutoCompletePopup.jsm
create mode 100644 modules/BrowserNewTabPreloader.jsm
create mode 100644 modules/CharsetMenu.jsm
create mode 100644 modules/FormSubmitObserver.jsm
create mode 100644 modules/FormValidationHandler.jsm
create mode 100644 modules/NetworkPrioritizer.jsm
create mode 100644 modules/PageMenu.jsm
create mode 100644 modules/PopupNotifications.jsm
create mode 100644 modules/QuotaManager.jsm
create mode 100644 modules/RecentWindow.jsm
create mode 100644 modules/SharedFrame.jsm
create mode 100644 modules/Windows8WindowFrameColor.jsm
create mode 100644 modules/WindowsJumpLists.jsm
create mode 100644 modules/WindowsPreviewPerTab.jsm
create mode 100644 modules/moz.build
create mode 100644 modules/offlineAppCache.jsm
create mode 100644 modules/openLocationLastURL.jsm
create mode 100644 modules/webrtcUI.jsm
create mode 100644 moz.build
create mode 100644 moz.configure
create mode 100644 mozconfig.example
create mode 100644 themes/LICENSE
create mode 100644 themes/linux/Geolocation-16.png
create mode 100644 themes/linux/Geolocation-64.png
create mode 100644 themes/linux/Go-arrow.png
create mode 100644 themes/linux/Info.png
create mode 100644 themes/linux/KUI-close.png
create mode 100644 themes/linux/Makefile.in
create mode 100644 themes/linux/Privacy-16.png
create mode 100644 themes/linux/Privacy-32.png
create mode 100644 themes/linux/Privacy-48.png
create mode 100644 themes/linux/Privacy-64.png
create mode 100644 themes/linux/Secure.png
create mode 100644 themes/linux/Security-broken.png
create mode 100644 themes/linux/Toolbar-small.png
create mode 100644 themes/linux/Toolbar.png
create mode 100644 themes/linux/aboutCertError.css
create mode 100644 themes/linux/aboutCertError_sectionCollapsed-rtl.png
create mode 100644 themes/linux/aboutCertError_sectionCollapsed.png
create mode 100644 themes/linux/aboutCertError_sectionExpanded.png
create mode 100644 themes/linux/aboutPrivateBrowsing.css
create mode 100644 themes/linux/aboutSessionRestore-window-icon.png
create mode 100644 themes/linux/aboutSessionRestore.css
create mode 100644 themes/linux/aboutSyncTabs.css
create mode 100644 themes/linux/actionicon-tab.png
create mode 100644 themes/linux/autocomplete.css
create mode 100644 themes/linux/browser.css
create mode 100644 themes/linux/click-to-play-warning-stripes.png
create mode 100644 themes/linux/communicator/communicator.css
create mode 100644 themes/linux/communicator/jar.mn
create mode 100644 themes/linux/communicator/moz.build
create mode 100644 themes/linux/downloads/allDownloadsViewOverlay.css
create mode 100644 themes/linux/downloads/buttons.png
create mode 100644 themes/linux/downloads/contentAreaDownloadsView.css
create mode 100644 themes/linux/downloads/download-glow-small.png
create mode 100644 themes/linux/downloads/download-glow.png
create mode 100644 themes/linux/downloads/download-notification-finish.png
create mode 100644 themes/linux/downloads/download-notification-start.png
create mode 100644 themes/linux/downloads/download-summary.png
create mode 100644 themes/linux/downloads/downloads.css
create mode 100644 themes/linux/engineManager.css
create mode 100644 themes/linux/feeds/feedIcon.png
create mode 100644 themes/linux/feeds/feedIcon16.png
create mode 100644 themes/linux/feeds/subscribe-ui.css
create mode 100644 themes/linux/feeds/subscribe.css
create mode 100644 themes/linux/icon.png
create mode 100644 themes/linux/identity-icons-generic.png
create mode 100644 themes/linux/identity-icons-https-ev.png
create mode 100644 themes/linux/identity-icons-https-mixed-active.png
create mode 100644 themes/linux/identity-icons-https.png
create mode 100644 themes/linux/identity.png
create mode 100644 themes/linux/imagedocument.png
create mode 100644 themes/linux/jar.mn
create mode 100644 themes/linux/mixed-content-blocked-16.png
create mode 100644 themes/linux/mixed-content-blocked-64.png
create mode 100644 themes/linux/monitor.png
create mode 100644 themes/linux/monitor_16-10.png
create mode 100644 themes/linux/moz.build
create mode 100644 themes/linux/newtab/newTab.css
create mode 100644 themes/linux/page-livemarks.png
create mode 100644 themes/linux/pageInfo.css
create mode 100644 themes/linux/pageInfo.png
create mode 100644 themes/linux/permissions/aboutPermissions.css
create mode 100644 themes/linux/places/bookmarksMenu.png
create mode 100644 themes/linux/places/bookmarksToolbar.png
create mode 100644 themes/linux/places/calendar.png
create mode 100644 themes/linux/places/downloads.png
create mode 100644 themes/linux/places/editBookmarkOverlay.css
create mode 100644 themes/linux/places/livemark-item.png
create mode 100644 themes/linux/places/organizer.css
create mode 100644 themes/linux/places/organizer.xml
create mode 100644 themes/linux/places/pageStarred.png
create mode 100644 themes/linux/places/places.css
create mode 100644 themes/linux/places/query.png
create mode 100644 themes/linux/places/star-icons.png
create mode 100644 themes/linux/places/starPage.png
create mode 100644 themes/linux/places/starred48.png
create mode 100644 themes/linux/places/tag.png
create mode 100644 themes/linux/places/toolbarDropMarker.png
create mode 100644 themes/linux/places/unsortedBookmarks.png
create mode 100644 themes/linux/places/unstarred48.png
create mode 100644 themes/linux/pointerLock-16.png
create mode 100644 themes/linux/pointerLock-64.png
create mode 100644 themes/linux/preferences/Options-sync.png
create mode 100644 themes/linux/preferences/Options.png
create mode 100644 themes/linux/preferences/alwaysAsk.png
create mode 100644 themes/linux/preferences/applications.css
create mode 100644 themes/linux/preferences/mail.png
create mode 100644 themes/linux/preferences/preferences.css
create mode 100644 themes/linux/privatebrowsing-mask.png
create mode 100644 themes/linux/sanitizeDialog.css
create mode 100644 themes/linux/searchbar.css
create mode 100644 themes/linux/setDesktopBackground.css
create mode 100644 themes/linux/slowStartup-16.png
create mode 100644 themes/linux/statusbar/overlay.css
create mode 100644 themes/linux/statusbar/prefs.css
create mode 100644 themes/linux/sync-128.png
create mode 100644 themes/linux/sync-16-throbber.png
create mode 100644 themes/linux/sync-16.png
create mode 100644 themes/linux/sync-24-throbber.png
create mode 100644 themes/linux/sync-32.png
create mode 100644 themes/linux/sync-bg.png
create mode 100644 themes/linux/sync-desktopIcon.png
create mode 100644 themes/linux/sync-mobileIcon.png
create mode 100644 themes/linux/syncCommon.css
create mode 100644 themes/linux/syncProgress.css
create mode 100644 themes/linux/syncQuota.css
create mode 100644 themes/linux/syncSetup.css
create mode 100644 themes/linux/tabbrowser/alltabs.png
create mode 100644 themes/linux/tabbrowser/connecting.png
create mode 100644 themes/linux/tabbrowser/loading.png
create mode 100644 themes/linux/tabbrowser/tab-overflow-border.png
create mode 100644 themes/linux/tabbrowser/tab.png
create mode 100644 themes/linux/tabbrowser/tabDragIndicator.png
create mode 100644 themes/linux/urlbar-arrow.png
create mode 100644 themes/linux/web-notifications-icon.svg
create mode 100644 themes/linux/web-notifications-tray.svg
create mode 100644 themes/linux/webRTC-shareDevice-16.png
create mode 100644 themes/linux/webRTC-shareDevice-64.png
create mode 100644 themes/linux/webRTC-sharingDevice-16.png
create mode 100644 themes/moz.build
create mode 100644 themes/osx/Geolocation-16.png
create mode 100644 themes/osx/Geolocation-64.png
create mode 100644 themes/osx/Info.png
create mode 100644 themes/osx/KUI-background.png
create mode 100644 themes/osx/KUI-close.png
create mode 100644 themes/osx/Makefile.in
create mode 100644 themes/osx/Privacy-16.png
create mode 100644 themes/osx/Privacy-32.png
create mode 100644 themes/osx/Privacy-48.png
create mode 100644 themes/osx/Privacy-64.png
create mode 100644 themes/osx/Search-glass.png
create mode 100644 themes/osx/Secure24.png
create mode 100644 themes/osx/Toolbar-glass.png
create mode 100644 themes/osx/Toolbar-inverted.png
create mode 100644 themes/osx/Toolbar.png
create mode 100644 themes/osx/aboutCertError.css
create mode 100644 themes/osx/aboutCertError_sectionCollapsed-rtl.png
create mode 100644 themes/osx/aboutCertError_sectionCollapsed.png
create mode 100644 themes/osx/aboutCertError_sectionExpanded.png
create mode 100644 themes/osx/aboutPrivateBrowsing.css
create mode 100644 themes/osx/aboutSessionRestore.css
create mode 100644 themes/osx/aboutSyncTabs.css
create mode 100644 themes/osx/actionicon-tab.png
create mode 100644 themes/osx/appmenu-dropmarker.png
create mode 100644 themes/osx/appmenu-icons.png
create mode 100644 themes/osx/autocomplete.css
create mode 100644 themes/osx/browser.css
create mode 100644 themes/osx/click-to-play-warning-stripes.png
create mode 100644 themes/osx/communicator/communicator.css
create mode 100644 themes/osx/communicator/jar.mn
create mode 100644 themes/osx/communicator/moz.build
create mode 100644 themes/osx/downloads/allDownloadsViewOverlay.css
create mode 100644 themes/osx/downloads/buttons.png
create mode 100644 themes/osx/downloads/contentAreaDownloadsView.css
create mode 100644 themes/osx/downloads/download-glow.png
create mode 100644 themes/osx/downloads/download-notification-finish.png
create mode 100644 themes/osx/downloads/download-notification-start.png
create mode 100644 themes/osx/downloads/download-summary.png
create mode 100644 themes/osx/downloads/downloads.css
create mode 100644 themes/osx/engineManager.css
create mode 100644 themes/osx/feeds/feed-icons-16.png
create mode 100644 themes/osx/feeds/feedIcon.png
create mode 100644 themes/osx/feeds/feedIcon16.png
create mode 100644 themes/osx/feeds/subscribe-ui.css
create mode 100644 themes/osx/feeds/subscribe.css
create mode 100644 themes/osx/icon.png
create mode 100644 themes/osx/identity-icons-generic.png
create mode 100644 themes/osx/identity-icons-https-ev.png
create mode 100644 themes/osx/identity-icons-https-mixed-active.png
create mode 100644 themes/osx/identity-icons-https.png
create mode 100644 themes/osx/identity.png
create mode 100644 themes/osx/imagedocument.png
create mode 100644 themes/osx/jar.mn
create mode 100644 themes/osx/keyhole-forward-mask.svg
create mode 100644 themes/osx/livemark-folder.png
create mode 100644 themes/osx/menu-back.png
create mode 100644 themes/osx/menu-forward.png
create mode 100644 themes/osx/mixed-content-blocked-16.png
create mode 100644 themes/osx/mixed-content-blocked-64.png
create mode 100644 themes/osx/monitor.png
create mode 100644 themes/osx/monitor_16-10.png
create mode 100644 themes/osx/moz.build
create mode 100644 themes/osx/newtab/newTab.css
create mode 100644 themes/osx/page-livemarks.png
create mode 100644 themes/osx/page-livemarks@2x.png
create mode 100644 themes/osx/pageInfo.css
create mode 100644 themes/osx/pageInfo.png
create mode 100644 themes/osx/panel-expander-closed.png
create mode 100644 themes/osx/panel-expander-closed@2x.png
create mode 100644 themes/osx/panel-expander-open.png
create mode 100644 themes/osx/panel-expander-open@2x.png
create mode 100644 themes/osx/panel-plus-sign.png
create mode 100644 themes/osx/permissions/aboutPermissions.css
create mode 100644 themes/osx/places/allBookmarks.png
create mode 100644 themes/osx/places/bookmark.png
create mode 100644 themes/osx/places/bookmarksMenu.png
create mode 100644 themes/osx/places/bookmarksToolbar.png
create mode 100644 themes/osx/places/bookmarksToolbar@2x.png
create mode 100644 themes/osx/places/calendar.png
create mode 100644 themes/osx/places/downloads.png
create mode 100644 themes/osx/places/editBookmark.png
create mode 100644 themes/osx/places/editBookmarkOverlay.css
create mode 100644 themes/osx/places/expander-closed-active.png
create mode 100644 themes/osx/places/expander-closed.png
create mode 100644 themes/osx/places/expander-open-active.png
create mode 100644 themes/osx/places/expander-open.png
create mode 100644 themes/osx/places/folderDropArrow.png
create mode 100644 themes/osx/places/folderDropArrow@2x.png
create mode 100644 themes/osx/places/history.png
create mode 100644 themes/osx/places/history@2x.png
create mode 100644 themes/osx/places/libraryToolbar.png
create mode 100644 themes/osx/places/livemark-item.png
create mode 100644 themes/osx/places/organizer.css
create mode 100644 themes/osx/places/places.css
create mode 100644 themes/osx/places/query.png
create mode 100644 themes/osx/places/query@2x.png
create mode 100644 themes/osx/places/starred48.png
create mode 100644 themes/osx/places/tag.png
create mode 100644 themes/osx/places/tag@2x.png
create mode 100644 themes/osx/places/toolbarDropMarker.png
create mode 100644 themes/osx/places/unfiledBookmarks.png
create mode 100644 themes/osx/places/unfiledBookmarks@2x.png
create mode 100644 themes/osx/places/unsortedBookmarks.png
create mode 100644 themes/osx/places/unstarred48.png
create mode 100644 themes/osx/pointerLock-16.png
create mode 100644 themes/osx/pointerLock-64.png
create mode 100644 themes/osx/preferences/Options-sync.png
create mode 100644 themes/osx/preferences/Options.png
create mode 100644 themes/osx/preferences/alwaysAsk.png
create mode 100644 themes/osx/preferences/application.png
create mode 100644 themes/osx/preferences/applications.css
create mode 100644 themes/osx/preferences/mail.png
create mode 100644 themes/osx/preferences/preferences.css
create mode 100644 themes/osx/preferences/saveFile.png
create mode 100644 themes/osx/privatebrowsing-dark.png
create mode 100644 themes/osx/privatebrowsing-light.png
create mode 100644 themes/osx/privatebrowsing-mask.png
create mode 100644 themes/osx/privatebrowsing-mask@2x.png
create mode 100644 themes/osx/reload-stop-go.png
create mode 100644 themes/osx/sanitizeDialog.css
create mode 100644 themes/osx/searchbar-dropdown-arrow.png
create mode 100644 themes/osx/searchbar.css
create mode 100644 themes/osx/setDesktopBackground.css
create mode 100644 themes/osx/shared.inc
create mode 100644 themes/osx/slowStartup-16.png
create mode 100644 themes/osx/statusbar/overlay.css
create mode 100644 themes/osx/statusbar/prefs.css
create mode 100644 themes/osx/sync-128.png
create mode 100644 themes/osx/sync-16.png
create mode 100644 themes/osx/sync-32.png
create mode 100644 themes/osx/sync-bg.png
create mode 100644 themes/osx/sync-desktopIcon.png
create mode 100644 themes/osx/sync-mobileIcon.png
create mode 100644 themes/osx/sync-throbber.png
create mode 100644 themes/osx/syncCommon.css
create mode 100644 themes/osx/syncProgress.css
create mode 100644 themes/osx/syncQuota.css
create mode 100644 themes/osx/syncSetup.css
create mode 100644 themes/osx/tabbrowser/alltabs-inverted.png
create mode 100644 themes/osx/tabbrowser/alltabs.png
create mode 100644 themes/osx/tabbrowser/connecting.png
create mode 100644 themes/osx/tabbrowser/loading.png
create mode 100644 themes/osx/tabbrowser/newtab-glass.png
create mode 100644 themes/osx/tabbrowser/newtab-inverted.png
create mode 100644 themes/osx/tabbrowser/newtab.png
create mode 100644 themes/osx/tabbrowser/tab-arrow-left-glass.png
create mode 100644 themes/osx/tabbrowser/tab-arrow-left-inverted.png
create mode 100644 themes/osx/tabbrowser/tab-arrow-left.png
create mode 100644 themes/osx/tabbrowser/tab-overflow-border.png
create mode 100644 themes/osx/tabbrowser/tabDragIndicator.png
create mode 100644 themes/osx/toolbarbutton-dropdown-arrow-inverted.png
create mode 100644 themes/osx/toolbarbutton-dropdown-arrow.png
create mode 100644 themes/osx/urlbar-arrow.png
create mode 100644 themes/osx/urlbar-history-dropmarker.png
create mode 100644 themes/osx/urlbar-popup-blocked.png
create mode 100644 themes/osx/web-notifications-icon.svg
create mode 100644 themes/osx/web-notifications-tray.svg
create mode 100644 themes/osx/webRTC-shareDevice-16.png
create mode 100644 themes/osx/webRTC-shareDevice-64.png
create mode 100644 themes/osx/webRTC-sharingDevice-16.png
create mode 100644 themes/shared/browser.inc
create mode 100644 themes/shared/newtab/controls.png
create mode 100644 themes/shared/newtab/newTab.css.inc
create mode 100644 themes/shared/newtab/noise.png
create mode 100644 themes/shared/newtab/pinned.png
create mode 100644 themes/shared/plugin-doorhanger.inc.css
create mode 100644 themes/shared/plugins/notification-pluginAlert.png
create mode 100644 themes/shared/plugins/notification-pluginAlert@2x.png
create mode 100644 themes/shared/plugins/notification-pluginBlocked.png
create mode 100644 themes/shared/plugins/notification-pluginBlocked@2x.png
create mode 100644 themes/shared/plugins/notification-pluginNormal.png
create mode 100644 themes/shared/plugins/notification-pluginNormal@2x.png
create mode 100644 themes/shared/statusbar/dynamic.css
create mode 100644 themes/shared/statusbar/overlay.css
create mode 100644 themes/shared/statusbar/pms16.png
create mode 100644 themes/shared/statusbar/pms24.png
create mode 100644 themes/shared/statusbar/prefs.css
create mode 100644 themes/shared/statusbar/pulse.png
create mode 100644 themes/shared/statusbar/throbber-idle.png
create mode 100644 themes/shared/statusbar/throbberStatic.png
create mode 100644 themes/shared/tabbrowser/tab-audio-small.svg
create mode 100644 themes/shared/tabbrowser/tab-audio.svg
create mode 100644 themes/windows/Geolocation-16.png
create mode 100644 themes/windows/Geolocation-64.png
create mode 100644 themes/windows/Info.png
create mode 100644 themes/windows/KUI-background.png
create mode 100644 themes/windows/KUI-close.png
create mode 100644 themes/windows/Makefile.in
create mode 100644 themes/windows/Privacy-16.png
create mode 100644 themes/windows/Privacy-32.png
create mode 100644 themes/windows/Privacy-48.png
create mode 100644 themes/windows/Privacy-64.png
create mode 100644 themes/windows/Push-16.png
create mode 100644 themes/windows/Push-64.png
create mode 100644 themes/windows/Secure24.png
create mode 100644 themes/windows/Toolbar-glass.png
create mode 100644 themes/windows/Toolbar-glass.svg
create mode 100644 themes/windows/Toolbar-inverted.png
create mode 100644 themes/windows/Toolbar-inverted.svg
create mode 100644 themes/windows/Toolbar.png
create mode 100644 themes/windows/Toolbar.svg
create mode 100644 themes/windows/aboutCertError.css
create mode 100644 themes/windows/aboutCertError_sectionCollapsed-rtl.png
create mode 100644 themes/windows/aboutCertError_sectionCollapsed.png
create mode 100644 themes/windows/aboutCertError_sectionExpanded.png
create mode 100644 themes/windows/aboutPrivateBrowsing.css
create mode 100644 themes/windows/aboutSessionRestore-window-icon.png
create mode 100644 themes/windows/aboutSessionRestore.css
create mode 100644 themes/windows/aboutSyncTabs.css
create mode 100644 themes/windows/actionicon-tab.png
create mode 100644 themes/windows/appmenu-dropmarker.png
create mode 100644 themes/windows/appmenu-icons.png
create mode 100644 themes/windows/autocomplete.css
create mode 100644 themes/windows/browser.css
create mode 100644 themes/windows/caption-buttons.svg
create mode 100644 themes/windows/click-to-play-warning-stripes.png
create mode 100644 themes/windows/communicator/communicator.css
create mode 100644 themes/windows/communicator/jar.mn
create mode 100644 themes/windows/communicator/moz.build
create mode 100644 themes/windows/downloads/allDownloadsViewOverlay.css
create mode 100644 themes/windows/downloads/buttons.png
create mode 100644 themes/windows/downloads/contentAreaDownloadsView.css
create mode 100644 themes/windows/downloads/download-notification-finish.png
create mode 100644 themes/windows/downloads/download-notification-start.png
create mode 100644 themes/windows/downloads/download-summary.png
create mode 100644 themes/windows/downloads/downloads.css
create mode 100644 themes/windows/engineManager.css
create mode 100644 themes/windows/feeds/feed-icons-16.png
create mode 100644 themes/windows/feeds/feedIcon.png
create mode 100644 themes/windows/feeds/feedIcon16.png
create mode 100644 themes/windows/feeds/subscribe-ui.css
create mode 100644 themes/windows/feeds/subscribe.css
create mode 100644 themes/windows/icon.png
create mode 100644 themes/windows/identity-icons-generic.png
create mode 100644 themes/windows/identity-icons-https-ev.png
create mode 100644 themes/windows/identity-icons-https-mixed-active.png
create mode 100644 themes/windows/identity-icons-https.png
create mode 100644 themes/windows/identity.png
create mode 100644 themes/windows/imagedocument.png
create mode 100644 themes/windows/jar.mn
create mode 100644 themes/windows/keyhole-forward-mask.svg
create mode 100644 themes/windows/livemark-folder.png
create mode 100644 themes/windows/menu-back.png
create mode 100644 themes/windows/menu-forward.png
create mode 100644 themes/windows/mixed-content-blocked-16.png
create mode 100644 themes/windows/mixed-content-blocked-64.png
create mode 100644 themes/windows/monitor.png
create mode 100644 themes/windows/monitor_16-10.png
create mode 100644 themes/windows/moz.build
create mode 100644 themes/windows/newtab/newTab.css
create mode 100644 themes/windows/pageInfo.css
create mode 100644 themes/windows/pageInfo.png
create mode 100644 themes/windows/permissions/aboutPermissions.css
create mode 100644 themes/windows/places/allBookmarks.png
create mode 100644 themes/windows/places/bookmark.png
create mode 100644 themes/windows/places/bookmarksMenu.png
create mode 100644 themes/windows/places/bookmarksToolbar.png
create mode 100644 themes/windows/places/calendar.png
create mode 100644 themes/windows/places/downloads.png
create mode 100644 themes/windows/places/editBookmark.png
create mode 100644 themes/windows/places/editBookmarkOverlay.css
create mode 100644 themes/windows/places/history.png
create mode 100644 themes/windows/places/libraryToolbar.png
create mode 100644 themes/windows/places/livemark-item.png
create mode 100644 themes/windows/places/organizer.css
create mode 100644 themes/windows/places/places.css
create mode 100644 themes/windows/places/query.png
create mode 100644 themes/windows/places/starred48.png
create mode 100644 themes/windows/places/tag.png
create mode 100644 themes/windows/places/toolbarDropMarker.png
create mode 100644 themes/windows/places/unsortedBookmarks.png
create mode 100644 themes/windows/places/unstarred48.png
create mode 100644 themes/windows/pointerLock-16.png
create mode 100644 themes/windows/pointerLock-64.png
create mode 100644 themes/windows/preferences/Options-sync.png
create mode 100644 themes/windows/preferences/Options.png
create mode 100644 themes/windows/preferences/alwaysAsk.png
create mode 100644 themes/windows/preferences/application.png
create mode 100644 themes/windows/preferences/applications.css
create mode 100644 themes/windows/preferences/mail.png
create mode 100644 themes/windows/preferences/preferences.css
create mode 100644 themes/windows/preferences/saveFile.png
create mode 100644 themes/windows/privatebrowsing-dark.png
create mode 100644 themes/windows/privatebrowsing-light.png
create mode 100644 themes/windows/reload-stop-go.png
create mode 100644 themes/windows/sanitize.png
create mode 100644 themes/windows/sanitizeDialog.css
create mode 100644 themes/windows/searchbar-dropdown-arrow.png
create mode 100644 themes/windows/searchbar.css
create mode 100644 themes/windows/setDesktopBackground.css
create mode 100644 themes/windows/slowStartup-16.png
create mode 100644 themes/windows/statusbar/overlay.css
create mode 100644 themes/windows/statusbar/prefs.css
create mode 100644 themes/windows/sync-128.png
create mode 100644 themes/windows/sync-16.png
create mode 100644 themes/windows/sync-32.png
create mode 100644 themes/windows/sync-bg.png
create mode 100644 themes/windows/sync-desktopIcon.png
create mode 100644 themes/windows/sync-mobileIcon.png
create mode 100644 themes/windows/sync-throbber.png
create mode 100644 themes/windows/syncCommon.css
create mode 100644 themes/windows/syncProgress.css
create mode 100644 themes/windows/syncQuota.css
create mode 100644 themes/windows/syncSetup.css
create mode 100644 themes/windows/tabbrowser/alltabs-inverted.png
create mode 100644 themes/windows/tabbrowser/alltabs.png
create mode 100644 themes/windows/tabbrowser/connecting.png
create mode 100644 themes/windows/tabbrowser/loading.png
create mode 100644 themes/windows/tabbrowser/newtab-glass.png
create mode 100644 themes/windows/tabbrowser/newtab-inverted.png
create mode 100644 themes/windows/tabbrowser/newtab.png
create mode 100644 themes/windows/tabbrowser/tab-arrow-left-glass.png
create mode 100644 themes/windows/tabbrowser/tab-arrow-left-inverted.png
create mode 100644 themes/windows/tabbrowser/tab-arrow-left.png
create mode 100644 themes/windows/tabbrowser/tab-overflow-border.png
create mode 100644 themes/windows/tabbrowser/tabDragIndicator.png
create mode 100644 themes/windows/toolbarbutton-dropdown-arrow-inverted.png
create mode 100644 themes/windows/toolbarbutton-dropdown-arrow.png
create mode 100644 themes/windows/urlbar-arrow.png
create mode 100644 themes/windows/urlbar-history-dropmarker.png
create mode 100644 themes/windows/urlbar-popup-blocked.png
create mode 100644 themes/windows/web-notifications-icon.svg
create mode 100644 themes/windows/web-notifications-tray.svg
create mode 100644 themes/windows/webRTC-shareDevice-16.png
create mode 100644 themes/windows/webRTC-shareDevice-64.png
create mode 100644 themes/windows/webRTC-sharingDevice-16.png
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e3b7160
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,7 @@
+Please see the file ../toolkit/content/license.html for the copyright
+licensing conditions attached to this codebase, including copies of the
+licenses concerned.
+
+You are not granted rights or licenses to the trademarks of the
+Mozilla Foundation, Moonchild Productions or any party, including without
+limitation the Pale Moon name or logo.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..92527ea
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,13 @@
+# 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
+
+ifdef MAKENSISU
+
+# For Windows build the uninstaller during the application build since the
+# uninstaller is included with the application for mar file generation.
+libs::
+ $(MAKE) -C installer/windows uninstaller
+endif
diff --git a/app-rules.mk b/app-rules.mk
new file mode 100644
index 0000000..2c31653
--- /dev/null
+++ b/app-rules.mk
@@ -0,0 +1 @@
+PURGECACHES_DIRS = $(DIST)/bin/browser
diff --git a/app.mozbuild b/app.mozbuild
new file mode 100644
index 0000000..5f1c0b9
--- /dev/null
+++ b/app.mozbuild
@@ -0,0 +1,17 @@
+# 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/.
+
+if not CONFIG['LIBXUL_SDK']:
+ include('/toolkit/toolkit.mozbuild')
+
+if CONFIG['MOZ_EXTENSIONS']:
+ DIRS += ['/extensions']
+
+DIRS += ['/%s' % CONFIG['MOZ_BRANDING_DIRECTORY']]
+
+# Never add tier dirs after browser because they apparently won't get
+# packaged properly on Mac.
+DIRS += ['/application/webbrowser']
+
diff --git a/app/Makefile.in b/app/Makefile.in
new file mode 100644
index 0000000..d008010
--- /dev/null
+++ b/app/Makefile.in
@@ -0,0 +1,108 @@
+# 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/.
+
+dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
+
+# hardcode en-US for the moment
+AB_CD = en-US
+
+DEFINES += \
+ -DAB_CD=$(AB_CD) \
+ -DAPP_VERSION="$(MOZ_APP_VERSION)" \
+ -DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" \
+ -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" \
+ -DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \
+ -DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \
+ -DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \
+ $(NULL)
+
+# Build a binary bootstrapping with XRE_main
+
+ifndef MOZ_WINCONSOLE
+ifdef MOZ_DEBUG
+MOZ_WINCONSOLE = 1
+else
+MOZ_WINCONSOLE = 0
+endif
+endif
+
+# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
+# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
+NSDISTMODE = copy
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_ARCH),WINNT)
+# Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
+# (this dependency should really be just for firefox.exe, not other targets)
+EXTRA_DEPS += $(PROGRAM).manifest
+endif
+
+PROGRAMS_DEST = $(DIST)/bin
+
+include $(topsrcdir)/config/rules.mk
+
+ifneq (,$(filter-out WINNT,$(OS_ARCH)))
+
+ifdef COMPILE_ENVIRONMENT
+libs::
+ cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
+endif
+
+GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, palemoon.js)
+
+endif
+
+ifndef LIBXUL_SDK
+# channel-prefs.js is handled separate from other prefs due to bug 756325
+libs:: $(srcdir)/profile/channel-prefs.js
+ $(NSINSTALL) -D $(DIST)/bin/defaults/pref
+ $(call py_action,preprocessor,-Fsubstitution $(PREF_PPFLAGS) $(ACDEFINES) $^ -o $(DIST)/bin/defaults/pref/channel-prefs.js)
+endif
+
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+
+MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
+
+ifdef MOZ_DEBUG
+MAC_APP_NAME := $(MAC_APP_NAME)Debug
+endif
+
+AB_CD = $(MOZ_UI_LOCALE)
+
+AB := $(firstword $(subst -, ,$(AB_CD)))
+
+clean clobber repackage::
+ $(RM) -r $(dist_dest)
+
+MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/buildid.h)
+
+.PHONY: repackage
+tools repackage:: $(PROGRAM)
+ $(MKDIR) -p '$(dist_dest)/Contents/MacOS'
+ $(MKDIR) -p '$(dist_dest)/Contents/Resources/$(AB).lproj'
+ rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents '$(dist_dest)' --exclude English.lproj
+ rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ '$(dist_dest)/Contents/Resources/$(AB).lproj'
+ sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' $(srcdir)/macbuild/Contents/Info.plist.in > '$(dist_dest)/Contents/Info.plist'
+ sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > '$(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings'
+ rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ '$(dist_dest)/Contents/Resources'
+ rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ '$(dist_dest)/Contents/MacOS'
+ $(RM) '$(dist_dest)/Contents/MacOS/$(PROGRAM)'
+ rsync -aL $(PROGRAM) '$(dist_dest)/Contents/MacOS'
+ cp -RL $(DIST)/branding/firefox.icns '$(dist_dest)/Contents/Resources/firefox.icns'
+ cp -RL $(DIST)/branding/document.icns '$(dist_dest)/Contents/Resources/document.icns'
+ printf APPLMOZB > '$(dist_dest)/Contents/PkgInfo'
+endif
+
+ifdef LIBXUL_SDK #{
+ifndef SKIP_COPY_XULRUNNER #{
+libs::
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
+ rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework '$(dist_dest)/Contents/Frameworks'
+else
+ $(NSINSTALL) -D $(DIST)/bin/xulrunner
+ (cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
+endif #} cocoa
+endif #} SKIP_COPY_XULRUNNER
+endif #} LIBXUL_SDK
diff --git a/app/application.ini b/app/application.ini
new file mode 100644
index 0000000..c64ed90
--- /dev/null
+++ b/app/application.ini
@@ -0,0 +1,50 @@
+#if MOZ_APP_STATIC_INI
+#ifdef MOZ_BUILD_APP_IS_BROWSER
+; This file is not used. If you modify it and want the application to use
+; your modifications, move it under the browser/ subdirectory and start with
+; the "-app /path/to/browser/application.ini" argument.
+#else
+; This file is not used. If you modify it and want the application to use
+; your modifications, start with the "-app /path/to/application.ini"
+; argument.
+#endif
+#endif
+#if 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/.
+#endif
+#filter substitution
+#include @TOPOBJDIR@/buildid.h
+#include @TOPOBJDIR@/source-repo.h
+
+[App]
+# Vendor=@MOZ_APP_VENDOR@
+Vendor=Moonchild Productions
+# Name=@MOZ_APP_BASENAME@
+Name=Pale Moon
+RemotingName=@MOZ_APP_REMOTINGNAME@
+#ifdef MOZ_APP_DISPLAYNAME
+CodeName=@MOZ_APP_DISPLAYNAME@
+#endif
+Version=@MOZ_APP_VERSION@
+#ifdef MOZ_APP_PROFILE
+Profile=@MOZ_APP_PROFILE@
+#endif
+BuildID=@MOZ_BUILDID@
+#ifdef MOZ_SOURCE_REPO
+SourceRepository=@MOZ_SOURCE_REPO@
+#endif
+#ifdef MOZ_SOURCE_STAMP
+SourceStamp=@MOZ_SOURCE_STAMP@
+#endif
+ID=@MOZ_APP_ID@
+
+[Gecko]
+MinVersion=@GRE_MILESTONE@
+MaxVersion=@GRE_MILESTONE@
+
+[XRE]
+#ifdef MOZ_PROFILE_MIGRATOR
+EnableProfileMigrator=1
+#endif
\ No newline at end of file
diff --git a/app/blocklist.xml b/app/blocklist.xml
new file mode 100644
index 0000000..4bc4be1
--- /dev/null
+++ b/app/blocklist.xml
@@ -0,0 +1,3909 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ security.csp.enable
+ security.fileuri.strict_origin_policy
+ security.mixed_content.block_active_content
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app.update.auto
+ app.update.enabled
+ app.update.interval
+ app.update.url
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browser.startup.homepage
+ browser.search.defaultenginename
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://java.com/
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://java.com/
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://real.com/
+
+
+
+
+ https://get.adobe.com/shockwave/
+
+
+
+
+ https://get.adobe.com/shockwave/
+
+
+
+
+ https://java.com/
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+
+
+ https://java.com/
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ https://www.adobe.com/products/flashplayer/distribution3.html
+
+
+
+
+ WINNT 6.1
+ 0x10de
+
+ 0x0a6c
+
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 8.17.12.5896
+
+ LESS_THAN_OR_EQUAL
+
+
+ WINNT 6.1
+ 0x10de
+
+ 0x0a6c
+
+ DIRECT3D_9_LAYERS
+ BLOCKED_DRIVER_VERSION
+ 8.17.12.5896
+
+ LESS_THAN_OR_EQUAL
+
+
+ WINNT 5.1
+ 0x10de
+ DIRECT3D_9_LAYERS
+ BLOCKED_DRIVER_VERSION
+ 7.0.0.0
+
+ GREATER_THAN_OR_EQUAL
+
+
+ All
+ 0x1002
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 8.982.0.0
+ EQUAL
+
+
+ All
+ 0x1022
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 8.982.0.0
+ EQUAL
+
+
+ All
+ 0x1022
+ DIRECT3D_9_LAYERS
+ BLOCKED_DRIVER_VERSION
+ 8.982.0.0
+ EQUAL
+
+
+ All
+ 0x1002
+ DIRECT3D_9_LAYERS
+ BLOCKED_DRIVER_VERSION
+ 8.982.0.0
+ EQUAL
+
+
+ WINNT 6.2
+ 0x1002
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 9.10.8.0
+
+ LESS_THAN_OR_EQUAL
+
+
+ WINNT 6.2
+ 0x1022
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 9.10.8.0
+
+ LESS_THAN_OR_EQUAL
+
+
+ Darwin 10
+ 0x10de
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 11
+ 0x10de
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 12
+ 0x10de
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 10
+ 0x8086
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 11
+ 0x8086
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 12
+ 0x8086
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 10
+ 0x1002
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 11
+ 0x1002
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ Darwin 12
+ 0x1002
+ WEBGL_MSAA
+ BLOCKED_DEVICE
+
+
+ WINNT 6.1
+ 0x1002
+
+ 0x68e1
+ 0x68e4
+ 0x68e5
+ 0x68f9
+ 0x9802
+ 0x9803
+ 0x9803
+ 0x9804
+ 0x9805
+ 0x9806
+ 0x9807
+
+ DIRECT2D
+ BLOCKED_DEVICE
+
+
+ WINNT 6.1
+ 0x1002
+
+ 0x9802
+ 0x9803
+ 0x9803
+ 0x9804
+ 0x9805
+ 0x9806
+ 0x9807
+
+ DIRECT3D_9_LAYERS
+ BLOCKED_DEVICE
+
+
+ WINNT 10.0
+ 0x1002
+
+ 0x6920
+ 0x6921
+ 0x6928
+ 0x6929
+ 0x692b
+ 0x692f
+ 0x6930
+ 0x6938
+ 0x6939
+ 0x6900
+ 0x6901
+ 0x6902
+ 0x6903
+ 0x6907
+ 0x7300
+ 0x9870
+ 0x9874
+ 0x9875
+ 0x9876
+ 0x9877
+
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 15.201.1151.0
+ LESS_THAN
+
+
+ All
+ 0x8086
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.2413
+
+ LESS_THAN_OR_EQUAL
+
+
+ WINNT 8.1
+ 0x1002
+
+ 0x6920
+ 0x6921
+ 0x6928
+ 0x6929
+ 0x692b
+ 0x692f
+ 0x6930
+ 0x6938
+ 0x6939
+ 0x6900
+ 0x6901
+ 0x6902
+ 0x6903
+ 0x6907
+ 0x7300
+ 0x9870
+ 0x9874
+ 0x9875
+ 0x9876
+ 0x9877
+
+ DIRECT2D
+ BLOCKED_DRIVER_VERSION
+ 15.201.1151.0
+ LESS_THAN
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1851
+ EQUAL
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1855
+ EQUAL
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1872
+ EQUAL
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1883
+ EQUAL
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1892
+ EQUAL
+
+
+ 0x8086
+
+ 0x2a42
+ 0x2e22
+ 0x2e12
+ 0x2e32
+ 0x0046
+
+ BLOCKED_DRIVER_VERSION
+ 8.15.10.1994
+ EQUAL
+
+
+
diff --git a/app/macbuild/Contents/CodeResources b/app/macbuild/Contents/CodeResources
new file mode 100644
index 0000000..1a65e20
--- /dev/null
+++ b/app/macbuild/Contents/CodeResources
@@ -0,0 +1 @@
+_CodeSignature/CodeResources
\ No newline at end of file
diff --git a/app/macbuild/Contents/Info.plist.in b/app/macbuild/Contents/Info.plist.in
new file mode 100644
index 0000000..b224064
--- /dev/null
+++ b/app/macbuild/Contents/Info.plist.in
@@ -0,0 +1,227 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleDocumentTypes
+
+
+ CFBundleTypeExtensions
+
+ html
+ htm
+ shtml
+ xht
+ xhtml
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeName
+ HTML Document
+ CFBundleTypeOSTypes
+
+ HTML
+
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleTypeExtensions
+
+ svg
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeMIMETypes
+
+ image/svg+xml
+
+ CFBundleTypeName
+ SVG document
+ CFBundleTypeOSTypes
+
+ TEXT
+
+ CFBundleTypeRole
+ Viewer
+ NSDocumentClass
+ BrowserDocument
+
+
+ CFBundleTypeExtensions
+
+ text
+ txt
+ js
+ log
+ css
+ xul
+ rdf
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeName
+ Text Document
+ CFBundleTypeOSTypes
+
+ TEXT
+ utxt
+
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleTypeExtensions
+
+ jpeg
+ jpg
+ png
+ gif
+
+ CFBundleTypeIconFile
+ fileBookmark.icns
+ CFBundleTypeName
+ document.icns
+ CFBundleTypeOSTypes
+
+ GIFf
+ JPEG
+ PNGf
+
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleTypeExtensions
+
+ oga
+ ogg
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeMIMETypes
+
+ audio/ogg
+
+ CFBundleTypeName
+ HTML5 Audio (Ogg)
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleTypeExtensions
+
+ ogv
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeMIMETypes
+
+ video/ogg
+
+ CFBundleTypeName
+ HTML5 Video (Ogg)
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleTypeExtensions
+
+ webm
+
+ CFBundleTypeIconFile
+ document.icns
+ CFBundleTypeMIMETypes
+
+ video/webm
+
+ CFBundleTypeName
+ HTML5 Video (WebM)
+ CFBundleTypeRole
+ Viewer
+
+
+ CFBundleExecutable
+ palemoon
+ CFBundleGetInfoString
+ %MAC_APP_NAME% %APP_VERSION%
+ CFBundleIconFile
+ firefox
+ CFBundleIdentifier
+ %MOZ_MACBUNDLE_ID%
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ %MAC_APP_NAME%
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ %APP_VERSION%
+ CFBundleSignature
+ MOZB
+ CFBundleURLTypes
+
+
+ CFBundleURLIconFile
+ document.icns
+ CFBundleURLName
+ http URL
+ CFBundleURLSchemes
+
+ http
+
+
+
+ CFBundleURLIconFile
+ document.icns
+ CFBundleURLName
+ https URL
+ CFBundleURLSchemes
+
+ https
+
+
+
+ CFBundleURLName
+ ftp URL
+ CFBundleURLSchemes
+
+ ftp
+
+
+
+ CFBundleURLName
+ file URL
+ CFBundleURLSchemes
+
+ file
+
+
+
+ CFBundleVersion
+ %MAC_BUNDLE_VERSION%
+ NSAppleScriptEnabled
+
+ LSApplicationCategoryType
+ public.app-category.productivity
+ LSEnvironment
+
+ MallocNanoZone
+ 0
+
+ LSMinimumSystemVersion
+ 10.6
+ LSMinimumSystemVersionByArchitecture
+
+ i386
+ 10.6.0
+ x86_64
+ 10.6.0
+
+ NSSupportsAutomaticGraphicsSwitching
+
+ NSPrincipalClass
+ GoannaNSApplication
+
+
diff --git a/app/macbuild/Contents/MacOS-files.in b/app/macbuild/Contents/MacOS-files.in
new file mode 100644
index 0000000..561366d
--- /dev/null
+++ b/app/macbuild/Contents/MacOS-files.in
@@ -0,0 +1,10 @@
+/*.app/***
+/*.dylib
+/certutil
+/firefox-bin
+/gtest/***
+/pk12util
+/ssltunnel
+/xpcshell
+/XUL
+
diff --git a/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
new file mode 100644
index 0000000..74d192c
--- /dev/null
+++ b/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
@@ -0,0 +1,5 @@
+/* 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/. */
+
+CFBundleName = "%MAC_APP_NAME%";
diff --git a/app/macbuild/Contents/_CodeSignature/CodeResources b/app/macbuild/Contents/_CodeSignature/CodeResources
new file mode 100644
index 0000000..6f6e20e
--- /dev/null
+++ b/app/macbuild/Contents/_CodeSignature/CodeResources
@@ -0,0 +1,71 @@
+
+
+
+
+ rules
+
+ ^Info.plist$
+
+ ^PkgInfo$
+
+ ^MacOS/
+
+ ^Resources/
+
+ ^MacOS/distribution/.*
+ omit
+
+ weight
+ 10
+
+ ^MacOS/override.ini
+ omit
+
+ weight
+ 10
+
+ ^MacOS/updates/.*
+ omit
+
+ weight
+ 10
+
+ ^MacOS/active-update.xml$
+ omit
+
+ weight
+ 10
+
+ ^MacOS/defaults/.*
+ omit
+
+ weight
+ 10
+
+ ^MacOS/removed-files$
+ omit
+
+ weight
+ 10
+
+ ^MacOS/updates.xml$
+ omit
+
+ weight
+ 10
+
+ ^Updated.app/.*
+ omit
+
+ weight
+ 10
+
+ ^updating/.*
+ omit
+
+ weight
+ 10
+
+
+
+
diff --git a/app/macversion.py b/app/macversion.py
new file mode 100644
index 0000000..839aac1
--- /dev/null
+++ b/app/macversion.py
@@ -0,0 +1,44 @@
+#!/usr/bin/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/.
+
+
+from optparse import OptionParser
+import sys
+import re
+
+o = OptionParser()
+o.add_option("--buildid", dest="buildid")
+o.add_option("--version", dest="version")
+
+(options, args) = o.parse_args()
+
+if not options.buildid:
+ print >>sys.stderr, "--buildid is required"
+ sys.exit(1)
+
+if not options.version:
+ print >>sys.stderr, "--version is required"
+ sys.exit(1)
+
+# We want to build a version number that matches the format allowed for
+# CFBundleVersion (nnnnn[.nn[.nn]]). We'll incorporate both the version
+# number as well as the date, so that it changes at least daily (for nightly
+# builds), but also so that newly-built older versions (e.g. beta build) aren't
+# considered "newer" than previously-built newer versions (e.g. a trunk nightly)
+
+define, MOZ_BUILDID, buildid = open(options.buildid, 'r').read().split()
+
+# extract only the major version (i.e. "14" from "14.0b1")
+majorVersion = re.match(r'^(\d+)[^\d].*', options.version).group(1)
+# last two digits of the year
+twodigityear = buildid[2:4]
+month = buildid[4:6]
+if month[0] == '0':
+ month = month[1]
+day = buildid[6:8]
+if day[0] == '0':
+ day = day[1]
+
+print '%s.%s.%s' % (majorVersion + twodigityear, month, day)
diff --git a/app/module.ver b/app/module.ver
new file mode 100644
index 0000000..7a00230
--- /dev/null
+++ b/app/module.ver
@@ -0,0 +1,8 @@
+WIN32_MODULE_COMPANYNAME=Moonchild Productions
+WIN32_MODULE_COPYRIGHT=©Pale Moon, Firefox and Mozilla Developers, available under the MPL 2.0.
+WIN32_MODULE_PRODUCTVERSION=@MOZ_APP_WINVERSION@
+WIN32_MODULE_PRODUCTVERSION_STRING=@MOZ_APP_VERSION@
+WIN32_MODULE_TRADEMARKS=The Pale Moon logo and project names are the property of Moonchild Productions.
+WIN32_MODULE_DESCRIPTION=Pale Moon web browser
+WIN32_MODULE_PRODUCTNAME=Pale Moon
+WIN32_MODULE_NAME=Pale Moon
diff --git a/app/moz.build b/app/moz.build
new file mode 100644
index 0000000..8166760
--- /dev/null
+++ b/app/moz.build
@@ -0,0 +1,64 @@
+# -*- 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/.
+
+DIRS += ['profile/extensions']
+
+GeckoProgram(CONFIG['MOZ_APP_NAME'])
+
+JS_PREFERENCE_PP_FILES += [
+ 'profile/palemoon.js',
+]
+
+if CONFIG['LIBXUL_SDK']:
+ PREF_JS_EXPORTS += [
+ 'profile/channel-prefs.js',
+ ]
+
+SOURCES += ['nsBrowserApp.cpp']
+
+FINAL_TARGET_FILES += ['blocklist.xml']
+FINAL_TARGET_FILES.defaults += ['permissions']
+FINAL_TARGET_FILES.defaults.profile += ['profile/prefs.js']
+
+DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+
+LOCAL_INCLUDES += ['!/build']
+
+LOCAL_INCLUDES += [
+ '/toolkit/xre',
+ '/xpcom/base',
+ '/xpcom/build',
+]
+
+USE_LIBS += ['mozglue']
+
+if CONFIG['_MSC_VER']:
+ # Always enter a Windows program through wmain, whether or not we're
+ # a console application.
+ WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ RCINCLUDE = 'splash.rc'
+ DEFINES['MOZ_PHOENIX'] = True
+
+# Control the default heap size.
+# This is the heap returned by GetProcessHeap().
+# As we use the CRT heap, the default size is too large and wastes VM.
+#
+# The default heap size is 1MB on Win32.
+# The heap will grow if need be.
+#
+# Set it to 256k. See bug 127069.
+if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']:
+ LDFLAGS += ['/HEAP:0x40000']
+
+DISABLE_STL_WRAPPING = True
+
+if CONFIG['MOZ_LINKER']:
+ OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
+
+if CONFIG['HAVE_CLOCK_MONOTONIC']:
+ OS_LIBS += CONFIG['REALTIME_LIBS']
diff --git a/app/nsBrowserApp.cpp b/app/nsBrowserApp.cpp
new file mode 100644
index 0000000..8b06135
--- /dev/null
+++ b/app/nsBrowserApp.cpp
@@ -0,0 +1,393 @@
+/* -*- 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 "nsXULAppAPI.h"
+#include "mozilla/AppData.h"
+#include "application.ini.h"
+#include "nsXPCOMGlue.h"
+#if defined(XP_WIN)
+#include
+#include
+#elif defined(XP_UNIX)
+#include
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "nsCOMPtr.h"
+#include "nsIFile.h"
+#include "nsStringGlue.h"
+
+#ifdef XP_WIN
+#define XRE_WANT_ENVIRON
+#define strcasecmp _stricmp
+#endif
+#include "BinaryPath.h"
+
+#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
+
+#include "mozilla/Sprintf.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/WindowsDllBlocklist.h"
+
+#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
+#define MOZ_BROWSER_CAN_BE_CONTENTPROC
+#include "../../ipc/contentproc/plugin-container.cpp"
+#endif
+
+using namespace mozilla;
+
+#ifdef XP_MACOSX
+#define kOSXResourcesFolder "Resources"
+#endif
+#define kDesktopFolder "browser"
+
+static void Output(const char *fmt, ... )
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+#ifndef XP_WIN
+ vfprintf(stderr, fmt, ap);
+#else
+ char msg[2048];
+ vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
+
+ wchar_t wide_msg[2048];
+ MultiByteToWideChar(CP_UTF8,
+ 0,
+ msg,
+ -1,
+ wide_msg,
+ _countof(wide_msg));
+#if MOZ_WINCONSOLE
+ fwprintf_s(stderr, wide_msg);
+#else
+ // Linking user32 at load-time interferes with the DLL blocklist (bug 932100).
+ // This is a rare codepath, so we can load user32 at run-time instead.
+ HMODULE user32 = LoadLibraryW(L"user32.dll");
+ if (user32) {
+ decltype(MessageBoxW)* messageBoxW =
+ (decltype(MessageBoxW)*) GetProcAddress(user32, "MessageBoxW");
+ if (messageBoxW) {
+ messageBoxW(nullptr, wide_msg, L"Pale Moon", MB_OK
+ | MB_ICONERROR
+ | MB_SETFOREGROUND);
+ }
+ FreeLibrary(user32);
+ }
+#endif
+#endif
+
+ va_end(ap);
+}
+
+/**
+ * Return true if |arg| matches the given argument name.
+ */
+static bool IsArg(const char* arg, const char* s)
+{
+ if (*arg == '-')
+ {
+ if (*++arg == '-')
+ ++arg;
+ return !strcasecmp(arg, s);
+ }
+
+#if defined(XP_WIN)
+ if (*arg == '/')
+ return !strcasecmp(++arg, s);
+#endif
+
+ return false;
+}
+
+XRE_GetFileFromPathType XRE_GetFileFromPath;
+XRE_CreateAppDataType XRE_CreateAppData;
+XRE_FreeAppDataType XRE_FreeAppData;
+XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
+XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
+XRE_mainType XRE_main;
+XRE_StopLateWriteChecksType XRE_StopLateWriteChecks;
+XRE_XPCShellMainType XRE_XPCShellMain;
+XRE_GetProcessTypeType XRE_GetProcessType;
+XRE_SetProcessTypeType XRE_SetProcessType;
+XRE_InitChildProcessType XRE_InitChildProcess;
+XRE_EnableSameExecutableForContentProcType XRE_EnableSameExecutableForContentProc;
+#ifdef LIBFUZZER
+XRE_LibFuzzerSetMainType XRE_LibFuzzerSetMain;
+XRE_LibFuzzerGetFuncsType XRE_LibFuzzerGetFuncs;
+#endif
+
+static const nsDynamicFunctionLoad kXULFuncs[] = {
+ { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
+ { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
+ { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+ { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
+ { "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
+ { "XRE_main", (NSFuncPtr*) &XRE_main },
+ { "XRE_StopLateWriteChecks", (NSFuncPtr*) &XRE_StopLateWriteChecks },
+ { "XRE_XPCShellMain", (NSFuncPtr*) &XRE_XPCShellMain },
+ { "XRE_GetProcessType", (NSFuncPtr*) &XRE_GetProcessType },
+ { "XRE_SetProcessType", (NSFuncPtr*) &XRE_SetProcessType },
+ { "XRE_InitChildProcess", (NSFuncPtr*) &XRE_InitChildProcess },
+ { "XRE_EnableSameExecutableForContentProc", (NSFuncPtr*) &XRE_EnableSameExecutableForContentProc },
+#ifdef LIBFUZZER
+ { "XRE_LibFuzzerSetMain", (NSFuncPtr*) &XRE_LibFuzzerSetMain },
+ { "XRE_LibFuzzerGetFuncs", (NSFuncPtr*) &XRE_LibFuzzerGetFuncs },
+#endif
+ { nullptr, nullptr }
+};
+
+#ifdef LIBFUZZER
+int libfuzzer_main(int argc, char **argv);
+
+/* This wrapper is used by the libFuzzer main to call into libxul */
+
+void libFuzzerGetFuncs(const char* moduleName, LibFuzzerInitFunc* initFunc,
+ LibFuzzerTestingFunc* testingFunc) {
+ return XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
+}
+#endif
+
+static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
+{
+ nsCOMPtr appini;
+ nsresult rv;
+ uint32_t mainFlags = 0;
+
+ // Allow palemoon.exe to launch XULRunner apps via -app
+ // Note that -app must be the *first* argument.
+ const char *appDataFile = getenv("XUL_APP_FILE");
+ if (appDataFile && *appDataFile) {
+ rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
+ if (NS_FAILED(rv)) {
+ Output("Invalid path found: '%s'", appDataFile);
+ return 255;
+ }
+ }
+ else if (argc > 1 && IsArg(argv[1], "app")) {
+ if (argc == 2) {
+ Output("Incorrect number of arguments passed to -app");
+ return 255;
+ }
+
+ rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
+ if (NS_FAILED(rv)) {
+ Output("application.ini path not recognized: '%s'", argv[2]);
+ return 255;
+ }
+
+ char appEnv[MAXPATHLEN];
+ SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
+ if (putenv(strdup(appEnv))) {
+ Output("Couldn't set %s.\n", appEnv);
+ return 255;
+ }
+ argv[2] = argv[0];
+ argv += 2;
+ argc -= 2;
+ } else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
+ for (int i = 1; i < argc; i++) {
+ argv[i] = argv[i + 1];
+ }
+
+ return XRE_XPCShellMain(--argc, argv, envp);
+ }
+
+ if (appini) {
+ nsXREAppData *appData;
+ rv = XRE_CreateAppData(appini, &appData);
+ if (NS_FAILED(rv)) {
+ Output("Couldn't read application.ini");
+ return 255;
+ }
+#if defined(HAS_DLL_BLOCKLIST)
+ // The dll blocklist operates in the exe vs. xullib. Pass a flag to
+ // xullib so automated tests can check the result once the browser
+ // is up and running.
+ appData->flags |=
+ DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
+#endif
+ // xreDirectory already has a refcount from NS_NewLocalFile
+ appData->xreDirectory = xreDirectory;
+ int result = XRE_main(argc, argv, appData, mainFlags);
+ XRE_FreeAppData(appData);
+ return result;
+ }
+
+ ScopedAppData appData(&sAppData);
+ nsCOMPtr exeFile;
+ rv = mozilla::BinaryPath::GetFile(argv[0], getter_AddRefs(exeFile));
+ if (NS_FAILED(rv)) {
+ Output("Couldn't find the application directory.\n");
+ return 255;
+ }
+
+ nsCOMPtr greDir;
+ exeFile->GetParent(getter_AddRefs(greDir));
+#ifdef XP_MACOSX
+ greDir->SetNativeLeafName(NS_LITERAL_CSTRING(kOSXResourcesFolder));
+#endif
+ nsCOMPtr appSubdir;
+ greDir->Clone(getter_AddRefs(appSubdir));
+ appSubdir->Append(NS_LITERAL_STRING(kDesktopFolder));
+
+ SetStrongPtr(appData.directory, static_cast(appSubdir.get()));
+ // xreDirectory already has a refcount from NS_NewLocalFile
+ appData.xreDirectory = xreDirectory;
+
+#if defined(HAS_DLL_BLOCKLIST)
+ appData.flags |=
+ DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
+#endif
+
+#ifdef LIBFUZZER
+ if (getenv("LIBFUZZER"))
+ XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
+#endif
+
+ return XRE_main(argc, argv, &appData, mainFlags);
+}
+
+static bool
+FileExists(const char *path)
+{
+#ifdef XP_WIN
+ wchar_t wideDir[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
+ DWORD fileAttrs = GetFileAttributesW(wideDir);
+ return fileAttrs != INVALID_FILE_ATTRIBUTES;
+#else
+ return access(path, R_OK) == 0;
+#endif
+}
+
+static nsresult
+InitXPCOMGlue(const char *argv0, nsIFile **xreDirectory)
+{
+ char exePath[MAXPATHLEN];
+
+ nsresult rv = mozilla::BinaryPath::Get(argv0, exePath);
+ if (NS_FAILED(rv)) {
+ Output("Couldn't find the application directory.\n");
+ return rv;
+ }
+
+ char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
+ if (!lastSlash ||
+ (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
+ return NS_ERROR_FAILURE;
+
+ strcpy(lastSlash + 1, XPCOM_DLL);
+
+ if (!FileExists(exePath)) {
+ Output("Could not find the Mozilla runtime.\n");
+ return NS_ERROR_FAILURE;
+ }
+
+ // We do this because of data in bug 771745
+ XPCOMGlueEnablePreload();
+
+ rv = XPCOMGlueStartup(exePath);
+ if (NS_FAILED(rv)) {
+ Output("Couldn't load XPCOM.\n");
+ return rv;
+ }
+
+ rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
+ if (NS_FAILED(rv)) {
+ Output("Couldn't load XRE functions.\n");
+ return rv;
+ }
+
+ // This will set this thread as the main thread.
+ NS_LogInit();
+
+ if (xreDirectory) {
+ // chop XPCOM_DLL off exePath
+ *lastSlash = '\0';
+#ifdef XP_MACOSX
+ lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
+ strcpy(lastSlash + 1, kOSXResourcesFolder);
+#endif
+#ifdef XP_WIN
+ rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
+ xreDirectory);
+#else
+ rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
+ xreDirectory);
+#endif
+ }
+
+ return rv;
+}
+
+int main(int argc, char* argv[], char* envp[])
+{
+ mozilla::TimeStamp start = mozilla::TimeStamp::Now();
+
+#ifdef HAS_DLL_BLOCKLIST
+ DllBlocklist_Initialize();
+
+#ifdef DEBUG
+ // In order to be effective against AppInit DLLs, the blocklist must be
+ // initialized before user32.dll is loaded into the process (bug 932100).
+ if (GetModuleHandleA("user32.dll")) {
+ fprintf(stderr, "DLL blocklist was unable to intercept AppInit DLLs.\n");
+ }
+#endif
+#endif
+
+#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
+ // We are launching as a content process, delegate to the appropriate
+ // main
+ if (argc > 1 && IsArg(argv[1], "contentproc")) {
+ nsresult rv = InitXPCOMGlue(argv[0], nullptr);
+ if (NS_FAILED(rv)) {
+ return 255;
+ }
+
+ int result = content_process_main(argc, argv);
+
+ // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
+ NS_LogTerm();
+
+ return result;
+ }
+#endif
+
+
+ nsIFile *xreDirectory;
+
+ nsresult rv = InitXPCOMGlue(argv[0], &xreDirectory);
+ if (NS_FAILED(rv)) {
+ return 255;
+ }
+
+ XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
+
+#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
+ XRE_EnableSameExecutableForContentProc();
+#endif
+
+ int result = do_main(argc, argv, envp, xreDirectory);
+
+ NS_LogTerm();
+
+#ifdef XP_MACOSX
+ // Allow writes again. While we would like to catch writes from static
+ // destructors to allow early exits to use _exit, we know that there is
+ // at least one such write that we don't control (see bug 826029). For
+ // now we enable writes again and early exits will have to use exit instead
+ // of _exit.
+ XRE_StopLateWriteChecks();
+#endif
+
+ return result;
+}
diff --git a/app/palemoon.exe.manifest b/app/palemoon.exe.manifest
new file mode 100644
index 0000000..465effa
--- /dev/null
+++ b/app/palemoon.exe.manifest
@@ -0,0 +1,48 @@
+
+
+
+Pale Moon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/permissions b/app/permissions
new file mode 100644
index 0000000..4d90be8
--- /dev/null
+++ b/app/permissions
@@ -0,0 +1,14 @@
+# This file has default permissions for the permission manager.
+# The file-format is strict:
+# * matchtype \t type \t permission \t host
+# * "origin" should be used for matchtype, "host" is supported for legacy reasons
+# * type is a string that identifies the type of permission (e.g. "cookie")
+# * permission is an integer between 1 and 15
+# See nsPermissionManager.cpp for more...
+
+# XPInstall
+origin install 1 http://www.palemoon.org
+origin install 1 https://www.palemoon.org
+
+origin install 1 http://addons.palemoon.org
+origin install 1 https://addons.palemoon.org
diff --git a/app/profile/channel-prefs.js b/app/profile/channel-prefs.js
new file mode 100644
index 0000000..feb27c1
--- /dev/null
+++ b/app/profile/channel-prefs.js
@@ -0,0 +1,6 @@
+#filter substitution
+/* 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/. */
+
+pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
diff --git a/app/profile/extensions/moz.build b/app/profile/extensions/moz.build
new file mode 100644
index 0000000..df43182
--- /dev/null
+++ b/app/profile/extensions/moz.build
@@ -0,0 +1,7 @@
+# -*- 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/.
+
+DIRS += ['{972ce4c6-7e08-4474-a285-3208198ce6fd}']
diff --git a/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
new file mode 100644
index 0000000..ff9319d
--- /dev/null
+++ b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
@@ -0,0 +1,10 @@
+#
+# 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/.
+
+FILES := \
+ install.rdf.in \
+ $(NULL)
+FILES_PATH = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
+PP_TARGETS := FILES
diff --git a/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
new file mode 100644
index 0000000..f495013
--- /dev/null
+++ b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
@@ -0,0 +1,40 @@
+
+
+
+
+#filter substitution
+
+
+
+
+ {972ce4c6-7e08-4474-a285-3208198ce6fd}
+ @MOZ_APP_VERSION@
+
+
+
+
+ @MOZ_APP_ID@
+ @MOZ_APP_VERSION@
+ @MOZ_APP_VERSION@
+
+
+
+
+ Default
+ The default theme.
+
+
+ Moonchild Productions
+ Mozilla Contributors
+
+
+ true
+
+ classic/1.0
+
+
+
diff --git a/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
new file mode 100644
index 0000000..e14ac8e
--- /dev/null
+++ b/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
@@ -0,0 +1,8 @@
+# -*- 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/.
+
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['MOZ_APP_ID'] = CONFIG['MOZ_APP_ID']
\ No newline at end of file
diff --git a/app/profile/pagethemes.rdf b/app/profile/pagethemes.rdf
new file mode 100644
index 0000000..3d09b95
--- /dev/null
+++ b/app/profile/pagethemes.rdf
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/app/profile/palemoon.js b/app/profile/palemoon.js
new file mode 100644
index 0000000..b7698a8
--- /dev/null
+++ b/app/profile/palemoon.js
@@ -0,0 +1,1205 @@
+# -*- Mode: JavaScript; tab-width: 4; 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/.
+
+// XXX Toolkit-specific preferences should be moved into toolkit.js
+
+#filter substitution
+
+#
+# SYNTAX HINTS:
+#
+# - Dashes are delimiters; use underscores instead.
+# - The first character after a period must be alphabetic.
+# - Computed values (e.g. 50 * 1024) don't work.
+#
+
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+#define UNIX_BUT_NOT_MAC
+#endif
+#endif
+
+pref("browser.chromeURL","chrome://browser/content/");
+pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
+
+// Display the "Get Add-ons" pane in the Add-on Manager
+pref("extensions.getAddons.showPane", true);
+
+// Disables some extra Extension System Logging (can increase performance)
+pref("extensions.logging.enabled", false);
+
+// Disables strict compatibility, making addons compatible-by-default.
+pref("extensions.strictCompatibility", false);
+
+// Specifies a minimum maxVersion an addon needs to say it's compatible with
+// for it to be compatible by default.
+pref("extensions.minCompatibleAppVersion", "1.5");
+
+#define AM_DOMAIN addons.palemoon.org
+#define AM_AUS_ARGS reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%
+
+// Preferences for AMO integration
+pref("extensions.getAddons.cache.enabled", false);
+pref("extensions.getAddons.maxResults", 10);
+pref("extensions.getAddons.get.url", "https://@AM_DOMAIN@/?component=integration&type=internal&request=get&addonguid=%IDS%&os=%OS%&version=%VERSION%");
+pref("extensions.getAddons.getWithPerformance.url", "https://@AM_DOMAIN@/?component=integration&type=internal&request=get&addonguid=%IDS%&os=%OS%&version=%VERSION%");
+pref("extensions.getAddons.search.browseURL", "https://@AM_DOMAIN@/search/?terms=%TERMS%");
+pref("extensions.getAddons.search.url", "https://@AM_DOMAIN@/?component=integration&type=internal&request=search&q=%TERMS%&locale=%LOCALE%&os=%OS%&version=%VERSION%");
+pref("extensions.webservice.discoverURL", "http://@AM_DOMAIN@/?component=discover");
+pref("extensions.getAddons.recommended.url", "https://@AM_DOMAIN@/?component=integration&type=internal&request=recommended&locale=%LOCALE%&os=%OS%");
+pref("extensions.getAddons.browseAddons", "http://@AM_DOMAIN@/");
+pref("extensions.getAddons.recommended.browseURL", "https://@AM_DOMAIN@/?component=integration&type=external&request=recommended");
+
+// Blocklist preferences
+pref("extensions.blocklist.enabled", false); // Disable blocklist
+pref("extensions.blocklist.interval", 0); // Never auto-update blocklist
+pref("extensions.blocklist.level.updated", false);
+// Controls what level the blocklist switches from warning about items to forcibly
+// blocking them.
+pref("extensions.blocklist.level", 2);
+pref("extensions.blocklist.url", "https://blocklist.palemoon.org/?version=%VERSION%");
+pref("extensions.blocklist.detailsURL", "https://blocklist.palemoon.org/about.shtml");
+pref("extensions.blocklist.itemURL", "https://blocklist.palemoon.org/info/?id=%blockID%");
+
+pref("extensions.update.autoUpdateDefault", false);
+
+// Disable add-ons that are not installed by the user in all scopes by default.
+// See the SCOPE constants in AddonManager.jsm for values to use here.
+pref("extensions.autoDisableScopes", 15);
+
+// Dictionary download preference
+pref("browser.dictionaries.download.url", "https://@AM_DOMAIN@/dictionaries/");
+
+// Get More Tools link URL
+pref("browser.getdevtools.url","https://@AM_DOMAIN@/?component=integration&type=external&request=devtools");
+
+// Feedback URL
+pref("browser.feedback.url", "https://forum.palemoon.org");
+
+// Help button in slow startup dialog
+pref("browser.slowstartup.help.url", "http://www.palemoon.org/support/slowstartup.shtml");
+
+// Whether to escape to a content-less page if a user presses "Get me out of here"
+// on a network error page (e.g. cert error)
+pref("browser.escape_to_blank", false);
+
+// The minimum delay in seconds for the timer to fire.
+// default=2 minutes
+pref("app.update.timerMinimumDelay", 0);
+
+// App-specific update preferences
+
+// The interval to check for updates (app.update.interval) is defined in
+// palemoon-branding.js
+
+// Alternative windowtype for an application update user interface window. When
+// a window with this windowtype is open the application update service won't
+// open the normal application update user interface window.
+pref("app.update.altwindowtype", "Browser:About");
+
+// Enables some extra Application Update Logging (can reduce performance)
+pref("app.update.log", false);
+
+// The number of general background check failures to allow before notifying the
+// user of the failure. User initiated update checks always notify the user of
+// the failure.
+pref("app.update.backgroundMaxErrors", 10);
+
+// When |app.update.cert.requireBuiltIn| is true or not specified the
+// final certificate and all certificates the connection is redirected to before
+// the final certificate for the url specified in the |app.update.url|
+// preference must be built-in.
+pref("app.update.cert.requireBuiltIn", false);
+
+// When |app.update.cert.checkAttributes| is true or not specified the
+// certificate attributes specified in the |app.update.certs.| preference branch
+// are checked against the certificate for the url specified by the
+// |app.update.url| preference.
+pref("app.update.cert.checkAttributes", true);
+
+// The number of certificate attribute check failures to allow for background
+// update checks before notifying the user of the failure. User initiated update
+// checks always notify the user of the certificate attribute check failure.
+pref("app.update.cert.maxErrors", 5);
+
+// The |app.update.certs.| preference branch contains branches that are
+// sequentially numbered starting at 1 that contain attribute name / value
+// pairs for the certificate used by the server that hosts the update xml file
+// as specified in the |app.update.url| preference. When these preferences are
+// present the following conditions apply for a successful update check:
+// 1. the uri scheme must be https
+// 2. the preference name must exist as an attribute name on the certificate and
+// the value for the name must be the same as the value for the attribute name
+// on the certificate.
+// If these conditions aren't met it will be treated the same as when there is
+// no update available. This validation will not be performed when the
+// |app.update.url.override| user preference has been set for testing updates or
+// when the |app.update.cert.checkAttributes| preference is set to false. Also,
+// the |app.update.url.override| preference should ONLY be used for testing.
+pref("app.update.certs.1.issuerName", "CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB");
+pref("app.update.certs.1.commonName", "*.palemoon.org");
+
+// Whether or not app updates are enabled
+pref("app.update.enabled", false);
+
+// This preference turns on app.update.mode and allows automatic download and
+// install to take place. We use a separate boolean toggle for this to make
+// the UI easier to construct.
+pref("app.update.auto", false);
+
+// See chart in nsUpdateService.js source for more details
+pref("app.update.mode", 1);
+
+// If set to true, the Update Service will present no UI for any event.
+pref("app.update.silent", false);
+
+// If set to true, the Update Service will apply updates in the background
+// when it finishes downloading them.
+pref("app.update.staging.enabled", true);
+
+// app.update.url.manual is in branding section
+// app.update.url.details is in branding section
+
+// User-settable override to app.update.url for testing purposes.
+//pref("app.update.url.override", "");
+
+// app.update.interval is in branding section
+// app.update.promptWaitTime is in branding section
+
+// Show the Update Checking/Ready UI when the user was idle for x seconds
+pref("app.update.idletime", 180);
+
+// Whether or not we show a dialog box informing the user that the update was
+// successfully applied. This is off in Firefox by default since we show a
+// upgrade start page instead! Other apps may wish to show this UI, and supply
+// a whatsNewURL field in their brand.properties that contains a link to a page
+// which tells users what's new in this new update.
+pref("app.update.showInstalledUI", false);
+
+// 0 = suppress prompting for incompatibilities if there are updates available
+// to newer versions of installed addons that resolve them.
+// 1 = suppress prompting for incompatibilities only if there are VersionInfo
+// updates available to installed addons that resolve them, not newer
+// versions.
+pref("app.update.incompatible.mode", 0);
+
+// Symmetric (can be overridden by individual extensions) update preferences.
+// e.g.
+// extensions.{GUID}.update.enabled
+// extensions.{GUID}.update.url
+// .. etc ..
+//
+pref("extensions.update.enabled", false);
+pref("extensions.update.url", "https://@AM_DOMAIN@/?component=aus&@AM_AUS_ARGS@");
+//pref("extensions.update.background.url", "https://@AM_DOMAIN@/?component=aus&@AM_AUS_ARGS@");
+pref("extensions.update.interval", 0); // Do NOT check for updates to Extensions and
+ // Themes
+// Non-symmetric (not shared by extensions) extension-specific [update] preferences
+pref("extensions.dss.enabled", false); // Dynamic Skin Switching
+pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
+ // restart.
+
+pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name", "chrome://browser/locale/browser.properties");
+pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description", "chrome://browser/locale/browser.properties");
+
+pref("xpinstall.whitelist.required", false);
+// Allow installing XPI add-ons by direct URL requests (no referrer)
+pref("xpinstall.whitelist.directRequest", true);
+// Allow installing XPI add-ons from file referrers (chrome/file)
+pref("xpinstall.whitelist.fileRequest", true);
+
+pref("extensions.install.requireBuiltInCerts", false);
+// Only allow installation of extensions from https, chrome or file schemes
+pref("extensions.install.requireSecureOrigin", false);
+// Allow installation of distribution/bundles extensions
+pref("extensions.installDistroAddons", true);
+
+pref("lightweightThemes.animation.enabled", false);
+
+pref("keyword.enabled", true);
+
+pref("general.useragent.locale", "@AB_CD@");
+pref("general.skins.selectedSkin", "classic/1.0");
+
+// Native UA mode by default for unbranded
+pref("general.useragent.compatMode", 0);
+pref("general.useragent.compatMode.gecko", false);
+pref("general.useragent.compatMode.firefox", false);
+
+pref("general.smoothScroll", true);
+#ifdef UNIX_BUT_NOT_MAC
+pref("general.autoScroll", false);
+#else
+pref("general.autoScroll", true);
+#endif
+
+pref("general.useragent.complexOverride.moodle", false); // bug 797703
+
+// At startup, check if we're the default browser and prompt user if not.
+pref("browser.shell.checkDefaultBrowser", true);
+pref("browser.shell.shortcutFavicons",true);
+pref("browser.shell.mostRecentDateSetAsDefault", "");
+pref("browser.shell.skipDefaultBrowserCheckOnFirstRun", false);
+pref("browser.shell.skipDefaultBrowserCheck", true);
+pref("browser.shell.defaultBrowserCheckCount", 0);
+pref("browser.defaultbrowser.notificationbar", false);
+
+// 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
+// The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
+pref("browser.startup.page", 0);
+pref("browser.startup.homepage", "https://wiby.me");
+
+pref("browser.slowStartup.notificationDisabled", false);
+pref("browser.slowStartup.timeThreshold", 60000);
+pref("browser.slowStartup.maxSamples", 5);
+
+pref("browser.enable_automatic_image_resizing", true);
+pref("browser.chrome.site_icons", true);
+pref("browser.chrome.favicons", true);
+// If enabled, will process favicons by drawing them on a canvas,
+// optimizing display size for the UI. This also strips animations.
+pref("browser.chrome.favicons.process", false);
+// browser.warnOnQuit == false will override all other possible prompts when quitting or restarting
+pref("browser.warnOnQuit", true);
+// browser.showQuitWarning specifically controls the quit warning dialog. We
+// might still show the window closing dialog with showQuitWarning == false.
+pref("browser.showQuitWarning", false);
+pref("browser.fullscreen.autohide", true);
+pref("browser.fullscreen.animateUp", 1);
+pref("browser.overlink-delay", 80);
+
+pref("browser.urlbar.clickSelectsAll", true);
+pref("browser.urlbar.doubleClickSelectsAll", false);
+pref("browser.urlbar.autoFill", true);
+pref("browser.urlbar.autoFill.typed", true);
+// 0: Match anywhere (e.g., middle of words)
+// 1: Match on word boundaries and then try matching anywhere
+// 2: Match only on word boundaries (e.g., after / or .)
+// 3: Match at the beginning of the url or title
+pref("browser.urlbar.matchBehavior", 1);
+pref("browser.urlbar.filter.javascript", true);
+
+// the maximum number of results to show in autocomplete when doing richResults
+pref("browser.urlbar.maxRichResults", 12);
+// The amount of time (ms) to wait after the user has stopped typing
+// before starting to perform autocomplete. 50 is the default set in
+// autocomplete.xml.
+pref("browser.urlbar.delay", 50);
+
+// The special characters below can be typed into the urlbar to either restrict
+// the search to visited history, bookmarked, tagged pages; or force a match on
+// just the title text or url.
+pref("browser.urlbar.restrict.history", "^");
+pref("browser.urlbar.restrict.bookmark", "*");
+pref("browser.urlbar.restrict.tag", "+");
+pref("browser.urlbar.restrict.openpage", "%");
+pref("browser.urlbar.restrict.typed", "~");
+pref("browser.urlbar.match.title", "#");
+pref("browser.urlbar.match.url", "@");
+
+// The default behavior for the urlbar can be configured to use any combination
+// of the match filters with each additional filter adding more results (union).
+pref("browser.urlbar.suggest.history", true);
+pref("browser.urlbar.suggest.bookmark", true);
+pref("browser.urlbar.suggest.openpage", true);
+
+// Restrictions to current suggestions can also be applied (intersection).
+// Typed suggestion works only if history is set to true.
+pref("browser.urlbar.suggest.history.onlyTyped", false);
+
+pref("browser.urlbar.formatting.enabled", true);
+pref("browser.urlbar.trimURLs", false);
+
+// Display punycode in identity panel:
+// 0 = Display IDN name
+// 1 = Display punycode name for DV domains
+// 2 = Also display punycode for HTTP sites if IDN name used
+pref("browser.identity.display_punycode", 1);
+
+// Address bar RSS icon control, show by default
+pref("browser.urlbar.rss", true);
+
+pref("browser.altClickSave", true);
+
+// Enable logging downloads operations to the Error Console.
+pref("browser.download.debug", false);
+
+// Number of milliseconds to wait for the http headers (and thus
+// the Content-Disposition filename) before giving up and falling back to
+// picking a filename without that info in hand so that the user sees some
+// feedback from their action.
+pref("browser.download.saveLinkAsFilenameTimeout", 4000);
+
+// Do not use default download location as standard, but ask.
+pref("browser.download.useDownloadDir", false);
+
+pref("browser.download.folderList", 1);
+pref("browser.download.manager.showAlertOnComplete", true);
+pref("browser.download.manager.showAlertInterval", 2000);
+pref("browser.download.manager.retention", 2);
+pref("browser.download.manager.showWhenStarting", true);
+pref("browser.download.manager.closeWhenDone", false);
+pref("browser.download.manager.focusWhenStarting", false);
+pref("browser.download.manager.flashCount", 10);
+pref("browser.download.manager.addToRecentDocs", true);
+pref("browser.download.manager.quitBehavior", 2);
+pref("browser.download.manager.scanWhenDone", true);
+pref("browser.download.manager.resumeOnWakeDelay", 10000);
+
+// This records whether or not the panel has been shown at least once.
+pref("browser.download.panel.shown", false);
+
+// This records whether or not at least one session with the Downloads Panel
+// enabled has been completed already.
+pref("browser.download.panel.firstSessionCompleted", false);
+
+// search engines URL
+pref("browser.search.searchEnginesURL", "https://@AM_DOMAIN@/?component=integration&type=external&request=searchplugins");
+
+// pointer to the default engine name
+pref("browser.search.defaultenginename", "chrome://browser-region/locale/region.properties");
+
+// disable logging for the search service by default
+pref("browser.search.log", false);
+
+// Ordering of Search Engines in the Engine list.
+pref("browser.search.order.1", "chrome://browser-region/locale/region.properties");
+pref("browser.search.order.2", "chrome://browser-region/locale/region.properties");
+pref("browser.search.order.3", "chrome://browser-region/locale/region.properties");
+pref("browser.search.order.4", "chrome://browser-region/locale/region.properties");
+
+// search bar results always open in a new tab
+pref("browser.search.openintab", false);
+
+// do not swap focus to the context search tab.
+pref("browser.search.context.loadInBackground", true);
+
+// if no result, add the search term so that the panel of the new UI is shown anyway
+pref("browser.search.showOneOffButtons", true);
+
+// send ping to the server to update
+pref("browser.search.update", true);
+
+// disable logging for the search service update system by default
+pref("browser.search.update.log", false);
+
+// Check whether we need to perform engine updates every 6 hours
+pref("browser.search.update.interval", 21600);
+
+// enable search suggestions by default
+pref("browser.search.suggest.enabled", true);
+
+#ifdef MOZ_OFFICIAL_BRANDING
+// {moz:official} expands to "official"
+pref("browser.search.official", true);
+#endif
+
+pref("browser.sessionhistory.max_entries", 50);
+
+// handle links targeting new windows
+// 1=current window/tab, 2=new window, 3=new tab in most recent window
+pref("browser.link.open_newwindow", 3);
+
+// handle external links (i.e. links opened from a different application)
+// default: use browser.link.open_newwindow
+// 1-3: see browser.link.open_newwindow for interpretation
+pref("browser.link.open_newwindow.override.external", -1);
+
+// 0: no restrictions - divert everything
+// 1: don't divert window.open at all
+// 2: don't divert window.open with features
+pref("browser.link.open_newwindow.restriction", 2);
+
+// If true, this pref causes windows opened by window.open to be forced into new
+// tabs (rather than potentially opening separate windows, depending on
+// window.open arguments) when the browser is in fullscreen mode.
+// We set this differently on Mac because the fullscreen implementation there is
+// different.
+#ifdef XP_MACOSX
+pref("browser.link.open_newwindow.disabled_in_fullscreen", true);
+#else
+pref("browser.link.open_newwindow.disabled_in_fullscreen", false);
+#endif
+
+// Tabbed browser
+pref("browser.tabs.autoHide", false);
+pref("browser.tabs.closeWindowWithLastTab", true);
+pref("browser.tabs.insertRelatedAfterCurrent", true);
+pref("browser.tabs.warnOnClose", true);
+pref("browser.tabs.warnOnCloseOtherTabs", true);
+pref("browser.tabs.warnOnOpen", true);
+pref("browser.tabs.maxOpenBeforeWarn", 15);
+pref("browser.tabs.loadInBackground", true);
+pref("browser.tabs.opentabfor.middleclick", true);
+pref("browser.tabs.loadDivertedInBackground", false);
+pref("browser.tabs.loadBookmarksInBackground", false);
+pref("browser.tabs.noWindowActivationOnExternal", false);
+pref("browser.tabs.tabClipWidth", 140);
+pref("browser.tabs.animate", true);
+pref("browser.tabs.onTop", false);
+#ifdef XP_WIN
+pref("browser.tabs.drawInTitlebar", true);
+#else
+pref("browser.tabs.drawInTitlebar", false);
+#endif
+pref("browser.tabs.resize_immediately", false);
+
+// Where to show tab close buttons:
+// 0 on active tab only
+// 1 on all tabs until tabClipWidth is reached, then active tab only
+// 2 no close buttons at all
+// 3 at the end of the tabstrip
+pref("browser.tabs.closeButtons", 1);
+
+// When tabs opened by links in other tabs via a combination of
+// browser.link.open_newwindow being set to 3 and target="_blank" etc are
+// closed:
+// true return to the tab that opened this tab (its owner)
+// false return to the adjacent tab (old default)
+pref("browser.tabs.selectOwnerOnClose", true);
+
+pref("browser.tabs.showAudioPlayingIcon", true);
+// This should match Chromium's audio indicator delay.
+pref("browser.tabs.delayHidingAudioPlayingIconMS", 3000);
+
+pref("browser.allTabs.previews", true);
+pref("browser.ctrlTab.previews", true);
+pref("browser.ctrlTab.recentlyUsedLimit", 7);
+
+// By default, do not export HTML at shutdown.
+// If true, at shutdown the bookmarks in your menu and toolbar will
+// be exported as HTML to the bookmarks.html file.
+pref("browser.bookmarks.autoExportHTML", false);
+
+// The maximum number of daily bookmark backups to
+// keep in {PROFILEDIR}/bookmarkbackups. Special values:
+// -1: unlimited
+// 0: no backups created (and deletes all existing backups)
+pref("browser.bookmarks.max_backups", 10);
+
+// Scripts & Windows prefs
+pref("dom.disable_open_during_load", true);
+pref("javascript.options.showInConsole", true);
+#ifdef DEBUG
+pref("general.warnOnAboutConfig", false);
+#endif
+
+// This is the pref to control the location bar, change this to true to
+// force this - this makes the origin of popup windows more obvious to avoid
+// spoofing. We would rather not do it by default because it affects UE for web
+// applications, but without it there isn't a really good way to prevent chrome
+// spoofing, see bug 337344
+pref("dom.disable_window_open_feature.location", true);
+// Allow JS to set status messages
+pref("dom.disable_window_status_change", false);
+// allow JS to move and resize existing windows
+pref("dom.disable_window_move_resize", false);
+// prevent JS from monkeying with window focus, etc
+pref("dom.disable_window_flip", true);
+
+// Disable touch events on Desktop Firefox by default until they are properly
+// supported (bug 736048)
+pref("dom.w3c_touch_events.enabled", 0);
+
+// popups.policy 1=allow,2=reject
+pref("privacy.popups.policy", 1);
+pref("privacy.popups.usecustom", true);
+pref("privacy.popups.showBrowserMessage", true);
+
+pref("privacy.item.cookies", false);
+
+pref("privacy.clearOnShutdown.history", true);
+pref("privacy.clearOnShutdown.formdata", true);
+pref("privacy.clearOnShutdown.passwords", false);
+pref("privacy.clearOnShutdown.downloads", true);
+pref("privacy.clearOnShutdown.cookies", true);
+pref("privacy.clearOnShutdown.cache", true);
+pref("privacy.clearOnShutdown.sessions", true);
+pref("privacy.clearOnShutdown.offlineApps", false);
+pref("privacy.clearOnShutdown.siteSettings", false);
+pref("privacy.clearOnShutdown.connectivityData", false);
+
+pref("privacy.cpd.history", true);
+pref("privacy.cpd.formdata", true);
+pref("privacy.cpd.passwords", false);
+pref("privacy.cpd.downloads", true);
+pref("privacy.cpd.cookies", true);
+pref("privacy.cpd.cache", true);
+pref("privacy.cpd.sessions", true);
+pref("privacy.cpd.offlineApps", false);
+pref("privacy.cpd.siteSettings", false);
+pref("privacy.cpd.connectivityData", false);
+
+// What default should we use for the time span in the sanitizer:
+// 0 - Clear everything
+// 1 - Last Hour
+// 2 - Last 2 Hours
+// 3 - Last 4 Hours
+// 4 - Today
+pref("privacy.sanitize.timeSpan", 1);
+pref("privacy.sanitize.sanitizeOnShutdown", false);
+
+pref("privacy.sanitize.migrateFx3Prefs", false);
+
+pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols
+
+// Disable speculative half-open connections on Pale Moon
+pref("network.http.speculative-parallel-limit", 0);
+
+// Enable pipelining over SSL
+pref("network.http.pipelining.ssl", true);
+
+// Disable predictor/prefetch of URIs
+pref("network.predictor.enabled", false);
+pref("network.prefetch-next", false);
+
+// Disable DNS prefetching
+pref("network.dns.disablePrefetch", true);
+
+// Tune DNS lookups
+pref("network.dnsCacheEntries", 800);
+pref("network.dnsCacheExpiration", 180); // 3 minutes if no TTL given by DNS resolver
+pref("network.dns.get-ttl", true); // Get and use DNS resolver TTL
+pref("network.dnsCacheExpirationGracePeriod", 60); // 1 minute grace period for stale entry
+
+// simple gestures support
+pref("browser.gesture.swipe.left", "Browser:BackOrBackDuplicate");
+pref("browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate");
+pref("browser.gesture.swipe.up", "cmd_scrollTop");
+pref("browser.gesture.swipe.down", "cmd_scrollBottom");
+#ifdef XP_MACOSX
+pref("browser.gesture.pinch.latched", true);
+pref("browser.gesture.pinch.threshold", 150);
+#else
+pref("browser.gesture.pinch.latched", false);
+pref("browser.gesture.pinch.threshold", 25);
+#endif
+#ifdef XP_WIN
+// Enabled for touch input display zoom.
+pref("browser.gesture.pinch.out", "cmd_fullZoomEnlarge");
+pref("browser.gesture.pinch.in", "cmd_fullZoomReduce");
+pref("browser.gesture.pinch.out.shift", "cmd_fullZoomReset");
+pref("browser.gesture.pinch.in.shift", "cmd_fullZoomReset");
+#else
+// Disabled by default due to issues with track pad input.
+pref("browser.gesture.pinch.out", "");
+pref("browser.gesture.pinch.in", "");
+pref("browser.gesture.pinch.out.shift", "");
+pref("browser.gesture.pinch.in.shift", "");
+#endif
+pref("browser.gesture.twist.latched", false);
+pref("browser.gesture.twist.threshold", 0);
+pref("browser.gesture.twist.right", "cmd_gestureRotateRight");
+pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
+pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
+pref("browser.gesture.tap", "cmd_fullZoomReset");
+
+pref("browser.snapshots.limit", 0);
+
+// 0: Nothing happens
+// 1: Scroll contents
+// 2: Go back or go forward, in your history
+// 3: Zoom in or out
+// 4: Scroll contents with X and Y swapped
+#ifdef XP_MACOSX
+// On OS X, if the wheel has one axis only, shift+wheel comes through as a
+// horizontal scroll event. Thus, we can't assign anything other than normal
+// scrolling to shift+wheel.
+pref("mousewheel.with_alt.action", 2);
+pref("mousewheel.with_shift.action", 1);
+// On MacOS X, control+wheel is typically handled by system and we don't
+// receive the event. So, command key which is the main modifier key for
+// acceleration is the best modifier for zoom-in/out. However, we should keep
+// the control key setting for backward compatibility.
+pref("mousewheel.with_meta.action", 3); // command key on Mac
+// Disable control-/meta-modified horizontal mousewheel events, since
+// those are used on Mac as part of modified swipe gestures (e.g.
+// Left swipe+Cmd = go back in a new tab).
+pref("mousewheel.with_control.action.override_x", 0);
+pref("mousewheel.with_meta.action.override_x", 0);
+#else
+pref("mousewheel.with_alt.action", 1);
+pref("mousewheel.with_shift.action", 2);
+pref("mousewheel.with_meta.action", 1); // win key on Win, Super/Hyper on Linux
+#endif
+pref("mousewheel.with_control.action",3);
+pref("mousewheel.with_win.action", 1);
+
+pref("browser.xul.error_pages.enabled", true);
+pref("browser.xul.error_pages.expert_bad_cert", false);
+
+// Work Offline is best manually managed by the user.
+pref("network.manage-offline-status", false);
+
+// We want to make sure mail URLs are handled externally...
+pref("network.protocol-handler.external.mailto", true); // for mail
+pref("network.protocol-handler.external.news", true); // for news
+pref("network.protocol-handler.external.snews", true); // for secure news
+pref("network.protocol-handler.external.nntp", true); // also news
+#ifdef XP_WIN
+pref("network.protocol-handler.external.ms-windows-store", true);
+#endif
+
+// ...without warning dialogs
+pref("network.protocol-handler.warn-external.mailto", false);
+pref("network.protocol-handler.warn-external.news", false);
+pref("network.protocol-handler.warn-external.snews", false);
+pref("network.protocol-handler.warn-external.nntp", false);
+#ifdef XP_WIN
+pref("network.protocol-handler.warn-external.ms-windows-store", false);
+#endif
+
+// By default, all protocol handlers are exposed. This means that
+// the browser will respond to openURL commands for all URL types.
+// It will also try to open link clicks inside the browser before
+// failing over to the system handlers.
+pref("network.protocol-handler.expose-all", true);
+pref("network.protocol-handler.expose.mailto", false);
+pref("network.protocol-handler.expose.news", false);
+pref("network.protocol-handler.expose.snews", false);
+pref("network.protocol-handler.expose.nntp", false);
+
+pref("accessibility.typeaheadfind", false);
+pref("accessibility.typeaheadfind.timeout", 5000);
+pref("accessibility.typeaheadfind.linksonly", false);
+pref("accessibility.typeaheadfind.flashBar", 1);
+
+// by default we show an infobar message when pages require plugins that are blocked, or are outdated
+pref("plugins.hide_infobar_for_blocked_plugin", false);
+pref("plugins.hide_infobar_for_outdated_plugin", false);
+
+// Pale Moon:pref to always show the plugin indicator or not (default=false)
+pref("plugins.always_show_indicator", false);
+
+pref("plugins.update.url", "https://aus.palemoon.org/plugincheck/");
+pref("plugins.update.notifyUser", false);
+
+//Enable tri-state option (Always/Never/Ask)
+pref("plugins.click_to_play", true);
+
+#ifdef XP_WIN
+pref("browser.preferences.instantApply", false);
+#else
+pref("browser.preferences.instantApply", true);
+#endif
+#ifdef XP_MACOSX
+pref("browser.preferences.animateFadeIn", true);
+#else
+pref("browser.preferences.animateFadeIn", false);
+#endif
+
+pref("browser.download.show_plugins_in_list", true);
+pref("browser.download.hide_plugins_without_extensions", true);
+
+// Backspace and Shift+Backspace behavior
+// 0 goes Back/Forward
+// 1 act like PgUp/PgDown
+// 2 and other values, nothing
+#ifdef UNIX_BUT_NOT_MAC
+pref("browser.backspace_action", 2);
+#else
+pref("browser.backspace_action", 0);
+#endif
+
+// Pale Moon never eats the space with word selection, regardless of O.S.
+pref("layout.word_select.eat_space_to_next_word", false);
+
+// this will automatically enable inline spellchecking (if it is available) for
+// editable elements in HTML
+// 0 = spellcheck nothing
+// 1 = check multi-line controls [default]
+// 2 = check multi/single line controls
+pref("layout.spellcheckDefault", 1);
+
+pref("browser.send_pings", false);
+
+/* initial web feed readers list */
+pref("browser.contentHandlers.types.0.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.0.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.0.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.1.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.1.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.1.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.2.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.2.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.2.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.3.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.3.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.3.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.4.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.4.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.4.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.5.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.5.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.5.type", "application/vnd.mozilla.maybe.feed");
+
+pref("browser.feeds.handler", "ask");
+pref("browser.videoFeeds.handler", "ask");
+pref("browser.audioFeeds.handler", "ask");
+
+// At startup, if the handler service notices that the version number in the
+// region.properties file is newer than the version number in the handler
+// service datastore, it will add any new handlers it finds in the prefs (as
+// seeded by this file) to its datastore.
+pref("gecko.handlerService.defaultHandlersVersion", "chrome://browser-region/locale/region.properties");
+
+// The default set of web-based protocol handlers shown in the application
+// selection dialog for webcal: ; I've arbitrarily picked 4 default handlers
+// per protocol, but if some locale wants more than that (or defaults for some
+// protocol not currently listed here), we should go ahead and add those.
+
+// webcal
+pref("gecko.handlerService.schemes.webcal.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// mailto
+pref("gecko.handlerService.schemes.mailto.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// irc
+pref("gecko.handlerService.schemes.irc.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// ircs
+pref("gecko.handlerService.schemes.ircs.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// By default, we don't want protocol/content handlers to be registered from a different host, see bug 402287
+pref("gecko.handlerService.allowRegisterFromDifferentHost", false);
+
+pref("browser.geolocation.warning.infoURL", "http://www.palemoon.org/info-url/geolocation.shtml");
+pref("browser.mixedcontent.warning.infoURL", "http://www.palemoon.org/info-url/mixedcontent.shtml");
+pref("browser.push.warning.infoURL", "https://www.palemoon.org/info-url/push.shtml");
+
+pref("browser.EULA.version", 3);
+pref("browser.rights.version", 3);
+pref("browser.rights.3.shown", false);
+
+#ifdef DEBUG
+// Don't show the about:rights notification in debug builds.
+pref("browser.rights.override", true);
+#endif
+
+pref("browser.sessionstore.resume_from_crash", true);
+pref("browser.sessionstore.resume_session_once", false);
+
+// minimal interval between two save operations in milliseconds
+pref("browser.sessionstore.interval",60000);
+// maximum amount of POSTDATA to be saved in bytes per history entry (-1 = all of it)
+// (NB: POSTDATA will be saved either entirely or not at all)
+pref("browser.sessionstore.postdata", 0);
+// on which sites to save text data, POSTDATA and cookies
+// 0 = everywhere, 1 = unencrypted sites, 2 = nowhere
+pref("browser.sessionstore.privacy_level", 0);
+// the same as browser.sessionstore.privacy_level, but for saving deferred session data
+pref("browser.sessionstore.privacy_level_deferred", 1);
+// how many tabs can be reopened (per window)
+pref("browser.sessionstore.max_tabs_undo", 10);
+// how many windows can be reopened (per session) - on non-OS X platforms this
+// pref may be ignored when dealing with pop-up windows to ensure proper startup
+pref("browser.sessionstore.max_windows_undo", 3);
+// number of crashes that can occur before the about:sessionrestore page is displayed
+// (this pref has no effect if more than 6 hours have passed since the last crash)
+pref("browser.sessionstore.max_resumed_crashes", 1);
+// number of back button session history entries to save (-1 = all of them)
+pref("browser.sessionstore.max_serialize_back", 10);
+// number of forward button session history entries to save (-1 = all of them)
+pref("browser.sessionstore.max_serialize_forward", -1);
+// restore_on_demand overrides browser.sessionstore.max_concurrent_tabs
+// and restore_hidden_tabs. When true, tabs will not be restored until they are
+// focused (also applies to tabs that aren't visible). When false, the values
+// for browser.sessionstore.max_concurrent_tabs and restore_hidden_tabs are
+// respected. Selected tabs are always restored regardless of this pref.
+pref("browser.sessionstore.restore_on_demand", true);
+// The number of tabs that can restore concurrently.
+// Sane values are 1..10, default 3.
+pref("browser.sessionstore.max_concurrent_tabs", 3);
+// Whether to automatically restore hidden tabs (i.e., tabs in other tab groups) or not
+pref("browser.sessionstore.restore_hidden_tabs", false);
+// If restore_on_demand is set, pinned tabs are restored on startup by default.
+// When set to true, this pref overrides that behavior, and pinned tabs will only
+// be restored when they are focused.
+pref("browser.sessionstore.restore_pinned_tabs_on_demand", false);
+// Pale Moon: Allow the user to bypass cached versions of pages when restoring
+// tabs from a previous session
+// 0 = standard behavior: pull fully from cache
+// 1 = perform a soft refresh when restoring a tab (check network)
+// 2 = perform a hard refresh when restoring a tab (bypass cache completely)
+pref("browser.sessionstore.cache_behavior", 0);
+// Pale Moon: Allow exact positioning of windows to previous locations, even
+// if they would be outside of the screen bounds
+pref("browser.sessionstore.exactPos", false);
+
+// allow META refresh by default
+pref("accessibility.blockautorefresh", false);
+
+// Whether history is enabled or not.
+pref("places.history.enabled", true);
+
+// the (maximum) number of the recent visits to sample
+// when calculating frecency
+pref("places.frecency.numVisits", 10);
+
+// buckets (in days) for frecency calculation
+pref("places.frecency.firstBucketCutoff", 4);
+pref("places.frecency.secondBucketCutoff", 14);
+pref("places.frecency.thirdBucketCutoff", 31);
+pref("places.frecency.fourthBucketCutoff", 90);
+
+// weights for buckets for frecency calculations
+pref("places.frecency.firstBucketWeight", 100);
+pref("places.frecency.secondBucketWeight", 70);
+pref("places.frecency.thirdBucketWeight", 50);
+pref("places.frecency.fourthBucketWeight", 30);
+pref("places.frecency.defaultBucketWeight", 10);
+
+// bonus (in percent) for visit transition types for frecency calculations
+pref("places.frecency.embedVisitBonus", 0);
+pref("places.frecency.framedLinkVisitBonus", 0);
+pref("places.frecency.linkVisitBonus", 100);
+pref("places.frecency.typedVisitBonus", 2000);
+pref("places.frecency.bookmarkVisitBonus", 75);
+pref("places.frecency.downloadVisitBonus", 0);
+pref("places.frecency.permRedirectVisitBonus", 0);
+pref("places.frecency.tempRedirectVisitBonus", 0);
+pref("places.frecency.defaultVisitBonus", 0);
+
+// bonus (in percent) for place types for frecency calculations
+pref("places.frecency.unvisitedBookmarkBonus", 140);
+pref("places.frecency.unvisitedTypedBonus", 200);
+
+// Controls behavior of the "Add Exception" dialog launched from SSL error pages
+// 0 - don't pre-populate anything
+// 1 - pre-populate site URL, but don't fetch certificate
+// 2 - pre-populate site URL and pre-fetch certificate
+pref("browser.ssl_override_behavior", 2);
+
+// Controls the behavior of data storage for offline apps
+// 0 - Deny storage of offline app data without prompting (breaks sites!)
+// 1 - Ask the user if a website wants to store offline app data
+// 2 - Allow storage of offline app data without prompting (default)
+pref("offline-apps.permissions", 2);
+// True if storage of offline app data is allowed without prompting.
+pref("offline-apps.allow_by_default", true);
+// True if the user should be prompted when a web application supports
+// offline apps.
+pref("browser.offline-apps.notify", true);
+
+// if true, use full page zoom instead of text zoom
+pref("browser.zoom.full", true);
+
+// Whether or not to save and restore zoom levels on a per-site basis.
+pref("browser.zoom.siteSpecific", true);
+
+// Whether or not to update background tabs to the current zoom level.
+pref("browser.zoom.updateBackgroundTabs", true);
+
+// base URL for web-based support pages
+pref("app.support.baseURL", "http://www.palemoon.org/support/");
+
+// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
+pref("security.alternate_certificate_error_page", "certerror");
+
+// Whether to start the private browsing mode at application startup
+pref("browser.privatebrowsing.autostart", false);
+
+// Don't try to alter this pref, it'll be reset the next time you use the
+// bookmarking dialog
+pref("browser.bookmarks.editDialog.firstEditField", "namePicker");
+
+// Whether to use a panel that looks like an OS X sheet for customization
+#ifdef XP_MACOSX
+pref("toolbar.customization.usesheet", true);
+#else
+pref("toolbar.customization.usesheet", false);
+#endif
+
+#ifdef XP_MACOSX
+// On mac, the default pref is per-architecture
+pref("dom.ipc.plugins.enabled.i386", true);
+pref("dom.ipc.plugins.enabled.x86_64", true);
+#else
+pref("dom.ipc.plugins.enabled", true);
+#endif
+
+pref("browser.tabs.remote", false);
+
+// This pref governs whether we attempt to work around problems caused by
+// plugins using OS calls to manipulate the cursor while running out-of-
+// process. These workarounds all involve intercepting (hooking) certain
+// OS calls in the plugin process, then arranging to make certain OS calls
+// in the browser process. Eventually plugins will be required to use the
+// NPAPI to manipulate the cursor, and these workarounds will be removed.
+// See bug 621117.
+#ifdef XP_MACOSX
+pref("dom.ipc.plugins.nativeCursorSupport", true);
+#endif
+
+#ifdef XP_WIN
+pref("browser.taskbar.previews.enable", false);
+pref("browser.taskbar.previews.max", 20);
+pref("browser.taskbar.previews.cachetime", 5);
+pref("browser.taskbar.lists.enabled", true);
+pref("browser.taskbar.lists.frequent.enabled", true);
+pref("browser.taskbar.lists.recent.enabled", false);
+pref("browser.taskbar.lists.maxListItemCount", 7);
+pref("browser.taskbar.lists.tasks.enabled", true);
+pref("browser.taskbar.lists.refreshInSeconds", 120);
+#endif
+
+#ifdef MOZ_SERVICES_SYNC
+// Info when outdated sync detected
+pref("services.sync.outdated.url", "http://www.palemoon.org/sync/update/");
+// The sync engines to use.
+pref("services.sync.registerEngines", "Bookmarks,Form,History,Password,Prefs,Tab,Addons");
+// Preferences to be synced by default
+pref("services.sync.prefs.sync.accessibility.blockautorefresh", true);
+pref("services.sync.prefs.sync.accessibility.browsewithcaret", true);
+pref("services.sync.prefs.sync.accessibility.typeaheadfind", true);
+pref("services.sync.prefs.sync.accessibility.typeaheadfind.linksonly", true);
+pref("services.sync.prefs.sync.addons.ignoreUserEnabledChanges", true);
+
+// The addons prefs related to repository verification are intentionally
+// not synced for security reasons. If a system is compromised, a user
+// could weaken the pref locally, install an add-on from an untrusted
+// source, and this would propagate automatically to other,
+// uncompromised Sync-connected devices.
+pref("services.sync.prefs.sync.app.update.mode", true);
+pref("services.sync.prefs.sync.browser.download.manager.closeWhenDone", true);
+pref("services.sync.prefs.sync.browser.download.manager.retention", true);
+pref("services.sync.prefs.sync.browser.download.manager.scanWhenDone", true);
+pref("services.sync.prefs.sync.browser.download.manager.showWhenStarting", true);
+pref("services.sync.prefs.sync.browser.formfill.enable", true);
+pref("services.sync.prefs.sync.browser.link.open_newwindow", true);
+pref("services.sync.prefs.sync.browser.offline-apps.notify", true);
+pref("services.sync.prefs.sync.browser.search.selectedEngine", true);
+pref("services.sync.prefs.sync.browser.search.update", true);
+pref("services.sync.prefs.sync.browser.sessionstore.restore_on_demand", true);
+pref("services.sync.prefs.sync.browser.startup.homepage", true);
+pref("services.sync.prefs.sync.browser.startup.page", true);
+pref("services.sync.prefs.sync.browser.tabs.autoHide", true);
+pref("services.sync.prefs.sync.browser.tabs.closeButtons", true);
+pref("services.sync.prefs.sync.browser.tabs.loadInBackground", true);
+pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true);
+pref("services.sync.prefs.sync.browser.tabs.warnOnOpen", true);
+pref("services.sync.prefs.sync.browser.urlbar.autocomplete.enabled", true);
+pref("services.sync.prefs.sync.browser.urlbar.default.behavior", true);
+pref("services.sync.prefs.sync.browser.urlbar.maxRichResults", true);
+pref("services.sync.prefs.sync.dom.disable_open_during_load", true);
+pref("services.sync.prefs.sync.dom.disable_window_flip", true);
+pref("services.sync.prefs.sync.dom.disable_window_move_resize", true);
+pref("services.sync.prefs.sync.dom.event.contextmenu.enabled", true);
+pref("services.sync.prefs.sync.extensions.personas.current", true);
+pref("services.sync.prefs.sync.intl.accept_languages", true);
+pref("services.sync.prefs.sync.javascript.enabled", true);
+pref("services.sync.prefs.sync.layout.spellcheckDefault", true);
+pref("services.sync.prefs.sync.lightweightThemes.isThemeSelected", true);
+pref("services.sync.prefs.sync.lightweightThemes.usedThemes", true);
+pref("services.sync.prefs.sync.network.cookie.cookieBehavior", true);
+pref("services.sync.prefs.sync.network.cookie.lifetimePolicy", true);
+pref("services.sync.prefs.sync.permissions.default.image", true);
+pref("services.sync.prefs.sync.pref.advanced.images.disable_button.view_image", true);
+pref("services.sync.prefs.sync.pref.advanced.javascript.disable_button.advanced", true);
+pref("services.sync.prefs.sync.pref.downloads.disable_button.edit_actions", true);
+pref("services.sync.prefs.sync.pref.privacy.disable_button.cookie_exceptions", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.cache", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.cookies", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.downloads", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.formdata", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.history", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.offlineApps", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.passwords", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.sessions", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.siteSettings", true);
+pref("services.sync.prefs.sync.privacy.clearOnShutdown.connectivityData", true);
+pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
+pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
+pref("services.sync.prefs.sync.security.default_personal_cert", true);
+pref("services.sync.prefs.sync.security.tls.version.min", true);
+pref("services.sync.prefs.sync.security.tls.version.max", true);
+pref("services.sync.prefs.sync.signon.rememberSignons", true);
+pref("services.sync.prefs.sync.spellchecker.dictionary", true);
+pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
+#endif
+
+// Disable Geolocation services
+pref("geo.enabled", false);
+
+// Enable the error console
+pref("devtools.errorconsole.enabled", true);
+
+// Whether the character encoding menu is under the main Firefox button. This
+// preference is a string so that localizers can alter it.
+pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties");
+
+// Allow using tab-modal prompts when possible.
+pref("prompts.tab_modal.enabled", true);
+// Allow tab-modal prompts to switch tab focus
+pref("prompts.tab_modal.focusSwitch", true);
+
+// Defines the url to be used for new tabs.
+pref("browser.newtab.url", "about:logopage");
+pref("browser.newtab.choice", 1);
+
+// Activates preloading of the new tab url.
+pref("browser.newtab.preload", false);
+
+// Toggles the content of 'about:newtab'. Shows the grid when enabled.
+pref("browser.newtabpage.enabled", true);
+
+// Disables capturing of page thumbnails
+pref("browser.pagethumbnails.capturing_disabled", false);
+
+// enables showing basic placeholders for missing thumbnails
+pref("browser.newtabpage.thumbnailPlaceholder", false);
+
+// number of columns of newtab grid
+pref("browser.newtabpage.columns", 4);
+
+// number of rows of newtab grid
+pref("browser.newtabpage.rows", 3);
+
+// Enable the DOM fullscreen API.
+pref("full-screen-api.enabled", true);
+
+// about:permissions
+// Maximum number of sites to return from the places database.
+// 0-100 (currently)
+pref("permissions.places-sites-limit", 50);
+
+// Built-in default permissions.
+pref("permissions.manager.defaultsUrl", "resource://app/defaults/permissions");
+
+// Startup Crash Tracking
+// number of startup crashes that can occur before starting into safe mode automatically
+// (this pref has no effect if more than 6 hours have passed since the last crash)
+pref("toolkit.startup.max_resumed_crashes", 3);
+
+// The maximum amount of decoded image data we'll willingly keep around (we
+// might keep around more than this, but we'll try to get down to this value).
+// (This is intentionally on the high side; see bug 746055.)
+pref("image.mem.max_decoded_image_kb", 256000);
+
+// Turn on the CSP 1.0 parser for Content Security Policy headers
+pref("security.csp.speccompliant", true);
+
+// Block insecure active content on https pages
+pref("security.mixed_content.block_active_content", true);
+
+// Disable Microsoft Family Safety MitM support
+pref("security.family_safety.mode", 0);
+
+// Override the Gecko-default value of false for Pale Moon.
+pref("plain_text.wrap_long_lines", true);
+
+pref("media.webaudio.enabled", true);
+
+// If this turns true, Moz*Gesture events are not called stopPropagation()
+// before content.
+pref("dom.debug.propagate_gesture_events_through_content", false);
+
+// The request URL of the GeoLocation backend.
+pref("geo.wifi.uri", "http://ip-api.com/json/?fields=lat,lon,status,message");
+
+//Pale Moon padlock overlay preferences
+pref("browser.padlock.shown", true);
+/* Where to show the padlock
+ 1 = inside identity button, right side
+ 2 = inside identity button, left side
+ 3 = urlbar, right side (next to bookmark star)
+ 4 = statusbar
+ 5 = tabs bar, right side
+ 6-10 = same locations, classic style padlock */
+pref("browser.padlock.style", 1);
+// address bar border, 0 = no border, 1 = border, 2 = border only on secure sites
+pref("browser.padlock.urlbar_background", 2);
+
+//Pale Moon standalone image background color
+pref("browser.display.standalone_images.background_color", "#2E3B41");
+
+// These are the thumbnail width/height set in about:newtab.
+// If you change this, make sure the size is sufficient for tile sizes
+// in about:newtab. These values are in CSS pixels.
+pref("toolkit.pageThumbs.minWidth", 250);
+pref("toolkit.pageThumbs.minHeight", 180);
+
+// On GTK, we now default to showing the menubar only when alt is pressed:
+#ifdef MOZ_WIDGET_GTK
+pref("ui.key.menuAccessKeyFocuses", true);
+#endif
+
+// When a user cancels this number of authentication dialogs coming from
+// a single web page (eTLD+1) in a row, all following authentication dialogs
+// will be blocked (automatically canceled) for that page.
+// This counter is per-tab and per-domain to minimize false positives.
+// The counter resets when the page is reloaded from the UI
+// (content-reloads do NOT clear this to mitigate reloading tricks).
+pref("prompts.authentication_dialog_abuse_limit", 3);
+
+// ****************** s4e prefs ******************
+pref("status4evar.addonbar.borderStyle", false);
+pref("status4evar.addonbar.closeButton", false);
+pref("status4evar.addonbar.legacyShim", true);
+pref("status4evar.addonbar.windowGripper", true);
+
+pref("status4evar.advanced.status.detectFullScreen", false);
+pref("status4evar.advanced.status.detectVideo", true);
+
+pref("status4evar.download.button.action", 1);
+pref("status4evar.download.button.action.command", "");
+pref("status4evar.download.color.active", "#333399");
+pref("status4evar.download.color.paused", "#808080");
+pref("status4evar.download.force", false);
+pref("status4evar.download.label", 0);
+pref("status4evar.download.label.force", true);
+pref("status4evar.download.notify.animate", true);
+pref("status4evar.download.notify.timeout", 60);
+pref("status4evar.download.progress", 1);
+pref("status4evar.download.tooltip", 2);
+
+pref("status4evar.firstRun", true);
+
+pref("status4evar.progress.toolbar.css", "#333399");
+pref("status4evar.progress.toolbar.force", false);
+pref("status4evar.progress.toolbar.style", false);
+pref("status4evar.progress.toolbar.style.advanced", false);
+
+pref("status4evar.status", 1);
+pref("status4evar.status.default", true);
+pref("status4evar.status.network", true);
+pref("status4evar.status.network.xhr", true);
+pref("status4evar.status.timeout", 30);
+pref("status4evar.status.linkOver", 1);
+pref("status4evar.status.linkOver.delay.show", 0);
+pref("status4evar.status.linkOver.delay.hide", 0);
+
+pref("status4evar.status.toolbar.maxLength", 0);
+
+pref("status4evar.status.popup.invertMirror", false);
+pref("status4evar.status.popup.mouseMirror", true);
diff --git a/app/profile/prefs.js b/app/profile/prefs.js
new file mode 100644
index 0000000..8c6f0d6
--- /dev/null
+++ b/app/profile/prefs.js
@@ -0,0 +1,13 @@
+/* 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/. */
+
+# Mozilla User Preferences
+
+/* Do not edit this file.
+ *
+ * If you make changes to this file while the browser is running,
+ * the changes will be overwritten when the browser exits.
+ *
+ * To make a manual change to preferences, you can visit the URL about:config
+ */
diff --git a/app/splash.rc b/app/splash.rc
new file mode 100644
index 0000000..539c342
--- /dev/null
+++ b/app/splash.rc
@@ -0,0 +1,21 @@
+/* -*- 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
+#include "nsNativeAppSupportWin.h"
+
+1 24 "palemoon.exe.manifest"
+
+IDI_APPICON ICON FIREFOX_ICO
+IDI_DOCUMENT ICON DOCUMENT_ICO
+IDI_APPLICATION ICON FIREFOX_ICO
+IDI_NEWWINDOW ICON NEWWINDOW_ICO
+IDI_NEWTAB ICON NEWTAB_ICO
+IDI_PBMODE ICON PBMODE_ICO
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_STARTMENU_APPNAME, "@MOZ_APP_DISPLAYNAME@"
+END
diff --git a/base/content/aboutDialog.css b/base/content/aboutDialog.css
new file mode 100644
index 0000000..d96eba5
--- /dev/null
+++ b/base/content/aboutDialog.css
@@ -0,0 +1,74 @@
+/* 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/. */
+
+#aboutPMDialogContainer {
+ width: 700px;
+ height: 410px;
+}
+
+#aboutVersionBox {
+ font-family: Arial, helvetica;
+ height: 38 px;
+}
+
+#aboutVersion {
+ text-align: center;
+ font-size: 18px;
+ font-weight: bold;
+ margin: 4px;
+}
+
+#distribution,
+#distributionId {
+ text-align: center;
+ font-size: 14px;
+ font-weight: bold;
+ display: none;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#aboutTextBox {
+ font-family: Arial, helvetica;
+ font-size: 14px;
+ margin: 5px 20px;
+ padding: 4px 10px 0px;
+ border-radius: 3px;
+ color: black;
+ background-color: rgba(240, 240, 240, .6);
+}
+
+#aboutLinkBox {
+ font-family: Arial, helvetica;
+}
+
+.text-credits {
+ margin: 5px 0px;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-link,
+.text-link:focus {
+ margin: 0px;
+ padding: 0px;
+}
+
+.bottom-link,
+.bottom-link:focus {
+ text-align: center;
+ text-decoration: none !important;
+ padding: 4px;
+ border-radius: 3px;
+ color: #244C8A;
+ background-color: rgba(240, 240, 240, .7);
+ margin: 0 40px;
+ transition: background-color 0.5s ease-out;
+}
+
+.bottom-link:hover {
+ background-color: rgba(240, 240, 255, .95);
+}
diff --git a/base/content/aboutDialog.js b/base/content/aboutDialog.js
new file mode 100644
index 0000000..e4e18f2
--- /dev/null
+++ b/base/content/aboutDialog.js
@@ -0,0 +1,62 @@
+# 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/.
+
+// Services = object with smart getters for common XPCOM services
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function init(aEvent)
+{
+ if (aEvent.target != document)
+ return;
+
+ try {
+ var distroId = Services.prefs.getCharPref("distribution.id");
+ if (distroId) {
+ var distroVersion = Services.prefs.getCharPref("distribution.version");
+
+ var distroIdField = document.getElementById("distributionId");
+ distroIdField.value = distroId + " - " + distroVersion;
+ distroIdField.style.display = "block";
+
+ try {
+ // This is in its own try catch due to bug 895473 and bug 900925.
+ var distroAbout = Services.prefs.getComplexValue("distribution.about",
+ Components.interfaces.nsISupportsString);
+ var distroField = document.getElementById("distribution");
+ distroField.value = distroAbout;
+ distroField.style.display = "block";
+ }
+ catch (ex) {
+ // Pref is unset
+ Components.utils.reportError(ex);
+ }
+ }
+ }
+ catch (e) {
+ // Pref is unset
+ }
+
+ // Include the build ID if this is an "a#" or "b#" build
+ let version = Services.appinfo.version;
+ if (/[ab]\d+$/.test(version)) {
+ let buildID = Services.appinfo.appBuildID;
+ let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
+ document.getElementById("aboutVersion").textContent += " (" + buildDate + ")";
+ }
+
+#ifdef XP_MACOSX
+ // it may not be sized at this point, and we need its width to calculate its position
+ window.sizeToContent();
+ window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
+#endif
+
+// get release notes URL from prefs
+ var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+ var releaseNotesURL = formatter.formatURLPref("app.releaseNotesURL");
+ if (releaseNotesURL != "about:blank") {
+ var relnotes = document.getElementById("releaseNotesURL");
+ relnotes.setAttribute("href", releaseNotesURL);
+ }
+}
diff --git a/base/content/aboutDialog.xul b/base/content/aboutDialog.xul
new file mode 100644
index 0000000..91fa81e
--- /dev/null
+++ b/base/content/aboutDialog.xul
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+%brandDTD;
+
+%aboutDialogDTD;
+]>
+
+#ifdef XP_MACOSX
+
+#endif
+
+
+
+
+
+
+
+
+#ifdef HAVE_64BIT_BUILD
+#expand Version: __MOZ_APP_VERSION__ (64-bit)
+#else
+#expand Version: __MOZ_APP_VERSION__ (32-bit)
+#endif
+
+
+
+
+
+
+#if defined(MOZ_OFFICIAL_BRANDING) || defined(MC_OFFICIAL)
+#ifdef MC_PRIVATE_BUILD
+ This is a private build of Pale Moon. If you did not manually build this copy from source yourself, then please download an official version from the Pale Moon website .
+#else
+ Pale Moon is released by Moonchild Productions .
+
+
+ Special thanks to all our supporters and donors for making this browser possible!
+
+
+ If you wish to contribute, please consider helping out by providing support to other users on the Pale Moon forum
+ or getting involved in our development by tackling some of the issues found in our GitHub issue tracker.
+#endif
+#else
+ &brandFullName; is released by &vendorShortName;.
+
+
+ This is an experimental build of Web Browser.
+#endif
+
+
+
+
+ End-user rights
+ Licensing information
+ Release notes
+
+ &trademarkInfo.part1;
+
+
+
+
+
+
+
+#ifdef XP_MACOSX
+#include browserMountPoints.inc
+#endif
+
diff --git a/base/content/autocomplete.css b/base/content/autocomplete.css
new file mode 100644
index 0000000..960bdc4
--- /dev/null
+++ b/base/content/autocomplete.css
@@ -0,0 +1,17 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* Apply crisp rendering for favicons at exactly 2dppx resolution */
+@media (resolution: 2dppx) {
+ .ac-site-icon {
+ image-rendering: -moz-crisp-edges;
+ }
+}
+
+richlistitem > .ac-title-box > .ac-title > .ac-comment:not([selected]) > html|span.ac-selected-text {
+ display: none;
+}
diff --git a/base/content/autocomplete.xml b/base/content/autocomplete.xml
new file mode 100644
index 0000000..bd09284
--- /dev/null
+++ b/base/content/autocomplete.xml
@@ -0,0 +1,2128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ null
+ null
+ false
+ null
+
+ null
+ null
+ null
+ null
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ parseInt(this.getAttribute("shrinkdelay")) || 0
+
+
+
+ {
+ let utils = {};
+ Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm", utils);
+ utils.PrivateBrowsingUtils
+ }
+
+
+
+
+
+
+
+ 14
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
+
+
+ = 1)
+ this.mController.handleTab();
+ break;
+ case KeyEvent.DOM_VK_UP:
+ case KeyEvent.DOM_VK_DOWN:
+ case KeyEvent.DOM_VK_PAGE_UP:
+ case KeyEvent.DOM_VK_PAGE_DOWN:
+ cancel = this.mController.handleKeyNavigation(aEvent.keyCode);
+ break;
+ }
+ }
+
+ // Handle keys we know aren't part of a shortcut, even with Alt or
+ // Ctrl.
+ switch (aEvent.keyCode) {
+ case KeyEvent.DOM_VK_ESCAPE:
+ cancel = this.mController.handleEscape();
+ break;
+ case KeyEvent.DOM_VK_RETURN:
+ if (AppConstants.platform == "macosx") {
+ // Prevent the default action, since it will beep on Mac
+ if (aEvent.metaKey)
+ aEvent.preventDefault();
+ }
+ this.mEnterEvent = aEvent;
+ if (this.mController.selection) {
+ this._selectionDetails = {
+ index: this.mController.selection.currentIndex,
+ kind: "key"
+ };
+ }
+ cancel = this.handleEnter();
+ break;
+ case KeyEvent.DOM_VK_DELETE:
+ if (AppConstants.platform == "macosx" && !aEvent.shiftKey) {
+ break;
+ }
+ cancel = this.handleDelete();
+ break;
+ case KeyEvent.DOM_VK_BACK_SPACE:
+ if (AppConstants.platform == "macosx" && aEvent.shiftKey) {
+ cancel = this.handleDelete();
+ }
+ break;
+ case KeyEvent.DOM_VK_DOWN:
+ case KeyEvent.DOM_VK_UP:
+ if (aEvent.altKey)
+ this.toggleHistoryPopup();
+ break;
+ case KeyEvent.DOM_VK_F4:
+ if (AppConstants.platform != "macosx") {
+ this.toggleHistoryPopup();
+ }
+ break;
+ }
+
+ if (cancel) {
+ aEvent.stopPropagation();
+ aEvent.preventDefault();
+ }
+
+ return true;
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ aCommand == "cmd_paste",
+ doCommand: function(aCommand) {
+ this._autocomplete._valueIsPasted = true;
+ this._autocomplete.editor.paste(this._kGlobalClipboard);
+ this._autocomplete._valueIsPasted = false;
+ },
+ isCommandEnabled: function(aCommand) {
+ return this._autocomplete.editor.isSelectionEditable &&
+ this._autocomplete.editor.canPaste(this._kGlobalClipboard);
+ },
+ onEvent: function() {}
+ })
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = 1) {
+ // mousemove sets selected index. Don't blindly use that selected
+ // index in this blur handler since if the popup is open you can
+ // easily "select" another match just by moving the mouse over it.
+ let filledVal = this.value.replace(/.+ >> /, "").toLowerCase();
+ let selectedVal = null;
+ if (this.popup.selectedIndex >= 0) {
+ selectedVal = this.mController.getFinalCompleteValueAt(
+ this.popup.selectedIndex);
+ }
+ if (selectedVal && filledVal != selectedVal.toLowerCase()) {
+ for (let i = 0; i < this.mController.matchCount; i++) {
+ let matchVal = this.mController.getFinalCompleteValueAt(i);
+ if (matchVal.toLowerCase() == filledVal) {
+ this.popup.selectedIndex = i;
+ break;
+ }
+ }
+ }
+ this.mController.handleEnter(false);
+ }
+ if (!this.ignoreBlurWhileSearching)
+ this.detachController();
+ }
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ str).join(" ")
+
+ // allow consumers that have extended popups to override
+ // the label values for the richlistitems
+ let panel = this.parentNode.parentNode;
+ if (panel.createResultLabel) {
+ return panel.createResultLabel(this, label);
+ }
+
+ return label;
+ ]]>
+
+
+
+
+
+
+
+ null
+
+
+
+
+
+
+
+
+
+
+
+ = 0) {
+ regions.push([matchIndex, matchIndex + searchLen]);
+ }
+ }
+
+ // Sort the regions by start position then end position
+ regions = regions.sort((a, b) => {
+ let start = a[0] - b[0];
+ return (start == 0) ? a[1] - b[1] : start;
+ });
+
+ // Generate the boundary indices from each region
+ let start = 0;
+ let end = 0;
+ let boundaries = [];
+ let len = regions.length;
+ for (let i = 0; i < len; i++) {
+ // We have a new boundary if the start of the next is past the end
+ let region = regions[i];
+ if (region[0] > end) {
+ // First index is the beginning of match
+ boundaries.push(start);
+ // Second index is the beginning of non-match
+ boundaries.push(end);
+
+ // Track the new region now that we've stored the previous one
+ start = region[0];
+ }
+
+ // Push back the end index for the current or new region
+ end = Math.max(end, region[1]);
+ }
+
+ // Add the last region
+ boundaries.push(start);
+ boundaries.push(end);
+
+ // Put on the end boundary if necessary
+ if (end < aText.length)
+ boundaries.push(aText.length);
+
+ // Skip the first item because it's always 0
+ return boundaries.slice(1);
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = 0 && index < aReplacements.length) {
+ pairs.push([...aReplacements[index]]);
+ }
+ } else {
+ pairs.push([part]);
+ }
+ }
+
+ return pairs;
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
+
+
+
+
+ = 0) {
+ pairs = [
+ [searchSuggestion.substring(0, idx), ""],
+ [searchQuery, "match"],
+ [searchSuggestion.substring(idx + searchQuery.length), ""],
+ ];
+ } else {
+ pairs = [
+ [searchSuggestion, ""],
+ ];
+ }
+ } else {
+ pairs = [
+ [searchQuery, ""],
+ ];
+ }
+ pairs.push([engineStr, "selected"]);
+ let interpStr = pairs.map((pair, i) => `%${i + 1}$S`).join("");
+ title = this._generateEmphasisPairs(interpStr, pairs);
+
+ // If this is a default search match, we remove the image so we
+ // can style it ourselves with a generic search icon.
+ // We don't do this when matching an aliased search engine,
+ // because the icon helps with recognising which engine will be
+ // used (when using the default engine, we don't need that
+ // recognition).
+ if (!action.params.alias) {
+ this.removeAttribute("image");
+ }
+ } else if (action.type == "visiturl") {
+ emphasiseUrl = false;
+ displayUrl = this._unescapeUrl(action.params.url);
+ let sourceStr = this._stringBundle.GetStringFromName("visitURL");
+ title = this._generateEmphasisPairs(sourceStr, [
+ [displayUrl, "match"],
+ ]);
+ }
+ }
+
+ // Check if we have a search engine name
+ if (initialTypes.has("search")) {
+ emphasiseUrl = false;
+
+ const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
+
+ let searchEngine = "";
+ [title, searchEngine] = title.split(TITLE_SEARCH_ENGINE_SEPARATOR);
+ displayUrl = this._stringBundle.formatStringFromName("searchWithEngine", [searchEngine], 1);
+ }
+
+ if (!displayUrl) {
+ let input = this.parentNode.parentNode.input;
+ let url = typeof(input.trimValue) == "function" ?
+ input.trimValue(originalUrl) :
+ originalUrl;
+ displayUrl = this._unescapeUrl(url);
+ }
+ this.setAttribute("displayurl", displayUrl);
+
+ // Check if we have an auto-fill URL
+ if (initialTypes.has("autofill")) {
+ emphasiseUrl = false;
+
+ let sourceStr = this._stringBundle.GetStringFromName("visitURL");
+ title = this._generateEmphasisPairs(sourceStr, [
+ [displayUrl, "match"],
+ ]);
+ }
+
+ // If we have a tag match, show the tags and icon
+ if (type == "tag" || type == "bookmark-tag") {
+ // Configure the extra box for tags display
+ this._extraBox.hidden = false;
+ this._extraBox.childNodes[0].hidden = false;
+ this._extraBox.childNodes[1].hidden = true;
+ this._extraBox.pack = "end";
+ this._titleBox.flex = 1;
+
+ // The title is separated from the tags by an endash
+ let tags;
+ [, title, tags] = title.match(/^(.+) \u2013 (.+)$/);
+
+ // Each tag is split by a comma in an undefined order, so sort it
+ let sortedTags = tags.split(",").sort().join(", ");
+
+ // Emphasize the matching text in the tags
+ this._setUpDescription(this._extra, sortedTags);
+
+ // If we're suggesting bookmarks, then treat tagged matches as
+ // bookmarks for the star.
+ if (type == "bookmark-tag") {
+ type = "bookmark";
+ } else {
+ this._typeImage.hidden = true;
+ }
+ // keyword and favicon type results for search engines
+ // have an extra magnifying glass icon after them
+ } else if (type == "keyword" || (initialTypes.has("search") &&
+ initialTypes.has("favicon"))) {
+ // Configure the extra box for keyword display
+ this._extraBox.hidden = false;
+ this._extraBox.childNodes[0].hidden = true;
+ // The second child node is ":" and it should be hidden for non keyword types
+ this._extraBox.childNodes[1].hidden = type == "keyword" ? false : true;
+ this._extraBox.pack = "start";
+ this._titleBox.flex = 0;
+
+ // Hide the ellipsis so it doesn't take up space.
+ this._titleOverflowEllipsis.hidden = true;
+
+ if (type == "keyword") {
+ // Put the parameters next to the title if we have any
+ let search = this.getAttribute("text");
+ let params = "";
+ let paramsIndex = search.indexOf(" ");
+ if (paramsIndex != -1)
+ params = search.substr(paramsIndex + 1);
+
+ // Emphasize the keyword parameters
+ this._setUpDescription(this._extra, params);
+
+ // Don't emphasize keyword searches in the title or url
+ emphasiseUrl = false;
+ emphasiseTitle = false;
+ } else {
+ // Don't show any description for non keyword types.
+ this._setUpDescription(this._extra, "", true);
+ }
+ // If the result has the type favicon and a known search provider,
+ // customize it the same way as a keyword result.
+ type = "keyword";
+ }
+
+ // Give the image the icon style and a special one for the type
+ this._typeImage.className = "ac-type-icon" +
+ (type ? " ac-result-type-" + type : "");
+
+ // Show the domain as the title if we don't have a title.
+ if (title == "") {
+ title = displayUrl;
+ try {
+ let uri = Services.io.newURI(originalUrl, null, null);
+ // Not all valid URLs have a domain.
+ if (uri.host)
+ title = uri.host;
+ } catch (e) {}
+ }
+
+ // Emphasize the matching search terms for the description
+ if (Array.isArray(title))
+ this._setUpEmphasisedSections(this._title, title);
+ else
+ this._setUpDescription(this._title, title, !emphasiseTitle);
+
+ this._setUpDescription(this._url, displayUrl, !emphasiseUrl);
+
+ // Set up overflow on a timeout because the contents of the box
+ // might not have a width yet even though we just changed them
+ setTimeout(this._setUpOverflow, 0, this._titleBox, this._titleOverflowEllipsis);
+ setTimeout(this._setUpOverflow, 0, this._urlBox, this._urlOverflowEllipsis);
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+ 0) {
+ // Subtract a little less to account for subpixel rounding
+ widthDiff -= childWidth - .5;
+
+ // Add to the tooltip if it's not hidden and has text
+ let childText = children[i].textContent;
+ if (childText)
+ tooltip.push(childText);
+ }
+ }
+
+ // If the children take up more space than the parent.. overflow!
+ if (widthDiff < 0) {
+ // Re-show the ellipsis now that we know it's needed
+ aEllipsis.style.visibility = "visible";
+
+ // Separate text components with a ndash --
+ aParentBox.tooltipText = tooltip.join(" \u2013 ");
+ }
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Date.now()
+ -1
+
+
+
+
+
+
+
+ 30) {
+ let item = event.target;
+ while (item && item.localName != "richlistitem") {
+ item = item.parentNode;
+ }
+
+ if (!item)
+ return;
+
+ let index = this.getIndexOfItem(item);
+ if (index != this.selectedIndex) {
+ this.mouseSelectedIndex = this.selectedIndex = index;
+ }
+
+ this.mLastMoveTime = Date.now();
+ }
+ ]]>
+
+
+
+
+
+
+ Date.now()
+
+
+
+
+
+
+
+ 30) {
+ var rc = this.parentNode.treeBoxObject.getRowAt(event.clientX, event.clientY);
+ if (rc != this.parentNode.currentIndex)
+ this.parentNode.view.selection.select(rc);
+ this.mLastMoveTime = Date.now();
+ }
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/content/autorecovery.js b/base/content/autorecovery.js
new file mode 100644
index 0000000..01a092f
--- /dev/null
+++ b/base/content/autorecovery.js
@@ -0,0 +1,60 @@
+/* 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/. */
+
+/* Auto-recovery module.
+ * This module aims to catch fatal browser initialization errors and either
+ * automatically correct likely causes from them, or automatically restarting
+ * the browser in safe mode. This is hooked into the browser's "onload"
+ * event because it can be assumed that at that point, everything must
+ * have been properly initialized already.
+ */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+// Services = object with smart getters for common XPCOM services
+Cu.import("resource://gre/modules/Services.jsm");
+
+var browser_autoRecovery =
+{
+ onLoad: function() {
+
+ var nsIAS = Ci.nsIAppStartup; // Application startup interface
+
+ if (typeof gBrowser === "undefined") {
+ // gBrowser should always be defined at this point, but if it is not, then most likely
+ // it is due to an incompatible or outdated language pack being installed and selected.
+ // In this case, we reset "general.useragent.locale" to try to recover browser startup.
+ if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
+ // Restart automatically in en-US.
+ Services.prefs.clearUserPref("general.useragent.locale");
+ Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eRestart | nsIAS.eAttemptQuit);
+ } else if (!Services.appinfo.inSafeMode) {
+ // gBrowser isn't defined, and we're not using a custom locale. Most likely
+ // a user-installed add-on causes issues here, so we restart in Safe Mode.
+ let RISM = Services.prompt.confirm(null, "Error",
+ "The Browser didn't start properly!\n"+
+ "This is usually caused by an add-on or misconfiguration.\n\n"+
+ "Restart in Safe Mode?");
+ if (RISM) {
+ Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).restartInSafeMode(nsIAS.eRestart | nsIAS.eAttemptQuit);
+ } else {
+ // Force quit application
+ Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAS).quit(nsIAS.eForceQuit);
+ }
+ }
+ // Something else caused this issue and we're already in Safe Mode, so we return
+ // without doing anything else, and let normal error handling take place.
+ return;
+ } // gBrowser undefined
+
+ // Other checks than gBrowser undefined can go here!
+
+ // Remove our listener, since we don't want this to fire on every load.
+ window.removeEventListener("load", browser_autoRecovery.onLoad, false);
+ }
+};
+
+window.addEventListener("load", browser_autoRecovery.onLoad, false);
diff --git a/base/content/autorecovery.xul b/base/content/autorecovery.xul
new file mode 100644
index 0000000..866bdf2
--- /dev/null
+++ b/base/content/autorecovery.xul
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/base/content/baseMenuOverlay.xul b/base/content/baseMenuOverlay.xul
new file mode 100644
index 0000000..bccdec2
--- /dev/null
+++ b/base/content/baseMenuOverlay.xul
@@ -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/.
+
+
+%brandDTD;
+
+%baseMenuOverlayDTD;
+]>
+
diff --git a/base/content/browser-addons.js b/base/content/browser-addons.js
new file mode 100644
index 0000000..630a0cf
--- /dev/null
+++ b/base/content/browser-addons.js
@@ -0,0 +1,537 @@
+# -*- Mode: javascript; 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/.
+
+// Removes a doorhanger notification if all of the installs it was notifying
+// about have ended in some way.
+function removeNotificationOnEnd(notification, installs) {
+ let count = installs.length;
+
+ function maybeRemove(install) {
+ install.removeListener(this);
+
+ if (--count == 0) {
+ // Check that the notification is still showing
+ let current = PopupNotifications.getNotification(notification.id, notification.browser);
+ if (current === notification)
+ notification.remove();
+ }
+ }
+
+ for (let install of installs) {
+ install.addListener({
+ onDownloadCancelled: maybeRemove,
+ onDownloadFailed: maybeRemove,
+ onInstallFailed: maybeRemove,
+ onInstallEnded: maybeRemove
+ });
+ }
+}
+
+const gXPInstallObserver = {
+ _findChildShell: function (aDocShell, aSoughtShell)
+ {
+ if (aDocShell == aSoughtShell)
+ return aDocShell;
+
+ var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
+ for (var i = 0; i < node.childCount; ++i) {
+ var docShell = node.getChildAt(i);
+ docShell = this._findChildShell(docShell, aSoughtShell);
+ if (docShell == aSoughtShell)
+ return docShell;
+ }
+ return null;
+ },
+
+ _getBrowser: function (aDocShell)
+ {
+ for (let browser of gBrowser.browsers) {
+ if (this._findChildShell(browser.docShell, aDocShell))
+ return browser;
+ }
+ return null;
+ },
+
+ observe: function (aSubject, aTopic, aData)
+ {
+ var brandBundle = document.getElementById("bundle_brand");
+ var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
+ var browser = installInfo.browser;
+
+ // Make sure the browser is still alive.
+ if (!browser || gBrowser.browsers.indexOf(browser) == -1)
+ return;
+
+ const anchorID = "addons-notification-icon";
+ var messageString, action;
+ var brandShortName = brandBundle.getString("brandShortName");
+
+ var notificationID = aTopic;
+ // Make notifications persist a minimum of 30 seconds
+ var options = {
+ timeout: Date.now() + 30000
+ };
+
+ switch (aTopic) {
+ case "addon-install-disabled":
+ notificationID = "xpinstall-disabled"
+
+ if (gPrefService.prefIsLocked("xpinstall.enabled")) {
+ messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
+ buttons = [];
+ }
+ else {
+ messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
+
+ action = {
+ label: gNavigatorBundle.getString("xpinstallDisabledButton"),
+ accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
+ callback: function editPrefs() {
+ gPrefService.setBoolPref("xpinstall.enabled", true);
+ }
+ };
+ }
+
+ PopupNotifications.show(browser, notificationID, messageString, anchorID,
+ action, null, options);
+ break;
+ case "addon-install-origin-blocked": {
+ messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarningOrigin",
+ [brandShortName]);
+
+ let popup = PopupNotifications.show(browser, notificationID,
+ messageString, anchorID,
+ null, null, options);
+ removeNotificationOnEnd(popup, installInfo.installs);
+ break; }
+ case "addon-install-blocked":
+ let originatingHost;
+ try {
+ originatingHost = installInfo.originatingURI.host;
+ } catch (ex) {
+ // Need to deal with missing originatingURI and with about:/data: URIs more gracefully,
+ // see bug 1063418 - but for now, bail:
+ return;
+ }
+ messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
+ [brandShortName, originatingHost]);
+
+ action = {
+ label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
+ accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
+ callback: function() {
+ installInfo.install();
+ }
+ };
+
+ let popup = PopupNotifications.show(browser, notificationID, messageString,
+ anchorID, action, null, options);
+ removeNotificationOnEnd(popup, installInfo.installs);
+ break;
+ case "addon-install-started":
+ var needsDownload = function needsDownload(aInstall) {
+ return aInstall.state != AddonManager.STATE_DOWNLOADED;
+ }
+ // If all installs have already been downloaded then there is no need to
+ // show the download progress
+ if (!installInfo.installs.some(needsDownload))
+ return;
+ notificationID = "addon-progress";
+ messageString = gNavigatorBundle.getString("addonDownloading");
+ messageString = PluralForm.get(installInfo.installs.length, messageString);
+ options.installs = installInfo.installs;
+ options.contentWindow = browser.contentWindow;
+ options.sourceURI = browser.currentURI;
+ options.eventCallback = function(aEvent) {
+ if (aEvent != "removed")
+ return;
+ options.contentWindow = null;
+ options.sourceURI = null;
+ };
+ PopupNotifications.show(browser, notificationID, messageString, anchorID,
+ null, null, options);
+ break;
+ case "addon-install-failed":
+ // TODO This isn't terribly ideal for the multiple failure case
+ for (let install of installInfo.installs) {
+ let host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
+ installInfo.originatingURI.host;
+ if (!host)
+ host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
+ install.sourceURI.host;
+
+ let error = (host || install.error == 0) ? "addonError" : "addonLocalError";
+ if (install.error != 0)
+ error += install.error;
+ else if (install.addon.jetsdk)
+ error += "JetSDK";
+ else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
+ error += "Blocklisted";
+ else
+ error += "Incompatible";
+
+ messageString = gNavigatorBundle.getString(error);
+ messageString = messageString.replace("#1", install.name);
+ if (host)
+ messageString = messageString.replace("#2", host);
+ messageString = messageString.replace("#3", brandShortName);
+ messageString = messageString.replace("#4", Services.appinfo.version);
+
+ PopupNotifications.show(browser, notificationID, messageString, anchorID,
+ action, null, options);
+ }
+ break;
+ case "addon-install-complete":
+ var needsRestart = installInfo.installs.some(function(i) {
+ return i.addon.pendingOperations != AddonManager.PENDING_NONE;
+ });
+
+ if (needsRestart) {
+ messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
+ action = {
+ label: gNavigatorBundle.getString("addonInstallRestartButton"),
+ accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
+ callback: function() {
+ Application.restart();
+ }
+ };
+ }
+ else {
+ messageString = gNavigatorBundle.getString("addonsInstalled");
+ action = null;
+ }
+
+ messageString = PluralForm.get(installInfo.installs.length, messageString);
+ messageString = messageString.replace("#1", installInfo.installs[0].name);
+ messageString = messageString.replace("#2", installInfo.installs.length);
+ messageString = messageString.replace("#3", brandShortName);
+
+ // Remove notificaion on dismissal, since it's possible to cancel the
+ // install through the addons manager UI, making the "restart" prompt
+ // irrelevant.
+ options.removeOnDismissal = true;
+
+ PopupNotifications.show(browser, notificationID, messageString, anchorID,
+ action, null, options);
+ break;
+ }
+ }
+};
+
+/*
+ * When addons are installed/uninstalled, check and see if the number of items
+ * on the add-on bar changed:
+ * - If an add-on was installed, incrementing the count, show the bar.
+ * - If an add-on was uninstalled, and no more items are left, hide the bar.
+ */
+var AddonsMgrListener = {
+ get addonBar() document.getElementById("addon-bar"),
+ get statusBar() document.getElementById("status-bar"),
+ getAddonBarItemCount: function() {
+ // Take into account the contents of the status bar shim for the count.
+ var itemCount = this.statusBar.childNodes.length;
+
+ var defaultOrNoninteractive = this.addonBar.getAttribute("defaultset")
+ .split(",")
+ .concat(["separator", "spacer", "spring"]);
+ for (let item of this.addonBar.currentSet.split(",")) {
+ if (defaultOrNoninteractive.indexOf(item) == -1)
+ itemCount++;
+ }
+
+ return itemCount;
+ },
+ onInstalling: function(aAddon) {
+ this.lastAddonBarCount = this.getAddonBarItemCount();
+ },
+ onInstalled: function(aAddon) {
+ if (this.getAddonBarItemCount() > this.lastAddonBarCount)
+ setToolbarVisibility(this.addonBar, true);
+ },
+ onUninstalling: function(aAddon) {
+ this.lastAddonBarCount = this.getAddonBarItemCount();
+ },
+ onUninstalled: function(aAddon) {
+ if (this.getAddonBarItemCount() == 0)
+ setToolbarVisibility(this.addonBar, false);
+ },
+ onEnabling: function(aAddon) this.onInstalling(),
+ onEnabled: function(aAddon) this.onInstalled(),
+ onDisabling: function(aAddon) this.onUninstalling(),
+ onDisabled: function(aAddon) this.onUninstalled(),
+};
+
+#ifdef MOZ_PERSONAS
+var LightWeightThemeWebInstaller = {
+ handleEvent: function (event) {
+ switch (event.type) {
+ case "InstallBrowserTheme":
+ case "PreviewBrowserTheme":
+ case "ResetBrowserThemePreview":
+ // ignore requests from background tabs
+ if (event.target.ownerDocument.defaultView.top != content)
+ return;
+ }
+ switch (event.type) {
+ case "InstallBrowserTheme":
+ this._installRequest(event);
+ break;
+ case "PreviewBrowserTheme":
+ this._preview(event);
+ break;
+ case "ResetBrowserThemePreview":
+ this._resetPreview(event);
+ break;
+ case "pagehide":
+ case "TabSelect":
+ this._resetPreview();
+ break;
+ }
+ },
+
+ get _manager () {
+ var temp = {};
+ Cu.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
+ delete this._manager;
+ return this._manager = temp.LightweightThemeManager;
+ },
+
+ _installRequest: function (event) {
+ var node = event.target;
+ var data = this._getThemeFromNode(node);
+ if (!data)
+ return;
+
+ if (this._isAllowed(node)) {
+ this._install(data);
+ return;
+ }
+
+ var allowButtonText =
+ gNavigatorBundle.getString("lwthemeInstallRequest.allowButton");
+ var allowButtonAccesskey =
+ gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey");
+ var message =
+ gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message",
+ [node.ownerDocument.location.host]);
+ var buttons = [{
+ label: allowButtonText,
+ accessKey: allowButtonAccesskey,
+ callback: function () {
+ LightWeightThemeWebInstaller._install(data);
+ }
+ }];
+
+ this._removePreviousNotifications();
+
+ var notificationBox = gBrowser.getNotificationBox();
+ var notificationBar =
+ notificationBox.appendNotification(message, "lwtheme-install-request", "",
+ notificationBox.PRIORITY_INFO_MEDIUM,
+ buttons);
+ notificationBar.persistence = 1;
+ },
+
+ _install: function (newLWTheme) {
+ var previousLWTheme = this._manager.currentTheme;
+
+ var listener = {
+ onEnabling: function(aAddon, aRequiresRestart) {
+ if (!aRequiresRestart)
+ return;
+
+ let messageString = gNavigatorBundle.getFormattedString("lwthemeNeedsRestart.message",
+ [aAddon.name], 1);
+
+ let action = {
+ label: gNavigatorBundle.getString("lwthemeNeedsRestart.button"),
+ accessKey: gNavigatorBundle.getString("lwthemeNeedsRestart.accesskey"),
+ callback: function () {
+ Application.restart();
+ }
+ };
+
+ let options = {
+ timeout: Date.now() + 30000
+ };
+
+ PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",
+ messageString, "addons-notification-icon",
+ action, null, options);
+ },
+
+ onEnabled: function(aAddon) {
+ LightWeightThemeWebInstaller._postInstallNotification(newLWTheme, previousLWTheme);
+ }
+ };
+
+ AddonManager.addAddonListener(listener);
+ this._manager.currentTheme = newLWTheme;
+ AddonManager.removeAddonListener(listener);
+ },
+
+ _postInstallNotification: function (newTheme, previousTheme) {
+ function text(id) {
+ return gNavigatorBundle.getString("lwthemePostInstallNotification." + id);
+ }
+
+ var buttons = [{
+ label: text("undoButton"),
+ accessKey: text("undoButton.accesskey"),
+ callback: function () {
+ LightWeightThemeWebInstaller._manager.forgetUsedTheme(newTheme.id);
+ LightWeightThemeWebInstaller._manager.currentTheme = previousTheme;
+ }
+ }, {
+ label: text("manageButton"),
+ accessKey: text("manageButton.accesskey"),
+ callback: function () {
+ BrowserOpenAddonsMgr("addons://list/theme");
+ }
+ }];
+
+ this._removePreviousNotifications();
+
+ var notificationBox = gBrowser.getNotificationBox();
+ var notificationBar =
+ notificationBox.appendNotification(text("message"),
+ "lwtheme-install-notification", "",
+ notificationBox.PRIORITY_INFO_MEDIUM,
+ buttons);
+ notificationBar.persistence = 1;
+ notificationBar.timeout = Date.now() + 20000; // 20 seconds
+ },
+
+ _removePreviousNotifications: function () {
+ var box = gBrowser.getNotificationBox();
+
+ ["lwtheme-install-request",
+ "lwtheme-install-notification"].forEach(function (value) {
+ var notification = box.getNotificationWithValue(value);
+ if (notification)
+ box.removeNotification(notification);
+ });
+ },
+
+ _previewWindow: null,
+ _preview: function (event) {
+ if (!this._isAllowed(event.target))
+ return;
+
+ var data = this._getThemeFromNode(event.target);
+ if (!data)
+ return;
+
+ this._resetPreview();
+
+ this._previewWindow = event.target.ownerDocument.defaultView;
+ this._previewWindow.addEventListener("pagehide", this, true);
+ gBrowser.tabContainer.addEventListener("TabSelect", this, false);
+
+ this._manager.previewTheme(data);
+ },
+
+ _resetPreview: function (event) {
+ if (!this._previewWindow ||
+ event && !this._isAllowed(event.target))
+ return;
+
+ this._previewWindow.removeEventListener("pagehide", this, true);
+ this._previewWindow = null;
+ gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
+
+ this._manager.resetPreview();
+ },
+
+ _isAllowed: function (node) {
+ var pm = Services.perms;
+
+ var uri = node.ownerDocument.documentURIObject;
+ return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
+ },
+
+ _getThemeFromNode: function (node) {
+ return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
+ node.baseURI);
+ }
+}
+
+/*
+ * Listen for Lightweight Theme styling changes and update the browser's theme accordingly.
+ */
+var LightweightThemeListener = {
+ _modifiedStyles: [],
+
+ init: function () {
+ XPCOMUtils.defineLazyGetter(this, "styleSheet", function() {
+ for (let i = document.styleSheets.length - 1; i >= 0; i--) {
+ let sheet = document.styleSheets[i];
+ if (sheet.href == "chrome://browser/skin/browser-lightweightTheme.css")
+ return sheet;
+ }
+ });
+
+ Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
+ Services.obs.addObserver(this, "lightweight-theme-optimized", false);
+ if (document.documentElement.hasAttribute("lwtheme"))
+ this.updateStyleSheet(document.documentElement.style.backgroundImage);
+ },
+
+ uninit: function () {
+ Services.obs.removeObserver(this, "lightweight-theme-styling-update");
+ Services.obs.removeObserver(this, "lightweight-theme-optimized");
+ },
+
+ /**
+ * Append the headerImage to the background-image property of all rulesets in
+ * browser-lightweightTheme.css.
+ *
+ * @param headerImage - a string containing a CSS image for the lightweight theme header.
+ */
+ updateStyleSheet: function(headerImage) {
+ if (!this.styleSheet)
+ return;
+ this.substituteRules(this.styleSheet.cssRules, headerImage);
+ },
+
+ substituteRules: function(ruleList, headerImage, existingStyleRulesModified = 0) {
+ let styleRulesModified = 0;
+ for (let i = 0; i < ruleList.length; i++) {
+ let rule = ruleList[i];
+ if (rule instanceof Ci.nsIDOMCSSGroupingRule) {
+ // Add the number of modified sub-rules to the modified count
+ styleRulesModified += this.substituteRules(rule.cssRules, headerImage, existingStyleRulesModified + styleRulesModified);
+ } else if (rule instanceof Ci.nsIDOMCSSStyleRule) {
+ if (!rule.style.backgroundImage)
+ continue;
+ let modifiedIndex = existingStyleRulesModified + styleRulesModified;
+ if (!this._modifiedStyles[modifiedIndex])
+ this._modifiedStyles[modifiedIndex] = { backgroundImage: rule.style.backgroundImage };
+
+ rule.style.backgroundImage = this._modifiedStyles[modifiedIndex].backgroundImage + ", " + headerImage;
+ styleRulesModified++;
+ } else {
+ Cu.reportError("Unsupported rule encountered");
+ }
+ }
+ return styleRulesModified;
+ },
+
+ // nsIObserver
+ observe: function (aSubject, aTopic, aData) {
+ if ((aTopic != "lightweight-theme-styling-update" && aTopic != "lightweight-theme-optimized") ||
+ !this.styleSheet)
+ return;
+
+ if (aTopic == "lightweight-theme-optimized" && aSubject != window)
+ return;
+
+ let themeData = JSON.parse(aData);
+ if (!themeData)
+ return;
+ this.updateStyleSheet("url(" + themeData.headerURL + ")");
+ },
+};
+#endif
diff --git a/base/content/browser-appmenu.inc b/base/content/browser-appmenu.inc
new file mode 100644
index 0000000..9d202c9
--- /dev/null
+++ b/base/content/browser-appmenu.inc
@@ -0,0 +1,381 @@
+# -*- Mode: HTML -*-
+# 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/.
+
+
diff --git a/base/content/browser-charsetmenu.inc b/base/content/browser-charsetmenu.inc
new file mode 100644
index 0000000..628de13
--- /dev/null
+++ b/base/content/browser-charsetmenu.inc
@@ -0,0 +1,62 @@
+# 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/.
+
+#filter substitution
+
+#expand
diff --git a/base/content/browser-context.inc b/base/content/browser-context.inc
new file mode 100644
index 0000000..38c4725
--- /dev/null
+++ b/base/content/browser-context.inc
@@ -0,0 +1,384 @@
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef CONTEXT_COPY_IMAGE_CONTENTS
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef MOZ_DEVTOOLS
+
+
+#endif
diff --git a/base/content/browser-devtools-theme.js b/base/content/browser-devtools-theme.js
new file mode 100644
index 0000000..7b21dde
--- /dev/null
+++ b/base/content/browser-devtools-theme.js
@@ -0,0 +1,91 @@
+/* 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/. */
+
+/**
+ * Listeners for the DevTools theme.
+ */
+var DevToolsTheme = {
+ _devtoolsThemePrefName: "devtools.theme",
+ styleSheet: null,
+ initialized: false,
+
+ get isStyleSheetEnabled() {
+ return this.styleSheet && !this.styleSheet.sheet.disabled;
+ },
+
+ init: function () {
+ this.initialized = true;
+ Services.prefs.addObserver(this._devtoolsThemePrefName, this, false);
+ Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
+ Services.obs.addObserver(this, "lightweight-theme-window-updated", false);
+ this._updateDevtoolsThemeAttribute();
+ },
+
+ observe: function (subject, topic, data) {
+ if (topic == "lightweight-theme-styling-update") {
+ let newTheme = JSON.parse(data);
+ this._toggleStyleSheet();
+ }
+
+ if (topic == "nsPref:changed" && data == this._devtoolsThemePrefName) {
+ this._updateDevtoolsThemeAttribute();
+ }
+ },
+
+ _inferBrightness: function() {
+ ToolbarIconColor.inferFromText();
+ // Get an inverted full screen button if the dark theme is applied.
+ if (this.isStyleSheetEnabled &&
+ document.documentElement.getAttribute("devtoolstheme") == "dark") {
+ document.documentElement.setAttribute("brighttitlebarforeground", "true");
+ } else {
+ document.documentElement.removeAttribute("brighttitlebarforeground");
+ }
+ },
+
+ _updateDevtoolsThemeAttribute: function() {
+ // Set an attribute on root element to make it possible
+ // to change colors based on the selected devtools theme.
+ let devtoolsTheme = Services.prefs.getCharPref(this._devtoolsThemePrefName);
+ if (devtoolsTheme != "dark") {
+ devtoolsTheme = "light";
+ }
+ document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
+ this._inferBrightness();
+ },
+
+ handleEvent: function(e) {
+ if (e.type === "load") {
+ this.styleSheet.removeEventListener("load", this);
+ this.refreshBrowserDisplay();
+ }
+ },
+
+ refreshBrowserDisplay: function() {
+ // Don't touch things on the browser if gBrowserInit.onLoad hasn't
+ // yet fired.
+ if (this.initialized) {
+ gBrowser.tabContainer._positionPinnedTabs();
+ this._inferBrightness();
+ }
+ },
+
+ _toggleStyleSheet: function() {
+ let wasEnabled = this.isStyleSheetEnabled;
+ if (wasEnabled) {
+ this.styleSheet.sheet.disabled = true;
+ this.refreshBrowserDisplay();
+ }
+ },
+
+ uninit: function () {
+ Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
+ Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
+ Services.obs.removeObserver(this, "lightweight-theme-window-updated", false);
+ if (this.styleSheet) {
+ this.styleSheet.removeEventListener("load", this);
+ }
+ this.styleSheet = null;
+ }
+};
diff --git a/base/content/browser-doctype.inc b/base/content/browser-doctype.inc
new file mode 100644
index 0000000..6ee6384
--- /dev/null
+++ b/base/content/browser-doctype.inc
@@ -0,0 +1,19 @@
+
+%brandDTD;
+
+%browserDTD;
+
+%baseMenuDTD;
+
+%charsetDTD;
+
+%textcontextDTD;
+
+ %customizeToolbarDTD;
+
+%placesDTD;
+
+%aboutHomeDTD;
+]>
+
diff --git a/base/content/browser-feeds.js b/base/content/browser-feeds.js
new file mode 100644
index 0000000..c678772
--- /dev/null
+++ b/base/content/browser-feeds.js
@@ -0,0 +1,224 @@
+# -*- Mode: javascript; 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/.
+
+/**
+ * The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
+ * and shows UI when they are discovered.
+ */
+var FeedHandler = {
+
+ /* Pale Moon: Address Bar: Feeds
+ * The click handler for the Feed icon in the location bar. Opens the
+ * subscription page if user is not given a choice of feeds.
+ * (Otherwise the list of available feeds will be presented to the
+ * user in a popup menu.)
+ */
+ onFeedButtonPMClick: function(event) {
+ event.stopPropagation();
+
+ if (event.target.hasAttribute("feed") &&
+ event.eventPhase == Event.AT_TARGET &&
+ (event.button == 0 || event.button == 1)) {
+ this.subscribeToFeed(null, event);
+ }
+ },
+
+ /**
+ * The click handler for the Feed icon in the toolbar. Opens the
+ * subscription page if user is not given a choice of feeds.
+ * (Otherwise the list of available feeds will be presented to the
+ * user in a popup menu.)
+ */
+ onFeedButtonClick: function(event) {
+ event.stopPropagation();
+
+ let feeds = gBrowser.selectedBrowser.feeds || [];
+ // If there are multiple feeds, the menu will open, so no need to do
+ // anything. If there are no feeds, nothing to do either.
+ if (feeds.length != 1)
+ return;
+
+ if (event.eventPhase == Event.AT_TARGET &&
+ (event.button == 0 || event.button == 1)) {
+ this.subscribeToFeed(feeds[0].href, event);
+ }
+ },
+
+ /** Called when the user clicks on the Subscribe to This Page... menu item.
+ * Builds a menu of unique feeds associated with the page, and if there
+ * is only one, shows the feed inline in the browser window.
+ * @param menuPopup
+ * The feed list menupopup to be populated.
+ * @returns true if the menu should be shown, false if there was only
+ * one feed and the feed should be shown inline in the browser
+ * window (do not show the menupopup).
+ */
+ buildFeedList: function(menuPopup) {
+ var feeds = gBrowser.selectedBrowser.feeds;
+ if (feeds == null) {
+ // XXX hack -- menu opening depends on setting of an "open"
+ // attribute, and the menu refuses to open if that attribute is
+ // set (because it thinks it's already open). onpopupshowing gets
+ // called after the attribute is unset, and it doesn't get unset
+ // if we return false. so we unset it here; otherwise, the menu
+ // refuses to work past this point.
+ menuPopup.parentNode.removeAttribute("open");
+ return false;
+ }
+
+ while (menuPopup.firstChild)
+ menuPopup.removeChild(menuPopup.firstChild);
+
+ if (feeds.length == 1) {
+ var feedButtonPM = document.getElementById("ub-feed-button");
+ if (feedButtonPM)
+ feedButtonPM.setAttribute("feed", feeds[0].href);
+ return false;
+ }
+
+ if (feeds.length <= 1)
+ return false;
+
+ // Build the menu showing the available feed choices for viewing.
+ for (let feedInfo of feeds) {
+ var menuItem = document.createElement("menuitem");
+ var baseTitle = feedInfo.title || feedInfo.href;
+ var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
+ menuItem.setAttribute("class", "feed-menuitem");
+ menuItem.setAttribute("label", labelStr);
+ menuItem.setAttribute("feed", feedInfo.href);
+ menuItem.setAttribute("tooltiptext", feedInfo.href);
+ menuItem.setAttribute("crop", "center");
+ menuPopup.appendChild(menuItem);
+ }
+ return true;
+ },
+
+ /**
+ * Subscribe to a given feed. Called when
+ * 1. Page has a single feed and user clicks feed icon in location bar
+ * 2. Page has a single feed and user selects Subscribe menu item
+ * 3. Page has multiple feeds and user selects from feed icon popup
+ * 4. Page has multiple feeds and user selects from Subscribe submenu
+ * @param href
+ * The feed to subscribe to. May be null, in which case the
+ * event target's feed attribute is examined.
+ * @param event
+ * The event this method is handling. Used to decide where
+ * to open the preview UI. (Optional, unless href is null)
+ */
+ subscribeToFeed: function(href, event) {
+ // Just load the feed in the content area to either subscribe or show the
+ // preview UI
+ if (!href)
+ href = event.target.getAttribute("feed");
+ urlSecurityCheck(href, gBrowser.contentPrincipal,
+ Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
+ var feedURI = makeURI(href, document.characterSet);
+ // Use the feed scheme so X-Moz-Is-Feed will be set
+ // The value doesn't matter
+ if (/^https?$/.test(feedURI.scheme))
+ href = "feed:" + href;
+ this.loadFeed(href, event);
+ },
+
+ loadFeed: function(href, event) {
+ var feeds = gBrowser.selectedBrowser.feeds;
+ try {
+ openUILink(href, event, { ignoreAlt: true });
+ }
+ finally {
+ // We might default to a livebookmarks modal dialog,
+ // so reset that if the user happens to click it again
+ gBrowser.selectedBrowser.feeds = feeds;
+ }
+ },
+
+ get _feedMenuitem() {
+ delete this._feedMenuitem;
+ return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
+ },
+
+ get _feedMenupopup() {
+ delete this._feedMenupopup;
+ return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
+ },
+
+ /**
+ * Update the browser UI to show whether or not feeds are available when
+ * a page is loaded or the user switches tabs to a page that has feeds.
+ */
+ updateFeeds: function() {
+ if (this._updateFeedTimeout)
+ clearTimeout(this._updateFeedTimeout);
+
+ var feeds = gBrowser.selectedBrowser.feeds;
+ var haveFeeds = feeds && feeds.length > 0;
+
+ var feedButtonPM = document.getElementById("ub-feed-button");
+
+ var feedButton = document.getElementById("feed-button");
+
+ if (feedButton)
+ feedButton.disabled = !haveFeeds;
+
+ if (feedButtonPM) {
+ if (!haveFeeds) {
+ feedButtonPM.collapsed = true;
+ feedButtonPM.removeAttribute("feed");
+ } else {
+ feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
+ }
+ }
+
+ if (!haveFeeds) {
+ this._feedMenuitem.setAttribute("disabled", "true");
+ this._feedMenuitem.removeAttribute("hidden");
+ this._feedMenupopup.setAttribute("hidden", "true");
+ return;
+ }
+
+ if (feeds.length > 1) {
+ if (feedButtonPM)
+ feedButtonPM.removeAttribute("feed");
+ this._feedMenuitem.setAttribute("hidden", "true");
+ this._feedMenupopup.removeAttribute("hidden");
+ } else {
+ if (feedButtonPM)
+ feedButtonPM.setAttribute("feed", feeds[0].href);
+ this._feedMenuitem.setAttribute("feed", feeds[0].href);
+ this._feedMenuitem.removeAttribute("disabled");
+ this._feedMenuitem.removeAttribute("hidden");
+ this._feedMenupopup.setAttribute("hidden", "true");
+ }
+ },
+
+ addFeed: function(link, targetDoc) {
+ // find which tab this is for, and set the attribute on the browser
+ var browserForLink = gBrowser.getBrowserForDocument(targetDoc);
+ if (!browserForLink) {
+ // ignore feeds loaded in subframes (see bug 305472)
+ return;
+ }
+
+ if (!browserForLink.feeds)
+ browserForLink.feeds = [];
+
+ browserForLink.feeds.push({ href: link.href, title: link.title });
+
+ // If this addition was for the current browser, update the UI. For
+ // background browsers, we'll update on tab switch.
+ if (browserForLink == gBrowser.selectedBrowser) {
+ var feedButtonPM = document.getElementById("ub-feed-button");
+ if (feedButtonPM)
+ feedButtonPM.collapsed = !gPrefService.getBoolPref("browser.urlbar.rss");
+ // Batch updates to avoid updating the UI for multiple onLinkAdded events
+ // fired within 100ms of each other.
+ if (this._updateFeedTimeout)
+ clearTimeout(this._updateFeedTimeout);
+ this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
+ }
+ }
+};
diff --git a/base/content/browser-fullScreen.js b/base/content/browser-fullScreen.js
new file mode 100644
index 0000000..e816ce5
--- /dev/null
+++ b/base/content/browser-fullScreen.js
@@ -0,0 +1,462 @@
+# -*- Mode: javascript; 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/.
+
+var FullScreen = {
+ _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
+
+ toggle: function () {
+ var enterFS = window.fullScreen;
+
+ // Toggle the View:FullScreen command, which controls elements like the
+ // fullscreen menuitem, menubars, and the appmenu.
+ let fullscreenCommand = document.getElementById("View:FullScreen");
+ if (enterFS) {
+ fullscreenCommand.setAttribute("checked", enterFS);
+ } else {
+ fullscreenCommand.removeAttribute("checked");
+ }
+
+#ifdef XP_MACOSX
+ // Make sure the menu items are adjusted.
+ document.getElementById("enterFullScreenItem").hidden = enterFS;
+ document.getElementById("exitFullScreenItem").hidden = !enterFS;
+#endif
+
+ if (!this._fullScrToggler) {
+ this._fullScrToggler = document.getElementById("fullscr-toggler");
+ this._fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
+ this._fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
+ }
+
+ // On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
+ // we're entering DOM fullscreen, in which case we should hide the toolbars.
+ // If we're leaving fullscreen, then we'll go through the exit code below to
+ // make sure toolbars are made visible in the case of DOM fullscreen.
+ if (enterFS && this.useLionFullScreen) {
+ if (document.mozFullScreen) {
+ this.showXULChrome("toolbar", false);
+ }
+ else {
+ gNavToolbox.setAttribute("inFullscreen", true);
+ document.documentElement.setAttribute("inFullscreen", true);
+ }
+ return;
+ }
+
+ // show/hide menubars, toolbars (except the full screen toolbar)
+ this.showXULChrome("toolbar", !enterFS);
+
+ if (enterFS) {
+ document.addEventListener("keypress", this._keyToggleCallback, false);
+ document.addEventListener("popupshown", this._setPopupOpen, false);
+ document.addEventListener("popuphidden", this._setPopupOpen, false);
+ this._shouldAnimate = true;
+ if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
+ gBrowser.mPanelContainer.addEventListener("mousemove",
+ this._collapseCallback, false);
+ }
+ // We don't animate the toolbar collapse if in DOM full-screen mode,
+ // as the size of the content area would still be changing after the
+ // mozfullscreenchange event fired, which could confuse content script.
+ this.hideNavToolbox(document.mozFullScreen);
+ }
+ else {
+ this.showNavToolbox(false);
+ // This is needed if they use the context menu to quit fullscreen
+ this._isPopupOpen = false;
+
+ document.documentElement.removeAttribute("inDOMFullscreen");
+
+ this.cleanup();
+ }
+ },
+
+ exitDomFullScreen : function() {
+ document.mozCancelFullScreen();
+ },
+
+ handleEvent: function (event) {
+ switch (event.type) {
+ case "activate":
+ if (document.mozFullScreen) {
+ this.showWarning(this.fullscreenDoc);
+ }
+ break;
+ case "transitionend":
+ if (event.propertyName == "opacity")
+ this.cancelWarning();
+ break;
+ }
+ },
+
+ enterDomFullscreen : function(event) {
+ if (!document.mozFullScreen)
+ return;
+
+ // However, if we receive a "MozDOMFullscreen:NewOrigin" event for a document
+ // which is not a subdocument of a currently active (ie. visible) browser
+ // or iframe, we know that we've switched to a different frame since the
+ // request to enter full-screen was made, so we should exit full-screen
+ // since the "full-screen document" isn't acutally visible.
+ if (!event.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell).isActive) {
+ document.mozCancelFullScreen();
+ return;
+ }
+
+ let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
+ if (focusManager.activeWindow != window) {
+ // The top-level window has lost focus since the request to enter
+ // full-screen was made. Cancel full-screen.
+ document.mozCancelFullScreen();
+ return;
+ }
+
+ document.documentElement.setAttribute("inDOMFullscreen", true);
+
+ if (gFindBarInitialized)
+ gFindBar.close();
+
+ this.showWarning(event.target);
+
+ // Exit DOM full-screen mode upon open, close, or change tab.
+ gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
+ gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
+ gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
+
+ // Add listener to detect when the fullscreen window is re-focused.
+ // If a fullscreen window loses focus, we show a warning when the
+ // fullscreen window is refocused.
+ if (!this.useLionFullScreen) {
+ window.addEventListener("activate", this);
+ }
+
+ // Cancel any "hide the toolbar" animation which is in progress, and make
+ // the toolbar hide immediately.
+ this.hideNavToolbox(true);
+ },
+
+ cleanup: function () {
+ if (!window.fullScreen) {
+ gBrowser.mPanelContainer.removeEventListener("mousemove",
+ this._collapseCallback, false);
+ document.removeEventListener("keypress", this._keyToggleCallback, false);
+ document.removeEventListener("popupshown", this._setPopupOpen, false);
+ document.removeEventListener("popuphidden", this._setPopupOpen, false);
+
+ this.cancelWarning();
+ gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
+ gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
+ gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
+ if (!this.useLionFullScreen)
+ window.removeEventListener("activate", this);
+ this.fullscreenDoc = null;
+ }
+ },
+
+ // Event callbacks
+ _expandCallback: function()
+ {
+ FullScreen.showNavToolbox();
+ },
+ _collapseCallback: function()
+ {
+ FullScreen.hideNavToolbox();
+ },
+ _keyToggleCallback: function(aEvent)
+ {
+ // if we can use the keyboard (eg Ctrl+L or Ctrl+E) to open the toolbars, we
+ // should provide a way to collapse them too.
+ if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
+ FullScreen.hideNavToolbox(true);
+ }
+ // F6 is another shortcut to the address bar, but its not covered in OpenLocation()
+ else if (aEvent.keyCode == aEvent.DOM_VK_F6)
+ FullScreen.showNavToolbox();
+ },
+
+ // Checks whether we are allowed to collapse the chrome
+ _isPopupOpen: false,
+ _isChromeCollapsed: false,
+ _safeToCollapse: function(forceHide)
+ {
+ if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
+ return false;
+
+ // a popup menu is open in chrome: don't collapse chrome
+ if (!forceHide && this._isPopupOpen)
+ return false;
+
+ // a textbox in chrome is focused (location bar anyone?): don't collapse chrome
+ if (document.commandDispatcher.focusedElement &&
+ document.commandDispatcher.focusedElement.ownerDocument == document &&
+ document.commandDispatcher.focusedElement.localName == "input") {
+ if (forceHide)
+ // hidden textboxes that still have focus are bad bad bad
+ document.commandDispatcher.focusedElement.blur();
+ else
+ return false;
+ }
+ return true;
+ },
+
+ _setPopupOpen: function(aEvent)
+ {
+ // Popups should only veto chrome collapsing if they were opened when the chrome was not collapsed.
+ // Otherwise, they would not affect chrome and the user would expect the chrome to go away.
+ // e.g. we wouldn't want the autoscroll icon firing this event, so when the user
+ // toggles chrome when moving mouse to the top, it doesn't go away again.
+ if (aEvent.type == "popupshown" && !FullScreen._isChromeCollapsed &&
+ aEvent.target.localName != "tooltip" && aEvent.target.localName != "window")
+ FullScreen._isPopupOpen = true;
+ else if (aEvent.type == "popuphidden" && aEvent.target.localName != "tooltip" &&
+ aEvent.target.localName != "window")
+ FullScreen._isPopupOpen = false;
+ },
+
+ // Autohide helpers for the context menu item
+ getAutohide: function(aItem)
+ {
+ aItem.setAttribute("checked", gPrefService.getBoolPref("browser.fullscreen.autohide"));
+ },
+ setAutohide: function()
+ {
+ gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
+ },
+
+ // Animate the toolbars disappearing
+ _shouldAnimate: true,
+
+ cancelWarning: function(event) {
+ if (!this.warningBox)
+ return;
+ this.warningBox.removeEventListener("transitionend", this);
+ if (this.warningFadeOutTimeout) {
+ clearTimeout(this.warningFadeOutTimeout);
+ this.warningFadeOutTimeout = null;
+ }
+
+ // Ensure focus switches away from the (now hidden) warning box. If the user
+ // clicked buttons in the fullscreen key authorization UI, it would have been
+ // focused, and any key events would be directed at the (now hidden) chrome
+ // document instead of the target document.
+ gBrowser.selectedBrowser.focus();
+
+ this.warningBox.setAttribute("hidden", true);
+ this.warningBox.removeAttribute("fade-warning-out");
+ this.warningBox = null;
+ },
+
+ warningBox: null,
+ warningFadeOutTimeout: null,
+ fullscreenDoc: null,
+
+ // Shows a warning that the site has entered fullscreen for a short duration.
+ showWarning: function(targetDoc) {
+ let timeout = gPrefService.getIntPref("full-screen-api.warning.timeout");
+ if (!document.mozFullScreen || timeout <= 0)
+ return;
+
+ // Set the strings on the fullscreen warning UI.
+ this.fullscreenDoc = targetDoc;
+ let uri = this.fullscreenDoc.nodePrincipal.URI;
+ let host = null;
+ try {
+ host = uri.host;
+ } catch (e) { }
+ let hostLabel = document.getElementById("full-screen-domain-text");
+ if (host) {
+ // Document's principal's URI has a host. Display a warning including the hostname.
+ let utils = {};
+ Cu.import("resource://gre/modules/DownloadUtils.jsm", utils);
+ let displayHost = utils.DownloadUtils.getURIHost(uri.spec)[0];
+ let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+
+ hostLabel.textContent = bundle.formatStringFromName("fullscreen.entered", [displayHost], 1);
+ hostLabel.removeAttribute("hidden");
+ } else {
+ hostLabel.setAttribute("hidden", "true");
+ }
+
+ // Note: the warning box can be non-null if the warning box from the previous request
+ // wasn't hidden before another request was made.
+ if (!this.warningBox) {
+ this.warningBox = document.getElementById("full-screen-warning-container");
+ // Add a listener to clean up state after the warning is hidden.
+ this.warningBox.addEventListener("transitionend", this);
+ this.warningBox.removeAttribute("hidden");
+ } else {
+ if (this.warningFadeOutTimeout) {
+ clearTimeout(this.warningFadeOutTimeout);
+ this.warningFadeOutTimeout = null;
+ }
+ this.warningBox.removeAttribute("fade-warning-out");
+ }
+
+ // Set a timeout to fade the warning out after a few moments.
+ this.warningFadeOutTimeout = setTimeout(() => {
+ if (this.warningBox) {
+ this.warningBox.setAttribute("fade-warning-out", "true");
+ }
+ }, timeout);
+ },
+
+ showNavToolbox: function(trackMouse = true) {
+ this._fullScrToggler.hidden = true;
+ gNavToolbox.removeAttribute("fullscreenShouldAnimate");
+ gNavToolbox.style.marginTop = "";
+
+ if (!this._isChromeCollapsed) {
+ return;
+ }
+
+ // Track whether mouse is near the toolbox
+ this._isChromeCollapsed = false;
+ if (trackMouse) {
+ gBrowser.mPanelContainer.addEventListener("mousemove",
+ this._collapseCallback, false);
+ }
+ },
+
+ hideNavToolbox: function(forceHide = false) {
+ this._fullScrToggler.hidden = document.mozFullScreen;
+ if (this._isChromeCollapsed) {
+ if (forceHide) {
+ gNavToolbox.removeAttribute("fullscreenShouldAnimate");
+ }
+ return;
+ }
+ if (!this._safeToCollapse(forceHide)) {
+ this._fullScrToggler.hidden = true;
+ return;
+ }
+
+ // browser.fullscreen.animateUp
+ // 0 - never animate up
+ // 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
+ // 2 - animate every time it collapses
+ let animateUp = gPrefService.getIntPref("browser.fullscreen.animateUp");
+ if (animateUp == 0) {
+ this._shouldAnimate = false;
+ } else if (animateUp == 2) {
+ this._shouldAnimate = true;
+ }
+ if (this._shouldAnimate && !forceHide) {
+ gNavToolbox.setAttribute("fullscreenShouldAnimate", true);
+ this._shouldAnimate = false;
+ // Hide the fullscreen toggler until the transition ends.
+ let listener = () => {
+ gNavToolbox.removeEventListener("transitionend", listener, true);
+ if (this._isChromeCollapsed)
+ this._fullScrToggler.hidden = false;
+ };
+ gNavToolbox.addEventListener("transitionend", listener, true);
+ this._fullScrToggler.hidden = true;
+ }
+
+ gNavToolbox.style.marginTop =
+ -gNavToolbox.getBoundingClientRect().height + "px";
+ this._isChromeCollapsed = true;
+ gBrowser.mPanelContainer.removeEventListener("mousemove",
+ this._collapseCallback, false);
+ },
+
+ showXULChrome: function(aTag, aShow)
+ {
+ var els = document.getElementsByTagNameNS(this._XULNS, aTag);
+
+ for (let el of els) {
+ // XXX don't interfere with previously collapsed toolbars
+ if (el.getAttribute("fullscreentoolbar") == "true") {
+ if (!aShow) {
+
+ var toolbarMode = el.getAttribute("mode");
+ if (toolbarMode != "text") {
+ el.setAttribute("saved-mode", toolbarMode);
+ el.setAttribute("saved-iconsize", el.getAttribute("iconsize"));
+ el.setAttribute("mode", "icons");
+ el.setAttribute("iconsize", "small");
+ }
+
+ // Give the main nav bar and the tab bar the fullscreen context menu,
+ // otherwise remove context menu to prevent breakage
+ el.setAttribute("saved-context", el.getAttribute("context"));
+ if (el.id == "nav-bar" || el.id == "TabsToolbar")
+ el.setAttribute("context", "autohide-context");
+ else
+ el.removeAttribute("context");
+
+ // Set the inFullscreen attribute to allow specific styling
+ // in fullscreen mode
+ el.setAttribute("inFullscreen", true);
+ }
+ else {
+ var restoreAttr = function restoreAttr(attrName) {
+ var savedAttr = "saved-" + attrName;
+ if (el.hasAttribute(savedAttr)) {
+ el.setAttribute(attrName, el.getAttribute(savedAttr));
+ el.removeAttribute(savedAttr);
+ }
+ }
+
+ restoreAttr("mode");
+ restoreAttr("iconsize");
+ restoreAttr("context");
+
+ el.removeAttribute("inFullscreen");
+ }
+ } else {
+ // use moz-collapsed so it doesn't persist hidden/collapsed,
+ // so that new windows don't have missing toolbars
+ if (aShow)
+ el.removeAttribute("moz-collapsed");
+ else
+ el.setAttribute("moz-collapsed", "true");
+ }
+ }
+
+ if (aShow) {
+ gNavToolbox.removeAttribute("inFullscreen");
+ document.documentElement.removeAttribute("inFullscreen");
+ } else {
+ gNavToolbox.setAttribute("inFullscreen", true);
+ document.documentElement.setAttribute("inFullscreen", true);
+ }
+
+ // In tabs-on-top mode, move window controls to the tab bar,
+ // and in tabs-on-bottom mode, move them back to the navigation toolbar.
+ // When there is a chance the tab bar may be collapsed, put window
+ // controls on nav bar.
+ var fullscreenctls = document.getElementById("window-controls");
+ var navbar = document.getElementById("nav-bar");
+ var ctlsOnTabbar = window.toolbar.visible &&
+ (navbar.collapsed || (TabsOnTop.enabled &&
+ !gPrefService.getBoolPref("browser.tabs.autoHide")));
+ if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
+ fullscreenctls.removeAttribute("flex");
+ document.getElementById("TabsToolbar").appendChild(fullscreenctls);
+ }
+ else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
+ fullscreenctls.setAttribute("flex", "1");
+ navbar.appendChild(fullscreenctls);
+ }
+ fullscreenctls.hidden = aShow;
+
+ ToolbarIconColor.inferFromText();
+ }
+};
+XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
+ // We'll only use OS X Lion full screen if we're
+ // * on OS X
+ // * on Lion or higher (Darwin 11+)
+ // * have fullscreenbutton="true"
+#ifdef XP_MACOSX
+ return parseFloat(Services.sysinfo.getProperty("version")) >= 11 &&
+ document.documentElement.getAttribute("fullscreenbutton") == "true";
+#else
+ return false;
+#endif
+});
diff --git a/base/content/browser-fullZoom.js b/base/content/browser-fullZoom.js
new file mode 100644
index 0000000..890cd84
--- /dev/null
+++ b/base/content/browser-fullZoom.js
@@ -0,0 +1,526 @@
+/* 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/. */
+
+/**
+ * Controls the "full zoom" setting and its site-specific preferences.
+ */
+var FullZoom = {
+ // Identifies the setting in the content prefs database.
+ name: "browser.content.full-zoom",
+
+ // browser.zoom.siteSpecific preference cache
+ _siteSpecificPref: undefined,
+
+ // browser.zoom.updateBackgroundTabs preference cache
+ updateBackgroundTabs: undefined,
+
+ // This maps the browser to monotonically increasing integer
+ // tokens. _browserTokenMap[browser] is increased each time the zoom is
+ // changed in the browser. See _getBrowserToken and _ignorePendingZoomAccesses.
+ _browserTokenMap: new WeakMap(),
+
+ // Stores initial locations if we receive onLocationChange
+ // events before we're initialized.
+ _initialLocations: new WeakMap(),
+
+ get siteSpecific() {
+ return this._siteSpecificPref;
+ },
+
+ // nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
+ Ci.nsIObserver,
+ Ci.nsIContentPrefObserver,
+ Ci.nsISupportsWeakReference,
+ Ci.nsISupports]),
+
+ // Initialization & Destruction
+
+ init: function FullZoom_init() {
+ gBrowser.addEventListener("ZoomChangeUsingMouseWheel", this);
+
+ // Register ourselves with the service so we know when our pref changes.
+ this._cps2 = Cc["@mozilla.org/content-pref/service;1"].
+ getService(Ci.nsIContentPrefService2);
+ this._cps2.addObserverForName(this.name, this);
+
+ this._siteSpecificPref =
+ gPrefService.getBoolPref("browser.zoom.siteSpecific");
+ this.updateBackgroundTabs =
+ gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
+ // Listen for changes to the browser.zoom branch so we can enable/disable
+ // updating background tabs and per-site saving and restoring of zoom levels.
+ gPrefService.addObserver("browser.zoom.", this, true);
+
+ // If we received onLocationChange events for any of the current browsers
+ // before we were initialized we want to replay those upon initialization.
+ for (let browser of gBrowser.browsers) {
+ if (this._initialLocations.has(browser)) {
+ this.onLocationChange(...this._initialLocations.get(browser), browser);
+ }
+ }
+
+ // This should be nulled after initialization.
+ this._initialLocations = null;
+ },
+
+ destroy: function FullZoom_destroy() {
+ gPrefService.removeObserver("browser.zoom.", this);
+ this._cps2.removeObserverForName(this.name, this);
+ gBrowser.removeEventListener("ZoomChangeUsingMouseWheel", this);
+ },
+
+
+ // Event Handlers
+
+ // nsIDOMEventListener
+
+ handleEvent: function FullZoom_handleEvent(event) {
+ switch (event.type) {
+ case "ZoomChangeUsingMouseWheel":
+ let browser = this._getTargetedBrowser(event);
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
+ break;
+ }
+ },
+
+ // nsIObserver
+
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "nsPref:changed":
+ switch (aData) {
+ case "browser.zoom.siteSpecific":
+ this._siteSpecificPref =
+ gPrefService.getBoolPref("browser.zoom.siteSpecific");
+ break;
+ case "browser.zoom.updateBackgroundTabs":
+ this.updateBackgroundTabs =
+ gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
+ break;
+ }
+ break;
+ }
+ },
+
+ // nsIContentPrefObserver
+
+ onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue, aIsPrivate) {
+ this._onContentPrefChanged(aGroup, aValue, aIsPrivate);
+ },
+
+ onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName, aIsPrivate) {
+ this._onContentPrefChanged(aGroup, undefined, aIsPrivate);
+ },
+
+ /**
+ * Appropriately updates the zoom level after a content preference has
+ * changed.
+ *
+ * @param aGroup The group of the changed preference.
+ * @param aValue The new value of the changed preference. Pass undefined to
+ * indicate the preference's removal.
+ */
+ _onContentPrefChanged: function FullZoom__onContentPrefChanged(aGroup, aValue, aIsPrivate) {
+ if (this._isNextContentPrefChangeInternal) {
+ // Ignore changes that FullZoom itself makes. This works because the
+ // content pref service calls callbacks before notifying observers, and it
+ // does both in the same turn of the event loop.
+ delete this._isNextContentPrefChangeInternal;
+ return;
+ }
+
+ let browser = gBrowser.selectedBrowser;
+ if (!browser.currentURI)
+ return;
+
+ let ctxt = this._loadContextFromBrowser(browser);
+ let domain = this._cps2.extractDomain(browser.currentURI.spec);
+ if (aGroup) {
+ if (aGroup == domain && ctxt.usePrivateBrowsing == aIsPrivate)
+ this._applyPrefToZoom(aValue, browser);
+ return;
+ }
+
+ this._globalValue = aValue === undefined ? aValue :
+ this._ensureValid(aValue);
+
+ // If the current page doesn't have a site-specific preference, then its
+ // zoom should be set to the new global preference now that the global
+ // preference has changed.
+ let hasPref = false;
+ let token = this._getBrowserToken(browser);
+ this._cps2.getByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
+ handleResult: function () { hasPref = true; },
+ handleCompletion: function () {
+ if (!hasPref && token.isCurrent)
+ this._applyPrefToZoom(undefined, browser);
+ }.bind(this)
+ });
+ },
+
+ // location change observer
+
+ /**
+ * Called when the location of a tab changes.
+ * When that happens, we need to update the current zoom level if appropriate.
+ *
+ * @param aURI
+ * A URI object representing the new location.
+ * @param aIsTabSwitch
+ * Whether this location change has happened because of a tab switch.
+ * @param aBrowser
+ * (optional) browser object displaying the document
+ */
+ onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
+ let browser = aBrowser || gBrowser.selectedBrowser;
+
+ // If we haven't been initialized yet but receive an onLocationChange
+ // notification then let's store and replay it upon initialization.
+ if (this._initialLocations) {
+ this._initialLocations.set(browser, [aURI, aIsTabSwitch]);
+ return;
+ }
+
+ // Ignore all pending async zoom accesses in the browser. Pending accesses
+ // that started before the location change will be prevented from applying
+ // to the new location.
+ this._ignorePendingZoomAccesses(browser);
+
+ if (!aURI || (aIsTabSwitch && !this.siteSpecific)) {
+ this._notifyOnLocationChange(browser);
+ return;
+ }
+
+ // Avoid the cps roundtrip and apply the default/global pref.
+ if (aURI.spec == "about:blank") {
+ this._applyPrefToZoom(undefined, browser,
+ this._notifyOnLocationChange.bind(this, browser));
+ return;
+ }
+
+ // Media documents should always start at 1, and are not affected by prefs.
+ if (!aIsTabSwitch && browser.isSyntheticDocument) {
+ ZoomManager.setZoomForBrowser(browser, 1);
+ // _ignorePendingZoomAccesses already called above, so no need here.
+ this._notifyOnLocationChange(browser);
+ return;
+ }
+
+ // See if the zoom pref is cached.
+ let ctxt = this._loadContextFromBrowser(browser);
+ let pref = this._cps2.getCachedByDomainAndName(aURI.spec, this.name, ctxt);
+ if (pref) {
+ this._applyPrefToZoom(pref.value, browser,
+ this._notifyOnLocationChange.bind(this, browser));
+ return;
+ }
+
+ // It's not cached, so we have to asynchronously fetch it.
+ let value = undefined;
+ let token = this._getBrowserToken(browser);
+ this._cps2.getByDomainAndName(aURI.spec, this.name, ctxt, {
+ handleResult: function (resultPref) { value = resultPref.value; },
+ handleCompletion: function () {
+ if (!token.isCurrent) {
+ this._notifyOnLocationChange(browser);
+ return;
+ }
+ this._applyPrefToZoom(value, browser,
+ this._notifyOnLocationChange.bind(this, browser));
+ }.bind(this)
+ });
+ },
+
+ // update state of zoom type menu item
+
+ updateMenu: function FullZoom_updateMenu() {
+ var menuItem = document.getElementById("toggle_zoom");
+
+ menuItem.setAttribute("checked", !ZoomManager.useFullZoom);
+ },
+
+ // Setting & Pref Manipulation
+
+ /**
+ * Reduces the zoom level of the page in the current browser.
+ */
+ reduce: function FullZoom_reduce() {
+ ZoomManager.reduce();
+ let browser = gBrowser.selectedBrowser;
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
+ },
+
+ /**
+ * Enlarges the zoom level of the page in the current browser.
+ */
+ enlarge: function FullZoom_enlarge() {
+ ZoomManager.enlarge();
+ let browser = gBrowser.selectedBrowser;
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
+ },
+
+ /**
+ * Sets the zoom level for the given browser to the given floating
+ * point value, where 1 is the default zoom level.
+ */
+ setZoom: function (value, browser = gBrowser.selectedBrowser) {
+ ZoomManager.setZoomForBrowser(browser, value);
+ this._ignorePendingZoomAccesses(browser);
+ this._applyZoomToPref(browser);
+ },
+
+ /**
+ * Sets the zoom level of the page in the given browser to the global zoom
+ * level.
+ *
+ * @return A promise which resolves when the zoom reset has been applied.
+ */
+ reset: function FullZoom_reset(browser = gBrowser.selectedBrowser) {
+ let token = this._getBrowserToken(browser);
+ let result = this._getGlobalValue(browser).then(value => {
+ if (token.isCurrent) {
+ ZoomManager.setZoomForBrowser(browser, value === undefined ? 1 : value);
+ this._ignorePendingZoomAccesses(browser);
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
+ }
+ });
+ this._removePref(browser);
+ return result;
+ },
+
+ /**
+ * Set the zoom level for a given browser.
+ *
+ * Per nsPresContext::setFullZoom, we can set the zoom to its current value
+ * without significant impact on performance, as the setting is only applied
+ * if it differs from the current setting. In fact getting the zoom and then
+ * checking ourselves if it differs costs more.
+ *
+ * And perhaps we should always set the zoom even if it was more expensive,
+ * since nsDocumentViewer::SetTextZoom claims that child documents can have
+ * a different text zoom (although it would be unusual), and it implies that
+ * those child text zooms should get updated when the parent zoom gets set,
+ * and perhaps the same is true for full zoom
+ * (although nsDocumentViewer::SetFullZoom doesn't mention it).
+ *
+ * So when we apply new zoom values to the browser, we simply set the zoom.
+ * We don't check first to see if the new value is the same as the current
+ * one.
+ *
+ * @param aValue The zoom level value.
+ * @param aBrowser The zoom is set in this browser. Required.
+ * @param aCallback If given, it's asynchronously called when complete.
+ */
+ _applyPrefToZoom: function FullZoom__applyPrefToZoom(aValue, aBrowser, aCallback) {
+ if (!this.siteSpecific || gInPrintPreviewMode) {
+ this._executeSoon(aCallback);
+ return;
+ }
+
+ // The browser is sometimes half-destroyed because this method is called
+ // by content pref service callbacks, which themselves can be called at any
+ // time, even after browsers are closed.
+ if (!aBrowser.parentNode || aBrowser.isSyntheticDocument) {
+ this._executeSoon(aCallback);
+ return;
+ }
+
+ if (aValue !== undefined) {
+ ZoomManager.setZoomForBrowser(aBrowser, this._ensureValid(aValue));
+ this._ignorePendingZoomAccesses(aBrowser);
+ this._executeSoon(aCallback);
+ return;
+ }
+
+ let token = this._getBrowserToken(aBrowser);
+ this._getGlobalValue(aBrowser).then(value => {
+ if (token.isCurrent) {
+ ZoomManager.setZoomForBrowser(aBrowser, value === undefined ? 1 : value);
+ this._ignorePendingZoomAccesses(aBrowser);
+ }
+ this._executeSoon(aCallback);
+ });
+ },
+
+ /**
+ * Saves the zoom level of the page in the given browser to the content
+ * prefs store.
+ *
+ * @param browser The zoom of this browser will be saved. Required.
+ */
+ _applyZoomToPref: function FullZoom__applyZoomToPref(browser) {
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomChange", "");
+ if (!this.siteSpecific ||
+ gInPrintPreviewMode ||
+ browser.isSyntheticDocument)
+ return;
+
+ this._cps2.set(browser.currentURI.spec, this.name,
+ ZoomManager.getZoomForBrowser(browser),
+ this._loadContextFromBrowser(browser), {
+ handleCompletion: function () {
+ this._isNextContentPrefChangeInternal = true;
+ }.bind(this),
+ });
+ },
+
+ /**
+ * Removes from the content prefs store the zoom level of the given browser.
+ *
+ * @param browser The zoom of this browser will be removed. Required.
+ */
+ _removePref: function FullZoom__removePref(browser) {
+ Services.obs.notifyObservers(browser, "browser-fullZoom:zoomReset", "");
+ if (browser.isSyntheticDocument)
+ return;
+ let ctxt = this._loadContextFromBrowser(browser);
+ this._cps2.removeByDomainAndName(browser.currentURI.spec, this.name, ctxt, {
+ handleCompletion: function () {
+ this._isNextContentPrefChangeInternal = true;
+ }.bind(this),
+ });
+ },
+
+ // Utilities
+
+ /**
+ * Returns the zoom change token of the given browser. Asynchronous
+ * operations that access the given browser's zoom should use this method to
+ * capture the token before starting and use token.isCurrent to determine if
+ * it's safe to access the zoom when done. If token.isCurrent is false, then
+ * after the async operation started, either the browser's zoom was changed or
+ * the browser was destroyed, and depending on what the operation is doing, it
+ * may no longer be safe to set and get its zoom.
+ *
+ * @param browser The token of this browser will be returned.
+ * @return An object with an "isCurrent" getter.
+ */
+ _getBrowserToken: function FullZoom__getBrowserToken(browser) {
+ let map = this._browserTokenMap;
+ if (!map.has(browser))
+ map.set(browser, 0);
+ return {
+ token: map.get(browser),
+ get isCurrent() {
+ // At this point, the browser may have been destructed and unbound but
+ // its outer ID not removed from the map because outer-window-destroyed
+ // hasn't been received yet. In that case, the browser is unusable, it
+ // has no properties, so return false. Check for this case by getting a
+ // property, say, docShell.
+ return map.get(browser) === this.token && browser.parentNode;
+ },
+ };
+ },
+
+ /**
+ * Returns the browser that the supplied zoom event is associated with.
+ * @param event The ZoomChangeUsingMouseWheel event.
+ * @return The associated browser element, if one exists, otherwise null.
+ */
+ _getTargetedBrowser: function FullZoom__getTargetedBrowser(event) {
+ let target = event.originalTarget;
+
+ // With remote content browsers, the event's target is the browser
+ // we're looking for.
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ if (target instanceof window.XULElement &&
+ target.localName == "browser" &&
+ target.namespaceURI == XUL_NS)
+ return target;
+
+ // With in-process content browsers, the event's target is the content
+ // document.
+ if (target.nodeType == Node.DOCUMENT_NODE)
+ return gBrowser.getBrowserForDocument(target);
+
+ throw new Error("Unexpected ZoomChangeUsingMouseWheel event source");
+ },
+
+ /**
+ * Increments the zoom change token for the given browser so that pending
+ * async operations know that it may be unsafe to access they zoom when they
+ * finish.
+ *
+ * @param browser Pending accesses in this browser will be ignored.
+ */
+ _ignorePendingZoomAccesses: function FullZoom__ignorePendingZoomAccesses(browser) {
+ let map = this._browserTokenMap;
+ map.set(browser, (map.get(browser) || 0) + 1);
+ },
+
+ _ensureValid: function FullZoom__ensureValid(aValue) {
+ // Note that undefined is a valid value for aValue that indicates a known-
+ // not-to-exist value.
+ if (isNaN(aValue))
+ return 1;
+
+ if (aValue < ZoomManager.MIN)
+ return ZoomManager.MIN;
+
+ if (aValue > ZoomManager.MAX)
+ return ZoomManager.MAX;
+
+ return aValue;
+ },
+
+ /**
+ * Gets the global browser.content.full-zoom content preference.
+ *
+ * @param browser The browser pertaining to the zoom.
+ * @returns Promise
+ * Resolves to the preference value when done.
+ */
+ _getGlobalValue: function FullZoom__getGlobalValue(browser) {
+ // * !("_globalValue" in this) => global value not yet cached.
+ // * this._globalValue === undefined => global value known not to exist.
+ // * Otherwise, this._globalValue is a number, the global value.
+ return new Promise(resolve => {
+ if ("_globalValue" in this) {
+ resolve(this._globalValue);
+ return;
+ }
+ let value = undefined;
+ this._cps2.getGlobal(this.name, this._loadContextFromBrowser(browser), {
+ handleResult: function (pref) { value = pref.value; },
+ handleCompletion: (reason) => {
+ this._globalValue = this._ensureValid(value);
+ resolve(this._globalValue);
+ }
+ });
+ });
+ },
+
+ /**
+ * Gets the load context from the given Browser.
+ *
+ * @param Browser The Browser whose load context will be returned.
+ * @return The nsILoadContext of the given Browser.
+ */
+ _loadContextFromBrowser: function FullZoom__loadContextFromBrowser(browser) {
+ return browser.loadContext;
+ },
+
+ /**
+ * Asynchronously broadcasts "browser-fullZoom:location-change" so that
+ * listeners can be notified when the zoom levels on those pages change.
+ * The notification is always asynchronous so that observers are guaranteed a
+ * consistent behavior.
+ */
+ _notifyOnLocationChange: function FullZoom__notifyOnLocationChange(browser) {
+ this._executeSoon(function () {
+ Services.obs.notifyObservers(browser, "browser-fullZoom:location-change", "");
+ });
+ },
+
+ _executeSoon: function FullZoom__executeSoon(callback) {
+ if (!callback)
+ return;
+ Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+ },
+};
diff --git a/base/content/browser-gestureSupport.js b/base/content/browser-gestureSupport.js
new file mode 100644
index 0000000..13eb71b
--- /dev/null
+++ b/base/content/browser-gestureSupport.js
@@ -0,0 +1,1059 @@
+# 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/.
+
+// Simple gestures support
+//
+// As per bug #412486, web content must not be allowed to receive any
+// simple gesture events. Multi-touch gesture APIs are in their
+// infancy and we do NOT want to be forced into supporting an API that
+// will probably have to change in the future. (The current Mac OS X
+// API is undocumented and was reverse-engineered.) Until support is
+// implemented in the event dispatcher to keep these events as
+// chrome-only, we must listen for the simple gesture events during
+// the capturing phase and call stopPropagation on every event.
+
+var gGestureSupport = {
+ _currentRotation: 0,
+ _lastRotateDelta: 0,
+ _rotateMomentumThreshold: .75,
+
+ /**
+ * Add or remove mouse gesture event listeners
+ *
+ * @param aAddListener
+ * True to add/init listeners and false to remove/uninit
+ */
+ init: function GS_init(aAddListener) {
+ // Bug 863514 - Make gesture support work in electrolysis
+ if (gMultiProcessBrowser)
+ return;
+
+ const gestureEvents = ["SwipeGestureStart",
+ "SwipeGestureUpdate", "SwipeGestureEnd", "SwipeGesture",
+ "MagnifyGestureStart", "MagnifyGestureUpdate", "MagnifyGesture",
+ "RotateGestureStart", "RotateGestureUpdate", "RotateGesture",
+ "TapGesture", "PressTapGesture"];
+
+ let addRemove = aAddListener ? window.addEventListener :
+ window.removeEventListener;
+
+ gestureEvents.forEach(function (event) addRemove("Moz" + event, this, true),
+ this);
+ },
+
+ /**
+ * Dispatch events based on the type of mouse gesture event. For now, make
+ * sure to stop propagation of every gesture event so that web content cannot
+ * receive gesture events.
+ *
+ * @param aEvent
+ * The gesture event to handle
+ */
+ handleEvent: function GS_handleEvent(aEvent) {
+ if (!Services.prefs.getBoolPref(
+ "dom.debug.propagate_gesture_events_through_content")) {
+ aEvent.stopPropagation();
+ }
+
+ // Create a preference object with some defaults
+ let def = function(aThreshold, aLatched)
+ ({ threshold: aThreshold, latched: !!aLatched });
+
+ switch (aEvent.type) {
+ case "MozSwipeGestureStart":
+ aEvent.preventDefault();
+ this._setupSwipeGesture(aEvent);
+ break;
+ case "MozSwipeGestureUpdate":
+ aEvent.preventDefault();
+ this._doUpdate(aEvent);
+ break;
+ case "MozSwipeGestureEnd":
+ aEvent.preventDefault();
+ this._doEnd(aEvent);
+ break;
+ case "MozSwipeGesture":
+ aEvent.preventDefault();
+ this.onSwipe(aEvent);
+ break;
+ case "MozMagnifyGestureStart":
+ aEvent.preventDefault();
+#ifdef XP_WIN
+ this._setupGesture(aEvent, "pinch", def(25, 0), "out", "in");
+#else
+ this._setupGesture(aEvent, "pinch", def(150, 1), "out", "in");
+#endif
+ break;
+ case "MozRotateGestureStart":
+ aEvent.preventDefault();
+ this._setupGesture(aEvent, "twist", def(25, 0), "right", "left");
+ break;
+ case "MozMagnifyGestureUpdate":
+ case "MozRotateGestureUpdate":
+ aEvent.preventDefault();
+ this._doUpdate(aEvent);
+ break;
+ case "MozTapGesture":
+ aEvent.preventDefault();
+ this._doAction(aEvent, ["tap"]);
+ break;
+ case "MozRotateGesture":
+ aEvent.preventDefault();
+ this._doAction(aEvent, ["twist", "end"]);
+ break;
+ /* case "MozPressTapGesture":
+ break; */
+ }
+ },
+
+ /**
+ * Called at the start of "pinch" and "twist" gestures to setup all of the
+ * information needed to process the gesture
+ *
+ * @param aEvent
+ * The continual motion start event to handle
+ * @param aGesture
+ * Name of the gesture to handle
+ * @param aPref
+ * Preference object with the names of preferences and defaults
+ * @param aInc
+ * Command to trigger for increasing motion (without gesture name)
+ * @param aDec
+ * Command to trigger for decreasing motion (without gesture name)
+ */
+ _setupGesture: function GS__setupGesture(aEvent, aGesture, aPref, aInc, aDec) {
+ // Try to load user-set values from preferences
+ for (let [pref, def] in Iterator(aPref))
+ aPref[pref] = this._getPref(aGesture + "." + pref, def);
+
+ // Keep track of the total deltas and latching behavior
+ let offset = 0;
+ let latchDir = aEvent.delta > 0 ? 1 : -1;
+ let isLatched = false;
+
+ // Create the update function here to capture closure state
+ this._doUpdate = function GS__doUpdate(aEvent) {
+ // Update the offset with new event data
+ offset += aEvent.delta;
+
+ // Check if the cumulative deltas exceed the threshold
+ if (Math.abs(offset) > aPref["threshold"]) {
+ // Trigger the action if we don't care about latching; otherwise, make
+ // sure either we're not latched and going the same direction of the
+ // initial motion; or we're latched and going the opposite way
+ let sameDir = (latchDir ^ offset) >= 0;
+ if (!aPref["latched"] || (isLatched ^ sameDir)) {
+ this._doAction(aEvent, [aGesture, offset > 0 ? aInc : aDec]);
+
+ // We must be getting latched or leaving it, so just toggle
+ isLatched = !isLatched;
+ }
+
+ // Reset motion counter to prepare for more of the same gesture
+ offset = 0;
+ }
+ };
+
+ // The start event also contains deltas, so handle an update right away
+ this._doUpdate(aEvent);
+ },
+
+ /**
+ * Checks whether a swipe gesture event can navigate the browser history or
+ * not.
+ *
+ * @param aEvent
+ * The swipe gesture event.
+ * @return true if the swipe event may navigate the history, false othwerwise.
+ */
+ _swipeNavigatesHistory: function GS__swipeNavigatesHistory(aEvent) {
+ return this._getCommand(aEvent, ["swipe", "left"])
+ == "Browser:BackOrBackDuplicate" &&
+ this._getCommand(aEvent, ["swipe", "right"])
+ == "Browser:ForwardOrForwardDuplicate";
+ },
+
+ /**
+ * Sets up the history swipe animations for a swipe gesture event, if enabled.
+ *
+ * @param aEvent
+ * The swipe gesture start event.
+ */
+ _setupSwipeGesture: function GS__setupSwipeGesture(aEvent) {
+ if (!this._swipeNavigatesHistory(aEvent))
+ return;
+
+ let canGoBack = gHistorySwipeAnimation.canGoBack();
+ let canGoForward = gHistorySwipeAnimation.canGoForward();
+ let isLTR = gHistorySwipeAnimation.isLTR;
+
+ if (canGoBack)
+ aEvent.allowedDirections |= isLTR ? aEvent.DIRECTION_LEFT :
+ aEvent.DIRECTION_RIGHT;
+ if (canGoForward)
+ aEvent.allowedDirections |= isLTR ? aEvent.DIRECTION_RIGHT :
+ aEvent.DIRECTION_LEFT;
+
+ gHistorySwipeAnimation.startAnimation();
+
+ this._doUpdate = function GS__doUpdate(aEvent) {
+ gHistorySwipeAnimation.updateAnimation(aEvent.delta);
+ };
+
+ this._doEnd = function GS__doEnd(aEvent) {
+ gHistorySwipeAnimation.swipeEndEventReceived();
+
+ this._doUpdate = function (aEvent) {};
+ this._doEnd = function (aEvent) {};
+ }
+ },
+
+ /**
+ * Generator producing the powerset of the input array where the first result
+ * is the complete set and the last result (before StopIteration) is empty.
+ *
+ * @param aArray
+ * Source array containing any number of elements
+ * @yield Array that is a subset of the input array from full set to empty
+ */
+ _power: function GS__power(aArray) {
+ // Create a bitmask based on the length of the array
+ let num = 1 << aArray.length;
+ while (--num >= 0) {
+ // Only select array elements where the current bit is set
+ yield aArray.reduce(function (aPrev, aCurr, aIndex) {
+ if (num & 1 << aIndex)
+ aPrev.push(aCurr);
+ return aPrev;
+ }, []);
+ }
+ },
+
+ /**
+ * Determine what action to do for the gesture based on which keys are
+ * pressed and which commands are set, and execute the command.
+ *
+ * @param aEvent
+ * The original gesture event to convert into a fake click event
+ * @param aGesture
+ * Array of gesture name parts (to be joined by periods)
+ * @return Name of the executed command. Returns null if no command is
+ * found.
+ */
+ _doAction: function GS__doAction(aEvent, aGesture) {
+ let command = this._getCommand(aEvent, aGesture);
+ return command && this._doCommand(aEvent, command);
+ },
+
+ /**
+ * Determine what action to do for the gesture based on which keys are
+ * pressed and which commands are set
+ *
+ * @param aEvent
+ * The original gesture event to convert into a fake click event
+ * @param aGesture
+ * Array of gesture name parts (to be joined by periods)
+ */
+ _getCommand: function GS__getCommand(aEvent, aGesture) {
+ // Create an array of pressed keys in a fixed order so that a command for
+ // "meta" is preferred over "ctrl" when both buttons are pressed (and a
+ // command for both don't exist)
+ let keyCombos = [];
+ ["shift", "alt", "ctrl", "meta"].forEach(function (key) {
+ if (aEvent[key + "Key"])
+ keyCombos.push(key);
+ });
+
+ // Try each combination of key presses in decreasing order for commands
+ for (let subCombo of this._power(keyCombos)) {
+ // Convert a gesture and pressed keys into the corresponding command
+ // action where the preference has the gesture before "shift" before
+ // "alt" before "ctrl" before "meta" all separated by periods
+ let command;
+ try {
+ command = this._getPref(aGesture.concat(subCombo).join("."));
+ } catch (e) {}
+
+ if (command)
+ return command;
+ }
+ return null;
+ },
+
+ /**
+ * Execute the specified command.
+ *
+ * @param aEvent
+ * The original gesture event to convert into a fake click event
+ * @param aCommand
+ * Name of the command found for the event's keys and gesture.
+ */
+ _doCommand: function GS__doCommand(aEvent, aCommand) {
+ let node = document.getElementById(aCommand);
+ if (node) {
+ if (node.getAttribute("disabled") != "true") {
+ let cmdEvent = document.createEvent("xulcommandevent");
+ cmdEvent.initCommandEvent("command", true, true, window, 0,
+ aEvent.ctrlKey, aEvent.altKey,
+ aEvent.shiftKey, aEvent.metaKey, aEvent);
+ node.dispatchEvent(cmdEvent);
+ }
+
+ }
+ else {
+ goDoCommand(aCommand);
+ }
+ },
+
+ /**
+ * Handle continual motion events. This function will be set by
+ * _setupGesture or _setupSwipe.
+ *
+ * @param aEvent
+ * The continual motion update event to handle
+ */
+ _doUpdate: function(aEvent) {},
+
+ /**
+ * Handle gesture end events. This function will be set by _setupSwipe.
+ *
+ * @param aEvent
+ * The gesture end event to handle
+ */
+ _doEnd: function(aEvent) {},
+
+ /**
+ * Convert the swipe gesture into a browser action based on the direction.
+ *
+ * @param aEvent
+ * The swipe event to handle
+ */
+ onSwipe: function GS_onSwipe(aEvent) {
+ // Figure out which one (and only one) direction was triggered
+ for (let dir of ["UP", "RIGHT", "DOWN", "LEFT"]) {
+ if (aEvent.direction == aEvent["DIRECTION_" + dir]) {
+ this._coordinateSwipeEventWithAnimation(aEvent, dir);
+ break;
+ }
+ }
+ },
+
+ /**
+ * Process a swipe event based on the given direction.
+ *
+ * @param aEvent
+ * The swipe event to handle
+ * @param aDir
+ * The direction for the swipe event
+ */
+ processSwipeEvent: function GS_processSwipeEvent(aEvent, aDir) {
+ this._doAction(aEvent, ["swipe", aDir.toLowerCase()]);
+ },
+
+ /**
+ * Coordinates the swipe event with the swipe animation, if any.
+ * If an animation is currently running, the swipe event will be
+ * processed once the animation stops. This will guarantee a fluid
+ * motion of the animation.
+ *
+ * @param aEvent
+ * The swipe event to handle
+ * @param aDir
+ * The direction for the swipe event
+ */
+ _coordinateSwipeEventWithAnimation:
+ function GS__coordinateSwipeEventWithAnimation(aEvent, aDir) {
+ if ((gHistorySwipeAnimation.isAnimationRunning()) &&
+ (aDir == "RIGHT" || aDir == "LEFT")) {
+ gHistorySwipeAnimation.processSwipeEvent(aEvent, aDir);
+ }
+ else {
+ this.processSwipeEvent(aEvent, aDir);
+ }
+ },
+
+ /**
+ * Get a gesture preference or use a default if it doesn't exist
+ *
+ * @param aPref
+ * Name of the preference to load under the gesture branch
+ * @param aDef
+ * Default value if the preference doesn't exist
+ */
+ _getPref: function GS__getPref(aPref, aDef) {
+ // Preferences branch under which all gestures preferences are stored
+ const branch = "browser.gesture.";
+
+ try {
+ // Determine what type of data to load based on default value's type
+ let type = typeof aDef;
+ let getFunc = "get" + (type == "boolean" ? "Bool" :
+ type == "number" ? "Int" : "Char") + "Pref";
+ return gPrefService[getFunc](branch + aPref);
+ }
+ catch (e) {
+ return aDef;
+ }
+ },
+
+ /**
+ * Perform rotation for ImageDocuments
+ *
+ * @param aEvent
+ * The MozRotateGestureUpdate event triggering this call
+ */
+ rotate: function(aEvent) {
+ if (!(content.document instanceof ImageDocument))
+ return;
+
+ let contentElement = content.document.body.firstElementChild;
+ if (!contentElement)
+ return;
+ // If we're currently snapping, cancel that snap
+ if (contentElement.classList.contains("completeRotation"))
+ this._clearCompleteRotation();
+
+ this.rotation = Math.round(this.rotation + aEvent.delta);
+ contentElement.style.transform = "rotate(" + this.rotation + "deg)";
+ this._lastRotateDelta = aEvent.delta;
+ },
+
+ /**
+ * Perform a rotation end for ImageDocuments
+ */
+ rotateEnd: function() {
+ if (!(content.document instanceof ImageDocument))
+ return;
+
+ let contentElement = content.document.body.firstElementChild;
+ if (!contentElement)
+ return;
+
+ let transitionRotation = 0;
+
+ // The reason that 360 is allowed here is because when rotating between
+ // 315 and 360, setting rotate(0deg) will cause it to rotate the wrong
+ // direction around--spinning wildly.
+ if (this.rotation <= 45)
+ transitionRotation = 0;
+ else if (this.rotation > 45 && this.rotation <= 135)
+ transitionRotation = 90;
+ else if (this.rotation > 135 && this.rotation <= 225)
+ transitionRotation = 180;
+ else if (this.rotation > 225 && this.rotation <= 315)
+ transitionRotation = 270;
+ else
+ transitionRotation = 360;
+
+ // If we're going fast enough, and we didn't already snap ahead of rotation,
+ // then snap ahead of rotation to simulate momentum
+ if (this._lastRotateDelta > this._rotateMomentumThreshold &&
+ this.rotation > transitionRotation)
+ transitionRotation += 90;
+ else if (this._lastRotateDelta < -1 * this._rotateMomentumThreshold &&
+ this.rotation < transitionRotation)
+ transitionRotation -= 90;
+
+ // Only add the completeRotation class if it is is necessary
+ if (transitionRotation != this.rotation) {
+ contentElement.classList.add("completeRotation");
+ contentElement.addEventListener("transitionend", this._clearCompleteRotation);
+ }
+
+ contentElement.style.transform = "rotate(" + transitionRotation + "deg)";
+ this.rotation = transitionRotation;
+ },
+
+ /**
+ * Gets the current rotation for the ImageDocument
+ */
+ get rotation() {
+ return this._currentRotation;
+ },
+
+ /**
+ * Sets the current rotation for the ImageDocument
+ *
+ * @param aVal
+ * The new value to take. Can be any value, but it will be bounded to
+ * 0 inclusive to 360 exclusive.
+ */
+ set rotation(aVal) {
+ this._currentRotation = aVal % 360;
+ if (this._currentRotation < 0)
+ this._currentRotation += 360;
+ return this._currentRotation;
+ },
+
+ /**
+ * When the location/tab changes, need to reload the current rotation for the
+ * image
+ */
+ restoreRotationState: function() {
+ // Bug 863514 - Make gesture support work in electrolysis
+ if (gMultiProcessBrowser)
+ return;
+
+ if (!(content.document instanceof ImageDocument))
+ return;
+
+ let contentElement = content.document.body.firstElementChild;
+ let transformValue = content.window.getComputedStyle(contentElement, null)
+ .transform;
+
+ if (transformValue == "none") {
+ this.rotation = 0;
+ return;
+ }
+
+ // transformValue is a rotation matrix--split it and do mathemagic to
+ // obtain the real rotation value
+ transformValue = transformValue.split("(")[1]
+ .split(")")[0]
+ .split(",");
+ this.rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) *
+ (180 / Math.PI));
+ },
+
+ /**
+ * Removes the transition rule by removing the completeRotation class
+ */
+ _clearCompleteRotation: function() {
+ let contentElement = content.document &&
+ content.document instanceof ImageDocument &&
+ content.document.body &&
+ content.document.body.firstElementChild;
+ if (!contentElement)
+ return;
+ contentElement.classList.remove("completeRotation");
+ contentElement.removeEventListener("transitionend", this._clearCompleteRotation);
+ },
+};
+
+// History Swipe Animation Support (bug 678392)
+var gHistorySwipeAnimation = {
+
+ active: false,
+ isLTR: false,
+
+ /**
+ * Initializes the support for history swipe animations, if it is supported
+ * by the platform/configuration.
+ */
+ init: function HSA_init() {
+ if (!this._isSupported())
+ return;
+
+ this.active = false;
+ this.isLTR = document.documentElement.mozMatchesSelector(
+ ":-moz-locale-dir(ltr)");
+ this._trackedSnapshots = [];
+ this._historyIndex = -1;
+ this._boxWidth = -1;
+ this._maxSnapshots = this._getMaxSnapshots();
+ this._lastSwipeDir = "";
+
+ // We only want to activate history swipe animations if we store snapshots.
+ // If we don't store any, we handle horizontal swipes without animations.
+ if (this._maxSnapshots > 0) {
+ this.active = true;
+ gBrowser.addEventListener("pagehide", this, false);
+ gBrowser.addEventListener("pageshow", this, false);
+ gBrowser.addEventListener("popstate", this, false);
+ gBrowser.tabContainer.addEventListener("TabClose", this, false);
+ }
+ },
+
+ /**
+ * Uninitializes the support for history swipe animations.
+ */
+ uninit: function HSA_uninit() {
+ gBrowser.removeEventListener("pagehide", this, false);
+ gBrowser.removeEventListener("pageshow", this, false);
+ gBrowser.removeEventListener("popstate", this, false);
+ gBrowser.tabContainer.removeEventListener("TabClose", this, false);
+
+ this.active = false;
+ this.isLTR = false;
+ },
+
+ /**
+ * Starts the swipe animation and handles fast swiping (i.e. a swipe animation
+ * is already in progress when a new one is initiated).
+ */
+ startAnimation: function HSA_startAnimation() {
+ if (this.isAnimationRunning()) {
+ gBrowser.stop();
+ this._lastSwipeDir = "RELOAD"; // just ensure that != ""
+ this._canGoBack = this.canGoBack();
+ this._canGoForward = this.canGoForward();
+ this._handleFastSwiping();
+ }
+ else {
+ this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
+ this._canGoBack = this.canGoBack();
+ this._canGoForward = this.canGoForward();
+ if (this.active) {
+ this._takeSnapshot();
+ this._installPrevAndNextSnapshots();
+ this._addBoxes();
+ this._lastSwipeDir = "";
+ }
+ }
+ this.updateAnimation(0);
+ },
+
+ /**
+ * Stops the swipe animation.
+ */
+ stopAnimation: function HSA_stopAnimation() {
+ gHistorySwipeAnimation._removeBoxes();
+ },
+
+ /**
+ * Updates the animation between two pages in history.
+ *
+ * @param aVal
+ * A floating point value that represents the progress of the
+ * swipe gesture.
+ */
+ updateAnimation: function HSA_updateAnimation(aVal) {
+ if (!this.isAnimationRunning())
+ return;
+
+ if ((aVal >= 0 && this.isLTR) ||
+ (aVal <= 0 && !this.isLTR)) {
+ if (aVal > 1)
+ aVal = 1; // Cap value to avoid sliding the page further than allowed.
+
+ if (this._canGoBack)
+ this._prevBox.collapsed = false;
+ else
+ this._prevBox.collapsed = true;
+
+ // The current page is pushed to the right (LTR) or left (RTL),
+ // the intention is to go back.
+ // If there is a page to go back to, it should show in the background.
+ this._positionBox(this._curBox, aVal);
+
+ // The forward page should be pushed offscreen all the way to the right.
+ this._positionBox(this._nextBox, 1);
+ }
+ else {
+ if (aVal < -1)
+ aVal = -1; // Cap value to avoid sliding the page further than allowed.
+
+ // The intention is to go forward. If there is a page to go forward to,
+ // it should slide in from the right (LTR) or left (RTL).
+ // Otherwise, the current page should slide to the left (LTR) or
+ // right (RTL) and the backdrop should appear in the background.
+ // For the backdrop to be visible in that case, the previous page needs
+ // to be hidden (if it exists).
+ if (this._canGoForward) {
+ let offset = this.isLTR ? 1 : -1;
+ this._positionBox(this._curBox, 0);
+ this._positionBox(this._nextBox, offset + aVal); // aVal is negative
+ }
+ else {
+ this._prevBox.collapsed = true;
+ this._positionBox(this._curBox, aVal);
+ }
+ }
+ },
+
+ /**
+ * Event handler for events relevant to the history swipe animation.
+ *
+ * @param aEvent
+ * An event to process.
+ */
+ handleEvent: function HSA_handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "TabClose":
+ let browser = gBrowser.getBrowserForTab(aEvent.target);
+ this._removeTrackedSnapshot(-1, browser);
+ break;
+ case "pageshow":
+ case "popstate":
+ if (this.isAnimationRunning()) {
+ if (aEvent.target != gBrowser.selectedBrowser.contentDocument)
+ break;
+ this.stopAnimation();
+ }
+ this._historyIndex = gBrowser.webNavigation.sessionHistory.index;
+ break;
+ case "pagehide":
+ if (aEvent.target == gBrowser.selectedBrowser.contentDocument) {
+ // Take a snapshot of a page whenever it's about to be navigated away
+ // from.
+ this._takeSnapshot();
+ }
+ break;
+ }
+ },
+
+ /**
+ * Checks whether the history swipe animation is currently running or not.
+ *
+ * @return true if the animation is currently running, false otherwise.
+ */
+ isAnimationRunning: function HSA_isAnimationRunning() {
+ return !!this._container;
+ },
+
+ /**
+ * Process a swipe event based on the given direction.
+ *
+ * @param aEvent
+ * The swipe event to handle
+ * @param aDir
+ * The direction for the swipe event
+ */
+ processSwipeEvent: function HSA_processSwipeEvent(aEvent, aDir) {
+ if (aDir == "RIGHT")
+ this._historyIndex += this.isLTR ? 1 : -1;
+ else if (aDir == "LEFT")
+ this._historyIndex += this.isLTR ? -1 : 1;
+ else
+ return;
+ this._lastSwipeDir = aDir;
+ },
+
+ /**
+ * Checks if there is a page in the browser history to go back to.
+ *
+ * @return true if there is a previous page in history, false otherwise.
+ */
+ canGoBack: function HSA_canGoBack() {
+ if (this.isAnimationRunning())
+ return this._doesIndexExistInHistory(this._historyIndex - 1);
+ return gBrowser.webNavigation.canGoBack;
+ },
+
+ /**
+ * Checks if there is a page in the browser history to go forward to.
+ *
+ * @return true if there is a next page in history, false otherwise.
+ */
+ canGoForward: function HSA_canGoForward() {
+ if (this.isAnimationRunning())
+ return this._doesIndexExistInHistory(this._historyIndex + 1);
+ return gBrowser.webNavigation.canGoForward;
+ },
+
+ /**
+ * Used to notify the history swipe animation that the OS sent a swipe end
+ * event and that we should navigate to the page that the user swiped to, if
+ * any. This will also result in the animation overlay to be torn down.
+ */
+ swipeEndEventReceived: function HSA_swipeEndEventReceived() {
+ if (this._lastSwipeDir != "")
+ this._navigateToHistoryIndex();
+ else
+ this.stopAnimation();
+ },
+
+ /**
+ * Checks whether a particular index exists in the browser history or not.
+ *
+ * @param aIndex
+ * The index to check for availability for in the history.
+ * @return true if the index exists in the browser history, false otherwise.
+ */
+ _doesIndexExistInHistory: function HSA__doesIndexExistInHistory(aIndex) {
+ try {
+ gBrowser.webNavigation.sessionHistory.getEntryAtIndex(aIndex, false);
+ }
+ catch(ex) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Navigates to the index in history that is currently being tracked by
+ * |this|.
+ */
+ _navigateToHistoryIndex: function HSA__navigateToHistoryIndex() {
+ if (this._doesIndexExistInHistory(this._historyIndex)) {
+ gBrowser.webNavigation.gotoIndex(this._historyIndex);
+ }
+ },
+
+ /**
+ * Checks to see if history swipe animations are supported by this
+ * platform/configuration.
+ *
+ * return true if supported, false otherwise.
+ */
+ _isSupported: function HSA__isSupported() {
+ return window.matchMedia("(-moz-swipe-animation-enabled)").matches;
+ },
+
+ /**
+ * Handle fast swiping (i.e. a swipe animation is already in
+ * progress when a new one is initiated). This will swap out the snapshots
+ * used in the previous animation with the appropriate new ones.
+ */
+ _handleFastSwiping: function HSA__handleFastSwiping() {
+ this._installCurrentPageSnapshot(null);
+ this._installPrevAndNextSnapshots();
+ },
+
+ /**
+ * Adds the boxes that contain the snapshots used during the swipe animation.
+ */
+ _addBoxes: function HSA__addBoxes() {
+ let browserStack =
+ document.getAnonymousElementByAttribute(gBrowser.getNotificationBox(),
+ "class", "browserStack");
+ this._container = this._createElement("historySwipeAnimationContainer",
+ "stack");
+ browserStack.appendChild(this._container);
+
+ this._prevBox = this._createElement("historySwipeAnimationPreviousPage",
+ "box");
+ this._container.appendChild(this._prevBox);
+
+ this._curBox = this._createElement("historySwipeAnimationCurrentPage",
+ "box");
+ this._container.appendChild(this._curBox);
+
+ this._nextBox = this._createElement("historySwipeAnimationNextPage",
+ "box");
+ this._container.appendChild(this._nextBox);
+
+ this._boxWidth = this._curBox.getBoundingClientRect().width; // cache width
+ },
+
+ /**
+ * Removes the boxes.
+ */
+ _removeBoxes: function HSA__removeBoxes() {
+ this._curBox = null;
+ this._prevBox = null;
+ this._nextBox = null;
+ if (this._container)
+ this._container.parentNode.removeChild(this._container);
+ this._container = null;
+ this._boxWidth = -1;
+ },
+
+ /**
+ * Creates an element with a given identifier and tag name.
+ *
+ * @param aID
+ * An identifier to create the element with.
+ * @param aTagName
+ * The name of the tag to create the element for.
+ * @return the newly created element.
+ */
+ _createElement: function HSA__createElement(aID, aTagName) {
+ let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let element = document.createElementNS(XULNS, aTagName);
+ element.id = aID;
+ return element;
+ },
+
+ /**
+ * Moves a given box to a given X coordinate position.
+ *
+ * @param aBox
+ * The box element to position.
+ * @param aPosition
+ * The position (in X coordinates) to move the box element to.
+ */
+ _positionBox: function HSA__positionBox(aBox, aPosition) {
+ aBox.style.transform = "translateX(" + this._boxWidth * aPosition + "px)";
+ },
+
+ /**
+ * Takes a snapshot of the page the browser is currently on.
+ */
+ _takeSnapshot: function HSA__takeSnapshot() {
+ if ((this._maxSnapshots < 1) ||
+ (gBrowser.webNavigation.sessionHistory.index < 0))
+ return;
+
+ let browser = gBrowser.selectedBrowser;
+ let r = browser.getBoundingClientRect();
+ let canvas = document.createElementNS("http://www.w3.org/1999/xhtml",
+ "canvas");
+ canvas.mozOpaque = true;
+ canvas.width = r.width;
+ canvas.height = r.height;
+ let ctx = canvas.getContext("2d");
+ let zoom = browser.markupDocumentViewer.fullZoom;
+ ctx.scale(zoom, zoom);
+ ctx.drawWindow(browser.contentWindow, 0, 0, r.width, r.height, "white",
+ ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_VIEW |
+ ctx.DRAWWINDOW_ASYNC_DECODE_IMAGES |
+ ctx.DRAWWINDOW_USE_WIDGET_LAYERS);
+
+ this._installCurrentPageSnapshot(canvas);
+ this._assignSnapshotToCurrentBrowser(canvas);
+ },
+
+ /**
+ * Retrieves the maximum number of snapshots that should be kept in memory.
+ * This limit is a global limit and is valid across all open tabs.
+ */
+ _getMaxSnapshots: function HSA__getMaxSnapshots() {
+ return gPrefService.getIntPref("browser.snapshots.limit");
+ },
+
+ /**
+ * Adds a snapshot to the list and initiates the compression of said snapshot.
+ * Once the compression is completed, it will replace the uncompressed
+ * snapshot in the list.
+ *
+ * @param aCanvas
+ * The snapshot to add to the list and compress.
+ */
+ _assignSnapshotToCurrentBrowser:
+ function HSA__assignSnapshotToCurrentBrowser(aCanvas) {
+ let browser = gBrowser.selectedBrowser;
+ let currIndex = browser.webNavigation.sessionHistory.index;
+
+ this._removeTrackedSnapshot(currIndex, browser);
+ this._addSnapshotRefToArray(currIndex, browser);
+
+ if (!("snapshots" in browser))
+ browser.snapshots = [];
+ let snapshots = browser.snapshots;
+ // Temporarily store the canvas as the compressed snapshot.
+ // This avoids a blank page if the user swipes quickly
+ // between pages before the compression could complete.
+ snapshots[currIndex] = aCanvas;
+
+ // Kick off snapshot compression.
+ aCanvas.toBlob(function(aBlob) {
+ snapshots[currIndex] = aBlob;
+ }, "image/png"
+ );
+ },
+
+ /**
+ * Removes a snapshot identified by the browser and index in the array of
+ * snapshots for that browser, if present. If no snapshot could be identified
+ * the method simply returns without taking any action. If aIndex is negative,
+ * all snapshots for a particular browser will be removed.
+ *
+ * @param aIndex
+ * The index in history of the new snapshot, or negative value if all
+ * snapshots for a browser should be removed.
+ * @param aBrowser
+ * The browser the new snapshot was taken in.
+ */
+ _removeTrackedSnapshot: function HSA__removeTrackedSnapshot(aIndex, aBrowser) {
+ let arr = this._trackedSnapshots;
+ let requiresExactIndexMatch = aIndex >= 0;
+ for (let i = 0; i < arr.length; i++) {
+ if ((arr[i].browser == aBrowser) &&
+ (aIndex < 0 || aIndex == arr[i].index)) {
+ delete aBrowser.snapshots[arr[i].index];
+ arr.splice(i, 1);
+ if (requiresExactIndexMatch)
+ return; // Found and removed the only element.
+ i--; // Make sure to revisit the index that we just removed an
+ // element at.
+ }
+ }
+ },
+
+ /**
+ * Adds a new snapshot reference for a given index and browser to the array
+ * of references to tracked snapshots.
+ *
+ * @param aIndex
+ * The index in history of the new snapshot.
+ * @param aBrowser
+ * The browser the new snapshot was taken in.
+ */
+ _addSnapshotRefToArray:
+ function HSA__addSnapshotRefToArray(aIndex, aBrowser) {
+ let id = { index: aIndex,
+ browser: aBrowser };
+ let arr = this._trackedSnapshots;
+ arr.unshift(id);
+
+ while (arr.length > this._maxSnapshots) {
+ let lastElem = arr[arr.length - 1];
+ delete lastElem.browser.snapshots[lastElem.index];
+ arr.splice(-1, 1);
+ }
+ },
+
+ /**
+ * Converts a compressed blob to an Image object. In some situations
+ * (especially during fast swiping) aBlob may still be a canvas, not a
+ * compressed blob. In this case, we simply return the canvas.
+ *
+ * @param aBlob
+ * The compressed blob to convert, or a canvas if a blob compression
+ * couldn't complete before this method was called.
+ * @return A new Image object representing the converted blob.
+ */
+ _convertToImg: function HSA__convertToImg(aBlob) {
+ if (!aBlob)
+ return null;
+
+ // Return aBlob if it's still a canvas and not a compressed blob yet.
+ if (aBlob instanceof HTMLCanvasElement)
+ return aBlob;
+
+ let img = new Image();
+ let url = URL.createObjectURL(aBlob);
+ img.onload = function() {
+ URL.revokeObjectURL(url);
+ };
+ img.src = url;
+ return img;
+ },
+
+ /**
+ * Sets the snapshot of the current page to the snapshot passed as parameter,
+ * or to the one previously stored for the current index in history if the
+ * parameter is null.
+ *
+ * @param aCanvas
+ * The snapshot to set the current page to. If this parameter is null,
+ * the previously stored snapshot for this index (if any) will be used.
+ */
+ _installCurrentPageSnapshot:
+ function HSA__installCurrentPageSnapshot(aCanvas) {
+ let currSnapshot = aCanvas;
+ if (!currSnapshot) {
+ let snapshots = gBrowser.selectedBrowser.snapshots || {};
+ let currIndex = this._historyIndex;
+ if (currIndex in snapshots)
+ currSnapshot = this._convertToImg(snapshots[currIndex]);
+ }
+ document.mozSetImageElement("historySwipeAnimationCurrentPageSnapshot",
+ currSnapshot);
+ },
+
+ /**
+ * Sets the snapshots of the previous and next pages to the snapshots
+ * previously stored for their respective indeces.
+ */
+ _installPrevAndNextSnapshots:
+ function HSA__installPrevAndNextSnapshots() {
+ let snapshots = gBrowser.selectedBrowser.snapshots || [];
+ let currIndex = this._historyIndex;
+ let prevIndex = currIndex - 1;
+ let prevSnapshot = null;
+ if (prevIndex in snapshots)
+ prevSnapshot = this._convertToImg(snapshots[prevIndex]);
+ document.mozSetImageElement("historySwipeAnimationPreviousPageSnapshot",
+ prevSnapshot);
+
+ let nextIndex = currIndex + 1;
+ let nextSnapshot = null;
+ if (nextIndex in snapshots)
+ nextSnapshot = this._convertToImg(snapshots[nextIndex]);
+ document.mozSetImageElement("historySwipeAnimationNextPageSnapshot",
+ nextSnapshot);
+ },
+};
diff --git a/base/content/browser-menubar.inc b/base/content/browser-menubar.inc
new file mode 100644
index 0000000..fc6bc76
--- /dev/null
+++ b/base/content/browser-menubar.inc
@@ -0,0 +1,564 @@
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef XP_MACOSX
+
+#endif
+
+
diff --git a/base/content/browser-menudragging.js b/base/content/browser-menudragging.js
new file mode 100644
index 0000000..f3f00d7
--- /dev/null
+++ b/base/content/browser-menudragging.js
@@ -0,0 +1,340 @@
+// 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/.
+//
+// Based on original code by alice0775 https://github.com/alice0775
+
+
+"use strict";
+var browserMenuDragging = {
+ //-- config --
+ STAY_OPEN_ONDRAGEXIT: false,
+ DEBUG: false,
+ //-- config --
+
+ menupopup: ['bookmarksMenuPopup',
+ 'PlacesToolbar',
+ 'BMB_bookmarksPopup',
+ 'appmenu_bookmarksPopup',
+ 'BookmarksMenuToolButtonPopup',
+ 'UnsortedBookmarksFolderToolButtonPopup',
+ 'bookmarksMenuPopup-context'],
+ timer:[],
+ count:[],
+
+
+ init: function(){
+ window.removeEventListener('load', this, false);
+ window.addEventListener('unload', this, false);
+ this.addPrefListener(this.PrefListener);
+
+ window.addEventListener('aftercustomization', this, false);
+
+ this.initPref();
+ this.delayedStartup();
+ },
+
+ uninit: function(){
+ window.removeEventListener('unload', this, false);
+ this.removePrefListener(this.PrefListener);
+
+ window.removeEventListener('aftercustomization', this, false);
+
+ for (var i = 0; i < this.menupopup.length; i++){
+ var menupopup = document.getElementById(this.menupopup[i]);
+ if (menupopup){
+ menupopup.removeEventListener('popupshowing', this, false);
+ menupopup.removeEventListener('popuphiding', this, false);
+ }
+ }
+
+ },
+
+ initPref: function(){
+ this.STAY_OPEN_ONDRAGEXIT =
+ Services.prefs.getBoolPref('browser.menu.dragging.stayOpen', false);
+ this.DEBUG =
+ Services.prefs.getBoolPref('browser.menu.dragging.debug', false);
+ },
+
+ //delayed startup
+ delayedStartup: function(){
+ //wait until construction of bookmarksBarContent is completed.
+ for (var i = 0; i < this.menupopup.length; i++){
+ this.count[i] = 0;
+ this.timer[i] = setInterval(function(self, i){
+ if(++self.count[i] > 50 || document.getElementById(self.menupopup[i])){
+ clearInterval(self.timer[i]);
+ var menupopup = document.getElementById(self.menupopup[i]);
+ if (menupopup) {
+ menupopup.addEventListener('popupshowing', self, false);
+ menupopup.addEventListener('popuphiding', self, false);
+ }
+ }
+ }, 250, this, i);
+ }
+ },
+
+ handleEvent: function(event){
+ switch (event.type) {
+ case 'popupshowing':
+ this.popupshowing(event);
+ break;
+ case 'popuphiding':
+ this.popuphiding(event);
+ break;
+ case 'aftercustomization':
+ setTimeout(function(self){self.delayedStartup(self);}, 0, this);
+ break;
+ case 'load':
+ this.init();
+ break;
+ case 'unload':
+ this.uninit();
+ break;
+ }
+ },
+
+ popuphiding: function(event) {
+ var menupopup = event.originalTarget;
+ menupopup.parentNode.parentNode.openNode = null;
+
+ if (menupopup.parentNode.localName == 'toolbarbutton') {
+ // Fix for Bug 225434 - dragging bookmark from personal toolbar and releasing
+ // (on same bookmark or elsewhere) or clicking on bookmark menu then cancelling
+ // leaves button depressed/sunken when hovered
+ menupopup.parentNode.parentNode._openedMenuButton = null;
+
+ if (!PlacesControllerDragHelper.getSession())
+ // Clear the dragover attribute if present, if we are dragging into a
+ // folder in the hierachy of current opened popup we don't clear
+ // this attribute on clearOverFolder. See Notify for closeTimer.
+ if (menupopup.parentNode.hasAttribute('dragover'))
+ menupopup.parentNode.removeAttribute('dragover');
+ }
+ },
+
+ popupshowing: function(event) {
+ var menupopup = event.originalTarget;
+ browserMenuDragging.debug("popupshowing ===============\n" + menupopup.parentNode.getAttribute('label'));
+
+ var parentPopup = menupopup.parentNode.parentNode;
+
+ if (!!parentPopup.openNode){
+ try {
+ parentPopup.openNode.hidePopup();
+ } catch(e){}
+ }
+ parentPopup.openNode = menupopup;
+
+ menupopup.onDragStart = function (event) {
+ // Bug 555474 - While bookmark is dragged, the tooltip should not appear
+ browserMenuDragging.hideTooltip();
+ }
+
+ menupopup.onDragOver = function (event) {
+ // Bug 555474 - While bookmark is dragged, the tooltip should not appear
+ browserMenuDragging.hideTooltip();
+
+ var target = event.originalTarget;
+ while (target) {
+ if (/menupopup/.test(target.localName))
+ break;
+ target = target.parentNode;
+ }
+ if (this != target)
+ return;
+ event.stopPropagation();
+ browserMenuDragging.debug("onDragOver " + "\n" + this.parentNode.getAttribute('label'));
+
+ PlacesControllerDragHelper.currentDropTarget = event.target;
+ let dt = event.dataTransfer;
+
+ let dropPoint = this._getDropPoint(event);
+
+ if (!dropPoint || !dropPoint.ip ||
+ !PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
+ this._indicatorBar.hidden = true;
+ event.stopPropagation();
+ return;
+ }
+
+ // Mark this popup as being dragged over.
+ this.setAttribute('dragover', 'true');
+
+ if (dropPoint.folderElt) {
+ // We are dragging over a folder.
+ // _overFolder should take the care of opening it on a timer.
+ if (this._overFolder.elt &&
+ this._overFolder.elt != dropPoint.folderElt) {
+ }
+ if (!this._overFolder.elt) {
+ this._overFolder.elt = dropPoint.folderElt;
+ // Create the timer to open this folder.
+ this._overFolder.openTimer = this._overFolder
+ .setTimer(this._overFolder.hoverTime);
+ }
+ }
+ else {
+ // We are not dragging over a folder.
+ }
+
+ // Autoscroll the popup strip if we drag over the scroll buttons.
+ let anonid = event.originalTarget.getAttribute('anonid');
+ let scrollDir = anonid == 'scrollbutton-up' ? -1 :
+ anonid == 'scrollbutton-down' ? 1 : 0;
+ if (scrollDir != 0) {
+ this._scrollBox.scrollByIndex(scrollDir, false);
+ }
+
+ // Check if we should hide the drop indicator for this target.
+ if (dropPoint.folderElt || this._hideDropIndicator(event)) {
+ this._indicatorBar.hidden = true;
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+
+ // We should display the drop indicator relative to the arrowscrollbox.
+ let sbo = this._scrollBox.scrollBoxObject;
+ let newMarginTop = 0;
+ if (scrollDir == 0) {
+ let elt = this.firstChild;
+ while (elt && event.screenY > elt.boxObject.screenY +
+ elt.boxObject.height / 2)
+ elt = elt.nextSibling;
+ newMarginTop = elt ? elt.boxObject.screenY - sbo.screenY :
+ sbo.height;
+ }
+ else if (scrollDir == 1)
+ newMarginTop = sbo.height;
+
+ // Set the new marginTop based on arrowscrollbox.
+ newMarginTop += sbo.y - this._scrollBox.boxObject.y;
+ this._indicatorBar.firstChild.style.marginTop = newMarginTop + 'px';
+ this._indicatorBar.hidden = false;
+
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ menupopup.onDragExit = function (event) {
+ var target = event.originalTarget;
+ while (target) {
+ if (/menupopup/.test(target.localName))
+ break;
+ target = target.parentNode;
+ }
+ if (this != target)
+ return;
+ event.stopPropagation();
+ browserMenuDragging.debug("onDragExit " + browserMenuDragging.STAY_OPEN_ONDRAGEXIT);
+
+ PlacesControllerDragHelper.currentDropTarget = null;
+ this.removeAttribute('dragover');
+
+ // If we have not moved to a valid new target clear the drop indicator
+ // this happens when moving out of the popup.
+ target = event.relatedTarget;
+ if (!target)
+ this._indicatorBar.hidden = true;
+
+ // Close any folder being hovered over
+ if (this._overFolder.elt) {
+ this._overFolder.closeTimer = this._overFolder
+ .setTimer(this._overFolder.hoverTime);
+ }
+
+ // The auto-opened attribute is set when this folder was automatically
+ // opened after the user dragged over it. If this attribute is set,
+ // auto-close the folder on drag exit.
+ // We should also try to close this popup if the drag has started
+ // from here, the timer will check if we are dragging over a child.
+ if (this.hasAttribute('autoopened') ||
+ !browserMenuDragging.STAY_OPEN_ONDRAGEXIT &&
+ this.hasAttribute('dragstart')) {
+ this._overFolder.closeMenuTimer = this._overFolder
+ .setTimer(this._overFolder.hoverTime);
+ }
+
+ event.stopPropagation();
+ }
+
+ menupopup.addEventListener('dragstart', menupopup.onDragStart, true);
+ menupopup.addEventListener('dragover', menupopup.onDragOver, true);
+ menupopup.addEventListener('dragleave', menupopup.onDragExit, true);
+ },
+
+ hideTooltip: function() {
+ ['bhTooltip', 'btTooltip2'].forEach(function(id) {
+ var tooltip = document.getElementById(id);
+ if (tooltip)
+ tooltip.hidePopup();
+ });
+ },
+
+ get getVer(){
+ const Cc = Components.classes;
+ const Ci = Components.interfaces;
+ var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+ var ver = parseInt(info.version.substr(0,3) * 10,10) / 10;
+ return ver;
+ },
+
+ debug: function(aMsg){
+ if (!browserMenuDragging.DEBUG)
+ return;
+ Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService)
+ .logStringMessage(aMsg);
+ },
+
+ setPref: function(aPrefString, aPrefType, aValue){
+ var xpPref = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+ try{
+ switch (aPrefType){
+ case 'complex':
+ return xpPref.setComplexValue(aPrefString, Components.interfaces.nsILocalFile, aValue); break;
+ case 'str':
+ return xpPref.setCharPref(aPrefString, aValue); break;
+ case 'int':
+ aValue = parseInt(aValue);
+ return xpPref.setIntPref(aPrefString, aValue); break;
+ case 'bool':
+ default:
+ return xpPref.setBoolPref(aPrefString, aValue); break;
+ }
+ }catch(e){
+ }
+ return null;
+ },
+
+ addPrefListener: function(aObserver) {
+ try {
+ var pbi = Components.classes["@mozilla.org/preferences;1"].
+ getService(Components.interfaces.nsIPrefBranch2);
+ pbi.addObserver(aObserver.domain, aObserver, false);
+ } catch(e) {}
+ },
+
+ removePrefListener: function(aObserver) {
+ try {
+ var pbi = Components.classes["@mozilla.org/preferences;1"].
+ getService(Components.interfaces.nsIPrefBranch2);
+ pbi.removeObserver(aObserver.domain, aObserver);
+ } catch(e) {}
+ },
+
+ PrefListener:{
+ domain : 'browser.menu.dragging.stayOpen',
+
+ observe : function(aSubject, aTopic, aPrefstring) {
+ if (aTopic == 'nsPref:changed') {
+ browserMenuDragging.initPref();
+ }
+ }
+ }
+}
+
+window.addEventListener('load', browserMenuDragging, false);
\ No newline at end of file
diff --git a/base/content/browser-menudragging.xul b/base/content/browser-menudragging.xul
new file mode 100644
index 0000000..f5cabe5
--- /dev/null
+++ b/base/content/browser-menudragging.xul
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/base/content/browser-places.js b/base/content/browser-places.js
new file mode 100644
index 0000000..590fe7e
--- /dev/null
+++ b/base/content/browser-places.js
@@ -0,0 +1,1316 @@
+# 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/.
+
+////////////////////////////////////////////////////////////////////////////////
+//// StarUI
+
+var StarUI = {
+ _itemId: -1,
+ uri: null,
+ _batching: false,
+
+ _element: function(aID) {
+ return document.getElementById(aID);
+ },
+
+ // Edit-bookmark panel
+ get panel() {
+ delete this.panel;
+ var element = this._element("editBookmarkPanel");
+ // initially the panel is hidden
+ // to avoid impacting startup / new window performance
+ element.hidden = false;
+ element.addEventListener("popuphidden", this, false);
+ element.addEventListener("keypress", this, false);
+ return this.panel = element;
+ },
+
+ // Array of command elements to disable when the panel is opened.
+ get _blockedCommands() {
+ delete this._blockedCommands;
+ return this._blockedCommands =
+ ["cmd_close", "cmd_closeWindow"].map(function (id) this._element(id), this);
+ },
+
+ _blockCommands: function SU__blockCommands() {
+ this._blockedCommands.forEach(function (elt) {
+ // make sure not to permanently disable this item (see bug 409155)
+ if (elt.hasAttribute("wasDisabled"))
+ return;
+ if (elt.getAttribute("disabled") == "true") {
+ elt.setAttribute("wasDisabled", "true");
+ } else {
+ elt.setAttribute("wasDisabled", "false");
+ elt.setAttribute("disabled", "true");
+ }
+ });
+ },
+
+ _restoreCommandsState: function SU__restoreCommandsState() {
+ this._blockedCommands.forEach(function (elt) {
+ if (elt.getAttribute("wasDisabled") != "true")
+ elt.removeAttribute("disabled");
+ elt.removeAttribute("wasDisabled");
+ });
+ },
+
+ // nsIDOMEventListener
+ handleEvent: function SU_handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "popuphidden":
+ if (aEvent.originalTarget == this.panel) {
+ if (!this._element("editBookmarkPanelContent").hidden)
+ this.quitEditMode();
+
+ this._restoreCommandsState();
+ this._itemId = -1;
+ if (this._batching) {
+ PlacesUtils.transactionManager.endBatch(false);
+ this._batching = false;
+ }
+
+ switch (this._actionOnHide) {
+ case "cancel": {
+ PlacesUtils.transactionManager.undoTransaction();
+ break;
+ }
+ case "remove": {
+ // Remove all bookmarks for the bookmark's url, this also removes
+ // the tags for the url.
+ PlacesUtils.transactionManager.beginBatch(null);
+ let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
+ for (let i = 0; i < itemIds.length; i++) {
+ let txn = new PlacesRemoveItemTransaction(itemIds[i]);
+ PlacesUtils.transactionManager.doTransaction(txn);
+ }
+ PlacesUtils.transactionManager.endBatch(false);
+ break;
+ }
+ }
+ this._actionOnHide = "";
+ }
+ break;
+ case "keypress":
+ if (aEvent.defaultPrevented) {
+ // The event has already been consumed inside of the panel.
+ break;
+ }
+ switch (aEvent.keyCode) {
+ case KeyEvent.DOM_VK_ESCAPE:
+ if (!this._element("editBookmarkPanelContent").hidden)
+ this.cancelButtonOnCommand();
+ break;
+ case KeyEvent.DOM_VK_RETURN:
+ if (aEvent.target.className == "expander-up" ||
+ aEvent.target.className == "expander-down" ||
+ aEvent.target.id == "editBMPanel_newFolderButton") {
+ //XXX Why is this necessary? The defaultPrevented check should
+ // be enough.
+ break;
+ }
+ this.panel.hidePopup();
+ break;
+ }
+ break;
+ }
+ },
+
+ _overlayLoaded: false,
+ _overlayLoading: false,
+ showEditBookmarkPopup:
+ function SU_showEditBookmarkPopup(aItemId, aAnchorElement, aPosition) {
+ // Performance: load the overlay the first time the panel is opened
+ // (see bug 392443).
+ if (this._overlayLoading)
+ return;
+
+ if (this._overlayLoaded) {
+ this._doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition);
+ return;
+ }
+
+ this._overlayLoading = true;
+ document.loadOverlay(
+ "chrome://browser/content/places/editBookmarkOverlay.xul",
+ (function (aSubject, aTopic, aData) {
+ //XXX We just caused localstore.rdf to be re-applied (bug 640158)
+ retrieveToolbarIconsizesFromTheme();
+
+ // Move the header (star, title, button) into the grid,
+ // so that it aligns nicely with the other items (bug 484022).
+ let header = this._element("editBookmarkPanelHeader");
+ let rows = this._element("editBookmarkPanelGrid").lastChild;
+ rows.insertBefore(header, rows.firstChild);
+ header.hidden = false;
+
+ this._overlayLoading = false;
+ this._overlayLoaded = true;
+ this._doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition);
+ }).bind(this)
+ );
+ },
+
+ _doShowEditBookmarkPanel:
+ function SU__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) {
+ if (this.panel.state != "closed")
+ return;
+
+ this._blockCommands(); // un-done in the popuphiding handler
+
+ // Set panel title:
+ // if we are batching, i.e. the bookmark has been added now,
+ // then show Page Bookmarked, else if the bookmark did already exist,
+ // we are about editing it, then use Edit This Bookmark.
+ this._element("editBookmarkPanelTitle").value =
+ this._batching ?
+ gNavigatorBundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
+ gNavigatorBundle.getString("editBookmarkPanel.editBookmarkTitle");
+
+ // No description; show the Done, Cancel;
+ this._element("editBookmarkPanelDescription").textContent = "";
+ this._element("editBookmarkPanelBottomButtons").hidden = false;
+ this._element("editBookmarkPanelContent").hidden = false;
+
+ // The remove button is shown only if we're not already batching, i.e.
+ // if the cancel button/ESC does not remove the bookmark.
+ this._element("editBookmarkPanelRemoveButton").hidden = this._batching;
+
+ // The label of the remove button differs if the URI is bookmarked
+ // multiple times.
+ var bookmarks = PlacesUtils.getBookmarksForURI(gBrowser.currentURI);
+ var forms = gNavigatorBundle.getString("editBookmark.removeBookmarks.label");
+ var label = PluralForm.get(bookmarks.length, forms).replace("#1", bookmarks.length);
+ this._element("editBookmarkPanelRemoveButton").label = label;
+
+ // unset the unstarred state, if set
+ this._element("editBookmarkPanelStarIcon").removeAttribute("unstarred");
+
+ this._itemId = aItemId !== undefined ? aItemId : this._itemId;
+ this.beginBatch();
+
+ let onPanelReady = fn => {
+ let target = this.panel;
+ if (target.parentNode) {
+ // By targeting the panel's parent and using a capturing listener, we
+ // can have our listener called before others waiting for the panel to
+ // be shown (which probably expect the panel to be fully initialized)
+ target = target.parentNode;
+ }
+ target.addEventListener("popupshown", function(event) {
+ fn();
+ }, {"capture": true, "once": true});
+ };
+ gEditItemOverlay.initPanel(this._itemId,
+ { onPanelReady,
+ hiddenRows: ["description", "location",
+ "loadInSidebar", "keyword"] });
+
+ this.panel.openPopup(aAnchorElement, aPosition);
+ },
+
+ panelShown:
+ function SU_panelShown(aEvent) {
+ if (aEvent.target == this.panel) {
+ if (!this._element("editBookmarkPanelContent").hidden) {
+ let fieldToFocus = "editBMPanel_" +
+ gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField");
+ var elt = this._element(fieldToFocus);
+ elt.focus();
+ elt.select();
+ }
+ else {
+ // Note this isn't actually used anymore, we should remove this
+ // once we decide not to bring back the page bookmarked notification
+ this.panel.focus();
+ }
+ }
+ },
+
+ quitEditMode: function SU_quitEditMode() {
+ this._element("editBookmarkPanelContent").hidden = true;
+ this._element("editBookmarkPanelBottomButtons").hidden = true;
+ gEditItemOverlay.uninitPanel(true);
+ },
+
+ cancelButtonOnCommand: function SU_cancelButtonOnCommand() {
+ this._actionOnHide = "cancel";
+ this.panel.hidePopup();
+ },
+
+ removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
+ this._uriForRemoval = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
+ this._actionOnHide = "remove";
+ this.panel.hidePopup();
+ },
+
+ beginBatch: function SU_beginBatch() {
+ if (!this._batching) {
+ PlacesUtils.transactionManager.beginBatch(null);
+ this._batching = true;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// PlacesCommandHook
+
+var PlacesCommandHook = {
+ /**
+ * Adds a bookmark to the page loaded in the given browser.
+ *
+ * @param aBrowser
+ * a element.
+ * @param [optional] aParent
+ * The folder in which to create a new bookmark if the page loaded in
+ * aBrowser isn't bookmarked yet, defaults to the unfiled root.
+ * @param [optional] aShowEditUI
+ * whether or not to show the edit-bookmark UI for the bookmark item
+ */
+ bookmarkPage: function PCH_bookmarkPage(aBrowser, aParent, aShowEditUI) {
+ var uri = aBrowser.currentURI;
+ var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
+ if (itemId == -1) {
+ // Copied over from addBookmarkForBrowser:
+ // Bug 52536: We obtain the URL and title from the nsIWebNavigation
+ // associated with a rather than from a DOMWindow.
+ // This is because when a full page plugin is loaded, there is
+ // no DOMWindow (?) but information about the loaded document
+ // may still be obtained from the webNavigation.
+ var webNav = aBrowser.webNavigation;
+ var url = webNav.currentURI;
+ var title;
+ var description;
+ var charset;
+ try {
+ let isErrorPage = /^about:(neterror|certerror|blocked)/
+ .test(webNav.document.documentURI);
+ title = isErrorPage ? PlacesUtils.history.getPageTitle(url)
+ : webNav.document.title;
+ title = title || url.spec;
+ description = PlacesUIUtils.getDescriptionFromDocument(webNav.document);
+ charset = webNav.document.characterSet;
+ }
+ catch (e) { }
+
+ if (aShowEditUI) {
+ // If we bookmark the page here (i.e. page was not "starred" already)
+ // but open right into the "edit" state, start batching here, so
+ // "Cancel" in that state removes the bookmark.
+ StarUI.beginBatch();
+ }
+
+ var parent = aParent != undefined ?
+ aParent : PlacesUtils.unfiledBookmarksFolderId;
+ var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
+ var txn = new PlacesCreateBookmarkTransaction(uri, parent,
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ title, null, [descAnno]);
+ PlacesUtils.transactionManager.doTransaction(txn);
+ itemId = txn.item.id;
+ // Set the character-set
+ if (charset && !PrivateBrowsingUtils.isWindowPrivate(aBrowser.contentWindow))
+ PlacesUtils.setCharsetForURI(uri, charset);
+ }
+
+ // Revert the contents of the location bar
+ if (gURLBar)
+ gURLBar.handleRevert();
+
+ // If it was not requested to open directly in "edit" mode, we are done.
+ if (!aShowEditUI)
+ return;
+
+ // Try to dock the panel to:
+ // 1. the bookmarks menu button
+ // 2. the page-proxy-favicon
+ // 3. the content area
+ if (BookmarkingUI.anchor) {
+ StarUI.showEditBookmarkPopup(itemId, BookmarkingUI.anchor,
+ "bottomcenter topright");
+ return;
+ }
+
+ let pageProxyFavicon = document.getElementById("page-proxy-favicon");
+ if (isElementVisible(pageProxyFavicon)) {
+ StarUI.showEditBookmarkPopup(itemId, pageProxyFavicon,
+ "bottomcenter topright");
+ } else {
+ StarUI.showEditBookmarkPopup(itemId, aBrowser, "overlap");
+ }
+ },
+
+ /**
+ * Adds a bookmark to the page loaded in the current tab.
+ */
+ bookmarkCurrentPage: function PCH_bookmarkCurrentPage(aShowEditUI, aParent) {
+ this.bookmarkPage(gBrowser.selectedBrowser, aParent, aShowEditUI);
+ },
+
+ /**
+ * Adds a bookmark to the page targeted by a link.
+ * @param aParent
+ * The folder in which to create a new bookmark if aURL isn't
+ * bookmarked.
+ * @param aURL (string)
+ * the address of the link target
+ * @param aTitle
+ * The link text
+ */
+ bookmarkLink: function PCH_bookmarkLink(aParent, aURL, aTitle) {
+ var linkURI = makeURI(aURL);
+ var itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
+ if (itemId == -1) {
+ PlacesUIUtils.showBookmarkDialog({ action: "add"
+ , type: "bookmark"
+ , uri: linkURI
+ , title: aTitle
+ , hiddenRows: [ "description"
+ , "location"
+ , "loadInSidebar"
+ , "keyword" ]
+ }, window);
+ }
+ else {
+ PlacesUIUtils.showBookmarkDialog({ action: "edit"
+ , type: "bookmark"
+ , itemId: itemId
+ }, window);
+ }
+ },
+
+ /**
+ * List of nsIURI objects characterizing the tabs currently open in the
+ * browser, modulo pinned tabs. The URIs will be in the order in which their
+ * corresponding tabs appeared and duplicates are discarded.
+ */
+ get uniqueCurrentPages() {
+ let uniquePages = {};
+ let URIs = [];
+ gBrowser.visibleTabs.forEach(function (tab) {
+ let spec = tab.linkedBrowser.currentURI.spec;
+ if (!tab.pinned && !(spec in uniquePages)) {
+ uniquePages[spec] = null;
+ URIs.push(tab.linkedBrowser.currentURI);
+ }
+ });
+ return URIs;
+ },
+
+ /**
+ * Adds a folder with bookmarks to all of the currently open tabs in this
+ * window.
+ */
+ bookmarkCurrentPages: function PCH_bookmarkCurrentPages() {
+ let pages = this.uniqueCurrentPages;
+ if (pages.length > 1) {
+ PlacesUIUtils.showBookmarkDialog({ action: "add"
+ , type: "folder"
+ , URIList: pages
+ , hiddenRows: [ "description" ]
+ }, window);
+ }
+ },
+
+ /**
+ * Updates disabled state for the "Bookmark All Tabs" command.
+ */
+ updateBookmarkAllTabsCommand:
+ function PCH_updateBookmarkAllTabsCommand() {
+ // There's nothing to do in non-browser windows.
+ if (window.location.href != getBrowserURL())
+ return;
+
+ // Disable "Bookmark All Tabs" if there are less than two
+ // "unique current pages".
+ goSetCommandEnabled("Browser:BookmarkAllTabs",
+ this.uniqueCurrentPages.length >= 2);
+ },
+
+ /**
+ * Adds a Live Bookmark to a feed associated with the current page.
+ * @param url
+ * The nsIURI of the page the feed was attached to
+ * @title title
+ * The title of the feed. Optional.
+ * @subtitle subtitle
+ * A short description of the feed. Optional.
+ */
+ addLiveBookmark: function PCH_addLiveBookmark(url, feedTitle, feedSubtitle) {
+ let toolbarIP = new InsertionPoint(PlacesUtils.toolbarFolderId, -1);
+
+ let feedURI = makeURI(url);
+ let title = feedTitle || gBrowser.contentTitle;
+ let description = feedSubtitle;
+ if (!description) {
+ description = PlacesUIUtils.getDescriptionFromDocument(gBrowser.contentDocument);
+ }
+
+ PlacesUIUtils.showBookmarkDialog({ action: "add"
+ , type: "livemark"
+ , feedURI: feedURI
+ , siteURI: gBrowser.currentURI
+ , title: title
+ , description: description
+ , defaultInsertionPoint: toolbarIP
+ , hiddenRows: [ "feedLocation"
+ , "siteLocation"
+ , "description" ]
+ }, window);
+ },
+
+ /**
+ * Opens the Places Organizer.
+ * @param aLeftPaneRoot
+ * The query to select in the organizer window - options
+ * are: History, AllBookmarks, BookmarksMenu, BookmarksToolbar,
+ * UnfiledBookmarks, Tags and Downloads.
+ */
+ showPlacesOrganizer: function PCH_showPlacesOrganizer(aLeftPaneRoot) {
+ var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
+ // Due to bug 528706, getMostRecentWindow can return closed windows.
+ if (!organizer || organizer.closed) {
+ // No currently open places window, so open one with the specified mode.
+ openDialog("chrome://browser/content/places/places.xul",
+ "", "chrome,toolbar=yes,dialog=no,resizable", aLeftPaneRoot);
+ }
+ else {
+ organizer.PlacesOrganizer.selectLeftPaneQuery(aLeftPaneRoot);
+ organizer.focus();
+ }
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// HistoryMenu
+
+// View for the history menu.
+function HistoryMenu(aPopupShowingEvent) {
+ // Workaround for Bug 610187. The sidebar does not include all the Places
+ // views definitions, and we don't need them there.
+ // Defining the prototype inheritance in the prototype itself would cause
+ // browser.js to halt on "PlacesMenu is not defined" error.
+ this.__proto__.__proto__ = PlacesMenu.prototype;
+ XPCOMUtils.defineLazyServiceGetter(this, "_ss",
+ "@mozilla.org/browser/sessionstore;1",
+ "nsISessionStore");
+ PlacesMenu.call(this, aPopupShowingEvent,
+ "place:sort=4&maxResults=15");
+}
+
+HistoryMenu.prototype = {
+ toggleRestoreLastSession: function HM_toggleRestoreLastSession() {
+ let restoreItem = this._rootElt.ownerDocument.getElementById("Browser:RestoreLastSession");
+
+ if (this._ss.canRestoreLastSession &&
+ !PrivateBrowsingUtils.isWindowPrivate(window))
+ restoreItem.removeAttribute("disabled");
+ else
+ restoreItem.setAttribute("disabled", true);
+ },
+
+ toggleRecentlyClosedTabs: function HM_toggleRecentlyClosedTabs() {
+ // enable/disable the Recently Closed Tabs sub menu
+ var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
+
+ // no restorable tabs, so disable menu
+ if (this._ss.getClosedTabCount(window) == 0)
+ undoMenu.setAttribute("disabled", true);
+ else
+ undoMenu.removeAttribute("disabled");
+ },
+
+ /**
+ * Re-open a closed tab and put it to the end of the tab strip.
+ * Used for a middle click.
+ * @param aEvent
+ * The event when the user clicks the menu item
+ */
+ _undoCloseMiddleClick: function PHM__undoCloseMiddleClick(aEvent) {
+ if (aEvent.button != 1)
+ return;
+
+ undoCloseTab(aEvent.originalTarget.value);
+ gBrowser.moveTabToEnd();
+ },
+
+ /**
+ * Populate when the history menu is opened
+ */
+ populateUndoSubmenu: function PHM_populateUndoSubmenu() {
+ var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
+ var undoPopup = undoMenu.firstChild;
+
+ // remove existing menu items
+ while (undoPopup.hasChildNodes())
+ undoPopup.removeChild(undoPopup.firstChild);
+
+ // no restorable tabs, so make sure menu is disabled, and return
+ if (this._ss.getClosedTabCount(window) == 0) {
+ undoMenu.setAttribute("disabled", true);
+ return;
+ }
+
+ // enable menu
+ undoMenu.removeAttribute("disabled");
+
+ // populate menu
+ var undoItems = JSON.parse(this._ss.getClosedTabData(window));
+ for (var i = 0; i < undoItems.length; i++) {
+ var m = document.createElement("menuitem");
+ m.setAttribute("label", undoItems[i].title);
+ if (undoItems[i].image) {
+ let iconURL = undoItems[i].image;
+ // don't initiate a connection just to fetch a favicon (see bug 467828)
+ if (/^https?:/.test(iconURL))
+ iconURL = "moz-anno:favicon:" + iconURL;
+ m.setAttribute("image", iconURL);
+ }
+ m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
+ m.setAttribute("value", i);
+ m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
+
+ // Set the targetURI attribute so it will be shown in tooltip and trigger
+ // onLinkHovered. SessionStore uses one-based indexes, so we need to
+ // normalize them.
+ let tabData = undoItems[i].state;
+ let activeIndex = (tabData.index || tabData.entries.length) - 1;
+ if (activeIndex >= 0 && tabData.entries[activeIndex])
+ m.setAttribute("targetURI", tabData.entries[activeIndex].url);
+
+ m.addEventListener("click", this._undoCloseMiddleClick, false);
+ if (i == 0)
+ m.setAttribute("key", "key_undoCloseTab");
+ undoPopup.appendChild(m);
+ }
+
+ // "Restore All Tabs"
+ var strings = gNavigatorBundle;
+ undoPopup.appendChild(document.createElement("menuseparator"));
+ m = undoPopup.appendChild(document.createElement("menuitem"));
+ m.id = "menu_restoreAllTabs";
+ m.setAttribute("label", strings.getString("menuRestoreAllTabs.label"));
+ m.addEventListener("command", function() {
+ for (var i = 0; i < undoItems.length; i++)
+ undoCloseTab();
+ }, false);
+ },
+
+ toggleRecentlyClosedWindows: function PHM_toggleRecentlyClosedWindows() {
+ // enable/disable the Recently Closed Windows sub menu
+ var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedWindowsMenu")[0];
+
+ // no restorable windows, so disable menu
+ if (this._ss.getClosedWindowCount() == 0)
+ undoMenu.setAttribute("disabled", true);
+ else
+ undoMenu.removeAttribute("disabled");
+ },
+
+ /**
+ * Populate when the history menu is opened
+ */
+ populateUndoWindowSubmenu: function PHM_populateUndoWindowSubmenu() {
+ let undoMenu = this._rootElt.getElementsByClassName("recentlyClosedWindowsMenu")[0];
+ let undoPopup = undoMenu.firstChild;
+ let menuLabelString = gNavigatorBundle.getString("menuUndoCloseWindowLabel");
+ let menuLabelStringSingleTab =
+ gNavigatorBundle.getString("menuUndoCloseWindowSingleTabLabel");
+
+ // remove existing menu items
+ while (undoPopup.hasChildNodes())
+ undoPopup.removeChild(undoPopup.firstChild);
+
+ // no restorable windows, so make sure menu is disabled, and return
+ if (this._ss.getClosedWindowCount() == 0) {
+ undoMenu.setAttribute("disabled", true);
+ return;
+ }
+
+ // enable menu
+ undoMenu.removeAttribute("disabled");
+
+ // populate menu
+ let undoItems = JSON.parse(this._ss.getClosedWindowData());
+ for (let i = 0; i < undoItems.length; i++) {
+ let undoItem = undoItems[i];
+ let otherTabsCount = undoItem.tabs.length - 1;
+ let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
+ : PluralForm.get(otherTabsCount, menuLabelString);
+ let menuLabel = label.replace("#1", undoItem.title)
+ .replace("#2", otherTabsCount);
+ let m = document.createElement("menuitem");
+ m.setAttribute("label", menuLabel);
+ let selectedTab = undoItem.tabs[undoItem.selected - 1];
+ if (selectedTab.image) {
+ let iconURL = selectedTab.image;
+ // don't initiate a connection just to fetch a favicon (see bug 467828)
+ if (/^https?:/.test(iconURL))
+ iconURL = "moz-anno:favicon:" + iconURL;
+ m.setAttribute("image", iconURL);
+ }
+ m.setAttribute("class", "menuitem-iconic bookmark-item menuitem-with-favicon");
+ m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
+
+ // Set the targetURI attribute so it will be shown in tooltip.
+ // SessionStore uses one-based indexes, so we need to normalize them.
+ let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
+ if (activeIndex >= 0 && selectedTab.entries[activeIndex])
+ m.setAttribute("targetURI", selectedTab.entries[activeIndex].url);
+
+ if (i == 0)
+ m.setAttribute("key", "key_undoCloseWindow");
+ undoPopup.appendChild(m);
+ }
+
+ // "Open All in Windows"
+ undoPopup.appendChild(document.createElement("menuseparator"));
+ let m = undoPopup.appendChild(document.createElement("menuitem"));
+ m.id = "menu_restoreAllWindows";
+ m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
+ m.setAttribute("oncommand",
+ "for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
+ },
+
+ toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {
+ // This is a no-op if MOZ_SERVICES_SYNC isn't defined
+#ifdef MOZ_SERVICES_SYNC
+ // Enable/disable the Tabs From Other Computers menu. Some of the menus handled
+ // by HistoryMenu do not have this menuitem.
+ let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0];
+ if (!menuitem)
+ return;
+
+ // If Sync isn't configured yet, then don't show the menuitem.
+ if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
+ Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
+ menuitem.setAttribute("hidden", true);
+ return;
+ }
+
+ // The tabs engine might never be inited (if services.sync.registerEngines
+ // is modified), so make sure we avoid undefined errors.
+ let enabled = Weave.Service.isLoggedIn &&
+ Weave.Service.engineManager.get("tabs") &&
+ Weave.Service.engineManager.get("tabs").enabled;
+ menuitem.setAttribute("disabled", !enabled);
+ menuitem.setAttribute("hidden", false);
+#endif
+ },
+
+ _onPopupShowing: function HM__onPopupShowing(aEvent) {
+ PlacesMenu.prototype._onPopupShowing.apply(this, arguments);
+
+ // Don't handle events for submenus.
+ if (aEvent.target != aEvent.currentTarget)
+ return;
+
+ this.toggleRestoreLastSession();
+ this.toggleRecentlyClosedTabs();
+ this.toggleRecentlyClosedWindows();
+ this.toggleTabsFromOtherComputers();
+ },
+
+ _onCommand: function HM__onCommand(aEvent) {
+ let placesNode = aEvent.target._placesNode;
+ if (placesNode) {
+ if (!PrivateBrowsingUtils.isWindowPrivate(window))
+ PlacesUIUtils.markPageAsTyped(placesNode.uri);
+ openUILink(placesNode.uri, aEvent, { ignoreAlt: true });
+ }
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// BookmarksEventHandler
+
+/**
+ * Functions for handling events in the Bookmarks Toolbar and menu.
+ */
+var BookmarksEventHandler = {
+ /**
+ * Handler for click event for an item in the bookmarks toolbar or menu.
+ * Menus and submenus from the folder buttons bubble up to this handler.
+ * Left-click is handled in the onCommand function.
+ * When items are middle-clicked (or clicked with modifier), open in tabs.
+ * If the click came through a menu, close the menu.
+ * @param aEvent
+ * DOMEvent for the click
+ * @param aView
+ * The places view which aEvent should be associated with.
+ */
+ onClick: function BEH_onClick(aEvent, aView) {
+ // Only handle middle-click or left-click with modifiers.
+#ifdef XP_MACOSX
+ var modifKey = aEvent.metaKey || aEvent.shiftKey;
+#else
+ var modifKey = aEvent.ctrlKey || aEvent.shiftKey;
+#endif
+ if (aEvent.button == 2 || (aEvent.button == 0 && !modifKey))
+ return;
+
+ var target = aEvent.originalTarget;
+ // If this event bubbled up from a menu or menuitem, close the menus.
+ // Do this before opening tabs, to avoid hiding the open tabs confirm-dialog.
+ if (target.localName == "menu" || target.localName == "menuitem") {
+ for (node = target.parentNode; node; node = node.parentNode) {
+ if (node.localName == "menupopup")
+ node.hidePopup();
+ else if (node.localName != "menu" &&
+ node.localName != "splitmenu" &&
+ node.localName != "hbox" &&
+ node.localName != "vbox" )
+ break;
+ }
+ }
+
+ if (target._placesNode && PlacesUtils.nodeIsContainer(target._placesNode)) {
+ // Don't open the root folder in tabs when the empty area on the toolbar
+ // is middle-clicked or when a non-bookmark item except for Open in Tabs)
+ // in a bookmarks menupopup is middle-clicked.
+ if (target.localName == "menu" || target.localName == "toolbarbutton")
+ PlacesUIUtils.openContainerNodeInTabs(target._placesNode, aEvent, aView);
+ }
+ else if (aEvent.button == 1) {
+ // left-clicks with modifier are already served by onCommand
+ this.onCommand(aEvent, aView);
+ }
+ },
+
+ /**
+ * Handler for command event for an item in the bookmarks toolbar.
+ * Menus and submenus from the folder buttons bubble up to this handler.
+ * Opens the item.
+ * @param aEvent
+ * DOMEvent for the command
+ * @param aView
+ * The places view which aEvent should be associated with.
+ */
+ onCommand: function BEH_onCommand(aEvent, aView) {
+ var target = aEvent.originalTarget;
+ if (target._placesNode)
+ PlacesUIUtils.openNodeWithEvent(target._placesNode, aEvent, aView);
+ },
+
+ fillInBHTooltip: function BEH_fillInBHTooltip(aDocument, aEvent) {
+ var node;
+ var cropped = false;
+ var targetURI;
+
+ if (aDocument.tooltipNode.localName == "treechildren") {
+ var tree = aDocument.tooltipNode.parentNode;
+ var tbo = tree.treeBoxObject;
+ var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
+ if (cell.row == -1)
+ return false;
+ node = tree.view.nodeForTreeIndex(cell.row);
+ cropped = tbo.isCellCropped(cell.row, cell.col);
+ }
+ else {
+ // Check whether the tooltipNode is a Places node.
+ // In such a case use it, otherwise check for targetURI attribute.
+ var tooltipNode = aDocument.tooltipNode;
+ if (tooltipNode._placesNode)
+ node = tooltipNode._placesNode;
+ else {
+ // This is a static non-Places node.
+ targetURI = tooltipNode.getAttribute("targetURI");
+ }
+ }
+
+ if (!node && !targetURI)
+ return false;
+
+ // Show node.label as tooltip's title for non-Places nodes.
+ var title = node ? node.title : tooltipNode.label;
+
+ // Show URL only for Places URI-nodes or nodes with a targetURI attribute.
+ var url;
+ if (targetURI || PlacesUtils.nodeIsURI(node))
+ url = targetURI || node.uri;
+
+ // Show tooltip for containers only if their title is cropped.
+ if (!cropped && !url)
+ return false;
+
+ var tooltipTitle = aDocument.getElementById("bhtTitleText");
+ tooltipTitle.hidden = (!title || (title == url));
+ if (!tooltipTitle.hidden)
+ tooltipTitle.textContent = title;
+
+ var tooltipUrl = aDocument.getElementById("bhtUrlText");
+ tooltipUrl.hidden = !url;
+ if (!tooltipUrl.hidden)
+ tooltipUrl.value = url;
+
+ // Show tooltip.
+ return true;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// PlacesMenuDNDHandler
+
+// Handles special drag and drop functionality for Places menus that are not
+// part of a Places view (e.g. the bookmarks menu in the menubar).
+var PlacesMenuDNDHandler = {
+ _springLoadDelay: 350, // milliseconds
+ _loadTimer: null,
+ _closerTimer: null,
+
+ /**
+ * Called when the user enters the element during a drag.
+ * @param event
+ * The DragEnter event that spawned the opening.
+ */
+ onDragEnter: function PMDH_onDragEnter(event) {
+ // Opening menus in a Places popup is handled by the view itself.
+ if (!this._isStaticContainer(event.target))
+ return;
+
+ let popup = event.target.lastChild;
+ if (this._loadTimer || popup.state === "showing" || popup.state === "open")
+ return;
+
+ this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._loadTimer.initWithCallback(() => {
+ this._loadTimer = null;
+ popup.setAttribute("autoopened", "true");
+ popup.showPopup(popup);
+ }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+ event.preventDefault();
+ event.stopPropagation();
+ },
+
+ /**
+ * Handles dragleave on the element.
+ * @returns true if the element is a container element (menu or
+ * menu-toolbarbutton), false otherwise.
+ */
+ onDragLeave: function PMDH_onDragLeave(event) {
+ // Handle menu-button separate targets.
+ if (event.relatedTarget === event.currentTarget ||
+ event.relatedTarget.parentNode === event.currentTarget)
+ return;
+
+ // Closing menus in a Places popup is handled by the view itself.
+ if (!this._isStaticContainer(event.target))
+ return;
+
+ let popup = event.target.lastChild;
+
+ if (this._loadTimer) {
+ this._loadTimer.cancel();
+ this._loadTimer = null;
+ }
+ this._closeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._closeTimer.initWithCallback(function() {
+ this._closeTimer = null;
+ let node = PlacesControllerDragHelper.currentDropTarget;
+ let inHierarchy = false;
+ while (node && !inHierarchy) {
+ inHierarchy = node == event.target;
+ node = node.parentNode;
+ }
+ if (!inHierarchy && popup && popup.hasAttribute("autoopened")) {
+ popup.removeAttribute("autoopened");
+ popup.hidePopup();
+ }
+ }, this._springLoadDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+ },
+
+ /**
+ * Determines if a XUL element represents a static container.
+ * @returns true if the element is a container element (menu or
+ *` menu-toolbarbutton), false otherwise.
+ */
+ _isStaticContainer: function PMDH__isContainer(node) {
+ let isMenu = node.localName == "menu" ||
+ (node.localName == "toolbarbutton" &&
+ (node.getAttribute("type") == "menu" ||
+ node.getAttribute("type") == "menu-button"));
+ let isStatic = !("_placesNode" in node) && node.lastChild &&
+ node.lastChild.hasAttribute("placespopup") &&
+ !node.parentNode.hasAttribute("placespopup");
+ return isMenu && isStatic;
+ },
+
+ /**
+ * Called when the user drags over the element.
+ * @param event
+ * The DragOver event.
+ */
+ onDragOver: function PMDH_onDragOver(event) {
+ let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ Ci.nsITreeView.DROP_ON);
+ if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer))
+ event.preventDefault();
+
+ event.stopPropagation();
+ },
+
+ /**
+ * Called when the user drops on the element.
+ * @param event
+ * The Drop event.
+ */
+ onDrop: function PMDH_onDrop(event) {
+ // Put the item at the end of bookmark menu.
+ let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ Ci.nsITreeView.DROP_ON);
+ PlacesControllerDragHelper.onDrop(ip, event.dataTransfer);
+ event.stopPropagation();
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// PlacesToolbarHelper
+
+/**
+ * This object handles the initialization and uninitialization of the bookmarks
+ * toolbar.
+ */
+var PlacesToolbarHelper = {
+ _place: "place:folder=TOOLBAR",
+
+ get _viewElt() {
+ return document.getElementById("PlacesToolbar");
+ },
+
+ init: function PTH_init() {
+ let viewElt = this._viewElt;
+ if (!viewElt || viewElt._placesView)
+ return;
+
+ // If the bookmarks toolbar item is hidden because the parent toolbar is
+ // collapsed or hidden (i.e. in a popup), spare the initialization. Also,
+ // there is no need to initialize the toolbar if customizing because
+ // init() will be called when the customization is done.
+ let toolbar = viewElt.parentNode.parentNode;
+ if (toolbar.collapsed ||
+ getComputedStyle(toolbar, "").display == "none" ||
+ this._isCustomizing)
+ return;
+
+ new PlacesToolbar(this._place);
+ },
+
+ customizeStart: function PTH_customizeStart() {
+ let viewElt = this._viewElt;
+ if (viewElt && viewElt._placesView)
+ viewElt._placesView.uninit();
+
+ this._isCustomizing = true;
+ },
+
+ customizeDone: function PTH_customizeDone() {
+ this._isCustomizing = false;
+ this.init();
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// BookmarkingUI
+
+/**
+ * Handles the bookmarks star button in the URL bar, as well as the bookmark
+ * menu button.
+ */
+
+var BookmarkingUI = {
+ get button() {
+ if (!this._button) {
+ this._button = document.getElementById("bookmarks-menu-button");
+ }
+ return this._button;
+ },
+
+ get star() {
+ if (!this._star) {
+ this._star = document.getElementById("star-button");
+ }
+ return this._star;
+ },
+
+ get anchor() {
+ if (this.star && isElementVisible(this.star)) {
+ // Anchor to the icon, so the panel looks more natural.
+ return this.star;
+ }
+ return null;
+ },
+
+ STATUS_UPDATING: -1,
+ STATUS_UNSTARRED: 0,
+ STATUS_STARRED: 1,
+ get status() {
+ if (this._pendingStmt)
+ return this.STATUS_UPDATING;
+ return this.star &&
+ this.star.hasAttribute("starred") ? this.STATUS_STARRED
+ : this.STATUS_UNSTARRED;
+ },
+
+ get _starredTooltip()
+ {
+ delete this._starredTooltip;
+ return this._starredTooltip =
+ gNavigatorBundle.getString("starButtonOn.tooltip");
+ },
+
+ get _unstarredTooltip()
+ {
+ delete this._unstarredTooltip;
+ return this._unstarredTooltip =
+ gNavigatorBundle.getString("starButtonOff.tooltip");
+ },
+
+ /**
+ * The popup contents must be updated when the user customizes the UI, or
+ * changes the personal toolbar collapsed status. In such a case, any needed
+ * change should be handled in the popupshowing helper, for performance
+ * reasons.
+ */
+ _popupNeedsUpdate: true,
+ onToolbarVisibilityChange: function BUI_onToolbarVisibilityChange() {
+ this._popupNeedsUpdate = true;
+ },
+
+ onPopupShowing: function BUI_onPopupShowing(event) {
+ // Don't handle events for submenus.
+ if (event.target != event.currentTarget)
+ return;
+
+ if (!this._popupNeedsUpdate)
+ return;
+ this._popupNeedsUpdate = false;
+
+ let popup = event.target;
+ let getPlacesAnonymousElement =
+ aAnonId => document.getAnonymousElementByAttribute(popup.parentNode,
+ "placesanonid",
+ aAnonId);
+
+ let viewToolbarMenuitem = getPlacesAnonymousElement("view-toolbar");
+ if (viewToolbarMenuitem) {
+ // Update View bookmarks toolbar checkbox menuitem.
+ let personalToolbar = document.getElementById("PersonalToolbar");
+ viewToolbarMenuitem.setAttribute("checked", !personalToolbar.collapsed);
+ }
+
+ let toolbarMenuitem = getPlacesAnonymousElement("toolbar-autohide");
+ if (toolbarMenuitem) {
+ // If bookmarks items are visible, hide Bookmarks Toolbar menu and the
+ // separator after it.
+ toolbarMenuitem.collapsed = toolbarMenuitem.nextSibling.collapsed =
+ isElementVisible(document.getElementById("personal-bookmarks"));
+ }
+ },
+
+ /**
+ * Handles star styling based on page proxy state changes.
+ */
+ onPageProxyStateChanged: function BUI_onPageProxyStateChanged(aState) {
+ if (!this.star) {
+ return;
+ }
+
+ if (aState == "invalid") {
+ this.star.setAttribute("disabled", "true");
+ this.star.removeAttribute("starred");
+ }
+ else {
+ this.star.removeAttribute("disabled");
+ }
+ },
+
+ _updateToolbarStyle: function BUI__updateToolbarStyle() {
+ if (!this.button) {
+ return;
+ }
+
+ let personalToolbar = document.getElementById("PersonalToolbar");
+ let onPersonalToolbar = this.button.parentNode == personalToolbar ||
+ this.button.parentNode.parentNode == personalToolbar;
+
+ if (onPersonalToolbar) {
+ this.button.classList.add("bookmark-item");
+ this.button.classList.remove("toolbarbutton-1");
+ }
+ else {
+ this.button.classList.remove("bookmark-item");
+ this.button.classList.add("toolbarbutton-1");
+ }
+ },
+
+ _uninitView: function BUI__uninitView() {
+ // When an element with a placesView attached is removed and re-inserted,
+ // XBL reapplies the binding causing any kind of issues and possible leaks,
+ // so kill current view and let popupshowing generate a new one.
+ if (this.button && this.button._placesView) {
+ this.button._placesView.uninit();
+ }
+ // Also uninit the main menubar placesView, since it would have the same
+ // issues.
+ let menubar = document.getElementById("bookmarksMenu");
+ if (menubar && menubar._placesView) {
+ menubar._placesView.uninit();
+ }
+ },
+
+ customizeStart: function BUI_customizeStart() {
+ this._uninitView();
+ },
+
+ customizeChange: function BUI_customizeChange() {
+ this._updateToolbarStyle();
+ },
+
+ customizeDone: function BUI_customizeDone() {
+ delete this._button;
+ this.onToolbarVisibilityChange();
+ this._updateToolbarStyle();
+ },
+
+ _hasBookmarksObserver: false,
+ uninit: function BUI_uninit() {
+ this._uninitView();
+
+ if (this._hasBookmarksObserver) {
+ PlacesUtils.removeLazyBookmarkObserver(this);
+ }
+
+ if (this._pendingStmt) {
+ this._pendingStmt.cancel();
+ delete this._pendingStmt;
+ }
+ },
+
+ onLocationChange: function BUI_onLocationChange() {
+ if (this._uri && gBrowser.currentURI.equals(this._uri)) {
+ return;
+ }
+ this.updateStarState();
+ },
+
+ updateStarState: function BUI_updateStarState() {
+ // Reset tracked values.
+ this._uri = gBrowser.currentURI;
+ this._itemIds = [];
+
+ if (this._pendingStmt) {
+ this._pendingStmt.cancel();
+ delete this._pendingStmt;
+ }
+
+ // We can load about:blank before the actual page, but there is no point in handling that page.
+ if (isBlankPageURL(this._uri.spec)) {
+ return;
+ }
+
+ this._pendingStmt = PlacesUtils.asyncGetBookmarkIds(this._uri, (aItemIds, aURI) => {
+ // Safety check that the bookmarked URI equals the tracked one.
+ if (!aURI.equals(this._uri)) {
+ Components.utils.reportError("BookmarkingUI did not receive current URI");
+ return;
+ }
+
+ // It's possible that onItemAdded gets called before the async statement
+ // calls back. For such an edge case, retain all unique entries from both
+ // arrays.
+ this._itemIds = this._itemIds.filter(
+ function (id) aItemIds.indexOf(id) == -1
+ ).concat(aItemIds);
+
+ this._updateStar();
+
+ // Start observing bookmarks if needed.
+ if (!this._hasBookmarksObserver) {
+ try {
+ PlacesUtils.addLazyBookmarkObserver(this);
+ this._hasBookmarksObserver = true;
+ } catch(ex) {
+ Components.utils.reportError("BookmarkingUI failed adding a bookmarks observer: " + ex);
+ }
+ }
+
+ delete this._pendingStmt;
+ }, this);
+ },
+
+ _updateStar: function BUI__updateStar() {
+ if (!this.star) {
+ return;
+ }
+
+ if (this._itemIds.length > 0) {
+ this.star.setAttribute("starred", "true");
+ this.star.setAttribute("tooltiptext", this._starredTooltip);
+ }
+ else {
+ this.star.removeAttribute("starred");
+ this.star.setAttribute("tooltiptext", this._unstarredTooltip);
+ }
+ },
+
+ onCommand: function BUI_onCommand(aEvent) {
+ if (aEvent.target != aEvent.currentTarget) {
+ return;
+ }
+ // Ignore clicks on the star if we are updating its state.
+ if (!this._pendingStmt) {
+ PlacesCommandHook.bookmarkCurrentPage(this._itemIds.length > 0);
+ }
+ },
+
+ // nsINavBookmarkObserver
+ onItemAdded: function BUI_onItemAdded(aItemId, aParentId, aIndex, aItemType,
+ aURI) {
+ if (aURI && aURI.equals(this._uri)) {
+ // If a new bookmark has been added to the tracked uri, register it.
+ if (this._itemIds.indexOf(aItemId) == -1) {
+ this._itemIds.push(aItemId);
+ this._updateStar();
+ }
+ }
+ },
+
+ onItemRemoved: function BUI_onItemRemoved(aItemId) {
+ let index = this._itemIds.indexOf(aItemId);
+ // If one of the tracked bookmarks has been removed, unregister it.
+ if (index != -1) {
+ this._itemIds.splice(index, 1);
+ this._updateStar();
+ }
+ },
+
+ onItemChanged: function BUI_onItemChanged(aItemId, aProperty,
+ aIsAnnotationProperty, aNewValue) {
+ if (aProperty == "uri") {
+ let index = this._itemIds.indexOf(aItemId);
+ // If the changed bookmark was tracked, check if it is now pointing to
+ // a different uri and unregister it.
+ if (index != -1 && aNewValue != this._uri.spec) {
+ this._itemIds.splice(index, 1);
+ this._updateStar();
+ }
+ // If another bookmark is now pointing to the tracked uri, register it.
+ else if (index == -1 && aNewValue == this._uri.spec) {
+ this._itemIds.push(aItemId);
+ this._updateStar();
+ }
+ }
+ },
+
+ onBeginUpdateBatch: function () {},
+ onEndUpdateBatch: function () {},
+ onBeforeItemRemoved: function () {},
+ onItemVisited: function () {},
+ onItemMoved: function () {},
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsINavBookmarkObserver
+ ])
+};
diff --git a/base/content/browser-plugins.js b/base/content/browser-plugins.js
new file mode 100644
index 0000000..8382682
--- /dev/null
+++ b/base/content/browser-plugins.js
@@ -0,0 +1,781 @@
+# -*- Mode: javascript; 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/.
+
+const kPrefSessionPersistMinutes = "plugin.sessionPermissionNow.intervalInMinutes";
+const kPrefPersistentDays = "plugin.persistentPermissionAlways.intervalInDays";
+
+var gPluginHandler = {
+ PLUGIN_SCRIPTED_STATE_NONE: 0,
+ PLUGIN_SCRIPTED_STATE_FIRED: 1,
+ PLUGIN_SCRIPTED_STATE_DONE: 2,
+
+ getPluginUI: function (plugin, anonid) {
+ return plugin.ownerDocument.
+ getAnonymousElementByAttribute(plugin, "anonid", anonid);
+ },
+
+ _getPluginInfo: function (pluginElement) {
+ let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+ pluginElement.QueryInterface(Ci.nsIObjectLoadingContent);
+
+ let tagMimetype;
+ let pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
+ let pluginTag = null;
+ let permissionString = null;
+ let fallbackType = null;
+ let blocklistState = null;
+
+ if (pluginElement instanceof HTMLAppletElement) {
+ tagMimetype = "application/x-java-vm";
+ } else {
+ tagMimetype = pluginElement.actualType;
+
+ if (tagMimetype == "") {
+ tagMimetype = pluginElement.type;
+ }
+ }
+
+ if (gPluginHandler.isKnownPlugin(pluginElement)) {
+ pluginTag = pluginHost.getPluginTagForType(pluginElement.actualType);
+ pluginName = gPluginHandler.makeNicePluginName(pluginTag.name);
+
+ permissionString = pluginHost.getPermissionStringForType(pluginElement.actualType);
+ fallbackType = pluginElement.defaultFallbackType;
+ blocklistState = pluginHost.getBlocklistStateForType(pluginElement.actualType);
+ // Make state-softblocked == state-notblocked for our purposes,
+ // they have the same UI. STATE_OUTDATED should not exist for plugin
+ // items, but let's alias it anyway, just in case.
+ if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
+ blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
+ blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+ }
+ }
+
+ return { mimetype: tagMimetype,
+ pluginName: pluginName,
+ pluginTag: pluginTag,
+ permissionString: permissionString,
+ fallbackType: fallbackType,
+ blocklistState: blocklistState,
+ };
+ },
+
+ // Map the plugin's name to a filtered version more suitable for user UI.
+ makeNicePluginName : function (aName) {
+ if (aName == "Shockwave Flash")
+ return "Adobe Flash";
+
+ // Clean up the plugin name by stripping off any trailing version numbers
+ // or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar"
+ // Do this by first stripping the numbers, etc. off the end, and then
+ // removing "Plugin" (and then trimming to get rid of any whitespace).
+ // (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled)
+ let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim();
+ return newName;
+ },
+
+ isTooSmall : function (plugin, overlay) {
+ // Is the 's size too small to hold what we want to show?
+ let pluginRect = plugin.getBoundingClientRect();
+ // XXX bug 446693. The text-shadow on the submitted-report text at
+ // the bottom causes scrollHeight to be larger than it should be.
+ // Clamp width/height to properly show CTP overlay on different
+ // zoom levels when embedded in iframes (rounding bug). (Bug 972237)
+ let overflows = (overlay.scrollWidth > Math.ceil(pluginRect.width)) ||
+ (overlay.scrollHeight - 5 > Math.ceil(pluginRect.height));
+ return overflows;
+ },
+
+ addLinkClickCallback: function (linkNode, callbackName /*callbackArgs...*/) {
+ // XXX just doing (callback)(arg) was giving a same-origin error. bug?
+ let self = this;
+ let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
+ linkNode.addEventListener("click",
+ function(evt) {
+ if (!evt.isTrusted)
+ return;
+ evt.preventDefault();
+ if (callbackArgs.length == 0)
+ callbackArgs = [ evt ];
+ (self[callbackName]).apply(self, callbackArgs);
+ },
+ true);
+
+ linkNode.addEventListener("keydown",
+ function(evt) {
+ if (!evt.isTrusted)
+ return;
+ if (evt.keyCode == evt.DOM_VK_RETURN) {
+ evt.preventDefault();
+ if (callbackArgs.length == 0)
+ callbackArgs = [ evt ];
+ evt.preventDefault();
+ (self[callbackName]).apply(self, callbackArgs);
+ }
+ },
+ true);
+ },
+
+ // Helper to get the binding handler type from a plugin object
+ _getBindingType : function(plugin) {
+ if (!(plugin instanceof Ci.nsIObjectLoadingContent))
+ return null;
+
+ switch (plugin.pluginFallbackType) {
+ case Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED:
+ return "PluginNotFound";
+ case Ci.nsIObjectLoadingContent.PLUGIN_DISABLED:
+ return "PluginDisabled";
+ case Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED:
+ return "PluginBlocklisted";
+ case Ci.nsIObjectLoadingContent.PLUGIN_OUTDATED:
+ return "PluginOutdated";
+ case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
+ return "PluginClickToPlay";
+ case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
+ return "PluginVulnerableUpdatable";
+ case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
+ return "PluginVulnerableNoUpdate";
+ case Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW:
+ return "PluginPlayPreview";
+ default:
+ // Not all states map to a handler
+ return null;
+ }
+ },
+
+ handleEvent : function(event) {
+ let plugin;
+ let doc;
+
+ let eventType = event.type;
+ if (eventType === "PluginRemoved") {
+ doc = event.target;
+ }
+ else {
+ plugin = event.target;
+ doc = plugin.ownerDocument;
+
+ if (!(plugin instanceof Ci.nsIObjectLoadingContent))
+ return;
+ }
+
+ if (eventType == "PluginBindingAttached") {
+ // The plugin binding fires this event when it is created.
+ // As an untrusted event, ensure that this object actually has a binding
+ // and make sure we don't handle it twice
+ let overlay = this.getPluginUI(plugin, "main");
+ if (!overlay || overlay._bindingHandled) {
+ return;
+ }
+ overlay._bindingHandled = true;
+
+ // Lookup the handler for this binding
+ eventType = this._getBindingType(plugin);
+ if (!eventType) {
+ // Not all bindings have handlers
+ return;
+ }
+ }
+
+ let shouldShowNotification = false;
+ let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
+ if (!browser)
+ return;
+
+ switch (eventType) {
+ case "PluginCrashed":
+ this.pluginInstanceCrashed(plugin, event);
+ break;
+
+ case "PluginNotFound":
+ /* No action (plugin finder obsolete) */
+ break;
+
+ case "PluginBlocklisted":
+ case "PluginOutdated":
+ shouldShowNotification = true;
+ break;
+
+ case "PluginVulnerableUpdatable":
+ let updateLink = this.getPluginUI(plugin, "checkForUpdatesLink");
+ this.addLinkClickCallback(updateLink, "openPluginUpdatePage");
+ /* FALLTHRU */
+
+ case "PluginVulnerableNoUpdate":
+ case "PluginClickToPlay":
+ this._handleClickToPlayEvent(plugin);
+ let overlay = this.getPluginUI(plugin, "main");
+ let pluginName = this._getPluginInfo(plugin).pluginName;
+ let messageString = gNavigatorBundle.getFormattedString("PluginClickToActivate", [pluginName]);
+ let overlayText = this.getPluginUI(plugin, "clickToPlay");
+ overlayText.textContent = messageString;
+ if (eventType == "PluginVulnerableUpdatable" ||
+ eventType == "PluginVulnerableNoUpdate") {
+ let vulnerabilityString = gNavigatorBundle.getString(eventType);
+ let vulnerabilityText = this.getPluginUI(plugin, "vulnerabilityStatus");
+ vulnerabilityText.textContent = vulnerabilityString;
+ }
+ shouldShowNotification = true;
+ break;
+
+ case "PluginPlayPreview":
+ this._handlePlayPreviewEvent(plugin);
+ break;
+
+ case "PluginDisabled":
+ let manageLink = this.getPluginUI(plugin, "managePluginsLink");
+ this.addLinkClickCallback(manageLink, "managePlugins");
+ shouldShowNotification = true;
+ break;
+
+ case "PluginInstantiated":
+ //Pale Moon: don't show the indicator when plugins are enabled/allowed
+ if (gPrefService.getBoolPref("plugins.always_show_indicator")) {
+ shouldShowNotification = true;
+ }
+ break;
+ case "PluginRemoved":
+ shouldShowNotification = true;
+ break;
+ }
+
+ // Show the in-content UI if it's not too big. The crashed plugin handler already did this.
+ if (eventType != "PluginCrashed" && eventType != "PluginRemoved") {
+ let overlay = this.getPluginUI(plugin, "main");
+ if (overlay != null) {
+ if (!this.isTooSmall(plugin, overlay)) {
+ overlay.style.visibility = "visible";
+ }
+ plugin.addEventListener("overflow", function(event) {
+ overlay.style.visibility = "hidden";
+ });
+ plugin.addEventListener("underflow", function(event) {
+ // this is triggered if only one dimension underflows,
+ // the other dimension might still overflow
+ if (!gPluginHandler.isTooSmall(plugin, overlay)) {
+ overlay.style.visibility = "visible";
+ }
+ });
+ }
+ }
+
+ // Only show the notification after we've done the isTooSmall check, so
+ // that the notification can decide whether to show the "alert" icon
+ if (shouldShowNotification) {
+ this._showClickToPlayNotification(browser);
+ }
+ },
+
+ isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
+ return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
+ Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
+ },
+
+ canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) {
+ // if this isn't a known plugin, we can't activate it
+ // (this also guards pluginHost.getPermissionStringForType against
+ // unexpected input)
+ if (!gPluginHandler.isKnownPlugin(objLoadingContent))
+ return false;
+
+ let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+ let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
+ let principal = objLoadingContent.ownerDocument.defaultView.top.document.nodePrincipal;
+ let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
+
+ let isFallbackTypeValid =
+ objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
+ objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
+
+ if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
+ // checking if play preview is subject to CTP rules
+ let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
+ isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
+ }
+
+ return !objLoadingContent.activated &&
+ pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
+ isFallbackTypeValid;
+ },
+
+ hideClickToPlayOverlay: function(aPlugin) {
+ let overlay = this.getPluginUI(aPlugin, "main");
+ if (overlay)
+ overlay.style.visibility = "hidden";
+ },
+
+ stopPlayPreview: function PH_stopPlayPreview(aPlugin, aPlayPlugin) {
+ let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ if (objLoadingContent.activated)
+ return;
+
+ if (aPlayPlugin)
+ objLoadingContent.playPlugin();
+ else
+ objLoadingContent.cancelPlayPreview();
+ },
+
+ // Callback for user clicking on a disabled plugin
+ managePlugins: function (aEvent) {
+ BrowserOpenAddonsMgr("addons://list/plugin");
+ },
+
+ // Callback for user clicking on the link in a click-to-play plugin
+ // (where the plugin has an update)
+ openPluginUpdatePage: function (aEvent) {
+ openURL(Services.urlFormatter.formatURLPref("plugins.update.url"));
+ },
+
+ // Callback for user clicking a "reload page" link
+ reloadPage: function (browser) {
+ browser.reload();
+ },
+
+ // Callback for user clicking the help icon
+ openHelpPage: function () {
+ openHelpLink("plugin-crashed", false);
+ },
+
+ // Event listener for click-to-play plugins.
+ _handleClickToPlayEvent: function PH_handleClickToPlayEvent(aPlugin) {
+ let doc = aPlugin.ownerDocument;
+ let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
+ let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+ let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ // guard against giving pluginHost.getPermissionStringForType a type
+ // not associated with any known plugin
+ if (!gPluginHandler.isKnownPlugin(objLoadingContent))
+ return;
+ let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
+ let principal = doc.defaultView.top.document.nodePrincipal;
+ let pluginPermission = Services.perms.testPermissionFromPrincipal(principal, permissionString);
+
+ let overlay = this.getPluginUI(aPlugin, "main");
+
+ if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
+ if (overlay)
+ overlay.style.visibility = "hidden";
+ return;
+ }
+
+ if (overlay) {
+ overlay.addEventListener("click", gPluginHandler._overlayClickListener, true);
+ let closeIcon = gPluginHandler.getPluginUI(aPlugin, "closeIcon");
+ closeIcon.addEventListener("click", function(aEvent) {
+ if (aEvent.button == 0 && aEvent.isTrusted)
+ gPluginHandler.hideClickToPlayOverlay(aPlugin);
+ }, true);
+ }
+ },
+
+ _overlayClickListener: {
+ handleEvent: function PH_handleOverlayClick(aEvent) {
+ let plugin = document.getBindingParent(aEvent.target);
+ let contentWindow = plugin.ownerDocument.defaultView.top;
+ // gBrowser.getBrowserForDocument does not exist in the case where we
+ // drag-and-dropped a tab from a window containing only that tab. In
+ // that case, the window gets destroyed.
+ let browser = gBrowser.getBrowserForDocument ?
+ gBrowser.getBrowserForDocument(contentWindow.document) :
+ null;
+ // If browser is null here, we've been drag-and-dropped from another
+ // window, and this is the wrong click handler.
+ if (!browser) {
+ aEvent.target.removeEventListener("click", gPluginHandler._overlayClickListener, true);
+ return;
+ }
+ let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ // Have to check that the target is not the link to update the plugin
+ if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
+ (aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
+ aEvent.button == 0 && aEvent.isTrusted) {
+ gPluginHandler._showClickToPlayNotification(browser, plugin);
+ aEvent.stopPropagation();
+ aEvent.preventDefault();
+ }
+ }
+ },
+
+ _handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
+ let doc = aPlugin.ownerDocument;
+ let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
+ let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+ let pluginInfo = this._getPluginInfo(aPlugin);
+ let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
+
+ let previewContent = this.getPluginUI(aPlugin, "previewPluginContent");
+ let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
+ if (!iframe) {
+ // lazy initialization of the iframe
+ iframe = doc.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
+ iframe.className = "previewPluginContentFrame";
+ previewContent.appendChild(iframe);
+
+ // Force a style flush, so that we ensure our binding is attached.
+ aPlugin.clientTop;
+ }
+ iframe.src = playPreviewInfo.redirectURL;
+
+ // MozPlayPlugin event can be dispatched from the extension chrome
+ // code to replace the preview content with the native plugin
+ previewContent.addEventListener("MozPlayPlugin", function playPluginHandler(aEvent) {
+ if (!aEvent.isTrusted)
+ return;
+
+ previewContent.removeEventListener("MozPlayPlugin", playPluginHandler, true);
+
+ let playPlugin = !aEvent.detail;
+ gPluginHandler.stopPlayPreview(aPlugin, playPlugin);
+
+ // cleaning up: removes overlay iframe from the DOM
+ let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
+ if (iframe)
+ previewContent.removeChild(iframe);
+ }, true);
+
+ if (!playPreviewInfo.ignoreCTP) {
+ gPluginHandler._showClickToPlayNotification(browser);
+ }
+ },
+
+ reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
+ let browser = gBrowser.selectedBrowser;
+ let contentWindow = browser.contentWindow;
+ let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ let doc = contentWindow.document;
+ let plugins = cwu.plugins;
+ for (let plugin of plugins) {
+ let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+ if (overlay)
+ overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
+ let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ if (gPluginHandler.canActivatePlugin(objLoadingContent))
+ gPluginHandler._handleClickToPlayEvent(plugin);
+ }
+ gPluginHandler._showClickToPlayNotification(browser);
+ },
+
+ _clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
+ if (event == "showing") {
+ gPluginHandler._makeCenterActions(this);
+ }
+ else if (event == "dismissed") {
+ // Once the popup is dismissed, clicking the icon should show the full
+ // list again
+ this.options.primaryPlugin = null;
+ }
+ },
+
+ _makeCenterActions: function PH_makeCenterActions(notification) {
+ let contentWindow = notification.browser.contentWindow;
+ let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+
+ let principal = contentWindow.document.nodePrincipal;
+
+ let centerActions = [];
+ let pluginsFound = new Set();
+ for (let plugin of cwu.plugins) {
+ plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ if (plugin.getContentTypeForMIMEType(plugin.actualType) != Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
+ continue;
+ }
+
+ let pluginInfo = this._getPluginInfo(plugin);
+ if (pluginInfo.permissionString === null) {
+ Components.utils.reportError("No permission string for active plugin.");
+ continue;
+ }
+ if (pluginsFound.has(pluginInfo.permissionString)) {
+ continue;
+ }
+ pluginsFound.add(pluginInfo.permissionString);
+
+ // Add the per-site permissions and details URLs to pluginInfo here
+ // because they are more expensive to compute and so we avoid it in
+ // the tighter loop above.
+ let permissionObj = Services.perms.
+ getPermissionObject(principal, pluginInfo.permissionString, false);
+ if (permissionObj) {
+ pluginInfo.pluginPermissionPrePath = permissionObj.principal.originNoSuffix;
+ pluginInfo.pluginPermissionType = permissionObj.expireType;
+ }
+ else {
+ pluginInfo.pluginPermissionPrePath = principal.originNoSuffix;
+ pluginInfo.pluginPermissionType = undefined;
+ }
+
+ let url;
+ // TODO: allow the blocklist to specify a better link, bug 873093
+ if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
+ url = Services.urlFormatter.formatURLPref("plugins.update.url");
+ }
+ else if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
+ url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
+ }
+ pluginInfo.detailsLink = url;
+
+ centerActions.push(pluginInfo);
+ }
+ centerActions.sort(function(a, b) {
+ return a.pluginName.localeCompare(b.pluginName);
+ });
+
+ notification.options.centerActions = centerActions;
+ },
+
+ /**
+ * Called from the plugin doorhanger to set the new permissions for a plugin
+ * and activate plugins if necessary.
+ * aNewState should be either "allownow" "allowalways" or "block"
+ */
+ _updatePluginPermission: function PH_setPermissionForPlugins(aNotification, aPluginInfo, aNewState) {
+ let permission;
+ let expireType;
+ let expireTime;
+
+ switch (aNewState) {
+ case "allownow":
+ permission = Ci.nsIPermissionManager.ALLOW_ACTION;
+ expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
+ expireTime = Date.now() + Services.prefs.getIntPref(kPrefSessionPersistMinutes) * 60 * 1000;
+ break;
+
+ case "allowalways":
+ permission = Ci.nsIPermissionManager.ALLOW_ACTION;
+ expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
+ expireTime = Date.now() +
+ Services.prefs.getIntPref(kPrefPersistentDays) * 24 * 60 * 60 * 1000;
+ break;
+
+ case "block":
+ permission = Ci.nsIPermissionManager.PROMPT_ACTION;
+ expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
+ expireTime = 0;
+ break;
+
+ // In case a plugin has already been allowed in another tab, the "continue allowing" button
+ // shouldn't change any permissions but should run the plugin-enablement code below.
+ case "continue":
+ break;
+
+ default:
+ Cu.reportError(Error("Unexpected plugin state: " + aNewState));
+ return;
+ }
+
+ let browser = aNotification.browser;
+ let contentWindow = browser.contentWindow;
+ if (aNewState != "continue") {
+ let principal = contentWindow.document.nodePrincipal;
+ Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
+ permission, expireType, expireTime);
+
+ if (aNewState == "block") {
+ return;
+ }
+ }
+
+ // Manually activate the plugins that would have been automatically
+ // activated.
+ let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ let plugins = cwu.plugins;
+ let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+
+ for (let plugin of plugins) {
+ plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+ // canActivatePlugin will return false if this isn't a known plugin type,
+ // so the pluginHost.getPermissionStringForType call is protected
+ if (gPluginHandler.canActivatePlugin(plugin) &&
+ aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
+ plugin.playPlugin();
+ }
+ }
+ },
+
+ _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
+ let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
+
+ let contentWindow = aBrowser.contentWindow;
+ let contentDoc = aBrowser.contentDocument;
+ let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ // Pale Moon: cwu.plugins may contain non-plugin s, filter them out
+ let plugins = cwu.plugins.filter(function(plugin) {
+ return (plugin.getContentTypeForMIMEType(plugin.actualType) ==
+ Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
+ });
+ if (plugins.length == 0) {
+ if (notification) {
+ PopupNotifications.remove(notification);
+ }
+ return;
+ }
+
+ let icon = 'plugins-notification-icon';
+ for (let plugin of plugins) {
+ let fallbackType = plugin.pluginFallbackType;
+ if (fallbackType == plugin.PLUGIN_VULNERABLE_UPDATABLE ||
+ fallbackType == plugin.PLUGIN_VULNERABLE_NO_UPDATE ||
+ fallbackType == plugin.PLUGIN_BLOCKLISTED) {
+ icon = 'blocked-plugins-notification-icon';
+ break;
+ }
+ if (fallbackType == plugin.PLUGIN_CLICK_TO_PLAY) {
+ let overlay = contentDoc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+ if (!overlay || overlay.style.visibility == 'hidden') {
+ icon = 'alert-plugins-notification-icon';
+ }
+ }
+ }
+
+ let dismissed = notification ? notification.dismissed : true;
+ if (aPrimaryPlugin)
+ dismissed = false;
+
+ let primaryPluginPermission = null;
+ if (aPrimaryPlugin) {
+ primaryPluginPermission = this._getPluginInfo(aPrimaryPlugin).permissionString;
+ }
+
+ let options = {
+ dismissed: dismissed,
+ eventCallback: this._clickToPlayNotificationEventCallback,
+ primaryPlugin: primaryPluginPermission
+ };
+ PopupNotifications.show(aBrowser, "click-to-play-plugins",
+ "", icon,
+ null, null, options);
+ },
+
+ // Crashed-plugin observer. Notified once per plugin crash, before events
+ // are dispatched to individual plugin instances.
+ pluginCrashed : function(subject, topic, data) {
+ let propertyBag = subject;
+ if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
+ !(propertyBag instanceof Ci.nsIWritablePropertyBag2))
+ return;
+ },
+
+ // Crashed-plugin event listener. Called for every instance of a
+ // plugin in content.
+ pluginInstanceCrashed: function (plugin, aEvent) {
+ // Ensure the plugin and event are of the right type.
+ if (!(aEvent instanceof Ci.nsIDOMDataContainerEvent))
+ return;
+
+ let submittedReport = aEvent.getData("submittedCrashReport");
+ let doPrompt = true; // XXX followup for .getData("doPrompt");
+ let submitReports = true; // XXX followup for .getData("submitReports");
+ let pluginName = aEvent.getData("pluginName");
+ let pluginDumpID = aEvent.getData("pluginDumpID");
+ let browserDumpID = aEvent.getData("browserDumpID");
+
+ // Remap the plugin name to a more user-presentable form.
+ pluginName = this.makeNicePluginName(pluginName);
+
+ let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);
+
+ //
+ // Configure the crashed-plugin placeholder.
+ //
+
+ // Force a layout flush so the binding is attached.
+ plugin.clientTop;
+ let doc = plugin.ownerDocument;
+ let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
+ let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");
+
+ let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msgCrashedText");
+ crashText.textContent = messageString;
+
+ let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
+
+ let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink");
+ this.addLinkClickCallback(link, "reloadPage", browser);
+
+ let notificationBox = gBrowser.getNotificationBox(browser);
+
+ let isShowing = true;
+
+ // Is the 's size too small to hold what we want to show?
+ if (this.isTooSmall(plugin, overlay)) {
+ // First try hiding the crash report submission UI.
+ statusDiv.removeAttribute("status");
+
+ if (this.isTooSmall(plugin, overlay)) {
+ // Hide the overlay's contents. Use visibility style, so that it doesn't
+ // collapse down to 0x0.
+ overlay.style.visibility = "hidden";
+ isShowing = false;
+ }
+ }
+
+ if (isShowing) {
+ // If a previous plugin on the page was too small and resulted in adding a
+ // notification bar, then remove it because this plugin instance it big
+ // enough to serve as in-content notification.
+ hideNotificationBar();
+ doc.mozNoPluginCrashedNotification = true;
+ } else {
+ // If another plugin on the page was large enough to show our UI, we don't
+ // want to show a notification bar.
+ if (!doc.mozNoPluginCrashedNotification)
+ showNotificationBar(pluginDumpID, browserDumpID);
+ }
+
+ function hideNotificationBar() {
+ let notification = notificationBox.getNotificationWithValue("plugin-crashed");
+ if (notification)
+ notificationBox.removeNotification(notification, true);
+ }
+
+ function showNotificationBar(pluginDumpID, browserDumpID) {
+ // If there's already an existing notification bar, don't do anything.
+ let notification = notificationBox.getNotificationWithValue("plugin-crashed");
+ if (notification)
+ return;
+
+ // Configure the notification bar
+ let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
+ let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png";
+ let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label");
+ let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey");
+ let submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label");
+ let submitKey = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.accesskey");
+
+ let buttons = [{
+ label: reloadLabel,
+ accessKey: reloadKey,
+ popup: null,
+ callback: function() { browser.reload(); },
+ }];
+
+ notification = notificationBox.appendNotification(messageString, "plugin-crashed",
+ iconURL, priority, buttons);
+
+ // Add the "learn more" link.
+ let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let link = notification.ownerDocument.createElementNS(XULNS, "label");
+ link.className = "text-link";
+ link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
+ let crashurl = formatURL("app.support.baseURL", true);
+ crashurl += "plugin-crashed-notificationbar";
+ link.href = crashurl;
+
+ let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
+ description.appendChild(link);
+
+ // Remove the notfication when the page is reloaded.
+ doc.defaultView.top.addEventListener("unload", function() {
+ notificationBox.removeNotification(notification);
+ }, false);
+ }
+
+ }
+};
diff --git a/base/content/browser-sets.inc b/base/content/browser-sets.inc
new file mode 100644
index 0000000..78fce26
--- /dev/null
+++ b/base/content/browser-sets.inc
@@ -0,0 +1,357 @@
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+#define XP_GNOME 1
+#endif
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef MOZ_SERVICES_SYNC
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+#ifndef XP_MACOSX
+
+#endif
+
+#
+# Search Command Key Logic works like this:
+#
+# Unix: Ctrl+K (cross platform binding)
+# Ctrl+J (in case of emacs Ctrl-K conflict)
+# Mac: Cmd+K (cross platform binding)
+# Cmd+Opt+F (platform convention)
+# Win: Ctrl+K (cross platform binding)
+# Ctrl+E (IE compat)
+#
+# We support Ctrl+K on all platforms now and advertise it in the menu since it is
+# our standard - it is a "safe" choice since it is near no harmful keys like "W" as
+# "E" is. People mourning the loss of Ctrl+K for emacs compat can switch their GTK
+# system setting to use emacs emulation, and we should respect it. Focus-Search-Box
+# is a fundamental keybinding and we are maintaining a XP binding so that it is easy
+# for people to switch to Linux.
+#
+
+#ifdef XP_MACOSX
+
+#endif
+#ifdef XP_WIN
+
+#endif
+#ifdef XP_GNOME
+
+
+#else
+
+#endif
+
+
+
+
+
+
+
+
+#ifdef XP_UNIX
+
+#else
+
+#endif
+
+
+
+
+
+
+
+
+#ifndef XP_MACOSX
+
+
+#else
+
+
+#endif
+#ifdef XP_UNIX
+
+
+#endif
+
+
+#ifndef XP_MACOSX
+
+
+
+#else
+
+
+
+#endif
+
+
+
+#ifndef XP_WIN
+
+#endif
+
+
+
+
+
+
+
+# Accel+Shift+A-F are reserved on GTK
+#ifndef MOZ_WIDGET_GTK
+
+
+#else
+
+#endif
+
+#ifdef XP_WIN
+# Cmd+I is conventially mapped to Info on MacOS X, thus it should not be
+# overridden for other purposes there.
+
+#endif
+
+# Navigation cancel keys: Esc performs a cancel on loading (i.e.: stop button equivalent)
+# Shift-Esc (and similar Shift-modified stop on Mac) performs a "superstop": this halts all
+# networking requests, XHR, animated gifs, etc.
+
+
+#ifdef XP_MACOSX
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef XP_MACOSX
+
+#endif
+#ifdef XP_UNIX
+
+#endif
+
+#ifdef FULL_BROWSER_WINDOW
+
+#endif
+
+
+#ifdef XP_GNOME
+#define NUM_SELECT_TAB_MODIFIER alt
+#else
+#define NUM_SELECT_TAB_MODIFIER accel
+#endif
+
+#expand
+#expand
+#expand
+#expand
+#expand
+#expand
+#expand
+#expand
+#expand
+
+
+
+
+
+# Used by baseMenuOverlay
+#ifdef XP_MACOSX
+
+#endif
+
diff --git a/base/content/browser-syncui.js b/base/content/browser-syncui.js
new file mode 100644
index 0000000..86f6f48
--- /dev/null
+++ b/base/content/browser-syncui.js
@@ -0,0 +1,472 @@
+# 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/.
+
+// gSyncUI handles updating the tools menu
+var gSyncUI = {
+ _obs: ["weave:service:sync:start",
+ "weave:service:sync:delayed",
+ "weave:service:quota:remaining",
+ "weave:service:setup-complete",
+ "weave:service:login:start",
+ "weave:service:login:finish",
+ "weave:service:logout:finish",
+ "weave:service:start-over",
+ "weave:ui:login:error",
+ "weave:ui:sync:error",
+ "weave:ui:sync:finish",
+ "weave:ui:clear-error",
+ ],
+
+ _unloaded: false,
+
+ init: function SUI_init() {
+ // Proceed to set up the UI if Sync has already started up.
+ // Otherwise we'll do it when Sync is firing up.
+ let xps = Components.classes["@mozilla.org/weave/service;1"]
+ .getService(Components.interfaces.nsISupports)
+ .wrappedJSObject;
+ if (xps.ready) {
+ this.initUI();
+ return;
+ }
+
+ Services.obs.addObserver(this, "weave:service:ready", true);
+
+ // Remove the observer if the window is closed before the observer
+ // was triggered.
+ window.addEventListener("unload", function onUnload() {
+ gSyncUI._unloaded = true;
+ window.removeEventListener("unload", onUnload, false);
+ Services.obs.removeObserver(gSyncUI, "weave:service:ready");
+
+ if (Weave.Status.ready) {
+ gSyncUI._obs.forEach(function(topic) {
+ Services.obs.removeObserver(gSyncUI, topic);
+ });
+ }
+ }, false);
+ },
+
+ initUI: function SUI_initUI() {
+ // If this is a browser window?
+ if (gBrowser) {
+ this._obs.push("weave:notification:added");
+ }
+
+ this._obs.forEach(function(topic) {
+ Services.obs.addObserver(this, topic, true);
+ }, this);
+
+ if (gBrowser && Weave.Notifications.notifications.length) {
+ this.initNotifications();
+ }
+ this.updateUI();
+ },
+
+ initNotifications: function SUI_initNotifications() {
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let notificationbox = document.createElementNS(XULNS, "notificationbox");
+ notificationbox.id = "sync-notifications";
+ notificationbox.setAttribute("flex", "1");
+
+ let bottombox = document.getElementById("browser-bottombox");
+ bottombox.insertBefore(notificationbox, bottombox.firstChild);
+
+ // Force a style flush to ensure that our binding is attached.
+ notificationbox.clientTop;
+
+ // notificationbox will listen to observers from now on.
+ Services.obs.removeObserver(this, "weave:notification:added");
+ },
+
+ _wasDelayed: false,
+
+ _needsSetup: function SUI__needsSetup() {
+ let firstSync = Services.prefs.getCharPref("services.sync.firstSync", "");
+ return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
+ firstSync == "notReady";
+ },
+
+ updateUI: function SUI_updateUI() {
+ let needsSetup = this._needsSetup();
+ document.getElementById("sync-setup-state").hidden = !needsSetup;
+ document.getElementById("sync-syncnow-state").hidden = needsSetup;
+
+ if (!gBrowser) {
+ return;
+ }
+
+ let button = document.getElementById("sync-button");
+ if (!button) {
+ return;
+ }
+
+ button.removeAttribute("status");
+
+ this._updateLastSyncTime();
+
+ if (needsSetup) {
+ button.removeAttribute("tooltiptext");
+ button.setAttribute("label", this._stringBundle.GetStringFromName("setupsync.label"));
+ } else {
+ button.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
+ }
+ },
+
+
+ // Functions called by observers
+ onActivityStart: function SUI_onActivityStart() {
+ if (!gBrowser)
+ return;
+
+ let button = document.getElementById("sync-button");
+ if (!button)
+ return;
+
+ button.setAttribute("status", "active");
+ button.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label"));
+ },
+
+ onSyncDelay: function SUI_onSyncDelay() {
+ // basically, we want to just inform users that stuff is going to take a while
+ let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
+ let buttons = [new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
+ function() { gSyncUI.openServerStatus(); return true; }
+ )];
+ let notification = new Weave.Notification(
+ title, description, null, Weave.Notifications.PRIORITY_INFO, buttons);
+ Weave.Notifications.replaceTitle(notification);
+ this._wasDelayed = true;
+ },
+
+ onLoginFinish: function SUI_onLoginFinish() {
+ // Clear out any login failure notifications
+ let title = this._stringBundle.GetStringFromName("error.login.title");
+ this.clearError(title);
+ },
+
+ onSetupComplete: function SUI_onSetupComplete() {
+ this.onLoginFinish();
+ },
+
+ onLoginError: function SUI_onLoginError() {
+ // if login fails, any other notifications are essentially moot
+ Weave.Notifications.removeAll();
+
+ // if we haven't set up the client, don't show errors
+ if (this._needsSetup()) {
+ this.updateUI();
+ return;
+ }
+
+ let title = this._stringBundle.GetStringFromName("error.login.title");
+
+ let description;
+ if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
+ // Convert to days
+ let lastSync =
+ Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
+ description =
+ this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
+ } else {
+ let reason = Weave.Utils.getErrorString(Weave.Status.login);
+ description =
+ this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
+ }
+
+ let buttons = [];
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.login.prefs.label"),
+ this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
+ function() { gSyncUI.openPrefs(); return true; }
+ ));
+
+ let notification = new Weave.Notification(title, description, null,
+ Weave.Notifications.PRIORITY_WARNING, buttons);
+ Weave.Notifications.replaceTitle(notification);
+ this.updateUI();
+ },
+
+ onLogout: function SUI_onLogout() {
+ this.updateUI();
+ },
+
+ onStartOver: function SUI_onStartOver() {
+ this.clearError();
+ },
+
+ onQuotaNotice: function onQuotaNotice(subject, data) {
+ let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
+ let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
+ let buttons = [];
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
+ function() { gSyncUI.openQuotaDialog(); return true; }
+ ));
+
+ let notification = new Weave.Notification(
+ title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
+ Weave.Notifications.replaceTitle(notification);
+ },
+
+ openServerStatus: function () {
+ let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
+ window.openUILinkIn(statusURL, "tab");
+ },
+
+ // Commands
+ doSync: function SUI_doSync() {
+ setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
+ },
+
+ handleToolbarButton: function SUI_handleStatusbarButton() {
+ if (this._needsSetup())
+ this.openSetup();
+ else
+ this.doSync();
+ },
+
+ //XXXzpao should be part of syncCommon.js - which we might want to make a module...
+ // To be fixed in a followup (bug 583366)
+
+ /**
+ * Invoke the Sync setup wizard.
+ *
+ * @param wizardType
+ * Indicates type of wizard to launch:
+ * null -- regular set up wizard
+ * "pair" -- pair a device first
+ * "reset" -- reset sync
+ */
+
+ openSetup: function SUI_openSetup(wizardType) {
+ let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
+ if (win)
+ win.focus();
+ else {
+ window.openDialog("chrome://browser/content/sync/setup.xul",
+ "weaveSetup", "centerscreen,chrome,resizable=no",
+ wizardType);
+ }
+ },
+
+ openAddDevice: function () {
+ if (!Weave.Utils.ensureMPUnlocked())
+ return;
+
+ let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
+ if (win)
+ win.focus();
+ else
+ window.openDialog("chrome://browser/content/sync/addDevice.xul",
+ "syncAddDevice", "centerscreen,chrome,resizable=no");
+ },
+
+ openQuotaDialog: function SUI_openQuotaDialog() {
+ let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
+ if (win)
+ win.focus();
+ else
+ Services.ww.activeWindow.openDialog(
+ "chrome://browser/content/sync/quota.xul", "",
+ "centerscreen,chrome,dialog,modal");
+ },
+
+ openPrefs: function SUI_openPrefs() {
+ openPreferences("paneSync");
+ },
+
+
+ // Helpers
+ _updateLastSyncTime: function SUI__updateLastSyncTime() {
+ if (!gBrowser)
+ return;
+
+ let syncButton = document.getElementById("sync-button");
+ if (!syncButton)
+ return;
+
+ let lastSync = Services.prefs.getCharPref("services.sync.lastSync", "");
+ if (!lastSync || this._needsSetup()) {
+ syncButton.removeAttribute("tooltiptext");
+ return;
+ }
+
+ // Show the day-of-week and time (HH:MM) of last sync
+ let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
+ let lastSyncLabel =
+ this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
+
+ syncButton.setAttribute("tooltiptext", lastSyncLabel);
+ },
+
+ clearError: function SUI_clearError(errorString) {
+ Weave.Notifications.removeAll(errorString);
+ this.updateUI();
+ },
+
+ onSyncFinish: function SUI_onSyncFinish() {
+ let title = this._stringBundle.GetStringFromName("error.sync.title");
+
+ // Clear out sync failures on a successful sync
+ this.clearError(title);
+
+ if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
+ title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ this.clearError(title);
+ this._wasDelayed = false;
+ }
+ },
+
+ onSyncError: function SUI_onSyncError() {
+ let title = this._stringBundle.GetStringFromName("error.sync.title");
+
+ if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
+ this.onLoginError();
+ return;
+ }
+
+ let description;
+ if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
+ // Convert to days
+ let lastSync =
+ Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
+ description =
+ this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
+ } else {
+ let error = Weave.Utils.getErrorString(Weave.Status.sync);
+ description =
+ this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
+ }
+ let priority = Weave.Notifications.PRIORITY_WARNING;
+ let buttons = [];
+
+ // Check if the client is outdated in some way
+ let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
+ for (let [engine, reason] in Iterator(Weave.Status.engines))
+ outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
+
+ if (outdated) {
+ description = this._stringBundle.GetStringFromName(
+ "error.sync.needUpdate.description");
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
+ this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
+ function() {
+ window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab");
+ return true;
+ }
+ ));
+ }
+ else if (Weave.Status.sync == Weave.OVER_QUOTA) {
+ description = this._stringBundle.GetStringFromName(
+ "error.sync.quota.description");
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName(
+ "error.sync.viewQuotaButton.label"),
+ this._stringBundle.GetStringFromName(
+ "error.sync.viewQuotaButton.accesskey"),
+ function() { gSyncUI.openQuotaDialog(); return true; } )
+ );
+ }
+ else if (Weave.Status.enforceBackoff) {
+ priority = Weave.Notifications.PRIORITY_INFO;
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
+ function() { gSyncUI.openServerStatus(); return true; }
+ ));
+ }
+ else {
+ priority = Weave.Notifications.PRIORITY_INFO;
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
+ function() { gSyncUI.doSync(); return true; }
+ ));
+ }
+
+ let notification =
+ new Weave.Notification(title, description, null, priority, buttons);
+ Weave.Notifications.replaceTitle(notification);
+
+ if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
+ title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ Weave.Notifications.removeAll(title);
+ this._wasDelayed = false;
+ }
+
+ this.updateUI();
+ },
+
+ observe: function SUI_observe(subject, topic, data) {
+ if (this._unloaded) {
+ Cu.reportError("SyncUI observer called after unload: " + topic);
+ return;
+ }
+
+ switch (topic) {
+ case "weave:service:sync:start":
+ this.onActivityStart();
+ break;
+ case "weave:ui:sync:finish":
+ this.onSyncFinish();
+ break;
+ case "weave:ui:sync:error":
+ this.onSyncError();
+ break;
+ case "weave:service:sync:delayed":
+ this.onSyncDelay();
+ break;
+ case "weave:service:quota:remaining":
+ this.onQuotaNotice();
+ break;
+ case "weave:service:setup-complete":
+ this.onSetupComplete();
+ break;
+ case "weave:service:login:start":
+ this.onActivityStart();
+ break;
+ case "weave:service:login:finish":
+ this.onLoginFinish();
+ break;
+ case "weave:ui:login:error":
+ this.onLoginError();
+ break;
+ case "weave:service:logout:finish":
+ this.onLogout();
+ break;
+ case "weave:service:start-over":
+ this.onStartOver();
+ break;
+ case "weave:service:ready":
+ this.initUI();
+ break;
+ case "weave:notification:added":
+ this.initNotifications();
+ break;
+ case "weave:ui:clear-error":
+ this.clearError();
+ break;
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsIObserver,
+ Ci.nsISupportsWeakReference
+ ])
+};
+
+XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
+ //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
+ // but for now just make it work
+ return Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle("chrome://weave/locale/services/sync.properties");
+});
+
diff --git a/base/content/browser-tabPreviews.js b/base/content/browser-tabPreviews.js
new file mode 100644
index 0000000..e0755b8
--- /dev/null
+++ b/base/content/browser-tabPreviews.js
@@ -0,0 +1,1058 @@
+/*
+#ifdef 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/.
+#endif
+ */
+
+/**
+ * Tab previews utility, produces thumbnails
+ */
+var tabPreviews = {
+ aspectRatio: 0.5625, // 16:9
+
+ get width() {
+ delete this.width;
+ return this.width = Math.ceil(screen.availWidth / 5.75);
+ },
+
+ get height() {
+ delete this.height;
+ return this.height = Math.round(this.width * this.aspectRatio);
+ },
+
+ init: function tabPreviews_init() {
+ if (this._selectedTab)
+ return;
+ this._selectedTab = gBrowser.selectedTab;
+
+ gBrowser.tabContainer.addEventListener("TabSelect", this, false);
+ gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
+ },
+
+ get: function tabPreviews_get(aTab) {
+ let uri = aTab.linkedBrowser.currentURI.spec;
+
+ if (aTab.__thumbnail_lastURI &&
+ aTab.__thumbnail_lastURI != uri) {
+ aTab.__thumbnail = null;
+ aTab.__thumbnail_lastURI = null;
+ }
+
+ if (aTab.__thumbnail)
+ return aTab.__thumbnail;
+
+ if (aTab.getAttribute("pending") == "true") {
+ let img = new Image;
+ img.src = PageThumbs.getThumbnailURL(uri);
+ return img;
+ }
+
+ return this.capture(aTab, !aTab.hasAttribute("busy"));
+ },
+
+ capture: function tabPreviews_capture(aTab, aStore) {
+ var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+ thumbnail.mozOpaque = true;
+ thumbnail.height = this.height;
+ thumbnail.width = this.width;
+
+ var ctx = thumbnail.getContext("2d");
+ var win = aTab.linkedBrowser.contentWindow;
+ var snippetWidth = win.innerWidth * .6;
+ var scale = this.width / snippetWidth;
+ ctx.scale(scale, scale);
+ ctx.drawWindow(win, win.scrollX, win.scrollY,
+ snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)");
+
+ if (aStore &&
+ aTab.linkedBrowser /* bug 795608: the tab may got removed while drawing the thumbnail */) {
+ aTab.__thumbnail = thumbnail;
+ aTab.__thumbnail_lastURI = aTab.linkedBrowser.currentURI.spec;
+ }
+
+ return thumbnail;
+ },
+
+ handleEvent: function tabPreviews_handleEvent(event) {
+ switch (event.type) {
+ case "TabSelect":
+ if (this._selectedTab &&
+ this._selectedTab.parentNode &&
+ !this._pendingUpdate) {
+ // Generate a thumbnail for the tab that was selected.
+ // The timeout keeps the UI snappy and prevents us from generating thumbnails
+ // for tabs that will be closed. During that timeout, don't generate other
+ // thumbnails in case multiple TabSelect events occur fast in succession.
+ this._pendingUpdate = true;
+ setTimeout(function (self, aTab) {
+ self._pendingUpdate = false;
+ if (aTab.parentNode &&
+ !aTab.hasAttribute("busy") &&
+ !aTab.hasAttribute("pending"))
+ self.capture(aTab, true);
+ }, 2000, this, this._selectedTab);
+ }
+ this._selectedTab = event.target;
+ break;
+ case "SSTabRestored":
+ this.capture(event.target, true);
+ break;
+ }
+ }
+};
+
+var tabPreviewPanelHelper = {
+ opening: function (host) {
+ host.panel.hidden = false;
+
+ var handler = this._generateHandler(host);
+ host.panel.addEventListener("popupshown", handler, false);
+ host.panel.addEventListener("popuphiding", handler, false);
+
+ host._prevFocus = document.commandDispatcher.focusedElement;
+ },
+ _generateHandler: function (host) {
+ var self = this;
+ return function (event) {
+ if (event.target == host.panel) {
+ host.panel.removeEventListener(event.type, arguments.callee, false);
+ self["_" + event.type](host);
+ }
+ };
+ },
+ _popupshown: function (host) {
+ if ("setupGUI" in host)
+ host.setupGUI();
+ },
+ _popuphiding: function (host) {
+ if ("suspendGUI" in host)
+ host.suspendGUI();
+
+ if (host._prevFocus) {
+ Cc["@mozilla.org/focus-manager;1"]
+ .getService(Ci.nsIFocusManager)
+ .setFocus(host._prevFocus, Ci.nsIFocusManager.FLAG_NOSCROLL);
+ host._prevFocus = null;
+ } else
+ gBrowser.selectedBrowser.focus();
+
+ if (host.tabToSelect) {
+ gBrowser.selectedTab = host.tabToSelect;
+ host.tabToSelect = null;
+ }
+ }
+};
+
+/**
+ * Ctrl-Tab panel
+ */
+var ctrlTab = {
+ get panel () {
+ delete this.panel;
+ return this.panel = document.getElementById("ctrlTab-panel");
+ },
+ get showAllButton () {
+ delete this.showAllButton;
+ return this.showAllButton = document.getElementById("ctrlTab-showAll");
+ },
+ get previews () {
+ delete this.previews;
+ return this.previews = this.panel.getElementsByClassName("ctrlTab-preview");
+ },
+ get recentlyUsedLimit () {
+ delete this.recentlyUsedLimit;
+ return this.recentlyUsedLimit = gPrefService.getIntPref("browser.ctrlTab.recentlyUsedLimit");
+ },
+ get keys () {
+ var keys = {};
+ ["close", "find", "selectAll"].forEach(function (key) {
+ keys[key] = document.getElementById("key_" + key)
+ .getAttribute("key")
+ .toLocaleLowerCase().charCodeAt(0);
+ });
+ delete this.keys;
+ return this.keys = keys;
+ },
+ _selectedIndex: 0,
+ get selected () this._selectedIndex < 0 ?
+ document.activeElement :
+ this.previews.item(this._selectedIndex),
+ get isOpen () this.panel.state == "open" || this.panel.state == "showing" || this._timer,
+ get tabCount () this.tabList.length,
+ get tabPreviewCount () Math.min(this.previews.length - 1, this.tabCount),
+ get canvasWidth () Math.min(tabPreviews.width,
+ Math.ceil(screen.availWidth * .85 / this.tabPreviewCount)),
+ get canvasHeight () Math.round(this.canvasWidth * tabPreviews.aspectRatio),
+
+ get tabList () {
+ if (this._tabList)
+ return this._tabList;
+
+ // Using gBrowser.tabs instead of gBrowser.visibleTabs, as the latter
+ // exlcudes closing tabs, breaking the following loop in case the the
+ // selected tab is closing.
+ let list = Array.filter(gBrowser.tabs, function (tab) !tab.hidden);
+
+ // Rotate the list until the selected tab is first
+ while (!list[0].selected)
+ list.push(list.shift());
+
+ list = list.filter(function (tab) !tab.closing);
+
+ if (this.recentlyUsedLimit != 0) {
+ let recentlyUsedTabs = [];
+ for (let tab of this._recentlyUsedTabs) {
+ if (!tab.hidden && !tab.closing) {
+ recentlyUsedTabs.push(tab);
+ if (this.recentlyUsedLimit > 0 && recentlyUsedTabs.length >= this.recentlyUsedLimit)
+ break;
+ }
+ }
+ for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) {
+ list.splice(list.indexOf(recentlyUsedTabs[i]), 1);
+ list.unshift(recentlyUsedTabs[i]);
+ }
+ }
+
+ return this._tabList = list;
+ },
+
+ init: function ctrlTab_init() {
+ if (!this._recentlyUsedTabs) {
+ tabPreviews.init();
+
+ this._recentlyUsedTabs = [gBrowser.selectedTab];
+ this._init(true);
+ }
+ },
+
+ uninit: function ctrlTab_uninit() {
+ this._recentlyUsedTabs = null;
+ this._init(false);
+ },
+
+ prefName: "browser.ctrlTab.previews",
+ readPref: function ctrlTab_readPref() {
+ var enable =
+ gPrefService.getBoolPref(this.prefName) &&
+ (!gPrefService.prefHasUserValue("browser.ctrlTab.disallowForScreenReaders") ||
+ !gPrefService.getBoolPref("browser.ctrlTab.disallowForScreenReaders"));
+
+ if (enable)
+ this.init();
+ else
+ this.uninit();
+ },
+ observe: function (aSubject, aTopic, aPrefName) {
+ this.readPref();
+ },
+
+ updatePreviews: function ctrlTab_updatePreviews() {
+ for (let i = 0; i < this.previews.length; i++)
+ this.updatePreview(this.previews[i], this.tabList[i]);
+
+ var showAllLabel = gNavigatorBundle.getString("ctrlTab.showAll.label");
+ this.showAllButton.label =
+ PluralForm.get(this.tabCount, showAllLabel).replace("#1", this.tabCount);
+ },
+
+ updatePreview: function ctrlTab_updatePreview(aPreview, aTab) {
+ if (aPreview == this.showAllButton)
+ return;
+
+ aPreview._tab = aTab;
+
+ if (aPreview.firstChild)
+ aPreview.removeChild(aPreview.firstChild);
+ if (aTab) {
+ let canvasWidth = this.canvasWidth;
+ let canvasHeight = this.canvasHeight;
+ aPreview.appendChild(tabPreviews.get(aTab));
+ aPreview.setAttribute("label", aTab.label);
+ aPreview.setAttribute("tooltiptext", aTab.label);
+ aPreview.setAttribute("crop", aTab.crop);
+ aPreview.setAttribute("canvaswidth", canvasWidth);
+ aPreview.setAttribute("canvasstyle",
+ "max-width:" + canvasWidth + "px;" +
+ "min-width:" + canvasWidth + "px;" +
+ "max-height:" + canvasHeight + "px;" +
+ "min-height:" + canvasHeight + "px;");
+ if (aTab.image)
+ aPreview.setAttribute("image", aTab.image);
+ else
+ aPreview.removeAttribute("image");
+ aPreview.hidden = false;
+ } else {
+ aPreview.hidden = true;
+ aPreview.removeAttribute("label");
+ aPreview.removeAttribute("tooltiptext");
+ aPreview.removeAttribute("image");
+ }
+ },
+
+ advanceFocus: function ctrlTab_advanceFocus(aForward) {
+ let selectedIndex = Array.indexOf(this.previews, this.selected);
+ do {
+ selectedIndex += aForward ? 1 : -1;
+ if (selectedIndex < 0)
+ selectedIndex = this.previews.length - 1;
+ else if (selectedIndex >= this.previews.length)
+ selectedIndex = 0;
+ } while (this.previews[selectedIndex].hidden);
+
+ if (this._selectedIndex == -1) {
+ // Focus is already in the panel.
+ this.previews[selectedIndex].focus();
+ } else {
+ this._selectedIndex = selectedIndex;
+ }
+
+ if (this._timer) {
+ clearTimeout(this._timer);
+ this._timer = null;
+ this._openPanel();
+ }
+ },
+
+ _mouseOverFocus: function ctrlTab_mouseOverFocus(aPreview) {
+ if (this._trackMouseOver)
+ aPreview.focus();
+ },
+
+ pick: function ctrlTab_pick(aPreview) {
+ if (!this.tabCount)
+ return;
+
+ var select = (aPreview || this.selected);
+
+ if (select == this.showAllButton)
+ this.showAllTabs();
+ else
+ this.close(select._tab);
+ },
+
+ showAllTabs: function ctrlTab_showAllTabs(aPreview) {
+ this.close();
+ document.getElementById("Browser:ShowAllTabs").doCommand();
+ },
+
+ remove: function ctrlTab_remove(aPreview) {
+ if (aPreview._tab)
+ gBrowser.removeTab(aPreview._tab);
+ },
+
+ attachTab: function ctrlTab_attachTab(aTab, aPos) {
+ if (aPos == 0)
+ this._recentlyUsedTabs.unshift(aTab);
+ else if (aPos)
+ this._recentlyUsedTabs.splice(aPos, 0, aTab);
+ else
+ this._recentlyUsedTabs.push(aTab);
+ },
+ detachTab: function ctrlTab_detachTab(aTab) {
+ var i = this._recentlyUsedTabs.indexOf(aTab);
+ if (i >= 0)
+ this._recentlyUsedTabs.splice(i, 1);
+ },
+
+ open: function ctrlTab_open() {
+ if (this.isOpen)
+ return;
+
+ allTabs.close();
+
+ document.addEventListener("keyup", this, true);
+
+ this.updatePreviews();
+ this._selectedIndex = 1;
+
+ // Add a slight delay before showing the UI, so that a quick
+ // "ctrl-tab" keypress just flips back to the MRU tab.
+ this._timer = setTimeout(function (self) {
+ self._timer = null;
+ self._openPanel();
+ }, 200, this);
+ },
+
+ _openPanel: function ctrlTab_openPanel() {
+ tabPreviewPanelHelper.opening(this);
+
+ this.panel.width = Math.min(screen.availWidth * .99,
+ this.canvasWidth * 1.25 * this.tabPreviewCount);
+ var estimateHeight = this.canvasHeight * 1.25 + 75;
+ this.panel.openPopupAtScreen(screen.availLeft + (screen.availWidth - this.panel.width) / 2,
+ screen.availTop + (screen.availHeight - estimateHeight) / 2,
+ false);
+ },
+
+ close: function ctrlTab_close(aTabToSelect) {
+ if (!this.isOpen)
+ return;
+
+ if (this._timer) {
+ clearTimeout(this._timer);
+ this._timer = null;
+ this.suspendGUI();
+ if (aTabToSelect)
+ gBrowser.selectedTab = aTabToSelect;
+ return;
+ }
+
+ this.tabToSelect = aTabToSelect;
+ this.panel.hidePopup();
+ },
+
+ setupGUI: function ctrlTab_setupGUI() {
+ this.selected.focus();
+ this._selectedIndex = -1;
+
+ // Track mouse movement after a brief delay so that the item that happens
+ // to be under the mouse pointer initially won't be selected unintentionally.
+ this._trackMouseOver = false;
+ setTimeout(function (self) {
+ if (self.isOpen)
+ self._trackMouseOver = true;
+ }, 0, this);
+ },
+
+ suspendGUI: function ctrlTab_suspendGUI() {
+ document.removeEventListener("keyup", this, true);
+
+ Array.forEach(this.previews, function (preview) {
+ this.updatePreview(preview, null);
+ }, this);
+
+ this._tabList = null;
+ },
+
+ onKeyPress: function ctrlTab_onKeyPress(event) {
+ var isOpen = this.isOpen;
+
+ if (isOpen) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ switch (event.keyCode) {
+ case event.DOM_VK_TAB:
+ if (event.ctrlKey && !event.altKey && !event.metaKey) {
+ if (isOpen) {
+ this.advanceFocus(!event.shiftKey);
+ } else if (!event.shiftKey) {
+ event.preventDefault();
+ event.stopPropagation();
+ let tabs = gBrowser.visibleTabs;
+ if (tabs.length > 2) {
+ this.open();
+ } else if (tabs.length == 2) {
+ let index = tabs[0].selected ? 1 : 0;
+ gBrowser.selectedTab = tabs[index];
+ }
+ }
+ }
+ break;
+ default:
+ if (isOpen && event.ctrlKey) {
+ if (event.keyCode == event.DOM_VK_DELETE) {
+ this.remove(this.selected);
+ break;
+ }
+ switch (event.charCode) {
+ case this.keys.close:
+ this.remove(this.selected);
+ break;
+ case this.keys.find:
+ case this.keys.selectAll:
+ this.showAllTabs();
+ break;
+ }
+ }
+ }
+ },
+
+ removeClosingTabFromUI: function ctrlTab_removeClosingTabFromUI(aTab) {
+ if (this.tabCount == 2) {
+ this.close();
+ return;
+ }
+
+ this._tabList = null;
+ this.updatePreviews();
+
+ if (this.selected.hidden)
+ this.advanceFocus(false);
+ if (this.selected == this.showAllButton)
+ this.advanceFocus(false);
+
+ // If the current tab is removed, another tab can steal our focus.
+ if (aTab.selected && this.panel.state == "open") {
+ setTimeout(function (selected) {
+ selected.focus();
+ }, 0, this.selected);
+ }
+ },
+
+ handleEvent: function ctrlTab_handleEvent(event) {
+ switch (event.type) {
+ case "TabAttrModified":
+ // tab attribute modified (e.g. label, crop, busy, image, selected)
+ for (let i = this.previews.length - 1; i >= 0; i--) {
+ if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
+ this.updatePreview(this.previews[i], event.target);
+ break;
+ }
+ }
+ break;
+ case "TabSelect":
+ this.detachTab(event.target);
+ this.attachTab(event.target, 0);
+ break;
+ case "TabOpen":
+ this.attachTab(event.target, 1);
+ break;
+ case "TabClose":
+ this.detachTab(event.target);
+ if (this.isOpen)
+ this.removeClosingTabFromUI(event.target);
+ break;
+ case "keypress":
+ this.onKeyPress(event);
+ break;
+ case "keyup":
+ if (event.keyCode == event.DOM_VK_CONTROL)
+ this.pick();
+ break;
+ }
+ },
+
+ _init: function ctrlTab__init(enable) {
+ var toggleEventListener = enable ? "addEventListener" : "removeEventListener";
+
+ var tabContainer = gBrowser.tabContainer;
+ tabContainer[toggleEventListener]("TabOpen", this, false);
+ tabContainer[toggleEventListener]("TabAttrModified", this, false);
+ tabContainer[toggleEventListener]("TabSelect", this, false);
+ tabContainer[toggleEventListener]("TabClose", this, false);
+
+ document[toggleEventListener]("keypress", this, false);
+ gBrowser.mTabBox.handleCtrlTab = !enable;
+
+ // If we're not running, hide the "Show All Tabs" menu item,
+ // as Shift+Ctrl+Tab will be handled by the tab bar.
+ document.getElementById("menu_showAllTabs").hidden = !enable;
+
+ // Also disable the to ensure Shift+Ctrl+Tab never triggers
+ // Show All Tabs.
+ var key_showAllTabs = document.getElementById("key_showAllTabs");
+ if (enable)
+ key_showAllTabs.removeAttribute("disabled");
+ else
+ key_showAllTabs.setAttribute("disabled", "true");
+ }
+};
+
+
+/**
+ * All Tabs panel
+ */
+var allTabs = {
+ get panel () {
+ delete this.panel;
+ return this.panel = document.getElementById("allTabs-panel");
+ },
+ get filterField () {
+ delete this.filterField;
+ return this.filterField = document.getElementById("allTabs-filter");
+ },
+ get container () {
+ delete this.container;
+ return this.container = document.getElementById("allTabs-container");
+ },
+ get tabCloseButton () {
+ delete this.tabCloseButton;
+ return this.tabCloseButton = document.getElementById("allTabs-tab-close-button");
+ },
+ get toolbarButton() document.getElementById("alltabs-button"),
+ get previews () this.container.getElementsByClassName("allTabs-preview"),
+ get isOpen () this.panel.state == "open" || this.panel.state == "showing",
+
+ init: function allTabs_init() {
+ if (this._initiated)
+ return;
+ this._initiated = true;
+
+ tabPreviews.init();
+
+ Array.forEach(gBrowser.tabs, function (tab) {
+ this._addPreview(tab);
+ }, this);
+
+ gBrowser.tabContainer.addEventListener("TabOpen", this, false);
+ gBrowser.tabContainer.addEventListener("TabAttrModified", this, false);
+ gBrowser.tabContainer.addEventListener("TabMove", this, false);
+ gBrowser.tabContainer.addEventListener("TabClose", this, false);
+ },
+
+ uninit: function allTabs_uninit() {
+ if (!this._initiated)
+ return;
+
+ gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
+ gBrowser.tabContainer.removeEventListener("TabAttrModified", this, false);
+ gBrowser.tabContainer.removeEventListener("TabMove", this, false);
+ gBrowser.tabContainer.removeEventListener("TabClose", this, false);
+
+ while (this.container.hasChildNodes())
+ this.container.removeChild(this.container.firstChild);
+
+ this._initiated = false;
+ },
+
+ prefName: "browser.allTabs.previews",
+ readPref: function allTabs_readPref() {
+ var allTabsButton = this.toolbarButton;
+ if (!allTabsButton)
+ return;
+
+ if (gPrefService.getBoolPref(this.prefName)) {
+ allTabsButton.removeAttribute("type");
+ allTabsButton.setAttribute("command", "Browser:ShowAllTabs");
+ } else {
+ allTabsButton.setAttribute("type", "menu");
+ allTabsButton.removeAttribute("command");
+ allTabsButton.removeAttribute("oncommand");
+ }
+ },
+ observe: function (aSubject, aTopic, aPrefName) {
+ this.readPref();
+ },
+
+ pick: function allTabs_pick(aPreview) {
+ if (!aPreview)
+ aPreview = this._firstVisiblePreview;
+ if (aPreview)
+ this.tabToSelect = aPreview._tab;
+
+ this.close();
+ },
+
+ closeTab: function allTabs_closeTab(event) {
+ this.filterField.focus();
+ gBrowser.removeTab(event.currentTarget._targetPreview._tab);
+ },
+
+ filter: function allTabs_filter() {
+ if (this._currentFilter == this.filterField.value)
+ return;
+
+ this._currentFilter = this.filterField.value;
+
+ var filter = this._currentFilter.split(/\s+/g);
+ this._visible = 0;
+ Array.forEach(this.previews, function (preview) {
+ var tab = preview._tab;
+ var matches = 0;
+ if (filter.length && !tab.hidden) {
+ let tabstring = tab.linkedBrowser.currentURI.spec;
+ try {
+ tabstring = decodeURI(tabstring);
+ } catch (e) {}
+ tabstring = tab.label + " " + tab.label.toLocaleLowerCase() + " " + tabstring;
+ for (let i = 0; i < filter.length; i++)
+ matches += tabstring.includes(filter[i]);
+ }
+ if (matches < filter.length || tab.hidden) {
+ preview.hidden = true;
+ }
+ else {
+ this._visible++;
+ this._updatePreview(preview);
+ preview.hidden = false;
+ }
+ }, this);
+
+ this._reflow();
+ },
+
+ open: function allTabs_open() {
+ var allTabsButton = this.toolbarButton;
+ if (allTabsButton &&
+ allTabsButton.getAttribute("type") == "menu") {
+ // Without setTimeout, the menupopup won't stay open when invoking
+ // "View > Show All Tabs" and the menu bar auto-hides.
+ setTimeout(function () {
+ allTabsButton.open = true;
+ }, 0);
+ return;
+ }
+
+ this.init();
+
+ if (this.isOpen)
+ return;
+
+ this._maxPanelHeight = Math.max(gBrowser.clientHeight, screen.availHeight / 2);
+ this._maxPanelWidth = Math.max(gBrowser.clientWidth, screen.availWidth / 2);
+
+ this.filter();
+
+ tabPreviewPanelHelper.opening(this);
+
+ this.panel.popupBoxObject.setConsumeRollupEvent(PopupBoxObject.ROLLUP_NO_CONSUME);
+ this.panel.openPopup(gBrowser, "overlap", 0, 0, false, true);
+ },
+
+ close: function allTabs_close() {
+ this.panel.hidePopup();
+ },
+
+ setupGUI: function allTabs_setupGUI() {
+ this.filterField.focus();
+ this.filterField.placeholder = this.filterField.tooltipText;
+
+ this.panel.addEventListener("keypress", this, false);
+ this.panel.addEventListener("keypress", this, true);
+ this._browserCommandSet.addEventListener("command", this, false);
+
+ // When the panel is open, a second click on the all tabs button should
+ // close the panel but not re-open it.
+ document.getElementById("Browser:ShowAllTabs").setAttribute("disabled", "true");
+ },
+
+ suspendGUI: function allTabs_suspendGUI() {
+ this.filterField.placeholder = "";
+ this.filterField.value = "";
+ this._currentFilter = null;
+
+ this._updateTabCloseButton();
+
+ this.panel.removeEventListener("keypress", this, false);
+ this.panel.removeEventListener("keypress", this, true);
+ this._browserCommandSet.removeEventListener("command", this, false);
+
+ setTimeout(function () {
+ document.getElementById("Browser:ShowAllTabs").removeAttribute("disabled");
+ }, 300);
+ },
+
+ handleEvent: function allTabs_handleEvent(event) {
+ if (event.type.startsWith("Tab")) {
+ var tab = event.target;
+ if (event.type != "TabOpen")
+ var preview = this._getPreview(tab);
+ }
+ switch (event.type) {
+ case "TabAttrModified":
+ // tab attribute modified (e.g. label, crop, busy, image)
+ if (!preview.hidden)
+ this._updatePreview(preview);
+ break;
+ case "TabOpen":
+ if (this.isOpen)
+ this.close();
+ this._addPreview(tab);
+ break;
+ case "TabMove":
+ let siblingPreview = tab.nextSibling &&
+ this._getPreview(tab.nextSibling);
+ if (siblingPreview)
+ siblingPreview.parentNode.insertBefore(preview, siblingPreview);
+ else
+ this.container.lastChild.appendChild(preview);
+ if (this.isOpen && !preview.hidden) {
+ this._reflow();
+ preview.focus();
+ }
+ break;
+ case "TabClose":
+ this._removePreview(preview);
+ break;
+ case "keypress":
+ this._onKeyPress(event);
+ break;
+ case "command":
+ if (event.target.id != "Browser:ShowAllTabs") {
+ // Close the panel when there's a browser command executing in the background.
+ this.close();
+ }
+ break;
+ }
+ },
+
+ _visible: 0,
+ _currentFilter: null,
+ get _stack () {
+ delete this._stack;
+ return this._stack = document.getElementById("allTabs-stack");
+ },
+ get _browserCommandSet () {
+ delete this._browserCommandSet;
+ return this._browserCommandSet = document.getElementById("mainCommandSet");
+ },
+ get _previewLabelHeight () {
+ delete this._previewLabelHeight;
+ return this._previewLabelHeight = parseInt(getComputedStyle(this.previews[0], "").lineHeight);
+ },
+
+ get _visiblePreviews ()
+ Array.filter(this.previews, function (preview) !preview.hidden),
+
+ get _firstVisiblePreview () {
+ if (this._visible == 0)
+ return null;
+ var previews = this.previews;
+ for (let i = 0; i < previews.length; i++) {
+ if (!previews[i].hidden)
+ return previews[i];
+ }
+ return null;
+ },
+
+ _reflow: function allTabs_reflow() {
+ this._updateTabCloseButton();
+
+ const CONTAINER_MAX_WIDTH = this._maxPanelWidth * .95;
+ const CONTAINER_MAX_HEIGHT = this._maxPanelHeight - 35;
+ // the size of the whole preview relative to the thumbnail
+ const REL_PREVIEW_THUMBNAIL = 1.2;
+ const REL_PREVIEW_HEIGHT_WIDTH = tabPreviews.height / tabPreviews.width;
+ const PREVIEW_MAX_WIDTH = tabPreviews.width * REL_PREVIEW_THUMBNAIL;
+
+ var rows, previewHeight, previewWidth, outerHeight;
+ this._columns = Math.floor(CONTAINER_MAX_WIDTH / PREVIEW_MAX_WIDTH);
+ do {
+ rows = Math.ceil(this._visible / this._columns);
+ previewWidth = Math.min(PREVIEW_MAX_WIDTH,
+ Math.round(CONTAINER_MAX_WIDTH / this._columns));
+ previewHeight = Math.round(previewWidth * REL_PREVIEW_HEIGHT_WIDTH);
+ outerHeight = previewHeight + this._previewLabelHeight;
+ } while (rows * outerHeight > CONTAINER_MAX_HEIGHT && ++this._columns);
+
+ var outerWidth = previewWidth;
+ {
+ let innerWidth = Math.ceil(previewWidth / REL_PREVIEW_THUMBNAIL);
+ let innerHeight = Math.ceil(previewHeight / REL_PREVIEW_THUMBNAIL);
+ var canvasStyle = "max-width:" + innerWidth + "px;" +
+ "min-width:" + innerWidth + "px;" +
+ "max-height:" + innerHeight + "px;" +
+ "min-height:" + innerHeight + "px;";
+ }
+
+ var previews = Array.slice(this.previews);
+
+ while (this.container.hasChildNodes())
+ this.container.removeChild(this.container.firstChild);
+ for (let i = rows || 1; i > 0; i--)
+ this.container.appendChild(document.createElement("hbox"));
+
+ var row = this.container.firstChild;
+ var colCount = 0;
+ previews.forEach(function (preview) {
+ if (!preview.hidden &&
+ ++colCount > this._columns) {
+ row = row.nextSibling;
+ colCount = 1;
+ }
+ preview.setAttribute("minwidth", outerWidth);
+ preview.setAttribute("height", outerHeight);
+ preview.setAttribute("canvasstyle", canvasStyle);
+ preview.removeAttribute("closebuttonhover");
+ row.appendChild(preview);
+ }, this);
+
+ this._stack.width = this._maxPanelWidth;
+ this.container.width = Math.ceil(outerWidth * Math.min(this._columns, this._visible));
+ this.container.left = Math.round((this._maxPanelWidth - this.container.width) / 2);
+ this.container.maxWidth = this._maxPanelWidth - this.container.left;
+ this.container.maxHeight = rows * outerHeight;
+ },
+
+ _addPreview: function allTabs_addPreview(aTab) {
+ var preview = document.createElement("button");
+ preview.className = "allTabs-preview";
+ preview._tab = aTab;
+ this.container.lastChild.appendChild(preview);
+ },
+
+ _removePreview: function allTabs_removePreview(aPreview) {
+ var updateUI = (this.isOpen && !aPreview.hidden);
+ aPreview._tab = null;
+ aPreview.parentNode.removeChild(aPreview);
+ if (updateUI) {
+ this._visible--;
+ this._reflow();
+ this.filterField.focus();
+ }
+ },
+
+ _getPreview: function allTabs_getPreview(aTab) {
+ var previews = this.previews;
+ for (let i = 0; i < previews.length; i++)
+ if (previews[i]._tab == aTab)
+ return previews[i];
+ return null;
+ },
+
+ _updateTabCloseButton: function allTabs_updateTabCloseButton(event) {
+ if (event && event.target == this.tabCloseButton)
+ return;
+
+ if (this.tabCloseButton._targetPreview) {
+ if (event && event.target == this.tabCloseButton._targetPreview)
+ return;
+
+ this.tabCloseButton._targetPreview.removeAttribute("closebuttonhover");
+ }
+
+ if (event &&
+ event.target.parentNode.parentNode == this.container &&
+ (event.target._tab.previousSibling || event.target._tab.nextSibling)) {
+ let canvas = event.target.firstChild.getBoundingClientRect();
+ let container = this.container.getBoundingClientRect();
+ let tabCloseButton = this.tabCloseButton.getBoundingClientRect();
+ let alignLeft = getComputedStyle(this.panel, "").direction == "rtl";
+#ifdef XP_MACOSX
+ alignLeft = !alignLeft;
+#endif
+ this.tabCloseButton.left = canvas.left -
+ container.left +
+ parseInt(this.container.left) +
+ (alignLeft ? 0 :
+ canvas.width - tabCloseButton.width);
+ this.tabCloseButton.top = canvas.top - container.top;
+ this.tabCloseButton._targetPreview = event.target;
+ this.tabCloseButton.style.visibility = "visible";
+ event.target.setAttribute("closebuttonhover", "true");
+ } else {
+ this.tabCloseButton.style.visibility = "hidden";
+ this.tabCloseButton.left = this.tabCloseButton.top = 0;
+ this.tabCloseButton._targetPreview = null;
+ }
+ },
+
+ _updatePreview: function allTabs_updatePreview(aPreview) {
+ aPreview.setAttribute("label", aPreview._tab.label);
+ aPreview.setAttribute("tooltiptext", aPreview._tab.label);
+ aPreview.setAttribute("crop", aPreview._tab.crop);
+ if (aPreview._tab.image)
+ aPreview.setAttribute("image", aPreview._tab.image);
+ else
+ aPreview.removeAttribute("image");
+
+ aPreview.removeAttribute("soundplaying");
+ aPreview.removeAttribute("muted");
+ if (aPreview._tab.hasAttribute("muted"))
+ aPreview.setAttribute("muted", "true");
+ else if (aPreview._tab.hasAttribute("soundplaying"))
+ aPreview.setAttribute("soundplaying", "true");
+
+ var thumbnail = tabPreviews.get(aPreview._tab);
+ if (aPreview.firstChild) {
+ if (aPreview.firstChild == thumbnail)
+ return;
+ aPreview.removeChild(aPreview.firstChild);
+ }
+ aPreview.appendChild(thumbnail);
+ },
+
+ _onKeyPress: function allTabs_onKeyPress(event) {
+ if (event.eventPhase == event.CAPTURING_PHASE) {
+ this._onCapturingKeyPress(event);
+ return;
+ }
+
+ if (event.keyCode == event.DOM_VK_ESCAPE) {
+ this.close();
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+
+ if (event.target == this.filterField) {
+ switch (event.keyCode) {
+ case event.DOM_VK_UP:
+ if (this._visible) {
+ let previews = this._visiblePreviews;
+ let columns = Math.min(previews.length, this._columns);
+ previews[Math.floor(previews.length / columns) * columns - 1].focus();
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ break;
+ case event.DOM_VK_DOWN:
+ if (this._visible) {
+ this._firstVisiblePreview.focus();
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ break;
+ }
+ }
+ },
+
+ _onCapturingKeyPress: function allTabs_onCapturingKeyPress(event) {
+ switch (event.keyCode) {
+ case event.DOM_VK_UP:
+ case event.DOM_VK_DOWN:
+ if (event.target != this.filterField)
+ this._advanceFocusVertically(event);
+ break;
+ case event.DOM_VK_RETURN:
+ if (event.target == this.filterField) {
+ this.filter();
+ this.pick();
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ break;
+ }
+ },
+
+ _advanceFocusVertically: function allTabs_advanceFocusVertically(event) {
+ var preview = document.activeElement;
+ if (!preview || preview.parentNode.parentNode != this.container)
+ return;
+
+ event.stopPropagation();
+
+ var up = (event.keyCode == event.DOM_VK_UP);
+ var previews = this._visiblePreviews;
+
+ if (up && preview == previews[0]) {
+ this.filterField.focus();
+ return;
+ }
+
+ var i = previews.indexOf(preview);
+ var columns = Math.min(previews.length, this._columns);
+ var column = i % columns;
+ var row = Math.floor(i / columns);
+
+ function newIndex() row * columns + column;
+ function outOfBounds() newIndex() >= previews.length;
+
+ if (up) {
+ row--;
+ if (row < 0) {
+ let rows = Math.ceil(previews.length / columns);
+ row = rows - 1;
+ column--;
+ if (outOfBounds())
+ row--;
+ }
+ } else {
+ row++;
+ if (outOfBounds()) {
+ if (column == columns - 1) {
+ this.filterField.focus();
+ return;
+ }
+ row = 0;
+ column++;
+ }
+ }
+ previews[newIndex()].focus();
+ }
+};
diff --git a/base/content/browser-tabPreviews.xml b/base/content/browser-tabPreviews.xml
new file mode 100644
index 0000000..4f54321
--- /dev/null
+++ b/base/content/browser-tabPreviews.xml
@@ -0,0 +1,78 @@
+
+
+# -*- Mode: HTML -*-
+# 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/.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef XP_MACOSX
+# Control+click is a right click on OS X
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/content/browser-thumbnails.js b/base/content/browser-thumbnails.js
new file mode 100644
index 0000000..079b0ac
--- /dev/null
+++ b/base/content/browser-thumbnails.js
@@ -0,0 +1,203 @@
+#ifdef 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/. */
+#endif
+
+/**
+ * Keeps thumbnails of open web pages up-to-date.
+ */
+var gBrowserThumbnails = {
+ /**
+ * Pref that controls whether we can store SSL content on disk
+ */
+ PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
+
+ _captureDelayMS: 1000,
+
+ /**
+ * Used to keep track of disk_cache_ssl preference
+ */
+ _sslDiskCacheEnabled: null,
+
+ /**
+ * Map of capture() timeouts assigned to their browsers.
+ */
+ _timeouts: null,
+
+ /**
+ * List of tab events we want to listen for.
+ */
+ _tabEvents: ["TabClose", "TabSelect"],
+
+ init: function Thumbnails_init() {
+ // Bug 863512 - Make page thumbnails work in electrolysis
+ if (gMultiProcessBrowser)
+ return;
+
+ try {
+ if (Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled"))
+ return;
+ } catch (e) {}
+
+ PageThumbs.addExpirationFilter(this);
+ gBrowser.addTabsProgressListener(this);
+ Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
+
+ this._sslDiskCacheEnabled =
+ Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
+
+ this._tabEvents.forEach(function (aEvent) {
+ gBrowser.tabContainer.addEventListener(aEvent, this, false);
+ }, this);
+
+ this._timeouts = new WeakMap();
+ },
+
+ uninit: function Thumbnails_uninit() {
+ // Bug 863512 - Make page thumbnails work in electrolysis
+ if (gMultiProcessBrowser)
+ return;
+
+ PageThumbs.removeExpirationFilter(this);
+ gBrowser.removeTabsProgressListener(this);
+ Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
+
+ this._tabEvents.forEach(function (aEvent) {
+ gBrowser.tabContainer.removeEventListener(aEvent, this, false);
+ }, this);
+ },
+
+ handleEvent: function Thumbnails_handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "scroll":
+ let browser = aEvent.currentTarget;
+ if (this._timeouts.has(browser))
+ this._delayedCapture(browser);
+ break;
+ case "TabSelect":
+ this._delayedCapture(aEvent.target.linkedBrowser);
+ break;
+ case "TabClose": {
+ this._clearTimeout(aEvent.target.linkedBrowser);
+ break;
+ }
+ }
+ },
+
+ observe: function Thumbnails_observe() {
+ this._sslDiskCacheEnabled =
+ Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
+ },
+
+ filterForThumbnailExpiration:
+ function Thumbnails_filterForThumbnailExpiration(aCallback) {
+ // Tycho: aCallback([browser.currentURI.spec for (browser of gBrowser.browsers)]);
+ let result = [];
+ for (let browser of gBrowser.browsers) {
+ result.push(browser.currentURI.spec);
+ }
+ aCallback(result);
+ },
+
+ /**
+ * State change progress listener for all tabs.
+ */
+ onStateChange: function Thumbnails_onStateChange(aBrowser, aWebProgress,
+ aRequest, aStateFlags, aStatus) {
+ if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
+ aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)
+ this._delayedCapture(aBrowser);
+ },
+
+ _capture: function Thumbnails_capture(aBrowser) {
+ if (this._shouldCapture(aBrowser))
+ PageThumbs.captureAndStore(aBrowser);
+ },
+
+ _delayedCapture: function Thumbnails_delayedCapture(aBrowser) {
+ if (this._timeouts.has(aBrowser))
+ clearTimeout(this._timeouts.get(aBrowser));
+ else
+ aBrowser.addEventListener("scroll", this, true);
+
+ let timeout = setTimeout(function () {
+ this._clearTimeout(aBrowser);
+ this._capture(aBrowser);
+ }.bind(this), this._captureDelayMS);
+
+ this._timeouts.set(aBrowser, timeout);
+ },
+
+ _shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
+ // Capture only if it's the currently selected tab.
+ if (aBrowser != gBrowser.selectedBrowser)
+ return false;
+
+ // Don't capture in per-window private browsing mode.
+ if (PrivateBrowsingUtils.isWindowPrivate(window))
+ return false;
+
+ let doc = aBrowser.contentDocument;
+
+ // FIXME Bug 720575 - Don't capture thumbnails for SVG or XML documents as
+ // that currently regresses Talos SVG tests.
+ if (doc instanceof XMLDocument)
+ return false;
+
+ // There's no point in taking screenshot of loading pages.
+ if (aBrowser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
+ return false;
+
+ // Don't take screenshots of about: pages.
+ if (aBrowser.currentURI.schemeIs("about"))
+ return false;
+
+ let channel = aBrowser.docShell.currentDocumentChannel;
+
+ // No valid document channel. We shouldn't take a screenshot.
+ if (!channel)
+ return false;
+
+ // Don't take screenshots of internally redirecting about: pages.
+ // This includes error pages.
+ let uri = channel.originalURI;
+ if (uri.schemeIs("about"))
+ return false;
+
+ let httpChannel;
+ try {
+ httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
+ } catch (e) { /* Not an HTTP channel. */ }
+
+ if (httpChannel) {
+ // Continue only if we have a 2xx status code.
+ try {
+ if (Math.floor(httpChannel.responseStatus / 100) != 2)
+ return false;
+ } catch (e) {
+ // Can't get response information from the httpChannel
+ // because mResponseHead is not available.
+ return false;
+ }
+
+ // Cache-Control: no-store.
+ if (httpChannel.isNoStoreResponse())
+ return false;
+
+ // Don't capture HTTPS pages unless the user explicitly enabled it.
+ if (uri.schemeIs("https") && !this._sslDiskCacheEnabled)
+ return false;
+ }
+
+ return true;
+ },
+
+ _clearTimeout: function Thumbnails_clearTimeout(aBrowser) {
+ if (this._timeouts.has(aBrowser)) {
+ aBrowser.removeEventListener("scroll", this, false);
+ clearTimeout(this._timeouts.get(aBrowser));
+ this._timeouts.delete(aBrowser);
+ }
+ }
+};
diff --git a/base/content/browser-title.css b/base/content/browser-title.css
new file mode 100644
index 0000000..5f7e775
--- /dev/null
+++ b/base/content/browser-title.css
@@ -0,0 +1,204 @@
+/* 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/. */
+
+#main-window::after {
+ content: attr(title);
+ line-height: 50px;
+ max-height: 50px;
+ overflow: -moz-hidden-unscrollable;
+ pointer-events: none;
+ position: fixed;
+ word-wrap: break-word;
+ -moz-hyphens: auto;
+ color: CaptionText;
+ font-weight: bold;
+ text-align: left;
+}
+
+#main-window:-moz-window-inactive::after {
+ color: InactiveCaptionText;
+}
+
+/* Win10 doesn't respond to inactive caption, so dim it instead */
+@media (-moz-os-version: windows-win10) {
+ #main-window:-moz-window-inactive::after {
+ opacity: 0.5;
+ }
+}
+
+/* Hide in fullscreen/TiT mode */
+#main-window[inFullscreen="true"]::after,
+#main-window[sizemode="maximized"][tabsintitlebar="true"]::after,
+#main-window:not([chromemargin])::after {
+ opacity: 0 !important;
+}
+
+
+#main-window::after {
+ padding: 0 132px; /* AppMenu button/wincontrols width offset */
+ left: 0;
+ right: 0;
+}
+
+#main-window[privatebrowsingmode=temporary]::after {
+ padding: 0px 132px 0px 152px; /* AppMenu button width offset for PB mode */
+}
+
+#main-window[sizemode="normal"]::after {
+ left: -12px;
+ right: -12px;
+}
+
+/* Windows Classic theme */
+
+@media all and (-moz-windows-classic) {
+
+ #main-window::after {
+ top: -13px;
+ text-shadow: none !important;
+ background-position: 2px 18px;
+ }
+
+}
+
+
+/* Windows Aero (Vista, non-glass 7/8) */
+
+@media all and (-moz-windows-theme: aero) {
+
+ #main-window::after {
+ top: -11px;
+ font-weight: normal;
+ text-shadow: none;
+ background-position: 2px 17px;
+ }
+
+ #main-window[sizemode="maximized"]::after {
+ top: -7px;
+ }
+
+}
+
+
+/* Windows Aero Glass */
+
+@media (-moz-windows-glass) {
+
+ #main-window::after {
+ top: -13px;
+ color: black;
+ text-shadow: rgba(255,255,255,.6) 7px -1px 12px,
+ rgba(255,255,255,.6) 6px -1px 13px,
+ rgba(255,255,255,.9) 5px -1px 14px,
+ rgba(255,255,255,.6) -7px -1px 12px,
+ rgba(255,255,255,.6) -6px -1px 13px,
+ rgba(255,255,255,.9) -5px -1px 14px;
+ z-index: -99999;
+ background-position: 2px 18px;
+ font-weight: bold;
+ }
+
+ #main-window[sizemode="maximized"]::after {
+ top: -7px;
+ }
+
+ #main-window:-moz-window-inactive::after {
+ opacity: .9;
+ color: black;
+ text-shadow: rgba(255,255,255,.7) 7px -1px 12px,
+ rgba(255,255,255,.5) 6px -1px 13px,
+ rgba(255,255,255,.5) 5px -1px 14px,
+ rgba(255,255,255,.7) -7px -1px 12px,
+ rgba(255,255,255,.5) -6px -1px 13px,
+ rgba(255,255,255,.5) -5px -1px 14px;
+ }
+
+}
+
+
+/* Generic other themes */
+
+@media all and (-moz-windows-theme: generic) {
+
+ #main-window::after {
+ font-family: trebuchet MS;
+ font-size: 13px;
+ text-shadow: 1px 1px rgba(0, 0, 0, .2);
+ top: -9px;
+ background-position: 2px 16px;
+ }
+
+ #main-window:-moz-window-inactive::after {
+ text-shadow: none;
+ }
+
+}
+
+
+/* Compositor style for Win 8/10 */
+
+@media all and (-moz-windows-compositor) {
+ @media not all and (-moz-windows-glass) {
+
+ #main-window::after {
+ background-position: 4px 17px;
+ top: -13px;
+ }
+
+ @media (-moz-os-version: windows-win8) {
+ #main-window::after {
+ font-size: 15px;
+ text-align: center;
+ }
+
+ #main-window[darkwindowframe="true"]:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
+ /* Dark window frame/accent color on Win 8 */
+ color: white;
+ }
+ }
+
+ @media (-moz-os-version: windows-win10) {
+ #main-window::after {
+ text-align: left;
+ }
+
+ @media (-moz-windows-accent-color-applies: 0) {
+ #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
+ /* Default Windows 10 styling is white - apply black text styling */
+ color: black;
+ }
+ }
+
+ @media (-moz-windows-accent-color-applies) {
+ #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme)::after {
+ /* Accent color is applied - use the associated text styling */
+ color: -moz-win-accentcolortext;
+ }
+ }
+ }
+
+ #main-window[sizemode="maximized"]::after {
+ top: -5px;
+ }
+ }
+
+}
+
+/* Lightweight Themes */
+
+#main-window:-moz-lwtheme::after {
+ color: inherit;
+ text-shadow: inherit;
+}
+
+
+/* Hide for small windows */
+
+@media not all and (min-width: 320px) {
+
+ #main-window::after {
+ opacity: 0 !important;
+ }
+
+}
\ No newline at end of file
diff --git a/base/content/browser-uacompat.js b/base/content/browser-uacompat.js
new file mode 100644
index 0000000..933aa55
--- /dev/null
+++ b/base/content/browser-uacompat.js
@@ -0,0 +1,45 @@
+/* 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/. */
+
+var UserAgentCompatibility = {
+ PREF_UA_COMPAT: "general.useragent.compatMode",
+ PREF_UA_COMPAT_GECKO: "general.useragent.compatMode.gecko",
+ PREF_UA_COMPAT_FIREFOX: "general.useragent.compatMode.firefox",
+
+ init: function() {
+ this.checkPreferences();
+ Services.prefs.addObserver(this.PREF_UA_COMPAT, this, false);
+ Services.prefs.addObserver(this.PREF_UA_COMPAT_GECKO, this, false);
+ Services.prefs.addObserver(this.PREF_UA_COMPAT_FIREFOX, this, false);
+ },
+
+ uninit: function() {
+ Services.prefs.removeObserver(this.PREF_UA_COMPAT, this, false);
+ Services.prefs.removeObserver(this.PREF_UA_COMPAT_GECKO, this, false);
+ Services.prefs.removeObserver(this.PREF_UA_COMPAT_FIREFOX, this, false);
+ },
+
+ observe: function() {
+ this.checkPreferences();
+ },
+
+ checkPreferences: function() {
+ var compatMode = Services.prefs.getIntPref(this.PREF_UA_COMPAT);
+
+ switch(compatMode) {
+ case 0:
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, false);
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, false);
+ break;
+ case 1:
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, true);
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, false);
+ break;
+ case 2:
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_GECKO, true);
+ Services.prefs.setBoolPref(this.PREF_UA_COMPAT_FIREFOX, true);
+ break;
+ }
+ }
+};
diff --git a/base/content/browser-webrtcUI.js b/base/content/browser-webrtcUI.js
new file mode 100644
index 0000000..d59134c
--- /dev/null
+++ b/base/content/browser-webrtcUI.js
@@ -0,0 +1,55 @@
+# -*- Mode: javascript; 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/.
+
+var WebrtcIndicator = {
+ init: function () {
+ let temp = {};
+ Cu.import("resource:///modules/webrtcUI.jsm", temp);
+ this.UIModule = temp.webrtcUI;
+
+ this.updateButton();
+ },
+
+ get button() {
+ delete this.button;
+ return this.button = document.getElementById("webrtc-status-button");
+ },
+
+ updateButton: function () {
+ this.button.hidden = !this.UIModule.showGlobalIndicator;
+ },
+
+ fillPopup: function (aPopup) {
+ this._menuitemData = new WeakMap;
+ for (let streamData of this.UIModule.activeStreams) {
+ let menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("label", streamData.uri);
+ menuitem.setAttribute("tooltiptext", streamData.uri);
+
+ this._menuitemData.set(menuitem, streamData);
+
+ aPopup.appendChild(menuitem);
+ }
+ },
+
+ clearPopup: function (aPopup) {
+ while (aPopup.lastChild)
+ aPopup.removeChild(aPopup.lastChild);
+ },
+
+ menuCommand: function (aMenuitem) {
+ let streamData = this._menuitemData.get(aMenuitem);
+ if (!streamData)
+ return;
+
+ let browserWindow = streamData.browser.ownerDocument.defaultView;
+ if (streamData.tab) {
+ browserWindow.gBrowser.selectedTab = streamData.tab;
+ } else {
+ streamData.browser.focus();
+ }
+ browserWindow.focus();
+ }
+}
diff --git a/base/content/browser.css b/base/content/browser.css
new file mode 100644
index 0000000..a2970ae
--- /dev/null
+++ b/base/content/browser.css
@@ -0,0 +1,759 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+searchbar {
+ -moz-binding: url("chrome://browser/content/search/search.xml#searchbar");
+}
+
+browser[remote="true"] {
+ -moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
+}
+
+tabbrowser {
+ -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
+}
+
+.tabbrowser-tabs {
+ -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
+}
+
+#tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
+#tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
+#tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
+#TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
+#TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
+ visibility: collapse;
+}
+
+#alltabs-button { /* Pale Moon: Always show this button! (less jumpy UI) */
+ visibility: visible !important;
+}
+
+#tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
+ visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
+}
+
+.tabbrowser-tab {
+ -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
+}
+
+.tabbrowser-tab:not([pinned]) {
+ -moz-box-flex: 100;
+ max-width: 250px;
+ min-width: 100px;
+ width: 0;
+ transition: min-width 175ms ease-out,
+ max-width 200ms ease-out,
+ opacity 80ms ease-out 20ms /* hide the tab for the first 20ms of the max-width transition */;
+}
+
+.tabbrowser-tab:not([pinned]):not([fadein]) {
+ max-width: 0.1px;
+ min-width: 0.1px;
+ opacity: 0 !important;
+ transition: min-width 175ms ease-out,
+ max-width 200ms ease-out,
+ opacity 80ms ease-out 180ms /* hide the tab for the last 20ms of the max-width transition */;
+}
+
+.tab-throbber:not([fadein]):not([pinned]),
+.tab-label:not([fadein]):not([pinned]),
+.tab-icon-image:not([fadein]):not([pinned]),
+.tab-close-button:not([fadein]):not([pinned]) {
+ display: none;
+}
+
+.tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
+ position: fixed !important;
+ display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
+}
+
+.tabbrowser-tabs[movingtab] > .tabbrowser-tab[selected] {
+ position: relative;
+ z-index: 2;
+ pointer-events: none; /* avoid blocking dragover events on scroll buttons */
+}
+
+.tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
+ transition: transform 200ms ease-out;
+}
+
+#alltabs-popup {
+ -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
+}
+
+toolbar[printpreview="true"] {
+ -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
+}
+
+#toolbar-menubar {
+ -moz-box-ordinal-group: 5;
+}
+
+#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
+ -moz-box-ordinal-group: 50;
+}
+
+#TabsToolbar {
+ -moz-box-ordinal-group: 100;
+}
+
+#TabsToolbar[tabsontop="true"] {
+ -moz-box-ordinal-group: 10;
+}
+
+%ifdef CAN_DRAW_IN_TITLEBAR
+#main-window[inFullscreen] > #titlebar,
+#main-window[inFullscreen] .titlebar-placeholder,
+#main-window:not([tabsintitlebar]) .titlebar-placeholder {
+ display: none;
+}
+
+#titlebar {
+ -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
+ -moz-window-dragging: drag;
+}
+
+%ifdef XP_WIN
+#main-window[tabsontop="true"] #TabsToolbar,
+#main-window[tabsontop="true"] #toolbar-menubar,
+#main-window[tabsontop="true"] #navigator-toolbox > toolbar:-moz-lwtheme {
+ -moz-window-dragging: drag;
+}
+%endif
+
+#titlebar-spacer {
+ pointer-events: none;
+}
+
+#main-window[tabsintitlebar] #appmenu-button-container,
+#main-window[tabsintitlebar] #titlebar-buttonbox {
+ position: relative;
+}
+%endif
+
+#main-window[inDOMFullscreen] #sidebar-box,
+#main-window[inDOMFullscreen] #sidebar-splitter {
+ visibility: collapse;
+}
+
+.bookmarks-toolbar-customize,
+#wrapper-personal-bookmarks > #personal-bookmarks > #PlacesToolbar > hbox > #PlacesToolbarItems {
+ display: none;
+}
+
+#wrapper-personal-bookmarks[place="toolbar"] > #personal-bookmarks > #PlacesToolbar > .bookmarks-toolbar-customize {
+ display: -moz-box;
+}
+
+#main-window[disablechrome] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
+ visibility: collapse;
+}
+
+#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
+#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
+#urlbar-container[combined] + #reload-button + #stop-button,
+#urlbar-container[combined] + #reload-button,
+toolbar:not([mode="icons"]) > #urlbar-container > #urlbar > toolbarbutton,
+toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button:not([displaystop]) + #urlbar-stop-button,
+toolbar[mode="icons"] > #urlbar-container > #urlbar > #urlbar-reload-button[displaystop],
+toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
+toolbar[mode="icons"] > #reload-button[displaystop] {
+ visibility: collapse;
+}
+
+#feed-button > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+#feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
+ direction: rtl;
+}
+
+#main-window:-moz-lwtheme {
+ background-repeat: no-repeat;
+ background-position: top right;
+}
+
+%ifdef XP_MACOSX
+#main-window[inFullscreen="true"] {
+ padding-top: 0; /* override drawintitlebar="true" */
+}
+%endif
+
+#browser-bottombox[lwthemefooter="true"] {
+ background-repeat: no-repeat;
+ background-position: bottom left;
+}
+
+splitmenu {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#splitmenu");
+}
+
+.splitmenu-menuitem {
+ -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem");
+ list-style-image: inherit;
+ -moz-image-region: inherit;
+}
+
+.splitmenu-menuitem[iconic="true"] {
+ -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
+}
+
+.splitmenu-menu > .menu-text,
+:-moz-any(.splitmenu-menu, .splitmenu-menuitem) > .menu-accel-container,
+#appmenu-editmenu > .menu-text,
+#appmenu-editmenu > .menu-accel-container {
+ display: none;
+}
+
+.menuitem-tooltip {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-tooltip");
+}
+
+.menuitem-iconic-tooltip,
+.menuitem-tooltip[type="checkbox"],
+.menuitem-tooltip[type="radio"] {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-iconic-tooltip");
+}
+
+%ifdef MENUBAR_CAN_AUTOHIDE
+%ifndef CAN_DRAW_IN_TITLEBAR
+#appmenu-toolbar-button > .toolbarbutton-text {
+ display: -moz-box;
+}
+%endif
+
+#appmenu_offlineModeRecovery:not([checked=true]) {
+ display: none;
+}
+%endif
+
+/* Hide menu elements intended for keyboard access support */
+#main-menubar[openedwithkey=false] .show-only-for-keyboard {
+ display: none;
+}
+
+/* ::::: location bar ::::: */
+#urlbar {
+ -moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
+}
+
+.ac-url-text:-moz-locale-dir(rtl),
+.ac-title:-moz-locale-dir(rtl) > description {
+ direction: ltr !important;
+}
+
+/* For results that are actions, their description text is shown instead of
+ the URL - this needs to follow the locale's direction, unlike URLs. */
+panel:not([noactions]) > richlistbox > richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
+ direction: rtl;
+}
+
+panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-action-text,
+panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-action-icon {
+ visibility: collapse;
+}
+
+panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .ac-url > .ac-url-text {
+ visibility: visible;
+}
+
+#urlbar:not([actiontype]) > #urlbar-display-box {
+ display: none;
+}
+
+#wrapper-urlbar-container > #urlbar-container > #urlbar {
+ -moz-user-input: disabled;
+ cursor: -moz-grab;
+}
+
+#PopupAutoComplete {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
+}
+
+#PopupAutoCompleteRichResult {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
+}
+
+#DateTimePickerPanel[active="true"] {
+ -moz-binding: url("chrome://global/content/bindings/datetimepopup.xml#datetime-popup");
+}
+
+/* Pale Moon: Address bar: Feeds */
+#ub-feed-button > .button-box > .box-inherit > .button-text,
+#ub-feed-button > .button-box > .button-menu-dropmarker {
+ display: none;
+}
+
+#ub-feed-menu > .feed-menuitem:-moz-locale-dir(rtl) {
+ direction: rtl;
+}
+
+
+#urlbar-container[combined] > #urlbar > #urlbar-icons > #go-button,
+#urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon:not(#go-button),
+#urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button,
+#urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
+#urlbar[pageproxystate="valid"] > #urlbar-go-button,
+#urlbar:not([focused="true"]) > #urlbar-go-button {
+ visibility: collapse;
+}
+
+#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels {
+ visibility: collapse;
+}
+
+#urlbar[pageproxystate="invalid"] > #identity-box {
+ pointer-events: none;
+}
+
+#identity-icon-labels {
+ max-width: 18em;
+}
+
+#identity-icon-country-label {
+ direction: ltr;
+}
+
+#identity-box.verifiedIdentity > #identity-icon-labels > #identity-icon-label {
+ -moz-margin-end: 0.25em !important;
+}
+
+#wrapper-search-container > #search-container > #searchbar > .searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input {
+ visibility: hidden;
+}
+
+/* Private Autocomplete */
+textbox[type="private-autocomplete"] {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#autocomplete");
+}
+
+panel[type="private-autocomplete"] {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#autocomplete-result-popup");
+}
+
+panel[type="private-autocomplete-richlistbox"] {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-rich-result-popup");
+}
+
+.private-autocomplete-tree {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-tree");
+ -moz-user-focus: ignore;
+}
+
+.private-autocomplete-treebody {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-treebody");
+}
+
+.private-autocomplete-richlistbox {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-richlistbox");
+ -moz-user-focus: ignore;
+}
+
+.private-autocomplete-richlistbox > scrollbox {
+ overflow-x: hidden !important;
+}
+
+.private-autocomplete-richlistitem {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-richlistitem");
+ -moz-box-orient: vertical;
+ overflow: -moz-hidden-unscrollable;
+}
+
+.private-autocomplete-treerows {
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-autocomplete-treerows");
+}
+
+.private-autocomplete-history-dropmarker {
+ display: none;
+}
+
+.private-autocomplete-history-dropmarker[enablehistory="true"] {
+ display: -moz-box;
+ -moz-binding: url("chrome://browser/content/autocomplete.xml#private-history-dropmarker");
+}
+
+.ac-ellipsis-after {
+ visibility: hidden;
+}
+
+.ac-url-text[type~="action"],
+.ac-action-text:not([type~="action"]) {
+ visibility: collapse;
+}
+
+
+/* ::::: Unified Back-/Forward Button ::::: */
+#back-button > .toolbarbutton-menu-dropmarker,
+#forward-button > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+.unified-nav-current {
+ font-weight: bold;
+}
+
+toolbarbutton.bookmark-item {
+ max-width: 13em;
+}
+
+%ifdef MENUBAR_CAN_AUTOHIDE
+#toolbar-menubar:not([autohide="true"]) ~ toolbar > #bookmarks-menu-button,
+#toolbar-menubar:not([autohide="true"]) > #bookmarks-menu-button,
+#toolbar-menubar:not([autohide="true"]) ~ toolbar > #history-menu-button,
+#toolbar-menubar:not([autohide="true"]) > #history-menu-button {
+ display: none;
+}
+%endif
+
+#editBMPanel_tagsSelector {
+ /* override default listbox width from xul.css */
+ width: auto;
+}
+
+menupopup[emptyplacesresult="true"] > .hide-if-empty-places-result {
+ display: none;
+}
+
+menuitem.spell-suggestion {
+ font-weight: bold;
+}
+
+#sidebar-header > .tabs-closebutton {
+ -moz-user-focus: normal;
+}
+
+/* apply Fitts' law to the notification bar's close button */
+window[sizemode="maximized"] #content .notification-inner {
+ border-right: 0px !important;
+}
+
+/* Hide extension toolbars that neglected to set the proper class */
+window[chromehidden~="location"][chromehidden~="toolbar"] toolbar:not(.chromeclass-menubar),
+window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(#nav-bar):not(#TabsToolbar):not(#print-preview-toolbar):not(.chromeclass-menubar) {
+ display: none;
+}
+
+#navigator-toolbox ,
+#status-bar ,
+#mainPopupSet {
+ min-width: 1px;
+}
+
+%ifdef MOZ_SERVICES_SYNC
+/* Sync notification UI */
+#sync-notifications {
+ -moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
+ overflow-y: visible !important;
+}
+
+#sync-notifications notification {
+ -moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
+}
+%endif
+
+/* History Swipe Animation */
+
+#historySwipeAnimationContainer {
+ overflow: hidden;
+}
+
+#historySwipeAnimationPreviousPage,
+#historySwipeAnimationCurrentPage,
+#historySwipeAnimationNextPage {
+ background: none top left no-repeat white;
+}
+
+#historySwipeAnimationPreviousPage {
+ background-image: -moz-element(#historySwipeAnimationPreviousPageSnapshot);
+}
+
+#historySwipeAnimationCurrentPage {
+ background-image: -moz-element(#historySwipeAnimationCurrentPageSnapshot);
+}
+
+#historySwipeAnimationNextPage {
+ background-image: -moz-element(#historySwipeAnimationNextPageSnapshot);
+}
+
+/* Identity UI */
+#identity-popup-content-box.unknownIdentity > #identity-popup-connectedToLabel ,
+#identity-popup-content-box.unknownIdentity > #identity-popup-runByLabel ,
+#identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
+#identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
+#identity-popup-content-box.verifiedIdentity > #identity-popup-connectedToLabel2 ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-connectedToLabel2 {
+ display: none;
+}
+
+/* Full Screen UI */
+
+#fullscr-toggler {
+ height: 1px;
+ background: black;
+}
+
+#full-screen-warning-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 2147483647 !important;
+ pointer-events: none;
+}
+
+#full-screen-warning-container[fade-warning-out] {
+ transition-property: opacity !important;
+ transition-duration: 500ms !important;
+ opacity: 0.0;
+}
+
+#full-screen-warning-message {
+ /* We must specify a max-width, otherwise word-wrap:break-word doesn't
+ work in descendant and elements. Bug 630864. */
+ max-width: 800px;
+}
+
+#full-screen-domain-text {
+ word-wrap: break-word;
+ /* We must specify a min-width, otherwise word-wrap:break-word doesn't work. Bug 630864. */
+ min-width: 1px;
+}
+
+#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-icon {
+ display: -moz-box;
+}
+
+#nav-bar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
+ display: none;
+}
+
+/* ::::: Keyboard UI Panel ::::: */
+.KUI-panel-closebutton {
+ -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
+}
+
+:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|img,
+:-moz-any(.ctrlTab-preview, .allTabs-preview) > html|canvas {
+ min-width: inherit;
+ max-width: inherit;
+ min-height: inherit;
+ max-height: inherit;
+}
+
+.ctrlTab-favicon-container,
+.allTabs-favicon-container {
+ -moz-box-align: start;
+%ifdef XP_MACOSX
+ -moz-box-pack: end;
+%else
+ -moz-box-pack: start;
+%endif
+}
+
+.ctrlTab-favicon,
+.allTabs-favicon {
+ width: 16px;
+ height: 16px;
+}
+
+/* ::::: Ctrl-Tab Panel ::::: */
+.ctrlTab-preview {
+ -moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-preview");
+}
+
+/* ::::: All Tabs Panel ::::: */
+.allTabs-preview {
+ -moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#allTabs-preview");
+}
+
+#allTabs-tab-close-button {
+ -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
+ margin: 0;
+}
+
+
+/* notification anchors should only be visible when their associated
+ notifications are */
+.notification-anchor-icon {
+ -moz-user-focus: normal;
+}
+
+.notification-anchor-icon:not([showing]) {
+ display: none;
+}
+
+/* This was added with the identity toolkit, does it have any other purpose? */
+#notification-popup .text-link.custom-link {
+ -moz-binding: url("chrome://global/content/bindings/text.xml#text-label");
+ text-decoration: none;
+}
+
+#invalid-form-popup > description {
+ max-width: 280px;
+}
+
+.popup-anchor {
+ /* should occupy space but not be visible */
+ opacity: 0;
+ pointer-events: none;
+ -moz-stack-sizing: ignore;
+}
+
+#addon-progress-notification {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification");
+}
+
+#click-to-play-plugins-notification {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
+}
+
+.plugin-popupnotification-centeritem {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
+}
+
+/* override hidden="true" for the status bar compatibility shim
+ in case it was persisted for the real status bar */
+#status-bar {
+ display: -moz-box;
+}
+
+/* Remove the resizer from the statusbar compatibility shim */
+#status-bar[hideresizer] > .statusbar-resizerpanel {
+ display: none;
+}
+
+browser[tabmodalPromptShowing] {
+ -moz-user-focus: none !important;
+}
+
+/* Status panel */
+
+statuspanel {
+ -moz-binding: url("chrome://browser/content/tabbrowser.xml#statuspanel");
+ position: fixed;
+ margin-top: -3em;
+ left: 0;
+ max-width: calc(100% - 5px);
+ pointer-events: none;
+}
+
+statuspanel:-moz-locale-dir(ltr)[mirror],
+statuspanel:-moz-locale-dir(rtl):not([mirror]) {
+ left: auto;
+ right: 0;
+}
+
+statuspanel[sizelimit] {
+ max-width: 50%;
+}
+
+statuspanel[type=status] {
+ min-width: 23em;
+}
+
+@media all and (max-width: 800px) {
+ statuspanel[type=status] {
+ min-width: 33%;
+ }
+}
+
+statuspanel[type=overLink] {
+ transition: opacity 120ms ease-out;
+ direction: ltr;
+}
+
+statuspanel[inactive] {
+ transition: none;
+ opacity: 0;
+}
+
+statuspanel[inactive][previoustype=overLink] {
+ transition: opacity 200ms ease-out;
+}
+
+.statuspanel-inner {
+ height: 3em;
+ width: 100%;
+ -moz-box-align: end;
+}
+
+/* highlighter */
+%include highlighter.css
+
+/* gcli */
+
+html|*#gcli-tooltip-frame,
+html|*#gcli-output-frame,
+#gcli-output,
+#gcli-tooltip {
+ overflow-x: hidden;
+}
+
+.gclitoolbar-input-node,
+.gclitoolbar-complete-node {
+ direction: ltr;
+}
+
+#developer-toolbar-toolbox-button[error-count] > .toolbarbutton-icon {
+ display: none;
+}
+
+#developer-toolbar-toolbox-button[error-count]:before {
+ content: attr(error-count);
+ display: -moz-box;
+ -moz-box-pack: center;
+}
+
+/* Responsive Mode */
+
+.browserContainer[responsivemode] {
+ overflow: auto;
+}
+
+.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) {
+ -moz-box-pack: end;
+}
+
+.browserStack[responsivemode] {
+ transition-duration: 200ms;
+ transition-timing-function: linear;
+}
+
+.browserStack[responsivemode] {
+ transition-property: min-width, max-width, min-height, max-height;
+}
+
+.browserStack[responsivemode][notransition] {
+ transition: none;
+}
+
+.toolbarbutton-badge[badge]:not([badge=""])::after {
+ content: attr(badge);
+}
+
+toolbarbutton[type="badged"] {
+ -moz-binding: url("chrome://browser/content/urlbarBindings.xml#toolbarbutton-badged");
+}
+
+/* Strict icon size for PMkit 'ui/button' */
+toolbarbutton[pmkit-button="true"] > .toolbarbutton-badge-stack > .toolbarbutton-icon {
+ width: 16px;
+ height: 16px;
+}
+
+/* Remove white bar at the bottom of the screen when watching HTML5 video in fullscreen */
+#main-window[inFullscreen] #global-notificationbox,
+#main-window[inFullscreen] #high-priority-global-notificationbox {
+ visibility: collapse;
+}
+
+#navigator-toolbox[fullscreenShouldAnimate] {
+ transition: 0.7s margin-top ease-out;
+ transition-delay: 0.8s;
+}
diff --git a/base/content/browser.js b/base/content/browser.js
new file mode 100644
index 0000000..7615bc9
--- /dev/null
+++ b/base/content/browser.js
@@ -0,0 +1,7440 @@
+# -*- Mode: javascript; 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/.
+
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource:///modules/RecentWindow.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+ "resource://gre/modules/Task.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
+ "resource:///modules/CharsetMenu.jsm");
+
+const nsIWebNavigation = Ci.nsIWebNavigation;
+const gToolbarInfoSeparators = ["|", "-"];
+
+var gLastBrowserCharset = null;
+var gPrevCharset = null;
+var gProxyFavIcon = null;
+var gLastValidURLStr = "";
+var gInPrintPreviewMode = false;
+var gContextMenu = null; // nsContextMenu instance
+var gMultiProcessBrowser = false;
+
+#ifndef XP_MACOSX
+var gEditUIVisible = true;
+#endif
+
+[
+ ["gBrowser", "content"],
+ ["gNavToolbox", "navigator-toolbox"],
+ ["gURLBar", "urlbar"],
+ ["gNavigatorBundle", "bundle_browser"]
+].forEach(function (elementGlobal) {
+ var [name, id] = elementGlobal;
+ window.__defineGetter__(name, function () {
+ var element = document.getElementById(id);
+ if (!element)
+ return null;
+ delete window[name];
+ return window[name] = element;
+ });
+ window.__defineSetter__(name, function (val) {
+ delete window[name];
+ return window[name] = val;
+ });
+});
+
+// Smart getter for the findbar. If you don't wish to force the creation of
+// the findbar, check gFindBarInitialized first.
+var gFindBarInitialized = false;
+XPCOMUtils.defineLazyGetter(window, "gFindBar", function() {
+ let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let findbar = document.createElementNS(XULNS, "findbar");
+ findbar.id = "FindToolbar";
+
+ let browserBottomBox = document.getElementById("browser-bottombox");
+ browserBottomBox.insertBefore(findbar, browserBottomBox.firstChild);
+
+ // Force a style flush to ensure that our binding is attached.
+ findbar.clientTop;
+ findbar.browser = gBrowser.mCurrentBrowser;
+ window.gFindBarInitialized = true;
+ return findbar;
+});
+
+XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
+ "resource://gre/modules/BrowserUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gPrefService", function() {
+ return Services.prefs;
+});
+
+this.__defineGetter__("AddonManager", function() {
+ let tmp = {};
+ Cu.import("resource://gre/modules/AddonManager.jsm", tmp);
+ return this.AddonManager = tmp.AddonManager;
+});
+this.__defineSetter__("AddonManager", function (val) {
+ delete this.AddonManager;
+ return this.AddonManager = val;
+});
+
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+ "resource://gre/modules/PluralForm.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
+ "resource:///modules/AboutHomeUtils.jsm");
+
+#ifdef MOZ_SERVICES_SYNC
+XPCOMUtils.defineLazyModuleGetter(this, "Weave",
+ "resource://services-sync/main.js");
+#endif
+
+XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
+ let tmp = {};
+ Cu.import("resource:///modules/PopupNotifications.jsm", tmp);
+ try {
+ return new tmp.PopupNotifications(gBrowser,
+ document.getElementById("notification-popup"),
+ document.getElementById("notification-popup-box"));
+ } catch (ex) {
+ Cu.reportError(ex);
+ return null;
+ }
+});
+
+XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
+ "resource://gre/modules/PageThumbs.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "gBrowserNewTabPreloader",
+ "resource:///modules/BrowserNewTabPreloader.jsm", "BrowserNewTabPreloader");
+
+XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
+ "resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "FormValidationHandler",
+ "resource:///modules/FormValidationHandler.jsm");
+
+var gInitialPages = [
+ "about:blank",
+ "about:newtab",
+ "about:home",
+ "about:privatebrowsing",
+ "about:sessionrestore",
+ "about:logopage"
+];
+
+#include browser-addons.js
+#include browser-feeds.js
+#include browser-fullScreen.js
+#include browser-fullZoom.js
+#include browser-places.js
+#include browser-plugins.js
+#include browser-tabPreviews.js
+#include browser-thumbnails.js
+#include browser-uacompat.js
+
+#ifdef MOZ_WEBRTC
+#include browser-webrtcUI.js
+#endif
+
+#include browser-gestureSupport.js
+
+#ifdef MOZ_SERVICES_SYNC
+#include browser-syncui.js
+#endif
+
+XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
+#ifdef XP_WIN
+ const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
+ if (WINTASKBAR_CONTRACTID in Cc &&
+ Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar).available) {
+ let AeroPeek = Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", {}).AeroPeek;
+ return {
+ onOpenWindow: function () {
+ AeroPeek.onOpenWindow(window);
+ },
+ onCloseWindow: function () {
+ AeroPeek.onCloseWindow(window);
+ }
+ };
+ }
+#endif
+ return null;
+});
+
+XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
+ let tmp = {};
+ Cu.import("resource:///modules/PageMenu.jsm", tmp);
+ return new tmp.PageMenu();
+});
+
+/**
+* We can avoid adding multiple load event listeners and save some time by adding
+* one listener that calls all real handlers.
+*/
+function pageShowEventHandlers(persisted) {
+ charsetLoadListener();
+ XULBrowserWindow.asyncUpdateUI();
+
+ // The PluginClickToPlay events are not fired when navigating using the
+ // BF cache. |persisted| is true when the page is loaded from the
+ // BF cache, so this code reshows the notification if necessary.
+ if (persisted)
+ gPluginHandler.reshowClickToPlayNotification();
+}
+
+function UpdateBackForwardCommands(aWebNavigation) {
+ var backBroadcaster = document.getElementById("Browser:Back");
+ var forwardBroadcaster = document.getElementById("Browser:Forward");
+
+ // Avoid setting attributes on broadcasters if the value hasn't changed!
+ // Remember, guys, setting attributes on elements is expensive! They
+ // get inherited into anonymous content, broadcast to other widgets, etc.!
+ // Don't do it if the value hasn't changed! - dwh
+
+ var backDisabled = backBroadcaster.hasAttribute("disabled");
+ var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
+ if (backDisabled == aWebNavigation.canGoBack) {
+ if (backDisabled)
+ backBroadcaster.removeAttribute("disabled");
+ else
+ backBroadcaster.setAttribute("disabled", true);
+ }
+
+ if (forwardDisabled == aWebNavigation.canGoForward) {
+ if (forwardDisabled)
+ forwardBroadcaster.removeAttribute("disabled");
+ else
+ forwardBroadcaster.setAttribute("disabled", true);
+ }
+}
+
+/**
+ * Click-and-Hold implementation for the Back and Forward buttons
+ * XXXmano: should this live in toolbarbutton.xml?
+ */
+function SetClickAndHoldHandlers() {
+ var timer;
+
+ function openMenu(aButton) {
+ cancelHold(aButton);
+ aButton.firstChild.hidden = false;
+ aButton.open = true;
+ }
+
+ function mousedownHandler(aEvent) {
+ if (aEvent.button != 0 ||
+ aEvent.currentTarget.open ||
+ aEvent.currentTarget.disabled)
+ return;
+
+ // Prevent the menupopup from opening immediately
+ aEvent.currentTarget.firstChild.hidden = true;
+
+ aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
+ aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
+ timer = setTimeout(openMenu, 500, aEvent.currentTarget);
+ }
+
+ function mouseoutHandler(aEvent) {
+ let buttonRect = aEvent.currentTarget.getBoundingClientRect();
+ if (aEvent.clientX >= buttonRect.left &&
+ aEvent.clientX <= buttonRect.right &&
+ aEvent.clientY >= buttonRect.bottom)
+ openMenu(aEvent.currentTarget);
+ else
+ cancelHold(aEvent.currentTarget);
+ }
+
+ function mouseupHandler(aEvent) {
+ cancelHold(aEvent.currentTarget);
+ }
+
+ function cancelHold(aButton) {
+ clearTimeout(timer);
+ aButton.removeEventListener("mouseout", mouseoutHandler, false);
+ aButton.removeEventListener("mouseup", mouseupHandler, false);
+ }
+
+ function clickHandler(aEvent) {
+ if (aEvent.button == 0 &&
+ aEvent.target == aEvent.currentTarget &&
+ !aEvent.currentTarget.open &&
+ !aEvent.currentTarget.disabled) {
+ let cmdEvent = document.createEvent("xulcommandevent");
+ cmdEvent.initCommandEvent("command", true, true, window, 0,
+ aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
+ aEvent.metaKey, null);
+ aEvent.currentTarget.dispatchEvent(cmdEvent);
+ }
+ }
+
+ function _addClickAndHoldListenersOnElement(aElm) {
+ aElm.addEventListener("mousedown", mousedownHandler, true);
+ aElm.addEventListener("click", clickHandler, true);
+ }
+
+ // Bug 414797: Clone unified-back-forward-button's context menu into both the
+ // back and the forward buttons.
+ var unifiedButton = document.getElementById("unified-back-forward-button");
+ if (unifiedButton && !unifiedButton._clickHandlersAttached) {
+ unifiedButton._clickHandlersAttached = true;
+
+ let popup = document.getElementById("backForwardMenu").cloneNode(true);
+ popup.removeAttribute("id");
+ // Prevent the context attribute on unified-back-forward-button from being
+ // inherited.
+ popup.setAttribute("context", "");
+
+ let backButton = document.getElementById("back-button");
+ backButton.setAttribute("type", "menu");
+ backButton.appendChild(popup);
+ _addClickAndHoldListenersOnElement(backButton);
+
+ let forwardButton = document.getElementById("forward-button");
+ popup = popup.cloneNode(true);
+ forwardButton.setAttribute("type", "menu");
+ forwardButton.appendChild(popup);
+ _addClickAndHoldListenersOnElement(forwardButton);
+ }
+}
+
+const gSessionHistoryObserver = {
+ observe: function(subject, topic, data)
+ {
+ if (topic != "browser:purge-session-history")
+ return;
+
+ var backCommand = document.getElementById("Browser:Back");
+ backCommand.setAttribute("disabled", "true");
+ var fwdCommand = document.getElementById("Browser:Forward");
+ fwdCommand.setAttribute("disabled", "true");
+
+ // Hide session restore button on about:home
+ window.messageManager.broadcastAsyncMessage("Browser:HideSessionRestoreButton");
+
+ if (gURLBar) {
+ // Clear undo history of the URL bar
+ gURLBar.editor.transactionManager.clear()
+ }
+ }
+};
+
+var gFindBarSettings = {
+ messageName: "Findbar:Keypress",
+ prefName: "accessibility.typeaheadfind",
+ findAsYouType: null,
+
+ init: function() {
+ window.messageManager.addMessageListener(this.messageName, this);
+
+ gPrefService.addObserver(this.prefName, this, false);
+ this.writeFindAsYouType();
+ },
+
+ uninit: function() {
+ window.messageManager.removeMessageListener(this.messageName, this);
+
+ try {
+ gPrefService.removeObserver(this.prefName, this);
+ } catch (ex) {
+ Cu.reportError(ex);
+ }
+ },
+
+ observe: function(aSubject, aTopic, aData) {
+ if (aTopic != "nsPref:changed") {
+ return;
+ }
+
+ this.writeFindAsYouType();
+ },
+
+ writeFindAsYouType: function() {
+ this.findAsYouType = gPrefService.getBoolPref(this.prefName);
+ },
+
+ receiveMessage: function(aMessage) {
+ switch (aMessage.name) {
+ case this.messageName:
+ // If the find bar for chrome window's context is not yet alive,
+ // only initialize it if there's a possibility FindAsYouType
+ // will be used.
+ // There's no point in doing it for most random keypresses.
+ if (!gFindBarInitialized && aMessage.data.shouldFastFind) {
+ let shouldFastFind = this.findAsYouType;
+ if (!shouldFastFind) {
+ // Please keep in sync with toolkit/content/widgets/findbar.xml
+ const FAYT_LINKS_KEY = "'";
+ const FAYT_TEXT_KEY = "/";
+ let charCode = aMessage.data.fakeEvent.charCode;
+ let key = charCode ? String.fromCharCode(charCode) : null;
+ shouldFastFind = key == FAYT_LINKS_KEY || key == FAYT_TEXT_KEY;
+ }
+ if (shouldFastFind) {
+ // Make sure we return the result.
+ return gFindBar.receiveMessage(aMessage);
+ }
+ }
+ break;
+ }
+ }
+};
+
+var gURLBarSettings = {
+ prefSuggest: "browser.urlbar.suggest.",
+ /*
+ For searching in the source code:
+ browser.urlbar.suggest.bookmark
+ browser.urlbar.suggest.history
+ browser.urlbar.suggest.openpage
+ */
+ prefSuggests: [
+ "bookmark",
+ "history",
+ "openpage"
+ ],
+ prefKeyword: "keyword.enabled",
+
+ observe: function(aSubject, aTopic, aData) {
+ if (aTopic != "nsPref:changed")
+ return;
+
+ this.writePlaceholder();
+ },
+
+ writePlaceholder: function() {
+ if (!gURLBar) {
+ return;
+ }
+
+ let attribute = "placeholder";
+ let prefs = this.prefSuggests.map(pref => {
+ return this.prefSuggest + pref;
+ });
+ prefs.push(this.prefKeyword);
+ let placeholderDefault = prefs.some(pref => {
+ return gPrefService.getBoolPref(pref);
+ });
+
+ if (placeholderDefault) {
+ gURLBar.setAttribute(
+ attribute, gNavigatorBundle.getString("urlbar.placeholder"));
+ } else {
+ gURLBar.setAttribute(
+ attribute, gNavigatorBundle.getString("urlbar.placeholderURLOnly"));
+ }
+ }
+};
+
+/**
+ * Given a starting docshell and a URI to look up, find the docshell the URI
+ * is loaded in.
+ * @param aDocument
+ * A document to find instead of using just a URI - this is more specific.
+ * @param aDocShell
+ * The doc shell to start at
+ * @param aSoughtURI
+ * The URI that we're looking for
+ * @returns The doc shell that the sought URI is loaded in. Can be in
+ * subframes.
+ */
+function findChildShell(aDocument, aDocShell, aSoughtURI) {
+ aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation);
+ aDocShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
+ var doc = aDocShell.getInterface(Components.interfaces.nsIDOMDocument);
+ if ((aDocument && doc == aDocument) ||
+ (aSoughtURI && aSoughtURI.spec == aDocShell.currentURI.spec))
+ return aDocShell;
+
+ var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeItem);
+ for (var i = 0; i < node.childCount; ++i) {
+ var docShell = node.getChildAt(i);
+ docShell = findChildShell(aDocument, docShell, aSoughtURI);
+ if (docShell)
+ return docShell;
+ }
+ return null;
+}
+
+var gPopupBlockerObserver = {
+ _reportButton: null,
+
+ onReportButtonClick: function (aEvent)
+ {
+ if (aEvent.button != 0 || aEvent.target != this._reportButton)
+ return;
+
+ document.getElementById("blockedPopupOptions")
+ .openPopup(this._reportButton, "after_end", 0, 2, false, false, aEvent);
+ },
+
+ handleEvent: function (aEvent)
+ {
+ if (aEvent.originalTarget != gBrowser.selectedBrowser)
+ return;
+
+ if (!this._reportButton && gURLBar)
+ this._reportButton = document.getElementById("page-report-button");
+
+ if (!gBrowser.selectedBrowser.blockedPopups ||
+ !gBrowser.selectedBrowser.blockedPopups.length) {
+ // Hide the icon in the location bar (if the location bar exists)
+ if (gURLBar)
+ this._reportButton.hidden = true;
+ return;
+ }
+
+ if (gURLBar)
+ this._reportButton.hidden = false;
+
+ // Only show the notification again if we've not already shown it. Since
+ // notifications are per-browser, we don't need to worry about re-adding
+ // it.
+ if (!gBrowser.selectedBrowser.blockedPopups.reported) {
+ if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
+ var brandBundle = document.getElementById("bundle_brand");
+ var brandShortName = brandBundle.getString("brandShortName");
+ var popupCount = gBrowser.selectedBrowser.blockedPopups.length;
+ var popupButtonText = gNavigatorBundle.getString("popupWarningButton");
+ var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey");
+ var messageBase = gNavigatorBundle.getString("popupWarning.message");
+ var message = PluralForm.get(popupCount, messageBase)
+ .replace("#1", brandShortName)
+ .replace("#2", popupCount);
+
+ var notificationBox = gBrowser.getNotificationBox();
+ var notification = notificationBox.getNotificationWithValue("popup-blocked");
+ if (notification) {
+ notification.label = message;
+ }
+ else {
+ var buttons = [{
+ label: popupButtonText,
+ accessKey: popupButtonAccesskey,
+ popup: "blockedPopupOptions",
+ callback: null
+ }];
+
+ const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
+ notificationBox.appendNotification(message, "popup-blocked",
+ "chrome://browser/skin/Info.png",
+ priority, buttons);
+ }
+ }
+
+ // Record the fact that we've reported this blocked popup, so we don't
+ // show it again.
+ gBrowser.selectedBrowser.blockedPopups.reported = true;
+ }
+ },
+
+ toggleAllowPopupsForSite: function (aEvent)
+ {
+ var pm = Services.perms;
+ var shouldBlock = aEvent.target.getAttribute("block") == "true";
+ var perm = shouldBlock ? pm.DENY_ACTION : pm.ALLOW_ACTION;
+ pm.add(gBrowser.currentURI, "popup", perm);
+
+ gBrowser.getNotificationBox().removeCurrentNotification();
+ },
+
+ fillPopupList: function (aEvent)
+ {
+ // XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
+ // we should really walk the blockedPopups and create a list of "allow for "
+ // menuitems for the common subset of hosts present in the report, this will
+ // make us frame-safe.
+ //
+ // XXXjst - Note that when this is fixed to work with multi-framed sites,
+ // also back out the fix for bug 343772 where
+ // nsGlobalWindow::CheckOpenAllow() was changed to also
+ // check if the top window's location is whitelisted.
+ let browser = gBrowser.selectedBrowser;
+ var uri = browser.currentURI;
+ var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite");
+ try {
+ blockedPopupAllowSite.removeAttribute("hidden");
+
+ var pm = Services.perms;
+ if (pm.testPermission(uri, "popup") == pm.ALLOW_ACTION) {
+ // Offer an item to block popups for this site, if a whitelist entry exists
+ // already for it.
+ let blockString = gNavigatorBundle.getFormattedString("popupBlock", [uri.host || uri.spec]);
+ blockedPopupAllowSite.setAttribute("label", blockString);
+ blockedPopupAllowSite.setAttribute("block", "true");
+ }
+ else {
+ // Offer an item to allow popups for this site
+ let allowString = gNavigatorBundle.getFormattedString("popupAllow", [uri.host || uri.spec]);
+ blockedPopupAllowSite.setAttribute("label", allowString);
+ blockedPopupAllowSite.removeAttribute("block");
+ }
+ }
+ catch (e) {
+ blockedPopupAllowSite.setAttribute("hidden", "true");
+ }
+
+ if (PrivateBrowsingUtils.isWindowPrivate(window))
+ blockedPopupAllowSite.setAttribute("disabled", "true");
+ else
+ blockedPopupAllowSite.removeAttribute("disabled");
+
+ let blockedPopupDontShowMessage = document.getElementById("blockedPopupDontShowMessage");
+ let showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
+ blockedPopupDontShowMessage.setAttribute("checked", !showMessage);
+ if (aEvent.target.anchorNode.id == "page-report-button") {
+ aEvent.target.anchorNode.setAttribute("open", "true");
+ blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromLocationbar"));
+ } else {
+ blockedPopupDontShowMessage.setAttribute("label", gNavigatorBundle.getString("popupWarningDontShowFromMessage"));
+ }
+
+ let blockedPopupsSeparator =
+ document.getElementById("blockedPopupsSeparator");
+ blockedPopupsSeparator.setAttribute("hidden", true);
+
+ gBrowser.selectedBrowser.retrieveListOfBlockedPopups().then(blockedPopups => {
+ let foundUsablePopupURI = false;
+ if (blockedPopups) {
+ for (let i = 0; i < blockedPopups.length; i++) {
+ let blockedPopup = blockedPopups[i];
+
+ // popupWindowURI will be null if the file picker popup is blocked.
+ // xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
+ if (!blockedPopup.popupWindowURIspec)
+ continue;
+
+ var popupURIspec = blockedPopup.popupWindowURIspec;
+
+ // Sometimes the popup URI that we get back from the blockedPopup
+ // isn't useful (for instance, netscape.com's popup URI ends up
+ // being "http://www.netscape.com", which isn't really the URI of
+ // the popup they're trying to show). This isn't going to be
+ // useful to the user, so we won't create a menu item for it.
+ if (popupURIspec == "" || popupURIspec == "about:blank" ||
+ popupURIspec == "" ||
+ popupURIspec == uri.spec)
+ continue;
+
+ // Because of the short-circuit above, we may end up in a situation
+ // in which we don't have any usable popup addresses to show in
+ // the menu, and therefore we shouldn't show the separator. However,
+ // since we got past the short-circuit, we must've found at least
+ // one usable popup URI and thus we'll turn on the separator later.
+ foundUsablePopupURI = true;
+
+ var menuitem = document.createElement("menuitem");
+ var label = gNavigatorBundle.getFormattedString("popupShowPopupPrefix",
+ [popupURIspec]);
+ menuitem.setAttribute("label", label);
+ menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);");
+ menuitem.setAttribute("popupReportIndex", i);
+ menuitem.popupReportBrowser = browser;
+ aEvent.target.appendChild(menuitem);
+ }
+ }
+
+ // Show the separator if we added any
+ // showable popup addresses to the menu.
+ if (foundUsablePopupURI)
+ blockedPopupsSeparator.removeAttribute("hidden");
+ }, null);
+ },
+
+ onPopupHiding: function (aEvent) {
+ if (aEvent.target.anchorNode.id == "page-report-button")
+ aEvent.target.anchorNode.removeAttribute("open");
+
+ let item = aEvent.target.lastChild;
+ while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
+ let next = item.previousSibling;
+ item.parentNode.removeChild(item);
+ item = next;
+ }
+ },
+
+ showBlockedPopup: function (aEvent)
+ {
+ var target = aEvent.target;
+ var popupReportIndex = target.getAttribute("popupReportIndex");
+ let browser = target.popupReportBrowser;
+ browser.unblockPopup(popupReportIndex);
+ },
+
+ editPopupSettings: function ()
+ {
+ var host = "";
+ try {
+ host = gBrowser.currentURI.host;
+ }
+ catch (e) { }
+
+ var bundlePreferences = document.getElementById("bundle_preferences");
+ var params = { blockVisible : false,
+ sessionVisible : false,
+ allowVisible : true,
+ prefilledHost : host,
+ permissionType : "popup",
+ windowTitle : bundlePreferences.getString("popuppermissionstitle"),
+ introText : bundlePreferences.getString("popuppermissionstext") };
+ var existingWindow = Services.wm.getMostRecentWindow("Browser:Permissions");
+ if (existingWindow) {
+ existingWindow.initWithParams(params);
+ existingWindow.focus();
+ }
+ else
+ window.openDialog("chrome://browser/content/preferences/permissions.xul",
+ "_blank", "resizable,dialog=no,centerscreen", params);
+ },
+
+ dontShowMessage: function ()
+ {
+ var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
+ gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage);
+ gBrowser.getNotificationBox().removeCurrentNotification();
+ }
+};
+
+const gXSSObserver = {
+
+ observe: function (aSubject, aTopic, aData)
+ {
+
+ // Don't do anything if the notification is disabled.
+ if (!gPrefService.getBoolPref("security.xssfilter.displayWarning"))
+ return;
+
+ // Parse incoming XSS array
+ aSubject.QueryInterface(Ci.nsIArray);
+ var policy = aSubject.queryElementAt(0, Ci.nsISupportsString).data;
+ var content = aSubject.queryElementAt(1, Ci.nsISupportsString).data;
+ var domain = aSubject.queryElementAt(2, Ci.nsISupportsString).data;
+ var url = aSubject.queryElementAt(3, Ci.nsISupportsCString).data;
+ var blockMode = aSubject.queryElementAt(4, Ci.nsISupportsPRBool).data;
+
+ // If it is a block mode event, do not display the infobar
+ if (blockMode)
+ return;
+
+ var nb = gBrowser.getNotificationBox();
+ const priority = nb.PRIORITY_WARNING_MEDIUM;
+
+ var buttons = [{
+ label: 'View Unsafe Content',
+ accessKey: 'V',
+ popup: null,
+ callback: function () {
+ alert(content);
+ }
+ }];
+
+ if (domain !== "")
+ buttons.push({
+ label: 'Add Domain Exception',
+ accessKey: 'A',
+ popup: null,
+ callback: function () {
+ let whitelist = gPrefService.getCharPref("security.xssfilter.whitelist");
+ if (whitelist != "") {
+ whitelist = whitelist + "," + domain;
+ } else {
+ whitelist = domain;
+ }
+ // Write the updated whitelist. Since this is observed by the XSS filter,
+ // it will automatically sync to the back-end and update immediately.
+ gPrefService.setCharPref("security.xssfilter.whitelist", whitelist);
+ // After setting this, we automatically reload the page.
+ BrowserReloadSkipCache();
+ }
+ });
+
+ nb.appendNotification("The XSS Filter has detected a potential XSS attack. Type: " +
+ policy, 'popup-blocked', 'chrome://browser/skin/Info.png',
+ priority, buttons);
+ }
+};
+
+var gBrowserInit = {
+ delayedStartupFinished: false,
+
+ onLoad: function() {
+ gMultiProcessBrowser = gPrefService.getBoolPref("browser.tabs.remote");
+
+ var mustLoadSidebar = false;
+
+ Cc["@mozilla.org/eventlistenerservice;1"]
+ .getService(Ci.nsIEventListenerService)
+ .addSystemEventListener(gBrowser, "click", contentAreaClick, true);
+
+ gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
+
+ // Note that the XBL binding is untrusted
+ gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true);
+ gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
+ gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
+ gBrowser.addEventListener("PluginInstantiated", gPluginHandler, true);
+ gBrowser.addEventListener("PluginRemoved", gPluginHandler, true);
+
+ Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
+
+ window.addEventListener("AppCommand", HandleAppCommandEvent, true);
+
+ // These routines add message listeners. They must run before
+ // loading the frame script to ensure that we don't miss any
+ // message sent between when the frame script is loaded and when
+ // the listener is registered.
+#ifdef MOZ_DEVTOOLS
+ DevToolsTheme.init();
+#endif
+ gFindBarSettings.init();
+
+ messageManager.loadFrameScript("chrome://browser/content/content.js", true);
+ messageManager.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
+
+ // initialize observers and listeners
+ // and give C++ access to gBrowser
+ XULBrowserWindow.init();
+ window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIXULWindow)
+ .XULBrowserWindow = window.XULBrowserWindow;
+ window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
+ new nsBrowserAccess();
+
+ // set default character set if provided
+ // window.arguments[1]: character set (string)
+ if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
+ if (window.arguments[1].startsWith("charset=")) {
+ var arrayArgComponents = window.arguments[1].split("=");
+ if (arrayArgComponents) {
+ //we should "inherit" the charset menu setting in a new window
+ //TFE FIXME: this is now a wrappednative and can't be set this way.
+ //getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
+ }
+ }
+ }
+
+ // Manually hook up session and global history for the first browser
+ // so that we don't have to load global history before bringing up a
+ // window.
+ // Wire up session and global history before any possible
+ // progress notifications for back/forward button updating
+ gBrowser.webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].
+ createInstance(Ci.nsISHistory);
+ Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
+
+ // remove the disablehistory attribute so the browser cleans up, as
+ // though it had done this work itself
+ gBrowser.browsers[0].removeAttribute("disablehistory");
+
+ // enable global history
+ try {
+ if (!gMultiProcessBrowser)
+ gBrowser.docShell.useGlobalHistory = true;
+ } catch(ex) {
+ Cu.reportError("Places database may be locked: " + ex);
+ }
+
+ // hook up UI through progress listener
+ gBrowser.addProgressListener(window.XULBrowserWindow);
+ gBrowser.addTabsProgressListener(window.TabsProgressListener);
+
+ // setup our common DOMLinkAdded listener
+ gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
+
+ // setup our MozApplicationManifest listener
+ gBrowser.addEventListener("MozApplicationManifest",
+ OfflineApps, false);
+
+ // setup simple gestures support
+ gGestureSupport.init(true);
+
+ // setup history swipe animation
+ gHistorySwipeAnimation.init();
+
+ if (window.opener && !window.opener.closed) {
+ let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
+ // If the opener had a sidebar, open the same sidebar in our window.
+ // The opener can be the hidden window too, if we're coming from the state
+ // where no windows are open, and the hidden window has no sidebar box.
+ if (openerSidebarBox && !openerSidebarBox.hidden) {
+ let sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
+ let sidebarCmdElem = document.getElementById(sidebarCmd);
+
+ // dynamically generated sidebars will fail this check.
+ if (sidebarCmdElem) {
+ let sidebarBox = document.getElementById("sidebar-box");
+ let sidebarTitle = document.getElementById("sidebar-title");
+
+ sidebarTitle.setAttribute(
+ "value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
+ sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
+
+ sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
+ // Note: we're setting 'src' on sidebarBox, which is a , not on
+ // the
+">
+
+
+This network may require you to login to access the internet.
+">
+
+
+
+
+
+ Web addresses are usually written like
+ http://www.example.com/
+ Make sure that you’re using forward slashes (i.e.
+ / ).
+
+">
+
+
+
+
+
+The requested document is not available in &brandShortName;’s cache.As a security precaution, &brandShortName; does not automatically re-request sensitive documents. Click Try Again to re-request the document from the website. ">
+
+
+
+ Press "Try Again" to switch to online mode and reload the page.
+
+">
+
+
+
+ Please contact the website owners to inform them of this problem.
+
+">
+
+
+
+ Please contact the website owners to inform them of this problem.
+
+">
+
+
+
+
+
+
+
+
+
+ You might need to install other software to open this address.
+
+">
+
+
+
+ Check the proxy settings to make sure that they are correct.
+ Contact your network administrator to make sure the proxy server is
+ working.
+
+">
+
+
+
+ Check the proxy settings to make sure that they are correct.
+ Check to make sure your computer has a working network connection.
+ If your computer or network is protected by a firewall or proxy, make sure
+ that &brandShortName; is permitted to access the Web.
+
+">
+
+
+
+ This problem can sometimes be caused by disabling or refusing to accept
+ cookies.
+
+">
+
+
+
+ Check to make sure your system has the Personal Security Manager
+ installed.
+ This might be due to a non-standard configuration on the server.
+
+">
+
+
+
+ The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
+ Please contact the website owners to inform them of this problem.
+
+">
+
+
+
+ This could be a problem with the server's configuration, or it could be
+someone trying to impersonate the server.
+ If you have connected to this server successfully in the past, the error may
+be temporary, and you can try again later.
+
+">
+
+
+ has configured their website improperly. To protect your information from being stolen, &brandShortName; has not connected to this website.">
+
+
+ The site could be temporarily unavailable or too busy. Try again in a few
+ moments.
+ If you are unable to load any pages, check your computer’s network
+ connection.
+ If your computer or network is protected by a firewall or proxy, make sure
+ that &brandShortName; is permitted to access the Web.
+
+">
+
+
+&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.">
+
+
+
+ &brandShortName; blocked further actions on this page, because it contains
+ injected JavaScript code.
+ Loading of this page has been suspended because of either the explicit request
+ by the website to block this page in case of XSS attacks, or because &brandShortName;
+ has been configured to block pages in that situation.
+
+">
+
+
+The page you are trying to view cannot be shown because an error in the data transmission was detected.Please contact the website owners to inform them of this problem. ">
+
+The page you are trying to view cannot be shown because an error in the data transmission was detected.Please contact the website owners to inform them of this problem. ">
+
+
+
+
+
+
+
+
+You should not add an exception if you are using an internet connection that you do not trust completely or if you are not used to seeing a warning for this server.
+
+&securityOverride.getMeOutOfHereButton;
+&securityOverride.exceptionButtonLabel;
+">
+
+
+Please contact the website owners to inform them of this problem. ">
+
+
+
+
+
+
+
+
+
+
+
+
+ uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe.">
+ using outdated security">
+
+
+A secure connection to isn’t possible because your clock appears to show the wrong time. Your computer thinks it is . To fix this problem, change your date and time settings to match the correct time.
">
+
+
+
+
+
+
+
+ uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe. The website administrator will need to fix the server first before you can visit the site.Error code: NS_ERROR_NET_INADEQUATE_SECURITY
">
+
+
+
diff --git a/locales/en-US/chrome/overrides/settingsChange.dtd b/locales/en-US/chrome/overrides/settingsChange.dtd
new file mode 100644
index 0000000..efbdf4e
--- /dev/null
+++ b/locales/en-US/chrome/overrides/settingsChange.dtd
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/locales/en-US/crashreporter/crashreporter-override.ini b/locales/en-US/crashreporter/crashreporter-override.ini
new file mode 100644
index 0000000..3345d76
--- /dev/null
+++ b/locales/en-US/crashreporter/crashreporter-override.ini
@@ -0,0 +1,9 @@
+; 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 file is in the UTF-8 encoding
+[Strings]
+# LOCALIZATION NOTE (CrashReporterProductErrorText2): The %s is replaced with a string containing detailed information.
+CrashReporterProductErrorText2=Firefox had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
+CrashReporterDescriptionText2=Firefox had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
diff --git a/locales/en-US/defines.inc b/locales/en-US/defines.inc
new file mode 100644
index 0000000..539b809
--- /dev/null
+++ b/locales/en-US/defines.inc
@@ -0,0 +1,12 @@
+# 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/.
+#filter emptyLines
+
+#define MOZ_LANGPACK_CREATOR palemoon.org
+
+# If non-English locales wish to credit multiple contributors, uncomment this
+# variable definition and use the format specified.
+# #define MOZ_LANGPACK_CONTRIBUTORS Joe Solon Suzy Solon
+
+#unfilter emptyLines
diff --git a/locales/en-US/installer/custom.properties b/locales/en-US/installer/custom.properties
new file mode 100644
index 0000000..8f95a19
--- /dev/null
+++ b/locales/en-US/installer/custom.properties
@@ -0,0 +1,85 @@
+# 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/.
+
+# LOCALIZATION NOTE:
+
+# This file must be saved as UTF8
+
+# Accesskeys are defined by prefixing the letter that is to be used for the
+# accesskey with an ampersand (e.g. &).
+
+# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
+# custom string and always use the same one as used by the en-US files.
+# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
+# for double ampersand) and prevents the letter following the ampersand from
+# being used as an accesskey.
+
+# You can use \n to create a newline in the string but only when the string
+# from en-US contains a \n.
+
+REG_APP_DESC=$BrandShortName delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web.
+CONTEXT_OPTIONS=$BrandShortName &Options
+CONTEXT_SAFE_MODE=$BrandShortName &Safe Mode
+OPTIONS_PAGE_TITLE=Setup Type
+OPTIONS_PAGE_SUBTITLE=Choose setup options
+SHORTCUTS_PAGE_TITLE=Set Up Shortcuts
+SHORTCUTS_PAGE_SUBTITLE=Create Program Icons
+COMPONENTS_PAGE_TITLE=Set Up Optional Components
+COMPONENTS_PAGE_SUBTITLE=Optional Recommended Components
+SUMMARY_PAGE_TITLE=Summary
+SUMMARY_PAGE_SUBTITLE=Ready to start installing $BrandShortName
+SUMMARY_INSTALLED_TO=$BrandShortName will be installed to the following location:
+SUMMARY_REBOOT_REQUIRED_INSTALL=A restart of your computer may be required to complete the installation.
+SUMMARY_REBOOT_REQUIRED_UNINSTALL=A restart of your computer may be required to complete the uninstall.
+SUMMARY_TAKE_DEFAULTS=U&se $BrandShortName as my default web browser
+SUMMARY_INSTALL_CLICK=Click Install to continue.
+SUMMARY_UPGRADE_CLICK=Click Upgrade to continue.
+SURVEY_TEXT=&Tell us what you thought of $BrandShortName
+LAUNCH_TEXT=&Launch $BrandShortName now
+CREATE_ICONS_DESC=Create icons for $BrandShortName:
+ICONS_DESKTOP=On my &Desktop
+ICONS_STARTMENU=In my &Start Menu Programs folder
+ICONS_QUICKLAUNCH=In my &Quick Launch bar
+WARN_MANUALLY_CLOSE_APP_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nPlease close $BrandShortName to continue.
+WARN_MANUALLY_CLOSE_APP_UNINSTALL=$BrandShortName must be closed to proceed with the uninstall.\n\nPlease close $BrandShortName to continue.
+WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
+WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory.
+WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
+WARN_MIN_SUPPORTED_OSVER_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer.
+WARN_MIN_SUPPORTED_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires a processor with ${MinSupportedCPU} support.
+WARN_MIN_SUPPORTED_OSVER_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer and a processor with ${MinSupportedCPU} support.
+WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of $BrandShortName. Do you want to reboot now?
+WARN_RESTART_REQUIRED_UPGRADE=Your computer must be restarted to complete a previous upgrade of $BrandShortName. Do you want to reboot now?
+ERROR_CREATE_DIRECTORY_PREFIX=Error creating directory:
+ERROR_CREATE_DIRECTORY_SUFFIX=Click Cancel to stop the installation or\nRetry to try again.
+
+UN_CONFIRM_PAGE_TITLE=Uninstall $BrandFullName
+UN_CONFIRM_PAGE_SUBTITLE=Remove $BrandFullName from your computer.
+UN_CONFIRM_UNINSTALLED_FROM=$BrandShortName will be uninstalled from the following location:
+UN_CONFIRM_CLICK=Click Uninstall to continue.
+UN_REMOVE_PROFILES=&Remove my $BrandShortName personal data and customizations
+UN_REMOVE_PROFILES_DESC=This will permanently remove your bookmarks, saved passwords, cookies and customizations. You may wish to keep this information if you plan on installing another version of $BrandShortName in the future.
+
+BANNER_CHECK_EXISTING=Checking existing installation…
+
+STATUS_INSTALL_APP=Installing $BrandShortName…
+STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})…
+STATUS_UNINSTALL_MAIN=Uninstalling $BrandShortName…
+STATUS_CLEANUP=A Little Housekeeping…
+
+# _DESC strings support approximately 65 characters per line.
+# One line
+OPTIONS_SUMMARY=Choose the type of setup you prefer, then click Next.
+# One line
+OPTION_STANDARD_DESC=$BrandShortName will be installed with the most common options.
+OPTION_STANDARD_RADIO=&Standard
+# Two lines
+OPTION_CUSTOM_DESC=You may choose individual options to be installed. Recommended for experienced users.
+OPTION_CUSTOM_RADIO=&Custom
+
+# LOCALIZATION NOTE:
+# The following text replaces the Install button text on the summary page.
+# Verify that the access key for InstallBtn (in override.properties) and
+# UPGRADE_BUTTON is not already used by SUMMARY_TAKE_DEFAULTS.
+UPGRADE_BUTTON=&Upgrade
diff --git a/locales/en-US/installer/mui.properties b/locales/en-US/installer/mui.properties
new file mode 100644
index 0000000..c786dbb
--- /dev/null
+++ b/locales/en-US/installer/mui.properties
@@ -0,0 +1,61 @@
+# 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/.
+
+# To make the l10n tinderboxen see changes to this file you can change a value
+# name by adding - to the end of the name followed by chars (e.g. Branding-2).
+
+# LOCALIZATION NOTE:
+
+# This file must be saved as UTF8
+
+# Accesskeys are defined by prefixing the letter that is to be used for the
+# accesskey with an ampersand (e.g. &).
+
+# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
+# custom string and always use the same one as used by the en-US files.
+# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
+# for double ampersand) and prevents the letter following the ampersand from
+# being used as an accesskey.
+
+# You can use \n to create a newline in the string but only when the string
+# from en-US contains a \n.
+
+MUI_TEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Setup Wizard
+MUI_TEXT_WELCOME_INFO_TEXT=This wizard will guide you through the installation of $BrandFullNameDA.\n\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\n$_CLICK
+MUI_TEXT_COMPONENTS_TITLE=Choose Components
+MUI_TEXT_COMPONENTS_SUBTITLE=Choose which features of $BrandFullNameDA you want to install.
+MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE=Description
+MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO=Position your mouse over a component to see its description.
+MUI_TEXT_DIRECTORY_TITLE=Choose Install Location
+MUI_TEXT_DIRECTORY_SUBTITLE=Choose the folder in which to install $BrandFullNameDA.
+MUI_TEXT_INSTALLING_TITLE=Installing
+MUI_TEXT_INSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being installed.
+MUI_TEXT_FINISH_TITLE=Installation Complete
+MUI_TEXT_FINISH_SUBTITLE=Setup was completed successfully.
+MUI_TEXT_ABORT_TITLE=Installation Aborted
+MUI_TEXT_ABORT_SUBTITLE=Setup was not completed successfully.
+MUI_BUTTONTEXT_FINISH=&Finish
+MUI_TEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Setup Wizard
+MUI_TEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been installed on your computer.\n\nClick Finish to close this wizard.
+MUI_TEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the installation of $BrandFullNameDA. Do you want to reboot now?
+MUI_TEXT_FINISH_REBOOTNOW=Reboot now
+MUI_TEXT_FINISH_REBOOTLATER=I want to manually reboot later
+MUI_TEXT_STARTMENU_TITLE=Choose Start Menu Folder
+MUI_TEXT_STARTMENU_SUBTITLE=Choose a Start Menu folder for the $BrandFullNameDA shortcuts.
+MUI_INNERTEXT_STARTMENU_TOP=Select the Start Menu folder in which you would like to create the program's shortcuts. You can also enter a name to create a new folder.
+MUI_TEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Setup?
+MUI_UNTEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Uninstall Wizard
+MUI_UNTEXT_WELCOME_INFO_TEXT=This wizard will guide you through the uninstallation of $BrandFullNameDA.\n\nBefore starting the uninstallation, make sure $BrandFullNameDA is not running.\n\n$_CLICK
+MUI_UNTEXT_CONFIRM_TITLE=Uninstall $BrandFullNameDA
+MUI_UNTEXT_CONFIRM_SUBTITLE=Remove $BrandFullNameDA from your computer.
+MUI_UNTEXT_UNINSTALLING_TITLE=Uninstalling
+MUI_UNTEXT_UNINSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being uninstalled.
+MUI_UNTEXT_FINISH_TITLE=Uninstallation Complete
+MUI_UNTEXT_FINISH_SUBTITLE=Uninstall was completed successfully.
+MUI_UNTEXT_ABORT_TITLE=Uninstallation Aborted
+MUI_UNTEXT_ABORT_SUBTITLE=Uninstall was not completed successfully.
+MUI_UNTEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Uninstall Wizard
+MUI_UNTEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been uninstalled from your computer.\n\nClick Finish to close this wizard.
+MUI_UNTEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the uninstallation of $BrandFullNameDA. Do you want to reboot now?
+MUI_UNTEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Uninstall?
diff --git a/locales/en-US/installer/override.properties b/locales/en-US/installer/override.properties
new file mode 100644
index 0000000..288f674
--- /dev/null
+++ b/locales/en-US/installer/override.properties
@@ -0,0 +1,86 @@
+# 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/.
+
+# LOCALIZATION NOTE:
+
+# This file must be saved as UTF8
+
+# Accesskeys are defined by prefixing the letter that is to be used for the
+# accesskey with an ampersand (e.g. &).
+
+# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
+# custom string and always use the same one as used by the en-US files.
+# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
+# for double ampersand) and prevents the letter following the ampersand from
+# being used as an accesskey.
+
+# You can use \n to create a newline in the string but only when the string
+# from en-US contains a \n.
+
+# Strings that require a space at the end should be enclosed with double
+# quotes and the double quotes will be removed. To add quotes to the beginning
+# and end of a strong enclose the add and additional double quote to the
+# beginning and end of the string (e.g. ""This will include quotes"").
+
+SetupCaption=$BrandFullName Setup
+UninstallCaption=$BrandFullName Uninstall
+BackBtn=< &Back
+NextBtn=&Next >
+AcceptBtn=I &accept the terms in the License Agreement
+DontAcceptBtn=I &do not accept the terms in the License Agreement
+InstallBtn=&Install
+UninstallBtn=&Uninstall
+CancelBtn=Cancel
+CloseBtn=&Close
+BrowseBtn=B&rowse…
+ShowDetailsBtn=Show &details
+ClickNext=Click Next to continue.
+ClickInstall=Click Install to start the installation.
+ClickUninstall=Click Uninstall to start the uninstallation.
+Completed=Completed
+LicenseTextRB=Please review the license agreement before installing $BrandFullNameDA. If you accept all terms of the agreement, select the first option below. $_CLICK
+ComponentsText=Check the components you want to install and uncheck the components you don't want to install. $_CLICK
+ComponentsSubText2_NoInstTypes=Select components to install:
+DirText=Setup will install $BrandFullNameDA in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK
+DirSubText=Destination Folder
+DirBrowseText=Select the folder to install $BrandFullNameDA in:
+SpaceAvailable="Space available: "
+SpaceRequired="Space required: "
+UninstallingText=$BrandFullNameDA will be uninstalled from the following folder. $_CLICK
+UninstallingSubText=Uninstalling from:
+FileError=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file.
+FileError_NoIgnore=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation.
+CantWrite="Can't write: "
+CopyFailed=Copy failed
+CopyTo="Copy to "
+Registering="Registering: "
+Unregistering="Unregistering: "
+SymbolNotFound="Could not find symbol: "
+CouldNotLoad="Could not load: "
+CreateFolder="Create folder: "
+CreateShortcut="Create shortcut: "
+CreatedUninstaller="Created uninstaller: "
+Delete="Delete file: "
+DeleteOnReboot="Delete on reboot: "
+ErrorCreatingShortcut="Error creating shortcut: "
+ErrorCreating="Error creating: "
+ErrorDecompressing=Error decompressing data! Corrupted installer?
+ErrorRegistering=Error registering DLL
+ExecShell="ExecShell: "
+Exec="Execute: "
+Extract="Extract: "
+ErrorWriting="Extract: error writing to file "
+InvalidOpcode=Installer corrupted: invalid opcode
+NoOLE="No OLE for: "
+OutputFolder="Output folder: "
+RemoveFolder="Remove folder: "
+RenameOnReboot="Rename on reboot: "
+Rename="Rename: "
+Skipped="Skipped: "
+CopyDetails=Copy Details To Clipboard
+LogInstall=Log install process
+Byte=B
+Kilo=K
+Mega=M
+Giga=G
diff --git a/locales/en-US/palemoon-l10n.js b/locales/en-US/palemoon-l10n.js
new file mode 100644
index 0000000..642ad65
--- /dev/null
+++ b/locales/en-US/palemoon-l10n.js
@@ -0,0 +1,7 @@
+# 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/.
+
+#filter substitution
+
+pref("general.useragent.locale", "@AB_CD@");
diff --git a/locales/en-US/profile/bookmarks.inc b/locales/en-US/profile/bookmarks.inc
new file mode 100644
index 0000000..d2a701e
--- /dev/null
+++ b/locales/en-US/profile/bookmarks.inc
@@ -0,0 +1,40 @@
+# 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/.
+#filter emptyLines
+
+# LOCALIZATION NOTE: The 'en-US' strings in the URLs will be replaced with
+# your locale code, and link to your translated pages as soon as they're
+# live.
+
+#define bookmarks_title Bookmarks
+#define bookmarks_heading Bookmarks
+
+#define bookmarks_toolbarfolder Bookmarks Toolbar Folder
+#define bookmarks_toolbarfolder_description Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
+
+# LOCALIZATION NOTE (getting_started):
+# link title for https://www.mozilla.org/en-US/firefox/central/
+#define getting_started Getting Started
+
+# LOCALIZATION NOTE (firefox_heading):
+# Firefox links folder name
+#define firefox_heading Mozilla Firefox
+
+# LOCALIZATION NOTE (firefox_help):
+# link title for https://www.mozilla.org/en-US/firefox/help/
+#define firefox_help Help and Tutorials
+
+# LOCALIZATION NOTE (firefox_customize):
+# link title for https://www.mozilla.org/en-US/firefox/customize/
+#define firefox_customize Customize Firefox
+
+# LOCALIZATION NOTE (firefox_community):
+# link title for https://www.mozilla.org/en-US/contribute/
+#define firefox_community Get Involved
+
+# LOCALIZATION NOTE (firefox_about):
+# link title for https://www.mozilla.org/en-US/about/
+#define firefox_about About Us
+
+#unfilter emptyLines
diff --git a/locales/en-US/profile/chrome/userChrome-example.css b/locales/en-US/profile/chrome/userChrome-example.css
new file mode 100644
index 0000000..2495795
--- /dev/null
+++ b/locales/en-US/profile/chrome/userChrome-example.css
@@ -0,0 +1,50 @@
+/* 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/. */
+
+/*
+ * Edit this file and copy it as userChrome.css into your
+ * profile-directory/chrome/
+ */
+
+/*
+ * This file can be used to customize the look of Mozilla's user interface
+ * You should consider using !important on rules which you want to
+ * override default settings.
+ */
+
+/*
+ * Do not remove the @namespace line -- it's required for correct functioning
+ */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */
+
+
+/*
+ * Some possible accessibility enhancements:
+ */
+/*
+ * Make all the default font sizes 20 pt:
+ *
+ * * {
+ * font-size: 20pt !important
+ * }
+ */
+/*
+ * Make menu items in particular 15 pt instead of the default size:
+ *
+ * menupopup > * {
+ * font-size: 15pt !important
+ * }
+ */
+/*
+ * Give the Location (URL) Bar a fixed-width font
+ *
+ * #urlbar {
+ * font-family: monospace !important;
+ * }
+ */
+
+/*
+ * For more examples see http://www.mozilla.org/unix/customizing.html
+ */
+
diff --git a/locales/en-US/profile/chrome/userContent-example.css b/locales/en-US/profile/chrome/userContent-example.css
new file mode 100644
index 0000000..a90694d
--- /dev/null
+++ b/locales/en-US/profile/chrome/userContent-example.css
@@ -0,0 +1,32 @@
+/* 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/. */
+
+/*
+ * Edit this file and copy it as userContent.css into your
+ * profile-directory/chrome/
+ */
+
+/*
+ * This file can be used to apply a style to all web pages you view
+ * Rules without !important are overruled by author rules if the
+ * author sets any. Rules with !important overrule author rules.
+ */
+
+/*
+ * example: give all tables a 2px border
+ *
+ * table { border: 2px solid; }
+ */
+
+/*
+ * example: turn off "marquee" element
+ *
+ * marquee { -moz-binding: none; }
+ *
+ */
+
+/*
+ * For more examples see http://www.mozilla.org/unix/customizing.html
+ */
+
diff --git a/locales/en-US/searchplugins/amazondotcom.xml b/locales/en-US/searchplugins/amazondotcom.xml
new file mode 100644
index 0000000..56362e8
--- /dev/null
+++ b/locales/en-US/searchplugins/amazondotcom.xml
@@ -0,0 +1,15 @@
+
+
+
+Amazon.com
+Amazon.com Search
+ISO-8859-1
+data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==
+
+
+
+
+http://www.amazon.com/
+
diff --git a/locales/en-US/searchplugins/answers.xml b/locales/en-US/searchplugins/answers.xml
new file mode 100644
index 0000000..b219e61
--- /dev/null
+++ b/locales/en-US/searchplugins/answers.xml
@@ -0,0 +1,16 @@
+
+
+
+Answers.com
+Dictionary Search on Answers.com
+UTF-8
+data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////K////4f////E////5f///+n////P////mv///0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////fv///+//////////////////////7NnP/+LFtv/////+////of///xYAAAAAAAAAAAAAAAD///8D////lf////////////j0//bi1v/OlXf/tGU9/6FCEv/OmH3////////////////D////FgAAAAAAAAAA////avPm4P/evaz/8NbI//7r3//23M3/xYRi/5kzAP/Df1z//u/l//749P/v4dn/+PPw/////6j///8B////GP///+W/f1//smM7//bczf/+69///uvf/9ytlP+ZMwD/5se3/+/f1//AgmP/nj0N/927qv/////+////QP///2z/////8NvQ/8WCYP/+69///uvf//7r3/+7ckz/pUkb/9m1ov+ePQ3/okUW/8+fh//38O3//////////5r///+t//////7y6v/Cflv/58Cr//DRwP/mwKv/okQU/8ODYv/cuqj/yZN4//Tq5f/+9e///vDn///////////Q////yf/////+7+b/05yA/65ZLv+9dVD/sF40/5kzAP/kvKb//vTu//Tr5v/7+Pb//vfz//707f//////////6f///8X//////vDm/+K4ov/KjGz//ure/8uNbf+jRBX/+OTX/+3b0v+jSBr/pk0h/717Wv/Wrpr//Pn4/////+b///+i//////7z7f/02Mj/wn5b//vl2P+uWS7/vXhU//v49//48u//1q6a/717Wv+oUSb/tWxH//jz8P/////K////V///////+/j//ure/8aFZP/fs5v/oEAQ/9q1o/+zaEL/1ayX//718P/+9/P/+PHu//jz8P//////////h////wr////O///////38v/YpYr/tGQ7/6ZLHf/06eX/s2dB/549Df/x49z//vDn//7x6f//////////8////yoAAAAA////R/////v/////7dXI/5kzAP+7cUv//vHp/+vYzv+bNwX/vHlY//38/P///////////////30AAAAAAAAAAAAAAAD///9n////+/z5+P++e1n/3LGc//7w5//++PT/0KKL/8OIa//9/Pv//////////5X///8GAAAAAAAAAAAAAAAAAAAAAP///0n////K///////////////////////////+/v7/////5v///2z///8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Cv///1f///+g////xP///8n///+r////bP///xoAAAAAAAAAAAAAAAAAAAAA+B////AH///AA///wAH//4AB//+AAP//AAD//wAA//8AAP//AAD//4AA//+AAf//wAP//+AD///wD////D///w==
+
+
+
+
+http://www.answers.com/
+
diff --git a/locales/en-US/searchplugins/bing.xml b/locales/en-US/searchplugins/bing.xml
new file mode 100644
index 0000000..22019ce
--- /dev/null
+++ b/locales/en-US/searchplugins/bing.xml
@@ -0,0 +1,18 @@
+
+
+
+ Bing
+ Bing. Search by Microsoft.
+ UTF-8
+ data:image/x-icon;base64,AAABAAIAEBAAAAEACADaCwAAJgAAACAgAAABAAgAlAIAAAAMAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIAgAAAJCRaDYAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABBUlEQVR42mL8v4OBJMAEZ/0nTgMLnLXtitKRO9JmCi9cNR/wsP8mrOHfP8YbL4RvvBBWFXuvI/WGsJMYSHUSMujbY8LN/ttM4bmO1BtW5n+ENdipPmndbrHjqiIn6x9DuZc2yk8tlZ7hc5Kx/AtzxecMDAzff7Mcuys9/7gOAT8wMjAUOZ9x0XhI2A98HL+Eub/vuSG/8ozGmy+cEEF+zp/YNYjxfvPTv9O63fLpBx6ICCvz32DD24EGt7Fo4Gb/zcX2Z84RPbiIqfyLZJtL4rzfsDvJUf3R91+sC09o//7LJMn/NdXmkqHsSyzeQ0t8j9/znn8s7ql9Dy34cWogIbUSCQADAJ+jWQrH9LCsAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAACW0lEQVR4nGP8v5OBpoCJtsbTwQIWTKGUxe5mCi9M5V/oSL9mZf5HoQWMmHEQOD0AwuBg/WMo+8pB/ZGZwguyLcDiAzj48Zvl+D2pTz/YKLGAcBxcfSZCtulEWUAhGDQW3HstcOOF8P//jKRagC+SkQE/58/0pa7c7L9N5V+aKTw3kH3FxvKXmhYI83y3VXl64Jbs3htye2/IsbH8NZB9Zabw3FT+JR/nTypYwMDAEGBw+8AtWQj71x/mU/clT92XZGT8ry7+zlzxhbnic0n+LxRZIC/8yUju5blH4siC//8z3nghfOOF8MLj2jKCnydH7EXTRVoqCjC4g0f2yXteTEHSLNCVft0WcNhM4QXxiYmEIIIATcm3mpJvn37gmX7Q8OozYYLqycloTz/wLDulRYzpDMT4QFf6NZz95gvnyjMa+27I/SM6xxGwQJj7R6rtJQYGhk8/2NaeU9t+RfH3X2ZcihWEP5Fmgazg53qfY9zsv1ed0dh4UeXbL5yKudl/R5tdd9O6T4IFGhJvyz1OHbkts/qc2qfv7LiUMTIwOGk8irW4yo8jP2O3wEzxubHcy7I1Dq+/cOIymoGBQVn0Q5rtRTXx93jUYLFAX+b1sw88p+5L4tHGy/Er2uy6m9YDRsb/eJRht8BS+emCY7q4NDAyMLhpPYixuMbD/gu/0VD1WBtezz7w9O81vvNKEE1cTfxdmu0lZdEPxBiNzwIGBoa//xhXndFYfU4NUsnwcf6Ms7jmpPGQ1BoHpwUQcOOF0OT9RoayryJNr3Oz/ybRcCIsoBwMmkp/8FoAADmgy6ulKggYAAAAAElFTkSuQmCC
+
+
+
+
+
+
+
+ https://www.bing.com/search
+
diff --git a/locales/en-US/searchplugins/creativecommons.xml b/locales/en-US/searchplugins/creativecommons.xml
new file mode 100644
index 0000000..d9ac67e
--- /dev/null
+++ b/locales/en-US/searchplugins/creativecommons.xml
@@ -0,0 +1,14 @@
+
+
+
+Creative Commons
+Find photos, movies, music, and text to rip, sample, mash, and share.
+utf-8
+data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJUSURBVDiNjZO9S1thGMXPvTfJFbnkipNkLLS0ksFg0M0lf4CboNCEgIIg/RiKtEOn0qGWTtbVoBYcIji10I9J0ApWCjp0kRaXdhHjTW4+uGnur4NJ8GOwZ3nf4TnnfZ5z3scAdBGGYdyVdN+yrGHTNNOtVqsVhuG+pO+S3gE/LtV3BIxzPDJNc8FxHGN0dNRKpVIGoJ2dndr+/r5Vr9cl6bmkN0AoSQIEyHXdj5KYnZ3F932uolKpkM/nK5KQ9FmSCZwLOI7zQBLr6+vXiFdRLBaDtsiTTve3YrFYkM/nbyR3MDU1dSKpLumO+vr6Xruui+d5AFSrVVZWVtjY2KDRaABwdHTE4uIie3t7AJTLZaLRaFXSCyUSid1MJgOA53n09/eTTqdJJpPMzc2xurqKbduMj48Tj8fZ3d0FYHBw8FjSezmOU56fnwdgeXkZ27ap1WpUKhWazSZjY2Nks1kASqVSd4zp6eljSX/MtiHdRDpnEATyfb+bkiSVSqXu3TCM8xgHBga+dkY4OzvDdV2GhoZIJBLMzMxQKBSIRqNkMhlisRhbW1sAJJPJn5I+KB6Pv7poou/7rK2tsbm5SRAEXROXlpY4ODgAoFarYdu2J+llN8ZcLvffMeZyud+SGpLuCVBPT89jSRQKhRvJxWKxISmU9JTOT5Rk9Pb2fpHE5OQkJycn14inp6dMTEx4bdM/SbKAy8sk6WEkElmwLCuSSqUYGRmxgHB7e7t+eHgYazabgaRnkt7SeZnr63xbUtYwjGHTNNNhGP4F9iR9a6/zr4v1/wDE1D9XlC4rrAAAAABJRU5ErkJggg==
+
+
+
+http://search.creativecommons.org/
+
diff --git a/locales/en-US/searchplugins/duckduckgo-palemoon.xml b/locales/en-US/searchplugins/duckduckgo-palemoon.xml
new file mode 100644
index 0000000..57395e3
--- /dev/null
+++ b/locales/en-US/searchplugins/duckduckgo-palemoon.xml
@@ -0,0 +1,16 @@
+
+
+ DuckDuckGo
+ Search DuckDuckGo
+ UTF-8
+ Search Plugin for DuckDuckGo (HTTPS version)
+ data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11RgALs6oACbQ9wAj0v8AI9L/ACfQ9wAu0agANdUYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzzN4CNdL/oK/z//////////////////////+jsPv/BDXX/wAz0t4AAAAAAAAAAAAAAAAAAAAAAAAAAAAyzvNSduD//////8jK/v+P+Lf/IbQL/17RPP+J3Y//wOKX//////9YeuX/ADLO8wAAAAAAAAAAAAAAAAAw091piOX/8/X9/1Fx5P9xhu//WOWZ/0W9Lv9Lwjn/J8BB/xyDAP9bdfL/9fP//2mI5v8AMNPdAAAAAAc610YRQ9f//////0Zr4P8AGdD/sb32////////////wrv//wAh1/8MPab/ACPc/05r4///////EkPX/wc610YANtWkrr/y/6S48P8AJ9L/AB3R/+/w/v///////////3+D7f8AQeL/AYTw/wFr5/8AMNb/p7Tv/6698v8AM9WkADLW//////8yXt//AC3V/wAw1/////////////z///8A0P7/AKb1/wWI7P8AuPf/AJ3w/zZW3P//////ADHV/wAx2P//////AzrZ/wAu1/84ZOL////////////e////AND//wC1+f8Atff/AZbv/wY62f8ELNf//////wAw1/8AMtn//////wAw2f8ALNn/kKrz////+//cwbH////////////R////Rcb8/wDO/f8A/P//AHzo//////8AMNj/ADXa//////8vXuL/ACna/4yq9///79T/jUkg/9i+r///////r2Q0/7Cozv8BKdr/AirY/zdZ4P//////ADTa/wI72tOuv/T/prr0/wAl2v+JqPb//7yW/+bUxv/9+/n////u//W+n/+Op/L/ADPd/wAv2v+ru/T/r7/0/wI72tMLQd1DEEjg//////9Cbef/ADng///////////////////////R3///AC3g/wAy3v9SeOn//////xFI4P8LQd1DAAAAAAM64PNmiuz/9/j//2mN7f/m7P3///////////9Cb+n/ACXd/wAt3v9rju3//////2iL7P8DOuDzAAAAAAAAAAAAAAAAAT3g/0p16f//////3OT8/3OS7v8AKt3/ACPc/zhn5/+xw/b//////0956v8CPeD/AAAAAAAAAAAAAAAAAAAAAAAAAAAEPODzBUDh/5uz8//7/f7/////////////////prz0/wtF4v8FQeDzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtF5kYDQOOkADrj/wA44v8AOeP/ADzk/wVB46QPReZGAAAAAAAAAAAAAAAAAAAAAPAPAADgBwAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAA4AcAAPAPAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAATCwAAEwsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChIzyAnRNFwJ0TQryND0d8nRNH/J0TR/ydE0f8nRNH/I0PR3ydE0K8nRNFwKEjPIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChE00AlRdK/J0XS/ydF0v8nRdL/XXPd/11z3f94i+P/k6Lp/5Oi6f9rf+D/NVDV/ydF0v8nRdL/JUXSvyhE00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAzxAnRNOvJ0XT/ydF0/8lRdK/KEXSYOvu+6/+/v6//v7+v/39/c////////////7+/r/J0fOAKEXSYCVF0r8nRdP/J0XT/ydE068gQM8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlRdUwJ0bT7ydG0/8nRtHPKETTQAAAAADHx8dA2vHhn5TYpN/o9+z/////////////////8PL83ydG0o8lRdUwAAAAAChE00AnRtHPJ0bT/ydG0+8lRdUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKEXVYCdG1P8nRtT/KEbTgAAAAAAmRtZQI0PU38jIyP/F6s//Rrtk/0a7ZP9/yIr/c796/4vLkv+JpNf/M3Kq/zyWh/8zeKTfJkbWUAAAAAAoRtOAJ0bU/ydG1P8oRdVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVF1TAnR9X/J0fV/yhF1WAgQM8QJ0fTrydH1f9CW8//2tra/6Pdsv9Gu2T/Rrtk/0WzWv9Gu2T/Rrtk/0a7ZP9Gu2T/Rrtk/z6egP8nR9X/J0fTryBAzxAoRdVgJ0fV/ydH1f8lRdUwAAAAAAAAAAAAAAAAAAAAAAAAAAAgQM8QJ0fV7ydH1f8oSNVgIEDPECdH1c8nR9X/J0fV/1xwyf/t7e3/o92y/0a7ZP9Gu2T/Ra5U/0a7ZP9Gu2T/Rrtk/0a7ZP9Gu2T/Pp6A/ydH1f8nR9X/J0fVzyBAzxAoSNVgJ0fV/ydH1e8gQM8QAAAAAAAAAAAAAAAAAAAAACdH1q8nR9b/KEjVgCBQzxAnR9bPJ0fW/ydH1v8nR9b/gIzB//r6+v+j3bL/Rrtk/13Ed/+i26//ruG7/z6egf8+noH/Rrtk/0a7ZP86kI//J0fW/ydH1v8nR9b/J0fWzyBQzxAoSNWAJ0fW/ydH1q8AAAAAAAAAAAAAAAAoSNdAJkjW/yZH1s8AAAAAJEfWryZI1v8mSNb/JkjW/yZI1v+jqsT//////+j37P/R7tj////////////W3ff/JkjW/yZI1v8uZbr/PJeI/zJzrP8mSNb/JkjW/yZI1v8mSNb/JEfWrwAAAAAmR9bPJkjW/yhI10AAAAAAAAAAACVI1r8mSNf/KEjXQCZJ1lAmSNf/JkjX/yZI1/8mSNf/JkjX/9HR0f///////////////////////////5Ok6/8mSNf/JkjX/yZI1/8mSNf/JkjX/yZI1/8mSNf/JkjX/yZI1/8mSNf/JknWUChI10AmSNf/JUjWvwAAAAAoSNcgJknY/yZH2M8AAAAAI0nY3yZJ2P8mSdj/JknY/yZJ2P9KZM//39/f////////////////////////////XHfi/yZJ2P8mSdj/JknY/yZJ2P8mSdj/JknY/yZJ2P8mSdj/JknY/yZJ2P8jSdjfAAAAACZH2M8mSdj/KEjXICdJ2HAmSdj/JUjXYCVK2jAmSdj/JknY/yZJ2P8mSdj/JknY/2V4yf/t7e3///////////////////////////9cd+L/HXTj/xSf7/8Nwfj/CdL8/wnS/P8J0vz/ELDz/xt85v8mSdj/JknY/yZJ2P8lStowJUjXYCZJ2P8nSdhwJErZryZK2f8oSNcgJUnajyZK2f8mStn/JkrZ/yZK2f8mStn/iJPA////////////////////////////0ff+/xjV/P8J0vz/Drn1/xiO6/8Yjuv/GI7r/xCw8/8Lyvr/CdL8/xmF6P8mStn/JkrZ/yVJ2o8oSNcgJkrZ/yRK2a8jStrfI0rZ3wAAAAAlSdq/Jkra/yZK2v8mStr/Jkra/yZK2v+xtsf///////////////////////////8o2Pz/CdL8/wvK+v8mStr/Jkra/yZK2v8mStr/Jkra/yZK2v8iW97/Jkra/yZK2v8mStr/JUnavwAAAAAjStnfI0ra3yZK2v8lSdq/AAAAACZH2O8mStr/Jkra/yZK2v8mStr/L1HY/9HR0f///////////////////////////yjY/P8J0vz/CdL8/xCw9P8QsPT/ELD0/xSf7/8ddeX/Jkra/yZK2v8mStr/Jkra/yZK2v8mR9jvAAAAACVJ2r8mStr/Jkvb/yVJ2r8AAAAAJkvb/yZL2/8mS9v/Jkvb/yZL2/9KZtL/4+Pj////////////////////////////4Pn//0fd/f8J0vz/CdL8/wnS/P8J0vz/CdL8/wnS/P8Lyvr/Fpfu/yJc3/8mS9v/Jkvb/yZL2/8AAAAAJUnavyZL2/8mS9z/JUncvwAAAAAmS9z/Jkvc/yZL3P8mS9z/Jkvc/26AyP/x8fH//////////////////////////////////////9H3/v/C9P7/o+7+/2fa+/8Oufb/CdL8/wnS/P8J0vz/CdL8/xiP7P8mS9z/Jkvc/wAAAAAlSdy/Jkvc/yZM3P8lTNy/AAAAACZJ2e8mTNz/Jkzc/yZM3P8mTNz/iJTB////////////qnth/5VaOf/x6eX///////////////////////Hp5f/x6eX/ydL2/yZM3P8kVN7/G37o/xKo8v8QsfT/HXbm/yZM3P8mSdnvAAAAACVM3L8mTNz/I0vc3yZJ2u8AAAAAJUzevyZM3f8mTN3/Jkzd/yZM3f+fqc3///////////+VWjn/v5yI/+re1///////////////////////jk8s/7iRe//J0vb/Jkzd/yZM3f8mTN3/Jkzd/yZM3f8mTN3/Jkzd/yVM3r8AAAAAI0vc3yNL3N8kTd2vJk3d/yhQ3yAlTd2PJk3d/yZN3f8mTd3/Jk3d/6St0v////////////Hp5f/q3tf///////////////////////////+xhm7/49PK/6Cx8P8mTd3/Jk3d/yZN3f8mTd3/Jk3d/yZN3f8mTd3/JU3djyhQ3yAmTd3/JE3drydN33AmTd7/J03fcCVK3zAmTd7/Jk3e/yZN3v8mTd7/pK7S///////Sp5r/////////////////////////////////////////////////T27k/yZN3v8mTd7/Jk3e/yZN3v8mTd7/Jk3e/yZN3v8lSt8wJ03fcCZN3v8nTd9wKFDfICZO3/8mTt3PAAAAACVN3r8mTt//Jk7f/yZO3/+EltX//////+fRyv/SqaD/59LO///////////////////////at63/vIBy/7Glxf8mTt//Jk7f/yZO3/8mTt//Jk7f/yZO3/8mTt//JU3evwAAAAAmTt3PJk7f/yhQ3yAAAAAAJE/dryZO3/8oUN9AKFDfQCZO3/8mTt//Jk7f/zhb2v/o6/T/////////////////////////////////////////////////XHrn/yZO3/8mTt//Jk7f/yZO3/8mTt//Jk7f/yZO3/8oUN9AKFDfQCZO3/8kT92vAAAAAAAAAAAoUN9AJk7g/yZO4M8AAAAAJk/hnyZO4P8mTuD/Jk7g/05v5v/k6fv//////////////////////////////////////3eR7P8mTuD/Jk7g/yZO4P8mTuD/Jk7g/yZO4P8mTuD/Jk/hnwAAAAAmTuDPJk7g/yhQ30AAAAAAAAAAAAAAAAAjT+GfJU/h/yVO4Y8gUN8QIk7gzyVP4f8lT+H/SWnW/0lp1v+bq+H/8fHx/////////////////6Cy8v9OcOb/JU/h/yVP4f8lT+H/JU/h/yVP4f8lT+H/JU/h/yJO4M8gUN8QJU7hjyVP4f8jT+GfAAAAAAAAAAAAAAAAAAAAACBQ3xAlTOHvJU/h/yVQ4mAgUN8QIk7hzyVP4f+ktOv///////////////////////H0/f9phur/JU/h/yVP4f8lT+H/JU/h/yVP4f8lT+H/JU/h/yVP4f8iTuHPIFDfECVQ4mAlT+H/JUzh7yBQ3xAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ3zAlUOLvJVDi/yVQ4mAgUN8QI1Din4mb2//J0/j/ydP4/6299P93ku3/M1vk/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/I1DinyBQ3xAlUOJgJVDi/yVQ4u8lUN8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ5DAlUOLvJVDi/yVQ4o8AAAAAJFDjQCVQ4r8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDi/yVQ4v8lUOL/JVDivyRQ40AAAAAAJVDijyVQ4v8lUOLvJVDkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQ5DAjUeTfJVHj/yNR5N8kUONAAAAAACVQ5DAmUuOAJVHivyNR5N8lUeP/JVHj/yNR5N8lUeK/JlLjgCVQ5DAAAAAAJFDjQCNR5N8lUeP/I1Hk3yVQ5DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBQ3xAjUuSfJVHk/yVR5P8jUeTfJFLkcChQ5yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoUOcgJFLkcCNR5N8lUeT/JVHk/yNS5J8gUN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUONAI1LknyVS5P8lUuT/JVLk/yVS5O8lUeS/JVHkvyVR5L8lUeS/JVLk7yVS5P8lUuT/JVLk/yRS468kUONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFDfECVS5GAjUuWfIlPlzyVS5f8lUuX/JVLl/yVS5f8iU+XPI1LlnyVS5GAgUN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/ggBB/wgAEP4AAAB8AAAAPAAAADiAAAEYAAAAEQAAAIAAAAAAAAAAAgAAAEIAAABCAAAAQgAAAEIAAABCAAAAQAAAAAAAAAABAAAAiAAAABiAAAEcAAAAPAAAAD4AAAB/CAAQ/4IAQf/AfgP/8AAP//wAP/
+
+
+
+
+
+
+
+
+
diff --git a/locales/en-US/searchplugins/eBay.xml b/locales/en-US/searchplugins/eBay.xml
new file mode 100644
index 0000000..74af34c
--- /dev/null
+++ b/locales/en-US/searchplugins/eBay.xml
@@ -0,0 +1,19 @@
+
+
+
+eBay
+eBay - Online auctions
+ISO-8859-1
+data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB6AQAAJgAAACAgAAAAAAAAQgMAAKABAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFBSURBVDjLtZPdK0MBGIf3J5Babhx3rinFBWuipaUskX9DYvkopqgV90q5UJpyp0OKrUWM2VrRsS9D0zZKHGaOnW1nj4vtypVtPPe/533r9746QAAOAJXfo5Yzgg44pHrcugon/6Sgo0b+XuAOZ2iZiVQmyPoDpIwmUkYTzqM7GsdDdC7F6Lbf8pzOkfWOouzqeZem2b+2AqAV8zjD8yVBqqcf2b7C66yNiMGMfixIQSvi8Mp0LEbR5ADq1QSKWM+Gx0RC9nOZ2GLzwlIWdPWiuNzk4w/EpThNkyEAXKEP2ud8KGId2sspilhPMrmNwzfCuqePr/xbSfC5I/I0MMSj2YJ3z49gDdO2cEOrLUowJpE9G0QRG1ClKbR0EIdvmOPYcnUtnN+vsnZiQC1k/qnGagQ1n3LNzySUJZVskitnmr8BlQG7T2hvgxsAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAMJSURBVFjD7ZddSFNhGMeHXXQTZFFCWfR1pRhUECQlBdWVToo+6KYu1KigtDASG5qUfZgFZvahEDosECPDktKZS1FL+1DRnEvdUptjug91X2dnZzv/3vO6OZbWnR4v9sADL+fs7P97/s/znu2VAJD4UkpSSdKG+QubTyPBr+sXz8XCR64fIAHihVTis0SsUAoAVhEBrBKIHCGAEMB/ARi3F5LkbpS2WMRzYEEBXC2tsD6T03R9agsCGLNyqPw6CXmrBT06JvhbPHZwmkdwtR0B138PPKOHgzXD5jLAy3tmibo4K9weZwDAazJj/FQKRnfugfHMeRiTz0K3Ixam1HQKcPC+Fisu9NK1P08Uj4DleHgMdXC+WQ7nu3UEOhFMfTQcVUvQ1H4IN2sj8H2k7K+2TqCc3GseyA8AmDOzMBq7D9bS8sAr6nEJdNt3UbHVF1XQGtmZew8bTPT6tWoD3KpsUvlR8NxUoEICMvl6KQo+xqCwcRs4T8Ax5c8bFExjbAgAjO7aS8VsLypgq3g5nWStjztAhWRVhqAqeB6IuKTClkw1eNYEbrCQQBwD8yGGOsAooogLYejQPKBi7UPF9DkH+ezd+o141ZkUPAOC+L9SAMivNc7q46YMNSLTe4n1kaQF4XD3ZIDTPgU3XEYciKcAHrsGJS1xKFBGgyVzouiT4VbdGhjt/cEA5isyKsaz7jl3we7bg7Rqf6j0LoSldON4wWcqJDgQNGTN++l13vELA+MK6kKd6iryFOvxtidt9i5gO7owdjKJQliflNAU1pas6xQgnAzg1ux+lJEdILixNr0Pq9JUUA8NwVG9DM73G0jlcnh+V4BpjIWzJmIGQIjnXw5TiDuKSEwxurm3ITc8DNO51BnrLbIcsrW0dNA6RxgUKU1UdGVqLy5X6qGzTLvlnewiBZyGs3Yz6X8UeaYI3olvZDhzwLumZ+eHvooCCC0Q5VUsb4unwycM4YIDqA01tPqmgbzQr2EIYPECiPm33LYoDiZSsY9moh9O/Znoa4d9HkXtPg2pX/cPKCoRQ+ocZa4AAAAASUVORK5CYII=
+
+
+
+
+
+
+
+http://search.ebay.com/
+
+
diff --git a/locales/en-US/searchplugins/ecosia.xml b/locales/en-US/searchplugins/ecosia.xml
new file mode 100644
index 0000000..04c8d22
--- /dev/null
+++ b/locales/en-US/searchplugins/ecosia.xml
@@ -0,0 +1,12 @@
+
+ Ecosia
+ Search Ecosia
+ UTF-8
+ info@ecosia.org
+ Ecosia Search
+
+ data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAACMuAAAjLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8qzQBuaw3UrmsN6u5rDfruaw37bmsN+25rDfSuaw3fLmsNyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2rTokrLFGurqsNv+5rDf/uaw3/7msN/+5rDf/uaw3/7urNP/AqS7suqw2aAAAAAAAAAAAAAAAAAAAAAC/qjApkbpn4mvJlf/EqCr/uaw3/7msN/+5rDf/uaw3/7urNP+rsUj/ib5x/7qsNv+9qzKBAAAAAAAAAAC5rDcLwKkvzom9cf813Nb/lrlh/8KoLP+5rDf/uaw3/7msN//BqS3/eMSF/yXj6v+BwHv/lbli/7atO1IAAAAAuaw3bsCqL/+Rumb/K+Di/z3ZzP+dtln/vqox/7msN/+5rDf/waku/23Ikv8s4OH/ONvS/5m4Xv+7qzXZuaw3CbmsN9DBqS7/hL93/zDe3f8v393/RdbD/7OuPv+7qzX/uqw2/8WoKf99wn//Lt/e/y/e3f99wn//v6ow/7msN0+7qzT7s64+/0bWwf8y3tn/L97d/03TuP+usET/vKoz/7isOP+vr0P/XM6n/zDe3P813Nb/L97d/5O6Zf/EpymOu6s0/7OuPv8+2cv/J+Hn/1HStP+0rjz/vasy/76qMP9zxYr/NtzV/zTd1/823NX/NtzV/zLd2f9I1b//mbheqsGpLf+gtVX/bseR/3fEhv+wr0L/vaoy/7msN/+/qjD/Wc+q/yvg4/813Nb/Md7b/zfc1P833NT/Mt7a/zbc1aqHvnT6bMiT/522WP+wr0L/vqox/7msN/+5rDf/vaoy/6C1VP8/2cr/N9zT/2vJlf9hzKD/NtzU/zbc1f813NaONdzWz3HGjv9ky53/prNN/8SoKv+8qzT/uaw3/7msOP/EqCr/ecOE/0HYx/9V0K//N9vT/zXc1v823NX/NtzVTjXc120w3tz/Lt/e/0zUu/+Fv3X/rrBF/7msN/+7qzX/vaoy/6qxSf9G1sH/L9/d/zPd2P8x3tv/L9/e2C/f3Qk23NUKNtzVzDbc1v823NX/OdvQ/0nVvv+xr0H/ta07/7+qL/+7qzT/r69D/2LMoP823NX/VNGx/2TLnVEAAAAAAAAAADbc1Sc03dfgQNnJ/2bKm/862tD/pLRP/1vOqf9S0rP/ib1x/8CpL/+4rDj/qLJM/7qsNn4AAAAAAAAAAAAAAAAAAAAAM93YI0vUvLtux5H/VdGw/3DHj/9Zz6r/Xc2m/3rDgv+5rDf/u6s1672rM2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyaYjUburNaytsUbZuK056cGpLuS/qjDGuaw3gLmsNx4AAAAAAAAAAAAAAAAAAAAA+D8AAOAPAADAAwAAgAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAgAMAAMAHAADgDwAA+B8AAA==
+
+
+
+
diff --git a/locales/en-US/searchplugins/list.txt b/locales/en-US/searchplugins/list.txt
new file mode 100644
index 0000000..2f2ca32
--- /dev/null
+++ b/locales/en-US/searchplugins/list.txt
@@ -0,0 +1,6 @@
+duckduckgo-palemoon
+bing
+ecosia
+twitter
+wikipedia
+yahoo
diff --git a/locales/en-US/searchplugins/twitter.xml b/locales/en-US/searchplugins/twitter.xml
new file mode 100644
index 0000000..e1909e7
--- /dev/null
+++ b/locales/en-US/searchplugins/twitter.xml
@@ -0,0 +1,15 @@
+
+
+
+Twitter
+Realtime Twitter Search
+UTF-8
+data:image/x-icon;base64,AAABAAIAEBAAAAAAAAALAgAAJgAAACAgAAAAAAAAQQQAADECAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAHSSURBVDjLfVO/axRREP6SS0ihlv4FQpoYWxHyHxgCsUxhmToBS4tF7NLZWaiIEHLv7d5dJNEQ0tgYEAmIjeAfYC57++7MGbzLjxu/Nxt27zZrBoadnZnvm3kz7wEqMpZqmdAfBBMIZBzGVGCkorbXq4kFp/yPtBgPZCJzZvYQuNZ+jKhVo75G2LyHVz9uoeFmc6bILaHaepv9v/w6iRcypXbonmNPBB9OBbv82tYfmPgn7NHTnKAaP8E+g8Ztot68k/nXDm8ooNEVhHEP1vXROBbUf/M/Wc0Jwl8zsEkHOxcMtE6Y+A42nodpLtLfR9QWRMmA9jm2eh78aXQY4eF9VvjCgKDWEewM2PIZQc4nD9Sf6hk+sohNqorzW0kN91BBdYKtO9dE/00JZITA50XxsxTHlWarqMYBh/O3UPGqrednx7ox3o+UhbIRT7O1BO9PfIsXI5V9J34WvrqN94buwFi+b3N0k0nrCjAFAp1+Nz1Czd3N2y8Tm6ywYk9JTHKqk/cD9cM17YW89WExbo6Ja1zhvgK3+4Itql+rt8PkO1f6oBysBN3brLrMVhs84wHJvpHoMwnf8CI9ygZd3nbJgymrMvxeSoLjmlCsIJf+a17lP6juZmUWkMzvAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAECElEQVRYw+1XS2gTURS9ia0/EMSCCC4siCIKrly4UVwIrgRR3KgbXQmCCiIiCha7EQRR6cIupHShSeZjf6lttdWFgqBRBPGDKIqF1mQ+1Wp/SZvnvXfmTWfMpJ3U0pUPHplJ3rv33HO/Afi/5nPViTjuKm8rYlFlAoSI8a500R1SGLYUZRH+Hvee6+qqygvxW1KJ1XLd+74aUuY+0OzjoHw/BElj4zQQHxv0HDBUvjR9WQlNYmnJhSjK9dxFUC0LOsYE3M8LSI8LUKw8AmoG5ecqPtP8vgZ04zKeO+jqjUtBDi2qWY+71xPaKKpnpF0uzUpCnxDQOixQ+BSo9iR/3vsh4CF+r5of8D3F75r9udQAKUwx++AJXkhZCe9QBkGEuUSC1swTjhK0VrUmEYzw7SKCyUPrLwEP8IxufQN9aCfKPwCJwdq/lCPluvUG2n4jhQW8bD6Hu+amABvSd/LOTbEENOMjdIyicLuA1om/ADhbMqIZn/DMOMq+7iqPBanUzWfQOUGUjUFnnj5H0WdnQOlfFoxssdix3tjGgnWbrCuGKvdA4LmuSQJ6s9SN0zFwg6lS7Qmms+WngK4pEvAVg+w83MltCAAhAHSGFMwEgGQRq2quwZe2cShJkaYvtey39hEHMfsQL7cjxd1F4dBnPWUKVeMwaLmTkRggGd1oiJI9GxLcLg2NA8s5DTXzCKePbjtBJAVoVoGjmFxEwsgiCi5tFuoDDFinHcb9xWg6CBcjpS9ReReCeF9GOL5TsCEYhRkSs26HmSLXh2R2f8DlJS7Q7BZOwyhWzeZ3P2hijtJRG9wSXuQkIj27m1OKKKPUiQIiCv1ptF4x33rUh/Yb+aVqN8BjIf07HwDy0EPFzU2/ck0rgCpln8MgtOcBgOOiFizRSWt7aQCWA0GHdesSBuOAm+fFOQIoOFXVeBRqaGnvlsGIed5LwWiO/LP11KASg7tmt97fnRoz1Xj5NXc4WQP0Sliw6d4EN6mUdStyew8cbB6uQWGdXL+pPHMrjQLCVe40tHdo1NJoQ47X5XBnfKUykduBQ0U9+jEbKR5IOTc0IwfJb+tnjvwoq+3DCmxEV1iwvzyHtlzbSTnVHMRKuTm6crK8AcelDrGc/a/0r4WUsRcF3ebWzC4YCqt8Rbdo5XmO4IZj9IGSW+PFUuSVyu7BeeABIrdZMNFIfiSrCQQFouwDNHxQLyBQdK6nSPOfgftUSXWtaOlD67BkXkCLXrFV1IYJBAUifcpnspQHFjyjmi+4y8nBs6KIL1cJuRZkt6K1xzCYrvFAqdtptDCNz3dxX8V91Gsufqvn8r/CByJemd/kvJiprui/RAQkMaZR/r1i4W6a0rP/N/gXi6OvmDvBLoiyBV1/AN29Cs9hVFoUAAAAAElFTkSuQmCC
+https://twitter.com/search/
+
+
+
+
+
diff --git a/locales/en-US/searchplugins/wikipedia.xml b/locales/en-US/searchplugins/wikipedia.xml
new file mode 100644
index 0000000..6bfb0cc
--- /dev/null
+++ b/locales/en-US/searchplugins/wikipedia.xml
@@ -0,0 +1,18 @@
+
+
+
+Wikipedia (en)
+Wikipedia, the free encyclopedia
+UTF-8
+data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=
+
+
+
+
+
+
+
+http://en.wikipedia.org/wiki/Special:Search
+
diff --git a/locales/en-US/searchplugins/yahoo.xml b/locales/en-US/searchplugins/yahoo.xml
new file mode 100644
index 0000000..244e85f
--- /dev/null
+++ b/locales/en-US/searchplugins/yahoo.xml
@@ -0,0 +1,17 @@
+
+
+
+Yahoo
+Yahoo Search
+UTF-8
+data:image/x-icon;base64,AAABAAIAEBAAAAEACAA8DQAAJgAAACAgAAABAAgAowsAAGINAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAAJcEhZcwAACxMAAAsTAQCanBgAAApPaUNDUFBob3Rvc2hvcCBJQ0MgcHJvZmlsZQAAeNqdU2dUU+kWPffe9EJLiICUS29SFQggUkKLgBSRJiohCRBKiCGh2RVRwRFFRQQbyKCIA46OgIwVUSwMigrYB+Qhoo6Do4iKyvvhe6Nr1rz35s3+tdc+56zznbPPB8AIDJZIM1E1gAypQh4R4IPHxMbh5C5AgQokcAAQCLNkIXP9IwEA+H48PCsiwAe+AAF40wsIAMBNm8AwHIf/D+pCmVwBgIQBwHSROEsIgBQAQHqOQqYAQEYBgJ2YJlMAoAQAYMtjYuMAUC0AYCd/5tMAgJ34mXsBAFuUIRUBoJEAIBNliEQAaDsArM9WikUAWDAAFGZLxDkA2C0AMElXZkgAsLcAwM4QC7IACAwAMFGIhSkABHsAYMgjI3gAhJkAFEbyVzzxK64Q5yoAAHiZsjy5JDlFgVsILXEHV1cuHijOSRcrFDZhAmGaQC7CeZkZMoE0D+DzzAAAoJEVEeCD8/14zg6uzs42jrYOXy3qvwb/ImJi4/7lz6twQAAA4XR+0f4sL7MagDsGgG3+oiXuBGheC6B194tmsg9AtQCg6dpX83D4fjw8RaGQudnZ5eTk2ErEQlthyld9/mfCX8BX/Wz5fjz89/XgvuIkgTJdgUcE+ODCzPRMpRzPkgmEYtzmj0f8twv//B3TIsRJYrlYKhTjURJxjkSajPMypSKJQpIpxSXS/2Ti3yz7Az7fNQCwaj4Be5EtqF1jA/ZLJxBYdMDi9wAA8rtvwdQoCAOAaIPhz3f/7z/9R6AlAIBmSZJxAABeRCQuVMqzP8cIAABEoIEqsEEb9MEYLMAGHMEF3MEL/GA2hEIkxMJCEEIKZIAccmAprIJCKIbNsB0qYC/UQB00wFFohpNwDi7CVbgOPXAP+mEInsEovIEJBEHICBNhIdqIAWKKWCOOCBeZhfghwUgEEoskIMmIFFEiS5E1SDFSilQgVUgd8j1yAjmHXEa6kTvIADKC/Ia8RzGUgbJRPdQMtUO5qDcahEaiC9BkdDGajxagm9BytBo9jDah59CraA/ajz5DxzDA6BgHM8RsMC7Gw0KxOCwJk2PLsSKsDKvGGrBWrAO7ifVjz7F3BBKBRcAJNgR3QiBhHkFIWExYTthIqCAcJDQR2gk3CQOEUcInIpOoS7QmuhH5xBhiMjGHWEgsI9YSjxMvEHuIQ8Q3JBKJQzInuZACSbGkVNIS0kbSblIj6SypmzRIGiOTydpka7IHOZQsICvIheSd5MPkM+Qb5CHyWwqdYkBxpPhT4ihSympKGeUQ5TTlBmWYMkFVo5pS3aihVBE1j1pCraG2Uq9Rh6gTNHWaOc2DFklLpa2ildMaaBdo92mv6HS6Ed2VHk6X0FfSy+lH6JfoA/R3DA2GFYPHiGcoGZsYBxhnGXcYr5hMphnTixnHVDA3MeuY55kPmW9VWCq2KnwVkcoKlUqVJpUbKi9Uqaqmqt6qC1XzVctUj6leU32uRlUzU+OpCdSWq1WqnVDrUxtTZ6k7qIeqZ6hvVD+kfln9iQZZw0zDT0OkUaCxX+O8xiALYxmzeCwhaw2rhnWBNcQmsc3ZfHYqu5j9HbuLPaqpoTlDM0ozV7NS85RmPwfjmHH4nHROCecop5fzforeFO8p4ikbpjRMuTFlXGuqlpeWWKtIq1GrR+u9Nq7tp52mvUW7WfuBDkHHSidcJ0dnj84FnedT2VPdpwqnFk09OvWuLqprpRuhu0R3v26n7pievl6Ankxvp955vef6HH0v/VT9bfqn9UcMWAazDCQG2wzOGDzFNXFvPB0vx9vxUUNdw0BDpWGVYZfhhJG50Tyj1UaNRg+MacZc4yTjbcZtxqMmBiYhJktN6k3umlJNuaYppjtMO0zHzczNos3WmTWbPTHXMueb55vXm9+3YFp4Wiy2qLa4ZUmy5FqmWe62vG6FWjlZpVhVWl2zRq2drSXWu627pxGnuU6TTque1mfDsPG2ybaptxmw5dgG2662bbZ9YWdiF2e3xa7D7pO9k326fY39PQcNh9kOqx1aHX5ztHIUOlY63prOnO4/fcX0lukvZ1jPEM/YM+O2E8spxGmdU5vTR2cXZ7lzg/OIi4lLgssulz4umxvG3ci95Ep09XFd4XrS9Z2bs5vC7ajbr+427mnuh9yfzDSfKZ5ZM3PQw8hD4FHl0T8Ln5Uwa9+sfk9DT4FntecjL2MvkVet17C3pXeq92HvFz72PnKf4z7jPDfeMt5ZX8w3wLfIt8tPw2+eX4XfQ38j/2T/ev/RAKeAJQFnA4mBQYFbAvv4enwhv44/Ottl9rLZ7UGMoLlBFUGPgq2C5cGtIWjI7JCtIffnmM6RzmkOhVB+6NbQB2HmYYvDfgwnhYeFV4Y/jnCIWBrRMZc1d9HcQ3PfRPpElkTem2cxTzmvLUo1Kj6qLmo82je6NLo/xi5mWczVWJ1YSWxLHDkuKq42bmy+3/zt84fineIL43sXmC/IXXB5oc7C9IWnFqkuEiw6lkBMiE44lPBBECqoFowl8hN3JY4KecIdwmciL9E20YjYQ1wqHk7ySCpNepLskbw1eSTFM6Us5bmEJ6mQvEwNTN2bOp4WmnYgbTI9Or0xg5KRkHFCqiFNk7Zn6mfmZnbLrGWFsv7Fbou3Lx6VB8lrs5CsBVktCrZCpuhUWijXKgeyZ2VXZr/Nico5lqueK83tzLPK25A3nO+f/+0SwhLhkralhktXLR1Y5r2sajmyPHF52wrjFQUrhlYGrDy4irYqbdVPq+1Xl65+vSZ6TWuBXsHKgsG1AWvrC1UK5YV969zX7V1PWC9Z37Vh+oadGz4ViYquFNsXlxV/2CjceOUbh2/Kv5nclLSpq8S5ZM9m0mbp5t4tnlsOlqqX5pcObg3Z2rQN31a07fX2Rdsvl80o27uDtkO5o788uLxlp8nOzTs/VKRU9FT6VDbu0t21Ydf4btHuG3u89jTs1dtbvPf9Psm+21UBVU3VZtVl+0n7s/c/romq6fiW+21drU5tce3HA9ID/QcjDrbXudTVHdI9VFKP1ivrRw7HH77+ne93LQ02DVWNnMbiI3BEeeTp9wnf9x4NOtp2jHus4QfTH3YdZx0vakKa8ppGm1Oa+1tiW7pPzD7R1ureevxH2x8PnDQ8WXlK81TJadrpgtOTZ/LPjJ2VnX1+LvncYNuitnvnY87fag9v77oQdOHSRf+L5zu8O85c8rh08rLb5RNXuFearzpfbep06jz+k9NPx7ucu5quuVxrue56vbV7ZvfpG543zt30vXnxFv/W1Z45Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187RmNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQp/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACZ0lEQVR42mzSP4icZRTF4ee+38xOkp2sG5cQxVJIIaaKkICxTkqJjQhpJFYiop2F1YKFQqoUVpEoCBYSS7dfOxVFWGIsokUE/0TEye7OzPe977XYNWk83b0cDoffvXHWGxkKYjt0N1fi+FaJIzNIFSJ0kDXn0z5nF1O9Sp5PzaizamLD2NELo5W4sOwXqqX/04o1R2wg9PYs/GXUmTjqpGNxwvWdFzz19Akvjj+XUkYTggylFLfml93due+tZ7+y577BrkJnbNWke8yHmzvgi/4lq+WU1XjCsThl2p1ya3GZ4KNrt03KuhXH0SkkkbTOL5+u2PnuZ/D8axtGMTaKsbOvrINP3v/W3Y9XhCJjQCrUWRedVpaq3nvn7oHXrz8jD8PfvnEGbL0716LXytIoxqizkups4R/VwhB7hpi7sXkbXNo86bkrazK5sXnbEHND7BvMLcykOotz3vlxvZw+faRb08VEiVC64rPdSw/pZ/Ly9EutNi3TkHOLOvN3u3OnHNx7MFio5qq5Ifdce/WHhwEfXPnekPuq/UPPQhrAKOV0MFdyRFQFRefr7Z9wRrb0zfYd1aCpGmr2BvtSTkcp1wZLnX0tx4oQjeHX+UF97P75QGspM7VMqTfopVwb0aY1F4ZWlFK1SCVDHQKUEvphj0ztkEdrvZoLtOkoNS2XlkHJIlroIky7Jw8atDSJdQ/aPTUdtJBaLqVmlJpqQataCZKhY/L4HwcEI/Qbv1v8tivbIdVG1UtNnPVmFmPEoT9l/Dc9Ujp42Mx4uGl6I5pmgdjGzaLbopsdJqZHWZnqtKkXcZU8D/8OAPAMQ4kD8KK1AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEJGlDQ1BJQ0MgUHJvZmlsZQAAOBGFVd9v21QUPolvUqQWPyBYR4eKxa9VU1u5GxqtxgZJk6XtShal6dgqJOQ6N4mpGwfb6baqT3uBNwb8AUDZAw9IPCENBmJ72fbAtElThyqqSUh76MQPISbtBVXhu3ZiJ1PEXPX6yznfOec7517bRD1fabWaGVWIlquunc8klZOnFpSeTYrSs9RLA9Sr6U4tkcvNEi7BFffO6+EdigjL7ZHu/k72I796i9zRiSJPwG4VHX0Z+AxRzNRrtksUvwf7+Gm3BtzzHPDTNgQCqwKXfZwSeNHHJz1OIT8JjtAq6xWtCLwGPLzYZi+3YV8DGMiT4VVuG7oiZpGzrZJhcs/hL49xtzH/Dy6bdfTsXYNY+5yluWO4D4neK/ZUvok/17X0HPBLsF+vuUlhfwX4j/rSfAJ4H1H0qZJ9dN7nR19frRTeBt4Fe9FwpwtN+2p1MXscGLHR9SXrmMgjONd1ZxKzpBeA71b4tNhj6JGoyFNp4GHgwUp9qplfmnFW5oTdy7NamcwCI49kv6fN5IAHgD+0rbyoBc3SOjczohbyS1drbq6pQdqumllRC/0ymTtej8gpbbuVwpQfyw66dqEZyxZKxtHpJn+tZnpnEdrYBbueF9qQn93S7HQGGHnYP7w6L+YGHNtd1FJitqPAR+hERCNOFi1i1alKO6RQnjKUxL1GNjwlMsiEhcPLYTEiT9ISbN15OY/jx4SMshe9LaJRpTvHr3C/ybFYP1PZAfwfYrPsMBtnE6SwN9ib7AhLwTrBDgUKcm06FSrTfSj187xPdVQWOk5Q8vxAfSiIUc7Z7xr6zY/+hpqwSyv0I0/QMTRb7RMgBxNodTfSPqdraz/sDjzKBrv4zu2+a2t0/HHzjd2Lbcc2sG7GtsL42K+xLfxtUgI7YHqKlqHK8HbCCXgjHT1cAdMlDetv4FnQ2lLasaOl6vmB0CMmwT/IPszSueHQqv6i/qluqF+oF9TfO2qEGTumJH0qfSv9KH0nfS/9TIp0Wboi/SRdlb6RLgU5u++9nyXYe69fYRPdil1o1WufNSdTTsp75BfllPy8/LI8G7AUuV8ek6fkvfDsCfbNDP0dvRh0CrNqTbV7LfEEGDQPJQadBtfGVMWEq3QWWdufk6ZSNsjG2PQjp3ZcnOWWing6noonSInvi0/Ex+IzAreevPhe+CawpgP1/pMTMDo64G0sTCXIM+KdOnFWRfQKdJvQzV1+Bt8OokmrdtY2yhVX2a+qrykJfMq4Ml3VR4cVzTQVz+UoNne4vcKLoyS+gyKO6EHe+75Fdt0Mbe5bRIf/wjvrVmhbqBN97RD1vxrahvBOfOYzoosH9bq94uejSOQGkVM6sN/7HelL4t10t9F4gPdVzydEOx83Gv+uNxo7XyL/FtFl8z9ZAHF4bBsrEwAAAAlwSFlzAAALEwAACxMBAJqcGAAAByVJREFUWAm1l1uIldcVx9d3ruMZZzRaay+pCjFJH6LSRqxQqA1NH0pBiH3Qp774kEAg4EOkxKdQSCjUFvpm6YsNVNoSaGjFtmga2yZgCIIawdv04g2kM7Uz6lzO+c758v/t/9lzTB/61Oxhn7332muv9V+3vb8pnooDVRkzZ4oY/LmK6mQZa05frX6yFJ9Ae7x4qd2IuV1FFM9WMfhaI9Z+pQBAL+aiEZ0QgNBm2YuZmxHF9VZMXqmivFaLweUyuteWYvHGVPWr2f+F7YvF/ola9DZGVJsHUXs8YvBEK1ZrXt9URDwqxY1BdGMQvWjGqkgA+iLUtazHuADUoowHYugKTilaR7SIpZjWqOMRfY090RbasS4JglpFtzWIcqwZa+pSqnWVcLLXijXpZCFpvbgb/VhMe8huMLPylWkci8/oSD8xJq7hj4WUWvXrlbqVrUyKtBYdpX3Bh9YbzsdErwRgbZKyFP+KdqxPssu4l2hDAOOxIj6bCHigKWRNCcpMCHHHB4TJLc+TXxKHnC51Ct+Qgxl/TZ0qE5Be/EdWTwjqQuJJAPIB8qAZk4kZoXJnvHH+27Hq0+0YX12PH+w7E3/8zbWkitN2M8pS7kCKZ761OV55c2fcm+nG7J1e7N/+e3m2nbyKQcAhnHWZLC86B1rxiFRvSIkIgJHFVWzZ+qk4fG5HEr4wV8buVb+Vuv5QeVZsi/HeW//eHZ1HbNfLT5+Jc2dndBav9KXugfqc+pLsv6Xxvk6kVheumnpDnXlTVMZWfHh+Li6cdOKvmGzEC69+WTskzwr1SfUJ9ZWp7z/0pWXlF9+ejQtnUdCWnAxQ+al5Tdz80lIVEP8x9eZQWCQwOTAhNc34Re+rUW8U0S+r2Ns8nWzBKgONBOeX3V3RaCpPRN7XeFcO7yYl+InML2U3VdBVHszHzbSXYLBJkuTSQzBuphoYZ7X/u8O30gFAHHxzi+Yop8ETcfDXW5JyKMd/fFuO9l3mYuwLAl5gbMg8QuKdYQg4Zjcxo7HikMeIn37vcizes9Ide9bGhs9NLPN9YX0ndnzHpbZ4vx9HXr6kc6Sobo2hIkuzOnIh0xMFRlvc0waWL+p3UePCQ/Myjjx/JSnl59CJbUkJgl75g+ZD/D978Yrc7EuMPe4ESo6OYsaasiiX7tADAyny5cGtyMHsDxzFnP0Tx6Z0SfsW27B1PHZ+c13seGZdbNo2Lo6Iu7e7cfznfxc/8ggNQBhZI9dSs2c5k+rFaHBXmZhd32xTGdlZPvzDvefj9XddlgeObYVpuf1o3zkpyrEnCJwBDjlmr9i7XP3jgrYkDamhEqRA8UOBxZ53tcOtBbgyzr53M65f8DU6sVZ1o067cfFBvP+XGzrDOa5s+JkTShIc+dBtlLOLlRpqAUDc+yqQMnViNq81edDVnPixno/vP/dXjn2svbbnPa1RiqXEHVkYQ06RWygnFEtpbZDLAJws2X1OHgfCv+hiRkZU8Y+pmbjwzjTE1D48PR1TV+5IMErgsjex2A8TJrqCHH9Cw6U0BGBkPUWrKTZnPq4L9WqIOFvEO8ml+vbRvyUB/Jw6OiUa9GydM58qQl6lTrNHyiENrwyTkOvXLziVkMlOOsesVKyIFtZB1zfDAGvdyj4xtkD7yHQ8Ynn4hCrwvYA+DOJCSlXAZl3MjNQobNzVPK7gJm0AiPsQyEg0c6s1cbEB5X08AmDz1TTLucApzHHyJgADvUqVysJMKOSicLRQl+emOIvbnaw+ot2pSTzl5zzJVjPaZ6ix7zCSN4E1shOAWnqbyYH8bOqd1h9AGJ0qtl6LRBubcBKxbo6xh60kWlbLjgG4NJ2ETkwqbl7SeUXVSCq+BF1C2bWEgEO4CxBGvOydGmu3ooXv7AEogLFqn2JtWKO8yc9xAmDxjhGiWMOQXe63zCvHtIjOpGOIwvGJlhRQepyzaiu0MQ4MnFhuT7CiJQC+sUg4jtOYO+1IH9OdCwgBSmOkP2r60CarHeXMjxw3PGyvOBnN670EgOPOc1yEYgDYCxbqTPDXki1srChi4R6lpQ+uDmVFDtkA5GH1qJEvQFgacqCFT37pyP+Y+DMJs0Y54NgbiIVn61jhEUrNARuNIi3vOQf8iUeQuNzILe4b/jFZ7RDYJhTbVRaJTxyWh8PgO93hQJCBsSa2GQyyoLlBzWDxgnm9l0JgADgNgVxElCH22xs4NCsaieSUyzWXaSTLDAPlGQB0Kt6JaqpzYjkJQT9id60aNwqZjVqlz9Kqp+JcfDjOAqhirNoCI6MelpVPAjZ/CbFv45Y9YNcicqDMKm/Xo/FPJdMlqZ9SIK7qSrrci9mbl6q3/DGQ5f7XuK347rgKeuMgiicEfLPmT0rGY1K5SdI/ryritlMbJrr/PZ8+I8qf9PF8qhMrT39QHfHLkhj/fz/bi+eb83F/VxX1b6jWvt6KdTs/AvvCmqXE235jAAAAAElFTkSuQmCC
+
+
+
+
+
+https://search.yahoo.com/
+
diff --git a/locales/en-US/updater/updater.ini b/locales/en-US/updater/updater.ini
new file mode 100644
index 0000000..6bc731f
--- /dev/null
+++ b/locales/en-US/updater/updater.ini
@@ -0,0 +1,10 @@
+; 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 file is in the UTF-8 encoding
+; All strings must be less than 600 chars.
+[Strings]
+TitleText=%MOZ_APP_DISPLAYNAME% Update
+InfoText=%MOZ_APP_DISPLAYNAME% is installing your updates and will start in a few moments…
+MozillaMaintenanceDescription=The Mozilla Maintenance Service ensures that you have the latest and most secure version of Mozilla Firefox on your computer. Keeping Firefox up to date is very important for your online security, and Mozilla strongly recommends that you keep this service enabled.
diff --git a/locales/filter.py b/locales/filter.py
new file mode 100644
index 0000000..8e097db
--- /dev/null
+++ b/locales/filter.py
@@ -0,0 +1,37 @@
+# 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/.
+
+def test(mod, path, entity = None):
+ import re
+ # ignore anything but Firefox
+ if mod not in ("netwerk", "dom", "toolkit", "security/manager",
+ "browser", "browser/metro", "webapprt",
+ "extensions/reporter", "extensions/spellcheck",
+ "other-licenses/branding/firefox",
+ "browser/branding/official",
+ "services/sync"):
+ return False
+ if mod != "browser" and mod != "extensions/spellcheck":
+ # we only have exceptions for browser and extensions/spellcheck
+ return True
+ if not entity:
+ if mod == "extensions/spellcheck":
+ return False
+ # browser
+ return not (re.match(r"searchplugins\/.+\.xml", path) or
+ re.match(r"chrome\/help\/images\/[A-Za-z-_]+\.png", path))
+ if mod == "extensions/spellcheck":
+ # l10n ships en-US dictionary or something, do compare
+ return True
+ if path == "defines.inc":
+ return entity != "MOZ_LANGPACK_CONTRIBUTORS"
+
+ if path != "chrome/browser-region/region.properties":
+ # only region.properties exceptions remain, compare all others
+ return True
+
+ return not (re.match(r"browser\.search\.order\.[1-9]", entity) or
+ re.match(r"browser\.contentHandlers\.types\.[0-5]", entity) or
+ re.match(r"goanna\.handlerService\.schemes\.", entity) or
+ re.match(r"goanna\.handlerService\.defaultHandlersVersion", entity))
diff --git a/locales/generic/extract-bookmarks.py b/locales/generic/extract-bookmarks.py
new file mode 100644
index 0000000..7bf711f
--- /dev/null
+++ b/locales/generic/extract-bookmarks.py
@@ -0,0 +1,62 @@
+# 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/.
+
+import sys
+import re
+import codecs
+try:
+ from Mozilla.Parser import getParser
+except ImportError:
+ sys.exit('''extract-bookmarks needs compare-locales
+
+Find that on http://pypi.python.org/pypi/compare-locales.
+This script has been tested with version 0.6, and might work with future
+versions.''')
+
+ll=re.compile('\.(title|a|dd|h[0-9])$')
+
+p = getParser(sys.argv[1])
+p.readFile(sys.argv[1])
+
+template = '''#filter emptyLines
+
+# LOCALIZATION NOTE: The 'en-US' strings in the URLs will be replaced with
+# your locale code, and link to your translated pages as soon as they're
+# live.
+
+#define bookmarks_title %s
+#define bookmarks_heading %s
+
+#define bookmarks_toolbarfolder %s
+#define bookmarks_toolbarfolder_description %s
+
+# LOCALIZATION NOTE (getting_started):
+# link title for https://www.mozilla.org/en-US/firefox/central/
+#define getting_started %s
+
+# LOCALIZATION NOTE (firefox_heading):
+# Firefox links folder name
+#define firefox_heading %s
+
+# LOCALIZATION NOTE (firefox_help):
+# link title for https://www.mozilla.org/en-US/firefox/help/
+#define firefox_help %s
+
+# LOCALIZATION NOTE (firefox_customize):
+# link title for https://www.mozilla.org/en-US/firefox/customize/
+#define firefox_customize %s
+
+# LOCALIZATION NOTE (firefox_community):
+# link title for https://www.mozilla.org/en-US/contribute/
+#define firefox_community %s
+
+# LOCALIZATION NOTE (firefox_about):
+# link title for https://www.mozilla.org/en-US/about/
+#define firefox_about %s
+
+#unfilter emptyLines'''
+
+strings = tuple(e.val for e in p if ll.search(e.key))
+
+print codecs.utf_8_encode(template % strings)[0]
diff --git a/locales/generic/profile/bookmarks.html.in b/locales/generic/profile/bookmarks.html.in
new file mode 100644
index 0000000..90e3adf
--- /dev/null
+++ b/locales/generic/profile/bookmarks.html.in
@@ -0,0 +1,19 @@
+#filter substitution
+
+
+
+@bookmarks_title@
+@bookmarks_heading@
+
+
+
@bookmarks_toolbarfolder@
+@bookmarks_toolbarfolder_description@
+
+
Pale Moon
+ Pale Moon forum
+ F.A.Q.
+ Release notes
+
+
diff --git a/locales/generic/profile/localstore.rdf b/locales/generic/profile/localstore.rdf
new file mode 100644
index 0000000..cc4b3b5
--- /dev/null
+++ b/locales/generic/profile/localstore.rdf
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/locales/generic/profile/mimeTypes.rdf b/locales/generic/profile/mimeTypes.rdf
new file mode 100644
index 0000000..8407940
--- /dev/null
+++ b/locales/generic/profile/mimeTypes.rdf
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/locales/jar.mn b/locales/jar.mn
new file mode 100644
index 0000000..5fcee24
--- /dev/null
+++ b/locales/jar.mn
@@ -0,0 +1,97 @@
+#filter substitution
+# 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/.
+
+
+@AB_CD@.jar:
+% locale browser @AB_CD@ %locale/browser/
+ locale/browser/aboutCertError.dtd (%chrome/browser/aboutCertError.dtd)
+ locale/browser/aboutDialog.dtd (%chrome/browser/aboutDialog.dtd)
+ locale/browser/aboutPrivateBrowsing.dtd (%chrome/browser/aboutPrivateBrowsing.dtd)
+* locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
+ locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
+#ifdef MOZ_SERVICES_SYNC
+ locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd)
+ locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
+#endif
+* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
+ locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
+ locale/browser/charsetOverlay.dtd (%chrome/browser/charsetOverlay.dtd)
+ locale/browser/browser.properties (%chrome/browser/browser.properties)
+ locale/browser/charsetMenu.properties (%chrome/browser/charsetMenu.properties)
+ locale/browser/charsetMenu.dtd (%chrome/browser/charsetMenu.dtd)
+ locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
+ locale/browser/newTab.properties (%chrome/browser/newTab.properties)
+ locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)
+ locale/browser/openLocation.properties (%chrome/browser/openLocation.properties)
+ locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)
+ locale/browser/pageInfo.properties (%chrome/browser/pageInfo.properties)
+ locale/browser/palemoon.dtd (%chrome/browser/palemoon.dtd)
+ locale/browser/quitDialog.properties (%chrome/browser/quitDialog.properties)
+ locale/browser/safeMode.dtd (%chrome/browser/safeMode.dtd)
+ locale/browser/sanitize.dtd (%chrome/browser/sanitize.dtd)
+ locale/browser/search.properties (%chrome/browser/search.properties)
+ locale/browser/searchbar.dtd (%chrome/browser/searchbar.dtd)
+ locale/browser/engineManager.dtd (%chrome/browser/engineManager.dtd)
+ locale/browser/engineManager.properties (%chrome/browser/engineManager.properties)
+ locale/browser/setDesktopBackground.dtd (%chrome/browser/setDesktopBackground.dtd)
+ locale/browser/shellservice.properties (%chrome/browser/shellservice.properties)
+ locale/browser/statusbar/statusbar-overlay.dtd (%chrome/browser/statusbar/statusbar-overlay.dtd)
+ locale/browser/statusbar/statusbar-prefs.dtd (%chrome/browser/statusbar/statusbar-prefs.dtd)
+ locale/browser/statusbar/meta.properties (%chrome/browser/statusbar/meta.properties)
+ locale/browser/statusbar/overlay.properties (%chrome/browser/statusbar/overlay.properties)
+ locale/browser/statusbar/prefs.properties (%chrome/browser/statusbar/prefs.properties)
+ locale/browser/tabbrowser.dtd (%chrome/browser/tabbrowser.dtd)
+ locale/browser/tabbrowser.properties (%chrome/browser/tabbrowser.properties)
+ locale/browser/taskbar.properties (%chrome/browser/taskbar.properties)
+ locale/browser/downloads/downloads.dtd (%chrome/browser/downloads/downloads.dtd)
+ locale/browser/downloads/downloads.properties (%chrome/browser/downloads/downloads.properties)
+ locale/browser/places/places.dtd (%chrome/browser/places/places.dtd)
+ locale/browser/places/places.properties (%chrome/browser/places/places.properties)
+ locale/browser/places/editBookmarkOverlay.dtd (%chrome/browser/places/editBookmarkOverlay.dtd)
+ locale/browser/places/bookmarkProperties.properties (%chrome/browser/places/bookmarkProperties.properties)
+ locale/browser/preferences/selectBookmark.dtd (%chrome/browser/preferences/selectBookmark.dtd)
+ locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd)
+ locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
+ locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
+ locale/browser/permissions/aboutPermissions.dtd (%chrome/browser/permissions/aboutPermissions.dtd)
+ locale/browser/permissions/aboutPermissions.properties (%chrome/browser/permissions/aboutPermissions.properties)
+ locale/browser/preferences/advanced.dtd (%chrome/browser/preferences/advanced.dtd)
+ locale/browser/preferences/applicationManager.dtd (%chrome/browser/preferences/applicationManager.dtd)
+ locale/browser/preferences/applicationManager.properties (%chrome/browser/preferences/applicationManager.properties)
+ locale/browser/preferences/colors.dtd (%chrome/browser/preferences/colors.dtd)
+ locale/browser/preferences/cookies.dtd (%chrome/browser/preferences/cookies.dtd)
+ locale/browser/preferences/content.dtd (%chrome/browser/preferences/content.dtd)
+ locale/browser/preferences/connection.dtd (%chrome/browser/preferences/connection.dtd)
+ locale/browser/preferences/applications.dtd (%chrome/browser/preferences/applications.dtd)
+ locale/browser/preferences/fonts.dtd (%chrome/browser/preferences/fonts.dtd)
+ locale/browser/preferences/main.dtd (%chrome/browser/preferences/main.dtd)
+ locale/browser/preferences/languages.dtd (%chrome/browser/preferences/languages.dtd)
+ locale/browser/preferences/permissions.dtd (%chrome/browser/preferences/permissions.dtd)
+ locale/browser/preferences/preferences.dtd (%chrome/browser/preferences/preferences.dtd)
+ locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
+ locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
+ locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd)
+#ifdef MOZ_SERVICES_SYNC
+ locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
+#endif
+ locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
+#ifdef MOZ_SERVICES_SYNC
+ locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
+ locale/browser/syncSetup.dtd (%chrome/browser/syncSetup.dtd)
+ locale/browser/syncSetup.properties (%chrome/browser/syncSetup.properties)
+ locale/browser/syncGenericChange.properties (%chrome/browser/syncGenericChange.properties)
+ locale/browser/syncKey.dtd (%chrome/browser/syncKey.dtd)
+ locale/browser/syncQuota.dtd (%chrome/browser/syncQuota.dtd)
+ locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
+#endif
+% locale browser-region @AB_CD@ %locale/browser-region/
+ locale/browser-region/region.properties (%chrome/browser-region/region.properties)
+# the following files are browser-specific overrides
+ locale/browser/netError.dtd (%chrome/overrides/netError.dtd)
+ locale/browser/appstrings.properties (%chrome/overrides/appstrings.properties)
+ locale/browser/downloads/settingsChange.dtd (%chrome/overrides/settingsChange.dtd)
+% override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd
+% override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
+% override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://browser/locale/downloads/settingsChange.dtd
diff --git a/locales/l10n.ini b/locales/l10n.ini
new file mode 100644
index 0000000..9a466b6
--- /dev/null
+++ b/locales/l10n.ini
@@ -0,0 +1,22 @@
+# 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/.
+
+[general]
+depth = ../../..
+all = application/palemoon/locales/all-locales
+
+[compare]
+dirs = application/palemoon
+ extensions/reporter
+ other-licenses/branding/firefox
+ application/palemoon/branding/official
+
+[includes]
+# non-central apps might want to use %(topsrcdir)s here, or other vars
+# RFE: that needs to be supported by compare-locales, too, though
+toolkit = toolkit/locales/l10n.ini
+services_sync = services/sync/locales/l10n.ini
+
+[extras]
+dirs = extensions/spellcheck
diff --git a/locales/moz.build b/locales/moz.build
new file mode 100644
index 0000000..c97072b
--- /dev/null
+++ b/locales/moz.build
@@ -0,0 +1,7 @@
+# -*- 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']
\ No newline at end of file
diff --git a/locales/shipped-locales b/locales/shipped-locales
new file mode 100644
index 0000000..96bd960
--- /dev/null
+++ b/locales/shipped-locales
@@ -0,0 +1,90 @@
+ach
+af
+ak
+ar
+as
+ast
+be
+bg
+bn-BD
+bn-IN
+br
+bs
+ca
+cs
+csb
+cy
+da
+de
+el
+en-GB
+en-US
+en-ZA
+eo
+es-AR
+es-CL
+es-ES
+es-MX
+et
+eu
+fa
+ff
+fi
+fr
+fy-NL
+ga-IE
+gd
+gl
+gu-IN
+he
+hi-IN
+hr
+hu
+hy-AM
+id
+is
+it
+ja linux win32
+ja-JP-mac osx
+kk
+km
+kn
+ko
+ku
+lg
+lij
+lt
+lv
+mai
+mk
+ml
+mr
+nb-NO
+nl
+nn-NO
+nso
+or
+pa-IN
+pl
+pt-BR
+pt-PT
+rm
+ro
+ru
+si
+sk
+sl
+son
+sq
+sr
+sv-SE
+ta
+ta-LK
+te
+th
+tr
+uk
+vi
+zh-CN
+zh-TW
+zu
diff --git a/modules/AboutHomeUtils.jsm b/modules/AboutHomeUtils.jsm
new file mode 100644
index 0000000..72712e1
--- /dev/null
+++ b/modules/AboutHomeUtils.jsm
@@ -0,0 +1,67 @@
+/* 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 = [ "AboutHomeUtils" ];
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+this.AboutHomeUtils = {
+ /**
+ * Returns an object containing the name and searchURL of the original default
+ * search engine.
+ */
+ get defaultSearchEngine() {
+ let defaultEngine = Services.search.defaultEngine;
+ let submission = defaultEngine.getSubmission("_searchTerms_", null, "homepage");
+
+ return Object.freeze({
+ name: defaultEngine.name,
+ searchURL: submission.uri.spec,
+ postDataString: submission.postDataString
+ });
+ },
+
+ /*
+ * showKnowYourRights - Determines if the user should be shown the
+ * about:rights notification. The notification should *not* be shown if
+ * we've already shown the current version, or if the override pref says to
+ * never show it. The notification *should* be shown if it's never been seen
+ * before, if a newer version is available, or if the override pref says to
+ * always show it.
+ */
+ get showKnowYourRights() {
+ // Look for an unconditional override pref. If set, do what it says.
+ // (true --> never show, false --> always show)
+ try {
+ return !Services.prefs.getBoolPref("browser.rights.override");
+ } catch (e) { }
+ // Ditto, for the legacy EULA pref.
+ try {
+ return !Services.prefs.getBoolPref("browser.EULA.override");
+ } catch (e) { }
+
+#ifndef MC_OFFICIAL
+ // Non-official builds shouldn't show the notification.
+ return false;
+#endif
+
+ // Look to see if the user has seen the current version or not.
+ var currentVersion = Services.prefs.getIntPref("browser.rights.version");
+ try {
+ return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
+ } catch (e) { }
+
+ // Legacy: If the user accepted a EULA, we won't annoy them with the
+ // equivalent about:rights page until the version changes.
+ try {
+ return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
+ } catch (e) { }
+
+ // We haven't shown the notification before, so do so now.
+ return true;
+ }
+};
diff --git a/modules/AutoCompletePopup.jsm b/modules/AutoCompletePopup.jsm
new file mode 100644
index 0000000..c3698f9
--- /dev/null
+++ b/modules/AutoCompletePopup.jsm
@@ -0,0 +1,293 @@
+/* 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;
+
+this.EXPORTED_SYMBOLS = [ "AutoCompletePopup" ];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+// nsITreeView implementation that feeds the autocomplete popup
+// with the search data.
+var AutoCompleteTreeView = {
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView,
+ Ci.nsIAutoCompleteController]),
+
+ // Private variables
+ treeBox: null,
+ results: [],
+
+ // nsITreeView
+ selection: null,
+
+ get rowCount() { return this.results.length; },
+ setTree: function(treeBox) { this.treeBox = treeBox; },
+ getCellText: function(idx, column) { return this.results[idx].value },
+ isContainer: function(idx) { return false; },
+ getCellValue: function(idx, column) { return false },
+ isContainerOpen: function(idx) { return false; },
+ isContainerEmpty: function(idx) { return false; },
+ isSeparator: function(idx) { return false; },
+ isSorted: function() { return false; },
+ isEditable: function(idx, column) { return false; },
+ canDrop: function(idx, orientation, dt) { return false; },
+ getLevel: function(idx) { return 0; },
+ getParentIndex: function(idx) { return -1; },
+ hasNextSibling: function(idx, after) { return idx < this.results.length - 1 },
+ toggleOpenState: function(idx) { },
+ getCellProperties: function(idx, column) { return this.results[idx].style || ""; },
+ getRowProperties: function(idx) { return ""; },
+ getImageSrc: function(idx, column) { return null; },
+ getProgressMode : function(idx, column) { },
+ cycleHeader: function(column) { },
+ cycleCell: function(idx, column) { },
+ selectionChanged: function() { },
+ performAction: function(action) { },
+ performActionOnCell: function(action, index, column) { },
+ getColumnProperties: function(column) { return ""; },
+
+ // nsIAutoCompleteController
+ get matchCount() {
+ return this.rowCount;
+ },
+
+ handleEnter: function(aIsPopupSelection) {
+ AutoCompletePopup.handleEnter(aIsPopupSelection);
+ },
+
+ stopSearch: function() {},
+
+ // Internal JS-only API
+ clearResults: function() {
+ this.results = [];
+ },
+
+ setResults: function(results) {
+ this.results = results;
+ },
+};
+
+this.AutoCompletePopup = {
+ MESSAGES: [
+ "FormAutoComplete:SelectBy",
+ "FormAutoComplete:GetSelectedIndex",
+ "FormAutoComplete:SetSelectedIndex",
+ "FormAutoComplete:MaybeOpenPopup",
+ "FormAutoComplete:ClosePopup",
+ "FormAutoComplete:Disconnect",
+ "FormAutoComplete:RemoveEntry",
+ "FormAutoComplete:Invalidate",
+ ],
+
+ init: function() {
+ for (let msg of this.MESSAGES) {
+ Services.mm.addMessageListener(msg, this);
+ }
+ },
+
+ uninit: function() {
+ for (let msg of this.MESSAGES) {
+ Services.mm.removeMessageListener(msg, this);
+ }
+ },
+
+ handleEvent: function(evt) {
+ switch (evt.type) {
+ case "popupshowing": {
+ this.sendMessageToBrowser("FormAutoComplete:PopupOpened");
+ break;
+ }
+
+ case "popuphidden": {
+ this.sendMessageToBrowser("FormAutoComplete:PopupClosed");
+ this.openedPopup = null;
+ this.weakBrowser = null;
+ evt.target.removeEventListener("popuphidden", this);
+ evt.target.removeEventListener("popupshowing", this);
+ break;
+ }
+ }
+ },
+
+ // Along with being called internally by the receiveMessage handler,
+ // this function is also called directly by the login manager, which
+ // uses a single message to fill in the autocomplete results. See
+ // "RemoteLogins:autoCompleteLogins".
+ showPopupWithResults: function({ browser, rect, dir, results }) {
+ if (!results.length || this.openedPopup) {
+ // We shouldn't ever be showing an empty popup, and if we
+ // already have a popup open, the old one needs to close before
+ // we consider opening a new one.
+ return;
+ }
+
+ let window = browser.ownerDocument.defaultView;
+ let tabbrowser = window.gBrowser;
+ if (Services.focus.activeWindow != window ||
+ tabbrowser.selectedBrowser != browser) {
+ // We were sent a message from a window or tab that went into the
+ // background, so we'll ignore it for now.
+ return;
+ }
+
+ this.weakBrowser = Cu.getWeakReference(browser);
+ this.openedPopup = browser.autoCompletePopup;
+ this.openedPopup.hidden = false;
+ // don't allow the popup to become overly narrow
+ this.openedPopup.setAttribute("width", Math.max(100, rect.width));
+ this.openedPopup.style.direction = dir;
+
+ AutoCompleteTreeView.setResults(results);
+ this.openedPopup.view = AutoCompleteTreeView;
+ this.openedPopup.selectedIndex = -1;
+ this.openedPopup.invalidate();
+
+ if (results.length) {
+ // Reset fields that were set from the last time the search popup was open
+ this.openedPopup.mInput = null;
+ this.openedPopup.showCommentColumn = false;
+ this.openedPopup.showImageColumn = false;
+ this.openedPopup.addEventListener("popuphidden", this);
+ this.openedPopup.addEventListener("popupshowing", this);
+ this.openedPopup.openPopupAtScreenRect("after_start", rect.left, rect.top,
+ rect.width, rect.height, false,
+ false);
+ } else {
+ this.closePopup();
+ }
+ },
+
+ invalidate(results) {
+ if (!this.openedPopup) {
+ return;
+ }
+
+ if (!results.length) {
+ this.closePopup();
+ } else {
+ AutoCompleteTreeView.setResults(results);
+ // We need to re-set the view in order for the
+ // tree to know the view has changed.
+ this.openedPopup.view = AutoCompleteTreeView;
+ this.openedPopup.invalidate();
+ }
+ },
+
+ closePopup() {
+ if (this.openedPopup) {
+ // Note that hidePopup() closes the popup immediately,
+ // so popuphiding or popuphidden events will be fired
+ // and handled during this call.
+ this.openedPopup.hidePopup();
+ }
+ AutoCompleteTreeView.clearResults();
+ },
+
+ removeLogin(login) {
+ Services.logins.removeLogin(login);
+ },
+
+ receiveMessage: function(message) {
+ if (!message.target.autoCompletePopup) {
+ // Returning false to pacify ESLint, but this return value is
+ // ignored by the messaging infrastructure.
+ return false;
+ }
+
+ switch (message.name) {
+ case "FormAutoComplete:SelectBy": {
+ this.openedPopup.selectBy(message.data.reverse, message.data.page);
+ break;
+ }
+
+ case "FormAutoComplete:GetSelectedIndex": {
+ if (this.openedPopup) {
+ return this.openedPopup.selectedIndex;
+ }
+ // If the popup was closed, then the selection
+ // has not changed.
+ return -1;
+ }
+
+ case "FormAutoComplete:SetSelectedIndex": {
+ let { index } = message.data;
+ if (this.openedPopup) {
+ this.openedPopup.selectedIndex = index;
+ }
+ break;
+ }
+
+ case "FormAutoComplete:MaybeOpenPopup": {
+ let { results, rect, dir } = message.data;
+ this.showPopupWithResults({ browser: message.target, rect, dir,
+ results });
+ break;
+ }
+
+ case "FormAutoComplete:Invalidate": {
+ let { results } = message.data;
+ this.invalidate(results);
+ break;
+ }
+
+ case "FormAutoComplete:ClosePopup": {
+ this.closePopup();
+ break;
+ }
+
+ case "FormAutoComplete:Disconnect": {
+ // The controller stopped controlling the current input, so clear
+ // any cached data. This is necessary cause otherwise we'd clear data
+ // only when starting a new search, but the next input could not support
+ // autocomplete and it would end up inheriting the existing data.
+ AutoCompleteTreeView.clearResults();
+ break;
+ }
+ }
+ // Returning false to pacify ESLint, but this return value is
+ // ignored by the messaging infrastructure.
+ return false;
+ },
+
+ /**
+ * Despite its name, this handleEnter is only called when the user clicks on
+ * one of the items in the popup since the popup is rendered in the parent process.
+ * The real controller's handleEnter is called directly in the content process
+ * for other methods of completing a selection (e.g. using the tab or enter
+ * keys) since the field with focus is in that process.
+ */
+ handleEnter(aIsPopupSelection) {
+ if (this.openedPopup) {
+ this.sendMessageToBrowser("FormAutoComplete:HandleEnter", {
+ selectedIndex: this.openedPopup.selectedIndex,
+ isPopupSelection: aIsPopupSelection,
+ });
+ }
+ },
+
+ /**
+ * If a browser exists that AutoCompletePopup knows about,
+ * sends it a message. Otherwise, this is a no-op.
+ *
+ * @param {string} msgName
+ * The name of the message to send.
+ * @param {object} data
+ * The optional data to send with the message.
+ */
+ sendMessageToBrowser(msgName, data) {
+ let browser = this.weakBrowser ? this.weakBrowser.get()
+ : null;
+ if (browser) {
+ browser.messageManager.sendAsyncMessage(msgName, data);
+ }
+ },
+
+ stopSearch: function() {}
+}
diff --git a/modules/BrowserNewTabPreloader.jsm b/modules/BrowserNewTabPreloader.jsm
new file mode 100644
index 0000000..778698f
--- /dev/null
+++ b/modules/BrowserNewTabPreloader.jsm
@@ -0,0 +1,436 @@
+/* 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 = ["BrowserNewTabPreloader"];
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8, ";
+const NEWTAB_URL = "about:newtab";
+const PREF_BRANCH = "browser.newtab.";
+
+// The interval between swapping in a preload docShell and kicking off the
+// next preload in the background.
+const PRELOADER_INTERVAL_MS = 600;
+// The initial delay before we start preloading our first new tab page. The
+// timer is started after the first 'browser-delayed-startup' has been sent.
+const PRELOADER_INIT_DELAY_MS = 5000;
+// The number of miliseconds we'll wait after we received a notification that
+// causes us to update our list of browsers and tabbrowser sizes. This acts as
+// kind of a damper when too many events are occuring in quick succession.
+const PRELOADER_UPDATE_DELAY_MS = 3000;
+
+const TOPIC_TIMER_CALLBACK = "timer-callback";
+const TOPIC_DELAYED_STARTUP = "browser-delayed-startup-finished";
+const TOPIC_XUL_WINDOW_CLOSED = "xul-window-destroyed";
+
+function createTimer(obj, delay) {
+ let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.init(obj, delay, Ci.nsITimer.TYPE_ONE_SHOT);
+ return timer;
+}
+
+function clearTimer(timer) {
+ if (timer) {
+ timer.cancel();
+ }
+ return null;
+}
+
+this.BrowserNewTabPreloader = {
+ init: function Preloader_init() {
+ Initializer.start();
+ },
+
+ uninit: function Preloader_uninit() {
+ Initializer.stop();
+ HostFrame.destroy();
+ Preferences.uninit();
+ HiddenBrowsers.uninit();
+ },
+
+ newTab: function Preloader_newTab(aTab) {
+ let win = aTab.ownerDocument.defaultView;
+ if (win.gBrowser) {
+ let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+
+ let {width, height} = utils.getBoundsWithoutFlushing(win.gBrowser);
+ let hiddenBrowser = HiddenBrowsers.get(width, height)
+ if (hiddenBrowser) {
+ return hiddenBrowser.swapWithNewTab(aTab);
+ }
+ }
+
+ return false;
+ }
+};
+
+Object.freeze(BrowserNewTabPreloader);
+
+var Initializer = {
+ _timer: null,
+ _observing: false,
+
+ start: function Initializer_start() {
+ Services.obs.addObserver(this, TOPIC_DELAYED_STARTUP, false);
+ this._observing = true;
+ },
+
+ stop: function Initializer_stop() {
+ this._timer = clearTimer(this._timer);
+
+ if (this._observing) {
+ Services.obs.removeObserver(this, TOPIC_DELAYED_STARTUP);
+ this._observing = false;
+ }
+ },
+
+ observe: function Initializer_observe(aSubject, aTopic, aData) {
+ if (aTopic == TOPIC_DELAYED_STARTUP) {
+ Services.obs.removeObserver(this, TOPIC_DELAYED_STARTUP);
+ this._observing = false;
+ this._startTimer();
+ } else if (aTopic == TOPIC_TIMER_CALLBACK) {
+ this._timer = null;
+ this._startPreloader();
+ }
+ },
+
+ _startTimer: function Initializer_startTimer() {
+ this._timer = createTimer(this, PRELOADER_INIT_DELAY_MS);
+ },
+
+ _startPreloader: function Initializer_startPreloader() {
+ Preferences.init();
+ if (Preferences.enabled) {
+ HiddenBrowsers.init();
+ }
+ }
+};
+
+var Preferences = {
+ _enabled: null,
+ _branch: null,
+
+ get enabled() {
+ if (this._enabled === null) {
+ this._enabled = this._branch.getBoolPref("preload") &&
+ !this._branch.prefHasUserValue("url");
+ }
+
+ return this._enabled;
+ },
+
+ init: function Preferences_init() {
+ this._branch = Services.prefs.getBranch(PREF_BRANCH);
+ this._branch.addObserver("", this, false);
+ },
+
+ uninit: function Preferences_uninit() {
+ if (this._branch) {
+ this._branch.removeObserver("", this);
+ this._branch = null;
+ }
+ },
+
+ observe: function Preferences_observe() {
+ let prevEnabled = this._enabled;
+ this._enabled = null;
+
+ if (prevEnabled && !this.enabled) {
+ HiddenBrowsers.uninit();
+ } else if (!prevEnabled && this.enabled) {
+ HiddenBrowsers.init();
+ }
+ },
+};
+
+var HiddenBrowsers = {
+ _browsers: null,
+ _updateTimer: null,
+
+ _topics: [
+ TOPIC_DELAYED_STARTUP,
+ TOPIC_XUL_WINDOW_CLOSED
+ ],
+
+ init: function () {
+ this._browsers = new Map();
+ this._updateBrowserSizes();
+ this._topics.forEach(t => Services.obs.addObserver(this, t, false));
+ },
+
+ uninit: function () {
+ if (this._browsers) {
+ this._topics.forEach(t => Services.obs.removeObserver(this, t, false));
+ this._updateTimer = clearTimer(this._updateTimer);
+
+ for (let [key, browser] of this._browsers) {
+ browser.destroy();
+ }
+ this._browsers = null;
+ }
+ },
+
+ get: function (width, height) {
+ // We haven't been initialized, yet.
+ if (!this._browsers) {
+ return null;
+ }
+
+ let key = width + "x" + height;
+ if (!this._browsers.has(key)) {
+ // Update all browsers' sizes if we can't find a matching one.
+ this._updateBrowserSizes();
+ }
+
+ // We should now have a matching browser.
+ if (this._browsers.has(key)) {
+ return this._browsers.get(key);
+ }
+
+ // We should never be here. Return the first browser we find.
+ Cu.reportError("NewTabPreloader: no matching browser found after updating");
+ for (let [size, browser] of this._browsers) {
+ return browser;
+ }
+
+ // We should really never be here.
+ Cu.reportError("NewTabPreloader: not even a single browser was found?");
+ return null;
+ },
+
+ observe: function (subject, topic, data) {
+ if (topic === TOPIC_TIMER_CALLBACK) {
+ this._updateTimer = null;
+ this._updateBrowserSizes();
+ } else {
+ this._updateTimer = clearTimer(this._updateTimer);
+ this._updateTimer = createTimer(this, PRELOADER_UPDATE_DELAY_MS);
+ }
+ },
+
+ _updateBrowserSizes: function () {
+ let sizes = this._collectTabBrowserSizes();
+ let toRemove = [];
+
+ // Iterate all browsers and check that they
+ // each can be assigned to one of the sizes.
+ for (let [key, browser] of this._browsers) {
+ if (sizes.has(key)) {
+ // We already have a browser for that size, great!
+ sizes.delete(key);
+ } else {
+ // This browser is superfluous or needs to be resized.
+ toRemove.push(browser);
+ this._browsers.delete(key);
+ }
+ }
+
+ // Iterate all sizes that we couldn't find a browser for.
+ for (let [key, {width, height}] of sizes) {
+ let browser;
+ if (toRemove.length) {
+ // Let's just resize one of the superfluous
+ // browsers and put it back into the map.
+ browser = toRemove.shift();
+ browser.resize(width, height);
+ } else {
+ // No more browsers to reuse, create a new one.
+ browser = new HiddenBrowser(width, height);
+ }
+
+ this._browsers.set(key, browser);
+ }
+
+ // Finally, remove all browsers we don't need anymore.
+ toRemove.forEach(b => b.destroy());
+ },
+
+ _collectTabBrowserSizes: function () {
+ let sizes = new Map();
+
+ function tabBrowserBounds() {
+ let wins = Services.ww.getWindowEnumerator("navigator:browser");
+ while (wins.hasMoreElements()) {
+ let win = wins.getNext();
+ if (win.gBrowser) {
+ let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ yield utils.getBoundsWithoutFlushing(win.gBrowser);
+ }
+ }
+ }
+
+ // Collect the sizes of all s out there.
+ for (let {width, height} of tabBrowserBounds()) {
+ if (width > 0 && height > 0) {
+ let key = width + "x" + height;
+ if (!sizes.has(key)) {
+ sizes.set(key, {width: width, height: height});
+ }
+ }
+ }
+
+ return sizes;
+ }
+};
+
+function HiddenBrowser(width, height) {
+ this.resize(width, height);
+
+ HostFrame.get().then(aFrame => {
+ let doc = aFrame.document;
+ this._browser = doc.createElementNS(XUL_NS, "browser");
+ this._browser.setAttribute("type", "content");
+ this._browser.setAttribute("src", NEWTAB_URL);
+ this._applySize();
+ doc.getElementById("win").appendChild(this._browser);
+ });
+}
+
+HiddenBrowser.prototype = {
+ _width: null,
+ _height: null,
+ _timer: null,
+ _needsFrameScripts: true,
+
+ get isPreloaded() {
+ return this._browser &&
+ this._browser.contentDocument &&
+ this._browser.contentDocument.readyState === "complete" &&
+ this._browser.currentURI.spec === NEWTAB_URL;
+ },
+
+ swapWithNewTab: function (aTab) {
+ if (!this.isPreloaded || this._timer) {
+ return false;
+ }
+
+ let win = aTab.ownerDocument.defaultView;
+ let tabbrowser = win.gBrowser;
+
+ if (!tabbrowser) {
+ return false;
+ }
+
+ // Swap docShells.
+ tabbrowser.swapNewTabWithBrowser(aTab, this._browser);
+
+ // Load all default frame scripts.
+ if (this._needsFrameScripts) {
+ this._needsFrameScripts = false;
+
+ let mm = aTab.linkedBrowser.messageManager;
+ mm.loadFrameScript("chrome://browser/content/content.js", true);
+ mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
+
+ if ("TabView" in win) {
+ mm.loadFrameScript("chrome://browser/content/tabview-content.js", true);
+ }
+ }
+
+ // Start a timer that will kick off preloading the next newtab page.
+ this._timer = createTimer(this, PRELOADER_INTERVAL_MS);
+
+ // Signal that we swapped docShells.
+ return true;
+ },
+
+ observe: function () {
+ this._timer = null;
+
+ // Start pre-loading the new tab page.
+ this._browser.loadURI(NEWTAB_URL);
+ },
+
+ resize: function (width, height) {
+ this._width = width;
+ this._height = height;
+ this._applySize();
+ },
+
+ _applySize: function () {
+ if (this._browser) {
+ this._browser.style.width = this._width + "px";
+ this._browser.style.height = this._height + "px";
+ }
+ },
+
+ destroy: function () {
+ if (this._browser) {
+ this._browser.remove();
+ this._browser = null;
+ }
+
+ this._timer = clearTimer(this._timer);
+ }
+};
+
+var HostFrame = {
+ _frame: null,
+ _deferred: null,
+
+ get hiddenDOMDocument() {
+ return Services.appShell.hiddenDOMWindow.document;
+ },
+
+ get isReady() {
+ return this.hiddenDOMDocument.readyState === "complete";
+ },
+
+ get: function () {
+ if (!this._deferred) {
+ this._deferred = Promise.defer();
+ this._create();
+ }
+
+ return this._deferred.promise;
+ },
+
+ destroy: function () {
+ if (this._frame) {
+ if (!Cu.isDeadWrapper(this._frame)) {
+ this._frame.removeEventListener("load", this, true);
+ this._frame.remove();
+ }
+
+ this._frame = null;
+ this._deferred = null;
+ }
+ },
+
+ handleEvent: function () {
+ let contentWindow = this._frame.contentWindow;
+ if (contentWindow.location.href === XUL_PAGE) {
+ this._frame.removeEventListener("load", this, true);
+ this._deferred.resolve(contentWindow);
+ } else {
+ contentWindow.location = XUL_PAGE;
+ }
+ },
+
+ _create: function () {
+ if (this.isReady) {
+ let doc = this.hiddenDOMDocument;
+ this._frame = doc.createElementNS(HTML_NS, "iframe");
+ this._frame.addEventListener("load", this, true);
+ doc.documentElement.appendChild(this._frame);
+ } else {
+ let flags = Ci.nsIThread.DISPATCH_NORMAL;
+ Services.tm.currentThread.dispatch(() => this._create(), flags);
+ }
+ }
+};
diff --git a/modules/CharsetMenu.jsm b/modules/CharsetMenu.jsm
new file mode 100644
index 0000000..f973088
--- /dev/null
+++ b/modules/CharsetMenu.jsm
@@ -0,0 +1,160 @@
+/* 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.EXPORTED_SYMBOLS = [ "CharsetMenu" ];
+
+const { classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyGetter(this, "gBundle", function() {
+ const kUrl = "chrome://browser/locale/charsetMenu.properties";
+ return Services.strings.createBundle(kUrl);
+});
+/**
+ * This set contains encodings that are in the Encoding Standard, except:
+ * - XSS-dangerous encodings (except ISO-2022-JP which is assumed to be
+ * too common not to be included).
+ * - x-user-defined, which practically never makes sense as an end-user-chosen
+ * override.
+ * - Encodings that IE11 doesn't have in its correspoding menu.
+ */
+const kEncodings = new Set([
+ // Globally relevant
+ "UTF-8",
+ "windows-1252",
+ // Arabic
+ "windows-1256",
+ "ISO-8859-6",
+ // Baltic
+ "windows-1257",
+ "ISO-8859-4",
+ // "ISO-8859-13", // Hidden since not in menu in IE11
+ // Central European
+ "windows-1250",
+ "ISO-8859-2",
+ // Chinese, Simplified
+ "gbk",
+ "gb18030",
+ // Chinese, Traditional
+ "Big5",
+ // Cyrillic
+ "windows-1251",
+ "ISO-8859-5",
+ "KOI8-R",
+ "KOI8-U",
+ "IBM866", // Not in menu in Chromium. Maybe drop this?
+ // "x-mac-cyrillic", // Not in menu in IE11 or Chromium.
+ // Greek
+ "windows-1253",
+ "ISO-8859-7",
+ // Hebrew
+ "windows-1255",
+ "ISO-8859-8-I",
+ "ISO-8859-8",
+ // Japanese
+ "Shift_JIS",
+ "EUC-JP",
+ "ISO-2022-JP",
+ // Korean
+ "EUC-KR",
+ // Thai
+ "windows-874",
+ // Turkish
+ "windows-1254",
+ // Vietnamese
+ "windows-1258",
+ // Hiding rare European encodings that aren't in the menu in IE11 and would
+ // make the menu messy by sorting all over the place
+ // "ISO-8859-3",
+ // "ISO-8859-10",
+ // "ISO-8859-14",
+ // "ISO-8859-15",
+ // "ISO-8859-16",
+ // "macintosh"
+]);
+
+// Always at the start of the menu, in this order, followed by a separator.
+const kPinned = [
+ "UTF-8",
+ "windows-1252"
+];
+
+this.CharsetMenu = Object.freeze({
+ build: function BuildCharsetMenu(event) {
+ let parent = event.target;
+ if (parent.lastChild.localName != "menuseparator") {
+ // Detector menu or charset menu already built
+ return;
+ }
+ let doc = parent.ownerDocument;
+
+ function createItem(encoding) {
+ let menuItem = doc.createElement("menuitem");
+ menuItem.setAttribute("type", "radio");
+ menuItem.setAttribute("name", "charsetGroup");
+ try {
+ menuItem.setAttribute("label", gBundle.GetStringFromName(encoding));
+ } catch (e) {
+ // Localization error but put *something* in the menu to recover.
+ menuItem.setAttribute("label", encoding);
+ }
+ try {
+ menuItem.setAttribute("accesskey",
+ gBundle.GetStringFromName(encoding + ".key"));
+ } catch (e) {
+ // Some items intentionally don't have an accesskey
+ }
+ menuItem.setAttribute("id", "charset." + encoding);
+ return menuItem;
+ }
+
+ // Clone the set in order to be able to remove the pinned encodings from
+ // the cloned set.
+ let encodings = new Set(kEncodings);
+ for (let encoding of kPinned) {
+ encodings.delete(encoding);
+ parent.appendChild(createItem(encoding));
+ }
+ parent.appendChild(doc.createElement("menuseparator"));
+ let list = [];
+ for (let encoding of encodings) {
+ list.push(createItem(encoding));
+ }
+
+ list.sort(function (a, b) {
+ let titleA = a.getAttribute("label");
+ let titleB = b.getAttribute("label");
+ // Normal sorting sorts the part in parenthesis in an order that
+ // happens to make the less frequently-used items first.
+ let index;
+ if ((index = titleA.indexOf("(")) > -1) {
+ titleA = titleA.substring(0, index);
+ }
+ if ((index = titleB.indexOf("(")) > -1) {
+ titleA = titleB.substring(0, index);
+ }
+ let comp = titleA.localeCompare(titleB);
+ if (comp) {
+ return comp;
+ }
+ // secondarily reverse sort by encoding name to sort "windows" or
+ // "shift_jis" first. This works regardless of localization, because
+ // the ids aren't localized.
+ let idA = a.getAttribute("id");
+ let idB = b.getAttribute("id");
+ if (idA < idB) {
+ return 1;
+ }
+ if (idB < idA) {
+ return -1;
+ }
+ return 0;
+ });
+
+ for (let item of list) {
+ parent.appendChild(item);
+ }
+ },
+});
\ No newline at end of file
diff --git a/modules/FormSubmitObserver.jsm b/modules/FormSubmitObserver.jsm
new file mode 100644
index 0000000..6b2ea3c
--- /dev/null
+++ b/modules/FormSubmitObserver.jsm
@@ -0,0 +1,235 @@
+/* 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/. */
+
+/*
+ * Handles the validation callback from nsIFormFillController and
+ * the display of the help panel on invalid elements.
+ */
+
+"use strict";
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+var HTMLInputElement = Ci.nsIDOMHTMLInputElement;
+var HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement;
+var HTMLSelectElement = Ci.nsIDOMHTMLSelectElement;
+var HTMLButtonElement = Ci.nsIDOMHTMLButtonElement;
+
+this.EXPORTED_SYMBOLS = [ "FormSubmitObserver" ];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/BrowserUtils.jsm");
+
+function FormSubmitObserver(aWindow, aTabChildGlobal) {
+ this.init(aWindow, aTabChildGlobal);
+}
+
+FormSubmitObserver.prototype =
+{
+ _validationMessage: "",
+ _content: null,
+ _element: null,
+
+ /*
+ * Public apis
+ */
+
+ init: function(aWindow, aTabChildGlobal)
+ {
+ this._content = aWindow;
+ this._tab = aTabChildGlobal;
+ this._mm =
+ this._content.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDocShell)
+ .sameTypeRootTreeItem
+ .QueryInterface(Ci.nsIDocShell)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIContentFrameMessageManager);
+
+ // nsIFormSubmitObserver callback about invalid forms. See HTMLFormElement
+ // for details.
+ Services.obs.addObserver(this, "invalidformsubmit", false);
+ this._tab.addEventListener("pageshow", this, false);
+ this._tab.addEventListener("unload", this, false);
+ },
+
+ uninit: function()
+ {
+ Services.obs.removeObserver(this, "invalidformsubmit");
+ this._content.removeEventListener("pageshow", this, false);
+ this._content.removeEventListener("unload", this, false);
+ this._mm = null;
+ this._element = null;
+ this._content = null;
+ this._tab = null;
+ },
+
+ /*
+ * Events
+ */
+
+ handleEvent: function (aEvent) {
+ switch (aEvent.type) {
+ case "pageshow":
+ if (this._isRootDocumentEvent(aEvent)) {
+ this._hidePopup();
+ }
+ break;
+ case "unload":
+ this.uninit();
+ break;
+ case "input":
+ this._onInput(aEvent);
+ break;
+ case "blur":
+ this._onBlur(aEvent);
+ break;
+ }
+ },
+
+ /*
+ * nsIFormSubmitObserver
+ */
+
+ notifyInvalidSubmit : function (aFormElement, aInvalidElements)
+ {
+ // We are going to handle invalid form submission attempt by focusing the
+ // first invalid element and show the corresponding validation message in a
+ // panel attached to the element.
+ if (!aInvalidElements.length) {
+ return;
+ }
+
+ // Ensure that this is the FormSubmitObserver associated with the
+ // element / window this notification is about.
+ let element = aInvalidElements.queryElementAt(0, Ci.nsISupports);
+ if (this._content != element.ownerGlobal.top.document.defaultView) {
+ return;
+ }
+
+ if (!(element instanceof HTMLInputElement ||
+ element instanceof HTMLTextAreaElement ||
+ element instanceof HTMLSelectElement ||
+ element instanceof HTMLButtonElement)) {
+ return;
+ }
+
+ // Update validation message before showing notification
+ this._validationMessage = element.validationMessage;
+
+ // Don't connect up to the same element more than once.
+ if (this._element == element) {
+ this._showPopup(element);
+ return;
+ }
+ this._element = element;
+
+ element.focus();
+
+ // Watch for input changes which may change the validation message.
+ element.addEventListener("input", this, false);
+
+ // Watch for focus changes so we can disconnect our listeners and
+ // hide the popup.
+ element.addEventListener("blur", this, false);
+
+ this._showPopup(element);
+ },
+
+ /*
+ * Internal
+ */
+
+ /*
+ * Handles input changes on the form element we've associated a popup
+ * with. Updates the validation message or closes the popup if form data
+ * becomes valid.
+ */
+ _onInput: function (aEvent) {
+ let element = aEvent.originalTarget;
+
+ // If the form input is now valid, hide the popup.
+ if (element.validity.valid) {
+ this._hidePopup();
+ return;
+ }
+
+ // If the element is still invalid for a new reason, we should update
+ // the popup error message.
+ if (this._validationMessage != element.validationMessage) {
+ this._validationMessage = element.validationMessage;
+ this._showPopup(element);
+ }
+ },
+
+ /*
+ * Blur event handler in which we disconnect from the form element and
+ * hide the popup.
+ */
+ _onBlur: function (aEvent) {
+ aEvent.originalTarget.removeEventListener("input", this, false);
+ aEvent.originalTarget.removeEventListener("blur", this, false);
+ this._element = null;
+ this._hidePopup();
+ },
+
+ /*
+ * Send the show popup message to chrome with appropriate position
+ * information. Can be called repetitively to update the currently
+ * displayed popup position and text.
+ */
+ _showPopup: function (aElement) {
+ // Collect positional information and show the popup
+ let panelData = {};
+
+ panelData.message = this._validationMessage;
+
+ // Note, this is relative to the browser and needs to be translated
+ // in chrome.
+ panelData.contentRect = BrowserUtils.getElementBoundingRect(aElement);
+
+ // We want to show the popup at the middle of checkbox and radio buttons
+ // and where the content begin for the other elements.
+ let offset = 0;
+
+ if (aElement.tagName == 'INPUT' &&
+ (aElement.type == 'radio' || aElement.type == 'checkbox')) {
+ panelData.position = "bottomcenter topleft";
+ } else {
+ let win = aElement.ownerGlobal;
+ let style = win.getComputedStyle(aElement, null);
+ if (style.direction == 'rtl') {
+ offset = parseInt(style.paddingRight) + parseInt(style.borderRightWidth);
+ } else {
+ offset = parseInt(style.paddingLeft) + parseInt(style.borderLeftWidth);
+ }
+ let zoomFactor = this._getWindowUtils().fullZoom;
+ panelData.offset = Math.round(offset * zoomFactor);
+ panelData.position = "after_start";
+ }
+ this._mm.sendAsyncMessage("FormValidation:ShowPopup", panelData);
+ },
+
+ _hidePopup: function () {
+ this._mm.sendAsyncMessage("FormValidation:HidePopup", {});
+ },
+
+ _getWindowUtils: function () {
+ return this._content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+ },
+
+ _isRootDocumentEvent: function (aEvent) {
+ if (this._content == null) {
+ return true;
+ }
+ let target = aEvent.originalTarget;
+ return (target == this._content.document ||
+ (target.ownerDocument && target.ownerDocument == this._content.document));
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIFormSubmitObserver])
+};
diff --git a/modules/FormValidationHandler.jsm b/modules/FormValidationHandler.jsm
new file mode 100644
index 0000000..387c221
--- /dev/null
+++ b/modules/FormValidationHandler.jsm
@@ -0,0 +1,157 @@
+/* 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/. */
+
+/*
+ * Chrome side handling of form validation popup.
+ */
+
+"use strict";
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+this.EXPORTED_SYMBOLS = [ "FormValidationHandler" ];
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+var FormValidationHandler =
+{
+ _panel: null,
+ _anchor: null,
+
+ /*
+ * Public apis
+ */
+
+ init: function () {
+ let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
+ mm.addMessageListener("FormValidation:ShowPopup", this);
+ mm.addMessageListener("FormValidation:HidePopup", this);
+ },
+
+ uninit: function () {
+ let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
+ mm.removeMessageListener("FormValidation:ShowPopup", this);
+ mm.removeMessageListener("FormValidation:HidePopup", this);
+ this._panel = null;
+ this._anchor = null;
+ },
+
+ hidePopup: function () {
+ this._hidePopup();
+ },
+
+ /*
+ * Events
+ */
+
+ receiveMessage: function (aMessage) {
+ let window = aMessage.target.ownerDocument.defaultView;
+ let json = aMessage.json;
+ let tabBrowser = window.gBrowser;
+ switch (aMessage.name) {
+ case "FormValidation:ShowPopup":
+ // target is the , make sure we're receiving a message
+ // from the foreground tab.
+ if (tabBrowser && aMessage.target != tabBrowser.selectedBrowser) {
+ return;
+ }
+ this._showPopup(window, json);
+ break;
+ case "FormValidation:HidePopup":
+ this._hidePopup();
+ break;
+ }
+ },
+
+ observe: function (aSubject, aTopic, aData) {
+ this._hidePopup();
+ },
+
+ handleEvent: function (aEvent) {
+ switch (aEvent.type) {
+ case "FullZoomChange":
+ case "TextZoomChange":
+ case "ZoomChangeUsingMouseWheel":
+ case "scroll":
+ this._hidePopup();
+ break;
+ case "popuphiding":
+ this._onPopupHiding(aEvent);
+ break;
+ }
+ },
+
+ /*
+ * Internal
+ */
+
+ _onPopupHiding: function (aEvent) {
+ aEvent.originalTarget.removeEventListener("popuphiding", this, true);
+ let tabBrowser = aEvent.originalTarget.ownerDocument.getElementById("content");
+ tabBrowser.selectedBrowser.removeEventListener("scroll", this, true);
+ tabBrowser.selectedBrowser.removeEventListener("FullZoomChange", this, false);
+ tabBrowser.selectedBrowser.removeEventListener("TextZoomChange", this, false);
+ tabBrowser.selectedBrowser.removeEventListener("ZoomChangeUsingMouseWheel", this, false);
+
+ this._panel.hidden = true;
+ this._panel = null;
+ this._anchor.hidden = true;
+ this._anchor = null;
+ },
+
+ /*
+ * Shows the form validation popup at a specified position or updates the
+ * messaging and position if the popup is already displayed.
+ *
+ * @aWindow - the chrome window
+ * @aPanelData - Object that contains popup information
+ * aPanelData stucture detail:
+ * contentRect - the bounding client rect of the target element. If
+ * content is remote, this is relative to the browser, otherwise its
+ * relative to the window.
+ * position - popup positional string constants.
+ * message - the form element validation message text.
+ */
+ _showPopup: function (aWindow, aPanelData) {
+ let previouslyShown = !!this._panel;
+ this._panel = aWindow.document.getElementById("invalid-form-popup");
+ this._panel.firstChild.textContent = aPanelData.message;
+ this._panel.hidden = false;
+
+ let tabBrowser = aWindow.gBrowser;
+ this._anchor = tabBrowser.popupAnchor;
+ this._anchor.left = aPanelData.contentRect.left;
+ this._anchor.top = aPanelData.contentRect.top;
+ this._anchor.width = aPanelData.contentRect.width;
+ this._anchor.height = aPanelData.contentRect.height;
+ this._anchor.hidden = false;
+
+ // Display the panel if it isn't already visible.
+ if (!previouslyShown) {
+ // Cleanup after the popup is hidden
+ this._panel.addEventListener("popuphiding", this, true);
+
+ // Hide if the user scrolls the page
+ tabBrowser.selectedBrowser.addEventListener("scroll", this, true);
+ tabBrowser.selectedBrowser.addEventListener("FullZoomChange", this, false);
+ tabBrowser.selectedBrowser.addEventListener("TextZoomChange", this, false);
+ tabBrowser.selectedBrowser.addEventListener("ZoomChangeUsingMouseWheel", this, false);
+
+ // Open the popup
+ this._panel.openPopup(this._anchor, aPanelData.position, 0, 0, false);
+ }
+ },
+
+ /*
+ * Hide the popup if currently displayed. Will fire an event to onPopupHiding
+ * above if visible.
+ */
+ _hidePopup: function () {
+ if (this._panel) {
+ this._panel.hidePopup();
+ }
+ }
+};
diff --git a/modules/NetworkPrioritizer.jsm b/modules/NetworkPrioritizer.jsm
new file mode 100644
index 0000000..23d688a
--- /dev/null
+++ b/modules/NetworkPrioritizer.jsm
@@ -0,0 +1,179 @@
+/* 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 module adjusts network priority for tabs in a way that gives 'important'
+ * tabs a higher priority. There are 3 levels of priority. Each is listed below
+ * with the priority adjustment used.
+ *
+ * Highest (-10): Selected tab in the focused window.
+ * Medium (0): Background tabs in the focused window.
+ * Selected tab in background windows.
+ * Lowest (+10): Background tabs in background windows.
+ */
+
+this.EXPORTED_SYMBOLS = ["trackBrowserWindow"];
+
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+
+// Lazy getters
+XPCOMUtils.defineLazyServiceGetter(this, "_focusManager",
+ "@mozilla.org/focus-manager;1",
+ "nsIFocusManager");
+
+
+// Constants
+const TAB_EVENTS = ["TabOpen", "TabSelect"];
+const WINDOW_EVENTS = ["activate", "unload"];
+// PRIORITY DELTA is -10 because lower priority value is actually a higher priority
+const PRIORITY_DELTA = -10;
+
+
+// Variables
+var _lastFocusedWindow = null;
+var _windows = [];
+
+
+// Exported symbol
+this.trackBrowserWindow = function trackBrowserWindow(aWindow) {
+ WindowHelper.addWindow(aWindow);
+}
+
+
+// Global methods
+function _handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "TabOpen":
+ BrowserHelper.onOpen(aEvent.target.linkedBrowser);
+ break;
+ case "TabSelect":
+ BrowserHelper.onSelect(aEvent.target.linkedBrowser);
+ break;
+ case "activate":
+ WindowHelper.onActivate(aEvent.target);
+ break;
+ case "unload":
+ WindowHelper.removeWindow(aEvent.currentTarget);
+ break;
+ }
+}
+
+
+// Methods that impact a browser. Put into single object for organization.
+var BrowserHelper = {
+ onOpen: function NP_BH_onOpen(aBrowser) {
+ // If the tab is in the focused window, leave priority as it is
+ if (aBrowser.ownerDocument.defaultView != _lastFocusedWindow)
+ this.decreasePriority(aBrowser);
+ },
+
+ onSelect: function NP_BH_onSelect(aBrowser) {
+ let windowEntry = WindowHelper.getEntry(aBrowser.ownerDocument.defaultView);
+ if (windowEntry.lastSelectedBrowser)
+ this.decreasePriority(windowEntry.lastSelectedBrowser);
+ this.increasePriority(aBrowser);
+
+ windowEntry.lastSelectedBrowser = aBrowser;
+ },
+
+ increasePriority: function NP_BH_increasePriority(aBrowser) {
+ aBrowser.adjustPriority(PRIORITY_DELTA);
+ },
+
+ decreasePriority: function NP_BH_decreasePriority(aBrowser) {
+ aBrowser.adjustPriority(PRIORITY_DELTA * -1);
+ }
+};
+
+
+// Methods that impact a window. Put into single object for organization.
+var WindowHelper = {
+ addWindow: function NP_WH_addWindow(aWindow) {
+ // Build internal data object
+ _windows.push({ window: aWindow, lastSelectedBrowser: null });
+
+ // Add event listeners
+ TAB_EVENTS.forEach(function(event) {
+ aWindow.gBrowser.tabContainer.addEventListener(event, _handleEvent, false);
+ });
+ WINDOW_EVENTS.forEach(function(event) {
+ aWindow.addEventListener(event, _handleEvent, false);
+ });
+
+ // This gets called AFTER activate event, so if this is the focused window
+ // we want to activate it. Otherwise, deprioritize it.
+ if (aWindow == _focusManager.activeWindow)
+ this.handleFocusedWindow(aWindow);
+ else
+ this.decreasePriority(aWindow);
+
+ // Select the selected tab
+ BrowserHelper.onSelect(aWindow.gBrowser.selectedBrowser);
+ },
+
+ removeWindow: function NP_WH_removeWindow(aWindow) {
+ if (aWindow == _lastFocusedWindow)
+ _lastFocusedWindow = null;
+
+ // Delete this window from our tracking
+ _windows.splice(this.getEntryIndex(aWindow), 1);
+
+ // Remove the event listeners
+ TAB_EVENTS.forEach(function(event) {
+ aWindow.gBrowser.tabContainer.removeEventListener(event, _handleEvent, false);
+ });
+ WINDOW_EVENTS.forEach(function(event) {
+ aWindow.removeEventListener(event, _handleEvent, false);
+ });
+ },
+
+ onActivate: function NP_WH_onActivate(aWindow, aHasFocus) {
+ // If this window was the last focused window, we don't need to do anything
+ if (aWindow == _lastFocusedWindow)
+ return;
+
+ // handleFocusedWindow will deprioritize the current window
+ this.handleFocusedWindow(aWindow);
+
+ // Lastly we should increase priority for this window
+ this.increasePriority(aWindow);
+ },
+
+ handleFocusedWindow: function NP_WH_handleFocusedWindow(aWindow) {
+ // If we have a last focused window, we need to deprioritize it first
+ if (_lastFocusedWindow)
+ this.decreasePriority(_lastFocusedWindow);
+
+ // aWindow is now focused
+ _lastFocusedWindow = aWindow;
+ },
+
+ // Auxiliary methods
+ increasePriority: function NP_WH_increasePriority(aWindow) {
+ aWindow.gBrowser.browsers.forEach(function(aBrowser) {
+ BrowserHelper.increasePriority(aBrowser);
+ });
+ },
+
+ decreasePriority: function NP_WH_decreasePriority(aWindow) {
+ aWindow.gBrowser.browsers.forEach(function(aBrowser) {
+ BrowserHelper.decreasePriority(aBrowser);
+ });
+ },
+
+ getEntry: function NP_WH_getEntry(aWindow) {
+ return _windows[this.getEntryIndex(aWindow)];
+ },
+
+ getEntryIndex: function NP_WH_getEntryAtIndex(aWindow) {
+ // Assumes that every object has a unique window & it's in the array
+ for (let i = 0; i < _windows.length; i++)
+ if (_windows[i].window == aWindow)
+ return i;
+ }
+};
+
diff --git a/modules/PageMenu.jsm b/modules/PageMenu.jsm
new file mode 100644
index 0000000..d01f626
--- /dev/null
+++ b/modules/PageMenu.jsm
@@ -0,0 +1,238 @@
+/* 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.EXPORTED_SYMBOLS = ["PageMenu"];
+
+this.PageMenu = function PageMenu() {
+}
+
+PageMenu.prototype = {
+ PAGEMENU_ATTR: "pagemenu",
+ GENERATEDITEMID_ATTR: "generateditemid",
+
+ _popup: null,
+ _builder: null,
+
+ // Given a target node, get the context menu for it or its ancestor.
+ getContextMenu: function(aTarget) {
+ let target = aTarget;
+ while (target) {
+ let contextMenu = target.contextMenu;
+ if (contextMenu) {
+ return contextMenu;
+ }
+ target = target.parentNode;
+ }
+
+ return null;
+ },
+
+ // Given a target node, generate a JSON object for any context menu
+ // associated with it, or null if there is no context menu.
+ maybeBuild: function(aTarget) {
+ let pageMenu = this.getContextMenu(aTarget);
+ if (!pageMenu) {
+ return null;
+ }
+
+ pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
+ pageMenu.sendShowEvent();
+ // the show event is not cancelable, so no need to check a result here
+
+ this._builder = pageMenu.createBuilder();
+ if (!this._builder) {
+ return null;
+ }
+
+ pageMenu.build(this._builder);
+
+ // This serializes then parses again, however this could be avoided in
+ // the single-process case with further improvement.
+ let menuString = this._builder.toJSONString();
+ if (!menuString) {
+ return null;
+ }
+
+ return JSON.parse(menuString);
+ },
+
+ // Given a JSON menu object and popup, add the context menu to the popup.
+ buildAndAttachMenuWithObject: function(aMenu, aBrowser, aPopup) {
+ if (!aMenu) {
+ return false;
+ }
+
+ let insertionPoint = this.getInsertionPoint(aPopup);
+ if (!insertionPoint) {
+ return false;
+ }
+
+ let fragment = aPopup.ownerDocument.createDocumentFragment();
+ this.buildXULMenu(aMenu, fragment);
+
+ let pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
+ if (pos == "start") {
+ insertionPoint.insertBefore(fragment,
+ insertionPoint.firstChild);
+ } else if (pos.startsWith("#")) {
+ insertionPoint.insertBefore(fragment, insertionPoint.querySelector(pos));
+ } else {
+ insertionPoint.appendChild(fragment);
+ }
+
+ this._popup = aPopup;
+
+ this._popup.addEventListener("command", this);
+ this._popup.addEventListener("popuphidden", this);
+
+ return true;
+ },
+
+ // Construct the XUL menu structure for a given JSON object.
+ buildXULMenu: function(aNode, aElementForAppending) {
+ let document = aElementForAppending.ownerDocument;
+
+ let children = aNode.children;
+ for (let child of children) {
+ let menuitem;
+ switch (child.type) {
+ case "menuitem":
+ if (!child.id) {
+ continue; // Ignore children without ids
+ }
+
+ menuitem = document.createElement("menuitem");
+ if (child.checkbox) {
+ menuitem.setAttribute("type", "checkbox");
+ if (child.checked) {
+ menuitem.setAttribute("checked", "true");
+ }
+ }
+
+ if (child.label) {
+ menuitem.setAttribute("label", child.label);
+ }
+ if (child.icon) {
+ menuitem.setAttribute("image", child.icon);
+ menuitem.className = "menuitem-iconic";
+ }
+ if (child.disabled) {
+ menuitem.setAttribute("disabled", true);
+ }
+
+ break;
+
+ case "separator":
+ menuitem = document.createElement("menuseparator");
+ break;
+
+ case "menu":
+ menuitem = document.createElement("menu");
+ if (child.label) {
+ menuitem.setAttribute("label", child.label);
+ }
+
+ let menupopup = document.createElement("menupopup");
+ menuitem.appendChild(menupopup);
+
+ this.buildXULMenu(child, menupopup);
+ break;
+ }
+
+ menuitem.setAttribute(this.GENERATEDITEMID_ATTR, child.id ? child.id : 0);
+ aElementForAppending.appendChild(menuitem);
+ }
+ },
+
+ // Called when the generated menuitem is executed.
+ handleEvent: function(event) {
+ let type = event.type;
+ let target = event.target;
+ if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
+ // If a builder is assigned, call click on it directly. Otherwise, this is
+ // likely a menu with data from another process, so send a message to the
+ // browser to execute the menuitem.
+ if (this._builder) {
+ this._builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
+ }
+ } else if (type == "popuphidden" && this._popup == target) {
+ this.removeGeneratedContent(this._popup);
+
+ this._popup.removeEventListener("popuphidden", this);
+ this._popup.removeEventListener("command", this);
+
+ this._popup = null;
+ this._builder = null;
+ }
+ },
+
+ // Get the first child of the given element with the given tag name.
+ getImmediateChild: function(element, tag) {
+ let child = element.firstChild;
+ while (child) {
+ if (child.localName == tag) {
+ return child;
+ }
+ child = child.nextSibling;
+ }
+ return null;
+ },
+
+ // Return the location where the generated items should be inserted into the
+ // given popup. They should be inserted as the next sibling of the returned
+ // element.
+ getInsertionPoint: function(aPopup) {
+ if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
+ return aPopup;
+
+ let element = aPopup.firstChild;
+ while (element) {
+ if (element.localName == "menu") {
+ let popup = this.getImmediateChild(element, "menupopup");
+ if (popup) {
+ let result = this.getInsertionPoint(popup);
+ if (result) {
+ return result;
+ }
+ }
+ }
+ element = element.nextSibling;
+ }
+
+ return null;
+ },
+
+ // Returns true if custom menu items were present.
+ maybeBuildAndAttachMenu: function(aTarget, aPopup) {
+ let menuObject = this.maybeBuild(aTarget);
+ if (!menuObject) {
+ return false;
+ }
+
+ return this.buildAndAttachMenuWithObject(menuObject, null, aPopup);
+ },
+
+ // Remove the generated content from the given popup.
+ removeGeneratedContent: function(aPopup) {
+ let ungenerated = [];
+ ungenerated.push(aPopup);
+
+ let count;
+ while (0 != (count = ungenerated.length)) {
+ let last = count - 1;
+ let element = ungenerated[last];
+ ungenerated.splice(last, 1);
+
+ let i = element.childNodes.length;
+ while (i-- > 0) {
+ let child = element.childNodes[i];
+ if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
+ ungenerated.push(child);
+ continue;
+ }
+ element.removeChild(child);
+ }
+ }
+ }
+}
diff --git a/modules/PopupNotifications.jsm b/modules/PopupNotifications.jsm
new file mode 100644
index 0000000..0cb9702
--- /dev/null
+++ b/modules/PopupNotifications.jsm
@@ -0,0 +1,994 @@
+/* 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.EXPORTED_SYMBOLS = ["PopupNotifications"];
+
+var Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const NOTIFICATION_EVENT_DISMISSED = "dismissed";
+const NOTIFICATION_EVENT_REMOVED = "removed";
+const NOTIFICATION_EVENT_SHOWING = "showing";
+const NOTIFICATION_EVENT_SHOWN = "shown";
+const NOTIFICATION_EVENT_SWAPPING = "swapping";
+
+const ICON_SELECTOR = ".notification-anchor-icon";
+const ICON_ATTRIBUTE_SHOWING = "showing";
+
+const PREF_SECURITY_DELAY = "security.notification_enable_delay";
+
+var popupNotificationsMap = new WeakMap();
+var gNotificationParents = new WeakMap;
+
+function getAnchorFromBrowser(aBrowser) {
+ let anchor = aBrowser.getAttribute("popupnotificationanchor") ||
+ aBrowser.popupnotificationanchor;
+ if (anchor) {
+ if (anchor instanceof Ci.nsIDOMXULElement) {
+ return anchor;
+ }
+ return aBrowser.ownerDocument.getElementById(anchor);
+ }
+ return null;
+}
+
+function getNotificationFromElement(aElement) {
+ // Need to find the associated notification object, which is a bit tricky
+ // since it isn't associated with the element directly - this is kind of
+ // gross and very dependent on the structure of the popupnotification
+ // binding's content.
+ let notificationEl;
+ let parent = aElement;
+ while (parent && (parent = aElement.ownerDocument.getBindingParent(parent)))
+ notificationEl = parent;
+ return notificationEl;
+}
+
+/**
+ * Notification object describes a single popup notification.
+ *
+ * @see PopupNotifications.show()
+ */
+function Notification(id, message, anchorID, mainAction, secondaryActions,
+ browser, owner, options) {
+ this.id = id;
+ this.message = message;
+ this.anchorID = anchorID;
+ this.mainAction = mainAction;
+ this.secondaryActions = secondaryActions || [];
+ this.browser = browser;
+ this.owner = owner;
+ this.options = options || {};
+}
+
+Notification.prototype = {
+
+ id: null,
+ message: null,
+ anchorID: null,
+ mainAction: null,
+ secondaryActions: null,
+ browser: null,
+ owner: null,
+ options: null,
+ timeShown: null,
+
+ /**
+ * Removes the notification and updates the popup accordingly if needed.
+ */
+ remove: function Notification_remove() {
+ this.owner.remove(this);
+ },
+
+ get anchorElement() {
+ let iconBox = this.owner.iconBox;
+
+ let anchorElement = getAnchorFromBrowser(this.browser);
+
+ if (!iconBox)
+ return anchorElement;
+
+ if (!anchorElement && this.anchorID)
+ anchorElement = iconBox.querySelector("#"+this.anchorID);
+
+ // Use a default anchor icon if it's available
+ if (!anchorElement)
+ anchorElement = iconBox.querySelector("#default-notification-icon") ||
+ iconBox;
+
+ return anchorElement;
+ },
+
+ reshow: function() {
+ this.owner._reshowNotifications(this.anchorElement, this.browser);
+ }
+};
+
+/**
+ * The PopupNotifications object manages popup notifications for a given browser
+ * window.
+ * @param tabbrowser
+ * window's . Used to observe tab switching events and
+ * for determining the active browser element.
+ * @param panel
+ * The element to use for notifications. The panel is
+ * populated with children and displayed it as
+ * needed.
+ * @param iconBox
+ * Reference to a container element that should be hidden or
+ * unhidden when notifications are hidden or shown. It should be the
+ * parent of anchor elements whose IDs are passed to show().
+ * It is used as a fallback popup anchor if notifications specify
+ * invalid or non-existent anchor IDs.
+ */
+this.PopupNotifications = function PopupNotifications(tabbrowser, panel, iconBox) {
+ if (!(tabbrowser instanceof Ci.nsIDOMXULElement))
+ throw "Invalid tabbrowser";
+ if (iconBox && !(iconBox instanceof Ci.nsIDOMXULElement))
+ throw "Invalid iconBox";
+ if (!(panel instanceof Ci.nsIDOMXULElement))
+ throw "Invalid panel";
+
+ this.window = tabbrowser.ownerDocument.defaultView;
+ this.panel = panel;
+ this.tabbrowser = tabbrowser;
+ this.iconBox = iconBox;
+ this.buttonDelay = Services.prefs.getIntPref(PREF_SECURITY_DELAY);
+
+ this.panel.addEventListener("popuphidden", this, true);
+
+ this.window.addEventListener("activate", this, true);
+ if (this.tabbrowser.tabContainer)
+ this.tabbrowser.tabContainer.addEventListener("TabSelect", this, true);
+}
+
+PopupNotifications.prototype = {
+
+ window: null,
+ panel: null,
+ tabbrowser: null,
+
+ _iconBox: null,
+ set iconBox(iconBox) {
+ // Remove the listeners on the old iconBox, if needed
+ if (this._iconBox) {
+ this._iconBox.removeEventListener("click", this, false);
+ this._iconBox.removeEventListener("keypress", this, false);
+ }
+ this._iconBox = iconBox;
+ if (iconBox) {
+ iconBox.addEventListener("click", this, false);
+ iconBox.addEventListener("keypress", this, false);
+ }
+ },
+ get iconBox() {
+ return this._iconBox;
+ },
+
+ /**
+ * Retrieve a Notification object associated with the browser/ID pair.
+ * @param id
+ * The Notification ID to search for.
+ * @param browser
+ * The browser whose notifications should be searched. If null, the
+ * currently selected browser's notifications will be searched.
+ *
+ * @returns the corresponding Notification object, or null if no such
+ * notification exists.
+ */
+ getNotification: function PopupNotifications_getNotification(id, browser) {
+ let n = null;
+ let notifications = this._getNotificationsForBrowser(browser || this.tabbrowser.selectedBrowser);
+ notifications.some(function(x) x.id == id && (n = x));
+ return n;
+ },
+
+ /**
+ * Adds a new popup notification.
+ * @param browser
+ * The element associated with the notification. Must not
+ * be null.
+ * @param id
+ * A unique ID that identifies the type of notification (e.g.
+ * "geolocation"). Only one notification with a given ID can be visible
+ * at a time. If a notification already exists with the given ID, it
+ * will be replaced.
+ * @param message
+ * The text to be displayed in the notification.
+ * @param anchorID
+ * The ID of the element that should be used as this notification
+ * popup's anchor. May be null, in which case the notification will be
+ * anchored to the iconBox.
+ * @param mainAction
+ * A JavaScript object literal describing the notification button's
+ * action. If present, it must have the following properties:
+ * - label (string): the button's label.
+ * - accessKey (string): the button's accessKey.
+ * - callback (function): a callback to be invoked when the button is
+ * pressed, is passed an object that contains the following fields:
+ * - checkboxChecked: (boolean) If the optional checkbox is checked.
+ * If null, the notification will not have a button, and
+ * secondaryActions will be ignored.
+ * @param secondaryActions
+ * An optional JavaScript array describing the notification's alternate
+ * actions. The array should contain objects with the same properties
+ * as mainAction. These are used to populate the notification button's
+ * dropdown menu.
+ * @param options
+ * An options JavaScript object holding additional properties for the
+ * notification. The following properties are currently supported:
+ * persistence: An integer. The notification will not automatically
+ * dismiss for this many page loads.
+ * timeout: A time in milliseconds. The notification will not
+ * automatically dismiss before this time.
+ * persistWhileVisible:
+ * A boolean. If true, a visible notification will always
+ * persist across location changes.
+ * dismissed: Whether the notification should be added as a dismissed
+ * notification. Dismissed notifications can be activated
+ * by clicking on their anchorElement.
+ * eventCallback:
+ * Callback to be invoked when the notification changes
+ * state. The callback's first argument is a string
+ * identifying the state change:
+ * "dismissed": notification has been dismissed by the
+ * user (e.g. by clicking away or switching
+ * tabs)
+ * "removed": notification has been removed (due to
+ * location change or user action)
+ * "showing": notification is about to be shown
+ * (this can be fired multiple times as
+ * notifications are dismissed and re-shown)
+ * "shown": notification has been shown (this can be fired
+ * multiple times as notifications are dismissed
+ * and re-shown)
+ * "swapping": the docshell of the browser that created
+ * the notification is about to be swapped to
+ * another browser. A second parameter contains
+ * the browser that is receiving the docshell,
+ * so that the event callback can transfer stuff
+ * specific to this notification.
+ * If the callback returns true, the notification
+ * will be moved to the new browser.
+ * If the callback isn't implemented, returns false,
+ * or doesn't return any value, the notification
+ * will be removed.
+ * neverShow: Indicate that no popup should be shown for this
+ * notification. Useful for just showing the anchor icon.
+ * removeOnDismissal:
+ * Notifications with this parameter set to true will be
+ * removed when they would have otherwise been dismissed
+ * (i.e. any time the popup is closed due to user
+ * interaction).
+ * checkbox: An object that allows you to add a checkbox and
+ * control its behavior with these fields:
+ * label:
+ * (required) Label to be shown next to the checkbox.
+ * checked:
+ * (optional) Whether the checkbox should be checked
+ * by default. Defaults to false.
+ * checkedState:
+ * (optional) An object that allows you to customize
+ * the notification state when the checkbox is checked.
+ * disableMainAction:
+ * (optional) Whether the mainAction is disabled.
+ * Defaults to false.
+ * warningLabel:
+ * (optional) A (warning) text that is shown below the
+ * checkbox. Pass null to hide.
+ * uncheckedState:
+ * (optional) An object that allows you to customize
+ * the notification state when the checkbox is not checked.
+ * Has the same attributes as checkedState.
+ * popupIconURL:
+ * A string. URL of the image to be displayed in the popup.
+ * Normally specified in CSS using list-style-image and the
+ * .popup-notification-icon[popupid=...] selector.
+ * learnMoreURL:
+ * A string URL. Setting this property will make the
+ * prompt display a "Learn More" link that, when clicked,
+ * opens the URL in a new tab.
+ * @returns the Notification object corresponding to the added notification.
+ */
+ show: function PopupNotifications_show(browser, id, message, anchorID,
+ mainAction, secondaryActions, options) {
+ function isInvalidAction(a) {
+ return !a || !(typeof(a.callback) == "function") || !a.label || !a.accessKey;
+ }
+
+ if (!browser)
+ throw "PopupNotifications_show: invalid browser";
+ if (!id)
+ throw "PopupNotifications_show: invalid ID";
+ if (mainAction && isInvalidAction(mainAction))
+ throw "PopupNotifications_show: invalid mainAction";
+ if (secondaryActions && secondaryActions.some(isInvalidAction))
+ throw "PopupNotifications_show: invalid secondaryActions";
+
+ let notification = new Notification(id, message, anchorID, mainAction,
+ secondaryActions, browser, this, options);
+
+ if (options && options.dismissed)
+ notification.dismissed = true;
+
+ let existingNotification = this.getNotification(id, browser);
+ if (existingNotification)
+ this._remove(existingNotification);
+
+ let notifications = this._getNotificationsForBrowser(browser);
+ notifications.push(notification);
+
+ let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
+ if (browser.docShell.isActive && fm.activeWindow == this.window) {
+ // show panel now
+ this._update(notifications, notification.anchorElement, true);
+ } else {
+ // Otherwise, update() will display the notification the next time the
+ // relevant tab/window is selected.
+
+ // If the tab is selected but the window is in the background, let the OS
+ // tell the user that there's a notification waiting in that window.
+ // At some point we might want to do something about background tabs here
+ // too. When the user switches to this window, we'll show the panel if
+ // this browser is a tab (thus showing the anchor icon). For
+ // non-tabbrowser browsers, we need to make the icon visible now or the
+ // user will not be able to open the panel.
+ if (!notification.dismissed && browser.docShell.isActive) {
+ this.window.getAttention();
+ if (notification.anchorElement.parentNode != this.iconBox) {
+ notification.anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
+ }
+ }
+
+ // Notify observers that we're not showing the popup (useful for testing)
+ this._notify("backgroundShow");
+ }
+
+ return notification;
+ },
+
+ /**
+ * Returns true if the notification popup is currently being displayed.
+ */
+ get isPanelOpen() {
+ let panelState = this.panel.state;
+
+ return panelState == "showing" || panelState == "open";
+ },
+
+ /**
+ * Called by the consumer to indicate that a browser's location has changed,
+ * so that we can update the active notifications accordingly.
+ */
+ locationChange: function PopupNotifications_locationChange(aBrowser) {
+ if (!aBrowser)
+ throw "PopupNotifications_locationChange: invalid browser";
+
+ let notifications = this._getNotificationsForBrowser(aBrowser);
+
+ notifications = notifications.filter(function (notification) {
+ // The persistWhileVisible option allows an open notification to persist
+ // across location changes
+ if (notification.options.persistWhileVisible &&
+ this.isPanelOpen) {
+ if ("persistence" in notification.options &&
+ notification.options.persistence)
+ notification.options.persistence--;
+ return true;
+ }
+
+ // The persistence option allows a notification to persist across multiple
+ // page loads
+ if ("persistence" in notification.options &&
+ notification.options.persistence) {
+ notification.options.persistence--;
+ return true;
+ }
+
+ // The timeout option allows a notification to persist until a certain time
+ if ("timeout" in notification.options &&
+ Date.now() <= notification.options.timeout) {
+ return true;
+ }
+
+ this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
+ return false;
+ }, this);
+
+ this._setNotificationsForBrowser(aBrowser, notifications);
+
+ if (aBrowser.docShell.isActive) {
+ // get the anchor element if the browser has defined one so it will
+ // _update will handle both the tabs iconBox and non-tab permission
+ // anchors.
+ let anchorElement = notifications.length > 0 ? notifications[0].anchorElement : null;
+ if (!anchorElement)
+ anchorElement = getAnchorFromBrowser(aBrowser);
+ this._update(notifications, anchorElement);
+ }
+ },
+
+ /**
+ * Removes a Notification.
+ * @param notification
+ * The Notification object to remove.
+ */
+ remove: function PopupNotifications_remove(notification) {
+ this._remove(notification);
+
+ if (notification.browser.docShell.isActive) {
+ let notifications = this._getNotificationsForBrowser(notification.browser);
+ this._update(notifications, notification.anchorElement);
+ }
+ },
+
+ handleEvent: function (aEvent) {
+ switch (aEvent.type) {
+ case "popuphidden":
+ this._onPopupHidden(aEvent);
+ break;
+ case "activate":
+ case "TabSelect":
+ let self = this;
+ // setTimeout(..., 0) needed, otherwise openPopup from "activate" event
+ // handler results in the popup being hidden again for some reason...
+ this.window.setTimeout(function () {
+ self._update();
+ }, 0);
+ break;
+ case "click":
+ case "keypress":
+ this._onIconBoxCommand(aEvent);
+ break;
+ }
+ },
+
+////////////////////////////////////////////////////////////////////////////////
+// Utility methods
+////////////////////////////////////////////////////////////////////////////////
+
+ _ignoreDismissal: null,
+ _currentAnchorElement: null,
+
+ /**
+ * Gets notifications for the currently selected browser.
+ */
+ get _currentNotifications() {
+ return this.tabbrowser.selectedBrowser ? this._getNotificationsForBrowser(this.tabbrowser.selectedBrowser) : [];
+ },
+
+ _remove: function PopupNotifications_removeHelper(notification) {
+ // This notification may already be removed, in which case let's just fail
+ // silently.
+ let notifications = this._getNotificationsForBrowser(notification.browser);
+ if (!notifications)
+ return;
+
+ var index = notifications.indexOf(notification);
+ if (index == -1)
+ return;
+
+ if (notification.browser.docShell.isActive)
+ notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
+
+ // remove the notification
+ notifications.splice(index, 1);
+ this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
+ },
+
+ /**
+ * Dismisses the notification without removing it.
+ */
+ _dismiss: function PopupNotifications_dismiss() {
+ let browser = this.panel.firstChild &&
+ this.panel.firstChild.notification.browser;
+ if (typeof this.panel.hidePopup === "function") {
+ this.panel.hidePopup();
+ }
+ if (browser)
+ browser.focus();
+ },
+
+ /**
+ * Hides the notification popup.
+ */
+ _hidePanel: function PopupNotifications_hide() {
+ this._ignoreDismissal = true;
+ if (typeof this.panel.hidePopup === "function") {
+ this.panel.hidePopup();
+ }
+ this._ignoreDismissal = false;
+ },
+
+ /**
+ * Removes all notifications from the notification popup.
+ */
+ _clearPanel: function () {
+ let popupnotification;
+ while ((popupnotification = this.panel.lastChild)) {
+ this.panel.removeChild(popupnotification);
+
+ // If this notification was provided by the chrome document rather than
+ // created ad hoc, move it back to where we got it from.
+ let originalParent = gNotificationParents.get(popupnotification);
+ if (originalParent) {
+ popupnotification.notification = null;
+
+ // Remove nodes dynamically added to the notification's menu button
+ // in _refreshPanel. Keep popupnotificationcontent nodes; they are
+ // provided by the chrome document.
+ let contentNode = popupnotification.lastChild;
+ while (contentNode) {
+ let previousSibling = contentNode.previousSibling;
+ if (contentNode.nodeName != "popupnotificationcontent")
+ popupnotification.removeChild(contentNode);
+ contentNode = previousSibling;
+ }
+
+ // Re-hide the notification such that it isn't rendered in the chrome
+ // document. _refreshPanel will unhide it again when needed.
+ popupnotification.hidden = true;
+
+ originalParent.appendChild(popupnotification);
+ }
+ }
+ },
+
+ _refreshPanel: function PopupNotifications_refreshPanel(notificationsToShow) {
+ this._clearPanel();
+
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ notificationsToShow.forEach(function (n) {
+ let doc = this.window.document;
+
+ // Append "-notification" to the ID to try to avoid ID conflicts with other stuff
+ // in the document.
+ let popupnotificationID = n.id + "-notification";
+
+ // If the chrome document provides a popupnotification with this id, use
+ // that. Otherwise create it ad-hoc.
+ let popupnotification = doc.getElementById(popupnotificationID);
+ if (popupnotification)
+ gNotificationParents.set(popupnotification, popupnotification.parentNode);
+ else
+ popupnotification = doc.createElementNS(XUL_NS, "popupnotification");
+
+ popupnotification.setAttribute("label", n.message);
+ popupnotification.setAttribute("id", popupnotificationID);
+ popupnotification.setAttribute("popupid", n.id);
+ popupnotification.setAttribute("closebuttoncommand", "PopupNotifications._dismiss();");
+ if (n.mainAction) {
+ popupnotification.setAttribute("buttonlabel", n.mainAction.label);
+ popupnotification.setAttribute("buttonaccesskey", n.mainAction.accessKey);
+ popupnotification.setAttribute("buttoncommand", "PopupNotifications._onButtonCommand(event);");
+ popupnotification.setAttribute("menucommand", "PopupNotifications._onMenuCommand(event);");
+ popupnotification.setAttribute("closeitemcommand", "PopupNotifications._dismiss();event.stopPropagation();");
+ } else {
+ popupnotification.removeAttribute("buttonlabel");
+ popupnotification.removeAttribute("buttonaccesskey");
+ popupnotification.removeAttribute("buttoncommand");
+ popupnotification.removeAttribute("menucommand");
+ popupnotification.removeAttribute("closeitemcommand");
+ }
+
+ if (n.options.popupIconURL)
+ popupnotification.setAttribute("icon", n.options.popupIconURL);
+ if (n.options.learnMoreURL)
+ popupnotification.setAttribute("learnmoreurl", n.options.learnMoreURL);
+ else
+ popupnotification.removeAttribute("learnmoreurl");
+
+ popupnotification.notification = n;
+
+ if (n.secondaryActions) {
+ n.secondaryActions.forEach(function (a) {
+ let item = doc.createElementNS(XUL_NS, "menuitem");
+ item.setAttribute("label", a.label);
+ item.setAttribute("accesskey", a.accessKey);
+ item.notification = n;
+ item.action = a;
+
+ popupnotification.appendChild(item);
+ }, this);
+
+ if (n.secondaryActions.length) {
+ let closeItemSeparator = doc.createElementNS(XUL_NS, "menuseparator");
+ popupnotification.appendChild(closeItemSeparator);
+ }
+ }
+
+ let checkbox = n.options.checkbox;
+ if (checkbox && checkbox.label) {
+ let checked = n._checkboxChecked != null ? n._checkboxChecked : !!checkbox.checked;
+
+ popupnotification.setAttribute("checkboxhidden", "false");
+ popupnotification.setAttribute("checkboxchecked", checked);
+ popupnotification.setAttribute("checkboxlabel", checkbox.label);
+
+ popupnotification.setAttribute("checkboxcommand", "PopupNotifications._onCheckboxCommand(event);");
+
+ if (checked) {
+ this._setNotificationUIState(popupnotification, checkbox.checkedState);
+ } else {
+ this._setNotificationUIState(popupnotification, checkbox.uncheckedState);
+ }
+ } else {
+ popupnotification.setAttribute("checkboxhidden", "true");
+ }
+
+ this.panel.appendChild(popupnotification);
+
+ // The popupnotification may be hidden if we got it from the chrome
+ // document rather than creating it ad hoc.
+ popupnotification.hidden = false;
+ }, this);
+ },
+
+ _setNotificationUIState(notification, state={}) {
+ notification.setAttribute("mainactiondisabled", state.disableMainAction || "false");
+
+ if (state.warningLabel) {
+ notification.setAttribute("warninglabel", state.warningLabel);
+ notification.setAttribute("warninghidden", "false");
+ } else {
+ notification.setAttribute("warninghidden", "true");
+ }
+ },
+
+ _onCheckboxCommand(event) {
+ let notificationEl = getNotificationFromElement(event.originalTarget);
+ let checked = notificationEl.checkbox.checked;
+ let notification = notificationEl.notification;
+
+ // Save checkbox state to be able to persist it when re-opening the doorhanger.
+ notification._checkboxChecked = checked;
+
+ if (checked) {
+ this._setNotificationUIState(notificationEl, notification.options.checkbox.checkedState);
+ } else {
+ this._setNotificationUIState(notificationEl, notification.options.checkbox.uncheckedState);
+ }
+ },
+
+ _showPanel: function PopupNotifications_showPanel(notificationsToShow, anchorElement) {
+ this.panel.hidden = false;
+
+ notificationsToShow.forEach(function (n) {
+ this._fireCallback(n, NOTIFICATION_EVENT_SHOWING);
+ }, this);
+ this._refreshPanel(notificationsToShow);
+
+ if (this.isPanelOpen && this._currentAnchorElement == anchorElement)
+ return;
+
+ // If the panel is already open but we're changing anchors, we need to hide
+ // it first. Otherwise it can appear in the wrong spot. (_hidePanel is
+ // safe to call even if the panel is already hidden.)
+ this._hidePanel();
+
+ // If the anchor element is hidden or null, use the tab as the anchor. We
+ // only ever show notifications for the current browser, so we can just use
+ // the current tab.
+ let selectedTab = this.tabbrowser.selectedTab;
+ if (anchorElement) {
+ let bo = anchorElement.boxObject;
+ if (bo.height == 0 && bo.width == 0)
+ anchorElement = selectedTab; // hidden
+ } else {
+ anchorElement = selectedTab; // null
+ }
+
+ this._currentAnchorElement = anchorElement;
+
+ // On OS X and Linux we need a different panel arrow color for
+ // click-to-play plugins, so copy the popupid and use css.
+ this.panel.setAttribute("popupid", this.panel.firstChild.getAttribute("popupid"));
+ notificationsToShow.forEach(function (n) {
+ // Remember the time the notification was shown for the security delay.
+ n.timeShown = this.window.performance.now();
+ }, this);
+ this.panel.openPopup(anchorElement, "bottomcenter topleft");
+ notificationsToShow.forEach(function (n) {
+ this._fireCallback(n, NOTIFICATION_EVENT_SHOWN);
+ }, this);
+ },
+
+ /**
+ * Updates the notification state in response to window activation or tab
+ * selection changes.
+ *
+ * @param notifications an array of Notification instances. if null,
+ * notifications will be retrieved off the current
+ * browser tab
+ * @param anchor is a XUL element that the notifications panel will be
+ * anchored to
+ * @param dismissShowing if true, dismiss any currently visible notifications
+ * if there are no notifications to show. Otherwise,
+ * currently displayed notifications will be left alone.
+ */
+ _update: function PopupNotifications_update(notifications, anchor, dismissShowing = false) {
+ let useIconBox = this.iconBox && (!anchor || anchor.parentNode == this.iconBox);
+ if (useIconBox) {
+ // hide icons of the previous tab.
+ this._hideIcons();
+ }
+
+ let anchorElement = anchor, notificationsToShow = [];
+ if (!notifications)
+ notifications = this._currentNotifications;
+ let haveNotifications = notifications.length > 0;
+ if (haveNotifications) {
+ // Only show the notifications that have the passed-in anchor (or the
+ // first notification's anchor, if none was passed in). Other
+ // notifications will be shown once these are dismissed.
+ anchorElement = anchor || notifications[0].anchorElement;
+
+ if (useIconBox) {
+ this._showIcons(notifications);
+ this.iconBox.hidden = false;
+ } else if (anchorElement) {
+ anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
+ // use the anchorID as a class along with the default icon class as a
+ // fallback if anchorID is not defined in CSS. We always use the first
+ // notifications icon, so in the case of multiple notifications we'll
+ // only use the default icon
+ if (anchorElement.classList.contains("notification-anchor-icon")) {
+ // remove previous icon classes
+ let className = anchorElement.className.replace(/([-\w]+-notification-icon\s?)/g,"")
+ className = "default-notification-icon " + className;
+ if (notifications.length == 1) {
+ className = notifications[0].anchorID + " " + className;
+ }
+ anchorElement.className = className;
+ }
+ }
+
+ // Also filter out notifications that have been dismissed.
+ notificationsToShow = notifications.filter(function (n) {
+ return !n.dismissed && n.anchorElement == anchorElement &&
+ !n.options.neverShow;
+ });
+ }
+
+ if (notificationsToShow.length > 0) {
+ this._showPanel(notificationsToShow, anchorElement);
+ } else {
+ // Notify observers that we're not showing the popup (useful for testing)
+ this._notify("updateNotShowing");
+
+ // Close the panel if there are no notifications to show.
+ // When called from PopupNotifications.show() we should never close the
+ // panel, however. It may just be adding a dismissed notification, in
+ // which case we want to continue showing any existing notifications.
+ if (!dismissShowing)
+ this._dismiss();
+
+ // Only hide the iconBox if we actually have no notifications (as opposed
+ // to not having any showable notifications)
+ if (!haveNotifications) {
+ if (useIconBox)
+ this.iconBox.hidden = true;
+ else if (anchorElement)
+ anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
+ }
+ }
+ },
+
+ _showIcons: function PopupNotifications_showIcons(aCurrentNotifications) {
+ for (let notification of aCurrentNotifications) {
+ let anchorElm = notification.anchorElement;
+ if (anchorElm) {
+ anchorElm.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
+ }
+ }
+ },
+
+ _hideIcons: function PopupNotifications_hideIcons() {
+ let icons = this.iconBox.querySelectorAll(ICON_SELECTOR);
+ for (let icon of icons) {
+ icon.removeAttribute(ICON_ATTRIBUTE_SHOWING);
+ }
+ },
+
+ /**
+ * Gets and sets notifications for the browser.
+ */
+ _getNotificationsForBrowser: function PopupNotifications_getNotifications(browser) {
+ let notifications = popupNotificationsMap.get(browser);
+ if (!notifications) {
+ // Initialize the WeakMap for the browser so callers can reference/manipulate the array.
+ notifications = [];
+ popupNotificationsMap.set(browser, notifications);
+ }
+ return notifications;
+ },
+ _setNotificationsForBrowser: function PopupNotifications_setNotifications(browser, notifications) {
+ popupNotificationsMap.set(browser, notifications);
+ return notifications;
+ },
+
+ _onIconBoxCommand: function PopupNotifications_onIconBoxCommand(event) {
+ // Left click, space or enter only
+ let type = event.type;
+ if (type == "click" && event.button != 0)
+ return;
+
+ if (type == "keypress" &&
+ !(event.charCode == Ci.nsIDOMKeyEvent.DOM_VK_SPACE ||
+ event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN))
+ return;
+
+ if (this._currentNotifications.length == 0)
+ return;
+
+ // Get the anchor that is the immediate child of the icon box
+ let anchor = event.target;
+ while (anchor && anchor.parentNode != this.iconBox)
+ anchor = anchor.parentNode;
+
+ this._reshowNotifications(anchor);
+ },
+
+ _reshowNotifications: function PopupNotifications_reshowNotifications(anchor, browser) {
+ // Mark notifications anchored to this anchor as un-dismissed
+ let notifications = this._getNotificationsForBrowser(browser || this.tabbrowser.selectedBrowser);
+ notifications.forEach(function (n) {
+ if (n.anchorElement == anchor)
+ n.dismissed = false;
+ });
+
+ // ...and then show them.
+ this._update(notifications, anchor);
+ },
+
+ _swapBrowserNotifications: function PopupNotifications_swapBrowserNoficications(ourBrowser, otherBrowser) {
+ // When swaping browser docshells (e.g. dragging tab to new window) we need
+ // to update our notification map.
+
+ let ourNotifications = this._getNotificationsForBrowser(ourBrowser);
+ let other = otherBrowser.ownerDocument.defaultView.PopupNotifications;
+ if (!other) {
+ if (ourNotifications.length > 0)
+ Cu.reportError("unable to swap notifications: otherBrowser doesn't support notifications");
+ return;
+ }
+ let otherNotifications = other._getNotificationsForBrowser(otherBrowser);
+ if (ourNotifications.length < 1 && otherNotifications.length < 1) {
+ // No notification to swap.
+ return;
+ }
+
+ otherNotifications = otherNotifications.filter(n => {
+ if (this._fireCallback(n, NOTIFICATION_EVENT_SWAPPING, ourBrowser)) {
+ n.browser = ourBrowser;
+ n.owner = this;
+ return true;
+ }
+ other._fireCallback(n, NOTIFICATION_EVENT_REMOVED);
+ return false;
+ });
+
+ ourNotifications = ourNotifications.filter(n => {
+ if (this._fireCallback(n, NOTIFICATION_EVENT_SWAPPING, otherBrowser)) {
+ n.browser = otherBrowser;
+ n.owner = other;
+ return true;
+ }
+ this._fireCallback(n, NOTIFICATION_EVENT_REMOVED);
+ return false;
+ });
+
+ this._setNotificationsForBrowser(otherBrowser, ourNotifications);
+ other._setNotificationsForBrowser(ourBrowser, otherNotifications);
+
+ if (otherNotifications.length > 0)
+ this._update(otherNotifications, otherNotifications[0].anchorElement);
+ if (ourNotifications.length > 0)
+ other._update(ourNotifications, ourNotifications[0].anchorElement);
+ },
+
+ _fireCallback: function PopupNotifications_fireCallback(n, event, ...args) {
+ try {
+ if (n.options.eventCallback)
+ return n.options.eventCallback.call(n, event, ...args);
+ } catch (error) {
+ Cu.reportError(error);
+ }
+ return undefined;
+ },
+
+ _onPopupHidden: function PopupNotifications_onPopupHidden(event) {
+ if (event.target != this.panel || this._ignoreDismissal)
+ return;
+
+ let browser = this.panel.firstChild &&
+ this.panel.firstChild.notification.browser;
+ if (!browser)
+ return;
+
+ let notifications = this._getNotificationsForBrowser(browser);
+ // Mark notifications as dismissed and call dismissal callbacks
+ Array.forEach(this.panel.childNodes, function (nEl) {
+ let notificationObj = nEl.notification;
+ // Never call a dismissal handler on a notification that's been removed.
+ if (notifications.indexOf(notificationObj) == -1)
+ return;
+
+ // Do not mark the notification as dismissed or fire NOTIFICATION_EVENT_DISMISSED
+ // if the notification is removed.
+ if (notificationObj.options.removeOnDismissal)
+ this._remove(notificationObj);
+ else {
+ notificationObj.dismissed = true;
+ this._fireCallback(notificationObj, NOTIFICATION_EVENT_DISMISSED);
+ }
+ }, this);
+
+ this._clearPanel();
+
+ this._update();
+ },
+
+ _onButtonCommand: function PopupNotifications_onButtonCommand(event) {
+ let notificationEl = getNotificationFromElement(event.originalTarget);
+
+ if (!notificationEl)
+ throw "PopupNotifications_onButtonCommand: couldn't find notification element";
+
+ if (!notificationEl.notification)
+ throw "PopupNotifications_onButtonCommand: couldn't find notification";
+
+ let notification = notificationEl.notification;
+ let timeSinceShown = this.window.performance.now() - notification.timeShown;
+
+ // Only report the first time mainAction is triggered and remember that this occurred.
+ if (!notification.timeMainActionFirstTriggered) {
+ notification.timeMainActionFirstTriggered = timeSinceShown;
+ }
+
+ if (timeSinceShown < this.buttonDelay) {
+ Services.console.logStringMessage("PopupNotifications_onButtonCommand: " +
+ "Button click happened before the security delay: " +
+ timeSinceShown + "ms");
+ return;
+ }
+
+ try {
+ notification.mainAction.callback.call(undefined, {
+ checkboxChecked: notificationEl.checkbox.checked
+ });
+ } catch (error) {
+ Cu.reportError(error);
+ }
+
+ this._remove(notification);
+ this._update();
+ },
+
+ _onMenuCommand: function PopupNotifications_onMenuCommand(event) {
+ let target = event.originalTarget;
+ if (!target.action || !target.notification)
+ throw "menucommand target has no associated action/notification";
+
+ let notificationEl = target.parentElement;
+ event.stopPropagation();
+
+ try {
+ target.action.callback.call(undefined, {
+ checkboxChecked: notificationEl.checkbox.checked
+ });
+ } catch (error) {
+ Cu.reportError(error);
+ }
+
+ this._remove(target.notification);
+ this._update();
+ },
+
+ _notify: function PopupNotifications_notify(topic) {
+ Services.obs.notifyObservers(null, "PopupNotifications-" + topic, "");
+ },
+};
diff --git a/modules/QuotaManager.jsm b/modules/QuotaManager.jsm
new file mode 100644
index 0000000..48cfe88
--- /dev/null
+++ b/modules/QuotaManager.jsm
@@ -0,0 +1,51 @@
+/* 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.EXPORTED_SYMBOLS = ["QuotaManagerHelper"];
+
+Components.utils.import('resource://gre/modules/Services.jsm');
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+
+this.QuotaManagerHelper = {
+ clear: function(isShutDown) {
+ try {
+ var stord = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ stord.append("storage");
+ if (stord.exists() && stord.isDirectory()) {
+ var doms = {};
+ for (var stor of ["default", "permanent", "temporary"]) {
+ var storsubd = stord.clone();
+ storsubd.append(stor);
+ if (storsubd.exists() && storsubd.isDirectory()) {
+ var entries = storsubd.directoryEntries;
+ while(entries.hasMoreElements()) {
+ var host, entry = entries.getNext();
+ entry.QueryInterface(Ci.nsIFile);
+ if ((host = /^(https?|file)\+\+\+(.+)$/.exec(entry.leafName)) !== null) {
+ if (isShutDown) {
+ entry.remove(true);
+ } else {
+ doms[host[1] + "://" + host[2]] = true;
+ }
+ }
+ }
+ }
+ }
+ var qm = Cc["@mozilla.org/dom/quota-manager-service;1"]
+ .getService(Ci.nsIQuotaManagerService);
+ for (var dom in doms) {
+ var uri = Services.io.newURI(dom, null, null);
+ let principal = Services.scriptSecurityManager
+ .createCodebasePrincipal(uri, {});
+ qm.clearStoragesForPrincipal(principal);
+ }
+ }
+ } catch(er) {
+ Cu.reportError(er);
+ }
+ }
+};
diff --git a/modules/RecentWindow.jsm b/modules/RecentWindow.jsm
new file mode 100644
index 0000000..0018b50
--- /dev/null
+++ b/modules/RecentWindow.jsm
@@ -0,0 +1,68 @@
+/* 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 = ["RecentWindow"];
+
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+#ifndef XP_WIN
+#define BROKEN_WM_Z_ORDER
+#endif
+
+this.RecentWindow = {
+ /*
+ * Get the most recent browser window.
+ *
+ * @param aOptions an object accepting the arguments for the search.
+ * * private: true to restrict the search to private windows
+ * only, false to restrict the search to non-private only.
+ * Omit the property to search in both groups.
+ * * allowPopups: true if popup windows are permissable.
+ */
+ getMostRecentBrowserWindow: function RW_getMostRecentBrowserWindow(aOptions) {
+ let checkPrivacy = typeof aOptions == "object" &&
+ "private" in aOptions;
+
+ let allowPopups = typeof aOptions == "object" && !!aOptions.allowPopups;
+
+ function isSuitableBrowserWindow(win) {
+ return (!win.closed &&
+ (allowPopups || win.toolbar.visible) &&
+ (!checkPrivacy ||
+ PrivateBrowsingUtils.permanentPrivateBrowsing ||
+ PrivateBrowsingUtils.isWindowPrivate(win) == aOptions.private));
+ }
+
+#ifdef BROKEN_WM_Z_ORDER
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+
+ // if we're lucky, this isn't a popup, and we can just return this
+ if (win && !isSuitableBrowserWindow(win)) {
+ win = null;
+ let windowList = Services.wm.getEnumerator("navigator:browser");
+ // this is oldest to newest, so this gets a bit ugly
+ while (windowList.hasMoreElements()) {
+ let nextWin = windowList.getNext();
+ if (isSuitableBrowserWindow(nextWin))
+ win = nextWin;
+ }
+ }
+ return win;
+#else
+ let windowList = Services.wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
+ while (windowList.hasMoreElements()) {
+ let win = windowList.getNext();
+ if (isSuitableBrowserWindow(win))
+ return win;
+ }
+ return null;
+#endif
+ }
+};
+
diff --git a/modules/SharedFrame.jsm b/modules/SharedFrame.jsm
new file mode 100644
index 0000000..b9d59bf
--- /dev/null
+++ b/modules/SharedFrame.jsm
@@ -0,0 +1,221 @@
+/* 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 = [ "SharedFrame" ];
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+/**
+ * The purpose of this module is to create and group various iframe
+ * elements that are meant to all display the same content and only
+ * one at a time. This makes it possible to have the content loaded
+ * only once, while the other iframes can be kept as placeholders to
+ * quickly move the content to them through the swapFrameLoaders function
+ * when another one of the placeholder is meant to be displayed.
+ * */
+
+var Frames = new Map();
+
+/**
+ * The Frames map is the main data structure that holds information
+ * about the groups being tracked. Each entry's key is the group name,
+ * and the object holds information about what is the URL being displayed
+ * on that group, and what is the active element on the group (the frame that
+ * holds the loaded content).
+ * The reference to the activeFrame is a weak reference, which allows the
+ * frame to go away at any time, and when that happens the module considers that
+ * there are no active elements in that group. The group can be reactivated
+ * by changing the URL, calling preload again or adding a new element.
+ *
+ *
+ * Frames = {
+ * "messages-panel": {
+ * url: string,
+ * activeFrame: weakref
+ * }
+ * }
+ *
+ * Each object on the map is called a _SharedFrameGroup, which is an internal
+ * class of this module which does not automatically keep track of its state. This
+ * object should not be used externally, and all control should be handled by the
+ * module's functions.
+ */
+
+function UNLOADED_URL(aStr) "data:text/html;charset=utf-8,";
+
+
+this.SharedFrame = {
+ /**
+ * Creates an iframe element and track it as part of the specified group
+ * The module must create the iframe itself because it needs to do some special
+ * handling for the element's src attribute.
+ *
+ * @param aGroupName the name of the group to which this frame belongs
+ * @param aParent the parent element to which the frame will be appended to
+ * @param aFrameAttributes an object with a list of attributes to set in the iframe
+ * before appending it to the DOM. The "src" attribute has
+ * special meaning here and if it's not blank it specifies
+ * the URL that will be initially assigned to this group
+ * @param aPreload optional, tells if the URL specified in the src attribute
+ * should be preloaded in the frame being created, in case
+ * it's not yet preloaded in any other frame of the group.
+ * This parameter has no meaning if src is blank.
+ */
+ createFrame: function (aGroupName, aParent, aFrameAttributes, aPreload = true) {
+ let frame = aParent.ownerDocument.createElement("iframe");
+
+ for (let [key, val] of Iterator(aFrameAttributes)) {
+ frame.setAttribute(key, val);
+ }
+
+ let src = aFrameAttributes.src;
+ if (!src) {
+ aPreload = false;
+ }
+
+ let group = Frames.get(aGroupName);
+
+ if (group) {
+ // If this group has already been created
+
+ if (aPreload && !group.isAlive) {
+ // If aPreload is set and the group is not already loaded, load it.
+ // This can happen if:
+ // - aPreload was not used while creating the previous frames of this group, or
+ // - the previously active frame went dead in the meantime
+ group.url = src;
+ this.preload(aGroupName, frame);
+ } else {
+ // If aPreload is not set, or the group is already loaded in a different frame,
+ // there's not much that we need to do here: just create this frame as an
+ // inactivate placeholder
+ frame.setAttribute("src", UNLOADED_URL(aGroupName));
+ }
+
+ } else {
+ // This is the first time we hear about this group, so let's start tracking it,
+ // and also preload it if the src attribute was set and aPreload = true
+ group = new _SharedFrameGroup(src);
+ Frames.set(aGroupName, group);
+
+ if (aPreload) {
+ this.preload(aGroupName, frame);
+ } else {
+ frame.setAttribute("src", UNLOADED_URL(aGroupName));
+ }
+ }
+
+ aParent.appendChild(frame);
+ return frame;
+
+ },
+
+ /**
+ * Function that moves the loaded content from one active frame to
+ * another one that is currently a placeholder. If there's no active
+ * frame in the group, the content is loaded/reloaded.
+ *
+ * @param aGroupName the name of the group
+ * @param aTargetFrame the frame element to which the content should
+ * be moved to.
+ */
+ setOwner: function (aGroupName, aTargetFrame) {
+ let group = Frames.get(aGroupName);
+ let frame = group.activeFrame;
+
+ if (frame == aTargetFrame) {
+ // nothing to do here
+ return;
+ }
+
+ if (group.isAlive) {
+ // Move document ownership to the desired frame, and make it the active one
+ frame.QueryInterface(Ci.nsIFrameLoaderOwner).swapFrameLoaders(aTargetFrame);
+ group.activeFrame = aTargetFrame;
+ } else {
+ // Previous owner was dead, reload the document at the new owner and make it the active one
+ aTargetFrame.setAttribute("src", group.url);
+ group.activeFrame = aTargetFrame;
+ }
+ },
+
+ /**
+ * Updates the current URL in use by this group, and loads it into the active frame.
+ *
+ * @param aGroupName the name of the group
+ * @param aURL the new url
+ */
+ updateURL: function (aGroupName, aURL) {
+ let group = Frames.get(aGroupName);
+ group.url = aURL;
+
+ if (group.isAlive) {
+ group.activeFrame.setAttribute("src", aURL);
+ }
+ },
+
+ /**
+ * Loads the group's url into a target frame, if the group doesn't have a currently
+ * active frame.
+ *
+ * @param aGroupName the name of the group
+ * @param aTargetFrame the frame element which should be made active and
+ * have the group's content loaded to
+ */
+ preload: function (aGroupName, aTargetFrame) {
+ let group = Frames.get(aGroupName);
+ if (!group.isAlive) {
+ aTargetFrame.setAttribute("src", group.url);
+ group.activeFrame = aTargetFrame;
+ }
+ },
+
+ /**
+ * Tells if a group currently have an active element.
+ *
+ * @param aGroupName the name of the group
+ */
+ isGroupAlive: function (aGroupName) {
+ return Frames.get(aGroupName).isAlive;
+ },
+
+ /**
+ * Forgets about this group. This function doesn't need to be used
+ * unless the group's name needs to be reused.
+ *
+ * @param aGroupName the name of the group
+ */
+ forgetGroup: function (aGroupName) {
+ Frames.delete(aGroupName);
+ }
+}
+
+
+function _SharedFrameGroup(aURL) {
+ this.url = aURL;
+ this._activeFrame = null;
+}
+
+_SharedFrameGroup.prototype = {
+ get isAlive() {
+ let frame = this.activeFrame;
+ return !!(frame &&
+ frame.contentDocument &&
+ frame.contentDocument.location);
+ },
+
+ get activeFrame() {
+ return this._activeFrame &&
+ this._activeFrame.get();
+ },
+
+ set activeFrame(aActiveFrame) {
+ this._activeFrame = aActiveFrame
+ ? Cu.getWeakReference(aActiveFrame)
+ : null;
+ }
+}
diff --git a/modules/Windows8WindowFrameColor.jsm b/modules/Windows8WindowFrameColor.jsm
new file mode 100644
index 0000000..e7a447d
--- /dev/null
+++ b/modules/Windows8WindowFrameColor.jsm
@@ -0,0 +1,53 @@
+/* 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 {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+this.EXPORTED_SYMBOLS = ["Windows8WindowFrameColor"];
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/WindowsRegistry.jsm");
+
+var Windows8WindowFrameColor = {
+ _windowFrameColor: null,
+
+ get_win8: function() {
+ if (this._windowFrameColor)
+ return this._windowFrameColor;
+
+ const HKCU = Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER;
+ const dwmKey = "Software\\Microsoft\\Windows\\DWM";
+
+ // Window frame base color component values when Color Intensity is at 0.
+ let frameBaseColor = 217;
+
+ let windowFrameColor = WindowsRegistry.readRegKey(HKCU, dwmKey,
+ "ColorizationColor");
+ if (windowFrameColor == undefined) {
+ // Return the default color if unset or colorization not used
+ return this._windowFrameColor = [frameBaseColor, frameBaseColor, frameBaseColor];
+ }
+ // The color returned from the Registry is in decimal form.
+ let windowFrameColorHex = windowFrameColor.toString(16);
+ // Zero-pad the number just to make sure that it is 8 digits.
+ windowFrameColorHex = ("00000000" + windowFrameColorHex).substr(-8);
+ let windowFrameColorArray = windowFrameColorHex.match(/../g);
+ let [unused, fgR, fgG, fgB] = windowFrameColorArray.map(function(val) parseInt(val, 16));
+ let windowFrameColorBalance = WindowsRegistry.readRegKey(HKCU, dwmKey,
+ "ColorizationColorBalance");
+ // Default to balance=78 if reg key isn't defined
+ if (windowFrameColorBalance == undefined) {
+ windowFrameColorBalance = 78;
+ }
+ let alpha = windowFrameColorBalance / 100;
+
+ // Alpha-blend the foreground color with the frame base color.
+ let r = Math.round(fgR * alpha + frameBaseColor * (1 - alpha));
+ let g = Math.round(fgG * alpha + frameBaseColor * (1 - alpha));
+ let b = Math.round(fgB * alpha + frameBaseColor * (1 - alpha));
+ return this._windowFrameColor = [r, g, b];
+ }
+};
diff --git a/modules/WindowsJumpLists.jsm b/modules/WindowsJumpLists.jsm
new file mode 100644
index 0000000..e7f7855
--- /dev/null
+++ b/modules/WindowsJumpLists.jsm
@@ -0,0 +1,581 @@
+/* -*- 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/. */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+/**
+ * Constants
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// Stop updating jumplists after some idle time.
+const IDLE_TIMEOUT_SECONDS = 5 * 60;
+
+// Prefs
+const PREF_TASKBAR_BRANCH = "browser.taskbar.lists.";
+const PREF_TASKBAR_ENABLED = "enabled";
+const PREF_TASKBAR_ITEMCOUNT = "maxListItemCount";
+const PREF_TASKBAR_FREQUENT = "frequent.enabled";
+const PREF_TASKBAR_RECENT = "recent.enabled";
+const PREF_TASKBAR_TASKS = "tasks.enabled";
+const PREF_TASKBAR_REFRESH = "refreshInSeconds";
+
+// Hash keys for pendingStatements.
+const LIST_TYPE = {
+ FREQUENT: 0
+, RECENT: 1
+}
+
+/**
+ * Exports
+ */
+
+this.EXPORTED_SYMBOLS = [
+ "WinTaskbarJumpList",
+];
+
+/**
+ * Smart getters
+ */
+
+XPCOMUtils.defineLazyGetter(this, "_prefs", function() {
+ return Services.prefs.getBranch(PREF_TASKBAR_BRANCH);
+});
+
+XPCOMUtils.defineLazyGetter(this, "_stringBundle", function() {
+ return Services.strings
+ .createBundle("chrome://browser/locale/taskbar.properties");
+});
+
+XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
+ Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
+ return PlacesUtils;
+});
+
+XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
+ Components.utils.import("resource://gre/modules/NetUtil.jsm");
+ return NetUtil;
+});
+
+XPCOMUtils.defineLazyServiceGetter(this, "_idle",
+ "@mozilla.org/widget/idleservice;1",
+ "nsIIdleService");
+
+XPCOMUtils.defineLazyServiceGetter(this, "_taskbarService",
+ "@mozilla.org/windows-taskbar;1",
+ "nsIWinTaskbar");
+
+XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
+ "@mozilla.org/browser/shell-service;1",
+ "nsIWindowsShellService");
+
+XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
+ "resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+/**
+ * Global functions
+ */
+
+function _getString(name) {
+ return _stringBundle.GetStringFromName(name);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Task list configuration data object.
+
+var tasksCfg = [
+ /**
+ * Task configuration options: title, description, args, iconIndex, open, close.
+ *
+ * title - Task title displayed in the list. (strings in the table are temp fillers.)
+ * description - Tooltip description on the list item.
+ * args - Command line args to invoke the task.
+ * iconIndex - Optional win icon index into the main application for the
+ * list item.
+ * open - Boolean indicates if the command should be visible after the browser opens.
+ * close - Boolean indicates if the command should be visible after the browser closes.
+ */
+ // Open new tab
+ {
+ get title() _getString("taskbar.tasks.newTab.label"),
+ get description() _getString("taskbar.tasks.newTab.description"),
+ args: "-new-tab about:blank",
+ iconIndex: 3, // New window icon
+ open: true,
+ close: true, // The jump list already has an app launch icon, but
+ // we don't always update the list on shutdown.
+ // Thus true for consistency.
+ },
+
+ // Open new window
+ {
+ get title() _getString("taskbar.tasks.newWindow.label"),
+ get description() _getString("taskbar.tasks.newWindow.description"),
+ args: "-browser",
+ iconIndex: 2, // New tab icon
+ open: true,
+ close: true, // No point, but we don't always update the list on
+ // shutdown. Thus true for consistency.
+ },
+
+ // Open new private window
+ {
+ get title() _getString("taskbar.tasks.newPrivateWindow.label"),
+ get description() _getString("taskbar.tasks.newPrivateWindow.description"),
+ args: "-private-window",
+ iconIndex: 4, // Private browsing mode icon
+ open: true,
+ close: true, // No point, but we don't always update the list on
+ // shutdown. Thus true for consistency.
+ },
+];
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementation
+
+this.WinTaskbarJumpList =
+{
+ _builder: null,
+ _tasks: null,
+ _shuttingDown: false,
+
+ /**
+ * Startup, shutdown, and update
+ */
+
+ startup: function WTBJL_startup() {
+ // exit if this isn't win7 or higher.
+ if (!this._initTaskbar())
+ return;
+
+ // Win shell shortcut maintenance. If we've gone through an update,
+ // this will update any pinned taskbar shortcuts. Not specific to
+ // jump lists, but this was a convienent place to call it.
+ try {
+ // dev builds may not have helper.exe, ignore failures.
+ this._shortcutMaintenance();
+ } catch (ex) {
+ }
+
+ // Store our task list config data
+ this._tasks = tasksCfg;
+
+ // retrieve taskbar related prefs.
+ this._refreshPrefs();
+
+ // observer for private browsing and our prefs branch
+ this._initObs();
+
+ // jump list refresh timer
+ this._updateTimer();
+ },
+
+ update: function WTBJL_update() {
+ // are we disabled via prefs? don't do anything!
+ if (!this._enabled)
+ return;
+
+ // do what we came here to do, update the taskbar jumplist
+ this._buildList();
+ },
+
+ _shutdown: function WTBJL__shutdown() {
+ this._shuttingDown = true;
+
+ // Correctly handle a clear history on shutdown. If there are no
+ // entries be sure to empty all history lists. Luckily Places caches
+ // this value, so it's a pretty fast call.
+ if (!PlacesUtils.history.hasHistoryEntries) {
+ this.update();
+ }
+
+ this._free();
+ },
+
+ _shortcutMaintenance: function WTBJL__maintenace() {
+ _winShellService.shortcutMaintenance();
+ },
+
+ /**
+ * List building
+ *
+ * @note Async builders must add their mozIStoragePendingStatement to
+ * _pendingStatements object, using a different LIST_TYPE entry for
+ * each statement. Once finished they must remove it and call
+ * commitBuild(). When there will be no more _pendingStatements,
+ * commitBuild() will commit for real.
+ */
+
+ _pendingStatements: {},
+ _hasPendingStatements: function WTBJL__hasPendingStatements() {
+ return Object.keys(this._pendingStatements).length > 0;
+ },
+
+ _buildList: function WTBJL__buildList() {
+ if (this._hasPendingStatements()) {
+ // We were requested to update the list while another update was in
+ // progress, this could happen at shutdown, idle or privatebrowsing.
+ // Abort the current list building.
+ for (let listType in this._pendingStatements) {
+ this._pendingStatements[listType].cancel();
+ delete this._pendingStatements[listType];
+ }
+ this._builder.abortListBuild();
+ }
+
+ // anything to build?
+ if (!this._showFrequent && !this._showRecent && !this._showTasks) {
+ // don't leave the last list hanging on the taskbar.
+ this._deleteActiveJumpList();
+ return;
+ }
+
+ if (!this._startBuild())
+ return;
+
+ if (this._showTasks)
+ this._buildTasks();
+
+ // Space for frequent items takes priority over recent.
+ if (this._showFrequent)
+ this._buildFrequent();
+
+ if (this._showRecent)
+ this._buildRecent();
+
+ this._commitBuild();
+ },
+
+ /**
+ * Taskbar api wrappers
+ */
+
+ _startBuild: function WTBJL__startBuild() {
+ var removedItems = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ this._builder.abortListBuild();
+ if (this._builder.initListBuild(removedItems)) {
+ // Prior to building, delete removed items from history.
+ this._clearHistory(removedItems);
+ return true;
+ }
+ return false;
+ },
+
+ _commitBuild: function WTBJL__commitBuild() {
+ if (!this._hasPendingStatements() && !this._builder.commitListBuild()) {
+ this._builder.abortListBuild();
+ }
+ },
+
+ _buildTasks: function WTBJL__buildTasks() {
+ var items = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ this._tasks.forEach(function (task) {
+ if ((this._shuttingDown && !task.close) || (!this._shuttingDown && !task.open))
+ return;
+ var item = this._getHandlerAppItem(task.title, task.description,
+ task.args, task.iconIndex, null);
+ items.appendElement(item, false);
+ }, this);
+
+ if (items.length > 0)
+ this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
+ },
+
+ _buildCustom: function WTBJL__buildCustom(title, items) {
+ if (items.length > 0)
+ this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
+ },
+
+ _buildFrequent: function WTBJL__buildFrequent() {
+ // If history is empty, just bail out.
+ if (!PlacesUtils.history.hasHistoryEntries) {
+ return;
+ }
+
+ // Windows supports default frequent and recent lists,
+ // but those depend on internal windows visit tracking
+ // which we don't populate. So we build our own custom
+ // frequent and recent lists using our nav history data.
+
+ var items = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ // track frequent items so that we don't add them to
+ // the recent list.
+ this._frequentHashList = [];
+
+ this._pendingStatements[LIST_TYPE.FREQUENT] = this._getHistoryResults(
+ Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING,
+ this._maxItemCount,
+ function (aResult) {
+ if (!aResult) {
+ delete this._pendingStatements[LIST_TYPE.FREQUENT];
+ // The are no more results, build the list.
+ this._buildCustom(_getString("taskbar.frequent.label"), items);
+ this._commitBuild();
+ return;
+ }
+
+ let title = aResult.title || aResult.uri;
+ let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
+ let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
+ faviconPageUri);
+ items.appendElement(shortcut, false);
+ this._frequentHashList.push(aResult.uri);
+ },
+ this
+ );
+ },
+
+ _buildRecent: function WTBJL__buildRecent() {
+ // If history is empty, just bail out.
+ if (!PlacesUtils.history.hasHistoryEntries) {
+ return;
+ }
+
+ var items = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ // Frequent items will be skipped, so we select a double amount of
+ // entries and stop fetching results at _maxItemCount.
+ var count = 0;
+
+ this._pendingStatements[LIST_TYPE.RECENT] = this._getHistoryResults(
+ Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING,
+ this._maxItemCount * 2,
+ function (aResult) {
+ if (!aResult) {
+ // The are no more results, build the list.
+ this._buildCustom(_getString("taskbar.recent.label"), items);
+ delete this._pendingStatements[LIST_TYPE.RECENT];
+ this._commitBuild();
+ return;
+ }
+
+ if (count >= this._maxItemCount) {
+ return;
+ }
+
+ // Do not add items to recent that have already been added to frequent.
+ if (this._frequentHashList &&
+ this._frequentHashList.indexOf(aResult.uri) != -1) {
+ return;
+ }
+
+ let title = aResult.title || aResult.uri;
+ let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
+ let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
+ faviconPageUri);
+ items.appendElement(shortcut, false);
+ count++;
+ },
+ this
+ );
+ },
+
+ _deleteActiveJumpList: function WTBJL__deleteAJL() {
+ this._builder.deleteActiveList();
+ },
+
+ /**
+ * Jump list item creation helpers
+ */
+
+ _getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description,
+ args, iconIndex,
+ faviconPageUri) {
+ var file = Services.dirsvc.get("XREExeF", Ci.nsILocalFile);
+
+ var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Ci.nsILocalHandlerApp);
+ handlerApp.executable = file;
+ // handlers default to the leaf name if a name is not specified
+ if (name && name.length != 0)
+ handlerApp.name = name;
+ handlerApp.detailedDescription = description;
+ handlerApp.appendParameter(args);
+
+ var item = Cc["@mozilla.org/windows-jumplistshortcut;1"].
+ createInstance(Ci.nsIJumpListShortcut);
+ item.app = handlerApp;
+ item.iconIndex = iconIndex;
+ item.faviconPageUri = faviconPageUri;
+ return item;
+ },
+
+ _getSeparatorItem: function WTBJL__getSeparatorItem() {
+ var item = Cc["@mozilla.org/windows-jumplistseparator;1"].
+ createInstance(Ci.nsIJumpListSeparator);
+ return item;
+ },
+
+ /**
+ * Nav history helpers
+ */
+
+ _getHistoryResults:
+ function WTBLJL__getHistoryResults(aSortingMode, aLimit, aCallback, aScope) {
+ var options = PlacesUtils.history.getNewQueryOptions();
+ options.maxResults = aLimit;
+ options.sortingMode = aSortingMode;
+ var query = PlacesUtils.history.getNewQuery();
+
+ // Return the pending statement to the caller, to allow cancelation.
+ return PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
+ .asyncExecuteLegacyQueries([query], 1, options, {
+ handleResult: function (aResultSet) {
+ for (let row; (row = aResultSet.getNextRow());) {
+ try {
+ aCallback.call(aScope,
+ { uri: row.getResultByIndex(1)
+ , title: row.getResultByIndex(2)
+ });
+ } catch (e) {}
+ }
+ },
+ handleError: function (aError) {
+ Components.utils.reportError(
+ "Async execution error (" + aError.result + "): " + aError.message);
+ },
+ handleCompletion: function (aReason) {
+ aCallback.call(WinTaskbarJumpList, null);
+ },
+ });
+ },
+
+ _clearHistory: function WTBJL__clearHistory(items) {
+ if (!items)
+ return;
+ var URIsToRemove = [];
+ var e = items.enumerate();
+ while (e.hasMoreElements()) {
+ let oldItem = e.getNext().QueryInterface(Ci.nsIJumpListShortcut);
+ if (oldItem) {
+ try { // in case we get a bad uri
+ let uriSpec = oldItem.app.getParameter(0);
+ URIsToRemove.push(NetUtil.newURI(uriSpec));
+ } catch (err) { }
+ }
+ }
+ if (URIsToRemove.length > 0) {
+ PlacesUtils.bhistory.removePages(URIsToRemove, URIsToRemove.length, true);
+ }
+ },
+
+ /**
+ * Prefs utilities
+ */
+
+ _refreshPrefs: function WTBJL__refreshPrefs() {
+ this._enabled = _prefs.getBoolPref(PREF_TASKBAR_ENABLED);
+ this._showFrequent = _prefs.getBoolPref(PREF_TASKBAR_FREQUENT);
+ this._showRecent = _prefs.getBoolPref(PREF_TASKBAR_RECENT);
+ this._showTasks = _prefs.getBoolPref(PREF_TASKBAR_TASKS);
+ this._maxItemCount = _prefs.getIntPref(PREF_TASKBAR_ITEMCOUNT);
+ },
+
+ /**
+ * Init and shutdown utilities
+ */
+
+ _initTaskbar: function WTBJL__initTaskbar() {
+ this._builder = _taskbarService.createJumpListBuilder();
+ if (!this._builder || !this._builder.available)
+ return false;
+
+ return true;
+ },
+
+ _initObs: function WTBJL__initObs() {
+ // If the browser is closed while in private browsing mode, the "exit"
+ // notification is fired on quit-application-granted.
+ // History cleanup can happen at profile-change-teardown.
+ Services.obs.addObserver(this, "profile-before-change", false);
+ Services.obs.addObserver(this, "browser:purge-session-history", false);
+ _prefs.addObserver("", this, false);
+ },
+
+ _freeObs: function WTBJL__freeObs() {
+ Services.obs.removeObserver(this, "profile-before-change");
+ Services.obs.removeObserver(this, "browser:purge-session-history");
+ _prefs.removeObserver("", this);
+ },
+
+ _updateTimer: function WTBJL__updateTimer() {
+ if (this._enabled && !this._shuttingDown && !this._timer) {
+ this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._timer.initWithCallback(this,
+ _prefs.getIntPref(PREF_TASKBAR_REFRESH)*1000,
+ this._timer.TYPE_REPEATING_SLACK);
+ }
+ else if ((!this._enabled || this._shuttingDown) && this._timer) {
+ this._timer.cancel();
+ delete this._timer;
+ }
+ },
+
+ _hasIdleObserver: false,
+ _updateIdleObserver: function WTBJL__updateIdleObserver() {
+ if (this._enabled && !this._shuttingDown && !this._hasIdleObserver) {
+ _idle.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
+ this._hasIdleObserver = true;
+ }
+ else if ((!this._enabled || this._shuttingDown) && this._hasIdleObserver) {
+ _idle.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
+ this._hasIdleObserver = false;
+ }
+ },
+
+ _free: function WTBJL__free() {
+ this._freeObs();
+ this._updateTimer();
+ this._updateIdleObserver();
+ delete this._builder;
+ },
+
+ /**
+ * Notification handlers
+ */
+
+ notify: function WTBJL_notify(aTimer) {
+ // Add idle observer on the first notification so it doesn't hit startup.
+ this._updateIdleObserver();
+ this.update();
+ },
+
+ observe: function WTBJL_observe(aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "nsPref:changed":
+ if (this._enabled == true && !_prefs.getBoolPref(PREF_TASKBAR_ENABLED))
+ this._deleteActiveJumpList();
+ this._refreshPrefs();
+ this._updateTimer();
+ this._updateIdleObserver();
+ this.update();
+ break;
+
+ case "profile-before-change":
+ this._shutdown();
+ break;
+
+ case "browser:purge-session-history":
+ this.update();
+ break;
+ case "idle":
+ if (this._timer) {
+ this._timer.cancel();
+ delete this._timer;
+ }
+ break;
+
+ case "back":
+ this._updateTimer();
+ break;
+ }
+ },
+};
diff --git a/modules/WindowsPreviewPerTab.jsm b/modules/WindowsPreviewPerTab.jsm
new file mode 100644
index 0000000..4b5030a
--- /dev/null
+++ b/modules/WindowsPreviewPerTab.jsm
@@ -0,0 +1,861 @@
+/* vim: se cin sw=2 ts=2 et filetype=javascript :
+ * 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 module implements the front end behavior for AeroPeek. The taskbar
+ * allows an application to expose its tabbed interface by showing thumbnail
+ * previews rather than the default window preview.
+ * Additionally, when a user hovers over a thumbnail (tab or window),
+ * they are shown a live preview of the window (or tab + its containing window).
+ *
+ * In Windows 7, a title, icon, close button and optional toolbar are shown for
+ * each preview. This feature does not make use of the toolbar. For window
+ * previews, the title is the window title and the icon the window icon. For
+ * tab previews, the title is the page title and the page's favicon. In both
+ * cases, the close button "does the right thing."
+ *
+ * The primary objects behind this feature are nsITaskbarTabPreview and
+ * nsITaskbarPreviewController. Each preview has a controller. The controller
+ * responds to the user's interactions on the taskbar and provides the required
+ * data to the preview for determining the size of the tab and thumbnail. The
+ * PreviewController class implements this interface. The preview will request
+ * the controller to provide a thumbnail or preview when the user interacts with
+ * the taskbar. To reduce the overhead of drawing the tab area, the controller
+ * implementation caches the tab's contents in a element. If no
+ * previews or thumbnails have been requested for some time, the controller will
+ * discard its cached tab contents.
+ *
+ * Screen real estate is limited so when there are too many thumbnails to fit
+ * on the screen, the taskbar stops displaying thumbnails and instead displays
+ * just the title, icon and close button in a similar fashion to previous
+ * versions of the taskbar. If there are still too many previews to fit on the
+ * screen, the taskbar resorts to a scroll up and scroll down button pair to let
+ * the user scroll through the list of tabs. Since this is undoubtedly
+ * inconvenient for users with many tabs, the AeroPeek objects turns off all of
+ * the tab previews. This tells the taskbar to revert to one preview per window.
+ * If the number of tabs falls below this magic threshold, the preview-per-tab
+ * behavior returns. There is no reliable way to determine when the scroll
+ * buttons appear on the taskbar, so a magic pref-controlled number determines
+ * when this threshold has been crossed.
+ */
+this.EXPORTED_SYMBOLS = ["AeroPeek"];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/PlacesUtils.jsm");
+Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// Pref to enable/disable preview-per-tab
+const TOGGLE_PREF_NAME = "browser.taskbar.previews.enable";
+// Pref to determine the magic auto-disable threshold
+const DISABLE_THRESHOLD_PREF_NAME = "browser.taskbar.previews.max";
+// Pref to control the time in seconds that tab contents live in the cache
+const CACHE_EXPIRATION_TIME_PREF_NAME = "browser.taskbar.previews.cachetime";
+
+const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
+
+// Various utility properties
+XPCOMUtils.defineLazyServiceGetter(this, "imgTools",
+ "@mozilla.org/image/tools;1",
+ "imgITools");
+XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
+ "resource://gre/modules/PageThumbs.jsm");
+
+// nsIURI -> imgIContainer
+function _imageFromURI(uri, privateMode, callback) {
+ let channel = NetUtil.newChannel({
+ uri: uri,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_INTERNAL_IMAGE
+ });
+
+ try {
+ channel.QueryInterface(Ci.nsIPrivateBrowsingChannel);
+ channel.setPrivate(privateMode);
+ } catch (e) {
+ // Ignore channels which do not support nsIPrivateBrowsingChannel
+ }
+ NetUtil.asyncFetch(channel, function(inputStream, resultCode) {
+ if (!Components.isSuccessCode(resultCode))
+ return;
+ try {
+ let out_img = { value: null };
+ imgTools.decodeImageData(inputStream, channel.contentType, out_img);
+ callback(out_img.value);
+ } catch (e) {
+ // We failed, so use the default favicon (only if this wasn't the default
+ // favicon).
+ let defaultURI = PlacesUtils.favicons.defaultFavicon;
+ if (!defaultURI.equals(uri))
+ _imageFromURI(defaultURI, privateMode, callback);
+ }
+ });
+}
+
+// string? -> imgIContainer
+function getFaviconAsImage(iconurl, privateMode, callback) {
+ if (iconurl) {
+ _imageFromURI(NetUtil.newURI(iconurl), privateMode, callback);
+ } else {
+ _imageFromURI(PlacesUtils.favicons.defaultFavicon, privateMode, callback);
+ }
+}
+
+// Snaps the given rectangle to be pixel-aligned at the given scale
+function snapRectAtScale(r, scale) {
+ let x = Math.floor(r.x * scale);
+ let y = Math.floor(r.y * scale);
+ let width = Math.ceil((r.x + r.width) * scale) - x;
+ let height = Math.ceil((r.y + r.height) * scale) - y;
+
+ r.x = x / scale;
+ r.y = y / scale;
+ r.width = width / scale;
+ r.height = height / scale;
+}
+
+// PreviewController
+
+/*
+ * This class manages the behavior of thumbnails and previews. It has the following
+ * responsibilities:
+ * 1) Responding to requests from Windows taskbar for a thumbnail or window
+ * preview.
+ * 2) Listening for DOM events that result in a thumbnail or window preview needing
+ * to be refreshed, and communicating this to the taskbar.
+ * 3) Handling queryies and returning new thumbnail or window preview images to the
+ * taskbar through PageThumbs.
+ *
+ * @param win
+ * The TabWindow (see below) that owns the preview that this controls
+ * @param tab
+ * The that this preview is associated with
+ */
+function PreviewController(win, tab) {
+ this.win = win;
+ this.tab = tab;
+ this.linkedBrowser = tab.linkedBrowser;
+ this.preview = this.win.createTabPreview(this);
+
+ this.tab.addEventListener("TabAttrModified", this, false);
+
+ XPCOMUtils.defineLazyGetter(this, "canvasPreview", function () {
+ let canvas = PageThumbs.createCanvas();
+ canvas.mozOpaque = true;
+ return canvas;
+ });
+}
+
+PreviewController.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsITaskbarPreviewController,
+ Ci.nsIDOMEventListener]),
+
+ destroy: function () {
+ this.tab.removeEventListener("TabAttrModified", this, false);
+
+ // Break cycles, otherwise we end up leaking the window with everything
+ // attached to it.
+ delete this.win;
+ delete this.preview;
+ },
+
+ get wrappedJSObject() {
+ return this;
+ },
+
+ // Resizes the canvasPreview to 0x0, essentially freeing its memory.
+ resetCanvasPreview: function () {
+ this.canvasPreview.width = 0;
+ this.canvasPreview.height = 0;
+ },
+
+ /**
+ * Set the canvas dimensions.
+ */
+ resizeCanvasPreview: function (aRequestedWidth, aRequestedHeight) {
+ this.canvasPreview.width = aRequestedWidth;
+ this.canvasPreview.height = aRequestedHeight;
+ },
+
+
+ get zoom() {
+ // Note that winutils.fullZoom accounts for "quantization" of the zoom factor
+ // from nsIContentViewer due to conversion through appUnits.
+ // We do -not- want screenPixelsPerCSSPixel here, because that would -also-
+ // incorporate any scaling that is applied due to hi-dpi resolution options.
+ return this.tab.linkedBrowser.fullZoom;
+ },
+
+ get screenPixelsPerCSSPixel() {
+ let chromeWin = this.tab.ownerGlobal;
+ let windowUtils = chromeWin.getInterface(Ci.nsIDOMWindowUtils);
+ return windowUtils.screenPixelsPerCSSPixel;
+ },
+
+ get browserDims() {
+ return this.tab.linkedBrowser.getBoundingClientRect();
+ },
+
+ cacheBrowserDims: function () {
+ let dims = this.browserDims;
+ this._cachedWidth = dims.width;
+ this._cachedHeight = dims.height;
+ },
+
+ testCacheBrowserDims: function () {
+ let dims = this.browserDims;
+ return this._cachedWidth == dims.width &&
+ this._cachedHeight == dims.height;
+ },
+
+ /**
+ * Capture a new thumbnail image for this preview. Called by the controller
+ * in response to a request for a new thumbnail image.
+ */
+ updateCanvasPreview: function (aFullScale, aCallback) {
+ // Update our cached browser dims so that delayed resize
+ // events don't trigger another invalidation if this tab becomes active.
+ this.cacheBrowserDims();
+ PageThumbs.captureToCanvas(this.linkedBrowser, this.canvasPreview,
+ aCallback, { fullScale: aFullScale });
+ // If we're updating the canvas, then we're in the middle of a peek so
+ // don't discard the cache of previews.
+ AeroPeek.resetCacheTimer();
+ },
+
+ updateTitleAndTooltip: function () {
+ let title = this.win.tabbrowser.getWindowTitleForBrowser(this.linkedBrowser);
+ this.preview.title = title;
+ this.preview.tooltip = title;
+ },
+
+ // nsITaskbarPreviewController
+
+ // window width and height, not browser
+ get width() {
+ return this.win.width;
+ },
+
+ // window width and height, not browser
+ get height() {
+ return this.win.height;
+ },
+
+ get thumbnailAspectRatio() {
+ let browserDims = this.browserDims;
+ // Avoid returning 0
+ let tabWidth = browserDims.width || 1;
+ // Avoid divide by 0
+ let tabHeight = browserDims.height || 1;
+ return tabWidth / tabHeight;
+ },
+
+ /**
+ * Responds to taskbar requests for window previews. Returns the results asynchronously
+ * through updateCanvasPreview.
+ *
+ * @param aTaskbarCallback nsITaskbarPreviewCallback results callback
+ */
+ requestPreview: function (aTaskbarCallback) {
+ // Grab a high res content preview
+ this.resetCanvasPreview();
+ this.updateCanvasPreview(true, (aPreviewCanvas) => {
+ let winWidth = this.win.width;
+ let winHeight = this.win.height;
+
+ let composite = PageThumbs.createCanvas();
+
+ // Use transparency, Aero glass is drawn black without it.
+ composite.mozOpaque = false;
+
+ let ctx = composite.getContext('2d');
+ let scale = this.screenPixelsPerCSSPixel / this.zoom;
+
+ composite.width = winWidth * scale;
+ composite.height = winHeight * scale;
+
+ ctx.save();
+ ctx.scale(scale, scale);
+
+ // Draw chrome. Note we currently do not get scrollbars for remote frames
+ // in the image above.
+ ctx.drawWindow(this.win.win, 0, 0, winWidth, winHeight, "rgba(0,0,0,0)");
+
+ // Draw the content are into the composite canvas at the right location.
+ ctx.drawImage(aPreviewCanvas, this.browserDims.x, this.browserDims.y,
+ aPreviewCanvas.width, aPreviewCanvas.height);
+ ctx.restore();
+
+ // Deliver the resulting composite canvas to Windows
+ this.win.tabbrowser.previewTab(this.tab, function () {
+ aTaskbarCallback.done(composite, false);
+ });
+ });
+ },
+
+ /**
+ * Responds to taskbar requests for tab thumbnails. Returns the results asynchronously
+ * through updateCanvasPreview.
+ *
+ * Note Windows requests a specific width and height here, if the resulting thumbnail
+ * does not match these dimensions thumbnail display will fail.
+ *
+ * @param aTaskbarCallback nsITaskbarPreviewCallback results callback
+ * @param aRequestedWidth width of the requested thumbnail
+ * @param aRequestedHeight height of the requested thumbnail
+ */
+ requestThumbnail: function (aTaskbarCallback, aRequestedWidth, aRequestedHeight) {
+ this.resizeCanvasPreview(aRequestedWidth, aRequestedHeight);
+ this.updateCanvasPreview(false, (aThumbnailCanvas) => {
+ aTaskbarCallback.done(aThumbnailCanvas, false);
+ });
+ },
+
+ // Event handling
+
+ onClose: function () {
+ this.win.tabbrowser.removeTab(this.tab);
+ },
+
+ onActivate: function () {
+ this.win.tabbrowser.selectedTab = this.tab;
+
+ // Accept activation - this will restore the browser window
+ // if it's minimized
+ return true;
+ },
+
+ // nsIDOMEventListener
+ handleEvent: function (evt) {
+ switch (evt.type) {
+ case "TabAttrModified":
+ this.updateTitleAndTooltip();
+ break;
+ }
+ }
+};
+
+XPCOMUtils.defineLazyGetter(PreviewController.prototype, "canvasPreviewFlags",
+ function () { let canvasInterface = Ci.nsIDOMCanvasRenderingContext2D;
+ return canvasInterface.DRAWWINDOW_DRAW_VIEW
+ | canvasInterface.DRAWWINDOW_DRAW_CARET
+ | canvasInterface.DRAWWINDOW_ASYNC_DECODE_IMAGES
+ | canvasInterface.DRAWWINDOW_DO_NOT_FLUSH;
+});
+
+// TabWindow
+
+/*
+ * This class monitors a browser window for changes to its tabs
+ *
+ * @param win
+ * The nsIDOMWindow browser window
+ */
+function TabWindow(win) {
+ this.win = win;
+ this.tabbrowser = win.gBrowser;
+
+ this.previews = new Map();
+
+ for (let i = 0; i < this.tabEvents.length; i++)
+ this.tabbrowser.tabContainer.addEventListener(this.tabEvents[i], this, false);
+
+ for (let i = 0; i < this.winEvents.length; i++)
+ this.win.addEventListener(this.winEvents[i], this, false);
+
+ this.tabbrowser.addTabsProgressListener(this);
+
+ AeroPeek.windows.push(this);
+ let tabs = this.tabbrowser.tabs;
+ for (let i = 0; i < tabs.length; i++)
+ this.newTab(tabs[i]);
+
+ this.updateTabOrdering();
+ AeroPeek.checkPreviewCount();
+}
+
+TabWindow.prototype = {
+ _enabled: false,
+ _cachedWidth: 0,
+ _cachedHeight: 0,
+ tabEvents: ["TabOpen", "TabClose", "TabSelect", "TabMove"],
+ winEvents: ["resize"],
+
+ destroy: function () {
+ this._destroying = true;
+
+ let tabs = this.tabbrowser.tabs;
+
+ this.tabbrowser.removeTabsProgressListener(this);
+
+ for (let i = 0; i < this.winEvents.length; i++)
+ this.win.removeEventListener(this.winEvents[i], this, false);
+
+ for (let i = 0; i < this.tabEvents.length; i++)
+ this.tabbrowser.tabContainer.removeEventListener(this.tabEvents[i], this, false);
+
+ for (let i = 0; i < tabs.length; i++)
+ this.removeTab(tabs[i]);
+
+ let idx = AeroPeek.windows.indexOf(this.win.gTaskbarTabGroup);
+ AeroPeek.windows.splice(idx, 1);
+ AeroPeek.checkPreviewCount();
+ },
+
+ get width () {
+ return this.win.innerWidth;
+ },
+ get height () {
+ return this.win.innerHeight;
+ },
+
+ cacheDims: function () {
+ this._cachedWidth = this.width;
+ this._cachedHeight = this.height;
+ },
+
+ testCacheDims: function () {
+ return this._cachedWidth == this.width && this._cachedHeight == this.height;
+ },
+
+ // Invoked when the given tab is added to this window
+ newTab: function (tab) {
+ let controller = new PreviewController(this, tab);
+ // It's OK to add the preview now while the favicon still loads.
+ this.previews.set(tab, controller.preview);
+ AeroPeek.addPreview(controller.preview);
+ // updateTitleAndTooltip relies on having controller.preview which is lazily resolved.
+ // Now that we've updated this.previews, it will resolve successfully.
+ controller.updateTitleAndTooltip();
+ },
+
+ createTabPreview: function (controller) {
+ let docShell = this.win
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ let preview = AeroPeek.taskbar.createTaskbarTabPreview(docShell, controller);
+ preview.visible = AeroPeek.enabled;
+ preview.active = this.tabbrowser.selectedTab == controller.tab;
+ this.onLinkIconAvailable(controller.tab.linkedBrowser,
+ controller.tab.getAttribute("image"));
+ return preview;
+ },
+
+ // Invoked when the given tab is closed
+ removeTab: function (tab) {
+ let preview = this.previewFromTab(tab);
+ preview.active = false;
+ preview.visible = false;
+ preview.move(null);
+ preview.controller.wrappedJSObject.destroy();
+
+ this.previews.delete(tab);
+ AeroPeek.removePreview(preview);
+ },
+
+ get enabled () {
+ return this._enabled;
+ },
+
+ set enabled (enable) {
+ this._enabled = enable;
+ // Because making a tab visible requires that the tab it is next to be
+ // visible, it is far simpler to unset the 'next' tab and recreate them all
+ // at once.
+ for (let [, preview] of this.previews) {
+ preview.move(null);
+ preview.visible = enable;
+ }
+ this.updateTabOrdering();
+ },
+
+ previewFromTab: function (tab) {
+ return this.previews.get(tab);
+ },
+
+ updateTabOrdering: function () {
+ let previews = this.previews;
+ let tabs = this.tabbrowser.tabs;
+
+ // Previews are internally stored using a map, so we need to iterate the
+ // tabbrowser's array of tabs to retrieve previews in the same order.
+ let inorder = [];
+ for (let t of tabs) {
+ if (previews.has(t)) {
+ inorder.push(previews.get(t));
+ }
+ }
+
+ // Since the internal taskbar array has not yet been updated we must force
+ // on it the sorting order of our local array. To do so we must walk
+ // the local array backwards, otherwise we would send move requests in the
+ // wrong order. See bug 522610 for details.
+ for (let i = inorder.length - 1; i >= 0; i--) {
+ inorder[i].move(inorder[i + 1] || null);
+ }
+ },
+
+ // nsIDOMEventListener
+ handleEvent: function (evt) {
+ let tab = evt.originalTarget;
+ switch (evt.type) {
+ case "TabOpen":
+ this.newTab(tab);
+ this.updateTabOrdering();
+ break;
+ case "TabClose":
+ this.removeTab(tab);
+ this.updateTabOrdering();
+ break;
+ case "TabSelect":
+ this.previewFromTab(tab).active = true;
+ break;
+ case "TabMove":
+ this.updateTabOrdering();
+ break;
+ case "resize":
+ if (!AeroPeek._prefenabled)
+ return;
+ this.onResize();
+ break;
+ }
+ },
+
+ // Set or reset a timer that will invalidate visible thumbnails soon.
+ setInvalidationTimer: function () {
+ if (!this.invalidateTimer) {
+ this.invalidateTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ }
+ this.invalidateTimer.cancel();
+
+ // delay 1 second before invalidating
+ this.invalidateTimer.initWithCallback(() => {
+ // invalidate every preview. note the internal implementation of
+ // invalidate ignores thumbnails that aren't visible.
+ this.previews.forEach(function (aPreview) {
+ let controller = aPreview.controller.wrappedJSObject;
+ if (!controller.testCacheBrowserDims()) {
+ controller.cacheBrowserDims();
+ aPreview.invalidate();
+ }
+ });
+ }, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
+ },
+
+ onResize: function () {
+ // Specific to a window.
+
+ // Call invalidate on each tab thumbnail so that Windows will request an
+ // updated image. However don't do this repeatedly across multiple resize
+ // events triggered during window border drags.
+
+ if (this.testCacheDims()) {
+ return;
+ }
+
+ // update the window dims on our TabWindow object.
+ this.cacheDims();
+
+ // invalidate soon
+ this.setInvalidationTimer();
+ },
+
+ invalidateTabPreview: function(aBrowser) {
+ for (let [tab, preview] of this.previews) {
+ if (aBrowser == tab.linkedBrowser) {
+ preview.invalidate();
+ break;
+ }
+ }
+ },
+
+ // Browser progress listener
+
+ onLocationChange: function (aBrowser) {
+ // I'm not sure we need this, onStateChange does a really good job
+ // of picking up page changes.
+ // this.invalidateTabPreview(aBrowser);
+ },
+
+ onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
+ if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
+ aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
+ this.invalidateTabPreview(aBrowser);
+ }
+ },
+
+ directRequestProtocols: new Set([
+ "file", "chrome", "resource", "about"
+ ]),
+ onLinkIconAvailable: function (aBrowser, aIconURL) {
+ let self = this;
+ let requestURL = null;
+ if (aIconURL) {
+ let shouldRequestFaviconURL = true;
+ try {
+ let urlObject = NetUtil.newURI(aIconURL);
+ shouldRequestFaviconURL =
+ !this.directRequestProtocols.has(urlObject.scheme);
+ } catch (ex) {}
+
+ requestURL = shouldRequestFaviconURL ?
+ "moz-anno:favicon:" + aIconURL :
+ aIconURL;
+ }
+ let isDefaultFavicon = !requestURL;
+ getFaviconAsImage(
+ requestURL,
+ PrivateBrowsingUtils.isWindowPrivate(self.win),
+ img => {
+ let index = self.tabbrowser.browsers.indexOf(aBrowser);
+ // Only add it if we've found the index and the URI is still the same.
+ // The tab could have closed, and there's no guarantee the icons
+ // will have finished fetching 'in order'.
+ if (index != -1) {
+ let tab = self.tabbrowser.tabs[index];
+ let preview = self.previews.get(tab);
+ if (tab.getAttribute("image") == aIconURL ||
+ (!preview.icon && isDefaultFavicon)) {
+ preview.icon = img;
+ }
+ }
+ }
+ );
+ }
+}
+
+// AeroPeek
+
+/*
+ * This object acts as global storage and external interface for this feature.
+ * It maintains the values of the prefs.
+ */
+this.AeroPeek = {
+ available: false,
+ // Does the pref say we're enabled?
+ __prefenabled: false,
+
+ _enabled: true,
+
+ initialized: false,
+
+ // nsITaskbarTabPreview array
+ previews: [],
+
+ // TabWindow array
+ windows: [],
+
+ // nsIWinTaskbar service
+ taskbar: null,
+
+ // Maximum number of previews
+ maxpreviews: 20,
+
+ // Length of time in seconds that previews are cached
+ cacheLifespan: 20,
+
+ initialize: function () {
+ if (!(WINTASKBAR_CONTRACTID in Cc))
+ return;
+ this.taskbar = Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar);
+ this.available = this.taskbar.available;
+ if (!this.available)
+ return;
+
+ this.prefs.addObserver(TOGGLE_PREF_NAME, this, true);
+ this.enabled = this._prefenabled = this.prefs.getBoolPref(TOGGLE_PREF_NAME);
+ this.initialized = true;
+ },
+
+ destroy: function destroy() {
+ this._enabled = false;
+
+ if (this.cacheTimer)
+ this.cacheTimer.cancel();
+ },
+
+ get enabled() {
+ return this._enabled;
+ },
+
+ set enabled(enable) {
+ if (this._enabled == enable)
+ return;
+
+ this._enabled = enable;
+
+ this.windows.forEach(function (win) {
+ win.enabled = enable;
+ });
+ },
+
+ get _prefenabled() {
+ return this.__prefenabled;
+ },
+
+ set _prefenabled(enable) {
+ if (enable == this.__prefenabled) {
+ return;
+ }
+ this.__prefenabled = enable;
+
+ if (enable) {
+ this.enable();
+ } else {
+ this.disable();
+ }
+ },
+
+ _observersAdded: false,
+
+ enable() {
+ if (!this._observersAdded) {
+ this.prefs.addObserver(DISABLE_THRESHOLD_PREF_NAME, this, true);
+ this.prefs.addObserver(CACHE_EXPIRATION_TIME_PREF_NAME, this, true);
+ PlacesUtils.history.addObserver(this, true);
+ this._observersAdded = true;
+ }
+
+ this.cacheLifespan = this.prefs.getIntPref(CACHE_EXPIRATION_TIME_PREF_NAME);
+
+ this.maxpreviews = this.prefs.getIntPref(DISABLE_THRESHOLD_PREF_NAME);
+
+ // If the user toggled us on/off while the browser was already up
+ // (rather than this code running on startup because the pref was
+ // already set to true), we must initialize previews for open windows:
+ if (this.initialized) {
+ let browserWindows = Services.wm.getEnumerator("navigator:browser");
+ while (browserWindows.hasMoreElements()) {
+ let win = browserWindows.getNext();
+ if (!win.closed) {
+ this.onOpenWindow(win);
+ }
+ }
+ }
+ },
+
+ disable() {
+ while (this.windows.length) {
+ // We can't call onCloseWindow here because it'll bail if we're not
+ // enabled.
+ let tabWinObject = this.windows[0];
+ tabWinObject.destroy(); // This will remove us from the array.
+ delete tabWinObject.win.gTaskbarTabGroup; // Tidy up the window.
+ }
+ },
+
+ addPreview: function (preview) {
+ this.previews.push(preview);
+ this.checkPreviewCount();
+ },
+
+ removePreview: function (preview) {
+ let idx = this.previews.indexOf(preview);
+ this.previews.splice(idx, 1);
+ this.checkPreviewCount();
+ },
+
+ checkPreviewCount: function () {
+ if (!this._prefenabled) {
+ return;
+ }
+ this.enabled = this.previews.length <= this.maxpreviews;
+ },
+
+ onOpenWindow: function (win) {
+ // This occurs when the taskbar service is not available (xp, vista)
+ if (!this.available || !this._prefenabled)
+ return;
+
+ win.gTaskbarTabGroup = new TabWindow(win);
+ },
+
+ onCloseWindow: function (win) {
+ // This occurs when the taskbar service is not available (xp, vista)
+ if (!this.available || !this._prefenabled)
+ return;
+
+ win.gTaskbarTabGroup.destroy();
+ delete win.gTaskbarTabGroup;
+
+ if (this.windows.length == 0)
+ this.destroy();
+ },
+
+ resetCacheTimer: function () {
+ this.cacheTimer.cancel();
+ this.cacheTimer.init(this, 1000*this.cacheLifespan, Ci.nsITimer.TYPE_ONE_SHOT);
+ },
+
+ // nsIObserver
+ observe: function (aSubject, aTopic, aData) {
+ if (aTopic == "nsPref:changed" && aData == TOGGLE_PREF_NAME) {
+ this._prefenabled = this.prefs.getBoolPref(TOGGLE_PREF_NAME);
+ }
+ if (!this._prefenabled) {
+ return;
+ }
+ switch (aTopic) {
+ case "nsPref:changed":
+ if (aData == CACHE_EXPIRATION_TIME_PREF_NAME)
+ break;
+
+ if (aData == DISABLE_THRESHOLD_PREF_NAME)
+ this.maxpreviews = this.prefs.getIntPref(DISABLE_THRESHOLD_PREF_NAME);
+ // Might need to enable/disable ourselves
+ this.checkPreviewCount();
+ break;
+ case "timer-callback":
+ this.previews.forEach(function (preview) {
+ let controller = preview.controller.wrappedJSObject;
+ controller.resetCanvasPreview();
+ });
+ break;
+ }
+ },
+
+ /* nsINavHistoryObserver implementation */
+ onBeginUpdateBatch() {},
+ onEndUpdateBatch() {},
+ onVisit() {},
+ onTitleChanged() {},
+ onFrecencyChanged() {},
+ onManyFrecenciesChanged() {},
+ onDeleteURI() {},
+ onClearHistory() {},
+ onDeleteVisits() {},
+ onPageChanged(uri, changedConst, newValue) {
+ if (this.enabled && changedConst == Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
+ for (let win of this.windows) {
+ for (let [tab, ] of win.previews) {
+ if (tab.getAttribute("image") == newValue) {
+ win.onLinkIconAvailable(tab.linkedBrowser, newValue);
+ }
+ }
+ }
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsISupportsWeakReference,
+ Ci.nsINavHistoryObserver,
+ Ci.nsIObserver
+ ]),
+};
+
+XPCOMUtils.defineLazyGetter(AeroPeek, "cacheTimer", () =>
+ Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
+);
+
+XPCOMUtils.defineLazyServiceGetter(AeroPeek, "prefs",
+ "@mozilla.org/preferences-service;1",
+ "nsIPrefBranch");
+
+AeroPeek.initialize();
diff --git a/modules/moz.build b/modules/moz.build
new file mode 100644
index 0000000..12a3ece
--- /dev/null
+++ b/modules/moz.build
@@ -0,0 +1,42 @@
+# -*- 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/.
+
+EXTRA_JS_MODULES += [
+ 'AutoCompletePopup.jsm',
+ 'BrowserNewTabPreloader.jsm',
+ 'CharsetMenu.jsm',
+ 'FormSubmitObserver.jsm',
+ 'FormValidationHandler.jsm',
+ 'NetworkPrioritizer.jsm',
+ 'offlineAppCache.jsm',
+ 'openLocationLastURL.jsm',
+ 'PageMenu.jsm',
+ 'PopupNotifications.jsm',
+ 'QuotaManager.jsm',
+ 'SharedFrame.jsm'
+]
+
+if CONFIG['MOZ_WEBRTC']:
+ EXTRA_JS_MODULES += ['webrtcUI.jsm']
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ EXTRA_JS_MODULES += [
+ 'Windows8WindowFrameColor.jsm',
+ 'WindowsJumpLists.jsm',
+ 'WindowsPreviewPerTab.jsm',
+ ]
+
+EXTRA_PP_JS_MODULES += [
+ 'AboutHomeUtils.jsm',
+ 'RecentWindow.jsm',
+]
+
+# Pass down 'official build' flags
+if CONFIG['MC_OFFICIAL']:
+ DEFINES['MC_OFFICIAL'] = 1
+
+if CONFIG['MOZILLA_OFFICIAL']:
+ DEFINES['MOZILLA_OFFICIAL'] = 1
diff --git a/modules/offlineAppCache.jsm b/modules/offlineAppCache.jsm
new file mode 100644
index 0000000..00ded09
--- /dev/null
+++ b/modules/offlineAppCache.jsm
@@ -0,0 +1,20 @@
+/* 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.EXPORTED_SYMBOLS = ["OfflineAppCacheHelper"];
+
+Components.utils.import('resource://gre/modules/LoadContextInfo.jsm');
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+this.OfflineAppCacheHelper = {
+ clear: function() {
+ var cacheService = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
+ var appCacheStorage = cacheService.appCacheStorage(LoadContextInfo.default, null);
+ try {
+ appCacheStorage.asyncEvictStorage(null);
+ } catch(er) {}
+ }
+};
diff --git a/modules/openLocationLastURL.jsm b/modules/openLocationLastURL.jsm
new file mode 100644
index 0000000..3f58db8
--- /dev/null
+++ b/modules/openLocationLastURL.jsm
@@ -0,0 +1,85 @@
+/* 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 LAST_URL_PREF = "general.open_location.last_url";
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+this.EXPORTED_SYMBOLS = [ "OpenLocationLastURL" ];
+
+var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+var gOpenLocationLastURLData = "";
+
+var observer = {
+ QueryInterface: function (aIID) {
+ if (aIID.equals(Components.interfaces.nsIObserver) ||
+ aIID.equals(Components.interfaces.nsISupports) ||
+ aIID.equals(Components.interfaces.nsISupportsWeakReference))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ },
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "last-pb-context-exited":
+ gOpenLocationLastURLData = "";
+ break;
+ case "browser:purge-session-history":
+ prefSvc.clearUserPref(LAST_URL_PREF);
+ gOpenLocationLastURLData = "";
+ break;
+ }
+ }
+};
+
+var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+os.addObserver(observer, "last-pb-context-exited", true);
+os.addObserver(observer, "browser:purge-session-history", true);
+
+
+this.OpenLocationLastURL = function OpenLocationLastURL(aWindow) {
+ this.window = aWindow;
+}
+
+OpenLocationLastURL.prototype = {
+ isPrivate: function OpenLocationLastURL_isPrivate() {
+ // Assume not in private browsing mode, unless the browser window is
+ // in private mode.
+ if (!this.window)
+ return false;
+
+ return PrivateBrowsingUtils.isWindowPrivate(this.window);
+ },
+ get value() {
+ if (this.isPrivate())
+ return gOpenLocationLastURLData;
+ else {
+ try {
+ return prefSvc.getComplexValue(LAST_URL_PREF, nsISupportsString).data;
+ }
+ catch (e) {
+ return "";
+ }
+ }
+ },
+ set value(val) {
+ if (typeof val != "string")
+ val = "";
+ if (this.isPrivate())
+ gOpenLocationLastURLData = val;
+ else {
+ let str = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(Components.interfaces.nsISupportsString);
+ str.data = val;
+ prefSvc.setComplexValue(LAST_URL_PREF, nsISupportsString, str);
+ }
+ },
+ reset: function() {
+ prefSvc.clearUserPref(LAST_URL_PREF);
+ gOpenLocationLastURLData = "";
+ }
+};
diff --git a/modules/webrtcUI.jsm b/modules/webrtcUI.jsm
new file mode 100644
index 0000000..819ca18
--- /dev/null
+++ b/modules/webrtcUI.jsm
@@ -0,0 +1,292 @@
+/* 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 = ["webrtcUI"];
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
+ "resource://gre/modules/PluralForm.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
+ "@mozilla.org/mediaManagerService;1",
+ "nsIMediaManagerService");
+
+this.webrtcUI = {
+ init: function () {
+ Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
+ Services.obs.addObserver(updateIndicators, "recording-device-events", false);
+ Services.obs.addObserver(removeBrowserSpecificIndicator, "recording-window-ended", false);
+ },
+
+ uninit: function () {
+ Services.obs.removeObserver(handleRequest, "getUserMedia:request");
+ Services.obs.removeObserver(updateIndicators, "recording-device-events");
+ Services.obs.removeObserver(removeBrowserSpecificIndicator, "recording-window-ended");
+ },
+
+ showGlobalIndicator: false,
+
+ get activeStreams() {
+ let contentWindowSupportsArray = MediaManagerService.activeMediaCaptureWindows;
+ let count = contentWindowSupportsArray.Count();
+ let activeStreams = [];
+ for (let i = 0; i < count; i++) {
+ let contentWindow = contentWindowSupportsArray.GetElementAt(i);
+ let browser = getBrowserForWindow(contentWindow);
+ let browserWindow = browser.ownerDocument.defaultView;
+ let tab = browserWindow.gBrowser &&
+ browserWindow.gBrowser._getTabForContentWindow(contentWindow.top);
+ activeStreams.push({
+ uri: contentWindow.location.href,
+ tab: tab,
+ browser: browser
+ });
+ }
+ return activeStreams;
+ }
+}
+
+function getBrowserForWindowId(aWindowID) {
+ return getBrowserForWindow(Services.wm.getOuterWindowWithId(aWindowID));
+}
+
+function getBrowserForWindow(aContentWindow) {
+ return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .chromeEventHandler;
+}
+
+function handleRequest(aSubject, aTopic, aData) {
+ let {windowID: windowID, callID: callID} = JSON.parse(aData);
+
+ let params = aSubject.QueryInterface(Ci.nsIMediaStreamOptions);
+
+ Services.wm.getMostRecentWindow(null).navigator.mozGetUserMediaDevices(
+ function (devices) {
+ prompt(windowID, callID, params.audio, params.video || params.picture, devices);
+ },
+ function (error) {
+ // bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND
+ // and allow the user to plug in a device, instead of immediately failing.
+ denyRequest(callID, error);
+ }
+ );
+}
+
+function denyRequest(aCallID, aError) {
+ let msg = null;
+ if (aError) {
+ msg = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+ msg.data = aError;
+ }
+ Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
+}
+
+function prompt(aWindowID, aCallID, aAudioRequested, aVideoRequested, aDevices) {
+ let audioDevices = [];
+ let videoDevices = [];
+ for (let device of aDevices) {
+ device = device.QueryInterface(Ci.nsIMediaDevice);
+ switch (device.type) {
+ case "audio":
+ if (aAudioRequested)
+ audioDevices.push(device);
+ break;
+ case "video":
+ if (aVideoRequested)
+ videoDevices.push(device);
+ break;
+ }
+ }
+
+ let requestType;
+ if (audioDevices.length && videoDevices.length)
+ requestType = "CameraAndMicrophone";
+ else if (audioDevices.length)
+ requestType = "Microphone";
+ else if (videoDevices.length)
+ requestType = "Camera";
+ else {
+ denyRequest(aCallID, "NO_DEVICES_FOUND");
+ return;
+ }
+
+ let contentWindow = Services.wm.getOuterWindowWithId(aWindowID);
+ let host = contentWindow.document.documentURIObject.host;
+ let browser = getBrowserForWindow(contentWindow);
+ let chromeDoc = browser.ownerDocument;
+ let chromeWin = chromeDoc.defaultView;
+ let stringBundle = chromeWin.gNavigatorBundle;
+ let message = stringBundle.getFormattedString("getUserMedia.share" + requestType + ".message",
+ [ host ]);
+
+ let mainAction = {
+ label: PluralForm.get(requestType == "CameraAndMicrophone" ? 2 : 1,
+ stringBundle.getString("getUserMedia.shareSelectedDevices.label")),
+ accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
+ // The real callback will be set during the "showing" event. The
+ // empty function here is so that PopupNotifications.show doesn't
+ // reject the action.
+ callback: function() {}
+ };
+
+ let secondaryActions = [{
+ label: stringBundle.getString("getUserMedia.denyRequest.label"),
+ accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
+ callback: function () {
+ denyRequest(aCallID);
+ }
+ }];
+
+ let options = {
+ eventCallback: function(aTopic, aNewBrowser) {
+ if (aTopic == "swapping")
+ return true;
+
+ if (aTopic != "showing")
+ return false;
+
+ let chromeDoc = this.browser.ownerDocument;
+
+ function listDevices(menupopup, devices) {
+ while (menupopup.lastChild)
+ menupopup.removeChild(menupopup.lastChild);
+
+ let deviceIndex = 0;
+ for (let device of devices) {
+ addDeviceToList(menupopup, device.name, deviceIndex);
+ deviceIndex++;
+ }
+ }
+
+ function addDeviceToList(menupopup, deviceName, deviceIndex) {
+ let menuitem = chromeDoc.createElement("menuitem");
+ menuitem.setAttribute("value", deviceIndex);
+ menuitem.setAttribute("label", deviceName);
+ menuitem.setAttribute("tooltiptext", deviceName);
+ menupopup.appendChild(menuitem);
+ }
+
+ chromeDoc.getElementById("webRTC-selectCamera").hidden = !videoDevices.length;
+ chromeDoc.getElementById("webRTC-selectMicrophone").hidden = !audioDevices.length;
+
+ let camMenupopup = chromeDoc.getElementById("webRTC-selectCamera-menupopup");
+ let micMenupopup = chromeDoc.getElementById("webRTC-selectMicrophone-menupopup");
+ listDevices(camMenupopup, videoDevices);
+ listDevices(micMenupopup, audioDevices);
+ if (requestType == "CameraAndMicrophone") {
+ let stringBundle = chromeDoc.defaultView.gNavigatorBundle;
+ addDeviceToList(camMenupopup, stringBundle.getString("getUserMedia.noVideo.label"), "-1");
+ addDeviceToList(micMenupopup, stringBundle.getString("getUserMedia.noAudio.label"), "-1");
+ }
+
+ this.mainAction.callback = function() {
+ let allowedDevices = Cc["@mozilla.org/supports-array;1"]
+ .createInstance(Ci.nsISupportsArray);
+ if (videoDevices.length) {
+ let videoDeviceIndex = chromeDoc.getElementById("webRTC-selectCamera-menulist").value;
+ if (videoDeviceIndex != "-1")
+ allowedDevices.AppendElement(videoDevices[videoDeviceIndex]);
+ }
+ if (audioDevices.length) {
+ let audioDeviceIndex = chromeDoc.getElementById("webRTC-selectMicrophone-menulist").value;
+ if (audioDeviceIndex != "-1")
+ allowedDevices.AppendElement(audioDevices[audioDeviceIndex]);
+ }
+
+ if (allowedDevices.Count() == 0) {
+ denyRequest(aCallID);
+ return;
+ }
+
+ Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
+ };
+ return true;
+ }
+ };
+
+ chromeWin.PopupNotifications.show(browser, "webRTC-shareDevices", message,
+ "webRTC-shareDevices-notification-icon", mainAction,
+ secondaryActions, options);
+}
+
+function updateIndicators() {
+ webrtcUI.showGlobalIndicator =
+ MediaManagerService.activeMediaCaptureWindows.Count() > 0;
+
+ let e = Services.wm.getEnumerator("navigator:browser");
+ while (e.hasMoreElements())
+ e.getNext().WebrtcIndicator.updateButton();
+
+ for (let {browser: browser} of webrtcUI.activeStreams)
+ showBrowserSpecificIndicator(browser);
+}
+
+function showBrowserSpecificIndicator(aBrowser) {
+ let hasVideo = {};
+ let hasAudio = {};
+ MediaManagerService.mediaCaptureWindowState(aBrowser.contentWindow,
+ hasVideo, hasAudio);
+ let captureState;
+ if (hasVideo.value && hasAudio.value) {
+ captureState = "CameraAndMicrophone";
+ } else if (hasVideo.value) {
+ captureState = "Camera";
+ } else if (hasAudio.value) {
+ captureState = "Microphone";
+ } else {
+ Cu.reportError("showBrowserSpecificIndicator: got neither video nor audio access");
+ return;
+ }
+
+ let chromeWin = aBrowser.ownerDocument.defaultView;
+ let stringBundle = chromeWin.gNavigatorBundle;
+
+ let message = stringBundle.getString("getUserMedia.sharing" + captureState + ".message2");
+
+ let windowId = aBrowser.contentWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .currentInnerWindowID;
+ let mainAction = {
+ label: "Continue Sharing", //stringBundle.getString("getUserMedia.continueSharing.label"),
+ accessKey: "C", //stringBundle.getString("getUserMedia.continueSharing.accesskey"),
+ callback: function () {},
+ dismiss: true
+ };
+ let secondaryActions = [{
+ label: "Stop Sharing", //stringBundle.getString("getUserMedia.stopSharing.label"),
+ accessKey: "S", //stringBundle.getString("getUserMedia.stopSharing.accesskey"),
+ callback: function () {
+ Services.obs.notifyObservers(null, "getUserMedia:revoke", windowId);
+ }
+ }];
+ let options = {
+ hideNotNow: true,
+ dismissed: true,
+ eventCallback: function(aTopic) aTopic == "swapping"
+ };
+ chromeWin.PopupNotifications.show(aBrowser, "webRTC-sharingDevices", message,
+ "webRTC-sharingDevices-notification-icon", mainAction,
+ secondaryActions, options);
+}
+
+function removeBrowserSpecificIndicator(aSubject, aTopic, aData) {
+ let browser = getBrowserForWindowId(aData);
+ let PopupNotifications = browser.ownerDocument.defaultView.PopupNotifications;
+ let notification = PopupNotifications &&
+ PopupNotifications.getNotification("webRTC-sharingDevices",
+ browser);
+ if (notification)
+ PopupNotifications.remove(notification);
+}
diff --git a/moz.build b/moz.build
new file mode 100644
index 0000000..72e3767
--- /dev/null
+++ b/moz.build
@@ -0,0 +1,24 @@
+# -*- 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/.
+
+CONFIGURE_SUBST_FILES += ['installer/Makefile']
+
+DIRS += [
+ 'base',
+ 'components',
+ 'fonts',
+ 'locales',
+ 'modules',
+ 'themes',
+]
+
+DIRS += ['app']
+
+if CONFIG['MAKENSISU']:
+ DIRS += ['installer/windows']
+
+DIST_SUBDIR = 'browser'
+export('DIST_SUBDIR')
\ No newline at end of file
diff --git a/moz.configure b/moz.configure
new file mode 100644
index 0000000..7223625
--- /dev/null
+++ b/moz.configure
@@ -0,0 +1,7 @@
+# -*- 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
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+include('../../toolkit/moz.configure')
diff --git a/mozconfig.example b/mozconfig.example
new file mode 100644
index 0000000..9b92b92
--- /dev/null
+++ b/mozconfig.example
@@ -0,0 +1,42 @@
+mk_add_options AUTOCLOBBER=1
+mk_add_options MOZ_OBJDIR=/home/$USER/build/wbbuild/
+ac_add_options --enable-application=webbrowser
+
+ac_add_options --enable-optimize="-O2 -march=skylake -fomit-frame-pointer -pipe"
+#ac_add_options --enable-optimize="-O2 -pipe"
+ac_add_options --enable-ccache
+
+#ac_add_options CC=clang
+#ac_add_options CXX=clang++
+
+# Please see https://www.palemoon.org/redist.shtml for restrictions when using the official branding.
+#ac_add_options --enable-official-branding
+ac_add_options --disable-official-branding
+#export MOZILLA_OFFICIAL=1
+
+ac_add_options --enable-default-toolkit=cairo-gtk2
+ac_add_options --enable-jemalloc
+ac_add_options --enable-strip
+ac_add_options --with-pthreads
+ac_add_options --with-system-libevent
+ac_add_options --enable-hardware-aec-ns
+
+ac_add_options --disable-tests
+ac_add_options --disable-eme
+ac_add_options --disable-parental-controls
+ac_add_options --disable-accessibility
+ac_add_options --disable-gamepad
+ac_add_options --disable-necko-wifi
+ac_add_options --disable-updater
+ac_add_options --disable-sync
+ac_add_options --disable-pulseaudio
+ac_add_options --x-libraries=/usr/lib
+
+ac_add_options --enable-private-build
+ac_add_options --enable-webrtc
+ac_add_options --enable-alsa
+ac_add_options --enable-jack
+
+ac_add_options --disable-mozril-geoloc
+
+ac_add_options --with-system-libvpx
diff --git a/themes/LICENSE b/themes/LICENSE
new file mode 100644
index 0000000..39d4f8f
--- /dev/null
+++ b/themes/LICENSE
@@ -0,0 +1,2 @@
+All files in this directory are assumed to be licensed under the MPL 2 license
+which is used throughout this codebase.
diff --git a/themes/linux/Geolocation-16.png b/themes/linux/Geolocation-16.png
new file mode 100644
index 0000000..082b177
Binary files /dev/null and b/themes/linux/Geolocation-16.png differ
diff --git a/themes/linux/Geolocation-64.png b/themes/linux/Geolocation-64.png
new file mode 100644
index 0000000..6e09ab9
Binary files /dev/null and b/themes/linux/Geolocation-64.png differ
diff --git a/themes/linux/Go-arrow.png b/themes/linux/Go-arrow.png
new file mode 100644
index 0000000..259c8a4
Binary files /dev/null and b/themes/linux/Go-arrow.png differ
diff --git a/themes/linux/Info.png b/themes/linux/Info.png
new file mode 100644
index 0000000..d144798
Binary files /dev/null and b/themes/linux/Info.png differ
diff --git a/themes/linux/KUI-close.png b/themes/linux/KUI-close.png
new file mode 100644
index 0000000..08eeb81
Binary files /dev/null and b/themes/linux/KUI-close.png differ
diff --git a/themes/linux/Makefile.in b/themes/linux/Makefile.in
new file mode 100644
index 0000000..3b81bbf
--- /dev/null
+++ b/themes/linux/Makefile.in
@@ -0,0 +1,8 @@
+# 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/.
+
+ICON_FILES := icon.png
+ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
+INSTALL_TARGETS += ICON
+
diff --git a/themes/linux/Privacy-16.png b/themes/linux/Privacy-16.png
new file mode 100644
index 0000000..013cdc4
Binary files /dev/null and b/themes/linux/Privacy-16.png differ
diff --git a/themes/linux/Privacy-32.png b/themes/linux/Privacy-32.png
new file mode 100644
index 0000000..f56dd2d
Binary files /dev/null and b/themes/linux/Privacy-32.png differ
diff --git a/themes/linux/Privacy-48.png b/themes/linux/Privacy-48.png
new file mode 100644
index 0000000..8dd0243
Binary files /dev/null and b/themes/linux/Privacy-48.png differ
diff --git a/themes/linux/Privacy-64.png b/themes/linux/Privacy-64.png
new file mode 100644
index 0000000..106afb4
Binary files /dev/null and b/themes/linux/Privacy-64.png differ
diff --git a/themes/linux/Secure.png b/themes/linux/Secure.png
new file mode 100644
index 0000000..5ee25e9
Binary files /dev/null and b/themes/linux/Secure.png differ
diff --git a/themes/linux/Security-broken.png b/themes/linux/Security-broken.png
new file mode 100644
index 0000000..1ec110b
Binary files /dev/null and b/themes/linux/Security-broken.png differ
diff --git a/themes/linux/Toolbar-small.png b/themes/linux/Toolbar-small.png
new file mode 100644
index 0000000..bcc8f63
Binary files /dev/null and b/themes/linux/Toolbar-small.png differ
diff --git a/themes/linux/Toolbar.png b/themes/linux/Toolbar.png
new file mode 100644
index 0000000..2851657
Binary files /dev/null and b/themes/linux/Toolbar.png differ
diff --git a/themes/linux/aboutCertError.css b/themes/linux/aboutCertError.css
new file mode 100644
index 0000000..dbb3530
--- /dev/null
+++ b/themes/linux/aboutCertError.css
@@ -0,0 +1,73 @@
+/* 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/. */
+
+
+html {
+ background: #833;
+}
+
+body {
+ margin: 0;
+ padding: 0 1em;
+ color: -moz-FieldText;
+ font: message-box;
+}
+
+h1 {
+ margin: 0 0 .6em 0;
+ border-bottom: 1px solid ThreeDLightShadow;
+ font-size: 160%;
+}
+
+h2 {
+ font-size: 130%;
+}
+
+#errorPageContainer {
+ position: relative;
+ min-width: 13em;
+ max-width: 52em;
+ margin: 4em auto;
+ border: 2px solid #DD0D09;
+ border-radius: 10px;
+ box-shadow: 0px 0px 8px red;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat -moz-Field;
+ background-origin: content-box;
+}
+
+#errorPageContainer:-moz-dir(rtl) {
+ background-position: right 0;
+}
+
+#errorTitle {
+ -moz-margin-start: 80px;
+}
+
+#errorLongContent {
+ -moz-margin-start: 80px;
+}
+
+.expander > button {
+ -moz-padding-start: 20px;
+ -moz-margin-start: -20px;
+ background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
+ border: none;
+ font: inherit;
+ color: inherit;
+ cursor: pointer;
+}
+
+.expander > button:-moz-dir(rtl) {
+ background-position: right center;
+}
+
+.expander[collapsed] > button {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
+}
+
+.expander[collapsed] > button:-moz-dir(rtl) {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
+}
diff --git a/themes/linux/aboutCertError_sectionCollapsed-rtl.png b/themes/linux/aboutCertError_sectionCollapsed-rtl.png
new file mode 100644
index 0000000..84ba18c
Binary files /dev/null and b/themes/linux/aboutCertError_sectionCollapsed-rtl.png differ
diff --git a/themes/linux/aboutCertError_sectionCollapsed.png b/themes/linux/aboutCertError_sectionCollapsed.png
new file mode 100644
index 0000000..c9805f6
Binary files /dev/null and b/themes/linux/aboutCertError_sectionCollapsed.png differ
diff --git a/themes/linux/aboutCertError_sectionExpanded.png b/themes/linux/aboutCertError_sectionExpanded.png
new file mode 100644
index 0000000..128cef9
Binary files /dev/null and b/themes/linux/aboutCertError_sectionExpanded.png differ
diff --git a/themes/linux/aboutPrivateBrowsing.css b/themes/linux/aboutPrivateBrowsing.css
new file mode 100644
index 0000000..2bb39d2
--- /dev/null
+++ b/themes/linux/aboutPrivateBrowsing.css
@@ -0,0 +1,47 @@
+%if 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/. */
+%endif
+
+body.private > #errorPageContainer {
+ background-image: url("chrome://browser/skin/Privacy-48.png");
+}
+
+body.normal > #errorPageContainer {
+ background-image: url("moz-icon://stock/gtk-dialog-question?size=dialog");
+}
+
+#clearRecentHistoryDesc {
+ margin-top: 2em;
+}
+
+#clearRecentHistoryDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#startPrivateBrowsingDesc > button {
+ -moz-margin-start: 0;
+}
+
+#footerDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#moreInfo {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+ -moz-padding-start: 25px;
+ background: url("moz-icon://stock/gtk-dialog-info?size=menu") no-repeat top left;
+}
+
+#moreInfo:-moz-dir(rtl) {
+ background-position: top right;
+}
+
+#moreInfoText {
+ margin-bottom: 0;
+}
+
+#moreInfoLinkContainer {
+ margin-top: 0.5em;
+}
diff --git a/themes/linux/aboutSessionRestore-window-icon.png b/themes/linux/aboutSessionRestore-window-icon.png
new file mode 100644
index 0000000..a998323
Binary files /dev/null and b/themes/linux/aboutSessionRestore-window-icon.png differ
diff --git a/themes/linux/aboutSessionRestore.css b/themes/linux/aboutSessionRestore.css
new file mode 100644
index 0000000..a32b975
--- /dev/null
+++ b/themes/linux/aboutSessionRestore.css
@@ -0,0 +1,90 @@
+%if 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/. */
+%endif
+
+html {
+ background: #f8ffd0;
+ height: 100%;
+}
+
+body {
+ height: 100%;
+ text-align: center;
+}
+
+#errorPageContainer {
+ background-image: url("moz-icon://stock/gtk-dialog-warning?size=dialog");
+ display: -moz-box;
+ width: -moz-available;
+ max-width: 85%;
+ height: 75%;
+ max-height: 85%;
+ -moz-box-orient: vertical;
+ text-align: start;
+ border: 2px solid #efc;
+ box-shadow: 0px 0px 8px #aaa;
+}
+
+#errorShortDesc > p {
+ margin-top: 0.4em;
+ margin-bottom: 0;
+}
+
+#errorLongContent, #errorTrailerDesc {
+ display: -moz-box;
+ -moz-box-flex: 1;
+ -moz-box-orient: vertical;
+}
+
+#tabList {
+ margin-top: 2.5em;
+ width: 100%;
+ min-height: 12em;
+}
+
+treechildren::-moz-tree-image(icon),
+treechildren::-moz-tree-image(noicon) {
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+}
+
+treechildren::-moz-tree-image(noicon) {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+treechildren::-moz-tree-image(container, noicon) {
+ list-style-image: url("chrome://browser/skin/aboutSessionRestore-window-icon.png");
+}
+treechildren::-moz-tree-image(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-image(partial) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+/* undo odd row highlighting from tree.css */
+treechildren::-moz-tree-row(odd) {
+ background-color: transparent;
+}
+treechildren::-moz-tree-row(odd, selected, focus) {
+ background-color: Highlight;
+}
+
+/* highlight "windows" instead */
+treechildren::-moz-tree-row(alternate) {
+ background-color: -moz-oddtreerow;
+}
+treechildren::-moz-tree-row(alternate, selected) {
+ background-color: Highlight;
+}
+
+#buttons {
+ -moz-margin-start: 80px; /* same as #errorLongContent in netError.css */
+}
+#buttons > button {
+ margin-top: 2em;
+ -moz-margin-start: 5px;
+}
diff --git a/themes/linux/aboutSyncTabs.css b/themes/linux/aboutSyncTabs.css
new file mode 100644
index 0000000..4f21a9d
--- /dev/null
+++ b/themes/linux/aboutSyncTabs.css
@@ -0,0 +1,101 @@
+/* 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/. */
+
+#tabs-display,
+#tabsList {
+ background-color: transparent;
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#tabsList {
+ width: 100%;
+}
+
+#tabs-display {
+ background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
+}
+
+#headers {
+ background: url(chrome://browser/skin/sync-32.png) no-repeat;
+ margin-top: 4px;
+ width: 45em;
+ height: 32px;
+ -moz-margin-start: 2em;
+ -moz-margin-end: 2em;
+}
+
+#tabsListHeading {
+ font-size: 140%;
+ font-weight: bold;
+ -moz-margin-start: 40px;
+}
+
+richlistitem {
+ -moz-margin-end: 2em;
+}
+
+richlistitem[selected="true"],
+richlistitem:focus {
+ outline-style: none;
+}
+
+richlistitem[type="tab"] {
+ min-height: 3em;
+ border: #999999 1px solid !important;
+ padding: 2px 5px;
+ margin-bottom: 4px;
+ -moz-margin-start: 4em;
+ border-radius: 6px;
+ background-color: menu;
+ width: 44em;
+ opacity: 0.9;
+ box-shadow:
+ inset rgba(255, 255, 255, 0.5) 0 1px 0px,
+ inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
+ rgba(0, 0, 0, 0.1) 0px 1px 0px;
+}
+
+richlistitem[type="tab"][selected="true"] {
+ background-color: -moz-MenuHover;
+}
+
+richlistitem[type="client"] {
+ min-height: 2em;
+ color: #000000;
+ -moz-margin-start: 2em;
+ margin-top: 2px;
+ margin-bottom: 3px;
+ width: 42em;
+ border-radius: 6px;
+ background-color: transparent;
+ -moz-user-focus: ignore !important;
+}
+richlistitem.mobile[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+}
+richlistitem.desktop[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+}
+
+.title,
+.clientName {
+ color: #000000;
+ font-size: 1.1em;
+}
+
+.title[selected="true"],
+.url[selected="true"] {
+ color: inherit;
+}
+
+.url {
+ color: -moz-nativehyperlinktext;
+ font-size: 0.95em;
+}
+
+.tabIcon {
+ -moz-padding-start: 2px;
+ padding-top: 2px;
+}
diff --git a/themes/linux/actionicon-tab.png b/themes/linux/actionicon-tab.png
new file mode 100644
index 0000000..433c25e
Binary files /dev/null and b/themes/linux/actionicon-tab.png differ
diff --git a/themes/linux/autocomplete.css b/themes/linux/autocomplete.css
new file mode 100644
index 0000000..ab92685
--- /dev/null
+++ b/themes/linux/autocomplete.css
@@ -0,0 +1,210 @@
+/* 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/. */
+
+/* ===== autocomplete.css =================================================
+ == Styles used by the autocomplete widget.
+ ======================================================================= */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* ::::: autocomplete ::::: */
+
+/* .padded is used by autocomplete widgets that don't have an icon. Gross. -dwh */
+textbox:not(.padded) {
+ cursor: default;
+ padding: 0;
+}
+
+textbox[enablehistory="true"] {
+ -moz-appearance: none;
+ border: 0;
+ background-color: transparent;
+}
+
+textbox[nomatch="true"][highlightnonmatches="true"] {
+ color: red;
+}
+
+.private-autocomplete-textbox-container {
+ -moz-box-align: center;
+}
+
+textbox[enablehistory="true"] > .autocomplete-textbox-container {
+ -moz-appearance: menulist-textfield;
+}
+
+textbox:not(.padded) .textbox-input-box {
+ margin: 0 3px;
+}
+
+.textbox-input-box {
+ -moz-box-align: center;
+}
+
+/* ::::: autocomplete popups ::::: */
+
+panel[type="private-autocomplete"],
+panel[type="private-autocomplete-richlistbox"],
+.private-autocomplete-history-popup {
+ border-width: 1px;
+ -moz-border-top-colors: ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDDarkShadow;
+ -moz-border-bottom-colors: ThreeDDarkShadow;
+ -moz-border-left-colors: ThreeDDarkShadow;
+ padding: 0;
+ background-color: -moz-Field;
+}
+
+.private-autocomplete-history-popup {
+ max-height: 180px;
+}
+
+/* ::::: tree ::::: */
+
+.private-autocomplete-tree {
+ -moz-appearance: none !important;
+ border: none !important;
+ background-color: transparent !important;
+ color: MenuText;
+}
+
+.private-autocomplete-treecol {
+ -moz-appearance: none !important;
+ margin: 0 !important;
+ border: none !important;
+ padding: 0 !important;
+}
+
+/* GTK calculates space for a sort arrow */
+.private-autocomplete-treecol > .treecol-sortdirection {
+ -moz-appearance: none !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-cell-text {
+ -moz-padding-start: 8px;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-row(selected) {
+ background-color: Highlight;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-cell-text(selected) {
+ color: HighlightText !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-image(treecolAutoCompleteValue) {
+ max-width: 16px;
+ height: 16px;
+}
+
+/* ::::: richlistbox autocomplete ::::: */
+
+.private-autocomplete-richlistbox {
+ -moz-appearance: none;
+ margin: 1px;
+ background-color: transparent;
+}
+
+.private-autocomplete-richlistitem[selected="true"] {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+.private-autocomplete-richlistitem {
+ padding: 6px 2px;
+ color: MenuText;
+}
+
+.ac-url-box {
+ /* When setting a vertical margin here, half of that needs to be added
+ .ac-title-box's translateY for when .ac-url-box is hidden (see below). */
+ margin-top: 1px;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-url-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-url-box {
+ visibility: hidden;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-title-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-title-box {
+ /* Center the title by moving it down by half of .ac-url-box's height,
+ including vertical margins (if any). */
+ transform: translateY(.5em);
+}
+
+.ac-site-icon {
+ width: 16px;
+ height: 16px;
+ margin-bottom: -2px;
+ -moz-margin-start: 3px;
+ -moz-margin-end: 6px;
+}
+
+.ac-type-icon {
+ width: 16px;
+ height: 16px;
+ -moz-margin-start: 6px;
+ -moz-margin-end: 4px;
+}
+
+.ac-extra > .ac-result-type-tag {
+ margin: 0 4px;
+}
+
+.ac-extra > .ac-comment {
+ padding-right: 4px;
+}
+
+.ac-ellipsis-after {
+ margin: 0 !important;
+ padding: 0;
+ min-width: 1em;
+}
+
+.ac-normal-text {
+ margin: 0 !important;
+ padding: 0;
+}
+
+.ac-normal-text > html|span {
+ margin: 0 !important;
+ padding: 0;
+}
+
+html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(0,0,0,0.1);
+ background-color: rgba(0,0,0,0.05);
+ border-radius: 2px;
+ text-shadow: 0 0 currentColor; /*faux bold effect*/
+}
+
+.ac-url-text > html|span.ac-emphasize-text,
+.ac-action-text > html|span.ac-emphasize-text {
+ box-shadow: none;
+}
+
+.ac-normal-text[selected="true"] > html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.3);
+ background-color: rgba(255,255,255,0.2);
+}
+
+.ac-title, .ac-url {
+ overflow: hidden;
+}
+
+/* ::::: textboxes inside toolbarpaletteitems ::::: */
+
+toolbarpaletteitem > toolbaritem > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
+
+toolbarpaletteitem > toolbaritem > * > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
diff --git a/themes/linux/browser.css b/themes/linux/browser.css
new file mode 100644
index 0000000..4933b40
--- /dev/null
+++ b/themes/linux/browser.css
@@ -0,0 +1,2210 @@
+%if 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/. */
+%endif
+
+@import url("chrome://global/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+%include ../shared/browser.inc
+%filter substitution
+%define toolbarHighlight rgba(255,255,255,.3)
+%define selectedTabHighlight rgba(255,255,255,.8) 1px, rgba(255,255,255,.5) 3px
+%define forwardTransitionLength 150ms
+%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons], #nav-bar:not([currentset])[mode=icons]) > #unified-back-forward-button
+%define conditionalForwardWithUrlbar_small window:not([chromehidden~=toolbar]) :-moz-any(#nav-bar[currentset*="unified-back-forward-button,urlbar-container"][mode=icons][iconsize=small],#nav-bar:not([currentset])[mode=icons][iconsize=small]) > #unified-back-forward-button
+
+#menubar-items {
+ -moz-box-orient: vertical; /* for flex hack */
+}
+
+#main-menubar {
+ -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
+}
+
+#navigator-toolbox {
+ -moz-appearance: none;
+ background-color: transparent;
+ border-top: none;
+}
+
+#main-window:not([disablechrome]) #navigator-toolbox[tabsontop=true] {
+ border-bottom: 1px solid ThreeDShadow;
+}
+
+#navigator-toolbox[tabsontop=true] > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar):not(#TabsToolbar),
+#navigator-toolbox[tabsontop=false] > toolbar:not(:-moz-lwtheme):not(#toolbar-menubar) {
+ -moz-appearance: none;
+ border-style: none;
+ background-color: -moz-Dialog;
+}
+
+#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+#nav-bar:not(:-moz-lwtheme),
+#nav-bar[collapsed=true] + toolbar:not(:-moz-lwtheme),
+#nav-bar[collapsed=true] + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
+#nav-bar[tabsontop=true],
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
+}
+
+#nav-bar[tabsontop=true]:-moz-lwtheme,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(rgba(255,255,255,.8), rgba(255,255,255,0));
+}
+
+#nav-bar[tabsontop=true]:-moz-lwtheme-brighttext,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme-brighttext + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme-brighttext + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(rgba(32,32,32,.8), rgba(32,32,32,0));
+}
+
+#personal-bookmarks {
+ min-height: 29px;
+}
+
+#browser-bottombox {
+ /* opaque for layers optimization */
+ background-color: -moz-Dialog;
+}
+
+#urlbar:-moz-lwtheme:not([focused="true"]),
+.searchbar-textbox:-moz-lwtheme:not([focused="true"]) {
+ opacity: .85;
+}
+
+/* Places toolbar */
+toolbarbutton.bookmark-item {
+ margin: 0;
+ padding: 2px 3px;
+}
+
+toolbarbutton.bookmark-item:hover:active,
+toolbarbutton.bookmark-item[open="true"] {
+ padding-top: 3px;
+ padding-bottom: 1px;
+ -moz-padding-start: 4px;
+ -moz-padding-end: 2px;
+}
+
+.bookmark-item > .toolbarbutton-icon {
+ width: 16px;
+ height: 16px;
+}
+
+/* Prevent [mode="icons"] from hiding the label */
+.bookmark-item > .toolbarbutton-text {
+ display: -moz-box !important;
+}
+
+.bookmark-item > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+/* Dropmarker for folder bookmarks */
+.bookmark-item[container] > .toolbarbutton-menu-dropmarker {
+ display: -moz-box !important;
+}
+
+#wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
+ background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
+}
+
+.bookmarks-toolbar-customize {
+ max-width: 15em !important;
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+}
+
+/* Bookmark menus */
+menu.bookmark-item,
+menuitem.bookmark-item {
+ min-width: 0;
+ max-width: 32em;
+}
+
+.bookmark-item > .menu-iconic-left {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.bookmark-item > .menu-iconic-left > .menu-iconic-icon {
+ -moz-padding-start: 0px;
+}
+
+/* Bookmark drag and drop styles */
+.bookmark-item[dragover-into="true"] {
+ background: Highlight !important;
+ color: HighlightText !important;
+}
+
+/* rules for menupopup drop indicators */
+.menupopup-drop-indicator-bar {
+ position: relative;
+ /* these two margins must together compensate the indicator's height */
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+.menupopup-drop-indicator {
+ list-style-image: none;
+ height: 2px;
+ -moz-margin-end: -4em;
+ background-color: Highlight;
+}
+
+/* Bookmarks toolbar */
+#PlacesToolbarDropIndicator {
+ list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
+}
+
+/* Bookmark items */
+.bookmark-item {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.bookmark-item[container] {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+.bookmark-item[container][livemark] {
+ list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+}
+
+.bookmark-item[container][livemark] .bookmark-item {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.bookmark-item[container][livemark] .bookmark-item[visited] {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.bookmark-item[container][query] {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+}
+
+.bookmark-item[query][tagContainer] {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+}
+
+.bookmark-item[query][dayContainer] {
+ list-style-image: url("chrome://browser/skin/places/calendar.png");
+}
+
+.bookmark-item[query][hostContainer] {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+.bookmark-item[query][hostContainer][open] {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+.bookmark-item[cutting] > .toolbarbutton-icon,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
+ opacity: 0.5;
+}
+
+.bookmark-item[cutting] > .toolbarbutton-text,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
+ opacity: 0.7;
+}
+
+/* Stock icons for the menu bar items */
+menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
+ -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
+}
+
+#appmenu_newNavigator,
+#placesContext_open\:newwindow,
+#menu_newNavigator,
+#context-openlink,
+#context-openframe {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 80px 16px 64px);
+}
+
+#appmenu_newTab,
+#appmenu_newTab_popup,
+#placesContext_open\:newtab,
+#placesContext_openContainer\:tabs,
+#menu_newNavigatorTab,
+#context-openlinkintab,
+#context-openframeintab {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 64px 16px 48px);
+}
+
+#appmenu_openFile,
+#menu_openFile {
+ list-style-image: url("moz-icon://stock/gtk-open?size=menu");
+}
+
+#menu_close {
+ list-style-image: url("moz-icon://stock/gtk-close?size=menu");
+}
+
+#context-media-play {
+ list-style-image: url("moz-icon://stock/gtk-media-play?size=menu");
+}
+
+#context-media-pause {
+ list-style-image: url("moz-icon://stock/gtk-media-pause?size=menu");
+}
+
+#appmenu_savePage,
+#menu_savePage,
+#context-savelink,
+#context-saveimage,
+#context-savevideo,
+#context-saveaudio,
+#context-savepage,
+#context-saveframe {
+ list-style-image: url("moz-icon://stock/gtk-save-as?size=menu");
+}
+
+#appmenu_printPreview,
+#menu_printPreview {
+ list-style-image: url("moz-icon://stock/gtk-print-preview?size=menu");
+}
+
+#appmenu_print,
+#appmenu_print_popup,
+#menu_print,
+#context-printframe {
+ list-style-image: url("moz-icon://stock/gtk-print?size=menu");
+}
+
+#appmenu-quit,
+#menu_FileQuitItem {
+ list-style-image: url("moz-icon://stock/gtk-quit?size=menu");
+}
+
+#menu_undo,
+#context-undo {
+ list-style-image: url("moz-icon://stock/gtk-undo?size=menu");
+}
+
+#menu_undo[disabled],
+#context-undo[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-undo?size=menu&state=disabled");
+}
+
+#menu_redo {
+ list-style-image: url("moz-icon://stock/gtk-redo?size=menu");
+}
+
+#menu_redo[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-redo?size=menu&state=disabled");
+}
+
+#menu_cut,
+#placesContext_cut,
+#context-cut {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
+}
+
+#menu_cut[disabled],
+#placesContext_cut[disabled],
+#context-cut[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
+}
+
+#menu_copy,
+#placesContext_copy,
+#context-copy,
+#context-copyimage,
+#context-copyvideourl,
+#context-copyaudiourl,
+#context-copylink,
+#context-copyemail {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
+}
+
+#menu_copy[disabled],
+#placesContext_copy[disabled],
+#context-copy[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
+}
+
+#menu_paste,
+#placesContext_paste,
+#context-paste {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
+}
+
+#menu_paste[disabled],
+#placesContext_paste[disabled],
+#context-paste[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
+}
+
+#menu_delete,
+#placesContext_delete,
+#placesContext_delete_history,
+#context-delete {
+ list-style-image: url("moz-icon://stock/gtk-delete?size=menu");
+}
+
+#menu_delete[disabled],
+#placesContext_delete[disabled],
+#placesContext_delete_history[disabled],
+#context-delete[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-delete?size=menu&state=disabled");
+}
+
+#menu_selectAll,
+#context-selectall {
+ list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
+}
+
+#appmenu_find,
+#menu_find {
+ list-style-image: url("moz-icon://stock/gtk-find?size=menu");
+}
+
+#menu_find[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-find?size=menu&state=disabled");
+}
+
+#appmenu_customize,
+#appmenu_preferences,
+#menu_preferences {
+ list-style-image: url("moz-icon://stock/gtk-preferences?size=menu");
+}
+
+#menu_stop,
+#context-stop {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
+}
+
+#menu_stop[disabled],
+#context-stop[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
+}
+
+#menu_reload,
+#placesContext_reload,
+#context-reload,
+#context-reloadframe {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
+}
+
+#menu_reload[disabled],
+#context-reload[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu&state=disabled");
+}
+
+#menu_zoomEnlarge {
+ list-style-image: url("moz-icon://stock/gtk-zoom-in?size=menu");
+}
+
+#menu_zoomReduce {
+ list-style-image: url("moz-icon://stock/gtk-zoom-out?size=menu");
+}
+
+#menu_zoomReset {
+ list-style-image: url("moz-icon://stock/gtk-zoom-100?size=menu");
+}
+
+#historyMenuBack,
+#context-back {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
+}
+
+#historyMenuBack[disabled],
+#context-back[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
+}
+
+#historyMenuBack:-moz-locale-dir(rtl),
+#context-back:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
+}
+
+#historyMenuBack[disabled]:-moz-locale-dir(rtl),
+#context-back[disabled]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
+}
+
+#historyMenuForward,
+#context-forward {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
+}
+
+#historyMenuForward[disabled],
+#context-forward[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
+}
+
+#historyMenuForward:-moz-locale-dir(rtl),
+#context-forward:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
+}
+
+#historyMenuForward[disabled]:-moz-locale-dir(rtl),
+#context-forward[disabled]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
+}
+
+#historyMenuHome {
+ list-style-image: url("moz-icon://stock/gtk-home?size=menu");
+}
+
+#appmenu_history,
+#appmenu_showAllHistory,
+#menu_showAllHistory,
+#HMB_showAllHistory {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#appmenu_bookmarks,
+#appmenu_showAllBookmarks,
+#bookmarksShowAll,
+#BMB_bookmarksShowAll {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+#appmenu_subscribeToPage:not([disabled]),
+#appmenu_subscribeToPageMenu,
+#subscribeToPageMenuitem:not([disabled]),
+#subscribeToPageMenupopup,
+#BMB_subscribeToPageMenuitem:not([disabled]),
+#BMB_subscribeToPageMenupopup {
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+#appmenu_bookmarksToolbar,
+#bookmarksToolbarFolderMenu,
+#BMB_bookmarksToolbar {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+}
+
+#appmenu_bookmarkThisPage,
+#menu_bookmarkThisPage,
+#BMB_bookmarkThisPage {
+ list-style-image: url("chrome://browser/skin/places/starPage.png");
+}
+
+#appmenu_unsortedBookmarks,
+#menu_unsortedBookmarks,
+#BMB_unsortedBookmarks {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+}
+
+#appmenu_downloads,
+#menu_openDownloads {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+#appmenu_addons,
+#menu_openAddons {
+ list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
+}
+
+#menu_pageInfo,
+#context-viewinfo,
+#context-viewframeinfo {
+ list-style-image: url("moz-icon://stock/gtk-info?size=menu");
+}
+
+#appmenu_privateBrowsing,
+#appmenu_newPrivateWindow,
+#placesContext_open\:newprivatewindow,
+#privateBrowsingItem {
+ list-style-image: url("chrome://browser/skin/Privacy-16.png");
+}
+
+#placesContext_show\:info {
+ list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
+}
+
+#appmenu_sanitizeHistory,
+#sanitizeItem,
+#HMB_sanitizeItem {
+ list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
+}
+
+#appmenu_help,
+#appmenu_openHelp,
+#menu_openHelp {
+ list-style-image: url("moz-icon://stock/gtk-help?size=menu");
+}
+
+#appmenu_about,
+#aboutName {
+ list-style-image: url("moz-icon://stock/gtk-about?size=menu");
+}
+
+#javascriptConsole {
+ list-style-image: url("chrome://global/skin/console/console.png");
+}
+
+/* Primary toolbar buttons */
+.toolbarbutton-1:not([type="menu-button"]) {
+ -moz-box-orient: vertical;
+ min-width: 0;
+ list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+
+.toolbarbutton-1 > .toolbarbutton-icon {
+ -moz-margin-end: 0;
+}
+
+toolbar[mode="full"] .toolbarbutton-1:not([type="menu-button"]),
+toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ min-width: 57px;
+}
+
+.toolbarbutton-1:not([type="menu-button"]),
+.toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ padding: 5px;
+}
+
+.toolbarbutton-1[checked="true"] {
+ padding: 5px !important;
+}
+
+/* 24px primary toolbar buttons */
+#back-button {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
+}
+#back-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
+}
+
+#back-button:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
+}
+#back-button[disabled="true"]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
+}
+
+#forward-button/*,
+ @conditionalForwardWithUrlbar@ > #forward-button */{
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
+}
+#forward-button:-moz-locale-dir(rtl)/*,
+@conditionalForwardWithUrlbar@ > #forward-button:-moz-locale-dir(rtl) */{
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
+}
+
+#forward-button[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
+}
+#forward-button[disabled]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
+}
+
+/*@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
+ transition: @forwardTransitionLength@ ease-out;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button[disabled] {
+ transform: scale(0);
+ opacity: 0;
+ pointer-events: none;
+}*/
+
+#reload-button {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar");
+}
+#reload-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=toolbar&state=disabled");
+}
+
+#stop-button {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=toolbar");
+}
+#stop-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=toolbar&state=disabled");
+}
+
+#home-button {
+ list-style-image: url("moz-icon://stock/gtk-home?size=toolbar");
+}
+#home-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-home?size=toolbar&state=disabled");
+}
+
+#downloads-button {
+ -moz-image-region: rect(0px 24px 24px 0px);
+}
+
+#history-button,
+#history-menu-button {
+ -moz-image-region: rect(0px 48px 24px 24px);
+}
+
+#history-menu-button.toolbarbutton-1 {
+ -moz-box-orient: horizontal;
+}
+
+#bookmarks-button,
+#bookmarks-menu-button {
+ -moz-image-region: rect(0px 72px 24px 48px);
+}
+
+#bookmarks-menu-button.bookmark-item {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+}
+
+#bookmarks-menu-button.toolbarbutton-1 {
+ -moz-box-orient: horizontal;
+}
+
+#print-button {
+ list-style-image: url("moz-icon://stock/gtk-print?size=toolbar");
+}
+#print-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-print?size=toolbar&state=disabled");
+}
+
+#new-tab-button {
+ -moz-image-region: rect(0px 96px 24px 72px);
+}
+
+#new-window-button {
+ -moz-image-region: rect(0px 120px 24px 96px);
+}
+
+#cut-button {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar");
+}
+#cut-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=toolbar&state=disabled");
+}
+
+#copy-button {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar");
+}
+#copy-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=toolbar&state=disabled");
+}
+
+#paste-button {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar");
+}
+#paste-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled");
+}
+
+#fullscreen-button {
+ list-style-image: url("moz-icon://stock/gtk-fullscreen?size=toolbar");
+}
+
+#zoom-out-button {
+ list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar");
+}
+
+#zoom-in-button {
+ list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar");
+}
+
+#sync-button {
+ -moz-image-region: rect(0px 144px 24px 120px);
+}
+#sync-button[status="active"] {
+ list-style-image: url("chrome://browser/skin/sync-24-throbber.png");
+ -moz-image-region: rect(0px 24px 24px 0px);
+}
+
+#feed-button {
+ -moz-image-region: rect(0px 168px 24px 144px);
+}
+
+#feed-button[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+%ifdef MOZ_WEBRTC
+#webrtc-status-button {
+ -moz-image-region: rect(0px 192px 24px 168px);
+}
+%endif
+
+/* 16px primary toolbar buttons */
+toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) {
+ -moz-box-orient: vertical;
+ min-width: 0;
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+}
+
+toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
+ border: 0 !important;
+}
+
+toolbar[iconsize="small"] #back-button {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
+}
+.unified-nav-back[_moz-menuactive] {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu") !important;
+}
+toolbar[iconsize="small"] #back-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #back-button:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
+}
+.unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu") !important;
+}
+toolbar[iconsize="small"] #back-button[disabled="true"]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
+}
+
+toolbar[iconsize=small] #forward-button,
+@conditionalForwardWithUrlbar_small@ > #forward-button {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
+}
+.unified-nav-forward[_moz-menuactive] {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
+}
+toolbar[iconsize=small] #forward-button[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
+}
+
+toolbar[iconsize=small] #forward-button:-moz-locale-dir(rtl),
+@conditionalForwardWithUrlbar_small@ > #forward-button:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
+}
+.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu") !important;
+}
+toolbar[iconsize=small] #forward-button[disabled]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #stop-button {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
+}
+toolbar[iconsize="small"] #stop-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #reload-button {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
+}
+toolbar[iconsize="small"] #reload-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #home-button,
+#home-button.bookmark-item {
+ list-style-image: url("moz-icon://stock/gtk-home?size=menu");
+}
+toolbar[iconsize="small"] #home-button[disabled="true"],
+#home-button.bookmark-item[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-home?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #downloads-button {
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+%ifdef MOZ_WEBRTC
+toolbar[iconsize="small"] #webrtc-status-button /* temporary placeholder (bug 824825) */,
+%endif
+toolbar[iconsize="small"] #history-button,
+toolbar[iconsize="small"] #history-menu-button {
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+toolbar[iconsize="small"] #bookmarks-button,
+toolbar[iconsize="small"] #bookmarks-menu-button,
+#bookmarks-menu-button.bookmark-item {
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+toolbar[iconsize="small"] #print-button {
+ list-style-image: url("moz-icon://stock/gtk-print?size=menu");
+}
+toolbar[iconsize="small"] #print-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-print?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #new-tab-button {
+ -moz-image-region: rect(0px 64px 16px 48px);
+}
+
+toolbar[iconsize="small"] #new-window-button {
+ -moz-image-region: rect(0px 80px 16px 64px);
+}
+
+toolbar[iconsize="small"] #cut-button {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
+}
+toolbar[iconsize="small"] #cut-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #copy-button {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
+}
+toolbar[iconsize="small"] #copy-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #paste-button {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
+}
+toolbar[iconsize="small"] #paste-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
+}
+
+toolbar[iconsize="small"] #fullscreen-button {
+ list-style-image: url("moz-icon://stock/gtk-fullscreen?size=menu");
+}
+
+toolbar[iconsize="small"] #zoom-out-button {
+ list-style-image: url("moz-icon://stock/gtk-zoom-out?size=menu");
+}
+
+toolbar[iconsize="small"] #zoom-in-button {
+ list-style-image: url("moz-icon://stock/gtk-zoom-in?size=menu");
+}
+
+toolbar[iconsize="small"] #sync-button {
+ -moz-image-region: rect(0px 96px 16px 80px);
+}
+toolbar[iconsize="small"] #sync-button[status="active"] {
+ list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+toolbar[iconsize="small"] #feed-button {
+ -moz-image-region: rect(0px 112px 16px 96px);
+}
+
+%ifdef MOZ_WEBRTC
+toolbar[iconsize="small"] #webrtc-status-button {
+ -moz-image-region: rect(0px 128px 16px 112px);
+}
+%endif
+
+/* Fullscreen window controls */
+#window-controls {
+ -moz-box-align: start;
+ -moz-margin-start: 10px;
+}
+
+#minimize-button {
+ list-style-image: url("chrome://global/skin/icons/Minimize.gif");
+}
+#restore-button {
+ list-style-image: url("chrome://global/skin/icons/Restore.gif");
+}
+#close-button {
+ list-style-image: url("chrome://global/skin/icons/Close.gif");
+}
+
+/* Location bar */
+#urlbar {
+ width: 7em;
+ -moz-appearance: textfield;
+ padding: 0;
+}
+
+.urlbar-textbox-container {
+ -moz-appearance: none;
+ -moz-box-align: stretch;
+}
+
+.urlbar-input-box {
+ -moz-margin-start: 0;
+ min-width: 4em;
+}
+
+.urlbar-history-dropmarker {
+ -moz-appearance: toolbarbutton-dropdown;
+}
+
+#urlbar-container {
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+}
+
+#urlbar-icons {
+ -moz-box-align: center;
+}
+
+.urlbar-icon {
+ cursor: pointer;
+ padding: 0 3px;
+}
+
+#urlbar-search-splitter {
+ -moz-appearance: none;
+ width: 8px;
+ -moz-margin-start: -4px;
+}
+
+#urlbar-search-splitter + #urlbar-container > #urlbar ,
+#urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
+ -moz-margin-start: 0;
+}
+
+#urlbar-display-box {
+ margin-top: -1px;
+ margin-bottom: -1px;
+ -moz-border-end: 1px solid #AAA;
+ -moz-margin-end: 3px;
+}
+
+#urlbar-display {
+ margin-top: 0;
+ margin-bottom: 0;
+ -moz-margin-start: 0;
+ color: GrayText;
+}
+
+/* Favicon */
+#page-proxy-favicon {
+ width: 16px;
+ height: 16px;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ -moz-margin-start: 4px;
+ -moz-margin-end: 3px;
+ list-style-image: url(chrome://browser/skin/identity-icons-generic.png);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+/* Since we already have a padlock, always use the generic icon until the favicon loads
+.verifiedDomain > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https.png);
+}
+
+.verifiedIdentity > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
+}
+
+.mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
+}
+*/
+
+#identity-box:hover > #page-proxy-favicon {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#identity-box:hover:active > #page-proxy-favicon,
+#identity-box[open=true] > #page-proxy-favicon {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#page-proxy-favicon[pageproxystate="invalid"] {
+ opacity: 0.3;
+}
+
+/* Identity indicator */
+#identity-box {
+ padding: 1px;
+ margin: -1px;
+ -moz-margin-end: 0;
+ font-size: .9em;
+}
+
+#identity-box:-moz-locale-dir(ltr) {
+ border-top-left-radius: 2.5px;
+ border-bottom-left-radius: 2.5px;
+}
+
+#identity-box:-moz-locale-dir(rtl) {
+ border-top-right-radius: 2.5px;
+ border-bottom-right-radius: 2.5px;
+}
+
+#identity-box:-moz-focusring {
+ outline: 1px dotted #000;
+ outline-offset: -3px;
+}
+
+#identity-icon-labels {
+ -moz-padding-start: 2px;
+ -moz-padding-end: 5px;
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity {
+ color: rgb(95,127,67);
+ -moz-margin-end: 4px;
+ background-image: linear-gradient(rgba(226,246,208,1),
+ rgba(203,235,177,1));
+ background-position: right;
+ background-repeat: no-repeat;
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedDomain {
+ color: rgb(51,87,137);
+ -moz-margin-end: 4px;
+ background-image: linear-gradient(rgba(220,231,245,1),
+ rgba(207,221,242,1));
+ background-position: right;
+ background-repeat: no-repeat;
+}
+
+#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
+ background-position: left;
+}
+
+/* Address bar shading for SSL */
+
+#urlbar[https_color="all"][security_level="broken"],
+#urlbar[https_color="all"][security_level="low"] {
+ box-shadow: inset 0 0 4px rgb(168,0,0);
+}
+
+#urlbar[https_color="all"][security_level="mixed"],
+#urlbar[https_color="secure-mixed"][security_level="mixed"] {
+ box-shadow: inset 0 0 4px rgb(168,79,0);
+}
+
+#urlbar[https_color="all"][security_level="high"],
+#urlbar[https_color="secure-mixed"][security_level="high"],
+#urlbar[https_color="secure-only"][security_level="high"] {
+ box-shadow: inset 0 0 4px rgb(0,79,168);
+}
+
+#urlbar[https_color="all"][security_level="ev"],
+#urlbar[https_color="secure-mixed"][security_level="ev"],
+#urlbar[https_color="secure-only"][security_level="ev"] {
+ box-shadow: inset 0 0 4px rgb(0,168,0);
+}
+
+#urlbar[https_color="all"]:-moz-lwtheme-darktext,
+#urlbar[https_color="secure-mixed"]:-moz-lwtheme-darktext,
+#urlbar[https_color="secure-only"]:-moz-lwtheme-darktext {
+ box-shadow: inset 0 0 2px;
+}
+
+/* Identity popup icons */
+#identity-popup-icon {
+ height: 64px;
+ width: 64px;
+ padding: 0;
+ list-style-image: url("chrome://browser/skin/identity.png");
+ -moz-image-region: rect(0px, 64px, 64px, 0px);
+}
+
+#identity-popup.verifiedDomain > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(64px, 64px, 128px, 0px);
+}
+
+#identity-popup.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(128px, 64px, 192px, 0px);
+}
+
+/* Identity popup body text */
+.identity-popup-description {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 2px 0 4px;
+}
+
+.identity-popup-label {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 0;
+}
+
+#identity-popup-content-host ,
+#identity-popup-content-owner {
+ font-weight: bold;
+ max-width: 300px;
+}
+
+#identity-popup-content-host ,
+#identity-popup-content-box.verifiedIdentity > #identity-popup-content-owner {
+ font-size: 140%;
+}
+
+#identity-popup-content-owner {
+ margin-bottom: 0 !important;
+}
+
+#identity-popup-content-verifier {
+ margin: 4px 0 2px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption {
+ margin-top: 10px;
+ -moz-margin-start: -18px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption > vbox > #identity-popup-encryption-icon ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon {
+ list-style-image: url("chrome://browser/skin/Secure.png");
+}
+
+/* Identity popup bounding box */
+#identity-popup-container {
+ min-width: 280px;
+}
+
+/* Notification popup */
+#notification-popup {
+ min-width: 280px;
+}
+
+.popup-notification-icon {
+ width: 64px;
+ height: 64px;
+ -moz-margin-end: 10px;
+}
+
+.popup-notification-icon[popupid="geolocation"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+
+.popup-notification-icon[popupid="push"] {
+ list-style-image: url(chrome://browser/skin/Push-64.png);
+}
+
+.popup-notification-icon[popupid="xpinstall-disabled"],
+.popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-origin-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
+ width: 32px;
+ height: 32px;
+}
+
+.popup-notification-icon[popupid="click-to-play-plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
+}
+
+.popup-notification-icon[popupid="web-notifications"] {
+ list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+
+.addon-progress-description {
+ width: 350px;
+ max-width: 350px;
+}
+
+.popup-progress-label,
+.popup-progress-meter {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+.popup-progress-cancel {
+ -moz-appearance: none;
+ background: transparent;
+ border: none;
+ padding: 0;
+ margin: 0;
+ -moz-margin-start: 5px;
+ min-height: 0;
+ min-width: 0;
+ list-style-image: url("moz-icon://stock/gtk-cancel?size=menu");
+}
+
+.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+.popup-notification-icon[popupid="indexedDB-quota-prompt"],
+.popup-notification-icon[popupid*="offline-app-requested"],
+.popup-notification-icon[popupid="offline-app-usage"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+
+.popup-notification-icon[popupid="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+
+.popup-notification-icon[popupid="mixed-content-blocked"] {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+}
+
+%ifdef MOZ_WEBRTC
+.popup-notification-icon[popupid="webRTC-sharingDevices"],
+.popup-notification-icon[popupid="webRTC-shareDevices"] {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
+}
+%endif
+
+.popup-notification-icon[popupid="pointerLock"] {
+ list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+
+/* Notification icon box */
+#notification-popup-box {
+ position: relative;
+ background-color: #fff;
+ background-clip: padding-box;
+ padding-left: 4px;
+ border-radius: 2.5px 0 0 2.5px;
+ border-width: 0 8px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
+ -moz-margin-end: -8px;
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+#notification-popup-box:not([hidden]) + #identity-box {
+ -moz-padding-start: 10px;
+ border-radius: 0;
+}
+
+#notification-popup-box:-moz-locale-dir(rtl),
+.notification-anchor-icon:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+.notification-anchor-icon {
+ width: 16px;
+ height: 16px;
+ margin: 0 2px;
+}
+
+.notification-anchor-icon:-moz-focusring {
+ outline: 1px dotted -moz-DialogText;
+}
+
+.default-notification-icon,
+#default-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/information-16.png);
+}
+
+.geo-notification-icon,
+#geo-notification-icon {
+ list-style-image: url(chrome://browser/skin/Geolocation-16.png);
+}
+
+#addons-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
+}
+
+.indexedDB-notification-icon,
+#indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+}
+
+#password-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
+}
+
+#plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
+}
+
+#alert-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
+}
+
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
+}
+
+#plugins-notification-icon,
+#alert-plugins-notification-icon,
+#blocked-plugins-notification-icon {
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+#plugins-notification-icon:hover,
+#alert-plugins-notification-icon:hover,
+#blocked-plugins-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#plugins-notification-icon:active,
+#alert-plugins-notification-icon:active,
+#blocked-plugins-notification-icon:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#notification-popup-box[hidden] {
+ /* Override display:none to make the pluginBlockedNotification animation work
+ when showing the notification repeatedly. */
+ display: -moz-box;
+ visibility: collapse;
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+.mixed-content-blocked-notification-icon,
+#mixed-content-blocked-notification-icon {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+}
+
+%ifdef MOZ_WEBRTC
+.webRTC-shareDevices-notification-icon,
+#webRTC-shareDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
+}
+
+.webRTC-sharingDevices-notification-icon,
+#webRTC-sharingDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
+}
+%endif
+
+.web-notifications-notification-icon,
+#web-notifications-notification-icon {
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#pointerLock-notification-icon {
+ list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+#pointerLock-cancel {
+ margin: 0px;
+}
+
+/* Pale Moon: Feed icon */
+#ub-feed-button,
+#ub-feed-button > .button-box,
+#ub-feed-button:hover:active > .button-box {
+ padding: 0px;
+ margin: 0px;
+ border: 0px;
+ background-color: transparent !important;
+}
+
+#ub-feed-button {
+ -moz-appearance: none;
+ min-width: 0px;
+ margin-right: 1px !important;
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+
+#treecolAutoCompleteImage {
+ max-width : 36px;
+}
+
+.ac-result-type-bookmark,
+.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/star-icons.png");
+ -moz-image-region: rect(0px 32px 16px 16px);
+ width: 16px;
+ height: 16px;
+}
+
+.ac-result-type-keyword,
+.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
+ list-style-image: url(moz-icon://stock/gtk-find?size=menu);
+ width: 16px;
+ height: 16px;
+}
+
+.ac-result-type-tag,
+.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ width: 16px;
+ height: 16px;
+}
+
+.ac-comment {
+ font-size: 1.05em;
+}
+
+.ac-extra > .ac-comment {
+ font-size: inherit;
+}
+
+.ac-url-text,
+.ac-action-text {
+ color: -moz-nativehyperlinktext;
+ font-size: 0.9em;
+}
+
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+ list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+ padding: 0 3px;
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
+ color: GrayText;
+}
+
+.ac-comment[selected="true"],
+.ac-url-text[selected="true"],
+.ac-action-text[selected="true"] {
+ color: inherit !important;
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
+.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment) {
+ color: GrayText;
+ font-size: smaller;
+}
+
+.autocomplete-treebody::-moz-tree-cell(suggesthint) {
+ border-top: 1px solid GrayText;
+}
+
+/* Combined go/reload/stop button in location bar */
+
+#go-button {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+
+#urlbar > toolbarbutton {
+ -moz-appearance: none;
+ padding: 0;
+ border: none;
+ cursor: pointer;
+ width: 22px;
+}
+
+#go-button,
+#urlbar-go-button {
+ list-style-image: url("chrome://browser/skin/Go-arrow.png");
+}
+
+#go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#urlbar-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+#urlbar-reload-button {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
+}
+
+#urlbar-stop-button {
+ list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
+}
+
+/* Popup blocker button */
+#page-report-button {
+ list-style-image: url("chrome://browser/skin/Info.png");
+}
+
+/* Star button */
+#star-button {
+ list-style-image: url("chrome://browser/skin/places/starPage.png");
+}
+
+#star-button[starred="true"] {
+ list-style-image: url("chrome://browser/skin/places/pageStarred.png");
+}
+
+/* bookmarks menu-button */
+
+#bookmarks-menu-button[disabled] > .toolbarbutton-icon,
+#bookmarks-menu-button[disabled] > .toolbarbutton-menu-dropmarker,
+#bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-dropmarker,
+#bookmarks-menu-button[disabled] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+#bookmarks-menu-button > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+/* history menu-button */
+
+#history-menu-button[disabled] > .toolbarbutton-icon,
+#history-menu-button[disabled] > .toolbarbutton-menu-dropmarker,
+#history-menu-button[disabled] > .toolbarbutton-menubutton-dropmarker,
+#history-menu-button[disabled] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+#history-menu-button > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+/* Bookmarking panel */
+#editBookmarkPanelStarIcon {
+ list-style-image: url("chrome://browser/skin/places/starred48.png");
+ width: 48px;
+ height: 48px;
+}
+
+#editBookmarkPanelStarIcon[unstarred] {
+ list-style-image: url("chrome://browser/skin/places/unstarred48.png");
+}
+
+#editBookmarkPanelTitle {
+ font-size: 130%;
+}
+
+#editBookmarkPanelHeader,
+#editBookmarkPanelContent {
+ margin-bottom: .5em;
+}
+
+/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+#editBMPanel_folderTree {
+ min-width: 27em;
+}
+
+/* Content area */
+#sidebar {
+ background-color: Window;
+}
+
+/* Throbber */
+#navigator-throbber {
+ width: 16px;
+ min-height: 16px;
+ margin: 0 3px;
+}
+
+#navigator-throbber[busy="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#navigator-throbber,
+#wrapper-navigator-throbber > #navigator-throbber {
+ list-style-image: url("chrome://global/skin/icons/notloading_16.png");
+}
+
+/* Tabstrip */
+
+#TabsToolbar {
+ min-height: 0;
+ padding: 0;
+}
+
+#TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) {
+ -moz-appearance: menubar;
+ color: -moz-menubartext;
+ box-shadow: 0 -1px 0 rgba(0,0,0,.1) inset;
+}
+
+#TabsToolbar[tabsontop=true]:not(:-moz-lwtheme):-moz-system-metric(menubar-drag) {
+ -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
+}
+
+#TabsToolbar[tabsontop=false] {
+ background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, rgba(0,0,0,.05) 1px, transparent 50%);
+}
+
+/* When the tab bar is collapsed, show a 1px border in its place. */
+#TabsToolbar[tabsontop="false"][collapsed="true"]:not([customizing="true"]) {
+ visibility: visible;
+ height: 1px;
+ border-bottom-width: 1px;
+ /* !important here to override border-style: none on the toolbar */
+ border-bottom-style: solid !important;
+ border-bottom-color: ThreeDShadow;
+ overflow: hidden;
+}
+
+.tabbrowser-tab,
+.tabs-newtab-button {
+ position: static;
+ -moz-appearance: none;
+ background: linear-gradient(hsla(0,0%,100%,.2), hsla(0,0%,45%,.2) 2px, hsla(0,0%,32%,.2) 80%);
+ background-origin: border-box;
+ background-position: 1px 2px;
+ background-size: 100% calc(100% - 2px);
+ background-repeat: no-repeat;
+ color: inherit;
+ margin: 0;
+ padding: 0;
+ border-width: 4px 5px 3px 6px;
+ border-style: solid;
+ border-image: url(tabbrowser/tab.png) 4 5 3 6 fill repeat stretch;
+ border-radius: 10px 8px 0 0;
+ min-height: 25px; /* reserve space for the sometimes hidden close button */
+}
+
+.tabbrowser-tab:hover,
+.tabs-newtab-button:hover {
+ background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.2) 4px, hsla(0,0%,75%,.2) 80%);
+}
+
+.tabbrowser-tab[selected="true"] {
+ background-image: linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+.tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
+ color: -moz-dialogtext;
+}
+
+#main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
+ background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, transparent 1px),
+ linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 32%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+
+.tabbrowser-tab:-moz-lwtheme:not([selected="true"]) {
+ opacity: 0.9;
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme {
+ background-image: linear-gradient(rgba(255,255,255,.6), rgba(255,255,255,.8) 50%);
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(rgba(128,128,128,.9), rgba(32,32,32,.9) 50%, rgba(32,32,32,.9) 80%, rgba(32,32,32,.8) 100%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(hsla(0,0%,25%,.4), hsla(0,0%,15%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-brighttext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,10%,.8) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-darktext {
+ background-image: linear-gradient(hsla(0,0%,75%,.4), hsla(0,0%,85%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-darktext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,90%,.8) 80%);
+}
+
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) {
+ background-image: radial-gradient(circle farthest-corner at 50% 3px, rgba(233,242,252,1) 3%, rgba(172,206,255,.75) 40%, rgba(87,151,201,.5) 80%, rgba(87,151,201,0));
+}
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]):hover {
+ background-image: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.6) 2px, hsla(0,0%,75%,.2) 80%),
+ radial-gradient(circle farthest-corner at 50% 3px, rgba(233,242,252,1) 3%, rgba(172,206,255,.75) 40%, rgba(87,151,201,.5) 80%, rgba(87,151,201,0));
+}
+
+#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab > .tab-stack > .tab-content[pinned] {
+ min-height: 18px; /* corresponds to the max. height of non-textual tab contents, i.e. the tab close button */
+}
+
+.tabbrowser-tab:focus > .tab-stack {
+ outline: 1px dotted;
+}
+
+.tab-throbber,
+.tab-icon-image {
+ width: 16px;
+ height: 16px;
+ -moz-margin-end: 3px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.tab-throbber {
+ list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
+}
+
+.tab-throbber[progress] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
+}
+
+.tab-throbber[pinned],
+.tab-icon-image[pinned],
+.tabs-newtab-button > .toolbarbutton-icon {
+ -moz-margin-start: 2px;
+ -moz-margin-end: 2px;
+}
+
+#context_reloadTab {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
+}
+
+#context_closeOtherTabs {
+ list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
+}
+
+#context_closeOtherTabs[disabled] {
+ list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
+}
+
+#context_undoCloseTab {
+ list-style-image: url("moz-icon://stock/gtk-undelete?size=menu");
+}
+
+#context_closeTab {
+ list-style-image: url("moz-icon://stock/gtk-close?size=menu");
+}
+
+/* Tab drag and drop */
+.tab-drop-indicator {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
+ margin-bottom: -11px;
+}
+
+/* In-tab close button */
+.tab-close-button > .toolbarbutton-icon {
+ /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
+ use evil CSS to give the impression of smaller content */
+ margin: -4px;
+}
+
+.tab-close-button {
+ padding: 0;
+ margin-top: -1px;
+ margin-bottom: -1px;
+ -moz-margin-end: -1px;
+}
+
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.allTabs-endimage[soundplaying],
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.allTabs-endimage[muted],
+.tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.allTabs-endimage[blocked],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[soundplaying],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[blocked],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[muted] {
+ filter: invert(1);
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover),
+.tab-icon-overlay[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
+/* Tab icon overlay */
+.tab-icon-overlay {
+ width: 16px;
+ height: 16px;
+ margin-top: -8px;
+ margin-inline-start: -15px;
+ margin-inline-end: -1px;
+ position: relative;
+}
+
+.tab-icon-overlay[soundplaying],
+.tab-icon-overlay[muted]:not([crashed]),
+.tab-icon-overlay[blocked]:not([crashed]) {
+ border-radius: 10px;
+}
+
+.tab-icon-overlay[soundplaying]:hover,
+.tab-icon-overlay[muted]:not([crashed]):hover,
+.tab-icon-overlay[blocked]:not([crashed]):hover {
+ background-color: white;
+}
+
+.tab-icon-overlay[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio");
+}
+
+.tab-icon-overlay[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-muted");
+}
+
+.tab-icon-overlay[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[soundplaying]:not([selected]):not(:hover),
+.tab-icon-overlay[soundplaying][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[muted]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[muted][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-muted");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[blocked]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[blocked][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-blocked");
+}
+
+/* Tabstrip new tab button */
+.tabs-newtab-button,
+#TabsToolbar > #new-tab-button ,
+#TabsToolbar > #wrapper-new-tab-button > #new-tab-button {
+ list-style-image: url("moz-icon://stock/gtk-add?size=menu");
+ -moz-image-region: auto;
+}
+
+/* Tabstrip close button */
+.tabs-closebutton > .toolbarbutton-icon {
+ /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
+ use evil CSS to give the impression of smaller content */
+ margin: -2px;
+}
+
+/* Tabbrowser arrowscrollbox arrows */
+.tabbrowser-arrowscrollbox > .scrollbutton-up,
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ -moz-appearance: none;
+ margin: 0;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up {
+ -moz-border-start: 0;
+ -moz-border-end: 2px solid transparent;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ -moz-border-start: 2px solid transparent;
+ -moz-border-end: 0;
+ transition: 1s box-shadow ease-out;
+ border-radius: 4px;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
+ box-shadow: 0 0 5px 5px Highlight inset;
+ transition: none;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):-moz-locale-dir(ltr),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):-moz-locale-dir(rtl) {
+ border-width: 0 2px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/tabbrowser/tab-overflow-border.png") 0 2 0 2 fill;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):-moz-locale-dir(ltr),
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):-moz-locale-dir(rtl) {
+ border-width: 0 0 0 2px;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/tabbrowser/tab-overflow-border.png") 0 2 0 2 fill;
+}
+
+#TabsToolbar .toolbarbutton-1 > .toolbarbutton-icon,
+#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
+#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ margin-top: -2px;
+ margin-bottom: -2px;
+}
+
+#alltabs-button > .toolbarbutton-icon {
+ list-style-image: url("chrome://browser/skin/tabbrowser/alltabs.png");
+ margin: 2px 0 1px;
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker {
+ margin-bottom: -2px;
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-icon {
+ display: none;
+}
+
+/* All tabs menupopup */
+.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.alltabs-item[selected="true"] {
+ font-weight: bold;
+}
+
+.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.alltabs-item[tabIsVisible] {
+ /* box-shadow instead of background-color to work around native styling */
+ box-shadow: inset -5px 0 ThreeDShadow;
+}
+
+/* Sidebar */
+#sidebar-header > .tabs-closebutton {
+ margin-bottom: 0px !important;
+ padding: 0px 2px 0px 2px !important;
+}
+
+#sidebar-throbber[loading="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+ -moz-margin-end: 4px;
+}
+
+toolbarbutton.chevron {
+ list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
+}
+
+toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+toolbarbutton.chevron > .toolbarbutton-text,
+toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+toolbarbutton.chevron > .toolbarbutton-icon {
+ margin: 0;
+}
+
+toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
+ display: -moz-box; /* display chevron icon in text mode */
+}
+
+/* ::::: Keyboard UI Panel ::::: */
+
+.KUI-panel-closebutton {
+ list-style-image: url(KUI-close.png);
+}
+
+.KUI-panel-closebutton > .toolbarbutton-icon {
+ margin: 0;
+}
+
+/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
+
+.ctrlTab-preview,
+.allTabs-preview {
+ -moz-appearance: toolbarbutton;
+}
+
+.tabPreview-canvas {
+ box-shadow: 0 0 5px ThreeDShadow;
+}
+
+.ctrlTab-preview:focus .tabPreview-canvas,
+.ctrlTab-preview:hover .tabPreview-canvas,
+.allTabs-preview:focus .tabPreview-canvas,
+.allTabs-preview:hover .tabPreview-canvas {
+ box-shadow: none;
+}
+
+.ctrlTab-favicon[src],
+.allTabs-favicon[src] {
+ background-color: white;
+ width: 20px;
+ height: 20px;
+ padding: 2px;
+}
+
+/* Ctrl-Tab */
+
+#ctrlTab-panel {
+ padding: 10px;
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
+ margin-bottom: 2px;
+}
+
+#ctrlTab-showAll {
+ -moz-appearance: button;
+ color: ButtonText;
+ padding: 0 3px;
+ margin-top: 10px;
+}
+
+/* All Tabs */
+
+#allTabs-panel {
+ padding-bottom: 10px;
+}
+
+#allTabs-meta {
+ padding: 5px;
+}
+
+#allTabs-filter {
+ -moz-margin-start: 36px;
+ -moz-margin-end: 0;
+}
+
+.allTabs-preview-label {
+ transform: translate(0, 2px);
+}
+
+/* Application button menu */
+
+.splitmenu-menuitem {
+ -moz-margin-end: 1px;
+}
+
+#appmenu-toolbar-button:not(:hover):not([open]):not(:-moz-lwtheme) {
+ color: inherit;
+}
+
+#appmenu-toolbar-button > .toolbarbutton-text,
+#appmenu-toolbar-button > .toolbarbutton-menu-dropmarker {
+ margin-top: -2px !important;
+ margin-bottom: -2px !important;
+}
+#appmenuSecondaryPane {
+ -moz-border-start: 1px solid ThreeDShadow;
+}
+#appmenuSecondaryPane-spacer {
+ min-height: 1em;
+}
+#appmenu-cut,
+#appmenu-editmenu-cut {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
+}
+#appmenu-copy,
+#appmenu-editmenu-copy {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
+}
+#appmenu-paste,
+#appmenu-editmenu-paste {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
+}
+#wrapper-appmenu-toolbar-button,
+.appmenu-edit-button[disabled="true"] {
+ opacity: .3;
+}
+
+/* Add-on bar */
+
+#addon-bar {
+ box-shadow: 0 1px 0 rgba(0,0,0,.15) inset;
+ padding: 0;
+ min-height: 20px;
+}
+
+#status-bar {
+ min-height: 0;
+ -moz-appearance: none;
+ background-color: transparent;
+ border: none;
+}
+
+#addon-bar[customizing] > #status-bar {
+ opacity: .5;
+ background-image: repeating-linear-gradient(135deg,
+ rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
+ rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
+}
+
+#status-bar > statusbarpanel {
+ border-width: 0;
+ -moz-appearance: none;
+}
+
+#addonbar-closebutton > .toolbarbutton-icon {
+ margin-top: -2px;
+ margin-bottom: -2px;
+}
+
+/* Status panel */
+
+.statuspanel-label {
+ margin: 0;
+ padding: 2px 4px;
+ background: linear-gradient(#fff, #ddd);
+ border: 1px none #ccc;
+ border-top-style: solid;
+ color: #333;
+ text-shadow: none;
+}
+
+.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
+.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+ border-right-style: solid;
+ border-top-right-radius: .3em;
+ margin-right: 1em;
+}
+
+.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
+.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+ border-left-style: solid;
+ border-top-left-radius: .3em;
+ margin-left: 1em;
+}
+
+#full-screen-warning-message {
+ background-color: hsl(0,0%,15%);
+ color: white;
+ border-radius: 8px;
+ margin-top: 30px;
+ padding: 30px 50px;
+ box-shadow: 0 0 2px white;
+}
+
+.full-screen-description {
+ font-size: 150%;
+}
+
+#full-screen-domain-text {
+ font-size: 300%;
+}
+
+%ifdef MOZ_DEVTOOLS
+%include ../../../../devtools/client/themes/responsivedesign.inc.css
+%include ../../../../devtools/client/themes/commandline.inc.css
+%endif
+%include ../shared/plugin-doorhanger.inc.css
+
+%ifdef MOZ_DEVTOOLS
+.gcli-panel {
+ padding: 0;
+}
+
+.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
+ color: hsl(210,11%,16%);
+}
+
+/* Error counter */
+
+#developer-toolbar-toolbox-button[error-count]:before {
+ color: #FDF3DE;
+ min-width: 16px;
+ text-shadow: none;
+ background-image: linear-gradient(#B4211B, #8A1915);
+ border-radius: 1px;
+ -moz-margin-end: 2px;
+}
+%endif
+
+.toolbarbutton-badge-stack {
+ margin: 5px 3px;
+ position: relative;
+}
+
+toolbar[iconsize="small"] .toolbarbutton-badge-stack {
+ margin: 0;
+}
+
+.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+ left: 2px;
+ right: auto;
+}
+
+#main-window[privatebrowsingmode=temporary] #TabsToolbar::before {
+ display: -moz-box;
+ content: "";
+ background: url("chrome://browser/skin/privatebrowsing-mask.png") center no-repeat;
+ width: 40px;
+}
diff --git a/themes/linux/click-to-play-warning-stripes.png b/themes/linux/click-to-play-warning-stripes.png
new file mode 100644
index 0000000..29f15f7
Binary files /dev/null and b/themes/linux/click-to-play-warning-stripes.png differ
diff --git a/themes/linux/communicator/communicator.css b/themes/linux/communicator/communicator.css
new file mode 100644
index 0000000..0b57574
--- /dev/null
+++ b/themes/linux/communicator/communicator.css
@@ -0,0 +1,6 @@
+/* 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/. */
+
+@import url("chrome://global/skin/");
+
diff --git a/themes/linux/communicator/jar.mn b/themes/linux/communicator/jar.mn
new file mode 100644
index 0000000..612d133
--- /dev/null
+++ b/themes/linux/communicator/jar.mn
@@ -0,0 +1,7 @@
+# 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:
+% skin communicator classic/1.0 %skin/classic/communicator/
+ skin/classic/communicator/communicator.css
diff --git a/themes/linux/communicator/moz.build b/themes/linux/communicator/moz.build
new file mode 100644
index 0000000..c97072b
--- /dev/null
+++ b/themes/linux/communicator/moz.build
@@ -0,0 +1,7 @@
+# -*- 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']
\ No newline at end of file
diff --git a/themes/linux/downloads/allDownloadsViewOverlay.css b/themes/linux/downloads/allDownloadsViewOverlay.css
new file mode 100644
index 0000000..3526e01
--- /dev/null
+++ b/themes/linux/downloads/allDownloadsViewOverlay.css
@@ -0,0 +1,125 @@
+/* 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/. */
+
+#downloadsRichListBox {
+ /** The default listbox appearance comes with an unwanted margin. **/
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#downloadsRichListBox > richlistitem.download {
+ height: 5em;
+ padding: 5px 8px;
+}
+
+.downloadTypeIcon {
+ -moz-margin-end: 8px;
+ /* Prevent flickering when changing states. */
+ min-height: 32px;
+ min-width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+.downloadTarget {
+ margin-bottom: 3px;
+ cursor: inherit;
+}
+
+.downloadDetails {
+ opacity: 0.7;
+ font-size: 95%;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ background: transparent;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+richlistitem.download:hover > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+richlistitem.download:hover > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+richlistitem.download:hover > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+richlistitem.download[selected] > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 80px, 16px, 64px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 96px, 16px, 80px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 112px, 16px, 96px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 128px, 16px, 112px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+richlistitem.download:hover > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+richlistitem.download:hover > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+richlistitem.download:hover > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+richlistitem.download[selected] > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 80px, 32px, 64px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 96px, 32px, 80px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 112px, 32px, 96px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 128px, 32px, 112px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+richlistitem.download:hover > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+richlistitem.download:hover > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+richlistitem.download:hover > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+richlistitem.download[selected] > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 80px, 48px, 64px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 96px, 48px, 80px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 112px, 48px, 96px);
+}
+richlistitem.download:hover[selected] > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 128px, 48px, 112px);
+}
+
diff --git a/themes/linux/downloads/buttons.png b/themes/linux/downloads/buttons.png
new file mode 100644
index 0000000..071f7f7
Binary files /dev/null and b/themes/linux/downloads/buttons.png differ
diff --git a/themes/linux/downloads/contentAreaDownloadsView.css b/themes/linux/downloads/contentAreaDownloadsView.css
new file mode 100644
index 0000000..56917d7
--- /dev/null
+++ b/themes/linux/downloads/contentAreaDownloadsView.css
@@ -0,0 +1,11 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+#downloadsListEmptyDescription {
+ margin: 1em;
+ text-align: center;
+ color: GrayText;
+}
diff --git a/themes/linux/downloads/download-glow-small.png b/themes/linux/downloads/download-glow-small.png
new file mode 100644
index 0000000..0dbf602
Binary files /dev/null and b/themes/linux/downloads/download-glow-small.png differ
diff --git a/themes/linux/downloads/download-glow.png b/themes/linux/downloads/download-glow.png
new file mode 100644
index 0000000..7514317
Binary files /dev/null and b/themes/linux/downloads/download-glow.png differ
diff --git a/themes/linux/downloads/download-notification-finish.png b/themes/linux/downloads/download-notification-finish.png
new file mode 100644
index 0000000..7bcc7f5
Binary files /dev/null and b/themes/linux/downloads/download-notification-finish.png differ
diff --git a/themes/linux/downloads/download-notification-start.png b/themes/linux/downloads/download-notification-start.png
new file mode 100644
index 0000000..bd548b1
Binary files /dev/null and b/themes/linux/downloads/download-notification-start.png differ
diff --git a/themes/linux/downloads/download-summary.png b/themes/linux/downloads/download-summary.png
new file mode 100644
index 0000000..c5d4754
Binary files /dev/null and b/themes/linux/downloads/download-summary.png differ
diff --git a/themes/linux/downloads/downloads.css b/themes/linux/downloads/downloads.css
new file mode 100644
index 0000000..79bb5ee
--- /dev/null
+++ b/themes/linux/downloads/downloads.css
@@ -0,0 +1,376 @@
+/* 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/. */
+
+/*** Panel and outer controls ***/
+
+#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
+ padding: 0;
+}
+
+#downloadsListBox {
+ background: transparent;
+ padding: 4px;
+ color: inherit;
+}
+
+#downloadsPanel:not([hasdownloads]) > #downloadsListBox {
+ display: none;
+}
+
+#downloadsPanel[hasdownloads] > #emptyDownloads {
+ display: none;
+}
+
+#emptyDownloads {
+ padding: 10px 20px;
+ max-width: 40ch;
+}
+
+#downloadsHistory {
+ background: transparent;
+ color: -moz-nativehyperlinktext;
+ cursor: pointer;
+}
+
+#downloadsFooter {
+ border-top: 1px solid ThreeDShadow;
+ background-image: linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,0%,.08) 6px);
+}
+
+#downloadsHistory > .button-box {
+ margin: 1em;
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsHistory:focus > .button-box {
+ outline: 1px -moz-dialogtext dotted;
+}
+
+/*** Downloads Summary and List items ***/
+
+#downloadsSummary,
+richlistitem[type="download"] {
+ height: 6em;
+ -moz-padding-end: 0;
+ color: inherit;
+}
+
+#downloadsSummary {
+ padding: 8px 38px 8px 12px;
+ cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsSummary:focus {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
+}
+
+#downloadsSummary > .downloadTypeIcon {
+ list-style-image: url("chrome://browser/skin/downloads/download-summary.png");
+}
+
+#downloadsSummaryDescription {
+ color: -moz-nativehyperlinktext;
+}
+
+richlistitem[type="download"] {
+ margin: 0;
+ border-top: 1px solid hsla(0,0%,100%,.2);
+ border-bottom: 1px solid hsla(0,0%,0%,.15);
+ background: transparent;
+ padding: 8px;
+}
+
+richlistitem[type="download"]:first-child {
+ border-top: 1px solid transparent;
+}
+
+richlistitem[type="download"]:last-child {
+ border-bottom: 1px solid transparent;
+}
+
+#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -1px;
+}
+
+.downloadTypeIcon {
+ -moz-margin-end: 8px;
+ /* Prevent flickering when changing states. */
+ min-height: 32px;
+ min-width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+/* We hold .downloadDisplayName, .downloadProgress and .downloadDetails
+ inside of a vbox with class .downloadContainer. We set the font-size of
+ the entire container to 90% because:
+
+ 1) This is the size that we want .downloadDetails to be
+ 2) The container's width is set by localizers by &downloadDetails.width;,
+ which is a ch unit. Since this is the value that should control the
+ panel width, we apply it to the outer container to constrain
+ .downloadDisplayName and .downloadProgress.
+
+ Finally, since we want .downloadDisplayName's font-size to be at 100% of
+ the font-size of .downloadContainer's parent, we use calc to go from the
+ smaller font-size back to the original font-size.
+ */
+#downloadsSummaryDetails,
+.downloadContainer {
+ font-size: 90%;
+}
+
+#downloadsSummaryDescription,
+.downloadDisplayName {
+ margin-bottom: 7px;
+ cursor: inherit;
+}
+
+.downloadDisplayName {
+ font-size: calc(100%/0.9);
+}
+
+#downloadsSummaryDetails,
+.downloadDetails {
+ margin-top: 1px;
+ opacity: 0.6;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ background: transparent;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+.downloadButton > .button-box {
+ padding: 0;
+}
+
+.downloadButton:focus > .button-box {
+ outline: 1px -moz-dialogtext dotted;
+}
+
+/*** Highlighted list items ***/
+
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
+ border-radius: 3px;
+ border-top: 1px solid hsla(0,0%,100%,.3);
+ border-bottom: 1px solid hsla(0,0%,0%,.2);
+ background-color: Highlight;
+ background-image: linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,100%,0));
+ color: HighlightText;
+ cursor: pointer;
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 96px, 32px, 80px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 112px, 32px, 96px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 128px, 32px, 112px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+
+/*** Status and progress indicator ***/
+
+#downloads-indicator-anchor {
+ /* Makes the outermost stack element positioned, so that its contents are
+ rendered over the main browser window in the Z order. This is required by
+ the animated event notification. */
+ position: relative;
+}
+
+toolbar[iconsize="small"] > #downloads-indicator > #downloads-indicator-anchor {
+ min-width: 16px;
+ min-height: 16px;
+}
+
+toolbar[iconsize="large"] > #downloads-indicator > #downloads-indicator-anchor {
+ min-width: 24px;
+ min-height: 24px;
+}
+
+/*** Main indicator icon ***/
+
+toolbar[iconsize="small"] > #downloads-indicator > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
+ 0, 16, 16, 0) center no-repeat;
+}
+
+toolbar[iconsize="large"] > #downloads-indicator > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
+ 0, 24, 24, 0) center no-repeat;
+}
+
+toolbar[iconsize="small"] > #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background-image: url("chrome://browser/skin/downloads/download-glow-small.png");
+}
+
+toolbar[iconsize="large"] > #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+/* In the next few rules, we use :not([counter]) as a shortcut that is
+ equivalent to -moz-any([progress], [paused]). */
+
+#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
+ 0, 16, 16, 0) center no-repeat;
+ background-size: 12px;
+}
+
+#downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+/*** Download notifications ***/
+
+#downloads-indicator-notification {
+ opacity: 0;
+ background-size: 16px;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+@keyframes downloadsIndicatorNotificationStartRight {
+ from { opacity: 0; transform: translate(-128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+@keyframes downloadsIndicatorNotificationStartLeft {
+ from { opacity: 0; transform: translate(128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+#downloads-indicator[notification="start"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-start.png");
+ animation-name: downloadsIndicatorNotificationStartRight;
+ animation-duration: 1s;
+}
+
+#downloads-indicator[notification="start"]:-moz-locale-dir(rtl) > #downloads-indicator-anchor > #downloads-indicator-notification {
+ animation-name: downloadsIndicatorNotificationStartLeft;
+}
+
+@keyframes downloadsIndicatorNotificationFinish {
+ from { opacity: 0; transform: scale(1); }
+ 20% { opacity: .65; animation-timing-function: ease-in; }
+ to { opacity: 0; transform: scale(8); }
+}
+
+#downloads-indicator[notification="finish"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-finish.png");
+ animation-name: downloadsIndicatorNotificationFinish;
+ animation-duration: 1s;
+}
+
+/*** Progress bar and text ***/
+
+#downloads-indicator-counter {
+ height: 10px;
+ margin: 0;
+ color: hsl(0,0%,30%);
+ text-shadow: 0 1px 0 hsla(0,0%,100%,.5);
+ font-size: 10px;
+ line-height: 10px;
+ text-align: center;
+}
+
+toolbar[brighttext] #downloads-indicator-counter {
+ color: white;
+ text-shadow: 0 0 1px rgba(0,0,0,.7),
+ 0 1px 1.5px rgba(0,0,0,.5);
+}
+
+#downloads-indicator-progress {
+ width: 16px;
+ height: 6px;
+ min-width: 0;
+ min-height: 0;
+ margin-top: 1px;
+ margin-bottom: 2px;
+ border-radius: 2px;
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.4);
+}
+
+#downloads-indicator-progress > .progress-bar {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ /* The background-clip: border-box; and background-image: none; are there to expand the background-color behind the border */
+ background-clip: padding-box, border-box;
+ background-color: rgb(255, 135, 94);
+ background-image: linear-gradient(transparent 1px, rgba(255, 255, 255, 0.4) 1px, rgba(255, 255, 255, 0.4) 2px, transparent 2px), none;
+ border: 1px solid;
+ border-color: rgba(0,43,86,.6) rgba(0,43,86,.4) rgba(0,43,86,.4);
+ border-radius: 2px 0 0 2px;
+}
+
+#downloads-indicator-progress > .progress-remainder {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ background-image: linear-gradient(#505050, #575757);
+ border: 1px solid;
+ border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
+ -moz-border-start: none;
+ border-radius: 0 2px 2px 0;
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-bar {
+ background-color: rgb(220, 230, 81);
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
+ background-image: linear-gradient(#4b5000, #515700);
+}
+
+toolbar[mode="full"] > #downloads-indicator > .toolbarbutton-text {
+ margin: 0;
+ text-align: center;
+}
diff --git a/themes/linux/engineManager.css b/themes/linux/engineManager.css
new file mode 100644
index 0000000..18817cd
--- /dev/null
+++ b/themes/linux/engineManager.css
@@ -0,0 +1,16 @@
+%if 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/. */
+%endif
+
+#engineList treechildren::-moz-tree-image(engineName) {
+ -moz-margin-end: 4px;
+ -moz-margin-start: 1px;
+ width: 16px;
+ height: 16px;
+}
+
+#engineList treechildren::-moz-tree-row {
+ height: 20px;
+}
diff --git a/themes/linux/feeds/feedIcon.png b/themes/linux/feeds/feedIcon.png
new file mode 100644
index 0000000..a788fff
Binary files /dev/null and b/themes/linux/feeds/feedIcon.png differ
diff --git a/themes/linux/feeds/feedIcon16.png b/themes/linux/feeds/feedIcon16.png
new file mode 100644
index 0000000..f8536a4
Binary files /dev/null and b/themes/linux/feeds/feedIcon16.png differ
diff --git a/themes/linux/feeds/subscribe-ui.css b/themes/linux/feeds/subscribe-ui.css
new file mode 100644
index 0000000..b3c0b37
--- /dev/null
+++ b/themes/linux/feeds/subscribe-ui.css
@@ -0,0 +1,29 @@
+/* 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/. */
+
+.alwaysUse {
+ padding: 5px;
+}
+
+.handlersMenuPopup > menuitem {
+ -moz-padding-start: 23px;
+}
+
+.handlersMenuPopup > menuitem.menuitem-iconic {
+ -moz-padding-start: 2px;
+}
+
+.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
+ display: -moz-box;
+ min-width: 16px;
+ -moz-padding-end: 2px;
+}
+
+.chooseApplicationMenuItem {
+ list-style-image: url("moz-icon://dummy.exe?size=16");
+}
+
+#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
+ direction: rtl;
+}
diff --git a/themes/linux/feeds/subscribe.css b/themes/linux/feeds/subscribe.css
new file mode 100644
index 0000000..dd1e24e
--- /dev/null
+++ b/themes/linux/feeds/subscribe.css
@@ -0,0 +1,163 @@
+/* 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/. */
+
+html {
+ background: -moz-Dialog;
+ font: 3mm tahoma,arial,helvetica,sans-serif;
+}
+
+#feedBody {
+ border: 1px solid THreeDShadow;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ margin: 2em auto;
+ background: -moz-Field;
+}
+
+#feedHeaderContainer {
+ border: 1px solid ThreeDShadow;
+ border-radius: 10px;
+ margin: -4em auto 0 auto;
+ background-color: InfoBackground;
+}
+
+#feedHeader {
+ margin-top: 4.9em;
+ margin-bottom: 1em;
+ -moz-margin-start: 1.4em;
+ -moz-margin-end: 1em;
+ -moz-padding-start: 2.9em;
+ font-size: 110%;
+ color: InfoText;
+}
+
+.feedBackground {
+ background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.videoPodcastBackground {
+ background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.audioPodcastBackground {
+ background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+#feedHeader[dir="rtl"] {
+ background-position: 100% 10%;
+}
+
+#feedIntroText {
+ display: none;
+}
+
+#feedHeader[firstrun="true"] #feedIntroText {
+ padding-top: 0.1em;
+ -moz-padding-start: 0.6em;
+ display: block;
+}
+
+#feedHeader[firstrun="true"] > #feedSubscribeLine {
+ -moz-padding-start: 1.8em;
+}
+
+#feedSubscribeLine {
+ padding-top: 0.2em;
+}
+
+img {
+ max-width: 100%;
+}
+
+/* Don't print subscription UI */
+@media print {
+ #feedHeaderContainer {
+ display: none;
+ }
+}
+
+body {
+ margin: 0;
+ padding: 0 3em;
+ color: -moz-fieldText;
+ font: message-box;
+}
+
+h1 {
+ font-size: 160%;
+ border-bottom: 2px solid ThreeDLightShadow;
+ margin: 0 0 .2em 0;
+}
+
+h2 {
+ color: ThreeDDarkShadow;
+ font-size: 110%;
+ font-weight: normal;
+ margin: 0 0 .6em 0;
+}
+
+#feedTitleLink {
+ float: right;
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+a[href] img {
+ border: none;
+}
+
+#feedTitleContainer {
+ -moz-margin-start: 0;
+ -moz-margin-end: .6em;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#feedTitleImage {
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ max-width: 300px;
+ max-height: 150px;
+}
+
+.feedEntryContent {
+ font-size: 110%;
+}
+
+.link {
+ color: #0000FF;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.link:hover:active {
+ color: #FF0000;
+}
+
+.lastUpdated {
+ font-size: 85%;
+ font-weight: normal;
+}
+
+.type-icon {
+ vertical-align: bottom;
+ height: 16px;
+ width: 16px;
+}
+
+.enclosures {
+ border: 1px solid THreeDShadow;
+ padding: 1em;
+ margin: 1em auto;
+ background: -moz-Dialog;
+}
+
+.enclosure {
+ vertical-align: middle;
+ margin-left: 2px;
+}
diff --git a/themes/linux/icon.png b/themes/linux/icon.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/linux/icon.png differ
diff --git a/themes/linux/identity-icons-generic.png b/themes/linux/identity-icons-generic.png
new file mode 100644
index 0000000..a39e493
Binary files /dev/null and b/themes/linux/identity-icons-generic.png differ
diff --git a/themes/linux/identity-icons-https-ev.png b/themes/linux/identity-icons-https-ev.png
new file mode 100644
index 0000000..d49be13
Binary files /dev/null and b/themes/linux/identity-icons-https-ev.png differ
diff --git a/themes/linux/identity-icons-https-mixed-active.png b/themes/linux/identity-icons-https-mixed-active.png
new file mode 100644
index 0000000..3c77bc8
Binary files /dev/null and b/themes/linux/identity-icons-https-mixed-active.png differ
diff --git a/themes/linux/identity-icons-https.png b/themes/linux/identity-icons-https.png
new file mode 100644
index 0000000..ffd6694
Binary files /dev/null and b/themes/linux/identity-icons-https.png differ
diff --git a/themes/linux/identity.png b/themes/linux/identity.png
new file mode 100644
index 0000000..f3f790e
Binary files /dev/null and b/themes/linux/identity.png differ
diff --git a/themes/linux/imagedocument.png b/themes/linux/imagedocument.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/linux/imagedocument.png differ
diff --git a/themes/linux/jar.mn b/themes/linux/jar.mn
new file mode 100644
index 0000000..a7c426b
--- /dev/null
+++ b/themes/linux/jar.mn
@@ -0,0 +1,142 @@
+# 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:
+% skin browser classic/1.0 %skin/classic/browser/
+% override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
+ skin/classic/browser/sanitizeDialog.css
+* skin/classic/browser/aboutPrivateBrowsing.css
+* skin/classic/browser/aboutSessionRestore.css
+ skin/classic/browser/aboutSessionRestore-window-icon.png
+ skin/classic/browser/aboutCertError.css
+ skin/classic/browser/aboutCertError_sectionCollapsed.png
+ skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
+ skin/classic/browser/aboutCertError_sectionExpanded.png
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/aboutSyncTabs.css
+#endif
+* skin/classic/browser/autocomplete.css
+ skin/classic/browser/actionicon-tab.png
+* skin/classic/browser/browser.css
+ skin/classic/browser/click-to-play-warning-stripes.png
+* skin/classic/browser/engineManager.css
+ skin/classic/browser/Geolocation-16.png
+ skin/classic/browser/Geolocation-64.png
+ skin/classic/browser/Go-arrow.png
+ skin/classic/browser/identity.png
+ skin/classic/browser/imagedocument.png
+ skin/classic/browser/identity-icons-generic.png
+ skin/classic/browser/identity-icons-https.png
+ skin/classic/browser/identity-icons-https-ev.png
+ skin/classic/browser/identity-icons-https-mixed-active.png
+ skin/classic/browser/Info.png
+ skin/classic/browser/KUI-close.png
+ skin/classic/browser/mixed-content-blocked-16.png
+ skin/classic/browser/mixed-content-blocked-64.png
+ skin/classic/browser/monitor.png
+ skin/classic/browser/monitor_16-10.png
+* skin/classic/browser/pageInfo.css
+ skin/classic/browser/pageInfo.png
+ skin/classic/browser/page-livemarks.png
+ skin/classic/browser/pointerLock-16.png
+ skin/classic/browser/pointerLock-64.png
+ skin/classic/browser/Privacy-16.png
+ skin/classic/browser/Privacy-48.png
+ skin/classic/browser/privatebrowsing-mask.png
+ skin/classic/browser/searchbar.css
+ skin/classic/browser/Secure.png
+ skin/classic/browser/Security-broken.png
+ skin/classic/browser/setDesktopBackground.css
+ skin/classic/browser/slowStartup-16.png
+ skin/classic/browser/Toolbar.png
+ skin/classic/browser/Toolbar-small.png
+ skin/classic/browser/urlbar-arrow.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
+#ifdef MOZ_WEBRTC
+ skin/classic/browser/webRTC-shareDevice-16.png
+ skin/classic/browser/webRTC-shareDevice-64.png
+ skin/classic/browser/webRTC-sharingDevice-16.png
+#endif
+ skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
+ skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png)
+ skin/classic/browser/downloads/download-glow-small.png (downloads/download-glow-small.png)
+ skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png)
+ skin/classic/browser/downloads/download-notification-start.png (downloads/download-notification-start.png)
+ skin/classic/browser/downloads/download-summary.png (downloads/download-summary.png)
+ skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
+ skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
+ skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
+ skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/videoFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
+ skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
+* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
+ skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
+ skin/classic/browser/newtab/noise.png (../shared/newtab/noise.png)
+ skin/classic/browser/newtab/pinned.png (../shared/newtab/pinned.png)
+ skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
+ skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
+ skin/classic/browser/places/calendar.png (places/calendar.png)
+* skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
+ skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
+ skin/classic/browser/places/pageStarred.png (places/pageStarred.png)
+ skin/classic/browser/places/star-icons.png (places/star-icons.png)
+ skin/classic/browser/places/starred48.png (places/starred48.png)
+ skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
+ skin/classic/browser/places/places.css (places/places.css)
+ skin/classic/browser/places/organizer.css (places/organizer.css)
+ skin/classic/browser/places/organizer.xml (places/organizer.xml)
+ skin/classic/browser/places/query.png (places/query.png)
+ skin/classic/browser/places/starPage.png (places/starPage.png)
+ skin/classic/browser/places/tag.png (places/tag.png)
+ skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
+ skin/classic/browser/places/unsortedBookmarks.png (places/unsortedBookmarks.png)
+ skin/classic/browser/places/downloads.png (places/downloads.png)
+ skin/classic/browser/permissions/aboutPermissions.css (permissions/aboutPermissions.css)
+ skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
+ skin/classic/browser/preferences/mail.png (preferences/mail.png)
+ skin/classic/browser/preferences/Options.png (preferences/Options.png)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
+#endif
+* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
+ skin/classic/browser/preferences/applications.css (preferences/applications.css)
+ skin/classic/browser/statusbar/dynamic.css (../shared/statusbar/dynamic.css)
+* skin/classic/browser/statusbar/overlay.css (statusbar/overlay.css)
+* skin/classic/browser/statusbar/prefs.css (statusbar/prefs.css)
+ skin/classic/browser/statusbar/pulse.png (../shared/statusbar/pulse.png)
+ skin/classic/browser/statusbar/pms16.png (../shared/statusbar/pms16.png)
+ skin/classic/browser/statusbar/pms24.png (../shared/statusbar/pms24.png)
+ skin/classic/browser/statusbar/throbber-idle.png (../shared/statusbar/throbber-idle.png)
+ skin/classic/browser/statusbar/throbberStatic.png (../shared/statusbar/throbberStatic.png)
+ skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
+ skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
+ skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
+ skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
+ skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
+ skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/sync-16-throbber.png
+ skin/classic/browser/sync-16.png
+ skin/classic/browser/sync-24-throbber.png
+ skin/classic/browser/sync-32.png
+ skin/classic/browser/sync-bg.png
+ skin/classic/browser/sync-128.png
+ skin/classic/browser/sync-desktopIcon.png
+ skin/classic/browser/sync-mobileIcon.png
+ skin/classic/browser/syncSetup.css
+ skin/classic/browser/syncCommon.css
+ skin/classic/browser/syncQuota.css
+ skin/classic/browser/syncProgress.css
+#endif
+ skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
+ skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
+ skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
diff --git a/themes/linux/mixed-content-blocked-16.png b/themes/linux/mixed-content-blocked-16.png
new file mode 100644
index 0000000..7cf33ec
Binary files /dev/null and b/themes/linux/mixed-content-blocked-16.png differ
diff --git a/themes/linux/mixed-content-blocked-64.png b/themes/linux/mixed-content-blocked-64.png
new file mode 100644
index 0000000..cac4415
Binary files /dev/null and b/themes/linux/mixed-content-blocked-64.png differ
diff --git a/themes/linux/monitor.png b/themes/linux/monitor.png
new file mode 100644
index 0000000..35e7b20
Binary files /dev/null and b/themes/linux/monitor.png differ
diff --git a/themes/linux/monitor_16-10.png b/themes/linux/monitor_16-10.png
new file mode 100644
index 0000000..4195034
Binary files /dev/null and b/themes/linux/monitor_16-10.png differ
diff --git a/themes/linux/moz.build b/themes/linux/moz.build
new file mode 100644
index 0000000..6a7af20
--- /dev/null
+++ b/themes/linux/moz.build
@@ -0,0 +1,9 @@
+# -*- 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/.
+
+DIRS += ['communicator']
+
+JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
diff --git a/themes/linux/newtab/newTab.css b/themes/linux/newtab/newTab.css
new file mode 100644
index 0000000..357b313
--- /dev/null
+++ b/themes/linux/newtab/newTab.css
@@ -0,0 +1,27 @@
+/* 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 ../../shared/newtab/newTab.css.inc
+
+.newtab-undo-button {
+ -moz-appearance: none;
+ color: rgb(221,72,20);
+ cursor: pointer;
+ padding: 0;
+ margin: 0 4px;
+ border: 0;
+ background: transparent;
+ text-decoration: none;
+ min-width: 0;
+}
+
+#newtab-undo-close-button {
+ padding: 0;
+ border: none;
+ -moz-user-focus: normal;
+}
+
+#newtab-undo-close-button > .toolbarbutton-icon {
+ margin: -4px;
+}
diff --git a/themes/linux/page-livemarks.png b/themes/linux/page-livemarks.png
new file mode 100644
index 0000000..f8536a4
Binary files /dev/null and b/themes/linux/page-livemarks.png differ
diff --git a/themes/linux/pageInfo.css b/themes/linux/pageInfo.css
new file mode 100644
index 0000000..49ae493
--- /dev/null
+++ b/themes/linux/pageInfo.css
@@ -0,0 +1,276 @@
+%if 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/. */
+%endif
+
+@import url("chrome://global/skin/");
+
+/* View buttons */
+#viewGroup > radio {
+ list-style-image: url("chrome://browser/skin/pageInfo.png");
+ -moz-box-orient: vertical;
+ -moz-box-align: center;
+ -moz-appearance: none;
+ min-width: 4.5em;
+ margin: 0;
+ padding: 3px;
+ color: -moz-FieldText;
+}
+
+#viewGroup > radio[selected="true"] {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+#topBar {
+ -moz-appearance: listbox;
+ margin: 8px 8px 0;
+}
+
+#generalTab {
+ -moz-image-region: rect(0px, 32px, 32px, 0px)
+}
+
+#mediaTab {
+ -moz-image-region: rect(0px, 64px, 32px, 32px)
+}
+
+#feedTab {
+ -moz-image-region: rect(0px, 96px, 32px, 64px)
+}
+
+#permTab {
+ -moz-image-region: rect(0px, 128px, 32px, 96px)
+}
+
+#securityTab {
+ -moz-image-region: rect(0px, 160px, 32px, 128px)
+}
+
+#mainDeck {
+ padding-left: 2px;
+ padding-right: 2px;
+}
+
+deck {
+ padding: 10px 10px 10px 10px;
+}
+
+/* Misc */
+tree {
+ margin: .5em;
+}
+
+.gridSeparator {
+ width: .5em;
+}
+
+textbox {
+ background: transparent !important;
+ border: none;
+ padding: 0px;
+ margin-top: 1px;
+ -moz-appearance: none;
+}
+
+textbox.header {
+ -moz-margin-start: 0;
+}
+
+.iframe {
+ margin: .5em;
+ background: white;
+ overflow: auto;
+}
+
+.fixedsize {
+ height: 8.5em;
+}
+
+textbox[disabled] {
+ font-style: italic;
+}
+
+/* General Tab */
+#generalPanel > #titletext {
+ -moz-margin-start: 5px;
+}
+
+groupbox.collapsable caption .caption-icon {
+ width: 9px;
+ height: 9px;
+ background-repeat: no-repeat;
+ background-position: center;
+ -moz-margin-start: 1px;
+ -moz-margin-end: 3px;
+ background-image: url("chrome://global/skin/tree/twisty-open.png");
+}
+
+groupbox.collapsable[closed="true"] {
+ border: none;
+}
+
+groupbox.collapsable[closed="true"] caption .caption-icon {
+ background-image: url("chrome://global/skin/tree/twisty-clsd.png");
+}
+
+groupbox tree {
+ margin: 0;
+ border: none;
+}
+
+groupbox.treebox .groupbox-body {
+ -moz-margin-start: 5px;
+ -moz-margin-end: 1px;
+ padding-top: 0;
+}
+
+#securityBox description {
+ -moz-margin-start: 10px;
+}
+
+#general-security-identity {
+ white-space: pre-wrap;
+ line-height: 2em;
+}
+
+/* Media Tab */
+#imagetree {
+ min-height: 10em;
+ margin-top: 2px;
+ margin-bottom: 0;
+}
+
+#mediaSplitter {
+ -moz-appearance: none;
+ height: .8em;
+}
+
+#mediaGrid {
+ min-height: 9em;
+}
+
+#mediaLabelColumn {
+ min-width: 10em;
+}
+
+#thepreviewimage {
+ margin: 1em;
+}
+
+treechildren::-moz-tree-cell-text(broken) {
+ font-style: italic;
+ color: graytext;
+}
+
+#mediaPreviewBox .inset {
+ -moz-appearance: listbox;
+ margin-bottom: 0;
+}
+
+/* Feeds Tab */
+#feedPanel {
+ margin-left: 2px;
+ margin-right: 2px;
+}
+
+#feedtree {
+ margin-bottom: 0px;
+}
+
+#feedListbox richlistitem {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+ color: -moz-FieldText;
+}
+
+#feedListbox richlistitem[selected="true"] {
+ background-color: -moz-Dialog;
+ color: -moz-DialogText;
+}
+
+#feedListbox {
+ margin-bottom: 0;
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+}
+
+.feedTitle {
+ font-weight: bold;
+}
+
+/* Permissions Tab */
+#permPanel {
+ margin-left: 6px;
+ margin-right: 6px;
+}
+
+#permList {
+ -moz-appearance: listbox;
+ margin-top: .5em;
+ overflow: auto;
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+ background-color: -moz-field;
+ color: -moz-FieldText;
+}
+
+.permission {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+.permissionLabel {
+ font-weight: bold;
+}
+
+.permission:hover {
+ background-color: -moz-dialog;
+ color: -moz-DialogText;
+}
+
+/* Security Tab */
+#securityPanel .caption-icon {
+ display: none;
+}
+
+#securityPanel .header {
+ font-size: 120%;
+}
+
+#securityPanel .fieldLabel {
+ margin: 2px 10px 3px 10px;
+}
+
+#securityPanel .fieldValue {
+ font-weight: bold;
+ margin: 2px 10px 0px 10px;
+}
+
+/* Icons for context menus */
+menuitem:not([type]) {
+ -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
+}
+
+#menu_selectall {
+ list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
+}
+
+#menu_copy {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
+}
diff --git a/themes/linux/pageInfo.png b/themes/linux/pageInfo.png
new file mode 100644
index 0000000..2cbb15d
Binary files /dev/null and b/themes/linux/pageInfo.png differ
diff --git a/themes/linux/permissions/aboutPermissions.css b/themes/linux/permissions/aboutPermissions.css
new file mode 100644
index 0000000..386e167
--- /dev/null
+++ b/themes/linux/permissions/aboutPermissions.css
@@ -0,0 +1,149 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+/* header */
+
+#permissions-pagetitle {
+ font-size: 200%;
+ font-weight: bold;
+ padding-bottom: 0.5em;
+}
+
+/* content box */
+#permissions-content {
+ height: 100%;
+}
+
+/* sites box */
+
+#sites-box {
+ padding: 10px;
+ width: 25em;
+}
+
+#sites-filter {
+ margin: 0;
+}
+
+#sites-list {
+ margin: 5px 0 0 0;
+}
+
+.site {
+ padding: 4px;
+ border-bottom: 1px solid ThreeDLightShadow;
+}
+
+.site-favicon {
+ height: 16px;
+ width: 16px;
+ -moz-margin-end: 4px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+#all-sites-item > .site-container > .site-favicon {
+ list-style-image: none;
+}
+
+/* permissions box */
+
+#permissions-box {
+ padding-top: 10px;
+ overflow-y: auto;
+}
+
+#site-description {
+ font-size: 125%;
+ -moz-margin-start: 6px; /* to match button margin */
+}
+
+#site-label {
+ font-weight: bold;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#defaults-description {
+ font-size: 125%;
+ font-weight: bold;
+ -moz-margin-start: 6px;
+}
+
+.pref-item {
+ margin-bottom: 10px;
+}
+
+.pref-icon {
+ width: 36px;
+ height: 36px;
+ -moz-margin-end: 10px;
+}
+
+.pref-icon[type="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+.pref-icon[type="image"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="popup"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="cookie"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="desktop-notification"] {
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
+}
+.pref-icon[type="install"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
+}
+.pref-icon[type="geo"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+.pref-icon[type="plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
+}
+
+.pref-title {
+ font-size: 125%;
+ margin-bottom: 0;
+ font-weight: bold;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.pref-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+}
+
+.pref-set-default {
+ visibility: collapse;
+}
+
+.pref-menulist {
+ margin-left: 6px;
+ margin-right: 6px;
+}
+
+.plugins-label {
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-vulnerable {
+ margin-left: 0;
+ padding-left: 0;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+ margin-right: 1em;
+ padding-right: 0;
+}
diff --git a/themes/linux/places/bookmarksMenu.png b/themes/linux/places/bookmarksMenu.png
new file mode 100644
index 0000000..80dd216
Binary files /dev/null and b/themes/linux/places/bookmarksMenu.png differ
diff --git a/themes/linux/places/bookmarksToolbar.png b/themes/linux/places/bookmarksToolbar.png
new file mode 100644
index 0000000..09502fe
Binary files /dev/null and b/themes/linux/places/bookmarksToolbar.png differ
diff --git a/themes/linux/places/calendar.png b/themes/linux/places/calendar.png
new file mode 100644
index 0000000..f712868
Binary files /dev/null and b/themes/linux/places/calendar.png differ
diff --git a/themes/linux/places/downloads.png b/themes/linux/places/downloads.png
new file mode 100644
index 0000000..d641714
Binary files /dev/null and b/themes/linux/places/downloads.png differ
diff --git a/themes/linux/places/editBookmarkOverlay.css b/themes/linux/places/editBookmarkOverlay.css
new file mode 100644
index 0000000..f1f6210
--- /dev/null
+++ b/themes/linux/places/editBookmarkOverlay.css
@@ -0,0 +1,71 @@
+%if 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/. */
+%endif
+/**** folder menulist ****/
+.folder-icon > .menulist-label-box > .menulist-icon {
+ width: 16px;
+ height: 16px;
+}
+
+.folder-icon > .menu-iconic-left {
+ display: -moz-box;
+}
+
+.folder-icon {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu") !important;
+}
+
+
+/**** expanders ****/
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ padding: 2px 0;
+ -moz-padding-start: 2px;
+}
+
+.expander-up > .button-box {
+ -moz-appearance: button-arrow-up;
+}
+
+.expander-down > .button-box {
+ -moz-appearance: button-arrow-down;
+}
+
+#editBookmarkPanelContent {
+ min-width: 23em;
+}
+
+#editBMPanel_folderTree {
+ margin-top: 2px;
+ margin-bottom: 2px;
+}
+
+/* Hide the value column of the tag autocomplete popup
+ * leaving only the comment column visible. This is
+ * so that only the tag being edited is shown in the
+ * popup.
+ */
+#editBMPanel_tagsField #treecolAutoCompleteValue {
+ visibility: collapse;
+}
+
+
+/* Bookmark panel dropdown menu items */
+#editBMPanel_folderMenuList[selectedIndex="0"],
+#editBMPanel_toolbarFolderItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="1"],
+#editBMPanel_bmRootItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png") !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="2"],
+#editBMPanel_unfiledRootItem {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png") !important;
+}
diff --git a/themes/linux/places/livemark-item.png b/themes/linux/places/livemark-item.png
new file mode 100644
index 0000000..9184b95
Binary files /dev/null and b/themes/linux/places/livemark-item.png differ
diff --git a/themes/linux/places/organizer.css b/themes/linux/places/organizer.css
new file mode 100644
index 0000000..cabeebb
--- /dev/null
+++ b/themes/linux/places/organizer.css
@@ -0,0 +1,107 @@
+/* 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/. */
+
+
+/* Toolbar */
+#placesToolbar {
+ border: none;
+}
+
+/* back button */
+
+#back-button {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar");
+}
+#back-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=toolbar&state=disabled");
+}
+
+#back-button:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar");
+}
+#back-button[disabled="true"]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=toolbar&state=disabled");
+}
+
+/* forward button */
+
+#forward-button {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar");
+}
+#forward-button[disabled="true"] {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=toolbar&state=disabled");
+}
+
+#forward-button:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar");
+}
+#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
+ list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=toolbar&state=disabled");
+}
+
+/* Menu */
+#placesMenu {
+ -moz-appearance: none;
+ border: none;
+}
+
+#placesMenu > menu {
+ -moz-padding-start: 4px;
+ -moz-binding: url("chrome://browser/skin/places/organizer.xml#toolbarbutton-dropdown");
+ -moz-appearance: toolbarbutton;
+ color: -moz-DialogText;
+}
+
+#placesMenu > menu:hover:not(:active):not([open="true"]) {
+ color: -moz-buttonhovertext;
+}
+
+#placesMenu > menu > .menubar-right {
+ -moz-appearance: toolbarbutton-dropdown;
+ width: 12px;
+ height: 12px;
+}
+
+/* Root View */
+#placesView {
+ background-color: Window;
+}
+
+/* Info box */
+#detailsDeck {
+ padding: 5px;
+}
+
+#infoBoxExpanderLabel {
+ -moz-padding-start: 2px;
+}
+
+#searchModifiers {
+ padding-right: 3px;
+}
+
+#saveSearch {
+ list-style-image: url("moz-icon://stock/gtk-save?size=menu");
+}
+
+/**** menuitem stock icons ****/
+#orgClose {
+ list-style-image: url("moz-icon://stock/gtk-close?size=menu");
+}
+
+#fileImport {
+ list-style-image: url("moz-icon://stock/gtk-revert-to-saved?size=menu");
+}
+
+#fileExport {
+ list-style-image: url("moz-icon://stock/gtk-save-as?size=menu");
+}
+
+/**
+ * Downloads pane
+ */
+
+#clearDownloadsButton > .toolbarbutton-icon {
+ display: none;
+}
diff --git a/themes/linux/places/organizer.xml b/themes/linux/places/organizer.xml
new file mode 100644
index 0000000..8331ebb
--- /dev/null
+++ b/themes/linux/places/organizer.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/linux/places/pageStarred.png b/themes/linux/places/pageStarred.png
new file mode 100644
index 0000000..61a9f90
Binary files /dev/null and b/themes/linux/places/pageStarred.png differ
diff --git a/themes/linux/places/places.css b/themes/linux/places/places.css
new file mode 100644
index 0000000..d2b806b
--- /dev/null
+++ b/themes/linux/places/places.css
@@ -0,0 +1,221 @@
+/* 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/. */
+
+/* Sidebars */
+.sidebar-placesTree {
+ margin: 0;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
+.sidebar-placesTreechildren::-moz-tree-image(leaf) {
+ cursor: pointer;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(separator) {
+ cursor: default;
+}
+
+/* Trees */
+treechildren::-moz-tree-image(title) {
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+treechildren::-moz-tree-image(title, livemarkItem) {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+treechildren::-moz-tree-image(title, livemarkItem, visited) {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, separator) {
+ list-style-image: none;
+ width: 0;
+ height: 0;
+}
+
+treechildren::-moz-tree-image(title, container) {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+treechildren::-moz-tree-image(title, container, livemark) {
+ list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_AllBookmarks) {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksToolbar) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksMenu) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_UnfiledBookmarks) {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+ -moz-image-region: auto;
+}
+
+/* query-nodes should be styled even if they're not expandable */
+treechildren::-moz-tree-image(title, query) {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+}
+
+treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
+ list-style-image: url("chrome://browser/skin/places/downloads.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(title, query, tagContainer),
+treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+}
+
+/* calendar icon for folders grouping items by date */
+treechildren::-moz-tree-image(title, query, dayContainer) {
+ list-style-image: url("chrome://browser/skin/places/calendar.png");
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer) {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer, open) {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+treechildren::-moz-tree-image(title, query, OrganizerQuery_History) {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+/* We want some queries to look like ordinary folders. This must come
+ after the (title, query) selector, or it would get overridden. */
+treechildren::-moz-tree-image(title, query, folder) {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+treechildren::-moz-tree-image(cutting) {
+ opacity: 0.5;
+}
+
+treechildren::-moz-tree-cell-text(cutting) {
+ opacity: 0.7;
+}
+
+/**** menuitem stock icons ****/
+menuitem:not([type]) {
+ -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
+}
+
+menuitem[command="cmd_cut"],
+menuitem[cmd="cmd_cut"] {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
+}
+
+menuitem[command="cmd_cut"][disabled],
+menuitem[cmd="cmd_cut"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_copy"],
+menuitem[cmd="cmd_copy"] {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
+}
+
+menuitem[command="cmd_copy"][disabled],
+menuitem[cmd="cmd_copy"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_paste"],
+menuitem[cmd="cmd_paste"] {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
+}
+
+menuitem[command="cmd_paste"][disabled],
+menuitem[cmd="cmd_paste"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_delete"],
+menuitem[cmd="cmd_delete"] {
+ list-style-image: url("moz-icon://stock/gtk-delete?size=menu");
+}
+
+menuitem[command="cmd_delete"][disabled],
+menuitem[cmd="cmd_delete"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-delete?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_undo"],
+menuitem[cmd="cmd_undo"] {
+ list-style-image: url("moz-icon://stock/gtk-undo?size=menu");
+}
+
+menuitem[command="cmd_undo"][disabled],
+menuitem[cmd="cmd_undo"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-undo?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_redo"] {
+ list-style-image: url("moz-icon://stock/gtk-redo?size=menu");
+}
+
+menuitem[command="cmd_redo"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-redo?size=menu&state=disabled");
+}
+
+menuitem[command="cmd_selectAll"],
+menuitem[cmd="cmd_selectAll"] {
+ list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
+}
+
+menuitem[command="cmd_selectAll"][disabled],
+menuitem[cmd="cmd_selectAll"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-select-all?size=menu&state=disabled");
+}
+
+#placesContext_open\:newwindow,
+menuitem[command="placesCmd_open:window"] {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 80px 16px 64px);
+}
+
+#placesContext_open\:newprivatewindow,
+menuitem[command="placesCmd_open:privatewindow"] {
+ list-style-image: url("chrome://browser/skin/Privacy-16.png");
+}
+
+#placesContext_open\:newtab,
+menuitem[command="placesCmd_open:tab"] {
+ list-style-image: url("chrome://browser/skin/Toolbar-small.png");
+ -moz-image-region: rect(0px 64px 16px 48px);
+}
+
+#placesContext_show\:info,
+menuitem[command="placesCmd_show:info"] {
+ list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
+}
+
+#placesContext_reload {
+ list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
+}
diff --git a/themes/linux/places/query.png b/themes/linux/places/query.png
new file mode 100644
index 0000000..2420dee
Binary files /dev/null and b/themes/linux/places/query.png differ
diff --git a/themes/linux/places/star-icons.png b/themes/linux/places/star-icons.png
new file mode 100644
index 0000000..2f50c6a
Binary files /dev/null and b/themes/linux/places/star-icons.png differ
diff --git a/themes/linux/places/starPage.png b/themes/linux/places/starPage.png
new file mode 100644
index 0000000..3193a35
Binary files /dev/null and b/themes/linux/places/starPage.png differ
diff --git a/themes/linux/places/starred48.png b/themes/linux/places/starred48.png
new file mode 100644
index 0000000..deefaec
Binary files /dev/null and b/themes/linux/places/starred48.png differ
diff --git a/themes/linux/places/tag.png b/themes/linux/places/tag.png
new file mode 100644
index 0000000..27176cc
Binary files /dev/null and b/themes/linux/places/tag.png differ
diff --git a/themes/linux/places/toolbarDropMarker.png b/themes/linux/places/toolbarDropMarker.png
new file mode 100644
index 0000000..ed3200f
Binary files /dev/null and b/themes/linux/places/toolbarDropMarker.png differ
diff --git a/themes/linux/places/unsortedBookmarks.png b/themes/linux/places/unsortedBookmarks.png
new file mode 100644
index 0000000..4dcf761
Binary files /dev/null and b/themes/linux/places/unsortedBookmarks.png differ
diff --git a/themes/linux/places/unstarred48.png b/themes/linux/places/unstarred48.png
new file mode 100644
index 0000000..1544863
Binary files /dev/null and b/themes/linux/places/unstarred48.png differ
diff --git a/themes/linux/pointerLock-16.png b/themes/linux/pointerLock-16.png
new file mode 100644
index 0000000..862cd11
Binary files /dev/null and b/themes/linux/pointerLock-16.png differ
diff --git a/themes/linux/pointerLock-64.png b/themes/linux/pointerLock-64.png
new file mode 100644
index 0000000..a35ce04
Binary files /dev/null and b/themes/linux/pointerLock-64.png differ
diff --git a/themes/linux/preferences/Options-sync.png b/themes/linux/preferences/Options-sync.png
new file mode 100644
index 0000000..89901fb
Binary files /dev/null and b/themes/linux/preferences/Options-sync.png differ
diff --git a/themes/linux/preferences/Options.png b/themes/linux/preferences/Options.png
new file mode 100644
index 0000000..82bebd2
Binary files /dev/null and b/themes/linux/preferences/Options.png differ
diff --git a/themes/linux/preferences/alwaysAsk.png b/themes/linux/preferences/alwaysAsk.png
new file mode 100644
index 0000000..45256d4
Binary files /dev/null and b/themes/linux/preferences/alwaysAsk.png differ
diff --git a/themes/linux/preferences/applications.css b/themes/linux/preferences/applications.css
new file mode 100644
index 0000000..c9d1b8c
--- /dev/null
+++ b/themes/linux/preferences/applications.css
@@ -0,0 +1,66 @@
+/* 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/. */
+
+/**
+ * Line up the actions menu with action labels above and below it.
+ * Equalize the distance from the left side of the action box to the left side
+ * of the icon for both the menu and the non-menu versions of the action box.
+ * Also make sure the labels are the same distance away from the icons.
+ */
+.actionsMenu {
+ margin-top: -1px;
+ margin-bottom: -1px;
+ -moz-margin-start: -1px;
+ -moz-margin-end: 0;
+}
+
+.typeIcon,
+.actionIcon {
+ -moz-margin-start: 3px;
+ -moz-margin-end: 3px;
+}
+
+richlistitem label {
+ -moz-margin-start: 1px;
+ margin-top: 2px;
+}
+
+richlistitem {
+ min-height: 25px;
+}
+
+richlistitem[appHandlerIcon="ask"],
+menuitem[appHandlerIcon="ask"] {
+ list-style-image: url("chrome://browser/skin/preferences/alwaysAsk.png");
+}
+
+richlistitem[appHandlerIcon="save"],
+menuitem[appHandlerIcon="save"] {
+ list-style-image: url("moz-icon://stock/gtk-save?size=menu");
+}
+
+richlistitem[appHandlerIcon="feed"],
+menuitem[appHandlerIcon="feed"] {
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+richlistitem[appHandlerIcon="plugin"],
+menuitem[appHandlerIcon="plugin"] {
+ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
+}
+
+.actionsMenu .menulist-icon {
+ -moz-margin-end: 1px;
+ height: 16px;
+ width: 16px;
+}
+
+.actionsMenu > menupopup > menuitem > .menu-iconic-left {
+ -moz-padding-start: 0;
+ -moz-padding-end: 4px !important;
+}
+
+.actionsMenu > menupopup > menuitem {
+ -moz-padding-start: 3px;
+}
diff --git a/themes/linux/preferences/mail.png b/themes/linux/preferences/mail.png
new file mode 100644
index 0000000..66d2bc9
Binary files /dev/null and b/themes/linux/preferences/mail.png differ
diff --git a/themes/linux/preferences/preferences.css b/themes/linux/preferences/preferences.css
new file mode 100644
index 0000000..52f8658
--- /dev/null
+++ b/themes/linux/preferences/preferences.css
@@ -0,0 +1,156 @@
+%if 0
+/*
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+*/
+%endif
+
+/* Global Styles */
+#BrowserPreferences radio[pane] {
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+}
+
+radio[pane=paneMain] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px)
+}
+
+radio[pane=paneTabs] {
+ -moz-image-region: rect(0px, 64px, 32px, 32px)
+}
+
+radio[pane=paneContent] {
+ -moz-image-region: rect(0px, 96px, 32px, 64px)
+}
+
+radio[pane=paneApplications] {
+ -moz-image-region: rect(0px, 128px, 32px, 96px)
+}
+
+radio[pane=panePrivacy] {
+ -moz-image-region: rect(0px, 160px, 32px, 128px)
+}
+
+radio[pane=paneSecurity] {
+ -moz-image-region: rect(0px, 192px, 32px, 160px)
+}
+
+radio[pane=paneAdvanced] {
+ -moz-image-region: rect(0px, 224px, 32px, 192px)
+}
+
+%ifdef MOZ_SERVICES_SYNC
+radio[pane=paneSync] {
+ list-style-image: url("chrome://browser/skin/preferences/Options-sync.png") !important;
+}
+%endif
+
+/* Applications Pane */
+#BrowserPreferences[animated="true"] #handlersView {
+ height: 25em;
+}
+
+#BrowserPreferences[animated="false"] #handlersView {
+ -moz-box-flex: 1;
+}
+
+/* Privacy Pane */
+
+/* styles for the link elements copied from .text-link in global.css */
+.inline-link {
+ color: -moz-nativehyperlinktext;
+ text-decoration: none;
+}
+
+.inline-link:hover {
+ text-decoration: underline;
+}
+
+/* Modeless Window Dialogs */
+.windowDialog,
+.windowDialog prefpane {
+ padding: 0px;
+}
+
+#browserHomePage:-moz-locale-dir(rtl) input {
+ unicode-bidi: plaintext;
+ direction: rtl;
+}
+
+.contentPane {
+ margin: 9px 8px 5px 8px;
+}
+
+.actionButtons {
+ margin: 0px 3px 6px 3px !important;
+}
+
+/* Cookies Manager */
+#cookiesChildren::-moz-tree-image(domainCol) {
+ width: 16px;
+ height: 16px;
+ margin: 0px 2px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+#paneApplications {
+ margin-left: 4px;
+ margin-right: 4px;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+#linksOpenInBox {
+ margin-top: 5px;
+}
+
+#paneAdvanced {
+ padding-bottom: 10px;
+}
+#advancedPrefs {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#cookiesChildren::-moz-tree-image(domainCol, container) {
+ list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
+}
+
+#cookieInfoBox {
+ border: 1px solid ThreeDShadow;
+ border-radius: 0px;
+ margin: 4px;
+ padding: 0px;
+}
+
+/* bottom-most box containing a groupbox in a prefpane. Prevents the bottom
+ of the groupbox from being cutoff */
+.bottomBox {
+ padding-bottom: 4px;
+}
+
+/**
+ * Clear Private Data
+ */
+#SanitizeDialogPane > groupbox {
+ margin-top: 0;
+}
+
+%ifdef MOZ_SERVICES_SYNC
+/* Sync Pane */
+
+#syncDesc {
+ padding: 0 8em;
+}
+
+#accountCaptionImage {
+ list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
+}
+
+#syncAddDeviceLabel {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+%endif
diff --git a/themes/linux/privatebrowsing-mask.png b/themes/linux/privatebrowsing-mask.png
new file mode 100644
index 0000000..9eaf3ae
Binary files /dev/null and b/themes/linux/privatebrowsing-mask.png differ
diff --git a/themes/linux/sanitizeDialog.css b/themes/linux/sanitizeDialog.css
new file mode 100644
index 0000000..96cf3bc
--- /dev/null
+++ b/themes/linux/sanitizeDialog.css
@@ -0,0 +1,107 @@
+/* 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/. */
+
+#sanitizeDurationChoice {
+ -moz-margin-end: 0;
+}
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 3px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=dialog");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin-top: 6px;
+ margin-bottom: 6px;
+ -moz-margin-start: -6px;
+ -moz-margin-end: 0;
+}
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ padding: 2px 0;
+ -moz-padding-start: 2px;
+}
+
+.expander-up {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
+}
+
+.expander-down {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
+}
+
+.expander-down:hover:active {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
+}
+
+.expander-up:hover:active {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+/* Without this a useless scrollbar appears in the listbox when its rows
+ attribute is set to the total number of listitems, as it is currently. See
+ bug 489958 comment 14 and bug 491788. */
+#itemList > listitem {
+ padding: 1px 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="accept"] {
+ -moz-margin-end: 0;
+}
diff --git a/themes/linux/searchbar.css b/themes/linux/searchbar.css
new file mode 100644
index 0000000..cb6ecff
--- /dev/null
+++ b/themes/linux/searchbar.css
@@ -0,0 +1,72 @@
+/* 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/. */
+
+.searchbar-textbox {
+ min-height: 22px;
+ width: 6em;
+ min-width: 6em;
+ background-color: -moz-field;
+}
+
+.autocomplete-textbox-container {
+ -moz-box-align: stretch;
+}
+
+.textbox-input-box {
+ margin: 0;
+}
+
+.searchbar-engine-menuitem[selected="true"] > .menu-iconic-text {
+ font-weight: bold;
+}
+
+/* Engine button */
+.searchbar-engine-image {
+ height: 16px;
+ width: 16px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+ -moz-margin-start: 2px;
+}
+
+.searchbar-engine-button {
+ -moz-appearance: none;
+ min-width: 0;
+ margin: 0;
+ border: 0;
+ -moz-box-align: center;
+ background-color: transparent;
+}
+
+.searchbar-engine-button > .button-box {
+ -moz-appearance: none;
+ padding: 2px 0;
+ -moz-padding-end: 2px;
+ border: 0;
+}
+
+.searchbar-dropmarker-image {
+ -moz-appearance: toolbarbutton-dropdown !important;
+ width: 12px;
+ height: 12px;
+}
+
+/* Search go button */
+.search-go-container {
+ -moz-box-align: center;
+}
+
+.search-go-button {
+ padding: 1px;
+ list-style-image: url(moz-icon://stock/gtk-find?size=menu);
+ cursor: pointer;
+}
+
+menuitem[cmd="cmd_clearhistory"] {
+ list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
+}
+
+menuitem[cmd="cmd_clearhistory"][disabled] {
+ list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
+}
+
diff --git a/themes/linux/setDesktopBackground.css b/themes/linux/setDesktopBackground.css
new file mode 100644
index 0000000..585284c
--- /dev/null
+++ b/themes/linux/setDesktopBackground.css
@@ -0,0 +1,18 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+html|canvas#screen {
+ margin: 12px 11px 32px;
+}
+
+#monitor {
+ list-style-image: url("chrome://browser/skin/monitor.png");
+}
+
+#monitor[aspectratio="16:10"] {
+ list-style-image: url("chrome://browser/skin/monitor_16-10.png");
+}
diff --git a/themes/linux/slowStartup-16.png b/themes/linux/slowStartup-16.png
new file mode 100644
index 0000000..834dc0f
Binary files /dev/null and b/themes/linux/slowStartup-16.png differ
diff --git a/themes/linux/statusbar/overlay.css b/themes/linux/statusbar/overlay.css
new file mode 100644
index 0000000..2351aac
--- /dev/null
+++ b/themes/linux/statusbar/overlay.css
@@ -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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/overlay.css
+
+/*
+ * General
+ */
+
+#status4evar-status-text,
+#status4evar-progress-bar
+{
+ margin: 0px 4px;
+}
+
+/*
+ * Download status
+ */
+
+#status4evar-download-progress-bar
+{
+ height: 6px;
+}
+
+toolbar[iconsize="small"] #status4evar-download-progress-bar
+{
+ height: 4px;
+}
+
+#status4evar-download-button[attention] #status4evar-download-icon
+{
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+#status4evar-download-button #status4evar-download-icon
+{
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 24, 24, 0) center no-repeat;
+ min-width: 24px;
+ min-height: 24px;
+}
+
+toolbar[iconsize="small"] #status4evar-download-button #status4evar-download-icon
+{
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"), 0, 16, 16, 0) center no-repeat;
+ min-width: 16px;
+ min-height: 16px;
+}
+
+toolbar[iconsize="small"] > #status4evar-download-button[attention] #status4evar-download-icon {
+ background-image: url("chrome://browser/skin/downloads/download-glow-small.png");
+}
+
+toolbar[mode="icons"] #status4evar-download-button[forcelabel="true"] > label
+{
+ margin: 0px 2px !important;
+ margin-top: -1px !important;
+ -moz-margin-start: 4px !important;
+}
+
+/*
+ * Splitter
+ */
+
+splitter.status4evar-status-splitter
+{
+ width: 8px;
+ margin: 0px -4px;
+}
+
+/*
+ * Location bar
+ */
+
+#urlbar-progress-alt
+{
+ margin: -1px;
+}
+
+#notification-popup-box
+{
+ -moz-margin-start: -1px;
+}
+
+#urlbar .urlbar-over-link-box
+{
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+/*
+ * Add-on bar
+ */
+
+#browser-bottombox[s4eboarder="true"] :-moz-any(#status4evar-status-bar, #addon-bar)
+{
+ -moz-appearance: none;
+}
+
+#browser-bottombox[s4eboarder="true"] > *:not([hidden="true"]):not([collapsed="true"])
+{
+ box-shadow: none !important;
+ border: none !important;
+ border-top: 2px solid !important;
+ -moz-border-top-colors: ThreeDShadow ThreeDHighlight !important;
+}
+
+#browser-bottombox[s4eboarder="true"] > *:not([hidden="true"]):not([collapsed="true"]) ~ *
+{
+ border: none !important;
+}
+
diff --git a/themes/linux/statusbar/prefs.css b/themes/linux/statusbar/prefs.css
new file mode 100644
index 0000000..db6f24e
--- /dev/null
+++ b/themes/linux/statusbar/prefs.css
@@ -0,0 +1,8 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/prefs.css
+
diff --git a/themes/linux/sync-128.png b/themes/linux/sync-128.png
new file mode 100644
index 0000000..1ea3481
Binary files /dev/null and b/themes/linux/sync-128.png differ
diff --git a/themes/linux/sync-16-throbber.png b/themes/linux/sync-16-throbber.png
new file mode 100644
index 0000000..d6f801a
Binary files /dev/null and b/themes/linux/sync-16-throbber.png differ
diff --git a/themes/linux/sync-16.png b/themes/linux/sync-16.png
new file mode 100644
index 0000000..0afb1c7
Binary files /dev/null and b/themes/linux/sync-16.png differ
diff --git a/themes/linux/sync-24-throbber.png b/themes/linux/sync-24-throbber.png
new file mode 100644
index 0000000..5587174
Binary files /dev/null and b/themes/linux/sync-24-throbber.png differ
diff --git a/themes/linux/sync-32.png b/themes/linux/sync-32.png
new file mode 100644
index 0000000..7a762cb
Binary files /dev/null and b/themes/linux/sync-32.png differ
diff --git a/themes/linux/sync-bg.png b/themes/linux/sync-bg.png
new file mode 100644
index 0000000..893a27d
Binary files /dev/null and b/themes/linux/sync-bg.png differ
diff --git a/themes/linux/sync-desktopIcon.png b/themes/linux/sync-desktopIcon.png
new file mode 100644
index 0000000..d3d1e27
Binary files /dev/null and b/themes/linux/sync-desktopIcon.png differ
diff --git a/themes/linux/sync-mobileIcon.png b/themes/linux/sync-mobileIcon.png
new file mode 100644
index 0000000..a3bda57
Binary files /dev/null and b/themes/linux/sync-mobileIcon.png differ
diff --git a/themes/linux/syncCommon.css b/themes/linux/syncCommon.css
new file mode 100644
index 0000000..9a84ceb
--- /dev/null
+++ b/themes/linux/syncCommon.css
@@ -0,0 +1,49 @@
+/* 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/. */
+
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
+.status {
+ color: -moz-dialogtext;
+}
+
+.statusIcon {
+ -moz-margin-start: 4px;
+ max-height: 16px;
+ max-width: 16px;
+}
+
+.statusIcon[status="active"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.statusIcon[status="error"] {
+ list-style-image: url("moz-icon://stock/gtk-dialog-error?size=menu");
+}
+
+.statusIcon[status="success"] {
+ list-style-image: url("moz-icon://stock/gtk-dialog-info?size=menu");
+}
+
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
+ a separate stylesheet for it. */
+.data {
+ font-size: 90%;
+ font-weight: bold;
+}
+
+dialog#change-dialog {
+ width: 40em;
+}
+
+image#syncIcon {
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
+
+#introText {
+ margin-top: 2px;
+}
+
+#feedback {
+ height: 2em;
+}
diff --git a/themes/linux/syncProgress.css b/themes/linux/syncProgress.css
new file mode 100644
index 0000000..d7aa599
--- /dev/null
+++ b/themes/linux/syncProgress.css
@@ -0,0 +1,46 @@
+/* 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/. */
+@import url(chrome://global/skin/inContentUI.css);
+
+:root {
+ height: 100%;
+ width: 100%;
+ padding: 0;
+}
+
+body {
+ margin: 0;
+ padding: 0 2em;
+}
+
+#floatingBox {
+ margin: 4em auto;
+ max-width: 40em;
+ min-width: 23em;
+ padding: 1em 1.5em;
+ position: relative;
+ text-align: center;
+}
+
+#successLogo {
+ margin: 1em 2em;
+}
+
+#loadingText {
+ margin: 2em 6em;
+}
+
+#progressBar {
+ margin: 2em 10em;
+}
+
+#uploadProgressBar{
+ width: 100%;
+}
+
+#bottomRow {
+ margin-top: 2em;
+ padding: 0;
+ text-align: end;
+}
diff --git a/themes/linux/syncQuota.css b/themes/linux/syncQuota.css
new file mode 100644
index 0000000..1577de8
--- /dev/null
+++ b/themes/linux/syncQuota.css
@@ -0,0 +1,26 @@
+/* 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/. */
+
+#quotaDialog {
+ width: 33em;
+ height: 25em;
+}
+
+treechildren::-moz-tree-checkbox {
+ list-style-image: none;
+}
+treechildren::-moz-tree-checkbox(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-checkbox(disabled) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+#treeCaption {
+ height: 4em;
+}
+
+.captionWarning {
+ font-weight: bold;
+}
diff --git a/themes/linux/syncSetup.css b/themes/linux/syncSetup.css
new file mode 100644
index 0000000..4c6518a
--- /dev/null
+++ b/themes/linux/syncSetup.css
@@ -0,0 +1,127 @@
+/* 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/. */
+
+wizard {
+ -moz-appearance: none;
+ width: 55em;
+ height: 45em;
+ padding: 0;
+ background-color: Window;
+}
+
+.wizard-page-box {
+ -moz-appearance: none;
+ padding-left: 0;
+ padding-right: 0;
+ margin: 0;
+}
+
+wizardpage {
+ -moz-box-pack: center;
+ -moz-box-align: center;
+ margin: 0;
+ padding: 0 6em;
+ background-color: Window;
+}
+
+.wizard-header {
+ -moz-appearance: none;
+ border: none;
+ padding: 2em 0 1em 0;
+ text-align: center;
+}
+.wizard-header-label {
+ font-size: 24pt;
+ font-weight: normal;
+}
+
+.wizard-buttons {
+ background-color: rgba(0,0,0,0.1);
+ padding: 1em;
+}
+
+.wizard-buttons-separator {
+ visibility: collapse;
+}
+
+.wizard-header-icon {
+ visibility: collapse;
+}
+
+.accountChoiceButton {
+ font: menu;
+}
+
+.confirm {
+ border: 1px solid black;
+ padding: 1em;
+ border-radius: 5px;
+}
+
+/* Override the text-link style from global.css */
+description > .text-link,
+description > .text-link:focus {
+ margin: 0px;
+ padding: 0px;
+ border: 0px;
+}
+
+
+.success,
+.error {
+ padding: 2px;
+ border-radius: 2px;
+}
+
+.error {
+ background-color: #FF0000 !important;
+ color: #FFFFFF !important;
+}
+
+.success {
+ background-color: #00FF00 !important;
+}
+
+.warning {
+ font-weight: bold;
+ font-size: 100%;
+ color: red;
+}
+
+.mainDesc {
+ font-weight: bold;
+ font-size: 100%;
+}
+
+.normal {
+ font-size: 100%;
+}
+
+.inputColumn {
+ -moz-margin-end: 2px
+}
+
+.pin {
+ font-size: 18pt;
+ width: 4em;
+ text-align: center;
+}
+
+#passphraseHelpSpacer {
+ width: 0.5em;
+}
+
+#pairDeviceThrobber > image,
+#login-throbber > image {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#captchaFeedback {
+ visibility: hidden;
+}
+
+#successPageIcon {
+ /* TODO replace this with a 128px version (bug 591122) */
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
diff --git a/themes/linux/tabbrowser/alltabs.png b/themes/linux/tabbrowser/alltabs.png
new file mode 100644
index 0000000..2f19025
Binary files /dev/null and b/themes/linux/tabbrowser/alltabs.png differ
diff --git a/themes/linux/tabbrowser/connecting.png b/themes/linux/tabbrowser/connecting.png
new file mode 100644
index 0000000..e564fb5
Binary files /dev/null and b/themes/linux/tabbrowser/connecting.png differ
diff --git a/themes/linux/tabbrowser/loading.png b/themes/linux/tabbrowser/loading.png
new file mode 100644
index 0000000..55f25e5
Binary files /dev/null and b/themes/linux/tabbrowser/loading.png differ
diff --git a/themes/linux/tabbrowser/tab-overflow-border.png b/themes/linux/tabbrowser/tab-overflow-border.png
new file mode 100644
index 0000000..77f2462
Binary files /dev/null and b/themes/linux/tabbrowser/tab-overflow-border.png differ
diff --git a/themes/linux/tabbrowser/tab.png b/themes/linux/tabbrowser/tab.png
new file mode 100644
index 0000000..deeeb0a
Binary files /dev/null and b/themes/linux/tabbrowser/tab.png differ
diff --git a/themes/linux/tabbrowser/tabDragIndicator.png b/themes/linux/tabbrowser/tabDragIndicator.png
new file mode 100644
index 0000000..df7d914
Binary files /dev/null and b/themes/linux/tabbrowser/tabDragIndicator.png differ
diff --git a/themes/linux/urlbar-arrow.png b/themes/linux/urlbar-arrow.png
new file mode 100644
index 0000000..fcab253
Binary files /dev/null and b/themes/linux/urlbar-arrow.png differ
diff --git a/themes/linux/web-notifications-icon.svg b/themes/linux/web-notifications-icon.svg
new file mode 100644
index 0000000..f7186c7
--- /dev/null
+++ b/themes/linux/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/themes/linux/web-notifications-tray.svg b/themes/linux/web-notifications-tray.svg
new file mode 100644
index 0000000..314026a
--- /dev/null
+++ b/themes/linux/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/linux/webRTC-shareDevice-16.png b/themes/linux/webRTC-shareDevice-16.png
new file mode 100644
index 0000000..8bc5b3a
Binary files /dev/null and b/themes/linux/webRTC-shareDevice-16.png differ
diff --git a/themes/linux/webRTC-shareDevice-64.png b/themes/linux/webRTC-shareDevice-64.png
new file mode 100644
index 0000000..d125789
Binary files /dev/null and b/themes/linux/webRTC-shareDevice-64.png differ
diff --git a/themes/linux/webRTC-sharingDevice-16.png b/themes/linux/webRTC-sharingDevice-16.png
new file mode 100644
index 0000000..a670676
Binary files /dev/null and b/themes/linux/webRTC-sharingDevice-16.png differ
diff --git a/themes/moz.build b/themes/moz.build
new file mode 100644
index 0000000..5040c10
--- /dev/null
+++ b/themes/moz.build
@@ -0,0 +1,14 @@
+# -*- 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/.
+
+toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
+
+if toolkit == 'cocoa':
+ DIRS += ['osx']
+elif toolkit in ('gtk2', 'gtk3', 'qt'):
+ DIRS += ['linux']
+else:
+ DIRS += ['windows']
diff --git a/themes/osx/Geolocation-16.png b/themes/osx/Geolocation-16.png
new file mode 100644
index 0000000..d710e73
Binary files /dev/null and b/themes/osx/Geolocation-16.png differ
diff --git a/themes/osx/Geolocation-64.png b/themes/osx/Geolocation-64.png
new file mode 100644
index 0000000..1bd46ba
Binary files /dev/null and b/themes/osx/Geolocation-64.png differ
diff --git a/themes/osx/Info.png b/themes/osx/Info.png
new file mode 100644
index 0000000..d09e82b
Binary files /dev/null and b/themes/osx/Info.png differ
diff --git a/themes/osx/KUI-background.png b/themes/osx/KUI-background.png
new file mode 100644
index 0000000..104a49f
Binary files /dev/null and b/themes/osx/KUI-background.png differ
diff --git a/themes/osx/KUI-close.png b/themes/osx/KUI-close.png
new file mode 100644
index 0000000..08eeb81
Binary files /dev/null and b/themes/osx/KUI-close.png differ
diff --git a/themes/osx/Makefile.in b/themes/osx/Makefile.in
new file mode 100644
index 0000000..173ca68
--- /dev/null
+++ b/themes/osx/Makefile.in
@@ -0,0 +1,7 @@
+# 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/.
+
+ICON_FILES := icon.png
+ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
+INSTALL_TARGETS += ICON
diff --git a/themes/osx/Privacy-16.png b/themes/osx/Privacy-16.png
new file mode 100644
index 0000000..a4be3e9
Binary files /dev/null and b/themes/osx/Privacy-16.png differ
diff --git a/themes/osx/Privacy-32.png b/themes/osx/Privacy-32.png
new file mode 100644
index 0000000..dd07c1a
Binary files /dev/null and b/themes/osx/Privacy-32.png differ
diff --git a/themes/osx/Privacy-48.png b/themes/osx/Privacy-48.png
new file mode 100644
index 0000000..2396f99
Binary files /dev/null and b/themes/osx/Privacy-48.png differ
diff --git a/themes/osx/Privacy-64.png b/themes/osx/Privacy-64.png
new file mode 100644
index 0000000..d360501
Binary files /dev/null and b/themes/osx/Privacy-64.png differ
diff --git a/themes/osx/Search-glass.png b/themes/osx/Search-glass.png
new file mode 100644
index 0000000..9eb0e25
Binary files /dev/null and b/themes/osx/Search-glass.png differ
diff --git a/themes/osx/Secure24.png b/themes/osx/Secure24.png
new file mode 100644
index 0000000..896343a
Binary files /dev/null and b/themes/osx/Secure24.png differ
diff --git a/themes/osx/Toolbar-glass.png b/themes/osx/Toolbar-glass.png
new file mode 100644
index 0000000..23cc4bf
Binary files /dev/null and b/themes/osx/Toolbar-glass.png differ
diff --git a/themes/osx/Toolbar-inverted.png b/themes/osx/Toolbar-inverted.png
new file mode 100644
index 0000000..2c3253f
Binary files /dev/null and b/themes/osx/Toolbar-inverted.png differ
diff --git a/themes/osx/Toolbar.png b/themes/osx/Toolbar.png
new file mode 100644
index 0000000..3d1b80e
Binary files /dev/null and b/themes/osx/Toolbar.png differ
diff --git a/themes/osx/aboutCertError.css b/themes/osx/aboutCertError.css
new file mode 100644
index 0000000..dbb3530
--- /dev/null
+++ b/themes/osx/aboutCertError.css
@@ -0,0 +1,73 @@
+/* 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/. */
+
+
+html {
+ background: #833;
+}
+
+body {
+ margin: 0;
+ padding: 0 1em;
+ color: -moz-FieldText;
+ font: message-box;
+}
+
+h1 {
+ margin: 0 0 .6em 0;
+ border-bottom: 1px solid ThreeDLightShadow;
+ font-size: 160%;
+}
+
+h2 {
+ font-size: 130%;
+}
+
+#errorPageContainer {
+ position: relative;
+ min-width: 13em;
+ max-width: 52em;
+ margin: 4em auto;
+ border: 2px solid #DD0D09;
+ border-radius: 10px;
+ box-shadow: 0px 0px 8px red;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat -moz-Field;
+ background-origin: content-box;
+}
+
+#errorPageContainer:-moz-dir(rtl) {
+ background-position: right 0;
+}
+
+#errorTitle {
+ -moz-margin-start: 80px;
+}
+
+#errorLongContent {
+ -moz-margin-start: 80px;
+}
+
+.expander > button {
+ -moz-padding-start: 20px;
+ -moz-margin-start: -20px;
+ background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
+ border: none;
+ font: inherit;
+ color: inherit;
+ cursor: pointer;
+}
+
+.expander > button:-moz-dir(rtl) {
+ background-position: right center;
+}
+
+.expander[collapsed] > button {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
+}
+
+.expander[collapsed] > button:-moz-dir(rtl) {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
+}
diff --git a/themes/osx/aboutCertError_sectionCollapsed-rtl.png b/themes/osx/aboutCertError_sectionCollapsed-rtl.png
new file mode 100644
index 0000000..84ba18c
Binary files /dev/null and b/themes/osx/aboutCertError_sectionCollapsed-rtl.png differ
diff --git a/themes/osx/aboutCertError_sectionCollapsed.png b/themes/osx/aboutCertError_sectionCollapsed.png
new file mode 100644
index 0000000..c9805f6
Binary files /dev/null and b/themes/osx/aboutCertError_sectionCollapsed.png differ
diff --git a/themes/osx/aboutCertError_sectionExpanded.png b/themes/osx/aboutCertError_sectionExpanded.png
new file mode 100644
index 0000000..128cef9
Binary files /dev/null and b/themes/osx/aboutCertError_sectionExpanded.png differ
diff --git a/themes/osx/aboutPrivateBrowsing.css b/themes/osx/aboutPrivateBrowsing.css
new file mode 100644
index 0000000..cd6026b
--- /dev/null
+++ b/themes/osx/aboutPrivateBrowsing.css
@@ -0,0 +1,47 @@
+%if 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/. */
+%endif
+
+body.private > #errorPageContainer {
+ background-image: url("chrome://browser/skin/Privacy-48.png");
+}
+
+body.normal > #errorPageContainer {
+ background-image: url("chrome://global/skin/icons/question-48.png");
+}
+
+#clearRecentHistoryDesc {
+ margin-top: 2em;
+}
+
+#clearRecentHistoryDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#startPrivateBrowsingDesc > button {
+ -moz-margin-start: 0;
+}
+
+#footerDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#moreInfo {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+ -moz-padding-start: 25px;
+ background: url("chrome://global/skin/icons/information-16.png") no-repeat top left;
+}
+
+#moreInfo:-moz-dir(rtl) {
+ background-position: top right;
+}
+
+#moreInfoText {
+ margin-bottom: 0;
+}
+
+#moreInfoLinkContainer {
+ margin-top: 0.5em;
+}
diff --git a/themes/osx/aboutSessionRestore.css b/themes/osx/aboutSessionRestore.css
new file mode 100644
index 0000000..4fa4907
--- /dev/null
+++ b/themes/osx/aboutSessionRestore.css
@@ -0,0 +1,73 @@
+%if 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/. */
+%endif
+
+html {
+ background: #f8ffd0;
+ height: 100%;
+}
+
+body {
+ height: 100%;
+ text-align: center;
+}
+
+#errorPageContainer {
+ background-image: url("chrome://global/skin/icons/warning-large.png");
+ display: -moz-box;
+ width: -moz-available;
+ max-width: 85%;
+ height: 75%;
+ max-height: 85%;
+ -moz-box-orient: vertical;
+ text-align: start;
+ border: 2px solid #efc;
+ box-shadow: 0px 0px 8px #aaa;
+}
+
+#errorShortDesc > p {
+ margin-top: 0.4em;
+ margin-bottom: 0;
+}
+
+#errorLongContent, #errorTrailerDesc {
+ display: -moz-box;
+ -moz-box-flex: 1;
+ -moz-box-orient: vertical;
+}
+
+#tabList {
+ margin-top: 2.5em;
+ width: 100%;
+ min-height: 12em;
+}
+
+treechildren::-moz-tree-image(icon),
+treechildren::-moz-tree-image(noicon) {
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+}
+
+treechildren::-moz-tree-image(noicon) {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+treechildren::-moz-tree-image(container, noicon) {
+ list-style-image: url("chrome://browser/skin/aboutSessionRestore-window-icon.png");
+}
+treechildren::-moz-tree-image(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-image(partial) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+#buttons {
+ width: 100%;
+}
+#buttons > button {
+ margin-top: 2em;
+}
diff --git a/themes/osx/aboutSyncTabs.css b/themes/osx/aboutSyncTabs.css
new file mode 100644
index 0000000..4f21a9d
--- /dev/null
+++ b/themes/osx/aboutSyncTabs.css
@@ -0,0 +1,101 @@
+/* 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/. */
+
+#tabs-display,
+#tabsList {
+ background-color: transparent;
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#tabsList {
+ width: 100%;
+}
+
+#tabs-display {
+ background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
+}
+
+#headers {
+ background: url(chrome://browser/skin/sync-32.png) no-repeat;
+ margin-top: 4px;
+ width: 45em;
+ height: 32px;
+ -moz-margin-start: 2em;
+ -moz-margin-end: 2em;
+}
+
+#tabsListHeading {
+ font-size: 140%;
+ font-weight: bold;
+ -moz-margin-start: 40px;
+}
+
+richlistitem {
+ -moz-margin-end: 2em;
+}
+
+richlistitem[selected="true"],
+richlistitem:focus {
+ outline-style: none;
+}
+
+richlistitem[type="tab"] {
+ min-height: 3em;
+ border: #999999 1px solid !important;
+ padding: 2px 5px;
+ margin-bottom: 4px;
+ -moz-margin-start: 4em;
+ border-radius: 6px;
+ background-color: menu;
+ width: 44em;
+ opacity: 0.9;
+ box-shadow:
+ inset rgba(255, 255, 255, 0.5) 0 1px 0px,
+ inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
+ rgba(0, 0, 0, 0.1) 0px 1px 0px;
+}
+
+richlistitem[type="tab"][selected="true"] {
+ background-color: -moz-MenuHover;
+}
+
+richlistitem[type="client"] {
+ min-height: 2em;
+ color: #000000;
+ -moz-margin-start: 2em;
+ margin-top: 2px;
+ margin-bottom: 3px;
+ width: 42em;
+ border-radius: 6px;
+ background-color: transparent;
+ -moz-user-focus: ignore !important;
+}
+richlistitem.mobile[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+}
+richlistitem.desktop[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+}
+
+.title,
+.clientName {
+ color: #000000;
+ font-size: 1.1em;
+}
+
+.title[selected="true"],
+.url[selected="true"] {
+ color: inherit;
+}
+
+.url {
+ color: -moz-nativehyperlinktext;
+ font-size: 0.95em;
+}
+
+.tabIcon {
+ -moz-padding-start: 2px;
+ padding-top: 2px;
+}
diff --git a/themes/osx/actionicon-tab.png b/themes/osx/actionicon-tab.png
new file mode 100644
index 0000000..ced958e
Binary files /dev/null and b/themes/osx/actionicon-tab.png differ
diff --git a/themes/osx/appmenu-dropmarker.png b/themes/osx/appmenu-dropmarker.png
new file mode 100644
index 0000000..27deaff
Binary files /dev/null and b/themes/osx/appmenu-dropmarker.png differ
diff --git a/themes/osx/appmenu-icons.png b/themes/osx/appmenu-icons.png
new file mode 100644
index 0000000..78f3658
Binary files /dev/null and b/themes/osx/appmenu-icons.png differ
diff --git a/themes/osx/autocomplete.css b/themes/osx/autocomplete.css
new file mode 100644
index 0000000..a50dbd8
--- /dev/null
+++ b/themes/osx/autocomplete.css
@@ -0,0 +1,198 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* .padded is used by autocomplete widgets that don't have an icon. Gross. -dwh */
+textbox:not(.padded) {
+ cursor: default;
+ padding: 0;
+}
+
+textbox[nomatch="true"][highlightnonmatches="true"] {
+ color: red;
+}
+
+textbox:not(.padded) .textbox-input-box {
+ margin: 0 3px;
+}
+
+.textbox-input-box {
+ -moz-box-align: center;
+}
+
+/* ::::: history button ::::: */
+
+.private-autocomplete-history-dropmarker {
+ -moz-appearance: none !important;
+ border: none !important;
+ background-color: transparent !important;
+ padding: 0px;
+ list-style-image: url("chrome://global/skin/icons/autocomplete-dropmarker.png");
+ margin: 0px;
+}
+
+/* ::::: autocomplete popups ::::: */
+
+panel[type="private-autocomplete"],
+panel[type="private-autocomplete-richlistbox"],
+.private-autocomplete-history-popup {
+ padding: 0px !important;
+ color: -moz-FieldText;
+ background-color: -moz-Field;
+ font: icon;
+ -moz-appearance: none;
+}
+
+.private-autocomplete-history-popup {
+ max-height: 180px;
+}
+
+/* ::::: tree ::::: */
+
+.private-autocomplete-tree {
+ -moz-appearance: none !important;
+ border: none !important;
+ background-color: transparent !important;
+}
+
+.private-autocomplete-treecol {
+ -moz-appearance: none !important;
+ margin: 0 !important;
+ border: none !important;
+ padding: 0 !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-cell-text {
+ padding-left: 2px;
+}
+
+.private-autocomplete-treebody::-moz-tree-row {
+ border-top: none;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-row(selected) {
+ background-color: Highlight;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-cell-text(selected) {
+ color: HighlightText !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-image(treecolAutoCompleteValue) {
+ max-width: 16px;
+ height: 16px;
+}
+
+/* ::::: richlistbox autocomplete ::::: */
+
+.private-autocomplete-richlistbox {
+ -moz-appearance: none;
+ margin: 0;
+}
+
+.private-autocomplete-richlistitem[selected="true"] {
+ background-color: Highlight;
+ color: HighlightText;
+ background-image: linear-gradient(rgba(255,255,255,0.3), transparent);
+}
+
+.private-autocomplete-richlistitem {
+ padding: 5px 2px;
+}
+
+.ac-url-box {
+ /* When setting a vertical margin here, half of that needs to be added
+ .ac-title-box's translateY for when .ac-url-box is hidden (see below). */
+ margin-top: 1px;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-url-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-url-box {
+ visibility: hidden;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-title-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-title-box {
+ /* Center the title by moving it down by half of .ac-url-box's height,
+ including vertical margins (if any). */
+ transform: translateY(.5em);
+}
+
+.ac-site-icon {
+ width: 16px;
+ height: 16px;
+ margin-bottom: -1px;
+ -moz-margin-start: 7px;
+ -moz-margin-end: 5px;
+}
+
+.ac-type-icon {
+ width: 16px;
+ height: 16px;
+ -moz-margin-start: 6px;
+ -moz-margin-end: 4px;
+}
+
+.ac-url-box > .ac-site-icon,
+.ac-url-box > .ac-type-icon {
+ /* Otherwise the spacer is big enough to stretch its container */
+ height: auto;
+}
+
+.ac-extra > .ac-result-type-tag {
+ margin: 0 4px;
+}
+
+.ac-extra > .ac-comment {
+ padding-right: 4px;
+}
+
+.ac-ellipsis-after {
+ margin: 0 !important;
+ padding: 0;
+ min-width: 1.1em;
+}
+
+.ac-normal-text {
+ margin: 0 !important;
+ padding: 0;
+}
+
+.ac-normal-text > html|span {
+ margin: 0 !important;
+ padding: 0;
+}
+
+html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(208,208,208,0.4);
+ background-color: rgba(208,208,208,0.2);
+ border-radius: 2px;
+ text-shadow: 0 0 currentColor;
+}
+
+.ac-url-text > html|span.ac-emphasize-text,
+.ac-action-text > html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(183,210,226,0.4);
+ background-color: rgba(183,210,226,0.3);
+}
+
+.ac-title, .ac-url {
+ overflow: hidden;
+}
+
+/* ::::: textboxes inside toolbarpaletteitems ::::: */
+
+toolbarpaletteitem > toolbaritem > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
+
+toolbarpaletteitem > toolbaritem > * > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
diff --git a/themes/osx/browser.css b/themes/osx/browser.css
new file mode 100644
index 0000000..20e453d
--- /dev/null
+++ b/themes/osx/browser.css
@@ -0,0 +1,2802 @@
+/* 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/. */
+
+@import url("chrome://global/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+%include shared.inc
+%filter substitution
+%define toolbarHighlight rgba(255,255,255,.5)
+%define selectedTabHighlight rgba(255,255,255,.7)
+%define toolbarShadowColor rgba(10%,10%,10%,.4)
+%define toolbarShadowOnTab linear-gradient(to top, rgba(10%,10%,10%,.4) 1px, transparent 1px)
+%define bgTabTexture linear-gradient(transparent, hsla(0,0%,45%,.1) 1px, hsla(0,0%,32%,.2) 80%, hsla(0,0%,0%,.2))
+%define bgTabTextureHover linear-gradient(hsla(0,0%,100%,.3) 1px, hsla(0,0%,75%,.2) 80%, hsla(0,0%,60%,.2))
+%define navbarTextboxCustomBorder border-color: rgba(0,0,0,.32);
+%define navbarLargeIcons #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar
+%define forwardTransitionLength 150ms
+%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) #navigator-toolbox[iconsize=large][mode=icons] > :-moz-any(#nav-bar[currentset*="unified-back-forward-button"],#nav-bar:not([currentset])) > #unified-back-forward-button
+%define conditionalForwardWithUrlbarWidth 27
+
+#navigator-toolbox {
+ -moz-appearance: none;
+ background-color: transparent;
+ border-top: none;
+}
+
+#main-window {
+ -moz-appearance: none;
+ background-color: #eeeeee;
+}
+
+#navigator-toolbox::after {
+ content: "";
+ display: -moz-box;
+ -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
+ height: 1px;
+ background-color: ThreeDShadow;
+}
+#navigator-toolbox[tabsontop=false]::after,
+#main-window[disablechrome] #navigator-toolbox::after {
+ visibility: collapse;
+}
+
+#navigator-toolbox > toolbar:not(:-moz-lwtheme) {
+ -moz-appearance: none;
+ border-style: none;
+ background-color: -moz-Dialog;
+}
+
+#nav-bar[tabsontop=true]:not(:-moz-lwtheme),
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):not(:-moz-lwtheme) + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):not(:-moz-lwtheme) + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
+}
+
+#nav-bar[tabsontop=true]:-moz-lwtheme,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(rgba(255,255,255,.8), rgba(255,255,255,0));
+}
+
+#nav-bar[tabsontop=true]:-moz-lwtheme-brighttext,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme-brighttext + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]):-moz-lwtheme-brighttext + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(rgba(32,32,32,.8), rgba(32,32,32,0));
+}
+
+#personal-bookmarks {
+ min-height: 24px;
+}
+
+#print-preview-toolbar:not(:-moz-lwtheme) {
+ -moz-appearance: toolbox;
+}
+
+#browser-bottombox:not(:-moz-lwtheme) {
+ background-color: -moz-dialog;
+}
+
+
+
+/* ::::: titlebar ::::: */
+
+#main-window[sizemode="normal"]:not([privatebrowsingmode=temporary]) > #titlebar {
+ -moz-appearance: -moz-window-titlebar;
+}
+
+#main-window[sizemode="maximized"] > #titlebar {
+ -moz-appearance: -moz-window-titlebar-maximized;
+}
+
+#titlebar-buttonbox {
+ -moz-appearance: -moz-window-button-box;
+}
+
+#main-window[sizemode="maximized"] #titlebar-buttonbox {
+ -moz-appearance: -moz-window-button-box-maximized;
+}
+
+.titlebar-placeholder[type="appmenu-button"] {
+ margin-left: 4px;
+}
+
+.titlebar-placeholder[type="caption-buttons"] {
+ margin-left: 10px;
+}
+
+/* titlebar command buttons */
+
+#titlebar-min {
+ -moz-appearance: -moz-window-button-minimize;
+}
+
+#titlebar-max {
+ -moz-appearance: -moz-window-button-maximize;
+}
+
+#main-window[sizemode="maximized"] #titlebar-max {
+ -moz-appearance: -moz-window-button-restore;
+}
+
+#titlebar-close {
+ -moz-appearance: -moz-window-button-close;
+}
+
+/* ensure titlebar on privacy windows is of correct size */
+#titlebar {
+ height: 22px;
+}
+
+/* ensure extra titlebar doesn't appear on normal (e.g. non-privacy) windows */
+#main-window:not([privatebrowsingmode=temporary]):not(:-moz-lwtheme) > #titlebar > #titlebar-content > #titlebar-buttonbox-container,
+#main-window:not([drawintitlebar=true]):not(:-moz-lwtheme) > #titlebar {
+ display: none;
+}
+
+#titlebar-buttonbox-container {
+ margin-left: 7px;
+ margin-top: 3px;
+}
+
+/* ::::: bookmark toolbar ::::: */
+
+#personal-bookmarks {
+ min-height: 17px; /* 16px button height + 1px margin-bottom */
+}
+
+toolbarbutton.chevron {
+ list-style-image: url("chrome://global/skin/icons/chevron.png");
+ margin: 1px 0 0;
+ padding: 0;
+}
+
+toolbarbutton.chevron > .toolbarbutton-text {
+ display: none;
+}
+
+toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
+ display: -moz-box; /* display chevron icon in text mode */
+}
+
+toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+@media (min-resolution: 2dppx) {
+ toolbarbutton.chevron {
+ list-style-image: url("chrome://global/skin/icons/chevron@2x.png");
+ }
+
+ toolbarbutton.chevron > .toolbarbutton-icon {
+ width: 13px;
+ }
+}
+
+/* ::::: bookmark buttons ::::: */
+
+toolbarbutton.bookmark-item {
+ color: #222;
+ border: 0;
+ border-radius: 10000px;
+ padding: 1px 8px;
+ margin: 0 0 1px;
+}
+
+.bookmark-item > .toolbarbutton-menu-dropmarker {
+ list-style-image: url("chrome://browser/skin/places/folderDropArrow.png");
+ -moz-image-region: rect(0, 7px, 5px, 0);
+ margin-top: 1px;
+ -moz-margin-start: 3px;
+ -moz-margin-end: -2px;
+}
+
+@media (min-resolution: 2dppx) {
+ .bookmark-item > .toolbarbutton-menu-dropmarker {
+ list-style-image: url("chrome://browser/skin/places/folderDropArrow@2x.png");
+ -moz-image-region: rect(0, 14px, 10px, 0);
+ }
+
+ .bookmark-item > .toolbarbutton-menu-dropmarker > .dropmarker-icon {
+ width: 7px;
+ }
+}
+
+.bookmark-item > .toolbarbutton-text {
+ display: -moz-box !important; /* prevent [mode="icons"] from hiding the label */
+ margin: 0 !important;
+}
+
+toolbarbutton.bookmark-item:hover,
+toolbarbutton.bookmark-item[open="true"] {
+ background-color: rgba(0, 0, 0, .205);
+}
+
+toolbarbutton.bookmark-item:hover,
+toolbarbutton.bookmark-item[open="true"] {
+ color: #FFF !important;
+ text-shadow: 0 1px rgba(0, 0, 0, .4) !important;
+}
+
+.bookmark-item:hover > .toolbarbutton-menu-dropmarker,
+.bookmark-item[open="true"] > .toolbarbutton-menu-dropmarker {
+ -moz-image-region: rect(5px, 7px, 10px, 0);
+}
+
+@media (min-resolution: 2dppx) {
+ .bookmark-item:hover > .toolbarbutton-menu-dropmarker,
+ .bookmark-item[open="true"] > .toolbarbutton-menu-dropmarker {
+ -moz-image-region: rect(10px, 14px, 20px, 0);
+ }
+}
+
+toolbarbutton.bookmark-item:active:hover,
+toolbarbutton.bookmark-item[open="true"] {
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.4), 0 1px rgba(255, 255, 255, 0.4);
+ background-color: rgba(0, 0, 0, .5);
+}
+
+toolbarbutton.bookmark-item > menupopup {
+ margin-top: 2px;
+ -moz-margin-start: 3px;
+}
+
+.bookmark-item > .toolbarbutton-icon {
+ width: 16px;
+ min-height: 16px;
+ max-height: 16px;
+}
+
+.bookmark-item > .toolbarbutton-icon[label]:not([label=""]),
+.bookmark-item > .toolbarbutton-icon[type="menu"] {
+ -moz-margin-end: 5px;
+}
+
+.bookmark-item[container] {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+}
+
+.bookmark-item[container][livemark] {
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+.bookmark-item[container][livemark] .bookmark-item {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.bookmark-item[container][livemark] .bookmark-item[visited] {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.bookmark-item[container][query] {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+}
+
+.bookmark-item[query][tagContainer] {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+}
+
+.bookmark-item[query][dayContainer] {
+ list-style-image: url("chrome://browser/skin/places/history.png");
+}
+
+.bookmark-item[query][hostContainer] {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+}
+
+.bookmark-item[query][hostContainer][open] {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+}
+
+@media (min-resolution: 2dppx) {
+ .bookmark-item[container] {
+ list-style-image: url("chrome://global/skin/tree/folder@2x.png");
+ }
+
+ .bookmark-item[container][livemark] {
+ list-style-image: url("chrome://browser/skin/page-livemarks@2x.png");
+ }
+
+ .bookmark-item[container][livemark] .bookmark-item {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ }
+
+ .bookmark-item[container][query] {
+ list-style-image: url("chrome://browser/skin/places/query@2x.png");
+ }
+
+ .bookmark-item[query][tagContainer] {
+ list-style-image: url("chrome://browser/skin/places/tag@2x.png");
+ }
+
+ .bookmark-item[query][dayContainer] {
+ list-style-image: url("chrome://browser/skin/places/history@2x.png");
+ }
+
+ .bookmark-item[query][hostContainer] {
+ list-style-image: url("chrome://global/skin/tree/folder@2x.png");
+ }
+
+ .bookmark-item[query][hostContainer][open] {
+ list-style-image: url("chrome://global/skin/tree/folder@2x.png");
+ }
+}
+
+/* Workaround for native menubar inheritance */
+.openintabs-menuitem,
+.openlivemarksite-menuitem,
+.livemarkstatus-menuitem {
+ list-style-image: none;
+}
+
+.bookmark-item[cutting] > .toolbarbutton-icon,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
+ opacity: 0.5;
+}
+
+.bookmark-item[cutting] > .toolbarbutton-text,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
+ opacity: 0.7;
+}
+
+@media (min-resolution: 2dppx) {
+ .bookmark-item > .toolbarbutton-icon,
+ .bookmark-item > .menu-iconic-left > .menu-iconic-icon {
+ image-rendering: -moz-crisp-edges;
+ }
+}
+
+#wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
+ background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
+}
+
+.bookmarks-toolbar-customize {
+ max-width: 15em !important;
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+}
+
+@media (min-resolution: 2dppx) {
+ #wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
+ background-image: url("chrome://browser/skin/places/bookmarksToolbar@2x.png");
+ background-size: 16px;
+ }
+
+ .bookmarks-toolbar-customize {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar@2x.png") !important;
+ }
+
+ .bookmarks-toolbar-customize > .toolbarbutton-icon {
+ width: 16px;
+ }
+}
+
+/* ::::: bookmark menus ::::: */
+
+.bookmark-item > .menu-iconic-left > .menu-iconic-icon {
+ width: 16px;
+ height: 16px;
+}
+
+/* ::::: primary toolbar buttons ::::: */
+
+.toolbarbutton-1 {
+ list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+
+toolbar[brighttext] .toolbarbutton-1 {
+ list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
+}
+
+.toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-dropmarker,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+.toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
+}
+
+toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
+toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
+}
+
+.toolbarbutton-1 > .toolbarbutton-icon,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ -moz-margin-end: 0;
+}
+
+toolbar[mode=full] .toolbarbutton-1:not([type=menu-button]) {
+ -moz-box-orient: vertical;
+}
+
+toolbar[mode=full] .toolbarbutton-1,
+toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ min-width: 57px;
+}
+
+#nav-bar {
+ /* force iconsize="small" on this toolbar */
+ counter-reset: smallicons;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ -moz-appearance: none;
+ border: none;
+ padding: 0;
+ background: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not([type=menu-button]),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ padding: 5px 2px;
+ -moz-box-pack: center;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button) {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > menupopup {
+ margin-top: -3px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ -moz-padding-end: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ -moz-padding-start: 0;
+ -moz-box-align: center;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+ padding: 2px 6px;
+ background: hsla(210,32%,93%,.3) padding-box;
+ background-image: linear-gradient(hsla(0,0%,100%,.4), hsla(0,0%,100%,.1));
+ background-clip: padding-box;
+ border-radius: 2.5px;
+ border: 1px solid;
+ border-color: hsla(210,54%,20%,.2) hsla(210,54%,20%,.2) hsla(210,54%,20%,.2);
+ box-shadow: 0 1px hsla(0,0%,100%,.05) inset,
+ 0 1px hsla(210,54%,20%,.05),
+ 0 0 2px hsla(210,54%,20%,.05);
+ transition-property: background-image, background-color, border-color, box-shadow;
+ transition-duration: 150ms;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ padding: 3px 7px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1[type=menu] > .toolbarbutton-text /* hack for add-ons that forcefully display the label */ {
+ -moz-padding-end: 17px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
+ -moz-margin-start: -15px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ -moz-border-end: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+ padding: 8px 5px 7px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before {
+ content: "";
+ display: -moz-box;
+ width: 1px;
+ height: 18px;
+ -moz-margin-end: -1px;
+ background-image: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
+ background-clip: padding-box;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 1px 18px;
+ box-shadow: 0 0 0 1px hsla(0,0%,100%,.2);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(ltr),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(rtl) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(rtl),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(ltr) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):hover > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack,
+@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([open]):not([disabled]):not(:active)) > .toolbarbutton-icon {
+ background-image: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.5));
+ border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.3) hsla(210,54%,20%,.35);
+ box-shadow: 0 1px hsla(0,0%,100%,.3) inset,
+ 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+ transition-property: background-image, background-color, border-color, box-shadow;
+ transition-duration: 150ms;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):not([open]):not(:active):hover > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon,
+@conditionalForwardWithUrlbar@ > #forward-button:not([open]):not(:active):not([disabled]):hover > .toolbarbutton-icon {
+ border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
+ background-color: hsla(210,48%,96%,.75);
+ box-shadow: 0 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover:active > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1[open] > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack {
+ background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
+ background-color: hsla(210,54%,20%,.15);
+ border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
+ box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
+ 0 0 1px hsla(210,54%,20%,.2) inset,
+ /* allows windows-keyhole-forward-clip-path to be used for non-hover as well as hover: */
+ 0 1px 0 hsla(210,54%,20%,0),
+ 0 0 2px hsla(210,54%,20%,0);
+ text-shadow: none;
+ transition: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:-moz-any(:hover,[open]) > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
+ -moz-border-start-color: hsla(210,54%,20%,.35);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon {
+ background-color: rgba(90%,90%,90%,.4);
+ transition: background-color .4s;
+}
+
+:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1,
+:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.tabbrowser-arrowscrollbox > .scrollbutton-up,
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ -moz-appearance: none;
+ border-style: none;
+ padding: 0 3px;
+}
+
+#TabsToolbar .toolbarbutton-1:not([disabled]):hover,
+#TabsToolbar .toolbarbutton-1[open],
+#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover,
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):hover,
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):hover {
+ background-image: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.5)),
+ linear-gradient(transparent, rgba(0,0,0,.25) 30%),
+ linear-gradient(transparent, rgba(0,0,0,.25) 30%);
+ background-position: 1px -1px, 0 -1px, 100% -1px;
+ background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
+ background-repeat: no-repeat;
+}
+
+#addon-bar .toolbarbutton-1:not([disabled]):hover,
+#addon-bar .toolbarbutton-1[open],
+#addon-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover {
+ background-image: linear-gradient(to top, transparent, rgba(0,0,0,.15)),
+ linear-gradient(to top, transparent, rgba(0,0,0,.15) 30%),
+ linear-gradient(to top, transparent, rgba(0,0,0,.15) 30%);
+ background-position: left, left, right;
+ background-size: auto, 1px 100%, 1px 100%;
+ background-repeat: no-repeat;
+}
+
+/* unified back/forward button */
+
+#back-button {
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#forward-button {
+ -moz-image-region: rect(0, 36px, 18px, 18px);
+}
+
+#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#forward-button:-moz-locale-dir(rtl),
+#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-text {
+ transform: scaleX(-1);
+}
+
+@conditionalForwardWithUrlbar@ {
+ -moz-box-align: center;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button {
+ padding: 0;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button > menupopup {
+ margin-top: 1px;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button > .toolbarbutton-icon {
+ /*mask: url(keyhole-forward-mask.svg#mask); XXX: this regresses twinopen */
+ clip-path: url(chrome://browser/content/browser.xul#windows-keyhole-forward-clip-path);
+ -moz-margin-start: -6px !important;
+ border-left-style: none;
+ border-radius: 0;
+ padding-left: 7px;
+ padding-right: 3px;
+}
+
+@conditionalForwardWithUrlbar@:not([switchingtabs]) > #forward-button {
+ transition: opacity @forwardTransitionLength@ ease-out;
+}
+
+@conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
+ /* opacity: 0; */
+}
+
+@conditionalForwardWithUrlbar@ > #back-button {
+ -moz-image-region: rect(18px, 20px, 38px, 0);
+ padding-top: 3px;
+ padding-bottom: 3px;
+ -moz-padding-start: 5px;
+ -moz-padding-end: 0;
+ position: relative;
+ z-index: 1;
+ border-radius: 0 10000px 10000px 0;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:-moz-locale-dir(rtl) {
+ border-radius: 10000px 0 0 10000px;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button > menupopup {
+ margin-top: -1px;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button > .toolbarbutton-icon {
+ border-radius: 10000px;
+ padding: 5px;
+ border: none;
+ background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(210,54%,20%,.25),
+ 0 1px 0 hsla(210,54%,20%,.35);
+ transition-property: background-color, box-shadow;
+ transition-duration: 250ms;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
+ background-color: hsla(210,48%,96%,.75);
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(210,54%,20%,.3),
+ 0 1px 0 hsla(210,54%,20%,.4),
+ 0 0 4px hsla(210,54%,20%,.2);
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
+@conditionalForwardWithUrlbar@ > #back-button[open="true"] > .toolbarbutton-icon {
+ background-color: hsla(210,54%,20%,.15);
+ box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
+ 0 0 1px hsla(210,54%,20%,.2) inset,
+ 0 0 0 1px hsla(210,54%,20%,.4),
+ 0 1px 0 hsla(210,54%,20%,.2);
+ transition: none;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button[disabled] > .toolbarbutton-icon {
+ box-shadow: 0 0 0 1px hsla(210,54%,20%,.55),
+ 0 1px 0 hsla(210,54%,20%,.65);
+ transition: none;
+}
+
+.unified-nav-back[_moz-menuactive]:-moz-locale-dir(ltr),
+.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("chrome://browser/skin/menu-back.png") !important;
+}
+
+.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(ltr),
+.unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
+}
+
+#stop-button {
+ -moz-image-region: rect(0, 54px, 18px, 36px);
+}
+
+#reload-button {
+ -moz-image-region: rect(0, 72px, 18px, 54px);
+}
+
+#home-button.bookmark-item {
+ list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+toolbar[brighttext] #home-button.bookmark-item {
+ list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
+}
+
+#home-button {
+ -moz-image-region: rect(0, 90px, 18px, 72px);
+}
+
+#downloads-button {
+ -moz-image-region: rect(0, 108px, 18px, 90px);
+}
+
+#history-button,
+#history-menu-button {
+ -moz-image-region: rect(0, 126px, 18px, 108px);
+}
+
+#bookmarks-button,
+#bookmarks-menu-button {
+ -moz-image-region: rect(0, 144px, 18px, 126px);
+}
+
+#bookmarks-menu-button.bookmark-item {
+ list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+
+toolbar[brighttext] #bookmarks-menu-button.bookmark-item {
+ list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
+}
+
+#print-button {
+ -moz-image-region: rect(0, 162px, 18px, 144px);
+}
+
+#new-tab-button {
+ -moz-image-region: rect(0, 180px, 18px, 162px);
+}
+
+#new-window-button {
+ -moz-image-region: rect(0, 198px, 18px, 180px);
+}
+
+#cut-button {
+ -moz-image-region: rect(0, 216px, 18px, 198px);
+}
+
+#copy-button {
+ -moz-image-region: rect(0, 234px, 18px, 216px);
+}
+
+#paste-button {
+ -moz-image-region: rect(0, 252px, 18px, 234px);
+}
+
+#fullscreen-button {
+ -moz-image-region: rect(0, 270px, 18px, 252px);
+}
+
+#zoom-out-button {
+ -moz-image-region: rect(0, 288px, 18px, 270px);
+}
+
+#zoom-in-button {
+ -moz-image-region: rect(0, 306px, 18px, 288px);
+}
+
+#sync-button {
+ -moz-image-region: rect(0, 324px, 18px, 306px);
+}
+#sync-button[status="active"] {
+ list-style-image: url("chrome://browser/skin/sync-throbber.png");
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#feed-button {
+ -moz-image-region: rect(0, 342px, 18px, 324px);
+}
+
+%ifdef MOZ_WEBRTC
+#webrtc-status-button {
+ -moz-image-region: rect(0, 360px, 18px, 342px);
+}
+%endif
+
+/* ::::: Location Bar ::::: */
+
+#urlbar,
+.searchbar-textbox {
+ -moz-appearance: none;
+ margin: 1px 3px;
+ padding: 0;
+ background-clip: padding-box;
+ border: 1px solid ThreeDShadow;
+ border-radius: 2px;
+}
+
+#urlbar {
+ width: 7em;
+ -moz-padding-end: 2px;
+}
+
+@media (-moz-mac-lion-theme) {
+ #urlbar,
+ .searchbar-textbox {
+ @navbarTextboxCustomBorder@
+ }
+}
+
+#urlbar:-moz-lwtheme,
+.searchbar-textbox:-moz-lwtheme {
+ background-color: rgba(255,255,255,.8);
+ @navbarTextboxCustomBorder@
+ color: black;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container {
+ padding-left: @conditionalForwardWithUrlbarWidth@px;
+ -moz-margin-start: -@conditionalForwardWithUrlbarWidth@px;
+ position: relative;
+ pointer-events: none;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar {
+ -moz-border-start: none;
+ margin-left: 0;
+ pointer-events: all;
+}
+
+@conditionalForwardWithUrlbar@:not([switchingtabs]) + #urlbar-container > #urlbar {
+ transition: margin-left @forwardTransitionLength@ ease-out;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(ltr) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container {
+ clip-path: url("chrome://browser/content/browser.xul#windows-urlbar-back-button-clip-path");
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container:-moz-locale-dir(rtl),
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
+ /* let windows-urlbar-back-button-mask clip the urlbar's right side for RTL */
+ transform: scaleX(-1);
+}
+
+html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
+.searchbar-textbox:-moz-lwtheme > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input::-moz-placeholder {
+ opacity: 1.0;
+ color: #777;
+}
+
+#urlbar:-moz-lwtheme[focused="true"],
+.searchbar-textbox:-moz-lwtheme[focused="true"] {
+ background-color: white;
+}
+
+#urlbar-container {
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+}
+
+.urlbar-textbox-container {
+ -moz-box-align: stretch;
+}
+
+.urlbar-input-box {
+ -moz-margin-start: 0;
+ min-width: 4em;
+}
+
+#urlbar-icons {
+ -moz-box-align: center;
+}
+
+.urlbar-icon {
+ padding: 0 3px;
+}
+
+.searchbar-engine-button,
+.search-go-container {
+ padding: 2px 2px;
+}
+
+.urlbar-icon:hover {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.3), hsla(200,100%,70%,0));
+}
+
+.urlbar-icon[open="true"],
+.urlbar-icon:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.1), hsla(200,100%,70%,0));
+}
+
+#urlbar-search-splitter {
+ min-width: 6px;
+ -moz-margin-start: -3px;
+ border: none;
+ background: transparent;
+}
+
+#urlbar-search-splitter + #urlbar-container > #urlbar ,
+#urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
+ -moz-margin-start: 0;
+}
+
+#urlbar-display-box {
+ -moz-border-end: 1px solid #AAA;
+ -moz-margin-end: 3px;
+}
+
+#urlbar-display {
+ margin-top: 0;
+ margin-bottom: 0;
+ -moz-margin-start: 0;
+ color: GrayText;
+}
+
+/* identity box */
+
+#identity-box {
+ padding: 2px;
+ font-size: .9em;
+}
+
+#identity-box:-moz-locale-dir(ltr) {
+ border-top-left-radius: 1.5px;
+ border-bottom-left-radius: 1.5px;
+}
+
+#identity-box:-moz-locale-dir(rtl) {
+ border-top-right-radius: 1.5px;
+ border-bottom-right-radius: 1.5px;
+}
+
+#notification-popup-box:not([hidden]) + #identity-box {
+ -moz-padding-start: 10px;
+ border-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar > #identity-box {
+ border-radius: 0;
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity {
+ color: hsl(92,100%,30%);
+ -moz-margin-end: 4px;
+ background-image: -moz-linear-gradient(hsla(92,81%,16%,0),
+ hsla(92,81%,16%,.08) 25%,
+ hsla(92,81%,16%,.08) 75%,
+ hsla(92,81%,16%,0));
+ background-position: right;
+ background-repeat: no-repeat;
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedDomain {
+ color: rgb(0,79,168);
+ -moz-margin-end: 4px;
+ background-image: -moz-linear-gradient(rgba(0,79,168,0),
+ rgba(0,79,168,.08) 25%,
+ rgba(0,79,168,.08) 75%,
+ rgba(0,79,168,0));
+ background-position: right;
+ background-repeat: no-repeat;
+}
+
+#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
+ background-position: left;
+}
+
+#identity-box.verifiedIdentity:not(:-moz-lwtheme) {
+ background-color: #fff;
+ box-shadow: inset 0 0 2px rgb(0,168,0);
+}
+
+#identity-box.verifiedDomain:not(:-moz-lwtheme) {
+ background-color: rgb(224,234,247);
+ box-shadow: inset 0 0 2px rgb(0,79,168);
+}
+
+#identity-box:-moz-focusring {
+ outline: 1px dotted #000;
+ outline-offset: -3px;
+}
+
+#identity-icon-labels {
+ -moz-padding-start: 2px;
+ -moz-padding-end: 5px;
+}
+
+/* Address bar shading for SSL */
+
+#urlbar[https_color="all"][security_level="broken"],
+#urlbar[https_color="all"][security_level="low"] {
+ box-shadow: inset 0 0 4px rgb(168,0,0);
+}
+
+#urlbar[https_color="all"][security_level="mixed"],
+#urlbar[https_color="secure-mixed"][security_level="mixed"] {
+ box-shadow: inset 0 0 4px rgb(168,79,0);
+}
+
+#urlbar[https_color="all"][security_level="high"],
+#urlbar[https_color="secure-mixed"][security_level="high"],
+#urlbar[https_color="secure-only"][security_level="high"] {
+ box-shadow: inset 0 0 4px rgb(0,79,168);
+}
+
+#urlbar[https_color="all"][security_level="ev"],
+#urlbar[https_color="secure-mixed"][security_level="ev"],
+#urlbar[https_color="secure-only"][security_level="ev"] {
+ box-shadow: inset 0 0 4px rgb(0,168,0);
+}
+
+#urlbar[https_color="all"]:-moz-lwtheme-darktext,
+#urlbar[https_color="secure-mixed"]:-moz-lwtheme-darktext,
+#urlbar[https_color="secure-only"]:-moz-lwtheme-darktext {
+ box-shadow: inset 0 0 2px;
+}
+
+
+/* Location bar dropmarker */
+
+.urlbar-history-dropmarker {
+ -moz-appearance: none;
+ padding: 0 3px;
+ background-color: transparent;
+ border: none;
+ width: auto;
+ list-style-image: url("chrome://browser/skin/urlbar-history-dropmarker.png");
+ -moz-image-region: rect(0px, 11px, 14px, 0px);
+}
+
+.urlbar-history-dropmarker:hover {
+ background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
+ -moz-image-region: rect(0px, 22px, 14px, 11px);
+}
+
+.urlbar-history-dropmarker:hover:active,
+.urlbar-history-dropmarker[open="true"] {
+ background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.1), hsla(205,100%,70%,0));
+ -moz-image-region: rect(0px, 33px, 14px, 22px);
+}
+
+/* page proxy icon */
+
+#page-proxy-favicon {
+ width: 16px;
+ height: 16px;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ -moz-margin-start: 3px;
+ -moz-margin-end: 2px;
+ list-style-image: url(chrome://browser/skin/identity-icons-generic.png);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar > #identity-box > #page-proxy-favicon {
+ -moz-margin-end: 1px;
+}
+
+/* Since we already have a padlock, always use the generic icon until the favicon loads
+.verifiedDomain > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https.png);
+}
+
+.verifiedIdentity > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
+}
+
+.mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
+}
+*/
+
+#identity-box:hover > #page-proxy-favicon {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#identity-box:hover:active > #page-proxy-favicon,
+#identity-box[open=true] > #page-proxy-favicon {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#page-proxy-favicon[pageproxystate="invalid"] {
+ opacity: 0.3;
+}
+
+/* autocomplete */
+
+#treecolAutoCompleteImage {
+ max-width: 36px;
+}
+
+.ac-result-type-bookmark,
+.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0px 48px 16px 32px);
+ width: 16px;
+ height: 16px;
+}
+
+.ac-result-type-keyword,
+.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
+ list-style-image: url(chrome://global/skin/icons/search-textbox.png);
+ margin: 2px;
+ width: 12px;
+ height: 12px;
+}
+
+.ac-result-type-tag,
+.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ width: 16px;
+ height: 16px;
+}
+
+.ac-comment {
+ font-size: 1.06em;
+}
+
+.ac-extra > .ac-comment {
+ font-size: 1em;
+}
+
+.ac-url-text,
+.ac-action-text {
+ font-size: 1em;
+ color: -moz-nativehyperlinktext;
+}
+
+@media (-moz-mac-lion-theme) {
+ .ac-url-text:not([selected="true"]),
+ .ac-action-text:not([selected="true"]) {
+ color: #008800;
+ }
+}
+
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+ list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+ -moz-image-region: rect(0, 16px, 11px, 0);
+ padding: 0 3px;
+}
+
+richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
+ -moz-image-region: rect(11px, 16px, 22px, 0);
+}
+
+.ac-comment[selected="true"],
+.ac-url-text[selected="true"],
+.ac-action-text[selected="true"] {
+ color: inherit !important;
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
+ color: GrayText;
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
+.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
+{
+ color: GrayText;
+ font-size: smaller;
+}
+
+.autocomplete-treebody::-moz-tree-cell(suggesthint) {
+ border-top: 1px solid GrayText;
+}
+
+/* combined go/reload/stop button in location bar */
+
+#go-button,
+#urlbar > toolbarbutton {
+ -moz-appearance: none;
+ padding: 0 2px;
+ background-origin: border-box;
+ border: none;
+ list-style-image: url("chrome://browser/skin/reload-stop-go.png");
+}
+
+#go-button {
+ padding: 0 3px;
+}
+
+#urlbar-reload-button {
+ -moz-image-region: rect(0, 14px, 14px, 0);
+}
+
+#urlbar-reload-button:not([disabled]):hover {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), hsla(200,100%,70%,0));
+ -moz-image-region: rect(14px, 14px, 28px, 0);
+}
+
+#urlbar-reload-button:not([disabled]):hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), hsla(200,100%,60%,0));
+ -moz-image-region: rect(28px, 14px, 42px, 0);
+}
+
+#urlbar-reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+#go-button,
+#urlbar-go-button {
+ -moz-image-region: rect(0, 42px, 14px, 28px);
+}
+
+#go-button:hover,
+#urlbar-go-button:hover {
+ background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), hsla(110,70%,50%,0));
+ -moz-image-region: rect(14px, 42px, 28px, 28px);
+}
+
+#go-button:hover:active,
+#urlbar-go-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), hsla(110,70%,50%,0));
+ -moz-image-region: rect(28px, 42px, 42px, 28px);
+}
+
+#go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#urlbar-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+#urlbar-stop-button {
+ -moz-image-region: rect(0, 28px, 14px, 14px);
+}
+
+#urlbar-stop-button:not([disabled]):hover {
+ background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), hsla(5,100%,75%,0));
+ -moz-image-region: rect(14px, 28px, 28px, 14px);
+}
+
+#urlbar-stop-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), hsla(5,100%,75%,0));
+ -moz-image-region: rect(28px, 28px, 42px, 14px);
+}
+
+/* popup blocker button */
+
+#page-report-button {
+ list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+#page-report-button:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#page-report-button:hover:active,
+#page-report-button[open="true"] {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+
+/* star button */
+
+#star-button {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+#star-button:hover {
+ background-image: radial-gradient(circle closest-side, hsla(45,100%,73%,.3), hsla(45,100%,73%,0));
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#star-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(45,100%,73%,.1), hsla(45,100%,73%,0));
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+#star-button[starred] {
+ list-style-image: url("chrome://browser/skin/places/editBookmark.png");
+}
+
+/* bookmarking panel */
+
+#editBookmarkPanelStarIcon {
+ list-style-image: url("chrome://browser/skin/places/starred48.png");
+ width: 48px;
+ height: 48px;
+}
+
+#editBookmarkPanelStarIcon[unstarred] {
+ list-style-image: url("chrome://browser/skin/places/unstarred48.png");
+}
+
+#editBookmarkPanelTitle {
+ font-size: 130%;
+}
+
+#editBookmarkPanelHeader,
+#editBookmarkPanelContent {
+ margin-bottom: .5em;
+}
+
+/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+#editBMPanel_folderTree {
+ min-width: 27em;
+}
+
+/* BOOKMARKING PANEL */
+#editBookmarkPanelStarIcon {
+ list-style-image: url("chrome://browser/skin/places/starred48.png");
+ width: 48px;
+ height: 48px;
+}
+
+#editBookmarkPanelStarIcon[unstarred] {
+ list-style-image: url("chrome://browser/skin/places/unstarred48.png");
+}
+
+#editBookmarkPanelTitle {
+ font-size: 130%;
+ font-weight: bold;
+}
+
+#editBMPanel_rows > row {
+ margin-bottom: 8px;
+}
+
+#editBMPanel_rows > row:last-of-type {
+ margin-bottom: 0;
+}
+
+/**** Input elements ****/
+
+#editBMPanel_rows > row > textbox,
+#editBMPanel_rows > row > hbox > textbox {
+ -moz-appearance: none;
+ background: linear-gradient(#fafafa, #fff);
+ background-clip: padding-box;
+ border-radius: 3px;
+ border: 1px solid rgba(0,0,0,.3) !important;
+ box-shadow: inset 0 1px 1px 1px rgba(0,0,0,.05),
+ 0 1px rgba(255,255,255,.3);
+ margin: 0;
+ padding: 3px 6px;
+}
+
+#editBMPanel_rows > row > textbox[focused="true"],
+#editBMPanel_rows > row > hbox > textbox[focused="true"] {
+ border-color: -moz-mac-focusring !important;
+ box-shadow: @focusRingShadow@;
+}
+
+/**** HUD style buttons ****/
+
+.editBookmarkPanelHeaderButton,
+.editBookmarkPanelBottomButton {
+ @hudButton@
+ margin: 0;
+ min-width: 82px;
+ min-height: 22px;
+}
+
+.editBookmarkPanelHeaderButton:hover:active,
+.editBookmarkPanelBottomButton:hover:active {
+ @hudButtonPressed@
+}
+
+.editBookmarkPanelHeaderButton:-moz-focusring,
+.editBookmarkPanelBottomButton:-moz-focusring {
+ @hudButtonFocused@
+}
+
+.editBookmarkPanelBottomButton[default="true"] {
+ background-color: #666;
+}
+
+#editBookmarkPanelHeader {
+ margin-bottom: 6px;
+}
+
+.editBookmarkPanelBottomButton:last-child {
+ -moz-margin-start: 8px;
+}
+
+/* The following elements come from editBookmarkOverlay.xul. Styling that's
+ specific to the editBookmarkPanel should be in browser.css. Styling that
+ should be shared by all editBookmarkOverlay.xul consumers should be in
+ editBookmarkOverlay.css. */
+
+#editBMPanel_newFolderBox {
+ background: linear-gradient(#fff, #f2f2f2);
+ background-origin: padding-box;
+ background-clip: padding-box;
+ border-radius: 0 0 3px 3px;
+ border: 1px solid #a5a5a5;
+ box-shadow: inset 0 1px rgba(255,255,255,.8),
+ inset 0 0 1px rgba(255,255, 255,.25),
+ 0 1px rgba(255,255,255,.3);
+ margin: 0;
+ padding: 0;
+ height: 20px;
+}
+
+#editBMPanel_newFolderButton {
+ -moz-appearance: none;
+ border: 0 solid #a5a5a5;
+ -moz-border-end-width: 1px;
+ padding: 0 9px;
+ margin: 0;
+ min-width: 21px;
+ min-height: 20px;
+ height: 20px;
+ color: #fff;
+ list-style-image: url("chrome://browser/skin/panel-plus-sign.png");
+ position: relative;
+}
+
+#editBMPanel_newFolderButton:hover:active {
+ background: linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9));
+ box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4);
+}
+
+#editBMPanel_newFolderButton:-moz-focusring {
+ @hudButtonFocused@
+}
+
+#editBMPanel_newFolderButton .button-text {
+ display: none;
+}
+
+#editBMPanel_folderMenuList {
+ @hudButton@
+ background-clip: padding-box;
+ margin: 0;
+ min-height: 22px;
+ padding-top: 2px;
+ padding-bottom: 1px;
+ -moz-padding-start: 8px;
+ -moz-padding-end: 4px;
+}
+
+#editBMPanel_folderMenuList:-moz-focusring {
+ @hudButtonFocused@
+}
+
+#editBMPanel_folderMenuList[open="true"],
+#editBMPanel_folderMenuList:hover:active {
+ @hudButtonPressed@
+}
+
+#editBMPanel_folderMenuList > .menulist-dropmarker {
+ -moz-appearance: none;
+ display: -moz-box;
+ background-color: transparent;
+ border: 0;
+ margin: 0;
+ padding: 0;
+ -moz-padding-end: 4px;
+ width: 7px;
+}
+
+#editBMPanel_folderMenuList > .menulist-dropmarker > .dropmarker-icon {
+ list-style-image: url("chrome://global/skin/icons/panel-dropmarker.png");
+}
+
+/**** folder tree and tag selector ****/
+
+#editBMPanel_folderTree,
+#editBMPanel_tagsSelector {
+ -moz-appearance: none;
+ background: linear-gradient(#fafafa, #fff);
+ background-clip: padding-box;
+ border-radius: 3px;
+ border: 1px solid rgba(0,0,0,.3);
+ box-shadow: inset 0 1px 1px 1px rgba(0,0,0,.05),
+ 0 1px rgba(255,255,255,.3);
+ margin: 0;
+}
+
+#editBMPanel_folderTree:-moz-focusring,
+#editBMPanel_tagsSelector:-moz-focusring {
+ border-color: -moz-mac-focusring;
+ box-shadow: @focusRingShadow@;
+}
+
+#editBMPanel_folderTree {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ /* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+ margin: 0 !important;
+ min-width: 27em;
+ position: relative;
+}
+
+/**** expanders ****/
+
+#editBookmarkPanel .expander-up,
+#editBookmarkPanel .expander-down {
+ @hudButton@
+ margin: 0;
+ -moz-margin-start: 4px;
+ min-width: 27px;
+ min-height: 22px;
+}
+
+#editBookmarkPanel .expander-up:-moz-focusring,
+#editBookmarkPanel .expander-down:-moz-focusring {
+ @hudButtonFocused@
+}
+
+#editBookmarkPanel .expander-up:hover:active,
+#editBookmarkPanel .expander-down:hover:active {
+ @hudButtonPressed@
+}
+
+#editBookmarkPanel .expander-up {
+ list-style-image: url("chrome://browser/skin/panel-expander-open.png");
+}
+
+#editBookmarkPanel .expander-down {
+ list-style-image: url("chrome://browser/skin/panel-expander-closed.png");
+}
+
+#editBookmarkPanel .expander-up > .button-box > .button-icon,
+#editBookmarkPanel .expander-down > .button-box > .button-icon {
+ margin: 1px 0 0;
+}
+
+#editBookmarkPanel .expander-up > .button-box > .button-text,
+#editBookmarkPanel .expander-down > .button-box > .button-text {
+ display: none;
+}
+
+@media (min-resolution: 2dppx) {
+ #editBookmarkPanel .expander-up {
+ list-style-image: url("chrome://browser/skin/panel-expander-open@2x.png");
+ }
+
+ #editBookmarkPanel .expander-down {
+ list-style-image: url("chrome://browser/skin/panel-expander-closed@2x.png");
+ }
+
+ #editBookmarkPanel .expander-up > .button-box > .button-icon,
+ #editBookmarkPanel .expander-down > .button-box > .button-icon {
+ width: 9px;
+ }
+}
+
+#editBMPanel_tagsField > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input::-moz-placeholder {
+ opacity: 1.0;
+ color: #bbb;
+}
+
+.editBMPanel_rowLabel {
+ text-align: end;
+}
+
+/* ::::: content area ::::: */
+
+#sidebar {
+ background-color: Window;
+}
+
+#sidebar-title {
+ -moz-padding-start: 0px;
+}
+
+/* ::::: throbber ::::: */
+
+#navigator-throbber {
+ width: 16px;
+ min-height: 16px;
+ margin: 0 3px;
+}
+
+#navigator-throbber[busy="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#navigator-throbber,
+#wrapper-navigator-throbber > #navigator-throbber {
+ list-style-image: url("chrome://global/skin/icons/notloading_16.png");
+}
+
+/* Tabstrip */
+
+#TabsToolbar {
+ min-height: 0;
+ padding: 0;
+}
+
+#TabsToolbar:not(:-moz-lwtheme),
+#TabsToolbar[tabsontop=false] {
+ background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%);
+}
+
+/* When the tab bar is collapsed, show a 1px border in its place. */
+#TabsToolbar[tabsontop="false"][collapsed="true"]:not([customizing="true"]) {
+ visibility: visible;
+ height: 1px;
+ border-bottom-width: 1px;
+ /* !important here to override border-style: none on the toolbar */
+ border-bottom-style: solid !important;
+ border-bottom-color: ThreeDShadow;
+ overflow: hidden;
+}
+
+@media (-moz-mac-lion-theme) {
+ #main-window[sizemode=normal] #TabsToolbar {
+ padding-left: 2px;
+ padding-right: 2px;
+ }
+}
+
+/* remove 5 pixel border on left and right of browser screen */
+.tabbrowser-tabbox {
+ margin: 0;
+}
+
+.tabbrowser-tab,
+.tabs-newtab-button {
+ -moz-appearance: none;
+ background: @toolbarShadowOnTab@, @bgTabTexture@,
+ linear-gradient(-moz-dialog, -moz-dialog);
+ background-clip: padding-box;
+ padding: 3px 1px 4px;
+ /* Setting a transparent outer border allows us to have a 1px gap
+ between the tabs and the top edge of the screen, even when the
+ tabs have a top margin of 0, which is important for Fitts' law
+ compliance */
+ border: 2px solid;
+ border-bottom: none;
+ border-radius: 6px 6px 0px 0px;
+ -moz-border-top-colors: transparent #929292;
+ -moz-border-left-colors: transparent #929292;
+ -moz-border-right-colors: transparent #929292;
+ /* Hide the transparent top border by default */
+ margin-top: -1px;
+ /* Reduce the gap between the tabs */
+ -moz-margin-start: -1px;
+ box-shadow: inset 0.5px 1px 1px rgba(255,255,255,.7);
+}
+
+.tabbrowser-tab {
+ -moz-padding-end: 3px;
+}
+
+/* Override the default (globally-set) tab width values; increase
+ by 2px to compensate for the transparent outer border of the tabs */
+.tabbrowser-tab:not([pinned]) {
+ max-width: 252px;
+ min-width: 102px;
+}
+
+/* When the tabs are on top and the window is maximized or in full-
+ screen mode, unhide the transparent top border of the tabs so we
+ have a 1px gap between the tabs and the top edge of the screen */
+#main-window[sizemode="maximized"][tabsontop=true] .tabbrowser-tab,
+#main-window[sizemode="maximized"][tabsontop=true] .tabs-newtab-button,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabbrowser-tab,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabs-newtab-button {
+ margin-top: 0px;
+}
+
+/* make the tab text colors match those of the Windows client */
+@media (-moz-mac-lion-theme) {
+ tab {
+ text-shadow: none;
+ color: black !important;
+ }
+}
+
+.tabbrowser-tab:hover,
+.tabs-newtab-button:hover {
+ background-image: @toolbarShadowOnTab@, @bgTabTextureHover@,
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+.tabbrowser-tab[selected="true"] {
+ background-image: linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 50%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+#main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
+ background-image: @toolbarShadowOnTab@,
+ linear-gradient(@selectedTabHighlight@, @toolbarHighlight@ 50%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+.tabbrowser-tab[visuallyselected=true]:not(:-moz-lwtheme) {
+ /* overriding tabbox.css */
+ color: inherit;
+}
+
+.tabbrowser-tab[visuallyselected=true] {
+ /* overriding tabbox.css */
+ text-shadow: inherit;
+}
+
+/* Remove highlight fuzz on dark themes */
+.tabbrowser-tab:-moz-lwtheme-brighttext,
+.tabs-newtab-button:-moz-lwtheme-brighttext {
+ box-shadow:none;
+ -moz-border-top-colors: transparent #707070;
+ -moz-border-left-colors: transparent #707070;
+ -moz-border-right-colors: transparent #707070;
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme {
+ background-image: linear-gradient(rgba(255,255,255,.6), rgba(255,255,255,.8) 50%);
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(rgba(128,128,128,.9), rgba(32,32,32,.9) 50%, rgba(32,32,32,.9) 80%, rgba(32,32,32,.8) 100%);
+ -moz-border-top-colors: transparent #D0D0D0;
+ -moz-border-left-colors: transparent #D0D0D0;
+ -moz-border-right-colors: transparent #D0D0D0;
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(hsla(0,0%,25%,.4), hsla(0,0%,15%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-brighttext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,10%,.8) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-darktext {
+ background-image: linear-gradient(hsla(0,0%,75%,.4), hsla(0,0%,85%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-darktext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,90%,.8) 80%);
+}
+
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) {
+ background-image: radial-gradient(circle farthest-corner at 50% 3px, rgba(255,255,255,1) 3%, rgba(186,221,251,.75) 40%, rgba(127,179,255,.5) 80%, rgba(127,179,255,.25));
+}
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]):hover {
+ background-image: linear-gradient(hsla(0,0%,100%,.4), hsla(0,0%,75%,.4) 80%),
+ radial-gradient(circle farthest-corner at 50% 3px, rgba(255,255,255,1) 3%, rgba(186,221,251,.75) 40%, rgba(127,179,255,.5) 80%, rgba(127,179,255,.25));
+}
+
+.tab-throbber,
+.tab-icon-image {
+ width: 16px;
+ height: 16px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+ -moz-margin-start: 2px;
+ -moz-margin-end: 3px;
+}
+
+.tab-throbber {
+ list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
+}
+
+.tab-throbber[progress] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
+}
+
+.tab-throbber[pinned],
+.tab-icon-image[pinned] {
+ -moz-margin-start: 5px;
+ -moz-margin-end: 5px;
+}
+
+/* tabbrowser-tab focus ring */
+.tabbrowser-tab:focus > .tab-stack {
+ outline: 1px dotted;
+}
+
+/* Tab DnD indicator */
+.tab-drop-indicator {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
+ margin-bottom: -11px;
+}
+
+/* Tab close button */
+.tab-close-button {
+ -moz-appearance: none;
+ border: none;
+ padding: 0px;
+}
+
+.tab-close-button:-moz-lwtheme-brighttext {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.png");
+}
+
+@media (min-resolution: 2dppx) {
+ .tab-close-button:-moz-lwtheme-brighttext {
+ list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
+ }
+}
+
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.allTabs-endimage[soundplaying],
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.allTabs-endimage[muted],
+.tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.allTabs-endimage[blocked],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[soundplaying],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[blocked],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[muted] {
+ filter: invert(1);
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover),
+.tab-icon-overlay[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
+/* Tab icon overlay */
+.tab-icon-overlay {
+ width: 16px;
+ height: 16px;
+ margin-top: -8px;
+ margin-inline-start: -15px;
+ margin-inline-end: -1px;
+ position: relative;
+}
+
+.tab-icon-overlay[soundplaying],
+.tab-icon-overlay[muted]:not([crashed]),
+.tab-icon-overlay[blocked]:not([crashed]) {
+ border-radius: 10px;
+}
+
+.tab-icon-overlay[soundplaying]:hover,
+.tab-icon-overlay[muted]:not([crashed]):hover,
+.tab-icon-overlay[blocked]:not([crashed]):hover {
+ background-color: white;
+}
+
+.tab-icon-overlay[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio");
+}
+
+.tab-icon-overlay[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-muted");
+}
+
+.tab-icon-overlay[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[soundplaying]:not([selected]):not(:hover),
+.tab-icon-overlay[soundplaying][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[muted]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[muted][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-muted");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[blocked]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[blocked][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-blocked");
+}
+
+/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up,
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
+ margin: 0;
+ padding-right: 2px;
+ border-right: 2px solid transparent;
+ background-origin: border-box;
+}
+
+toolbar[brighttext] .tabbrowser-arrowscrollbox > .scrollbutton-up,
+toolbar[brighttext] .tabbrowser-arrowscrollbox > .scrollbutton-down {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.png);
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
+.tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
+ opacity: .4;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
+ transform: scaleX(-1);
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ transition: 1s background-color ease-out;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
+ background-color: Highlight;
+ transition: none;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]) {
+ border-width: 0 2px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/tabbrowser/tab-overflow-border.png") 0 2 0 2 fill;
+}
+
+.tabs-newtab-button > .toolbarbutton-icon {
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+.tabs-newtab-button,
+#TabsToolbar > #new-tab-button,
+#TabsToolbar > toolbarpaletteitem > #new-tab-button {
+ list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
+ -moz-image-region: auto;
+}
+
+.tabs-newtab-button:-moz-lwtheme-brighttext,
+toolbar[brighttext] #TabsToolbar > #new-tab-button,
+toolbar[brighttext] #TabsToolbar > toolbarpaletteitem > #new-tab-button {
+ list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
+}
+
+.tabs-newtab-button {
+ width: 28px;
+}
+
+#TabsToolbar > #new-tab-button {
+ width: 26px;
+}
+
+#alltabs-button {
+ list-style-image: url("chrome://browser/skin/tabbrowser/alltabs.png");
+ -moz-image-region: rect(0, 14px, 16px, 0);
+}
+
+#alltabs-button[type="menu"] {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
+ -moz-image-region: auto;
+}
+
+toolbar[brighttext] #alltabs-button {
+ list-style-image: url("chrome://browser/skin/tabbrowser/alltabs-inverted.png");
+}
+
+toolbar[brighttext] #alltabs-button[type="menu"] {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-icon {
+ margin: 0 2px;
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+/* All tabs menupopup */
+.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.alltabs-item[selected="true"] {
+ font-weight: bold;
+}
+
+.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.alltabs-item[tabIsVisible] {
+ /* box-shadow instead of background-color to work around native styling */
+ box-shadow: inset -5px 0 ThreeDShadow;
+}
+
+/* Tabstrip close button */
+.tabs-closebutton {
+ -moz-appearance: none;
+ padding: 4px 2px;
+ margin: 0px;
+ border: none;
+}
+
+toolbar[brighttext] .tabs-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.png");
+}
+
+@media (min-resolution: 2dppx) {
+ toolbar[brighttext] .tabs-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
+ }
+}
+
+.tabs-closebutton > .toolbarbutton-icon {
+ -moz-margin-end: 0px !important;
+ -moz-padding-end: 2px !important;
+ -moz-padding-start: 2px !important;
+}
+
+#sidebar-throbber[loading="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+ -moz-margin-end: 4px;
+}
+
+/* Pale Moon: Feed icon */
+#ub-feed-button,
+#ub-feed-button > .button-box,
+#ub-feed-button:hover:active > .button-box {
+ padding: 0px;
+ margin: 0px;
+ border: 0px;
+ background-color: transparent !important;
+}
+
+#ub-feed-button {
+ -moz-appearance: none;
+ min-width: 0px;
+ list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+#ub-feed-button:hover {
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#ub-feed-button[open="true"],
+#ub-feed-button:hover:active {
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+
+/* Bookmarks toolbar */
+#PlacesToolbarDropIndicator {
+ list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
+}
+
+toolbarbutton.bookmark-item[dragover="true"][open="true"] {
+ -moz-appearance: none;
+ background: Highlight !important;
+ color: HighlightText !important;
+}
+
+/* rules for menupopup drop indicators */
+.menupopup-drop-indicator-bar {
+ position: relative;
+ /* these two margins must together compensate the indicator's height */
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+.menupopup-drop-indicator {
+ list-style-image: none;
+ height: 2px;
+ -moz-margin-end: -4em;
+ background-color: Highlight;
+}
+
+/* ::::: Identity Indicator Styling ::::: */
+
+/* Popup Icons */
+#identity-popup-icon {
+ height: 64px;
+ width: 64px;
+ padding: 0;
+ list-style-image: url("chrome://browser/skin/identity.png");
+ -moz-image-region: rect(0px, 64px, 64px, 0px);
+}
+
+#identity-popup.verifiedDomain > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(64px, 64px, 128px, 0px);
+}
+
+#identity-popup.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(128px, 64px, 192px, 0px);
+}
+
+/* Popup Body Text */
+.identity-popup-description {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 2px 0 4px;
+}
+
+.identity-popup-label {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 0;
+}
+
+#identity-popup-content-host,
+#identity-popup-content-box.verifiedIdentity > #identity-popup-content-owner {
+ font-size: 1.2em;
+}
+
+#identity-popup-content-host {
+ margin-top: 3px;
+ margin-bottom: 5px;
+ font-weight: bold;
+ max-width: 300px;
+}
+
+#identity-popup-content-owner {
+ margin-top: 4px;
+ margin-bottom: 0 !important;
+ font-weight: bold;
+ max-width: 300px;
+}
+
+.verifiedDomain > #identity-popup-content-owner {
+ font-weight: normal;
+}
+
+#identity-popup-content-verifier {
+ margin: 4px 0 2px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption {
+ margin-top: 10px;
+ -moz-margin-start: -24px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption > vbox > #identity-popup-encryption-icon ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon {
+ list-style-image: url("chrome://browser/skin/Secure24.png");
+}
+
+#identity-popup-more-info-button {
+ margin-top: 6px;
+ margin-bottom: 0;
+ -moz-margin-end: 0;
+}
+
+.popup-notification-icon {
+ width: 64px;
+ height: 64px;
+ -moz-margin-end: 10px;
+}
+
+.popup-notification-icon[popupid="geolocation"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+
+.popup-notification-icon[popupid="xpinstall-disabled"],
+.popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-origin-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
+ width: 32px;
+ height: 32px;
+}
+
+.popup-notification-icon[popupid="click-to-play-plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
+}
+
+.popup-notification-icon[popupid="web-notifications"] {
+ list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+
+.addon-progress-description {
+ width: 350px;
+ max-width: 350px;
+}
+
+.popup-progress-label,
+.popup-progress-meter {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+.popup-progress-cancel {
+ -moz-appearance: none;
+ background: transparent;
+ border: none;
+ padding: 0;
+ min-height: 16px;
+ min-width: 16px;
+ max-height: 16px;
+ max-width: 16px;
+ margin: 0 1px 0 1px;
+ list-style-image: url(chrome://mozapps/skin/downloads/buttons.png);
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.popup-progress-cancel:hover {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.popup-progress-cancel:active {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+
+.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+.popup-notification-icon[popupid="indexedDB-quota-prompt"],
+.popup-notification-icon[popupid*="offline-app-requested"],
+.popup-notification-icon[popupid="offline-app-usage"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+
+.popup-notification-icon[popupid="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+
+.popup-notification-icon[popupid="mixed-content-blocked"] {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+}
+
+%ifdef MOZ_WEBRTC
+.popup-notification-icon[popupid="webRTC-sharingDevices"],
+.popup-notification-icon[popupid="webRTC-shareDevices"] {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
+}
+
+%endif
+.popup-notification-icon[popupid="pointerLock"] {
+ list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+
+/* Notification icon box */
+#notification-popup-box {
+ position: relative;
+ background-color: #fff;
+ background-clip: padding-box;
+ padding-left: 3px;
+ border-radius: 2.5px 0 0 2.5px;
+ border-width: 0 8px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
+ -moz-margin-end: -8px;
+}
+
+@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar > #notification-popup-box {
+ padding-left: 5px;
+}
+
+#notification-popup-box:-moz-locale-dir(rtl),
+.notification-anchor-icon:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+.notification-anchor-icon {
+ width: 16px;
+ height: 16px;
+ margin: 0 2px;
+}
+
+.notification-anchor-icon:-moz-focusring {
+ outline: 1px dotted -moz-DialogText;
+ outline-offset: -3px;
+}
+
+.default-notification-icon,
+#default-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/information-16.png);
+}
+
+.geo-notification-icon,
+#geo-notification-icon {
+ list-style-image: url(chrome://browser/skin/Geolocation-16.png);
+}
+
+#addons-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
+}
+
+.indexedDB-notification-icon,
+#indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+}
+
+#password-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
+}
+
+#plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
+}
+
+#alert-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
+}
+
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
+}
+
+#plugins-notification-icon,
+#alert-plugins-notification-icon,
+#blocked-plugins-notification-icon {
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+#plugins-notification-icon:hover,
+#alert-plugins-notification-icon:hover,
+#blocked-plugins-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#plugins-notification-icon:active,
+#alert-plugins-notification-icon:active,
+#blocked-plugins-notification-icon:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#notification-popup-box[hidden] {
+ /* Override display:none to make the pluginBlockedNotification animation work
+ when showing the notification repeatedly. */
+ display: -moz-box;
+ visibility: collapse;
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+.mixed-content-blocked-notification-icon,
+#mixed-content-blocked-notification-icon {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+}
+
+%ifdef MOZ_WEBRTC
+.webRTC-shareDevices-notification-icon,
+#webRTC-shareDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
+}
+
+.webRTC-sharingDevices-notification-icon,
+#webRTC-sharingDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
+}
+%endif
+
+.web-notifications-notification-icon,
+#web-notifications-notification-icon {
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#pointerLock-notification-icon {
+ list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+#pointerLock-cancel {
+ margin: 0px;
+}
+
+#identity-popup-container {
+ min-width: 280px;
+}
+
+/* Bookmarks roots menu-items */
+#appmenu_subscribeToPage:not([disabled]),
+#appmenu_subscribeToPageMenu,
+#subscribeToPageMenuitem:not([disabled]),
+#subscribeToPageMenupopup,
+#BMB_subscribeToPageMenuitem:not([disabled]),
+#BMB_subscribeToPageMenupopup {
+ list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+}
+
+#appmenu_bookmarksToolbar,
+#bookmarksToolbarFolderMenu,
+#BMB_bookmarksToolbar {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+ -moz-image-region: auto;
+}
+
+@media (min-resolution: 2dppx) {
+ #bookmarksToolbarFolderMenu,
+ #BMB_bookmarksToolbar {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar@2x.png");
+ -moz-image-region: auto;
+ }
+}
+
+#appmenu_unsortedBookmarks,
+#BMB_unsortedBookmarks {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+ -moz-image-region: auto;
+}
+
+/* ::::: Keyboard UI Panel ::::: */
+
+.KUI-panel {
+ -moz-appearance: none;
+ background: rgba(27%,27%,27%,.9) url(KUI-background.png) repeat-x;
+ color: white;
+ border-style: none;
+ border-radius: 20px;
+}
+
+.KUI-panel[level="top"] {
+ background-color: rgba(27%,27%,27%,.65);
+}
+
+.KUI-panel-closebutton {
+ list-style-image: url(KUI-close.png);
+ -moz-appearance: none;
+ border: none;
+ padding: 0;
+ width: 24px;
+ height: 24px;
+}
+
+.KUI-panel-closebutton:not(:hover) {
+ opacity: .6;
+}
+
+.KUI-panel-closebutton > .toolbarbutton-icon {
+ margin: 0;
+}
+
+/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
+
+/* Ctrl-Tab */
+
+#ctrlTab-panel {
+ padding: 20px 10px 10px;
+ font-weight: bold;
+ text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 2px rgb(27%,27%,27%);
+}
+
+.ctrlTab-favicon[src] {
+ background-color: white;
+ width: 20px;
+ height: 20px;
+ padding: 2px;
+}
+
+.ctrlTab-preview-inner > .tabPreview-canvas {
+ box-shadow: 1px 1px 2px rgb(12%,12%,12%);
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
+ margin-bottom: 2px;
+}
+
+.ctrlTab-preview-inner {
+ padding-bottom: 10px;
+}
+
+#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
+ padding: 10px;
+ background-color: rgba(255,255,255,.2);
+ border-radius: .5em;
+}
+
+.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
+ color: white;
+ background-color: rgba(0,0,0,.6);
+ text-shadow: none;
+ padding: 8px;
+ border: 2px solid white;
+ border-radius: .5em;
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
+ margin: -10px -10px 0;
+}
+
+#ctrlTab-showAll {
+ margin-top: .5em;
+}
+
+/* All Tabs */
+
+#allTabs-panel {
+ padding-bottom: 10px;
+ -moz-appearance: none;
+ border: none;
+ background: -moz-dialog;
+ color: -moz-dialogText;
+}
+
+#allTabs-meta {
+ margin: 10px;
+}
+
+#allTabs-filter {
+ -moz-margin-start: 24px;
+ -moz-margin-end: 0;
+}
+
+#allTabs-tab-close-button > .toolbarbutton-icon {
+ margin: 0;
+}
+
+/* Make sure the allTab previews always have regular close buttons */
+#allTabs-tab-close-button:-moz-lwtheme-brighttext {
+ list-style-image: url("chrome://global/skin/icons/close.png");
+}
+
+.allTabs-favicon[src] {
+ background-color: -moz-dialog;
+ width: 22px;
+ height: 22px;
+ padding-top: 1px;
+ padding-bottom: 5px;
+ -moz-padding-start: 1px;
+ -moz-padding-end: 5px;
+ margin-top: -2px;
+ -moz-margin-start: -2px;
+ border-bottom-right-radius: 4px;
+}
+
+.allTabs-favicon[src]:-moz-locale-dir(rtl) {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 4px;
+}
+
+.allTabs-preview-inner > .tabPreview-canvas {
+ background-color: rgb(60%,60%,60%);
+ box-shadow: 0 0 1.5px ThreeDShadow;
+}
+
+.allTabs-preview:not(:hover):not([closebuttonhover]) > html|canvas {
+ opacity: .8;
+}
+
+.allTabs-preview:focus > * > .allTabs-preview-inner {
+ outline: 1px dotted -moz-dialogText;
+}
+
+/* Add-on bar */
+
+#addon-bar {
+ -moz-appearance: none;
+ min-height: 20px;
+ border-top-style: none;
+ border-bottom-style: none;
+ padding-top: 1px;
+ background-image: linear-gradient(rgba(0,0,0,.15) 1px, rgba(255,255,255,.15) 1px);
+ background-size: 100% 2px;
+ background-repeat: no-repeat;
+}
+
+#status-bar {
+ -moz-appearance: none;
+ background-color: transparent;
+ border: none;
+ min-height: 0;
+}
+
+#addon-bar[customizing] > #status-bar {
+ opacity: .5;
+ background-image: repeating-linear-gradient(135deg,
+ rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
+ rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
+}
+
+#status-bar > statusbarpanel {
+ border-width: 0;
+ -moz-appearance: none;
+}
+
+#addonbar-closebutton {
+ border: none;
+ padding: 0 5px;
+ -moz-appearance: none;
+}
+
+toolbar[brighttext] #addonbar-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.png");
+}
+
+@media (min-resolution: 2dppx) {
+ toolbar[brighttext] #addonbar-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
+ }
+}
+
+/* Status panel */
+
+.statuspanel-label {
+ margin: 0;
+ padding: 2px 4px;
+ background: linear-gradient(#fff, #ddd);
+ border: 1px none #ccc;
+ border-top-style: solid;
+ color: #333;
+ text-shadow: none;
+}
+
+.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
+.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+ border-right-style: solid;
+ /* disabled for triggering grayscale AA (bug 659213)
+ border-top-right-radius: .3em;
+ */
+ margin-right: 1em;
+}
+
+.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
+.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+ border-left-style: solid;
+ /* disabled for triggering grayscale AA (bug 659213)
+ border-top-left-radius: .3em;
+ */
+ margin-left: 1em;
+}
+
+#full-screen-warning-message {
+ background-color: hsl(0,0%,15%);
+ color: white;
+ border-radius: 8px;
+ margin-top: 30px;
+ padding: 30px 50px;
+ box-shadow: 0 0 2px white;
+}
+
+.full-screen-description {
+ font-size: 150%;
+}
+
+#full-screen-domain-text {
+ font-size: 300%;
+}
+
+%ifdef MOZ_DEVTOOLS
+%include ../../../../devtools/client/themes/responsivedesign.inc.css
+%include ../../../../devtools/client/themes/commandline.inc.css
+%endif
+%include ../shared/plugin-doorhanger.inc.css
+
+%ifdef MOZ_DEVTOOLS
+/* Error counter */
+
+#developer-toolbar-toolbox-button[error-count]:before {
+ color: #FDF3DE;
+ min-width: 16px;
+ text-shadow: none;
+ background-image: linear-gradient(#B4211B, #8A1915);
+ border-radius: 1px;
+ -moz-margin-end: 5px;
+}
+%endif
+
+.toolbarbutton-badge-stack {
+ margin: 0;
+ padding: 0;
+ position: relative;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-badge-stack {
+ padding: 2px 5px;
+}
+
+.toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbar-icon {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+}
+
+.toolbarbutton-badge-stack > .toolbarbutton-icon[label]:not([label=""]) {
+ -moz-margin-end: 0;
+}
+
+@navbarLargeIcons@ *|* > .toolbarbutton-badge[badge]:not([badge=""])::after {
+ top: 1px;
+ right: 1px;
+}
+
+.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+ left: 0;
+ right: auto;
+}
+
+@navbarLargeIcons@ *|* > .toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+ left: 1px;
+ right: auto;
+}
+
+#main-window[privatebrowsingmode=temporary] {
+ background-image: url("chrome://browser/skin/privatebrowsing-mask.png");
+ background-position: top right;
+ background-repeat: no-repeat;
+ background-color: moz-mac-chrome-active;
+}
+
+@media (min-resolution: 2dppx) {
+ #main-window[privatebrowsingmode=temporary] {
+ background-image: url("chrome://browser/skin/privatebrowsing-mask@2x.png");
+ background-size: 38px;
+ }
+}
+
+#main-window[privatebrowsingmode=temporary] {
+ background-position: top right 40px;
+}
+
+#main-window[privatebrowsingmode=temporary][inFullscreen] {
+ background-position: top right 10px;
+}
+
+#main-window[privatebrowsingmode=temporary]:-moz-locale-dir(rtl) {
+ background-position: top left 70px;
+}
+
+#main-window[privatebrowsingmode=temporary][inFullscreen]:-moz-locale-dir(rtl) {
+ background-position: top left 10px;
+}
+
+#main-window[privatebrowsingmode=temporary]:-moz-window-inactive {
+ background-color: -moz-mac-chrome-inactive;
+}
+
+#main-window[privatebrowsingmode=temporary][inFullscreen] #nav-bar[tabsontop=false] {
+ -moz-padding-end: 50px !important;
+}
+
+@media (-moz-mac-lion-theme) {
+ #main-window[privatebrowsingmode=temporary][inFullscreen] #TabsToolbar[tabsontop=true] {
+ -moz-padding-end: 50px;
+ }
+}
+
+@media not all and (-moz-mac-lion-theme) {
+ #main-window[privatebrowsingmode=temporary] {
+ background-position: top right 10px;
+ }
+
+ #main-window[privatebrowsingmode=temporary][inFullscreen][tabsontop=true] #window-controls {
+ -moz-padding-end: 50px;
+ }
+}
diff --git a/themes/osx/click-to-play-warning-stripes.png b/themes/osx/click-to-play-warning-stripes.png
new file mode 100644
index 0000000..29f15f7
Binary files /dev/null and b/themes/osx/click-to-play-warning-stripes.png differ
diff --git a/themes/osx/communicator/communicator.css b/themes/osx/communicator/communicator.css
new file mode 100644
index 0000000..0b57574
--- /dev/null
+++ b/themes/osx/communicator/communicator.css
@@ -0,0 +1,6 @@
+/* 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/. */
+
+@import url("chrome://global/skin/");
+
diff --git a/themes/osx/communicator/jar.mn b/themes/osx/communicator/jar.mn
new file mode 100644
index 0000000..612d133
--- /dev/null
+++ b/themes/osx/communicator/jar.mn
@@ -0,0 +1,7 @@
+# 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:
+% skin communicator classic/1.0 %skin/classic/communicator/
+ skin/classic/communicator/communicator.css
diff --git a/themes/osx/communicator/moz.build b/themes/osx/communicator/moz.build
new file mode 100644
index 0000000..c97072b
--- /dev/null
+++ b/themes/osx/communicator/moz.build
@@ -0,0 +1,7 @@
+# -*- 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']
\ No newline at end of file
diff --git a/themes/osx/downloads/allDownloadsViewOverlay.css b/themes/osx/downloads/allDownloadsViewOverlay.css
new file mode 100644
index 0000000..eb99f4c
--- /dev/null
+++ b/themes/osx/downloads/allDownloadsViewOverlay.css
@@ -0,0 +1,146 @@
+/* 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/. */
+
+#downloadsRichListBox {
+ /** The default listbox appearance comes with an unwanted margin. **/
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#downloadsRichListBox > richlistitem.download {
+ height: 6em;
+ padding: 5px 8px;
+}
+
+.downloadTypeIcon {
+ -moz-margin-end: 8px;
+ /* explicitly size the icon, so size doesn't vary on hidpi systems */
+ height: 32px;
+ width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+.downloadTarget {
+ margin-bottom: 3px;
+ cursor: inherit;
+}
+
+.downloadDetails {
+ opacity: 0.7;
+ font-size: 95%;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ background: transparent;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+
+richlistitem.download[selected] > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 80px, 16px, 64px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 96px, 16px, 80px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 112px, 16px, 96px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 128px, 16px, 112px);
+}
+
+richlistitem.download[selected] > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 80px, 32px, 64px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 96px, 32px, 80px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 112px, 32px, 96px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 128px, 32px, 112px);
+}
+
+richlistitem.download[selected] > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 80px, 48px, 64px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 96px, 48px, 80px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 112px, 48px, 96px);
+}
+
+richlistitem.download[selected]:hover > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 128px, 48px, 112px);
+}
+
diff --git a/themes/osx/downloads/buttons.png b/themes/osx/downloads/buttons.png
new file mode 100644
index 0000000..ca87b40
Binary files /dev/null and b/themes/osx/downloads/buttons.png differ
diff --git a/themes/osx/downloads/contentAreaDownloadsView.css b/themes/osx/downloads/contentAreaDownloadsView.css
new file mode 100644
index 0000000..ece99ea
--- /dev/null
+++ b/themes/osx/downloads/contentAreaDownloadsView.css
@@ -0,0 +1,22 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+.downloadButton {
+ box-shadow: none;
+}
+
+.downloadButton:not([disabled="true"]):hover:active,
+.downloadButton:not([disabled]):hover:active {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+}
+
+#downloadsListEmptyDescription {
+ margin: 1em;
+ text-align: center;
+ color: GrayText;
+}
diff --git a/themes/osx/downloads/download-glow.png b/themes/osx/downloads/download-glow.png
new file mode 100644
index 0000000..53182d7
Binary files /dev/null and b/themes/osx/downloads/download-glow.png differ
diff --git a/themes/osx/downloads/download-notification-finish.png b/themes/osx/downloads/download-notification-finish.png
new file mode 100644
index 0000000..5194f5d
Binary files /dev/null and b/themes/osx/downloads/download-notification-finish.png differ
diff --git a/themes/osx/downloads/download-notification-start.png b/themes/osx/downloads/download-notification-start.png
new file mode 100644
index 0000000..bd548b1
Binary files /dev/null and b/themes/osx/downloads/download-notification-start.png differ
diff --git a/themes/osx/downloads/download-summary.png b/themes/osx/downloads/download-summary.png
new file mode 100644
index 0000000..67003c7
Binary files /dev/null and b/themes/osx/downloads/download-summary.png differ
diff --git a/themes/osx/downloads/downloads.css b/themes/osx/downloads/downloads.css
new file mode 100644
index 0000000..267574e
--- /dev/null
+++ b/themes/osx/downloads/downloads.css
@@ -0,0 +1,394 @@
+/* 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/. */
+
+/*** Panel and outer controls ***/
+
+#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
+ padding: 0;
+}
+
+#downloadsListBox {
+ background-color: transparent;
+ padding: 4px;
+ color: inherit;
+}
+
+#downloadsPanel:not([hasdownloads]) > #downloadsListBox {
+ display: none;
+}
+
+#downloadsPanel[hasdownloads] > #emptyDownloads {
+ display: none;
+}
+
+#emptyDownloads {
+ padding: 10px 20px;
+ max-width: 40ch;
+}
+
+#downloadsHistory {
+ background: transparent;
+ color: -moz-nativehyperlinktext;
+ cursor: pointer;
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsHistory:focus {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -1px;
+}
+
+#downloadsHistory > .button-box {
+ border: none;
+ margin: 1em;
+}
+
+@media (-moz-mac-lion-theme) {
+ #downloadsFooter {
+ background-color: hsla(216,45%,88%,.98);
+ box-shadow: 0px 1px 2px rgb(204,214,234) inset;
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+}
+
+/*** Downloads Summary and List items ***/
+
+#downloadsSummary,
+richlistitem[type="download"] {
+ height: 7em;
+ -moz-padding-end: 0;
+ color: inherit;
+}
+
+#downloadsSummary {
+ padding: 8px 38px 8px 12px;
+ cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsSummary:focus {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
+}
+
+#downloadsSummary > .downloadTypeIcon {
+ list-style-image: url("chrome://browser/skin/downloads/download-summary.png");
+}
+
+#downloadsSummaryDescription {
+ color: -moz-nativehyperlinktext;
+}
+
+richlistitem[type="download"] {
+ margin: 0;
+ border-top: 1px solid hsla(0,0%,100%,.3);
+ border-bottom: 1px solid hsla(220,18%,51%,.25);
+ background: transparent;
+ padding: 8px;
+}
+
+richlistitem[type="download"]:first-child {
+ border-top: 1px solid transparent;
+}
+
+@media (-moz-mac-lion-theme) {
+ richlistitem[type="download"]:last-child {
+ border-bottom: 1px solid transparent;
+ }
+}
+
+#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -1px;
+}
+
+.downloadTypeIcon {
+ -moz-margin-end: 8px;
+ /* Prevent flickering when changing states. */
+ height: 32px;
+ width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+/* We hold .downloadDisplayName, .downloadProgress and .downloadDetails
+ inside of a vbox with class .downloadContainer. We set the font-size of
+ the entire container to 90% because:
+
+ 1) This is the size that we want .downloadDetails to be
+ 2) The container's width is set by localizers by &downloadDetails.width;,
+ which is a ch unit. Since this is the value that should control the
+ panel width, we apply it to the outer container to constrain
+ .downloadDisplayName and .downloadProgress.
+
+ Finally, since we want .downloadDisplayName's font-size to be at 100% of
+ the font-size of .downloadContainer's parent, we use calc to go from the
+ smaller font-size back to the original font-size.
+ */
+#downloadsSummaryDetails,
+.downloadContainer {
+ font-size: 90%;
+}
+
+#downloadsSummaryDescription,
+.downloadDisplayName {
+ margin-bottom: 6px;
+ cursor: inherit;
+}
+
+.downloadDisplayName {
+ font-size: calc(100%/0.9);
+}
+
+#downloadsSummaryDetails,
+.downloadDetails {
+ opacity: 0.6;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ background: transparent;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+.downloadButton > .button-box {
+ border: 1px solid transparent;
+ padding: 0;
+}
+
+#downloadsPanel[keyfocus] .downloadButton:focus > .button-box {
+ border: 1px dotted ThreeDDarkShadow;
+}
+
+/*** Highlighted list items ***/
+
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
+ border-radius: 3px;
+ border-top: 1px solid hsla(0,0%,100%,.2);
+ border-bottom: 1px solid hsla(0,0%,0%,.2);
+ background-color: Highlight;
+ color: HighlightText;
+ cursor: pointer;
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+#downloadsPanel[keyfocus] > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 96px, 32px, 80px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 112px, 32px, 96px);
+}
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 128px, 32px, 112px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+
+/*** Status and progress indicator ***/
+
+#downloads-indicator-anchor {
+ /* Makes the outermost stack element positioned, so that its contents are
+ rendered over the main browser window in the Z order. This is required by
+ the animated event notification. */
+ position: relative;
+}
+
+/*** Main indicator icon ***/
+
+#downloads-indicator-icon {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
+ 0, 108, 18, 90) center no-repeat;
+ min-width: 18px;
+ min-height: 18px;
+}
+
+toolbar[brighttext] #downloads-indicator-icon {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
+ 0, 108, 18, 90) center no-repeat;
+}
+
+#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+/* In the next few rules, we use :not([counter]) as a shortcut that is
+ equivalent to -moz-any([progress], [paused]). */
+
+#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
+ 0, 108, 18, 90) center no-repeat;
+ background-size: 12px;
+}
+
+toolbar[brighttext] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
+ 0, 108, 18, 90) center no-repeat;
+}
+
+#downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+/*** Download notifications ***/
+
+#downloads-indicator-notification {
+ opacity: 0;
+ background-size: 16px;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+@keyframes downloadsIndicatorNotificationStartRight {
+ from { opacity: 0; transform: translate(-128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+@keyframes downloadsIndicatorNotificationStartLeft {
+ from { opacity: 0; transform: translate(128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+#downloads-indicator[notification="start"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-start.png");
+ animation-name: downloadsIndicatorNotificationStartRight;
+ animation-duration: 1s;
+}
+
+#downloads-indicator[notification="start"]:-moz-locale-dir(rtl) > #downloads-indicator-anchor > #downloads-indicator-notification {
+ animation-name: downloadsIndicatorNotificationStartLeft;
+}
+
+@keyframes downloadsIndicatorNotificationFinish {
+ from { opacity: 0; transform: scale(1); }
+ 20% { opacity: .65; animation-timing-function: ease-in; }
+ to { opacity: 0; transform: scale(8); }
+}
+
+#downloads-indicator[notification="finish"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-finish.png");
+ animation-name: downloadsIndicatorNotificationFinish;
+ animation-duration: 1s;
+}
+
+/*** Progress bar and text ***/
+
+#downloads-indicator-counter {
+ height: 9px;
+ margin: -3px 0px 0px 0px;
+ color: hsl(0,0%,30%);
+ text-shadow: hsla(0,0%,100%,.5) 0 1px;
+ font-size: 9px;
+ line-height: 9px;
+ text-align: center;
+}
+
+toolbar[brighttext] #downloads-indicator-counter {
+ color: white;
+ text-shadow: 0 0 1px rgba(0,0,0,.7),
+ 0 1px 1.5px rgba(0,0,0,.5);
+}
+
+#downloads-indicator-progress {
+ width: 16px;
+ height: 5px;
+ min-width: 0;
+ min-height: 0;
+ margin-top: 1px;
+ margin-bottom: 2px;
+ border-radius: 2px;
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.4);
+}
+
+#downloads-indicator-progress > .progress-bar {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ /* The background-clip: border-box; and background-image: none; are there to expand the background-color behind the border */
+ background-clip: padding-box, border-box;
+ background-color: rgb(90, 201, 66);
+ background-image: linear-gradient(transparent 1px, rgba(255, 255, 255, 0.4) 1px, rgba(255, 255, 255, 0.4) 2px, transparent 2px), none;
+ border: 1px solid;
+ border-color: rgba(0,43,86,.6) rgba(0,43,86,.4) rgba(0,43,86,.4);
+ border-radius: 2px 0 0 2px;
+}
+
+#downloads-indicator-progress > .progress-remainder {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ background-image: linear-gradient(#505050, #575757);
+ border: 1px solid;
+ border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
+ -moz-border-start: none;
+ border-radius: 0 2px 2px 0;
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-bar {
+ background-color: rgb(220, 230, 81);
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
+ background-image: linear-gradient(#4b5000, #515700);
+}
+
+toolbar[mode="full"] > #downloads-indicator > .toolbarbutton-text {
+ margin: 0;
+ text-align: center;
+}
diff --git a/themes/osx/engineManager.css b/themes/osx/engineManager.css
new file mode 100644
index 0000000..18817cd
--- /dev/null
+++ b/themes/osx/engineManager.css
@@ -0,0 +1,16 @@
+%if 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/. */
+%endif
+
+#engineList treechildren::-moz-tree-image(engineName) {
+ -moz-margin-end: 4px;
+ -moz-margin-start: 1px;
+ width: 16px;
+ height: 16px;
+}
+
+#engineList treechildren::-moz-tree-row {
+ height: 20px;
+}
diff --git a/themes/osx/feeds/feed-icons-16.png b/themes/osx/feeds/feed-icons-16.png
new file mode 100644
index 0000000..bcca086
Binary files /dev/null and b/themes/osx/feeds/feed-icons-16.png differ
diff --git a/themes/osx/feeds/feedIcon.png b/themes/osx/feeds/feedIcon.png
new file mode 100644
index 0000000..e69bc44
Binary files /dev/null and b/themes/osx/feeds/feedIcon.png differ
diff --git a/themes/osx/feeds/feedIcon16.png b/themes/osx/feeds/feedIcon16.png
new file mode 100644
index 0000000..d778807
Binary files /dev/null and b/themes/osx/feeds/feedIcon16.png differ
diff --git a/themes/osx/feeds/subscribe-ui.css b/themes/osx/feeds/subscribe-ui.css
new file mode 100644
index 0000000..8ca5328
--- /dev/null
+++ b/themes/osx/feeds/subscribe-ui.css
@@ -0,0 +1,29 @@
+/* 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/. */
+
+.alwaysUse {
+ padding: 5px;
+}
+
+.handlersMenuPopup > menuitem {
+ -moz-padding-start: 23px;
+}
+
+.handlersMenuPopup > menuitem.menuitem-iconic {
+ -moz-padding-start: 2px;
+}
+
+.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
+ display: -moz-box;
+ min-width: 16px;
+ -moz-padding-end: 2px;
+}
+
+.chooseApplicationMenuItem {
+ list-style-image: url("chrome://browser/skin/preferences/application.png");
+}
+
+#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
+ direction: rtl;
+}
diff --git a/themes/osx/feeds/subscribe.css b/themes/osx/feeds/subscribe.css
new file mode 100644
index 0000000..780a7f8
--- /dev/null
+++ b/themes/osx/feeds/subscribe.css
@@ -0,0 +1,159 @@
+/* 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/. */
+
+html {
+ background: -moz-Dialog;
+ font: 3mm tahoma,arial,helvetica,sans-serif;
+}
+
+#feedBody {
+ border: 1px solid THreeDShadow;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ margin: 2em auto;
+ background: -moz-Field;
+}
+
+#feedHeaderContainer {
+ border: 1px solid ThreeDShadow;
+ border-radius: 10px;
+ margin: -4em auto 0 auto;
+ background-color: InfoBackground;
+}
+
+#feedHeader {
+ margin-top: 4.9em;
+ margin-bottom: 1em;
+ -moz-margin-start: 1.4em;
+ -moz-margin-end: 1em;
+ -moz-padding-start: 2.9em;
+ font-size: 110%;
+ color: InfoText;
+}
+
+#feedIntroText {
+ display: none;
+}
+
+.feedBackground {
+ background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.videoPodcastBackground {
+ background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.audioPodcastBackground {
+ background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+#feedHeader[dir="rtl"] {
+ background-position: 100% 10%;
+}
+
+#feedHeader[firstrun="true"] #feedIntroText {
+ padding-top: 0.1em;
+ -moz-padding-start: 0.6em;
+ display: block;
+}
+
+#feedHeader[firstrun="true"] > #feedSubscribeLine {
+ -moz-padding-start: 1.8em;
+}
+
+#feedSubscribeLine {
+ padding-top: 0.2em;
+}
+
+/* Don't print subscription UI */
+@media print {
+ #feedHeaderContainer {
+ display: none;
+ }
+}
+
+body {
+ margin: 0;
+ padding: 0 3em;
+ color: -moz-fieldText;
+ font: message-box;
+}
+
+h1 {
+ font-size: 160%;
+ border-bottom: 2px solid ThreeDLightShadow;
+ margin: 0 0 .2em 0;
+}
+
+h2 {
+ color: ThreeDDarkShadow;
+ font-size: 110%;
+ font-weight: normal;
+ margin: 0 0 .6em 0;
+}
+
+#feedTitleLink {
+ float: right;
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+a[href] img {
+ border: none;
+}
+
+#feedTitleContainer {
+ -moz-margin-start: 0;
+ -moz-margin-end: .6em;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#feedTitleImage {
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ max-width: 300px;
+ max-height: 150px;
+}
+
+.feedEntryContent {
+ font-size: 110%;
+}
+
+.link {
+ color: #0000FF;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.link:hover:active {
+ color: #FF0000;
+}
+
+.lastUpdated {
+ font-size: 85%;
+ font-weight: normal;
+}
+
+.type-icon {
+ vertical-align: bottom;
+ height: 16px;
+ width: 16px;
+}
+
+.enclosures {
+ border: 1px solid THreeDShadow;
+ padding: 1em;
+ margin: 1em auto;
+ background: -moz-Dialog;
+}
+
+.enclosure {
+ vertical-align: middle;
+ margin-left: 2px;
+}
diff --git a/themes/osx/icon.png b/themes/osx/icon.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/osx/icon.png differ
diff --git a/themes/osx/identity-icons-generic.png b/themes/osx/identity-icons-generic.png
new file mode 100644
index 0000000..a39e493
Binary files /dev/null and b/themes/osx/identity-icons-generic.png differ
diff --git a/themes/osx/identity-icons-https-ev.png b/themes/osx/identity-icons-https-ev.png
new file mode 100644
index 0000000..d49be13
Binary files /dev/null and b/themes/osx/identity-icons-https-ev.png differ
diff --git a/themes/osx/identity-icons-https-mixed-active.png b/themes/osx/identity-icons-https-mixed-active.png
new file mode 100644
index 0000000..3c77bc8
Binary files /dev/null and b/themes/osx/identity-icons-https-mixed-active.png differ
diff --git a/themes/osx/identity-icons-https.png b/themes/osx/identity-icons-https.png
new file mode 100644
index 0000000..ffd6694
Binary files /dev/null and b/themes/osx/identity-icons-https.png differ
diff --git a/themes/osx/identity.png b/themes/osx/identity.png
new file mode 100644
index 0000000..60d5261
Binary files /dev/null and b/themes/osx/identity.png differ
diff --git a/themes/osx/imagedocument.png b/themes/osx/imagedocument.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/osx/imagedocument.png differ
diff --git a/themes/osx/jar.mn b/themes/osx/jar.mn
new file mode 100644
index 0000000..67339c7
--- /dev/null
+++ b/themes/osx/jar.mn
@@ -0,0 +1,181 @@
+# 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:
+% skin browser classic/1.0 %skin/classic/browser/
+ skin/classic/browser/sanitizeDialog.css
+* skin/classic/browser/aboutPrivateBrowsing.css
+* skin/classic/browser/aboutSessionRestore.css
+ skin/classic/browser/aboutSessionRestore-window-icon.png (preferences/application.png)
+ skin/classic/browser/aboutCertError.css
+ skin/classic/browser/aboutCertError_sectionCollapsed.png
+ skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
+ skin/classic/browser/aboutCertError_sectionExpanded.png
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/aboutSyncTabs.css
+#endif
+* skin/classic/browser/autocomplete.css
+ skin/classic/browser/actionicon-tab.png
+ skin/classic/browser/appmenu-icons.png
+ skin/classic/browser/appmenu-dropmarker.png
+* skin/classic/browser/browser.css
+ skin/classic/browser/click-to-play-warning-stripes.png
+* skin/classic/browser/engineManager.css
+ skin/classic/browser/Geolocation-16.png
+ skin/classic/browser/Geolocation-64.png
+ skin/classic/browser/Info.png
+ skin/classic/browser/identity.png
+ skin/classic/browser/imagedocument.png
+ skin/classic/browser/identity-icons-generic.png
+ skin/classic/browser/identity-icons-https.png
+ skin/classic/browser/identity-icons-https-ev.png
+ skin/classic/browser/identity-icons-https-mixed-active.png
+ skin/classic/browser/keyhole-forward-mask.svg
+ skin/classic/browser/KUI-background.png
+ skin/classic/browser/KUI-close.png
+ skin/classic/browser/livemark-folder.png
+ skin/classic/browser/menu-back.png
+ skin/classic/browser/menu-forward.png
+ skin/classic/browser/mixed-content-blocked-16.png
+ skin/classic/browser/mixed-content-blocked-64.png
+ skin/classic/browser/monitor.png
+ skin/classic/browser/monitor_16-10.png
+ skin/classic/browser/panel-expander-closed.png
+ skin/classic/browser/panel-expander-closed@2x.png
+ skin/classic/browser/panel-expander-open.png
+ skin/classic/browser/panel-expander-open@2x.png
+ skin/classic/browser/panel-plus-sign.png
+ skin/classic/browser/pageInfo.css
+ skin/classic/browser/pageInfo.png
+ skin/classic/browser/page-livemarks.png
+ skin/classic/browser/page-livemarks@2x.png
+ skin/classic/browser/pointerLock-16.png
+ skin/classic/browser/pointerLock-64.png
+ skin/classic/browser/Privacy-16.png
+ skin/classic/browser/Privacy-32.png
+ skin/classic/browser/Privacy-48.png
+ skin/classic/browser/privatebrowsing-mask.png
+ skin/classic/browser/privatebrowsing-mask@2x.png
+ skin/classic/browser/privatebrowsing-light.png
+ skin/classic/browser/privatebrowsing-dark.png
+ skin/classic/browser/reload-stop-go.png
+ skin/classic/browser/Search-glass.png
+ skin/classic/browser/searchbar.css
+ skin/classic/browser/searchbar-dropdown-arrow.png
+ skin/classic/browser/Secure24.png
+ skin/classic/browser/setDesktopBackground.css
+ skin/classic/browser/slowStartup-16.png
+ skin/classic/browser/Toolbar.png
+ skin/classic/browser/Toolbar-inverted.png
+ skin/classic/browser/toolbarbutton-dropdown-arrow.png
+ skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
+ skin/classic/browser/urlbar-arrow.png
+ skin/classic/browser/urlbar-popup-blocked.png
+ skin/classic/browser/urlbar-history-dropmarker.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
+ skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
+ skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
+ skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
+#ifdef MOZ_WEBRTC
+ skin/classic/browser/webRTC-shareDevice-16.png
+ skin/classic/browser/webRTC-shareDevice-64.png
+ skin/classic/browser/webRTC-sharingDevice-16.png
+#endif
+ skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
+ skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png)
+ skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png)
+ skin/classic/browser/downloads/download-notification-start.png (downloads/download-notification-start.png)
+ skin/classic/browser/downloads/download-summary.png (downloads/download-summary.png)
+* skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
+* skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
+ skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
+ skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/feed-icons-16.png (feeds/feed-icons-16.png)
+ skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/videoFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
+ skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
+* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
+ skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
+ skin/classic/browser/newtab/noise.png (../shared/newtab/noise.png)
+ skin/classic/browser/newtab/pinned.png (../shared/newtab/pinned.png)
+ skin/classic/browser/places/places.css (places/places.css)
+* skin/classic/browser/places/organizer.css (places/organizer.css)
+ skin/classic/browser/places/editBookmark.png (places/editBookmark.png)
+ skin/classic/browser/places/bookmark.png (places/bookmark.png)
+ skin/classic/browser/places/query.png (places/query.png)
+ skin/classic/browser/places/query@2x.png (places/query@2x.png)
+ skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
+ skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
+ skin/classic/browser/places/bookmarksToolbar@2x.png (places/bookmarksToolbar@2x.png)
+ skin/classic/browser/places/calendar.png (places/calendar.png)
+ skin/classic/browser/places/folderDropArrow.png (places/folderDropArrow.png)
+ skin/classic/browser/places/folderDropArrow@2x.png (places/folderDropArrow@2x.png)
+ skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
+ skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
+ skin/classic/browser/places/libraryToolbar.png (places/libraryToolbar.png)
+ skin/classic/browser/places/starred48.png (places/starred48.png)
+ skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
+ skin/classic/browser/places/unfiledBookmarks.png (places/unfiledBookmarks.png)
+ skin/classic/browser/places/unfiledBookmarks@2x.png (places/unfiledBookmarks@2x.png)
+ skin/classic/browser/places/tag.png (places/tag.png)
+ skin/classic/browser/places/tag@2x.png (places/tag@2x.png)
+ skin/classic/browser/places/history.png (places/history.png)
+ skin/classic/browser/places/history@2x.png (places/history@2x.png)
+ skin/classic/browser/places/allBookmarks.png (places/allBookmarks.png)
+ skin/classic/browser/places/unsortedBookmarks.png (places/unsortedBookmarks.png)
+ skin/classic/browser/places/downloads.png (places/downloads.png)
+ skin/classic/browser/places/expander-closed-active.png (places/expander-closed-active.png)
+ skin/classic/browser/places/expander-open-active.png (places/expander-open-active.png)
+ skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
+ skin/classic/browser/places/expander-closed.png (places/expander-closed.png)
+ skin/classic/browser/places/expander-open.png (places/expander-open.png)
+ skin/classic/browser/permissions/aboutPermissions.css (permissions/aboutPermissions.css)
+ skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
+ skin/classic/browser/preferences/application.png (preferences/application.png)
+ skin/classic/browser/preferences/mail.png (preferences/mail.png)
+ skin/classic/browser/preferences/Options.png (preferences/Options.png)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
+#endif
+ skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png)
+* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
+ skin/classic/browser/preferences/applications.css (preferences/applications.css)
+ skin/classic/browser/statusbar/dynamic.css (../shared/statusbar/dynamic.css)
+* skin/classic/browser/statusbar/overlay.css (statusbar/overlay.css)
+* skin/classic/browser/statusbar/prefs.css (statusbar/prefs.css)
+ skin/classic/browser/statusbar/pulse.png (../shared/statusbar/pulse.png)
+ skin/classic/browser/statusbar/pms16.png (../shared/statusbar/pms16.png)
+ skin/classic/browser/statusbar/pms24.png (../shared/statusbar/pms24.png)
+ skin/classic/browser/statusbar/throbber-idle.png (../shared/statusbar/throbber-idle.png)
+ skin/classic/browser/statusbar/throbberStatic.png (../shared/statusbar/throbberStatic.png)
+ skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
+ skin/classic/browser/tabbrowser/alltabs-inverted.png (tabbrowser/alltabs-inverted.png)
+ skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
+ skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
+ skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
+ skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
+ skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
+ skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
+ skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
+ skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/sync-throbber.png
+ skin/classic/browser/sync-16.png
+ skin/classic/browser/sync-32.png
+ skin/classic/browser/sync-128.png
+ skin/classic/browser/sync-bg.png
+ skin/classic/browser/sync-desktopIcon.png
+ skin/classic/browser/sync-mobileIcon.png
+ skin/classic/browser/syncSetup.css
+ skin/classic/browser/syncCommon.css
+ skin/classic/browser/syncQuota.css
+ skin/classic/browser/syncProgress.css
+#endif
diff --git a/themes/osx/keyhole-forward-mask.svg b/themes/osx/keyhole-forward-mask.svg
new file mode 100644
index 0000000..8355447
--- /dev/null
+++ b/themes/osx/keyhole-forward-mask.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/osx/livemark-folder.png b/themes/osx/livemark-folder.png
new file mode 100644
index 0000000..38a4f10
Binary files /dev/null and b/themes/osx/livemark-folder.png differ
diff --git a/themes/osx/menu-back.png b/themes/osx/menu-back.png
new file mode 100644
index 0000000..ecb8ccd
Binary files /dev/null and b/themes/osx/menu-back.png differ
diff --git a/themes/osx/menu-forward.png b/themes/osx/menu-forward.png
new file mode 100644
index 0000000..2083492
Binary files /dev/null and b/themes/osx/menu-forward.png differ
diff --git a/themes/osx/mixed-content-blocked-16.png b/themes/osx/mixed-content-blocked-16.png
new file mode 100644
index 0000000..7cf33ec
Binary files /dev/null and b/themes/osx/mixed-content-blocked-16.png differ
diff --git a/themes/osx/mixed-content-blocked-64.png b/themes/osx/mixed-content-blocked-64.png
new file mode 100644
index 0000000..cac4415
Binary files /dev/null and b/themes/osx/mixed-content-blocked-64.png differ
diff --git a/themes/osx/monitor.png b/themes/osx/monitor.png
new file mode 100644
index 0000000..35e7b20
Binary files /dev/null and b/themes/osx/monitor.png differ
diff --git a/themes/osx/monitor_16-10.png b/themes/osx/monitor_16-10.png
new file mode 100644
index 0000000..4195034
Binary files /dev/null and b/themes/osx/monitor_16-10.png differ
diff --git a/themes/osx/moz.build b/themes/osx/moz.build
new file mode 100644
index 0000000..6a7af20
--- /dev/null
+++ b/themes/osx/moz.build
@@ -0,0 +1,9 @@
+# -*- 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/.
+
+DIRS += ['communicator']
+
+JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
diff --git a/themes/osx/newtab/newTab.css b/themes/osx/newtab/newTab.css
new file mode 100644
index 0000000..b8b0fd6
--- /dev/null
+++ b/themes/osx/newtab/newTab.css
@@ -0,0 +1,29 @@
+/* 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 ../../shared/newtab/newTab.css.inc
+
+.newtab-undo-button {
+ -moz-appearance: none;
+ color: -moz-nativehyperlinktext;
+ color: rgb(0,102,204);
+ cursor: pointer;
+ padding: 0;
+ margin: 0 4px;
+ border: 0;
+ background: transparent;
+ text-decoration: none;
+ min-width: 0;
+}
+
+.newtab-undo-button > .button-box {
+ padding: 0;
+}
+
+#newtab-undo-close-button {
+ -moz-appearance: none;
+ padding: 0;
+ border: none;
+ -moz-user-focus: normal;
+}
diff --git a/themes/osx/page-livemarks.png b/themes/osx/page-livemarks.png
new file mode 100644
index 0000000..e526458
Binary files /dev/null and b/themes/osx/page-livemarks.png differ
diff --git a/themes/osx/page-livemarks@2x.png b/themes/osx/page-livemarks@2x.png
new file mode 100644
index 0000000..7b17089
Binary files /dev/null and b/themes/osx/page-livemarks@2x.png differ
diff --git a/themes/osx/pageInfo.css b/themes/osx/pageInfo.css
new file mode 100644
index 0000000..f205b57
--- /dev/null
+++ b/themes/osx/pageInfo.css
@@ -0,0 +1,258 @@
+/* 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/. */
+
+@import "chrome://global/skin/";
+
+/* View buttons */
+#viewGroup {
+ -moz-padding-start: 10px;
+}
+
+#viewGroup > radio {
+ list-style-image: url("chrome://browser/skin/pageInfo.png");
+ -moz-box-orient: vertical;
+ -moz-box-align: center;
+ -moz-appearance: none;
+ padding: 5px 3px 1px 3px;
+ margin: 0 1px;
+ min-width: 4.5em;
+}
+
+#viewGroup > radio:hover {
+ background-color: #E0E8F6;
+ color: black;
+}
+
+#viewGroup > radio[selected="true"] {
+ background-color: #C1D2EE;
+ color: black;
+}
+
+#topBar {
+ border-bottom: 2px groove ThreeDFace;
+ -moz-padding-start: 10px;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+}
+
+#generalTab {
+ -moz-image-region: rect(0px, 32px, 32px, 0px)
+}
+
+#generalTab:hover, #generalTab[selected="true"] {
+ -moz-image-region: rect(32px, 32px, 64px, 0px)
+}
+
+#mediaTab {
+ -moz-image-region: rect(0px, 64px, 32px, 32px)
+}
+
+#mediaTab:hover, #mediaTab[selected="true"] {
+ -moz-image-region: rect(32px, 64px, 64px, 32px)
+}
+
+#feedTab {
+ -moz-image-region: rect(0px, 96px, 32px, 64px)
+}
+
+#feedTab:hover, #feedTab[selected="true"] {
+ -moz-image-region: rect(32px, 96px, 64px, 64px)
+}
+
+#permTab {
+ -moz-image-region: rect(0px, 128px, 32px, 96px)
+}
+
+#permTab:hover, #permTab[selected="true"] {
+ -moz-image-region: rect(32px, 128px, 64px, 96px)
+}
+
+#securityTab {
+ -moz-image-region: rect(0px, 160px, 32px, 128px)
+}
+
+#securityTab:hover, #securityTab[selected="true"] {
+ -moz-image-region: rect(32px, 160px, 64px, 128px)
+}
+
+deck {
+ padding: 10px 10px 10px 10px;
+}
+
+/* Misc */
+tree {
+ margin: .5em;
+}
+
+.gridSeparator {
+ width: .5em;
+}
+
+textbox {
+ background: transparent !important;
+ border: none;
+ padding: 0px;
+ margin-top: 1px;
+ -moz-appearance: none;
+}
+
+textbox.header {
+ -moz-margin-start: 0;
+}
+
+.iframe {
+ margin: .5em;
+ background: white;
+ overflow: auto;
+}
+
+.fixedsize {
+ height: 8.5em;
+}
+
+textbox[disabled] {
+ font-style: italic;
+}
+
+/* General Tab */
+groupbox.collapsable caption .caption-icon {
+ width: 9px;
+ height: 9px;
+ background-repeat: no-repeat;
+ background-position: center;
+ -moz-margin-start: 2px;
+ -moz-margin-end: 2px;
+ background-image: url("chrome://global/skin/tree/twisty-open.png");
+}
+
+groupbox.collapsable[closed="true"] {
+ border: none;
+ margin-bottom: 9px;
+ -moz-appearance: none;
+}
+
+groupbox.collapsable[closed="true"] caption .caption-icon {
+ background-image: url("chrome://global/skin/tree/twisty-clsd.png");
+}
+
+groupbox tree {
+ margin: 0 3px;
+ border: none;
+}
+
+#securityBox description {
+ -moz-margin-start: 10px;
+}
+
+#general-security-identity {
+ white-space: pre-wrap;
+ line-height: 2em;
+}
+
+/* Media Tab */
+#imagetree {
+ min-height: 10em;
+ margin-bottom: 0;
+}
+
+#mediaSplitter {
+ border-style: none;
+ background: none;
+ height: .8em;
+}
+
+#mediaGrid {
+ min-height: 9em;
+}
+
+#mediaLabelColumn {
+ min-width: 10em;
+}
+
+#thepreviewimage {
+ margin: 1em;
+}
+
+treechildren::-moz-tree-cell-text(broken) {
+ font-style: italic;
+ color: graytext;
+}
+
+/* Feeds Tab */
+#feedtree {
+ margin-bottom: 0px;
+}
+
+#feedListbox richlistitem {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+#feedListbox richlistitem[selected="true"] {
+ background-color: -moz-Dialog;
+ color: -moz-DialogText;
+}
+
+#feedListbox {
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+}
+
+.feedTitle {
+ font-weight: bold;
+}
+
+/* Permissions Tab */
+#permList {
+ margin-top: .5em;
+ overflow: auto;
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+ background-color: -moz-field;
+}
+
+.permission {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+.permissionLabel {
+ font-weight: bold;
+}
+
+.permission:hover {
+ background-color: -moz-dialog;
+}
+
+/* Security Tab */
+#securityPanel .caption-icon {
+ display: none;
+}
+
+#securityPanel .header {
+ font-size: 120%;
+}
+
+#securityPanel .fieldLabel {
+ margin: 2px 10px 3px 10px;
+}
+
+#securityPanel .fieldValue {
+ font-weight: bold;
+ margin: 2px 10px 0px 10px;
+}
diff --git a/themes/osx/pageInfo.png b/themes/osx/pageInfo.png
new file mode 100644
index 0000000..237381b
Binary files /dev/null and b/themes/osx/pageInfo.png differ
diff --git a/themes/osx/panel-expander-closed.png b/themes/osx/panel-expander-closed.png
new file mode 100644
index 0000000..f0e97b2
Binary files /dev/null and b/themes/osx/panel-expander-closed.png differ
diff --git a/themes/osx/panel-expander-closed@2x.png b/themes/osx/panel-expander-closed@2x.png
new file mode 100644
index 0000000..0e7ded5
Binary files /dev/null and b/themes/osx/panel-expander-closed@2x.png differ
diff --git a/themes/osx/panel-expander-open.png b/themes/osx/panel-expander-open.png
new file mode 100644
index 0000000..e3febf4
Binary files /dev/null and b/themes/osx/panel-expander-open.png differ
diff --git a/themes/osx/panel-expander-open@2x.png b/themes/osx/panel-expander-open@2x.png
new file mode 100644
index 0000000..3913370
Binary files /dev/null and b/themes/osx/panel-expander-open@2x.png differ
diff --git a/themes/osx/panel-plus-sign.png b/themes/osx/panel-plus-sign.png
new file mode 100644
index 0000000..375601e
Binary files /dev/null and b/themes/osx/panel-plus-sign.png differ
diff --git a/themes/osx/permissions/aboutPermissions.css b/themes/osx/permissions/aboutPermissions.css
new file mode 100644
index 0000000..f9a4a88
--- /dev/null
+++ b/themes/osx/permissions/aboutPermissions.css
@@ -0,0 +1,153 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+/* header */
+
+#permissions-pagetitle {
+ font-size: 200%;
+ font-weight: bold;
+ padding-bottom: 0.5em;
+}
+
+/* content box */
+#permissions-content {
+ height: 100%;
+}
+
+/* sites box */
+
+#sites-box {
+ padding: 10px;
+ width: 25em;
+}
+
+#sites-filter {
+ margin: 0;
+}
+
+#sites-list {
+ -moz-appearance: none;
+ border: 1px solid rgba(0, 0, 0, 0.32);
+ background-color: rgba(255, 255, 255, 0.4);
+ margin: 5px 0 0 0;
+}
+
+.site {
+ padding: 4px;
+ border-bottom: 1px solid ThreeDLightShadow;
+}
+
+.site-favicon {
+ height: 16px;
+ width: 16px;
+ -moz-margin-end: 4px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+#all-sites-item > .site-container > .site-favicon {
+ list-style-image: none;
+}
+
+/* permissions box */
+
+#permissions-box {
+ padding-top: 10px;
+ overflow-y: auto;
+}
+
+#site-description {
+ font-size: 125%;
+ -moz-margin-start: 6px; /* to match button margin */
+}
+
+#site-label {
+ font-weight: bold;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#defaults-description {
+ font-size: 125%;
+ font-weight: bold;
+ -moz-margin-start: 6px;
+}
+
+.pref-item {
+ margin-bottom: 10px;
+}
+
+.pref-icon {
+ width: 36px;
+ height: 36px;
+ -moz-margin-end: 10px;
+}
+
+.pref-icon[type="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+.pref-icon[type="image"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="popup"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="cookie"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+.pref-icon[type="desktop-notification"] {
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
+}
+.pref-icon[type="install"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
+}
+.pref-icon[type="geo"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+.pref-icon[type="plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
+}
+
+.pref-title {
+ font-size: 125%;
+ margin-bottom: 0;
+ font-weight: bold;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.pref-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+}
+
+.pref-set-default {
+ visibility: collapse;
+}
+
+.pref-menulist {
+ margin-left: 6px;
+ margin-right: 6px;
+ min-width: 10em; /* native menulists ellipsize their longest entries by default on many themes */
+}
+
+.plugins-label {
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-vulnerable {
+ margin-left: 0;
+ padding-left: 0;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+ margin-right: 1em;
+ padding-right: 0;
+}
diff --git a/themes/osx/places/allBookmarks.png b/themes/osx/places/allBookmarks.png
new file mode 100644
index 0000000..d1abe81
Binary files /dev/null and b/themes/osx/places/allBookmarks.png differ
diff --git a/themes/osx/places/bookmark.png b/themes/osx/places/bookmark.png
new file mode 100644
index 0000000..2e9a206
Binary files /dev/null and b/themes/osx/places/bookmark.png differ
diff --git a/themes/osx/places/bookmarksMenu.png b/themes/osx/places/bookmarksMenu.png
new file mode 100644
index 0000000..c27bd6a
Binary files /dev/null and b/themes/osx/places/bookmarksMenu.png differ
diff --git a/themes/osx/places/bookmarksToolbar.png b/themes/osx/places/bookmarksToolbar.png
new file mode 100644
index 0000000..2047bff
Binary files /dev/null and b/themes/osx/places/bookmarksToolbar.png differ
diff --git a/themes/osx/places/bookmarksToolbar@2x.png b/themes/osx/places/bookmarksToolbar@2x.png
new file mode 100644
index 0000000..dd45898
Binary files /dev/null and b/themes/osx/places/bookmarksToolbar@2x.png differ
diff --git a/themes/osx/places/calendar.png b/themes/osx/places/calendar.png
new file mode 100644
index 0000000..1855c9f
Binary files /dev/null and b/themes/osx/places/calendar.png differ
diff --git a/themes/osx/places/downloads.png b/themes/osx/places/downloads.png
new file mode 100644
index 0000000..0756cb6
Binary files /dev/null and b/themes/osx/places/downloads.png differ
diff --git a/themes/osx/places/editBookmark.png b/themes/osx/places/editBookmark.png
new file mode 100644
index 0000000..fbca052
Binary files /dev/null and b/themes/osx/places/editBookmark.png differ
diff --git a/themes/osx/places/editBookmarkOverlay.css b/themes/osx/places/editBookmarkOverlay.css
new file mode 100644
index 0000000..cc749c1
--- /dev/null
+++ b/themes/osx/places/editBookmarkOverlay.css
@@ -0,0 +1,105 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/**** folder menulist ****/
+.folder-icon > .menulist-label-box > .menulist-icon,
+.folder-icon > .menu-iconic-left > .menu-iconic-icon {
+ width: 16px;
+ height: 16px;
+}
+
+.folder-icon > .menu-iconic-left {
+ display: -moz-box;
+}
+
+.folder-icon {
+ list-style-image: url("chrome://global/skin/tree/folder.png") !important;
+}
+
+@media (min-resolution: 2dppx) {
+ .folder-icon {
+ list-style-image: url("chrome://global/skin/tree/folder@2x.png") !important;
+ }
+}
+
+.menulist-icon {
+ margin: 0 !important;
+}
+
+/**** expanders ****/
+
+.expander-up,
+.expander-down {
+ -moz-appearance: none;
+ margin: 0;
+ margin-left: 8px;
+ padding: 0;
+ min-width: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://browser/skin/places/expander-open.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://browser/skin/places/expander-closed.png");
+}
+
+.expander-down:hover:active {
+ list-style-image: url("chrome://browser/skin/places/expander-closed-active.png");
+}
+
+.expander-up:hover:active {
+ list-style-image: url("chrome://browser/skin/places/expander-open-active.png");
+}
+
+#editBookmarkPanelContent {
+ min-width: 23em;
+}
+
+#editBMPanel_folderTree {
+ margin: 6px 4px 0 4px;
+}
+
+/* Hide the value column of the tag autocomplete popup
+ * leaving only the comment column visible. This is
+ * so that only the tag being edited is shown in the
+ * popup.
+ */
+#editBMPanel_tagsField #treecolAutoCompleteValue {
+ visibility: collapse;
+}
+
+
+/* ----- BOOKMARK PANEL DROPDOWN MENU ITEMS ----- */
+
+#editBMPanel_folderMenuList[selectedIndex="0"],
+#editBMPanel_toolbarFolderItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="1"],
+#editBMPanel_bmRootItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png") !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="2"],
+#editBMPanel_unfiledRootItem {
+ list-style-image: url("chrome://browser/skin/places/unfiledBookmarks.png") !important;
+}
+
+@media (min-resolution: 2dppx) {
+ #editBMPanel_folderMenuList[selectedIndex="0"],
+ #editBMPanel_toolbarFolderItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar@2x.png") !important;
+ }
+
+ #editBMPanel_folderMenuList[selectedIndex="2"],
+ #editBMPanel_unfiledRootItem {
+ list-style-image: url("chrome://browser/skin/places/unfiledBookmarks@2x.png") !important;
+ }
+}
diff --git a/themes/osx/places/expander-closed-active.png b/themes/osx/places/expander-closed-active.png
new file mode 100644
index 0000000..7ef5f04
Binary files /dev/null and b/themes/osx/places/expander-closed-active.png differ
diff --git a/themes/osx/places/expander-closed.png b/themes/osx/places/expander-closed.png
new file mode 100644
index 0000000..7850c9e
Binary files /dev/null and b/themes/osx/places/expander-closed.png differ
diff --git a/themes/osx/places/expander-open-active.png b/themes/osx/places/expander-open-active.png
new file mode 100644
index 0000000..673ead5
Binary files /dev/null and b/themes/osx/places/expander-open-active.png differ
diff --git a/themes/osx/places/expander-open.png b/themes/osx/places/expander-open.png
new file mode 100644
index 0000000..7655357
Binary files /dev/null and b/themes/osx/places/expander-open.png differ
diff --git a/themes/osx/places/folderDropArrow.png b/themes/osx/places/folderDropArrow.png
new file mode 100644
index 0000000..8d722cc
Binary files /dev/null and b/themes/osx/places/folderDropArrow.png differ
diff --git a/themes/osx/places/folderDropArrow@2x.png b/themes/osx/places/folderDropArrow@2x.png
new file mode 100644
index 0000000..9efb6d9
Binary files /dev/null and b/themes/osx/places/folderDropArrow@2x.png differ
diff --git a/themes/osx/places/history.png b/themes/osx/places/history.png
new file mode 100644
index 0000000..e5a00b5
Binary files /dev/null and b/themes/osx/places/history.png differ
diff --git a/themes/osx/places/history@2x.png b/themes/osx/places/history@2x.png
new file mode 100644
index 0000000..684b374
Binary files /dev/null and b/themes/osx/places/history@2x.png differ
diff --git a/themes/osx/places/libraryToolbar.png b/themes/osx/places/libraryToolbar.png
new file mode 100644
index 0000000..2ed627a
Binary files /dev/null and b/themes/osx/places/libraryToolbar.png differ
diff --git a/themes/osx/places/livemark-item.png b/themes/osx/places/livemark-item.png
new file mode 100644
index 0000000..9184b95
Binary files /dev/null and b/themes/osx/places/livemark-item.png differ
diff --git a/themes/osx/places/organizer.css b/themes/osx/places/organizer.css
new file mode 100644
index 0000000..611c0c0
--- /dev/null
+++ b/themes/osx/places/organizer.css
@@ -0,0 +1,134 @@
+/* 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/. */
+
+/* Toolbar */
+#placesToolbar {
+ padding: 3px;
+ -moz-padding-end: 6px;
+}
+
+#placesToolbar > toolbarbutton[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+#back-button,
+#forward-button {
+ list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+
+#back-button {
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#forward-button {
+ -moz-image-region: rect(0, 36px, 18px, 18px);
+}
+
+#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+/* organize, view and maintenance buttons icons */
+#organizeButton,
+#viewMenu,
+#maintenanceButton {
+ list-style-image: url("chrome://browser/skin/places/libraryToolbar.png");
+}
+
+/* organize button */
+#organizeButton {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+#organizeButton:hover,
+#organizeButton[open="true"] {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+/* view button */
+#viewMenu {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+#viewMenu:hover,
+#viewMenu[open="true"] {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+/* maintenance button */
+#maintenanceButton {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+#maintenanceButton:hover,
+#maintenanceButton[open="true"] {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+/* Root View */
+#placesView {
+ border-top: 1px solid ThreeDDarkShadow;
+}
+
+/* Info box */
+#detailsDeck {
+ border-top: 1px solid ThreeDShadow;
+ padding: 5px;
+}
+
+#infoBoxExpanderLabel {
+ -moz-padding-start: 2px;
+}
+
+#searchFilter {
+ margin: 0;
+}
+
+/**
+ * Downloads pane
+ */
+
+#clearDownloadsButton > .toolbarbutton-icon {
+ display: none;
+}
+
+#clearDownloadsButton {
+ -moz-padding-start: 9px;
+ -moz-padding-end: 9px;
+}
+
+/* hover-over/open button highlighting */
+
+#organizeButton,
+#viewMenu,
+#maintenanceButton,
+#organizeButton,
+#clearDownloadsButton {
+ color: #222;
+ border: 0;
+ border-radius: 10000px;
+ padding: 1px 8px;
+ margin: 0 0 1px;
+}
+
+#back-button,
+#forward-button {
+ color: #222;
+ border: 0;
+ border-radius: 10000px;
+ padding: 1px 1px;
+ margin: 0 0 1px;
+}
+
+#organizeButton:hover,
+#organizeButton[open="true"],
+#viewMenu:hover,
+#viewMenu[open="true"],
+#maintenanceButton:hover,
+#maintenanceButton[open="true"],
+#organizeButton:hover,
+#organizeButton[open="true"],
+#clearDownloadsButton:hover,
+#back-button:not([disabled]):hover,
+#forward-button:not([disabled]):hover {
+ background-color: rgba(0, 0, 0, .205);
+}
diff --git a/themes/osx/places/places.css b/themes/osx/places/places.css
new file mode 100644
index 0000000..4243779
--- /dev/null
+++ b/themes/osx/places/places.css
@@ -0,0 +1,146 @@
+/* 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/. */
+
+/* Sidebars */
+.sidebar-placesTree {
+ -moz-appearance: none;
+ border: 0;
+ margin: 0;
+ border-top: 1px solid ThreeDShadow;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
+.sidebar-placesTreechildren::-moz-tree-image(leaf) {
+ cursor: pointer;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(separator) {
+ cursor: default;
+}
+
+/* Trees */
+treechildren::-moz-tree-image(title) {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+}
+
+treechildren::-moz-tree-image(title, livemarkItem) {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+treechildren::-moz-tree-image(title, livemarkItem, visited) {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, separator) {
+ list-style-image: none;
+ width: 0;
+ height: 0;
+}
+
+treechildren::-moz-tree-image(title, container),
+treechildren::-moz-tree-image(title, open) {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+treechildren::-moz-tree-image(title, container, livemark) {
+ list-style-image: url("chrome://browser/skin/livemark-folder.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_AllBookmarks) {
+ list-style-image: url("chrome://browser/skin/places/allBookmarks.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksToolbar) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksMenu) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_UnfiledBookmarks) {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+ -moz-image-region: auto;
+}
+
+/* query-nodes should be styled even if they're not expandable */
+treechildren::-moz-tree-image(title, query) {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(title, query, tagContainer),
+treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
+ list-style-image: url("chrome://browser/skin/places/downloads.png");
+ -moz-image-region: auto;
+}
+
+/* calendar icon for folders grouping items by date */
+treechildren::-moz-tree-image(title, query, dayContainer) {
+ list-style-image: url("chrome://browser/skin/places/calendar.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer) {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer, open) {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+}
+
+treechildren::-moz-tree-image(title, query, OrganizerQuery_History) {
+ list-style-image: url("chrome://browser/skin/places/history.png");
+}
+
+/* We want some queries to look like ordinary folders. This must come
+ after the (title, query) selector, or it would get overridden. */
+
+treechildren::-moz-tree-image(title, query, folder),
+treechildren::-moz-tree-image(title, query, folder, open) {
+ list-style-image: url("chrome://global/skin/tree/folder.png");
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+treechildren::-moz-tree-image(cutting) {
+ opacity: 0.5;
+}
+
+treechildren::-moz-tree-cell-text(cutting) {
+ opacity: 0.7;
+}
+
+/* Browser Sidebars */
+
+/* Default button vert. margins are 1px/2px, and this can cause misalignment */
+#viewButton {
+ margin-top: 2px;
+ margin-bottom: 2px;
+}
+
+#viewButton > .button-box > .button-menu-dropmarker {
+ height: auto;
+ width: auto;
+ -moz-margin-end: -3px;
+}
diff --git a/themes/osx/places/query.png b/themes/osx/places/query.png
new file mode 100644
index 0000000..0ccb847
Binary files /dev/null and b/themes/osx/places/query.png differ
diff --git a/themes/osx/places/query@2x.png b/themes/osx/places/query@2x.png
new file mode 100644
index 0000000..20b458a
Binary files /dev/null and b/themes/osx/places/query@2x.png differ
diff --git a/themes/osx/places/starred48.png b/themes/osx/places/starred48.png
new file mode 100644
index 0000000..bfa1459
Binary files /dev/null and b/themes/osx/places/starred48.png differ
diff --git a/themes/osx/places/tag.png b/themes/osx/places/tag.png
new file mode 100644
index 0000000..a4038bb
Binary files /dev/null and b/themes/osx/places/tag.png differ
diff --git a/themes/osx/places/tag@2x.png b/themes/osx/places/tag@2x.png
new file mode 100644
index 0000000..673814b
Binary files /dev/null and b/themes/osx/places/tag@2x.png differ
diff --git a/themes/osx/places/toolbarDropMarker.png b/themes/osx/places/toolbarDropMarker.png
new file mode 100644
index 0000000..a217b0e
Binary files /dev/null and b/themes/osx/places/toolbarDropMarker.png differ
diff --git a/themes/osx/places/unfiledBookmarks.png b/themes/osx/places/unfiledBookmarks.png
new file mode 100644
index 0000000..69495da
Binary files /dev/null and b/themes/osx/places/unfiledBookmarks.png differ
diff --git a/themes/osx/places/unfiledBookmarks@2x.png b/themes/osx/places/unfiledBookmarks@2x.png
new file mode 100644
index 0000000..44efd6a
Binary files /dev/null and b/themes/osx/places/unfiledBookmarks@2x.png differ
diff --git a/themes/osx/places/unsortedBookmarks.png b/themes/osx/places/unsortedBookmarks.png
new file mode 100644
index 0000000..893e75a
Binary files /dev/null and b/themes/osx/places/unsortedBookmarks.png differ
diff --git a/themes/osx/places/unstarred48.png b/themes/osx/places/unstarred48.png
new file mode 100644
index 0000000..8b82aab
Binary files /dev/null and b/themes/osx/places/unstarred48.png differ
diff --git a/themes/osx/pointerLock-16.png b/themes/osx/pointerLock-16.png
new file mode 100644
index 0000000..862cd11
Binary files /dev/null and b/themes/osx/pointerLock-16.png differ
diff --git a/themes/osx/pointerLock-64.png b/themes/osx/pointerLock-64.png
new file mode 100644
index 0000000..a35ce04
Binary files /dev/null and b/themes/osx/pointerLock-64.png differ
diff --git a/themes/osx/preferences/Options-sync.png b/themes/osx/preferences/Options-sync.png
new file mode 100644
index 0000000..89901fb
Binary files /dev/null and b/themes/osx/preferences/Options-sync.png differ
diff --git a/themes/osx/preferences/Options.png b/themes/osx/preferences/Options.png
new file mode 100644
index 0000000..448eca6
Binary files /dev/null and b/themes/osx/preferences/Options.png differ
diff --git a/themes/osx/preferences/alwaysAsk.png b/themes/osx/preferences/alwaysAsk.png
new file mode 100644
index 0000000..ddd4cb2
Binary files /dev/null and b/themes/osx/preferences/alwaysAsk.png differ
diff --git a/themes/osx/preferences/application.png b/themes/osx/preferences/application.png
new file mode 100644
index 0000000..ff2ecc2
Binary files /dev/null and b/themes/osx/preferences/application.png differ
diff --git a/themes/osx/preferences/applications.css b/themes/osx/preferences/applications.css
new file mode 100644
index 0000000..80699b4
--- /dev/null
+++ b/themes/osx/preferences/applications.css
@@ -0,0 +1,64 @@
+/* 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/. */
+
+/**
+ * Line up the actions menu with action labels above and below it.
+ * Equalize the distance from the left side of the action box to the left side
+ * of the icon for both the menu and the non-menu versions of the action box.
+ * Also make sure the labels are the same distance away from the icons.
+ */
+.actionsMenu {
+ margin-top: 0;
+ margin-bottom: 0;
+ -moz-margin-start: -2px;
+ -moz-margin-end: 0;
+}
+
+.typeIcon,
+.actionIcon {
+ -moz-margin-start: 3px;
+ -moz-margin-end: 3px;
+}
+
+richlistitem label {
+ -moz-margin-start: 1px;
+ margin-top: 2px;
+}
+
+richlistitem {
+ min-height: 22px;
+}
+
+richlistitem[appHandlerIcon="ask"],
+menuitem[appHandlerIcon="ask"] {
+ list-style-image: url("chrome://browser/skin/preferences/alwaysAsk.png");
+}
+
+richlistitem[appHandlerIcon="save"],
+menuitem[appHandlerIcon="save"] {
+ list-style-image: url("chrome://browser/skin/preferences/application.png");
+}
+
+richlistitem[appHandlerIcon="feed"],
+menuitem[appHandlerIcon="feed"] {
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+richlistitem[appHandlerIcon="plugin"],
+menuitem[appHandlerIcon="plugin"] {
+ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
+}
+
+.actionsMenu .menulist-icon {
+ -moz-margin-end: 3px;
+}
+
+.actionsMenu > menupopup > menuitem > .menu-iconic-left {
+ -moz-padding-start: 0px;
+ -moz-padding-end: 2px;
+}
+
+.actionsMenu > menupopup > menuitem {
+ -moz-padding-start: 4px;
+}
diff --git a/themes/osx/preferences/mail.png b/themes/osx/preferences/mail.png
new file mode 100644
index 0000000..c40d159
Binary files /dev/null and b/themes/osx/preferences/mail.png differ
diff --git a/themes/osx/preferences/preferences.css b/themes/osx/preferences/preferences.css
new file mode 100644
index 0000000..4075b1e
--- /dev/null
+++ b/themes/osx/preferences/preferences.css
@@ -0,0 +1,142 @@
+/*
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+*/
+
+/* Global Styles */
+#BrowserPreferences radio[pane] {
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+ padding: 5px 3px 1px;
+}
+
+radio[pane=paneMain] {
+ -moz-image-region: rect(0, 32px, 32px, 0);
+}
+
+radio[pane=paneTabs] {
+ -moz-image-region: rect(0, 64px, 32px, 32px);
+}
+
+radio[pane=paneContent] {
+ -moz-image-region: rect(0, 96px, 32px, 64px);
+}
+
+radio[pane=paneApplications] {
+ -moz-image-region: rect(0, 128px, 32px, 96px);
+}
+
+radio[pane=panePrivacy] {
+ -moz-image-region: rect(0, 160px, 32px, 128px);
+}
+
+radio[pane=paneSecurity] {
+ -moz-image-region: rect(0, 192px, 32px, 160px);
+}
+
+radio[pane=paneAdvanced] {
+ -moz-image-region: rect(0, 224px, 32px, 192px);
+}
+
+%ifdef MOZ_SERVICES_SYNC
+radio[pane=paneSync] {
+ list-style-image: url("chrome://browser/skin/preferences/Options-sync.png") !important;
+}
+%endif
+
+/* Applications Pane */
+#BrowserPreferences[animated="true"] #handlersView {
+ height: 25em;
+}
+
+#BrowserPreferences[animated="false"] #handlersView {
+ -moz-box-flex: 1;
+}
+
+/* Privacy Pane */
+
+/* styles for the link elements copied from .text-link in global.css */
+.inline-link {
+ color: -moz-nativehyperlinktext;
+ text-decoration: none;
+}
+
+.inline-link:hover {
+ text-decoration: underline;
+}
+
+/* Modeless Window Dialogs */
+.windowDialog,
+.windowDialog prefpane {
+ padding: 0;
+}
+
+#browserHomePage:-moz-locale-dir(rtl) input {
+ unicode-bidi: plaintext;
+ direction: rtl;
+}
+
+.contentPane {
+ margin: 9px 8px 5px;
+}
+
+.actionButtons {
+ margin: 0 3px 6px !important;
+}
+
+/* Cookies Manager */
+#cookiesChildren::-moz-tree-image(domainCol) {
+ width: 16px;
+ height: 16px;
+ margin: 0 2px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png") !important;
+}
+
+#cookiesChildren::-moz-tree-image(domainCol, container),
+#cookiesChildren::-moz-tree-image(domainCol, container, open) {
+ list-style-image: url("chrome://global/skin/tree/folder.png") !important;
+}
+
+#cookieInfoBox {
+ border: 1px solid ThreeDShadow;
+ border-radius: 0;
+ margin: 4px;
+ padding: 0;
+}
+
+/* Advanced Pane */
+
+/* Adding padding-bottom prevents the bottom of the tabpanel from being cutoff
+ when browser.preferences.animateFadeIn = true */
+#advancedPrefs {
+ padding-bottom: 8px;
+}
+
+/* bottom-most box containing a groupbox in a prefpane. Prevents the bottom
+ of the groupbox from being cutoff */
+.bottomBox {
+ padding-bottom: 4px;
+}
+
+%ifdef MOZ_SERVICES_SYNC
+/* Sync Pane */
+
+#syncDesc {
+ padding: 0 8em;
+}
+
+.syncGroupBox {
+ padding: 10px;
+}
+
+#accountCaptionImage {
+ list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
+}
+
+#syncAddDeviceLabel {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+%endif
diff --git a/themes/osx/preferences/saveFile.png b/themes/osx/preferences/saveFile.png
new file mode 100644
index 0000000..c210e84
Binary files /dev/null and b/themes/osx/preferences/saveFile.png differ
diff --git a/themes/osx/privatebrowsing-dark.png b/themes/osx/privatebrowsing-dark.png
new file mode 100644
index 0000000..9eaf3ae
Binary files /dev/null and b/themes/osx/privatebrowsing-dark.png differ
diff --git a/themes/osx/privatebrowsing-light.png b/themes/osx/privatebrowsing-light.png
new file mode 100644
index 0000000..c12f507
Binary files /dev/null and b/themes/osx/privatebrowsing-light.png differ
diff --git a/themes/osx/privatebrowsing-mask.png b/themes/osx/privatebrowsing-mask.png
new file mode 100644
index 0000000..92f60e2
Binary files /dev/null and b/themes/osx/privatebrowsing-mask.png differ
diff --git a/themes/osx/privatebrowsing-mask@2x.png b/themes/osx/privatebrowsing-mask@2x.png
new file mode 100644
index 0000000..ec1cf74
Binary files /dev/null and b/themes/osx/privatebrowsing-mask@2x.png differ
diff --git a/themes/osx/reload-stop-go.png b/themes/osx/reload-stop-go.png
new file mode 100644
index 0000000..1017be9
Binary files /dev/null and b/themes/osx/reload-stop-go.png differ
diff --git a/themes/osx/sanitizeDialog.css b/themes/osx/sanitizeDialog.css
new file mode 100644
index 0000000..40dc4b2
--- /dev/null
+++ b/themes/osx/sanitizeDialog.css
@@ -0,0 +1,93 @@
+/* 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/. */
+
+#sanitizeDurationChoice {
+ -moz-margin-end: 0;
+}
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 3px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("chrome://global/skin/icons/warning-large.png");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin: 6px 0;
+}
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ margin: 0;
+}
+
+.expander-up > .button-box,
+.expander-down > .button-box {
+ padding: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://browser/skin/places/expander-open.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://browser/skin/places/expander-closed.png");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="cancel"] {
+ -moz-margin-end: 0;
+}
diff --git a/themes/osx/searchbar-dropdown-arrow.png b/themes/osx/searchbar-dropdown-arrow.png
new file mode 100644
index 0000000..7f5f55e
Binary files /dev/null and b/themes/osx/searchbar-dropdown-arrow.png differ
diff --git a/themes/osx/searchbar.css b/themes/osx/searchbar.css
new file mode 100644
index 0000000..55fdfc4
--- /dev/null
+++ b/themes/osx/searchbar.css
@@ -0,0 +1,79 @@
+/* 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/. */
+
+.searchbar-textbox {
+ width: 6em;
+ min-width: 6em;
+}
+
+.autocomplete-textbox-container {
+ -moz-box-align: stretch;
+}
+
+.textbox-input-box {
+ margin: 0;
+}
+
+/* ::::: searchbar-engine-button ::::: */
+
+.searchbar-engine-image {
+ height: 16px;
+ width: 16px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.searchbar-engine-button {
+ -moz-appearance: none;
+ min-width: 0;
+ margin: 0;
+ padding: 0;
+ -moz-padding-end: 2px;
+ -moz-box-align: center;
+ background: none;
+ border: none;
+}
+
+.searchbar-engine-button > .button-box {
+ -moz-appearance: none;
+ padding: 0;
+ border: 0;
+}
+
+.searchbar-dropmarker-image {
+ list-style-image: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
+ -moz-image-region: rect(0, 13px, 11px, 0);
+}
+
+.searchbar-engine-button[open="true"] > .searchbar-dropmarker-image {
+ -moz-image-region: rect(0, 26px, 11px, 13px);
+}
+
+
+/* ::::: search-go-button ::::: */
+
+.search-go-container {
+ -moz-box-align: center;
+}
+
+.search-go-button {
+ padding: 1px;
+ list-style-image: url("chrome://browser/skin/Search-glass.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+.search-go-button:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+.search-go-button:hover {
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+.search-go-button:hover:active {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+.searchbar-engine-menuitem[selected="true"] > .menu-iconic-text {
+ font-weight: bold;
+}
diff --git a/themes/osx/setDesktopBackground.css b/themes/osx/setDesktopBackground.css
new file mode 100644
index 0000000..585284c
--- /dev/null
+++ b/themes/osx/setDesktopBackground.css
@@ -0,0 +1,18 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+html|canvas#screen {
+ margin: 12px 11px 32px;
+}
+
+#monitor {
+ list-style-image: url("chrome://browser/skin/monitor.png");
+}
+
+#monitor[aspectratio="16:10"] {
+ list-style-image: url("chrome://browser/skin/monitor_16-10.png");
+}
diff --git a/themes/osx/shared.inc b/themes/osx/shared.inc
new file mode 100644
index 0000000..ef27746
--- /dev/null
+++ b/themes/osx/shared.inc
@@ -0,0 +1,6 @@
+%include ../../../../toolkit/themes/osx/global/shared.inc
+%include ../shared/browser.inc
+
+%define hudButton -moz-appearance: none; color: #434343; border-radius: 4px; border: 1px solid #b5b5b5; background: linear-gradient(#fff, #f2f2f2); box-shadow: inset 0 1px rgba(255,255,255,.8), inset 0 0 1px rgba(255,255, 255,.25), 0 1px rgba(255,255,255,.3); background-clip: padding-box; background-origin: padding-box; padding: 2px 6px;
+%define hudButtonPressed box-shadow: inset 0 1px 4px -3px #000, 0 1px rgba(255,255,255,.3);
+%define hudButtonFocused box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;
diff --git a/themes/osx/slowStartup-16.png b/themes/osx/slowStartup-16.png
new file mode 100644
index 0000000..5551ef0
Binary files /dev/null and b/themes/osx/slowStartup-16.png differ
diff --git a/themes/osx/statusbar/overlay.css b/themes/osx/statusbar/overlay.css
new file mode 100644
index 0000000..ab1cc8f
--- /dev/null
+++ b/themes/osx/statusbar/overlay.css
@@ -0,0 +1,108 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/overlay.css
+
+/*
+ * General
+ */
+
+#status4evar-status-text,
+#status4evar-progress-bar
+{
+ margin: 0px 4px;
+}
+
+/*
+ * Download status
+ */
+
+#status4evar-download-progress-bar
+{
+ height: 5px;
+}
+
+#status4evar-download-button[attention] #status4evar-download-icon
+{
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+#status-bar
+{
+ padding-right: 0px;
+}
+
+#browser-bottombox > #addon-bar:last-child
+{
+ padding-right: 16px;
+}
+
+#status4evar-download-button #status4evar-download-icon
+{
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 108, 18, 90) center no-repeat;
+ min-width: 18px;
+ min-height: 18px;
+}
+
+#status4evar-download-button:-moz-lwtheme-brighttext #status4evar-download-icon
+{
+ background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 108, 18, 90) center no-repeat;
+}
+
+#status4evar-download-button[attention] #status4evar-download-icon
+{
+ background-image: url("chrome://browser/skin/downloads/download-glow.png");
+}
+
+toolbar[mode="icons"] #status4evar-download-button[forcelabel="true"] > label
+{
+ margin: 0px 2px !important;
+ -moz-margin-start: 3px !important;
+}
+
+/*
+ * Splitter
+ */
+
+splitter.status4evar-status-splitter
+{
+ width: 8px;
+ margin: 0px -4px;
+}
+
+/*
+ * Location bar
+ */
+
+#urlbar-progress-alt
+{
+ margin-right: -1px;
+}
+
+/*
+ * Toolbar progress
+ */
+
+#status4evar-progress-bar[s4estyle="true"]
+{
+ -moz-appearance: none;
+ border: 1px solid gray;
+}
+
+#status4evar-progress-bar[s4estyle="true"] > .progress-remainder
+{
+ background-color: white;
+}
+
+/*
+ * Gripper
+ */
+
+#status4evar-window-gripper
+{
+ display: none;
+}
+
diff --git a/themes/osx/statusbar/prefs.css b/themes/osx/statusbar/prefs.css
new file mode 100644
index 0000000..798a62d
--- /dev/null
+++ b/themes/osx/statusbar/prefs.css
@@ -0,0 +1,13 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/prefs.css
+
+#status4evar-addonbar-windowGripper-check
+{
+ display: none;
+}
+
diff --git a/themes/osx/sync-128.png b/themes/osx/sync-128.png
new file mode 100644
index 0000000..1ea3481
Binary files /dev/null and b/themes/osx/sync-128.png differ
diff --git a/themes/osx/sync-16.png b/themes/osx/sync-16.png
new file mode 100644
index 0000000..0afb1c7
Binary files /dev/null and b/themes/osx/sync-16.png differ
diff --git a/themes/osx/sync-32.png b/themes/osx/sync-32.png
new file mode 100644
index 0000000..7a762cb
Binary files /dev/null and b/themes/osx/sync-32.png differ
diff --git a/themes/osx/sync-bg.png b/themes/osx/sync-bg.png
new file mode 100644
index 0000000..893a27d
Binary files /dev/null and b/themes/osx/sync-bg.png differ
diff --git a/themes/osx/sync-desktopIcon.png b/themes/osx/sync-desktopIcon.png
new file mode 100644
index 0000000..d3d1e27
Binary files /dev/null and b/themes/osx/sync-desktopIcon.png differ
diff --git a/themes/osx/sync-mobileIcon.png b/themes/osx/sync-mobileIcon.png
new file mode 100644
index 0000000..a3bda57
Binary files /dev/null and b/themes/osx/sync-mobileIcon.png differ
diff --git a/themes/osx/sync-throbber.png b/themes/osx/sync-throbber.png
new file mode 100644
index 0000000..d25490b
Binary files /dev/null and b/themes/osx/sync-throbber.png differ
diff --git a/themes/osx/syncCommon.css b/themes/osx/syncCommon.css
new file mode 100644
index 0000000..f0beae0
--- /dev/null
+++ b/themes/osx/syncCommon.css
@@ -0,0 +1,49 @@
+/* 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/. */
+
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
+.status {
+ color: -moz-dialogtext;
+}
+
+.statusIcon {
+ -moz-margin-start: 4px;
+ max-height: 16px;
+ max-width: 16px;
+}
+
+.statusIcon[status="active"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.statusIcon[status="error"] {
+ list-style-image: url("chrome://global/skin/icons/error-16.png");
+}
+
+.statusIcon[status="success"] {
+ list-style-image: url("chrome://global/skin/icons/information-16.png");
+}
+
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
+ a separate stylesheet for it. */
+.data {
+ font-size: 90%;
+ font-weight: bold;
+}
+
+dialog#change-dialog {
+ width: 40em;
+}
+
+image#syncIcon {
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
+
+#introText {
+ margin-top: 2px;
+}
+
+#feedback {
+ height: 2em;
+}
diff --git a/themes/osx/syncProgress.css b/themes/osx/syncProgress.css
new file mode 100644
index 0000000..d7aa599
--- /dev/null
+++ b/themes/osx/syncProgress.css
@@ -0,0 +1,46 @@
+/* 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/. */
+@import url(chrome://global/skin/inContentUI.css);
+
+:root {
+ height: 100%;
+ width: 100%;
+ padding: 0;
+}
+
+body {
+ margin: 0;
+ padding: 0 2em;
+}
+
+#floatingBox {
+ margin: 4em auto;
+ max-width: 40em;
+ min-width: 23em;
+ padding: 1em 1.5em;
+ position: relative;
+ text-align: center;
+}
+
+#successLogo {
+ margin: 1em 2em;
+}
+
+#loadingText {
+ margin: 2em 6em;
+}
+
+#progressBar {
+ margin: 2em 10em;
+}
+
+#uploadProgressBar{
+ width: 100%;
+}
+
+#bottomRow {
+ margin-top: 2em;
+ padding: 0;
+ text-align: end;
+}
diff --git a/themes/osx/syncQuota.css b/themes/osx/syncQuota.css
new file mode 100644
index 0000000..1577de8
--- /dev/null
+++ b/themes/osx/syncQuota.css
@@ -0,0 +1,26 @@
+/* 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/. */
+
+#quotaDialog {
+ width: 33em;
+ height: 25em;
+}
+
+treechildren::-moz-tree-checkbox {
+ list-style-image: none;
+}
+treechildren::-moz-tree-checkbox(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-checkbox(disabled) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+#treeCaption {
+ height: 4em;
+}
+
+.captionWarning {
+ font-weight: bold;
+}
diff --git a/themes/osx/syncSetup.css b/themes/osx/syncSetup.css
new file mode 100644
index 0000000..fff65e9
--- /dev/null
+++ b/themes/osx/syncSetup.css
@@ -0,0 +1,132 @@
+/* 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/. */
+
+wizard {
+ -moz-appearance: none;
+ width: 55em;
+ height: 45em;
+ padding: 0;
+ background-color: Window;
+}
+
+.wizard-page-box {
+ -moz-appearance: none;
+ padding-left: 0;
+ padding-right: 0;
+ margin: 0;
+}
+
+wizardpage {
+ -moz-box-pack: center;
+ -moz-box-align: center;
+ margin: 0;
+ padding: 0 6em;
+ background-color: Window;
+}
+
+.wizard-header {
+ -moz-appearance: none;
+ border: none;
+ padding: 2em 0 1em 0;
+ text-align: center;
+}
+.wizard-header-label {
+ font-size: 24pt;
+ font-weight: normal;
+}
+
+.wizard-buttons {
+ background-color: rgba(0,0,0,0.1);
+ padding: 1em;
+}
+
+.wizard-buttons-separator {
+ visibility: collapse;
+}
+
+.wizard-header-icon {
+ visibility: collapse;
+}
+
+.accountChoiceButton {
+ font: menu;
+}
+
+.confirm {
+ border: 1px solid black;
+ padding: 1em;
+ border-radius: 5px;
+}
+
+/* Override the text-link style from global.css */
+description > .text-link,
+description > .text-link:focus {
+ margin: 0px;
+ padding: 0px;
+ border: 0px;
+}
+
+
+.success,
+.error {
+ padding: 2px;
+ border-radius: 2px;
+}
+
+.error {
+ background-color: #FF0000 !important;
+ color: #FFFFFF !important;
+}
+
+.success {
+ background-color: #00FF00 !important;
+}
+
+.warning {
+ font-weight: bold;
+ font-size: 100%;
+ color: red;
+}
+
+.mainDesc {
+ font-weight: bold;
+ font-size: 100%;
+}
+
+.normal {
+ font-size: 100%;
+}
+
+.inputColumn {
+ -moz-margin-end: 2px
+}
+
+.pin {
+ font-size: 18pt;
+ width: 4em;
+ text-align: center;
+}
+
+#passphraseHelpSpacer {
+ width: 0.5em;
+}
+
+#pairDeviceThrobber > image,
+#login-throbber > image {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#captchaFeedback {
+ visibility: hidden;
+}
+
+#successPageIcon {
+ /* TODO replace this with a 128px version (bug 591122) */
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
+
+#tosDesc {
+ margin-left: -7px;
+ margin-bottom: 3px;
+}
\ No newline at end of file
diff --git a/themes/osx/tabbrowser/alltabs-inverted.png b/themes/osx/tabbrowser/alltabs-inverted.png
new file mode 100644
index 0000000..002bdd4
Binary files /dev/null and b/themes/osx/tabbrowser/alltabs-inverted.png differ
diff --git a/themes/osx/tabbrowser/alltabs.png b/themes/osx/tabbrowser/alltabs.png
new file mode 100644
index 0000000..172d425
Binary files /dev/null and b/themes/osx/tabbrowser/alltabs.png differ
diff --git a/themes/osx/tabbrowser/connecting.png b/themes/osx/tabbrowser/connecting.png
new file mode 100644
index 0000000..e564fb5
Binary files /dev/null and b/themes/osx/tabbrowser/connecting.png differ
diff --git a/themes/osx/tabbrowser/loading.png b/themes/osx/tabbrowser/loading.png
new file mode 100644
index 0000000..ba54836
Binary files /dev/null and b/themes/osx/tabbrowser/loading.png differ
diff --git a/themes/osx/tabbrowser/newtab-glass.png b/themes/osx/tabbrowser/newtab-glass.png
new file mode 100644
index 0000000..15185be
Binary files /dev/null and b/themes/osx/tabbrowser/newtab-glass.png differ
diff --git a/themes/osx/tabbrowser/newtab-inverted.png b/themes/osx/tabbrowser/newtab-inverted.png
new file mode 100644
index 0000000..4ac1eba
Binary files /dev/null and b/themes/osx/tabbrowser/newtab-inverted.png differ
diff --git a/themes/osx/tabbrowser/newtab.png b/themes/osx/tabbrowser/newtab.png
new file mode 100644
index 0000000..7cea7bd
Binary files /dev/null and b/themes/osx/tabbrowser/newtab.png differ
diff --git a/themes/osx/tabbrowser/tab-arrow-left-glass.png b/themes/osx/tabbrowser/tab-arrow-left-glass.png
new file mode 100644
index 0000000..aac93a7
Binary files /dev/null and b/themes/osx/tabbrowser/tab-arrow-left-glass.png differ
diff --git a/themes/osx/tabbrowser/tab-arrow-left-inverted.png b/themes/osx/tabbrowser/tab-arrow-left-inverted.png
new file mode 100644
index 0000000..16cd7a2
Binary files /dev/null and b/themes/osx/tabbrowser/tab-arrow-left-inverted.png differ
diff --git a/themes/osx/tabbrowser/tab-arrow-left.png b/themes/osx/tabbrowser/tab-arrow-left.png
new file mode 100644
index 0000000..e0fb348
Binary files /dev/null and b/themes/osx/tabbrowser/tab-arrow-left.png differ
diff --git a/themes/osx/tabbrowser/tab-overflow-border.png b/themes/osx/tabbrowser/tab-overflow-border.png
new file mode 100644
index 0000000..77f2462
Binary files /dev/null and b/themes/osx/tabbrowser/tab-overflow-border.png differ
diff --git a/themes/osx/tabbrowser/tabDragIndicator.png b/themes/osx/tabbrowser/tabDragIndicator.png
new file mode 100644
index 0000000..c67c233
Binary files /dev/null and b/themes/osx/tabbrowser/tabDragIndicator.png differ
diff --git a/themes/osx/toolbarbutton-dropdown-arrow-inverted.png b/themes/osx/toolbarbutton-dropdown-arrow-inverted.png
new file mode 100644
index 0000000..f3261f1
Binary files /dev/null and b/themes/osx/toolbarbutton-dropdown-arrow-inverted.png differ
diff --git a/themes/osx/toolbarbutton-dropdown-arrow.png b/themes/osx/toolbarbutton-dropdown-arrow.png
new file mode 100644
index 0000000..a7abe73
Binary files /dev/null and b/themes/osx/toolbarbutton-dropdown-arrow.png differ
diff --git a/themes/osx/urlbar-arrow.png b/themes/osx/urlbar-arrow.png
new file mode 100644
index 0000000..fcab253
Binary files /dev/null and b/themes/osx/urlbar-arrow.png differ
diff --git a/themes/osx/urlbar-history-dropmarker.png b/themes/osx/urlbar-history-dropmarker.png
new file mode 100644
index 0000000..fc8b0be
Binary files /dev/null and b/themes/osx/urlbar-history-dropmarker.png differ
diff --git a/themes/osx/urlbar-popup-blocked.png b/themes/osx/urlbar-popup-blocked.png
new file mode 100644
index 0000000..e6fd29f
Binary files /dev/null and b/themes/osx/urlbar-popup-blocked.png differ
diff --git a/themes/osx/web-notifications-icon.svg b/themes/osx/web-notifications-icon.svg
new file mode 100644
index 0000000..f7186c7
--- /dev/null
+++ b/themes/osx/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/themes/osx/web-notifications-tray.svg b/themes/osx/web-notifications-tray.svg
new file mode 100644
index 0000000..314026a
--- /dev/null
+++ b/themes/osx/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/osx/webRTC-shareDevice-16.png b/themes/osx/webRTC-shareDevice-16.png
new file mode 100644
index 0000000..df01b33
Binary files /dev/null and b/themes/osx/webRTC-shareDevice-16.png differ
diff --git a/themes/osx/webRTC-shareDevice-64.png b/themes/osx/webRTC-shareDevice-64.png
new file mode 100644
index 0000000..d125789
Binary files /dev/null and b/themes/osx/webRTC-shareDevice-64.png differ
diff --git a/themes/osx/webRTC-sharingDevice-16.png b/themes/osx/webRTC-sharingDevice-16.png
new file mode 100644
index 0000000..a670676
Binary files /dev/null and b/themes/osx/webRTC-sharingDevice-16.png differ
diff --git a/themes/shared/browser.inc b/themes/shared/browser.inc
new file mode 100644
index 0000000..18e69ad
--- /dev/null
+++ b/themes/shared/browser.inc
@@ -0,0 +1,8 @@
+%filter substitution
+
+%ifndef MOZ_WEBRTC
+%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #history-menu-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button
+%else
+%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #downloads-indicator, #history-button, #history-menu-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-button, #feed-button, #alltabs-button, #webrtc-status-button
+%endif
+
diff --git a/themes/shared/newtab/controls.png b/themes/shared/newtab/controls.png
new file mode 100644
index 0000000..14f382f
Binary files /dev/null and b/themes/shared/newtab/controls.png differ
diff --git a/themes/shared/newtab/newTab.css.inc b/themes/shared/newtab/newTab.css.inc
new file mode 100644
index 0000000..3341ba7
--- /dev/null
+++ b/themes/shared/newtab/newTab.css.inc
@@ -0,0 +1,203 @@
+/* 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/. */
+
+:root {
+ -moz-appearance: none;
+ font-size: 75%;
+ background-color: transparent;
+}
+
+body {
+ background: linear-gradient(to top,#DFF3FF,#F9F9F9) fixed;
+}
+
+/* SCROLLBOX */
+#newtab-scrollbox:not([page-disabled]) {
+ background-color: rgb(229,229,229);
+ background-image: url(chrome://browser/skin/newtab/noise.png),
+ linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
+ background-attachment: fixed;
+}
+
+/* UNDO */
+#newtab-undo-container {
+ padding: 4px 3px;
+ border: 1px solid;
+ border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
+ background-color: rgba(255,255,255,.4);
+ color: #525e69;
+}
+
+#newtab-undo-label {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+
+.newtab-undo-button:hover {
+ text-decoration: underline;
+}
+
+.newtab-undo-button:-moz-focusring {
+ outline: 1px dotted;
+}
+
+
+#newtab-undo-close-button > .toolbarbutton-text {
+ display: none;
+}
+
+#newtab-undo-close-button:-moz-focusring {
+ outline: 1px dotted;
+}
+
+/* TOGGLE */
+#newtab-toggle {
+ width: 16px;
+ height: 16px;
+ padding: 0;
+ border: none;
+ background: -216px 0 transparent url(chrome://browser/skin/newtab/controls.png);
+}
+
+#newtab-toggle[page-disabled] {
+ background-position: -232px 0;
+}
+
+/* ROWS */
+.newtab-row {
+ margin-bottom: 20px;
+}
+
+.newtab-row:last-child {
+ margin-bottom: 0;
+}
+
+/* CELLS */
+.newtab-cell {
+ -moz-margin-end: 20px;
+ background-color: rgba(255,255,255,.2);
+ border: 1px solid;
+ border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
+ border-radius: 1px;
+ transition: border-color 100ms ease-out;
+}
+
+.newtab-cell:empty {
+ border: 1px dashed;
+ border-color: rgba(8,22,37,.15) rgba(8,22,37,.17) rgba(8,22,37,.19);
+}
+
+.newtab-cell:last-child {
+ -moz-margin-end: 0;
+}
+
+.newtab-cell:hover:not(:empty):not([dragged]) {
+ border-color: rgba(8,22,37,.25) rgba(8,22,37,.27) rgba(8,22,37,.3);
+}
+
+/* SITES */
+.newtab-site {
+ text-decoration: none;
+ transition-property: top, left, opacity, box-shadow, background-color;
+}
+
+.newtab-site:hover,
+.newtab-site[dragged] {
+ box-shadow: 0 3px 6px 1px rgba(8,20,37,.6);
+}
+
+.newtab-site[dragged] {
+ transition-property: box-shadow, background-color;
+ background-color: rgb(242,242,242);
+}
+
+/* THUMBNAILS */
+.newtab-thumbnail {
+ background-origin: padding-box;
+ background-clip: padding-box;
+ background-repeat: no-repeat;
+ background-size: cover;
+}
+
+/* TITLES */
+.newtab-title {
+ padding: 0 8px 1px;
+ background-color: rgba(248,249,251,.95);
+ color: #1f364c;
+ line-height: 24px;
+}
+
+.newtab-site[pinned] .newtab-title {
+ padding-inline-start: 16px;
+}
+
+.newtab-site[pinned] .newtab-title::before {
+ background-image: url(chrome://browser/skin/newtab/pinned.png);
+ content: "";
+ left: 2px;
+ top: 2px;
+ position: absolute;
+ width: 12px;
+ height: 20px;
+}
+
+.newtab-site[pinned] .newtab-title:dir(rtl)::before {
+ left: auto;
+ right: 2px;
+}
+
+/* CONTROLS */
+.newtab-control {
+ background-color: transparent;
+ background-size: 24px;
+ border: none;
+ height: 24px;
+ width: 24px;
+ top: 4px;
+ background: transparent url(chrome://browser/skin/newtab/controls.png);
+}
+
+.newtab-control-pin:dir(ltr),
+.newtab-control-block:dir(rtl) {
+ left: 4px;
+}
+
+.newtab-control-block:dir(ltr),
+.newtab-control-pin:dir(rtl) {
+ right: 4px;
+}
+
+.newtab-control-pin:hover {
+ background-position: -24px 0;
+}
+
+.newtab-control-pin:active {
+ background-position: -48px 0;
+}
+
+.newtab-site[pinned] .newtab-control-pin {
+ background-position: -72px 0;
+}
+
+.newtab-site[pinned] .newtab-control-pin:hover {
+ background-position: -96px 0;
+}
+
+.newtab-site[pinned] .newtab-control-pin:active {
+ background-position: -120px 0;
+}
+
+.newtab-control-block {
+ background-position: -144px 0;
+}
+
+.newtab-control-block:hover {
+ background-position: -168px 0;
+}
+
+.newtab-control-block:active {
+ background-position: -192px 0;
+}
+
diff --git a/themes/shared/newtab/noise.png b/themes/shared/newtab/noise.png
new file mode 100644
index 0000000..01d340a
Binary files /dev/null and b/themes/shared/newtab/noise.png differ
diff --git a/themes/shared/newtab/pinned.png b/themes/shared/newtab/pinned.png
new file mode 100644
index 0000000..ddd731b
Binary files /dev/null and b/themes/shared/newtab/pinned.png differ
diff --git a/themes/shared/plugin-doorhanger.inc.css b/themes/shared/plugin-doorhanger.inc.css
new file mode 100644
index 0000000..bda08e4
--- /dev/null
+++ b/themes/shared/plugin-doorhanger.inc.css
@@ -0,0 +1,53 @@
+#notification-popup[popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowcontent {
+ padding: 0px;
+}
+
+.click-to-play-plugins-notification-content {
+ width: 28em;
+}
+
+.click-to-play-plugins-notification-center-box {
+ border: 1px solid ThreeDShadow;
+ margin: 10px;
+}
+
+.plugin-popupnotification-centeritem:nth-child(odd) {
+ background-color: rgba(0,0,0,0.1);
+}
+
+.center-item-label {
+ -moz-margin-start: 6px;
+ margin-bottom: 0;
+ text-overflow: ellipsis;
+}
+
+.center-item-warning-icon {
+ background-image: url("chrome://mozapps/skin/extensions/alerticon-info-negative.png");
+ background-repeat: no-repeat;
+ width: 16px;
+ height: 15px;
+ -moz-margin-start: 6px;
+}
+
+.click-to-play-plugins-notification-button-container {
+ background: linear-gradient(rgba(0,0,0,0.04) 60%, transparent);
+ padding: 10px;
+ margin-top: 5px;
+}
+
+.click-to-play-popup-button {
+ width: 50%;
+}
+
+.click-to-play-plugins-notification-description-box {
+ padding: 10px;
+}
+
+.click-to-play-plugins-outer-description {
+ margin-top: 8px;
+}
+
+.click-to-play-plugins-notification-link,
+.center-item-link {
+ margin: 0;
+}
diff --git a/themes/shared/plugins/notification-pluginAlert.png b/themes/shared/plugins/notification-pluginAlert.png
new file mode 100644
index 0000000..7492fdd
Binary files /dev/null and b/themes/shared/plugins/notification-pluginAlert.png differ
diff --git a/themes/shared/plugins/notification-pluginAlert@2x.png b/themes/shared/plugins/notification-pluginAlert@2x.png
new file mode 100644
index 0000000..f335996
Binary files /dev/null and b/themes/shared/plugins/notification-pluginAlert@2x.png differ
diff --git a/themes/shared/plugins/notification-pluginBlocked.png b/themes/shared/plugins/notification-pluginBlocked.png
new file mode 100644
index 0000000..e2e9489
Binary files /dev/null and b/themes/shared/plugins/notification-pluginBlocked.png differ
diff --git a/themes/shared/plugins/notification-pluginBlocked@2x.png b/themes/shared/plugins/notification-pluginBlocked@2x.png
new file mode 100644
index 0000000..5126be0
Binary files /dev/null and b/themes/shared/plugins/notification-pluginBlocked@2x.png differ
diff --git a/themes/shared/plugins/notification-pluginNormal.png b/themes/shared/plugins/notification-pluginNormal.png
new file mode 100644
index 0000000..979e92b
Binary files /dev/null and b/themes/shared/plugins/notification-pluginNormal.png differ
diff --git a/themes/shared/plugins/notification-pluginNormal@2x.png b/themes/shared/plugins/notification-pluginNormal@2x.png
new file mode 100644
index 0000000..c081bbb
Binary files /dev/null and b/themes/shared/plugins/notification-pluginNormal@2x.png differ
diff --git a/themes/shared/statusbar/dynamic.css b/themes/shared/statusbar/dynamic.css
new file mode 100644
index 0000000..2c53cb2
--- /dev/null
+++ b/themes/shared/statusbar/dynamic.css
@@ -0,0 +1,25 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+/* Progress bar/line styles */
+
+#status4evar-progress-bar[s4estyle="true"] > .progress-bar
+{
+ -moz-appearance: none;
+ background: #333399;
+ border-radius: 3px;
+}
+
+#status4evar-download-progress-bar[pmType^="active"] > .progress-bar
+{
+ background-color: #333399;
+}
+
+#status4evar-download-progress-bar[pmType^="paused"] > .progress-bar
+{
+ background-color: gray;
+}
+
diff --git a/themes/shared/statusbar/overlay.css b/themes/shared/statusbar/overlay.css
new file mode 100644
index 0000000..89b3dac
--- /dev/null
+++ b/themes/shared/statusbar/overlay.css
@@ -0,0 +1,169 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/*
+ * General styles
+ */
+
+#status4evar-status-widget,
+#status4evar-progress-widget
+{
+ -moz-box-align: center;
+}
+
+[forcevisible="true"]
+{
+ visibility: visible !important;
+}
+
+#wrapper-status4evar-progress-widget progressmeter,
+#wrapper-status4evar-download-button toolbarbutton
+{
+ visibility: visible;
+}
+
+#wrapper-status4evar-status-widget toolbaritem label
+{
+ background-color: rgba(0,0,0,0.2);
+ padding: 2px 4px;
+}
+
+/*
+ * Options button
+ */
+
+#status4evar-options-button
+{
+ list-style-image: url("chrome://browser/skin/statusbar/pms24.png");
+}
+
+toolbar[iconsize="small"] #status4evar-options-button
+{
+ list-style-image: url("chrome://browser/skin/statusbar/pms16.png");
+}
+
+/*
+ * Download status
+ */
+
+toolbar[mode="icons"] #status4evar-download-button[forcelabel="true"],
+toolbar[mode="text"] #status4evar-download-button
+{
+ -moz-box-orient: horizontal !important;
+}
+
+toolbar[mode="icons"] #status4evar-download-button[forcelabel="true"] > label
+{
+ display: -moz-box !important;
+}
+
+#status4evar-download-progress-bar
+{
+ border: 1px solid gray;
+ -moz-appearance: none;
+ margin: 0px;
+ min-height: 0px;
+ min-width: 0px;
+}
+
+#status4evar-download-progress-bar > *
+{
+ -moz-appearance: none;
+ background: #FFFFFF;
+}
+
+#status4evar-download-progress-bar[pmType$="unknown"] > .progress-bar
+{
+ background-image: url("chrome://browser/skin/statusbar/pulse.png");
+}
+
+#status4evar-download-notification-container
+{
+ min-height: 1px;
+ min-width: 1px;
+ height: 1px;
+ margin-bottom: -1px;
+ position: relative;
+ z-index: 5;
+}
+
+#status4evar-download-notification-icon
+{
+ opacity: 0;
+ background-size: 16px;
+ background-position: center;
+ background-repeat: no-repeat;
+ width: 16px;
+ height: 16px;
+}
+
+@keyframes status4evar-download-notification-finish
+{
+ from { opacity: 0; transform: scale(1); }
+ 20% { opacity: .65; animation-timing-function: ease-in; }
+ to { opacity: 0; transform: scale(8); }
+}
+
+#status4evar-download-notification-anchor[notification="finish"][forcevisible="true"] #status4evar-download-notification-icon
+{
+ background-image: url("chrome://browser/skin/downloads/download-notification-finish.png");
+ animation-name: status4evar-download-notification-finish;
+ animation-duration: 1s;
+}
+
+/*
+ * Splitter
+ */
+
+splitter.status4evar-status-splitter
+{
+ -moz-appearance: splitter;
+ border: none;
+ background: transparent;
+ position: relative;
+}
+
+splitter.status4evar-status-splitter:not(:hover)
+{
+ -moz-appearance: none;
+}
+
+/*
+ * General progress
+ */
+
+#status4evar-progress-bar[s4estyle="true"] > *
+{
+ border: none;
+}
+
+#status4evar-progress-bar > .progress-remainder
+{
+ background-image: none;
+ background-color: transparent;
+}
+
+#status4evar-progress-bar[s4estyle="true"] > .progress-bar
+{
+ border-right: 1px solid rgba(0,0,0,.2);
+}
+
+#status4evar-progress-bar[s4estyle="true"][value="0"] > .progress-bar,
+#status4evar-progress-bar[s4estyle="true"][value="100"] > .progress-bar
+{
+ border-right: none;
+}
+
+/*
+ * Status bar
+ */
+
+#status-bar > .statusbar-resizerpanel
+{
+ display: none !important;
+}
+
diff --git a/themes/shared/statusbar/pms16.png b/themes/shared/statusbar/pms16.png
new file mode 100644
index 0000000..830c586
Binary files /dev/null and b/themes/shared/statusbar/pms16.png differ
diff --git a/themes/shared/statusbar/pms24.png b/themes/shared/statusbar/pms24.png
new file mode 100644
index 0000000..cdc69b9
Binary files /dev/null and b/themes/shared/statusbar/pms24.png differ
diff --git a/themes/shared/statusbar/prefs.css b/themes/shared/statusbar/prefs.css
new file mode 100644
index 0000000..45b138f
--- /dev/null
+++ b/themes/shared/statusbar/prefs.css
@@ -0,0 +1,38 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#status4evar-prefs > prefpane > vbox.content-box
+{
+ min-height: 18em !important;
+}
+
+radio[pane="status4evar-pane-status"]
+{
+ list-style-image: url("chrome://global/skin/icons/information-32.png");
+}
+
+radio[pane="status4evar-pane-progress"]
+{
+ list-style-image: url("chrome://browser/skin/statusbar/throbberStatic.png");
+}
+
+radio[pane="status4evar-pane-download"]
+{
+ list-style-image: url("chrome://mozapps/skin/downloads/downloadIcon.png");
+}
+
+radio[pane="status4evar-pane-addonbar"]
+{
+ list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.png");
+}
+
+radio[pane="status4evar-pane-advanced"]
+{
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+ -moz-image-region: rect(0px, 224px, 32px, 192px);
+}
+
+
diff --git a/themes/shared/statusbar/pulse.png b/themes/shared/statusbar/pulse.png
new file mode 100644
index 0000000..374369c
Binary files /dev/null and b/themes/shared/statusbar/pulse.png differ
diff --git a/themes/shared/statusbar/throbber-idle.png b/themes/shared/statusbar/throbber-idle.png
new file mode 100644
index 0000000..bcdd65b
Binary files /dev/null and b/themes/shared/statusbar/throbber-idle.png differ
diff --git a/themes/shared/statusbar/throbberStatic.png b/themes/shared/statusbar/throbberStatic.png
new file mode 100644
index 0000000..e2bf274
Binary files /dev/null and b/themes/shared/statusbar/throbberStatic.png differ
diff --git a/themes/shared/tabbrowser/tab-audio-small.svg b/themes/shared/tabbrowser/tab-audio-small.svg
new file mode 100644
index 0000000..abfe712
--- /dev/null
+++ b/themes/shared/tabbrowser/tab-audio-small.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/shared/tabbrowser/tab-audio.svg b/themes/shared/tabbrowser/tab-audio.svg
new file mode 100644
index 0000000..274e10c
--- /dev/null
+++ b/themes/shared/tabbrowser/tab-audio.svg
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/Geolocation-16.png b/themes/windows/Geolocation-16.png
new file mode 100644
index 0000000..d710e73
Binary files /dev/null and b/themes/windows/Geolocation-16.png differ
diff --git a/themes/windows/Geolocation-64.png b/themes/windows/Geolocation-64.png
new file mode 100644
index 0000000..1bd46ba
Binary files /dev/null and b/themes/windows/Geolocation-64.png differ
diff --git a/themes/windows/Info.png b/themes/windows/Info.png
new file mode 100644
index 0000000..f9c6ef2
Binary files /dev/null and b/themes/windows/Info.png differ
diff --git a/themes/windows/KUI-background.png b/themes/windows/KUI-background.png
new file mode 100644
index 0000000..104a49f
Binary files /dev/null and b/themes/windows/KUI-background.png differ
diff --git a/themes/windows/KUI-close.png b/themes/windows/KUI-close.png
new file mode 100644
index 0000000..08eeb81
Binary files /dev/null and b/themes/windows/KUI-close.png differ
diff --git a/themes/windows/Makefile.in b/themes/windows/Makefile.in
new file mode 100644
index 0000000..173ca68
--- /dev/null
+++ b/themes/windows/Makefile.in
@@ -0,0 +1,7 @@
+# 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/.
+
+ICON_FILES := icon.png
+ICON_DEST = $(FINAL_TARGET)/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
+INSTALL_TARGETS += ICON
diff --git a/themes/windows/Privacy-16.png b/themes/windows/Privacy-16.png
new file mode 100644
index 0000000..f801bfe
Binary files /dev/null and b/themes/windows/Privacy-16.png differ
diff --git a/themes/windows/Privacy-32.png b/themes/windows/Privacy-32.png
new file mode 100644
index 0000000..41ecd5d
Binary files /dev/null and b/themes/windows/Privacy-32.png differ
diff --git a/themes/windows/Privacy-48.png b/themes/windows/Privacy-48.png
new file mode 100644
index 0000000..372b823
Binary files /dev/null and b/themes/windows/Privacy-48.png differ
diff --git a/themes/windows/Privacy-64.png b/themes/windows/Privacy-64.png
new file mode 100644
index 0000000..bd8d191
Binary files /dev/null and b/themes/windows/Privacy-64.png differ
diff --git a/themes/windows/Push-16.png b/themes/windows/Push-16.png
new file mode 100644
index 0000000..d710e73
Binary files /dev/null and b/themes/windows/Push-16.png differ
diff --git a/themes/windows/Push-64.png b/themes/windows/Push-64.png
new file mode 100644
index 0000000..27fecb8
Binary files /dev/null and b/themes/windows/Push-64.png differ
diff --git a/themes/windows/Secure24.png b/themes/windows/Secure24.png
new file mode 100644
index 0000000..265d79b
Binary files /dev/null and b/themes/windows/Secure24.png differ
diff --git a/themes/windows/Toolbar-glass.png b/themes/windows/Toolbar-glass.png
new file mode 100644
index 0000000..f8aac24
Binary files /dev/null and b/themes/windows/Toolbar-glass.png differ
diff --git a/themes/windows/Toolbar-glass.svg b/themes/windows/Toolbar-glass.svg
new file mode 100644
index 0000000..9feaac2
--- /dev/null
+++ b/themes/windows/Toolbar-glass.svg
@@ -0,0 +1,3218 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/Toolbar-inverted.png b/themes/windows/Toolbar-inverted.png
new file mode 100644
index 0000000..54d83bf
Binary files /dev/null and b/themes/windows/Toolbar-inverted.png differ
diff --git a/themes/windows/Toolbar-inverted.svg b/themes/windows/Toolbar-inverted.svg
new file mode 100644
index 0000000..ce59313
--- /dev/null
+++ b/themes/windows/Toolbar-inverted.svg
@@ -0,0 +1,302 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/Toolbar.png b/themes/windows/Toolbar.png
new file mode 100644
index 0000000..8ec756e
Binary files /dev/null and b/themes/windows/Toolbar.png differ
diff --git a/themes/windows/Toolbar.svg b/themes/windows/Toolbar.svg
new file mode 100644
index 0000000..7a68c06
--- /dev/null
+++ b/themes/windows/Toolbar.svg
@@ -0,0 +1,1356 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/aboutCertError.css b/themes/windows/aboutCertError.css
new file mode 100644
index 0000000..dbb3530
--- /dev/null
+++ b/themes/windows/aboutCertError.css
@@ -0,0 +1,73 @@
+/* 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/. */
+
+
+html {
+ background: #833;
+}
+
+body {
+ margin: 0;
+ padding: 0 1em;
+ color: -moz-FieldText;
+ font: message-box;
+}
+
+h1 {
+ margin: 0 0 .6em 0;
+ border-bottom: 1px solid ThreeDLightShadow;
+ font-size: 160%;
+}
+
+h2 {
+ font-size: 130%;
+}
+
+#errorPageContainer {
+ position: relative;
+ min-width: 13em;
+ max-width: 52em;
+ margin: 4em auto;
+ border: 2px solid #DD0D09;
+ border-radius: 10px;
+ box-shadow: 0px 0px 8px red;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat -moz-Field;
+ background-origin: content-box;
+}
+
+#errorPageContainer:-moz-dir(rtl) {
+ background-position: right 0;
+}
+
+#errorTitle {
+ -moz-margin-start: 80px;
+}
+
+#errorLongContent {
+ -moz-margin-start: 80px;
+}
+
+.expander > button {
+ -moz-padding-start: 20px;
+ -moz-margin-start: -20px;
+ background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
+ border: none;
+ font: inherit;
+ color: inherit;
+ cursor: pointer;
+}
+
+.expander > button:-moz-dir(rtl) {
+ background-position: right center;
+}
+
+.expander[collapsed] > button {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
+}
+
+.expander[collapsed] > button:-moz-dir(rtl) {
+ background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
+}
diff --git a/themes/windows/aboutCertError_sectionCollapsed-rtl.png b/themes/windows/aboutCertError_sectionCollapsed-rtl.png
new file mode 100644
index 0000000..84ba18c
Binary files /dev/null and b/themes/windows/aboutCertError_sectionCollapsed-rtl.png differ
diff --git a/themes/windows/aboutCertError_sectionCollapsed.png b/themes/windows/aboutCertError_sectionCollapsed.png
new file mode 100644
index 0000000..c9805f6
Binary files /dev/null and b/themes/windows/aboutCertError_sectionCollapsed.png differ
diff --git a/themes/windows/aboutCertError_sectionExpanded.png b/themes/windows/aboutCertError_sectionExpanded.png
new file mode 100644
index 0000000..128cef9
Binary files /dev/null and b/themes/windows/aboutCertError_sectionExpanded.png differ
diff --git a/themes/windows/aboutPrivateBrowsing.css b/themes/windows/aboutPrivateBrowsing.css
new file mode 100644
index 0000000..cd6026b
--- /dev/null
+++ b/themes/windows/aboutPrivateBrowsing.css
@@ -0,0 +1,47 @@
+%if 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/. */
+%endif
+
+body.private > #errorPageContainer {
+ background-image: url("chrome://browser/skin/Privacy-48.png");
+}
+
+body.normal > #errorPageContainer {
+ background-image: url("chrome://global/skin/icons/question-48.png");
+}
+
+#clearRecentHistoryDesc {
+ margin-top: 2em;
+}
+
+#clearRecentHistoryDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#startPrivateBrowsingDesc > button {
+ -moz-margin-start: 0;
+}
+
+#footerDesc > p {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+}
+
+#moreInfo {
+ font-size: 110%; /* to match the value set in chrome://global/skin/netError.css */
+ -moz-padding-start: 25px;
+ background: url("chrome://global/skin/icons/information-16.png") no-repeat top left;
+}
+
+#moreInfo:-moz-dir(rtl) {
+ background-position: top right;
+}
+
+#moreInfoText {
+ margin-bottom: 0;
+}
+
+#moreInfoLinkContainer {
+ margin-top: 0.5em;
+}
diff --git a/themes/windows/aboutSessionRestore-window-icon.png b/themes/windows/aboutSessionRestore-window-icon.png
new file mode 100644
index 0000000..0077405
Binary files /dev/null and b/themes/windows/aboutSessionRestore-window-icon.png differ
diff --git a/themes/windows/aboutSessionRestore.css b/themes/windows/aboutSessionRestore.css
new file mode 100644
index 0000000..4fa4907
--- /dev/null
+++ b/themes/windows/aboutSessionRestore.css
@@ -0,0 +1,73 @@
+%if 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/. */
+%endif
+
+html {
+ background: #f8ffd0;
+ height: 100%;
+}
+
+body {
+ height: 100%;
+ text-align: center;
+}
+
+#errorPageContainer {
+ background-image: url("chrome://global/skin/icons/warning-large.png");
+ display: -moz-box;
+ width: -moz-available;
+ max-width: 85%;
+ height: 75%;
+ max-height: 85%;
+ -moz-box-orient: vertical;
+ text-align: start;
+ border: 2px solid #efc;
+ box-shadow: 0px 0px 8px #aaa;
+}
+
+#errorShortDesc > p {
+ margin-top: 0.4em;
+ margin-bottom: 0;
+}
+
+#errorLongContent, #errorTrailerDesc {
+ display: -moz-box;
+ -moz-box-flex: 1;
+ -moz-box-orient: vertical;
+}
+
+#tabList {
+ margin-top: 2.5em;
+ width: 100%;
+ min-height: 12em;
+}
+
+treechildren::-moz-tree-image(icon),
+treechildren::-moz-tree-image(noicon) {
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+}
+
+treechildren::-moz-tree-image(noicon) {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+treechildren::-moz-tree-image(container, noicon) {
+ list-style-image: url("chrome://browser/skin/aboutSessionRestore-window-icon.png");
+}
+treechildren::-moz-tree-image(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-image(partial) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+#buttons {
+ width: 100%;
+}
+#buttons > button {
+ margin-top: 2em;
+}
diff --git a/themes/windows/aboutSyncTabs.css b/themes/windows/aboutSyncTabs.css
new file mode 100644
index 0000000..4f21a9d
--- /dev/null
+++ b/themes/windows/aboutSyncTabs.css
@@ -0,0 +1,101 @@
+/* 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/. */
+
+#tabs-display,
+#tabsList {
+ background-color: transparent;
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#tabsList {
+ width: 100%;
+}
+
+#tabs-display {
+ background: #fff url(chrome://browser/skin/sync-bg.png) repeat-x center -80px;
+}
+
+#headers {
+ background: url(chrome://browser/skin/sync-32.png) no-repeat;
+ margin-top: 4px;
+ width: 45em;
+ height: 32px;
+ -moz-margin-start: 2em;
+ -moz-margin-end: 2em;
+}
+
+#tabsListHeading {
+ font-size: 140%;
+ font-weight: bold;
+ -moz-margin-start: 40px;
+}
+
+richlistitem {
+ -moz-margin-end: 2em;
+}
+
+richlistitem[selected="true"],
+richlistitem:focus {
+ outline-style: none;
+}
+
+richlistitem[type="tab"] {
+ min-height: 3em;
+ border: #999999 1px solid !important;
+ padding: 2px 5px;
+ margin-bottom: 4px;
+ -moz-margin-start: 4em;
+ border-radius: 6px;
+ background-color: menu;
+ width: 44em;
+ opacity: 0.9;
+ box-shadow:
+ inset rgba(255, 255, 255, 0.5) 0 1px 0px,
+ inset rgba(0, 0, 0, 0.1) 0 -2px 0px,
+ rgba(0, 0, 0, 0.1) 0px 1px 0px;
+}
+
+richlistitem[type="tab"][selected="true"] {
+ background-color: -moz-MenuHover;
+}
+
+richlistitem[type="client"] {
+ min-height: 2em;
+ color: #000000;
+ -moz-margin-start: 2em;
+ margin-top: 2px;
+ margin-bottom: 3px;
+ width: 42em;
+ border-radius: 6px;
+ background-color: transparent;
+ -moz-user-focus: ignore !important;
+}
+richlistitem.mobile[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-mobileIcon.png");
+}
+richlistitem.desktop[type="client"] {
+ list-style-image: url("chrome://browser/skin/sync-desktopIcon.png");
+}
+
+.title,
+.clientName {
+ color: #000000;
+ font-size: 1.1em;
+}
+
+.title[selected="true"],
+.url[selected="true"] {
+ color: inherit;
+}
+
+.url {
+ color: -moz-nativehyperlinktext;
+ font-size: 0.95em;
+}
+
+.tabIcon {
+ -moz-padding-start: 2px;
+ padding-top: 2px;
+}
diff --git a/themes/windows/actionicon-tab.png b/themes/windows/actionicon-tab.png
new file mode 100644
index 0000000..ced958e
Binary files /dev/null and b/themes/windows/actionicon-tab.png differ
diff --git a/themes/windows/appmenu-dropmarker.png b/themes/windows/appmenu-dropmarker.png
new file mode 100644
index 0000000..27deaff
Binary files /dev/null and b/themes/windows/appmenu-dropmarker.png differ
diff --git a/themes/windows/appmenu-icons.png b/themes/windows/appmenu-icons.png
new file mode 100644
index 0000000..78f3658
Binary files /dev/null and b/themes/windows/appmenu-icons.png differ
diff --git a/themes/windows/autocomplete.css b/themes/windows/autocomplete.css
new file mode 100644
index 0000000..b3cab44
--- /dev/null
+++ b/themes/windows/autocomplete.css
@@ -0,0 +1,238 @@
+/* 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/. */
+
+/* ===== autocomplete.css =================================================
+ == Styles used by the autocomplete widget.
+ ======================================================================= */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+/* ::::: autocomplete ::::: */
+
+/* .padded is used by autocomplete widgets that don't have an icon. Gross. -dwh */
+textbox:not(.padded) {
+ cursor: default;
+ padding: 0;
+}
+
+textbox[nomatch="true"][highlightnonmatches="true"] {
+ color: red;
+}
+
+.private-autocomplete-textbox-container {
+ -moz-box-align: center;
+}
+
+textbox:not(.padded) .textbox-input-box {
+ margin: 0 3px;
+}
+
+.textbox-input-box {
+ -moz-box-align: center;
+}
+
+/* ::::: autocomplete popups ::::: */
+
+panel[type="private-autocomplete"],
+panel[type="private-autocomplete-richlistbox"],
+.private-autocomplete-history-popup {
+ -moz-appearance: none;
+ border-width: 1px;
+ -moz-border-top-colors: ThreeDShadow;
+ -moz-border-right-colors: ThreeDShadow;
+ -moz-border-bottom-colors: ThreeDShadow;
+ -moz-border-left-colors: ThreeDShadow;
+ padding: 0;
+ color: -moz-FieldText;
+ background-color: -moz-Field;
+}
+
+.private-autocomplete-history-popup {
+ max-height: 180px;
+}
+
+/* ::::: tree ::::: */
+
+.private-autocomplete-tree {
+ -moz-appearance: none !important;
+ border: none !important;
+ background-color: transparent !important;
+}
+
+.private-autocomplete-treecol {
+ -moz-appearance: none !important;
+ margin: 0 !important;
+ border: none !important;
+ padding: 0 !important;
+}
+
+/* GTK calculates space for a sort arrow */
+.private-autocomplete-treecol > .treecol-sortdirection {
+ -moz-appearance: none !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-cell-text {
+ -moz-padding-start: 8px;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-row(selected) {
+ background-color: Highlight;
+}
+
+treechildren.private-autocomplete-treebody::-moz-tree-cell-text(selected) {
+ color: HighlightText !important;
+}
+
+.private-autocomplete-treebody::-moz-tree-image(treecolAutoCompleteValue) {
+ max-width: 16px;
+ height: 16px;
+}
+
+/* ::::: richlistbox autocomplete ::::: */
+
+.private-autocomplete-richlistbox {
+ -moz-appearance: none;
+ margin: 0;
+}
+
+.private-autocomplete-richlistitem {
+ padding: 1px;
+}
+
+.private-autocomplete-richlistitem[selected="true"] {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+%ifdef XP_WIN
+@media (-moz-os-version: windows-vista) and (-moz-windows-default-theme),
+ (-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
+ .private-autocomplete-richlistitem[selected="true"] {
+ color: inherit;
+ background-color: transparent;
+ /* four gradients for the bevel highlights on each edge, one for blue background */
+ background-image:
+ linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
+ linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
+ linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
+ linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
+ linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
+ background-clip: content-box;
+ border-radius: 6px;
+ outline: 1px solid rgb(124,163,206);
+ -moz-outline-radius: 3px;
+ outline-offset: -2px;
+ }
+}
+%endif
+
+.ac-title-box {
+ margin-top: 4px;
+}
+
+.ac-url-box {
+ /* When setting a vertical margin here, half of that needs to be added
+ .ac-title-box's translateY for when .ac-url-box is hidden (see below). */
+ margin: 1px 0 4px;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-url-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-url-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-url-box {
+ visibility: hidden;
+}
+
+.private-autocomplete-richlistitem[actiontype="keyword"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="searchengine"] .ac-title-box,
+.private-autocomplete-richlistitem[actiontype="visiturl"] .ac-title-box,
+.private-autocomplete-richlistitem[type~="autofill"] .ac-title-box {
+ /* Center the title by moving it down by half of .ac-url-box's height,
+ including vertical margins (if any). */
+ transform: translateY(calc(.5em + 2px));
+}
+
+.ac-site-icon {
+ width: 16px;
+ height: 16px;
+ margin: 0 5px -2px;
+}
+
+.ac-type-icon {
+ width: 16px;
+ height: 16px;
+ -moz-margin-start: 6px;
+ -moz-margin-end: 4px;
+ margin-bottom: -1px;
+}
+
+.ac-url-box > .ac-site-icon,
+.ac-url-box > .ac-type-icon {
+ /* Otherwise the spacer is big enough to stretch its container */
+ height: auto;
+}
+
+.ac-extra > .ac-result-type-tag {
+ margin: 0 4px;
+}
+
+.ac-extra > .ac-comment {
+ padding-right: 4px;
+}
+
+.ac-ellipsis-after {
+ margin: 0 !important;
+ padding: 0;
+ min-width: 1em;
+}
+
+.ac-normal-text {
+ margin: 0 !important;
+ padding: 0;
+}
+
+.ac-normal-text > html|span {
+ margin: 0 !important;
+ padding: 0;
+}
+
+html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(208,208,208,0.5);
+ background-color: rgba(208,208,208,0.3);
+ border-radius: 2px;
+ text-shadow: 0 0 currentColor;
+}
+
+@media (-moz-windows-default-theme) {
+ @media not all and (-moz-os-version: windows-xp) {
+ html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(0,0,0,0.1);
+ background-color: rgba(0,0,0,0.05);
+ }
+ }
+
+ @media (-moz-os-version: windows-xp) {
+ .ac-url-text > html|span.ac-emphasize-text,
+ .ac-action-text > html|span.ac-emphasize-text {
+ box-shadow: inset 0 0 1px 1px rgba(202,214,201,0.3);
+ background-color: rgba(202,214,201,0.2);
+ }
+ }
+}
+
+.ac-title, .ac-url {
+ overflow: hidden;
+}
+
+/* ::::: textboxes inside toolbarpaletteitems ::::: */
+
+toolbarpaletteitem > toolbaritem > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
+
+toolbarpaletteitem > toolbaritem > * > textbox > hbox > hbox > html|*.textbox-input {
+ visibility: hidden;
+}
+
diff --git a/themes/windows/browser.css b/themes/windows/browser.css
new file mode 100644
index 0000000..88c3087
--- /dev/null
+++ b/themes/windows/browser.css
@@ -0,0 +1,3856 @@
+/* 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/. */
+
+@import url("chrome://global/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+%include ../shared/browser.inc
+%filter substitution
+%define toolbarShadowColor rgba(10%,10%,10%,.4)
+%define toolbarShadowOnTab linear-gradient(to top, rgba(10%,10%,10%,.4) 1px, transparent 1px)
+%define navbarTextboxCustomBorder border-color: rgba(0,0,0,.32);
+%define navbarLargeIcons #navigator-toolbox[iconsize=large][mode=icons] > #nav-bar
+%define forwardTransitionLength 150ms
+%define conditionalForwardWithUrlbar window:not([chromehidden~=toolbar]) #navigator-toolbox[iconsize=large][mode=icons] > :-moz-any(#nav-bar[currentset*="unified-back-forward-button"],#nav-bar:not([currentset])) > #unified-back-forward-button
+%define conditionalForwardWithUrlbar2 window:not([chromehidden~=toolbar]) #navigator-toolbox[iconsize=large][mode=icons] > :-moz-any(#nav-bar[currentset*="unified-back-forward-button"]:not([currentset*="unified-back-forward-button,urlbar-container"]),#nav-bar:not([currentset])) > #unified-back-forward-button
+%define conditionalForwardWithUrlbarWidth 27
+%define glassActiveBorderColor rgb(37, 44, 51)
+%define glassInactiveBorderColor rgb(102, 102, 102)
+
+%ifdef MOZ_OFFICIAL_BRANDING
+%define appMenuButtonBorderColor rgba(255,255,255,.5) rgba(6,42,83,.9)
+%else
+%if MOZ_UPDATE_CHANNEL == aurora
+%define appMenuButtonBorderColor hsla(0,0%,100%,.5) hsla(214,89%,21%,.9)
+%else
+%define appMenuButtonBorderColor hsla(0,0%,100%,.5) hsla(210,59%,13%,.9)
+%endif
+%endif
+
+:root {
+ --toolbox-after-color: ThreeDShadow;
+
+ --toolbar-custom-color: hsl(210,75%,92%);
+ --toolbar-highlight-top: rgba(255,255,255,.5);
+ --toolbar-highlight-bottom: transparent;
+
+ --toolbarbutton-background-color: hsla(210,32%,93%,.3);
+ --toolbarbutton-border-radius: 2.5px;
+ --toolbarbutton-border-color: hsla(210,54%,20%,.2);
+
+ --toolbarbutton-image: url("chrome://browser/skin/Toolbar.png");
+ --toolbarbutton-glass-image: url("chrome://browser/skin/Toolbar-glass.png");
+ --toolbarbutton-inverted-image: url("chrome://browser/skin/Toolbar-inverted.png");
+
+ --tab-background: linear-gradient(transparent, hsla(0,0%,45%,.1) 1px, hsla(0,0%,32%,.2) 80%, hsla(0,0%,0%,.2));
+ --tab-background-hover: linear-gradient(hsla(0,0%,100%,.3) 1px, hsla(0,0%,75%,.2) 80%, hsla(0,0%,60%,.2));
+ --tab-border-radius: 6px;
+ --tab-box-shadow: inset 0.5px 1px 1px var(--tab-selected-highlight);
+ --tab-selected-highlight: rgba(255,255,255,.7);
+
+ --window-text-color: currentColor;
+}
+
+/* Use SVG for HiDPI 133%+ */
+@media (min-resolution: 1.33dppx) {
+ :root {
+ --toolbarbutton-image: url("chrome://browser/skin/Toolbar.svg");
+ --toolbarbutton-glass-image: url("chrome://browser/skin/Toolbar-glass.svg");
+ --toolbarbutton-inverted-image: url("chrome://browser/skin/Toolbar-inverted.svg");
+ }
+}
+
+:root:-moz-lwtheme-brighttext {
+ --toolbar-highlight-top: rgba(32,32,32,.8);
+ --toolbar-highlight-bottom: rgba(32,32,32,0);
+}
+
+:root:-moz-lwtheme-darktext {
+ --toolbar-highlight-top: rgba(255,255,255,.8);
+
+ --tab-selected-highlight: rgba(255,255,255,.6);
+}
+
+#menubar-items {
+ -moz-box-orient: vertical; /* for flex hack */
+}
+
+#main-menubar {
+ -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
+}
+
+#navigator-toolbox {
+ -moz-appearance: none;
+ background-color: transparent;
+ border-top: none;
+}
+
+#navigator-toolbox::after {
+ content: "";
+ display: -moz-box;
+ -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
+ height: 1px;
+ background-color: var(--toolbox-after-color);
+}
+#navigator-toolbox[tabsontop=false]::after,
+#main-window[disablechrome] #navigator-toolbox::after {
+ visibility: collapse;
+}
+
+#navigator-toolbox > toolbar:not(:-moz-lwtheme) {
+ -moz-appearance: none;
+ border-style: none;
+ background-color: -moz-Dialog;
+}
+
+@media not all and (-moz-windows-compositor) {
+ #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar[inactive] ~ #TabsToolbar:not(:-moz-lwtheme) {
+ background: linear-gradient(to top, @toolbarShadowColor@ 1px, transparent 1px),
+ linear-gradient(rgba(50%,50%,50%,0), ActiveCaption 85%);
+ color: CaptionText;
+ }
+ #main-window[tabsintitlebar]:not([inFullscreen]) #toolbar-menubar[inactive] ~ #TabsToolbar:not(:-moz-lwtheme):-moz-window-inactive {
+ background: linear-gradient(to top, @toolbarShadowColor@ 1px, transparent 1px),
+ linear-gradient(rgba(50%,50%,50%,0), InactiveCaption 85%);
+ color: InactiveCaptionText;
+ }
+
+ #main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
+ visibility: hidden;
+ }
+ #main-window[tabsintitlebar] #titlebar-content:-moz-lwtheme {
+ -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
+ visibility: visible;
+ }
+
+ #main-menubar > menu:not(:-moz-lwtheme) {
+ color: inherit; /* allow menubar items to be styled */
+ }
+}
+
+#nav-bar[tabsontop=true],
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar {
+ background-image: linear-gradient(var(--toolbar-highlight-top), var(--toolbar-highlight-bottom));
+}
+
+#personal-bookmarks {
+ min-height: 24px;
+}
+
+#print-preview-toolbar:not(:-moz-lwtheme) {
+ -moz-appearance: toolbox;
+}
+
+#browser-bottombox:not(:-moz-lwtheme) {
+ background-color: -moz-dialog;
+}
+
+/* ::::: app menu button ::::: */
+
+#appmenu-button {
+ -moz-appearance: none;
+ background-clip: padding-box;
+ border: 1px solid;
+ border-top: none;
+ color: white;
+ text-shadow: 0 0 1px rgba(0,0,0,.7),
+ 0 1px 1.5px rgba(0,0,0,.5);
+ font-weight: bold;
+ padding: 0 1.5em .05em;
+ margin: 0 0 2px;
+}
+
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ #appmenu-button {
+ border-radius: 0 0 4px 4px;
+ }
+}
+
+@media (-moz-windows-classic) {
+ #appmenu-button {
+ margin-bottom: 1px;
+ }
+}
+
+#appmenu-button:hover:active,
+#appmenu-button[open] {
+ border-radius: 0;
+}
+
+%ifdef MOZ_OFFICIAL_BRANDING
+#appmenu-button {
+ background-image: linear-gradient(rgb(82,182,247), rgb(10,98,215) 95%);
+ border-color: rgba(6,42,83,.9);
+ box-shadow: 0 1px 0 rgba(255,255,255,.25) inset,
+ 0 0 0 1px rgba(255,255,255,.25) inset;
+}
+#appmenu-button:hover:not(:active):not([open]) {
+ background-image: radial-gradient(farthest-side at bottom, rgba(89,240,252,.5) 10%, rgba(89,240,252,0) 70%),
+ radial-gradient(farthest-side at bottom, rgb(60,68,236), rgba(172,229,255,0)),
+ linear-gradient(rgb(69,170,246), rgb(30,40,209) 95%);
+ border-color: rgba(6,42,83,.9);
+ box-shadow: 0 1px 0 rgba(255,255,255,.1) inset,
+ 0 0 2px 1px rgba(169,234,250,.7) inset,
+ 0 -1px 0 rgba(169,234,250,.5) inset;
+}
+#appmenu-button:hover:active,
+#appmenu-button[open] {
+ background-image: linear-gradient(rgb(69,170,246), rgb(0,74,209) 95%);
+ box-shadow: 0 2px 3px rgba(0,0,0,.4) inset,
+ 0 1px 1px rgba(0,0,0,.2) inset;
+}
+%else
+%if MOZ_UPDATE_CHANNEL == aurora
+#appmenu-button {
+ background-image: linear-gradient(hsl(208,99%,37%), hsl(214,90%,23%) 95%);
+ border-color: hsla(214,89%,21%,.9);
+ box-shadow: 0 1px 0 hsla(205,100%,72%,.2) inset,
+ 0 0 2px 1px hsla(205,100%,72%,.25) inset;
+}
+#appmenu-button:hover:not(:active):not([open]) {
+ background-image: radial-gradient(farthest-side at bottom, hsla(202,100%,85%,.5) 10%, hsla(202,100%,85%,0) 70%),
+ radial-gradient(farthest-side at bottom, hsla(205,100%,72%,.7), hsla(205,100%,72%,0)),
+ linear-gradient(hsl(208,98%,34%), hsl(213,87%,20%) 95%);
+ border-color: hsla(214,89%,21%,.9);
+ box-shadow: 0 1px 0 hsla(205,100%,72%,.15) inset,
+ 0 0 2px 1px hsla(205,100%,72%,.5) inset,
+ 0 -1px 0 hsla(205,100%,72%,.2) inset;
+}
+#appmenu-button:hover:active,
+#appmenu-button[open] {
+ background-image: linear-gradient(hsl(208,95%,30%), hsl(214,85%,17%) 95%);
+ box-shadow: 0 2px 3px rgba(0,0,0,.4) inset,
+ 0 1px 1px rgba(0,0,0,.2) inset;
+}
+%else
+#appmenu-button {
+ background-image: linear-gradient(hsl(211,33%,32%), hsl(209,53%,10%) 95%);
+ border-color: hsla(210,59%,13%,.9);
+ box-shadow: 0 1px 0 hsla(210,48%,90%,.15) inset,
+ 0 0 2px 1px hsla(211,65%,85%,.15) inset;
+}
+#appmenu-button:hover:not(:active):not([open]) {
+ background-image: radial-gradient(farthest-side at bottom, hsla(210,48%,90%,.5) 10%, hsla(210,48%,90%,0) 70%),
+ radial-gradient(farthest-side at bottom, hsla(211,70%,83%,.5), hsla(211,70%,83%,0)),
+ linear-gradient(hsl(211,33%,32%), hsl(209,53%,10%) 95%);
+ border-color: hsla(210,59%,13%,.9);
+ box-shadow: 0 1px 0 hsla(210,48%,90%,.15) inset,
+ 0 0 2px 1px hsla(210,48%,90%,.4) inset,
+ 0 -1px 0 hsla(210,48%,90%,.2) inset;
+}
+#appmenu-button:hover:active,
+#appmenu-button[open] {
+ background-image: linear-gradient(hsl(211,33%,26%), hsl(209,53%,6%) 95%);
+ box-shadow: 0 2px 3px rgba(0,0,0,.4) inset,
+ 0 1px 1px rgba(0,0,0,.2) inset;
+}
+%endif
+%endif
+
+#main-window[privatebrowsingmode=temporary] #appmenu-button {
+ background-image: linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%);
+ border-color: rgba(43,8,65,.9);
+}
+
+#main-window[privatebrowsingmode=temporary] #appmenu-button:hover:not(:active):not([open]) {
+ background-image: radial-gradient(farthest-side at bottom, rgba(240,193,255,.5) 10%, rgba(240,193,255,0) 70%),
+ radial-gradient(farthest-side at bottom, rgb(192,81,247), rgba(236,172,255,0)),
+ linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%);
+ border-color: rgba(43,8,65,.9);
+ box-shadow: 0 1px 0 rgba(255,255,255,.1) inset,
+ 0 0 2px 1px rgba(240,193,255,.7) inset,
+ 0 -1px 0 rgba(240,193,255,.5) inset;
+}
+
+#main-window[privatebrowsingmode=temporary] #appmenu-button:hover:active,
+#main-window[privatebrowsingmode=temporary] #appmenu-button[open] {
+ background-image: linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%);
+}
+
+
+
+#appmenu-button > .button-box {
+ border-style: none;
+ padding: 0;
+}
+
+#appmenu-button > .button-box > .button-menu-dropmarker {
+ list-style-image: url(appmenu-dropmarker.png);
+ width: auto;
+ height: auto;
+ padding: 0;
+ margin: 0;
+ -moz-margin-start: .5em;
+}
+
+.splitmenu-menuitem {
+ -moz-margin-end: 1px;
+ -moz-padding-end: 0.5em;
+}
+
+.splitmenu-menu {
+ -moz-box-pack: end;
+}
+
+.appmenu-edit-button {
+ -moz-appearance: none;
+ border: 1px solid transparent;
+ padding: 2px;
+ background: transparent;
+ border-radius: 3px;
+}
+
+.appmenu-edit-button[disabled="true"] {
+ opacity: .3;
+}
+
+#appmenuPrimaryPane {
+ -moz-border-end: 1px solid ThreeDShadow;
+}
+
+@media (-moz-windows-default-theme) {
+ #appmenu-popup {
+ -moz-appearance: none;
+ background: white;
+ border: 1px solid ThreeDShadow;
+ }
+ #appmenuPrimaryPane {
+ background-color: rgba(255,255,255,0.5);
+ padding: 2px;
+ -moz-border-end: none;
+ }
+ #appmenuSecondaryPane {
+ background-color: #f1f5fb;
+ box-shadow: 1px 0 2px rgb(204,214,234) inset;
+ -moz-padding-start: 3px;
+ -moz-padding-end: 2px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ font-family: "Segoe UI Semibold", "Segoe UI", sans-serif;
+ }
+ #appmenuSecondaryPane:-moz-locale-dir(rtl) {
+ box-shadow: -1px 0 2px rgb(204,214,234) inset;
+ }
+
+ #appmenuPrimaryPane menupopup {
+ -moz-appearance: none;
+ background-image: linear-gradient(to right, white 26px, ThreeDLightShadow 26px,
+ ThreeDLightShadow 27px, ThreeDHighlight 27px,
+ ThreeDHighlight 28px, white 28px);
+ border: 3px solid;
+ -moz-border-top-colors: ThreeDShadow white;
+ -moz-border-bottom-colors: ThreeDShadow white;
+ -moz-border-left-colors: ThreeDShadow white;
+ -moz-border-right-colors: ThreeDShadow white;
+ }
+
+ #appmenuSecondaryPane menupopup {
+ -moz-appearance: none;
+ background-image: linear-gradient(to right, #f1f5fb 26px, ThreeDLightShadow 26px,
+ ThreeDLightShadow 27px, ThreeDHighlight 27px,
+ ThreeDHighlight 28px, #f1f5fb 28px);
+ border: 3px solid;
+ -moz-border-top-colors: ThreeDShadow #f1f5fb;
+ -moz-border-bottom-colors: ThreeDShadow #f1f5fb;
+ -moz-border-left-colors: ThreeDShadow #f1f5fb;
+ -moz-border-right-colors: ThreeDShadow #f1f5fb;
+ }
+
+ #appmenuPrimaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, white 26px, ThreeDLightShadow 26px,
+ ThreeDLightShadow 27px, ThreeDHighlight 27px,
+ ThreeDHighlight 28px, white 28px);
+ }
+ #appmenuSecondaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, #f1f5fb 26px, ThreeDLightShadow 26px,
+ ThreeDLightShadow 27px, ThreeDHighlight 27px,
+ ThreeDHighlight 28px, #f1f5fb 28px);
+ }
+
+ /* Hi-DPI overrides of the menu backgrounds, to adjust where the gutter line falls */
+ @media (min-resolution: 1.25dppx) {
+ #appmenuPrimaryPane menupopup {
+ background-image: linear-gradient(to right, white 22.4px, ThreeDLightShadow 22.4px,
+ ThreeDLightShadow 23.2px, ThreeDHighlight 23.2px,
+ ThreeDHighlight 24px, white 24px);
+ }
+ #appmenuSecondaryPane menupopup {
+ background-image: linear-gradient(to right, #f1f5fb 22.4px, ThreeDLightShadow 22.4px,
+ ThreeDLightShadow 23.2px, ThreeDHighlight 23.2px,
+ ThreeDHighlight 24px, #f1f5fb 24px);
+ }
+ #appmenuPrimaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, white 22.4px, ThreeDLightShadow 22.4px,
+ ThreeDLightShadow 23.2px, ThreeDHighlight 23.2px,
+ ThreeDHighlight 24px, white 24px);
+ }
+ #appmenuSecondaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, #f1f5fb 22.4px, ThreeDLightShadow 22.4px,
+ ThreeDLightShadow 23.2px, ThreeDHighlight 23.2px,
+ ThreeDHighlight 24px, #f1f5fb 24px);
+ }
+ }
+
+ @media (min-resolution: 1.5dppx) {
+ #appmenuPrimaryPane menupopup {
+ background-image: linear-gradient(to right, white 20.6667px, ThreeDLightShadow 20.6667px,
+ ThreeDLightShadow 21.3333px, ThreeDHighlight 21.3333px,
+ ThreeDHighlight 22px, white 22px);
+ }
+ #appmenuSecondaryPane menupopup {
+ background-image: linear-gradient(to right, #f1f5fb 20.6667px, ThreeDLightShadow 20.6667px,
+ ThreeDLightShadow 21.3333px, ThreeDHighlight 21.3333px,
+ ThreeDHighlight 22px, #f1f5fb 22px);
+ }
+ #appmenuPrimaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, white 20.6667px, ThreeDLightShadow 20.6667px,
+ ThreeDLightShadow 21.3333px, ThreeDHighlight 21.3333px,
+ ThreeDHighlight 22px, white 22px);
+ }
+ #appmenuSecondaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, #f1f5fb 20.6667px, ThreeDLightShadow 20.6667px,
+ ThreeDLightShadow 21.3333px, ThreeDHighlight 21.3333px,
+ ThreeDHighlight 22px, #f1f5fb 22px);
+ }
+ }
+
+ @media (min-resolution: 2dppx) {
+ #appmenuPrimaryPane menupopup {
+ background-image: linear-gradient(to right, white 19.5px, ThreeDLightShadow 19.5px,
+ ThreeDLightShadow 20px, ThreeDHighlight 20px,
+ ThreeDHighlight 20.5px, white 20.5px);
+ }
+ #appmenuSecondaryPane menupopup {
+ background-image: linear-gradient(to right, #f1f5fb 19.5px, ThreeDLightShadow 19.5px,
+ ThreeDLightShadow 20px, ThreeDHighlight 20px,
+ ThreeDHighlight 20.5px, #f1f5fb 20.5px);
+ }
+ #appmenuPrimaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, white 19.5px, ThreeDLightShadow 19.5px,
+ ThreeDLightShadow 20px, ThreeDHighlight 20px,
+ ThreeDHighlight 20.5px, white 20.5px);
+ }
+ #appmenuSecondaryPane menupopup:-moz-locale-dir(rtl) {
+ background-image: linear-gradient(to left, #f1f5fb 19.5px, ThreeDLightShadow 19.5px,
+ ThreeDLightShadow 20px, ThreeDHighlight 20px,
+ ThreeDHighlight 20.5px, #f1f5fb 20.5px);
+ }
+ }
+
+ .appmenu-menuseparator {
+ -moz-appearance: none;
+ margin-top: 3px;
+ margin-bottom: 3px;
+ -moz-margin-start: 30px;
+ padding: 0;
+ border-top: 1px solid #d6e5f5;
+ border-bottom: none;
+ }
+
+ @media (min-resolution: 1.25dppx) {
+ .appmenu-menuseparator {
+ -moz-margin-start: 25px;
+ }
+ }
+ @media (min-resolution: 1.5dppx) {
+ .appmenu-menuseparator {
+ -moz-margin-start: 24px;
+ }
+ }
+ @media (min-resolution: 2dppx) {
+ .appmenu-menuseparator {
+ -moz-margin-start: 22px;
+ }
+ }
+
+ .appmenu-edit-button:not([disabled]):hover {
+ border: 1px solid #b8d6fb;
+ box-shadow: inset 0 0 1px white;
+ background: linear-gradient(#fafbfd, #ebf3fd);
+ transition: .2s ease-in;
+ }
+}
+
+#appmenuSecondaryPane-spacer {
+ min-height: 1em;
+}
+
+#appmenu-editmenu {
+ -moz-box-pack: end;
+}
+
+#appmenu_print,
+#appmenu_print_popup,
+.appmenu-edit-button,
+#appmenu-editmenu-cut,
+#appmenu-editmenu-copy,
+#appmenu-editmenu-paste,
+#appmenu-quit {
+ list-style-image: url("appmenu-icons.png");
+}
+
+#appmenu-cut,
+#appmenu-editmenu-cut {
+ -moz-image-region: rect(0 16px 16px 0);
+}
+
+#appmenu-copy,
+#appmenu-editmenu-copy {
+ -moz-image-region: rect(0 32px 16px 16px);
+}
+
+#appmenu-paste,
+#appmenu-editmenu-paste {
+ -moz-image-region: rect(0 48px 16px 32px);
+}
+
+#appmenu_print,
+#appmenu_print_popup {
+ -moz-image-region: rect(0 64px 16px 48px);
+}
+
+#appmenu-quit {
+ -moz-image-region: rect(0 80px 16px 64px);
+}
+
+#appmenu-edit-label {
+ -moz-appearance: none;
+ background: transparent;
+ font-style: italic;
+}
+
+#appmenu_bookmarks {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+#appmenu_privateBrowsing,
+#appmenu_newPrivateWindow {
+ list-style-image: url("chrome://browser/skin/Privacy-16.png");
+}
+
+@media (min-resolution: 1.25dppx) {
+ #appmenu_privateBrowsing,
+ #appmenu_newPrivateWindow {
+ list-style-image: url("chrome://browser/skin/Privacy-32.png");
+ }
+}
+
+#appmenu_addons {
+ list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
+}
+
+@media (min-resolution: 1.25dppx) {
+ #appmenu_addons {
+ list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.png");
+ }
+}
+
+#appmenu_showAllBookmarks,
+#bookmarksShowAll,
+#BMB_bookmarksShowAll {
+ list-style-image: url("chrome://browser/skin/places/allBookmarks.png");
+}
+
+#appmenu_bookmarkThisPage,
+#menu_bookmarkThisPage,
+#BMB_bookmarkThisPage {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0 16px 16px 0);
+}
+
+#appmenu_showAllHistory,
+#menu_showAllHistory,
+#HMB_showAllHistory {
+ list-style-image: url("chrome://browser/skin/places/history.png");
+}
+
+#appmenu_sanitizeHistory,
+#sanitizeItem,
+#HMB_sanitizeItem {
+ list-style-image: url("chrome://browser/skin/sanitize.png");
+}
+
+/* ::::: titlebar ::::: */
+
+#main-window[sizemode="normal"] > #titlebar {
+ -moz-appearance: -moz-window-titlebar;
+}
+
+#main-window[sizemode="maximized"] > #titlebar {
+ -moz-appearance: -moz-window-titlebar-maximized;
+}
+
+@media (-moz-windows-classic) {
+ #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container {
+ margin-top: 4px;
+ }
+}
+
+#titlebar-buttonbox {
+ -moz-appearance: -moz-window-button-box;
+}
+
+#main-window[sizemode="maximized"] #titlebar-buttonbox {
+ -moz-appearance: -moz-window-button-box-maximized;
+}
+
+.titlebar-placeholder[type="appmenu-button"] {
+ margin-left: 4px;
+}
+
+.titlebar-placeholder[type="caption-buttons"] {
+ margin-left: 22px; /* additional space for Aero Snap */
+}
+
+/* titlebar command buttons */
+
+#titlebar-min {
+ -moz-appearance: -moz-window-button-minimize;
+}
+
+#titlebar-max {
+ -moz-appearance: -moz-window-button-maximize;
+}
+
+#main-window[sizemode="maximized"] #titlebar-max {
+ -moz-appearance: -moz-window-button-restore;
+}
+
+#titlebar-close {
+ -moz-appearance: -moz-window-button-close;
+}
+
+@media not all and (-moz-windows-classic) {
+ #titlebar-min {
+ -moz-margin-end: 2px;
+ }
+}
+
+/* ::::: bookmark buttons ::::: */
+
+toolbarbutton.bookmark-item {
+ margin: 0;
+ padding: 2px 3px;
+}
+
+toolbarbutton.bookmark-item:hover:active:not([disabled="true"]),
+toolbarbutton.bookmark-item[open="true"] {
+ padding-top: 3px;
+ padding-bottom: 1px;
+ -moz-padding-start: 4px;
+ -moz-padding-end: 2px;
+}
+
+.bookmark-item:not(#bookmarks-menu-button) > .toolbarbutton-icon {
+ width: 16px;
+ height: 16px;
+}
+
+/* Prevent [mode="icons"] from hiding the label */
+.bookmark-item > .toolbarbutton-text {
+ display: -moz-box !important;
+}
+
+.bookmark-item > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+#wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
+ background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
+}
+
+.bookmarks-toolbar-customize {
+ max-width: 15em !important;
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+}
+
+/* ::::: bookmark menus ::::: */
+
+menu.bookmark-item,
+menuitem.bookmark-item {
+ min-width: 0;
+ max-width: 32em;
+}
+
+.bookmark-item > .menu-iconic-left {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.bookmark-item > .menu-iconic-left > .menu-iconic-icon {
+ -moz-padding-start: 0px;
+}
+
+/* ::::: bookmark items ::::: */
+
+.bookmark-item {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.bookmark-item[container] {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.bookmark-item[container][open] {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.bookmark-item[container][livemark] {
+ list-style-image: url("chrome://browser/skin/livemark-folder.png");
+ -moz-image-region: auto;
+}
+
+.bookmark-item[container][livemark] .bookmark-item {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.bookmark-item[container][livemark] .bookmark-item[visited] {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.bookmark-item[container][query] {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+ -moz-image-region: auto;
+}
+
+.bookmark-item[query][tagContainer] {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ -moz-image-region: auto;
+}
+
+.bookmark-item[query][dayContainer] {
+ list-style-image: url("chrome://browser/skin/places/calendar.png");
+ -moz-image-region: auto;
+}
+
+.bookmark-item[query][hostContainer] {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.bookmark-item[query][hostContainer][open] {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.bookmark-item[cutting] > .toolbarbutton-icon,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
+ opacity: 0.5;
+}
+
+.bookmark-item[cutting] > .toolbarbutton-text,
+.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
+ opacity: 0.7;
+}
+
+/* ::::: primary toolbar buttons ::::: */
+
+.toolbarbutton-1 {
+ list-style-image: var(--toolbarbutton-image);
+}
+
+toolbar[brighttext] .toolbarbutton-1 {
+ list-style-image: var(--toolbarbutton-inverted-image);
+}
+
+.toolbarbutton-1:not(:-moz-lwtheme) {
+ list-style-image: var(--toolbarbutton-glass-image);
+}
+
+.toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-dropmarker,
+.toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+.toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
+}
+
+toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
+toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
+}
+
+.toolbarbutton-1 > .toolbarbutton-icon,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ -moz-margin-end: 0;
+}
+
+toolbar[mode=full] .toolbarbutton-1:not([type=menu-button]) {
+ -moz-box-orient: vertical;
+}
+
+toolbar[mode=full] .toolbarbutton-1,
+toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ min-width: 57px;
+}
+
+#nav-bar {
+ /* force iconsize="small" on this toolbar */
+ counter-reset: smallicons;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ -moz-appearance: none;
+ border: none;
+ padding: 0;
+ background: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not([type=menu-button]),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ padding: 5px 2px;
+ -moz-box-pack: center;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button) {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > menupopup {
+ margin-top: -3px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button {
+ -moz-padding-end: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+ -moz-padding-start: 0;
+ -moz-box-align: center;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+ padding: 2px 6px;
+ background: var(--toolbarbutton-background-color) padding-box;
+ background-image: linear-gradient(hsla(0,0%,100%,.4), hsla(0,0%,100%,.1));
+ background-clip: padding-box;
+ border-radius: var(--toolbarbutton-border-radius);
+ border: 1px solid;
+ border-color: var(--toolbarbutton-border-color) var(--toolbarbutton-border-color) var(--toolbarbutton-border-color);
+ box-shadow: 0 1px hsla(0,0%,100%,.05) inset,
+ 0 1px hsla(210,54%,20%,.05),
+ 0 0 2px hsla(210,54%,20%,.05);
+}
+
+@media (-moz-os-version: windows-win10) {
+ /* Square is the new round, courtesy of microsoft */
+ :root {
+ --toolbarbutton-border-radius: 0px;
+ }
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1:not(:-moz-any(@primaryToolbarButtons@)) > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ padding: 3px 7px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[type=menu]:not(#back-button):not(#forward-button):not(#feed-button) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1[type=menu] > .toolbarbutton-text /* hack for add-ons that forcefully display the label */ {
+ -moz-padding-end: 17px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
+ -moz-margin-start: -15px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+ -moz-border-end: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+ padding: 8px 5px 7px;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before {
+ content: "";
+ display: -moz-box;
+ width: 1px;
+ height: 18px;
+ -moz-margin-end: -1px;
+ background-image: linear-gradient(var(--toolbarbutton-border-color) 0, var(--toolbarbutton-border-color) 18px);
+ background-clip: padding-box;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 1px 18px;
+ box-shadow: 0 0 0 1px hsla(0,0%,100%,.2);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(ltr),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(rtl) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon:-moz-locale-dir(rtl),
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-locale-dir(ltr) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):hover > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+ background-image: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.5));
+ border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.3) hsla(210,54%,20%,.35);
+ box-shadow: 0 1px hsla(0,0%,100%,.3) inset,
+ 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):not([open]):not(:active):hover > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
+ background-color: hsla(210,48%,96%,.75);
+ border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
+ box-shadow: 0 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1:not([disabled]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack,
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover:active > .toolbarbutton-icon,
+@navbarLargeIcons@ .toolbarbutton-1[open] > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
+ background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
+ background-color: hsla(210,54%,20%,.15);
+ border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
+ box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
+ 0 0 1px var(--toolbarbutton-border-color) inset,
+ /* allows windows-keyhole-forward-clip-path to be used for non-hover as well as hover: */
+ 0 1px 0 hsla(210,54%,20%,0),
+ 0 0 2px hsla(210,54%,20%,0);
+ text-shadow: none;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1:-moz-any(:hover,[open]) > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon {
+ -moz-border-start-color: hsla(210,54%,20%,.35);
+}
+
+@navbarLargeIcons@ .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon {
+ background-color: rgba(90%,90%,90%,.4);
+ transition: background-color .4s;
+}
+
+:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1,
+:-moz-any(#TabsToolbar, #addon-bar) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.tabbrowser-arrowscrollbox > .scrollbutton-up,
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ -moz-appearance: none;
+ border-style: none;
+ padding: 0 3px;
+}
+
+#TabsToolbar .toolbarbutton-1:not([disabled]):hover,
+#TabsToolbar .toolbarbutton-1[open],
+#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover,
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):hover,
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):hover {
+ background-image: linear-gradient(var(--toolbar-highlight-bottom), var(--toolbar-highlight-top)),
+ linear-gradient(transparent, rgba(0,0,0,.25) 30%),
+ linear-gradient(transparent, rgba(0,0,0,.25) 30%);
+ background-position: 1px -1px, 0 -1px, 100% -1px;
+ background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
+ background-repeat: no-repeat;
+}
+
+#addon-bar .toolbarbutton-1:not([disabled]):hover,
+#addon-bar .toolbarbutton-1[open],
+#addon-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover {
+ background-image: linear-gradient(to top, transparent, rgba(0,0,0,.15)),
+ linear-gradient(to top, transparent, rgba(0,0,0,.15) 30%),
+ linear-gradient(to top, transparent, rgba(0,0,0,.15) 30%);
+ background-position: left, left, right;
+ background-size: auto, 1px 100%, 1px 100%;
+ background-repeat: no-repeat;
+}
+
+/* unified back/forward button */
+
+#back-button {
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#forward-button {
+ -moz-image-region: rect(0, 36px, 18px, 18px);
+}
+
+#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#forward-button:-moz-locale-dir(rtl),
+#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-text {
+ transform: scaleX(-1);
+}
+
+@conditionalForwardWithUrlbar@ {
+ -moz-box-align: center;
+}
+
+@conditionalForwardWithUrlbar@ > .toolbarbutton-1:-moz-any([disabled],:not([disabled]):not([open]):not(:active)) > .toolbarbutton-icon {
+ border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.3) hsla(210,54%,20%,.35);
+ box-shadow: 0 1px hsla(0,0%,100%,.3) inset,
+ 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button {
+ padding: 0;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button > menupopup {
+ margin-top: 1px;
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button > .toolbarbutton-icon {
+ clip-path: url(chrome://browser/content/browser.xul#windows-keyhole-forward-clip-path);
+ -moz-margin-start: -6px !important;
+ border-left-style: none;
+ border-radius: 0;
+ padding-left: 7px;
+ padding-right: 3px;
+}
+
+@conditionalForwardWithUrlbar2@ > #forward-button:-moz-locale-dir(ltr) > .toolbarbutton-icon {
+ border-top-right-radius: var(--toolbarbutton-border-radius);
+ border-bottom-right-radius: var(--toolbarbutton-border-radius);
+}
+
+@conditionalForwardWithUrlbar2@ > #forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ border-top-left-radius: var(--toolbarbutton-border-radius);
+ border-bottom-left-radius: var(--toolbarbutton-border-radius);
+}
+
+@conditionalForwardWithUrlbar@ > #forward-button:not([disabled]):not([open]):not(:active):hover > .toolbarbutton-icon {
+ background-color: hsla(210,48%,96%,.75);
+ border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
+ box-shadow: 0 0 1px hsla(210,54%,20%,.03),
+ 0 0 2px hsla(210,54%,20%,.1);
+}
+
+@conditionalForwardWithUrlbar@ > #back-button {
+ -moz-image-region: rect(18px, 20px, 38px, 0);
+ padding-top: 3px;
+ padding-bottom: 3px;
+ -moz-padding-start: 5px;
+ -moz-padding-end: 0;
+ position: relative;
+ z-index: 1;
+ border-radius: 0 10000px 10000px 0;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:-moz-locale-dir(rtl) {
+ border-radius: 10000px 0 0 10000px;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button > menupopup {
+ margin-top: -1px;
+}
+
+@conditionalForwardWithUrlbar@ > #back-button > .toolbarbutton-icon {
+ border-radius: 10000px;
+ padding: 5px;
+ border: none;
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(210,54%,20%,.25),
+ 0 1px 0 hsla(210,54%,20%,.35);
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover > .toolbarbutton-icon {
+ background-color: hsla(210,48%,96%,.75);
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(0,0%,100%,.3) inset,
+ 0 0 0 1px hsla(210,54%,20%,.3),
+ 0 1px 0 hsla(210,54%,20%,.4),
+ 0 0 4px var(--toolbarbutton-border-color);
+}
+
+@conditionalForwardWithUrlbar@ > #back-button:not([disabled="true"]):hover:active > .toolbarbutton-icon,
+@conditionalForwardWithUrlbar@ > #back-button[open="true"] > .toolbarbutton-icon {
+ background-color: hsla(210,54%,20%,.15);
+ box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
+ 0 0 1px var(--toolbarbutton-border-color) inset,
+ 0 0 0 1px hsla(210,54%,20%,.4),
+ 0 1px 0 var(--toolbarbutton-border-color);
+}
+
+@conditionalForwardWithUrlbar@ > #back-button[disabled] > .toolbarbutton-icon {
+ box-shadow: 0 0 0 1px hsla(210,54%,20%,.55),
+ 0 1px 0 hsla(210,54%,20%,.65);
+}
+
+.unified-nav-back[_moz-menuactive]:-moz-locale-dir(ltr),
+.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("chrome://browser/skin/menu-back.png") !important;
+}
+
+.unified-nav-forward[_moz-menuactive]:-moz-locale-dir(ltr),
+.unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
+ list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
+}
+
+#stop-button {
+ -moz-image-region: rect(0, 54px, 18px, 36px);
+}
+
+#reload-button {
+ -moz-image-region: rect(0, 72px, 18px, 54px);
+}
+
+#home-button.bookmark-item {
+ list-style-image: var(--toolbarbutton-image);
+}
+toolbar[brighttext] #home-button.bookmark-item {
+ list-style-image: var(--toolbarbutton-inverted-image);
+}
+
+#home-button.bookmark-item:not(:-moz-lwtheme) {
+ list-style-image: var(--toolbarbutton-glass-image);
+}
+
+#home-button {
+ -moz-image-region: rect(0, 90px, 18px, 72px);
+}
+
+#downloads-button {
+ -moz-image-region: rect(0, 108px, 18px, 90px);
+}
+
+#history-button,
+#history-menu-button {
+ -moz-image-region: rect(0, 126px, 18px, 108px);
+}
+
+#bookmarks-button,
+#bookmarks-menu-button {
+ -moz-image-region: rect(0, 144px, 18px, 126px);
+}
+
+#bookmarks-menu-button.bookmark-item {
+ list-style-image: var(--toolbarbutton-image);
+}
+
+toolbar[brighttext] #bookmarks-menu-button.bookmark-item {
+ list-style-image: var(--toolbarbutton-inverted-image);
+}
+
+#bookmarks-menu-button.bookmark-item:not(:-moz-lwtheme) {
+ list-style-image: var(--toolbarbutton-glass-image);
+}
+
+#print-button {
+ -moz-image-region: rect(0, 162px, 18px, 144px);
+}
+
+#new-tab-button {
+ -moz-image-region: rect(0, 180px, 18px, 162px);
+}
+
+#new-window-button {
+ -moz-image-region: rect(0, 198px, 18px, 180px);
+}
+
+#cut-button {
+ -moz-image-region: rect(0, 216px, 18px, 198px);
+}
+
+#copy-button {
+ -moz-image-region: rect(0, 234px, 18px, 216px);
+}
+
+#paste-button {
+ -moz-image-region: rect(0, 252px, 18px, 234px);
+}
+
+#fullscreen-button {
+ -moz-image-region: rect(0, 270px, 18px, 252px);
+}
+
+#zoom-out-button {
+ -moz-image-region: rect(0, 288px, 18px, 270px);
+}
+
+#zoom-in-button {
+ -moz-image-region: rect(0, 306px, 18px, 288px);
+}
+
+#sync-button {
+ -moz-image-region: rect(0, 324px, 18px, 306px);
+}
+#sync-button[status="active"] {
+ list-style-image: url("chrome://browser/skin/sync-throbber.png");
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#feed-button {
+ -moz-image-region: rect(0, 342px, 18px, 324px);
+}
+
+%ifdef MOZ_WEBRTC
+#webrtc-status-button {
+ -moz-image-region: rect(0, 360px, 18px, 342px);
+}
+%endif
+
+/* ::::: fullscreen window controls ::::: */
+
+#window-controls {
+ -moz-margin-start: 4px;
+}
+
+#minimize-button,
+#restore-button,
+#close-button {
+ list-style-image: url("chrome://global/skin/icons/windowControls.png");
+ padding: 0;
+}
+
+#minimize-button {
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+#minimize-button:hover {
+ -moz-image-region: rect(16px, 16px, 32px, 0);
+}
+#minimize-button:hover:active {
+ -moz-image-region: rect(32px, 16px, 48px, 0);
+}
+#restore-button {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+#restore-button:hover {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+#restore-button:hover:active {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+#close-button {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+ -moz-appearance: none;
+ border-style: none;
+ margin: 2px;
+}
+#close-button:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+#close-button:hover:active {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+
+/* ::::: Location Bar ::::: */
+
+#urlbar,
+.searchbar-textbox {
+ -moz-appearance: none;
+ margin: 1px 3px;
+ padding: 0;
+ background-clip: padding-box;
+ border: 1px solid ThreeDShadow;
+ border-radius: 2px;
+}
+
+#urlbar {
+ width: 7em;
+ -moz-padding-end: 2px;
+}
+
+@media (-moz-windows-default-theme) {
+ #urlbar,
+ .searchbar-textbox {
+ @navbarTextboxCustomBorder@
+ }
+}
+
+#urlbar:-moz-lwtheme,
+.searchbar-textbox:-moz-lwtheme {
+ background-color: rgba(255,255,255,.8);
+ @navbarTextboxCustomBorder@
+ color: black;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container {
+ padding-left: @conditionalForwardWithUrlbarWidth@px;
+ -moz-margin-start: -@conditionalForwardWithUrlbarWidth@px;
+ position: relative;
+ pointer-events: none;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar {
+ -moz-border-start: none;
+ margin-left: 0;
+ pointer-events: all;
+}
+
+@conditionalForwardWithUrlbar@:not([switchingtabs]) + #urlbar-container > #urlbar {
+ transition: margin-left @forwardTransitionLength@ ease-out;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(ltr) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container {
+ clip-path: url("chrome://browser/content/browser.xul#windows-urlbar-back-button-clip-path");
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container:-moz-locale-dir(rtl),
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
+ /* let windows-urlbar-back-button-mask clip the urlbar's right side for RTL */
+ transform: scaleX(-1);
+}
+
+html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
+.searchbar-textbox:-moz-lwtheme > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input::-moz-placeholder {
+ opacity: 1.0;
+ color: #777;
+}
+
+#urlbar:-moz-lwtheme[focused="true"],
+.searchbar-textbox:-moz-lwtheme[focused="true"] {
+ background-color: white;
+}
+
+#urlbar-container {
+ -moz-box-orient: horizontal;
+ -moz-box-align: stretch;
+}
+
+.urlbar-textbox-container {
+ -moz-box-align: stretch;
+}
+
+.urlbar-input-box {
+ -moz-margin-start: 0;
+ min-width: 4em;
+}
+
+#urlbar-icons {
+ -moz-box-align: center;
+}
+
+.urlbar-icon {
+ padding: 0 3px;
+}
+
+.searchbar-engine-button,
+.search-go-container {
+ padding: 2px 2px;
+}
+
+.urlbar-icon:hover {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.3), hsla(200,100%,70%,0));
+}
+
+.urlbar-icon[open="true"],
+.urlbar-icon:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.1), hsla(200,100%,70%,0));
+}
+
+#urlbar-search-splitter {
+ min-width: 6px;
+ -moz-margin-start: -3px;
+ border: none;
+ background: transparent;
+}
+
+#urlbar-search-splitter + #urlbar-container > #urlbar ,
+#urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
+ -moz-margin-start: 0;
+}
+
+#urlbar-display-box {
+ -moz-border-end: 1px solid #AAA;
+ -moz-margin-end: 3px;
+}
+
+#urlbar-display {
+ margin-top: 0;
+ margin-bottom: 0;
+ -moz-margin-start: 0;
+ color: GrayText;
+}
+
+/* identity box */
+
+#identity-box {
+ padding: 2px;
+ font-size: .9em;
+}
+
+#identity-box:-moz-locale-dir(ltr) {
+ border-top-left-radius: 1.5px;
+ border-bottom-left-radius: 1.5px;
+}
+
+#identity-box:-moz-locale-dir(rtl) {
+ border-top-right-radius: 1.5px;
+ border-bottom-right-radius: 1.5px;
+}
+
+#notification-popup-box:not([hidden]) + #identity-box {
+ -moz-padding-start: 10px;
+ border-radius: 0;
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar > #identity-box {
+ border-radius: 0;
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity {
+ color: hsl(92,100%,20%);
+ -moz-margin-end: 4px;
+ background-image: -moz-linear-gradient(hsla(92,81%,16%,0),
+ hsla(92,81%,16%,.08) 25%,
+ hsla(92,81%,16%,.08) 75%,
+ hsla(92,81%,16%,0));
+ background-position: right;
+ background-repeat: no-repeat;
+ border-right: 1px solid hsla(92,100%,20%,0.5);
+}
+
+#urlbar[pageproxystate="valid"] > #identity-box.verifiedDomain {
+ color: rgb(0,79,168);
+ -moz-margin-end: 4px;
+ background-image: -moz-linear-gradient(rgba(0,79,168,0),
+ rgba(0,79,168,.08) 25%,
+ rgba(0,79,168,.08) 75%,
+ rgba(0,79,168,0));
+ background-position: right;
+ background-repeat: no-repeat;
+ border-right: 1px solid rgba(0,79,168,0.5);
+}
+
+#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
+ background-position: left;
+ border-right: none;
+ border-left: 1px solid hsla(92,100%,20%,0.5);
+}
+
+#identity-box.verifiedDomain:-moz-locale-dir(rtl) {
+ background-position: left;
+ border-right: none;
+ border-left: 1px solid rgba(0,79,168,0.5);
+}
+
+#identity-box:-moz-focusring {
+ outline: 1px dotted #000;
+ outline-offset: -3px;
+}
+
+#identity-icon-labels {
+ -moz-padding-start: 2px;
+ -moz-padding-end: 5px;
+}
+
+/* Address bar shading for SSL */
+
+#urlbar[https_color="all"][security_level="broken"],
+#urlbar[https_color="all"][security_level="low"] {
+ box-shadow: inset 0 0 2px rgb(168,0,0);
+}
+
+#urlbar[https_color="all"][security_level="mixed"],
+#urlbar[https_color="secure-mixed"][security_level="mixed"] {
+ box-shadow: inset 0 0 2px rgb(168,79,0);
+}
+
+#urlbar[https_color="all"][security_level="high"],
+#urlbar[https_color="secure-mixed"][security_level="high"],
+#urlbar[https_color="secure-only"][security_level="high"] {
+ box-shadow: inset 0 0 2px rgb(0,79,168);
+}
+
+#urlbar[https_color="all"][security_level="ev"],
+#urlbar[https_color="secure-mixed"][security_level="ev"],
+#urlbar[https_color="secure-only"][security_level="ev"] {
+ box-shadow: inset 0 0 2px rgb(0,168,0);
+}
+
+#urlbar[https_color="all"][security_level="broken"]:not(:-moz-lwtheme),
+#urlbar[https_color="all"][security_level="low"]:not(:-moz-lwtheme) {
+ box-shadow: inset 0 0 3px rgba(168,0,0,0.8);
+}
+
+#urlbar[https_color="all"][security_level="mixed"]:not(:-moz-lwtheme),
+#urlbar[https_color="secure-mixed"][security_level="mixed"]:not(:-moz-lwtheme) {
+ box-shadow: inset 0 0 3px rgba(168,79,0,0.8);
+}
+
+#urlbar[https_color="all"][security_level="high"]:not(:-moz-lwtheme),
+#urlbar[https_color="secure-mixed"][security_level="high"]:not(:-moz-lwtheme),
+#urlbar[https_color="secure-only"][security_level="high"]:not(:-moz-lwtheme) {
+ box-shadow: inset 0 0 3px rgba(0,79,168,0.8);
+}
+
+#urlbar[https_color="all"][security_level="ev"]:not(:-moz-lwtheme),
+#urlbar[https_color="secure-mixed"][security_level="ev"]:not(:-moz-lwtheme),
+#urlbar[https_color="secure-only"][security_level="ev"]:not(:-moz-lwtheme) {
+ box-shadow: inset 0 0 3px rgba(0,168,0,0.8);
+}
+
+/* Location bar dropmarker */
+
+.urlbar-history-dropmarker {
+ -moz-appearance: none;
+ padding: 0 3px;
+ background-color: transparent;
+ border: none;
+ width: auto;
+ list-style-image: url("chrome://browser/skin/urlbar-history-dropmarker.png");
+ -moz-image-region: rect(0px, 11px, 14px, 0px);
+}
+
+.urlbar-history-dropmarker:hover {
+ background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), hsla(205,100%,70%,0));
+ -moz-image-region: rect(0px, 22px, 14px, 11px);
+}
+
+.urlbar-history-dropmarker:hover:active,
+.urlbar-history-dropmarker[open="true"] {
+ background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.1), hsla(205,100%,70%,0));
+ -moz-image-region: rect(0px, 33px, 14px, 22px);
+}
+
+/* page proxy icon */
+
+#page-proxy-favicon {
+ width: 16px;
+ height: 16px;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ -moz-margin-start: 3px;
+ -moz-margin-end: 2px;
+ list-style-image: url(chrome://browser/skin/identity-icons-generic.png);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar > #identity-box > #page-proxy-favicon {
+ -moz-margin-end: 1px;
+}
+
+/* Since we already have a padlock, always use the generic icon until the favicon loads
+.verifiedDomain > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https.png);
+}
+
+.verifiedIdentity > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-ev.png);
+}
+
+.mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
+ list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
+}
+*/
+
+#identity-box:hover > #page-proxy-favicon {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#identity-box:hover:active > #page-proxy-favicon,
+#identity-box[open=true] > #page-proxy-favicon {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#page-proxy-favicon[pageproxystate="invalid"] {
+ opacity: 0.3;
+}
+
+/* autocomplete */
+
+#treecolAutoCompleteImage {
+ max-width: 36px;
+}
+
+.ac-result-type-bookmark,
+.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0px 48px 16px 32px);
+ width: 16px;
+ height: 16px;
+}
+
+.ac-result-type-keyword,
+.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
+ list-style-image: url(chrome://global/skin/icons/Search-glass.png);
+ -moz-image-region: rect(0px 32px 16px 16px);
+ width: 16px;
+ height: 16px;
+}
+
+.ac-result-type-tag,
+.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ width: 16px;
+ height: 16px;
+}
+
+.ac-comment {
+ font-size: 1.06em;
+}
+
+.ac-extra > .ac-comment {
+ font-size: 1em;
+}
+
+.ac-url-text,
+.ac-action-text {
+ font-size: 1em;
+ color: -moz-nativehyperlinktext;
+}
+
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+ list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+ -moz-image-region: rect(0, 16px, 11px, 0);
+ padding: 0 3px;
+}
+
+@media not all and (-moz-os-version: windows-vista),
+ not all and (-moz-windows-default-theme) {
+ @media not all and (-moz-os-version: windows-win7),
+ not all and (-moz-windows-default-theme) {
+ richlistitem[type~="action"][actiontype$="tab"][selected="true"] > .ac-url-box > .ac-action-icon {
+ -moz-image-region: rect(11px, 16px, 22px, 0);
+ }
+
+ .ac-comment[selected="true"],
+ .ac-url-text[selected="true"],
+ .ac-action-text[selected="true"] {
+ color: inherit !important;
+ }
+ }
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
+ color: GrayText;
+}
+
+.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
+.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
+{
+ color: GrayText;
+ font-size: smaller;
+}
+
+.autocomplete-treebody::-moz-tree-cell(suggesthint) {
+ border-top: 1px solid GrayText;
+}
+
+/* combined go/reload/stop button in location bar */
+
+#go-button,
+#urlbar > toolbarbutton {
+ -moz-appearance: none;
+ padding: 0 2px;
+ background-origin: border-box;
+ border: none;
+ list-style-image: url("chrome://browser/skin/reload-stop-go.png");
+}
+
+#go-button {
+ padding: 0 3px;
+}
+
+#urlbar-reload-button {
+ -moz-image-region: rect(0, 14px, 14px, 0);
+}
+
+#urlbar-reload-button:not([disabled]):hover {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,70%,.2), hsla(200,100%,70%,0));
+ -moz-image-region: rect(14px, 14px, 28px, 0);
+}
+
+#urlbar-reload-button:not([disabled]):hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(200,100%,60%,.1), hsla(200,100%,60%,0));
+ -moz-image-region: rect(28px, 14px, 42px, 0);
+}
+
+#urlbar-reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+#go-button,
+#urlbar-go-button {
+ -moz-image-region: rect(0, 42px, 14px, 28px);
+}
+
+#go-button:hover,
+#urlbar-go-button:hover {
+ background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.2), hsla(110,70%,50%,0));
+ -moz-image-region: rect(14px, 42px, 28px, 28px);
+}
+
+#go-button:hover:active,
+#urlbar-go-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(110,70%,50%,.1), hsla(110,70%,50%,0));
+ -moz-image-region: rect(28px, 42px, 42px, 28px);
+}
+
+#go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#urlbar-go-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+#urlbar-stop-button {
+ -moz-image-region: rect(0, 28px, 14px, 14px);
+}
+
+#urlbar-stop-button:not([disabled]):hover {
+ background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.3), hsla(5,100%,75%,0));
+ -moz-image-region: rect(14px, 28px, 28px, 14px);
+}
+
+#urlbar-stop-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(5,100%,75%,.1), hsla(5,100%,75%,0));
+ -moz-image-region: rect(28px, 28px, 42px, 14px);
+}
+
+/* popup blocker button */
+
+#page-report-button {
+ list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+#page-report-button:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#page-report-button:hover:active,
+#page-report-button[open="true"] {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+/* star button */
+
+#star-button {
+ list-style-image: url("chrome://browser/skin/places/bookmark.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+#star-button:hover {
+ background-image: radial-gradient(circle closest-side, hsla(45,100%,73%,.3), hsla(45,100%,73%,0));
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#star-button:hover:active {
+ background-image: radial-gradient(circle closest-side, hsla(45,100%,73%,.1), hsla(45,100%,73%,0));
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+#star-button[starred] {
+ list-style-image: url("chrome://browser/skin/places/editBookmark.png");
+}
+
+/* bookmarking panel */
+
+#editBookmarkPanelStarIcon {
+ list-style-image: url("chrome://browser/skin/places/starred48.png");
+ width: 48px;
+ height: 48px;
+}
+
+#editBookmarkPanelStarIcon[unstarred] {
+ list-style-image: url("chrome://browser/skin/places/unstarred48.png");
+}
+
+#editBookmarkPanelTitle {
+ font-size: 130%;
+}
+
+#editBookmarkPanelHeader,
+#editBookmarkPanelContent {
+ margin-bottom: .5em;
+}
+
+/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
+#editBMPanel_folderTree {
+ min-width: 27em;
+}
+
+/* ::::: content area ::::: */
+
+#sidebar {
+ background-color: Window;
+}
+
+#sidebar-title {
+ -moz-padding-start: 0px;
+}
+
+/* ::::: throbber ::::: */
+
+#navigator-throbber {
+ width: 16px;
+ min-height: 16px;
+ margin: 0 3px;
+}
+
+#navigator-throbber[busy="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#navigator-throbber,
+#wrapper-navigator-throbber > #navigator-throbber {
+ list-style-image: url("chrome://global/skin/icons/notloading_16.png");
+}
+
+/* Tabstrip */
+
+#TabsToolbar {
+ min-height: 0;
+ padding: 0;
+}
+
+/* Make sure the Navigation toolbar buttons are more or less
+ vertically centered between the tabs and the AppMenu button
+ when the tabs are not on top and the Bookmarks toolbar is
+ disabled */
+#nav-bar + #customToolbars + #PersonalToolbar:-moz-any([collapsed=true],[moz-collapsed=true]) + #TabsToolbar[tabsontop=false] {
+ margin-top: 1px;
+}
+
+/* Make sure the elements on the Tab bar are not "glued" right
+ up against the AppMenu button / the caption when the tabs are
+ on top and the window is unmaximized */
+#main-window[sizemode="normal"] #TabsToolbar[tabsontop=true] {
+ margin-top: 1px;
+}
+
+#TabsToolbar:not(:-moz-lwtheme),
+#TabsToolbar[tabsontop=false] {
+ background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%);
+}
+
+/* When the tab bar is collapsed, show a 1px border in its place. */
+#TabsToolbar[tabsontop="false"][collapsed="true"]:not([customizing="true"]) {
+ visibility: visible;
+ height: 1px;
+ border-bottom-width: 1px;
+ /* !important here to override border-style: none on the toolbar */
+ border-bottom-style: solid !important;
+ border-bottom-color: var(--toolbox-after-color);
+ overflow: hidden;
+}
+
+.tabbrowser-tab,
+.tabs-newtab-button {
+ -moz-appearance: none;
+ background: @toolbarShadowOnTab@, var(--tab-background),
+ linear-gradient(-moz-dialog, -moz-dialog);
+ background-clip: padding-box;
+ padding: 3px 1px 4px;
+ /* Setting a transparent outer border allows us to have a 1px gap
+ between the tabs and the top edge of the screen, even when the
+ tabs have a top margin of 0, which is important for Fitts' law
+ compliance */
+ border: 1.6px solid;
+ border-bottom: none;
+ border-radius: var(--tab-border-radius) var(--tab-border-radius) 0px 0px;
+ -moz-border-top-colors: transparent #929292;
+ -moz-border-left-colors: transparent #929292;
+ -moz-border-right-colors: transparent #929292;
+ /* Hide the transparent top border by default */
+ margin-top: -1px;
+ /* Reduce the gap between the tabs */
+ -moz-margin-start: -1px;
+ box-shadow: var(--tab-box-shadow);
+}
+
+.tabbrowser-tab {
+ -moz-padding-end: 3px;
+}
+
+/* Override the default (globally-set) tab width values; increase
+ by 2px to compensate for the transparent outer border of the tabs */
+.tabbrowser-tab:not([pinned]) {
+ max-width: 252px;
+ min-width: 102px;
+}
+
+/* When the tabs are on top and the window is maximized or in full-
+ screen mode, unhide the transparent top border of the tabs so we
+ have a 1px gap between the tabs and the top edge of the screen */
+#main-window[sizemode="maximized"][tabsontop=true] .tabbrowser-tab,
+#main-window[sizemode="maximized"][tabsontop=true] .tabs-newtab-button,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabbrowser-tab,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabs-newtab-button {
+ margin-top: 0px;
+}
+
+@media (-moz-os-version: windows-win8) {
+ /* Square is the new round, courtesy of microsoft */
+ /* We keep the hinting at round here because that's the hybrid in use
+ on our other controls in the navigation toolbars */
+ :root {
+ --tab-border-radius: 3.5px;
+ }
+}
+
+@media (-moz-os-version: windows-win10) {
+ /* Square is the new round, courtesy of microsoft */
+ :root {
+ --tab-border-radius: 0px;
+ --tab-box-shadow: none;
+ }
+}
+
+.tabbrowser-tab:hover,
+.tabs-newtab-button:hover {
+ background-image: @toolbarShadowOnTab@, var(--tab-background-hover),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+.tabbrowser-tab[selected="true"] {
+ background-image: linear-gradient(var(--tab-selected-highlight), var(--toolbar-highlight-top) 50%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+#main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
+ background-image: @toolbarShadowOnTab@,
+ linear-gradient(var(--tab-selected-highlight), var(--toolbar-highlight-top) 50%),
+ linear-gradient(-moz-dialog, -moz-dialog);
+}
+
+.tabbrowser-tab:-moz-lwtheme {
+ color: inherit;
+ /* 0.99 opacity rquired to force an active layer, see bug #1028369 */
+ opacity: 0.99;
+}
+
+.tabbrowser-tab:-moz-lwtheme:not([selected="true"]) {
+ opacity: 0.9;
+}
+
+/* Remove highlight fuzz on dark themes */
+.tabbrowser-tab:-moz-lwtheme-brighttext,
+.tabs-newtab-button:-moz-lwtheme-brighttext {
+ box-shadow:none;
+ -moz-border-top-colors: transparent #707070;
+ -moz-border-left-colors: transparent #707070;
+ -moz-border-right-colors: transparent #707070;
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme {
+ background-image: linear-gradient(var(--tab-selected-highlight), var(--toolbar-highlight-top) 50%);
+}
+
+.tabbrowser-tab[selected="true"]:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(rgba(128,128,128,.9), rgba(32,32,32,.9) 50%, rgba(32,32,32,.9) 80%, var(--toolbar-highlight-top) 100%);
+ -moz-border-top-colors: transparent #D0D0D0;
+ -moz-border-left-colors: transparent #D0D0D0;
+ -moz-border-right-colors: transparent #D0D0D0;
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-brighttext {
+ background-image: linear-gradient(hsla(0,0%,25%,.4), hsla(0,0%,15%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-brighttext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,10%,.8) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]),
+.tabs-newtab-button:-moz-lwtheme-darktext {
+ background-image: linear-gradient(hsla(0,0%,75%,.4), hsla(0,0%,85%,.6) 80%);
+}
+
+.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]):hover,
+.tabs-newtab-button:-moz-lwtheme-darktext:hover {
+ background-image: linear-gradient(hsla(0,0%,60%,.4), hsla(0,0%,90%,.8) 80%);
+}
+
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) {
+ background-image: radial-gradient(circle farthest-corner at 50% 3px, rgba(255,255,255,1) 3%, rgba(186,221,251,.75) 40%, rgba(127,179,255,.5) 80%, rgba(127,179,255,.25));
+}
+.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]):hover {
+ background-image: linear-gradient(hsla(0,0%,100%,.4), hsla(0,0%,75%,.4) 80%),
+ radial-gradient(circle farthest-corner at 50% 3px, rgba(255,255,255,1) 3%, rgba(186,221,251,.75) 40%, rgba(127,179,255,.5) 80%, rgba(127,179,255,.25));
+}
+
+.tab-throbber,
+.tab-icon-image {
+ width: 16px;
+ height: 16px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+ -moz-margin-start: 2px;
+ -moz-margin-end: 3px;
+}
+
+.tab-throbber {
+ list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
+}
+
+.tab-throbber[progress] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
+}
+
+.tab-throbber[pinned],
+.tab-icon-image[pinned] {
+ -moz-margin-start: 5px;
+ -moz-margin-end: 5px;
+}
+
+/* tabbrowser-tab focus ring */
+.tabbrowser-tab:focus > .tab-stack {
+ outline: 1px dotted;
+}
+
+/* Tab DnD indicator */
+.tab-drop-indicator {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
+ margin-bottom: -11px;
+}
+
+/* Tab close button */
+.tab-close-button {
+ -moz-appearance: none;
+ border: none;
+ padding: 0px;
+}
+
+.tab-close-button:not([selected]):not(:hover):not(:active) {
+ -moz-image-region: rect(0, 64px, 16px, 48px);
+}
+
+.tab-close-button:-moz-lwtheme-brighttext {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.svg");
+}
+
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.allTabs-endimage[soundplaying],
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.allTabs-endimage[muted],
+.tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.allTabs-endimage[blocked],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[soundplaying],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[blocked],
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-sound[muted] {
+ filter: invert(1);
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover),
+.tab-icon-overlay[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
+/* Tab icon overlay */
+.tab-icon-overlay {
+ width: 16px;
+ height: 16px;
+ margin-top: -8px;
+ margin-inline-start: -15px;
+ margin-inline-end: -1px;
+ position: relative;
+}
+
+.tab-icon-overlay[soundplaying],
+.tab-icon-overlay[muted]:not([crashed]),
+.tab-icon-overlay[blocked]:not([crashed]) {
+ border-radius: 10px;
+}
+
+.tab-icon-overlay[soundplaying]:hover,
+.tab-icon-overlay[muted]:not([crashed]):hover,
+.tab-icon-overlay[blocked]:not([crashed]):hover {
+ background-color: white;
+}
+
+.tab-icon-overlay[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio");
+}
+
+.tab-icon-overlay[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-muted");
+}
+
+.tab-icon-overlay[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-blocked");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[soundplaying]:not([selected]):not(:hover),
+.tab-icon-overlay[soundplaying][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[muted]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[muted][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-muted");
+}
+
+#TabsToolbar:-moz-lwtheme-brighttext .tab-icon-overlay[blocked]:not([crashed]):not([selected]):not(:hover),
+.tab-icon-overlay[blocked][selected]:-moz-lwtheme-brighttext:not(:hover) {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-blocked");
+}
+
+/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up,
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
+ margin: 0;
+ padding-right: 2px;
+ border-right: 2px solid transparent;
+ background-origin: border-box;
+}
+
+/* Prevent the icon from being vertically stretched when we unhide
+ the transparent top border of the tabs (when the tabs are on top
+ and the window is maximized or in full-screen mode) */
+#main-window[sizemode="maximized"][tabsontop=true] .tabbrowser-arrowscrollbox > .scrollbutton-up > .toolbarbutton-icon,
+#main-window[sizemode="maximized"][tabsontop=true] .tabbrowser-arrowscrollbox > .scrollbutton-down > .toolbarbutton-icon,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabbrowser-arrowscrollbox > .scrollbutton-up > .toolbarbutton-icon,
+#main-window[sizemode="fullscreen"][tabsontop=true] .tabbrowser-arrowscrollbox > .scrollbutton-down > .toolbarbutton-icon {
+ margin-bottom: 1px;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-system-metric(windows-compositor):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-glass.png);
+}
+
+toolbar[brighttext] .tabbrowser-arrowscrollbox > .scrollbutton-up,
+toolbar[brighttext] .tabbrowser-arrowscrollbox > .scrollbutton-down {
+ list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.png);
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
+.tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
+ opacity: .4;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
+ transform: scaleX(-1);
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down {
+ transition: 1s background-color ease-out;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
+ background-color: Highlight;
+ transition: none;
+}
+
+.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]),
+.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]) {
+ border-width: 0 2px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/tabbrowser/tab-overflow-border.png") 0 2 0 2 fill;
+}
+
+.tabs-newtab-button > .toolbarbutton-icon {
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+.tabs-newtab-button,
+#TabsToolbar > #new-tab-button,
+#TabsToolbar > toolbarpaletteitem > #new-tab-button {
+ list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
+ -moz-image-region: auto;
+}
+
+#TabsToolbar > #new-tab-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+#TabsToolbar > toolbarpaletteitem > #new-tab-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/tabbrowser/newtab-glass.png);
+}
+
+.tabs-newtab-button:-moz-lwtheme-brighttext,
+#TabsToolbar[brighttext] > #new-tab-button,
+#TabsToolbar[brighttext] > toolbarpaletteitem > #new-tab-button {
+ list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
+}
+
+.tabs-newtab-button {
+/* The button has a transparent outer border, so it will appear
+ to be 2px narrower than the width we set for it here */
+ width: 30px;
+}
+
+#TabsToolbar > #new-tab-button {
+ width: 26px;
+}
+
+#alltabs-button {
+ list-style-image: url("chrome://browser/skin/tabbrowser/alltabs.png");
+ -moz-image-region: rect(0, 14px, 16px, 0);
+}
+
+#alltabs-button[type="menu"] {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
+ -moz-image-region: auto;
+}
+
+toolbar[brighttext] #alltabs-button {
+ list-style-image: url("chrome://browser/skin/tabbrowser/alltabs-inverted.png");
+}
+
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > #alltabs-button[type=menu]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > toolbarpaletteitem > #alltabs-button[type=menu]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+toolbar[brighttext] #alltabs-button[type="menu"] {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-icon {
+ margin: 0 2px;
+}
+
+#alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+/* All tabs menupopup */
+.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+.alltabs-item[selected="true"] {
+ font-weight: bold;
+}
+
+.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.alltabs-item[tabIsVisible] {
+ /* box-shadow instead of background-color to work around native styling */
+ box-shadow: inset -5px 0 ThreeDShadow;
+}
+
+/* Tabstrip close button */
+.tabs-closebutton {
+ -moz-appearance: none;
+ padding: 4px 2px;
+ margin: 0px;
+ border: none;
+}
+
+toolbar[brighttext] .tabs-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.svg");
+}
+
+.tabs-closebutton > .toolbarbutton-icon {
+ -moz-margin-end: 0px !important;
+ -moz-padding-end: 2px !important;
+ -moz-padding-start: 2px !important;
+}
+
+toolbarbutton.chevron {
+ list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important;
+}
+
+toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+toolbarbutton.chevron > .toolbarbutton-text,
+toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
+ display: none;
+}
+
+toolbarbutton.chevron > .toolbarbutton-icon {
+ margin: 0;
+}
+
+toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
+ display: -moz-box; /* display chevron icon in text mode */
+}
+
+#sidebar-throbber[loading="true"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+ -moz-margin-end: 4px;
+}
+
+/* Pale Moon: Feed icon */
+#ub-feed-button,
+#ub-feed-button > .button-box,
+#ub-feed-button:hover:active > .button-box {
+ padding: 0px;
+ margin: 0px;
+ border: 0px;
+ background-color: transparent !important;
+}
+
+#ub-feed-button {
+ -moz-appearance: none;
+ min-width: 0px;
+ list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+#ub-feed-button:hover {
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+#ub-feed-button[open="true"],
+#ub-feed-button:hover:active {
+ -moz-image-region: rect(0px 48px 16px 32px);
+}
+
+
+/* Bookmarks toolbar */
+#PlacesToolbarDropIndicator {
+ list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
+}
+
+toolbarbutton.bookmark-item[dragover="true"][open="true"] {
+ -moz-appearance: none;
+ background: Highlight !important;
+ color: HighlightText !important;
+}
+
+/* rules for menupopup drop indicators */
+.menupopup-drop-indicator-bar {
+ position: relative;
+ /* these two margins must together compensate the indicator's height */
+ margin-top: -1px;
+ margin-bottom: -1px;
+}
+
+.menupopup-drop-indicator {
+ list-style-image: none;
+ height: 2px;
+ -moz-margin-end: -4em;
+ background-color: Highlight;
+}
+
+/* ::::: Identity Indicator Styling ::::: */
+
+/* Popup Icons */
+#identity-popup-icon {
+ height: 64px;
+ width: 64px;
+ padding: 0;
+ list-style-image: url("chrome://browser/skin/identity.png");
+ -moz-image-region: rect(0px, 64px, 64px, 0px);
+}
+
+#identity-popup.verifiedDomain > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(64px, 64px, 128px, 0px);
+}
+
+#identity-popup.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
+ -moz-image-region: rect(128px, 64px, 192px, 0px);
+}
+
+/* Popup Body Text */
+.identity-popup-description {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 2px 0 4px;
+}
+
+.identity-popup-label {
+ white-space: pre-wrap;
+ -moz-padding-start: 15px;
+ margin: 0;
+}
+
+#identity-popup-content-host,
+#identity-popup-content-box.verifiedIdentity > #identity-popup-content-owner {
+ font-size: 1.2em;
+}
+
+#identity-popup-content-host {
+ margin-top: 3px;
+ margin-bottom: 5px;
+ font-weight: bold;
+ max-width: 300px;
+}
+
+#identity-popup-content-owner {
+ margin-top: 4px;
+ margin-bottom: 0 !important;
+ font-weight: bold;
+ max-width: 300px;
+}
+
+.verifiedDomain > #identity-popup-content-owner {
+ font-weight: normal;
+}
+
+#identity-popup-content-verifier {
+ margin: 4px 0 2px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption {
+ margin-top: 10px;
+ -moz-margin-start: -24px;
+}
+
+#identity-popup-content-box.verifiedIdentity > #identity-popup-encryption > vbox > #identity-popup-encryption-icon ,
+#identity-popup-content-box.verifiedDomain > #identity-popup-encryption > vbox > #identity-popup-encryption-icon {
+ list-style-image: url("chrome://browser/skin/Secure24.png");
+}
+
+#identity-popup-more-info-button {
+ margin-top: 6px;
+ margin-bottom: 0;
+ -moz-margin-end: 0;
+}
+
+.popup-notification-icon {
+ width: 64px;
+ height: 64px;
+ -moz-margin-end: 10px;
+}
+
+.popup-notification-icon[popupid="geolocation"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+
+.popup-notification-icon[popupid="xpinstall-disabled"],
+.popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-origin-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
+ width: 32px;
+ height: 32px;
+}
+
+.popup-notification-icon[popupid="click-to-play-plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
+}
+
+.popup-notification-icon[popupid="web-notifications"] {
+ list-style-image: url(chrome://browser/skin/notification-64.png);
+}
+
+.addon-progress-description {
+ width: 350px;
+ max-width: 350px;
+}
+
+.popup-progress-label,
+.popup-progress-meter {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+.popup-progress-cancel {
+ -moz-appearance: none;
+ background: transparent;
+ border: none;
+ padding: 0;
+ margin: 0;
+ min-height: 0;
+ min-width: 0;
+ list-style-image: url(chrome://mozapps/skin/downloads/downloadButtons.png);
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.popup-progress-cancel:hover {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.popup-progress-cancel:active {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+
+.popup-notification-icon[popupid="indexedDB-permissions-prompt"],
+.popup-notification-icon[popupid="indexedDB-quota-prompt"],
+.popup-notification-icon[popupid*="offline-app-requested"],
+.popup-notification-icon[popupid="offline-app-usage"] {
+ list-style-image: url(chrome://global/skin/icons/question-64.png);
+}
+
+.popup-notification-icon[popupid="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+
+.popup-notification-icon[popupid="mixed-content-blocked"] {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+}
+
+%ifdef MOZ_WEBRTC
+.popup-notification-icon[popupid="webRTC-sharingDevices"],
+.popup-notification-icon[popupid="webRTC-shareDevices"] {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
+}
+%endif
+
+.popup-notification-icon[popupid="pointerLock"] {
+ list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+
+/* Notification icon box */
+#notification-popup-box {
+ position: relative;
+ background-color: #fff;
+ background-clip: padding-box;
+ padding-left: 3px;
+ border-radius: var(--toolbarbutton-border-radius) 0 0 var(--toolbarbutton-border-radius);
+ border-width: 0 8px 0 0;
+ border-style: solid;
+ border-image: url("chrome://browser/skin/urlbar-arrow.png") 0 8 0 0 fill;
+ -moz-margin-end: -8px;
+}
+
+@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar > #notification-popup-box {
+ padding-left: 5px;
+}
+
+#notification-popup-box:-moz-locale-dir(rtl),
+.notification-anchor-icon:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+.notification-anchor-icon {
+ width: 16px;
+ height: 16px;
+ margin: 0 2px;
+}
+
+.notification-anchor-icon:-moz-focusring {
+ outline: 1px dotted -moz-DialogText;
+ outline-offset: -3px;
+}
+
+.default-notification-icon,
+#default-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/information-16.png);
+}
+
+.geo-notification-icon,
+#geo-notification-icon {
+ list-style-image: url(chrome://browser/skin/Geolocation-16.png);
+}
+
+#addons-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
+}
+
+.indexedDB-notification-icon,
+#indexedDB-notification-icon {
+ list-style-image: url(chrome://global/skin/icons/question-16.png);
+}
+
+#password-notification-icon {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16.png);
+}
+
+#plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
+}
+
+#alert-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
+}
+
+#blocked-plugins-notification-icon {
+ list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
+}
+
+#plugins-notification-icon,
+#alert-plugins-notification-icon,
+#blocked-plugins-notification-icon {
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+#plugins-notification-icon:hover,
+#alert-plugins-notification-icon:hover,
+#blocked-plugins-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#plugins-notification-icon:active,
+#alert-plugins-notification-icon:active,
+#blocked-plugins-notification-icon:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#notification-popup-box[hidden] {
+ /* Override display:none to make the pluginBlockedNotification animation work
+ when showing the notification repeatedly. */
+ display: -moz-box;
+ visibility: collapse;
+}
+
+#blocked-plugins-notification-icon[showing] {
+ animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
+}
+
+@keyframes pluginBlockedNotification {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+.mixed-content-blocked-notification-icon,
+#mixed-content-blocked-notification-icon {
+ list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+}
+
+%ifdef MOZ_WEBRTC
+.webRTC-shareDevices-notification-icon,
+#webRTC-shareDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
+}
+
+.webRTC-sharingDevices-notification-icon,
+#webRTC-sharingDevices-notification-icon {
+ list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
+}
+%endif
+
+.web-notifications-notification-icon,
+#web-notifications-notification-icon {
+ list-style-image: url(chrome://browser/skin/web-notifications-tray.svg);
+ -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.web-notifications-notification-icon:hover,
+#web-notifications-notification-icon:hover {
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.web-notifications-notification-icon:hover:active,
+#web-notifications-notification-icon:hover:active {
+ -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+#pointerLock-notification-icon {
+ list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+#pointerLock-cancel {
+ margin: 0px;
+}
+
+#identity-popup-container {
+ min-width: 280px;
+}
+
+/* Bookmarks roots menu-items */
+#appmenu_subscribeToPage:not([disabled]),
+#appmenu_subscribeToPageMenu,
+#subscribeToPageMenuitem:not([disabled]),
+#subscribeToPageMenupopup,
+#BMB_subscribeToPageMenuitem:not([disabled]),
+#BMB_subscribeToPageMenupopup {
+ list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+}
+
+#appmenu_bookmarksToolbar,
+#bookmarksToolbarFolderMenu,
+#BMB_bookmarksToolbar {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+ -moz-image-region: auto;
+}
+
+#appmenu_unsortedBookmarks,
+#menu_unsortedBookmarks,
+#BMB_unsortedBookmarks {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+ -moz-image-region: auto;
+}
+
+/* ::::: Keyboard UI Panel ::::: */
+
+.KUI-panel {
+ -moz-appearance: none;
+ background: rgba(27%,27%,27%,.9) url(KUI-background.png) repeat-x;
+ color: white;
+ border-style: none;
+ border-radius: 20px;
+}
+
+.KUI-panel[level="top"] {
+ background-color: rgba(27%,27%,27%,.65);
+}
+
+.KUI-panel-closebutton {
+ list-style-image: url(KUI-close.png);
+ -moz-appearance: none;
+ border: none;
+ padding: 0;
+ width: 24px;
+ height: 24px;
+}
+
+.KUI-panel-closebutton:not(:hover) {
+ opacity: .6;
+}
+
+.KUI-panel-closebutton > .toolbarbutton-icon {
+ margin: 0;
+}
+
+/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
+
+/* Ctrl-Tab */
+
+#ctrlTab-panel {
+ padding: 20px 10px 10px;
+ font-weight: bold;
+ text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 2px rgb(27%,27%,27%);
+}
+
+.ctrlTab-favicon[src] {
+ background-color: white;
+ width: 20px;
+ height: 20px;
+ padding: 2px;
+}
+
+.ctrlTab-preview-inner > .tabPreview-canvas {
+ box-shadow: 1px 1px 2px rgb(12%,12%,12%);
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll) > * > .ctrlTab-preview-inner > .tabPreview-canvas {
+ margin-bottom: 2px;
+}
+
+.ctrlTab-preview-inner {
+ padding-bottom: 10px;
+}
+
+#ctrlTab-showAll:not(:focus) > * > .ctrlTab-preview-inner {
+ padding: 10px;
+ background-color: rgba(255,255,255,.2);
+ border-radius: .5em;
+}
+
+.ctrlTab-preview:focus > * > .ctrlTab-preview-inner {
+ color: white;
+ background-color: rgba(0,0,0,.6);
+ text-shadow: none;
+ padding: 8px;
+ border: 2px solid white;
+ border-radius: .5em;
+}
+
+.ctrlTab-preview:not(#ctrlTab-showAll):focus > * > .ctrlTab-preview-inner {
+ margin: -10px -10px 0;
+}
+
+#ctrlTab-showAll {
+ margin-top: .5em;
+}
+
+/* All Tabs */
+
+#allTabs-panel {
+ padding-bottom: 10px;
+ -moz-appearance: none;
+ border: none;
+ background: -moz-dialog;
+ color: -moz-dialogText;
+}
+
+#allTabs-meta {
+ margin: 10px;
+}
+
+#allTabs-filter {
+ -moz-margin-start: 24px;
+ -moz-margin-end: 0;
+}
+
+#allTabs-tab-close-button > .toolbarbutton-icon {
+ margin: 0;
+}
+
+/* Make sure the allTab previews always have regular close buttons */
+#allTabs-tab-close-button:-moz-lwtheme-brighttext {
+ list-style-image: url("chrome://global/skin/icons/close.svg");
+}
+
+.allTabs-favicon[src] {
+ background-color: -moz-dialog;
+ width: 22px;
+ height: 22px;
+ padding-top: 1px;
+ padding-bottom: 5px;
+ -moz-padding-start: 1px;
+ -moz-padding-end: 5px;
+ margin-top: -2px;
+ -moz-margin-start: -2px;
+ border-bottom-right-radius: 4px;
+}
+
+.allTabs-favicon[src]:-moz-locale-dir(rtl) {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 4px;
+}
+
+.allTabs-preview-inner > .tabPreview-canvas {
+ background-color: rgb(60%,60%,60%);
+ box-shadow: 0 0 1.5px ThreeDShadow;
+}
+
+.allTabs-preview:not(:hover):not([closebuttonhover]) > html|canvas {
+ opacity: .8;
+}
+
+.allTabs-preview:focus > * > .allTabs-preview-inner {
+ outline: 1px dotted -moz-dialogText;
+}
+
+/* Add-on bar */
+
+#addon-bar {
+ -moz-appearance: none;
+ min-height: 20px;
+ border-top-style: none;
+ border-bottom-style: none;
+ padding-top: 1px;
+ background-image: linear-gradient(rgba(0,0,0,.15) 1px, rgba(255,255,255,.15) 1px);
+ background-size: 100% 2px;
+ background-repeat: no-repeat;
+}
+
+#status-bar {
+ -moz-appearance: none;
+ background-color: transparent;
+ border: none;
+ min-height: 0;
+}
+
+#addon-bar[customizing] > #status-bar {
+ opacity: .5;
+ background-image: repeating-linear-gradient(135deg,
+ rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
+ rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
+}
+
+#status-bar > statusbarpanel {
+ border-width: 0;
+ -moz-appearance: none;
+}
+
+#addonbar-closebutton {
+ border: none;
+ padding: 0 5px;
+ -moz-appearance: none;
+}
+
+toolbar[brighttext] #addonbar-closebutton {
+ list-style-image: url("chrome://global/skin/icons/close-inverted.svg");
+}
+
+/* Status panel */
+
+.statuspanel-label {
+ margin: 0;
+ padding: 2px 4px;
+ background: linear-gradient(#fff, #ddd);
+ border: 1px none #ccc;
+ border-top-style: solid;
+ color: #333;
+ text-shadow: none;
+}
+
+.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
+.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+ border-right-style: solid;
+ /* disabled for triggering grayscale AA (bug 659213)
+ border-top-right-radius: .3em;
+ */
+ margin-right: 1em;
+}
+
+.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
+.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+ border-left-style: solid;
+ /* disabled for triggering grayscale AA (bug 659213)
+ border-top-left-radius: .3em;
+ */
+ margin-left: 1em;
+}
+
+#full-screen-warning-message {
+ background-color: hsl(0,0%,15%);
+ color: white;
+ border-radius: 8px;
+ margin-top: 30px;
+ padding: 30px 50px;
+ box-shadow: 0 0 2px white;
+}
+
+.full-screen-description {
+ font-size: 150%;
+}
+
+#full-screen-domain-text {
+ font-size: 300%;
+}
+
+%ifdef MOZ_DEVTOOLS
+%include ../../../../devtools/client/themes/responsivedesign.inc.css
+%include ../../../../devtools/client/themes/commandline.inc.css
+%endif
+%include ../shared/plugin-doorhanger.inc.css
+
+%ifdef MOZ_DEVTOOLS
+/* Error counter */
+
+#developer-toolbar-toolbox-button[error-count]:before {
+ color: #FDF3DE;
+ min-width: 16px;
+ text-shadow: none;
+ background-image: linear-gradient(#B4211B, #8A1915);
+ border-radius: 1px;
+ -moz-margin-end: 5px;
+}
+%endif
+
+.toolbarbutton-badge-stack {
+ margin: 0;
+ padding: 0;
+ position: relative;
+}
+
+@navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-badge-stack {
+ padding: 2px 5px;
+}
+
+.toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbar-icon {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+}
+
+.toolbarbutton-badge-stack > .toolbarbutton-icon[label]:not([label=""]) {
+ -moz-margin-end: 0;
+}
+
+@navbarLargeIcons@ *|* > .toolbarbutton-badge[badge]:not([badge=""])::after {
+ top: 1px;
+ right: 1px;
+}
+
+.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+ left: 0;
+ right: auto;
+}
+
+@navbarLargeIcons@ *|* > .toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+ left: 1px;
+ right: auto;
+}
+
+#main-window[privatebrowsingmode=temporary] #toolbar-menubar {
+ background-image: url("chrome://browser/skin/privatebrowsing-dark.png");
+ background-position: top right;
+ background-repeat: no-repeat;
+}
+
+#main-window[privatebrowsingmode=temporary] #toolbar-menubar:-moz-locale-dir(rtl) {
+ background-position: top left;
+}
+
+#main-window[privatebrowsingmode=temporary] #appmenu-button > .button-box > .box-inherit > .button-icon {
+ list-style-image: url("chrome://browser/skin/privatebrowsing-light.png");
+ width: 20px;
+ height: 16px;
+}
+
+@media not all and (-moz-windows-classic) {
+ #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container {
+ margin-top: 1px;
+ }
+
+ #appmenu-button {
+ border-width: 2px;
+ -moz-border-left-colors: @appMenuButtonBorderColor@;
+ -moz-border-bottom-colors: @appMenuButtonBorderColor@;
+ -moz-border-right-colors: @appMenuButtonBorderColor@;
+ margin-bottom: 1px; /* compensate white outer border */
+ box-shadow: 0 1px 0 rgba(255,255,255,.25) inset,
+ 0 0 2px 1px rgba(255,255,255,.25) inset;
+ }
+
+ #main-window[privatebrowsingmode=temporary] #appmenu-button {
+ -moz-border-left-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
+ -moz-border-bottom-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
+ -moz-border-right-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
+ }
+
+ #appmenu-popup {
+ margin-top: -1px;
+ -moz-margin-start: 1px;
+ }
+
+ .panel-promo-message {
+ font-style: italic;
+ }
+}
+
+@media (-moz-windows-default-theme) {
+ #navigator-toolbox > toolbar:not(:-moz-lwtheme),
+ #browser-bottombox:not(:-moz-lwtheme) {
+ background-color: var(--toolbar-custom-color);
+ }
+
+ .tabbrowser-tab:not(:-moz-lwtheme),
+ .tabs-newtab-button:not(:-moz-lwtheme) {
+ background-image: @toolbarShadowOnTab@, var(--tab-background),
+ linear-gradient(var(--toolbar-custom-color), var(--toolbar-custom-color));
+ }
+
+ .tabbrowser-tab:not(:-moz-lwtheme):hover,
+ .tabs-newtab-button:not(:-moz-lwtheme):hover {
+ background-image: @toolbarShadowOnTab@, var(--tab-background-hover),
+ linear-gradient(var(--toolbar-custom-color), var(--toolbar-custom-color));
+ }
+
+ .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
+ background-image: linear-gradient(#fff, var(--toolbar-highlight-top) 50%),
+ linear-gradient(var(--toolbar-custom-color), var(--toolbar-custom-color));
+ }
+
+ #main-window[tabsontop=false]:not([disablechrome]) .tabbrowser-tab[selected=true]:not(:-moz-lwtheme) {
+ background-image: @toolbarShadowOnTab@,
+ linear-gradient(#fff, var(--toolbar-highlight-top) 50%),
+ linear-gradient(var(--toolbar-custom-color), var(--toolbar-custom-color));
+ }
+
+ @media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ :root:not(:-moz-lwtheme) {
+ --toolbox-after-color: #aabccf;
+ }
+ }
+
+ @media (-moz-os-version: windows-win8),
+ (-moz-os-version: windows-win10) {
+ :root {
+ --toolbar-custom-color: hsl(210,0%,92%);
+ }
+
+ :root:not(:-moz-lwtheme) {
+ --toolbox-after-color: #bcbcbc;
+ }
+ }
+
+ #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme),
+ #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme) {
+ border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
+ }
+
+ #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme):not([focused]):hover,
+ #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme):not([focused]):hover {
+ border-color: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
+ }
+
+ #navigator-toolbox[tabsontop=true] #urlbar:not(:-moz-lwtheme)[focused],
+ #navigator-toolbox[tabsontop=true] .searchbar-textbox:not(:-moz-lwtheme)[focused] {
+ border-color: hsla(206,100%,60%,.65) hsla(206,100%,55%,.65) hsla(206,100%,50%,.65);
+ }
+
+ .sidebar-splitter {
+ border: 0;
+ -moz-border-end: 1px solid #A9B7C9;
+ min-width: 0;
+ width: 3px;
+ background-color: transparent;
+ -moz-margin-start: -3px;
+ position: relative;
+ }
+
+ #appcontent ~ .sidebar-splitter {
+ -moz-border-start: 1px solid #A9B7C9;
+ -moz-border-end: none;
+ -moz-margin-start: 0;
+ -moz-margin-end: -3px;
+ }
+
+ .menu-accel,
+ .menu-iconic-accel {
+ color: graytext;
+ }
+
+ .chatbar-button,
+ chatbar > chatbox {
+ border-color: #A9B7C9;
+ }
+}
+
+@media (-moz-windows-compositor) {
+ #main-window {
+ background-color: transparent;
+ -moz-appearance: -moz-win-glass;
+ }
+
+ /* On win 10, if we don't set this on the entire browser container, including
+ * the sidebar, then the accent color bleeds through in the titlebar
+ * if the sidebar is open. */
+ #browser {
+ -moz-appearance: -moz-win-exclude-glass;
+ }
+
+/* ==== Windows 10 styling ==== */
+
+ @media (-moz-os-version: windows-win10) {
+ /* Draw XUL caption buttons and background on Win10 */
+ @media (-moz-windows-accent-color-applies: 0) {
+ /* Default styling for when no accent color is applied */
+ #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ background-color: white;
+ }
+
+ :root:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ --window-text-color: black;
+ }
+
+ #titlebar-min:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize);
+ }
+
+ #titlebar-max:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize);
+ }
+
+ #main-window[sizemode="maximized"] #titlebar-max:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore);
+ }
+
+ #titlebar-close:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close);
+ }
+
+ .titlebar-button:not(#titlebar-close):not(:-moz-window-inactive):not(:-moz-lwtheme):hover {
+ background-color: hsla(0, 0%, 0%, .17);
+ }
+
+ .titlebar-button:not(#titlebar-close):not(:-moz-window-inactive):not(:-moz-lwtheme):hover:active {
+ background-color: hsla(0, 0%, 0%, .27);
+ transition: none;
+ }
+
+ #titlebar-close:not(:-moz-window-inactive):not(:-moz-lwtheme):hover {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-highlight);
+ background-color: hsla(0, 86%, 49%, 1);
+ }
+
+ #titlebar-close:not(:-moz-window-inactive):not(:-moz-lwtheme):hover:active {
+ background-color: hsla(0, 60%, 49%, 0.6);
+ transition: none;
+ }
+ }
+
+ @media (-moz-windows-accent-color-applies) {
+ /* Styling for when an accent color is applied to the titlebar */
+ #main-window:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ background-color: -moz-win-accentcolor;
+ }
+
+ :root:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+ --window-text-color: -moz-win-accentcolortext;
+ }
+
+ #titlebar-min {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize);
+ }
+
+ #titlebar-max {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize);
+ }
+
+ #main-window[sizemode="maximized"] #titlebar-max {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore);
+ }
+
+ #titlebar-close {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close);
+ }
+
+ .titlebar-button:hover {
+ background-color: hsla(0, 0%, 0%, .17);
+ }
+
+ .titlebar-button:hover:active {
+ background-color: hsla(0, 0%, 0%, .27);
+ transition: none;
+ }
+
+ @media (-moz-windows-accent-color-is-dark) {
+ /* dark accent color */
+ #titlebar-min {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-highlight);
+ }
+
+ #titlebar-max {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize-highlight);
+ }
+
+ #main-window[sizemode="maximized"] #titlebar-max {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-highlight);
+ }
+
+ #titlebar-close {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-highlight);
+ }
+
+ .titlebar-button:not(#titlebar-close):not(:-moz-window-inactive):not(:-moz-lwtheme):hover {
+ background-color: hsla(0, 0%, 100%, .17);
+ }
+
+ .titlebar-button:not(#titlebar-close):not(:-moz-window-inactive):not(:-moz-lwtheme):hover:active {
+ background-color: hsla(0, 0%, 100%, .27);
+ transition: none;
+ }
+
+ #titlebar-close:not(:-moz-window-inactive):not(:-moz-lwtheme):hover {
+ background-color: hsla(0, 86%, 49%, 1);
+ }
+
+ #titlebar-close:not(:-moz-window-inactive):not(:-moz-lwtheme):hover:active {
+ background-color: hsla(0, 60%, 39%, 1);
+ transition: none;
+ }
+ }
+ }
+
+ #main-window:-moz-window-inactive:not(:-moz-lwtheme) {
+ background-color: hsl(0, 0%, 95%);
+ }
+
+ /* If we don't have [chromemargin], it means the menubar is active; set the
+ window background to transparent in that case to match it with the dwm
+ color and prevent a drawing delay between title bar and UI region */
+ #main-window:not([chromemargin]):not(:-moz-lwtheme) {
+ background-color: transparent;
+ }
+
+ #titlebar-buttonbox,
+ .titlebar-button {
+ -moz-appearance: none !important;
+ }
+
+ .titlebar-button {
+ border: none;
+ margin: 0 !important;
+ padding: 9px 17px;
+ transition: background-color linear 120ms;
+ }
+
+ #main-window[sizemode="maximized"][tabsontop=true] #tabbrowser-tabs {
+ min-height: 28px;
+ }
+
+ #main-window[sizemode=maximized] .titlebar-button {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ }
+
+ .titlebar-button > .toolbarbutton-icon {
+ width: 12px;
+ height: 12px;
+ }
+
+ .titlebar-button:not(:hover) > .toolbarbutton-icon:-moz-window-inactive {
+ opacity: 0.5;
+ }
+
+ #main-window[chromemargin^="0,"][sizemode=normal] #navigator-toolbox {
+ margin-top: -4px;
+ }
+
+ #main-window[sizemode="maximized"] #titlebar-close {
+ padding-right: 19px;
+ }
+
+ #titlebar-close:hover {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-highlight);
+ background-color: hsla(0, 86%, 49%, 1);
+ transition: background-color linear 160ms;
+ }
+
+ #titlebar-close:hover:active {
+ background-color: hsla(0, 86%, 49%, 0.6);
+ transition: none;
+ }
+
+ /* inactive window */
+
+ #titlebar-min:-moz-window-inactive:not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-inactive);
+ }
+
+ #titlebar-max:-moz-window-inactive:not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize-inactive);
+ }
+
+ #main-window[sizemode="maximized"] #titlebar-max:-moz-window-inactive:not(:-moz-lwtheme) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-inactive);
+ }
+
+ #titlebar-close:-moz-window-inactive:not(:-moz-lwtheme):not(:hover) {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-inactive);
+ }
+
+ .titlebar-button:-moz-window-inactive:not(:-moz-lwtheme):hover {
+ background-color: hsla(0, 0%, 0%, .17);
+ }
+
+ .titlebar-button:-moz-window-inactive:not(:-moz-lwtheme):hover:active {
+ background-color: hsla(0, 0%, 0%, .27);
+ transition: none;
+ }
+
+ /* light persona */
+
+ .titlebar-button:-moz-lwtheme-darktext:hover {
+ background-color: hsla(0, 0%, 0%, .17);
+ }
+
+ .titlebar-button:-moz-lwtheme-darktext:hover:active {
+ background-color: hsla(0, 0%, 0%, .27);
+ transition: none;
+ }
+
+ #titlebar-min:-moz-lwtheme-darktext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-outline);
+ }
+
+ #titlebar-max:-moz-lwtheme-darktext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize-outline);
+ }
+
+ #main-window[sizemode="maximized"]:-moz-lwtheme-darktext #titlebar-max:-moz-lwtheme-darktext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-outline);
+ }
+
+ #titlebar-close:-moz-lwtheme-darktext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-outline);
+ }
+ #titlebar-close:hover:-moz-lwtheme-darktext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-outline);
+ }
+
+ /* dark persona */
+
+ .titlebar-button:-moz-lwtheme-brighttext:hover {
+ background-color: hsla(0, 0%, 100%, .27);
+ }
+
+ .titlebar-button:-moz-lwtheme-brighttext:hover:active {
+ background-color: hsla(0, 0%, 100%, .37);
+ transition: none;
+ }
+
+ #titlebar-min:-moz-lwtheme-brighttext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#minimize-outline-inverted);
+ }
+
+ #titlebar-max:-moz-lwtheme-brighttext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#maximize-outline-inverted);
+ }
+
+ #main-window[sizemode="maximized"]:-moz-lwtheme-brighttext #titlebar-max:-moz-lwtheme-brighttext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#restore-outline-inverted);
+ }
+
+ #titlebar-close:-moz-lwtheme-brighttext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-outline-inverted);
+ }
+ #titlebar-close:hover:-moz-lwtheme-brighttext {
+ list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-outline-inverted);
+ }
+
+ /* the 12px image renders a 10px icon, and the 10px upscaled gets rounded to 12.5, which
+ * rounds up to 13px, which makes the icon one pixel too big on 1.25dppx. Fix: */
+ @media (min-resolution: 1.20dppx) and (max-resolution: 1.45dppx) {
+ .titlebar-button > .toolbarbutton-icon {
+ width: 11.5px;
+ height: 11.5px;
+ }
+ }
+
+ /* 175% dpi should result in the same device pixel sizes as 150% dpi. */
+ @media (min-resolution: 1.70dppx) and (max-resolution: 1.95dppx) {
+ .titlebar-button {
+ padding-left: 14.1px;
+ padding-right: 14.1px;
+ }
+
+ .titlebar-button > .toolbarbutton-icon {
+ width: 10.8px;
+ height: 10.8px;
+ }
+ }
+
+ /* 225% dpi should result in the same device pixel sizes as 200% dpi. */
+ @media (min-resolution: 2.20dppx) and (max-resolution: 2.45dppx) {
+ .titlebar-button {
+ padding-left: 15.3333px;
+ padding-right: 15.3333px;
+ }
+
+ .titlebar-button > .toolbarbutton-icon {
+ width: 10.8px;
+ height: 10.8px;
+ }
+ }
+
+ /* 275% dpi should result in the same device pixel sizes as 250% dpi. */
+ @media (min-resolution: 2.70dppx) and (max-resolution: 2.95dppx) {
+ .titlebar-button > .toolbarbutton-icon {
+ width: 10.8px;
+ height: 10.8px;
+ }
+ }
+
+ #appmenu-button {
+ margin-top: -1px;
+ margin-bottom: 5px;
+ }
+ }
+
+/* ==== Windows Vista/7/8 styling ==== */
+
+ @media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7),
+ (-moz-os-version: windows-win8) {
+ /* Make sure the native margins are correct on Win Vista/7/8.
+ * We can't use -moz-win-glass there because the border sizing would
+ * not be correct. */
+ #main-window {
+ -moz-appearance: -moz-win-borderless-glass;
+ }
+
+ /* These should be hidden w/ glass enabled. Windows draws its own buttons. */
+ .titlebar-button {
+ display: none;
+ }
+
+ /* The borders on the glass frame are ours, and inside #browser, and on
+ * vista and win7 we want to make sure they are "glassy", so we can't use
+ * #browser as the exclude-glass container. We use #appcontent instead. */
+ #browser {
+ -moz-appearance: none;
+ }
+
+ #appcontent {
+ -moz-appearance: -moz-win-exclude-glass;
+ }
+
+ #main-window[chromemargin^="0,"][sizemode=normal] #navigator-toolbox {
+ margin-top: -7px;
+ }
+
+ /* Artificially draw window borders that are covered by lwtheme, see bug 591930. */
+ #main-window[sizemode="normal"] > #titlebar > #titlebar-content:-moz-lwtheme {
+ border-top: 2px solid;
+ -moz-border-top-colors: @glassActiveBorderColor@ rgba(255,255,255,.6);
+ }
+
+ #main-window[sizemode="normal"] > #titlebar > #titlebar-content:-moz-lwtheme:-moz-window-inactive {
+ -moz-border-top-colors: @glassInactiveBorderColor@ rgba(255,255,255,.6);
+ }
+
+ #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container:-moz-lwtheme {
+ margin-top: -1px;
+ }
+
+ #main-window[sizemode="normal"] #titlebar-buttonbox:-moz-lwtheme {
+ margin-top: -2px;
+ }
+
+ #appmenu-button {
+ margin-bottom: -1px; /* compensate white outer border */
+ }
+
+ }
+
+/* ==== Windows Vista/7 (true glass) styling ==== */
+
+ @media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ #toolbar-menubar:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme),
+ #nav-bar[tabsontop=false]:not(:-moz-lwtheme),
+ #nav-bar[tabsontop=false]:not(:-moz-lwtheme) .toolbarbutton-text,
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child:not(:-moz-lwtheme) {
+ text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
+ }
+
+ #main-menubar:not(:-moz-lwtheme):not(:-moz-window-inactive) {
+ background-color: rgba(255,255,255,.7);
+ border-radius: var(--toolbarbutton-border-radius);
+ color: black;
+ }
+
+ :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
+ :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme) {
+ list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
+ }
+ }
+
+/* ==== Windows 8/10 (flat color) styling ==== */
+
+ @media (-moz-os-version: windows-win8) {
+ /* Use a light text styling on dark window frames */
+ :root[darkwindowframe="true"]:not(:-moz-lwtheme):not(:-moz-window-inactive) {
+ --window-text-color: white;
+ }
+ }
+
+ @media (-moz-os-version: windows-win8),
+ (-moz-os-version: windows-win10) {
+ /* Fade text stylings on window inactivity */
+ :root:not(:-moz-lwtheme):-moz-window-inactive {
+ --window-text-color: rgba(0, 0, 0, 0.5);
+ }
+ }
+
+/* ==== ==== */
+
+ #main-window[sizemode=fullscreen]:not(:-moz-lwtheme) {
+ -moz-appearance: none;
+ background-color: #556;
+ }
+
+ #toolbar-menubar:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme),
+ #nav-bar[tabsontop=false]:not(:-moz-lwtheme),
+ #nav-bar[tabsontop=false]:not(:-moz-lwtheme) .toolbarbutton-text,
+ #nav-bar + #customToolbars + #PersonalToolbar:-moz-any([collapsed=true],[moz-collapsed=true]) + #TabsToolbar[tabsontop=false]:last-child:not(:-moz-lwtheme) {
+ background-color: transparent !important;
+ color: var(--window-text-color);
+ border-left-style: none !important;
+ border-right-style: none !important;
+ }
+
+ #main-menubar > menu:not(:-moz-lwtheme) {
+ color: inherit;
+ }
+
+ :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) :-moz-any(@primaryToolbarButtons@) > toolbarbutton > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@) > toolbarbutton > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@) > toolbarbutton > .toolbarbutton-icon:not(:-moz-lwtheme) {
+ list-style-image: var(--toolbarbutton-glass-image);
+ }
+
+/* Show toolbar borders on vista through win8, but not on win10 and later: */
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7),
+ (-moz-os-version: windows-win8) {
+ /* Vertical toolbar border */
+ #main-window[sizemode=normal] #navigator-toolbox::after,
+ #main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > toolbar:not(#toolbar-menubar):not(#TabsToolbar),
+ #main-window[sizemode=normal] #navigator-toolbox[tabsontop=false] > toolbar:not(#toolbar-menubar):not(#nav-bar) {
+ border-left: 1px solid @toolbarShadowColor@;
+ border-right: 1px solid @toolbarShadowColor@;
+ background-clip: padding-box;
+ }
+ #main-window[sizemode=normal] #navigator-toolbox > toolbar:-moz-lwtheme {
+ border-color: transparent !important;
+ }
+ #main-window[sizemode=normal] #browser-border-start,
+ #main-window[sizemode=normal] #browser-border-end {
+ display: -moz-box;
+ background-color: @toolbarShadowColor@;
+ width: 1px;
+ }
+ #main-window[sizemode=normal] #browser-bottombox {
+ border: 1px solid @toolbarShadowColor@;
+ border-top-style: none;
+ background-clip: padding-box;
+ }
+}
+
+ #main-window[sizemode=normal][tabsontop=false] #PersonalToolbar:not(:-moz-lwtheme) {
+ border-top-left-radius: var(--toolbarbutton-border-radius);
+ border-top-right-radius: var(--toolbarbutton-border-radius);
+ }
+
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true]:not(:-moz-lwtheme),
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
+ #main-window[sizemode=normal][disablechrome] #navigator-toolbox[tabsontop=true]:not(:-moz-lwtheme)::after {
+ border-top-left-radius: var(--toolbarbutton-border-radius);
+ border-top-right-radius: var(--toolbarbutton-border-radius);
+ }
+
+ /* Toolbar shadow behind tabs */
+ /* This code is only needed for restored windows (i.e. sizemode=normal)
+ because of the border radius on the toolbar below the tab bar. */
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true]:not(:-moz-lwtheme),
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
+ #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
+ #main-window[sizemode=normal][disablechrome] #navigator-toolbox[tabsontop=true]:not(:-moz-lwtheme)::after {
+ border-top: 1px solid @toolbarShadowColor@;
+ background-clip: padding-box;
+ }
+ #main-window[sizemode=normal] #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) {
+ margin-bottom: -1px;
+ background-image: none !important;
+ }
+ #main-window[sizemode=normal] #tabbrowser-tabs[tabsontop=true] > .tabbrowser-arrowscrollbox > .arrowscrollbox-scrollbox > .scrollbox-innerbox:not(:-moz-lwtheme) {
+ position: relative;
+ }
+
+ #navigator-toolbox[tabsontop=false] > #PersonalToolbar {
+ margin-top: 3px;
+ }
+
+ #navigator-toolbox[tabsontop=false] > #PersonalToolbar:not(:-moz-lwtheme) {
+ margin-top: 2px;
+ border-top: 1px solid @toolbarShadowColor@;
+ background-image: linear-gradient(var(--toolbar-highlight-top), var(--toolbar-highlight-bottom));
+ }
+
+ @media (-moz-os-version: windows-win10) {
+ /* Remove gradient and make border faded */
+ #navigator-toolbox[tabsontop=false] > #PersonalToolbar:not(:-moz-lwtheme) {
+ border-top: 1px solid rgba(10%,10%,10%,.2);
+ background-image: none;
+ }
+ }
+
+ #main-window[sizemode=normal] #TabsToolbar[tabsontop=true] {
+ padding-left: 4px;
+ padding-right: 4px;
+ }
+
+ #main-window[sizemode=normal] #TabsToolbar[tabsontop=false] {
+ padding-left: 2px;
+ padding-right: 2px;
+ }
+
+ /* Rounded corners for when chrome is disabled */
+ #main-window[sizemode=normal][disablechrome] #navigator-toolbox[tabsontop=true]:not(:-moz-lwtheme)::after {
+ visibility: visible;
+ background-color: var(--toolbar-custom-color);
+ background-image: linear-gradient(var(--toolbar-highlight-top), var(--toolbar-highlight-top));
+ height: 4px;
+ }
+
+ /* Make the window draggable by glassed toolbars (bug 555081) */
+ #toolbar-menubar:not([autohide="true"]),
+ #TabsToolbar[tabsontop="true"],
+ #nav-bar[tabsontop=false],
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar[tabsontop="false"]:last-child,
+ #navigator-toolbox > toolbar:not(#toolbar-menubar):-moz-lwtheme {
+ -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
+ }
+
+ #appcontent:not(:-moz-lwtheme) {
+ background-color: -moz-dialog;
+ }
+
+ #navigator-toolbox[tabsontop=false] #urlbar:not(:-moz-lwtheme),
+ #navigator-toolbox[tabsontop=false] .searchbar-textbox:not(:-moz-lwtheme) {
+ background-color: rgba(255,255,255,.725);
+ @navbarTextboxCustomBorder@
+ color: black;
+ }
+
+ #navigator-toolbox[tabsontop=false] html|*.urlbar-input:not(:-moz-lwtheme)::-moz-placeholder,
+ #navigator-toolbox[tabsontop=false] .searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box > html|*.textbox-input:not(:-moz-lwtheme)::-moz-placeholder {
+ opacity: 1.0;
+ color: #777;
+ }
+
+ #navigator-toolbox[tabsontop=false] #urlbar:not(:-moz-lwtheme):hover,
+ #navigator-toolbox[tabsontop=false] .searchbar-textbox:not(:-moz-lwtheme):hover {
+ background-color: rgba(255,255,255,.898);
+ }
+
+ #navigator-toolbox[tabsontop=false] #urlbar:not(:-moz-lwtheme)[focused],
+ #navigator-toolbox[tabsontop=false] .searchbar-textbox:not(:-moz-lwtheme)[focused] {
+ background-color: white;
+ }
+
+ .tabbrowser-tab:not(:-moz-lwtheme) {
+ text-shadow: none;
+ }
+
+ #main-window[sizemode=normal] .statuspanel-inner {
+ /* align with the browser's side borders */
+ padding-left: 1px;
+ padding-right: 1px;
+ }
+
+ #allTabs-panel,
+ #ctrlTab-panel {
+ background: transparent;
+ -moz-appearance: -moz-win-glass;
+ border-radius: 0;
+ border: none;
+ font: normal 1.2em "Segoe UI";
+ color: black;
+ text-shadow: white -1px -1px .35em, white -1px 1px .35em, white 1px 1px .35em, white 1px -1px .35em;
+ }
+}
+
+@media not all and (-moz-windows-compositor) {
+ @media (-moz-windows-default-theme) {
+ #main-window {
+ background-color: rgb(185,209,234);
+ }
+ #main-window:-moz-window-inactive {
+ background-color: rgb(215,228,242);
+ }
+
+ #toolbar-menubar:not([autohide=true]):not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme),
+ #navigator-toolbox[tabsontop=false] > toolbar:not(#toolbar-menubar):not(:-moz-lwtheme) {
+ -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
+ background-color: transparent;
+ }
+ #toolbar-menubar[autohide=true] {
+ background-color: transparent !important;
+ }
+ }
+
+ #print-preview-toolbar:not(:-moz-lwtheme) {
+ -moz-appearance: -moz-win-browsertabbar-toolbox;
+ }
+}
+
+/* ::::: fullscreen window controls ::::: */
+
+#window-controls {
+ -moz-box-align: start;
+}
+
+#minimize-button,
+#restore-button,
+#close-button {
+ -moz-appearance: none;
+ border-style: none;
+ margin: 0;
+}
+#close-button {
+ -moz-image-region: rect(0, 49px, 16px, 32px);
+}
+#close-button:hover {
+ -moz-image-region: rect(16px, 49px, 32px, 32px);
+}
+#close-button:hover:active {
+ -moz-image-region: rect(32px, 49px, 48px, 32px);
+}
+
+#minimize-button:-moz-locale-dir(rtl),
+#restore-button:-moz-locale-dir(rtl),
+#close-button:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+/* ::::: splitmenu highlight style that imitates Windows 7 start menu ::::: */
+@media (-moz-os-version: windows-vista) and (-moz-windows-default-theme),
+ (-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
+ .splitmenu-menuitem,
+ .splitmenu-menu {
+ -moz-appearance: none;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border: 1px solid transparent;
+ }
+ .splitmenu-menuitem {
+ -moz-margin-end: 0;
+ }
+ .splitmenu-menu {
+ -moz-margin-start: -1px;
+ }
+ .splitmenu-menuitem:-moz-locale-dir(ltr),
+ .splitmenu-menu:-moz-locale-dir(rtl) {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+ .splitmenu-menu:-moz-locale-dir(ltr),
+ .splitmenu-menuitem:-moz-locale-dir(rtl) {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ }
+
+ .splitmenu-menuitem > .menu-text {
+ -moz-margin-start: 1px !important;
+ -moz-margin-end: 3px !important;
+ }
+ .splitmenu-menu > .menu-right {
+ -moz-margin-end: -3px;
+ }
+
+ .splitmenu-menuitem[iconic],
+ .splitmenu-menu[iconic] {
+ padding-bottom: 1px;
+ }
+ .splitmenu-menuitem[iconic] > .menu-iconic-left {
+ margin-top: -3px;
+ margin-bottom: -2px;
+ -moz-margin-start: -1px;
+ }
+ .splitmenu-menuitem[iconic] > .menu-iconic-text {
+ -moz-margin-start: 2px !important;
+ -moz-margin-end: 3px !important;
+ }
+ .splitmenu-menu[iconic] > .menu-right {
+ margin-top: -1px;
+ }
+
+ .splitmenu-menuitem[_moz-menuactive],
+ .splitmenu-menu[_moz-menuactive] {
+ background-color: transparent;
+ background-image: linear-gradient(#fafbfd, #ebf3fd);
+ border-color: #aeccf1;
+ }
+
+ .splitmenu-menuitem[disabled][_moz-menuactive],
+ .splitmenu-menu[disabled][_moz-menuactive] {
+ background-image: linear-gradient(#f8f9f9, #eaeaea);
+ border-color: #d8d7d7;
+ }
+
+ .splitmenu-menu[_moz-menuactive]:not(:hover):not([open]) {
+ background-image: none;
+ }
+}
diff --git a/themes/windows/caption-buttons.svg b/themes/windows/caption-buttons.svg
new file mode 100644
index 0000000..9342aca
--- /dev/null
+++ b/themes/windows/caption-buttons.svg
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/themes/windows/click-to-play-warning-stripes.png b/themes/windows/click-to-play-warning-stripes.png
new file mode 100644
index 0000000..29f15f7
Binary files /dev/null and b/themes/windows/click-to-play-warning-stripes.png differ
diff --git a/themes/windows/communicator/communicator.css b/themes/windows/communicator/communicator.css
new file mode 100644
index 0000000..0b57574
--- /dev/null
+++ b/themes/windows/communicator/communicator.css
@@ -0,0 +1,6 @@
+/* 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/. */
+
+@import url("chrome://global/skin/");
+
diff --git a/themes/windows/communicator/jar.mn b/themes/windows/communicator/jar.mn
new file mode 100644
index 0000000..612d133
--- /dev/null
+++ b/themes/windows/communicator/jar.mn
@@ -0,0 +1,7 @@
+# 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:
+% skin communicator classic/1.0 %skin/classic/communicator/
+ skin/classic/communicator/communicator.css
diff --git a/themes/windows/communicator/moz.build b/themes/windows/communicator/moz.build
new file mode 100644
index 0000000..c97072b
--- /dev/null
+++ b/themes/windows/communicator/moz.build
@@ -0,0 +1,7 @@
+# -*- 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']
\ No newline at end of file
diff --git a/themes/windows/downloads/allDownloadsViewOverlay.css b/themes/windows/downloads/allDownloadsViewOverlay.css
new file mode 100644
index 0000000..bd3b789
--- /dev/null
+++ b/themes/windows/downloads/allDownloadsViewOverlay.css
@@ -0,0 +1,178 @@
+/* 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/. */
+
+#downloadsRichListBox {
+ /** The default listbox appearance comes with an unwanted margin. **/
+ -moz-appearance: none;
+ margin: 0;
+}
+
+#downloadsRichListBox > richlistitem.download {
+ height: 6em;
+}
+
+.downloadTypeIcon {
+ -moz-margin-start: 8px;
+ -moz-margin-end: 8px;
+ /* explicitly size the icon, so size doesn't vary on hidpi systems */
+ height: 32px;
+ width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+.downloadTarget {
+ margin-bottom: 3px;
+ cursor: inherit;
+}
+
+.downloadDetails {
+ opacity: 0.7;
+ font-size: 95%;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ background: transparent;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+
+richlistitem.download:hover > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+
+@media not all and (-moz-os-version: windows-vista) and (-moz-windows-default-theme) {
+ @media not all and (-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
+ richlistitem.download[selected] > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 80px, 16px, 64px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 96px, 16px, 80px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 112px, 16px, 96px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 128px, 16px, 112px);
+ }
+
+ richlistitem.download[selected] > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 80px, 32px, 64px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 96px, 32px, 80px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 112px, 32px, 96px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 128px, 32px, 112px);
+ }
+
+ richlistitem.download[selected] > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 80px, 48px, 64px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 96px, 48px, 80px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 112px, 48px, 96px);
+ }
+
+ richlistitem.download[selected]:hover > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 128px, 48px, 112px);
+ }
+ }
+}
+
+@media (-moz-os-version: windows-vista) and (-moz-windows-default-theme),
+ (-moz-os-version: windows-win7) and (-moz-windows-default-theme) {
+ /*
+ -moz-appearance: menuitem is almost right, but the hover effect is not
+ transparent and is lighter than desired.
+
+ Copied from the autocomplete richlistbox styling in
+ toolkit/themes/windows/global/autocomplete.css
+
+ This styling should be kept in sync with the style from the above file.
+ */
+ #downloadsRichListBox > richlistitem.download[selected] {
+ color: inherit;
+ background-color: transparent;
+ /* four gradients for the bevel highlights on each edge, one for blue background */
+ background-image:
+ linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
+ linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
+ linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
+ linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
+ linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
+ background-clip: content-box;
+ border-radius: 6px;
+ outline: 1px solid rgb(124,163,206);
+ -moz-outline-radius: 3px;
+ outline-offset: -2px;
+ }
+}
diff --git a/themes/windows/downloads/buttons.png b/themes/windows/downloads/buttons.png
new file mode 100644
index 0000000..ca87b40
Binary files /dev/null and b/themes/windows/downloads/buttons.png differ
diff --git a/themes/windows/downloads/contentAreaDownloadsView.css b/themes/windows/downloads/contentAreaDownloadsView.css
new file mode 100644
index 0000000..ece99ea
--- /dev/null
+++ b/themes/windows/downloads/contentAreaDownloadsView.css
@@ -0,0 +1,22 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+.downloadButton {
+ box-shadow: none;
+}
+
+.downloadButton:not([disabled="true"]):hover:active,
+.downloadButton:not([disabled]):hover:active {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+}
+
+#downloadsListEmptyDescription {
+ margin: 1em;
+ text-align: center;
+ color: GrayText;
+}
diff --git a/themes/windows/downloads/download-notification-finish.png b/themes/windows/downloads/download-notification-finish.png
new file mode 100644
index 0000000..5194f5d
Binary files /dev/null and b/themes/windows/downloads/download-notification-finish.png differ
diff --git a/themes/windows/downloads/download-notification-start.png b/themes/windows/downloads/download-notification-start.png
new file mode 100644
index 0000000..bd548b1
Binary files /dev/null and b/themes/windows/downloads/download-notification-start.png differ
diff --git a/themes/windows/downloads/download-summary.png b/themes/windows/downloads/download-summary.png
new file mode 100644
index 0000000..67003c7
Binary files /dev/null and b/themes/windows/downloads/download-summary.png differ
diff --git a/themes/windows/downloads/downloads.css b/themes/windows/downloads/downloads.css
new file mode 100644
index 0000000..f169896
--- /dev/null
+++ b/themes/windows/downloads/downloads.css
@@ -0,0 +1,487 @@
+/* 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/. */
+
+/*** Panel and outer controls ***/
+
+#downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
+ padding: 0;
+}
+
+#downloadsListBox {
+ background-color: transparent;
+ padding: 4px;
+ color: inherit;
+}
+
+#downloadsPanel:not([hasdownloads]) > #downloadsListBox {
+ display: none;
+}
+
+#downloadsPanel[hasdownloads] > #emptyDownloads {
+ display: none;
+}
+
+#emptyDownloads {
+ padding: 10px 20px;
+ max-width: 40ch;
+}
+
+#downloadsHistory {
+ background: transparent;
+ cursor: pointer;
+}
+
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ #downloadsHistory {
+ color: -moz-nativehyperlinktext;
+ }
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsHistory:focus {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -1px;
+}
+
+#downloadsHistory > .button-box {
+ border: none;
+ margin: 1em;
+}
+
+#downloadsFooter {
+ background-color: hsla(210,4%,10%,.04);
+ box-shadow: 0 1px 0 hsla(210,4%,10%,.08) inset;
+ transition-duration: 150ms;
+ transition-property: background-color;
+}
+
+#downloadsFooter:hover {
+ background-color: hsla(210,4%,10%,.05);
+}
+
+#downloadsFooter:hover:active {
+ background-color: hsla(210,4%,10%,.1);
+ box-shadow: 0 2px 0 0 hsla(210,4%,10%,.1) inset;
+}
+
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ @media (-moz-windows-default-theme) {
+ #downloadsFooter {
+ border-bottom-left-radius: 3px;
+ border-bottom-right-radius: 3px;
+ transition-duration: 0s;
+ }
+
+ #downloadsFooter,
+ #downloadsFooter:hover,
+ #downloadsFooter:hover:active {
+ background-color: #f1f5fb;
+ box-shadow: 0px 1px 2px rgb(204,214,234) inset;
+ }
+ }
+}
+
+/*** Downloads Summary and List items ***/
+
+#downloadsSummary,
+richlistitem[type="download"] {
+ height: 7em;
+ -moz-padding-end: 0;
+ color: inherit;
+}
+
+#downloadsSummary {
+ padding: 8px 38px 8px 12px;
+ cursor: pointer;
+ -moz-user-focus: normal;
+}
+
+#downloadsPanel[keyfocus] > #downloadsFooter > #downloadsSummary:focus {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -5px;
+}
+
+#downloadsSummary > .downloadTypeIcon {
+ list-style-image: url("chrome://browser/skin/downloads/download-summary.png");
+}
+
+#downloadsSummaryDescription {
+ color: -moz-nativehyperlinktext;
+}
+
+richlistitem[type="download"] {
+ margin: 0;
+ border-top: 1px solid hsla(0,0%,100%,.3);
+ border-bottom: 1px solid hsla(220,18%,51%,.25);
+ background: transparent;
+ padding: 8px;
+}
+
+@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
+ (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
+ richlistitem[type="download"] {
+ border: 1px solid transparent;
+ border-bottom: 1px solid hsl(213,40%,90%);
+ }
+}
+
+richlistitem[type="download"]:first-child {
+ border-top: 1px solid transparent;
+}
+
+@media (-moz-windows-default-theme) {
+ richlistitem[type="download"]:last-child {
+ border-bottom: 1px solid transparent;
+ }
+}
+
+#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] {
+ outline: 1px -moz-dialogtext dotted;
+ outline-offset: -1px;
+}
+
+.downloadTypeIcon {
+ -moz-margin-end: 8px;
+ /* Prevent flickering when changing states. */
+ height: 32px;
+ width: 32px;
+}
+
+.blockedIcon {
+ list-style-image: url("chrome://global/skin/icons/Error.png");
+}
+
+/* We hold .downloadDisplayName, .downloadProgress and .downloadDetails
+ inside of a vbox with class .downloadContainer. We set the font-size of
+ the entire container to 90% because:
+
+ 1) This is the size that we want .downloadDetails to be
+ 2) The container's width is set by localizers by &downloadDetails.width;,
+ which is a ch unit. Since this is the value that should control the
+ panel width, we apply it to the outer container to constrain
+ .downloadDisplayName and .downloadProgress.
+
+ Finally, since we want .downloadDisplayName's font-size to be at 100% of
+ the font-size of .downloadContainer's parent, we use calc to go from the
+ smaller font-size back to the original font-size.
+ */
+#downloadsSummaryDetails,
+.downloadContainer {
+ font-size: 90%;
+}
+
+#downloadsSummaryDescription,
+.downloadDisplayName {
+ margin-bottom: 6px;
+ cursor: inherit;
+}
+
+.downloadDisplayName {
+ font-size: calc(100%/0.9);
+}
+
+#downloadsSummaryDetails,
+.downloadDetails {
+ opacity: 0.6;
+ cursor: inherit;
+}
+
+.downloadButton {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ margin: 3px;
+ border: none;
+ background: transparent;
+ padding: 5px;
+ list-style-image: url("chrome://browser/skin/downloads/buttons.png");
+}
+
+.downloadButton > .button-box {
+ border: 1px solid transparent;
+ padding: 0;
+}
+
+#downloadsPanel[keyfocus] .downloadButton:focus > .button-box {
+ border: 1px dotted ThreeDDarkShadow;
+}
+
+/*** Highlighted list items ***/
+
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
+ background-color: hsla(210,4%,10%,.08);
+ outline: 1px solid hsla(210,4%,10%,.1);
+ outline-offset: -1px;
+ cursor: pointer;
+}
+
+#downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover:active {
+ background-color: hsla(210,4%,10%,.15);
+ outline: 1px solid hsla(210,4%,10%,.15);
+ box-shadow: 0 1px 0 0 hsla(210,4%,10%,.05) inset;
+}
+
+@media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ #downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
+ border-radius: 3px;
+ outline: 0;
+ border-top: 1px solid hsla(0,0%,100%,.2);
+ border-bottom: 1px solid hsla(0,0%,0%,.2);
+ background-color: Highlight;
+ color: HighlightText;
+ }
+
+ #downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover:active {
+ background-color: Highlight;
+ outline: 0;
+ box-shadow: none;
+ }
+}
+
+@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
+ (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
+ #downloadsPanel:not([keyfocus]) > #downloadsListBox > richlistitem[type="download"][state="1"][exists]:hover {
+ border: 1px solid hsl(213,45%,65%);
+ box-shadow: 0 0 0 1px hsla(0,0%,100%,.5) inset,
+ 0 1px 0 hsla(0,0%,100%,.3) inset;
+ background-image: linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
+ color: black;
+ }
+}
+
+/*** Button icons ***/
+
+.downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadShow:active {
+ -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+
+.downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 16px, 48px, 0px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry {
+ -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:hover {
+ -moz-image-region: rect(32px, 48px, 48px, 32px);
+}
+richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:active {
+ -moz-image-region: rect(32px, 64px, 48px, 48px);
+}
+
+/*** Status and progress indicator ***/
+
+#downloads-indicator-anchor {
+ /* Makes the outermost stack element positioned, so that its contents are
+ rendered over the main browser window in the Z order. This is required by
+ the animated event notification. */
+ position: relative;
+}
+
+#navigator-toolbox[iconsize=large][mode=icons] > #nav-bar[brighttext] #downloads-indicator[counter] > #downloads-indicator-anchor {
+ /* Use a dark download button when appropriate to improve text legibility */
+ background: hsla(94,56%,18%,.3) padding-box;
+ background-image: linear-gradient(hsla(0,0%,0%,.1), hsla(0,0%,0%,.4));
+ border-color: hsla(29,12%,90%,.2) hsla(29,12%,90%,.2) hsla(29,12%,90%,.2);
+ box-shadow: 0 1px hsla(0,0%,0%,.05) inset,
+ 0 1px hsla(29,12%,90%,.05),
+ 0 0 2px hsla(29,12%,90%,.05);
+}
+
+/*** Main indicator icon ***/
+
+#downloads-indicator-icon {
+ background: -moz-image-rect(var(--toolbarbutton-image),
+ 0, 108, 18, 90) center no-repeat;
+ min-width: 18px;
+ min-height: 18px;
+}
+
+toolbar[brighttext] #downloads-indicator-icon {
+ background: -moz-image-rect(var(--toolbarbutton-inverted-image),
+ 0, 108, 18, 90) center no-repeat;
+}
+
+#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background: -moz-image-rect(var(--toolbarbutton-image),
+ 19, 108, 36, 90) center no-repeat;
+}
+
+@media (-moz-windows-compositor) {
+ :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) #downloads-indicator-icon:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] #downloads-indicator-icon:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #downloads-indicator-icon:not(:-moz-lwtheme) {
+ background: -moz-image-rect(var(--toolbarbutton-glass-image),
+ 0, 108, 18, 90) center no-repeat;
+ }
+ #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+ background: -moz-image-rect(var(--toolbarbutton-glass-image),
+ 19, 108, 36, 90) center no-repeat;
+}
+
+
+}
+
+/* In the next few rules, we use :not([counter]) as a shortcut that is
+ equivalent to -moz-any([progress], [paused]). */
+
+#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(var(--toolbarbutton-image),
+ 0, 108, 18, 90) center no-repeat;
+ background-size: 12px;
+}
+
+toolbar[brighttext] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(var(--toolbarbutton-inverted-image),
+ 0, 108, 18, 90) center no-repeat;
+}
+
+@media (-moz-windows-compositor) {
+ :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter:not(:-moz-lwtheme) {
+ background: -moz-image-rect(var(--toolbarbutton-glass-image),
+ 0, 108, 18, 90) center no-repeat;
+ }
+ #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
+ background: -moz-image-rect(var(--toolbarbutton-glass-image),
+ 19, 108, 36, 90) center no-repeat;
+ }
+}
+
+/*** Download notifications ***/
+
+#downloads-indicator-notification {
+ opacity: 0;
+ background-size: 16px;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+@keyframes downloadsIndicatorNotificationStartRight {
+ from { opacity: 0; transform: translate(-128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+@keyframes downloadsIndicatorNotificationStartLeft {
+ from { opacity: 0; transform: translate(128px, 128px) scale(8); }
+ 20% { opacity: .85; animation-timing-function: ease-out; }
+ to { opacity: 0; transform: translate(0) scale(1); }
+}
+
+#downloads-indicator[notification="start"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-start.png");
+ animation-name: downloadsIndicatorNotificationStartRight;
+ animation-duration: 1s;
+}
+
+#downloads-indicator[notification="start"]:-moz-locale-dir(rtl) > #downloads-indicator-anchor > #downloads-indicator-notification {
+ animation-name: downloadsIndicatorNotificationStartLeft;
+}
+
+@keyframes downloadsIndicatorNotificationFinish {
+ from { opacity: 0; transform: scale(1); }
+ 20% { opacity: .65; animation-timing-function: ease-in; }
+ to { opacity: 0; transform: scale(8); }
+}
+
+#downloads-indicator[notification="finish"] > #downloads-indicator-anchor > #downloads-indicator-notification {
+ background-image: url("chrome://browser/skin/downloads/download-notification-finish.png");
+ animation-name: downloadsIndicatorNotificationFinish;
+ animation-duration: 1s;
+}
+
+/*** Progress bar and text ***/
+
+#downloads-indicator-counter {
+ height: 9px;
+ margin: -3px 0px 0px 0px;
+ color: hsl(0,0%,30%);
+ text-shadow: hsla(0,0%,100%,.5) 0 1px;
+ font-size: 9px;
+ line-height: 9px;
+ text-align: center;
+}
+
+toolbar[brighttext] #downloads-indicator-counter {
+ color: white;
+ text-shadow: 0 0 1px rgba(0,0,0,.7),
+ 0 1px 1.5px rgba(0,0,0,.5);
+}
+
+#downloads-indicator-progress {
+ width: 16px;
+ height: 5px;
+ min-width: 0;
+ min-height: 0;
+ margin-top: 1px;
+ margin-bottom: 2px;
+ border-radius: 2px;
+ box-shadow: 0 1px 0 hsla(0,0%,100%,.4);
+}
+
+#downloads-indicator-progress > .progress-bar {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ /* The background-clip: border-box; and background-image: none; are there to expand the background-color behind the border */
+ background-clip: padding-box, border-box;
+ background-color: rgb(90, 201, 66);
+ background-image: linear-gradient(transparent 1px, rgba(255, 255, 255, 0.4) 1px, rgba(255, 255, 255, 0.4) 2px, transparent 2px), none;
+ border: 1px solid;
+ border-color: rgba(0,43,86,.6) rgba(0,43,86,.4) rgba(0,43,86,.4);
+ border-radius: 2px 0 0 2px;
+}
+
+#downloads-indicator-progress > .progress-remainder {
+ -moz-appearance: none;
+ min-width: 0;
+ min-height: 0;
+ background-image: linear-gradient(#505050, #575757);
+ border: 1px solid;
+ border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
+ -moz-border-start: none;
+ border-radius: 0 2px 2px 0;
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-bar {
+ background-color: rgb(220, 230, 81);
+}
+
+#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
+ background-image: linear-gradient(#4b5000, #515700);
+}
+
+toolbar[mode="full"] > #downloads-indicator > .toolbarbutton-text {
+ margin: 0;
+ text-align: center;
+}
+
+#downloads-indicator-counter {
+ margin-bottom: -1px;
+}
diff --git a/themes/windows/engineManager.css b/themes/windows/engineManager.css
new file mode 100644
index 0000000..18817cd
--- /dev/null
+++ b/themes/windows/engineManager.css
@@ -0,0 +1,16 @@
+%if 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/. */
+%endif
+
+#engineList treechildren::-moz-tree-image(engineName) {
+ -moz-margin-end: 4px;
+ -moz-margin-start: 1px;
+ width: 16px;
+ height: 16px;
+}
+
+#engineList treechildren::-moz-tree-row {
+ height: 20px;
+}
diff --git a/themes/windows/feeds/feed-icons-16.png b/themes/windows/feeds/feed-icons-16.png
new file mode 100644
index 0000000..b822aa4
Binary files /dev/null and b/themes/windows/feeds/feed-icons-16.png differ
diff --git a/themes/windows/feeds/feedIcon.png b/themes/windows/feeds/feedIcon.png
new file mode 100644
index 0000000..b4d5994
Binary files /dev/null and b/themes/windows/feeds/feedIcon.png differ
diff --git a/themes/windows/feeds/feedIcon16.png b/themes/windows/feeds/feedIcon16.png
new file mode 100644
index 0000000..7c3aceb
Binary files /dev/null and b/themes/windows/feeds/feedIcon16.png differ
diff --git a/themes/windows/feeds/subscribe-ui.css b/themes/windows/feeds/subscribe-ui.css
new file mode 100644
index 0000000..8ca5328
--- /dev/null
+++ b/themes/windows/feeds/subscribe-ui.css
@@ -0,0 +1,29 @@
+/* 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/. */
+
+.alwaysUse {
+ padding: 5px;
+}
+
+.handlersMenuPopup > menuitem {
+ -moz-padding-start: 23px;
+}
+
+.handlersMenuPopup > menuitem.menuitem-iconic {
+ -moz-padding-start: 2px;
+}
+
+.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
+ display: -moz-box;
+ min-width: 16px;
+ -moz-padding-end: 2px;
+}
+
+.chooseApplicationMenuItem {
+ list-style-image: url("chrome://browser/skin/preferences/application.png");
+}
+
+#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
+ direction: rtl;
+}
diff --git a/themes/windows/feeds/subscribe.css b/themes/windows/feeds/subscribe.css
new file mode 100644
index 0000000..dc9304b
--- /dev/null
+++ b/themes/windows/feeds/subscribe.css
@@ -0,0 +1,163 @@
+/* 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/. */
+
+html {
+ background: -moz-Dialog;
+ font: 3mm tahoma,arial,helvetica,sans-serif;
+}
+
+#feedBody {
+ border: 1px solid THreeDShadow;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ margin: 2em auto;
+ background: -moz-Field;
+}
+
+#feedHeaderContainer {
+ border: 1px solid ThreeDShadow;
+ border-radius: 10px;
+ margin: -4em auto 0 auto;
+ background-color: InfoBackground;
+}
+
+#feedHeader {
+ margin-top: 4.9em;
+ margin-bottom: 1em;
+ -moz-margin-start: 1.4em;
+ -moz-margin-end: 1em;
+ -moz-padding-start: 2.9em;
+ font-size: 110%;
+ color: InfoText;
+}
+
+#feedIntroText {
+ display: none;
+}
+
+.feedBackground {
+ background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.videoPodcastBackground {
+ background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+.audioPodcastBackground {
+ background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
+}
+
+#feedHeader[dir="rtl"] {
+ background-position: 100% 10%;
+}
+
+#feedHeader[firstrun="true"] #feedIntroText {
+ padding-top: 0.1em;
+ -moz-padding-start: 0.6em;
+ display: block;
+}
+
+#feedHeader[firstrun="true"] > #feedSubscribeLine {
+ -moz-padding-start: 1.8em;
+}
+
+#feedSubscribeLine {
+ padding-top: 0.2em;
+}
+
+img {
+ max-width: 100%;
+}
+
+/* Don't print subscription UI */
+@media print {
+ #feedHeaderContainer {
+ display: none;
+ }
+}
+
+body {
+ margin: 0;
+ padding: 0 3em;
+ color: -moz-fieldText;
+ font: message-box;
+}
+
+h1 {
+ font-size: 160%;
+ border-bottom: 2px solid ThreeDLightShadow;
+ margin: 0 0 .2em 0;
+}
+
+h2 {
+ color: ThreeDDarkShadow;
+ font-size: 110%;
+ font-weight: normal;
+ margin: 0 0 .6em 0;
+}
+
+#feedTitleLink {
+ float: right;
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+a[href] img {
+ border: none;
+}
+
+#feedTitleContainer {
+ -moz-margin-start: 0;
+ -moz-margin-end: .6em;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#feedTitleImage {
+ -moz-margin-start: .6em;
+ -moz-margin-end: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ max-width: 300px;
+ max-height: 150px;
+}
+
+.feedEntryContent {
+ font-size: 110%;
+}
+
+.link {
+ color: #0000FF;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.link:hover:active {
+ color: #FF0000;
+}
+
+.lastUpdated {
+ font-size: 85%;
+ font-weight: normal;
+}
+
+.type-icon {
+ vertical-align: bottom;
+ height: 16px;
+ width: 16px;
+}
+
+.enclosures {
+ border: 1px solid THreeDShadow;
+ padding: 1em;
+ margin: 1em auto;
+ background: -moz-Dialog;
+}
+
+.enclosure {
+ vertical-align: middle;
+ margin-left: 2px;
+}
diff --git a/themes/windows/icon.png b/themes/windows/icon.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/windows/icon.png differ
diff --git a/themes/windows/identity-icons-generic.png b/themes/windows/identity-icons-generic.png
new file mode 100644
index 0000000..a39e493
Binary files /dev/null and b/themes/windows/identity-icons-generic.png differ
diff --git a/themes/windows/identity-icons-https-ev.png b/themes/windows/identity-icons-https-ev.png
new file mode 100644
index 0000000..d49be13
Binary files /dev/null and b/themes/windows/identity-icons-https-ev.png differ
diff --git a/themes/windows/identity-icons-https-mixed-active.png b/themes/windows/identity-icons-https-mixed-active.png
new file mode 100644
index 0000000..3c77bc8
Binary files /dev/null and b/themes/windows/identity-icons-https-mixed-active.png differ
diff --git a/themes/windows/identity-icons-https.png b/themes/windows/identity-icons-https.png
new file mode 100644
index 0000000..ffd6694
Binary files /dev/null and b/themes/windows/identity-icons-https.png differ
diff --git a/themes/windows/identity.png b/themes/windows/identity.png
new file mode 100644
index 0000000..0dcccd4
Binary files /dev/null and b/themes/windows/identity.png differ
diff --git a/themes/windows/imagedocument.png b/themes/windows/imagedocument.png
new file mode 100644
index 0000000..ff4f21f
Binary files /dev/null and b/themes/windows/imagedocument.png differ
diff --git a/themes/windows/jar.mn b/themes/windows/jar.mn
new file mode 100644
index 0000000..4422bb6
--- /dev/null
+++ b/themes/windows/jar.mn
@@ -0,0 +1,168 @@
+# 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:
+% skin browser classic/1.0 %skin/classic/browser/
+ skin/classic/browser/sanitizeDialog.css
+* skin/classic/browser/aboutPrivateBrowsing.css
+* skin/classic/browser/aboutSessionRestore.css
+ skin/classic/browser/aboutSessionRestore-window-icon.png
+ skin/classic/browser/aboutCertError.css
+ skin/classic/browser/aboutCertError_sectionCollapsed.png
+ skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
+ skin/classic/browser/aboutCertError_sectionExpanded.png
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/aboutSyncTabs.css
+#endif
+* skin/classic/browser/autocomplete.css
+ skin/classic/browser/actionicon-tab.png
+ skin/classic/browser/appmenu-icons.png
+ skin/classic/browser/appmenu-dropmarker.png
+* skin/classic/browser/browser.css
+ skin/classic/browser/caption-buttons.svg
+ skin/classic/browser/click-to-play-warning-stripes.png
+* skin/classic/browser/engineManager.css
+ skin/classic/browser/Geolocation-16.png
+ skin/classic/browser/Geolocation-64.png
+ skin/classic/browser/Info.png
+ skin/classic/browser/identity.png
+ skin/classic/browser/imagedocument.png
+ skin/classic/browser/identity-icons-generic.png
+ skin/classic/browser/identity-icons-https.png
+ skin/classic/browser/identity-icons-https-ev.png
+ skin/classic/browser/identity-icons-https-mixed-active.png
+ skin/classic/browser/keyhole-forward-mask.svg
+ skin/classic/browser/KUI-background.png
+ skin/classic/browser/KUI-close.png
+ skin/classic/browser/livemark-folder.png
+ skin/classic/browser/menu-back.png
+ skin/classic/browser/menu-forward.png
+ skin/classic/browser/mixed-content-blocked-16.png
+ skin/classic/browser/mixed-content-blocked-64.png
+ skin/classic/browser/monitor.png
+ skin/classic/browser/monitor_16-10.png
+ skin/classic/browser/pageInfo.css
+ skin/classic/browser/pageInfo.png
+ skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png)
+ skin/classic/browser/pointerLock-16.png
+ skin/classic/browser/pointerLock-64.png
+ skin/classic/browser/Privacy-16.png
+ skin/classic/browser/Privacy-32.png
+ skin/classic/browser/Privacy-48.png
+ skin/classic/browser/Privacy-64.png
+ skin/classic/browser/privatebrowsing-light.png
+ skin/classic/browser/privatebrowsing-dark.png
+ skin/classic/browser/reload-stop-go.png
+ skin/classic/browser/sanitize.png
+ skin/classic/browser/searchbar.css
+ skin/classic/browser/searchbar-dropdown-arrow.png
+ skin/classic/browser/Secure24.png
+ skin/classic/browser/setDesktopBackground.css
+ skin/classic/browser/slowStartup-16.png
+ skin/classic/browser/Toolbar.png
+ skin/classic/browser/Toolbar-glass.png
+ skin/classic/browser/Toolbar-inverted.png
+ skin/classic/browser/Toolbar.svg
+ skin/classic/browser/Toolbar-glass.svg
+ skin/classic/browser/Toolbar-inverted.svg
+ skin/classic/browser/toolbarbutton-dropdown-arrow.png
+ skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
+ skin/classic/browser/urlbar-arrow.png
+ skin/classic/browser/urlbar-popup-blocked.png
+ skin/classic/browser/urlbar-history-dropmarker.png
+ skin/classic/browser/web-notifications-icon.svg
+ skin/classic/browser/web-notifications-tray.svg
+ skin/classic/browser/notification-pluginNormal.png (../shared/plugins/notification-pluginNormal.png)
+ skin/classic/browser/notification-pluginAlert.png (../shared/plugins/notification-pluginAlert.png)
+ skin/classic/browser/notification-pluginBlocked.png (../shared/plugins/notification-pluginBlocked.png)
+#ifdef MOZ_WEBRTC
+ skin/classic/browser/webRTC-shareDevice-16.png
+ skin/classic/browser/webRTC-shareDevice-64.png
+ skin/classic/browser/webRTC-sharingDevice-16.png
+#endif
+ skin/classic/browser/downloads/buttons.png (downloads/buttons.png)
+ skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png)
+ skin/classic/browser/downloads/download-notification-start.png (downloads/download-notification-start.png)
+ skin/classic/browser/downloads/download-summary.png (downloads/download-summary.png)
+ skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
+ skin/classic/browser/downloads/allDownloadsViewOverlay.css (downloads/allDownloadsViewOverlay.css)
+ skin/classic/browser/downloads/contentAreaDownloadsView.css (downloads/contentAreaDownloadsView.css)
+ skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/videoFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png)
+ skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
+ skin/classic/browser/feeds/feed-icons-16.png (feeds/feed-icons-16.png)
+ skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
+ skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
+* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
+ skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
+ skin/classic/browser/newtab/noise.png (../shared/newtab/noise.png)
+ skin/classic/browser/newtab/pinned.png (../shared/newtab/pinned.png)
+ skin/classic/browser/places/places.css (places/places.css)
+* skin/classic/browser/places/organizer.css (places/organizer.css)
+ skin/classic/browser/places/editBookmark.png (places/editBookmark.png)
+ skin/classic/browser/places/bookmark.png (places/bookmark.png)
+ skin/classic/browser/places/query.png (places/query.png)
+ skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
+ skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
+ skin/classic/browser/places/calendar.png (places/calendar.png)
+ skin/classic/browser/places/toolbarDropMarker.png (places/toolbarDropMarker.png)
+ skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
+ skin/classic/browser/places/libraryToolbar.png (places/libraryToolbar.png)
+ skin/classic/browser/places/starred48.png (places/starred48.png)
+ skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
+ skin/classic/browser/places/tag.png (places/tag.png)
+ skin/classic/browser/places/history.png (places/history.png)
+ skin/classic/browser/places/allBookmarks.png (places/allBookmarks.png)
+ skin/classic/browser/places/unsortedBookmarks.png (places/unsortedBookmarks.png)
+ skin/classic/browser/places/downloads.png (places/downloads.png)
+ skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
+ skin/classic/browser/permissions/aboutPermissions.css (permissions/aboutPermissions.css)
+ skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
+ skin/classic/browser/preferences/application.png (preferences/application.png)
+ skin/classic/browser/preferences/mail.png (preferences/mail.png)
+ skin/classic/browser/preferences/Options.png (preferences/Options.png)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png)
+#endif
+ skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png)
+* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
+ skin/classic/browser/preferences/applications.css (preferences/applications.css)
+ skin/classic/browser/statusbar/dynamic.css (../shared/statusbar/dynamic.css)
+* skin/classic/browser/statusbar/overlay.css (statusbar/overlay.css)
+* skin/classic/browser/statusbar/prefs.css (statusbar/prefs.css)
+ skin/classic/browser/statusbar/pulse.png (../shared/statusbar/pulse.png)
+ skin/classic/browser/statusbar/pms16.png (../shared/statusbar/pms16.png)
+ skin/classic/browser/statusbar/pms24.png (../shared/statusbar/pms24.png)
+ skin/classic/browser/statusbar/throbber-idle.png (../shared/statusbar/throbber-idle.png)
+ skin/classic/browser/statusbar/throbberStatic.png (../shared/statusbar/throbberStatic.png)
+ skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
+ skin/classic/browser/tabbrowser/alltabs-inverted.png (tabbrowser/alltabs-inverted.png)
+ skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
+ skin/classic/browser/tabbrowser/newtab-glass.png (tabbrowser/newtab-glass.png)
+ skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
+ skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
+ skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
+ skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
+ skin/classic/browser/tabbrowser/tab-arrow-left-glass.png (tabbrowser/tab-arrow-left-glass.png)
+ skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
+ skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
+ skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
+#ifdef MOZ_SERVICES_SYNC
+ skin/classic/browser/sync-throbber.png
+ skin/classic/browser/sync-16.png
+ skin/classic/browser/sync-32.png
+ skin/classic/browser/sync-128.png
+ skin/classic/browser/sync-bg.png
+ skin/classic/browser/sync-desktopIcon.png
+ skin/classic/browser/sync-mobileIcon.png
+ skin/classic/browser/syncSetup.css
+ skin/classic/browser/syncCommon.css
+ skin/classic/browser/syncQuota.css
+ skin/classic/browser/syncProgress.css
+#endif
diff --git a/themes/windows/keyhole-forward-mask.svg b/themes/windows/keyhole-forward-mask.svg
new file mode 100644
index 0000000..8355447
--- /dev/null
+++ b/themes/windows/keyhole-forward-mask.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/livemark-folder.png b/themes/windows/livemark-folder.png
new file mode 100644
index 0000000..79e3329
Binary files /dev/null and b/themes/windows/livemark-folder.png differ
diff --git a/themes/windows/menu-back.png b/themes/windows/menu-back.png
new file mode 100644
index 0000000..2f99ea7
Binary files /dev/null and b/themes/windows/menu-back.png differ
diff --git a/themes/windows/menu-forward.png b/themes/windows/menu-forward.png
new file mode 100644
index 0000000..82cd874
Binary files /dev/null and b/themes/windows/menu-forward.png differ
diff --git a/themes/windows/mixed-content-blocked-16.png b/themes/windows/mixed-content-blocked-16.png
new file mode 100644
index 0000000..7cf33ec
Binary files /dev/null and b/themes/windows/mixed-content-blocked-16.png differ
diff --git a/themes/windows/mixed-content-blocked-64.png b/themes/windows/mixed-content-blocked-64.png
new file mode 100644
index 0000000..cac4415
Binary files /dev/null and b/themes/windows/mixed-content-blocked-64.png differ
diff --git a/themes/windows/monitor.png b/themes/windows/monitor.png
new file mode 100644
index 0000000..35e7b20
Binary files /dev/null and b/themes/windows/monitor.png differ
diff --git a/themes/windows/monitor_16-10.png b/themes/windows/monitor_16-10.png
new file mode 100644
index 0000000..4195034
Binary files /dev/null and b/themes/windows/monitor_16-10.png differ
diff --git a/themes/windows/moz.build b/themes/windows/moz.build
new file mode 100644
index 0000000..6a7af20
--- /dev/null
+++ b/themes/windows/moz.build
@@ -0,0 +1,9 @@
+# -*- 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/.
+
+DIRS += ['communicator']
+
+JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
diff --git a/themes/windows/newtab/newTab.css b/themes/windows/newtab/newTab.css
new file mode 100644
index 0000000..b8b0fd6
--- /dev/null
+++ b/themes/windows/newtab/newTab.css
@@ -0,0 +1,29 @@
+/* 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 ../../shared/newtab/newTab.css.inc
+
+.newtab-undo-button {
+ -moz-appearance: none;
+ color: -moz-nativehyperlinktext;
+ color: rgb(0,102,204);
+ cursor: pointer;
+ padding: 0;
+ margin: 0 4px;
+ border: 0;
+ background: transparent;
+ text-decoration: none;
+ min-width: 0;
+}
+
+.newtab-undo-button > .button-box {
+ padding: 0;
+}
+
+#newtab-undo-close-button {
+ -moz-appearance: none;
+ padding: 0;
+ border: none;
+ -moz-user-focus: normal;
+}
diff --git a/themes/windows/pageInfo.css b/themes/windows/pageInfo.css
new file mode 100644
index 0000000..ec65cc4
--- /dev/null
+++ b/themes/windows/pageInfo.css
@@ -0,0 +1,268 @@
+/* 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/. */
+
+@import "chrome://global/skin/";
+
+/* View buttons */
+#viewGroup {
+ -moz-padding-start: 10px;
+}
+
+#viewGroup > radio {
+ list-style-image: url("chrome://browser/skin/pageInfo.png");
+ -moz-box-orient: vertical;
+ -moz-box-align: center;
+ -moz-appearance: none;
+ padding: 5px 3px 1px 3px;
+ margin: 0 1px;
+ min-width: 4.5em;
+}
+
+#viewGroup > radio:hover {
+ background-color: #E0E8F6;
+ color: black;
+}
+
+#viewGroup > radio[selected="true"] {
+ background-color: #C1D2EE;
+ color: black;
+}
+
+#topBar {
+ border-bottom: 2px groove ThreeDFace;
+ -moz-padding-start: 10px;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+}
+
+#generalTab {
+ -moz-image-region: rect(0px, 32px, 32px, 0px)
+}
+
+#generalTab:hover, #generalTab[selected="true"] {
+ -moz-image-region: rect(32px, 32px, 64px, 0px)
+}
+
+#mediaTab {
+ -moz-image-region: rect(0px, 64px, 32px, 32px)
+}
+
+#mediaTab:hover, #mediaTab[selected="true"] {
+ -moz-image-region: rect(32px, 64px, 64px, 32px)
+}
+
+#feedTab {
+ -moz-image-region: rect(0px, 96px, 32px, 64px)
+}
+
+#feedTab:hover, #feedTab[selected="true"] {
+ -moz-image-region: rect(32px, 96px, 64px, 64px)
+}
+
+#permTab {
+ -moz-image-region: rect(0px, 128px, 32px, 96px)
+}
+
+#permTab:hover, #permTab[selected="true"] {
+ -moz-image-region: rect(32px, 128px, 64px, 96px)
+}
+
+#securityTab {
+ -moz-image-region: rect(0px, 160px, 32px, 128px)
+}
+
+#securityTab:hover, #securityTab[selected="true"] {
+ -moz-image-region: rect(32px, 160px, 64px, 128px)
+}
+
+deck {
+ padding: 10px 10px 10px 10px;
+}
+
+/* Misc */
+tree {
+ margin: .5em;
+}
+
+.gridSeparator {
+ width: .5em;
+}
+
+textbox {
+ background: transparent !important;
+ border: none;
+ padding: 0px;
+ margin-top: 1px;
+ -moz-appearance: none;
+}
+
+textbox.header {
+ -moz-margin-start: 0;
+}
+
+.iframe {
+ margin: .5em;
+ background: white;
+ overflow: auto;
+}
+
+.fixedsize {
+ height: 8.5em;
+}
+
+textbox[disabled] {
+ font-style: italic;
+}
+
+/* General Tab */
+groupbox.collapsable caption .caption-icon {
+ width: 9px;
+ height: 9px;
+ background-repeat: no-repeat;
+ background-position: center;
+ -moz-margin-start: 2px;
+ -moz-margin-end: 2px;
+ background-image: url("chrome://global/skin/tree/twisty.svg#open");
+}
+
+groupbox.collapsable[closed="true"] {
+ border: none;
+ margin-bottom: 9px;
+ -moz-appearance: none;
+}
+
+groupbox.collapsable[closed="true"] caption .caption-icon {
+ background-image: url("chrome://global/skin/tree/twisty.svg#clsd");
+}
+
+groupbox tree {
+ margin: 0 3px;
+ border: none;
+}
+
+#securityBox description {
+ -moz-margin-start: 10px;
+}
+
+#general-security-identity {
+ white-space: pre-wrap;
+ line-height: 2em;
+}
+
+@media (-moz-os-version: windows-win10) {
+ groupbox.collapsable caption .caption-icon {
+ background-image: url("chrome://global/skin/tree/twisty-10.svg#open");
+ }
+
+ groupbox.collapsable[closed="true"] caption .caption-icon {
+ background-image: url("chrome://global/skin/tree/twisty-10.svg#clsd");
+ }
+}
+
+/* Media Tab */
+#imagetree {
+ min-height: 10em;
+ margin-bottom: 0;
+}
+
+#mediaSplitter {
+ border-style: none;
+ background: none;
+ height: .8em;
+}
+
+#mediaGrid {
+ min-height: 9em;
+}
+
+#mediaLabelColumn {
+ min-width: 10em;
+}
+
+#thepreviewimage {
+ margin: 1em;
+}
+
+treechildren::-moz-tree-cell-text(broken) {
+ font-style: italic;
+ color: graytext;
+}
+
+/* Feeds Tab */
+#feedtree {
+ margin-bottom: 0px;
+}
+
+#feedListbox richlistitem {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+#feedListbox richlistitem[selected="true"] {
+ background-color: -moz-Dialog;
+ color: -moz-DialogText;
+}
+
+#feedListbox {
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+}
+
+.feedTitle {
+ font-weight: bold;
+}
+
+/* Permissions Tab */
+#permList {
+ margin-top: .5em;
+ overflow: auto;
+ border: 2px solid;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
+ background-color: -moz-field;
+}
+
+.permission {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+.permissionLabel {
+ font-weight: bold;
+}
+
+.permission:hover {
+ background-color: -moz-dialog;
+}
+
+/* Security Tab */
+#securityPanel .caption-icon {
+ display: none;
+}
+
+#securityPanel .header {
+ font-size: 120%;
+}
+
+#securityPanel .fieldLabel {
+ margin: 2px 10px 3px 10px;
+}
+
+#securityPanel .fieldValue {
+ font-weight: bold;
+ margin: 2px 10px 0px 10px;
+}
diff --git a/themes/windows/pageInfo.png b/themes/windows/pageInfo.png
new file mode 100644
index 0000000..fcc713b
Binary files /dev/null and b/themes/windows/pageInfo.png differ
diff --git a/themes/windows/permissions/aboutPermissions.css b/themes/windows/permissions/aboutPermissions.css
new file mode 100644
index 0000000..60ee816
--- /dev/null
+++ b/themes/windows/permissions/aboutPermissions.css
@@ -0,0 +1,153 @@
+/* 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/. */
+
+@import url("chrome://global/skin/inContentUI.css");
+
+/* header */
+
+#permissions-pagetitle {
+ font-size: 200%;
+ font-weight: bold;
+ padding-bottom: 0.5em;
+}
+
+/* content box */
+#permissions-content {
+ height: 100%;
+}
+
+/* sites box */
+
+#sites-box {
+ padding: 10px;
+ width: 25em;
+}
+
+#sites-filter {
+ margin: 0;
+}
+
+#sites-list {
+ -moz-appearance: none;
+ border: 1px solid rgba(0, 0, 0, 0.32);
+ background-color: rgba(255, 255, 255, 0.4);
+ margin: 5px 0 0 0;
+}
+
+.site {
+ padding: 4px;
+ border-bottom: 1px solid ThreeDLightShadow;
+}
+
+.site-favicon {
+ height: 16px;
+ width: 16px;
+ -moz-margin-end: 4px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+}
+
+#all-sites-item > .site-container > .site-favicon {
+ list-style-image: none;
+}
+
+/* permissions box */
+
+#permissions-box {
+ padding-top: 10px;
+ overflow-y: auto;
+}
+
+#site-description {
+ font-size: 125%;
+ -moz-margin-start: 6px; /* to match button margin */
+}
+
+#site-label {
+ font-weight: bold;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#defaults-description {
+ font-size: 125%;
+ font-weight: bold;
+ -moz-margin-start: 6px;
+}
+
+.pref-item {
+ margin-bottom: 10px;
+}
+
+.pref-icon {
+ width: 48px;
+ height: 48px;
+ -moz-margin-end: 10px;
+}
+
+.pref-icon[type="password"] {
+ list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
+}
+.pref-icon[type="image"] {
+ list-style-image: url(chrome://global/skin/icons/question-48.png);
+}
+.pref-icon[type="popup"] {
+ list-style-image: url(chrome://global/skin/icons/question-48.png);
+}
+.pref-icon[type="cookie"] {
+ list-style-image: url(chrome://global/skin/icons/question-48.png);
+}
+.pref-icon[type="desktop-notification"] {
+ list-style-image: url(chrome://browser/skin/web-notifications-icon.svg);
+}
+.pref-icon[type="install"] {
+ list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-48.png);
+}
+.pref-icon[type="geo"] {
+ list-style-image: url(chrome://browser/skin/Geolocation-64.png);
+}
+.pref-icon[type="plugins"] {
+ list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric-48.png);
+}
+
+.pref-title {
+ font-size: 125%;
+ margin-bottom: 0;
+ font-weight: bold;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.pref-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+}
+
+.pref-set-default {
+ visibility: collapse;
+}
+
+.pref-menulist {
+ margin-left: 6px;
+ margin-right: 6px;
+ min-width: 10em; /* native menulists ellipsize their longest entries by default on many themes */
+}
+
+.plugins-label {
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-vulnerable {
+ margin-left: 0;
+ padding-left: 0;
+ margin-right: 0;
+ padding-right: 0;
+}
+
+.plugins-default {
+ margin-left: 0.5em;
+ padding-left: 0;
+ margin-right: 1em;
+ padding-right: 0;
+}
diff --git a/themes/windows/places/allBookmarks.png b/themes/windows/places/allBookmarks.png
new file mode 100644
index 0000000..177c31c
Binary files /dev/null and b/themes/windows/places/allBookmarks.png differ
diff --git a/themes/windows/places/bookmark.png b/themes/windows/places/bookmark.png
new file mode 100644
index 0000000..2e9a206
Binary files /dev/null and b/themes/windows/places/bookmark.png differ
diff --git a/themes/windows/places/bookmarksMenu.png b/themes/windows/places/bookmarksMenu.png
new file mode 100644
index 0000000..14c9601
Binary files /dev/null and b/themes/windows/places/bookmarksMenu.png differ
diff --git a/themes/windows/places/bookmarksToolbar.png b/themes/windows/places/bookmarksToolbar.png
new file mode 100644
index 0000000..5a4a693
Binary files /dev/null and b/themes/windows/places/bookmarksToolbar.png differ
diff --git a/themes/windows/places/calendar.png b/themes/windows/places/calendar.png
new file mode 100644
index 0000000..c0d1071
Binary files /dev/null and b/themes/windows/places/calendar.png differ
diff --git a/themes/windows/places/downloads.png b/themes/windows/places/downloads.png
new file mode 100644
index 0000000..d37bc40
Binary files /dev/null and b/themes/windows/places/downloads.png differ
diff --git a/themes/windows/places/editBookmark.png b/themes/windows/places/editBookmark.png
new file mode 100644
index 0000000..fbca052
Binary files /dev/null and b/themes/windows/places/editBookmark.png differ
diff --git a/themes/windows/places/editBookmarkOverlay.css b/themes/windows/places/editBookmarkOverlay.css
new file mode 100644
index 0000000..be3ea83
--- /dev/null
+++ b/themes/windows/places/editBookmarkOverlay.css
@@ -0,0 +1,80 @@
+/* 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/. */
+
+/**** folder menulist ****/
+.folder-icon > .menulist-label-box > .menulist-icon {
+ width: 16px;
+ height: 16px;
+}
+
+.folder-icon > .menu-iconic-left {
+ display: -moz-box;
+}
+
+.folder-icon {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png") !important;
+ -moz-image-region: rect(0px, 32px, 16px, 16px) !important;
+}
+
+
+/**** expanders ****/
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ margin: 0;
+ -moz-margin-end: 4px;
+}
+
+.expander-up > .button-box,
+.expander-down > .button-box {
+ padding: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://global/skin/icons/collapse.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://global/skin/icons/expand.png");
+}
+
+#editBookmarkPanelContent {
+ min-width: 23em;
+}
+
+#editBMPanel_folderTree {
+ margin-top: 2px;
+ margin-bottom: 2px;
+}
+
+/* Hide the value column of the tag autocomplete popup
+ * leaving only the comment column visible. This is
+ * so that only the tag being edited is shown in the
+ * popup.
+ */
+#editBMPanel_tagsField #treecolAutoCompleteValue {
+ visibility: collapse;
+}
+
+
+/* ::::: bookmark panel dropdown icons ::::: */
+
+#editBMPanel_folderMenuList[selectedIndex="0"],
+#editBMPanel_toolbarFolderItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png") !important;
+ -moz-image-region: auto !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="1"],
+#editBMPanel_bmRootItem {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png") !important;
+ -moz-image-region: auto !important;
+}
+
+#editBMPanel_folderMenuList[selectedIndex="2"],
+#editBMPanel_unfiledRootItem {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png") !important;
+ -moz-image-region: auto !important;
+}
diff --git a/themes/windows/places/history.png b/themes/windows/places/history.png
new file mode 100644
index 0000000..cc3b067
Binary files /dev/null and b/themes/windows/places/history.png differ
diff --git a/themes/windows/places/libraryToolbar.png b/themes/windows/places/libraryToolbar.png
new file mode 100644
index 0000000..f5f3654
Binary files /dev/null and b/themes/windows/places/libraryToolbar.png differ
diff --git a/themes/windows/places/livemark-item.png b/themes/windows/places/livemark-item.png
new file mode 100644
index 0000000..9184b95
Binary files /dev/null and b/themes/windows/places/livemark-item.png differ
diff --git a/themes/windows/places/organizer.css b/themes/windows/places/organizer.css
new file mode 100644
index 0000000..45851d0
--- /dev/null
+++ b/themes/windows/places/organizer.css
@@ -0,0 +1,253 @@
+/* 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/. */
+
+:root {
+ --toolbar-custom-color: hsl(210,75%,92%);
+ --toolbar-highlight-top: rgba(255,255,255,.5);
+ --toolbarbutton-image: url("chrome://browser/skin/Toolbar.png");
+}
+
+/* Use SVG for HiDPI 133%+ */
+@media (min-resolution: 1.33dppx) {
+ :root {
+ --toolbarbutton-image: url("chrome://browser/skin/Toolbar.svg");
+ }
+}
+
+/* Toolbar */
+#placesToolbar {
+ padding: 3px;
+ -moz-padding-end: 6px;
+}
+
+#placesToolbar > toolbarbutton[disabled] > .toolbarbutton-icon {
+ opacity: .4;
+}
+
+#back-button,
+#forward-button {
+ list-style-image: var(--toolbarbutton-image);
+}
+
+#back-button {
+ -moz-image-region: rect(0, 18px, 18px, 0);
+}
+
+#forward-button {
+ -moz-image-region: rect(0, 36px, 18px, 18px);
+}
+
+#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
+#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon {
+ transform: scaleX(-1);
+}
+
+/* Menu */
+#placesMenu {
+ -moz-margin-start: 6px;
+ -moz-appearance: none;
+ border: none;
+}
+
+#placesMenu > menu {
+ -moz-padding-start: 4px;
+ -moz-padding-end: 1px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ -moz-appearance: toolbarbutton;
+%ifdef XP_WIN
+% use standard menu colors on OS/2
+ color: -moz-DialogText;
+%endif
+ border: 1px solid transparent;
+}
+
+#placesMenu > menu[_moz-menuactive="true"] {
+ background-color: transparent;
+}
+
+#placesMenu > menu:hover {
+ border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight;
+}
+
+#placesMenu > menu[open="true"] {
+ border-color: ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow;
+ -moz-padding-start: 5px;
+ -moz-padding-end: 0px;
+ padding-top: 3px;
+ padding-bottom: 1px;
+}
+
+#placesMenu > menu > .menubar-text {
+ -moz-padding-end: 8px;
+ background: url(chrome://global/skin/arrow/arrow-dn.gif) right center no-repeat;
+}
+
+#placesMenu > menu > .menubar-text:-moz-locale-dir(rtl) {
+ background-position: left center;
+}
+
+/* organize, view and maintenance buttons icons */
+#organizeButton,
+#viewMenu,
+#maintenanceButton {
+ list-style-image: url("chrome://browser/skin/places/libraryToolbar.png");
+}
+
+/* organize button */
+#organizeButton {
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+#organizeButton:hover,
+#organizeButton[open="true"] {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+/* view button */
+#viewMenu {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+#viewMenu:hover,
+#viewMenu[open="true"] {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+/* maintenance button */
+#maintenanceButton {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+#maintenanceButton:hover,
+#maintenanceButton[open="true"] {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+/* Root View */
+#placesView {
+ border-top: 1px solid ThreeDDarkShadow;
+}
+
+/* Info box */
+#detailsDeck {
+ border-top: 1px solid ThreeDShadow;
+ padding: 5px;
+}
+
+#infoBoxExpanderLabel {
+ -moz-padding-start: 2px;
+}
+
+#organizerScopeBar {
+ padding: 2px 0;
+ -moz-padding-end: 3px;
+}
+
+#organizerScopeBar > toolbarbutton {
+ -moz-appearance: none;
+ border: 1px solid transparent;
+ border-radius: 2px;
+ padding: 0 !important;
+ margin: 0 1px;
+}
+
+#organizerScopeBar > toolbarbutton > .toolbarbutton-icon {
+ padding: 0;
+ margin: 0;
+}
+
+#organizerScopeBar > toolbarbutton > .toolbarbutton-text {
+ margin: 0;
+ padding: 2px 5px;
+}
+
+#organizerScopeBar > toolbarbutton:not([disabled="true"]):not([checked="true"]):hover {
+ border-color: ThreeDShadow;
+}
+
+#organizerScopeBar > toolbarbutton[checked="true"] {
+ border-color: ThreeDDarkShadow !important;
+}
+
+#searchFilter {
+ margin: 0;
+}
+
+/**
+ * Downloads pane
+ */
+
+#clearDownloadsButton > .toolbarbutton-icon {
+ display: none;
+}
+
+#clearDownloadsButton {
+ -moz-padding-start: 9px;
+ -moz-padding-end: 9px;
+}
+
+#placesView {
+ border-top: none;
+}
+
+@media not all and (-moz-windows-classic) {
+ #placesToolbox {
+ -moz-appearance: none;
+ background-color: transparent;
+ }
+
+ #placesToolbar {
+ -moz-appearance: none;
+ background-color: -moz-Dialog;
+ color: -moz-dialogText;
+ }
+}
+
+@media (-moz-windows-default-theme) {
+ #placesView > splitter {
+ border: 0;
+ -moz-border-end: 1px solid #A9B7C9;
+ min-width: 0;
+ width: 3px;
+ background-color: transparent;
+ -moz-margin-start: -3px;
+ position: relative;
+ }
+}
+
+@media (-moz-windows-glass) {
+ #placesToolbox {
+ border-top: none;
+ }
+
+ #placesToolbar {
+ background-image: linear-gradient(var(--toolbar-highlight-top), transparent);
+ }
+}
+
+@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
+ (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
+ #placesView,
+ #infoPane,
+ #placesList,
+ #placeContent {
+ background-color: #EEF3FA;
+ }
+
+ #placesToolbar {
+ background-color: var(--toolbar-custom-color);
+ color: black;
+ }
+
+ #detailsDeck {
+ border-top-color: #A9B7C9;
+ }
+
+ #searchFilter {
+ -moz-appearance: none;
+ padding: 2px;
+ -moz-padding-start: 4px;
+ background-clip: padding-box;
+ border: 1px solid rgba(0,0,0,.32);
+ border-radius: 2px;
+ }
+}
diff --git a/themes/windows/places/places.css b/themes/windows/places/places.css
new file mode 100644
index 0000000..bb16046
--- /dev/null
+++ b/themes/windows/places/places.css
@@ -0,0 +1,172 @@
+/* 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/. */
+
+/* Sidebars */
+.sidebar-placesTree {
+ -moz-appearance: none;
+ border: 0;
+ margin: 0;
+ border-top: 1px solid ThreeDShadow;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
+.sidebar-placesTreechildren::-moz-tree-image(leaf) {
+ cursor: pointer;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+.sidebar-placesTreechildren::-moz-tree-cell(separator) {
+ cursor: default;
+}
+
+@media (-moz-windows-default-theme) {
+ .sidebar-placesTree {
+ background-color: transparent;
+ border-top: none;
+ }
+
+ .sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+ text-decoration: none;
+ }
+
+ @media (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ #bookmarksPanel,
+ #history-panel {
+ background-color: #EEF3FA;
+ }
+ }
+}
+
+/* Trees */
+treechildren::-moz-tree-image(title) {
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
+ padding-right: 2px;
+ margin: 0px 2px;
+ width: 16px;
+ height: 16px;
+}
+
+treechildren::-moz-tree-image(title, livemarkItem) {
+ list-style-image: url("chrome://browser/skin/places/livemark-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+treechildren::-moz-tree-image(title, livemarkItem, visited) {
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, separator) {
+ list-style-image: none;
+ width: 0;
+ height: 0;
+}
+
+treechildren::-moz-tree-image(title, container) {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, open) {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+treechildren::-moz-tree-image(title, container, livemark) {
+ list-style-image: url("chrome://browser/skin/livemark-folder.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_AllBookmarks) {
+ list-style-image: url("chrome://browser/skin/places/allBookmarks.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksToolbar) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_BookmarksMenu) {
+ list-style-image: url("chrome://browser/skin/places/bookmarksMenu.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(container, OrganizerQuery_UnfiledBookmarks) {
+ list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
+ -moz-image-region: auto;
+}
+
+/* query-nodes should be styled even if they're not expandable */
+treechildren::-moz-tree-image(title, query) {
+ list-style-image: url("chrome://browser/skin/places/query.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(title, query, tagContainer),
+treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
+ list-style-image: url("chrome://browser/skin/places/tag.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
+ list-style-image: url("chrome://browser/skin/places/downloads.png");
+ -moz-image-region: auto;
+}
+
+/* calendar icon for folders grouping items by date */
+treechildren::-moz-tree-image(title, query, dayContainer) {
+ list-style-image: url("chrome://browser/skin/places/calendar.png");
+ -moz-image-region: auto;
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer) {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, query, hostContainer, open) {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+treechildren::-moz-tree-image(title, query, OrganizerQuery_History) {
+ list-style-image: url("chrome://browser/skin/places/history.png");
+}
+
+/* We want some queries to look like ordinary folders. This must come
+ after the (title, query) selector, or it would get overridden. */
+treechildren::-moz-tree-image(title, query, folder) {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+treechildren::-moz-tree-image(title, query, folder, open) {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+treechildren::-moz-tree-image(cutting) {
+ opacity: 0.5;
+}
+
+treechildren::-moz-tree-cell-text(cutting) {
+ opacity: 0.7;
+}
+
+/* Browser Sidebars */
+
+/* Default button vert. margins are 1px/2px, and this can cause misalignment */
+#viewButton {
+ margin-top: 2px;
+ margin-bottom: 2px;
+}
+
+#viewButton > .button-box > .button-menu-dropmarker {
+ height: auto;
+ width: auto;
+ -moz-margin-end: -3px;
+}
diff --git a/themes/windows/places/query.png b/themes/windows/places/query.png
new file mode 100644
index 0000000..fff0fb0
Binary files /dev/null and b/themes/windows/places/query.png differ
diff --git a/themes/windows/places/starred48.png b/themes/windows/places/starred48.png
new file mode 100644
index 0000000..2f7e878
Binary files /dev/null and b/themes/windows/places/starred48.png differ
diff --git a/themes/windows/places/tag.png b/themes/windows/places/tag.png
new file mode 100644
index 0000000..da90624
Binary files /dev/null and b/themes/windows/places/tag.png differ
diff --git a/themes/windows/places/toolbarDropMarker.png b/themes/windows/places/toolbarDropMarker.png
new file mode 100644
index 0000000..3abb7c2
Binary files /dev/null and b/themes/windows/places/toolbarDropMarker.png differ
diff --git a/themes/windows/places/unsortedBookmarks.png b/themes/windows/places/unsortedBookmarks.png
new file mode 100644
index 0000000..d18a501
Binary files /dev/null and b/themes/windows/places/unsortedBookmarks.png differ
diff --git a/themes/windows/places/unstarred48.png b/themes/windows/places/unstarred48.png
new file mode 100644
index 0000000..8b82aab
Binary files /dev/null and b/themes/windows/places/unstarred48.png differ
diff --git a/themes/windows/pointerLock-16.png b/themes/windows/pointerLock-16.png
new file mode 100644
index 0000000..862cd11
Binary files /dev/null and b/themes/windows/pointerLock-16.png differ
diff --git a/themes/windows/pointerLock-64.png b/themes/windows/pointerLock-64.png
new file mode 100644
index 0000000..a35ce04
Binary files /dev/null and b/themes/windows/pointerLock-64.png differ
diff --git a/themes/windows/preferences/Options-sync.png b/themes/windows/preferences/Options-sync.png
new file mode 100644
index 0000000..89901fb
Binary files /dev/null and b/themes/windows/preferences/Options-sync.png differ
diff --git a/themes/windows/preferences/Options.png b/themes/windows/preferences/Options.png
new file mode 100644
index 0000000..2cb1f50
Binary files /dev/null and b/themes/windows/preferences/Options.png differ
diff --git a/themes/windows/preferences/alwaysAsk.png b/themes/windows/preferences/alwaysAsk.png
new file mode 100644
index 0000000..d12805e
Binary files /dev/null and b/themes/windows/preferences/alwaysAsk.png differ
diff --git a/themes/windows/preferences/application.png b/themes/windows/preferences/application.png
new file mode 100644
index 0000000..d67993d
Binary files /dev/null and b/themes/windows/preferences/application.png differ
diff --git a/themes/windows/preferences/applications.css b/themes/windows/preferences/applications.css
new file mode 100644
index 0000000..80699b4
--- /dev/null
+++ b/themes/windows/preferences/applications.css
@@ -0,0 +1,64 @@
+/* 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/. */
+
+/**
+ * Line up the actions menu with action labels above and below it.
+ * Equalize the distance from the left side of the action box to the left side
+ * of the icon for both the menu and the non-menu versions of the action box.
+ * Also make sure the labels are the same distance away from the icons.
+ */
+.actionsMenu {
+ margin-top: 0;
+ margin-bottom: 0;
+ -moz-margin-start: -2px;
+ -moz-margin-end: 0;
+}
+
+.typeIcon,
+.actionIcon {
+ -moz-margin-start: 3px;
+ -moz-margin-end: 3px;
+}
+
+richlistitem label {
+ -moz-margin-start: 1px;
+ margin-top: 2px;
+}
+
+richlistitem {
+ min-height: 22px;
+}
+
+richlistitem[appHandlerIcon="ask"],
+menuitem[appHandlerIcon="ask"] {
+ list-style-image: url("chrome://browser/skin/preferences/alwaysAsk.png");
+}
+
+richlistitem[appHandlerIcon="save"],
+menuitem[appHandlerIcon="save"] {
+ list-style-image: url("chrome://browser/skin/preferences/application.png");
+}
+
+richlistitem[appHandlerIcon="feed"],
+menuitem[appHandlerIcon="feed"] {
+ list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
+richlistitem[appHandlerIcon="plugin"],
+menuitem[appHandlerIcon="plugin"] {
+ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
+}
+
+.actionsMenu .menulist-icon {
+ -moz-margin-end: 3px;
+}
+
+.actionsMenu > menupopup > menuitem > .menu-iconic-left {
+ -moz-padding-start: 0px;
+ -moz-padding-end: 2px;
+}
+
+.actionsMenu > menupopup > menuitem {
+ -moz-padding-start: 4px;
+}
diff --git a/themes/windows/preferences/mail.png b/themes/windows/preferences/mail.png
new file mode 100644
index 0000000..be1ed4d
Binary files /dev/null and b/themes/windows/preferences/mail.png differ
diff --git a/themes/windows/preferences/preferences.css b/themes/windows/preferences/preferences.css
new file mode 100644
index 0000000..40be343
--- /dev/null
+++ b/themes/windows/preferences/preferences.css
@@ -0,0 +1,146 @@
+/*
+# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+# 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/.
+*/
+
+/* Global Styles */
+#BrowserPreferences radio[pane] {
+ list-style-image: url("chrome://browser/skin/preferences/Options.png");
+ padding: 5px 3px 1px;
+}
+
+radio[pane=paneMain] {
+ -moz-image-region: rect(0, 32px, 32px, 0);
+}
+
+radio[pane=paneTabs] {
+ -moz-image-region: rect(0, 64px, 32px, 32px);
+}
+
+radio[pane=paneContent] {
+ -moz-image-region: rect(0, 96px, 32px, 64px);
+}
+
+radio[pane=paneApplications] {
+ -moz-image-region: rect(0, 128px, 32px, 96px);
+}
+
+radio[pane=panePrivacy] {
+ -moz-image-region: rect(0, 160px, 32px, 128px);
+}
+
+radio[pane=paneSecurity] {
+ -moz-image-region: rect(0, 192px, 32px, 160px);
+}
+
+radio[pane=paneAdvanced] {
+ -moz-image-region: rect(0, 224px, 32px, 192px);
+}
+
+%ifdef MOZ_SERVICES_SYNC
+radio[pane=paneSync] {
+ list-style-image: url("chrome://browser/skin/preferences/Options-sync.png") !important;
+}
+%endif
+
+/* Applications Pane */
+#BrowserPreferences[animated="true"] #handlersView {
+ height: 25em;
+}
+
+#BrowserPreferences[animated="false"] #handlersView {
+ -moz-box-flex: 1;
+}
+
+/* Privacy Pane */
+
+/* styles for the link elements copied from .text-link in global.css */
+.inline-link {
+ color: -moz-nativehyperlinktext;
+ text-decoration: none;
+}
+
+.inline-link:hover {
+ text-decoration: underline;
+}
+
+/* Modeless Window Dialogs */
+.windowDialog,
+.windowDialog prefpane {
+ padding: 0;
+}
+
+#browserHomePage:-moz-locale-dir(rtl) input {
+ unicode-bidi: plaintext;
+ direction: rtl;
+}
+
+.contentPane {
+ margin: 9px 8px 5px;
+}
+
+.actionButtons {
+ margin: 0 3px 6px !important;
+}
+
+/* Cookies Manager */
+#cookiesChildren::-moz-tree-image(domainCol) {
+ width: 16px;
+ height: 16px;
+ margin: 0 2px;
+ list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png") !important;
+}
+
+#cookiesChildren::-moz-tree-image(domainCol, container) {
+ list-style-image: url("chrome://global/skin/icons/folder-item.png") !important;
+ -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+#cookiesChildren::-moz-tree-image(domainCol, container, open) {
+ -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+#cookieInfoBox {
+ border: 1px solid ThreeDShadow;
+ border-radius: 0;
+ margin: 4px;
+ padding: 0;
+}
+
+/* Advanced Pane */
+
+/* Adding padding-bottom prevents the bottom of the tabpanel from being cutoff
+ when browser.preferences.animateFadeIn = true */
+#advancedPrefs {
+ padding-bottom: 8px;
+}
+
+/* bottom-most box containing a groupbox in a prefpane. Prevents the bottom
+ of the groupbox from being cutoff */
+.bottomBox {
+ padding-bottom: 4px;
+}
+
+%ifdef MOZ_SERVICES_SYNC
+/* Sync Pane */
+
+#syncDesc {
+ padding: 0 8em;
+}
+
+.syncGroupBox {
+ padding: 10px;
+}
+
+#accountCaptionImage {
+ list-style-image: url("chrome://mozapps/skin/profile/profileicon.png");
+}
+
+#syncAddDeviceLabel {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+%endif
diff --git a/themes/windows/preferences/saveFile.png b/themes/windows/preferences/saveFile.png
new file mode 100644
index 0000000..1248dd3
Binary files /dev/null and b/themes/windows/preferences/saveFile.png differ
diff --git a/themes/windows/privatebrowsing-dark.png b/themes/windows/privatebrowsing-dark.png
new file mode 100644
index 0000000..9eaf3ae
Binary files /dev/null and b/themes/windows/privatebrowsing-dark.png differ
diff --git a/themes/windows/privatebrowsing-light.png b/themes/windows/privatebrowsing-light.png
new file mode 100644
index 0000000..c12f507
Binary files /dev/null and b/themes/windows/privatebrowsing-light.png differ
diff --git a/themes/windows/reload-stop-go.png b/themes/windows/reload-stop-go.png
new file mode 100644
index 0000000..1017be9
Binary files /dev/null and b/themes/windows/reload-stop-go.png differ
diff --git a/themes/windows/sanitize.png b/themes/windows/sanitize.png
new file mode 100644
index 0000000..72eea2c
Binary files /dev/null and b/themes/windows/sanitize.png differ
diff --git a/themes/windows/sanitizeDialog.css b/themes/windows/sanitizeDialog.css
new file mode 100644
index 0000000..4312eb8
--- /dev/null
+++ b/themes/windows/sanitizeDialog.css
@@ -0,0 +1,93 @@
+/* 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/. */
+
+#sanitizeDurationChoice {
+ -moz-margin-end: 0;
+}
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 3px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("chrome://global/skin/icons/warning-large.png");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin: 6px 0;
+}
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ margin: 0;
+}
+
+.expander-up > .button-box,
+.expander-down > .button-box {
+ padding: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://global/skin/icons/collapse.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://global/skin/icons/expand.png");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="cancel"] {
+ -moz-margin-end: 0;
+}
diff --git a/themes/windows/searchbar-dropdown-arrow.png b/themes/windows/searchbar-dropdown-arrow.png
new file mode 100644
index 0000000..79d8d61
Binary files /dev/null and b/themes/windows/searchbar-dropdown-arrow.png differ
diff --git a/themes/windows/searchbar.css b/themes/windows/searchbar.css
new file mode 100644
index 0000000..86a4855
--- /dev/null
+++ b/themes/windows/searchbar.css
@@ -0,0 +1,81 @@
+/* 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/. */
+
+.searchbar-textbox {
+ width: 6em;
+ min-width: 6em;
+}
+
+.autocomplete-textbox-container {
+ -moz-box-align: stretch;
+}
+
+.textbox-input-box {
+ margin: 0;
+}
+
+/* ::::: searchbar-engine-button ::::: */
+
+.searchbar-engine-image {
+ height: 16px;
+ width: 16px;
+ list-style-image: url("chrome://global/skin/icons/folder-item.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+ -moz-margin-start: 2px;
+}
+
+.searchbar-engine-button {
+ -moz-appearance: none;
+ min-width: 0;
+ margin: 0;
+ padding: 0;
+ -moz-padding-end: 2px;
+ -moz-box-align: center;
+ background: none;
+ border: none;
+}
+
+.searchbar-engine-button > .button-box {
+ -moz-appearance: none;
+ padding: 0;
+ border: 0;
+}
+
+.searchbar-dropmarker-image {
+ list-style-image: url("chrome://browser/skin/searchbar-dropdown-arrow.png");
+ -moz-image-region: rect(0, 13px, 11px, 0);
+}
+
+.searchbar-engine-button[open="true"] > .searchbar-dropmarker-image {
+ -moz-image-region: rect(0, 26px, 11px, 13px);
+}
+
+
+/* ::::: search-go-button ::::: */
+
+.search-go-container {
+ -moz-box-align: center;
+}
+
+.search-go-button {
+ padding: 1px;
+ list-style-image: url("chrome://global/skin/icons/Search-glass.png");
+ -moz-image-region: rect(0px 16px 16px 0px);
+}
+
+.search-go-button:-moz-locale-dir(rtl) {
+ transform: scaleX(-1);
+}
+
+.search-go-button:hover {
+ -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+.search-go-button:hover:active {
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+.searchbar-engine-menuitem[selected="true"] > .menu-iconic-text {
+ font-weight: bold;
+}
diff --git a/themes/windows/setDesktopBackground.css b/themes/windows/setDesktopBackground.css
new file mode 100644
index 0000000..585284c
--- /dev/null
+++ b/themes/windows/setDesktopBackground.css
@@ -0,0 +1,18 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+@namespace html url("http://www.w3.org/1999/xhtml");
+
+html|canvas#screen {
+ margin: 12px 11px 32px;
+}
+
+#monitor {
+ list-style-image: url("chrome://browser/skin/monitor.png");
+}
+
+#monitor[aspectratio="16:10"] {
+ list-style-image: url("chrome://browser/skin/monitor_16-10.png");
+}
diff --git a/themes/windows/slowStartup-16.png b/themes/windows/slowStartup-16.png
new file mode 100644
index 0000000..5551ef0
Binary files /dev/null and b/themes/windows/slowStartup-16.png differ
diff --git a/themes/windows/statusbar/overlay.css b/themes/windows/statusbar/overlay.css
new file mode 100644
index 0000000..7f9a598
--- /dev/null
+++ b/themes/windows/statusbar/overlay.css
@@ -0,0 +1,104 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/overlay.css
+
+/*
+ * General
+ */
+
+#status4evar-status-text,
+#status4evar-progress-bar
+{
+ margin: 0px 3px;
+}
+
+/*
+ * Download status
+ */
+
+#status4evar-download-progress-bar
+{
+ height: 4px;
+}
+
+#status4evar-download-button #status4evar-download-icon
+{
+ min-width: 18px;
+ min-height: 18px;
+}
+
+#status4evar-download-button #status4evar-download-icon
+{
+ background: -moz-image-rect(var(--toolbarbutton-image), 0, 108, 18, 90) center no-repeat;
+}
+
+toolbar[brighttext] #status4evar-download-button #status4evar-download-icon
+{
+ background: -moz-image-rect(var(--toolbarbutton-inverted-image), 0, 108, 18, 90) center no-repeat;
+}
+
+@media (-moz-windows-compositor)
+{
+ :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) #status4evar-download-button #status4evar-download-icon:not(:-moz-lwtheme),
+ #TabsToolbar[tabsontop=true] #status4evar-download-button #status4evar-download-icon:not(:-moz-lwtheme),
+ #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child #status4evar-download-button #status4evar-download-icon:not(:-moz-lwtheme)
+ {
+ background: -moz-image-rect(var(--toolbarbutton-glass-image), 0, 108, 18, 90) center no-repeat;
+ }
+}
+
+#status4evar-download-button[attention] #status4evar-download-icon
+{
+ background: -moz-image-rect(var(--toolbarbutton-glass-image), 19, 108, 36, 90) center no-repeat;
+}
+
+toolbar[mode="icons"] #status4evar-download-button[forcelabel="true"] > label
+{
+ -moz-margin-start: 5px !important;
+}
+
+/*
+ * Splitter
+ */
+
+splitter.status4evar-status-splitter
+{
+ width: 6px;
+ margin: 0px -3px;
+}
+
+/*
+ * Location bar
+ */
+
+#urlbar-progress-alt
+{
+ -moz-margin-end: -2px;
+}
+
+/*
+ * Status bar
+ */
+
+#browser-bottombox[s4eboarder="true"] :-moz-any(#status4evar-status-bar, #addon-bar)
+{
+ -moz-appearance: none;
+}
+
+#browser-bottombox[s4eboarder="true"] > *:not([hidden="true"]):not([collapsed="true"])
+{
+ box-shadow: none !important;
+ border: none !important;
+ border-top: 2px solid !important;
+ -moz-border-top-colors: ThreeDShadow ThreeDHighlight !important;
+}
+
+#browser-bottombox[s4eboarder="true"] > *:not([hidden="true"]):not([collapsed="true"]) ~ *
+{
+ border: none !important;
+}
+
diff --git a/themes/windows/statusbar/prefs.css b/themes/windows/statusbar/prefs.css
new file mode 100644
index 0000000..005088b
--- /dev/null
+++ b/themes/windows/statusbar/prefs.css
@@ -0,0 +1,7 @@
+/* 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/. */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+%include ../../shared/statusbar/prefs.css
diff --git a/themes/windows/sync-128.png b/themes/windows/sync-128.png
new file mode 100644
index 0000000..1ea3481
Binary files /dev/null and b/themes/windows/sync-128.png differ
diff --git a/themes/windows/sync-16.png b/themes/windows/sync-16.png
new file mode 100644
index 0000000..0afb1c7
Binary files /dev/null and b/themes/windows/sync-16.png differ
diff --git a/themes/windows/sync-32.png b/themes/windows/sync-32.png
new file mode 100644
index 0000000..7a762cb
Binary files /dev/null and b/themes/windows/sync-32.png differ
diff --git a/themes/windows/sync-bg.png b/themes/windows/sync-bg.png
new file mode 100644
index 0000000..893a27d
Binary files /dev/null and b/themes/windows/sync-bg.png differ
diff --git a/themes/windows/sync-desktopIcon.png b/themes/windows/sync-desktopIcon.png
new file mode 100644
index 0000000..d3d1e27
Binary files /dev/null and b/themes/windows/sync-desktopIcon.png differ
diff --git a/themes/windows/sync-mobileIcon.png b/themes/windows/sync-mobileIcon.png
new file mode 100644
index 0000000..a3bda57
Binary files /dev/null and b/themes/windows/sync-mobileIcon.png differ
diff --git a/themes/windows/sync-throbber.png b/themes/windows/sync-throbber.png
new file mode 100644
index 0000000..d25490b
Binary files /dev/null and b/themes/windows/sync-throbber.png differ
diff --git a/themes/windows/syncCommon.css b/themes/windows/syncCommon.css
new file mode 100644
index 0000000..f0beae0
--- /dev/null
+++ b/themes/windows/syncCommon.css
@@ -0,0 +1,49 @@
+/* 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/. */
+
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
+.status {
+ color: -moz-dialogtext;
+}
+
+.statusIcon {
+ -moz-margin-start: 4px;
+ max-height: 16px;
+ max-width: 16px;
+}
+
+.statusIcon[status="active"] {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+.statusIcon[status="error"] {
+ list-style-image: url("chrome://global/skin/icons/error-16.png");
+}
+
+.statusIcon[status="success"] {
+ list-style-image: url("chrome://global/skin/icons/information-16.png");
+}
+
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
+ a separate stylesheet for it. */
+.data {
+ font-size: 90%;
+ font-weight: bold;
+}
+
+dialog#change-dialog {
+ width: 40em;
+}
+
+image#syncIcon {
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
+
+#introText {
+ margin-top: 2px;
+}
+
+#feedback {
+ height: 2em;
+}
diff --git a/themes/windows/syncProgress.css b/themes/windows/syncProgress.css
new file mode 100644
index 0000000..d7aa599
--- /dev/null
+++ b/themes/windows/syncProgress.css
@@ -0,0 +1,46 @@
+/* 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/. */
+@import url(chrome://global/skin/inContentUI.css);
+
+:root {
+ height: 100%;
+ width: 100%;
+ padding: 0;
+}
+
+body {
+ margin: 0;
+ padding: 0 2em;
+}
+
+#floatingBox {
+ margin: 4em auto;
+ max-width: 40em;
+ min-width: 23em;
+ padding: 1em 1.5em;
+ position: relative;
+ text-align: center;
+}
+
+#successLogo {
+ margin: 1em 2em;
+}
+
+#loadingText {
+ margin: 2em 6em;
+}
+
+#progressBar {
+ margin: 2em 10em;
+}
+
+#uploadProgressBar{
+ width: 100%;
+}
+
+#bottomRow {
+ margin-top: 2em;
+ padding: 0;
+ text-align: end;
+}
diff --git a/themes/windows/syncQuota.css b/themes/windows/syncQuota.css
new file mode 100644
index 0000000..1577de8
--- /dev/null
+++ b/themes/windows/syncQuota.css
@@ -0,0 +1,26 @@
+/* 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/. */
+
+#quotaDialog {
+ width: 33em;
+ height: 25em;
+}
+
+treechildren::-moz-tree-checkbox {
+ list-style-image: none;
+}
+treechildren::-moz-tree-checkbox(checked) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
+}
+treechildren::-moz-tree-checkbox(disabled) {
+ list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
+}
+
+#treeCaption {
+ height: 4em;
+}
+
+.captionWarning {
+ font-weight: bold;
+}
diff --git a/themes/windows/syncSetup.css b/themes/windows/syncSetup.css
new file mode 100644
index 0000000..fff65e9
--- /dev/null
+++ b/themes/windows/syncSetup.css
@@ -0,0 +1,132 @@
+/* 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/. */
+
+wizard {
+ -moz-appearance: none;
+ width: 55em;
+ height: 45em;
+ padding: 0;
+ background-color: Window;
+}
+
+.wizard-page-box {
+ -moz-appearance: none;
+ padding-left: 0;
+ padding-right: 0;
+ margin: 0;
+}
+
+wizardpage {
+ -moz-box-pack: center;
+ -moz-box-align: center;
+ margin: 0;
+ padding: 0 6em;
+ background-color: Window;
+}
+
+.wizard-header {
+ -moz-appearance: none;
+ border: none;
+ padding: 2em 0 1em 0;
+ text-align: center;
+}
+.wizard-header-label {
+ font-size: 24pt;
+ font-weight: normal;
+}
+
+.wizard-buttons {
+ background-color: rgba(0,0,0,0.1);
+ padding: 1em;
+}
+
+.wizard-buttons-separator {
+ visibility: collapse;
+}
+
+.wizard-header-icon {
+ visibility: collapse;
+}
+
+.accountChoiceButton {
+ font: menu;
+}
+
+.confirm {
+ border: 1px solid black;
+ padding: 1em;
+ border-radius: 5px;
+}
+
+/* Override the text-link style from global.css */
+description > .text-link,
+description > .text-link:focus {
+ margin: 0px;
+ padding: 0px;
+ border: 0px;
+}
+
+
+.success,
+.error {
+ padding: 2px;
+ border-radius: 2px;
+}
+
+.error {
+ background-color: #FF0000 !important;
+ color: #FFFFFF !important;
+}
+
+.success {
+ background-color: #00FF00 !important;
+}
+
+.warning {
+ font-weight: bold;
+ font-size: 100%;
+ color: red;
+}
+
+.mainDesc {
+ font-weight: bold;
+ font-size: 100%;
+}
+
+.normal {
+ font-size: 100%;
+}
+
+.inputColumn {
+ -moz-margin-end: 2px
+}
+
+.pin {
+ font-size: 18pt;
+ width: 4em;
+ text-align: center;
+}
+
+#passphraseHelpSpacer {
+ width: 0.5em;
+}
+
+#pairDeviceThrobber > image,
+#login-throbber > image {
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+
+#captchaFeedback {
+ visibility: hidden;
+}
+
+#successPageIcon {
+ /* TODO replace this with a 128px version (bug 591122) */
+ list-style-image: url("chrome://browser/skin/sync-32.png");
+}
+
+#tosDesc {
+ margin-left: -7px;
+ margin-bottom: 3px;
+}
\ No newline at end of file
diff --git a/themes/windows/tabbrowser/alltabs-inverted.png b/themes/windows/tabbrowser/alltabs-inverted.png
new file mode 100644
index 0000000..002bdd4
Binary files /dev/null and b/themes/windows/tabbrowser/alltabs-inverted.png differ
diff --git a/themes/windows/tabbrowser/alltabs.png b/themes/windows/tabbrowser/alltabs.png
new file mode 100644
index 0000000..172d425
Binary files /dev/null and b/themes/windows/tabbrowser/alltabs.png differ
diff --git a/themes/windows/tabbrowser/connecting.png b/themes/windows/tabbrowser/connecting.png
new file mode 100644
index 0000000..e564fb5
Binary files /dev/null and b/themes/windows/tabbrowser/connecting.png differ
diff --git a/themes/windows/tabbrowser/loading.png b/themes/windows/tabbrowser/loading.png
new file mode 100644
index 0000000..ba54836
Binary files /dev/null and b/themes/windows/tabbrowser/loading.png differ
diff --git a/themes/windows/tabbrowser/newtab-glass.png b/themes/windows/tabbrowser/newtab-glass.png
new file mode 100644
index 0000000..15185be
Binary files /dev/null and b/themes/windows/tabbrowser/newtab-glass.png differ
diff --git a/themes/windows/tabbrowser/newtab-inverted.png b/themes/windows/tabbrowser/newtab-inverted.png
new file mode 100644
index 0000000..4ac1eba
Binary files /dev/null and b/themes/windows/tabbrowser/newtab-inverted.png differ
diff --git a/themes/windows/tabbrowser/newtab.png b/themes/windows/tabbrowser/newtab.png
new file mode 100644
index 0000000..7cea7bd
Binary files /dev/null and b/themes/windows/tabbrowser/newtab.png differ
diff --git a/themes/windows/tabbrowser/tab-arrow-left-glass.png b/themes/windows/tabbrowser/tab-arrow-left-glass.png
new file mode 100644
index 0000000..aac93a7
Binary files /dev/null and b/themes/windows/tabbrowser/tab-arrow-left-glass.png differ
diff --git a/themes/windows/tabbrowser/tab-arrow-left-inverted.png b/themes/windows/tabbrowser/tab-arrow-left-inverted.png
new file mode 100644
index 0000000..16cd7a2
Binary files /dev/null and b/themes/windows/tabbrowser/tab-arrow-left-inverted.png differ
diff --git a/themes/windows/tabbrowser/tab-arrow-left.png b/themes/windows/tabbrowser/tab-arrow-left.png
new file mode 100644
index 0000000..e0fb348
Binary files /dev/null and b/themes/windows/tabbrowser/tab-arrow-left.png differ
diff --git a/themes/windows/tabbrowser/tab-overflow-border.png b/themes/windows/tabbrowser/tab-overflow-border.png
new file mode 100644
index 0000000..77f2462
Binary files /dev/null and b/themes/windows/tabbrowser/tab-overflow-border.png differ
diff --git a/themes/windows/tabbrowser/tabDragIndicator.png b/themes/windows/tabbrowser/tabDragIndicator.png
new file mode 100644
index 0000000..c67c233
Binary files /dev/null and b/themes/windows/tabbrowser/tabDragIndicator.png differ
diff --git a/themes/windows/toolbarbutton-dropdown-arrow-inverted.png b/themes/windows/toolbarbutton-dropdown-arrow-inverted.png
new file mode 100644
index 0000000..f3261f1
Binary files /dev/null and b/themes/windows/toolbarbutton-dropdown-arrow-inverted.png differ
diff --git a/themes/windows/toolbarbutton-dropdown-arrow.png b/themes/windows/toolbarbutton-dropdown-arrow.png
new file mode 100644
index 0000000..a7abe73
Binary files /dev/null and b/themes/windows/toolbarbutton-dropdown-arrow.png differ
diff --git a/themes/windows/urlbar-arrow.png b/themes/windows/urlbar-arrow.png
new file mode 100644
index 0000000..fcab253
Binary files /dev/null and b/themes/windows/urlbar-arrow.png differ
diff --git a/themes/windows/urlbar-history-dropmarker.png b/themes/windows/urlbar-history-dropmarker.png
new file mode 100644
index 0000000..fc8b0be
Binary files /dev/null and b/themes/windows/urlbar-history-dropmarker.png differ
diff --git a/themes/windows/urlbar-popup-blocked.png b/themes/windows/urlbar-popup-blocked.png
new file mode 100644
index 0000000..e6fd29f
Binary files /dev/null and b/themes/windows/urlbar-popup-blocked.png differ
diff --git a/themes/windows/web-notifications-icon.svg b/themes/windows/web-notifications-icon.svg
new file mode 100644
index 0000000..f7186c7
--- /dev/null
+++ b/themes/windows/web-notifications-icon.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/themes/windows/web-notifications-tray.svg b/themes/windows/web-notifications-tray.svg
new file mode 100644
index 0000000..314026a
--- /dev/null
+++ b/themes/windows/web-notifications-tray.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/themes/windows/webRTC-shareDevice-16.png b/themes/windows/webRTC-shareDevice-16.png
new file mode 100644
index 0000000..df01b33
Binary files /dev/null and b/themes/windows/webRTC-shareDevice-16.png differ
diff --git a/themes/windows/webRTC-shareDevice-64.png b/themes/windows/webRTC-shareDevice-64.png
new file mode 100644
index 0000000..d125789
Binary files /dev/null and b/themes/windows/webRTC-shareDevice-64.png differ
diff --git a/themes/windows/webRTC-sharingDevice-16.png b/themes/windows/webRTC-sharingDevice-16.png
new file mode 100644
index 0000000..a670676
Binary files /dev/null and b/themes/windows/webRTC-sharingDevice-16.png differ
--
cgit v1.2.3