1
0
Эх сурвалжийг харах

PlantUML: unify online PlantUML process

Le Tan 7 жил өмнө
parent
commit
74032f4a08

+ 46 - 0
src/resources/common.js

@@ -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);
+        });
+    }
+};

+ 1 - 0
src/resources/markdown_template.html

@@ -29,6 +29,7 @@
     <script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
     <!-- EXTRA_PLACE_HOLDER -->
     <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/markdown_template.js" defer></script>
 </head>

+ 32 - 54
src/resources/markdown_template.js

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

+ 16 - 40
src/resources/mathjax_preview.js

@@ -223,44 +223,20 @@ var renderFlowchartOne = function(identifier, id, timeStamp, text) {
 };
 
 var renderPlantUMLOne = function(identifier, id, timeStamp, text) {
-    var format = 'svg';
-    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 = 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);
-        });
-    } else if (format == 'svg') {
-        httpGet(url, 'text', function(resp) {
-            content.diagramResultReady(identifier, id, timeStamp, 'svg', resp);
-        });
-    }
+    var data = { identifier: identifier,
+                 id: id,
+                 timeStamp: timeStamp
+               };
+
+    renderPlantUMLOnline(VPlantUMLServer,
+                         'svg',
+                         text,
+                         function(data, format, result) {
+                             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);
-}

+ 1 - 0
src/resources/mathjax_preview_template.html

@@ -11,6 +11,7 @@
     <!-- EXTRA_PLACE_HOLDER -->
     <script src="JS_PLACE_HOLDER" async></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>
 </head>
 <body>

+ 1 - 1
src/vmdtab.cpp

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

+ 1 - 0
src/vnote.qrc

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