зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1574852 - part 93: Move `HTMLEditRules::CheckInterlinePosition()` to `HTMLEditor` r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D44797 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2fb41871a9
Коммит
e3bcdb2d3c
|
@ -707,8 +707,9 @@ nsresult HTMLEditRules::AfterEditInner() {
|
||||||
// adjust selection HINT if needed
|
// adjust selection HINT if needed
|
||||||
if (!HTMLEditorRef()
|
if (!HTMLEditorRef()
|
||||||
.TopLevelEditSubActionDataRef()
|
.TopLevelEditSubActionDataRef()
|
||||||
.mDidExplicitlySetInterLine) {
|
.mDidExplicitlySetInterLine &&
|
||||||
CheckInterlinePosition();
|
SelectionRefPtr()->IsCollapsed()) {
|
||||||
|
HTMLEditorRef().SetSelectionInterlinePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -9666,13 +9667,9 @@ nsresult HTMLEditRules::PinSelectionToNewBlock() {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLEditRules::CheckInterlinePosition() {
|
void HTMLEditor::SetSelectionInterlinePosition() {
|
||||||
MOZ_ASSERT(IsEditorDataAvailable());
|
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||||
|
MOZ_ASSERT(SelectionRefPtr()->IsCollapsed());
|
||||||
// If the selection isn't collapsed, do nothing.
|
|
||||||
if (!SelectionRefPtr()->IsCollapsed()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the (collapsed) selection location
|
// Get the (collapsed) selection location
|
||||||
nsRange* firstRange = SelectionRefPtr()->GetRangeAt(0);
|
nsRange* firstRange = SelectionRefPtr()->GetRangeAt(0);
|
||||||
|
@ -9680,50 +9677,63 @@ void HTMLEditRules::CheckInterlinePosition() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
|
EditorDOMPoint atCaret(firstRange->StartRef());
|
||||||
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
|
if (NS_WARN_IF(!atCaret.IsSet())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
|
MOZ_ASSERT(atCaret.IsSetAndValid());
|
||||||
|
|
||||||
// First, let's check to see if we are after a <br>. We take care of this
|
// First, let's check to see if we are after a `<br>`. We take care of this
|
||||||
// special-case first so that we don't accidentally fall through into one of
|
// special-case first so that we don't accidentally fall through into one of
|
||||||
// the other conditionals.
|
// the other conditionals.
|
||||||
nsCOMPtr<nsIContent> node =
|
// XXX Although I don't understand "interline position", if caret is
|
||||||
HTMLEditorRef().GetPreviousEditableHTMLNodeInBlock(atStartOfSelection);
|
// immediately after non-editable contents, but previous editable
|
||||||
if (node && node->IsHTMLElement(nsGkAtoms::br)) {
|
// content is `<br>`, does this do right thing?
|
||||||
|
if (nsIContent* previousEditableContentInBlock =
|
||||||
|
GetPreviousEditableHTMLNodeInBlock(atCaret)) {
|
||||||
|
if (previousEditableContentInBlock->IsHTMLElement(nsGkAtoms::br)) {
|
||||||
IgnoredErrorResult ignoredError;
|
IgnoredErrorResult ignoredError;
|
||||||
SelectionRefPtr()->SetInterlinePosition(true, ignoredError);
|
SelectionRefPtr()->SetInterlinePosition(true, ignoredError);
|
||||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
NS_WARNING_ASSERTION(
|
||||||
"Failed to set interline position");
|
!ignoredError.Failed(),
|
||||||
|
"Selection::SetInterlinePosition(true) failed, but ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atCaret.GetChild()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we after a block? If so try set caret to following content
|
// If caret is immediately after a block, set interline position to "right".
|
||||||
if (atStartOfSelection.GetChild()) {
|
// XXX Although I don't understand "interline position", if caret is
|
||||||
node = HTMLEditorRef().GetPriorHTMLSibling(atStartOfSelection.GetChild());
|
// immediately after non-editable contents, but previous editable
|
||||||
} else {
|
// content is a block, does this do right thing?
|
||||||
node = nullptr;
|
if (nsIContent* previousEditableContentInBlockAtCaret =
|
||||||
}
|
GetPriorHTMLSibling(atCaret.GetChild())) {
|
||||||
if (node && HTMLEditor::NodeIsBlockStatic(*node)) {
|
if (HTMLEditor::NodeIsBlockStatic(*previousEditableContentInBlockAtCaret)) {
|
||||||
IgnoredErrorResult ignoredError;
|
IgnoredErrorResult ignoredError;
|
||||||
SelectionRefPtr()->SetInterlinePosition(true, ignoredError);
|
SelectionRefPtr()->SetInterlinePosition(true, ignoredError);
|
||||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
NS_WARNING_ASSERTION(
|
||||||
"Failed to set interline position");
|
!ignoredError.Failed(),
|
||||||
|
"Selection::SetInterlinePosition(true) failed, but ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we before a block? If so try set caret to prior content
|
|
||||||
if (atStartOfSelection.GetChild()) {
|
|
||||||
node = HTMLEditorRef().GetNextHTMLSibling(atStartOfSelection.GetChild());
|
|
||||||
} else {
|
|
||||||
node = nullptr;
|
|
||||||
}
|
}
|
||||||
if (node && HTMLEditor::NodeIsBlockStatic(*node)) {
|
|
||||||
|
// If caret is immediately before a block, set interline position to "left".
|
||||||
|
// XXX Although I don't understand "interline position", if caret is
|
||||||
|
// immediately before non-editable contents, but next editable
|
||||||
|
// content is a block, does this do right thing?
|
||||||
|
if (nsIContent* nextEditableContentInBlockAtCaret =
|
||||||
|
GetNextHTMLSibling(atCaret.GetChild())) {
|
||||||
|
if (HTMLEditor::NodeIsBlockStatic(*nextEditableContentInBlockAtCaret)) {
|
||||||
IgnoredErrorResult ignoredError;
|
IgnoredErrorResult ignoredError;
|
||||||
SelectionRefPtr()->SetInterlinePosition(false, ignoredError);
|
SelectionRefPtr()->SetInterlinePosition(false, ignoredError);
|
||||||
NS_WARNING_ASSERTION(!ignoredError.Failed(),
|
NS_WARNING_ASSERTION(
|
||||||
"Failed to unset interline position");
|
!ignoredError.Failed(),
|
||||||
|
"Selection::SetInterlinePosition(false) failed, but ignored");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,8 +198,6 @@ class HTMLEditRules : public TextEditRules {
|
||||||
*/
|
*/
|
||||||
MOZ_MUST_USE nsresult PinSelectionToNewBlock();
|
MOZ_MUST_USE nsresult PinSelectionToNewBlock();
|
||||||
|
|
||||||
void CheckInterlinePosition();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DocumentModifiedWorker() is called by DocumentModified() either
|
* DocumentModifiedWorker() is called by DocumentModified() either
|
||||||
* synchronously or asynchronously.
|
* synchronously or asynchronously.
|
||||||
|
|
|
@ -2633,6 +2633,13 @@ class HTMLEditor final : public TextEditor,
|
||||||
*/
|
*/
|
||||||
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult RemoveEmptyNodesIn(nsRange& aRange);
|
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult RemoveEmptyNodesIn(nsRange& aRange);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SetSelectionInterlinePosition() may set interline position if caret is
|
||||||
|
* positioned around `<br>` or block boundary. Don't call this when
|
||||||
|
* `Selection` is not collapsed.
|
||||||
|
*/
|
||||||
|
void SetSelectionInterlinePosition();
|
||||||
|
|
||||||
protected: // Called by helper classes.
|
protected: // Called by helper classes.
|
||||||
virtual void OnStartToHandleTopLevelEditSubAction(
|
virtual void OnStartToHandleTopLevelEditSubAction(
|
||||||
EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;
|
EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче