diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml index c133e121d17bde0278b60c65288faf8fd11a5003..3465e0da6ad5d5fe07b9914944718db5351df1e0 100644 --- a/examples/webengine/quicknanobrowser/BrowserWindow.qml +++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml @@ -140,6 +140,27 @@ ApplicationWindow { id: navigationBar RowLayout { anchors.fill: parent; + ToolButton { + enabled: currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward) + menu:Menu { + id: historyMenu + + Instantiator { + model: currentWebView && currentWebView.navigationHistory.items + MenuItem { + text: model.title + onTriggered: currentWebView.goBackOrForward(model.offset) + checkable: !enabled + checked: !enabled + enabled: model.offset + } + + onObjectAdded: historyMenu.insertItem(index, object) + onObjectRemoved: historyMenu.removeItem(object) + } + } + } + ToolButton { id: backButton iconSource: "icons/go-previous.png" diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp index f8c354eacb947d8395376e6d3699409d921a7612..3b6d7bb2f92bf1e990db232d482585b7682896b8 100644 --- a/src/webengine/api/qquickwebenginehistory.cpp +++ b/src/webengine/api/qquickwebenginehistory.cpp @@ -51,6 +51,23 @@ QQuickWebEngineHistoryListModelPrivate::~QQuickWebEngineHistoryListModelPrivate( { } +int QQuickWebEngineHistoryListModelPrivate::count() const +{ + if (!adapter()) + return -1; + return adapter()->navigationEntryCount(); +} + +int QQuickWebEngineHistoryListModelPrivate::index(int index) const +{ + return index; +} + +int QQuickWebEngineHistoryListModelPrivate::offsetForIndex(int index) const +{ + return index - adapter()->currentNavigationEntryIndex(); +} + WebContentsAdapter *QQuickWebEngineHistoryListModelPrivate::adapter() const { return view->adapter.data(); @@ -74,6 +91,11 @@ int QQuickWebEngineBackHistoryListModelPrivate::index(int i) const return count() - 1 - i; } +int QQuickWebEngineBackHistoryListModelPrivate::offsetForIndex(int index) const +{ + return - index - 1; +} + QQuickWebEngineForwardHistoryListModelPrivate::QQuickWebEngineForwardHistoryListModelPrivate(QQuickWebEngineViewPrivate *view) : QQuickWebEngineHistoryListModelPrivate(view) { @@ -91,6 +113,11 @@ int QQuickWebEngineForwardHistoryListModelPrivate::index(int i) const return adapter()->currentNavigationEntryIndex() + i + 1; } +int QQuickWebEngineForwardHistoryListModelPrivate::offsetForIndex(int index) const +{ + return index + 1; +} + QQuickWebEngineHistoryListModel::QQuickWebEngineHistoryListModel() : QAbstractListModel() { @@ -111,6 +138,7 @@ QHash<int, QByteArray> QQuickWebEngineHistoryListModel::roleNames() const QHash<int, QByteArray> roles; roles[QQuickWebEngineHistory::UrlRole] = "url"; roles[QQuickWebEngineHistory::TitleRole] = "title"; + roles[QQuickWebEngineHistory::OffsetRole] = "offset"; return roles; } @@ -128,7 +156,7 @@ QVariant QQuickWebEngineHistoryListModel::data(const QModelIndex &index, int rol if (!index.isValid()) return QVariant(); - if (role < QQuickWebEngineHistory::UrlRole || role > QQuickWebEngineHistory::TitleRole) + if (role < QQuickWebEngineHistory::UrlRole || role > QQuickWebEngineHistory::OffsetRole) return QVariant(); if (role == QQuickWebEngineHistory::UrlRole) @@ -137,6 +165,8 @@ QVariant QQuickWebEngineHistoryListModel::data(const QModelIndex &index, int rol if (role == QQuickWebEngineHistory::TitleRole) return QString(d->adapter()->getNavigationEntryTitle(d->index(index.row()))); + if (role == QQuickWebEngineHistory::OffsetRole) + return d->offsetForIndex(index.row()); return QVariant(); } @@ -147,8 +177,7 @@ void QQuickWebEngineHistoryListModel::reset() } QQuickWebEngineHistoryPrivate::QQuickWebEngineHistoryPrivate(QQuickWebEngineViewPrivate *view) - : m_backNavigationModel(new QQuickWebEngineHistoryListModel(new QQuickWebEngineBackHistoryListModelPrivate(view))) - , m_forwardNavigationModel(new QQuickWebEngineHistoryListModel(new QQuickWebEngineForwardHistoryListModelPrivate(view))) + : m_view(view) { } @@ -165,23 +194,39 @@ QQuickWebEngineHistory::~QQuickWebEngineHistory() { } +QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::items() const +{ + Q_D(const QQuickWebEngineHistory); + if (!d->m_navigationModel) + d->m_navigationModel.reset(new QQuickWebEngineHistoryListModel(new QQuickWebEngineHistoryListModelPrivate(d->m_view))); + return d->m_navigationModel.data(); +} + QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::backItems() const { Q_D(const QQuickWebEngineHistory); + if (!d->m_backNavigationModel) + d->m_backNavigationModel.reset(new QQuickWebEngineHistoryListModel(new QQuickWebEngineBackHistoryListModelPrivate(d->m_view))); return d->m_backNavigationModel.data(); } QQuickWebEngineHistoryListModel *QQuickWebEngineHistory::forwardItems() const { Q_D(const QQuickWebEngineHistory); + if (!d->m_forwardNavigationModel) + d->m_forwardNavigationModel.reset(new QQuickWebEngineHistoryListModel(new QQuickWebEngineForwardHistoryListModelPrivate(d->m_view))); return d->m_forwardNavigationModel.data(); } void QQuickWebEngineHistory::reset() { Q_D(QQuickWebEngineHistory); - d->m_backNavigationModel->reset(); - d->m_forwardNavigationModel->reset(); + if (d->m_navigationModel) + d->m_navigationModel->reset(); + if (d->m_backNavigationModel) + d->m_backNavigationModel->reset(); + if (d->m_forwardNavigationModel) + d->m_forwardNavigationModel->reset(); } diff --git a/src/webengine/api/qquickwebenginehistory_p.h b/src/webengine/api/qquickwebenginehistory_p.h index 5a68fdd9684d53a088bced69f1957e22d1d48912..02f29b35b66b84267c33245f52270c0cb10b02cc 100644 --- a/src/webengine/api/qquickwebenginehistory_p.h +++ b/src/webengine/api/qquickwebenginehistory_p.h @@ -37,7 +37,7 @@ #ifndef QQUICKWEBENGINEHISTORY_P_H #define QQUICKWEBENGINEHISTORY_P_H -#include <qtwebengineglobal_p.h> +#include <qtwebengineglobal.h> #include <QAbstractListModel> #include <QtCore/qshareddata.h> #include <QQuickItem> @@ -54,7 +54,7 @@ class QQuickWebEngineHistoryListModelPrivate; class QQuickWebEngineLoadRequest; class QQuickWebEngineViewPrivate; -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineHistoryListModel : public QAbstractListModel { +class Q_WEBENGINE_EXPORT QQuickWebEngineHistoryListModel : public QAbstractListModel { Q_OBJECT public: @@ -75,8 +75,9 @@ private: friend class QQuickWebEngineHistory; }; -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineHistory : public QQuickItem { +class Q_WEBENGINE_EXPORT QQuickWebEngineHistory : public QQuickItem { Q_OBJECT + Q_PROPERTY(QQuickWebEngineHistoryListModel *items READ items CONSTANT FINAL) Q_PROPERTY(QQuickWebEngineHistoryListModel *backItems READ backItems CONSTANT FINAL) Q_PROPERTY(QQuickWebEngineHistoryListModel *forwardItems READ forwardItems CONSTANT FINAL) @@ -86,9 +87,11 @@ public: enum NavigationHistoryRoles { UrlRole = Qt::UserRole + 1, - TitleRole = Qt::UserRole + 2 + TitleRole = Qt::UserRole + 2, + OffsetRole = Qt::UserRole + 3, }; + QQuickWebEngineHistoryListModel *items() const; QQuickWebEngineHistoryListModel *backItems() const; QQuickWebEngineHistoryListModel *forwardItems() const; diff --git a/src/webengine/api/qquickwebenginehistory_p_p.h b/src/webengine/api/qquickwebenginehistory_p_p.h index ad9b1ffaf5476ae7d8e83f789006495e9ceb562a..2ad2af26fe2d613c619e5ee3bbc7460c3bf07f5f 100644 --- a/src/webengine/api/qquickwebenginehistory_p_p.h +++ b/src/webengine/api/qquickwebenginehistory_p_p.h @@ -48,8 +48,9 @@ public: QQuickWebEngineHistoryListModelPrivate(QQuickWebEngineViewPrivate*); virtual ~QQuickWebEngineHistoryListModelPrivate(); - virtual int count() const = 0; - virtual int index(int) const = 0; + virtual int count() const; + virtual int index(int) const; + virtual int offsetForIndex(int) const; WebContentsAdapter *adapter() const; @@ -60,16 +61,18 @@ class QQuickWebEngineBackHistoryListModelPrivate : public QQuickWebEngineHistory public: QQuickWebEngineBackHistoryListModelPrivate(QQuickWebEngineViewPrivate*); - int count() const; - int index(int) const; + int count() const override; + int index(int) const override; + int offsetForIndex(int) const override; }; class QQuickWebEngineForwardHistoryListModelPrivate : public QQuickWebEngineHistoryListModelPrivate { public: QQuickWebEngineForwardHistoryListModelPrivate(QQuickWebEngineViewPrivate*); - int count() const; - int index(int) const; + int count() const override; + int index(int) const override; + int offsetForIndex(int) const override; }; class QQuickWebEngineHistoryPrivate { @@ -77,8 +80,10 @@ public: QQuickWebEngineHistoryPrivate(QQuickWebEngineViewPrivate*); ~QQuickWebEngineHistoryPrivate(); - QScopedPointer<QQuickWebEngineHistoryListModel> m_backNavigationModel; - QScopedPointer<QQuickWebEngineHistoryListModel> m_forwardNavigationModel; + QQuickWebEngineViewPrivate *m_view; + mutable QScopedPointer<QQuickWebEngineHistoryListModel> m_navigationModel; + mutable QScopedPointer<QQuickWebEngineHistoryListModel> m_backNavigationModel; + mutable QScopedPointer<QQuickWebEngineHistoryListModel> m_forwardNavigationModel; }; QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 69120daa055048597d7f5348ccc76acfde21f340..9bcb7d32623f3032a491a0fbd0622fed739b0b26 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -807,9 +807,10 @@ void QQuickWebEngineViewExperimental::findText(const QString &subString, FindFla } } -QQuickWebEngineHistory *QQuickWebEngineViewExperimental::navigationHistory() const +QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const { - return d_ptr->m_history.data(); + Q_D(const QQuickWebEngineView); + return d->m_history.data(); } /*! @@ -874,26 +875,19 @@ void QQuickWebEngineViewExperimental::grantFeaturePermission(const QUrl &securit } } -void QQuickWebEngineViewExperimental::goBackTo(int index) +void QQuickWebEngineView::goBackOrForward(int offset) { - if (!d_ptr->adapter) - return; - int count = d_ptr->adapter->currentNavigationEntryIndex(); - if (index < 0 || index >= count) + Q_D(QQuickWebEngineView); + if (!d->adapter) return; + const int current = d->adapter->currentNavigationEntryIndex(); + const int count = d->adapter->navigationEntryCount(); + const int index = current + offset; - d_ptr->adapter->navigateToIndex(count - 1 - index); -} - -void QQuickWebEngineViewExperimental::goForwardTo(int index) -{ - if (!d_ptr->adapter) - return; - int count = d_ptr->adapter->navigationEntryCount() - d_ptr->adapter->currentNavigationEntryIndex() - 1; if (index < 0 || index >= count) return; - d_ptr->adapter->navigateToIndex(d_ptr->adapter->currentNavigationEntryIndex() + 1 + index); + d->adapter->navigateToIndex(index); } void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 91fd4f654aaa9bbe22ad5ee2a24eb73cb8aad3b5..a9f387e8731f1402e6e0efed57b0977c6a575774 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -44,6 +44,7 @@ QT_BEGIN_NAMESPACE class QQmlWebChannel; class QQuickWebEngineCertificateError; +class QQuickWebEngineHistory; class QQuickWebEngineLoadRequest; class QQuickWebEngineNavigationRequest; class QQuickWebEngineNewViewRequest; @@ -64,6 +65,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged REVISION 1) Q_PROPERTY(QQuickWebEngineProfile *profile READ profile WRITE setProfile FINAL REVISION 1) Q_PROPERTY(QQuickWebEngineSettings *settings READ settings REVISION 1) + Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL REVISION 1) Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1) Q_ENUMS(NavigationRequestAction); Q_ENUMS(NavigationType); @@ -147,12 +149,14 @@ public: QQuickWebEngineSettings *settings() const; QQmlWebChannel *webChannel(); void setWebChannel(QQmlWebChannel *); + QQuickWebEngineHistory *navigationHistory() const; public Q_SLOTS: void runJavaScript(const QString&, const QJSValue & = QJSValue()); void loadHtml(const QString &html, const QUrl &baseUrl = QUrl()); void goBack(); void goForward(); + void goBackOrForward(int index); void reload(); void stop(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 14770282ef5e3923fde82308223f90f887fc4975..a3b29af19019defc23e99b54594c64b1f9a7f051 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -50,7 +50,6 @@ class WebContentsAdapter; class UIDelegatesManager; QT_BEGIN_NAMESPACE -class QQuickWebEngineHistory; class QQuickWebEngineView; class QQmlComponent; class QQmlContext; @@ -79,7 +78,6 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObjec Q_PROPERTY(QQuickWebEngineViewport *viewport READ viewport) Q_PROPERTY(QQmlComponent *extraContextMenuEntriesComponent READ extraContextMenuEntriesComponent WRITE setExtraContextMenuEntriesComponent NOTIFY extraContextMenuEntriesComponentChanged) Q_PROPERTY(bool isFullScreen READ isFullScreen WRITE setIsFullScreen NOTIFY isFullScreenChanged) - Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL) Q_ENUMS(Feature) Q_FLAGS(FindFlags) @@ -102,11 +100,8 @@ public: QQuickWebEngineViewport *viewport() const; void setExtraContextMenuEntriesComponent(QQmlComponent *); QQmlComponent *extraContextMenuEntriesComponent() const; - QQuickWebEngineHistory *navigationHistory() const; public Q_SLOTS: - void goBackTo(int index); - void goForwardTo(int index); void findText(const QString&, FindFlags, const QJSValue & = QJSValue()); void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted); diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp index 857f1de0ebe661b0e558bc0ddc4dfe46c2a1fbdf..29b5413f47c52121681fe4f174a90e94e442f796 100644 --- a/src/webengine/plugin/experimental/plugin.cpp +++ b/src/webengine/plugin/experimental/plugin.cpp @@ -36,7 +36,6 @@ #include <QtQml/qqmlextensionplugin.h> -#include "qquickwebenginehistory_p.h" #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" @@ -67,10 +66,6 @@ public: QObject::tr("Cannot create a separate instance of WebEngineViewExperimental")); qmlRegisterUncreatableType<QQuickWebEngineViewport>(uri, 1, 0, "WebEngineViewport", QObject::tr("Cannot create a separate instance of WebEngineViewport")); - qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 0, "NavigationHistory", - QObject::tr("Cannot create a separate instance of NavigationHistory")); - qmlRegisterUncreatableType<QQuickWebEngineHistoryListModel>(uri, 1, 0, "NavigationHistoryListModel", - QObject::tr("Cannot create a separate instance of NavigationHistory")); // Use the latest revision of QQuickWebEngineView when importing QtWebEngine.experimental 1.0 qmlRegisterRevision<QQuickWebEngineView, 1>(uri, 1, 0); diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index da1b4f81bc40e0d3f8d7ad3de90f839a641ef271..b752315f7a95ce284aec8d05e5138bcf33d9dd9f 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -38,6 +38,7 @@ #include "qquickwebenginecertificateerror_p.h" #include "qquickwebenginedownloaditem_p.h" +#include "qquickwebenginehistory_p.h" #include "qquickwebengineloadrequest_p.h" #include "qquickwebenginenavigationrequest_p.h" #include "qquickwebenginenewviewrequest_p.h" @@ -75,6 +76,10 @@ public: qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", QObject::tr("Cannot create separate instance of WebEngineNewViewRequest")); qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", QObject::tr("Cannot create a separate instance of WebEngineSettings")); qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider); + qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory", + QObject::tr("Cannot create a separate instance of NavigationHistory")); + qmlRegisterUncreatableType<QQuickWebEngineHistoryListModel>(uri, 1, 1, "NavigationHistoryListModel", + QObject::tr("Cannot create a separate instance of NavigationHistory")); } }; diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index 42c58bf145b701c0ffd2c0d06ed14e7d5162c8c7..605eaa041c0bc954a1efdbcd772f008e6b45dcf1 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -48,6 +48,7 @@ #include <private/qquickwebengineview_p.h> #include <private/qquickwebenginecertificateerror_p.h> #include <private/qquickwebenginedownloaditem_p.h> +#include <private/qquickwebenginehistory_p.h> #include <private/qquickwebengineloadrequest_p.h> #include <private/qquickwebenginenavigationrequest_p.h> #include <private/qquickwebenginenewviewrequest_p.h> @@ -63,6 +64,8 @@ static QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *>() << &QQuickWebEngineView::staticMetaObject << &QQuickWebEngineCertificateError::staticMetaObject << &QQuickWebEngineDownloadItem::staticMetaObject + << &QQuickWebEngineHistory::staticMetaObject + << &QQuickWebEngineHistoryListModel::staticMetaObject << &QQuickWebEngineLoadRequest::staticMetaObject << &QQuickWebEngineNavigationRequest::staticMetaObject << &QQuickWebEngineNewViewRequest::staticMetaObject @@ -123,7 +126,6 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineView.loading --> bool" << "QQuickWebEngineView.loadProgress --> int" << "QQuickWebEngineView.titleChanged() --> void" - << "QQuickWebEngineView.navigationHistoryChanged() --> void" << "QQuickWebEngineView.loadingChanged(QQuickWebEngineLoadRequest*) --> void" << "QQuickWebEngineView.certificateError(QQuickWebEngineCertificateError*) --> void" << "QQuickWebEngineView.loadProgressChanged() --> void" @@ -138,11 +140,13 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineView.loadHtml(QString) --> void" << "QQuickWebEngineView.goBack() --> void" << "QQuickWebEngineView.goForward() --> void" + << "QQuickWebEngineView.goBackOrForward(int) --> void" << "QQuickWebEngineView.stop() --> void" << "QQuickWebEngineView.reload() --> void" << "QQuickWebEngineView.zoomFactor --> double" << "QQuickWebEngineView.zoomFactorChanged(double) --> void" << "QQuickWebEngineView.profile --> QQuickWebEngineProfile*" + << "QQuickWebEngineView.navigationHistory --> QQuickWebEngineHistory*" << "QQuickWebEngineView.newViewRequested(QQuickWebEngineNewViewRequest*) --> void" << "QQuickWebEngineDownloadItem.id --> uint" << "QQuickWebEngineDownloadItem.state --> DownloadState" @@ -156,6 +160,9 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineDownloadItem.progressChanged() --> void" << "QQuickWebEngineDownloadItem.pathChanged() --> void" << "QQuickWebEngineDownloadItem.cancel() --> void" + << "QQuickWebEngineHistory.items --> QQuickWebEngineHistoryListModel*" + << "QQuickWebEngineHistory.backItems --> QQuickWebEngineHistoryListModel*" + << "QQuickWebEngineHistory.forwardItems --> QQuickWebEngineHistoryListModel*" << "QQuickWebEngineLoadRequest.url --> QUrl" << "QQuickWebEngineLoadRequest.status --> QQuickWebEngineView::LoadStatus" << "QQuickWebEngineLoadRequest.errorString --> QString" diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml index 9312ed20e9a17a912438c2d2a0bd0b1c8dcc01b4..2c8e9e1ea111f606f788da1d15c00418edc4a4d1 100644 --- a/tests/quicktestbrowser/BrowserWindow.qml +++ b/tests/quicktestbrowser/BrowserWindow.qml @@ -161,10 +161,10 @@ ApplicationWindow { id: backHistoryMenu Instantiator { - model: currentWebView && currentWebView.experimental.navigationHistory.backItems + model: currentWebView && currentWebView.navigationHistory.backItems MenuItem { text: model.title - onTriggered: currentWebView.experimental.goBackTo(index) + onTriggered: currentWebView.goBackOrForward(model.offset) } onObjectAdded: backHistoryMenu.insertItem(index, object) @@ -176,10 +176,10 @@ ApplicationWindow { id: forwardHistoryMenu Instantiator { - model: currentWebView && currentWebView.experimental.navigationHistory.forwardItems + model: currentWebView && currentWebView.navigationHistory.forwardItems MenuItem { text: model.title - onTriggered: currentWebView.experimental.goForwardTo(index) + onTriggered: currentWebView.goBackOrForward(model.offset) } onObjectAdded: forwardHistoryMenu.insertItem(index, object)