mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 04:17:35 +00:00
LibWeb: Re-implement HTML::Navigator using IDL
Get rid of the bespoke NavigatorObject class and use the modern IDL strategies for creating platform objects to re-implement Navigator and its associcated mixin interfaces. While we're here, implement it in a way that brings WorkerNavigator up to spec :^)
This commit is contained in:
parent
14e1513077
commit
2d5bee256e
27 changed files with 343 additions and 208 deletions
27
Userland/Libraries/LibWeb/HTML/Navigator.cpp
Normal file
27
Userland/Libraries/LibWeb/HTML/Navigator.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/Navigator.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
JS::NonnullGCPtr<Navigator> Navigator::create(JS::Realm& realm)
|
||||
{
|
||||
return *realm.heap().allocate<Navigator>(realm, realm);
|
||||
}
|
||||
|
||||
Navigator::Navigator(JS::Realm& realm)
|
||||
: PlatformObject(realm)
|
||||
{
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "Navigator"));
|
||||
}
|
||||
|
||||
Navigator::~Navigator() = default;
|
||||
|
||||
}
|
48
Userland/Libraries/LibWeb/HTML/Navigator.h
Normal file
48
Userland/Libraries/LibWeb/HTML/Navigator.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/HTML/NavigatorConcurrentHardware.h>
|
||||
#include <LibWeb/HTML/NavigatorID.h>
|
||||
#include <LibWeb/HTML/NavigatorLanguage.h>
|
||||
#include <LibWeb/HTML/NavigatorOnLine.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class Navigator : public Bindings::PlatformObject
|
||||
, public NavigatorConcurrentHardwareMixin
|
||||
, public NavigatorIDMixin
|
||||
, public NavigatorLanguageMixin
|
||||
, public NavigatorOnLineMixin {
|
||||
WEB_PLATFORM_OBJECT(Navigator, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<Navigator> create(JS::Realm&);
|
||||
|
||||
// FIXME: Implement NavigatorContentUtilsMixin
|
||||
|
||||
// NavigatorCookies
|
||||
// FIXME: Hook up to Agent level state
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-cookieenabled
|
||||
bool cookie_enabled() const { return true; }
|
||||
|
||||
// NavigatorPlugins
|
||||
// FIXME: Actually support pdf viewing
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-javaenabled
|
||||
bool java_enabled() const { return false; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-pdfviewerenabled
|
||||
bool pdf_viewer_enabled() const { return false; }
|
||||
|
||||
virtual ~Navigator() override;
|
||||
|
||||
private:
|
||||
explicit Navigator(JS::Realm&);
|
||||
};
|
||||
|
||||
}
|
41
Userland/Libraries/LibWeb/HTML/Navigator.idl
Normal file
41
Userland/Libraries/LibWeb/HTML/Navigator.idl
Normal file
|
@ -0,0 +1,41 @@
|
|||
#import <HTML/NavigatorID.idl>
|
||||
#import <HTML/NavigatorLanguage.idl>
|
||||
#import <HTML/NavigatorOnLine.idl>
|
||||
#import <HTML/NavigatorConcurrentHardware.idl>
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#navigator
|
||||
[Exposed=Window]
|
||||
interface Navigator {
|
||||
// objects implementing this interface also implement the interfaces given below
|
||||
};
|
||||
|
||||
// NOTE: As NavigatorContentUtils, NavigatorCookies, and NavigatorPlugins are not used in WorkerNavigator,
|
||||
// we define them here.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatorcontentutils
|
||||
interface mixin NavigatorContentUtils {
|
||||
// FIXME: [SecureContext] undefined registerProtocolHandler(DOMString scheme, USVString url);
|
||||
// FIXME: [SecureContext] undefined unregisterProtocolHandler(DOMString scheme, USVString url);
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatorcookies
|
||||
interface mixin NavigatorCookies {
|
||||
readonly attribute boolean cookieEnabled;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatorplugins
|
||||
interface mixin NavigatorPlugins {
|
||||
// FIXME: [SameObject] readonly attribute PluginArray plugins;
|
||||
// FIXME: [SameObject] readonly attribute MimeTypeArray mimeTypes;
|
||||
boolean javaEnabled();
|
||||
readonly attribute boolean pdfViewerEnabled;
|
||||
};
|
||||
|
||||
Navigator includes NavigatorID;
|
||||
Navigator includes NavigatorLanguage;
|
||||
Navigator includes NavigatorOnLine;
|
||||
Navigator includes NavigatorContentUtils;
|
||||
Navigator includes NavigatorCookies;
|
||||
Navigator includes NavigatorPlugins;
|
||||
Navigator includes NavigatorConcurrentHardware;
|
||||
|
17
Userland/Libraries/LibWeb/HTML/NavigatorConcurrentHardware.h
Normal file
17
Userland/Libraries/LibWeb/HTML/NavigatorConcurrentHardware.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class NavigatorConcurrentHardwareMixin {
|
||||
public:
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#dom-navigator-hardwareconcurrency
|
||||
unsigned long long hardware_concurrency() { return 1; }
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
// https://html.spec.whatwg.org/multipage/workers.html#navigatorconcurrenthardware
|
||||
interface mixin NavigatorConcurrentHardware {
|
||||
readonly attribute unsigned long long hardwareConcurrency;
|
||||
};
|
53
Userland/Libraries/LibWeb/HTML/NavigatorID.cpp
Normal file
53
Userland/Libraries/LibWeb/HTML/NavigatorID.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/HTML/NavigatorID.h>
|
||||
#include <LibWeb/Loader/ResourceLoader.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-appversion
|
||||
String NavigatorIDMixin::app_version() const
|
||||
{
|
||||
// Must return the appropriate string that starts with "5.0 (", as follows:
|
||||
|
||||
// Let trail be the substring of default `User-Agent` value that follows the "Mozilla/" prefix.
|
||||
auto user_agent_string = ResourceLoader::the().user_agent();
|
||||
|
||||
auto trail = user_agent_string.substring_view(strlen("Mozilla/"), user_agent_string.length() - strlen("Mozilla/"));
|
||||
|
||||
// If the navigator compatibility mode is Chrome or WebKit
|
||||
// NOTE: We are using Chrome for now. Make sure to update all APIs if you add a toggle for this.
|
||||
|
||||
// Return trail.
|
||||
return trail;
|
||||
|
||||
// If the navigator compatibility mode is Gecko
|
||||
// If trail starts with "5.0 (Windows", then return "5.0 (Windows)".
|
||||
// Otherwise, return the prefix of trail up to but not including the first U+003B (;), concatenated with the
|
||||
// character U+0029 RIGHT PARENTHESIS. For example, "5.0 (Macintosh)", "5.0 (Android 10)", or "5.0 (X11)".
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-platform
|
||||
String NavigatorIDMixin::platform() const
|
||||
{
|
||||
// Must return a string representing the platform on which the browser is executing (e.g. "MacIntel", "Win32",
|
||||
// "Linux x86_64", "Linux armv81") or, for privacy and compatibility, a string that is commonly returned on another
|
||||
// platform.
|
||||
|
||||
// FIXME: Use some portion of the user agent string to make spoofing work 100%
|
||||
return "SerenityOS";
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-useragent
|
||||
String NavigatorIDMixin::user_agent() const
|
||||
{
|
||||
// Must return the default `User-Agent` value.
|
||||
return ResourceLoader::the().user_agent();
|
||||
}
|
||||
|
||||
}
|
51
Userland/Libraries/LibWeb/HTML/NavigatorID.h
Normal file
51
Userland/Libraries/LibWeb/HTML/NavigatorID.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class NavigatorIDMixin {
|
||||
public:
|
||||
// WARNING: Any information in this API that varies from user to user can be used to profile the user. In fact, if
|
||||
// enough such information is available, a user can actually be uniquely identified. For this reason, user agent
|
||||
// implementers are strongly urged to include as little information in this API as possible.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-appcodename
|
||||
String app_code_name() const { return "Mozilla"sv; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-appcodename
|
||||
String app_name() const { return "Netscape"sv; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-appversion
|
||||
String app_version() const;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-platform
|
||||
String platform() const;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-product
|
||||
String product() const { return "Gecko"sv; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-productsub
|
||||
String product_sub() const { return "20030107"sv; } // Compatability mode "Chrome"
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-useragent
|
||||
String user_agent() const;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-vendor
|
||||
String vendor() const { return "Google Inc."sv; } // Compatability mode "Chrome"
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-vendorsub
|
||||
String vendor_sub() const { return ""sv; }
|
||||
|
||||
// NOTE: If the navigator compatibility mode is Gecko, then the user agent must also support the following partial interface:
|
||||
// bool taint_enabled()
|
||||
// String oscpu()
|
||||
};
|
||||
|
||||
}
|
12
Userland/Libraries/LibWeb/HTML/NavigatorID.idl
Normal file
12
Userland/Libraries/LibWeb/HTML/NavigatorID.idl
Normal file
|
@ -0,0 +1,12 @@
|
|||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatorid
|
||||
interface mixin NavigatorID {
|
||||
readonly attribute DOMString appCodeName; // constant "Mozilla"
|
||||
readonly attribute DOMString appName; // constant "Netscape"
|
||||
readonly attribute DOMString appVersion;
|
||||
readonly attribute DOMString platform;
|
||||
readonly attribute DOMString product; // constant "Gecko"
|
||||
[Exposed=Window] readonly attribute DOMString productSub;
|
||||
readonly attribute DOMString userAgent;
|
||||
[Exposed=Window] readonly attribute DOMString vendor;
|
||||
[Exposed=Window] readonly attribute DOMString vendorSub; // constant ""
|
||||
};
|
28
Userland/Libraries/LibWeb/HTML/NavigatorLanguage.h
Normal file
28
Userland/Libraries/LibWeb/HTML/NavigatorLanguage.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class NavigatorLanguageMixin {
|
||||
public:
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-language
|
||||
String language() const { return m_current_preferred_languages[0]; }
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-languages
|
||||
// FIXME: The same object must be returned until the user agent needs to return different values, or values in a
|
||||
// different order.
|
||||
Vector<String> languages() const { return m_current_preferred_languages; }
|
||||
|
||||
protected:
|
||||
Vector<String> m_current_preferred_languages = { "en-US" };
|
||||
};
|
||||
|
||||
}
|
7
Userland/Libraries/LibWeb/HTML/NavigatorLanguage.idl
Normal file
7
Userland/Libraries/LibWeb/HTML/NavigatorLanguage.idl
Normal file
|
@ -0,0 +1,7 @@
|
|||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatorlanguage
|
||||
interface mixin NavigatorLanguage {
|
||||
readonly attribute DOMString language;
|
||||
// FIXME: readonly attribute FrozenArray<DOMString> languages;
|
||||
// This is supposed to be a FrozenArray that always returns the same object
|
||||
sequence<DOMString> languages();
|
||||
};
|
18
Userland/Libraries/LibWeb/HTML/NavigatorOnLine.h
Normal file
18
Userland/Libraries/LibWeb/HTML/NavigatorOnLine.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
class NavigatorOnLineMixin {
|
||||
public:
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-online
|
||||
// FIXME: Reflect actual connectivity status.
|
||||
bool on_line() const { return true; }
|
||||
};
|
||||
|
||||
}
|
4
Userland/Libraries/LibWeb/HTML/NavigatorOnLine.idl
Normal file
4
Userland/Libraries/LibWeb/HTML/NavigatorOnLine.idl
Normal file
|
@ -0,0 +1,4 @@
|
|||
// https://html.spec.whatwg.org/multipage/system-state.html#navigatoronline
|
||||
interface mixin NavigatorOnLine {
|
||||
readonly attribute boolean onLine;
|
||||
};
|
|
@ -17,7 +17,6 @@
|
|||
#include <LibWeb/Bindings/CSSNamespace.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/LocationObject.h>
|
||||
#include <LibWeb/Bindings/NavigatorObject.h>
|
||||
#include <LibWeb/Bindings/Replaceable.h>
|
||||
#include <LibWeb/Bindings/WindowExposedInterfaces.h>
|
||||
#include <LibWeb/Bindings/WindowPrototype.h>
|
||||
|
@ -33,6 +32,7 @@
|
|||
#include <LibWeb/HTML/EventHandler.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/MessageEvent.h>
|
||||
#include <LibWeb/HTML/Navigator.h>
|
||||
#include <LibWeb/HTML/Origin.h>
|
||||
#include <LibWeb/HTML/PageTransitionEvent.h>
|
||||
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
||||
|
@ -95,6 +95,7 @@ void Window::visit_edges(JS::Cell::Visitor& visitor)
|
|||
visitor.visit(m_screen.ptr());
|
||||
visitor.visit(m_location_object);
|
||||
visitor.visit(m_crypto);
|
||||
visitor.visit(m_navigator);
|
||||
for (auto& it : m_timers)
|
||||
visitor.visit(it.value.ptr());
|
||||
}
|
||||
|
@ -813,9 +814,9 @@ void Window::initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>)
|
|||
|
||||
m_location_object = heap().allocate<Bindings::LocationObject>(realm, realm);
|
||||
|
||||
auto* m_navigator_object = heap().allocate<Bindings::NavigatorObject>(realm, realm);
|
||||
define_direct_property("navigator", m_navigator_object, JS::Attribute::Enumerable | JS::Attribute::Configurable);
|
||||
define_direct_property("clientInformation", m_navigator_object, JS::Attribute::Enumerable | JS::Attribute::Configurable);
|
||||
m_navigator = heap().allocate<HTML::Navigator>(realm, realm);
|
||||
define_direct_property("navigator", m_navigator, JS::Attribute::Enumerable | JS::Attribute::Configurable);
|
||||
define_direct_property("clientInformation", m_navigator, JS::Attribute::Enumerable | JS::Attribute::Configurable);
|
||||
|
||||
// NOTE: location is marked as [LegacyUnforgeable], meaning it isn't configurable.
|
||||
define_native_accessor(realm, "location", location_getter, location_setter, JS::Attribute::Enumerable);
|
||||
|
|
|
@ -157,6 +157,7 @@ private:
|
|||
JS::GCPtr<HighResolutionTime::Performance> m_performance;
|
||||
JS::GCPtr<Crypto::Crypto> m_crypto;
|
||||
JS::GCPtr<CSS::Screen> m_screen;
|
||||
JS::GCPtr<HTML::Navigator> m_navigator;
|
||||
|
||||
AnimationFrameCallbackDriver m_animation_frame_callback_driver;
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ private:
|
|||
|
||||
JS::GCPtr<WorkerLocation> m_location;
|
||||
|
||||
// FIXME: Implement WorkerNavigator according to the spec
|
||||
JS::GCPtr<WorkerNavigator> m_navigator;
|
||||
|
||||
// FIXME: Add all these internal slots
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/WorkerGlobalScope.h>
|
||||
#include <LibWeb/HTML/WorkerNavigator.h>
|
||||
|
||||
|
@ -18,7 +19,7 @@ JS::NonnullGCPtr<WorkerNavigator> WorkerNavigator::create(WorkerGlobalScope& glo
|
|||
WorkerNavigator::WorkerNavigator(WorkerGlobalScope& global_scope)
|
||||
: PlatformObject(global_scope.realm())
|
||||
{
|
||||
// FIXME: Set prototype once we can get to worker scope prototypes.
|
||||
set_prototype(&Bindings::cached_web_prototype(global_scope.realm(), "WorkerNavigator"));
|
||||
}
|
||||
|
||||
WorkerNavigator::~WorkerNavigator() = default;
|
||||
|
|
|
@ -7,11 +7,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/HTML/NavigatorConcurrentHardware.h>
|
||||
#include <LibWeb/HTML/NavigatorID.h>
|
||||
#include <LibWeb/HTML/NavigatorLanguage.h>
|
||||
#include <LibWeb/HTML/NavigatorOnLine.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// FIXME: Add Mixin APIs from https://html.spec.whatwg.org/multipage/workers.html#the-workernavigator-object
|
||||
class WorkerNavigator : public Bindings::PlatformObject {
|
||||
class WorkerNavigator : public Bindings::PlatformObject
|
||||
, public NavigatorConcurrentHardwareMixin
|
||||
, public NavigatorIDMixin
|
||||
, public NavigatorLanguageMixin
|
||||
, public NavigatorOnLineMixin {
|
||||
WEB_PLATFORM_OBJECT(WorkerNavigator, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#import <HTML/NavigatorID.idl>
|
||||
#import <HTML/NavigatorLanguage.idl>
|
||||
#import <HTML/NavigatorOnLine.idl>
|
||||
#import <HTML/NavigatorConcurrentHardware.idl>
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#workernavigator
|
||||
[Exposed=Worker]
|
||||
interface WorkerNavigator {};
|
||||
|
||||
// FIXME: Add these mixins that are used to prevent duplication b/w WorkerNavigator and Navigator
|
||||
// WorkerNavigator includes NavigatorID;
|
||||
// WorkerNavigator includes NavigatorLanguage;
|
||||
// WorkerNavigator includes NavigatorOnLine;
|
||||
// WorkerNavigator includes NavigatorConcurrentHardware;
|
||||
WorkerNavigator includes NavigatorID;
|
||||
WorkerNavigator includes NavigatorLanguage;
|
||||
WorkerNavigator includes NavigatorOnLine;
|
||||
WorkerNavigator includes NavigatorConcurrentHardware;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue