Diff
Modified: trunk/LayoutTests/ChangeLog (147112 => 147113)
--- trunk/LayoutTests/ChangeLog 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/LayoutTests/ChangeLog 2013-03-28 14:34:21 UTC (rev 147113)
@@ -1,3 +1,13 @@
+2013-03-28 Hajime Morrita <morr...@google.com>
+
+ Custom Elements: should support non-HTML namespaces.
+ https://bugs.webkit.org/show_bug.cgi?id=111693
+
+ Reviewed by Dimitri Glazkov.
+
+ * fast/dom/custom/document-register-namespace-expected.txt: Added.
+ * fast/dom/custom/document-register-namespace.html: Added.
+
2013-03-28 Christophe Dumez <ch.du...@sisa.samsung.com>
Unreviewed EFL gardening.
Added: trunk/LayoutTests/fast/dom/custom/document-register-namespace-expected.txt (0 => 147113)
--- trunk/LayoutTests/fast/dom/custom/document-register-namespace-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/custom/document-register-namespace-expected.txt 2013-03-28 14:34:21 UTC (rev 147113)
@@ -0,0 +1,38 @@
+Using document.register() for extending HTML and non-HTML elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS html1.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS html2.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS html3.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS html4.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS notHTML.namespaceURI is 'http://www.example.com/'
+PASS notHTML instanceof CustomHTMLElement is false
+PASS notHTML instanceof HTMLElement is false
+PASS svg1.tagName is 'svg-foo'
+PASS svg1.namespaceURI is 'http://www.w3.org/2000/svg'
+PASS svg2.tagName is 'svg-foo'
+PASS svg2.namespaceURI is 'http://www.w3.org/2000/svg'
+PASS svg3.tagName is 'svg-foo'
+PASS svg3.namespaceURI is 'http://www.w3.org/2000/svg'
+PASS notSVG1.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS notSVG1 instanceof CustomSVGElement is false
+PASS notSVG1 instanceof HTMLUnknownElement is true
+PASS notSVG2.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS notSVG2 instanceof CustomSVGElement is false
+PASS notSVG2 instanceof HTMLUnknownElement is true
+PASS xml1.tagName is 'xml-foo'
+PASS xml1.namespaceURI is null
+PASS xml2.tagName is 'xml-foo'
+PASS xml2.namespaceURI is null
+PASS notXML1.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS notXML1 instanceof CustomXMLElement is false
+PASS notXML1 instanceof HTMLUnknownElement is true
+PASS notXML2.namespaceURI is 'http://www.w3.org/1999/xhtml'
+PASS notXML2 instanceof CustomXMLElement is false
+PASS notXML2 instanceof HTMLUnknownElement is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/custom/document-register-namespace.html (0 => 147113)
--- trunk/LayoutTests/fast/dom/custom/document-register-namespace.html (rev 0)
+++ trunk/LayoutTests/fast/dom/custom/document-register-namespace.html 2013-03-28 14:34:21 UTC (rev 147113)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description("Using document.register() for extending HTML and non-HTML elements.");
+
+document.register = document.register || document.webkitRegister;
+
+function createElementFromHTML(html)
+{
+ var container = document.createElement("div");
+ container.innerHTML = html;
+ return container.firstChild;
+}
+
+function createElementFromSVG(svg)
+{
+ var container = document.createElement("div");
+ container.innerHTML = "<svg xmlns='http://www.w3.org/2000/svg'>" + svg + "</svg>";
+ return container.firstChild.firstChild;
+}
+
+CustomHTMLElement = document.register('html-foo', { prototype: Object.create(HTMLElement.prototype) });
+CustomSVGElement = document.register('svg-foo', { prototype: Object.create(SVGElement.prototype) });
+CustomXMLElement = document.register('xml-foo', { prototype: Object.create(Element.prototype) });
+
+var html1 = new CustomHTMLElement();
+shouldBe("html1.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+var html2 = document.createElement("html-foo");
+shouldBe("html2.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+var html3 = document.createElementNS("http://www.w3.org/1999/xhtml", "html-foo");
+shouldBe("html3.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+var html4 = createElementFromHTML("<html-foo></html-foo>");
+shouldBe("html4.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+
+var notHTML = document.createElementNS("http://www.example.com/", "html-foo");
+shouldBe("notHTML.namespaceURI", "'http://www.example.com/'");
+shouldBeFalse("notHTML instanceof CustomHTMLElement");
+shouldBeFalse("notHTML instanceof HTMLElement");
+
+var svg1 = new CustomSVGElement();
+shouldBe("svg1.tagName", "'svg-foo'");
+shouldBe("svg1.namespaceURI", "'http://www.w3.org/2000/svg'");
+var svg2 = document.createElementNS("http://www.w3.org/2000/svg", "svg-foo");
+shouldBe("svg2.tagName", "'svg-foo'");
+shouldBe("svg2.namespaceURI", "'http://www.w3.org/2000/svg'");
+var svg3 = createElementFromSVG("<svg-foo></svg-foo>");
+shouldBe("svg3.tagName", "'svg-foo'");
+shouldBe("svg3.namespaceURI", "'http://www.w3.org/2000/svg'");
+
+var notSVG1 = document.createElement("svg-foo");
+shouldBe("notSVG1.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+shouldBeFalse("notSVG1 instanceof CustomSVGElement");
+shouldBeTrue("notSVG1 instanceof HTMLUnknownElement");
+var notSVG2 = createElementFromHTML("<svg-foo></svg-foo>");
+shouldBe("notSVG2.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+shouldBeFalse("notSVG2 instanceof CustomSVGElement");
+shouldBeTrue("notSVG2 instanceof HTMLUnknownElement");
+
+var xml1 = new CustomXMLElement();
+shouldBe("xml1.tagName", "'xml-foo'");
+shouldBe("xml1.namespaceURI", "null");
+var xml2 = document.createElementNS(null, "xml-foo");
+shouldBe("xml2.tagName", "'xml-foo'");
+shouldBe("xml2.namespaceURI", "null");
+
+var notXML1 = document.createElement("xml-foo");
+shouldBe("notXML1.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+shouldBeFalse("notXML1 instanceof CustomXMLElement");
+shouldBeTrue("notXML1 instanceof HTMLUnknownElement");
+var notXML2 = createElementFromHTML("<xml-foo></xml-foo>");
+shouldBe("notXML2.namespaceURI", "'http://www.w3.org/1999/xhtml'");
+shouldBeFalse("notXML2 instanceof CustomXMLElement");
+shouldBeTrue("notXML2 instanceof HTMLUnknownElement");
+
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (147112 => 147113)
--- trunk/Source/WebCore/ChangeLog 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/ChangeLog 2013-03-28 14:34:21 UTC (rev 147113)
@@ -1,3 +1,32 @@
+2013-03-28 Hajime Morrita <morr...@google.com>
+
+ Custom Elements: should support non-HTML namespaces.
+ https://bugs.webkit.org/show_bug.cgi?id=111693
+
+ Reviewed by Dimitri Glazkov.
+
+ 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):
+
2013-03-28 Hans Muller <hmul...@adobe.com>
[CSS Exclusions] Add support for the simple case of padding a polygonal shape-inside
Modified: trunk/Source/WebCore/bindings/v8/CustomElementHelpers.cpp (147112 => 147113)
--- trunk/Source/WebCore/bindings/v8/CustomElementHelpers.cpp 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/bindings/v8/CustomElementHelpers.cpp 2013-03-28 14:34:21 UTC (rev 147113)
@@ -33,12 +33,13 @@
#include "CustomElementRegistry.h"
#include "DOMWrapperWorld.h"
+#include "SVGNames.h"
#include "ScriptController.h"
#include "V8CustomElementConstructor.h"
#include "V8HTMLElementWrapperFactory.h"
-#include "V8HTMLParagraphElement.h"
-#include "V8HTMLSpanElement.h"
+#include "V8SVGElementWrapperFactory.h"
+
namespace WebCore {
#if ENABLE(CUSTOM_ELEMENTS)
@@ -98,10 +99,22 @@
return true;
}
-static bool hasValidPrototypeChain(v8::Handle<v8::Object> requiredAncestor, v8::Handle<v8::Value> chain)
+static bool hasValidPrototypeChainFor(v8::Handle<v8::Object> prototypeObject, WrapperTypeInfo* typeInfo, v8::Handle<v8::Context> context)
{
+ // document.register() sets the constructor property, so the prototype shouldn't have one.
+ if (prototypeObject->HasOwnProperty(v8String("constructor", context->GetIsolate())))
+ return false;
+
+ v8::Handle<v8::Object> elementConstructor = v8::Handle<v8::Object>::Cast(V8PerContextData::from(context)->constructorForType(typeInfo));
+ if (elementConstructor.IsEmpty())
+ return false;
+ v8::Handle<v8::Object> elementPrototype = v8::Handle<v8::Object>::Cast(elementConstructor->Get(v8String("prototype", context->GetIsolate())));
+ if (elementPrototype.IsEmpty())
+ return false;
+
+ v8::Handle<v8::Value> chain = prototypeObject;
while (!chain.IsEmpty() && chain->IsObject()) {
- if (chain == requiredAncestor)
+ if (chain == elementPrototype)
return true;
chain = v8::Handle<v8::Object>::Cast(chain)->GetPrototype();
}
@@ -109,26 +122,30 @@
return false;
}
-bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& prototype, ScriptState* state)
+bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& prototype, ScriptState* state, AtomicString& namespaceURI)
{
if (prototype.v8Value().IsEmpty() || !prototype.v8Value()->IsObject())
return false;
- // document.register() sets the constructor property, so the prototype shouldn't have one.
v8::Handle<v8::Object> prototypeObject = v8::Handle<v8::Object>::Cast(prototype.v8Value());
- if (prototypeObject->HasOwnProperty(v8String("constructor", state->context()->GetIsolate())))
- return false;
- V8PerContextData* perContextData = V8PerContextData::from(state->context());
- // FIXME: non-HTML subclasses should be also supported: https://bugs.webkit.org/show_bug.cgi?id=111693
- v8::Handle<v8::Object> htmlConstructor = v8::Handle<v8::Object>::Cast(perContextData->constructorForType(&V8HTMLElement::info));
- if (htmlConstructor.IsEmpty())
- return false;
- v8::Handle<v8::Object> htmlPrototype = v8::Handle<v8::Object>::Cast(htmlConstructor->Get(v8String("prototype", state->context()->GetIsolate())));
- if (htmlPrototype.IsEmpty())
- return false;
- if (!hasValidPrototypeChain(htmlPrototype, prototypeObject))
- return false;
- return true;
+ if (hasValidPrototypeChainFor(prototypeObject, &V8HTMLElement::info, state->context())) {
+ namespaceURI = HTMLNames::xhtmlNamespaceURI;
+ return true;
+ }
+
+#if ENABLE(SVG)
+ if (hasValidPrototypeChainFor(prototypeObject, &V8SVGElement::info, state->context())) {
+ namespaceURI = SVGNames::svgNamespaceURI;
+ return true;
+ }
+#endif
+
+ if (hasValidPrototypeChainFor(prototypeObject, &V8Element::info, state->context())) {
+ namespaceURI = nullAtom;
+ return true;
+ }
+
+ return false;
}
bool CustomElementHelpers::isFeatureAllowed(ScriptState* state)
@@ -169,7 +186,13 @@
WrapperTypeInfo* type = CustomElementHelpers::findWrapperType(chain);
if (!type)
return 0;
- return findHTMLTagNameOfV8Type(type);
+ if (const QualifiedName* htmlName = findHTMLTagNameOfV8Type(type))
+ return htmlName;
+#if ENABLE(SVG)
+ if (const QualifiedName* svgName = findSVGTagNameOfV8Type(type))
+ return svgName;
+#endif
+ return 0;
}
void CustomElementHelpers::invokeReadyCallbackIfNeeded(Element* element, v8::Handle<v8::Context> context)
Modified: trunk/Source/WebCore/bindings/v8/CustomElementHelpers.h (147112 => 147113)
--- trunk/Source/WebCore/bindings/v8/CustomElementHelpers.h 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/bindings/v8/CustomElementHelpers.h 2013-03-28 14:34:21 UTC (rev 147113)
@@ -56,6 +56,7 @@
class CustomElementHelpers {
public:
static bool initializeConstructorWrapper(CustomElementConstructor*, const ScriptValue& prototype, ScriptState*);
+ static bool isValidPrototypeParameter(const ScriptValue&, ScriptState*, AtomicString& namespaceURI);
static bool isValidPrototypeParameter(const ScriptValue&, ScriptState*);
static bool isFeatureAllowed(ScriptState*);
static const QualifiedName* findLocalName(const ScriptValue& prototype);
@@ -93,6 +94,12 @@
return 0;
}
+inline bool CustomElementHelpers::isValidPrototypeParameter(const ScriptValue& value, ScriptState* state)
+{
+ AtomicString namespaceURI;
+ return isValidPrototypeParameter(value, state, namespaceURI);
+}
+
#endif // ENABLE(CUSTOM_ELEMENTS)
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/CustomElementConstructor.cpp (147112 => 147113)
--- trunk/Source/WebCore/dom/CustomElementConstructor.cpp 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/dom/CustomElementConstructor.cpp 2013-03-28 14:34:21 UTC (rev 147113)
@@ -38,6 +38,8 @@
#include "Document.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
+#include "SVGElement.h"
+#include "SVGNames.h"
#include <wtf/Assertions.h>
namespace WebCore {
@@ -77,7 +79,13 @@
return 0;
if (m_localName != m_typeName)
return setTypeExtension(document()->createElement(m_localName, document()), m_typeName.localName());
- return HTMLElement::create(m_typeName, document());
+ if (HTMLNames::xhtmlNamespaceURI == m_typeName.namespaceURI())
+ return HTMLElement::create(m_typeName, document());
+#if ENABLE(SVG)
+ if (SVGNames::svgNamespaceURI == m_typeName.namespaceURI())
+ return SVGElement::create(m_typeName, document());
+#endif
+ return Element::create(m_typeName, document());
}
PassRefPtr<Element> setTypeExtension(PassRefPtr<Element> element, const AtomicString& typeExtension)
Modified: trunk/Source/WebCore/dom/CustomElementRegistry.cpp (147112 => 147113)
--- trunk/Source/WebCore/dom/CustomElementRegistry.cpp 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/dom/CustomElementRegistry.cpp 2013-03-28 14:34:21 UTC (rev 147113)
@@ -115,8 +115,8 @@
if (!CustomElementHelpers::isFeatureAllowed(state))
return 0;
- QualifiedName newName(nullAtom, name.lower(), HTMLNames::xhtmlNamespaceURI);
- if (!isValidName(newName.localName())) {
+ AtomicString lowerName = name.lower();
+ if (!isValidName(lowerName)) {
ec = INVALID_CHARACTER_ERR;
return 0;
}
@@ -132,19 +132,21 @@
return 0;
}
- if (!CustomElementHelpers::isValidPrototypeParameter(prototypeValue, state)) {
+ AtomicString namespaceURI;
+ if (!CustomElementHelpers::isValidPrototypeParameter(prototypeValue, state, namespaceURI)) {
ec = INVALID_STATE_ERR;
return 0;
}
- if (m_names.contains(newName)) {
+ if (m_names.contains(lowerName)) {
ec = INVALID_STATE_ERR;
return 0;
}
const QualifiedName* localNameFound = CustomElementHelpers::findLocalName(prototypeValue);
- QualifiedName localNameToUse = localNameFound ? *localNameFound : newName;
- if (find(newName, localNameToUse)) {
+ QualifiedName typeName(nullAtom, lowerName, namespaceURI);
+ QualifiedName localNameToUse = localNameFound ? *localNameFound : typeName;
+ if (find(typeName, localNameToUse)) {
ec = INVALID_STATE_ERR;
return 0;
}
@@ -155,14 +157,14 @@
return 0;
}
- RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), newName, localNameToUse, prototypeValue);
+ RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(state, document(), typeName, localNameToUse, prototypeValue);
if (!constructor) {
ec = INVALID_STATE_ERR;
return 0;
}
m_constructors.add(std::make_pair(constructor->typeName(), constructor->localName()), constructor);
- m_names.add(constructor->typeName());
+ m_names.add(lowerName);
return constructor;
}
Modified: trunk/Source/WebCore/dom/CustomElementRegistry.h (147112 => 147113)
--- trunk/Source/WebCore/dom/CustomElementRegistry.h 2013-03-28 14:28:32 UTC (rev 147112)
+++ trunk/Source/WebCore/dom/CustomElementRegistry.h 2013-03-28 14:34:21 UTC (rev 147113)
@@ -38,13 +38,13 @@
#include "QualifiedName.h"
#include "ScriptValue.h"
#include "Supplementable.h"
-#include <wtf/Forward.h>
#include <wtf/HashSet.h>
#include <wtf/ListHashSet.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
@@ -93,7 +93,7 @@
private:
typedef HashMap<std::pair<QualifiedName, QualifiedName>, RefPtr<CustomElementConstructor> > ConstructorMap;
- typedef HashSet<QualifiedName> NameSet;
+ typedef HashSet<AtomicString> NameSet;
typedef ListHashSet<CustomElementRegistry*> InstanceSet;
static bool isValidName(const AtomicString&);