зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1077515 - part 7 - Support physical caret movement and selection commands in nsGlobalWindowCommands. r=roc
This commit is contained in:
Родитель
74d961eaf3
Коммит
2476fc58fc
|
@ -83,6 +83,24 @@ const char * const sSelectPageDownString = "cmd_selectPageDown";
|
|||
const char * const sSelectTopString = "cmd_selectTop";
|
||||
const char * const sSelectBottomString = "cmd_selectBottom";
|
||||
|
||||
// Physical-direction movement and selection commands
|
||||
const char * const sMoveLeftString = "cmd_moveLeft";
|
||||
const char * const sMoveRightString = "cmd_moveRight";
|
||||
const char * const sMoveUpString = "cmd_moveUp";
|
||||
const char * const sMoveDownString = "cmd_moveDown";
|
||||
const char * const sMoveLeft2String = "cmd_moveLeft2";
|
||||
const char * const sMoveRight2String = "cmd_moveRight2";
|
||||
const char * const sMoveUp2String = "cmd_moveUp2";
|
||||
const char * const sMoveDown2String = "cmd_moveDown2";
|
||||
|
||||
const char * const sSelectLeftString = "cmd_selectLeft";
|
||||
const char * const sSelectRightString = "cmd_selectRight";
|
||||
const char * const sSelectUpString = "cmd_selectUp";
|
||||
const char * const sSelectDownString = "cmd_selectDown";
|
||||
const char * const sSelectLeft2String = "cmd_selectLeft2";
|
||||
const char * const sSelectRight2String = "cmd_selectRight2";
|
||||
const char * const sSelectUp2String = "cmd_selectUp2";
|
||||
const char * const sSelectDown2String = "cmd_selectDown2";
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
|
@ -116,6 +134,16 @@ public:
|
|||
// no member variables, please, we're stateless!
|
||||
};
|
||||
|
||||
// this class implements physical-movement versions of the above
|
||||
class nsPhysicalSelectMoveScrollCommand : public nsSelectionCommandsBase
|
||||
{
|
||||
public:
|
||||
|
||||
NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
|
||||
|
||||
// no member variables, please, we're stateless!
|
||||
};
|
||||
|
||||
// this class implements other selection commands
|
||||
class nsSelectCommand : public nsSelectionCommandsBase
|
||||
{
|
||||
|
@ -126,6 +154,16 @@ public:
|
|||
// no member variables, please, we're stateless!
|
||||
};
|
||||
|
||||
// this class implements physical-movement versions of selection commands
|
||||
class nsPhysicalSelectCommand : public nsSelectionCommandsBase
|
||||
{
|
||||
public:
|
||||
|
||||
NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
|
||||
|
||||
// no member variables, please, we're stateless!
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
@ -194,6 +232,39 @@ nsSelectionCommandsBase::GetSelectionControllerFromWindow(nsPIDOMWindow *aWindow
|
|||
#pragma mark -
|
||||
#endif
|
||||
|
||||
// Helpers for nsSelectMoveScrollCommand and nsPhysicalSelectMoveScrollCommand
|
||||
static void
|
||||
AdjustFocusAfterCaretMove(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
// adjust the focus to the new caret position
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
nsCOMPtr<nsIDOMElement> result;
|
||||
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
||||
nsIFocusManager::FLAG_NOSCROLL, getter_AddRefs(result));
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsCaretOnInWindow(nsPIDOMWindow* aWindow, nsISelectionController* aSelCont)
|
||||
{
|
||||
// We allow the caret to be moved with arrow keys on any window for which
|
||||
// the caret is enabled. In particular, this includes caret-browsing mode
|
||||
// in non-chrome documents.
|
||||
bool caretOn = false;
|
||||
aSelCont->GetCaretEnabled(&caretOn);
|
||||
if (!caretOn) {
|
||||
caretOn = Preferences::GetBool("accessibility.browsewithcaret");
|
||||
if (caretOn) {
|
||||
nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
|
||||
if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
caretOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return caretOn;
|
||||
}
|
||||
|
||||
static const struct BrowseCommand {
|
||||
const char *reverse, *forward;
|
||||
nsresult (NS_STDCALL nsISelectionController::*scroll)(bool);
|
||||
|
@ -235,85 +306,158 @@ nsSelectMoveScrollCommand::DoCommand(const char *aCommandName, nsISupports *aCom
|
|||
GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
|
||||
NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// We allow the caret to be moved with arrow keys on any window for which
|
||||
// the caret is enabled. In particular, this includes caret-browsing mode
|
||||
// in non-chrome documents.
|
||||
bool caretOn = false;
|
||||
selCont->GetCaretEnabled(&caretOn);
|
||||
if (!caretOn) {
|
||||
caretOn = Preferences::GetBool("accessibility.browsewithcaret");
|
||||
if (caretOn) {
|
||||
nsCOMPtr<nsIDocShell> docShell = piWindow->GetDocShell();
|
||||
if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
caretOn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool caretOn = IsCaretOnInWindow(piWindow, selCont);
|
||||
|
||||
for (size_t i = 0; i < ArrayLength(browseCommands); i++) {
|
||||
bool forward = !strcmp(aCommandName, browseCommands[i].forward);
|
||||
if (forward || !strcmp(aCommandName, browseCommands[i].reverse)) {
|
||||
if (caretOn && browseCommands[i].move &&
|
||||
NS_SUCCEEDED((selCont->*(browseCommands[i].move))(forward, false))) {
|
||||
// adjust the focus to the new caret position
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
nsCOMPtr<nsIDOMElement> result;
|
||||
fm->MoveFocus(piWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
||||
nsIFocusManager::FLAG_NOSCROLL,
|
||||
getter_AddRefs(result));
|
||||
}
|
||||
AdjustFocusAfterCaretMove(piWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
return (selCont->*(browseCommands[i].scroll))(forward);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
// XXX It's not clear to me yet how we should handle the "scroll" option
|
||||
// for these commands; for now, I'm mapping them back to ScrollCharacter,
|
||||
// ScrollLine, etc., as if for horizontal-mode content, but this may need
|
||||
// to be reconsidered once we have more experience with vertical content.
|
||||
static const struct PhysicalBrowseCommand {
|
||||
const char *command;
|
||||
int16_t direction, amount;
|
||||
nsresult (NS_STDCALL nsISelectionController::*scroll)(bool);
|
||||
} physicalBrowseCommands[] = {
|
||||
{ sMoveLeftString, nsISelectionController::MOVE_LEFT, 0,
|
||||
&nsISelectionController::ScrollCharacter },
|
||||
{ sMoveRightString, nsISelectionController::MOVE_RIGHT, 0,
|
||||
&nsISelectionController::ScrollCharacter },
|
||||
{ sMoveUpString, nsISelectionController::MOVE_UP, 0,
|
||||
&nsISelectionController::ScrollLine },
|
||||
{ sMoveDownString, nsISelectionController::MOVE_DOWN, 0,
|
||||
&nsISelectionController::ScrollLine },
|
||||
{ sMoveLeft2String, nsISelectionController::MOVE_LEFT, 1,
|
||||
&nsISelectionController::ScrollCharacter },
|
||||
{ sMoveRight2String, nsISelectionController::MOVE_RIGHT, 1,
|
||||
&nsISelectionController::ScrollCharacter },
|
||||
{ sMoveUp2String, nsISelectionController::MOVE_UP, 1,
|
||||
&nsISelectionController::CompleteScroll },
|
||||
{ sMoveDown2String, nsISelectionController::MOVE_DOWN, 1,
|
||||
&nsISelectionController::CompleteScroll },
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsSelectCommand::DoCommand(const char *aCommandName, nsISupports *aCommandContext)
|
||||
nsPhysicalSelectMoveScrollCommand::DoCommand(const char *aCommandName,
|
||||
nsISupports *aCommandContext)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(aCommandContext));
|
||||
nsCOMPtr<nsISelectionController> selCont;
|
||||
GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
|
||||
NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
bool caretOn = IsCaretOnInWindow(piWindow, selCont);
|
||||
|
||||
for (size_t i = 0; i < ArrayLength(physicalBrowseCommands); i++) {
|
||||
const PhysicalBrowseCommand& cmd = physicalBrowseCommands[i];
|
||||
if (!strcmp(aCommandName, cmd.command)) {
|
||||
int16_t dir = cmd.direction;
|
||||
if (caretOn &&
|
||||
NS_SUCCEEDED(selCont->PhysicalMove(dir, cmd.amount, false))) {
|
||||
AdjustFocusAfterCaretMove(piWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool forward = (dir == nsISelectionController::MOVE_RIGHT ||
|
||||
dir == nsISelectionController::MOVE_DOWN);
|
||||
return (selCont->*(cmd.scroll))(forward);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
static const struct SelectCommand {
|
||||
const char *reverse, *forward;
|
||||
nsresult (NS_STDCALL nsISelectionController::*select)(bool, bool);
|
||||
} selectCommands[] = {
|
||||
{ sSelectCharPreviousString, sSelectCharNextString,
|
||||
&nsISelectionController::CharacterMove },
|
||||
{ sSelectWordPreviousString, sSelectWordNextString,
|
||||
&nsISelectionController::WordMove },
|
||||
{ sSelectBeginLineString, sSelectEndLineString,
|
||||
&nsISelectionController::IntraLineMove },
|
||||
{ sSelectLinePreviousString, sSelectLineNextString,
|
||||
&nsISelectionController::LineMove },
|
||||
{ sSelectPageUpString, sSelectPageDownString,
|
||||
&nsISelectionController::PageMove },
|
||||
{ sSelectTopString, sSelectBottomString,
|
||||
&nsISelectionController::CompleteMove }
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsSelectCommand::DoCommand(const char *aCommandName,
|
||||
nsISupports *aCommandContext)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(aCommandContext));
|
||||
nsCOMPtr<nsISelectionController> selCont;
|
||||
GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
|
||||
NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// These commands are so the browser can use caret navigation key bindings -
|
||||
// Helps with accessibility - aaronl@netscape.com
|
||||
if (!nsCRT::strcmp(aCommandName, sSelectCharPreviousString))
|
||||
rv = selCont->CharacterMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectCharNextString))
|
||||
rv = selCont->CharacterMove(true, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectWordPreviousString))
|
||||
rv = selCont->WordMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectWordNextString))
|
||||
rv = selCont->WordMove(true, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectBeginLineString))
|
||||
rv = selCont->IntraLineMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectEndLineString))
|
||||
rv = selCont->IntraLineMove(true, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectLinePreviousString))
|
||||
rv = selCont->LineMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectLineNextString))
|
||||
rv = selCont->LineMove(true, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectPageUpString))
|
||||
rv = selCont->PageMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectPageDownString))
|
||||
rv = selCont->PageMove(true, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectTopString))
|
||||
rv = selCont->CompleteMove(false, true);
|
||||
else if (!nsCRT::strcmp(aCommandName, sSelectBottomString))
|
||||
rv = selCont->CompleteMove(true, true);
|
||||
for (size_t i = 0; i < ArrayLength(selectCommands); i++) {
|
||||
bool forward = !strcmp(aCommandName, selectCommands[i].forward);
|
||||
if (forward || !strcmp(aCommandName, selectCommands[i].reverse)) {
|
||||
return (selCont->*(selectCommands[i].select))(forward, true);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return rv;
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
static const struct PhysicalSelectCommand {
|
||||
const char *command;
|
||||
int16_t direction, amount;
|
||||
} physicalSelectCommands[] = {
|
||||
{ sSelectLeftString, nsISelectionController::MOVE_LEFT, 0 },
|
||||
{ sSelectRightString, nsISelectionController::MOVE_RIGHT, 0 },
|
||||
{ sSelectUpString, nsISelectionController::MOVE_UP, 0 },
|
||||
{ sSelectDownString, nsISelectionController::MOVE_DOWN, 0 },
|
||||
{ sSelectLeft2String, nsISelectionController::MOVE_LEFT, 1 },
|
||||
{ sSelectRight2String, nsISelectionController::MOVE_RIGHT, 1 },
|
||||
{ sSelectUp2String, nsISelectionController::MOVE_UP, 1 },
|
||||
{ sSelectDown2String, nsISelectionController::MOVE_DOWN, 1 }
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsPhysicalSelectCommand::DoCommand(const char *aCommandName,
|
||||
nsISupports *aCommandContext)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(aCommandContext));
|
||||
nsCOMPtr<nsISelectionController> selCont;
|
||||
GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
|
||||
NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
for (size_t i = 0; i < ArrayLength(physicalSelectCommands); i++) {
|
||||
if (!strcmp(aCommandName, physicalSelectCommands[i].command)) {
|
||||
return selCont->PhysicalMove(physicalSelectCommands[i].direction,
|
||||
physicalSelectCommands[i].amount,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -868,6 +1012,15 @@ nsWindowCommandRegistration::RegisterWindowCommands(
|
|||
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sCharPreviousString);
|
||||
NS_REGISTER_LAST_COMMAND(nsSelectMoveScrollCommand, sCharNextString);
|
||||
|
||||
NS_REGISTER_FIRST_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveLeftString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveRightString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveUpString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveDownString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveLeft2String);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveRight2String);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveUp2String);
|
||||
NS_REGISTER_LAST_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveDown2String);
|
||||
|
||||
NS_REGISTER_FIRST_COMMAND(nsSelectCommand, sSelectCharPreviousString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectCharNextString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectWordPreviousString);
|
||||
|
@ -881,6 +1034,15 @@ nsWindowCommandRegistration::RegisterWindowCommands(
|
|||
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectTopString);
|
||||
NS_REGISTER_LAST_COMMAND(nsSelectCommand, sSelectBottomString);
|
||||
|
||||
NS_REGISTER_FIRST_COMMAND(nsPhysicalSelectCommand, sSelectLeftString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectRightString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectUpString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectDownString);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectLeft2String);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectRight2String);
|
||||
NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectUp2String);
|
||||
NS_REGISTER_LAST_COMMAND(nsPhysicalSelectCommand, sSelectDown2String);
|
||||
|
||||
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_cut");
|
||||
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copy");
|
||||
NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_paste");
|
||||
|
|
Загрузка…
Ссылка в новой задаче