diff options
Diffstat (limited to 'src/core/web_contents_adapter.cpp')
-rw-r--r-- | src/core/web_contents_adapter.cpp | 296 |
1 files changed, 208 insertions, 88 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 3521bb547..6decf8780 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -8,12 +8,14 @@ #include "web_contents_adapter.h" #include "autofill_client_qt.h" +#include "content_browser_client_qt.h" #include "devtools_frontend_qt.h" #include "download_manager_delegate_qt.h" #include "favicon_driver_qt.h" #include "favicon_service_factory_qt.h" #include "find_text_helper.h" #include "media_capture_devices_dispatcher.h" +#include "pdf_util_qt.h" #include "profile_adapter.h" #include "profile_qt.h" #include "qwebengineloadinginfo.h" @@ -27,18 +29,17 @@ #include "base/command_line.h" #include "base/metrics/user_metrics.h" #include "base/task/current_thread.h" -#include "base/task/post_task.h" #include "base/task/sequence_manager/sequence_manager_impl.h" #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" #include "base/values.h" #include "chrome/browser/tab_contents/form_interaction_tab_helper.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/embedder_support/user_agent_utils.h" #include "components/favicon/core/favicon_service.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/download_request_utils.h" @@ -49,6 +50,7 @@ #include "content/public/browser/favicon_status.h" #include "content/public/common/content_switches.h" #include "content/public/common/drop_data.h" +#include "content/public/common/url_constants.h" #include "extensions/buildflags/buildflags.h" #include "third_party/blink/public/common/page/page_zoom.h" #include "third_party/blink/public/common/page_state/page_state.h" @@ -58,8 +60,26 @@ #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/gfx/font_render_params.h" +#include "ui/native_theme/native_theme.h" #include "qtwebengine/browser/qtwebenginepage.mojom.h" +#include <QtCore/QVariant> +#include <QtCore/QElapsedTimer> +#include <QtCore/QMimeData> +#include <QtCore/QTemporaryDir> +#include <QtGui/QDrag> +#include <QtGui/QDragEnterEvent> +#include <QtGui/QGuiApplication> +#include <QtGui/QPageLayout> +#include <QtGui/QPixmap> +#include <QtGui/QStyleHints> + +#if QT_CONFIG(accessibility) +#include "browser_accessibility_qt.h" +#include "content/browser/accessibility/browser_accessibility_manager.h" +#include <QtGui/qaccessible.h> +#endif + #if QT_CONFIG(webengine_printing_and_pdf) #include "printing/print_view_manager_qt.h" #endif @@ -73,30 +93,14 @@ #include "extensions/extension_web_contents_observer_qt.h" #endif -#include <QtCore/QVariant> -#include <QtCore/QElapsedTimer> -#include <QtCore/QMimeData> -#include <QtCore/QTemporaryDir> -#include <QtGui/QDrag> -#include <QtGui/QDragEnterEvent> -#include <QtGui/QGuiApplication> -#include <QtGui/QPageLayout> -#include <QtGui/QPixmap> -#include <QtGui/QStyleHints> - -// Can't include headers as qaccessible.h conflicts with Chromium headers. -namespace content { -extern QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc); -} - namespace QtWebEngineCore { #define CHECK_INITIALIZED(return_value) \ if (!isInitialized()) \ return return_value -#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \ - if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \ +#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_frame_host) \ + if (!render_frame_host->IsRenderFrameLive() && render_frame_host->GetView()) { \ LOG(WARNING) << "Ignore navigation due to terminated render process with invalid RenderWidgetHostView."; \ return; \ } @@ -129,37 +133,30 @@ static QVariant fromJSValue(const base::Value *result) } case base::Value::Type::STRING: { - std::u16string out; - if (result->GetAsString(&out)) - ret.setValue(toQt(out)); + if (auto out = result->GetIfString()) + ret.setValue(toQt(*out)); break; } case base::Value::Type::LIST: { - const base::ListValue *out; - if (result->GetAsList(&out)) { - size_t size = out->GetList().size(); + if (const auto out = result->GetIfList()) { + size_t size = out->size(); QVariantList list; list.reserve(size); for (size_t i = 0; i < size; ++i) { - const base::Value *outVal = 0; - if (out->Get(i, &outVal) && outVal) - list.insert(i, fromJSValue(outVal)); + auto &outVal = (*out)[i]; + list.insert(i, fromJSValue(&outVal)); } ret.setValue(list); } break; } - case base::Value::Type::DICTIONARY: + case base::Value::Type::DICT: { - const base::DictionaryValue *out; - if (result->GetAsDictionary(&out)) { + if (const auto dict = result->GetIfDict()) { QVariantMap map; - base::DictionaryValue::Iterator it(*out); - while (!it.IsAtEnd()) { - map.insert(toQt(it.key()), fromJSValue(&it.value())); - it.Advance(); - } + for (const auto pair : *dict) + map.insert(toQt(pair.first), fromJSValue(&pair.second)); ret.setValue(map); } break; @@ -212,10 +209,28 @@ static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsA return webContents; } +static int navigationListSize(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return 0 as the navigation list size. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return 0; + return controller.GetEntryCount(); +} + +static int navigationListCurrentIndex(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return -1 as the current index. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return -1; + return controller.GetCurrentEntryIndex(); +} + static void serializeNavigationHistory(content::NavigationController &controller, QDataStream &output) { - const int currentIndex = controller.GetCurrentEntryIndex(); - const int count = controller.GetEntryCount(); + const int currentIndex = navigationListCurrentIndex(controller); + const int count = navigationListSize(controller); const int pendingIndex = controller.GetPendingEntryIndex(); output << kHistoryStreamVersion; @@ -264,7 +279,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, int count; input >> count >> *currentIndex; - std::unique_ptr<content::NavigationEntryRestoreContext> context = content::NavigationEntryRestoreContext::Create(); // FIXME? + std::unique_ptr<content::NavigationEntryRestoreContext> context = content::NavigationEntryRestoreContext::Create(); entries->reserve(count); // Logic taken from SerializedNavigationEntry::ReadFromPickle and ToNavigationEntries. @@ -306,6 +321,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, toGurl(virtualUrl), content::Referrer(toGurl(referrerUrl), static_cast<network::mojom::ReferrerPolicy>(referrerPolicy)), absl::nullopt, // optional initiator_origin + absl::nullopt, // optional initiator_base_url // Use a transition type of reload so that we don't incorrectly // increase the typed count. ui::PAGE_TRANSITION_RELOAD, @@ -391,17 +407,6 @@ QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavig content::NavigationController &controller = newWebContents->GetController(); controller.Restore(currentIndex, content::RestoreType::kRestored, &entries); - if (controller.GetActiveEntry()) { - // Set up the file access rights for the selected navigation entry. - // TODO(joth): This is duplicated from chrome/.../session_restore.cc and - // should be shared e.g. in NavigationController. http://crbug.com/68222 - const int id = newWebContents->GetMainFrame()->GetProcess()->GetID(); - const blink::PageState& pageState = controller.GetActiveEntry()->GetPageState(); - const std::vector<base::FilePath>& filePaths = pageState.GetReferencedFiles(); - for (std::vector<base::FilePath>::const_iterator file = filePaths.begin(); file != filePaths.end(); ++file) - content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id, *file); - } - return QSharedPointer<WebContentsAdapter>::create(std::move(newWebContents)); } @@ -449,6 +454,10 @@ bool WebContentsAdapter::isInitialized() const return (bool)m_webContentsDelegate; } +ui::NativeTheme::PreferredColorScheme toWeb(Qt::ColorScheme colorScheme) { + return colorScheme == Qt::ColorScheme::Dark ? ui::NativeTheme::PreferredColorScheme::kDark : ui::NativeTheme::PreferredColorScheme::kLight; +} + void WebContentsAdapter::initialize(content::SiteInstance *site) { Q_ASSERT(m_adapterClient); @@ -486,9 +495,6 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) webContents(), FaviconServiceFactoryQt::GetForBrowserContext(context), m_adapterClient); AutofillClientQt::CreateForWebContents(webContents()); - autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( - webContents(), AutofillClientQt::FromWebContents(webContents()), - /* app_locale = */ "", autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER); // Create an instance of WebEngineVisitedLinksManager to catch the first // content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will @@ -499,12 +505,18 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) // Create a RenderView with the initial empty document content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); Q_ASSERT(rvh); - if (!rvh->IsRenderViewLive()) + if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive()) static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager( rvh, absl::nullopt, nullptr); m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh); + // Make sure the system theme's light/dark mode is propagated to webpages + QObject::connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, [](Qt::ColorScheme colorScheme){ + ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(colorScheme)); + }); + ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(QGuiApplication::styleHints()->colorScheme())); + m_adapterClient->initializationFinished(); } @@ -518,6 +530,7 @@ void WebContentsAdapter::initializeRenderPrefs() rendererPrefs->caret_blink_interval = base::Milliseconds(0.5 * static_cast<double>(qtCursorFlashTime)); rendererPrefs->user_agent_override = blink::UserAgentOverride::UserAgentOnly(m_profileAdapter->httpUserAgent().toStdString()); + rendererPrefs->user_agent_override.ua_metadata_override = profile()->userAgentMetadata(); rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString(); #if QT_CONFIG(webengine_webrtc) base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess(); @@ -531,6 +544,8 @@ void WebContentsAdapter::initializeRenderPrefs() ? blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly : blink::kWebRTCIPHandlingDefault; #endif + rendererPrefs->can_accept_load_drops = m_adapterClient->webEngineSettings()->testAttribute(QWebEngineSettings::NavigateOnDropEnabled); + // Set web-contents font settings to the default font settings as Chromium constantly overrides // the global font defaults with the font settings of the latest web-contents created. static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr); @@ -582,7 +597,7 @@ void WebContentsAdapter::reload() bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded); setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings()); settings->doApply(); if (!wasDiscarded) // undiscard() already triggers a reload @@ -597,7 +612,7 @@ void WebContentsAdapter::reloadAndBypassCache() bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded); setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings()); settings->doApply(); if (!wasDiscarded) // undiscard() already triggers a reload @@ -629,7 +644,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) setLifecycleState(LifecycleState::Active); } - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply(); @@ -703,7 +718,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) if (resizeNeeded) { // Schedule navigation on the event loop. - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params))); } else { Navigate(this, params); @@ -717,7 +732,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT else setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply(); @@ -749,7 +764,7 @@ void WebContentsAdapter::save(const QString &filePath, int savePageFormat) { CHECK_INITIALIZED(); base::RecordAction(base::UserMetricsAction("SavePage")); - m_webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat)); + m_webContentsDelegate->setSavePageInfo(new SavePageInfo(filePath, savePageFormat)); m_webContents->OnSavePage(); } @@ -868,7 +883,7 @@ void WebContentsAdapter::navigateBack() { CHECK_INITIALIZED(); base::RecordAction(base::UserMetricsAction("Back")); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); if (!m_webContents->GetController().CanGoBack()) return; m_webContents->GetController().GoBack(); @@ -879,7 +894,7 @@ void WebContentsAdapter::navigateForward() { CHECK_INITIALIZED(); base::RecordAction(base::UserMetricsAction("Forward")); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); if (!m_webContents->GetController().CanGoForward()) return; m_webContents->GetController().GoForward(); @@ -889,7 +904,7 @@ void WebContentsAdapter::navigateForward() void WebContentsAdapter::navigateToIndex(int offset) { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); m_webContents->GetController().GoToIndex(offset); focusIfNecessary(); } @@ -897,7 +912,7 @@ void WebContentsAdapter::navigateToIndex(int offset) void WebContentsAdapter::navigateToOffset(int offset) { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); m_webContents->GetController().GoToOffset(offset); focusIfNecessary(); } @@ -905,13 +920,13 @@ void WebContentsAdapter::navigateToOffset(int offset) int WebContentsAdapter::navigationEntryCount() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetEntryCount(); + return navigationListSize(m_webContents->GetController()); } int WebContentsAdapter::currentNavigationEntryIndex() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetCurrentEntryIndex(); + return navigationListCurrentIndex(m_webContents->GetController()); } QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index) @@ -975,9 +990,8 @@ void WebContentsAdapter::setZoomFactor(qreal factor) content::HostZoomMap *zoomMap = content::HostZoomMap::GetForWebContents(m_webContents.get()); if (zoomMap) { - int render_process_id = m_webContents->GetMainFrame()->GetProcess()->GetID(); - int render_view_id = m_webContents->GetRenderViewHost()->GetRoutingID(); - zoomMap->SetTemporaryZoomLevel(render_process_id, render_view_id, zoomLevel); + const content::GlobalRenderFrameHostId global_id = m_webContents->GetPrimaryMainFrame()->GetGlobalId(); + zoomMap->SetTemporaryZoomLevel(global_id, zoomLevel); } } @@ -1013,13 +1027,13 @@ QWebEngineUrlRequestInterceptor* WebContentsAdapter::requestInterceptor() const QAccessibleInterface *WebContentsAdapter::browserAccessible() { CHECK_INITIALIZED(nullptr); - content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetMainFrame()); + content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetPrimaryMainFrame()); if (!rfh) return nullptr; content::BrowserAccessibilityManager *manager = rfh->GetOrCreateBrowserAccessibilityManager(); if (!manager) // FIXME! return nullptr; - content::BrowserAccessibility *acc = manager->GetRoot(); + content::BrowserAccessibility *acc = manager->GetFromAXNode(manager->GetRoot()); return content::toQAccessibleInterface(acc); } @@ -1028,8 +1042,12 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible() void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId) { CHECK_INITIALIZED(); - content::RenderFrameHost *rfh = m_webContents->GetMainFrame(); + content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame(); Q_ASSERT(rfh); + if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) { + qWarning() << "Local frame is gone, not running script"; + return; + } if (worldId == 0) rfh->ExecuteJavaScript(toString16(javaScript), base::NullCallback()); else @@ -1039,8 +1057,12 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId) { CHECK_INITIALIZED(0); - content::RenderFrameHost *rfh = m_webContents->GetMainFrame(); + content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame(); Q_ASSERT(rfh); + if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) { + qWarning() << "Local frame is gone, not running script"; + return 0; + } content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId); if (worldId == 0) rfh->ExecuteJavaScript(toString16(javaScript), std::move(callback)); @@ -1151,7 +1173,7 @@ qint64 WebContentsAdapter::renderProcessPid() const { CHECK_INITIALIZED(0); - content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess(); + content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess(); const base::Process &process = renderProcessHost->GetProcess(); if (!process.IsValid()) return 0; @@ -1161,7 +1183,7 @@ qint64 WebContentsAdapter::renderProcessPid() const void WebContentsAdapter::copyImageAt(const QPoint &location) { CHECK_INITIALIZED(); - m_webContents->GetMainFrame()->CopyImageAt(location.x(), location.y()); + m_webContents->GetPrimaryMainFrame()->CopyImageAt(location.x(), location.y()); } static blink::mojom::MediaPlayerActionType toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action) @@ -1188,7 +1210,7 @@ void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, Medi if (action == MediaPlayerNoAction) return; blink::mojom::MediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable); - m_webContents->GetMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction); + m_webContents->GetPrimaryMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction); } void WebContentsAdapter::inspectElementAt(const QPoint &location) @@ -1239,7 +1261,10 @@ void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter> setLifecycleState(LifecycleState::Active); - m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, m_webContents.get()); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, webContents); updateRecommendedState(); } @@ -1259,6 +1284,11 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend) updateRecommendedState(); } +QString WebContentsAdapter::devToolsId() +{ + return QString::fromStdString(DevToolsFrontendQt::GetId(m_webContents.get())); +} + void WebContentsAdapter::exitFullScreen() { CHECK_INITIALIZED(); @@ -1519,7 +1549,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD } { - base::CurrentThread::ScopedNestableTaskAllower allow; + base::CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop allow; drag->exec(allowedActions); } @@ -1589,7 +1619,7 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat } if (!dropData->filenames.empty()) return; - if (mimeData->hasUrls()) { + if (!urls.empty()) { dropData->url = toGurl(urls.first()); if (mimeData->hasText()) dropData->url_title = toString16(mimeData->text()); @@ -1768,6 +1798,94 @@ void WebContentsAdapter::resetTouchSelectionController() rwhv->resetTouchSelectionController(); } +void WebContentsAdapter::changeTextDirection(bool leftToRight) +{ + CHECK_INITIALIZED(); + if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) { + auto textInputManager = rwhv->GetTextInputManager(); + if (!textInputManager) + return; + if (auto activeWidget = textInputManager->GetActiveWidget()) { + activeWidget->UpdateTextDirection(leftToRight ? base::i18n::TextDirection::LEFT_TO_RIGHT : base::i18n::TextDirection::RIGHT_TO_LEFT); + activeWidget->NotifyTextDirection(); + } + } +} + +quint64 WebContentsAdapter::mainFrameId() const +{ + CHECK_INITIALIZED(content::RenderFrameHost::kNoFrameTreeNodeId); + return static_cast<quint64>(m_webContents->GetPrimaryMainFrame()->GetFrameTreeNodeId()); +} + +#define CHECK_INITIALIZED_AND_VALID_FRAME(webengine_frame_id_variable, frame_tree_node_variable, \ + return_value) \ + CHECK_INITIALIZED(return_value); \ + if (webengine_frame_id_variable == kInvalidFrameId) \ + return return_value; \ + auto *frame_tree_node_variable = content::FrameTreeNode::GloballyFindByID( \ + static_cast<int>(webengine_frame_id_variable)); \ + if (!frame_tree_node_variable) \ + return return_value + +QString WebContentsAdapter::frameName(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QString()); + return QString::fromStdString(ftn->frame_name()); +} + +QString WebContentsAdapter::frameHtmlName(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QString()); + auto &maybeName = ftn->html_name(); + return maybeName ? QString::fromStdString(*maybeName) : QString(""); +} + +QList<quint64> WebContentsAdapter::frameChildren(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, {}); + QList<quint64> result; + size_t numChildren = ftn->child_count(); + result.reserve(numChildren); + for (size_t i = 0; i < numChildren; ++i) { + result.push_back(ftn->child_at(i)->frame_tree_node_id()); + } + return result; +} + +QUrl WebContentsAdapter::frameUrl(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QUrl()); + return toQt(ftn->current_url()); +} + +QSizeF WebContentsAdapter::frameSize(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, QSizeF()); + auto *rfh = ftn->current_frame_host(); + Q_ASSERT(rfh); + auto maybeSize = rfh->GetFrameSize(); + return maybeSize ? toQt(*maybeSize) : QSizeF(); +} + +std::optional<quint64> WebContentsAdapter::findFrameIdByName(const QString &name) const +{ + CHECK_INITIALIZED({}); + auto *ftn = content::FrameTreeNode::From(m_webContents->GetPrimaryMainFrame()); + Q_ASSERT(ftn); + if (auto *foundFtn = ftn->frame_tree().FindByName(name.toStdString())) + return foundFtn->frame_tree_node_id(); + return {}; +} + +bool WebContentsAdapter::hasFrame(quint64 id) const +{ + CHECK_INITIALIZED_AND_VALID_FRAME(id, ftn, false); + auto *rfh = ftn->current_frame_host(); + Q_ASSERT(rfh); + return content::WebContents::FromRenderFrameHost(rfh) == m_webContents.get(); +} + WebContentsAdapterClient::RenderProcessTerminationStatus WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1); @@ -1776,18 +1894,20 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { status = WebContentsAdapterClient::NormalTerminationStatus; break; case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + case base::TERMINATION_STATUS_LAUNCH_FAILED: status = WebContentsAdapterClient::AbnormalTerminationStatus; break; case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: -#if defined(OS_CHROMEOS) - case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: -#endif + case base::TERMINATION_STATUS_OOM: status = WebContentsAdapterClient::KilledTerminationStatus; break; case base::TERMINATION_STATUS_PROCESS_CRASHED: -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) case base::TERMINATION_STATUS_OOM_PROTECTED: #endif +#if BUILDFLAG(IS_WIN) + case base::TERMINATION_STATUS_INTEGRITY_FAILURE: +#endif status = WebContentsAdapterClient::CrashedTerminationStatus; break; case base::TERMINATION_STATUS_STILL_RUNNING: @@ -1809,7 +1929,7 @@ void WebContentsAdapter::viewSource() { CHECK_INITIALIZED(); base::RecordAction(base::UserMetricsAction("ViewSource")); - m_webContents->GetMainFrame()->ViewSource(); + m_webContents->GetPrimaryMainFrame()->ViewSource(); } bool WebContentsAdapter::canViewSource() @@ -1921,7 +2041,7 @@ WebContentsAdapter::LifecycleState WebContentsAdapter::determineRecommendedState // Do not discard PDFs as they might contain entry that is not saved and they // don't remember their scrolling positions. See crbug.com/547286 and // crbug.com/65244. - if (m_webContents->GetContentsMimeType() == "application/pdf") + if (m_webContents->GetContentsMimeType() == kPDFMimeType) return LifecycleState::Frozen; return LifecycleState::Discarded; @@ -1996,7 +2116,7 @@ void WebContentsAdapter::discard() nullContents->SetWasDiscarded(true); // Kill render process if this is the only page it's got. - content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess(); + content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess(); renderProcessHost->FastShutdownIfPossible(/* page_count */ 1u, /* skip_unload_handlers */ false); @@ -2033,7 +2153,7 @@ void WebContentsAdapter::undiscard() // Create a RenderView with the initial empty document content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); Q_ASSERT(rvh); - if (!rvh->IsRenderViewLive()) + if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive()) static_cast<content::WebContentsImpl *>(m_webContents.get()) ->CreateRenderViewForRenderManager(rvh, absl::nullopt, nullptr); m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh); |