diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index b4cafbc34227..bb6059695ed1 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1102,6 +1102,12 @@ var gBrowserInit = { // the original tab in the other window. let tabToOpen = uriToLoad; + // If this tab was passed as a window argument, clear the + // reference to it from the arguments array. + if (window.arguments[0] == tabToOpen) { + window.arguments[0] = null; + } + // Stop the about:blank load gBrowser.stop(); // make sure it has a docshell diff --git a/browser/base/content/sanitize.js b/browser/base/content/sanitize.js index 9a5594631c6f..4d77f87404c0 100644 --- a/browser/base/content/sanitize.js +++ b/browser/base/content/sanitize.js @@ -694,20 +694,21 @@ Sanitizer.sanitize = function(aParentWindow) Sanitizer.onStartup = Task.async(function*() { // Make sure that we are triggered during shutdown, at the right time, // and only once. - let placesClient = Cc["@mozilla.org/browser/nav-history-service;1"] .getService(Ci.nsPIPlacesDatabase) - .shutdownClient - .jsclient; + let placesClient = Cc["@mozilla.org/browser/nav-history-service;1"] + .getService(Ci.nsPIPlacesDatabase) + .shutdownClient + .jsclient; let deferredSanitization = PromiseUtils.defer(); let sanitizationInProgress = false; let doSanitize = function() { - if (sanitizationInProgress) { - return deferredSanitization.promise; + if (!sanitizationInProgress) { + sanitizationInProgress = true; + Sanitizer.onShutdown().catch(er => {Promise.reject(er) /* Do not return rejected promise */;}).then(() => + deferredSanitization.resolve() + ); } - sanitizationInProgress = true; - Sanitizer.onShutdown().catch(er => {Promise.reject(er) /* Do not return rejected promise */;}).then(() => - deferredSanitization.resolve() - ); + return deferredSanitization.promise; } placesClient.addBlocker("sanitize.js: Sanitize on shutdown", doSanitize); diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index f6f191e87d03..35e87d46d0c4 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -747,6 +747,8 @@ let topLevel = aWebProgress.isTopLevel; if (topLevel) { + let isSameDocument = + !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT); // If userTypedClear > 0, the document loaded correctly and we should be // clearing the user typed value. We also need to clear the typed value // if the document failed to load, to make sure the urlbar reflects the @@ -758,14 +760,12 @@ if (this.mBrowser.userTypedClear > 0 || ((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) && aLocation.spec != "about:blank") || - aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) { + isSameDocument) { this.mBrowser.userTypedValue = null; } // If the browser was playing audio, we should remove the playing state. - if (this.mTab.hasAttribute("soundplaying") && - (!this.mBrowser.lastURI || - this.mBrowser.lastURI.spec != aLocation.spec)) { + if (this.mTab.hasAttribute("soundplaying") && !isSameDocument) { this.mTab.removeAttribute("soundplaying"); this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]); } @@ -788,9 +788,9 @@ } // Don't clear the favicon if this onLocationChange was - // triggered by a pushState or a replaceState. See bug 550565. - if (aWebProgress.isLoadingDocument && - !(aWebProgress.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE)) { + // triggered by a pushState or a replaceState (bug 550565) or + // a hash change (bug 408415). + if (aWebProgress.isLoadingDocument && !isSameDocument) { this.mBrowser.mIconURL = null; } @@ -1758,6 +1758,7 @@ var aForceNotRemote; var aNoReferrer; var aUserContextId; + var aEventDetail; if (arguments.length == 2 && typeof arguments[1] == "object" && !(arguments[1] instanceof Ci.nsIURI)) { @@ -1775,6 +1776,7 @@ aForceNotRemote = params.forceNotRemote; aNoReferrer = params.noReferrer; aUserContextId = params.userContextId; + aEventDetail = params.eventDetail; } // if we're adding tabs, we're past interrupt mode, ditch the owner @@ -1893,8 +1895,8 @@ // Dispatch a new tab notification. We do this once we're // entirely done, so that things are in a consistent state // even if the event listener opens or closes tabs. - var evt = document.createEvent("Events"); - evt.initEvent("TabOpen", true, false); + var detail = aEventDetail || {}; + var evt = new CustomEvent("TabOpen", { bubbles: true, detail }); t.dispatchEvent(evt); // If we didn't swap docShells with a preloaded browser @@ -2128,7 +2130,7 @@ var isLastTab = (this.tabs.length - this._removingTabs.length == 1); - if (!this._beginRemoveTab(aTab, false, null, true, skipPermitUnload)) + if (!this._beginRemoveTab(aTab, null, null, true, skipPermitUnload)) return; if (!aTab.pinned && !aTab.hidden && aTab._fullyOpen && byMouse) @@ -2173,7 +2175,7 @@ - + @@ -2207,7 +2209,7 @@ newTab = true; } - if (!aTab._pendingPermitUnload && !aTabWillBeMoved && !aSkipPermitUnload) { + if (!aTab._pendingPermitUnload && !aAdoptedByTab && !aSkipPermitUnload) { // We need to block while calling permitUnload() because it // processes the event queue and may lead to another removeTab() // call before permitUnload() returns. @@ -2241,11 +2243,10 @@ // Dispatch a notification. // We dispatch it before any teardown so that event listeners can // inspect the tab that's about to close. - var evt = document.createEvent("UIEvent"); - evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0); + var evt = new CustomEvent("TabClose", { bubbles: true, detail: { adoptedBy: aAdoptedByTab } }); aTab.dispatchEvent(evt); - if (!aTabWillBeMoved && !gMultiProcessBrowser) { + if (!aAdoptedByTab && !gMultiProcessBrowser) { // Prevent this tab from showing further dialogs, since we're closing it var windowUtils = browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor). getInterface(Ci.nsIDOMWindowUtils); @@ -2261,7 +2262,7 @@ filter.removeProgressListener(listener); listener.destroy(); - if (browser.registeredOpenURI && !aTabWillBeMoved) { + if (browser.registeredOpenURI && !aAdoptedByTab) { this._placesAutocomplete.unregisterOpenPage(browser.registeredOpenURI); this._unifiedComplete.unregisterOpenPage(browser.registeredOpenURI); delete browser.registeredOpenURI; @@ -2495,7 +2496,7 @@ // First, start teardown of the other browser. Make sure to not // fire the beforeunload event in the process. Close the other // window if this was its last tab. - if (!remoteBrowser._beginRemoveTab(aOtherTab, true, true)) + if (!remoteBrowser._beginRemoveTab(aOtherTab, aOurTab, true)) return; let modifiedAttrs = []; @@ -2946,7 +2947,7 @@ // Swap the dropped tab with a new one we create and then close // it in the other window (making it seem to have moved between // windows). - let newTab = this.addTab("about:blank"); + let newTab = this.addTab("about:blank", { eventDetail: { adoptedTab: aTab } }); let newBrowser = this.getBrowserForTab(newTab); let newURL = aTab.linkedBrowser.currentURI.spec; diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 68529e7173be..07820104649f 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -29,8 +29,8 @@ support-files = download_page.html dummy_page.html feed_tab.html - file_bug550565_favicon.ico - file_bug550565_popup.html + file_generic_favicon.ico + file_with_favicon.html file_bug822367_1.html file_bug822367_1.js file_bug822367_2.html @@ -165,6 +165,7 @@ skip-if = e10s # Bug 1236991 - Update or remove tests that use fillInPageTooltip [browser_bug380960.js] [browser_bug386835.js] [browser_bug406216.js] +[browser_bug408415.js] [browser_bug409481.js] [browser_bug409624.js] [browser_bug413915.js] diff --git a/browser/base/content/test/general/browser_bug408415.js b/browser/base/content/test/general/browser_bug408415.js new file mode 100644 index 000000000000..8a34374ac939 --- /dev/null +++ b/browser/base/content/test/general/browser_bug408415.js @@ -0,0 +1,21 @@ +function test() { + waitForExplicitFinish(); + + let testPath = getRootDirectory(gTestPath); + + let tab = gBrowser.addTab(testPath + "file_with_favicon.html"); + + tab.linkedBrowser.addEventListener("DOMContentLoaded", function() { + tab.linkedBrowser.removeEventListener("DOMContentLoaded", arguments.callee, true); + + let expectedIcon = testPath + "file_generic_favicon.ico"; + + is(gBrowser.getIcon(tab), expectedIcon, "Correct icon before hash change."); + tab.linkedBrowser.contentWindow.location.href += "#foo"; + is(gBrowser.getIcon(tab), expectedIcon, "Correct icon after hash change."); + + gBrowser.removeTab(tab); + + finish(); + }, true); +} diff --git a/browser/base/content/test/general/browser_bug491431.js b/browser/base/content/test/general/browser_bug491431.js index 9dd6312ae0e3..d30e2ad125c4 100644 --- a/browser/base/content/test/general/browser_bug491431.js +++ b/browser/base/content/test/general/browser_bug491431.js @@ -13,14 +13,14 @@ function test() { tabA = gBrowser.addTab(testPage); gBrowser.tabContainer.addEventListener("TabClose", function(aEvent) { gBrowser.tabContainer.removeEventListener("TabClose", arguments.callee, true); - ok(!aEvent.detail, "This was a normal tab close"); + ok(!aEvent.detail.adoptedBy, "This was a normal tab close"); // test tab close by moving tabB = gBrowser.addTab(testPage); gBrowser.tabContainer.addEventListener("TabClose", function(aEvent) { gBrowser.tabContainer.removeEventListener("TabClose", arguments.callee, true); executeSoon(function() { - ok(aEvent.detail, "This was a tab closed by moving"); + ok(aEvent.detail.adoptedBy, "This was a tab closed by moving"); // cleanup newWin.close(); diff --git a/browser/base/content/test/general/browser_bug550565.js b/browser/base/content/test/general/browser_bug550565.js index 0dfa4ed4a646..84f7b803b2b9 100644 --- a/browser/base/content/test/general/browser_bug550565.js +++ b/browser/base/content/test/general/browser_bug550565.js @@ -3,12 +3,12 @@ function test() { let testPath = getRootDirectory(gTestPath); - let tab = gBrowser.addTab(testPath + "file_bug550565_popup.html"); + let tab = gBrowser.addTab(testPath + "file_with_favicon.html"); tab.linkedBrowser.addEventListener("DOMContentLoaded", function() { tab.linkedBrowser.removeEventListener("DOMContentLoaded", arguments.callee, true); - let expectedIcon = testPath + "file_bug550565_favicon.ico"; + let expectedIcon = testPath + "file_generic_favicon.ico"; is(gBrowser.getIcon(tab), expectedIcon, "Correct icon before pushState."); tab.linkedBrowser.contentWindow.history.pushState("page2", "page2", "page2"); diff --git a/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js b/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js index ce7f683081f2..dbccc5debd8b 100644 --- a/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js +++ b/browser/base/content/test/general/browser_tab_drag_drop_perwindow.js @@ -147,3 +147,33 @@ add_task(function* test_dragging_blacklisted() { yield BrowserTestUtils.closeWindow(remoteWin1); yield BrowserTestUtils.closeWindow(remoteWin2); }); + + +/** + * Tests that tabs dragged between windows dispatch TabOpen and TabClose + * events with the appropriate adoption details. + */ +add_task(function* test_dragging_adoption_events() { + let win1 = yield BrowserTestUtils.openNewBrowserWindow(); + let win2 = yield BrowserTestUtils.openNewBrowserWindow(); + + let tab1 = yield BrowserTestUtils.openNewForegroundTab(win1.gBrowser); + let tab2 = yield BrowserTestUtils.openNewForegroundTab(win2.gBrowser); + + let awaitCloseEvent = BrowserTestUtils.waitForEvent(tab1, "TabClose"); + let awaitOpenEvent = BrowserTestUtils.waitForEvent(win2, "TabOpen"); + + let effect = ChromeUtils.synthesizeDrop(tab1, tab2, + [[{type: TAB_DROP_TYPE, data: tab1}]], + null, win1, win2); + is(effect, "move", "Tab should be moved from win1 to win2."); + + let closeEvent = yield awaitCloseEvent; + let openEvent = yield awaitOpenEvent; + + is(openEvent.detail.adoptedTab, tab1, "New tab adopted old tab"); + is(closeEvent.detail.adoptedBy, openEvent.target, "Old tab adopted by new tab"); + + yield BrowserTestUtils.closeWindow(win1); + yield BrowserTestUtils.closeWindow(win2); +}); diff --git a/browser/base/content/test/general/file_bug550565_popup.html b/browser/base/content/test/general/file_bug550565_popup.html deleted file mode 100644 index b4cddf971be9..000000000000 --- a/browser/base/content/test/general/file_bug550565_popup.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - Test file for bug 550565. - - - - - - Test file for bug 550565. - - diff --git a/browser/base/content/test/general/file_bug550565_favicon.ico b/browser/base/content/test/general/file_generic_favicon.ico similarity index 100% rename from browser/base/content/test/general/file_bug550565_favicon.ico rename to browser/base/content/test/general/file_generic_favicon.ico diff --git a/browser/base/content/test/general/file_with_favicon.html b/browser/base/content/test/general/file_with_favicon.html new file mode 100644 index 000000000000..0702b4aabaf8 --- /dev/null +++ b/browser/base/content/test/general/file_with_favicon.html @@ -0,0 +1,12 @@ + + + + Test file for bugs with favicons + + + + + + Test file for bugs with favicons + + diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index 82b4ebe0a05c..2d619afefe82 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -891,8 +891,9 @@ var SessionStoreInternal = { this.onTabAdd(win, target); break; case "TabClose": - // aEvent.detail determines if the tab was closed by moving to a different window - if (!aEvent.detail) + // `adoptedBy` will be set if the tab was closed because it is being + // moved to a new window. + if (!aEvent.detail.adoptedBy) this.onTabClose(win, target); this.onTabRemove(win, target); break; diff --git a/configure.in b/configure.in index aedfd392a0c5..4f0967538b76 100644 --- a/configure.in +++ b/configure.in @@ -3758,6 +3758,7 @@ MOZ_SCTP= MOZ_ANDROID_OMX= MOZ_MEDIA_NAVIGATOR= MOZ_OMX_PLUGIN= +MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE= MOZ_VPX_ERROR_CONCEALMENT= MOZ_WEBSPEECH=1 MOZ_WEBSPEECH_MODELS= @@ -5366,8 +5367,26 @@ if test -n "$MOZ_OMX_PLUGIN"; then dnl Only allow building OMX plugin on Gonk (B2G) or Android AC_DEFINE(MOZ_OMX_PLUGIN) else - dnl fail if we're not building on Gonk or Android - AC_MSG_ERROR([OMX media plugin can only be built on B2G or Android]) + dnl fail if we're not building on Gonk or Android + AC_MSG_ERROR([OMX media plugin can only be built on B2G or Android]) + fi +fi + +dnl ======================================================== +dnl = Enable building mobile/android with Gradle +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(gradle-mobile-android-builds, +[ --enable-gradle-mobile-android-builds Enable building mobile/android with Gradle], + MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE=1, + MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE=) + +if test -n "$MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE"; then + if test "$OS_TARGET" = "Android" -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then + dnl Only allow building mobile/android with Gradle. + AC_DEFINE(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE) + else + dnl fail if we're not building mobile/android. + AC_MSG_ERROR([Can only build mobile/android with Gradle]) fi fi @@ -8907,6 +8926,7 @@ AC_SUBST(MOZ_DIRECTSHOW) AC_SUBST(MOZ_ANDROID_OMX) AC_SUBST(MOZ_APPLEMEDIA) AC_SUBST(MOZ_OMX_PLUGIN) +AC_SUBST(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE) AC_SUBST(MOZ_VPX_ERROR_CONCEALMENT) AC_SUBST(VPX_AS) AC_SUBST_LIST(VPX_ASFLAGS) diff --git a/devtools/bootstrap.js b/devtools/bootstrap.js index 46c1fe3026de..d9b1f423355f 100644 --- a/devtools/bootstrap.js +++ b/devtools/bootstrap.js @@ -82,7 +82,7 @@ function reload(event) { devtools.reload(reloadToolbox); // Also tells gDevTools to reload its dependencies - const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); + const {gDevTools} = devtools.require("devtools/client/framework/devtools"); gDevTools.reload(); } diff --git a/devtools/client/aboutdebugging/components/target.js b/devtools/client/aboutdebugging/components/target.js index c88986e268fc..44e3bf2cb0ac 100644 --- a/devtools/client/aboutdebugging/components/target.js +++ b/devtools/client/aboutdebugging/components/target.js @@ -17,8 +17,8 @@ loader.lazyRequireGetter(this, "Services"); loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm"); -loader.lazyImporter(this, "gDevTools", - "resource://devtools/client/framework/gDevTools.jsm"); +loader.lazyRequireGetter(this, "gDevTools", + "devtools/client/framework/devtools", true); const Strings = Services.strings.createBundle( "chrome://devtools/locale/aboutdebugging.properties"); diff --git a/devtools/client/animationinspector/components/animation-time-block.js b/devtools/client/animationinspector/components/animation-time-block.js index 8c12b6389e66..e05f6cd21ba0 100644 --- a/devtools/client/animationinspector/components/animation-time-block.js +++ b/devtools/client/animationinspector/components/animation-time-block.js @@ -148,13 +148,24 @@ AnimationTimeBlock.prototype = { /** * Get a formatted title for this animation. This will be either: - * "some-name", "some-name : CSS Transition", or "some-name : CSS Animation", - * depending if the server provides the type, and what type it is. + * "some-name", "some-name : CSS Transition", "some-name : CSS Animation", + * "some-name : Script Animation", or "Script Animation", depending + * if the server provides the type, what type it is and if the animation + * has a name * @param {AnimationPlayerFront} animation */ function getFormattedAnimationTitle({state}) { - // Older servers don't send the type. - return state.type - ? L10N.getFormatStr("timeline." + state.type + ".nameLabel", state.name) - : state.name; + // Older servers don't send a type, and only know about + // CSSAnimations and CSSTransitions, so it's safe to use + // just the name. + if (!state.type) { + return state.name; + } + + // Script-generated animations may not have a name. + if (state.type === "scriptanimation" && !state.name) { + return L10N.getStr("timeline.scriptanimation.unnamedLabel"); + } + + return L10N.getFormatStr(`timeline.${state.type}.nameLabel`, state.name); } diff --git a/devtools/client/animationinspector/test/browser.ini b/devtools/client/animationinspector/test/browser.ini index 418d9fa0e201..d4f02fc3a1f4 100644 --- a/devtools/client/animationinspector/test/browser.ini +++ b/devtools/client/animationinspector/test/browser.ini @@ -8,6 +8,7 @@ support-files = doc_modify_playbackRate.html doc_negative_animation.html doc_simple_animation.html + doc_multiple_animation_types.html head.js [browser_animation_animated_properties_displayed.js] diff --git a/devtools/client/animationinspector/test/browser_animation_playerWidgets_appear_on_panel_init.js b/devtools/client/animationinspector/test/browser_animation_playerWidgets_appear_on_panel_init.js index 01c7251d828f..2c66eb636ead 100644 --- a/devtools/client/animationinspector/test/browser_animation_playerWidgets_appear_on_panel_init.js +++ b/devtools/client/animationinspector/test/browser_animation_playerWidgets_appear_on_panel_init.js @@ -7,11 +7,41 @@ // Test that player widgets are displayed right when the animation panel is // initialized, if the selected node ( by default) is animated. +const { ANIMATION_TYPES } = require("devtools/server/actors/animation"); + add_task(function*() { - yield addTab(TEST_URL_ROOT + "doc_body_animation.html"); + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [ + ["dom.animations-api.core.enabled", true] + ]}, resolve); + }); + + yield addTab(TEST_URL_ROOT + "doc_multiple_animation_types.html"); let {panel} = yield openAnimationInspector(); - is(panel.animationsTimelineComponent.animations.length, 1, - "One animation is handled by the timeline after init"); - assertAnimationsDisplayed(panel, 1, "One animation is displayed after init"); + is(panel.animationsTimelineComponent.animations.length, 3, + "Three animations are handled by the timeline after init"); + assertAnimationsDisplayed(panel, 3, + "Three animations are displayed after init"); + is( + panel.animationsTimelineComponent + .animationsEl + .querySelectorAll(`.animation.${ANIMATION_TYPES.SCRIPT_ANIMATION}`) + .length, + 1, + "One script-generated animation is displayed"); + is( + panel.animationsTimelineComponent + .animationsEl + .querySelectorAll(`.animation.${ANIMATION_TYPES.CSS_ANIMATION}`) + .length, + 1, + "One CSS animation is displayed"); + is( + panel.animationsTimelineComponent + .animationsEl + .querySelectorAll(`.animation.${ANIMATION_TYPES.CSS_TRANSITION}`) + .length, + 1, + "One CSS transition is displayed"); }); diff --git a/devtools/client/animationinspector/test/doc_multiple_animation_types.html b/devtools/client/animationinspector/test/doc_multiple_animation_types.html new file mode 100644 index 000000000000..f3606a63bd1c --- /dev/null +++ b/devtools/client/animationinspector/test/doc_multiple_animation_types.html @@ -0,0 +1,58 @@ + + + + + + + +
+
+
+ + + + diff --git a/devtools/client/animationinspector/test/head.js b/devtools/client/animationinspector/test/head.js index 2db590865c8a..5e9d915ba024 100644 --- a/devtools/client/animationinspector/test/head.js +++ b/devtools/client/animationinspector/test/head.js @@ -5,8 +5,8 @@ "use strict"; var Cu = Components.utils; -const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); const promise = require("promise"); const {TargetFactory} = require("devtools/client/framework/target"); const {console} = Cu.import("resource://gre/modules/Console.jsm", {}); diff --git a/devtools/client/canvasdebugger/test/head.js b/devtools/client/canvasdebugger/test/head.js index f0dd9bb2951d..e36879ac5adc 100644 --- a/devtools/client/canvasdebugger/test/head.js +++ b/devtools/client/canvasdebugger/test/head.js @@ -13,10 +13,10 @@ Services.prefs.setBoolPref("devtools.debugger.log", false); var { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator); var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); var promise = require("promise"); +var { gDevTools } = require("devtools/client/framework/devtools"); var { DebuggerClient } = require("devtools/shared/client/main"); var { DebuggerServer } = require("devtools/server/main"); var { CallWatcherFront } = require("devtools/server/actors/call-watcher"); diff --git a/devtools/client/debugger/debugger-commands.js b/devtools/client/debugger/debugger-commands.js index cb27bbc907b7..4be6976b8599 100644 --- a/devtools/client/debugger/debugger-commands.js +++ b/devtools/client/debugger/debugger-commands.js @@ -8,8 +8,7 @@ const { Cc, Ci, Cu } = require("chrome"); const l10n = require("gcli/l10n"); - -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); +const { gDevTools } = require("devtools/client/framework/devtools"); /** * The commands and converters that are exported to GCLI diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-02.js b/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-02.js index bfe67bd2b6f8..a2c7b022d08a 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-02.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_listtabs-02.js @@ -101,7 +101,7 @@ function removeTabA() { let deferred = promise.defer(); once(gBrowser.tabContainer, "TabClose").then(aEvent => { - ok(!aEvent.detail, "This was a normal tab close"); + ok(!aEvent.detail.adoptedBy, "This was a normal tab close"); // Let the actor's TabClose handler finish first. executeSoon(deferred.resolve); @@ -145,7 +145,7 @@ function removeTabC() { let deferred = promise.defer(); once(gBrowser.tabContainer, "TabClose").then(aEvent => { - ok(aEvent.detail, "This was a tab closed by moving"); + ok(aEvent.detail.adoptedBy, "This was a tab closed by moving"); // Let the actor's TabClose handler finish first. executeSoon(deferred.resolve); @@ -203,7 +203,7 @@ function removeTabB() { let deferred = promise.defer(); once(gBrowser.tabContainer, "TabClose").then(aEvent => { - ok(!aEvent.detail, "This was a normal tab close"); + ok(!aEvent.detail.adoptedBy, "This was a normal tab close"); // Let the actor's TabClose handler finish first. executeSoon(deferred.resolve); diff --git a/devtools/client/devtools-clhandler.js b/devtools/client/devtools-clhandler.js index 593a1aec472e..873c3aaf6879 100644 --- a/devtools/client/devtools-clhandler.js +++ b/devtools/client/devtools-clhandler.js @@ -51,8 +51,13 @@ devtoolsCommandlineHandler.prototype = { let window = Services.wm.getMostRecentWindow("devtools:webconsole"); if (!window) { let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); - // Load the browser devtools main module as the loader's main module. - Cu.import("resource://devtools/client/framework/gDevTools.jsm"); + // Ensure loading main devtools module that hooks up into browser UI + // and initialize all devtools machinery. + // browser.xul or main top-level document used to load this module, + // but this code may be called without/before it. + // Bug 1247203 should ease handling this. + require("devtools/client/framework/devtools-browser"); + let hudservice = require("devtools/client/webconsole/hudservice"); let { console } = Cu.import("resource://gre/modules/Console.jsm", {}); hudservice.toggleBrowserConsole().then(null, console.error); @@ -71,9 +76,10 @@ devtoolsCommandlineHandler.prototype = { Services.obs.addObserver(function onStartup(window) { Services.obs.removeObserver(onStartup, "browser-delayed-startup-finished"); - const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); - const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {}); - let target = devtools.TargetFactory.forTab(window.gBrowser.selectedTab); + const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); + const {gDevTools} = require("devtools/client/framework/devtools"); + const {TargetFactory} = require("devtools/client/framework/target"); + let target = TargetFactory.forTab(window.gBrowser.selectedTab); gDevTools.showToolbox(target); }, "browser-delayed-startup-finished", false); }, diff --git a/devtools/client/framework/connect/connect.js b/devtools/client/framework/connect/connect.js index e7aa340cd09e..5284cc7585a7 100644 --- a/devtools/client/framework/connect/connect.js +++ b/devtools/client/framework/connect/connect.js @@ -10,8 +10,8 @@ var Cu = Components.utils; Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); -var {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var {gDevTools} = require("devtools/client/framework/devtools"); var {TargetFactory} = require("devtools/client/framework/target"); var {Toolbox} = require("devtools/client/framework/toolbox") var promise = require("promise"); diff --git a/devtools/client/framework/gDevTools.jsm b/devtools/client/framework/gDevTools.jsm index 227fe332c5d5..df1d45425f15 100644 --- a/devtools/client/framework/gDevTools.jsm +++ b/devtools/client/framework/gDevTools.jsm @@ -9,18 +9,12 @@ * Please now use the modules: * - devtools/client/framework/devtools for gDevTools * - devtools/client/framework/devtools-browser for gDevToolsBrowser - * - * We still do use gDevTools.jsm in our codebase, - * bug 1245462 is going to ensure we no longer do that. */ this.EXPORTED_SYMBOLS = [ "gDevTools", "gDevToolsBrowser" ]; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - const { loader } = Cu.import("resource://devtools/shared/Loader.jsm", {}); /** diff --git a/devtools/client/framework/test/shared-head.js b/devtools/client/framework/test/shared-head.js index a00592dbe7f2..d2299dc5499c 100644 --- a/devtools/client/framework/test/shared-head.js +++ b/devtools/client/framework/test/shared-head.js @@ -17,11 +17,11 @@ function scopedCuImport(path) { } const {Services} = scopedCuImport("resource://gre/modules/Services.jsm"); -const {gDevTools} = scopedCuImport("resource://devtools/client/framework/gDevTools.jsm"); const {console} = scopedCuImport("resource://gre/modules/Console.jsm"); const {ScratchpadManager} = scopedCuImport("resource://devtools/client/scratchpad/scratchpad-manager.jsm"); const {require} = scopedCuImport("resource://devtools/shared/Loader.jsm"); +const {gDevTools} = require("devtools/client/framework/devtools"); const {TargetFactory} = require("devtools/client/framework/target"); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); let promise = require("promise"); diff --git a/devtools/client/framework/toolbox-options.js b/devtools/client/framework/toolbox-options.js index eea72c3fa35a..9bce031c2532 100644 --- a/devtools/client/framework/toolbox-options.js +++ b/devtools/client/framework/toolbox-options.js @@ -9,7 +9,7 @@ const Services = require("Services"); const promise = require("promise"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Task.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); +const {gDevTools} = require("devtools/client/framework/devtools"); exports.OptionsPanel = OptionsPanel; diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index cc50512c6495..53cbb2372332 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -16,6 +16,7 @@ const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER"; var {Cc, Ci, Cu} = require("chrome"); var promise = require("promise"); +var {gDevTools} = require("devtools/client/framework/devtools"); var EventEmitter = require("devtools/shared/event-emitter"); var Telemetry = require("devtools/client/shared/telemetry"); var HUDService = require("devtools/client/webconsole/hudservice"); @@ -23,7 +24,6 @@ var viewSource = require("devtools/client/shared/view-source"); var { attachThread, detachThread } = require("./attach-thread"); Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm"); Cu.import("resource://devtools/client/shared/DOMHelpers.jsm"); Cu.import("resource://gre/modules/Task.jsm"); diff --git a/devtools/client/inspector/computed/computed.js b/devtools/client/inspector/computed/computed.js index f71332450fa6..c18f27144fab 100644 --- a/devtools/client/inspector/computed/computed.js +++ b/devtools/client/inspector/computed/computed.js @@ -18,7 +18,7 @@ const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", const {OutputParser} = require("devtools/client/shared/output-parser"); const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils"); const {createChild} = require("devtools/client/inspector/shared/utils"); -const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); loader.lazyRequireGetter(this, "overlays", "devtools/client/inspector/shared/style-inspector-overlays"); diff --git a/devtools/client/inspector/fonts/fonts.js b/devtools/client/inspector/fonts/fonts.js index c5531dfab98a..8284135ebb54 100644 --- a/devtools/client/inspector/fonts/fonts.js +++ b/devtools/client/inspector/fonts/fonts.js @@ -9,6 +9,7 @@ const {Cu} = require("chrome"); const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); const DEFAULT_PREVIEW_TEXT = "Abc"; const PREVIEW_UPDATE_DELAY = 150; diff --git a/devtools/client/inspector/inspector-commands.js b/devtools/client/inspector/inspector-commands.js index 718c2d7fa100..bc9d8cca0239 100644 --- a/devtools/client/inspector/inspector-commands.js +++ b/devtools/client/inspector/inspector-commands.js @@ -22,7 +22,7 @@ exports.items = [{ ], exec: function(args, context) { let target = context.environment.target; - let gDevTools = require("resource://devtools/client/framework/gDevTools.jsm").gDevTools; + let {gDevTools} = require("devtools/client/framework/devtools"); return gDevTools.showToolbox(target, "inspector").then(toolbox => { toolbox.getCurrentPanel().selection.setNode(args.selector, "gcli"); diff --git a/devtools/client/inspector/rules/rules.js b/devtools/client/inspector/rules/rules.js index 0f44740568ad..bdca31f05fb7 100644 --- a/devtools/client/inspector/rules/rules.js +++ b/devtools/client/inspector/rules/rules.js @@ -24,11 +24,10 @@ const {RuleEditor} = require("devtools/client/inspector/rules/views/rule-editor"); const {createChild, promiseWarn} = require("devtools/client/inspector/shared/utils"); +const {gDevTools} = require("devtools/client/framework/devtools"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -loader.lazyGetter(this, "gDevTools", () => - Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}).gDevTools); loader.lazyRequireGetter(this, "overlays", "devtools/client/inspector/shared/style-inspector-overlays"); loader.lazyRequireGetter(this, "EventEmitter", diff --git a/devtools/client/inspector/shared/test/head.js b/devtools/client/inspector/shared/test/head.js index 8d1bf4f12506..5857f12c7f29 100644 --- a/devtools/client/inspector/shared/test/head.js +++ b/devtools/client/inspector/shared/test/head.js @@ -5,8 +5,8 @@ "use strict"; var Cu = Components.utils; -var {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var {gDevTools} = require("devtools/client/framework/devtools"); var {TargetFactory} = require("devtools/client/framework/target"); var {CssRuleView, _ElementStyle} = require("devtools/client/inspector/rules/rules"); var {CssLogic, CssSelector} = require("devtools/shared/inspector/css-logic"); @@ -14,8 +14,7 @@ var DevToolsUtils = require("devtools/shared/DevToolsUtils"); var promise = require("promise"); var {editableField, getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor"); -var {console} = - Components.utils.import("resource://gre/modules/Console.jsm", {}); +var {console} = Cu.import("resource://gre/modules/Console.jsm", {}); // All tests are asynchronous waitForExplicitFinish(); diff --git a/devtools/client/jsonview/main.js b/devtools/client/jsonview/main.js index 91a1408b8add..47d6d78270a4 100644 --- a/devtools/client/jsonview/main.js +++ b/devtools/client/jsonview/main.js @@ -18,7 +18,7 @@ XPCOMUtils.defineLazyGetter(this, "JsonViewService", function() { /** * Singleton object that represents the JSON View in-content tool. * It has the same lifetime as the browser. Initialization done by - * DevTools() object from gDevTools.jsm + * DevTools() object from devtools/client/framework/devtools.js */ var JsonView = { initialize: function() { diff --git a/devtools/client/locales/en-US/animationinspector.properties b/devtools/client/locales/en-US/animationinspector.properties index bf44b7c4df6a..c31b632c5ad1 100644 --- a/devtools/client/locales/en-US/animationinspector.properties +++ b/devtools/client/locales/en-US/animationinspector.properties @@ -108,6 +108,17 @@ timeline.cssanimation.nameLabel=%S - CSS Animation # %S will be replaced by the name of the transition at run-time. timeline.csstransition.nameLabel=%S - CSS Transition +# LOCALIZATION NOTE (timeline.scriptanimation.nameLabel): +# This string is displayed in a tooltip of the animation panel that is shown +# when hovering over the name of a script-generated animation in the timeline UI. +# %S will be replaced by the name of the animation at run-time. +timeline.scriptanimation.nameLabel=%S - Script Animation + +# LOCALIZATION NOTE (timeline.scriptanimation.unnamedLabel): +# This string is displayed in a tooltip of the animation panel that is shown +# when hovering over an unnamed script-generated animation in the timeline UI. +timeline.scriptanimation.unnamedLabel=Script Animation + # LOCALIZATION NOTE (timeline.unknown.nameLabel): # This string is displayed in a tooltip of the animation panel that is shown # when hovering over the name of an unknown animation type in the timeline UI. diff --git a/devtools/client/main.js b/devtools/client/main.js index 7e9dc705b4f3..f632ae0cca73 100644 --- a/devtools/client/main.js +++ b/devtools/client/main.js @@ -6,7 +6,7 @@ const { Cu } = require("chrome"); Cu.import("resource://gre/modules/Services.jsm"); -const { gDevTools } = require("resource://devtools/client/framework/gDevTools.jsm"); +const { gDevTools } = require("devtools/client/framework/devtools"); const { defaultTools, defaultThemes } = require("devtools/client/definitions"); diff --git a/devtools/client/memory/test/browser/browser.ini b/devtools/client/memory/test/browser/browser.ini index 7d8e4339bd21..29fee425dc42 100644 --- a/devtools/client/memory/test/browser/browser.ini +++ b/devtools/client/memory/test/browser/browser.ini @@ -14,6 +14,7 @@ support-files = [browser_memory_dominator_trees_01.js] [browser_memory_dominator_trees_02.js] [browser_memory_filter_01.js] +[browser_memory_keyboard.js] [browser_memory_no_allocation_stacks.js] [browser_memory_no_auto_expand.js] skip-if = debug # bug 1219554 diff --git a/devtools/client/memory/test/browser/browser_memory_keyboard.js b/devtools/client/memory/test/browser/browser_memory_keyboard.js new file mode 100644 index 000000000000..205fe198c796 --- /dev/null +++ b/devtools/client/memory/test/browser/browser_memory_keyboard.js @@ -0,0 +1,101 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Bug 1246570 - Check that when pressing on LEFT arrow, the parent tree node +// gets focused. + +"use strict"; + +const { + snapshotState +} = require("devtools/client/memory/constants"); +const { + takeSnapshotAndCensus +} = require("devtools/client/memory/actions/snapshot"); + +const TEST_URL = "http://example.com/browser/devtools/client/memory/test/browser/doc_steady_allocation.html"; + +function waitUntilFocused(store, node) { + return waitUntilState(store, state => + state.snapshots.length === 1 && + state.snapshots[0].state === snapshotState.SAVED_CENSUS && + state.snapshots[0].census && + state.snapshots[0].census.focused && + state.snapshots[0].census.focused === node + ); +} + +function waitUntilExpanded(store, node) { + return waitUntilState(store, state => + state.snapshots[0] && + state.snapshots[0].census && + state.snapshots[0].census.expanded.has(node.id)); +} + +this.test = makeMemoryTest(TEST_URL, function* ({ tab, panel }) { + const heapWorker = panel.panelWin.gHeapAnalysesClient; + const front = panel.panelWin.gFront; + const store = panel.panelWin.gStore; + const { getState, dispatch } = store; + const doc = panel.panelWin.document; + + is(getState().breakdown.by, "coarseType"); + yield dispatch(takeSnapshotAndCensus(front, heapWorker)); + let census = getState().snapshots[0].census; + let root1 = census.report.children[0]; + let root2 = census.report.children[0]; + let root3 = census.report.children[0]; + let root4 = census.report.children[0]; + let child1 = root1.children[0]; + + info("Click on first node."); + let firstNode = doc.querySelector(".tree .heap-tree-item-name"); + EventUtils.synthesizeMouseAtCenter(firstNode, {}, panel.panelWin); + yield waitUntilFocused(store, root1); + ok(true, "First root is selected after click."); + + info("Press DOWN key, expect second root focused."); + EventUtils.synthesizeKey("VK_DOWN", {}, panel.panelWin); + yield waitUntilFocused(store, root2); + ok(true, "Second root is selected after pressing DOWN arrow."); + + info("Press DOWN key, expect third root focused."); + EventUtils.synthesizeKey("VK_DOWN", {}, panel.panelWin); + yield waitUntilFocused(store, root3); + ok(true, "Third root is selected after pressing DOWN arrow."); + + info("Press DOWN key, expect fourth root focused."); + EventUtils.synthesizeKey("VK_DOWN", {}, panel.panelWin); + yield waitUntilFocused(store, root4); + ok(true, "Fourth root is selected after pressing DOWN arrow."); + + info("Press UP key, expect third root focused."); + EventUtils.synthesizeKey("VK_UP", {}, panel.panelWin); + yield waitUntilFocused(store, root3); + ok(true, "Third root is selected after pressing UP arrow."); + + info("Press UP key, expect second root focused."); + EventUtils.synthesizeKey("VK_UP", {}, panel.panelWin); + yield waitUntilFocused(store, root2); + ok(true, "Second root is selected after pressing UP arrow."); + + info("Press UP key, expect first root focused."); + EventUtils.synthesizeKey("VK_UP", {}, panel.panelWin); + yield waitUntilFocused(store, root1); + ok(true, "First root is selected after pressing UP arrow."); + + info("Press RIGHT key"); + EventUtils.synthesizeKey("VK_RIGHT", {}, panel.panelWin); + yield waitUntilExpanded(store, root1); + ok(true, "Root node is expanded."); + + info("Press RIGHT key, expect first child focused."); + EventUtils.synthesizeKey("VK_RIGHT", {}, panel.panelWin); + yield waitUntilFocused(store, child1); + ok(true, "First child is selected after pressing RIGHT arrow."); + + info("Press LEFT key, expect first root focused."); + EventUtils.synthesizeKey("VK_LEFT", {}, panel.panelWin); + yield waitUntilFocused(store, root1); + ok(true, "First root is selected after pressing LEFT arrow."); +}); diff --git a/devtools/client/memory/test/unit/head.js b/devtools/client/memory/test/unit/head.js index 890cb0b063e0..3f9d9ef31441 100644 --- a/devtools/client/memory/test/unit/head.js +++ b/devtools/client/memory/test/unit/head.js @@ -5,14 +5,13 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; var { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var { console } = Cu.import("resource://gre/modules/Console.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); DevToolsUtils.testing = true; DevToolsUtils.dumpn.wantLogging = true; -DevToolsUtils.dumpv.wantLogging = true; +DevToolsUtils.dumpv.wantVerbose = false; var { OS } = require("resource://gre/modules/osfile.jsm"); var { FileUtils } = require("resource://gre/modules/FileUtils.jsm"); diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js index 41c282af49e4..a27fe46d0347 100644 --- a/devtools/client/netmonitor/test/head.js +++ b/devtools/client/netmonitor/test/head.js @@ -6,8 +6,8 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; var { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var { gDevTools } = require("devtools/client/framework/devtools"); var { CurlUtils } = Cu.import("resource://devtools/client/shared/Curl.jsm", {}); var promise = require("promise"); var NetworkHelper = require("devtools/shared/webconsole/network-helper"); diff --git a/devtools/client/performance/performance-controller.js b/devtools/client/performance/performance-controller.js index 63a027bd78c5..e740b8ad02a9 100644 --- a/devtools/client/performance/performance-controller.js +++ b/devtools/client/performance/performance-controller.js @@ -9,6 +9,7 @@ Cu.import("resource://devtools/client/shared/browser-loader.js", BrowserLoaderMo var { loader, require } = BrowserLoaderModule.BrowserLoader("resource://devtools/client/performance/", this); var { Task } = require("resource://gre/modules/Task.jsm"); var { Heritage, ViewHelpers, WidgetMethods } = require("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); +var {gDevTools} = require("devtools/client/framework/devtools"); // Events emitted by various objects in the panel. var EVENTS = require("devtools/client/performance/events"); diff --git a/devtools/client/performance/test/head.js b/devtools/client/performance/test/head.js index 1de443d54f2c..846acbddcfab 100644 --- a/devtools/client/performance/test/head.js +++ b/devtools/client/performance/test/head.js @@ -8,7 +8,7 @@ var { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); var { Preferences } = Cu.import("resource://gre/modules/Preferences.jsm", {}); var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); +var { gDevTools } = require("devtools/client/framework/devtools"); var { console } = require("resource://gre/modules/Console.jsm"); var { TargetFactory } = require("devtools/client/framework/target"); var Promise = require("promise"); diff --git a/devtools/client/responsive.html/actions/index.js b/devtools/client/responsive.html/actions/index.js index 9e84fa8f887d..88dab35d295c 100644 --- a/devtools/client/responsive.html/actions/index.js +++ b/devtools/client/responsive.html/actions/index.js @@ -17,6 +17,9 @@ createEnum([ // Add an additional viewport to display the document. "ADD_VIEWPORT", + // Resize the viewport. + "RESIZE_VIEWPORT", + // Rotate the viewport. "ROTATE_VIEWPORT", diff --git a/devtools/client/responsive.html/actions/viewports.js b/devtools/client/responsive.html/actions/viewports.js index 0ded91cb2325..6723032aba12 100644 --- a/devtools/client/responsive.html/actions/viewports.js +++ b/devtools/client/responsive.html/actions/viewports.js @@ -4,7 +4,11 @@ "use strict"; -const { ADD_VIEWPORT, ROTATE_VIEWPORT } = require("./index"); +const { + ADD_VIEWPORT, + RESIZE_VIEWPORT, + ROTATE_VIEWPORT +} = require("./index"); module.exports = { @@ -17,6 +21,18 @@ module.exports = { }; }, + /** + * Resize the viewport. + */ + resizeViewport(id, width, height) { + return { + type: RESIZE_VIEWPORT, + id, + width, + height, + }; + }, + /** * Rotate the viewport. */ diff --git a/devtools/client/responsive.html/app.js b/devtools/client/responsive.html/app.js index c189224a46ce..a34049901ee2 100644 --- a/devtools/client/responsive.html/app.js +++ b/devtools/client/responsive.html/app.js @@ -8,7 +8,7 @@ const { createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react"); const { connect } = require("devtools/client/shared/vendor/react-redux"); -const { rotateViewport } = require("./actions/viewports"); +const { resizeViewport, rotateViewport } = require("./actions/viewports"); const Types = require("./types"); const Viewports = createFactory(require("./components/viewports")); @@ -34,6 +34,8 @@ let App = createClass({ location, viewports, onRotateViewport: id => dispatch(rotateViewport(id)), + onResizeViewport: (id, width, height) => + dispatch(resizeViewport(id, width, height)), }); }, diff --git a/devtools/client/responsive.html/components/browser.js b/devtools/client/responsive.html/components/browser.js index f20de52c01a9..ff1b4bbdac99 100644 --- a/devtools/client/responsive.html/components/browser.js +++ b/devtools/client/responsive.html/components/browser.js @@ -4,7 +4,7 @@ "use strict"; -const { DOM: dom, createClass } = +const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react"); const Types = require("../types"); @@ -17,6 +17,7 @@ module.exports = createClass({ location: Types.location.isRequired, width: Types.viewport.width.isRequired, height: Types.viewport.height.isRequired, + isResizing: PropTypes.bool.isRequired, }, render() { @@ -24,11 +25,17 @@ module.exports = createClass({ location, width, height, + isResizing, } = this.props; + let className = "browser"; + if (isResizing) { + className += " resizing"; + } + return dom.iframe( { - className: "browser", + className, src: location, width, height, diff --git a/devtools/client/responsive.html/components/moz.build b/devtools/client/responsive.html/components/moz.build index 426a572e8d87..9a98dbe75c57 100644 --- a/devtools/client/responsive.html/components/moz.build +++ b/devtools/client/responsive.html/components/moz.build @@ -6,6 +6,7 @@ DevToolsModules( 'browser.js', + 'resizable-viewport.js', 'viewport-toolbar.js', 'viewport.js', 'viewports.js', diff --git a/devtools/client/responsive.html/components/resizable-viewport.js b/devtools/client/responsive.html/components/resizable-viewport.js new file mode 100644 index 000000000000..91a6623f174f --- /dev/null +++ b/devtools/client/responsive.html/components/resizable-viewport.js @@ -0,0 +1,143 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* global window */ + +"use strict"; + +const { DOM: dom, createClass, createFactory, PropTypes } = + require("devtools/client/shared/vendor/react"); + +const Types = require("../types"); +const Browser = createFactory(require("./browser")); +const ViewportToolbar = createFactory(require("./viewport-toolbar")); + +const VIEWPORT_MIN_WIDTH = 280; +const VIEWPORT_MIN_HEIGHT = 280; + +module.exports = createClass({ + + displayName: "ResizableViewport", + + propTypes: { + location: Types.location.isRequired, + viewport: PropTypes.shape(Types.viewport).isRequired, + onResizeViewport: PropTypes.func.isRequired, + onRotateViewport: PropTypes.func.isRequired, + }, + + getInitialState() { + return { + isResizing: false, + lastClientX: 0, + lastClientY: 0, + ignoreX: false, + ignoreY: false, + }; + }, + + onResizeStart({ target, clientX, clientY }) { + window.addEventListener("mousemove", this.onResizeDrag, true); + window.addEventListener("mouseup", this.onResizeStop, true); + + this.setState({ + isResizing: true, + lastClientX: clientX, + lastClientY: clientY, + ignoreX: target === this.refs.resizeBarY, + ignoreY: target === this.refs.resizeBarX, + }); + }, + + onResizeStop() { + window.removeEventListener("mousemove", this.onResizeDrag, true); + window.removeEventListener("mouseup", this.onResizeStop, true); + + this.setState({ + isResizing: false, + lastClientX: 0, + lastClientY: 0, + ignoreX: false, + ignoreY: false, + }); + }, + + onResizeDrag({ clientX, clientY }) { + if (!this.state.isResizing) { + return; + } + + let { lastClientX, lastClientY, ignoreX, ignoreY } = this.state; + let deltaX = clientX - lastClientX; + let deltaY = clientY - lastClientY; + + if (ignoreX) { + deltaX = 0; + } + if (ignoreY) { + deltaY = 0; + } + + let width = this.props.viewport.width + deltaX; + let height = this.props.viewport.height + deltaY; + + if (width < VIEWPORT_MIN_WIDTH) { + width = VIEWPORT_MIN_WIDTH; + } else { + lastClientX = clientX; + } + + if (height < VIEWPORT_MIN_HEIGHT) { + height = VIEWPORT_MIN_HEIGHT; + } else { + lastClientY = clientY; + } + + // Update the viewport store with the new width and height. + this.props.onResizeViewport(width, height); + + this.setState({ + lastClientX, + lastClientY + }); + }, + + render() { + let { + location, + viewport, + onRotateViewport, + } = this.props; + + return dom.div( + { + className: "resizable-viewport", + }, + ViewportToolbar({ + onRotateViewport, + }), + Browser({ + location, + width: viewport.width, + height: viewport.height, + isResizing: this.state.isResizing + }), + dom.div({ + className: "viewport-resize-handle", + onMouseDown: this.onResizeStart, + }), + dom.div({ + ref: "resizeBarX", + className: "viewport-horizontal-resize-handle", + onMouseDown: this.onResizeStart, + }), + dom.div({ + ref: "resizeBarY", + className: "viewport-vertical-resize-handle", + onMouseDown: this.onResizeStart, + }) + ); + }, + +}); diff --git a/devtools/client/responsive.html/components/viewport.js b/devtools/client/responsive.html/components/viewport.js index 8ed829a7f097..8f1767c40b9d 100644 --- a/devtools/client/responsive.html/components/viewport.js +++ b/devtools/client/responsive.html/components/viewport.js @@ -8,8 +8,7 @@ const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react"); const Types = require("../types"); -const Browser = createFactory(require("./browser")); -const ViewportToolbar = createFactory(require("./viewport-toolbar")); +const ResizableViewport = createFactory(require("./resizable-viewport")); module.exports = createClass({ @@ -18,6 +17,7 @@ module.exports = createClass({ propTypes: { location: Types.location.isRequired, viewport: PropTypes.shape(Types.viewport).isRequired, + onResizeViewport: PropTypes.func.isRequired, onRotateViewport: PropTypes.func.isRequired, }, @@ -25,20 +25,19 @@ module.exports = createClass({ let { location, viewport, + onResizeViewport, onRotateViewport, } = this.props; return dom.div( { - className: "viewport" + className: "viewport", }, - ViewportToolbar({ - onRotateViewport, - }), - Browser({ + ResizableViewport({ location, - width: viewport.width, - height: viewport.height, + viewport, + onResizeViewport, + onRotateViewport, }) ); }, diff --git a/devtools/client/responsive.html/components/viewports.js b/devtools/client/responsive.html/components/viewports.js index 229b401fc3b1..97d216f27480 100644 --- a/devtools/client/responsive.html/components/viewports.js +++ b/devtools/client/responsive.html/components/viewports.js @@ -17,6 +17,7 @@ module.exports = createClass({ propTypes: { location: Types.location.isRequired, viewports: PropTypes.arrayOf(PropTypes.shape(Types.viewport)).isRequired, + onResizeViewport: PropTypes.func.isRequired, onRotateViewport: PropTypes.func.isRequired, }, @@ -24,6 +25,7 @@ module.exports = createClass({ let { location, viewports, + onResizeViewport, onRotateViewport, } = this.props; @@ -36,6 +38,8 @@ module.exports = createClass({ key: viewport.id, location, viewport, + onResizeViewport: (width, height) => + onResizeViewport(viewport.id, width, height), onRotateViewport: () => onRotateViewport(viewport.id), }); }) diff --git a/devtools/client/responsive.html/images/grippers.svg b/devtools/client/responsive.html/images/grippers.svg new file mode 100644 index 000000000000..91db83af9d20 --- /dev/null +++ b/devtools/client/responsive.html/images/grippers.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/responsive.html/images/moz.build b/devtools/client/responsive.html/images/moz.build index c97d4941f60f..e7bf743777cf 100644 --- a/devtools/client/responsive.html/images/moz.build +++ b/devtools/client/responsive.html/images/moz.build @@ -5,5 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( + 'grippers.svg', 'rotate-viewport.svg', ) diff --git a/devtools/client/responsive.html/index.css b/devtools/client/responsive.html/index.css index a7df3e3b6bca..1f7aa4841e4e 100644 --- a/devtools/client/responsive.html/index.css +++ b/devtools/client/responsive.html/index.css @@ -13,6 +13,10 @@ --viewport-box-shadow: 0 4px 4px 0 rgba(105, 105, 105, 0.26); } +* { + box-sizing: border-box; +} + html, body { margin: 0; height: 100%; @@ -57,6 +61,10 @@ body { box-shadow: var(--viewport-box-shadow); } +.resizable-viewport { + position: relative; +} + /** * Viewport Toolbar */ @@ -96,7 +104,51 @@ body { mask-image: url("./images/rotate-viewport.svg"); } +/** + * Viewport Browser + */ + .browser { display: block; border: 0; } + +.browser.resizing { + pointer-events: none; +} + +/** + * Viewport Resize Handles + */ + +.viewport-resize-handle { + position: absolute; + width: 16px; + height: 16px; + bottom: 0; + right: 0; + background-image: url("./images/grippers.svg"); + background-position: bottom right; + padding: 0 1px 1px 0; + background-repeat: no-repeat; + background-origin: content-box; + cursor: se-resize; +} + +.viewport-horizontal-resize-handle { + position: absolute; + width: 5px; + height: calc(100% - 16px); + right: -4px; + top: 0; + cursor: e-resize; +} + +.viewport-vertical-resize-handle { + position: absolute; + width: calc(100% - 16px); + height: 5px; + left: 0; + bottom: -4px; + cursor: s-resize; +} diff --git a/devtools/client/responsive.html/reducers/viewports.js b/devtools/client/responsive.html/reducers/viewports.js index 177e38617223..14674cd18dcd 100644 --- a/devtools/client/responsive.html/reducers/viewports.js +++ b/devtools/client/responsive.html/reducers/viewports.js @@ -4,7 +4,11 @@ "use strict"; -const { ADD_VIEWPORT, ROTATE_VIEWPORT } = require("../actions/index"); +const { + ADD_VIEWPORT, + RESIZE_VIEWPORT, + ROTATE_VIEWPORT, +} = require("../actions/index"); let nextViewportId = 0; @@ -25,6 +29,19 @@ let reducers = { return [...viewports, Object.assign({}, INITIAL_VIEWPORT)]; }, + [RESIZE_VIEWPORT](viewports, { id, width, height }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + return Object.assign({}, viewport, { + width, + height, + }); + }); + }, + [ROTATE_VIEWPORT](viewports, { id }) { return viewports.map(viewport => { if (viewport.id !== id) { diff --git a/devtools/client/responsive.html/test/unit/test_resize_viewport.js b/devtools/client/responsive.html/test/unit/test_resize_viewport.js new file mode 100644 index 000000000000..0d3cf7809468 --- /dev/null +++ b/devtools/client/responsive.html/test/unit/test_resize_viewport.js @@ -0,0 +1,21 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test resizing the viewport. + +const { addViewport, resizeViewport } = + require("devtools/client/responsive.html/actions/viewports"); + +add_task(function*() { + let store = Store(); + const { getState, dispatch } = store; + + dispatch(addViewport()); + dispatch(resizeViewport(0, 500, 500)); + + let viewport = getState().viewports[0]; + equal(viewport.width, 500, "Resized width of 500"); + equal(viewport.height, 500, "Resized height of 500"); +}); diff --git a/devtools/client/responsive.html/test/unit/xpcshell.ini b/devtools/client/responsive.html/test/unit/xpcshell.ini index 95d978f53582..3b9e704e333d 100644 --- a/devtools/client/responsive.html/test/unit/xpcshell.ini +++ b/devtools/client/responsive.html/test/unit/xpcshell.ini @@ -6,4 +6,5 @@ firefox-appdir = browser [test_add_viewport.js] [test_change_location.js] +[test_resize_viewport.js] [test_rotate_viewport.js] diff --git a/devtools/client/responsivedesign/responsivedesign.jsm b/devtools/client/responsivedesign/responsivedesign.jsm index 367f3b7e139d..540853b57010 100644 --- a/devtools/client/responsivedesign/responsivedesign.jsm +++ b/devtools/client/responsivedesign/responsivedesign.jsm @@ -7,21 +7,18 @@ const Ci = Components.interfaces; const Cu = Components.utils; -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); -Cu.import("resource://devtools/shared/event-emitter.js"); -Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var { loader, require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); var Telemetry = require("devtools/client/shared/telemetry"); var { showDoorhanger } = require("devtools/client/shared/doorhanger"); var { TouchEventSimulator } = require("devtools/shared/touch/simulator"); var { Task } = require("resource://gre/modules/Task.jsm"); var promise = require("promise"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); +var Services = require("Services"); +var EventEmitter = require("devtools/shared/event-emitter"); +var { ViewHelpers } = require("devtools/client/shared/widgets/ViewHelpers.jsm"); +loader.lazyImporter(this, "SystemAppProxy", + "resource://gre/modules/SystemAppProxy.jsm"); this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"]; @@ -1092,6 +1089,6 @@ ResponsiveUI.prototype = { }, } -XPCOMUtils.defineLazyGetter(ResponsiveUI.prototype, "strings", function () { +loader.lazyGetter(ResponsiveUI.prototype, "strings", function () { return Services.strings.createBundle("chrome://devtools/locale/responsiveUI.properties"); }); diff --git a/devtools/client/scratchpad/scratchpad.js b/devtools/client/scratchpad/scratchpad.js index 4dff1db53a39..78fe239df9fb 100644 --- a/devtools/client/scratchpad/scratchpad.js +++ b/devtools/client/scratchpad/scratchpad.js @@ -52,13 +52,13 @@ const EventEmitter = require("devtools/shared/event-emitter"); const {DevToolsWorker} = require("devtools/shared/worker/worker"); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); const promise = require("promise"); +const {gDevTools} = require("devtools/client/framework/devtools"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://devtools/client/scratchpad/scratchpad-manager.jsm"); Cu.import("resource://gre/modules/jsdebugger.jsm"); -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); Cu.import("resource://gre/modules/reflect.jsm"); diff --git a/devtools/client/shadereditor/test/head.js b/devtools/client/shadereditor/test/head.js index 0aa18bd9ec25..4429482667e6 100644 --- a/devtools/client/shadereditor/test/head.js +++ b/devtools/client/shadereditor/test/head.js @@ -11,10 +11,10 @@ var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log"); Services.prefs.setBoolPref("devtools.debugger.log", false); var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); var promise = require("promise"); +var { gDevTools } = require("devtools/client/framework/devtools"); var { DebuggerClient } = require("devtools/shared/client/main"); var { DebuggerServer } = require("devtools/server/main"); var { WebGLFront } = require("devtools/server/actors/webgl"); diff --git a/devtools/client/shared/autocomplete-popup.js b/devtools/client/shared/autocomplete-popup.js index 11e8924b38a9..355c1f1a1d0b 100644 --- a/devtools/client/shared/autocomplete-popup.js +++ b/devtools/client/shared/autocomplete-popup.js @@ -9,7 +9,7 @@ const {Cc, Ci, Cu} = require("chrome"); const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm"); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); +const {gDevTools} = require("devtools/client/framework/devtools"); const events = require("devtools/shared/event-emitter"); /** diff --git a/devtools/client/shared/components/test/mochitest/head.js b/devtools/client/shared/components/test/mochitest/head.js index b4706ab29fa0..f037dc370553 100644 --- a/devtools/client/shared/components/test/mochitest/head.js +++ b/devtools/client/shared/components/test/mochitest/head.js @@ -8,10 +8,10 @@ Cu.import("resource://testing-common/Assert.jsm"); Cu.import("resource://gre/modules/Task.jsm"); var { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); -var { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); +var { gDevTools } = require("devtools/client/framework/devtools"); var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {}); +var promise = require("promise"); var { DebuggerServer } = require("devtools/server/main"); var { DebuggerClient } = require("devtools/shared/client/main"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); diff --git a/devtools/client/shared/test/browser_toolbar_webconsole_errors_count.js b/devtools/client/shared/test/browser_toolbar_webconsole_errors_count.js index 3bde1598e24b..235af7bd0a2f 100644 --- a/devtools/client/shared/test/browser_toolbar_webconsole_errors_count.js +++ b/devtools/client/shared/test/browser_toolbar_webconsole_errors_count.js @@ -6,9 +6,6 @@ function test() { const TEST_URI = TEST_URI_ROOT + "browser_toolbar_webconsole_errors_count.html"; - let gDevTools = Cu.import("resource://devtools/client/framework/gDevTools.jsm", - {}).gDevTools; - let webconsole = document.getElementById("developer-toolbar-toolbox-button"); let tab1, tab2; diff --git a/devtools/client/shared/theme-switching.js b/devtools/client/shared/theme-switching.js index c5c85ecdbc62..c076f8734929 100644 --- a/devtools/client/shared/theme-switching.js +++ b/devtools/client/shared/theme-switching.js @@ -159,8 +159,8 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components; Cu.import("resource://gre/modules/Services.jsm"); - Cu.import("resource://devtools/client/framework/gDevTools.jsm"); const {require} = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); + const {gDevTools} = require("devtools/client/framework/devtools"); const StylesheetUtils = require("sdk/stylesheet/utils"); if (documentElement.hasAttribute("force-theme")) { diff --git a/devtools/client/shared/theme.js b/devtools/client/shared/theme.js index bcf5e8452927..68ccee368bef 100644 --- a/devtools/client/shared/theme.js +++ b/devtools/client/shared/theme.js @@ -12,7 +12,7 @@ const { Ci, Cu } = require("chrome"); const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {}); loader.lazyRequireGetter(this, "Services"); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); +const { gDevTools } = require("devtools/client/framework/devtools"); const VARIABLES_URI = "chrome://devtools/skin/variables.css"; const THEME_SELECTOR_STRINGS = { diff --git a/devtools/client/shared/view-source.js b/devtools/client/shared/view-source.js index 08375d609fb5..09caa67d2e3c 100644 --- a/devtools/client/shared/view-source.js +++ b/devtools/client/shared/view-source.js @@ -5,9 +5,9 @@ "use strict"; loader.lazyRequireGetter(this, "Services"); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); loader.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm"); +var {gDevTools} = require("devtools/client/framework/devtools"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); /** diff --git a/devtools/client/shims/gDevTools.jsm b/devtools/client/shims/gDevTools.jsm index 94df038d6638..0bdf45633f60 100644 --- a/devtools/client/shims/gDevTools.jsm +++ b/devtools/client/shims/gDevTools.jsm @@ -24,7 +24,6 @@ if (Services.prefs.getBoolPref(WARNING_PREF)) { this.EXPORTED_SYMBOLS = [ "gDevTools", - "DevTools", "gDevToolsBrowser" ]; diff --git a/devtools/client/styleeditor/StyleEditorUI.jsm b/devtools/client/styleeditor/StyleEditorUI.jsm index 0b375f7133d0..1d17f91ca942 100644 --- a/devtools/client/styleeditor/StyleEditorUI.jsm +++ b/devtools/client/styleeditor/StyleEditorUI.jsm @@ -16,7 +16,7 @@ const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {}); const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {}); const {Task} = Cu.import("resource://gre/modules/Task.jsm", {}); const EventEmitter = require("devtools/shared/event-emitter"); -const {gDevTools} = require("resource://devtools/client/framework/gDevTools.jsm"); +const {gDevTools} = require("devtools/client/framework/devtools"); /* import-globals-from StyleEditorUtil.jsm */ Cu.import("resource://devtools/client/styleeditor/StyleEditorUtil.jsm"); const {SplitView} = Cu.import("resource://devtools/client/shared/SplitView.jsm", {}); diff --git a/devtools/client/styleeditor/styleeditor-commands.js b/devtools/client/styleeditor/styleeditor-commands.js index 9ae4c48f9ef2..d4803b715b68 100644 --- a/devtools/client/styleeditor/styleeditor-commands.js +++ b/devtools/client/styleeditor/styleeditor-commands.js @@ -58,7 +58,7 @@ exports.items = [{ to: "dom", exec: function(args, context) { let target = context.environment.target; - let gDevTools = require("resource://devtools/client/framework/gDevTools.jsm").gDevTools; + let {gDevTools} = require("devtools/client/framework/devtools"); return gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) { let styleEditor = toolbox.getCurrentPanel(); styleEditor.selectStyleSheet(args.href, args.line); diff --git a/devtools/client/themes/animationinspector.css b/devtools/client/themes/animationinspector.css index 0ae8f4b12d25..0872dd5e0ead 100644 --- a/devtools/client/themes/animationinspector.css +++ b/devtools/client/themes/animationinspector.css @@ -42,6 +42,11 @@ --timeline-background-color: var(--theme-highlight-blue); } +.animation.scriptanimation { + --timeline-border-color: var(--theme-highlight-green); + --timeline-background-color: var(--theme-graphs-green); +} + html { height: 100%; } @@ -529,6 +534,10 @@ body { background-color: var(--theme-highlight-blue); } +.keyframes.scriptanimation { + background-color: var(--theme-graphs-green); +} + .keyframes .frame { position: absolute; top: 0; diff --git a/devtools/client/themes/images/diff.svg b/devtools/client/themes/images/diff.svg index 887f77b1770c..fabe70062370 100644 --- a/devtools/client/themes/images/diff.svg +++ b/devtools/client/themes/images/diff.svg @@ -2,6 +2,6 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - + + diff --git a/devtools/client/tilt/tilt-visualizer.js b/devtools/client/tilt/tilt-visualizer.js index 68f6f929ea7e..5eb9b4ef4afb 100644 --- a/devtools/client/tilt/tilt-visualizer.js +++ b/devtools/client/tilt/tilt-visualizer.js @@ -14,7 +14,7 @@ var {EPSILON, TiltMath, vec3, mat4, quat4} = require("devtools/client/tilt/tilt- var {TargetFactory} = require("devtools/client/framework/target"); Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); +var {gDevTools} = require("devtools/client/framework/devtools"); const ELEMENT_MIN_SIZE = 4; const INVISIBLE_ELEMENTS = { diff --git a/devtools/client/webaudioeditor/includes.js b/devtools/client/webaudioeditor/includes.js index b7911c7ec496..047b7a8a55a8 100644 --- a/devtools/client/webaudioeditor/includes.js +++ b/devtools/client/webaudioeditor/includes.js @@ -8,7 +8,6 @@ var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); const { loader, require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); @@ -23,6 +22,7 @@ const L10N = new ViewHelpers.L10N(STRINGS_URI); const Telemetry = require("devtools/client/shared/telemetry"); const telemetry = new Telemetry(); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); +const { gDevTools } = require("devtools/client/framework/devtools"); loader.lazyRequireGetter(this, "LineGraphWidget", "devtools/client/shared/widgets/LineGraphWidget"); diff --git a/devtools/client/webaudioeditor/test/head.js b/devtools/client/webaudioeditor/test/head.js index a9ba98652d0a..c9c41245ecfa 100644 --- a/devtools/client/webaudioeditor/test/head.js +++ b/devtools/client/webaudioeditor/test/head.js @@ -12,8 +12,8 @@ var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log"); Services.prefs.setBoolPref("devtools.debugger.log", false); var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); -var { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var { gDevTools } = require("devtools/client/framework/devtools"); var { TargetFactory } = require("devtools/client/framework/target"); var { DebuggerServer } = require("devtools/server/main"); var { generateUUID } = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); diff --git a/devtools/client/webconsole/console-commands.js b/devtools/client/webconsole/console-commands.js index 098592b46a2d..7a056d6029ff 100644 --- a/devtools/client/webconsole/console-commands.js +++ b/devtools/client/webconsole/console-commands.js @@ -7,7 +7,7 @@ "use strict"; const l10n = require("gcli/l10n"); -loader.lazyGetter(this, "gDevTools", () => require("resource://devtools/client/framework/gDevTools.jsm").gDevTools); +loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); exports.items = [ { diff --git a/devtools/client/webconsole/console-output.js b/devtools/client/webconsole/console-output.js index f903b8fb43a5..f0f6847758ee 100644 --- a/devtools/client/webconsole/console-output.js +++ b/devtools/client/webconsole/console-output.js @@ -12,11 +12,11 @@ const { Services } = require("resource://gre/modules/Services.jsm"); loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm"); loader.lazyImporter(this, "escapeHTML", "resource://devtools/client/shared/widgets/VariablesView.jsm"); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); loader.lazyImporter(this, "Task", "resource://gre/modules/Task.jsm"); loader.lazyImporter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm"); loader.lazyRequireGetter(this, "promise"); +loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); loader.lazyRequireGetter(this, "TableWidget", "devtools/client/shared/widgets/TableWidget", true); loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/main", true); diff --git a/devtools/client/webconsole/hudservice.js b/devtools/client/webconsole/hudservice.js index c4373f0ede1b..34828bc629af 100644 --- a/devtools/client/webconsole/hudservice.js +++ b/devtools/client/webconsole/hudservice.js @@ -14,13 +14,13 @@ var {TargetFactory} = require("devtools/client/framework/target"); var {Tools} = require("devtools/client/definitions"); var promise = require("promise"); -loader.lazyGetter(this, "Telemetry", () => require("devtools/client/shared/telemetry")); -loader.lazyGetter(this, "WebConsoleFrame", () => require("devtools/client/webconsole/webconsole").WebConsoleFrame); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm"); +loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry"); +loader.lazyRequireGetter(this, "WebConsoleFrame", "devtools/client/webconsole/webconsole", true); +loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true); loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true); -loader.lazyGetter(this, "showDoorhanger", () => require("devtools/client/shared/doorhanger").showDoorhanger); +loader.lazyRequireGetter(this, "showDoorhanger", "devtools/client/shared/doorhanger", true); loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source"); const STRINGS_URI = "chrome://devtools/locale/webconsole.properties"; diff --git a/devtools/client/webconsole/webconsole.js b/devtools/client/webconsole/webconsole.js index 3626684ce3eb..ebf0f24640d1 100644 --- a/devtools/client/webconsole/webconsole.js +++ b/devtools/client/webconsole/webconsole.js @@ -29,8 +29,8 @@ loader.lazyRequireGetter(this, "system", "devtools/shared/system"); loader.lazyRequireGetter(this, "Timers", "sdk/timers"); loader.lazyImporter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm"); loader.lazyImporter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm"); +loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); loader.lazyImporter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm"); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); const STRINGS_URI = "chrome://devtools/locale/webconsole.properties"; var l10n = new WebConsoleUtils.l10n(STRINGS_URI); diff --git a/devtools/client/webide/content/details.js b/devtools/client/webide/content/details.js index 917ed3441d1f..d59e8cd05bd3 100644 --- a/devtools/client/webide/content/details.js +++ b/devtools/client/webide/content/details.js @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var Cu = Components.utils; -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); const {Services} = Cu.import("resource://gre/modules/Services.jsm"); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); const {AppManager} = require("devtools/client/webide/modules/app-manager"); diff --git a/devtools/client/webide/content/logs.js b/devtools/client/webide/content/logs.js index 64f425028361..238da963f34d 100644 --- a/devtools/client/webide/content/logs.js +++ b/devtools/client/webide/content/logs.js @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var Cu = Components.utils; -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); const {AppManager} = require("devtools/client/webide/modules/app-manager"); diff --git a/devtools/client/webide/content/monitor.js b/devtools/client/webide/content/monitor.js index 289094ee3773..99b90da678e6 100644 --- a/devtools/client/webide/content/monitor.js +++ b/devtools/client/webide/content/monitor.js @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var Cu = Components.utils; -Cu.import('resource://devtools/client/framework/gDevTools.jsm'); const {require} = Cu.import('resource://devtools/shared/Loader.jsm', {}); const {Services} = Cu.import('resource://gre/modules/Services.jsm'); const {AppManager} = require('devtools/client/webide/modules/app-manager'); diff --git a/devtools/client/webide/content/webide.js b/devtools/client/webide/content/webide.js index 38bf96a63342..d22548b2241f 100644 --- a/devtools/client/webide/content/webide.js +++ b/devtools/client/webide/content/webide.js @@ -6,10 +6,11 @@ var Cc = Components.classes; var Cu = Components.utils; var Ci = Components.interfaces; -Cu.import("resource://devtools/client/framework/gDevTools.jsm"); Cu.import("resource://gre/modules/Task.jsm"); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); +const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); const {Toolbox} = require("devtools/client/framework/toolbox"); const Services = require("Services"); const {AppProjects} = require("devtools/client/webide/modules/app-projects"); diff --git a/devtools/client/webide/test/head.js b/devtools/client/webide/test/head.js index 6e6667cc5b40..1e7ecc7902d2 100644 --- a/devtools/client/webide/test/head.js +++ b/devtools/client/webide/test/head.js @@ -10,7 +10,7 @@ Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/Task.jsm"); const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -const {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}); +const {gDevTools} = require("devtools/client/framework/devtools"); const promise = require("promise"); const {AppProjects} = require("devtools/client/webide/modules/app-projects"); const DevToolsUtils = require("devtools/shared/DevToolsUtils"); diff --git a/devtools/client/webide/test/test_basic.html b/devtools/client/webide/test/test_basic.html index 544179f5b594..e619a0f06892 100644 --- a/devtools/client/webide/test/test_basic.html +++ b/devtools/client/webide/test/test_basic.html @@ -21,7 +21,7 @@ Task.spawn(function* () { let win = yield openWebIDE(); - const {gDevToolsBrowser} = Cu.import("resource://devtools/client/framework/gDevTools.jsm"); + const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser"); yield gDevToolsBrowser.isWebIDEInitialized.promise; ok(true, "WebIDE was initialized"); diff --git a/devtools/server/actors/animation.js b/devtools/server/actors/animation.js index 47a191033fe8..c95427d1c728 100644 --- a/devtools/server/actors/animation.js +++ b/devtools/server/actors/animation.js @@ -39,6 +39,7 @@ const events = require("sdk/event/core"); const ANIMATION_TYPES = { CSS_ANIMATION: "cssanimation", CSS_TRANSITION: "csstransition", + SCRIPT_ANIMATION: "scriptanimation", UNKNOWN: "unknown" }; exports.ANIMATION_TYPES = ANIMATION_TYPES; @@ -119,19 +120,28 @@ var AnimationPlayerActor = ActorClass({ return data; }, - isAnimation: function(player = this.player) { + isCssAnimation: function(player = this.player) { return player instanceof this.window.CSSAnimation; }, - isTransition: function(player = this.player) { + isCssTransition: function(player = this.player) { return player instanceof this.window.CSSTransition; }, + isScriptAnimation: function(player = this.player) { + return player instanceof this.window.Animation && !( + player instanceof this.window.CSSAnimation || + player instanceof this.window.CSSTransition + ); + }, + getType: function() { - if (this.isAnimation()) { + if (this.isCssAnimation()) { return ANIMATION_TYPES.CSS_ANIMATION; - } else if (this.isTransition()) { + } else if (this.isCssTransition()) { return ANIMATION_TYPES.CSS_TRANSITION; + } else if (this.isScriptAnimation()) { + return ANIMATION_TYPES.SCRIPT_ANIMATION; } return ANIMATION_TYPES.UNKNOWN; @@ -146,9 +156,9 @@ var AnimationPlayerActor = ActorClass({ getName: function() { if (this.player.id) { return this.player.id; - } else if (this.isAnimation()) { + } else if (this.isCssAnimation()) { return this.player.animationName; - } else if (this.isTransition()) { + } else if (this.isCssTransition()) { return this.player.transitionProperty; } @@ -626,9 +636,9 @@ var AnimationsActor = exports.AnimationsActor = ActorClass({ // a "removed" event for the one we already have. let index = this.actors.findIndex(a => { let isSameType = a.player.constructor === player.constructor; - let isSameName = (a.isAnimation() && + let isSameName = (a.isCssAnimation() && a.player.animationName === player.animationName) || - (a.isTransition() && + (a.isCssTransition() && a.player.transitionProperty === player.transitionProperty); let isSameNode = a.player.effect.target === player.effect.target; diff --git a/devtools/server/actors/csscoverage.js b/devtools/server/actors/csscoverage.js index 2aada9da661d..68ecce0cf3f2 100644 --- a/devtools/server/actors/csscoverage.js +++ b/devtools/server/actors/csscoverage.js @@ -12,10 +12,8 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm"); const events = require("sdk/event/core"); const protocol = require("devtools/server/protocol"); const { method, custom, RetVal, Arg } = protocol; +const {gDevTools} = require("devtools/client/framework/devtools"); -loader.lazyGetter(this, "gDevTools", () => { - return require("resource://devtools/client/framework/gDevTools.jsm").gDevTools; -}); loader.lazyGetter(this, "DOMUtils", () => { return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils) }); diff --git a/devtools/server/tests/unit/test_animation_name.js b/devtools/server/tests/unit/test_animation_name.js index 82cf438ee5f8..2f266b6aeff2 100644 --- a/devtools/server/tests/unit/test_animation_name.js +++ b/devtools/server/tests/unit/test_animation_name.js @@ -24,6 +24,9 @@ function run_test() { } }; + window.CSSAnimation.prototype = Object.create(window.Animation.prototype); + window.CSSTransition.prototype = Object.create(window.Animation.prototype); + // Helper to get a mock DOM node. function getMockNode() { return { @@ -46,6 +49,11 @@ function run_test() { animation: new window.Animation(), props: { id: "animation-id" }, expectedName: "animation-id" + }, { + desc: "Animation without an id", + animation: new window.Animation(), + props: {}, + expectedName: "" }, { desc: "CSSTransition with an id", animation: new window.CSSTransition(), diff --git a/devtools/server/tests/unit/test_animation_type.js b/devtools/server/tests/unit/test_animation_type.js index 0d31266c5ffd..e8859a748317 100644 --- a/devtools/server/tests/unit/test_animation_type.js +++ b/devtools/server/tests/unit/test_animation_type.js @@ -24,6 +24,9 @@ function run_test() { } }; + window.CSSAnimation.prototype = Object.create(window.Animation.prototype); + window.CSSTransition.prototype = Object.create(window.Animation.prototype); + // Helper to get a mock DOM node. function getMockNode() { return { @@ -47,6 +50,10 @@ function run_test() { desc: "Test CSSTransition type", animation: new window.CSSTransition(), expectedType: ANIMATION_TYPES.CSS_TRANSITION + }, { + desc: "Test ScriptAnimation type", + animation: new window.Animation(), + expectedType: ANIMATION_TYPES.SCRIPT_ANIMATION }, { desc: "Test unknown type", animation: {effect: {target: getMockNode()}}, diff --git a/devtools/shared/Loader.jsm b/devtools/shared/Loader.jsm index 536e32325c15..cc08f17d4cc8 100644 --- a/devtools/shared/Loader.jsm +++ b/devtools/shared/Loader.jsm @@ -444,7 +444,7 @@ DevToolsLoader.prototype = { setTimeout(() => { let { gBrowser } = window; let target = this.TargetFactory.forTab(gBrowser.selectedTab); - const { gDevTools } = this.require("resource://devtools/client/framework/gDevTools.jsm"); + const { gDevTools } = require("devtools/client/framework/devtools"); gDevTools.showToolbox(target); }, 1000); } else if (location.includes("/webide.xul")) { diff --git a/devtools/shared/gcli/commands/calllog.js b/devtools/shared/gcli/commands/calllog.js index 58b0abafa420..f3c57aca56ef 100644 --- a/devtools/shared/gcli/commands/calllog.js +++ b/devtools/shared/gcli/commands/calllog.js @@ -7,18 +7,11 @@ const { Cc, Ci, Cu } = require("chrome"); const l10n = require("gcli/l10n"); const gcli = require("gcli/index"); +const { gDevTools } = require("devtools/client/framework/devtools"); +const Debugger = require("Debugger"); loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true); -loader.lazyImporter(this, "gDevTools", "resource://devtools/client/framework/gDevTools.jsm"); - -loader.lazyGetter(this, "Debugger", () => { - let global = Cu.getGlobalForObject({}); - let JsDebugger = Cu.import("resource://gre/modules/jsdebugger.jsm", {}); - JsDebugger.addDebuggerToGlobal(global); - return global.Debugger; -}); - var debuggers = []; var chromeDebuggers = []; var sandboxes = []; diff --git a/devtools/shared/gcli/commands/csscoverage.js b/devtools/shared/gcli/commands/csscoverage.js index d893727ed309..7d417b44dc76 100644 --- a/devtools/shared/gcli/commands/csscoverage.js +++ b/devtools/shared/gcli/commands/csscoverage.js @@ -6,8 +6,7 @@ const { Cc, Ci } = require("chrome"); -loader.lazyGetter(this, "gDevTools", () => require("resource://devtools/client/framework/gDevTools.jsm").gDevTools); - +const { gDevTools } = require("devtools/client/framework/devtools"); const domtemplate = require("gcli/util/domtemplate"); const csscoverage = require("devtools/server/actors/csscoverage"); const l10n = csscoverage.l10n; diff --git a/devtools/shared/gcli/source/lib/gcli/l10n.js b/devtools/shared/gcli/source/lib/gcli/l10n.js index afdab932fd95..d9a3cb1bc41d 100644 --- a/devtools/shared/gcli/source/lib/gcli/l10n.js +++ b/devtools/shared/gcli/source/lib/gcli/l10n.js @@ -47,7 +47,7 @@ exports.lookup = function(name) { * l10n:l10n.propertyLookup in the template data and use it * like ${l10n.BLAH} */ -exports.propertyLookup = Proxy.create({ +exports.propertyLookup = new Proxy({}, { get: function(rcvr, name) { return exports.lookup(name); } diff --git a/devtools/shared/gcli/source/lib/gcli/util/l10n.js b/devtools/shared/gcli/source/lib/gcli/util/l10n.js index 569389706919..8532b6961ad5 100644 --- a/devtools/shared/gcli/source/lib/gcli/util/l10n.js +++ b/devtools/shared/gcli/source/lib/gcli/util/l10n.js @@ -71,7 +71,7 @@ exports.lookup = function(key) { }; /** @see propertyLookup in lib/gcli/util/l10n.js */ -exports.propertyLookup = Proxy.create({ +exports.propertyLookup = new Proxy({}, { get: function(rcvr, name) { return exports.lookup(name); } diff --git a/devtools/shared/heapsnapshot/CensusUtils.js b/devtools/shared/heapsnapshot/CensusUtils.js index 200825c44fca..63bf494e211f 100644 --- a/devtools/shared/heapsnapshot/CensusUtils.js +++ b/devtools/shared/heapsnapshot/CensusUtils.js @@ -375,7 +375,7 @@ const createParentMap = exports.createParentMap = function (node, if (node.children) { for (let i = 0, length = node.children.length; i < length; i++) { const child = node.children[i]; - aggregator[getId(child)] = getId(node); + aggregator[getId(child)] = node; createParentMap(child, getId, aggregator); } } diff --git a/devtools/shared/heapsnapshot/HeapAnalysesClient.js b/devtools/shared/heapsnapshot/HeapAnalysesClient.js index 1a2ab23cc949..f8ada1820430 100644 --- a/devtools/shared/heapsnapshot/HeapAnalysesClient.js +++ b/devtools/shared/heapsnapshot/HeapAnalysesClient.js @@ -21,7 +21,7 @@ var workerCounter = 0; const HeapAnalysesClient = module.exports = function () { this._worker = new DevToolsWorker(WORKER_URL, { name: `HeapAnalyses-${workerCounter++}`, - verbose: DevToolsUtils.dumpv.wantLogging + verbose: DevToolsUtils.dumpv.wantVerbose }); }; diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 34d35660bce0..1c9e8aecfc2a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -4,3 +4,4 @@ distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-all.zip +distributionSha256Sum=2ba0aaa11a3e96ec0af31d532d808e1f09cc6dcad0954e637902a1ab544b9e60 diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 0a455191c097..ee2843a52653 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -2,6 +2,12 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +# We call mach -> Make -> gradle -> mach, which races to find and +# create .mozconfig files and to generate targets. +ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +.NOTPARALLEL: +endif + MOZ_BUILDID := $(shell cat $(DEPTH)/config/buildid) # Set the appropriate version code, based on the existance of the @@ -201,9 +207,21 @@ endif # MOZ_INSTALL_TRACKING library_jars := $(subst $(NULL) ,:,$(strip $(library_jars))) +gradle_dir := $(topobjdir)/gradle/build/mobile/android + +ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +.gradle.deps: .aapt.deps FORCE + @$(TOUCH) $@ + $(topsrcdir)/mach gradle --no-daemon --offline app:dexAutomationDebug app:assembleAutomationDebugAndroidTest -x lint + +classes.dex: .gradle.deps + $(REPORT_BUILD) + cp $(gradle_dir)/app/intermediates/dex/automation/debug/classes.dex $@ +else classes.dex: .proguard.deps $(REPORT_BUILD) $(DX) --dex --output=classes.dex jars-proguarded +endif ifdef MOZ_DISABLE_PROGUARD PROGUARD_PASSES=0 @@ -501,8 +519,13 @@ endef # .aapt.deps: $(all_resources) $(eval $(call aapt_command,.aapt.deps,$(all_resources),gecko.ap_,generated/,./)) -# .aapt.nodeps: $(abspath $(CURDIR)/AndroidManifest.xml) FORCE -$(eval $(call aapt_command,.aapt.nodeps,$(abspath $(CURDIR)/AndroidManifest.xml) FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/)) +ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +.aapt.nodeps: FORCE + cp $(gradle_dir)/app/intermediates/res/resources-automation-debug.ap_ gecko-nodeps.ap_ +else +# .aapt.nodeps: $(CURDIR)/AndroidManifest.xml FORCE +$(eval $(call aapt_command,.aapt.nodeps,$(CURDIR)/AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/)) +endif # Override the Java settings with some specific android settings include $(topsrcdir)/config/android-common.mk @@ -532,7 +555,14 @@ gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f)) gradle-targets: $(abspath AndroidManifest.xml) gradle-targets: $(ANDROID_GENERATED_RESFILES) -gradle-omnijar: $(ABS_DIST)/fennec/$(OMNIJAR_NAME) +ifndef MOZILLA_OFFICIAL +# Local developers update omni.ja during their builds. There's a +# chicken-and-egg problem here. +gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME)) +else +# In automation, omni.ja is built only during packaging. +gradle-omnijar: +endif .PHONY: gradle-targets gradle-omnijar @@ -543,8 +573,8 @@ endif # GeneratedJNIWrappers.cpp target also generates # GeneratedJNIWrappers.h and GeneratedJNINatives.h -libs:: classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp $(CURDIR)/fennec_ids.txt - $(INSTALL) classes.dex $(FINAL_TARGET) +ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +libs:: jni-stubs.inc GeneratedJNIWrappers.cpp @(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && \ diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null && \ diff GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h >/dev/null && \ @@ -558,3 +588,9 @@ libs:: classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp $(CURDIR)/fennec_ids.t echo '* Repeat the build, and check in any changes. *' && \ echo '*****************************************************' && \ exit 1) +endif + +libs:: $(CURDIR)/fennec_ids.txt + +libs:: classes.dex + $(INSTALL) classes.dex $(FINAL_TARGET) diff --git a/mobile/android/base/java/org/mozilla/gecko/db/URLMetadataTable.java b/mobile/android/base/java/org/mozilla/gecko/db/URLMetadataTable.java index 664005f8a726..4ba45f677d7e 100644 --- a/mobile/android/base/java/org/mozilla/gecko/db/URLMetadataTable.java +++ b/mobile/android/base/java/org/mozilla/gecko/db/URLMetadataTable.java @@ -57,6 +57,7 @@ public class URLMetadataTable extends BaseTable { // This table was added in v21 of the db. Force its creation if we're coming from an earlier version if (newVersion >= 21 && oldVersion < 21) { onCreate(db); + return; } // Removed the redundant metadata_url_idx index in version 26 diff --git a/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java b/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java index 5db1f5d817c1..2e6bd6cc23ff 100644 --- a/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java +++ b/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java @@ -269,6 +269,57 @@ public class DateTimePicker extends FrameLayout { Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight); } + // Set the min / max attribute. + try { + if (minDateValue != null && !minDateValue.equals("")) { + mMinDate.setTime(new SimpleDateFormat(dateFormat).parse(minDateValue)); + } else { + mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); + } + } catch (Exception ex) { + Log.e(LOGTAG, "Error parsing format sting: " + ex); + mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); + } + + try { + if (maxDateValue != null && !maxDateValue.equals("")) { + mMaxDate.setTime(new SimpleDateFormat(dateFormat).parse(maxDateValue)); + } else { + mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); + } + } catch (Exception ex) { + Log.e(LOGTAG, "Error parsing format string: " + ex); + mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); + } + + // Find the initial date from the constructor arguments. + try { + if (!dateTimeValue.equals("")) { + mTempDate.setTime(new SimpleDateFormat(dateFormat).parse(dateTimeValue)); + } else { + mTempDate.setTimeInMillis(System.currentTimeMillis()); + } + } catch (Exception ex) { + Log.e(LOGTAG, "Error parsing format string: " + ex); + mTempDate.setTimeInMillis(System.currentTimeMillis()); + } + + if (mMaxDate.before(mMinDate)) { + // If the input date range is illogical/garbage, we should not restrict the input range (i.e. allow the + // user to select any date). If we try to make any assumptions based on the illogical min/max date we could + // potentially prevent the user from selecting dates that are in the developers intended range, so it's best + // to allow anything. + mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); + mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); + } + + // mTempDate will either be a site-supplied value, or today's date otherwise. CalendarView implementations can + // crash if they're supplied an invalid date (i.e. a date not in the specified range), hence we need to set + // a sensible default date here. + if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) { + mTempDate.setTimeInMillis(mMinDate.getTimeInMillis()); + } + // If we're displaying a date, the screen is wide enough // (and if we're using an SDK where the calendar view exists) // then display a calendar. @@ -312,41 +363,6 @@ public class DateTimePicker extends FrameLayout { mCalendar = null; } - // Find the initial date from the constructor arguments. - try { - if (!dateTimeValue.equals("")) { - mTempDate.setTime(new SimpleDateFormat(dateFormat).parse(dateTimeValue)); - } else { - mTempDate.setTimeInMillis(System.currentTimeMillis()); - } - } catch (Exception ex) { - Log.e(LOGTAG, "Error parsing format string: " + ex); - mTempDate.setTimeInMillis(System.currentTimeMillis()); - } - - // Set the min / max attribute. - try { - if (minDateValue != null && !minDateValue.equals("")) { - mMinDate.setTime(new SimpleDateFormat(dateFormat).parse(minDateValue)); - } else { - mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); - } - } catch (Exception ex) { - Log.e(LOGTAG, "Error parsing format sting: " + ex); - mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); - } - - try { - if (maxDateValue != null && !maxDateValue.equals("")) { - mMaxDate.setTime(new SimpleDateFormat(dateFormat).parse(maxDateValue)); - } else { - mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); - } - } catch (Exception ex) { - Log.e(LOGTAG, "Error parsing format string: " + ex); - mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); - } - // Initialize all spinners. mDaySpinner = setupSpinner(R.id.day, 1, mTempDate.get(Calendar.DAY_OF_MONTH)); diff --git a/mobile/android/base/locales/en-US/sync_strings.dtd b/mobile/android/base/locales/en-US/sync_strings.dtd index 079a8d833aae..f8cc009e5cbd 100644 --- a/mobile/android/base/locales/en-US/sync_strings.dtd +++ b/mobile/android/base/locales/en-US/sync_strings.dtd @@ -8,72 +8,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mobile/android/mach_commands.py b/mobile/android/mach_commands.py index 329ca25e502e..11cafbdcbbbb 100644 --- a/mobile/android/mach_commands.py +++ b/mobile/android/mach_commands.py @@ -21,16 +21,6 @@ from mach.decorators import ( Command, ) -SUCCESS = ''' -You should be ready to build with Gradle and import into IntelliJ! Test with - - ./mach gradle build - -and in IntelliJ select File > Import project... and choose - - {topobjdir}/mobile/android/gradle -''' - # NOTE python/mach/mach/commands/commandinfo.py references this function # by name. If this function is renamed or removed, that file should diff --git a/mobile/android/moz.build b/mobile/android/moz.build index 049293ed682d..d7d6eb6f2af0 100644 --- a/mobile/android/moz.build +++ b/mobile/android/moz.build @@ -31,8 +31,9 @@ if CONFIG['MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER']: DIRS += ['../../xulrunner/tools/redit'] -TEST_DIRS += [ - 'tests', -] +if not CONFIG['MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE']: + TEST_DIRS += [ + 'tests', + ] SPHINX_TREES['fennec'] = 'docs' diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java index 87505470d48b..008fc7ccbe63 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java @@ -213,6 +213,9 @@ public class FxAccountStatusFragment syncNowPreference = ensureFindPreference("sync_now"); syncNowPreference.setEnabled(true); syncNowPreference.setOnPreferenceClickListener(this); + + ensureFindPreference("linktos").setOnPreferenceClickListener(this); + ensureFindPreference("linkprivacy").setOnPreferenceClickListener(this); } /** @@ -294,6 +297,16 @@ public class FxAccountStatusFragment return true; } + if (TextUtils.equals("linktos", preference.getKey())) { + ActivityUtils.openURLInFennec(getActivity().getApplicationContext(), getResources().getString(R.string.fxaccount_link_tos)); + return true; + } + + if (TextUtils.equals("linkprivacy", preference.getKey())) { + ActivityUtils.openURLInFennec(getActivity().getApplicationContext(), getResources().getString(R.string.fxaccount_link_pn)); + return true; + } + return false; } diff --git a/mobile/android/services/src/main/res/xml/fxaccount_status_prefscreen.xml b/mobile/android/services/src/main/res/xml/fxaccount_status_prefscreen.xml index 51138a4c37c2..570e362cc2dd 100644 --- a/mobile/android/services/src/main/res/xml/fxaccount_status_prefscreen.xml +++ b/mobile/android/services/src/main/res/xml/fxaccount_status_prefscreen.xml @@ -114,20 +114,16 @@ - - - - - - + + diff --git a/mobile/android/services/strings.xml.in b/mobile/android/services/strings.xml.in index bd971d67e4d0..b84e5e601934 100644 --- a/mobile/android/services/strings.xml.in +++ b/mobile/android/services/strings.xml.in @@ -2,105 +2,31 @@ - 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/. --> - - &brandShortName; + +&brandShortName; - &sync.app.name.label; - &sync.title.adddevice.label; - &sync.title.pair.label; + +&sync.configure.engines.title.passwords2; +&sync.configure.engines.title.history; +&sync.configure.engines.title.tabs; - - &sync.subtitle.header2.label; - &sync.subtitle.connectlocation2.label; - &sync.pair.connectlocation.label; - &sync.pin.oneline.label; - &sync.link.show.label; - &sync.link.advancedsetup.label; + +&bookmarks.folder.menu.label; +&bookmarks.folder.places.label; +&bookmarks.folder.tags.label; +&bookmarks.folder.toolbar.label; +&bookmarks.folder.unfiled.label; +&bookmarks.folder.desktop.label; +&bookmarks.folder.mobile.label; +&bookmarks.folder.readinglist.label; +&bookmarks.folder.pinned.label; - - - &sync.jpake.subtitle.waiting.label; - - - &sync.subtitle.account.label; - &sync.input.username.label; - &sync.input.password.label; - &sync.input.key.label; - &sync.checkbox.server.label; - &sync.input.server.label; - - - &sync.title.fail.label; - &sync.subtitle.fail.label; - &sync.button.tryagain.label; - &sync.button.manual.label; - &sync.subtitle.nointernet.label; - &sync.subtitle.failaccount.label; - &sync.subtitle.failmultiple.label; - - - &sync.title.success.label; - &sync.subtitle.success.label1; - &sync.settings.label; - &sync.subtitle.manage.label1; - - - &sync.pair.tryagain.label; - - - &sync.settings.options.label; - &sync.summary.pair.label; - - - &sync.configure.engines.title.label; - &sync.configure.engines.sync.my.title.label; - &sync.configure.engines.title.bookmarks; - &sync.configure.engines.title.passwords2; - &sync.configure.engines.title.history; - &sync.configure.engines.title.tabs; - - - &sync.button.cancel.label; - &sync.button.connect.label; - &sync.button.ok.label; - - - &sync.account.label; - - - &bookmarks.folder.menu.label; - &bookmarks.folder.places.label; - &bookmarks.folder.tags.label; - &bookmarks.folder.toolbar.label; - &bookmarks.folder.unfiled.label; - &bookmarks.folder.desktop.label; - &bookmarks.folder.mobile.label; - &bookmarks.folder.readinglist.label; - &bookmarks.folder.pinned.label; - - - &sync.notification.oneaccount.label; - &sync.notification.configure.saved; - - - &sync.invalidcreds.label; - &sync.invalidserver.label; - &sync.verifying.label; - &sync.new.recoverykey.status.incorrect; - - - &new_tab; - &sync.title.send.tab.label; - &sync.button.send.label; - &sync.button.set.up.sync.label; - &sync.title.redirect.to.set.up.sync.label; - &sync.text.redirect.to.set.up.sync.label; - &sync.text.tab.sent.label; - &sync.text.tab.not.sent.label; - &sync.default.client.name; - -@ANDROID_PACKAGE_NAME@ -@ANDROID_PACKAGE_NAME@.App + +&sync.title.redirect.to.set.up.sync.label; +&sync.text.redirect.to.set.up.sync.label; +&sync.text.tab.sent.label; +&sync.text.tab.not.sent.label; +&sync.default.client.name; diff --git a/python/mozbuild/mozbuild/mozconfig.py b/python/mozbuild/mozbuild/mozconfig.py index 2e829422d8d8..a60b79774dd3 100644 --- a/python/mozbuild/mozbuild/mozconfig.py +++ b/python/mozbuild/mozbuild/mozconfig.py @@ -107,7 +107,7 @@ class MozconfigLoader(ProcessExecutionMixin): if 'MOZ_MYCONFIG' in env: raise MozconfigFindException(MOZ_MYCONFIG_ERROR) - env_path = env.get('MOZCONFIG', None) + env_path = env.get('MOZCONFIG', None) or None if env_path is not None: if not os.path.isabs(env_path): potential_roots = [self.topsrcdir, os.getcwd()] diff --git a/testing/instrumentation/Makefile.in b/testing/instrumentation/Makefile.in index 6b1c225c87b2..0ccb15a2c8f3 100644 --- a/testing/instrumentation/Makefile.in +++ b/testing/instrumentation/Makefile.in @@ -14,10 +14,12 @@ include $(topsrcdir)/config/android-common.mk stage-package: $(NSINSTALL) -D $(_DEST_DIR) +ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE $(call RELEASE_SIGN_ANDROID_APK,\ $(DEPTH)/mobile/android/tests/background/junit3/background-junit3-debug-unsigned-unaligned.apk,\ $(_DEST_DIR)/background-junit3.apk) $(call RELEASE_SIGN_ANDROID_APK,\ $(DEPTH)/mobile/android/tests/browser/junit3/browser-junit3-debug-unsigned-unaligned.apk,\ $(_DEST_DIR)/browser-junit3.apk) +endif @(cd $(DEPTH)/_tests/ && tar $(TAR_CREATE_FLAGS) - instrumentation) | (cd $(PKG_STAGE) && tar -xf -) diff --git a/testing/mochitest/Makefile.in b/testing/mochitest/Makefile.in index e4eedf120bfa..a0448dcd7bb9 100644 --- a/testing/mochitest/Makefile.in +++ b/testing/mochitest/Makefile.in @@ -107,11 +107,15 @@ $(_DEST_DIR): ifeq ($(MOZ_BUILD_APP),mobile/android) include $(topsrcdir)/config/android-common.mk +ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +robocop_apk := $(topobjdir)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk +else +robocop_apk := $(topobjdir)/gradle/build/mobile/android/app/outputs/apk/app-automation-debug-androidTest-unaligned.apk +endif + stage-package-android: $(NSINSTALL) -D $(_DEST_DIR) - $(call RELEASE_SIGN_ANDROID_APK,\ - $(DEPTH)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk,\ - $(_DEST_DIR)/robocop.apk) + $(call RELEASE_SIGN_ANDROID_APK,$(robocop_apk),$(_DEST_DIR)/robocop.apk) stage-package: stage-package-android endif diff --git a/toolkit/components/extensions/ext-webRequest.js b/toolkit/components/extensions/ext-webRequest.js index 2e205315bef7..e3bc693a31b5 100644 --- a/toolkit/components/extensions/ext-webRequest.js +++ b/toolkit/components/extensions/ext-webRequest.js @@ -41,6 +41,10 @@ function WebRequestEventManager(context, eventName) { parentFrameId: ExtensionManagement.getParentFrameId(data.parentWindowId, data.windowId), }; + if ("ip" in data) { + data2.ip = data.ip; + } + // Fills in tabId typically. let result = {}; extensions.emit("fill-browser-data", data.browser, data2, result); diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html b/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html index a4b3562ab942..2c578a5592e9 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html @@ -87,6 +87,7 @@ function compareLists(list1, list2, kind) { function backgroundScript() { const BASE = "http://mochi.test:8888/tests/toolkit/components/extensions/test/mochitest"; + let checkCompleted = true; let savedTabId = -1; function checkType(details) { @@ -197,15 +198,36 @@ function backgroundScript() { } } + let completedUrls = { + responseStarted: new Set(), + completed: new Set(), + }; + + function checkIpAndRecord(kind, details) { + onRecord(kind, details); + + // When resources are cached, the ip property is not present, + // so only check for the ip property the first time around. + if (checkCompleted && !completedUrls[kind].has(details.url)) { + browser.test.assertEq(details.ip, "127.0.0.1", "correct ip"); + completedUrls[kind].add(details.url); + } + } + browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: [""]}, ["blocking"]); browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, {urls: [""]}, ["blocking"]); browser.webRequest.onSendHeaders.addListener(onRecord.bind(null, "sendHeaders"), {urls: [""]}); browser.webRequest.onBeforeRedirect.addListener(onBeforeRedirect, {urls: [""]}); - browser.webRequest.onResponseStarted.addListener(onRecord.bind(null, "responseStarted"), {urls: [""]}); - browser.webRequest.onCompleted.addListener(onRecord.bind(null, "completed"), {urls: [""]}); + browser.webRequest.onResponseStarted.addListener(checkIpAndRecord.bind(null, "responseStarted"), {urls: [""]}); + browser.webRequest.onCompleted.addListener(checkIpAndRecord.bind(null, "completed"), {urls: [""]}); - function onTestMessage() { - browser.test.sendMessage("results", recorded); + function onTestMessage(msg) { + if (msg == "skipCompleted") { + checkCompleted = false; + browser.test.sendMessage("ackSkipCompleted"); + } else { + browser.test.sendMessage("results", recorded); + } } browser.test.onMessage.addListener(onTestMessage); @@ -213,7 +235,7 @@ function backgroundScript() { browser.test.sendMessage("ready", browser.webRequest.ResourceType); } -function* test_once() { +function* test_once(skipCompleted) { let extensionData = { manifest: { permissions: [ @@ -228,6 +250,11 @@ function* test_once() { let [, resourceTypes] = yield Promise.all([extension.startup(), extension.awaitMessage("ready")]); info("webrequest extension loaded"); + if (skipCompleted) { + extension.sendMessage("skipCompleted"); + yield extension.awaitMessage("ackSkipCompleted"); + } + for (let key in resourceTypes) { let value = resourceTypes[key]; is(key, value.toUpperCase()); @@ -278,8 +305,8 @@ function* test_once() { } // Run the test twice to make sure it works with caching. -add_task(test_once); -add_task(test_once); +add_task(function*() { yield test_once(false); }); +add_task(function*() { yield test_once(true); }); diff --git a/toolkit/components/places/PlacesDBUtils.jsm b/toolkit/components/places/PlacesDBUtils.jsm index 49332a1bfece..4d2cabd42dee 100644 --- a/toolkit/components/places/PlacesDBUtils.jsm +++ b/toolkit/components/places/PlacesDBUtils.jsm @@ -854,27 +854,15 @@ this.PlacesDBUtils = { }, /** - * Collects telemetry data. - * - * There are essentially two modes of collection and the mode is - * determined by the presence of aHealthReportCallback. If - * aHealthReportCallback is not defined (the default) then we are in - * "Telemetry" mode. Results will be reported to Telemetry. If we are - * in "Health Report" mode only the probes with a true healthreport - * flag will be collected and the results will be reported to the - * aHealthReportCallback. + * Collects telemetry data and reports it to Telemetry. * * @param [optional] aTasks * Tasks object to execute. - * @param [optional] aHealthReportCallback - * Function to receive data relevant for Firefox Health Report. */ - telemetry: function PDBU_telemetry(aTasks, aHealthReportCallback=null) + telemetry: function PDBU_telemetry(aTasks) { let tasks = new Tasks(aTasks); - let isTelemetry = !aHealthReportCallback; - // This will be populated with one integer property for each probe result, // using the histogram name as key. let probeValues = {}; @@ -891,19 +879,15 @@ this.PlacesDBUtils = { // histogram. If a query is also present, its result is passed // as the first argument of the function. If the function // raises an exception, no data is added to the histogram. - // healthreport: Boolean indicating whether this probe is relevant - // to Firefox Health Report. // // Since all queries are executed in order by the database backend, the // callbacks can also use the result of previous queries stored in the // probeValues object. let probes = [ { histogram: "PLACES_PAGES_COUNT", - healthreport: true, query: "SELECT count(*) FROM moz_places" }, { histogram: "PLACES_BOOKMARKS_COUNT", - healthreport: true, query: `SELECT count(*) FROM moz_bookmarks b JOIN moz_bookmarks t ON t.id = b.parent AND t.parent <> :tags_folder @@ -989,15 +973,9 @@ this.PlacesDBUtils = { places_root: PlacesUtils.placesRootId }; - let outstandingProbes = []; - for (let i = 0; i < probes.length; i++) { let probe = probes[i]; - if (!isTelemetry && !probe.healthreport) { - continue; - } - let promiseDone = new Promise((resolve, reject) => { if (!("query" in probe)) { resolve([probe]); @@ -1027,7 +1005,7 @@ this.PlacesDBUtils = { // Report the result of the probe through Telemetry. // The resulting promise cannot reject. - promiseDone = promiseDone.then( + promiseDone.then( // On success ([aProbe, aValue]) => { let value = aValue; @@ -1045,14 +1023,6 @@ this.PlacesDBUtils = { }, // On failure this._handleError); - - outstandingProbes.push(promiseDone); - } - - if (aHealthReportCallback) { - Promise.all(outstandingProbes).then(() => - aHealthReportCallback(probeValues) - ); } PlacesDBUtils._executeTasks(tasks); diff --git a/toolkit/components/places/tests/unit/test_telemetry.js b/toolkit/components/places/tests/unit/test_telemetry.js index 62d704780cea..ea8132d715d2 100644 --- a/toolkit/components/places/tests/unit/test_telemetry.js +++ b/toolkit/components/places/tests/unit/test_telemetry.js @@ -124,18 +124,3 @@ add_task(function* test_execute() do_check_true(snapshot.counts.reduce((a, b) => a + b) > 0); } }); - -add_test(function test_healthreport_callback() { - Services.prefs.clearUserPref("places.database.lastMaintenance"); - PlacesDBUtils.telemetry(null, function onResult(data) { - do_check_neq(data, null); - - do_check_eq(Object.keys(data).length, 2); - do_check_eq(data.PLACES_PAGES_COUNT, 1); - do_check_eq(data.PLACES_BOOKMARKS_COUNT, 1); - - do_check_true(!Services.prefs.prefHasUserValue("places.database.lastMaintenance")); - run_next_test(); - }); -}); - diff --git a/toolkit/components/thumbnails/test/browser.ini b/toolkit/components/thumbnails/test/browser.ini index 72fb1e7a35f8..dad8d145c833 100644 --- a/toolkit/components/thumbnails/test/browser.ini +++ b/toolkit/components/thumbnails/test/browser.ini @@ -13,14 +13,13 @@ support-files = [browser_thumbnails_bg_crash_during_capture.js] skip-if = buildapp == 'mulet' || !crashreporter || e10s # crashing the remote thumbnailer crashes the remote test tab [browser_thumbnails_bg_crash_while_idle.js] -skip-if = buildapp == 'mulet' || !crashreporter || e10s +skip-if = buildapp == 'mulet' || !crashreporter [browser_thumbnails_bg_basic.js] [browser_thumbnails_bg_queueing.js] [browser_thumbnails_bg_timeout.js] [browser_thumbnails_bg_redirect.js] [browser_thumbnails_bg_destroy_browser.js] [browser_thumbnails_bg_no_cookies_sent.js] -skip-if = e10s # e10s cookie problems [browser_thumbnails_bg_no_cookies_stored.js] [browser_thumbnails_bg_no_auth_prompt.js] [browser_thumbnails_bg_no_alert.js] @@ -29,10 +28,8 @@ skip-if = e10s # e10s cookie problems [browser_thumbnails_bug726727.js] skip-if = buildapp == 'mulet' [browser_thumbnails_bug727765.js] -skip-if = e10s # tries to open crypto/local file from the child [browser_thumbnails_bug818225.js] [browser_thumbnails_capture.js] -skip-if = e10s # tries to call drawWindow with a remote browser. [browser_thumbnails_expiration.js] [browser_thumbnails_privacy.js] [browser_thumbnails_redirect.js] diff --git a/toolkit/content/aboutSupport.js b/toolkit/content/aboutSupport.js index b3594adbb867..14663c89934d 100644 --- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -37,6 +37,7 @@ var snapshotFormatters = { application: function application(data) { $("application-box").textContent = data.name; $("useragent-box").textContent = data.userAgent; + $("osarch-box").textContent = data.osVersion + " " + data.arch; $("supportLink").href = data.supportURL; let version = AppConstants.MOZ_APP_VERSION_DISPLAY; if (data.vendor) diff --git a/toolkit/content/aboutSupport.xhtml b/toolkit/content/aboutSupport.xhtml index 625f746ada27..46144461fab8 100644 --- a/toolkit/content/aboutSupport.xhtml +++ b/toolkit/content/aboutSupport.xhtml @@ -130,6 +130,15 @@ + + + &aboutSupport.appBasicsOS; + + + + + + #ifdef XP_WIN diff --git a/toolkit/locales/en-US/chrome/global/aboutSupport.dtd b/toolkit/locales/en-US/chrome/global/aboutSupport.dtd index fcda5cd90831..13dda60d9103 100644 --- a/toolkit/locales/en-US/chrome/global/aboutSupport.dtd +++ b/toolkit/locales/en-US/chrome/global/aboutSupport.dtd @@ -54,6 +54,7 @@ Windows/Mac use the term "Folder" instead of "Directory" --> + diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index e364a0555dd8..b8a287575808 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -178,8 +178,14 @@ this.Troubleshoot = { var dataProviders = { application: function application(done) { + + let sysInfo = Cc["@mozilla.org/system-info;1"]. + getService(Ci.nsIPropertyBag2); + let data = { name: Services.appinfo.name, + osVersion: sysInfo.getProperty("name") + " " + sysInfo.getProperty("version"), + arch: sysInfo.getProperty("arch"), version: AppConstants.MOZ_APP_VERSION_DISPLAY, buildID: Services.appinfo.appBuildID, userAgent: Cc["@mozilla.org/network/protocol;1?name=http"]. diff --git a/toolkit/modules/addons/WebRequest.jsm b/toolkit/modules/addons/WebRequest.jsm index 99c3382cf8f0..3937e53b099a 100644 --- a/toolkit/modules/addons/WebRequest.jsm +++ b/toolkit/modules/addons/WebRequest.jsm @@ -333,6 +333,15 @@ HttpObserverManager = { windowId: loadInfo ? loadInfo.outerWindowID : 0, parentWindowId: loadInfo ? loadInfo.parentOuterWindowID : 0, }; + + let httpChannel = channel.QueryInterface(Ci.nsIHttpChannelInternal); + try { + data.ip = httpChannel.remoteAddress; + } catch (e) { + // The remoteAddress getter throws if the address is unavailable, + // but ip is an optional property so just ignore the exception. + } + if (extraData) { Object.assign(data, extraData); } diff --git a/toolkit/modules/tests/browser/browser_Troubleshoot.js b/toolkit/modules/tests/browser/browser_Troubleshoot.js index 49cb92de82a0..53d055ef589f 100644 --- a/toolkit/modules/tests/browser/browser_Troubleshoot.js +++ b/toolkit/modules/tests/browser/browser_Troubleshoot.js @@ -112,6 +112,14 @@ const SNAPSHOT_SCHEMA = { required: true, type: "string", }, + osVersion: { + required: true, + type: "string", + }, + arch: { + required: true, + type: "string", + }, vendor: { type: "string", }, diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 4ea3767e1606..cf7cd7a98603 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -4213,8 +4213,9 @@ this.XPIProvider = { * @return true if enabling the add-on should block e10s */ isBlockingE10s: function(aAddon) { - // Only extensions change behaviour - if (aAddon.type != "extension") + if (aAddon.type != "extension" && + aAddon.type != "webextension" && + aAddon.type != "theme") return false; // The hotfix is exempt @@ -4222,6 +4223,11 @@ this.XPIProvider = { if (hotfixID && hotfixID == aAddon.id) return false; + // The default theme is exempt + if (aAddon.type == "theme" && + aAddon.internalName == XPIProvider.defaultSkin) + return false; + // System add-ons are exempt let locName = aAddon._installLocation ? aAddon._installLocation.name : undefined; diff --git a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js index e9ca852ceb76..a08ac34982d2 100644 --- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js +++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js @@ -1404,8 +1404,10 @@ this.XPIDatabase = { for (let [, addon] of this.addonDB) { let active = (addon.visible && !addon.disabled && !addon.pendingUninstall); - if (active && XPIProvider.isBlockingE10s(addon)) + if (active && XPIProvider.isBlockingE10s(addon)) { blockE10s = true; + break; + } } Preferences.set(PREF_E10S_BLOCKED_BY_ADDONS, blockE10s); }, diff --git a/toolkit/mozapps/installer/upload-files.mk b/toolkit/mozapps/installer/upload-files.mk index 9cfe53c11c34..d4297fa3fd8c 100644 --- a/toolkit/mozapps/installer/upload-files.mk +++ b/toolkit/mozapps/installer/upload-files.mk @@ -325,13 +325,18 @@ UPLOAD_EXTRA_FILES += geckoview_library/geckoview_assets.zip # Robocop/Robotium tests, Android Background tests, and Fennec need to # be signed with the same key, which means release signing them all. -ROBOCOP_PATH = $(topobjdir)/mobile/android/tests/browser/robocop +ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +robocop_apk := $(topobjdir)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk +else +robocop_apk := $(topobjdir)/gradle/build/mobile/android/app/outputs/apk/app-automation-debug-androidTest-unaligned.apk +endif + # Normally, $(NSINSTALL) would be used instead of cp, but INNER_ROBOCOP_PACKAGE # is used in a series of commands that run under a "cd something", while # $(NSINSTALL) is relative. INNER_ROBOCOP_PACKAGE= \ cp $(GECKO_APP_AP_PATH)/fennec_ids.txt $(ABS_DIST) && \ - $(call RELEASE_SIGN_ANDROID_APK,$(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk,$(ABS_DIST)/robocop.apk) + $(call RELEASE_SIGN_ANDROID_APK,$(robocop_apk),$(ABS_DIST)/robocop.apk) endif else INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you' @@ -470,6 +475,15 @@ PKG_SUFFIX = .apk INNER_SZIP_LIBRARIES = \ $(if $(ALREADY_SZIPPED),,$(foreach lib,$(SZIP_LIBRARIES),host/bin/szip $(MOZ_SZIP_FLAGS) $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(lib) && )) true +ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE +INNER_CHECK_R_TXT=echo 'No R.txt checking for you!' +else +INNER_CHECK_R_TXT=\ + ((test ! -f $(GECKO_APP_AP_PATH)/R.txt && echo "*** Warning: The R.txt that is being packaged might not agree with the R.txt that was built. This is normal during l10n repacks.") || \ + diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \ + (echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1)) +endif + # Insert $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex into # $(ABS_DIST)/gecko.ap_, producing $(ABS_DIST)/gecko.apk. INNER_MAKE_APK = \ @@ -490,13 +504,11 @@ INNER_MAKE_APK = \ $(ZIPALIGN) -f -v 4 $(ABS_DIST)/gecko.apk $(PACKAGE) ifeq ($(MOZ_BUILD_APP),mobile/android) -INNER_MAKE_PACKAGE = \ +INNER_MAKE_PACKAGE = \ $(INNER_SZIP_LIBRARIES) && \ make -C $(GECKO_APP_AP_PATH) gecko-nodeps.ap_ && \ cp $(GECKO_APP_AP_PATH)/gecko-nodeps.ap_ $(ABS_DIST)/gecko.ap_ && \ - ( (test ! -f $(GECKO_APP_AP_PATH)/R.txt && echo "*** Warning: The R.txt that is being packaged might not agree with the R.txt that was built. This is normal during l10n repacks.") || \ - diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \ - (echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1)) && \ + $(INNER_CHECK_R_TXT) && \ $(INNER_MAKE_APK) && \ $(INNER_ROBOCOP_PACKAGE) && \ $(INNER_INSTALL_BOUNCER_PACKAGE) && \ @@ -505,7 +517,7 @@ INNER_MAKE_PACKAGE = \ endif ifeq ($(MOZ_BUILD_APP),mobile/android/b2gdroid) -INNER_MAKE_PACKAGE = \ +INNER_MAKE_PACKAGE = \ $(INNER_SZIP_LIBRARIES) && \ cp $(topobjdir)/mobile/android/b2gdroid/app/classes.dex $(ABS_DIST)/classes.dex && \ cp $(topobjdir)/mobile/android/b2gdroid/app/b2gdroid-unsigned-unaligned.apk $(ABS_DIST)/gecko.ap_ && \