From 18310b3f3ecff1010ef0e100ca7a0f53ffb90f1e Mon Sep 17 00:00:00 2001 From: Robert Strong Date: Fri, 23 Aug 2013 12:24:43 -0700 Subject: [PATCH 01/20] Bug 907975 - Several telemetry histograms sent for checkForBackgroundUpdates and notify that should only be sent for notify. r=bbondy --- toolkit/mozapps/update/nsUpdateService.js | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index a6b2597d2a5..4c41e1d7e5c 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -2543,6 +2543,24 @@ UpdateService.prototype = { * The timer that fired */ notify: function AUS_notify(timer) { + // The telemetry below is specific to background notification. + this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_ENABLED, + "UPDATER_UPDATES_ENABLED"); + this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_METRO_ENABLED, + "UPDATER_UPDATES_METRO_ENABLED"); + this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO, + "UPDATER_UPDATES_AUTOMATIC"); + this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED, + "UPDATER_STAGE_ENABLED"); + +#ifdef XP_WIN + this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ENABLED, + "UPDATER_SERVICE_ENABLED"); + this._sendIntPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ERRORS, + "UPDATER_SERVICE_ERRORS"); + this._sendServiceInstalledTelemetryPing(); +#endif + this._checkForBackgroundUpdates(true); }, @@ -2561,24 +2579,10 @@ UpdateService.prototype = { */ _checkForBackgroundUpdates: function AUS__checkForBackgroundUpdates(isNotify) { this._isNotify = isNotify; - // This ensures that telemetry is gathered even if update is disabled. + // From this point on, the telemetry reported differentiates between a call + // to notify and a call to checkForBackgroundUpdates so they are reported + // separately. this._sendLastNotifyIntervalPing(); - this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_ENABLED, - "UPDATER_UPDATES_ENABLED"); - this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_METRO_ENABLED, - "UPDATER_UPDATES_METRO_ENABLED"); - this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_AUTO, - "UPDATER_UPDATES_AUTOMATIC"); - this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_STAGING_ENABLED, - "UPDATER_STAGE_ENABLED"); - -#ifdef XP_WIN - this._sendBoolPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ENABLED, - "UPDATER_SERVICE_ENABLED"); - this._sendIntPrefTelemetryPing(PREF_APP_UPDATE_SERVICE_ERRORS, - "UPDATER_SERVICE_ERRORS"); - this._sendServiceInstalledTelemetryPing(); -#endif // If a download is in progress or the patch has been staged do nothing. if (this.isDownloading) { From 1c593a304a6275f96cd321cb8dd93b7bbe2bc813 Mon Sep 17 00:00:00 2001 From: Robert Strong Date: Fri, 23 Aug 2013 12:25:03 -0700 Subject: [PATCH 02/20] Possible fix for Bug 908020 - tests 160 and 161 _appInUse take too long (top 8 duration). r=bbondy --- toolkit/mozapps/update/test/unit/head_update.js.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/toolkit/mozapps/update/test/unit/head_update.js.in b/toolkit/mozapps/update/test/unit/head_update.js.in index 51eedb0e715..988e7d9a947 100644 --- a/toolkit/mozapps/update/test/unit/head_update.js.in +++ b/toolkit/mozapps/update/test/unit/head_update.js.in @@ -109,7 +109,7 @@ var gSwitchApp = false; var gDisableReplaceFallback = false; // Time to wait for the test helper process before continuing the test -const TEST_HELPER_TIMEOUT = 2000; +const TEST_HELPER_TIMEOUT = 100; // Use a copy of the main application executable for the test to avoid main // executable in use errors. @@ -1057,7 +1057,7 @@ function waitForHelperSleep() { return; } output.remove(false); - do_timeout(TEST_HELPER_TIMEOUT, doUpdate); + doUpdate(); } function waitForHelperFinished() { @@ -1070,7 +1070,7 @@ function waitForHelperFinished() { } // Give the lock file process time to unlock the file before deleting the // input and output files. - do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinishFileUnlock); + waitForHelperFinishFileUnlock(); } function waitForHelperFinishFileUnlock() { @@ -1090,13 +1090,13 @@ function waitForHelperFinishFileUnlock() { do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinishFileUnlock); return; } - do_timeout(TEST_HELPER_TIMEOUT, checkUpdate); + checkUpdate(); } function setupHelperFinish() { let input = getApplyDirFile("a/b/input", true); writeFile(input, "finish\n"); - do_timeout(TEST_HELPER_TIMEOUT, waitForHelperFinished); + waitForHelperFinished(); } /** @@ -1570,7 +1570,7 @@ function removeCallbackCopy() { } // Use a timeout to give any files that were in use additional // time to close. Same as updater.exe without service tests. - do_timeout(TEST_HELPER_TIMEOUT, do_test_finished); + do_test_finished(); } // Waits until files that are in use that break tests are no longer in use and From 5a96525fbb2cf377692bbdce1410caeac31055b0 Mon Sep 17 00:00:00 2001 From: Brian Nicholson Date: Fri, 23 Aug 2013 12:32:19 -0700 Subject: [PATCH 03/20] Bug 904741 - Change session restore pref to have two states. r=mfinkle --- mobile/android/base/GeckoApp.java | 26 ++++++------------- mobile/android/base/GeckoPreferences.java | 2 +- .../base/locales/en-US/android_strings.dtd | 3 +-- .../android/base/resources/values/arrays.xml | 6 ++--- .../xml-v11/preferences_customize.xml | 4 +-- .../xml-v11/preferences_customize_tablet.xml | 4 +-- .../xml/preferences_customize.xml.in | 4 +-- mobile/android/base/strings.xml.in | 3 +-- 8 files changed, 19 insertions(+), 33 deletions(-) diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index 4a9be3ea931..22f75c10710 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -1664,12 +1664,11 @@ abstract public class GeckoApp protected int getSessionRestoreState(Bundle savedInstanceState) { final SharedPreferences prefs = GeckoApp.getAppSharedPreferences(); int restoreMode = RESTORE_NONE; - boolean allowCrashRestore = true; - // If the version has changed, the user has done an upgrade, so restore - // previous tabs. final int versionCode = getVersionCode(); if (prefs.getInt(PREFS_VERSION_CODE, 0) != versionCode) { + // If the version has changed, the user has done an upgrade, so restore + // previous tabs. ThreadUtils.postToBackgroundThread(new Runnable() { @Override public void run() { @@ -1680,19 +1679,12 @@ abstract public class GeckoApp }); restoreMode = RESTORE_NORMAL; - } else if (savedInstanceState != null) { + } else if (savedInstanceState != null || PreferenceManager.getDefaultSharedPreferences(this) + .getString(GeckoPreferences.PREFS_RESTORE_SESSION, "quit") + .equals("always")) { + // We're coming back from a background kill by the OS or the user + // has chosen to always restore, so restore. restoreMode = RESTORE_NORMAL; - } else { - String restorePref = PreferenceManager.getDefaultSharedPreferences(this) - .getString(GeckoPreferences.PREFS_RESTORE_SESSION, "crash"); - if ("always".equals(restorePref)) { - restoreMode = RESTORE_NORMAL; - } else { - restoreMode = RESTORE_NONE; - if ("never".equals(restorePref)) { - allowCrashRestore = false; - } - } } // We record crashes in the crash reporter. If sessionstore.js @@ -1709,9 +1701,7 @@ abstract public class GeckoApp } }); - if (allowCrashRestore) { - restoreMode = RESTORE_CRASH; - } + restoreMode = RESTORE_CRASH; } return restoreMode; diff --git a/mobile/android/base/GeckoPreferences.java b/mobile/android/base/GeckoPreferences.java index e6c197ef666..29b928de70f 100644 --- a/mobile/android/base/GeckoPreferences.java +++ b/mobile/android/base/GeckoPreferences.java @@ -77,7 +77,7 @@ public class GeckoPreferences private static String PREFS_HEALTHREPORT_LINK = NON_PREF_PREFIX + "healthreport.link"; private static String PREFS_DEVTOOLS_REMOTE_ENABLED = "devtools.debugger.remote-enabled"; - public static String PREFS_RESTORE_SESSION = NON_PREF_PREFIX + "restoreSession2"; + public static String PREFS_RESTORE_SESSION = NON_PREF_PREFIX + "restoreSession3"; // These values are chosen to be distinct from other Activity constants. private static int REQUEST_CODE_PREF_SCREEN = 5; diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd index 0f3c23701cf..1fa58faeb41 100644 --- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -112,8 +112,7 @@ - - + diff --git a/mobile/android/base/resources/values/arrays.xml b/mobile/android/base/resources/values/arrays.xml index 3796d10bfb9..7671246e0de 100644 --- a/mobile/android/base/resources/values/arrays.xml +++ b/mobile/android/base/resources/values/arrays.xml @@ -101,13 +101,11 @@ @string/pref_restore_always - @string/pref_restore_crash - @string/pref_restore_never + @string/pref_restore_quit always - crash - never + quit @string/pref_update_autodownload_enabled diff --git a/mobile/android/base/resources/xml-v11/preferences_customize.xml b/mobile/android/base/resources/xml-v11/preferences_customize.xml index db95e75d5cb..78ab8839798 100644 --- a/mobile/android/base/resources/xml-v11/preferences_customize.xml +++ b/mobile/android/base/resources/xml-v11/preferences_customize.xml @@ -25,9 +25,9 @@ android:negativeButtonText="@string/button_cancel" android:persistent="false" /> - diff --git a/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml b/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml index 51160aefdb6..d3ccd8caae2 100644 --- a/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml +++ b/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml @@ -31,9 +31,9 @@ android:negativeButtonText="@string/button_cancel" android:persistent="false" /> - diff --git a/mobile/android/base/resources/xml/preferences_customize.xml.in b/mobile/android/base/resources/xml/preferences_customize.xml.in index cf24a78dc89..106987d9885 100644 --- a/mobile/android/base/resources/xml/preferences_customize.xml.in +++ b/mobile/android/base/resources/xml/preferences_customize.xml.in @@ -27,9 +27,9 @@ android:negativeButtonText="@string/button_cancel" android:persistent="false" /> - diff --git a/mobile/android/base/strings.xml.in b/mobile/android/base/strings.xml.in index af43eb451f2..a5c18fb43f2 100644 --- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -129,8 +129,7 @@ &pref_reflow_on_zoom4; &pref_restore; &pref_restore_always; - &pref_restore_crash; - &pref_restore_never; + &pref_restore_quit; &pref_show_product_announcements; &pref_sync; &pref_search_suggestions; From aa88201efeb770253b8d40fa3c1e8b6e3b1203e7 Mon Sep 17 00:00:00 2001 From: Margaret Leibovic Date: Fri, 23 Aug 2013 13:09:24 -0700 Subject: [PATCH 04/20] Bug 907881 - Update normal cursor position when moving beyond its bounds in TopSitesCursorWrapper. r=wesj --- mobile/android/base/db/BrowserDB.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mobile/android/base/db/BrowserDB.java b/mobile/android/base/db/BrowserDB.java index a076dc7cada..fbdc8da5884 100644 --- a/mobile/android/base/db/BrowserDB.java +++ b/mobile/android/base/db/BrowserDB.java @@ -407,11 +407,16 @@ public class BrowserDB { public boolean moveToPosition(int position) { mIndex = position; - // move the real cursor as if we were stepping through it to this position - // be careful not to move it to far, and to account for any pinned sites + // Move the real cursor as if we were stepping through it to this position. + // Account for pinned sites, and be careful to update its position to the + // minimum or maximum position, even if we're moving beyond its bounds. int before = getPinnedBefore(position); int p2 = position - before; - if (p2 >= -1 && p2 <= mCursor.getCount()) { + if (p2 <= -1) { + super.moveToPosition(-1); + } else if (p2 >= mCursor.getCount()) { + super.moveToPosition(mCursor.getCount()); + } else { super.moveToPosition(p2); } From a55554c39e146d0c98cdd6dc71e738a5c8db5261 Mon Sep 17 00:00:00 2001 From: Marina Samuel Date: Fri, 23 Aug 2013 16:47:13 -0400 Subject: [PATCH 05/20] Bug 907520 - Close soft keyboard when findbar closes. r=mbrubeck --- browser/metro/base/content/helperui/FindHelperUI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/metro/base/content/helperui/FindHelperUI.js b/browser/metro/base/content/helperui/FindHelperUI.js index a52b8eb8721..b367ebc9245 100644 --- a/browser/metro/base/content/helperui/FindHelperUI.js +++ b/browser/metro/base/content/helperui/FindHelperUI.js @@ -140,13 +140,13 @@ var FindHelperUI = { this._container.removeEventListener("transitionend", onTransitionEnd, true); this._textbox.value = ""; this.status = null; - this._textbox.blur(); this._open = false; // Restore the scroll synchronisation Browser.selectedBrowser.scrollSync = true; }; + this._textbox.blur(); this._container.addEventListener("transitionend", onTransitionEnd, true); this._container.dismiss(); Elements.browsers.removeAttribute("findbar"); From 35a55170b730fc5cc2fb6baea6355c552b5ed89c Mon Sep 17 00:00:00 2001 From: Sam Foster Date: Fri, 23 Aug 2013 13:58:55 -0700 Subject: [PATCH 06/20] Bug 848137 - Begin break out of Utils.js into a ContentUtil.jsm module. r=mbrubeck --- browser/metro/base/content/Util.js | 48 ++++--------------- .../metro/base/tests/unit/test_util_extend.js | 6 +-- browser/metro/base/tests/unit/xpcshell.ini | 3 +- browser/metro/modules/ContentUtil.jsm | 47 ++++++++++++++++++ browser/metro/modules/moz.build | 1 + 5 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 browser/metro/modules/ContentUtil.jsm diff --git a/browser/metro/base/content/Util.js b/browser/metro/base/content/Util.js index 316e5c317fd..dc7176747eb 100644 --- a/browser/metro/base/content/Util.js +++ b/browser/metro/base/content/Util.js @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +Components.utils.import("resource:///modules/ContentUtil.jsm"); + let Util = { /* * General purpose utilities @@ -37,44 +39,6 @@ let Util = { Services.io.offline = false; }, - // Pass several objects in and it will combine them all into the first object and return it. - // NOTE: Deep copy is not supported - extend: function extend() { - // copy reference to target object - let target = arguments[0] || {}; - let length = arguments.length; - - if (length === 1) { - return target; - } - - // Handle case when target is a string or something - if (typeof target != "object" && typeof target != "function") { - target = {}; - } - - for (let i = 1; i < length; i++) { - // Only deal with non-null/undefined values - let options = arguments[i]; - if (options != null) { - // Extend the base object - for (let name in options) { - let copy = options[name]; - - // Prevent never-ending loop - if (target === copy) - continue; - - if (copy !== undefined) - target[name] = copy; - } - } - } - - // Return the modified object - return target; - }, - /* * Timing utilties */ @@ -540,3 +504,11 @@ Util.Timeout.prototype = { } }; +// Mixin the ContentUtil module exports +{ + for (let name in ContentUtil) { + let copy = ContentUtil[name]; + if (copy !== undefined) + Util[name] = copy; + } +} diff --git a/browser/metro/base/tests/unit/test_util_extend.js b/browser/metro/base/tests/unit/test_util_extend.js index 2d32c976080..a22ca7adbc5 100644 --- a/browser/metro/base/tests/unit/test_util_extend.js +++ b/browser/metro/base/tests/unit/test_util_extend.js @@ -1,10 +1,10 @@ "use strict"; -load('Util.js'); +load("Util.js"); function run_test() { do_print("Testing Util.extend"); - + do_print("Check if function is defined"); do_check_true(!!Util.extend); @@ -14,7 +14,7 @@ function run_test() { let nullRes = Util.extend(null); do_check_true(nullRes && typeof nullRes == "object"); - + do_print("Simple extend"); let simpleExtend = {a: 1, b: 2}; let simpleExtendResult = Util.extend(simpleExtend, {b: 3, c: 4}); diff --git a/browser/metro/base/tests/unit/xpcshell.ini b/browser/metro/base/tests/unit/xpcshell.ini index 8d01cd7508f..8cc41da1188 100644 --- a/browser/metro/base/tests/unit/xpcshell.ini +++ b/browser/metro/base/tests/unit/xpcshell.ini @@ -1,5 +1,6 @@ [DEFAULT] -head = +head = tail = +firefox-appdir = metro [test_util_extend.js] diff --git a/browser/metro/modules/ContentUtil.jsm b/browser/metro/modules/ContentUtil.jsm new file mode 100644 index 00000000000..2b80a571f91 --- /dev/null +++ b/browser/metro/modules/ContentUtil.jsm @@ -0,0 +1,47 @@ +/* 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 = ["ContentUtil"]; + +this.ContentUtil = { + // Pass several objects in and it will combine them all into the first object and return it. + // NOTE: Deep copy is not supported + extend: function extend() { + // copy reference to target object + let target = arguments[0] || {}; + let length = arguments.length; + + if (length === 1) { + return target; + } + + // Handle case when target is a string or something + if (typeof target != "object" && typeof target != "function") { + target = {}; + } + + for (let i = 1; i < length; i++) { + // Only deal with non-null/undefined values + let options = arguments[i]; + if (options != null) { + // Extend the base object + for (let name in options) { + let copy = options[name]; + + // Prevent never-ending loop + if (target === copy) + continue; + + if (copy !== undefined) + target[name] = copy; + } + } + } + + // Return the modified object + return target; + } + +}; diff --git a/browser/metro/modules/moz.build b/browser/metro/modules/moz.build index 835b2bd21f7..69f8f89b080 100644 --- a/browser/metro/modules/moz.build +++ b/browser/metro/modules/moz.build @@ -5,6 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXTRA_JS_MODULES += [ + 'ContentUtil.jsm', 'CrossSlide.jsm', 'View.jsm', 'colorUtils.jsm', From 9f1d577145c5a98e7e2285038de2ea75aaaf8a76 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 23 Aug 2013 14:18:08 -0700 Subject: [PATCH 07/20] Bug 908870 - disable logging RDP packets in mochitests by default again; r=me --- browser/devtools/debugger/test/head.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/devtools/debugger/test/head.js b/browser/devtools/debugger/test/head.js index d5c96918438..0ad25164961 100644 --- a/browser/devtools/debugger/test/head.js +++ b/browser/devtools/debugger/test/head.js @@ -12,7 +12,7 @@ let Services = tempScope.Services; // Disable logging for faster test runs. Set this pref to true if you want to // debug a test in your try runs. let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log"); -Services.prefs.setBoolPref("devtools.debugger.log", true); +Services.prefs.setBoolPref("devtools.debugger.log", false); Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope); Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope); From 9ceb6edb29b876ad2f89d27ca1980e765fe290c4 Mon Sep 17 00:00:00 2001 From: Brian Nicholson Date: Fri, 23 Aug 2013 14:40:35 -0700 Subject: [PATCH 08/20] Bug 904741 - Follow-up to update tests. r=me --- mobile/android/base/tests/testSettingsMenuItems.java.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/android/base/tests/testSettingsMenuItems.java.in b/mobile/android/base/tests/testSettingsMenuItems.java.in index c80a6ab321a..8b248915853 100644 --- a/mobile/android/base/tests/testSettingsMenuItems.java.in +++ b/mobile/android/base/tests/testSettingsMenuItems.java.in @@ -26,7 +26,7 @@ public class testSettingsMenuItems extends PixelTest { String[][] OPTIONS_CUSTOMIZE = { { "Search settings", "", "Show search suggestions", "Installed search engines" }, { "Import from Android", "", "Bookmarks", "History", "Import" }, - { "Tabs", "Restore after a crash", "Always restore", "Restore after a crash", "Never restore" }, + { "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME }, { "Automatic updates", "Only over Wi-Fi", "Enabled", "Only over Wi-Fi", "Disabled" }, }; From fb564e9cd4023fd424fbffa42e90ef28d07a2dc2 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 23 Aug 2013 15:04:03 -0700 Subject: [PATCH 09/20] Bug 882795 - source responses in the RDP should include a contentType property; r=vporof --- toolkit/devtools/client/dbg-client.jsm | 6 ++- toolkit/devtools/server/actors/script.js | 40 +++++++++++-------- .../server/tests/unit/test_source-01.js | 7 +--- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/toolkit/devtools/client/dbg-client.jsm b/toolkit/devtools/client/dbg-client.jsm index 40b4424c9bb..109e9c7126d 100644 --- a/toolkit/devtools/client/dbg-client.jsm +++ b/toolkit/devtools/client/dbg-client.jsm @@ -1993,8 +1993,9 @@ SourceClient.prototype = { return; } + let { contentType, source } = aResponse; let longString = this._client.activeThread.threadLongString( - aResponse.source); + source); longString.substring(0, longString.length, function (aResponse) { if (aResponse.error) { aCallback(aResponse); @@ -2002,7 +2003,8 @@ SourceClient.prototype = { } aCallback({ - source: aResponse.substring + source: aResponse.substring, + contentType: contentType }); }); }.bind(this)); diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index bdb3d083bf8..e6e1317beb6 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -704,7 +704,7 @@ ThreadActor.prototype = { }; }) .then(packet => { - this.conn.send(packet) + this.conn.send(packet); }); }); @@ -1029,7 +1029,7 @@ ThreadActor.prototype = { if (this.state !== "paused") { return { error: "wrongState", message: "Debuggee must be paused to evaluate code." }; - }; + } let frame = this._requestFrame(aRequest.frame); if (!frame) { @@ -1040,7 +1040,7 @@ ThreadActor.prototype = { if (!frame.environment) { return { error: "notDebuggee", message: "cannot access the environment of this frame." }; - }; + } // We'll clobber the youngest frame if the eval causes a pause, so // save our frame now to be restored after eval returns. @@ -1505,7 +1505,7 @@ ThreadActor.prototype = { return { error: "notImplemented", message: "eventListeners request is only supported in content debugging" - } + }; } let els = Cc["@mozilla.org/eventlistenerservice;1"] @@ -2248,21 +2248,21 @@ SourceActor.prototype = { // source because we can't guarantee that the cache has the most up to date // content for this source like we can if it isn't source mapped. return fetch(this._url, { loadFromCache: !this._sourceMap }) - .then((aSource) => { - return this.threadActor.createValueGrip( - aSource, this.threadActor.threadLifetimePool); - }) - .then((aSourceGrip) => { + .then(({ content, contentType }) => { return { from: this.actorID, - source: aSourceGrip + source: this.threadActor.createValueGrip( + content, this.threadActor.threadLifetimePool), + contentType: contentType }; - }, (aError) => { + }) + .then(null, (aError) => { reportError(aError, "Got an exception during SA_onSource: "); return { "from": this.actorID, "error": "loadSourceError", - "message": "Could not load the source for " + this._url + "." + "message": "Could not load the source for " + this._url + ".\n" + + safeErrorString(aError) }; }); }, @@ -3483,8 +3483,8 @@ ThreadSources.prototype = { return this._sourceMaps[aAbsSourceMapURL]; } - let promise = fetch(aAbsSourceMapURL).then(rawSourceMap => { - let map = new SourceMapConsumer(rawSourceMap); + let promise = fetch(aAbsSourceMapURL).then(({ content }) => { + let map = new SourceMapConsumer(content); this._setSourceMapRoot(map, aAbsSourceMapURL, aScriptURL); return map; }); @@ -3698,6 +3698,7 @@ function fetch(aURL, aOptions={ loadFromCache: true }) { let scheme; let url = aURL.split(" -> ").pop(); let charset; + let contentType; try { scheme = Services.io.extractScheme(url); @@ -3714,13 +3715,14 @@ function fetch(aURL, aOptions={ loadFromCache: true }) { case "chrome": case "resource": try { - NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) { + NetUtil.asyncFetch(url, function onFetch(aStream, aStatus, aRequest) { if (!Components.isSuccessCode(aStatus)) { deferred.reject(new Error("Request failed: " + url)); return; } let source = NetUtil.readInputStreamToString(aStream, aStream.available()); + contentType = aRequest.contentType; deferred.resolve(source); aStream.close(); }); @@ -3756,6 +3758,7 @@ function fetch(aURL, aOptions={ loadFromCache: true }) { } charset = channel.contentCharset; + contentType = channel.contentType; deferred.resolve(chunks.join("")); } }; @@ -3767,8 +3770,11 @@ function fetch(aURL, aOptions={ loadFromCache: true }) { break; } - return deferred.promise.then(function (source) { - return convertToUnicode(source, charset); + return deferred.promise.then(source => { + return { + content: convertToUnicode(source, charset), + contentType: contentType + }; }); } diff --git a/toolkit/devtools/server/tests/unit/test_source-01.js b/toolkit/devtools/server/tests/unit/test_source-01.js index a69c9d93752..fdd4f69800f 100644 --- a/toolkit/devtools/server/tests/unit/test_source-01.js +++ b/toolkit/devtools/server/tests/unit/test_source-01.js @@ -22,17 +22,12 @@ function run_test() gClient.connect(function() { attachTestTabAndResume(gClient, "test-grips", function(aResponse, aTabClient, aThreadClient) { gThreadClient = aThreadClient; - gThreadClient.addListener("unsolicitedPause", unsolicitedPauseListener); test_source(); }); }); do_test_pending(); } -function unsolicitedPauseListener(aEvent, aPacket, aContinue) { - gContinue = aContinue; -} - function test_source() { DebuggerServer.LONG_STRING_LENGTH = 200; @@ -43,7 +38,6 @@ function test_source() do_check_true(!!aResponse.sources); gClient.compat.supportsFeature("sources").then(function (supported) { do_check_true(supported); - }); let source = aResponse.sources.filter(function (s) { @@ -57,6 +51,7 @@ function test_source() do_check_true(!!aResponse); do_check_true(!aResponse.error); do_check_true(!!aResponse.source); + do_check_true(aResponse.contentType.contains("javascript")); do_check_eq(readFile("test_source-01.js"), aResponse.source); From d06e2cf8e8e6fbe2d377a57a0f91f5302cd89e15 Mon Sep 17 00:00:00 2001 From: Sam Foster Date: Fri, 23 Aug 2013 16:29:51 -0700 Subject: [PATCH 10/20] Bug 893091 - New populateFragmentFromString+tests, format the save-or-run download notification bar text. r=mbrubeck --- browser/metro/base/tests/unit/blank.xhtml | 5 ++ .../test_util_populateFragmentFromString.js | 90 +++++++++++++++++++ browser/metro/base/tests/unit/xpcshell.ini | 2 + browser/metro/components/HelperAppDialog.js | 31 +++++-- browser/metro/modules/ContentUtil.jsm | 45 ++++++++++ browser/metro/theme/browser.css | 11 ++- 6 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 browser/metro/base/tests/unit/blank.xhtml create mode 100644 browser/metro/base/tests/unit/test_util_populateFragmentFromString.js diff --git a/browser/metro/base/tests/unit/blank.xhtml b/browser/metro/base/tests/unit/blank.xhtml new file mode 100644 index 00000000000..af669a741ee --- /dev/null +++ b/browser/metro/base/tests/unit/blank.xhtml @@ -0,0 +1,5 @@ + + + + + diff --git a/browser/metro/base/tests/unit/test_util_populateFragmentFromString.js b/browser/metro/base/tests/unit/test_util_populateFragmentFromString.js new file mode 100644 index 00000000000..759dc4134c3 --- /dev/null +++ b/browser/metro/base/tests/unit/test_util_populateFragmentFromString.js @@ -0,0 +1,90 @@ +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +let Cu = Components.utils; +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource:///modules/ContentUtil.jsm"); +load("Util.js"); + +function empty_node(node) { + let cnode; + while((cnode = node.firstChild)) + node.removeChild(cnode); + return node; +} + +function DOMSerializer() { + return Components.classes["@mozilla.org/xmlextras/xmlserializer;1"] + .createInstance(Components.interfaces.nsIDOMSerializer); +} + +function serializeContents(node) { + let str = DOMSerializer().serializeToString(node); + return str.replace(/^<[^>]+>/, '') + .replace(/<\/[^>]+>$/, ''); +} + +function run_test() { + let doc, body, str, expectedResult, frag; + + do_print("Testing Util.populateFragmentFromString"); + + do_check_true(!!Util.populateFragmentFromString); + do_check_true(!!ContentUtil.populateFragmentFromString); + do_check_eq(ContentUtil.populateFragmentFromString, Util.populateFragmentFromString); + + do_print("Loading blank document"); + doc = do_parse_document("blank.xhtml", "application/xhtml+xml"); + + // sanity check + do_check_eq(doc.nodeType, 9); + do_check_true(doc.documentElement.localName != "parsererror"); + + body = doc.documentElement.getElementsByTagName("body")[0]; + do_check_eq(1, body.nodeType); + + frag = doc.createDocumentFragment(); + + // test proper handling of leading and trailing text + str = "Before, #2, #1. After"; + Util.populateFragmentFromString( + frag, str, + { text: "One", className: "text-one"}, + { text: "Two", className: "text-two"} + ); + + empty_node(body); + body.appendChild(frag); + + expectedResult = 'Before, Two, One. After'; + do_check_eq(serializeContents(body), expectedResult); + + // test proper handling of unspecified markers + str = "#8080: #1. http://localhost/#bar"; + Util.populateFragmentFromString( + frag, str, + { text: "One" } + ); + + empty_node(body); + body.appendChild(frag); + + expectedResult = '#8080: One. http://localhost/#bar'; + do_check_eq(serializeContents(body), expectedResult); + + // test proper handling of markup in strings + str = "#1 tag. © 2000 - Some Corp\u2122"; + Util.populateFragmentFromString( + frag, str, + { text: "About the" } + ); + + empty_node(body); + body.appendChild(frag); + expectedResult = "About the <body> tag. &copy; 2000 - Some Corp™" + do_check_eq(serializeContents(body), expectedResult); +} \ No newline at end of file diff --git a/browser/metro/base/tests/unit/xpcshell.ini b/browser/metro/base/tests/unit/xpcshell.ini index 8cc41da1188..9b18598e54d 100644 --- a/browser/metro/base/tests/unit/xpcshell.ini +++ b/browser/metro/base/tests/unit/xpcshell.ini @@ -4,3 +4,5 @@ tail = firefox-appdir = metro [test_util_extend.js] +[test_util_populateFragmentFromString.js] + diff --git a/browser/metro/components/HelperAppDialog.js b/browser/metro/components/HelperAppDialog.js index 38552f8f5c9..177e52ac69b 100644 --- a/browser/metro/components/HelperAppDialog.js +++ b/browser/metro/components/HelperAppDialog.js @@ -14,6 +14,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DownloadUtils.jsm"); +XPCOMUtils.defineLazyGetter(this, "ContentUtil", function() { + Cu.import("resource:///modules/ContentUtil.jsm"); + return ContentUtil; +}); + // ----------------------------------------------------------------------- // HelperApp Launcher Dialog // ----------------------------------------------------------------------- @@ -97,19 +102,35 @@ HelperAppLauncherDialog.prototype = { let window = Services.wm.getMostRecentWindow("navigator:browser"); let chromeWin = this._getChromeWindow(window).wrappedJSObject; let notificationBox = chromeWin.Browser.getNotificationBox(); + let document = notificationBox.ownerDocument; downloadSize = this._getDownloadSize(aLauncher.contentLength); - let msg = browserBundle.GetStringFromName("alertDownloadSave") - .replace("#1", aLauncher.suggestedFileName) - .replace("#2", downloadSize) - .replace("#3", aLauncher.source.host); + let msg = browserBundle.GetStringFromName("alertDownloadSave"); + let fragment = ContentUtil.populateFragmentFromString( + document.createDocumentFragment(), + msg, + { + text: aLauncher.suggestedFileName, + className: "download-filename-text" + }, + { + text: aLauncher.suggestedFileName, + className: "download-size-text" + }, + { + text: aLauncher.source.host, + className: "download-host-text" + } + ); notificationBox.notificationsHidden = false; - let newBar = notificationBox.appendNotification(msg, + let newBar = notificationBox.appendNotification("", "save-download", URI_GENERIC_ICON_DOWNLOAD, notificationBox.PRIORITY_WARNING_HIGH, buttons); + let messageContainer = document.getAnonymousElementByAttribute(newBar, "anonid", "messageText"); + messageContainer.appendChild(fragment); }, promptForSaveToFile: function hald_promptForSaveToFile(aLauncher, aContext, aDefaultFile, aSuggestedFileExt, aForcePrompt) { diff --git a/browser/metro/modules/ContentUtil.jsm b/browser/metro/modules/ContentUtil.jsm index 2b80a571f91..f62b33afd97 100644 --- a/browser/metro/modules/ContentUtil.jsm +++ b/browser/metro/modules/ContentUtil.jsm @@ -5,7 +5,52 @@ this.EXPORTED_SYMBOLS = ["ContentUtil"]; +const XHTML_NS = "http://www.w3.org/1999/xhtml"; + this.ContentUtil = { + populateFragmentFromString: function populateFragmentFromString(fragment, str) { + let re = /^([^#]*)#(\d+)\b([^#]*)/, + document = fragment.ownerDocument, + // the remaining arguments are our {text, className} values + replacements = Array.slice(arguments, 2), + match; + + // walk over the string, building textNode/spans as nec. with replacement content + // note that #1,#2 etc. may not appear in numerical order in the string + while ((match = re.exec(str))) { + let [mstring,pre,num,post] = match, + replaceText = "", + replaceClass, + idx = num-1; // markers are 1-based, replacement indices 0 based + + str = str.substring(re.lastIndex+mstring.length); + + if (pre) + fragment.appendChild(document.createTextNode(pre)); + + if (replacements[idx]) { + replaceText = replacements[idx].text; + let spanNode = document.createElementNS(XHTML_NS, "span"); + spanNode.appendChild(document.createTextNode(replaceText)); + // add class to the span when provided + if(replacements[idx].className) + spanNode.classList.add(replacements[idx].className); + + fragment.appendChild(spanNode); + } else { + // put it back if no replacement was provided + fragment.appendChild(document.createTextNode("#"+num)); + } + + if(post) + fragment.appendChild(document.createTextNode(post)); + } + if(str) + fragment.appendChild(document.createTextNode(str)); + + return fragment; + }, + // Pass several objects in and it will combine them all into the first object and return it. // NOTE: Deep copy is not supported extend: function extend() { diff --git a/browser/metro/theme/browser.css b/browser/metro/theme/browser.css index eb8e6936352..aec13e2905d 100644 --- a/browser/metro/theme/browser.css +++ b/browser/metro/theme/browser.css @@ -696,7 +696,7 @@ documenttab[selected] .documenttab-selection { } /* navbar edit button: one button out of three - when editing: go, when !editing, - loading: stop, when !editing, !loading: reload */ + loading: stop, when !editing, !loading: reload */ #go-button, #reload-button, #stop-button { visibility: collapse; @@ -1006,6 +1006,15 @@ documenttab[selected] .documenttab-selection { -moz-image-region: rect(80px, 560px, 120px, 520px) !important; } +/* Download notifications ======================================================= */ + +.download-filename-text { + font-weight: bold; +} +.download-host-text { + font-weight: bold; +} + /* Autoscroll popup ======================================================== */ .autoscroller { From 3c9ea1637d327892a1335fa7c183a3b24496cb8f Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sat, 24 Aug 2013 11:50:48 +1200 Subject: [PATCH 11/20] Bug 905136 - Blackbox icons missing from debugger (Linux); r=msucan --- browser/themes/linux/devtools/debugger.css | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/browser/themes/linux/devtools/debugger.css b/browser/themes/linux/devtools/debugger.css index b6c0e727aef..3f72806688f 100644 --- a/browser/themes/linux/devtools/debugger.css +++ b/browser/themes/linux/devtools/debugger.css @@ -37,7 +37,11 @@ transition: opacity .15s ease 0s; } -.side-menu-widget-item-checkbox > .checkbox-check { +.side-menu-widget-item-checkbox > .checkbox-spacer-box { + -moz-appearance: none; +} + +.side-menu-widget-item-checkbox > .checkbox-spacer-box > .checkbox-check { -moz-appearance: none; background: none; background-image: url(itemToggle.png); @@ -50,7 +54,7 @@ border: 0; } -.side-menu-widget-item-checkbox[checked] > .checkbox-check { +.side-menu-widget-item-checkbox[checked] > .checkbox-spacer-box > .checkbox-check { background-position: 0 0; } From 55c548ae2a8ffc3929fe7dd92b5399fc93a93315 Mon Sep 17 00:00:00 2001 From: Wes Johnston Date: Fri, 23 Aug 2013 17:06:59 -0700 Subject: [PATCH 12/20] Bug 885717 - Use a property animator for button toast. r=lucasr --- mobile/android/base/widget/ButtonToast.java | 25 ++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/mobile/android/base/widget/ButtonToast.java b/mobile/android/base/widget/ButtonToast.java index 1b9df9fe8c7..7c747e87cfd 100644 --- a/mobile/android/base/widget/ButtonToast.java +++ b/mobile/android/base/widget/ButtonToast.java @@ -31,6 +31,7 @@ import android.widget.TextView; import java.util.LinkedList; +import org.mozilla.gecko.animation.PropertyAnimator; import org.mozilla.gecko.R; import org.mozilla.gecko.gfx.BitmapUtils; @@ -123,11 +124,9 @@ public class ButtonToast { mView.setVisibility(View.VISIBLE); int duration = immediate ? 0 : mView.getResources().getInteger(android.R.integer.config_longAnimTime); - mView.clearAnimation(); - AlphaAnimation alpha = new AlphaAnimation(0.0f, 1.0f); - alpha.setDuration(duration); - alpha.setFillAfter(true); - mView.startAnimation(alpha); + PropertyAnimator animator = new PropertyAnimator(duration); + animator.attach(mView, PropertyAnimator.Property.ALPHA, 1.0f); + animator.start(); } public void hide(boolean immediate, ReasonHidden reason) { @@ -149,20 +148,20 @@ public class ButtonToast { mView.setVisibility(View.GONE); showNextInQueue(); } else { - AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); - alpha.setDuration(duration); - alpha.setFillAfter(true); - alpha.setAnimationListener(new Animation.AnimationListener () { + // Using Android's animation frameworks will not correctly turn off clicking. + // See bug 885717. + PropertyAnimator animator = new PropertyAnimator(duration); + animator.attach(mView, PropertyAnimator.Property.ALPHA, 0.0f); + animator.setPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener () { // If we are showing a toast and go in the background // onAnimationEnd will be called when the app is restored - public void onAnimationEnd(Animation animation) { + public void onPropertyAnimationEnd() { mView.setVisibility(View.GONE); showNextInQueue(); } - public void onAnimationRepeat(Animation animation) { } - public void onAnimationStart(Animation animation) { } + public void onPropertyAnimationStart() { } }); - mView.startAnimation(alpha); + animator.start(); } } From d217407be8359f538088393f7b3e3688a63b38b3 Mon Sep 17 00:00:00 2001 From: Shilpan Bhagat Date: Fri, 23 Aug 2013 16:28:00 -0700 Subject: [PATCH 13/20] Bug 899376: PageActions for helper apps. r=wesj --- mobile/android/base/Makefile.in | 3 ++ .../drawable-hdpi/icon_openinapp.png | Bin 0 -> 340 bytes .../drawable-mdpi/icon_openinapp.png | Bin 0 -> 249 bytes .../drawable-xhdpi/icon_openinapp.png | Bin 0 -> 454 bytes mobile/android/chrome/content/HelperApps.js | 48 ++++++++++++++++++ mobile/android/chrome/content/browser.js | 3 ++ .../locales/en-US/chrome/browser.properties | 3 ++ 7 files changed, 57 insertions(+) create mode 100644 mobile/android/base/resources/drawable-hdpi/icon_openinapp.png create mode 100644 mobile/android/base/resources/drawable-mdpi/icon_openinapp.png create mode 100644 mobile/android/base/resources/drawable-xhdpi/icon_openinapp.png diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index a7b3f2e3aec..7766c6fd9d8 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -668,6 +668,7 @@ RES_DRAWABLE_MDPI = \ res/drawable-mdpi/icon_most_recent_empty.png \ res/drawable-mdpi/icon_most_visited.png \ res/drawable-mdpi/icon_most_visited_empty.png \ + res/drawable-mdpi/icon_openinapp.png \ res/drawable-mdpi/icon_pageaction.png \ res/drawable-mdpi/icon_reading_list_empty.png \ res/drawable-mdpi/progress_spinner.png \ @@ -780,6 +781,7 @@ RES_DRAWABLE_HDPI = \ res/drawable-hdpi/icon_most_recent_empty.png \ res/drawable-hdpi/icon_most_visited.png \ res/drawable-hdpi/icon_most_visited_empty.png \ + res/drawable-hdpi/icon_openinapp.png \ res/drawable-hdpi/icon_pageaction.png \ res/drawable-hdpi/icon_reading_list_empty.png \ res/drawable-hdpi/tab_indicator_divider.9.png \ @@ -878,6 +880,7 @@ RES_DRAWABLE_XHDPI = \ res/drawable-xhdpi/icon_most_recent_empty.png \ res/drawable-xhdpi/icon_most_visited.png \ res/drawable-xhdpi/icon_most_visited_empty.png \ + res/drawable-xhdpi/icon_openinapp.png \ res/drawable-xhdpi/icon_pageaction.png \ res/drawable-xhdpi/icon_reading_list_empty.png \ res/drawable-xhdpi/spinner_default.9.png \ diff --git a/mobile/android/base/resources/drawable-hdpi/icon_openinapp.png b/mobile/android/base/resources/drawable-hdpi/icon_openinapp.png new file mode 100644 index 0000000000000000000000000000000000000000..6884b6fb04d041398ae9077c822ab2408d69f080 GIT binary patch literal 340 zcmV-a0jvIrP)KMR#k0QkyQ5#a0G(I5HN_EA~^ttBcQke6xCqJ1_B{C1c8tmT2Wci)HMi7 z|9oP^WX0R;HWS2F{LITsz9&XZBRanjM4OFW;kzvIkrkf8~DU6 zqN?EzzR~w)3AVB4?6_Iv>_gbC9CpqjT;Lf?DCZZiIK>-Ah}Q`>aR!xijYidQiU+8o zd!%K<2|l1Ty(2+!7%}c3XNC^im>7`>+HQ9SIT>OUhEE{R(0eFPM)=V?dFDsdv!>v5wva`Yvq(mcO4x8?@+%%Vao;c^wqJ(0?t+z?3Ce wv%;9=eb5CLu1QDjBYZ#PaL5%o?mpF|@0y+>`E(ms2GB1Ip00i_>zopr09s64M*si- literal 0 HcmV?d00001 diff --git a/mobile/android/base/resources/drawable-xhdpi/icon_openinapp.png b/mobile/android/base/resources/drawable-xhdpi/icon_openinapp.png new file mode 100644 index 0000000000000000000000000000000000000000..c2dec739ef722c50483b7ab40b49865136686dca GIT binary patch literal 454 zcmV;%0XhDOP)E>Fabk@5X!i= znAr~W;|GF0O@X%%6#EYZG7x;i-)CG5(iYPdIE^<5t~zEjSj8sNZAq-a*Rkut69hLf z^aKJ)2%6YH29Ib#EHOg?#|U8`f;#4P2aX{R=}`;65FEkK890R#G$0yWU{Y7$9EuRl z3JCTaxPUTbKwh!fYhVD+kO3 0) + this._setPageActionFor(uri, apps); + else + this._removePageAction(); + }, + + _setPageActionFor: function setPageActionFor(uri, apps) { + this._pageActionUri = uri; + + // If the pageaction is already added, simply update the URI to be launched when 'onclick' is triggered. + if (this._pageActionId != undefined) + return; + + this._pageActionId = NativeWindow.pageactions.add({ + title: Strings.browser.GetStringFromName("openInApp.pageAction"), + icon: "drawable://icon_openinapp", + clickCallback: function() { + if (apps.length == 1) + this._launchApp(apps[0], this._pageActionUri); + else + this.openUriInApp(this._pageActionUri); + }.bind(this) + }); + }, + + _removePageAction: function removePageAction() { + if(!this._pageActionId) + return; + + NativeWindow.pageactions.remove(this._pageActionId); + delete this._pageActionId; + }, + + _launchApp: function launchApp(appData, uri) { + let mimeType = ContentAreaUtils.getMIMETypeForURI(uri) || ""; + let msg = { + type: "Intent:Open", + mime: mimeType, + action: "android.intent.action.VIEW", + url: uri.spec, + packageName: appData.packageName, + className: appData.activityName + }; + sendMessageToJava(msg); + }, + openUriInApp: function openUriInApp(uri) { let mimeType = ContentAreaUtils.getMIMETypeForURI(uri) || ""; let msg = { diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 78b0ca834e5..a91ccbd05ff 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -3540,6 +3540,9 @@ Tab.prototype = { this._linkifier.linkifyNumbers(this.browser.contentWindow.document); } + // Show page actions for helper apps. + HelperApps.updatePageAction(this.browser.currentURI); + if (!Reader.isEnabledForParseOnLoad) return; diff --git a/mobile/android/locales/en-US/chrome/browser.properties b/mobile/android/locales/en-US/chrome/browser.properties index 0101ccdf999..7b12179145f 100644 --- a/mobile/android/locales/en-US/chrome/browser.properties +++ b/mobile/android/locales/en-US/chrome/browser.properties @@ -288,3 +288,6 @@ getUserMedia.sharingCameraAndMicrophone.message2 = Camera and microphone are on #Reader mode readerMode.enter = Enter Reader Mode readerMode.exit = Exit Reader Mode + +#Open in App +openInApp.pageAction = Open in App From c2e27d0bc0f8431c96fc5cdff5e2cd9bf12eeeb5 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Fri, 23 Aug 2013 17:10:29 -0700 Subject: [PATCH 14/20] Bug 906047 - Remove unused code from metro/base/content/Util.js [r=sfoster] --HG-- extra : rebase_source : 76af61778df8adf89b63006e7331ed69e1c7b32c --- browser/metro/base/content/Util.js | 141 ----------------------- browser/metro/base/content/browser-ui.js | 8 -- browser/metro/base/content/browser.xul | 6 - 3 files changed, 155 deletions(-) diff --git a/browser/metro/base/content/Util.js b/browser/metro/base/content/Util.js index dc7176747eb..e59d22c2077 100644 --- a/browser/metro/base/content/Util.js +++ b/browser/metro/base/content/Util.js @@ -13,26 +13,6 @@ let Util = { return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); }, - // Recursively find all documents, including root document. - getAllDocuments: function getAllDocuments(doc, resultSoFar) { - resultSoFar = resultSoFar || [doc]; - if (!doc.defaultView) - return resultSoFar; - let frames = doc.defaultView.frames; - if (!frames) - return resultSoFar; - - let i; - let currentDoc; - for (i = 0; i < frames.length; i++) { - currentDoc = frames[i].document; - resultSoFar.push(currentDoc); - this.getAllDocuments(currentDoc, resultSoFar); - } - - return resultSoFar; - }, - // Put the Mozilla networking code into a state that will kick the // auto-connection process. forceOnline: function forceOnline() { @@ -56,17 +36,6 @@ let Util = { * Console printing utilities */ - dumpf: function dumpf(str) { - let args = arguments; - let i = 1; - dump(str.replace(/%s/g, function() { - if (i >= args.length) { - throw "dumps received too many placeholders and not enough arguments"; - } - return args[i++].toString(); - })); - }, - // Like dump, but each arg is handled and there's an automatic newline dumpLn: function dumpLn() { for (let i = 0; i < arguments.length; i++) @@ -74,30 +43,10 @@ let Util = { dump("\n"); }, - dumpElement: function dumpElement(aElement) { - this.dumpLn(aElement.id); - }, - - dumpElementTree: function dumpElementTree(aElement) { - let node = aElement; - while (node) { - this.dumpLn("node:", node, "id:", node.id, "class:", node.classList); - node = node.parentNode; - } - }, - /* * Element utilities */ - highlightElement: function highlightElement(aElement) { - if (aElement == null) { - this.dumpLn("aElement is null"); - return; - } - aElement.style.border = "2px solid red"; - }, - transitionElementVisibility: function(aNodes, aVisible) { // accept single node or a collection of nodes aNodes = aNodes.length ? aNodes : [aNodes]; @@ -125,24 +74,6 @@ let Util = { return defd.promise; }, - getHrefForElement: function getHrefForElement(target) { - let link = null; - while (target) { - if (target instanceof Ci.nsIDOMHTMLAnchorElement || - target instanceof Ci.nsIDOMHTMLAreaElement || - target instanceof Ci.nsIDOMHTMLLinkElement) { - if (target.hasAttribute("href")) - link = target; - } - target = target.parentNode; - } - - if (link && link.hasAttribute("href")) - return link.href; - else - return null; - }, - isTextInput: function isTextInput(aElement) { return ((aElement instanceof Ci.nsIDOMHTMLInputElement && aElement.mozIsTextField(false)) || @@ -272,16 +203,6 @@ let Util = { aURL.indexOf("chrome:") == 0); }, - isOpenableScheme: function isShareableScheme(aProtocol) { - let dontOpen = /^(mailto|javascript|news|snews)$/; - return (aProtocol && !dontOpen.test(aProtocol)); - }, - - isShareableScheme: function isShareableScheme(aProtocol) { - let dontShare = /^(chrome|about|file|javascript|resource)$/; - return (aProtocol && !dontShare.test(aProtocol)); - }, - // Don't display anything in the urlbar for these special URIs. isURLEmpty: function isURLEmpty(aURL) { return (!aURL || @@ -346,68 +267,6 @@ let Util = { return this.displayDPI = this.getWindowUtils(window).displayDPI; }, - isPortrait: function isPortrait() { - return (window.innerWidth <= window.innerHeight); - }, - - LOCALE_DIR_RTL: -1, - LOCALE_DIR_LTR: 1, - get localeDir() { - // determine browser dir first to know which direction to snap to - let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry); - return chromeReg.isLocaleRTL("global") ? this.LOCALE_DIR_RTL : this.LOCALE_DIR_LTR; - }, - - /* - * Process utilities - */ - - isParentProcess: function isInParentProcess() { - let appInfo = Cc["@mozilla.org/xre/app-info;1"]; - return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT); - }, - - /* - * Event utilities - */ - - modifierMaskFromEvent: function modifierMaskFromEvent(aEvent) { - return (aEvent.altKey ? Ci.nsIDOMEvent.ALT_MASK : 0) | - (aEvent.ctrlKey ? Ci.nsIDOMEvent.CONTROL_MASK : 0) | - (aEvent.shiftKey ? Ci.nsIDOMEvent.SHIFT_MASK : 0) | - (aEvent.metaKey ? Ci.nsIDOMEvent.META_MASK : 0); - }, - - /* - * Download utilities - */ - - insertDownload: function insertDownload(aSrcUri, aFile) { - let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); - let db = dm.DBConnection; - - let stmt = db.createStatement( - "INSERT INTO moz_downloads (name, source, target, startTime, endTime, state, referrer) " + - "VALUES (:name, :source, :target, :startTime, :endTime, :state, :referrer)" - ); - - stmt.params.name = aFile.leafName; - stmt.params.source = aSrcUri.spec; - stmt.params.target = aFile.path; - stmt.params.startTime = Date.now() * 1000; - stmt.params.endTime = Date.now() * 1000; - stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED; - stmt.params.referrer = aSrcUri.spec; - - stmt.execute(); - stmt.finalize(); - - let newItemId = db.lastInsertRowID; - let download = dm.getDownload(newItemId); - //dm.resumeDownload(download); - //Services.obs.notifyObservers(download, "dl-start", null); - }, - /* * Local system utilities */ diff --git a/browser/metro/base/content/browser-ui.js b/browser/metro/base/content/browser-ui.js index ccafe6d67ea..cd1475a4627 100644 --- a/browser/metro/base/content/browser-ui.js +++ b/browser/metro/base/content/browser-ui.js @@ -1096,14 +1096,6 @@ var BrowserUI = { case "cmd_panel": PanelUI.toggle(); break; - case "cmd_volumeLeft": - // Zoom in (portrait) or out (landscape) - Browser.zoom(Util.isPortrait() ? -1 : 1); - break; - case "cmd_volumeRight": - // Zoom out (portrait) or in (landscape) - Browser.zoom(Util.isPortrait() ? 1 : -1); - break; case "cmd_openFile": this.openFile(); break; diff --git a/browser/metro/base/content/browser.xul b/browser/metro/base/content/browser.xul index b140d03bbf4..b3082c1ef2d 100644 --- a/browser/metro/base/content/browser.xul +++ b/browser/metro/base/content/browser.xul @@ -95,12 +95,6 @@ - - - - - - From bd8dcf3d0bd02dc8f2b5d370cfcf55953395bd9c Mon Sep 17 00:00:00 2001 From: Drew Willcoxon Date: Fri, 23 Aug 2013 17:38:21 -0700 Subject: [PATCH 15/20] Bug 908060 - Choose a better size for the background thumbnail service's browser. r=markh --- .../thumbnails/BackgroundPageThumbs.jsm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm index c00a8b2b5ff..a532cc7c3ee 100644 --- a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm +++ b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm @@ -146,17 +146,19 @@ const BackgroundPageThumbs = { browser.setAttribute("remote", "true"); browser.setAttribute("privatebrowsing", "true"); - // Size the browser. Setting the width and height attributes doesn't - // work -- the resulting thumbnails are blank and transparent -- but - // setting the style does. - let width = {}; - let height = {}; + // Size the browser. Make its aspect ratio the same as the canvases' that + // the thumbnails are drawn into; the canvases' aspect ratio is the same as + // the screen's, so use that. Aim for a size in the ballpark of 1024x768. + let [swidth, sheight] = [{}, {}]; Cc["@mozilla.org/gfx/screenmanager;1"]. getService(Ci.nsIScreenManager). primaryScreen. - GetRectDisplayPix({}, {}, width, height); - browser.style.width = width.value + "px"; - browser.style.height = height.value + "px"; + GetRectDisplayPix({}, {}, swidth, sheight); + let bwidth = Math.min(1024, swidth.value); + // Setting the width and height attributes doesn't work -- the resulting + // thumbnails are blank and transparent -- but setting the style does. + browser.style.width = bwidth + "px"; + browser.style.height = (bwidth * sheight.value / swidth.value) + "px"; this._parentWin.document.documentElement.appendChild(browser); From 767dddc75fb81f7902cb6decb241aad3f32e9eca Mon Sep 17 00:00:00 2001 From: Justin Dolske Date: Fri, 23 Aug 2013 18:30:07 -0700 Subject: [PATCH 16/20] Bug 901747 - The "slow startup" notification bar should point users to the help article on resetting Firefox. r=jaws --- browser/components/nsBrowserGlue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 2d4628dc24c..0cd1aa3ecd2 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -543,7 +543,7 @@ BrowserGlue.prototype = { label: win.gNavigatorBundle.getString("slowStartup.helpButton.label"), accessKey: win.gNavigatorBundle.getString("slowStartup.helpButton.accesskey"), callback: function () { - win.openUILinkIn("https://support.mozilla.org/kb/firefox-takes-long-time-start-up", "tab"); + win.openUILinkIn("https://support.mozilla.org/kb/reset-firefox-easily-fix-most-problems", "tab"); } }, { From 7636514fe1cbc389f43a1d3a5f58d0a0bf785f0a Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Fri, 23 Aug 2013 18:55:47 -0700 Subject: [PATCH 17/20] Back out caa126fcb928 (bug 885717) because of Android build errors --- mobile/android/base/widget/ButtonToast.java | 25 +++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/mobile/android/base/widget/ButtonToast.java b/mobile/android/base/widget/ButtonToast.java index 7c747e87cfd..1b9df9fe8c7 100644 --- a/mobile/android/base/widget/ButtonToast.java +++ b/mobile/android/base/widget/ButtonToast.java @@ -31,7 +31,6 @@ import android.widget.TextView; import java.util.LinkedList; -import org.mozilla.gecko.animation.PropertyAnimator; import org.mozilla.gecko.R; import org.mozilla.gecko.gfx.BitmapUtils; @@ -124,9 +123,11 @@ public class ButtonToast { mView.setVisibility(View.VISIBLE); int duration = immediate ? 0 : mView.getResources().getInteger(android.R.integer.config_longAnimTime); - PropertyAnimator animator = new PropertyAnimator(duration); - animator.attach(mView, PropertyAnimator.Property.ALPHA, 1.0f); - animator.start(); + mView.clearAnimation(); + AlphaAnimation alpha = new AlphaAnimation(0.0f, 1.0f); + alpha.setDuration(duration); + alpha.setFillAfter(true); + mView.startAnimation(alpha); } public void hide(boolean immediate, ReasonHidden reason) { @@ -148,20 +149,20 @@ public class ButtonToast { mView.setVisibility(View.GONE); showNextInQueue(); } else { - // Using Android's animation frameworks will not correctly turn off clicking. - // See bug 885717. - PropertyAnimator animator = new PropertyAnimator(duration); - animator.attach(mView, PropertyAnimator.Property.ALPHA, 0.0f); - animator.setPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener () { + AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); + alpha.setDuration(duration); + alpha.setFillAfter(true); + alpha.setAnimationListener(new Animation.AnimationListener () { // If we are showing a toast and go in the background // onAnimationEnd will be called when the app is restored - public void onPropertyAnimationEnd() { + public void onAnimationEnd(Animation animation) { mView.setVisibility(View.GONE); showNextInQueue(); } - public void onPropertyAnimationStart() { } + public void onAnimationRepeat(Animation animation) { } + public void onAnimationStart(Animation animation) { } }); - animator.start(); + mView.startAnimation(alpha); } } From 614090c17da397311dda88c45251389838232538 Mon Sep 17 00:00:00 2001 From: Justin Dolske Date: Fri, 23 Aug 2013 20:28:11 -0700 Subject: [PATCH 18/20] Bug 355063 - Password manager does not work on script-generated forms, should use new DOMFormHasPassword event instead. r=mattn,jwilde,margaret --- browser/base/content/content.js | 1 + .../base/content/contenthandlers/Content.js | 5 ++ mobile/android/chrome/content/browser.js | 7 ++ modules/libpref/src/init/all.js | 1 + .../passwordmgr/LoginManagerContent.jsm | 70 ++++++++++++++++++- .../components/passwordmgr/test/Makefile.in | 1 + ...est_basic_form_observer_autofillForms.html | 59 ++++++++-------- .../test/test_basic_form_pwevent.html | 61 ++++++++++++++++ .../passwordmgr/test/test_maxforms_1.html | 7 +- .../passwordmgr/test/test_maxforms_2.html | 7 +- .../passwordmgr/test/test_maxforms_3.html | 7 +- 11 files changed, 191 insertions(+), 35 deletions(-) create mode 100644 toolkit/components/passwordmgr/test/test_basic_form_pwevent.html diff --git a/browser/base/content/content.js b/browser/base/content/content.js index c75a8a40e35..824b29a2ac4 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -48,6 +48,7 @@ if (Services.prefs.getBoolPref("browser.tabs.remote")) { }); addEventListener("DOMFormHasPassword", function(event) { InsecurePasswordUtils.checkForInsecurePasswords(event.target); + LoginManagerContent.onFormPassword(event); }); addEventListener("DOMAutoComplete", function(event) { LoginManagerContent.onUsernameInput(event); diff --git a/browser/metro/base/content/contenthandlers/Content.js b/browser/metro/base/content/contenthandlers/Content.js index 0f39bee82b3..cc5051c050f 100644 --- a/browser/metro/base/content/contenthandlers/Content.js +++ b/browser/metro/base/content/contenthandlers/Content.js @@ -140,6 +140,7 @@ let Content = { addEventListener("MozApplicationManifest", this, false); addEventListener("DOMContentLoaded", this, false); addEventListener("DOMAutoComplete", this, false); + addEventListener("DOMFormHasPassword", this, false); addEventListener("blur", this, false); addEventListener("pagehide", this, false); // Attach a listener to watch for "click" events bubbling up from error @@ -189,6 +190,10 @@ let Content = { this._onClickCapture(aEvent); break; + case "DOMFormHasPassword": + LoginManagerContent.onFormPassword(aEvent); + break; + case "DOMContentLoaded": LoginManagerContent.onContentLoaded(aEvent); this._maybeNotifyErrorPage(); diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index a91ccbd05ff..b4ff4cd79a8 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -2663,6 +2663,7 @@ Tab.prototype = { this.browser.sessionHistory.addSHistoryListener(this); this.browser.addEventListener("DOMContentLoaded", this, true); + this.browser.addEventListener("DOMFormHasPassword", this, true); this.browser.addEventListener("DOMLinkAdded", this, true); this.browser.addEventListener("DOMTitleChanged", this, true); this.browser.addEventListener("DOMWindowClose", this, true); @@ -2811,6 +2812,7 @@ Tab.prototype = { this.browser.sessionHistory.removeSHistoryListener(this); this.browser.removeEventListener("DOMContentLoaded", this, true); + this.browser.removeEventListener("DOMFormHasPassword", this, true); this.browser.removeEventListener("DOMLinkAdded", this, true); this.browser.removeEventListener("DOMTitleChanged", this, true); this.browser.removeEventListener("DOMWindowClose", this, true); @@ -3368,6 +3370,11 @@ Tab.prototype = { break; } + case "DOMFormHasPassword": { + LoginManagerContent.onFormPassword(aEvent); + break; + } + case "DOMLinkAdded": { let target = aEvent.originalTarget; if (!target.href || target.disabled) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 9fdf62f3d8e..628d36c30db 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3909,6 +3909,7 @@ pref("signon.SignonFileName3", "signons3.txt"); // obsolete pref("signon.autofillForms", true); pref("signon.autologin.proxy", false); pref("signon.debug", false); +pref("signon.useDOMFormHasPassword", true); // Satchel (Form Manager) prefs pref("browser.formfill.debug", false); diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index 75f24cee19e..f22bacf9bee 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -13,7 +13,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); -var gEnabled = false, gDebug = false; // these mirror signon.* prefs +var gEnabled = false, gDebug = false, gAutofillForms = true; // these mirror signon.* prefs +var gUseDOMFormHasPassword = false; // use DOMFormHasPassword event for autofill function log(...pieces) { function generateLogMessage(args) { @@ -70,6 +71,8 @@ var observer = { onPrefChange : function() { gDebug = Services.prefs.getBoolPref("signon.debug"); gEnabled = Services.prefs.getBoolPref("signon.rememberSignons"); + gAutofillForms = Services.prefs.getBoolPref("signon.autofillForms"); + gUseDOMFormHasPassword = Services.prefs.getBoolPref("signon.useDOMFormHasPassword"); }, }; @@ -92,6 +95,10 @@ var LoginManagerContent = { }, onContentLoaded : function (event) { + // If we're using the new DOMFormHasPassword event, don't fill at pageload. + if (gUseDOMFormHasPassword) + return; + if (!event.isTrusted) return; @@ -108,6 +115,64 @@ var LoginManagerContent = { }, + onFormPassword: function (event) { + // If we're not using the new DOMFormHasPassword event, only fill at pageload. + if (!gUseDOMFormHasPassword) + return; + + if (!event.isTrusted) + return; + + if (!gEnabled) + return; + + let form = event.target; + let doc = form.ownerDocument; + + log("onFormPassword for", doc.documentURI); + + // If there are no logins for this site, bail out now. + let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI); + if (!Services.logins.countLogins(formOrigin, "", null)) + return; + + // If we're currently displaying a master password prompt, defer + // processing this form until the user handles the prompt. + if (Services.logins.uiBusy) { + log("deferring onFormPassword for", doc.documentURI); + let self = this; + let observer = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), + + observe: function (subject, topic, data) { + log("Got deferred onFormPassword notification:", topic); + // Only run observer once. + Services.obs.removeObserver(this, "passwordmgr-crypto-login"); + Services.obs.removeObserver(this, "passwordmgr-crypto-loginCanceled"); + if (topic == "passwordmgr-crypto-loginCanceled") + return; + self.onFormPassword(event); + }, + handleEvent : function (event) { + // Not expected to be called + } + }; + // Trickyness follows: We want an observer, but don't want it to + // cause leaks. So add the observer with a weak reference, and use + // a dummy event listener (a strong reference) to keep it alive + // until the form is destroyed. + Services.obs.addObserver(observer, "passwordmgr-crypto-login", true); + Services.obs.addObserver(observer, "passwordmgr-crypto-loginCanceled", true); + form.addEventListener("mozCleverClosureHack", observer); + return; + } + + let autofillForm = gAutofillForms && !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView); + + this._fillForm(form, autofillForm, false, false, null); + }, + + /* * onUsernameInput * @@ -537,8 +602,7 @@ var LoginManagerContent = { log("fillDocument processing", forms.length, "forms on", doc.documentURI); - var autofillForm = !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView) && - Services.prefs.getBoolPref("signon.autofillForms"); + var autofillForm = gAutofillForms && !PrivateBrowsingUtils.isWindowPrivate(doc.defaultView); var previousActionOrigin = null; var foundLogins = null; diff --git a/toolkit/components/passwordmgr/test/Makefile.in b/toolkit/components/passwordmgr/test/Makefile.in index 1eced10a9d6..0852f8bf88a 100644 --- a/toolkit/components/passwordmgr/test/Makefile.in +++ b/toolkit/components/passwordmgr/test/Makefile.in @@ -27,6 +27,7 @@ MOCHITEST_FILES = \ test_basic_form_observer_autocomplete.html \ test_basic_form_observer_foundLogins.html \ test_basic_form_pwonly.html \ + test_basic_form_pwevent.html \ test_bug_227640.html \ test_bug_242956.html \ test_bug_360493_1.html \ diff --git a/toolkit/components/passwordmgr/test/test_basic_form_observer_autofillForms.html b/toolkit/components/passwordmgr/test/test_basic_form_observer_autofillForms.html index 199d810671f..552b7930ecc 100644 --- a/toolkit/components/passwordmgr/test/test_basic_form_observer_autofillForms.html +++ b/toolkit/components/passwordmgr/test/test_basic_form_observer_autofillForms.html @@ -21,6 +21,36 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); // Assume that the pref starts out true, so set to false SpecialPowers.setBoolPref("signon.autofillForms", false); + +var TestObserver = { + receivedNotificationFoundForm : false, + receivedNotificationFoundLogins : false, + dataFoundForm : "", + dataFoundLogins : null, + QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), + observe : function (subject, topic, data) { + netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); + var pwmgr = Cc["@mozilla.org/login-manager;1"]. + getService(Ci.nsILoginManager); + if (topic == "passwordmgr-found-form") { + info("got passwordmgr-found-form"); + this.receivedNotificationFoundForm = true; + this.dataFoundForm = data; + // Now fill the form + pwmgr.fillForm(subject); + } else if (topic == "passwordmgr-found-logins") { + info("got passwordmgr-found-logins"); + this.receivedNotificationFoundLogins = true; + this.dataFoundLogins = subject.QueryInterface(Ci.nsIPropertyBag2); + } + } +}; + +// Add the observer +var os = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); +os.addObserver(TestObserver, "passwordmgr-found-form", false); +os.addObserver(TestObserver, "passwordmgr-found-logins", false);

@@ -42,35 +72,6 @@ SpecialPowers.setBoolPref("signon.autofillForms", false); + + + + + +Mozilla Bug 355063 +

+
+forms go here! +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/test_maxforms_1.html b/toolkit/components/passwordmgr/test/test_maxforms_1.html index d7fa80c52f0..bcc2e29660c 100644 --- a/toolkit/components/passwordmgr/test/test_maxforms_1.html +++ b/toolkit/components/passwordmgr/test/test_maxforms_1.html @@ -52,7 +52,12 @@ function startTest() { SimpleTest.finish(); } -window.onload = startTest; +if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) { + info("skipping test when signon.useDOMFormHasPassword is enabled"); + SimpleTest.finish(); +} else { + window.onload = startTest; +} diff --git a/toolkit/components/passwordmgr/test/test_maxforms_2.html b/toolkit/components/passwordmgr/test/test_maxforms_2.html index 281f12d17a1..da315c42029 100644 --- a/toolkit/components/passwordmgr/test/test_maxforms_2.html +++ b/toolkit/components/passwordmgr/test/test_maxforms_2.html @@ -52,7 +52,12 @@ function startTest() { SimpleTest.finish(); } -window.onload = startTest; +if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) { + info("skipping test when signon.useDOMFormHasPassword is enabled"); + SimpleTest.finish(); +} else { + window.onload = startTest; +} diff --git a/toolkit/components/passwordmgr/test/test_maxforms_3.html b/toolkit/components/passwordmgr/test/test_maxforms_3.html index 84fa863f42f..63d2bfedd49 100644 --- a/toolkit/components/passwordmgr/test/test_maxforms_3.html +++ b/toolkit/components/passwordmgr/test/test_maxforms_3.html @@ -52,7 +52,12 @@ function startTest() { SimpleTest.finish(); } -window.onload = startTest; +if (SpecialPowers.getBoolPref("signon.useDOMFormHasPassword")) { + info("skipping test when signon.useDOMFormHasPassword is enabled"); + SimpleTest.finish(); +} else { + window.onload = startTest; +} From 56fc803e4eba1816433ba0191414278d99017009 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Fri, 23 Aug 2013 22:41:28 -0700 Subject: [PATCH 19/20] Bug 895616 - get{Original/Generated}Location should take object/keyword arguments instead of positional arguments; r=fitzgen --- toolkit/devtools/server/actors/script.js | 131 ++++++++++++----------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index e6e1317beb6..7848c3d865e 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -692,8 +692,7 @@ ThreadActor.prototype = { } packet.why = aReason; - let { url, line, column } = packet.frame.where; - this.sources.getOriginalLocation(url, line, column).then(aOrigPosition => { + this.sources.getOriginalLocation(packet.frame.where).then(aOrigPosition => { packet.frame.where = aOrigPosition; resolve(onPacket(packet)) .then(null, error => { @@ -772,10 +771,11 @@ ThreadActor.prototype = { // Define the JS hook functions for stepping. let onEnterFrame = aFrame => { - let { url } = this.synchronize(this.sources.getOriginalLocation( - aFrame.script.url, - aFrame.script.getOffsetLine(aFrame.offset), - getOffsetColumn(aFrame.offset, aFrame.script))); + let { url } = this.synchronize(this.sources.getOriginalLocation({ + url: aFrame.script.url, + line: aFrame.script.getOffsetLine(aFrame.offset), + column: getOffsetColumn(aFrame.offset, aFrame.script) + })); return this.sources.isBlackBoxed(url) ? undefined @@ -787,10 +787,11 @@ ThreadActor.prototype = { let onPop = function TA_onPop(aCompletion) { // onPop is called with 'this' set to the current frame. - let { url } = thread.synchronize(thread.sources.getOriginalLocation( - this.script.url, - this.script.getOffsetLine(this.offset), - getOffsetColumn(this.offset, this.script))); + let { url } = thread.synchronize(thread.sources.getOriginalLocation({ + url: this.script.url, + line: this.script.getOffsetLine(this.offset), + column: getOffsetColumn(this.offset, this.script) + })); if (thread.sources.isBlackBoxed(url)) { return undefined; @@ -818,10 +819,11 @@ ThreadActor.prototype = { let onStep = function TA_onStep() { // onStep is called with 'this' set to the current frame. - let { url } = thread.synchronize(thread.sources.getOriginalLocation( - this.script.url, - this.script.getOffsetLine(this.offset), - getOffsetColumn(this.offset, this.script))); + let { url } = thread.synchronize(thread.sources.getOriginalLocation({ + url: this.script.url, + line: this.script.getOffsetLine(this.offset), + column: getOffsetColumn(this.offset, this.script) + })); if (thread.sources.isBlackBoxed(url)) { return undefined; @@ -1091,8 +1093,7 @@ ThreadActor.prototype = { form.depth = i; frames.push(form); - let { url, line, column } = form.where; - let promise = this.sources.getOriginalLocation(url, line, column) + let promise = this.sources.getOriginalLocation(form.where) .then((aOrigLocation) => { form.where = aOrigLocation; let source = this.sources.source(form.where.url); @@ -1142,9 +1143,7 @@ ThreadActor.prototype = { line: originalLine, column: originalColumn } = aRequest.location; - let locationPromise = this.sources.getGeneratedLocation(originalSource, - originalLine, - originalColumn); + let locationPromise = this.sources.getGeneratedLocation(aRequest.location); return locationPromise.then(({url, line, column}) => { if (line == null || line < 0 || @@ -1160,16 +1159,17 @@ ThreadActor.prototype = { // If the original location of our generated location is different from // the original location we attempted to set the breakpoint on, we will // need to know so that we can set actualLocation on the response. - let originalLocation = this.sources.getOriginalLocation(url, line, column); + let originalLocation = this.sources.getOriginalLocation({ + url: url, + line: line, + column: column + }); return all([response, originalLocation]) .then(([aResponse, {url, line}]) => { if (aResponse.actualLocation) { - let actualOrigLocation = this.sources.getOriginalLocation( - aResponse.actualLocation.url, - aResponse.actualLocation.line, - aResponse.actualLocation.column); - return actualOrigLocation.then(function ({ url, line, column }) { + let actualOrigLocation = this.sources.getOriginalLocation(aResponse.actualLocation); + return actualOrigLocation.then(({ url, line, column }) => { if (url !== originalSource || line !== originalLine || column !== originalColumn) { @@ -1940,10 +1940,11 @@ ThreadActor.prototype = { onDebuggerStatement: function TA_onDebuggerStatement(aFrame) { // Don't pause if we are currently stepping (in or over) or the frame is // black-boxed. - let { url } = this.synchronize(this.sources.getOriginalLocation( - aFrame.script.url, - aFrame.script.getOffsetLine(aFrame.offset), - getOffsetColumn(aFrame.offset, aFrame.script))); + let { url } = this.synchronize(this.sources.getOriginalLocation({ + url: aFrame.script.url, + line: aFrame.script.getOffsetLine(aFrame.offset), + column: getOffsetColumn(aFrame.offset, aFrame.script) + })); return this.sources.isBlackBoxed(url) || aFrame.onStep ? undefined @@ -1960,10 +1961,11 @@ ThreadActor.prototype = { * The exception that was thrown. */ onExceptionUnwind: function TA_onExceptionUnwind(aFrame, aValue) { - let { url } = this.synchronize(this.sources.getOriginalLocation( - aFrame.script.url, - aFrame.script.getOffsetLine(aFrame.offset), - getOffsetColumn(aFrame.offset, aFrame.script))); + let { url } = this.synchronize(this.sources.getOriginalLocation({ + url: aFrame.script.url, + line: aFrame.script.getOffsetLine(aFrame.offset), + column: getOffsetColumn(aFrame.offset, aFrame.script) + })); if (this.sources.isBlackBoxed(url)) { return undefined; @@ -3010,10 +3012,11 @@ BreakpointActor.prototype = { // Don't pause if we are currently stepping (in or over) or the frame is // black-boxed. let { url } = this.threadActor.synchronize( - this.threadActor.sources.getOriginalLocation( - this.location.url, - this.location.line, - this.location.column)); + this.threadActor.sources.getOriginalLocation({ + url: this.location.url, + line: this.location.line, + column: this.location.column + })); if (this.threadActor.sources.isBlackBoxed(url) || aFrame.onStep) { return undefined; @@ -3515,28 +3518,27 @@ ThreadSources.prototype = { * Returns a promise of the location in the original source if the source is * source mapped, otherwise a promise of the same location. */ - getOriginalLocation: - function TS_getOriginalLocation(aSourceUrl, aLine, aColumn) { - if (aSourceUrl in this._sourceMapsByGeneratedSource) { - return this._sourceMapsByGeneratedSource[aSourceUrl] - .then(function (aSourceMap) { - let { source, line, column } = aSourceMap.originalPositionFor({ - line: aLine, - column: aColumn - }); - return { - url: source, + getOriginalLocation: function TS_getOriginalLocation({ url, line, column }) { + if (url in this._sourceMapsByGeneratedSource) { + return this._sourceMapsByGeneratedSource[url] + .then((aSourceMap) => { + let { source: aSourceURL, line: aLine, column: aColumn } = aSourceMap.originalPositionFor({ line: line, column: column + }); + return { + url: aSourceURL, + line: aLine, + column: aColumn }; }); } // No source map return resolve({ - url: aSourceUrl, - line: aLine, - column: aColumn + url: url, + line: line, + column: column }); }, @@ -3549,29 +3551,28 @@ ThreadSources.prototype = { * the tables this function uses; thus, it won't know that S's original * source URLs map to S until P is resolved. */ - getGeneratedLocation: - function TS_getGeneratedLocation(aSourceUrl, aLine, aColumn) { - if (aSourceUrl in this._sourceMapsByOriginalSource) { - return this._sourceMapsByOriginalSource[aSourceUrl] + getGeneratedLocation: function TS_getGeneratedLocation({ url, line, column }) { + if (url in this._sourceMapsByOriginalSource) { + return this._sourceMapsByOriginalSource[url] .then((aSourceMap) => { - let { line, column } = aSourceMap.generatedPositionFor({ - source: aSourceUrl, - line: aLine, - column: aColumn == null ? Infinity : aColumn + let { line: aLine, column: aColumn } = aSourceMap.generatedPositionFor({ + source: url, + line: line, + column: column == null ? Infinity : column }); return { - url: this._generatedUrlsByOriginalUrl[aSourceUrl], - line: line, - column: column + url: this._generatedUrlsByOriginalUrl[url], + line: aLine, + column: aColumn }; }); } // No source map return resolve({ - url: aSourceUrl, - line: aLine, - column: aColumn + url: url, + line: line, + column: column }); }, From 9f0b9f359c094feba3cf34c3c536f431075a2d2b Mon Sep 17 00:00:00 2001 From: Gavin Sharp Date: Sat, 24 Aug 2013 08:09:10 -0700 Subject: [PATCH 20/20] Bug 907893: update nsIBrowserSearchService IID because we forgot to in bug 493051, r=lumpy --HG-- extra : transplant_source : %81%8F%8Dw2%BCp%E6%02B%CE6%23%F5%8Bz%A7%88%A0p --- netwerk/base/public/nsIBrowserSearchService.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/base/public/nsIBrowserSearchService.idl b/netwerk/base/public/nsIBrowserSearchService.idl index 6860e88d004..d8182fd81f8 100644 --- a/netwerk/base/public/nsIBrowserSearchService.idl +++ b/netwerk/base/public/nsIBrowserSearchService.idl @@ -184,7 +184,7 @@ interface nsIBrowserSearchInitObserver : nsISupports void onInitComplete(in nsresult aStatus); }; -[scriptable, uuid(89beea9f-61a8-45d3-818d-b259f00195fe)] +[scriptable, uuid(939d74a4-5b01-463c-80c7-4301f0c0f9ef)] interface nsIBrowserSearchService : nsISupports { /**