From 24b95ccebb11a366ac4c83265b9cd8d2e9acbbb5 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Mon, 9 Sep 2024 16:56:08 -0400 Subject: [PATCH] fixup! Temporary code for UI testing only --- kiwix-desktop.pro | 2 +- resources/js/toc.js | 202 +++++++++++++++++++++++++++++++++++---- resources/js/tocStyle.js | 143 ++++++++++++++++++++------- src/kiwixapp.cpp | 4 +- src/kprofile.cpp | 2 +- src/tabbar.cpp | 17 ++++ src/topwidget.cpp | 3 + src/urlschemehandler.cpp | 10 +- src/webpage.cpp | 55 ++++++++++- src/webpage.h | 7 ++ src/zimview.cpp | 9 ++ 11 files changed, 388 insertions(+), 66 deletions(-) diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro index a8a16cbc3..653db7f7f 100644 --- a/kiwix-desktop.pro +++ b/kiwix-desktop.pro @@ -5,7 +5,7 @@ #------------------------------------------------- QT += core gui network -QT += webenginewidgets +QT += webenginewidgets webchannel QT += printsupport # Avoid stripping incompatible files, due to false identification as executables, on WSL diff --git a/resources/js/toc.js b/resources/js/toc.js index 95ff7e7b6..542a3797d 100644 --- a/resources/js/toc.js +++ b/resources/js/toc.js @@ -1,5 +1,25 @@ const KIWIX_TAG_PREFIX = "kiwix-toc-"; + +function showToolTip (elem) { /* added argument */ + var tooltip = elem.getElementsByClassName("kiwix-tool-tip")[0]; + if (elem.offsetWidth < elem.scrollWidth) + { + tooltip.style.display="block"; /* changed variable to argument */ + + var zoom = window.outerWidth / window.document.documentElement.clientWidth; + + var rect = elem.getBoundingClientRect(); + tooltip.style.top = (rect.top).toString() + "px"; + tooltip.style.left = (rect.left + (286 / zoom.toFixed(1))).toString() + "px"; + } +} +function hideToolTip (elem) { /* added argument */ + var tooltip = elem.getElementsByClassName("kiwix-tool-tip")[0]; + tooltip.style.display=""; /* changed variable to argument */ +} + + /** * Construct recurseData.str as a nested list of headers by recursively going * through all children of elem that has header tags. @@ -26,14 +46,14 @@ function recurseChild(elem, recurseData) /* Start or end a list or item based on current and previous level */ if (level > prevLevel) - recurseData.toc += (new Array(level - prevLevel + 1)).join(''; else - recurseData.toc += (new Array(prevLevel+ 1)).join(''); + recurseData.toc += ''; recurseData.level = parseInt(level); - recurseData.toc += '
  • ' + headerText + ''; + recurseData.toc += '
  • ' + headerText + '' + headerText + ''; } var c = elem.children; @@ -57,22 +77,96 @@ function tocHTMLStr() return recurseData.toc; } +function closePop() +{ + var tocElem = document.getElementById("kiwix-toc-side"); + tocElem.style.display = "none"; + // var c = document.body.children; + // for (var i = 0; i < c.length; i++) + // { + // if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + // { + // c[i].style.marginLeft = null; + // } + // } + document.body.style.marginLeft = null + document.body.style.maxWidth = null +} + function openPop() { - var tocElem = document.getElementById("kiwix-toc"); + var tocElem = document.getElementById("kiwix-toc-side"); + tocElem.style.display = "block"; + // var zoom = window.outerWidth / window.document.documentElement.clientWidth; + // var c = document.body.children; + // for (var i = 0; i < c.length; i++) + // { + // if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + // { + // c[i].style.marginLeft = (300 / zoom.toFixed(1)).toString() + "px"; + // } + // } + + var zoom = window.outerWidth / window.document.documentElement.clientWidth; + document.body.style.marginLeft = (290 / zoom.toFixed(1)).toString() + "px"; + document.body.style.maxWidth = "calc(100vw - " + (290 / zoom.toFixed(1)).toString() + "px)"; +} + +function urlRequest(){ + + // Creating Our XMLHttpRequest object + let xhr = new XMLHttpRequest(); + + // Making our connection + let url = 'zim://kiwix-desktop'; + xhr.open("GET", url, true); + xhr.send(); +} + +function togglePop() +{ + var tocElem = document.getElementById("kiwix-toc-side"); var isTOCVisible = tocElem.style.display === "block"; - tocElem.style.display = isTOCVisible ? "none" : "block"; + + if (isTOCVisible) + { + closePop(); + urlRequest(); + } + else + { + tocElem.style.display = "block"; + var c = document.body.children; + // for (var i = 0; i < c.length; i++) + // { + // if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + // { + // c[i].style.marginLeft = "286px"; + // } + // } + // var zoom = window.outerWidth / window.document.documentElement.clientWidth; + // var c = document.body.children; + // for (var i = 0; i < c.length; i++) + // { + // if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + // { + // c[i].style.marginLeft = (300 / zoom.toFixed(1)).toString() + "px"; + // } + // } + + var zoom = window.outerWidth / window.document.documentElement.clientWidth; + document.body.style.marginLeft = (290 / zoom.toFixed(1)).toString() + "px"; + document.body.style.maxWidth = "calc(100vw - " + (290 / zoom.toFixed(1)).toString() + "px)"; + } } function tocPopupButtonElem() { - var tocPopupButton = document.createElement('input'); + var tocPopupButton = document.createElement('button'); tocPopupButton.id = "kiwix-toc-button" - tocPopupButton.onclick = openPop; - tocPopupButton.type = "image"; - tocPopupButton.src = "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' id='toc'%3E%3Cpath fill='none' d='M0 0h24v24H0V0zm0 0h24v24H0V0z'%3E%3C/path%3E%3Cpath d='M4 9h12c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zm0 4h12c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zm0 4h12c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1zm15 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z'%3E%3C/path%3E%3C/svg%3E%0A"; - tocPopupButton.width = 40; - tocPopupButton.height = 40; + tocPopupButton.onclick = togglePop; + tocPopupButton.textContent = "Hide"; + return tocPopupButton; } @@ -82,21 +176,89 @@ function setupTOC() toc.id = "kiwix-toc"; tocContent = tocHTMLStr(); - if (tocContent.length == 0) - return; - toc.innerHTML += tocContent; + var c = toc.getElementsByClassName("kiwix-toc-list-a"); + for (var i = 0; i < c.length; i++) + { + if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + { + var p = c[i].parentNode; + var count = -1; + while (p) + { + if (p.nodeName.match(/^UL$/)) + count += 1; + p = p.parentNode; + } + c[i].style.paddingLeft = ((count == -1 ? 0 : count) * 30).toString() + "px"; + + c[i].addEventListener("mouseover", (event) => {showToolTip(event.target);}); + c[i].addEventListener("mouseout", (event) => {hideToolTip(event.target);}); + } + } + + var tocTitleDiv = document.createElement('div'); + tocTitleDiv.id = "kiwix-toc-title-div"; var tocTitle = document.createElement('p'); tocTitle.id = "kiwix-toc-title"; tocTitle.textContent = KIWIX_GT_CONTENT; - toc.prepend(tocTitle); - + tocTitleDiv.append(tocTitle); + tocTitleDiv.append(tocPopupButtonElem()); + var tocDiv = document.createElement('div'); tocDiv.id = "kiwix-toc-div"; tocDiv.prepend(toc); - tocDiv.prepend(tocPopupButtonElem()); - document.body.prepend(tocDiv); + tocDiv.prepend(tocTitleDiv); + + var tocSideDiv = document.createElement('div'); + tocSideDiv.id = "kiwix-toc-side"; + tocSideDiv.style.display = "none"; + tocSideDiv.prepend(tocDiv); + + var closeBut = document.createElement('button'); + closeBut.id = "kiwix-toc-close-button" + closeBut.onclick = closePop; + closeBut.style.display = "none"; + + var openBut = document.createElement('button'); + openBut.id = "kiwix-toc-open-button" + openBut.onclick = openPop; + openBut.style.display = "none"; + + document.body.prepend(tocSideDiv); + document.body.append(closeBut); + document.body.append(openBut); } -setupTOC(); \ No newline at end of file +setupTOC(); + +function resize(){ + var zoom = window.outerWidth / window.document.documentElement.clientWidth; + var width = 286; + document.getElementById("kiwix-toc-side").style.width = (parseInt(width) / zoom.toFixed(1)).toString() + "px"; + + if (document.getElementById("kiwix-toc-side").style.display !== "none") + { + // var c = document.body.children; + // for (var i = 0; i < c.length; i++) + // { + // if (c[i] !== "undefined" && c[i].id !== "kiwix-toc-side" && c[i].style) + // { + // c[i].style.marginLeft = (parseInt(width) / zoom.toFixed(1)).toString() + "px"; + // } + // } + var zoom = window.outerWidth / window.document.documentElement.clientWidth; + document.body.style.marginLeft = (290 / zoom.toFixed(1)).toString() + "px"; + document.body.style.maxWidth = "calc(100vw - " + (290 / zoom.toFixed(1)).toString() + "px)"; + } + +} +window.onresize = resize; +resize(); + +new QWebChannel(qt.webChannelTransport, function(channel) { + + var JSobject = channel.objects.obj; + JSobject.foo(); +}); diff --git a/resources/js/tocStyle.js b/resources/js/tocStyle.js index c428474c6..242872cda 100644 --- a/resources/js/tocStyle.js +++ b/resources/js/tocStyle.js @@ -5,55 +5,92 @@ style.innerHTML = ` display: list-item; list-style-type: none; visibility: inherit; - - unicode-bidi: plaintext; - text-align: start; - - font-size: 20px; - font-family: Arial; - - margin: 5px 20px; + position: relative; + width: 100%; + // margin: 10px 30px; + // margin-right: 0px; } - + .kiwix-toc-list { all: initial; display: block; visibility: inherit; + width: 100%; margin: 0px; padding: 0px; + counter-reset: item; } .kiwix-toc-a { + all: initial; + color: inherit; + outline: inherit; + text-decoration: inherit; +} + +.kiwix-toc-a:hover { + color: inherit; + text-decoration: inherit; +} + +.kiwix-toc-list-a { + all: initial; color: inherit; outline: none; + display: block; text-decoration: none; + position: relative; + font-size: 16px; + padding-bottom: 5px; + padding-top: 5px; + line-height: 20px; + font-family: Arial; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + border: 1px solid transparent; } -.kiwix-toc-a:hover { +.kiwix-toc-list-a:hover { color: inherit; text-decoration: none; + border: 1px solid #3366CC; + background-color: #D9E9FF; + border-right: 1px solid transparent; + border-left: 1px solid transparent; + cursor: pointer; } +.kiwix-toc-list-a:before { content: counters(item, ".") " "; counter-increment: item; margin-right: 10px; padding-left: 10px; } -#kiwix-toc { +.kiwix-tool-tip { all: initial; display: none; - position: relative; + /* NEW */ + background-color: #ffffe1; + border: 1px solid black; + position: fixed; + padding: 0px; + font-size: 16px; + padding: 5px; + line-height: 20px; + font-family: Arial; + z-index: 20000; +} - max-height: 50vh; - max-width: 50vh; - width: max-content; - overflow-y: auto; +#kiwix-toc { + all: initial; + display: block; - padding: 8px; - padding-top: 0px; - background: white; - border: 1px solid #cccccc; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + position: relative; + max-height: calc(100vh - 20vh); + width: 100%; + overflow: auto; + border-top: 1px solid #ccc; } #kiwix-toc::-webkit-scrollbar { - width: 5px; + width: 0px; border: none; outline: none; } @@ -66,42 +103,74 @@ style.innerHTML = ` #kiwix-toc-title { all: initial; display: block; + align-items: center; + position: relative; visibility: inherit; - font-size: 24px; + line-height: 30px; font-weight: bold; font-family: Arial; - text-align: center; - - margin-left: auto; - margin-right: auto; + unicode-bidi: plaintext; + text-align: start; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin: 0px; + padding: 0px; } #kiwix-toc-button { all: initial; + display: flex; + align-items: center; position: relative; - display: block; background: white; + color: #3366CC; margin: 0px; - padding 0px; - outline: none; - border: 1px solid #ccc; - border-radius: 3px; + padding: 0px; + font-size: 12px; + line-height: 1; + font-family: Arial; + font-weight: bold; + margin-top: 7px; } #kiwix-toc-button:hover { - border: 1px solid #3366CC; - background-color: #D9E9FF; + text-decoration: underline; } #kiwix-toc-div { all: initial; - display: block; font-size: 0px; - margin: 8px; + padding: 0px; + margin: 0px; +} + +#kiwix-toc-title-div { + all: initial; + display: flex; + justify-content: space-between; + position: relative; + font-size: 0px; + min-height: 30px; + margin: 0px; + border: 0px; + padding: 10px; +} + +#kiwix-toc-side { + all: initial; position: fixed; top: 0px; - z-index: 1000; + left: 0px; + width: 286px; + height: 100vh; + border-right: 1px solid #ccc; + border-left: 1px solid #ccc; + background: white; + margin: 0px; + padding: 0px; + z-index: 10000; } ` document.head.appendChild(style); diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index ce0712908..683d3ba92 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -435,8 +435,7 @@ void KiwixApp::createActions() }); mpa_actions[ToggleFullscreenAction]->setCheckable(true); - CREATE_ACTION_SHORTCUT(ToggleTOCAction, gt("table-of-content"), QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_1)); - HIDE_ACTION(ToggleTOCAction); + CREATE_ACTION_ICON_SHORTCUT(ToggleTOCAction, "toc", gt("table-of-content"), QKeySequence(Qt::CTRL | Qt::Key_M)); CREATE_ACTION_ONOFF_ICON_SHORTCUT(ToggleReadingListAction, "reading-list-active", "reading-list", gt("reading-list"), QKeySequence(Qt::CTRL | Qt::Key_B)); @@ -498,6 +497,7 @@ void KiwixApp::handleItemsState(TabType tabType) app->getAction(KiwixApp::ZoomResetAction)->setDisabled(libraryOrSettingsTab); app->getAction(KiwixApp::RandomArticleAction)->setDisabled(libraryOrSettingsTab); app->getAction(KiwixApp::OpenHomePageAction)->setDisabled(libraryOrSettingsTab); + app->getAction(KiwixApp::ToggleTOCAction)->setDisabled(libraryOrSettingsTab); /* Non-Zim tabs are not bookmarkable therefore never in reading list. */ if (notBookmarkableTab) diff --git a/src/kprofile.cpp b/src/kprofile.cpp index d1297c20e..0ce5d4b05 100644 --- a/src/kprofile.cpp +++ b/src/kprofile.cpp @@ -73,7 +73,7 @@ void KProfile::downloadFinished() void ExternalReqInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) { const QString reqUrl = info.requestUrl().toString(); - if (!reqUrl.startsWith("zim://")) + if (!reqUrl.startsWith("zim://") && !reqUrl.startsWith("kiwix-desktop://") && !reqUrl.startsWith("qrc:/")) { qDebug() << "Blocked external request to URL: " << reqUrl; info.block(true); diff --git a/src/tabbar.cpp b/src/tabbar.cpp index 71b5c538c..00c467162 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -3,6 +3,7 @@ class QMenu; #include "tabbar.h" #include "kiwixapp.h" +#include "webpage.h" #include #include #include @@ -10,6 +11,7 @@ class QMenu; #include #include #include +#include #define QUITIFNULL(VIEW) if (nullptr==(VIEW)) { return; } #define CURRENTIFNULL(VIEW) if(nullptr==VIEW) { VIEW = currentZimView();} @@ -60,6 +62,8 @@ TabBar::TabBar(QWidget *parent) : // the slot relies the connection will be direct to reverting back the tab connect(this, SIGNAL(tabMoved(int,int)), this, SLOT(onTabMoved(int,int)), Qt::DirectConnection); + + getAction(KiwixApp::ToggleTOCAction)->setCheckable(true); } void TabBar::openHomePage() { @@ -351,6 +355,19 @@ void TabBar::onCurrentChanged(int index) emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back)); emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward)); emit tabDisplayed(TabType::ZimViewTab); + auto page = qobject_cast(view->page()); + if(page) + { + if (KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->isChecked() && KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->isEnabled() + && !KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->isChecked()) + { + zv->getWebView()->page()->runJavaScript("document.getElementById(\"kiwix-toc-open-button\").click();"); + } + else + { + zv->getWebView()->page()->runJavaScript("document.getElementById(\"kiwix-toc-close-button\").click();"); + } + } QTimer::singleShot(0, [=](){emit currentTitleChanged(view->title());}); } else if (qobject_cast(w)) { emit webActionEnabledChanged(QWebEnginePage::Back, false); diff --git a/src/topwidget.cpp b/src/topwidget.cpp index c29d59279..9843b0bf9 100644 --- a/src/topwidget.cpp +++ b/src/topwidget.cpp @@ -30,6 +30,9 @@ TopWidget::TopWidget(QWidget *parent) : QAction *random = app->getAction(KiwixApp::RandomArticleAction); addAction(random); + QAction *toc = app->getAction(KiwixApp::ToggleTOCAction); + addAction(toc); + // For CSS if (QGuiApplication::isLeftToRight()) { widgetForAction(back)->setObjectName("leftHistoryButton"); diff --git a/src/urlschemehandler.cpp b/src/urlschemehandler.cpp index a5434e3a4..0b3a1e7d1 100644 --- a/src/urlschemehandler.cpp +++ b/src/urlschemehandler.cpp @@ -266,13 +266,21 @@ UrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request) { auto qurl = request->requestUrl(); auto host = qurl.host(); + if (qurl.url() == "zim://kiwix-desktop") + { + auto old = KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->blockSignals(true); + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->setChecked(false); + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->blockSignals(old); + return; + } if (host.endsWith(".zim")) { handleContentRequest(request); } else if (host.endsWith(".meta")) { handleMetaRequest(request); } else if (host.endsWith(".search")) { handleSearchRequest(request); - } else { + } + else { request->fail(QWebEngineUrlRequestJob::UrlNotFound); } } diff --git a/src/webpage.cpp b/src/webpage.cpp index abba46037..0e50cb1d1 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -7,15 +7,16 @@ #include #include #include +#include namespace { -QWebEngineScript getScript(const QString& filename) +QWebEngineScript getScript(const QString& filename, QWebEngineScript::InjectionPoint point = QWebEngineScript::DocumentReady) { QWebEngineScript tocScript; - tocScript.setInjectionPoint(QWebEngineScript::DocumentReady); - + tocScript.setInjectionPoint(point); + tocScript.setWorldId(QWebEngineScript::UserWorld); QFile scriptFile(filename); scriptFile.open(QIODevice::ReadOnly); tocScript.setSourceCode(scriptFile.readAll()); @@ -34,9 +35,55 @@ WebPage::WebPage(QObject *parent) : auto tocScript = getScript(":/js/toc.js"); auto source = tocScript.sourceCode().prepend("const KIWIX_GT_CONTENT = \"" + gt("table-of-content") + "\";"); tocScript.setSourceCode(source); - qInfo() << source; scripts().insert(tocScript); scripts().insert(getScript(":/js/tocStyle.js")); + + scripts().insert(getScript(":/qtwebchannel/qwebchannel.js", QWebEngineScript::DocumentCreation)); + QWebChannel * channel = new QWebChannel(this); + setWebChannel(channel, QWebEngineScript::UserWorld); + auto v = new SomeAction; + channel->registerObject(QString("obj"), v); + connect(v, &QAction::triggered, this, [=](){ + }); + + connect(this, &QWebEnginePage::loadFinished, this, [=](){ + if (KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->isEnabled() + && !KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->isChecked()) + + runJavaScript("var shouldOpen = " + QString((KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->isChecked() ? "true;" : "false;")) + + "if (shouldOpen) {document.getElementById(\"kiwix-toc-open-button\").click();}"); + }); + + connect(KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction), &QAction::toggled, this, [=](bool toggle){ + if (this != KiwixApp::instance()->getTabWidget()->currentWebView()->page()) + return; + if (toggle) + { + runJavaScript("document.getElementById(\"kiwix-toc-close-button\").click();"); + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->setChecked(false); + } + }); + + connect(KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction), &QAction::triggered, this, [=](){ + if (this != KiwixApp::instance()->getTabWidget()->currentWebView()->page()) + return; + runJavaScript("document.getElementById(\"kiwix-toc-button\").click(); document.getElementById(\"kiwix-toc-side\").display === \"none\"", QWebEngineScript::UserWorld, [=](QVariant hidden){ + auto old = KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->blockSignals(true); + auto old1 = KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->blockSignals(old); + if (!hidden.toBool()) + { + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->setChecked(true); + KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->setChecked(false); + } + else + { + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->setChecked(false); + KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->setChecked(true); + } + KiwixApp::instance()->getAction(KiwixApp::ToggleTOCAction)->blockSignals(old); + KiwixApp::instance()->getAction(KiwixApp::ToggleReadingListAction)->blockSignals(old1); + }); + }); } bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType /*type*/, bool /*isMainFrame*/) diff --git a/src/webpage.h b/src/webpage.h index d594b0f21..cd7686c73 100644 --- a/src/webpage.h +++ b/src/webpage.h @@ -2,6 +2,7 @@ #define WEBPAGE_H #include +#include class WebPage : public QWebEnginePage { @@ -13,4 +14,10 @@ class WebPage : public QWebEnginePage bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame); }; +class SomeAction : public QAction { + Q_OBJECT +public slots: + void foo() { trigger(); }; +}; + #endif // WEBPAGE_H diff --git a/src/zimview.cpp b/src/zimview.cpp index 3e7af7786..066f69764 100644 --- a/src/zimview.cpp +++ b/src/zimview.cpp @@ -3,6 +3,7 @@ #include #include #include +#include ZimView::ZimView(TabBar *tabBar, QWidget *parent) : QWidget(parent), @@ -85,6 +86,14 @@ ZimView::ZimView(TabBar *tabBar, QWidget *parent) auto link = url; if (url.startsWith("zim://")) { link = QUrl(url).path(); + if (url.contains("#kiwix-toc")) + { + auto str = url.split("#").last(); + return mp_webView->page()->runJavaScript("document.getElementById(\"" + str + "\").textContent.trim();", QWebEngineScript::UserWorld, [=](QVariant tooltip){ + auto pos = mp_tabBar->mapToGlobal(QPoint(-3, mp_tabBar->currentWebView()->height() - mp_tabBar->PdmHeightMM + 2)); + QToolTip::showText(pos, link + "#" + tooltip.toString()); + }); + } } /* because we use QWebEnginePage::linkHovered signal,