When defaultParagraphSeparator is not "br", and we hit Enter on a line
that is not contained in any block element, we first create a new <div>
(or <p>) wrapper to hold the line's contents. If creating this wrapper
fails for some reason, we go ahead and insert a <br> instead.
In some cases, we would get confused and think we didn't create the
block element when really we did. We would insert a <br>, and
afterwards something would get rid of the empty block element. In a
corner case where the line only consisted of a <br> to start with, this
would result in nothing happening, because the original <br> was removed
when creating the block element, and only one <br> was inserted to
replace it.
The correct fix is to just not get confused!
MozReview-Commit-ID: 1U8KHC71bfw
ConfirmSelectionInBody uses a lot of QI and TextEditUtils::IsBody call to check body element. So we shouldn't use nsIDOM* to avoid QI and EditorBase::GetTag().
Also, if did not found body element, it calls collapse to set caret. If collapse is successful, we might not have to check end selection... How do you think?
MozReview-Commit-ID: F7FhPrlEpCc
*aHandled was previously always set to true in WillMakeBasicBlock, which
was probably a bug but is not addressed in this commit.
MozReview-Commit-ID: 41JSmptVc0l
Before this change, if you did formatBlock on "a<span
contenteditable=false>b</span>c", it would become "acb", because the "a"
and "c" would be moved to the front of the node, and the "b" would be
left alone at the end because the editing code doesn't want to move it.
Now we will move the "b" as well, even though it's not editable, so that
the node remains "abc". The rule is that a non-editable element cannot
have its attributes or children changed, but it can have its parent
changed, so there's nothing wrong with moving it here.
On the way, I fixed an exception in insert*List if there was an
uneditable inline node around. I don't intend to fix all the todo's in
the test, but now it should have better coverage, at least.
MozReview-Commit-ID: 3okcGq4an3f
I don't personally agree with this behavior (although I did spec it some
years ago), but it's the behavior of all other UAs, so we should do it
anyway.
MozReview-Commit-ID: IiIg41kMJIU
At first, HTMLEditor::GetActiveEditingHost might return null in this situation, we should check whether nullptr is returned. At second, SplitNodeDeep returns error since curent is design mode and selection node has no parent. So we should check error.
MozReview-Commit-ID: 2YlWXPNtf80
This is a kind of regression of bug 1088054 part 6. If new block doesn't have child node, GetLastEditableChild will return null after landing bug 1088054. So, we should use new block when GetLastEditableChild returns null.
MozReview-Commit-ID: Gzt1Xp3Sl47
***
P1
MozReview-Commit-ID: 8LVp5qGnme4
This is the patch that all the others have been leading up to: by inheriting from nsTStringRepr, nsTLiteralString loses its destructor (previously suppplied by nsTSubstring).
I included an AsString() cast as an escape hatch for a few pieces of code that couldn't easily accommodate the new hierarchy, but I'm pretty pleased with how little it was necessary.
MozReview-Commit-ID: 2zGkaw1sMUp
This is the patch that all the others have been leading up to: by inheriting from nsTStringRepr, nsTLiteralString loses its destructor (previously suppplied by nsTSubstring).
I included an AsString() cast as an escape hatch for a few pieces of code that couldn't easily accommodate the new hierarchy, but I'm pretty pleased with how little it was necessary.
MozReview-Commit-ID: 2zGkaw1sMUp
Before I will fix some justify* command's bug, I would like to clean up HTMLEditRules::RemoveAlignment to get rid of nsIDOM* into this method.
MozReview-Commit-ID: 4UATycS5iBl
RemoveEmptyNodes doesn't check whether parent node is null. So we shouldn't add null to skip list.
Also, although this crash depends on clang, if debug build, it will hit the assertion on all compiler.
MozReview-Commit-ID: GgiczVExlIn
HTMLEditRules can access both mTextEditor and mHTMLEditor, but we should use mHTMLEditor only on HTMLEditRules for readability.
MozReview-Commit-ID: HfzwAD554XQ
Some uses nsIDOMCharacterData to get the attribute of text node. But, by using Text object, we don't need nsIDOMCharacter. So we should use Text object instead of nsIDOMCharacterData instead if possible.
MozReview-Commit-ID: 1cwTUcecFj3
PopListItem still uses nsIDOM*. We should new binding API instead and it is unnecessary to use QI and refcounting if possible.
MozReview-Commit-ID: DJL105hNt6z
designMode is too strange. Parent of common ancestor of selection might be nullptr, so we should check whether nullptr.
MozReview-Commit-ID: Cy1k2Mpkws0
PopListItem still uses nsIDOM*. We should new binding API instead and it is unnecessary to use QI and refcounting if possible.
MozReview-Commit-ID: DJL105hNt6z
designMode is too strange. Parent of common ancestor of selection might be nullptr, so we should check whether nullptr.
MozReview-Commit-ID: Cy1k2Mpkws0
The target node of HTMLEditRules::ReapplyCachedStyles() may be styled with its parent. When HTMLEditRules::ReapplyCachedStyles() is called, it shouldn't restore another style cache if it's already specified in current DOM tree.
MozReview-Commit-ID: DKCpQ8YyW7
Most codes into HTMLEditRules and TextEditRules don't use explicitly static method call such as EditorBase::GetStartNodeAndOffset. So we should use it instead of "editor->GetStartNodeAndOffset".
MozReview-Commit-ID: DGAEFK6AYzh
In a lot of places, edit action handlers and their helper methods return nsresult and aHandled and aCanceled with out params. However, the out params cause the code complicated since:
* it's not unclear if the method will overwrite aHandled and aCanceled value.
* callers need to create temporary variable event if some of them are not necessary.
This patch rewrites the helper methods of HTMLEditRules::WillDeleteSelection() with it.
MozReview-Commit-ID: CJv75KdOdXf
When selection is collapsed and JoinBlocks() doesn't handle nor cancel the action, WillDeleteSelection() should move selection to the start/end of leftmost/rightmost editable leaf node and retry to handle the action again.
For avoiding infinite loop, it checks if selected node is changed actually before calling itself again.
MozReview-Commit-ID: GtEC4dim3r9
When HTMLEditRules::WillDeleteSelection() tries to remove something from the end/start of a block to its last/first text node but it's contained by block elements, it tries to join the container and the block. However, JoinBlocks() always fails to join them since it's impossible operation. In this case, HTMLEditRules::WillDeleteSelection() should retry to remove something in the leaf, however, it's impossible for now because JoinBlocks() and its helper methods don't return if it handles the action actually.
This patch renames |JoinBlocks()| to |TryToJoinBlocks()| for representing what it is. And this patch adds |bool* aHandled| to the helper methods. Then, *aHandled and *aCancel are now always returns the result of each method. Therefore, for merging the result of multiple helper methods, callers need to receive the result with temporary variables and merge them by themselves.
Note that when they modify DOM node actually or the action should do nothing (for example, selection is across tables), aHandled is set to true.
MozReview-Commit-ID: 7ApUOgtLUog
If not text node, QI to nsIContent will be failed. So we should use IsNodeType (Or EditorBase::IsTextNode) without QI for detection of text node.
Also, to get content length into text node, we should use TextLength() simply instead of getting content string. It can reduce memory allocation.
MozReview-Commit-ID: C8EKxfUBjTP
Although GetGoodSelPointForNode only supports ePrevious or eNext as action, we use other action. So we should add aseetion for it.
MozReview-Commit-ID: 3gLFFTAdNxU
Currently, when selection is collapsed at an empty text node, the behavior of each major browser is different.
When you remove the last character of non-empty text node followed by empty text nodes, Chromium removes all following empty text nodes. However, Edge never removes empty text nodes even when selection is collapsed at an empty text node.
With this patch, our behavior becomes same as Edge. I think that we should take this for keeping backward compatibility since Gecko never removes empty text nodes. So, in other words, this patch makes Backspace key press at an empty text node modify the preceding non-empty text node.
When you remove the first character of non-empty text node preceded with empty text nodes, Edge removes all preceding empty text nodes. However, Chromium and Gecko keeps previous empty text nodes than caret position. So, we should keep current behavior for backward compatibility. In other words, this patch makes Delete key press at an empty text node modify the following non-empty text node and keep current behavior.
The fixing approach of this is, making WSRunObject::PriorVisibleNode() and WSRunObject::NextVisibleNode() ignore empty text node. This should make sense because empty text node is not a visible node. (On the other hand, when the DOMPoint has a null character, it should treat as visible character. That is visible with Unicode codepoint.)
MozReview-Commit-ID: 11YtqBktEvK
Giving '0' (literal zero) to nsCOMPtr is now ambiguous, as both
nsCOMPtr(decltype(nullptr)) and nsCOMPtr(T*) could be used.
In any case, our coding standards mandate the use of 'nullptr' for pointers.
So I'm changing all zeroes into nullptr's where necessary.
MozReview-Commit-ID: LXiZTu87Ck6
Currently, editor code uses following style (or similar style) in a lot of places:
if (foo)
{
}
else
{
}
This patch fixes this as conforming to our coding rules, i.e., it becomes:
if (foo) {
} else {
}
Additionally, this fixes other odd control statements in the files which include above issue because it's difficult to find following issues with searching the files:
* if (foo) bar;
* if (foo) { bar; }
* if (foo)
bar;
Finally, if it becomes much simpler than current code, this patch rewrites existing code with "early return style". But this case is only a few places because this is risky.
MozReview-Commit-ID: 2Gs26goWXrF
In our coding rules, variable names of nsresult should be rv. Indeed, when you see |rv| in the code, you must assume that its type if nsresult.
However, a lot of code under editor/ uses |res| for the variables of nsresult. Let's replace |res| with |rv|.
And this patch improves following points:
1. When |rv| is set in both |if| and |else| block and they are check outside of them, this moves the check into each |if| and |else| block because even if the failure is notified with warning, you cannot see which case was performed and failed. This change makes it clear.
2. When |return rv;| returns non-error code because |rv| is checked with NS_ENSURE_SUCCESS() immediately before, setting replacing it with |return NS_OK;| is clearer.
3. Move declaration of |nsresult rv| into smaller scope as far as possible. This prevents setting rv to unexpected value and easier to check its value at reading the code.
MozReview-Commit-ID: 9MAqj7sFey3
When deleting, we previously would only move the cursor back into the
previous block if the last leaf node was a text node, for some reason.
We should move into the previous block in other cases as well, like if
the leaf node is a collapsed <br>. (Probably it's not correct to move
backward into tables, but that already was happening if the table had
text at the end. There may be other cases where this is wrong.)
MozReview-Commit-ID: 8e0dTU3lNYO