зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1408829 - Make spellCheckAfterEditorChange as noscript. r=masayuki
No one uses nsIInlineSpellChecker.spellCheckAfterEditorChange from script. So I think we can mark this interface as noscript. Since this method is scriptable, we need QI to get nsIDOMNode. If we can change to noscript, it can reduce QI to get nsIDOMNode. MozReview-Commit-ID: GC0WuFyTlaZ --HG-- extra : rebase_source : 16ca9fc548e86747ac17407be48295c709174fb5
This commit is contained in:
Родитель
302308a0a1
Коммит
7f97c4e179
|
@ -5000,12 +5000,12 @@ EditorBase::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent)
|
|||
nsresult
|
||||
EditorBase::HandleInlineSpellCheck(EditAction action,
|
||||
Selection* aSelection,
|
||||
nsIDOMNode* previousSelectedNode,
|
||||
int32_t previousSelectedOffset,
|
||||
nsIDOMNode* aStartContainer,
|
||||
int32_t aStartOffset,
|
||||
nsIDOMNode* aEndContainer,
|
||||
int32_t aEndOffset)
|
||||
nsINode* previousSelectedNode,
|
||||
uint32_t previousSelectedOffset,
|
||||
nsINode* aStartContainer,
|
||||
uint32_t aStartOffset,
|
||||
nsINode* aEndContainer,
|
||||
uint32_t aEndOffset)
|
||||
{
|
||||
// Have to cast action here because this method is from an IDL
|
||||
return mInlineSpellChecker ? mInlineSpellChecker->SpellCheckAfterEditorChange(
|
||||
|
|
|
@ -1183,12 +1183,12 @@ public:
|
|||
|
||||
nsresult HandleInlineSpellCheck(EditAction action,
|
||||
Selection* aSelection,
|
||||
nsIDOMNode* previousSelectedNode,
|
||||
int32_t previousSelectedOffset,
|
||||
nsIDOMNode* aStartContainer,
|
||||
int32_t aStartOffset,
|
||||
nsIDOMNode* aEndContainer,
|
||||
int32_t aEndOffset);
|
||||
nsINode* previousSelectedNode,
|
||||
uint32_t previousSelectedOffset,
|
||||
nsINode* aStartContainer,
|
||||
uint32_t aStartOffset,
|
||||
nsINode* aEndContainer,
|
||||
uint32_t aEndOffset);
|
||||
|
||||
virtual already_AddRefed<dom::EventTarget> GetDOMEventTarget() = 0;
|
||||
|
||||
|
|
|
@ -565,12 +565,12 @@ HTMLEditRules::AfterEditInner(EditAction action,
|
|||
nsresult rv =
|
||||
mHTMLEditor->HandleInlineSpellCheck(
|
||||
action, selection,
|
||||
GetAsDOMNode(mRangeItem->mStartContainer),
|
||||
mRangeItem->mStartContainer,
|
||||
mRangeItem->mStartOffset,
|
||||
GetAsDOMNode(rangeStartContainer),
|
||||
static_cast<int32_t>(rangeStartOffset),
|
||||
GetAsDOMNode(rangeEndContainer),
|
||||
static_cast<int32_t>(rangeEndOffset));
|
||||
rangeStartContainer,
|
||||
rangeStartOffset,
|
||||
rangeEndContainer,
|
||||
rangeEndOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// detect empty doc
|
||||
|
|
|
@ -227,7 +227,7 @@ TextEditRules::AfterEdit(EditAction action,
|
|||
NS_ENSURE_STATE(mTextEditor);
|
||||
nsresult rv =
|
||||
mTextEditor->HandleInlineSpellCheck(action, selection,
|
||||
GetAsDOMNode(mCachedSelectionNode),
|
||||
mCachedSelectionNode,
|
||||
mCachedSelectionOffset,
|
||||
nullptr, 0, nullptr, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -297,7 +297,7 @@ protected:
|
|||
// Cached selected node.
|
||||
nsCOMPtr<nsINode> mCachedSelectionNode;
|
||||
// Cached selected offset.
|
||||
int32_t mCachedSelectionOffset;
|
||||
uint32_t mCachedSelectionOffset;
|
||||
uint32_t mActionNesting;
|
||||
bool mLockRulesSniffing;
|
||||
bool mDidExplicitlySetInterline;
|
||||
|
|
|
@ -10,6 +10,11 @@ interface nsISelection;
|
|||
interface nsIEditor;
|
||||
interface nsIEditorSpellCheck;
|
||||
|
||||
%{ C++
|
||||
class nsINode;
|
||||
%}
|
||||
[ptr] native nsINodePtr(nsINode);
|
||||
|
||||
[scriptable, uuid(b7b7a77c-40c4-4196-b0b7-b0338243b3fe)]
|
||||
interface nsIInlineSpellChecker : nsISupports
|
||||
{
|
||||
|
@ -20,14 +25,15 @@ interface nsIInlineSpellChecker : nsISupports
|
|||
|
||||
attribute boolean enableRealTimeSpell;
|
||||
|
||||
void spellCheckAfterEditorChange(in long aAction,
|
||||
in nsISelection aSelection,
|
||||
in nsIDOMNode aPreviousSelectedNode,
|
||||
in long aPreviousSelectedOffset,
|
||||
in nsIDOMNode aStartNode,
|
||||
in long aStartOffset,
|
||||
in nsIDOMNode aEndNode,
|
||||
in long aEndOffset);
|
||||
[noscript] void spellCheckAfterEditorChange(
|
||||
in long aAction,
|
||||
in nsISelection aSelection,
|
||||
in nsINodePtr aPreviousSelectedNode,
|
||||
in unsigned long aPreviousSelectedOffset,
|
||||
in nsINodePtr aStartNode,
|
||||
in unsigned long aStartOffset,
|
||||
in nsINodePtr aEndNode,
|
||||
in unsigned long aEndOffset);
|
||||
|
||||
void spellCheckRange(in nsIDOMRange aSelection);
|
||||
|
||||
|
|
|
@ -115,30 +115,26 @@ mozInlineSpellStatus::mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker)
|
|||
nsresult
|
||||
mozInlineSpellStatus::InitForEditorChange(
|
||||
EditAction aAction,
|
||||
nsIDOMNode* aAnchorNode, int32_t aAnchorOffset,
|
||||
nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
|
||||
nsIDOMNode* aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode* aEndNode, int32_t aEndOffset)
|
||||
nsINode* aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode* aPreviousNode, uint32_t aPreviousOffset,
|
||||
nsINode* aStartNode, uint32_t aStartOffset,
|
||||
nsINode* aEndNode, uint32_t aEndOffset)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
rv = GetDocument(getter_AddRefs(doc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(!aAnchorNode) || NS_WARN_IF(!aPreviousNode)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// save the anchor point as a range so we can find the current word later
|
||||
rv = PositionToCollapsedRange(doc, aAnchorNode, aAnchorOffset,
|
||||
getter_AddRefs(mAnchorRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsINode> prevNode = do_QueryInterface(aPreviousNode);
|
||||
NS_ENSURE_STATE(prevNode);
|
||||
mAnchorRange = PositionToCollapsedRange(aAnchorNode, aAnchorOffset);
|
||||
if (NS_WARN_IF(!mAnchorRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool deleted = aAction == EditAction::deleteSelection;
|
||||
if (aAction == EditAction::insertIMEText) {
|
||||
// IME may remove the previous node if it cancels composition when
|
||||
// there is no text around the composition.
|
||||
deleted = !prevNode->IsInComposedDoc();
|
||||
deleted = !aPreviousNode->IsInComposedDoc();
|
||||
}
|
||||
|
||||
if (deleted) {
|
||||
|
@ -153,27 +149,27 @@ mozInlineSpellStatus::InitForEditorChange(
|
|||
mOp = eOpChange;
|
||||
|
||||
// range to check
|
||||
mRange = new nsRange(prevNode);
|
||||
mRange = new nsRange(aPreviousNode);
|
||||
|
||||
// ...we need to put the start and end in the correct order
|
||||
int16_t cmpResult;
|
||||
rv = mAnchorRange->ComparePoint(aPreviousNode, aPreviousOffset, &cmpResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ErrorResult errorResult;
|
||||
int16_t cmpResult =
|
||||
mAnchorRange->ComparePoint(*aPreviousNode, aPreviousOffset, errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return errorResult.StealNSResult();
|
||||
}
|
||||
nsresult rv;
|
||||
if (cmpResult < 0) {
|
||||
// previous anchor node is before the current anchor
|
||||
nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
|
||||
nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
|
||||
rv = mRange->SetStartAndEnd(previousNode, aPreviousOffset,
|
||||
anchorNode, aAnchorOffset);
|
||||
rv = mRange->SetStartAndEnd(aPreviousNode, aPreviousOffset,
|
||||
aAnchorNode, aAnchorOffset);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
// previous anchor node is after (or the same as) the current anchor
|
||||
nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
|
||||
nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
|
||||
rv = mRange->SetStartAndEnd(anchorNode, aAnchorOffset,
|
||||
previousNode, aPreviousOffset);
|
||||
rv = mRange->SetStartAndEnd(aAnchorNode, aAnchorOffset,
|
||||
aPreviousNode, aPreviousOffset);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -186,15 +182,19 @@ mozInlineSpellStatus::InitForEditorChange(
|
|||
|
||||
// if we were given a range, we need to expand our range to encompass it
|
||||
if (aStartNode && aEndNode) {
|
||||
rv = mRange->ComparePoint(aStartNode, aStartOffset, &cmpResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
cmpResult = mRange->ComparePoint(*aStartNode, aStartOffset, errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return errorResult.StealNSResult();
|
||||
}
|
||||
if (cmpResult < 0) { // given range starts before
|
||||
rv = mRange->SetStart(aStartNode, aStartOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mRange->ComparePoint(aEndNode, aEndOffset, &cmpResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
cmpResult = mRange->ComparePoint(*aEndNode, aEndOffset, errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return errorResult.StealNSResult();
|
||||
}
|
||||
if (cmpResult > 0) { // given range ends after
|
||||
rv = mRange->SetEnd(aEndNode, aEndOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -214,8 +214,8 @@ mozInlineSpellStatus::InitForEditorChange(
|
|||
nsresult
|
||||
mozInlineSpellStatus::InitForNavigation(
|
||||
bool aForceCheck, int32_t aNewPositionOffset,
|
||||
nsIDOMNode* aOldAnchorNode, int32_t aOldAnchorOffset,
|
||||
nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset,
|
||||
nsINode* aOldAnchorNode, uint32_t aOldAnchorOffset,
|
||||
nsINode* aNewAnchorNode, uint32_t aNewAnchorOffset,
|
||||
bool* aContinue)
|
||||
{
|
||||
mOp = eOpNavigation;
|
||||
|
@ -228,29 +228,26 @@ mozInlineSpellStatus::InitForNavigation(
|
|||
if (NS_WARN_IF(!textEditor)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsINode> root = textEditor->GetRoot();
|
||||
Element* root = textEditor->GetRoot();
|
||||
if (NS_WARN_IF(!root)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// the anchor node might not be in the DOM anymore, check
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsINode> currentAnchor = do_QueryInterface(aOldAnchorNode, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (root && currentAnchor && ! ContentIsDescendantOf(currentAnchor, root)) {
|
||||
if (root && aOldAnchorNode && ! ContentIsDescendantOf(aOldAnchorNode, root)) {
|
||||
*aContinue = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
rv = GetDocument(getter_AddRefs(doc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = PositionToCollapsedRange(doc, aOldAnchorNode, aOldAnchorOffset,
|
||||
getter_AddRefs(mOldNavigationAnchorRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = PositionToCollapsedRange(doc, aNewAnchorNode, aNewAnchorOffset,
|
||||
getter_AddRefs(mAnchorRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mOldNavigationAnchorRange =
|
||||
PositionToCollapsedRange(aOldAnchorNode, aOldAnchorOffset);
|
||||
if (NS_WARN_IF(!mOldNavigationAnchorRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mAnchorRange =
|
||||
PositionToCollapsedRange(aNewAnchorNode, aNewAnchorOffset);
|
||||
if (NS_WARN_IF(!mAnchorRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aContinue = true;
|
||||
return NS_OK;
|
||||
|
@ -430,21 +427,14 @@ mozInlineSpellStatus::FillNoCheckRangeFromAnchor(
|
|||
// Returns the nsIDOMDocument object for the document for the
|
||||
// current spellchecker.
|
||||
|
||||
nsresult
|
||||
mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument)
|
||||
already_AddRefed<nsIDocument>
|
||||
mozInlineSpellStatus::GetDocument()
|
||||
{
|
||||
*aDocument = nullptr;
|
||||
if (!mSpellChecker->mTextEditor) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc =
|
||||
mSpellChecker->mTextEditor->GetDOMDocument();
|
||||
if (NS_WARN_IF(!domDoc)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
domDoc.forget(aDocument);
|
||||
return NS_OK;
|
||||
return mSpellChecker->mTextEditor->GetDocument();
|
||||
}
|
||||
|
||||
// mozInlineSpellStatus::PositionToCollapsedRange
|
||||
|
@ -453,24 +443,23 @@ mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument)
|
|||
// position. We use ranges to store DOM positions becuase they stay
|
||||
// updated as the DOM is changed.
|
||||
|
||||
nsresult
|
||||
mozInlineSpellStatus::PositionToCollapsedRange(nsIDOMDocument* aDocument,
|
||||
nsIDOMNode* aNode,
|
||||
int32_t aOffset,
|
||||
nsRange** aRange)
|
||||
already_AddRefed<nsRange>
|
||||
mozInlineSpellStatus::PositionToCollapsedRange(nsINode* aNode,
|
||||
uint32_t aOffset)
|
||||
{
|
||||
*aRange = nullptr;
|
||||
nsCOMPtr<nsINode> documentNode = do_QueryInterface(aDocument);
|
||||
RefPtr<nsRange> range = new nsRange(documentNode);
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
nsresult rv = range->CollapseTo(node, aOffset);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
nsCOMPtr<nsIDocument> document = GetDocument();
|
||||
if (NS_WARN_IF(!document)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
range.swap(*aRange);
|
||||
return NS_OK;
|
||||
RefPtr<nsRange> range = new nsRange(document);
|
||||
|
||||
nsresult rv = range->CollapseTo(aNode, aOffset);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return range.forget();
|
||||
}
|
||||
|
||||
// mozInlineSpellResume
|
||||
|
@ -872,9 +861,9 @@ mozInlineSpellChecker::NotifyObservers(const char* aTopic,
|
|||
NS_IMETHODIMP
|
||||
mozInlineSpellChecker::SpellCheckAfterEditorChange(
|
||||
int32_t aAction, nsISelection *aSelection,
|
||||
nsIDOMNode *aPreviousSelectedNode, int32_t aPreviousSelectedOffset,
|
||||
nsIDOMNode *aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode, int32_t aEndOffset)
|
||||
nsINode *aPreviousSelectedNode, uint32_t aPreviousSelectedOffset,
|
||||
nsINode *aStartNode, uint32_t aStartOffset,
|
||||
nsINode *aEndNode, uint32_t aEndOffset)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(aSelection);
|
||||
|
@ -885,17 +874,13 @@ mozInlineSpellChecker::SpellCheckAfterEditorChange(
|
|||
// therefore, we should spellcheck for subsequent caret navigations
|
||||
mNeedsCheckAfterNavigation = true;
|
||||
|
||||
// the anchor node is the position of the caret
|
||||
nsCOMPtr<nsIDOMNode> anchorNode;
|
||||
rv = aSelection->GetAnchorNode(getter_AddRefs(anchorNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
int32_t anchorOffset;
|
||||
rv = aSelection->GetAnchorOffset(&anchorOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
RefPtr<Selection> selection = aSelection->AsSelection();
|
||||
|
||||
// the anchor node is the position of the caret
|
||||
auto status = MakeUnique<mozInlineSpellStatus>(this);
|
||||
rv = status->InitForEditorChange((EditAction)aAction,
|
||||
anchorNode, anchorOffset,
|
||||
selection->GetAnchorNode(),
|
||||
selection->AnchorOffset(),
|
||||
aPreviousSelectedNode,
|
||||
aPreviousSelectedOffset,
|
||||
aStartNode, aStartOffset,
|
||||
|
@ -1840,7 +1825,7 @@ mozInlineSpellChecker::SaveCurrentSelectionPosition()
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCurrentSelectionAnchorNode = do_QueryInterface(selection->GetFocusNode());
|
||||
mCurrentSelectionAnchorNode = selection->GetFocusNode();
|
||||
mCurrentSelectionOffset = selection->FocusOffset();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1890,8 +1875,8 @@ mozInlineSpellChecker::HandleNavigationEvent(bool aForceWordSpellCheck,
|
|||
if (! mNeedsCheckAfterNavigation)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> currentAnchorNode = mCurrentSelectionAnchorNode;
|
||||
int32_t currentAnchorOffset = mCurrentSelectionOffset;
|
||||
nsCOMPtr<nsINode> currentAnchorNode = mCurrentSelectionAnchorNode;
|
||||
uint32_t currentAnchorOffset = mCurrentSelectionOffset;
|
||||
|
||||
// now remember the new focus position resulting from the event
|
||||
rv = SaveCurrentSelectionPosition();
|
||||
|
|
|
@ -37,13 +37,13 @@ public:
|
|||
explicit mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker);
|
||||
|
||||
nsresult InitForEditorChange(EditAction aAction,
|
||||
nsIDOMNode* aAnchorNode, int32_t aAnchorOffset,
|
||||
nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
|
||||
nsIDOMNode* aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode* aEndNode, int32_t aEndOffset);
|
||||
nsINode* aAnchorNode, uint32_t aAnchorOffset,
|
||||
nsINode* aPreviousNode, uint32_t aPreviousOffset,
|
||||
nsINode* aStartNode, uint32_t aStartOffset,
|
||||
nsINode* aEndNode, uint32_t aEndOffset);
|
||||
nsresult InitForNavigation(bool aForceCheck, int32_t aNewPositionOffset,
|
||||
nsIDOMNode* aOldAnchorNode, int32_t aOldAnchorOffset,
|
||||
nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset,
|
||||
nsINode* aOldAnchorNode, uint32_t aOldAnchorOffset,
|
||||
nsINode* aNewAnchorNode, uint32_t aNewAnchorOffset,
|
||||
bool* aContinue);
|
||||
nsresult InitForSelection();
|
||||
nsresult InitForRange(nsRange* aRange);
|
||||
|
@ -109,10 +109,9 @@ protected:
|
|||
|
||||
nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
|
||||
|
||||
nsresult GetDocument(nsIDOMDocument** aDocument);
|
||||
nsresult PositionToCollapsedRange(nsIDOMDocument* aDocument,
|
||||
nsIDOMNode* aNode, int32_t aOffset,
|
||||
nsRange** aRange);
|
||||
already_AddRefed<nsIDocument> GetDocument();
|
||||
already_AddRefed<nsRange> PositionToCollapsedRange(nsINode* aNode,
|
||||
uint32_t aOffset);
|
||||
};
|
||||
|
||||
class mozInlineSpellChecker final : public nsIInlineSpellChecker,
|
||||
|
@ -151,8 +150,8 @@ private:
|
|||
|
||||
// we need to keep track of the current text position in the document
|
||||
// so we can spell check the old word when the user clicks around the document.
|
||||
nsCOMPtr<nsIDOMNode> mCurrentSelectionAnchorNode;
|
||||
int32_t mCurrentSelectionOffset;
|
||||
nsCOMPtr<nsINode> mCurrentSelectionAnchorNode;
|
||||
uint32_t mCurrentSelectionOffset;
|
||||
|
||||
// Tracks the number of pending spell checks *and* async operations that may
|
||||
// lead to spell checks, like updating the current dictionary. This is
|
||||
|
|
Загрузка…
Ссылка в новой задаче