Skip to content

Commit e5cf85c

Browse files
alicekcirkel@mozilla.com
authored andcommitted
Bug 1981341 - Add referenceTarget and shadowRootReferenceTarget attributes. r=webidl,emilio,hsivonen
Allows setting referenceTarget when creating shadow roots declaratively or programatically, and also getting the referenceTarget value for a shadow root. Differential Revision: https://phabricator.services.mozilla.com/D260140
1 parent dd68ccb commit e5cf85c

24 files changed

+1289
-1224
lines changed

dom/base/Element.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,16 +1349,19 @@ already_AddRefed<ShadowRoot> Element::AttachShadow(const ShadowRootInit& aInit,
13491349
OwnerDoc()->ReportShadowDOMUsage();
13501350
}
13511351

1352+
const nsString& referenceTarget = aInit.mReferenceTarget.WasPassed()
1353+
? aInit.mReferenceTarget.Value()
1354+
: VoidString();
13521355
return AttachShadowWithoutNameChecks(
13531356
aInit.mMode, DelegatesFocus(aInit.mDelegatesFocus), aInit.mSlotAssignment,
13541357
ShadowRootClonable(aInit.mClonable),
1355-
ShadowRootSerializable(aInit.mSerializable));
1358+
ShadowRootSerializable(aInit.mSerializable), referenceTarget);
13561359
}
13571360

13581361
already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
13591362
ShadowRootMode aMode, DelegatesFocus aDelegatesFocus,
13601363
SlotAssignmentMode aSlotAssignment, ShadowRootClonable aClonable,
1361-
ShadowRootSerializable aSerializable) {
1364+
ShadowRootSerializable aSerializable, const nsAString& aReferenceTarget) {
13621365
nsAutoScriptBlocker scriptBlocker;
13631366

13641367
auto* nim = mNodeInfo->NodeInfoManager();
@@ -1385,6 +1388,7 @@ already_AddRefed<ShadowRoot> Element::AttachShadowWithoutNameChecks(
13851388
RefPtr<ShadowRoot> shadowRoot = new (nim)
13861389
ShadowRoot(this, aMode, aDelegatesFocus, aSlotAssignment, aClonable,
13871390
aSerializable, ShadowRootDeclarative::No, nodeInfo.forget());
1391+
shadowRoot->SetReferenceTarget(aReferenceTarget);
13881392

13891393
if (NodeOrAncestorHasDirAuto()) {
13901394
shadowRoot->SetAncestorHasDirAuto();

dom/base/Element.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,8 @@ class Element : public FragmentOrElement {
14781478
ShadowRootMode aMode, DelegatesFocus = DelegatesFocus::No,
14791479
SlotAssignmentMode aSlotAssignmentMode = SlotAssignmentMode::Named,
14801480
ShadowRootClonable aClonable = ShadowRootClonable::No,
1481-
ShadowRootSerializable aSerializable = ShadowRootSerializable::No);
1481+
ShadowRootSerializable aSerializable = ShadowRootSerializable::No,
1482+
const nsAString& aReferenceTarget = EmptyString());
14821483

14831484
// Attach UA Shadow Root if it is not attached.
14841485
enum class NotifyUAWidgetSetup : bool { No, Yes };

dom/base/ShadowRoot.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ ShadowRoot::ShadowRoot(Element* aElement, ShadowRootMode aMode,
7070
mIsAvailableToElementInternals(false),
7171
mIsDeclarative(aDeclarative),
7272
mIsClonable(aIsClonable),
73-
mIsSerializable(aIsSerializable) {
73+
mIsSerializable(aIsSerializable),
74+
mReferenceTarget(nsGkAtoms::_empty) {
7475
// nsINode.h relies on this.
7576
MOZ_ASSERT(static_cast<nsINode*>(this) == reinterpret_cast<nsINode*>(this));
7677
MOZ_ASSERT(static_cast<nsIContent*>(this) ==
@@ -936,3 +937,7 @@ void ShadowRoot::GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult) {
936937
this, true, aResult, aOptions.mSerializableShadowRoots,
937938
aOptions.mShadowRoots);
938939
}
940+
void ShadowRoot::SetReferenceTarget(RefPtr<nsAtom> aTarget) {
941+
MOZ_ASSERT(aTarget);
942+
mReferenceTarget = std::move(aTarget);
943+
}

dom/base/ShadowRoot.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,19 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
275275

276276
void GetHTML(const GetHTMLOptions& aOptions, nsAString& aResult);
277277

278+
void GetReferenceTarget(nsAString& aResult) const {
279+
mReferenceTarget->ToString(aResult);
280+
}
281+
nsAtom* ReferenceTarget() const { return mReferenceTarget; }
282+
void SetReferenceTarget(const nsAString& aValue) {
283+
SetReferenceTarget(NS_Atomize(aValue));
284+
}
285+
void SetReferenceTarget(RefPtr<nsAtom> aTarget);
286+
Element* GetReferenceTargetElement() const {
287+
return mReferenceTarget->IsEmpty() ? nullptr
288+
: GetElementById(mReferenceTarget);
289+
}
290+
278291
protected:
279292
// FIXME(emilio): This will need to become more fine-grained.
280293
void ApplicableRulesChanged();
@@ -321,6 +334,8 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
321334
// https://dom.spec.whatwg.org/#shadowroot-serializable
322335
const IsSerializable mIsSerializable;
323336

337+
RefPtr<nsAtom> mReferenceTarget;
338+
324339
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
325340
};
326341

dom/base/nsContentUtils.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12385,11 +12385,10 @@ int32_t nsContentUtils::CompareTreePosition(const nsINode* aNode1,
1238512385
return static_cast<int32_t>(static_cast<int64_t>(*index1) - *index2);
1238612386
}
1238712387

12388-
nsIContent* nsContentUtils::AttachDeclarativeShadowRoot(nsIContent* aHost,
12389-
ShadowRootMode aMode,
12390-
bool aIsClonable,
12391-
bool aIsSerializable,
12392-
bool aDelegatesFocus) {
12388+
nsIContent* nsContentUtils::AttachDeclarativeShadowRoot(
12389+
nsIContent* aHost, ShadowRootMode aMode, bool aIsClonable,
12390+
bool aIsSerializable, bool aDelegatesFocus,
12391+
const nsAString& aReferenceTarget) {
1239312392
RefPtr<Element> host = mozilla::dom::Element::FromNodeOrNull(aHost);
1239412393
if (!host || host->GetShadowRoot()) {
1239512394
// https://html.spec.whatwg.org/#parsing-main-inhead:shadow-host
@@ -12409,6 +12408,7 @@ nsIContent* nsContentUtils::AttachDeclarativeShadowRoot(nsIContent* aHost,
1240912408
nsGenericHTMLFormControlElement::ShadowRootDeclarative::Yes);
1241012409
// https://html.spec.whatwg.org/#parsing-main-inhead:available-to-element-internals
1241112410
shadowRoot->SetAvailableToElementInternals();
12411+
shadowRoot->SetReferenceTarget(aReferenceTarget);
1241212412
}
1241312413
return shadowRoot;
1241412414
}

dom/base/nsContentUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3562,7 +3562,7 @@ class nsContentUtils {
35623562
MOZ_CAN_RUN_SCRIPT_BOUNDARY
35633563
static nsIContent* AttachDeclarativeShadowRoot(
35643564
nsIContent* aHost, mozilla::dom::ShadowRootMode aMode, bool aIsClonable,
3565-
bool aIsSerializable, bool aDelegatesFocus);
3565+
bool aIsSerializable, bool aDelegatesFocus, const nsAString&);
35663566

35673567
static bool NavigationMustBeAReplace(nsIURI& aURI, const Document& aDocument);
35683568

dom/base/nsINode.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3960,6 +3960,8 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
39603960
return nullptr;
39613961
}
39623962
newShadowRoot->SetIsDeclarative(originalShadowRoot->IsDeclarative());
3963+
nsAtom* referenceTarget = originalShadowRoot->ReferenceTarget();
3964+
newShadowRoot->SetReferenceTarget(referenceTarget);
39633965

39643966
for (nsIContent* origChild = originalShadowRoot->GetFirstChild();
39653967
origChild; origChild = origChild->GetNextSibling()) {

dom/html/HTMLTemplateElement.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class HTMLTemplateElement final : public nsGenericHTMLElement {
7272
SetHTMLBoolAttr(nsGkAtoms::shadowrootserializable, aValue, aRv);
7373
}
7474

75+
void GetShadowRootReferenceTarget(nsAString& aResult) const {
76+
GetHTMLAttr(nsGkAtoms::shadowrootreferencetarget, aResult);
77+
}
78+
void SetShadowRootReferenceTarget(const nsAString& aValue, ErrorResult& aRv) {
79+
SetHTMLAttr(nsGkAtoms::shadowrootreferencetarget, aValue);
80+
}
81+
7582
void SetHTML(const nsAString& aInnerHTML, const SetHTMLOptions& aOptions,
7683
ErrorResult& aError) final;
7784

dom/webidl/Element.webidl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ dictionary ShadowRootInit {
279279
SlotAssignmentMode slotAssignment = "named";
280280
boolean clonable = false;
281281
boolean serializable = false;
282+
283+
// https://github.com/whatwg/dom/pull/1353
284+
[Pref="dom.shadowdom.referenceTarget.enabled"]
285+
DOMString referenceTarget;
282286
};
283287

284288
// https://dom.spec.whatwg.org/#element

dom/webidl/HTMLTemplateElement.webidl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ interface HTMLTemplateElement : HTMLElement {
2222
attribute boolean shadowRootClonable;
2323
[CEReactions, SetterThrows]
2424
attribute boolean shadowRootSerializable;
25+
[CEReactions, SetterThrows, Pref="dom.shadowdom.referenceTarget.enabled"]
26+
attribute DOMString shadowRootReferenceTarget;
2527
};

0 commit comments

Comments
 (0)