Reviewed by Darin Adler.
further fixes towards REGRESSION (r57292): 1% PLT regression from visited link information leak fix
https://bugs.webkit.org/show_bug.cgi?id=38682
<rdar://problem/
7859794>
Looks like a 1-2% speedup on PLT.
- Reorder CSS properties.
- Remove short circuit tag check in matchRulesForList which costs more than it saves.
- Inline initForStyleResolve.
- Optimize applyDeclarations to avoid switch and take fewer branches in the inner loop.
- Change the way Node handles flags - replace bitfield with a uint32_t and explicit masking,
to make it cheaper to initialize the bits and give faster access.
- Added new Node flags to check for isStyledElement, isHTMLElement, isSVGElement, isComment,
and devirtualize those methods.
- Inline constructors for Node, Element, Text, CharacterData, StyledElement, etc since
they are very simple and lots of nodes get constructed.
* css/CSSPropertyNames.in: Move a few of the properties up front so we can check for them
with < instead of switch statements
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::matchRulesForList): Remove unnecessary preflight check
for tag match before checking selector. This check very rarely short circuits anything,
since most rules with a tag end up in the appropriate tag bucket. So doing the check
cost more time than the time saved.
(WebCore::CSSStyleSelector::initForStyleResolve): Inline. Create RenderStyle in a better way.
(WebCore::CSSStyleSelector::applyDeclarations): Get rid of switch statement and use <= to
check for the high priority properties. Convert to template to avoid checking "applyFirst"
each time through the loop.
(WebCore::CSSStyleSelector::styleForElement): Adjust for new applyDeclarations() signature.
(WebCore::CSSStyleSelector::keyframeStylesForAnimation): ditto
(WebCore::CSSStyleSelector::pseudoStyleForElement): ditto
* css/CSSStyleSelector.h: Adjust for new applyDeclarations() signature.
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::RenderStyle): Inline constructor.
* rendering/style/RenderStyle.h: Make constructor private so it can be inline.
* dom/Node.h:
(WebCore::): See high-level description of changes above. Redid the
way boolean flags work.
(WebCore::Node::isElementNode):
(WebCore::Node::isContainerNode):
(WebCore::Node::isTextNode):
(WebCore::Node::isHTMLElement):
(WebCore::Node::isSVGElement):
(WebCore::Node::isStyledElement):
(WebCore::Node::isCommentNode):
(WebCore::Node::hasID):
(WebCore::Node::hasClass):
(WebCore::Node::active):
(WebCore::Node::inActiveChain):
(WebCore::Node::inDetach):
(WebCore::Node::hovered):
(WebCore::Node::attached):
(WebCore::Node::setAttached):
(WebCore::Node::needsStyleRecalc):
(WebCore::Node::styleChangeType):
(WebCore::Node::childNeedsStyleRecalc):
(WebCore::Node::isLink):
(WebCore::Node::setHasID):
(WebCore::Node::setHasClass):
(WebCore::Node::setChildNeedsStyleRecalc):
(WebCore::Node::clearChildNeedsStyleRecalc):
(WebCore::Node::setInDocument):
(WebCore::Node::clearInDocument):
(WebCore::Node::setInActiveChain):
(WebCore::Node::clearInActiveChain):
(WebCore::Node::setIsLink):
(WebCore::Node::clearIsLink):
(WebCore::Node::setActive):
(WebCore::Node::setHovered):
(WebCore::Node::inDocument):
(WebCore::Node::):
(WebCore::Node::getFlag):
(WebCore::Node::setFlag):
(WebCore::Node::clearFlag):
(WebCore::Node::hasRareData):
(WebCore::Node::isParsingChildrenFinished):
(WebCore::Node::setIsParsingChildrenFinished):
(WebCore::Node::clearIsParsingChildrenFinished):
(WebCore::Node::isStyleAttributeValid):
(WebCore::Node::setIsStyleAttributeValid):
(WebCore::Node::clearIsStyleAttributeValid):
(WebCore::Node::isSynchronizingStyleAttribute):
(WebCore::Node::setIsSynchronizingStyleAttribute):
(WebCore::Node::clearIsSynchronizingStyleAttribute):
(WebCore::Node::areSVGAttributesValid):
(WebCore::Node::setAreSVGAttributesValid):
(WebCore::Node::clearAreSVGAttributesValid):
(WebCore::Node::isSynchronizingSVGAttributes):
(WebCore::Node::setIsSynchronizingSVGAttributes):
(WebCore::Node::clearIsSynchronizingSVGAttributes):
(WebCore::Node::hasRareSVGData):
(WebCore::Node::setHasRareSVGData):
(WebCore::Node::clearHasRareSVGData):
(WebCore::Node::initialRefCount):
* dom/Node.cpp:
(WebCore::Node::trackForDebugging): Adjusted for changes in
flag handling.
(WebCore::Node::ensureRareData): ditto
(WebCore::Node::setStyleChange): ditto
(WebCore::Node::setNeedsStyleRecalc): ditto
(WebCore::Node::lazyAttach): ditto
(WebCore::Node::attach): ditto
(WebCore::Node::detach): ditto
(WebCore::Node::insertedIntoDocument): ditto
(WebCore::Node::removedFromDocument): ditto
* dom/CharacterData.cpp:
* dom/CharacterData.h:
(WebCore::CharacterData::CharacterData): Inline the constructor (moved from .cpp)
* dom/Comment.cpp:
(WebCore::Comment::Comment): Tell the base class that we're a comment.
* dom/Comment.h: Remove isCommentNode override.
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::detach): Adjusted for changes in flag
handling.
(WebCore::ContainerNode::removedFromDocument): ditto
* dom/Document.cpp:
(WebCore::Document::Document): Adjusted for changes in flag handling.
(WebCore::Document::recalcStyle): ditto
(WebCore::Document::setFocusedNode): ditto
* dom/Document.h:
(WebCore::Node::Node): Inline the Node constructor - goes here
because it uses Document.
* dom/DocumentFragment.cpp: include Document.h due to above change
* dom/EditingText.cpp: ditto
* dom/EntityReference.cpp: ditto
* dom/Element.cpp:
(WebCore::Element::getAttribute): Adjusted for changes in flag
handling.
(WebCore::Element::setAttribute): ditto
(WebCore::Element::hasAttributes): ditto
(WebCore::Element::recalcStyle): ditto
(WebCore::Element::finishParsingChildren): ditto
* dom/Element.h:
(WebCore::Element::Element): Inline (moved from .cpp)
(WebCore::Element::isFinishedParsingChildren):
(WebCore::Element::beginParsingChildren):
(WebCore::Element::attributes): Adjusted for changes in flag
handling.
* dom/StyledElement.cpp:
(WebCore::StyledElement::updateStyleAttribute): Adjust for
changes to flag handling.
(WebCore::StyledElement::mapToEntry): ditto
(WebCore::StyledElement::parseMappedAttribute): ditto
(WebCore::StyledElement::copyNonAttributeProperties): ditto
* dom/StyledElement.h:
(WebCore::StyledElement::StyledElement): Inline (moved from.cpp)
(WebCore::StyledElement::invalidateStyleAttribute): Adjust for
changes in flag handling.
* dom/Text.h:
(WebCore::Text::Text): Inline (moved from .cpp)
* dom/Text.cpp:
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::HTMLAnchorElement): Adjust for changes in
flag handling.
(WebCore::HTMLAnchorElement::parseMappedAttribute): ditto
* html/HTMLElement.cpp:
(WebCore::HTMLElement::create): Tell base class we're an HTML element.
* html/HTMLElement.h: ditto above; remove isHTMLElement override.
* html/HTMLFormControlElement.h: Tell base class we're an HTML element.
* html/HTMLFrameOwnerElement.cpp:
(WebCore::HTMLFrameOwnerElement::HTMLFrameOwnerElement): ditto
* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::HTMLProgressElement): ditto
* mathml/MathMLElement.cpp:
(WebCore::MathMLElement::MathMLElement): Tell base class we're a styled
element.
* rendering/MediaControlElements.cpp:
(WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
Adjust for changes in flag handling.
(WebCore::MediaControlElement::MediaControlElement): ditto
(WebCore::MediaControlInputElement::MediaControlInputElement): ditto
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::updateFromElement): ditto
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateHoverActiveState): ditto
* rendering/RenderProgress.cpp:
(WebCore::RenderProgress::updateValuePartState): ditto
* rendering/RenderSlider.cpp:
(WebCore::RenderSlider::updateFromElement): ditto
* rendering/SVGShadowTreeElements.cpp:
(WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): ditto
* rendering/TextControlInnerElements.cpp:
(WebCore::TextControlInnerElement::attachInnerElement): ditto
* svg/SVGAnimatedProperty.h:
(WebCore::SVGAnimatedPropertyTearOff::setBaseVal): ditto
(WebCore::SVGAnimatedPropertyTearOff::setAnimVal): ditto
* svg/SVGElement.cpp:
(WebCore::SVGElement::SVGElement): Tell base class we're
an svg element.
(WebCore::SVGElement::ensureRareSVGData): Adjust for flag handling
changes.
(WebCore::SVGElement::updateAnimatedSVGAttribute): ditto
* svg/SVGElement.h:
(WebCore::SVGElement::invalidateSVGAttributes): ditto
* svg/SVGPolyElement.cpp:
(WebCore::SVGPolyElement::svgAttributeChanged): ditto
* wml/WMLAnchorElement.cpp:
(WebCore::WMLAnchorElement::WMLAnchorElement): ditto
* wml/WMLElement.cpp:
(WebCore::WMLElement::WMLElement): Tell base class we're a styled
element.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@58914
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2010-05-06 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin Adler.
+
+ further fixes towards REGRESSION (r57292): 1% PLT regression from visited link information leak fix
+ https://bugs.webkit.org/show_bug.cgi?id=38682
+ <rdar://problem/7859794>
+
+ Looks like a 1-2% speedup on PLT.
+
+ - Reorder CSS properties.
+ - Remove short circuit tag check in matchRulesForList which costs more than it saves.
+ - Inline initForStyleResolve.
+ - Optimize applyDeclarations to avoid switch and take fewer branches in the inner loop.
+
+ - Change the way Node handles flags - replace bitfield with a uint32_t and explicit masking,
+ to make it cheaper to initialize the bits and give faster access.
+ - Added new Node flags to check for isStyledElement, isHTMLElement, isSVGElement, isComment,
+ and devirtualize those methods.
+ - Inline constructors for Node, Element, Text, CharacterData, StyledElement, etc since
+ they are very simple and lots of nodes get constructed.
+
+ * css/CSSPropertyNames.in: Move a few of the properties up front so we can check for them
+ with < instead of switch statements
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::matchRulesForList): Remove unnecessary preflight check
+ for tag match before checking selector. This check very rarely short circuits anything,
+ since most rules with a tag end up in the appropriate tag bucket. So doing the check
+ cost more time than the time saved.
+ (WebCore::CSSStyleSelector::initForStyleResolve): Inline. Create RenderStyle in a better way.
+ (WebCore::CSSStyleSelector::applyDeclarations): Get rid of switch statement and use <= to
+ check for the high priority properties. Convert to template to avoid checking "applyFirst"
+ each time through the loop.
+ (WebCore::CSSStyleSelector::styleForElement): Adjust for new applyDeclarations() signature.
+ (WebCore::CSSStyleSelector::keyframeStylesForAnimation): ditto
+ (WebCore::CSSStyleSelector::pseudoStyleForElement): ditto
+ * css/CSSStyleSelector.h: Adjust for new applyDeclarations() signature.
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::RenderStyle): Inline constructor.
+ * rendering/style/RenderStyle.h: Make constructor private so it can be inline.
+ * dom/Node.h:
+ (WebCore::): See high-level description of changes above. Redid the
+ way boolean flags work.
+ (WebCore::Node::isElementNode):
+ (WebCore::Node::isContainerNode):
+ (WebCore::Node::isTextNode):
+ (WebCore::Node::isHTMLElement):
+ (WebCore::Node::isSVGElement):
+ (WebCore::Node::isStyledElement):
+ (WebCore::Node::isCommentNode):
+ (WebCore::Node::hasID):
+ (WebCore::Node::hasClass):
+ (WebCore::Node::active):
+ (WebCore::Node::inActiveChain):
+ (WebCore::Node::inDetach):
+ (WebCore::Node::hovered):
+ (WebCore::Node::attached):
+ (WebCore::Node::setAttached):
+ (WebCore::Node::needsStyleRecalc):
+ (WebCore::Node::styleChangeType):
+ (WebCore::Node::childNeedsStyleRecalc):
+ (WebCore::Node::isLink):
+ (WebCore::Node::setHasID):
+ (WebCore::Node::setHasClass):
+ (WebCore::Node::setChildNeedsStyleRecalc):
+ (WebCore::Node::clearChildNeedsStyleRecalc):
+ (WebCore::Node::setInDocument):
+ (WebCore::Node::clearInDocument):
+ (WebCore::Node::setInActiveChain):
+ (WebCore::Node::clearInActiveChain):
+ (WebCore::Node::setIsLink):
+ (WebCore::Node::clearIsLink):
+ (WebCore::Node::setActive):
+ (WebCore::Node::setHovered):
+ (WebCore::Node::inDocument):
+ (WebCore::Node::):
+ (WebCore::Node::getFlag):
+ (WebCore::Node::setFlag):
+ (WebCore::Node::clearFlag):
+ (WebCore::Node::hasRareData):
+ (WebCore::Node::isParsingChildrenFinished):
+ (WebCore::Node::setIsParsingChildrenFinished):
+ (WebCore::Node::clearIsParsingChildrenFinished):
+ (WebCore::Node::isStyleAttributeValid):
+ (WebCore::Node::setIsStyleAttributeValid):
+ (WebCore::Node::clearIsStyleAttributeValid):
+ (WebCore::Node::isSynchronizingStyleAttribute):
+ (WebCore::Node::setIsSynchronizingStyleAttribute):
+ (WebCore::Node::clearIsSynchronizingStyleAttribute):
+ (WebCore::Node::areSVGAttributesValid):
+ (WebCore::Node::setAreSVGAttributesValid):
+ (WebCore::Node::clearAreSVGAttributesValid):
+ (WebCore::Node::isSynchronizingSVGAttributes):
+ (WebCore::Node::setIsSynchronizingSVGAttributes):
+ (WebCore::Node::clearIsSynchronizingSVGAttributes):
+ (WebCore::Node::hasRareSVGData):
+ (WebCore::Node::setHasRareSVGData):
+ (WebCore::Node::clearHasRareSVGData):
+ (WebCore::Node::initialRefCount):
+ * dom/Node.cpp:
+ (WebCore::Node::trackForDebugging): Adjusted for changes in
+ flag handling.
+ (WebCore::Node::ensureRareData): ditto
+ (WebCore::Node::setStyleChange): ditto
+ (WebCore::Node::setNeedsStyleRecalc): ditto
+ (WebCore::Node::lazyAttach): ditto
+ (WebCore::Node::attach): ditto
+ (WebCore::Node::detach): ditto
+ (WebCore::Node::insertedIntoDocument): ditto
+ (WebCore::Node::removedFromDocument): ditto
+ * dom/CharacterData.cpp:
+ * dom/CharacterData.h:
+ (WebCore::CharacterData::CharacterData): Inline the constructor (moved from .cpp)
+ * dom/Comment.cpp:
+ (WebCore::Comment::Comment): Tell the base class that we're a comment.
+ * dom/Comment.h: Remove isCommentNode override.
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::detach): Adjusted for changes in flag
+ handling.
+ (WebCore::ContainerNode::removedFromDocument): ditto
+ * dom/Document.cpp:
+ (WebCore::Document::Document): Adjusted for changes in flag handling.
+ (WebCore::Document::recalcStyle): ditto
+ (WebCore::Document::setFocusedNode): ditto
+ * dom/Document.h:
+ (WebCore::Node::Node): Inline the Node constructor - goes here
+ because it uses Document.
+ * dom/DocumentFragment.cpp: include Document.h due to above change
+ * dom/EditingText.cpp: ditto
+ * dom/EntityReference.cpp: ditto
+ * dom/Element.cpp:
+ (WebCore::Element::getAttribute): Adjusted for changes in flag
+ handling.
+ (WebCore::Element::setAttribute): ditto
+ (WebCore::Element::hasAttributes): ditto
+ (WebCore::Element::recalcStyle): ditto
+ (WebCore::Element::finishParsingChildren): ditto
+ * dom/Element.h:
+ (WebCore::Element::Element): Inline (moved from .cpp)
+ (WebCore::Element::isFinishedParsingChildren):
+ (WebCore::Element::beginParsingChildren):
+ (WebCore::Element::attributes): Adjusted for changes in flag
+ handling.
+ * dom/StyledElement.cpp:
+ (WebCore::StyledElement::updateStyleAttribute): Adjust for
+ changes to flag handling.
+ (WebCore::StyledElement::mapToEntry): ditto
+ (WebCore::StyledElement::parseMappedAttribute): ditto
+ (WebCore::StyledElement::copyNonAttributeProperties): ditto
+ * dom/StyledElement.h:
+ (WebCore::StyledElement::StyledElement): Inline (moved from.cpp)
+ (WebCore::StyledElement::invalidateStyleAttribute): Adjust for
+ changes in flag handling.
+ * dom/Text.h:
+ (WebCore::Text::Text): Inline (moved from .cpp)
+ * dom/Text.cpp:
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::HTMLAnchorElement): Adjust for changes in
+ flag handling.
+ (WebCore::HTMLAnchorElement::parseMappedAttribute): ditto
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::create): Tell base class we're an HTML element.
+ * html/HTMLElement.h: ditto above; remove isHTMLElement override.
+ * html/HTMLFormControlElement.h: Tell base class we're an HTML element.
+ * html/HTMLFrameOwnerElement.cpp:
+ (WebCore::HTMLFrameOwnerElement::HTMLFrameOwnerElement): ditto
+ * html/HTMLProgressElement.cpp:
+ (WebCore::HTMLProgressElement::HTMLProgressElement): ditto
+ * mathml/MathMLElement.cpp:
+ (WebCore::MathMLElement::MathMLElement): Tell base class we're a styled
+ element.
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlShadowRootElement::MediaControlShadowRootElement):
+ Adjust for changes in flag handling.
+ (WebCore::MediaControlElement::MediaControlElement): ditto
+ (WebCore::MediaControlInputElement::MediaControlInputElement): ditto
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::RenderFileUploadControl::updateFromElement): ditto
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateHoverActiveState): ditto
+ * rendering/RenderProgress.cpp:
+ (WebCore::RenderProgress::updateValuePartState): ditto
+ * rendering/RenderSlider.cpp:
+ (WebCore::RenderSlider::updateFromElement): ditto
+ * rendering/SVGShadowTreeElements.cpp:
+ (WebCore::SVGShadowTreeRootElement::SVGShadowTreeRootElement): ditto
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerElement::attachInnerElement): ditto
+ * svg/SVGAnimatedProperty.h:
+ (WebCore::SVGAnimatedPropertyTearOff::setBaseVal): ditto
+ (WebCore::SVGAnimatedPropertyTearOff::setAnimVal): ditto
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::SVGElement): Tell base class we're
+ an svg element.
+ (WebCore::SVGElement::ensureRareSVGData): Adjust for flag handling
+ changes.
+ (WebCore::SVGElement::updateAnimatedSVGAttribute): ditto
+ * svg/SVGElement.h:
+ (WebCore::SVGElement::invalidateSVGAttributes): ditto
+ * svg/SVGPolyElement.cpp:
+ (WebCore::SVGPolyElement::svgAttributeChanged): ditto
+ * wml/WMLAnchorElement.cpp:
+ (WebCore::WMLAnchorElement::WMLAnchorElement): ditto
+ * wml/WMLElement.cpp:
+ (WebCore::WMLElement::WMLElement): Tell base class we're a styled
+ element.
+
2010-05-06 Adam Barth <abarth@webkit.org>
Unreviewed. Fix indent. Sorry, my OCD was acting up.
# http://msdn.microsoft.com/workshop/author/css/reference/attributes.asp
#
+# high-priority property names have to be listed first, to simplify the check
+# for applying them first.
+color
+direction
+display
+font
+font-family
+font-size
+font-style
+font-variant
+font-weight
+-webkit-text-size-adjust
+zoom
+
+# line height needs to be right after the above high-priority properties
+line-height
+
+# The remaining properties are listed in alphabetical order
background
background-attachment
background-clip
caption-side
clear
clip
-color
content
counter-increment
counter-reset
cursor
-direction
-display
empty-cells
float
-font
-font-family
-font-size
font-stretch
-font-style
-font-variant
-font-weight
height
left
letter-spacing
-line-height
list-style
list-style-image
list-style-position
word-spacing
word-wrap
z-index
-zoom
-webkit-animation
-webkit-animation-delay
-webkit-animation-direction
-webkit-text-decorations-in-effect
-webkit-text-fill-color
-webkit-text-security
--webkit-text-size-adjust
-webkit-text-stroke
-webkit-text-stroke-color
-webkit-text-stroke-width
if (!rules)
return;
- const AtomicString& localName = m_element->localName();
for (CSSRuleData* d = rules->first(); d; d = d->next()) {
CSSStyleRule* rule = d->rule();
- const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
- if ((localName == selectorLocalName || selectorLocalName == starAtom) && checkSelector(d->selector())) {
+ if (checkSelector(d->selector())) {
// If the rule has no properties to apply, then ignore it.
CSSMutableStyleDeclaration* decl = rule->declaration();
if (!decl || !decl->length())
m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
}
-void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
+inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
{
m_checker.m_pseudoStyle = pseudoID;
// will vanish if a style recalc happens during loading.
if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
if (!s_styleNotYetAvailable) {
- s_styleNotYetAvailable = ::new RenderStyle;
+ s_styleNotYetAvailable = RenderStyle::create().releaseRef();
s_styleNotYetAvailable->ref();
s_styleNotYetAvailable->setDisplay(NONE);
s_styleNotYetAvailable->font().update(m_fontSelector);
// The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
// and (4) normal important.
m_lineHeightValue = 0;
- applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
+ applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
if (!resolveForRootDefault) {
- applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
- applyDeclarations(true, true, firstUserRule, lastUserRule);
+ applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations<true>(true, firstUserRule, lastUserRule);
}
- applyDeclarations(true, true, firstUARule, lastUARule);
+ applyDeclarations<true>(true, firstUARule, lastUARule);
// If our font got dirtied, go ahead and update it now.
if (m_fontDirty)
applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
// Now do the normal priority UA properties.
- applyDeclarations(false, false, firstUARule, lastUARule);
+ applyDeclarations<false>(false, firstUARule, lastUARule);
// Cache our border and background so that we can examine them later.
cacheBorderAndBackground();
// Now do the author and user normal priority properties and all the !important properties.
if (!resolveForRootDefault) {
- applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
- applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
- applyDeclarations(false, true, firstUserRule, lastUserRule);
+ applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
+ applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations<false>(true, firstUserRule, lastUserRule);
}
- applyDeclarations(false, true, firstUARule, lastUARule);
+ applyDeclarations<false>(true, firstUARule, lastUARule);
// If our font got dirtied by one of the non-essential font props,
// go ahead and update it a second time.
// We don't need to bother with !important. Since there is only ever one
// decl, there's nothing to override. So just add the first properties.
- applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
+ applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
// If our font got dirtied, go ahead and update it now.
if (m_fontDirty)
applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
// Now do rest of the properties.
- applyDeclarations(false, false, 0, m_matchedDecls.size() - 1);
+ applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
// If our font got dirtied by one of the non-essential font props,
// go ahead and update it a second time.
m_checker.m_matchVisitedPseudoClass = helperCallForVisitedStyle;
// High-priority properties.
- applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
- applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
- applyDeclarations(true, true, firstUserRule, lastUserRule);
- applyDeclarations(true, true, firstUARule, lastUARule);
+ applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
+ applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations<true>(true, firstUserRule, lastUserRule);
+ applyDeclarations<true>(true, firstUARule, lastUARule);
// If our font got dirtied, go ahead and update it now.
if (m_fontDirty)
applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
// Now do the normal priority properties.
- applyDeclarations(false, false, firstUARule, lastUARule);
+ applyDeclarations<false>(false, firstUARule, lastUARule);
// Cache our border and background so that we can examine them later.
cacheBorderAndBackground();
- applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
- applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
- applyDeclarations(false, true, firstUserRule, lastUserRule);
- applyDeclarations(false, true, firstUARule, lastUARule);
+ applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
+ applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
+ applyDeclarations<false>(true, firstUserRule, lastUserRule);
+ applyDeclarations<false>(true, firstUARule, lastUARule);
// If our font got dirtied by one of the non-essential font props,
// go ahead and update it a second time.
return l;
}
-void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
- int startIndex, int endIndex)
+template <bool applyFirst>
+void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex)
{
if (startIndex == -1)
return;
CSSMutableStyleDeclaration::const_iterator end = decl->end();
for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); it != end; ++it) {
const CSSProperty& current = *it;
- // give special priority to font-xxx, color properties
if (isImportant == current.isImportant()) {
- bool first;
- switch (current.id()) {
- case CSSPropertyLineHeight:
- m_lineHeightValue = current.value();
- first = !applyFirst; // we apply line-height later
- break;
- case CSSPropertyColor:
- case CSSPropertyDirection:
- case CSSPropertyDisplay:
- case CSSPropertyFont:
- case CSSPropertyFontSize:
- case CSSPropertyFontStyle:
- case CSSPropertyFontFamily:
- case CSSPropertyFontWeight:
- case CSSPropertyWebkitTextSizeAdjust:
- case CSSPropertyFontVariant:
- case CSSPropertyZoom:
- // these have to be applied first, because other properties use the computed
- // values of these properties.
- first = true;
- break;
- default:
- first = false;
- break;
+ int property = current.id();
+
+ if (applyFirst) {
+ COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
+ COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 10, CSS_zoom_is_end_of_first_prop_range);
+ COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
+
+ // give special priority to font-xxx, color properties, etc
+ if (property <= CSSPropertyLineHeight) {
+ // we apply line-height later
+ if (property == CSSPropertyLineHeight)
+ m_lineHeightValue = current.value();
+ else
+ applyProperty(current.id(), current.value());
+ }
+ } else {
+ if (property > CSSPropertyLineHeight)
+ applyProperty(current.id(), current.value());
}
- if (first == applyFirst)
- applyProperty(current.id(), current.value());
}
}
}
void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex);
void sortMatchedRules(unsigned start, unsigned end);
- void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
+ template <bool firstPass>
+ void applyDeclarations(bool important, int startIndex, int endIndex);
CSSRuleSet* m_authorStyle;
CSSRuleSet* m_userStyle;
namespace WebCore {
-CharacterData::CharacterData(Document* document, const String& text, ConstructionType type)
- : Node(document, type)
- , m_data(text.impl() ? text.impl() : StringImpl::empty())
-{
- ASSERT(type == CreateOther || type == CreateText);
-}
-
void CharacterData::setData(const String& data, ExceptionCode&)
{
StringImpl* dataImpl = data.impl() ? data.impl() : StringImpl::empty();
StringImpl* dataImpl() { return m_data.get(); }
protected:
- CharacterData(Document*, const String&, ConstructionType);
+ CharacterData(Document* document, const String& text, ConstructionType type)
+ : Node(document, type)
+ , m_data(text.impl() ? text.impl() : StringImpl::empty())
+ {
+ ASSERT(type == CreateOther || type == CreateText);
+ }
virtual bool rendererIsNeeded(RenderStyle*);
#include "config.h"
#include "Comment.h"
+#include "Document.h"
+
namespace WebCore {
inline Comment::Comment(Document* document, const String& text)
- : CharacterData(document, text, CreateOther)
+ : CharacterData(document, text, CreateComment)
{
}
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
- virtual bool isCommentNode() const { return true; }
virtual bool childTypeAllowed(NodeType);
};
{
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->detach();
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
Node::detach();
}
Node::removedFromDocument();
if (document()->cssTarget() == this)
document()->setCSSTarget(0);
- setInDocument(false);
+ clearInDocument();
removedFromTree(false);
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->removedFromDocument();
m_textColor = Color::black;
m_listenerTypes = 0;
- m_inDocument = true;
+ setInDocument();
m_inStyleRecalc = false;
m_closeAfterStyleRecalc = false;
bail_out:
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
unscheduleStyleRecalc();
if (view())
m_focusedNode = 0;
// Remove focus from the existing focus node (if any)
- if (oldFocusedNode && !oldFocusedNode->m_inDetach) {
+ if (oldFocusedNode && !oldFocusedNode->inDetach()) {
if (oldFocusedNode->active())
oldFocusedNode->setActive(false);
return this == m_document;
}
+// here because it uses a Document method but we really want to inline it
+inline Node::Node(Document* document, ConstructionType type)
+ : TreeShared<Node>(initialRefCount(type))
+ , m_document(document)
+ , m_previous(0)
+ , m_next(0)
+ , m_renderer(0)
+ , m_nodeFlags(type)
+{
+ if (m_document)
+ m_document->selfOnlyRef();
+#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
+ trackForDebugging();
+#endif
+}
+
} // namespace WebCore
#endif // Document_h
#include "config.h"
#include "DocumentFragment.h"
+#include "Document.h"
+
namespace WebCore {
inline DocumentFragment::DocumentFragment(Document* document)
#include "config.h"
#include "EditingText.h"
+#include "Document.h"
+
// FIXME: Does this really require a class? Perhaps instead any text node
// inside an editable element could have the "always create a renderer" behavior.
using namespace HTMLNames;
using namespace XMLNames;
-Element::Element(const QualifiedName& tagName, Document* document, ConstructionType type)
- : ContainerNode(document, type)
- , m_tagName(tagName)
-{
-}
-
PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
{
return adoptRef(new Element(tagName, document, CreateElement));
const AtomicString& Element::getAttribute(const QualifiedName& name) const
{
- if (name == styleAttr && !m_isStyleAttributeValid)
+ if (name == styleAttr && !isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(name);
#endif
bool ignoreCase = shouldIgnoreAttributeCase(this);
// Update the 'style' attribute if it's invalid and being requested:
- if (!m_isStyleAttributeValid && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
+ if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid) {
+ if (!areSVGAttributesValid()) {
// We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
}
#if ENABLE(INSPECTOR)
if (Page* page = document()->page()) {
if (InspectorController* inspectorController = page->inspectorController()) {
- if (!m_synchronizingStyleAttribute)
+ if (!isSynchronizingStyleAttribute())
inspectorController->didModifyDOMAttr(this);
}
}
#if ENABLE(INSPECTOR)
if (Page* page = document()->page()) {
if (InspectorController* inspectorController = page->inspectorController()) {
- if (!m_synchronizingStyleAttribute)
+ if (!isSynchronizingStyleAttribute())
inspectorController->didModifyDOMAttr(this);
}
}
bool Element::hasAttributes() const
{
- if (!m_isStyleAttributeValid)
+ if (!isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(anyQName());
#endif
attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
// attach recalulates the style for all children. No need to do it twice.
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
return;
}
}
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
}
bool Element::childTypeAllowed(NodeType type)
void Element::finishParsingChildren()
{
ContainerNode::finishParsingChildren();
- m_parsingChildrenFinished = true;
+ setIsParsingChildrenFinished();
checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
}
#include "Document.h"
#include "HTMLNames.h"
#include "MappedAttributeEntry.h"
+#include "NamedNodeMap.h"
#include "QualifiedName.h"
#include "ScrollTypes.h"
// Use Document::registerForMediaVolumeCallbacks() to subscribe to this
virtual void mediaVolumeDidChange() { }
- bool isFinishedParsingChildren() const { return m_parsingChildrenFinished; }
+ bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
virtual void finishParsingChildren();
- virtual void beginParsingChildren() { m_parsingChildrenFinished = false; }
+ virtual void beginParsingChildren() { clearIsParsingChildrenFinished(); }
// ElementTraversal API
Element* firstElementChild() const;
virtual void dispatchFormControlChangeEvent() { }
protected:
- Element(const QualifiedName&, Document*, ConstructionType);
+ Element(const QualifiedName& tagName, Document* document, ConstructionType type)
+ : ContainerNode(document, type)
+ , m_tagName(tagName)
+ {
+ }
virtual void insertedIntoDocument();
virtual void removedFromDocument();
inline NamedNodeMap* Element::attributes(bool readonly) const
{
- if (!m_isStyleAttributeValid)
+ if (!isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(anyQName());
#endif
#include "config.h"
#include "EntityReference.h"
+#include "Document.h"
+
namespace WebCore {
inline EntityReference::EntityReference(Document* document, const String& entityName)
return ch;
}
-inline bool Node::initialRefCount(ConstructionType type)
+void Node::trackForDebugging()
{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateOther:
- case CreateText:
- return 1;
- case CreateElementZeroRefCount:
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 1;
-}
-
-inline bool Node::isContainer(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateElementZeroRefCount:
- return true;
- case CreateOther:
- case CreateText:
- return false;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-inline bool Node::isElement(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateOther:
- case CreateText:
- return false;
- case CreateElement:
- case CreateElementZeroRefCount:
- return true;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-inline bool Node::isText(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateElementZeroRefCount:
- case CreateOther:
- return false;
- case CreateText:
- return true;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-Node::Node(Document* document, ConstructionType type)
- : TreeShared<Node>(initialRefCount(type))
- , m_document(document)
- , m_previous(0)
- , m_next(0)
- , m_renderer(0)
- , m_styleChange(NoStyleChange)
- , m_hasId(false)
- , m_hasClass(false)
- , m_attached(false)
- , m_childNeedsStyleRecalc(false)
- , m_inDocument(false)
- , m_isLink(false)
- , m_active(false)
- , m_hovered(false)
- , m_inActiveChain(false)
- , m_inDetach(false)
- , m_hasRareData(false)
- , m_isElement(isElement(type))
- , m_isContainer(isContainer(type))
- , m_isText(isText(type))
- , m_parsingChildrenFinished(true)
- , m_isStyleAttributeValid(true)
- , m_synchronizingStyleAttribute(false)
-#if ENABLE(SVG)
- , m_areSVGAttributesValid(true)
- , m_synchronizingSVGAttributes(false)
- , m_hasRareSVGData(false)
-#endif
-{
- if (m_document)
- m_document->selfOnlyRef();
-
#ifndef NDEBUG
if (shouldIgnoreLeaks)
ignoreSet.add(this);
ASSERT(!NodeRareData::rareDataMap().contains(this));
NodeRareData* data = createRareData();
NodeRareData::rareDataMap().set(this, data);
- m_hasRareData = true;
+ setFlag(HasRareDataFlag);
return data;
}
return false;
}
+inline void Node::setStyleChange(StyleChangeType changeType)
+{
+ m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
+}
+
void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
if ((changeType != NoStyleChange) && !attached()) // changed compared to what?
return;
- if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == SyntheticStyleChange)))
- m_styleChange = changeType;
+ if (!(changeType == InlineStyleChange && (styleChangeType() == FullStyleChange || styleChangeType() == SyntheticStyleChange)))
+ setStyleChange(changeType);
- if (m_styleChange != NoStyleChange) {
+ if (styleChangeType() != NoStyleChange) {
for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc(true);
+ p->setChildNeedsStyleRecalc();
if (document()->childNeedsStyleRecalc())
document()->scheduleStyleRecalc();
}
}
if (n->firstChild())
- n->setChildNeedsStyleRecalc(true);
- n->m_styleChange = FullStyleChange;
- n->m_attached = true;
+ n->setChildNeedsStyleRecalc();
+ n->setStyleChange(FullStyleChange);
+ n->setAttached();
}
if (mustDoFullAttach) {
lazyAttachedAncestor->attach();
} else {
for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc(true);
+ p->setChildNeedsStyleRecalc();
if (document()->childNeedsStyleRecalc())
document()->scheduleStyleRecalc();
}
}
}
- m_attached = true;
+ setAttached();
}
void Node::willRemove()
void Node::detach()
{
- m_inDetach = true;
+ setFlag(InDetachFlag);
if (renderer())
renderer()->destroy();
setRenderer(0);
Document* doc = document();
- if (m_hovered)
+ if (hovered())
doc->hoveredNodeDetached(this);
- if (m_inActiveChain)
+ if (inActiveChain())
doc->activeChainNodeDetached(this);
- m_active = false;
- m_hovered = false;
- m_inActiveChain = false;
- m_attached = false;
- m_inDetach = false;
+ clearFlag(IsActiveFlag);
+ clearFlag(IsHoveredFlag);
+ clearFlag(InActiveChainFlag);
+ clearFlag(IsAttachedFlag);
+
+ clearFlag(InDetachFlag);
}
Node *Node::previousEditable() const
void Node::insertedIntoDocument()
{
- setInDocument(true);
+ setInDocument();
}
void Node::removedFromDocument()
{
- setInDocument(false);
+ clearInDocument();
}
void Node::willMoveToNewOwnerDocument()
typedef int ExceptionCode;
+const int nodeStyleChangeShift = 24;
+
// SyntheticStyleChange means that we need to go through the entire style change logic even though
// no style property has actually changed. It is used to restructure the tree when, for instance,
// RenderLayers are created or destroyed due to animation changes.
-enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, SyntheticStyleChange };
+enum StyleChangeType {
+ NoStyleChange = 0,
+ InlineStyleChange = 1 << nodeStyleChangeShift,
+ FullStyleChange = 2 << nodeStyleChangeShift,
+ SyntheticStyleChange = 3 << nodeStyleChangeShift
+};
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
// Other methods (not part of DOM)
- bool isElementNode() const { return m_isElement; }
- bool isContainerNode() const { return m_isContainer; }
- bool isTextNode() const { return m_isText; }
+ bool isElementNode() const { return getFlag(IsElementFlag); }
+ bool isContainerNode() const { return getFlag(IsContainerFlag); }
+ bool isTextNode() const { return getFlag(IsTextFlag); }
- virtual bool isHTMLElement() const { return false; }
+ bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
-#if ENABLE(SVG)
- virtual bool isSVGElement() const { return false; }
-#else
- static bool isSVGElement() { return false; }
-#endif
+ bool isSVGElement() const { return getFlag(IsSVGFlag); }
#if ENABLE(WML)
virtual bool isWMLElement() const { return false; }
virtual bool isMediaControlElement() const { return false; }
- virtual bool isStyledElement() const { return false; }
+ bool isStyledElement() const { return getFlag(IsStyledElementFlag); }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isAttributeNode() const { return false; }
- virtual bool isCommentNode() const { return false; }
+ bool isCommentNode() const { return getFlag(IsCommentFlag); }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
virtual bool isShadowNode() const { return false; }
// For <link> and <style> elements.
virtual bool sheetLoaded() { return true; }
- bool hasID() const { return m_hasId; }
- bool hasClass() const { return m_hasClass; }
- bool active() const { return m_active; }
- bool inActiveChain() const { return m_inActiveChain; }
- bool inDetach() const { return m_inDetach; }
- bool hovered() const { return m_hovered; }
+ bool hasID() const { return getFlag(HasIDFlag); }
+ bool hasClass() const { return getFlag(HasClassFlag); }
+ bool active() const { return getFlag(IsActiveFlag); }
+ bool inActiveChain() const { return getFlag(InActiveChainFlag); }
+ bool inDetach() const { return getFlag(InDetachFlag); }
+ bool hovered() const { return getFlag(IsHoveredFlag); }
bool focused() const { return hasRareData() ? rareDataFocused() : false; }
- bool attached() const { return m_attached; }
- void setAttached(bool b = true) { m_attached = b; }
- bool needsStyleRecalc() const { return m_styleChange != NoStyleChange; }
- StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_styleChange); }
- bool childNeedsStyleRecalc() const { return m_childNeedsStyleRecalc; }
- bool isLink() const { return m_isLink; }
- void setHasID(bool b = true) { m_hasId = b; }
- void setHasClass(bool b = true) { m_hasClass = b; }
- void setChildNeedsStyleRecalc(bool b = true) { m_childNeedsStyleRecalc = b; }
- void setInDocument(bool b = true) { m_inDocument = b; }
- void setInActiveChain(bool b = true) { m_inActiveChain = b; }
+ bool attached() const { return getFlag(IsAttachedFlag); }
+ void setAttached() { setFlag(IsAttachedFlag); }
+ bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
+ StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
+ bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
+ bool isLink() const { return getFlag(IsLinkFlag); }
+
+ void setHasID(bool f) { setFlag(f, HasIDFlag); }
+ void setHasClass(bool f) { setFlag(f, HasClassFlag); }
+ void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
+ void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
+ void setInDocument() { setFlag(InDocumentFlag); }
+ void clearInDocument() { clearFlag(InDocumentFlag); }
+
+ void setInActiveChain() { setFlag(InActiveChainFlag); }
+ void clearInActiveChain() { clearFlag(InActiveChainFlag); }
void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
- void setIsLink(bool b = true) { m_isLink = b; }
+ void setIsLink(bool f) { setFlag(f, IsLinkFlag); }
+ void setIsLink() { setFlag(IsLinkFlag); }
+ void clearIsLink() { clearFlag(IsLinkFlag); }
void lazyAttach();
virtual bool canLazyAttach();
virtual void setFocus(bool b = true);
- virtual void setActive(bool b = true, bool /*pause*/ = false) { m_active = b; }
- virtual void setHovered(bool b = true) { m_hovered = b; }
+ virtual void setActive(bool f = true, bool /*pause*/ = false) { setFlag(f, IsActiveFlag); }
+ virtual void setHovered(bool f = true) { setFlag(f, IsHoveredFlag); }
virtual short tabIndex() const;
bool inDocument() const
{
ASSERT(m_document || !m_inDocument);
- return m_inDocument;
+ return getFlag(InDocumentFlag);
}
bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
}
#endif
+private:
+ enum NodeFlags {
+ IsTextFlag = 1,
+ IsCommentFlag = 1 << 1,
+ IsContainerFlag = 1 << 2,
+ IsElementFlag = 1 << 3,
+ IsStyledElementFlag = 1 << 4,
+ IsHTMLFlag = 1 << 5,
+ IsSVGFlag = 1 << 6,
+ HasIDFlag = 1 << 7,
+ HasClassFlag = 1 << 8,
+ IsAttachedFlag = 1 << 9,
+ ChildNeedsStyleRecalcFlag = 1 << 10,
+ InDocumentFlag = 1 << 11,
+ IsLinkFlag = 1 << 12,
+ IsActiveFlag = 1 << 13,
+ IsHoveredFlag = 1 << 14,
+ InActiveChainFlag = 1 << 15,
+ InDetachFlag = 1 << 16,
+ HasRareDataFlag = 1 << 17,
+
+ // These bits are used by derived classes, pulled up here so they can
+ // be stored in the same memory word as the Node bits above.
+ IsParsingChildrenFinishedFlag = 1 << 18, // Element
+ IsStyleAttributeValidFlag = 1 << 19, // StyledElement
+ IsSynchronizingStyleAttributeFlag = 1 << 20, // StyledElement
+#if ENABLE(SVG)
+ AreSVGAttributesValidFlag = 1 << 21, // Element
+ IsSynchronizingSVGAttributesFlag = 1 << 22, // SVGElement
+ HasSVGRareDataFlag = 1 << 23, // SVGElement
+#endif
+ StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
+ CreateWithZeroRefCountFlag = 1 << 26,
+
+#if ENABLE(SVG)
+ DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag
+#else
+ DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag
+#endif
+ };
+
+ // 5 bits remaining
+
+ bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
+ void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-f & mask); }
+ void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
+ void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
+
protected:
// CreateElementZeroRefCount is deprecated and can be removed once we convert all element
// classes to start with a reference count of 1.
- enum ConstructionType { CreateContainer, CreateElement, CreateOther, CreateText, CreateElementZeroRefCount };
+ enum ConstructionType {
+ CreateOther = DefaultNodeFlags,
+ CreateText = DefaultNodeFlags | IsTextFlag,
+ CreateComment = DefaultNodeFlags | IsCommentFlag,
+ CreateContainer = DefaultNodeFlags | IsContainerFlag,
+ CreateElement = CreateContainer | IsElementFlag,
+ CreateElementZeroRefCount = IsElementFlag | CreateWithZeroRefCountFlag,
+ CreateStyledElement = CreateElement | IsStyledElementFlag,
+ CreateStyledElementZeroRefCount = CreateStyledElement | CreateWithZeroRefCountFlag,
+ CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
+ CreateHTMLElementZeroRefCount = CreateHTMLElement | CreateWithZeroRefCountFlag,
+ CreateSVGElement = CreateStyledElement | IsSVGFlag,
+ CreateSVGElementZeroRefCount = CreateSVGElement | CreateWithZeroRefCountFlag,
+ };
Node(Document*, ConstructionType);
virtual void willMoveToNewOwnerDocument();
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
void setTabIndexExplicitly(short);
- bool hasRareData() const { return m_hasRareData; }
-#if ENABLE(SVG)
- bool hasRareSVGData() const { return m_hasRareSVGData; }
-#endif
+ bool hasRareData() const { return getFlag(HasRareDataFlag); }
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
#endif
static bool initialRefCount(ConstructionType);
- static bool isContainer(ConstructionType);
- static bool isElement(ConstructionType);
- static bool isText(ConstructionType);
+ void setStyleChange(StyleChangeType);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
Element* ancestorElement() const;
void appendTextContent(bool convertBRsToNewlines, StringBuilder&) const;
+ void trackForDebugging();
Document* m_document;
Node* m_previous;
Node* m_next;
RenderObject* m_renderer;
-
- unsigned m_styleChange : 2;
- bool m_hasId : 1;
- bool m_hasClass : 1;
- bool m_attached : 1;
- bool m_childNeedsStyleRecalc : 1;
- bool m_inDocument : 1;
- bool m_isLink : 1;
- bool m_active : 1;
- bool m_hovered : 1;
- bool m_inActiveChain : 1;
- bool m_inDetach : 1;
- bool m_hasRareData : 1;
- const bool m_isElement : 1;
- const bool m_isContainer : 1;
- const bool m_isText : 1;
-
-protected:
- // These bits are used by derived classes, pulled up here so they can
- // be stored in the same memory word as the Node bits above.
-
- bool m_parsingChildrenFinished : 1; // Element
- mutable bool m_isStyleAttributeValid : 1; // StyledElement
- mutable bool m_synchronizingStyleAttribute : 1; // StyledElement
+ mutable uint32_t m_nodeFlags;
+
+ protected:
+ bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
+ void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
+ void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
+ bool isStyleAttributeValid() const { return getFlag(IsStyleAttributeValidFlag); }
+ void setIsStyleAttributeValid(bool f) { setFlag(f, IsStyleAttributeValidFlag); }
+ void setIsStyleAttributeValid() const { setFlag(IsStyleAttributeValidFlag); }
+ void clearIsStyleAttributeValid() { clearFlag(IsStyleAttributeValidFlag); }
+ bool isSynchronizingStyleAttribute() const { return getFlag(IsSynchronizingStyleAttributeFlag); }
+ void setIsSynchronizingStyleAttribute(bool f) { setFlag(f, IsSynchronizingStyleAttributeFlag); }
+ void setIsSynchronizingStyleAttribute() const { setFlag(IsSynchronizingStyleAttributeFlag); }
+ void clearIsSynchronizingStyleAttribute() const { clearFlag(IsSynchronizingStyleAttributeFlag); }
#if ENABLE(SVG)
- mutable bool m_areSVGAttributesValid : 1; // Element
- mutable bool m_synchronizingSVGAttributes : 1; // SVGElement
- bool m_hasRareSVGData : 1; // SVGElement
+ bool areSVGAttributesValid() const { return getFlag(AreSVGAttributesValidFlag); }
+ void setAreSVGAttributesValid() const { setFlag(AreSVGAttributesValidFlag); }
+ void clearAreSVGAttributesValid() { clearFlag(AreSVGAttributesValidFlag); }
+ bool isSynchronizingSVGAttributes() const { return getFlag(IsSynchronizingSVGAttributesFlag); }
+ void setIsSynchronizingSVGAttributes() const { setFlag(IsSynchronizingSVGAttributesFlag); }
+ void clearIsSynchronizingSVGAttributes() const { clearFlag(IsSynchronizingSVGAttributesFlag); }
+ bool hasRareSVGData() const { return getFlag(HasSVGRareDataFlag); }
+ void setHasRareSVGData() { setFlag(HasSVGRareDataFlag); }
+ void clearHasRareSVGData() { clearFlag(HasSVGRareDataFlag); }
#endif
-
- // 10 bits remaining
};
+inline bool Node::initialRefCount(ConstructionType type)
+{
+ return !(type & CreateWithZeroRefCountFlag);
+}
+
// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
{
void StyledElement::updateStyleAttribute() const
{
- ASSERT(!m_isStyleAttributeValid);
- m_isStyleAttributeValid = true;
- m_synchronizingStyleAttribute = true;
+ ASSERT(!isStyleAttributeValid());
+ setIsStyleAttributeValid();
+ setIsSynchronizingStyleAttribute();
if (m_inlineStyleDecl)
const_cast<StyledElement*>(this)->setAttribute(styleAttr, m_inlineStyleDecl->cssText());
- m_synchronizingStyleAttribute = false;
-}
-
-StyledElement::StyledElement(const QualifiedName& name, Document* document, ConstructionType type)
- : Element(name, document, type)
-{
+ clearIsSynchronizingStyleAttribute();
}
StyledElement::~StyledElement()
{
result = eNone;
if (attrName == styleAttr)
- return !m_synchronizingStyleAttribute;
+ return !isSynchronizingStyleAttribute();
return true;
}
destroyInlineStyleDecl();
else
getInlineStyleDecl()->parseDeclaration(attr->value());
- m_isStyleAttributeValid = true;
+ setIsStyleAttributeValid();
setNeedsStyleRecalc();
}
}
return;
*getInlineStyleDecl() = *source->m_inlineStyleDecl;
- m_isStyleAttributeValid = source->m_isStyleAttributeValid;
- m_synchronizingStyleAttribute = source->m_synchronizingStyleAttribute;
+ setIsStyleAttributeValid(source->isStyleAttributeValid());
+ setIsSynchronizingStyleAttribute(source->isSynchronizingStyleAttribute());
Element::copyNonAttributeProperties(sourceElement);
}
#ifndef StyledElement_h
#define StyledElement_h
+#include "CSSMutableStyleDeclaration.h"
#include "CSSPrimitiveValue.h"
#include "Element.h"
#include "MappedAttributeEntry.h"
namespace WebCore {
class CSSMappedAttributeDeclaration;
-class CSSMutableStyleDeclaration;
class MappedAttribute;
class StyledElement : public Element {
virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
protected:
- StyledElement(const QualifiedName&, Document*, ConstructionType);
+ StyledElement(const QualifiedName& name, Document* document, ConstructionType type)
+ : Element(name, document, type)
+ {
+ }
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
virtual void parseMappedAttribute(MappedAttribute*);
virtual void didMoveToNewOwnerDocument();
private:
- virtual bool isStyledElement() const { return true; }
-
void createMappedDecl(MappedAttribute*);
void createInlineStyleDecl();
inline void StyledElement::invalidateStyleAttribute()
{
- m_isStyleAttributeValid = false;
+ clearIsStyleAttributeValid();
}
} //namespace
namespace WebCore {
-Text::Text(Document* document, const String& data)
- : CharacterData(document, data, CreateText)
-{
-}
-
PassRefPtr<Text> Text::create(Document* document, const String& data)
{
return adoptRef(new Text(document, data));
virtual void attach();
protected:
- Text(Document*, const String&);
+ Text(Document* document, const String& data)
+ : CharacterData(document, data, CreateText)
+ {
+ }
private:
virtual String nodeName() const;
using namespace HTMLNames;
HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document)
- : HTMLElement(tagName, document, CreateElement)
+ : HTMLElement(tagName, document, CreateHTMLElement)
, m_wasShiftKeyDownOnMouseDown(false)
, m_linkRelations(0)
{
ResourceHandle::prepareForURL(document()->completeURL(parsedURL));
}
if (document()->page() && !document()->page()->javaScriptURLsAreAllowed() && protocolIsJavaScript(parsedURL)) {
- setIsLink(false);
+ clearIsLink();
attr->setValue(nullAtom);
}
}
PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new HTMLElement(tagName, document, CreateElement));
+ return adoptRef(new HTMLElement(tagName, document, CreateHTMLElement));
}
String HTMLElement::nodeName() const
static void addHTMLAlignmentToStyledElement(StyledElement*, MappedAttribute*);
protected:
- HTMLElement(const QualifiedName& tagName, Document*, ConstructionType = CreateElementZeroRefCount);
+ HTMLElement(const QualifiedName& tagName, Document*, ConstructionType = CreateHTMLElementZeroRefCount);
void addHTMLAlignment(MappedAttribute*);
HTMLFormElement* findFormAncestor() const;
private:
- virtual bool isHTMLElement() const { return true; }
-
virtual String nodeName() const;
void setContentEditable(MappedAttribute*);
class HTMLFormControlElement : public HTMLElement {
public:
- HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*, ConstructionType = CreateElementZeroRefCount);
+ HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*, ConstructionType = CreateHTMLElementZeroRefCount);
virtual ~HTMLFormControlElement();
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
namespace WebCore {
HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document* document)
- : HTMLElement(tagName, document, CreateElement)
+ : HTMLElement(tagName, document, CreateHTMLElement)
, m_contentFrame(0)
, m_sandboxFlags(SandboxNone)
{
using namespace HTMLNames;
HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
- : HTMLFormControlElement(tagName, document, form, CreateElement)
+ : HTMLFormControlElement(tagName, document, form, CreateHTMLElement)
{
ASSERT(hasTagName(progressTag));
}
using namespace MathMLNames;
MathMLElement::MathMLElement(const QualifiedName& tagName, Document* document)
- : StyledElement(tagName, document, CreateElementZeroRefCount)
+ : StyledElement(tagName, document, CreateStyledElementZeroRefCount)
{
}
renderer->setStyle(rootStyle.release());
setRenderer(renderer);
setAttached();
- setInDocument(true);
+ setInDocument();
}
void MediaControlShadowRootElement::updateStyle()
, m_mediaElement(mediaElement)
, m_pseudoStyleId(pseudo)
{
- setInDocument(true);
+ setInDocument();
switch (pseudo) {
case MEDIA_CONTROLS_CURRENT_TIME_DISPLAY:
m_displayType = MediaCurrentTimeDisplay;
, m_pseudoStyleId(pseudo)
{
setInputType(type);
- setInDocument(true);
+ setInDocument();
switch (pseudo) {
case MEDIA_CONTROLS_MUTE_BUTTON:
renderer->setStyle(buttonStyle.release());
renderer->updateFromElement();
m_button->setAttached();
- m_button->setInDocument(true);
+ m_button->setInDocument();
addChild(renderer);
}
// We are clearing the :active chain because the mouse has been released.
for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
if (curr->node() && !curr->isText())
- curr->node()->setInActiveChain(false);
+ curr->node()->clearInActiveChain();
}
doc->setActiveNode(0);
} else {
// will need to reference this chain.
for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
if (curr->node() && !curr->isText()) {
- curr->node()->setInActiveChain(true);
+ curr->node()->setInActiveChain();
}
}
doc->setActiveNode(newActiveNode);
m_valuePart->setRenderer(m_valuePart->createRenderer(renderArena(), styleForValuePart.get()));
m_valuePart->renderer()->setStyle(styleForValuePart.release());
m_valuePart->setAttached();
- m_valuePart->setInDocument(true);
+ m_valuePart->setInDocument();
addChild(m_valuePart->renderer());
} else if (style()->hasAppearance() && m_valuePart) {
m_valuePart->detach();
m_thumb->setRenderer(m_thumb->createRenderer(renderArena(), thumbStyle.get()));
m_thumb->renderer()->setStyle(thumbStyle.release());
m_thumb->setAttached();
- m_thumb->setInDocument(true);
+ m_thumb->setInDocument();
addChild(m_thumb->renderer());
}
setNeedsLayout(true);
: SVGShadowTreeContainerElement(document)
, m_shadowParent(shadowParent)
{
- setInDocument(true);
+ setInDocument();
}
SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
// Set these explicitly since this normally happens during an attach()
setAttached();
- setInDocument(true);
+ setInDocument();
// For elements without a shadow parent, add the node to the DOM normally.
if (!m_shadowParent)
return adoptRef(new RenderStyle(*other));
}
-RenderStyle::RenderStyle()
+ALWAYS_INLINE RenderStyle::RenderStyle()
: m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
setBitDefaults(); // Would it be faster to copy this from the default style?
}
-RenderStyle::RenderStyle(bool)
+ALWAYS_INLINE RenderStyle::RenderStyle(bool)
: m_affectedByAttributeSelectors(false)
, m_unique(false)
, m_affectedByEmpty(false)
#endif
}
-RenderStyle::RenderStyle(const RenderStyle& o)
+ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
: RefCounted<RenderStyle>()
, m_affectedByAttributeSelectors(false)
, m_unique(false)
noninherited_flags._isLink = false;
}
-protected:
+private:
RenderStyle();
// used to create the default style.
RenderStyle(bool);
virtual void setBaseVal(PassType type)
{
m_creator.setBaseValue(type);
- m_contextElement->setSynchronizedSVGAttributes(false);
+ m_contextElement->invalidateSVGAttributes();
}
virtual void setAnimVal(PassType type)
{
m_creator.setValue(type);
- m_contextElement->setSynchronizedSVGAttributes(false);
+ m_contextElement->invalidateSVGAttributes();
}
virtual ReturnType baseVal() const { return m_creator.baseValue(); }
{ \
m_##LowerProperty.setValue(type); \
SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
- contextElement->setSynchronizedSVGAttributes(false); \
+ contextElement->invalidateSVGAttributes(); \
} \
\
void set##UpperProperty##BaseValue(SVGAnimatedPropertyTraits<AnimatedType>::PassType type) \
{ \
m_##LowerProperty.setBaseValue(type); \
SVGElement* contextElement = GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value>::ownerElement(this); \
- contextElement->setSynchronizedSVGAttributes(false); \
+ contextElement->invalidateSVGAttributes(); \
} \
\
void synchronize##UpperProperty() \
using namespace HTMLNames;
SVGElement::SVGElement(const QualifiedName& tagName, Document* document)
- : StyledElement(tagName, document, CreateElementZeroRefCount)
+ : StyledElement(tagName, document, CreateSVGElementZeroRefCount)
{
}
ASSERT(!SVGElementRareData::rareDataMap().contains(this));
SVGElementRareData* data = new SVGElementRareData;
SVGElementRareData::rareDataMap().set(this, data);
- m_hasRareSVGData = true;
+ setHasRareSVGData();
return data;
}
void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const
{
- if (m_synchronizingSVGAttributes || m_areSVGAttributesValid)
+ if (isSynchronizingSVGAttributes() || areSVGAttributesValid())
return;
- m_synchronizingSVGAttributes = true;
+ setIsSynchronizingSVGAttributes();
const_cast<SVGElement*>(this)->synchronizeProperty(name);
if (name == anyQName())
- m_areSVGAttributesValid = true;
+ setAreSVGAttributesValid();
- m_synchronizingSVGAttributes = false;
+ clearIsSynchronizingSVGAttributes();
}
ContainerNode* SVGElement::eventParentNode()
virtual AffineTransform* supplementalTransform() { return 0; }
- void setSynchronizedSVGAttributes(bool value) { m_areSVGAttributesValid = value; }
+ void invalidateSVGAttributes() { clearAreSVGAttributesValid(); }
const HashSet<SVGElementInstance*>& instancesForElement() const;
private:
friend class SVGElementInstance;
- virtual bool isSVGElement() const { return true; }
virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
virtual ContainerNode* eventParentNode();
// The points property is not a regular SVGAnimatedProperty, still we use the same SVG<->XML DOM synchronization framework.
if (attrName == SVGNames::pointsAttr)
- setSynchronizedSVGAttributes(false);
+ invalidateSVGAttributes();
RenderPath* renderer = static_cast<RenderPath*>(this->renderer());
if (!renderer)
: WMLAElement(tagName, doc)
, m_task(0)
{
- // Calling setIsLink(true), and returning a non-null value on CSSStyleSelectors' linkAttribute
+ // Calling setIsLink(), and returning a non-null value on CSSStyleSelectors' linkAttribute
// method, makes it possible to 'appear as link' (just like <a href="..">) without the need to
// actually set the href value to an empty value in the DOM tree.
- setIsLink(true);
+ setIsLink();
}
WMLAnchorElement::~WMLAnchorElement()
using namespace WMLNames;
WMLElement::WMLElement(const QualifiedName& tagName, Document* document)
- : StyledElement(tagName, document, CreateElementZeroRefCount)
+ : StyledElement(tagName, document, CreateStyledElementZeroRefCount)
{
}