Commit 18ac0a07 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

custom-elements: document.createElementNS() should set prefixes to custom elements.

We had a bug that createElementNS() ignored prefixes.
New behavior matches to the specification and Firefox.

* Document-createElementNS.html:
  Fix a copypasta error.

* ScriptCustomElementDefinition::CreateElementSync:
  Implement Step 6.1.10.

* Document::createElementNS:
  Fix an argument of definition lookup.

* CustomElement::CreateUndefinedElement:
  Use Document::CreateRawElement(), which sets prefixes correctly,
  instead of HTMLElementFactory::createHTMLElement().

* ustomElementDefinition::CreateElementAsync:
  Use Document::CreateRawElement(), which sets prefixes correctly,
  instead of HTMLElementFactory::createRawHTMLElement().

Bug: 806639
Change-Id: I74b431d4475d7cf84f65ab0ff1b24773cbc64079
Reviewed-on: https://chromium-review.googlesource.com/892802Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532821}
parent 1017eb91
This is a testharness.js-based test.
FAIL autonomous: document.createElementNS should create custom elements with prefixes. assert_equals: expected (string) "p" but got (object) null
PASS autonomous: document.createElementNS should check namespaces.
FAIL builtin: document.createElementNS should create custom elements with prefixes. Failed to execute 'createElementNS' on 'Document': Custom element definition not found.
PASS builtin: document.createElementNS should check namespaces.
Harness: the test ran to completion.
...@@ -28,7 +28,7 @@ test(() => { ...@@ -28,7 +28,7 @@ test(() => {
customElements.define('my-builtin', MyBuiltinElement, { extends: 'address' }); customElements.define('my-builtin', MyBuiltinElement, { extends: 'address' });
let element = document.createElementNS('http://www.w3.org/1999/xhtml', 'p:address', { is: 'my-builtin'}); let element = document.createElementNS('http://www.w3.org/1999/xhtml', 'p:address', { is: 'my-builtin'});
assert_true(element instanceof MyElement); assert_true(element instanceof MyBuiltinElement);
assert_equals(element.prefix, 'p'); assert_equals(element.prefix, 'p');
}, 'builtin: document.createElementNS should create custom elements with prefixes.'); }, 'builtin: document.createElementNS should create custom elements with prefixes.');
......
...@@ -188,6 +188,9 @@ HTMLElement* ScriptCustomElementDefinition::CreateElementSync( ...@@ -188,6 +188,9 @@ HTMLElement* ScriptCustomElementDefinition::CreateElementSync(
return HandleCreateElementSyncException(document, tag_name, isolate, return HandleCreateElementSyncException(document, tag_name, isolate,
exception_state); exception_state);
} }
// 6.1.10. Set result’s namespace prefix to prefix.
if (element->prefix() != tag_name.Prefix())
element->SetTagNameForCreateElementNS(tag_name);
DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kCustom); DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kCustom);
return ToHTMLElement(element); return ToHTMLElement(element);
} }
......
...@@ -1080,7 +1080,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, ...@@ -1080,7 +1080,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri,
// 2. // 2.
const AtomicString& is = const AtomicString& is =
AtomicString(GetTypeExtension(this, string_or_options, exception_state)); AtomicString(GetTypeExtension(this, string_or_options, exception_state));
const AtomicString& name = should_create_builtin ? is : qualified_name; const AtomicString& name = should_create_builtin ? is : q_name.LocalName();
if (!IsValidElementName(this, qualified_name)) { if (!IsValidElementName(this, qualified_name)) {
exception_state.ThrowDOMException( exception_state.ThrowDOMException(
...@@ -1093,9 +1093,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri, ...@@ -1093,9 +1093,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri,
CustomElementDefinition* definition = nullptr; CustomElementDefinition* definition = nullptr;
if (is_v1 && namespace_uri == HTMLNames::xhtmlNamespaceURI) { if (is_v1 && namespace_uri == HTMLNames::xhtmlNamespaceURI) {
const CustomElementDescriptor desc = const CustomElementDescriptor desc =
RuntimeEnabledFeatures::CustomElementsBuiltinEnabled() CustomElementDescriptor(name, q_name.LocalName());
? CustomElementDescriptor(name, qualified_name)
: CustomElementDescriptor(qualified_name, qualified_name);
if (CustomElementRegistry* registry = CustomElement::Registry(*this)) if (CustomElementRegistry* registry = CustomElement::Registry(*this))
definition = registry->DefinitionFor(desc); definition = registry->DefinitionFor(desc);
......
...@@ -170,8 +170,8 @@ HTMLElement* CustomElement::CreateUndefinedElement( ...@@ -170,8 +170,8 @@ HTMLElement* CustomElement::CreateUndefinedElement(
SECURITY_DCHECK(v0element->IsHTMLElement()); SECURITY_DCHECK(v0element->IsHTMLElement());
element = ToHTMLElement(v0element); element = ToHTMLElement(v0element);
} else if (should_create_builtin) { } else if (should_create_builtin) {
element = HTMLElementFactory::createHTMLElement( element = ToHTMLElement(
tag_name.LocalName(), document, kCreatedByCreateElement); document.CreateRawElement(tag_name, kCreatedByCreateElement));
} else { } else {
element = HTMLElement::Create(tag_name, document); element = HTMLElement::Create(tag_name, document);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/ExceptionState.h"
#include "core/dom/Attr.h" #include "core/dom/Attr.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h" #include "core/dom/ExceptionCode.h"
#include "core/html/HTMLElement.h" #include "core/html/HTMLElement.h"
#include "core/html/custom/CustomElement.h" #include "core/html/custom/CustomElement.h"
...@@ -121,14 +122,13 @@ HTMLElement* CustomElementDefinition::CreateElementAsync( ...@@ -121,14 +122,13 @@ HTMLElement* CustomElementDefinition::CreateElementAsync(
// prefix set to prefix, local name set to localName, custom element // prefix set to prefix, local name set to localName, custom element
// state set to "undefined", custom element definition set to null, // state set to "undefined", custom element definition set to null,
// is value set to is, and node document set to document. // is value set to is, and node document set to document.
auto* result = HTMLElementFactory::CreateRawHTMLElement( auto* result = document.CreateRawElement(tag_name, flags);
tag_name.LocalName(), document, flags);
result->SetCustomElementState(CustomElementState::kUndefined); result->SetCustomElementState(CustomElementState::kUndefined);
// 5.4. Otherwise, enqueue a custom element upgrade reaction given // 5.4. Otherwise, enqueue a custom element upgrade reaction given
// result and definition. // result and definition.
EnqueueUpgradeReaction(result); EnqueueUpgradeReaction(result);
return result; return ToHTMLElement(result);
} }
// 6. If definition is non-null, then: // 6. If definition is non-null, then:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment