summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/build/scripts/templates/element_factory.cc.tmpl
blob: dc3f44c5b10399da76e4caa685dcded63d9997a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{% from "templates/macros.tmpl" import license, source_files_for_generated_file %}
{{ license() }}

{{source_files_for_generated_file(template_file, input_files)}}

#include "third_party/blink/renderer/core/{{namespace|lower}}_element_factory.h"

#include "base/stl_util.h"  // for base::size()
#include "third_party/blink/renderer/core/{{namespace|lower}}_names.h"
{% for header in tags|groupby('interface_header') %}
#include "{{header[0]}}"
{% endfor %}
{% if fallback_interface %}
#include "third_party/blink/renderer/core/{{namespace|lower}}/{{fallback_interface_header}}"
{% endif %}
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"

namespace blink {

using {{namespace}}ConstructorFunction = {{namespace}}Element* (*)(
    Document&, const CreateElementFlags);

using {{namespace}}FunctionMap = HashMap<AtomicString, {{namespace}}ConstructorFunction>;

static {{namespace}}FunctionMap* g_{{namespace|lower}}_constructors = nullptr;

{% for tag in tags|sort if not tag.noConstructor %}
static {{namespace}}Element* {{namespace}}{{tag.name.to_upper_camel_case()}}Constructor(
    Document& document, const CreateElementFlags flags) {
  {% if tag.runtimeEnabled %}
  if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(document.GetExecutionContext()))
    return MakeGarbageCollected<{{fallback_interface}}>({{cpp_namespace}}::{{tag|symbol}}Tag, document);
  {% endif %}
  return MakeGarbageCollected<{{tag.interface}}>(
      {%- if tag.multipleTagNames %}{{cpp_namespace}}::{{tag|symbol}}Tag, {% endif -%}
      document
      {%- if tag.constructorNeedsCreateElementFlags %}, flags{% endif -%}
  );
}
{% endfor %}

struct Create{{namespace}}FunctionMapData {
  const QualifiedName& tag;
  {{namespace}}ConstructorFunction func;
};

static void Create{{namespace}}FunctionMap() {
  DCHECK(!g_{{namespace|lower}}_constructors);
  g_{{namespace|lower}}_constructors = new {{namespace}}FunctionMap;
  // Empty array initializer lists are illegal [dcl.init.aggr] and will not
  // compile in MSVC. If tags list is empty, add check to skip this.
  static const Create{{namespace}}FunctionMapData data[] = {
  {% for tag in tags|sort if not tag.noConstructor %}
    { {{cpp_namespace}}::{{tag|symbol}}Tag, {{namespace}}{{tag.name.to_upper_camel_case()}}Constructor },
  {% endfor %}
  };
  for (size_t i = 0; i < base::size(data); i++)
    g_{{namespace|lower}}_constructors->Set(data[i].tag.LocalName(), data[i].func);
}

{{namespace}}Element* {{namespace}}ElementFactory::Create(
    const AtomicString& local_name,
    Document& document,
    const CreateElementFlags flags) {
  if (!g_{{namespace|lower}}_constructors)
    Create{{namespace}}FunctionMap();
  if ({{namespace}}ConstructorFunction function = g_{{namespace|lower}}_constructors->at(local_name))
    return function(document, flags);
  return nullptr;
}

}  // namespace blink