summaryrefslogtreecommitdiffstats
path: root/src/core/api/qwebenginehistory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/api/qwebenginehistory.cpp')
-rw-r--r--src/core/api/qwebenginehistory.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/src/core/api/qwebenginehistory.cpp b/src/core/api/qwebenginehistory.cpp
new file mode 100644
index 000000000..5d2fc8e9e
--- /dev/null
+++ b/src/core/api/qwebenginehistory.cpp
@@ -0,0 +1,389 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebenginehistory.h"
+#include "qwebenginehistory_p.h"
+
+#include "web_contents_adapter.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \fn QWebEngineHistoryItem::swap(QWebEngineHistoryItem &other)
+ Swaps the history item with the \a other item.
+*/
+
+QWebEngineHistoryItemPrivate::QWebEngineHistoryItemPrivate(
+ QtWebEngineCore::WebContentsAdapterClient *client, int index)
+ : client(client), index(index)
+{
+}
+
+QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryItemPrivate::adapter() const
+{
+ return client ? client->webContentsAdapter() : nullptr;
+}
+
+QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *d) : d(d) { }
+QWebEngineHistoryItem::QWebEngineHistoryItem(const QWebEngineHistoryItem &other) = default;
+QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItem &&other) = default;
+QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(const QWebEngineHistoryItem &other) = default;
+QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(QWebEngineHistoryItem &&other) = default;
+QWebEngineHistoryItem::~QWebEngineHistoryItem() = default;
+
+QUrl QWebEngineHistoryItem::originalUrl() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ return d->adapter() ? d->adapter()->getNavigationEntryOriginalUrl(d->index) : QUrl();
+}
+
+QUrl QWebEngineHistoryItem::url() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ return d->adapter() ? d->adapter()->getNavigationEntryUrl(d->index) : QUrl();
+}
+
+QString QWebEngineHistoryItem::title() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ return d->adapter() ? d->adapter()->getNavigationEntryTitle(d->index) : QString();
+}
+
+QDateTime QWebEngineHistoryItem::lastVisited() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ return d->adapter() ? d->adapter()->getNavigationEntryTimestamp(d->index) : QDateTime();
+}
+
+/*!
+ Returns the URL of the icon associated with the history item.
+
+ \sa url(), originalUrl(), title()
+*/
+QUrl QWebEngineHistoryItem::iconUrl() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ return d->adapter() ? d->adapter()->getNavigationEntryIconUrl(d->index) : QUrl();
+}
+
+bool QWebEngineHistoryItem::isValid() const
+{
+ Q_D(const QWebEngineHistoryItem);
+ if (!d->client)
+ return false;
+ return d->index >= 0 && d->index < d->adapter()->navigationEntryCount();
+}
+
+QWebEngineHistoryPrivate::QWebEngineHistoryPrivate(QtWebEngineCore::WebContentsAdapterClient *client,
+ const ImageProviderUrl &imageProviderUrl)
+ : client(client), imageProviderUrl(imageProviderUrl)
+{
+ Q_ASSERT(client);
+}
+
+QWebEngineHistoryPrivate::~QWebEngineHistoryPrivate()
+{
+ // Invalidate shared item references possibly still out there.
+ QList<QWebEngineHistoryItem>::iterator it, end;
+ for (it = items.begin(), end = items.end(); it != end; ++it)
+ it->d->client = nullptr;
+}
+
+void QWebEngineHistoryPrivate::updateItems() const
+{
+ // Keep track of items we return to be able to invalidate them
+ // and avoid dangling references to our client.
+ int entryCount = adapter()->navigationEntryCount();
+ while (items.size() > entryCount) {
+ items.last().d->client = nullptr;
+ items.removeLast();
+ }
+ while (items.size() < entryCount) {
+ int nextIndex = items.size();
+ items.append(QWebEngineHistoryItem(new QWebEngineHistoryItemPrivate(client, nextIndex)));
+ }
+}
+
+QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryPrivate::adapter() const
+{
+ Q_ASSERT(client->webContentsAdapter());
+ return client->webContentsAdapter();
+}
+
+QWebEngineHistoryModelPrivate::QWebEngineHistoryModelPrivate(const QWebEngineHistoryPrivate *history)
+ : history(history)
+{
+ Q_ASSERT(history);
+}
+
+QWebEngineHistoryModelPrivate::~QWebEngineHistoryModelPrivate()
+{
+}
+
+QtWebEngineCore::WebContentsAdapter *QWebEngineHistoryModelPrivate::adapter() const
+{
+ Q_ASSERT(history->adapter());
+ return history->adapter();
+}
+
+int QWebEngineHistoryModelPrivate::count() const
+{
+ return adapter()->navigationEntryCount();
+}
+
+int QWebEngineHistoryModelPrivate::index(int index) const
+{
+ return index;
+}
+
+int QWebEngineHistoryModelPrivate::offsetForIndex(int index) const
+{
+ return index - adapter()->currentNavigationEntryIndex();
+}
+
+int QWebEngineBackHistoryModelPrivate::count() const
+{
+ return adapter()->currentNavigationEntryIndex();
+}
+
+int QWebEngineBackHistoryModelPrivate::index(int i) const
+{
+ Q_ASSERT(i >= 0 && i < count());
+ return count() - 1 - i;
+}
+
+int QWebEngineBackHistoryModelPrivate::offsetForIndex(int index) const
+{
+ return - index - 1;
+}
+
+int QWebEngineForwardHistoryModelPrivate::count() const
+{
+ if (!adapter()->isInitialized())
+ return 0;
+ return adapter()->navigationEntryCount() - adapter()->currentNavigationEntryIndex() - 1;
+}
+
+int QWebEngineForwardHistoryModelPrivate::index(int i) const
+{
+ return adapter()->currentNavigationEntryIndex() + i + 1;
+}
+
+int QWebEngineForwardHistoryModelPrivate::offsetForIndex(int index) const
+{
+ return index + 1;
+}
+
+QWebEngineHistoryModel::QWebEngineHistoryModel(QWebEngineHistoryModelPrivate *d)
+ : d_ptr(d)
+{
+}
+
+QWebEngineHistoryModel::~QWebEngineHistoryModel()
+{
+}
+
+QHash<int, QByteArray> QWebEngineHistoryModel::roleNames() const
+{
+ QHash<int, QByteArray> roles;
+ roles[Qt::DisplayRole] = "display";
+ roles[Qt::ToolTipRole] = "toolTip";
+ roles[UrlRole] = "url";
+ roles[TitleRole] = "title";
+ roles[OffsetRole] = "offset";
+ roles[IconUrlRole] = "icon";
+ return roles;
+}
+
+int QWebEngineHistoryModel::rowCount(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ Q_D(const QWebEngineHistoryModel);
+ return d->count();
+}
+
+QVariant QWebEngineHistoryModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const QWebEngineHistoryModel);
+
+ if (!index.isValid())
+ return QVariant();
+
+ switch (role) {
+ case Qt::DisplayRole:
+ case TitleRole:
+ return d->adapter()->getNavigationEntryTitle(d->index(index.row()));
+
+ case Qt::ToolTipRole:
+ case UrlRole:
+ return d->adapter()->getNavigationEntryUrl(d->index(index.row()));
+
+ case OffsetRole:
+ return d->offsetForIndex(index.row());
+
+ case IconUrlRole: {
+ QUrl url = QUrl(d->adapter()->getNavigationEntryIconUrl(d->index(index.row())));
+ return d->history->urlOrImageProviderUrl(url);
+ }
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+void QWebEngineHistoryModel::reset()
+{
+ beginResetModel();
+ endResetModel();
+}
+
+QWebEngineHistory::QWebEngineHistory(QWebEngineHistoryPrivate *d) : d_ptr(d) { }
+
+QWebEngineHistory::~QWebEngineHistory() { }
+
+void QWebEngineHistory::clear()
+{
+ Q_D(const QWebEngineHistory);
+ d->adapter()->clearNavigationHistory();
+ d->client->updateNavigationActions();
+ reset();
+}
+
+QList<QWebEngineHistoryItem> QWebEngineHistory::items() const
+{
+ Q_D(const QWebEngineHistory);
+ d->updateItems();
+ return d->items;
+}
+
+QList<QWebEngineHistoryItem> QWebEngineHistory::backItems(int maxItems) const
+{
+ Q_D(const QWebEngineHistory);
+ d->updateItems();
+ const int end = currentItemIndex();
+ const int start = std::max(0, end - maxItems);
+ return d->items.mid(start, end - start);
+}
+
+QList<QWebEngineHistoryItem> QWebEngineHistory::forwardItems(int maxItems) const
+{
+ Q_D(const QWebEngineHistory);
+ d->updateItems();
+ const int start = currentItemIndex() + 1;
+ const int end = std::min(count(), start + maxItems);
+ return d->items.mid(start, end - start);
+}
+
+bool QWebEngineHistory::canGoBack() const
+{
+ Q_D(const QWebEngineHistory);
+ return d->adapter()->canGoToOffset(-1);
+}
+
+bool QWebEngineHistory::canGoForward() const
+{
+ Q_D(const QWebEngineHistory);
+ return d->adapter()->canGoToOffset(1);
+}
+
+void QWebEngineHistory::back()
+{
+ Q_D(const QWebEngineHistory);
+ d->adapter()->navigateToOffset(-1);
+}
+
+void QWebEngineHistory::forward()
+{
+ Q_D(const QWebEngineHistory);
+ d->adapter()->navigateToOffset(1);
+}
+
+void QWebEngineHistory::goToItem(const QWebEngineHistoryItem &item)
+{
+ Q_D(const QWebEngineHistory);
+ Q_ASSERT(item.d->client == d->client);
+ d->adapter()->navigateToIndex(item.d->index);
+}
+
+QWebEngineHistoryItem QWebEngineHistory::backItem() const
+{
+ return itemAt(currentItemIndex() - 1);
+}
+
+QWebEngineHistoryItem QWebEngineHistory::currentItem() const
+{
+ return itemAt(currentItemIndex());
+}
+
+QWebEngineHistoryItem QWebEngineHistory::forwardItem() const
+{
+ return itemAt(currentItemIndex() + 1);
+}
+
+QWebEngineHistoryItem QWebEngineHistory::itemAt(int i) const
+{
+ Q_D(const QWebEngineHistory);
+ if (i >= 0 && i < count()) {
+ d->updateItems();
+ return d->items[i];
+ } else {
+ // Return an invalid item right away.
+ QWebEngineHistoryItem item(new QWebEngineHistoryItemPrivate(0, i));
+ Q_ASSERT(!item.isValid());
+ return item;
+ }
+}
+
+int QWebEngineHistory::currentItemIndex() const
+{
+ Q_D(const QWebEngineHistory);
+ return d->adapter()->currentNavigationEntryIndex();
+}
+
+int QWebEngineHistory::count() const
+{
+ Q_D(const QWebEngineHistory);
+ if (!d->adapter()->isInitialized())
+ return 0;
+ return d->adapter()->navigationEntryCount();
+}
+
+QWebEngineHistoryModel *QWebEngineHistory::itemsModel() const
+{
+ Q_D(const QWebEngineHistory);
+ if (!d->navigationModel)
+ d->navigationModel.reset(new QWebEngineHistoryModel(new QWebEngineHistoryModelPrivate(d)));
+ return d->navigationModel.data();
+}
+
+QWebEngineHistoryModel *QWebEngineHistory::backItemsModel() const
+{
+ Q_D(const QWebEngineHistory);
+ if (!d->backNavigationModel)
+ d->backNavigationModel.reset(new QWebEngineHistoryModel(new QWebEngineBackHistoryModelPrivate(d)));
+ return d->backNavigationModel.data();
+}
+
+QWebEngineHistoryModel *QWebEngineHistory::forwardItemsModel() const
+{
+ Q_D(const QWebEngineHistory);
+ if (!d->forwardNavigationModel)
+ d->forwardNavigationModel.reset(new QWebEngineHistoryModel(new QWebEngineForwardHistoryModelPrivate(d)));
+ return d->forwardNavigationModel.data();
+}
+
+void QWebEngineHistory::reset()
+{
+ Q_D(QWebEngineHistory);
+ if (d->navigationModel)
+ d->navigationModel->reset();
+ if (d->backNavigationModel)
+ d->backNavigationModel->reset();
+ if (d->forwardNavigationModel)
+ d->forwardNavigationModel->reset();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginehistory.cpp"