Skip to content

Commit 74bbfe4

Browse files
committed
Split getElement{,sArray}Attribute into internal/bindings versions.
Also use these methods in place of TreeScope::getElementById() for non-bindings code.
1 parent 483d3bf commit 74bbfe4

13 files changed

+70
-70
lines changed

Source/WebCore/accessibility/AXObjectCache.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -5275,10 +5275,10 @@ bool AXObjectCache::addRelation(Element& origin, const QualifiedName& attribute)
52755275
if (!m_document)
52765276
return false;
52775277
if (Element::isElementReflectionAttribute(Ref { m_document->settings() }, attribute)) {
5278-
if (auto reflectedElement = origin.getElementAttribute(attribute))
5278+
if (auto reflectedElement = origin.getElementForAttributeInternal(attribute))
52795279
return addRelation(origin, *reflectedElement, relationType);
52805280
} else if (Element::isElementsArrayReflectionAttribute(attribute)) {
5281-
if (auto reflectedElements = origin.getElementsArrayAttribute(attribute)) {
5281+
if (auto reflectedElements = origin.getElementsArrayForAttributeInternal(attribute)) {
52825282
for (auto reflectedElement : reflectedElements.value()) {
52835283
if (addRelation(origin, reflectedElement, relationType))
52845284
addedRelation = true;

Source/WebCore/accessibility/AccessibilityObject.cpp

+5-22
Original file line numberDiff line numberDiff line change
@@ -3257,11 +3257,10 @@ bool AccessibilityObject::hasDatalist() const
32573257
return false;
32583258

32593259
auto element = this->element();
3260-
if (!element)
3260+
if (!element || !is<HTMLInputElement>(element))
32613261
return false;
32623262

3263-
auto datalist = element->treeScope().getElementById(datalistId);
3264-
return is<HTMLDataListElement>(datalist);
3263+
return dynamicDowncast<HTMLInputElement>(element)->hasDataList();
32653264
}
32663265

32673266
bool AccessibilityObject::supportsSetSize() const
@@ -4048,31 +4047,15 @@ Vector<Ref<Element>> AccessibilityObject::elementsFromAttribute(const QualifiedN
40484047
if (!element)
40494048
return { };
40504049

4051-
if (Element::isElementReflectionAttribute(document()->settings(), attribute)) {
4052-
if (RefPtr reflectedElement = element->getElementAttribute(attribute)) {
4053-
Vector<Ref<Element>> elements;
4054-
elements.append(reflectedElement.releaseNonNull());
4055-
return elements;
4056-
}
4057-
} else if (Element::isElementsArrayReflectionAttribute(attribute)) {
4058-
if (auto reflectedElements = element->getElementsArrayAttribute(attribute)) {
4059-
return reflectedElements.value();
4060-
}
4050+
if (auto elementsFromAttribute = element->getElementsArrayForAttributeInternal(attribute)) {
4051+
return elementsFromAttribute.value();
40614052
}
40624053

4063-
auto& idsString = getAttribute(attribute);
4064-
if (idsString.isEmpty()) {
40654054
if (auto* defaultARIA = element->customElementDefaultARIAIfExists()) {
40664055
return defaultARIA->elementsForAttribute(*element, attribute);
40674056
}
4068-
return { };
4069-
}
40704057

4071-
auto& treeScope = element->treeScope();
4072-
SpaceSplitString ids(idsString, SpaceSplitString::ShouldFoldCase::No);
4073-
return WTF::compactMap(ids, [&](auto& id) {
4074-
return treeScope.getElementById(id);
4075-
});
4058+
return { };
40764059
}
40774060

40784061
#if PLATFORM(COCOA)

Source/WebCore/bindings/js/JSElementCustom.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static JSValue getElementsArrayAttribute(JSGlobalObject& lexicalGlobalObject, co
9999
const_cast<JSElement&>(thisObject).putDirect(vm, builtinNames(vm).cachedAttrAssociatedElementsPrivateName(), cachedObject);
100100
}
101101

102-
std::optional<Vector<Ref<Element>>> elements = thisObject.wrapped().getElementsArrayAttribute(attributeName);
102+
std::optional<Vector<Ref<Element>>> elements = thisObject.wrapped().getElementsArrayAttributeForBindings(attributeName);
103103
auto propertyName = PropertyName(Identifier::fromString(vm, attributeName.toString()));
104104
JSValue cachedValue = cachedObject->getDirect(vm, propertyName);
105105
if (!cachedValue.isEmpty()) {

Source/WebCore/bindings/js/JSElementInternalsCustom.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static JSValue getElementsArrayAttribute(JSGlobalObject& lexicalGlobalObject, co
8989
const_cast<JSElementInternals&>(thisObject).putDirect(vm, builtinNames(vm).cachedAttrAssociatedElementsPrivateName(), cachedObject);
9090
}
9191

92-
std::optional<Vector<Ref<Element>>> elements = thisObject.wrapped().getElementsArrayAttribute(attributeName);
92+
std::optional<Vector<Ref<Element>>> elements = thisObject.wrapped().getElementsArrayAttributeForBindings(attributeName);
9393
auto propertyName = PropertyName(Identifier::fromString(vm, attributeName.toString()));
9494
JSValue cachedValue = cachedObject->getDirect(vm, propertyName);
9595
if (!cachedValue.isEmpty()) {

Source/WebCore/bindings/scripts/CodeGenerator.pm

+1-3
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,7 @@ sub GetterExpression
11281128
} elsif ($attributeType->name eq "unsigned long") {
11291129
$functionName = "getUnsignedIntegralAttribute";
11301130
} elsif ($attributeType->name eq "Element") {
1131-
$functionName = "getElementAttribute";
1132-
} elsif ($attributeType->name eq "FrozenArray" && scalar @{$attributeType->subtypes} == 1 && @{$attributeType->subtypes}[0]->name eq "Element") {
1133-
$functionName = "getElementsArrayAttribute";
1131+
$functionName = "getElementAttributeForBindings";
11341132
} else {
11351133
if ($contentAttributeName eq "WebCore::HTMLNames::idAttr") {
11361134
$functionName = "getIdAttribute";

Source/WebCore/dom/Element.cpp

+43-25
Original file line numberDiff line numberDiff line change
@@ -2327,9 +2327,9 @@ ExplicitlySetAttrElementsMap* Element::explicitlySetAttrElementsMapIfExists() co
23272327
return hasRareData() ? &elementRareData()->explicitlySetAttrElementsMap() : nullptr;
23282328
}
23292329

2330-
static RefPtr<Element> getElementByIdIncludingDisconnected(const Element& startElement, const AtomString& id)
2330+
static RefPtr<Element> getElementByIdInternalIncludingDisconnected(const Element& startElement, const AtomString& id)
23312331
{
2332-
if (id.isEmpty())
2332+
if (id.isNull() || id.isEmpty())
23332333
return nullptr;
23342334

23352335
if (LIKELY(startElement.isInTreeScope()))
@@ -2349,26 +2349,34 @@ static RefPtr<Element> getElementByIdIncludingDisconnected(const Element& startE
23492349
return nullptr;
23502350
}
23512351

2352-
RefPtr<Element> Element::getElementAttribute(const QualifiedName& attributeName) const
2352+
RefPtr<Element> Element::getElementForAttributeInternal(const QualifiedName& attributeName) const
23532353
{
2354-
ASSERT(isElementReflectionAttribute(document().settings(), attributeName));
2354+
RefPtr<Element> element = nullptr;
2355+
bool hasExplicitlySetElement = false;
23552356

23562357
if (auto* map = explicitlySetAttrElementsMapIfExists()) {
23572358
auto it = map->find(attributeName);
23582359
if (it != map->end()) {
23592360
ASSERT(it->value.size() == 1);
2360-
RefPtr element = it->value[0].get();
2361-
if (element && isDescendantOrShadowDescendantOf(element->rootNode()))
2362-
return element;
2363-
return nullptr;
2361+
hasExplicitlySetElement = true;
2362+
RefPtr explicitlySetElement = it->value[0].get();
2363+
if (explicitlySetElement && isDescendantOrShadowDescendantOf(explicitlySetElement->rootNode()))
2364+
element = explicitlySetElement;
23642365
}
23652366
}
2367+
2368+
if (!hasExplicitlySetElement) {
2369+
const AtomString& id = getAttribute(attributeName);
2370+
element = getElementByIdInternalIncludingDisconnected(*this, id);
2371+
}
23662372

2367-
auto id = getAttribute(attributeName);
2368-
if (id.isNull())
2369-
return nullptr;
2373+
return element;
2374+
}
23702375

2371-
return getElementByIdIncludingDisconnected(*this, id);
2376+
RefPtr<Element> Element::getElementAttributeForBindings(const QualifiedName& attributeName) const
2377+
{
2378+
ASSERT(isElementReflectionAttribute(document().settings(), attributeName));
2379+
return getElementForAttributeInternal(attributeName);
23722380
}
23732381

23742382
void Element::setElementAttribute(const QualifiedName& attributeName, Element* element)
@@ -2390,13 +2398,16 @@ void Element::setElementAttribute(const QualifiedName& attributeName, Element* e
23902398
cache->updateRelations(*this, attributeName);
23912399
}
23922400

2393-
std::optional<Vector<Ref<Element>>> Element::getElementsArrayAttribute(const QualifiedName& attributeName) const
2401+
std::optional<Vector<Ref<Element>>> Element::getElementsArrayForAttributeInternal(const QualifiedName& attributeName) const
23942402
{
2395-
ASSERT(isElementsArrayReflectionAttribute(attributeName));
2403+
std::optional<Vector<Ref<Element>>> elements;
2404+
bool hasExplicitlySetElements = false;
23962405

23972406
if (auto* map = explicitlySetAttrElementsMapIfExists()) {
2398-
if (auto it = map->find(attributeName); it != map->end()) {
2399-
return compactMap(it->value, [&](auto& weakElement) -> std::optional<Ref<Element>> {
2407+
auto it = map->find(attributeName);
2408+
if (it != map->end()) {
2409+
hasExplicitlySetElements = true;
2410+
elements = compactMap(it->value, [&](auto& weakElement) -> std::optional<Ref<Element>> {
24002411
RefPtr element = weakElement.get();
24012412
if (element && isDescendantOrShadowDescendantOf(element->rootNode()))
24022413
return element.releaseNonNull();
@@ -2405,17 +2416,24 @@ std::optional<Vector<Ref<Element>>> Element::getElementsArrayAttribute(const Qua
24052416
}
24062417
}
24072418

2408-
auto attr = attributeName;
2409-
if (attr == HTMLNames::aria_labelledbyAttr && !hasAttribute(HTMLNames::aria_labelledbyAttr) && hasAttribute(HTMLNames::aria_labeledbyAttr))
2410-
attr = HTMLNames::aria_labeledbyAttr;
2419+
if (!hasExplicitlySetElements) {
2420+
auto attr = attributeName;
2421+
if (attr == HTMLNames::aria_labelledbyAttr && !hasAttribute(HTMLNames::aria_labelledbyAttr) && hasAttribute(HTMLNames::aria_labeledbyAttr))
2422+
attr = HTMLNames::aria_labeledbyAttr;
24112423

2412-
if (!hasAttribute(attr))
2413-
return std::nullopt;
2424+
SpaceSplitString ids(getAttribute(attr), SpaceSplitString::ShouldFoldCase::No);
2425+
elements = compactMap(ids, [&](auto& id) {
2426+
return getElementByIdInternalIncludingDisconnected(*this, id);
2427+
});
2428+
}
24142429

2415-
SpaceSplitString ids(getAttribute(attr), SpaceSplitString::ShouldFoldCase::No);
2416-
return WTF::compactMap(ids, [&](auto& id) {
2417-
return getElementByIdIncludingDisconnected(*this, id);
2418-
});
2430+
return elements;
2431+
}
2432+
2433+
std::optional<Vector<Ref<Element>>> Element::getElementsArrayAttributeForBindings(const QualifiedName& attributeName) const
2434+
{
2435+
ASSERT(isElementsArrayReflectionAttribute(attributeName));
2436+
return getElementsArrayForAttributeInternal(attributeName);
24192437
}
24202438

24212439
void Element::setElementsArrayAttribute(const QualifiedName& attributeName, std::optional<Vector<Ref<Element>>>&& elements)

Source/WebCore/dom/Element.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ class Element : public ContainerNode {
184184
WEBCORE_EXPORT void setIntegralAttribute(const QualifiedName& attributeName, int value);
185185
WEBCORE_EXPORT unsigned getUnsignedIntegralAttribute(const QualifiedName& attributeName) const;
186186
WEBCORE_EXPORT void setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value);
187-
WEBCORE_EXPORT RefPtr<Element> getElementAttribute(const QualifiedName& attributeName) const;
187+
WEBCORE_EXPORT RefPtr<Element> getElementAttributeForBindings(const QualifiedName& attributeName) const;
188188
WEBCORE_EXPORT void setElementAttribute(const QualifiedName& attributeName, Element* value);
189-
WEBCORE_EXPORT std::optional<Vector<Ref<Element>>> getElementsArrayAttribute(const QualifiedName& attributeName) const;
189+
WEBCORE_EXPORT std::optional<Vector<Ref<Element>>> getElementsArrayAttributeForBindings(const QualifiedName& attributeName) const;
190190
WEBCORE_EXPORT void setElementsArrayAttribute(const QualifiedName& attributeName, std::optional<Vector<Ref<Element>>>&& value);
191191
static bool isElementReflectionAttribute(const Settings&, const QualifiedName&);
192192
static bool isElementsArrayReflectionAttribute(const QualifiedName&);
@@ -221,6 +221,8 @@ class Element : public ContainerNode {
221221
WEBCORE_EXPORT const AtomString& getAttributeNS(const AtomString& namespaceURI, const AtomString& localName) const;
222222
AtomString getAttributeForBindings(const AtomString& qualifiedName, ResolveURLs = ResolveURLs::NoExcludingURLsForPrivacy) const;
223223
inline AtomString getAttributeNSForBindings(const AtomString& namespaceURI, const AtomString& localName, ResolveURLs = ResolveURLs::NoExcludingURLsForPrivacy) const;
224+
RefPtr<Element> getElementForAttributeInternal(const QualifiedName& attributeName) const;
225+
std::optional<Vector<Ref<Element>>> getElementsArrayForAttributeInternal(const QualifiedName& attributeName) const;
224226

225227
WEBCORE_EXPORT ExceptionOr<void> setAttribute(const AtomString& qualifiedName, const AtomString& value);
226228
ExceptionOr<void> setAttribute(const AtomString& qualifiedName, const TrustedTypeOrString& value);

Source/WebCore/dom/ElementInternals.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ const AtomString& ElementInternals::attributeWithoutSynchronization(const Qualif
154154
return defaultARIA ? defaultARIA->valueForAttribute(*element, name) : nullAtom();
155155
}
156156

157-
RefPtr<Element> ElementInternals::getElementAttribute(const QualifiedName& name) const
157+
RefPtr<Element> ElementInternals::getElementAttributeForBindings(const QualifiedName& name) const
158158
{
159159
RefPtr element = m_element.get();
160160
CheckedPtr defaultARIA = m_element->customElementDefaultARIAIfExists();
@@ -172,7 +172,7 @@ void ElementInternals::setElementAttribute(const QualifiedName& name, Element* v
172172
cache->deferAttributeChangeIfNeeded(*element, name, oldValue, computeValueForAttribute(*element, name));
173173
}
174174

175-
std::optional<Vector<Ref<Element>>> ElementInternals::getElementsArrayAttribute(const QualifiedName& name) const
175+
std::optional<Vector<Ref<Element>>> ElementInternals::getElementsArrayAttributeForBindings(const QualifiedName& name) const
176176
{
177177
RefPtr element = m_element.get();
178178
CheckedPtr defaultARIA = m_element->customElementDefaultARIAIfExists();

Source/WebCore/dom/ElementInternals.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ class ElementInternals final : public ScriptWrappable, public RefCounted<Element
6868
const AtomString& attributeWithoutSynchronization(const QualifiedName&) const;
6969
void setAttributeWithoutSynchronization(const QualifiedName&, const AtomString& value);
7070

71-
RefPtr<Element> getElementAttribute(const QualifiedName&) const;
71+
RefPtr<Element> getElementAttributeForBindings(const QualifiedName&) const;
7272
void setElementAttribute(const QualifiedName&, Element*);
73-
std::optional<Vector<Ref<Element>>> getElementsArrayAttribute(const QualifiedName&) const;
73+
std::optional<Vector<Ref<Element>>> getElementsArrayAttributeForBindings(const QualifiedName&) const;
7474
void setElementsArrayAttribute(const QualifiedName&, std::optional<Vector<Ref<Element>>>&&);
7575

7676
CustomStateSet& states();

Source/WebCore/html/FormListedElement.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static RefPtr<HTMLFormElement> findAssociatedForm(const HTMLElement& element, HT
104104
// the first element in the document to have an ID that equal to
105105
// the value of form attribute, so we put the result of
106106
// treeScope().getElementById() over the given element.
107-
RefPtr newFormCandidate = dynamicDowncast<HTMLFormElement>(element.treeScope().getElementById(formId));
107+
RefPtr newFormCandidate = dynamicDowncast<HTMLFormElement>(element.getElementForAttributeInternal(formAttr));
108108
if (!newFormCandidate)
109109
return nullptr;
110110
if (&element.traverseToRootNode() == &element.treeScope().rootNode()) {

Source/WebCore/html/HTMLFormControlElement.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ RefPtr<HTMLElement> HTMLFormControlElement::popoverTargetElement() const
371371
if (form() && isSubmitButton())
372372
return nullptr;
373373

374-
RefPtr element = dynamicDowncast<HTMLElement>(getElementAttribute(popovertargetAttr));
374+
RefPtr element = dynamicDowncast<HTMLElement>(getElementForAttributeInternal(popovertargetAttr));
375375
if (element && element->popoverState() != PopoverState::None)
376376
return element;
377377
return nullptr;
@@ -433,7 +433,7 @@ RefPtr<Element> HTMLFormControlElement::commandForElement() const
433433
if (!canInvoke(*this))
434434
return nullptr;
435435

436-
return getElementAttribute(commandforAttr);
436+
return getElementForAttributeInternal(commandforAttr);
437437
}
438438

439439
constexpr ASCIILiteral togglePopoverLiteral = "togglepopover"_s;

Source/WebCore/html/HTMLInputElement.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ RefPtr<HTMLDataListElement> HTMLInputElement::dataList() const
19001900
if (!m_hasNonEmptyList || !m_inputType->shouldRespectListAttribute())
19011901
return nullptr;
19021902

1903-
return dynamicDowncast<HTMLDataListElement>(treeScope().getElementById(attributeWithoutSynchronization(listAttr)));
1903+
return dynamicDowncast<HTMLDataListElement>(getElementForAttributeInternal(listAttr));
19041904
}
19051905

19061906
void HTMLInputElement::resetListAttributeTargetObserver()

Source/WebCore/html/HTMLLabelElement.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ WTF_MAKE_TZONE_OR_ISO_ALLOCATED_IMPL(HTMLLabelElement);
4444

4545
using namespace HTMLNames;
4646

47-
static HTMLElement* firstElementWithIdIfLabelable(TreeScope& treeScope, const AtomString& id)
47+
static HTMLElement* elementForAttributeIfLabelable(const HTMLLabelElement& context, const QualifiedName& attributeName)
4848
{
49-
if (RefPtr element = treeScope.getElementById(id)) {
49+
if (RefPtr element = context.getElementForAttributeInternal(attributeName)) {
5050
if (auto* labelableElement = dynamicDowncast<HTMLElement>(*element)) {
5151
if (labelableElement->isLabelable())
5252
return labelableElement;
@@ -73,18 +73,17 @@ Ref<HTMLLabelElement> HTMLLabelElement::create(Document& document)
7373

7474
RefPtr<HTMLElement> HTMLLabelElement::control() const
7575
{
76-
auto& controlId = attributeWithoutSynchronization(forAttr);
77-
if (controlId.isNull()) {
76+
if (!hasAttributeWithoutSynchronization(forAttr)) {
7877
// Search the children and descendants of the label element for a form element.
7978
// per http://dev.w3.org/html5/spec/Overview.html#the-label-element
8079
// the form element must be "labelable form-associated element".
81-
for (const auto& labelableElement : descendantsOfType<HTMLElement>(*this)) {
80+
for (const HTMLElement& labelableElement : descendantsOfType<HTMLElement>(*this)) {
8281
if (labelableElement.isLabelable())
8382
return const_cast<HTMLElement*>(&labelableElement);
8483
}
8584
return nullptr;
8685
}
87-
return isConnected() ? firstElementWithIdIfLabelable(treeScope(), controlId) : nullptr;
86+
return isConnected() ? elementForAttributeIfLabelable(*this, forAttr) : nullptr;
8887
}
8988

9089
RefPtr<HTMLElement> HTMLLabelElement::controlForBindings() const

0 commit comments

Comments
 (0)