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
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
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
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
Using concrete class rather than interface classes (nsI*Editor) will allow to reduce QI and some virtual calls. Therefore, Editor classes should be used as concrete class as far as possible.
Unfortunately, if classes referring editor are initialized via scriptable interface, we cannot do this because nsI*Editor is still not marked as builtinclass. Therefore, their editor may be implemented by JS. E.g., inline nsIInlineSpellChecker.init() and nsIDocShell.editor. Such remaining cases should be fixed after nsI*Editor classes are marked as builtinclass.
Note that this patch also creates nsIdentifierMapEntry.h which is separated from nsDocument.h because ShadowRoot.h needs the class but exposing nsDocument.h to the global and includes it causes bustage on Linux and Android. Therefore, for fixing the include hell, this patch touches them and ContentChild.cpp.
MozReview-Commit-ID: i6fLWw6Qeo
We get previous input.value twice in HTMLInputElement::SetValue and nsTextEditorState::SetValue when setting input.value. Since nsTextEditorState::GetValue uses DocumentEncoder, it is expensive. So we should use old value as parameter of nsTextEditorState::SetValue if possible.
MozReview-Commit-ID: A1UPfETTVCn
Actually, we use GetValue to check whether value is empty or not for placeholder. But since GetValue uses TextEditor::OutputToString when on editor, it is expensive. Since editor has DocumentIsEmpty method, we should use it for this case.
MozReview-Commit-ID: rQX8yjnWQz
maxlength will be set by nsTextControlFrame::AttributeChanged via RestyleManager. If element is display:none, RestyleManager won't call Frame's AttributeChanged. So we should always initialize maxlength when setting focus.
Also, wrap attribute for textarea element will be updated by HTMLTextAreaElement even if display:none. So this issue doesn't occur. maxlength might have to be updated by HTMLInputElement. But it is unnecessary to update editor's maxlength on display:none since this is used on focused editor.
MozReview-Commit-ID: JHODOBTv62v
This introduces two behavior changes:
1) In cached mode, we used to treat unknown selection directions as "none".
Now we treat it like "forward", consistently with the "have an editor" mode.
2) Before this change, in cached mode, we did not fire "select" events on
selectionDirection changes.
MozReview-Commit-ID: 4nBCAm3mAiz
This introduces three behavior changes:
1) Before this change, in cached mode, we did not enforce the "start <= end"
invariant.
2) Before this change, in cached mode, we did not fire "select" events on
selectionEnd changes.
3) Changes the IDL type of HTMLInputElement's selectionEnd attribute to
"unsigned long" to match the spec and HTMLTextareaElement.
MozReview-Commit-ID: J3Gkhr8VnbS
This introduces three behavior changes:
1) Before this change, in cached mode, we did not enforce the "start <= end"
invariant.
2) Before this change, in cached mode, we did not fire "select" events on
selectionStart changes.
3) Changes the IDL type of HTMLInputElement's selectionStart attribute to
"unsigned long" to match the spec and HTMLTextareaElement.
MozReview-Commit-ID: JM9XXMMPUHM
Really, there are only two cases we need to worry about. Either
IsSelectionCached(), and then our SelectionProperties has the data we want, or
not and then we have a non-null mSelCon which has the data we want.
MozReview-Commit-ID: AEW9D1zG6sM
Really, there are only two cases we need to worry about. Either
IsSelectionCached(), and then our SelectionProperties has the data we want, or
not and then we have a non-null mSelCon which has the data we want.
Since we are now using cached selection state a lot more (instead of
initializing the editor whenever someone asks for selection state), we need to
actually update it more correctly when .value is set.
And since we now update the cached selection state for the case when .value has
been set (to point to the end of the text), we need to change
HTMLInputElement::HasCachedSelection to return false for that case. Otherwise
we will always do eager editor init on value set. We handle that by not doing
eager init if the cached selection is collapsed.
The web platform test changes test the "update on .value set" behavior. They
fail without this patch, pass with it.
MozReview-Commit-ID: DDU8U4MGb23
At this point, all this method does is ensure editor initialization and then ask
the editor state for various information. Let's cut out the middleman.
MozReview-Commit-ID: p491umScJO
AFAICT this doesn't change behavior, since all the callers of GetRootNode should
occur after we've already called BindToFrame. However, it makes it easier for
future static analysis to see that we don't trigger node creation from
nsTextControlFrame::AppendAnonymousContentTo.
I don't know the full history here; roc asked about this exact thing in
bug 534785 when reviewing the creation of nsTextEditorState. The answer
then was "historical reasons" (the original code is hg@1)...maybe to try
and save some space? Regardless, since the only thing we do here is
convert from/to incoming/outgoing nsStrings, which at least sometimes
appear to be causing OOMs, we might as well hold it as an nsString all
the time. This change will ideally eliminate allocations, as we'll be
able to use nsString's buffer sharing underneath the hood.
This change is just a minor tidying; we need to distinguish between
"have a value" and "don't have a value" in nsTextEditorState::GetValue,
but we can do better than heap-allocating the string.
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
The bulk of this commit was generated by running:
run-clang-tidy.py \
-checks='-*,llvm-namespace-comment' \
-header-filter=^/.../mozilla-central/.* \
-fix
This patch handles most of the call sites for these allocations except
for a few where I added TODO comments with some information. Handling
those places may require reworking lots of code, so I prefer to not do
that here.