Bug 1778345 - Align PerformanceEventTiming::GetAnElement with the spec r=emilio

There are two bugs in this function, first the function doesn't do
the `is not connected` check correctly as it supposes to use
`IsInComposed()` but rather `IsInUnComposed()`. Second, it
doesn't get the root of the element correctly.

Also this patch converts the function be static so that it can be
reused.

Differential Revision: https://phabricator.services.mozilla.com/D151081
This commit is contained in:
Sean Feng 2022-07-06 20:11:44 +00:00
Родитель 85fad4f836
Коммит 6910219457
4 изменённых файлов: 44 добавлений и 34 удалений

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

@ -2538,6 +2538,32 @@ nsINode* nsContentUtils::Retarget(nsINode* aTargetA, nsINode* aTargetB) {
return nullptr;
}
// static
nsINode* nsContentUtils::GetAnElementForTiming(Element* aTarget,
const Document* aDocument,
nsIGlobalObject* aGlobal) {
if (!aTarget->IsInComposedDoc()) {
return nullptr;
}
if (!aDocument) {
nsCOMPtr<nsPIDOMWindowInner> inner = do_QueryInterface(aGlobal);
if (!inner) {
return nullptr;
}
aDocument = inner->GetExtantDoc();
}
MOZ_ASSERT(aDocument);
if (aTarget->GetUncomposedDocOrConnectedShadowRoot() != aDocument ||
!aDocument->IsCurrentActiveDocument()) {
return nullptr;
}
return aTarget;
}
// static
nsresult nsContentUtils::GetInclusiveAncestors(nsINode* aNode,
nsTArray<nsINode*>& aArray) {

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

@ -432,6 +432,13 @@ class nsContentUtils {
*/
static nsINode* Retarget(nsINode* aTargetA, nsINode* aTargetB);
/**
* @see https://wicg.github.io/element-timing/#get-an-element
*/
static nsINode* GetAnElementForTiming(Element* aTarget,
const Document* aDocument,
nsIGlobalObject* aGlobal);
/*
* https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor.
*

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

@ -10,6 +10,7 @@
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/Event.h"
#include "nsContentUtils.h"
#include "nsIDocShell.h"
#include <algorithm>
@ -167,16 +168,18 @@ void PerformanceEventTiming::BufferEntryIfNeeded() {
}
nsINode* PerformanceEventTiming::GetTarget() const {
if (!mTarget) {
nsCOMPtr<Element> element = do_QueryReferent(mTarget);
if (!element) {
return nullptr;
}
nsCOMPtr<nsINode> target = do_QueryReferent(mTarget);
if (!target || !target->IsInUncomposedDoc()) {
nsCOMPtr<nsPIDOMWindowInner> global =
do_QueryInterface(element->GetOwnerGlobal());
if (!global) {
return nullptr;
}
return target;
return nsContentUtils::GetAnElementForTiming(element, global->GetExtantDoc(),
mPerformance->GetParentObject());
}
void PerformanceEventTiming::FinalizeEventTiming(EventTarget* aTarget) {
@ -191,36 +194,13 @@ void PerformanceEventTiming::FinalizeEventTiming(EventTarget* aTarget) {
mProcessingEnd = mPerformance->NowUnclamped();
nsINode* node = nsINode::FromEventTarget(aTarget);
if (!node || node->ChromeOnlyAccess()) {
Element* element = Element::FromEventTarget(aTarget);
if (!element || element->ChromeOnlyAccess()) {
return;
}
mTarget = do_GetWeakReference(GetAnElement(node, global->GetExtantDoc()));
mTarget = do_GetWeakReference(element);
mPerformance->InsertEventTimingEntry(this);
}
nsINode* PerformanceEventTiming::GetAnElement(nsINode* aTarget,
const Document* aDocument) {
if (!aTarget->IsInUncomposedDoc()) {
return nullptr;
}
if (!aDocument) {
nsCOMPtr<nsPIDOMWindowInner> inner =
do_QueryInterface(mPerformance->GetParentObject());
MOZ_ASSERT(inner);
aDocument = inner->GetExtantDoc();
}
MOZ_ASSERT(aDocument);
if (aTarget->GetComposedDoc() != aDocument ||
!aDocument->IsCurrentActiveDocument()) {
return nullptr;
}
return aTarget;
}
} // namespace mozilla::dom

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

@ -114,9 +114,6 @@ class PerformanceEventTiming final
~PerformanceEventTiming() = default;
// Perform the get an element algorithm
nsINode* GetAnElement(nsINode* aTarget, const Document* aDocument);
RefPtr<Performance> mPerformance;
DOMHighResTimeStamp mProcessingStart;