mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1574852 - part 104: Move TextEditRules::WillInsertText()
to TextEditor
and make HTMLEditor::WillInsertText()
override it r=m_kato
And also this patch moves `TextEditRules::HandleNewLines()` and `TextEditRules::DontEchoPassword()` to `TextEditor`. Differential Revision: https://phabricator.services.mozilla.com/D45298 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
1a291f1700
commit
f521a40385
@ -401,8 +401,9 @@ class HyperTextAccessible : public AccessibleWrap {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EditableTextAccessible
|
||||
|
||||
void ReplaceText(const nsAString& aText);
|
||||
void InsertText(const nsAString& aText, int32_t aPosition);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void ReplaceText(const nsAString& aText);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void InsertText(const nsAString& aText,
|
||||
int32_t aPosition);
|
||||
void CopyText(int32_t aStartPos, int32_t aEndPos);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void CutText(int32_t aStartPos, int32_t aEndPos);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DeleteText(int32_t aStartPos,
|
||||
|
@ -507,10 +507,6 @@ class EditorBase : public nsIEditor,
|
||||
return (mFlags & nsIPlaintextEditor::eEditorAllowInteraction) != 0;
|
||||
}
|
||||
|
||||
bool DontEchoPassword() const {
|
||||
return (mFlags & nsIPlaintextEditor::eEditorDontEchoPassword) != 0;
|
||||
}
|
||||
|
||||
bool ShouldSkipSpellCheck() const {
|
||||
return (mFlags & nsIPlaintextEditor::eEditorSkipSpellCheck) != 0;
|
||||
}
|
||||
|
@ -777,12 +777,6 @@ nsresult HTMLEditRules::WillDoAction(EditSubActionInfo& aInfo, bool* aCancel,
|
||||
}
|
||||
|
||||
switch (aInfo.mEditSubAction) {
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
TextEditorRef().UndefineCaretBidiLevel();
|
||||
return MOZ_KnownLive(HTMLEditorRef())
|
||||
.WillInsertText(aInfo.mEditSubAction, aCancel, aHandled,
|
||||
aInfo.inString, aInfo.outString, aInfo.maxLength);
|
||||
case EditSubAction::eDeleteSelectedContent:
|
||||
result = MOZ_KnownLive(HTMLEditorRef())
|
||||
.HandleDeleteSelection(aInfo.collapsedAction,
|
||||
@ -809,6 +803,8 @@ nsresult HTMLEditRules::WillDoAction(EditSubActionInfo& aInfo, bool* aCancel,
|
||||
case EditSubAction::eIndent:
|
||||
case EditSubAction::eInsertHTMLSource:
|
||||
case EditSubAction::eInsertParagraphSeparator:
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
case EditSubAction::eOutdent:
|
||||
case EditSubAction::eUndo:
|
||||
case EditSubAction::eRedo:
|
||||
@ -832,9 +828,6 @@ nsresult HTMLEditRules::DidDoAction(EditSubActionInfo& aInfo,
|
||||
AutoSafeEditorData setData(*this, *mHTMLEditor);
|
||||
|
||||
switch (aInfo.mEditSubAction) {
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
return NS_OK;
|
||||
case EditSubAction::eInsertElement:
|
||||
case EditSubAction::eInsertQuotedText:
|
||||
return NS_OK;
|
||||
@ -848,6 +841,8 @@ nsresult HTMLEditRules::DidDoAction(EditSubActionInfo& aInfo,
|
||||
case EditSubAction::eInsertHTMLSource:
|
||||
case EditSubAction::eInsertLineBreak:
|
||||
case EditSubAction::eInsertParagraphSeparator:
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
case EditSubAction::eOutdent:
|
||||
case EditSubAction::eUndo:
|
||||
case EditSubAction::eRedo:
|
||||
@ -1379,47 +1374,47 @@ nsresult HTMLEditor::WillInsert(bool* aCancel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
bool* aHandled, const nsAString* inString,
|
||||
nsAString* outString, int32_t aMaxLength) {
|
||||
EditActionResult HTMLEditor::HandleInsertText(
|
||||
EditSubAction aEditSubAction, const nsAString& aInsertionString) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
MOZ_ASSERT(aEditSubAction == EditSubAction::eInsertText ||
|
||||
aEditSubAction == EditSubAction::eInsertTextComingFromIME);
|
||||
|
||||
if (NS_WARN_IF(!aCancel) || NS_WARN_IF(!aHandled)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
EditActionResult result = CanHandleHTMLEditSubAction();
|
||||
if (NS_WARN_IF(result.Failed()) || result.Canceled()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// initialize out param
|
||||
*aCancel = false;
|
||||
*aHandled = true;
|
||||
UndefineCaretBidiLevel();
|
||||
|
||||
// If the selection isn't collapsed, delete it. Don't delete existing inline
|
||||
// tags, because we're hopefully going to insert text (bug 787432).
|
||||
if (!SelectionRefPtr()->IsCollapsed()) {
|
||||
nsresult rv =
|
||||
DeleteSelectionAsSubAction(nsIEditor::eNone, nsIEditor::eNoStrip);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
}
|
||||
|
||||
// FYI: Ignore cancel result of WillInsert().
|
||||
nsresult rv = WillInsert();
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WillInsert() failed");
|
||||
|
||||
// we need to get the doc
|
||||
RefPtr<Document> doc = GetDocument();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
RefPtr<Document> document = GetDocument();
|
||||
if (NS_WARN_IF(!document)) {
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RefPtr<nsRange> firstRange = SelectionRefPtr()->GetRangeAt(0);
|
||||
if (NS_WARN_IF(!firstRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// for every property that is set, insert a new inline style node
|
||||
@ -1427,24 +1422,24 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
// it should just return the insertion point instead.
|
||||
rv = CreateStyleForInsertText(*firstRange);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
firstRange = SelectionRefPtr()->GetRangeAt(0);
|
||||
if (NS_WARN_IF(!firstRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
EditorDOMPoint pointToInsert(firstRange->StartRef());
|
||||
if (NS_WARN_IF(!pointToInsert.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
MOZ_ASSERT(pointToInsert.IsSetAndValid());
|
||||
|
||||
// dont put text in places that can't have it
|
||||
if (!EditorBase::IsTextNode(pointToInsert.GetContainer()) &&
|
||||
!CanContainTag(*pointToInsert.GetContainer(), *nsGkAtoms::textTagName)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (aEditSubAction == EditSubAction::eInsertTextComingFromIME) {
|
||||
@ -1453,17 +1448,18 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
compositionStartPoint = pointToInsert;
|
||||
}
|
||||
|
||||
if (inString->IsEmpty()) {
|
||||
if (aInsertionString.IsEmpty()) {
|
||||
// Right now the WSRunObject code bails on empty strings, but IME needs
|
||||
// the InsertTextWithTransaction() call to still happen since empty
|
||||
// strings are meaningful there.
|
||||
rv = InsertTextWithTransaction(*doc, *inString, compositionStartPoint);
|
||||
nsresult rv = InsertTextWithTransaction(*document, aInsertionString,
|
||||
compositionStartPoint);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"InsertTextWithTransaction() failed");
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
EditorRawDOMPoint compositionEndPoint = GetCompositionEndPoint();
|
||||
@ -1471,12 +1467,12 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
compositionEndPoint = compositionStartPoint;
|
||||
}
|
||||
WSRunObject wsObj(this, compositionStartPoint, compositionEndPoint);
|
||||
rv = wsObj.InsertText(*doc, *inString);
|
||||
nsresult rv = wsObj.InsertText(*document, aInsertionString);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
compositionStartPoint = GetCompositionStartPoint();
|
||||
@ -1484,14 +1480,14 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
if (NS_WARN_IF(!compositionStartPoint.IsSet()) ||
|
||||
NS_WARN_IF(!compositionEndPoint.IsSet())) {
|
||||
// Mutation event listener has changed the DOM tree...
|
||||
return NS_OK;
|
||||
return EditActionHandled();
|
||||
}
|
||||
rv = TopLevelEditSubActionDataRef().mChangedRange->SetStartAndEnd(
|
||||
compositionStartPoint.ToRawRangeBoundary(),
|
||||
compositionEndPoint.ToRawRangeBoundary());
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Faliled to set mChangedRange to composing range");
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aEditSubAction == EditSubAction::eInsertText);
|
||||
@ -1513,8 +1509,6 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
|
||||
// don't change my selection in subtransactions
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(*this);
|
||||
nsAutoString tString(*inString);
|
||||
const char16_t* unicodeBuf = tString.get();
|
||||
int32_t pos = 0;
|
||||
NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
|
||||
|
||||
@ -1525,11 +1519,11 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
// its a lot cheaper to search the input string for only newlines than
|
||||
// it is to search for both tabs and newlines.
|
||||
if (isPRE || IsPlaintextEditor()) {
|
||||
while (unicodeBuf && pos != -1 &&
|
||||
pos < static_cast<int32_t>(inString->Length())) {
|
||||
while (pos != -1 &&
|
||||
pos < static_cast<int32_t>(aInsertionString.Length())) {
|
||||
int32_t oldPos = pos;
|
||||
int32_t subStrLen;
|
||||
pos = tString.FindChar(nsCRT::LF, oldPos);
|
||||
pos = aInsertionString.FindChar(nsCRT::LF, oldPos);
|
||||
|
||||
if (pos != -1) {
|
||||
subStrLen = pos - oldPos;
|
||||
@ -1538,21 +1532,21 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
subStrLen = 1;
|
||||
}
|
||||
} else {
|
||||
subStrLen = tString.Length() - oldPos;
|
||||
pos = tString.Length();
|
||||
subStrLen = aInsertionString.Length() - oldPos;
|
||||
pos = aInsertionString.Length();
|
||||
}
|
||||
|
||||
nsDependentSubstring subStr(tString, oldPos, subStrLen);
|
||||
nsDependentSubstring subStr(aInsertionString, oldPos, subStrLen);
|
||||
|
||||
// is it a return?
|
||||
if (subStr.Equals(newlineStr)) {
|
||||
RefPtr<Element> brElement =
|
||||
InsertBRElementWithTransaction(currentPoint, nsIEditor::eNone);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(!brElement)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
pos++;
|
||||
if (brElement->GetNextSibling()) {
|
||||
@ -1573,14 +1567,14 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
"by mutation observer");
|
||||
} else {
|
||||
EditorRawDOMPoint pointAfterInsertedString;
|
||||
rv = InsertTextWithTransaction(*doc, subStr,
|
||||
EditorRawDOMPoint(currentPoint),
|
||||
&pointAfterInsertedString);
|
||||
nsresult rv = InsertTextWithTransaction(
|
||||
*document, subStr, EditorRawDOMPoint(currentPoint),
|
||||
&pointAfterInsertedString);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
currentPoint = pointAfterInsertedString;
|
||||
pointToInsert = pointAfterInsertedString;
|
||||
@ -1590,11 +1584,12 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
NS_NAMED_LITERAL_STRING(tabStr, "\t");
|
||||
NS_NAMED_LITERAL_STRING(spacesStr, " ");
|
||||
char specialChars[] = {TAB, nsCRT::LF, 0};
|
||||
while (unicodeBuf && pos != -1 &&
|
||||
pos < static_cast<int32_t>(inString->Length())) {
|
||||
nsAutoString insertionString(aInsertionString); // For FindCharInSet().
|
||||
while (pos != -1 &&
|
||||
pos < static_cast<int32_t>(insertionString.Length())) {
|
||||
int32_t oldPos = pos;
|
||||
int32_t subStrLen;
|
||||
pos = tString.FindCharInSet(specialChars, oldPos);
|
||||
pos = insertionString.FindCharInSet(specialChars, oldPos);
|
||||
|
||||
if (pos != -1) {
|
||||
subStrLen = pos - oldPos;
|
||||
@ -1603,22 +1598,23 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
subStrLen = 1;
|
||||
}
|
||||
} else {
|
||||
subStrLen = tString.Length() - oldPos;
|
||||
pos = tString.Length();
|
||||
subStrLen = insertionString.Length() - oldPos;
|
||||
pos = insertionString.Length();
|
||||
}
|
||||
|
||||
nsDependentSubstring subStr(tString, oldPos, subStrLen);
|
||||
nsDependentSubstring subStr(insertionString, oldPos, subStrLen);
|
||||
WSRunObject wsObj(this, currentPoint);
|
||||
|
||||
// is it a tab?
|
||||
if (subStr.Equals(tabStr)) {
|
||||
EditorRawDOMPoint pointAfterInsertedSpaces;
|
||||
rv = wsObj.InsertText(*doc, spacesStr, &pointAfterInsertedSpaces);
|
||||
nsresult rv =
|
||||
wsObj.InsertText(*document, spacesStr, &pointAfterInsertedSpaces);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
pos++;
|
||||
MOZ_ASSERT(pointAfterInsertedSpaces.IsSet());
|
||||
@ -1631,10 +1627,10 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
wsObj.InsertBreak(MOZ_KnownLive(*SelectionRefPtr()), currentPoint,
|
||||
nsIEditor::eNone);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(!newBRElement)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
pos++;
|
||||
if (newBRElement->GetNextSibling()) {
|
||||
@ -1655,12 +1651,13 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
"Perhaps, newBRElement has been moved or removed unexpectedly");
|
||||
} else {
|
||||
EditorRawDOMPoint pointAfterInsertedString;
|
||||
rv = wsObj.InsertText(*doc, subStr, &pointAfterInsertedString);
|
||||
nsresult rv =
|
||||
wsObj.InsertText(*document, subStr, &pointAfterInsertedString);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
MOZ_ASSERT(pointAfterInsertedString.IsSet());
|
||||
currentPoint = pointAfterInsertedString;
|
||||
@ -1681,7 +1678,7 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
IgnoredErrorResult ignoredError;
|
||||
SelectionRefPtr()->Collapse(currentPoint, ignoredError);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
||||
"Failed to collapse at current point");
|
||||
@ -1690,15 +1687,15 @@ nsresult HTMLEditor::WillInsertText(EditSubAction aEditSubAction, bool* aCancel,
|
||||
// manually update the doc changed range so that AfterEdit will clean up
|
||||
// the correct portion of the document.
|
||||
if (currentPoint.IsSet()) {
|
||||
rv = TopLevelEditSubActionDataRef().mChangedRange->SetStartAndEnd(
|
||||
nsresult rv = TopLevelEditSubActionDataRef().mChangedRange->SetStartAndEnd(
|
||||
pointToInsert.ToRawRangeBoundary(), currentPoint.ToRawRangeBoundary());
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to set mChangedRange");
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
rv = TopLevelEditSubActionDataRef().mChangedRange->CollapseTo(pointToInsert);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to collapse mChangedRange");
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
bool HTMLEditor::CanContainParagraph(Element& aElement) const {
|
||||
|
@ -1166,22 +1166,14 @@ class HTMLEditor final : public TextEditor,
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult WillInsert(bool* aCancel = nullptr);
|
||||
|
||||
/**
|
||||
* Called before inserting text.
|
||||
* This method may actually inserts text into the editor. Therefore, this
|
||||
* might cause destroying the editor.
|
||||
* HandleInsertText() handles inserting text at selection.
|
||||
*
|
||||
* @param aEditSubAction Must be EditSubAction::eInsertTextComingFromIME
|
||||
* or EditSubAction::eInsertText.
|
||||
* @param aCancel Returns true if the operation is canceled.
|
||||
* @param aHandled Returns true if the edit action is handled.
|
||||
* @param inString String to be inserted.
|
||||
* @param outString String actually inserted.
|
||||
* @param aMaxLength The maximum string length which the editor
|
||||
* allows to set.
|
||||
* @param aEditSubAction Must be EditSubAction::eInsertText or
|
||||
* EditSubAction::eInsertTextComingFromIME.
|
||||
* @param aInsertionString String to be inserted at selection.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult WillInsertText(
|
||||
EditSubAction aEditSubAction, bool* aCancel, bool* aHandled,
|
||||
const nsAString* inString, nsAString* outString, int32_t aMaxLength);
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE virtual EditActionResult HandleInsertText(
|
||||
EditSubAction aEditSubAction, const nsAString& aInsertionString) final;
|
||||
|
||||
/**
|
||||
* GetInlineStyles() retrieves the style of aNode and modifies each item of
|
||||
|
@ -202,11 +202,6 @@ nsresult TextEditRules::WillDoAction(EditSubActionInfo& aInfo, bool* aCancel,
|
||||
|
||||
// my kingdom for dynamic cast
|
||||
switch (aInfo.mEditSubAction) {
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
TextEditorRef().UndefineCaretBidiLevel();
|
||||
return WillInsertText(aInfo.mEditSubAction, aCancel, aHandled,
|
||||
aInfo.inString, aInfo.outString, aInfo.maxLength);
|
||||
case EditSubAction::eSetText:
|
||||
TextEditorRef().UndefineCaretBidiLevel();
|
||||
return WillSetText(aCancel, aHandled, aInfo.inString, aInfo.maxLength);
|
||||
@ -234,6 +229,8 @@ nsresult TextEditRules::WillDoAction(EditSubActionInfo& aInfo, bool* aCancel,
|
||||
}
|
||||
case EditSubAction::eInsertElement:
|
||||
case EditSubAction::eInsertLineBreak:
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
case EditSubAction::eUndo:
|
||||
case EditSubAction::eRedo:
|
||||
MOZ_ASSERT_UNREACHABLE("This path should've been dead code");
|
||||
@ -253,6 +250,8 @@ nsresult TextEditRules::DidDoAction(EditSubActionInfo& aInfo,
|
||||
case EditSubAction::eDeleteSelectedContent:
|
||||
case EditSubAction::eInsertElement:
|
||||
case EditSubAction::eInsertLineBreak:
|
||||
case EditSubAction::eInsertText:
|
||||
case EditSubAction::eInsertTextComingFromIME:
|
||||
case EditSubAction::eUndo:
|
||||
case EditSubAction::eRedo:
|
||||
MOZ_ASSERT_UNREACHABLE("This path should've been dead code");
|
||||
@ -284,7 +283,7 @@ EditActionResult TextEditor::InsertLineFeedCharacterAtSelection() {
|
||||
if (mMaxTextLength >= 0) {
|
||||
nsAutoString insertionString(NS_LITERAL_STRING("\n"));
|
||||
EditActionResult result =
|
||||
TruncateInsertionStringForMaxLength(insertionString, mMaxTextLength);
|
||||
TruncateInsertionStringForMaxLength(insertionString);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result;
|
||||
}
|
||||
@ -467,9 +466,11 @@ TextEditRules::GetTextNodeAroundSelectionStartContainer() {
|
||||
return node.forget();
|
||||
}
|
||||
|
||||
void TextEditRules::HandleNewLines(nsString& aString) {
|
||||
void TextEditor::HandleNewLinesInStringForSingleLineEditor(
|
||||
nsString& aString) const {
|
||||
static const char16_t kLF = static_cast<char16_t>('\n');
|
||||
MOZ_ASSERT(IsEditorDataAvailable());
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(IsPlaintextEditor());
|
||||
MOZ_ASSERT(aString.FindChar(static_cast<uint16_t>('\r')) == kNotFound);
|
||||
|
||||
// First of all, check if aString contains '\n' since if the string
|
||||
@ -479,7 +480,7 @@ void TextEditRules::HandleNewLines(nsString& aString) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (TextEditorRef().mNewlineHandling) {
|
||||
switch (mNewlineHandling) {
|
||||
case nsIPlaintextEditor::eNewlinesReplaceWithSpaces:
|
||||
// Default of Firefox:
|
||||
// Strip trailing newlines first so we don't wind up with trailing spaces
|
||||
@ -540,84 +541,70 @@ void TextEditRules::HandleNewLines(nsString& aString) {
|
||||
}
|
||||
}
|
||||
|
||||
nsresult TextEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
bool* aCancel, bool* aHandled,
|
||||
const nsAString* inString,
|
||||
nsAString* outString,
|
||||
int32_t aMaxLength) {
|
||||
MOZ_ASSERT(IsEditorDataAvailable());
|
||||
EditActionResult TextEditor::HandleInsertText(
|
||||
EditSubAction aEditSubAction, const nsAString& aInsertionString) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aEditSubAction == EditSubAction::eInsertText ||
|
||||
aEditSubAction == EditSubAction::eInsertTextComingFromIME);
|
||||
|
||||
if (NS_WARN_IF(!aCancel) || NS_WARN_IF(!aHandled)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
UndefineCaretBidiLevel();
|
||||
|
||||
if (inString->IsEmpty() &&
|
||||
if (aInsertionString.IsEmpty() &&
|
||||
aEditSubAction != EditSubAction::eInsertTextComingFromIME) {
|
||||
// HACK: this is a fix for bug 19395
|
||||
// I can't outlaw all empty insertions
|
||||
// because IME transaction depend on them
|
||||
// There is more work to do to make the
|
||||
// world safe for IME.
|
||||
*aCancel = true;
|
||||
*aHandled = false;
|
||||
return NS_OK;
|
||||
return EditActionCanceled();
|
||||
}
|
||||
|
||||
// initialize out param
|
||||
*aCancel = false;
|
||||
*aHandled = true;
|
||||
|
||||
outString->Assign(*inString);
|
||||
if (aMaxLength >= 0) {
|
||||
nsAutoString insertionString(aInsertionString);
|
||||
if (mMaxTextLength >= 0) {
|
||||
EditActionResult result =
|
||||
TextEditorRef().TruncateInsertionStringForMaxLength(*outString,
|
||||
aMaxLength);
|
||||
TruncateInsertionStringForMaxLength(insertionString);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.Rv();
|
||||
return result.MarkAsHandled();
|
||||
}
|
||||
// If we're exceeding the maxlength when composing IME, we need to clean up
|
||||
// the composing text, so we shouldn't return early.
|
||||
if (result.Handled() && outString->IsEmpty() &&
|
||||
if (result.Handled() && insertionString.IsEmpty() &&
|
||||
aEditSubAction != EditSubAction::eInsertTextComingFromIME) {
|
||||
*aCancel = true;
|
||||
return NS_OK;
|
||||
return EditActionCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t start = 0;
|
||||
if (IsPasswordEditor()) {
|
||||
if (TextEditorRef().GetComposition() &&
|
||||
!TextEditorRef().GetComposition()->String().IsEmpty()) {
|
||||
start = TextEditorRef().GetComposition()->XPOffsetInTextNode();
|
||||
if (GetComposition() && !GetComposition()->String().IsEmpty()) {
|
||||
start = GetComposition()->XPOffsetInTextNode();
|
||||
} else {
|
||||
uint32_t end = 0;
|
||||
nsContentUtils::GetSelectionInTextControl(
|
||||
SelectionRefPtr(), TextEditorRef().GetRoot(), start, end);
|
||||
nsContentUtils::GetSelectionInTextControl(SelectionRefPtr(), GetRoot(),
|
||||
start, end);
|
||||
}
|
||||
}
|
||||
|
||||
// if the selection isn't collapsed, delete it.
|
||||
if (!SelectionRefPtr()->IsCollapsed()) {
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(TextEditorRef())
|
||||
.DeleteSelectionAsSubAction(nsIEditor::eNone, nsIEditor::eStrip);
|
||||
if (NS_WARN_IF(!CanHandleEditAction())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
DeleteSelectionAsSubAction(nsIEditor::eNone, nsIEditor::eStrip);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Why do we set `aCancel` here, but ignore it?
|
||||
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
||||
// XXX Why don't we cancel here? Shouldn't we do this first?
|
||||
CANCEL_OPERATION_AND_RETURN_EDIT_ACTION_RESULT_IF_READONLY_OF_DISABLED
|
||||
|
||||
TextEditorRef().MaybeDoAutoPasswordMasking();
|
||||
MaybeDoAutoPasswordMasking();
|
||||
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(TextEditorRef()).EnsureNoPaddingBRElementForEmptyEditor();
|
||||
nsresult rv = EnsureNoPaddingBRElementForEmptyEditor();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
// People have lots of different ideas about what text fields
|
||||
@ -631,7 +618,6 @@ nsresult TextEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
// 5. strip newlines and surrounding whitespace
|
||||
// So find out what we're expected to do:
|
||||
if (IsSingleLineEditor()) {
|
||||
nsAutoString tString(*outString);
|
||||
// XXX Some callers of TextEditor::InsertTextAsAction() already make the
|
||||
// string use only \n as a linebreaker. However, they are not hot
|
||||
// path and nsContentUtils::PlatformToDOMLineBreaks() does nothing
|
||||
@ -639,104 +625,98 @@ nsresult TextEditRules::WillInsertText(EditSubAction aEditSubAction,
|
||||
// here. Note that there are too many callers of
|
||||
// TextEditor::InsertTextAsAction(). So, it's difficult to keep
|
||||
// maintaining all of them won't reach here without \r nor \r\n.
|
||||
nsContentUtils::PlatformToDOMLineBreaks(tString);
|
||||
HandleNewLines(tString);
|
||||
outString->Assign(tString);
|
||||
// XXX Should we handle do this before truncating the string for
|
||||
// `maxlength`?
|
||||
nsContentUtils::PlatformToDOMLineBreaks(insertionString);
|
||||
HandleNewLinesInStringForSingleLineEditor(insertionString);
|
||||
}
|
||||
|
||||
// get the (collapsed) selection location
|
||||
nsRange* firstRange = SelectionRefPtr()->GetRangeAt(0);
|
||||
if (NS_WARN_IF(!firstRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
EditorRawDOMPoint atStartOfSelection(firstRange->StartRef());
|
||||
if (NS_WARN_IF(!atStartOfSelection.IsSetAndValid())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// don't put text in places that can't have it
|
||||
if (!atStartOfSelection.IsInTextNode() &&
|
||||
!TextEditorRef().CanContainTag(*atStartOfSelection.GetContainer(),
|
||||
*nsGkAtoms::textTagName)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
!CanContainTag(*atStartOfSelection.GetContainer(),
|
||||
*nsGkAtoms::textTagName)) {
|
||||
return EditActionHandled(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// we need to get the doc
|
||||
RefPtr<Document> doc = TextEditorRef().GetDocument();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
RefPtr<Document> document = GetDocument();
|
||||
if (NS_WARN_IF(!document)) {
|
||||
return EditActionHandled(NS_ERROR_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
if (aEditSubAction == EditSubAction::eInsertTextComingFromIME) {
|
||||
EditorRawDOMPoint compositionStartPoint =
|
||||
TextEditorRef().GetCompositionStartPoint();
|
||||
EditorRawDOMPoint compositionStartPoint = GetCompositionStartPoint();
|
||||
if (!compositionStartPoint.IsSet()) {
|
||||
compositionStartPoint =
|
||||
TextEditorRef().FindBetterInsertionPoint(atStartOfSelection);
|
||||
compositionStartPoint = FindBetterInsertionPoint(atStartOfSelection);
|
||||
}
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(TextEditorRef())
|
||||
.InsertTextWithTransaction(*doc, *outString, compositionStartPoint);
|
||||
if (NS_WARN_IF(!CanHandleEditAction())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
nsresult rv = InsertTextWithTransaction(*document, insertionString,
|
||||
compositionStartPoint);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
} else {
|
||||
// aEditSubAction == EditSubAction::eInsertText
|
||||
MOZ_ASSERT(aEditSubAction == EditSubAction::eInsertText);
|
||||
|
||||
// don't change my selection in subtransactions
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(TextEditorRef());
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(*this);
|
||||
|
||||
EditorRawDOMPoint pointAfterStringInserted;
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(TextEditorRef())
|
||||
.InsertTextWithTransaction(*doc, *outString, atStartOfSelection,
|
||||
&pointAfterStringInserted);
|
||||
if (NS_WARN_IF(!CanHandleEditAction())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
nsresult rv = InsertTextWithTransaction(*document, insertionString,
|
||||
atStartOfSelection,
|
||||
&pointAfterStringInserted);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
if (pointAfterStringInserted.IsSet()) {
|
||||
// Make the caret attach to the inserted text, unless this text ends with
|
||||
// a LF, in which case make the caret attach to the next line.
|
||||
bool endsWithLF = !outString->IsEmpty() && outString->Last() == nsCRT::LF;
|
||||
IgnoredErrorResult error;
|
||||
SelectionRefPtr()->SetInterlinePosition(endsWithLF, error);
|
||||
NS_WARNING_ASSERTION(!error.Failed(),
|
||||
"Failed to set or unset interline position");
|
||||
bool endsWithLF =
|
||||
!insertionString.IsEmpty() && insertionString.Last() == nsCRT::LF;
|
||||
IgnoredErrorResult ignoredError;
|
||||
SelectionRefPtr()->SetInterlinePosition(endsWithLF, ignoredError);
|
||||
NS_WARNING_ASSERTION(
|
||||
!ignoredError.Failed(),
|
||||
"Selection::SetInterlinePosition() failed, but ignored");
|
||||
|
||||
MOZ_ASSERT(
|
||||
!pointAfterStringInserted.GetChild(),
|
||||
"After inserting text into a text node, pointAfterStringInserted."
|
||||
"GetChild() should be nullptr");
|
||||
error = IgnoredErrorResult();
|
||||
SelectionRefPtr()->Collapse(pointAfterStringInserted, error);
|
||||
if (NS_WARN_IF(!CanHandleEditAction())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
ignoredError = IgnoredErrorResult();
|
||||
SelectionRefPtr()->Collapse(pointAfterStringInserted, ignoredError);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
!error.Failed(),
|
||||
"Failed to collapse selection after inserting string");
|
||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
||||
"Selection::Collapse() failed, but ignored");
|
||||
}
|
||||
}
|
||||
|
||||
// Unmask inputted character(s) if necessary.
|
||||
if (IsPasswordEditor() && IsMaskingPassword() && !DontEchoPassword()) {
|
||||
nsresult rv =
|
||||
MOZ_KnownLive(TextEditorRef())
|
||||
.SetUnmaskRangeAndNotify(start, outString->Length(),
|
||||
LookAndFeel::GetPasswordMaskDelay());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (IsPasswordEditor() && IsMaskingPassword() && CanEchoPasswordNow()) {
|
||||
nsresult rv = SetUnmaskRangeAndNotify(start, insertionString.Length(),
|
||||
LookAndFeel::GetPasswordMaskDelay());
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "SetUnmaskRangeAndNotify() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return EditActionHandled();
|
||||
}
|
||||
|
||||
nsresult TextEditRules::WillSetText(bool* aCancel, bool* aHandled,
|
||||
@ -812,7 +792,7 @@ nsresult TextEditRules::WillSetText(bool* aCancel, bool* aHandled,
|
||||
// Is this intentional?
|
||||
nsAutoString tString(*aString);
|
||||
if (IsSingleLineEditor() && !IsPasswordEditor()) {
|
||||
HandleNewLines(tString);
|
||||
TextEditorRef().HandleNewLinesInStringForSingleLineEditor(tString);
|
||||
}
|
||||
|
||||
if (!firstChild || !EditorBase::IsTextNode(firstChild)) {
|
||||
@ -1148,8 +1128,9 @@ nsresult TextEditRules::CreateTrailingBRIfNeeded() {
|
||||
}
|
||||
|
||||
EditActionResult TextEditor::TruncateInsertionStringForMaxLength(
|
||||
nsAString& aInsertionString, uint32_t aMaxLength) {
|
||||
nsAString& aInsertionString) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(mMaxTextLength >= 0);
|
||||
|
||||
if (!IsPlaintextEditor() || IsIMEComposing()) {
|
||||
return EditActionIgnored();
|
||||
@ -1175,16 +1156,17 @@ EditActionResult TextEditor::TruncateInsertionStringForMaxLength(
|
||||
// is part of kOldCompositionStringLength.
|
||||
const uint32_t kNewLength =
|
||||
currentLength - kSelectionLength - kOldCompositionStringLength;
|
||||
if (kNewLength >= aMaxLength) {
|
||||
if (kNewLength >= static_cast<uint32_t>(mMaxTextLength)) {
|
||||
aInsertionString.Truncate(); // Too long, we cannot accept new character.
|
||||
return EditActionHandled();
|
||||
}
|
||||
|
||||
if (aInsertionString.Length() + kNewLength <= aMaxLength) {
|
||||
if (aInsertionString.Length() + kNewLength <=
|
||||
static_cast<uint32_t>(mMaxTextLength)) {
|
||||
return EditActionIgnored(); // Enough short string.
|
||||
}
|
||||
|
||||
int32_t newInsertionStringLength = aMaxLength - kNewLength;
|
||||
int32_t newInsertionStringLength = mMaxTextLength - kNewLength;
|
||||
MOZ_ASSERT(newInsertionStringLength > 0);
|
||||
char16_t maybeHighSurrogate =
|
||||
aInsertionString.CharAt(newInsertionStringLength - 1);
|
||||
@ -1229,20 +1211,14 @@ bool TextEditRules::IsMailEditor() const {
|
||||
return mTextEditor ? mTextEditor->IsMailEditor() : false;
|
||||
}
|
||||
|
||||
bool TextEditRules::DontEchoPassword() const {
|
||||
if (!mTextEditor) {
|
||||
// XXX Why do we use echo password if editor is null?
|
||||
bool TextEditor::CanEchoPasswordNow() const {
|
||||
if (!LookAndFeel::GetEchoPassword() ||
|
||||
(mFlags & nsIPlaintextEditor::eEditorDontEchoPassword)) {
|
||||
return false;
|
||||
}
|
||||
if (!LookAndFeel::GetEchoPassword() || mTextEditor->DontEchoPassword()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mTextEditor->GetEditAction() != EditAction::eDrop &&
|
||||
mTextEditor->GetEditAction() != EditAction::ePaste) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return GetEditAction() != EditAction::eDrop &&
|
||||
GetEditAction() != EditAction::ePaste;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -102,55 +102,10 @@ class TextEditRules {
|
||||
protected:
|
||||
virtual ~TextEditRules() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Handles the newline characters according to the default system prefs
|
||||
* (editor.singleLine.pasteNewlines).
|
||||
* Each value means:
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithSpaces (2, Firefox default):
|
||||
* replace newlines with spaces.
|
||||
* nsIPlaintextEditor::eNewlinesStrip (3):
|
||||
* remove newlines from the string.
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithCommas (4, Thunderbird default):
|
||||
* replace newlines with commas.
|
||||
* nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace (5):
|
||||
* collapse newlines and surrounding whitespace characters and
|
||||
* remove them from the string.
|
||||
* nsIPlaintextEditor::eNewlinesPasteIntact (0):
|
||||
* only remove the leading and trailing newlines.
|
||||
* nsIPlaintextEditor::eNewlinesPasteToFirst (1) or any other value:
|
||||
* remove the first newline and all characters following it.
|
||||
*
|
||||
* @param aString the string to be modified in place.
|
||||
*/
|
||||
void HandleNewLines(nsString& aString);
|
||||
|
||||
protected:
|
||||
void InitFields();
|
||||
|
||||
// TextEditRules implementation methods
|
||||
|
||||
/**
|
||||
* Called before inserting text.
|
||||
* This method may actually inserts text into the editor. Therefore, this
|
||||
* might cause destroying the editor.
|
||||
*
|
||||
* @param aEditSubAction Must be EditSubAction::eInsertTextComingFromIME
|
||||
* or EditSubAction::eInsertText.
|
||||
* @param aCancel Returns true if the operation is canceled.
|
||||
* @param aHandled Returns true if the edit action is handled.
|
||||
* @param inString String to be inserted.
|
||||
* @param outString String actually inserted.
|
||||
* @param aMaxLength The maximum string length which the editor
|
||||
* allows to set.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
MOZ_MUST_USE nsresult WillInsertText(EditSubAction aEditSubAction,
|
||||
bool* aCancel, bool* aHandled,
|
||||
const nsAString* inString,
|
||||
nsAString* outString,
|
||||
int32_t aMaxLength);
|
||||
|
||||
/**
|
||||
* Called before setting text to the text editor.
|
||||
* This method may actually set text to it. Therefore, this might cause
|
||||
|
@ -954,9 +954,6 @@ nsresult TextEditor::InsertTextAsSubAction(const nsAString& aStringToInsert) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
// Protect the edit rules object from dying.
|
||||
RefPtr<TextEditRules> rules(mRules);
|
||||
|
||||
EditSubAction editSubAction = ShouldHandleIMEComposition()
|
||||
? EditSubAction::eInsertTextComingFromIME
|
||||
: EditSubAction::eInsertText;
|
||||
@ -964,32 +961,9 @@ nsresult TextEditor::InsertTextAsSubAction(const nsAString& aStringToInsert) {
|
||||
AutoEditSubActionNotifier startToHandleEditSubAction(*this, editSubAction,
|
||||
nsIEditor::eNext);
|
||||
|
||||
nsAutoString resultString;
|
||||
// XXX can we trust instring to outlive subActionInfo,
|
||||
// XXX and subActionInfo not to refer to instring in its dtor?
|
||||
// nsAutoString instring(aStringToInsert);
|
||||
EditSubActionInfo subActionInfo(editSubAction);
|
||||
subActionInfo.inString = &aStringToInsert;
|
||||
subActionInfo.outString = &resultString;
|
||||
subActionInfo.maxLength = mMaxTextLength;
|
||||
|
||||
bool cancel, handled;
|
||||
nsresult rv = rules->WillDoAction(subActionInfo, &cancel, &handled);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (!cancel && !handled) {
|
||||
// we rely on rules code for now - no default implementation
|
||||
}
|
||||
if (cancel) {
|
||||
return NS_OK;
|
||||
}
|
||||
// post-process
|
||||
rv = rules->DidDoAction(subActionInfo, NS_OK);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
EditActionResult result = HandleInsertText(editSubAction, aStringToInsert);
|
||||
NS_WARNING_ASSERTION(result.Succeeded(), "HandleInsertText() failed");
|
||||
return result.Rv();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -214,8 +214,8 @@ class TextEditor : public EditorBase,
|
||||
* JS. If set to nullptr, will be treated as
|
||||
* called by system.
|
||||
*/
|
||||
nsresult InsertTextAsAction(const nsAString& aStringToInsert,
|
||||
nsIPrincipal* aPrincipal = nullptr);
|
||||
MOZ_CAN_RUN_SCRIPT nsresult InsertTextAsAction(
|
||||
const nsAString& aStringToInsert, nsIPrincipal* aPrincipal = nullptr);
|
||||
|
||||
/**
|
||||
* PasteAsQuotationAsAction() pastes content in clipboard as quotation.
|
||||
@ -423,7 +423,8 @@ class TextEditor : public EditorBase,
|
||||
*
|
||||
* @param aStringToInsert The string to insert.
|
||||
*/
|
||||
nsresult InsertTextAsSubAction(const nsAString& aStringToInsert);
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
|
||||
InsertTextAsSubAction(const nsAString& aStringToInsert);
|
||||
|
||||
/**
|
||||
* DeleteSelectionAsSubAction() removes selection content or content around
|
||||
@ -586,7 +587,7 @@ class TextEditor : public EditorBase,
|
||||
* more characters, returns "as handled".
|
||||
*/
|
||||
EditActionResult TruncateInsertionStringForMaxLength(
|
||||
nsAString& aInsertionString, uint32_t aMaxLength);
|
||||
nsAString& aInsertionString);
|
||||
|
||||
/**
|
||||
* InsertLineFeedCharacterAtSelection() inserts a linefeed character at
|
||||
@ -595,6 +596,38 @@ class TextEditor : public EditorBase,
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE EditActionResult
|
||||
InsertLineFeedCharacterAtSelection();
|
||||
|
||||
/**
|
||||
* Handles the newline characters according to the default system prefs
|
||||
* (editor.singleLine.pasteNewlines).
|
||||
* Each value means:
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithSpaces (2, Firefox default):
|
||||
* replace newlines with spaces.
|
||||
* nsIPlaintextEditor::eNewlinesStrip (3):
|
||||
* remove newlines from the string.
|
||||
* nsIPlaintextEditor::eNewlinesReplaceWithCommas (4, Thunderbird default):
|
||||
* replace newlines with commas.
|
||||
* nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace (5):
|
||||
* collapse newlines and surrounding whitespace characters and
|
||||
* remove them from the string.
|
||||
* nsIPlaintextEditor::eNewlinesPasteIntact (0):
|
||||
* only remove the leading and trailing newlines.
|
||||
* nsIPlaintextEditor::eNewlinesPasteToFirst (1) or any other value:
|
||||
* remove the first newline and all characters following it.
|
||||
*
|
||||
* @param aString the string to be modified in place.
|
||||
*/
|
||||
void HandleNewLinesInStringForSingleLineEditor(nsString& aString) const;
|
||||
|
||||
/**
|
||||
* HandleInsertText() handles inserting text at selection.
|
||||
*
|
||||
* @param aEditSubAction Must be EditSubAction::eInsertText or
|
||||
* EditSubAction::eInsertTextComingFromIME.
|
||||
* @param aInsertionString String to be inserted at selection.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE virtual EditActionResult HandleInsertText(
|
||||
EditSubAction aEditSubAction, const nsAString& aInsertionString);
|
||||
|
||||
protected: // Called by helper classes.
|
||||
virtual void OnStartToHandleTopLevelEditSubAction(
|
||||
EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;
|
||||
@ -632,6 +665,13 @@ class TextEditor : public EditorBase,
|
||||
|
||||
int32_t WrapWidth() const { return mWrapColumn; }
|
||||
|
||||
/**
|
||||
* CanEchoPasswordNow() returns true if currently we can echo password.
|
||||
* If it's direct user input such as pasting or dropping text, this
|
||||
* returns false even if we may echo password.
|
||||
*/
|
||||
bool CanEchoPasswordNow() const;
|
||||
|
||||
/**
|
||||
* Make the given selection span the entire document.
|
||||
*/
|
||||
@ -643,7 +683,8 @@ class TextEditor : public EditorBase,
|
||||
*
|
||||
* @param aStringToInsert The string to insert.
|
||||
*/
|
||||
nsresult OnInputText(const nsAString& aStringToInsert);
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
|
||||
OnInputText(const nsAString& aStringToInsert);
|
||||
|
||||
/**
|
||||
* InsertLineBreakAsSubAction() inserts a line break, i.e., \n if it's
|
||||
@ -687,7 +728,8 @@ class TextEditor : public EditorBase,
|
||||
* @param aQuotedText String to insert. This will be quoted by ">"
|
||||
* automatically.
|
||||
*/
|
||||
nsresult InsertWithQuotationsAsSubAction(const nsAString& aQuotedText);
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
|
||||
InsertWithQuotationsAsSubAction(const nsAString& aQuotedText);
|
||||
|
||||
/**
|
||||
* Return true if the data is safe to insert as the source and destination
|
||||
@ -730,7 +772,8 @@ class TextEditor : public EditorBase,
|
||||
*/
|
||||
virtual nsresult PrepareTransferable(nsITransferable** transferable);
|
||||
|
||||
nsresult InsertTextFromTransferable(nsITransferable* transferable);
|
||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
|
||||
InsertTextFromTransferable(nsITransferable* transferable);
|
||||
|
||||
/**
|
||||
* DeleteSelectionAndCreateElement() creates a element whose name is aTag.
|
||||
|
@ -86,6 +86,7 @@ interface nsIPlaintextEditor : nsISupports
|
||||
*
|
||||
* @param aString the string to be inserted
|
||||
*/
|
||||
[can_run_script]
|
||||
void insertText(in AString aStringToInsert);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user