Optimize hasTagName when called on an HTMLElement
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Mar 2014 16:38:58 +0000 (16:38 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 16 Mar 2014 16:38:58 +0000 (16:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=130090

Reviewed by Antti Koivisto.

Source/WebCore:

Added new hasTagName functions that have the efficiency of hasLocalName.
but are safe.

Now we can always use hasTagName, and we'll get a compile time error if
we try to use an SVG tag name with an HTML element. All call sites that
use the more specific tag name types are more efficient, and call sites
that have a specific pointer type will get even more efficient checking
that is exactly what we used to get by calling hasLocalName.

* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::hasTagName): Cast explicitly to Element
since Node::hasTagName no longer works on a general QualifiedName.
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::isDescendantOfElementType): Use
more specific type, RenderElement, so we can call hasTagName on Element
instead of Node; eliminates an unnecessary branch.

* accessibility/AccessibilityTableColumn.cpp: Added now-needed include.
* accessibility/atk/AccessibilityObjectAtk.cpp: Ditto.

* dom/DocumentStyleSheetCollection.cpp:
(WebCore::DocumentStyleSheetCollection::collectActiveStyleSheets): Use
new for loop and full words for variable names. Also use nullptr instead
of 0. Call toHTMLElement and toSVGElement in code that checks hasTagName
since it's already checking isHTMLElement and isSVGElement.

* dom/Element.cpp:
(WebCore::attrNodeListMap): Use NeverDestroyed and put the vectors into
the map rather than putting pointers to a vector into the map.
(WebCore::attrNodeListForElement): Take a reference rather than a pointer,
and update for the change above.
(WebCore::ensureAttrNodeListForElement): Ditto.
(WebCore::removeAttrNodeListForElement): Ditto.
(WebCore::findAttrNodeInList): Ditto.
(WebCore::Element::isFocusable): Use lineageOfType<HTMLCanvasElement>
to fine the canvas rather than a hand-written loop.
(WebCore::Element::attrNodeList): Update for above changes.
(WebCore::Element::setAttributeNode): Ditto.
(WebCore::Element::attrIfExists): Ditto.
(WebCore::Element::ensureAttr): Ditto.
(WebCore::Element::detachAttrNodeFromElementWithValue): Ditto.
(WebCore::Element::detachAllAttrNodesFromElement): Ditto.

* dom/Element.h: Removed the overload of hasLocalName that takes a
QualifiedName and ignores the non-local-name parts of it. Callers should
use hasTagName instead, now that it's optimized appropriately. Added
overloads of hasTagName for all the specific qualified name types. It's
more efficient to use the Node versions of these functions rather than
using QualifiedName::matches to do the check. Removed the hasTagName and
hasLocalName functions from the Node class; the only convenience functions
needed in Node are the specific checks for tags from HTML, MathML, and SVG,
not the general purpose ones.

* dom/Node.h: Removed hasLocalName and replaced the single hasTagName
that takes a QualifiedName with three faster ones that take HTML, MathML,
and SVG qualified names instead. Also updated to use nullptr instead of 0.

* dom/PositionIterator.cpp: Added now-needed include.
* dom/Text.cpp: Ditto.

* dom/make_names.pl:
(printHeaderHead): Renamed an argument for clarity and added a definitions
argument, which is where we insert the classes derived from QualifiedName.
(printCppHead): Renamed an argument for clarity.
(printTypeHelpers): Use hasTagName rather than hasLocalName, since the
former is now optimized to be the same as what the latter was.
(printNamesHeaderFile): Define a class derived from QualifiedName that can
be used at compile time to avoid having to check the namespace.
(printNamesCppFile): Use the new more-specific type as needed.

* editing/ApplyStyleCommand.cpp:
(WebCore::isLegacyAppleStyleSpan): Use hasTagName instead of hasLocalName,
and references instead of pointers.
(WebCore::ApplyStyleCommand::ApplyStyleCommand): Removed uneeded explicit
construction of a smart pointer.
(WebCore::ApplyStyleCommand::shouldApplyInlineStyleToRun): Updated to use
the enclosingElementWithTag function by its new name.

* editing/Editor.cpp:
(WebCore::Editor::selectionUnorderedListState): Updated to use the
enclosingElementWithTag function by its new name.
(WebCore::Editor::selectionOrderedListState): Ditto.

* editing/InsertListCommand.cpp:
(WebCore::InsertListCommand::doApply): Use a more-specific type for the list tag.
(WebCore::InsertListCommand::doApplyForSingleParagraph): Ditto.
* editing/InsertListCommand.h: Ditto.

* editing/MarkupAccumulator.cpp:
(WebCore::MarkupAccumulator::serializeNodesWithNamespaces): Added an explicit
cast to Element in the loop that is already guarded by an isElementNode check.
Also use a modern C++ for loop.

* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder):
Updated to use the enclosingElementWithTag function by its new name.
(WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds): Ditto.
(WebCore::ReplaceSelectionCommand::positionAtEndOfInsertedContent): Ditto.

* editing/TypingCommand.cpp: Added now-needed includes.
* editing/VisibleUnits.cpp: Ditto.

* editing/htmlediting.cpp:
(WebCore::enclosingElementWithTag): Changed to return an Element instead of a Node,
since nodes other than elements do not have tags.
* editing/htmlediting.h: Ditto.

* editing/mac/EditorMac.mm:
(WebCore::Editor::adjustedSelectionRange): Updated to use the enclosingElementWithTag
function by its new name.
* editing/markup.cpp:
(WebCore::StyledMarkupAccumulator::appendText): Ditto.
(WebCore::StyledMarkupAccumulator::traverseNodesForSerialization): Ditto.
(WebCore::highestAncestorToWrapMarkup): Ditto.
(WebCore::createMarkupInternal): Ditto.
(WebCore::createContextualFragment): Ditto. Use hasTagName instead of hasLocalName,
since the former is now optimized to be the same as the latter was before.

* html/HTMLCollection.cpp:
(WebCore::isMatchingElement): Use hasTagName instead of hasLocalName,
since the former is now optimized to be the same as the latter was before.
(WebCore::nameShouldBeVisibleInDocumentAll): Ditto.
* html/HTMLElement.cpp:
(WebCore::HTMLElement::ieForbidsInsertHTML): Ditto.
(WebCore::unicodeBidiAttributeForDirAuto): Ditto.
(WebCore::HTMLElement::parseBorderWidthAttribute): Ditto.
(WebCore::HTMLElement::setInnerHTML): Ditto.
(WebCore::shouldProhibitSetInnerOuterText): Ditto. Added this to share code between
setInnerText and setOuterText.
(WebCore::HTMLElement::setInnerText): Ditto.
(WebCore::HTMLElement::setOuterText): Ditto.
(WebCore::HTMLElement::rendererIsNeeded): Ditto.
(WebCore::HTMLElement::createElementRenderer): Ditto.

* html/HTMLElement.h: Added hasTagName, which hides the one inherited from Element
and takes the more-specific HTMLQualifiedName type. This means we don't need to check
the namespace at runtime because it's known at compile time. Also put the
implementation of Node::hasTagName for HTMLQualifiedName into this header.

* html/HTMLObjectElement.cpp:
(WebCore::isRecognizedTagName): Updated for change in return type of
HTMLNames::getHTMLTags.

* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::add): Use hasTagName inastead of hasLocalName.
(WebCore::HTMLSelectElement::value): Use isHTMLOptionElement instead of hasTagName.
Also use a new style for loop and emptyString() instead of "".
(WebCore::HTMLSelectElement::setValue): Ditto.
(WebCore::HTMLSelectElement::setLength): Ditto.
(WebCore::HTMLSelectElement::searchOptionsForValue): Ditto.
(WebCore::HTMLSelectElement::restoreFormControlState): Ditto.

* html/HTMLTableColElement.cpp:
(WebCore::HTMLTableColElement::additionalPresentationAttributeStyle): Use hasTagName
instead of hasLocalName.

* html/HTMLTableRowsCollection.cpp:
(WebCore::isInSection): Updated to use hasTagName and take a reference.
(WebCore::HTMLTableRowsCollection::rowAfter): Pass a reference.

* html/parser/HTMLConstructionSite.cpp: Added now-needed include.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::createCaseMap): Updated to return a map rather than filling one in, and to
be flxible about the type of the table being used.
(WebCore::adjustSVGTagNameCase): Updated to use NeverDestroyed.
(WebCore::adjustAttributes): Added new helper so we can share more code. Updated
template argument names for clarity.
(WebCore::adjustSVGAttributes): Marked this inline, since it just turns around and
calls a single non-inline function.
(WebCore::adjustMathMLAttributes): Ditto.
(WebCore::addNamesWithPrefix): Changed to take argument by reference instead of pointer.
(WebCore::createForeignAttributesMap): Added. Factors out the map creation from the
function below.
(WebCore::adjustForeignAttributes): Updated for above changes.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Updated to pass reference.
(WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.

* inspector/InspectorStyleSheet.cpp: Added now-needed include.

* mathml/MathMLElement.h: Added hasTagName, which hides the one inherited from Element
and takes the more-specific MathMLQualifiedName type. This means we don't need to check
the namespace at runtime because it's known at compile time. Also put the
implementation of Node::hasTagName for MathMLQualifiedName into this header.

* mathml/MathMLInlineContainerElement.cpp:
(WebCore::MathMLInlineContainerElement::createElementRenderer): Use hasTagName.

* mathml/MathMLSelectElement.cpp:
(WebCore::MathMLSelectElement::attributeChanged): Use hasTagName.
(WebCore::MathMLSelectElement::getSelectedActionChildAndIndex): Ditto.
(WebCore::MathMLSelectElement::getSelectedActionChild): Ditto.
(WebCore::MathMLSelectElement::getSelectedSemanticsChild): Ditto.
(WebCore::MathMLSelectElement::updateSelectedChild): Ditto.
* mathml/MathMLTextElement.cpp:
(WebCore::MathMLTextElement::createElementRenderer): Ditto.
(WebCore::MathMLTextElement::childShouldCreateRenderer): Ditto.

* platform/gtk/PasteboardGtk.cpp: Added now-needed include.
* platform/mac/HTMLConverter.mm: Ditto.
* rendering/RenderBlockFlow.cpp: Ditto.

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended): Use hasTagName.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::rendererForRootBackground): Ditto.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): Ditto.

* rendering/RenderReplaced.cpp: Added now-needed include.

* rendering/mathml/RenderMathMLScripts.cpp:
(WebCore::RenderMathMLScripts::RenderMathMLScripts): Use hasTagName.
* rendering/mathml/RenderMathMLUnderOver.cpp:
(WebCore::RenderMathMLUnderOver::RenderMathMLUnderOver): Ditto.

* svg/SVGElement.h: Added hasTagName, which hides the one inherited from Element
and takes the more-specific SVGQualifiedName type. This means we don't need to check
the namespace at runtime because it's known at compile time. Also put the
implementation of Node::hasTagName for SVGQualifiedName into this header.

* svg/SVGFontFaceSrcElement.cpp:
(WebCore::SVGFontFaceSrcElement::childrenChanged): Use isSVGFontFaceElement instead
of calling hasTagName.

* svg/SVGUseElement.cpp:
(WebCore::isDirectReference): Changed to take a reference and a more specific type.
(WebCore::SVGUseElement::toClipPath): Added a type cast.
(WebCore::SVGUseElement::rendererClipChild): Use more specific types so we don't
need a type cast.

* xml/parser/XMLDocumentParser.cpp:
(WebCore::XMLDocumentParser::parseDocumentFragment): Added explicit calls to this
unusual call site that has a good reason to use hasLocalName instead of hasTagName.

Source/WebKit:

* WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
Updated exports for QualifiedName -> HTMLQualifiedName change.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@165699 268f45cc-cd09-0410-ab3c-d52691b4dbfc

57 files changed:
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityList.cpp
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityTableCell.cpp
Source/WebCore/accessibility/AccessibilityTableColumn.cpp
Source/WebCore/accessibility/atk/AccessibilityObjectAtk.cpp
Source/WebCore/dom/DocumentStyleSheetCollection.cpp
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.h
Source/WebCore/dom/PositionIterator.cpp
Source/WebCore/dom/StyledElement.cpp
Source/WebCore/dom/Text.cpp
Source/WebCore/dom/make_names.pl
Source/WebCore/editing/ApplyStyleCommand.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/InsertListCommand.cpp
Source/WebCore/editing/InsertListCommand.h
Source/WebCore/editing/MarkupAccumulator.cpp
Source/WebCore/editing/ReplaceSelectionCommand.cpp
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/editing/TypingCommand.cpp
Source/WebCore/editing/VisibleUnits.cpp
Source/WebCore/editing/htmlediting.cpp
Source/WebCore/editing/htmlediting.h
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/editing/markup.cpp
Source/WebCore/html/HTMLCollection.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLObjectElement.cpp
Source/WebCore/html/HTMLSelectElement.cpp
Source/WebCore/html/HTMLTableColElement.cpp
Source/WebCore/html/HTMLTableRowsCollection.cpp
Source/WebCore/html/parser/HTMLConstructionSite.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/inspector/InspectorStyleSheet.cpp
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/mathml/MathMLInlineContainerElement.cpp
Source/WebCore/mathml/MathMLSelectElement.cpp
Source/WebCore/mathml/MathMLTextElement.cpp
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/platform/mac/HTMLConverter.mm
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/mathml/RenderMathMLScripts.cpp
Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGFontFaceSrcElement.cpp
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/xml/parser/XMLDocumentParser.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in

index a1711d5..fa52ac0 100644 (file)
@@ -1,3 +1,245 @@
+2014-03-16  Darin Adler  <darin@apple.com>
+
+        Optimize hasTagName when called on an HTMLElement
+        https://bugs.webkit.org/show_bug.cgi?id=130090
+
+        Reviewed by Antti Koivisto.
+
+        Added new hasTagName functions that have the efficiency of hasLocalName.
+        but are safe.
+
+        Now we can always use hasTagName, and we'll get a compile time error if
+        we try to use an SVG tag name with an HTML element. All call sites that
+        use the more specific tag name types are more efficient, and call sites
+        that have a specific pointer type will get even more efficient checking
+        that is exactly what we used to get by calling hasLocalName.
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::hasTagName): Cast explicitly to Element
+        since Node::hasTagName no longer works on a general QualifiedName.
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::isDescendantOfElementType): Use
+        more specific type, RenderElement, so we can call hasTagName on Element
+        instead of Node; eliminates an unnecessary branch.
+
+        * accessibility/AccessibilityTableColumn.cpp: Added now-needed include.
+        * accessibility/atk/AccessibilityObjectAtk.cpp: Ditto.
+
+        * dom/DocumentStyleSheetCollection.cpp:
+        (WebCore::DocumentStyleSheetCollection::collectActiveStyleSheets): Use
+        new for loop and full words for variable names. Also use nullptr instead
+        of 0. Call toHTMLElement and toSVGElement in code that checks hasTagName
+        since it's already checking isHTMLElement and isSVGElement.
+
+        * dom/Element.cpp:
+        (WebCore::attrNodeListMap): Use NeverDestroyed and put the vectors into
+        the map rather than putting pointers to a vector into the map.
+        (WebCore::attrNodeListForElement): Take a reference rather than a pointer,
+        and update for the change above.
+        (WebCore::ensureAttrNodeListForElement): Ditto.
+        (WebCore::removeAttrNodeListForElement): Ditto.
+        (WebCore::findAttrNodeInList): Ditto.
+        (WebCore::Element::isFocusable): Use lineageOfType<HTMLCanvasElement>
+        to fine the canvas rather than a hand-written loop.
+        (WebCore::Element::attrNodeList): Update for above changes.
+        (WebCore::Element::setAttributeNode): Ditto.
+        (WebCore::Element::attrIfExists): Ditto.
+        (WebCore::Element::ensureAttr): Ditto.
+        (WebCore::Element::detachAttrNodeFromElementWithValue): Ditto.
+        (WebCore::Element::detachAllAttrNodesFromElement): Ditto.
+
+        * dom/Element.h: Removed the overload of hasLocalName that takes a
+        QualifiedName and ignores the non-local-name parts of it. Callers should
+        use hasTagName instead, now that it's optimized appropriately. Added
+        overloads of hasTagName for all the specific qualified name types. It's
+        more efficient to use the Node versions of these functions rather than
+        using QualifiedName::matches to do the check. Removed the hasTagName and
+        hasLocalName functions from the Node class; the only convenience functions
+        needed in Node are the specific checks for tags from HTML, MathML, and SVG,
+        not the general purpose ones.
+
+        * dom/Node.h: Removed hasLocalName and replaced the single hasTagName
+        that takes a QualifiedName with three faster ones that take HTML, MathML,
+        and SVG qualified names instead. Also updated to use nullptr instead of 0.
+
+        * dom/PositionIterator.cpp: Added now-needed include.
+        * dom/Text.cpp: Ditto.
+
+        * dom/make_names.pl:
+        (printHeaderHead): Renamed an argument for clarity and added a definitions
+        argument, which is where we insert the classes derived from QualifiedName.
+        (printCppHead): Renamed an argument for clarity.
+        (printTypeHelpers): Use hasTagName rather than hasLocalName, since the
+        former is now optimized to be the same as what the latter was.
+        (printNamesHeaderFile): Define a class derived from QualifiedName that can
+        be used at compile time to avoid having to check the namespace.
+        (printNamesCppFile): Use the new more-specific type as needed.
+
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::isLegacyAppleStyleSpan): Use hasTagName instead of hasLocalName,
+        and references instead of pointers.
+        (WebCore::ApplyStyleCommand::ApplyStyleCommand): Removed uneeded explicit
+        construction of a smart pointer.
+        (WebCore::ApplyStyleCommand::shouldApplyInlineStyleToRun): Updated to use
+        the enclosingElementWithTag function by its new name.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::selectionUnorderedListState): Updated to use the
+        enclosingElementWithTag function by its new name.
+        (WebCore::Editor::selectionOrderedListState): Ditto.
+
+        * editing/InsertListCommand.cpp:
+        (WebCore::InsertListCommand::doApply): Use a more-specific type for the list tag.
+        (WebCore::InsertListCommand::doApplyForSingleParagraph): Ditto.
+        * editing/InsertListCommand.h: Ditto.
+
+        * editing/MarkupAccumulator.cpp:
+        (WebCore::MarkupAccumulator::serializeNodesWithNamespaces): Added an explicit
+        cast to Element in the loop that is already guarded by an isElementNode check.
+        Also use a modern C++ for loop.
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder):
+        Updated to use the enclosingElementWithTag function by its new name.
+        (WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds): Ditto.
+        (WebCore::ReplaceSelectionCommand::positionAtEndOfInsertedContent): Ditto.
+
+        * editing/TypingCommand.cpp: Added now-needed includes.
+        * editing/VisibleUnits.cpp: Ditto.
+
+        * editing/htmlediting.cpp:
+        (WebCore::enclosingElementWithTag): Changed to return an Element instead of a Node,
+        since nodes other than elements do not have tags.
+        * editing/htmlediting.h: Ditto.
+
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::adjustedSelectionRange): Updated to use the enclosingElementWithTag
+        function by its new name.
+        * editing/markup.cpp:
+        (WebCore::StyledMarkupAccumulator::appendText): Ditto.
+        (WebCore::StyledMarkupAccumulator::traverseNodesForSerialization): Ditto.
+        (WebCore::highestAncestorToWrapMarkup): Ditto.
+        (WebCore::createMarkupInternal): Ditto.
+        (WebCore::createContextualFragment): Ditto. Use hasTagName instead of hasLocalName,
+        since the former is now optimized to be the same as the latter was before.
+
+        * html/HTMLCollection.cpp:
+        (WebCore::isMatchingElement): Use hasTagName instead of hasLocalName,
+        since the former is now optimized to be the same as the latter was before.
+        (WebCore::nameShouldBeVisibleInDocumentAll): Ditto.
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::ieForbidsInsertHTML): Ditto.
+        (WebCore::unicodeBidiAttributeForDirAuto): Ditto.
+        (WebCore::HTMLElement::parseBorderWidthAttribute): Ditto.
+        (WebCore::HTMLElement::setInnerHTML): Ditto.
+        (WebCore::shouldProhibitSetInnerOuterText): Ditto. Added this to share code between
+        setInnerText and setOuterText.
+        (WebCore::HTMLElement::setInnerText): Ditto.
+        (WebCore::HTMLElement::setOuterText): Ditto.
+        (WebCore::HTMLElement::rendererIsNeeded): Ditto.
+        (WebCore::HTMLElement::createElementRenderer): Ditto.
+
+        * html/HTMLElement.h: Added hasTagName, which hides the one inherited from Element
+        and takes the more-specific HTMLQualifiedName type. This means we don't need to check
+        the namespace at runtime because it's known at compile time. Also put the
+        implementation of Node::hasTagName for HTMLQualifiedName into this header.
+
+        * html/HTMLObjectElement.cpp:
+        (WebCore::isRecognizedTagName): Updated for change in return type of
+        HTMLNames::getHTMLTags.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::add): Use hasTagName inastead of hasLocalName.
+        (WebCore::HTMLSelectElement::value): Use isHTMLOptionElement instead of hasTagName.
+        Also use a new style for loop and emptyString() instead of "".
+        (WebCore::HTMLSelectElement::setValue): Ditto.
+        (WebCore::HTMLSelectElement::setLength): Ditto.
+        (WebCore::HTMLSelectElement::searchOptionsForValue): Ditto.
+        (WebCore::HTMLSelectElement::restoreFormControlState): Ditto.
+
+        * html/HTMLTableColElement.cpp:
+        (WebCore::HTMLTableColElement::additionalPresentationAttributeStyle): Use hasTagName
+        instead of hasLocalName.
+
+        * html/HTMLTableRowsCollection.cpp:
+        (WebCore::isInSection): Updated to use hasTagName and take a reference.
+        (WebCore::HTMLTableRowsCollection::rowAfter): Pass a reference.
+
+        * html/parser/HTMLConstructionSite.cpp: Added now-needed include.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::createCaseMap): Updated to return a map rather than filling one in, and to
+        be flxible about the type of the table being used.
+        (WebCore::adjustSVGTagNameCase): Updated to use NeverDestroyed.
+        (WebCore::adjustAttributes): Added new helper so we can share more code. Updated
+        template argument names for clarity.
+        (WebCore::adjustSVGAttributes): Marked this inline, since it just turns around and
+        calls a single non-inline function.
+        (WebCore::adjustMathMLAttributes): Ditto.
+        (WebCore::addNamesWithPrefix): Changed to take argument by reference instead of pointer.
+        (WebCore::createForeignAttributesMap): Added. Factors out the map creation from the
+        function below.
+        (WebCore::adjustForeignAttributes): Updated for above changes.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Updated to pass reference.
+        (WebCore::HTMLTreeBuilder::processTokenInForeignContent): Ditto.
+
+        * inspector/InspectorStyleSheet.cpp: Added now-needed include.
+
+        * mathml/MathMLElement.h: Added hasTagName, which hides the one inherited from Element
+        and takes the more-specific MathMLQualifiedName type. This means we don't need to check
+        the namespace at runtime because it's known at compile time. Also put the
+        implementation of Node::hasTagName for MathMLQualifiedName into this header.
+
+        * mathml/MathMLInlineContainerElement.cpp:
+        (WebCore::MathMLInlineContainerElement::createElementRenderer): Use hasTagName.
+
+        * mathml/MathMLSelectElement.cpp:
+        (WebCore::MathMLSelectElement::attributeChanged): Use hasTagName.
+        (WebCore::MathMLSelectElement::getSelectedActionChildAndIndex): Ditto.
+        (WebCore::MathMLSelectElement::getSelectedActionChild): Ditto.
+        (WebCore::MathMLSelectElement::getSelectedSemanticsChild): Ditto.
+        (WebCore::MathMLSelectElement::updateSelectedChild): Ditto.
+        * mathml/MathMLTextElement.cpp:
+        (WebCore::MathMLTextElement::createElementRenderer): Ditto.
+        (WebCore::MathMLTextElement::childShouldCreateRenderer): Ditto.
+
+        * platform/gtk/PasteboardGtk.cpp: Added now-needed include.
+        * platform/mac/HTMLConverter.mm: Ditto.
+        * rendering/RenderBlockFlow.cpp: Ditto.
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended): Use hasTagName.
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::rendererForRootBackground): Ditto.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): Ditto.
+
+        * rendering/RenderReplaced.cpp: Added now-needed include.
+
+        * rendering/mathml/RenderMathMLScripts.cpp:
+        (WebCore::RenderMathMLScripts::RenderMathMLScripts): Use hasTagName.
+        * rendering/mathml/RenderMathMLUnderOver.cpp:
+        (WebCore::RenderMathMLUnderOver::RenderMathMLUnderOver): Ditto.
+
+        * svg/SVGElement.h: Added hasTagName, which hides the one inherited from Element
+        and takes the more-specific SVGQualifiedName type. This means we don't need to check
+        the namespace at runtime because it's known at compile time. Also put the
+        implementation of Node::hasTagName for SVGQualifiedName into this header.
+
+        * svg/SVGFontFaceSrcElement.cpp:
+        (WebCore::SVGFontFaceSrcElement::childrenChanged): Use isSVGFontFaceElement instead
+        of calling hasTagName.
+
+        * svg/SVGUseElement.cpp:
+        (WebCore::isDirectReference): Changed to take a reference and a more specific type.
+        (WebCore::SVGUseElement::toClipPath): Added a type cast.
+        (WebCore::SVGUseElement::rendererClipChild): Use more specific types so we don't
+        need a type cast.
+
+        * xml/parser/XMLDocumentParser.cpp:
+        (WebCore::XMLDocumentParser::parseDocumentFragment): Added explicit calls to this
+        unusual call site that has a good reason to use hasLocalName instead of hasTagName.
+
 2014-03-16  Andreas Kling  <akling@apple.com>
 
         Stop pulling in JSDOMBinding.h via JSEventListener.h
index 925a970..327d2a1 100644 (file)
@@ -30,6 +30,7 @@
 #include "AccessibilityList.h"
 
 #include "AXObjectCache.h"
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "RenderListItem.h"
 #include "RenderObject.h"
index 2a99938..b48019e 100644 (file)
@@ -1555,9 +1555,8 @@ String AccessibilityObject::invalidStatus() const
  
 bool AccessibilityObject::hasTagName(const QualifiedName& tagName) const
 {
-    if (Node* node = this->node())
-        return node->hasTagName(tagName);
-    return false;
+    Node* node = this->node();
+    return node && node->isElementNode() && toElement(*node).hasTagName(tagName);
 }
     
 bool AccessibilityObject::hasAttribute(const QualifiedName& attribute) const
index a80ac84..ec78e1b 100644 (file)
@@ -2415,8 +2415,8 @@ AccessibilityObject* AccessibilityRenderObject::observableObject() const
 
 bool AccessibilityRenderObject::isDescendantOfElementType(const QualifiedName& tagName) const
 {
-    for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) {
-        if (parent->node() && parent->node()->hasTagName(tagName))
+    for (auto& ancestor : ancestorsOfType<RenderElement>(*m_renderer)) {
+        if (ancestor.element() && ancestor.element()->hasTagName(tagName))
             return true;
     }
     return false;
index a2f6855..6daa7e5 100644 (file)
@@ -32,6 +32,7 @@
 #include "AXObjectCache.h"
 #include "AccessibilityTable.h"
 #include "AccessibilityTableRow.h"
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "RenderObject.h"
 #include "RenderTableCell.h"
index f34b635..7cee3da 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "AXObjectCache.h"
 #include "AccessibilityTableCell.h"
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "RenderTable.h"
 #include "RenderTableCell.h"
index 51e1b78..56f84dc 100644 (file)
@@ -21,8 +21,8 @@
 #include "config.h"
 #include "AccessibilityObject.h"
 
+#include "HTMLElement.h"
 #include "HTMLNames.h"
-#include "RenderObject.h"
 #include "RenderText.h"
 #include <glib-object.h>
 
index 7199c01..a949c1f 100644 (file)
@@ -262,15 +262,12 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
     if (m_document.settings() && !m_document.settings()->authorAndUserStylesEnabled())
         return;
 
-    StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
-    StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
-    for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) {
-        Node* n = *it;
-        StyleSheet* sheet = 0;
-        if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
+    for (auto& node : m_styleSheetCandidateNodes) {
+        StyleSheet* sheet = nullptr;
+        if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
             // Processing instruction (XML documents only).
             // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
-            ProcessingInstruction* pi = toProcessingInstruction(n);
+            ProcessingInstruction* pi = toProcessingInstruction(node);
             sheet = pi->sheet();
 #if ENABLE(XSLT)
             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
@@ -281,47 +278,41 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
                 return;
             }
 #endif
-        } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
-            || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
-            Element* e = toElement(n);
-            AtomicString title = e->getAttribute(titleAttr);
+        } else if ((node->isHTMLElement() && (toHTMLElement(*node).hasTagName(linkTag) || toHTMLElement(*node).hasTagName(styleTag))) || (node->isSVGElement() && toSVGElement(*node).hasTagName(SVGNames::styleTag))) {
+            Element& element = toElement(*node);
+            AtomicString title = element.getAttribute(titleAttr);
             bool enabledViaScript = false;
-            if (e->hasTagName(linkTag)) {
+            if (isHTMLLinkElement(element)) {
                 // <LINK> element
-                HTMLLinkElement* linkElement = toHTMLLinkElement(n);
-                if (linkElement->isDisabled())
+                HTMLLinkElement& linkElement = toHTMLLinkElement(element);
+                if (linkElement.isDisabled())
                     continue;
-                enabledViaScript = linkElement->isEnabledViaScript();
-                if (linkElement->styleSheetIsLoading()) {
+                enabledViaScript = linkElement.isEnabledViaScript();
+                if (linkElement.styleSheetIsLoading()) {
                     // it is loading but we should still decide which style sheet set to use
                     if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSetName.isEmpty()) {
-                        const AtomicString& rel = e->getAttribute(relAttr);
-                        if (!rel.contains("alternate")) {
+                        if (!linkElement.fastGetAttribute(relAttr).contains("alternate")) {
                             m_preferredStylesheetSetName = title;
                             m_selectedStylesheetSetName = title;
                         }
                     }
                     continue;
                 }
-                if (!linkElement->sheet())
+                if (!linkElement.sheet())
                     title = nullAtom;
             }
             // Get the current preferred styleset. This is the
             // set of sheets that will be enabled.
-            if (isSVGStyleElement(e))
-                sheet = toSVGStyleElement(e)->sheet();
-            else {
-                if (isHTMLLinkElement(e))
-                    sheet = toHTMLLinkElement(n)->sheet();
-                else {
-                    // <STYLE> element
-                    sheet = toHTMLStyleElement(e)->sheet();
-                }
-            }
+            if (isSVGStyleElement(element))
+                sheet = toSVGStyleElement(element).sheet();
+            else if (isHTMLLinkElement(element))
+                sheet = toHTMLLinkElement(element).sheet();
+            else
+                sheet = toHTMLStyleElement(element).sheet();
             // Check to see if this sheet belongs to a styleset
             // (thus making it PREFERRED or ALTERNATE rather than
             // PERSISTENT).
-            AtomicString rel = e->getAttribute(relAttr);
+            auto& rel = element.fastGetAttribute(relAttr);
             if (!enabledViaScript && !title.isEmpty()) {
                 // Yes, we have a title.
                 if (m_preferredStylesheetSetName.isEmpty()) {
@@ -329,15 +320,15 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
                     // we are NOT an alternate sheet, then establish
                     // us as the preferred set. Otherwise, just ignore
                     // this sheet.
-                    if (e->hasTagName(styleTag) || !rel.contains("alternate"))
+                    if (isHTMLStyleElement(element) || !rel.contains("alternate"))
                         m_preferredStylesheetSetName = m_selectedStylesheetSetName = title;
                 }
                 if (title != m_preferredStylesheetSetName)
-                    sheet = 0;
+                    sheet = nullptr;
             }
 
             if (rel.contains("alternate") && title.isEmpty())
-                sheet = 0;
+                sheet = nullptr;
         }
         if (sheet)
             sheets.append(sheet);
index 9a76bc9..3507461 100644 (file)
@@ -44,9 +44,9 @@
 #include "FocusEvent.h"
 #include "FrameSelection.h"
 #include "FrameView.h"
+#include "HTMLCanvasElement.h"
 #include "HTMLCollection.h"
 #include "HTMLDocument.h"
-#include "HTMLElement.h"
 #include "HTMLFormControlsCollection.h"
 #include "HTMLLabelElement.h"
 #include "HTMLNameCollection.h"
@@ -93,50 +93,46 @@ static inline bool shouldIgnoreAttributeCase(const Element& element)
     return element.isHTMLElement() && element.document().isHTMLDocument();
 }
 
-typedef Vector<RefPtr<Attr>> AttrNodeList;
-typedef HashMap<Element*, OwnPtr<AttrNodeList>> AttrNodeListMap;
-
-static AttrNodeListMap& attrNodeListMap()
+static HashMap<Element*, Vector<RefPtr<Attr>>>& attrNodeListMap()
 {
-    DEPRECATED_DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
+    static NeverDestroyed<HashMap<Element*, Vector<RefPtr<Attr>>>> map;
     return map;
 }
 
-static AttrNodeList* attrNodeListForElement(Element* element)
+static Vector<RefPtr<Attr>>* attrNodeListForElement(Element& element)
 {
-    if (!element->hasSyntheticAttrChildNodes())
-        return 0;
-    ASSERT(attrNodeListMap().contains(element));
-    return attrNodeListMap().get(element);
+    if (!element.hasSyntheticAttrChildNodes())
+        return nullptr;
+    ASSERT(attrNodeListMap().contains(&element));
+    return &attrNodeListMap().find(&element)->value;
 }
 
-static AttrNodeList& ensureAttrNodeListForElement(Element* element)
+static Vector<RefPtr<Attr>>& ensureAttrNodeListForElement(Element& element)
 {
-    if (element->hasSyntheticAttrChildNodes()) {
-        ASSERT(attrNodeListMap().contains(element));
-        return *attrNodeListMap().get(element);
+    if (element.hasSyntheticAttrChildNodes()) {
+        ASSERT(attrNodeListMap().contains(&element));
+        return attrNodeListMap().find(&element)->value;
     }
-    ASSERT(!attrNodeListMap().contains(element));
-    element->setHasSyntheticAttrChildNodes(true);
-    AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
-    return *result.iterator->value;
+    ASSERT(!attrNodeListMap().contains(&element));
+    element.setHasSyntheticAttrChildNodes(true);
+    return attrNodeListMap().add(&element, Vector<RefPtr<Attr>>()).iterator->value;
 }
 
-static void removeAttrNodeListForElement(Element* element)
+static void removeAttrNodeListForElement(Element& element)
 {
-    ASSERT(element->hasSyntheticAttrChildNodes());
-    ASSERT(attrNodeListMap().contains(element));
-    attrNodeListMap().remove(element);
-    element->setHasSyntheticAttrChildNodes(false);
+    ASSERT(element.hasSyntheticAttrChildNodes());
+    ASSERT(attrNodeListMap().contains(&element));
+    attrNodeListMap().remove(&element);
+    element.setHasSyntheticAttrChildNodes(false);
 }
 
-static Attr* findAttrNodeInList(AttrNodeList& attrNodeList, const QualifiedName& name)
+static Attr* findAttrNodeInList(Vector<RefPtr<Attr>>& attrNodeList, const QualifiedName& name)
 {
-    for (unsigned i = 0; i < attrNodeList.size(); ++i) {
-        if (attrNodeList.at(i)->qualifiedName() == name)
-            return attrNodeList.at(i).get();
+    for (auto& node : attrNodeList) {
+        if (node->qualifiedName() == name)
+            return node.get();
     }
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document& document)
@@ -434,11 +430,9 @@ bool Element::isFocusable() const
     // Elements in canvas fallback content are not rendered, but they are allowed to be
     // focusable as long as their canvas is displayed and visible.
     if (isInCanvasSubtree()) {
-        const Element* e = this;
-        while (e && !e->hasLocalName(canvasTag))
-            e = e->parentElement();
-        ASSERT(e);
-        return e->renderer() && e->renderer()->style().visibility() == VISIBLE;
+        ASSERT(lineageOfType<HTMLCanvasElement>(*this).first());
+        auto& canvas = *lineageOfType<HTMLCanvasElement>(*this).first();
+        return canvas.renderer() && canvas.renderer()->style().visibility() == VISIBLE;
     }
 
     if (!renderer()) {
@@ -1638,7 +1632,7 @@ void Element::formatForDebugger(char* buffer, unsigned length) const
 const Vector<RefPtr<Attr>>& Element::attrNodeList()
 {
     ASSERT(hasSyntheticAttrChildNodes());
-    return *attrNodeListForElement(this);
+    return *attrNodeListForElement(*this);
 }
 
 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
@@ -1674,7 +1668,7 @@ PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
 
     attrNode->attachToElement(this);
     treeScope().adoptIfNeeded(attrNode);
-    ensureAttrNodeListForElement(this).append(attrNode);
+    ensureAttrNodeListForElement(*this).append(attrNode);
 
     return oldAttrNode.release();
 }
@@ -2769,14 +2763,14 @@ void Element::setSavedLayerScrollOffset(const IntSize& size)
 
 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
 {
-    if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
+    if (auto* attrNodeList = attrNodeListForElement(*this))
         return findAttrNodeInList(*attrNodeList, name);
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
 {
-    AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
+    auto& attrNodeList = ensureAttrNodeListForElement(*this);
     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
     if (!attrNode) {
         attrNode = Attr::create(this, name);
@@ -2791,12 +2785,12 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
     ASSERT(hasSyntheticAttrChildNodes());
     attrNode->detachFromElementWithValue(value);
 
-    AttrNodeList* attrNodeList = attrNodeListForElement(this);
+    auto* attrNodeList = attrNodeListForElement(*this);
     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
             attrNodeList->remove(i);
             if (attrNodeList->isEmpty())
-                removeAttrNodeListForElement(this);
+                removeAttrNodeListForElement(*this);
             return;
         }
     }
@@ -2805,7 +2799,7 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
 
 void Element::detachAllAttrNodesFromElement()
 {
-    AttrNodeList* attrNodeList = attrNodeListForElement(this);
+    auto* attrNodeList = attrNodeListForElement(*this);
     ASSERT(attrNodeList);
 
     for (const Attribute& attribute : attributesIterator()) {
@@ -2813,7 +2807,7 @@ void Element::detachAllAttrNodesFromElement()
             attrNode->detachFromElementWithValue(attribute.value());
     }
 
-    removeAttrNodeListForElement(this);
+    removeAttrNodeListForElement(*this);
 }
 
 void Element::resetComputedStyle()
index 98b37db..158bba2 100644 (file)
@@ -260,10 +260,12 @@ public:
 #endif // ENABLE(CSS_SELECTOR_JIT)
     String tagName() const { return nodeName(); }
     bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
-    
+    bool hasTagName(const HTMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
+    bool hasTagName(const MathMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
+    bool hasTagName(const SVGQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
+
     // A fast function for checking the local name against another atomic string.
     bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
-    bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
 
     virtual const AtomicString& localName() const override final { return m_tagName.localName(); }
     virtual const AtomicString& prefix() const override final { return m_tagName.prefix(); }
@@ -686,16 +688,6 @@ template <typename Type> bool isElementOfType(const Element&);
 template <typename Type> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const Type>(toElement(node)); }
 template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
 
-inline bool Node::hasTagName(const QualifiedName& name) const
-{
-    return isElementNode() && toElement(this)->hasTagName(name);
-}
-    
-inline bool Node::hasLocalName(const AtomicString& name) const
-{
-    return isElementNode() && toElement(this)->hasLocalName(name);
-}
-
 inline bool Node::hasAttributes() const
 {
     return isElementNode() && toElement(this)->hasAttributes();
index 6ba9926..e4ebdd2 100644 (file)
@@ -60,8 +60,10 @@ class EventListener;
 class FloatPoint;
 class Frame;
 class HTMLInputElement;
+class HTMLQualifiedName;
 class IntRect;
 class KeyboardEvent;
+class MathMLQualifiedName;
 class NSResolver;
 class NamedNodeMap;
 class NameNodeList;
@@ -75,6 +77,7 @@ class RenderBox;
 class RenderBoxModelObject;
 class RenderObject;
 class RenderStyle;
+class SVGQualifiedName;
 class ShadowRoot;
 class TagNodeList;
 
@@ -157,8 +160,9 @@ public:
 
     // DOM methods & attributes for Node
 
-    bool hasTagName(const QualifiedName&) const;
-    bool hasLocalName(const AtomicString&) const;
+    bool hasTagName(const HTMLQualifiedName&) const;
+    bool hasTagName(const MathMLQualifiedName&) const;
+    bool hasTagName(const SVGQualifiedName&) const;
     virtual String nodeName() const = 0;
     virtual String nodeValue() const;
     virtual void setNodeValue(const String&, ExceptionCode&);
@@ -259,7 +263,7 @@ public:
     bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
     void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
 
-    // If this node is in a shadow tree, returns its shadow host. Otherwise, returns 0.
+    // If this node is in a shadow tree, returns its shadow host. Otherwise, returns null.
     Element* shadowHost() const;
     // If this node is in a shadow tree, returns its shadow host. Otherwise, returns this.
     // Deprecated. Should use shadowHost() and check the return value.
@@ -267,7 +271,7 @@ public:
     ShadowRoot* containingShadowRoot() const;
     ShadowRoot* shadowRoot() const;
 
-    // Returns 0, a child of ShadowRoot, or a legacy shadow root.
+    // Returns null, a child of ShadowRoot, or a legacy shadow root.
     Node* nonBoundaryShadowTreeRootNode();
 
     // Node's parent or shadow tree host.
@@ -276,9 +280,9 @@ public:
     void setParentNode(ContainerNode*);
     Node* highestAncestor() const;
 
-    // Use when it's guaranteed to that shadowHost is 0.
+    // Use when it's guaranteed to that shadowHost is null.
     ContainerNode* parentNodeGuaranteedHostFree() const;
-    // Returns the parent node, but 0 if the parent node is a ShadowRoot.
+    // Returns the parent node, but null if the parent node is a ShadowRoot.
     ContainerNode* nonShadowBoundaryParentNode() const;
 
     bool selfOrAncestorHasDirAutoAttribute() const { return getFlag(SelfOrAncestorHasDirAutoFlag); }
@@ -377,11 +381,11 @@ public:
 
     unsigned nodeIndex() const;
 
-    // Returns the DOM ownerDocument attribute. This method never returns 0, except in the case
+    // Returns the DOM ownerDocument attribute. This method never returns null, except in the case
     // of a Document node.
     Document* ownerDocument() const;
 
-    // Returns the document associated with this node. This method never returns 0.
+    // Returns the document associated with this node.
     // A Document node returns itself.
     Document& document() const
     {
@@ -491,11 +495,11 @@ public:
     void showNode(const char* prefix = "") const;
     void showTreeForThis() const;
     void showNodePathForThis() const;
-    void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
+    void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = nullptr, const char* markedLabel2 = nullptr) const;
     void showTreeForThisAcrossFrame() const;
 #endif
 
-    void invalidateNodeListAndCollectionCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0);
+    void invalidateNodeListAndCollectionCachesInAncestors(const QualifiedName* attrName = nullptr, Element* attributeOwnerElement = nullptr);
     NodeListsNodeData* nodeLists();
     void clearNodeLists();
 
@@ -670,7 +674,7 @@ private:
     virtual void refEventTarget() override;
     virtual void derefEventTarget() override;
 
-    virtual RenderStyle* nonRendererStyle() const { return 0; }
+    virtual RenderStyle* nonRendererStyle() const { return nullptr; }
 
     Element* ancestorElement() const;
 
index 97812dd..b31a1b8 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "PositionIterator.h"
 
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "RenderBlock.h"
 #include "RenderText.h"
index a1f06fb..e357a53 100644 (file)
@@ -30,6 +30,7 @@
 #include "CSSValuePool.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMTokenList.h"
+#include "HTMLElement.h"
 #include "HTMLParserIdioms.h"
 #include "InspectorInstrumentation.h"
 #include "PropertySetCSSStyleDeclaration.h"
index 50d1315..40533c3 100644 (file)
 #include "RenderCombineText.h"
 #include "RenderSVGInlineText.h"
 #include "RenderText.h"
+#include "SVGElement.h"
+#include "SVGNames.h"
 #include "ScopedEventQueue.h"
 #include "ShadowRoot.h"
-#include "SVGNames.h"
-#include "TextNodeTraversal.h"
-
 #include "StyleInheritedData.h"
 #include "StyleResolver.h"
+#include "TextNodeTraversal.h"
 #include <wtf/CheckedArithmetic.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
index 4bfe144..29637f2 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 
-# Copyright (C) 2005, 2006, 2007, 2009, 2013 Apple Inc. All rights reserved.
+# Copyright (C) 2005-2007, 2009, 2013-2014 Apple Inc. All rights reserved.
 # Copyright (C) 2009, Julien Chaffraix <jchaffraix@webkit.org>
 # Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 # Copyright (C) 2011 Ericsson AB. All rights reserved.
@@ -103,7 +103,7 @@ if (length($fontNamesIn)) {
     open F, ">$header" or die "Unable to open $header for writing.";
 
     printLicenseHeader($F);
-    printHeaderHead($F, "CSS", $familyNamesFileBase, "#include <wtf/text/AtomicString.h>");
+    printHeaderHead($F, "CSS", $familyNamesFileBase, "#include <wtf/text/AtomicString.h>", "");
 
     printMacros($F, "extern const WTF::AtomicString", "", \%parameters);
     print F "#endif\n\n";
@@ -525,34 +525,41 @@ sub upperCaseName
 
 sub printHeaderHead
 {
-    my ($F, $prefix, $nsName, $includes) = @_;
+    my ($F, $prefix, $namespace, $includes, $definitions) = @_;
 
-    print F "#ifndef ${prefix}_${nsName}Names_h\n";
-    print F "#define ${prefix}_${nsName}Names_h\n\n";
-    print F "$includes\n\n";
+    print F<<END
+#ifndef ${prefix}_${namespace}Names_h
 
-    print F "namespace WebCore {\n\n";
-    print F "namespace ${nsName}Names {\n\n";
+#define ${prefix}_${namespace}Names_h
+
+$includes
+
+namespace WebCore {
 
-    print F "#ifndef ${prefix}_${nsName}NAMES_HIDE_GLOBALS\n";
+${definitions}namespace ${namespace}Names {
+
+#ifndef ${prefix}_${namespace}_NAMES_HIDE_GLOBALS
+
+END
+    ;
 }
 
 sub printCppHead
 {
-    my ($F, $prefix, $nsName, $usedNamespace) = @_;
+    my ($F, $prefix, $namespace, $usedNamespace) = @_;
 
     print F "#include \"config.h\"\n\n";
     print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";
-    print F "#define ${prefix}_${nsName}NAMES_HIDE_GLOBALS 1\n";
+    print F "#define ${prefix}_${namespace}_NAMES_HIDE_GLOBALS 1\n";
     print F "#else\n";
     print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";
     print F "#endif\n\n";
 
-    print F "#include \"${nsName}Names.h\"\n\n";
+    print F "#include \"${namespace}Names.h\"\n\n";
     print F "#include <wtf/StaticConstructors.h>\n";
 
     print F "namespace WebCore {\n\n";
-    print F "namespace ${nsName}Names {\n\n";
+    print F "namespace ${namespace}Names {\n\n";
     print F "using namespace $usedNamespace;\n\n";
 }
 
@@ -639,13 +646,13 @@ END
             if ($parsedTags{$name}{wrapperOnlyIfMediaIsAvailable}) {
                 # We need to check for HTMLUnknownElement if it might have been created by the factory.
                 print F <<END
-inline bool $checkHelper(const HTMLElement& element) { return !element.isHTMLUnknownElement() && element.hasLocalName($parameters{namespace}Names::${name}Tag); }
+inline bool $checkHelper(const HTMLElement& element) { return !element.isHTMLUnknownElement() && element.hasTagName($parameters{namespace}Names::${name}Tag); }
 inline bool $checkHelper(const HTMLElement* element) { ASSERT(element); return $checkHelper(*element); }
 END
                 ;
             } else {
                 print F <<END
-inline bool $checkHelper(const HTMLElement& element) { return element.hasLocalName(HTMLNames::${name}Tag); }
+inline bool $checkHelper(const HTMLElement& element) { return element.hasTagName(HTMLNames::${name}Tag); }
 inline bool $checkHelper(const HTMLElement* element) { ASSERT(element); return $checkHelper(*element); }
 END
                 ;
@@ -701,15 +708,16 @@ sub printNamesHeaderFile
     open F, ">$headerPath";
 
     printLicenseHeader($F);
-    printHeaderHead($F, "DOM", $parameters{namespace}, "#include \"QualifiedName.h\"");
+    printHeaderHead($F, "DOM", $parameters{namespace}, '#include "QualifiedName.h"', "class $parameters{namespace}QualifiedName : public QualifiedName { };\n\n");
+
+    my $lowercaseNamespacePrefix = lc($parameters{namespacePrefix});
 
-    my $lowerNamespace = lc($parameters{namespacePrefix});
     print F "// Namespace\n";
-    print F "extern const WTF::AtomicString ${lowerNamespace}NamespaceURI;\n\n";
+    print F "extern const WTF::AtomicString ${lowercaseNamespacePrefix}NamespaceURI;\n\n";
 
     if (keys %allTags) {
         print F "// Tags\n";
-        printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%allTags);
+        printMacros($F, "extern const WebCore::$parameters{namespace}QualifiedName", "Tag", \%allTags);
     }
 
     if (keys %allAttrs) {
@@ -720,12 +728,12 @@ sub printNamesHeaderFile
 
     if (keys %allTags) {
         print F "const unsigned $parameters{namespace}TagsCount = ", scalar(keys %allTags), ";\n";
-        print F "const WebCore::QualifiedName* const * get$parameters{namespace}Tags();\n";
+        print F "const WebCore::$parameters{namespace}QualifiedName* const* get$parameters{namespace}Tags();\n";
     }
 
     if (keys %allAttrs) {
         print F "const unsigned $parameters{namespace}AttrsCount = ", scalar(keys %allAttrs), ";\n";
-        print F "const WebCore::QualifiedName* const * get$parameters{namespace}Attrs();\n";
+        print F "const WebCore::QualifiedName* const* get$parameters{namespace}Attrs();\n";
     }
 
     printInit($F, 1);
@@ -741,22 +749,22 @@ sub printNamesCppFile
     printLicenseHeader($F);
     printCppHead($F, "DOM", $parameters{namespace}, "WebCore");
     
-    my $lowerNamespace = lc($parameters{namespacePrefix});
+    my $lowercaseNamespacePrefix = lc($parameters{namespacePrefix});
 
-    print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI)\n\n";
+    print F "DEFINE_GLOBAL(AtomicString, ${lowercaseNamespacePrefix}NamespaceURI)\n\n";
 
     print F StaticString::GenerateStrings(\%allStrings);
 
     if (keys %allTags) {
         print F "// Tags\n";
         for my $name (sort keys %allTags) {
-            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag)\n";
+            print F "DEFINE_GLOBAL($parameters{namespace}QualifiedName, ", $name, "Tag)\n";
         }
         
-        print F "\n\nconst WebCore::QualifiedName* const * get$parameters{namespace}Tags()\n";
-        print F "{\n    static const WebCore::QualifiedName* const $parameters{namespace}Tags[] = {\n";
+        print F "\n\nconst WebCore::$parameters{namespace}QualifiedName* const* get$parameters{namespace}Tags()\n";
+        print F "{\n    static const WebCore::$parameters{namespace}QualifiedName* const $parameters{namespace}Tags[] = {\n";
         for my $name (sort keys %allTags) {
-            print F "        reinterpret_cast<const WebCore::QualifiedName*>(&${name}Tag),\n";
+            print F "        reinterpret_cast<const WebCore::$parameters{namespace}QualifiedName*>(&${name}Tag),\n";
         }
         print F "    };\n";
         print F "    return $parameters{namespace}Tags;\n";
@@ -768,7 +776,7 @@ sub printNamesCppFile
         for my $name (sort keys %allAttrs) {
             print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
         }
-        print F "\n\nconst WebCore::QualifiedName* const * get$parameters{namespace}Attrs()\n";
+        print F "\n\nconst WebCore::QualifiedName* const* get$parameters{namespace}Attrs()\n";
         print F "{\n    static const WebCore::QualifiedName* const $parameters{namespace}Attrs[] = {\n";
         for my $name (sort keys %allAttrs) {
             print F "        reinterpret_cast<const WebCore::QualifiedName*>(&${name}Attr),\n";
@@ -780,19 +788,19 @@ sub printNamesCppFile
 
     printInit($F, 0);
 
-    print(F "    AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
+    print(F "    AtomicString ${lowercaseNamespacePrefix}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
 
     print(F "    // Namespace\n");
-    print(F "    new (NotNull, (void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n");
+    print(F "    new (NotNull, (void*)&${lowercaseNamespacePrefix}NamespaceURI) AtomicString(${lowercaseNamespacePrefix}NS);\n");
     print(F "\n");
     print F StaticString::GenerateStringAsserts(\%allStrings);
 
     if (keys %allTags) {
-        my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
+        my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowercaseNamespacePrefix}NS";
         printDefinitions($F, \%allTags, "tags", $tagsNamespace);
     }
     if (keys %allAttrs) {
-        my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
+        my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowercaseNamespacePrefix}NS";
         printDefinitions($F, \%allAttrs, "attributes", $attrsNamespace);
     }
 
index 689c4db..8bb3df6 100644 (file)
@@ -65,13 +65,13 @@ static String& styleSpanClassString()
     return styleSpanClassString;
 }
 
-bool isLegacyAppleStyleSpan(const Node *node)
+bool isLegacyAppleStyleSpan(const Nodenode)
 {
     if (!node || !node->isHTMLElement())
         return false;
 
-    const HTMLElement* elem = toHTMLElement(node);
-    return elem->hasLocalName(spanAttr) && elem->getAttribute(classAttr) == styleSpanClassString();
+    const HTMLElement& element = toHTMLElement(*node);
+    return element.hasTagName(spanTag) && element.fastGetAttribute(classAttr) == styleSpanClassString();
 }
 
 static bool hasNoAttributeOrOnlyStyleAttribute(const StyledElement* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty)
@@ -130,7 +130,6 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
     , m_start(endingSelection().start().downstream())
     , m_end(endingSelection().end().upstream())
     , m_useEndingSelection(true)
-    , m_styledInlineElement(0)
     , m_removeOnly(false)
     , m_isInlineElementToRemoveFunction(0)
 {
@@ -144,7 +143,6 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
     , m_start(start)
     , m_end(end)
     , m_useEndingSelection(false)
-    , m_styledInlineElement(0)
     , m_removeOnly(false)
     , m_isInlineElementToRemoveFunction(0)
 {
@@ -172,7 +170,6 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
     , m_start(endingSelection().start().downstream())
     , m_end(endingSelection().end().upstream())
     , m_useEndingSelection(true)
-    , m_styledInlineElement(0)
     , m_removeOnly(true)
     , m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction)
 {
@@ -850,7 +847,7 @@ bool ApplyStyleCommand::shouldApplyInlineStyleToRun(EditingStyle* style, Node* r
         // We don't consider m_isInlineElementToRemoveFunction here because we never apply style when m_isInlineElementToRemoveFunction is specified
         if (!style->styleIsPresentInComputedStyleOfNode(node))
             return true;
-        if (m_styledInlineElement && !enclosingNodeWithTag(positionBeforeNode(node), m_styledInlineElement->tagQName()))
+        if (m_styledInlineElement && !enclosingElementWithTag(positionBeforeNode(node), m_styledInlineElement->tagQName()))
             return true;
     }
     return false;
index 07574f7..a05e4a0 100644 (file)
@@ -797,11 +797,11 @@ bool Editor::hasBidiSelection() const
 TriState Editor::selectionUnorderedListState() const
 {
     if (m_frame.selection().isCaret()) {
-        if (enclosingNodeWithTag(m_frame.selection().selection().start(), ulTag))
+        if (enclosingElementWithTag(m_frame.selection().selection().start(), ulTag))
             return TrueTriState;
     } else if (m_frame.selection().isRange()) {
-        Node* startNode = enclosingNodeWithTag(m_frame.selection().selection().start(), ulTag);
-        Node* endNode = enclosingNodeWithTag(m_frame.selection().selection().end(), ulTag);
+        auto* startNode = enclosingElementWithTag(m_frame.selection().selection().start(), ulTag);
+        auto* endNode = enclosingElementWithTag(m_frame.selection().selection().end(), ulTag);
         if (startNode && endNode && startNode == endNode)
             return TrueTriState;
     }
@@ -812,11 +812,11 @@ TriState Editor::selectionUnorderedListState() const
 TriState Editor::selectionOrderedListState() const
 {
     if (m_frame.selection().isCaret()) {
-        if (enclosingNodeWithTag(m_frame.selection().selection().start(), olTag))
+        if (enclosingElementWithTag(m_frame.selection().selection().start(), olTag))
             return TrueTriState;
     } else if (m_frame.selection().isRange()) {
-        Node* startNode = enclosingNodeWithTag(m_frame.selection().selection().start(), olTag);
-        Node* endNode = enclosingNodeWithTag(m_frame.selection().selection().end(), olTag);
+        auto* startNode = enclosingElementWithTag(m_frame.selection().selection().start(), olTag);
+        auto* endNode = enclosingElementWithTag(m_frame.selection().selection().end(), olTag);
         if (startNode && endNode && startNode == endNode)
             return TrueTriState;
     }
index 4bc44f5..44050c0 100644 (file)
@@ -130,7 +130,7 @@ void InsertListCommand::doApply()
     if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary))
         setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional()));
 
-    const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag;
+    auto& listTag = (m_type == OrderedList) ? olTag : ulTag;
     if (endingSelection().isRange()) {
         VisibleSelection selection = selectionForParagraphIteration(endingSelection());
         ASSERT(selection.isRange());
@@ -192,7 +192,7 @@ void InsertListCommand::doApply()
     doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get());
 }
 
-void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range* currentSelection)
+void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName& listTag, Range* currentSelection)
 {
     // FIXME: This will produce unexpected results for a selection that starts just before a
     // table and ends inside the first cell, selectionForParagraphIteration should probably
@@ -207,9 +207,10 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
             listNode = fixOrphanedListChild(listChildNode);
             listNode = mergeWithNeighboringLists(listNode);
         }
-        if (!listNode->hasTagName(listTag))
+        if (!listNode->hasTagName(listTag)) {
             // listChildNode will be removed from the list and a list of type m_type will be created.
             switchListType = true;
+        }
 
         // If the list is of the desired type, and we are not removing the list, then exit early.
         if (!switchListType && forceCreateList)
index 59730fb..9a4659b 100644 (file)
@@ -31,6 +31,7 @@
 namespace WebCore {
 
 class HTMLElement;
+class HTMLQualifiedName;
 
 class InsertListCommand : public CompositeEditCommand {
 public:
@@ -54,7 +55,7 @@ private:
     HTMLElement* fixOrphanedListChild(Node*);
     bool selectionHasListOfType(const VisibleSelection& selection, const QualifiedName&);
     PassRefPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtr<HTMLElement>);
-    void doApplyForSingleParagraph(bool forceCreateList, const QualifiedName&, Range* currentSelection);
+    void doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName&, Range* currentSelection);
     void unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode);
     PassRefPtr<HTMLElement> listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag);
     RefPtr<HTMLElement> m_listElement;
index 9ee8ac1..172b85c 100644 (file)
@@ -140,8 +140,8 @@ void MarkupAccumulator::serializeNodesWithNamespaces(Node& targetNode, Node* nod
         return;
 
     if (tagNamesToSkip && targetNode.isElementNode()) {
-        for (size_t i = 0; i < tagNamesToSkip->size(); ++i) {
-            if (targetNode.hasTagName(tagNamesToSkip->at(i)))
+        for (auto& name : *tagNamesToSkip) {
+            if (toElement(targetNode).hasTagName(name))
                 return;
         }
     }
index dc10102..fedfa0a 100644 (file)
@@ -628,12 +628,12 @@ void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild
             continue;
 
         if (isProhibitedParagraphChild(toHTMLElement(node.get())->localName())) {
-            if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithTag(positionInParentBeforeNode(node.get()), pTag)))
+            if (auto* paragraphElement = enclosingElementWithTag(positionInParentBeforeNode(node.get()), pTag))
                 moveNodeOutOfAncestor(node, paragraphElement);
         }
 
         if (isHeaderElement(node.get())) {
-            if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement)))
+            if (auto* headerElement = highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement))
                 moveNodeOutOfAncestor(node, headerElement);
         }
     }
@@ -672,8 +672,8 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
 
     Node* lastLeafInserted = insertedNodes.lastLeafInserted();
     if (lastLeafInserted && lastLeafInserted->isTextNode() && !hasRenderedText(toText(*lastLeafInserted))
-        && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag)
-        && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) {
+        && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag)
+        && !enclosingElementWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) {
         insertedNodes.willRemoveNode(lastLeafInserted);
         removeNode(lastLeafInserted);
     }
@@ -690,7 +690,7 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
 {
     // FIXME: Why is this hack here?  What's special about <select> tags?
-    Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectTag);
+    auto* enclosingSelect = enclosingElementWithTag(m_endOfInsertedContent, selectTag);
     return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent;
 }
 
index bc0ae04..4dd2e93 100644 (file)
@@ -807,12 +807,12 @@ static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText)
 
 static bool hasHeaderTag(HTMLElement& element)
 {
-    return element.hasLocalName(h1Tag)
-        || element.hasLocalName(h2Tag)
-        || element.hasLocalName(h3Tag)
-        || element.hasLocalName(h4Tag)
-        || element.hasLocalName(h5Tag)
-        || element.hasLocalName(h6Tag);
+    return element.hasTagName(h1Tag)
+        || element.hasTagName(h2Tag)
+        || element.hasTagName(h3Tag)
+        || element.hasTagName(h4Tag)
+        || element.hasTagName(h5Tag)
+        || element.hasTagName(h6Tag);
 }
 
 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
@@ -825,19 +825,19 @@ static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
             return false;
         auto& element = toHTMLElement(node);
         return hasHeaderTag(element)
-            || element.hasLocalName(blockquoteTag)
-            || element.hasLocalName(ddTag)
-            || element.hasLocalName(divTag)
-            || element.hasLocalName(dlTag)
-            || element.hasLocalName(dtTag)
-            || element.hasLocalName(hrTag)
-            || element.hasLocalName(liTag)
-            || element.hasLocalName(listingTag)
-            || element.hasLocalName(olTag)
-            || element.hasLocalName(pTag)
-            || element.hasLocalName(preTag)
-            || element.hasLocalName(trTag)
-            || element.hasLocalName(ulTag);
+            || element.hasTagName(blockquoteTag)
+            || element.hasTagName(ddTag)
+            || element.hasTagName(divTag)
+            || element.hasTagName(dlTag)
+            || element.hasTagName(dtTag)
+            || element.hasTagName(hrTag)
+            || element.hasTagName(liTag)
+            || element.hasTagName(listingTag)
+            || element.hasTagName(olTag)
+            || element.hasTagName(pTag)
+            || element.hasTagName(preTag)
+            || element.hasTagName(trTag)
+            || element.hasTagName(ulTag);
     }
     
     // Need to make an exception for table cells, because they are blocks, but we
@@ -894,7 +894,7 @@ static bool shouldEmitExtraNewlineForNode(Node& node)
     // NOTE: We only do this for a select set of nodes, and WinIE appears not to do this at all.
     if (!node.isHTMLElement())
         return false;
-    if (!(hasHeaderTag(toHTMLElement(node)) || toHTMLElement(node).hasLocalName(pTag)))
+    if (!(hasHeaderTag(toHTMLElement(node)) || toHTMLElement(node).hasTagName(pTag)))
         return false;
 
     int bottomMargin = toRenderBox(renderer)->collapsedMarginAfter();
index ff8f809..3a6dba3 100644 (file)
 #include "Editor.h"
 #include "Element.h"
 #include "Frame.h"
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "InsertLineBreakCommand.h"
 #include "InsertParagraphSeparatorCommand.h"
 #include "InsertTextCommand.h"
+#include "MathMLElement.h"
 #include "RenderElement.h"
 #include "TextIterator.h"
 #include "VisibleUnits.h"
index 0c91fa5..f9a3068 100644 (file)
@@ -27,7 +27,7 @@
 #include "VisibleUnits.h"
 
 #include "Document.h"
-#include "Element.h"
+#include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "InlineTextBox.h"
 #include "NodeTraversal.h"
index ad333a5..8d41190 100644 (file)
@@ -542,22 +542,24 @@ bool isListItem(const Node *n)
     return n && (isListElement(n->parentNode()) || (n->renderer() && n->renderer()->isListItem()));
 }
 
-Node* enclosingNodeWithTag(const Position& p, const QualifiedName& tagName)
+Element* enclosingElementWithTag(const Position& position, const QualifiedName& tagName)
 {
-    if (p.isNull())
-        return 0;
-        
-    Node* root = highestEditableRoot(p);
-    for (Node* n = p.deprecatedNode(); n; n = n->parentNode()) {
-        if (root && !n->hasEditableStyle())
+    if (position.isNull())
+        return nullptr;
+
+    Node* root = highestEditableRoot(position);
+    for (Node* node = position.deprecatedNode(); node; node = node->parentNode()) {
+        if (root && !node->hasEditableStyle())
             continue;
-        if (n->hasTagName(tagName))
-            return n;
-        if (n == root)
-            return 0;
+        if (!node->isElementNode())
+            continue;
+        if (toElement(*node).hasTagName(tagName))
+            return toElement(node);
+        if (node == root)
+            return nullptr;
     }
-    
-    return 0;
+
+    return nullptr;
 }
 
 Node* enclosingNodeOfType(const Position& p, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule rule)
index 9b48073..e9b674e 100644 (file)
@@ -65,7 +65,7 @@ Element* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingB
 Node* enclosingTableCell(const Position&);
 Node* enclosingEmptyListItem(const VisiblePosition&);
 Element* enclosingAnchorElement(const Position&);
-Node* enclosingNodeWithTag(const Position&, const QualifiedName&);
+Element* enclosingElementWithTag(const Position&, const QualifiedName&);
 Node* enclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*), EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
 
 Node* tabSpanNode(const Node*);
index 536eacb..3cff968 100644 (file)
@@ -298,7 +298,7 @@ PassRefPtr<Range> Editor::adjustedSelectionRange()
     RefPtr<Range> range = selectedRange();
     Node* commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTION);
     ASSERT(commonAncestor);
-    Node* enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
+    auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
     if (enclosingAnchor && comparePositions(firstPositionInOrBeforeNode(range->startPosition().anchorNode()), range->startPosition()) >= 0)
         range->setStart(enclosingAnchor, 0, IGNORE_EXCEPTION);
     return range;
index a00a8f9..dabb190 100644 (file)
@@ -249,7 +249,7 @@ void StyledMarkupAccumulator::appendText(StringBuilder& out, const Text& text)
     if (!shouldAnnotate() || parentIsTextarea)
         MarkupAccumulator::appendText(out, text);
     else {
-        const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(const_cast<Text*>(&text)), selectTag);
+        const bool useRenderedText = !enclosingElementWithTag(firstPositionInNode(const_cast<Text*>(&text)), selectTag);
         String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
         StringBuilder buffer;
         appendCharactersReplacingEntities(buffer, content, 0, content.length(), EntityMaskInPCDATA);
@@ -387,7 +387,7 @@ Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
             // Don't write out empty block containers that aren't fully selected.
             continue;
 
-        if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode(n), selectTag)) {
+        if (!n->renderer() && !enclosingElementWithTag(firstPositionInOrBeforeNode(n), selectTag)) {
             next = NodeTraversal::nextSkippingChildren(n);
             // Don't skip over pastEnd.
             if (pastEnd && pastEnd->isDescendantOf(n))
@@ -547,7 +547,7 @@ static Node* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterch
     if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
         specialCommonAncestor = commonAncestor;
 
-    if (Node *enclosingAnchor = enclosingNodeWithTag(firstPositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
+    if (auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
         specialCommonAncestor = enclosingAnchor;
 
     return specialCommonAncestor;
@@ -569,7 +569,7 @@ static String createMarkupInternal(Document& document, const Range& range, const
 
     document.updateLayoutIgnorePendingStylesheets();
 
-    Node* body = enclosingNodeWithTag(firstPositionInNode(commonAncestor), bodyTag);
+    auto* body = enclosingElementWithTag(firstPositionInNode(commonAncestor), bodyTag);
     Node* fullySelectedRoot = 0;
     // FIXME: Do this for all fully selected blocks, not just the body.
     if (body && VisiblePosition(firstPositionInNode(body)) == VisiblePosition(range.startPosition())
@@ -948,8 +948,8 @@ PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
         return 0;
     }
 
-    if (element->hasLocalName(colTag) || element->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag)
-        || element->hasLocalName(headTag) || element->hasLocalName(styleTag) || element->hasLocalName(titleTag)) {
+    if (element->hasTagName(colTag) || element->hasTagName(colgroupTag) || element->hasTagName(framesetTag)
+        || element->hasTagName(headTag) || element->hasTagName(styleTag) || element->hasTagName(titleTag)) {
         ec = NOT_SUPPORTED_ERR;
         return 0;
     }
index 65a1372..fb07da4 100644 (file)
@@ -176,38 +176,38 @@ inline bool isMatchingElement(const HTMLCollection& htmlCollection, Element& ele
 
     switch (type) {
     case DocImages:
-        return element.hasLocalName(imgTag);
+        return element.hasTagName(imgTag);
     case DocScripts:
-        return element.hasLocalName(scriptTag);
+        return element.hasTagName(scriptTag);
     case DocForms:
-        return element.hasLocalName(formTag);
+        return element.hasTagName(formTag);
     case TableTBodies:
-        return element.hasLocalName(tbodyTag);
+        return element.hasTagName(tbodyTag);
     case TRCells:
-        return element.hasLocalName(tdTag) || element.hasLocalName(thTag);
+        return element.hasTagName(tdTag) || element.hasTagName(thTag);
     case TSectionRows:
-        return element.hasLocalName(trTag);
+        return element.hasTagName(trTag);
     case SelectOptions:
-        return element.hasLocalName(optionTag);
+        return element.hasTagName(optionTag);
     case SelectedOptions:
-        return element.hasLocalName(optionTag) && toHTMLOptionElement(element).selected();
+        return element.hasTagName(optionTag) && toHTMLOptionElement(element).selected();
     case DataListOptions:
-        if (element.hasLocalName(optionTag)) {
+        if (element.hasTagName(optionTag)) {
             HTMLOptionElement& option = toHTMLOptionElement(element);
             if (!option.isDisabledFormControl() && !option.value().isEmpty())
                 return true;
         }
         return false;
     case MapAreas:
-        return element.hasLocalName(areaTag);
+        return element.hasTagName(areaTag);
     case DocApplets:
-        return element.hasLocalName(appletTag) || (element.hasLocalName(objectTag) && toHTMLObjectElement(element).containsJavaApplet());
+        return element.hasTagName(appletTag) || (element.hasTagName(objectTag) && toHTMLObjectElement(element).containsJavaApplet());
     case DocEmbeds:
-        return element.hasLocalName(embedTag);
+        return element.hasTagName(embedTag);
     case DocLinks:
-        return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
+        return (element.hasTagName(aTag) || element.hasTagName(areaTag)) && element.fastHasAttribute(hrefAttr);
     case DocAnchors:
-        return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
+        return element.hasTagName(aTag) && element.fastHasAttribute(nameAttr);
     case DocAll:
     case NodeChildren:
         return true;
@@ -269,13 +269,13 @@ static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement& element)
 {
     // The document.all collection returns only certain types of elements by name,
     // although it returns any type of element by id.
-    return element.hasLocalName(appletTag)
-        || element.hasLocalName(embedTag)
-        || element.hasLocalName(formTag)
-        || element.hasLocalName(imgTag)
-        || element.hasLocalName(inputTag)
-        || element.hasLocalName(objectTag)
-        || element.hasLocalName(selectTag);
+    return element.hasTagName(appletTag)
+        || element.hasTagName(embedTag)
+        || element.hasTagName(formTag)
+        || element.hasTagName(imgTag)
+        || element.hasTagName(inputTag)
+        || element.hasTagName(objectTag)
+        || element.hasTagName(selectTag);
 }
 
 inline Element* firstMatchingChildElement(const HTMLCollection& nodeList, ContainerNode& root)
index ba05180..c271ab2 100644 (file)
@@ -91,28 +91,28 @@ bool HTMLElement::ieForbidsInsertHTML() const
     // This is also called from editing and assumed to be the list of tags
     // for which no end tag should be serialized. It's unclear if the list for
     // IE compat and the list for serialization sanity are the same.
-    if (hasLocalName(areaTag)
-        || hasLocalName(baseTag)
-        || hasLocalName(basefontTag)
-        || hasLocalName(brTag)
-        || hasLocalName(colTag)
-        || hasLocalName(embedTag)
-        || hasLocalName(frameTag)
-        || hasLocalName(hrTag)
-        || hasLocalName(imageTag)
-        || hasLocalName(imgTag)
-        || hasLocalName(inputTag)
-        || hasLocalName(isindexTag)
-        || hasLocalName(linkTag)
-        || hasLocalName(metaTag)
-        || hasLocalName(paramTag)
-        || hasLocalName(sourceTag)
-        || hasLocalName(wbrTag))
+    if (hasTagName(areaTag)
+        || hasTagName(baseTag)
+        || hasTagName(basefontTag)
+        || hasTagName(brTag)
+        || hasTagName(colTag)
+        || hasTagName(embedTag)
+        || hasTagName(frameTag)
+        || hasTagName(hrTag)
+        || hasTagName(imageTag)
+        || hasTagName(imgTag)
+        || hasTagName(inputTag)
+        || hasTagName(isindexTag)
+        || hasTagName(linkTag)
+        || hasTagName(metaTag)
+        || hasTagName(paramTag)
+        || hasTagName(sourceTag)
+        || hasTagName(wbrTag))
         return true;
     // FIXME: I'm not sure why dashboard mode would want to change the
     // serialization of <canvas>, that seems like a bad idea.
 #if ENABLE(DASHBOARD_SUPPORT)
-    if (hasLocalName(canvasTag)) {
+    if (hasTagName(canvasTag)) {
         Settings* settings = document().settings();
         if (settings && settings->usesDashboardBackwardCompatibilityMode())
             return true;
@@ -123,7 +123,7 @@ bool HTMLElement::ieForbidsInsertHTML() const
 
 static inline CSSValueID unicodeBidiAttributeForDirAuto(HTMLElement& element)
 {
-    if (element.hasLocalName(preTag) || element.hasLocalName(textareaTag))
+    if (element.hasTagName(preTag) || element.hasTagName(textareaTag))
         return CSSValueWebkitPlaintext;
     // FIXME: For bdo element, dir="auto" should result in "bidi-override isolate" but we don't support having multiple values in unicode-bidi yet.
     // See https://bugs.webkit.org/show_bug.cgi?id=73164.
@@ -134,7 +134,7 @@ unsigned HTMLElement::parseBorderWidthAttribute(const AtomicString& value) const
 {
     unsigned borderWidth = 0;
     if (value.isEmpty() || !parseHTMLNonNegativeInteger(value, borderWidth))
-        return hasLocalName(tableTag) ? 1 : borderWidth;
+        return hasTagName(tableTag) ? 1 : borderWidth;
     return borderWidth;
 }
 
@@ -378,7 +378,7 @@ void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
     if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, ec)) {
         ContainerNode* container = this;
 #if ENABLE(TEMPLATE_ELEMENT)
-        if (hasLocalName(templateTag))
+        if (hasTagName(templateTag))
             container = toHTMLTemplateElement(this)->content();
 #endif
         replaceChildrenWithFragment(*container, fragment.release(), ec);
@@ -455,16 +455,27 @@ PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Exc
     return fragment;
 }
 
+static inline bool shouldProhibitSetInnerOuterText(const HTMLElement& element)
+{
+    return element.hasTagName(colTag)
+        || element.hasTagName(colgroupTag)
+        || element.hasTagName(framesetTag)
+        || element.hasTagName(headTag)
+        || element.hasTagName(htmlTag)
+        || element.hasTagName(tableTag)
+        || element.hasTagName(tbodyTag)
+        || element.hasTagName(tfootTag)
+        || element.hasTagName(theadTag)
+        || element.hasTagName(trTag);
+}
+
 void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
 {
     if (ieForbidsInsertHTML()) {
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
-    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
-        hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || 
-        hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||
-        hasLocalName(trTag)) {
+    if (shouldProhibitSetInnerOuterText(*this)) {
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
@@ -509,10 +520,7 @@ void HTMLElement::setOuterText(const String& text, ExceptionCode& ec)
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
-    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||
-        hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || 
-        hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) ||
-        hasLocalName(trTag)) {
+    if (shouldProhibitSetInnerOuterText(*this)) {
         ec = NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
@@ -791,11 +799,11 @@ PassRefPtr<HTMLCollection> HTMLElement::children()
 
 bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
 {
-    if (hasLocalName(noscriptTag)) {
+    if (hasTagName(noscriptTag)) {
         Frame* frame = document().frame();
         if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
             return false;
-    } else if (hasLocalName(noembedTag)) {
+    } else if (hasTagName(noembedTag)) {
         Frame* frame = document().frame();
         if (frame && frame->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin))
             return false;
@@ -805,7 +813,7 @@ bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
 
 RenderPtr<RenderElement> HTMLElement::createElementRenderer(PassRef<RenderStyle> style)
 {
-    if (hasLocalName(wbrTag))
+    if (hasTagName(wbrTag))
         return createRenderer<RenderLineBreak>(*this, std::move(style));
     return RenderElement::createFor(*this, std::move(style));
 }
index 0080677..c9b60df 100644 (file)
@@ -99,6 +99,8 @@ public:
     virtual bool isLabelable() const { return false; }
     virtual FormNamedItem* asFormNamedItem() { return 0; }
 
+    bool hasTagName(const HTMLQualifiedName& name) const { return hasLocalName(name.localName()); }
+
 protected:
     HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 
@@ -151,6 +153,11 @@ template <> inline bool isElementOfType<const HTMLElement>(const Element& elemen
 
 NODE_TYPE_CASTS(HTMLElement)
 
+inline bool Node::hasTagName(const HTMLQualifiedName& name) const
+{
+    return isHTMLElement() && toHTMLElement(*this).hasTagName(name);
+}
+
 } // namespace WebCore
 
 #include "HTMLElementTypeHelpers.h"
index 47d0d29..aef11a8 100644 (file)
@@ -397,7 +397,7 @@ static bool isRecognizedTagName(const QualifiedName& tagName)
 {
     DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
     if (tagList.isEmpty()) {
-        const QualifiedName* const * tags = HTMLNames::getHTMLTags();
+        auto* tags = HTMLNames::getHTMLTags();
         for (size_t i = 0; i < HTMLNames::HTMLTagsCount; i++) {
             if (*tags[i] == bgsoundTag
                 || *tags[i] == commandTag
index d72c764..a50605e 100644 (file)
@@ -220,7 +220,7 @@ int HTMLSelectElement::activeSelectionEndListIndex() const
 
 void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionCode& ec)
 {
-    if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
+    if (!element || !(isHTMLOptionElement(*element) || element->hasTagName(hrTag)))
         return;
 
     // Make sure the element is ref'd and deref'd so we don't leak it.
@@ -249,15 +249,14 @@ void HTMLSelectElement::remove(HTMLOptionElement* option)
 
 String HTMLSelectElement::value() const
 {
-    const Vector<HTMLElement*>& items = listItems();
-    for (unsigned i = 0; i < items.size(); i++) {
-        if (items[i]->hasLocalName(optionTag)) {
-            HTMLOptionElement* option = toHTMLOptionElement(items[i]);
-            if (option->selected())
-                return option->value();
+    for (auto* item : listItems()) {
+        if (isHTMLOptionElement(*item)) {
+            HTMLOptionElement& option = toHTMLOptionElement(*item);
+            if (option.selected())
+                return option.value();
         }
     }
-    return "";
+    return emptyString();
 }
 
 void HTMLSelectElement::setValue(const String &value)
@@ -269,15 +268,14 @@ void HTMLSelectElement::setValue(const String &value)
     }
 
     // Find the option with value() matching the given parameter and make it the current selection.
-    const Vector<HTMLElement*>& items = listItems();
     unsigned optionIndex = 0;
-    for (unsigned i = 0; i < items.size(); i++) {
-        if (items[i]->hasLocalName(optionTag)) {
-            if (toHTMLOptionElement(items[i])->value() == value) {
+    for (auto* item : listItems()) {
+        if (isHTMLOptionElement(*item)) {
+            if (toHTMLOptionElement(*item).value() == value) {
                 setSelectedIndex(optionIndex);
                 return;
             }
-            optionIndex++;
+            ++optionIndex;
         }
     }
 
@@ -484,18 +482,16 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
         // of elements that we intend to remove then attempt to remove them one at a time.
         Vector<RefPtr<Element>> itemsToRemove;
         size_t optionIndex = 0;
-        for (size_t i = 0; i < items.size(); ++i) {
-            Element* item = items[i];
-            if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) {
+        for (auto& item : items) {
+            if (isHTMLOptionElement(*item) && optionIndex++ >= newLen) {
                 ASSERT(item->parentNode());
                 itemsToRemove.append(item);
             }
         }
 
-        for (size_t i = 0; i < itemsToRemove.size(); ++i) {
-            Element* item = itemsToRemove[i].get();
+        for (auto& item : itemsToRemove) {
             if (item->parentNode())
-                item->parentNode()->removeChild(item, ec);
+                item->parentNode()->removeChild(item.get(), ec);
         }
     }
     setNeedsValidityCheck();
@@ -997,7 +993,7 @@ size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t list
     const Vector<HTMLElement*>& items = listItems();
     size_t loopEndIndex = std::min(items.size(), listIndexEnd);
     for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
-        if (!items[i]->hasLocalName(optionTag))
+        if (!isHTMLOptionElement(items[i]))
             continue;
         if (toHTMLOptionElement(items[i])->value() == value)
             return i;
@@ -1015,7 +1011,7 @@ void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
         return;
 
     for (size_t i = 0; i < itemsSize; ++i) {
-        if (!items[i]->hasLocalName(optionTag))
+        if (!isHTMLOptionElement(items[i]))
             continue;
         toHTMLOptionElement(items[i])->setSelectedState(false);
     }
@@ -1495,9 +1491,9 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
         } else if (m_multiple && keyCode == ' ' && m_allowsNonContiguousSelection) {
             // Use space to toggle selection change.
             m_activeSelectionState = !m_activeSelectionState;
-            ASSERT(m_activeSelectionEndIndex >= 0
-                && m_activeSelectionEndIndex < static_cast<int>(listItems.size())
-                && listItems[m_activeSelectionEndIndex]->hasTagName(optionTag));
+            ASSERT(m_activeSelectionEndIndex >= 0);
+            ASSERT(m_activeSelectionEndIndex < static_cast<int>(listItems.size()));
+            ASSERT(isHTMLOptionElement(*listItems[m_activeSelectionEndIndex]));
             updateSelectedState(m_activeSelectionEndIndex, true /*multi*/, false /*shift*/);
             listBoxOnChange();
             event->setDefaultHandled();
index bbf8108..016899f 100644 (file)
@@ -84,11 +84,11 @@ void HTMLTableColElement::parseAttribute(const QualifiedName& name, const Atomic
 
 const StyleProperties* HTMLTableColElement::additionalPresentationAttributeStyle()
 {
-    if (!hasLocalName(colgroupTag))
-        return 0;
+    if (!hasTagName(colgroupTag))
+        return nullptr;
     if (HTMLTableElement* table = findParentTable())
         return table->additionalGroupStyle(false);
-    return 0;
+    return nullptr;
 }
 
 void HTMLTableColElement::setSpan(int n)
index 5f8bc0b..7e5f664 100644 (file)
@@ -54,12 +54,11 @@ static inline void assertRowIsInTable(HTMLTableElement* table, HTMLTableRowEleme
 #endif
 }
 
-static inline bool isInSection(HTMLTableRowElement* row, const QualifiedName& sectionTag)
+static inline bool isInSection(HTMLTableRowElement& row, const HTMLQualifiedName& sectionTag)
 {
-    // Because we know that the parent is a table or a section, all of which are in the HTML
-    // namespace, it's OK to do the faster hasLocalName here instead of the more typical hasTagName,
-    // since we don't need the check for the HTML namespace.
-    return toElement(row->parentNode())->hasLocalName(sectionTag);
+    // Because we know that the parent is a table or a section, it's safe to cast it to an HTMLElement
+    // giving us access to the faster hasTagName overload from that class.
+    return toHTMLElement(row.parentNode())->hasTagName(sectionTag);
 }
 
 HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
@@ -81,7 +80,7 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table,
     // If still looking at head sections, find the first row in the next head section.
     if (!previous)
         child = ElementTraversal::firstChild(table);
-    else if (isInSection(previous, theadTag))
+    else if (isInSection(*previous, theadTag))
         child = ElementTraversal::nextSibling(previous->parentNode());
     for (; child; child = ElementTraversal::nextSibling(child)) {
         if (child->hasTagName(theadTag)) {
@@ -91,11 +90,11 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table,
     }
 
     // If still looking at top level and bodies, find the next row in top level or the first in the next body section.
-    if (!previous || isInSection(previous, theadTag))
+    if (!previous || isInSection(*previous, theadTag))
         child = ElementTraversal::firstChild(table);
     else if (previous->parentNode() == table)
         child = ElementTraversal::nextSibling(previous);
-    else if (isInSection(previous, tbodyTag))
+    else if (isInSection(*previous, tbodyTag))
         child = ElementTraversal::nextSibling(previous->parentNode());
     for (; child; child = ElementTraversal::nextSibling(child)) {
         if (isHTMLTableRowElement(child))
@@ -107,7 +106,7 @@ HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table,
     }
 
     // Find the first row in the next foot section.
-    if (!previous || !isInSection(previous, tfootTag))
+    if (!previous || !isInSection(*previous, tfootTag))
         child = ElementTraversal::firstChild(table);
     else
         child = ElementTraversal::nextSibling(previous->parentNode());
index 0f06998..3407d29 100644 (file)
@@ -42,6 +42,7 @@
 #include "HTMLScriptElement.h"
 #include "HTMLTemplateElement.h"
 #include "NotImplemented.h"
+#include "SVGElement.h"
 #include "Text.h"
 
 namespace WebCore {
index bb07748..213858e 100644 (file)
@@ -42,6 +42,7 @@
 #include "XMLNSNames.h"
 #include "XMLNames.h"
 #include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/unicode/CharacterNames.h>
 
 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
@@ -522,91 +523,81 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
     m_tree.insertHTMLElement(token);
 }
 
-typedef HashMap<AtomicString, QualifiedName> PrefixedNameToQualifiedNameMap;
-
-static void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, const QualifiedName* const names[], size_t length)
+template <typename TableQualifiedName>
+static HashMap<AtomicString, QualifiedName> createCaseMap(const TableQualifiedName* const names[], unsigned length)
 {
-    for (size_t i = 0; i < length; ++i) {
+    HashMap<AtomicString, QualifiedName> map;
+    for (unsigned i = 0; i < length; ++i) {
         const QualifiedName& name = *names[i];
         const AtomicString& localName = name.localName();
         AtomicString loweredLocalName = localName.lower();
         if (loweredLocalName != localName)
-            map->add(loweredLocalName, name);
+            map.add(loweredLocalName, name);
     }
+    return map;
 }
 
-static void adjustSVGTagNameCase(AtomicHTMLToken* token)
+static void adjustSVGTagNameCase(AtomicHTMLToken& token)
 {
-    static PrefixedNameToQualifiedNameMap* caseMap = 0;
-    if (!caseMap) {
-        caseMap = new PrefixedNameToQualifiedNameMap;
-        mapLoweredLocalNameToName(caseMap, SVGNames::getSVGTags(), SVGNames::SVGTagsCount);
-    }
-
-    const QualifiedName& casedName = caseMap->get(token->name());
+    static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createCaseMap(SVGNames::getSVGTags(), SVGNames::SVGTagsCount);
+    const QualifiedName& casedName = map.get().get(token.name());
     if (casedName.localName().isNull())
         return;
-    token->setName(casedName.localName());
+    token.setName(casedName.localName());
 }
 
-template<const QualifiedName* const * getAttrs(), unsigned length>
-static void adjustAttributes(AtomicHTMLToken* token)
+static inline void adjustAttributes(HashMap<AtomicString, QualifiedName>& map, AtomicHTMLToken& token)
 {
-    static PrefixedNameToQualifiedNameMap* caseMap = 0;
-    if (!caseMap) {
-        caseMap = new PrefixedNameToQualifiedNameMap;
-        mapLoweredLocalNameToName(caseMap, getAttrs(), length);
-    }
-
-    for (unsigned i = 0; i < token->attributes().size(); ++i) {
-        Attribute& tokenAttribute = token->attributes().at(i);
-        const QualifiedName& casedName = caseMap->get(tokenAttribute.localName());
+    for (auto& attribute : token.attributes()) {
+        const QualifiedName& casedName = map.get(attribute.localName());
         if (!casedName.localName().isNull())
-            tokenAttribute.parserSetName(casedName);
+            attribute.parserSetName(casedName);
     }
 }
 
-static void adjustSVGAttributes(AtomicHTMLToken* token)
+template<const QualifiedName* const* attributesTable(), unsigned attributesTableLength>
+static void adjustAttributes(AtomicHTMLToken& token)
+{
+    static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createCaseMap(attributesTable(), attributesTableLength);
+    adjustAttributes(map, token);
+}
+
+static inline void adjustSVGAttributes(AtomicHTMLToken& token)
 {
     adjustAttributes<SVGNames::getSVGAttrs, SVGNames::SVGAttrsCount>(token);
 }
 
-static void adjustMathMLAttributes(AtomicHTMLToken* token)
+static inline void adjustMathMLAttributes(AtomicHTMLToken& token)
 {
     adjustAttributes<MathMLNames::getMathMLAttrs, MathMLNames::MathMLAttrsCount>(token);
 }
 
-static void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, const QualifiedName* const names[], size_t length)
+static void addNamesWithPrefix(HashMap<AtomicString, QualifiedName>& map, const AtomicString& prefix, const QualifiedName* const names[], unsigned length)
 {
-    for (size_t i = 0; i < length; ++i) {
+    for (unsigned i = 0; i < length; ++i) {
         const QualifiedName& name = *names[i];
         const AtomicString& localName = name.localName();
-        AtomicString prefixColonLocalName = prefix + ':' + localName;
-        QualifiedName nameWithPrefix(prefix, localName, name.namespaceURI());
-        map->add(prefixColonLocalName, nameWithPrefix);
+        map.add(prefix + ':' + localName, QualifiedName(prefix, localName, name.namespaceURI()));
     }
 }
 
-static void adjustForeignAttributes(AtomicHTMLToken* token)
+static HashMap<AtomicString, QualifiedName> createForeignAttributesMap()
 {
-    static PrefixedNameToQualifiedNameMap* map = 0;
-    if (!map) {
-        map = new PrefixedNameToQualifiedNameMap;
+    HashMap<AtomicString, QualifiedName> map;
 
-        addNamesWithPrefix(map, xlinkAtom, XLinkNames::getXLinkAttrs(), XLinkNames::XLinkAttrsCount);
+    addNamesWithPrefix(map, xlinkAtom, XLinkNames::getXLinkAttrs(), XLinkNames::XLinkAttrsCount);
+    addNamesWithPrefix(map, xmlAtom, XMLNames::getXMLAttrs(), XMLNames::XMLAttrsCount);
 
-        addNamesWithPrefix(map, xmlAtom, XMLNames::getXMLAttrs(), XMLNames::XMLAttrsCount);
+    map.add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
+    map.add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
 
-        map->add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
-        map->add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
-    }
+    return map;
+}
 
-    for (unsigned i = 0; i < token->attributes().size(); ++i) {
-        Attribute& tokenAttribute = token->attributes().at(i);
-        const QualifiedName& name = map->get(tokenAttribute.localName());
-        if (!name.localName().isNull())
-            tokenAttribute.parserSetName(name);
-    }
+static void adjustForeignAttributes(AtomicHTMLToken& token)
+{
+    static NeverDestroyed<HashMap<AtomicString, QualifiedName>> map = createForeignAttributesMap();
+    adjustAttributes(map, token);
 }
 
 void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
@@ -896,15 +887,15 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
     }
     if (token->name() == MathMLNames::mathTag.localName()) {
         m_tree.reconstructTheActiveFormattingElements();
-        adjustMathMLAttributes(token);
-        adjustForeignAttributes(token);
+        adjustMathMLAttributes(*token);
+        adjustForeignAttributes(*token);
         m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
         return;
     }
     if (token->name() == SVGNames::svgTag.localName()) {
         m_tree.reconstructTheActiveFormattingElements();
-        adjustSVGAttributes(token);
-        adjustForeignAttributes(token);
+        adjustSVGAttributes(*token);
+        adjustForeignAttributes(*token);
         m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
         return;
     }
@@ -2926,18 +2917,18 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
         }
         const AtomicString& currentNamespace = m_tree.currentStackItem()->namespaceURI();
         if (currentNamespace == MathMLNames::mathmlNamespaceURI)
-            adjustMathMLAttributes(token);
+            adjustMathMLAttributes(*token);
         if (currentNamespace == SVGNames::svgNamespaceURI) {
-            adjustSVGTagNameCase(token);
-            adjustSVGAttributes(token);
+            adjustSVGTagNameCase(*token);
+            adjustSVGAttributes(*token);
         }
-        adjustForeignAttributes(token);
+        adjustForeignAttributes(*token);
         m_tree.insertForeignElement(token, currentNamespace);
         break;
     }
     case HTMLToken::EndTag: {
         if (m_tree.currentStackItem()->namespaceURI() == SVGNames::svgNamespaceURI)
-            adjustSVGTagNameCase(token);
+            adjustSVGTagNameCase(*token);
 
         if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
             if (scriptingContentIsAllowed(m_tree.parserContentPolicy()))
index d02e67e..c635c58 100644 (file)
@@ -48,6 +48,7 @@
 #include "InspectorCSSAgent.h"
 #include "InspectorPageAgent.h"
 #include "Node.h"
+#include "SVGElement.h"
 #include "SVGNames.h"
 #include "StyleProperties.h"
 #include "StyleResolver.h"
index 9f988a9..98e0449 100644 (file)
@@ -54,6 +54,8 @@ public:
 
     virtual bool isPresentationMathML() const;
 
+    bool hasTagName(const MathMLQualifiedName& name) const { return hasLocalName(name.localName()); }
+
 protected:
     MathMLElement(const QualifiedName& tagName, Document&);
 
@@ -63,15 +65,20 @@ protected:
 
     virtual bool isPresentationAttribute(const QualifiedName&) const override;
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
-private:    
 
-    virtual void updateSelectedChild() { };
+private:
+    virtual void updateSelectedChild() { }
 };
 
 void isMathMLElement(const MathMLElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isMathMLElement(const Node& node) { return node.isMathMLElement(); }
 NODE_TYPE_CASTS(MathMLElement)
 
+inline bool Node::hasTagName(const MathMLQualifiedName& name) const
+{
+    return isMathMLElement() && toMathMLElement(*this).hasTagName(name);
+}
+
 }
 
 #endif // ENABLE(MATHML)
index 90ddb99..a4144ec 100644 (file)
@@ -60,7 +60,7 @@ void MathMLInlineContainerElement::childrenChanged(const ChildChange& change)
     if (renderer()) {
         if (renderer()->isRenderMathMLRow())
             toRenderMathMLRow(renderer())->updateOperatorProperties();
-        else if (hasLocalName(mathTag) || hasLocalName(msqrtTag)) {
+        else if (hasTagName(mathTag) || hasTagName(msqrtTag)) {
             auto childRenderer = renderer()->firstChild();
             if (childRenderer && childRenderer->isRenderMathMLRow())
                 toRenderMathMLRow(childRenderer)->updateOperatorProperties();
@@ -71,33 +71,33 @@ void MathMLInlineContainerElement::childrenChanged(const ChildChange& change)
 
 RenderPtr<RenderElement> MathMLInlineContainerElement::createElementRenderer(PassRef<RenderStyle> style)
 {
-    if (hasLocalName(annotation_xmlTag))
+    if (hasTagName(annotation_xmlTag))
         return createRenderer<RenderMathMLRow>(*this, std::move(style));
-    if (hasLocalName(merrorTag) || hasLocalName(mphantomTag) || hasLocalName(mrowTag) || hasLocalName(mstyleTag))
+    if (hasTagName(merrorTag) || hasTagName(mphantomTag) || hasTagName(mrowTag) || hasTagName(mstyleTag))
         return createRenderer<RenderMathMLRow>(*this, std::move(style));
-    if (hasLocalName(msubTag))
+    if (hasTagName(msubTag))
         return createRenderer<RenderMathMLScripts>(*this, std::move(style));
-    if (hasLocalName(msupTag))
+    if (hasTagName(msupTag))
         return createRenderer<RenderMathMLScripts>(*this, std::move(style));
-    if (hasLocalName(msubsupTag))
+    if (hasTagName(msubsupTag))
         return createRenderer<RenderMathMLScripts>(*this, std::move(style));
-    if (hasLocalName(mmultiscriptsTag))
+    if (hasTagName(mmultiscriptsTag))
         return createRenderer<RenderMathMLScripts>(*this, std::move(style));
-    if (hasLocalName(moverTag))
+    if (hasTagName(moverTag))
         return createRenderer<RenderMathMLUnderOver>(*this, std::move(style));
-    if (hasLocalName(munderTag))
+    if (hasTagName(munderTag))
         return createRenderer<RenderMathMLUnderOver>(*this, std::move(style));
-    if (hasLocalName(munderoverTag))
+    if (hasTagName(munderoverTag))
         return createRenderer<RenderMathMLUnderOver>(*this, std::move(style));
-    if (hasLocalName(mfracTag))
+    if (hasTagName(mfracTag))
         return createRenderer<RenderMathMLFraction>(*this, std::move(style));
-    if (hasLocalName(msqrtTag))
+    if (hasTagName(msqrtTag))
         return createRenderer<RenderMathMLSquareRoot>(*this, std::move(style));
-    if (hasLocalName(mrootTag))
+    if (hasTagName(mrootTag))
         return createRenderer<RenderMathMLRoot>(*this, std::move(style));
-    if (hasLocalName(mfencedTag))
+    if (hasTagName(mfencedTag))
         return createRenderer<RenderMathMLFenced>(*this, std::move(style));
-    if (hasLocalName(mtableTag))
+    if (hasTagName(mtableTag))
         return createRenderer<RenderMathMLTable>(*this, std::move(style));
 
     return createRenderer<RenderMathMLBlock>(*this, std::move(style));
index a127bfd..1e1cd62 100644 (file)
@@ -71,7 +71,7 @@ void MathMLSelectElement::childrenChanged(const ChildChange& change)
 
 void MathMLSelectElement::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason reason)
 {
-    if (hasLocalName(mactionTag) && (name == MathMLNames::actiontypeAttr || name == MathMLNames::selectionAttr))
+    if (hasTagName(mactionTag) && (name == MathMLNames::actiontypeAttr || name == MathMLNames::selectionAttr))
         updateSelectedChild();
 
     MathMLInlineContainerElement::attributeChanged(name, oldValue, newValue, reason);
@@ -79,7 +79,7 @@ void MathMLSelectElement::attributeChanged(const QualifiedName& name, const Atom
 
 int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild)
 {
-    ASSERT(hasLocalName(mactionTag));
+    ASSERT(hasTagName(mactionTag));
 
     // We "round up or down to the closest allowable value" of the selection attribute, as suggested by the MathML specification.
     selectedChild = firstElementChild();
@@ -100,7 +100,7 @@ int MathMLSelectElement::getSelectedActionChildAndIndex(Element*& selectedChild)
 
 Element* MathMLSelectElement::getSelectedActionChild()
 {
-    ASSERT(hasLocalName(mactionTag));
+    ASSERT(hasTagName(mactionTag));
 
     Element* child = firstElementChild();
     if (!child)
@@ -124,7 +124,7 @@ Element* MathMLSelectElement::getSelectedActionChild()
 
 Element* MathMLSelectElement::getSelectedSemanticsChild()
 {
-    ASSERT(hasLocalName(semanticsTag));
+    ASSERT(hasTagName(semanticsTag));
 
     Element* child = firstElementChild();
     if (!child)
@@ -143,7 +143,7 @@ Element* MathMLSelectElement::getSelectedSemanticsChild()
         if (!child->isMathMLElement())
             continue;
 
-        if (child->hasLocalName(MathMLNames::annotationTag)) {
+        if (child->hasTagName(MathMLNames::annotationTag)) {
             // If the <annotation> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation.
             if (child->hasAttribute(MathMLNames::srcAttr))
                 continue;
@@ -151,7 +151,7 @@ Element* MathMLSelectElement::getSelectedSemanticsChild()
             return child;
         }
 
-        if (child->hasLocalName(MathMLNames::annotation_xmlTag)) {
+        if (child->hasTagName(MathMLNames::annotation_xmlTag)) {
             // If the <annotation-xml> element has an src attribute then it is a reference to arbitrary binary data and it is not clear whether we can display it. Hence we just ignore the annotation.
             if (child->hasAttribute(MathMLNames::srcAttr))
                 continue;
@@ -175,7 +175,7 @@ Element* MathMLSelectElement::getSelectedSemanticsChild()
 
 void MathMLSelectElement::updateSelectedChild()
 {
-    Element* newSelectedChild = hasLocalName(mactionTag) ? getSelectedActionChild() : getSelectedSemanticsChild();
+    Element* newSelectedChild = hasTagName(mactionTag) ? getSelectedActionChild() : getSelectedSemanticsChild();
 
     if (m_selectedChild == newSelectedChild)
         return;
index 001482f..94d9ddb 100644 (file)
@@ -66,11 +66,11 @@ void MathMLTextElement::childrenChanged(const ChildChange& change)
 
 RenderPtr<RenderElement> MathMLTextElement::createElementRenderer(PassRef<RenderStyle> style)
 {
-    if (hasLocalName(MathMLNames::moTag))
+    if (hasTagName(MathMLNames::moTag))
         return createRenderer<RenderMathMLOperator>(*this, std::move(style));
-    if (hasLocalName(MathMLNames::miTag))
+    if (hasTagName(MathMLNames::miTag))
         return createRenderer<RenderMathMLToken>(*this, std::move(style));
-    if (hasLocalName(MathMLNames::mspaceTag))
+    if (hasTagName(MathMLNames::mspaceTag))
         return createRenderer<RenderMathMLSpace>(*this, std::move(style));
 
     return MathMLElement::createElementRenderer(std::move(style));
@@ -78,7 +78,7 @@ RenderPtr<RenderElement> MathMLTextElement::createElementRenderer(PassRef<Render
 
 bool MathMLTextElement::childShouldCreateRenderer(const Node& child) const
 {
-    return !hasLocalName(mspaceTag) && child.isTextNode();
+    return !hasTagName(mspaceTag) && child.isTextNode();
 }
 
 }
index c91a598..808eda2 100644 (file)
@@ -34,6 +34,7 @@
 #include "URL.h"
 #include "PasteboardHelper.h"
 #include "RenderImage.h"
+#include "SVGElement.h"
 #include "SVGNames.h"
 #include "XLinkNames.h"
 #include "markup.h"
index c0c9eed..6c5eb89 100644 (file)
@@ -46,6 +46,7 @@
 #import "Font.h"
 #import "Frame.h"
 #import "FrameLoader.h"
+#import "HTMLElement.h"
 #import "HTMLNames.h"
 #import "HTMLParserIdioms.h"
 #import "LoaderNSURLExtras.h"
index 20c1d4a..e11fe83 100644 (file)
@@ -27,6 +27,7 @@
 #include "Editor.h"
 #include "FloatingObjects.h"
 #include "Frame.h"
+#include "HTMLElement.h"
 #include "HitTestLocation.h"
 #include "InlineTextBox.h"
 #include "LayoutRepainter.h"
 #include "ShapeInsideInfo.h"
 #endif
 
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-#include "HTMLElement.h"
-#endif
-
 namespace WebCore {
 
 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
index cb9e79a..89f376c 100644 (file)
@@ -756,7 +756,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
                     HTMLElement* body = document().body();
                     if (body) {
                         // Can't scroll a frameset document anyway.
-                        isOpaqueRoot = body->hasLocalName(framesetTag);
+                        isOpaqueRoot = body->hasTagName(framesetTag);
                     } else {
                         // SVG documents and XML documents with SVG root nodes are transparent.
                         isOpaqueRoot = !document().hasSVGRootNode();
index b0dba5e..32c7d0b 100644 (file)
@@ -1084,7 +1084,7 @@ RenderElement& RenderElement::rendererForRootBackground()
         // anonymous blocks created by inline <body> tags etc. We can locate the <body>
         // render object very easily via the DOM.
         if (auto body = document().body()) {
-            if (body->hasLocalName(HTMLNames::bodyTag)) {
+            if (body->hasTagName(HTMLNames::bodyTag)) {
                 if (auto renderer = body->renderer())
                     return *renderer;
             }
index 192cef9..a8ac1ad 100644 (file)
@@ -1743,7 +1743,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
         
         // Now look at the body's renderer.
         HTMLElement* body = renderer().document().body();
-        RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
+        RenderObject* bodyObject = (body && body->hasTagName(bodyTag)) ? body->renderer() : 0;
         if (!bodyObject)
             return false;
         
index 181bd2c..2d1fad7 100644 (file)
@@ -27,6 +27,7 @@
 #include "FloatRoundedRect.h"
 #include "Frame.h"
 #include "GraphicsContext.h"
+#include "HTMLElement.h"
 #include "InlineElementBox.h"
 #include "LayoutRepainter.h"
 #include "Page.h"
index 9f3bb8e..b7b744c 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "RenderMathMLScripts.h"
 
-#include "MathMLNames.h"
+#include "MathMLElement.h"
 
 namespace WebCore {
     
@@ -61,14 +61,14 @@ RenderMathMLScripts::RenderMathMLScripts(Element& element, PassRef<RenderStyle>
     , m_baseWrapper(0)
 {
     // Determine what kind of sub/sup expression we have by element name
-    if (element.hasLocalName(MathMLNames::msubTag))
+    if (element.hasTagName(MathMLNames::msubTag))
         m_kind = Sub;
-    else if (element.hasLocalName(MathMLNames::msupTag))
+    else if (element.hasTagName(MathMLNames::msupTag))
         m_kind = Super;
-    else if (element.hasLocalName(MathMLNames::msubsupTag))
+    else if (element.hasTagName(MathMLNames::msubsupTag))
         m_kind = SubSup;
     else {
-        ASSERT(element.hasLocalName(MathMLNames::mmultiscriptsTag));
+        ASSERT(element.hasTagName(MathMLNames::mmultiscriptsTag));
         m_kind = Multiscripts;
     }
 }
index 34af852..f4fb992 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "RenderMathMLUnderOver.h"
 
-#include "MathMLNames.h"
+#include "MathMLElement.h"
 
 namespace WebCore {
 
@@ -39,12 +39,12 @@ RenderMathMLUnderOver::RenderMathMLUnderOver(Element& element, PassRef<RenderSty
     : RenderMathMLBlock(element, std::move(style))
 {
     // Determine what kind of under/over expression we have by element name
-    if (element.hasLocalName(MathMLNames::munderTag))
+    if (element.hasTagName(MathMLNames::munderTag))
         m_kind = Under;
-    else if (element.hasLocalName(MathMLNames::moverTag))
+    else if (element.hasTagName(MathMLNames::moverTag))
         m_kind = Over;
     else {
-        ASSERT(element.hasLocalName(MathMLNames::munderoverTag));
+        ASSERT(element.hasTagName(MathMLNames::munderoverTag));
         m_kind = UnderOver;
     }
 }
index 6433377..bab0f5c 100644 (file)
@@ -140,6 +140,8 @@ public:
     virtual bool shouldMoveToFlowThread(const RenderStyle&) const override;
 #endif
 
+    bool hasTagName(const SVGQualifiedName& name) const { return hasLocalName(name.localName()); }
+
 protected:
     SVGElement(const QualifiedName&, Document&);
     virtual ~SVGElement();
@@ -213,6 +215,11 @@ template <> inline bool isElementOfType<const SVGElement>(const Element& element
 
 NODE_TYPE_CASTS(SVGElement)
 
+inline bool Node::hasTagName(const SVGQualifiedName& name) const
+{
+    return isSVGElement() && toSVGElement(*this).hasTagName(name);
+}
+
 }
 
 #endif
index 4848bc2..bbfbc29 100644 (file)
@@ -63,7 +63,7 @@ PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const
 void SVGFontFaceSrcElement::childrenChanged(const ChildChange& change)
 {
     SVGElement::childrenChanged(change);
-    if (parentNode() && parentNode()->hasTagName(font_faceTag))
+    if (parentNode() && isSVGFontFaceElement(parentNode()))
         toSVGFontFaceElement(parentNode())->rebuildFontFace();
 }
 
index d2e5cbf..baa7175 100644 (file)
@@ -522,15 +522,15 @@ RenderPtr<RenderElement> SVGUseElement::createElementRenderer(PassRef<RenderStyl
     return createRenderer<RenderSVGTransformableContainer>(*this, std::move(style));
 }
 
-static bool isDirectReference(const Node* node)
+static bool isDirectReference(const SVGElement& element)
 {
-    return node->hasTagName(SVGNames::pathTag)
-           || node->hasTagName(SVGNames::rectTag)
-           || node->hasTagName(SVGNames::circleTag)
-           || node->hasTagName(SVGNames::ellipseTag)
-           || node->hasTagName(SVGNames::polygonTag)
-           || node->hasTagName(SVGNames::polylineTag)
-           || node->hasTagName(SVGNames::textTag);
+    return element.hasTagName(SVGNames::pathTag)
+        || element.hasTagName(SVGNames::rectTag)
+        || element.hasTagName(SVGNames::circleTag)
+        || element.hasTagName(SVGNames::ellipseTag)
+        || element.hasTagName(SVGNames::polygonTag)
+        || element.hasTagName(SVGNames::polylineTag)
+        || element.hasTagName(SVGNames::textTag);
 }
 
 void SVGUseElement::toClipPath(Path& path)
@@ -541,12 +541,12 @@ void SVGUseElement::toClipPath(Path& path)
     if (!n)
         return;
 
-    if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) {
-        if (!isDirectReference(n))
+    if (n->isSVGElement() && toSVGElement(*n).isSVGGraphicsElement()) {
+        if (!isDirectReference(toSVGElement(*n))) {
             // Spec: Indirect references are an error (14.3.5)
             document().accessSVGExtensions()->reportError("Not allowed to use indirect reference in <clip-path>");
-        else {
-            toSVGGraphicsElement(n)->toClipPath(path);
+        else {
+            toSVGGraphicsElement(*n).toClipPath(path);
             // FIXME: Avoid manual resolution of x/y here. Its potentially harmful.
             SVGLengthContext lengthContext(this);
             path.translate(FloatSize(x().value(lengthContext), y().value(lengthContext)));
@@ -557,14 +557,17 @@ void SVGUseElement::toClipPath(Path& path)
 
 RenderElement* SVGUseElement::rendererClipChild() const
 {
-    Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
-    if (!n)
-        return 0;
+    if (!m_targetElementInstance)
+        return nullptr;
 
-    if (n->isSVGElement() && isDirectReference(n))
-        return toSVGElement(n)->renderer();
+    auto* element = m_targetElementInstance->shadowTreeElement();
+    if (!element)
+        return nullptr;
 
-    return 0;
+    if (!isDirectReference(*element))
+        return nullptr;
+
+    return element->renderer();
 }
 
 void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundProblem, bool foundUse)
index a62cec9..11e347e 100644 (file)
@@ -275,17 +275,16 @@ bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragm
     // FIXME: We need to implement the HTML5 XML Fragment parsing algorithm:
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#xml-fragment-parsing-algorithm
     // For now we have a hack for script/style innerHTML support:
-    if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag) || contextElement->hasLocalName(HTMLNames::styleTag))) {
+    if (contextElement && (contextElement->hasLocalName(HTMLNames::scriptTag.localName()) || contextElement->hasLocalName(HTMLNames::styleTag.localName()))) {
         fragment.parserAppendChild(fragment.document().createTextNode(chunk));
         return true;
     }
 
     RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
     bool wellFormed = parser->appendFragmentSource(chunk);
-    // Do not call finish().  Current finish() and doEnd() implementations touch the main Document/loader
-    // and can cause crashes in the fragment case.
+    // Do not call finish(). The finish() and doEnd() implementations touch the main document and loader and can cause crashes in the fragment case.
     parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
-    return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than wellFormed().
+    return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than Document::wellFormed().
 }
 
 } // namespace WebCore
index 6c7d881..f7a7764 100644 (file)
@@ -1,3 +1,13 @@
+2014-03-16  Darin Adler  <darin@apple.com>
+
+        Optimize hasTagName when called on an HTMLElement
+        https://bugs.webkit.org/show_bug.cgi?id=130090
+
+        Reviewed by Antti Koivisto.
+
+        * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
+        Updated exports for QualifiedName -> HTMLQualifiedName change.
+
 2014-03-14  Maciej Stachowiak  <mjs@apple.com>
 
         Replace "Apple Computer, Inc." with "Apple Inc." in copyright headers
index 760b90b..d78716e 100644 (file)
@@ -207,10 +207,10 @@ EXPORTS
         symbolWithPointer(?getElementById@TreeScope@WebCore@@QBEPAVElement@2@ABVString@WTF@@@Z, ?getElementById@TreeScope@WebCore@@QEBAPEAVElement@2@AEBVString@WTF@@@Z)
         symbolWithPointer(?getLocationAndLengthFromRange@TextIterator@WebCore@@SA_NPAVNode@2@PBVRange@2@AAI2@Z, ?getLocationAndLengthFromRange@TextIterator@WebCore@@SA_NPEAVNode@2@PEBVRange@2@AEA_K2@Z)
         symbolWithPointer(?hitTest@RenderView@WebCore@@QAE_NABVHitTestRequest@2@AAVHitTestResult@2@@Z, ?hitTest@RenderView@WebCore@@QEAA_NAEBVHitTestRequest@2@AEAVHitTestResult@2@@Z)
-        ?inputTag@HTMLNames@WebCore@@3VQualifiedName@2@B
+        ?inputTag@HTMLNames@WebCore@@3VHTMLQualifiedName@2@B
         symbolWithPointer(?intersects@IntRect@WebCore@@QBE_NABV12@@Z, ?intersects@IntRect@WebCore@@QEBA_NAEBV12@@Z)
         symbolWithPointer(?item@StaticNodeList@WebCore@@UBEPAVNode@2@I@Z, ?item@StaticNodeList@WebCore@@UEBAPEAVNode@2@I@Z)
-        ?selectTag@HTMLNames@WebCore@@3VQualifiedName@2@B
+        ?selectTag@HTMLNames@WebCore@@3VHTMLQualifiedName@2@B
 #if ENABLE(INSPECTOR)
         symbolWithPointer(?buildObjectForHighlightedNode@InspectorController@WebCore@@QBE?AV?$PassRefPtr@VInspectorObject@Inspector@@@WTF@@XZ, ?buildObjectForHighlightedNode@InspectorController@WebCore@@QEBA?AV?$PassRefPtr@VInspectorObject@Inspector@@@WTF@@XZ)
         symbolWithPointer(?getHighlight@InspectorController@WebCore@@QBEXPAUHighlight@2@@Z, ?getHighlight@InspectorController@WebCore@@QEBAXPEAUHighlight@2@@Z)
@@ -310,7 +310,7 @@ EXPORTS
         symbolWithPointer(?suggestedValue@HTMLInputElement@WebCore@@QBEABVString@WTF@@XZ, ?suggestedValue@HTMLInputElement@WebCore@@QEBAAEBVString@WTF@@XZ)
         symbolWithPointer(?target@HistoryItem@WebCore@@QBEABVString@WTF@@XZ, ?target@HistoryItem@WebCore@@QEBAAEBVString@WTF@@XZ)
         symbolWithPointer(?text@Range@WebCore@@QBE?AVString@WTF@@XZ, ?text@Range@WebCore@@QEBA?AVString@WTF@@XZ)
-        ?textareaTag@HTMLNames@WebCore@@3VQualifiedName@2@B
+        ?textareaTag@HTMLNames@WebCore@@3VHTMLQualifiedName@2@B
         symbolWithPointer(?textContent@Node@WebCore@@QBE?AVString@WTF@@_N@Z, ?textContent@Node@WebCore@@QEBA?AVString@WTF@@_N@Z)
         symbolWithPointer(?toDocument@WebCore@@YAPAVDocument@1@VJSValue@JSC@@@Z, ?toDocument@WebCore@@YAPEAVDocument@1@VJSValue@JSC@@@Z)
         symbolWithPointer(?toDOMStringList@WebCore@@YA?AV?$PassRefPtr@VDOMStringList@WebCore@@@WTF@@PAVExecState@JSC@@VJSValue@5@@Z, ?toDOMStringList@WebCore@@YA?AV?$PassRefPtr@VDOMStringList@WebCore@@@WTF@@PEAVExecState@JSC@@VJSValue@5@@Z)