File indexing completed on 2024-05-19 05:01:19
0001 /* 0002 This file is part of the KDE project. 0003 0004 SPDX-FileCopyrightText: 2022 Stefano Crocco <stefano.crocco@alice.it> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #include "navigationrecorder.h" 0010 #include "webenginepage.h" 0011 0012 NavigationRecorder::NavigationRecorder(QObject *parent) : QObject(parent) 0013 { 0014 } 0015 0016 NavigationRecorder::~NavigationRecorder() noexcept 0017 { 0018 } 0019 0020 void NavigationRecorder::registerPage(WebEnginePage* page) 0021 { 0022 connect(page, &QObject::destroyed, this, &NavigationRecorder::removePage); 0023 connect(page, &WebEnginePage::mainFrameNavigationRequested, this, &NavigationRecorder::recordNavigation); 0024 connect(page, &WebEnginePage::loadFinished, this, [this, page](bool){recordNavigationFinished(page, page->url());}); 0025 } 0026 0027 void NavigationRecorder::removePage(QObject*) 0028 { 0029 //NOTE: we cannot use QMultiHash::remove because this is connected to the QObject::destroyed signal, 0030 //which is emitted *after* the WebEnginePage destructor has been called, so it cannot be cast. 0031 //The workaround is to remove all nullptr entries, since the destroyed signal is emitted after 0032 //all instances of QPointer have been notified 0033 for (const QUrl &url : m_pendingNavigations.keys()) { 0034 m_pendingNavigations.remove(url, nullptr); 0035 } 0036 for (const QUrl &url : m_postNavigations.keys()) { 0037 m_postNavigations.remove(url, nullptr); 0038 } 0039 } 0040 0041 void NavigationRecorder::recordNavigation(WebEnginePage* page, const QUrl& url) 0042 { 0043 m_pendingNavigations.insert(url, page); 0044 } 0045 0046 void NavigationRecorder::recordNavigationFinished(WebEnginePage* page, const QUrl& url) 0047 { 0048 m_postNavigations.remove(url, page); 0049 } 0050 0051 bool NavigationRecorder::isPostRequest(const QUrl& url, WebEnginePage* page) const 0052 { 0053 return m_postNavigations.contains(url, page); 0054 } 0055 0056 void NavigationRecorder::recordRequestDetails(const QWebEngineUrlRequestInfo& info) 0057 { 0058 QUrl url(info.requestUrl()); 0059 QList<QPointer<WebEnginePage>> pages = m_pendingNavigations.values(url); 0060 WebEnginePage *page = nullptr; 0061 if (!pages.isEmpty()) { 0062 //NOTE: QMultiHash::values returns a list where the first element is the one inserted last: 0063 //pages.last() is the page which first made the navigation request 0064 page = pages.last(); 0065 m_pendingNavigations.remove(url, page); 0066 } else { 0067 return; 0068 } 0069 if (info.requestMethod() == QByteArrayLiteral("POST")) { 0070 m_postNavigations.insert(url, page); 0071 } 0072 }