mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
Ladybird+LibWeb+WebContent: Generalize video context menus for all media
The data we want to send out of the WebContent process is identical for audio and video elements. Rather than just duplicating all of this for audio, generalize the names used for this IPC for all media elements. This also encapsulates that data into a struct. This makes adding new fields to be sent much easier (such as an upcoming field for muting the element).
This commit is contained in:
parent
e81abbde7b
commit
14ca04de25
Notes:
sideshowbarker
2024-07-17 03:45:48 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/14ca04de25 Pull-request: https://github.com/SerenityOS/serenity/pull/19423
17 changed files with 198 additions and 147 deletions
|
@ -374,49 +374,49 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::
|
|||
m_image_context_menu->exec(screen_position);
|
||||
};
|
||||
|
||||
m_video_context_menu_play_icon = make<QIcon>(QString("%1/res/icons/16x16/play.png").arg(s_serenity_resource_root.characters()));
|
||||
m_video_context_menu_pause_icon = make<QIcon>(QString("%1/res/icons/16x16/pause.png").arg(s_serenity_resource_root.characters()));
|
||||
m_media_context_menu_play_icon = make<QIcon>(QString("%1/res/icons/16x16/play.png").arg(s_serenity_resource_root.characters()));
|
||||
m_media_context_menu_pause_icon = make<QIcon>(QString("%1/res/icons/16x16/pause.png").arg(s_serenity_resource_root.characters()));
|
||||
|
||||
m_video_context_menu_play_pause_action = make<QAction>("&Play", this);
|
||||
m_video_context_menu_play_pause_action->setIcon(*m_video_context_menu_play_icon);
|
||||
QObject::connect(m_video_context_menu_play_pause_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_video_play_state();
|
||||
m_media_context_menu_play_pause_action = make<QAction>("&Play", this);
|
||||
m_media_context_menu_play_pause_action->setIcon(*m_media_context_menu_play_icon);
|
||||
QObject::connect(m_media_context_menu_play_pause_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_media_play_state();
|
||||
});
|
||||
|
||||
m_video_context_menu_controls_action = make<QAction>("Show &Controls", this);
|
||||
m_video_context_menu_controls_action->setCheckable(true);
|
||||
QObject::connect(m_video_context_menu_controls_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_video_controls_state();
|
||||
m_media_context_menu_controls_action = make<QAction>("Show &Controls", this);
|
||||
m_media_context_menu_controls_action->setCheckable(true);
|
||||
QObject::connect(m_media_context_menu_controls_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_media_controls_state();
|
||||
});
|
||||
|
||||
m_video_context_menu_loop_action = make<QAction>("&Loop Video", this);
|
||||
m_video_context_menu_loop_action->setCheckable(true);
|
||||
QObject::connect(m_video_context_menu_loop_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_video_loop_state();
|
||||
m_media_context_menu_loop_action = make<QAction>("&Loop", this);
|
||||
m_media_context_menu_loop_action->setCheckable(true);
|
||||
QObject::connect(m_media_context_menu_loop_action, &QAction::triggered, this, [this]() {
|
||||
view().toggle_media_loop_state();
|
||||
});
|
||||
|
||||
auto* open_video_action = new QAction("&Open Video", this);
|
||||
open_video_action->setIcon(QIcon(QString("%1/res/icons/16x16/filetype-video.png").arg(s_serenity_resource_root.characters())));
|
||||
QObject::connect(open_video_action, &QAction::triggered, this, [this]() {
|
||||
open_link(m_video_context_menu_url);
|
||||
open_link(m_media_context_menu_url);
|
||||
});
|
||||
|
||||
auto* open_video_in_new_tab_action = new QAction("Open Video in New &Tab", this);
|
||||
open_video_in_new_tab_action->setIcon(QIcon(QString("%1/res/icons/16x16/new-tab.png").arg(s_serenity_resource_root.characters())));
|
||||
QObject::connect(open_video_in_new_tab_action, &QAction::triggered, this, [this]() {
|
||||
open_link_in_new_tab(m_video_context_menu_url);
|
||||
open_link_in_new_tab(m_media_context_menu_url);
|
||||
});
|
||||
|
||||
auto* copy_video_url_action = new QAction("Copy Video &URL", this);
|
||||
copy_video_url_action->setIcon(QIcon(QString("%1/res/icons/16x16/edit-copy.png").arg(s_serenity_resource_root.characters())));
|
||||
QObject::connect(copy_video_url_action, &QAction::triggered, this, [this]() {
|
||||
copy_link_url(m_video_context_menu_url);
|
||||
copy_link_url(m_media_context_menu_url);
|
||||
});
|
||||
|
||||
m_video_context_menu = make<QMenu>("Video context menu", this);
|
||||
m_video_context_menu->addAction(m_video_context_menu_play_pause_action);
|
||||
m_video_context_menu->addAction(m_video_context_menu_controls_action);
|
||||
m_video_context_menu->addAction(m_video_context_menu_loop_action);
|
||||
m_video_context_menu->addAction(m_media_context_menu_play_pause_action);
|
||||
m_video_context_menu->addAction(m_media_context_menu_controls_action);
|
||||
m_video_context_menu->addAction(m_media_context_menu_loop_action);
|
||||
m_video_context_menu->addSeparator();
|
||||
m_video_context_menu->addAction(open_video_action);
|
||||
m_video_context_menu->addAction(open_video_in_new_tab_action);
|
||||
|
@ -425,22 +425,24 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::
|
|||
m_video_context_menu->addSeparator();
|
||||
m_video_context_menu->addAction(&m_window->inspect_dom_node_action());
|
||||
|
||||
view().on_video_context_menu_request = [this](auto const& video_url, Gfx::IntPoint, bool is_playing, bool has_user_agent_controls, bool is_looping) {
|
||||
m_video_context_menu_url = video_url;
|
||||
view().on_media_context_menu_request = [this](Gfx::IntPoint, Web::Page::MediaContextMenu const& menu) {
|
||||
m_media_context_menu_url = menu.media_url;
|
||||
|
||||
if (is_playing) {
|
||||
m_video_context_menu_play_pause_action->setIcon(*m_video_context_menu_play_icon);
|
||||
m_video_context_menu_play_pause_action->setText("&Play");
|
||||
if (menu.is_playing) {
|
||||
m_media_context_menu_play_pause_action->setIcon(*m_media_context_menu_pause_icon);
|
||||
m_media_context_menu_play_pause_action->setText("&Pause");
|
||||
} else {
|
||||
m_video_context_menu_play_pause_action->setIcon(*m_video_context_menu_pause_icon);
|
||||
m_video_context_menu_play_pause_action->setText("&Pause");
|
||||
m_media_context_menu_play_pause_action->setIcon(*m_media_context_menu_play_icon);
|
||||
m_media_context_menu_play_pause_action->setText("&Play");
|
||||
}
|
||||
|
||||
m_video_context_menu_controls_action->setChecked(has_user_agent_controls);
|
||||
m_video_context_menu_loop_action->setChecked(is_looping);
|
||||
m_media_context_menu_controls_action->setChecked(menu.has_user_agent_controls);
|
||||
m_media_context_menu_loop_action->setChecked(menu.is_looping);
|
||||
|
||||
auto screen_position = QCursor::pos();
|
||||
m_video_context_menu->exec(screen_position);
|
||||
|
||||
if (menu.is_video)
|
||||
m_video_context_menu->exec(screen_position);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -97,12 +97,12 @@ private:
|
|||
URL m_image_context_menu_url;
|
||||
|
||||
OwnPtr<QMenu> m_video_context_menu;
|
||||
OwnPtr<QIcon> m_video_context_menu_play_icon;
|
||||
OwnPtr<QIcon> m_video_context_menu_pause_icon;
|
||||
OwnPtr<QAction> m_video_context_menu_play_pause_action;
|
||||
OwnPtr<QAction> m_video_context_menu_controls_action;
|
||||
OwnPtr<QAction> m_video_context_menu_loop_action;
|
||||
URL m_video_context_menu_url;
|
||||
OwnPtr<QIcon> m_media_context_menu_play_icon;
|
||||
OwnPtr<QIcon> m_media_context_menu_pause_icon;
|
||||
OwnPtr<QAction> m_media_context_menu_play_pause_action;
|
||||
OwnPtr<QAction> m_media_context_menu_controls_action;
|
||||
OwnPtr<QAction> m_media_context_menu_loop_action;
|
||||
URL m_media_context_menu_url;
|
||||
|
||||
int tab_index();
|
||||
|
||||
|
|
|
@ -374,54 +374,56 @@ Tab::Tab(BrowserWindow& window)
|
|||
m_image_context_menu->popup(screen_position);
|
||||
};
|
||||
|
||||
m_video_context_menu_play_pause_action = GUI::Action::create("&Play", g_icon_bag.play, [this](auto&) {
|
||||
view().toggle_video_play_state();
|
||||
m_media_context_menu_play_pause_action = GUI::Action::create("&Play", g_icon_bag.play, [this](auto&) {
|
||||
view().toggle_media_play_state();
|
||||
});
|
||||
m_video_context_menu_controls_action = GUI::Action::create_checkable("Show &Controls", [this](auto&) {
|
||||
view().toggle_video_controls_state();
|
||||
m_media_context_menu_controls_action = GUI::Action::create_checkable("Show &Controls", [this](auto&) {
|
||||
view().toggle_media_controls_state();
|
||||
});
|
||||
m_video_context_menu_loop_action = GUI::Action::create_checkable("&Loop Video", [this](auto&) {
|
||||
view().toggle_video_loop_state();
|
||||
m_media_context_menu_loop_action = GUI::Action::create_checkable("&Loop", [this](auto&) {
|
||||
view().toggle_media_loop_state();
|
||||
});
|
||||
|
||||
m_video_context_menu = GUI::Menu::construct();
|
||||
m_video_context_menu->add_action(*m_video_context_menu_play_pause_action);
|
||||
m_video_context_menu->add_action(*m_video_context_menu_controls_action);
|
||||
m_video_context_menu->add_action(*m_video_context_menu_loop_action);
|
||||
m_video_context_menu->add_action(*m_media_context_menu_play_pause_action);
|
||||
m_video_context_menu->add_action(*m_media_context_menu_controls_action);
|
||||
m_video_context_menu->add_action(*m_media_context_menu_loop_action);
|
||||
m_video_context_menu->add_separator();
|
||||
m_video_context_menu->add_action(GUI::Action::create("&Open Video", g_icon_bag.filetype_video, [this](auto&) {
|
||||
view().on_link_click(m_video_context_menu_url, "", 0);
|
||||
view().on_link_click(m_media_context_menu_url, "", 0);
|
||||
}));
|
||||
m_video_context_menu->add_action(GUI::Action::create("Open Video in New &Tab", g_icon_bag.new_tab, [this](auto&) {
|
||||
view().on_link_click(m_video_context_menu_url, "_blank", 0);
|
||||
view().on_link_click(m_media_context_menu_url, "_blank", 0);
|
||||
}));
|
||||
m_video_context_menu->add_separator();
|
||||
m_video_context_menu->add_action(GUI::Action::create("Copy Video &URL", g_icon_bag.copy, [this](auto&) {
|
||||
GUI::Clipboard::the().set_plain_text(m_video_context_menu_url.to_deprecated_string());
|
||||
GUI::Clipboard::the().set_plain_text(m_media_context_menu_url.to_deprecated_string());
|
||||
}));
|
||||
m_video_context_menu->add_separator();
|
||||
m_video_context_menu->add_action(GUI::Action::create("&Download", g_icon_bag.download, [this](auto&) {
|
||||
start_download(m_video_context_menu_url);
|
||||
start_download(m_media_context_menu_url);
|
||||
}));
|
||||
m_video_context_menu->add_separator();
|
||||
m_video_context_menu->add_action(window.inspect_dom_node_action());
|
||||
|
||||
view().on_video_context_menu_request = [this](auto& video_url, auto widget_position, bool is_playing, bool has_user_agent_controls, bool is_looping) {
|
||||
m_video_context_menu_url = video_url;
|
||||
view().on_media_context_menu_request = [this](auto widget_position, Web::Page::MediaContextMenu const& menu) {
|
||||
m_media_context_menu_url = menu.media_url;
|
||||
|
||||
if (is_playing) {
|
||||
m_video_context_menu_play_pause_action->set_icon(g_icon_bag.play);
|
||||
m_video_context_menu_play_pause_action->set_text("&Play"sv);
|
||||
if (menu.is_playing) {
|
||||
m_media_context_menu_play_pause_action->set_icon(g_icon_bag.pause);
|
||||
m_media_context_menu_play_pause_action->set_text("&Pause"sv);
|
||||
} else {
|
||||
m_video_context_menu_play_pause_action->set_icon(g_icon_bag.pause);
|
||||
m_video_context_menu_play_pause_action->set_text("&Pause"sv);
|
||||
m_media_context_menu_play_pause_action->set_icon(g_icon_bag.play);
|
||||
m_media_context_menu_play_pause_action->set_text("&Play"sv);
|
||||
}
|
||||
|
||||
m_video_context_menu_controls_action->set_checked(has_user_agent_controls);
|
||||
m_video_context_menu_loop_action->set_checked(is_looping);
|
||||
m_media_context_menu_controls_action->set_checked(menu.has_user_agent_controls);
|
||||
m_media_context_menu_loop_action->set_checked(menu.is_looping);
|
||||
|
||||
auto screen_position = view().screen_relative_rect().location().translated(widget_position);
|
||||
m_video_context_menu->popup(screen_position);
|
||||
|
||||
if (menu.is_video)
|
||||
m_video_context_menu->popup(screen_position);
|
||||
};
|
||||
|
||||
view().on_link_middle_click = [this](auto& href, auto&, auto) {
|
||||
|
|
|
@ -144,10 +144,10 @@ private:
|
|||
URL m_image_context_menu_url;
|
||||
|
||||
RefPtr<GUI::Menu> m_video_context_menu;
|
||||
RefPtr<GUI::Action> m_video_context_menu_play_pause_action;
|
||||
RefPtr<GUI::Action> m_video_context_menu_controls_action;
|
||||
RefPtr<GUI::Action> m_video_context_menu_loop_action;
|
||||
URL m_video_context_menu_url;
|
||||
RefPtr<GUI::Action> m_media_context_menu_play_pause_action;
|
||||
RefPtr<GUI::Action> m_media_context_menu_controls_action;
|
||||
RefPtr<GUI::Action> m_media_context_menu_loop_action;
|
||||
URL m_media_context_menu_url;
|
||||
|
||||
RefPtr<GUI::Menu> m_tab_context_menu;
|
||||
RefPtr<GUI::Menu> m_page_context_menu;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <LibWeb/HTML/HTMLAnchorElement.h>
|
||||
#include <LibWeb/HTML/HTMLIFrameElement.h>
|
||||
#include <LibWeb/HTML/HTMLImageElement.h>
|
||||
#include <LibWeb/HTML/HTMLMediaElement.h>
|
||||
#include <LibWeb/HTML/HTMLVideoElement.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Page/EventHandler.h>
|
||||
|
@ -307,17 +308,19 @@ bool EventHandler::handle_mouseup(CSSPixelPoint position, unsigned button, unsig
|
|||
auto image_url = image_element.document().parse_url(image_element.src());
|
||||
if (auto* page = m_browsing_context->page())
|
||||
page->client().page_did_request_image_context_menu(m_browsing_context->to_top_level_position(position), image_url, "", modifiers, image_element.bitmap());
|
||||
} else if (is<HTML::HTMLVideoElement>(*node)) {
|
||||
auto& video_element = verify_cast<HTML::HTMLVideoElement>(*node);
|
||||
} else if (is<HTML::HTMLMediaElement>(*node)) {
|
||||
auto& media_element = verify_cast<HTML::HTMLMediaElement>(*node);
|
||||
|
||||
auto video_id = video_element.id();
|
||||
auto video_url = video_element.document().parse_url(video_element.current_src());
|
||||
auto is_playing = !video_element.potentially_playing();
|
||||
auto has_user_agent_controls = video_element.has_attribute(HTML::AttributeNames::controls);
|
||||
auto is_looping = video_element.has_attribute(HTML::AttributeNames::loop);
|
||||
Page::MediaContextMenu menu {
|
||||
.media_url = media_element.document().parse_url(media_element.current_src()),
|
||||
.is_video = is<HTML::HTMLVideoElement>(*node),
|
||||
.is_playing = media_element.potentially_playing(),
|
||||
.has_user_agent_controls = media_element.has_attribute(HTML::AttributeNames::controls),
|
||||
.is_looping = media_element.has_attribute(HTML::AttributeNames::loop),
|
||||
};
|
||||
|
||||
if (auto* page = m_browsing_context->page())
|
||||
page->did_request_video_context_menu(video_id, m_browsing_context->to_top_level_position(position), video_url, "", modifiers, is_playing, has_user_agent_controls, is_looping);
|
||||
page->did_request_media_context_menu(media_element.id(), m_browsing_context->to_top_level_position(position), "", modifiers, move(menu));
|
||||
} else if (auto* page = m_browsing_context->page()) {
|
||||
page->client().page_did_request_context_menu(m_browsing_context->to_top_level_position(position));
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/HTMLVideoElement.h>
|
||||
#include <LibWeb/HTML/HTMLMediaElement.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
|
@ -286,88 +288,111 @@ void Page::accept_dialog()
|
|||
}
|
||||
}
|
||||
|
||||
void Page::did_request_video_context_menu(i32 video_id, CSSPixelPoint position, AK::URL const& url, DeprecatedString const& target, unsigned modifiers, bool is_playing, bool has_user_agent_controls, bool is_looping)
|
||||
void Page::did_request_media_context_menu(i32 media_id, CSSPixelPoint position, DeprecatedString const& target, unsigned modifiers, MediaContextMenu menu)
|
||||
{
|
||||
m_video_context_menu_element_id = video_id;
|
||||
client().page_did_request_video_context_menu(position, url, target, modifiers, is_playing, has_user_agent_controls, is_looping);
|
||||
m_media_context_menu_element_id = media_id;
|
||||
client().page_did_request_media_context_menu(position, target, modifiers, move(menu));
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> Page::toggle_video_play_state()
|
||||
WebIDL::ExceptionOr<void> Page::toggle_media_play_state()
|
||||
{
|
||||
auto video_element = video_context_menu_element();
|
||||
if (!video_element)
|
||||
auto media_element = media_context_menu_element();
|
||||
if (!media_element)
|
||||
return {};
|
||||
|
||||
// FIXME: This runs from outside the context of any user script, so we do not have a running execution
|
||||
// context. This pushes one to allow the promise creation hook to run.
|
||||
auto& environment_settings = video_element->document().relevant_settings_object();
|
||||
auto& environment_settings = media_element->document().relevant_settings_object();
|
||||
environment_settings.prepare_to_run_script();
|
||||
|
||||
ScopeGuard guard { [&] { environment_settings.clean_up_after_running_script(); } };
|
||||
|
||||
if (video_element->potentially_playing())
|
||||
TRY(video_element->pause());
|
||||
if (media_element->potentially_playing())
|
||||
TRY(media_element->pause());
|
||||
else
|
||||
TRY(video_element->play());
|
||||
TRY(media_element->play());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> Page::toggle_video_loop_state()
|
||||
WebIDL::ExceptionOr<void> Page::toggle_media_loop_state()
|
||||
{
|
||||
auto video_element = video_context_menu_element();
|
||||
if (!video_element)
|
||||
auto media_element = media_context_menu_element();
|
||||
if (!media_element)
|
||||
return {};
|
||||
|
||||
// FIXME: This runs from outside the context of any user script, so we do not have a running execution
|
||||
// context. This pushes one to allow the promise creation hook to run.
|
||||
auto& environment_settings = video_element->document().relevant_settings_object();
|
||||
auto& environment_settings = media_element->document().relevant_settings_object();
|
||||
environment_settings.prepare_to_run_script();
|
||||
|
||||
ScopeGuard guard { [&] { environment_settings.clean_up_after_running_script(); } };
|
||||
|
||||
if (video_element->has_attribute(HTML::AttributeNames::loop))
|
||||
video_element->remove_attribute(HTML::AttributeNames::loop);
|
||||
if (media_element->has_attribute(HTML::AttributeNames::loop))
|
||||
media_element->remove_attribute(HTML::AttributeNames::loop);
|
||||
else
|
||||
TRY(video_element->set_attribute(HTML::AttributeNames::loop, {}));
|
||||
TRY(media_element->set_attribute(HTML::AttributeNames::loop, {}));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> Page::toggle_video_controls_state()
|
||||
WebIDL::ExceptionOr<void> Page::toggle_media_controls_state()
|
||||
{
|
||||
auto video_element = video_context_menu_element();
|
||||
if (!video_element)
|
||||
auto media_element = media_context_menu_element();
|
||||
if (!media_element)
|
||||
return {};
|
||||
|
||||
// FIXME: This runs from outside the context of any user script, so we do not have a running execution
|
||||
// context. This pushes one to allow the promise creation hook to run.
|
||||
auto& environment_settings = video_element->document().relevant_settings_object();
|
||||
auto& environment_settings = media_element->document().relevant_settings_object();
|
||||
environment_settings.prepare_to_run_script();
|
||||
|
||||
ScopeGuard guard { [&] { environment_settings.clean_up_after_running_script(); } };
|
||||
|
||||
if (video_element->has_attribute(HTML::AttributeNames::controls))
|
||||
video_element->remove_attribute(HTML::AttributeNames::controls);
|
||||
if (media_element->has_attribute(HTML::AttributeNames::controls))
|
||||
media_element->remove_attribute(HTML::AttributeNames::controls);
|
||||
else
|
||||
TRY(video_element->set_attribute(HTML::AttributeNames::controls, {}));
|
||||
TRY(media_element->set_attribute(HTML::AttributeNames::controls, {}));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
JS::GCPtr<HTML::HTMLVideoElement> Page::video_context_menu_element()
|
||||
JS::GCPtr<HTML::HTMLMediaElement> Page::media_context_menu_element()
|
||||
{
|
||||
if (!m_video_context_menu_element_id.has_value())
|
||||
if (!m_media_context_menu_element_id.has_value())
|
||||
return nullptr;
|
||||
|
||||
auto* dom_node = DOM::Node::from_id(*m_video_context_menu_element_id);
|
||||
auto* dom_node = DOM::Node::from_id(*m_media_context_menu_element_id);
|
||||
if (dom_node == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (!is<HTML::HTMLVideoElement>(dom_node))
|
||||
if (!is<HTML::HTMLMediaElement>(dom_node))
|
||||
return nullptr;
|
||||
|
||||
return static_cast<HTML::HTMLVideoElement*>(dom_node);
|
||||
return static_cast<HTML::HTMLMediaElement*>(dom_node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> IPC::encode(Encoder& encoder, Web::Page::MediaContextMenu const& menu)
|
||||
{
|
||||
TRY(encoder.encode(menu.media_url));
|
||||
TRY(encoder.encode(menu.is_video));
|
||||
TRY(encoder.encode(menu.is_playing));
|
||||
TRY(encoder.encode(menu.has_user_agent_controls));
|
||||
TRY(encoder.encode(menu.is_looping));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<Web::Page::MediaContextMenu> IPC::decode(Decoder& decoder)
|
||||
{
|
||||
return Web::Page::MediaContextMenu {
|
||||
.media_url = TRY(decoder.decode<AK::URL>()),
|
||||
.is_video = TRY(decoder.decode<bool>()),
|
||||
.is_playing = TRY(decoder.decode<bool>()),
|
||||
.has_user_agent_controls = TRY(decoder.decode<bool>()),
|
||||
.is_looping = TRY(decoder.decode<bool>()),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibGfx/StandardCursor.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
|
@ -120,15 +121,22 @@ public:
|
|||
void dismiss_dialog();
|
||||
void accept_dialog();
|
||||
|
||||
void did_request_video_context_menu(i32 video_id, CSSPixelPoint, AK::URL const&, DeprecatedString const& target, unsigned modifiers, bool is_playing, bool has_user_agent_controls, bool is_looping);
|
||||
WebIDL::ExceptionOr<void> toggle_video_play_state();
|
||||
WebIDL::ExceptionOr<void> toggle_video_loop_state();
|
||||
WebIDL::ExceptionOr<void> toggle_video_controls_state();
|
||||
struct MediaContextMenu {
|
||||
AK::URL media_url;
|
||||
bool is_video { false };
|
||||
bool is_playing { false };
|
||||
bool has_user_agent_controls { false };
|
||||
bool is_looping { false };
|
||||
};
|
||||
void did_request_media_context_menu(i32 media_id, CSSPixelPoint, DeprecatedString const& target, unsigned modifiers, MediaContextMenu);
|
||||
WebIDL::ExceptionOr<void> toggle_media_play_state();
|
||||
WebIDL::ExceptionOr<void> toggle_media_loop_state();
|
||||
WebIDL::ExceptionOr<void> toggle_media_controls_state();
|
||||
|
||||
bool pdf_viewer_supported() const { return m_pdf_viewer_supported; }
|
||||
|
||||
private:
|
||||
JS::GCPtr<HTML::HTMLVideoElement> video_context_menu_element();
|
||||
JS::GCPtr<HTML::HTMLMediaElement> media_context_menu_element();
|
||||
|
||||
PageClient& m_client;
|
||||
|
||||
|
@ -155,7 +163,7 @@ private:
|
|||
Optional<bool> m_pending_confirm_response;
|
||||
Optional<Optional<String>> m_pending_prompt_response;
|
||||
|
||||
Optional<int> m_video_context_menu_element_id;
|
||||
Optional<int> m_media_context_menu_element_id;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-supported
|
||||
// Each user agent has a PDF viewer supported boolean, whose value is implementation-defined (and might vary according to user preferences).
|
||||
|
@ -192,7 +200,7 @@ public:
|
|||
virtual void page_did_request_context_menu(CSSPixelPoint) { }
|
||||
virtual void page_did_request_link_context_menu(CSSPixelPoint, AK::URL const&, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers) { }
|
||||
virtual void page_did_request_image_context_menu(CSSPixelPoint, AK::URL const&, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers, Gfx::Bitmap const*) { }
|
||||
virtual void page_did_request_video_context_menu(CSSPixelPoint, AK::URL const&, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers, [[maybe_unused]] bool is_playing, [[maybe_unused]] bool has_user_agent_controls, [[maybe_unused]] bool is_looping) { }
|
||||
virtual void page_did_request_media_context_menu(CSSPixelPoint, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers, Page::MediaContextMenu) { }
|
||||
virtual void page_did_click_link(const AK::URL&, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers) { }
|
||||
virtual void page_did_middle_click_link(const AK::URL&, [[maybe_unused]] DeprecatedString const& target, [[maybe_unused]] unsigned modifiers) { }
|
||||
virtual void page_did_enter_tooltip_area(CSSPixelPoint, DeprecatedString const&) { }
|
||||
|
@ -231,3 +239,13 @@ protected:
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, Web::Page::MediaContextMenu const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<Web::Page::MediaContextMenu> decode(Decoder&);
|
||||
|
||||
}
|
||||
|
|
|
@ -151,19 +151,19 @@ void ViewImplementation::js_console_request_messages(i32 start_index)
|
|||
client().async_js_console_request_messages(start_index);
|
||||
}
|
||||
|
||||
void ViewImplementation::toggle_video_play_state()
|
||||
void ViewImplementation::toggle_media_play_state()
|
||||
{
|
||||
client().async_toggle_video_play_state();
|
||||
client().async_toggle_media_play_state();
|
||||
}
|
||||
|
||||
void ViewImplementation::toggle_video_loop_state()
|
||||
void ViewImplementation::toggle_media_loop_state()
|
||||
{
|
||||
client().async_toggle_video_loop_state();
|
||||
client().async_toggle_media_loop_state();
|
||||
}
|
||||
|
||||
void ViewImplementation::toggle_video_controls_state()
|
||||
void ViewImplementation::toggle_media_controls_state()
|
||||
{
|
||||
client().async_toggle_video_controls_state();
|
||||
client().async_toggle_media_controls_state();
|
||||
}
|
||||
|
||||
void ViewImplementation::handle_resize()
|
||||
|
|
|
@ -74,9 +74,9 @@ public:
|
|||
void js_console_input(DeprecatedString const& js_source);
|
||||
void js_console_request_messages(i32 start_index);
|
||||
|
||||
void toggle_video_play_state();
|
||||
void toggle_video_loop_state();
|
||||
void toggle_video_controls_state();
|
||||
void toggle_media_play_state();
|
||||
void toggle_media_loop_state();
|
||||
void toggle_media_controls_state();
|
||||
|
||||
enum class ScreenshotType {
|
||||
Visible,
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
Function<void(Gfx::IntPoint screen_position)> on_context_menu_request;
|
||||
Function<void(const AK::URL&, Gfx::IntPoint screen_position)> on_link_context_menu_request;
|
||||
Function<void(const AK::URL&, Gfx::IntPoint screen_position, Gfx::ShareableBitmap const&)> on_image_context_menu_request;
|
||||
Function<void(const AK::URL&, Gfx::IntPoint screen_position, bool, bool, bool)> on_video_context_menu_request;
|
||||
Function<void(Gfx::IntPoint screen_position, Web::Page::MediaContextMenu const&)> on_media_context_menu_request;
|
||||
Function<void(const AK::URL&)> on_link_hover;
|
||||
Function<void()> on_link_unhover;
|
||||
Function<void(const AK::URL&, DeprecatedString const& target, unsigned modifiers)> on_link_click;
|
||||
|
|
|
@ -176,10 +176,10 @@ void WebContentClient::did_request_image_context_menu(Gfx::IntPoint content_posi
|
|||
m_view.on_image_context_menu_request(url, m_view.to_widget_position(content_position), bitmap);
|
||||
}
|
||||
|
||||
void WebContentClient::did_request_video_context_menu(Gfx::IntPoint content_position, AK::URL const& url, DeprecatedString const&, unsigned, bool is_playing, bool has_user_agent_controls, bool is_looping)
|
||||
void WebContentClient::did_request_media_context_menu(Gfx::IntPoint content_position, DeprecatedString const&, unsigned, Web::Page::MediaContextMenu const& menu)
|
||||
{
|
||||
if (m_view.on_video_context_menu_request)
|
||||
m_view.on_video_context_menu_request(url, m_view.to_widget_position(content_position), is_playing, has_user_agent_controls, is_looping);
|
||||
if (m_view.on_media_context_menu_request)
|
||||
m_view.on_media_context_menu_request(m_view.to_widget_position(content_position), menu);
|
||||
}
|
||||
|
||||
void WebContentClient::did_get_source(AK::URL const& url, DeprecatedString const& source)
|
||||
|
|
|
@ -52,7 +52,7 @@ private:
|
|||
virtual void did_request_context_menu(Gfx::IntPoint) override;
|
||||
virtual void did_request_link_context_menu(Gfx::IntPoint, AK::URL const&, DeprecatedString const&, unsigned) override;
|
||||
virtual void did_request_image_context_menu(Gfx::IntPoint, AK::URL const&, DeprecatedString const&, unsigned, Gfx::ShareableBitmap const&) override;
|
||||
virtual void did_request_video_context_menu(Gfx::IntPoint, AK::URL const&, DeprecatedString const&, unsigned, bool, bool, bool) override;
|
||||
virtual void did_request_media_context_menu(Gfx::IntPoint, DeprecatedString const&, unsigned, Web::Page::MediaContextMenu const&) override;
|
||||
virtual void did_get_source(AK::URL const&, DeprecatedString const&) override;
|
||||
virtual void did_get_dom_tree(DeprecatedString const&) override;
|
||||
virtual void did_get_dom_node_properties(i32 node_id, DeprecatedString const& computed_style, DeprecatedString const& resolved_style, DeprecatedString const& custom_properties, DeprecatedString const& node_box_sizing) override;
|
||||
|
|
|
@ -785,19 +785,19 @@ void ConnectionFromClient::prompt_closed(Optional<String> const& response)
|
|||
m_page_host->prompt_closed(response);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::toggle_video_play_state()
|
||||
void ConnectionFromClient::toggle_media_play_state()
|
||||
{
|
||||
m_page_host->toggle_video_play_state().release_value_but_fixme_should_propagate_errors();
|
||||
m_page_host->toggle_media_play_state().release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::toggle_video_loop_state()
|
||||
void ConnectionFromClient::toggle_media_loop_state()
|
||||
{
|
||||
m_page_host->toggle_video_loop_state().release_value_but_fixme_should_propagate_errors();
|
||||
m_page_host->toggle_media_loop_state().release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::toggle_video_controls_state()
|
||||
void ConnectionFromClient::toggle_media_controls_state()
|
||||
{
|
||||
m_page_host->toggle_video_controls_state().release_value_but_fixme_should_propagate_errors();
|
||||
m_page_host->toggle_media_controls_state().release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::inspect_accessibility_tree()
|
||||
|
|
|
@ -96,9 +96,9 @@ private:
|
|||
virtual void confirm_closed(bool accepted) override;
|
||||
virtual void prompt_closed(Optional<String> const& response) override;
|
||||
|
||||
virtual void toggle_video_play_state() override;
|
||||
virtual void toggle_video_loop_state() override;
|
||||
virtual void toggle_video_controls_state() override;
|
||||
virtual void toggle_media_play_state() override;
|
||||
virtual void toggle_media_loop_state() override;
|
||||
virtual void toggle_media_controls_state() override;
|
||||
|
||||
virtual Messages::WebContentServer::TakeDocumentScreenshotResponse take_document_screenshot() override;
|
||||
|
||||
|
|
|
@ -334,19 +334,19 @@ void PageHost::prompt_closed(Optional<String> response)
|
|||
page().prompt_closed(move(response));
|
||||
}
|
||||
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_video_play_state()
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_media_play_state()
|
||||
{
|
||||
return page().toggle_video_play_state();
|
||||
return page().toggle_media_play_state();
|
||||
}
|
||||
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_video_loop_state()
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_media_loop_state()
|
||||
{
|
||||
return page().toggle_video_loop_state();
|
||||
return page().toggle_media_loop_state();
|
||||
}
|
||||
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_video_controls_state()
|
||||
Web::WebIDL::ExceptionOr<void> PageHost::toggle_media_controls_state()
|
||||
{
|
||||
return page().toggle_video_controls_state();
|
||||
return page().toggle_media_controls_state();
|
||||
}
|
||||
|
||||
void PageHost::page_did_request_accept_dialog()
|
||||
|
@ -370,9 +370,9 @@ void PageHost::page_did_request_image_context_menu(Web::CSSPixelPoint content_po
|
|||
m_client.async_did_request_image_context_menu({ content_position.x().to_int(), content_position.y().to_int() }, url, target, modifiers, bitmap);
|
||||
}
|
||||
|
||||
void PageHost::page_did_request_video_context_menu(Web::CSSPixelPoint content_position, URL const& url, DeprecatedString const& target, unsigned modifiers, bool is_playing, bool has_user_agent_controls, bool is_looping)
|
||||
void PageHost::page_did_request_media_context_menu(Web::CSSPixelPoint content_position, DeprecatedString const& target, unsigned modifiers, Web::Page::MediaContextMenu menu)
|
||||
{
|
||||
m_client.async_did_request_video_context_menu({ content_position.x().to_int(), content_position.y().to_int() }, url, target, modifiers, is_playing, has_user_agent_controls, is_looping);
|
||||
m_client.async_did_request_media_context_menu({ content_position.x().to_int(), content_position.y().to_int() }, target, modifiers, move(menu));
|
||||
}
|
||||
|
||||
Vector<Web::Cookie::Cookie> PageHost::page_did_request_all_cookies(URL const& url)
|
||||
|
|
|
@ -49,9 +49,9 @@ public:
|
|||
void confirm_closed(bool accepted);
|
||||
void prompt_closed(Optional<String> response);
|
||||
|
||||
Web::WebIDL::ExceptionOr<void> toggle_video_play_state();
|
||||
Web::WebIDL::ExceptionOr<void> toggle_video_loop_state();
|
||||
Web::WebIDL::ExceptionOr<void> toggle_video_controls_state();
|
||||
Web::WebIDL::ExceptionOr<void> toggle_media_play_state();
|
||||
Web::WebIDL::ExceptionOr<void> toggle_media_loop_state();
|
||||
Web::WebIDL::ExceptionOr<void> toggle_media_controls_state();
|
||||
|
||||
[[nodiscard]] Gfx::Color background_color() const;
|
||||
|
||||
|
@ -98,7 +98,7 @@ private:
|
|||
virtual void page_did_request_dismiss_dialog() override;
|
||||
virtual void page_did_change_favicon(Gfx::Bitmap const&) override;
|
||||
virtual void page_did_request_image_context_menu(Web::CSSPixelPoint, const URL&, DeprecatedString const& target, unsigned modifiers, Gfx::Bitmap const*) override;
|
||||
virtual void page_did_request_video_context_menu(Web::CSSPixelPoint, const URL&, DeprecatedString const& target, unsigned modifiers, bool is_playing, bool has_user_agent_controls, bool is_looping) override;
|
||||
virtual void page_did_request_media_context_menu(Web::CSSPixelPoint, DeprecatedString const& target, unsigned modifiers, Web::Page::MediaContextMenu) override;
|
||||
virtual Vector<Web::Cookie::Cookie> page_did_request_all_cookies(URL const&) override;
|
||||
virtual Optional<Web::Cookie::Cookie> page_did_request_named_cookie(URL const&, DeprecatedString const&) override;
|
||||
virtual DeprecatedString page_did_request_cookie(const URL&, Web::Cookie::Source) override;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <LibWeb/Cookie/Cookie.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/HTML/ActivateTab.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
endpoint WebContentClient
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ endpoint WebContentClient
|
|||
did_request_context_menu(Gfx::IntPoint content_position) =|
|
||||
did_request_link_context_menu(Gfx::IntPoint content_position, URL url, DeprecatedString target, unsigned modifiers) =|
|
||||
did_request_image_context_menu(Gfx::IntPoint content_position, URL url, DeprecatedString target, unsigned modifiers, Gfx::ShareableBitmap bitmap) =|
|
||||
did_request_video_context_menu(Gfx::IntPoint content_position, URL url, DeprecatedString target, unsigned modifiers, bool is_playing, bool has_user_agent_controls, bool is_looping) =|
|
||||
did_request_media_context_menu(Gfx::IntPoint content_position, DeprecatedString target, unsigned modifiers, Web::Page::MediaContextMenu menu) =|
|
||||
did_request_alert(String message) =|
|
||||
did_request_confirm(String message) =|
|
||||
did_request_prompt(String message, String default_) =|
|
||||
|
|
|
@ -78,7 +78,7 @@ endpoint WebContentServer
|
|||
confirm_closed(bool accepted) =|
|
||||
prompt_closed(Optional<String> response) =|
|
||||
|
||||
toggle_video_play_state() =|
|
||||
toggle_video_loop_state() =|
|
||||
toggle_video_controls_state() =|
|
||||
toggle_media_play_state() =|
|
||||
toggle_media_loop_state() =|
|
||||
toggle_media_controls_state() =|
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue