Bug 1668134 - part 1: Make `nsPIDOMWindowInner` have an API to know whether the window or its descendants has had `beforeinput` event listeners r=smaug

When `HTMLEditor` instances are destroyed, I'd like to collect how much
instances are worked with `beforeinput` event listeners.  Before adding such
telemetry probe, this patch adds methods to set/get whether a `beforeinput`
event listener has had added or not to `nsPIDOMWindowInner`.

Differential Revision: https://phabricator.services.mozilla.com/D92546
This commit is contained in:
Masayuki Nakano 2020-10-08 02:25:35 +00:00
Родитель 580c003812
Коммит 8c5fa85517
7 изменённых файлов: 52 добавлений и 12 удалений

Просмотреть файл

@ -7479,6 +7479,7 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
mMayHaveSelectionChangeEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mMayHaveBeforeInputEventListenerForTelemetry(false),
mOuterWindow(aOuterWindow),
mWindowID(0),
mHasNotifiedGlobalCreated(false),

Просмотреть файл

@ -224,6 +224,24 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
mMayHavePointerEnterLeaveEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a beforeinput event listener.
* Returing false may be wrong if some nodes have come from another document
* with `Document.adoptNode`.
*/
bool HasBeforeInputEventListenersForTelemetry() const {
return mMayHaveBeforeInputEventListenerForTelemetry;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a beforeinput event listener.
*/
void SetHasBeforeInputEventListenersForTelemetry() {
mMayHaveBeforeInputEventListenerForTelemetry = true;
}
// Sets the event for window.event. Does NOT take ownership, so
// the caller is responsible for clearing the event before the
// event gets deallocated. Pass nullptr to set window.event to
@ -588,6 +606,9 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
bool mMayHaveSelectionChangeEventListener;
bool mMayHaveMouseEnterLeaveEventListener;
bool mMayHavePointerEnterLeaveEventListener;
// Only used for telemetry probes. This may be wrong if some nodes have
// come from another document with `Document.adoptNode`.
bool mMayHaveBeforeInputEventListenerForTelemetry;
// Our inner window's outer window.
nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;

Просмотреть файл

@ -382,6 +382,10 @@ void EventListenerManager::AddEventListenerInternal(
doc->SetUseCounter(eUseCounter_custom_onfinish);
}
}
} else if (aTypeAtom == nsGkAtoms::onbeforeinput) {
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
window->SetHasBeforeInputEventListenersForTelemetry();
}
}
if (IsApzAwareListener(listener)) {

Просмотреть файл

@ -2483,7 +2483,7 @@ EditorBase::ComputeInsertedRange(const EditorDOMPointInText& aInsertedPoint,
// The DOM was potentially modified during the transaction. This is possible
// through mutation event listeners. That is, the node could've been removed
// from the doc or otherwise modified.
if (!MaybeHasMutationEventListeners(
if (!MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED)) {
EditorDOMPointInText endOfInsertion(
aInsertedPoint.ContainerAsText(),

Просмотреть файл

@ -205,7 +205,7 @@ class EditorBase : public nsIEditor,
}
/**
* MaybeHasMutationEventListeners() returns true when the window may have
* MayHaveMutationEventListeners() returns true when the window may have
* mutation event listeners.
*
* @param aMutationEventType One or multiple of NS_EVENT_BITS_MUTATION_*.
@ -213,7 +213,7 @@ class EditorBase : public nsIEditor,
* and at least one of NS_EVENT_BITS_MUTATION_* is
* set to the window or in debug build.
*/
bool MaybeHasMutationEventListeners(
bool MayHaveMutationEventListeners(
uint32_t aMutationEventType = 0xFFFFFFFF) const {
if (IsTextEditor()) {
// DOM mutation event listeners cannot catch the changes of
@ -232,6 +232,20 @@ class EditorBase : public nsIEditor,
#endif // #ifdef DEBUG #else
}
/**
* MayHaveBeforeInputEventListenersForTelemetry() returns true when the
* window may have or have had one or more `beforeinput` event listeners.
* Note that this may return false even if there is a `beforeinput`.
* See nsPIDOMWindowInner::HasBeforeInputEventListenersForTelemetry()'s
* comment for the detail.
*/
bool MayHaveBeforeInputEventListenersForTelemetry() const {
if (const nsPIDOMWindowInner* window = GetInnerWindow()) {
return window->HasBeforeInputEventListenersForTelemetry();
}
return false;
}
PresShell* GetPresShell() const {
return mDocument ? mDocument->GetPresShell() : nullptr;
}

Просмотреть файл

@ -3785,7 +3785,7 @@ EditActionResult HTMLEditor::AutoDeleteRangesHandler::Run(
"invalid");
return EditActionHandled(NS_ERROR_FAILURE);
}
if (aHTMLEditor.MaybeHasMutationEventListeners(
if (aHTMLEditor.MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED |
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT)) {
@ -4241,7 +4241,7 @@ EditActionResult HTMLEditor::AutoDeleteRangesHandler::
"failed");
return EditActionResult(rv);
}
if (aHTMLEditor.MaybeHasMutationEventListeners(
if (aHTMLEditor.MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
NS_EVENT_BITS_MUTATION_ATTRMODIFIED |
@ -5871,7 +5871,7 @@ HTMLEditor::AutoDeleteRangesHandler::DeleteParentBlocksWithTransactionIfEmpty(
// If we have mutation event listeners, the next point is now outside of
// editing host or editing hos has been changed.
if (aHTMLEditor.MaybeHasMutationEventListeners(
if (aHTMLEditor.MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED)) {
@ -6534,7 +6534,7 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
break; // There is no more text which we need to delete.
}
}
if (MaybeHasMutationEventListeners(
if (MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED) &&
(NS_WARN_IF(!trackingEndToDelete.IsSetAndValid()) ||
NS_WARN_IF(!trackingEndToDelete.IsInTextNode()))) {
@ -6547,7 +6547,7 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
// we should stop handling the deletion.
startToDelete =
EditorDOMPointInText::AtEndOf(*startToDelete.ContainerAsText());
if (MaybeHasMutationEventListeners(
if (MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED) &&
NS_WARN_IF(!startToDelete.IsBefore(endToDelete))) {
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
@ -6574,7 +6574,7 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
if (normalizedWhiteSpacesInLastNode.IsEmpty()) {
break; // There is no more text which we need to delete.
}
if (MaybeHasMutationEventListeners(
if (MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED |
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
@ -7264,7 +7264,7 @@ MoveNodeResult HTMLEditor::MoveOneHardLineContents(
NS_SUCCEEDED(rvIgnored),
"HTMLEditor::DeleteNodeWithTransaction() failed, but ignored");
result.MarkAsHandled();
if (MaybeHasMutationEventListeners()) {
if (MayHaveMutationEventListeners()) {
// Mutation event listener may make `offset` value invalid with
// removing some previous children while we call
// `DeleteNodeWithTransaction()` so that we should adjust it here.
@ -7351,7 +7351,7 @@ MoveNodeResult HTMLEditor::MoveNodeOrChildrenWithTransaction(
NS_WARNING("HTMLEditor::DeleteNodeWithTransaction() failed");
return MoveNodeResult(rv);
}
if (MaybeHasMutationEventListeners()) {
if (MayHaveMutationEventListeners()) {
// Mutation event listener may make `offset` value invalid with
// removing some previous children while we call
// `DeleteNodeWithTransaction()` so that we should adjust it here.

Просмотреть файл

@ -1826,7 +1826,7 @@ nsresult WhiteSpaceVisibilityKeeper::
}
EditorDOMRange rangeToDelete(aRangeToDelete);
bool mayBecomeUnexpectedDOMTree = aHTMLEditor.MaybeHasMutationEventListeners(
bool mayBecomeUnexpectedDOMTree = aHTMLEditor.MayHaveMutationEventListeners(
NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED |
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |