According to existing comments, TextEditor::TypedText() and
HTMLEditor::TypedText() are intentional bottleneck to debug. However, only
for that purpose, it and its internal methods are made virtual. This really
doesn't make sense.
So, this patch creates TextEditor::OnInputText() for callers of TypedText()
with non-empty string, TextEditor::OnInputParagraphSeparator() for callers
of TypedText() with eTypeBreak (Enter key or insertParagraphSeparator),
HTMLEditor::OnInputLineBreak() for callers of TypedText() with eTypeBR
(Shift + Enter or insertLineBreak). Additionally, this creates internal
non-virtual methods for XPCOM methods which are used as internal methods of
TypedText(). One is InsertTextAsAction() for nsIPlatintextEditor.insertText().
the other is InsertParagraphSeparator() for nsIPlaintextEditor.insertLineBreak().
Although those new methods are not have "WithTransaction" postfix, they must
be clearer they'll use transactions since user input and actions should be
undo-able.
MozReview-Commit-ID: AmOkMqovIKA
--HG--
extra : rebase_source : 9c0f4b25fa2a36ad2f3394f72eb290824c31d82a
First, EditorBase::DeleteSelection() is never used since
TextEditor::DeleteSelection() overrides it but does not call it. So, this patch
makes EditorBase::DeleteSelection() only returns NS_ERROR_NOT_IMPLEMENTED.
Next, EditorBase::DeleteSelectionImpl() actually removes content for
TextEditor::DeleteSelection(). So, it should be named as
DeleteSelectionWithTransaction(). However, it'll be done in the following
patch. On the other hand, its callers are EditorBase::HandleKeyPressEvent()
and EditorBase::DeleteSelectionAndPrepareToCreateNode(). Fortunately, they
can be moved to TextEditor simply. Therefore this patch moves the methods
to TextEditor for making related methods in a place.
Then, we can make the implementation of nsIEditor::TextEditor() as a non-virtual
method, TextEditor::DeleteSelectionAsAction().
MozReview-Commit-ID: KXFDhW3G9lA
--HG--
extra : rebase_source : 15986979279b2cae3b61cda1bf6bf3d9e4987f3f
So, this patch replaces the setter with non-virtual method and removing the
getter since where is already non-virtual getter method.
MozReview-Commit-ID: Is19Yriz8t8
--HG--
extra : rebase_source : bb2f49f380ddb2e2f96e8690effd8d47d24ae0ae
And then fix up everything else that needs to change as well.
MozReview-Commit-ID: GDMfERqdQAc
--HG--
extra : rebase_source : 01fe06c3182245a409099a53383d92bf4fa0155c
nsIEditor::EnableUndo() and nsITransactionManager::Clear(),
nsITransactionManager::SetMaxTransactionCount() are called a lot but they are
virtual and some of or all of them are called once. There should be each
non-virtual method to do what each root caller wants. Therefore, this patch
adds EditorBase::EnableUndoRedo(), EditorBase::DisableUndoRedo(),
EditorBase::ClearUndoRedo(), TransactionManager::EnableUndoRedo(),
TransactionManager::DisableUndoRedo() and TransactionManager::ClearUndoRedo().
Note that this patch makes TransactionManager won't clear mUndoStack nor
mRedoStack if mDoStack is not empty. This is checked only by
TransactionManager::SetMaxTransactionCount() but according to the comment,
TransactionManager::Clear(), TransactionManager::UndoStack() and
TransactionManager::RedoStack() should check it too.
MozReview-Commit-ID: 6qBZOQNwdhw
--HG--
extra : rebase_source : 3249137f7acca0b4698713ab732774140bcc27e8
Now, both TransactionManager.h and TransactionStack.h are exposed. So,
TransactionManager::GetNumberOfUndoItems() and
TransactionManager::GetNumberOfRedoItems() can be rewritten with non-virtual
inline methods because they just return mUndoStack.GetSize() and
mRedoStack.GetSize(). Then, we can implement EditorBase::NumbeOfUndoItems(),
EditorBase::NumberOfRedoItems(), EditorBase::CanUndo() and
EditorBase::CanRedo() as inline methods.
MozReview-Commit-ID: 3CJd0VrlvFY
--HG--
extra : rebase_source : 6848d80a395f1c161e10bfb50d15bd63de288095
nsTextEditorState is reusable object by HTMLInputElement. When it is unused,
it will call Unlink method to remove dependency of HTMLInputElement etc.
So we should reset TextInputListener on Editor too on Unlink because anyone might call nsTextEditorState from TextInputListener.
MozReview-Commit-ID: DZFyIguJLLB
--HG--
extra : rebase_source : 0ce7f4efdedb5a4181336f5a1ea34333e110a8fb
Since We can use EditorBase/TextEditor/HTMLEditor directly, we can
movei noscript methods in nsIEditor to each class.
Also, Init is unnecessary to use nsIDOMDocument and nsIContent since method
isn't in IDL. And some methods are unused now.
MozReview-Commit-ID: D3B6oSlcT0L
--HG--
extra : rebase_source : 6cab2e6e7b4ba8cfb56d8320be24ca4afcbe55fb
extra : amend_source : 1d8c59086a9158a49dd270b64ecf8341ed4002ce
This patch makes EditorBase derived from nsISelectionListener. Then, we can
make IMEContentObserver, TextInputListener, ComposerCommandsUpdater,
TypeInState not derived from nsISelectionListener since EditorBase or
HTMLEditor can notify them of selection change directly. Additionally,
ResizerSelectionListener is not necessary anymore since it just implements
nsISelectionListener and calls only a method of HTMLEditor. So, HTMLEditor
can call it directly.
Note that the order of selection listeners may be different. However,
according to what each selection listener does, changing the order isn't
problem.
MozReview-Commit-ID: 1JXZxQcS0tP
--HG--
extra : rebase_source : c2ebe622a74001ad4e421da492dcdab8e6fe1649
Now, EditorBase can store TextInputListener directly instead of as
nsIEditorObserver. And then, EditorBase can call its EditAction() method
directly. Therefore, we can make TextInputListener not derived from
nsIEditorObserver.
MozReview-Commit-ID: 4qPnnvReLKy
--HG--
extra : rebase_source : cde47e245c9856abf696dbaf8e26d8e4d6d98d42
EditorBase needs to access nsTextInputListener directly for saving runtime
cost of EditorBase::NotifyEditorObservers(). Therefore, it should be
exposed as "mozilla/TextInputLitener.h".
This patch rename it to mozilla::TextInputListener too.
MozReview-Commit-ID: 6PMzNWfTIHW
--HG--
rename : dom/html/nsTextEditorState.cpp => dom/html/TextInputListener.h
extra : rebase_source : 43c685a8f4c023c62bea26b3bf55b4f728ab438e
nsTextEditorState::GetValue() uses mCachedValue only when the value isn't empty
string. However, with SetIsVoid() and IsVoid() of nsAString, nsTextEditorState
can cache empty value only with mCachedValue.
MozReview-Commit-ID: AmQDquEn9M8
--HG--
extra : rebase_source : 3acfe765cbe37664ef3e28e640753da240bf38a4
Currently, nsTextEditorState caches the value of TextEditor only when it's for
a multi-line text control, i.e., <textarea>. However, using it for single-line
text control improves the score of attachment 8848015. Although this might
increase the cost of creating and registering mutation observer, but it may not
make damage to performance of loading pages since editor for each element won't
be initialized until each element gets focus.
MozReview-Commit-ID: DnjEJ5AUh3M
--HG--
extra : rebase_source : 8f45cb57ac03dff9a696acaaa5d0fd35faed0c09
nsTextEditorState::GetValue() refers nsITextControlElement::IsPlainTextControl()
via nsTextEditorState::IsPlainTextEditor(). However, it always returns true and
virtual call with QI. So, we should get rid of these unnecessary methods.
MozReview-Commit-ID: 3gHdGrzlys4
--HG--
extra : rebase_source : a1be33a18e93e64b8cc87e4f12d5e494b14520bf
When setting value of <input type="text">, nsTextEditorState removes all
ranges of normal selection first. Then, TextEditor sets the value. Finally,
TextEditor collapses the selection at the end of the text.
In bug 1386471, we got that there are some problems to remove the call of
Selection::RemoveAllRanges() in nsTextEditorState. Therefore, we need another
approach to improve Selection::Collapse().
The approach of this patch is, when removing all ranges from normal selection,
Selection can cache an nsRange instance if there is an instance which is not
referenced from other than the Selection (i.e., it'll be removed when
Selection::Clear() is called). Then, Selection::Collapse() can reuse it. With
this fix, Selection::Collapse() can reduce allocation cost and may reduce some
other cost like adding it to mutation observer.
However, keeping nsRange instance may cause increasing mutation observer's cost
since nsRange will be adjusted its start node/offset and end node/offset with
mutation observer to guarantee that the range is always valid. So, we can
cache such range only when the caller (or its callee) will set selection range
later. Therefore, this patch adds Selection::RemoveAllRangesTemporarily()
and make only nsTextEditorState::SetValue() and
ContentEventHandler::OnSelectionEvent() use it.
MozReview-Commit-ID: FjWrbz4S1ld
--HG--
extra : rebase_source : 83677640525e0b1a84bdd7fce63ff4704b9cc22b
nsTextEditorState stores selection controller as
RefPtr<nsTextInputSelectionImpl> mSelCon. However, some methods still use
nsTextInputSelectionImpl::GetSelection(RawSelectionType, nsISelection**) which
is a virtual method overriding nsISelectionController.
So, instead, we should make it use
nsTextInputSelectionImpl::GetSelection(SelectionType).
MozReview-Commit-ID: Cvxa85LegsO
--HG--
extra : rebase_source : f8618fb9b4b2a1d3a02b4ce49906c8b995766e3f
The failure mode in the attached crashtest is an inconsistency in the flattened
tree. Specifically, we null out mVideoControls in an nsVideoFrame, but defer
the UnbindFromTree call on that NAC element, which measn that its mParent still
points to the nsVideoFrame's mContent. Because all this stuff runs off of script
runners, and the anonymous content destroyer is not guaranteed to run before
other potential script runners, we end up running arbitrary script while the
tree mismatch exists. This script calls back into ProcessPendingRestyles, which
causes trouble.
We could build a separate deferral mechanism, but it's not clear that we actually
need to defer the unbind anymore. The deferred unbind was added in bug 489008,
which predated a lot of simplifications in layout/dom interaction.
MozReview-Commit-ID: 1JYAhiXKVJC
nsTextFrame stores text as single byte character array if all characters are
less than U+0100. Although, this saves footprint, but retrieving and modifying
text needs converting cost. Therefore, if it's created for a text node in
<input> or <textarea>, it should store text as char16_t array.
MozReview-Commit-ID: 9Z82rketT7g
--HG--
extra : rebase_source : 59f59ac1488c21a57d95d253cc794a011d672c95