| // Copyright 2014 The Cobalt Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef COBALT_DOM_ELEMENT_H_ |
| #define COBALT_DOM_ELEMENT_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| |
| #include "base/containers/hash_tables.h" |
| #include "base/containers/small_map.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/optional.h" |
| #include "base/strings/string_piece.h" |
| #include "cobalt/base/token.h" |
| #include "cobalt/cssom/style_sheet_list.h" |
| #include "cobalt/dom/element_intersection_observer_module.h" |
| #include "cobalt/dom/intersection_observer.h" |
| #include "cobalt/dom/node.h" |
| #include "cobalt/script/exception_state.h" |
| #include "cobalt/web/dom_exception.h" |
| #include "cobalt/web_animations/animation_set.h" |
| |
| namespace cobalt { |
| namespace dom { |
| |
| class DOMRect; |
| class DOMRectList; |
| class DOMTokenList; |
| class HTMLCollection; |
| class HTMLElement; |
| class HTMLElementContext; |
| class NamedNodeMap; |
| |
| // The Element interface represents an object of a Document. This interface |
| // describes methods and properties common to all kinds of elements. |
| // https://www.w3.org/TR/2014/WD-dom-20140710/#interface-element |
| class Element : public Node { |
| public: |
| // NOTE1: The array size of base::small_map and the decision to use |
| // base::hash_map as the underlying container type are based on extensive |
| // performance testing. Do not change these unless additional profiling data |
| // justifies it. |
| // NOTE2: Using base::small_map rather than base::hash_map also results in |
| // substantial memory gains when live videos are played. These videos trigger |
| // the creation of XML documents with over 20k elements, of which over 99% |
| // contain a single attribute. By using base::small_map, these single |
| // attribute elements are contained within arrays rather than hash_maps. |
| typedef base::small_map<std::unordered_map<std::string, std::string>, 1> |
| AttributeMap; |
| |
| explicit Element(Document* document); |
| Element(Document* document, base_token::Token local_name); |
| |
| // Web API: Node |
| // |
| base_token::Token node_name() const override { return tag_name(); } |
| NodeType node_type() const override { return Node::kElementNode; } |
| |
| base::Optional<std::string> text_content() const override; |
| void set_text_content( |
| const base::Optional<std::string>& text_content) override; |
| |
| bool HasAttributes() const override; |
| |
| // Web API: Element |
| // |
| base_token::Token local_name() const { return local_name_; } |
| |
| base_token::Token tag_name() const; |
| |
| base_token::Token id() const { return id_attribute_; } |
| void set_id(const std::string& value) { SetAttribute("id", value); } |
| |
| std::string class_name() const { return GetAttribute("class").value_or(""); } |
| void set_class_name(const std::string& value) { |
| SetAttribute("class", value); |
| } |
| |
| const scoped_refptr<DOMTokenList>& class_list(); |
| scoped_refptr<NamedNodeMap> attributes(); |
| |
| base::Optional<std::string> GetAttribute(const std::string& name) const; |
| void SetAttribute(const std::string& name, const std::string& value); |
| void RemoveAttribute(const std::string& name); |
| bool HasAttribute(const std::string& name) const; |
| |
| base::Optional<std::string> GetAttributeNS(const std::string& namespace_uri, |
| const std::string& name) const; |
| bool HasAttributeNS(const std::string& namespace_uri, |
| const std::string& name) const; |
| bool Matches(const std::string& selectors, |
| script::ExceptionState* exception_state); |
| |
| scoped_refptr<HTMLCollection> GetElementsByTagName( |
| const std::string& local_name) const; |
| scoped_refptr<HTMLCollection> GetElementsByClassName( |
| const std::string& class_name) const; |
| |
| // Web API: CSSOM View Module: Extensions to the Element Interface (partial |
| // interface) |
| // https://www.w3.org/TR/2013/WD-cssom-view-20131217/#extensions-to-the-element-interface |
| scoped_refptr<DOMRect> GetBoundingClientRect(); |
| virtual scoped_refptr<DOMRectList> GetClientRects(); |
| virtual float client_top(); |
| virtual float client_left(); |
| virtual float client_width(); |
| virtual float client_height(); |
| |
| // Updated version of the CSSOM View Module extensions: |
| // https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface |
| // If the element does not have any associated CSS layout box return zero. |
| virtual int32 scroll_width() { return 0; } |
| virtual int32 scroll_height() { return 0; } |
| virtual float scroll_left() { return 0.0f; } |
| virtual float scroll_top() { return 0.0f; } |
| |
| // If the element does not have any associated CSS layout box, the element |
| // has no associated scrolling box, or the element has no overflow, terminate |
| // these steps. |
| virtual void set_scroll_left(float x) {} |
| virtual void set_scroll_top(float y) {} |
| |
| // Web API: DOM Parsing and Serialization (partial interface) |
| // https://www.w3.org/TR/DOM-Parsing/#extensions-to-the-element-interface |
| // |
| std::string inner_html() const; |
| void set_inner_html(const std::string& inner_html); |
| std::string outer_html(script::ExceptionState* exception_state) const; |
| void set_outer_html(const std::string& outer_html, |
| script::ExceptionState* exception_state); |
| |
| // Web API: Pointer Events: Extensions to the Element Interface (partial |
| // interface) |
| // https://www.w3.org/TR/2015/REC-pointerevents-20150224/#extensions-to-the-element-interface |
| void SetPointerCapture(int32_t pointer_id, |
| script::ExceptionState* exception_state); |
| void ReleasePointerCapture(int32_t pointer_id, |
| script::ExceptionState* exception_state); |
| bool HasPointerCapture(int32_t pointer_id); |
| |
| // Custom, not in any spec: Node. |
| // |
| Element* AsElement() override { return this; } |
| |
| void Accept(NodeVisitor* visitor) override; |
| void Accept(ConstNodeVisitor* visitor) const override; |
| |
| scoped_refptr<Node> Duplicate() const override; |
| |
| // Custom, not in any spec. |
| // |
| |
| // Returns whether the element has no children at all except comments or |
| // processing instructions. |
| // https://www.w3.org/TR/selectors4/#empty-pseudo |
| bool IsEmpty(); |
| |
| // Returns whether the element has focus. |
| // https://www.w3.org/TR/selectors4/#focus-pseudo |
| bool HasFocus(); |
| |
| // Returns a map that holds the actual attributes of the element. |
| const AttributeMap& attribute_map() const { return attribute_map_; } |
| |
| // These are called when the element is generated by the parser, rather than |
| // by javascript. |
| // opening_tag_location points to ">" of opening tag. |
| virtual void OnParserStartTag( |
| const base::SourceLocation& opening_tag_location) {} |
| virtual void OnParserEndTag() {} |
| |
| // Used to ensure that the style attribute value reflects the style |
| // declaration. |
| // https://www.w3.org/TR/html50/dom.html#the-style-attribute |
| virtual base::Optional<std::string> GetStyleAttribute() const; |
| virtual void SetStyleAttribute(const std::string& value); |
| virtual void RemoveStyleAttribute(); |
| |
| // Adds all style sheets contained within the this element and its descendants |
| // to the style sheet vector. The style sheets are added in depth-first |
| // pre-order. |
| void CollectStyleSheetsOfElementAndDescendants( |
| cssom::StyleSheetVector* style_sheets) const; |
| |
| virtual scoped_refptr<HTMLElement> AsHTMLElement(); |
| |
| const scoped_refptr<web_animations::AnimationSet>& animations() { |
| return animations_; |
| } |
| |
| void RegisterIntersectionObserverRoot(IntersectionObserver* observer); |
| void UnregisterIntersectionObserverRoot(IntersectionObserver* observer); |
| void RegisterIntersectionObserverTarget(IntersectionObserver* observer); |
| void UnregisterIntersectionObserverTarget(IntersectionObserver* observer); |
| ElementIntersectionObserverModule::LayoutIntersectionObserverRootVector |
| GetLayoutIntersectionObserverRoots(); |
| ElementIntersectionObserverModule::LayoutIntersectionObserverTargetVector |
| GetLayoutIntersectionObserverTargets(); |
| |
| DEFINE_WRAPPABLE_TYPE(Element); |
| void TraceMembers(script::Tracer* tracer) override; |
| |
| protected: |
| ~Element() override; |
| |
| // Getting and setting boolean attribute. |
| // https://www.w3.org/TR/html50/infrastructure.html#boolean-attribute |
| bool GetBooleanAttribute(const std::string& name) const; |
| void SetBooleanAttribute(const std::string& name, bool value); |
| |
| void CopyAttributes(const Element& other); |
| |
| HTMLElementContext* html_element_context(); |
| |
| private: |
| // From EventTarget. |
| std::string GetDebugName() override; |
| |
| virtual void OnSetAttribute(const std::string& name, |
| const std::string& value) {} |
| virtual void OnRemoveAttribute(const std::string& name) {} |
| |
| // Adds this element's style sheet to the style sheet vector. By default, this |
| // function does nothing, but is implemented by element subclasses that |
| // generate style sheets (HTMLStyleElement and HTMLLinkElement). |
| virtual void CollectStyleSheet(cssom::StyleSheetVector* style_sheets) const {} |
| |
| // Callback for error when parsing inner / outer HTML. |
| void HTMLParseError(const std::string& error); |
| |
| void EnsureIntersectionObserverModuleInitialized(); |
| |
| // Local name of the element. |
| base_token::Token local_name_; |
| // A map that holds the actual element attributes. |
| AttributeMap attribute_map_; |
| // The "id" attribute for this element. Stored here in addition to being |
| // stored in |attribute_map_| as an optimization for id(). |
| base_token::Token id_attribute_; |
| // A weak pointer to a NamedNodeMap that proxies the actual attributes. |
| // This heavy weight object is kept in memory only when needed by the user. |
| base::WeakPtr<NamedNodeMap> named_node_map_; |
| // Lazily created list of CSS classes. |
| // After creation this is kept in memory because of the significant negative |
| // performance impact of repeatedly recreating it. |
| scoped_refptr<DOMTokenList> class_list_; |
| |
| // A set of all animations currently applied to this element. |
| scoped_refptr<web_animations::AnimationSet> animations_; |
| |
| std::unique_ptr<ElementIntersectionObserverModule> |
| element_intersection_observer_module_; |
| }; |
| |
| } // namespace dom |
| } // namespace cobalt |
| |
| #endif // COBALT_DOM_ELEMENT_H_ |