mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
Bug 1077515 - part 6 - Create a new nsISelectionController::PhysicalMove command. r=roc
This commit is contained in:
parent
9fd75be794
commit
74d961eaf3
@ -16,7 +16,7 @@ interface nsIDOMNode;
|
||||
interface nsISelection;
|
||||
interface nsISelectionDisplay;
|
||||
|
||||
[scriptable, uuid(b1ff7faa-8097-431d-b7f1-b0615e3cd596)]
|
||||
[scriptable, uuid(7835DE46-DB36-4BB7-8684-1049A0C13049)]
|
||||
interface nsISelectionController : nsISelectionDisplay
|
||||
{
|
||||
const short SELECTION_NONE=0;
|
||||
@ -143,6 +143,26 @@ interface nsISelectionController : nsISelectionDisplay
|
||||
*/
|
||||
void characterMove(in boolean forward, in boolean extend);
|
||||
|
||||
/** PhysicalMove will move the selection one "unit" in a given direction
|
||||
* within the document.
|
||||
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
|
||||
* the "point" of selection that is extended is considered the "focus" point.
|
||||
* or the last point adjusted by the selection.
|
||||
* @param aDirection
|
||||
* @param aAmount character/line; word/lineBoundary
|
||||
* @param aExtend should it collapse the selection of extend it?
|
||||
*/
|
||||
void physicalMove(in short direction, in short amount, in boolean extend);
|
||||
|
||||
/**
|
||||
* nsFrameSelection::PhysicalMove depends on the ordering of these values;
|
||||
* do not change without checking there!
|
||||
*/
|
||||
const short MOVE_LEFT = 0;
|
||||
const short MOVE_RIGHT = 1;
|
||||
const short MOVE_UP = 2;
|
||||
const short MOVE_DOWN = 3;
|
||||
|
||||
/**
|
||||
* CharacterExtendForDelete will extend the selection one character cell
|
||||
* forward in the document.
|
||||
|
@ -227,6 +227,7 @@ public:
|
||||
NS_IMETHOD GetCaretEnabled(bool *_retval);
|
||||
NS_IMETHOD GetCaretVisible(bool *_retval);
|
||||
NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility);
|
||||
NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) MOZ_OVERRIDE;
|
||||
NS_IMETHOD CharacterMove(bool aForward, bool aExtend);
|
||||
NS_IMETHOD CharacterExtendForDelete();
|
||||
NS_IMETHOD CharacterExtendForBackspace();
|
||||
@ -445,6 +446,15 @@ nsTextInputSelectionImpl::SetCaretVisibilityDuringSelection(bool aVisibility)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::PhysicalMove(int16_t aDirection, int16_t aAmount,
|
||||
bool aExtend)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->PhysicalMove(aDirection, aAmount, aExtend);
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::CharacterMove(bool aForward, bool aExtend)
|
||||
{
|
||||
|
@ -2303,6 +2303,12 @@ NS_IMETHODIMP PresShell::GetSelectionFlags(int16_t *aOutEnable)
|
||||
|
||||
//implementation of nsISelectionController
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend)
|
||||
{
|
||||
return mSelection->PhysicalMove(aDirection, aAmount, aExtend);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::CharacterMove(bool aForward, bool aExtend)
|
||||
{
|
||||
|
@ -249,6 +249,7 @@ public:
|
||||
|
||||
// nsISelectionController
|
||||
|
||||
NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) MOZ_OVERRIDE;
|
||||
NS_IMETHOD CharacterMove(bool aForward, bool aExtend) MOZ_OVERRIDE;
|
||||
NS_IMETHOD CharacterExtendForDelete() MOZ_OVERRIDE;
|
||||
NS_IMETHOD CharacterExtendForBackspace() MOZ_OVERRIDE;
|
||||
|
@ -415,6 +415,16 @@ public:
|
||||
*/
|
||||
virtual void UndefineCaretBidiLevel();
|
||||
|
||||
/** PhysicalMove will generally be called from the nsiselectioncontroller implementations.
|
||||
* the effect being the selection will move one unit 'aAmount' in the
|
||||
* given aDirection.
|
||||
* @param aDirection the direction to move the selection
|
||||
* @param aAmount amount of movement (char/line; word/page; eol/doc)
|
||||
* @param aExtend continue selection
|
||||
*/
|
||||
/*unsafe*/
|
||||
nsresult PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend);
|
||||
|
||||
/** CharacterMove will generally be called from the nsiselectioncontroller implementations.
|
||||
* the effect being the selection will move one character left or right.
|
||||
* @param aForward move forward in document.
|
||||
|
@ -1897,6 +1897,96 @@ nsFrameSelection::CommonPageMove(bool aForward,
|
||||
offsets.offset, aExtend, false, CARET_ASSOCIATE_AFTER);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameSelection::PhysicalMove(int16_t aDirection, int16_t aAmount,
|
||||
bool aExtend)
|
||||
{
|
||||
NS_ENSURE_STATE(mShell);
|
||||
// Flush out layout, since we need it to be up to date to do caret
|
||||
// positioning.
|
||||
mShell->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
if (!mShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check that parameters are safe
|
||||
if (aDirection < 0 || aDirection > 3 || aAmount < 0 || aAmount > 1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsPresContext *context = mShell->GetPresContext();
|
||||
if (!context) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
|
||||
nsRefPtr<Selection> sel = mDomSelections[index];
|
||||
if (!sel) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Map the abstract movement amounts (0-1) to direction-specific
|
||||
// selection units.
|
||||
static const nsSelectionAmount inlineAmount[] =
|
||||
{ eSelectCluster, eSelectWord };
|
||||
static const nsSelectionAmount blockPrevAmount[] =
|
||||
{ eSelectLine, eSelectBeginLine };
|
||||
static const nsSelectionAmount blockNextAmount[] =
|
||||
{ eSelectLine, eSelectEndLine };
|
||||
|
||||
struct PhysicalToLogicalMapping {
|
||||
nsDirection direction;
|
||||
const nsSelectionAmount *amounts;
|
||||
};
|
||||
static const PhysicalToLogicalMapping verticalLR[4] = {
|
||||
{ eDirPrevious, blockPrevAmount }, // left
|
||||
{ eDirNext, blockNextAmount }, // right
|
||||
{ eDirPrevious, inlineAmount }, // up
|
||||
{ eDirNext, inlineAmount } // down
|
||||
};
|
||||
static const PhysicalToLogicalMapping verticalRL[4] = {
|
||||
{ eDirNext, blockNextAmount },
|
||||
{ eDirPrevious, blockPrevAmount },
|
||||
{ eDirPrevious, inlineAmount },
|
||||
{ eDirNext, inlineAmount }
|
||||
};
|
||||
static const PhysicalToLogicalMapping horizontal[4] = {
|
||||
{ eDirPrevious, inlineAmount },
|
||||
{ eDirNext, inlineAmount },
|
||||
{ eDirPrevious, blockPrevAmount },
|
||||
{ eDirNext, blockNextAmount }
|
||||
};
|
||||
|
||||
WritingMode wm;
|
||||
nsIFrame *frame = nullptr;
|
||||
int32_t offsetused = 0;
|
||||
if (NS_SUCCEEDED(sel->GetPrimaryFrameForFocusNode(&frame, &offsetused,
|
||||
true))) {
|
||||
if (frame) {
|
||||
wm = frame->GetWritingMode();
|
||||
}
|
||||
}
|
||||
|
||||
const PhysicalToLogicalMapping& mapping =
|
||||
wm.IsVertical()
|
||||
? wm.IsVerticalLR() ? verticalLR[aDirection] : verticalRL[aDirection]
|
||||
: horizontal[aDirection];
|
||||
|
||||
nsresult rv = MoveCaret(mapping.direction, aExtend, mapping.amounts[aAmount],
|
||||
eVisual);
|
||||
if (NS_FAILED(rv)) {
|
||||
// If we tried to do a line move, but couldn't move in the given direction,
|
||||
// then we'll "promote" this to a line-edge move instead.
|
||||
if (mapping.amounts[aAmount] == eSelectLine) {
|
||||
rv = MoveCaret(mapping.direction, aExtend, mapping.amounts[aAmount + 1],
|
||||
eVisual);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameSelection::CharacterMove(bool aForward, bool aExtend)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user