in-plcae preview not working due to Promise JS error

This commit is contained in:
Le Tan 2019-07-28 13:12:02 +08:00
parent e40b8c677e
commit a5e81a08ea
9 changed files with 232 additions and 34 deletions

View File

@ -13,7 +13,16 @@ if (typeof VPlantUMLServer == 'undefined') {
VPlantUMLServer = 'http://www.plantuml.com/plantuml'; VPlantUMLServer = 'http://www.plantuml.com/plantuml';
} }
new QWebChannel(qt.webChannelTransport, if (typeof VWebChannelPort == 'undefined') {
var VWebChannelPort = '20001';
}
window.addEventListener('load', function() {
var baseUrl = 'ws://localhost:' + VWebChannelPort;
var socket = new WebSocket(baseUrl);
socket.onopen = function() {
console.log('WebSocket connected to ' + baseUrl);
new QWebChannel(socket,
function(channel) { function(channel) {
content = channel.objects.content; content = channel.objects.content;
@ -22,8 +31,10 @@ new QWebChannel(qt.webChannelTransport,
channelInitialized = true; channelInitialized = true;
}); });
}
});
var timeStamps = new Map(); var timeStamps = new Object();
var htmlToElement = function(html) { var htmlToElement = function(html) {
var template = document.createElement('template'); var template = document.createElement('template');
@ -37,7 +48,7 @@ var isEmptyMathJax = function(text) {
}; };
var previewMathJax = function(identifier, id, timeStamp, text, isHtml) { var previewMathJax = function(identifier, id, timeStamp, text, isHtml) {
timeStamps.set(identifier, timeStamp); timeStamps[identifier] = timeStamp;
if (isEmptyMathJax(text)) { if (isEmptyMathJax(text)) {
content.mathjaxResultReady(identifier, id, timeStamp, 'png', ''); content.mathjaxResultReady(identifier, id, timeStamp, 'png', '');
@ -87,7 +98,7 @@ var previewMathJax = function(identifier, id, timeStamp, text, isHtml) {
}; };
var postProcessMathJax = function(identifier, id, timeStamp, container, isBlock) { var postProcessMathJax = function(identifier, id, timeStamp, container, isBlock) {
if (timeStamps.get(identifier) != timeStamp) { if (timeStamps[identifier] != timeStamp) {
contentDiv.removeChild(container); contentDiv.removeChild(container);
delete container; delete container;
return; return;

View File

@ -8,7 +8,7 @@
</style> </style>
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER"> <link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
<script src="qrc:/resources/qwebchannel.js"></script> <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<!-- EXTRA_PLACE_HOLDER --> <!-- EXTRA_PLACE_HOLDER -->
<script src="JS_PLACE_HOLDER" async></script> <script src="JS_PLACE_HOLDER" async></script>
<script src="qrc:/utils/dom-to-image/dom-to-image.js" defer></script> <script src="qrc:/utils/dom-to-image/dom-to-image.js" defer></script>

View File

@ -160,7 +160,8 @@ SOURCES += main.cpp\
vpreviewpage.cpp \ vpreviewpage.cpp \
vwebview.cpp \ vwebview.cpp \
websocketclientwrapper.cpp \ websocketclientwrapper.cpp \
websockettransport.cpp websockettransport.cpp \
vmathjaxwebdocument.cpp
HEADERS += vmainwindow.h \ HEADERS += vmainwindow.h \
vdirectorytree.h \ vdirectorytree.h \
@ -305,7 +306,8 @@ HEADERS += vmainwindow.h \
vpreviewpage.h \ vpreviewpage.h \
vwebview.h \ vwebview.h \
websocketclientwrapper.h \ websocketclientwrapper.h \
websockettransport.h websockettransport.h \
vmathjaxwebdocument.h
RESOURCES += \ RESOURCES += \
vnote.qrc \ vnote.qrc \

View File

@ -978,7 +978,7 @@ with 2em, if there are Chinese characters in it, the font will be a mess.
return templ; return templ;
} }
QString VUtils::generateMathJaxPreviewTemplate() QString VUtils::generateMathJaxPreviewTemplate(quint16 p_port)
{ {
QString mj = g_config->getMathjaxJavascript(); QString mj = g_config->getMathjaxJavascript();
QString templ = VNote::generateMathJaxPreviewTemplate(); QString templ = VNote::generateMathJaxPreviewTemplate();
@ -1027,6 +1027,8 @@ QString VUtils::generateMathJaxPreviewTemplate()
"<script type=\"text/javascript\" src=\"" + VNote::c_plantUMLZopfliJsFile + "\"></script>\n" + "<script type=\"text/javascript\" src=\"" + VNote::c_plantUMLZopfliJsFile + "\"></script>\n" +
"<script>var VPlantUMLServer = '" + g_config->getPlantUMLServer() + "';</script>\n"; "<script>var VPlantUMLServer = '" + g_config->getPlantUMLServer() + "';</script>\n";
extraFile += "<script>var VWebChannelPort = '" + QString::number(p_port) + "';</script>\n";
templ.replace(HtmlHolder::c_extraHolder, extraFile); templ.replace(HtmlHolder::c_extraHolder, extraFile);
return templ; return templ;

View File

@ -206,7 +206,7 @@ public:
static QString generateSimpleHtmlTemplate(const QString &p_body); static QString generateSimpleHtmlTemplate(const QString &p_body);
// Generate template for MathJax preview. // Generate template for MathJax preview.
static QString generateMathJaxPreviewTemplate(); static QString generateMathJaxPreviewTemplate(quint16 p_port);
// Get an available file name in @p_directory with base @p_baseFileName. // Get an available file name in @p_directory with base @p_baseFileName.
// If there already exists a file named @p_baseFileName, try to add sequence // If there already exists a file named @p_baseFileName, try to add sequence

View File

@ -1,11 +1,14 @@
#include "vmathjaxpreviewhelper.h" #include "vmathjaxpreviewhelper.h"
// #include <QWebEngineView> #include <QWebView>
// #include <QWebChannel> #include <QWebChannel>
#include <QWebSocketServer>
#include "utils/vutils.h" #include "utils/vutils.h"
// #include "vmathjaxwebdocument.h" #include "vmathjaxwebdocument.h"
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "websocketclientwrapper.h"
#include "websockettransport.h"
extern VConfigManager *g_config; extern VConfigManager *g_config;
@ -14,7 +17,8 @@ VMathJaxPreviewHelper::VMathJaxPreviewHelper(QWidget *p_parentWidget, QObject *p
m_parentWidget(p_parentWidget), m_parentWidget(p_parentWidget),
m_initialized(false), m_initialized(false),
m_nextID(0), m_nextID(0),
// m_webView(NULL), m_webView(NULL),
m_channel(nullptr),
m_webReady(false) m_webReady(false)
{ {
} }
@ -30,9 +34,8 @@ void VMathJaxPreviewHelper::doInit()
m_initialized = true; m_initialized = true;
/* m_webView = new QWebView(m_parentWidget);
m_webView = new QWebEngineView(m_parentWidget); connect(m_webView, &QWebView::loadFinished,
connect(m_webView, &QWebEngineView::loadFinished,
this, [this]() { this, [this]() {
m_webReady = true; m_webReady = true;
for (auto const & it : m_pendingFunc) { for (auto const & it : m_pendingFunc) {
@ -41,6 +44,7 @@ void VMathJaxPreviewHelper::doInit()
m_pendingFunc.clear(); m_pendingFunc.clear();
}); });
m_webView->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
m_webView->hide(); m_webView->hide();
m_webView->setFocusPolicy(Qt::NoFocus); m_webView->setFocusPolicy(Qt::NoFocus);
@ -71,16 +75,14 @@ void VMathJaxPreviewHelper::doInit()
emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba); emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba);
}); });
QWebChannel *channel = new QWebChannel(m_webView); quint16 port = 20001;
channel->registerObject(QStringLiteral("content"), m_webDoc); bindToChannel(port, "content", m_webDoc);
m_webView->page()->setWebChannel(channel);
// setHtml() will change focus if it is not disabled. // setHtml() will change focus if it is not disabled.
m_webView->setEnabled(false); m_webView->setEnabled(false);
QUrl baseUrl(QUrl::fromLocalFile(g_config->getDocumentPathOrHomePath() + QDir::separator())); QUrl baseUrl(QUrl::fromLocalFile(g_config->getDocumentPathOrHomePath() + QDir::separator()));
m_webView->setHtml(VUtils::generateMathJaxPreviewTemplate(), baseUrl); m_webView->setHtml(VUtils::generateMathJaxPreviewTemplate(port), baseUrl);
m_webView->setEnabled(true); m_webView->setEnabled(true);
*/
} }
void VMathJaxPreviewHelper::previewMathJax(int p_identifier, void VMathJaxPreviewHelper::previewMathJax(int p_identifier,
@ -90,7 +92,18 @@ void VMathJaxPreviewHelper::previewMathJax(int p_identifier,
{ {
init(); init();
emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, "png", ""); if (!m_webReady) {
auto func = std::bind(&VMathJaxWebDocument::previewMathJax,
m_webDoc,
p_identifier,
p_id,
p_timeStamp,
p_text,
false);
m_pendingFunc.append(func);
} else {
m_webDoc->previewMathJax(p_identifier, p_id, p_timeStamp, p_text, false);
}
} }
void VMathJaxPreviewHelper::previewMathJaxFromHtml(int p_identifier, void VMathJaxPreviewHelper::previewMathJaxFromHtml(int p_identifier,
@ -100,7 +113,18 @@ void VMathJaxPreviewHelper::previewMathJaxFromHtml(int p_identifier,
{ {
init(); init();
emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, "png", ""); if (!m_webReady) {
auto func = std::bind(&VMathJaxWebDocument::previewMathJax,
m_webDoc,
p_identifier,
p_id,
p_timeStamp,
p_html,
true);
m_pendingFunc.append(func);
} else {
m_webDoc->previewMathJax(p_identifier, p_id, p_timeStamp, p_html, true);
}
} }
void VMathJaxPreviewHelper::previewDiagram(int p_identifier, void VMathJaxPreviewHelper::previewDiagram(int p_identifier,
@ -111,5 +135,36 @@ void VMathJaxPreviewHelper::previewDiagram(int p_identifier,
{ {
init(); init();
emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, "png", ""); if (!m_webReady) {
auto func = std::bind(&VMathJaxWebDocument::previewDiagram,
m_webDoc,
p_identifier,
p_id,
p_timeStamp,
p_lang,
p_text);
m_pendingFunc.append(func);
} else {
m_webDoc->previewDiagram(p_identifier, p_id, p_timeStamp, p_lang, p_text);
}
}
void VMathJaxPreviewHelper::bindToChannel(quint16 p_port, const QString &p_name, QObject *p_object)
{
Q_ASSERT(!m_channel);
auto server = new QWebSocketServer("Web View for Preview",
QWebSocketServer::NonSecureMode,
this);
quint16 port = p_port;
if (!server->listen(QHostAddress::LocalHost, port)) {
qWarning() << "fail to open web socket server on port" << port;
delete server;
return;
}
auto clientWrapper = new WebSocketClientWrapper(server, this);
m_channel = new QWebChannel(this);
connect(clientWrapper, &WebSocketClientWrapper::clientConnected,
m_channel, &QWebChannel::connectTo);
m_channel->registerObject(p_name, p_object);
} }

View File

@ -7,8 +7,9 @@
#include "vconstants.h" #include "vconstants.h"
// class QWebEngineView; class QWebView;
// class VMathJaxWebDocument; class QWebChannel;
class VMathJaxWebDocument;
class QWidget; class QWidget;
typedef std::function<void(void)> PendingFunc; typedef std::function<void(void)> PendingFunc;
@ -61,15 +62,19 @@ private:
void doInit(); void doInit();
void bindToChannel(quint16 p_port, const QString &p_name, QObject *p_object);
QWidget *m_parentWidget; QWidget *m_parentWidget;
int m_initialized; int m_initialized;
int m_nextID; int m_nextID;
// QWebEngineView *m_webView; QWebView *m_webView;
// VMathJaxWebDocument *m_webDoc; QWebChannel *m_channel;
VMathJaxWebDocument *m_webDoc;
bool m_webReady; bool m_webReady;

View File

@ -0,0 +1,54 @@
#include "vmathjaxwebdocument.h"
#include <QDebug>
VMathJaxWebDocument::VMathJaxWebDocument(QObject *p_parent)
: QObject(p_parent)
{
}
void VMathJaxWebDocument::previewMathJax(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_text,
bool p_isHtml)
{
emit requestPreviewMathJax(p_identifier, p_id, p_timeStamp, p_text, p_isHtml);
}
void VMathJaxWebDocument::mathjaxResultReady(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data)
{
emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data);
}
void VMathJaxWebDocument::diagramResultReady(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data)
{
emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data);
}
void VMathJaxWebDocument::previewDiagram(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_lang,
const QString &p_text)
{
emit requestPreviewDiagram(p_identifier,
p_id,
p_timeStamp,
p_lang,
p_text);
}
void VMathJaxWebDocument::setLog(const QString &p_log)
{
qDebug() << "JS:" << p_log;
}

69
src/vmathjaxwebdocument.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef VMATHJAXWEBDOCUMENT_H
#define VMATHJAXWEBDOCUMENT_H
#include <QObject>
#include "vconstants.h"
class VMathJaxWebDocument : public QObject
{
Q_OBJECT
public:
explicit VMathJaxWebDocument(QObject *p_parent = nullptr);
void previewMathJax(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_text,
bool p_isHtml);
void previewDiagram(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_lang,
const QString &p_text);
public slots:
// Will be called in the HTML side
void mathjaxResultReady(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data);
void diagramResultReady(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data);
void setLog(const QString &p_log);
signals:
void requestPreviewMathJax(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_text,
bool p_isHtml);
void requestPreviewDiagram(int p_identifier,
int p_id,
unsigned long long p_timeStamp,
const QString &p_lang,
const QString &p_text);
void mathjaxPreviewResultReady(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_format,
const QString &p_data);
void diagramPreviewResultReady(int p_identifier,
int p_id,
TimeStamp p_timeStamp,
const QString &p_format,
const QString &p_data);
};
#endif // VMATHJAXWEBDOCUMENT_H