1/*
2 * Copyright (C) 2000 Harri Porten (porten@kde.org)
3 * Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
4 * Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006 Apple Inc.
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "config.h"
24#include "Navigator.h"
25
26#include "Chrome.h"
27#include "CookieJar.h"
28#include "DOMMimeTypeArray.h"
29#include "DOMPluginArray.h"
30#include "Document.h"
31#include "Frame.h"
32#include "FrameLoader.h"
33#include "FrameLoaderClient.h"
34#include "Geolocation.h"
35#include "JSDOMPromiseDeferred.h"
36#include "LoaderStrategy.h"
37#include "Page.h"
38#include "PlatformStrategies.h"
39#include "PluginData.h"
40#include "ResourceLoadObserver.h"
41#include "RuntimeEnabledFeatures.h"
42#include "ScriptController.h"
43#include "SecurityOrigin.h"
44#include "Settings.h"
45#include <wtf/IsoMallocInlines.h>
46#include <wtf/Language.h>
47#include <wtf/StdLibExtras.h>
48#include <wtf/WeakPtr.h>
49
50namespace WebCore {
51
52WTF_MAKE_ISO_ALLOCATED_IMPL(Navigator);
53
54Navigator::Navigator(ScriptExecutionContext* context, DOMWindow& window)
55 : NavigatorBase(context)
56 , DOMWindowProperty(&window)
57{
58}
59
60Navigator::~Navigator() = default;
61
62String Navigator::appVersion() const
63{
64 auto* frame = this->frame();
65 if (!frame)
66 return String();
67 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
68 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::AppVersion);
69 return NavigatorBase::appVersion();
70}
71
72const String& Navigator::userAgent() const
73{
74 auto* frame = this->frame();
75 if (!frame || !frame->page())
76 return m_userAgent;
77 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
78 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::UserAgent);
79 if (m_userAgent.isNull())
80 m_userAgent = frame->loader().userAgentForJavaScript(frame->document()->url());
81 return m_userAgent;
82}
83
84String Navigator::platform() const
85{
86 auto* frame = this->frame();
87 if (!frame || !frame->page())
88 return m_platform;
89
90 if (m_platform.isNull())
91 m_platform = frame->loader().navigatorPlatform();
92
93 if (m_platform.isNull())
94 m_platform = NavigatorBase::platform();
95 return m_platform;
96}
97
98void Navigator::userAgentChanged()
99{
100 m_userAgent = String();
101}
102
103bool Navigator::onLine() const
104{
105 return platformStrategies()->loaderStrategy()->isOnLine();
106}
107
108void Navigator::share(ScriptExecutionContext& context, ShareData data, Ref<DeferredPromise>&& promise)
109{
110 auto* frame = this->frame();
111 if (!frame || !frame->page()) {
112 promise->reject(TypeError);
113 return;
114 }
115
116 if (data.title.isEmpty() && data.url.isEmpty() && data.text.isEmpty()) {
117 promise->reject(TypeError);
118 return;
119 }
120
121 Optional<URL> url;
122 if (!data.url.isEmpty()) {
123 url = context.completeURL(data.url);
124 if (!url->isValid()) {
125 promise->reject(TypeError);
126 return;
127 }
128 }
129
130 if (!UserGestureIndicator::processingUserGesture()) {
131 promise->reject(NotAllowedError);
132 return;
133 }
134
135 ShareDataWithParsedURL shareData = {
136 data,
137 url,
138 };
139
140 frame->page()->chrome().showShareSheet(shareData, [promise = WTFMove(promise)] (bool completed) {
141 if (completed) {
142 promise->resolve();
143 return;
144 }
145 promise->reject(Exception { AbortError, "Abort due to cancellation of share."_s });
146 });
147}
148
149DOMPluginArray& Navigator::plugins()
150{
151 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
152 if (auto* frame = this->frame())
153 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::Plugins);
154 }
155 if (!m_plugins)
156 m_plugins = DOMPluginArray::create(window());
157 return *m_plugins;
158}
159
160DOMMimeTypeArray& Navigator::mimeTypes()
161{
162 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
163 if (auto* frame = this->frame())
164 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::MimeTypes);
165 }
166 if (!m_mimeTypes)
167 m_mimeTypes = DOMMimeTypeArray::create(window());
168 return *m_mimeTypes;
169}
170
171bool Navigator::cookieEnabled() const
172{
173 auto* frame = this->frame();
174 if (!frame)
175 return false;
176
177 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
178 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::CookieEnabled);
179
180 auto* page = frame->page();
181 if (!page)
182 return false;
183
184 if (!page->settings().cookieEnabled())
185 return false;
186
187 auto* document = frame->document();
188 if (!document)
189 return false;
190
191 return page->cookieJar().cookiesEnabled(*document);
192}
193
194bool Navigator::javaEnabled() const
195{
196 auto* frame = this->frame();
197 if (!frame)
198 return false;
199
200 if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
201 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::JavaEnabled);
202
203 if (!frame->settings().isJavaEnabled())
204 return false;
205 if (frame->document()->securityOrigin().isLocal() && !frame->settings().isJavaEnabledForLocalFiles())
206 return false;
207
208 return true;
209}
210
211#if PLATFORM(IOS_FAMILY)
212
213bool Navigator::standalone() const
214{
215 auto* frame = this->frame();
216 return frame && frame->settings().standalone();
217}
218
219#endif
220
221void Navigator::getStorageUpdates()
222{
223}
224
225} // namespace WebCore
226