mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 04:47:36 +00:00
LibWeb: Implement navigator.{plugins,mimeTypes}
This commit is contained in:
parent
5e422bdae0
commit
4d0277cd9a
20 changed files with 767 additions and 4 deletions
|
@ -270,6 +270,8 @@ set(SOURCES
|
|||
HTML/MessageChannel.cpp
|
||||
HTML/MessageEvent.cpp
|
||||
HTML/MessagePort.cpp
|
||||
HTML/MimeType.cpp
|
||||
HTML/MimeTypeArray.cpp
|
||||
HTML/Navigator.cpp
|
||||
HTML/NavigatorID.cpp
|
||||
HTML/PageTransitionEvent.cpp
|
||||
|
@ -281,6 +283,8 @@ set(SOURCES
|
|||
HTML/Parser/ListOfActiveFormattingElements.cpp
|
||||
HTML/Parser/StackOfOpenElements.cpp
|
||||
HTML/Path2D.cpp
|
||||
HTML/Plugin.cpp
|
||||
HTML/PluginArray.cpp
|
||||
HTML/PromiseRejectionEvent.cpp
|
||||
HTML/Scripting/ClassicScript.cpp
|
||||
HTML/Scripting/Environments.cpp
|
||||
|
|
|
@ -328,11 +328,15 @@ class Location;
|
|||
class MessageChannel;
|
||||
class MessageEvent;
|
||||
class MessagePort;
|
||||
class MimeType;
|
||||
class MimeTypeArray;
|
||||
struct NavigationParams;
|
||||
class Navigator;
|
||||
class Origin;
|
||||
class PageTransitionEvent;
|
||||
class Path2D;
|
||||
class Plugin;
|
||||
class PluginArray;
|
||||
struct PolicyContainer;
|
||||
class PromiseRejectionEvent;
|
||||
class WorkerDebugConsoleClient;
|
||||
|
|
65
Userland/Libraries/LibWeb/HTML/MimeType.cpp
Normal file
65
Userland/Libraries/LibWeb/HTML/MimeType.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/MimeType.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
MimeType::MimeType(JS::Realm& realm, String const& type)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
MimeType::~MimeType() = default;
|
||||
|
||||
JS::ThrowCompletionOr<void> MimeType::initialize(JS::Realm& realm)
|
||||
{
|
||||
MUST_OR_THROW_OOM(Base::initialize(realm));
|
||||
set_prototype(&Bindings::ensure_web_prototype<Bindings::MimeTypePrototype>(realm, "MimeType"));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#concept-mimetype-type
|
||||
String const& MimeType::type() const
|
||||
{
|
||||
// The MimeType interface's type getter steps are to return this's type.
|
||||
return m_type;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetype-description
|
||||
JS::ThrowCompletionOr<String> MimeType::description() const
|
||||
{
|
||||
// The MimeType interface's description getter steps are to return "Portable Document Format".
|
||||
static String description_string = TRY_OR_THROW_OOM(vm(), String::from_utf8("Portable Document Format"sv));
|
||||
return description_string;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetype-suffixes
|
||||
String const& MimeType::suffixes() const
|
||||
{
|
||||
// The MimeType interface's suffixes getter steps are to return "pdf".
|
||||
static String suffixes_string = String::from_utf8_short_string("pdf"sv);
|
||||
return suffixes_string;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetype-enabledplugin
|
||||
JS::NonnullGCPtr<Plugin> MimeType::enabled_plugin() const
|
||||
{
|
||||
// The MimeType interface's enabledPlugin getter steps are to return this's relevant global object's PDF viewer plugin objects[0] (i.e., the generic "PDF Viewer" one).
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto plugin_objects = window.pdf_viewer_plugin_objects();
|
||||
|
||||
// NOTE: If a MimeType object was created, that means PDF viewer support is enabled, meaning there will be Plugin objects.
|
||||
VERIFY(!plugin_objects.is_empty());
|
||||
return plugin_objects.first();
|
||||
}
|
||||
|
||||
}
|
34
Userland/Libraries/LibWeb/HTML/MimeType.h
Normal file
34
Userland/Libraries/LibWeb/HTML/MimeType.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/LegacyPlatformObject.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#mimetype
|
||||
class MimeType : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(MimeType, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~MimeType() override;
|
||||
|
||||
String const& type() const;
|
||||
JS::ThrowCompletionOr<String> description() const;
|
||||
String const& suffixes() const;
|
||||
JS::NonnullGCPtr<Plugin> enabled_plugin() const;
|
||||
|
||||
private:
|
||||
MimeType(JS::Realm&, String const& type);
|
||||
|
||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#concept-mimetype-type
|
||||
String m_type;
|
||||
};
|
||||
|
||||
}
|
9
Userland/Libraries/LibWeb/HTML/MimeType.idl
Normal file
9
Userland/Libraries/LibWeb/HTML/MimeType.idl
Normal file
|
@ -0,0 +1,9 @@
|
|||
#import <HTML/Plugin.idl>
|
||||
|
||||
[Exposed=Window, UseNewAKString]
|
||||
interface MimeType {
|
||||
readonly attribute DOMString type;
|
||||
readonly attribute DOMString description;
|
||||
readonly attribute DOMString suffixes;
|
||||
readonly attribute Plugin enabledPlugin;
|
||||
};
|
112
Userland/Libraries/LibWeb/HTML/MimeTypeArray.cpp
Normal file
112
Userland/Libraries/LibWeb/HTML/MimeTypeArray.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/MimeTypeArray.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
MimeTypeArray::MimeTypeArray(JS::Realm& realm)
|
||||
: Bindings::LegacyPlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
MimeTypeArray::~MimeTypeArray() = default;
|
||||
|
||||
JS::ThrowCompletionOr<void> MimeTypeArray::initialize(JS::Realm& realm)
|
||||
{
|
||||
MUST_OR_THROW_OOM(Base::initialize(realm));
|
||||
set_prototype(&Bindings::ensure_web_prototype<Bindings::MimeTypeArrayPrototype>(realm, "MimeTypeArray"));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:support-named-properties-2
|
||||
Vector<DeprecatedString> MimeTypeArray::supported_property_names() const
|
||||
{
|
||||
// The MimeTypeArray interface supports named properties. If the user agent's PDF viewer supported is true, then they are the PDF viewer mime types. Otherwise, they are the empty list.
|
||||
auto const& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
VERIFY(window.page());
|
||||
if (!window.page()->pdf_viewer_supported())
|
||||
return {};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-types
|
||||
static Vector<DeprecatedString> mime_types = {
|
||||
"application/pdf"sv,
|
||||
"text/pdf"sv,
|
||||
};
|
||||
|
||||
return mime_types;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:supports-indexed-properties-2
|
||||
bool MimeTypeArray::is_supported_property_index(u32 index) const
|
||||
{
|
||||
// The MimeTypeArray interface supports indexed properties. The supported property indices are the indices of this's relevant global object's PDF viewer mime type objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return index < window.pdf_viewer_mime_type_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetypearray-length
|
||||
size_t MimeTypeArray::length() const
|
||||
{
|
||||
// The MimeTypeArray interface's length getter steps are to return this's relevant global object's PDF viewer mime type objects's size.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return window.pdf_viewer_mime_type_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetypearray-item
|
||||
JS::GCPtr<MimeType> MimeTypeArray::item(u32 index) const
|
||||
{
|
||||
// 1. Let mimeTypes be this's relevant global object's PDF viewer mime type objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto mime_types = window.pdf_viewer_mime_type_objects();
|
||||
|
||||
// 2. If index < mimeType's size, then return mimeTypes[index].
|
||||
if (index < mime_types.size())
|
||||
return mime_types[index];
|
||||
|
||||
// 3. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetypearray-nameditem
|
||||
JS::GCPtr<MimeType> MimeTypeArray::named_item(String const& name) const
|
||||
{
|
||||
// 1. For each MimeType mimeType of this's relevant global object's PDF viewer mime type objects: if mimeType's type is name, then return mimeType.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto mime_types = window.pdf_viewer_mime_type_objects();
|
||||
|
||||
for (auto& mime_type : mime_types) {
|
||||
if (mime_type->type() == name)
|
||||
return mime_type;
|
||||
}
|
||||
|
||||
// 2. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> MimeTypeArray::item_value(size_t index) const
|
||||
{
|
||||
auto return_value = item(index);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> MimeTypeArray::named_item_value(DeprecatedFlyString const& name) const
|
||||
{
|
||||
auto converted_name = TRY_OR_THROW_OOM(vm(), String::from_deprecated_string(name));
|
||||
auto return_value = named_item(converted_name);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
}
|
48
Userland/Libraries/LibWeb/HTML/MimeTypeArray.h
Normal file
48
Userland/Libraries/LibWeb/HTML/MimeTypeArray.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/LegacyPlatformObject.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#mimetypearray
|
||||
class MimeTypeArray : public Bindings::LegacyPlatformObject {
|
||||
WEB_PLATFORM_OBJECT(MimeTypeArray, Bindings::LegacyPlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~MimeTypeArray() override;
|
||||
|
||||
size_t length() const;
|
||||
JS::GCPtr<MimeType> item(u32 index) const;
|
||||
JS::GCPtr<MimeType> named_item(String const& name) const;
|
||||
|
||||
private:
|
||||
MimeTypeArray(JS::Realm&);
|
||||
|
||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||
|
||||
// ^Bindings::LegacyPlatformObject
|
||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override;
|
||||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
virtual bool supports_indexed_properties() const override { return true; }
|
||||
virtual bool supports_named_properties() const override { return true; }
|
||||
virtual bool has_indexed_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_deleter() const override { return false; }
|
||||
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; }
|
||||
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||
};
|
||||
|
||||
}
|
8
Userland/Libraries/LibWeb/HTML/MimeTypeArray.idl
Normal file
8
Userland/Libraries/LibWeb/HTML/MimeTypeArray.idl
Normal file
|
@ -0,0 +1,8 @@
|
|||
#import <HTML/MimeType.idl>
|
||||
|
||||
[Exposed=Window, LegacyUnenumerableNamedProperties, UseNewAKString]
|
||||
interface MimeTypeArray {
|
||||
readonly attribute unsigned long length;
|
||||
getter MimeType? item(unsigned long index);
|
||||
getter MimeType? namedItem(DOMString name);
|
||||
};
|
|
@ -39,7 +39,7 @@ JS::ThrowCompletionOr<void> Navigator::initialize(JS::Realm& realm)
|
|||
bool Navigator::pdf_viewer_enabled() const
|
||||
{
|
||||
// The NavigatorPlugins mixin's pdfViewerEnabled getter steps are to return the user agent's PDF viewer supported.
|
||||
// NOTE: THe NavigatorPlugins mixin should only be exposed on the Window object.
|
||||
// NOTE: The NavigatorPlugins mixin should only be exposed on the Window object.
|
||||
auto const& window = verify_cast<HTML::Window>(HTML::current_global_object());
|
||||
return window.page()->pdf_viewer_supported();
|
||||
}
|
||||
|
@ -54,4 +54,25 @@ bool Navigator::webdriver() const
|
|||
return window.page()->is_webdriver_active();
|
||||
}
|
||||
|
||||
void Navigator::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_mime_type_array);
|
||||
visitor.visit(m_plugin_array);
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<JS::NonnullGCPtr<MimeTypeArray>> Navigator::mime_types()
|
||||
{
|
||||
if (!m_mime_type_array)
|
||||
m_mime_type_array = TRY(heap().allocate<MimeTypeArray>(realm(), realm()));
|
||||
return *m_mime_type_array;
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<JS::NonnullGCPtr<PluginArray>> Navigator::plugins()
|
||||
{
|
||||
if (!m_plugin_array)
|
||||
m_plugin_array = TRY(heap().allocate<PluginArray>(realm(), realm()));
|
||||
return *m_plugin_array;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/HTML/MimeTypeArray.h>
|
||||
#include <LibWeb/HTML/NavigatorConcurrentHardware.h>
|
||||
#include <LibWeb/HTML/NavigatorID.h>
|
||||
#include <LibWeb/HTML/NavigatorLanguage.h>
|
||||
#include <LibWeb/HTML/NavigatorOnLine.h>
|
||||
#include <LibWeb/HTML/PluginArray.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
@ -35,17 +37,25 @@ public:
|
|||
// 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;
|
||||
|
||||
bool webdriver() const;
|
||||
|
||||
JS::ThrowCompletionOr<JS::NonnullGCPtr<MimeTypeArray>> mime_types();
|
||||
JS::ThrowCompletionOr<JS::NonnullGCPtr<PluginArray>> plugins();
|
||||
|
||||
virtual ~Navigator() override;
|
||||
|
||||
protected:
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
explicit Navigator(JS::Realm&);
|
||||
|
||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||
|
||||
JS::GCPtr<PluginArray> m_plugin_array;
|
||||
JS::GCPtr<MimeTypeArray> m_mime_type_array;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#import <HTML/MimeTypeArray.idl>
|
||||
#import <HTML/NavigatorID.idl>
|
||||
#import <HTML/NavigatorLanguage.idl>
|
||||
#import <HTML/NavigatorOnLine.idl>
|
||||
#import <HTML/NavigatorConcurrentHardware.idl>
|
||||
#import <HTML/PluginArray.idl>
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#navigator
|
||||
[Exposed=Window]
|
||||
|
@ -25,8 +27,8 @@ interface mixin NavigatorCookies {
|
|||
|
||||
// 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;
|
||||
[SameObject] readonly attribute PluginArray plugins;
|
||||
[SameObject] readonly attribute MimeTypeArray mimeTypes;
|
||||
boolean javaEnabled();
|
||||
readonly attribute boolean pdfViewerEnabled;
|
||||
};
|
||||
|
|
135
Userland/Libraries/LibWeb/HTML/Plugin.cpp
Normal file
135
Userland/Libraries/LibWeb/HTML/Plugin.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/Plugin.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
Plugin::Plugin(JS::Realm& realm, String const& name)
|
||||
: Bindings::LegacyPlatformObject(realm)
|
||||
, m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
Plugin::~Plugin() = default;
|
||||
|
||||
JS::ThrowCompletionOr<void> Plugin::initialize(JS::Realm& realm)
|
||||
{
|
||||
MUST_OR_THROW_OOM(Base::initialize(realm));
|
||||
set_prototype(&Bindings::ensure_web_prototype<Bindings::PluginPrototype>(realm, "Plugin"));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-name
|
||||
String const& Plugin::name() const
|
||||
{
|
||||
// The Plugin interface's name getter steps are to return this's name.
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-description
|
||||
JS::ThrowCompletionOr<String> Plugin::description() const
|
||||
{
|
||||
// The Plugin interface's description getter steps are to return "Portable Document Format".
|
||||
static String description_string = TRY_OR_THROW_OOM(vm(), String::from_utf8("Portable Document Format"sv));
|
||||
return description_string;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-filename
|
||||
JS::ThrowCompletionOr<String> Plugin::filename() const
|
||||
{
|
||||
// The Plugin interface's filename getter steps are to return "internal-pdf-viewer".
|
||||
static String filename_string = TRY_OR_THROW_OOM(vm(), String::from_utf8("internal-pdf-viewer"sv));
|
||||
return filename_string;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:support-named-properties-3
|
||||
Vector<DeprecatedString> Plugin::supported_property_names() const
|
||||
{
|
||||
// The Plugin interface supports named properties. If the user agent's PDF viewer supported is true, then they are the PDF viewer mime types. Otherwise, they are the empty list.
|
||||
auto const& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
VERIFY(window.page());
|
||||
if (!window.page()->pdf_viewer_supported())
|
||||
return {};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-types
|
||||
static Vector<DeprecatedString> mime_types = {
|
||||
"application/pdf"sv,
|
||||
"text/pdf"sv,
|
||||
};
|
||||
|
||||
return mime_types;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:supports-indexed-properties-3
|
||||
bool Plugin::is_supported_property_index(u32 index) const
|
||||
{
|
||||
// The Plugin interface supports indexed properties. The supported property indices are the indices of this's relevant global object's PDF viewer mime type objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return index < window.pdf_viewer_mime_type_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-length
|
||||
size_t Plugin::length() const
|
||||
{
|
||||
// The Plugin interface's length getter steps are to return this's relevant global object's PDF viewer mime type objects's size.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return window.pdf_viewer_mime_type_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-item
|
||||
JS::GCPtr<MimeType> Plugin::item(u32 index) const
|
||||
{
|
||||
// 1. Let mimeTypes be this's relevant global object's PDF viewer mime type objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto mime_types = window.pdf_viewer_mime_type_objects();
|
||||
|
||||
// 2. If index < mimeType's size, then return mimeTypes[index].
|
||||
if (index < mime_types.size())
|
||||
return mime_types[index];
|
||||
|
||||
// 3. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::GCPtr<MimeType> Plugin::named_item(String const& name) const
|
||||
{
|
||||
// 1. For each MimeType mimeType of this's relevant global object's PDF viewer mime type objects: if mimeType's type is name, then return mimeType.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto mime_types = window.pdf_viewer_mime_type_objects();
|
||||
|
||||
for (auto& mime_type : mime_types) {
|
||||
if (mime_type->type() == name)
|
||||
return mime_type;
|
||||
}
|
||||
|
||||
// 2. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> Plugin::item_value(size_t index) const
|
||||
{
|
||||
auto return_value = item(index);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> Plugin::named_item_value(DeprecatedFlyString const& name) const
|
||||
{
|
||||
auto converted_name = TRY_OR_THROW_OOM(vm(), String::from_deprecated_string(name));
|
||||
auto return_value = named_item(converted_name);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
}
|
54
Userland/Libraries/LibWeb/HTML/Plugin.h
Normal file
54
Userland/Libraries/LibWeb/HTML/Plugin.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/LegacyPlatformObject.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin
|
||||
class Plugin : public Bindings::LegacyPlatformObject {
|
||||
WEB_PLATFORM_OBJECT(Plugin, Bindings::LegacyPlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~Plugin() override;
|
||||
|
||||
String const& name() const;
|
||||
JS::ThrowCompletionOr<String> description() const;
|
||||
JS::ThrowCompletionOr<String> filename() const;
|
||||
size_t length() const;
|
||||
JS::GCPtr<MimeType> item(u32 index) const;
|
||||
JS::GCPtr<MimeType> named_item(String const& name) const;
|
||||
|
||||
private:
|
||||
Plugin(JS::Realm&, String const& name);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#concept-plugin-name
|
||||
String m_name;
|
||||
|
||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||
|
||||
// ^Bindings::LegacyPlatformObject
|
||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override;
|
||||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
virtual bool supports_indexed_properties() const override { return true; }
|
||||
virtual bool supports_named_properties() const override { return true; }
|
||||
virtual bool has_indexed_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_deleter() const override { return false; }
|
||||
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; }
|
||||
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||
};
|
||||
|
||||
}
|
11
Userland/Libraries/LibWeb/HTML/Plugin.idl
Normal file
11
Userland/Libraries/LibWeb/HTML/Plugin.idl
Normal file
|
@ -0,0 +1,11 @@
|
|||
#import <HTML/MimeType.idl>
|
||||
|
||||
[Exposed=Window, LegacyUnenumerableNamedProperties, UseNewAKString]
|
||||
interface Plugin {
|
||||
readonly attribute DOMString name;
|
||||
readonly attribute DOMString description;
|
||||
readonly attribute DOMString filename;
|
||||
readonly attribute unsigned long length;
|
||||
getter MimeType? item(unsigned long index);
|
||||
getter MimeType? namedItem(DOMString name);
|
||||
};
|
121
Userland/Libraries/LibWeb/HTML/PluginArray.cpp
Normal file
121
Userland/Libraries/LibWeb/HTML/PluginArray.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/PluginArray.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
PluginArray::PluginArray(JS::Realm& realm)
|
||||
: Bindings::LegacyPlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
PluginArray::~PluginArray() = default;
|
||||
|
||||
JS::ThrowCompletionOr<void> PluginArray::initialize(JS::Realm& realm)
|
||||
{
|
||||
MUST_OR_THROW_OOM(Base::initialize(realm));
|
||||
set_prototype(&Bindings::ensure_web_prototype<Bindings::PluginArrayPrototype>(realm, "PluginArray"));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-pluginarray-refresh
|
||||
void PluginArray::refresh() const
|
||||
{
|
||||
// The PluginArray interface's refresh() method steps are to do nothing.
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:support-named-properties
|
||||
Vector<DeprecatedString> PluginArray::supported_property_names() const
|
||||
{
|
||||
// The PluginArray interface supports named properties. If the user agent's PDF viewer supported is true, then they are the PDF viewer plugin names. Otherwise, they are the empty list.
|
||||
auto const& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
VERIFY(window.page());
|
||||
if (!window.page()->pdf_viewer_supported())
|
||||
return {};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-names
|
||||
static Vector<DeprecatedString> plugin_names = {
|
||||
"PDF Viewer"sv,
|
||||
"Chrome PDF Viewer"sv,
|
||||
"Chromium PDF Viewer"sv,
|
||||
"Microsoft Edge PDF Viewer"sv,
|
||||
"WebKit built-in PDF"sv,
|
||||
};
|
||||
|
||||
return plugin_names;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewing-support:supports-indexed-properties
|
||||
bool PluginArray::is_supported_property_index(u32 index) const
|
||||
{
|
||||
// The PluginArray interface supports indexed properties. The supported property indices are the indices of this's relevant global object's PDF viewer plugin objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return index < window.pdf_viewer_plugin_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-pluginarray-length
|
||||
size_t PluginArray::length() const
|
||||
{
|
||||
// The PluginArray interface's length getter steps are to return this's relevant global object's PDF viewer plugin objects's size.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
return window.pdf_viewer_plugin_objects().size();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-pluginarray-item
|
||||
JS::GCPtr<Plugin> PluginArray::item(u32 index) const
|
||||
{
|
||||
// 1. Let plugins be this's relevant global object's PDF viewer plugin objects.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto plugins = window.pdf_viewer_plugin_objects();
|
||||
|
||||
// 2. If index < plugins's size, then return plugins[index].
|
||||
if (index < plugins.size())
|
||||
return plugins[index];
|
||||
|
||||
// 3. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#dom-pluginarray-nameditem
|
||||
JS::GCPtr<Plugin> PluginArray::named_item(String const& name) const
|
||||
{
|
||||
// 1. For each Plugin plugin of this's relevant global object's PDF viewer plugin objects: if plugin's name is name, then return plugin.
|
||||
auto& window = verify_cast<HTML::Window>(HTML::relevant_global_object(*this));
|
||||
auto plugins = window.pdf_viewer_plugin_objects();
|
||||
|
||||
for (auto& plugin : plugins) {
|
||||
if (plugin->name() == name)
|
||||
return plugin;
|
||||
}
|
||||
|
||||
// 2. Return null.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> PluginArray::item_value(size_t index) const
|
||||
{
|
||||
auto return_value = item(index);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> PluginArray::named_item_value(DeprecatedFlyString const& name) const
|
||||
{
|
||||
auto converted_name = TRY_OR_THROW_OOM(vm(), String::from_deprecated_string(name));
|
||||
auto return_value = named_item(converted_name);
|
||||
if (!return_value)
|
||||
return JS::js_null();
|
||||
return return_value.ptr();
|
||||
}
|
||||
|
||||
}
|
49
Userland/Libraries/LibWeb/HTML/PluginArray.h
Normal file
49
Userland/Libraries/LibWeb/HTML/PluginArray.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/LegacyPlatformObject.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pluginarray
|
||||
class PluginArray : public Bindings::LegacyPlatformObject {
|
||||
WEB_PLATFORM_OBJECT(PluginArray, Bindings::LegacyPlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~PluginArray() override;
|
||||
|
||||
void refresh() const;
|
||||
size_t length() const;
|
||||
JS::GCPtr<Plugin> item(u32 index) const;
|
||||
JS::GCPtr<Plugin> named_item(String const& name) const;
|
||||
|
||||
private:
|
||||
PluginArray(JS::Realm&);
|
||||
|
||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||
|
||||
// ^Bindings::LegacyPlatformObject
|
||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override;
|
||||
virtual bool is_supported_property_index(u32) const override;
|
||||
|
||||
virtual bool supports_indexed_properties() const override { return true; }
|
||||
virtual bool supports_named_properties() const override { return true; }
|
||||
virtual bool has_indexed_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_setter() const override { return false; }
|
||||
virtual bool has_named_property_deleter() const override { return false; }
|
||||
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; }
|
||||
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||
};
|
||||
|
||||
}
|
9
Userland/Libraries/LibWeb/HTML/PluginArray.idl
Normal file
9
Userland/Libraries/LibWeb/HTML/PluginArray.idl
Normal file
|
@ -0,0 +1,9 @@
|
|||
#import <HTML/Plugin.idl>
|
||||
|
||||
[Exposed=Window, LegacyUnenumerableNamedProperties, UseNewAKString]
|
||||
interface PluginArray {
|
||||
undefined refresh();
|
||||
readonly attribute unsigned long length;
|
||||
getter Plugin? item(unsigned long index);
|
||||
getter Plugin? namedItem(DOMString name);
|
||||
};
|
|
@ -108,6 +108,10 @@ void Window::visit_edges(JS::Cell::Visitor& visitor)
|
|||
visitor.visit(m_navigator);
|
||||
for (auto& it : m_timers)
|
||||
visitor.visit(it.value.ptr());
|
||||
for (auto& plugin_object : m_pdf_viewer_plugin_objects)
|
||||
visitor.visit(plugin_object);
|
||||
for (auto& mime_type_object : m_pdf_viewer_mime_type_objects)
|
||||
visitor.visit(mime_type_object);
|
||||
}
|
||||
|
||||
Window::~Window() = default;
|
||||
|
@ -1060,6 +1064,54 @@ HTML::BrowsingContext* Window::browsing_context()
|
|||
return m_associated_document->browsing_context();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-objects
|
||||
Vector<JS::NonnullGCPtr<Plugin>> Window::pdf_viewer_plugin_objects()
|
||||
{
|
||||
// Each Window object has a PDF viewer plugin objects list. If the user agent's PDF viewer supported is false, then it is the empty list.
|
||||
// Otherwise, it is a list containing five Plugin objects, whose names are, respectively:
|
||||
// 0. "PDF Viewer"
|
||||
// 1. "Chrome PDF Viewer"
|
||||
// 2. "Chromium PDF Viewer"
|
||||
// 3. "Microsoft Edge PDF Viewer"
|
||||
// 4. "WebKit built-in PDF"
|
||||
// The values of the above list form the PDF viewer plugin names list. https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-names
|
||||
VERIFY(page());
|
||||
if (!page()->pdf_viewer_supported())
|
||||
return {};
|
||||
|
||||
if (m_pdf_viewer_plugin_objects.is_empty()) {
|
||||
// FIXME: Remove the MUSTs and propagate the errors instead.
|
||||
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), MUST(String::from_utf8("PDF Viewer"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), MUST(String::from_utf8("Chrome PDF Viewer"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), MUST(String::from_utf8("Chromium PDF Viewer"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), MUST(String::from_utf8("Microsoft Edge PDF Viewer"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), MUST(String::from_utf8("WebKit built-in PDF"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
return m_pdf_viewer_plugin_objects;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-type-objects
|
||||
Vector<JS::NonnullGCPtr<MimeType>> Window::pdf_viewer_mime_type_objects()
|
||||
{
|
||||
// Each Window object has a PDF viewer mime type objects list. If the user agent's PDF viewer supported is false, then it is the empty list.
|
||||
// Otherwise, it is a list containing two MimeType objects, whose types are, respectively:
|
||||
// 0. "application/pdf"
|
||||
// 1. "text/pdf"
|
||||
// The values of the above list form the PDF viewer mime types list. https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-types
|
||||
VERIFY(page());
|
||||
if (!page()->pdf_viewer_supported())
|
||||
return {};
|
||||
|
||||
if (m_pdf_viewer_mime_type_objects.is_empty()) {
|
||||
// FIXME: Remove the MUSTs and propagate the errors instead.
|
||||
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), MUST(String::from_utf8("application/pdf"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), MUST(String::from_utf8("text/pdf"sv))).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
}
|
||||
|
||||
return m_pdf_viewer_mime_type_objects;
|
||||
}
|
||||
|
||||
void Window::initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <LibWeb/HTML/AnimationFrameCallbackDriver.h>
|
||||
#include <LibWeb/HTML/CrossOrigin/CrossOriginPropertyDescriptorMap.h>
|
||||
#include <LibWeb/HTML/GlobalEventHandlers.h>
|
||||
#include <LibWeb/HTML/MimeType.h>
|
||||
#include <LibWeb/HTML/Plugin.h>
|
||||
#include <LibWeb/HTML/Scripting/ImportMap.h>
|
||||
#include <LibWeb/HTML/WindowEventHandlers.h>
|
||||
|
||||
|
@ -137,6 +139,9 @@ public:
|
|||
|
||||
void initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>);
|
||||
|
||||
Vector<JS::NonnullGCPtr<Plugin>> pdf_viewer_plugin_objects();
|
||||
Vector<JS::NonnullGCPtr<MimeType>> pdf_viewer_mime_type_objects();
|
||||
|
||||
private:
|
||||
explicit Window(JS::Realm&);
|
||||
|
||||
|
@ -184,6 +189,12 @@ private:
|
|||
// https://w3c.github.io/requestidlecallback/#dfn-idle-callback-identifier
|
||||
u32 m_idle_callback_identifier = 0;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-objects
|
||||
Vector<JS::NonnullGCPtr<Plugin>> m_pdf_viewer_plugin_objects;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-type-objects
|
||||
Vector<JS::NonnullGCPtr<MimeType>> m_pdf_viewer_mime_type_objects;
|
||||
|
||||
public:
|
||||
HTML::Origin origin() const;
|
||||
|
||||
|
|
|
@ -152,9 +152,13 @@ libweb_js_bindings(HTML/Location)
|
|||
libweb_js_bindings(HTML/MessageChannel)
|
||||
libweb_js_bindings(HTML/MessageEvent)
|
||||
libweb_js_bindings(HTML/MessagePort)
|
||||
libweb_js_bindings(HTML/MimeType)
|
||||
libweb_js_bindings(HTML/MimeTypeArray)
|
||||
libweb_js_bindings(HTML/Navigator)
|
||||
libweb_js_bindings(HTML/PageTransitionEvent)
|
||||
libweb_js_bindings(HTML/Path2D)
|
||||
libweb_js_bindings(HTML/Plugin)
|
||||
libweb_js_bindings(HTML/PluginArray)
|
||||
libweb_js_bindings(HTML/PromiseRejectionEvent)
|
||||
libweb_js_bindings(HTML/Storage)
|
||||
libweb_js_bindings(HTML/SubmitEvent)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue