зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1757923 - Make ElementInternals keeping the target element alive; r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D140310
This commit is contained in:
Родитель
cab117c6f9
Коммит
95e0e6704c
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
class CustomElement extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
let element = document.createElement("custom-element");
|
||||
customElements.define("custom-element", CustomElement);
|
||||
customElements.upgrade(element);
|
||||
|
||||
const internals = element.attachInternals();
|
||||
element = undefined;
|
||||
SpecialPowers.forceGC();
|
||||
SpecialPowers.forceCC();
|
||||
internals.shadowRoot;
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
|
@ -265,3 +265,4 @@ skip-if(winWidget||Android) pref(print.always_print_silent,true) pref(print.prin
|
|||
skip-if(ThreadSanitizer||Android) load 1697525.html
|
||||
skip-if(ThreadSanitizer||Android) load 1712198.html # Mysterious failure that should be investigated (bug 1712866).
|
||||
skip-if(Android) HTTP load 1728670-1.html
|
||||
load 1757923.html
|
||||
|
|
|
@ -19,8 +19,22 @@
|
|||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ElementInternals, mSubmissionValue,
|
||||
mState, mValidity, mValidationAnchor)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(ElementInternals)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ElementInternals)
|
||||
tmp->Unlink();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTarget, mSubmissionValue, mState, mValidity,
|
||||
mValidationAnchor);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ElementInternals)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTarget, mSubmissionValue, mState,
|
||||
mValidity, mValidationAnchor);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(ElementInternals)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ElementInternals)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ElementInternals)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ElementInternals)
|
||||
|
@ -59,12 +73,14 @@ void ElementInternals::SetFormValue(
|
|||
const Nullable<FileOrUSVStringOrFormData>& aValue,
|
||||
const Optional<Nullable<FileOrUSVStringOrFormData>>& aState,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
/**
|
||||
* 1. Let element be this's target element.
|
||||
* 2. If element is not a form-associated custom element, then throw a
|
||||
* "NotSupportedError" DOMException.
|
||||
*/
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return;
|
||||
|
@ -118,7 +134,9 @@ void ElementInternals::SetFormValue(
|
|||
|
||||
// https://html.spec.whatwg.org/#dom-elementinternals-form
|
||||
HTMLFormElement* ElementInternals::GetForm(ErrorResult& aRv) const {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return nullptr;
|
||||
|
@ -130,12 +148,14 @@ HTMLFormElement* ElementInternals::GetForm(ErrorResult& aRv) const {
|
|||
void ElementInternals::SetValidity(
|
||||
const ValidityStateFlags& aFlags, const Optional<nsAString>& aMessage,
|
||||
const Optional<NonNull<nsGenericHTMLElement>>& aAnchor, ErrorResult& aRv) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
/**
|
||||
* 1. Let element be this's target element.
|
||||
* 2. If element is not a form-associated custom element, then throw a
|
||||
* "NotSupportedError" DOMException.
|
||||
*/
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return;
|
||||
|
@ -204,7 +224,9 @@ void ElementInternals::SetValidity(
|
|||
|
||||
// https://html.spec.whatwg.org/#dom-elementinternals-willvalidate
|
||||
bool ElementInternals::GetWillValidate(ErrorResult& aRv) const {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return false;
|
||||
|
@ -214,7 +236,9 @@ bool ElementInternals::GetWillValidate(ErrorResult& aRv) const {
|
|||
|
||||
// https://html.spec.whatwg.org/#dom-elementinternals-validity
|
||||
ValidityState* ElementInternals::GetValidity(ErrorResult& aRv) {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return nullptr;
|
||||
|
@ -225,7 +249,9 @@ ValidityState* ElementInternals::GetValidity(ErrorResult& aRv) {
|
|||
// https://html.spec.whatwg.org/#dom-elementinternals-validationmessage
|
||||
void ElementInternals::GetValidationMessage(nsAString& aValidationMessage,
|
||||
ErrorResult& aRv) const {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return;
|
||||
|
@ -235,7 +261,9 @@ void ElementInternals::GetValidationMessage(nsAString& aValidationMessage,
|
|||
|
||||
// https://html.spec.whatwg.org/#dom-elementinternals-checkvalidity
|
||||
bool ElementInternals::CheckValidity(ErrorResult& aRv) {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return false;
|
||||
|
@ -245,7 +273,9 @@ bool ElementInternals::CheckValidity(ErrorResult& aRv) {
|
|||
|
||||
// https://html.spec.whatwg.org/#dom-elementinternals-reportvalidity
|
||||
bool ElementInternals::ReportValidity(ErrorResult& aRv) {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return false;
|
||||
|
@ -289,7 +319,9 @@ bool ElementInternals::ReportValidity(ErrorResult& aRv) {
|
|||
// https://html.spec.whatwg.org/#dom-elementinternals-labels
|
||||
already_AddRefed<nsINodeList> ElementInternals::GetLabels(
|
||||
ErrorResult& aRv) const {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return nullptr;
|
||||
|
@ -299,7 +331,9 @@ already_AddRefed<nsINodeList> ElementInternals::GetLabels(
|
|||
|
||||
nsGenericHTMLElement* ElementInternals::GetValidationAnchor(
|
||||
ErrorResult& aRv) const {
|
||||
if (!mTarget || !mTarget->IsFormAssociatedElement()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
|
||||
if (!mTarget->IsFormAssociatedElement()) {
|
||||
aRv.ThrowNotSupportedError(
|
||||
"Target element is not a form-associated custom element");
|
||||
return nullptr;
|
||||
|
@ -379,7 +413,6 @@ void ElementInternals::Unlink() {
|
|||
if (mFieldSet) {
|
||||
mFieldSet->RemoveElement(mTarget);
|
||||
}
|
||||
mTarget = nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
|
|
@ -87,9 +87,7 @@ class ElementInternals final : public nsIFormControl,
|
|||
~ElementInternals() = default;
|
||||
|
||||
// It's a target element which is a custom element.
|
||||
// It's safe to use raw pointer because it will be reset via
|
||||
// CustomElementData::Unlink when mTarget is released or unlinked.
|
||||
HTMLElement* mTarget;
|
||||
RefPtr<HTMLElement> mTarget;
|
||||
|
||||
// The form that contains the target element.
|
||||
// It's safe to use raw pointer because it will be reset via
|
||||
|
|
Загрузка…
Ссылка в новой задаче