Bug 795418 - Ensure that the inserted wrapper element has a frame to make it IsEditable. r=masayuki, a=jcristau
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -2,16 +2,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_EditorBase_h
#define mozilla_EditorBase_h
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
+#include "mozFlushType.h" // for mozFlushType enum
#include "mozilla/OwningNonNull.h" // for OwningNonNull
#include "mozilla/SelectionState.h" // for RangeUpdater, etc.
#include "mozilla/StyleSheet.h" // for StyleSheet
#include "mozilla/dom/Text.h"
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
#include "nsCycleCollectionParticipant.h"
#include "nsGkAtoms.h"
#include "nsIEditor.h" // for nsIEditor::EDirection, etc.
@@ -935,16 +936,24 @@ public:
/**
* HideCaret() hides caret with nsCaret::AddForceHide() or may show carent
* with nsCaret::RemoveForceHide(). This does NOT set visibility of
* nsCaret. Therefore, this is stateless.
*/
void HideCaret(bool aHide);
+ void FlushFrames()
+ {
+ nsCOMPtr<nsIDocument> doc = GetDocument();
+ if (doc) {
+ doc->FlushPendingNotifications(Flush_Frames);
+ }
+ }
+
protected:
enum Tristate
{
eTriUnset,
eTriFalse,
eTriTrue
};
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1656,16 +1656,19 @@ HTMLEditor::PasteAsCitedQuotation(const
// Try to set type=cite. Ignore it if this fails.
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("cite"), true);
// Set the selection to the underneath the node we just inserted:
rv = selection->Collapse(newNode, 0);
NS_ENSURE_SUCCESS(rv, rv);
+ // Ensure that the inserted <blockquote> has a frame to make it IsEditable.
+ FlushFrames();
+
return Paste(aSelectionType);
}
/**
* Paste a plaintext quotation.
*/
NS_IMETHODIMP
HTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType)
@@ -1712,16 +1715,17 @@ HTMLEditor::PasteAsPlaintextQuotation(in
}
return rv;
}
NS_IMETHODIMP
HTMLEditor::InsertTextWithQuotations(const nsAString& aStringToInsert)
{
+ AutoEditBatch beginBatching(this);
// The whole operation should be undoable in one transaction:
BeginTransaction();
// We're going to loop over the string, collecting up a "hunk"
// that's all the same type (quoted or not),
// Whenever the quotedness changes (or we reach the string's end)
// we will insert the hunk all at once, quoted or non.
@@ -1875,16 +1879,19 @@ HTMLEditor::InsertAsPlaintextQuotation(c
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
NS_LITERAL_STRING("white-space: pre-wrap;"), true);
}
// and set the selection inside it:
selection->Collapse(newNode, 0);
}
+ // Ensure that the inserted <span> has a frame to make it IsEditable.
+ FlushFrames();
+
if (aAddCites) {
rv = TextEditor::InsertAsQuotation(aQuotedText, aNodeInserted);
} else {
rv = TextEditor::InsertText(aQuotedText);
}
// Note that if !aAddCites, aNodeInserted isn't set.
// That's okay because the routines that use aAddCites
// don't need to know the inserted node.
@@ -1958,16 +1965,19 @@ HTMLEditor::InsertAsCitedQuotation(const
if (!aCitation.IsEmpty()) {
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::cite, aCitation, true);
}
// Set the selection inside the blockquote so aQuotedText will go there:
selection->Collapse(newNode, 0);
+ // Ensure that the inserted <blockquote> has a frame to make it IsEditable.
+ FlushFrames();
+
if (aInsertHTML) {
rv = LoadHTML(aQuotedText);
} else {
rv = InsertText(aQuotedText); // XXX ignore charset
}
if (aNodeInserted && NS_SUCCEEDED(rv)) {
*aNodeInserted = GetAsDOMNode(newNode);