Commit 1c6d493b authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

custom-elements: Customized built-in elements should work in innerHTML.

HTMLConstructionSite should call CustomElementDefinition::
CreateElementAsync() if it's in fragment parsing mode.

- Separate HTMLElementFactory::createHTMLElement() into two.
  CreateElementAsync() uses the first part of separated functions.

Bug: 805280
Change-Id: I2e2dafcd33c033c87c3accaca7c1b00c56474591
Reviewed-on: https://chromium-review.googlesource.com/890680Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532308}
parent 8a854532
......@@ -67,7 +67,7 @@ static void create{{namespace}}FunctionMap() {
g_{{namespace}}_constructors->Set(data[i].tag.LocalName(), data[i].func);
}
{{namespace}}Element* {{namespace}}ElementFactory::create{{namespace}}Element(
{{namespace}}Element* {{namespace}}ElementFactory::CreateRaw{{namespace}}Element(
const AtomicString& localName,
Document& document,
CreateElementFlags flags) {
......@@ -75,6 +75,15 @@ static void create{{namespace}}FunctionMap() {
create{{namespace}}FunctionMap();
if ({{namespace}}ConstructorFunction function = g_{{namespace}}_constructors->at(localName))
return function(document, flags);
return nullptr;
}
{{namespace}}Element* {{namespace}}ElementFactory::create{{namespace}}Element(
const AtomicString& localName,
Document& document,
CreateElementFlags flags) {
if (auto* element = {{namespace}}ElementFactory::CreateRaw{{namespace}}Element(localName, document, flags))
return element;
{% if namespace == 'HTML' %}
// createElement handles custom element creation itself in order to
......@@ -85,7 +94,7 @@ static void create{{namespace}}FunctionMap() {
if (flags != kCreatedByCreateElement && CustomElement::ShouldCreateCustomElement(localName)) {
QualifiedName tagName(g_null_atom, localName, HTMLNames::xhtmlNamespaceURI);
if (flags & kAsynchronousCustomElements)
return CustomElement::CreateCustomElementAsync(document, tagName);
return CustomElement::CreateCustomElementAsync(document, tagName, flags);
return CustomElement::CreateCustomElementSync(document, tagName);
}
{% endif %}
......
......@@ -6,18 +6,24 @@
#ifndef BLINK_CORE_{{namespace|upper}}_ELEMENT_FACTORY_H_
#define BLINK_CORE_{{namespace|upper}}_ELEMENT_FACTORY_H_
#include "core/dom/Document.h"
#include "core/dom/CreateElementFlags.h"
#include "platform/wtf/Forward.h"
namespace blink {
class Document;
class {{namespace}}Element;
{% if namespace == 'HTML' %}
class HTMLFormElement;
{% endif %}
class {{namespace}}ElementFactory {
public:
// If |localName| is unknown, nullptr is returned.
static {{namespace}}Element* CreateRaw{{namespace}}Element(
const AtomicString& localName,
Document&,
CreateElementFlags flags);
// CreateRaw{{namespace}}Element() + custom element processing.
// If |localName| is unknown, a {{fallback_interface}} instance is returned.
static {{namespace}}Element* create{{namespace}}Element(
const AtomicString& localName,
Document&,
......
......@@ -138,7 +138,8 @@ HTMLElement* CustomElement::CreateCustomElementSync(
HTMLElement* CustomElement::CreateCustomElementAsync(
Document& document,
const QualifiedName& tag_name) {
const QualifiedName& tag_name,
CreateElementFlags flags) {
DCHECK(ShouldCreateCustomElement(tag_name));
// To create an element:
......@@ -148,7 +149,7 @@ HTMLElement* CustomElement::CreateCustomElementAsync(
if (CustomElementDefinition* definition = DefinitionFor(
document,
CustomElementDescriptor(tag_name.LocalName(), tag_name.LocalName())))
return definition->CreateElementAsync(document, tag_name);
return definition->CreateElementAsync(document, tag_name, flags);
return CreateUndefinedElement(document, tag_name);
}
......@@ -257,8 +258,11 @@ void CustomElement::TryToUpgrade(Element* element) {
CustomElementRegistry* registry = CustomElement::Registry(*element);
if (!registry)
return;
if (CustomElementDefinition* definition = registry->DefinitionFor(
CustomElementDescriptor(element->localName(), element->localName())))
const AtomicString& is_value = element->FastGetAttribute(HTMLNames::isAttr);
if (CustomElementDefinition* definition =
registry->DefinitionFor(CustomElementDescriptor(
is_value.IsNull() ? element->localName() : is_value,
element->localName())))
definition->EnqueueUpgradeReaction(element);
else
registry->AddCandidate(element);
......
......@@ -6,6 +6,7 @@
#define CustomElement_h
#include "core/CoreExport.h"
#include "core/dom/CreateElementFlags.h"
#include "core/dom/Element.h"
#include "platform/text/Character.h"
#include "platform/wtf/ASCIICType.h"
......@@ -74,7 +75,9 @@ class CORE_EXPORT CustomElement {
static HTMLElement* CreateCustomElementSync(Document&,
const QualifiedName&,
CustomElementDefinition*);
static HTMLElement* CreateCustomElementAsync(Document&, const QualifiedName&);
static HTMLElement* CreateCustomElementAsync(Document&,
const QualifiedName&,
CreateElementFlags);
static HTMLElement* CreateFailedElement(Document&, const QualifiedName&);
......
......@@ -16,6 +16,7 @@
#include "core/html/custom/CustomElementReaction.h"
#include "core/html/custom/CustomElementReactionStack.h"
#include "core/html/custom/CustomElementUpgradeReaction.h"
#include "core/html_element_factory.h"
namespace blink {
......@@ -106,8 +107,30 @@ HTMLElement* CustomElementDefinition::CreateElementForConstructor(
HTMLElement* CustomElementDefinition::CreateElementAsync(
Document& document,
const QualifiedName& tag_name) {
const QualifiedName& tag_name,
CreateElementFlags flags) {
// https://dom.spec.whatwg.org/#concept-create-element
// 5. If definition is non-null, and definition’s name is not equal to
// its local name (i.e., definition represents a customized built-in
// element), then:
if (!descriptor_.IsAutonomous()) {
// 5.1. Let interface be the element interface for localName and the
// HTML namespace.
// 5.2. Set result to a new element that implements interface, with
// no attributes, namespace set to the HTML namespace, namespace
// prefix set to prefix, local name set to localName, custom element
// state set to "undefined", custom element definition set to null,
// is value set to is, and node document set to document.
auto* result = HTMLElementFactory::CreateRawHTMLElement(
tag_name.LocalName(), document, flags);
result->SetCustomElementState(CustomElementState::kUndefined);
// 5.4. Otherwise, enqueue a custom element upgrade reaction given
// result and definition.
EnqueueUpgradeReaction(result);
return result;
}
// 6. If definition is non-null, then:
// 6.2. If the synchronous custom elements flag is not set:
// 6.2.1. Set result to a new element that implements the HTMLElement
......
......@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "bindings/core/v8/ScriptValue.h"
#include "core/CoreExport.h"
#include "core/dom/CreateElementFlags.h"
#include "core/html/custom/CustomElementDescriptor.h"
#include "platform/bindings/ScriptWrappable.h" // For TraceWrapperBase
#include "platform/heap/Handle.h"
......@@ -54,7 +55,9 @@ class CORE_EXPORT CustomElementDefinition
HTMLElement* CreateElementForConstructor(Document&);
virtual HTMLElement* CreateElementSync(Document&, const QualifiedName&) = 0;
HTMLElement* CreateElementAsync(Document&, const QualifiedName&);
HTMLElement* CreateElementAsync(Document&,
const QualifiedName&,
CreateElementFlags);
void Upgrade(Element*);
......
......@@ -870,9 +870,7 @@ Element* HTMLConstructionSite::CreateElement(
QualifiedName tag_name(g_null_atom, token->GetName(), namespace_uri);
// "3. Let is be the value of the "is" attribute in the given token ..." etc.
// "4. Let definition be the result of looking up a custom element ..." etc.
CustomElementDefinition* definition =
is_parsing_fragment_ ? nullptr
: LookUpCustomElementDefinition(document, token);
auto* definition = LookUpCustomElementDefinition(document, token);
// "5. If definition is non-null and the parser was not originally created
// for the HTML fragment parsing algorithm, then let will execute script
// be true."
......@@ -911,7 +909,12 @@ Element* HTMLConstructionSite::CreateElement(
// and ThrowOnDynamicMarkupInsertionCountIncrementer destructors implement
// steps 9.1-3.
} else {
element = document.createElement(tag_name, GetCreateElementFlags());
if (definition) {
element = definition->CreateElementAsync(document, tag_name,
GetCreateElementFlags());
} else {
element = document.createElement(tag_name, GetCreateElementFlags());
}
// Definition for the created element does not exist here and it cannot be
// custom or failed.
DCHECK_NE(element->GetCustomElementState(), CustomElementState::kCustom);
......
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