diff --git a/Makefile.in b/Makefile.in index 078ac34edf90..66da95c0b1de 100644 --- a/Makefile.in +++ b/Makefile.in @@ -218,7 +218,6 @@ MAKE_SYM_STORE_ARGS += --install-manifest=$(DEPTH)/_build_manifests/install/dist SYM_STORE_SOURCE_DIRS := $(topsrcdir) -ifndef JS_STANDALONE include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk ifdef MOZ_SYMBOLS_EXTRA_BUILDID @@ -261,7 +260,6 @@ ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE else $(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip' endif -endif # MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment. # exporting it makes make run its $(shell) command for each invoked submake, diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 2e8eb1772986..7a985f808c23 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 6d3a777a6b53..3f498c2b7547 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 843ffd458fe1..d6ac976e0c1d 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 7d85b5ab452a..552af1c445a7 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index cfc151effcac..bbdeb62b2376 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 0657c914e349..5813adda4b64 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 843ffd458fe1..d6ac976e0c1d 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 80e55b7582e7..4aa3349c02f1 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 0eed58ed1ce6..d49718b799b3 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "9f665863ea9c3dd9585905ef002e8fa06713d820", + "git_revision": "ce8365a8d3867bc0661a1627aaa2cda51d1f7c05", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "9f635ea7f4ca6be790a3912220fbcd5da25cbefa", + "revision": "3bdee71faf41c858d77aeb084e5ca6cccaef349b", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/nexus-4-kk/sources.xml b/b2g/config/nexus-4-kk/sources.xml index 3dd540405439..8b3747bf22de 100644 --- a/b2g/config/nexus-4-kk/sources.xml +++ b/b2g/config/nexus-4-kk/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index ac7dcd683da5..71b618c6ad6b 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 509c736bdb9d..1ee03fdfef61 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -21,7 +21,7 @@ - + diff --git a/b2g/gaia/Makefile.in b/b2g/gaia/Makefile.in index 2ba440f46c8a..99925c930aed 100644 --- a/b2g/gaia/Makefile.in +++ b/b2g/gaia/Makefile.in @@ -19,4 +19,4 @@ include $(topsrcdir)/config/rules.mk libs:: +$(MAKE) -j1 -C $(GAIADIR) clean +$(GAIA_OPTIONS) $(MAKE) -j1 -C $(GAIADIR) profile - (cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -) + (cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(ABS_DIST)/bin/$(GAIA_PATH) && tar -xf -) diff --git a/b2g/locales/Makefile.in b/b2g/locales/Makefile.in index dd8df0382805..577ee30875b9 100644 --- a/b2g/locales/Makefile.in +++ b/b2g/locales/Makefile.in @@ -19,8 +19,8 @@ PWD := $(CURDIR) # pulls. You may override them if you provide your own files. You _must_ # override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not # work in that case. -ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE) -WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe +ZIP_IN ?= $(ABS_DIST)/$(PACKAGE) +WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe RETRIEVE_WINDOWS_INSTALLER = 1 MOZ_LANGPACK_EID=langpack-$(AB_CD)@b2g.mozilla.org @@ -31,9 +31,9 @@ L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warning PP_TARGETS += L10N_PREF_JS_EXPORTS ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT))) -MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore -MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png -MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns +MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore +MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png +MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ ' endif @@ -41,8 +41,8 @@ ifeq (WINNT,$(OS_ARCH)) UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \ $(NSINSTALL) -D $(STAGEDIST)/uninstall; \ cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \ - $(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \ - cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \ + $(RM) $(ABS_DIST)/l10n-stage/setup.exe; \ + cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \ $(NULL) endif @@ -57,7 +57,7 @@ $(DIST)/branding: libs:: @if test -f '$(LOCALE_SRCDIR)/existing-profile-defaults.js'; then \ - $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) \ + $(PYTHON) -m mozbuild.action.preprocessor $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) \ $(LOCALE_SRCDIR)/existing-profile-defaults.js -o $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \ fi @@ -75,7 +75,7 @@ chrome-%: @$(MAKE) chrome AB_CD=$* @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$* -repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe +repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD) @echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).' $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export diff --git a/browser/base/content/test/general/browser_audioTabIcon.js b/browser/base/content/test/general/browser_audioTabIcon.js index 707e5a5b3c23..0eb55aa58dc8 100644 --- a/browser/base/content/test/general/browser_audioTabIcon.js +++ b/browser/base/content/test/general/browser_audioTabIcon.js @@ -181,22 +181,56 @@ function* test_playing_icon_on_tab(tab, browser, isPinned) { yield test_muting_using_menu(tab, true); } -function* test_swapped_browser(oldTab, newBrowser, isPlaying) { +function* test_swapped_browser_while_playing(oldTab, newBrowser) { ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab"); - is(oldTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the old tab"); + ok(oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab"); let newTab = gBrowser.getTabForBrowser(newBrowser); let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => { - return (event.detail.changed.indexOf("soundplaying") >= 0 || !isPlaying) && + return event.detail.changed.indexOf("soundplaying") >= 0 && event.detail.changed.indexOf("muted") >= 0; }); + + gBrowser.swapBrowsersAndCloseOther(newTab, oldTab); + yield AttrChangePromise; + + ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); + ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); + + let receivedSoundPlaying = 0; + // We need to receive two TabAttrModified events with 'soundplaying' + // because swapBrowsersAndCloseOther involves nsDocument::OnPageHide and + // nsDocument::OnPageShow. Each methods lead to TabAttrModified event. + yield BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => { + if (event.detail.changed.indexOf("soundplaying") >= 0) { + return (++receivedSoundPlaying == 2); + } + }); + + ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); + ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); + + let icon = document.getAnonymousElementByAttribute(newTab, "anonid", + "soundplaying-icon"); + yield test_tooltip(icon, "Unmute tab", true); +} + +function* test_swapped_browser_while_not_playing(oldTab, newBrowser) { + ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab"); + ok(!oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab"); + + let newTab = gBrowser.getTabForBrowser(newBrowser); + let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => { + return event.detail.changed.indexOf("muted") >= 0; + }); + let AudioPlaybackPromise = new Promise(resolve => { let observer = (subject, topic, data) => { - ok(true, "Should see an audio-playback notification"); + ok(false, "Should not see an audio-playback notification"); }; - Services.obs.addObserver(observer, "audio-playback", false); + Services.obs.addObserver(observer, "audiochannel-activity-normal", false); setTimeout(() => { - Services.obs.removeObserver(observer, "audio-playback"); + Services.obs.removeObserver(observer, "audiochannel-activity-normal"); resolve(); }, 100); }); @@ -205,13 +239,13 @@ function* test_swapped_browser(oldTab, newBrowser, isPlaying) { yield AttrChangePromise; ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); - is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab"); + ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); // Wait to see if an audio-playback event is dispatched. yield AudioPlaybackPromise; ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); - is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab"); + ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); let icon = document.getAnonymousElementByAttribute(newTab, "anonid", "soundplaying-icon"); @@ -230,7 +264,7 @@ function* test_browser_swapping(tab, browser) { gBrowser, url: "about:blank", }, function*(newBrowser) { - yield test_swapped_browser(tab, newBrowser, true) + yield test_swapped_browser_while_playing(tab, newBrowser) // Now, test swapping with a muted but not playing tab. // Note that the tab remains muted, so we only need to pause playback. @@ -240,7 +274,7 @@ function* test_browser_swapping(tab, browser) { yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank", - }, newBrowser => test_swapped_browser(tab, newBrowser, false)); + }, newBrowser => test_swapped_browser_while_not_playing(tab, newBrowser)); }); } diff --git a/browser/base/content/test/general/browser_bug575561.js b/browser/base/content/test/general/browser_bug575561.js index 7f85dd822d2e..cd8615a5681f 100644 --- a/browser/base/content/test/general/browser_bug575561.js +++ b/browser/base/content/test/general/browser_bug575561.js @@ -1,3 +1,5 @@ +requestLongerTimeout(2); + const TEST_URL = "http://example.com/browser/browser/base/content/test/general/app_bug575561.html"; add_task(function*() { diff --git a/browser/base/content/test/general/browser_bug676619.js b/browser/base/content/test/general/browser_bug676619.js index 9dd00912232f..ef8f2b10af49 100644 --- a/browser/base/content/test/general/browser_bug676619.js +++ b/browser/base/content/test/general/browser_bug676619.js @@ -1,5 +1,5 @@ function test () { - requestLongerTimeout(2); + requestLongerTimeout(3); waitForExplicitFinish(); var isHTTPS = false; diff --git a/browser/base/content/test/general/browser_devices_get_user_media.js b/browser/base/content/test/general/browser_devices_get_user_media.js index 5452dc7f5eb9..287592b8436e 100644 --- a/browser/base/content/test/general/browser_devices_get_user_media.js +++ b/browser/base/content/test/general/browser_devices_get_user_media.js @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +requestLongerTimeout(2); + const kObservedTopics = [ "getUserMedia:response:allow", "getUserMedia:revoke", diff --git a/browser/base/content/test/general/browser_e10s_switchbrowser.js b/browser/base/content/test/general/browser_e10s_switchbrowser.js index 5a32efce88bf..e6134f749fe8 100644 --- a/browser/base/content/test/general/browser_e10s_switchbrowser.js +++ b/browser/base/content/test/general/browser_e10s_switchbrowser.js @@ -1,3 +1,5 @@ +requestLongerTimeout(2); + const DUMMY_PATH = "browser/browser/base/content/test/general/dummy_page.html"; const gExpectedHistory = { diff --git a/browser/base/content/test/general/browser_sanitize-timespans.js b/browser/base/content/test/general/browser_sanitize-timespans.js index 77a734b21cf8..8abe82187881 100644 --- a/browser/base/content/test/general/browser_sanitize-timespans.js +++ b/browser/base/content/test/general/browser_sanitize-timespans.js @@ -1,6 +1,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); +requestLongerTimeout(2); + // Bug 453440 - Test the timespan-based logic of the sanitizer code var now_mSec = Date.now(); var now_uSec = now_mSec * 1000; 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 145e003141a5..ce7f683081f2 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 @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +requestLongerTimeout(2); + const CHROMEUTILS_URL = "chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"; var ChromeUtils = {}; diff --git a/browser/base/content/test/newtab/browser_newtab_block.js b/browser/base/content/test/newtab/browser_newtab_block.js index 1a958b794b30..5e464d87bec0 100644 --- a/browser/base/content/test/newtab/browser_newtab_block.js +++ b/browser/base/content/test/newtab/browser_newtab_block.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /* * These tests make sure that blocking/removing sites from the grid works * as expected. Pinned tabs should not be moved. Gaps will be re-filled diff --git a/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js b/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js index 745ba939f263..4b712a6aca8b 100644 --- a/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js +++ b/browser/base/content/test/newtab/browser_newtab_drag_drop_ext.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns"; /* diff --git a/browser/base/content/test/newtab/browser_newtab_enhanced.js b/browser/base/content/test/newtab/browser_newtab_enhanced.js index a5ddd2838109..323ae18d512a 100644 --- a/browser/base/content/test/newtab/browser_newtab_enhanced.js +++ b/browser/base/content/test/newtab/browser_newtab_enhanced.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + const PRELOAD_PREF = "browser.newtab.preload"; var suggestedLink = { diff --git a/browser/components/customizableui/test/browser_880164_customization_context_menus.js b/browser/components/customizableui/test/browser_880164_customization_context_menus.js index 86becf29fc4b..ad7aa1ebfcdc 100644 --- a/browser/components/customizableui/test/browser_880164_customization_context_menus.js +++ b/browser/components/customizableui/test/browser_880164_customization_context_menus.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + const isOSX = (Services.appinfo.OS === "Darwin"); // Right-click on the home button should diff --git a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js index 51ff0ca68992..b9eeaea1b1e6 100644 --- a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js +++ b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + var bookmarksToolbar = document.getElementById("PersonalToolbar"); var navbar = document.getElementById("nav-bar"); var tabsToolbar = document.getElementById("TabsToolbar"); diff --git a/browser/components/customizableui/test/browser_970511_undo_restore_default.js b/browser/components/customizableui/test/browser_970511_undo_restore_default.js index 599dfdf72085..33530ea34dd9 100644 --- a/browser/components/customizableui/test/browser_970511_undo_restore_default.js +++ b/browser/components/customizableui/test/browser_970511_undo_restore_default.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Restoring default should show an "undo" option which undoes the restoring operation. add_task(function() { let homeButtonId = "home-button"; diff --git a/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js b/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js index 95964e9e6984..0bba6fee3363 100644 --- a/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js +++ b/browser/components/customizableui/test/browser_975719_customtoolbars_behaviour.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + const kXULWidgetId = "a-test-button"; // we'll create a button with this ID. add_task(function setup() { diff --git a/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js b/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js index af4316b13439..2c5f0c79cc29 100644 --- a/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js +++ b/browser/components/customizableui/test/browser_bootstrapped_custom_toolbar.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + const kTestBarID = "testBar"; const kWidgetID = "characterencoding-button"; diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js index 5c354b606d72..2682ad819a1f 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_executeScript_good.js @@ -2,6 +2,8 @@ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; +requestLongerTimeout(2); + function* testHasPermission(params) { let contentSetup = params.contentSetup || (() => Promise.resolve()); diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js index ce05577ffd0b..4a58b0fc467f 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js @@ -2,6 +2,8 @@ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; +requestLongerTimeout(2); + add_task(function* () { let win1 = yield BrowserTestUtils.openNewBrowserWindow(); diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_query.js b/browser/components/extensions/test/browser/browser_ext_tabs_query.js index 32ee3afb283a..1c719a8adeae 100644 --- a/browser/components/extensions/test/browser/browser_ext_tabs_query.js +++ b/browser/components/extensions/test/browser/browser_ext_tabs_query.js @@ -2,6 +2,8 @@ /* vim: set sts=2 sw=2 et tw=80: */ "use strict"; +requestLongerTimeout(2); + add_task(function* () { let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:robots"); let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:config"); diff --git a/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js b/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js index 9fe661d33d5b..89313d7366fe 100644 --- a/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js +++ b/browser/components/preferences/in-content/tests/browser_cookies_exceptions.js @@ -1,9 +1,11 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + function test() { waitForExplicitFinish(); - requestLongerTimeout(2); + requestLongerTimeout(3); testRunner.runTests(); } diff --git a/browser/components/preferences/in-content/tests/browser_privacypane_4.js b/browser/components/preferences/in-content/tests/browser_privacypane_4.js index ad22217a177d..0b3d57fc250d 100644 --- a/browser/components/preferences/in-content/tests/browser_privacypane_4.js +++ b/browser/components/preferences/in-content/tests/browser_privacypane_4.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + function test() { let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. getService(Ci.mozIJSSubScriptLoader); diff --git a/browser/components/sessionstore/test/browser_522545.js b/browser/components/sessionstore/test/browser_522545.js index 73395d579dbe..1c64bd7e82f2 100644 --- a/browser/components/sessionstore/test/browser_522545.js +++ b/browser/components/sessionstore/test/browser_522545.js @@ -6,7 +6,7 @@ function test() { /** Test for Bug 522545 **/ waitForExplicitFinish(); - requestLongerTimeout(3); + requestLongerTimeout(4); // This tests the following use case: // User opens a new tab which gets focus. The user types something into the diff --git a/browser/components/sessionstore/test/browser_586068-apptabs.js b/browser/components/sessionstore/test/browser_586068-apptabs.js index 46a0b7754dbd..f8727c04f8fe 100644 --- a/browser/components/sessionstore/test/browser_586068-apptabs.js +++ b/browser/components/sessionstore/test/browser_586068-apptabs.js @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +requestLongerTimeout(2); + const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand"; add_task(function* test() { diff --git a/browser/components/sessionstore/test/browser_600545.js b/browser/components/sessionstore/test/browser_600545.js index 51dbb60279f6..6852357c2ca5 100644 --- a/browser/components/sessionstore/test/browser_600545.js +++ b/browser/components/sessionstore/test/browser_600545.js @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +requestLongerTimeout(2); + var stateBackup = JSON.parse(ss.getBrowserState()); function test() { diff --git a/browser/components/sessionstore/test/browser_crashedTabs.js b/browser/components/sessionstore/test/browser_crashedTabs.js index e073d7ef3610..3e1a6ec466b9 100644 --- a/browser/components/sessionstore/test/browser_crashedTabs.js +++ b/browser/components/sessionstore/test/browser_crashedTabs.js @@ -3,6 +3,8 @@ "use strict"; +requestLongerTimeout(2); + const PAGE_1 = "data:text/html,A%20regular,%20everyday,%20normal%20page."; const PAGE_2 = "data:text/html,Another%20regular,%20everyday,%20normal%20page."; diff --git a/browser/components/sessionstore/test/browser_formdata_cc.js b/browser/components/sessionstore/test/browser_formdata_cc.js index ef908f43dda6..6e27ca970e72 100644 --- a/browser/components/sessionstore/test/browser_formdata_cc.js +++ b/browser/components/sessionstore/test/browser_formdata_cc.js @@ -3,7 +3,7 @@ const URL = "http://mochi.test:8888/browser/browser/components/" + "sessionstore/test/browser_formdata_sample.html"; -requestLongerTimeout(2); +requestLongerTimeout(3); /** * This test ensures that credit card numbers in form data will not be diff --git a/browser/components/sessionstore/test/browser_sessionHistory.js b/browser/components/sessionstore/test/browser_sessionHistory.js index 120f918b3f72..f4523e06a245 100644 --- a/browser/components/sessionstore/test/browser_sessionHistory.js +++ b/browser/components/sessionstore/test/browser_sessionHistory.js @@ -3,6 +3,8 @@ "use strict"; +requestLongerTimeout(2); + /** * Ensure that starting a load invalidates shistory. */ diff --git a/browser/experiments/Makefile.in b/browser/experiments/Makefile.in index 831d9ef209f7..5558582a6805 100644 --- a/browser/experiments/Makefile.in +++ b/browser/experiments/Makefile.in @@ -6,7 +6,7 @@ include $(topsrcdir)/config/rules.mk # This is so hacky. Waiting on bug 988938. addondir = $(srcdir)/test/addons -testdir = $(abspath $(DEPTH)/_tests/xpcshell/browser/experiments/test/xpcshell) +testdir = $(topobjdir)/_tests/xpcshell/browser/experiments/test/xpcshell misc:: $(call mkdir_deps,$(testdir)) $(EXIT_ON_ERROR) \ diff --git a/browser/extensions/loop/jar.mn b/browser/extensions/loop/jar.mn index 3df2c1c6933d..d90360d6e174 100644 --- a/browser/extensions/loop/jar.mn +++ b/browser/extensions/loop/jar.mn @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -[.] chrome.jar: +[features/loop@mozilla.org] chrome.jar: % content loop %content/ contentaccessible=yes % skin loop classic/1.0 %skin/linux/ os=Linux % skin loop classic/1.0 %skin/osx/ os=Darwin diff --git a/browser/extensions/loop/moz.build b/browser/extensions/loop/moz.build index 98a3ce2fd125..c747a75e965c 100644 --- a/browser/extensions/loop/moz.build +++ b/browser/extensions/loop/moz.build @@ -4,13 +4,11 @@ # 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/. -FINAL_TARGET = 'dist/bin/browser/features/loop@mozilla.org' - -FINAL_TARGET_FILES += [ +FINAL_TARGET_FILES.features['loop@mozilla.org'] += [ 'bootstrap.js' ] -FINAL_TARGET_PP_FILES += [ +FINAL_TARGET_PP_FILES.features['loop@mozilla.org'] += [ 'install.rdf.in' ] diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js b/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js index 3a822366857c..ace52c050f04 100644 --- a/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js +++ b/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + Components.utils.import("resource://gre/modules/Promise.jsm", this); const RELATIVE_DIR = "browser/extensions/pdfjs/test/"; diff --git a/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js b/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js index c06cf39c009a..acc35a98aa6a 100644 --- a/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js +++ b/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + Components.utils.import("resource://gre/modules/Promise.jsm", this); const RELATIVE_DIR = "browser/extensions/pdfjs/test/"; diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index dec094c25c73..5e6a90d1b3d0 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -35,8 +35,8 @@ PWD := $(CURDIR) # pulls. You may override them if you provide your own files. You _must_ # override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not # work in that case. -ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE) -WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe +ZIP_IN ?= $(ABS_DIST)/$(PACKAGE) +WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe RETRIEVE_WINDOWS_INSTALLER = 1 MOZ_LANGPACK_EID=langpack-$(AB_CD)@firefox.mozilla.org @@ -47,9 +47,9 @@ L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warning PP_TARGETS += L10N_PREF_JS_EXPORTS ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT))) -MOZ_PKG_MAC_DSSTORE=$(_ABS_DIST)/branding/dsstore -MOZ_PKG_MAC_BACKGROUND=$(_ABS_DIST)/branding/background.png -MOZ_PKG_MAC_ICON=$(_ABS_DIST)/branding/disk.icns +MOZ_PKG_MAC_DSSTORE=$(ABS_DIST)/branding/dsstore +MOZ_PKG_MAC_BACKGROUND=$(ABS_DIST)/branding/background.png +MOZ_PKG_MAC_ICON=$(ABS_DIST)/branding/disk.icns MOZ_PKG_MAC_EXTRA=--symlink '/Applications:/ ' endif @@ -57,14 +57,14 @@ ifeq (WINNT,$(OS_ARCH)) UNINSTALLER_PACKAGE_HOOK = $(RM) -r $(STAGEDIST)/uninstall; \ $(NSINSTALL) -D $(STAGEDIST)/uninstall; \ cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall; \ - $(RM) $(_ABS_DIST)/l10n-stage/setup.exe; \ - cp ../installer/windows/l10ngen/setup.exe $(_ABS_DIST)/l10n-stage; \ + $(RM) $(ABS_DIST)/l10n-stage/setup.exe; \ + cp ../installer/windows/l10ngen/setup.exe $(ABS_DIST)/l10n-stage; \ $(NULL) -STUB_HOOK = $(NSINSTALL) -D '$(_ABS_DIST)/$(PKG_INST_PATH)'; \ - $(RM) '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ - cp ../installer/windows/l10ngen/stub.exe '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ - chmod 0755 '$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ +STUB_HOOK = $(NSINSTALL) -D '$(ABS_DIST)/$(PKG_INST_PATH)'; \ + $(RM) '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ + cp ../installer/windows/l10ngen/stub.exe '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ + chmod 0755 '$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_STUB_BASENAME).exe'; \ $(NULL) endif @@ -140,7 +140,7 @@ endif @$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR) @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* -repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe +repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe repackage-win32-installer: $(call ESCAPE_WILDCARD,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD) @echo 'Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT).' $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export diff --git a/browser/locales/generic/install.rdf b/browser/locales/generic/install.rdf deleted file mode 100644 index 8b5520db719d..000000000000 --- a/browser/locales/generic/install.rdf +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -#ifdef MOZ_LANGPACK_CONTRIBUTORS - @MOZ_LANGPACK_CONTRIBUTORS@ -#endif - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - @MOZ_APP_VERSION@ - @MOZ_APP_MAXVERSION@ - - - - diff --git a/build/Makefile.in b/build/Makefile.in index 2d82093b882b..b0261635f0e7 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -33,7 +33,7 @@ endif # NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir. # needs to be absolute to be distinct from $(topsrcdir)/.gdbinit GDBINIT_OBJDIR_FILES = $(topsrcdir)/.gdbinit -GDBINIT_OBJDIR_DEST = $(abspath $(DEPTH)) +GDBINIT_OBJDIR_DEST = $(topobjdir) INSTALL_TARGETS += GDBINIT_OBJDIR # Put a .lldbinit in the bin directory and the objdir, to be picked up @@ -52,7 +52,7 @@ INSTALL_TARGETS += LLDBINIT_FINAL_TARGET # Put the .ycm_extra_conf.py file at the root of the objdir. It is used by # the vim plugin YouCompleteMe. YCM_FILES := $(topsrcdir)/.ycm_extra_conf.py -YCM_DEST := $(abspath $(DEPTH)) +YCM_DEST := $(topobjdir) YCM_TARGET := export INSTALL_TARGETS += YCM diff --git a/build/autoconf/compiler-opts.m4 b/build/autoconf/compiler-opts.m4 index 56d6af4b2c76..fd4bf42d184f 100644 --- a/build/autoconf/compiler-opts.m4 +++ b/build/autoconf/compiler-opts.m4 @@ -128,13 +128,13 @@ fi AC_SUBST(MOZ_NO_DEBUG_RTL) -MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -DTRACING" +MOZ_DEBUG_ENABLE_DEFS="DEBUG TRACING" MOZ_ARG_WITH_STRING(debug-label, [ --with-debug-label=LABELS Define DEBUG_ for each comma-separated value given.], [ for option in `echo $withval | sed 's/,/ /g'`; do - MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${option}" + MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS DEBUG_${option}" done]) if test -n "$MOZ_DEBUG"; then @@ -153,10 +153,10 @@ if test -n "$MOZ_DEBUG"; then MOZ_DEBUG_DEFINES="$MOZ_DEBUG_ENABLE_DEFS" else - MOZ_DEBUG_DEFINES="-DNDEBUG -DTRIMMED" + MOZ_DEBUG_DEFINES="NDEBUG TRIMMED" fi -AC_SUBST(MOZ_DEBUG_DEFINES) +AC_SUBST_LIST(MOZ_DEBUG_DEFINES) dnl ======================================================== dnl = Enable generation of debug symbols diff --git a/build/pgo/profileserver.py b/build/pgo/profileserver.py index 473f7074d3ba..71dc1a3894a1 100644 --- a/build/pgo/profileserver.py +++ b/build/pgo/profileserver.py @@ -63,6 +63,14 @@ if __name__ == '__main__': if os.path.exists(vc12dir): env["PATH"] = vc12dir + ";" + env["PATH"] + # Run Firefox a first time to initialize its profile + runner = FirefoxRunner(profile=profile, + binary=build.get_binary_path(where="staged-package"), + cmdargs=['javascript:Quitter.quit()'], + env=env) + runner.start() + runner.wait() + jarlog = os.getenv("JARLOG_FILE") if jarlog: env["MOZ_JAR_LOG_FILE"] = os.path.abspath(jarlog) diff --git a/config/baseconfig.mk b/config/baseconfig.mk index 86920aadedf8..76e1f76705de 100644 --- a/config/baseconfig.mk +++ b/config/baseconfig.mk @@ -11,6 +11,7 @@ DIST = dist else DIST = $(DEPTH)/dist endif +ABS_DIST = $(topobjdir)/dist # We do magic with OBJ_SUFFIX in config.mk, the following ensures we don't # manually use it before config.mk inclusion diff --git a/config/config.mk b/config/config.mk index d0de93df2b06..c56c754c12cb 100644 --- a/config/config.mk +++ b/config/config.mk @@ -159,8 +159,6 @@ _DEBUG_ASFLAGS := _DEBUG_CFLAGS := _DEBUG_LDFLAGS := -_DEBUG_CFLAGS += $(MOZ_DEBUG_DEFINES) - ifneq (,$(MOZ_DEBUG)$(MOZ_DEBUG_SYMBOLS)) ifeq ($(AS),yasm) ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_) @@ -289,9 +287,9 @@ CCC = $(CXX) INCLUDES = \ -I$(srcdir) \ - -I. \ + -I$(CURDIR) \ $(LOCAL_INCLUDES) \ - -I$(DIST)/include \ + -I$(ABS_DIST)/include \ $(NULL) ifndef IS_GYP_DIR @@ -329,6 +327,8 @@ LDFLAGS += $(MOZ_OPTIMIZE_LDFLAGS) RUSTFLAGS += $(MOZ_OPTIMIZE_RUSTFLAGS) endif # MOZ_OPTIMIZE +HOST_CFLAGS += $(_DEPEND_CFLAGS) +HOST_CXXFLAGS += $(_DEPEND_CFLAGS) ifdef CROSS_COMPILE HOST_CFLAGS += $(HOST_OPTIMIZE_FLAGS) else @@ -409,8 +409,8 @@ OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch endif endif -COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) -COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) +COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(_DEPEND_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) +COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS) COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS) ASFLAGS += $(MOZBUILD_ASFLAGS) diff --git a/config/external/nspr/Makefile.in b/config/external/nspr/Makefile.in index c4349f35b6ea..753c91046e64 100644 --- a/config/external/nspr/Makefile.in +++ b/config/external/nspr/Makefile.in @@ -8,7 +8,6 @@ include $(topsrcdir)/config/rules.mk ifdef MOZ_BUILD_NSPR # Copy NSPR to the SDK -ABS_DIST = $(abspath $(DIST)) ifdef MOZ_FOLD_LIBS # Trick the nspr build system into not building shared libraries. diff --git a/config/external/nss/Makefile.in b/config/external/nss/Makefile.in index 713c66a3384c..9ad7e2db362b 100644 --- a/config/external/nss/Makefile.in +++ b/config/external/nss/Makefile.in @@ -85,15 +85,6 @@ NSS_EXTRA_DLLS += freebl_64int_3 NSS_EXTRA_DLLS += freebl_64fpu_3 endif -ABS_DIST := $(abspath $(DIST)) -ifeq ($(HOST_OS_ARCH),WINNT) -ifdef CYGDRIVE_MOUNT -ABS_DIST := $(shell cygpath -w $(ABS_DIST) | sed -e 's|\\|/|g') -endif -ifneq (,$(filter mingw%,$(host_os))) -ABS_DIST := $(shell cd $(DIST) && pwd -W) -endif -endif # For all variables such as DLLFLAGS, that may contain $(DIST) DIST := $(ABS_DIST) NSPR_INCLUDE_DIR = $(firstword $(filter -I%,$(NSPR_CFLAGS))) @@ -344,31 +335,6 @@ ifdef MOZ_FOLD_LIBS # Add all static libraries for nss, smime, ssl and nssutil STATIC_LIBS += $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS)) -nss_def_file := $(srcdir)/nss.def - -ifeq (WINNT,$(OS_TARGET)) -# Create a .def file based on the various .def files for nss, smime, ssl and -# nssutil. -nss3.def: $(nss_def_file) $(DEPTH)/db/sqlite3/src/sqlite-processed.def $(NSS_EXTRA_SYMBOLS_FILE) - echo LIBRARY nss3$(DLL_SUFFIX) > $@.tmp - echo EXPORTS >> $@.tmp - grep -v -h -e ^LIBRARY -e ^EXPORTS -e ^\; $^ >> $@.tmp - mv $@.tmp $@ -else -ifdef GCC_USE_GNU_LD -sqlite_def_file := $(topsrcdir)/db/sqlite3/src/sqlite.def -nspr_def_file := $(srcdir)/nspr-dummy.def - -nss3.def: $(nss_def_file) $(sqlite_def_file) $(nspr_def_file) $(NSS_EXTRA_SYMBOLS_FILE) - @$(call py_action,convert_def_file, \ - $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) -o $@ $^) - -GARBAGE += \ - nss3.def \ - $(NULL) -endif # GCC_USE_GNU_LD -endif # WINNT - IMPORT_LIB_FILES = $(IMPORT_LIBRARY) IMPORT_LIB_DEST ?= $(DIST)/lib IMPORT_LIB_TARGET = target diff --git a/config/external/nss/moz.build b/config/external/nss/moz.build index 572cebf74a30..10a12ea592ee 100644 --- a/config/external/nss/moz.build +++ b/config/external/nss/moz.build @@ -31,11 +31,7 @@ elif CONFIG['MOZ_FOLD_LIBS']: OS_LIBS += CONFIG['REALTIME_LIBS'] - if CONFIG['OS_TARGET'] == 'WINNT': - DEFFILE = 'nss3.def' - - if CONFIG['OS_ARCH'] == 'Linux' and CONFIG['GCC_USE_GNU_LD']: - LD_VERSION_SCRIPT = 'nss3.def' + SYMBOLS_FILE = 'nss.symbols' else: Library('nss') USE_LIBS += [ diff --git a/config/external/nss/nspr-dummy.def b/config/external/nss/nspr-dummy.def deleted file mode 100644 index b14fcf82c84f..000000000000 --- a/config/external/nss/nspr-dummy.def +++ /dev/null @@ -1,15 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. -; -; This is a fake .def file, to be used for generating linker scripts -; for our folded libnss when MOZ_FOLD_LIBS. NSPR, unlike NSS, exports -; symbols with symbol visibility (Unix) or __declspec (Windows). When -; using a linker script, however, we need to explicitly specify that -; NSPR's symbols should be globally visible. Otherwise, NSPR's exported -; symbols would match the |local: *| rule and be hidden. -LIBRARY libnsprdummy -EXPORTS -PR_* ; Actual .def files don't allow wildcards, of course. -_PR_* -PL_* diff --git a/config/external/nss/nss.def b/config/external/nss/nss.symbols similarity index 89% rename from config/external/nss/nss.def rename to config/external/nss/nss.symbols index 2e631536ce3b..e6c5e7bbf92b 100644 --- a/config/external/nss/nss.def +++ b/config/external/nss/nss.symbols @@ -1,11 +1,19 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. -; -; This is a fake .def file, to be used for generating linker scripts -; for our folded libnss when MOZ_FOLD_LIBS. -LIBRARY nss3 -EXPORTS +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef XP_WIN +# NSPR, unlike NSS, exports symbols with symbol visibility (Unix) or __declspec +# (Windows). When using a linker script, however, we need to explicitly +# specify that NSPR's symbols should be globally visible. Otherwise, NSPR's +# exported symbols would be hidden. +# .def files on Windows don't allow wildcards, of course, which is why this is +# excluded on Windows, but it doesn't matter because the symbols are already +# exported in NSPR (Windows peculiarity). +PR_* +PL_* +#endif +#include ../../../db/sqlite3/src/sqlite.symbols ATOB_AsciiToData ATOB_AsciiToData_Util ATOB_ConvertAsciiToItem @@ -21,8 +29,8 @@ __CERT_AddTempCertToPerm CERT_AsciiToName CERT_CacheOCSPResponseFromSideChannel CERT_CertChainFromCert -CERT_CertificateRequestTemplate DATA -CERT_CertificateTemplate DATA +CERT_CertificateRequestTemplate @DATA@ +CERT_CertificateTemplate @DATA@ CERT_CertListFromCert CERT_ChangeCertTrust CERT_CheckCertUsage @@ -38,7 +46,7 @@ CERT_CreateCertificate CERT_CreateCertificateRequest CERT_CreateSubjectCertList CERT_CreateValidity -CERT_CrlTemplate DATA +CERT_CrlTemplate @DATA@ CERT_DecodeAltNameExtension CERT_DecodeAuthInfoAccessExtension CERT_DecodeAuthKeyID @@ -128,7 +136,7 @@ CERT_IsCACert CERT_IsUserCert CERT_MakeCANickname CERT_MergeExtensions -CERT_NameTemplate DATA +CERT_NameTemplate @DATA@ CERT_NameToAscii CERT_NewCertList CERT_NewTempCertificate @@ -138,15 +146,15 @@ CERT_PKIXVerifyCert CERT_RemoveCertListNode CERT_RFC1485_EscapeAndQuote CERT_SaveSMimeProfile -CERT_SequenceOfCertExtensionTemplate DATA +CERT_SequenceOfCertExtensionTemplate @DATA@ CERT_SetOCSPFailureMode CERT_SetOCSPTimeout -CERT_SignedCrlTemplate DATA -CERT_SignedDataTemplate DATA +CERT_SignedCrlTemplate @DATA@ +CERT_SignedDataTemplate @DATA@ CERT_StartCertExtensions CERT_StartCertificateRequestAttributes -CERT_SubjectPublicKeyInfoTemplate DATA -CERT_TimeChoiceTemplate DATA +CERT_SubjectPublicKeyInfoTemplate @DATA@ +CERT_TimeChoiceTemplate @DATA@ CERT_VerifyCertificate CERT_VerifySignedDataWithPublicKeyInfo DER_AsciiToTime_Util @@ -462,7 +470,7 @@ PORT_UCS2_UTF8Conversion_Util PORT_ZAlloc PORT_ZAlloc_Util PORT_ZFree_Util -SEC_AnyTemplate_Util DATA +SEC_AnyTemplate_Util @DATA@ SEC_ASN1Decode SEC_ASN1DecodeInteger SEC_ASN1DecodeItem @@ -473,20 +481,20 @@ SEC_ASN1EncodeItem SEC_ASN1EncodeItem_Util SEC_ASN1EncodeUnsignedInteger_Util SEC_ASN1Encode_Util -SEC_BitStringTemplate DATA -SEC_BitStringTemplate_Util DATA -SEC_BMPStringTemplate DATA -SEC_BooleanTemplate_Util DATA +SEC_BitStringTemplate @DATA@ +SEC_BitStringTemplate_Util @DATA@ +SEC_BMPStringTemplate @DATA@ +SEC_BooleanTemplate_Util @DATA@ SEC_CertNicknameConflict SEC_DeletePermCertificate SEC_DerSignData SEC_DestroyCrl -SEC_GeneralizedTimeTemplate_Util DATA +SEC_GeneralizedTimeTemplate_Util @DATA@ SEC_GetSignatureAlgorithmOidTag -SEC_IA5StringTemplate DATA -SEC_IA5StringTemplate_Util DATA -SEC_IntegerTemplate DATA -SEC_IntegerTemplate_Util DATA +SEC_IA5StringTemplate @DATA@ +SEC_IA5StringTemplate_Util @DATA@ +SEC_IntegerTemplate @DATA@ +SEC_IntegerTemplate_Util @DATA@ SECITEM_AllocArray SECITEM_AllocItem SECITEM_AllocItem_Util @@ -524,7 +532,7 @@ SECKEY_ExtractPublicKey SECKEY_GetPublicKeyType SECKEY_ImportDERPublicKey SECKEY_PublicKeyStrength -SECKEY_RSAPSSParamsTemplate DATA +SECKEY_RSAPSSParamsTemplate @DATA@ SECKEY_SignatureLen SECMIME_DecryptionAllowed SECMOD_AddNewModule @@ -555,14 +563,14 @@ SECMOD_ReleaseReadLock SECMOD_UnloadUserModule SECMOD_UpdateModule SECMOD_WaitForAnyTokenEvent -SEC_NullTemplate_Util DATA -SEC_ObjectIDTemplate_Util DATA -SEC_OctetStringTemplate DATA -SEC_OctetStringTemplate_Util DATA +SEC_NullTemplate_Util @DATA@ +SEC_ObjectIDTemplate_Util @DATA@ +SEC_OctetStringTemplate @DATA@ +SEC_OctetStringTemplate_Util @DATA@ SECOID_AddEntry SECOID_AddEntry_Util -SECOID_AlgorithmIDTemplate DATA -SECOID_AlgorithmIDTemplate_Util DATA +SECOID_AlgorithmIDTemplate @DATA@ +SECOID_AlgorithmIDTemplate_Util @DATA@ SECOID_CopyAlgorithmID_Util SECOID_DestroyAlgorithmID SECOID_DestroyAlgorithmID_Util @@ -618,10 +626,10 @@ SEC_QuickDERDecodeItem SEC_QuickDERDecodeItem_Util SEC_RegisterDefaultHttpClient SEC_SignData -SEC_SignedCertificateTemplate DATA +SEC_SignedCertificateTemplate @DATA@ SEC_StringToOID -SEC_UTF8StringTemplate DATA -SEC_UTF8StringTemplate_Util DATA +SEC_UTF8StringTemplate @DATA@ +SEC_UTF8StringTemplate_Util @DATA@ SGN_Begin SGN_CreateDigestInfo_Util SGN_DecodeDigestInfo @@ -650,9 +658,9 @@ SSL_GetNumImplementedCiphers SSL_GetSRTPCipher SSL_HandshakeCallback SSL_HandshakeNegotiatedExtension -SSL_ImplementedCiphers DATA +SSL_ImplementedCiphers @DATA@ SSL_ImportFD -SSL_NumImplementedCiphers DATA +SSL_NumImplementedCiphers @DATA@ SSL_OptionSet SSL_OptionSetDefault SSL_PeerCertificate @@ -684,3 +692,6 @@ VFY_VerifyDataWithAlgorithmID VFY_VerifyDigestDirect _SGN_VerifyPKCS1DigestInfo __PK11_SetCertificateNickname +#ifdef NSS_EXTRA_SYMBOLS_FILE +#include @NSS_EXTRA_SYMBOLS_FILE@ +#endif diff --git a/config/external/sqlite/Makefile.in b/config/external/sqlite/Makefile.in index 02dde0576dbf..55fa73618954 100644 --- a/config/external/sqlite/Makefile.in +++ b/config/external/sqlite/Makefile.in @@ -3,26 +3,3 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. LIB_IS_C_ONLY = 1 - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_ARCH),WINNT) -# This needs to stay there for now -DEFFILE = $(DEPTH)/db/sqlite3/src/sqlite-processed.def - -else -ifndef MOZ_FOLD_LIBS -ifdef GCC_USE_GNU_LD - -GARBAGE += \ - $(LD_VERSION_SCRIPT) \ - $(NULL) - -# Convert to the format we need for ld. -$(LD_VERSION_SCRIPT): $(topsrcdir)/db/sqlite3/src/sqlite.def - @$(call py_action,convert_def_file, \ - $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) -o $@ $^) - -endif -endif -endif diff --git a/config/external/sqlite/moz.build b/config/external/sqlite/moz.build index b6f500727f4d..97aeba158146 100644 --- a/config/external/sqlite/moz.build +++ b/config/external/sqlite/moz.build @@ -19,5 +19,4 @@ else: SharedLibrary('sqlite') SHARED_LIBRARY_NAME = 'mozsqlite3' - if CONFIG['OS_ARCH'] == 'Linux' and CONFIG['GCC_USE_GNU_LD']: - LD_VERSION_SCRIPT = 'sqlite-processed.def' + SYMBOLS_FILE = '/db/sqlite3/src/sqlite.symbols' diff --git a/config/faster/rules.mk b/config/faster/rules.mk index 17f5494b6f98..29d64d5e6835 100644 --- a/config/faster/rules.mk +++ b/config/faster/rules.mk @@ -107,7 +107,6 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build -DAB_CD=en-US \ -DMOZ_APP_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid) \ $(ACDEFINES) \ - $(MOZ_DEBUG_DEFINES) \ install_$(subst /,_,$*) # ============================================================================ diff --git a/config/makefiles/debugmake.mk b/config/makefiles/debugmake.mk index c72a78c1bfda..619f1c7cea61 100644 --- a/config/makefiles/debugmake.mk +++ b/config/makefiles/debugmake.mk @@ -57,6 +57,7 @@ ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $ endif $(LOOP_OVER_DIRS) +showbuild showhost: _DEPEND_CFLAGS= showbuild: $(call print_vars,\ MOZ_BUILD_ROOT \ diff --git a/config/rules.mk b/config/rules.mk index 499c7431f9e5..b7000be3d969 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -60,7 +60,7 @@ ifdef COMPILE_ENVIRONMENT # through TestHarness.h, by modifying the list of includes and the libs against # which stuff links. SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS) -INCLUDES += -I$(DIST)/include/testing +INCLUDES += -I$(ABS_DIST)/include/testing ifndef MOZ_PROFILE_GENERATE CPP_UNIT_TESTS_FILES = $(CPP_UNIT_TESTS) @@ -462,6 +462,19 @@ EXTRA_DEPS += $(LD_VERSION_SCRIPT) endif endif +ifdef SYMBOLS_FILE +ifdef GCC_USE_GNU_LD +EXTRA_DSO_LDOPTS += -Wl,--version-script,$(SYMBOLS_FILE) +else +ifeq ($(OS_TARGET),Darwin) +EXTRA_DSO_LDOPTS += -Wl,-exported_symbols_list,$(SYMBOLS_FILE) +endif +ifeq ($(OS_TARGET),WINNT) +EXTRA_DSO_LDOPTS += -DEF:$(call normalizepath,$(SYMBOLS_FILE)) +endif +endif +EXTRA_DEPS += $(SYMBOLS_FILE) +endif # # GNU doesn't have path length limitation # @@ -1204,7 +1217,7 @@ endif libs realchrome:: $(FINAL_TARGET)/chrome $(call py_action,jar_maker,\ $(QUIET) -d $(FINAL_TARGET) \ - $(MAKE_JARS_FLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) \ + $(MAKE_JARS_FLAGS) $(DEFINES) $(ACDEFINES) \ $(JAR_MANIFEST)) endif @@ -1446,7 +1459,9 @@ PP_TARGETS_ALL_RESULTS := $(sort $(foreach tier,$(PP_TARGETS_TIERS),$(PP_TARGETS $(PP_TARGETS_ALL_RESULTS): $(if $(filter-out $(notdir $@),$(notdir $(<:.in=))),$(error Looks like $@ has an unexpected dependency on $< which breaks PP_TARGETS)) $(RM) '$@' - $(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) $(MOZ_DEBUG_DEFINES) '$<' -o '$@') + $(call py_action,preprocessor,--depend $(MDDEPDIR)/$(@F).pp $(PP_TARGET_FLAGS) $(DEFINES) $(ACDEFINES) '$<' -o '$@') + +$(filter %.css,$(PP_TARGETS_ALL_RESULTS)): PP_TARGET_FLAGS+=--marker % # The depfile is based on the filename, and we don't want conflicts. So check # there's only one occurrence of any given filename in PP_TARGETS_ALL_RESULTS. diff --git a/configure.in b/configure.in index 76a2fbbc1b36..5f197470b7bb 100644 --- a/configure.in +++ b/configure.in @@ -1515,7 +1515,7 @@ if test "$GNU_CC"; then esac fi - _DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT' + _DEFINES_CFLAGS='-include $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT' _USE_CPP_INCLUDE_FLAG=1 ASFLAGS="$ASFLAGS $_DEFINES_CFLAGS" @@ -1619,7 +1619,7 @@ if test "$GNU_CXX"; then esac fi - _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h' + _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/mozilla-config.h' _USE_CPP_INCLUDE_FLAG=1 # Recent clang and gcc support C++11 deleted functions without warnings if @@ -2227,8 +2227,8 @@ ia64*-hpux*) WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION _USE_CPP_INCLUDE_FLAG=1 - _DEFINES_CFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT' - _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT' + _DEFINES_CFLAGS='-FI $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT' + _DEFINES_CXXFLAGS='-FI $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT' CFLAGS="$CFLAGS -W3 -Gy" CXXFLAGS="$CXXFLAGS -W3 -Gy" if test "$CPU_ARCH" = "x86" -a -z "$CLANG_CL"; then @@ -8785,22 +8785,19 @@ CXXFLAGS=`echo \ COMPILE_CFLAGS=`echo \ $_DEFINES_CFLAGS \ - $_DEPEND_CFLAGS \ $COMPILE_CFLAGS` COMPILE_CXXFLAGS=`echo \ $_DEFINES_CXXFLAGS \ - $_DEPEND_CFLAGS \ $COMPILE_CXXFLAGS` HOST_CFLAGS=`echo \ - $HOST_CFLAGS \ - $_DEPEND_CFLAGS` + $HOST_CFLAGS` HOST_CXXFLAGS=`echo \ - $HOST_CXXFLAGS \ - $_DEPEND_CFLAGS` + $HOST_CXXFLAGS` +AC_SUBST(_DEPEND_CFLAGS) AC_SUBST(MOZ_NATIVE_JPEG) AC_SUBST(MOZ_NATIVE_PNG) AC_SUBST(MOZ_NATIVE_BZ2) diff --git a/db/sqlite3/src/Makefile.in b/db/sqlite3/src/Makefile.in deleted file mode 100644 index 338fc0c2a813..000000000000 --- a/db/sqlite3/src/Makefile.in +++ /dev/null @@ -1,20 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -include $(topsrcdir)/config/config.mk - -ifeq ($(OS_ARCH),WINNT) -DEFFILE = $(CURDIR)/sqlite-processed.def - -GARBAGE += \ - $(DEFFILE) \ - $(NULL) - -# We have to preprocess our def file because we need different symbols in debug -# builds exposed that are not built in non-debug builds. -$(DEFFILE): sqlite.def - @$(call py_action,preprocessor,$(DEFINES) $(MOZ_DEBUG_DEFINES) \ - $(srcdir)/sqlite.def -o $(DEFFILE)) -endif diff --git a/db/sqlite3/src/sqlite.def b/db/sqlite3/src/sqlite.def deleted file mode 100644 index 56d8001f532f..000000000000 --- a/db/sqlite3/src/sqlite.def +++ /dev/null @@ -1,162 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -LIBRARY mozsqlite3.dll - -EXPORTS - sqlite3_aggregate_context - sqlite3_aggregate_count - sqlite3_auto_extension - sqlite3_bind_blob - sqlite3_bind_double - sqlite3_bind_int - sqlite3_bind_int64 - sqlite3_bind_null - sqlite3_bind_parameter_count - sqlite3_bind_parameter_index - sqlite3_bind_parameter_name - sqlite3_bind_text - sqlite3_bind_text16 - sqlite3_bind_value - sqlite3_busy_handler - sqlite3_busy_timeout - sqlite3_changes - sqlite3_clear_bindings - sqlite3_close - sqlite3_collation_needed - sqlite3_collation_needed16 - sqlite3_column_blob - sqlite3_column_bytes - sqlite3_column_bytes16 - sqlite3_column_count - sqlite3_column_decltype - sqlite3_column_decltype16 - sqlite3_column_double - sqlite3_column_int - sqlite3_column_int64 - sqlite3_column_name - sqlite3_column_name16 - sqlite3_column_text - sqlite3_column_text16 - sqlite3_column_type - sqlite3_column_value - sqlite3_commit_hook - sqlite3_complete - sqlite3_complete16 - sqlite3_config - sqlite3_create_collation - sqlite3_create_collation16 - sqlite3_create_function - sqlite3_create_function16 - sqlite3_create_module - sqlite3_data_count - sqlite3_db_filename - sqlite3_db_handle - sqlite3_db_mutex - sqlite3_db_status - sqlite3_declare_vtab - sqlite3_enable_load_extension - sqlite3_enable_shared_cache - sqlite3_errcode - sqlite3_errmsg - sqlite3_errmsg16 - sqlite3_exec - sqlite3_expired - sqlite3_extended_result_codes - sqlite3_file_control - sqlite3_finalize - sqlite3_free - sqlite3_free_table - sqlite3_get_autocommit - sqlite3_get_auxdata - sqlite3_get_table - sqlite3_global_recover - sqlite3_initialize - sqlite3_interrupt - sqlite3_last_insert_rowid - sqlite3_libversion - sqlite3_libversion_number - sqlite3_load_extension - sqlite3_malloc - sqlite3_memory_alarm - sqlite3_memory_highwater - sqlite3_memory_used - sqlite3_mutex_alloc - sqlite3_mutex_enter - sqlite3_mutex_free - sqlite3_mutex_leave - sqlite3_mutex_try - sqlite3_mprintf - sqlite3_next_stmt - sqlite3_open - sqlite3_open_v2 - sqlite3_open16 - sqlite3_overload_function - sqlite3_prepare - sqlite3_prepare16 - sqlite3_prepare16_v2 - sqlite3_prepare_v2 - sqlite3_profile - sqlite3_progress_handler - sqlite3_realloc - sqlite3_release_memory - sqlite3_reset - sqlite3_reset_auto_extension - sqlite3_result_blob - sqlite3_result_double - sqlite3_result_error - sqlite3_result_error16 - sqlite3_result_error_code - sqlite3_result_error_nomem - sqlite3_result_int - sqlite3_result_int64 - sqlite3_result_null - sqlite3_result_text - sqlite3_result_text16 - sqlite3_result_text16be - sqlite3_result_text16le - sqlite3_result_value - sqlite3_rollback_hook - sqlite3_set_authorizer - sqlite3_set_auxdata - sqlite3_shutdown - sqlite3_sleep - sqlite3_snprintf - sqlite3_sql - sqlite3_status - sqlite3_step - sqlite3_stmt_readonly - sqlite3_stmt_status -#ifdef XP_UNIX - sqlite3_temp_directory -#endif - sqlite3_thread_cleanup - sqlite3_total_changes - sqlite3_trace - sqlite3_transfer_bindings - sqlite3_unlock_notify - sqlite3_update_hook - sqlite3_uri_parameter - sqlite3_user_data - sqlite3_value_blob - sqlite3_value_bytes - sqlite3_value_bytes16 - sqlite3_value_double - sqlite3_value_int - sqlite3_value_int64 - sqlite3_value_numeric_type - sqlite3_value_text - sqlite3_value_text16 - sqlite3_value_text16be - sqlite3_value_text16le - sqlite3_value_type - sqlite3_version - sqlite3_vfs_find - sqlite3_vfs_unregister - sqlite3_vfs_register - sqlite3_vmprintf -#ifdef DEBUG - sqlite3_mutex_held - sqlite3_mutex_notheld -#endif diff --git a/db/sqlite3/src/sqlite.symbols b/db/sqlite3/src/sqlite.symbols new file mode 100644 index 000000000000..edd000a97c8c --- /dev/null +++ b/db/sqlite3/src/sqlite.symbols @@ -0,0 +1,159 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +sqlite3_aggregate_context +sqlite3_aggregate_count +sqlite3_auto_extension +sqlite3_bind_blob +sqlite3_bind_double +sqlite3_bind_int +sqlite3_bind_int64 +sqlite3_bind_null +sqlite3_bind_parameter_count +sqlite3_bind_parameter_index +sqlite3_bind_parameter_name +sqlite3_bind_text +sqlite3_bind_text16 +sqlite3_bind_value +sqlite3_busy_handler +sqlite3_busy_timeout +sqlite3_changes +sqlite3_clear_bindings +sqlite3_close +sqlite3_collation_needed +sqlite3_collation_needed16 +sqlite3_column_blob +sqlite3_column_bytes +sqlite3_column_bytes16 +sqlite3_column_count +sqlite3_column_decltype +sqlite3_column_decltype16 +sqlite3_column_double +sqlite3_column_int +sqlite3_column_int64 +sqlite3_column_name +sqlite3_column_name16 +sqlite3_column_text +sqlite3_column_text16 +sqlite3_column_type +sqlite3_column_value +sqlite3_commit_hook +sqlite3_complete +sqlite3_complete16 +sqlite3_config +sqlite3_create_collation +sqlite3_create_collation16 +sqlite3_create_function +sqlite3_create_function16 +sqlite3_create_module +sqlite3_data_count +sqlite3_db_filename +sqlite3_db_handle +sqlite3_db_mutex +sqlite3_db_status +sqlite3_declare_vtab +sqlite3_enable_load_extension +sqlite3_enable_shared_cache +sqlite3_errcode +sqlite3_errmsg +sqlite3_errmsg16 +sqlite3_exec +sqlite3_expired +sqlite3_extended_result_codes +sqlite3_file_control +sqlite3_finalize +sqlite3_free +sqlite3_free_table +sqlite3_get_autocommit +sqlite3_get_auxdata +sqlite3_get_table +sqlite3_global_recover +sqlite3_initialize +sqlite3_interrupt +sqlite3_last_insert_rowid +sqlite3_libversion +sqlite3_libversion_number +sqlite3_load_extension +sqlite3_malloc +sqlite3_memory_alarm +sqlite3_memory_highwater +sqlite3_memory_used +sqlite3_mutex_alloc +sqlite3_mutex_enter +sqlite3_mutex_free +sqlite3_mutex_leave +sqlite3_mutex_try +sqlite3_mprintf +sqlite3_next_stmt +sqlite3_open +sqlite3_open_v2 +sqlite3_open16 +sqlite3_overload_function +sqlite3_prepare +sqlite3_prepare16 +sqlite3_prepare16_v2 +sqlite3_prepare_v2 +sqlite3_profile +sqlite3_progress_handler +sqlite3_realloc +sqlite3_release_memory +sqlite3_reset +sqlite3_reset_auto_extension +sqlite3_result_blob +sqlite3_result_double +sqlite3_result_error +sqlite3_result_error16 +sqlite3_result_error_code +sqlite3_result_error_nomem +sqlite3_result_int +sqlite3_result_int64 +sqlite3_result_null +sqlite3_result_text +sqlite3_result_text16 +sqlite3_result_text16be +sqlite3_result_text16le +sqlite3_result_value +sqlite3_rollback_hook +sqlite3_set_authorizer +sqlite3_set_auxdata +sqlite3_shutdown +sqlite3_sleep +sqlite3_snprintf +sqlite3_sql +sqlite3_status +sqlite3_step +sqlite3_stmt_readonly +sqlite3_stmt_status +#ifdef XP_UNIX +sqlite3_temp_directory +#endif +sqlite3_thread_cleanup +sqlite3_total_changes +sqlite3_trace +sqlite3_transfer_bindings +sqlite3_unlock_notify +sqlite3_update_hook +sqlite3_uri_parameter +sqlite3_user_data +sqlite3_value_blob +sqlite3_value_bytes +sqlite3_value_bytes16 +sqlite3_value_double +sqlite3_value_int +sqlite3_value_int64 +sqlite3_value_numeric_type +sqlite3_value_text +sqlite3_value_text16 +sqlite3_value_text16be +sqlite3_value_text16le +sqlite3_value_type +sqlite3_version +sqlite3_vfs_find +sqlite3_vfs_unregister +sqlite3_vfs_register +sqlite3_vmprintf +#ifdef DEBUG +sqlite3_mutex_held +sqlite3_mutex_notheld +#endif diff --git a/devtools/client/animationinspector/test/browser_animation_empty_on_invalid_nodes.js b/devtools/client/animationinspector/test/browser_animation_empty_on_invalid_nodes.js index 3bd3925815e5..ea3d18662849 100644 --- a/devtools/client/animationinspector/test/browser_animation_empty_on_invalid_nodes.js +++ b/devtools/client/animationinspector/test/browser_animation_empty_on_invalid_nodes.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the panel shows no animation data for invalid or not animated nodes add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_participate_in_inspector_update.js b/devtools/client/animationinspector/test/browser_animation_participate_in_inspector_update.js index 674903bdfa3c..70e48ce37b85 100644 --- a/devtools/client/animationinspector/test/browser_animation_participate_in_inspector_update.js +++ b/devtools/client/animationinspector/test/browser_animation_participate_in_inspector_update.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the update of the animation panel participate in the // inspector-updated event. This means that the test verifies that the // inspector-updated event is emitted *after* the animation panel is ready. diff --git a/devtools/client/animationinspector/test/browser_animation_playerFronts_are_refreshed.js b/devtools/client/animationinspector/test/browser_animation_playerFronts_are_refreshed.js index cf9b8f79e529..9031418ae78c 100644 --- a/devtools/client/animationinspector/test/browser_animation_playerFronts_are_refreshed.js +++ b/devtools/client/animationinspector/test/browser_animation_playerFronts_are_refreshed.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the AnimationPlayerFront objects lifecycle is managed by the // AnimationController. diff --git a/devtools/client/animationinspector/test/browser_animation_playerWidgets_target_nodes.js b/devtools/client/animationinspector/test/browser_animation_playerWidgets_target_nodes.js index 9a3b803f646e..b4b102e9463c 100644 --- a/devtools/client/animationinspector/test/browser_animation_playerWidgets_target_nodes.js +++ b/devtools/client/animationinspector/test/browser_animation_playerWidgets_target_nodes.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that player widgets display information about target nodes add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_refresh_on_added_animation.js b/devtools/client/animationinspector/test/browser_animation_refresh_on_added_animation.js index f0f934c7b721..3c20fd52e137 100644 --- a/devtools/client/animationinspector/test/browser_animation_refresh_on_added_animation.js +++ b/devtools/client/animationinspector/test/browser_animation_refresh_on_added_animation.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the panel content refreshes when new animations are added. add_task(function*() { @@ -42,4 +44,4 @@ function* changeElementAndWait(options, panel, inspector) { yield promise.all([ onInspectorUpdated, onPanelUpdated, waitForAllAnimationTargets(panel)]); -} \ No newline at end of file +} diff --git a/devtools/client/animationinspector/test/browser_animation_refresh_on_removed_animation.js b/devtools/client/animationinspector/test/browser_animation_refresh_on_removed_animation.js index 4582f4044c11..3c45a19a1099 100644 --- a/devtools/client/animationinspector/test/browser_animation_refresh_on_removed_animation.js +++ b/devtools/client/animationinspector/test/browser_animation_refresh_on_removed_animation.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the panel content refreshes when animations are removed. add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_refresh_when_active.js b/devtools/client/animationinspector/test/browser_animation_refresh_when_active.js index 6ef11468b0a7..fe078ac542c3 100644 --- a/devtools/client/animationinspector/test/browser_animation_refresh_when_active.js +++ b/devtools/client/animationinspector/test/browser_animation_refresh_when_active.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the panel only refreshes when it is visible in the sidebar. add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js b/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js index 6b84f800c765..41bcd4dec98e 100644 --- a/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js +++ b/devtools/client/animationinspector/test/browser_animation_running_on_compositor.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that when animations displayed in the timeline are running on the // compositor, they get a special icon and information in the tooltip. diff --git a/devtools/client/animationinspector/test/browser_animation_same_nb_of_playerWidgets_and_playerFronts.js b/devtools/client/animationinspector/test/browser_animation_same_nb_of_playerWidgets_and_playerFronts.js index b47e39773d7f..c1a30ca3212f 100644 --- a/devtools/client/animationinspector/test/browser_animation_same_nb_of_playerWidgets_and_playerFronts.js +++ b/devtools/client/animationinspector/test/browser_animation_same_nb_of_playerWidgets_and_playerFronts.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that when playerFronts are updated, the same number of playerWidgets // are created in the panel. diff --git a/devtools/client/animationinspector/test/browser_animation_shows_player_on_valid_node.js b/devtools/client/animationinspector/test/browser_animation_shows_player_on_valid_node.js index 5a6b25507cb9..17fb85de458a 100644 --- a/devtools/client/animationinspector/test/browser_animation_shows_player_on_valid_node.js +++ b/devtools/client/animationinspector/test/browser_animation_shows_player_on_valid_node.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the panel shows an animation player when an animated node is // selected. diff --git a/devtools/client/animationinspector/test/browser_animation_target_highlight_select.js b/devtools/client/animationinspector/test/browser_animation_target_highlight_select.js index c537f534572e..cd03e6832234 100644 --- a/devtools/client/animationinspector/test/browser_animation_target_highlight_select.js +++ b/devtools/client/animationinspector/test/browser_animation_target_highlight_select.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the DOM element targets displayed in animation player widgets can // be used to highlight elements in the DOM and select them in the inspector. diff --git a/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js b/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js index ab64ba6f54f9..9c82797b2bb1 100644 --- a/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js +++ b/devtools/client/animationinspector/test/browser_animation_target_highlighter_lock.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the DOM element targets displayed in animation player widgets can // be used to highlight elements in the DOM and select them in the inspector. diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js b/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js index e0b7dd5c5376..2335d31ce9a7 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_currentTime.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline toolbar displays the current time, and that it // changes when animations are playing, gets back to 0 when animations are // rewound, and stops when animations are paused. diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_header.js b/devtools/client/animationinspector/test/browser_animation_timeline_header.js index 7f7c12b0f499..8945bec8a8b2 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_header.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_header.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline shows correct time graduations in the header. const {findOptimalTimeInterval} = require("devtools/client/animationinspector/utils"); diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js index 2cdcd9ba2338..51d91043f6cd 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline toolbar contains a pause button and that this pause // button can be clicked. Check that when it is, the current animations // displayed in the timeline get their playstates changed accordingly, and check diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js b/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js index 56341742fe1f..ba0c0ec9e137 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_rate_selector.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline toolbar contains a playback rate selector UI and that // it can be used to change the playback rate of animations in the timeline. // Also check that it displays the rate of the current animations in case they diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js b/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js index 7e42e1b1688f..bc80b411887e 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_rewind_button.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline toolbar contains a rewind button and that it can be // clicked. Check that when it is, the current animations displayed in the // timeline get their playstates changed to paused, and their currentTimes diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_exists.js b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_exists.js index e63f953a3af3..bf4bd61c87d0 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_exists.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_exists.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline does have a scrubber element. add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_movable.js b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_movable.js index 54fc349130d2..c6dcff83111e 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_movable.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_movable.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the scrubber in the timeline can be moved by clicking & dragging // in the header area. // Also check that doing so changes the timeline's play/pause button to paused diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js index c66fee6eed27..63f32d03006d 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_scrubber_moves.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the scrubber in the timeline moves when animations are playing. // The animations in the test page last for a very long time, so the test just // measures the position of the scrubber once, then waits for some time to pass diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_shows_delay.js b/devtools/client/animationinspector/test/browser_animation_timeline_shows_delay.js index b15c68499001..42c245083a8e 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_shows_delay.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_shows_delay.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that animation delay is visualized in the timeline when the animation // is delayed. // Also check that negative delays do not overflow the UI, and are shown like diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_shows_iterations.js b/devtools/client/animationinspector/test/browser_animation_timeline_shows_iterations.js index 3752254a64f8..dbd4d73e751d 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_shows_iterations.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_shows_iterations.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline is displays as many iteration elements as there are // iterations in an animation. diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js b/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js index 6259a5eb83eb..e2924eb37b74 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_shows_time_info.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline displays animations' duration, delay and iteration // counts in tooltips. diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_ui.js b/devtools/client/animationinspector/test/browser_animation_timeline_ui.js index dc62524d7ff3..bb0e826e122d 100644 --- a/devtools/client/animationinspector/test/browser_animation_timeline_ui.js +++ b/devtools/client/animationinspector/test/browser_animation_timeline_ui.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Check that the timeline contains the right elements. add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_toggle_button_resets_on_navigate.js b/devtools/client/animationinspector/test/browser_animation_toggle_button_resets_on_navigate.js index d57460043533..d66730095f96 100644 --- a/devtools/client/animationinspector/test/browser_animation_toggle_button_resets_on_navigate.js +++ b/devtools/client/animationinspector/test/browser_animation_toggle_button_resets_on_navigate.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that a page navigation resets the state of the global toggle button. add_task(function*() { diff --git a/devtools/client/animationinspector/test/browser_animation_toggle_button_toggles_animations.js b/devtools/client/animationinspector/test/browser_animation_toggle_button_toggles_animations.js index 384c89d3ec48..5885fec00904 100644 --- a/devtools/client/animationinspector/test/browser_animation_toggle_button_toggles_animations.js +++ b/devtools/client/animationinspector/test/browser_animation_toggle_button_toggles_animations.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the main toggle button actually toggles animations. // This test doesn't need to be extra careful about checking that *all* // animations have been paused (including inside iframes) because there's an diff --git a/devtools/client/animationinspector/test/browser_animation_toolbar_exists.js b/devtools/client/animationinspector/test/browser_animation_toolbar_exists.js index c2ddff879b2d..8ecc44ccfde0 100644 --- a/devtools/client/animationinspector/test/browser_animation_toolbar_exists.js +++ b/devtools/client/animationinspector/test/browser_animation_toolbar_exists.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that the animation panel has a top toolbar that contains the play/pause // button and that is displayed at all times. // Also test that this toolbar gets replaced by the timeline toolbar when there diff --git a/devtools/client/animationinspector/test/browser_animation_ui_updates_when_animation_data_changes.js b/devtools/client/animationinspector/test/browser_animation_ui_updates_when_animation_data_changes.js index 38e1c88f83a8..b27e2ebe39d2 100644 --- a/devtools/client/animationinspector/test/browser_animation_ui_updates_when_animation_data_changes.js +++ b/devtools/client/animationinspector/test/browser_animation_ui_updates_when_animation_data_changes.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Verify that if the animation's duration, iterations or delay change in // content, then the widget reflects the changes. diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_host-layout.js b/devtools/client/debugger/test/mochitest/browser_dbg_host-layout.js index f7c715c6f3ff..5376421d9188 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_host-layout.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_host-layout.js @@ -12,7 +12,7 @@ var gDefaultHostType = Services.prefs.getCharPref("devtools.toolbox.host"); function test() { // test is too slow on some platforms due to the number of test cases - requestLongerTimeout(2); + requestLongerTimeout(3); Task.spawn(function*() { yield testHosts(["bottom", "side", "window:big"], ["horizontal", "vertical", "horizontal"]); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js index 676878d245cd..8f7173ac3344 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests if opening the variables inspection popup preserves the highlighting * associated with the currently debugged line. diff --git a/devtools/client/fontinspector/test/browser_fontinspector.js b/devtools/client/fontinspector/test/browser_fontinspector.js index 3f90fad59ebb..17497d30448a 100644 --- a/devtools/client/fontinspector/test/browser_fontinspector.js +++ b/devtools/client/fontinspector/test/browser_fontinspector.js @@ -3,6 +3,8 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; +requestLongerTimeout(2); + const TEST_URI = BASE_URI + "browser_fontinspector.html"; const FONTS = [ {name: "Ostrich Sans Medium", remote: true, url: BASE_URI + "ostrich-regular.ttf", diff --git a/devtools/client/fontinspector/test/browser_fontinspector_theme-change.js b/devtools/client/fontinspector/test/browser_fontinspector_theme-change.js index 8096bb952966..6c42e6b6ac2b 100644 --- a/devtools/client/fontinspector/test/browser_fontinspector_theme-change.js +++ b/devtools/client/fontinspector/test/browser_fontinspector_theme-change.js @@ -3,6 +3,8 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; +requestLongerTimeout(2); + // Test that the preview images are updated when the theme changes. const { getTheme, setTheme } = require("devtools/client/shared/theme"); diff --git a/devtools/client/framework/test/browser_toolbox_options_disable_cache-01.js b/devtools/client/framework/test/browser_toolbox_options_disable_cache-01.js index b2ebc87df4d8..2625cf4703e4 100644 --- a/devtools/client/framework/test/browser_toolbox_options_disable_cache-01.js +++ b/devtools/client/framework/test/browser_toolbox_options_disable_cache-01.js @@ -3,6 +3,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; +requestLongerTimeout(2); + // Tests that disabling the cache for a tab works as it should when toolboxes // are not toggled. loadHelperScript("helper_disable_cache.js"); diff --git a/devtools/client/framework/test/browser_toolbox_options_disable_cache-02.js b/devtools/client/framework/test/browser_toolbox_options_disable_cache-02.js index 0f71c8579e06..3861d3cdb977 100644 --- a/devtools/client/framework/test/browser_toolbox_options_disable_cache-02.js +++ b/devtools/client/framework/test/browser_toolbox_options_disable_cache-02.js @@ -3,6 +3,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; +requestLongerTimeout(2); + // Tests that disabling the cache for a tab works as it should when toolboxes // are toggled. loadHelperScript("helper_disable_cache.js"); diff --git a/devtools/client/framework/test/browser_toolbox_tabsswitch_shortcuts.js b/devtools/client/framework/test/browser_toolbox_tabsswitch_shortcuts.js index b42a643ab83a..73c06e10a845 100644 --- a/devtools/client/framework/test/browser_toolbox_tabsswitch_shortcuts.js +++ b/devtools/client/framework/test/browser_toolbox_tabsswitch_shortcuts.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + var {Toolbox} = require("devtools/client/framework/toolbox"); var toolbox, toolIDs, idIndex, secondTime = false, diff --git a/devtools/client/framework/test/browser_toolbox_window_reload_target.js b/devtools/client/framework/test/browser_toolbox_window_reload_target.js index a99bc519fd1a..71a65b9a2b71 100644 --- a/devtools/client/framework/test/browser_toolbox_window_reload_target.js +++ b/devtools/client/framework/test/browser_toolbox_window_reload_target.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + const TEST_URL = "data:text/html;charset=utf-8,"+ "Test reload"+ "

Testing reload from devtools

"; diff --git a/devtools/client/inspector/test/browser_inspector_highlighter-inline.js b/devtools/client/inspector/test/browser_inspector_highlighter-inline.js index 0299f251320f..1abddafeff88 100644 --- a/devtools/client/inspector/test/browser_inspector_highlighter-inline.js +++ b/devtools/client/inspector/test/browser_inspector_highlighter-inline.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that highlighting various inline boxes displays the right number of // polygons in the page. diff --git a/devtools/client/markupview/test/browser_markupview_anonymous_02.js b/devtools/client/markupview/test/browser_markupview_anonymous_02.js index 6847f08658b2..d8dc826a163d 100644 --- a/devtools/client/markupview/test/browser_markupview_anonymous_02.js +++ b/devtools/client/markupview/test/browser_markupview_anonymous_02.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test XBL anonymous content in the markupview const TEST_URL = "chrome://devtools/content/scratchpad/scratchpad.xul"; diff --git a/devtools/client/markupview/test/browser_markupview_dragdrop_reorder.js b/devtools/client/markupview/test/browser_markupview_dragdrop_reorder.js index 8fafcc7ef8d7..98164e2a4fbd 100644 --- a/devtools/client/markupview/test/browser_markupview_dragdrop_reorder.js +++ b/devtools/client/markupview/test/browser_markupview_dragdrop_reorder.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test different kinds of drag and drop node re-ordering. const TEST_URL = TEST_URL_ROOT + "doc_markup_dragdrop.html"; diff --git a/devtools/client/markupview/test/browser_markupview_events_jquery_1.6.js b/devtools/client/markupview/test/browser_markupview_events_jquery_1.6.js index 78ecb01216e5..3c1e76962a29 100644 --- a/devtools/client/markupview/test/browser_markupview_events_jquery_1.6.js +++ b/devtools/client/markupview/test/browser_markupview_events_jquery_1.6.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that markup view event bubbles show the correct event info for jQuery // and jQuery Live events (jQuery version 1.6). diff --git a/devtools/client/markupview/test/browser_markupview_events_jquery_1.7.js b/devtools/client/markupview/test/browser_markupview_events_jquery_1.7.js index a1c316fba2ec..ad238b8059c0 100644 --- a/devtools/client/markupview/test/browser_markupview_events_jquery_1.7.js +++ b/devtools/client/markupview/test/browser_markupview_events_jquery_1.7.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that markup view event bubbles show the correct event info for jQuery // and jQuery Live events (jQuery version 1.7). diff --git a/devtools/client/markupview/test/browser_markupview_events_jquery_2.1.1.js b/devtools/client/markupview/test/browser_markupview_events_jquery_2.1.1.js index a43adb5a2e08..17bade18522a 100644 --- a/devtools/client/markupview/test/browser_markupview_events_jquery_2.1.1.js +++ b/devtools/client/markupview/test/browser_markupview_events_jquery_2.1.1.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Test that markup view event bubbles show the correct event info for jQuery // and jQuery Live events (jQuery version 2.1.1). diff --git a/devtools/client/markupview/test/browser_markupview_keybindings_01.js b/devtools/client/markupview/test/browser_markupview_keybindings_01.js index 3c37739b512a..39654d7ad57a 100644 --- a/devtools/client/markupview/test/browser_markupview_keybindings_01.js +++ b/devtools/client/markupview/test/browser_markupview_keybindings_01.js @@ -4,6 +4,8 @@ "use strict"; +requestLongerTimeout(2); + // Tests tabbing through attributes on a node const TEST_URL = "data:text/html;charset=utf8,
"; diff --git a/devtools/client/markupview/test/browser_markupview_keybindings_04.js b/devtools/client/markupview/test/browser_markupview_keybindings_04.js index 2529641b3e87..357ad4022438 100644 --- a/devtools/client/markupview/test/browser_markupview_keybindings_04.js +++ b/devtools/client/markupview/test/browser_markupview_keybindings_04.js @@ -5,6 +5,8 @@ "use strict"; +requestLongerTimeout(2); + // Tests that selecting a node using the browser context menu (inspect element) // or the element picker focuses that node so that the keyboard can be used // immediately. diff --git a/devtools/client/performance/test/browser_perf-categories-js-calltree.js b/devtools/client/performance/test/browser_perf-categories-js-calltree.js index 111c8fecd838..db82ac5a2372 100644 --- a/devtools/client/performance/test/browser_perf-categories-js-calltree.js +++ b/devtools/client/performance/test/browser_perf-categories-js-calltree.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the categories are shown in the js call tree when platform data * is enabled. diff --git a/devtools/client/performance/test/browser_perf-console-record-05.js b/devtools/client/performance/test/browser_perf-console-record-05.js index 5e92ce90a9d8..3f49aba7a28e 100644 --- a/devtools/client/performance/test/browser_perf-console-record-05.js +++ b/devtools/client/performance/test/browser_perf-console-record-05.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that multiple recordings with the same label (non-overlapping) appear * in the recording list. diff --git a/devtools/client/performance/test/browser_perf-details-03.js b/devtools/client/performance/test/browser_perf-details-03.js index 7b77a43e8581..6bfce6c0b50f 100644 --- a/devtools/client/performance/test/browser_perf-details-03.js +++ b/devtools/client/performance/test/browser_perf-details-03.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the details view hides the memory buttons when a recording does not * have memory data (withMemory: false), and that when a memory panel is selected, diff --git a/devtools/client/performance/test/browser_perf-details-04.js b/devtools/client/performance/test/browser_perf-details-04.js index f5af138a52e8..abb03af79205 100644 --- a/devtools/client/performance/test/browser_perf-details-04.js +++ b/devtools/client/performance/test/browser_perf-details-04.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the details view hides the toolbar buttons when a recording * doesn't exist or is in progress. diff --git a/devtools/client/performance/test/browser_perf-details-05.js b/devtools/client/performance/test/browser_perf-details-05.js index ccd3979c570a..740dfa99a276 100644 --- a/devtools/client/performance/test/browser_perf-details-05.js +++ b/devtools/client/performance/test/browser_perf-details-05.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the details view utility functions work as advertised. */ diff --git a/devtools/client/performance/test/browser_perf-details-06.js b/devtools/client/performance/test/browser_perf-details-06.js index 258bd1366fb1..9dbf74ec25e2 100644 --- a/devtools/client/performance/test/browser_perf-details-06.js +++ b/devtools/client/performance/test/browser_perf-details-06.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the views with `shouldUpdateWhileMouseIsActive` works as intended. */ diff --git a/devtools/client/performance/test/browser_perf-details-calltree-render.js b/devtools/client/performance/test/browser_perf-details-calltree-render.js index ec2aab652b84..61e6c0778bd5 100644 --- a/devtools/client/performance/test/browser_perf-details-calltree-render.js +++ b/devtools/client/performance/test/browser_perf-details-calltree-render.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the call tree view renders content after recording. */ diff --git a/devtools/client/performance/test/browser_perf-jit-view-01.js b/devtools/client/performance/test/browser_perf-jit-view-01.js index a5b6f1099ee9..552f08cb2bdc 100644 --- a/devtools/client/performance/test/browser_perf-jit-view-01.js +++ b/devtools/client/performance/test/browser_perf-jit-view-01.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the JIT Optimizations view renders optimization data * if on, and displays selected frames on focus. diff --git a/devtools/client/performance/test/browser_perf-legacy-front-01.js b/devtools/client/performance/test/browser_perf-legacy-front-01.js index 70c9642980cf..f01ee8b2ad17 100644 --- a/devtools/client/performance/test/browser_perf-legacy-front-01.js +++ b/devtools/client/performance/test/browser_perf-legacy-front-01.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that when setting recording features in the UI (like enabling framerate or memory), * if the target does not support these features, then the target's support overrides diff --git a/devtools/client/performance/test/browser_perf-legacy-front-02.js b/devtools/client/performance/test/browser_perf-legacy-front-02.js index 5587031ff6d0..0537fe6850b8 100644 --- a/devtools/client/performance/test/browser_perf-legacy-front-02.js +++ b/devtools/client/performance/test/browser_perf-legacy-front-02.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the recording model is populated correctly when using timeline * and memory actor mocks, and the correct views are shown. diff --git a/devtools/client/performance/test/browser_perf-loading-02.js b/devtools/client/performance/test/browser_perf-loading-02.js index 2519d112ae1a..09aa7f6f71e2 100644 --- a/devtools/client/performance/test/browser_perf-loading-02.js +++ b/devtools/client/performance/test/browser_perf-loading-02.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the details view is locked after recording has stopped and before * the recording has finished loading. diff --git a/devtools/client/performance/test/browser_perf-options-enable-framerate.js b/devtools/client/performance/test/browser_perf-options-enable-framerate.js index cc0cd274506f..5f39daa62325 100644 --- a/devtools/client/performance/test/browser_perf-options-enable-framerate.js +++ b/devtools/client/performance/test/browser_perf-options-enable-framerate.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that `enable-framerate` toggles the visibility of the fps graph, * as well as enabling ticks data on the PerformanceFront. diff --git a/devtools/client/performance/test/browser_perf-options-show-idle-blocks-01.js b/devtools/client/performance/test/browser_perf-options-show-idle-blocks-01.js index e8124223aaf8..d4d4ae6543ac 100644 --- a/devtools/client/performance/test/browser_perf-options-show-idle-blocks-01.js +++ b/devtools/client/performance/test/browser_perf-options-show-idle-blocks-01.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the js flamegraphs get rerendered when toggling `show-idle-blocks` */ diff --git a/devtools/client/performance/test/browser_perf-options-show-platform-data-01.js b/devtools/client/performance/test/browser_perf-options-show-platform-data-01.js index 251a8b40bc38..3868399aa19e 100644 --- a/devtools/client/performance/test/browser_perf-options-show-platform-data-01.js +++ b/devtools/client/performance/test/browser_perf-options-show-platform-data-01.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the js call tree views get rerendered when toggling `show-platform-data` */ diff --git a/devtools/client/performance/test/browser_perf-overview-selection-01.js b/devtools/client/performance/test/browser_perf-overview-selection-01.js index 7c1e5b4cc290..448160dc5201 100644 --- a/devtools/client/performance/test/browser_perf-overview-selection-01.js +++ b/devtools/client/performance/test/browser_perf-overview-selection-01.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that events are fired from OverviewView from selection manipulation. */ diff --git a/devtools/client/performance/test/browser_perf-overview-selection-02.js b/devtools/client/performance/test/browser_perf-overview-selection-02.js index 3f5541f47402..2e161da1a176 100644 --- a/devtools/client/performance/test/browser_perf-overview-selection-02.js +++ b/devtools/client/performance/test/browser_perf-overview-selection-02.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that the graphs' selection is correctly disabled or enabled. */ diff --git a/devtools/client/performance/test/browser_perf-private-browsing.js b/devtools/client/performance/test/browser_perf-private-browsing.js index c43d4a0b368a..5d6ce557d985 100644 --- a/devtools/client/performance/test/browser_perf-private-browsing.js +++ b/devtools/client/performance/test/browser_perf-private-browsing.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Tests that disables the frontend when in private browsing mode. */ diff --git a/devtools/client/performance/test/browser_perf-refresh.js b/devtools/client/performance/test/browser_perf-refresh.js index 345d9e096d31..24f6be284ad6 100644 --- a/devtools/client/performance/test/browser_perf-refresh.js +++ b/devtools/client/performance/test/browser_perf-refresh.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + /** * Rough test that the recording still continues after a refresh. */ diff --git a/devtools/client/shared/test/browser_filter-editor-05.js b/devtools/client/shared/test/browser_filter-editor-05.js index b12132b5e4ee..95d85098838f 100644 --- a/devtools/client/shared/test/browser_filter-editor-05.js +++ b/devtools/client/shared/test/browser_filter-editor-05.js @@ -3,6 +3,8 @@ "use strict"; +requestLongerTimeout(2); + // Tests the Filter Editor Widget's label-dragging const TEST_URI = "chrome://devtools/content/shared/widgets/filter-frame.xhtml"; diff --git a/devtools/client/sourceeditor/test/browser_vimemacs.js b/devtools/client/sourceeditor/test/browser_vimemacs.js index 05c12be89320..6680bc8628f9 100644 --- a/devtools/client/sourceeditor/test/browser_vimemacs.js +++ b/devtools/client/sourceeditor/test/browser_vimemacs.js @@ -3,6 +3,8 @@ "use strict"; +requestLongerTimeout(2); + const URI = "chrome://mochitests/content/browser/devtools/client" + "/sourceeditor/test/codemirror/vimemacs.html"; loadHelperScript("helper_codemirror_runner.js"); diff --git a/devtools/shared/heapsnapshot/AutoMemMap.cpp b/devtools/shared/heapsnapshot/AutoMemMap.cpp index 162ee5d5ede6..c9b821d787a7 100644 --- a/devtools/shared/heapsnapshot/AutoMemMap.cpp +++ b/devtools/shared/heapsnapshot/AutoMemMap.cpp @@ -29,7 +29,7 @@ AutoMemMap::~AutoMemMap() } nsresult -AutoMemMap::init(const char* filePath, PRIntn flags, PRIntn mode, PRFileMapProtect prot) +AutoMemMap::init(const char* filePath, int flags, int mode, PRFileMapProtect prot) { MOZ_ASSERT(!fd); MOZ_ASSERT(!fileMap); diff --git a/devtools/shared/heapsnapshot/AutoMemMap.h b/devtools/shared/heapsnapshot/AutoMemMap.h index 2b378704eb09..537d680042ec 100644 --- a/devtools/shared/heapsnapshot/AutoMemMap.h +++ b/devtools/shared/heapsnapshot/AutoMemMap.h @@ -54,7 +54,7 @@ public: ~AutoMemMap(); // Initialize this AutoMemMap. - nsresult init(const char* filePath, PRIntn flags = PR_RDONLY, PRIntn mode = 0, + nsresult init(const char* filePath, int flags = PR_RDONLY, int mode = 0, PRFileMapProtect prot = PR_PROT_READONLY); // Get the size of the memory mapped file. diff --git a/dom/base/nsWrapperCache.cpp b/dom/base/nsWrapperCache.cpp index 0b19e1a3630f..e1d88feaee10 100644 --- a/dom/base/nsWrapperCache.cpp +++ b/dom/base/nsWrapperCache.cpp @@ -9,6 +9,7 @@ #include "js/Class.h" #include "js/Proxy.h" #include "mozilla/dom/DOMJSProxyHandler.h" +#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/HoldDropJSObjects.h" #include "nsCycleCollectionTraversalCallback.h" #include "nsCycleCollector.h" @@ -24,11 +25,25 @@ nsWrapperCache::HasJSObjectMovedOp(JSObject* aWrapper) } #endif -/* static */ void +void nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder, nsScriptObjectTracer* aTracer) { cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer); + if (mWrapper && !JS::ObjectIsTenured(mWrapper)) { + CycleCollectedJSRuntime::Get()->NurseryWrapperPreserved(mWrapper); + } +} + +void +nsWrapperCache::SetWrapperJSObject(JSObject* aWrapper) +{ + mWrapper = aWrapper; + UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING); + + if (aWrapper && !JS::ObjectIsTenured(aWrapper)) { + CycleCollectedJSRuntime::Get()->NurseryWrapperAdded(this); + } } void diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index af645a66a8b4..0c8daaa35baa 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -258,14 +258,15 @@ protected: void TraceWrapper(JSTracer* aTrc, const char* name) { if (mWrapper) { - JS_CallObjectTracer(aTrc, &mWrapper, name); + JS_CallUnbarrieredObjectTracer(aTrc, &mWrapper, name); } } void PoisonWrapper() { if (mWrapper) { - mWrapper.setToCrashOnTouch(); + // See setToCrashOnTouch() in RootingAPI.h + mWrapper = reinterpret_cast(1); } } @@ -287,13 +288,7 @@ private: return mWrapper; } - void SetWrapperJSObject(JSObject* aWrapper) - { - mWrapper = aWrapper; - UnsetWrapperFlags(kWrapperFlagsMask & ~WRAPPER_IS_NOT_DOM_BINDING); - } - - void TraceWrapperJSObject(JSTracer* aTrc, const char* aName); + void SetWrapperJSObject(JSObject* aWrapper); FlagsType GetWrapperFlags() const { @@ -318,8 +313,8 @@ private: mFlags &= ~aFlagsToUnset; } - static void HoldJSObjects(void* aScriptObjectHolder, - nsScriptObjectTracer* aTracer); + void HoldJSObjects(void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer); #ifdef DEBUG public: @@ -349,8 +344,8 @@ private: enum { kWrapperFlagsMask = (WRAPPER_BIT_PRESERVED | WRAPPER_IS_NOT_DOM_BINDING) }; - JS::Heap mWrapper; - FlagsType mFlags; + JSObject* mWrapper; + FlagsType mFlags; }; enum { WRAPPER_CACHE_FLAGS_BITS_USED = 2 }; diff --git a/dom/base/nsWrapperCacheInlines.h b/dom/base/nsWrapperCacheInlines.h index 6bba5350acf9..f91e5db591ea 100644 --- a/dom/base/nsWrapperCacheInlines.h +++ b/dom/base/nsWrapperCacheInlines.h @@ -53,10 +53,4 @@ nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis) return IsBlack() && HasNothingToTrace(aThis); } -inline void -nsWrapperCache::TraceWrapperJSObject(JSTracer* aTrc, const char* aName) -{ - JS_CallObjectTracer(aTrc, &mWrapper, aName); -} - #endif /* nsWrapperCache_h___ */ diff --git a/dom/base/test/browser_use_counters.js b/dom/base/test/browser_use_counters.js index 304a831039aa..48a3b76abc6b 100644 --- a/dom/base/test/browser_use_counters.js +++ b/dom/base/test/browser_use_counters.js @@ -1,5 +1,7 @@ /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +requestLongerTimeout(2); + var {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); const gHttpTestRoot = "http://example.com/browser/dom/base/test/"; diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 66d66c9fb879..6dfe6825f270 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -422,6 +422,8 @@ class CGDOMJSClass(CGThing): classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount traceHook = 'nullptr' reservedSlots = slotCount + if self.descriptor.interface.isProbablyShortLivingObject(): + classFlags += " | JSCLASS_SKIP_NURSERY_FINALIZE" if self.descriptor.interface.getExtendedAttribute("NeedResolve"): resolveHook = RESOLVE_HOOK_NAME mayResolveHook = MAY_RESOLVE_HOOK_NAME diff --git a/dom/bindings/Makefile.in b/dom/bindings/Makefile.in index 8875e103518c..2161aa5a17e9 100644 --- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -2,7 +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/. -abs_dist := $(abspath $(DIST)) webidl_base := $(topsrcdir)/dom/webidl # Generated by moz.build diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index bee6af4d92cc..e664988d2c01 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -564,6 +564,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins): def isJSImplemented(self): return False + def isProbablyShortLivingObject(self): + return False + def getNavigatorProperty(self): return None @@ -1408,7 +1411,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): identifier == "ChromeOnly" or identifier == "Unforgeable" or identifier == "UnsafeInPrerendering" or - identifier == "LegacyEventInit"): + identifier == "LegacyEventInit" or + identifier == "ProbablyShortLivingObject"): # Known extended attributes that do not take values if not attr.noArguments(): raise WebIDLError("[%s] must take no arguments" % identifier, @@ -1522,6 +1526,14 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): def isJSImplemented(self): return bool(self.getJSImplementation()) + def isProbablyShortLivingObject(self): + current = self + while current: + if current.getExtendedAttribute("ProbablyShortLivingObject"): + return True + current = current.parent + return False + def getNavigatorProperty(self): naviProp = self.getExtendedAttribute("NavigatorProperty") if not naviProp: diff --git a/dom/canvas/WebGLContextBuffers.cpp b/dom/canvas/WebGLContextBuffers.cpp index 7a221782e8d7..1e6497c9b43c 100644 --- a/dom/canvas/WebGLContextBuffers.cpp +++ b/dom/canvas/WebGLContextBuffers.cpp @@ -177,7 +177,9 @@ WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage) } boundBuffer->SetByteLength(size); + if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) { + boundBuffer->SetByteLength(0); return ErrorOutOfMemory("bufferData: out of memory"); } } @@ -227,9 +229,12 @@ WebGLContext::BufferDataT(GLenum target, } boundBuffer->SetByteLength(data.LengthAllowShared()); + // Warning: Possibly shared memory. See bug 1225033. - if (!boundBuffer->ElementArrayCacheBufferData(data.DataAllowShared(), data.LengthAllowShared())) + if (!boundBuffer->ElementArrayCacheBufferData(data.DataAllowShared(), data.LengthAllowShared())) { + boundBuffer->SetByteLength(0); return ErrorOutOfMemory("bufferData: out of memory"); + } } void diff --git a/dom/devicestorage/DeviceStorageStatics.cpp b/dom/devicestorage/DeviceStorageStatics.cpp index d8fed46d4ad3..6db92455366d 100644 --- a/dom/devicestorage/DeviceStorageStatics.cpp +++ b/dom/devicestorage/DeviceStorageStatics.cpp @@ -131,6 +131,30 @@ DeviceStorageStatics::InitDirs() sMutex.AssertCurrentThreadOwns(); DS_LOG_INFO(""); +#if !defined(MOZ_WIDGET_GONK) + if (!XRE_IsParentProcess()) { + // For gonk, we have the parent process forward the directory information + // to the child using ContentParent::ForwardKnownInfo. On desktop, this + // winds up slowing down the startup (in particular ts_paint), so rather + // than penalize all e10s processes, we do a synchronous IPC call here, + // which only penalizes child processes which actually use DeviceStorage. + + dom::ContentChild* child = dom::ContentChild::GetSingleton(); + DeviceStorageLocationInfo locationInfo; + child->SendGetDeviceStorageLocations(&locationInfo); + + NS_NewLocalFile(locationInfo.apps(), true, getter_AddRefs(sInstance->mDirs[TYPE_APPS])); + NS_NewLocalFile(locationInfo.crashes(), true, getter_AddRefs(sInstance->mDirs[TYPE_CRASHES])); + NS_NewLocalFile(locationInfo.pictures(), true, getter_AddRefs(sInstance->mDirs[TYPE_PICTURES])); + NS_NewLocalFile(locationInfo.videos(), true, getter_AddRefs(sInstance->mDirs[TYPE_VIDEOS])); + NS_NewLocalFile(locationInfo.music(), true, getter_AddRefs(sInstance->mDirs[TYPE_MUSIC])); + NS_NewLocalFile(locationInfo.sdcard(), true, getter_AddRefs(sInstance->mDirs[TYPE_SDCARD])); + + sInstance->mInitialized = true; + return; + } +#endif + nsCOMPtr dirService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); MOZ_ASSERT(dirService); @@ -271,6 +295,13 @@ DeviceStorageStatics::DumpDirs() nullptr }; + const char* ptStr; + if (XRE_IsParentProcess()) { + ptStr = "parent"; + } else { + ptStr = "child"; + } + for (uint32_t i = 0; i < TYPE_COUNT; ++i) { MOZ_ASSERT(storageTypes[i]); @@ -278,8 +309,8 @@ DeviceStorageStatics::DumpDirs() if (mDirs[i]) { mDirs[i]->GetPath(path); } - DS_LOG_INFO("%s: '%s'", - storageTypes[i], NS_LossyConvertUTF16toASCII(path).get()); + DS_LOG_INFO("(%s) %s: '%s'", + ptStr, storageTypes[i], NS_LossyConvertUTF16toASCII(path).get()); } #endif } @@ -297,6 +328,23 @@ DeviceStorageStatics::Shutdown() Preferences::RemoveObserver(this, kPrefWritableName); } +/* static */ void +DeviceStorageStatics::GetDeviceStorageLocationsForIPC( + DeviceStorageLocationInfo* aLocationInfo) +{ + MOZ_ASSERT(XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); + + InitializeDirs(); + + GetDirPath(TYPE_APPS, aLocationInfo->apps()); + GetDirPath(TYPE_CRASHES, aLocationInfo->crashes()); + GetDirPath(TYPE_PICTURES, aLocationInfo->pictures()); + GetDirPath(TYPE_VIDEOS, aLocationInfo->videos()); + GetDirPath(TYPE_MUSIC, aLocationInfo->music()); + GetDirPath(TYPE_SDCARD, aLocationInfo->sdcard()); +} + /* static */ already_AddRefed DeviceStorageStatics::GetDir(DeviceStorageType aType) { @@ -332,6 +380,16 @@ DeviceStorageStatics::GetDir(DeviceStorageType aType) return file.forget(); } +/* static */ void +DeviceStorageStatics::GetDirPath(DeviceStorageType aType, nsString& aDirPath) +{ + aDirPath.Truncate(); + nsCOMPtr file = GetDir(aType); + if (file) { + file->GetPath(aDirPath); + } +} + /* static */ bool DeviceStorageStatics::HasOverrideRootDir() { diff --git a/dom/devicestorage/DeviceStorageStatics.h b/dom/devicestorage/DeviceStorageStatics.h index 5fa7d9b4164e..2c8fa0b0f07e 100644 --- a/dom/devicestorage/DeviceStorageStatics.h +++ b/dom/devicestorage/DeviceStorageStatics.h @@ -8,7 +8,12 @@ #define mozilla_dom_devicestorage_DeviceStorageStatics_h #include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/StaticPtr.h" +#include "nsArrayUtils.h" +class nsString; class nsDOMDeviceStorage; class DeviceStorageFile; #ifdef MOZ_WIDGET_GONK @@ -35,6 +40,8 @@ public: static void GetWritableName(nsString& aName); static void SetWritableName(const nsAString& aName); + static void GetDeviceStorageLocationsForIPC(DeviceStorageLocationInfo* aLocationInfo); + static bool HasOverrideRootDir(); static already_AddRefed GetAppsDir(); static already_AddRefed GetCrashesDir(); @@ -56,6 +63,7 @@ private: }; static already_AddRefed GetDir(DeviceStorageType aType); + static void GetDirPath(DeviceStorageType aType, nsString& aString); DeviceStorageStatics(); virtual ~DeviceStorageStatics(); diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index 9d12b2fb4609..e600094e90c9 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -237,9 +237,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END JSObject* Event::WrapObject(JSContext* aCx, JS::Handle aGivenProto) { - if (mIsMainThreadEvent && !GetWrapperPreserveColor()) { - nsJSContext::LikelyShortLivingObjectCreated(); - } return WrapObjectInternal(aCx, aGivenProto); } diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 819e8a5bc336..9584a14d4319 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1210,6 +1210,10 @@ EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent, return retval; } + case ePluginEventClass: { + *aStatus = nsEventStatus_eConsumeNoDefault; + return remote->SendPluginEvent(*aEvent->AsPluginEvent()); + } default: { MOZ_CRASH("Attempt to send non-whitelisted event?"); } diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index fbcdb4cdea74..f2cefeb44ca0 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -20,6 +20,21 @@ #include "mozilla/unused.h" #include "mozilla/dom/TabParent.h" +#ifdef XP_MACOSX +// Some defiens will be conflict with OSX SDK +#define TextRange _TextRange +#define TextRangeArray _TextRangeArray +#define Comment _Comment +#endif + +#include "nsPluginInstanceOwner.h" + +#ifdef XP_MACOSX +#undef TextRange +#undef TextRangeArray +#undef Comment +#endif + using namespace mozilla::widget; namespace mozilla { @@ -117,12 +132,26 @@ TextComposition::CloneAndDispatchAs( nsEventStatus* status = aStatus ? aStatus : &dummyStatus; if (aMessage == eCompositionUpdate) { mLastData = compositionEvent.mData; + mLastRanges = aCompositionEvent->mRanges; } - EventDispatcher::Dispatch(mNode, mPresContext, - &compositionEvent, nullptr, status, aCallBack); + + DispatchEvent(&compositionEvent, status, aCallBack, aCompositionEvent); return compositionEvent.mFlags; } +void +TextComposition::DispatchEvent(WidgetCompositionEvent* aDispatchEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallBack, + const WidgetCompositionEvent *aOriginalEvent) +{ + nsPluginInstanceOwner::GeneratePluginEvent(aOriginalEvent, + aDispatchEvent); + + EventDispatcher::Dispatch(mNode, mPresContext, + aDispatchEvent, nullptr, aStatus, aCallBack); +} + void TextComposition::OnCompositionEventDiscarded( WidgetCompositionEvent* aCompositionEvent) @@ -217,6 +246,7 @@ TextComposition::DispatchCompositionEvent( aCompositionEvent->mFlags.mPropagationStopped = true; if (aCompositionEvent->CausesDOMTextEvent()) { mLastData = aCompositionEvent->mData; + mLastRanges = aCompositionEvent->mRanges; // Although, the composition event hasn't been actually handled yet, // emulate an editor to be handling the composition event. EditorWillHandleCompositionChangeEvent(aCompositionEvent); @@ -341,8 +371,7 @@ TextComposition::DispatchCompositionEvent( CloneAndDispatchAs(aCompositionEvent, eCompositionChange, aStatus, aCallBack); } else { - EventDispatcher::Dispatch(mNode, mPresContext, - aCompositionEvent, nullptr, aStatus, aCallBack); + DispatchEvent(aCompositionEvent, aStatus, aCallBack); } } else { *aStatus = nsEventStatus_eConsumeNoDefault; diff --git a/dom/events/TextComposition.h b/dom/events/TextComposition.h index 12cca5bbff11..6ddcde248019 100644 --- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -61,6 +61,10 @@ public: // Note that mString and mLastData are different between dispatcing // compositionupdate and compositionchange event handled by focused editor. const nsString& String() const { return mString; } + // The latest clauses range of the composition string. + // During compositionupdate event, GetRanges() returns old ranges. + // So if getting on compositionupdate, Use GetLastRange instead of GetRange(). + TextRangeArray* GetLastRanges() const { return mLastRanges; } // Returns the clauses and/or caret range of the composition string. // This is modified at a call of EditorWillHandleCompositionChangeEvent(). // This may return null if there is no clauses and caret. @@ -191,6 +195,9 @@ private: // This is the clause and caret range information which is managed by // the focused editor. This may be null if there is no clauses or caret. RefPtr mRanges; + // Same as mRange, but mRange will have old data during compositionupdate. + // So this will be valied during compositionupdate. + RefPtr mLastRanges; // mNativeContext stores a opaque pointer. This works as the "ID" for this // composition. Don't access the instance, it may not be available. @@ -293,6 +300,15 @@ private: EventDispatchingCallback* aCallBack, bool aIsSynthesized); + /** + * Simply calling EventDispatcher::Dispatch() with plugin event. + * If dispatching event has no orginal clone, aOriginalEvent can be null. + */ + void DispatchEvent(WidgetCompositionEvent* aDispatchEvent, + nsEventStatus* aStatus, + EventDispatchingCallback* aCallback, + const WidgetCompositionEvent *aOriginalEvent = nullptr); + /** * HandleSelectionEvent() sends the selection event to ContentEventHandler * or dispatches it to the focused child process. diff --git a/dom/html/HTMLSharedListElement.cpp b/dom/html/HTMLSharedListElement.cpp index 61d5ba15d385..e63a980a36e8 100644 --- a/dom/html/HTMLSharedListElement.cpp +++ b/dom/html/HTMLSharedListElement.cpp @@ -99,11 +99,8 @@ HTMLSharedListElement::MapAttributesIntoRule(const nsMappedAttributes* aAttribut if (listStyleType->GetUnit() == eCSSUnit_Null) { // type: enum const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::type); - if (value) { - if (value->Type() == nsAttrValue::eEnum) - listStyleType->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated); - else - listStyleType->SetIntValue(NS_STYLE_LIST_STYLE_DECIMAL, eCSSUnit_Enumerated); + if (value && value->Type() == nsAttrValue::eEnum) { + listStyleType->SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated); } } } diff --git a/dom/html/test/browser_bug1108547.js b/dom/html/test/browser_bug1108547.js index a36177e865a2..ee872e199586 100644 --- a/dom/html/test/browser_bug1108547.js +++ b/dom/html/test/browser_bug1108547.js @@ -1,6 +1,8 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +requestLongerTimeout(2); + function test() { waitForExplicitFinish(); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index d40cb331ca5b..9d6675139f7d 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -30,6 +30,7 @@ #include "AudioChannelService.h" #include "BlobParent.h" #include "CrashReporterParent.h" +#include "DeviceStorageStatics.h" #include "GMPServiceParent.h" #include "HandlerServiceParent.h" #include "IHistory.h" @@ -5780,6 +5781,13 @@ ContentParent::RecvGetDeviceStorageLocation(const nsString& aType, #endif } +bool +ContentParent::RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info) +{ + DeviceStorageStatics::GetDeviceStorageLocationsForIPC(info); + return true; +} + bool ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index c6b0fafa16b3..d28ac058989b 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -948,6 +948,8 @@ private: virtual bool RecvGetDeviceStorageLocation(const nsString& aType, nsString* aPath) override; + virtual bool RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info) override; + virtual bool RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo) override; // If you add strong pointers to cycle collected objects here, be sure to diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 61dc5a4ce717..a5367aab0480 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -52,6 +52,7 @@ using class mozilla::WidgetDragEvent from "ipc/nsGUIEventIPC.h"; using struct nsRect from "nsRect.h"; using class mozilla::WidgetSelectionEvent from "ipc/nsGUIEventIPC.h"; using class mozilla::WidgetTouchEvent from "ipc/nsGUIEventIPC.h"; +using class mozilla::WidgetPluginEvent from "ipc/nsGUIEventIPC.h"; using struct mozilla::dom::RemoteDOMEvent from "mozilla/dom/TabMessageUtils.h"; using mozilla::dom::ScreenOrientationInternal from "mozilla/dom/ScreenOrientation.h"; using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h"; @@ -280,6 +281,16 @@ parent: */ prio(urgent) async SetPluginFocused(bool aFocused); + /** + * Set IME candidate window by windowless plugin if plugin has focus. + */ + async SetCandidateWindowForPlugin(int32_t aX, int32_t aY); + + /** + * When plugin event isn't consumed, call this + */ + async DefaultProcOfPluginEvent(WidgetPluginEvent aEvent); + /** * Request that the parent process move focus to the browser's frame. If * canRaise is true, the window can be raised if it is inactive. @@ -634,6 +645,7 @@ child: uint64_t aInputBlockId, nsEventStatus aApzResponse); RealDragEvent(WidgetDragEvent aEvent, uint32_t aDragAction, uint32_t aDropEffect); + PluginEvent(WidgetPluginEvent aEvent); /** * @see nsIDOMWindowUtils sendKeyEvent. diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 95ba01c98a75..d516cb777a57 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -219,6 +219,15 @@ union DeviceStorageParams DeviceStorageUnmountParams; }; +struct DeviceStorageLocationInfo { + nsString music; + nsString pictures; + nsString videos; + nsString sdcard; + nsString apps; + nsString crashes; +}; + struct FMRadioRequestEnableParams { double frequency; @@ -1163,6 +1172,9 @@ parent: sync GetDeviceStorageLocation(nsString type) returns (nsString path); + sync GetDeviceStorageLocations() + returns (DeviceStorageLocationInfo info); + sync GetAndroidSystemInfo() returns (AndroidSystemInfo info); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index b07b65018ecb..056b4ae1c030 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1943,6 +1943,19 @@ TabChild::RecvRealDragEvent(const WidgetDragEvent& aEvent, return true; } +bool +TabChild::RecvPluginEvent(const WidgetPluginEvent& aEvent) +{ + WidgetPluginEvent localEvent(aEvent); + localEvent.widget = mPuppetWidget; + nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent); + if (status != nsEventStatus_eConsumeNoDefault) { + // If not consumed, we should call default action + SendDefaultProcOfPluginEvent(aEvent); + } + return true; +} + void TabChild::RequestNativeKeyBindings(AutoCacheNativeKeyCommands* aAutoCache, WidgetKeyboardEvent* aEvent) diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 1ba716afafe0..83c030a4159b 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -379,6 +379,7 @@ public: const nsString& aEvent) override; virtual bool RecvNativeSynthesisResponse(const uint64_t& aObserverId, const nsCString& aResponse) override; + virtual bool RecvPluginEvent(const WidgetPluginEvent& aEvent) override; virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event) override; virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event) override; virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture) override; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index e05afeb186a1..95913d99e6d1 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2396,6 +2396,31 @@ TabParent::RecvSetPluginFocused(const bool& aFocused) return true; } + bool +TabParent::RecvSetCandidateWindowForPlugin(const int32_t& aX, + const int32_t& aY) +{ + nsCOMPtr widget = GetWidget(); + if (!widget) { + return true; + } + + widget->SetCandidateWindowForPlugin(aX, aY); + return true; +} + +bool +TabParent::RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) +{ + nsCOMPtr widget = GetWidget(); + if (!widget) { + return true; + } + + widget->DefaultProcOfPluginEvent(aEvent); + return true; +} + bool TabParent::RecvGetInputContext(int32_t* aIMEEnabled, int32_t* aIMEOpen) diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 4d533f8bebf6..5b1efe49483d 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -196,6 +196,10 @@ public: const int32_t& aPanelY, nsString* aCommitted) override; virtual bool RecvSetPluginFocused(const bool& aFocused) override; + virtual bool RecvSetCandidateWindowForPlugin(const int32_t& aX, + const int32_t& aY) override; + virtual bool RecvDefaultProcOfPluginEvent( + const WidgetPluginEvent& aEvent) override; virtual bool RecvGetInputContext(int32_t* aIMEEnabled, int32_t* aIMEOpen) override; virtual bool RecvSetInputContext(const int32_t& aIMEEnabled, diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js index edb6a76d3a9b..f7358d6f3ac8 100644 --- a/dom/media/PeerConnection.js +++ b/dom/media/PeerConnection.js @@ -1038,6 +1038,34 @@ RTCPeerConnection.prototype = { }); }, + _setParameters: function(sender, parameters) { + if (!Services.prefs.getBoolPref("media.peerconnection.simulcast")) { + return; + } + // validate parameters input + var encodings = parameters.encodings || []; + + encodings.reduce((uniqueRids, encoding) => { + if (!encoding.rid && encodings.length > 1) { + throw new this._win.DOMException("Missing rid", "TypeError"); + } + if (uniqueRids[encoding.rid]) { + throw new this._win.DOMException("Duplicate rid", "TypeError"); + } + uniqueRids[encoding.rid] = true; + return uniqueRids; + }, {}); + + this._impl.setParameters(sender.track, parameters); + }, + + _getParameters: function(sender) { + if (!Services.prefs.getBoolPref("media.peerconnection.simulcast")) { + return; + } + return this._impl.getParameters(sender.track); + }, + close: function() { if (this._closed) { return; @@ -1494,6 +1522,14 @@ RTCRtpSender.prototype = { replaceTrack: function(withTrack) { return this._pc._chain(() => this._pc._replaceTrack(this, withTrack)); + }, + + setParameters: function(parameters) { + return this._pc._setParameters(this, parameters); + }, + + getParameters: function() { + return this._pc._getParameters(this); } }; diff --git a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp index 3dafa11fa19d..8fc94ef3951b 100644 --- a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp @@ -67,10 +67,8 @@ FFmpegH264Decoder::FFmpegH264Decoder( ImageContainer* aImageContainer) : FFmpegDataDecoder(aTaskQueue, aCallback, GetCodecId(aConfig.mMimeType)) , mImageContainer(aImageContainer) - , mPictureWidth(aConfig.mImage.width) - , mPictureHeight(aConfig.mImage.height) - , mDisplayWidth(aConfig.mDisplay.width) - , mDisplayHeight(aConfig.mDisplay.height) + , mDisplay(aConfig.mDisplay) + , mImage(aConfig.mImage) { MOZ_COUNT_CTOR(FFmpegH264Decoder); // Use a new MediaByteBuffer as the object will be modified during initialization. @@ -87,8 +85,8 @@ FFmpegH264Decoder::Init() mCodecContext->get_buffer = AllocateBufferCb; mCodecContext->release_buffer = ReleaseBufferCb; - mCodecContext->width = mPictureWidth; - mCodecContext->height = mPictureHeight; + mCodecContext->width = mImage.width; + mCodecContext->height = mImage.height; return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__); } @@ -207,7 +205,7 @@ FFmpegH264Decoder::DoDecodeFrame(MediaRawData* aSample, } VideoInfo info; - info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight); + info.mDisplay = mDisplay; VideoData::YCbCrBuffer b; b.mPlanes[0].mData = mFrame->data[0]; @@ -236,7 +234,7 @@ FFmpegH264Decoder::DoDecodeFrame(MediaRawData* aSample, b, !!mFrame->key_frame, -1, - gfx::IntRect(0, 0, mCodecContext->width, mCodecContext->height)); + mImage); if (!v) { NS_WARNING("image allocation error."); mCallback->Error(); diff --git a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.h b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.h index 5a89815dba5e..b35d601cf2e5 100644 --- a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.h +++ b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.h @@ -64,10 +64,8 @@ private: static void ReleaseBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame); RefPtr mImageContainer; - uint32_t mPictureWidth; - uint32_t mPictureHeight; - uint32_t mDisplayWidth; - uint32_t mDisplayHeight; + nsIntSize mDisplay; + nsIntRect mImage; class PtsCorrectionContext { public: diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index 323970df4e87..5d23ed830abc 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -147,6 +147,8 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' & [test_peerConnection_setLocalAnswerInHaveLocalOffer.html] [test_peerConnection_setLocalAnswerInStable.html] [test_peerConnection_setLocalOfferInHaveRemoteOffer.html] +[test_peerConnection_setParameters.html] +skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator) [test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html] [test_peerConnection_setRemoteAnswerInStable.html] [test_peerConnection_setRemoteOfferInHaveLocalOffer.html] diff --git a/dom/media/tests/mochitest/test_peerConnection_setParameters.html b/dom/media/tests/mochitest/test_peerConnection_setParameters.html new file mode 100644 index 000000000000..2b5733c0bc92 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_setParameters.html @@ -0,0 +1,89 @@ + + + + + + +
+
+
+ + diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 15eff7a7419b..b132753d90af 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -191,11 +191,11 @@ nsPluginHost *nsPluginHost::sInst; /* we should probably put this into a global library now that this is the second time we need this. */ static -PRInt32 -busy_beaver_PR_Read(PRFileDesc *fd, void * start, PRInt32 len) +int32_t +busy_beaver_PR_Read(PRFileDesc *fd, void * start, int32_t len) { int n; - PRInt32 remaining = len; + int32_t remaining = len; while (remaining > 0) { diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index fed6b11e52fb..5ba6fb04d020 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -60,6 +60,9 @@ using mozilla::DefaultXDisplay; #include "nsFrameSelection.h" #include "PuppetWidget.h" #include "nsPIWindowRoot.h" +#include "mozilla/IMEStateManager.h" +#include "mozilla/TextComposition.h" +#include "mozilla/AutoRestore.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" @@ -366,6 +369,11 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() mFullScreen = false; mJavaView = nullptr; #endif + +#ifdef XP_WIN + mGotCompositionData = false; + mSentStartComposition = false; +#endif } nsPluginInstanceOwner::~nsPluginInstanceOwner() @@ -791,7 +799,185 @@ nsPluginInstanceOwner::SetNetscapeWindowAsParent(HWND aWindowToAdopt) reinterpret_cast(aWindowToAdopt)); return NS_OK; } -#endif + +bool +nsPluginInstanceOwner::GetCompositionString(uint32_t aType, + nsTArray* aDist, + int32_t* aLength) +{ + // Mark pkugin calls ImmGetCompositionStringW correctly + mGotCompositionData = true; + + RefPtr composition = GetTextComposition(); + if (NS_WARN_IF(!composition)) { + return false; + } + + switch(aType) { + case GCS_COMPSTR: { + if (!composition->IsComposing()) { + *aLength = 0; + return true; + } + + uint32_t len = composition->LastData().Length() * sizeof(char16_t); + if (len) { + aDist->SetLength(len); + memcpy(aDist->Elements(), composition->LastData().get(), len); + } + *aLength = len; + return true; + } + + case GCS_RESULTSTR: { + if (composition->IsComposing()) { + *aLength = 0; + return true; + } + + uint32_t len = composition->LastData().Length() * sizeof(char16_t); + if (len) { + aDist->SetLength(len); + memcpy(aDist->Elements(), composition->LastData().get(), len); + } + *aLength = len; + return true; + } + + case GCS_CURSORPOS: { + *aLength = 0; + TextRangeArray* ranges = composition->GetLastRanges(); + if (!ranges) { + return true; + } + *aLength = ranges->GetCaretPosition(); + if (*aLength < 0) { + return false; + } + return true; + } + + case GCS_COMPATTR: { + TextRangeArray* ranges = composition->GetLastRanges(); + if (!ranges || ranges->IsEmpty()) { + *aLength = 0; + return true; + } + + aDist->SetLength(composition->LastData().Length()); + memset(aDist->Elements(), ATTR_INPUT, aDist->Length()); + + for (TextRange& range : *ranges) { + uint8_t type = ATTR_INPUT; + switch(range.mRangeType) { + case NS_TEXTRANGE_RAWINPUT: + type = ATTR_INPUT; + break; + case NS_TEXTRANGE_SELECTEDRAWTEXT: + type = ATTR_TARGET_NOTCONVERTED; + break; + case NS_TEXTRANGE_CONVERTEDTEXT: + type = ATTR_CONVERTED; + break; + case NS_TEXTRANGE_SELECTEDCONVERTEDTEXT: + type = ATTR_TARGET_CONVERTED; + break; + default: + continue; + } + + size_t minLen = std::min(range.mEndOffset, aDist->Length()); + for (size_t i = range.mStartOffset; i < minLen; i++) { + (*aDist)[i] = type; + } + } + *aLength = aDist->Length(); + return true; + } + + case GCS_COMPCLAUSE: { + RefPtr ranges = composition->GetLastRanges(); + if (!ranges || ranges->IsEmpty()) { + aDist->SetLength(sizeof(uint32_t)); + memset(aDist->Elements(), 0, sizeof(uint32_t)); + *aLength = aDist->Length(); + return true; + } + nsAutoTArray clauses; + clauses.AppendElement(0); + for (TextRange& range : *ranges) { + if (!range.IsClause()) { + continue; + } + clauses.AppendElement(range.mEndOffset); + } + + aDist->SetLength(clauses.Length() * sizeof(uint32_t)); + memcpy(aDist->Elements(), clauses.Elements(), aDist->Length()); + *aLength = aDist->Length(); + return true; + } + + case GCS_RESULTREADSTR: { + // When returning error causes unexpected error, so we return 0 instead. + *aLength = 0; + return true; + } + + case GCS_RESULTCLAUSE: { + // When returning error causes unexpected error, so we return 0 instead. + *aLength = 0; + return true; + } + + default: + NS_WARNING( + nsPrintfCString("Unsupported type %x of ImmGetCompositionStringW hook", + aType).get()); + break; + } + + return false; +} + +bool +nsPluginInstanceOwner::SetCandidateWindow(int32_t aX, int32_t aY) +{ + if (NS_WARN_IF(!mPluginFrame)) { + return false; + } + + nsCOMPtr widget = GetContainingWidgetIfOffset(); + if (!widget) { + widget = GetRootWidgetForPluginFrame(mPluginFrame); + if (NS_WARN_IF(!widget)) { + return false; + } + } + + widget->SetCandidateWindowForPlugin(aX, aY); + return true; +} + +bool +nsPluginInstanceOwner::RequestCommitOrCancel(bool aCommitted) +{ + nsCOMPtr widget = GetContainingWidgetIfOffset(); + if (!widget) { + widget = GetRootWidgetForPluginFrame(mPluginFrame); + if (NS_WARN_IF(!widget)) { + return false; + } + } + + if (aCommitted) { + widget->NotifyIME(widget::REQUEST_TO_COMMIT_COMPOSITION); + } else { + widget->NotifyIME(widget::REQUEST_TO_CANCEL_COMPOSITION); + } + return true; +} +#endif // #ifdef XP_WIN NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel) { @@ -1597,6 +1783,154 @@ nsresult nsPluginInstanceOwner::DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent, return NS_OK; } +#ifdef XP_WIN +void +nsPluginInstanceOwner::CallDefaultProc(const WidgetGUIEvent* aEvent) +{ + nsCOMPtr widget = GetContainingWidgetIfOffset(); + if (!widget) { + widget = GetRootWidgetForPluginFrame(mPluginFrame); + if (NS_WARN_IF(!widget)) { + return; + } + } + + const NPEvent* npEvent = + static_cast(aEvent->mPluginEvent); + if (NS_WARN_IF(!npEvent)) { + return; + } + + WidgetPluginEvent pluginEvent(true, ePluginInputEvent, widget); + pluginEvent.mPluginEvent.Copy(*npEvent); + widget->DefaultProcOfPluginEvent(pluginEvent); +} + +already_AddRefed +nsPluginInstanceOwner::GetTextComposition() +{ + if (NS_WARN_IF(!mPluginFrame)) { + return nullptr; + } + + nsCOMPtr widget = GetContainingWidgetIfOffset(); + if (!widget) { + widget = GetRootWidgetForPluginFrame(mPluginFrame); + if (NS_WARN_IF(!widget)) { + return nullptr; + } + } + + RefPtr composition = + IMEStateManager::GetTextCompositionFor(widget); + if (NS_WARN_IF(!composition)) { + return nullptr; + } + + return composition.forget(); +} +#endif + +nsresult +nsPluginInstanceOwner::DispatchCompositionToPlugin(nsIDOMEvent* aEvent) +{ +#ifdef XP_WIN + if (!mPluginWindow) { + // CompositionEvent isn't cancellable. So it is unnecessary to call + // PreventDefaults() to consume event + return NS_OK; + } + WidgetCompositionEvent* compositionEvent = + aEvent->GetInternalNSEvent()->AsCompositionEvent(); + if (NS_WARN_IF(!compositionEvent)) { + return NS_ERROR_INVALID_ARG; + } + + if (compositionEvent->mMessage == eCompositionChange) { + RefPtr composition = GetTextComposition(); + if (NS_WARN_IF(!composition)) { + return NS_ERROR_FAILURE; + } + TextComposition::CompositionChangeEventHandlingMarker + compositionChangeEventHandlingMarker(composition, compositionEvent); + } + + // Protected mode Flash returns noDefault by NPP_HandleEvent, but + // composition information into plugin is invalid because plugin's bug. + // So if plugin doesn't get composition data by WM_IME_COMPOSITION, we + // recongnize it isn't handled + AutoRestore restore(mGotCompositionData); + mGotCompositionData = false; + + nsEventStatus status = ProcessEvent(*compositionEvent); + aEvent->StopImmediatePropagation(); + + // Composition event isn't handled by plugin, so we have to call default proc. + const NPEvent* pPluginEvent = + static_cast(compositionEvent->mPluginEvent); + if (NS_WARN_IF(!pPluginEvent)) { + return NS_OK; + } + + if (pPluginEvent->event == WM_IME_STARTCOMPOSITION) { + // Flash's protected mode lies that composition event is handled, but it + // cannot do it well. So even if handled, we should post this message when + // no IMM API calls during WM_IME_COMPOSITION. + if (nsEventStatus_eConsumeNoDefault != status) { + CallDefaultProc(compositionEvent); + mSentStartComposition = true; + } else { + mSentStartComposition = false; + } + return NS_OK; + } + + if (pPluginEvent->event == WM_IME_ENDCOMPOSITION) { + // Always post WM_END_COMPOSITION to default proc. Because Flash may lie + // that it doesn't handle composition well, but event is handled. + // Even if posting this message, default proc do nothing if unnecessary. + CallDefaultProc(compositionEvent); + return NS_OK; + } + + if (pPluginEvent->event == WM_IME_COMPOSITION && !mGotCompositionData) { + nsCOMPtr widget = GetContainingWidgetIfOffset(); + if (!widget) { + widget = GetRootWidgetForPluginFrame(mPluginFrame); + } + + if (pPluginEvent->lParam & GCS_RESULTSTR) { + // GCS_RESULTSTR's default proc will generate WM_CHAR. So emulate it. + for (size_t i = 0; i < compositionEvent->mData.Length(); i++) { + WidgetPluginEvent charEvent(true, ePluginInputEvent, widget); + NPEvent event; + event.event = WM_CHAR; + event.wParam = compositionEvent->mData[i]; + event.lParam = 0; + charEvent.mPluginEvent.Copy(event); + ProcessEvent(charEvent); + } + return NS_OK; + } + if (!mSentStartComposition) { + // We post WM_IME_COMPOSITION to default proc, but + // WM_IME_STARTCOMPOSITION isn't post yet. We should post it at first. + WidgetPluginEvent event(true, ePluginInputEvent, widget); + NPEvent npevent; + npevent.event = WM_IME_STARTCOMPOSITION; + npevent.wParam = 0; + npevent.lParam = 0; + event.mPluginEvent.Copy(npevent); + CallDefaultProc(&event); + mSentStartComposition = true; + } + + CallDefaultProc(compositionEvent); + } +#endif // #ifdef XP_WIN + return NS_OK; +} + nsresult nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent) { @@ -1651,6 +1985,11 @@ nsPluginInstanceOwner::HandleEvent(nsIDOMEvent* aEvent) if (eventType.EqualsLiteral("keypress")) { return ProcessKeyPress(aEvent); } + if (eventType.EqualsLiteral("compositionstart") || + eventType.EqualsLiteral("compositionend") || + eventType.EqualsLiteral("text")) { + return DispatchCompositionToPlugin(aEvent); + } nsCOMPtr dragEvent(do_QueryInterface(aEvent)); if (dragEvent && mInstance) { @@ -2477,6 +2816,11 @@ nsPluginInstanceOwner::Destroy() content->RemoveEventListener(NS_LITERAL_STRING("dragstart"), this, true); content->RemoveEventListener(NS_LITERAL_STRING("draggesture"), this, true); content->RemoveEventListener(NS_LITERAL_STRING("dragend"), this, true); + content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionstart"), + this, true); + content->RemoveSystemEventListener(NS_LITERAL_STRING("compositionend"), + this, true); + content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true); #if MOZ_WIDGET_ANDROID RemovePluginView(); @@ -2872,6 +3216,11 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent) aContent->AddEventListener(NS_LITERAL_STRING("dragstart"), this, true); aContent->AddEventListener(NS_LITERAL_STRING("draggesture"), this, true); aContent->AddEventListener(NS_LITERAL_STRING("dragend"), this, true); + aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionstart"), + this, true); + aContent->AddSystemEventListener(NS_LITERAL_STRING("compositionend"), this, + true); + aContent->AddSystemEventListener(NS_LITERAL_STRING("text"), this, true); return NS_OK; } @@ -3374,6 +3723,51 @@ already_AddRefed nsPluginInstanceOwner::GetBaseURI() const return content->GetBaseURI(); } +// static +void +nsPluginInstanceOwner::GeneratePluginEvent( + const WidgetCompositionEvent* aSrcCompositionEvent, + WidgetCompositionEvent* aDistCompositionEvent) +{ +#ifdef XP_WIN + NPEvent newEvent; + switch (aDistCompositionEvent->mMessage) { + case eCompositionChange: { + newEvent.event = WM_IME_COMPOSITION; + newEvent.wParam = 0; + if (aSrcCompositionEvent && + (aSrcCompositionEvent->mMessage == eCompositionCommit || + aSrcCompositionEvent->mMessage == eCompositionCommitAsIs)) { + newEvent.lParam = GCS_RESULTSTR; + } else { + newEvent.lParam = GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE; + } + TextRangeArray* ranges = aDistCompositionEvent->mRanges; + if (ranges && ranges->HasCaret()) { + newEvent.lParam |= GCS_CURSORPOS; + } + break; + } + + case eCompositionStart: + newEvent.event = WM_IME_STARTCOMPOSITION; + newEvent.wParam = 0; + newEvent.lParam = 0; + break; + + case eCompositionEnd: + newEvent.event = WM_IME_ENDCOMPOSITION; + newEvent.wParam = 0; + newEvent.lParam = 0; + break; + + default: + return; + } + aDistCompositionEvent->mPluginEvent.Copy(newEvent); +#endif +} + // nsPluginDOMContextMenuListener class implementation nsPluginDOMContextMenuListener::nsPluginDOMContextMenuListener(nsIContent* aContent) diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index e902b2d797e6..eb73f062e85c 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -29,6 +29,7 @@ class nsPluginFrame; class nsDisplayListBuilder; namespace mozilla { +class TextComposition; namespace dom { struct MozPluginParameter; } // namespace dom @@ -118,6 +119,10 @@ public: nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent); + static void GeneratePluginEvent( + const mozilla::WidgetCompositionEvent* aSrcCompositionEvent, + mozilla::WidgetCompositionEvent* aDistCompositionEvent); + #if defined(XP_WIN) void SetWidgetWindowAsParent(HWND aWindowToAdopt); nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt); @@ -256,6 +261,11 @@ public: void NotifyHostCreateWidget(); void NotifyDestroyPending(); + bool GetCompositionString(uint32_t aIndex, nsTArray* aString, + int32_t* aLength); + bool SetCandidateWindow(int32_t aX, int32_t aY); + bool RequestCommitOrCancel(bool aCommitted); + private: virtual ~nsPluginInstanceOwner(); @@ -278,6 +288,10 @@ private: #if defined(XP_WIN) nsIWidget* GetContainingWidgetIfOffset(); + already_AddRefed GetTextComposition(); + + bool mGotCompositionData; + bool mSentStartComposition; #endif nsPluginNativeWindow *mPluginWindow; @@ -329,6 +343,11 @@ private: nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent, bool aAllowPropagate = false); nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); + nsresult DispatchCompositionToPlugin(nsIDOMEvent* aEvent); + +#ifdef XP_WIN + void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent); +#endif #ifdef XP_MACOSX static NPBool ConvertPointPuppet(PuppetWidget *widget, nsPluginFrame* pluginFrame, diff --git a/dom/plugins/ipc/NPEventWindows.h b/dom/plugins/ipc/NPEventWindows.h index d485000b31fe..79a694b7bd05 100644 --- a/dom/plugins/ipc/NPEventWindows.h +++ b/dom/plugins/ipc/NPEventWindows.h @@ -100,6 +100,18 @@ struct ParamTraits case WM_SETFOCUS: case WM_KILLFOCUS: + + case WM_IME_STARTCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_ENDCOMPOSITION: + case WM_IME_CHAR: + case WM_IME_SETCONTEXT: + case WM_IME_COMPOSITIONFULL: + case WM_IME_KEYDOWN: + case WM_IME_KEYUP: + case WM_IME_SELECT: + case WM_INPUTLANGCHANGEREQUEST: + case WM_INPUTLANGCHANGE: break; default: diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index edf9f4bf7ca9..1fb1286dc5a4 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -260,6 +260,15 @@ parent: // returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows. async SetNetscapeWindowAsParent(NativeWindowHandle childWindow); + sync GetCompositionString(uint32_t aType) + returns (uint8_t[] aDist, int32_t aLength); + // Set candidate window position. + // + // @param aX x position of candidate window + // @param aY y position of candidate window + async SetCandidateWindow(int32_t aX, int32_t aY); + sync RequestCommitOrCancel(bool aCommitted); + both: async PPluginScriptableObject(); diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 4fe39efe1b43..083ac4736cd1 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -73,6 +73,25 @@ static WindowsDllInterceptor sUser32Intercept; static HWND sWinlessPopupSurrogateHWND = nullptr; static User32TrackPopupMenu sUser32TrackPopupMenuStub = nullptr; +typedef HIMC (WINAPI *Imm32ImmGetContext)(HWND hWND); +typedef BOOL (WINAPI *Imm32ImmReleaseContext)(HWND hWND, HIMC hIMC); +typedef LONG (WINAPI *Imm32ImmGetCompositionString)(HIMC hIMC, + DWORD dwIndex, + LPVOID lpBuf, + DWORD dwBufLen); +typedef BOOL (WINAPI *Imm32ImmSetCandidateWindow)(HIMC hIMC, + LPCANDIDATEFORM lpCandidate); +typedef BOOL (WINAPI *Imm32ImmNotifyIME)(HIMC hIMC, DWORD dwAction, + DWORD dwIndex, DWORD dwValue); +static WindowsDllInterceptor sImm32Intercept; +static Imm32ImmGetContext sImm32ImmGetContextStub = nullptr; +static Imm32ImmReleaseContext sImm32ImmReleaseContextStub = nullptr; +static Imm32ImmGetCompositionString sImm32ImmGetCompositionStringStub = nullptr; +static Imm32ImmSetCandidateWindow sImm32ImmSetCandidateWindowStub = nullptr; +static Imm32ImmNotifyIME sImm32ImmNotifyIME = nullptr; +static PluginInstanceChild* sCurrentPluginInstance = nullptr; +static const HIMC sHookIMC = (const HIMC)0xefefefef; + using mozilla::gfx::SharedDIB; #include @@ -197,6 +216,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface, if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) { SetUnityHooks(); } + InitImm32Hook(); #endif // OS_WIN } @@ -1983,6 +2003,135 @@ PluginInstanceChild::CreateWinlessPopupSurrogate() SendSetNetscapeWindowAsParent(mWinlessPopupSurrogateHWND); } +// static +HIMC +PluginInstanceChild::ImmGetContextProc(HWND aWND) +{ + if (!sCurrentPluginInstance) { + return sImm32ImmGetContextStub(aWND); + } + + wchar_t szClass[21]; + int haveClass = GetClassNameW(aWND, szClass, ArrayLength(szClass)); + if (!haveClass || wcscmp(szClass, L"SWFlash_PlaceholderX")) { + NS_WARNING("We cannot recongnize hooked window class"); + return sImm32ImmGetContextStub(aWND); + } + + return sHookIMC; +} + +// static +BOOL +PluginInstanceChild::ImmReleaseContextProc(HWND aWND, HIMC aIMC) +{ + if (aIMC == sHookIMC) { + return TRUE; + } + + return sImm32ImmReleaseContextStub(aWND, aIMC); +} + +// static +LONG +PluginInstanceChild::ImmGetCompositionStringProc(HIMC aIMC, DWORD aIndex, + LPVOID aBuf, DWORD aLen) +{ + if (aIMC != sHookIMC) { + return sImm32ImmGetCompositionStringStub(aIMC, aIndex, aBuf, aLen); + } + if (!sCurrentPluginInstance) { + return IMM_ERROR_GENERAL; + } + nsAutoTArray dist; + int32_t length = 0; // IMM_ERROR_NODATA + sCurrentPluginInstance->SendGetCompositionString(aIndex, &dist, &length); + if (length == IMM_ERROR_NODATA || length == IMM_ERROR_GENERAL) { + return length; + } + + if (aBuf && aLen >= static_cast(length)) { + memcpy(aBuf, dist.Elements(), length); + } + return length; +} + +// staitc +BOOL +PluginInstanceChild::ImmSetCandidateWindowProc(HIMC aIMC, LPCANDIDATEFORM aForm) +{ + if (aIMC != sHookIMC) { + return sImm32ImmSetCandidateWindowStub(aIMC, aForm); + } + + if (!sCurrentPluginInstance || + aForm->dwIndex != 0 || + !(aForm->dwStyle & CFS_CANDIDATEPOS)) { + // Flash only uses CFS_CANDIDATEPOS with index == 0. + return FALSE; + } + + sCurrentPluginInstance->SendSetCandidateWindow( + aForm->ptCurrentPos.x, aForm->ptCurrentPos.y); + return TRUE; +} + +// static +BOOL +PluginInstanceChild::ImmNotifyIME(HIMC aIMC, DWORD aAction, DWORD aIndex, + DWORD aValue) +{ + if (aIMC != sHookIMC) { + return sImm32ImmNotifyIME(aIMC, aAction, aIndex, aValue); + } + + // We only supports NI_COMPOSITIONSTR because Flash uses it only + if (!sCurrentPluginInstance || + aAction != NI_COMPOSITIONSTR || + (aIndex != CPS_COMPLETE && aIndex != CPS_CANCEL)) { + return FALSE; + } + + sCurrentPluginInstance->SendRequestCommitOrCancel(aAction == CPS_COMPLETE); + return TRUE; +} + +void +PluginInstanceChild::InitImm32Hook() +{ + if (!(GetQuirks() & QUIRK_WINLESS_HOOK_IME)) { + return; + } + + if (sImm32ImmGetContextStub) { + return; + } + + // When using windowless plugin, IMM API won't work due ot OOP. + + sImm32Intercept.Init("imm32.dll"); + sImm32Intercept.AddHook( + "ImmGetContext", + reinterpret_cast(ImmGetContextProc), + (void**)&sImm32ImmGetContextStub); + sImm32Intercept.AddHook( + "ImmReleaseContext", + reinterpret_cast(ImmReleaseContextProc), + (void**)&sImm32ImmReleaseContextStub); + sImm32Intercept.AddHook( + "ImmGetCompositionStringW", + reinterpret_cast(ImmGetCompositionStringProc), + (void**)&sImm32ImmGetCompositionStringStub); + sImm32Intercept.AddHook( + "ImmSetCandidateWindow", + reinterpret_cast(ImmSetCandidateWindowProc), + (void**)&sImm32ImmSetCandidateWindowStub); + sImm32Intercept.AddHook( + "ImmNotifyIME", + reinterpret_cast(ImmNotifyIME), + (void**)&sImm32ImmNotifyIME); +} + void PluginInstanceChild::DestroyWinlessPopupSurrogate() { @@ -2016,6 +2165,13 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event) focusHwnd = SetFocus(mWinlessPopupSurrogateHWND); } + AutoRestore pluginInstance(sCurrentPluginInstance); + if (event.event == WM_IME_STARTCOMPOSITION || + event.event == WM_IME_COMPOSITION || + event.event == WM_KILLFOCUS) { + sCurrentPluginInstance = this; + } + MessageLoop* loop = MessageLoop::current(); AutoRestore modalLoop(loop->os_modal_loop()); diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 37164aec3590..6ddd751219d7 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -305,6 +305,7 @@ private: void HookSetWindowLongPtr(); void SetUnityHooks(); void ClearUnityHooks(); + void InitImm32Hook(); static inline bool SetWindowLongHookCheck(HWND hWnd, int nIndex, LONG_PTR newLong); @@ -350,6 +351,15 @@ private: LONG newLong); #endif + static HIMC WINAPI ImmGetContextProc(HWND aWND); + static BOOL WINAPI ImmReleaseContextProc(HWND aWND, HIMC aIMC); + static LONG WINAPI ImmGetCompositionStringProc(HIMC aIMC, DWORD aIndex, + LPVOID aBuf, DWORD aLen); + static BOOL WINAPI ImmSetCandidateWindowProc(HIMC hIMC, + LPCANDIDATEFORM plCandidate); + static BOOL WINAPI ImmNotifyIME(HIMC aIMC, DWORD aAction, DWORD aIndex, + DWORD aValue); + class FlashThrottleAsyncMsg : public ChildAsyncCall { public: diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 46374a5daeaa..e8e63f5f957a 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -1568,6 +1568,16 @@ PluginInstanceParent::NPP_HandleEvent(void* event) // We send this in nsPluginFrame just before painting return SendWindowPosChanged(npremoteevent); } + + case WM_IME_STARTCOMPOSITION: + case WM_IME_COMPOSITION: + case WM_IME_ENDCOMPOSITION: + if (!(mParent->GetQuirks() & QUIRK_WINLESS_HOOK_IME)) { + // IME message will be posted on allowed plugins only such as + // Flash. Because if we cannot know that plugin can handle + // IME correctly. + return 0; + } break; } } @@ -2368,6 +2378,50 @@ PluginInstanceParent::Cast(NPP aInstance, PluginAsyncSurrogate** aSurrogate) return instancePtr; } +bool +PluginInstanceParent::RecvGetCompositionString(const uint32_t& aIndex, + nsTArray* aDist, + int32_t* aLength) +{ +#if defined(OS_WIN) + nsPluginInstanceOwner* owner = GetOwner(); + if (!owner) { + *aLength = IMM_ERROR_GENERAL; + return true; + } + + if (!owner->GetCompositionString(aIndex, aDist, aLength)) { + *aLength = IMM_ERROR_NODATA; + } +#endif + return true; +} + +bool +PluginInstanceParent::RecvSetCandidateWindow(const int32_t& aX, + const int32_t& aY) +{ +#if defined(OS_WIN) + nsPluginInstanceOwner* owner = GetOwner(); + if (owner) { + owner->SetCandidateWindow(aX, aY); + } +#endif + return true; +} + +bool +PluginInstanceParent::RecvRequestCommitOrCancel(const bool& aCommitted) +{ +#if defined(OS_WIN) + nsPluginInstanceOwner* owner = GetOwner(); + if (owner) { + owner->RequestCommitOrCancel(aCommitted); + } +#endif + return true; +} + void PluginInstanceParent::RecordDrawingModel() { diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 2469da5bfa77..43700f7b0e0f 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -352,6 +352,16 @@ public: static PluginInstanceParent* Cast(NPP instance, PluginAsyncSurrogate** aSurrogate = nullptr); + // for IME hook + virtual bool + RecvGetCompositionString(const uint32_t& aIndex, + nsTArray* aBuffer, + int32_t* aLength) override; + virtual bool + RecvSetCandidateWindow(const int32_t& aX, const int32_t& aY) override; + virtual bool + RecvRequestCommitOrCancel(const bool& aCommitted) override; + private: // Create an appropriate platform surface for a background of size // |aSize|. Return true if successful. diff --git a/dom/plugins/ipc/PluginQuirks.cpp b/dom/plugins/ipc/PluginQuirks.cpp index 86c890093e30..a6528e661856 100644 --- a/dom/plugins/ipc/PluginQuirks.cpp +++ b/dom/plugins/ipc/PluginQuirks.cpp @@ -34,6 +34,7 @@ int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType, quirks |= QUIRK_FLASH_HOOK_SETLONGPTR; quirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO; quirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE; + quirks |= QUIRK_WINLESS_HOOK_IME; #endif } @@ -62,6 +63,12 @@ int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType, } #endif +#ifdef OS_WIN + if (specialType == nsPluginHost::eSpecialType_Test) { + quirks |= QUIRK_WINLESS_HOOK_IME; + } +#endif + return quirks; } diff --git a/dom/plugins/ipc/PluginQuirks.h b/dom/plugins/ipc/PluginQuirks.h index fb77afd74c6b..8b59066c0dc7 100644 --- a/dom/plugins/ipc/PluginQuirks.h +++ b/dom/plugins/ipc/PluginQuirks.h @@ -58,6 +58,8 @@ enum PluginQuirks { QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN = 1 << 11, // Win: Addresses a Unity bug with mouse capture. QUIRK_UNITY_FIXUP_MOUSE_CAPTURE = 1 << 12, + // Win: Hook IMM32 API to handle IME event on windowless plugin + QUIRK_WINLESS_HOOK_IME = 1 << 13, }; int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType, diff --git a/dom/plugins/test/mochitest/mochitest.ini b/dom/plugins/test/mochitest/mochitest.ini index 6494bc7ac9b2..6ed983d34c6b 100644 --- a/dom/plugins/test/mochitest/mochitest.ini +++ b/dom/plugins/test/mochitest/mochitest.ini @@ -116,6 +116,8 @@ skip-if = toolkit != "cocoa" [test_twostreams.html] [test_windowed_invalidate.html] skip-if = os != "win" +[test_windowless_ime.html] +skip-if = os != "win" [test_visibility.html] skip-if = toolkit == "cocoa" [test_zero_opacity.html] diff --git a/dom/plugins/test/mochitest/test_windowless_ime.html b/dom/plugins/test/mochitest/test_windowless_ime.html new file mode 100644 index 000000000000..8a1264fdc2a9 --- /dev/null +++ b/dom/plugins/test/mochitest/test_windowless_ime.html @@ -0,0 +1,46 @@ + + + + + Test #1 for Bug 539565 + + + + + + + + + + + + diff --git a/dom/plugins/test/testaddon/Makefile.in b/dom/plugins/test/testaddon/Makefile.in index b023a0db199b..7b6dd6bc5f53 100644 --- a/dom/plugins/test/testaddon/Makefile.in +++ b/dom/plugins/test/testaddon/Makefile.in @@ -13,7 +13,7 @@ addon_file_name = testaddon.xpi endif # This is so hacky. Waiting on bug 988938. -testdir = $(abspath $(DEPTH)/_tests/xpcshell/dom/plugins/test/unit/) +testdir = $(topobjdir)/_tests/xpcshell/dom/plugins/test/unit/ addonpath = $(testdir)/$(addon_file_name) ifdef COMPILE_ENVIRONMENT diff --git a/dom/plugins/test/testplugin/nptest.cpp b/dom/plugins/test/testplugin/nptest.cpp index 6e3dc640a9b0..6651ce349681 100644 --- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -173,6 +173,7 @@ static bool startAudioPlayback(NPObject* npobj, const NPVariant* args, uint32_t static bool stopAudioPlayback(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool getAudioMuted(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool nativeWidgetIsVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); +static bool getLastCompositionText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static const NPUTF8* sPluginMethodIdentifierNames[] = { "npnEvaluateTest", @@ -244,6 +245,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = { "stopAudioPlayback", "audioMuted", "nativeWidgetIsVisible", + "getLastCompositionText", }; static NPIdentifier sPluginMethodIdentifiers[MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames)]; static const ScriptableFunction sPluginMethodFunctions[] = { @@ -316,6 +318,7 @@ static const ScriptableFunction sPluginMethodFunctions[] = { stopAudioPlayback, getAudioMuted, nativeWidgetIsVisible, + getLastCompositionText, }; static_assert(MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames) == @@ -852,6 +855,7 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* instanceData->asyncDrawing = AD_NONE; instanceData->frontBuffer = nullptr; instanceData->backBuffer = nullptr; + instanceData->placeholderWnd = nullptr; instance->pdata = instanceData; TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass); @@ -3514,6 +3518,26 @@ nativeWidgetIsVisible(NPObject* npobj, const NPVariant* args, } #endif +bool +getLastCompositionText(NPObject* npobj, const NPVariant* args, + uint32_t argCount, NPVariant* result) +{ +#ifdef XP_WIN + if (argCount != 0) { + return false; + } + + NPP npp = static_cast(npobj)->npp; + InstanceData* id = static_cast(npp->pdata); + char *outval = NPN_StrDup(id->lastComposition.c_str()); + STRINGZ_TO_NPVARIANT(outval, *result); + return true; +#else + // XXX not implemented + return false; +#endif +} + bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result) { diff --git a/dom/plugins/test/testplugin/nptest.h b/dom/plugins/test/testplugin/nptest.h index 12e427a5e60f..2fbc2d4b437c 100644 --- a/dom/plugins/test/testplugin/nptest.h +++ b/dom/plugins/test/testplugin/nptest.h @@ -156,6 +156,8 @@ typedef struct InstanceData { AsyncDrawing asyncDrawing; NPAsyncSurface *frontBuffer; NPAsyncSurface *backBuffer; + std::string lastComposition; + void* placeholderWnd; } InstanceData; void notifyDidPaint(InstanceData* instanceData); diff --git a/dom/plugins/test/testplugin/nptest_windows.cpp b/dom/plugins/test/testplugin/nptest_windows.cpp index 3d807bc532ec..8b02872e9540 100644 --- a/dom/plugins/test/testplugin/nptest_windows.cpp +++ b/dom/plugins/test/testplugin/nptest_windows.cpp @@ -654,6 +654,29 @@ pluginGetClipRegionRectEdge(InstanceData* instanceData, return NPTEST_INT32_ERROR; } +static +void +createDummyWindowForIME(InstanceData* instanceData) +{ + WNDCLASSW wndClass; + wndClass.style = 0; + wndClass.lpfnWndProc = DefWindowProcW; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = GetModuleHandleW(NULL); + wndClass.hIcon = nullptr; + wndClass.hCursor = nullptr; + wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW; + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = L"SWFlash_PlaceholderX"; + RegisterClassW(&wndClass); + + instanceData->placeholderWnd = + static_cast(CreateWindowW(L"SWFlash_PlaceholderX", L"", WS_CHILD, 0, + 0, 0, 0, HWND_MESSAGE, NULL, + GetModuleHandleW(NULL), NULL)); +} + /* windowless plugin events */ static bool @@ -725,6 +748,35 @@ handleEventInternal(InstanceData* instanceData, NPEvent* pe, LRESULT* result) return true; } + case WM_IME_STARTCOMPOSITION: + instanceData->lastComposition.erase(); + if (!instanceData->placeholderWnd) { + createDummyWindowForIME(instanceData); + } + return true; + + case WM_IME_ENDCOMPOSITION: + instanceData->lastComposition.erase(); + return true; + + case WM_IME_COMPOSITION: { + if (pe->lParam & GCS_COMPSTR) { + HIMC hIMC = ImmGetContext((HWND)instanceData->placeholderWnd); + if (!hIMC) { + return false; + } + WCHAR compStr[256]; + LONG len = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, compStr, + 256 * sizeof(WCHAR)); + CHAR buffer[256]; + len = ::WideCharToMultiByte(CP_UTF8, 0, compStr, len / sizeof(WCHAR), + buffer, 256, nullptr, nullptr); + instanceData->lastComposition.append(buffer, len); + ::ImmReleaseContext((HWND)instanceData->placeholderWnd, hIMC); + } + return true; + } + default: return false; } diff --git a/dom/plugins/test/testplugin/testplugin.mozbuild b/dom/plugins/test/testplugin/testplugin.mozbuild index e8e1a7615cce..86e3fc24a7c9 100644 --- a/dom/plugins/test/testplugin/testplugin.mozbuild +++ b/dom/plugins/test/testplugin/testplugin.mozbuild @@ -38,6 +38,7 @@ elif toolkit == 'windows': ] OS_LIBS += [ 'msimg32', + 'imm32' ] # must link statically with the CRT; nptest isn't Gecko code diff --git a/dom/tests/mochitest/pointerlock/file_allowPointerLockSandboxFlag.html b/dom/tests/mochitest/pointerlock/file_allowPointerLockSandboxFlag.html index 5cef661c48c7..5540909ef75e 100644 --- a/dom/tests/mochitest/pointerlock/file_allowPointerLockSandboxFlag.html +++ b/dom/tests/mochitest/pointerlock/file_allowPointerLockSandboxFlag.html @@ -32,7 +32,7 @@ SimpleTest.waitForExplicitFinish(1); - var iframe + var iframe = document.getElementById("iframe") , iframeDiv , contentDocument , pointerLocked = 0 @@ -55,7 +55,9 @@ } function startTest () { - iframe = document.getElementById("iframe"); + SimpleTest.waitForFocus(doStartTest, iframe.contentWindow); + } + function doStartTest() { contentDocument = iframe.contentDocument; iframeDiv = contentDocument.getElementById("div"); @@ -64,7 +66,7 @@ contentDocument.addEventListener("mozpointerlockchange", function () { if (contentDocument.mozPointerLockElement === iframeDiv) { pointerLocked++; - resetIframe(); + contentDocument.mozCancelFullScreen(); } }); @@ -73,11 +75,14 @@ }); contentDocument.addEventListener("mozfullscreenchange", function () { - if (contentDocument.mozFullScreen && - contentDocument.mozFullScreenElement === iframeDiv) { + if (contentDocument.mozFullScreen) { + ok(contentDocument.mozFullScreenElement === iframeDiv, + "Fullscreen element can only be iframe div"); // during second run iframe won't have allow-pointer-lock flag and // mozRequestPointerLock will fail, mozpointerlockerror should be fired iframeDiv.mozRequestPointerLock(); + } else if (numberOfRuns === 1) { + resetIframe(); } else if (numberOfRuns === 2) { runTests(); } diff --git a/dom/tests/mochitest/pointerlock/file_nestedFullScreen.html b/dom/tests/mochitest/pointerlock/file_nestedFullScreen.html index bba42edbb413..56d1fefbbe49 100644 --- a/dom/tests/mochitest/pointerlock/file_nestedFullScreen.html +++ b/dom/tests/mochitest/pointerlock/file_nestedFullScreen.html @@ -57,9 +57,10 @@ if (document.mozFullScreenElement === parentDiv) { if (parentDivFullScreen === true) { document.mozCancelFullScreen(); + } else { + parentDivFullScreen = true; + parentDiv.mozRequestPointerLock(); } - parentDivFullScreen = true; - parentDiv.mozRequestPointerLock(); } else if (document.mozFullScreenElement === childDiv) { pointerLocked = !!document.mozPointerLockElement; diff --git a/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html b/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html index 200feec207ab..01b1d1d43e1d 100644 --- a/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html +++ b/dom/tests/mochitest/pointerlock/file_screenClientXYConst.html @@ -24,6 +24,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=633602 */ SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("We may need to wait for window's moving"); var div , divRect diff --git a/dom/tests/mochitest/pointerlock/mochitest.ini b/dom/tests/mochitest/pointerlock/mochitest.ini index 07aeac0abd1a..14a5b627e286 100644 --- a/dom/tests/mochitest/pointerlock/mochitest.ini +++ b/dom/tests/mochitest/pointerlock/mochitest.ini @@ -21,4 +21,4 @@ support-files = iframe_differentDOM.html [test_pointerlock-api.html] -skip-if = buildapp == 'b2g' || toolkit == 'android' || os == 'linux' || os == 'win' # B2G - window.open focus issues using fullscreen. (For Linux & Win) Bug1180351 +skip-if = buildapp == 'b2g' || toolkit == 'android' # B2G - window.open focus issues using fullscreen. diff --git a/dom/tests/mochitest/pointerlock/test_pointerlock-api.html b/dom/tests/mochitest/pointerlock/test_pointerlock-api.html index 002bd781733e..fbf6e0a50d45 100644 --- a/dom/tests/mochitest/pointerlock/test_pointerlock-api.html +++ b/dom/tests/mochitest/pointerlock/test_pointerlock-api.html @@ -60,8 +60,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=633602 var gDisableList = [ // Bug 1174323 - { file: "file_screenClientXYConst.html", - platform: "MacIntel" } + { file: "file_screenClientXYConst.html", platform: "MacIntel" }, + { file: "file_screenClientXYConst.html", platform: "Win32" }, + { file: "file_screenClientXYConst.html", platform: "Win64" }, ]; var gTestWindow = null; diff --git a/dom/webidl/Event.webidl b/dom/webidl/Event.webidl index 8e908db743e0..3b479c1f0920 100644 --- a/dom/webidl/Event.webidl +++ b/dom/webidl/Event.webidl @@ -11,7 +11,7 @@ */ [Constructor(DOMString type, optional EventInit eventInitDict), - Exposed=(Window,Worker,System)] + Exposed=(Window,Worker,System), ProbablyShortLivingObject] interface Event { [Pure] readonly attribute DOMString type; diff --git a/dom/webidl/MutationObserver.webidl b/dom/webidl/MutationObserver.webidl index ccb188b65e7e..a891205c2773 100644 --- a/dom/webidl/MutationObserver.webidl +++ b/dom/webidl/MutationObserver.webidl @@ -7,6 +7,7 @@ * http://dom.spec.whatwg.org */ +[ProbablyShortLivingObject] interface MutationRecord { [Constant] readonly attribute DOMString type; diff --git a/dom/webidl/PeerConnectionImpl.webidl b/dom/webidl/PeerConnectionImpl.webidl index 3fe6e4b4debd..e09606cca737 100644 --- a/dom/webidl/PeerConnectionImpl.webidl +++ b/dom/webidl/PeerConnectionImpl.webidl @@ -47,6 +47,11 @@ interface PeerConnectionImpl { [Throws] void replaceTrack(MediaStreamTrack thisTrack, MediaStreamTrack withTrack); [Throws] + void setParameters(MediaStreamTrack track, + optional RTCRtpParameters parameters); + [Throws] + RTCRtpParameters getParameters(MediaStreamTrack track); + [Throws] void closeStreams(); sequence getLocalStreams(); diff --git a/dom/webidl/RTCRtpSender.webidl b/dom/webidl/RTCRtpSender.webidl index dda71d680537..a08ed370e8e5 100644 --- a/dom/webidl/RTCRtpSender.webidl +++ b/dom/webidl/RTCRtpSender.webidl @@ -4,13 +4,73 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. * * The origin of this IDL file is - * http://lists.w3.org/Archives/Public/public-webrtc/2014May/0067.html + * http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface */ +enum RTCPriorityType { + "very-low", + "low", + "medium", + "high" +}; + +enum RTCDegradationPreference { + "maintain-framerate", + "maintain-resolution", + "balanced" +}; + +dictionary RTCRtxParameters { + unsigned long ssrc; +}; + +dictionary RTCFecParameters { + unsigned long ssrc; +}; + +dictionary RTCRtpEncodingParameters { + unsigned long ssrc; + RTCRtxParameters rtx; + RTCFecParameters fec; + boolean active; + RTCPriorityType priority; + unsigned long maxBitrate; + RTCDegradationPreference degradationPreference = "balanced"; + DOMString rid; + float scaleResolutionDownBy = 1.0; +}; + +dictionary RTCRtpHeaderExtensionParameters { + DOMString uri; + unsigned short id; + boolean encrypted; +}; + +dictionary RTCRtcpParameters { + DOMString cname; + boolean reducedSize; +}; + +dictionary RTCRtpCodecParameters { + unsigned short payloadType; + DOMString mimeType; + unsigned long clockRate; + unsigned short channels = 1; + DOMString sdpFmtpLine; +}; + +dictionary RTCRtpParameters { + sequence encodings; + sequence headerExtensions; + RTCRtcpParameters rtcp; + sequence codecs; +}; + [Pref="media.peerconnection.enabled", JSImplementation="@mozilla.org/dom/rtpsender;1"] interface RTCRtpSender { readonly attribute MediaStreamTrack track; - + void setParameters (optional RTCRtpParameters parameters); + RTCRtpParameters getParameters(); Promise replaceTrack(MediaStreamTrack track); }; diff --git a/gfx/harfbuzz/src/Makefile.in b/gfx/harfbuzz/src/Makefile.in deleted file mode 100644 index b28584491f44..000000000000 --- a/gfx/harfbuzz/src/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2010 Mozilla Foundation -# -# This is used to integrate the HarfBuzz library with the Mozilla build. -# -# Permission is hereby granted, without written agreement and without -# license or royalty fees, to use, copy, modify, and distribute this -# software and its documentation for any purpose, provided that the -# above copyright notice and the following two paragraphs appear in -# all copies of this software. -# -# IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -# ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -# IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -# DAMAGE. -# -# THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -# ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -# -# Mozilla author(s): Jonathan Kew -# - -include $(topsrcdir)/config/rules.mk - -# Cancel the effect of the -DDEBUG macro if present, -# because harfbuzz uses that name for its own purposes -COMPILE_CXXFLAGS += -UDEBUG diff --git a/gfx/harfbuzz/src/moz.build b/gfx/harfbuzz/src/moz.build index 51dfc705c125..86bbb2b56f6c 100644 --- a/gfx/harfbuzz/src/moz.build +++ b/gfx/harfbuzz/src/moz.build @@ -69,3 +69,6 @@ DEFINES['PACKAGE_BUGREPORT'] = '"http://bugzilla.mozilla.org/"' DEFINES['HAVE_OT'] = 1 DEFINES['HB_NO_MT'] = True DEFINES['HB_NO_UNICODE_FUNCS'] = True +# Cancel the effect of the -DDEBUG macro if present, +# because harfbuzz uses that name for its own purposes +DEFINES['DEBUG'] = False diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index 35169aae2753..44f845c1e7b2 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -149,7 +149,6 @@ InitializeOculusCAPI() } if (!ovrlib) { - printf_stderr("Failed to load Oculus VR library!\n"); return false; } } diff --git a/gfx/vr/gfxVROculus050.cpp b/gfx/vr/gfxVROculus050.cpp index e3542632e73c..af867f165699 100644 --- a/gfx/vr/gfxVROculus050.cpp +++ b/gfx/vr/gfxVROculus050.cpp @@ -153,7 +153,6 @@ InitializeOculusCAPI() } if (!ovrlib) { - printf_stderr("Failed to load Oculus VR library!\n"); return false; } } diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp index 56a2b865ec8b..0080323cf0b2 100644 --- a/gfx/vr/ipc/VRManagerParent.cpp +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -106,7 +106,6 @@ VRManagerParent::CreateSameProcess() void VRManagerParent::DeferredDestroy() { - MOZ_ASSERT(mCompositorThreadHolder); mCompositorThreadHolder = nullptr; mSelfRef = nullptr; } diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h index 642f4d773055..ee9931278718 100644 --- a/js/public/TrackedOptimizationInfo.h +++ b/js/public/TrackedOptimizationInfo.h @@ -144,6 +144,7 @@ namespace JS { \ _(ICNameStub_ReadSlot) \ _(ICNameStub_CallGetter) \ + _(ICNameStub_TypeOfNoProperty) \ \ _(CantInlineGeneric) \ _(CantInlineNoTarget) \ diff --git a/js/src/asmjs/AsmJS.cpp b/js/src/asmjs/AsmJS.cpp index b50d1688cf6d..80169567eb20 100644 --- a/js/src/asmjs/AsmJS.cpp +++ b/js/src/asmjs/AsmJS.cpp @@ -2034,9 +2034,12 @@ class MOZ_STACK_CLASS ModuleValidator auto mutedErrors = Module::MutedBool(parser_.ss->mutedErrors()); - CacheableChars filename = make_string_copy(parser_.ss->filename()); - if (!filename) - return false; + CacheableChars filename; + if (parser_.ss->filename()) { + filename = make_string_copy(parser_.ss->filename()); + if (!filename) + return false; + } CacheableTwoByteChars displayURL; if (parser_.ss->hasDisplayURL()) { @@ -6738,7 +6741,6 @@ CheckSwitch(FunctionValidator& f, ParseNode* switchStmt) if (!CheckStatement(f, CaseBody(stmt))) return false; - } bool hasDefault = false; diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index b8ab10954377..0248b990d823 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -3075,7 +3075,6 @@ wasm::IonCompileFunction(IonCompileTask* task) // Compile MIR graph { - jit::SpewBeginFunction(&mir, nullptr); jit::AutoSpewEndFunction spewEndFunction(&mir); diff --git a/js/src/builtin/Date.js b/js/src/builtin/Date.js index 8e938b30da9f..bd2d5854cbd0 100644 --- a/js/src/builtin/Date.js +++ b/js/src/builtin/Date.js @@ -101,7 +101,7 @@ function Date_toLocaleString() { } // Step 7. - return intl_FormatDateTime(dateTimeFormat, x); + return intl_FormatDateTime(dateTimeFormat, x, false); } @@ -134,7 +134,7 @@ function Date_toLocaleDateString() { } // Step 7. - return intl_FormatDateTime(dateTimeFormat, x); + return intl_FormatDateTime(dateTimeFormat, x, false); } @@ -167,5 +167,5 @@ function Date_toLocaleTimeString() { } // Step 7. - return intl_FormatDateTime(dateTimeFormat, x); + return intl_FormatDateTime(dateTimeFormat, x, false); } diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 89fe2178688a..c780d1434745 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -12,6 +12,7 @@ #include "builtin/Intl.h" #include "mozilla/Range.h" +#include "mozilla/ScopeExit.h" #include @@ -45,6 +46,7 @@ using namespace js; using mozilla::IsFinite; using mozilla::IsNegativeZero; +using mozilla::MakeScopeExit; #if ENABLE_INTL_API using icu::Locale; @@ -176,6 +178,7 @@ ucol_getKeywordValuesForLocale(const char* key, const char* locale, UBool common struct UParseError; struct UFieldPosition; +struct UFieldPositionIterator; typedef void* UNumberFormat; enum UNumberFormatStyle { @@ -339,6 +342,46 @@ udatpg_close(UDateTimePatternGenerator* dtpg) typedef void* UCalendar; typedef void* UDateFormat; +enum UDateFormatField { + UDAT_ERA_FIELD = 0, + UDAT_YEAR_FIELD = 1, + UDAT_MONTH_FIELD = 2, + UDAT_DATE_FIELD = 3, + UDAT_HOUR_OF_DAY1_FIELD = 4, + UDAT_HOUR_OF_DAY0_FIELD = 5, + UDAT_MINUTE_FIELD = 6, + UDAT_SECOND_FIELD = 7, + UDAT_FRACTIONAL_SECOND_FIELD = 8, + UDAT_DAY_OF_WEEK_FIELD = 9, + UDAT_DAY_OF_YEAR_FIELD = 10, + UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11, + UDAT_WEEK_OF_YEAR_FIELD = 12, + UDAT_WEEK_OF_MONTH_FIELD = 13, + UDAT_AM_PM_FIELD = 14, + UDAT_HOUR1_FIELD = 15, + UDAT_HOUR0_FIELD = 16, + UDAT_TIMEZONE_FIELD = 17, + UDAT_YEAR_WOY_FIELD = 18, + UDAT_DOW_LOCAL_FIELD = 19, + UDAT_EXTENDED_YEAR_FIELD = 20, + UDAT_JULIAN_DAY_FIELD = 21, + UDAT_MILLISECONDS_IN_DAY_FIELD = 22, + UDAT_TIMEZONE_RFC_FIELD = 23, + UDAT_TIMEZONE_GENERIC_FIELD = 24, + UDAT_STANDALONE_DAY_FIELD = 25, + UDAT_STANDALONE_MONTH_FIELD = 26, + UDAT_QUARTER_FIELD = 27, + UDAT_STANDALONE_QUARTER_FIELD = 28, + UDAT_TIMEZONE_SPECIAL_FIELD = 29, + UDAT_YEAR_NAME_FIELD = 30, + UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD = 31, + UDAT_TIMEZONE_ISO_FIELD = 32, + UDAT_TIMEZONE_ISO_LOCAL_FIELD = 33, + UDAT_RELATED_YEAR_FIELD = 34, + UDAT_TIME_SEPARATOR_FIELD = 35, + UDAT_FIELD_COUNT = 36 +}; + enum UDateFormatStyle { UDAT_PATTERN = -2, UDAT_IGNORE = UDAT_PATTERN @@ -383,6 +426,32 @@ udat_format(const UDateFormat* format, UDate dateToFormat, UChar* result, MOZ_CRASH("udat_format: Intl API disabled"); } +static int32_t +udat_formatForFields(const UDateFormat* format, UDate dateToFormat, + UChar* result, int32_t resultLength, UFieldPositionIterator* fpositer, + UErrorCode* status) +{ + MOZ_CRASH("udat_formatForFields: Intl API disabled"); +} + +static UFieldPositionIterator* +ufieldpositer_open(UErrorCode* status) +{ + MOZ_CRASH("ufieldpositer_open: Intl API disabled"); +} + +static void +ufieldpositer_close(UFieldPositionIterator* fpositer) +{ + MOZ_CRASH("ufieldpositer_close: Intl API disabled"); +} + +static int32_t +ufieldpositer_next(UFieldPositionIterator* fpositer, int32_t* beginIndex, int32_t* endIndex) +{ + MOZ_CRASH("ufieldpositer_next: Intl API disabled"); +} + static void udat_close(UDateFormat* format) { @@ -1669,11 +1738,9 @@ InitDateTimeFormatClass(JSContext* cx, HandleObject Intl, Handle if (!JS_DefineFunctions(cx, proto, dateTimeFormat_methods)) return nullptr; - /* - * Install the getter for DateTimeFormat.prototype.format, which returns a - * bound formatting function for the specified DateTimeFormat object - * (suitable for passing to methods like Array.prototype.map). - */ + // Install a getter for DateTimeFormat.prototype.format that returns a + // formatting function bound to a specified DateTimeFormat object (suitable + // for passing to methods like Array.prototype.map). RootedValue getter(cx); if (!GlobalObject::getIntrinsicValue(cx, cx->global(), cx->names().DateTimeFormatFormatGet, &getter)) @@ -1687,6 +1754,22 @@ InitDateTimeFormatClass(JSContext* cx, HandleObject Intl, Handle return nullptr; } + // If the still-experimental DateTimeFormat.prototype.formatToParts method + // is enabled, also add its getter. + if (cx->compartment()->creationOptions().experimentalDateTimeFormatFormatToPartsEnabled()) { + if (!GlobalObject::getIntrinsicValue(cx, cx->global(), + cx->names().DateTimeFormatFormatToPartsGet, &getter)) + { + return nullptr; + } + if (!DefineProperty(cx, proto, cx->names().formatToParts, UndefinedHandleValue, + JS_DATA_TO_FUNC_PTR(JSGetterOp, &getter.toObject()), + nullptr, JSPROP_GETTER | JSPROP_SHARED)) + { + return nullptr; + } + } + RootedValue options(cx); if (!CreateDefaultOptions(cx, &options)) return nullptr; @@ -1986,6 +2069,210 @@ intl_FormatDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue return false; result.setString(str); + + return true; +} + +using FieldType = ImmutablePropertyNamePtr JSAtomState::*; + +static FieldType +GetFieldTypeForFormatField(UDateFormatField fieldName) +{ + // See intl/icu/source/i18n/unicode/udat.h for a detailed field list. This + // switch is deliberately exhaustive: cases might have to be added/removed + // if this code is compiled with a different ICU with more + // UDateFormatField enum initializers. Please guard such cases with + // appropriate ICU version-testing #ifdefs, should cross-version divergence + // occur. + switch (fieldName) { + case UDAT_ERA_FIELD: + return &JSAtomState::era; + case UDAT_YEAR_FIELD: + case UDAT_YEAR_WOY_FIELD: + case UDAT_EXTENDED_YEAR_FIELD: + case UDAT_YEAR_NAME_FIELD: + return &JSAtomState::year; + + case UDAT_MONTH_FIELD: + case UDAT_STANDALONE_MONTH_FIELD: + return &JSAtomState::month; + + case UDAT_DATE_FIELD: + case UDAT_JULIAN_DAY_FIELD: + return &JSAtomState::day; + + case UDAT_HOUR_OF_DAY1_FIELD: + case UDAT_HOUR_OF_DAY0_FIELD: + case UDAT_HOUR1_FIELD: + case UDAT_HOUR0_FIELD: + return &JSAtomState::hour; + + case UDAT_MINUTE_FIELD: + return &JSAtomState::minute; + + case UDAT_SECOND_FIELD: + return &JSAtomState::second; + + case UDAT_DAY_OF_WEEK_FIELD: + case UDAT_STANDALONE_DAY_FIELD: + case UDAT_DOW_LOCAL_FIELD: + case UDAT_DAY_OF_WEEK_IN_MONTH_FIELD: + return &JSAtomState::weekday; + + case UDAT_AM_PM_FIELD: + return &JSAtomState::dayperiod; + + case UDAT_TIMEZONE_FIELD: + return &JSAtomState::timeZoneName; + + case UDAT_FRACTIONAL_SECOND_FIELD: + case UDAT_DAY_OF_YEAR_FIELD: + case UDAT_WEEK_OF_YEAR_FIELD: + case UDAT_WEEK_OF_MONTH_FIELD: + case UDAT_MILLISECONDS_IN_DAY_FIELD: + case UDAT_TIMEZONE_RFC_FIELD: + case UDAT_TIMEZONE_GENERIC_FIELD: + case UDAT_QUARTER_FIELD: + case UDAT_STANDALONE_QUARTER_FIELD: + case UDAT_TIMEZONE_SPECIAL_FIELD: + case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: + case UDAT_TIMEZONE_ISO_FIELD: + case UDAT_TIMEZONE_ISO_LOCAL_FIELD: +#ifndef U_HIDE_INTERNAL_API + case UDAT_RELATED_YEAR_FIELD: +#endif +#ifndef U_HIDE_DRAFT_API + case UDAT_TIME_SEPARATOR_FIELD: +#endif + // These fields are all unsupported. + return nullptr; + + case UDAT_FIELD_COUNT: + MOZ_ASSERT_UNREACHABLE("format field sentinel value returned by " + "iterator!"); + } + + MOZ_ASSERT_UNREACHABLE("unenumerated, undocumented format field returned " + "by iterator"); + return nullptr; +} + +static bool +intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue result) +{ + if (!IsFinite(x)) { + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE); + return false; + } + + Vector chars(cx); + if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE)) + return false; + + UErrorCode status = U_ZERO_ERROR; + UFieldPositionIterator* fpositer = ufieldpositer_open(&status); + if (U_FAILURE(status)) { + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + return false; + } + auto closeFieldPosIter = MakeScopeExit([&]() { ufieldpositer_close(fpositer); }); + + int resultSize = + udat_formatForFields(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, + fpositer, &status); + if (status == U_BUFFER_OVERFLOW_ERROR) { + if (!chars.resize(resultSize)) + return false; + status = U_ZERO_ERROR; + udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status); + } + if (U_FAILURE(status)) { + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + return false; + } + + RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx)); + if (!partsArray) + return false; + if (resultSize == 0) { + // An empty string contains no parts, so avoid extra work below. + result.setObject(*partsArray); + return true; + } + + RootedString overallResult(cx, NewStringCopyN(cx, chars.begin(), resultSize)); + if (!overallResult) + return false; + + size_t lastEndIndex = 0; + + uint32_t partIndex = 0; + RootedObject singlePart(cx); + RootedValue partType(cx); + RootedString partSubstr(cx); + RootedValue val(cx); + + auto AppendPart = [&](FieldType type, size_t beginIndex, size_t endIndex) { + singlePart = NewBuiltinClassInstance(cx); + if (!singlePart) + return false; + + partType = StringValue(cx->names().*type); + if (!DefineProperty(cx, singlePart, cx->names().type, partType)) + return false; + + partSubstr = SubstringKernel(cx, overallResult, beginIndex, endIndex - beginIndex); + if (!partSubstr) + return false; + + val = StringValue(partSubstr); + if (!DefineProperty(cx, singlePart, cx->names().value, val)) + return false; + + val = ObjectValue(*singlePart); + if (!DefineElement(cx, partsArray, partIndex, val)) + return false; + + lastEndIndex = endIndex; + partIndex++; + return true; + }; + + int32_t fieldInt, beginIndexInt, endIndexInt; + while ((fieldInt = ufieldpositer_next(fpositer, &beginIndexInt, &endIndexInt)) >= 0) { + MOZ_ASSERT(beginIndexInt >= 0); + MOZ_ASSERT(endIndexInt >= 0); + MOZ_ASSERT(beginIndexInt <= endIndexInt, + "field iterator returning invalid range"); + + size_t beginIndex(beginIndexInt); + size_t endIndex(endIndexInt); + + // Technically this isn't guaranteed. But it appears true in pratice, + // and http://bugs.icu-project.org/trac/ticket/12024 is expected to + // correct the documentation lapse. + MOZ_ASSERT(lastEndIndex <= beginIndex, + "field iteration didn't return fields in order start to " + "finish as expected"); + + if (FieldType type = GetFieldTypeForFormatField(static_cast(fieldInt))) { + if (lastEndIndex < beginIndex) { + if (!AppendPart(&JSAtomState::separator, lastEndIndex, beginIndex)) + return false; + } + + if (!AppendPart(type, beginIndex, endIndex)) + return false; + } + } + + // Append any final separator. + if (lastEndIndex < overallResult->length()) { + if (!AppendPart(&JSAtomState::separator, lastEndIndex, overallResult->length())) + return false; + } + + result.setObject(*partsArray); return true; } @@ -1993,9 +2280,10 @@ bool js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() == 2); + MOZ_ASSERT(args.length() == 3); MOZ_ASSERT(args[0].isObject()); MOZ_ASSERT(args[1].isNumber()); + MOZ_ASSERT(args[2].isBoolean()); RootedObject dateTimeFormat(cx, &args[0].toObject()); @@ -2024,7 +2312,9 @@ js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp) // Use the UDateFormat to actually format the time stamp. RootedValue result(cx); - bool success = intl_FormatDateTime(cx, df, args[1].toNumber(), &result); + bool success = args[2].toBoolean() + ? intl_FormatToPartsDateTime(cx, df, args[1].toNumber(), &result) + : intl_FormatDateTime(cx, df, args[1].toNumber(), &result); if (!isDateTimeFormatInstance) udat_close(df); diff --git a/js/src/builtin/Intl.js b/js/src/builtin/Intl.js index d69fa4599671..de7a1132265f 100644 --- a/js/src/builtin/Intl.js +++ b/js/src/builtin/Intl.js @@ -2712,10 +2712,9 @@ function dateTimeFormatFormatToBind() { var x = (date === undefined) ? std_Date_now() : ToNumber(date); // Step 1.a.iii. - return intl_FormatDateTime(this, x); + return intl_FormatDateTime(this, x, false); } - /** * Returns a function bound to this DateTimeFormat that returns a String value * representing the result of calling ToNumber(date) according to the @@ -2742,6 +2741,35 @@ function Intl_DateTimeFormat_format_get() { } +function dateTimeFormatFormatToPartsToBind() { + // Steps 1.a.i-ii + var date = arguments.length > 0 ? arguments[0] : undefined; + var x = (date === undefined) ? std_Date_now() : ToNumber(date); + + // Step 1.a.iii. + return intl_FormatDateTime(this, x, true); +} + + +function Intl_DateTimeFormat_formatToParts_get() { + // Check "this DateTimeFormat object" per introduction of section 12.3. + var internals = getDateTimeFormatInternals(this, "formatToParts"); + + // Step 1. + if (internals.boundFormatToParts === undefined) { + // Step 1.a. + var F = dateTimeFormatFormatToPartsToBind; + + // Step 1.b-d. + var bf = callFunction(std_Function_bind, F, this); + internals.boundFormatToParts = bf; + } + + // Step 2. + return internals.boundFormatToParts; +} + + /** * Returns the resolved options for a DateTimeFormat object. * diff --git a/js/src/builtin/embedjs.py b/js/src/builtin/embedjs.py index ece905dfefc3..fc2e9942e6f2 100644 --- a/js/src/builtin/embedjs.py +++ b/js/src/builtin/embedjs.py @@ -134,12 +134,8 @@ def get_config_defines(buildconfig): # Collect defines equivalent to ACDEFINES and add MOZ_DEBUG_DEFINES. env = {key: value for key, value in buildconfig.defines.iteritems() if key not in buildconfig.non_global_defines} - for value in buildconfig.substs['MOZ_DEBUG_DEFINES'].split(): - assert value[:2] == "-D" - pair = value[2:].split('=', 1) - if len(pair) == 1: - pair.append(1) - env[pair[0]] = pair[1] + for define in buildconfig.substs['MOZ_DEBUG_DEFINES']: + env[define] = 1 return env def process_inputs(namespace, c_out, msg_file, inputs): diff --git a/js/src/configure.in b/js/src/configure.in index 0f02b1fc2e78..74807ee6629c 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -1272,7 +1272,7 @@ if test "$GNU_CC"; then esac fi - _DEFINES_CFLAGS='-include $(DEPTH)/js/src/js-confdefs.h -DMOZILLA_CLIENT' + _DEFINES_CFLAGS='-include $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT' _USE_CPP_INCLUDE_FLAG=1 elif test "$SOLARIS_SUNPRO_CC"; then @@ -1384,7 +1384,7 @@ if test "$GNU_CXX"; then esac fi - _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/js/src/js-confdefs.h' + _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/js/src/js-confdefs.h' _USE_CPP_INCLUDE_FLAG=1 # Recent clang and gcc support C++11 deleted functions without warnings if @@ -1744,8 +1744,8 @@ ia64*-hpux*) WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION _USE_CPP_INCLUDE_FLAG=1 - _DEFINES_CFLAGS='-FI $(DEPTH)/js/src/js-confdefs.h -DMOZILLA_CLIENT' - _DEFINES_CXXFLAGS='-FI $(DEPTH)/js/src/js-confdefs.h -DMOZILLA_CLIENT' + _DEFINES_CFLAGS='-FI $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT' + _DEFINES_CXXFLAGS='-FI $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT' CFLAGS="$CFLAGS -W3 -Gy" CXXFLAGS="$CXXFLAGS -W3 -Gy" if test "$CPU_ARCH" = "x86" -a -z "$CLANG_CL"; then @@ -3731,22 +3731,19 @@ CXXFLAGS=`echo \ COMPILE_CFLAGS=`echo \ $_DEFINES_CFLAGS \ - $_DEPEND_CFLAGS \ $COMPILE_CFLAGS` COMPILE_CXXFLAGS=`echo \ $_DEFINES_CXXFLAGS \ - $_DEPEND_CFLAGS \ $COMPILE_CXXFLAGS` HOST_CFLAGS=`echo \ - $HOST_CFLAGS \ - $_DEPEND_CFLAGS` + $HOST_CFLAGS` HOST_CXXFLAGS=`echo \ - $HOST_CXXFLAGS \ - $_DEPEND_CFLAGS` + $HOST_CXXFLAGS` +AC_SUBST(_DEPEND_CFLAGS) AC_SUBST(MOZ_NATIVE_NSPR) if test -n "$MOZ_NUWA_PROCESS"; then diff --git a/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js b/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js new file mode 100644 index 000000000000..47001030f4bb --- /dev/null +++ b/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js @@ -0,0 +1,25 @@ +window.tests.set('propertyTreeSplitting', (function() { +var garbage = []; +var garbageIndex = 0; +return { + description: "use delete to generate Shape garbage", + load: (N) => { garbage = new Array(N); }, + unload: () => { garbage = []; garbageIndex = 0; }, + makeGarbage: (N) => { + function f() + { + var a1 = eval; + delete eval; + eval = a1; + var a3 = toString; + delete toString; + toString = a3; + } + for (var a = 0; a < N; ++a) { + garbage[garbageIndex++] = new f(); + if (garbageIndex == garbage.length) + garbageIndex = 0; + } + } +}; +})()); diff --git a/js/src/devtools/gc-ubench/index.html b/js/src/devtools/gc-ubench/index.html index 027e0c06f968..3b2ae9076877 100644 --- a/js/src/devtools/gc-ubench/index.html +++ b/js/src/devtools/gc-ubench/index.html @@ -20,6 +20,7 @@ + diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index 860e06eacb52..c603f9828cf4 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -78,7 +78,8 @@ var ignoreCallees = { "z_stream_s.zfree" : true, "GrGLInterface.fCallback" : true, "std::strstreambuf._M_alloc_fun" : true, - "std::strstreambuf._M_free_fun" : true + "std::strstreambuf._M_free_fun" : true, + "struct js::gc::Callback.op" : true, }; function fieldCallCannotGC(csu, fullfield) @@ -187,6 +188,9 @@ var ignoreFunctions = { "void test::RingbufferDumper::OnTestPartResult(testing::TestPartResult*)" : true, "float64 JS_GetCurrentEmbedderTime()" : true, + + "uint64 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true, + "uint32 js::TenuringTracer::moveObjectToTenured(JSObject*, JSObject*, int32)" : true, }; function isProtobuf(name) diff --git a/js/src/doc/JITOptimizations/Outcomes.md b/js/src/doc/JITOptimizations/Outcomes.md index 38e6089319e3..ddd59da2a007 100644 --- a/js/src/doc/JITOptimizations/Outcomes.md +++ b/js/src/doc/JITOptimizations/Outcomes.md @@ -407,6 +407,11 @@ a scope chain object. An inline cache element which loads a bare variable name by calling a getter function on the global object. +### ICNameStub_TypeOfNoProperty + +An inline cache element which loads undefined for the type +of a missing property. + ## Call Inlining Outcomes Optimization outcomes of attempts to inline function calls. diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index d7cf559b9874..0ee6357a11c7 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -756,6 +756,9 @@ class GCRuntime void setGCCallback(JSGCCallback callback, void* data); void callGCCallback(JSGCStatus status) const; + void setObjectsTenuredCallback(JSObjectsTenuredCallback callback, + void* data); + void callObjectsTenuredCallback(); bool addFinalizeCallback(JSFinalizeCallback callback, void* data); void removeFinalizeCallback(JSFinalizeCallback func); bool addWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback, void* data); @@ -1273,6 +1276,7 @@ class GCRuntime bool fullCompartmentChecks; Callback gcCallback; + Callback tenuredCallback; CallbackVector finalizeCallbacks; CallbackVector updateWeakPointerZoneGroupCallbacks; CallbackVector updateWeakPointerCompartmentCallbacks; diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 8df3c3c6d226..2627b12cc9ae 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -2215,6 +2215,8 @@ js::TenuringTracer::moveObjectToTenured(JSObject* dst, JSObject* src, AllocKind tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind); } else if (src->is()) { tenuredSize += ArgumentsObject::objectMovedDuringMinorGC(this, dst, src); + } else if (JSObjectMovedOp op = dst->getClass()->ext.objectMovedOp) { + op(dst, src); } else { // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above // to ensure any additional nursery buffers they hold are moved. diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index a5bcb6b9696d..8d03adc05073 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -496,6 +496,10 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList forwardedBuffers.finish(); TIME_END(updateJitActivations); + TIME_START(objectsTenuredCallback); + rt->gc.callObjectsTenuredCallback(); + TIME_END(objectsTenuredCallback); + // Sweep. TIME_START(freeMallocedBuffers); freeMallocedBuffers(); @@ -576,6 +580,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList {"mkDbgr", TIME_TOTAL(markDebugger)}, {"clrNOC", TIME_TOTAL(clearNewObjectCache)}, {"collct", TIME_TOTAL(collectToFP)}, + {" tenCB", TIME_TOTAL(objectsTenuredCallback)}, {"swpABO", TIME_TOTAL(sweepArrayBufferViewList)}, {"updtIn", TIME_TOTAL(updateJitActivations)}, {"frSlts", TIME_TOTAL(freeMallocedBuffers)}, diff --git a/js/src/jit-test/tests/ion/bug470143.js b/js/src/jit-test/tests/ion/bug470143.js new file mode 100644 index 000000000000..0b63d4f0a4ff --- /dev/null +++ b/js/src/jit-test/tests/ion/bug470143.js @@ -0,0 +1,6 @@ +// Test that getname caches correctly handle typeof for missing names. +function f() { for (i = 0; i < 2000; ++i) { var k = typeof nosuchvar; } return k; } + +assertEq(f(), "undefined"); +this.nosuchvar = 5; +assertEq(f(), "number"); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index ca3b6fda210e..2d358735af1a 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -4920,6 +4920,62 @@ IsCacheableNameCallGetter(HandleObject scopeChain, HandleObject obj, HandleObjec IsCacheableGetPropCallScripted(obj, holder, shape); } +bool +NameIC::attachTypeOfNoProperty(JSContext* cx, HandleScript outerScript, IonScript* ion, + HandleObject scopeChain) +{ + MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); + Label failures; + StubAttacher attacher(*this); + + Register scratchReg = outputReg().valueReg().scratchReg(); + + masm.movePtr(scopeChainReg(), scratchReg); + + // Generate scope chain guards. + // Since the property was not defined on any object, iterate until reaching the global. + JSObject* tobj = scopeChain; + while (true) { + GenerateScopeChainGuard(masm, tobj, scratchReg, nullptr, &failures); + + if (tobj->is()) + break; + + // Load the next link. + tobj = &tobj->as().enclosingScope(); + masm.extractObject(Address(scratchReg, ScopeObject::offsetOfEnclosingScope()), scratchReg); + } + + masm.moveValue(UndefinedValue(), outputReg().valueReg()); + attacher.jumpRejoin(masm); + + masm.bind(&failures); + attacher.jumpNextStub(masm); + + return linkAndAttachStub(cx, masm, attacher, ion, "generic", + JS::TrackedOutcome::ICNameStub_TypeOfNoProperty); +} + +static bool +IsCacheableNameNoProperty(HandleObject scopeChain, HandleObject obj, + HandleObject holder, HandleShape shape, jsbytecode* pc, + NameIC& cache) +{ + if (cache.isTypeOf() && !shape) { + MOZ_ASSERT(!obj); + MOZ_ASSERT(!holder); + MOZ_ASSERT(scopeChain); + + // Assert those extra things checked by IsCacheableNoProperty(). + MOZ_ASSERT(cache.outputReg().hasValue()); + MOZ_ASSERT(pc != nullptr); + + return true; + } + + return false; +} + bool NameIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex, HandleObject scopeChain, MutableHandleValue vp) @@ -4962,6 +5018,9 @@ NameIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex, Handl { return false; } + } else if (IsCacheableNameNoProperty(scopeChain, obj, holder, shape, pc, cache)) { + if (!cache.attachTypeOfNoProperty(cx, outerScript, ion, scopeChain)) + return false; } } diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index e3c3e35371f8..9655be2f2c6c 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -794,6 +794,9 @@ class NameIC : public IonCache HandleObject scopeChain, HandleObject obj, HandleObject holder, HandleShape shape, void* returnAddr); + bool attachTypeOfNoProperty(JSContext* cx, HandleScript outerScript, IonScript* ion, + HandleObject scopeChain); + static bool update(JSContext* cx, HandleScript outerScript, size_t cacheIndex, HandleObject scopeChain, MutableHandleValue vp); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e3e0cad2eb0c..07a75f3f9d71 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1395,6 +1395,14 @@ JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data) rt->gc.setGCCallback(cb, data); } +JS_PUBLIC_API(void) +JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb, + void* data) +{ + AssertHeapIsIdle(rt); + rt->gc.setObjectsTenuredCallback(cb, data); +} + JS_PUBLIC_API(bool) JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data) { diff --git a/js/src/jsapi.h b/js/src/jsapi.h index fd8e23699aff..07f9e34199c1 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -572,6 +572,9 @@ typedef enum JSGCStatus { typedef void (* JSGCCallback)(JSRuntime* rt, JSGCStatus status, void* data); +typedef void +(* JSObjectsTenuredCallback)(JSRuntime* rt, void* data); + typedef enum JSFinalizeStatus { /** * Called when preparing to sweep a group of compartments, before anything @@ -1654,6 +1657,10 @@ JS_MaybeGC(JSContext* cx); extern JS_PUBLIC_API(void) JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data); +extern JS_PUBLIC_API(void) +JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb, + void* data); + extern JS_PUBLIC_API(bool) JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data); @@ -2173,7 +2180,8 @@ class JS_PUBLIC_API(CompartmentCreationOptions) invisibleToDebugger_(false), mergeable_(false), preserveJitCode_(false), - cloneSingletons_(false) + cloneSingletons_(false), + experimentalDateTimeFormatFormatToPartsEnabled_(false) { zone_.spec = JS::FreshZone; } @@ -2236,6 +2244,24 @@ class JS_PUBLIC_API(CompartmentCreationOptions) return *this; } + // ECMA-402 is considering adding a "formatToParts" DateTimeFormat method, + // that exposes not just a formatted string but its ordered subcomponents. + // The method, its semantics, and its name are all well short of being + // finalized, so for now it's exposed *only* if requested. + // + // Until "formatToParts" is included in a final specification edition, it's + // subject to change or removal at any time. Do *not* rely on it in + // mission-critical code that can't be changed if ECMA-402 decides not to + // accept the method in its current form. + bool experimentalDateTimeFormatFormatToPartsEnabled() const { + return experimentalDateTimeFormatFormatToPartsEnabled_; + } + CompartmentCreationOptions& setExperimentalDateTimeFormatFormatToPartsEnabled(bool flag) { + experimentalDateTimeFormatFormatToPartsEnabled_ = flag; + return *this; + } + + private: JSAddonId* addonId_; JSTraceOp traceGlobal_; @@ -2247,6 +2273,7 @@ class JS_PUBLIC_API(CompartmentCreationOptions) bool mergeable_; bool preserveJitCode_; bool cloneSingletons_; + bool experimentalDateTimeFormatFormatToPartsEnabled_; }; /** diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index e8d3d583d878..99ee99ee1b53 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1606,6 +1606,21 @@ GCRuntime::callGCCallback(JSGCStatus status) const gcCallback.op(rt, status, gcCallback.data); } +void +GCRuntime::setObjectsTenuredCallback(JSObjectsTenuredCallback callback, + void* data) +{ + tenuredCallback.op = callback; + tenuredCallback.data = data; +} + +void +GCRuntime::callObjectsTenuredCallback() +{ + if (tenuredCallback.op) + tenuredCallback.op(rt, tenuredCallback.data); +} + namespace { class AutoNotifyGCActivity { diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index b7e90943b8ef..d45948c06422 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3977,6 +3977,11 @@ NewGlobal(JSContext* cx, unsigned argc, Value* vp) if (v.isBoolean()) creationOptions.setCloneSingletons(v.toBoolean()); + if (!JS_GetProperty(cx, opts, "experimentalDateTimeFormatFormatToPartsEnabled", &v)) + return true; + if (v.isBoolean()) + creationOptions.setExperimentalDateTimeFormatFormatToPartsEnabled(v.toBoolean()); + if (!JS_GetProperty(cx, opts, "sameZoneAs", &v)) return false; if (v.isObject()) diff --git a/js/src/tests/Intl/DateTimeFormat/formatToParts.js b/js/src/tests/Intl/DateTimeFormat/formatToParts.js new file mode 100644 index 000000000000..e88439cffdcd --- /dev/null +++ b/js/src/tests/Intl/DateTimeFormat/formatToParts.js @@ -0,0 +1,176 @@ +// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.newGlobal||!newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat().formatToParts) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Tests the format function with a diverse set of locales and options. +// Always use UTC to avoid dependencies on test environment. + +/* + * Return true if A is equal to B, where equality on arrays and objects + * means that they have the same set of enumerable properties, the values + * of each property are deep_equal, and their 'length' properties are + * equal. Equality on other types is ==. + */ +function deepEqual(a, b) { + if (typeof a !== typeof b) + return false; + + if (a === null) + return b === null; + + if (typeof a === 'object') { + // For every property of a, does b have that property with an equal value? + var props = {}; + for (var prop in a) { + if (!deepEqual(a[prop], b[prop])) + return false; + props[prop] = true; + } + + // Are all of b's properties present on a? + for (var prop in b) + if (!props[prop]) + return false; + + // length isn't enumerable, but we want to check it, too. + return a.length === b.length; + } + + return Object.is(a, b); +} + +function composeDate(parts) { + return parts.map(({value}) => value) + .reduce((string, part) => string + part); +} + +var format; +var date = Date.UTC(2012, 11, 17, 3, 0, 42); + +// The experimental formatToParts method is only exposed if specifically +// requested. Perform all tests using DateTimeFormat instances from a global +// object with this method enabled. +var DateTimeFormat = + newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat; + +// Locale en-US; default options. +format = new DateTimeFormat("en-us", {timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'month', value: '12' }, + { type: 'separator', value: '/' }, + { type: 'day', value: '17' }, + { type: 'separator', value: '/' }, + { type: 'year', value: '2012' } +]), true); + +// Just date +format = new DateTimeFormat("en-us", { + year: 'numeric', + month: 'numeric', + day: 'numeric', + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'month', value: '12' }, + { type: 'separator', value: '/' }, + { type: 'day', value: '17' }, + { type: 'separator', value: '/' }, + { type: 'year', value: '2012' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Just time in hour24 +format = new DateTimeFormat("en-us", { + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: false, + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'hour', value: '03' }, + { type: 'separator', value: ':' }, + { type: 'minute', value: '00' }, + { type: 'separator', value: ':' }, + { type: 'second', value: '42' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Just time in hour12 +format = new DateTimeFormat("en-us", { + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: true, + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'hour', value: '3' }, + { type: 'separator', value: ':' }, + { type: 'minute', value: '00' }, + { type: 'separator', value: ':' }, + { type: 'second', value: '42' }, + { type: 'separator', value: ' ' }, + { type: 'dayperiod', value: 'AM' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Just month. +format = new DateTimeFormat("en-us", { + month: "narrow", + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'month', value: 'D' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Just weekday. +format = new DateTimeFormat("en-us", { + weekday: "narrow", + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'weekday', value: 'M' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Year and era. +format = new DateTimeFormat("en-us", { + year: "numeric", + era: "short", + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'year', value: '2012' }, + { type: 'separator', value: ' ' }, + { type: 'era', value: 'AD' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +// Time and date +format = new DateTimeFormat("en-us", { + weekday: 'long', + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: true, + timeZone: "UTC"}); +assertEq(deepEqual(format.formatToParts(date), [ + { type: 'weekday', value: 'Monday' }, + { type: 'separator', value: ', ' }, + { type: 'month', value: '12' }, + { type: 'separator', value: '/' }, + { type: 'day', value: '17' }, + { type: 'separator', value: '/' }, + { type: 'year', value: '2012' }, + { type: 'separator', value: ', ' }, + { type: 'hour', value: '3' }, + { type: 'separator', value: ':' }, + { type: 'minute', value: '00' }, + { type: 'separator', value: ':' }, + { type: 'second', value: '42' }, + { type: 'separator', value: ' ' }, + { type: 'dayperiod', value: 'AM' } +]), true); +assertEq(composeDate(format.formatToParts(date)), format.format(date)); + +if (typeof reportCompare === "function") + reportCompare(0, 0, 'ok'); diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 23aead116693..b6cf006254f7 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -59,6 +59,9 @@ macro(currencyDisplay, currencyDisplay, "currencyDisplay") \ macro(DateTimeFormat, DateTimeFormat, "DateTimeFormat") \ macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \ + macro(DateTimeFormatFormatToPartsGet, DateTimeFormatFormatToPartsGet, "Intl_DateTimeFormat_formatToParts_get") \ + macro(day, day, "day") \ + macro(dayperiod, dayperiod, "dayperiod") \ macro(decodeURI, decodeURI, "decodeURI") \ macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \ macro(default_, default_, "default") \ @@ -80,6 +83,7 @@ macro(endTimestamp, endTimestamp, "endTimestamp") \ macro(enumerable, enumerable, "enumerable") \ macro(enumerate, enumerate, "enumerate") \ + macro(era, era, "era") \ macro(escape, escape, "escape") \ macro(eval, eval, "eval") \ macro(false, false_, "false") \ @@ -95,6 +99,7 @@ macro(forceInterpreter, forceInterpreter, "forceInterpreter") \ macro(forEach, forEach, "forEach") \ macro(format, format, "format") \ + macro(formatToParts, formatToParts, "formatToParts") \ macro(frame, frame, "frame") \ macro(from, from, "from") \ macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \ @@ -109,6 +114,7 @@ macro(has, has, "has") \ macro(hasOwn, hasOwn, "hasOwn") \ macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \ + macro(hour, hour, "hour") \ macro(ignoreCase, ignoreCase, "ignoreCase") \ macro(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \ macro(index, index, "index") \ @@ -152,8 +158,10 @@ macro(minimumFractionDigits, minimumFractionDigits, "minimumFractionDigits") \ macro(minimumIntegerDigits, minimumIntegerDigits, "minimumIntegerDigits") \ macro(minimumSignificantDigits, minimumSignificantDigits, "minimumSignificantDigits") \ + macro(minute, minute, "minute") \ macro(missingArguments, missingArguments, "missingArguments") \ macro(module, module, "module") \ + macro(month, month, "month") \ macro(multiline, multiline, "multiline") \ macro(name, name, "name") \ macro(NaN, NaN, "NaN") \ @@ -200,7 +208,9 @@ macro(revoke, revoke, "revoke") \ macro(script, script, "script") \ macro(scripts, scripts, "scripts") \ + macro(second, second, "second") \ macro(sensitivity, sensitivity, "sensitivity") \ + macro(separator, separator, "separator") \ macro(set, set, "set") \ macro(shape, shape, "shape") \ macro(size, size, "size") \ @@ -221,6 +231,7 @@ macro(throw, throw_, "throw") \ macro(timestamp, timestamp, "timestamp") \ macro(timeZone, timeZone, "timeZone") \ + macro(timeZoneName, timeZoneName, "timeZoneName") \ macro(toGMTString, toGMTString, "toGMTString") \ macro(toISOString, toISOString, "toISOString") \ macro(toJSON, toJSON, "toJSON") \ @@ -229,6 +240,7 @@ macro(toString, toString, "toString") \ macro(toUTCString, toUTCString, "toUTCString") \ macro(true, true_, "true") \ + macro(type, type, "type") \ macro(unescape, unescape, "unescape") \ macro(uneval, uneval, "uneval") \ macro(unicode, unicode, "unicode") \ @@ -255,7 +267,9 @@ macro(void0, void0, "(void 0)") \ macro(watch, watch, "watch") \ macro(WeakSet_add, WeakSet_add, "WeakSet_add") \ + macro(weekday, weekday, "weekday") \ macro(writable, writable, "writable") \ + macro(year, year, "year") \ macro(yield, yield, "yield") \ macro(raw, raw, "raw") \ /* Type names must be contiguous and ordered; see js::TypeName. */ \ diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index a4f52875a768..10d04db34ff9 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1062,6 +1062,9 @@ IsStickyFrameActive(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame* // Find the nearest scrollframe. nsIFrame* cursor = aFrame; nsIFrame* parent = aParent; + if (!parent) { + parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame); + } while (parent->GetType() != nsGkAtoms::scrollFrame) { cursor = parent; if ((parent = nsLayoutUtils::GetCrossDocParentFrame(cursor)) == nullptr) { @@ -4952,6 +4955,12 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder) // determine if we are inside a fixed pos subtree. If we use the outer AGR // from outside the fixed pos subtree FLB can't tell that we are fixed pos. mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren; + } else if (mFrame->StyleDisplay()->mPosition == NS_STYLE_POSITION_STICKY && + IsStickyFrameActive(aBuilder, mFrame, nullptr)) { + // Similar to the IsFixedPosFrameInDisplayPort case we are our own AGR. + // We are inside the sticky position, so our AGR is the sticky positioned + // frame, which is our AGR, not the parent AGR. + mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren; } else if (mAnimatedGeometryRoot->mParentAGR) { mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index d59f3d6ce7a8..53af68d3a272 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -6204,7 +6204,6 @@ nsTextFrame::DrawEmphasisMarks(gfxContext* aContext, WritingMode aWM, auto info = static_cast( Properties().Get(EmphasisMarkProperty())); if (!info) { - MOZ_ASSERT(!StyleText()->HasTextEmphasis()); return; } @@ -7873,7 +7872,9 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext, if (i > wordStart) { nscoord width = - NSToCoordCeilClamped(textRun->GetAdvanceWidth(wordStart, i - wordStart, &provider)); + NSToCoordCeilClamped(textRun->GetAdvanceWidth(wordStart, i - wordStart, + &provider)); + width = std::max(0, width); aData->currentLine = NSCoordSaturatingAdd(aData->currentLine, width); aData->atStartOfLine = false; @@ -7885,8 +7886,11 @@ nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext, aData->trailingWhitespace += width; } else { // Some non-whitespace so the old trailingWhitespace is no longer trailing - aData->trailingWhitespace = - NSToCoordCeilClamped(textRun->GetAdvanceWidth(trimStart, i - trimStart, &provider)); + nscoord wsWidth = + NSToCoordCeilClamped(textRun->GetAdvanceWidth(trimStart, + i - trimStart, + &provider)); + aData->trailingWhitespace = std::max(0, wsWidth); } } else { aData->trailingWhitespace = 0; @@ -8025,7 +8029,9 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext, if (i > lineStart) { nscoord width = - NSToCoordCeilClamped(textRun->GetAdvanceWidth(lineStart, i - lineStart, &provider)); + NSToCoordCeilClamped(textRun->GetAdvanceWidth(lineStart, i - lineStart, + &provider)); + width = std::max(0, width); aData->currentLine = NSCoordSaturatingAdd(aData->currentLine, width); if (collapseWhitespace) { @@ -8036,8 +8042,11 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext, aData->trailingWhitespace += width; } else { // Some non-whitespace so the old trailingWhitespace is no longer trailing - aData->trailingWhitespace = - NSToCoordCeilClamped(textRun->GetAdvanceWidth(trimStart, i - trimStart, &provider)); + nscoord wsWidth = + NSToCoordCeilClamped(textRun->GetAdvanceWidth(trimStart, + i - trimStart, + &provider)); + aData->trailingWhitespace = std::max(0, wsWidth); } } else { aData->trailingWhitespace = 0; diff --git a/layout/reftests/reftest.list b/layout/reftests/reftest.list index e9204af90771..0a889acc7e29 100644 --- a/layout/reftests/reftest.list +++ b/layout/reftests/reftest.list @@ -370,6 +370,9 @@ skip-if(Android) include ../xul/reftest/reftest.list # xul grid (no XUL theme on Android) skip-if(Android) include ../xul/grid/reftests/reftest.list +# -webkit-box & associated properties (mapped to modern flexbox) +include webkit-box/reftest.list + # -webkit-gradient expressions include webkit-gradient/reftest.list diff --git a/layout/reftests/text/negative-letter-spacing-1-ref.html b/layout/reftests/text/negative-letter-spacing-1-ref.html new file mode 100644 index 000000000000..3411c34a1f8f --- /dev/null +++ b/layout/reftests/text/negative-letter-spacing-1-ref.html @@ -0,0 +1,13 @@ + + + + + + + +
sameline?
diff --git a/layout/reftests/text/negative-letter-spacing-1.html b/layout/reftests/text/negative-letter-spacing-1.html new file mode 100644 index 000000000000..69c1f6fa4bde --- /dev/null +++ b/layout/reftests/text/negative-letter-spacing-1.html @@ -0,0 +1,18 @@ + + + + + + + +
same line?
diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index f1a55ad6527d..fab1274ef91f 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -324,3 +324,6 @@ pref(layout.css.control-characters.visible,true) != control-chars-04d.html contr # font fallback for when not supported in the primary font family - bug 970891 HTTP(..) == space-font-1.html space-font-1-ref.html + +# handling of highly negative letter-spacing and intrinsic width +== negative-letter-spacing-1.html negative-letter-spacing-1-ref.html diff --git a/layout/reftests/webkit-box/reftest.list b/layout/reftests/webkit-box/reftest.list new file mode 100644 index 000000000000..2ef9346e969b --- /dev/null +++ b/layout/reftests/webkit-box/reftest.list @@ -0,0 +1,13 @@ +# This directory contains tests for "display: -webkit-box" and associated +# CSS properties. These tests require webkit prefix support to be enabled. +default-preferences pref(layout.css.prefixes.webkit,true) + +# Tests for "-webkit-box-align" (cross-axis alignment): +== webkit-box-align-horiz-1a.html webkit-box-align-horiz-1-ref.html +== webkit-box-align-horiz-1b.html webkit-box-align-horiz-1-ref.html +== webkit-box-align-vert-1.html webkit-box-align-vert-1-ref.html + +# Tests for "-webkit-box-pack" (main-axis alignment): +== webkit-box-pack-horiz-1a.html webkit-box-pack-horiz-1-ref.html +== webkit-box-pack-horiz-1b.html webkit-box-pack-horiz-1-ref.html +== webkit-box-pack-vert-1.html webkit-box-pack-vert-1-ref.html diff --git a/layout/reftests/webkit-box/webkit-box-align-horiz-1-ref.html b/layout/reftests/webkit-box/webkit-box-align-horiz-1-ref.html new file mode 100644 index 000000000000..2ee021a63e4f --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-align-horiz-1-ref.html @@ -0,0 +1,172 @@ + + + + + + CSS Reference + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-align-horiz-1a.html b/layout/reftests/webkit-box/webkit-box-align-horiz-1a.html new file mode 100644 index 000000000000..eb2dc06f7461 --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-align-horiz-1a.html @@ -0,0 +1,173 @@ + + + + + + CSS Test: horizontally-oriented "display: -webkit-box" container, + with all the various -webkit-box-align values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-align-horiz-1b.html b/layout/reftests/webkit-box/webkit-box-align-horiz-1b.html new file mode 100644 index 000000000000..9d200346d006 --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-align-horiz-1b.html @@ -0,0 +1,174 @@ + + + + + + CSS Test: horizontally-oriented "display: -webkit-box" container, + with all the various -webkit-box-align values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-align-vert-1-ref.html b/layout/reftests/webkit-box/webkit-box-align-vert-1-ref.html new file mode 100644 index 000000000000..f71af621b3da --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-align-vert-1-ref.html @@ -0,0 +1,173 @@ + + + + + + CSS Reference + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-align-vert-1.html b/layout/reftests/webkit-box/webkit-box-align-vert-1.html new file mode 100644 index 000000000000..63d4ff0b4dfd --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-align-vert-1.html @@ -0,0 +1,174 @@ + + + + + + CSS Test: vertically-oriented "display: -webkit-box" container, + with all the various -webkit-box-align values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-pack-horiz-1-ref.html b/layout/reftests/webkit-box/webkit-box-pack-horiz-1-ref.html new file mode 100644 index 000000000000..0e57cfbe40de --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-pack-horiz-1-ref.html @@ -0,0 +1,151 @@ + + + + + + CSS Reference + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-pack-horiz-1a.html b/layout/reftests/webkit-box/webkit-box-pack-horiz-1a.html new file mode 100644 index 000000000000..1b97305f99e6 --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-pack-horiz-1a.html @@ -0,0 +1,152 @@ + + + + + + CSS Test: horizontally-oriented "display: -webkit-box" container, + with all the various -webkit-box-pack values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-pack-horiz-1b.html b/layout/reftests/webkit-box/webkit-box-pack-horiz-1b.html new file mode 100644 index 000000000000..924581b622b0 --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-pack-horiz-1b.html @@ -0,0 +1,153 @@ + + + + + + CSS Test: horizontally-oriented "display: -webkit-box" container, + with all the various -webkit-box-pack values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-pack-vert-1-ref.html b/layout/reftests/webkit-box/webkit-box-pack-vert-1-ref.html new file mode 100644 index 000000000000..e859941fce11 --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-pack-vert-1-ref.html @@ -0,0 +1,152 @@ + + + + + + CSS Reference + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/reftests/webkit-box/webkit-box-pack-vert-1.html b/layout/reftests/webkit-box/webkit-box-pack-vert-1.html new file mode 100644 index 000000000000..d6ea3e14842d --- /dev/null +++ b/layout/reftests/webkit-box/webkit-box-pack-vert-1.html @@ -0,0 +1,153 @@ + + + + + + CSS Test: vertically-oriented "display: -webkit-box" container, + with all the various -webkit-box-pack values. + + + + + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+ + +
+
a
b
+
+
+ + + diff --git a/layout/style/html.css b/layout/style/html.css index bb3a1d46e17e..f8f47c660ef9 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -759,7 +759,7 @@ audio:not([controls]) { *|*::-moz-html-canvas-content { display: block !important; /* we want to be an absolute and fixed container */ - -moz-transform: translate(0) !important; + transform: translate(0) !important; } video > .caption-box { diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index d2953eb13109..653a4cb01772 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -13,6 +13,7 @@ #include "CSSVariableImageTable.h" #include "mozilla/css/Declaration.h" #include "mozilla/css/ImageLoader.h" +#include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" #include "mozilla/WritingModes.h" #include "nsIDocument.h" @@ -39,6 +40,50 @@ MoveValue(nsCSSValue* aSource, nsCSSValue* aDest) return changed; } +/** + * This function maps "-webkit-box-orient" values to "flex-direction" values, + * for a given writing-mode (taken from aRuleData). + * + * Specifically: + * - If aBoxOrientVal is an enumerated value (representing a physical axis), + * then we'll map it to the appropriate logical "flex-direction" value, using + * the writing mode. The converted value will be emplace()'d into in the + * outparam aConvertedValStorage, and we'll return a pointer to that value. + * - Otherwise (e.g. if we have "inherit" or "initial"), we won't do any + * mapping, and we'll directly return the passed-in aBoxOrientVal. + * + * Either way, the idea is that our caller can treat the returned value as if + * it were a value for "flex-direction". + */ +static const nsCSSValue* +ConvertBoxOrientToFlexDirection(const nsCSSValue* aBoxOrientVal, + const nsRuleData* aRuleData, + Maybe& aConvertedValStorage) +{ + MOZ_ASSERT(aBoxOrientVal, "expecting a non-null value to convert"); + MOZ_ASSERT(aConvertedValStorage.isNothing(), + "expecting outparam for converted-value to be initially empty"); + + if (aBoxOrientVal->GetUnit() != eCSSUnit_Enumerated) { + // We probably have "inherit" or "initial" -- just return that & have the + // caller directly use it as a "flex-direction" value. + return aBoxOrientVal; + } + + // OK, we have an enumerated value -- "horizontal" or "vertical". + + WritingMode wm(aRuleData->mStyleContext); + // In a horizontal writing-mode, "horizontal" maps to "row". + // In a vertical writing-mode, "horizontal" maps to "column". + bool isRow = wm.IsVertical() != + (aBoxOrientVal->GetIntValue() == NS_STYLE_BOX_ORIENT_HORIZONTAL); + + aConvertedValStorage.emplace(isRow ? NS_STYLE_FLEX_DIRECTION_ROW : + NS_STYLE_FLEX_DIRECTION_COLUMN, + eCSSUnit_Enumerated); + return aConvertedValStorage.ptr(); +} + static bool ShouldIgnoreColors(nsRuleData *aRuleData) { @@ -124,57 +169,84 @@ ShouldStartImageLoads(nsRuleData *aRuleData, nsCSSProperty aProperty) } static void -MapSinglePropertyInto(nsCSSProperty aProp, - const nsCSSValue* aValue, - nsCSSValue* aTarget, +MapSinglePropertyInto(nsCSSProperty aSrcProp, + const nsCSSValue* aSrcValue, + nsCSSProperty aTargetProp, + nsCSSValue* aTargetValue, nsRuleData* aRuleData) { - MOZ_ASSERT(aValue->GetUnit() != eCSSUnit_Null, "oops"); + MOZ_ASSERT(!nsCSSProps::PropHasFlags(aTargetProp, CSS_PROPERTY_LOGICAL), + "Can't map into a logical property"); + MOZ_ASSERT(aSrcProp == aTargetProp || + nsCSSProps::PropHasFlags(aSrcProp, CSS_PROPERTY_LOGICAL), + "Source & target property must be the same, except when we're " + "doing a logical-to-physical property mapping"); + MOZ_ASSERT(aSrcValue->GetUnit() != eCSSUnit_Null, "oops"); - // Although aTarget is the nsCSSValue we are going to write into, + // Handle logical properties that have custom value-mapping behavior: + Maybe convertedVal; // storage for converted value, if needed + bool hasCustomValMapping = + nsCSSProps::PropHasFlags(aSrcProp, + CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING); + if (hasCustomValMapping) { + if (aSrcProp == eCSSProperty_webkit_box_orient) { + aSrcValue = ConvertBoxOrientToFlexDirection(aSrcValue, aRuleData, + convertedVal); + } + } + + // Although aTargetValue is the nsCSSValue we are going to write into, // we also look at its value before writing into it. This is done - // when aTarget is a token stream value, which is the case when we + // when aTargetValue is a token stream value, which is the case when we // have just re-parsed a property that had a variable reference (in // nsCSSParser::ParsePropertyWithVariableReferences). TryToStartImageLoad // then records any resulting ImageValue objects in the // CSSVariableImageTable, to give them the appropriate lifetime. - MOZ_ASSERT(aTarget->GetUnit() == eCSSUnit_TokenStream || - aTarget->GetUnit() == eCSSUnit_Null, - "aTarget must only be a token stream (when re-parsing " + MOZ_ASSERT(aTargetValue->GetUnit() == eCSSUnit_TokenStream || + aTargetValue->GetUnit() == eCSSUnit_Null, + "aTargetValue must only be a token stream (when re-parsing " "properties with variable references) or null"); - if (ShouldStartImageLoads(aRuleData, aProp)) { + if (ShouldStartImageLoads(aRuleData, aTargetProp)) { nsIDocument* doc = aRuleData->mPresContext->Document(); - TryToStartImageLoad(*aValue, doc, aRuleData->mStyleContext, aProp, - aTarget->GetUnit() == eCSSUnit_TokenStream); + TryToStartImageLoad(*aSrcValue, doc, aRuleData->mStyleContext, + aTargetProp, + aTargetValue->GetUnit() == eCSSUnit_TokenStream); } - *aTarget = *aValue; - if (nsCSSProps::PropHasFlags(aProp, + *aTargetValue = *aSrcValue; + if (nsCSSProps::PropHasFlags(aTargetProp, CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) && ShouldIgnoreColors(aRuleData)) { - if (aProp == eCSSProperty_background_color) { + if (aTargetProp == eCSSProperty_background_color) { // Force non-'transparent' background // colors to the user's default. - if (aTarget->IsNonTransparentColor()) { - aTarget->SetColorValue(aRuleData->mPresContext-> - DefaultBackgroundColor()); + if (aTargetValue->IsNonTransparentColor()) { + aTargetValue->SetColorValue(aRuleData->mPresContext-> + DefaultBackgroundColor()); } } else { // Ignore 'color', 'border-*-color', etc. - *aTarget = nsCSSValue(); + *aTargetValue = nsCSSValue(); } } } /** - * If aProperty is a logical property, converts it to the equivalent physical + * If aProperty is a logical property, returns the equivalent physical * property based on writing mode information obtained from aRuleData's * style context. */ -static inline void -EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) +static inline nsCSSProperty +EnsurePhysicalProperty(nsCSSProperty aProperty, nsRuleData* aRuleData) { + if (!nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL)) { + return aProperty; + } + + bool isSingleProperty = + nsCSSProps::PropHasFlags(aProperty, + CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING); bool isAxisProperty = nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS); bool isBlock = @@ -182,7 +254,9 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) int index; - if (isAxisProperty) { + if (isSingleProperty) { + index = 0; // We always map to the same physical property. + } else if (isAxisProperty) { LogicalAxis logicalAxis = isBlock ? eLogicalAxisBlock : eLogicalAxisInline; uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode; PhysicalAxis axis = @@ -222,7 +296,8 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) const nsCSSProperty* props = nsCSSProps::LogicalGroup(aProperty); #ifdef DEBUG { - size_t len = isAxisProperty ? 2 : 4; + // Table-length is 1 for single prop, 2 for axis prop, 4 for block prop. + size_t len = isSingleProperty ? 1 : (isAxisProperty ? 2 : 4); for (size_t i = 0; i < len; i++) { MOZ_ASSERT(props[i] != eCSSProperty_UNKNOWN, "unexpected logical group length"); @@ -231,7 +306,7 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData) "unexpected logical group length"); } #endif - aProperty = props[index]; + return props[index]; } void @@ -251,15 +326,16 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const nsCSSProperty iProp = PropertyAtIndex(i); if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) & aRuleData->mSIDs) { - if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) { - EnsurePhysicalProperty(iProp, aRuleData); + nsCSSProperty physicalProp = EnsurePhysicalProperty(iProp, + aRuleData); + if (physicalProp != iProp) { // We can't cache anything on the rule tree if we use any data from // the style context, since data cached in the rule tree could be // used with a style context with a different value. uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits(); aRuleData->mConditions.SetWritingModeDependency(wm); } - nsCSSValue* target = aRuleData->ValueFor(iProp); + nsCSSValue* target = aRuleData->ValueFor(physicalProp); if (target->GetUnit() == eCSSUnit_Null) { const nsCSSValue *val = ValueAtIndex(i); // In order for variable resolution to have the right information @@ -271,7 +347,8 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const if (val->GetUnit() == eCSSUnit_TokenStream) { val->GetTokenStreamValue()->mLevel = aRuleData->mLevel; } - MapSinglePropertyInto(iProp, val, target, aRuleData); + MapSinglePropertyInto(iProp, val, physicalProp, target, + aRuleData); } } } @@ -713,9 +790,8 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID, const nsCSSValue* src = PropertyAt(aPropID); MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null); - nsCSSProperty physicalProp = aPropID; - if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) { - EnsurePhysicalProperty(physicalProp, aRuleData); + nsCSSProperty physicalProp = EnsurePhysicalProperty(aPropID, aRuleData); + if (physicalProp != aPropID) { uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits(); aRuleData->mConditions.SetWritingModeDependency(wm); } @@ -725,7 +801,7 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID, dest->GetTokenStreamValue()->mPropertyID == aPropID); CSSVariableImageTable::ReplaceAll(aRuleData->mStyleContext, aPropID, [=] { - MapSinglePropertyInto(physicalProp, src, dest, aRuleData); + MapSinglePropertyInto(aPropID, src, physicalProp, dest, aRuleData); }); } diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 6c3c3fe45043..11bc0a37b89f 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1644,6 +1644,22 @@ CSS_PROP_POSITION( kFlexDirectionKTable, offsetof(nsStylePosition, mFlexDirection), eStyleAnimType_EnumU8) +/* We treat -webkit-box-orient as a writing-mode-aware logical alias + * for "flex-direction": */ +CSS_PROP_LOGICAL( + -webkit-box-orient, + webkit_box_orient, + WebkitBoxOrient, + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_LOGICAL | + CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING, + "layout.css.prefixes.webkit", + VARIANT_HK, + kBoxOrientKTable, + WebkitBoxOrient, + Position, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) CSS_PROP_SHORTHAND( flex-flow, flex_flow, diff --git a/layout/style/nsCSSPropLogicalGroupList.h b/layout/style/nsCSSPropLogicalGroupList.h index 3d8a52bc90a9..05371d944213 100644 --- a/layout/style/nsCSSPropLogicalGroupList.h +++ b/layout/style/nsCSSPropLogicalGroupList.h @@ -44,6 +44,17 @@ // defined in nCSSProps.cpp named gLogicalGroupTable // containing the two physical properties in vertical/horizontal // order, followed by an nsCSSProperty_UNKNOWN entry. +// +// CSS_PROP_LOGICAL_GROUP_SINGLE(name_) +// Defines a logical property group in which the logical property always +// maps to the same physical property. For such properties, the +// "logicalness" is in the value-mapping, not in the property-mapping. For +// example, the logical property "-webkit-box-orient" is always mapped to +// "flex-direction", but its values ("horizontal", "vertical") map to +// different flex-direction values ("row", "column") depending on the +// writing-mode. A table must be defined in nsCSSProps.cpp named +// gLogicalGroupTable containing the one physical property, +// followed by an nsCSSProperty_UNKNOWN entry. CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderColor) CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderStyle) @@ -54,3 +65,4 @@ CSS_PROP_LOGICAL_GROUP_BOX(Offset) CSS_PROP_LOGICAL_GROUP_SHORTHAND(Padding) CSS_PROP_LOGICAL_GROUP_AXIS(MinSize) CSS_PROP_LOGICAL_GROUP_AXIS(Size) +CSS_PROP_LOGICAL_GROUP_SINGLE(WebkitBoxOrient) diff --git a/layout/style/nsCSSProperty.h b/layout/style/nsCSSProperty.h index 0e0536da785e..aef29c96ee35 100644 --- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -103,10 +103,13 @@ enum nsCSSPropertyLogicalGroup { eCSSPropertyLogicalGroup_##name_, #define CSS_PROP_LOGICAL_GROUP_BOX(name_) \ eCSSPropertyLogicalGroup_##name_, +#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) \ + eCSSPropertyLogicalGroup_##name_, #define CSS_PROP_LOGICAL_GROUP_SHORTHAND(name_) \ eCSSPropertyLogicalGroup_##name_, #include "nsCSSPropLogicalGroupList.h" #undef CSS_PROP_LOGICAL_GROUP_SHORTHAND +#undef CSS_PROP_LOGICAL_GROUP_SINGLE #undef CSS_PROP_LOGICAL_GROUP_BOX #undef CSS_PROP_LOGICAL_GROUP_AXIS eCSSPropertyLogicalGroup_COUNT diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index a0e10fe860c3..ee34db58f64c 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -2865,12 +2865,19 @@ static const nsCSSProperty gSizeLogicalGroupTable[] = { eCSSProperty_UNKNOWN }; +static const nsCSSProperty gWebkitBoxOrientLogicalGroupTable[] = { + eCSSProperty_flex_direction, + eCSSProperty_UNKNOWN +}; + const nsCSSProperty* const nsCSSProps::kLogicalGroupTable[eCSSPropertyLogicalGroup_COUNT] = { #define CSS_PROP_LOGICAL_GROUP_SHORTHAND(id_) g##id_##SubpropTable, #define CSS_PROP_LOGICAL_GROUP_AXIS(name_) g##name_##LogicalGroupTable, #define CSS_PROP_LOGICAL_GROUP_BOX(name_) g##name_##LogicalGroupTable, +#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) g##name_##LogicalGroupTable, #include "nsCSSPropLogicalGroupList.h" +#undef CSS_PROP_LOGICAL_GROUP_SINGLE #undef CSS_PROP_LOGICAL_GROUP_BOX #undef CSS_PROP_LOGICAL_GROUP_AXIS #undef CSS_PROP_LOGICAL_GROUP_SHORTHAND @@ -3171,7 +3178,10 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = { "the CSS_PROPERTY_LOGICAL_BLOCK_AXIS flag"); \ static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE), \ "only properties defined with CSS_PROP_LOGICAL can use " \ - "the CSS_PROPERTY_LOGICAL_END_EDGE flag"); + "the CSS_PROPERTY_LOGICAL_END_EDGE flag"); \ + static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING),\ + "only properties defined with CSS_PROP_LOGICAL can use " \ + "the CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag"); #define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \ kwtable_, group_, stylestruct_, \ stylestructoffset_, animtype_) \ @@ -3184,7 +3194,21 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = { static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \ ((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE)), \ "CSS_PROPERTY_LOGICAL_END_EDGE makes no sense when used " \ - "with CSS_PROPERTY_LOGICAL_AXIS"); + "with CSS_PROPERTY_LOGICAL_AXIS"); \ + /* Make sure CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING isn't used */ \ + /* with other mutually-exclusive flags: */ \ + static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \ + ((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\ + "CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \ + "sense when used with CSS_PROPERTY_LOGICAL_AXIS"); \ + static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_BLOCK_AXIS) && \ + ((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\ + "CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \ + "sense when used with CSS_PROPERTY_LOGICAL_BLOCK_AXIS"); \ + static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE) && \ + ((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\ + "CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \ + "sense when used with CSS_PROPERTY_LOGICAL_END_EDGE"); #include "nsCSSPropList.h" #undef CSS_PROP_LOGICAL #undef CSS_PROP diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 45be06c891cc..398cebbc0615 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -247,20 +247,26 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK & // margin-block-start or margin-inline-start). #define CSS_PROPERTY_LOGICAL_END_EDGE (1<<26) +// This property is a logical property which always maps to the same physical +// property, and its values have some custom processing when being mapped to +// the physical property's values. Must not be used in conjunction with +// CSS_PROPERTY_LOGICAL_{AXIS,BLOCK_AXIS,END_EDGE}. +#define CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING (1<<27) + // This property can be animated on the compositor. -#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<27) +#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<28) // This property is an internal property that is not represented // in the DOM. Properties with this flag must be defined in an #ifndef // CSS_PROP_LIST_EXCLUDE_INTERNAL section of nsCSSPropList.h. -#define CSS_PROPERTY_INTERNAL (1<<28) +#define CSS_PROPERTY_INTERNAL (1<<29) // This property has values that can establish a containing block for // fixed positioned and absolutely positioned elements. // This should be set for any properties that can cause an element to be // such a containing block, as implemented in // nsStyleDisplay::IsFixedPosContainingBlock. -#define CSS_PROPERTY_FIXPOS_CB (1<<29) +#define CSS_PROPERTY_FIXPOS_CB (1<<30) // This property has values that can establish a containing block for // absolutely positioned elements. @@ -269,7 +275,10 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK & // nsStyleDisplay::IsAbsPosContainingBlock. // It does not need to be set for properties that also have // CSS_PROPERTY_FIXPOS_CB set. -#define CSS_PROPERTY_ABSPOS_CB (1<<30) +#define CSS_PROPERTY_ABSPOS_CB (1u<<31) + +// NOTE: Before adding any new CSS_PROPERTY_* flags here, we'll need to +// upgrade kFlagsTable to 64-bits -- see bug 1231384. /** * Types of animatable values. @@ -543,8 +552,11 @@ public: * by the sentinel. * * When called with a property that has the CSS_PROPERTY_LOGICAL_AXIS - * flag, the returned array will have two values preceding the sentinel; - * otherwise it will have four. + * flag, the returned array will have two values preceding the sentinel. + * When called with a property that has the + * CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag, the returned array + * will have one value preceding the sentinel. + * Otherwise it will have four values preceding the sentinel. * * (Note that the running time of this function is proportional to the * number of logical longhand properties that exist. If we start diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index 5ab3d717e389..b92e590950f5 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -291,4 +291,5 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support) [test_visited_reftests.html] skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support) +[test_webkit_box_orient.html] [test_webkit_device_pixel_ratio.html] diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index c86c221e8ca5..0dc2c85a85aa 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4849,6 +4849,25 @@ function logical_box_prop_get_computed(cs, property) return cs.getPropertyValue(property); } +// Helper to get computed style of "-webkit-box-orient" from "flex-direction" +// and the "writing-mode". +function webkit_orient_get_computed(cs, property) +{ + var writingMode = cs.getPropertyValue("writing-mode") || "horizontal-tb"; + + var mapping; // map from flex-direction values to -webkit-box-orient values. + if (writingMode == "horizontal-tb") { + // Horizontal writing-mode + mapping = { "row" : "horizontal", "column" : "vertical"}; + } else { + // Vertical writing-mode + mapping = { "row" : "vertical", "column" : "horizontal"}; + } + + var flexDirection = cs.getPropertyValue("flex-direction"); + return mapping[flexDirection]; +} + // Get the computed value for a property. For shorthands, return the // computed values of all the subproperties, delimited by " ; ". function get_computed_value(cs, property) @@ -6947,6 +6966,21 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) { alias_for: "order", subproperties: [ "order" ], }; + /* This one is not an alias - it's implemented as a logical property: */ + gCSSProperties["-webkit-box-orient"] = { + domProp: "webkitBoxOrient", + inherited: false, + type: CSS_TYPE_LONGHAND, + logical: true, + get_computed: webkit_orient_get_computed, + initial_values: [ "horizontal" ], + other_values: [ "vertical" ], + invalid_values: [ + "0", "0px", "auto", + /* Flex-direction values: */ + "row", "column", "row-reverse", "column-reverse", + ], + }; gCSSProperties["-webkit-box-align"] = { domProp: "webkitBoxAlign", inherited: false, diff --git a/layout/style/test/test_webkit_box_orient.html b/layout/style/test/test_webkit_box_orient.html new file mode 100644 index 000000000000..63eadf551b02 --- /dev/null +++ b/layout/style/test/test_webkit_box_orient.html @@ -0,0 +1,54 @@ + + + + Test the writing-mode-dependent mapping of '-webkit-box-orient' values to + 'flex-direction' values, when emulating -webkit-box styles with modern flexbox + + + + + + diff --git a/layout/style/ua.css b/layout/style/ua.css index d91a1e1167df..87c227ef37e3 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -43,10 +43,10 @@ justify-self: inherit; order: inherit; /* needed for "order" to work on table flex/grid items */ /* Bug 722777 */ - -moz-transform: inherit; - -moz-transform-origin: inherit; + transform: inherit; + transform-origin: inherit; /* Bug 724750 */ - -moz-backface-visibility: inherit; + backface-visibility: inherit; clip: inherit; } @@ -282,7 +282,6 @@ left: 0 !important; right: 0 !important; bottom: 0 !important; - z-index: 2147483647 !important; background: black; width: 100% !important; height: 100% !important; @@ -292,6 +291,8 @@ min-height: 0 !important; max-height: none !important; box-sizing: border-box !important; + object-fit: contain !important; + transform: none !important; } /* Selectors here should match the check in diff --git a/media/libsoundtouch/src/moz.build b/media/libsoundtouch/src/moz.build index 2ecf1ef487a5..900658e31113 100644 --- a/media/libsoundtouch/src/moz.build +++ b/media/libsoundtouch/src/moz.build @@ -37,7 +37,7 @@ if CONFIG['INTEL_ARCHITECTURE']: if CONFIG['OS_ARCH'] != 'WINNT': # GCC/Clang require permissions to be explicitly set for the soundtouch # header. - CXXFLAGS += ['-include', 'soundtouch_perms.h'] + CXXFLAGS += ['-include', SRCDIR + '/soundtouch_perms.h'] else: # Windows need alloca renamed to _alloca DEFINES['alloca'] = '_alloca' diff --git a/media/libvpx/clang-cl.patch b/media/libvpx/clang-cl.patch new file mode 100644 index 000000000000..2ca9be88379d --- /dev/null +++ b/media/libvpx/clang-cl.patch @@ -0,0 +1,98 @@ +Bug 1233983 - Make libvpx build with clang-cl + +diff --git a/media/libvpx/vp8/common/generic/systemdependent.c b/media/libvpx/vp8/common/generic/systemdependent.c +index 4393ced..8ee7e02 100644 +--- a/media/libvpx/vp8/common/generic/systemdependent.c ++++ b/media/libvpx/vp8/common/generic/systemdependent.c +@@ -24,6 +24,7 @@ + #include + #elif defined(_WIN32) + #include ++#include + typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); + #elif defined(__OS2__) + #define INCL_DOS +diff --git a/media/libvpx/vp8/common/rtcd.c b/media/libvpx/vp8/common/rtcd.c +index ab0e9b4..98c2ecd 100644 +--- a/media/libvpx/vp8/common/rtcd.c ++++ b/media/libvpx/vp8/common/rtcd.c +@@ -11,6 +11,9 @@ + #define RTCD_C + #include "./vp8_rtcd.h" + #include "vpx_ports/vpx_once.h" ++#ifdef _MSC_VER ++#include ++#endif + + + void vp8_rtcd() +diff --git a/media/libvpx/vp8/decoder/threading.c b/media/libvpx/vp8/decoder/threading.c +index 6801532..a76672f 100644 +--- a/media/libvpx/vp8/decoder/threading.c ++++ b/media/libvpx/vp8/decoder/threading.c +@@ -28,6 +28,9 @@ + #if CONFIG_ERROR_CONCEALMENT + #include "error_concealment.h" + #endif ++#ifdef _MSC_VER ++#include ++#endif + + #define CALLOC_ARRAY(p, n) CHECK_MEM_ERROR((p), vpx_calloc(sizeof(*(p)), (n))) + #define CALLOC_ARRAY_ALIGNED(p, n, algn) do { \ +diff --git a/media/libvpx/vp8/encoder/encodeframe.c b/media/libvpx/vp8/encoder/encodeframe.c +index d381d8d..5e84fb4 100644 +--- a/media/libvpx/vp8/encoder/encodeframe.c ++++ b/media/libvpx/vp8/encoder/encodeframe.c +@@ -34,6 +34,9 @@ + #include "bitstream.h" + #endif + #include "encodeframe.h" ++#ifdef _MSC_VER ++#include ++#endif + + extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) ; + extern void vp8_calc_ref_frame_costs(int *ref_frame_cost, +diff --git a/media/libvpx/vp8/encoder/ethreading.c b/media/libvpx/vp8/encoder/ethreading.c +index 4e234cc..519ae73b 100644 +--- a/media/libvpx/vp8/encoder/ethreading.c ++++ b/media/libvpx/vp8/encoder/ethreading.c +@@ -14,6 +14,9 @@ + #include "vp8/common/extend.h" + #include "bitstream.h" + #include "encodeframe.h" ++#ifdef _MSC_VER ++#include ++#endif + + #if CONFIG_MULTITHREAD + +diff --git a/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c b/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c +index 5fe27b6..d247603 100644 +--- a/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c ++++ b/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c +@@ -11,6 +11,9 @@ + #define RTCD_C + #include "./vpx_dsp_rtcd.h" + #include "vpx_ports/vpx_once.h" ++#ifdef _MSC_VER ++#include ++#endif + + void vpx_dsp_rtcd() { + once(setup_rtcd_internal); +diff --git a/media/libvpx/vpx_scale/vpx_scale_rtcd.c b/media/libvpx/vpx_scale/vpx_scale_rtcd.c +index bea603f..65532ba 100644 +--- a/media/libvpx/vpx_scale/vpx_scale_rtcd.c ++++ b/media/libvpx/vpx_scale/vpx_scale_rtcd.c +@@ -11,6 +11,9 @@ + #define RTCD_C + #include "./vpx_scale_rtcd.h" + #include "vpx_ports/vpx_once.h" ++#ifdef _MSC_VER ++#include ++#endif + + void vpx_scale_rtcd() + { diff --git a/media/libvpx/update.py b/media/libvpx/update.py index 9785f3d8849c..2bf8a27a58cf 100755 --- a/media/libvpx/update.py +++ b/media/libvpx/update.py @@ -598,6 +598,8 @@ def apply_patches(): os.system("patch -p3 < clamp_abs_lvl_seg.patch") # Bug 1224361 - Clamp QIndex also in abs-value mode. os.system("patch -p3 < clamp-abs-QIndex.patch") + # Bug 1233983 - Make libvpx build with clang-cl + os.system("patch -p3 < clang-cl.patch") def update_readme(commit): with open('README_MOZILLA') as f: diff --git a/media/libvpx/vp8/common/generic/systemdependent.c b/media/libvpx/vp8/common/generic/systemdependent.c index 4393ced48c80..8ee7e0230569 100644 --- a/media/libvpx/vp8/common/generic/systemdependent.c +++ b/media/libvpx/vp8/common/generic/systemdependent.c @@ -24,6 +24,7 @@ #include #elif defined(_WIN32) #include +#include typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); #elif defined(__OS2__) #define INCL_DOS diff --git a/media/libvpx/vp8/common/rtcd.c b/media/libvpx/vp8/common/rtcd.c index ab0e9b47fe8d..98c2ecd74755 100644 --- a/media/libvpx/vp8/common/rtcd.c +++ b/media/libvpx/vp8/common/rtcd.c @@ -11,6 +11,9 @@ #define RTCD_C #include "./vp8_rtcd.h" #include "vpx_ports/vpx_once.h" +#ifdef _MSC_VER +#include +#endif void vp8_rtcd() diff --git a/media/libvpx/vp8/decoder/threading.c b/media/libvpx/vp8/decoder/threading.c index 6801532f1187..a76672fa8141 100644 --- a/media/libvpx/vp8/decoder/threading.c +++ b/media/libvpx/vp8/decoder/threading.c @@ -28,6 +28,9 @@ #if CONFIG_ERROR_CONCEALMENT #include "error_concealment.h" #endif +#ifdef _MSC_VER +#include +#endif #define CALLOC_ARRAY(p, n) CHECK_MEM_ERROR((p), vpx_calloc(sizeof(*(p)), (n))) #define CALLOC_ARRAY_ALIGNED(p, n, algn) do { \ diff --git a/media/libvpx/vp8/encoder/encodeframe.c b/media/libvpx/vp8/encoder/encodeframe.c index d381d8ddf452..5e84fb4919e8 100644 --- a/media/libvpx/vp8/encoder/encodeframe.c +++ b/media/libvpx/vp8/encoder/encodeframe.c @@ -34,6 +34,9 @@ #include "bitstream.h" #endif #include "encodeframe.h" +#ifdef _MSC_VER +#include +#endif extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) ; extern void vp8_calc_ref_frame_costs(int *ref_frame_cost, diff --git a/media/libvpx/vp8/encoder/ethreading.c b/media/libvpx/vp8/encoder/ethreading.c index 4e234ccd58bf..519ae73b480d 100644 --- a/media/libvpx/vp8/encoder/ethreading.c +++ b/media/libvpx/vp8/encoder/ethreading.c @@ -14,6 +14,9 @@ #include "vp8/common/extend.h" #include "bitstream.h" #include "encodeframe.h" +#ifdef _MSC_VER +#include +#endif #if CONFIG_MULTITHREAD diff --git a/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c b/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c index 5fe27b614bdc..d2476039deee 100644 --- a/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c +++ b/media/libvpx/vpx_dsp/vpx_dsp_rtcd.c @@ -11,6 +11,9 @@ #define RTCD_C #include "./vpx_dsp_rtcd.h" #include "vpx_ports/vpx_once.h" +#ifdef _MSC_VER +#include +#endif void vpx_dsp_rtcd() { once(setup_rtcd_internal); diff --git a/media/libvpx/vpx_scale/vpx_scale_rtcd.c b/media/libvpx/vpx_scale/vpx_scale_rtcd.c index bea603fd1046..65532ba94b64 100644 --- a/media/libvpx/vpx_scale/vpx_scale_rtcd.c +++ b/media/libvpx/vpx_scale/vpx_scale_rtcd.c @@ -11,6 +11,9 @@ #define RTCD_C #include "./vpx_scale_rtcd.h" #include "vpx_ports/vpx_once.h" +#ifdef _MSC_VER +#include +#endif void vpx_scale_rtcd() { diff --git a/media/webrtc/signaling/src/jsep/JsepSession.h b/media/webrtc/signaling/src/jsep/JsepSession.h index 9cf59d125082..26fa7192a964 100644 --- a/media/webrtc/signaling/src/jsep/JsepSession.h +++ b/media/webrtc/signaling/src/jsep/JsepSession.h @@ -110,6 +110,15 @@ public: const std::string& oldTrackId, const std::string& newStreamId, const std::string& newTrackId) = 0; + virtual nsresult SetParameters( + const std::string& streamId, + const std::string& trackId, + const std::vector& constraints) = 0; + + virtual nsresult GetParameters( + const std::string& streamId, + const std::string& trackId, + std::vector* outConstraints) = 0; virtual std::vector> GetLocalTracks() const = 0; diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp index 59cc8b98e6df..3b07a685a6e8 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -264,6 +264,37 @@ JsepSessionImpl::ReplaceTrack(const std::string& oldStreamId, return NS_OK; } +nsresult +JsepSessionImpl::SetParameters(const std::string& streamId, + const std::string& trackId, + const std::vector& constraints) +{ + auto it = FindTrackByIds(mLocalTracks, streamId, trackId); + + if (it == mLocalTracks.end()) { + JSEP_SET_ERROR("Track " << streamId << "/" << trackId << " was never added."); + return NS_ERROR_INVALID_ARG; + } + it->mTrack->SetJsConstraints(constraints); + return NS_OK; +} + +nsresult +JsepSessionImpl::GetParameters(const std::string& streamId, + const std::string& trackId, + std::vector* outConstraints) +{ + auto it = FindTrackByIds(mLocalTracks, streamId, trackId); + + if (it == mLocalTracks.end()) { + JSEP_SET_ERROR("Track " << streamId << "/" << trackId << " was never added."); + return NS_ERROR_INVALID_ARG; + } + + it->mTrack->GetJsConstraints(outConstraints); + return NS_OK; +} + std::vector> JsepSessionImpl::GetLocalTracks() const { diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h index bcf13abdae5e..121ef296c369 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h @@ -87,6 +87,16 @@ public: const std::string& newStreamId, const std::string& newTrackId) override; + virtual nsresult SetParameters( + const std::string& streamId, + const std::string& trackId, + const std::vector& constraints) override; + + virtual nsresult GetParameters( + const std::string& streamId, + const std::string& trackId, + std::vector* outConstraints) override; + virtual std::vector> GetLocalTracks() const override; virtual std::vector> GetRemoteTracks() const override; diff --git a/media/webrtc/signaling/src/jsep/JsepTrack.h b/media/webrtc/signaling/src/jsep/JsepTrack.h index f08db5435c54..519acf2cbcb5 100644 --- a/media/webrtc/signaling/src/jsep/JsepTrack.h +++ b/media/webrtc/signaling/src/jsep/JsepTrack.h @@ -185,6 +185,12 @@ public: mJsEncodeConstraints = constraintsList; } + void GetJsConstraints(std::vector* outConstraintsList) const + { + MOZ_ASSERT(outConstraintsList); + *outConstraintsList = mJsEncodeConstraints; + } + static void AddToMsection(const std::vector& constraintsList, sdp::Direction direction, SdpMediaSection* msection); diff --git a/media/webrtc/signaling/src/media-conduit/CodecConfig.h b/media/webrtc/signaling/src/media-conduit/CodecConfig.h index 74d68879b51b..b8e8275f1e55 100755 --- a/media/webrtc/signaling/src/media-conduit/CodecConfig.h +++ b/media/webrtc/signaling/src/media-conduit/CodecConfig.h @@ -79,6 +79,11 @@ public: std::vector mCcmFbTypes; EncodingConstraints mEncodingConstraints; + struct SimulcastEncoding { + std::string rid; + EncodingConstraints constraints; + }; + std::vector mSimulcastEncodings; std::string mSpropParameterSets; uint8_t mProfile; uint8_t mConstraints; diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index e2c9fc9e78eb..d7b2d695397f 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -958,6 +958,30 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs( return kMediaConduitNoError; } +struct ResolutionAndBitrateLimits { + uint32_t resolution_in_mb; + uint16_t min_bitrate; + uint16_t max_bitrate; +}; + +#define MB_OF(w,h) ((unsigned int)((((w)>>4))*((unsigned int)((h)>>4)))) + +// For now, try to set the max rates well above the knee in the curve. +// Chosen somewhat arbitrarily; it's hard to find good data oriented for +// realtime interactive/talking-head recording. These rates assume +// 30fps. + +// XXX Populate this based on a pref (which we should consider sorting because +// people won't assume they need to). +static ResolutionAndBitrateLimits kResolutionAndBitrateLimits[] = { + {MB_OF(1920, 1200), 1500, 10000}, // >HD (3K, 4K, etc) + {MB_OF(1280, 720), 1200, 5000}, // HD ~1080-1200 + {MB_OF(800, 480), 600, 2500}, // HD ~720 + {std::max(MB_OF(400, 240), MB_OF(352, 288)), 200, 1300}, // VGA, WVGA + {MB_OF(176, 144), 100, 500}, // WQVGA, CIF + {0 , 40, 250} // QCIF and below +}; + static void SelectBandwidth(webrtc::VideoCodec& vie_codec, unsigned short width, @@ -972,42 +996,12 @@ SelectBandwidth(webrtc::VideoCodec& vie_codec, mb_height = (height + 15) >> 4; fs = mb_width * mb_height; - // For now, try to set the max rates well above the knee in the curve. - // Chosen somewhat arbitrarily; it's hard to find good data oriented for - // realtime interactive/talking-head recording. These rates assume - // 30fps. -#define MB_OF(w,h) ((unsigned int)((((w)>>4))*((unsigned int)((h)>>4)))) - - // XXX replace this with parsing a config var with roughly a format - // of "max_fs,min_bw,max_bw," repeated to populate a table (which we - // should consider sorting because people won't assume they need to). - // Then iterate through the sorted array comparing fs. - if (fs > MB_OF(1920, 1200)) { - // >HD (3K, 4K, etc) - vie_codec.minBitrate = 1500; - vie_codec.maxBitrate = 10000; - } else if (fs > MB_OF(1280, 720)) { - // HD ~1080-1200 - vie_codec.minBitrate = 1200; - vie_codec.maxBitrate = 5000; - } else if (fs > MB_OF(800, 480)) { - // HD ~720 - vie_codec.minBitrate = 600; - vie_codec.maxBitrate = 2500; - } else if (fs > std::max(MB_OF(400, 240), MB_OF(352, 288))) { - // WVGA - // VGA - vie_codec.minBitrate = 200; - vie_codec.maxBitrate = 1300; - } else if (fs > MB_OF(176, 144)) { - // WQVGA - // CIF - vie_codec.minBitrate = 100; - vie_codec.maxBitrate = 500; - } else { - // QCIF and below - vie_codec.minBitrate = 40; - vie_codec.maxBitrate = 250; + for (ResolutionAndBitrateLimits resAndLimits : kResolutionAndBitrateLimits) { + if (fs > resAndLimits.resolution_in_mb) { + vie_codec.minBitrate = resAndLimits.min_bitrate; + vie_codec.maxBitrate = resAndLimits.max_bitrate; + break; + } } // mLastFramerateTenths is an atomic, and scaled by *10 @@ -1029,6 +1023,31 @@ SelectBandwidth(webrtc::VideoCodec& vie_codec, vie_codec.minBitrate); } +static void ConstrainPreservingAspectRatioExact(uint32_t max_fs, + unsigned short* width, + unsigned short* height) +{ + unsigned int mb_width = (*width + 15) >> 4; + unsigned int mb_height = (*height + 15) >> 4; + + // We could try to pick a better starting divisor, but it won't make any real + // performance difference. + for (size_t d = 1; d < std::min(mb_width, mb_height); ++d) { + if ((mb_width % d) || (mb_height % d)) { + continue; // Not divisible + } + + if ((mb_width*mb_height)/(d*d) <= max_fs) { + *width = 16 * mb_width / d; + *height = 16 * mb_height / d; + return; + } + } + + *width = 0; + *height = 0; +} + static void ConstrainPreservingAspectRatio(uint16_t max_width, uint16_t max_height, unsigned short* width, @@ -1211,6 +1230,47 @@ WebrtcVideoConduit::ReconfigureSendCodec(unsigned short width, vie_codec.maxFramerate = mSendingFramerate; SelectBandwidth(vie_codec, width, height, mLastFramerateTenths); + // TODO: If/when we begin supporting width/height constraints on simulcast + // streams, for each such constraint we will need to choose a resolution + // that is the same aspect ratio as all other streams. This requires us to + // store the original constraints somewhere. + for (size_t i = vie_codec.numberOfSimulcastStreams; i > 0; --i) { + webrtc::SimulcastStream& stream(vie_codec.simulcastStream[i - 1]); + if (stream.maxBitrate && (stream.maxBitrate < vie_codec.minBitrate)) { + // This stream cannot do full resolution with good quality. Need to + // scale down. + stream.width = 0; + stream.height = 0; + uint32_t max_fs_in_mb = kResolutionAndBitrateLimits[0].resolution_in_mb; + for (ResolutionAndBitrateLimits resAndLimits : + kResolutionAndBitrateLimits) { + if (resAndLimits.min_bitrate < stream.maxBitrate) { + // Use the resolution from the _previous_ entry + unsigned short adjusted_width = width; + unsigned short adjusted_height = height; + // webrtc.org won't tolerate simulcast unless every stream is + // exactly the same aspect ratio + ConstrainPreservingAspectRatioExact(max_fs_in_mb, + &adjusted_width, + &adjusted_height); + stream.width = adjusted_width; + stream.height = adjusted_height; + break; + } + max_fs_in_mb = resAndLimits.resolution_in_mb; + } + } else { + stream.width = width; + stream.height = height; + } + // webrtc.org also gets upset if the last simulcast stream has a + // different resolution than the vie_codec + if (i == vie_codec.numberOfSimulcastStreams) { + vie_codec.width = stream.width; + vie_codec.height = stream.height; + } + } + if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0) { CSFLogError(logTag, "%s: SetSendCodec(%ux%u) failed, err %d", @@ -1660,6 +1720,18 @@ WebrtcVideoConduit::DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) return -1; } +template +T MinIgnoreZero(const T& a, const T& b) +{ + if (!a) { + return b; + } else if (!b) { + return a; + } else { + return std::min(a, b); + } +} + /** * Copy the codec passed into Conduit's database */ @@ -1712,8 +1784,10 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo, cinst.codecSpecific.H264.level = codecInfo->mLevel; cinst.codecSpecific.H264.packetizationMode = codecInfo->mPacketizationMode; if (codecInfo->mEncodingConstraints.maxBr > 0) { - cinst.maxBitrate = std::min(cinst.maxBitrate, - codecInfo->mEncodingConstraints.maxBr); + // webrtc.org uses kbps, we use bps + cinst.maxBitrate = + MinIgnoreZero(cinst.maxBitrate, + codecInfo->mEncodingConstraints.maxBr)/1000; } if (codecInfo->mEncodingConstraints.maxMbps > 0) { // Not supported yet! @@ -1725,6 +1799,46 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo, cinst.codecSpecific.H264.spsLen = 0; cinst.codecSpecific.H264.ppsData = nullptr; cinst.codecSpecific.H264.ppsLen = 0; + } else { + // TODO(bug 1210175): H264 doesn't support simulcast yet. + for (size_t i = 0; i < codecInfo->mSimulcastEncodings.size(); ++i) { + const VideoCodecConfig::SimulcastEncoding& encoding = + codecInfo->mSimulcastEncodings[i]; + // Make sure the constraints on the whole stream are reflected. + webrtc::SimulcastStream stream; + memset(&stream, 0, sizeof(stream)); + stream.width = cinst.width; + stream.height = cinst.height; + stream.numberOfTemporalLayers = 1; + stream.maxBitrate = cinst.maxBitrate; + stream.targetBitrate = cinst.targetBitrate; + stream.minBitrate = cinst.minBitrate; + stream.qpMax = cinst.qpMax; + strncpy(stream.rid, encoding.rid.c_str(), sizeof(stream.rid)-1); + stream.rid[sizeof(stream.rid) - 1] = 0; + + // Apply encoding-specific constraints. + stream.width = MinIgnoreZero( + stream.width, + (unsigned short)encoding.constraints.maxWidth); + stream.height = MinIgnoreZero( + stream.height, + (unsigned short)encoding.constraints.maxHeight); + + if (encoding.constraints.maxBr) { + // webrtc.org uses kbps, we use bps + stream.maxBitrate = encoding.constraints.maxBr/1000; + stream.minBitrate = MinIgnoreZero(stream.minBitrate, stream.maxBitrate); + stream.targetBitrate = MinIgnoreZero(stream.targetBitrate, + stream.maxBitrate); + } + + // webrtc.org expects simulcast streams to be ordered by increasing + // fidelity, our jsep code does the opposite. + cinst.simulcastStream[codecInfo->mSimulcastEncodings.size()-i-1] = stream; + } + + cinst.numberOfSimulcastStreams = codecInfo->mSimulcastEncodings.size(); } } diff --git a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp index ad309cb41230..f10ffdeb4595 100644 --- a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp +++ b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp @@ -162,8 +162,12 @@ NegotiatedDetailsToVideoCodecConfigs(const JsepTrackNegotiatedDetails& aDetails, } for (size_t i = 0; i < aDetails.GetEncodingCount(); ++i) { - if (aDetails.GetEncoding(i).HasFormat(codec->mDefaultPt)) { - // TODO(bug 1192390): Roll constraints into simulcast entries + const JsepTrackEncoding& jsepEncoding(aDetails.GetEncoding(i)); + if (jsepEncoding.HasFormat(codec->mDefaultPt)) { + VideoCodecConfig::SimulcastEncoding encoding; + encoding.rid = jsepEncoding.mRid; + encoding.constraints = jsepEncoding.mConstraints; + config->mSimulcastEncodings.push_back(encoding); } } aConfigs->values.push_back(config); diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index a00794acf358..03eba7e6304a 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -77,6 +77,7 @@ #include "mozilla/PeerIdentity.h" #include "mozilla/dom/RTCCertificate.h" #include "mozilla/dom/RTCConfigurationBinding.h" +#include "mozilla/dom/RTCRtpSenderBinding.h" #include "mozilla/dom/RTCStatsReportBinding.h" #include "mozilla/dom/RTCPeerConnectionBinding.h" #include "mozilla/dom/PeerConnectionImplBinding.h" @@ -2319,6 +2320,73 @@ PeerConnectionImpl::ReplaceTrack(MediaStreamTrack& aThisTrack, return NS_OK; } +#if !defined(MOZILLA_EXTERNAL_LINKAGE) +NS_IMETHODIMP +PeerConnectionImpl::SetParameters(MediaStreamTrack& aTrack, + const RTCRtpParameters& aParameters) { + PC_AUTO_ENTER_API_CALL(true); + + std::vector constraints; + if (aParameters.mEncodings.WasPassed()) { + for (auto& encoding : aParameters.mEncodings.Value()) { + JsepTrack::JsConstraints constraint; + if (encoding.mRid.WasPassed()) { + constraint.rid = NS_ConvertUTF16toUTF8(encoding.mRid.Value()).get(); + } + if (encoding.mMaxBitrate.WasPassed()) { + constraint.constraints.maxBr = encoding.mMaxBitrate.Value(); + } + constraints.push_back(constraint); + } + } + return SetParameters(aTrack, constraints); +} +#endif + +nsresult +PeerConnectionImpl::SetParameters( + MediaStreamTrack& aTrack, + const std::vector& aConstraints) +{ + std::string trackId = PeerConnectionImpl::GetTrackId(aTrack); + std::string streamId = PeerConnectionImpl::GetStreamId(*aTrack.GetStream()); + + return mJsepSession->SetParameters(streamId, trackId, aConstraints); +} + +#if !defined(MOZILLA_EXTERNAL_LINKAGE) +NS_IMETHODIMP +PeerConnectionImpl::GetParameters(MediaStreamTrack& aTrack, + RTCRtpParameters& aOutParameters) { + PC_AUTO_ENTER_API_CALL(true); + + std::vector constraints; + nsresult rv = GetParameters(aTrack, &constraints); + if (NS_FAILED(rv)) { + return rv; + } + aOutParameters.mEncodings.Construct(); + for (auto& constraint : constraints) { + RTCRtpEncodingParameters encoding; + encoding.mRid.Construct(NS_ConvertASCIItoUTF16(constraint.rid.c_str())); + encoding.mMaxBitrate.Construct(constraint.constraints.maxBr); + aOutParameters.mEncodings.Value().AppendElement(Move(encoding), fallible); + } + return NS_OK; +} +#endif + +nsresult +PeerConnectionImpl::GetParameters( + MediaStreamTrack& aTrack, + std::vector* aOutConstraints) +{ + std::string trackId = PeerConnectionImpl::GetTrackId(aTrack); + std::string streamId = PeerConnectionImpl::GetStreamId(*aTrack.GetStream()); + + return mJsepSession->GetParameters(streamId, trackId, aOutConstraints); +} + nsresult PeerConnectionImpl::CalculateFingerprint( const std::string& algorithm, diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index 5a704b79f327..4987b3e3047c 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -81,6 +81,7 @@ class RTCCertificate; struct RTCConfiguration; struct RTCIceServer; struct RTCOfferOptions; +struct RTCRtpParameters; #ifdef USE_FAKE_MEDIA_STREAMS typedef Fake_MediaStreamTrack MediaStreamTrack; #else @@ -443,6 +444,30 @@ public: rv = ReplaceTrack(aThisTrack, aWithTrack); } +#if !defined(MOZILLA_EXTERNAL_LINKAGE) + NS_IMETHODIMP_TO_ERRORRESULT(SetParameters, ErrorResult &rv, + dom::MediaStreamTrack& aTrack, + const dom::RTCRtpParameters& aParameters) + { + rv = SetParameters(aTrack, aParameters); + } + + NS_IMETHODIMP_TO_ERRORRESULT(GetParameters, ErrorResult &rv, + dom::MediaStreamTrack& aTrack, + dom::RTCRtpParameters& aOutParameters) + { + rv = GetParameters(aTrack, aOutParameters); + } +#endif + + nsresult + SetParameters(dom::MediaStreamTrack& aTrack, + const std::vector& aConstraints); + + nsresult + GetParameters(dom::MediaStreamTrack& aTrack, + std::vector* aOutConstraints); + nsresult GetPeerIdentity(nsAString& peerIdentity) { #if !defined(MOZILLA_EXTERNAL_LINKAGE) diff --git a/media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.cc b/media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.cc index f5040f9ee0ef..32772539fc65 100644 --- a/media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.cc +++ b/media/webrtc/trunk/webrtc/modules/video_coding/main/source/generic_encoder.cc @@ -85,6 +85,7 @@ int32_t VCMGenericEncoder::Release() rtc::CritScope lock(&rates_lock_); bit_rate_ = 0; frame_rate_ = 0; + encoder_->RegisterEncodeCompleteCallback(nullptr); vcm_encoded_frame_callback_ = nullptr; } diff --git a/memory/replace/logalloc/Makefile.in b/memory/replace/logalloc/Makefile.in deleted file mode 100644 index b0fe8129e475..000000000000 --- a/memory/replace/logalloc/Makefile.in +++ /dev/null @@ -1,6 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Avoid Lock_impl code depending on mozilla::Logger -MOZ_DEBUG_DEFINES= diff --git a/memory/replace/logalloc/moz.build b/memory/replace/logalloc/moz.build index 9deb355131e2..12bf6eb15b5d 100644 --- a/memory/replace/logalloc/moz.build +++ b/memory/replace/logalloc/moz.build @@ -16,6 +16,7 @@ USE_STATIC_LIBS = True DEFINES['MOZ_NO_MOZALLOC'] = True # Avoid Lock_impl code depending on mozilla::Logger. DEFINES['NDEBUG'] = True +DEFINES['DEBUG'] = False # Use locking code from the chromium stack. if CONFIG['OS_TARGET'] == 'WINNT': diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 1b78ec71dded..eecdf9e56756 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -475,7 +475,7 @@ update-generated-wrappers: # does most of the packaging step, and then updates omni.ja in # place. If you're not using an IDE, you should be using |mach build # mobile/android && mach package|. -$(abspath $(DIST)/fennec/$(OMNIJAR_NAME)): FORCE +$(ABS_DIST)/fennec/$(OMNIJAR_NAME): FORCE $(REPORT_BUILD) $(MAKE) -C ../../../faster $(MAKE) -C ../installer stage-package @@ -488,7 +488,7 @@ gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f)) gradle-targets: $(abspath AndroidManifest.xml) gradle-targets: $(ANDROID_GENERATED_RESFILES) -gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME)) +gradle-omnijar: $(ABS_DIST)/fennec/$(OMNIJAR_NAME) .PHONY: gradle-targets gradle-omnijar diff --git a/mobile/android/base/java/org/mozilla/gecko/CrashHandler.java b/mobile/android/base/java/org/mozilla/gecko/CrashHandler.java index 84ff6e833ac0..c1183b6ce471 100644 --- a/mobile/android/base/java/org/mozilla/gecko/CrashHandler.java +++ b/mobile/android/base/java/org/mozilla/gecko/CrashHandler.java @@ -145,7 +145,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { * @param thread The exception thread * @param exc An exception */ - protected void logException(final Thread thread, final Throwable exc) { + public static void logException(final Thread thread, final Throwable exc) { try { Log.e(LOGTAG, ">>> REPORTING UNCAUGHT EXCEPTION FROM THREAD " + thread.getId() + " (\"" + thread.getName() + "\")", exc); diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java index cda80b6f1e3d..0a115d3c1b16 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java @@ -396,8 +396,20 @@ public class GeckoAppShell */ @WrapForJNI(allowMultithread = true, noThrow = true) - public static void handleUncaughtException(Thread thread, Throwable e) { - CRASH_HANDLER.uncaughtException(thread, e); + public static String handleUncaughtException(Throwable e) { + if (AppConstants.MOZ_CRASHREPORTER) { + final Throwable exc = CrashHandler.getRootException(e); + final StackTraceElement[] stack = exc.getStackTrace(); + if (stack.length >= 1 && stack[0].isNativeMethod()) { + // The exception occurred when running native code. Return an exception + // string and trigger the crash reporter inside the caller so that we get + // a better native stack in Socorro. + CrashHandler.logException(Thread.currentThread(), exc); + return CrashHandler.getExceptionStackTrace(exc); + } + } + CRASH_HANDLER.uncaughtException(null, e); + return null; } private static final Object sEventAckLock = new Object(); diff --git a/mobile/android/base/locales/Makefile.in b/mobile/android/base/locales/Makefile.in index 7cb50de7c908..a1352e22c6fb 100644 --- a/mobile/android/base/locales/Makefile.in +++ b/mobile/android/base/locales/Makefile.in @@ -16,9 +16,9 @@ SEARCHSTRINGSPATH = $(abspath $(call MERGE_FILE,search_strings.dtd)) SYNCSTRINGSPATH = $(abspath $(call MERGE_FILE,sync_strings.dtd)) STRINGSPATH = $(abspath $(call MERGE_FILE,android_strings.dtd)) ifeq (,$(XPI_NAME)) -BRANDPATH = $(abspath $(DEPTH)/dist/bin/chrome/$(AB_CD)/locale/branding/brand.dtd) +BRANDPATH = $(topobjdir)/dist/bin/chrome/$(AB_CD)/locale/branding/brand.dtd else -BRANDPATH = $(abspath $(DIST)/xpi-stage/$(XPI_NAME)/chrome/$(AB_CD)/locale/branding/brand.dtd) +BRANDPATH = $(ABS_DIST)/xpi-stage/$(XPI_NAME)/chrome/$(AB_CD)/locale/branding/brand.dtd endif $(warnIfEmpty,AB_CD) # todo: $(errorIfEmpty ) diff --git a/mobile/android/geckoview_library/Makefile.in b/mobile/android/geckoview_library/Makefile.in index b68f1b14b850..60aecae13acb 100644 --- a/mobile/android/geckoview_library/Makefile.in +++ b/mobile/android/geckoview_library/Makefile.in @@ -29,16 +29,14 @@ GARBAGE_DIRS = \ include $(topsrcdir)/config/rules.mk -abs_dist = $(abspath $(DIST)) - -dist_files = $(addprefix $(abs_dist)/bin/, libmozglue.so $(MOZ_CHILD_PROCESS_NAME) $(MOZ_CHILD_PROCESS_NAME_PIE)) +dist_files = $(addprefix $(ABS_DIST)/bin/, libmozglue.so $(MOZ_CHILD_PROCESS_NAME) $(MOZ_CHILD_PROCESS_NAME_PIE)) package: local.properties project.properties AndroidManifest.xml FORCE # Make directory for the zips - $(MKDIR) -p $(abs_dist)/geckoview_library + $(MKDIR) -p $(ABS_DIST)/geckoview_library # Zip the assets into $(DIST)/geckoview_library/geckoview_assets.zip - $(call py_action,zip,-C $(abs_dist)/$(MOZ_APP_NAME) $(abs_dist)/geckoview_library/geckoview_assets.zip assets) + $(call py_action,zip,-C $(ABS_DIST)/$(MOZ_APP_NAME) $(ABS_DIST)/geckoview_library/geckoview_assets.zip assets) # Make empty directories to fit an Android project structure $(MKDIR) -p bin gen libs/$(ANDROID_CPU_ARCH) src @@ -55,8 +53,8 @@ package: local.properties project.properties AndroidManifest.xml FORCE $(RM) -rf res $(MKDIR) -p res cd res && \ - $(UNZIP) -q -u -o $(abs_dist)/bin/geckoview_resources.zip + $(UNZIP) -q -u -o $(ABS_DIST)/bin/geckoview_resources.zip # Zip the directory cd $(DEPTH)/mobile/android && \ - $(ZIP) -q -r $(abs_dist)/geckoview_library/geckoview_library.zip geckoview_library -x geckoview_library/backend.mk geckoview_library/Makefile + $(ZIP) -q -r $(ABS_DIST)/geckoview_library/geckoview_library.zip geckoview_library -x geckoview_library/backend.mk geckoview_library/Makefile diff --git a/mobile/android/locales/generic/install.rdf b/mobile/android/locales/generic/install.rdf deleted file mode 100644 index 50a2475bbca5..000000000000 --- a/mobile/android/locales/generic/install.rdf +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -#ifdef MOZ_LANGPACK_CONTRIBUTORS - @MOZ_LANGPACK_CONTRIBUTORS@ -#endif - - - - {a23983c0-fd0e-11dc-95ff-0800200c9a66} - @MOZ_APP_VERSION@ - @MOZ_APP_MAXVERSION@ - - - - diff --git a/modules/libmar/tests/Makefile.in b/modules/libmar/tests/Makefile.in index 0d11b3b53524..5c614a086750 100644 --- a/modules/libmar/tests/Makefile.in +++ b/modules/libmar/tests/Makefile.in @@ -2,7 +2,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -TESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/$(relativesrcdir) +TESTROOT = $(topobjdir)/_tests/xpcshell/$(relativesrcdir) include $(topsrcdir)/config/rules.mk diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index db452edecb5f..3abea29232a6 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2308,7 +2308,7 @@ pref("layout.css.prefixes.font-features", true); pref("layout.css.prefixes.gradients", true); // Are webkit-prefixed properties & property-values supported? -pref("layout.css.prefixes.webkit", false); +pref("layout.css.prefixes.webkit", true); // Is the CSS Unprefixing Service enabled? (This service emulates support // for certain vendor-prefixed properties & values, for sites on a "fixlist".) diff --git a/netwerk/base/PrivateBrowsingChannel.h b/netwerk/base/PrivateBrowsingChannel.h index 165bea03c462..0fe96bd1a29f 100644 --- a/netwerk/base/PrivateBrowsingChannel.h +++ b/netwerk/base/PrivateBrowsingChannel.h @@ -48,7 +48,7 @@ public: NS_IMETHOD GetIsChannelPrivate(bool *aResult) { NS_ENSURE_ARG_POINTER(aResult); - *aResult = NS_UsePrivateBrowsing(static_cast(this)); + *aResult = mPrivateBrowsing; return NS_OK; } @@ -63,6 +63,21 @@ public: return NS_OK; } + // Must be called every time the channel's callbacks or loadGroup is updated + void UpdatePrivateBrowsing() + { + // once marked as private we never go un-private + if (mPrivateBrowsing) { + return; + } + + nsCOMPtr loadContext; + NS_QueryNotificationCallbacks(static_cast(this), loadContext); + if (loadContext) { + mPrivateBrowsing = loadContext->UsePrivateBrowsing(); + } + } + bool CanSetCallbacks(nsIInterfaceRequestor* aCallbacks) const { // Make sure that the private bit override flag is not set. diff --git a/netwerk/base/nsBaseChannel.cpp b/netwerk/base/nsBaseChannel.cpp index 4bf5dc076ae2..0a6829349b2f 100644 --- a/netwerk/base/nsBaseChannel.cpp +++ b/netwerk/base/nsBaseChannel.cpp @@ -101,7 +101,7 @@ nsBaseChannel::Redirect(nsIChannel *newChannel, uint32_t redirectFlags, newChannel->SetLoadInfo(nullptr); } - // Try to preserve the privacy bit if it has been overridden + // Preserve the privacy bit if it has been overridden if (mPrivateBrowsingOverriden) { nsCOMPtr newPBChannel = do_QueryInterface(newChannel); @@ -424,6 +424,7 @@ nsBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) mLoadGroup = aLoadGroup; CallbacksChanged(); + UpdatePrivateBrowsing(); return NS_OK; } @@ -497,6 +498,7 @@ nsBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) mCallbacks = aCallbacks; CallbacksChanged(); + UpdatePrivateBrowsing(); return NS_OK; } diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index a1a7025b8026..6991af98f89e 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -1220,13 +1220,12 @@ bool NS_UsePrivateBrowsing(nsIChannel *channel) { bool isPrivate = false; - bool isOverriden = false; nsCOMPtr pbChannel = do_QueryInterface(channel); - if (pbChannel && - NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate, &isOverriden)) && - isOverriden) { + if (pbChannel && NS_SUCCEEDED(pbChannel->GetIsChannelPrivate(&isPrivate))) { return isPrivate; } + + // Some channels may not implement nsIPrivateBrowsingChannel nsCOMPtr loadContext; NS_QueryNotificationCallbacks(channel, loadContext); return loadContext && loadContext->UsePrivateBrowsing(); diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 3cbda7ed2748..046a45059fde 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -261,7 +261,7 @@ HttpBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) mLoadGroup = aLoadGroup; mProgressSink = nullptr; - mPrivateBrowsing = NS_UsePrivateBrowsing(this); + UpdatePrivateBrowsing(); return NS_OK; } @@ -419,7 +419,7 @@ HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) mCallbacks = aCallbacks; mProgressSink = nullptr; - mPrivateBrowsing = NS_UsePrivateBrowsing(this); + UpdatePrivateBrowsing(); return NS_OK; } diff --git a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp index c7a55275b429..f4f7c1a266e7 100644 --- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp +++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp @@ -433,6 +433,8 @@ WyciwygChannelChild::SetLoadGroup(nsILoadGroup * aLoadGroup) mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); + + UpdatePrivateBrowsing(); return NS_OK; } @@ -525,6 +527,7 @@ WyciwygChannelChild::SetNotificationCallbacks(nsIInterfaceRequestor * aCallbacks mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); + UpdatePrivateBrowsing(); return NS_OK; } diff --git a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp index 20e69e660d85..dd58105547c7 100644 --- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp +++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp @@ -231,7 +231,7 @@ nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); - mPrivateBrowsing = NS_UsePrivateBrowsing(this); + UpdatePrivateBrowsing(); NS_GetOriginAttributes(this, mOriginAttributes); return NS_OK; @@ -328,7 +328,7 @@ nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationC NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); - mPrivateBrowsing = NS_UsePrivateBrowsing(this); + UpdatePrivateBrowsing(); NS_GetOriginAttributes(this, mOriginAttributes); return NS_OK; diff --git a/python/mozboot/mozboot/base.py b/python/mozboot/mozboot/base.py index a257f099b6d3..ab119356465f 100644 --- a/python/mozboot/mozboot/base.py +++ b/python/mozboot/mozboot/base.py @@ -10,7 +10,6 @@ import subprocess import sys from distutils.version import LooseVersion -from distutils.version import StrictVersion NO_MERCURIAL = ''' @@ -74,7 +73,9 @@ We recommend the following tools for installing Python: # Upgrade Mercurial older than this. -MODERN_MERCURIAL_VERSION = StrictVersion('3.2.4') +# This should match OLDEST_NON_LEGACY_VERSION from +# tools/mercurial/hgsetup/wizard.py. +MODERN_MERCURIAL_VERSION = LooseVersion('3.5.2') # Upgrade Python older than this. MODERN_PYTHON_VERSION = LooseVersion('2.7.3') @@ -292,7 +293,7 @@ class BaseBootstrapper(object): print('ERROR: Unable to identify Mercurial version.') return True, False, None - our = StrictVersion(match.group(1)) + our = LooseVersion(match.group(1)) return True, our >= MODERN_MERCURIAL_VERSION, our diff --git a/python/mozbuild/mozbuild/action/convert_def_file.py b/python/mozbuild/mozbuild/action/convert_def_file.py deleted file mode 100644 index 0b86ea17ed0b..000000000000 --- a/python/mozbuild/mozbuild/action/convert_def_file.py +++ /dev/null @@ -1,112 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Convert Windows-style export files into a single Unix-style linker -# script, applying any necessary preprocessing. - -from __future__ import absolute_import - -import itertools -import re -import sys -from StringIO import StringIO - -from mozbuild.preprocessor import Preprocessor -from mozbuild.util import FileAvoidWrite - -def preprocess_file(pp, deffile): - pp.out = StringIO() - with open(deffile, 'rU') as input: - pp.do_include(input, False) - return pp.out.getvalue().splitlines() - -# NSS .def files serve multiple masters, as this copied comment indicates: -# -# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS -# 1. For all unix platforms, the string ";-" means "remove this line" -# 2. For all unix platforms, the string " DATA " will be removed from any -# line on which it occurs. -# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -# On AIX, lines containing ";+" will be removed. -# 4. For all unix platforms, the string ";;" will have the ";;" removed. -# 5. For all unix platforms, after the above processing has taken place, -# all characters after the first ";" on the line will be removed. -# And for AIX, the first ";" will also be removed. -# This file is passed directly to windows. Since ';' is a comment, all UNIX -# directives are hidden behind ";", ";+", and ";-" -# -# We don't care about rule 1, as that mainly serves to eliminate LIBRARY -# and EXPORTS lines. Our symbol extraction routines handle DATA, so we -# don't need to bother with rule 2. We don't want to enforce rule 3, as -# we know how to eliminate comments. ';+' also tends to hide Unix -# linker-script specific things, which we don't want to deal with here. -# Rule 5 is also unnecessary; later comment-aware processing will deal -# with that. -# -# We need to handle rule 4, since ';;' often hides things marked with DATA. -def nss_preprocess_file(deffile): - with open(deffile, 'r') as input: - for line in input: - yield line.replace(';;', '') - -COMMENT = re.compile(';.*') - -def extract_symbols(lines): - # Filter comments. - nocomments = iter(COMMENT.sub('', s).strip() for s in lines) - lines = iter(s for s in nocomments if len(s)) - - exports = itertools.dropwhile(lambda s: 'EXPORTS' not in s, lines) - symbols = set() - for line in exports: - if 'EXPORTS' in line: - # Handle the case where symbols are specified along with EXPORT. - fields = line.split()[1:] - if len(fields) == 0: - continue - else: - fields = line.split() - - # We don't support aliases, and we only support the DATA keyword on - # symbols. But since aliases can also be specified as 'SYM=ALIAS' - # with no whitespace, we need extra checks on the original symbol. - if '=' in fields[0]: - raise BaseException, 'aliases are not supported (%s)' % line - if len(fields) == 1: - pass - elif len(fields) != 2 or fields[1] != 'DATA': - raise BaseException, 'aliases and keywords other than DATA are not supported (%s)' % line - - symbols.add(fields[0]) - - return symbols - -def main(args): - pp = Preprocessor() - optparser = pp.getCommandLineParser() - optparser.add_option('--nss-file', action='append', - type='string', dest='nss_files', default=[], - help='Specify a .def file that should have NSS\'s processing rules applied to it') - options, deffiles = optparser.parse_args(args) - - symbols = set() - for f in options.nss_files: - symbols |= extract_symbols(nss_preprocess_file(f)) - for f in deffiles: - # Start each deffile off with a clean slate. - defpp = pp.clone() - symbols |= extract_symbols(preprocess_file(defpp, f)) - - script = """{ -global: - %s -local: - *; -}; -""" - with FileAvoidWrite(options.output) as f: - f.write(script % '\n '.join("%s;" % s for s in sorted(symbols))) - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/python/mozbuild/mozbuild/action/generate_symbols_file.py b/python/mozbuild/mozbuild/action/generate_symbols_file.py new file mode 100644 index 000000000000..9f76f9823e3f --- /dev/null +++ b/python/mozbuild/mozbuild/action/generate_symbols_file.py @@ -0,0 +1,79 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from __future__ import absolute_import, print_function, unicode_literals + +import buildconfig +import os +from StringIO import StringIO +from mozbuild.preprocessor import Preprocessor + + +def generate_symbols_file(output, input): + ''' ''' + input = os.path.abspath(input) + + pp = Preprocessor() + pp.context.update(buildconfig.defines) + # Hack until MOZ_DEBUG_FLAGS are simply part of buildconfig.defines + if buildconfig.substs['MOZ_DEBUG']: + pp.context['DEBUG'] = '1' + # Ensure @DATA@ works as expected (see the Windows section further below) + if buildconfig.substs['OS_TARGET'] == 'WINNT': + pp.context['DATA'] = 'DATA' + else: + pp.context['DATA'] = '' + pp.out = StringIO() + pp.do_filter('substitution') + pp.do_include(input) + + symbols = [s.strip() for s in pp.out.getvalue().splitlines() if s.strip()] + + if buildconfig.substs['GCC_USE_GNU_LD']: + # A linker version script is generated for GNU LD that looks like the + # following: + # { + # global: + # symbol1; + # symbol2; + # ... + # local: + # *; + # }; + output.write('{\nglobal:\n %s;\nlocal:\n *;\n};' + % ';\n '.join(symbols)) + elif buildconfig.substs['OS_TARGET'] == 'Darwin': + # A list of symbols is generated for Apple ld that simply lists all + # symbols, with an underscore prefix. + output.write(''.join('_%s\n' % s for s in symbols)) + elif buildconfig.substs['OS_TARGET'] == 'WINNT': + # A def file is generated for MSVC link.exe that looks like the + # following: + # LIBRARY library.dll + # EXPORTS + # symbol1 + # symbol2 + # ... + # + # link.exe however requires special markers for data symbols, so in + # that case the symbols look like: + # data_symbol1 DATA + # data_symbol2 DATA + # ... + # + # In the input file, this is just annotated with the following syntax: + # data_symbol1 @DATA@ + # data_symbol2 @DATA@ + # ... + # The DATA variable is "simply" expanded by the preprocessor, to + # nothing on non-Windows, such that we only get the symbol name on + # those platforms, and to DATA on Windows, so that the "DATA" part + # is, in fact, part of the symbol name as far as the symbols variable + # is concerned. + libname, ext = os.path.splitext(os.path.basename(output.name)) + assert ext == '.symbols' + output.write('LIBRARY %s\nEXPORTS\n %s\n' + % (libname, '\n '.join(symbols))) + + return set(pp.includes) diff --git a/python/mozbuild/mozbuild/action/process_define_files.py b/python/mozbuild/mozbuild/action/process_define_files.py index c353e436af88..f6d0c1695a68 100644 --- a/python/mozbuild/mozbuild/action/process_define_files.py +++ b/python/mozbuild/mozbuild/action/process_define_files.py @@ -76,7 +76,7 @@ def process_define_file(output, input): output.write(l) - return {config.source} + return {path, config.source} def main(argv): diff --git a/python/mozbuild/mozbuild/backend/base.py b/python/mozbuild/mozbuild/backend/base.py index 6a4f6b3eba53..cf17807979d3 100644 --- a/python/mozbuild/mozbuild/backend/base.py +++ b/python/mozbuild/mozbuild/backend/base.py @@ -218,6 +218,7 @@ class BuildBackend(LoggingMixin): pp.context.update(obj.config.substs) pp.context.update( top_srcdir=obj.topsrcdir, + topobjdir=obj.topobjdir, srcdir=srcdir, relativesrcdir=mozpath.relpath(srcdir, obj.topsrcdir) or '.', DEPTH=mozpath.relpath(obj.topobjdir, mozpath.dirname(obj.output_path)) or '.', diff --git a/python/mozbuild/mozbuild/backend/common.py b/python/mozbuild/mozbuild/backend/common.py index 0bad59af6883..c242f0502f1a 100644 --- a/python/mozbuild/mozbuild/backend/common.py +++ b/python/mozbuild/mozbuild/backend/common.py @@ -12,12 +12,21 @@ import re import mozpack.path as mozpath import mozwebidlcodegen -from .base import BuildBackend +from mozbuild.backend.base import BuildBackend -from ..frontend.data import ( +from mozbuild.frontend.context import ( + Context, + Path, + RenamedSourcePath, + VARIABLES, +) +from mozbuild.frontend.data import ( + ChromeManifestEntry, ConfigFileSubstitution, ExampleWebIDLInterface, IPDLFile, + FinalTargetPreprocessedFiles, + FinalTargetFiles, GeneratedEventWebIDLFile, GeneratedWebIDLFile, PreprocessedTestWebIDLFile, @@ -28,12 +37,13 @@ from ..frontend.data import ( XPIDLFile, WebIDLFile, ) +from mozbuild.jar import JarManifestParser +from mozbuild.preprocessor import Preprocessor +from mozpack.chrome.manifest import parse_manifest_line from collections import defaultdict -from ..util import ( - group_unified_files, -) +from mozbuild.util import group_unified_files class XPIDLManager(object): """Helps manage XPCOM IDLs in the context of the build system.""" @@ -367,3 +377,93 @@ class CommonBackend(BuildBackend): for unified_file, source_filenames in unified_source_mapping: self._write_unified_file(unified_file, source_filenames, output_directory, poison_windows_h) + + def _consume_jar_manifest(self, obj): + # Ideally, this would all be handled somehow in the emitter, but + # this would require all the magic surrounding l10n and addons in + # the recursive make backend to die, which is not going to happen + # any time soon enough. + # Notably missing: + # - DEFINES from config/config.mk + # - L10n support + # - The equivalent of -e when USE_EXTENSION_MANIFEST is set in + # moz.build, but it doesn't matter in dist/bin. + pp = Preprocessor() + if obj.defines: + pp.context.update(obj.defines.defines) + pp.context.update(self.environment.defines) + pp.context.update( + AB_CD='en-US', + BUILD_FASTER=1, + ) + pp.out = JarManifestParser() + pp.do_include(obj.path.full_path) + self.backend_input_files |= pp.includes + + for jarinfo in pp.out: + jar_context = Context( + allowed_variables=VARIABLES, config=obj._context.config) + jar_context.push_source(obj._context.main_path) + jar_context.push_source(obj.path.full_path) + + install_target = obj.install_target + if jarinfo.base: + install_target = mozpath.normpath( + mozpath.join(install_target, jarinfo.base)) + jar_context['FINAL_TARGET'] = install_target + if obj.defines: + jar_context['DEFINES'] = obj.defines.defines + files = jar_context['FINAL_TARGET_FILES'] + files_pp = jar_context['FINAL_TARGET_PP_FILES'] + + for e in jarinfo.entries: + if e.is_locale: + if jarinfo.relativesrcdir: + src = '/%s' % jarinfo.relativesrcdir + else: + src = '' + src = mozpath.join(src, 'en-US', e.source) + else: + src = e.source + + src = Path(jar_context, src) + + if '*' not in e.source and not os.path.exists(src.full_path): + if e.is_locale: + raise Exception( + '%s: Cannot find %s' % (obj.path, e.source)) + if e.source.startswith('/'): + src = Path(jar_context, '!' + e.source) + else: + # This actually gets awkward if the jar.mn is not + # in the same directory as the moz.build declaring + # it, but it's how it works in the recursive make, + # not that anything relies on that, but it's simpler. + src = Path(obj._context, '!' + e.source) + + output_basename = mozpath.basename(e.output) + if output_basename != src.target_basename: + src = RenamedSourcePath(jar_context, + (src, output_basename)) + path = mozpath.dirname(mozpath.join(jarinfo.name, e.output)) + + if e.preprocess: + if '*' in e.source: + raise Exception('%s: Wildcards are not supported with ' + 'preprocessing' % obj.path) + files_pp[path] += [src] + else: + files[path] += [src] + + if files: + self.consume_object(FinalTargetFiles(jar_context, files)) + if files_pp: + self.consume_object( + FinalTargetPreprocessedFiles(jar_context, files_pp)) + + for m in jarinfo.chrome_manifests: + entry = parse_manifest_line( + mozpath.dirname(jarinfo.name), + m.replace('%', mozpath.basename(jarinfo.name) + '/')) + self.consume_object(ChromeManifestEntry( + jar_context, '%s.manifest' % jarinfo.name, entry)) diff --git a/python/mozbuild/mozbuild/backend/fastermake.py b/python/mozbuild/mozbuild/backend/fastermake.py index e95cd90c0fc2..b6fe12f52b16 100644 --- a/python/mozbuild/mozbuild/backend/fastermake.py +++ b/python/mozbuild/mozbuild/backend/fastermake.py @@ -5,34 +5,26 @@ from __future__ import absolute_import, unicode_literals, print_function from mozbuild.backend.common import CommonBackend +from mozbuild.frontend.context import ( + ObjDirPath, +) from mozbuild.frontend.data import ( ChromeManifestEntry, - ContextDerived, - Defines, FinalTargetPreprocessedFiles, FinalTargetFiles, JARManifest, XPIDLFile, ) -from mozbuild.jar import JarManifestParser from mozbuild.makeutil import Makefile -from mozbuild.preprocessor import Preprocessor from mozbuild.util import OrderedDefaultDict from mozpack.manifests import InstallManifest import mozpack.path as mozpath -from collections import OrderedDict -from itertools import chain -import os -import sys class FasterMakeBackend(CommonBackend): def _init(self): super(FasterMakeBackend, self)._init() - self._seen_directories = set() - self._defines = dict() - self._manifest_entries = OrderedDefaultDict(set) self._install_manifests = OrderedDefaultDict(InstallManifest) @@ -44,9 +36,11 @@ class FasterMakeBackend(CommonBackend): def _add_preprocess(self, obj, path, dest, target=None, **kwargs): if target is None: target = mozpath.basename(path) - # This matches what PP_TARGETS do in config/rules. - if target.endswith('.in'): - target = target[:-3] + # This matches what PP_TARGETS do in config/rules. + if target.endswith('.in'): + target = target[:-3] + if target.endswith('.css'): + kwargs['marker'] = '%' depfile = mozpath.join( self.environment.topobjdir, 'faster', '.deps', mozpath.join(obj.install_target, dest, target).replace('/', '_')) @@ -57,36 +51,44 @@ class FasterMakeBackend(CommonBackend): **kwargs) def consume_object(self, obj): - if not isinstance(obj, Defines) and isinstance(obj, ContextDerived): - defines = self._defines.get(obj.objdir, {}) - if defines: - defines = defines.defines - - if isinstance(obj, Defines): - self._defines[obj.objdir] = obj - - # We're assuming below that Defines come first for a given objdir, - # which is kind of set in stone from the order things are treated - # in emitter.py. - assert obj.objdir not in self._seen_directories - - elif isinstance(obj, JARManifest) and \ + if isinstance(obj, JARManifest) and \ obj.install_target.startswith('dist/bin'): - self._consume_jar_manifest(obj, defines) + self._consume_jar_manifest(obj) elif isinstance(obj, (FinalTargetFiles, FinalTargetPreprocessedFiles)) and \ obj.install_target.startswith('dist/bin'): + defines = obj.defines or {} + if defines: + defines = defines.defines for path, files in obj.files.walk(): for f in files: if isinstance(obj, FinalTargetPreprocessedFiles): self._add_preprocess(obj, f.full_path, path, + target=f.target_basename, defines=defines) + elif '*' in f: + def _prefix(s): + for p in mozpath.split(s): + if '*' not in p: + yield p + '/' + prefix = ''.join(_prefix(f.full_path)) + + self._install_manifests[obj.install_target] \ + .add_pattern_symlink( + prefix, + f.full_path[len(prefix):], + mozpath.join(path, f.target_basename)) else: self._install_manifests[obj.install_target].add_symlink( f.full_path, - mozpath.join(path, mozpath.basename(f)) + mozpath.join(path, f.target_basename) ) + if isinstance(f, ObjDirPath): + dep_target = 'install-%s' % obj.install_target + self._dependencies[dep_target].append( + mozpath.relpath(f.full_path, + self.environment.topobjdir)) elif isinstance(obj, ChromeManifestEntry) and \ obj.install_target.startswith('dist/bin'): @@ -99,123 +101,11 @@ class FasterMakeBackend(CommonBackend): elif isinstance(obj, XPIDLFile): self._has_xpidl = True - # XPIDL are emitted before Defines, which breaks the assert in the - # branch for Defines. OTOH, we don't actually care about the - # XPIDLFile objects just yet, so we can just pretend we didn't see - # an object in the directory yet. - return True - else: - # We currently ignore a lot of object types, so just acknowledge - # everything. - return True - - self._seen_directories.add(obj.objdir) + # We currently ignore a lot of object types, so just acknowledge + # everything. return True - def _consume_jar_manifest(self, obj, defines): - # Ideally, this would all be handled somehow in the emitter, but - # this would require all the magic surrounding l10n and addons in - # the recursive make backend to die, which is not going to happen - # any time soon enough. - # Notably missing: - # - DEFINES from config/config.mk - # - L10n support - # - The equivalent of -e when USE_EXTENSION_MANIFEST is set in - # moz.build, but it doesn't matter in dist/bin. - pp = Preprocessor() - pp.context.update(defines) - pp.context.update(self.environment.defines) - pp.context.update( - AB_CD='en-US', - BUILD_FASTER=1, - ) - pp.out = JarManifestParser() - pp.do_include(obj.path) - self.backend_input_files |= pp.includes - - for jarinfo in pp.out: - install_target = obj.install_target - if jarinfo.base: - install_target = mozpath.normpath( - mozpath.join(install_target, jarinfo.base)) - for e in jarinfo.entries: - if e.is_locale: - if jarinfo.relativesrcdir: - path = mozpath.join(self.environment.topsrcdir, - jarinfo.relativesrcdir) - else: - path = mozpath.dirname(obj.path) - src = mozpath.join( path, 'en-US', e.source) - elif e.source.startswith('/'): - src = mozpath.join(self.environment.topsrcdir, - e.source[1:]) - else: - src = mozpath.join(mozpath.dirname(obj.path), e.source) - - if '*' in e.source: - if e.preprocess: - raise Exception('%s: Wildcards are not supported with ' - 'preprocessing' % obj.path) - def _prefix(s): - for p in s.split('/'): - if '*' not in p: - yield p + '/' - prefix = ''.join(_prefix(src)) - - self._install_manifests[install_target] \ - .add_pattern_symlink( - prefix, - src[len(prefix):], - mozpath.join(jarinfo.name, e.output)) - continue - - if not os.path.exists(src): - if e.is_locale: - raise Exception( - '%s: Cannot find %s' % (obj.path, e.source)) - if e.source.startswith('/'): - src = mozpath.join(self.environment.topobjdir, - e.source[1:]) - else: - # This actually gets awkward if the jar.mn is not - # in the same directory as the moz.build declaring - # it, but it's how it works in the recursive make, - # not that anything relies on that, but it's simpler. - src = mozpath.join(obj.objdir, e.source) - self._dependencies['install-%s' % install_target] \ - .append(mozpath.relpath( - src, self.environment.topobjdir)) - - if e.preprocess: - kwargs = {} - if src.endswith('.css'): - kwargs['marker'] = '%' - self._add_preprocess( - obj, - src, - mozpath.join(jarinfo.name, mozpath.dirname(e.output)), - mozpath.basename(e.output), - defines=defines, - **kwargs) - else: - self._install_manifests[install_target].add_symlink( - src, - mozpath.join(jarinfo.name, e.output)) - - manifest = mozpath.normpath(mozpath.join(install_target, - jarinfo.name)) - manifest += '.manifest' - for m in jarinfo.chrome_manifests: - self._manifest_entries[manifest].add( - m.replace('%', mozpath.basename(jarinfo.name) + '/')) - - if jarinfo.name != 'chrome': - manifest = mozpath.normpath(mozpath.join(install_target, - 'chrome.manifest')) - entry = 'manifest %s.manifest' % jarinfo.name - self._manifest_entries[manifest].add(entry) - def consume_finished(self): mk = Makefile() # Add the default rule at the very beginning. diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 43a01d865077..84116dec24a8 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -26,6 +26,7 @@ import mozpack.path as mozpath from mozbuild.frontend.context import ( Path, + RenamedSourcePath, SourcePath, ObjDirPath, ) @@ -455,6 +456,9 @@ class RecursiveMakeBackend(CommonBackend): if consumed: return True + if not isinstance(obj, Defines): + self.consume_object(obj.defines) + if isinstance(obj, DirectoryTraversal): self._process_directory_traversal(obj, backend_file) elif isinstance(obj, ConfigFileSubstitution): @@ -528,7 +532,7 @@ class RecursiveMakeBackend(CommonBackend): self._process_test_harness_files(obj, backend_file) elif isinstance(obj, JARManifest): - backend_file.write('JAR_MANIFEST := %s\n' % obj.path) + backend_file.write('JAR_MANIFEST := %s\n' % obj.path.full_path) elif isinstance(obj, Program): self._process_program(obj.program, backend_file) @@ -854,20 +858,23 @@ class RecursiveMakeBackend(CommonBackend): ensureParentDir(mozpath.join(self.environment.topobjdir, 'dist', 'foo')) - def _pretty_path(self, path, backend_file): + def _pretty_path_parts(self, path, backend_file): assert isinstance(path, Path) if isinstance(path, SourcePath): if path.full_path.startswith(backend_file.srcdir): - return '$(srcdir)' + path.full_path[len(backend_file.srcdir):] + return '$(srcdir)', path.full_path[len(backend_file.srcdir):] if path.full_path.startswith(backend_file.topsrcdir): - return '$(topsrcdir)' + path.full_path[len(backend_file.topsrcdir):] + return '$(topsrcdir)', path.full_path[len(backend_file.topsrcdir):] elif isinstance(path, ObjDirPath): if path.full_path.startswith(backend_file.objdir): - return path.full_path[len(backend_file.objdir) + 1:] + return '', path.full_path[len(backend_file.objdir) + 1:] if path.full_path.startswith(self.environment.topobjdir): - return '$(DEPTH)' + path.full_path[len(self.environment.topobjdir):] + return '$(DEPTH)', path.full_path[len(self.environment.topobjdir):] - return path.full_path + return '', path.full_path + + def _pretty_path(self, path, backend_file): + return ''.join(self._pretty_path_parts(path, backend_file)) def _process_unified_sources(self, obj): backend_file = self._get_backend_file_for(obj) @@ -923,10 +930,8 @@ class RecursiveMakeBackend(CommonBackend): """Output the DEFINES rules to the given backend file.""" defines = list(obj.get_defines()) if defines: - backend_file.write(which + ' +=') - for define in defines: - backend_file.write(' %s' % define) - backend_file.write('\n') + defines = ' '.join(shell_quote(d) for d in defines) + backend_file.write_once('%s += %s\n' % (which, defines)) def _process_test_harness_files(self, obj, backend_file): for path, files in obj.srcdir_files.iteritems(): @@ -1110,11 +1115,18 @@ INSTALL_TARGETS += %(prefix)s self.backend_input_files |= obj.manifest.manifests def _process_local_include(self, local_include, backend_file): - path = self._pretty_path(local_include, backend_file) - if ' ' in path: - backend_file.write('LOCAL_INCLUDES += -I\'%s\'\n' % path) + d, path = self._pretty_path_parts(local_include, backend_file) + if isinstance(local_include, ObjDirPath) and not d: + # path doesn't start with a slash in this case + d = '$(CURDIR)/' + elif d == '$(DEPTH)': + d = '$(topobjdir)' + quoted_path = shell_quote(path) if path else path + if quoted_path != path: + path = quoted_path[0] + d + quoted_path[1:] else: - backend_file.write('LOCAL_INCLUDES += -I%s\n' % path) + path = d + path + backend_file.write('LOCAL_INCLUDES += -I%s\n' % path) def _process_per_source_flag(self, per_source_flag, backend_file): for flag in per_source_flag.flags: @@ -1170,6 +1182,8 @@ INSTALL_TARGETS += %(prefix)s backend_file.write('DSO_SONAME := %s\n' % libdef.soname) if libdef.is_sdk: backend_file.write('SDK_LIBRARY := %s\n' % libdef.import_name) + if libdef.symbols_file: + backend_file.write('SYMBOLS_FILE := %s\n' % libdef.symbols_file) def _process_static_library(self, libdef, backend_file): backend_file.write_once('LIBRARY_NAME := %s\n' % libdef.basename) @@ -1242,7 +1256,7 @@ INSTALL_TARGETS += %(prefix)s backend_file.write_once('HOST_EXTRA_LIBS += %s\n' % lib) # Process library-based defines - self._process_defines(obj.defines, backend_file) + self._process_defines(obj.lib_defines, backend_file) def _process_final_target_files(self, obj, files, backend_file): target = obj.install_target @@ -1273,8 +1287,8 @@ INSTALL_TARGETS += %(prefix)s if path else target).replace('/', '_') have_objdir_files = False for f in files: - dest = mozpath.join(reltarget, path, - mozpath.basename(f.full_path)) + assert not isinstance(f, RenamedSourcePath) + dest = mozpath.join(reltarget, path, f.target_basename) if not isinstance(f, ObjDirPath): install_manifest.add_symlink(f.full_path, dest) else: @@ -1374,6 +1388,7 @@ INSTALL_TARGETS += %(prefix)s pp.context['autoconfmk'] = 'autoconf.mk' pp.handleLine(b'# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n'); pp.handleLine(b'DEPTH := @DEPTH@\n') + pp.handleLine(b'topobjdir := @topobjdir@\n') pp.handleLine(b'topsrcdir := @top_srcdir@\n') pp.handleLine(b'srcdir := @srcdir@\n') pp.handleLine(b'VPATH := @srcdir@\n') @@ -1446,7 +1461,7 @@ INSTALL_TARGETS += %(prefix)s # which would modify content in the source directory. '$(RM) $@', '$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) ' - '$(MOZ_DEBUG_DEFINES) $< -o $@)' + '$< -o $@)' ]) self._add_unified_build_rules(mk, diff --git a/python/mozbuild/mozbuild/compilation/codecomplete.py b/python/mozbuild/mozbuild/compilation/codecomplete.py index ada2cacbb430..a5768b330755 100644 --- a/python/mozbuild/mozbuild/compilation/codecomplete.py +++ b/python/mozbuild/mozbuild/compilation/codecomplete.py @@ -15,7 +15,11 @@ from mach.decorators import ( ) from mozbuild.base import MachCommandBase -from mozbuild.shellutil import quote as shell_quote +from mozbuild.shellutil import ( + split as shell_split, + quote as shell_quote, +) + @CommandProvider class Introspection(MachCommandBase): @@ -51,6 +55,4 @@ class Introspection(MachCommandBase): return print(' '.join(shell_quote(arg) - for arg in util.get_flags(self.topobjdir, make_dir, - build_vars, name))) - + for arg in shell_split(build_vars[name]))) diff --git a/python/mozbuild/mozbuild/compilation/database.py b/python/mozbuild/mozbuild/compilation/database.py index 39b7c99248d7..0c9970446313 100644 --- a/python/mozbuild/mozbuild/compilation/database.py +++ b/python/mozbuild/mozbuild/compilation/database.py @@ -15,7 +15,10 @@ from mozbuild.frontend.data import ( UnifiedSources, GeneratedSources, ) -from mozbuild.shellutil import quote as shell_quote +from mozbuild.shellutil import ( + split as shell_split, + quote as shell_quote, +) from mach.config import ConfigSettings from mach.logging import LoggingManager @@ -107,8 +110,7 @@ class CompileDBBackend(CommonBackend): if name not in build_vars: continue - build_vars[name] = util.get_flags(self.environment.topobjdir, directory, - build_vars, name) + build_vars[name] = shell_split(build_vars[name]) self._flags[directory] = build_vars return self._flags[directory] diff --git a/python/mozbuild/mozbuild/compilation/util.py b/python/mozbuild/mozbuild/compilation/util.py index 542b036e34e6..1a9f0625ccb7 100644 --- a/python/mozbuild/mozbuild/compilation/util.py +++ b/python/mozbuild/mozbuild/compilation/util.py @@ -33,29 +33,3 @@ def get_build_vars(directory, cmd): cmd.log_manager.replace_terminal_handler(old_logger) return build_vars - -def get_flags(topobjdir, make_dir, build_vars, name): - flags = ['-isystem', '-I', '-include', '-MF'] - new_args = [] - path = os.path.join(topobjdir, make_dir) - - # Take case to handle things such as the following correctly: - # * -DMOZ_APP_VERSION='"40.0a1"' - # * -DR_PLATFORM_INT_TYPES='' - # * -DAPP_ID='{ec8030f7-c20a-464f-9b0e-13a3a9e97384} - # * -D__UNUSED__='__attribute__((unused))' - args = shellutil.split(build_vars[name]) - - for arg in list(args): - if new_args and new_args[-1] in flags: - arg = os.path.normpath(os.path.join(path, arg)) - else: - flag = [(f, arg[len(f):]) for f in flags + ['--sysroot='] - if arg.startswith(f)] - if flag: - flag, val = flag[0] - if val: - arg = flag + os.path.normpath(os.path.join(path, val)) - new_args.append(arg) - - return new_args diff --git a/python/mozbuild/mozbuild/frontend/context.py b/python/mozbuild/mozbuild/frontend/context.py index c41fbd3b4575..51ae42933af7 100644 --- a/python/mozbuild/mozbuild/frontend/context.py +++ b/python/mozbuild/mozbuild/frontend/context.py @@ -281,6 +281,15 @@ class SubContext(Context, ContextDerivedValue): self._sandbox().pop_subcontext(self) +class InitializedDefines(ContextDerivedValue, OrderedDict): + def __init__(self, context, value=None): + OrderedDict.__init__(self) + for define in context.config.substs.get('MOZ_DEBUG_DEFINES', ()): + self[define] = 1 + if value: + self.update(value) + + class FinalTargetValue(ContextDerivedValue, unicode): def __new__(cls, context, value=""): if not value: @@ -398,6 +407,10 @@ class Path(ContextDerivedValue, unicode): def __hash__(self): return hash(self.full_path) + @memoized_property + def target_basename(self): + return mozpath.basename(self.full_path) + class SourcePath(Path): """Like Path, but limited to paths in the source directory.""" @@ -433,6 +446,24 @@ class SourcePath(Path): return ObjDirPath(self.context, '!%s' % self).full_path +class RenamedSourcePath(SourcePath): + """Like SourcePath, but with a different base name when installed. + + The constructor takes a tuple of (source, target_basename). + + This class is not meant to be exposed to moz.build sandboxes as of now, + and is not supported by the RecursiveMake backend. + """ + def __init__(self, context, value): + assert isinstance(value, tuple) + source, self._target_basename = value + super(RenamedSourcePath, self).__init__(context, source) + + @property + def target_basename(self): + return self._target_basename + + class ObjDirPath(Path): """Like Path, but limited to paths in the object directory.""" def __init__(self, context, value=None): @@ -935,7 +966,7 @@ VARIABLES = { indicating extra files the output depends on. """, 'export'), - 'DEFINES': (OrderedDict, dict, + 'DEFINES': (InitializedDefines, dict, """Dictionary of compiler defines to declare. These are passed in to the compiler as ``-Dkey='value'`` for string @@ -1191,6 +1222,16 @@ VARIABLES = { This variable can only be used on Linux. """, None), + 'SYMBOLS_FILE': (SourcePath, unicode, + """A file containing a list of symbols to export from a shared library. + + The given file contains a list of symbols to be exported, and is + preprocessed. + A special marker "@DATA@" must be added after a symbol name if it + points to data instead of code, so that the Windows linker can treat + them correctly. + """, None), + 'BRANDING_FILES': (ContextDerivedTypedHierarchicalStringList(Path), list, """List of files to be installed into the branding directory. @@ -1307,7 +1348,7 @@ VARIABLES = { will be made explicit. """, None), - 'JAR_MANIFESTS': (StrictOrderingOnAppendList, list, + 'JAR_MANIFESTS': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list, """JAR manifest files that should be processed as part of the build. JAR manifests are files in the tree that define how to package files diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py index e07ac0f162e4..cdd3fec2e771 100644 --- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -18,7 +18,6 @@ structures. from __future__ import absolute_import, unicode_literals from mozbuild.util import StrictOrderingOnAppendList -from mozbuild.shellutil import quote as shell_quote from mozpack.chrome.manifest import ManifestEntry import mozpack.path as mozpath @@ -77,11 +76,23 @@ class ContextDerived(TreeMetadata): def install_target(self): return self._context['FINAL_TARGET'] + @property + def defines(self): + defines = self._context['DEFINES'] + return Defines(self._context, defines) if defines else None + @property def relobjdir(self): return mozpath.relpath(self.objdir, self.topobjdir) +class HostMixin(object): + @property + def defines(self): + defines = self._context['HOST_DEFINES'] + return HostDefines(self._context, defines) if defines else None + + class DirectoryTraversal(ContextDerived): """Describes how directory traversal for building should work. @@ -174,7 +185,7 @@ class BaseDefines(ContextDerived): elif value is False: yield('-U%s' % define) else: - yield('-D%s=%s' % (define, shell_quote(value))) + yield('-D%s=%s' % (define, value)) def update(self, more_defines): if isinstance(more_defines, Defines): @@ -311,7 +322,7 @@ class LinkageWrongKindError(Exception): class Linkable(ContextDerived): """Generic context derived container object for programs and libraries""" __slots__ = ( - 'defines', + 'lib_defines', 'linked_libraries', 'linked_system_libs', ) @@ -320,7 +331,7 @@ class Linkable(ContextDerived): ContextDerived.__init__(self, context) self.linked_libraries = [] self.linked_system_libs = [] - self.defines = Defines(context, {}) + self.lib_defines = Defines(context, {}) def link_library(self, obj): assert isinstance(obj, BaseLibrary) @@ -374,7 +385,7 @@ class Program(BaseProgram): KIND = 'target' -class HostProgram(BaseProgram): +class HostProgram(HostMixin, BaseProgram): """Context derived container object for HOST_PROGRAM""" SUFFIX_VAR = 'HOST_BIN_SUFFIX' KIND = 'host' @@ -386,7 +397,7 @@ class SimpleProgram(BaseProgram): KIND = 'target' -class HostSimpleProgram(BaseProgram): +class HostSimpleProgram(HostMixin, BaseProgram): """Context derived container object for each program in HOST_SIMPLE_PROGRAMS""" SUFFIX_VAR = 'HOST_BIN_SUFFIX' @@ -449,6 +460,7 @@ class SharedLibrary(Library): __slots__ = ( 'soname', 'variant', + 'symbols_file', ) FRAMEWORK = 1 @@ -456,7 +468,7 @@ class SharedLibrary(Library): MAX_VARIANT = 3 def __init__(self, context, basename, real_name=None, is_sdk=False, - soname=None, variant=None): + soname=None, variant=None, symbols_file=False): assert(variant in range(1, self.MAX_VARIANT) or variant is None) Library.__init__(self, context, basename, real_name, is_sdk) self.variant = variant @@ -485,6 +497,11 @@ class SharedLibrary(Library): else: self.soname = self.lib_name + if symbols_file: + self.symbols_file = '%s.symbols' % self.lib_name + else: + self.symbols_file = None + class ExternalLibrary(object): """Empty mixin for libraries built by an external build system.""" @@ -500,7 +517,7 @@ class ExternalSharedLibrary(SharedLibrary, ExternalLibrary): build system.""" -class HostLibrary(BaseLibrary): +class HostLibrary(HostMixin, BaseLibrary): """Context derived container object for a host library""" KIND = 'host' @@ -694,7 +711,7 @@ class GeneratedSources(BaseSources): BaseSources.__init__(self, context, files, canonical_suffix) -class HostSources(BaseSources): +class HostSources(HostMixin, BaseSources): """Represents files to be compiled for the host during the build.""" def __init__(self, context, files, canonical_suffix): diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index 3197803daa73..ac364b3ed398 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -244,7 +244,7 @@ class TreeMetadataEmitter(LoggingMixin): # Propagate LIBRARY_DEFINES to all child libraries recursively. def propagate_defines(outerlib, defines): - outerlib.defines.update(defines) + outerlib.lib_defines.update(defines) for lib in outerlib.linked_libraries: # Propagate defines only along FINAL_LIBRARY paths, not USE_LIBS # paths. @@ -254,7 +254,7 @@ class TreeMetadataEmitter(LoggingMixin): for lib in (l for libs in self._libs.values() for l in libs): if isinstance(lib, Library): - propagate_defines(lib, lib.defines) + propagate_defines(lib, lib.lib_defines) yield lib for obj in self._binaries.values(): @@ -507,6 +507,23 @@ class TreeMetadataEmitter(LoggingMixin): 'STATIC_LIBRARY_NAME. Please change one of them.', context) + symbols_file = context.get('SYMBOLS_FILE') + if symbols_file: + if not shared_lib: + raise SandboxValidationError( + 'SYMBOLS_FILE can only be used with a SHARED_LIBRARY.', + context) + if context.get('DEFFILE') or context.get('LD_VERSION_SCRIPT'): + raise SandboxValidationError( + 'SYMBOLS_FILE cannot be used along DEFFILE or ' + 'LD_VERSION_SCRIPT.', context) + if not os.path.exists(symbols_file.full_path): + raise SandboxValidationError( + 'Path specified in SYMBOLS_FILE does not exist: %s ' + '(resolved to %s)' % (symbols_file, + symbols_file.full_path), context) + shared_args['symbols_file'] = True + if shared_lib: lib = SharedLibrary(context, libname, **shared_args) self._libs[libname].append(lib) @@ -515,6 +532,13 @@ class TreeMetadataEmitter(LoggingMixin): yield ChromeManifestEntry(context, 'components/components.manifest', ManifestBinaryComponent('components', lib.lib_name)) + if symbols_file: + script = mozpath.join( + mozpath.dirname(mozpath.dirname(__file__)), + 'action', 'generate_symbols_file.py') + yield GeneratedFile(context, script, + 'generate_symbols_file', lib.symbols_file, + [symbols_file.full_path]) if static_lib: lib = StaticLibrary(context, libname, **static_args) self._libs[libname].append(lib) @@ -524,7 +548,7 @@ class TreeMetadataEmitter(LoggingMixin): if not libname: raise SandboxValidationError('LIBRARY_DEFINES needs a ' 'LIBRARY_NAME to take effect', context) - lib.defines.update(lib_defines) + lib.lib_defines.update(lib_defines) def emit_from_context(self, context): """Convert a Context to tree metadata objects. @@ -681,7 +705,7 @@ class TreeMetadataEmitter(LoggingMixin): 'File listed in %s does not exist: %s' % (var, path), context) else: - if mozpath.basename(f.full_path) not in generated_files: + if f.target_basename not in generated_files: raise SandboxValidationError( ('Objdir file listed in %s not in ' + 'GENERATED_FILES: %s') % (var, f), context) @@ -1269,7 +1293,7 @@ class TreeMetadataEmitter(LoggingMixin): 'it is currently limited to one value.', context) for path in jar_manifests: - yield JARManifest(context, mozpath.join(context.srcdir, path)) + yield JARManifest(context, path) # Temporary test to look for jar.mn files that creep in without using # the new declaration. Before, we didn't require jar.mn files to diff --git a/python/mozbuild/mozbuild/jar.py b/python/mozbuild/mozbuild/jar.py index 3c8dcbab8d1c..97d366057a8e 100644 --- a/python/mozbuild/mozbuild/jar.py +++ b/python/mozbuild/mozbuild/jar.py @@ -154,7 +154,7 @@ class JarManifestParser(object): # - chrome manifest entries, prefixed with "%". m = self.regline.match(line) if m: - rline = m.group(1) + rline = ' '.join(m.group(1).split()) if rline not in self._current_jar.chrome_manifests: self._current_jar.chrome_manifests.append(rline) return diff --git a/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build b/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build index afc4b90b0dcc..8d6218ea9bb8 100644 --- a/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build +++ b/python/mozbuild/mozbuild/test/backend/data/build/app/moz.build @@ -26,6 +26,7 @@ FINAL_TARGET_FILES.child += [ FINAL_TARGET_PP_FILES += [ '../baz.ini', + '../foo.css', ] FINAL_TARGET_PP_FILES.child2 += [ @@ -45,5 +46,9 @@ JS_PREFERENCE_FILES += [ '../prefs.js', ] +JAR_MANIFESTS += [ + '../jar.mn', +] + DEFINES['FOO'] = 'bar' DEFINES['BAR'] = True diff --git a/python/mozbuild/mozbuild/test/backend/data/build/foo.css b/python/mozbuild/mozbuild/test/backend/data/build/foo.css new file mode 100644 index 000000000000..1803d6c57209 --- /dev/null +++ b/python/mozbuild/mozbuild/test/backend/data/build/foo.css @@ -0,0 +1,2 @@ +%filter substitution +foo.css: FOO is @FOO@ diff --git a/python/mozbuild/mozbuild/test/backend/data/build/jar.mn b/python/mozbuild/mozbuild/test/backend/data/build/jar.mn index 09d70e7db44f..393055c4eaa7 100644 --- a/python/mozbuild/mozbuild/test/backend/data/build/jar.mn +++ b/python/mozbuild/mozbuild/test/backend/data/build/jar.mn @@ -2,9 +2,10 @@ foo.jar: % content bar %child/ % content foo % foo.js +* foo.css bar.js (subdir/bar.js) qux.js (subdir/bar.js) * child/hoge.js (bar.js) * child/baz.jsm -% override chrome://foo/bar.svg#hello chrome://bar/bar.svg#hello +% override chrome://foo/bar.svg#hello chrome://bar/bar.svg#hello diff --git a/python/mozbuild/mozbuild/test/backend/data/build/moz.build b/python/mozbuild/mozbuild/test/backend/data/build/moz.build index 8e5f5084e030..b0b0cabd14fb 100644 --- a/python/mozbuild/mozbuild/test/backend/data/build/moz.build +++ b/python/mozbuild/mozbuild/test/backend/data/build/moz.build @@ -32,6 +32,7 @@ FINAL_TARGET_PP_FILES += [ ] FINAL_TARGET_PP_FILES.child2 += [ + 'foo.css', 'qux.ini', ] diff --git a/python/mozbuild/mozbuild/test/backend/test_build.py b/python/mozbuild/mozbuild/test/backend/test_build.py index e0eeb30fbd6f..2fa47bcc3845 100644 --- a/python/mozbuild/mozbuild/test/backend/test_build.py +++ b/python/mozbuild/mozbuild/test/backend/test_build.py @@ -133,6 +133,7 @@ class TestBuild(unittest.TestCase): self.assertEqual(result, { 'bin/baz.ini': 'baz.ini: FOO is foo\n', 'bin/child/bar.ini': 'bar.ini\n', + 'bin/child2/foo.css': 'foo.css: FOO is foo\n', 'bin/child2/qux.ini': 'qux.ini: BAR is not defined\n', 'bin/chrome.manifest': 'manifest chrome/foo.manifest\n' @@ -147,6 +148,7 @@ class TestBuild(unittest.TestCase): '//@line 2 "%sbaz.jsm"\nbaz.jsm: FOO is foo\n' % (test_path), 'bin/chrome/foo/child/hoge.js': '//@line 2 "%sbar.js"\nbar.js: FOO is foo\n' % (test_path), + 'bin/chrome/foo/foo.css': 'foo.css: FOO is foo\n', 'bin/chrome/foo/foo.js': 'foo.js\n', 'bin/chrome/foo/qux.js': 'bar.js\n', 'bin/components/bar.js': @@ -169,13 +171,29 @@ class TestBuild(unittest.TestCase): 'bin/app/baz.ini': 'baz.ini: FOO is bar\n', 'bin/app/child/bar.ini': 'bar.ini\n', 'bin/app/child2/qux.ini': 'qux.ini: BAR is defined\n', - 'bin/app/chrome.manifest': 'manifest components/components.manifest\n', + 'bin/app/chrome.manifest': + 'manifest chrome/foo.manifest\n' + 'manifest components/components.manifest\n', + 'bin/app/chrome/foo.manifest': + 'content bar foo/child/\n' + 'content foo foo/\n' + 'override chrome://foo/bar.svg#hello ' + 'chrome://bar/bar.svg#hello\n', + 'bin/app/chrome/foo/bar.js': 'bar.js\n', + 'bin/app/chrome/foo/child/baz.jsm': + '//@line 2 "%sbaz.jsm"\nbaz.jsm: FOO is bar\n' % (test_path), + 'bin/app/chrome/foo/child/hoge.js': + '//@line 2 "%sbar.js"\nbar.js: FOO is bar\n' % (test_path), + 'bin/app/chrome/foo/foo.css': 'foo.css: FOO is bar\n', + 'bin/app/chrome/foo/foo.js': 'foo.js\n', + 'bin/app/chrome/foo/qux.js': 'bar.js\n', 'bin/app/components/bar.js': '//@line 2 "%sbar.js"\nbar.js: FOO is bar\n' % (test_path), 'bin/app/components/components.manifest': 'component {foo} foo.js\ncomponent {bar} bar.js\n', 'bin/app/components/foo.js': 'foo.js\n', 'bin/app/defaults/preferences/prefs.js': 'prefs.js\n', + 'bin/app/foo.css': 'foo.css: FOO is bar\n', 'bin/app/foo.ini': 'foo.ini\n', 'bin/app/modules/baz.jsm': '//@line 2 "%sbaz.jsm"\nbaz.jsm: FOO is bar\n' % (test_path), diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index b7e04f762d39..9a82f50de2a3 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -188,6 +188,7 @@ class TestRecursiveMakeBackend(BackendTester): lines = [l.strip() for l in open(p, 'rt').readlines()[1:] if not l.startswith('#')] self.assertEqual(lines, [ 'DEPTH := .', + 'topobjdir := %s' % env.topobjdir, 'topsrcdir := %s' % env.topsrcdir, 'srcdir := %s' % env.topsrcdir, 'VPATH := %s' % env.topsrcdir, @@ -207,7 +208,7 @@ class TestRecursiveMakeBackend(BackendTester): self.assertTrue(os.path.exists(p)) lines = [l.strip() for l in open(p, 'rt').readlines()] - self.assertEqual(len(lines), 9) + self.assertEqual(len(lines), 10) self.assertTrue(lines[0].startswith('# THIS FILE WAS AUTOMATICALLY')) @@ -615,7 +616,7 @@ class TestRecursiveMakeBackend(BackendTester): var = 'DEFINES' defines = [val for val in lines if val.startswith(var)] - expected = ['DEFINES += -DFOO -DBAZ=\'"ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz'] + expected = ['DEFINES += -DFOO \'-DBAZ="ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz'] self.assertEqual(defines, expected) def test_host_defines(self): @@ -628,7 +629,7 @@ class TestRecursiveMakeBackend(BackendTester): var = 'HOST_DEFINES' defines = [val for val in lines if val.startswith(var)] - expected = ['HOST_DEFINES += -DFOO -DBAZ=\'"ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz'] + expected = ['HOST_DEFINES += -DFOO \'-DBAZ="ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz'] self.assertEqual(defines, expected) def test_local_includes(self): @@ -656,8 +657,8 @@ class TestRecursiveMakeBackend(BackendTester): topobjdir = env.topobjdir.replace('\\', '/') expected = [ - 'LOCAL_INCLUDES += -Ibar/baz', - 'LOCAL_INCLUDES += -Ifoo', + 'LOCAL_INCLUDES += -I$(CURDIR)/bar/baz', + 'LOCAL_INCLUDES += -I$(CURDIR)/foo', ] found = [str for str in lines if str.startswith('LOCAL_INCLUDES')] diff --git a/python/mozbuild/mozbuild/test/frontend/test_emitter.py b/python/mozbuild/mozbuild/test/frontend/test_emitter.py index 075c30d2ac3b..71aef45b7096 100644 --- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py +++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py @@ -11,6 +11,7 @@ from mozunit import main from mozbuild.frontend.context import ( ObjDirPath, + Path, ) from mozbuild.frontend.data import ( AndroidResDirs, @@ -698,7 +699,7 @@ class TestEmitterBasic(unittest.TestCase): self.assertEqual(len(objs), 1) for obj in objs: self.assertIsInstance(obj, JARManifest) - self.assertTrue(os.path.isabs(obj.path)) + self.assertIsInstance(obj.path, Path) def test_jar_manifests_multiple_files(self): with self.assertRaisesRegexp(SandboxValidationError, 'limited to one value'): @@ -733,7 +734,7 @@ class TestEmitterBasic(unittest.TestCase): } defines = {} for lib in libraries: - defines[lib.basename] = ' '.join(lib.defines.get_defines()) + defines[lib.basename] = ' '.join(lib.lib_defines.get_defines()) self.assertEqual(expected, defines) def test_sources(self): diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py index 77f97a6677b6..e4348fdd1497 100644 --- a/python/mozbuild/mozbuild/virtualenv.py +++ b/python/mozbuild/mozbuild/virtualenv.py @@ -144,7 +144,8 @@ class VirtualenvManager(object): stderr=subprocess.STDOUT, env=env) if result: - raise Exception('Error creating virtualenv.') + raise Exception( + 'Failed to create virtualenv: %s' % self.virtualenv_root) return self.virtualenv_root diff --git a/testing/mozbase/mozcrash/mozcrash/mozcrash.py b/testing/mozbase/mozcrash/mozcrash/mozcrash.py index 776095540e66..a24506d7d10e 100644 --- a/testing/mozbase/mozcrash/mozcrash/mozcrash.py +++ b/testing/mozbase/mozcrash/mozcrash/mozcrash.py @@ -445,3 +445,18 @@ def kill_and_get_minidump(pid, dump_directory=None): needs_killing = False if needs_killing: kill_pid(pid) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('--stackwalk-binary', '-b') + parser.add_argument('--dump-save-path', '-o') + parser.add_argument('--test-name', '-n') + parser.add_argument('dump_directory') + parser.add_argument('symbols_path') + args = parser.parse_args() + + check_for_crashes(args.dump_directory, args.symbols_path, + stackwalk_binary=args.stackwalk_binary, + dump_save_path=args.dump_save_path, + test_name=args.test_name) diff --git a/testing/mozharness/configs/developer_config.py b/testing/mozharness/configs/developer_config.py index c489399e9a29..4686b31d4b92 100644 --- a/testing/mozharness/configs/developer_config.py +++ b/testing/mozharness/configs/developer_config.py @@ -25,6 +25,7 @@ config = { "exes": { "hgtool.py": os.path.join(LOCAL_WORKDIR, "hgtool.py"), "gittool.py": os.path.join(LOCAL_WORKDIR, "gittool.py"), + "virtualenv": ["python", "-m", "virtualenv"], }, "env": { "PIP_TRUSTED_HOST": "pypi.pub.build.mozilla.org", diff --git a/testing/mozharness/mozharness/mozilla/building/hazards.py b/testing/mozharness/mozharness/mozilla/building/hazards.py index b90f5ec46903..6de235f8929b 100644 --- a/testing/mozharness/mozharness/mozilla/building/hazards.py +++ b/testing/mozharness/mozharness/mozilla/building/hazards.py @@ -36,7 +36,12 @@ class HazardAnalysis(object): env=builder.env, error_list=MakefileErrorList) if rc != 0: - raise HazardError("autoconf failed, can't continue.") + rc = builder.run_command(['autoconf2.13'], + cwd=js_src_dir, + env=builder.env, + error_list=MakefileErrorList) + if rc != 0: + raise HazardError("autoconf failed, can't continue.") rc = builder.run_command([os.path.join(js_src_dir, 'configure'), '--enable-optimize', diff --git a/testing/taskcluster/tasks/branches/base_jobs.yml b/testing/taskcluster/tasks/branches/base_jobs.yml index 5bffe59128e5..d22d84490a5c 100644 --- a/testing/taskcluster/tasks/branches/base_jobs.yml +++ b/testing/taskcluster/tasks/branches/base_jobs.yml @@ -270,5 +270,7 @@ tests: task: tasks/tests/fx_linux64_web_platform_tests_reftests.yml xpcshell: allowed_build_tasks: + tasks/builds/b2g_emulator_x86_kk_opt.yml: + task: tasks/tests/b2g_emulator_xpcshell_chunked.yml tasks/builds/dbg_linux64.yml: task: tasks/tests/fx_linux64_xpcshell.yml diff --git a/testing/taskcluster/tasks/branches/try/job_flags.yml b/testing/taskcluster/tasks/branches/try/job_flags.yml index c358734ea84d..401f6ab9ab76 100644 --- a/testing/taskcluster/tasks/branches/try/job_flags.yml +++ b/testing/taskcluster/tasks/branches/try/job_flags.yml @@ -190,7 +190,5 @@ tests: task: tasks/tests/fx_linux64_web_platform_tests_reftests.yml xpcshell: allowed_build_tasks: - tasks/builds/b2g_emulator_x86_kk_opt.yml: - task: tasks/tests/b2g_emulator_xpcshell_chunked.yml tasks/builds/dbg_linux64_clobber.yml: task: tasks/tests/fx_linux64_xpcshell.yml diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index bfc10281dd9e..b8ca8214c51b 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -4389,6 +4389,16 @@ ], "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html" }, + { + "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html", + "references": [ + [ + "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html", + "==" + ] + ], + "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html" + }, { "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html", "references": [ @@ -4489,6 +4499,16 @@ ], "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html" }, + { + "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html", + "references": [ + [ + "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html", + "==" + ] + ], + "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html" + }, { "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html", "references": [ diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html new file mode 100644 index 000000000000..6c1198ef50ce --- /dev/null +++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html @@ -0,0 +1,6 @@ + + +ol@type: unsupported type: invalid + +
  1. 1
  2. 2
+
  1. 1
  2. 2
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html new file mode 100644 index 000000000000..c6ee14eac810 --- /dev/null +++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html @@ -0,0 +1,7 @@ + + +ul@type: unsupported type: invalid + +
  • first item
  • second item
+
  • first item
  • second item
+
  • first item
  • second item
diff --git a/toolkit/components/perfmonitoring/tests/browser/browser_AddonWatcher.js b/toolkit/components/perfmonitoring/tests/browser/browser_AddonWatcher.js index d157cee9e495..5632b8ac83b9 100644 --- a/toolkit/components/perfmonitoring/tests/browser/browser_AddonWatcher.js +++ b/toolkit/components/perfmonitoring/tests/browser/browser_AddonWatcher.js @@ -5,6 +5,8 @@ "use strict"; +requestLongerTimeout(2); + Cu.import("resource://gre/modules/Promise.jsm", this); Cu.import("resource://gre/modules/AddonManager.jsm", this); Cu.import("resource://gre/modules/Services.jsm", this); diff --git a/toolkit/components/social/test/browser/browser_frameworker.js b/toolkit/components/social/test/browser/browser_frameworker.js index aabcc8bf1f3e..e6a717fadcd5 100644 --- a/toolkit/components/social/test/browser/browser_frameworker.js +++ b/toolkit/components/social/test/browser/browser_frameworker.js @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +requestLongerTimeout(2); + // This file tests message ports and semantics of the frameworker which aren't // directly related to the sandbox. See also browser_frameworker_sandbox.js. diff --git a/toolkit/components/telemetry/Makefile.in b/toolkit/components/telemetry/Makefile.in index 5cfcd252283c..2abb15a7788b 100644 --- a/toolkit/components/telemetry/Makefile.in +++ b/toolkit/components/telemetry/Makefile.in @@ -15,7 +15,7 @@ include $(topsrcdir)/config/rules.mk # This is so hacky. Waiting on bug 988938. addondir = $(srcdir)/tests/addons -testdir = $(abspath $(DEPTH)/_tests/xpcshell/toolkit/components/telemetry/tests/unit) +testdir = $(topobjdir)/_tests/xpcshell/toolkit/components/telemetry/tests/unit misc:: $(call mkdir_deps,$(testdir)) $(EXIT_ON_ERROR) \ diff --git a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js index df696b758ec9..ff54ef172039 100644 --- a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js +++ b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js @@ -1,3 +1,4 @@ +requestLongerTimeout(2); add_task(function* () { function pushPref(name, value) { diff --git a/toolkit/crashreporter/client/Makefile.in b/toolkit/crashreporter/client/Makefile.in index 65ebab288d82..78719416c1a3 100644 --- a/toolkit/crashreporter/client/Makefile.in +++ b/toolkit/crashreporter/client/Makefile.in @@ -7,14 +7,6 @@ ifeq ($(OS_ARCH),WINNT) MOZ_WINCONSOLE = 0 endif -ifdef MOZ_WIDGET_GTK -OS_CXXFLAGS += $(TK_CFLAGS) $(MOZ_GTHREAD_CFLAGS) -endif - -ifeq ($(OS_ARCH),SunOS) -OS_CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GTHREAD_CFLAGS) -endif - include $(topsrcdir)/config/rules.mk ifeq ($(OS_ARCH),Darwin) diff --git a/toolkit/crashreporter/client/moz.build b/toolkit/crashreporter/client/moz.build index 14cc0ffad4cf..d067c1da58cf 100644 --- a/toolkit/crashreporter/client/moz.build +++ b/toolkit/crashreporter/client/moz.build @@ -65,6 +65,8 @@ if CONFIG['MOZ_ENABLE_GTK']: ] OS_LIBS += CONFIG['TK_LIBS'] OS_LIBS += CONFIG['MOZ_GTHREAD_LIBS'] + CXXFLAGS += CONFIG['TK_CFLAGS'] + CXXFLAGS += CONFIG['MOZ_GTHREAD_CFLAGS'] RCINCLUDE = 'crashreporter.rc' diff --git a/b2g/locales/generic/install.rdf b/toolkit/locales/generic/install.rdf similarity index 92% rename from b2g/locales/generic/install.rdf rename to toolkit/locales/generic/install.rdf index 3d32c03abd75..e6b82ac51311 100644 --- a/b2g/locales/generic/install.rdf +++ b/toolkit/locales/generic/install.rdf @@ -5,6 +5,8 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. #filter substitution +#include @TK_DEFINES@ +#include @APP_DEFINES@ --> - {3c2e2abc-06d4-11e1-ac3b-374f68613e61} + @MOZ_APP_ID@ @MOZ_APP_VERSION@ @MOZ_APP_MAXVERSION@ diff --git a/toolkit/locales/l10n.mk b/toolkit/locales/l10n.mk index a8e3ce652c50..312e6aea8d61 100644 --- a/toolkit/locales/l10n.mk +++ b/toolkit/locales/l10n.mk @@ -43,15 +43,16 @@ endif # pulls. You may override them if you provide your own files. You _must_ # override them when MOZ_PKG_PRETTYNAMES is defined - the defaults will not # work in that case. -ZIP_IN ?= $(_ABS_DIST)/$(PACKAGE) -WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe +ZIP_IN ?= $(ABS_DIST)/$(PACKAGE) +WIN32_INSTALLER_IN ?= $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe # Allows overriding the final destination of the repackaged file -ZIP_OUT ?= $(_ABS_DIST)/$(PACKAGE) +ZIP_OUT ?= $(ABS_DIST)/$(PACKAGE) ACDEFINES += \ -DAB_CD=$(AB_CD) \ -DMOZ_LANGPACK_EID=$(MOZ_LANGPACK_EID) \ + -DMOZ_APP_ID=$(MOZ_APP_ID) \ -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \ -DMOZ_APP_MAXVERSION=$(MOZ_APP_MAXVERSION) \ -DLOCALE_SRCDIR=$(abspath $(LOCALE_SRCDIR)) \ @@ -67,15 +68,15 @@ clobber-%: PACKAGER_NO_LIBS = 1 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) -STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR)/$(_APPNAME)/Contents/Resources +STAGEDIST = $(ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR)/$(_APPNAME)/Contents/Resources else -STAGEDIST = $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR) +STAGEDIST = $(ABS_DIST)/l10n-stage/$(MOZ_PKG_DIR) endif include $(MOZILLA_DIR)/toolkit/mozapps/installer/signing.mk include $(MOZILLA_DIR)/toolkit/mozapps/installer/packager.mk -PACKAGE_BASE_DIR = $(_ABS_DIST)/l10n-stage +PACKAGE_BASE_DIR = $(ABS_DIST)/l10n-stage $(STAGEDIST): AB_CD:=en-US $(STAGEDIST): UNPACKAGE=$(call ESCAPE_WILDCARD,$(ZIP_IN)) @@ -140,7 +141,7 @@ endif ifdef MAKE_COMPLETE_MAR $(MAKE) -C $(MOZDEPTH)/tools/update-packaging full-update AB_CD=$(AB_CD) \ MOZ_PKG_PRETTYNAMES=$(MOZ_PKG_PRETTYNAMES) \ - PACKAGE_BASE_DIR='$(_ABS_DIST)/l10n-stage' + PACKAGE_BASE_DIR='$(ABS_DIST)/l10n-stage' endif # packaging done, undo l10n stuff ifneq (en,$(LPROJ_ROOT)) @@ -167,14 +168,14 @@ TK_DEFINES = $(firstword \ # chrome directory. PKG_ZIP_DIRS = chrome $(or $(DIST_SUBDIRS),$(DIST_SUBDIR)) -langpack-%: LANGPACK_FILE=$(_ABS_DIST)/$(PKG_LANGPACK_PATH)$(PKG_LANGPACK_BASENAME).xpi +langpack-%: LANGPACK_FILE=$(ABS_DIST)/$(PKG_LANGPACK_PATH)$(PKG_LANGPACK_BASENAME).xpi langpack-%: AB_CD=$* langpack-%: XPI_NAME=locale-$* langpack-%: libs-% @echo 'Making langpack $(LANGPACK_FILE)' $(NSINSTALL) -D $(DIST)/$(PKG_LANGPACK_PATH) $(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) \ - -I$(TK_DEFINES) -I$(APP_DEFINES) $(srcdir)/generic/install.rdf -o $(DIST)/xpi-stage/$(XPI_NAME)/install.rdf) + -DTK_DEFINES=$(TK_DEFINES) -DAPP_DEFINES=$(APP_DEFINES) $(MOZILLA_DIR)/toolkit/locales/generic/install.rdf -o $(DIST)/xpi-stage/$(XPI_NAME)/install.rdf) $(call py_action,zip,-C $(DIST)/xpi-stage/locale-$(AB_CD) $(LANGPACK_FILE) install.rdf $(PKG_ZIP_DIRS) chrome.manifest) # This variable is to allow the wget-en-US target to know which ftp server to download from @@ -189,20 +190,20 @@ wget-en-US: ifndef WGET $(error Wget not installed) endif - $(NSINSTALL) -D $(_ABS_DIST)/$(PKG_PATH) - (cd $(_ABS_DIST)/$(PKG_PATH) && $(WGET) --no-cache -nv -N '$(EN_US_BINARY_URL)/$(PACKAGE)') - @echo 'Downloaded $(EN_US_BINARY_URL)/$(PACKAGE) to $(_ABS_DIST)/$(PKG_PATH)/$(PACKAGE)' + $(NSINSTALL) -D $(ABS_DIST)/$(PKG_PATH) + (cd $(ABS_DIST)/$(PKG_PATH) && $(WGET) --no-cache -nv -N '$(EN_US_BINARY_URL)/$(PACKAGE)') + @echo 'Downloaded $(EN_US_BINARY_URL)/$(PACKAGE) to $(ABS_DIST)/$(PKG_PATH)/$(PACKAGE)' ifdef RETRIEVE_WINDOWS_INSTALLER ifeq ($(OS_ARCH), WINNT) - $(NSINSTALL) -D $(_ABS_DIST)/$(PKG_INST_PATH) - (cd $(_ABS_DIST)/$(PKG_INST_PATH) && $(WGET) --no-cache -nv -N '$(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe') - @echo 'Downloaded $(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe to $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe' + $(NSINSTALL) -D $(ABS_DIST)/$(PKG_INST_PATH) + (cd $(ABS_DIST)/$(PKG_INST_PATH) && $(WGET) --no-cache -nv -N '$(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe') + @echo 'Downloaded $(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe to $(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe' endif endif generate-snippet-%: $(PYTHON) $(MOZILLA_DIR)/tools/update-packaging/generatesnippet.py \ - --mar-path=$(_ABS_DIST)/update \ + --mar-path=$(ABS_DIST)/update \ --application-ini-file=$(STAGEDIST)/application.ini \ --locale=$* \ --product=$(MOZ_PKG_APPNAME) \ diff --git a/toolkit/modules/SessionRecorder.jsm b/toolkit/modules/SessionRecorder.jsm index d741c8e66aec..8cf31abb4304 100644 --- a/toolkit/modules/SessionRecorder.jsm +++ b/toolkit/modules/SessionRecorder.jsm @@ -2,8 +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/. */ -#ifndef MERGED_COMPARTMENT - "use strict"; this.EXPORTED_SYMBOLS = [ @@ -12,8 +10,6 @@ this.EXPORTED_SYMBOLS = [ const {classes: Cc, interfaces: Ci, utils: Cu} = Components; -#endif - Cu.import("resource://gre/modules/Preferences.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Log.jsm"); diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 691eb3e86338..116e35bcbe8e 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -65,6 +65,7 @@ EXTRA_JS_MODULES += [ 'SelectContentHelper.jsm', 'SelectParentHelper.jsm', 'Services.jsm', + 'SessionRecorder.jsm', 'sessionstore/FormData.jsm', 'sessionstore/ScrollPosition.jsm', 'sessionstore/XPathGenerator.jsm', @@ -83,7 +84,6 @@ EXTRA_JS_MODULES += [ EXTRA_PP_JS_MODULES += [ 'AppConstants.jsm', - 'SessionRecorder.jsm', ] if 'Android' != CONFIG['OS_TARGET']: diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index f6cfbed8152a..1b25ca89d048 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -59,7 +59,7 @@ ifndef MOZ_THUNDERBIRD # Package mozharness $(call py_action,test_archive, \ mozharness \ - $(abspath $(DIST))/$(PKG_PATH)$(MOZHARNESS_PACKAGE)) + $(ABS_DIST)/$(PKG_PATH)$(MOZHARNESS_PACKAGE)) endif # MOZ_THUNDERBIRD ifdef MOZ_PACKAGE_JSSHELL # Package JavaScript Shell diff --git a/toolkit/mozapps/installer/upload-files.mk b/toolkit/mozapps/installer/upload-files.mk index 217ad97eb241..33633eb5f29a 100644 --- a/toolkit/mozapps/installer/upload-files.mk +++ b/toolkit/mozapps/installer/upload-files.mk @@ -46,7 +46,7 @@ STAGEPATH = universal/ endif endif -PACKAGE_BASE_DIR = $(_ABS_DIST) +PACKAGE_BASE_DIR = $(ABS_DIST) PACKAGE = $(PKG_PATH)$(PKG_BASENAME)$(PKG_SUFFIX) # By default, the SDK uses the same packaging type as the main bundle, @@ -116,8 +116,7 @@ endif # WINNT endif # MOZ_STATIC_JS MAKE_JSSHELL = $(call py_action,zip,-C $(DIST)/bin $(abspath $(PKG_JSSHELL)) $(JSSHELL_BINS)) -_ABS_DIST = $(abspath $(DIST)) -JARLOG_DIR = $(abspath $(DEPTH)/jarlog/) +JARLOG_DIR = $(topobjdir)/jarlog/ JARLOG_FILE_AB_CD = $(JARLOG_DIR)/$(AB_CD).log TAR_CREATE_FLAGS := --exclude=.mkdir.done $(TAR_CREATE_FLAGS) @@ -177,12 +176,12 @@ PKG_SUFFIX = .rpm MOZ_NUMERIC_APP_VERSION = $(shell echo $(MOZ_PKG_VERSION) | sed 's/[^0-9.].*//' ) MOZ_RPM_RELEASE = $(shell echo $(MOZ_PKG_VERSION) | sed 's/[0-9.]*//' ) -RPMBUILD_TOPDIR=$(_ABS_DIST)/rpmbuild -RPMBUILD_RPMDIR=$(_ABS_DIST) -RPMBUILD_SRPMDIR=$(_ABS_DIST) +RPMBUILD_TOPDIR=$(ABS_DIST)/rpmbuild +RPMBUILD_RPMDIR=$(ABS_DIST) +RPMBUILD_SRPMDIR=$(ABS_DIST) RPMBUILD_SOURCEDIR=$(RPMBUILD_TOPDIR)/SOURCES RPMBUILD_SPECDIR=$(topsrcdir)/toolkit/mozapps/installer/linux/rpm -RPMBUILD_BUILDDIR=$(_ABS_DIST)/.. +RPMBUILD_BUILDDIR=$(ABS_DIST)/.. SPEC_FILE = $(RPMBUILD_SPECDIR)/mozilla.spec RPM_INCIDENTALS=$(topsrcdir)/toolkit/mozapps/installer/linux/rpm @@ -194,7 +193,7 @@ RPM_CMD = \ -DMOZ_APP_DISPLAYNAME='$(MOZ_APP_DISPLAYNAME)' \ $(RPM_INCIDENTALS)/mozilla.desktop \ -o $(RPMBUILD_SOURCEDIR)/$(MOZ_APP_NAME).desktop && \ - rm -rf $(_ABS_DIST)/$(TARGET_CPU) && \ + rm -rf $(ABS_DIST)/$(TARGET_CPU) && \ $(RPMBUILD) -bb \ $(SPEC_FILE) \ --target $(TARGET_CPU) \ @@ -239,18 +238,18 @@ endif #uploaded and that they are beside the other build artifacts MAIN_RPM= $(MOZ_APP_NAME)-$(MOZ_NUMERIC_APP_VERSION)-$(MOZ_RPM_RELEASE).$(BUILDID).$(TARGET_CPU)$(PKG_SUFFIX) UPLOAD_EXTRA_FILES += $(MAIN_RPM) -RPM_CMD += && mv $(TARGET_CPU)/$(MAIN_RPM) $(_ABS_DIST)/ +RPM_CMD += && mv $(TARGET_CPU)/$(MAIN_RPM) $(ABS_DIST)/ ifdef ENABLE_TESTS TESTS_RPM=$(MOZ_APP_NAME)-tests-$(MOZ_NUMERIC_APP_VERSION)-$(MOZ_RPM_RELEASE).$(BUILDID).$(TARGET_CPU)$(PKG_SUFFIX) UPLOAD_EXTRA_FILES += $(TESTS_RPM) -RPM_CMD += && mv $(TARGET_CPU)/$(TESTS_RPM) $(_ABS_DIST)/ +RPM_CMD += && mv $(TARGET_CPU)/$(TESTS_RPM) $(ABS_DIST)/ endif ifdef INSTALL_SDK SDK_RPM=$(MOZ_APP_NAME)-devel-$(MOZ_NUMERIC_APP_VERSION)-$(MOZ_RPM_RELEASE).$(BUILDID).$(TARGET_CPU)$(PKG_SUFFIX) UPLOAD_EXTRA_FILES += $(SDK_RPM) -RPM_CMD += && mv $(TARGET_CPU)/$(SDK_RPM) $(_ABS_DIST)/ +RPM_CMD += && mv $(TARGET_CPU)/$(SDK_RPM) $(ABS_DIST)/ endif INNER_MAKE_PACKAGE = $(RPM_CMD) @@ -320,7 +319,7 @@ UPLOAD_EXTRA_FILES += gecko-unsigned-unaligned.apk DIST_FILES += $(MOZ_CHILD_PROCESS_NAME) -GECKO_APP_AP_PATH = $(abspath $(DEPTH)/mobile/android/base) +GECKO_APP_AP_PATH = $(topobjdir)/mobile/android/base ifdef ENABLE_TESTS INNER_ROBOCOP_PACKAGE=echo @@ -334,13 +333,13 @@ UPLOAD_EXTRA_FILES += ../embedding/android/geckoview_example/geckoview_example.a # Robocop/Robotium tests, Android Background tests, and Fennec need to # be signed with the same key, which means release signing them all. -ROBOCOP_PATH = $(abspath $(DEPTH)/mobile/android/tests/browser/robocop) +ROBOCOP_PATH = $(topobjdir)/mobile/android/tests/browser/robocop # 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) + 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) endif else INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you' @@ -388,9 +387,9 @@ INNER_MAKE_GECKOLIBS_AAR= \ --verbose \ --revision $(geckoaar-revision) \ --topsrcdir '$(topsrcdir)' \ - --distdir '$(_ABS_DIST)' \ + --distdir '$(ABS_DIST)' \ --appname '$(MOZ_APP_NAME)' \ - '$(_ABS_DIST)' + '$(ABS_DIST)' else INNER_MAKE_GECKOLIBS_AAR=echo 'Android geckolibs.aar packaging requires packaging geckoview' endif # MOZ_DISABLE_GECKOVIEW @@ -462,29 +461,29 @@ INNER_SZIP_LIBRARIES = \ $(if $(ALREADY_SZIPPED),,$(foreach lib,$(SZIP_LIBRARIES),host/bin/szip $(MOZ_SZIP_FLAGS) $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(lib) && )) true # Insert $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex into -# $(_ABS_DIST)/gecko.ap_, producing $(_ABS_DIST)/gecko.apk. +# $(ABS_DIST)/gecko.ap_, producing $(ABS_DIST)/gecko.apk. INNER_MAKE_APK = \ ( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \ - unzip -o $(_ABS_DIST)/gecko.ap_ && \ - rm $(_ABS_DIST)/gecko.ap_ && \ - $(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ assets && \ - $(ZIP) $(if $(ALREADY_SZIPPED),-0 ,$(if $(MOZ_ENABLE_SZIP),-0 ))$(_ABS_DIST)/gecko.ap_ $(ASSET_SO_LIBRARIES) && \ - $(ZIP) -r9D $(_ABS_DIST)/gecko.ap_ $(DIST_FILES) -x $(NON_DIST_FILES) $(SZIP_LIBRARIES) && \ + unzip -o $(ABS_DIST)/gecko.ap_ && \ + rm $(ABS_DIST)/gecko.ap_ && \ + $(ZIP) -r9D $(ABS_DIST)/gecko.ap_ assets && \ + $(ZIP) $(if $(ALREADY_SZIPPED),-0 ,$(if $(MOZ_ENABLE_SZIP),-0 ))$(ABS_DIST)/gecko.ap_ $(ASSET_SO_LIBRARIES) && \ + $(ZIP) -r9D $(ABS_DIST)/gecko.ap_ $(DIST_FILES) -x $(NON_DIST_FILES) $(SZIP_LIBRARIES) && \ $(if $(filter-out ./,$(OMNIJAR_DIR)), \ mkdir -p $(OMNIJAR_DIR) && mv $(OMNIJAR_NAME) $(OMNIJAR_DIR) && ) \ - $(ZIP) -0 $(_ABS_DIST)/gecko.ap_ $(OMNIJAR_DIR)$(OMNIJAR_NAME)) && \ - rm -f $(_ABS_DIST)/gecko.apk && \ - cp $(_ABS_DIST)/gecko.ap_ $(_ABS_DIST)/gecko.apk && \ - $(ZIP) -j0 $(_ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \ - cp $(_ABS_DIST)/gecko.apk $(_ABS_DIST)/gecko-unsigned-unaligned.apk && \ - $(RELEASE_JARSIGNER) $(_ABS_DIST)/gecko.apk && \ - $(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) + $(ZIP) -0 $(ABS_DIST)/gecko.ap_ $(OMNIJAR_DIR)$(OMNIJAR_NAME)) && \ + rm -f $(ABS_DIST)/gecko.apk && \ + cp $(ABS_DIST)/gecko.ap_ $(ABS_DIST)/gecko.apk && \ + $(ZIP) -j0 $(ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \ + cp $(ABS_DIST)/gecko.apk $(ABS_DIST)/gecko-unsigned-unaligned.apk && \ + $(RELEASE_JARSIGNER) $(ABS_DIST)/gecko.apk && \ + $(ZIPALIGN) -f -v 4 $(ABS_DIST)/gecko.apk $(PACKAGE) ifeq ($(MOZ_BUILD_APP),mobile/android) 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_ && \ + 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)) && \ @@ -498,8 +497,8 @@ endif ifeq ($(MOZ_BUILD_APP),mobile/android/b2gdroid) INNER_MAKE_PACKAGE = \ $(INNER_SZIP_LIBRARIES) && \ - cp $(abspath $(DEPTH)/mobile/android/b2gdroid/app)/classes.dex $(_ABS_DIST)/classes.dex && \ - cp $(abspath $(DEPTH)/mobile/android/b2gdroid/app)/b2gdroid-unsigned-unaligned.apk $(_ABS_DIST)/gecko.ap_ && \ + 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_ && \ $(INNER_MAKE_APK) endif @@ -526,17 +525,17 @@ PKG_DMG_SOURCE = $(STAGEPATH)$(MOZ_PKG_DIR) INNER_MAKE_PACKAGE = $(call py_action,make_dmg,'$(PKG_DMG_SOURCE)' '$(PACKAGE)') INNER_UNMAKE_PACKAGE = \ set -ex; \ - rm -rf $(_ABS_DIST)/unpack.tmp; \ - mkdir -p $(_ABS_DIST)/unpack.tmp; \ - $(_ABS_MOZSRCDIR)/build/package/mac_osx/unpack-diskimage $(UNPACKAGE) /tmp/$(MOZ_PKG_APPNAME)-unpack $(_ABS_DIST)/unpack.tmp; \ - rsync -a '$(_ABS_DIST)/unpack.tmp/$(_APPNAME)' $(MOZ_PKG_DIR); \ + rm -rf $(ABS_DIST)/unpack.tmp; \ + mkdir -p $(ABS_DIST)/unpack.tmp; \ + $(_ABS_MOZSRCDIR)/build/package/mac_osx/unpack-diskimage $(UNPACKAGE) /tmp/$(MOZ_PKG_APPNAME)-unpack $(ABS_DIST)/unpack.tmp; \ + rsync -a '$(ABS_DIST)/unpack.tmp/$(_APPNAME)' $(MOZ_PKG_DIR); \ test -n '$(MOZ_PKG_MAC_DSSTORE)' && \ - rsync -a '$(_ABS_DIST)/unpack.tmp/.DS_Store' '$(MOZ_PKG_MAC_DSSTORE)'; \ + rsync -a '$(ABS_DIST)/unpack.tmp/.DS_Store' '$(MOZ_PKG_MAC_DSSTORE)'; \ test -n '$(MOZ_PKG_MAC_BACKGROUND)' && \ - rsync -a '$(_ABS_DIST)/unpack.tmp/.background/$(notdir $(MOZ_PKG_MAC_BACKGROUND))' '$(MOZ_PKG_MAC_BACKGROUND)'; \ + rsync -a '$(ABS_DIST)/unpack.tmp/.background/$(notdir $(MOZ_PKG_MAC_BACKGROUND))' '$(MOZ_PKG_MAC_BACKGROUND)'; \ test -n '$(MOZ_PKG_MAC_ICON)' && \ - rsync -a '$(_ABS_DIST)/unpack.tmp/.VolumeIcon.icns' '$(MOZ_PKG_MAC_ICON)'; \ - rm -rf $(_ABS_DIST)/unpack.tmp; \ + rsync -a '$(ABS_DIST)/unpack.tmp/.VolumeIcon.icns' '$(MOZ_PKG_MAC_ICON)'; \ + rm -rf $(ABS_DIST)/unpack.tmp; \ if test -n '$(MOZ_PKG_MAC_RSRC)' ; then \ cp $(UNPACKAGE) $(MOZ_PKG_APPNAME).tmp.dmg && \ hdiutil unflatten $(MOZ_PKG_APPNAME).tmp.dmg && \ @@ -556,7 +555,7 @@ endif ifdef MOZ_INTERNAL_SIGNING_FORMAT MOZ_SIGN_PREPARED_PACKAGE_CMD=$(MOZ_SIGN_CMD) $(foreach f,$(MOZ_INTERNAL_SIGNING_FORMAT),-f $(f)) $(foreach i,$(SIGN_INCLUDES),-i $(i)) $(foreach x,$(SIGN_EXCLUDES),-x $(x)) ifeq (WINNT,$(OS_ARCH)) -MOZ_SIGN_PREPARED_PACKAGE_CMD += --nsscmd '$(_ABS_DIST)/bin/shlibsign$(BIN_SUFFIX) -v -i' +MOZ_SIGN_PREPARED_PACKAGE_CMD += --nsscmd '$(ABS_DIST)/bin/shlibsign$(BIN_SUFFIX) -v -i' endif endif diff --git a/toolkit/mozapps/update/tests/Makefile.in b/toolkit/mozapps/update/tests/Makefile.in index 1a8baec0838b..c96aebe47082 100644 --- a/toolkit/mozapps/update/tests/Makefile.in +++ b/toolkit/mozapps/update/tests/Makefile.in @@ -2,8 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -XPCSHELLTESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/$(relativesrcdir) -CHROMETESTROOT = $(abspath $(DEPTH))/_tests/testing/mochitest/chrome/$(relativesrcdir) +XPCSHELLTESTROOT = $(topobjdir)/_tests/xpcshell/$(relativesrcdir) +CHROMETESTROOT = $(topobjdir)/_tests/testing/mochitest/chrome/$(relativesrcdir) pp_const_file = $(srcdir)/data/xpcshellConstantsPP.js diff --git a/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in b/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in index 7b16d18eeb5b..9f49cdc40a9c 100644 --- a/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in +++ b/toolkit/mozapps/update/updater/updater-xpcshell/Makefile.in @@ -5,8 +5,8 @@ # For changes here, also consider ../Makefile.in -XPCSHELLTESTROOT = $(abspath $(DEPTH))/_tests/xpcshell/toolkit/mozapps/update/tests -MOCHITESTROOT = $(abspath $(DEPTH))/_tests/testing/mochitest/chrome/toolkit/mozapps/update/tests +XPCSHELLTESTROOT = $(topobjdir)/_tests/xpcshell/toolkit/mozapps/update/tests +MOCHITESTROOT = $(topobjdir)/_tests/testing/mochitest/chrome/toolkit/mozapps/update/tests include $(topsrcdir)/config/rules.mk diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp index 3381da012fb3..ea85e8ca7f12 100644 --- a/toolkit/xre/test/win/TestDllInterceptor.cpp +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp @@ -159,6 +159,9 @@ int main() TestHook("gdi32.dll", "CreateDIBSection") && TestHook("kernel32.dll", "CreateFileW") && #endif + TestHook("imm32.dll", "ImmGetContext") && + TestHook("imm32.dll", "ImmGetCompositionStringW") && + TestHook("imm32.dll", "ImmSetCandidateWindow") && TestDetour("ntdll.dll", "LdrLoadDll")) { printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n"); return 0; diff --git a/tools/mercurial/hgsetup/wizard.py b/tools/mercurial/hgsetup/wizard.py index cb64d50ce7ca..f4eecb9fc099 100644 --- a/tools/mercurial/hgsetup/wizard.py +++ b/tools/mercurial/hgsetup/wizard.py @@ -42,6 +42,8 @@ are up to date and you won't have to do anything. To begin, press the enter/return key. '''.strip() +# This should match MODERN_MERCURIAL_VERSION in +# python/mozboot/mozboot/base.py. OLDEST_NON_LEGACY_VERSION = LooseVersion('3.5.2') LEGACY_MERCURIAL = ''' You are running an out of date Mercurial client (%s). diff --git a/tools/update-packaging/Makefile.in b/tools/update-packaging/Makefile.in index 74d1d85db40c..7c55958b62aa 100644 --- a/tools/update-packaging/Makefile.in +++ b/tools/update-packaging/Makefile.in @@ -11,7 +11,7 @@ STANDALONE_MAKEFILE := 1 PACKAGE_BASE_DIR = $(DIST) # Default output location for update archive -STAGE_DIR = $(abspath $(DIST)/$(PKG_UPDATE_PATH)) +STAGE_DIR = $(ABS_DIST)/$(PKG_UPDATE_PATH) ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) ifdef UNIVERSAL_BINARY @@ -35,7 +35,7 @@ full-update:: complete-patch ifeq ($(OS_TARGET), WINNT) MOZ_PKG_FORMAT := SFX7Z -UNPACKAGE = '$(subst $(DIST),$(_ABS_DIST),$(INSTALLER_PACKAGE))' +UNPACKAGE = '$(subst $(DIST),$(ABS_DIST),$(INSTALLER_PACKAGE))' ifdef AB_CD UNPACKAGE = '$(PACKAGE_BASE_DIR)/$(PACKAGE)' endif diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 4e2c92fcba87..cb2059679c8e 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -408,7 +408,7 @@ static nsresult GetDownloadDirectory(nsIFile **_directory, // creating. Note that Creating directories with specified permission only // supported on Unix platform right now. That's why above if exists. - PRUint32 permissions; + uint32_t permissions; rv = dir->GetPermissions(&permissions); NS_ENSURE_SUCCESS(rv, rv); diff --git a/widget/ContentCache.cpp b/widget/ContentCache.cpp index fb3767cab9e9..af4c00c67d03 100644 --- a/widget/ContentCache.cpp +++ b/widget/ContentCache.cpp @@ -497,6 +497,17 @@ ContentCacheInParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent, ("ContentCacheInParent: 0x%p HandleQueryContentEvent(" "aEvent={ mMessage=eQuerySelectedText }, aWidget=0x%p)", this, aWidget)); + if (aWidget->PluginHasFocus()) { + MOZ_LOG(sContentCacheLog, LogLevel::Info, + ("ContentCacheInParent: 0x%p HandleQueryContentEvent(), " + "return emtpy selection becasue plugin has focus", + this)); + aEvent.mSucceeded = true; + aEvent.mReply.mOffset = 0; + aEvent.mReply.mReversed = false; + aEvent.mReply.mHasSelection = false; + return true; + } if (NS_WARN_IF(!IsSelectionValid())) { // If content cache hasn't been initialized properly, make the query // failed. @@ -835,7 +846,12 @@ ContentCacheInParent::OnCompositionEvent(const WidgetCompositionEvent& aEvent) // We must be able to simulate the selection because // we might not receive selection updates in time if (!mIsComposing) { - mCompositionStart = mSelection.StartOffset(); + if (aEvent.widget && aEvent.widget->PluginHasFocus()) { + // If focus is on plugin, we cannot get selection range + mCompositionStart = 0; + } else { + mCompositionStart = mSelection.StartOffset(); + } } mIsComposing = !aEvent.CausesDOMCompositionEndEvent(); diff --git a/widget/MiscEvents.h b/widget/MiscEvents.h index 4349dd786b12..c2af44b5b59e 100644 --- a/widget/MiscEvents.h +++ b/widget/MiscEvents.h @@ -15,6 +15,11 @@ namespace mozilla { +namespace dom { + class PBrowserParent; + class PBrowserChild; +} // namespace dom + /****************************************************************************** * mozilla::WidgetContentCommandEvent ******************************************************************************/ @@ -142,6 +147,10 @@ public: class WidgetPluginEvent : public WidgetGUIEvent { +private: + friend class dom::PBrowserParent; + friend class dom::PBrowserChild; + public: virtual WidgetPluginEvent* AsPluginEvent() override { return this; } @@ -175,6 +184,11 @@ public: retargetToFocusedDocument = aEvent.retargetToFocusedDocument; } + +protected: + WidgetPluginEvent() + { + } }; } // namespace mozilla diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index f9e6cda21a51..829bc7789dc4 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -687,6 +687,15 @@ PuppetWidget::SetPluginFocused(bool& aFocused) return NS_OK; } +void +PuppetWidget::DefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) +{ + if (!mTabChild) { + return; + } + mTabChild->SendDefaultProcOfPluginEvent(aEvent); +} + NS_IMETHODIMP_(void) PuppetWidget::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) @@ -1404,5 +1413,15 @@ PuppetWidget::GetCurrentWidgetListener() return mAttachedWidgetListener; } +void +PuppetWidget::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +{ + if (!mTabChild) { + return; + } + + mTabChild->SendSetCandidateWindowForPlugin(aX, aY); +} + } // namespace widget } // namespace mozilla diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 931212faf207..288941d8ac9f 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -220,6 +220,8 @@ public: nsString& aCommitted) override; NS_IMETHOD SetPluginFocused(bool& aFocused) override; + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override; virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, int32_t aNativeKeyCode, @@ -254,6 +256,9 @@ public: virtual uint32_t GetMaxTouchPoints() const override; virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override; + + virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) override; + protected: virtual nsresult NotifyIMEInternal( const IMENotification& aIMENotification) override; diff --git a/widget/TextRange.h b/widget/TextRange.h index 122cde91a722..e85a0e584119 100644 --- a/widget/TextRange.h +++ b/widget/TextRange.h @@ -256,6 +256,26 @@ public: ElementAt(i).RemoveCharacter(aOffset); } } + + bool HasCaret() const + { + for (const TextRange& range : *this) { + if (range.mRangeType == NS_TEXTRANGE_CARETPOSITION) { + return true; + } + } + return false; + } + + uint32_t GetCaretPosition() const + { + for (const TextRange& range : *this) { + if (range.mRangeType == NS_TEXTRANGE_CARETPOSITION) { + return range.mStartOffset; + } + } + return UINT32_MAX; + } }; } // namespace mozilla diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index 0c7740c7ceb5..983c5e330909 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -2148,20 +2148,20 @@ Object::LocalRef AndroidBridge::ChannelCreate(Object::Param stream) { JNIEnv* const env = GetEnvForThread(); auto rv = Object::LocalRef::Adopt(env, env->CallStaticObjectMethod( sBridge->jChannels, sBridge->jChannelCreate, stream.Get())); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); return rv; } void AndroidBridge::InputStreamClose(Object::Param obj) { JNIEnv* const env = GetEnvForThread(); env->CallVoidMethod(obj.Get(), sBridge->jClose); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); } uint32_t AndroidBridge::InputStreamAvailable(Object::Param obj) { JNIEnv* const env = GetEnvForThread(); auto rv = env->CallIntMethod(obj.Get(), sBridge->jAvailable); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); return rv; } diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 410e6af75345..66073b9f8bb0 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -561,7 +561,7 @@ public: bool CheckForException() { if (mJNIEnv->ExceptionCheck()) { - jni::HandleUncaughtException(mJNIEnv); + MOZ_CATCH_JNI_EXCEPTION(mJNIEnv); return true; } return false; diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp index 77cffdbda4ea..f5e88c785303 100644 --- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -449,9 +449,9 @@ auto GeckoAppShell::HandleGeckoMessageWrapper(mozilla::jni::Object::Param a0) -> constexpr char GeckoAppShell::HandleUncaughtException_t::name[]; constexpr char GeckoAppShell::HandleUncaughtException_t::signature[]; -auto GeckoAppShell::HandleUncaughtException(mozilla::jni::Object::Param a0, mozilla::jni::Throwable::Param a1) -> void +auto GeckoAppShell::HandleUncaughtException(mozilla::jni::Throwable::Param a0) -> mozilla::jni::String::LocalRef { - return mozilla::jni::Method::Call(nullptr, nullptr, a0, a1); + return mozilla::jni::Method::Call(nullptr, nullptr, a0); } constexpr char GeckoAppShell::HideProgressDialog_t::name[]; diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h index 677d01f4d016..c95566dfae13 100644 --- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -1084,21 +1084,20 @@ public: public: struct HandleUncaughtException_t { typedef GeckoAppShell Owner; - typedef void ReturnType; - typedef void SetterType; + typedef mozilla::jni::String::LocalRef ReturnType; + typedef mozilla::jni::String::Param SetterType; typedef mozilla::jni::Args< - mozilla::jni::Object::Param, mozilla::jni::Throwable::Param> Args; static constexpr char name[] = "handleUncaughtException"; static constexpr char signature[] = - "(Ljava/lang/Thread;Ljava/lang/Throwable;)V"; + "(Ljava/lang/Throwable;)Ljava/lang/String;"; static const bool isStatic = true; static const bool isMultithreaded = true; static const mozilla::jni::ExceptionMode exceptionMode = mozilla::jni::ExceptionMode::IGNORE; }; - static auto HandleUncaughtException(mozilla::jni::Object::Param, mozilla::jni::Throwable::Param) -> void; + static auto HandleUncaughtException(mozilla::jni::Throwable::Param) -> mozilla::jni::String::LocalRef; public: struct HideProgressDialog_t { diff --git a/widget/android/jni/Accessors.h b/widget/android/jni/Accessors.h index e3a73f449890..21129c7c0b29 100644 --- a/widget/android/jni/Accessors.h +++ b/widget/android/jni/Accessors.h @@ -72,10 +72,10 @@ protected: static void EndAccess(JNIEnv* env, nsresult* rv) { if (Traits::exceptionMode == ExceptionMode::ABORT) { - return HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); } else if (Traits::exceptionMode == ExceptionMode::NSRESULT) { - return GetNsresult(env, rv); + GetNsresult(env, rv); } } }; diff --git a/widget/android/jni/Natives.h b/widget/android/jni/Natives.h index d65d7f5a88c2..459b353475b7 100644 --- a/widget/android/jni/Natives.h +++ b/widget/android/jni/Natives.h @@ -107,7 +107,7 @@ struct NativePtr Clear(instance); SetNativeHandle(instance.Env(), instance.Get(), reinterpret_cast(ptr.release())); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); } template @@ -115,11 +115,11 @@ struct NativePtr { UniquePtr ptr(reinterpret_cast( GetNativeHandle(instance.Env(), instance.Get()))); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); if (ptr) { SetNativeHandle(instance.Env(), instance.Get(), 0); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); } } }; @@ -155,7 +155,7 @@ struct NativePtr Clear(instance); SetNativeHandle(instance.Env(), instance.Get(), reinterpret_cast(new WeakPtr(ptr))); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); } template @@ -163,11 +163,11 @@ struct NativePtr { const auto ptr = reinterpret_cast*>( GetNativeHandle(instance.Env(), instance.Get())); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); if (ptr) { SetNativeHandle(instance.Env(), instance.Get(), 0); - HandleUncaughtException(instance.Env()); + MOZ_CATCH_JNI_EXCEPTION(instance.Env()); delete ptr; } } @@ -328,7 +328,7 @@ class ProxyNativeCall mozilla::IndexSequence) const { Impl* const impl = NativePtr::Get(inst); - HandleUncaughtException(inst.Env()); + MOZ_CATCH_JNI_EXCEPTION(inst.Env()); (impl->*mNativeCall)(inst, mozilla::Get(mArgs)...); } @@ -338,7 +338,7 @@ class ProxyNativeCall mozilla::IndexSequence) const { Impl* const impl = NativePtr::Get(inst); - HandleUncaughtException(inst.Env()); + MOZ_CATCH_JNI_EXCEPTION(inst.Env()); (impl->*mNativeCall)(mozilla::Get(mArgs)...); } diff --git a/widget/android/jni/Refs.h b/widget/android/jni/Refs.h index 867add4c4ea2..c713b8b6657a 100644 --- a/widget/android/jni/Refs.h +++ b/widget/android/jni/Refs.h @@ -571,7 +571,7 @@ public: MOZ_ASSERT(ObjectArray::mInstance); JNIEnv* const env = GetEnvForThread(); const size_t ret = env->GetArrayLength(jarray(ObjectArray::mInstance)); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); return ret; } @@ -581,7 +581,7 @@ public: JNIEnv* const env = GetEnvForThread(); auto ret = Object::LocalRef::Adopt(env, env->GetObjectArrayElement( jobjectArray(ObjectArray::mInstance), jsize(index))); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); return ret; } @@ -597,7 +597,7 @@ public: array.AppendElement(Object::LocalRef::Adopt( env, env->GetObjectArrayElement( jobjectArray(ObjectArray::mInstance), i))); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); } return array; } @@ -613,7 +613,7 @@ public: JNIEnv* const env = GetEnvForThread(); env->SetObjectArrayElement(jobjectArray(ObjectArray::mInstance), jsize(index), element.Get()); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); } }; @@ -677,7 +677,7 @@ private: const jstring result = env->NewString( reinterpret_cast(str.BeginReading()), str.Length()); - HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); return result; } diff --git a/widget/android/jni/Utils.cpp b/widget/android/jni/Utils.cpp index 0feeb7a74b55..0b0f57eb4ae9 100644 --- a/widget/android/jni/Utils.cpp +++ b/widget/android/jni/Utils.cpp @@ -8,6 +8,10 @@ #include "AndroidBridge.h" #include "GeneratedJNIWrappers.h" +#ifdef MOZ_CRASHREPORTER +#include "nsExceptionHandler.h" +#endif + namespace mozilla { namespace jni { @@ -129,23 +133,34 @@ bool ThrowException(JNIEnv *aEnv, const char *aClass, return !aEnv->ThrowNew(cls.Get(), aMessage); } -void HandleUncaughtException(JNIEnv *aEnv) +bool HandleUncaughtException(JNIEnv* aEnv) { MOZ_ASSERT(aEnv, "Invalid thread JNI env"); if (!aEnv->ExceptionCheck()) { - return; + return false; } +#ifdef DEBUG + aEnv->ExceptionDescribe(); +#endif + Throwable::LocalRef e = Throwable::LocalRef::Adopt(aEnv->ExceptionOccurred()); MOZ_ASSERT(e); aEnv->ExceptionClear(); - widget::GeckoAppShell::HandleUncaughtException(nullptr, e); + String::LocalRef stack = widget::GeckoAppShell::HandleUncaughtException(e); - // Should be dead by now... - MOZ_CRASH("Failed to handle uncaught exception"); +#ifdef MOZ_CRASHREPORTER + if (stack) { + // GeckoAppShell wants us to annotate and trigger the crash reporter. + CrashReporter::AnnotateCrashReport( + NS_LITERAL_CSTRING("AuxiliaryJavaStack"), nsCString(stack)); + } +#endif // MOZ_CRASHREPORTER + + return true; } namespace { diff --git a/widget/android/jni/Utils.h b/widget/android/jni/Utils.h index fb69f1bef826..1e8c0d44b785 100644 --- a/widget/android/jni/Utils.h +++ b/widget/android/jni/Utils.h @@ -53,7 +53,14 @@ inline bool ThrowException(const char *aMessage) return ThrowException(GetEnvForThread(), aMessage); } -void HandleUncaughtException(JNIEnv *aEnv); +bool HandleUncaughtException(JNIEnv* aEnv); + +#define MOZ_CATCH_JNI_EXCEPTION(env) \ + do { \ + if (mozilla::jni::HandleUncaughtException((env))) { \ + MOZ_CRASH("JNI exception"); \ + } \ + } while (0) uintptr_t GetNativeHandle(JNIEnv* env, jobject instance); diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 08363755b0f2..fc1c96730800 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -183,7 +183,7 @@ public: const auto natives = reinterpret_cast< mozilla::WeakPtr*>( jni::GetNativeHandle(env, thisArg.Get())); - jni::HandleUncaughtException(env); + MOZ_CATCH_JNI_EXCEPTION(env); // The call is stale if the nsWindow has been destroyed on the // Gecko side, but the Java object is still attached to it through diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index db52c1a33ba3..04cc0647de46 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -217,6 +217,12 @@ public: { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD SetPluginFocused(bool& aFocused) override { return NS_ERROR_NOT_IMPLEMENTED; } + virtual void SetCandidateWindowForPlugin(int32_t aX, + int32_t aY) override + { } + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override + { } NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) override { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD_(bool) ExecuteNativeKeyBinding( NativeKeyBindingsType aType, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 8129263c84cd..b8a9a894b605 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -133,8 +133,8 @@ typedef void* nsNativeWidget; #endif #define NS_IWIDGET_IID \ -{ 0xaaa79c8d, 0xc99d, 0x4fe1, \ - { 0xa5, 0x11, 0xd3, 0xeb, 0xb1, 0x61, 0x9e, 0x26 } } +{ 0x73c0a475, 0x450f, 0x4202, \ + { 0xab, 0xb4, 0x62, 0xf8, 0x9d, 0xbe, 0xf7, 0x9a } } /* * Window shadow styles @@ -1791,6 +1791,25 @@ public: */ NS_IMETHOD SetPluginFocused(bool& aFocused) = 0; + /* + * Tell the plugin has focus. It is unnecessary to use IPC + */ + bool PluginHasFocus() + { + return GetInputContext().mIMEState.mEnabled == IMEState::PLUGIN; + } + + /** + * Set IME candidate window position by windowless plugin. + */ + virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) = 0; + + /** + * Handle default action when PluginEvent isn't handled + */ + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) = 0; + /* * Notifies the input context changes. */ diff --git a/widget/windows/IMMHandler.cpp b/widget/windows/IMMHandler.cpp index 8c5b04a7b305..9eed50ac7f31 100644 --- a/widget/windows/IMMHandler.cpp +++ b/widget/windows/IMMHandler.cpp @@ -585,7 +585,8 @@ IMMHandler::MaybeAdjustCompositionFont(nsWindow* aWindow, // Like Navi-Bar of ATOK, some IMEs may require proper composition font even // before sending WM_IME_STARTCOMPOSITION. IMEContext context(aWindow); - gIMMHandler->AdjustCompositionFont(context, aWritingMode, aForceUpdate); + gIMMHandler->AdjustCompositionFont(aWindow, context, aWritingMode, + aForceUpdate); } // static @@ -623,10 +624,13 @@ IMMHandler::ProcessMessage(nsWindow* aWindow, // if the new window handle is not focused, probably, we should not start // the composition, however, such case should not be, it's just bad scenario. - // When a plug-in has focus or compsition, we should dispatch the IME events - // to the plug-in. - if (aWindow->PluginHasFocus() || IsComposingOnPlugin()) { - return ProcessMessageForPlugin(aWindow, msg, wParam, lParam, aResult); + // When a plug-in has focus, we should dispatch the IME events to + // the plug-in at first. + if (aWindow->PluginHasFocus()) { + bool ret = false; + if (ProcessMessageForPlugin(aWindow, msg, wParam, lParam, ret, aResult)) { + return ret; + } } aResult.mResult = 0; @@ -671,6 +675,7 @@ IMMHandler::ProcessMessageForPlugin(nsWindow* aWindow, UINT msg, WPARAM& wParam, LPARAM& lParam, + bool& aRet, MSGResult& aResult) { aResult.mResult = 0; @@ -679,38 +684,35 @@ IMMHandler::ProcessMessageForPlugin(nsWindow* aWindow, case WM_INPUTLANGCHANGEREQUEST: case WM_INPUTLANGCHANGE: aWindow->DispatchPluginEvent(msg, wParam, lParam, false); - return ProcessInputLangChangeMessage(aWindow, wParam, lParam, aResult); - case WM_IME_COMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMECompositionOnPlugin(aWindow, wParam, lParam, - aResult); - case WM_IME_STARTCOMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMEStartCompositionOnPlugin(aWindow, wParam, - lParam, aResult); - case WM_IME_ENDCOMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMEEndCompositionOnPlugin(aWindow, wParam, lParam, - aResult); + aRet = ProcessInputLangChangeMessage(aWindow, wParam, lParam, aResult); + return true; case WM_IME_CHAR: EnsureHandlerInstance(); - return gIMMHandler->OnIMECharOnPlugin(aWindow, wParam, lParam, aResult); + aRet = gIMMHandler->OnIMECharOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_IME_SETCONTEXT: - return OnIMESetContextOnPlugin(aWindow, wParam, lParam, aResult); + aRet = OnIMESetContextOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_CHAR: if (!gIMMHandler) { - return false; + return true; } - return gIMMHandler->OnCharOnPlugin(aWindow, wParam, lParam, aResult); + aRet = gIMMHandler->OnCharOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_IME_COMPOSITIONFULL: case WM_IME_CONTROL: case WM_IME_KEYDOWN: case WM_IME_KEYUP: - case WM_IME_REQUEST: case WM_IME_SELECT: aResult.mConsumed = aWindow->DispatchPluginEvent(msg, wParam, lParam, false); + aRet = true; return true; + case WM_IME_REQUEST: + // Our plugin implementation is alwasy OOP. So WM_IME_REQUEST doesn't + // allow that parameter is pointer and shouldn't handle into Gecko. + aRet = false; + return true; } return false; } @@ -772,9 +774,6 @@ IMMHandler::OnIMEComposition(nsWindow* aWindow, GetBoolName(lParam & GCS_COMPATTR), GetBoolName(lParam & GCS_COMPCLAUSE), GetBoolName(lParam & GCS_CURSORPOS))); - MOZ_ASSERT(!aWindow->PluginHasFocus(), - "OnIMEComposition should not be called when a plug-in has focus"); - IMEContext context(aWindow); aResult.mConsumed = HandleComposition(aWindow, context, lParam); return true; @@ -1089,11 +1088,10 @@ IMMHandler::OnChar(nsWindow* aWindow, * message handlers for plug-in ****************************************************************************/ -bool +void IMMHandler::OnIMEStartCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMEStartCompositionOnPlugin, hWnd=%08x, mIsComposingOnPlugin=%s", @@ -1104,18 +1102,13 @@ IMMHandler::OnIMEStartCompositionOnPlugin(nsWindow* aWindow, SetIMERelatedWindowsPosOnPlugin(aWindow, context); // On widnowless plugin, we should assume that the focused editor is always // in horizontal writing mode. - AdjustCompositionFont(context, WritingMode()); - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_STARTCOMPOSITION, wParam, lParam, - false); - return true; + AdjustCompositionFont(aWindow, context, WritingMode()); } -bool +void IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMECompositionOnPlugin, hWnd=%08x, lParam=%08x, " @@ -1129,6 +1122,7 @@ IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, if (IS_COMMITTING_LPARAM(lParam)) { mIsComposingOnPlugin = false; mComposingWindow = nullptr; + return; } // Continue composition if there is still a string being composed. if (IS_COMPOSING_LPARAM(lParam)) { @@ -1137,16 +1131,12 @@ IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, IMEContext context(aWindow); SetIMERelatedWindowsPosOnPlugin(aWindow, context); } - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_COMPOSITION, wParam, lParam, true); - return true; } -bool +void IMMHandler::OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMEEndCompositionOnPlugin, hWnd=%08x, mIsComposingOnPlugin=%s", @@ -1159,11 +1149,6 @@ IMMHandler::OnIMEEndCompositionOnPlugin(nsWindow* aWindow, ::DestroyCaret(); mNativeCaretIsCreated = false; } - - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_ENDCOMPOSITION, wParam, lParam, - false); - return true; } bool @@ -1232,6 +1217,12 @@ IMMHandler::OnCharOnPlugin(nsWindow* aWindow, LPARAM lParam, MSGResult& aResult) { + NS_WARNING("OnCharOnPlugin"); + if (mIsComposing) { + aWindow->NotifyIME(REQUEST_TO_COMMIT_COMPOSITION); + return true; + } + // We should never consume char message on windowless plugin. aResult.mConsumed = false; if (IsIMECharRecordsEmpty()) { @@ -1264,8 +1255,6 @@ IMMHandler::HandleStartComposition(nsWindow* aWindow, { NS_PRECONDITION(!mIsComposing, "HandleStartComposition is called but mIsComposing is TRUE"); - NS_PRECONDITION(!aWindow->PluginHasFocus(), - "HandleStartComposition should not be called when a plug-in has focus"); Selection& selection = GetSelection(); if (!selection.EnsureValidSelection(aWindow)) { @@ -1275,7 +1264,7 @@ IMMHandler::HandleStartComposition(nsWindow* aWindow, return; } - AdjustCompositionFont(aContext, selection.mWritingMode); + AdjustCompositionFont(aWindow, aContext, selection.mWritingMode); mCompositionStart = selection.mOffset; mCursorPosition = NO_IME_CARET; @@ -1298,9 +1287,6 @@ IMMHandler::HandleComposition(nsWindow* aWindow, const IMEContext& aContext, LPARAM lParam) { - NS_PRECONDITION(!aWindow->PluginHasFocus(), - "HandleComposition should not be called when a plug-in has focus"); - // for bug #60050 // MS-IME 95/97/98/2000 may send WM_IME_COMPOSITION with non-conversion // mode before it send WM_IME_STARTCOMPOSITION. @@ -1541,8 +1527,6 @@ IMMHandler::HandleEndComposition(nsWindow* aWindow, { MOZ_ASSERT(mIsComposing, "HandleEndComposition is called but mIsComposing is FALSE"); - MOZ_ASSERT(!aWindow->PluginHasFocus(), - "HandleComposition should not be called when a plug-in has focus"); MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: HandleEndComposition(aWindow=0x%p, aCommitString=0x%p (\"%s\"))", @@ -1848,9 +1832,8 @@ IMMHandler::CommitCompositionOnPreviousWindow(nsWindow* aWindow) } MOZ_LOG(gIMMLog, LogLevel::Info, - ("IMM: CommitCompositionOnPreviousWindow, mIsComposing=%s, " - "mIsComposingOnPlugin=%s", - GetBoolName(mIsComposing), GetBoolName(mIsComposingOnPlugin))); + ("IMM: CommitCompositionOnPreviousWindow, mIsComposing=%s", + GetBoolName(mIsComposing))); // If we have composition, we should dispatch composition events internally. if (mIsComposing) { @@ -1861,9 +1844,7 @@ IMMHandler::CommitCompositionOnPreviousWindow(nsWindow* aWindow) return true; } - // XXX When plug-in has composition, we should commit composition on the - // plug-in. However, we need some more work for that. - return mIsComposingOnPlugin; + return false; } static uint32_t @@ -2531,7 +2512,8 @@ SetVerticalFontToLogFont(const nsAString& aFontFace, } void -IMMHandler::AdjustCompositionFont(const IMEContext& aContext, +IMMHandler::AdjustCompositionFont(nsWindow* aWindow, + const IMEContext& aContext, const WritingMode& aWritingMode, bool aForceUpdate) { @@ -2617,8 +2599,8 @@ IMMHandler::AdjustCompositionFont(const IMEContext& aContext, logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logFont.lfPitchAndFamily = DEFAULT_PITCH; - if (!mIsComposingOnPlugin && - aWritingMode.IsVertical() && IsVerticalWritingSupported()) { + if (!aWindow->PluginHasFocus() && + aWritingMode.IsVertical() && IsVerticalWritingSupported()) { SetVerticalFontToLogFont( IsJapanist2003Active() ? sCompositionFontForJapanist2003 : sCompositionFont, logFont); @@ -2759,6 +2741,41 @@ IMMHandler::OnKeyDownEvent(nsWindow* aWindow, } } +// static +void +IMMHandler::SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm) +{ + IMEContext context(aWindow); + ImmSetCandidateWindow(context.get(), aForm); +} + +// staitc +void +IMMHandler::DefaultProcOfPluginEvent(nsWindow* aWindow, const NPEvent* aEvent) +{ + switch (aEvent->event) { + case WM_IME_STARTCOMPOSITION: + EnsureHandlerInstance(); + gIMMHandler->OnIMEStartCompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + break; + + case WM_IME_COMPOSITION: + if (gIMMHandler) { + gIMMHandler->OnIMECompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + } + break; + + case WM_IME_ENDCOMPOSITION: + if (gIMMHandler) { + gIMMHandler->OnIMEEndCompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + } + break; + } +} + /****************************************************************************** * IMMHandler::Selection ******************************************************************************/ diff --git a/widget/windows/IMMHandler.h b/widget/windows/IMMHandler.h index 8bd3bda4ca64..fea5c5c1b1a4 100644 --- a/widget/windows/IMMHandler.h +++ b/widget/windows/IMMHandler.h @@ -15,6 +15,7 @@ #include "mozilla/EventForwards.h" #include "nsRect.h" #include "WritingModes.h" +#include "npapi.h" class nsWindow; @@ -118,7 +119,7 @@ public: MSGResult& aResult); static bool IsComposing() { - return IsComposingOnOurEditor() || IsComposingOnPlugin(); + return IsComposingOnOurEditor(); } static bool IsComposingOn(nsWindow* aWindow) { @@ -150,6 +151,9 @@ public: // IME. Otherwise, NS_OK. static nsresult OnMouseButtonEvent(nsWindow* aWindow, const IMENotification& aIMENotification); + static void SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm); + static void DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aEvent); protected: static void EnsureHandlerInstance(); @@ -180,7 +184,7 @@ protected: MSGResult& aResult); static bool ProcessMessageForPlugin(nsWindow* aWindow, UINT msg, WPARAM &wParam, LPARAM &lParam, - MSGResult& aResult); + bool &aRet, MSGResult& aResult); IMMHandler(); ~IMMHandler(); @@ -191,16 +195,15 @@ protected: MSGResult& aResult); bool OnIMEStartComposition(nsWindow* aWindow, MSGResult& aResult); - bool OnIMEStartCompositionOnPlugin(nsWindow* aWindow, - WPARAM wParam, LPARAM lParam, - MSGResult& aResult); + void OnIMEStartCompositionOnPlugin(nsWindow* aWindow, + WPARAM wParam, LPARAM lParam); bool OnIMEComposition(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, MSGResult& aResult); - bool OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, - MSGResult& aResult); + void OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, + LPARAM lParam); bool OnIMEEndComposition(nsWindow* aWindow, MSGResult& aResult); - bool OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, MSGResult& aResult); + void OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, + LPARAM lParam); bool OnIMERequest(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, MSGResult& aResult); bool OnIMECharOnPlugin(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, @@ -326,7 +329,8 @@ protected: * If aForceUpdate is true, it will update composition font even if writing * mode isn't being changed. */ - void AdjustCompositionFont(const IMEContext& aContext, + void AdjustCompositionFont(nsWindow* aWindow, + const IMEContext& aContext, const mozilla::WritingMode& aWritingMode, bool aForceUpdate = false); diff --git a/widget/windows/WinIMEHandler.cpp b/widget/windows/WinIMEHandler.cpp index bb719ab6b30a..97880fba0c72 100644 --- a/widget/windows/WinIMEHandler.cpp +++ b/widget/windows/WinIMEHandler.cpp @@ -948,5 +948,27 @@ IMEHandler::GetOnScreenKeyboardWindow() return nullptr; } +// static +void +IMEHandler::SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm) +{ + if (!sPluginHasFocus) { + return; + } + + IMMHandler::SetCandidateWindow(aWindow, aForm); +} + +// static +void +IMEHandler::DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aPluginEvent) +{ + if (!sPluginHasFocus) { + return; + } + IMMHandler::DefaultProcOfPluginEvent(aWindow, aPluginEvent); +} + } // namespace widget } // namespace mozilla diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h index 405c70f96775..9a6d8f87715d 100644 --- a/widget/windows/WinIMEHandler.h +++ b/widget/windows/WinIMEHandler.h @@ -8,6 +8,7 @@ #include "nscore.h" #include "nsIWidget.h" +#include "npapi.h" #include #include @@ -103,6 +104,17 @@ public: */ static void InitInputContext(nsWindow* aWindow, InputContext& aInputContext); + /* + * For windowless plugin helper. + */ + static void SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm); + + /* + * For WM_IME_*COMPOSITION messages and e10s with windowless plugin + */ + static void DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aPluginEvent); + #ifdef DEBUG /** * Returns true when current keyboard layout has IME. Otherwise, false. diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 51b70566b69b..2397e3aba14f 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -7751,6 +7751,39 @@ nsWindow::ComputeShouldAccelerate() return nsBaseWidget::ComputeShouldAccelerate(); } +void +nsWindow::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +{ + CANDIDATEFORM form; + form.dwIndex = 0; + form.dwStyle = CFS_CANDIDATEPOS; + form.ptCurrentPos.x = aX; + form.ptCurrentPos.y = aY; + + IMEHandler::SetCandidateWindow(this, &form); +} + +void +nsWindow::DefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) +{ + const NPEvent* pPluginEvent = + static_cast(aEvent.mPluginEvent); + + if (NS_WARN_IF(!pPluginEvent)) { + return; + } + + if (!mWnd) { + return; + } + + // For WM_IME_*COMPOSITION + IMEHandler::DefaultProcOfPluginEvent(this, pPluginEvent); + + CallWindowProcW(GetPrevWindowProc(), mWnd, pPluginEvent->event, + pPluginEvent->wParam, pPluginEvent->lParam); +} + /************************************************************** ************************************************************** ** diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 6819c4c4392f..954f6768f341 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -297,6 +297,11 @@ public: const IMEContext& DefaultIMC() const { return mDefaultIMC; } + virtual void SetCandidateWindowForPlugin(int32_t aX, + int32_t aY) override; + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override; + protected: virtual ~nsWindow(); diff --git a/widget/windows/nsWindowBase.h b/widget/windows/nsWindowBase.h index ec5f4fc8d609..dfea13d8f3ae 100644 --- a/widget/windows/nsWindowBase.h +++ b/widget/windows/nsWindowBase.h @@ -77,14 +77,6 @@ public: */ virtual bool DispatchPluginEvent(const MSG& aMsg); - /* - * Returns true if a plugin has focus on this widget. Otherwise, false. - */ - virtual bool PluginHasFocus() const final - { - return (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); - } - /* * Touch input injection apis */ diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 8e92c4278ba7..d7da4ff126e0 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -73,6 +73,7 @@ #include "nsCycleCollector.h" #include "nsDOMJSUtils.h" #include "nsJSUtils.h" +#include "nsWrapperCache.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" @@ -397,6 +398,12 @@ NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing) // CycleCollectedJSRuntime. It should never be used directly. static const JSZoneParticipant sJSZoneCycleCollectorGlobal; +static +void JSObjectsTenuredCb(JSRuntime* aRuntime, void* aData) +{ + static_cast(aData)->JSObjectsTenured(aRuntime); +} + CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime, uint32_t aMaxBytes, uint32_t aMaxNurseryBytes) @@ -430,6 +437,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime, JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this); JS_SetGCCallback(mJSRuntime, GCCallback, this); mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback); + JS_SetObjectsTenuredCallback(mJSRuntime, JSObjectsTenuredCb, this); JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this); JS::SetLargeAllocationFailureCallback(mJSRuntime, LargeAllocationFailureCallback, this); @@ -785,6 +793,11 @@ struct JsGcTracer : public TraceCallbacks { JS_CallObjectTracer(static_cast(aClosure), aPtr, aName); } + virtual void Trace(JSObject** aPtr, const char* aName, + void* aClosure) const override + { + JS_CallUnbarrieredObjectTracer(static_cast(aClosure), aPtr, aName); + } virtual void Trace(JS::TenuredHeap* aPtr, const char* aName, void* aClosure) const override { @@ -852,6 +865,12 @@ struct ClearJSHolder : TraceCallbacks *aPtr = nullptr; } + virtual void Trace(JSObject** aPtr, const char* aName, + void* aClosure) const override + { + *aPtr = nullptr; + } + virtual void Trace(JS::TenuredHeap* aPtr, const char*, void*) const override { *aPtr = nullptr; @@ -1008,6 +1027,46 @@ CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const JS::GCForReason(mJSRuntime, GC_NORMAL, gcreason); } +void +CycleCollectedJSRuntime::JSObjectsTenured(JSRuntime* aRuntime) +{ + for (auto iter = mNurseryObjects.Iter(); !iter.Done(); iter.Next()) { + nsWrapperCache* cache = iter.Get(); + JSObject* wrapper = cache->GetWrapperPreserveColor(); + MOZ_ASSERT(wrapper); + if (!JS::ObjectIsTenured(wrapper)) { + MOZ_ASSERT(!cache->PreservingWrapper()); + const JSClass* jsClass = js::GetObjectJSClass(wrapper); + jsClass->finalize(nullptr, wrapper); + } + } + +#ifdef DEBUG +for (auto iter = mPreservedNurseryObjects.Iter(); !iter.Done(); iter.Next()) { + MOZ_ASSERT(JS::ObjectIsTenured(iter.Get().get())); +} +#endif + + mNurseryObjects.Clear(); + mPreservedNurseryObjects.Clear(); +} + +void +CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) +{ + MOZ_ASSERT(aCache); + MOZ_ASSERT(aCache->GetWrapperPreserveColor()); + MOZ_ASSERT(!JS::ObjectIsTenured(aCache->GetWrapperPreserveColor())); + mNurseryObjects.InfallibleAppend(aCache); +} + +void +CycleCollectedJSRuntime::NurseryWrapperPreserved(JSObject* aWrapper) +{ + mPreservedNurseryObjects.InfallibleAppend( + JS::PersistentRooted(mJSRuntime, aWrapper)); +} + void CycleCollectedJSRuntime::DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc, diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 53875db9085d..e9d83bd9363b 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -10,7 +10,9 @@ #include #include "mozilla/DeferredFinalize.h" +#include "mozilla/mozalloc.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/SegmentedVector.h" #include "jsapi.h" #include "nsCycleCollectionParticipant.h" @@ -22,6 +24,7 @@ class nsCycleCollectionNoteRootCallback; class nsIException; class nsIRunnable; class nsThread; +class nsWrapperCache; namespace js { struct Class; @@ -280,6 +283,10 @@ public: bool AreGCGrayBitsValid() const; void GarbageCollect(uint32_t aReason) const; + void NurseryWrapperAdded(nsWrapperCache* aCache); + void NurseryWrapperPreserved(JSObject* aWrapper); + void JSObjectsTenured(JSRuntime* aRuntime); + void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc, void* aThing); @@ -361,6 +368,13 @@ private: OOMState mOutOfMemoryState; OOMState mLargeAllocationFailureState; + + static const size_t kSegmentSize = 512; + SegmentedVector + mNurseryObjects; + SegmentedVector, kSegmentSize, + InfallibleAllocPolicy> + mPreservedNurseryObjects; }; void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer); diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index a046f6ea705d..cc92b560278a 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -2677,7 +2677,7 @@ public: } virtual void Trace(JS::Heap* aValue, const char* aName, - void* aClosure) const + void* aClosure) const override { if (aValue->isMarkable() && ValueIsGrayCCThing(*aValue)) { MOZ_ASSERT(!js::gc::IsInsideNursery(aValue->toGCThing())); @@ -2686,7 +2686,7 @@ public: } virtual void Trace(JS::Heap* aId, const char* aName, - void* aClosure) const + void* aClosure) const override { } @@ -2699,29 +2699,35 @@ public: } virtual void Trace(JS::Heap* aObject, const char* aName, - void* aClosure) const + void* aClosure) const override + { + AppendJSObjectToPurpleBuffer(*aObject); + } + + virtual void Trace(JSObject** aObject, const char* aName, + void* aClosure) const override { AppendJSObjectToPurpleBuffer(*aObject); } virtual void Trace(JS::TenuredHeap* aObject, const char* aName, - void* aClosure) const + void* aClosure) const override { AppendJSObjectToPurpleBuffer(*aObject); } virtual void Trace(JS::Heap* aString, const char* aName, - void* aClosure) const + void* aClosure) const override { } virtual void Trace(JS::Heap* aScript, const char* aName, - void* aClosure) const + void* aClosure) const override { } virtual void Trace(JS::Heap* aFunction, const char* aName, - void* aClosure) const + void* aClosure) const override { } diff --git a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp index 7687be0ccebd..0e4e5d876a4f 100644 --- a/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp +++ b/xpcom/base/nsCycleCollectorTraceJSHelpers.cpp @@ -61,6 +61,13 @@ TraceCallbackFunc::Trace(JS::Heap* aPtr, const char* aName, mCallback(JS::GCCellPtr(aPtr->get()), aName, aClosure); } +void +TraceCallbackFunc::Trace(JSObject** aPtr, const char* aName, + void* aClosure) const +{ + mCallback(JS::GCCellPtr(*aPtr), aName, aClosure); +} + void TraceCallbackFunc::Trace(JS::TenuredHeap* aPtr, const char* aName, void* aClosure) const diff --git a/xpcom/build/nsWindowsDllInterceptor.h b/xpcom/build/nsWindowsDllInterceptor.h index 1ef9a7a5fd7d..8615885c8e91 100644 --- a/xpcom/build/nsWindowsDllInterceptor.h +++ b/xpcom/build/nsWindowsDllInterceptor.h @@ -99,7 +99,7 @@ private: class WindowsDllNopSpacePatcher { - typedef unsigned char* byteptr_t; + typedef uint8_t* byteptr_t; HMODULE mModule; // Dumb array for remembering the addresses of functions we've patched. @@ -371,6 +371,66 @@ protected: int mMaxHooks; int mCurHooks; +#if defined(_M_X64) + // To patch for JMP and JE + + enum JumpType { + Je, + Jmp + }; + + struct JumpPatch { + JumpPatch() + : mHookOffset(0), mJumpAddress(0), mType(JumpType::Jmp) + { + } + + JumpPatch(size_t aOffset, intptr_t aAddress, JumpType aType = JumpType::Jmp) + : mHookOffset(aOffset), mJumpAddress(aAddress), mType(aType) + { + } + + void AddJumpPatch(size_t aHookOffset, intptr_t aAbsJumpAddress, + JumpType aType = JumpType::Jmp) + { + mHookOffset = aHookOffset; + mJumpAddress = aAbsJumpAddress; + mType = aType; + } + + size_t GenerateJump(uint8_t* aCode) + { + size_t offset = mHookOffset; + if (mType == JumpType::Je) { + // JNE RIP+14 + aCode[offset] = 0x75; + aCode[offset + 1] = 14; + offset += 2; + } + + // JMP [RIP+0] + aCode[offset] = 0xff; + aCode[offset + 1] = 0x25; + *reinterpret_cast(aCode + offset + 2) = 0; + + // Jump table + *reinterpret_cast(aCode + offset + 2 + 4) = mJumpAddress; + + return offset + 2 + 4 + 8; + } + + bool HasJumpPatch() const + { + return !!mJumpAddress; + } + + size_t mHookOffset; + intptr_t mJumpAddress; + JumpType mType; + }; + +#endif + void CreateTrampoline(void* aOrigFunction, intptr_t aDest, void** aOutTramp) { *aOutTramp = nullptr; @@ -383,9 +443,9 @@ protected: byteptr_t origBytes = (byteptr_t)aOrigFunction; int nBytes = 0; - int pJmp32 = -1; #if defined(_M_IX86) + int pJmp32 = -1; while (nBytes < 5) { // Understand some simple instructions that might be found in a // prologue; we might need to extend this as necessary. @@ -447,12 +507,12 @@ protected: } } #elif defined(_M_X64) - byteptr_t directJmpAddr; + JumpPatch jump; while (nBytes < 13) { // if found JMP 32bit offset, next bytes must be NOP or INT3 - if (pJmp32 >= 0) { + if (jump.HasJumpPatch()) { if (origBytes[nBytes] == 0x90 || origBytes[nBytes] == 0xcc) { nBytes++; continue; @@ -473,6 +533,15 @@ protected: } else if (origBytes[nBytes] == 0x05) { // syscall nBytes++; + } else if (origBytes[nBytes] == 0x84) { + // je rel32 + jump.AddJumpPatch(nBytes - 1, + (intptr_t) + origBytes + nBytes + 5 + + *(reinterpret_cast(origBytes + + nBytes + 1)), + JumpType::Je); + nBytes += 5; } else { return; } @@ -516,6 +585,13 @@ protected: (origBytes[nBytes + 1] & 0xf8) == 0x60) { // and [r+d], imm8 nBytes += 5; + } else if (origBytes[nBytes] == 0x85) { + // 85 /r => TEST r/m32, r32 + if ((origBytes[nBytes + 1] & 0xc0) == 0xc0) { + nBytes += 2; + } else { + return; + } } else if ((origBytes[nBytes] & 0xfd) == 0x89) { // MOV r/m64, r64 | MOV r64, r/m64 if ((origBytes[nBytes + 1] & 0xc0) == 0x40) { @@ -546,15 +622,16 @@ protected: return; } } else if (origBytes[nBytes] == 0xff) { - pJmp32 = nBytes - 1; // JMP /4 if ((origBytes[nBytes + 1] & 0xc0) == 0x0 && (origBytes[nBytes + 1] & 0x07) == 0x5) { // [rip+disp32] // convert JMP 32bit offset to JMP 64bit direct - directJmpAddr = - (byteptr_t)*((uint64_t*)(origBytes + nBytes + 6 + - (*((int32_t*)(origBytes + nBytes + 2))))); + jump.AddJumpPatch(nBytes - 1, + *reinterpret_cast( + origBytes + nBytes + 6 + + *reinterpret_cast(origBytes + nBytes + + 2))); nBytes += 6; } else { // not support yet! @@ -576,11 +653,16 @@ protected: } else if (origBytes[nBytes] == 0xc3) { // ret nBytes++; + } else if (origBytes[nBytes] == 0xcc) { + // int 3 + nBytes++; } else if (origBytes[nBytes] == 0xe9) { - pJmp32 = nBytes; - // convert JMP 32bit offset to JMP 64bit direct - directJmpAddr = origBytes + pJmp32 + 5 + (*((int32_t*)(origBytes + pJmp32 + 1))); // jmp 32bit offset + jump.AddJumpPatch(nBytes, + // convert JMP 32bit offset to JMP 64bit direct + (intptr_t) + origBytes + nBytes + 5 + + *(reinterpret_cast(origBytes + nBytes + 1))); nBytes += 5; } else if (origBytes[nBytes] == 0xff) { nBytes++; @@ -625,27 +707,16 @@ protected: (intptr_t)trampDest - (intptr_t)(tramp + nBytes + 5); // target displacement } #elif defined(_M_X64) - // If JMP32 opcode found, we don't insert to trampoline jump - if (pJmp32 >= 0) { - // mov r11, address - tramp[pJmp32] = 0x49; - tramp[pJmp32 + 1] = 0xbb; - *((intptr_t*)(tramp + pJmp32 + 2)) = (intptr_t)directJmpAddr; - - // jmp r11 - tramp[pJmp32 + 10] = 0x41; - tramp[pJmp32 + 11] = 0xff; - tramp[pJmp32 + 12] = 0xe3; + // If JMP/JE opcode found, we don't insert to trampoline jump + if (jump.HasJumpPatch()) { + size_t offset = jump.GenerateJump(tramp); + if (jump.mType != JumpType::Jmp) { + JumpPatch patch(offset, reinterpret_cast(trampDest)); + patch.GenerateJump(tramp); + } } else { - // mov r11, address - tramp[nBytes] = 0x49; - tramp[nBytes + 1] = 0xbb; - *((intptr_t*)(tramp + nBytes + 2)) = (intptr_t)trampDest; - - // jmp r11 - tramp[nBytes + 10] = 0x41; - tramp[nBytes + 11] = 0xff; - tramp[nBytes + 12] = 0xe3; + JumpPatch patch(nBytes, reinterpret_cast(trampDest)); + patch.GenerateJump(tramp); } #endif diff --git a/xpcom/glue/nsCycleCollectionParticipant.h b/xpcom/glue/nsCycleCollectionParticipant.h index 5db54b3adc8b..fd114b76f018 100644 --- a/xpcom/glue/nsCycleCollectionParticipant.h +++ b/xpcom/glue/nsCycleCollectionParticipant.h @@ -64,6 +64,8 @@ struct TraceCallbacks void* aClosure) const = 0; virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const = 0; + virtual void Trace(JSObject** aPtr, const char* aName, + void* aClosure) const = 0; virtual void Trace(JS::TenuredHeap* aPtr, const char* aName, void* aClosure) const = 0; virtual void Trace(JS::Heap* aPtr, const char* aName, @@ -90,6 +92,8 @@ struct TraceCallbackFunc : public TraceCallbacks void* aClosure) const override; virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const override; + virtual void Trace(JSObject** aPtr, const char* aName, + void* aClosure) const override; virtual void Trace(JS::TenuredHeap* aPtr, const char* aName, void* aClosure) const override; virtual void Trace(JS::Heap* aPtr, const char* aName, diff --git a/xulrunner/installer/windows/Header.bmp b/xulrunner/installer/windows/Header.bmp deleted file mode 100644 index 75559d1b4bdf..000000000000 Binary files a/xulrunner/installer/windows/Header.bmp and /dev/null differ diff --git a/xulrunner/installer/windows/Makefile.in b/xulrunner/installer/windows/Makefile.in deleted file mode 100644 index c7bccdc94b21..000000000000 --- a/xulrunner/installer/windows/Makefile.in +++ /dev/null @@ -1,14 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -CONFIG_DIR=$(abspath $(srcdir)) -OBJ_DIR=$(abspath $(DEPTH)) -SRC_DIR=$(abspath $(topsrcdir)) - -include $(topsrcdir)/config/rules.mk - -export:: - $(NSINSTALL) -D $(DIST)/branding - cp $(srcdir)/Header.bmp $(DIST)/branding/Header.bmp - cp $(srcdir)/Watermrk.bmp $(DIST)/branding/Watermrk.bmp diff --git a/xulrunner/installer/windows/Watermrk.bmp b/xulrunner/installer/windows/Watermrk.bmp deleted file mode 100644 index 3cf524f16d3c..000000000000 Binary files a/xulrunner/installer/windows/Watermrk.bmp and /dev/null differ diff --git a/xulrunner/installer/windows/moz.build b/xulrunner/installer/windows/moz.build deleted file mode 100644 index 895d11993cfb..000000000000 --- a/xulrunner/installer/windows/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - diff --git a/xulrunner/moz.build b/xulrunner/moz.build index 911acfbe0f21..c7845e2e9643 100644 --- a/xulrunner/moz.build +++ b/xulrunner/moz.build @@ -12,9 +12,6 @@ DIRS += [ 'examples', ] -if CONFIG['MAKENSISU']: - DIRS += ['installer/windows'] - if CONFIG['OS_ARCH'] == 'WINNT': DIRS += ['tools/redit']