PlantUML: unify online PlantUML process

This commit is contained in:
Le Tan 2018-09-13 19:59:47 +08:00
parent a7bdcf4d54
commit 74032f4a08
7 changed files with 97 additions and 94 deletions

46
src/resources/common.js Normal file
View File

@ -0,0 +1,46 @@
var httpGet = function(url, type, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url);
xmlHttp.responseType = type;
xmlHttp.onload = function() {
callback(xmlHttp.response);
};
xmlHttp.send(null);
};
var getPlantUMLOnlineURL = function(server, format, text) {
var s = unescape(encodeURIComponent(text));
var arr = [];
for (var i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i));
}
var compressor = new Zopfli.RawDeflate(arr);
var compressed = compressor.compress();
var url = server + "/" + format + "/" + encode64_(compressed);
return url;
};
var renderPlantUMLOnline = function(server, format, text, callback, data) {
var url = getPlantUMLOnlineURL(server, format, text);
if (format == 'png') {
httpGet(url, 'blob', function(resp) {
var blob = resp;
var reader = new FileReader();
reader.onload = function () {
var dataUrl = reader.result;
var png = dataUrl.substring(dataUrl.indexOf(',') + 1);
callback(data, format, png);
};
reader.readAsDataURL(blob);
});
} else if (format == 'svg') {
httpGet(url, 'text', function(resp) {
callback(data, format, resp);
});
}
};

View File

@ -29,6 +29,7 @@
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script> <script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
<!-- EXTRA_PLACE_HOLDER --> <!-- EXTRA_PLACE_HOLDER -->
<script src="JS_PLACE_HOLDER" defer></script> <script src="JS_PLACE_HOLDER" defer></script>
<script src="qrc:/resources/common.js" defer></script>
<script src="qrc:/resources/view_image.js" defer></script> <script src="qrc:/resources/view_image.js" defer></script>
<script src="qrc:/resources/markdown_template.js" defer></script> <script src="qrc:/resources/markdown_template.js" defer></script>
</head> </head>

View File

@ -22,6 +22,8 @@ var VPlantUMLDivClass = 'plantuml-diagram';
var VMetaDataCodeClass = 'markdown-metadata'; var VMetaDataCodeClass = 'markdown-metadata';
var VMarkRectDivClass = 'mark-rect'; var VMarkRectDivClass = 'mark-rect';
var VPreviewMode = false;
if (typeof VEnableMermaid == 'undefined') { if (typeof VEnableMermaid == 'undefined') {
VEnableMermaid = false; VEnableMermaid = false;
} else if (VEnableMermaid) { } else if (VEnableMermaid) {
@ -700,10 +702,7 @@ var renderPlantUML = function(className) {
var code = codes[i]; var code = codes[i];
if (code.classList.contains(className)) { if (code.classList.contains(className)) {
if (VPlantUMLMode == 1) { if (VPlantUMLMode == 1) {
if (renderPlantUMLOneOnline(code)) { renderPlantUMLOneOnline(code);
// replaceChild() will decrease codes.length.
--i;
}
} else { } else {
renderPlantUMLOneLocal(code); renderPlantUMLOneLocal(code);
} }
@ -711,37 +710,22 @@ var renderPlantUML = function(className) {
} }
}; };
// Render @code as PlantUML graph. // Render @code as PlantUML graph asynchronously.
// Returns true if succeeded.
var renderPlantUMLOneOnline = function(code) { var renderPlantUMLOneOnline = function(code) {
var s = unescape(encodeURIComponent(code.textContent)); ++asyncJobsCount;
var arr = []; code.classList.add(plantUMLCodeClass + plantUMLIdx);
for (var i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i));
}
var compressor = new Zopfli.RawDeflate(arr); data = { index: plantUMLIdx,
var compressed = compressor.compress(); setupView: !VPreviewMode
var url = VPlantUMLServer + "/" + VPlantUMLFormat + "/" + encode64_(compressed); };
renderPlantUMLOnline(VPlantUMLServer,
var obj = null; VPlantUMLFormat,
if (VPlantUMLFormat == 'svg') { code.textContent,
var svgObj = document.createElement('object'); function(data, format, result) {
svgObj.type = 'image/svg+xml'; handlePlantUMLResultExt(data.index, 0, format, result, data.setupView);
svgObj.data = url; },
data);
obj = document.createElement('div'); plantUMLIdx++;
obj.classList.add(VPlantUMLDivClass);
obj.appendChild(svgObj);
} else {
obj = document.createElement('img');
obj.src = url;
setupIMGToView(obj);
}
var preNode = code.parentNode;
preNode.parentNode.replaceChild(obj, preNode);
return true;
}; };
var renderPlantUMLOneLocal = function(code) { var renderPlantUMLOneLocal = function(code) {
@ -1364,6 +1348,10 @@ var specialCodeBlock = function(lang) {
}; };
var handlePlantUMLResult = function(id, timeStamp, format, result) { var handlePlantUMLResult = function(id, timeStamp, format, result) {
handlePlantUMLResultExt(id, timeStamp, format, result, true);
};
var handlePlantUMLResultExt = function(id, timeStamp, format, result, isSetupView) {
var code = document.getElementsByClassName(plantUMLCodeClass + id)[0]; var code = document.getElementsByClassName(plantUMLCodeClass + id)[0];
if (code && result.length > 0) { if (code && result.length > 0) {
var obj = null; var obj = null;
@ -1371,12 +1359,16 @@ var handlePlantUMLResult = function(id, timeStamp, format, result) {
obj = document.createElement('div'); obj = document.createElement('div');
obj.classList.add(VPlantUMLDivClass); obj.classList.add(VPlantUMLDivClass);
obj.innerHTML = result; obj.innerHTML = result;
if (isSetupView) {
setupSVGToView(obj.children[0], true); setupSVGToView(obj.children[0], true);
}
} else { } else {
obj = document.createElement('img'); obj = document.createElement('img');
obj.src = "data:image/" + format + ";base64, " + result; obj.src = "data:image/" + format + ";base64, " + result;
if (isSetupView) {
setupIMGToView(obj); setupIMGToView(obj);
} }
}
var preNode = code.parentNode; var preNode = code.parentNode;
preNode.parentNode.replaceChild(obj, preNode); preNode.parentNode.replaceChild(obj, preNode);
@ -1422,6 +1414,8 @@ var setPreviewEnabled = function(enabled) {
previewDiv.innerHTML = ''; previewDiv.innerHTML = '';
} }
VPreviewMode = enabled;
clearMarkRectDivs(); clearMarkRectDivs();
}; };
@ -1642,18 +1636,8 @@ var performSmartLivePreview = function(lang, text, hints, isRegex) {
} }
var previewNode = previewDiv; var previewNode = previewDiv;
var trectOffset = null;
try { // Accessing contentDocument will fail due to crossing orgin.
var objs = previewNode.getElementsByTagName('object');
if (objs.length > 0) {
var obj = objs[0];
previewNode = obj.contentDocument.children[0];
trectOffset = obj.getBoundingClientRect();
}
} catch (err) {
content.setLog("err: " + err);
return;
}
// PlantUML. // PlantUML.
var targetNode = null; var targetNode = null;
@ -1724,13 +1708,7 @@ var performSmartLivePreview = function(lang, text, hints, isRegex) {
// (left, top) is relative to the viewport. // (left, top) is relative to the viewport.
// Should add window.scrollX and window.scrollY to get the real content offset. // Should add window.scrollX and window.scrollY to get the real content offset.
var tbrect = targetNode.getBoundingClientRect(); var trect = targetNode.getBoundingClientRect();
var trect = {
left: tbrect.left + (trectOffset ? trectOffset.left : 0),
top: tbrect.top + (trectOffset ? trectOffset.top : 0),
width: tbrect.width,
height: tbrect.height
};
var vrect = { var vrect = {
left: document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset, left: document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset,

View File

@ -223,44 +223,20 @@ var renderFlowchartOne = function(identifier, id, timeStamp, text) {
}; };
var renderPlantUMLOne = function(identifier, id, timeStamp, text) { var renderPlantUMLOne = function(identifier, id, timeStamp, text) {
var format = 'svg'; var data = { identifier: identifier,
var s = unescape(encodeURIComponent(text)); id: id,
var arr = []; timeStamp: timeStamp
for (var i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i));
}
var compressor = new Zopfli.RawDeflate(arr);
var compressed = compressor.compress();
var url = VPlantUMLServer + "/" + format + "/" + encode64_(compressed);
if (format == 'png') {
httpGet(url, 'blob', function(resp) {
var blob = resp;
var reader = new FileReader();
reader.onload = function () {
var dataUrl = reader.result;
var png = dataUrl.substring(dataUrl.indexOf(',') + 1);
content.diagramResultReady(identifier, id, timeStamp, 'png', png);
}; };
reader.readAsDataURL(blob); renderPlantUMLOnline(VPlantUMLServer,
}); 'svg',
} else if (format == 'svg') { text,
httpGet(url, 'text', function(resp) { function(data, format, result) {
content.diagramResultReady(identifier, id, timeStamp, 'svg', resp); content.diagramResultReady(data.identifier,
}); data.id,
} data.timeStamp,
format,
result);
},
data);
}; };
var httpGet = function(url, type, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url);
xmlHttp.responseType = type;
xmlHttp.onload = function() {
callback(xmlHttp.response);
};
xmlHttp.send(null);
}

View File

@ -11,6 +11,7 @@
<!-- 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>
<script src="qrc:/resources/common.js" defer></script>
<script src="qrc:/resources/mathjax_preview.js" defer></script> <script src="qrc:/resources/mathjax_preview.js" defer></script>
</head> </head>
<body> <body>

View File

@ -70,7 +70,7 @@ VMdTab::VMdTab(VFile *p_file, VEditArea *p_editArea,
m_livePreviewTimer->setInterval(500); m_livePreviewTimer->setInterval(500);
connect(m_livePreviewTimer, &QTimer::timeout, connect(m_livePreviewTimer, &QTimer::timeout,
this, [this]() { this, [this]() {
QString text = m_webViewer->selectedText(); QString text = m_webViewer->selectedText().trimmed();
if (text.isEmpty()) { if (text.isEmpty()) {
return; return;
} }

View File

@ -271,5 +271,6 @@
<file>utils/turndown/turndown-plugin-gfm.js</file> <file>utils/turndown/turndown-plugin-gfm.js</file>
<file>resources/common.css</file> <file>resources/common.css</file>
<file>resources/icons/quick_access.svg</file> <file>resources/icons/quick_access.svg</file>
<file>resources/common.js</file>
</qresource> </qresource>
</RCC> </RCC>