2018-01-18 10:59:35 -06:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
2018-03-28 11:25:02 -05:00
|
|
|
<!-- Proof of concept of running loleaflet.html in an iframe. Also
|
|
|
|
shows how to, from outside the iframe, invoke Python scripting in
|
|
|
|
the underlying LibreOffice instance that manipulates the document
|
|
|
|
being edited.
|
2018-01-18 10:59:35 -06:00
|
|
|
|
2018-03-28 09:05:36 -05:00
|
|
|
The top part of this page has several forms. The first one with
|
|
|
|
three input fields: "x", "y", and "color", a submit button, and a
|
|
|
|
"result" field used for output only.
|
2018-01-18 10:59:35 -06:00
|
|
|
|
|
|
|
When the submit button is pressed, the input fields are passed as
|
2018-01-19 04:16:55 -06:00
|
|
|
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.
|
2018-01-18 10:59:35 -06:00
|
|
|
|
2018-03-28 09:05:36 -05:00
|
|
|
The other forms call other Python functions in other files. (In
|
2018-03-28 11:25:02 -05:00
|
|
|
particular, in NamedRanges.py in the same directory.) The forms
|
|
|
|
invoke Python functions that list, add, and delete named ranges
|
|
|
|
in a Calc document being edited.
|
2018-03-28 09:05:36 -05:00
|
|
|
|
2018-03-28 08:06:05 -05:00
|
|
|
To test this, do 'make run', and then in your browser open the
|
|
|
|
equivalent of
|
|
|
|
http://snorken.local:9980/loleaflet/3304e9093/framed.html if the
|
|
|
|
browser is running on a different machine, or
|
|
|
|
http://localhost:9980/loleaflet/3304e9093/framed.html if running
|
|
|
|
on the same machine.
|
|
|
|
|
2018-01-18 10:59:35 -06:00
|
|
|
-->
|
|
|
|
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
|
<title>Online Editor</title>
|
|
|
|
|
|
|
|
<script>
|
2018-03-28 11:25:02 -05:00
|
|
|
|
|
|
|
// These functions named call* are invoked when submitting the
|
|
|
|
// forms defined in the body of this web page. They show how to
|
|
|
|
// post a message to the iframe where Online is running, that
|
|
|
|
// will cause a Python script in the underlying LibreOffice
|
|
|
|
// instance to be invoked.
|
|
|
|
|
2018-01-19 10:02:13 -06:00
|
|
|
function callSetCellColor() {
|
2018-01-18 10:59:35 -06:00
|
|
|
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);
|
2018-01-19 04:16:55 -06:00
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript',
|
2018-01-18 10:59:35 -06:00
|
|
|
'SendTime': Date.now(),
|
2018-01-19 04:16:55 -06:00
|
|
|
'ScriptFile': 'SetCellColor.py',
|
|
|
|
'Function': 'SetCellColor',
|
|
|
|
'Values': {'x': {'type': 'long', 'value': x},
|
|
|
|
'y': {'type': 'long', 'value': y},
|
|
|
|
'color': {'type': 'long', 'value': color}
|
2018-01-18 10:59:35 -06:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
'*');
|
|
|
|
}
|
|
|
|
|
2018-01-19 10:02:13 -06:00
|
|
|
function callGetNamedRanges() {
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*');
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript',
|
|
|
|
'SendTime': Date.now(),
|
|
|
|
'ScriptFile': 'NamedRanges.py',
|
|
|
|
'Function': 'GetNamedRanges',
|
|
|
|
'Values': null
|
|
|
|
}),
|
|
|
|
'*');
|
|
|
|
}
|
|
|
|
|
2018-01-19 13:17:15 -06:00
|
|
|
function callAddNamedRange() {
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*');
|
2018-01-22 04:09:06 -06:00
|
|
|
// Our form below takes input in A1 format, the Python script wants zero-based indexes and width and height
|
2018-01-22 04:03:14 -06:00
|
|
|
var abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
2018-01-22 06:53:19 -06:00
|
|
|
var name = document.forms['add-named-range-form'].elements['name'].value;
|
2018-01-22 04:03:14 -06:00
|
|
|
var x0 = document.forms['add-named-range-form'].elements['x0'].value;
|
|
|
|
var x1 = document.forms['add-named-range-form'].elements['x1'].value;
|
|
|
|
var y0 = parseInt(document.forms['add-named-range-form'].elements['y0'].value);
|
|
|
|
var y1 = parseInt(document.forms['add-named-range-form'].elements['y1'].value);
|
|
|
|
console.log('x0=' + x0 + ', x1=' + x1)
|
|
|
|
x0 = abc.indexOf(x0);
|
|
|
|
x1 = abc.indexOf(x1);
|
2018-01-19 13:17:15 -06:00
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript',
|
|
|
|
'SendTime': Date.now(),
|
|
|
|
'ScriptFile': 'NamedRanges.py',
|
|
|
|
'Function': 'DefineNamedRange',
|
|
|
|
'Values': {'sheet': {'type': 'string', 'value': 'Sheet1'},
|
2018-01-22 04:03:14 -06:00
|
|
|
'x0': {'type': 'long', 'value': x0},
|
|
|
|
'y0': {'type': 'long', 'value': y0-1},
|
|
|
|
'width': {'type': 'long', 'value': x1-x0+1},
|
|
|
|
'height': {'type': 'long', 'value': y1-y0+1},
|
2018-01-22 06:53:19 -06:00
|
|
|
'name': {'type': 'string', 'value': name}
|
2018-01-19 13:17:15 -06:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
'*');
|
|
|
|
}
|
|
|
|
|
2018-03-28 08:51:59 -05:00
|
|
|
function callDeleteNamedRange() {
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*');
|
|
|
|
var name = document.forms['delete-named-range-form'].elements['name'].value;
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'CallPythonScript',
|
|
|
|
'SendTime': Date.now(),
|
|
|
|
'ScriptFile': 'NamedRanges.py',
|
|
|
|
'Function': 'DeleteNamedRange',
|
|
|
|
'Values': {'name': {'type': 'string', 'value': name}
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
'*');
|
|
|
|
}
|
|
|
|
|
2019-05-13 10:29:02 -05:00
|
|
|
function ShowMenubar(visible) {
|
|
|
|
var messageId = visible ? 'Show_Menubar' : 'Hide_Menubar';
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': 'Host_PostmessageReady'}), '*');
|
|
|
|
window.frames[0].postMessage(JSON.stringify({'MessageId': messageId}), '*');
|
|
|
|
}
|
|
|
|
|
2018-03-28 11:25:02 -05:00
|
|
|
// This function is invoked when the iframe posts a message back.
|
|
|
|
|
2018-01-18 10:59:35 -06:00
|
|
|
function receiveMessage(event) {
|
|
|
|
var msg = JSON.parse(event.data);
|
|
|
|
console.log('==== framed.html receiveMessage: ' + event.data);
|
|
|
|
console.log(' ' + msg);
|
2018-03-28 11:25:02 -05:00
|
|
|
|
|
|
|
// We are only interested in messages that are marked as being
|
|
|
|
// a result from a Python script invoked by one of the call*
|
|
|
|
// functions above.
|
|
|
|
|
2018-01-18 10:59:35 -06:00
|
|
|
if (msg.hasOwnProperty('MessageId') &&
|
2018-01-19 04:16:55 -06:00
|
|
|
msg.MessageId === 'CallPythonScript-Result' &&
|
2018-01-18 10:59:35 -06:00
|
|
|
msg.hasOwnProperty('Values') &&
|
|
|
|
msg.Values.hasOwnProperty('commandName') &&
|
|
|
|
msg.Values.hasOwnProperty('success') &&
|
|
|
|
msg.Values.success == 'true' &&
|
|
|
|
msg.Values.hasOwnProperty('result') &&
|
|
|
|
msg.Values.result.hasOwnProperty('value')) {
|
2018-03-28 11:25:02 -05:00
|
|
|
// We are only interested in the result of the SetCellColor and GetNamedRanges functions
|
2018-01-19 10:02:13 -06:00
|
|
|
if (msg.Values.commandName === 'vnd.sun.star.script:SetCellColor.py$SetCellColor?language=Python&location=share') {
|
|
|
|
document.forms['cell-colour-form'].elements['result'].readOnly = false;
|
|
|
|
document.forms['cell-colour-form'].elements['result'].value = msg.Values.result.value;
|
|
|
|
document.forms['cell-colour-form'].elements['result'].readOnly = true;
|
|
|
|
}
|
|
|
|
else if (msg.Values.commandName === 'vnd.sun.star.script:NamedRanges.py$GetNamedRanges?language=Python&location=share') {
|
|
|
|
document.forms['get-named-ranges-form'].elements['result'].readOnly = false;
|
|
|
|
var index = 0;
|
|
|
|
var result = '';
|
|
|
|
while (msg.Values.result.value.hasOwnProperty(index.toString())) {
|
2018-01-22 03:26:23 -06:00
|
|
|
if (msg.Values.result.value[index.toString()].value.hasOwnProperty('0') &&
|
|
|
|
msg.Values.result.value[index.toString()].value['0'].hasOwnProperty('value') &&
|
|
|
|
msg.Values.result.value[index.toString()].value.hasOwnProperty('1') &&
|
|
|
|
msg.Values.result.value[index.toString()].value['1'].hasOwnProperty('value'))
|
|
|
|
result += msg.Values.result.value[index.toString()].value[0].value + ": " +
|
|
|
|
msg.Values.result.value[index.toString()].value[1].value + "\n";
|
2018-01-19 10:02:13 -06:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
document.forms['get-named-ranges-form'].elements['result'].value = result;
|
|
|
|
document.forms['get-named-ranges-form'].elements['result'].readOnly = true;
|
|
|
|
}
|
2018-01-18 10:59:35 -06:00
|
|
|
}
|
|
|
|
}
|
2018-03-28 11:25:02 -05:00
|
|
|
|
|
|
|
// 'main' code of this <script> block, run when page is being
|
|
|
|
// rendered. Install the message listener.
|
2018-01-18 10:59:35 -06:00
|
|
|
window.addEventListener("message", receiveMessage, false);
|
2018-03-28 11:25:02 -05:00
|
|
|
|
2018-01-18 10:59:35 -06:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body style="user-select: none;">
|
2019-05-13 10:29:02 -05:00
|
|
|
<h3>Calc functions</h3>
|
2018-01-18 10:59:35 -06:00
|
|
|
<p>
|
2018-01-19 10:02:13 -06:00
|
|
|
<form id="cell-colour-form">
|
2018-01-18 10:59:35 -06:00
|
|
|
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>
|
2018-01-19 10:02:13 -06:00
|
|
|
Click <button onclick="callSetCellColor(); return false;">here</button>
|
2018-01-18 10:59:35 -06:00
|
|
|
to send message to iframe below. It returned <input type="text" name="result" value="" readonly>.
|
|
|
|
</form>
|
|
|
|
</p>
|
|
|
|
|
2018-01-19 10:02:13 -06:00
|
|
|
<form id="get-named-ranges-form">
|
|
|
|
Click <button onclick="callGetNamedRanges(); return false;">here</button> to get a list of named ranges in the document:
|
2018-01-22 03:22:58 -06:00
|
|
|
<textarea name="result" value="" rows="10" cols="80"></textarea>
|
2018-01-19 10:02:13 -06:00
|
|
|
</form>
|
|
|
|
|
2018-01-22 04:03:14 -06:00
|
|
|
<form id="add-named-range-form">
|
2018-01-22 06:53:19 -06:00
|
|
|
Click <button onclick="callAddNamedRange(); return false;">here</button> to add a new named range called
|
|
|
|
<input type="text" name="name"> on Sheet1 from (A1 syntax)
|
2018-01-22 04:03:14 -06:00
|
|
|
<input type="text" name="x0" value="A" size="1" pattern="[A-Z]{1}"> <input type="number" name="y0", min="1" max="999" value="1"> to
|
|
|
|
<input type="text" name="x1" value="B" size="1" pattern="[A-Z]{1}"> <input type="number" name="y1", min="1" max="999" value="3">.
|
2018-01-19 13:17:15 -06:00
|
|
|
</form>
|
|
|
|
|
2018-03-28 08:51:59 -05:00
|
|
|
<form id="delete-named-range-form">
|
|
|
|
Click <button onclick="callDeleteNamedRange(); return false;">here</button> to delete the named range called <input type="text" name="name">
|
|
|
|
</form>
|
|
|
|
|
2019-05-13 10:29:02 -05:00
|
|
|
<h3>UI modification</h3>
|
|
|
|
<form id="menubar-toggle">
|
|
|
|
<button onclick="ShowMenubar(false); return false;">Hide Menubar</button>
|
|
|
|
<button onclick="ShowMenubar(true); return false;">Show Menubar</button>
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Document frame</h3>
|
|
|
|
|
2018-01-19 04:31:38 -06:00
|
|
|
<!-- The hostname and pathnames below are obviously specific to my
|
2019-05-15 03:19:29 -05:00
|
|
|
personal environment and need to be changed appropriately. -->
|
2018-01-18 11:06:08 -06:00
|
|
|
|
2018-11-29 02:15:39 -06:00
|
|
|
<iframe src="http://localhost:9980/loleaflet/dist/loleaflet.html?file_path=file:///libreoffice/online/test/data/hello-world.ods&NotWOPIButIframe=true" height="1000" width="1000"></iframe>
|
2018-01-18 10:59:35 -06:00
|
|
|
</body>
|
|
|
|
</html>
|