Diff
Modified: trunk/LayoutTests/ChangeLog (197916 => 197917)
--- trunk/LayoutTests/ChangeLog 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/LayoutTests/ChangeLog 2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,3 +1,16 @@
+2016-03-09 Ryosuke Niwa <[email protected]>
+
+ defineElement should upgrade existing unresolved custom elements
+ https://bugs.webkit.org/show_bug.cgi?id=155107
+
+ Reviewed by Darin Adler.
+
+ Added W3C style testharness.js tests for asynchronously defining custom elements.
+
+ * fast/custom-elements/upgrading/Node-cloneNode.html:
+ * fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt: Added.
+ * fast/custom-elements/upgrading/upgrading-parser-created-element.html: Added.
+
2016-03-09 Saam Barati <[email protected]>
ES6: Implement lexical scoping for function definitions in strict mode
Modified: trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html (197916 => 197917)
--- trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/Node-cloneNode.html 2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
-<title>Custom Elements: Extensions to Document interface</title>
+<title>Custom Elements: Upgrading</title>
<meta name="author" title="Ryosuke Niwa" href=""
<meta name="assert" content="Node.prototype.cloneNode should upgrade a custom element">
<link rel="help" href=""
Added: trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt (0 => 197917)
--- trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element-expected.txt 2016-03-10 02:33:12 UTC (rev 197917)
@@ -0,0 +1,6 @@
+
+PASS Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map
+PASS HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself after super() call
+PASS HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed due to a custom element constructor constructing itself before super() call
+PASS Upgrading a custom element must throw an InvalidStateError when the returned element is not SameValue as the upgraded element
+
Added: trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html (0 => 197917)
--- trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/upgrading/upgrading-parser-created-element.html 2016-03-10 02:33:12 UTC (rev 197917)
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom Elements: Upgrading unresolved elements</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="HTML parser must add an unresolved custom element to the upgrade candidates map">
+<link rel="help" href=""
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<my-custom-element></my-custom-element>
+<instantiates-itself-after-super></instantiates-itself-after-super>
+<instantiates-itself-before-super></instantiates-itself-before-super>
+<my-other-element id="instance"></my-other-element>
+<my-other-element id="otherInstance"></my-other-element>
+<script>
+
+test(function () {
+ class MyCustomElement extends HTMLElement { }
+
+ var instance = document.querySelector('my-custom-element');
+ assert_true(instance instanceof HTMLElement);
+ assert_false(instance instanceof HTMLUnknownElement,
+ 'an unresolved custom element should not be an instance of HTMLUnknownElement');
+ assert_false(instance instanceof MyCustomElement);
+
+ document.defineElement('my-custom-element', MyCustomElement);
+
+ assert_true(instance instanceof HTMLElement);
+ assert_true(instance instanceof MyCustomElement,
+ 'Calling defineElement must upgrade existing custom elements');
+
+}, 'Element.prototype.createElement must add an unresolved custom element to the upgrade candidates map');
+
+
+test(function () {
+ class InstantiatesItselfAfterSuper extends HTMLElement {
+ constructor(doNotCreateItself) {
+ super();
+ if (!doNotCreateItself)
+ new InstantiatesItselfAfterSuper(true);
+ }
+ }
+
+ assert_throws({'name': 'InvalidStateError'}, function () {
+ document.defineElement('instantiates-itself-after-super', InstantiatesItselfAfterSuper);
+ });
+}, 'HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed'
+ + ' due to a custom element constructor constructing itself after super() call');
+
+test(function () {
+ class InstantiatesItselfBeforeSuper extends HTMLElement {
+ constructor(doNotCreateItself) {
+ if (!doNotCreateItself)
+ new InstantiatesItselfBeforeSuper(true);
+ super();
+ }
+ }
+
+ assert_throws({'name': 'InvalidStateError'}, function () {
+ document.defineElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
+ });
+}, 'HTMLElement constructor must throw an InvalidStateError when the top of the construction stack is marked AlreadyConstructed'
+ + ' due to a custom element constructor constructing itself before super() call');
+
+test(function () {
+ class MyOtherElement extends HTMLElement {
+ constructor() {
+ super();
+ if (this == instance)
+ return otherInstance;
+ }
+ }
+ var instance = document.getElementById('instance');
+ var otherInstance = document.getElementById('otherInstance');
+
+ assert_false(instance instanceof MyOtherElement);
+ assert_false(otherInstance instanceof MyOtherElement);
+
+ assert_throws({'name': 'InvalidStateError'}, function () {
+ document.defineElement('my-other-element', MyOtherElement);
+ });
+
+ assert_true(document.createElement('my-other-element') instanceof MyOtherElement,
+ 'Upgrading of custom elements must happen after the definition was added to the registry.');
+}, 'Upgrading a custom element must throw an InvalidStateError when the returned element is not SameValue as the upgraded element');
+
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (197916 => 197917)
--- trunk/Source/WebCore/ChangeLog 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/ChangeLog 2016-03-10 02:33:12 UTC (rev 197917)
@@ -1,3 +1,60 @@
+2016-03-09 Ryosuke Niwa <[email protected]>
+
+ defineElement should upgrade existing unresolved custom elements
+ https://bugs.webkit.org/show_bug.cgi?id=155107
+
+ Reviewed by Darin Adler.
+
+ Added the support for upgrading existing unresolved custom elements when defineElement is called.
+
+ The current implementation upgrades elements in the order they were created and has the issue that
+ it keeps accumulating all elements with a hyphen in its name until defineElement is called as
+ documented in https://github.com/w3c/webcomponents/issues/419
+
+ This patch re-purposes IsEditingTextFlag to indicate that the node is an unresolved custom element.
+ Since isEditingText() is only called in textRendererIsNeeded only on Text nodes, it's mutually
+ exclusive with isUnresolvedCustomElement().
+
+ The list of unresolved custom elements is kept in m_upgradeCandidatesMap, a hash map of element names
+ to the list of unresolved elements with that name.
+
+ In addition, added the logic to use HTMLElement as the interface for unresolved custom element instead
+ of HTMLUnknownElement.
+
+ Test: fast/custom-elements/upgrading/upgrading-parser-created-element.html
+
+ * bindings/js/JSCustomElementInterface.cpp:
+ (WebCore::JSCustomElementInterface::upgradeElement): Clear the flag.
+ * bindings/js/JSDocumentCustom.cpp:
+ (WebCore::JSDocument::defineElement): Set the unique private name to keep the interface alive before
+ calling addElementDefinition as the call can now invoke author scripts.
+ * dom/CustomElementDefinitions.cpp:
+ (WebCore::CustomElementDefinitions::addElementDefinition): Upgrade existing unresolved elements kept
+ in m_upgradeCandidatesMap.
+ (WebCore::CustomElementDefinitions::addUpgradeCandidate): Added.
+ * dom/CustomElementDefinitions.h:
+ * dom/Document.cpp:
+ (WebCore::createHTMLElementWithNameValidation): Added the code to add the unresolved custom elements
+ to the upgrade candidates map. Also instantiate it as HTMLElement instead of HTMLUnknownElement.
+ (WebCore::createFallbackHTMLElement): Ditto.
+ * dom/Node.h:
+ (WebCore::Node::setIsCustomElement):
+ (WebCore::Node::isUnresolvedCustomElement): Added.
+ (WebCore::Node::setIsUnresolvedCustomElement): Added.
+ (WebCore::Node::setCustomElementIsResolved): Added. Clears IsEditingTextOrUnresolvedCustomElementFlag
+ and sets IsCustomElement.
+ (WebCore::Node::isEditingText): Check both IsEditingTextOrUnresolvedCustomElementFlag and IsTextFlag
+ for safety even though it's currently only used in textRendererIsNeeded which takes Text&.
+ * dom/make_names.pl:
+ (defaultParametersHash): Added customElementInterfaceName as a parameter.
+ (printWrapperFactoryCppFile): Generate the code to use customElementInterfaceName when the element
+ for which the wrapper is created has isUnresolvedCustomElement flag set.
+ * html/HTMLTagNames.in: Use HTMLElement for unresolved custom elements.
+ * html/parser/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::createHTMLElementOrFindCustomElementInterface): Added the code to add
+ the unresolved custom elements to the upgrade candidates map. Also instantiate it as HTMLElement instead
+ of HTMLUnknownElement.
+
2016-03-09 Enrica Casucci <[email protected]>
Retrieve additional context for some data detector link for preview and action menu.
Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (197916 => 197917)
--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp 2016-03-10 02:33:12 UTC (rev 197917)
@@ -104,7 +104,7 @@
void JSCustomElementInterface::upgradeElement(Element& element)
{
- ASSERT(element.isCustomElement());
+ ASSERT(element.isUnresolvedCustomElement());
if (!canInvokeCallback())
return;
@@ -147,6 +147,7 @@
throwInvalidStateError(*state, "Custom element constructor failed to upgrade an element");
return;
}
+ wrappedElement->setCustomElementIsResolved();
ASSERT(wrappedElement->isCustomElement());
}
Modified: trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp (197916 => 197917)
--- trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp 2016-03-10 02:33:12 UTC (rev 197917)
@@ -180,11 +180,12 @@
// FIXME: 13. Let detachedCallback be Get(prototype, "detachedCallback"). Rethrow any exceptions.
// FIXME: 14. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
- QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
- definitions.addElementDefinition(JSCustomElementInterface::create(name, object, globalObject()));
PrivateName uniquePrivateName;
globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object);
+ QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
+ definitions.addElementDefinition(JSCustomElementInterface::create(name, object, globalObject()));
+
// FIXME: 17. Let map be registry's upgrade candidates map.
// FIXME: 18. Upgrade a newly-defined element given map and definition.
Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.cpp (197916 => 197917)
--- trunk/Source/WebCore/dom/CustomElementDefinitions.cpp 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.cpp 2016-03-10 02:33:12 UTC (rev 197917)
@@ -74,9 +74,35 @@
AtomicString localName = interface->name().localName();
ASSERT(!m_nameMap.contains(localName));
m_constructorMap.add(interface->constructor(), interface.ptr());
- m_nameMap.add(localName, WTFMove(interface));
+ m_nameMap.add(localName, interface.copyRef());
+
+ auto candidateList = m_upgradeCandidatesMap.find(localName);
+ if (candidateList == m_upgradeCandidatesMap.end())
+ return;
+
+ Vector<RefPtr<Element>> list(WTFMove(candidateList->value));
+
+ m_upgradeCandidatesMap.remove(localName);
+
+ for (auto& candidate : list) {
+ ASSERT(candidate);
+ interface->upgradeElement(*candidate);
+ }
+
+ // We should not be adding more upgrade candidate for this local name.
+ ASSERT(!m_upgradeCandidatesMap.contains(localName));
}
+void CustomElementDefinitions::addUpgradeCandidate(Element& candidate)
+{
+ auto result = m_upgradeCandidatesMap.ensure(candidate.localName(), [] {
+ return Vector<RefPtr<Element>>();
+ });
+ auto& nodeVector = result.iterator->value;
+ ASSERT(!nodeVector.contains(&candidate));
+ nodeVector.append(&candidate);
+}
+
JSCustomElementInterface* CustomElementDefinitions::findInterface(const QualifiedName& name) const
{
auto it = m_nameMap.find(name.localName());
Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.h (197916 => 197917)
--- trunk/Source/WebCore/dom/CustomElementDefinitions.h 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.h 2016-03-10 02:33:12 UTC (rev 197917)
@@ -49,6 +49,7 @@
WTF_MAKE_FAST_ALLOCATED;
public:
void addElementDefinition(Ref<JSCustomElementInterface>&&);
+ void addUpgradeCandidate(Element&);
JSCustomElementInterface* findInterface(const QualifiedName&) const;
JSCustomElementInterface* findInterface(const AtomicString&) const;
@@ -59,6 +60,7 @@
static NameStatus checkName(const AtomicString& tagName);
private:
+ HashMap<AtomicString, Vector<RefPtr<Element>>> m_upgradeCandidatesMap;
HashMap<AtomicString, RefPtr<JSCustomElementInterface>> m_nameMap;
HashMap<const JSC::JSObject*, JSCustomElementInterface*> m_constructorMap;
};
Modified: trunk/Source/WebCore/dom/Document.cpp (197916 => 197917)
--- trunk/Source/WebCore/dom/Document.cpp 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/Document.cpp 2016-03-10 02:33:12 UTC (rev 197917)
@@ -899,7 +899,18 @@
return nullptr;
}
- return HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), document);
+ QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI);
+
+#if ENABLE(CUSTOM_ELEMENTS)
+ if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) {
+ Ref<HTMLElement> element = HTMLElement::create(qualifiedName, document);
+ element->setIsUnresolvedCustomElement();
+ document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get());
+ return WTFMove(element);
+ }
+#endif
+
+ return HTMLUnknownElement::create(qualifiedName, document);
}
RefPtr<Element> Document::createElementForBindings(const AtomicString& name, ExceptionCode& ec)
@@ -1080,11 +1091,18 @@
if (UNLIKELY(definitions)) {
if (auto* interface = definitions->findInterface(name)) {
Ref<HTMLElement> element = HTMLElement::create(name, document);
- element->setIsCustomElement(); // Pre-upgrade element is still considered a custom element.
+ element->setIsUnresolvedCustomElement();
LifecycleCallbackQueue::enqueueElementUpgrade(element.get(), *interface);
return element;
}
}
+ // FIXME: Should we also check the equality of prefix between the custom element and name?
+ if (CustomElementDefinitions::checkName(name.localName()) == CustomElementDefinitions::NameStatus::Valid) {
+ Ref<HTMLElement> element = HTMLElement::create(name, document);
+ element->setIsUnresolvedCustomElement();
+ document.ensureCustomElementDefinitions().addUpgradeCandidate(element.get());
+ return element;
+ }
#endif
return HTMLUnknownElement::create(name, document);
}
Modified: trunk/Source/WebCore/dom/Node.h (197916 => 197917)
--- trunk/Source/WebCore/dom/Node.h 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/Node.h 2016-03-10 02:33:12 UTC (rev 197917)
@@ -266,7 +266,11 @@
#if ENABLE(CUSTOM_ELEMENTS)
bool isCustomElement() const { return getFlag(IsCustomElement); }
- void setIsCustomElement() { return setFlag(IsCustomElement); }
+ void setIsCustomElement() { setFlag(IsCustomElement); }
+
+ bool isUnresolvedCustomElement() const { return isElementNode() && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
+ void setIsUnresolvedCustomElement() { setFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
+ void setCustomElementIsResolved();
#endif
// Returns null, a child of ShadowRoot, or a legacy shadow root.
@@ -320,7 +324,7 @@
StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
bool styleIsAffectedByPreviousSibling() const { return getFlag(StyleIsAffectedByPreviousSibling); }
- bool isEditingText() const { return getFlag(IsEditingTextFlag); }
+ bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
void clearChildNeedsStyleRecalc() { m_nodeFlags &= ~(ChildNeedsStyleRecalcFlag | DirectChildNeedsStyleRecalcFlag); }
@@ -595,7 +599,7 @@
IsParsingChildrenFinishedFlag = 1 << 13, // Element
StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1) | 1 << (nodeStyleChangeShift + 2),
- IsEditingTextFlag = 1 << 17,
+ IsEditingTextOrUnresolvedCustomElementFlag = 1 << 17,
IsNamedFlowContentNodeFlag = 1 << 18,
HasSyntheticAttrChildNodesFlag = 1 << 19,
HasCustomStyleResolveCallbacksFlag = 1 << 20,
@@ -634,7 +638,7 @@
CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
CreateSVGElement = CreateStyledElement | IsSVGFlag | HasCustomStyleResolveCallbacksFlag,
CreateDocument = CreateContainer | InDocumentFlag,
- CreateEditingText = CreateText | IsEditingTextFlag,
+ CreateEditingText = CreateText | IsEditingTextOrUnresolvedCustomElementFlag,
CreateMathMLElement = CreateStyledElement | IsMathMLFlag
};
Node(Document&, ConstructionType);
@@ -769,6 +773,16 @@
return parentNode();
}
+#if ENABLE(CUSTOM_ELEMENTS)
+
+inline void Node::setCustomElementIsResolved()
+{
+ clearFlag(IsEditingTextOrUnresolvedCustomElementFlag);
+ setFlag(IsCustomElement);
+}
+
+#endif
+
} // namespace WebCore
#if ENABLE(TREE_DEBUGGING)
Modified: trunk/Source/WebCore/dom/make_names.pl (197916 => 197917)
--- trunk/Source/WebCore/dom/make_names.pl 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/dom/make_names.pl 2016-03-10 02:33:12 UTC (rev 197917)
@@ -216,6 +216,7 @@
'attrsNullNamespace' => 0,
'fallbackInterfaceName' => '',
'fallbackJSInterfaceName' => '',
+ 'customElementInterfaceName' => '',
);
}
@@ -1318,6 +1319,20 @@
populate$parameters{namespace}WrapperMap(functions);
if (auto function = functions.get().get(element->localName().impl()))
return function(globalObject, element);
+END
+;
+
+ if ($parameters{customElementInterfaceName}) {
+ print F <<END
+#if ENABLE(CUSTOM_ELEMENTS)
+ if (element->isUnresolvedCustomElement())
+ return CREATE_DOM_WRAPPER(globalObject, $parameters{customElementInterfaceName}, element.get());
+#endif
+END
+;
+ }
+
+ print F <<END
return CREATE_DOM_WRAPPER(globalObject, $parameters{fallbackJSInterfaceName}, element.get());
}
Modified: trunk/Source/WebCore/html/HTMLTagNames.in (197916 => 197917)
--- trunk/Source/WebCore/html/HTMLTagNames.in 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/html/HTMLTagNames.in 2016-03-10 02:33:12 UTC (rev 197917)
@@ -2,6 +2,7 @@
namespacePrefix="xhtml"
namespaceURI="http://www.w3.org/1999/xhtml"
fallbackInterfaceName="HTMLUnknownElement"
+customElementInterfaceName="HTMLElement"
a interfaceName=HTMLAnchorElement
abbr interfaceName=HTMLElement
Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp (197916 => 197917)
--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp 2016-03-10 02:05:49 UTC (rev 197916)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp 2016-03-10 02:33:12 UTC (rev 197917)
@@ -672,20 +672,29 @@
bool insideTemplateElement = !ownerDocument.frame();
RefPtr<Element> element = HTMLElementFactory::createKnownElement(localName, ownerDocument, insideTemplateElement ? nullptr : form(), true);
if (UNLIKELY(!element)) {
-
#if ENABLE(CUSTOM_ELEMENTS)
- auto* definitions = ownerDocumentForCurrentNode().customElementDefinitions();
- if (customElementInterface && UNLIKELY(definitions)) {
- if (auto* interface = definitions->findInterface(localName)) {
- *customElementInterface = interface;
- return nullptr;
+ if (customElementInterface) {
+ auto* definitions = ownerDocument.customElementDefinitions();
+ if (UNLIKELY(definitions)) {
+ if (auto* interface = definitions->findInterface(localName)) {
+ *customElementInterface = interface;
+ return nullptr;
+ }
}
}
#else
UNUSED_PARAM(customElementInterface);
#endif
- element = HTMLUnknownElement::create(QualifiedName(nullAtom, localName, xhtmlNamespaceURI), ownerDocumentForCurrentNode());
+ QualifiedName qualifiedName(nullAtom, localName, xhtmlNamespaceURI);
+#if ENABLE(CUSTOM_ELEMENTS)
+ if (CustomElementDefinitions::checkName(localName) == CustomElementDefinitions::NameStatus::Valid) {
+ element = HTMLElement::create(qualifiedName, ownerDocument);
+ element->setIsUnresolvedCustomElement();
+ ownerDocument.ensureCustomElementDefinitions().addUpgradeCandidate(*element);
+ } else
+#endif
+ element = HTMLUnknownElement::create(qualifiedName, ownerDocument);
}
ASSERT(element);