Bug 1713050 - P1: Add granularity to selection change notification. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D139745
This commit is contained in:
Eitan Isaacson 2022-03-16 05:56:25 +00:00
Родитель ccfc2564d5
Коммит d4418e9378
10 изменённых файлов: 35 добавлений и 12 удалений

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

@ -157,8 +157,8 @@ void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) {
NS_IMETHODIMP
SelectionManager::NotifySelectionChanged(dom::Document* aDocument,
Selection* aSelection,
int16_t aReason) {
Selection* aSelection, int16_t aReason,
int32_t aAmount) {
if (NS_WARN_IF(!aDocument) || NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}

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

@ -3198,6 +3198,8 @@ void Selection::NotifySelectionListeners() {
reason |= nsISelectionListener::JS_REASON;
}
int32_t amount = static_cast<int32_t>(frameSelection->GetCaretMoveAmount());
if (mNotifyAutoCopy) {
AutoCopyListener::OnSelectionChange(doc, *this, reason);
}
@ -3218,7 +3220,7 @@ void Selection::NotifySelectionListeners() {
//
// This can go away once
// https://bugzilla.mozilla.org/show_bug.cgi?id=1620312 is fixed.
MOZ_KnownLive(listener)->NotifySelectionChanged(doc, this, reason);
MOZ_KnownLive(listener)->NotifySelectionChanged(doc, this, reason, amount);
}
}

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

@ -24,9 +24,21 @@ interface nsISelectionListener : nsISupports
// of Selection API or Range API.
const short JS_REASON=256;
// Values of nsSelectionAmount.
// Reflects the granularity in which the selection caret has moved.
const long CHARACTER_AMOUNT = 0;
const long CLUSTER_AMOUNT = 1;
const long WORD_AMOUNT = 2;
const long WORDNOSPACE_AMOUNT = 3;
const long LINE_AMOUNT = 4;
const long BEGINLINE_AMOUNT = 5;
const long ENDLINE_AMOUNT = 6;
const long NO_AMOUNT = 7;
const long PARAGRAPH_AMOUNT = 8;
[can_run_script]
void notifySelectionChanged(in Document doc, in Selection sel,
in short reason);
in short reason, in long amount);
};
%{C++

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

@ -2178,7 +2178,8 @@ nsresult EditorBase::DeleteNodeWithTransaction(nsIContent& aContent) {
NS_IMETHODIMP EditorBase::NotifySelectionChanged(Document* aDocument,
Selection* aSelection,
int16_t aReason) {
int16_t aReason,
int32_t aAmount) {
if (NS_WARN_IF(!aDocument) || NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}

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

@ -554,7 +554,8 @@ bool HTMLEditor::UpdateMetaCharsetWithTransaction(
NS_IMETHODIMP HTMLEditor::NotifySelectionChanged(Document* aDocument,
Selection* aSelection,
int16_t aReason) {
int16_t aReason,
int32_t aAmount) {
if (NS_WARN_IF(!aDocument) || NS_WARN_IF(!aSelection)) {
return NS_ERROR_INVALID_ARG;
}
@ -593,8 +594,8 @@ NS_IMETHODIMP HTMLEditor::NotifySelectionChanged(Document* aDocument,
updater->OnSelectionChange();
}
nsresult rv =
EditorBase::NotifySelectionChanged(aDocument, aSelection, aReason);
nsresult rv = EditorBase::NotifySelectionChanged(aDocument, aSelection,
aReason, aAmount);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::NotifySelectionChanged() failed");
return rv;

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

@ -37,7 +37,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1053048
// synthesizing the key press. So, we don't need to check whether a
// notification actually comes here.
let selectionListener = {
notifySelectionChanged(aDocument, aSelection, aReason) {
notifySelectionChanged(aDocument, aSelection, aReason, aAmount) {
ok(true, "selectionStart: " + textarea.selectionStart);
ok(true, "selectionEnd: " + textarea.selectionEnd);
},

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

@ -569,8 +569,8 @@ void nsCaret::PaintCaret(DrawTarget& aDrawTarget, nsIFrame* aForFrame,
}
NS_IMETHODIMP
nsCaret::NotifySelectionChanged(Document*, Selection* aDomSel,
int16_t aReason) {
nsCaret::NotifySelectionChanged(Document*, Selection* aDomSel, int16_t aReason,
int32_t aAmount) {
// Note that aDomSel, per the comment below may not be the same as our
// selection, but that's OK since if that is the case, it wouldn't have
// mattered what IsVisible() returns here, so we just opt for checking

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

@ -2824,7 +2824,7 @@ NS_IMETHODIMP nsDocumentViewer::GetInImage(bool* aInImage) {
}
NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(
Document*, Selection*, int16_t aReason) {
Document*, Selection*, int16_t aReason, int32_t aAmount) {
if (!mDocViewer) {
return NS_OK;
}

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

@ -729,6 +729,8 @@ nsresult nsFrameSelection::MoveCaret(nsDirection aDirection,
SetChangeReasons(nsISelectionListener::KEYPRESS_REASON);
}
mCaretMoveAmount = aAmount;
AutoPrepareFocusRange prep(sel, false);
// we must keep this around and revalidate it when its just UP/DOWN
@ -2170,6 +2172,7 @@ void nsFrameSelection::EndBatchChanges(const char* aRequesterFuncName,
if (mBatching.mCounter == 0 && mBatching.mChangesDuringBatching) {
AddChangeReasons(aReasons);
mCaretMoveAmount = eSelectNoAmount;
mBatching.mChangesDuringBatching = false;
// Be aware, the Selection instance may be destroyed after this call.
NotifySelectionListeners(SelectionType::eNormal);
@ -2182,6 +2185,7 @@ nsresult nsFrameSelection::NotifySelectionListeners(
if (index >= 0 && mDomSelections[index]) {
RefPtr<Selection> selection = mDomSelections[index];
selection->NotifySelectionListeners();
mCaretMoveAmount = eSelectNoAmount;
return NS_OK;
}
return NS_ERROR_FAILURE;

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

@ -829,6 +829,8 @@ class nsFrameSelection final {
return retval;
}
nsSelectionAmount GetCaretMoveAmount() { return mCaretMoveAmount; }
bool IsUserSelectionReason() const {
return (mSelectionChangeReasons &
(nsISelectionListener::DRAG_REASON |
@ -1047,6 +1049,7 @@ class nsFrameSelection final {
int16_t mSelectionChangeReasons = nsISelectionListener::NO_REASON;
// For visual display purposes.
int16_t mDisplaySelection = nsISelectionController::SELECTION_OFF;
nsSelectionAmount mCaretMoveAmount = eSelectNoAmount;
struct Caret {
// Hint to tell if the selection is at the end of this line or beginning of