diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index d1513908533b991ab2ea81aab2b8013ef2d808aa..290896df86987147cf32f0a80cec7b5fd2dbed20 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,13 @@ +2010-07-10 Eric Seidel + + Reviewed by Adam Barth. + + HTMLTreeBuilder needs adjustForeignAttributes support + https://bugs.webkit.org/show_bug.cgi?id=42022 + + * html5lib/runner-expected-html5.txt: + - We now pass 3 more tests. + 2010-07-09 Tony Chang Reviewed by Ojan Vafai. diff --git a/LayoutTests/html5lib/runner-expected-html5.txt b/LayoutTests/html5lib/runner-expected-html5.txt index 24b7f4014535b65e1e33f172a5872eec9677167f..03dc42b39053da07e42f127e74ed8c13a6a619be 100644 --- a/LayoutTests/html5lib/runner-expected-html5.txt +++ b/LayoutTests/html5lib/runner-expected-html5.txt @@ -910,10 +910,6 @@ resources/tests10.dat: 15 18 19 -22 -23 -24 -25 Test 13 of 25 in resources/tests10.dat failed. Input:
foobar

baz

quux @@ -1071,102 +1067,6 @@ Expected: | "bar" |

| "baz" - -Test 22 of 25 in resources/tests10.dat failed. Input: - -Got: -| -| -| -| -| xlink:href="foo" -| -| xlink:href="foo" -Expected: -| -| -| -| -| xlink:href="foo" -| -| xlink href="foo" - -Test 23 of 25 in resources/tests10.dat failed. Input: - -Got: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink:href="foo" -| xml:lang="en" -Expected: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink href="foo" -| xml lang="en" - -Test 24 of 25 in resources/tests10.dat failed. Input: - -Got: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink:href="foo" -| xml:lang="en" -Expected: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink href="foo" -| xml lang="en" - -Test 25 of 25 in resources/tests10.dat failed. Input: -bar -Got: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink:href="foo" -| xml:lang="en" -| "bar" -Expected: -| -| -| -| -| xlink:href="foo" -| xml:lang="en" -| -| -| xlink href="foo" -| xml lang="en" -| "bar" resources/tests11.dat: 4 8 diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index 9eb576dd829b1eaf5c756e255d46bf8845337765..6305c7347edf200033decba2b85c3d5555cc45e0 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,22 @@ +2010-07-10 Eric Seidel + + Reviewed by Adam Barth. + + HTMLTreeBuilder needs adjustForeignAttributes support + https://bugs.webkit.org/show_bug.cgi?id=42022 + + To add adjust foreign attributes support I had to add an + AtomicString (prefixed name) to QualifiedName hash. Once I had + done that, I decided it would be best for the other "adjust" functions + to share the same hash logic, so I moved them to using the same + AtomicString -> QualifiedName hash as well. + + Tested by html5lib/runner.html + + * dom/Attribute.h: + (WebCore::Attribute::parserSetName): + * html/HTMLTreeBuilder.cpp: + 2010-07-10 Rob Buis Reviewed by Darin Adler. diff --git a/WebCore/dom/Attribute.h b/WebCore/dom/Attribute.h index 668039db6e82c06e7e86fd6ce419339dce5c367a..cf84a6fdd6566e8e4ac28da475f0967c5baeedee 100644 --- a/WebCore/dom/Attribute.h +++ b/WebCore/dom/Attribute.h @@ -78,13 +78,10 @@ public: void setValue(const AtomicString& value) { m_value = value; } void setPrefix(const AtomicString& prefix) { m_name.setPrefix(prefix); } - // Note: This API is only for HTMLTreeBuilder. It is not safe to change the name - // of an attribute once parseMappedAttributes has been called as DOM elements - // may placed the Attribute in a hash. - void parserSetLocalName(const AtomicString& localName) - { - m_name = QualifiedName(m_name.prefix(), localName, m_name.namespaceURI()); - } + // Note: This API is only for HTMLTreeBuilder. It is not safe to change the + // name of an attribute once parseMappedAttribute has been called as DOM + // elements may have placed the Attribute in a hash by name. + void parserSetName(const QualifiedName& name) { m_name = name; } bool isMappedAttribute() { return m_isMappedAttribute; } diff --git a/WebCore/html/HTMLTreeBuilder.cpp b/WebCore/html/HTMLTreeBuilder.cpp index 111dd841c25a04b04dfa30280694ad6fabfcdff9..36c79c9bfbcacedcafc6ad72fbf906b5a6fb3feb 100644 --- a/WebCore/html/HTMLTreeBuilder.cpp +++ b/WebCore/html/HTMLTreeBuilder.cpp @@ -51,6 +51,9 @@ #include "ScriptController.h" #include "Settings.h" #include "Text.h" +#include "XLinkNames.h" +#include "XMLNSNames.h" +#include "XMLNames.h" #include namespace WebCore { @@ -660,48 +663,20 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token) namespace { -#if ENABLE(SVG) - -typedef HashMap NameCaseMap; - -void addName(NameCaseMap* map, const QualifiedName& attributeName) -{ - map->add(attributeName.localName().lower(), attributeName.localName()); -} +typedef HashMap PrefixedNameToQualifiedNameMap; -NameCaseMap* createCaseMapForNames(QualifiedName** names, size_t length) +void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, QualifiedName** names, size_t length) { - NameCaseMap* caseMap = new NameCaseMap; for (size_t i = 0; i < length; ++i) { - QualifiedName* name = names[i]; - const AtomicString& localName = name->localName(); + const QualifiedName& name = *names[i]; + const AtomicString& localName = name.localName(); AtomicString loweredLocalName = localName.lower(); if (loweredLocalName != localName) - caseMap->add(loweredLocalName, localName); + map->add(loweredLocalName, name); } - return caseMap; } -void adjustSVGAttributes(AtomicHTMLToken& token) -{ - static NameCaseMap* caseMap = 0; - if (!caseMap) { - size_t length = 0; - QualifiedName** svgAttrs = SVGNames::getSVGAttrs(&length); - caseMap = createCaseMapForNames(svgAttrs, length); - } - - NamedNodeMap* attributes = token.attributes(); - if (!attributes) - return; - - for (unsigned x = 0; x < attributes->length(); ++x) { - Attribute* attribute = attributes->attributeItem(x); - const AtomicString& casedName = caseMap->get(attribute->localName()); - if (!casedName.isNull()) - attribute->parserSetLocalName(casedName); - } -} +#if ENABLE(SVG) // FIXME: This is a hack until we can fix SVGNames to always generate all names. QualifiedName svgTagNameFor(const AtomicString& localName) @@ -709,13 +684,19 @@ QualifiedName svgTagNameFor(const AtomicString& localName) return QualifiedName(nullAtom, localName, SVGNames::svgNamespaceURI); } +void addName(PrefixedNameToQualifiedNameMap* map, const QualifiedName& name) +{ + map->add(name.localName().lower(), name); +} + void adjustSVGTagNameCase(AtomicHTMLToken& token) { - static NameCaseMap* caseMap = 0; + static PrefixedNameToQualifiedNameMap* caseMap = 0; if (!caseMap) { + caseMap = new PrefixedNameToQualifiedNameMap; size_t length = 0; QualifiedName** svgTags = SVGNames::getSVGTags(&length); - caseMap = createCaseMapForNames(svgTags, length); + mapLoweredLocalNameToName(caseMap, svgTags, length); // FIXME: This is a hack around the fact that SVGNames does not // currently include all values HTML5 expects it to. addName(caseMap, svgTagNameFor("altGlyphDef")); @@ -723,10 +704,32 @@ void adjustSVGTagNameCase(AtomicHTMLToken& token) addName(caseMap, svgTagNameFor("glyphRef")); } - const AtomicString& casedName = caseMap->get(token.name()); - if (casedName.isNull()) + const QualifiedName& casedName = caseMap->get(token.name()); + if (casedName.localName().isNull()) + return; + token.setName(casedName.localName()); +} + +void adjustSVGAttributes(AtomicHTMLToken& token) +{ + static PrefixedNameToQualifiedNameMap* caseMap = 0; + if (!caseMap) { + caseMap = new PrefixedNameToQualifiedNameMap; + size_t length = 0; + QualifiedName** svgAttrs = SVGNames::getSVGAttrs(&length); + mapLoweredLocalNameToName(caseMap, svgAttrs, length); + } + + NamedNodeMap* attributes = token.attributes(); + if (!attributes) return; - token.setName(casedName); + + for (unsigned x = 0; x < attributes->length(); ++x) { + Attribute* attribute = attributes->attributeItem(x); + const QualifiedName& casedName = caseMap->get(attribute->localName()); + if (!casedName.localName().isNull()) + attribute->parserSetName(casedName); + } } #endif @@ -738,9 +741,43 @@ void adjustMathMLAttributes(AtomicHTMLToken&) } #endif -void adjustForeignAttributes(AtomicHTMLToken&) +void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, QualifiedName** names, size_t length) { - notImplemented(); + for (size_t i = 0; i < length; ++i) { + QualifiedName* name = names[i]; + const AtomicString& localName = name->localName(); + AtomicString prefixColonLocalName(prefix + ":" + localName); + QualifiedName nameWithPrefix(prefix, localName, name->namespaceURI()); + map->add(prefixColonLocalName, nameWithPrefix); + } +} + +void adjustForeignAttributes(AtomicHTMLToken& token) +{ + static PrefixedNameToQualifiedNameMap* map = 0; + if (!map) { + map = new PrefixedNameToQualifiedNameMap; + size_t length = 0; + QualifiedName** attrs = XLinkNames::getXLinkAttrs(&length); + addNamesWithPrefix(map, "xlink", attrs, length); + + attrs = XMLNames::getXMLAttrs(&length); + addNamesWithPrefix(map, "xml", attrs, length); + + map->add("xmlns", XMLNSNames::xmlnsAttr); + map->add("xmlns:xlink", QualifiedName("xmlns", "xlink", XMLNSNames::xmlnsNamespaceURI)); + } + + NamedNodeMap* attributes = token.attributes(); + if (!attributes) + return; + + for (unsigned x = 0; x < attributes->length(); ++x) { + Attribute* attribute = attributes->attributeItem(x); + const QualifiedName& name = map->get(attribute->localName()); + if (!name.localName().isNull()) + attribute->parserSetName(name); + } } }