зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
9fbc76ace6
|
@ -24,6 +24,8 @@ run-if = debug || devedition || nightly_build # Requires startupRecorder.js, whi
|
||||||
[browser_tabclose_grow.js]
|
[browser_tabclose_grow.js]
|
||||||
[browser_tabclose.js]
|
[browser_tabclose.js]
|
||||||
skip-if = (os == 'win' && bits == 32) # Bug 1488537
|
skip-if = (os == 'win' && bits == 32) # Bug 1488537
|
||||||
|
[browser_tabdetach.js]
|
||||||
|
skip-if = debug # Bug 1501789
|
||||||
[browser_tabopen.js]
|
[browser_tabopen.js]
|
||||||
skip-if = (verify && (os == 'mac'))
|
skip-if = (verify && (os == 'mac'))
|
||||||
[browser_tabopen_squeeze.js]
|
[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()};
|
actualStacks: new Map()};
|
||||||
});
|
});
|
||||||
let unexpectedReflows = 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) {
|
for (let stack of reflows) {
|
||||||
let path =
|
let path =
|
||||||
stack.split("\n").slice(1) // the first frame which is our test code.
|
stack.split("\n").slice(1) // the first frame which is our test code.
|
||||||
|
@ -142,9 +149,10 @@ function reportUnexpectedReflows(reflows, expectedReflows = []) {
|
||||||
continue;
|
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.
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,3 +139,9 @@ VIAddVersionKey "ProductVersion" "${AppVersion}"
|
||||||
!define PROGRESS_BAR_TOP_DU 112u
|
!define PROGRESS_BAR_TOP_DU 112u
|
||||||
!define APPNAME_BMP_EDGE_DU 19u
|
!define APPNAME_BMP_EDGE_DU 19u
|
||||||
!define APPNAME_BMP_TOP_DU 12u
|
!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
|
# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in
|
||||||
# ApplicationID http://nsis.sourceforge.net/ApplicationID_plug-in
|
# ApplicationID http://nsis.sourceforge.net/ApplicationID_plug-in
|
||||||
# CityHash http://dxr.mozilla.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash
|
# 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
|
# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in
|
||||||
# UAC http://nsis.sourceforge.net/UAC_plug-in
|
# UAC http://nsis.sourceforge.net/UAC_plug-in
|
||||||
# ServicesHelper Mozilla specific plugin that is located in /other-licenses/nsis
|
# ServicesHelper Mozilla specific plugin that is located in /other-licenses/nsis
|
||||||
|
@ -39,6 +40,18 @@ Var ExtensionRecommender
|
||||||
Var PageName
|
Var PageName
|
||||||
Var PreventRebootRequired
|
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
|
; 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
|
; an application's Start Menu PROGRAMS directory and doesn't define the
|
||||||
; StartMenuDir variable can use the common InstallOnInitCommon macro.
|
; StartMenuDir variable can use the common InstallOnInitCommon macro.
|
||||||
|
@ -84,6 +97,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
|
||||||
!insertmacro CleanUpdateDirectories
|
!insertmacro CleanUpdateDirectories
|
||||||
!insertmacro CopyFilesFromDir
|
!insertmacro CopyFilesFromDir
|
||||||
!insertmacro CreateRegKey
|
!insertmacro CreateRegKey
|
||||||
|
!insertmacro GetFirstInstallPath
|
||||||
!insertmacro GetLongPath
|
!insertmacro GetLongPath
|
||||||
!insertmacro GetPathFromString
|
!insertmacro GetPathFromString
|
||||||
!insertmacro GetParent
|
!insertmacro GetParent
|
||||||
|
@ -188,6 +202,7 @@ Page custom preSummary leaveSummary
|
||||||
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
|
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
|
||||||
!define MUI_FINISHPAGE_RUN_TEXT $(LAUNCH_TEXT)
|
!define MUI_FINISHPAGE_RUN_TEXT $(LAUNCH_TEXT)
|
||||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish
|
!define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish
|
||||||
|
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE postFinish
|
||||||
!insertmacro MUI_PAGE_FINISH
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
|
||||||
; Use the default dialog for IDD_VERIFY for a simple Banner
|
; 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.
|
; Cleanup operations to perform at the start of the installation.
|
||||||
Section "-InstallStartCleanup"
|
Section "-InstallStartCleanup"
|
||||||
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
|
Pop $InstallPhaseStart
|
||||||
|
|
||||||
SetDetailsPrint both
|
SetDetailsPrint both
|
||||||
DetailPrint $(STATUS_CLEANUP)
|
DetailPrint $(STATUS_CLEANUP)
|
||||||
SetDetailsPrint none
|
SetDetailsPrint none
|
||||||
|
@ -663,7 +681,7 @@ Section "-InstallEndCleanup"
|
||||||
ClearErrors
|
ClearErrors
|
||||||
${MUI_INSTALLOPTIONS_READ} $0 "summary.ini" "Field 4" "State"
|
${MUI_INSTALLOPTIONS_READ} $0 "summary.ini" "Field 4" "State"
|
||||||
${If} "$0" == "1"
|
${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
|
; 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
|
; value was before we changed it. To do so, we read it here and store it
|
||||||
; in our own registry key.
|
; in our own registry key.
|
||||||
|
@ -698,6 +716,7 @@ Section "-InstallEndCleanup"
|
||||||
UAC::ExecCodeSegment $0
|
UAC::ExecCodeSegment $0
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${ElseIfNot} ${Errors}
|
${ElseIfNot} ${Errors}
|
||||||
|
StrCpy $SetAsDefault false
|
||||||
${LogHeader} "Writing default-browser opt-out"
|
${LogHeader} "Writing default-browser opt-out"
|
||||||
ClearErrors
|
ClearErrors
|
||||||
WriteRegStr HKCU "Software\Mozilla\Firefox" "DefaultBrowserOptOut" "True"
|
WriteRegStr HKCU "Software\Mozilla\Firefox" "DefaultBrowserOptOut" "True"
|
||||||
|
@ -756,6 +775,14 @@ Section "-InstallEndCleanup"
|
||||||
${EndUnless}
|
${EndUnless}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${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
|
SectionEnd
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
@ -904,6 +931,8 @@ Function LaunchApp
|
||||||
GetFunctionAddress $0 LaunchAppFromElevatedProcess
|
GetFunctionAddress $0 LaunchAppFromElevatedProcess
|
||||||
UAC::ExecCodeSegment $0
|
UAC::ExecCodeSegment $0
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
|
StrCpy $LaunchedNewApp true
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
Function LaunchAppFromElevatedProcess
|
Function LaunchAppFromElevatedProcess
|
||||||
|
@ -913,6 +942,170 @@ Function LaunchAppFromElevatedProcess
|
||||||
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\""
|
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\""
|
||||||
FunctionEnd
|
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
|
# Language
|
||||||
|
|
||||||
|
@ -939,9 +1132,15 @@ Function preWelcome
|
||||||
Delete "$PLUGINSDIR\modern-wizard.bmp"
|
Delete "$PLUGINSDIR\modern-wizard.bmp"
|
||||||
CopyFiles /SILENT "$EXEDIR\core\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp"
|
CopyFiles /SILENT "$EXEDIR\core\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp"
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
|
Pop $IntroPhaseStart
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
Function preOptions
|
Function preOptions
|
||||||
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
|
Pop $OptionsPhaseStart
|
||||||
|
|
||||||
StrCpy $PageName "Options"
|
StrCpy $PageName "Options"
|
||||||
${If} ${FileExists} "$EXEDIR\core\distribution\modern-header.bmp"
|
${If} ${FileExists} "$EXEDIR\core\distribution\modern-header.bmp"
|
||||||
${AndIf} $hHeaderBitmap == ""
|
${AndIf} $hHeaderBitmap == ""
|
||||||
|
@ -975,6 +1174,8 @@ FunctionEnd
|
||||||
Function preDirectory
|
Function preDirectory
|
||||||
StrCpy $PageName "Directory"
|
StrCpy $PageName "Directory"
|
||||||
${PreDirectoryCommon}
|
${PreDirectoryCommon}
|
||||||
|
|
||||||
|
StrCpy $DefaultInstDir $INSTDIR
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
Function leaveDirectory
|
Function leaveDirectory
|
||||||
|
@ -1288,11 +1489,19 @@ FunctionEnd
|
||||||
; When we add an optional action to the finish page the cancel button is
|
; 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.
|
; enabled. This disables it and leaves the finish button as the only choice.
|
||||||
Function preFinish
|
Function preFinish
|
||||||
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
|
Pop $FinishPhaseStart
|
||||||
|
|
||||||
StrCpy $PageName ""
|
StrCpy $PageName ""
|
||||||
${EndInstallLog} "${BrandFullName}"
|
${EndInstallLog} "${BrandFullName}"
|
||||||
!insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0"
|
!insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0"
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
Function postFinish
|
||||||
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
|
Pop $FinishPhaseEnd
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Initialization Functions
|
# Initialization Functions
|
||||||
|
|
||||||
|
@ -1301,6 +1510,18 @@ Function .onInit
|
||||||
; This only effects LoadLibrary calls and not implicitly loaded DLLs.
|
; This only effects LoadLibrary calls and not implicitly loaded DLLs.
|
||||||
System::Call 'kernel32::SetDllDirectoryW(w "")'
|
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 $PageName ""
|
||||||
StrCpy $LANGUAGE 0
|
StrCpy $LANGUAGE 0
|
||||||
${SetBrandNameVars} "$EXEDIR\core\distribution\setup.ini"
|
${SetBrandNameVars} "$EXEDIR\core\distribution\setup.ini"
|
||||||
|
@ -1338,6 +1559,20 @@ Function .onInit
|
||||||
SetRegView 64
|
SetRegView 64
|
||||||
!endif
|
!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)"
|
${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
|
||||||
|
|
||||||
!insertmacro InitInstallOptionsFile "options.ini"
|
!insertmacro InitInstallOptionsFile "options.ini"
|
||||||
|
@ -1527,4 +1762,5 @@ FunctionEnd
|
||||||
|
|
||||||
Function .onGUIEnd
|
Function .onGUIEnd
|
||||||
${OnEndCommon}
|
${OnEndCommon}
|
||||||
|
Call SendPing
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
|
@ -1218,7 +1218,7 @@ Function LaunchFullInstaller
|
||||||
System::Call "kernel32::GetTickCount()l .s"
|
System::Call "kernel32::GetTickCount()l .s"
|
||||||
Pop $EndPreInstallPhaseTickCount
|
Pop $EndPreInstallPhaseTickCount
|
||||||
|
|
||||||
Exec "$\"$PLUGINSDIR\download.exe$\" /INI=$PLUGINSDIR\${CONFIG_INI}"
|
Exec "$\"$PLUGINSDIR\download.exe$\" /LaunchedFromStub /INI=$PLUGINSDIR\${CONFIG_INI}"
|
||||||
${NSD_CreateTimer} CheckInstall ${InstallIntervalMS}
|
${NSD_CreateTimer} CheckInstall ${InstallIntervalMS}
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,8 @@ def build_one_stage(cc, cxx, asm, ld, ar, ranlib, libtool,
|
||||||
"-DCMAKE_SYSTEM_NAME=Darwin",
|
"-DCMAKE_SYSTEM_NAME=Darwin",
|
||||||
"-DCMAKE_SYSTEM_VERSION=10.10",
|
"-DCMAKE_SYSTEM_VERSION=10.10",
|
||||||
"-DLLVM_ENABLE_THREADS=OFF",
|
"-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,
|
"-DLIBCXXABI_LIBCXX_INCLUDES=%s" % libcxx_include_dir,
|
||||||
"-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
|
"-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
|
||||||
"-DCMAKE_FIND_ROOT_PATH=%s" % slashify_path(os.getenv("CROSS_CCTOOLS_PATH")), # noqa
|
"-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",
|
"stages": "1",
|
||||||
"build_libcxx": true,
|
"build_libcxx": true,
|
||||||
"build_type": "Release",
|
"build_type": "Release",
|
||||||
"assertions": false,
|
"assertions": false,
|
||||||
"osx_cross_compile": true,
|
"osx_cross_compile": true,
|
||||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/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_601/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_601/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_601/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_601/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_601/final",
|
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
|
||||||
"python_path": "/usr/bin/python2.7",
|
"python_path": "/usr/bin/python2.7",
|
||||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||||
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||||
|
@ -23,9 +23,6 @@
|
||||||
"patches": [
|
"patches": [
|
||||||
"static-llvm-symbolizer.patch",
|
"static-llvm-symbolizer.patch",
|
||||||
"compiler-rt-cross-compile.patch",
|
"compiler-rt-cross-compile.patch",
|
||||||
"compiler-rt-no-codesign.patch",
|
"compiler-rt-no-codesign.patch"
|
||||||
"r322401.patch",
|
|
||||||
"r325356.patch",
|
|
||||||
"r339636.patch"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -2,9 +2,9 @@ Disable codesign for macosx cross-compile toolchain. Codesign only works on OSX.
|
||||||
|
|
||||||
Index: cmake/Modules/AddCompilerRT.cmake
|
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)
|
+++ 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_PREFIX "")
|
||||||
set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
|
set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
|
||||||
endif()
|
endif()
|
||||||
|
@ -18,4 +18,4 @@ Index: cmake/Modules/AddCompilerRT.cmake
|
||||||
- endif()
|
- endif()
|
||||||
endif()
|
endif()
|
||||||
install(TARGETS ${libname}
|
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();
|
nsIScrollableFrame *sf = GetScrollFrame();
|
||||||
if (sf) {
|
if (sf) {
|
||||||
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
|
ScrollToOptions options;
|
||||||
scrollPos += CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScrollDif),
|
options.mLeft.Construct(aXScrollDif);
|
||||||
mozilla::ToZeroIfNonfinite(aYScrollDif));
|
options.mTop.Construct(aYScrollDif);
|
||||||
Scroll(scrollPos, ScrollOptions());
|
ScrollBy(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,14 +900,25 @@ Element::ScrollBy(const ScrollToOptions& aOptions)
|
||||||
{
|
{
|
||||||
nsIScrollableFrame *sf = GetScrollFrame();
|
nsIScrollableFrame *sf = GetScrollFrame();
|
||||||
if (sf) {
|
if (sf) {
|
||||||
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
|
CSSIntPoint scrollDelta;
|
||||||
if (aOptions.mLeft.WasPassed()) {
|
if (aOptions.mLeft.WasPassed()) {
|
||||||
scrollPos.x += mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
|
scrollDelta.x = mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
|
||||||
}
|
}
|
||||||
if (aOptions.mTop.WasPassed()) {
|
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();
|
nsIScrollableFrame *sf = GetScrollFrame();
|
||||||
|
|
||||||
if (sf) {
|
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
|
// It seems like it would make more sense for ScrollBy to use
|
||||||
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
// SMOOTH mode, but tests seem to depend on the synchronous behaviour.
|
||||||
// Perhaps Web content does too.
|
// 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();
|
nsIScrollableFrame *sf = GetScrollFrame();
|
||||||
|
|
||||||
if (sf) {
|
if (sf) {
|
||||||
CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
|
CSSIntPoint scrollDelta;
|
||||||
if (aOptions.mLeft.WasPassed()) {
|
if (aOptions.mLeft.WasPassed()) {
|
||||||
scrollPos.x += mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
|
scrollDelta.x = mozilla::ToZeroIfNonfinite(aOptions.mLeft.Value());
|
||||||
}
|
}
|
||||||
if (aOptions.mTop.WasPassed()) {
|
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;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
|
AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
|
||||||
|
|
|
@ -3104,7 +3104,6 @@ struct CreateGlobalOptions<nsGlobalWindowInner>
|
||||||
{
|
{
|
||||||
static constexpr ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind =
|
static constexpr ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind =
|
||||||
ProtoAndIfaceCache::WindowLike;
|
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
|
// The return value is true if we created and successfully performed our part of
|
||||||
|
|
|
@ -11,6 +11,8 @@ import math
|
||||||
import textwrap
|
import textwrap
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
from perfecthash import PerfectHash
|
||||||
|
|
||||||
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLInterfaceMember, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary
|
from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLInterfaceMember, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary
|
||||||
from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor, MemberIsUnforgeable, iteratorNativeType
|
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'
|
ENUM_ENTRY_VARIABLE_NAME = 'strings'
|
||||||
INSTANCE_RESERVED_SLOTS = 1
|
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):
|
def memberReservedSlot(member, descriptor):
|
||||||
return ("(DOM_INSTANCE_RESERVED_SLOTS + %d)" %
|
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)
|
names.extend((n.identifier.name, desc) for n in desc.interface.namedConstructors)
|
||||||
return names
|
return names
|
||||||
|
|
||||||
class CGGlobalNamesString(CGGeneric):
|
class CGGlobalNames(CGGeneric):
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
globalNames = getGlobalNames(config)
|
|
||||||
currentOffset = 0
|
currentOffset = 0
|
||||||
strings = []
|
strings = []
|
||||||
for (name, _) in globalNames:
|
entries = []
|
||||||
strings.append('/* %i */ "%s\\0"' % (currentOffset, name))
|
for name, desc in getGlobalNames(config):
|
||||||
currentOffset += len(name) + 1 # Add trailing null.
|
# 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("""
|
define = fill("""
|
||||||
const uint32_t WebIDLGlobalNameHash::sCount = ${count};
|
const uint32_t WebIDLGlobalNameHash::sCount = ${count};
|
||||||
|
|
||||||
const char WebIDLGlobalNameHash::sNames[] =
|
const char WebIDLGlobalNameHash::sNames[] =
|
||||||
$*{strings}
|
$*{strings}
|
||||||
|
|
||||||
|
$*{entries}
|
||||||
|
|
||||||
|
$*{getter}
|
||||||
|
|
||||||
""",
|
""",
|
||||||
count=len(globalNames),
|
count=len(phf.entries),
|
||||||
strings="\n".join(strings) + ";\n")
|
strings="\n".join(strings) + ";\n",
|
||||||
|
entries=entries,
|
||||||
|
getter=getter)
|
||||||
CGGeneric.__init__(self, define=define)
|
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):
|
def dependencySortObjects(objects, dependencyGetter, nameGetter):
|
||||||
"""
|
"""
|
||||||
Sort IDL objects with dependencies on each other such that if A
|
Sort IDL objects with dependencies on each other such that if A
|
||||||
|
@ -17119,11 +17161,7 @@ class GlobalGenRoots():
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def RegisterBindings(config):
|
def RegisterBindings(config):
|
||||||
|
|
||||||
curr = CGList([CGGlobalNamesString(config), CGRegisterGlobalNames(config)])
|
curr = CGNamespace.build(['mozilla', 'dom'], CGGlobalNames(config))
|
||||||
|
|
||||||
# Wrap all of that in our namespaces.
|
|
||||||
curr = CGNamespace.build(['mozilla', 'dom'],
|
|
||||||
CGWrapper(curr, post='\n'))
|
|
||||||
curr = CGWrapper(curr, post='\n')
|
curr = CGWrapper(curr, post='\n')
|
||||||
|
|
||||||
# Add the includes
|
# Add the includes
|
||||||
|
@ -17133,6 +17171,7 @@ class GlobalGenRoots():
|
||||||
register=True)]
|
register=True)]
|
||||||
defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h')
|
defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h')
|
||||||
defineIncludes.append('mozilla/dom/PrototypeList.h')
|
defineIncludes.append('mozilla/dom/PrototypeList.h')
|
||||||
|
defineIncludes.append('mozilla/PerfectHash.h')
|
||||||
defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)
|
defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)
|
||||||
for desc in config.getDescriptors(isNavigatorProperty=True,
|
for desc in config.getDescriptors(isNavigatorProperty=True,
|
||||||
register=True)])
|
register=True)])
|
||||||
|
|
|
@ -28,168 +28,6 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
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*
|
static JSObject*
|
||||||
FindNamedConstructorForXray(JSContext* aCx, JS::Handle<jsid> aId,
|
FindNamedConstructorForXray(JSContext* aCx, JS::Handle<jsid> aId,
|
||||||
const WebIDLNameTableEntry* aEntry)
|
const WebIDLNameTableEntry* aEntry)
|
||||||
|
@ -231,12 +69,7 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
|
||||||
|
|
||||||
const WebIDLNameTableEntry* entry;
|
const WebIDLNameTableEntry* entry;
|
||||||
{
|
{
|
||||||
WebIDLNameTableKey key(JSID_TO_FLAT_STRING(aId));
|
entry = GetEntry(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
@ -345,12 +178,7 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
|
||||||
bool
|
bool
|
||||||
WebIDLGlobalNameHash::MayResolve(jsid aId)
|
WebIDLGlobalNameHash::MayResolve(jsid aId)
|
||||||
{
|
{
|
||||||
WebIDLNameTableKey key(JSID_TO_FLAT_STRING(aId));
|
return GetEntry(JSID_TO_FLAT_STRING(aId)) != nullptr;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* 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.
|
// aObj is always a Window here, so GetProtoAndIfaceCache on it is safe.
|
||||||
ProtoAndIfaceCache* cache = GetProtoAndIfaceCache(aObj);
|
ProtoAndIfaceCache* cache = GetProtoAndIfaceCache(aObj);
|
||||||
for (auto iter = sWebIDLGlobalNames->Iter(); !iter.Done(); iter.Next()) {
|
for (size_t i = 0; i < sCount; ++i) {
|
||||||
const WebIDLNameTableEntry* entry = iter.Get();
|
const WebIDLNameTableEntry& entry = sEntries[i];
|
||||||
// If aNameType is not AllNames, only include things whose entry slot in the
|
// If aNameType is not AllNames, only include things whose entry slot in the
|
||||||
// ProtoAndIfaceCache is null.
|
// ProtoAndIfaceCache is null.
|
||||||
if ((aNameType == AllNames ||
|
if ((aNameType == AllNames ||
|
||||||
!cache->HasEntryInSlot(entry->mConstructorId)) &&
|
!cache->HasEntryInSlot(entry.mConstructorId)) &&
|
||||||
(!entry->mEnabled || entry->mEnabled(aCx, aObj))) {
|
(!entry.mEnabled || entry.mEnabled(aCx, aObj))) {
|
||||||
JSString* str = JS_AtomizeStringN(aCx, sNames + entry->mNameOffset,
|
JSString* str = JS_AtomizeStringN(aCx, sNames + entry.mNameOffset,
|
||||||
entry->mNameLength);
|
entry.mNameLength);
|
||||||
if (!str || !aNames.append(NON_INTEGER_ATOM_TO_JSID(str))) {
|
if (!str || !aNames.append(NON_INTEGER_ATOM_TO_JSID(str))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,38 +11,36 @@
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
|
|
||||||
|
class JSFlatString;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
struct WebIDLNameTableEntry;
|
|
||||||
|
|
||||||
namespace constructors {
|
namespace constructors {
|
||||||
namespace id {
|
namespace id {
|
||||||
enum ID : uint16_t;
|
enum ID : uint16_t;
|
||||||
} // namespace id
|
} // namespace id
|
||||||
} // namespace constructors
|
} // namespace constructors
|
||||||
|
|
||||||
class WebIDLGlobalNameHash
|
struct WebIDLNameTableEntry
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
static void Init();
|
|
||||||
static void Shutdown();
|
|
||||||
|
|
||||||
// Check whether a constructor should be enabled for the given object.
|
// 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
|
// Note that the object should NOT be an Xray, since Xrays will end up
|
||||||
// defining constructors on the underlying object.
|
// defining constructors on the underlying object.
|
||||||
// This is a typedef for the function type itself, not the function
|
typedef bool (*ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
|
||||||
// pointer, so it's more obvious that pointers to a ConstructorEnabled
|
|
||||||
// can be null.
|
|
||||||
typedef bool
|
|
||||||
(*ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
|
|
||||||
|
|
||||||
static void Register(uint16_t aNameOffset, uint16_t aNameLength,
|
uint16_t mNameOffset;
|
||||||
CreateInterfaceObjectsMethod aCreate,
|
uint16_t mNameLength;
|
||||||
ConstructorEnabled aEnabled,
|
constructors::id::ID mConstructorId;
|
||||||
constructors::id::ID aConstructorId);
|
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
|
// Returns false if something failed. aFound is set to true if the name is in
|
||||||
// the hash, whether it's enabled or not.
|
// the hash, whether it's enabled or not.
|
||||||
|
@ -69,12 +67,20 @@ public:
|
||||||
private:
|
private:
|
||||||
friend struct WebIDLNameTableEntry;
|
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.
|
// The value of sCount is generated by Codegen.py in RegisterBindings.cpp.
|
||||||
static const uint32_t sCount;
|
static const uint32_t sCount;
|
||||||
|
|
||||||
// The names that will be registered in the hash, concatenated as one big
|
// The name table entries in the hash.
|
||||||
// string with \0 as a separator between names.
|
// 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.
|
// The value of sNames is generated by Codegen.py in RegisterBindings.cpp.
|
||||||
static const char sNames[];
|
static const char sNames[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,10 @@ WebGL2Context::IsSampler(const WebGLSampler* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return gl->fIsSampler(obj->mGLName);
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -54,7 +54,10 @@ WebGL2Context::IsTransformFeedback(const WebGLTransformFeedback* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return gl->fIsTransformFeedback(obj->mGLName);
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return obj->mHasBeenBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -90,6 +93,7 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
|
||||||
|
|
||||||
if (mBoundTransformFeedback) {
|
if (mBoundTransformFeedback) {
|
||||||
mBoundTransformFeedback->AddBufferBindCounts(+1);
|
mBoundTransformFeedback->AddBufferBindCounts(+1);
|
||||||
|
mBoundTransformFeedback->mHasBeenBound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2501,7 +2501,10 @@ WebGLContext::ValidateIsObject(const WebGLDeletableObject* const object) const
|
||||||
if (!object->IsCompatibleWithContext(this))
|
if (!object->IsCompatibleWithContext(this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !object->IsDeleted();
|
if (object->IsDeleted())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -147,9 +147,7 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
|
||||||
} else {
|
} else {
|
||||||
GLuint framebuffername = wfb->mGLName;
|
GLuint framebuffername = wfb->mGLName;
|
||||||
gl->fBindFramebuffer(target, framebuffername);
|
gl->fBindFramebuffer(target, framebuffername);
|
||||||
#ifdef ANDROID
|
wfb->mHasBeenBound = true;
|
||||||
wfb->mIsFB = true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (target) {
|
switch (target) {
|
||||||
|
@ -1065,7 +1063,10 @@ WebGLContext::IsBuffer(const WebGLBuffer* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return gl->fIsBuffer(obj->mGLName);
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return obj->Content() != WebGLBuffer::Kind::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1075,15 +1076,10 @@ WebGLContext::IsFramebuffer(const WebGLFramebuffer* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef ANDROID
|
if (obj->IsDeleteRequested())
|
||||||
if (gl->WorkAroundDriverBugs() &&
|
return false;
|
||||||
gl->Renderer() == GLRenderer::AndroidEmulator)
|
|
||||||
{
|
|
||||||
return obj->mIsFB;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return gl->fIsFramebuffer(obj->mGLName);
|
return obj->mHasBeenBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1100,7 +1096,10 @@ WebGLContext::IsQuery(const WebGLQuery* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return obj->IsQuery();
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bool(obj->Target());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1110,6 +1109,9 @@ WebGLContext::IsRenderbuffer(const WebGLRenderbuffer* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
return obj->mHasBeenBound;
|
return obj->mHasBeenBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,7 +1129,10 @@ WebGLContext::IsTexture(const WebGLTexture* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return obj->IsTexture();
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return bool(obj->Target());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1137,7 +1142,10 @@ WebGLContext::IsVertexArray(const WebGLVertexArray* const obj)
|
||||||
if (!ValidateIsObject(obj))
|
if (!ValidateIsObject(obj))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return obj->IsVertexArray();
|
if (obj->IsDeleteRequested())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return obj->mHasBeenBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -
|
// -
|
||||||
|
|
|
@ -702,8 +702,8 @@ WebGLContext::AssertCachedBindings() const
|
||||||
GetAndFlushUnderlyingGLErrors();
|
GetAndFlushUnderlyingGLErrors();
|
||||||
|
|
||||||
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
|
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
|
||||||
GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0;
|
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING,
|
||||||
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
|
mBoundVertexArray->mGLName);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint stencilBits = 0;
|
GLint stencilBits = 0;
|
||||||
|
|
|
@ -621,10 +621,6 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDefaultVertexArray = WebGLVertexArray::Create(this);
|
|
||||||
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
|
|
||||||
mBoundVertexArray = mDefaultVertexArray;
|
|
||||||
|
|
||||||
// OpenGL core profiles remove the default VAO object from version
|
// OpenGL core profiles remove the default VAO object from version
|
||||||
// 4.0.0. We create a default VAO for all core profiles,
|
// 4.0.0. We create a default VAO for all core profiles,
|
||||||
// regardless of version.
|
// regardless of version.
|
||||||
|
@ -633,11 +629,9 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
||||||
// (https://www.opengl.org/registry/doc/glspec40.core.20100311.pdf)
|
// (https://www.opengl.org/registry/doc/glspec40.core.20100311.pdf)
|
||||||
// in Section E.2.2 "Removed Features", pg 397: "[...] The default
|
// in Section E.2.2 "Removed Features", pg 397: "[...] The default
|
||||||
// vertex array object (the name zero) is also deprecated. [...]"
|
// vertex array object (the name zero) is also deprecated. [...]"
|
||||||
|
mDefaultVertexArray = WebGLVertexArray::Create(this);
|
||||||
if (gl->IsCoreProfile()) {
|
mDefaultVertexArray->BindVertexArray();
|
||||||
mDefaultVertexArray->GenVertexArray();
|
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
|
||||||
mDefaultVertexArray->BindVertexArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
mPixelStore_FlipY = false;
|
mPixelStore_FlipY = false;
|
||||||
mPixelStore_PremultiplyAlpha = false;
|
mPixelStore_PremultiplyAlpha = false;
|
||||||
|
|
|
@ -35,6 +35,7 @@ WebGLContext::BindVertexArray(WebGLVertexArray* array)
|
||||||
MOZ_ASSERT(mBoundVertexArray == array);
|
MOZ_ASSERT(mBoundVertexArray == array);
|
||||||
if (mBoundVertexArray) {
|
if (mBoundVertexArray) {
|
||||||
mBoundVertexArray->AddBufferBindCounts(+1);
|
mBoundVertexArray->AddBufferBindCounts(+1);
|
||||||
|
mBoundVertexArray->mHasBeenBound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +47,6 @@ WebGLContext::CreateVertexArray()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
RefPtr<WebGLVertexArray> globj = CreateVertexArrayImpl();
|
RefPtr<WebGLVertexArray> globj = CreateVertexArrayImpl();
|
||||||
|
|
||||||
globj->GenVertexArray();
|
|
||||||
|
|
||||||
return globj.forget();
|
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
|
// We need to check immutable textures though, because checking completeness is
|
||||||
// also when we zero invalidated/no-data tex images.
|
// also when we zero invalidated/no-data tex images.
|
||||||
const bool complete = [&]() {
|
const bool complete = [&]() {
|
||||||
const auto texCompleteness = tex->CalcCompletenessInfo();
|
const bool ensureInit = false;
|
||||||
|
const auto texCompleteness = tex->CalcCompletenessInfo(ensureInit);
|
||||||
if (!texCompleteness) // OOM
|
if (!texCompleteness) // OOM
|
||||||
return false;
|
return false;
|
||||||
if (!texCompleteness->levels)
|
if (!texCompleteness->levels)
|
||||||
|
@ -508,10 +509,6 @@ WebGLFramebuffer::Delete()
|
||||||
mContext->gl->fDeleteFramebuffers(1, &mGLName);
|
mContext->gl->fDeleteFramebuffers(1, &mGLName);
|
||||||
|
|
||||||
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
|
LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
mIsFB = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
|
@ -1232,7 +1229,7 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum attachEnum,
|
||||||
if (!mContext->ValidateObject("texture", *tex))
|
if (!mContext->ValidateObject("texture", *tex))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!tex->HasEverBeenBound()) {
|
if (!tex->Target()) {
|
||||||
mContext->ErrorInvalidOperation("`texture` has never been bound.");
|
mContext->ErrorInvalidOperation("`texture` has never been bound.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1314,7 @@ WebGLFramebuffer::FramebufferTextureLayer(GLenum attachEnum,
|
||||||
if (!mContext->ValidateObject("texture", *tex))
|
if (!mContext->ValidateObject("texture", *tex))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!tex->HasEverBeenBound()) {
|
if (!tex->Target()) {
|
||||||
mContext->ErrorInvalidOperation("`texture` has never been bound.");
|
mContext->ErrorInvalidOperation("`texture` has never been bound.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,28 +140,18 @@ class WebGLFramebuffer final
|
||||||
, public SupportsWeakPtr<WebGLFramebuffer>
|
, public SupportsWeakPtr<WebGLFramebuffer>
|
||||||
, public CacheInvalidator
|
, public CacheInvalidator
|
||||||
{
|
{
|
||||||
friend class WebGLContext;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
|
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
|
||||||
|
|
||||||
const GLuint mGLName;
|
const GLuint mGLName;
|
||||||
|
bool mHasBeenBound = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable uint64_t mNumFBStatusInvals = 0;
|
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 mDepthAttachment;
|
||||||
WebGLFBAttachPoint mStencilAttachment;
|
WebGLFBAttachPoint mStencilAttachment;
|
||||||
WebGLFBAttachPoint mDepthStencilAttachment;
|
WebGLFBAttachPoint mDepthStencilAttachment;
|
||||||
|
|
|
@ -52,7 +52,6 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
|
||||||
, mPrimaryRB( DoCreateRenderbuffer(webgl->gl) )
|
, mPrimaryRB( DoCreateRenderbuffer(webgl->gl) )
|
||||||
, mEmulatePackedDepthStencil( EmulatePackedDepthStencil(webgl->gl) )
|
, mEmulatePackedDepthStencil( EmulatePackedDepthStencil(webgl->gl) )
|
||||||
, mSecondaryRB(0)
|
, mSecondaryRB(0)
|
||||||
, mHasBeenBound(false)
|
|
||||||
{
|
{
|
||||||
mContext->mRenderbuffers.insertBack(this);
|
mContext->mRenderbuffers.insertBack(this);
|
||||||
|
|
||||||
|
|
|
@ -26,16 +26,15 @@ class WebGLRenderbuffer final
|
||||||
, public WebGLRectangleObject
|
, public WebGLRectangleObject
|
||||||
, public CacheInvalidator
|
, public CacheInvalidator
|
||||||
{
|
{
|
||||||
friend class WebGLContext;
|
|
||||||
friend class WebGLFramebuffer;
|
friend class WebGLFramebuffer;
|
||||||
friend class WebGLFBAttachPoint;
|
friend class WebGLFBAttachPoint;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const GLuint mPrimaryRB;
|
const GLuint mPrimaryRB;
|
||||||
|
bool mHasBeenBound = false;
|
||||||
protected:
|
protected:
|
||||||
const bool mEmulatePackedDepthStencil;
|
const bool mEmulatePackedDepthStencil;
|
||||||
GLuint mSecondaryRB;
|
GLuint mSecondaryRB;
|
||||||
bool mHasBeenBound;
|
|
||||||
webgl::ImageInfo mImageInfo;
|
webgl::ImageInfo mImageInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WebGLSampler::WebGLSampler(WebGLContext* const webgl)
|
WebGLSampler::WebGLSampler(WebGLContext* const webgl)
|
||||||
: WebGLRefCountedObject(webgl)
|
: WebGLRefCountedObject(webgl)
|
||||||
, mGLName([&]() {
|
, mGLName([&]() {
|
||||||
|
|
|
@ -20,9 +20,6 @@ class WebGLSampler final
|
||||||
, public LinkedListElement<WebGLSampler>
|
, public LinkedListElement<WebGLSampler>
|
||||||
, public CacheInvalidator
|
, public CacheInvalidator
|
||||||
{
|
{
|
||||||
friend class WebGLContext2;
|
|
||||||
friend class WebGLTexture;
|
|
||||||
|
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,8 @@ public:
|
||||||
return get() >= other.get();
|
return get() >= other.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const { return bool(get()); }
|
||||||
|
|
||||||
static bool IsValueLegal(GLenum value) {
|
static bool IsValueLegal(GLenum value) {
|
||||||
if (value > UINT16_MAX) {
|
if (value > UINT16_MAX) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -155,7 +155,7 @@ ZeroTextureData(const WebGLContext* webgl, GLuint tex,
|
||||||
uint32_t depth);
|
uint32_t depth);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
|
WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel, const bool ensureInit,
|
||||||
bool* const out_initFailed) const
|
bool* const out_initFailed) const
|
||||||
{
|
{
|
||||||
*out_initFailed = false;
|
*out_initFailed = false;
|
||||||
|
@ -187,7 +187,7 @@ WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MOZ_UNLIKELY( !cur.mHasData )) {
|
if (MOZ_UNLIKELY( ensureInit && !cur.mHasData )) {
|
||||||
auto imageTarget = mTarget.get();
|
auto imageTarget = mTarget.get();
|
||||||
if (imageTarget == LOCAL_GL_TEXTURE_CUBE_MAP) {
|
if (imageTarget == LOCAL_GL_TEXTURE_CUBE_MAP) {
|
||||||
imageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
imageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
||||||
|
@ -213,7 +213,7 @@ WebGLTexture::IsMipAndCubeComplete(const uint32_t maxLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<const WebGLTexture::CompletenessInfo>
|
Maybe<const WebGLTexture::CompletenessInfo>
|
||||||
WebGLTexture::CalcCompletenessInfo() const
|
WebGLTexture::CalcCompletenessInfo(const bool ensureInit, const bool skipMips) const
|
||||||
{
|
{
|
||||||
Maybe<CompletenessInfo> ret = Some(CompletenessInfo());
|
Maybe<CompletenessInfo> ret = Some(CompletenessInfo());
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ WebGLTexture::CalcCompletenessInfo() const
|
||||||
|
|
||||||
// "* The texture is a cube map texture, and is not cube complete."
|
// "* The texture is a cube map texture, and is not cube complete."
|
||||||
bool initFailed = false;
|
bool initFailed = false;
|
||||||
if (!IsMipAndCubeComplete(mBaseMipmapLevel, &initFailed)) {
|
if (!IsMipAndCubeComplete(mBaseMipmapLevel, ensureInit, &initFailed)) {
|
||||||
if (initFailed)
|
if (initFailed)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -279,7 +279,10 @@ WebGLTexture::CalcCompletenessInfo() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsMipAndCubeComplete(maxLevel, &initFailed)) {
|
if (skipMips)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!IsMipAndCubeComplete(maxLevel, ensureInit, &initFailed)) {
|
||||||
if (initFailed)
|
if (initFailed)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -299,7 +302,8 @@ WebGLTexture::CalcSampleableInfo(const WebGLSampler* const sampler) const
|
||||||
{
|
{
|
||||||
Maybe<webgl::SampleableInfo> ret = Some(webgl::SampleableInfo());
|
Maybe<webgl::SampleableInfo> ret = Some(webgl::SampleableInfo());
|
||||||
|
|
||||||
const auto completeness = CalcCompletenessInfo();
|
const bool ensureInit = true;
|
||||||
|
const auto completeness = CalcCompletenessInfo(ensureInit);
|
||||||
if (!completeness)
|
if (!completeness)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -577,8 +581,9 @@ ZeroTextureData(const WebGLContext* webgl, GLuint tex,
|
||||||
// We have no sympathy for any of these cases.
|
// We have no sympathy for any of these cases.
|
||||||
|
|
||||||
// "Doctor, it hurts when I do this!" "Well don't do that!"
|
// "Doctor, it hurts when I do this!" "Well don't do that!"
|
||||||
webgl->GenerateWarning("This operation requires zeroing texture data. This is"
|
const auto targetStr = EnumString(target.get());
|
||||||
" slow.");
|
webgl->GeneratePerfWarning("Tex image %s level %u is incurring lazy initialization.",
|
||||||
|
targetStr.c_str(), level);
|
||||||
|
|
||||||
gl::GLContext* gl = webgl->GL();
|
gl::GLContext* gl = webgl->GL();
|
||||||
|
|
||||||
|
@ -698,7 +703,7 @@ WebGLTexture::BindTexture(TexTarget texTarget)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isFirstBinding = !HasEverBeenBound();
|
const bool isFirstBinding = !mTarget;
|
||||||
if (!isFirstBinding && mTarget != texTarget) {
|
if (!isFirstBinding && mTarget != texTarget) {
|
||||||
mContext->ErrorInvalidOperation("bindTexture: This texture has already been bound"
|
mContext->ErrorInvalidOperation("bindTexture: This texture has already been bound"
|
||||||
" to a different target.");
|
" to a different target.");
|
||||||
|
@ -737,7 +742,10 @@ WebGLTexture::GenerateMipmap()
|
||||||
// derived from the level base array, regardless of their previous contents. All
|
// 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
|
// other mipmap arrays, including the level base array, are left unchanged by this
|
||||||
// computation."
|
// 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) {
|
if (!completeness || !completeness->levels) {
|
||||||
mContext->ErrorInvalidOperation("The texture's base level must be complete.");
|
mContext->ErrorInvalidOperation("The texture's base level must be complete.");
|
||||||
return;
|
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.
|
// Here we have to support all pnames with both int and float params.
|
||||||
// See this discussion:
|
// See this discussion:
|
||||||
// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
|
// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
|
||||||
|
|
|
@ -145,7 +145,8 @@ protected:
|
||||||
mutable CacheWeakMap<const WebGLSampler*, webgl::SampleableInfo> mSamplingCache;
|
mutable CacheWeakMap<const WebGLSampler*, webgl::SampleableInfo> mSamplingCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Maybe<const CompletenessInfo> CalcCompletenessInfo() const;
|
Maybe<const CompletenessInfo> CalcCompletenessInfo(bool ensureInit,
|
||||||
|
bool skipMips = false) const;
|
||||||
Maybe<const webgl::SampleableInfo> CalcSampleableInfo(const WebGLSampler*) const;
|
Maybe<const webgl::SampleableInfo> CalcSampleableInfo(const WebGLSampler*) const;
|
||||||
|
|
||||||
const webgl::SampleableInfo* GetSampleableInfo(const WebGLSampler*) const;
|
const webgl::SampleableInfo* GetSampleableInfo(const WebGLSampler*) const;
|
||||||
|
@ -172,7 +173,6 @@ public:
|
||||||
|
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
|
|
||||||
TexTarget Target() const { return mTarget; }
|
TexTarget Target() const { return mTarget; }
|
||||||
|
|
||||||
WebGLContext* GetParentObject() const {
|
WebGLContext* GetParentObject() const {
|
||||||
|
@ -192,7 +192,6 @@ public:
|
||||||
bool BindTexture(TexTarget texTarget);
|
bool BindTexture(TexTarget texTarget);
|
||||||
void GenerateMipmap();
|
void GenerateMipmap();
|
||||||
JS::Value GetTexParameter(TexTarget texTarget, GLenum pname);
|
JS::Value GetTexParameter(TexTarget texTarget, GLenum pname);
|
||||||
bool IsTexture() const;
|
|
||||||
void TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& param);
|
void TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& param);
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
@ -310,7 +309,8 @@ public:
|
||||||
bool EnsureImageDataInitialized(TexImageTarget target,
|
bool EnsureImageDataInitialized(TexImageTarget target,
|
||||||
uint32_t level);
|
uint32_t level);
|
||||||
void PopulateMipChain(uint32_t maxLevel);
|
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); }
|
bool IsCubeMap() const { return (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,6 +30,7 @@ class WebGLTransformFeedback final
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const GLuint mGLName;
|
const GLuint mGLName;
|
||||||
|
bool mHasBeenBound = false;
|
||||||
private:
|
private:
|
||||||
// GLES 3.0.4 p267, Table 6.24 "Transform Feedback State"
|
// 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
|
// 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);
|
return dom::WebGLVertexArrayObject_Binding::Wrap(cx, this, givenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
|
WebGLVertexArray::WebGLVertexArray(WebGLContext* const webgl, const GLuint name)
|
||||||
: WebGLRefCountedObject(webgl)
|
: WebGLRefCountedObject(webgl)
|
||||||
, mGLName(0)
|
, mGLName(name)
|
||||||
{
|
{
|
||||||
mAttribs.SetLength(mContext->mGLMaxVertexAttribs);
|
mAttribs.SetLength(mContext->mGLMaxVertexAttribs);
|
||||||
mContext->mVertexArrays.insertBack(this);
|
mContext->mVertexArrays.insertBack(this);
|
||||||
|
@ -65,12 +65,6 @@ WebGLVertexArray::Delete()
|
||||||
mAttribs.Clear();
|
mAttribs.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
WebGLVertexArray::IsVertexArray() const
|
|
||||||
{
|
|
||||||
return IsVertexArrayImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
|
||||||
mAttribs,
|
mAttribs,
|
||||||
mElementArrayBuffer)
|
mElementArrayBuffer)
|
||||||
|
|
|
@ -31,15 +31,7 @@ class WebGLVertexArray
|
||||||
public:
|
public:
|
||||||
static WebGLVertexArray* Create(WebGLContext* webgl);
|
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();
|
void Delete();
|
||||||
bool IsVertexArray() const;
|
|
||||||
|
|
||||||
WebGLContext* GetParentObject() const {
|
WebGLContext* GetParentObject() const {
|
||||||
return mContext;
|
return mContext;
|
||||||
|
@ -50,20 +42,19 @@ public:
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
|
||||||
|
|
||||||
GLuint GLName() const { return mGLName; }
|
|
||||||
|
|
||||||
void AddBufferBindCounts(int8_t addVal) const;
|
void AddBufferBindCounts(int8_t addVal) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit WebGLVertexArray(WebGLContext* webgl);
|
WebGLVertexArray(WebGLContext* webgl, GLuint name);
|
||||||
virtual ~WebGLVertexArray();
|
virtual ~WebGLVertexArray();
|
||||||
|
|
||||||
virtual void GenVertexArray() = 0;
|
virtual void BindVertexArray() = 0;
|
||||||
virtual void BindVertexArrayImpl() = 0;
|
|
||||||
virtual void DeleteImpl() = 0;
|
virtual void DeleteImpl() = 0;
|
||||||
virtual bool IsVertexArrayImpl() const = 0;
|
|
||||||
|
|
||||||
GLuint mGLName;
|
public:
|
||||||
|
const GLuint mGLName;
|
||||||
|
bool mHasBeenBound = false;
|
||||||
|
protected:
|
||||||
nsTArray<WebGLVertexAttribData> mAttribs;
|
nsTArray<WebGLVertexAttribData> mAttribs;
|
||||||
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
|
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,11 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl)
|
WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl)
|
||||||
: WebGLVertexArray(webgl)
|
: WebGLVertexArray(webgl, 0)
|
||||||
, mIsVAO(false)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void
|
void
|
||||||
WebGLVertexArrayFake::BindVertexArrayImpl()
|
WebGLVertexArrayFake::BindVertexArray()
|
||||||
{
|
{
|
||||||
// Go through and re-bind all buffers and setup all
|
// Go through and re-bind all buffers and setup all
|
||||||
// vertex attribute pointers
|
// vertex attribute pointers
|
||||||
|
@ -52,19 +51,6 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
|
||||||
}
|
}
|
||||||
|
|
||||||
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
|
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
|
||||||
mIsVAO = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
WebGLVertexArrayFake::DeleteImpl()
|
|
||||||
{
|
|
||||||
mIsVAO = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
WebGLVertexArrayFake::IsVertexArrayImpl() const
|
|
||||||
{
|
|
||||||
return mIsVAO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -16,10 +16,8 @@ class WebGLVertexArrayFake final
|
||||||
friend class WebGLVertexArray;
|
friend class WebGLVertexArray;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void BindVertexArrayImpl() override;
|
virtual void BindVertexArray() override;
|
||||||
virtual void DeleteImpl() override;
|
virtual void DeleteImpl() override {}
|
||||||
virtual void GenVertexArray() override {};
|
|
||||||
virtual bool IsVertexArrayImpl() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit WebGLVertexArrayFake(WebGLContext* webgl);
|
explicit WebGLVertexArrayFake(WebGLContext* webgl);
|
||||||
|
@ -27,8 +25,6 @@ private:
|
||||||
~WebGLVertexArrayFake() {
|
~WebGLVertexArrayFake() {
|
||||||
DeleteOnce();
|
DeleteOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mIsVAO;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -11,8 +11,12 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl)
|
WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl)
|
||||||
: WebGLVertexArray(webgl)
|
: WebGLVertexArray(webgl,
|
||||||
, mIsVAO(false)
|
[&]() {
|
||||||
|
GLuint ret = 0;
|
||||||
|
webgl->gl->fGenVertexArrays(1, &ret);
|
||||||
|
return ret;
|
||||||
|
}())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
WebGLVertexArrayGL::~WebGLVertexArrayGL()
|
WebGLVertexArrayGL::~WebGLVertexArrayGL()
|
||||||
|
@ -26,35 +30,13 @@ WebGLVertexArrayGL::DeleteImpl()
|
||||||
mElementArrayBuffer = nullptr;
|
mElementArrayBuffer = nullptr;
|
||||||
|
|
||||||
mContext->gl->fDeleteVertexArrays(1, &mGLName);
|
mContext->gl->fDeleteVertexArrays(1, &mGLName);
|
||||||
|
|
||||||
mIsVAO = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WebGLVertexArrayGL::BindVertexArrayImpl()
|
WebGLVertexArrayGL::BindVertexArray()
|
||||||
{
|
{
|
||||||
mContext->mBoundVertexArray = this;
|
mContext->mBoundVertexArray = this;
|
||||||
mContext->gl->fBindVertexArray(mGLName);
|
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
|
} // namespace mozilla
|
||||||
|
|
|
@ -17,19 +17,11 @@ class WebGLVertexArrayGL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void DeleteImpl() override;
|
virtual void DeleteImpl() override;
|
||||||
virtual void BindVertexArrayImpl() override;
|
virtual void BindVertexArray() override;
|
||||||
virtual void GenVertexArray() override;
|
|
||||||
virtual bool IsVertexArrayImpl() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit WebGLVertexArrayGL(WebGLContext* webgl);
|
explicit WebGLVertexArrayGL(WebGLContext* webgl);
|
||||||
~WebGLVertexArrayGL();
|
~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
|
} // namespace mozilla
|
||||||
|
|
|
@ -645,11 +645,11 @@ function runBoundDeleteTests() {
|
||||||
wtu.glErrorShouldBe(gl, expectedError,
|
wtu.glErrorShouldBe(gl, expectedError,
|
||||||
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
|
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
|
||||||
|
|
||||||
if (!gl.isBuffer(positionBuffer)) {
|
if (gl.isBuffer(positionBuffer)) {
|
||||||
testFailed("References from unbound VAOs keep Position buffer alive.");
|
testFailed("References from unbound VAOs don't keep Position buffer alive.");
|
||||||
}
|
}
|
||||||
if (!gl.isBuffer(colorBuffer)) {
|
if (gl.isBuffer(colorBuffer)) {
|
||||||
testFailed("References from unbound VAOs keep Color buffer alive");
|
testFailed("References from unbound VAOs don't keep Color buffer alive");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,11 +590,11 @@ function runBoundDeleteTests() {
|
||||||
wtu.glErrorShouldBe(gl, expectedError,
|
wtu.glErrorShouldBe(gl, expectedError,
|
||||||
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
|
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
|
||||||
|
|
||||||
if (!gl.isBuffer(positionBuffer)) {
|
if (gl.isBuffer(positionBuffer)) {
|
||||||
testFailed("References from unbound VAOs keep Position buffer alive.");
|
testFailed("References from unbound VAOs don't keep Position buffer alive.");
|
||||||
}
|
}
|
||||||
if (!gl.isBuffer(colorBuffer)) {
|
if (gl.isBuffer(colorBuffer)) {
|
||||||
testFailed("References from unbound VAOs keep Color buffer alive");
|
testFailed("References from unbound VAOs don't keep Color buffer alive");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5324,6 +5324,7 @@ subsuite = webgl2-core
|
||||||
subsuite = webgl2-core
|
subsuite = webgl2-core
|
||||||
[generated/test_2_conformance2__rendering__framebuffer-texture-changing-base-level.html]
|
[generated/test_2_conformance2__rendering__framebuffer-texture-changing-base-level.html]
|
||||||
subsuite = webgl2-core
|
subsuite = webgl2-core
|
||||||
|
fail-if = (os == 'win')
|
||||||
[generated/test_2_conformance2__rendering__framebuffer-texture-level1.html]
|
[generated/test_2_conformance2__rendering__framebuffer-texture-level1.html]
|
||||||
subsuite = webgl2-core
|
subsuite = webgl2-core
|
||||||
fail-if = (os == 'mac')
|
fail-if = (os == 'mac')
|
||||||
|
|
|
@ -1101,3 +1101,6 @@ skip-if = (os == 'win')
|
||||||
skip-if = (os == 'win')
|
skip-if = (os == 'win')
|
||||||
[generated/test_2_conformance__textures__misc__tex-video-using-tex-unit-non-zero.html]
|
[generated/test_2_conformance__textures__misc__tex-video-using-tex-unit-non-zero.html]
|
||||||
skip-if = (os == 'win')
|
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 "nsFrameSelection.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
|
#include "mozilla/ShortcutKeys.h"
|
||||||
|
#include "nsXBLPrototypeHandler.h"
|
||||||
|
#include "mozilla/dom/KeyboardEvent.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
@ -957,13 +960,44 @@ TextInputListener::HandleEvent(Event* aEvent)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetKeyboardEvent* keyEvent =
|
RefPtr<KeyboardEvent> keyEvent = aEvent->AsKeyboardEvent();
|
||||||
aEvent->WidgetEventPtr()->AsKeyboardEvent();
|
|
||||||
if (!keyEvent) {
|
if (!keyEvent) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,7 +1006,7 @@ TextInputListener::HandleEvent(Event* aEvent)
|
||||||
nsIWidget::NativeKeyBindingsForMultiLineEditor :
|
nsIWidget::NativeKeyBindingsForMultiLineEditor :
|
||||||
nsIWidget::NativeKeyBindingsForSingleLineEditor;
|
nsIWidget::NativeKeyBindingsForSingleLineEditor;
|
||||||
|
|
||||||
nsIWidget* widget = keyEvent->mWidget;
|
nsIWidget* widget = widgetKeyEvent->mWidget;
|
||||||
// If the event is created by chrome script, the widget is nullptr.
|
// If the event is created by chrome script, the widget is nullptr.
|
||||||
if (!widget) {
|
if (!widget) {
|
||||||
widget = mFrame->GetNearestWidget();
|
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
|
// 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
|
// execute native key bindings. Therefore, we need to set widget to
|
||||||
// WidgetEvent::mWidget temporarily.
|
// WidgetEvent::mWidget temporarily.
|
||||||
AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(keyEvent->mWidget);
|
AutoRestore<nsCOMPtr<nsIWidget>> saveWidget(widgetKeyEvent->mWidget);
|
||||||
keyEvent->mWidget = widget;
|
widgetKeyEvent->mWidget = widget;
|
||||||
if (keyEvent->ExecuteEditCommands(nativeKeyBindingsType,
|
if (widgetKeyEvent->ExecuteEditCommands(nativeKeyBindingsType,
|
||||||
DoCommandCallback, mFrame)) {
|
DoCommandCallback, mFrame)) {
|
||||||
aEvent->PreventDefault();
|
aEvent->PreventDefault();
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -244,38 +244,36 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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()) {
|
if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
|
||||||
// Guard against stale updates (updates meant for a pres shell which
|
// Guard against stale updates (updates meant for a pres shell which
|
||||||
// has since been torn down and destroyed).
|
// has since been torn down and destroyed).
|
||||||
if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
|
if (aRequest.GetPresShellId() == shell->GetPresShellId()) {
|
||||||
ProcessUpdateFrame(aFrameMetrics);
|
ProcessUpdateFrame(aRequest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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.
|
// This requires special handling.
|
||||||
FrameMetrics newSubFrameMetrics(aFrameMetrics);
|
APZCCallbackHelper::UpdateSubFrame(aRequest);
|
||||||
APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
TabChildBase::ProcessUpdateFrame(const RepaintRequest& aRequest)
|
||||||
{
|
{
|
||||||
if (!mTabChildMessageManager) {
|
if (!mTabChildMessageManager) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameMetrics newMetrics = aFrameMetrics;
|
APZCCallbackHelper::UpdateRootFrame(aRequest);
|
||||||
APZCCallbackHelper::UpdateRootFrame(newMetrics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1303,9 +1301,9 @@ TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
|
TabChild::UpdateFrame(const RepaintRequest& aRequest)
|
||||||
{
|
{
|
||||||
return TabChildBase::UpdateFrameHandler(aFrameMetrics);
|
return TabChildBase::UpdateFrameHandler(aRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
|
|
|
@ -185,9 +185,9 @@ protected:
|
||||||
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||||
const nsAString& aJSONData);
|
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:
|
protected:
|
||||||
RefPtr<TabChildMessageManager> mTabChildMessageManager;
|
RefPtr<TabChildMessageManager> mTabChildMessageManager;
|
||||||
|
@ -635,7 +635,7 @@ public:
|
||||||
void SetAllowedTouchBehavior(uint64_t aInputBlockId,
|
void SetAllowedTouchBehavior(uint64_t aInputBlockId,
|
||||||
const nsTArray<TouchBehaviorFlags>& aFlags) const;
|
const nsTArray<TouchBehaviorFlags>& aFlags) const;
|
||||||
|
|
||||||
bool UpdateFrame(const FrameMetrics& aFrameMetrics);
|
bool UpdateFrame(const layers::RepaintRequest& aRequest);
|
||||||
bool NotifyAPZStateChange(const ViewID& aViewId,
|
bool NotifyAPZStateChange(const ViewID& aViewId,
|
||||||
const layers::GeckoContentController::APZStateChange& aChange,
|
const layers::GeckoContentController::APZStateChange& aChange,
|
||||||
const int& aArg);
|
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/gamepad/mochitest.ini',
|
||||||
'mochitest/general/mochitest.ini',
|
'mochitest/general/mochitest.ini',
|
||||||
'mochitest/geolocation/mochitest.ini',
|
'mochitest/geolocation/mochitest.ini',
|
||||||
|
'mochitest/keyhandling/mochitest.ini',
|
||||||
'mochitest/localstorage/mochitest.ini',
|
'mochitest/localstorage/mochitest.ini',
|
||||||
'mochitest/orientation/mochitest.ini',
|
'mochitest/orientation/mochitest.ini',
|
||||||
'mochitest/pointerlock/mochitest.ini',
|
'mochitest/pointerlock/mochitest.ini',
|
||||||
|
@ -177,6 +178,7 @@ MOCHITEST_CHROME_MANIFESTS += [
|
||||||
'mochitest/chrome/chrome.ini',
|
'mochitest/chrome/chrome.ini',
|
||||||
'mochitest/general/chrome.ini',
|
'mochitest/general/chrome.ini',
|
||||||
'mochitest/geolocation/chrome.ini',
|
'mochitest/geolocation/chrome.ini',
|
||||||
|
'mochitest/keyhandling/chrome.ini',
|
||||||
'mochitest/localstorage/chrome.ini',
|
'mochitest/localstorage/chrome.ini',
|
||||||
'mochitest/sessionstorage/chrome.ini',
|
'mochitest/sessionstorage/chrome.ini',
|
||||||
'mochitest/webcomponents/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
|
# 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/.
|
# 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
|
# 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/.
|
# 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
|
# 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/.
|
# 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:
|
else:
|
||||||
DIRS += ['emacs']
|
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
|
# 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/.
|
# 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
|
# 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/.
|
# 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 += [
|
EXPORTS += [
|
||||||
'nsBindingManager.h',
|
'nsBindingManager.h',
|
||||||
'nsXBLBinding.h',
|
'nsXBLBinding.h',
|
||||||
|
'nsXBLPrototypeHandler.h',
|
||||||
'nsXBLService.h',
|
'nsXBLService.h',
|
||||||
'nsXBLWindowKeyHandler.h',
|
'nsXBLWindowKeyHandler.h',
|
||||||
]
|
]
|
||||||
|
|
|
@ -106,11 +106,11 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(const char16_t* aEvent,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXBLPrototypeHandler::nsXBLPrototypeHandler(Element* aHandlerElement, XBLReservedKey aReserved)
|
nsXBLPrototypeHandler::nsXBLPrototypeHandler(Element* aHandlerElement, XBLReservedKey aReserved)
|
||||||
: mHandlerElement(nullptr),
|
: mHandlerElement(nullptr)
|
||||||
mLineNumber(0),
|
, mLineNumber(0)
|
||||||
mReserved(aReserved),
|
, mReserved(aReserved)
|
||||||
mNextHandler(nullptr),
|
, mNextHandler(nullptr)
|
||||||
mPrototypeBinding(nullptr)
|
, mPrototypeBinding(nullptr)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
@ -118,6 +118,21 @@ nsXBLPrototypeHandler::nsXBLPrototypeHandler(Element* aHandlerElement, XBLReserv
|
||||||
ConstructPrototype(aHandlerElement);
|
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)
|
nsXBLPrototypeHandler::nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding)
|
||||||
: mHandlerText(nullptr),
|
: mHandlerText(nullptr),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "nsIWeakReference.h"
|
#include "nsIWeakReference.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "js/TypeDecls.h"
|
#include "js/TypeDecls.h"
|
||||||
|
#include "mozilla/ShortcutKeys.h"
|
||||||
|
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIObjectInputStream;
|
class nsIObjectInputStream;
|
||||||
|
@ -93,6 +94,10 @@ public:
|
||||||
// This constructor is used only by XUL key handlers (e.g., <key>)
|
// This constructor is used only by XUL key handlers (e.g., <key>)
|
||||||
explicit nsXBLPrototypeHandler(mozilla::dom::Element* aKeyElement, XBLReservedKey aReserved);
|
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
|
// This constructor is used for handlers loaded from the cache
|
||||||
explicit nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding);
|
explicit nsXBLPrototypeHandler(nsXBLPrototypeBinding* aBinding);
|
||||||
|
|
||||||
|
|
|
@ -34,119 +34,18 @@
|
||||||
#include "mozilla/dom/EventBinding.h"
|
#include "mozilla/dom/EventBinding.h"
|
||||||
#include "mozilla/dom/KeyboardEvent.h"
|
#include "mozilla/dom/KeyboardEvent.h"
|
||||||
#include "mozilla/layers/KeyboardMap.h"
|
#include "mozilla/layers/KeyboardMap.h"
|
||||||
|
#include "mozilla/ShortcutKeys.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
using namespace mozilla::layers;
|
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,
|
nsXBLWindowKeyHandler::nsXBLWindowKeyHandler(Element* aElement,
|
||||||
EventTarget* aTarget)
|
EventTarget* aTarget)
|
||||||
: mTarget(aTarget),
|
: mTarget(aTarget),
|
||||||
mHandler(nullptr)
|
mHandler(nullptr)
|
||||||
{
|
{
|
||||||
mWeakPtrForElement = do_GetWeakReference(aElement);
|
mWeakPtrForElement = do_GetWeakReference(aElement);
|
||||||
++sRefCnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
|
nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
|
||||||
|
@ -154,11 +53,6 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
|
||||||
// If mWeakPtrForElement is non-null, we created a prototype handler.
|
// If mWeakPtrForElement is non-null, we created a prototype handler.
|
||||||
if (mWeakPtrForElement)
|
if (mWeakPtrForElement)
|
||||||
delete mHandler;
|
delete mHandler;
|
||||||
|
|
||||||
--sRefCnt;
|
|
||||||
if (!sRefCnt) {
|
|
||||||
sXBLSpecialDocInfo = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsXBLWindowKeyHandler,
|
NS_IMPL_ISUPPORTS(nsXBLWindowKeyHandler,
|
||||||
|
@ -230,14 +124,12 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
|
|
||||||
BuildHandlerChain(el, &mHandler);
|
BuildHandlerChain(el, &mHandler);
|
||||||
} else { // We are an XBL file of handlers.
|
} else { // We are an XBL file of handlers.
|
||||||
EnsureSpecialDocInfo();
|
|
||||||
|
|
||||||
// Now determine which handlers we should be using.
|
// Now determine which handlers we should be using.
|
||||||
if (IsHTMLEditableFieldFocused()) {
|
if (IsHTMLEditableFieldFocused()) {
|
||||||
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("editor"), &mHandler);
|
mHandler = ShortcutKeys::GetHandlers(HandlerType::eEditor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("browser"), &mHandler);
|
mHandler = ShortcutKeys::GetHandlers(HandlerType::eBrowser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +137,7 @@ nsXBLWindowKeyHandler::EnsureHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType)
|
nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent)
|
||||||
{
|
{
|
||||||
if (aKeyEvent->DefaultPrevented()) {
|
if (aKeyEvent->DefaultPrevented()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -267,7 +159,7 @@ nsXBLWindowKeyHandler::WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkHandlersInternal(aKeyEvent, aEventType, true);
|
WalkHandlersInternal(aKeyEvent, true);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -396,11 +288,7 @@ nsXBLWindowKeyHandler::RemoveKeyboardEventListenersFrom(
|
||||||
/* static */ KeyboardMap
|
/* static */ KeyboardMap
|
||||||
nsXBLWindowKeyHandler::CollectKeyboardShortcuts()
|
nsXBLWindowKeyHandler::CollectKeyboardShortcuts()
|
||||||
{
|
{
|
||||||
// Load the XBL handlers
|
nsXBLPrototypeHandler* handlers = ShortcutKeys::GetHandlers(HandlerType::eBrowser);
|
||||||
EnsureSpecialDocInfo();
|
|
||||||
|
|
||||||
nsXBLPrototypeHandler* handlers = nullptr;
|
|
||||||
sXBLSpecialDocInfo->GetHandlers(NS_LITERAL_CSTRING("browser"), &handlers);
|
|
||||||
|
|
||||||
// Convert the handlers into keyboard shortcuts, using an AutoTArray with
|
// Convert the handlers into keyboard shortcuts, using an AutoTArray with
|
||||||
// the maximum amount of shortcuts used on any platform to minimize allocations
|
// the maximum amount of shortcuts used on any platform to minimize allocations
|
||||||
|
@ -421,30 +309,6 @@ nsXBLWindowKeyHandler::CollectKeyboardShortcuts()
|
||||||
return KeyboardMap(std::move(shortcuts));
|
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
|
NS_IMETHODIMP
|
||||||
nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
|
nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
|
||||||
{
|
{
|
||||||
|
@ -492,9 +356,7 @@ nsXBLWindowKeyHandler::HandleEvent(Event* aEvent)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsAtom> eventTypeAtom =
|
return WalkHandlers(keyEvent);
|
||||||
ConvertEventToDOMEventType(*widgetKeyboardEvent);
|
|
||||||
return WalkHandlers(keyEvent, eventTypeAtom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -602,7 +464,6 @@ nsXBLWindowKeyHandler::IsHTMLEditableFieldFocused()
|
||||||
//
|
//
|
||||||
bool
|
bool
|
||||||
nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
||||||
nsAtom* aEventType,
|
|
||||||
bool aExecute,
|
bool aExecute,
|
||||||
bool* aOutReservedForChrome)
|
bool* aOutReservedForChrome)
|
||||||
{
|
{
|
||||||
|
@ -614,8 +475,7 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
||||||
nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys);
|
nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys);
|
||||||
|
|
||||||
if (shortcutKeys.IsEmpty()) {
|
if (shortcutKeys.IsEmpty()) {
|
||||||
return WalkHandlersAndExecute(aKeyEvent, aEventType,
|
return WalkHandlersAndExecute(aKeyEvent, 0, IgnoreModifierState(),
|
||||||
0, IgnoreModifierState(),
|
|
||||||
aExecute, aOutReservedForChrome);
|
aExecute, aOutReservedForChrome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,8 +483,7 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
||||||
ShortcutKeyCandidate& key = shortcutKeys[i];
|
ShortcutKeyCandidate& key = shortcutKeys[i];
|
||||||
IgnoreModifierState ignoreModifierState;
|
IgnoreModifierState ignoreModifierState;
|
||||||
ignoreModifierState.mShift = key.mIgnoreShift;
|
ignoreModifierState.mShift = key.mIgnoreShift;
|
||||||
if (WalkHandlersAndExecute(aKeyEvent, aEventType,
|
if (WalkHandlersAndExecute(aKeyEvent, key.mCharCode, ignoreModifierState,
|
||||||
key.mCharCode, ignoreModifierState,
|
|
||||||
aExecute, aOutReservedForChrome)) {
|
aExecute, aOutReservedForChrome)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -635,7 +494,6 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
||||||
bool
|
bool
|
||||||
nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
KeyboardEvent* aKeyEvent,
|
KeyboardEvent* aKeyEvent,
|
||||||
nsAtom* aEventType,
|
|
||||||
uint32_t aCharCode,
|
uint32_t aCharCode,
|
||||||
const IgnoreModifierState& aIgnoreModifierState,
|
const IgnoreModifierState& aIgnoreModifierState,
|
||||||
bool aExecute,
|
bool aExecute,
|
||||||
|
@ -651,6 +509,8 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsAtom* eventType = ShortcutKeys::ConvertEventToDOMEventType(widgetKeyboardEvent);
|
||||||
|
|
||||||
// Try all of the handlers until we find one that matches the event.
|
// Try all of the handlers until we find one that matches the event.
|
||||||
for (nsXBLPrototypeHandler* handler = mHandler;
|
for (nsXBLPrototypeHandler* handler = mHandler;
|
||||||
handler;
|
handler;
|
||||||
|
@ -672,7 +532,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
}
|
}
|
||||||
// The other event types should exactly be matched with the handler's
|
// The other event types should exactly be matched with the handler's
|
||||||
// event type.
|
// event type.
|
||||||
} else if (!handler->EventTypeEquals(aEventType)) {
|
} else if (!handler->EventTypeEquals(eventType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -683,12 +543,12 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
// prevented, following keypress event won't be fired. However, if
|
// prevented, following keypress event won't be fired. However, if
|
||||||
// following keypress event is reserved, we shouldn't allow web
|
// following keypress event is reserved, we shouldn't allow web
|
||||||
// contents to prevent the default of the preceding keydown event.
|
// contents to prevent the default of the preceding keydown event.
|
||||||
if (aEventType != nsGkAtoms::keydown &&
|
if (eventType != nsGkAtoms::keydown &&
|
||||||
aEventType != nsGkAtoms::keypress) {
|
eventType != nsGkAtoms::keypress) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (!handler->EventTypeEquals(aEventType)) {
|
} else if (!handler->EventTypeEquals(eventType)) {
|
||||||
// Otherwise, aEventType should exactly be matched.
|
// Otherwise, eventType should exactly be matched.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,7 +573,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aExecute) {
|
if (!aExecute) {
|
||||||
if (handler->EventTypeEquals(aEventType)) {
|
if (handler->EventTypeEquals(eventType)) {
|
||||||
if (aOutReservedForChrome) {
|
if (aOutReservedForChrome) {
|
||||||
*aOutReservedForChrome = IsReservedKey(widgetKeyboardEvent, handler);
|
*aOutReservedForChrome = IsReservedKey(widgetKeyboardEvent, handler);
|
||||||
}
|
}
|
||||||
|
@ -724,7 +584,7 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
// If the command is reserved and the event is keydown, check also if
|
// If the command is reserved and the event is keydown, check also if
|
||||||
// the handler is for keypress because if following keypress event is
|
// the handler is for keypress because if following keypress event is
|
||||||
// reserved, we shouldn't dispatch the event into web contents.
|
// reserved, we shouldn't dispatch the event into web contents.
|
||||||
if (aEventType == nsGkAtoms::keydown &&
|
if (eventType == nsGkAtoms::keydown &&
|
||||||
handler->EventTypeEquals(nsGkAtoms::keypress)) {
|
handler->EventTypeEquals(nsGkAtoms::keypress)) {
|
||||||
if (IsReservedKey(widgetKeyboardEvent, handler)) {
|
if (IsReservedKey(widgetKeyboardEvent, handler)) {
|
||||||
if (aOutReservedForChrome) {
|
if (aOutReservedForChrome) {
|
||||||
|
@ -773,8 +633,8 @@ nsXBLWindowKeyHandler::WalkHandlersAndExecute(
|
||||||
if (!aIgnoreModifierState.mOS && widgetKeyboardEvent->IsOS()) {
|
if (!aIgnoreModifierState.mOS && widgetKeyboardEvent->IsOS()) {
|
||||||
IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
|
IgnoreModifierState ignoreModifierState(aIgnoreModifierState);
|
||||||
ignoreModifierState.mOS = true;
|
ignoreModifierState.mOS = true;
|
||||||
return WalkHandlersAndExecute(aKeyEvent, aEventType,
|
return WalkHandlersAndExecute(aKeyEvent, aCharCode, ignoreModifierState,
|
||||||
aCharCode, ignoreModifierState, aExecute);
|
aExecute);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -819,10 +679,7 @@ nsXBLWindowKeyHandler::HasHandlerForEvent(KeyboardEvent* aEvent,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsAtom> eventTypeAtom =
|
return WalkHandlersInternal(aEvent, false, aOutReservedForChrome);
|
||||||
ConvertEventToDOMEventType(*widgetKeyboardEvent);
|
|
||||||
return WalkHandlersInternal(aEvent, eventTypeAtom, false,
|
|
||||||
aOutReservedForChrome);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Element>
|
already_AddRefed<Element>
|
||||||
|
|
|
@ -50,17 +50,16 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsXBLWindowKeyHandler();
|
virtual ~nsXBLWindowKeyHandler();
|
||||||
|
|
||||||
nsresult WalkHandlers(KeyboardEvent* aKeyEvent, nsAtom* aEventType);
|
nsresult WalkHandlers(KeyboardEvent* aKeyEvent);
|
||||||
|
|
||||||
// walk the handlers, looking for one to handle the event
|
// walk the handlers, looking for one to handle the event
|
||||||
bool WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
bool WalkHandlersInternal(KeyboardEvent* aKeyEvent,
|
||||||
nsAtom* aEventType,
|
|
||||||
bool aExecute,
|
bool aExecute,
|
||||||
bool* aOutReservedForChrome = nullptr);
|
bool* aOutReservedForChrome = nullptr);
|
||||||
|
|
||||||
// walk the handlers for aEvent, aCharCode and aIgnoreModifierState. Execute
|
// walk the handlers for aEvent, aCharCode and aIgnoreModifierState. Execute
|
||||||
// it if aExecute = true.
|
// it if aExecute = true.
|
||||||
bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent, nsAtom* aEventType,
|
bool WalkHandlersAndExecute(KeyboardEvent* aKeyEvent,
|
||||||
uint32_t aCharCode,
|
uint32_t aCharCode,
|
||||||
const IgnoreModifierState& aIgnoreModifierState,
|
const IgnoreModifierState& aIgnoreModifierState,
|
||||||
bool aExecute,
|
bool aExecute,
|
||||||
|
@ -82,15 +81,6 @@ protected:
|
||||||
bool IsReservedKey(mozilla::WidgetKeyboardEvent* aKeyEvent,
|
bool IsReservedKey(mozilla::WidgetKeyboardEvent* aKeyEvent,
|
||||||
nsXBLPrototypeHandler* aHandler);
|
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
|
// lazily load the handlers. Overridden to handle being attached
|
||||||
// to a particular element rather than the document
|
// to a particular element rather than the document
|
||||||
nsresult EnsureHandlers();
|
nsresult EnsureHandlers();
|
||||||
|
@ -126,12 +116,7 @@ protected:
|
||||||
nsWeakPtr mWeakPtrForElement;
|
nsWeakPtr mWeakPtrForElement;
|
||||||
mozilla::dom::EventTarget* mTarget; // weak ref
|
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
|
nsXBLPrototypeHandler* mHandler; // platform bindings
|
||||||
|
|
||||||
// holds reference count to document info about bindings
|
|
||||||
static uint32_t sRefCnt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
already_AddRefed<nsXBLWindowKeyHandler>
|
already_AddRefed<nsXBLWindowKeyHandler>
|
||||||
|
|
|
@ -56,6 +56,26 @@ using namespace vm;
|
||||||
|
|
||||||
namespace {
|
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 void * direct_run(const bool get_table_mode,
|
||||||
const instr * program,
|
const instr * program,
|
||||||
const byte * data,
|
const byte * data,
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#define __GFXMESSAGEUTILS_H__
|
#define __GFXMESSAGEUTILS_H__
|
||||||
|
|
||||||
#include "FilterSupport.h"
|
#include "FilterSupport.h"
|
||||||
#include "FrameMetrics.h"
|
|
||||||
#include "ImageTypes.h"
|
#include "ImageTypes.h"
|
||||||
#include "RegionBuilder.h"
|
#include "RegionBuilder.h"
|
||||||
#include "base/process_util.h"
|
#include "base/process_util.h"
|
||||||
|
|
|
@ -38,6 +38,8 @@ namespace layers {
|
||||||
struct ScrollUpdateInfo {
|
struct ScrollUpdateInfo {
|
||||||
uint32_t mScrollGeneration;
|
uint32_t mScrollGeneration;
|
||||||
CSSPoint mScrollOffset;
|
CSSPoint mScrollOffset;
|
||||||
|
CSSPoint mBaseScrollOffset;
|
||||||
|
bool mIsRelative;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,10 +64,6 @@ public:
|
||||||
ePending, // The scroll offset was updated on the main thread, but not
|
ePending, // The scroll offset was updated on the main thread, but not
|
||||||
// painted, so the layer texture data is still at the old
|
// painted, so the layer texture data is still at the old
|
||||||
// offset.
|
// 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
|
eRestore // The scroll offset was updated by the main thread, but as
|
||||||
// a restore from history or after a frame reconstruction.
|
// a restore from history or after a frame reconstruction.
|
||||||
// In this case, APZ can ignore the offset change if the
|
// In this case, APZ can ignore the offset change if the
|
||||||
|
@ -82,6 +80,7 @@ public:
|
||||||
, mCumulativeResolution()
|
, mCumulativeResolution()
|
||||||
, mDevPixelsPerCSSPixel(1)
|
, mDevPixelsPerCSSPixel(1)
|
||||||
, mScrollOffset(0, 0)
|
, mScrollOffset(0, 0)
|
||||||
|
, mBaseScrollOffset(0, 0)
|
||||||
, mZoom()
|
, mZoom()
|
||||||
, mScrollGeneration(0)
|
, mScrollGeneration(0)
|
||||||
, mSmoothScrollOffset(0, 0)
|
, mSmoothScrollOffset(0, 0)
|
||||||
|
@ -93,6 +92,7 @@ public:
|
||||||
, mPaintRequestTime()
|
, mPaintRequestTime()
|
||||||
, mScrollUpdateType(eNone)
|
, mScrollUpdateType(eNone)
|
||||||
, mIsRootContent(false)
|
, mIsRootContent(false)
|
||||||
|
, mIsRelative(false)
|
||||||
, mDoSmoothScroll(false)
|
, mDoSmoothScroll(false)
|
||||||
, mUseDisplayPortMargins(false)
|
, mUseDisplayPortMargins(false)
|
||||||
, mIsScrollInfoLayer(false)
|
, mIsScrollInfoLayer(false)
|
||||||
|
@ -113,6 +113,7 @@ public:
|
||||||
mCumulativeResolution == aOther.mCumulativeResolution &&
|
mCumulativeResolution == aOther.mCumulativeResolution &&
|
||||||
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
|
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
|
||||||
mScrollOffset == aOther.mScrollOffset &&
|
mScrollOffset == aOther.mScrollOffset &&
|
||||||
|
mBaseScrollOffset == aOther.mBaseScrollOffset &&
|
||||||
// don't compare mZoom
|
// don't compare mZoom
|
||||||
mScrollGeneration == aOther.mScrollGeneration &&
|
mScrollGeneration == aOther.mScrollGeneration &&
|
||||||
mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
|
mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
|
||||||
|
@ -124,6 +125,7 @@ public:
|
||||||
mPaintRequestTime == aOther.mPaintRequestTime &&
|
mPaintRequestTime == aOther.mPaintRequestTime &&
|
||||||
mScrollUpdateType == aOther.mScrollUpdateType &&
|
mScrollUpdateType == aOther.mScrollUpdateType &&
|
||||||
mIsRootContent == aOther.mIsRootContent &&
|
mIsRootContent == aOther.mIsRootContent &&
|
||||||
|
mIsRelative == aOther.mIsRelative &&
|
||||||
mDoSmoothScroll == aOther.mDoSmoothScroll &&
|
mDoSmoothScroll == aOther.mDoSmoothScroll &&
|
||||||
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
|
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
|
||||||
mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
|
mIsScrollInfoLayer == aOther.mIsScrollInfoLayer;
|
||||||
|
@ -251,29 +253,53 @@ public:
|
||||||
mZoom.yScale *= aScale.height;
|
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;
|
mScrollOffset = aOther.mScrollOffset;
|
||||||
mScrollGeneration = aOther.mScrollGeneration;
|
mScrollGeneration = aOther.mScrollGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopySmoothScrollInfoFrom(const FrameMetrics& aOther)
|
void ApplySmoothScrollUpdateFrom(const FrameMetrics& aOther)
|
||||||
{
|
{
|
||||||
mSmoothScrollOffset = aOther.mSmoothScrollOffset;
|
mSmoothScrollOffset = aOther.mSmoothScrollOffset;
|
||||||
mScrollGeneration = aOther.mScrollGeneration;
|
mScrollGeneration = aOther.mScrollGeneration;
|
||||||
mDoSmoothScroll = aOther.mDoSmoothScroll;
|
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)
|
void UpdatePendingScrollInfo(const ScrollUpdateInfo& aInfo)
|
||||||
{
|
{
|
||||||
mScrollOffset = aInfo.mScrollOffset;
|
mScrollOffset = aInfo.mScrollOffset;
|
||||||
|
mBaseScrollOffset = aInfo.mBaseScrollOffset;
|
||||||
mScrollGeneration = aInfo.mScrollGeneration;
|
mScrollGeneration = aInfo.mScrollGeneration;
|
||||||
mScrollUpdateType = ePending;
|
mScrollUpdateType = ePending;
|
||||||
}
|
mIsRelative = aInfo.mIsRelative;
|
||||||
|
|
||||||
void SetRepaintDrivenByUserAction(bool aUserAction)
|
|
||||||
{
|
|
||||||
mScrollUpdateType = aUserAction ? eUserAction : eNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -352,6 +378,11 @@ public:
|
||||||
mScrollOffset = aScrollOffset;
|
mScrollOffset = aScrollOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetBaseScrollOffset(const CSSPoint& aScrollOffset)
|
||||||
|
{
|
||||||
|
mBaseScrollOffset = aScrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
// Set scroll offset, first clamping to the scroll range.
|
// Set scroll offset, first clamping to the scroll range.
|
||||||
void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
|
void ClampAndSetScrollOffset(const CSSPoint& aScrollOffset)
|
||||||
{
|
{
|
||||||
|
@ -363,11 +394,21 @@ public:
|
||||||
return mScrollOffset;
|
return mScrollOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CSSPoint& GetBaseScrollOffset() const
|
||||||
|
{
|
||||||
|
return mBaseScrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
|
void SetSmoothScrollOffset(const CSSPoint& aSmoothScrollDestination)
|
||||||
{
|
{
|
||||||
mSmoothScrollOffset = aSmoothScrollDestination;
|
mSmoothScrollOffset = aSmoothScrollDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClampAndSetSmoothScrollOffset(const CSSPoint& aSmoothScrollOffset)
|
||||||
|
{
|
||||||
|
SetSmoothScrollOffset(CalculateScrollRange().ClampPoint(aSmoothScrollOffset));
|
||||||
|
}
|
||||||
|
|
||||||
const CSSPoint& GetSmoothScrollOffset() const
|
const CSSPoint& GetSmoothScrollOffset() const
|
||||||
{
|
{
|
||||||
return mSmoothScrollOffset;
|
return mSmoothScrollOffset;
|
||||||
|
@ -383,16 +424,14 @@ public:
|
||||||
return mZoom;
|
return mZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScrollOffsetUpdated(uint32_t aScrollGeneration)
|
void SetScrollGeneration(uint32_t aScrollGeneration)
|
||||||
{
|
{
|
||||||
mScrollUpdateType = eMainThread;
|
|
||||||
mScrollGeneration = aScrollGeneration;
|
mScrollGeneration = aScrollGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScrollOffsetRestored(uint32_t aScrollGeneration)
|
void SetScrollOffsetUpdateType(ScrollOffsetUpdateType aScrollUpdateType)
|
||||||
{
|
{
|
||||||
mScrollUpdateType = eRestore;
|
mScrollUpdateType = aScrollUpdateType;
|
||||||
mScrollGeneration = aScrollGeneration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
|
void SetSmoothScrollOffsetUpdated(int32_t aScrollGeneration)
|
||||||
|
@ -411,6 +450,16 @@ public:
|
||||||
return mScrollUpdateType != eNone;
|
return mScrollUpdateType != eNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetIsRelative(bool aIsRelative)
|
||||||
|
{
|
||||||
|
mIsRelative = aIsRelative;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRelative() const
|
||||||
|
{
|
||||||
|
return mIsRelative;
|
||||||
|
}
|
||||||
|
|
||||||
bool GetDoSmoothScroll() const
|
bool GetDoSmoothScroll() const
|
||||||
{
|
{
|
||||||
return mDoSmoothScroll;
|
return mDoSmoothScroll;
|
||||||
|
@ -651,6 +700,10 @@ private:
|
||||||
// not any parents, regardless of parent transforms.
|
// not any parents, regardless of parent transforms.
|
||||||
CSSPoint mScrollOffset;
|
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,
|
// 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
|
// 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
|
// 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.
|
// Whether or not this is the root scroll frame for the root content document.
|
||||||
bool mIsRootContent:1;
|
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
|
// When mDoSmoothScroll, the scroll offset should be animated to
|
||||||
// smoothly transition to mScrollOffset rather than be updated instantly.
|
// smoothly transition to mScrollOffset rather than be updated instantly.
|
||||||
bool mDoSmoothScroll:1;
|
bool mDoSmoothScroll:1;
|
||||||
|
|
|
@ -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/Assertions.h" // for MOZ_ASSERT_HELPER2
|
||||||
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
|
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
|
||||||
#include "mozilla/EventForwards.h" // for Modifiers
|
#include "mozilla/EventForwards.h" // for Modifiers
|
||||||
|
#include "mozilla/layers/RepaintRequest.h" // for RepaintRequest
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
@ -27,7 +28,7 @@ public:
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
|
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.
|
* Implementations per-platform are responsible for actually handling this.
|
||||||
*
|
*
|
||||||
* This method must always be called on the repaint thread, which depends
|
* 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
|
* Gecko main thread, while for RemoteContentController it is the compositor
|
||||||
* thread where it can send IPDL messages.
|
* 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
|
* 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
|
* A negative number prevents repaint requests during a scale.\n
|
||||||
* Units: ms
|
* 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);
|
ClampAndSetScrollOffset(Metrics().GetScrollOffset() + aOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncPanZoomController::CopyScrollInfoFrom(const FrameMetrics& aFrameMetrics) {
|
|
||||||
Metrics().CopyScrollInfoFrom(aFrameMetrics);
|
|
||||||
Metrics().RecalculateViewportOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncPanZoomController::ScaleWithFocus(float aScale,
|
void AsyncPanZoomController::ScaleWithFocus(float aScale,
|
||||||
const CSSPoint& aFocus) {
|
const CSSPoint& aFocus) {
|
||||||
Metrics().ZoomBy(aScale);
|
Metrics().ZoomBy(aScale);
|
||||||
|
@ -3597,7 +3597,7 @@ int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
|
||||||
return listener ? listener->GetLastTouchIdentifier() : -1;
|
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
|
// 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
|
// important to do this before the call to CalculatePendingDisplayPort, so
|
||||||
// that CalculatePendingDisplayPort uses the most recent available version of
|
// that CalculatePendingDisplayPort uses the most recent available version of
|
||||||
|
@ -3608,13 +3608,13 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
|
||||||
}
|
}
|
||||||
if (!controller->IsRepaintThread()) {
|
if (!controller->IsRepaintThread()) {
|
||||||
// use the local variable to resolve the function overload.
|
// 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);
|
(&AsyncPanZoomController::RequestContentRepaint);
|
||||||
controller->DispatchToRepaintThread(NewRunnableMethod<bool>(
|
controller->DispatchToRepaintThread(NewRunnableMethod<RepaintUpdateType>(
|
||||||
"layers::AsyncPanZoomController::RequestContentRepaint",
|
"layers::AsyncPanZoomController::RequestContentRepaint",
|
||||||
this,
|
this,
|
||||||
func,
|
func,
|
||||||
aUserAction));
|
aUpdateType));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3625,8 +3625,7 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
|
||||||
Metrics().SetDisplayPortMargins(CalculatePendingDisplayPort(Metrics(), velocity));
|
Metrics().SetDisplayPortMargins(CalculatePendingDisplayPort(Metrics(), velocity));
|
||||||
Metrics().SetUseDisplayPortMargins(true);
|
Metrics().SetUseDisplayPortMargins(true);
|
||||||
Metrics().SetPaintRequestTime(TimeStamp::Now());
|
Metrics().SetPaintRequestTime(TimeStamp::Now());
|
||||||
Metrics().SetRepaintDrivenByUserAction(aUserAction);
|
RequestContentRepaint(Metrics(), velocity, aUpdateType);
|
||||||
RequestContentRepaint(Metrics(), velocity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ CSSRect
|
/*static*/ CSSRect
|
||||||
|
@ -3642,7 +3641,8 @@ GetDisplayPortRect(const FrameMetrics& aFrameMetrics)
|
||||||
|
|
||||||
void
|
void
|
||||||
AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
|
AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
|
||||||
const ParentLayerPoint& aVelocity)
|
const ParentLayerPoint& aVelocity,
|
||||||
|
RepaintUpdateType aUpdateType)
|
||||||
{
|
{
|
||||||
RefPtr<GeckoContentController> controller = GetGeckoContentController();
|
RefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||||
if (!controller) {
|
if (!controller) {
|
||||||
|
@ -3650,31 +3650,33 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(controller->IsRepaintThread());
|
MOZ_ASSERT(controller->IsRepaintThread());
|
||||||
|
|
||||||
|
RepaintRequest request(aFrameMetrics, aUpdateType);
|
||||||
|
|
||||||
// If we're trying to paint what we already think is painted, discard this
|
// If we're trying to paint what we already think is painted, discard this
|
||||||
// request since it's a pointless paint.
|
// request since it's a pointless paint.
|
||||||
ScreenMargin marginDelta = (mLastPaintRequestMetrics.GetDisplayPortMargins()
|
ScreenMargin marginDelta = (mLastPaintRequestMetrics.GetDisplayPortMargins()
|
||||||
- aFrameMetrics.GetDisplayPortMargins());
|
- request.GetDisplayPortMargins());
|
||||||
if (fabsf(marginDelta.left) < EPSILON &&
|
if (fabsf(marginDelta.left) < EPSILON &&
|
||||||
fabsf(marginDelta.top) < EPSILON &&
|
fabsf(marginDelta.top) < EPSILON &&
|
||||||
fabsf(marginDelta.right) < EPSILON &&
|
fabsf(marginDelta.right) < EPSILON &&
|
||||||
fabsf(marginDelta.bottom) < EPSILON &&
|
fabsf(marginDelta.bottom) < EPSILON &&
|
||||||
fabsf(mLastPaintRequestMetrics.GetScrollOffset().x -
|
fabsf(mLastPaintRequestMetrics.GetScrollOffset().x -
|
||||||
aFrameMetrics.GetScrollOffset().x) < EPSILON &&
|
request.GetScrollOffset().x) < EPSILON &&
|
||||||
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
|
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
|
||||||
aFrameMetrics.GetScrollOffset().y) < EPSILON &&
|
request.GetScrollOffset().y) < EPSILON &&
|
||||||
aFrameMetrics.GetPresShellResolution() == mLastPaintRequestMetrics.GetPresShellResolution() &&
|
request.GetPresShellResolution() == mLastPaintRequestMetrics.GetPresShellResolution() &&
|
||||||
aFrameMetrics.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
|
request.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
|
||||||
fabsf(aFrameMetrics.GetViewport().Width() -
|
fabsf(request.GetViewport().Width() -
|
||||||
mLastPaintRequestMetrics.GetViewport().Width()) < EPSILON &&
|
mLastPaintRequestMetrics.GetViewport().Width()) < EPSILON &&
|
||||||
fabsf(aFrameMetrics.GetViewport().Height() -
|
fabsf(request.GetViewport().Height() -
|
||||||
mLastPaintRequestMetrics.GetViewport().Height()) < EPSILON &&
|
mLastPaintRequestMetrics.GetViewport().Height()) < EPSILON &&
|
||||||
fabsf(aFrameMetrics.GetViewport().X() -
|
fabsf(request.GetViewport().X() -
|
||||||
mLastPaintRequestMetrics.GetViewport().X()) < EPSILON &&
|
mLastPaintRequestMetrics.GetViewport().X()) < EPSILON &&
|
||||||
fabsf(aFrameMetrics.GetViewport().Y() -
|
fabsf(request.GetViewport().Y() -
|
||||||
mLastPaintRequestMetrics.GetViewport().Y()) < EPSILON &&
|
mLastPaintRequestMetrics.GetViewport().Y()) < EPSILON &&
|
||||||
aFrameMetrics.GetScrollGeneration() ==
|
request.GetScrollGeneration() ==
|
||||||
mLastPaintRequestMetrics.GetScrollGeneration() &&
|
mLastPaintRequestMetrics.GetScrollGeneration() &&
|
||||||
aFrameMetrics.GetScrollUpdateType() ==
|
request.GetScrollUpdateType() ==
|
||||||
mLastPaintRequestMetrics.GetScrollUpdateType()) {
|
mLastPaintRequestMetrics.GetScrollUpdateType()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3692,11 +3694,9 @@ AsyncPanZoomController::RequestContentRepaint(const FrameMetrics& aFrameMetrics,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(aFrameMetrics.GetScrollUpdateType() == FrameMetrics::eNone ||
|
controller->RequestContentRepaint(request);
|
||||||
aFrameMetrics.GetScrollUpdateType() == FrameMetrics::eUserAction);
|
|
||||||
controller->RequestContentRepaint(aFrameMetrics);
|
|
||||||
mExpectedGeckoMetrics = aFrameMetrics;
|
mExpectedGeckoMetrics = aFrameMetrics;
|
||||||
mLastPaintRequestMetrics = aFrameMetrics;
|
mLastPaintRequestMetrics = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||||
|
@ -4260,6 +4260,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||||
// ignore it
|
// ignore it
|
||||||
|
|
||||||
bool needContentRepaint = false;
|
bool needContentRepaint = false;
|
||||||
|
bool userAction = false;
|
||||||
bool viewportUpdated = false;
|
bool viewportUpdated = false;
|
||||||
|
|
||||||
// We usually don't entertain viewport updates on the same transaction as
|
// 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());
|
mScrollMetadata.SetOverscrollBehavior(aScrollMetadata.GetOverscrollBehavior());
|
||||||
|
|
||||||
if (scrollOffsetUpdated) {
|
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
|
// Send an acknowledgement with the new scroll generation so that any
|
||||||
// repaint requests later in this function go through.
|
// repaint requests later in this function go through.
|
||||||
// Because of the scroll generation update, any inflight paint requests are
|
// 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
|
// becomes incorrect for the purposes of calculating the LD transform. To
|
||||||
// correct this we need to update mExpectedGeckoMetrics to be the
|
// correct this we need to update mExpectedGeckoMetrics to be the
|
||||||
// last thing we know was painted by Gecko.
|
// 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();
|
mCompositedLayoutViewport = Metrics().GetViewport();
|
||||||
mCompositedScrollOffset = Metrics().GetScrollOffset();
|
mCompositedScrollOffset = Metrics().GetScrollOffset();
|
||||||
mExpectedGeckoMetrics = aLayerMetrics;
|
mExpectedGeckoMetrics = aLayerMetrics;
|
||||||
|
@ -4428,7 +4448,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||||
|
|
||||||
// See comment on the similar code in the |if (scrollOffsetUpdated)| block
|
// See comment on the similar code in the |if (scrollOffsetUpdated)| block
|
||||||
// above.
|
// above.
|
||||||
Metrics().CopySmoothScrollInfoFrom(aLayerMetrics);
|
if (gfxPrefs::APZRelativeUpdate() && aLayerMetrics.IsRelative()) {
|
||||||
|
Metrics().ApplyRelativeSmoothScrollUpdateFrom(aLayerMetrics);
|
||||||
|
} else {
|
||||||
|
Metrics().ApplySmoothScrollUpdateFrom(aLayerMetrics);
|
||||||
|
}
|
||||||
needContentRepaint = true;
|
needContentRepaint = true;
|
||||||
mExpectedGeckoMetrics = aLayerMetrics;
|
mExpectedGeckoMetrics = aLayerMetrics;
|
||||||
|
|
||||||
|
@ -4447,7 +4471,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||||
|
|
||||||
if (needContentRepaint) {
|
if (needContentRepaint) {
|
||||||
// This repaint request is not driven by a user action on the APZ side
|
// 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();
|
UpdateSharedCompositorFrameMetrics();
|
||||||
}
|
}
|
||||||
|
@ -4624,25 +4652,25 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
|
||||||
CalculatePendingDisplayPort(endZoomToMetrics, velocity));
|
CalculatePendingDisplayPort(endZoomToMetrics, velocity));
|
||||||
endZoomToMetrics.SetUseDisplayPortMargins(true);
|
endZoomToMetrics.SetUseDisplayPortMargins(true);
|
||||||
endZoomToMetrics.SetPaintRequestTime(TimeStamp::Now());
|
endZoomToMetrics.SetPaintRequestTime(TimeStamp::Now());
|
||||||
endZoomToMetrics.SetRepaintDrivenByUserAction(true);
|
|
||||||
|
|
||||||
RefPtr<GeckoContentController> controller = GetGeckoContentController();
|
RefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||||
if (!controller) {
|
if (!controller) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (controller->IsRepaintThread()) {
|
if (controller->IsRepaintThread()) {
|
||||||
RequestContentRepaint(endZoomToMetrics, velocity);
|
RequestContentRepaint(endZoomToMetrics, velocity, RepaintUpdateType::eUserAction);
|
||||||
} else {
|
} else {
|
||||||
// use a local var to resolve the function overload
|
// 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);
|
(&AsyncPanZoomController::RequestContentRepaint);
|
||||||
controller->DispatchToRepaintThread(
|
controller->DispatchToRepaintThread(
|
||||||
NewRunnableMethod<FrameMetrics, ParentLayerPoint>(
|
NewRunnableMethod<FrameMetrics, ParentLayerPoint, RepaintUpdateType>(
|
||||||
"layers::AsyncPanZoomController::ZoomToRect",
|
"layers::AsyncPanZoomController::ZoomToRect",
|
||||||
this,
|
this,
|
||||||
func,
|
func,
|
||||||
endZoomToMetrics,
|
endZoomToMetrics,
|
||||||
velocity));
|
velocity,
|
||||||
|
RepaintUpdateType::eUserAction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "CrossProcessMutex.h"
|
#include "CrossProcessMutex.h"
|
||||||
#include "mozilla/layers/GeckoContentController.h"
|
#include "mozilla/layers/GeckoContentController.h"
|
||||||
|
#include "mozilla/layers/RepaintRequest.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
#include "mozilla/Monitor.h"
|
#include "mozilla/Monitor.h"
|
||||||
|
@ -150,6 +151,8 @@ class AsyncPanZoomController {
|
||||||
|
|
||||||
typedef mozilla::MonitorAutoLock MonitorAutoLock;
|
typedef mozilla::MonitorAutoLock MonitorAutoLock;
|
||||||
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
|
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
|
||||||
|
typedef mozilla::layers::RepaintRequest::ScrollOffsetUpdateType
|
||||||
|
RepaintUpdateType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum GestureBehavior {
|
enum GestureBehavior {
|
||||||
|
@ -706,11 +709,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
void ScrollByAndClamp(const CSSPoint& aOffset);
|
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
|
* 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
|
* 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
|
* from a non-main thread, it will redispatch itself to the main thread, and
|
||||||
* use the latest metrics during the redispatch.
|
* 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
|
* Send the provided metrics to Gecko to trigger a repaint. This function
|
||||||
|
@ -816,7 +815,8 @@ protected:
|
||||||
* called on the main thread.
|
* called on the main thread.
|
||||||
*/
|
*/
|
||||||
void RequestContentRepaint(const FrameMetrics& aFrameMetrics,
|
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
|
* Gets the current frame metrics. This is *not* the Gecko copy stored in the
|
||||||
|
@ -933,8 +933,8 @@ private:
|
||||||
// sending messages back to Gecko.
|
// sending messages back to Gecko.
|
||||||
ScrollMetadata mLastContentPaintMetadata;
|
ScrollMetadata mLastContentPaintMetadata;
|
||||||
FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to mLastContentPaintMetadata.mMetrics
|
FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to mLastContentPaintMetadata.mMetrics
|
||||||
// The last metrics used for a content repaint request.
|
// The last content repaint request.
|
||||||
FrameMetrics mLastPaintRequestMetrics;
|
RepaintRequest mLastPaintRequestMetrics;
|
||||||
// The metrics that we expect content to have. This is updated when we
|
// 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.
|
// request a content repaint, and when we receive a shadow layers update.
|
||||||
// This allows us to transform events into Gecko's coordinate space.
|
// This allows us to transform events into Gecko's coordinate space.
|
||||||
|
|
|
@ -101,7 +101,7 @@ static TimeStamp GetStartupTime() {
|
||||||
|
|
||||||
class MockContentController : public GeckoContentController {
|
class MockContentController : public GeckoContentController {
|
||||||
public:
|
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(RequestFlingSnap, void(const FrameMetrics::ViewID& aScrollId, const mozilla::CSSPoint& aDestination));
|
||||||
MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
|
MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
|
||||||
MOCK_METHOD5(HandleTap, void(TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t));
|
MOCK_METHOD5(HandleTap, void(TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t));
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
[test_group_keyboard.html]
|
[test_group_keyboard.html]
|
||||||
[test_layerization.html]
|
[test_layerization.html]
|
||||||
skip-if = (os == 'android') # wheel events not supported on mobile
|
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]
|
[test_scroll_inactive_bug1190112.html]
|
||||||
skip-if = (os == 'android') # wheel events not supported on mobile
|
skip-if = (os == 'android') # wheel events not supported on mobile
|
||||||
[test_scroll_inactive_flattened_frame.html]
|
[test_scroll_inactive_flattened_frame.html]
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче