/src/serenity/Userland/Libraries/LibWeb/HTML/Navigator.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org> |
3 | | * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> |
4 | | * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | */ |
8 | | |
9 | | #include <LibJS/Heap/Heap.h> |
10 | | #include <LibJS/Runtime/Realm.h> |
11 | | #include <LibWeb/Bindings/Intrinsics.h> |
12 | | #include <LibWeb/Bindings/NavigatorPrototype.h> |
13 | | #include <LibWeb/Clipboard/Clipboard.h> |
14 | | #include <LibWeb/HTML/Navigator.h> |
15 | | #include <LibWeb/HTML/Scripting/Environments.h> |
16 | | #include <LibWeb/HTML/ServiceWorkerContainer.h> |
17 | | #include <LibWeb/HTML/Window.h> |
18 | | #include <LibWeb/Loader/ResourceLoader.h> |
19 | | #include <LibWeb/Page/Page.h> |
20 | | |
21 | | namespace Web::HTML { |
22 | | |
23 | | JS_DEFINE_ALLOCATOR(Navigator); |
24 | | |
25 | | JS::NonnullGCPtr<Navigator> Navigator::create(JS::Realm& realm) |
26 | 0 | { |
27 | 0 | return realm.heap().allocate<Navigator>(realm, realm); |
28 | 0 | } |
29 | | |
30 | | Navigator::Navigator(JS::Realm& realm) |
31 | 0 | : PlatformObject(realm) |
32 | 0 | { |
33 | 0 | } |
34 | | |
35 | 0 | Navigator::~Navigator() = default; |
36 | | |
37 | | void Navigator::initialize(JS::Realm& realm) |
38 | 0 | { |
39 | 0 | Base::initialize(realm); |
40 | 0 | WEB_SET_PROTOTYPE_FOR_INTERFACE(Navigator); |
41 | 0 | } |
42 | | |
43 | | // https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-pdfviewerenabled |
44 | | bool Navigator::pdf_viewer_enabled() const |
45 | 0 | { |
46 | | // The NavigatorPlugins mixin's pdfViewerEnabled getter steps are to return the user agent's PDF viewer supported. |
47 | | // NOTE: The NavigatorPlugins mixin should only be exposed on the Window object. |
48 | 0 | auto const& window = verify_cast<HTML::Window>(HTML::current_global_object()); |
49 | 0 | return window.page().pdf_viewer_supported(); |
50 | 0 | } |
51 | | |
52 | | // https://w3c.github.io/webdriver/#dfn-webdriver |
53 | | bool Navigator::webdriver() const |
54 | 0 | { |
55 | | // Returns true if webdriver-active flag is set, false otherwise. |
56 | | |
57 | | // NOTE: The NavigatorAutomationInformation interface should not be exposed on WorkerNavigator. |
58 | 0 | auto const& window = verify_cast<HTML::Window>(HTML::current_global_object()); |
59 | 0 | return window.page().is_webdriver_active(); |
60 | 0 | } |
61 | | |
62 | | void Navigator::visit_edges(Cell::Visitor& visitor) |
63 | 0 | { |
64 | 0 | Base::visit_edges(visitor); |
65 | 0 | visitor.visit(m_mime_type_array); |
66 | 0 | visitor.visit(m_plugin_array); |
67 | 0 | visitor.visit(m_clipboard); |
68 | 0 | visitor.visit(m_user_activation); |
69 | 0 | visitor.visit(m_service_worker_container); |
70 | 0 | visitor.visit(m_media_capabilities); |
71 | 0 | } |
72 | | |
73 | | JS::NonnullGCPtr<MimeTypeArray> Navigator::mime_types() |
74 | 0 | { |
75 | 0 | if (!m_mime_type_array) |
76 | 0 | m_mime_type_array = heap().allocate<MimeTypeArray>(realm(), realm()); |
77 | 0 | return *m_mime_type_array; |
78 | 0 | } |
79 | | |
80 | | JS::NonnullGCPtr<PluginArray> Navigator::plugins() |
81 | 0 | { |
82 | 0 | if (!m_plugin_array) |
83 | 0 | m_plugin_array = heap().allocate<PluginArray>(realm(), realm()); |
84 | 0 | return *m_plugin_array; |
85 | 0 | } |
86 | | |
87 | | JS::NonnullGCPtr<Clipboard::Clipboard> Navigator::clipboard() |
88 | 0 | { |
89 | 0 | if (!m_clipboard) |
90 | 0 | m_clipboard = heap().allocate<Clipboard::Clipboard>(realm(), realm()); |
91 | 0 | return *m_clipboard; |
92 | 0 | } |
93 | | |
94 | | JS::NonnullGCPtr<UserActivation> Navigator::user_activation() |
95 | 0 | { |
96 | 0 | if (!m_user_activation) |
97 | 0 | m_user_activation = heap().allocate<UserActivation>(realm(), realm()); |
98 | 0 | return *m_user_activation; |
99 | 0 | } |
100 | | |
101 | | // https://w3c.github.io/pointerevents/#dom-navigator-maxtouchpoints |
102 | | WebIDL::Long Navigator::max_touch_points() |
103 | 0 | { |
104 | 0 | dbgln("FIXME: Unimplemented Navigator.maxTouchPoints"); |
105 | 0 | return 0; |
106 | 0 | } |
107 | | |
108 | | // https://www.w3.org/TR/tracking-dnt/#dom-navigator-donottrack |
109 | | Optional<FlyString> Navigator::do_not_track() const |
110 | 0 | { |
111 | | // The value is null if no DNT header field would be sent (e.g., because a tracking preference is not |
112 | | // enabled and no user-granted exception is applicable); otherwise, the value is a string beginning with |
113 | | // "0" or "1", possibly followed by DNT-extension characters. |
114 | 0 | if (ResourceLoader::the().enable_do_not_track()) |
115 | 0 | return "1"_fly_string; |
116 | | |
117 | 0 | return {}; |
118 | 0 | } |
119 | | |
120 | | JS::NonnullGCPtr<ServiceWorkerContainer> Navigator::service_worker() |
121 | 0 | { |
122 | 0 | if (!m_service_worker_container) |
123 | 0 | m_service_worker_container = heap().allocate<ServiceWorkerContainer>(realm(), realm()); |
124 | 0 | return *m_service_worker_container; |
125 | 0 | } |
126 | | |
127 | | JS::NonnullGCPtr<MediaCapabilitiesAPI::MediaCapabilities> Navigator::media_capabilities() |
128 | 0 | { |
129 | 0 | if (!m_media_capabilities) |
130 | 0 | m_media_capabilities = heap().allocate<MediaCapabilitiesAPI::MediaCapabilities>(realm(), realm()); |
131 | 0 | return *m_media_capabilities; |
132 | 0 | } |
133 | | |
134 | | } |