Merge fx-team to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 23 Aug 2013 16:56:55 -0400
changeset 144147 ce881259e2d0a10897c9ca1ecf116a1cba1a8e56
parent 144137 6dea0e001df0371b7a1bfe3633eff926fcdb4a3c (current diff)
parent 144146 d7f20a38e66e208822fe4f12bb192d53f3cf6ddb (diff)
child 144148 17143a9a0d838ced69fa159d8b12c7ecfcc5d8c4
push id32885
push userryanvm@gmail.com
push dateFri, 23 Aug 2013 22:11:15 +0000
treeherdermozilla-inbound@d0fda982e6a5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge fx-team to m-c.
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1718,17 +1718,17 @@
 
             if (this.warnAboutClosingTabs(this.closingTabsEnum.OTHER)) {
               let tabs = this.visibleTabs;
               this.selectedTab = aTab;
 
               let closedTabs = 0;
               for (let i = tabs.length - 1; i >= 0; --i) {
                 if (tabs[i] != aTab && !tabs[i].pinned) {
-                  this.removeTab(tabs[i]);
+                  this.removeTab(tabs[i], {animate: true});
                   closedTabs++;
                 }
               }
               let ss = Cc["@mozilla.org/browser/sessionstore;1"].
                        getService(Ci.nsISessionStore);
               ss.setNumberOfTabsClosedLast(window, closedTabs);
             }
           ]]>
--- a/browser/base/content/test/browser_bug577121.js
+++ b/browser/base/content/test/browser_bug577121.js
@@ -1,13 +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/. */
 
 function test() {
+  Services.prefs.setBoolPref("browser.tabs.animate", false);
+  registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("browser.tabs.animate");
+  });
+
   // Open 2 other tabs, and pin the second one. Like that, the initial tab
   // should get closed.
   let testTab1 = gBrowser.addTab();
   let testTab2 = gBrowser.addTab();
   gBrowser.pinTab(testTab2);
 
   // Now execute "Close other Tabs" on the first manually opened tab (tab1).
   // -> tab2 ist pinned, tab1 should remain open and the initial tab should
--- a/browser/base/content/test/browser_bug887515.js
+++ b/browser/base/content/test/browser_bug887515.js
@@ -37,17 +37,19 @@ function verifyUndoMultipleClose() {
      "The label should be showing that the command will restore multiple tabs");
 
   finish();
 }
 
 function test() {
   waitForExplicitFinish();
 
+  Services.prefs.setBoolPref("browser.tabs.animate", false);
   registerCleanupFunction(function() {
+    Services.prefs.clearUserPref("browser.tabs.animate");
     originalTab.linkedBrowser.loadURI("about:blank");
     originalTab = null;
   });
 
   let undoCloseTabElement = document.getElementById("context_undoCloseTab");
   updateTabContextMenu();
   is(undoCloseTabElement.label, undoCloseTabElement.getAttribute("singletablabel"),
      "The label should be showing that the command will restore a single tab");
--- a/build/pgo/index.html
+++ b/build/pgo/index.html
@@ -152,19 +152,20 @@
  var idx = 0;
  var w;
  
  window.onload = function () {
      w = window.open("about:blank");
      window.setTimeout(loadURL, interval); 
  };
  function loadURL () {
-     w.location.href = list[idx++];
+     w.close();
+     w = window.open(list[idx++]);
      if (idx < list.length) {
- 	window.setTimeout(loadURL, interval);
+     window.setTimeout(loadURL, interval);
      } else {
          window.setTimeout(goQuitApplication, interval);
      }
  }
  var i;
  
  for(i=0; i < list.length;i++) {
      document.write(list[i]);
--- a/mobile/android/base/home/SearchEngineRow.java
+++ b/mobile/android/base/home/SearchEngineRow.java
@@ -133,28 +133,40 @@ class SearchEngineRow extends AnimatedHe
         setOnLongClickListener(new OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
                 return true;
             }
         });
     }
 
+    private void setDescriptionOnSuggestion(View v, String suggestion) {
+        v.setContentDescription(getResources().getString(R.string.suggestion_for_engine,
+                                                         mSearchEngine.name, suggestion));
+    }
+
     private String getSuggestionTextFromView(View v) {
         final TextView suggestionText = (TextView) v.findViewById(R.id.suggestion_text);
         return suggestionText.getText().toString();
     }
 
     private void setSuggestionOnView(View v, String suggestion) {
         final TextView suggestionText = (TextView) v.findViewById(R.id.suggestion_text);
         suggestionText.setText(suggestion);
+        setDescriptionOnSuggestion(suggestionText, suggestion);
     }
 
     public void setSearchTerm(String searchTerm) {
         mUserEnteredTextView.setText(searchTerm);
+
+        // mSearchEngine is not set in the first call to this method; the content description
+        // is instead initially set in updateFromSearchEngine.
+        if (mSearchEngine != null) {
+            setDescriptionOnSuggestion(mUserEnteredTextView, searchTerm);
+        }
     }
 
     public void setOnUrlOpenListener(OnUrlOpenListener listener) {
         mUrlOpenListener = listener;
     }
 
     public void setOnSearchListener(OnSearchListener listener) {
         mSearchListener = listener;
@@ -166,16 +178,19 @@ class SearchEngineRow extends AnimatedHe
 
     public void updateFromSearchEngine(SearchEngine searchEngine, boolean animate) {
         // Update search engine reference
         mSearchEngine = searchEngine;
 
         // Set the search engine icon (e.g., Google) for the row
         mIconView.updateImage(mSearchEngine.icon, mSearchEngine.name);
 
+        // Set the initial content description
+        setDescriptionOnSuggestion(mUserEnteredTextView, mUserEnteredTextView.getText().toString());
+
         // Add additional suggestions given by this engine
         final int recycledSuggestionCount = mSuggestionView.getChildCount();
         final int suggestionCount = mSearchEngine.suggestions.size();
 
         for (int i = 0; i < suggestionCount; i++) {
             final View suggestionItem;
 
             // Reuse suggestion views from recycled view, if possible
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -328,16 +328,21 @@ just addresses the organization to follo
 <!ENTITY bookmarkhistory_import_history "Importing history
                                          from Android">
 <!ENTITY bookmarkhistory_import_wait "Please wait...">
 
 <!-- Localization note (suggestions_prompt2): The placeholder &formatS; will be
      replaced with the name of the search engine. -->
 <!ENTITY suggestions_prompt2 "Would you like to turn on &formatS; search suggestions?">
 
+<!-- Localization note (suggestion_for_engine): The placeholder &formatS1; will be
+     replaced with the name of the search engine. The placeholder &formatS2; will be
+     replaced with the search query. -->
+<!ENTITY suggestion_for_engine "Search &formatS1; for &formatS2;">
+
 <!ENTITY webapp_generic_name "App">
 
 <!ENTITY searchable_description "Bookmarks and history">
 
 <!ENTITY devtools_remote_debugging_forward "Don\'t forget to set up port forwarding!">
 
  <!-- Updater notifications -->
 <!ENTITY updater_start_title2 "Update available for &brandShortName;">
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -6,16 +6,18 @@
 
 <!DOCTYPE resources [
 #includesubst @BRANDPATH@
 #includesubst @STRINGSPATH@
 #includesubst @SYNCSTRINGSPATH@
 
 <!-- C-style format strings. -->
 <!ENTITY formatS "&#037;s">
+<!ENTITY formatS1 "&#037;1&#036;s">
+<!ENTITY formatS2 "&#037;2&#036;s">
 <!ENTITY formatD "&#037;d">
 ]>
 
 #includesubst @BOOKMARKSPATH@
 <resources>
   <string name="moz_app_displayname">@MOZ_APP_DISPLAYNAME@</string>
 #include ../services/strings.xml.in
   <string name="no_space_to_start_error">&no_space_to_start_error;</string>
@@ -319,16 +321,18 @@
   <string name="updater_downloading_retry">&updater_downloading_retry2;</string>
 
   <string name="updater_apply_title">&updater_apply_title2;</string>
   <string name="updater_apply_select">&updater_apply_select2;</string>
 
   <!-- Search suggestions opt-in -->
   <string name="suggestions_prompt">&suggestions_prompt2;</string>
 
+  <string name="suggestion_for_engine">&suggestion_for_engine;</string>
+
   <!-- Set Image Notifications -->
   <string name="set_image_fail">&set_image_fail;</string>
   <string name="set_image_chooser_title">&set_image_chooser_title;</string>
 
   <!-- Contacts API -->
   <string name="contacts_account_chooser_dialog_title">Share contacts from...</string>
 
 
--- a/mobile/android/base/tests/AboutHomeTest.java.in
+++ b/mobile/android/base/tests/AboutHomeTest.java.in
@@ -116,50 +116,36 @@ abstract class AboutHomeTest extends Bas
             if (TextUtils.equals(listTag, tag)) {
                 return listView;
             }
         }
 
         return null;
     }
 
+    /**
+     * Adds a bookmark, or updates the bookmark title if the url already exists.
+     *
+     * The LocalBrowserDB.addBookmark implementation handles updating existing bookmarks.
+     * Since we don't modify bookmark keywords in tests, we don't need a separate
+     * implemention of updateBookmark.
+     */
     protected void addOrUpdateMobileBookmark(String title, String url) {
-        if (isBookmark(url)) {
-            updateBookmark(title, url, null);
-        } else {
-            addMobileBookmark(title, url);
-        }
-    }
-
-    protected void addMobileBookmark(String title, String url) {
         try {
             ContentResolver resolver = getActivity().getContentResolver();
             ClassLoader classLoader = getActivity().getClassLoader();
             Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
             Method addBookmark = browserDB.getMethod("addBookmark", ContentResolver.class, String.class, String.class);
             addBookmark.invoke(null, resolver, title, url);
-            mAsserter.ok(true, "Inserting a new bookmark", "Inserter the bookmark with the title = " + title + " and the url = " + url);
+            mAsserter.ok(true, "Inserting/updating a new bookmark", "Inserting/updating the bookmark with the title = " + title + " and the url = " + url);
         } catch (Exception e) {
             mAsserter.ok(false, "Exception adding bookmark: ", e.toString());
         }
     }
 
-    protected void updateBookmark(String title, String url, String keyword) {
-        try {
-            ContentResolver resolver = getActivity().getContentResolver();
-            ClassLoader classLoader = getActivity().getClassLoader();
-            Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
-            Method updateBookmark = browserDB.getMethod("updateBookmark", ContentResolver.class, String.class, String.class);
-            updateBookmark.invoke(null, resolver, title, url, keyword);
-            mAsserter.ok(true, "Updating existing bookmark", "Setting the values to title = " + title + ", url = " + url + " and keyword = " + keyword);
-        } catch (Exception e) {
-            mAsserter.ok(false, "Exception updating bookmark: ", e.toString());
-        }
-    }
-
     protected void deleteBookmark(String url) {
         try {
             ContentResolver resolver = getActivity().getContentResolver();
             ClassLoader classLoader = getActivity().getClassLoader();
             Class browserDB = classLoader.loadClass("org.mozilla.gecko.db.BrowserDB");
             Method removeBookmark = browserDB.getMethod("removeBookmarksWithURL", ContentResolver.class, String.class);
             removeBookmark.invoke(null, resolver, url);
         } catch (Exception e) {
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -23,17 +23,17 @@
 [testSharedPreferences]
 # [testThumbnails] # see bug 813107
 [testAddonManager]
 [testHistory]
 # [testVkbOverlap] # see bug 907274
 [testDoorHanger]
 [testTabHistory]
 [testShareLink]
-# [testClearPrivateData] # disabled on fig - bug 880060
+[testClearPrivateData]
 [testSettingsMenuItems]
 [testSystemPages]
 # [testPermissions] # see bug 757475
 [testJarReader]
 [testDistribution]
 [testFindInPage]
 [testInputUrlBar]
 # [testAddSearchEngine] # disabled on fig - bug 880060
--- a/mobile/android/base/tests/testClearPrivateData.java.in
+++ b/mobile/android/base/tests/testClearPrivateData.java.in
@@ -1,45 +1,44 @@
 #filter substitution
 package @ANDROID_PACKAGE_NAME@.tests;
 
 import @ANDROID_PACKAGE_NAME@.*;
-import android.widget.ListView;
+import java.util.ArrayList;
 
-public class testClearPrivateData extends AboutHomeTest  {
+public class testClearPrivateData extends AboutHomeTest {
+    private final String BLANK1_TITLE = "Browser Blank Page 01";
+    private final String BLANK2_TITLE = "Browser Blank Page 02";
 
     @Override
     protected int getTestType() {
         return TEST_MOCHITEST;
     }
 
     public void testClearPrivateData() {
         blockForGeckoReady();
         clearHistory();
     }
 
     private void clearHistory() {
-        // Loading a page so we are sure that there is at least one history entry
-        String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
-        inputAndLoadUrl(url);
+        // Loading a page and adding a second one as bookmark to have user made bookmarks and history
+        String blank1 = getAbsoluteUrl("/robocop/robocop_blank_01.html");
+        String blank2 = getAbsoluteUrl("/robocop/robocop_blank_02.html");
 
-        /*  Removed by Bug 896576 - [fig] Remove [getHistoryList] from BaseTest
-        // Checking that the history list is not empty
-        ListView hList = getHistoryList("Today|Yesterday");
-        mAsserter.ok(hList.getAdapter().getCount() > 0,"checking history exists","history exists");
+        inputAndLoadUrl(blank1);
+        waitForText(BLANK1_TITLE);
 
-        // Quit the awesomescreen
-        mActions.sendSpecialKey(Actions.SpecialKey.BACK);
-        waitForText("Browser Blank Page 01");
+        addOrUpdateMobileBookmark(BLANK2_TITLE, blank2);
 
-        // Clearing private data
-        selectSettingsItem("Privacy", "Clear private data");
-        mAsserter.ok(mSolo.searchButton("Clear data"),"checking clear button","clear button exists");
-        mSolo.clickOnButton("Clear data");
-        // TODO: extra long wait here for bug 837274
-        mAsserter.is(mSolo.waitForText("Private data cleared", 0, 60000),true,"private data cleared successfully");
+        // Checking that the history list is not empty
+        ArrayList<String> browserHistory = getBrowserDBUrls(BrowserDataType.HISTORY);
+        mAsserter.ok(browserHistory.size() > 0,"Checking history exists","History exists");
+
+        clearPrivateData();
 
         // Checking that history list is empty
-        hList = getHistoryList("History", 0);
-        mAsserter.ok(hList != null,"checking history is cleared ","history is cleared");
-        */
+        browserHistory = getBrowserDBUrls(BrowserDataType.HISTORY);
+        mAsserter.ok(browserHistory.size() == 0,"Checking history is cleared ","History is cleared");
+
+        // Checking that the user made bookmark is not removed
+        mAsserter.ok(isBookmark(blank2), "Checking that bookmarks have not been removed", "User made bookmarks were not removed with private data");
     }
 }
--- a/mobile/android/base/tests/testImportFromAndroid.java.in
+++ b/mobile/android/base/tests/testImportFromAndroid.java.in
@@ -105,17 +105,17 @@ public class testImportFromAndroid exten
 
     private void addData() {
         ArrayList<String> androidBookmarks = getAndroidUrls("bookmarks");
 
         // Add a few Bookmarks from Android to Firefox Mobile
         for (String url:androidBookmarks) {
             // Add every 3rd bookmark to Firefox Mobile
             if ((androidBookmarks.indexOf(url) % 3) == 0) {
-                 addOrUpdateMobileBookmark("Bookmar Number" + String.valueOf(androidBookmarks.indexOf(url)), url);
+                 addOrUpdateMobileBookmark("Bookmark Number " + String.valueOf(androidBookmarks.indexOf(url)), url);
             }
         }
 
         // Add a few history items in Firefox Mobile
         ContentResolver resolver = getActivity().getContentResolver();
         Uri uri = Uri.parse("content://@ANDROID_PACKAGE_NAME@.db.browser/history");
         uri = uri.buildUpon().appendQueryParameter("profile", "default")
                              .appendQueryParameter("sync", "true").build();
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -106,29 +106,44 @@ class MochitestRunner(MozbuildObject):
         for handler in remove_handlers:
             logging.getLogger().removeHandler(handler)
 
         runner = mochitest.Mochitest(automation)
 
         opts = mochitest.MochitestOptions(automation)
         options, args = opts.parse_args([])
 
+        appname = ''
+        if sys.platform.startswith('darwin'):
+            appname = os.path.join(self.distdir, self.substs['MOZ_MACBUNDLE_NAME'],
+            'Contents', 'MacOS', 'webapprt-stub' + automation.BIN_SUFFIX)
+        else:
+            appname = os.path.join(self.distdir, 'bin', 'webapprt-stub' +
+            automation.BIN_SUFFIX)
+
         # Need to set the suite options before verifyOptions below.
         if suite == 'plain':
             # Don't need additional options for plain.
             pass
         elif suite == 'chrome':
             options.chrome = True
         elif suite == 'browser':
             options.browserChrome = True
         elif suite == 'metro':
             options.immersiveMode = True
             options.browserChrome = True
         elif suite == 'a11y':
             options.a11y = True
+        elif suite == 'webapprt-content':
+            options.webapprtContent = True
+            options.app = appname
+        elif suite == 'webapprt-chrome':
+            options.webapprtChrome = True
+            options.app = appname
+            options.browserArgs.append("-test-mode")
         else:
             raise Exception('None or unrecognized mochitest suite type.')
 
         options.autorun = not no_autorun
         options.closeWhenDone = not keep_open
         options.shuffle = shuffle
         options.consoleLevel = 'INFO'
         options.repeat = repeat
@@ -222,17 +237,17 @@ def MochitestCommand(func):
         help='Shuffle execution order.')
     func = shuffle(func)
 
     keep_open = CommandArgument('--keep-open', action='store_true',
         help='Keep the browser open after tests complete.')
     func = keep_open(func)
 
     rerun = CommandArgument('--rerun-failures', action='store_true',
-        help='Run only the tests that filed during the last test run.')
+        help='Run only the tests that failed during the last test run.')
     func = rerun(func)
 
     autorun = CommandArgument('--no-autorun', action='store_true',
         help='Do not starting running tests automatically.')
     func = autorun(func)
 
     repeat = CommandArgument('--repeat', type=int, default=0,
         help='Repeat the test the given number of times.')
@@ -285,14 +300,26 @@ class MachCommands(MachCommandBase):
         return self.run_mochitest(test_file, 'metro', **kwargs)
 
     @Command('mochitest-a11y', category='testing',
         description='Run an a11y mochitest.')
     @MochitestCommand
     def run_mochitest_a11y(self, test_file, **kwargs):
         return self.run_mochitest(test_file, 'a11y', **kwargs)
 
+    @Command('webapprt-test-chrome', category='testing',
+        description='Run a webapprt chrome mochitest.')
+    @MochitestCommand
+    def run_mochitest_webapprt_chrome(self, test_file, **kwargs):
+        return self.run_mochitest(test_file, 'webapprt-chrome', **kwargs)
+
+    @Command('webapprt-test-content', category='testing',
+        description='Run a webapprt content mochitest.')
+    @MochitestCommand
+    def run_mochitest_webapprt_content(self, test_file, **kwargs):
+        return self.run_mochitest(test_file, 'webapprt-content', **kwargs)
+
     def run_mochitest(self, test_file, flavor, **kwargs):
         self._ensure_state_subdir_exists('.')
 
         mochitest = self._spawn(MochitestRunner)
         return mochitest.run_mochitest_test(test_file=test_file, suite=flavor,
             **kwargs)
--- a/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
+++ b/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
@@ -867,16 +867,17 @@ let test_system_shutdown = maketest("sys
   });
 });
 
 /**
  * Test optional duration reporting that can be used for telemetry.
  */
 let test_duration = maketest("duration", function duration(test) {
   return Task.spawn(function() {
+    Services.prefs.setBoolPref("toolkit.osfile.log", true);
     // Options structure passed to a OS.File copy method.
     let copyOptions = {
       // This field should be overridden with the actual duration
       // measurement.
       outExecutionDuration: null
     };
     let currentDir = yield OS.File.getCurrentDirectory();
     let pathSource = OS.Path.join(currentDir, EXISTING_FILE);
@@ -942,17 +943,17 @@ let test_duration = maketest("duration",
       tmpPath: tmpPath
     };
     backupDuration = writeAtomicOptions.outExecutionDuration;
 
     yield OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
     test.ok(copyOptions.outExecutionDuration >= backupDuration, "duration has increased 3");
     OS.File.remove(pathDest);
 
-    Services.prefs.setBoolPref("toolkit.osfile.log", true);
     OS.Shared.TEST = true;
 
     // Testing an operation that doesn't take arguments at all
     let file = yield OS.File.open(pathSource);
     yield file.stat();
     yield file.close();
+    Services.prefs.setBoolPref("toolkit.osfile.log", false);
   });
 });
--- a/toolkit/themes/windows/global/tree-aero.css
+++ b/toolkit/themes/windows/global/tree-aero.css
@@ -65,17 +65,16 @@ treechildren:-moz-locale-dir(rtl)::-moz-
 
 @media (-moz-windows-default-theme) {
   treechildren::-moz-tree-row {
     height: 1.8em;
     color: -moz-FieldText;
     -moz-margin-start: 1px;
     -moz-margin-end: 1px;
     border-width: 2px;
-    border-style: solid !important;
     border-color: transparent;
     border-radius: 3px;
     background-repeat: no-repeat;
     background-size: 100% 100%;
     -moz-outline-radius: 3px;
   }
 
   treechildren::-moz-tree-row(selected) {
@@ -84,16 +83,17 @@ treechildren:-moz-locale-dir(rtl)::-moz-
     -moz-border-left-colors: @selectedBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-bottom-colors: @selectedBorderColor@ @whiteOpacityBottomBorderColor@;
     background-image: linear-gradient(@selectedGradientColor1@, @selectedGradientColor2@);
     background-color: transparent;
     outline: 1px solid @whiteOpacityBorderColor@;
   }
 
   treechildren::-moz-tree-row(current, focus) {
+    border-style: solid;
     -moz-border-top-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-right-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-left-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-bottom-colors: @hoverAndFocusBorderColor@ @whiteOpacityBottomBorderColor@;
     outline: 1px solid @whiteOpacityBorderColor@;
   }
 
   treechildren::-moz-tree-row(selected, focus),
@@ -102,16 +102,17 @@ treechildren:-moz-locale-dir(rtl)::-moz-
     -moz-border-right-colors: @selectedFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-left-colors: @selectedFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-bottom-colors: @selectedFocusBorderColor@ @whiteOpacityBottomBorderColor@;
     background-image: linear-gradient(@selectedFocusGradientColor1@, @selectedFocusGradientColor2@);
     background-color: transparent;
   }
 
   treechildren::-moz-tree-row(selected, current, focus) {
+    border-style: solid;
     -moz-border-top-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-right-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-left-colors: @hoverAndFocusBorderColor@ @whiteOpacityBorderColor@;
     -moz-border-bottom-colors: @hoverAndFocusBorderColor@ @whiteOpacityBottomBorderColor@;
     background-image: linear-gradient(@hoverAndCurrentFocusGradientColor1@, @hoverAndCurrentFocusGradientColor2@);
   }
 
   treechildren::-moz-tree-row(hover) {
--- a/toolkit/themes/windows/global/tree.css
+++ b/toolkit/themes/windows/global/tree.css
@@ -56,16 +56,17 @@ treechildren::-moz-tree-row(current, foc
 treechildren::-moz-tree-row(selected, current, focus) {
   border: 1px dotted #F3D982;
 }
 
 tree[seltype="cell"] > treechildren::-moz-tree-row,
 tree[seltype="text"] > treechildren::-moz-tree-row {
   border: none;
   background-color: transparent;
+  background-image: none;
 }
 
 /* ::::: tree cells ::::: */
 
 treechildren::-moz-tree-cell {
   padding: 0px 2px 0px 2px;
 }