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_document.h"
32 
33 #include "base/memory/scoped_refptr.h"
34 #include "services/network/public/mojom/referrer_policy.mojom-blink.h"
35 #include "third_party/blink/public/platform/web_distillability.h"
36 #include "third_party/blink/public/platform/web_url.h"
37 #include "third_party/blink/public/web/web_dom_event.h"
38 #include "third_party/blink/public/web/web_element.h"
39 #include "third_party/blink/public/web/web_element_collection.h"
40 #include "third_party/blink/public/web/web_form_element.h"
41 #include "third_party/blink/renderer/core/css/css_selector_watch.h"
42 #include "third_party/blink/renderer/core/css/style_engine.h"
43 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
44 #include "third_party/blink/renderer/core/dom/document.h"
45 #include "third_party/blink/renderer/core/dom/document_statistics_collector.h"
46 #include "third_party/blink/renderer/core/dom/document_type.h"
47 #include "third_party/blink/renderer/core/dom/element.h"
48 #include "third_party/blink/renderer/core/dom/events/event.h"
49 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
50 #include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
51 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
52 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
53 #include "third_party/blink/renderer/core/html/forms/html_form_element.h"
54 #include "third_party/blink/renderer/core/html/html_all_collection.h"
55 #include "third_party/blink/renderer/core/html/html_body_element.h"
56 #include "third_party/blink/renderer/core/html/html_collection.h"
57 #include "third_party/blink/renderer/core/html/html_document.h"
58 #include "third_party/blink/renderer/core/html/html_element.h"
59 #include "third_party/blink/renderer/core/html/html_head_element.h"
60 #include "third_party/blink/renderer/core/html/html_link_element.h"
61 #include "third_party/blink/renderer/core/html/plugin_document.h"
62 #include "third_party/blink/renderer/core/layout/layout_object.h"
63 #include "third_party/blink/renderer/core/layout/layout_view.h"
64 #include "third_party/blink/renderer/core/loader/document_loader.h"
65 #include "third_party/blink/renderer/core/page/page.h"
66 #include "third_party/blink/renderer/platform/heap/heap.h"
67 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
68 #include "third_party/blink/renderer/platform/wtf/casting.h"
69 
70 namespace {
71 
GenerateStyleSheetKey()72 static const blink::WebStyleSheetKey GenerateStyleSheetKey() {
73   static unsigned counter = 0;
74   return String::Number(++counter);
75 }
76 
77 }  // namespace
78 
79 namespace blink {
80 
Url() const81 WebURL WebDocument::Url() const {
82   return ConstUnwrap<Document>()->Url();
83 }
84 
GetSecurityOrigin() const85 WebSecurityOrigin WebDocument::GetSecurityOrigin() const {
86   if (!ConstUnwrap<Document>())
87     return WebSecurityOrigin();
88   return WebSecurityOrigin(ConstUnwrap<Document>()->GetSecurityOrigin());
89 }
90 
IsSecureContext() const91 bool WebDocument::IsSecureContext() const {
92   const Document* document = ConstUnwrap<Document>();
93   return document && document->IsSecureContext();
94 }
95 
Encoding() const96 WebString WebDocument::Encoding() const {
97   return ConstUnwrap<Document>()->EncodingName();
98 }
99 
ContentLanguage() const100 WebString WebDocument::ContentLanguage() const {
101   return ConstUnwrap<Document>()->ContentLanguage();
102 }
103 
GetReferrer() const104 WebString WebDocument::GetReferrer() const {
105   return ConstUnwrap<Document>()->referrer();
106 }
107 
ThemeColor() const108 base::Optional<SkColor> WebDocument::ThemeColor() const {
109   base::Optional<Color> color = ConstUnwrap<Document>()->ThemeColor();
110   if (color)
111     return color->Rgb();
112   return base::nullopt;
113 }
114 
OpenSearchDescriptionURL() const115 WebURL WebDocument::OpenSearchDescriptionURL() const {
116   return const_cast<Document*>(ConstUnwrap<Document>())
117       ->OpenSearchDescriptionURL();
118 }
119 
GetFrame() const120 WebLocalFrame* WebDocument::GetFrame() const {
121   return WebLocalFrameImpl::FromFrame(ConstUnwrap<Document>()->GetFrame());
122 }
123 
IsHTMLDocument() const124 bool WebDocument::IsHTMLDocument() const {
125   return IsA<HTMLDocument>(ConstUnwrap<Document>());
126 }
127 
IsXHTMLDocument() const128 bool WebDocument::IsXHTMLDocument() const {
129   return ConstUnwrap<Document>()->IsXHTMLDocument();
130 }
131 
IsPluginDocument() const132 bool WebDocument::IsPluginDocument() const {
133   return IsA<PluginDocument>(ConstUnwrap<Document>());
134 }
135 
BaseURL() const136 WebURL WebDocument::BaseURL() const {
137   return ConstUnwrap<Document>()->BaseURL();
138 }
139 
GetUkmSourceId() const140 ukm::SourceId WebDocument::GetUkmSourceId() const {
141   return ConstUnwrap<Document>()->UkmSourceID();
142 }
143 
SiteForCookies() const144 net::SiteForCookies WebDocument::SiteForCookies() const {
145   return ConstUnwrap<Document>()->SiteForCookies();
146 }
147 
TopFrameOrigin() const148 WebSecurityOrigin WebDocument::TopFrameOrigin() const {
149   return ConstUnwrap<Document>()->TopFrameOrigin();
150 }
151 
DocumentElement() const152 WebElement WebDocument::DocumentElement() const {
153   return WebElement(ConstUnwrap<Document>()->documentElement());
154 }
155 
Body() const156 WebElement WebDocument::Body() const {
157   return WebElement(ConstUnwrap<Document>()->body());
158 }
159 
Head()160 WebElement WebDocument::Head() {
161   return WebElement(Unwrap<Document>()->head());
162 }
163 
Title() const164 WebString WebDocument::Title() const {
165   return WebString(ConstUnwrap<Document>()->title());
166 }
167 
ContentAsTextForTesting() const168 WebString WebDocument::ContentAsTextForTesting() const {
169   Element* document_element = ConstUnwrap<Document>()->documentElement();
170   if (!document_element)
171     return WebString();
172   return document_element->innerText();
173 }
174 
All()175 WebElementCollection WebDocument::All() {
176   return WebElementCollection(Unwrap<Document>()->all());
177 }
178 
Forms(WebVector<WebFormElement> & results) const179 void WebDocument::Forms(WebVector<WebFormElement>& results) const {
180   HTMLCollection* forms =
181       const_cast<Document*>(ConstUnwrap<Document>())->forms();
182   size_t source_length = forms->length();
183   Vector<WebFormElement> temp;
184   temp.ReserveCapacity(source_length);
185   for (size_t i = 0; i < source_length; ++i) {
186     Element* element = forms->item(i);
187     // Strange but true, sometimes node can be 0.
188     if (auto* html_form_element = DynamicTo<HTMLFormElement>(element))
189       temp.push_back(WebFormElement(html_form_element));
190   }
191   results.Assign(temp);
192 }
193 
CompleteURL(const WebString & partial_url) const194 WebURL WebDocument::CompleteURL(const WebString& partial_url) const {
195   return ConstUnwrap<Document>()->CompleteURL(partial_url);
196 }
197 
GetElementById(const WebString & id) const198 WebElement WebDocument::GetElementById(const WebString& id) const {
199   return WebElement(ConstUnwrap<Document>()->getElementById(id));
200 }
201 
FocusedElement() const202 WebElement WebDocument::FocusedElement() const {
203   return WebElement(ConstUnwrap<Document>()->FocusedElement());
204 }
205 
InsertStyleSheet(const WebString & source_code,const WebStyleSheetKey * key,CSSOrigin origin)206 WebStyleSheetKey WebDocument::InsertStyleSheet(const WebString& source_code,
207                                                const WebStyleSheetKey* key,
208                                                CSSOrigin origin) {
209   Document* document = Unwrap<Document>();
210   DCHECK(document);
211   auto* parsed_sheet = MakeGarbageCollected<StyleSheetContents>(
212       MakeGarbageCollected<CSSParserContext>(*document));
213   parsed_sheet->ParseString(source_code);
214   const WebStyleSheetKey& injection_key =
215       key && !key->IsNull() ? *key : GenerateStyleSheetKey();
216   DCHECK(!injection_key.IsEmpty());
217   document->GetStyleEngine().InjectSheet(injection_key, parsed_sheet, origin);
218   return injection_key;
219 }
220 
RemoveInsertedStyleSheet(const WebStyleSheetKey & key,CSSOrigin origin)221 void WebDocument::RemoveInsertedStyleSheet(const WebStyleSheetKey& key,
222                                            CSSOrigin origin) {
223   Unwrap<Document>()->GetStyleEngine().RemoveInjectedSheet(key, origin);
224 }
225 
WatchCSSSelectors(const WebVector<WebString> & web_selectors)226 void WebDocument::WatchCSSSelectors(const WebVector<WebString>& web_selectors) {
227   Document* document = Unwrap<Document>();
228   CSSSelectorWatch* watch = CSSSelectorWatch::FromIfExists(*document);
229   if (!watch && web_selectors.empty())
230     return;
231   Vector<String> selectors;
232   selectors.Append(web_selectors.Data(), web_selectors.size());
233   CSSSelectorWatch::From(*document).WatchCSSSelectors(selectors);
234 }
235 
GetReferrerPolicy() const236 network::mojom::ReferrerPolicy WebDocument::GetReferrerPolicy() const {
237   return ConstUnwrap<Document>()->GetReferrerPolicy();
238 }
239 
OutgoingReferrer()240 WebString WebDocument::OutgoingReferrer() {
241   return WebString(Unwrap<Document>()->OutgoingReferrer());
242 }
243 
DraggableRegions() const244 WebVector<WebDraggableRegion> WebDocument::DraggableRegions() const {
245   WebVector<WebDraggableRegion> draggable_regions;
246   const Document* document = ConstUnwrap<Document>();
247   if (document->HasAnnotatedRegions()) {
248     const Vector<AnnotatedRegionValue>& regions = document->AnnotatedRegions();
249     draggable_regions = WebVector<WebDraggableRegion>(regions.size());
250     for (size_t i = 0; i < regions.size(); i++) {
251       const AnnotatedRegionValue& value = regions[i];
252       draggable_regions[i].draggable = value.draggable;
253       draggable_regions[i].bounds = PixelSnappedIntRect(value.bounds);
254     }
255   }
256   return draggable_regions;
257 }
258 
CanonicalUrlForSharing() const259 WebURL WebDocument::CanonicalUrlForSharing() const {
260   const Document* document = ConstUnwrap<Document>();
261   HTMLLinkElement* link_element = document->LinkCanonical();
262   if (!link_element)
263     return WebURL();
264   return link_element->Href();
265 }
266 
DistillabilityFeatures()267 WebDistillabilityFeatures WebDocument::DistillabilityFeatures() {
268   return DocumentStatisticsCollector::CollectStatistics(*Unwrap<Document>());
269 }
270 
SetShowBeforeUnloadDialog(bool show_dialog)271 void WebDocument::SetShowBeforeUnloadDialog(bool show_dialog) {
272   if (!IsHTMLDocument())
273     return;
274 
275   Document* doc = Unwrap<Document>();
276   doc->SetShowBeforeUnloadDialog(show_dialog);
277 }
278 
GetVisualViewportScrollingElementIdForTesting()279 uint64_t WebDocument::GetVisualViewportScrollingElementIdForTesting() {
280   return blink::To<Document>(private_.Get())
281       ->GetPage()
282       ->GetVisualViewport()
283       .GetScrollElementId()
284       .GetStableId();
285 }
286 
WebDocument(Document * elem)287 WebDocument::WebDocument(Document* elem) : WebNode(elem) {}
288 
289 DEFINE_WEB_NODE_TYPE_CASTS(WebDocument, ConstUnwrap<Node>()->IsDocumentNode())
290 
operator =(Document * elem)291 WebDocument& WebDocument::operator=(Document* elem) {
292   private_ = elem;
293   return *this;
294 }
295 
operator Document*() const296 WebDocument::operator Document*() const {
297   return blink::To<Document>(private_.Get());
298 }
299 
300 }  // namespace blink
301