Merge inbound to mozilla-central. a=merge

This commit is contained in:
Csoregi Natalia 2018-10-25 07:45:08 +03:00
Родитель 44c897a308 2d27550851
Коммит 9fbc76ace6
150 изменённых файлов: 12406 добавлений и 5895 удалений

Просмотреть файл

@ -24,6 +24,8 @@ run-if = debug || devedition || nightly_build # Requires startupRecorder.js, whi
[browser_tabclose_grow.js]
[browser_tabclose.js]
skip-if = (os == 'win' && bits == 32) # Bug 1488537
[browser_tabdetach.js]
skip-if = debug # Bug 1501789
[browser_tabopen.js]
skip-if = (verify && (os == 'mac'))
[browser_tabopen_squeeze.js]

Просмотреть файл

@ -0,0 +1,106 @@
"use strict";
/**
* WHOA THERE: We should never be adding new things to EXPECTED_REFLOWS. This
* is a whitelist that should slowly go away as we improve the performance of
* the front-end. Instead of adding more reflows to the whitelist, you should
* be modifying your code to avoid the reflow.
*
* See https://developer.mozilla.org/en-US/Firefox/Performance_best_practices_for_Firefox_fe_engineers
* for tips on how to do that.
*/
const EXPECTED_REFLOWS = [
{
stack: [
"clientX@chrome://browser/content/tabbrowser.xml",
"onxbldragstart@chrome://browser/content/tabbrowser.xml",
"synthesizeMouseAtPoint@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
"synthesizeMouse@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
"synthesizePlainDragAndDrop@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
],
maxCount: 2,
},
{
stack: [
"onxbldragstart@chrome://browser/content/tabbrowser.xml",
"synthesizeMouseAtPoint@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
"synthesizeMouse@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
"synthesizePlainDragAndDrop@chrome://mochikit/content/tests/SimpleTest/EventUtils.js",
],
},
];
/**
* This test ensures that there are no unexpected uninterruptible reflows when
* detaching a tab via drag and drop. The first testcase tests a non-overflowed
* tab strip, and the second tests an overflowed one.
*/
add_task(async function test_detach_not_overflowed() {
await ensureNoPreloadedBrowser();
await createTabs(1);
// Make sure we didn't overflow, as expected
await BrowserTestUtils.waitForCondition(() => {
return !gBrowser.tabContainer.hasAttribute("overflow");
});
let win;
await withPerfObserver(async function() {
win = await detachTab(gBrowser.tabs[1]);
}, {
expectedReflows: EXPECTED_REFLOWS,
// we are opening a whole new window, so there's no point in tracking
// rects being painted
frames: { filter: rects => [] },
});
await BrowserTestUtils.closeWindow(win);
win = null;
});
add_task(async function test_detach_overflowed() {
const TAB_COUNT_FOR_OVERFLOW = computeMaxTabCount();
await createTabs(TAB_COUNT_FOR_OVERFLOW + 1);
// Make sure we overflowed, as expected
await BrowserTestUtils.waitForCondition(() => {
return gBrowser.tabContainer.hasAttribute("overflow");
});
let win;
await withPerfObserver(async function() {
win = await detachTab(gBrowser.tabs[Math.floor(TAB_COUNT_FOR_OVERFLOW / 2)]);
}, {
expectedReflows: EXPECTED_REFLOWS,
// we are opening a whole new window, so there's no point in tracking
// rects being painted
frames: { filter: rects => [] },
});
await BrowserTestUtils.closeWindow(win);
win = null;
await removeAllButFirstTab();
});
async function detachTab(tab) {
let newWindowPromise = BrowserTestUtils.waitForNewWindow();
await EventUtils.synthesizePlainDragAndDrop({
srcElement: tab,
// destElement is null because tab detaching happens due
// to a drag'n'drop on an invalid drop target.
destElement: null,
// don't move horizontally because that could cause a tab move
// animation, and there's code to prevent a tab detaching if
// the dragged tab is released while the animation is running.
stepX: 0,
stepY: 100,
});
return newWindowPromise;
}

Просмотреть файл

@ -130,6 +130,13 @@ function reportUnexpectedReflows(reflows, expectedReflows = []) {
actualStacks: new Map()};
});
let unexpectedReflows = new Map();
if (knownReflows.some(r => r.path.includes("*"))) {
Assert.ok(false,
"Do not include async frames in the stack, as " +
"that feature is not available on all trees.");
}
for (let stack of reflows) {
let path =
stack.split("\n").slice(1) // the first frame which is our test code.
@ -142,9 +149,10 @@ function reportUnexpectedReflows(reflows, expectedReflows = []) {
continue;
}
// synthesizeKey from EventUtils.js causes us to reflow. That's the test
// Functions from EventUtils.js calculate coordinates and
// dimensions, causing us to reflow. That's the test
// harness and we don't care about that, so we'll filter that out.
if (path.startsWith("synthesizeKey@chrome://mochikit/content/tests/SimpleTest/EventUtils.js")) {
if (/^(synthesize|send|createDragEventObject).*?@chrome:\/\/mochikit.*?EventUtils\.js/.test(path)) {
continue;
}

Просмотреть файл

@ -139,3 +139,9 @@ VIAddVersionKey "ProductVersion" "${AppVersion}"
!define PROGRESS_BAR_TOP_DU 112u
!define APPNAME_BMP_EDGE_DU 19u
!define APPNAME_BMP_TOP_DU 12u
# Constants for parts of the telemetry submission URL
!define TELEMETRY_BASE_URL https://incoming.telemetry.mozilla.org/submit
!define TELEMETRY_NAMESPACE firefox-installer
!define TELEMETRY_INSTALL_PING_VERSION 1
!define TELEMETRY_INSTALL_PING_DOCTYPE install

Просмотреть файл

@ -6,6 +6,7 @@
# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in
# ApplicationID http://nsis.sourceforge.net/ApplicationID_plug-in
# CityHash http://dxr.mozilla.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash
# nsJSON http://nsis.sourceforge.net/NsJSON_plug-in
# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in
# UAC http://nsis.sourceforge.net/UAC_plug-in
# ServicesHelper Mozilla specific plugin that is located in /other-licenses/nsis
@ -39,6 +40,18 @@ Var ExtensionRecommender
Var PageName
Var PreventRebootRequired
; Telemetry ping fields
Var SetAsDefault
Var HadOldInstall
Var DefaultInstDir
Var IntroPhaseStart
Var OptionsPhaseStart
Var InstallPhaseStart
Var FinishPhaseStart
Var FinishPhaseEnd
Var InstallResult
Var LaunchedNewApp
; By defining NO_STARTMENU_DIR an installer that doesn't provide an option for
; an application's Start Menu PROGRAMS directory and doesn't define the
; StartMenuDir variable can use the common InstallOnInitCommon macro.
@ -84,6 +97,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
!insertmacro CleanUpdateDirectories
!insertmacro CopyFilesFromDir
!insertmacro CreateRegKey
!insertmacro GetFirstInstallPath
!insertmacro GetLongPath
!insertmacro GetPathFromString
!insertmacro GetParent
@ -188,6 +202,7 @@ Page custom preSummary leaveSummary
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
!define MUI_FINISHPAGE_RUN_TEXT $(LAUNCH_TEXT)
!define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE postFinish
!insertmacro MUI_PAGE_FINISH
; Use the default dialog for IDD_VERIFY for a simple Banner
@ -198,6 +213,9 @@ ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe"
; Cleanup operations to perform at the start of the installation.
Section "-InstallStartCleanup"
System::Call "kernel32::GetTickCount()l .s"
Pop $InstallPhaseStart
SetDetailsPrint both
DetailPrint $(STATUS_CLEANUP)
SetDetailsPrint none
@ -663,7 +681,7 @@ Section "-InstallEndCleanup"
ClearErrors
${MUI_INSTALLOPTIONS_READ} $0 "summary.ini" "Field 4" "State"
${If} "$0" == "1"
; NB: this code is duplicated in stub.nsi. Please keep in sync.
StrCpy $SetAsDefault true
; For data migration in the app, we want to know what the default browser
; value was before we changed it. To do so, we read it here and store it
; in our own registry key.
@ -698,6 +716,7 @@ Section "-InstallEndCleanup"
UAC::ExecCodeSegment $0
${EndIf}
${ElseIfNot} ${Errors}
StrCpy $SetAsDefault false
${LogHeader} "Writing default-browser opt-out"
ClearErrors
WriteRegStr HKCU "Software\Mozilla\Firefox" "DefaultBrowserOptOut" "True"
@ -756,6 +775,14 @@ Section "-InstallEndCleanup"
${EndUnless}
${EndIf}
${EndIf}
StrCpy $InstallResult "success"
; When we're using the GUI, .onGUIEnd sends the ping, but of course that isn't
; invoked when we're running silently.
${If} ${Silent}
Call SendPing
${EndIf}
SectionEnd
################################################################################
@ -904,6 +931,8 @@ Function LaunchApp
GetFunctionAddress $0 LaunchAppFromElevatedProcess
UAC::ExecCodeSegment $0
${EndIf}
StrCpy $LaunchedNewApp true
FunctionEnd
Function LaunchAppFromElevatedProcess
@ -913,6 +942,170 @@ Function LaunchAppFromElevatedProcess
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\""
FunctionEnd
Function SendPing
${GetParameters} $0
${GetOptions} $0 "/LaunchedFromStub" $0
${IfNot} ${Errors}
Return
${EndIf}
; Create a GUID to use as the unique document ID.
System::Call "rpcrt4::UuidCreate(g . r0)i"
; StringFromGUID2 (which is what System::Call uses internally to stringify
; GUIDs) includes braces in its output, and we don't want those.
StrCpy $0 $0 -1 1
; Configure the HTTP request for the ping
nsJSON::Set /tree ping /value "{}"
nsJSON::Set /tree ping "Url" /value \
'"${TELEMETRY_BASE_URL}/${TELEMETRY_NAMESPACE}/${TELEMETRY_INSTALL_PING_DOCTYPE}/${TELEMETRY_INSTALL_PING_VERSION}/$0"'
nsJSON::Set /tree ping "Verb" /value '"POST"'
nsJSON::Set /tree ping "DataType" /value '"JSON"'
nsJSON::Set /tree ping "AccessType" /value '"PreConfig"'
; Fill in the ping payload
nsJSON::Set /tree ping "Data" /value "{}"
nsJSON::Set /tree ping "Data" "installer_type" /value '"full"'
nsJSON::Set /tree ping "Data" "installer_version" /value '"${AppVersion}"'
nsJSON::Set /tree ping "Data" "build_channel" /value '"${Channel}"'
nsJSON::Set /tree ping "Data" "update_channel" /value '"${UpdateChannel}"'
nsJSON::Set /tree ping "Data" "locale" /value '"${AB_CD}"'
ReadINIStr $0 "$INSTDIR\application.ini" "App" "Version"
nsJSON::Set /tree ping "Data" "version" /value '"$0"'
ReadINIStr $0 "$INSTDIR\application.ini" "App" "BuildID"
nsJSON::Set /tree ping "Data" "build_id" /value '"$0"'
${GetParameters} $0
${GetOptions} $0 "/LaunchedFromMSI" $0
${IfNot} ${Errors}
nsJSON::Set /tree ping "Data" "from_msi" /value true
${EndIf}
!ifdef HAVE_64BIT_BUILD
nsJSON::Set /tree ping "Data" "64bit_build" /value true
!else
nsJSON::Set /tree ping "Data" "64bit_build" /value false
!endif
${If} ${RunningX64}
nsJSON::Set /tree ping "Data" "64bit_os" /value true
${Else}
nsJSON::Set /tree ping "Data" "64bit_os" /value false
${EndIf}
; Though these values are sometimes incorrect due to bug 444664 it happens
; so rarely it isn't worth working around it by reading the registry values.
${WinVerGetMajor} $0
${WinVerGetMinor} $1
${WinVerGetBuild} $2
nsJSON::Set /tree ping "Data" "os_version" /value '"$0.$1.$2"'
${If} ${IsServerOS}
nsJSON::Set /tree ping "Data" "server_os" /value true
${Else}
nsJSON::Set /tree ping "Data" "server_os" /value false
${EndIf}
ClearErrors
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
"Write Test"
${If} ${Errors}
nsJSON::Set /tree ping "Data" "admin_user" /value false
${Else}
DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
nsJSON::Set /tree ping "Data" "admin_user" /value true
${EndIf}
${If} $DefaultInstDir == $INSTDIR
nsJSON::Set /tree ping "Data" "default_path" /value true
${Else}
nsJSON::Set /tree ping "Data" "default_path" /value false
${EndIf}
nsJSON::Set /tree ping "Data" "set_default" /value "$SetAsDefault"
nsJSON::Set /tree ping "Data" "new_default" /value false
nsJSON::Set /tree ping "Data" "old_default" /value false
AppAssocReg::QueryCurrentDefault "http" "protocol" "effective"
Pop $0
ReadRegStr $0 HKCR "$0\shell\open\command" ""
${If} $0 != ""
${GetPathFromString} "$0" $0
${GetParent} "$0" $1
${GetLongPath} "$1" $1
${If} $1 == $INSTDIR
nsJSON::Set /tree ping "Data" "new_default" /value true
${Else}
StrCpy $0 "$0" "" -11 # 11 == length of "firefox.exe"
${If} "$0" == "${FileMainEXE}"
nsJSON::Set /tree ping "Data" "old_default" /value true
${EndIf}
${EndIf}
${EndIf}
nsJSON::Set /tree ping "Data" "had_old_install" /value "$HadOldInstall"
${If} ${Silent}
; In silent mode, only the install phase is executed, and the GUI events
; that initialize most of the phase times are never called; only
; $InstallPhaseStart and $FinishPhaseStart have usable values.
${GetSecondsElapsed} $InstallPhaseStart $FinishPhaseStart $0
nsJSON::Set /tree ping "Data" "intro_time" /value 0
nsJSON::Set /tree ping "Data" "options_time" /value 0
nsJSON::Set /tree ping "Data" "install_time" /value "$0"
nsJSON::Set /tree ping "Data" "finish_time" /value 0
${Else}
; In GUI mode, all we can be certain of is that the intro phase has started;
; the user could have canceled at any time and phases after that won't
; have run at all. So we have to be prepared for anything after
; $IntroPhaseStart to be uninitialized. For anything that isn't filled in
; yet we'll use the current tick count. That means that any phases that
; weren't entered at all will get 0 for their times because the start and
; end tick counts will be the same.
System::Call "kernel32::GetTickCount()l .s"
Pop $0
${If} $OptionsPhaseStart == 0
StrCpy $OptionsPhaseStart $0
${EndIf}
${GetSecondsElapsed} $IntroPhaseStart $OptionsPhaseStart $1
nsJSON::Set /tree ping "Data" "intro_time" /value "$1"
${If} $InstallPhaseStart == 0
StrCpy $InstallPhaseStart $0
${EndIf}
${GetSecondsElapsed} $OptionsPhaseStart $InstallPhaseStart $1
nsJSON::Set /tree ping "Data" "options_time" /value "$1"
${If} $FinishPhaseStart == 0
StrCpy $FinishPhaseStart $0
${EndIf}
${GetSecondsElapsed} $InstallPhaseStart $FinishPhaseStart $1
nsJSON::Set /tree ping "Data" "install_time" /value "$1"
${If} $FinishPhaseEnd == 0
StrCpy $FinishPhaseEnd $0
${EndIf}
${GetSecondsElapsed} $FinishPhaseStart $FinishPhaseEnd $1
nsJSON::Set /tree ping "Data" "finish_time" /value "$1"
${EndIf}
nsJSON::Set /tree ping "Data" "new_launched" /value "$LaunchedNewApp"
nsJSON::Set /tree ping "Data" "succeeded" /value false
${If} $InstallResult == "cancel"
nsJSON::Set /tree ping "Data" "user_cancelled" /value true
${ElseIf} $InstallResult == "success"
nsJSON::Set /tree ping "Data" "succeeded" /value true
${EndIf}
; Send the ping request. This call will block until a response is received,
; but we shouldn't have any windows still open, so we won't jank anything.
nsJSON::Set /http ping
FunctionEnd
################################################################################
# Language
@ -939,9 +1132,15 @@ Function preWelcome
Delete "$PLUGINSDIR\modern-wizard.bmp"
CopyFiles /SILENT "$EXEDIR\core\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp"
${EndIf}
System::Call "kernel32::GetTickCount()l .s"
Pop $IntroPhaseStart
FunctionEnd
Function preOptions
System::Call "kernel32::GetTickCount()l .s"
Pop $OptionsPhaseStart
StrCpy $PageName "Options"
${If} ${FileExists} "$EXEDIR\core\distribution\modern-header.bmp"
${AndIf} $hHeaderBitmap == ""
@ -975,6 +1174,8 @@ FunctionEnd
Function preDirectory
StrCpy $PageName "Directory"
${PreDirectoryCommon}
StrCpy $DefaultInstDir $INSTDIR
FunctionEnd
Function leaveDirectory
@ -1288,11 +1489,19 @@ FunctionEnd
; When we add an optional action to the finish page the cancel button is
; enabled. This disables it and leaves the finish button as the only choice.
Function preFinish
System::Call "kernel32::GetTickCount()l .s"
Pop $FinishPhaseStart
StrCpy $PageName ""
${EndInstallLog} "${BrandFullName}"
!insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0"
FunctionEnd
Function postFinish
System::Call "kernel32::GetTickCount()l .s"
Pop $FinishPhaseEnd
FunctionEnd
################################################################################
# Initialization Functions
@ -1301,6 +1510,18 @@ Function .onInit
; This only effects LoadLibrary calls and not implicitly loaded DLLs.
System::Call 'kernel32::SetDllDirectoryW(w "")'
; Initialize the variables used for telemetry
StrCpy $SetAsDefault true
StrCpy $HadOldInstall false
StrCpy $DefaultInstDir $INSTDIR
StrCpy $IntroPhaseStart 0
StrCpy $OptionsPhaseStart 0
StrCpy $InstallPhaseStart 0
StrCpy $FinishPhaseStart 0
StrCpy $FinishPhaseEnd 0
StrCpy $InstallResult "cancel"
StrCpy $LaunchedNewApp false
StrCpy $PageName ""
StrCpy $LANGUAGE 0
${SetBrandNameVars} "$EXEDIR\core\distribution\setup.ini"
@ -1338,6 +1559,20 @@ Function .onInit
SetRegView 64
!endif
SetShellVarContext all
${GetFirstInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0
${If} "$0" == "false"
SetShellVarContext current
${GetFirstInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0
${If} "$0" == "false"
StrCpy $HadOldInstall false
${Else}
StrCpy $HadOldInstall true
${EndIf}
${Else}
StrCpy $HadOldInstall true
${EndIf}
${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
!insertmacro InitInstallOptionsFile "options.ini"
@ -1527,4 +1762,5 @@ FunctionEnd
Function .onGUIEnd
${OnEndCommon}
Call SendPing
FunctionEnd

Просмотреть файл

@ -1218,7 +1218,7 @@ Function LaunchFullInstaller
System::Call "kernel32::GetTickCount()l .s"
Pop $EndPreInstallPhaseTickCount
Exec "$\"$PLUGINSDIR\download.exe$\" /INI=$PLUGINSDIR\${CONFIG_INI}"
Exec "$\"$PLUGINSDIR\download.exe$\" /LaunchedFromStub /INI=$PLUGINSDIR\${CONFIG_INI}"
${NSD_CreateTimer} CheckInstall ${InstallIntervalMS}
FunctionEnd

Просмотреть файл

@ -235,6 +235,8 @@ def build_one_stage(cc, cxx, asm, ld, ar, ranlib, libtool,
"-DCMAKE_SYSTEM_NAME=Darwin",
"-DCMAKE_SYSTEM_VERSION=10.10",
"-DLLVM_ENABLE_THREADS=OFF",
# Xray requires a OSX 10.12 SDK (https://bugs.llvm.org/show_bug.cgi?id=38959)
"-DCOMPILER_RT_BUILD_XRAY=OFF",
"-DLIBCXXABI_LIBCXX_INCLUDES=%s" % libcxx_include_dir,
"-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
"-DCMAKE_FIND_ROOT_PATH=%s" % slashify_path(os.getenv("CROSS_CCTOOLS_PATH")), # noqa

Просмотреть файл

@ -1,16 +1,16 @@
{
"llvm_revision": "335538",
"llvm_revision": "342383",
"stages": "1",
"build_libcxx": true,
"build_type": "Release",
"assertions": false,
"osx_cross_compile": true,
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_601/final",
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_601/final",
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_601/final",
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_601/final",
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_601/final",
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_601/final",
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_700/final",
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
"python_path": "/usr/bin/python2.7",
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
@ -23,9 +23,6 @@
"patches": [
"static-llvm-symbolizer.patch",
"compiler-rt-cross-compile.patch",
"compiler-rt-no-codesign.patch",
"r322401.patch",
"r325356.patch",
"r339636.patch"
"compiler-rt-no-codesign.patch"
]
}

Просмотреть файл

@ -2,9 +2,9 @@ Disable codesign for macosx cross-compile toolchain. Codesign only works on OSX.
Index: cmake/Modules/AddCompilerRT.cmake
===================================================================
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake (revision 312553)
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake (revision 342374)
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake (working copy)
@@ -224,14 +224,6 @@
@@ -290,14 +290,6 @@
set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "")
set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
endif()
@ -18,4 +18,4 @@ Index: cmake/Modules/AddCompilerRT.cmake
- endif()
endif()
install(TARGETS ${libname}
ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${install_dir_${libname}}

Просмотреть файл

@ -888,10 +888,10 @@ Element::ScrollBy(double aXScrollDif, double aYScrollDif)
{
nsIScrollableFrame *sf = GetScrollFrame();
if (sf) {
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
scrollPos += CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScrollDif),
mozilla::ToZeroIfNonfinite(aYScrollDif));
Scroll(scrollPos, ScrollOptions());
ScrollToOptions options;
options.mLeft.Construct(aXScrollDif);
options.mTop.Construct(aYScrollDif);
ScrollBy(options);
}
}
@ -900,14 +900,25 @@ Element::ScrollBy(const ScrollToOptions& aOptions)
{
nsIScrollableFrame *sf = GetScrollFrame();
if (sf) {
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
CSSIntPoint scrollDelta;
if (aOptions.mLeft.WasPassed()) {
scrollPos.x += mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
scrollDelta.x = mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
}
if (aOptions.mTop.WasPassed()) {
scrollPos.y += mozilla::ToZeroIfNonfinite(aOptions.mTop.Value());
scrollDelta.y = mozilla::ToZeroIfNonfinite(aOptions.mTop.Value());
}
Scroll(scrollPos, aOptions);
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
} else if (aOptions.mBehavior == ScrollBehavior::Auto) {
ScrollStyles styles = sf->GetScrollStyles();
if (styles.mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
}
}
sf->ScrollByCSSPixels(scrollDelta, scrollMode, nsGkAtoms::relative);
}
}

Просмотреть файл

@ -3942,13 +3942,13 @@ nsGlobalWindowInner::ScrollBy(double aXScrollDif, double aYScrollDif)
nsIScrollableFrame *sf = GetScrollFrame();
if (sf) {
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
auto scrollDif = CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScrollDif),
mozilla::ToZeroIfNonfinite(aYScrollDif));
// It seems like it would make more sense for ScrollBy to use
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
// Perhaps Web content does too.
ScrollTo(sf->GetScrollPositionCSSPixels() + scrollDif, ScrollOptions());
ScrollToOptions options;
options.mLeft.Construct(aXScrollDif);
options.mTop.Construct(aYScrollDif);
ScrollBy(options);
}
}
@ -3959,15 +3959,25 @@ nsGlobalWindowInner::ScrollBy(const ScrollToOptions& aOptions)
nsIScrollableFrame *sf = GetScrollFrame();
if (sf) {
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
CSSIntPoint scrollDelta;
if (aOptions.mLeft.WasPassed()) {
scrollPos.x += mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
scrollDelta.x = mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
}
if (aOptions.mTop.WasPassed()) {
scrollPos.y += mozilla::ToZeroIfNonfinite(aOptions.mTop.Value());
scrollDelta.y = mozilla::ToZeroIfNonfinite(aOptions.mTop.Value());
}
ScrollTo(scrollPos, aOptions);
nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;
if (aOptions.mBehavior == ScrollBehavior::Smooth) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
} else if (aOptions.mBehavior == ScrollBehavior::Auto) {
ScrollStyles styles = sf->GetScrollStyles();
if (styles.mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) {
scrollMode = nsIScrollableFrame::SMOOTH_MSD;
}
}
sf->ScrollByCSSPixels(scrollDelta, scrollMode, nsGkAtoms::relative);
}
}

Просмотреть файл

@ -3412,31 +3412,6 @@ CreateGlobalOptionsWithXPConnect::PostCreateGlobal(JSContext* aCx,
return true;
}
static bool sRegisteredDOMNames = false;
static void
RegisterDOMNames()
{
if (sRegisteredDOMNames) {
return;
}
// Register new DOM bindings
WebIDLGlobalNameHash::Init();
sRegisteredDOMNames = true;
}
/* static */
bool
CreateGlobalOptions<nsGlobalWindowInner>::PostCreateGlobal(JSContext* aCx,
JS::Handle<JSObject*> aGlobal)
{
RegisterDOMNames();
return CreateGlobalOptionsWithXPConnect::PostCreateGlobal(aCx, aGlobal);
}
#ifdef DEBUG
void
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,

Просмотреть файл

@ -3104,7 +3104,6 @@ struct CreateGlobalOptions<nsGlobalWindowInner>
{
static constexpr ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind =
ProtoAndIfaceCache::WindowLike;
static bool PostCreateGlobal(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
};
// The return value is true if we created and successfully performed our part of

Просмотреть файл

@ -11,6 +11,8 @@ import math
import textwrap
import functools
from perfecthash import PerfectHash
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLInterfaceMember, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor, MemberIsUnforgeable, iteratorNativeType
@ -29,6 +31,11 @@ NEW_ENUMERATE_HOOK_NAME = '_newEnumerate'
ENUM_ENTRY_VARIABLE_NAME = 'strings'
INSTANCE_RESERVED_SLOTS = 1
# This size is arbitrary. It is a power of 2 to make using it as a modulo
# operand cheap, and is usually around 1/3-1/5th of the set size (sometimes
# smaller for very large sets).
GLOBAL_NAMES_PHF_SIZE=256
def memberReservedSlot(member, descriptor):
return ("(DOM_INSTANCE_RESERVED_SLOTS + %d)" %
@ -13691,49 +13698,84 @@ def getGlobalNames(config):
names.extend((n.identifier.name, desc) for n in desc.interface.namedConstructors)
return names
class CGGlobalNamesString(CGGeneric):
class CGGlobalNames(CGGeneric):
def __init__(self, config):
globalNames = getGlobalNames(config)
currentOffset = 0
strings = []
for (name, _) in globalNames:
strings.append('/* %i */ "%s\\0"' % (currentOffset, name))
currentOffset += len(name) + 1 # Add trailing null.
entries = []
for name, desc in getGlobalNames(config):
# Add a string to the list.
offset = currentOffset
strings.append('/* %i */ "%s\\0"' % (offset, name))
currentOffset += len(name) + 1 # Add trailing null.
# Generate the entry declaration
# XXX(nika): mCreate & mEnabled require relocations. If we want to
# reduce those, we could move them into separate tables.
nativeEntry = fill("""
{
/* mNameOffset */ ${nameOffset}, // "${name}"
/* mNameLength */ ${nameLength},
/* mConstructorId */ constructors::id::${realname},
/* mCreate */ ${realname}_Binding::CreateInterfaceObjects,
/* mEnabled */ ${enabled}
}
""",
nameOffset=offset,
nameLength=len(name),
name=name,
realname=desc.name,
enabled=("%s_Binding::ConstructorEnabled" % desc.name
if desc.isExposedConditionally() else "nullptr"))
entries.append((name, nativeEntry))
# Unfortunately, when running tests, we may have no entries.
# PerfectHash will assert if we give it an empty set of entries, so we
# just generate a dummy value.
if len(entries) == 0:
CGGeneric.__init__(self, define=dedent('''
static_assert(false, "No WebIDL global name entries!");
'''))
return
# Build the perfect hash function.
phf = PerfectHash(entries, GLOBAL_NAMES_PHF_SIZE)
# Generate code for the PHF
phfCodegen = phf.codegen('WebIDLGlobalNameHash::sEntries',
'WebIDLNameTableEntry')
entries = phfCodegen.gen_entries(lambda e: e[1])
getter = phfCodegen.gen_jsflatstr_getter(
name='WebIDLGlobalNameHash::GetEntry',
return_type='const WebIDLNameTableEntry*',
# XXX(nika): It would be nice to have a length overload for
# JS_FlatStringEqualsAscii.
return_entry=dedent("""
if (JS_FlatStringEqualsAscii(aKey, sNames + entry.mNameOffset)) {
return &entry;
}
return nullptr;
"""))
define = fill("""
const uint32_t WebIDLGlobalNameHash::sCount = ${count};
const char WebIDLGlobalNameHash::sNames[] =
$*{strings}
$*{entries}
$*{getter}
""",
count=len(globalNames),
strings="\n".join(strings) + ";\n")
count=len(phf.entries),
strings="\n".join(strings) + ";\n",
entries=entries,
getter=getter)
CGGeneric.__init__(self, define=define)
class CGRegisterGlobalNames(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(self, None, 'RegisterWebIDLGlobalNames',
'void', [])
self.config = config
def definition_body(self):
def getCheck(desc):
if not desc.isExposedConditionally():
return "nullptr"
return "%s_Binding::ConstructorEnabled" % desc.name
define = ""
currentOffset = 0
for (name, desc) in getGlobalNames(self.config):
length = len(name)
define += "WebIDLGlobalNameHash::Register(%i, %i, %s_Binding::CreateInterfaceObjects, %s, constructors::id::%s);\n" % (
currentOffset, length, desc.name, getCheck(desc), desc.name)
currentOffset += length + 1 # Add trailing null.
return define
def dependencySortObjects(objects, dependencyGetter, nameGetter):
"""
Sort IDL objects with dependencies on each other such that if A
@ -17119,11 +17161,7 @@ class GlobalGenRoots():
@staticmethod
def RegisterBindings(config):
curr = CGList([CGGlobalNamesString(config), CGRegisterGlobalNames(config)])
# Wrap all of that in our namespaces.
curr = CGNamespace.build(['mozilla', 'dom'],
CGWrapper(curr, post='\n'))
curr = CGNamespace.build(['mozilla', 'dom'], CGGlobalNames(config))
curr = CGWrapper(curr, post='\n')
# Add the includes
@ -17133,6 +17171,7 @@ class GlobalGenRoots():
register=True)]
defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h')
defineIncludes.append('mozilla/dom/PrototypeList.h')
defineIncludes.append('mozilla/PerfectHash.h')
defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(isNavigatorProperty=True,
register=True)])

Просмотреть файл

@ -28,168 +28,6 @@
namespace mozilla {
namespace dom {
struct MOZ_STACK_CLASS WebIDLNameTableKey
{
explicit WebIDLNameTableKey(JSFlatString* aJSString)
: mLength(js::GetFlatStringLength(aJSString))
{
mNogc.emplace();
JSLinearString* jsString = js::FlatStringToLinearString(aJSString);
if (js::LinearStringHasLatin1Chars(jsString)) {
mLatin1String = reinterpret_cast<const char*>(
js::GetLatin1LinearStringChars(*mNogc, jsString));
mTwoBytesString = nullptr;
mHash = mLatin1String ? HashString(mLatin1String, mLength) : 0;
} else {
mLatin1String = nullptr;
mTwoBytesString = js::GetTwoByteLinearStringChars(*mNogc, jsString);
mHash = mTwoBytesString ? HashString(mTwoBytesString, mLength) : 0;
}
}
explicit WebIDLNameTableKey(const char* aString, size_t aLength)
: mLatin1String(aString),
mTwoBytesString(nullptr),
mLength(aLength),
mHash(HashString(aString, aLength))
{
MOZ_ASSERT(aString[aLength] == '\0');
}
Maybe<JS::AutoCheckCannotGC> mNogc;
const char* mLatin1String;
const char16_t* mTwoBytesString;
size_t mLength;
PLDHashNumber mHash;
};
struct WebIDLNameTableEntry : public PLDHashEntryHdr
{
typedef const WebIDLNameTableKey& KeyType;
typedef const WebIDLNameTableKey* KeyTypePointer;
explicit WebIDLNameTableEntry(KeyTypePointer aKey)
: mNameOffset(0),
mNameLength(0),
mConstructorId(constructors::id::_ID_Count),
mCreate(nullptr),
mEnabled(nullptr)
{}
WebIDLNameTableEntry(WebIDLNameTableEntry&& aEntry)
: mNameOffset(aEntry.mNameOffset),
mNameLength(aEntry.mNameLength),
mConstructorId(aEntry.mConstructorId),
mCreate(aEntry.mCreate),
mEnabled(aEntry.mEnabled)
{}
~WebIDLNameTableEntry()
{}
bool KeyEquals(KeyTypePointer aKey) const
{
if (mNameLength != aKey->mLength) {
return false;
}
const char* name = WebIDLGlobalNameHash::sNames + mNameOffset;
if (aKey->mLatin1String) {
return ArrayEqual(aKey->mLatin1String, name, aKey->mLength);
}
return nsCharTraits<char16_t>::compareASCII(aKey->mTwoBytesString, name,
aKey->mLength) == 0;
}
static KeyTypePointer KeyToPointer(KeyType aKey)
{
return &aKey;
}
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return aKey->mHash;
}
enum { ALLOW_MEMMOVE = true };
uint16_t mNameOffset;
uint16_t mNameLength;
constructors::id::ID mConstructorId;
CreateInterfaceObjectsMethod mCreate;
// May be null if enabled unconditionally
WebIDLGlobalNameHash::ConstructorEnabled mEnabled;
};
static nsTHashtable<WebIDLNameTableEntry>* sWebIDLGlobalNames;
class WebIDLGlobalNamesHashReporter final : public nsIMemoryReporter
{
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
~WebIDLGlobalNamesHashReporter() {}
public:
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize) override
{
int64_t amount =
sWebIDLGlobalNames ?
sWebIDLGlobalNames->ShallowSizeOfIncludingThis(MallocSizeOf) : 0;
MOZ_COLLECT_REPORT(
"explicit/dom/webidl-globalnames", KIND_HEAP, UNITS_BYTES, amount,
"Memory used by the hash table for WebIDL's global names.");
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(WebIDLGlobalNamesHashReporter, nsIMemoryReporter)
/* static */
void
WebIDLGlobalNameHash::Init()
{
sWebIDLGlobalNames = new nsTHashtable<WebIDLNameTableEntry>(sCount);
RegisterWebIDLGlobalNames();
RegisterStrongMemoryReporter(new WebIDLGlobalNamesHashReporter());
}
/* static */
void
WebIDLGlobalNameHash::Shutdown()
{
delete sWebIDLGlobalNames;
}
/* static */
void
WebIDLGlobalNameHash::Register(uint16_t aNameOffset, uint16_t aNameLength,
CreateInterfaceObjectsMethod aCreate,
ConstructorEnabled aEnabled,
constructors::id::ID aConstructorId)
{
const char* name = sNames + aNameOffset;
WebIDLNameTableKey key(name, aNameLength);
WebIDLNameTableEntry* entry = sWebIDLGlobalNames->PutEntry(key);
entry->mNameOffset = aNameOffset;
entry->mNameLength = aNameLength;
entry->mCreate = aCreate;
entry->mEnabled = aEnabled;
entry->mConstructorId = aConstructorId;
}
/* static */
void
WebIDLGlobalNameHash::Remove(const char* aName, uint32_t aLength)
{
WebIDLNameTableKey key(aName, aLength);
sWebIDLGlobalNames->RemoveEntry(key);
}
static JSObject*
FindNamedConstructorForXray(JSContext* aCx, JS::Handle<jsid> aId,
const WebIDLNameTableEntry* aEntry)
@ -231,12 +69,7 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
const WebIDLNameTableEntry* entry;
{
WebIDLNameTableKey key(JSID_TO_FLAT_STRING(aId));
// Rooting analysis thinks nsTHashtable<...>::GetEntry may GC because it
// ends up calling through PLDHashTableOps' matchEntry function pointer, but
// we know WebIDLNameTableEntry::KeyEquals can't cause a GC.
JS::AutoSuppressGCAnalysis suppress;
entry = sWebIDLGlobalNames->GetEntry(key);
entry = GetEntry(JSID_TO_FLAT_STRING(aId));
}
if (!entry) {
@ -345,12 +178,7 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
bool
WebIDLGlobalNameHash::MayResolve(jsid aId)
{
WebIDLNameTableKey key(JSID_TO_FLAT_STRING(aId));
// Rooting analysis thinks nsTHashtable<...>::Contains may GC because it ends
// up calling through PLDHashTableOps' matchEntry function pointer, but we
// know WebIDLNameTableEntry::KeyEquals can't cause a GC.
JS::AutoSuppressGCAnalysis suppress;
return sWebIDLGlobalNames->Contains(key);
return GetEntry(JSID_TO_FLAT_STRING(aId)) != nullptr;
}
/* static */
@ -360,15 +188,15 @@ WebIDLGlobalNameHash::GetNames(JSContext* aCx, JS::Handle<JSObject*> aObj,
{
// aObj is always a Window here, so GetProtoAndIfaceCache on it is safe.
ProtoAndIfaceCache* cache = GetProtoAndIfaceCache(aObj);
for (auto iter = sWebIDLGlobalNames->Iter(); !iter.Done(); iter.Next()) {
const WebIDLNameTableEntry* entry = iter.Get();
for (size_t i = 0; i < sCount; ++i) {
const WebIDLNameTableEntry& entry = sEntries[i];
// If aNameType is not AllNames, only include things whose entry slot in the
// ProtoAndIfaceCache is null.
if ((aNameType == AllNames ||
!cache->HasEntryInSlot(entry->mConstructorId)) &&
(!entry->mEnabled || entry->mEnabled(aCx, aObj))) {
JSString* str = JS_AtomizeStringN(aCx, sNames + entry->mNameOffset,
entry->mNameLength);
!cache->HasEntryInSlot(entry.mConstructorId)) &&
(!entry.mEnabled || entry.mEnabled(aCx, aObj))) {
JSString* str = JS_AtomizeStringN(aCx, sNames + entry.mNameOffset,
entry.mNameLength);
if (!str || !aNames.append(NON_INTEGER_ATOM_TO_JSID(str))) {
return false;
}

Просмотреть файл

@ -11,38 +11,36 @@
#include "nsTArray.h"
#include "mozilla/dom/BindingDeclarations.h"
class JSFlatString;
namespace mozilla {
namespace dom {
struct WebIDLNameTableEntry;
namespace constructors {
namespace id {
enum ID : uint16_t;
} // namespace id
} // namespace constructors
class WebIDLGlobalNameHash
struct WebIDLNameTableEntry
{
public:
static void Init();
static void Shutdown();
// Check whether a constructor should be enabled for the given object.
// Note that the object should NOT be an Xray, since Xrays will end up
// defining constructors on the underlying object.
// This is a typedef for the function type itself, not the function
// pointer, so it's more obvious that pointers to a ConstructorEnabled
// can be null.
typedef bool
(*ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
typedef bool (*ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
static void Register(uint16_t aNameOffset, uint16_t aNameLength,
CreateInterfaceObjectsMethod aCreate,
ConstructorEnabled aEnabled,
constructors::id::ID aConstructorId);
uint16_t mNameOffset;
uint16_t mNameLength;
constructors::id::ID mConstructorId;
CreateInterfaceObjectsMethod mCreate;
// May be null if enabled unconditionally
ConstructorEnabled mEnabled;
};
static void Remove(const char* aName, uint32_t aLength);
class WebIDLGlobalNameHash
{
public:
typedef WebIDLNameTableEntry::ConstructorEnabled ConstructorEnabled;
// Returns false if something failed. aFound is set to true if the name is in
// the hash, whether it's enabled or not.
@ -69,12 +67,20 @@ public:
private:
friend struct WebIDLNameTableEntry;
// The total number of names that we will add to the hash.
// Look up an entry by key name. `nullptr` if the entry was not found.
// The impl of GetEntry is generated by Codegen.py in RegisterBindings.cpp
static const WebIDLNameTableEntry* GetEntry(JSFlatString* aKey);
// The total number of names in the hash.
// The value of sCount is generated by Codegen.py in RegisterBindings.cpp.
static const uint32_t sCount;
// The names that will be registered in the hash, concatenated as one big
// string with \0 as a separator between names.
// The name table entries in the hash.
// The value of sEntries is generated by Codegen.py in RegisterBindings.cpp.
static const WebIDLNameTableEntry sEntries[];
// The names registered in the hash, concatenated as one big string with \0
// as a separator between names.
// The value of sNames is generated by Codegen.py in RegisterBindings.cpp.
static const char sNames[];
};

Просмотреть файл

@ -43,7 +43,10 @@ WebGL2Context::IsSampler(const WebGLSampler* const obj)
if (!ValidateIsObject(obj))
return false;
return gl->fIsSampler(obj->mGLName);
if (obj->IsDeleteRequested())
return false;
return true;
}
void

Просмотреть файл

@ -54,7 +54,10 @@ WebGL2Context::IsTransformFeedback(const WebGLTransformFeedback* const obj)
if (!ValidateIsObject(obj))
return false;
return gl->fIsTransformFeedback(obj->mGLName);
if (obj->IsDeleteRequested())
return false;
return obj->mHasBeenBound;
}
void
@ -90,6 +93,7 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
if (mBoundTransformFeedback) {
mBoundTransformFeedback->AddBufferBindCounts(+1);
mBoundTransformFeedback->mHasBeenBound = true;
}
}

Просмотреть файл

@ -2501,7 +2501,10 @@ WebGLContext::ValidateIsObject(const WebGLDeletableObject* const object) const
if (!object->IsCompatibleWithContext(this))
return false;
return !object->IsDeleted();
if (object->IsDeleted())
return false;
return true;
}
bool

Просмотреть файл

@ -147,9 +147,7 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
} else {
GLuint framebuffername = wfb->mGLName;
gl->fBindFramebuffer(target, framebuffername);
#ifdef ANDROID
wfb->mIsFB = true;
#endif
wfb->mHasBeenBound = true;
}
switch (target) {
@ -1065,7 +1063,10 @@ WebGLContext::IsBuffer(const WebGLBuffer* const obj)
if (!ValidateIsObject(obj))
return false;
return gl->fIsBuffer(obj->mGLName);
if (obj->IsDeleteRequested())
return false;
return obj->Content() != WebGLBuffer::Kind::Undefined;
}
bool
@ -1075,15 +1076,10 @@ WebGLContext::IsFramebuffer(const WebGLFramebuffer* const obj)
if (!ValidateIsObject(obj))
return false;
#ifdef ANDROID
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::AndroidEmulator)
{
return obj->mIsFB;
}
#endif
if (obj->IsDeleteRequested())
return false;
return gl->fIsFramebuffer(obj->mGLName);
return obj->mHasBeenBound;
}
bool
@ -1100,7 +1096,10 @@ WebGLContext::IsQuery(const WebGLQuery* const obj)
if (!ValidateIsObject(obj))
return false;
return obj->IsQuery();
if (obj->IsDeleteRequested())
return false;
return bool(obj->Target());
}
bool
@ -1110,6 +1109,9 @@ WebGLContext::IsRenderbuffer(const WebGLRenderbuffer* const obj)
if (!ValidateIsObject(obj))
return false;
if (obj->IsDeleteRequested())
return false;
return obj->mHasBeenBound;
}
@ -1127,7 +1129,10 @@ WebGLContext::IsTexture(const WebGLTexture* const obj)
if (!ValidateIsObject(obj))
return false;
return obj->IsTexture();
if (obj->IsDeleteRequested())
return false;
return bool(obj->Target());
}
bool
@ -1137,7 +1142,10 @@ WebGLContext::IsVertexArray(const WebGLVertexArray* const obj)
if (!ValidateIsObject(obj))
return false;
return obj->IsVertexArray();
if (obj->IsDeleteRequested())
return false;
return obj->mHasBeenBound;
}
// -

Просмотреть файл

@ -702,8 +702,8 @@ WebGLContext::AssertCachedBindings() const
GetAndFlushUnderlyingGLErrors();
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING,
mBoundVertexArray->mGLName);
}
GLint stencilBits = 0;

Просмотреть файл

@ -621,10 +621,6 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
return false;
}
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mBoundVertexArray = mDefaultVertexArray;
// OpenGL core profiles remove the default VAO object from version
// 4.0.0. We create a default VAO for all core profiles,
// regardless of version.
@ -633,11 +629,9 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
// (https://www.opengl.org/registry/doc/glspec40.core.20100311.pdf)
// in Section E.2.2 "Removed Features", pg 397: "[...] The default
// vertex array object (the name zero) is also deprecated. [...]"
if (gl->IsCoreProfile()) {
mDefaultVertexArray->GenVertexArray();
mDefaultVertexArray->BindVertexArray();
}
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->BindVertexArray();
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mPixelStore_FlipY = false;
mPixelStore_PremultiplyAlpha = false;

Просмотреть файл

@ -35,6 +35,7 @@ WebGLContext::BindVertexArray(WebGLVertexArray* array)
MOZ_ASSERT(mBoundVertexArray == array);
if (mBoundVertexArray) {
mBoundVertexArray->AddBufferBindCounts(+1);
mBoundVertexArray->mHasBeenBound = true;
}
}
@ -46,9 +47,6 @@ WebGLContext::CreateVertexArray()
return nullptr;
RefPtr<WebGLVertexArray> globj = CreateVertexArrayImpl();
globj->GenVertexArray();
return globj.forget();
}

Просмотреть файл

@ -131,7 +131,8 @@ WebGLFBAttachPoint::IsComplete(WebGLContext* webgl, nsCString* const out_info) c
// We need to check immutable textures though, because checking completeness is
// also when we zero invalidated/no-data tex images.
const bool complete = [&]() {
const auto texCompleteness = tex->CalcCompletenessInfo();
const bool ensureInit = false;
const auto texCompleteness = tex->CalcCompletenessInfo(ensureInit);
if (!texCompleteness) // OOM
return false;
if (!texCompleteness->levels)
@ -508,10 +509,6 @@ WebGLFramebuffer::Delete()
mContext->gl->fDeleteFramebuffers(1, &mGLName);
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
#ifdef ANDROID
mIsFB = false;
#endif
}
////
@ -1232,7 +1229,7 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum attachEnum,
if (!mContext->ValidateObject("texture", *tex))
return;
if (!tex->HasEverBeenBound()) {
if (!tex->Target()) {
mContext->ErrorInvalidOperation("`texture` has never been bound.");
return;
}
@ -1317,7 +1314,7 @@ WebGLFramebuffer::FramebufferTextureLayer(GLenum attachEnum,
if (!mContext->ValidateObject("texture", *tex))
return;
if (!tex->HasEverBeenBound()) {
if (!tex->Target()) {
mContext->ErrorInvalidOperation("`texture` has never been bound.");
return;
}

Просмотреть файл

@ -140,28 +140,18 @@ class WebGLFramebuffer final
, public SupportsWeakPtr<WebGLFramebuffer>
, public CacheInvalidator
{
friend class WebGLContext;
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
const GLuint mGLName;
bool mHasBeenBound = false;
private:
mutable uint64_t mNumFBStatusInvals = 0;
protected:
#ifdef ANDROID
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsRenderbuffer, maybe others.
// This shows up on Android 2.3 emulator.
//
// So we track the `is a Framebuffer` state ourselves.
bool mIsFB = false;
#endif
////
protected:
WebGLFBAttachPoint mDepthAttachment;
WebGLFBAttachPoint mStencilAttachment;
WebGLFBAttachPoint mDepthStencilAttachment;

Просмотреть файл

@ -52,7 +52,6 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
, mPrimaryRB( DoCreateRenderbuffer(webgl->gl) )
, mEmulatePackedDepthStencil( EmulatePackedDepthStencil(webgl->gl) )
, mSecondaryRB(0)
, mHasBeenBound(false)
{
mContext->mRenderbuffers.insertBack(this);

Просмотреть файл

@ -26,16 +26,15 @@ class WebGLRenderbuffer final
, public WebGLRectangleObject
, public CacheInvalidator
{
friend class WebGLContext;
friend class WebGLFramebuffer;
friend class WebGLFBAttachPoint;
public:
const GLuint mPrimaryRB;
bool mHasBeenBound = false;
protected:
const bool mEmulatePackedDepthStencil;
GLuint mSecondaryRB;
bool mHasBeenBound;
webgl::ImageInfo mImageInfo;
public:

Просмотреть файл

@ -11,8 +11,6 @@
namespace mozilla {
WebGLSampler::WebGLSampler(WebGLContext* const webgl)
: WebGLRefCountedObject(webgl)
, mGLName([&]() {

Просмотреть файл

@ -20,9 +20,6 @@ class WebGLSampler final
, public LinkedListElement<WebGLSampler>
, public CacheInvalidator
{
friend class WebGLContext2;
friend class WebGLTexture;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)

Просмотреть файл

@ -155,6 +155,8 @@ public:
return get() >= other.get();
}
explicit operator bool() const { return bool(get()); }
static bool IsValueLegal(GLenum value) {
if (value > UINT16_MAX) {
return false;

Просмотреть файл

@ -155,7 +155,7 @@ ZeroTextureData(const WebGLContext* webgl, GLuint tex,
uint32_t depth);
bool
WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel, const bool ensureInit,
bool* const out_initFailed) const
{
*out_initFailed = false;
@ -187,7 +187,7 @@ WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
return false;
}
if (MOZ_UNLIKELY( !cur.mHasData )) {
if (MOZ_UNLIKELY( ensureInit && !cur.mHasData )) {
auto imageTarget = mTarget.get();
if (imageTarget == LOCAL_GL_TEXTURE_CUBE_MAP) {
imageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
@ -213,7 +213,7 @@ WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
}
Maybe<const WebGLTexture::CompletenessInfo>
WebGLTexture::CalcCompletenessInfo() const
WebGLTexture::CalcCompletenessInfo(const bool ensureInit, const bool skipMips) const
{
Maybe<CompletenessInfo> ret = Some(CompletenessInfo());
@ -243,7 +243,7 @@ WebGLTexture::CalcCompletenessInfo() const
// "* The texture is a cube map texture, and is not cube complete."
bool initFailed = false;
if (!IsMipAndCubeComplete(mBaseMipmapLevel, &initFailed)) {
if (!IsMipAndCubeComplete(mBaseMipmapLevel, ensureInit, &initFailed)) {
if (initFailed)
return {};
@ -279,7 +279,10 @@ WebGLTexture::CalcCompletenessInfo() const
return ret;
}
if (!IsMipAndCubeComplete(maxLevel, &initFailed)) {
if (skipMips)
return ret;
if (!IsMipAndCubeComplete(maxLevel, ensureInit, &initFailed)) {
if (initFailed)
return {};
@ -299,7 +302,8 @@ WebGLTexture::CalcSampleableInfo(const WebGLSampler* const sampler) const
{
Maybe<webgl::SampleableInfo> ret = Some(webgl::SampleableInfo());
const auto completeness = CalcCompletenessInfo();
const bool ensureInit = true;
const auto completeness = CalcCompletenessInfo(ensureInit);
if (!completeness)
return {};
@ -577,8 +581,9 @@ ZeroTextureData(const WebGLContext* webgl, GLuint tex,
// We have no sympathy for any of these cases.
// "Doctor, it hurts when I do this!" "Well don't do that!"
webgl->GenerateWarning("This operation requires zeroing texture data. This is"
" slow.");
const auto targetStr = EnumString(target.get());
webgl->GeneratePerfWarning("Tex image %s level %u is incurring lazy initialization.",
targetStr.c_str(), level);
gl::GLContext* gl = webgl->GL();
@ -698,7 +703,7 @@ WebGLTexture::BindTexture(TexTarget texTarget)
return false;
}
const bool isFirstBinding = !HasEverBeenBound();
const bool isFirstBinding = !mTarget;
if (!isFirstBinding && mTarget != texTarget) {
mContext->ErrorInvalidOperation("bindTexture: This texture has already been bound"
" to a different target.");
@ -737,7 +742,10 @@ WebGLTexture::GenerateMipmap()
// derived from the level base array, regardless of their previous contents. All
// other mipmap arrays, including the level base array, are left unchanged by this
// computation."
const auto completeness = CalcCompletenessInfo();
// But only check and init the base level.
const bool ensureInit = true;
const bool skipMips = true;
const auto completeness = CalcCompletenessInfo(ensureInit, skipMips);
if (!completeness || !completeness->levels) {
mContext->ErrorInvalidOperation("The texture's base level must be complete.");
return;
@ -856,12 +864,6 @@ WebGLTexture::GetTexParameter(TexTarget texTarget, GLenum pname)
}
}
bool
WebGLTexture::IsTexture() const
{
return HasEverBeenBound() && !IsDeleted();
}
// Here we have to support all pnames with both int and float params.
// See this discussion:
// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html

Просмотреть файл

@ -145,7 +145,8 @@ protected:
mutable CacheWeakMap<const WebGLSampler*, webgl::SampleableInfo> mSamplingCache;
public:
Maybe<const CompletenessInfo> CalcCompletenessInfo() const;
Maybe<const CompletenessInfo> CalcCompletenessInfo(bool ensureInit,
bool skipMips = false) const;
Maybe<const webgl::SampleableInfo> CalcSampleableInfo(const WebGLSampler*) const;
const webgl::SampleableInfo* GetSampleableInfo(const WebGLSampler*) const;
@ -172,7 +173,6 @@ public:
void Delete();
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
TexTarget Target() const { return mTarget; }
WebGLContext* GetParentObject() const {
@ -192,7 +192,6 @@ public:
bool BindTexture(TexTarget texTarget);
void GenerateMipmap();
JS::Value GetTexParameter(TexTarget texTarget, GLenum pname);
bool IsTexture() const;
void TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& param);
////////////////////////////////////
@ -310,7 +309,8 @@ public:
bool EnsureImageDataInitialized(TexImageTarget target,
uint32_t level);
void PopulateMipChain(uint32_t maxLevel);
bool IsMipAndCubeComplete(uint32_t maxLevel, bool* out_initFailed) const;
bool IsMipAndCubeComplete(uint32_t maxLevel, bool ensureInit,
bool* out_initFailed) const;
bool IsCubeMap() const { return (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP); }
};

Просмотреть файл

@ -30,6 +30,7 @@ class WebGLTransformFeedback final
public:
const GLuint mGLName;
bool mHasBeenBound = false;
private:
// GLES 3.0.4 p267, Table 6.24 "Transform Feedback State"
// It's not yet in the ES3 spec, but the generic TF buffer bind point has been moved

Просмотреть файл

@ -20,9 +20,9 @@ WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
return dom::WebGLVertexArrayObject_Binding::Wrap(cx, this, givenProto);
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
WebGLVertexArray::WebGLVertexArray(WebGLContext* const webgl, const GLuint name)
: WebGLRefCountedObject(webgl)
, mGLName(0)
, mGLName(name)
{
mAttribs.SetLength(mContext->mGLMaxVertexAttribs);
mContext->mVertexArrays.insertBack(this);
@ -65,12 +65,6 @@ WebGLVertexArray::Delete()
mAttribs.Clear();
}
bool
WebGLVertexArray::IsVertexArray() const
{
return IsVertexArrayImpl();
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
mAttribs,
mElementArrayBuffer)

Просмотреть файл

@ -31,15 +31,7 @@ class WebGLVertexArray
public:
static WebGLVertexArray* Create(WebGLContext* webgl);
void BindVertexArray() {
// Bind to dummy value to signal that this vertex array has ever been
// bound.
BindVertexArrayImpl();
};
// Implement parent classes:
void Delete();
bool IsVertexArray() const;
WebGLContext* GetParentObject() const {
return mContext;
@ -50,20 +42,19 @@ public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
GLuint GLName() const { return mGLName; }
void AddBufferBindCounts(int8_t addVal) const;
protected:
explicit WebGLVertexArray(WebGLContext* webgl);
WebGLVertexArray(WebGLContext* webgl, GLuint name);
virtual ~WebGLVertexArray();
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
virtual void BindVertexArray() = 0;
virtual void DeleteImpl() = 0;
virtual bool IsVertexArrayImpl() const = 0;
GLuint mGLName;
public:
const GLuint mGLName;
bool mHasBeenBound = false;
protected:
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;

Просмотреть файл

@ -11,12 +11,11 @@
namespace mozilla {
WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
, mIsVAO(false)
: WebGLVertexArray(webgl, 0)
{ }
void
WebGLVertexArrayFake::BindVertexArrayImpl()
WebGLVertexArrayFake::BindVertexArray()
{
// Go through and re-bind all buffers and setup all
// vertex attribute pointers
@ -52,19 +51,6 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
mIsVAO = true;
}
void
WebGLVertexArrayFake::DeleteImpl()
{
mIsVAO = false;
}
bool
WebGLVertexArrayFake::IsVertexArrayImpl() const
{
return mIsVAO;
}
} // namespace mozilla

Просмотреть файл

@ -16,10 +16,8 @@ class WebGLVertexArrayFake final
friend class WebGLVertexArray;
protected:
virtual void BindVertexArrayImpl() override;
virtual void DeleteImpl() override;
virtual void GenVertexArray() override {};
virtual bool IsVertexArrayImpl() const override;
virtual void BindVertexArray() override;
virtual void DeleteImpl() override {}
private:
explicit WebGLVertexArrayFake(WebGLContext* webgl);
@ -27,8 +25,6 @@ private:
~WebGLVertexArrayFake() {
DeleteOnce();
}
bool mIsVAO;
};
} // namespace mozilla

Просмотреть файл

@ -11,8 +11,12 @@
namespace mozilla {
WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
, mIsVAO(false)
: WebGLVertexArray(webgl,
[&]() {
GLuint ret = 0;
webgl->gl->fGenVertexArrays(1, &ret);
return ret;
}())
{ }
WebGLVertexArrayGL::~WebGLVertexArrayGL()
@ -26,35 +30,13 @@ WebGLVertexArrayGL::DeleteImpl()
mElementArrayBuffer = nullptr;
mContext->gl->fDeleteVertexArrays(1, &mGLName);
mIsVAO = false;
}
void
WebGLVertexArrayGL::BindVertexArrayImpl()
WebGLVertexArrayGL::BindVertexArray()
{
mContext->mBoundVertexArray = this;
mContext->gl->fBindVertexArray(mGLName);
mIsVAO = true;
}
void
WebGLVertexArrayGL::GenVertexArray()
{
mContext->gl->fGenVertexArrays(1, &mGLName);
}
bool
WebGLVertexArrayGL::IsVertexArrayImpl() const
{
gl::GLContext* gl = mContext->gl;
if (gl->WorkAroundDriverBugs())
{
return mIsVAO;
}
return mContext->gl->fIsVertexArray(mGLName) != 0;
}
} // namespace mozilla

Просмотреть файл

@ -17,19 +17,11 @@ class WebGLVertexArrayGL
public:
virtual void DeleteImpl() override;
virtual void BindVertexArrayImpl() override;
virtual void GenVertexArray() override;
virtual bool IsVertexArrayImpl() const override;
virtual void BindVertexArray() override;
protected:
explicit WebGLVertexArrayGL(WebGLContext* webgl);
~WebGLVertexArrayGL();
// Bug 1140459: Some drivers (including our test slaves!) don't
// give reasonable answers for IsVertexArray, maybe others.
//
// So we track the `is a VAO` state ourselves.
bool mIsVAO;
};
} // namespace mozilla

Просмотреть файл

@ -645,11 +645,11 @@ function runBoundDeleteTests() {
wtu.glErrorShouldBe(gl, expectedError,
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
if (!gl.isBuffer(positionBuffer)) {
testFailed("References from unbound VAOs keep Position buffer alive.");
if (gl.isBuffer(positionBuffer)) {
testFailed("References from unbound VAOs don't keep Position buffer alive.");
}
if (!gl.isBuffer(colorBuffer)) {
testFailed("References from unbound VAOs keep Color buffer alive");
if (gl.isBuffer(colorBuffer)) {
testFailed("References from unbound VAOs don't keep Color buffer alive");
}
}
}

Просмотреть файл

@ -590,11 +590,11 @@ function runBoundDeleteTests() {
wtu.glErrorShouldBe(gl, expectedError,
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
if (!gl.isBuffer(positionBuffer)) {
testFailed("References from unbound VAOs keep Position buffer alive.");
if (gl.isBuffer(positionBuffer)) {
testFailed("References from unbound VAOs don't keep Position buffer alive.");
}
if (!gl.isBuffer(colorBuffer)) {
testFailed("References from unbound VAOs keep Color buffer alive");
if (gl.isBuffer(colorBuffer)) {
testFailed("References from unbound VAOs don't keep Color buffer alive");
}
}
}

Просмотреть файл

@ -5324,6 +5324,7 @@ subsuite = webgl2-core
subsuite = webgl2-core
[generated/test_2_conformance2__rendering__framebuffer-texture-changing-base-level.html]
subsuite = webgl2-core
fail-if = (os == 'win')
[generated/test_2_conformance2__rendering__framebuffer-texture-level1.html]
subsuite = webgl2-core
fail-if = (os == 'mac')

Просмотреть файл

@ -1101,3 +1101,6 @@ skip-if = (os == 'win')
skip-if = (os == 'win')
[generated/test_2_conformance__textures__misc__tex-video-using-tex-unit-non-zero.html]
skip-if = (os == 'win')
[generated/test_2_conformance2__rendering__framebuffer-texture-changing-base-level.html]
# https://bugzilla.mozilla.org/show_bug.cgi?id=1501868 (ANGLE bug)
fail-if = (os == 'win')

Просмотреть файл

@ -45,6 +45,9 @@
#include "nsFrameSelection.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Telemetry.h"
#include "mozilla/ShortcutKeys.h"
#include "nsXBLPrototypeHandler.h"
#include "mozilla/dom/KeyboardEvent.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -957,13 +960,44 @@ TextInputListener::HandleEvent(Event* aEvent)
return NS_OK;
}
WidgetKeyboardEvent* keyEvent =
aEvent->WidgetEventPtr()->AsKeyboardEvent();
RefPtr<KeyboardEvent> keyEvent = aEvent->AsKeyboardEvent();
if (!keyEvent) {
return NS_ERROR_UNEXPECTED;
}
if (keyEvent->mMessage != eKeyPress) {
WidgetKeyboardEvent* widgetKeyEvent =
aEvent->WidgetEventPtr()->AsKeyboardEvent();
if (!keyEvent) {
return NS_ERROR_UNEXPECTED;
}
nsXBLPrototypeHandler* keyHandlers =
ShortcutKeys::GetHandlers(mTxtCtrlElement->IsTextArea() ?
HandlerType::eTextArea : HandlerType::eInput);
RefPtr<nsAtom> eventTypeAtom =
ShortcutKeys::ConvertEventToDOMEventType(widgetKeyEvent);
for (nsXBLPrototypeHandler* handler = keyHandlers;
handler;
handler = handler->GetNextHandler()) {
if (!handler->EventTypeEquals(eventTypeAtom)) {
continue;
}
if (!handler->KeyEventMatched(keyEvent, 0, IgnoreModifierState())) {
continue;
}
// XXX Do we execute only one handler even if the handler neither stops
// propagation nor prevents default of the event?
nsCOMPtr<EventTarget> target = do_QueryInterface(mTxtCtrlElement);
nsresult rv = handler->ExecuteHandler(target, aEvent);
if (NS_SUCCEEDED(rv)) {
return rv;
}
}
if (widgetKeyEvent->mMessage != eKeyPress) {
return NS_OK;
}
@ -972,7 +1006,7 @@ TextInputListener::HandleEvent(Event* aEvent)
nsIWidget::NativeKeyBindingsForMultiLineEditor :
nsIWidget::NativeKeyBindingsForSingleLineEditor;
nsIWidget* widget = keyEvent->mWidget;
nsIWidget* widget = widgetKeyEvent->mWidget;
// If the event is created by chrome script, the widget is nullptr.
if (!widget) {
widget = mFrame->GetNearestWidget();
@ -983,10 +1017,10 @@ TextInputListener::HandleEvent(Event* aEvent)
// If the event is created by chrome script, it is nullptr but we need to
// execute native key bindings. Therefore, we need to set widget to
// WidgetEvent::mWidget temporarily.
AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(keyEvent->mWidget);
keyEvent->mWidget = widget;
if (keyEvent->ExecuteEditCommands(nativeKeyBindingsType,
DoCommandCallback, mFrame)) {
AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(widgetKeyEvent->mWidget);
widgetKeyEvent->mWidget = widget;
if (widgetKeyEvent->ExecuteEditCommands(nativeKeyBindingsType,
DoCommandCallback, mFrame)) {
aEvent->PreventDefault();
}
return NS_OK;

Просмотреть файл

@ -244,38 +244,36 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
}
bool
TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
TabChildBase::UpdateFrameHandler(const RepaintRequest& aRequest)
{
MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
MOZ_ASSERT(aRequest.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
if (aFrameMetrics.IsRootContent()) {
if (aRequest.IsRootContent()) {
if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
// Guard against stale updates (updates meant for a pres shell which
// has since been torn down and destroyed).
if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
ProcessUpdateFrame(aFrameMetrics);
if (aRequest.GetPresShellId() == shell->GetPresShellId()) {
ProcessUpdateFrame(aRequest);
return true;
}
}
} else {
// aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
// aRequest.mIsRoot is false, so we are trying to update a subframe.
// This requires special handling.
FrameMetrics newSubFrameMetrics(aFrameMetrics);
APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
APZCCallbackHelper::UpdateSubFrame(aRequest);
return true;
}
return true;
}
void
TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
TabChildBase::ProcessUpdateFrame(const RepaintRequest& aRequest)
{
if (!mTabChildMessageManager) {
return;
}
if (!mTabChildMessageManager) {
return;
}
FrameMetrics newMetrics = aFrameMetrics;
APZCCallbackHelper::UpdateRootFrame(newMetrics);
APZCCallbackHelper::UpdateRootFrame(aRequest);
}
NS_IMETHODIMP
@ -1303,9 +1301,9 @@ TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
}
bool
TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
TabChild::UpdateFrame(const RepaintRequest& aRequest)
{
return TabChildBase::UpdateFrameHandler(aFrameMetrics);
return TabChildBase::UpdateFrameHandler(aRequest);
}
mozilla::ipc::IPCResult

Просмотреть файл

@ -185,9 +185,9 @@ protected:
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData);
void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
void ProcessUpdateFrame(const mozilla::layers::RepaintRequest& aRequest);
bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
bool UpdateFrameHandler(const mozilla::layers::RepaintRequest& aRequest);
protected:
RefPtr<TabChildMessageManager> mTabChildMessageManager;
@ -635,7 +635,7 @@ public:
void SetAllowedTouchBehavior(uint64_t aInputBlockId,
const nsTArray<TouchBehaviorFlags>& aFlags) const;
bool UpdateFrame(const FrameMetrics& aFrameMetrics);
bool UpdateFrame(const layers::RepaintRequest& aRequest);
bool NotifyAPZStateChange(const ViewID& aViewId,
const layers::GeckoContentController::APZStateChange& aChange,
const int& aArg);

Просмотреть файл

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>
<body>
<p style="white-space: nowrap">
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
A long paragraph to make a horizontal scrollbar.
</p>
<p id="paragraph">Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
<p>Lots of paragraphs to make a vertical scrollbar.</p>
</body>
</html>

Просмотреть файл

@ -0,0 +1,12 @@
[DEFAULT]
# nsIWidget::SynthesizeNativeKeyEvent() required (Bug 1410525 for headless)
skip-if = os == 'linux' || os == 'android' || headless
[test_browser.xul]
support-files =
browsertest.html
[test_editor.xul]
[test_windowed.xul]
support-files =
test_input.html
test_textarea.html

Просмотреть файл

@ -0,0 +1,6 @@
[DEFAULT]
# nsIWidget::SynthesizeNativeKeyEvent() required (Bug 1410525 for headless)
skip-if = os == 'linux' || os == 'android' || headless
[test_input.html]
[test_textarea.html]

Просмотреть файл

@ -0,0 +1,255 @@
<?xml version="1.0"?>
<window title="Browser element keyhandling tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"/>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
const IS_MAC = navigator.platform.indexOf("Mac") === 0;
const VK = {};
const CHARS = {};
// Copied values from NativeKeyCodes.js and EventUtils.js
if (IS_MAC) {
VK.LEFT = MAC_VK_LeftArrow;
CHARS.LEFT = "\uF702";
VK.RIGHT = MAC_VK_RightArrow;
CHARS.RIGHT = "\uF703";
VK.UP = MAC_VK_UpArrow;
CHARS.UP = "\uF700";
VK.DOWN = MAC_VK_DownArrow;
CHARS.DOWN = "\uF701";
VK.SPACE = MAC_VK_Space;
VK.PGDOWN = MAC_VK_PageDown;
CHARS.PGDOWN = "\uF72D";
VK.PGUP = MAC_VK_PageUp;
CHARS.PGUP = "\uF72C";
VK.C = MAC_VK_ANSI_C;
VK.HOME = MAC_VK_Home;
CHARS.HOME = "\uF729";
VK.END = MAC_VK_End;
CHARS.END = "\uF72B";
} else {
VK.LEFT = WIN_VK_LEFT;
CHARS.LEFT = "";
VK.RIGHT = WIN_VK_RIGHT;
CHARS.RIGHT = "";
VK.UP = WIN_VK_UP;
CHARS.UP = "";
VK.DOWN = WIN_VK_DOWN;
CHARS.DOWN = "";
VK.SPACE = WIN_VK_SPACE;
VK.PGDOWN = WIN_VK_NEXT;
CHARS.PGDOWN = "";
VK.PGUP = WIN_VK_PRIOR;
CHARS.PGUP = "";
VK.C = WIN_VK_C;
VK.HOME = WIN_VK_HOME;
CHARS.HOME = "";
VK.END = WIN_VK_END;
CHARS.END = "";
}
function waitForEvent(target, event) {
info(`Waiting for ${event} event.`);
return new Promise(resolve => {
browser.addEventListener(event, resolve, { once: true });
});
}
function synthesizeKey(keyCode, modifiers, chars) {
return new Promise((resolve, reject) => {
if (!synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, keyCode, modifiers, chars, chars, resolve)) {
reject();
}
});
}
function getWindowProperties(browser, properties) {
let results = {};
for (let prop of properties) {
results[prop] = browser.contentWindow[prop];
}
return results;
}
function getScrollPosition(browser) {
return getWindowProperties(browser, ["scrollX", "scrollY"]);
}
async function test() {
// Smooth scrolling makes scroll events take time and it's difficult to know
// when they've ended, so turn it off for this test.
await SpecialPowers.pushPrefEnv({"set": [["general.smoothScroll", false]] });
let browser = document.getElementById("browser");
browser.focus();
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
info("down");
await synthesizeKey(VK.DOWN, {}, CHARS.DOWN);
await waitForEvent(browser.contentWindow, "scroll");
let { scrollX: lineScrollX, scrollY: lineScrollY } = await getScrollPosition(browser);
is(lineScrollX, 0, "Should not be scrolled");
ok(lineScrollY > 0, "Should be scrolled");
info("up");
await synthesizeKey(VK.UP, {}, CHARS.UP);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await waitForEvent(browser.contentWindow, "scroll");
let { scrollX: rightScrollX, scrollY: rightScrollY } = await getScrollPosition(browser);
ok(rightScrollX > 0, "Should be scrolled");
is(rightScrollY, 0, "Should not be scrolled");
info("left");
await synthesizeKey(VK.LEFT, {}, CHARS.LEFT);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
info("space");
await synthesizeKey(VK.SPACE, {}, " ");
await waitForEvent(browser.contentWindow, "scroll");
let { scrollX: pageScrollX, scrollY: pageScrollY } = await getScrollPosition(browser);
is(pageScrollX, 0, "Should not be scrolled");
ok(pageScrollY > lineScrollY, "Should be scrolled more than a single line");
info("shift+space");
await synthesizeKey(VK.SPACE, { shiftKey: true }, " ");
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
info("page down");
await synthesizeKey(VK.PGDOWN, {}, CHARS.PGDOWN);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, pageScrollY, "Should be scrolled a page");
}
info("page up");
await synthesizeKey(VK.PGUP, {}, CHARS.PGUP);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
info("accel+down");
await synthesizeKey(VK.DOWN, { accelKey: true }, CHARS.DOWN);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY, innerHeight } = await getWindowProperties(browser, ["scrollX", "scrollY", "innerHeight"]);
is(scrollX, 0, "Should not be scrolled");
// We can't know the scrollbar height so check that we're scrolled to within 100px of what we expect.
isfuzzy(scrollY, browser.contentDocument.body.clientHeight - innerHeight, 100, "Should be scrolled to the end.");
}
info("accel+up");
await synthesizeKey(VK.UP, { accelKey: true }, CHARS.UP);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
info("end");
await synthesizeKey(VK.END, {}, CHARS.END);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY, innerHeight } = await getWindowProperties(browser, ["scrollX", "scrollY", "innerHeight"]);
is(scrollX, 0, "Should not be scrolled");
// We can't know the scrollbar height so check that we're scrolled to within 100px of what we expect.
isfuzzy(scrollY, browser.contentDocument.body.clientHeight - innerHeight, 100, "Should be scrolled to the end.");
}
info("home");
await synthesizeKey(VK.HOME, {}, CHARS.HOME);
await waitForEvent(browser.contentWindow, "scroll");
{
let { scrollX, scrollY } = await getScrollPosition(browser);
is(scrollX, 0, "Should not be scrolled");
is(scrollY, 0, "Should not be scrolled");
}
// Select the start of the first paragraph
let paragraph = browser.contentDocument.getElementById("paragraph");
let selection = browser.contentWindow.getSelection();
selection.setBaseAndExtent(paragraph.firstChild, 0, paragraph.firstChild, "Lots of".length);
info("copy");
await SimpleTest.promiseClipboardChange("Lots of", () => {
synthesizeKey(VK.C, { accelKey: true }, "c");
});
for (let i = 0; i < " paragraphs".length; i++) {
info("select right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
}
info("copy");
await SimpleTest.promiseClipboardChange("Lots of paragraphs", () => {
synthesizeKey(VK.C, { accelKey: true }, "c");
});
for (let i = 0; i < " paragraphs".length; i++) {
info("select left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
}
info("copy");
await SimpleTest.promiseClipboardChange("Lots of", () => {
synthesizeKey(VK.C, { accelKey: true }, "c");
});
info("select down");
await synthesizeKey(VK.DOWN, { shiftKey: true }, CHARS.DOWN);
info("copy");
await SimpleTest.promiseClipboardChange("Lots of paragraphs to make a vertical scrollbar.\n\nLots of", () => {
synthesizeKey(VK.C, { accelKey: true }, "c");
});
SimpleTest.finish();
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
</body>
<browser id="browser" src="browsertest.html" style="height: 500px"/>
</window>

Просмотреть файл

@ -0,0 +1,271 @@
<?xml version="1.0"?>
<window title="Browser element keyhandling tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"/>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
const IS_MAC = navigator.platform.indexOf("Mac") === 0;
const VK = {};
const CHARS = {};
// Copied values from NativeKeyCodes.js and EventUtils.js
if (IS_MAC) {
VK.LEFT = MAC_VK_LeftArrow;
CHARS.LEFT = "\uF702";
VK.RIGHT = MAC_VK_RightArrow;
CHARS.RIGHT = "\uF703";
VK.UP = MAC_VK_UpArrow;
CHARS.UP = "\uF700";
VK.DOWN = MAC_VK_DownArrow;
CHARS.DOWN = "\uF701";
VK.SPACE = MAC_VK_Space;
VK.X = MAC_VK_ANSI_X;
VK.V = MAC_VK_ANSI_V;
VK.A = MAC_VK_ANSI_A;
VK.Z = MAC_VK_ANSI_Z;
VK.F = MAC_VK_ANSI_F;
VK.O = MAC_VK_ANSI_O;
VK.BACKSPACE = MAC_VK_PC_Backspace;
CHARS.BACKSPACE = "\u007F";
} else {
VK.LEFT = WIN_VK_LEFT;
CHARS.LEFT = "";
VK.RIGHT = WIN_VK_RIGHT;
CHARS.RIGHT = "";
VK.HOME = WIN_VK_HOME;
CHARS.HOME = "";
VK.END = WIN_VK_END;
CHARS.END = "";
VK.SPACE = WIN_VK_SPACE;
VK.X = WIN_VK_X;
VK.V = WIN_VK_V;
VK.A = WIN_VK_A;
VK.Z = WIN_VK_Z;
VK.Y = WIN_VK_Y;
VK.F = WIN_VK_F;
VK.O = WIN_VK_O;
VK.BACKSPACE = WIN_VK_BACK;
CHARS.BACKSPACE = "";
}
function waitForEvent(target, event) {
info(`Waiting for ${event} event.`);
return new Promise(resolve => {
browser.addEventListener(event, resolve, { once: true });
});
}
function synthesizeKey(keyCode, modifiers, chars) {
return new Promise((resolve, reject) => {
if (!synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, keyCode, modifiers, chars, chars, resolve)) {
reject();
}
});
}
function* nodes(element) {
let node = element.firstChild;
while (node) {
yield node;
if (node.nodeType === Node.ELEMENT_NODE) {
yield* nodes(node);
}
node = node.nextSibling;
}
}
async function checkElement(element, start, selectedText, content = "Test text") {
selectionPosition = (element, range) => {
let pos = 0;
for (let node of nodes(element)) {
if (node.nodeType === Node.TEXT_NODE) {
if (node === range.startContainer) {
return pos + range.startOffset;
} else {
pos += node.nodeValue.length;
}
} else if (node === range.startContainer) {
for (let i = 0; i < range.startOffset; i++) {
pos += node.childNodes[i].textContent.length;
}
return pos;
}
}
throw new Error("startContainer of range never found.");
}
isReady = () => {
let selection = element.contentWindow.getSelection();
let range = selection.getRangeAt(0);
let pos = selectionPosition(element.contentDocument.documentElement, range);
if (start != pos) {
return false;
}
if (selectedText != selection.toString()) {
return false;
}
if (content != element.contentDocument.documentElement.textContent) {
return false;
}
return true;
};
for (let i = 0; i < 10; i++) {
if (isReady()) {
return;
}
SimpleTest.requestFlakyTimeout("Polling for changes to apply");
await new Promise(resolve => setTimeout(resolve, 50));
}
ok(false, `Timed out waiting for state ${start} "${selectedText}" "${content}"`);
let selection = element.contentWindow.getSelection();
let range = selection.getRangeAt(0);
info(`${selectionPosition(element.contentDocument.documentElement, range)} "${selection.toString()}" "${element.contentDocument.documentElement.textContent}"`);
}
async function test() {
let editor = document.getElementById("editor");
editor.contentDocument.designMode = "on";
editor.contentWindow.focus();
let edit = editor.getEditor(editor.contentWindow);
edit.beginningOfDocument();
await checkElement(editor, 0, "");
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(editor, 1, "");
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(editor, 1, "e");
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(editor, 1, "es");
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(editor, 1, "e");
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(editor, 1, "");
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(editor, 0, "T");
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(editor, 1, "");
info("left");
await synthesizeKey(VK.LEFT, {}, CHARS.LEFT);
await checkElement(editor, 0, "");
if (IS_MAC) {
info("down");
await synthesizeKey(VK.DOWN, { shiftKey: true }, CHARS.DOWN);
} else {
info("end");
await synthesizeKey(VK.END, { shiftKey: true }, CHARS.END);
}
await checkElement(editor, 0, "Test text");
info("cut");
await synthesizeKey(VK.X, { accelKey: true }, "x");
await checkElement(editor, 0, "", "");
let text = SpecialPowers.getClipboardData("text/unicode");
is(text, "Test text", "Should have cut to the clipboard");
SpecialPowers.clipboardCopyString("New text");
info("paste");
await synthesizeKey(VK.V, { accelKey: true }, "v");
await checkElement(editor, 8, "", "New text");
if (IS_MAC) {
info("up");
await synthesizeKey(VK.UP, {}, CHARS.UP);
} else {
info("home");
await synthesizeKey(VK.HOME, {}, CHARS.HOME);
}
await checkElement(editor, 0, "", "New text");
info("select all");
await synthesizeKey(VK.A, { accelKey: true}, "a", "select");
await checkElement(editor, 0, "New text", "New text");
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(editor, 8, "", "New text");
info("word left");
if (IS_MAC) {
await synthesizeKey(VK.LEFT, { altKey: true }, CHARS.LEFT);
} else {
await synthesizeKey(VK.LEFT, { ctrlKey: true }, CHARS.LEFT);
}
await checkElement(editor, 4, "", "New text");
info("delete word left");
if (IS_MAC) {
await synthesizeKey(VK.BACKSPACE, { altKey: true }, CHARS.BACKSPACE);
} else {
await synthesizeKey(VK.BACKSPACE, { ctrlKey: true }, CHARS.BACKSPACE);
}
await checkElement(editor, 0, "", "text");
info("undo");
await synthesizeKey(VK.Z, { accelKey: true }, "z");
await checkElement(editor, 4, "", "New text");
info("redo");
if (IS_MAC) {
await synthesizeKey(VK.Z, { accelKey: true, shiftKey: true }, "z");
} else {
await synthesizeKey(VK.Y, { accelKey: true }, "y");
}
await checkElement(editor, 0, "", "text");
info("typing");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.SPACE, {}, " ");
await synthesizeKey(VK.F, {}, "f");
await synthesizeKey(VK.O, {}, "o");
await synthesizeKey(VK.O, {}, "o");
await checkElement(editor, 8, "", "text foo");
SimpleTest.finish();
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
</body>
<editor id="editor" editortype="text" src="data:text/plain,Test text" style="height: 500px"/>
</window>

Просмотреть файл

@ -0,0 +1,226 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>input key handling</title>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/NativeKeyCodes.js"></script>
<link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css" />
<script type="text/javascript">
const IS_MAC = navigator.platform.indexOf("Mac") == 0;
const VK = {};
const CHARS = {};
if (IS_MAC) {
VK.LEFT = MAC_VK_LeftArrow;
CHARS.LEFT = "\uF702";
VK.RIGHT = MAC_VK_RightArrow;
CHARS.RIGHT = "\uF703";
VK.UP = MAC_VK_UpArrow;
CHARS.UP = "\uF700";
VK.DOWN = MAC_VK_DownArrow;
CHARS.DOWN = "\uF701";
VK.X = MAC_VK_ANSI_X;
VK.V = MAC_VK_ANSI_V;
VK.A = MAC_VK_ANSI_A;
VK.F = MAC_VK_ANSI_F;
VK.O = MAC_VK_ANSI_O;
VK.BACKSPACE = MAC_VK_PC_Backspace;
CHARS.BACKSPACE = "\u007F";
VK.Z = MAC_VK_ANSI_Z;
VK.SPACE = MAC_VK_Space;
} else {
VK.LEFT = WIN_VK_LEFT;
CHARS.LEFT = "";
VK.RIGHT = WIN_VK_RIGHT;
CHARS.RIGHT = "";
VK.UP = WIN_VK_UP;
CHARS.UP = "";
VK.DOWN = WIN_VK_DOWN;
CHARS.DOWN = "";
VK.X = WIN_VK_X;
VK.V = WIN_VK_V;
VK.A = WIN_VK_A;
VK.F = WIN_VK_F;
VK.O = WIN_VK_O;
VK.END = WIN_VK_END;
CHARS.END = "";
VK.HOME = WIN_VK_HOME;
CHARS.HOME = "";
VK.BACKSPACE = WIN_VK_BACK;
CHARS.BACKSPACE = "";
VK.Z = WIN_VK_Z;
VK.SPACE = WIN_VK_SPACE;
}
if (window.opener) {
ok = window.opener.ok;
is = window.opener.is;
}
function synthesizeKey(keyCode, modifiers, chars, event = "keyup") {
return new Promise((resolve, reject) => {
window.addEventListener(event, resolve, { once: true });
if (!synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, keyCode, modifiers, chars, chars)) {
reject();
}
});
}
async function checkElement(element, start, end, content = "Test text") {
isReady = () => {
if (start != element.selectionStart) {
return false;
}
if (end != element.selectionEnd) {
return false;
}
if (content != element.value) {
return false;
}
return true;
};
for (let i = 0; i < 10; i++) {
if (isReady()) {
return;
}
SimpleTest.requestFlakyTimeout("Polling for changes to apply");
await new Promise(resolve => setTimeout(resolve, 50));
}
ok(false, "Timed out waiting for state");
is(element.selectionStart, start, "Should have the right selectionStart");
is(element.selectionEnd, end, "Should have the right selectionEnd");
is(element.value, content, "Should have the right value");
}
async function startTest() {
let input = document.getElementById("input");
input.focus();
await checkElement(input, 0, 0);
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(input, 1, 1);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 2);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 3);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 1, 2);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 1, 1);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 0, 1);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 1);
info("left");
await synthesizeKey(VK.LEFT, {}, CHARS.LEFT);
await checkElement(input, 0, 0);
if (IS_MAC) {
info("down");
await synthesizeKey(VK.DOWN, { shiftKey: true }, CHARS.DOWN);
} else {
info("end");
await synthesizeKey(VK.END, { shiftKey: true }, CHARS.END);
}
await checkElement(input, 0, 9);
info("cut");
await synthesizeKey(VK.X, { accelKey: true }, "x", "input");
await checkElement(input, 0, 0, "");
let text = SpecialPowers.getClipboardData("text/unicode");
is(text, "Test text", "Should have cut to the clipboard");
SpecialPowers.clipboardCopyString("New text");
info("paste");
await synthesizeKey(VK.V, { accelKey: true }, "v", "input");
await checkElement(input, 8, 8, "New text");
if (IS_MAC) {
info("up");
await synthesizeKey(VK.UP, {}, CHARS.UP);
} else {
info("home");
await synthesizeKey(VK.HOME, {}, CHARS.HOME);
}
await checkElement(input, 0, 0, "New text");
info("select all");
await synthesizeKey(VK.A, { accelKey: true}, "a", "select");
await checkElement(input, 0, 8, "New text");
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(input, 8, 8, "New text");
info("word left");
if (IS_MAC) {
await synthesizeKey(VK.LEFT, { altKey: true }, CHARS.LEFT);
} else {
await synthesizeKey(VK.LEFT, { ctrlKey: true }, CHARS.LEFT);
}
await checkElement(input, 4, 4, "New text");
info("delete word left");
if (IS_MAC) {
await synthesizeKey(VK.BACKSPACE, { altKey: true }, CHARS.BACKSPACE);
} else {
await synthesizeKey(VK.BACKSPACE, { ctrlKey: true }, CHARS.BACKSPACE);
}
await checkElement(input, 0, 0, "text");
info("undo");
await synthesizeKey(VK.Z, { accelKey: true }, "", "input");
await checkElement(input, 4, 4, "New text");
info("redo");
await synthesizeKey(VK.Z, { accelKey: true, shiftKey: true }, "", "input");
await checkElement(input, 0, 0, "text");
info("typing");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.SPACE, {}, " ");
await synthesizeKey(VK.F, {}, "f");
await synthesizeKey(VK.O, {}, "o");
await synthesizeKey(VK.O, {}, "o");
await checkElement(input, 8, 8, "text foo");
}
async function runTest() {
// When running in windowed mode the caller will start the test once we have
// focus.
if (window.opener) {
return;
}
SimpleTest.waitForExplicitFinish();
await startTest();
SimpleTest.finish();
}
</script>
</head>
<body onload="runTest();">
<input id=input value="Test text"/>
</body>
</html>

Просмотреть файл

@ -0,0 +1,226 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>input key handling</title>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/NativeKeyCodes.js"></script>
<link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css" />
<script type="text/javascript">
const IS_MAC = navigator.platform.indexOf("Mac") == 0;
const VK = {};
const CHARS = {};
if (IS_MAC) {
VK.LEFT = MAC_VK_LeftArrow;
CHARS.LEFT = "\uF702";
VK.RIGHT = MAC_VK_RightArrow;
CHARS.RIGHT = "\uF703";
VK.UP = MAC_VK_UpArrow;
CHARS.UP = "\uF700";
VK.DOWN = MAC_VK_DownArrow;
CHARS.DOWN = "\uF701";
VK.X = MAC_VK_ANSI_X;
VK.V = MAC_VK_ANSI_V;
VK.A = MAC_VK_ANSI_A;
VK.F = MAC_VK_ANSI_F;
VK.O = MAC_VK_ANSI_O;
VK.BACKSPACE = MAC_VK_PC_Backspace;
CHARS.BACKSPACE = "\u007F";
VK.Z = MAC_VK_ANSI_Z;
VK.SPACE = MAC_VK_Space;
} else {
VK.LEFT = WIN_VK_LEFT;
CHARS.LEFT = "";
VK.RIGHT = WIN_VK_RIGHT;
CHARS.RIGHT = "";
VK.UP = WIN_VK_UP;
CHARS.UP = "";
VK.DOWN = WIN_VK_DOWN;
CHARS.DOWN = "";
VK.X = WIN_VK_X;
VK.V = WIN_VK_V;
VK.A = WIN_VK_A;
VK.F = WIN_VK_F;
VK.O = WIN_VK_O;
VK.END = WIN_VK_END;
CHARS.END = "";
VK.HOME = WIN_VK_HOME;
CHARS.HOME = "";
VK.BACKSPACE = WIN_VK_BACK;
CHARS.BACKSPACE = "";
VK.Z = WIN_VK_Z;
VK.SPACE = WIN_VK_SPACE;
}
if (window.opener) {
ok = window.opener.ok;
is = window.opener.is;
}
function synthesizeKey(keyCode, modifiers, chars, event = "keyup") {
return new Promise((resolve, reject) => {
window.addEventListener(event, resolve, { once: true });
if (!synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, keyCode, modifiers, chars, chars)) {
reject();
}
});
}
async function checkElement(element, start, end, content = "Test text") {
isReady = () => {
if (start != element.selectionStart) {
return false;
}
if (end != element.selectionEnd) {
return false;
}
if (content != element.value) {
return false;
}
return true;
};
for (let i = 0; i < 10; i++) {
if (isReady()) {
return;
}
SimpleTest.requestFlakyTimeout("Polling for changes to apply");
await new Promise(resolve => setTimeout(resolve, 50));
}
ok(false, "Timed out waiting for state");
is(element.selectionStart, start, "Should have the right selectionStart");
is(element.selectionEnd, end, "Should have the right selectionEnd");
is(element.value, content, "Should have the right value");
}
async function startTest() {
let input = document.getElementById("input");
input.focus();
await checkElement(input, 0, 0);
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(input, 1, 1);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 2);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 3);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 1, 2);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 1, 1);
info("shift+left");
await synthesizeKey(VK.LEFT, { shiftKey: true }, CHARS.LEFT);
await checkElement(input, 0, 1);
info("shift+right");
await synthesizeKey(VK.RIGHT, { shiftKey: true }, CHARS.RIGHT);
await checkElement(input, 1, 1);
info("left");
await synthesizeKey(VK.LEFT, {}, CHARS.LEFT);
await checkElement(input, 0, 0);
if (IS_MAC) {
info("down");
await synthesizeKey(VK.DOWN, { shiftKey: true }, CHARS.DOWN);
} else {
info("end");
await synthesizeKey(VK.END, { shiftKey: true }, CHARS.END);
}
await checkElement(input, 0, 9);
info("cut");
await synthesizeKey(VK.X, { accelKey: true }, "x", "input");
await checkElement(input, 0, 0, "");
let text = SpecialPowers.getClipboardData("text/unicode");
is(text, "Test text", "Should have cut to the clipboard");
SpecialPowers.clipboardCopyString("New text");
info("paste");
await synthesizeKey(VK.V, { accelKey: true }, "v", "input");
await checkElement(input, 8, 8, "New text");
if (IS_MAC) {
info("up");
await synthesizeKey(VK.UP, {}, CHARS.UP);
} else {
info("home");
await synthesizeKey(VK.HOME, {}, CHARS.HOME);
}
await checkElement(input, 0, 0, "New text");
info("select all");
await synthesizeKey(VK.A, { accelKey: true}, "a", "select");
await checkElement(input, 0, 8, "New text");
info("right");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await checkElement(input, 8, 8, "New text");
info("word left");
if (IS_MAC) {
await synthesizeKey(VK.LEFT, { altKey: true }, CHARS.LEFT);
} else {
await synthesizeKey(VK.LEFT, { ctrlKey: true }, CHARS.LEFT);
}
await checkElement(input, 4, 4, "New text");
info("delete word left");
if (IS_MAC) {
await synthesizeKey(VK.BACKSPACE, { altKey: true }, CHARS.BACKSPACE);
} else {
await synthesizeKey(VK.BACKSPACE, { ctrlKey: true }, CHARS.BACKSPACE);
}
await checkElement(input, 0, 0, "text");
info("undo");
await synthesizeKey(VK.Z, { accelKey: true }, "", "input");
await checkElement(input, 4, 4, "New text");
info("redo");
await synthesizeKey(VK.Z, { accelKey: true, shiftKey: true }, "", "input");
await checkElement(input, 0, 0, "text");
info("typing");
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.RIGHT, {}, CHARS.RIGHT);
await synthesizeKey(VK.SPACE, {}, " ");
await synthesizeKey(VK.F, {}, "f");
await synthesizeKey(VK.O, {}, "o");
await synthesizeKey(VK.O, {}, "o");
await checkElement(input, 8, 8, "text foo");
}
async function runTest() {
// When running in windowed mode the caller will start the test once we have
// focus.
if (window.opener) {
return;
}
SimpleTest.waitForExplicitFinish();
await startTest();
SimpleTest.finish();
}
</script>
</head>
<body onload="runTest();">
<textarea id=input>Test text</textarea>
</body>
</html>

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<window title="Top-level window keyhandling tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="test();">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
async function run_test(path) {
let win = window.openDialog(path, "_blank", "width=500,height=500");
await SimpleTest.promiseFocus(win);
await win.startTest();
}
async function test() {
await run_test("test_input.html");
await run_test("test_textarea.html");
SimpleTest.finish();
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display:none;"></div>
<pre id="test"></pre>
</body>
</window>

Просмотреть файл

@ -162,6 +162,7 @@ MOCHITEST_MANIFESTS += [
'mochitest/gamepad/mochitest.ini',
'mochitest/general/mochitest.ini',
'mochitest/geolocation/mochitest.ini',
'mochitest/keyhandling/mochitest.ini',
'mochitest/localstorage/mochitest.ini',
'mochitest/orientation/mochitest.ini',
'mochitest/pointerlock/mochitest.ini',
@ -177,6 +178,7 @@ MOCHITEST_CHROME_MANIFESTS += [
'mochitest/chrome/chrome.ini',
'mochitest/general/chrome.ini',
'mochitest/geolocation/chrome.ini',
'mochitest/keyhandling/chrome.ini',
'mochitest/localstorage/chrome.ini',
'mochitest/sessionstorage/chrome.ini',
'mochitest/webcomponents/chrome.ini',

Просмотреть файл

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
{ u"keypress", nullptr, u" ", u"shift", u"cmd_scrollPageUp" },
{ u"keypress", nullptr, u" ", nullptr, u"cmd_scrollPageDown" },
{ u"keypress", u"VK_UP", nullptr, nullptr, u"cmd_moveUp" },
{ u"keypress", u"VK_DOWN", nullptr, nullptr, u"cmd_moveDown" },
{ u"keypress", u"VK_LEFT", nullptr, nullptr, u"cmd_moveLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, nullptr, u"cmd_moveRight" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },

Просмотреть файл

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
{ u"keypress", nullptr, u" ", u"shift", u"cmd_scrollPageUp" },
{ u"keypress", nullptr, u" ", nullptr, u"cmd_scrollPageDown" },
{ u"keypress", u"VK_LEFT", nullptr, nullptr, u"cmd_moveLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, nullptr, u"cmd_moveRight" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_UP", nullptr, nullptr, u"cmd_moveUp" },
{ u"keypress", u"VK_DOWN", nullptr, nullptr, u"cmd_moveDown" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"v", u"accel,shift", u"cmd_pasteNoFormatting" },

Просмотреть файл

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
{ u"keypress", u"VK_LEFT", nullptr, nullptr, u"cmd_moveLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, nullptr, u"cmd_moveRight" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_UP", nullptr, nullptr, u"cmd_moveUp" },
{ u"keypress", u"VK_DOWN", nullptr, nullptr, u"cmd_moveDown" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },

Просмотреть файл

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
{ u"keypress", u"VK_LEFT", nullptr, nullptr, u"cmd_moveLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, nullptr, u"cmd_moveRight" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_UP", nullptr, nullptr, u"cmd_moveUp" },
{ u"keypress", u"VK_DOWN", nullptr, nullptr, u"cmd_moveDown" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },

Просмотреть файл

@ -0,0 +1,118 @@
#include "mozilla/ShortcutKeys.h"
#include "../nsXBLPrototypeHandler.h"
#include "nsContentUtils.h"
#include "nsAtom.h"
#include "mozilla/TextEvents.h"
namespace mozilla {
NS_IMPL_ISUPPORTS(ShortcutKeys, nsIObserver);
StaticRefPtr<ShortcutKeys> ShortcutKeys::sInstance;
ShortcutKeys::ShortcutKeys()
: mBrowserHandlers(nullptr)
, mEditorHandlers(nullptr)
, mInputHandlers(nullptr)
, mTextAreaHandlers(nullptr)
{
MOZ_ASSERT(!sInstance, "Attempt to instantiate a second ShortcutKeys.");
nsContentUtils::RegisterShutdownObserver(this);
}
ShortcutKeys::~ShortcutKeys()
{
delete mBrowserHandlers;
delete mEditorHandlers;
delete mInputHandlers;
delete mTextAreaHandlers;
}
nsresult
ShortcutKeys::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
{
// Clear our strong reference so we can clean up.
sInstance = nullptr;
return NS_OK;
}
/* static */ nsXBLPrototypeHandler*
ShortcutKeys::GetHandlers(HandlerType aType)
{
if (!sInstance) {
sInstance = new ShortcutKeys();
}
return sInstance->EnsureHandlers(aType);
}
/* static */ nsAtom*
ShortcutKeys::ConvertEventToDOMEventType(const WidgetKeyboardEvent* aWidgetKeyboardEvent)
{
if (aWidgetKeyboardEvent->IsKeyDownOrKeyDownOnPlugin()) {
return nsGkAtoms::keydown;
}
if (aWidgetKeyboardEvent->IsKeyUpOrKeyUpOnPlugin()) {
return nsGkAtoms::keyup;
}
// eAccessKeyNotFound event is always created from eKeyPress event and
// the original eKeyPress event has stopped its propagation before dispatched
// into the DOM tree in this process and not matched with remote content's
// access keys. So, we should treat it as an eKeyPress event and execute
// a command if it's registered as a shortcut key.
if (aWidgetKeyboardEvent->mMessage == eKeyPress ||
aWidgetKeyboardEvent->mMessage == eAccessKeyNotFound) {
return nsGkAtoms::keypress;
}
MOZ_ASSERT_UNREACHABLE("All event messages relating to shortcut keys should be handled");
return nullptr;
}
nsXBLPrototypeHandler*
ShortcutKeys::EnsureHandlers(HandlerType aType)
{
ShortcutKeyData* keyData;
nsXBLPrototypeHandler** cache;
switch (aType) {
case HandlerType::eBrowser:
keyData = &sBrowserHandlers[0];
cache = &mBrowserHandlers;
break;
case HandlerType::eEditor:
keyData = &sEditorHandlers[0];
cache = &mEditorHandlers;
break;
case HandlerType::eInput:
keyData = &sInputHandlers[0];
cache = &mInputHandlers;
break;
case HandlerType::eTextArea:
keyData = &sTextAreaHandlers[0];
cache = &mTextAreaHandlers;
break;
default:
MOZ_ASSERT(false, "Unknown handler type requested.");
}
if (*cache) {
return *cache;
}
nsXBLPrototypeHandler* lastHandler = nullptr;
while (keyData->event) {
nsXBLPrototypeHandler* handler =
new nsXBLPrototypeHandler(keyData);
if (lastHandler) {
lastHandler->SetNextHandler(handler);
} else {
*cache = handler;
}
lastHandler = handler;
keyData++;
}
return *cache;
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,71 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ShortcutKeys_h
#define mozilla_dom_ShortcutKeys_h
#include "nsIObserver.h"
class nsXBLPrototypeHandler;
class nsAtom;
namespace mozilla {
class WidgetKeyboardEvent;
typedef struct
{
const char16_t* event;
const char16_t* keycode;
const char16_t* key;
const char16_t* modifiers;
const char16_t* command;
} ShortcutKeyData;
enum class HandlerType
{
eInput,
eTextArea,
eBrowser,
eEditor,
};
class ShortcutKeys : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
// Returns a pointer to the first handler for the given type.
static nsXBLPrototypeHandler* GetHandlers(HandlerType aType);
// Gets the event type for a widget keyboard event.
static nsAtom* ConvertEventToDOMEventType(const WidgetKeyboardEvent* aWidgetKeyboardEvent);
protected:
ShortcutKeys();
virtual ~ShortcutKeys();
// Returns a pointer to the first handler for the given type.
nsXBLPrototypeHandler* EnsureHandlers(HandlerType aType);
// Maintains a strong reference to the only instance.
static StaticRefPtr<ShortcutKeys> sInstance;
// Shortcut keys for different elements.
static ShortcutKeyData sBrowserHandlers[];
static ShortcutKeyData sEditorHandlers[];
static ShortcutKeyData sInputHandlers[];
static ShortcutKeyData sTextAreaHandlers[];
// Cached event handlers generated from the above data.
nsXBLPrototypeHandler* mBrowserHandlers;
nsXBLPrototypeHandler* mEditorHandlers;
nsXBLPrototypeHandler* mInputHandlers;
nsXBLPrototypeHandler* mTextAreaHandlers;
};
} // namespace mozilla
#endif // #ifndef mozilla_dom_ShortcutKeys_h

Просмотреть файл

@ -0,0 +1,152 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ShortcutKeys.h"
namespace mozilla {
ShortcutKeyData ShortcutKeys::sInputHandlers[] =
{
#include "../ShortcutKeyDefinitionsForInputCommon.h"
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt", u"cmd_beginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt", u"cmd_endLine" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,alt", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,alt", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"alt", u"cmd_deleteToEndOfLine" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sTextAreaHandlers[] =
{
#include "../ShortcutKeyDefinitionsForTextAreaCommon.h"
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt", u"cmd_beginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt", u"cmd_endLine" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,alt", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,alt", u"cmd_selectEndLine" },
{ u"keypress", u"VK_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"alt", u"cmd_deleteToEndOfLine" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sBrowserHandlers[] =
{
#include "../ShortcutKeyDefinitionsForBrowserCommon.h"
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectCharPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectCharNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"control,shift", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control,shift", u"cmd_selectWordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt", u"cmd_beginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt", u"cmd_endLine" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,alt", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,alt", u"cmd_selectEndLine" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectLinePrevious" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectLineNext" },
{ u"keypress", u"VK_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"alt", u"cmd_deleteToEndOfLine" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sEditorHandlers[] =
{
#include "../ShortcutKeyDefinitionsForEditorCommon.h"
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt", u"cmd_beginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt", u"cmd_endLine" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,alt", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,alt", u"cmd_selectEndLine" },
{ u"keypress", u"VK_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"alt", u"cmd_moveTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"alt", u"cmd_moveBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift,alt", u"cmd_selectTop" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift,alt", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"alt", u"cmd_deleteToEndOfLine" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
} // namespace mozilla

Просмотреть файл

@ -1,6 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml)

Просмотреть файл

@ -4,4 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
SOURCES += ['ShortcutKeyDefinitions.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,162 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="htmlBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="inputFields" bindToUntrustedContent="true">
<handlers>
#include ../input-fields-base.inc
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectWordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,alt" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,alt" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="alt" command="cmd_deleteToEndOfLine"/>
</handlers>
</binding>
<binding id="textAreas" bindToUntrustedContent="true">
<handlers>
#include ../textareas-base.inc
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectWordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,alt" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,alt" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="alt" command="cmd_deleteToEndOfLine"/>
</handlers>
</binding>
<binding id="browser">
<handlers>
#include ../browser-base.inc
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectCharPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectCharNext" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectWordPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectWordNext" />
<handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,alt" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,alt" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectLinePrevious" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectLineNext" />
<handler event="keypress" keycode="VK_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="alt" command="cmd_deleteToEndOfLine"/>
</handlers>
</binding>
<binding id="editor">
<handlers>
#include ../editor-base.inc
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectWordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,alt" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,alt" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="alt" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="alt" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift,alt" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift,alt" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="alt" command="cmd_deleteToEndOfLine"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -1,14 +0,0 @@
<handler event="keypress" key=" " modifiers="shift" command="cmd_scrollPageUp" />
<handler event="keypress" key=" " command="cmd_scrollPageDown" />
<handler event="keypress" keycode="VK_UP" command="cmd_moveUp" />
<handler event="keypress" keycode="VK_DOWN" command="cmd_moveDown" />
<handler event="keypress" keycode="VK_LEFT" command="cmd_moveLeft" />
<handler event="keypress" keycode="VK_RIGHT" command="cmd_moveRight" />
<handler event="keypress" key="x" command="cmd_cut" modifiers="accel"/>
<handler event="keypress" key="c" command="cmd_copy" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_paste" modifiers="accel"/>
<handler event="keypress" key="z" command="cmd_undo" modifiers="accel"/>
<handler event="keypress" key="z" command="cmd_redo" modifiers="accel,shift" />
<handler event="keypress" key="a" command="cmd_selectAll" modifiers="accel"/>

Просмотреть файл

@ -1,19 +0,0 @@
<handler event="keypress" key=" " modifiers="shift" command="cmd_scrollPageUp" />
<handler event="keypress" key=" " command="cmd_scrollPageDown" />
<handler event="keypress" keycode="VK_LEFT" command="cmd_moveLeft"/>
<handler event="keypress" keycode="VK_RIGHT" command="cmd_moveRight"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight"/>
<handler event="keypress" keycode="VK_UP" command="cmd_moveUp"/>
<handler event="keypress" keycode="VK_DOWN" command="cmd_moveDown"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown"/>
<handler event="keypress" key="z" command="cmd_undo" modifiers="accel"/>
<handler event="keypress" key="z" command="cmd_redo" modifiers="accel,shift" />
<handler event="keypress" key="x" command="cmd_cut" modifiers="accel"/>
<handler event="keypress" key="c" command="cmd_copy" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_paste" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_pasteNoFormatting" modifiers="accel,shift"/>

Просмотреть файл

@ -0,0 +1,164 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ShortcutKeys.h"
namespace mozilla {
ShortcutKeyData ShortcutKeys::sInputHandlers[] =
{
#include "../ShortcutKeyDefinitionsForInputCommon.h"
{ u"keypress", nullptr, u"a", u"control", u"cmd_beginLine" },
{ u"keypress", nullptr, u"e", u"control", u"cmd_endLine" },
{ u"keypress", nullptr, u"b", u"control", u"cmd_charPrevious" },
{ u"keypress", nullptr, u"f", u"control", u"cmd_charNext" },
{ u"keypress", nullptr, u"h", u"control", u"cmd_deleteCharBackward" },
{ u"keypress", nullptr, u"d", u"control", u"cmd_deleteCharForward" },
{ u"keypress", nullptr, u"w", u"control", u"cmd_deleteWordBackward" },
{ u"keypress", nullptr, u"u", u"control", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", nullptr, u"k", u"control", u"cmd_deleteToEndOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_copyOrDelete" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control,shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"control,shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sTextAreaHandlers[] =
{
#include "../ShortcutKeyDefinitionsForTextAreaCommon.h"
{ u"keypress", nullptr, u"a", u"control", u"cmd_beginLine" },
{ u"keypress", nullptr, u"e", u"control", u"cmd_endLine" },
{ u"keypress", nullptr, u"b", u"control", u"cmd_charPrevious" },
{ u"keypress", nullptr, u"f", u"control", u"cmd_charNext" },
{ u"keypress", nullptr, u"h", u"control", u"cmd_deleteCharBackward" },
{ u"keypress", nullptr, u"d", u"control", u"cmd_deleteCharForward" },
{ u"keypress", nullptr, u"w", u"control", u"cmd_deleteWordBackward" },
{ u"keypress", nullptr, u"u", u"control", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", nullptr, u"k", u"control", u"cmd_deleteToEndOfLine" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_copyOrDelete" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", nullptr, u"n", u"control", u"cmd_lineNext" },
{ u"keypress", nullptr, u"p", u"control", u"cmd_linePrevious" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sBrowserHandlers[] =
{
#include "../ShortcutKeyDefinitionsForBrowserCommon.h"
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cut" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"control,shift", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control,shift", u"cmd_selectWordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectCharPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectCharNext" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectLinePrevious" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectLineNext" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sEditorHandlers[] =
{
#include "../ShortcutKeyDefinitionsForEditorCommon.h"
{ u"keypress", nullptr, u"h", u"control", u"cmd_deleteCharBackward" },
{ u"keypress", nullptr, u"d", u"control", u"cmd_deleteCharForward" },
{ u"keypress", nullptr, u"k", u"control", u"cmd_deleteToEndOfLine" },
{ u"keypress", nullptr, u"u", u"control", u"cmd_deleteToBeginningOfLine" },
{ u"keypress", nullptr, u"a", u"control", u"cmd_beginLine" },
{ u"keypress", nullptr, u"e", u"control", u"cmd_endLine" },
{ u"keypress", nullptr, u"b", u"control", u"cmd_charPrevious" },
{ u"keypress", nullptr, u"f", u"control", u"cmd_charNext" },
{ u"keypress", nullptr, u"p", u"control", u"cmd_linePrevious" },
{ u"keypress", nullptr, u"n", u"control", u"cmd_lineNext" },
{ u"keypress", nullptr, u"x", u"control", u"cmd_cut" },
{ u"keypress", nullptr, u"c", u"control", u"cmd_copy" },
{ u"keypress", nullptr, u"v", u"control", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"control", u"cmd_undo" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_copyOrDelete" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_wordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_wordNext" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectWordPrevious" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectWordNext" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
} // namespace mozilla

Просмотреть файл

@ -1,6 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml)

Просмотреть файл

@ -4,4 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
SOURCES += ['ShortcutKeyDefinitions.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,237 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="htmlBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="inputFields" bindToUntrustedContent="true">
<handlers>
#include ../input-fields-base.inc
<!-- Emacsish single-line motion and delete keys -->
<handler event="keypress" key="a" modifiers="control"
command="cmd_beginLine"/>
<handler event="keypress" key="e" modifiers="control"
command="cmd_endLine"/>
<handler event="keypress" key="b" modifiers="control"
command="cmd_charPrevious"/>
<handler event="keypress" key="f" modifiers="control"
command="cmd_charNext"/>
<handler event="keypress" key="h" modifiers="control"
command="cmd_deleteCharBackward"/>
<handler event="keypress" key="d" modifiers="control"
command="cmd_deleteCharForward"/>
<handler event="keypress" key="w" modifiers="control"
command="cmd_deleteWordBackward"/>
<handler event="keypress" key="u" modifiers="control"
command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" key="k" modifiers="control"
command="cmd_deleteToEndOfLine"/>
<!-- Alternate Windows copy/paste/undo/redo keys -->
<handler event="keypress" keycode="VK_DELETE" modifiers="shift"
command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control"
command="cmd_copyOrDelete"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control"
command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift"
command="cmd_paste"/>
<!-- navigating by word keys -->
<handler event="keypress" keycode="VK_HOME"
command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END"
command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift"
command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="shift"
command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control"
command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="control"
command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control,shift"
command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="control,shift"
command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control"
command="cmd_deleteWordBackward"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control"
command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control"
command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control"
command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control"
command="cmd_selectWordNext"/>
<handler event="keypress" key="y" modifiers="accel"
command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="alt"
command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="textAreas" bindToUntrustedContent="true">
<handlers>
#include ../textareas-base.inc
<!-- Emacsish single-line motion and delete keys -->
<handler event="keypress" key="a" modifiers="control"
command="cmd_beginLine"/>
<handler event="keypress" key="e" modifiers="control"
command="cmd_endLine"/>
<handler event="keypress" id="key_left" key="b" modifiers="control"
command="cmd_charPrevious"/>
<handler event="keypress" id="key_right" key="f" modifiers="control"
command="cmd_charNext"/>
<handler event="keypress" id="key_delback" key="h" modifiers="control"
command="cmd_deleteCharBackward"/>
<handler event="keypress" id="key_delforw" key="d" modifiers="control"
command="cmd_deleteCharForward"/>
<handler event="keypress" id="key_delwback" key="w" modifiers="control"
command="cmd_deleteWordBackward"/>
<handler event="keypress" id="key_del_bol" key="u" modifiers="control"
command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" id="key_del_eol" key="k" modifiers="control"
command="cmd_deleteToEndOfLine"/>
<!-- Alternate Windows copy/paste/undo/redo keys -->
<handler event="keypress" keycode="VK_DELETE" modifiers="shift"
command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control"
command="cmd_copyOrDelete"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control"
command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift"
command="cmd_paste"/>
<!-- Emacsish multi-line motion and delete keys -->
<handler event="keypress" id="key_linedown" key="n" modifiers="control"
command="cmd_lineNext"/>
<handler event="keypress" id="key_lineup" key="p" modifiers="control"
command="cmd_linePrevious"/>
<!-- handle home/end/arrow keys and redo -->
<handler event="keypress" keycode="VK_HOME"
command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END"
command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift"
command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="shift"
command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control"
command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control"
command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control"
command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_END" modifiers="shift,control"
command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP"
command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN"
command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift"
command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift"
command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control"
command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control"
command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control"
command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control"
command="cmd_selectWordNext"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control"
command="cmd_deleteWordBackward"/>
<handler event="keypress" key="y" modifiers="accel"
command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="alt"
command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="browser">
<handlers>
#include ../browser-base.inc
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cut" />
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectWordPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectWordNext" />
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectCharPrevious" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectCharNext" />
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectLinePrevious" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectLineNext" />
<handler event="keypress" key="a" modifiers="alt" command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="editor">
<handlers>
#include ../editor-base.inc
<handler event="keypress" key="h" modifiers="control" command="cmd_deleteCharBackward"/>
<handler event="keypress" key="d" modifiers="control" command="cmd_deleteCharForward"/>
<handler event="keypress" key="k" modifiers="control" command="cmd_deleteToEndOfLine"/>
<handler event="keypress" key="u" modifiers="control" command="cmd_deleteToBeginningOfLine"/>
<handler event="keypress" key="a" modifiers="control" command="cmd_beginLine"/>
<handler event="keypress" key="e" modifiers="control" command="cmd_endLine"/>
<handler event="keypress" key="b" modifiers="control" command="cmd_charPrevious"/>
<handler event="keypress" key="f" modifiers="control" command="cmd_charNext"/>
<handler event="keypress" key="p" modifiers="control" command="cmd_linePrevious"/>
<handler event="keypress" key="n" modifiers="control" command="cmd_lineNext"/>
<handler event="keypress" key="x" modifiers="control" command="cmd_cut"/>
<handler event="keypress" key="c" modifiers="control" command="cmd_copy"/>
<handler event="keypress" key="v" modifiers="control" command="cmd_paste"/>
<handler event="keypress" key="z" modifiers="control" command="cmd_undo"/>
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="alt" command="cmd_selectAll"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_copyOrDelete"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift" command="cmd_paste"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_wordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_wordNext"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectWordPrevious"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectWordNext"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control" command="cmd_deleteWordBackward"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -1,17 +0,0 @@
<handler event="keypress" keycode="VK_LEFT" command="cmd_moveLeft"/>
<handler event="keypress" keycode="VK_RIGHT" command="cmd_moveRight"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight"/>
<handler event="keypress" keycode="VK_UP" command="cmd_moveUp"/>
<handler event="keypress" keycode="VK_DOWN" command="cmd_moveDown"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown"/>
<!-- Cut/copy/paste/undo -->
<handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/>
<handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/>
<handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo" />

Просмотреть файл

@ -0,0 +1,73 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ShortcutKeys.h"
namespace mozilla {
ShortcutKeyData ShortcutKeys::sInputHandlers[] =
{
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sTextAreaHandlers[] =
{
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sBrowserHandlers[] =
{
#include "../ShortcutKeyDefinitionsForBrowserCommon.h"
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_scrollPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_scrollPageDown" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_scrollTop" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_scrollBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"alt,shift", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"alt,shift", u"cmd_selectRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_UP", nullptr, u"alt,shift", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"alt,shift", u"cmd_selectDown2" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", u"VK_UP", nullptr, u"accel", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"accel", u"cmd_moveDown2" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sEditorHandlers[] =
{
{ u"keypress", nullptr, u" ", u"shift", u"cmd_scrollPageUp" },
{ u"keypress", nullptr, u" ", nullptr, u"cmd_scrollPageDown" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"x", u"accel", u"cmd_cut" },
{ u"keypress", nullptr, u"c", u"accel", u"cmd_copy" },
{ u"keypress", nullptr, u"v", u"accel", u"cmd_paste" },
{ u"keypress", nullptr, u"v", u"accel,shift", u"cmd_pasteNoFormatting" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", nullptr, u"v", u"accel,alt,shift", u"cmd_pasteNoFormatting" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
} // namespace mozilla

Просмотреть файл

@ -1,6 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml)

Просмотреть файл

@ -4,4 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
SOURCES += ['ShortcutKeyDefinitions.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,72 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="htmlBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="inputFields" bindToUntrustedContent="true">
<handlers>
<handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/>
<handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/>
<handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="textAreas" bindToUntrustedContent="true">
<handlers>
<handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/>
<handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/>
<handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="browser">
<handlers>
#include ../browser-base.inc
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_scrollPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_scrollPageDown"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_scrollTop" />
<handler event="keypress" keycode="VK_END" command="cmd_scrollBottom" />
<handler event="keypress" keycode="VK_LEFT" modifiers="alt" command="cmd_moveLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt" command="cmd_moveRight2" />
<handler event="keypress" keycode="VK_LEFT" modifiers="alt,shift" command="cmd_selectLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="alt,shift" command="cmd_selectRight2" />
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight" />
<handler event="keypress" keycode="VK_UP" modifiers="alt,shift" command="cmd_selectUp2" />
<handler event="keypress" keycode="VK_DOWN" modifiers="alt,shift" command="cmd_selectDown2" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown" />
<handler event="keypress" keycode="VK_UP" modifiers="accel" command="cmd_moveUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="accel" command="cmd_moveDown2"/>
</handlers>
</binding>
<binding id="editor">
<handlers>
<handler event="keypress" key=" " modifiers="shift" command="cmd_scrollPageUp" />
<handler event="keypress" key=" " command="cmd_scrollPageDown" />
<handler event="keypress" key="z" command="cmd_undo" modifiers="accel"/>
<handler event="keypress" key="z" command="cmd_redo" modifiers="accel,shift" />
<handler event="keypress" key="x" command="cmd_cut" modifiers="accel"/>
<handler event="keypress" key="c" command="cmd_copy" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_paste" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_pasteNoFormatting" modifiers="accel,shift"/>
<handler event="keypress" key="a" command="cmd_selectAll" modifiers="accel"/>
<handler event="keypress" key="v" command="cmd_pasteNoFormatting" modifiers="accel,alt,shift"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -15,3 +15,8 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
else:
DIRS += ['emacs']
EXPORTS.mozilla += ['ShortcutKeys.h']
SOURCES += ['ShortcutKeys.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,16 +0,0 @@
<handler event="keypress" keycode="VK_LEFT" command="cmd_moveLeft"/>
<handler event="keypress" keycode="VK_RIGHT" command="cmd_moveRight"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight"/>
<handler event="keypress" keycode="VK_UP" command="cmd_moveUp"/>
<handler event="keypress" keycode="VK_DOWN" command="cmd_moveDown"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown"/>
<!-- Cut/copy/paste/undo -->
<handler event="keypress" key="c" modifiers="accel" command="cmd_copy"/>
<handler event="keypress" key="x" modifiers="accel" command="cmd_cut"/>
<handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo" />

Просмотреть файл

@ -0,0 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ShortcutKeys.h"
namespace mozilla {
ShortcutKeyData ShortcutKeys::sInputHandlers[] =
{
#include "../ShortcutKeyDefinitionsForInputCommon.h"
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sTextAreaHandlers[] =
{
#include "../ShortcutKeyDefinitionsForTextAreaCommon.h"
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sBrowserHandlers[] =
{
#include "../ShortcutKeyDefinitionsForBrowserCommon.h"
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cut" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"control,shift", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control,shift", u"cmd_selectRight2" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", u"VK_UP", nullptr, u"control", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control", u"cmd_moveDown2" },
{ u"keypress", u"VK_UP", nullptr, u"control,shift", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control,shift", u"cmd_selectDown2" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sEditorHandlers[] =
{
#include "../ShortcutKeyDefinitionsForEditorCommon.h"
{ u"keypress", nullptr, u"z", u"accel", u"cmd_undo" },
{ u"keypress", nullptr, u"z", u"accel,shift", u"cmd_redo" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ u"keypress", nullptr, u"a", u"alt", u"cmd_selectAll" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
} // namespace mozilla

Просмотреть файл

@ -1,6 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml)

Просмотреть файл

@ -4,4 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
SOURCES += ['ShortcutKeyDefinitions.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,82 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="htmlBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="inputFields" bindToUntrustedContent="true">
<handlers>
#include ../input-fields-base.inc
<handler event="keypress" key="a" modifiers="alt"
command="cmd_selectAll"/>
<handler event="keypress" key="y" modifiers="accel"
command="cmd_redo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
</handlers>
</binding>
<binding id="textAreas" bindToUntrustedContent="true">
<handlers>
#include ../textareas-base.inc
<handler event="keypress" key="a" modifiers="alt"
command="cmd_selectAll"/>
<handler event="keypress" key="y" modifiers="accel"
command="cmd_redo"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
</handlers>
</binding>
<binding id="browser">
<handlers>
#include ../browser-base.inc
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cut" />
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_moveLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_moveRight2" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectRight2" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown" />
<handler event="keypress" keycode="VK_UP" modifiers="control" command="cmd_moveUp2" />
<handler event="keypress" keycode="VK_DOWN" modifiers="control" command="cmd_moveDown2" />
<handler event="keypress" keycode="VK_UP" modifiers="control,shift" command="cmd_selectUp2" />
<handler event="keypress" keycode="VK_DOWN" modifiers="control,shift" command="cmd_selectDown2" />
<handler event="keypress" key="a" modifiers="alt" command="cmd_selectAll"/>
</handlers>
</binding>
<binding id="editor">
<handlers>
#include ../editor-base.inc
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift" command="cmd_redo"/>
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
<handler event="keypress" key="a" modifiers="alt" command="cmd_selectAll"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -0,0 +1,152 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../ShortcutKeys.h"
namespace mozilla {
ShortcutKeyData ShortcutKeys::sInputHandlers[] =
{
#include "../ShortcutKeyDefinitionsForInputCommon.h"
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectRight2" },
{ u"keypress", u"VK_UP", nullptr, u"control", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control", u"cmd_moveDown2" },
{ u"keypress", u"VK_UP", nullptr, u"shift,control", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,control", u"cmd_selectDown2" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_deleteWordForward" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_undo" },
{ u"keypress", u"VK_BACK", nullptr, u"alt,shift", u"cmd_redo" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sTextAreaHandlers[] =
{
#include "../ShortcutKeyDefinitionsForTextAreaCommon.h"
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,control", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,control", u"cmd_selectRight2" },
{ u"keypress", u"VK_UP", nullptr, u"control", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control", u"cmd_moveDown2" },
{ u"keypress", u"VK_UP", nullptr, u"shift,control", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,control", u"cmd_selectDown2" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_deleteWordForward" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_undo" },
{ u"keypress", u"VK_BACK", nullptr, u"alt,shift", u"cmd_redo" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sBrowserHandlers[] =
{
#include "../ShortcutKeyDefinitionsForBrowserCommon.h"
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cut" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_deleteWordForward" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_LEFT", nullptr, u"control", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"control,shift", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"control,shift", u"cmd_selectRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift", u"cmd_selectLeft" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift", u"cmd_selectRight" },
{ u"keypress", u"VK_UP", nullptr, u"control", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control", u"cmd_moveDown2" },
{ u"keypress", u"VK_UP", nullptr, u"control,shift", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"control,shift", u"cmd_selectDown2" },
{ u"keypress", u"VK_UP", nullptr, u"shift", u"cmd_selectUp" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift", u"cmd_selectDown" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
ShortcutKeyData ShortcutKeys::sEditorHandlers[] =
{
#include "../ShortcutKeyDefinitionsForEditorCommon.h"
{ u"keypress", nullptr, u"a", u"accel", u"cmd_selectAll" },
{ u"keypress", u"VK_DELETE", nullptr, u"shift", u"cmd_cutOrDelete" },
{ u"keypress", u"VK_DELETE", nullptr, u"control", u"cmd_deleteWordForward" },
{ u"keypress", u"VK_INSERT", nullptr, u"control", u"cmd_copy" },
{ u"keypress", u"VK_INSERT", nullptr, u"shift", u"cmd_paste" },
{ u"keypress", u"VK_BACK", nullptr, u"alt", u"cmd_undo" },
{ u"keypress", u"VK_BACK", nullptr, u"alt,shift", u"cmd_redo" },
{ u"keypress", u"VK_LEFT", nullptr, u"accel", u"cmd_moveLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"accel", u"cmd_moveRight2" },
{ u"keypress", u"VK_LEFT", nullptr, u"shift,accel", u"cmd_selectLeft2" },
{ u"keypress", u"VK_RIGHT", nullptr, u"shift,accel", u"cmd_selectRight2" },
{ u"keypress", u"VK_UP", nullptr, u"accel", u"cmd_moveUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"accel", u"cmd_moveDown2" },
{ u"keypress", u"VK_UP", nullptr, u"shift,accel", u"cmd_selectUp2" },
{ u"keypress", u"VK_DOWN", nullptr, u"shift,accel", u"cmd_selectDown2" },
{ u"keypress", u"VK_HOME", nullptr, u"shift,control", u"cmd_selectTop" },
{ u"keypress", u"VK_END", nullptr, u"shift,control", u"cmd_selectBottom" },
{ u"keypress", u"VK_HOME", nullptr, u"control", u"cmd_moveTop" },
{ u"keypress", u"VK_END", nullptr, u"control", u"cmd_moveBottom" },
{ u"keypress", u"VK_BACK", nullptr, u"control", u"cmd_deleteWordBackward" },
{ u"keypress", u"VK_HOME", nullptr, nullptr, u"cmd_beginLine" },
{ u"keypress", u"VK_END", nullptr, nullptr, u"cmd_endLine" },
{ u"keypress", u"VK_HOME", nullptr, u"shift", u"cmd_selectBeginLine" },
{ u"keypress", u"VK_END", nullptr, u"shift", u"cmd_selectEndLine" },
{ u"keypress", u"VK_PAGE_UP", nullptr, nullptr, u"cmd_movePageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, nullptr, u"cmd_movePageDown" },
{ u"keypress", u"VK_PAGE_UP", nullptr, u"shift", u"cmd_selectPageUp" },
{ u"keypress", u"VK_PAGE_DOWN", nullptr, u"shift", u"cmd_selectPageDown" },
{ u"keypress", nullptr, u"y", u"accel", u"cmd_redo" },
{ nullptr, nullptr, nullptr, nullptr, nullptr }
};
} // namespace mozilla

Просмотреть файл

@ -1,6 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
toolkit.jar:
* content/global/platformHTMLBindings.xml (platformHTMLBindings.xml)

Просмотреть файл

@ -4,4 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
SOURCES += ['ShortcutKeyDefinitions.cpp']
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,164 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<bindings id="htmlBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="inputFields" bindToUntrustedContent="true">
<handlers>
#include ../input-fields-base.inc
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_moveLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_moveRight2"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectRight2"/>
<handler event="keypress" keycode="VK_UP" modifiers="control" command="cmd_moveUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="control" command="cmd_moveDown2"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,control" command="cmd_selectUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,control" command="cmd_selectDown2"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_deleteWordForward"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift" command="cmd_paste"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_undo"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt,shift" command="cmd_redo"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control" command="cmd_deleteWordBackward"/>
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
</handlers>
</binding>
<binding id="textAreas" bindToUntrustedContent="true">
<handlers>
#include ../textareas-base.inc
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine"/>
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_moveLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_moveRight2"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,control" command="cmd_selectLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,control" command="cmd_selectRight2"/>
<handler event="keypress" keycode="VK_UP" modifiers="control" command="cmd_moveUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="control" command="cmd_moveDown2"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,control" command="cmd_selectUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,control" command="cmd_selectDown2"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_deleteWordForward"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift" command="cmd_paste"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_undo"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt,shift" command="cmd_redo"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control" command="cmd_deleteWordBackward"/>
<handler event="keypress" key="a" modifiers="accel" command="cmd_selectAll"/>
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
</handlers>
</binding>
<binding id="browser">
<handlers>
#include ../browser-base.inc
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cut"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_deleteWordForward"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control" command="cmd_moveLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control" command="cmd_moveRight2" />
<handler event="keypress" keycode="VK_LEFT" modifiers="control,shift" command="cmd_selectLeft2" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="control,shift" command="cmd_selectRight2" />
<handler event="keypress" keycode="VK_LEFT" modifiers="shift" command="cmd_selectLeft" />
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectRight" />
<handler event="keypress" keycode="VK_UP" modifiers="control" command="cmd_moveUp2" />
<handler event="keypress" keycode="VK_DOWN" modifiers="control" command="cmd_moveDown2" />
<handler event="keypress" keycode="VK_UP" modifiers="control,shift" command="cmd_selectUp2" />
<handler event="keypress" keycode="VK_DOWN" modifiers="control,shift" command="cmd_selectDown2" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectUp" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectDown" />
<handler event="keypress" keycode="VK_HOME" modifiers="shift" command="cmd_selectBeginLine" />
<handler event="keypress" keycode="VK_END" modifiers="shift" command="cmd_selectEndLine" />
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
</handlers>
</binding>
<binding id="editor">
<handlers>
#include ../editor-base.inc
<handler event="keypress" key="a" command="cmd_selectAll" modifiers="accel"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="shift" command="cmd_cutOrDelete"/>
<handler event="keypress" keycode="VK_DELETE" modifiers="control" command="cmd_deleteWordForward"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_INSERT" modifiers="shift" command="cmd_paste"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt" command="cmd_undo"/>
<handler event="keypress" keycode="VK_BACK" modifiers="alt,shift" command="cmd_redo"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="accel" command="cmd_moveLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="accel" command="cmd_moveRight2"/>
<handler event="keypress" keycode="VK_LEFT" modifiers="shift,accel" command="cmd_selectLeft2"/>
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift,accel" command="cmd_selectRight2"/>
<handler event="keypress" keycode="VK_UP" modifiers="accel" command="cmd_moveUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="accel" command="cmd_moveDown2"/>
<handler event="keypress" keycode="VK_UP" modifiers="shift,accel" command="cmd_selectUp2"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="shift,accel" command="cmd_selectDown2"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop"/>
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_BACK" modifiers="control" command="cmd_deleteWordBackward"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_selectBeginLine" modifiers="shift"/>
<handler event="keypress" keycode="VK_END" command="cmd_selectEndLine" modifiers="shift"/>
<handler event="keypress" keycode="VK_PAGE_UP" command="cmd_movePageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" command="cmd_movePageDown"/>
<handler event="keypress" keycode="VK_PAGE_UP" modifiers="shift" command="cmd_selectPageUp"/>
<handler event="keypress" keycode="VK_PAGE_DOWN" modifiers="shift" command="cmd_selectPageDown"/>
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
</handlers>
</binding>
</bindings>

Просмотреть файл

@ -12,6 +12,7 @@ DIRS += ['builtin']
EXPORTS += [
'nsBindingManager.h',
'nsXBLBinding.h',
'nsXBLPrototypeHandler.h',
'nsXBLService.h',
'nsXBLWindowKeyHandler.h',
]

Просмотреть файл

@ -106,11 +106,11 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const char16_t* aEvent,
}
nsXBLPrototypeHandler::nsXBLPrototypeHandler(Element* aHandlerElement, XBLReservedKey aReserved)
: mHandlerElement(nullptr),
mLineNumber(0),
mReserved(aReserved),
mNextHandler(nullptr),
mPrototypeBinding(nullptr)
: mHandlerElement(nullptr)
, mLineNumber(0)
, mReserved(aReserved)
, mNextHandler(nullptr)
, mPrototypeBinding(nullptr)
{
Init();
@ -118,6 +118,21 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(Element* aHandlerElement, XBLReserv
ConstructPrototype(aHandlerElement);
}
nsXBLPrototypeHandler::nsXBLPrototypeHandler(ShortcutKeyData* aKeyData)
: mHandlerText(nullptr),
mLineNumber(0),
mReserved(XBLReservedKey_False),
mNextHandler(nullptr),
mPrototypeBinding(nullptr)
{
Init();
ConstructPrototype(nullptr, aKeyData->event, nullptr, nullptr,
aKeyData->command, aKeyData->keycode, aKeyData->key,
aKeyData->modifiers, nullptr, nullptr, nullptr, nullptr,
nullptr);
}
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding)
: mHandlerText(nullptr),
mLineNumber(0),

Просмотреть файл

@ -18,6 +18,7 @@
#include "nsIWeakReference.h"
#include "nsCycleCollectionParticipant.h"
#include "js/TypeDecls.h"
#include "mozilla/ShortcutKeys.h"
class nsIContent;
class nsIObjectInputStream;
@ -93,6 +94,10 @@ public:
// This constructor is used only by XUL key handlers (e.g., <key>)
explicit nsXBLPrototypeHandler(mozilla::dom::Element* aKeyElement, XBLReservedKey aReserved);
// This constructor is used for keyboard handlers for browser, editor, input
// and textarea elements.
explicit nsXBLPrototypeHandler(mozilla::ShortcutKeyData* aKeyData);
// This constructor is used for handlers loaded from the cache
explicit nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding);

Просмотреть файл

@ -34,119 +34,18 @@
#include "mozilla/dom/EventBinding.h"
#include "mozilla/dom/KeyboardEvent.h"
#include "mozilla/layers/KeyboardMap.h"
#include "mozilla/ShortcutKeys.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layers;
class nsXBLSpecialDocInfo : public nsIObserver
{
public:
RefPtr<nsXBLDocumentInfo> mHTMLBindings;
static const char sHTMLBindingStr[];
static const char sUserHTMLBindingStr[];
bool mInitialized;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
void LoadDocInfo();
void GetHandlers(const nsACString& aRef,
nsXBLPrototypeHandler** handler);
nsXBLSpecialDocInfo() : mInitialized(false) {}
protected:
virtual ~nsXBLSpecialDocInfo() {}
};
const char nsXBLSpecialDocInfo::sHTMLBindingStr[] =
"chrome://global/content/platformHTMLBindings.xml";
NS_IMPL_ISUPPORTS(nsXBLSpecialDocInfo, nsIObserver)
NS_IMETHODIMP
nsXBLSpecialDocInfo::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown"), "wrong topic");
// On shutdown, clear our fields to avoid an extra cycle collection.
mHTMLBindings = nullptr;
mInitialized = false;
nsContentUtils::UnregisterShutdownObserver(this);
return NS_OK;
}
void nsXBLSpecialDocInfo::LoadDocInfo()
{
if (mInitialized)
return;
mInitialized = true;
nsContentUtils::RegisterShutdownObserver(this);
nsXBLService* xblService = nsXBLService::GetInstance();
if (!xblService)
return;
// Obtain the platform doc info
nsCOMPtr<nsIURI> bindingURI;
NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr);
if (!bindingURI) {
return;
}
xblService->LoadBindingDocumentInfo(nullptr, nullptr,
bindingURI,
nullptr,
true,
getter_AddRefs(mHTMLBindings));
}
//
// GetHandlers
//
//
void
nsXBLSpecialDocInfo::GetHandlers(const nsACString& aRef,
nsXBLPrototypeHandler** aHandler)
{
if (mHTMLBindings) {
nsXBLPrototypeBinding* binding = mHTMLBindings->GetPrototypeBinding(aRef);
NS_ASSERTION(binding, "No binding found for the XBL window key handler.");
if (!binding)
return;
*aHandler = binding->GetPrototypeHandlers();
}
}
// Init statics
static StaticRefPtr<nsXBLSpecialDocInfo> sXBLSpecialDocInfo;
uint32_t nsXBLWindowKeyHandler::sRefCnt = 0;
/* static */ void
nsXBLWindowKeyHandler::EnsureSpecialDocInfo()
{
if (!sXBLSpecialDocInfo) {
sXBLSpecialDocInfo = new nsXBLSpecialDocInfo();
}
sXBLSpecialDocInfo->LoadDocInfo();
}
nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(Element* aElement,
EventTarget* aTarget)
: mTarget(aTarget),
mHandler(nullptr)
{
mWeakPtrForElement = do_GetWeakReference(aElement);
++sRefCnt;
}
nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
@ -154,11 +53,6 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
// If mWeakPtrForElement is non-null, we created a prototype handler.
if (mWeakPtrForElement)
delete mHandler;
--sRefCnt;
if (!sRefCnt) {
sXBLSpecialDocInfo = nullptr;
}
}
NS_IMPL_ISUPPORTS(nsXBLWindowKeyHandler,
@ -230,14 +124,12 @@ nsXBLWindowKeyHandler::EnsureHandlers()
BuildHandlerChain(el, &mHandler);
} else { // We are an XBL file of handlers.
EnsureSpecialDocInfo();
// Now determine which handlers we should be using.
if (IsHTMLEditableFieldFocused()) {
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("editor"), &mHandler);
mHandler = ShortcutKeys::GetHandlers(HandlerType::eEditor);
}
else {
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("browser"), &mHandler);
mHandler = ShortcutKeys::GetHandlers(HandlerType::eBrowser);
}
}
@ -245,7 +137,7 @@ nsXBLWindowKeyHandler::EnsureHandlers()
}
nsresult
nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType)
nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent)
{
if (aKeyEvent->DefaultPrevented()) {
return NS_OK;
@ -267,7 +159,7 @@ nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType
return NS_OK;
}
WalkHandlersInternal(aKeyEvent, aEventType, true);
WalkHandlersInternal(aKeyEvent, true);
return NS_OK;
}
@ -396,11 +288,7 @@ nsXBLWindowKeyHandler::RemoveKeyboardEventListenersFrom(
/* static */ KeyboardMap
nsXBLWindowKeyHandler::CollectKeyboardShortcuts()
{
// Load the XBL handlers
EnsureSpecialDocInfo();
nsXBLPrototypeHandler* handlers = nullptr;
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("browser"), &handlers);
nsXBLPrototypeHandler* handlers = ShortcutKeys::GetHandlers(HandlerType::eBrowser);
// Convert the handlers into keyboard shortcuts, using an AutoTArray with
// the maximum amount of shortcuts used on any platform to minimize allocations
@ -421,30 +309,6 @@ nsXBLWindowKeyHandler::CollectKeyboardShortcuts()
return KeyboardMap(std::move(shortcuts));
}
nsAtom*
nsXBLWindowKeyHandler::ConvertEventToDOMEventType(
const WidgetKeyboardEvent& aWidgetKeyboardEvent) const
{
if (aWidgetKeyboardEvent.IsKeyDownOrKeyDownOnPlugin()) {
return nsGkAtoms::keydown;
}
if (aWidgetKeyboardEvent.IsKeyUpOrKeyUpOnPlugin()) {
return nsGkAtoms::keyup;
}
// eAccessKeyNotFound event is always created from eKeyPress event and
// the original eKeyPress event has stopped its propagation before dispatched
// into the DOM tree in this process and not matched with remote content's
// access keys. So, we should treat it as an eKeyPress event and execute
// a command if it's registered as a shortcut key.
if (aWidgetKeyboardEvent.mMessage == eKeyPress ||
aWidgetKeyboardEvent.mMessage == eAccessKeyNotFound) {
return nsGkAtoms::keypress;
}
MOZ_ASSERT_UNREACHABLE(
"All event messages which this instance listens to should be handled");
return nullptr;
}
NS_IMETHODIMP
nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
{
@ -492,9 +356,7 @@ nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
return NS_OK;
}
RefPtr<nsAtom> eventTypeAtom =
ConvertEventToDOMEventType(*widgetKeyboardEvent);
return WalkHandlers(keyEvent, eventTypeAtom);
return WalkHandlers(keyEvent);
}
void
@ -602,7 +464,6 @@ nsXBLWindowKeyHandler::IsHTMLEditableFieldFocused()
//
bool
nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
nsAtom* aEventType,
bool aExecute,
bool* aOutReservedForChrome)
{
@ -614,8 +475,7 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys);
if (shortcutKeys.IsEmpty()) {
return WalkHandlersAndExecute(aKeyEvent, aEventType,
0, IgnoreModifierState(),
return WalkHandlersAndExecute(aKeyEvent, 0, IgnoreModifierState(),
aExecute, aOutReservedForChrome);
}
@ -623,8 +483,7 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
ShortcutKeyCandidate& key = shortcutKeys[i];
IgnoreModifierState ignoreModifierState;
ignoreModifierState.mShift = key.mIgnoreShift;
if (WalkHandlersAndExecute(aKeyEvent, aEventType,
key.mCharCode, ignoreModifierState,
if (WalkHandlersAndExecute(aKeyEvent, key.mCharCode, ignoreModifierState,
aExecute, aOutReservedForChrome)) {
return true;
}
@ -635,7 +494,6 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
bool
nsXBLWindowKeyHandler::WalkHandlersAndExecute(
KeyboardEvent* aKeyEvent,
nsAtom* aEventType,
uint32_t aCharCode,
const IgnoreModifierState& aIgnoreModifierState,
bool aExecute,
@ -651,6 +509,8 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
return false;
}
nsAtom* eventType = ShortcutKeys::ConvertEventToDOMEventType(widgetKeyboardEvent);
// Try all of the handlers until we find one that matches the event.
for (nsXBLPrototypeHandler* handler = mHandler;
handler;
@ -672,7 +532,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
}
// The other event types should exactly be matched with the handler's
// event type.
} else if (!handler->EventTypeEquals(aEventType)) {
} else if (!handler->EventTypeEquals(eventType)) {
continue;
}
} else {
@ -683,12 +543,12 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
// prevented, following keypress event won't be fired. However, if
// following keypress event is reserved, we shouldn't allow web
// contents to prevent the default of the preceding keydown event.
if (aEventType != nsGkAtoms::keydown &&
aEventType != nsGkAtoms::keypress) {
if (eventType != nsGkAtoms::keydown &&
eventType != nsGkAtoms::keypress) {
continue;
}
} else if (!handler->EventTypeEquals(aEventType)) {
// Otherwise, aEventType should exactly be matched.
} else if (!handler->EventTypeEquals(eventType)) {
// Otherwise, eventType should exactly be matched.
continue;
}
}
@ -713,7 +573,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
}
if (!aExecute) {
if (handler->EventTypeEquals(aEventType)) {
if (handler->EventTypeEquals(eventType)) {
if (aOutReservedForChrome) {
*aOutReservedForChrome = IsReservedKey(widgetKeyboardEvent, handler);
}
@ -724,7 +584,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
// If the command is reserved and the event is keydown, check also if
// the handler is for keypress because if following keypress event is
// reserved, we shouldn't dispatch the event into web contents.
if (aEventType == nsGkAtoms::keydown &&
if (eventType == nsGkAtoms::keydown &&
handler->EventTypeEquals(nsGkAtoms::keypress)) {
if (IsReservedKey(widgetKeyboardEvent, handler)) {
if (aOutReservedForChrome) {
@ -773,8 +633,8 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
if (!aIgnoreModifierState.mOS && widgetKeyboardEvent->IsOS()) {
IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
ignoreModifierState.mOS = true;
return WalkHandlersAndExecute(aKeyEvent, aEventType,
aCharCode, ignoreModifierState, aExecute);
return WalkHandlersAndExecute(aKeyEvent, aCharCode, ignoreModifierState,
aExecute);
}
#endif
@ -819,10 +679,7 @@ nsXBLWindowKeyHandler::HasHandlerForEvent(KeyboardEvent* aEvent,
return false;
}
RefPtr<nsAtom> eventTypeAtom =
ConvertEventToDOMEventType(*widgetKeyboardEvent);
return WalkHandlersInternal(aEvent, eventTypeAtom, false,
aOutReservedForChrome);
return WalkHandlersInternal(aEvent, false, aOutReservedForChrome);
}
already_AddRefed<Element>

Просмотреть файл

@ -50,17 +50,16 @@ public:
protected:
virtual ~nsXBLWindowKeyHandler();
nsresult WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType);
nsresult WalkHandlers(KeyboardEvent* aKeyEvent);
// walk the handlers, looking for one to handle the event
bool WalkHandlersInternal(KeyboardEvent* aKeyEvent,
nsAtom* aEventType,
bool aExecute,
bool* aOutReservedForChrome = nullptr);
// walk the handlers for aEvent, aCharCode and aIgnoreModifierState. Execute
// it if aExecute = true.
bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent, nsAtom* aEventType,
bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent,
uint32_t aCharCode,
const IgnoreModifierState& aIgnoreModifierState,
bool aExecute,
@ -82,15 +81,6 @@ protected:
bool IsReservedKey(mozilla::WidgetKeyboardEvent* aKeyEvent,
nsXBLPrototypeHandler* aHandler);
// Returns event type for matching between aWidgetKeyboardEvent and
// shortcut key handlers. This is used for calling WalkHandlers(),
// WalkHandlersInternal() and WalkHandlersAndExecute().
nsAtom* ConvertEventToDOMEventType(
const mozilla::WidgetKeyboardEvent& aWidgetKeyboardEvent) const;
// lazily load the special doc info for loading handlers
static void EnsureSpecialDocInfo();
// lazily load the handlers. Overridden to handle being attached
// to a particular element rather than the document
nsresult EnsureHandlers();
@ -126,12 +116,7 @@ protected:
nsWeakPtr mWeakPtrForElement;
mozilla::dom::EventTarget* mTarget; // weak ref
// these are not owning references; the prototype handlers are owned
// by the prototype bindings which are owned by the docinfo.
nsXBLPrototypeHandler* mHandler; // platform bindings
// holds reference count to document info about bindings
static uint32_t sRefCnt;
};
already_AddRefed<nsXBLWindowKeyHandler>

Просмотреть файл

@ -56,6 +56,26 @@ using namespace vm;
namespace {
// The GCC manual has this to say about labels as values:
// The &&foo expressions for the same label might have different values
// if the containing function is inlined or cloned. If a program relies
// on them being always the same, __attribute__((__noinline__,__noclone__))
// should be used to prevent inlining and cloning.
//
// is_return in Code.cpp relies on being able to do comparisons, so it needs
// them to be always the same.
//
// The GCC manual further adds:
// If &&foo is used in a static variable initializer, inlining and
// cloning is forbidden.
//
// In this file, &&foo *is* used in a static variable initializer, and it's not
// entirely clear whether this should prevent inlining of the function or not.
// In practice, though, clang 7 can end up inlining the function with ThinLTO,
// which breaks at least is_return. https://bugs.llvm.org/show_bug.cgi?id=39241
// So all in all, we need at least the __noinline__ attribute. __noclone__
// is not supported by clang.
__attribute__((__noinline__))
const void * direct_run(const bool get_table_mode,
const instr * program,
const byte * data,

Просмотреть файл

@ -8,7 +8,6 @@
#define __GFXMESSAGEUTILS_H__
#include "FilterSupport.h"
#include "FrameMetrics.h"
#include "ImageTypes.h"
#include "RegionBuilder.h"
#include "base/process_util.h"

Просмотреть файл

@ -38,6 +38,8 @@ namespace layers {
struct ScrollUpdateInfo {
uint32_t mScrollGeneration;
CSSPoint mScrollOffset;
CSSPoint mBaseScrollOffset;
bool mIsRelative;
};
/**
@ -62,10 +64,6 @@ public:
ePending, // The scroll offset was updated on the main thread, but not
// painted, so the layer texture data is still at the old
// offset.
eUserAction, // In an APZ repaint request, this means the APZ generated
// the scroll position based on user action (the alternative
// is eNone which means it's just request a repaint because
// it got a scroll update from the main thread).
eRestore // The scroll offset was updated by the main thread, but as
// a restore from history or after a frame reconstruction.
// In this case, APZ can ignore the offset change if the
@ -82,6 +80,7 @@ public:
, mCumulativeResolution()
, mDevPixelsPerCSSPixel(1)
, mScrollOffset(0, 0)
, mBaseScrollOffset(0, 0)
, mZoom()
, mScrollGeneration(0)
, mSmoothScrollOffset(0, 0)
@ -93,6 +92,7 @@ public:
, mPaintRequestTime()
, mScrollUpdateType(eNone)
, mIsRootContent(false)
, mIsRelative(false)
, mDoSmoothScroll(false)
, mUseDisplayPortMargins(false)
, mIsScrollInfoLayer(false)
@ -113,6 +113,7 @@ public:
mCumulativeResolution == aOther.mCumulativeResolution &&
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
mScrollOffset == aOther.mScrollOffset &&
mBaseScrollOffset == aOther.mBaseScrollOffset &&
// don't compare mZoom
mScrollGeneration == aOther.mScrollGeneration &&
mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
@ -124,6 +125,7 @@ public:
mPaintRequestTime == aOther.mPaintRequestTime &&
mScrollUpdateType == aOther.mScrollUpdateType &&
mIsRootContent == aOther.mIsRootContent &&
mIsRelative == aOther.mIsRelative &&
mDoSmoothScroll == aOther.mDoSmoothScroll &&
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
@ -251,29 +253,53 @@ public:
mZoom.yScale *= aScale.height;
}
void CopyScrollInfoFrom(const FrameMetrics& aOther)
/*
* Compares an APZ frame metrics with an incoming content frame metrics
* to see if APZ has a scroll offset that has not been incorporated into
* the content frame metrics.
*/
bool HasPendingScroll(const FrameMetrics& aContentFrameMetrics) const
{
return mScrollOffset != aContentFrameMetrics.mBaseScrollOffset;
}
void ApplyScrollUpdateFrom(const FrameMetrics& aOther)
{
mScrollOffset = aOther.mScrollOffset;
mScrollGeneration = aOther.mScrollGeneration;
}
void CopySmoothScrollInfoFrom(const FrameMetrics& aOther)
void ApplySmoothScrollUpdateFrom(const FrameMetrics& aOther)
{
mSmoothScrollOffset = aOther.mSmoothScrollOffset;
mScrollGeneration = aOther.mScrollGeneration;
mDoSmoothScroll = aOther.mDoSmoothScroll;
}
void ApplyRelativeScrollUpdateFrom(const FrameMetrics& aOther)
{
MOZ_ASSERT(aOther.IsRelative());
CSSPoint delta = (aOther.mScrollOffset - aOther.mBaseScrollOffset);
ClampAndSetScrollOffset(mScrollOffset + delta);
mScrollGeneration = aOther.mScrollGeneration;
}
void ApplyRelativeSmoothScrollUpdateFrom(const FrameMetrics& aOther)
{
MOZ_ASSERT(aOther.IsRelative());
CSSPoint delta = (aOther.mSmoothScrollOffset - aOther.mBaseScrollOffset);
ClampAndSetSmoothScrollOffset(mScrollOffset + delta);
mScrollGeneration = aOther.mScrollGeneration;
mDoSmoothScroll = aOther.mDoSmoothScroll;
}
void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo)
{
mScrollOffset = aInfo.mScrollOffset;
mBaseScrollOffset = aInfo.mBaseScrollOffset;
mScrollGeneration = aInfo.mScrollGeneration;
mScrollUpdateType = ePending;
}
void SetRepaintDrivenByUserAction(bool aUserAction)
{
mScrollUpdateType = aUserAction ? eUserAction : eNone;
mIsRelative = aInfo.mIsRelative;
}
public:
@ -352,6 +378,11 @@ public:
mScrollOffset = aScrollOffset;
}
void SetBaseScrollOffset(const CSSPoint& aScrollOffset)
{
mBaseScrollOffset = aScrollOffset;
}
// Set scroll offset, first clamping to the scroll range.
void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
{
@ -363,11 +394,21 @@ public:
return mScrollOffset;
}
const CSSPoint& GetBaseScrollOffset() const
{
return mBaseScrollOffset;
}
void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
{
mSmoothScrollOffset = aSmoothScrollDestination;
}
void ClampAndSetSmoothScrollOffset(const CSSPoint& aSmoothScrollOffset)
{
SetSmoothScrollOffset(CalculateScrollRange().ClampPoint(aSmoothScrollOffset));
}
const CSSPoint& GetSmoothScrollOffset() const
{
return mSmoothScrollOffset;
@ -383,16 +424,14 @@ public:
return mZoom;
}
void SetScrollOffsetUpdated(uint32_t aScrollGeneration)
void SetScrollGeneration(uint32_t aScrollGeneration)
{
mScrollUpdateType = eMainThread;
mScrollGeneration = aScrollGeneration;
}
void SetScrollOffsetRestored(uint32_t aScrollGeneration)
void SetScrollOffsetUpdateType(ScrollOffsetUpdateType aScrollUpdateType)
{
mScrollUpdateType = eRestore;
mScrollGeneration = aScrollGeneration;
mScrollUpdateType = aScrollUpdateType;
}
void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
@ -411,6 +450,16 @@ public:
return mScrollUpdateType != eNone;
}
void SetIsRelative(bool aIsRelative)
{
mIsRelative = aIsRelative;
}
bool IsRelative() const
{
return mIsRelative;
}
bool GetDoSmoothScroll() const
{
return mDoSmoothScroll;
@ -651,6 +700,10 @@ private:
// not any parents, regardless of parent transforms.
CSSPoint mScrollOffset;
// The base scroll offset to use for calculating a relative update to a
// scroll offset.
CSSPoint mBaseScrollOffset;
// The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
@ -698,6 +751,10 @@ private:
// Whether or not this is the root scroll frame for the root content document.
bool mIsRootContent:1;
// When mIsRelative, the scroll offset was updated using a relative API,
// such as `ScrollBy`, and can combined with an async scroll.
bool mIsRelative:1;
// When mDoSmoothScroll, the scroll offset should be animated to
// smoothly transition to mScrollOffset rather than be updated instantly.
bool mDoSmoothScroll:1;

357
gfx/layers/RepaintRequest.h Normal file
Просмотреть файл

@ -0,0 +1,357 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_REPAINTREQUEST_H
#define GFX_REPAINTREQUEST_H
#include <stdint.h> // for uint8_t, uint32_t, uint64_t
#include "FrameMetrics.h" // for FrameMetrics
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "Units.h" // for CSSRect, CSSPixel, etc
namespace IPC {
template <typename T> struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace layers {
struct RepaintRequest {
friend struct IPC::ParamTraits<mozilla::layers::RepaintRequest>;
public:
MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
ScrollOffsetUpdateType, uint8_t, (
eNone, // The default; the scroll offset was not updated.
eUserAction // The scroll offset was updated by APZ.
));
RepaintRequest()
: mScrollId(FrameMetrics::NULL_SCROLL_ID)
, mPresShellResolution(1)
, mCompositionBounds(0, 0, 0, 0)
, mCumulativeResolution()
, mDevPixelsPerCSSPixel(1)
, mScrollOffset(0, 0)
, mZoom()
, mScrollGeneration(0)
, mDisplayPortMargins(0, 0, 0, 0)
, mPresShellId(-1)
, mViewport(0, 0, 0, 0)
, mExtraResolution()
, mPaintRequestTime()
, mScrollUpdateType(eNone)
, mIsRootContent(false)
, mUseDisplayPortMargins(false)
, mIsScrollInfoLayer(false)
{
}
RepaintRequest(const FrameMetrics& aOther, const ScrollOffsetUpdateType aScrollUpdateType)
: mScrollId(aOther.GetScrollId())
, mPresShellResolution(aOther.GetPresShellResolution())
, mCompositionBounds(aOther.GetCompositionBounds())
, mCumulativeResolution(aOther.GetCumulativeResolution())
, mDevPixelsPerCSSPixel(aOther.GetDevPixelsPerCSSPixel())
, mScrollOffset(aOther.GetScrollOffset())
, mZoom(aOther.GetZoom())
, mScrollGeneration(aOther.GetScrollGeneration())
, mDisplayPortMargins(aOther.GetDisplayPortMargins())
, mPresShellId(aOther.GetPresShellId())
, mViewport(aOther.GetViewport())
, mExtraResolution(aOther.GetExtraResolution())
, mPaintRequestTime(aOther.GetPaintRequestTime())
, mScrollUpdateType(aScrollUpdateType)
, mIsRootContent(aOther.IsRootContent())
, mUseDisplayPortMargins(aOther.GetUseDisplayPortMargins())
, mIsScrollInfoLayer(aOther.IsScrollInfoLayer())
{
}
// Default copy ctor and operator= are fine
bool operator==(const RepaintRequest& aOther) const
{
// Put mScrollId at the top since it's the most likely one to fail.
return mScrollId == aOther.mScrollId &&
mPresShellResolution == aOther.mPresShellResolution &&
mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
mCumulativeResolution == aOther.mCumulativeResolution &&
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
mScrollOffset == aOther.mScrollOffset &&
// don't compare mZoom
mScrollGeneration == aOther.mScrollGeneration &&
mDisplayPortMargins == aOther.mDisplayPortMargins &&
mPresShellId == aOther.mPresShellId &&
mViewport.IsEqualEdges(aOther.mViewport) &&
mExtraResolution == aOther.mExtraResolution &&
mPaintRequestTime == aOther.mPaintRequestTime &&
mScrollUpdateType == aOther.mScrollUpdateType &&
mIsRootContent == aOther.mIsRootContent &&
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
}
bool operator!=(const RepaintRequest& aOther) const
{
return !operator==(aOther);
}
CSSToScreenScale2D DisplayportPixelsPerCSSPixel() const
{
// Note: use 'mZoom * ParentLayerToLayerScale(1.0f)' as the CSS-to-Layer scale
// instead of LayersPixelsPerCSSPixel(), because displayport calculations
// are done in the context of a repaint request, where we ask Layout to
// repaint at a new resolution that includes any async zoom. Until this
// repaint request is processed, LayersPixelsPerCSSPixel() does not yet
// include the async zoom, but it will when the displayport is interpreted
// for the repaint.
return mZoom * ParentLayerToLayerScale(1.0f) / mExtraResolution;
}
CSSToLayerScale2D LayersPixelsPerCSSPixel() const
{
return mDevPixelsPerCSSPixel * mCumulativeResolution;
}
// Get the amount by which this frame has been zoomed since the last repaint.
LayerToParentLayerScale GetAsyncZoom() const
{
// The async portion of the zoom should be the same along the x and y
// axes.
return (mZoom / LayersPixelsPerCSSPixel()).ToScaleFactor();
}
CSSSize CalculateCompositedSizeInCssPixels() const
{
if (GetZoom() == CSSToParentLayerScale2D(0, 0)) {
return CSSSize(); // avoid division by zero
}
return mCompositionBounds.Size() / GetZoom();
}
float GetPresShellResolution() const
{
return mPresShellResolution;
}
const ParentLayerRect& GetCompositionBounds() const
{
return mCompositionBounds;
}
const LayoutDeviceToLayerScale2D& GetCumulativeResolution() const
{
return mCumulativeResolution;
}
const CSSToLayoutDeviceScale& GetDevPixelsPerCSSPixel() const
{
return mDevPixelsPerCSSPixel;
}
bool IsRootContent() const
{
return mIsRootContent;
}
const CSSPoint& GetScrollOffset() const
{
return mScrollOffset;
}
const CSSToParentLayerScale2D& GetZoom() const
{
return mZoom;
}
ScrollOffsetUpdateType GetScrollUpdateType() const
{
return mScrollUpdateType;
}
bool GetScrollOffsetUpdated() const
{
return mScrollUpdateType != eNone;
}
uint32_t GetScrollGeneration() const
{
return mScrollGeneration;
}
FrameMetrics::ViewID GetScrollId() const
{
return mScrollId;
}
const ScreenMargin& GetDisplayPortMargins() const
{
return mDisplayPortMargins;
}
bool GetUseDisplayPortMargins() const
{
return mUseDisplayPortMargins;
}
uint32_t GetPresShellId() const
{
return mPresShellId;
}
const CSSRect& GetViewport() const
{
return mViewport;
}
const ScreenToLayerScale2D& GetExtraResolution() const
{
return mExtraResolution;
}
const TimeStamp& GetPaintRequestTime() const {
return mPaintRequestTime;
}
bool IsScrollInfoLayer() const {
return mIsScrollInfoLayer;
}
protected:
void SetIsRootContent(bool aIsRootContent)
{
mIsRootContent = aIsRootContent;
}
void SetUseDisplayPortMargins(bool aValue)
{
mUseDisplayPortMargins = aValue;
}
void SetIsScrollInfoLayer(bool aIsScrollInfoLayer)
{
mIsScrollInfoLayer = aIsScrollInfoLayer;
}
private:
// A unique ID assigned to each scrollable frame.
FrameMetrics::ViewID mScrollId;
// The pres-shell resolution that has been induced on the document containing
// this scroll frame as a result of zooming this scroll frame (whether via
// user action, or choosing an initial zoom level on page load). This can
// only be different from 1.0 for frames that are zoomable, which currently
// is just the root content document's root scroll frame (mIsRoot = true).
// This is a plain float rather than a ScaleFactor because in and of itself
// it does not convert between any coordinate spaces for which we have names.
float mPresShellResolution;
// This is the area within the widget that we're compositing to. It is in the
// same coordinate space as the reference frame for the scrolled frame.
//
// This is useful because, on mobile, the viewport and composition dimensions
// are not always the same. In this case, we calculate the displayport using
// an area bigger than the region we're compositing to. If we used the
// viewport dimensions to calculate the displayport, we'd run into situations
// where we're prerendering the wrong regions and the content may be clipped,
// or too much of it prerendered. If the composition dimensions are the same
// as the viewport dimensions, there is no need for this and we can just use
// the viewport instead.
//
// This value is valid for nested scrollable layers as well, and is still
// relative to the layer tree origin. This value is provided by Gecko at
// layout/paint time.
ParentLayerRect mCompositionBounds;
// The cumulative resolution that the current frame has been painted at.
// This is the product of the pres-shell resolutions of the document
// containing this scroll frame and its ancestors, and any css-driven
// resolution. This information is provided by Gecko at layout/paint time.
// Note that this is allowed to have different x- and y-scales, but only
// for subframes (mIsRoot = false). (The same applies to other scales that
// "inherit" the 2D-ness of this one, such as mZoom.)
LayoutDeviceToLayerScale2D mCumulativeResolution;
// The conversion factor between CSS pixels and device pixels for this frame.
// This can vary based on a variety of things, such as reflowing-zoom. The
// conversion factor for device pixels to layers pixels is just the
// resolution.
CSSToLayoutDeviceScale mDevPixelsPerCSSPixel;
// The position of the top-left of the CSS viewport, relative to the document
// (or the document relative to the viewport, if that helps understand it).
//
// Thus it is relative to the document. It is in the same coordinate space as
// |mScrollableRect|, but a different coordinate space than |mViewport| and
// |mDisplayPort|.
//
// It is required that the rect:
// { x = mScrollOffset.x, y = mScrollOffset.y,
// width = mCompositionBounds.x / mResolution.scale,
// height = mCompositionBounds.y / mResolution.scale }
// Be within |mScrollableRect|.
//
// This is valid for any layer, but is always relative to this frame and
// not any parents, regardless of parent transforms.
CSSPoint mScrollOffset;
// The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
// diverge. This information is initialized in Gecko but updated in the APZC.
CSSToParentLayerScale2D mZoom;
// The scroll generation counter used to acknowledge the scroll offset update.
uint32_t mScrollGeneration;
// A display port expressed as layer margins that apply to the rect of what
// is drawn of the scrollable element.
ScreenMargin mDisplayPortMargins;
uint32_t mPresShellId;
// The CSS viewport, which is the dimensions we're using to constrain the
// <html> element of this frame, relative to the top-left of the layer. Note
// that its offset is structured in such a way that it doesn't depend on the
// method layout uses to scroll content.
//
// This is mainly useful on the root layer, however nested iframes can have
// their own viewport, which will just be the size of the window of the
// iframe. For layers that don't correspond to a document, this metric is
// meaningless and invalid.
CSSRect mViewport;
// The extra resolution at which content in this scroll frame is drawn beyond
// that necessary to draw one Layer pixel per Screen pixel.
ScreenToLayerScale2D mExtraResolution;
// The time at which the APZC last requested a repaint for this scrollframe.
TimeStamp mPaintRequestTime;
// The type of repaint request this represents.
ScrollOffsetUpdateType mScrollUpdateType;
// Whether or not this is the root scroll frame for the root content document.
bool mIsRootContent:1;
// If this is true then we use the display port margins on this metrics,
// otherwise use the display port rect.
bool mUseDisplayPortMargins:1;
// Whether or not this frame has a "scroll info layer" to capture events.
bool mIsScrollInfoLayer:1;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_REPAINTREQUEST_H */

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/EventForwards.h" // for Modifiers
#include "mozilla/layers/RepaintRequest.h" // for RepaintRequest
#include "nsISupportsImpl.h"
namespace mozilla {
@ -27,7 +28,7 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
/**
* Requests a paint of the given FrameMetrics |aFrameMetrics| from Gecko.
* Requests a paint of the given RepaintRequest |aRequest| from Gecko.
* Implementations per-platform are responsible for actually handling this.
*
* This method must always be called on the repaint thread, which depends
@ -35,7 +36,7 @@ public:
* Gecko main thread, while for RemoteContentController it is the compositor
* thread where it can send IPDL messages.
*/
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) = 0;
virtual void RequestContentRepaint(const RepaintRequest& aRequest) = 0;
/**
* Different types of tap-related events that can be sent in

Просмотреть файл

@ -491,6 +491,11 @@ typedef PlatformSpecificStateBase PlatformSpecificState; // no extra state, jus
* A negative number prevents repaint requests during a scale.\n
* Units: ms
*
* \li\b apz.relative-update.enabled
* Whether to enable relative scroll offset updates or not. Relative scroll
* offset updates allow APZ and the main thread to concurrently update
* the scroll offset and merge the result.
*
*/
/**
@ -3382,11 +3387,6 @@ void AsyncPanZoomController::ScrollByAndClamp(const CSSPoint& aOffset) {
ClampAndSetScrollOffset(Metrics().GetScrollOffset() + aOffset);
}
void AsyncPanZoomController::CopyScrollInfoFrom(const FrameMetrics& aFrameMetrics) {
Metrics().CopyScrollInfoFrom(aFrameMetrics);
Metrics().RecalculateViewportOffset();
}
void AsyncPanZoomController::ScaleWithFocus(float aScale,
const CSSPoint& aFocus) {
Metrics().ZoomBy(aScale);
@ -3597,7 +3597,7 @@ int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
return listener ? listener->GetLastTouchIdentifier() : -1;
}
void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
void AsyncPanZoomController::RequestContentRepaint(RepaintUpdateType aUpdateType) {
// Reinvoke this method on the repaint thread if it's not there already. It's
// important to do this before the call to CalculatePendingDisplayPort, so
// that CalculatePendingDisplayPort uses the most recent available version of
@ -3608,13 +3608,13 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
}
if (!controller->IsRepaintThread()) {
// use the local variable to resolve the function overload.
auto func = static_cast<void (AsyncPanZoomController::*)(bool)>
auto func = static_cast<void (AsyncPanZoomController::*)(RepaintUpdateType)>
(&AsyncPanZoomController::RequestContentRepaint);
controller->DispatchToRepaintThread(NewRunnableMethod<bool>(
controller->DispatchToRepaintThread(NewRunnableMethod<RepaintUpdateType>(
"layers::AsyncPanZoomController::RequestContentRepaint",
this,
func,
aUserAction));
aUpdateType));
return;
}
@ -3625,8 +3625,7 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
Metrics().SetDisplayPortMargins(CalculatePendingDisplayPort(Metrics(), velocity));
Metrics().SetUseDisplayPortMargins(true);
Metrics().SetPaintRequestTime(TimeStamp::Now());
Metrics().SetRepaintDrivenByUserAction(aUserAction);
RequestContentRepaint(Metrics(), velocity);
RequestContentRepaint(Metrics(), velocity, aUpdateType);
}
/*static*/ CSSRect
@ -3642,7 +3641,8 @@ GetDisplayPortRect(const FrameMetrics& aFrameMetrics)
void
AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
const ParentLayerPoint& aVelocity)
const ParentLayerPoint& aVelocity,
RepaintUpdateType aUpdateType)
{
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
@ -3650,31 +3650,33 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
}
MOZ_ASSERT(controller->IsRepaintThread());
RepaintRequest request(aFrameMetrics, aUpdateType);
// If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint.
ScreenMargin marginDelta = (mLastPaintRequestMetrics.GetDisplayPortMargins()
- aFrameMetrics.GetDisplayPortMargins());
- request.GetDisplayPortMargins());
if (fabsf(marginDelta.left) < EPSILON &&
fabsf(marginDelta.top) < EPSILON &&
fabsf(marginDelta.right) < EPSILON &&
fabsf(marginDelta.bottom) < EPSILON &&
fabsf(mLastPaintRequestMetrics.GetScrollOffset().x -
aFrameMetrics.GetScrollOffset().x) < EPSILON &&
request.GetScrollOffset().x) < EPSILON &&
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
aFrameMetrics.GetScrollOffset().y) < EPSILON &&
aFrameMetrics.GetPresShellResolution() == mLastPaintRequestMetrics.GetPresShellResolution() &&
aFrameMetrics.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
fabsf(aFrameMetrics.GetViewport().Width() -
request.GetScrollOffset().y) < EPSILON &&
request.GetPresShellResolution() == mLastPaintRequestMetrics.GetPresShellResolution() &&
request.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
fabsf(request.GetViewport().Width() -
mLastPaintRequestMetrics.GetViewport().Width()) < EPSILON &&
fabsf(aFrameMetrics.GetViewport().Height() -
fabsf(request.GetViewport().Height() -
mLastPaintRequestMetrics.GetViewport().Height()) < EPSILON &&
fabsf(aFrameMetrics.GetViewport().X() -
fabsf(request.GetViewport().X() -
mLastPaintRequestMetrics.GetViewport().X()) < EPSILON &&
fabsf(aFrameMetrics.GetViewport().Y() -
fabsf(request.GetViewport().Y() -
mLastPaintRequestMetrics.GetViewport().Y()) < EPSILON &&
aFrameMetrics.GetScrollGeneration() ==
request.GetScrollGeneration() ==
mLastPaintRequestMetrics.GetScrollGeneration() &&
aFrameMetrics.GetScrollUpdateType() ==
request.GetScrollUpdateType() ==
mLastPaintRequestMetrics.GetScrollUpdateType()) {
return;
}
@ -3692,11 +3694,9 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
}
}
MOZ_ASSERT(aFrameMetrics.GetScrollUpdateType() == FrameMetrics::eNone ||
aFrameMetrics.GetScrollUpdateType() == FrameMetrics::eUserAction);
controller->RequestContentRepaint(aFrameMetrics);
controller->RequestContentRepaint(request);
mExpectedGeckoMetrics = aFrameMetrics;
mLastPaintRequestMetrics = aFrameMetrics;
mLastPaintRequestMetrics = request;
}
bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
@ -4260,6 +4260,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// ignore it
bool needContentRepaint = false;
bool userAction = false;
bool viewportUpdated = false;
// We usually don't entertain viewport updates on the same transaction as
@ -4376,10 +4377,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
mScrollMetadata.SetOverscrollBehavior(aScrollMetadata.GetOverscrollBehavior());
if (scrollOffsetUpdated) {
APZC_LOG("%p updating scroll offset from %s to %s\n", this,
ToString(Metrics().GetScrollOffset()).c_str(),
ToString(aLayerMetrics.GetScrollOffset()).c_str());
// Send an acknowledgement with the new scroll generation so that any
// repaint requests later in this function go through.
// Because of the scroll generation update, any inflight paint requests are
@ -4387,7 +4384,30 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// becomes incorrect for the purposes of calculating the LD transform. To
// correct this we need to update mExpectedGeckoMetrics to be the
// last thing we know was painted by Gecko.
CopyScrollInfoFrom(aLayerMetrics);
if (gfxPrefs::APZRelativeUpdate() && aLayerMetrics.IsRelative()) {
APZC_LOG("%p relative updating scroll offset from %s by %s\n", this,
ToString(Metrics().GetScrollOffset()).c_str(),
ToString(aLayerMetrics.GetScrollOffset() - aLayerMetrics.GetBaseScrollOffset()).c_str());
// It's possible that the main thread has ignored an APZ scroll offset
// update for the pending relative scroll that we have just received.
// When this happens, we need to send a new scroll offset update with
// the combined scroll offset or else the main thread may have an
// incorrect scroll offset for a period of time.
if (Metrics().HasPendingScroll(aLayerMetrics)) {
needContentRepaint = true;
userAction = true;
}
Metrics().ApplyRelativeScrollUpdateFrom(aLayerMetrics);
} else {
APZC_LOG("%p updating scroll offset from %s to %s\n", this,
ToString(Metrics().GetScrollOffset()).c_str(),
ToString(aLayerMetrics.GetScrollOffset()).c_str());
Metrics().ApplyScrollUpdateFrom(aLayerMetrics);
}
Metrics().RecalculateViewportOffset();
mCompositedLayoutViewport = Metrics().GetViewport();
mCompositedScrollOffset = Metrics().GetScrollOffset();
mExpectedGeckoMetrics = aLayerMetrics;
@ -4428,7 +4448,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// See comment on the similar code in the |if (scrollOffsetUpdated)| block
// above.
Metrics().CopySmoothScrollInfoFrom(aLayerMetrics);
if (gfxPrefs::APZRelativeUpdate() && aLayerMetrics.IsRelative()) {
Metrics().ApplyRelativeSmoothScrollUpdateFrom(aLayerMetrics);
} else {
Metrics().ApplySmoothScrollUpdateFrom(aLayerMetrics);
}
needContentRepaint = true;
mExpectedGeckoMetrics = aLayerMetrics;
@ -4447,7 +4471,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
if (needContentRepaint) {
// This repaint request is not driven by a user action on the APZ side
RequestContentRepaint(false);
RepaintUpdateType updateType = RepaintUpdateType::eNone;
if (userAction) {
updateType = RepaintUpdateType::eUserAction;
}
RequestContentRepaint(updateType);
}
UpdateSharedCompositorFrameMetrics();
}
@ -4624,25 +4652,25 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
CalculatePendingDisplayPort(endZoomToMetrics, velocity));
endZoomToMetrics.SetUseDisplayPortMargins(true);
endZoomToMetrics.SetPaintRequestTime(TimeStamp::Now());
endZoomToMetrics.SetRepaintDrivenByUserAction(true);
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (!controller) {
return;
}
if (controller->IsRepaintThread()) {
RequestContentRepaint(endZoomToMetrics, velocity);
RequestContentRepaint(endZoomToMetrics, velocity, RepaintUpdateType::eUserAction);
} else {
// use a local var to resolve the function overload
auto func = static_cast<void (AsyncPanZoomController::*)(const FrameMetrics&, const ParentLayerPoint&)>
auto func = static_cast<void (AsyncPanZoomController::*)(const FrameMetrics&, const ParentLayerPoint&, RepaintUpdateType)>
(&AsyncPanZoomController::RequestContentRepaint);
controller->DispatchToRepaintThread(
NewRunnableMethod<FrameMetrics, ParentLayerPoint>(
NewRunnableMethod<FrameMetrics, ParentLayerPoint, RepaintUpdateType>(
"layers::AsyncPanZoomController::ZoomToRect",
this,
func,
endZoomToMetrics,
velocity));
velocity,
RepaintUpdateType::eUserAction));
}
}
}

Просмотреть файл

@ -9,6 +9,7 @@
#include "CrossProcessMutex.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/RepaintRequest.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/Monitor.h"
@ -150,6 +151,8 @@ class AsyncPanZoomController {
typedef mozilla::MonitorAutoLock MonitorAutoLock;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::layers::RepaintRequest::ScrollOffsetUpdateType
RepaintUpdateType;
public:
enum GestureBehavior {
@ -706,11 +709,6 @@ protected:
*/
void ScrollByAndClamp(const CSSPoint& aOffset);
/**
* Copy the scroll offset and scroll generation from |aFrameMetrics|.
*/
void CopyScrollInfoFrom(const FrameMetrics& aFrameMetrics);
/**
* Scales the viewport by an amount (note that it multiplies this scale in to
* the current scale, it doesn't set it to |aScale|). Also considers a focus
@ -808,7 +806,8 @@ protected:
* from a non-main thread, it will redispatch itself to the main thread, and
* use the latest metrics during the redispatch.
*/
void RequestContentRepaint(bool aUserAction = true);
void RequestContentRepaint(RepaintUpdateType aUpdateType =
RepaintUpdateType::eUserAction);
/**
* Send the provided metrics to Gecko to trigger a repaint. This function
@ -816,7 +815,8 @@ protected:
* called on the main thread.
*/
void RequestContentRepaint(const FrameMetrics& aFrameMetrics,
const ParentLayerPoint& aVelocity);
const ParentLayerPoint& aVelocity,
RepaintUpdateType aUpdateType);
/**
* Gets the current frame metrics. This is *not* the Gecko copy stored in the
@ -933,8 +933,8 @@ private:
// sending messages back to Gecko.
ScrollMetadata mLastContentPaintMetadata;
FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to mLastContentPaintMetadata.mMetrics
// The last metrics used for a content repaint request.
FrameMetrics mLastPaintRequestMetrics;
// The last content repaint request.
RepaintRequest mLastPaintRequestMetrics;
// The metrics that we expect content to have. This is updated when we
// request a content repaint, and when we receive a shadow layers update.
// This allows us to transform events into Gecko's coordinate space.

Просмотреть файл

@ -101,7 +101,7 @@ static TimeStamp GetStartupTime() {
class MockContentController : public GeckoContentController {
public:
MOCK_METHOD1(RequestContentRepaint, void(const FrameMetrics&));
MOCK_METHOD1(RequestContentRepaint, void(const RepaintRequest&));
MOCK_METHOD2(RequestFlingSnap, void(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination));
MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
MOCK_METHOD5(HandleTap, void(TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t));

Просмотреть файл

@ -36,6 +36,8 @@
[test_group_keyboard.html]
[test_layerization.html]
skip-if = (os == 'android') # wheel events not supported on mobile
[test_relative_update.html]
skip-if = (os == 'android') # wheel events not supported on mobile
[test_scroll_inactive_bug1190112.html]
skip-if = (os == 'android') # wheel events not supported on mobile
[test_scroll_inactive_flattened_frame.html]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше