diff --git a/editor/libeditor/HTMLAbsPositionEditor.cpp b/editor/libeditor/HTMLAbsPositionEditor.cpp index 2378d243dd1e..52cf72af5e42 100644 --- a/editor/libeditor/HTMLAbsPositionEditor.cpp +++ b/editor/libeditor/HTMLAbsPositionEditor.cpp @@ -135,6 +135,12 @@ NS_IMETHODIMP HTMLEditor::SetAbsolutePositioningEnabled(bool aIsEnabled) { return NS_OK; } +NS_IMETHODIMP HTMLEditor::GetIsAbsolutePositioningActive(bool* aIsActive) { + MOZ_ASSERT(aIsActive); + *aIsActive = !!mAbsolutelyPositionedObject; + return NS_OK; +} + Result HTMLEditor::AddZIndexWithTransaction( nsStyledElement& aStyledElement, int32_t aChange) { if (!aChange) { diff --git a/editor/libeditor/HTMLAnonymousNodeEditor.cpp b/editor/libeditor/HTMLAnonymousNodeEditor.cpp index f89b4e334ab7..f2e6dca7ca64 100644 --- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp +++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp @@ -12,6 +12,7 @@ #include "mozilla/PresShellInlines.h" #include "mozilla/dom/BindContext.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/ElementInlines.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/mozalloc.h" #include "nsAString.h" @@ -292,31 +293,44 @@ void HTMLEditor::HideAnonymousEditingUIs() { void HTMLEditor::HideAnonymousEditingUIsIfUnnecessary() { // XXX Perhaps, this is wrong approach to hide multiple UIs because // hiding one UI may causes overwriting existing UI with newly - // created one. In such case, we will leak ovewritten UI. - if (!IsAbsolutePositionEditorEnabled() && mAbsolutelyPositionedObject) { - // XXX If we're moving something, we need to cancel or commit the - // operation now. - HideGrabberInternal(); - NS_ASSERTION(!mAbsolutelyPositionedObject, - "HTMLEditor::HideGrabberInternal() failed, but ignored"); + // created one. In such case, we will leak overwritten UI. + if (mAbsolutelyPositionedObject) { + const Element* const editingHost = + mAbsolutelyPositionedObject->GetEditingHost(); + if (!IsAbsolutePositionEditorEnabled() || !editingHost || + editingHost->IsContentEditablePlainTextOnly()) { + // XXX If we're moving something, we need to cancel or commit the + // operation now. + HideGrabberInternal(); + NS_ASSERTION(!mAbsolutelyPositionedObject, + "HTMLEditor::HideGrabberInternal() failed, but ignored"); + } } - if (!IsInlineTableEditorEnabled() && mInlineEditedCell) { - // XXX If we're resizing a table element, we need to cancel or commit the - // operation now. - HideInlineTableEditingUIInternal(); - NS_ASSERTION( - !mInlineEditedCell, - "HTMLEditor::HideInlineTableEditingUIInternal() failed, but ignored"); + if (mInlineEditedCell) { + const Element* const editingHost = mInlineEditedCell->GetEditingHost(); + if (!IsInlineTableEditorEnabled() || !editingHost || + editingHost->IsContentEditablePlainTextOnly()) { + // XXX If we're resizing a table element, we need to cancel or commit the + // operation now. + HideInlineTableEditingUIInternal(); + NS_ASSERTION( + !mInlineEditedCell, + "HTMLEditor::HideInlineTableEditingUIInternal() failed, but ignored"); + } } - if (!IsObjectResizerEnabled() && mResizedObject) { - // XXX If we're resizing something, we need to cancel or commit the - // operation now. - DebugOnly rvIgnored = HideResizersInternal(); - NS_WARNING_ASSERTION( - NS_SUCCEEDED(rvIgnored), - "HTMLEditor::HideResizersInternal() failed, but ignored"); - NS_ASSERTION(!mResizedObject, - "HTMLEditor::HideResizersInternal() failed, but ignored"); + if (mResizedObject) { + const Element* const editingHost = mResizedObject->GetEditingHost(); + if (!IsObjectResizerEnabled() || !editingHost || + editingHost->IsContentEditablePlainTextOnly()) { + // XXX If we're resizing something, we need to cancel or commit the + // operation now. + DebugOnly rvIgnored = HideResizersInternal(); + NS_WARNING_ASSERTION( + NS_SUCCEEDED(rvIgnored), + "HTMLEditor::HideResizersInternal() failed, but ignored"); + NS_ASSERTION(!mResizedObject, + "HTMLEditor::HideResizersInternal() failed, but ignored"); + } } } @@ -361,6 +375,13 @@ nsresult HTMLEditor::RefreshEditingUI() { return NS_OK; } + const RefPtr editingHost = + ComputeEditingHost(LimitInBodyElement::No); + if (editingHost && editingHost->IsContentEditablePlainTextOnly()) { + return NS_OK; + } + MOZ_ASSERT(editingHost == selectionContainerElement->GetEditingHost()); + // what's its tag? RefPtr focusElement = std::move(selectionContainerElement); nsAtom* focusTagAtom = focusElement->NodeInfo()->NameAtom(); @@ -443,11 +464,9 @@ nsresult HTMLEditor::RefreshEditingUI() { } // now, let's display all contextual UI for good - nsIContent* hostContent = ComputeEditingHost(); - if (IsObjectResizerEnabled() && focusElement && HTMLEditUtils::IsSimplyEditableNode(*focusElement) && - focusElement != hostContent) { + focusElement != editingHost) { if (nsGkAtoms::img == focusTagAtom) { mResizedObjectIsAnImage = true; } @@ -468,7 +487,7 @@ nsresult HTMLEditor::RefreshEditingUI() { if (IsAbsolutePositionEditorEnabled() && absPosElement && HTMLEditUtils::IsSimplyEditableNode(*absPosElement) && - absPosElement != hostContent) { + absPosElement != editingHost) { if (mAbsolutelyPositionedObject) { nsresult rv = RefreshGrabberInternal(); if (NS_FAILED(rv)) { @@ -487,7 +506,7 @@ nsresult HTMLEditor::RefreshEditingUI() { // XXX Shouldn't we check whether the `` element is editable or not? if (IsInlineTableEditorEnabled() && cellElement && HTMLEditUtils::IsSimplyEditableNode(*cellElement) && - cellElement != hostContent) { + cellElement != editingHost) { if (mInlineEditedCell) { nsresult rv = RefreshInlineTableEditingUIInternal(); if (NS_FAILED(rv)) { diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp index 8a11c8487c1c..a9b9cc3c828f 100644 --- a/editor/libeditor/HTMLEditorObjectResizer.cpp +++ b/editor/libeditor/HTMLEditorObjectResizer.cpp @@ -1481,6 +1481,12 @@ NS_IMETHODIMP HTMLEditor::SetObjectResizingEnabled( return NS_OK; } +NS_IMETHODIMP HTMLEditor::GetIsObjectResizingActive(bool* aIsActive) { + MOZ_ASSERT(aIsActive); + *aIsActive = !!mResizedObject; + return NS_OK; +} + #undef kTopLeft #undef kTop #undef kTopRight diff --git a/editor/libeditor/HTMLInlineTableEditor.cpp b/editor/libeditor/HTMLInlineTableEditor.cpp index 434854e10be3..16d5b2cc91f3 100644 --- a/editor/libeditor/HTMLInlineTableEditor.cpp +++ b/editor/libeditor/HTMLInlineTableEditor.cpp @@ -31,6 +31,12 @@ NS_IMETHODIMP HTMLEditor::GetInlineTableEditingEnabled(bool* aIsEnabled) { return NS_OK; } +NS_IMETHODIMP HTMLEditor::GetIsInlineTableEditingActive(bool* aIsActive) { + MOZ_ASSERT(aIsActive); + *aIsActive = !!mInlineEditedCell; + return NS_OK; +} + nsresult HTMLEditor::ShowInlineTableEditingUIInternal(Element& aCellElement) { if (NS_WARN_IF(!HTMLEditUtils::IsTableCell(&aCellElement))) { return NS_OK; diff --git a/editor/libeditor/tests/mochitest.toml b/editor/libeditor/tests/mochitest.toml index 8d82343f7acb..a0b1a781c250 100644 --- a/editor/libeditor/tests/mochitest.toml +++ b/editor/libeditor/tests/mochitest.toml @@ -444,6 +444,8 @@ skip-if = ["os == 'android'"] # Needs interaction with the scrollbar ["test_dragend_target.html"] +["test_editing_UI_in_plaintext-only.html"] + ["test_execCommandPaste_noTarget.html"] ["test_focus_caret_navigation_between_nested_editors.html"] diff --git a/editor/libeditor/tests/test_editing_UI_in_plaintext-only.html b/editor/libeditor/tests/test_editing_UI_in_plaintext-only.html new file mode 100644 index 000000000000..63ef371a193b --- /dev/null +++ b/editor/libeditor/tests/test_editing_UI_in_plaintext-only.html @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+

+
+
+

+ +
+ +
+ + diff --git a/editor/nsIHTMLAbsPosEditor.idl b/editor/nsIHTMLAbsPosEditor.idl index e04c13a3b575..3106b6ce0916 100644 --- a/editor/nsIHTMLAbsPosEditor.idl +++ b/editor/nsIHTMLAbsPosEditor.idl @@ -15,6 +15,11 @@ interface nsIHTMLAbsPosEditor : nsISupports [setter_can_run_script] attribute boolean absolutePositioningEnabled; + /** + * true if the grabber to drag the absolutly positioned element is visible. + */ + [infallible] readonly attribute boolean isAbsolutePositioningActive; + /* Utility methods */ diff --git a/editor/nsIHTMLInlineTableEditor.idl b/editor/nsIHTMLInlineTableEditor.idl index 479dbb2b3010..a0f7e732c723 100644 --- a/editor/nsIHTMLInlineTableEditor.idl +++ b/editor/nsIHTMLInlineTableEditor.idl @@ -17,4 +17,9 @@ interface nsIHTMLInlineTableEditor : nsISupports */ [setter_can_run_script] attribute boolean inlineTableEditingEnabled; + + /** + * true if the inline table editing UI is visible. + */ + [infallible] readonly attribute boolean isInlineTableEditingActive; }; diff --git a/editor/nsIHTMLObjectResizer.idl b/editor/nsIHTMLObjectResizer.idl index 120fa06b8452..4c2185b24029 100644 --- a/editor/nsIHTMLObjectResizer.idl +++ b/editor/nsIHTMLObjectResizer.idl @@ -29,6 +29,11 @@ interface nsIHTMLObjectResizer : nsISupports [setter_can_run_script] attribute boolean objectResizingEnabled; + /** + * true if the object resizing UI is visible. + */ + [infallible] readonly attribute boolean isObjectResizingActive; + /** * Hide resizers if they are visible. If this is called while there is no * visible resizers, this does not throw exception, just does nothing.