#include "config.h"
#include "core/css/resolver/SharedStyleFinder.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/StyleResolverStats.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/FullscreenElementStack.h"
#include "core/dom/Node.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/QualifiedName.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLOptGroupElement.h"
+#include "core/html/HTMLOptionElement.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/svg/SVGElement.h"
#include "wtf/HashSet.h"
#include "wtf/text/AtomicString.h"
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
bool SharedStyleFinder::canShareStyleWithControl(Element& candidate) const
{
- if (!candidate.hasTagName(inputTag) || !element().hasTagName(inputTag))
+ if (!isHTMLInputElement(candidate) || !isHTMLInputElement(element()))
return false;
HTMLInputElement& candidateInput = toHTMLInputElement(candidate);
bool SharedStyleFinder::sharingCandidateHasIdenticalStyleAffectingAttributes(Element& candidate) const
{
- if (element().elementData() == candidate.elementData())
+ if (element().sharesSameElementData(candidate))
return true;
if (element().fastGetAttribute(XMLNames::langAttr) != candidate.fastGetAttribute(XMLNames::langAttr))
return false;
if (element().fastGetAttribute(langAttr) != candidate.fastGetAttribute(langAttr))
return false;
- // These two checks must be here since RuleSet has a specail case to allow style sharing between elements
+ // These two checks must be here since RuleSet has a special case to allow style sharing between elements
// with type and readonly attributes whereas other attribute selectors prevent sharing.
if (typeAttributeValue(element()) != typeAttributeValue(candidate))
return false;
// FIXME: Consider removing this, it's unlikely we'll have so many progress elements
// that sharing the style makes sense. Instead we should just not support style sharing
// for them.
- if (element().hasTagName(progressTag)) {
+ if (isHTMLProgressElement(element())) {
if (element().shouldAppearIndeterminate() != candidate.shouldAppearIndeterminate())
return false;
}
+ if (isHTMLOptGroupElement(element()) || isHTMLOptionElement(element())) {
+ if (element().isDisabledFormControl() != candidate.isDisabledFormControl())
+ return false;
+ if (isHTMLOptionElement(element()) && toHTMLOptionElement(element()).selected() != toHTMLOptionElement(candidate).selected())
+ return false;
+ }
+
return true;
}
-bool SharedStyleFinder::sharingCandidateShadowHasSharedStyleSheetContents(Element& candidate) const
+bool SharedStyleFinder::sharingCandidateCanShareHostStyles(Element& candidate) const
{
- if (!element().shadow() || !element().shadow()->containsActiveStyles())
+ const ElementShadow* elementShadow = element().shadow();
+ const ElementShadow* candidateShadow = candidate.shadow();
+
+ if (!elementShadow && !candidateShadow)
+ return true;
+
+ if (static_cast<bool>(elementShadow) != static_cast<bool>(candidateShadow))
return false;
- return element().shadow()->hasSameStyles(candidate.shadow());
+ return elementShadow->hasSameStyles(candidateShadow);
}
bool SharedStyleFinder::sharingCandidateDistributedToSameInsertionPoint(Element& candidate) const
{
- Vector<InsertionPoint*, 8> insertionPoints, candidateInsertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints, candidateInsertionPoints;
collectDestinationInsertionPoints(element(), insertionPoints);
collectDestinationInsertionPoints(candidate, candidateInsertionPoints);
if (insertionPoints.size() != candidateInsertionPoints.size())
return false;
if (candidate.isLink() != element().isLink())
return false;
- if (candidate.hovered() != element().hovered())
- return false;
- if (candidate.active() != element().active())
- return false;
- if (candidate.focused() != element().focused())
- return false;
if (candidate.shadowPseudoId() != element().shadowPseudoId())
return false;
- if (candidate == document().cssTarget())
- return false;
if (!sharingCandidateHasIdenticalStyleAffectingAttributes(candidate))
return false;
if (candidate.additionalPresentationAttributeStyle() != element().additionalPresentationAttributeStyle())
return false;
if (candidate.hasID() && m_features.hasSelectorForId(candidate.idForStyleResolution()))
return false;
- if (candidate.hasScopedHTMLStyleChild())
- return false;
- if (candidate.shadow() && candidate.shadow()->containsActiveStyles() && !sharingCandidateShadowHasSharedStyleSheetContents(candidate))
+ if (!sharingCandidateCanShareHostStyles(candidate))
return false;
if (!sharingCandidateDistributedToSameInsertionPoint(candidate))
return false;
return false;
bool isControl = candidate.isFormControlElement();
-
- if (isControl != element().isFormControlElement())
+ ASSERT(isControl == element().isFormControlElement());
+ if (isControl && !canShareStyleWithControl(candidate))
return false;
- if (isControl && !canShareStyleWithControl(candidate))
+ if (isHTMLOptionElement(candidate) && isHTMLOptionElement(element())
+ && (toHTMLOptionElement(candidate).selected() != toHTMLOptionElement(element()).selected()
+ || toHTMLOptionElement(candidate).spatialNavigationFocused() != toHTMLOptionElement(element()).spatialNavigationFocused()))
return false;
// FIXME: This line is surprisingly hot, we may wish to inline hasDirectionAuto into StyleResolver.
if (element().parentOrShadowHostElement() != parent) {
if (!parent->isStyledElement())
return false;
- if (parent->hasScopedHTMLStyleChild())
- return false;
if (parent->inlineStyle())
return false;
if (parent->isSVGElement() && toSVGElement(parent)->animatedSMILStyleProperties())
}
// Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
- if (!element().parentOrShadowHostElement()->childrenSupportStyleSharing()) {
+ if (!element().parentElementOrShadowRoot()->childrenSupportStyleSharing()) {
INCREMENT_STYLE_STATS_COUNTER(m_styleResolver, sharedStyleRejectedByParent);
return 0;
}