Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make collabora save and exit actions more intuitive #12 #16

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONObject;
import org.restlet.Request;
import org.slf4j.Logger;
import org.xwiki.component.annotation.Component;
import org.xwiki.model.reference.AttachmentReference;
Expand Down Expand Up @@ -101,6 +102,8 @@ public Response get(String fileId, String token, String userCanWrite) throws XWi
message.put("Size", String.valueOf(attachment.getLongSize()));
message.put("UserCanWrite", userCanWrite);
message.put(LAST_MODIFIED_TIME, dateFormat.format(attachment.getDate()));
// Needed for using the PostMessage API.
message.put("PostMessageOrigin", Request.getCurrent().getHostRef().toString());

return Response.status(Response.Status.OK).entity(message.toString()).type(MediaType.APPLICATION_JSON)
.build();
Expand Down
161 changes: 142 additions & 19 deletions application-collabora-ui/src/main/resources/Collabora/Code/Main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,50 @@
<syntaxId>xwiki/2.1</syntaxId>
<hidden>true</hidden>
<content>{{velocity output="false"}}
#macro (renderCollaboraContent $mode)
## Display logo and some information about the currently edited file. Show Cancel action on the right.
## Save action is included in Collabora editor.
&lt;div class="actionMenu"&gt;
&lt;div&gt;
&lt;a href="${xwiki.getURL('Main.WebHome')}"&gt;&lt;img src="$xwiki.getSkinFile('logo.svg')"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;strong&gt;$currentAction&lt;/strong&gt;
&lt;em&gt;$escapetool.xml($request.filename)&lt;/em&gt;
$escapetool.xml($services.localization.render('collabora.editor.onPage'))
&lt;a href="${fileDoc.URL}#Attachments" title="$escapetool.xml($services.localization.render('cancel'))"&gt;
$escapetool.xml($fileDoc.displayTitle)
&lt;/a&gt;
#macro (unsavedChangesModal)
&lt;div class="modal fade" id="editUnsavedChanges" tabindex="-1" role="dialog" aria-hidden="true"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
&lt;div class="modal fade" id="editUnsavedChanges" tabindex="-1" role="dialog" aria-hidden="true"
&lt;div class="modal fade" id="collaboraUnsavedChanges" tabindex="-1" role="dialog" aria-hidden="true"

aria-label="$escapetool.xml($services.localization.render('collabora.editor.unsaved.label'))"&gt;
&lt;div class="modal-dialog modal-sm"&gt;
&lt;div class="modal-content"&gt;
&lt;div class="modal-body"&gt;
$escapetool.xml($services.localization.render('collabora.editor.unsaved.info'))
&lt;/div&gt;
&lt;div&gt;
&lt;a href="${fileDoc.URL}#Attachments" class="btn btn-default"
title="$escapetool.xml($services.localization.render('cancel'))"&gt;
$escapetool.xml($services.localization.render('cancel'))
&lt;/a&gt;
&lt;div class="modal-footer"&gt;
&lt;input type="submit" class="btn btn-danger"
value="$escapetool.xml($services.localization.render('collabora.editor.unsaved.submit'))"&gt;
&lt;input type="button" class="btn btn-default" data-dismiss="modal"
value="$escapetool.xml($services.localization.render('collabora.editor.unsaved.close'))"&gt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to also have the option to save before closing the editor?

&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
#end
#macro (renderCollaboraContent $mode)
## Display logo and some information about the currently edited file. Save, Save and exit and Close actions are
## included in Collabora editor.
&lt;div class="actionMenu"&gt;
&lt;div&gt;
&lt;a href="${xwiki.getURL('Main.WebHome')}"&gt;&lt;img src="$xwiki.getSkinFile('logo.svg')"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;strong&gt;$currentAction&lt;/strong&gt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you do the escaping below, when setting the value, but I find it more clear to perform the escaping in the place where the value is used (because the escaping depends on the context where the value is used). specially since you use the value only once, here.

&lt;em&gt;$escapetool.xml($request.filename)&lt;/em&gt;
$escapetool.xml($services.localization.render('collabora.editor.onPage'))
&lt;a id='fileHomePage' href="${fileDoc.URL}#Attachments"
title="$escapetool.xml($services.localization.render('cancel'))"&gt;
$escapetool.xml($fileDoc.displayTitle)
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
#set ($saveAndExitIconURL = $xwiki.getDocument('Collabora.Code.UI').getAttachmentURL('saveAndExit.png'))
#set ($closeIconURL = $xwiki.getDocument('Collabora.Code.UI').getAttachmentURL('close.png'))
#set ($saveAndExitMessage = $escapetool.xml($services.localization.render('collabora.editor.saveAndExit')))
#set ($closeMessage = $escapetool.xml($services.localization.render('collabora.editor.close')))
## TODO: The translations are added for now as a data attribute. This should be changed once the application starts
## depending on a XWiki version &gt;= 13.8 to include XWIKI-18973: Simplify the way JavaScript code loads translation
## messages.
&lt;span id="collaboraConfig" data-save-exit-icon="$saveAndExitIconURL" data-close-icon="$closeIconURL"
data-save-exit-message="$saveAndExitMessage" data-close-message="$closeMessage"&gt;&lt;/span&gt;
## Information needed by collabora to be able to edit the current file.
#set ($fileId = $escapetool.xml($services.model.serialize($attachment.getReference(), 'default')))
#set ($errorMessage = $escapetool.xml($services.localization.render('collabora.editor.error')))
Expand All @@ -70,6 +92,7 @@
&lt;/form&gt;
## Where the document will be displayed.
&lt;iframe id="collaboraViewer" name="collaboraViewer"&gt;&lt;/iframe&gt;
#unsavedChangesModal()
#end
{{/velocity}}

Expand Down Expand Up @@ -197,6 +220,99 @@
<property>
<code>require(['jquery'], function($) {
const collaboraPath ='/rest/collabora/files/';
const iframeWindow = document.getElementById('collaboraViewer').contentWindow;
var isDocModified = false;

var getSaveAndExitButtonMessage = function() {
return JSON.stringify({
'MessageId': 'Insert_Button',
'SendTime': Date.now(),
'Values': {
'id': 'saveAndExitEditor',
'imgurl': window.location.origin + $("#collaboraConfig").data('saveExitIcon'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'imgurl': window.location.origin + $("#collaboraConfig").data('saveExitIcon'),
'imgurl': new URL($("#collaboraConfig").data('saveExitIcon'), window.location.origin),

'hint': $("#collaboraConfig").data('saveExitMessage'),
'mobile': true,
'label': $("#collaboraConfig").data('saveExitMessage')
}
});
};

var getCloseButtonMessage = function() {
return JSON.stringify({
'MessageId': 'Insert_Button',
'SendTime': Date.now(),
'Values': {
'id': 'closeEditor',
'imgurl': window.location.origin + $("#collaboraConfig").data('closeIcon'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

'hint': $("#collaboraConfig").data('closeMessage'),
'mobile': true,
'label': $("#collaboraConfig").data('closeMessage')
}
});
};

var getSaveDocumentMessage = function() {
return JSON.stringify({
"MessageId" : "Action_Save",
"SendTime": Date.now(),
"Values" : {
"DontTerminateEdit" : true,
"DontSaveIfUnmodified": true,
"Notify" : true
}
});
}

/**
* If there are unsaved changes, ask the user if these should be discarded. Otherwise, go to the file home page.
*/
var onCloseEditor = function() {
if (isDocModified) {
$('#editUnsavedChanges').modal('show');
} else {
window.location.href = $('#fileHomePage').attr('href');
}
};

var onDocumentLoaded = function() {
// Notify the server that postMessage is going to be used.
iframeWindow.postMessage(JSON.stringify({ 'MessageId': 'Host_PostmessageReady' }), '*');
// Add the saveAndExit and close custom buttons.
iframeWindow.postMessage(getSaveAndExitButtonMessage(), '*');
iframeWindow.postMessage(getCloseButtonMessage(), '*');
};

var receiveMessage = function(event) {
// Skip messages that are not from this iframe.
if (event.source !== iframeWindow) {
return;
}
var msg = JSON.parse(event.data);
if (!msg) {
return;
}

if (msg.MessageId == 'App_LoadingStatus' &amp;&amp; msg.Values &amp;&amp; msg.Values.Status == 'Document_Loaded') {
onDocumentLoaded();
} else if (msg.MessageId == 'Doc_ModifiedStatus') {
isDocModified = msg.Values &amp;&amp; msg.Values.Modified;
} else if (msg.MessageId == 'Clicked_Button') {
if (msg.Values &amp;&amp; msg.Values.Id == 'saveAndExitEditor') {
// Save the file and let the editor close action be handleded after this is finished, on Action_Save_Resp.
iframeWindow.postMessage(getSaveDocumentMessage(), '*');
} else if (msg.Values &amp;&amp; msg.Values.Id == 'closeEditor') {
onCloseEditor();
}
} else if (msg.MessageId == 'Action_Save_Resp') {
// This event is send when Action_Save or Action_Save_As are triggered from our code, and UI_Save when using the
// editor's default save button. Right now, we only fire Action_Save on the custom saveAndExit button. So after
// this save is succesfull, a redirect to the file home page is required.
if (msg.Values &amp;&amp; msg.Values.success) {
window.location.href = $('#fileHomePage').attr('href');
}
}
}

$(function() {
const fileId = $("#collaboraServer").data('fileId');
const userCanWrite = $("#collaboraServer").data('mode') === 'edit';
Expand All @@ -219,6 +335,13 @@
}).fail(function(jqxhr, textStatus, error) {
new XWiki.widgets.Notification(errorMessage + error, 'error');
});

// Listen to messages send by Collabora server.
window.addEventListener("message", receiveMessage, false);
});

$(document).on('click', '#editUnsavedChanges input.btn-danger', function(e) {
window.location.href = $('#fileHomePage').attr('href');
});

$(window).unload(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ collabora.attachment.view.title=View using Collabora
## Editor
collabora.editor.onPage=on page
collabora.editor.error=Error while loading this file. Cause:
collabora.editor.close=Close editor
collabora.editor.saveAndExit=Save and exit
collabora.editor.unsaved.close=Keep editing
collabora.editor.unsaved.info=There are unsaved changes. Are you sure you want to exit without saving?
collabora.editor.unsaved.label=Unsaved changes
collabora.editor.unsaved.submit=Close without saving
collabora.validation.attachmentMissing=Document or attachment not found!
collabora.validation.documentMissing=Document parameter required!
collabora.validation.filenameMissing=Filename parameter required!</content>
Expand Down
20 changes: 20 additions & 0 deletions application-collabora-ui/src/main/resources/Collabora/Code/UI.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@
<syntaxId>xwiki/2.1</syntaxId>
<hidden>true</hidden>
<content/>
<attachment>
<filename>close.png</filename>
<mimetype>image/png</mimetype>
<charset>UTF-8</charset>
<author>xwiki:XWiki.Admin</author>
<version>1.1</version>
<comment/>
<content>iVBORw0KGgoAAAANSUhEUgAAABgAAAAYBAMAAAASWSDLAAAAMFBMVEUAAADkLx/iMCDiMCDjMSDkMCDiLx/iMCDiLx/iMCDiMB/////iMB/iLx/iMCDiMR8QM5r+AAAAEHRSTlMAYJ/P/19Q35CP4P/woO/Q9/WoOgAAAKVJREFUeJxjYMALhEycVWHsdBcgKIOwOVzAYAKY0wLheIDYbC5QkADkcLl473FxOb3FpQDIEXHx5j7is3uLixuQc8XFb8Oe07ufuPgCOV9cXF7v3r3PxcUZyAFq9dsNlHBxgXB8du8+AuEAlZ3evQFooD/YAJ/d+15zHwEbADR69xM/qNFAS4FGvd7isgDdOSgOhXmhAeKhLBB7Gcyrsl/8L+IPGABYMkPB47UBjQAAAABJRU5ErkJggg==</content>
<filesize>310</filesize>
</attachment>
<attachment>
<filename>collabora-symbol.svg</filename>
<mimetype>image/svg+xml</mimetype>
Expand All @@ -47,6 +57,16 @@
<content>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTJweCIgaGVpZ2h0PSIxMnB4IiB2aWV3Qm94PSIwIDAgMTIgMTIiIHZlcnNpb249IjEuMSI+CjxnIGlkPSJzdXJmYWNlMSI+CjxwYXRoIHN0eWxlPSIgc3Ryb2tlOm5vbmU7ZmlsbC1ydWxlOm5vbnplcm87ZmlsbDpyZ2IoMTAwJSwxMDAlLDEwMCUpO2ZpbGwtb3BhY2l0eToxOyIgZD0iTSAwIDAgTCAxMS45ODQzNzUgMCBMIDExLjk4NDM3NSAxMS45ODQzNzUgTCAwIDExLjk4NDM3NSBaIE0gMCAwICIvPgo8cGF0aCBzdHlsZT0iIHN0cm9rZTpub25lO2ZpbGwtcnVsZTpub256ZXJvO2ZpbGw6cmdiKDEwMCUsMTAwJSwxMDAlKTtmaWxsLW9wYWNpdHk6MTsiIGQ9Ik0gMy40NDUzMTIgMy43MzQzNzUgTCAzLjU4OTg0NCAzLjU4OTg0NCBMIDUuOTkyMTg4IDUuOTkyMTg4IEwgMy41ODk4NDQgOC4zOTQ1MzEgTCAzLjQ0NTMxMiA4LjI1IEwgNS43MDMxMjUgNS45OTIxODggWiBNIDMuNDQ1MzEyIDMuNzM0Mzc1ICIvPgo8cGF0aCBzdHlsZT0iIHN0cm9rZTpub25lO2ZpbGwtcnVsZTpub256ZXJvO2ZpbGw6cmdiKDc4LjQzMTM3MyUsNzguNDMxMzczJSw3OC40MzEzNzMlKTtmaWxsLW9wYWNpdHk6MTsiIGQ9Ik0gMy40NDUzMTIgMy43MzQzNzUgTCAzLjQ0NTMxMiA4LjI1IEwgNS43MDMxMjUgNS45OTIxODggWiBNIDMuNDQ1MzEyIDMuNzM0Mzc1ICIvPgo8cGF0aCBzdHlsZT0iIHN0cm9rZTpub25lO2ZpbGwtcnVsZTpub256ZXJvO2ZpbGw6cmdiKDMxLjM3MjU0OSUsMjguNjI3NDUxJSw2MCUpO2ZpbGwtb3BhY2l0eToxOyIgZD0iTSA1LjQ5MjE4OCAxLjY4NzUgTCAzLjU4OTg0NCAzLjU4OTg0NCBMIDUuOTkyMTg4IDUuOTkyMTg4IEwgMy41ODk4NDQgOC4zOTQ1MzEgTCA1LjQ5MjE4OCAxMC4yOTY4NzUgTCA5Ljc5Njg3NSA1Ljk5MjE4OCBaIE0gNS40OTIxODggMS42ODc1ICIvPgo8cGF0aCBzdHlsZT0iIHN0cm9rZTpub25lO2ZpbGwtcnVsZTpub256ZXJvO2ZpbGw6cmdiKDIxLjk2MDc4NCUsMTQuNTA5ODA0JSw0Ny44NDMxMzclKTtmaWxsLW9wYWNpdHk6MTsiIGQ9Ik0gNS40MDIzNDQgNi41ODIwMzEgTCAzLjgxMjUgOC4xNjc5NjkgTCA2LjE2MDE1NiA3LjY1MjM0NCBaIE0gNS40MDIzNDQgNi41ODIwMzEgIi8+CjwvZz4KPC9zdmc+Cg==</content>
<filesize>1225</filesize>
</attachment>
<attachment>
<filename>saveAndExit.png</filename>
<mimetype>image/png</mimetype>
<charset>UTF-8</charset>
<author>xwiki:XWiki.Admin</author>
<version>1.1</version>
<comment/>
<content>iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAmVBMVEUAAAA6Ojg6Ojg6Ojh5d3T6+vr5+Pj129vvvbvusrCoNi6famZ7dnOPODHYMiTjMSDZQDWPODK3XVjjMiHlMCGlZ2LjMSDlMh/aPzT////jMSCgamanNi7tsbCFODNBOjjmbGfjNCXjMCA7OzlXV1Tz1dTlMCBISEg6Ojnwvr3jMyJFRUXWMiTWMSSYNzH/fwDnMiLkMx/lMiI9Pt+zAAAAM3RSTlMAxf/D/////////////////////3n//lH//97/////////3cv//08V0v94Fv//1QRCe40eLfJ5AAAArElEQVR4nMXS1w6CMBQGYKzUiR6xrrqwgnsAvv/D2Z62WCR64Y1/Agn/F9LpeT+kRiqpIxDfJ9SJ+v4LNJqtdqcbvMCk1weVQWjBZMjAZFSCMQMtDCZTB4IZMM5lr15zBxbYcXwADKiRl6AF+wLkVFdgBMrw8Q+yVj19H0NCtAFRzGorIU40kJ0AYdexl3A4JhroSdiVn3FPLrHdq/CK9e1eOf80yx95ln67Ik+P+BKgdL3gCAAAAABJRU5ErkJggg==</content>
<filesize>457</filesize>
</attachment>
<object>
<name>Collabora.Code.UI</name>
<number>0</number>
Expand Down