Skip to content

Commit aa36018

Browse files
committed
Implement HTML bookmark import for QtWebEngine
1 parent abf883a commit aa36018

File tree

2 files changed

+162
-1
lines changed

2 files changed

+162
-1
lines changed

src/modules/importers/html/HtmlBookmarksImporter.cpp

+155-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <QtWebKitWidgets/QWebPage>
3030
#include <QtWebKitWidgets/QWebFrame>
3131
#include <QtWebKit/QWebElementCollection>
32+
#elif defined(OTTER_ENABLE_QTWEBENGINE)
33+
#include <QtWebEngineWidgets/QWebEnginePage>
3234
#endif
3335

3436
namespace Otter
@@ -226,6 +228,33 @@ QDateTime HtmlBookmarksImporter::getDateTime(const QWebElement &element, const Q
226228
return ((seconds != 0) ? QDateTime::fromSecsSinceEpoch(seconds) : QDateTime());
227229
#endif
228230
}
231+
#elif defined(OTTER_ENABLE_QTWEBENGINE)
232+
QDateTime HtmlBookmarksImporter::getDateTime(const QVariant &attribute)
233+
{
234+
#if QT_VERSION < 0x050800
235+
const uint seconds(attribute.toUInt());
236+
237+
return ((seconds > 0) ? QDateTime::fromTime_t(seconds) : QDateTime());
238+
#else
239+
const qint64 seconds(attribute.toLongLong());
240+
241+
return ((seconds != 0) ? QDateTime::fromSecsSinceEpoch(seconds) : QDateTime());
242+
#endif
243+
}
244+
245+
QVariant HtmlBookmarksImporter::execJavascript(QWebEnginePage &page, const QString &script)
246+
{
247+
QVariant jsResult;
248+
QEventLoop loop;
249+
250+
page.runJavaScript(script, [&loop, &jsResult](const QVariant &result) {
251+
jsResult = result;
252+
loop.exit(0);
253+
});
254+
loop.exec();
255+
256+
return jsResult;
257+
}
229258
#endif
230259

231260
QStringList HtmlBookmarksImporter::getFileFilters() const
@@ -235,7 +264,7 @@ QStringList HtmlBookmarksImporter::getFileFilters() const
235264

236265
bool HtmlBookmarksImporter::import(const QString &path)
237266
{
238-
#ifdef OTTER_ENABLE_QTWEBKIT
267+
#if defined(OTTER_ENABLE_QTWEBKIT) || defined(OTTER_ENABLE_QTWEBENGINE)
239268
QFile file(getSuggestedPath(path));
240269

241270
if (!file.open(QIODevice::ReadOnly))
@@ -262,7 +291,10 @@ bool HtmlBookmarksImporter::import(const QString &path)
262291
setImportFolder(m_optionsWidget->getTargetFolder());
263292
}
264293
}
294+
#endif
295+
265296

297+
#ifdef OTTER_ENABLE_QTWEBKIT
266298
QWebPage page;
267299
page.settings()->setAttribute(QWebSettings::JavascriptEnabled, false);
268300
page.mainFrame()->setHtml(QString::fromLatin1(file.readAll()));
@@ -282,11 +314,133 @@ bool HtmlBookmarksImporter::import(const QString &path)
282314
file.close();
283315

284316
return true;
317+
#elif defined(OTTER_ENABLE_QTWEBENGINE)
318+
319+
QEventLoop loop;
320+
QWebEnginePage page;
321+
322+
connect(&page, &QWebEnginePage::loadFinished,
323+
[this, &page, &loop](bool ok) {
324+
325+
if (!ok)
326+
{
327+
m_totalAmount = 0;
328+
loop.exit();
329+
return;
330+
}
331+
332+
QVariant jsResult;
333+
334+
jsResult = execJavascript(page, "document.getElementsByTagName('DT').length");
335+
m_totalAmount = jsResult.toInt(&ok);
336+
if (!ok)
337+
{
338+
m_totalAmount = 0;
339+
loop.exit();
340+
return;
341+
}
342+
343+
emit importStarted(BookmarksImport, m_totalAmount);
344+
345+
jsResult = execJavascript(page, "document.getElementsByTagName('a').length");
346+
const int numLinks = jsResult.toInt(&ok);
347+
348+
BookmarksManager::getModel()->beginImport(getImportFolder(),
349+
numLinks,
350+
numLinks);
351+
352+
jsResult = execJavascript(page, "var nodes=[];document.querySelectorAll('h3,a,hr').forEach(function(node){if(node.tagName.toUpperCase()=='A'){nodes.push({'type':'anchor','title':node.innerHTML,'url':node.getAttribute('href'),'add_date':node.getAttribute('add_date'),'last_modified':node.getAttribute('last_modified')})}else if(node.tagName.toUpperCase()=='HR'){nodes.push({'type':'separator'})}else if(node.tagName.toUpperCase()=='H3'){sibling=node.parentNode.querySelector('dl');numChildren=sibling.querySelectorAll(':scope > dt').length;nodes.push({'type':'folder','title':node.innerHTML,'numChildren':numChildren,'add_date':node.getAttribute('add_date'),'last_modified':node.getAttribute('last_modified')})}});nodes");
353+
QList<QVariant> items = jsResult.toList();
354+
355+
processBookmarkItems(items, getImportFolder(), -1);
356+
BookmarksManager::getModel()->endImport();
357+
358+
loop.exit();
359+
});
360+
361+
page.setHtml(QString::fromLatin1(file.readAll()));
362+
loop.exec();
363+
364+
emit importFinished(BookmarksImport, SuccessfullImport, m_totalAmount);
365+
366+
file.close();
367+
368+
return true;
369+
285370
#else
286371
Q_UNUSED(path)
287372

373+
emit importFinished(BookmarksImport, FailedImport, 0);
374+
288375
return false;
289376
#endif
290377
}
291378

379+
#ifdef OTTER_ENABLE_QTWEBENGINE
380+
void HtmlBookmarksImporter::processBookmarkItems(QList<QVariant> &items, BookmarksModel::Bookmark *importFolder, int numChildren)
381+
{
382+
while (numChildren != 0 && m_currentAmount < m_totalAmount)
383+
{
384+
const QVariant &item = items.at(m_currentAmount++);
385+
-- numChildren;
386+
387+
const QMap<QString, QVariant> itemMap = item.toMap();
388+
const QString typeString = itemMap["type"].toString();
389+
const QString title = itemMap["title"].toString();
390+
391+
BookmarksModel::BookmarkType type(BookmarksModel::UnknownBookmark);
392+
QMap<int, QVariant> metaData({{BookmarksModel::TitleRole, title}});
393+
394+
if (typeString == "folder" || typeString == "anchor")
395+
{
396+
const QDateTime addDate(getDateTime(itemMap["add_date"]));
397+
const QDateTime lastModified(getDateTime(itemMap["last_modified"]));
398+
399+
if (addDate.isValid())
400+
{
401+
metaData[BookmarksModel::TimeAddedRole] = addDate;
402+
}
403+
404+
if (lastModified.isValid())
405+
{
406+
metaData[BookmarksModel::TimeAddedRole] = lastModified;
407+
}
408+
}
409+
410+
if (typeString == "folder")
411+
{
412+
processBookmarkItems(items,
413+
BookmarksManager::addBookmark(BookmarksModel::FolderBookmark, metaData, importFolder),
414+
itemMap["numChildren"].toInt());
415+
}
416+
else
417+
{
418+
if (typeString == "anchor")
419+
{
420+
type = BookmarksModel::UrlBookmark;
421+
const QString url = itemMap["url"].toString();
422+
423+
if (!areDuplicatesAllowed() && BookmarksManager::hasBookmark(url))
424+
{
425+
continue;
426+
}
427+
428+
metaData[BookmarksModel::UrlRole] = url;
429+
}
430+
else if (typeString == "separator")
431+
{
432+
type = BookmarksModel::SeparatorBookmark;
433+
}
434+
435+
if (type != BookmarksModel::UnknownBookmark)
436+
{
437+
BookmarksManager::addBookmark(type, metaData, importFolder);
438+
}
439+
}
440+
441+
emit importProgress(BookmarksImport, m_totalAmount, m_currentAmount);
442+
}
443+
}
444+
#endif
445+
292446
}

src/modules/importers/html/HtmlBookmarksImporter.h

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#ifdef OTTER_ENABLE_QTWEBKIT
2727
#include <QtWebKit/QWebElement>
28+
#elif defined(OTTER_ENABLE_QTWEBENGINE)
29+
#include <QtWebEngineWidgets/QWebEnginePage>
2830
#endif
2931

3032
namespace Otter
@@ -52,10 +54,15 @@ class HtmlBookmarksImporter final : public BookmarksImporter
5254
public slots:
5355
bool import(const QString &path) override;
5456

57+
protected:
5558
#ifdef OTTER_ENABLE_QTWEBKIT
5659
protected:
5760
void processElement(const QWebElement &element);
5861
static QDateTime getDateTime(const QWebElement &element, const QString &attribute);
62+
#elif defined(OTTER_ENABLE_QTWEBENGINE)
63+
void processBookmarkItems(QList<QVariant> &items, BookmarksModel::Bookmark *importFolder, int numChildren);
64+
static QDateTime getDateTime(const QVariant &attribute);
65+
QVariant execJavascript(QWebEnginePage &page, const QString &script);
5966
#endif
6067

6168
private:

0 commit comments

Comments
 (0)