Index: Source/build/scripts/templates/ElementTypeHelpers.h.tmpl |
diff --git a/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl b/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dd9ad85645640c9e8be60b113676fff220ea6b6b |
--- /dev/null |
+++ b/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl |
@@ -0,0 +1,64 @@ |
+{% from "macros.tmpl" import license -%} |
+{{ license() }} |
+ |
+#ifndef {{namespace}}ElementTypeHelpers_h |
+#define {{namespace}}ElementTypeHelpers_h |
+ |
+#include "core/dom/ContextFeatures.h" |
+#include "core/dom/Element.h" |
+#include "{{namespace}}Names.h" |
+#include "RuntimeEnabledFeatures.h" |
+ |
+namespace WebCore { |
+// Type checking. |
+{% for tag in tags|sort if not tag.multipleTagNames %} |
+class {{tag.interface}}; |
+void is{{tag.interface}}(const {{tag.interface}}&); // Catch unnecessary runtime check of type known at compile time. |
+void is{{tag.interface}}(const {{tag.interface}}*); // Catch unnecessary runtime check of type known at compile time. |
+inline bool is{{tag.interface}}(const Element& element) { |
+{%- if tag.contextConditional %} |
+ if (!ContextFeatures::{{tag.contextConditional}}Enabled(&element.document())) |
+ return false; |
+{%- endif %} |
+{%- if tag.runtimeEnabled %} |
+ if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled()) |
+ return false; |
+{%- endif %} |
+ return element.hasTagName({{namespace}}Names::{{tag.name}}Tag); |
+} |
+inline bool is{{tag.interface}}(const Element* element) { ASSERT(element); return is{{tag.interface}}(*element); } |
+inline bool is{{tag.interface}}(const Node& node) { return node.isElementNode() ? is{{tag.interface}}(toElement(node)) : false; } |
+inline bool is{{tag.interface}}(const Node* node) { ASSERT(node); return node->isElementNode() ? is{{tag.interface}}(*toElement(node)) : false; } |
+template <> inline bool isElementOfType<const {{tag.interface}}>(const Element& element) { return is{{tag.interface}}(element); } |
+{% endfor %} |
+// Type casting. |
+template<typename T> inline T& toElement(Node& node) |
+{ |
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node)); |
+ return static_cast<T&>(node); |
+} |
+template<typename T> inline T* toElement(Node* node) |
+{ |
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node)); |
+ return static_cast<T*>(node); |
+} |
+template<typename T> inline const T& toElement(const Node& node) |
+{ |
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node)); |
+ return static_cast<const T&>(node); |
+} |
+template<typename T> inline const T* toElement(const Node* node) |
+{ |
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node)); |
+ return static_cast<const T*>(node); |
+} |
+template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); } |
+ |
+// Using macros because the types are forward-declared and we don't want to use reinterpret_cast in the |
+// casting functions above. reinterpret_cast would be unsafe due to multiple inheritence. |
+{% for tag in tags|sort if not tag.multipleTagNames %} |
+#define to{{tag.interface}}(x) WebCore::toElement<WebCore::{{tag.interface}}>(x) |
+{% endfor %} |
+} // WebCore |
+ |
+#endif |