loleaflet/dist/framed.html            |  117 ++++++++++++++++++++++++++++++++++
 loleaflet/src/layer/tile/TileLayer.js |    9 ++
 loleaflet/src/map/handler/Map.WOPI.js |    7 ++
 3 files changed, 133 insertions(+)

New commits:
commit 9975e51d60bb9924407d1f32423a29e9adde316e
Author: Tor Lillqvist <t...@collabora.com>
Date:   Thu Jan 18 18:54:20 2018 +0200

    Add handling of the SetCellColor proof-of-concept postMessage event
    
    When we receive such a message, we forward it to the corresponding
    Python script (from core's scripting/examples/python/SetCellColor.py).
    We also save the event's source so that we can send the return value
    of the script back to its window.
    
    Change-Id: I1f54a90000937d6c9b91fb15cdfde329223cf8db
    (cherry picked from commit 0b77d1b1761f4bb64862ed38b2b8d6f152e9beaa)
    (cherry picked from commit 05917b9a46f4784a3d88b52c00b0ff821e7bbaf9)
    (cherry picked from commit d43c3ec8595436ed2fc215219043f676d3ef59f6)
    (cherry picked from commit fdaa96cff0d7230429b8e86fbd63fac14608f3af)
    (cherry picked from commit a0158a143230a3ed573c56275f51d857f61d8da3)
    Reviewed-on: https://gerrit.libreoffice.org/52104
    Reviewed-by: Jan Holesovsky <ke...@collabora.com>
    Tested-by: Jan Holesovsky <ke...@collabora.com>

diff --git a/loleaflet/dist/framed.html b/loleaflet/dist/framed.html
new file mode 100644
index 000000000..f45054d4f
--- /dev/null
+++ b/loleaflet/dist/framed.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+
+<!-- Proof of concept of running loleaflet.html in an iframe.
+
+     The top part of this page has a form with three input fields:
+     "x", "y", and "color", a submit button, and a "result" field used
+     for output only.
+
+     When the submit button is pressed, the input fields are passed as
+     a postMessage to the iframe. The message also specifies what
+     Python script to call. (In this demo case, the 'SetCellColor'
+     script in scripting/examples/python/SetCellColor.py in
+     LibreOffice core.) The parameters are then in our JavaScript
+     passed on to the Python script that acts on the document open in
+     the iframe. The Python script returns a value, which gets passed
+     to loleaflet in a unocommandresult: message, and passed on to the
+     event listener on this page, which writes it to the output field.
+
+     For this to work, in the trivial proof of concept case of 'make
+     run', the below patch is needed to the C++ code. It is probably
+     not necessary in a "real" WOPI-based setup where iframes are
+     already used and things work fine.
+
+--- a/wsd/FileServer.cpp
++++ b/wsd/FileServer.cpp
+@@ -172,7 +172,7 @@ void FileServerRequestHandler::handleRequest(const 
HTTPRequest& request, Poco::M
+         const auto& config = Application::instance().config();
+         const std::string loleafletHtml = config.getString("loleaflet_html", 
"loleaflet.html");
+         const std::string endPoint = requestSegments[requestSegments.size() - 
1];
+-        if (endPoint == loleafletHtml)
++        if (endPoint == loleafletHtml || endPoint == "framed.html")
+         {
+             preprocessFile(request, message, socket);
+             return;
+@@ -548,7 +548,7 @@ void FileServerRequestHandler::preprocessFile(const 
HTTPRequest& request, Poco::
+         LOG_TRC("Denied frame ancestor: " << frameAncestor);
+ 
+         cspOss << "img-src 'self' data: ;";
+-        oss << "X-Frame-Options: deny\r\n";
++        oss << "X-Frame-Options: sameorigin\r\n";
+     }
+ 
+     cspOss << "\r\n";
+
+-->
+
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Online Editor</title>
+
+    <script>
+      function callPythonScript() {
+        window.frames[0].postMessage(JSON.stringify({'MessageId': 
'Host_PostmessageReady'}), '*');
+        var x = document.forms[0].elements['x'].value;
+        var y = document.forms[0].elements['y'].value;
+        var color = document.forms[0].elements['color'].value;
+        console.log('x=' + x + ' y=' + y + ' color=' + color);
+        color = parseInt('0x' + color.substring(1));
+        console.log('x=' + x + ' y=' + y + ' color=' + color);
+        window.frames[0].postMessage(JSON.stringify({'MessageId': 
'CallPythonScript',
+                                                     'SendTime': Date.now(),
+                                                     'ScriptFile': 
'SetCellColor.py',
+                                                     'Function': 
'SetCellColor',
+                                                     'Values': {'x': {'type': 
'long', 'value': x},
+                                                                'y': {'type': 
'long', 'value': y},
+                                                                'color': 
{'type': 'long', 'value': color}
+                                                                }
+                                                     }),
+                                     '*');
+      }
+
+      function receiveMessage(event) {
+        var msg = JSON.parse(event.data);
+        console.log('==== framed.html receiveMessage: ' + event.data);
+        console.log('                                 ' + msg);
+        if (msg.hasOwnProperty('MessageId') &&
+            msg.MessageId === 'CallPythonScript-Result' &&
+            msg.hasOwnProperty('Values') &&
+            msg.Values.hasOwnProperty('commandName') &&
+           msg.Values.commandName === 
'vnd.sun.star.script:SetCellColor.py$SetCellColor?language=Python&location=share'
 &&
+           msg.Values.hasOwnProperty('success') &&
+           msg.Values.success == 'true' &&
+           msg.Values.hasOwnProperty('result') &&
+           msg.Values.result.hasOwnProperty('value')) {
+          document.forms[0].elements['result'].readOnly = false;
+          document.forms[0].elements['result'].value = msg.Values.result.value;
+          document.forms[0].elements['result'].readOnly = true;
+        }
+      }
+      window.addEventListener("message", receiveMessage, false);
+    </script>
+
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  </head>
+
+  <body style="user-select: none;">
+
+    <p>
+      <form id="frm1">
+       Cell: (<input type="number" name="x" min="0" max="20" value="0">, 
<input type="number" name="y" min="0" max="20" value="0">),
+       colour: <input type="text" name="color" value="#008000">
+       <br>
+       Click <button onclick="callPythonScript(); return false;">here</button>
+       to send message to iframe below. It returned <input type="text" 
name="result" value="" readonly>.
+      </form>
+    </p>
+
+    <!-- The hostname and pathnames below are obviously specific to my
+    personal environment and need to be changed appropriately. Also
+    the hex string needs to be changed of course, to the right one as
+    shown by 'make run'. -->
+
+    <iframe 
src="http://snorken.local:9980/loleaflet/94781ec6/loleaflet.html?file_path=file:///home/tml/lo/internal-online/test/data/empty.ods&NotWOPIButIframe=true";
 height="1000" width="1000"></iframe>
+  </body>
+</html>
diff --git a/loleaflet/src/layer/tile/TileLayer.js 
b/loleaflet/src/layer/tile/TileLayer.js
index 4fdee2095..330c86c90 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -1081,6 +1081,7 @@ L.TileLayer = L.GridLayer.extend({
        },
 
        _onUnoCommandResultMsg: function (textMsg) {
+               // console.log('_onUnoCommandResultMsg: "' + textMsg + '"');
                textMsg = textMsg.substring(18);
                var obj = JSON.parse(textMsg);
                var commandName = obj.commandName;
@@ -1094,6 +1095,14 @@ L.TileLayer = L.GridLayer.extend({
                this._map.hideBusy();
                this._map.fire('commandresult', {commandName: commandName, 
success: success, result: obj.result});
 
+               if (this._map.CallPythonScriptSource != null) {
+                       
this._map.CallPythonScriptSource.postMessage(JSON.stringify({'MessageId': 
'CallPythonScript-Result',
+                                                                               
     'SendTime': Date.now(),
+                                                                               
     'Values': obj
+                                                                               
    }),
+                                                                    '*');
+                       this._map.CallPythonScriptSource = null;
+               }
        },
 
        _onRulerUpdate: function (textMsg) {
diff --git a/loleaflet/src/map/handler/Map.WOPI.js 
b/loleaflet/src/map/handler/Map.WOPI.js
index c7055c440..b95dd1ed9 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -18,6 +18,7 @@ L.Map.WOPI = L.Handler.extend({
        DisableCopy: false,
        DisableInactiveMessages: false,
        UserCanNotWriteRelative: true,
+       CallPythonScriptSource: null,
 
        _appLoadedConditions: {
                docloaded: false,
@@ -244,6 +245,12 @@ L.Map.WOPI = L.Handler.extend({
                                this._map._socket.sendMessage('versionrestore 
prerestore');
                        }
                }
+               else if (msg.MessageId === 'CallPythonScript' &&
+                        msg.hasOwnProperty('ScriptFile') &&
+                        msg.hasOwnProperty('Function')) {
+                       this._map.CallPythonScriptSource = e.source;
+                       this._map.sendUnoCommand('vnd.sun.star.script:' + 
msg.ScriptFile + '$' + msg.Function + '?language=Python&location=share', 
msg.Values);
+               }
        },
 
        _postMessage: function(e) {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to