Changeset 147113 in webkit


Ignore:
Timestamp:
Mar 28, 2013 7:34:21 AM (11 years ago)
Author:
morrita@google.com
Message:

Custom Elements: should support non-HTML namespaces.
https://bugs.webkit.org/show_bug.cgi?id=111693

Reviewed by Dimitri Glazkov.

Source/WebCore:

Some existing code assumes that the element extends HTMLElements.
This change allow it to extend from Element. Note that the
namespace URI of a custom element is determined by given element
prototype: An element will have XHTML namespace if its prototype
chain includes HTMLElements, SVGElement leads SVG namespace and
null otherwise, respectively.

Test: fast/dom/custom/document-register-namespace.html

  • bindings/v8/CustomElementHelpers.cpp:

(WebCore::hasValidPrototypeChainFor): Factored out from isValidPrototypeParameter()
(WebCore::CustomElementHelpers::isValidPrototypeParameter): Extend to support non HTMLElement prototype
(WebCore::CustomElementHelpers::findLocalName): Support non-HTML element names.

  • bindings/v8/CustomElementHelpers.h:

(CustomElementHelpers):

  • dom/CustomElementConstructor.cpp:

(WebCore::CustomElementConstructor::createElementInternal):

  • dom/CustomElementRegistry.cpp:

(WebCore::CustomElementRegistry::registerElement): No longer hard-codes namespace and picks one based on the prototype value.

  • dom/CustomElementRegistry.h:

(CustomElementRegistry):

LayoutTests:

  • fast/dom/custom/document-register-namespace-expected.txt: Added.
  • fast/dom/custom/document-register-namespace.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r147112 r147113  
     12013-03-28  Hajime Morrita  <morrita@google.com>
     2
     3        Custom Elements: should support non-HTML namespaces.
     4        https://bugs.webkit.org/show_bug.cgi?id=111693
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        * fast/dom/custom/document-register-namespace-expected.txt: Added.
     9        * fast/dom/custom/document-register-namespace.html: Added.
     10
    1112013-03-28  Christophe Dumez  <ch.dumez@sisa.samsung.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r147111 r147113  
     12013-03-28  Hajime Morrita  <morrita@google.com>
     2
     3        Custom Elements: should support non-HTML namespaces.
     4        https://bugs.webkit.org/show_bug.cgi?id=111693
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        Some existing code assumes that the element extends HTMLElements.
     9        This change allow it to extend from Element. Note that the
     10        namespace URI of a custom element is determined by given element
     11        prototype: An element will have XHTML namespace if its prototype
     12        chain includes HTMLElements, SVGElement leads SVG namespace and
     13        null otherwise, respectively.
     14
     15        Test: fast/dom/custom/document-register-namespace.html
     16
     17        * bindings/v8/CustomElementHelpers.cpp:
     18        (WebCore::hasValidPrototypeChainFor): Factored out from isValidPrototypeParameter()
     19        (WebCore::CustomElementHelpers::isValidPrototypeParameter): Extend to support non HTMLElement prototype
     20        (WebCore::CustomElementHelpers::findLocalName): Support non-HTML element names.
     21        * bindings/v8/CustomElementHelpers.h:
     22        (CustomElementHelpers):
     23        * dom/CustomElementConstructor.cpp:
     24        (WebCore::CustomElementConstructor::createElementInternal):
     25        * dom/CustomElementRegistry.cpp:
     26        (WebCore::CustomElementRegistry::registerElement): No longer hard-codes namespace and picks one based on the prototype value.
     27        * dom/CustomElementRegistry.h:
     28        (CustomElementRegistry):
     29
    1302013-03-28  Hans Muller  <hmuller@adobe.com>
    231
  • trunk/Source/WebCore/bindings/v8/CustomElementHelpers.cpp

    r146851 r147113  
    3434#include "CustomElementRegistry.h"
    3535#include "DOMWrapperWorld.h"
     36#include "SVGNames.h"
    3637#include "ScriptController.h"
    3738#include "V8CustomElementConstructor.h"
    3839#include "V8HTMLElementWrapperFactory.h"
    39 #include "V8HTMLParagraphElement.h"
    40 #include "V8HTMLSpanElement.h"
     40#include "V8SVGElementWrapperFactory.h"
     41
    4142
    4243namespace WebCore {
     
    99100}
    100101
    101 static bool hasValidPrototypeChain(v8::Handle<v8::Object> requiredAncestor, v8::Handle<v8::Value> chain)
    102 {
     102static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, WrapperTypeInfo* typeInfo, v8::Handle<v8::Context> context)
     103{
     104    // document.register() sets the constructor property, so the prototype shouldn't have one.
     105    if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsolate())))
     106        return false;
     107
     108    v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8PerContextData::from(context)->constructorForType(typeInfo));
     109    if (elementConstructor.IsEmpty())
     110        return false;
     111    v8::Handle<v8::Object> elementPrototype = v8::Handle<v8::Object>::Cast(elementConstructor->Get(v8String("prototype", context->GetIsolate())));
     112    if (elementPrototype.IsEmpty())
     113        return false;
     114
     115    v8::Handle<v8::Value> chain = prototypeObject;
    103116    while (!chain.IsEmpty() && chain->IsObject()) {
    104         if (chain == requiredAncestor)
     117        if (chain == elementPrototype)
    105118            return true;
    106119        chain = v8::Handle<v8::Object>::Cast(chain)->GetPrototype();
     
    110123}
    111124
    112 bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& prototype, ScriptState* state)
     125bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& prototype, ScriptState* state, AtomicString& namespaceURI)
    113126{
    114127    if (prototype.v8Value().IsEmpty() || !prototype.v8Value()->IsObject())
    115128        return false;
    116129
    117     // document.register() sets the constructor property, so the prototype shouldn't have one.
    118130    v8::Handle<v8::Object> prototypeObject = v8::Handle<v8::Object>::Cast(prototype.v8Value());
    119     if (prototypeObject->HasOwnProperty(v8String("constructor", state->context()->GetIsolate())))
    120         return false;
    121     V8PerContextData* perContextData = V8PerContextData::from(state->context());
    122     // FIXME: non-HTML subclasses should be also supported: https://bugs.webkit.org/show_bug.cgi?id=111693
    123     v8::Handle<v8::Object> htmlConstructor = v8::Handle<v8::Object>::Cast(perContextData->constructorForType(&V8HTMLElement::info));
    124     if (htmlConstructor.IsEmpty())
    125         return false;
    126     v8::Handle<v8::Object> htmlPrototype = v8::Handle<v8::Object>::Cast(htmlConstructor->Get(v8String("prototype", state->context()->GetIsolate())));
    127     if (htmlPrototype.IsEmpty())
    128         return false;
    129     if (!hasValidPrototypeChain(htmlPrototype, prototypeObject))
    130         return false;
    131     return true;
     131    if (hasValidPrototypeChainFor(prototypeObject, &V8HTMLElement::info, state->context())) {
     132        namespaceURI = HTMLNames::xhtmlNamespaceURI;
     133        return true;
     134    }
     135
     136#if ENABLE(SVG)
     137    if (hasValidPrototypeChainFor(prototypeObject, &V8SVGElement::info, state->context())) {
     138        namespaceURI = SVGNames::svgNamespaceURI;
     139        return true;
     140    }
     141#endif
     142
     143    if (hasValidPrototypeChainFor(prototypeObject, &V8Element::info, state->context())) {
     144        namespaceURI = nullAtom;
     145        return true;
     146    }
     147
     148    return false;
    132149}
    133150
     
    170187    if (!type)
    171188        return 0;
    172     return findHTMLTagNameOfV8Type(type);
     189    if (const QualifiedName* htmlName = findHTMLTagNameOfV8Type(type))
     190        return htmlName;
     191#if ENABLE(SVG)
     192    if (const QualifiedName* svgName = findSVGTagNameOfV8Type(type))
     193        return svgName;
     194#endif
     195    return 0;
    173196}
    174197
  • trunk/Source/WebCore/bindings/v8/CustomElementHelpers.h

    r146851 r147113  
    5757public:
    5858    static bool initializeConstructorWrapper(CustomElementConstructor*, const ScriptValue& prototype, ScriptState*);
     59    static bool isValidPrototypeParameter(const ScriptValue&, ScriptState*, AtomicString& namespaceURI);
    5960    static bool isValidPrototypeParameter(const ScriptValue&, ScriptState*);
    6061    static bool isFeatureAllowed(ScriptState*);
     
    9495}
    9596
     97inline bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& value, ScriptState* state)
     98{
     99    AtomicString namespaceURI;
     100    return isValidPrototypeParameter(value, state, namespaceURI);
     101}
     102
    96103#endif // ENABLE(CUSTOM_ELEMENTS)
    97104
  • trunk/Source/WebCore/dom/CustomElementConstructor.cpp

    r146583 r147113  
    3939#include "HTMLElement.h"
    4040#include "HTMLNames.h"
     41#include "SVGElement.h"
     42#include "SVGNames.h"
    4143#include <wtf/Assertions.h>
    4244
     
    7880    if (m_localName != m_typeName)
    7981        return setTypeExtension(document()->createElement(m_localName, document()), m_typeName.localName());
    80     return HTMLElement::create(m_typeName, document());
     82    if (HTMLNames::xhtmlNamespaceURI == m_typeName.namespaceURI())
     83        return HTMLElement::create(m_typeName, document());
     84#if ENABLE(SVG)
     85    if (SVGNames::svgNamespaceURI == m_typeName.namespaceURI())
     86        return SVGElement::create(m_typeName, document());
     87#endif
     88    return Element::create(m_typeName, document());
    8189}
    8290
  • trunk/Source/WebCore/dom/CustomElementRegistry.cpp

    r146583 r147113  
    116116        return 0;
    117117
    118     QualifiedName newName(nullAtom, name.lower(), HTMLNames::xhtmlNamespaceURI);
    119     if (!isValidName(newName.localName())) {
     118    AtomicString lowerName = name.lower();
     119    if (!isValidName(lowerName)) {
    120120        ec = INVALID_CHARACTER_ERR;
    121121        return 0;
     
    133133    }
    134134
    135     if (!CustomElementHelpers::isValidPrototypeParameter(prototypeValue, state)) {
    136         ec = INVALID_STATE_ERR;
    137         return 0;
    138     }
    139 
    140     if (m_names.contains(newName)) {
     135    AtomicString namespaceURI;
     136    if (!CustomElementHelpers::isValidPrototypeParameter(prototypeValue, state, namespaceURI)) {
     137        ec = INVALID_STATE_ERR;
     138        return 0;
     139    }
     140
     141    if (m_names.contains(lowerName)) {
    141142        ec = INVALID_STATE_ERR;
    142143        return 0;
     
    144145
    145146    const QualifiedName* localNameFound = CustomElementHelpers::findLocalName(prototypeValue);
    146     QualifiedName localNameToUse = localNameFound ? *localNameFound : newName;
    147     if (find(newName, localNameToUse)) {
     147    QualifiedName typeName(nullAtom, lowerName, namespaceURI);
     148    QualifiedName localNameToUse = localNameFound ? *localNameFound : typeName;
     149    if (find(typeName, localNameToUse)) {
    148150        ec = INVALID_STATE_ERR;
    149151        return 0;
     
    156158    }
    157159
    158     RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), newName, localNameToUse, prototypeValue);
     160    RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), typeName, localNameToUse, prototypeValue);
    159161    if (!constructor) {
    160162        ec = INVALID_STATE_ERR;
     
    163165       
    164166    m_constructors.add(std::make_pair(constructor->typeName(), constructor->localName()), constructor);
    165     m_names.add(constructor->typeName());
     167    m_names.add(lowerName);
    166168
    167169    return constructor;
  • trunk/Source/WebCore/dom/CustomElementRegistry.h

    r146583 r147113  
    3939#include "ScriptValue.h"
    4040#include "Supplementable.h"
    41 #include <wtf/Forward.h>
    4241#include <wtf/HashSet.h>
    4342#include <wtf/ListHashSet.h>
     
    4645#include <wtf/RefPtr.h>
    4746#include <wtf/Vector.h>
     47#include <wtf/text/AtomicStringHash.h>
    4848
    4949namespace WebCore {
     
    9494private:
    9595    typedef HashMap<std::pair<QualifiedName, QualifiedName>, RefPtr<CustomElementConstructor> > ConstructorMap;
    96     typedef HashSet<QualifiedName> NameSet;
     96    typedef HashSet<AtomicString> NameSet;
    9797    typedef ListHashSet<CustomElementRegistry*> InstanceSet;
    9898
Note: See TracChangeset for help on using the changeset viewer.