1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "third_party/blink/public/web/web_node.h"
32 
33 #include "third_party/blink/public/platform/task_type.h"
34 #include "third_party/blink/public/platform/web_string.h"
35 #include "third_party/blink/public/web/web_document.h"
36 #include "third_party/blink/public/web/web_dom_event.h"
37 #include "third_party/blink/public/web/web_element.h"
38 #include "third_party/blink/public/web/web_element_collection.h"
39 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
40 #include "third_party/blink/renderer/core/dom/document.h"
41 #include "third_party/blink/renderer/core/dom/element.h"
42 #include "third_party/blink/renderer/core/dom/events/event.h"
43 #include "third_party/blink/renderer/core/dom/node.h"
44 #include "third_party/blink/renderer/core/dom/node_list.h"
45 #include "third_party/blink/renderer/core/dom/static_node_list.h"
46 #include "third_party/blink/renderer/core/dom/tag_collection.h"
47 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
48 #include "third_party/blink/renderer/core/editing/serializers/serialization.h"
49 #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
50 #include "third_party/blink/renderer/core/html/html_collection.h"
51 #include "third_party/blink/renderer/core/html/html_element.h"
52 #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
53 #include "third_party/blink/renderer/core/layout/layout_object.h"
54 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
55 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
56 
57 namespace blink {
58 
59 WebNode::WebNode() = default;
60 
WebNode(const WebNode & n)61 WebNode::WebNode(const WebNode& n) {
62   Assign(n);
63 }
64 
operator =(const WebNode & n)65 WebNode& WebNode::operator=(const WebNode& n) {
66   Assign(n);
67   return *this;
68 }
69 
~WebNode()70 WebNode::~WebNode() {
71   Reset();
72 }
73 
Reset()74 void WebNode::Reset() {
75   private_.Reset();
76 }
77 
Assign(const WebNode & other)78 void WebNode::Assign(const WebNode& other) {
79   private_ = other.private_;
80 }
81 
Equals(const WebNode & n) const82 bool WebNode::Equals(const WebNode& n) const {
83   return private_.Get() == n.private_.Get();
84 }
85 
LessThan(const WebNode & n) const86 bool WebNode::LessThan(const WebNode& n) const {
87   return private_.Get() < n.private_.Get();
88 }
89 
ParentNode() const90 WebNode WebNode::ParentNode() const {
91   return WebNode(const_cast<ContainerNode*>(private_->parentNode()));
92 }
93 
NodeValue() const94 WebString WebNode::NodeValue() const {
95   return private_->nodeValue();
96 }
97 
GetDocument() const98 WebDocument WebNode::GetDocument() const {
99   return WebDocument(&private_->GetDocument());
100 }
101 
FirstChild() const102 WebNode WebNode::FirstChild() const {
103   return WebNode(private_->firstChild());
104 }
105 
LastChild() const106 WebNode WebNode::LastChild() const {
107   return WebNode(private_->lastChild());
108 }
109 
PreviousSibling() const110 WebNode WebNode::PreviousSibling() const {
111   return WebNode(private_->previousSibling());
112 }
113 
NextSibling() const114 WebNode WebNode::NextSibling() const {
115   return WebNode(private_->nextSibling());
116 }
117 
IsNull() const118 bool WebNode::IsNull() const {
119   return private_.IsNull();
120 }
121 
IsLink() const122 bool WebNode::IsLink() const {
123   return private_->IsLink();
124 }
125 
IsTextNode() const126 bool WebNode::IsTextNode() const {
127   return private_->IsTextNode();
128 }
129 
IsCommentNode() const130 bool WebNode::IsCommentNode() const {
131   return private_->getNodeType() == Node::kCommentNode;
132 }
133 
IsFocusable() const134 bool WebNode::IsFocusable() const {
135   auto* element = DynamicTo<Element>(private_.Get());
136   if (!element)
137     return false;
138   if (!private_->GetDocument().HaveRenderBlockingResourcesLoaded())
139     return false;
140   private_->GetDocument().UpdateStyleAndLayoutTreeForNode(private_.Get());
141   return element->IsFocusable();
142 }
143 
IsContentEditable() const144 bool WebNode::IsContentEditable() const {
145   private_->GetDocument().UpdateStyleAndLayoutTree();
146   return HasEditableStyle(*private_);
147 }
148 
IsInsideFocusableElementOrARIAWidget() const149 bool WebNode::IsInsideFocusableElementOrARIAWidget() const {
150   return AXObjectCache::IsInsideFocusableElementOrARIAWidget(
151       *this->ConstUnwrap<Node>());
152 }
153 
IsElementNode() const154 bool WebNode::IsElementNode() const {
155   return private_->IsElementNode();
156 }
157 
IsDocumentNode() const158 bool WebNode::IsDocumentNode() const {
159   return private_->IsDocumentNode();
160 }
161 
IsDocumentTypeNode() const162 bool WebNode::IsDocumentTypeNode() const {
163   return private_->getNodeType() == Node::kDocumentTypeNode;
164 }
165 
SimulateClick()166 void WebNode::SimulateClick() {
167   private_->GetExecutionContext()
168       ->GetTaskRunner(TaskType::kUserInteraction)
169       ->PostTask(
170           FROM_HERE,
171           WTF::Bind(&Node::DispatchSimulatedClick,
172                     WrapWeakPersistent(private_.Get()), nullptr, kSendNoEvents,
173                     SimulatedClickCreationScope::kFromUserAgent));
174 }
175 
GetElementsByHTMLTagName(const WebString & tag) const176 WebElementCollection WebNode::GetElementsByHTMLTagName(
177     const WebString& tag) const {
178   if (private_->IsContainerNode()) {
179     return WebElementCollection(
180         blink::To<ContainerNode>(private_.Get())
181             ->getElementsByTagNameNS(html_names::xhtmlNamespaceURI, tag));
182   }
183   return WebElementCollection();
184 }
185 
QuerySelector(const WebString & selector) const186 WebElement WebNode::QuerySelector(const WebString& selector) const {
187   if (!private_->IsContainerNode())
188     return WebElement();
189   return blink::To<ContainerNode>(private_.Get())
190       ->QuerySelector(selector, IGNORE_EXCEPTION_FOR_TESTING);
191 }
192 
QuerySelectorAll(const WebString & selector) const193 WebVector<WebElement> WebNode::QuerySelectorAll(
194     const WebString& selector) const {
195   if (!private_->IsContainerNode())
196     return WebVector<WebElement>();
197   StaticElementList* elements =
198       blink::To<ContainerNode>(private_.Get())
199           ->QuerySelectorAll(selector, IGNORE_EXCEPTION_FOR_TESTING);
200   if (elements) {
201     WebVector<WebElement> vector((size_t)elements->length());
202     for (unsigned i = 0; i < elements->length(); ++i)
203       vector[i] = elements->item(i);
204     return vector;
205   }
206   return WebVector<WebElement>();
207 }
208 
Focused() const209 bool WebNode::Focused() const {
210   return private_->IsFocused();
211 }
212 
ScrollingElementIdForTesting() const213 uint64_t WebNode::ScrollingElementIdForTesting() const {
214   return private_->GetLayoutBox()
215       ->GetScrollableArea()
216       ->GetScrollElementId()
217       .GetStableId();
218 }
219 
PluginContainer() const220 WebPluginContainer* WebNode::PluginContainer() const {
221   return private_->GetWebPluginContainer();
222 }
223 
WebNode(Node * node)224 WebNode::WebNode(Node* node) : private_(node) {}
225 
operator =(Node * node)226 WebNode& WebNode::operator=(Node* node) {
227   private_ = node;
228   return *this;
229 }
230 
operator Node*() const231 WebNode::operator Node*() const {
232   return private_.Get();
233 }
234 
235 }  // namespace blink
236