diff --git a/accessible/tests/browser/browser.ini b/accessible/tests/browser/browser.ini index e9a5ab63a9d9..11c7318b8139 100644 --- a/accessible/tests/browser/browser.ini +++ b/accessible/tests/browser/browser.ini @@ -10,7 +10,7 @@ support-files = [browser_shutdown_multi_acc_reference_doc.js] [browser_shutdown_multi_reference.js] [browser_shutdown_parent_own_reference.js] -skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. +skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_proxy_acc_reference.js] skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_proxy_doc_acc_reference.js] @@ -20,10 +20,10 @@ skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown be [browser_shutdown_multi_proxy_acc_reference_obj.js] skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_remote_no_reference.js] -skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. +skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_remote_only.js] -skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. +skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_remote_own_reference.js] -skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. +skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content. [browser_shutdown_scope_lifecycle.js] [browser_shutdown_start_restart.js] diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 58c55ee6f955..91df6353bb29 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -272,7 +272,6 @@ tags = mcb [browser_bug970746.js] [browser_bug1015721.js] skip-if = os == 'win' -[browser_bug1064280_changeUrlInPinnedTab.js] [browser_accesskeys.js] [browser_clipboard.js] subsuite = clipboard diff --git a/browser/base/content/test/newtab/browser.ini b/browser/base/content/test/newtab/browser.ini index 3931f35b602e..2ff40d72d9e1 100644 --- a/browser/base/content/test/newtab/browser.ini +++ b/browser/base/content/test/newtab/browser.ini @@ -8,6 +8,7 @@ support-files = [browser_newtab_block.js] [browser_newtab_bug721442.js] [browser_newtab_bug722273.js] +skip-if = (os == "mac" && debug) # temporary skip-if due to increase in intermittent failures on Mac debug - bug 1119906 [browser_newtab_bug723102.js] [browser_newtab_bug723121.js] [browser_newtab_bug725996.js] diff --git a/browser/base/content/test/tabs/browser.ini b/browser/base/content/test/tabs/browser.ini index 7771e0a6efb3..a8f714dfd6bf 100644 --- a/browser/base/content/test/tabs/browser.ini +++ b/browser/base/content/test/tabs/browser.ini @@ -2,3 +2,4 @@ skip-if = !e10s # Tab spinner is e10s only. [browser_tabSwitchPrintPreview.js] skip-if = os == 'mac' +[browser_navigatePinnedTab.js] diff --git a/browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js b/browser/base/content/test/tabs/browser_navigatePinnedTab.js similarity index 51% rename from browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js rename to browser/base/content/test/tabs/browser_navigatePinnedTab.js index 89e41df0e75c..e92e3edf5877 100644 --- a/browser/base/content/test/general/browser_bug1064280_changeUrlInPinnedTab.js +++ b/browser/base/content/test/tabs/browser_navigatePinnedTab.js @@ -29,8 +29,31 @@ add_task(function* () { is(appTab.linkedBrowser.currentURI.spec, TEST_LINK_CHANGED, "New page loaded in the app tab"); is(gBrowser.tabs.length, initialTabsNo, "No additional tabs were opened"); + + // Now check that opening a link that does create a new tab works, + // and also that it nulls out the opener. + let pageLoadPromise = BrowserTestUtils.browserLoaded(appTab.linkedBrowser, "http://example.com/"); + yield BrowserTestUtils.loadURI(appTab.linkedBrowser, "http://example.com/"); + info("Started loading example.com"); + yield pageLoadPromise; + info("Loaded example.com"); + let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "http://example.org/"); + yield ContentTask.spawn(browser, null, function* () { + let link = content.document.createElement("a"); + link.href = "http://example.org/"; + content.document.body.appendChild(link); + link.click(); + }); + info("Created & clicked link"); + let extraTab = yield newTabPromise; + info("Got a new tab"); + yield ContentTask.spawn(extraTab.linkedBrowser, null, function* () { + is(content.opener, null, "No opener should be available"); + }); + yield BrowserTestUtils.removeTab(extraTab); }); + registerCleanupFunction(function() { gBrowser.removeTab(gBrowser.selectedTab); }); diff --git a/browser/branding/aurora/branding.nsi b/browser/branding/aurora/branding.nsi index bb42794d145c..2341b7433a1d 100644 --- a/browser/branding/aurora/branding.nsi +++ b/browser/branding/aurora/branding.nsi @@ -14,7 +14,8 @@ !define URLInfoAbout "https://www.mozilla.org" !define HelpLink "https://support.mozilla.org" -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-aurora-latest" +!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-aurora-latest" +!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-aurora-latest" !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=aurora&installer_lang=${AB_CD}" !define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/" !define Channel "aurora" diff --git a/browser/branding/nightly/branding.nsi b/browser/branding/nightly/branding.nsi index fa13b32c6d6e..ba6b4e514735 100644 --- a/browser/branding/nightly/branding.nsi +++ b/browser/branding/nightly/branding.nsi @@ -13,7 +13,8 @@ !define URLInfoAbout "https://www.mozilla.org" !define HelpLink "https://support.mozilla.org" -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-nightly-latest" +!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-nightly-latest" +!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-nightly-latest" !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=nightly&installer_lang=${AB_CD}" !define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/" !define Channel "nightly" diff --git a/browser/branding/official/branding.nsi b/browser/branding/official/branding.nsi index 5960f3107ad2..a6025a326d5c 100644 --- a/browser/branding/official/branding.nsi +++ b/browser/branding/official/branding.nsi @@ -18,7 +18,8 @@ ; Beta since they share the same branding when building with other branches that ; set the update channel to beta. !define OFFICIAL -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-latest" +!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-latest" +!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-latest" !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=release&installer_lang=${AB_CD}" !define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/" !define Channel "release" diff --git a/browser/branding/unofficial/branding.nsi b/browser/branding/unofficial/branding.nsi index 34214453f9da..8a81823311fe 100644 --- a/browser/branding/unofficial/branding.nsi +++ b/browser/branding/unofficial/branding.nsi @@ -13,7 +13,8 @@ !define URLInfoAbout "https://www.mozilla.org" !define HelpLink "https://support.mozilla.org" -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-latest" +!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-latest" +!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-latest" !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=release&installer_lang=${AB_CD}" !define URLSystemRequirements "https://www.mozilla.org/firefox/system-requirements/" !define Channel "unofficial" diff --git a/browser/components/contextualidentity/test/browser/browser_count_and_remove.js b/browser/components/contextualidentity/test/browser/browser_count_and_remove.js index 23b7e948a23e..ee6043f137ad 100644 --- a/browser/components/contextualidentity/test/browser/browser_count_and_remove.js +++ b/browser/components/contextualidentity/test/browser/browser_count_and_remove.js @@ -22,13 +22,26 @@ add_task(function* test() { openTabInUserContext(1); is(ContextualIdentityService.countContainerTabs(), 1, "1 container tab created"); + is(ContextualIdentityService.countContainerTabs(1), 1, "1 container tab created with id 1"); + is(ContextualIdentityService.countContainerTabs(2), 0, "0 container tabs created with id 2"); openTabInUserContext(1); - is(ContextualIdentityService.countContainerTabs(), 2, "2 container tab created"); + is(ContextualIdentityService.countContainerTabs(), 2, "2 container tabs created"); + is(ContextualIdentityService.countContainerTabs(1), 2, "2 container tabs created with id 1"); + is(ContextualIdentityService.countContainerTabs(2), 0, "0 container tabs created with id 2"); openTabInUserContext(2); is(ContextualIdentityService.countContainerTabs(), 3, "3 container tab created"); + is(ContextualIdentityService.countContainerTabs(1), 2, "2 container tabs created with id 1"); + is(ContextualIdentityService.countContainerTabs(2), 1, "1 container tab created with id 2"); - ContextualIdentityService.closeAllContainerTabs(); - is(ContextualIdentityService.countContainerTabs(), 0, "0 container tab at the end."); + ContextualIdentityService.closeContainerTabs(1); + is(ContextualIdentityService.countContainerTabs(), 1, "1 container tab created"); + is(ContextualIdentityService.countContainerTabs(1), 0, "0 container tabs created with id 1"); + is(ContextualIdentityService.countContainerTabs(2), 1, "1 container tab created with id 2"); + + ContextualIdentityService.closeContainerTabs(); + is(ContextualIdentityService.countContainerTabs(), 0, "0 container tabs at the end."); + is(ContextualIdentityService.countContainerTabs(1), 0, "0 container tabs at the end with id 1."); + is(ContextualIdentityService.countContainerTabs(2), 0, "0 container tabs at the end with id 2."); }); diff --git a/browser/components/preferences/in-content/containers.js b/browser/components/preferences/in-content/containers.js index f63806a3d6dd..7968f55395a4 100644 --- a/browser/components/preferences/in-content/containers.js +++ b/browser/components/preferences/in-content/containers.js @@ -39,10 +39,34 @@ let gContainersPane = { }, onRemoveClick(button) { - let userContextId = button.getAttribute("value"); + let userContextId = parseInt(button.getAttribute("value"), 10); + + let count = ContextualIdentityService.countContainerTabs(userContextId); + if (count > 0) { + let bundlePreferences = document.getElementById("bundlePreferences"); + + let title = bundlePreferences.getString("removeContainerAlertTitle"); + let message = PluralForm.get(count, bundlePreferences.getString("removeContainerMsg")) + .replace("#S", count) + let okButton = bundlePreferences.getString("removeContainerOkButton"); + let cancelButton = bundlePreferences.getString("removeContainerButton2"); + + let buttonFlags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) + + (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1); + + let rv = Services.prompt.confirmEx(window, title, message, buttonFlags, + okButton, cancelButton, null, null, {}); + if (rv != 0) { + return; + } + + ContextualIdentityService.closeContainerTabs(userContextId); + } + ContextualIdentityService.remove(userContextId); this._rebuildView(); }, + onPeferenceClick(button) { this.openPreferenceDialog(button.getAttribute("value")); }, diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js index ffa7a9c391d5..d71e77e99c66 100644 --- a/browser/components/preferences/in-content/privacy.js +++ b/browser/components/preferences/in-content/privacy.js @@ -104,7 +104,7 @@ var gPrivacyPane = { let rv = Services.prompt.confirmEx(window, title, message, buttonFlags, okButton, cancelButton, null, null, {}); if (rv == 0) { - ContextualIdentityService.closeAllContainerTabs(); + ContextualIdentityService.closeContainerTabs(); Services.prefs.setBoolPref("privacy.userContext.enabled", false); return; } diff --git a/browser/installer/windows/nsis/stub.nsi b/browser/installer/windows/nsis/stub.nsi index 72ac7ee010ad..d641592bfb01 100644 --- a/browser/installer/windows/nsis/stub.nsi +++ b/browser/installer/windows/nsis/stub.nsi @@ -35,11 +35,10 @@ Var LabelDownloading Var LabelInstalling Var LabelFreeSpace Var CheckboxSetAsDefault -Var CheckboxShortcutOnBar ; Used for Quicklaunch or Taskbar as appropriate -Var CheckboxShortcutInStartMenu -Var CheckboxShortcutOnDesktop +Var CheckboxShortcuts Var CheckboxSendPing Var CheckboxInstallMaintSvc +Var DroplistArch Var DirRequest Var ButtonBrowse Var LabelBlurb1 @@ -73,7 +72,6 @@ Var InstallStepSize Var InstallTotalSteps Var ProgressCompleted Var ProgressTotal -Var TmpVal Var ExitCode Var FirefoxLaunchCode @@ -108,6 +106,8 @@ Var DownloadRetryCount Var OpenedDownloadPage Var DownloadServerIP Var PostSigningData +Var PreviousInstallDir +Var PreviousInstallArch Var ControlHeightPX Var ControlRightPX @@ -218,6 +218,9 @@ Var ControlRightPX !define INVALID_HANDLE_VALUE -1 !endif +!define DefaultInstDir32bit "$PROGRAMFILES32\${BrandFullName}" +!define DefaultInstDir64bit "$PROGRAMFILES64\${BrandFullName}" + !include "nsDialogs.nsh" !include "LogicLib.nsh" !include "FileFunc.nsh" @@ -230,6 +233,9 @@ Var ControlRightPX !insertmacro LineFind !insertmacro StrFilter +!include "StrFunc.nsh" +${StrTok} + !include "locales.nsi" !include "branding.nsi" @@ -243,8 +249,10 @@ Var ControlRightPX ; set the update channel to beta. !ifdef OFFICIAL !ifdef BETA_UPDATE_CHANNEL -!undef URLStubDownload -!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-beta-latest" +!undef URLStubDownload32 +!undef URLStubDownload64 +!define URLStubDownload32 "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-beta-latest" +!define URLStubDownload64 "http://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-beta-latest" !undef URLManualDownload !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=beta&installer_lang=${AB_CD}" !undef Channel @@ -275,11 +283,6 @@ icon "setup.ico" XPStyle on BrandingText " " ChangeUI all "nsisui.exe" -!ifdef HAVE_64BIT_BUILD - InstallDir "$PROGRAMFILES64\${BrandFullName}\" -!else - InstallDir "$PROGRAMFILES32\${BrandFullName}\" -!endif !ifdef ${AB_CD}_rtl LoadLanguageFile "locale-rtl.nlf" @@ -340,9 +343,11 @@ Function .onInit Quit ${EndIf} -!ifdef HAVE_64BIT_BUILD - SetRegView 64 -!endif + ${If} ${RunningX64} + StrCpy $INSTDIR "${DefaultInstDir64bit}" + ${Else} + StrCpy $INSTDIR "${DefaultInstDir32bit}" + ${EndIf} ; Require elevation if the user can elevate ${ElevateUAC} @@ -355,16 +360,25 @@ Function .onInit ${EndIf} !endif + ; If we have any existing installation, use its location as the default + ; path for this install, even if it's not the same architecture. + SetRegView 32 SetShellVarContext all ; Set SHCTX to HKLM ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 + ${If} "$R9" == "false" + ${AndIf} ${RunningX64} + SetRegView 64 + ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 + ${EndIf} + ${If} "$R9" == "false" SetShellVarContext current ; Set SHCTX to HKCU ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 ${If} ${RunningX64} ; In HKCU there is no WOW64 redirection, which means we may have gotten - ; the path to a 32-bit install even though we're 64-bit, or vice-versa. + ; the path to a 32-bit install even though we're 64-bit. ; In that case, just use the default path instead of offering an upgrade. ; But only do that override if the existing install is in Program Files, ; because that's the only place we can be sure is specific @@ -372,20 +386,36 @@ Function .onInit ; The WordFind syntax below searches for the first occurence of the ; "delimiter" (the Program Files path) in the install path and returns ; anything that appears before that. If nothing appears before that, - ; then the install is under Program Files (32 or 64). -!ifdef HAVE_64BIT_BUILD + ; then the install is under Program Files. ${WordFind} $R9 $PROGRAMFILES32 "+1{" $0 -!else - ${WordFind} $R9 $PROGRAMFILES64 "+1{" $0 -!endif ${If} $0 == "" StrCpy $R9 "false" ${EndIf} ${EndIf} ${EndIf} + StrCpy $PreviousInstallDir "" + StrCpy $PreviousInstallArch "" ${If} "$R9" != "false" - StrCpy $INSTDIR "$R9" + ; Don't override the default install path with an existing installation + ; of a different architecture. + System::Call "*(i)p.r0" + StrCpy $1 "$R9\${FileMainEXE}" + System::Call "Kernel32::GetBinaryTypeW(w r1, p r0)i" + System::Call "*$0(i.r2)" + System::Free $0 + + ${If} $2 == "6" ; 6 == SCS_64BIT_BINARY + ${AndIf} ${RunningX64} + StrCpy $PreviousInstallDir "$R9" + StrCpy $PreviousInstallArch "64" + StrCpy $INSTDIR "$PreviousInstallDir" + ${ElseIf} $2 == "0" ; 0 == SCS_32BIT_BINARY + ${AndIfNot} ${RunningX64} + StrCpy $PreviousInstallDir "$R9" + StrCpy $PreviousInstallArch "32" + StrCpy $INSTDIR "$PreviousInstallDir" + ${EndIf} ${EndIf} ; Used to determine if the default installation directory was used. @@ -422,9 +452,7 @@ Function .onInit StrCpy $InitialInstallRequirementsCode "" StrCpy $IsDownloadFinished "" StrCpy $FirefoxLaunchCode "0" - StrCpy $CheckboxShortcutOnBar "1" - StrCpy $CheckboxShortcutInStartMenu "1" - StrCpy $CheckboxShortcutOnDesktop "1" + StrCpy $CheckboxShortcuts "1" StrCpy $CheckboxSendPing "1" !ifdef MOZ_MAINTENANCE_SERVICE StrCpy $CheckboxInstallMaintSvc "1" @@ -432,6 +460,11 @@ Function .onInit StrCpy $CheckboxInstallMaintSvc "0" !endif StrCpy $WasOptionsButtonClicked "0" + ${If} ${RunningX64} + StrCpy $DroplistArch "$(VERSION_64BIT)" + ${Else} + StrCpy $DroplistArch "$(VERSION_32BIT)" + ${EndIf} StrCpy $0 "" !ifdef FONT_FILE1 @@ -575,11 +608,11 @@ Function SendPing ; completion of all phases. ${GetSecondsElapsed} "$EndInstallPhaseTickCount" "$EndFinishPhaseTickCount" $4 -!ifdef HAVE_64BIT_BUILD - StrCpy $R0 "1" -!else - StrCpy $R0 "0" -!endif + ${If} $DroplistArch == "$(VERSION_64BIT)" + StrCpy $R0 "1" + ${Else} + StrCpy $R0 "0" + ${EndIf} ${If} ${RunningX64} StrCpy $R1 "1" @@ -903,54 +936,13 @@ Function createOptions ; background colors of the Dialog must also be hardcoded. SetCtlColors $Dialog ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 18u ${OPTIONS_ITEM_WIDTH_DU} \ - 12u "$(CREATE_SHORTCUTS)" - Pop $0 - SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - SendMessage $0 ${WM_SETFONT} $FontNormal 0 - - ${If} ${AtLeastWin7} - StrCpy $0 "$(ADD_SC_TASKBAR)" - ${Else} - StrCpy $0 "$(ADD_SC_QUICKLAUNCHBAR)" - ${EndIf} - ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 38u \ - ${OPTIONS_SUBITEM_WIDTH_DU} 12u "$0" - Pop $CheckboxShortcutOnBar - ; The uxtheme must be disabled on checkboxes in order to override the system - ; font color. - System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnBar, w " ", w " ")' - SetCtlColors $CheckboxShortcutOnBar ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - SendMessage $CheckboxShortcutOnBar ${WM_SETFONT} $FontNormal 0 - ${NSD_Check} $CheckboxShortcutOnBar - - ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 54u ${OPTIONS_SUBITEM_WIDTH_DU} \ - 12u "$(ADD_CheckboxShortcutInStartMenu)" - Pop $CheckboxShortcutInStartMenu - ; The uxtheme must be disabled on checkboxes in order to override the system - ; font color. - System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutInStartMenu, w " ", w " ")' - SetCtlColors $CheckboxShortcutInStartMenu ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - SendMessage $CheckboxShortcutInStartMenu ${WM_SETFONT} $FontNormal 0 - ${NSD_Check} $CheckboxShortcutInStartMenu - - ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 70u ${OPTIONS_SUBITEM_WIDTH_DU} \ - 12u "$(ADD_CheckboxShortcutOnDesktop)" - Pop $CheckboxShortcutOnDesktop - ; The uxtheme must be disabled on checkboxes in order to override the system - ; font color. - System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnDesktop, w " ", w " ")' - SetCtlColors $CheckboxShortcutOnDesktop ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - SendMessage $CheckboxShortcutOnDesktop ${WM_SETFONT} $FontNormal 0 - ${NSD_Check} $CheckboxShortcutOnDesktop - - ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 100u ${OPTIONS_ITEM_WIDTH_DU} \ + ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 25u ${OPTIONS_ITEM_WIDTH_DU} \ 12u "$(DEST_FOLDER)" Pop $0 SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} SendMessage $0 ${WM_SETFONT} $FontNormal 0 - ${NSD_CreateDirRequest} ${OPTIONS_SUBITEM_EDGE_DU} 116u 159u 14u "$INSTDIR" + ${NSD_CreateDirRequest} ${OPTIONS_SUBITEM_EDGE_DU} 41u 159u 14u "$INSTDIR" Pop $DirRequest SetCtlColors $DirRequest ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} SendMessage $DirRequest ${WM_SETFONT} $FontNormal 0 @@ -966,7 +958,7 @@ Function createOptions ${NSD_AddExStyle} $DirRequest ${WS_EX_LTRREADING}|${WS_EX_LEFT} !endif - ${NSD_CreateBrowseButton} 280u 116u 50u 14u "$(BROWSE_BUTTON)" + ${NSD_CreateBrowseButton} 280u 41u 50u 14u "$(BROWSE_BUTTON)" Pop $ButtonBrowse SetCtlColors $ButtonBrowse "" ${COMMON_BKGRD_COLOR} ${NSD_OnClick} $ButtonBrowse OnClick_ButtonBrowse @@ -987,13 +979,13 @@ Function createOptions IntOp $0 $0 + 8 ; Add padding to the control's width ; Make both controls the same width as the widest control - ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 134u $0 $ControlHeightPX "$(SPACE_REQUIRED)" + ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 59u $0 $ControlHeightPX "$(SPACE_REQUIRED)" Pop $5 SetCtlColors $5 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} SendMessage $5 ${WM_SETFONT} $FontItalic 0 IntOp $2 $2 + 8 ; Add padding to the control's width - ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 145u $2 $ControlHeightPX "$(SPACE_AVAILABLE)" + ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 70u $2 $ControlHeightPX "$(SPACE_AVAILABLE)" Pop $6 SetCtlColors $6 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} SendMessage $6 ${WM_SETFONT} $FontItalic 0 @@ -1007,7 +999,7 @@ Function createOptions IntOp $ControlRightPX $ControlRightPX + 6 - ${NSD_CreateLabel} $ControlRightPX 134u 100% $ControlHeightPX \ + ${NSD_CreateLabel} $ControlRightPX 59u 100% $ControlHeightPX \ "${APPROXIMATE_REQUIRED_SPACE_MB} $(MEGA)$(BYTE)" Pop $7 SetCtlColors $7 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} @@ -1015,14 +1007,29 @@ Function createOptions ; Create the free space label with an empty string and update it by calling ; UpdateFreeSpaceLabel - ${NSD_CreateLabel} $ControlRightPX 145u 100% $ControlHeightPX " " + ${NSD_CreateLabel} $ControlRightPX 70u 100% $ControlHeightPX " " Pop $LabelFreeSpace SetCtlColors $LabelFreeSpace ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} SendMessage $LabelFreeSpace ${WM_SETFONT} $FontNormal 0 Call UpdateFreeSpaceLabel - ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 168u ${OPTIONS_SUBITEM_WIDTH_DU} \ + ${If} ${AtLeastWin7} + StrCpy $0 "$(ADD_SC_DESKTOP_TASKBAR)" + ${Else} + StrCpy $0 "$(ADD_SC_DESKTOP_QUICKLAUNCHBAR)" + ${EndIf} + ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 100u \ + ${OPTIONS_ITEM_WIDTH_DU} 12u "$0" + Pop $CheckboxShortcuts + ; The uxtheme must be disabled on checkboxes in order to override the system + ; font color. + System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcuts, w " ", w " ")' + SetCtlColors $CheckboxShortcuts ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxShortcuts ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxShortcuts + + ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 116u ${OPTIONS_SUBITEM_WIDTH_DU} \ 12u "$(SEND_PING)" Pop $CheckboxSendPing ; The uxtheme must be disabled on checkboxes in order to override the system @@ -1033,6 +1040,7 @@ Function createOptions ${NSD_Check} $CheckboxSendPing !ifdef MOZ_MAINTENANCE_SERVICE + StrCpy $CheckboxInstallMaintSvc "0" ; We can only install the maintenance service if the user is an admin. Call IsUserAdmin Pop $0 @@ -1045,31 +1053,100 @@ Function createOptions StrCpy $0 "false" ${EndIf} - ; Only show the maintenance service checkbox if we have write access to HKLM - ClearErrors - WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ - "Write Test" - ${If} ${Errors} - ${OrIf} $0 != "true" - StrCpy $CheckboxInstallMaintSvc "0" - ${Else} + ${If} $0 == "true" + ; Only show the maintenance service checkbox if we have write access to HKLM DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" - ; Read the registry instead of using ServicesHelper::IsInstalled so the - ; plugin isn't included in the stub installer to lessen its size. ClearErrors - ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\services\MozillaMaintenance" "ImagePath" - ${If} ${Errors} - ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 184u ${OPTIONS_ITEM_WIDTH_DU} \ - 12u "$(INSTALL_MAINT_SERVICE)" - Pop $CheckboxInstallMaintSvc - System::Call 'uxtheme::SetWindowTheme(i $CheckboxInstallMaintSvc, w " ", w " ")' - SetCtlColors $CheckboxInstallMaintSvc ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} - SendMessage $CheckboxInstallMaintSvc ${WM_SETFONT} $FontNormal 0 - ${NSD_Check} $CheckboxInstallMaintSvc + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ + "Write Test" + ${IfNot} ${Errors} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + ; Read the registry instead of using ServicesHelper::IsInstalled so the + ; plugin isn't included in the stub installer to lessen its size. + ClearErrors + ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\services\MozillaMaintenance" "ImagePath" + ${If} ${Errors} + ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 132u ${OPTIONS_ITEM_WIDTH_DU} \ + 12u "$(INSTALL_MAINT_SERVICE)" + Pop $CheckboxInstallMaintSvc + System::Call 'uxtheme::SetWindowTheme(i $CheckboxInstallMaintSvc, w " ", w " ")' + SetCtlColors $CheckboxInstallMaintSvc ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxInstallMaintSvc ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxInstallMaintSvc + ${EndIf} ${EndIf} ${EndIf} !endif + ${If} ${RunningX64} + ; Get the exact pixel width we're going to need for this label. + ; The label string has a keyboard accelerator, which is an '&' that's in + ; the string but is not rendered, and GetTextExtent doesn't account for + ; those, so remove them first. Also handle any escaped &'s ("&&"). + StrCpy $R0 "$(ARCH_DROPLIST_LABEL)" + StrCpy $R1 "" + ${Do} + ${StrTok} $R2 $R0 "&" 0 0 + StrCpy $R1 "$R1$R2" + StrLen $R3 $R2 + IntOp $R3 $R3 + 1 + StrCpy $R0 $R0 "" $R3 + StrCpy $R4 $R0 1 + ${If} $R4 == "&" + StrCpy $R1 "$R1&" + StrCpy $R0 $R0 "" 1 + ${EndIf} + ${LoopUntil} $R0 == "" + + ${GetTextExtent} $R1 $FontNormal $R0 $R1 + ${If} $CheckboxInstallMaintSvc == "0" + ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 134u $R0 $R1 "$(ARCH_DROPLIST_LABEL)" + ${Else} + ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 154u $R0 $R1 "$(ARCH_DROPLIST_LABEL)" + ${EndIf} + Pop $0 + SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $0 ${WM_SETFONT} $FontNormal 0 + + ; Set the dropdown list size to the same as the larger of the two options. + ${GetTextExtent} "$(VERSION_32BIT)" $FontNormal $R0 $R1 + ${GetTextExtent} "$(VERSION_64BIT)" $FontNormal $R2 $R3 + ${If} $R0 < $R2 + StrCpy $R0 $R2 + ${EndIf} + ${If} $R1 < $R3 + StrCpy $R3 $R1 + ${EndIf} + ; Add enough width for the dropdown button. How wide the button is depends + ; on he system display scaling setting, which we cannot easily determine, + ; so just use a value that works fine for a setting of 200% and adds a + ; little too much padding for settings below that. + IntOp $R0 $R0 + 56 + + ; Put the droplist right after the label, with some padding. + ${GetDlgItemEndPX} $0 $ControlRightPX + IntOp $ControlRightPX $ControlRightPX + 4 + ${If} $CheckboxInstallMaintSvc == "0" + ${NSD_CreateDropList} $ControlRightPX 132u $R0 $R3 "" + ${Else} + ${NSD_CreateDropList} $ControlRightPX 152u $R0 $R3 "" + ${EndIf} + Pop $DroplistArch + ${NSD_CB_AddString} $DroplistArch "$(VERSION_32BIT)" + ${NSD_CB_AddString} $DroplistArch "$(VERSION_64BIT)" + ${NSD_OnChange} $DroplistArch OnChange_DroplistArch + ; The uxtheme must be disabled in order to override the system colors. + System::Call 'uxtheme::SetWindowTheme(i $DroplistArch, w " ", w " ")' + SetCtlColors $DroplistArch ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $DroplistArch ${WM_SETFONT} $FontNormal 0 + + ${If} ${RunningX64} + ${NSD_CB_SelectString} $DroplistArch "$(VERSION_64BIT)" + ${Else} + ${NSD_CB_SelectString} $DroplistArch "$(VERSION_32BIT)" + ${EndIf} + ${EndIf} + GetDlgItem $0 $HWNDPARENT 1 ; Install button ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" @@ -1137,9 +1214,8 @@ Function leaveOptions IntOp $OptionsPhaseSeconds $OptionsPhaseSeconds + 1 ${EndIf} - ${NSD_GetState} $CheckboxShortcutOnBar $CheckboxShortcutOnBar - ${NSD_GetState} $CheckboxShortcutInStartMenu $CheckboxShortcutInStartMenu - ${NSD_GetState} $CheckboxShortcutOnDesktop $CheckboxShortcutOnDesktop + ${NSD_GetState} $CheckboxShortcuts $CheckboxShortcuts + ${NSD_GetText} $DroplistArch $DroplistArch ${NSD_GetState} $CheckboxSendPing $CheckboxSendPing !ifdef MOZ_MAINTENANCE_SERVICE ${NSD_GetState} $CheckboxInstallMaintSvc $CheckboxInstallMaintSvc @@ -1334,8 +1410,15 @@ FunctionEnd Function StartDownload ${NSD_KillTimer} StartDownload - InetBgDL::Get "${URLStubDownload}${URLStubDownloadAppend}" "$PLUGINSDIR\download.exe" \ - /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END + ${If} $DroplistArch == "$(VERSION_64BIT)" + InetBgDL::Get "${URLStubDownload64}${URLStubDownloadAppend}" \ + "$PLUGINSDIR\download.exe" \ + /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END + ${Else} + InetBgDL::Get "${URLStubDownload32}${URLStubDownloadAppend}" \ + "$PLUGINSDIR\download.exe" \ + /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END + ${EndIf} StrCpy $4 "" ${NSD_CreateTimer} OnDownload ${DownloadIntervalMS} ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" @@ -1556,23 +1639,18 @@ Function OnDownload ; Don't create the QuickLaunch or Taskbar shortcut from the launched installer WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "QuickLaunchShortcut" "false" - ; Either avoid or force adding a taskbar pin based on the checkbox value: - ${If} $CheckboxShortcutOnBar == 0 + ; Always create a start menu shortcut, so the user always has some way + ; to access the application. + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true" + + ; Either avoid or force adding a taskbar pin and desktop shortcut + ; based on the checkbox value. + ${If} $CheckboxShortcuts == 0 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "false" + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false" ${Else} WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "true" - ${EndIf} - - ${If} $CheckboxShortcutOnDesktop == 1 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "true" - ${Else} - WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false" - ${EndIf} - - ${If} $CheckboxShortcutInStartMenu == 1 - WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true" - ${Else} - WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "false" ${EndIf} !ifdef MOZ_MAINTENANCE_SERVICE @@ -1749,7 +1827,7 @@ Function FinishInstall ${EndIf} ${EndIf} - ${If} $CheckboxShortcutOnBar == 1 + ${If} $CheckboxShortcuts == 1 ${If} ${AtMostWinVista} ClearErrors ${GetParameters} $0 @@ -1885,6 +1963,30 @@ Function OnClick_ButtonBrowse ${EndIf} FunctionEnd +Function OnChange_DroplistArch + ; When the user changes the 32/64-bit setting, change the default install path + ; to use the correct version of Program Files. But only do that if the user + ; hasn't selected their own install path yet, and if we didn't select our + ; default as the location of an existing install. + ${If} $INSTDIR == $InitialInstallDir + ${NSD_GetText} $DroplistArch $0 + ${If} $0 == "$(VERSION_32BIT)" + ${If} $PreviousInstallArch == 32 + StrCpy $InitialInstallDir $PreviousInstallDir + ${Else} + StrCpy $InitialInstallDir "${DefaultInstDir32bit}" + ${EndIf} + ${Else} + ${If} $PreviousInstallArch == 64 + StrCpy $InitialInstallDir $PreviousInstallDir + ${Else} + StrCpy $InitialInstallDir "${DefaultInstDir64bit}" + ${EndIf} + ${EndIf} + ${NSD_SetText} $DirRequest $InitialInstallDir + ${EndIf} +FunctionEnd + Function CheckSpace ${If} "$ExistingTopDir" != "" StrLen $0 "$ExistingTopDir" @@ -1949,6 +2051,7 @@ Function CanWrite GetTempFileName $2 "$0" Delete $2 CreateDirectory "$2" + ${If} ${FileExists} "$2" ${If} ${FileExists} "$INSTDIR" GetTempFileName $3 "$INSTDIR" diff --git a/browser/locales/en-US/chrome/browser/preferences/preferences.properties b/browser/locales/en-US/chrome/browser/preferences/preferences.properties index 149a952671eb..59ab19ba0f97 100644 --- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties @@ -198,3 +198,13 @@ disableContainersMsg=If you disable Container Tabs now, #S container tab will be disableContainersOkButton=Close #S Container Tab;Close #S Container Tabs disableContainersButton2=Keep enabled + +removeContainerAlertTitle=Remove This Container? + +# LOCALIZATION NOTE (removeContainerMsg): Semi-colon list of plural forms. +# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals +# #S is the number of container tabs +removeContainerMsg=If you remove this Container now, #S container tab will be closed. Are you sure you want to remove this Container?;If you remove this Container now, #S container tabs will be closed. Are you sure you want to remove this Container? + +removeContainerOkButton=Remove this Container +removeContainerButton2=Don’t remove this Container diff --git a/browser/locales/en-US/installer/nsisstrings.properties b/browser/locales/en-US/installer/nsisstrings.properties index 389405696987..82c2c40bfec4 100644 --- a/browser/locales/en-US/installer/nsisstrings.properties +++ b/browser/locales/en-US/installer/nsisstrings.properties @@ -41,11 +41,11 @@ CANCEL_BUTTON=Cancel OPTIONS_BUTTON=&Options MAKE_DEFAULT=&Make $BrandShortName my default browser -CREATE_SHORTCUTS=Create Shortcuts for $BrandShortName: -ADD_SC_TASKBAR=On my &Task bar -ADD_SC_QUICKLAUNCHBAR=On my &Quick Launch bar -ADD_CheckboxShortcutInStartMenu=In my &Start Menu Programs Folder -ADD_CheckboxShortcutOnDesktop=On my &Desktop +ADD_SC_DESKTOP_TASKBAR=&Create desktop and taskbar shortcuts for $BrandShortName +ADD_SC_DESKTOP_QUICKLAUNCHBAR=&Create desktop and quick launch shortcuts for $BrandShortName +VERSION_32BIT=32-bit $BrandShortName +VERSION_64BIT=64-bit $BrandShortName +ARCH_DROPLIST_LABEL=&Version to install SPACE_REQUIRED=Space Required: SPACE_AVAILABLE=Space Available: ONE_MOMENT_INSTALL=One moment, $BrandShortName will launch as soon as the install is complete… diff --git a/browser/themes/shared/autocomplete.inc.css b/browser/themes/shared/autocomplete.inc.css index f634bc9e4e4e..79402ff5c86f 100644 --- a/browser/themes/shared/autocomplete.inc.css +++ b/browser/themes/shared/autocomplete.inc.css @@ -12,15 +12,32 @@ padding: 0px 1px 0px 1px; } +#PopupAutoComplete > richlistbox > richlistitem > .ac-site-icon { + margin-inline-start: 4px; + margin-inline-end: 0; +} + #PopupAutoComplete > richlistbox > richlistitem > .ac-title { font: icon; - margin-inline-start: 6px; + margin-inline-start: 4px; } #PopupAutoComplete > richlistbox { padding: 0; } + +/* Login form autocompletion */ +#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon { + display: initial; + list-style-image: url(chrome://browser/skin/notification-icons.svg#login); +} + +#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon[selected] { + list-style-image: url(chrome://browser/skin/notification-icons.svg#login-highlighted); +} + + /* Insecure field warning */ #PopupAutoComplete > richlistbox > richlistitem[originaltype="insecureWarning"] { background-color: #F6F6F6; /* Bug 1319176 */ diff --git a/browser/themes/shared/notification-icons.svg b/browser/themes/shared/notification-icons.svg index 09b97533bee9..04ed3b950a74 100644 --- a/browser/themes/shared/notification-icons.svg +++ b/browser/themes/shared/notification-icons.svg @@ -21,6 +21,11 @@ clip-path: url(#clip); } + #login-highlighted { + fill: HighlightText; + fill-opacity: 1; + } + #plugin-blocked, #plugin-blocked:target ~ #strikeout { fill: #d92215; @@ -73,6 +78,7 @@ + diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index 601dd2737a37..16fde196b8cf 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -1106,7 +1106,11 @@ toolbar[brighttext] #close-button { #minimize-button, #restore-button, #close-button { - list-style-image: url("chrome://global/skin/icons/windowControls.png"); + /* Important to ensure this applies even on toolbar[brighttext] */ + list-style-image: url("chrome://global/skin/icons/windowControls.png") !important; + /* Also override background color to a avoid hover background styling + * leaking through around the image. */ + background-color: transparent !important; padding: 0; } diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index 5bd140814ce0..da85641d04c8 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -412,8 +412,8 @@ bool typeIsRefPtr(QualType Q) { // The method defined in clang for ignoring implicit nodes doesn't work with // some AST trees. To get around this, we define our own implementation of -// IgnoreImplicit. -const Stmt *IgnoreImplicit(const Stmt *s) { +// IgnoreTrivials. +const Stmt *IgnoreTrivials(const Stmt *s) { while (true) { if (auto *ewc = dyn_cast(s)) { s = ewc->getSubExpr(); @@ -423,6 +423,8 @@ const Stmt *IgnoreImplicit(const Stmt *s) { s = bte->getSubExpr(); } else if (auto *ice = dyn_cast(s)) { s = ice->getSubExpr(); + } else if (auto *pe = dyn_cast(s)) { + s = pe->getSubExpr(); } else { break; } @@ -431,8 +433,8 @@ const Stmt *IgnoreImplicit(const Stmt *s) { return s; } -const Expr *IgnoreImplicit(const Expr *e) { - return cast(IgnoreImplicit(static_cast(e))); +const Expr *IgnoreTrivials(const Expr *e) { + return cast(IgnoreTrivials(static_cast(e))); } } @@ -905,6 +907,8 @@ AST_MATCHER(CXXRecordDecl, needsMemMovableMembers) { AST_MATCHER(CXXConstructorDecl, isInterestingImplicitCtor) { const CXXConstructorDecl *Declaration = Node.getCanonicalDecl(); return + // Skip constructors in system headers + !ASTIsInSystemHeader(Declaration->getASTContext(), *Declaration) && // Skip ignored namespaces and paths !isInIgnoredNamespaceForImplicitCtor(Declaration) && !isIgnoredPathForImplicitCtor(Declaration) && @@ -1918,7 +1922,7 @@ void DiagnosticsMatcher::KungFuDeathGripChecker::run( return; } - const Expr *E = IgnoreImplicit(D->getInit()); + const Expr *E = IgnoreTrivials(D->getInit()); const CXXConstructExpr *CE = dyn_cast(E); if (CE && CE->getNumArgs() == 0) { // We don't report an error when we construct and don't use a nsCOMPtr / @@ -1931,10 +1935,10 @@ void DiagnosticsMatcher::KungFuDeathGripChecker::run( // We don't want to look at the single argument conversion constructors // which are inbetween the declaration and the actual object which we are // assigning into the nsCOMPtr/RefPtr. To do this, we repeatedly - // IgnoreImplicit, then look at the expression. If it is one of these + // IgnoreTrivials, then look at the expression. If it is one of these // conversion constructors, we ignore it and continue to dig. while ((CE = dyn_cast(E)) && CE->getNumArgs() == 1) { - E = IgnoreImplicit(CE->getArg(0)); + E = IgnoreTrivials(CE->getArg(0)); } // We allow taking a kungFuDeathGrip of `this` because it cannot change diff --git a/build/clang-plugin/tests/TestKungFuDeathGrip.cpp b/build/clang-plugin/tests/TestKungFuDeathGrip.cpp index 0b94d8a885b7..c9eef3ff2a5d 100644 --- a/build/clang-plugin/tests/TestKungFuDeathGrip.cpp +++ b/build/clang-plugin/tests/TestKungFuDeathGrip.cpp @@ -35,6 +35,7 @@ public: nsCOMPtr never_referenced; nsCOMPtr kfdg_t1(this); nsCOMPtr kfdg_t2 = this; + nsCOMPtr kfdg_t3 = (this); nsCOMPtr kfdg_m1(p); // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m1', or explicitly pass 'kfdg_m1' to `mozilla::Unused`}} nsCOMPtr kfdg_m2 = p; // expected-error {{Unused "kungFuDeathGrip" 'nsCOMPtr' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m2', or explicitly pass 'kfdg_m2' to `mozilla::Unused`}} @@ -51,8 +52,9 @@ public: RefPtr never_referenced2; - RefPtr kfdg_t3(this); - RefPtr kfdg_t4 = this; + RefPtr kfdg_t4(this); + RefPtr kfdg_t5 = this; + RefPtr kfdg_t6 = (this); RefPtr kfdg_m5(p); // expected-error {{Unused "kungFuDeathGrip" 'RefPtr' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m5', or explicitly pass 'kfdg_m5' to `mozilla::Unused`}} RefPtr kfdg_m6 = p; // expected-error {{Unused "kungFuDeathGrip" 'RefPtr' objects constructed from members are prohibited}} expected-note {{Please switch all accesses to this member to go through 'kfdg_m6', or explicitly pass 'kfdg_m6' to `mozilla::Unused`}} diff --git a/build/moz.configure/windows.configure b/build/moz.configure/windows.configure index b9a3898a1d2f..4751c10d34df 100644 --- a/build/moz.configure/windows.configure +++ b/build/moz.configure/windows.configure @@ -335,8 +335,11 @@ def lib_path(target, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir): atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target) if not os.path.isdir(atlmfc_dir): - die('Cannot find the ATL/MFC libraries in the Visual C++ directory (%s). ' - 'Please install them.' % vc_path) + # For Visual Studio 2017 + atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', sdk_target) + if not os.path.isdir(atlmfc_dir): + die('Cannot find the ATL/MFC libraries in the Visual C++ directory ' + '(%s). Please install them.' % vc_path) libs = [] diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index f7fbc50c77e8..d06d081824f4 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -326,9 +326,12 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, } nsSecurityFlags securityFlags = loadInfo->GetSecurityMode(); - if (securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS || - securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS || - securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) { + // The data: inheritance flags should only apply to the initial load, + // not to loads that it might have redirected to. + if (loadInfo->RedirectChain().IsEmpty() && + (securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS || + securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS || + securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) { nsCOMPtr uri; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); diff --git a/config/check_spidermonkey_style.py b/config/check_spidermonkey_style.py index d66d6dc65844..ea6e726a095e 100644 --- a/config/check_spidermonkey_style.py +++ b/config/check_spidermonkey_style.py @@ -87,7 +87,7 @@ included_inclnames_to_ignore = set([ 'unicode/udat.h', # ICU 'unicode/udatpg.h', # ICU 'unicode/uenum.h', # ICU - 'unicode/unorm.h', # ICU + 'unicode/unorm2.h', # ICU 'unicode/unum.h', # ICU 'unicode/unumsys.h', # ICU 'unicode/ustring.h', # ICU diff --git a/devtools/client/inspector/layout/layout.js b/devtools/client/inspector/layout/layout.js index 2f7c6726c007..52c69fb3011c 100644 --- a/devtools/client/inspector/layout/layout.js +++ b/devtools/client/inspector/layout/layout.js @@ -10,7 +10,7 @@ const { createFactory, createElement } = require("devtools/client/shared/vendor/ const { Provider } = require("devtools/client/shared/vendor/react-redux"); const { updateGrids } = require("./actions/grids"); -const App = createFactory(require("./components/app")); +const App = createFactory(require("./components/App")); const Store = require("./store"); const { LocalizationHelper } = require("devtools/shared/l10n"); diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 40e0457f1f57..d9faa67c01e1 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -13785,6 +13785,7 @@ public: const nsAString& aFileName, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream, + bool aNoOpenerImplied, bool aIsTrusted); NS_IMETHOD Run() override @@ -13801,6 +13802,7 @@ public: mHandler->OnLinkClickSync(mContent, mURI, mTargetSpec.get(), mFileName, mPostDataStream, mHeadersDataStream, + mNoOpenerImplied, nullptr, nullptr); } return NS_OK; @@ -13815,6 +13817,7 @@ private: nsCOMPtr mHeadersDataStream; nsCOMPtr mContent; PopupControlState mPopupState; + bool mNoOpenerImplied; bool mIsTrusted; }; @@ -13825,6 +13828,7 @@ OnLinkClickEvent::OnLinkClickEvent(nsDocShell* aHandler, const nsAString& aFileName, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream, + bool aNoOpenerImplied, bool aIsTrusted) : mHandler(aHandler) , mURI(aURI) @@ -13834,6 +13838,7 @@ OnLinkClickEvent::OnLinkClickEvent(nsDocShell* aHandler, , mHeadersDataStream(aHeadersDataStream) , mContent(aContent) , mPopupState(mHandler->mScriptGlobal->GetPopupControlState()) + , mNoOpenerImplied(aNoOpenerImplied) , mIsTrusted(aIsTrusted) { } @@ -13871,11 +13876,15 @@ nsDocShell::OnLinkClick(nsIContent* aContent, nsAutoString target; nsCOMPtr browserChrome3 = do_GetInterface(mTreeOwner); + bool noOpenerImplied = false; if (browserChrome3) { nsCOMPtr linkNode = do_QueryInterface(aContent); nsAutoString oldTarget(aTargetSpec); rv = browserChrome3->OnBeforeLinkTraversal(oldTarget, aURI, linkNode, mIsAppTab, target); + if (!oldTarget.Equals(target)) { + noOpenerImplied = true; + } } if (NS_FAILED(rv)) { @@ -13884,7 +13893,8 @@ nsDocShell::OnLinkClick(nsIContent* aContent, nsCOMPtr ev = new OnLinkClickEvent(this, aContent, aURI, target.get(), aFileName, - aPostDataStream, aHeadersDataStream, aIsTrusted); + aPostDataStream, aHeadersDataStream, noOpenerImplied, + aIsTrusted); return NS_DispatchToCurrentThread(ev); } @@ -13895,6 +13905,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent, const nsAString& aFileName, nsIInputStream* aPostDataStream, nsIInputStream* aHeadersDataStream, + bool aNoOpenerImplied, nsIDocShell** aDocShell, nsIRequest** aRequest) { @@ -13960,6 +13971,9 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent, flags |= INTERNAL_LOAD_FLAGS_NO_OPENER; } } + if (aNoOpenerImplied) { + flags |= INTERNAL_LOAD_FLAGS_NO_OPENER; + } } // Get the owner document of the link that was clicked, this will be diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 925115e95d8b..a723102c54bd 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -207,6 +207,7 @@ public: const nsAString& aFileName, nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0, + bool aNoOpenerImplied = false, nsIDocShell** aDocShell = 0, nsIRequest** aRequest = 0) override; NS_IMETHOD OnOverLink(nsIContent* aContent, diff --git a/docshell/base/nsILinkHandler.h b/docshell/base/nsILinkHandler.h index 7cdcd566dfa0..62cbccb59a59 100644 --- a/docshell/base/nsILinkHandler.h +++ b/docshell/base/nsILinkHandler.h @@ -59,6 +59,7 @@ public: * @param aFileName non-null when the link should be downloaded as the given file * @param aPostDataStream the POST data to send * @param aHeadersDataStream ??? + * @param aNoOpenerImplied if the link implies "noopener" * @param aDocShell (out-param) the DocShell that the request was opened on * @param aRequest the request that was opened */ @@ -68,6 +69,7 @@ public: const nsAString& aFileName, nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0, + bool aNoOpenerImplied = false, nsIDocShell** aDocShell = 0, nsIRequest** aRequest = 0) = 0; diff --git a/dom/animation/EffectCompositor.cpp b/dom/animation/EffectCompositor.cpp index 458511d93d60..700eef0f298f 100644 --- a/dom/animation/EffectCompositor.cpp +++ b/dom/animation/EffectCompositor.cpp @@ -86,6 +86,11 @@ FindAnimationsForCompositor(const nsIFrame* aFrame, return false; } + if (aFrame->StyleContext()->StyleSource().IsServoComputedValues()) { + NS_ERROR("stylo: cannot handle compositor-driven animations yet"); + return false; + } + // The animation cascade will almost always be up-to-date by this point // but there are some cases such as when we are restoring the refresh driver // from test control after seeking where it might not be the case. @@ -203,9 +208,11 @@ EffectCompositor::RequestRestyle(dom::Element* aElement, if (aRestyleType == RestyleType::Layer) { // Prompt layers to re-sync their animations. - MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(), - "stylo: Servo-backed style system should not be using " + if (mPresContext->RestyleManager()->IsServo()) { + NS_ERROR("stylo: Servo-backed style system should not be using " "EffectCompositor"); + return; + } mPresContext->RestyleManager()->AsGecko()->IncrementAnimationGeneration(); EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType); diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index 82eb8250b0ba..4833789998a6 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -170,11 +170,12 @@ DOMIntersectionObserver::UnlinkTarget(Element& aTarget) if (!mObservationTargets.Contains(&aTarget)) { return false; } - if (mObservationTargets.Count() == 1) { + + mObservationTargets.RemoveEntry(&aTarget); + if (mObservationTargets.Count() == 0) { Disconnect(); return false; } - mObservationTargets.RemoveEntry(&aTarget); return true; } @@ -195,6 +196,8 @@ DOMIntersectionObserver::Disconnect() if (!mConnected) { return; } + + mConnected = false; for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) { Element* target = iter.Get()->GetKey(); target->UnregisterIntersectionObserver(this); @@ -204,7 +207,6 @@ DOMIntersectionObserver::Disconnect() nsIDocument* document = mOwner->GetExtantDoc(); document->RemoveIntersectionObserver(this); } - mConnected = false; } void @@ -278,7 +280,10 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time if (rootFrame) { nsPresContext* presContext = rootFrame->PresContext(); while (!presContext->IsRootContentDocument()) { - presContext = rootFrame->PresContext()->GetParentPresContext(); + presContext = presContext->GetParentPresContext(); + if (!presContext) { + break; + } rootFrame = presContext->PresShell()->GetRootScrollFrame(); } root = rootFrame->GetContent()->AsElement(); diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 1045ee4e5003..8b731a7110e1 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -236,50 +236,10 @@ UnwrapObject(JSObject* obj, U& value) PrototypeTraits::Depth); } -inline bool -IsNotDateOrRegExp(JSContext* cx, JS::Handle obj, - bool* notDateOrRegExp) -{ - MOZ_ASSERT(obj); - - js::ESClass cls; - if (!js::GetBuiltinClass(cx, obj, &cls)) { - return false; - } - - *notDateOrRegExp = cls != js::ESClass::Date && cls != js::ESClass::RegExp; - return true; -} - MOZ_ALWAYS_INLINE bool -IsObjectValueConvertibleToDictionary(JSContext* cx, - JS::Handle objVal, - bool* convertible) +IsConvertibleToDictionary(JS::Handle val) { - JS::Rooted obj(cx, &objVal.toObject()); - return IsNotDateOrRegExp(cx, obj, convertible); -} - -MOZ_ALWAYS_INLINE bool -IsConvertibleToDictionary(JSContext* cx, JS::Handle val, - bool* convertible) -{ - if (val.isNullOrUndefined()) { - *convertible = true; - return true; - } - if (!val.isObject()) { - *convertible = false; - return true; - } - return IsObjectValueConvertibleToDictionary(cx, val, convertible); -} - -MOZ_ALWAYS_INLINE bool -IsConvertibleToCallbackInterface(JSContext* cx, JS::Handle obj, - bool* convertible) -{ - return IsNotDateOrRegExp(cx, obj, convertible); + return val.isNullOrUndefined() || val.isObject(); } // The items in the protoAndIfaceCache are indexed by the prototypes::id::ID, @@ -2309,6 +2269,22 @@ AddStringToIDVector(JSContext* cx, JS::AutoIdVector& vector, const char* name) AtomizeAndPinJSString(cx, *(vector[vector.length() - 1]).address(), name); } +// We use one constructor JSNative to represent all DOM interface objects (so +// we can easily detect when we need to wrap them in an Xray wrapper). We store +// the real JSNative in the mNative member of a JSNativeHolder in the +// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a +// specific interface object. We also store the NativeProperties in the +// JSNativeHolder. +// Note that some interface objects are not yet a JSFunction but a normal +// JSObject with a DOMJSClass, those do not use these slots. + +enum { + CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0 +}; + +bool +Constructor(JSContext* cx, unsigned argc, JS::Value* vp); + // Implementation of the bits that XrayWrapper needs /** @@ -2382,6 +2358,9 @@ XrayGetNativeProto(JSContext* cx, JS::Handle obj, } else { protop.set(JS::GetRealmObjectPrototype(cx)); } + } else if (JS_ObjectIsFunction(cx, obj)) { + MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor)); + protop.set(JS::GetRealmFunctionPrototype(cx)); } else { const js::Class* clasp = js::GetObjectClass(obj); MOZ_ASSERT(IsDOMIfaceAndProtoClass(clasp)); @@ -2448,22 +2427,6 @@ extern const js::ClassOps sBoringInterfaceObjectClassClassOps; extern const js::ObjectOps sInterfaceObjectClassObjectOps; -// We use one constructor JSNative to represent all DOM interface objects (so -// we can easily detect when we need to wrap them in an Xray wrapper). We store -// the real JSNative in the mNative member of a JSNativeHolder in the -// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a -// specific interface object. We also store the NativeProperties in the -// JSNativeHolder. -// Note that some interface objects are not yet a JSFunction but a normal -// JSObject with a DOMJSClass, those do not use these slots. - -enum { - CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0 -}; - -bool -Constructor(JSContext* cx, unsigned argc, JS::Value* vp); - inline bool UseDOMXray(JSObject* obj) { @@ -2480,7 +2443,7 @@ HasConstructor(JSObject* obj) return JS_IsNativeFunction(obj, Constructor) || js::GetObjectClass(obj)->getConstruct(); } - #endif +#endif // Helpers for creating a const version of a type. template diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 886c476517ee..917a504d2e93 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5783,30 +5783,24 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, exceptionCode=exceptionCode) if failureCode is not None: - if isDefinitelyObject: - dictionaryTest = "IsObjectValueConvertibleToDictionary" + # This means we're part of an overload or union conversion, and + # should simply skip stuff if our value is not convertible to + # dictionary, instead of trying and throwing. If we're either + # isDefinitelyObject or isNullOrUndefined then we're convertible to + # dictionary and don't need to check here. + if isDefinitelyObject or isNullOrUndefined: + template = conversionCode else: - dictionaryTest = "IsConvertibleToDictionary" - - template = fill(""" - { // scope for isConvertible - bool isConvertible; - if (!${testConvertible}(cx, ${val}, &isConvertible)) { - $*{exceptionCode} - } - if (!isConvertible) { - $*{failureCode} - } - - $*{conversionCode} - } - - """, - testConvertible=dictionaryTest, - val=val, - exceptionCode=exceptionCode, - failureCode=failureCode, - conversionCode=conversionCode) + template = fill( + """ + if (!IsConvertibleToDictionary(${val})) { + $*{failureCode} + } + $*{conversionCode} + """, + val=val, + failureCode=failureCode, + conversionCode=conversionCode) else: template = conversionCode @@ -8030,12 +8024,12 @@ class CGMethodCall(CGThing): # 1) A platform object that's not a platform array object, being # passed to an interface or "object" arg. # 2) A Date object being passed to a Date or "object" arg. - # 3) A RegExp object being passed to a RegExp or "object" arg. - # 4) A callable object being passed to a callback or "object" arg. - # 5) An iterable object being passed to a sequence arg. - # 6) Any non-Date and non-RegExp object being passed to a - # array or callback interface or dictionary or - # "object" arg. + # XXXbz This is actually gone from the spec now, but we still + # have some APIs using Date. + # 3) A callable object being passed to a callback or "object" arg. + # 4) An iterable object being passed to a sequence arg. + # 5) Any object being passed to a array or callback interface or + # dictionary or "object" arg. # First grab all the overloads that have a non-callback interface # (which includes typed arrays and arraybuffers) at the @@ -12591,14 +12585,8 @@ class CGDictionary(CGThing): else: body += dedent( """ - { // scope for isConvertible - bool isConvertible; - if (!IsConvertibleToDictionary(cx, val, &isConvertible)) { - return false; - } - if (!isConvertible) { - return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription); - } + if (!IsConvertibleToDictionary(val)) { + return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription); } """) diff --git a/dom/bindings/parser/tests/test_distinguishability.py b/dom/bindings/parser/tests/test_distinguishability.py index d7780c1ffa11..9a6cf13c4ebb 100644 --- a/dom/bindings/parser/tests/test_distinguishability.py +++ b/dom/bindings/parser/tests/test_distinguishability.py @@ -163,7 +163,8 @@ def WebIDLTest(parser, harness): "Promise", "Promise?", "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "Uint8Array", "Uint16Array" ] - # When we can parse Date and RegExp, we need to add them here. + # When we can parse Date, we need to add it here. + # XXXbz we can, and should really do that... # Try to categorize things a bit to keep list lengths down def allBut(list1, list2): diff --git a/dom/bindings/test/chrome.ini b/dom/bindings/test/chrome.ini index fdf90d300bd4..9fdbd7fd30ba 100644 --- a/dom/bindings/test/chrome.ini +++ b/dom/bindings/test/chrome.ini @@ -19,3 +19,4 @@ skip-if = e10s # prerendering doesn't work in e10s yet skip-if = e10s # prerendering doesn't work in e10s yet [test_bug1123516_maplikesetlikechrome.xul] skip-if = debug == false +[test_bug1287912.html] diff --git a/dom/bindings/test/test_bug1287912.html b/dom/bindings/test/test_bug1287912.html new file mode 100644 index 000000000000..ae72b23165f0 --- /dev/null +++ b/dom/bindings/test/test_bug1287912.html @@ -0,0 +1,37 @@ + + + + + + Test for Bug 1287912 + + + + +Mozilla Bug 1287912 +

+ +
+
+
+ + diff --git a/dom/bindings/test/test_exception_messages.html b/dom/bindings/test/test_exception_messages.html index a0f0cabe63a2..9d5378f23fc0 100644 --- a/dom/bindings/test/test_exception_messages.html +++ b/dom/bindings/test/test_exception_messages.html @@ -44,9 +44,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=882653 [ 'document.createTreeWalker(document, 0xFFFFFFFF, { acceptNode: 5 }).nextNode()', "Property 'acceptNode' is not callable.", "non-callable callback interface operation property" ], - [ '(new TextDecoder).decode(new Uint8Array(), new RegExp())', + [ '(new TextDecoder).decode(new Uint8Array(), 5)', "Argument 2 of TextDecoder.decode can't be converted to a dictionary.", - "regexp passed for a dictionary" ], + "primitive passed for a dictionary" ], [ 'URL.createObjectURL(null, null)', "Argument 1 is not valid for any of the 2-argument overloads of URL.createObjectURL.", "overload resolution failure" ], diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h index 52609c13e5aa..144984f355f8 100644 --- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -121,7 +121,7 @@ public: { const char funcName[] = "compressedTexImage3D"; const uint8_t funcDims = 3; - const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride); + const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, border, src); } @@ -135,7 +135,7 @@ public: { const char funcName[] = "compressedTexSubImage3D"; const uint8_t funcDims = 3; - const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride); + const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, src); } @@ -159,7 +159,7 @@ public: GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { - const TexImageSourceAdapter src(anySrc, &out_error); + const TexImageSourceAdapter src(&anySrc, &out_error); TexImage3D(target, level, internalFormat, width, height, depth, border, unpackFormat, unpackType, src); } @@ -169,7 +169,7 @@ public: GLenum unpackType, const dom::ArrayBufferView& view, GLuint viewElemOffset, ErrorResult&) { - const TexImageSourceAdapter src(view, viewElemOffset); + const TexImageSourceAdapter src(&view, viewElemOffset); TexImage3D(target, level, internalFormat, width, height, depth, border, unpackFormat, unpackType, src); } @@ -194,7 +194,7 @@ public: GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { - const TexImageSourceAdapter src(anySrc, &out_error); + const TexImageSourceAdapter src(&anySrc, &out_error); TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, unpackType, src); } @@ -212,7 +212,7 @@ public: return; const auto& srcView = maybeSrcView.Value(); - const TexImageSourceAdapter src(srcView, srcElemOffset); + const TexImageSourceAdapter src(&srcView, srcElemOffset); TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, unpackType, src); } diff --git a/dom/canvas/WebGL2ContextBuffers.cpp b/dom/canvas/WebGL2ContextBuffers.cpp index fd5c986089c3..81812e8f9745 100644 --- a/dom/canvas/WebGL2ContextBuffers.cpp +++ b/dom/canvas/WebGL2ContextBuffers.cpp @@ -31,15 +31,6 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget, if (!writeBuffer) return; - if (readBuffer->mNumActiveTFOs || - writeBuffer->mNumActiveTFOs) - { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - funcName); - return; - } - if (!ValidateNonNegative(funcName, "readOffset", readOffset) || !ValidateNonNegative(funcName, "writeOffset", writeOffset) || !ValidateNonNegative(funcName, "size", size)) @@ -129,21 +120,6 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr srcByteOffset, //// - if (buffer->mNumActiveTFOs) { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - funcName); - return; - } - - if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && - mBoundTransformFeedback->mIsActive) - { - ErrorInvalidOperation("%s: Currently bound transform feedback is active.", - funcName); - return; - } - if (!CheckedInt(byteLen).isValid()) { ErrorOutOfMemory("%s: Size too large.", funcName); return; diff --git a/dom/canvas/WebGLBuffer.cpp b/dom/canvas/WebGLBuffer.cpp index f47176d73ea2..2647bc33cbac 100644 --- a/dom/canvas/WebGLBuffer.cpp +++ b/dom/canvas/WebGLBuffer.cpp @@ -18,15 +18,12 @@ WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf) , mContent(Kind::Undefined) , mUsage(LOCAL_GL_STATIC_DRAW) , mByteLength(0) - , mNumActiveTFOs(0) - , mBoundForTF(false) { mContext->mBuffers.insertBack(this); } WebGLBuffer::~WebGLBuffer() { - MOZ_ASSERT(!mNumActiveTFOs); DeleteOnce(); } @@ -111,13 +108,6 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa if (!ValidateBufferUsageEnum(mContext, funcName, usage)) return; - if (mNumActiveTFOs) { - mContext->ErrorInvalidOperation("%s: Buffer is bound to an active transform" - " feedback object.", - funcName); - return; - } - const auto& gl = mContext->gl; gl->MakeCurrent(); const ScopedLazyBind lazyBind(gl, target, this); @@ -220,15 +210,6 @@ WebGLBuffer::IsElementArrayUsedWithMultipleTypes() const bool WebGLBuffer::ValidateCanBindToTarget(const char* funcName, GLenum target) { - const bool wouldBeTF = (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER); - if (mWebGLRefCnt && wouldBeTF != mBoundForTF) { - mContext->ErrorInvalidOperation("%s: Buffers cannot be simultaneously bound to " - " transform feedback and bound elsewhere.", - funcName); - return false; - } - mBoundForTF = wouldBeTF; - /* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1 * * In the WebGL 2 API, buffers have their WebGL buffer type diff --git a/dom/canvas/WebGLBuffer.h b/dom/canvas/WebGLBuffer.h index 3bb1db1071f9..cb4c87edc33b 100644 --- a/dom/canvas/WebGLBuffer.h +++ b/dom/canvas/WebGLBuffer.h @@ -79,8 +79,6 @@ protected: GLenum mUsage; size_t mByteLength; UniquePtr mCache; - size_t mNumActiveTFOs; - bool mBoundForTF; }; } // namespace mozilla diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index e05e612d43e9..bbfa26e6097b 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -120,6 +120,7 @@ WebGLContext::WebGLContext() , mMaxFetchedInstances(0) , mLayerIsMirror(false) , mBypassShaderValidation(false) + , mBuffersForUB_Dirty(true) , mContextLossHandler(this) , mNeedsFakeNoAlpha(false) , mNeedsFakeNoDepth(false) @@ -262,6 +263,7 @@ WebGLContext::DestroyResourcesAndContext() mQuerySlot_TimeElapsed = nullptr; mIndexedUniformBufferBindings.clear(); + OnUBIndexedBindingsChanged(); ////// @@ -2570,6 +2572,42 @@ WebGLContext::ValidateArrayBufferView(const char* funcName, return true; } +//// + +const decltype(WebGLContext::mBuffersForUB)& +WebGLContext::BuffersForUB() const +{ + if (mBuffersForUB_Dirty) { + mBuffersForUB.clear(); + for (const auto& cur : mIndexedUniformBufferBindings) { + if (cur.mBufferBinding) { + mBuffersForUB.insert(cur.mBufferBinding.get()); + } + } + mBuffersForUB_Dirty = false; + } + return mBuffersForUB; +} + +//// + +bool +WebGLContext::ValidateForNonTransformFeedback(const char* funcName, WebGLBuffer* buffer) +{ + if (!mBoundTransformFeedback) + return true; + + const auto& buffersForTF = mBoundTransformFeedback->BuffersForTF(); + if (buffersForTF.count(buffer)) { + ErrorInvalidOperation("%s: Specified WebGLBuffer is currently bound for transform" + " feedback.", + funcName); + return false; + } + + return true; +} + //////////////////////////////////////////////////////////////////////////////// // XPCOM goop diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index e00c2fd8e441..e7634474361e 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -220,40 +220,40 @@ protected: struct TexImageSourceAdapter final : public TexImageSource { - TexImageSourceAdapter(const dom::Nullable& maybeView, + TexImageSourceAdapter(const dom::Nullable* maybeView, ErrorResult*) { - if (!maybeView.IsNull()) { - mView = &(maybeView.Value()); + if (!maybeView->IsNull()) { + mView = &(maybeView->Value()); } } - TexImageSourceAdapter(const dom::ArrayBufferView& view, ErrorResult*) { - mView = &view; + TexImageSourceAdapter(const dom::ArrayBufferView* view, ErrorResult*) { + mView = view; } - TexImageSourceAdapter(const dom::ArrayBufferView& view, GLuint viewElemOffset, + TexImageSourceAdapter(const dom::ArrayBufferView* view, GLuint viewElemOffset, GLuint viewElemLengthOverride = 0) { - mView = &view; + mView = view; mViewElemOffset = viewElemOffset; mViewElemLengthOverride = viewElemLengthOverride; } - TexImageSourceAdapter(WebGLsizeiptr pboOffset, GLuint ignored1, GLuint ignored2 = 0) { - mPboOffset = &pboOffset; + TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, GLuint ignored1, GLuint ignored2 = 0) { + mPboOffset = pboOffset; } - TexImageSourceAdapter(WebGLsizeiptr pboOffset, ErrorResult* ignored) { - mPboOffset = &pboOffset; + TexImageSourceAdapter(const WebGLsizeiptr* pboOffset, ErrorResult* ignored) { + mPboOffset = pboOffset; } - TexImageSourceAdapter(const dom::ImageData& imageData, ErrorResult*) { - mImageData = &imageData; + TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) { + mImageData = imageData; } - TexImageSourceAdapter(const dom::Element& domElem, ErrorResult* const out_error) { - mDomElem = &domElem; + TexImageSourceAdapter(const dom::Element* domElem, ErrorResult* const out_error) { + mDomElem = domElem; mOut_error = out_error; } }; @@ -1026,7 +1026,7 @@ public: const char funcName[] = "compressedTexImage2D"; const uint8_t funcDims = 2; const GLsizei depth = 1; - const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride); + const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, border, src); } @@ -1041,7 +1041,7 @@ public: const uint8_t funcDims = 2; const GLint zOffset = 0; const GLsizei depth = 1; - const TexImageSourceAdapter src(anySrc, viewElemOffset, viewElemLengthOverride); + const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, src); } @@ -1115,7 +1115,7 @@ public: GLsizei height, GLint border, GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { - const TexImageSourceAdapter src(anySrc, &out_error); + const TexImageSourceAdapter src(&anySrc, &out_error); TexImage2D(target, level, internalFormat, width, height, border, unpackFormat, unpackType, src); } @@ -1125,7 +1125,7 @@ public: const dom::ArrayBufferView& view, GLuint viewElemOffset, ErrorResult&) { - const TexImageSourceAdapter src(view, viewElemOffset); + const TexImageSourceAdapter src(&view, viewElemOffset); TexImage2D(target, level, internalFormat, width, height, border, unpackFormat, unpackType, src); } @@ -1155,7 +1155,7 @@ public: GLsizei width, GLsizei height, GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { - const TexImageSourceAdapter src(anySrc, &out_error); + const TexImageSourceAdapter src(&anySrc, &out_error); TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat, unpackType, src); } @@ -1165,7 +1165,7 @@ public: GLenum unpackType, const dom::ArrayBufferView& view, GLuint viewElemOffset, ErrorResult&) { - const TexImageSourceAdapter src(view, viewElemOffset); + const TexImageSourceAdapter src(&view, viewElemOffset); TexSubImage2D(target, level, xOffset, yOffset, width, height, unpackFormat, unpackType, src); } @@ -1580,7 +1580,9 @@ protected: } WebGLRefPtr* ValidateBufferSlot(const char* funcName, GLenum target); +public: WebGLBuffer* ValidateBufferSelection(const char* funcName, GLenum target); +protected: IndexedBufferBinding* ValidateIndexedBufferSlot(const char* funcName, GLenum target, GLuint index); @@ -1596,6 +1598,8 @@ protected: return true; } + bool ValidateForNonTransformFeedback(const char* funcName, WebGLBuffer* buffer); + public: template bool ValidateNonNull(const char* funcName, const dom::Nullable& maybe) { @@ -1754,6 +1758,17 @@ protected: //////////////////////////////////// +private: + mutable bool mBuffersForUB_Dirty; + mutable std::set mBuffersForUB; + +public: + void OnUBIndexedBindingsChanged() const { mBuffersForUB_Dirty = true; } + const decltype(mBuffersForUB)& BuffersForUB() const; + + //////////////////////////////////// + +protected: // Generic Vertex Attributes UniquePtr mVertexAttribType; GLfloat mVertexAttrib0Vector[4]; diff --git a/dom/canvas/WebGLContextBuffers.cpp b/dom/canvas/WebGLContextBuffers.cpp index c3fc7035beb4..03bd50934b39 100644 --- a/dom/canvas/WebGLContextBuffers.cpp +++ b/dom/canvas/WebGLContextBuffers.cpp @@ -75,6 +75,9 @@ WebGLContext::ValidateBufferSelection(const char* funcName, GLenum target) return nullptr; } + if (!ValidateForNonTransformFeedback(funcName, buffer.get())) + return nullptr; + return buffer.get(); } @@ -212,6 +215,15 @@ WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer) if (buffer) { buffer->SetContentAfterBind(target); } + + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + mBoundTransformFeedback->OnIndexedBindingsChanged(); + break; + case LOCAL_GL_UNIFORM: + OnUBIndexedBindingsChanged(); + break; + } } void @@ -296,6 +308,15 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, if (buffer) { buffer->SetContentAfterBind(target); } + + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + mBoundTransformFeedback->OnIndexedBindingsChanged(); + break; + case LOCAL_GL_UNIFORM: + OnUBIndexedBindingsChanged(); + break; + } } //////////////////////////////////////// @@ -383,13 +404,6 @@ WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset, if (!buffer) return; - if (buffer->mNumActiveTFOs) { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - "bufferSubData"); - return; - } - if (!buffer->ValidateRange(funcName, dstByteOffset, dataLen)) return; diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp index d5411bb566e9..38447699b62c 100644 --- a/dom/canvas/WebGLContextDraw.cpp +++ b/dom/canvas/WebGLContextDraw.cpp @@ -19,6 +19,8 @@ #include "WebGLVertexArray.h" #include "WebGLVertexAttribData.h" +#include + namespace mozilla { // For a Tegra workaround. @@ -300,6 +302,16 @@ WebGLContext::DrawArrays_check(const char* funcName, GLenum mode, GLint first, //////////////////////////////////////// +template +static bool +DoSetsIntersect(const std::set& a, const std::set& b) +{ + std::vector intersection; + std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), + std::back_inserter(intersection)); + return bool(intersection.size()); +} + class ScopedDrawHelper final { WebGLContext* const mWebGL; @@ -343,7 +355,7 @@ public: //// // Check UBO sizes. - const auto& linkInfo = webgl->mActiveProgramLinkInfo; + const auto& linkInfo = mWebGL->mActiveProgramLinkInfo; for (const auto& cur : linkInfo->uniformBlocks) { const auto& dataSize = cur->mDataSize; const auto& binding = cur->mBinding; @@ -366,6 +378,22 @@ public: //// + const auto& tfo = mWebGL->mBoundTransformFeedback; + if (tfo) { + const auto& buffersForTF = tfo->BuffersForTF(); + const auto& buffersForUB = mWebGL->BuffersForUB(); + if (DoSetsIntersect(buffersForTF, buffersForUB)) { + mWebGL->ErrorInvalidOperation("%s: At least one WebGLBuffer is bound for" + " both transform feedback and as a uniform" + " buffer.", + funcName); + *out_error = true; + return; + } + } + + //// + mWebGL->RunContextLossTimer(); } diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index ae1d72cb25b7..6f091d999e9e 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -1462,41 +1462,33 @@ void WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, WebGLsizeiptr offset, ErrorResult& out_error) { + const char funcName[] = "readPixels"; if (!ReadPixels_SharedPrecheck(&out_error)) return; - if (!mBoundPixelPackBuffer) { - ErrorInvalidOperation("readPixels: PIXEL_PACK_BUFFER must not be null."); + const auto& buffer = ValidateBufferSelection(funcName, LOCAL_GL_PIXEL_PACK_BUFFER); + if (!buffer) return; - } - - if (mBoundPixelPackBuffer->mNumActiveTFOs) { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - "readPixels"); - return; - } ////// - if (offset < 0) { - ErrorInvalidValue("readPixels: offset must not be negative."); + if (!ValidateNonNegative(funcName, "offset", offset)) return; - } { const auto bytesPerType = webgl::BytesPerPixel({LOCAL_GL_RED, type}); if (offset % bytesPerType != 0) { - ErrorInvalidOperation("readPixels: `offset` must be divisible by the size" - " a `type` in bytes."); + ErrorInvalidOperation("%s: `offset` must be divisible by the size of `type`" + " in bytes.", + funcName); return; } } ////// - const auto bytesAvailable = mBoundPixelPackBuffer->ByteLength(); + const auto bytesAvailable = buffer->ByteLength(); const auto checkedBytesAfterOffset = CheckedUint32(bytesAvailable) - offset; uint32_t bytesAfterOffset = 0; @@ -1505,7 +1497,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum } gl->MakeCurrent(); - const ScopedLazyBind lazyBind(gl, LOCAL_GL_PIXEL_PACK_BUFFER, mBoundPixelPackBuffer); + const ScopedLazyBind lazyBind(gl, LOCAL_GL_PIXEL_PACK_BUFFER, buffer); ReadPixelsImpl(x, y, width, height, format, type, (void*)offset, bytesAfterOffset); } diff --git a/dom/canvas/WebGLProgram.cpp b/dom/canvas/WebGLProgram.cpp index 50ffd530a0b0..8abf4edb6e4d 100644 --- a/dom/canvas/WebGLProgram.cpp +++ b/dom/canvas/WebGLProgram.cpp @@ -1444,7 +1444,7 @@ WebGLProgram::TransformFeedbackVaryings(const dom::Sequence& varyings, GLuint maxAttribs = 0; gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxAttribs); - if (varyings.Length() >= maxAttribs) { + if (varyings.Length() > maxAttribs) { mContext->ErrorInvalidValue("%s: Length of `varyings` exceeds %s.", funcName, "TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"); diff --git a/dom/canvas/WebGLTextureUpload.cpp b/dom/canvas/WebGLTextureUpload.cpp index 0f76a9c6114b..b65510162c1a 100644 --- a/dom/canvas/WebGLTextureUpload.cpp +++ b/dom/canvas/WebGLTextureUpload.cpp @@ -185,14 +185,19 @@ FromView(WebGLContext* webgl, const char* funcName, TexImageTarget target, static UniquePtr FromPboOffset(WebGLContext* webgl, const char* funcName, TexImageTarget target, - uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset, - size_t availBufferBytes) + uint32_t width, uint32_t height, uint32_t depth, WebGLsizeiptr pboOffset) { if (pboOffset < 0) { webgl->ErrorInvalidValue("%s: offset cannot be negative.", funcName); return nullptr; } + const auto& buffer = webgl->ValidateBufferSelection(funcName, + LOCAL_GL_PIXEL_UNPACK_BUFFER); + if (!buffer) + return nullptr; + + size_t availBufferBytes = buffer->ByteLength(); if (size_t(pboOffset) > availBufferBytes) { webgl->ErrorInvalidOperation("%s: Offset is passed end of buffer.", funcName); return nullptr; @@ -366,25 +371,12 @@ WebGLContext::From(const char* funcName, TexImageTarget target, GLsizei rawWidth } if (src.mPboOffset) { - if (!mBoundPixelUnpackBuffer) { - ErrorInvalidOperation("%s: PACK_BUFFER must be non-null.", funcName); - return nullptr; - } - - if (mBoundPixelUnpackBuffer->mNumActiveTFOs) { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - funcName); - return nullptr; - } - - const auto& availBytes = mBoundPixelUnpackBuffer->ByteLength(); return FromPboOffset(this, funcName, target, width, height, depth, - *(src.mPboOffset), availBytes); + *(src.mPboOffset)); } if (mBoundPixelUnpackBuffer) { - ErrorInvalidOperation("%s: PACK_BUFFER must be null.", funcName); + ErrorInvalidOperation("%s: PIXEL_UNPACK_BUFFER must be null.", funcName); return nullptr; } @@ -1370,25 +1362,12 @@ WebGLContext::FromCompressed(const char* funcName, TexImageTarget target, } if (src.mPboOffset) { - if (!mBoundPixelUnpackBuffer) { - ErrorInvalidOperation("%s: PACK_BUFFER must be non-null.", funcName); - return nullptr; - } - - if (mBoundPixelUnpackBuffer->mNumActiveTFOs) { - ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" - " object.", - funcName); - return nullptr; - } - - const auto& availBytes = mBoundPixelUnpackBuffer->ByteLength(); return FromPboOffset(this, funcName, target, width, height, depth, - *(src.mPboOffset), availBytes); + *(src.mPboOffset)); } if (mBoundPixelUnpackBuffer) { - ErrorInvalidOperation("%s: PACK_BUFFER must be null.", funcName); + ErrorInvalidOperation("%s: PIXEL_UNPACK_BUFFER must be null.", funcName); return nullptr; } diff --git a/dom/canvas/WebGLTransformFeedback.cpp b/dom/canvas/WebGLTransformFeedback.cpp index 82ec8c648f01..2fa2752be879 100644 --- a/dom/canvas/WebGLTransformFeedback.cpp +++ b/dom/canvas/WebGLTransformFeedback.cpp @@ -17,6 +17,7 @@ WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl, GLuint tf) , mIndexedBindings(webgl->mGLMaxTransformFeedbackSeparateAttribs) , mIsPaused(false) , mIsActive(false) + , mBuffersForTF_Dirty(true) { mContext->mTransformFeedbacks.insertBack(this); } @@ -36,6 +37,28 @@ WebGLTransformFeedback::Delete() removeFrom(mContext->mTransformFeedbacks); } +//// + +const decltype(WebGLTransformFeedback::mBuffersForTF)& +WebGLTransformFeedback::BuffersForTF() const +{ + // The generic bind point cannot incur undefined read/writes because otherwise it + // would be impossible to read back from this. The spec implies that readback from + // the TRANSFORM_FEEDBACK target is possible, just not simultaneously with being + // "bound or in use for transform feedback". + // Therefore, only the indexed bindings of the TFO count. + if (mBuffersForTF_Dirty) { + mBuffersForTF.clear(); + for (const auto& cur : mIndexedBindings) { + if (cur.mBufferBinding) { + mBuffersForTF.insert(cur.mBufferBinding.get()); + } + } + mBuffersForTF_Dirty = false; + } + return mBuffersForTF; +} + //////////////////////////////////////// void @@ -107,13 +130,6 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode) //// - for (const auto& cur : mIndexedBindings) { - const auto& buffer = cur.mBufferBinding; - if (buffer) { - buffer->mNumActiveTFOs++; - } - } - mActive_Program->mNumActiveTFOs++; } @@ -139,13 +155,6 @@ WebGLTransformFeedback::EndTransformFeedback() //// - for (const auto& cur : mIndexedBindings) { - const auto& buffer = cur.mBufferBinding; - if (buffer) { - buffer->mNumActiveTFOs--; - } - } - mActive_Program->mNumActiveTFOs--; } diff --git a/dom/canvas/WebGLTransformFeedback.h b/dom/canvas/WebGLTransformFeedback.h index 34747af74efb..e681242291a0 100644 --- a/dom/canvas/WebGLTransformFeedback.h +++ b/dom/canvas/WebGLTransformFeedback.h @@ -37,6 +37,9 @@ private: MOZ_INIT_OUTSIDE_CTOR size_t mActive_VertPosition; MOZ_INIT_OUTSIDE_CTOR size_t mActive_VertCapacity; + mutable bool mBuffersForTF_Dirty; + mutable std::set mBuffersForTF; + public: WebGLTransformFeedback(WebGLContext* webgl, GLuint tf); private: @@ -50,6 +53,11 @@ public: WebGLContext* GetParentObject() const { return mContext; } virtual JSObject* WrapObject(JSContext*, JS::Handle) override; + //// + + void OnIndexedBindingsChanged() const { mBuffersForTF_Dirty = true; } + const decltype(mBuffersForTF)& BuffersForTF() const; + // GL Funcs void BeginTransformFeedback(GLenum primMode); void EndTransformFeedback(); diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html index a9d13496abd1..35532834c99f 100644 --- a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html @@ -61,6 +61,8 @@ shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0"); gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW); +wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); + shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer1"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0"); @@ -97,11 +99,13 @@ shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4"); gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW); +wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4"); gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 12, gl.STATIC_DRAW); +wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8"); shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4"); diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html index 57a8a8fbf3a2..206f07f0689f 100644 --- a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html @@ -88,7 +88,7 @@ var testBindingFn = function(firstBindFn, secondBindFn, firstTarget, secondTarge wtu.glErrorShouldBe(gl, gl.NO_ERROR, messagePrefix + "WORK"); else wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, messagePrefix + "FAIL"); - + /* if ((firstTarget == gl.TRANSFORM_FEEDBACK_BUFFER && secondTarget != gl.TRANSFORM_FEEDBACK_BUFFER) || (firstTarget != gl.TRANSFORM_FEEDBACK_BUFFER && secondTarget == gl.TRANSFORM_FEEDBACK_BUFFER)) { bind(firstBindFn, firstTarget, buffer); @@ -98,6 +98,7 @@ var testBindingFn = function(firstBindFn, secondBindFn, firstTarget, secondTarge + " and simultaneously binding buffer with " + secondBindFn + " to gl." + secondTargetStr + " should FAIL"; wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, message); } + */ } var testBinding = function(firstTarget, secondTarget) { diff --git a/dom/filesystem/Directory.h b/dom/filesystem/Directory.h index 09473b2bb851..5814b95994c5 100644 --- a/dom/filesystem/Directory.h +++ b/dom/filesystem/Directory.h @@ -144,6 +144,12 @@ public: bool ClonableToDifferentThreadOrProcess() const; + nsIFile* + GetInternalNsIFile() const + { + return mFile; + } + private: Directory(nsISupports* aParent, nsIFile* aFile, diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index 0088b57563a9..27d0fcb54b9d 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -829,7 +829,7 @@ HTMLFormElement::SubmitSubmission(HTMLFormSubmission* aFormSubmission) rv = linkHandler->OnLinkClickSync(this, actionURI, target.get(), NullString(), - postDataStream, nullptr, + postDataStream, nullptr, false, getter_AddRefs(docShell), getter_AddRefs(mSubmittingRequest)); NS_ENSURE_SUBMIT_SUCCESS(rv); diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index d4f6ee507758..42af7c563546 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -485,28 +485,37 @@ namespace { * where the file picker can create Blobs. */ static already_AddRefed -DOMFileOrDirectoryToLocalFile(const OwningFileOrDirectory& aData) +LastUsedDirectory(const OwningFileOrDirectory& aData) { - nsString path; - if (aData.IsFile()) { - ErrorResult rv; - aData.GetAsFile()->GetMozFullPathInternal(path, rv); - if (rv.Failed() || path.IsEmpty()) { - rv.SuppressException(); + nsAutoString path; + ErrorResult error; + aData.GetAsFile()->GetMozFullPathInternal(path, error); + if (error.Failed() || path.IsEmpty()) { + error.SuppressException(); return nullptr; } - } else { - MOZ_ASSERT(aData.IsDirectory()); - aData.GetAsDirectory()->GetFullRealPath(path); + + nsCOMPtr localFile; + nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true, + getter_AddRefs(localFile)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + nsCOMPtr parentFile; + rv = localFile->GetParent(getter_AddRefs(parentFile)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + return parentFile.forget(); } - nsCOMPtr localFile; - nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true, - getter_AddRefs(localFile)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return nullptr; - } + MOZ_ASSERT(aData.IsDirectory()); + + nsCOMPtr localFile = aData.GetAsDirectory()->GetInternalNsIFile(); + MOZ_ASSERT(localFile); return localFile.forget(); } @@ -616,12 +625,9 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult) } // Store the last used directory using the content pref service: - nsCOMPtr file = - DOMFileOrDirectoryToLocalFile(newFilesOrDirectories[0]); + nsCOMPtr lastUsedDir = LastUsedDirectory(newFilesOrDirectories[0]); - if (file) { - nsCOMPtr lastUsedDir; - file->GetParent(getter_AddRefs(lastUsedDir)); + if (lastUsedDir) { HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory( mInput->OwnerDoc(), lastUsedDir); } @@ -994,7 +1000,7 @@ HTMLInputElement::InitFilePicker(FilePickerType aType) filePicker->AppendFilters(nsIFilePicker::filterAll); } - // Set default directry and filename + // Set default directory and filename nsAutoString defaultName; const nsTArray& oldFiles = @@ -1005,15 +1011,11 @@ HTMLInputElement::InitFilePicker(FilePickerType aType) if (!oldFiles.IsEmpty() && aType != FILE_PICKER_DIRECTORY) { - nsString path; + nsAutoString path; - nsCOMPtr localFile = DOMFileOrDirectoryToLocalFile(oldFiles[0]); - if (localFile) { - nsCOMPtr parentFile; - nsresult rv = localFile->GetParent(getter_AddRefs(parentFile)); - if (NS_SUCCEEDED(rv)) { - filePicker->SetDisplayDirectory(parentFile); - } + nsCOMPtr parentFile = LastUsedDirectory(oldFiles[0]); + if (parentFile) { + filePicker->SetDisplayDirectory(parentFile); } // Unfortunately nsIFilePicker doesn't allow multiple files to be diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp index c5a4792bef57..bd2f872167d2 100644 --- a/dom/media/gmp/GMPParent.cpp +++ b/dom/media/gmp/GMPParent.cpp @@ -600,10 +600,6 @@ GMPCapability::Supports(const nsTArray& aCapabilities, if (!WMFDecoderModule::HasH264()) { continue; } - } else if (capabilities.mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER)) { - if (!WMFDecoderModule::HasAAC()) { - continue; - } } } #endif diff --git a/dom/smil/nsSMILAnimationController.cpp b/dom/smil/nsSMILAnimationController.cpp index f447509311bb..8350e3163fb9 100644 --- a/dom/smil/nsSMILAnimationController.cpp +++ b/dom/smil/nsSMILAnimationController.cpp @@ -321,6 +321,12 @@ nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers) bool isStyleFlushNeeded = mResampleNeeded; mResampleNeeded = false; + + if (mDocument->IsStyledByServo()) { + NS_ERROR("stylo: SMIL animations not supported yet"); + return; + } + // Set running sample flag -- do this before flushing styles so that when we // flush styles we don't end up requesting extra samples AutoRestore autoRestoreRunningSample(mRunningSample); diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 222157ab358b..419a5fef48fc 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -12,6 +12,7 @@ #include "Matrix.h" #include "Quaternion.h" #include "UserData.h" +#include // GenericRefCountedBase allows us to hold on to refcounted objects of any type // (contrary to RefCounted which requires knowing the type T) and, in particular, @@ -630,6 +631,10 @@ struct Glyph Point mPosition; }; +static inline bool operator==(const Glyph& aOne, const Glyph& aOther) { + return aOne.mIndex == aOther.mIndex && aOne.mPosition == aOther.mPosition; +} + /** This class functions as a glyph buffer that can be drawn to a DrawTarget. * @todo XXX - This should probably contain the guts of gfxTextRun in the future as * roc suggested. But for now it's a simple container for a glyph vector. @@ -664,7 +669,7 @@ struct GlyphMetrics * at a particular size. It is passed into text drawing calls to describe * the font used for the drawing call. */ -class ScaledFont : public RefCounted +class ScaledFont : public external::AtomicRefCounted { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont) @@ -778,6 +783,7 @@ public: virtual BackendType GetBackendType() const = 0; virtual bool IsRecording() const { return false; } + virtual bool IsCaptureDT() const { return false; } /** * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget. @@ -1272,6 +1278,17 @@ protected: class DrawTargetCapture : public DrawTarget { +public: + virtual bool IsCaptureDT() const { return true; } + + /** + * Returns true if the recording only contains FillGlyph calls with + * a single font and color. Returns the list of Glyphs along with + * the font and color as outparams if so. + */ + virtual bool ContainsOnlyColoredGlyphs(RefPtr& aScaledFont, + Color& aColor, + std::vector& aGlyphs) = 0; }; class DrawEventRecorder : public RefCounted diff --git a/gfx/2d/DrawCommand.h b/gfx/2d/DrawCommand.h index eb415c70a931..83bbad8c1f96 100644 --- a/gfx/2d/DrawCommand.h +++ b/gfx/2d/DrawCommand.h @@ -46,14 +46,14 @@ public: virtual bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) const { return false; } + CommandType GetType() { return mType; } + protected: explicit DrawingCommand(CommandType aType) : mType(aType) { } - CommandType GetType() { return mType; } - private: CommandType mType; }; @@ -418,6 +418,7 @@ private: class FillGlyphsCommand : public DrawingCommand { + friend class DrawTargetCaptureImpl; public: FillGlyphsCommand(ScaledFont* aFont, const GlyphBuffer& aBuffer, @@ -553,6 +554,7 @@ public: class SetTransformCommand : public DrawingCommand { + friend class DrawTargetCaptureImpl; public: explicit SetTransformCommand(const Matrix& aTransform) : DrawingCommand(CommandType::SETTRANSFORM) diff --git a/gfx/2d/DrawTargetCapture.cpp b/gfx/2d/DrawTargetCapture.cpp index f0584c427cc6..c6599275f9a6 100644 --- a/gfx/2d/DrawTargetCapture.cpp +++ b/gfx/2d/DrawTargetCapture.cpp @@ -197,5 +197,63 @@ DrawTargetCaptureImpl::ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransf } } +bool +DrawTargetCaptureImpl::ContainsOnlyColoredGlyphs(RefPtr& aScaledFont, + Color& aColor, + std::vector& aGlyphs) +{ + uint8_t* start = &mDrawCommandStorage.front(); + uint8_t* current = start; + + while (current < start + mDrawCommandStorage.size()) { + DrawingCommand* command = + reinterpret_cast(current + sizeof(uint32_t)); + current += *(uint32_t*)current; + + if (command->GetType() != CommandType::FILLGLYPHS && + command->GetType() != CommandType::SETTRANSFORM) { + return false; + } + + if (command->GetType() == CommandType::SETTRANSFORM) { + SetTransformCommand* transform = static_cast(command); + if (transform->mTransform != Matrix()) { + return false; + } + continue; + } + + FillGlyphsCommand* fillGlyphs = static_cast(command); + if (aScaledFont && fillGlyphs->mFont != aScaledFont) { + return false; + } + aScaledFont = fillGlyphs->mFont; + + Pattern& pat = fillGlyphs->mPattern; + + if (pat.GetType() != PatternType::COLOR) { + return false; + } + + ColorPattern* colorPat = static_cast(&pat); + if (aColor != Color() && colorPat->mColor != aColor) { + return false; + } + aColor = colorPat->mColor; + + if (fillGlyphs->mOptions.mCompositionOp != CompositionOp::OP_OVER || + fillGlyphs->mOptions.mAlpha != 1.0f) { + return false; + } + + //TODO: Deal with AA on the DrawOptions, and the GlyphRenderingOptions + + aGlyphs.insert(aGlyphs.end(), + fillGlyphs->mGlyphs.begin(), + fillGlyphs->mGlyphs.end()); + } + return true; +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/2d/DrawTargetCapture.h b/gfx/2d/DrawTargetCapture.h index a60e07b56b12..af6d71d20fd3 100644 --- a/gfx/2d/DrawTargetCapture.h +++ b/gfx/2d/DrawTargetCapture.h @@ -27,6 +27,8 @@ public: virtual BackendType GetBackendType() const { return mRefDT->GetBackendType(); } virtual DrawTargetType GetType() const { return mRefDT->GetType(); } + virtual bool IsCaptureDT() const { return true; } + virtual already_AddRefed Snapshot(); virtual void DetachAllSnapshots(); @@ -136,6 +138,8 @@ public: void ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform); + bool ContainsOnlyColoredGlyphs(RefPtr& aScaledFont, Color& aColor, std::vector& aGlyphs); + protected: ~DrawTargetCaptureImpl(); diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index e45aa7040c1f..fd838f5a809a 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -25,6 +25,7 @@ #include "mozilla/layers/LayersTypes.h" #include "nsRect.h" #include "nsRegion.h" +#include "mozilla/Array.h" #include @@ -1268,6 +1269,42 @@ struct ParamTraits } }; +template <> +struct ParamTraits +{ + typedef mozilla::gfx::Glyph paramType; + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mIndex); + WriteParam(aMsg, aParam.mPosition); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { + return (ReadParam(aMsg, aIter, &aResult->mIndex) && + ReadParam(aMsg, aIter, &aResult->mPosition) + ); + } +}; + +template +struct ParamTraits> +{ + typedef mozilla::Array paramType; + static void Write(Message* aMsg, const paramType& aParam) { + for (size_t i = 0; i < Length; i++) { + WriteParam(aMsg, aParam[i]); + } + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { + for (size_t i = 0; i < Length; i++) { + if (!ReadParam(aMsg, aIter, &aResult[i])) { + return false; + } + } + return true; + } +}; + } /* namespace IPC */ #endif /* __GFXMESSAGEUTILS_H__ */ diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index a5fdb2df008c..f2061f57d770 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -479,9 +479,9 @@ public: static ImageHost* GetImageHost(Layer* aLayer) { - LayerComposite* composite = aLayer->AsLayerComposite(); - if (composite) { - return static_cast(composite->GetCompositableHost()); + HostLayer* compositor = aLayer->AsHostLayer(); + if (compositor) { + return static_cast(compositor->GetCompositableHost()); } return nullptr; } @@ -609,6 +609,8 @@ CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */) case Layer::TYPE_READBACK: case Layer::TYPE_SHADOW: case Layer::TYPE_PAINTED: + case Layer::TYPE_TEXT: + case Layer::TYPE_BORDER: return MakeUnique(aRoot); } diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index c07eba481ca6..d621c408e8cc 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -576,7 +576,7 @@ Layer::CanUseOpaqueSurface() const Maybe& Layer::GetLocalClipRect() { - if (LayerComposite* shadow = AsLayerComposite()) { + if (HostLayer* shadow = AsHostLayer()) { return shadow->GetShadowClipRect(); } return GetClipRect(); @@ -585,7 +585,7 @@ Layer::GetLocalClipRect() const LayerIntRegion& Layer::GetLocalVisibleRegion() { - if (LayerComposite* shadow = AsLayerComposite()) { + if (HostLayer* shadow = AsHostLayer()) { return shadow->GetShadowVisibleRegion(); } return GetVisibleRegion(); @@ -782,7 +782,7 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect) } if (GetLocalVisibleRegion().IsEmpty() && - !(AsLayerComposite() && AsLayerComposite()->NeedToDrawCheckerboarding())) { + !(AsHostLayer() && AsHostLayer()->NeedToDrawCheckerboarding())) { // When our visible region is empty, our parent may not have created the // intermediate surface that we would require for correct clipping; however, // this does not matter since we are invisible. @@ -887,7 +887,7 @@ Layer::GetTransformTyped() const Matrix4x4 Layer::GetLocalTransform() { - if (LayerComposite* shadow = AsLayerComposite()) + if (HostLayer* shadow = AsHostLayer()) return shadow->GetShadowTransform(); else return GetTransform(); @@ -941,7 +941,7 @@ float Layer::GetLocalOpacity() { float opacity = mOpacity; - if (LayerComposite* shadow = AsLayerComposite()) + if (HostLayer* shadow = AsHostLayer()) opacity = shadow->GetShadowOpacity(); return std::min(std::max(opacity, 0.0f), 1.0f); } @@ -1661,7 +1661,7 @@ LayerManager::BeginTabSwitch() mTabSwitchStart = TimeStamp::Now(); } -static void PrintInfo(std::stringstream& aStream, LayerComposite* aLayerComposite); +static void PrintInfo(std::stringstream& aStream, HostLayer* aLayerComposite); #ifdef MOZ_DUMP_PAINTING template @@ -1702,8 +1702,8 @@ Layer::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml, bool aSorted) { #ifdef MOZ_DUMP_PAINTING - bool dumpCompositorTexture = gfxEnv::DumpCompositorTextures() && AsLayerComposite() && - AsLayerComposite()->GetCompositableHost(); + bool dumpCompositorTexture = gfxEnv::DumpCompositorTextures() && AsHostLayer() && + AsHostLayer()->GetCompositableHost(); bool dumpClientTexture = gfxEnv::DumpPaint() && AsShadowableLayer() && AsShadowableLayer()->GetCompositableClient(); nsCString layerId(Name()); @@ -1723,7 +1723,7 @@ Layer::Dump(std::stringstream& aStream, const char* aPrefix, #ifdef MOZ_DUMP_PAINTING if (dumpCompositorTexture) { - AsLayerComposite()->GetCompositableHost()->Dump(aStream, aPrefix, aDumpHtml); + AsHostLayer()->GetCompositableHost()->Dump(aStream, aPrefix, aDumpHtml); } else if (dumpClientTexture) { if (aDumpHtml) { aStream << nsPrintfCString(R"(