Commit 7bf233bb authored by Arnaud Fontaine's avatar Arnaud Fontaine

Add save button to Ace Editor to save source code while staying on the same page.

This has several benefits:

* No need to exit maximize/fullscreen modes to save.
* The cursor position in the editor does not change.

This implementation is hackish because it is too Component-specific, but until
RenderJS is being used, there is no probably no better way.
parent 1dd9753c
......@@ -69,11 +69,46 @@
.ace_line {\n
color: black !important;\n
}\n
\n
.ace_editor_save_button {\n
position: absolute;\n
top: 5px;\n
right: 20px;\n
width: 30px;\n
height: 30px;\n
border: none;\n
background-color: transparent;\n
cursor: pointer;\n
}\n
\n
.ace_editor_maximize_fullscreen_message {\n
display: table;\n
position: absolute;\n
bottom: 0;\n
right: 20px;\n
z-index: 424242;\n
padding: 20px;\n
background-color: #DAE6F6;\n
border: 1px solid #97B0D1;\n
opacity: 0.3;\n
cursor: pointer;\n
font-weight: bold;\n
}\n
\n
.ace_editor_maximize_fullscreen_error_message {\n
background-color: red;\n
}\n
\n
.ace_editor_maximize_fullscreen_message > div {\n
font-size: 14px;\n
display: table-cell;\n
vertical-align: middle;\n
}\n
\n
#maximize_message {\n
display: block !important;\n
position: absolute !important;\n
top: 0 !important;\n
bottom: 0 !important;\n
right: 0px !important;\n
z-index: 4243 !important;\n
padding: 10px;\n
......@@ -139,10 +174,16 @@
<script type="text/javascript"\n
tal:attributes="src string:${portal_url}/ace/mode-python.js"></script>\n
<script type="text/javascript"\n
tal:define=\'fullscreen_button string:<input type="button" value="Fullscreen" onclick="switchToFullScreen()" class="ace_editor_action_button" />\'\n
tal:define=\'fullscreen_button string:<input type="button" value="Fullscreen" onclick="switchToFullScreen()" class="ace_editor_action_button" />;\n
save_button string:<button class="ace_editor_save_button" onclick="saveDocument(event)"><img src="images/save2.png" width="30" height="30" border="0" /></button>;\'\n
\n
tal:content="structure string:\n
ace_editor_container_div = null;\n
ace_editor = null;\n
\n
function maximizeFullscreenRemoveSaveMessage() {\n
$(\'.ace_editor_maximize_fullscreen_message\').remove();\n
}\n
\n
function switchToFullScreen(id) {\n
element = document.getElementById(\'${container_div_id}\');\n
......@@ -151,10 +192,10 @@
if (element.requestFullScreen) {\n
element.requestFullScreen();\n
}\n
else if (element.mozRequestFullScreen) {\n
else if(element.mozRequestFullScreen) {\n
element.mozRequestFullScreen();\n
}\n
else if (element.webkitRequestFullScreen) {\n
else if(element.webkitRequestFullScreen) {\n
element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);\n
}\n
ace_editor.resize();\n
......@@ -181,6 +222,7 @@
\n
function unmaximize(event) {\n
if(event.keyCode == 27) {\n
maximizeFullscreenRemoveSaveMessage();\n
$(\'body\').css(\'overflow\', \'visible\');\n
ace_editor_container_div.removeClass(\'maximize\');\n
ace_editor_container_div.appendTo(ace_editor_container_div_parent_before_maximized);\n
......@@ -207,6 +249,104 @@
$(document).keyup(unmaximize);\n
ace_editor.resize();\n
}\n
\n
// Save source code only through an AJAX request\n
function saveDocument(event) {\n
event.stopPropagation();\n
event.preventDefault();\n
\n
clickSaveButton(\'Base_edit\');\n
\n
/* If the save is successful, then update validation state field (requires\n
* ace_editor_validation_state CSS class to be set on the field) and error\n
* message (requires error CSS class to be set on the field) on the main\n
* page. If inside maximize/fullscreen mode, display an box with the\n
* result as well\n
*/\n
function successHandler(data) {\n
transition_message = $(\'#transition_message\');\n
transition_message.css(\'opacity\', 0.0);\n
transition_message.html(data);\n
transition_message.animate({opacity: 1.0},\n
{duration: 3000, queue: false});\n
\n
var maximize_fullscreen_message = data;\n
var error_arr = [];\n
\n
var validation_state_span = $(\'div.input > .ace_editor_validation_state\');\n
if(validation_state_span.length) {\n
// Animate field to emphasize the change\n
function getTranslatedValidationStateTitleHandler(data) {\n
validation_state_span.css(\'opacity\', 0.0);\n
validation_state_span.html(data);\n
validation_state_span.animate({opacity: 1.0},\n
{duration: 3000, queue: false});\n
}\n
\n
$.ajax({type: \'GET\',\n
url: \'getTranslatedValidationStateTitle\',\n
success: getTranslatedValidationStateTitleHandler});\n
}\n
\n
var error_element = $(\'div.input > .error\');\n
if(error_element.length) {\n
// Animate field to emphasize the change\n
function getErrorMessageListHandler(data) {\n
error_arr = $.parseJSON(data);\n
error_element.css(\'opacity\', 0.0);\n
error_element.html(error_arr.join(\'<br />\'));\n
error_element.animate({opacity: 1.0},\n
{duration: 3000, queue: false});\n
}\n
\n
$.ajax({type: \'GET\',\n
async: false,\n
url: \'getErrorMessageList\',\n
data: \'as_json:int=1\',\n
success: getErrorMessageListHandler});\n
}\n
\n
if($(\'.maximize\').length ||\n
(document.fullScreenElement && document.fullScreenElement !== null &&\n
(document.mozFullScreen || document.webkitIsFullScreen))) {\n
var msg_elem_classes = \'ace_editor_maximize_fullscreen_message\';\n
if(error_arr.length) {\n
maximize_fullscreen_message = error_arr.join(\'<br />\');\n
msg_elem_classes += \' ace_editor_maximize_fullscreen_error_message\';\n
}\n
\n
// Clear previous saving message if any\n
maximizeFullscreenRemoveSaveMessage();\n
\n
msg_elem = $(\'<div class=&quot;\' + msg_elem_classes + \'&quot;>\' +\n
\'<div>\' + maximize_fullscreen_message + \'</div></div>\');\n
\n
msg_elem.appendTo($(\'#${div_id}\'));\n
\n
function animateMessageComplete() {\n
if(!error_arr.length)\n
$(this).remove();\n
else\n
$(this).bind(\'click\', function() { $(this).remove() });\n
}\n
msg_elem.animate({opacity: 1.0}, 1500, animateMessageComplete);\n
}\n
}\n
\n
function errorHandler(data, textStatus) {\n
alert(\'Saving failed: \' + textStatus);\n
}\n
\n
var edit_data = $(\'form#main_form\').serialize();\n
edit_data += \'&message_only:int=1\';\n
$.ajax({type: \'POST\',\n
url: \'Base_edit\',\n
data: edit_data,\n
success: successHandler,\n
error: errorHandler});\n
\n
return false;\n
}\n
\n
window.onload = function() {\n
ace_editor_container_div = $(\'#${container_div_id}\');\n
......@@ -225,11 +365,26 @@
ace_editor.getSession().on(\'change\', function() {\n
textarea.val(ace_editor.getSession().getValue());\n
});\n
\n
/* Only display the source code saving button if the main save button is\n
* displayed. This specific save button allows to save without reloading the\n
* page (and thus keep the cursor position and mode (maximize/fullscreen)\n
* through an AJAX request.\n
*\n
* TODO: Use RenderJS instead to avoid this ugly hack as only some fields\n
* are reloaded and this is not generic at all.\n
*/\n
if($$(\'div.actions > button.save[name=Base_edit:method]\').length)\n
$$(\'${save_button}\').appendTo($(\'#${div_id}\'));\n
\n
if(typeof document.cancelFullScreen != \'undefined\' ||\n
(typeof document.mozFullScreenEnabled != \'undefined\' && document.mozFullScreenEnabled) ||\n
typeof document.webkitCancelFullScreen != \'undefined\')\n
typeof document.webkitCancelFullScreen != \'undefined\') {\n
$$(document).bind(\'webkitfullscreenchange mozfullscreenchange fullscreenchange\',\n
maximizeFullscreenRemoveSaveMessage);\n
\n
$$(\'${fullscreen_button}\').insertAfter($$(\'input.ace_editor_action_button\'));\n
}\n
};">\n
</script>\n
</tal:block>
......
2013-07-19 arnaud.fontaine
* Add save button to Ace Editor to save source code while staying on the same page.
2013-07-09 arnaud.fontaine
* ZODB Components: Follow ERP5 Python indentation style in Ace editor.
......
9
\ No newline at end of file
10
\ No newline at end of file
......@@ -287,6 +287,9 @@ try:\n
except ActivityPendingError,e:\n
message = Base_translateString("%s" % e)\n
\n
if message_only:\n
return message\n
\n
ignore_layout = int(ignore_layout)\n
editable_mode = int(editable_mode)\n
spp = context.getPhysicalPath()\n
......@@ -332,7 +335,7 @@ return result\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id, selection_index=0, selection_name=\'\', dialog_id=\'\', ignore_layout=0, editable_mode=1, silent_mode=0, field_prefix=\'my_\', key_prefix=None, listbox_edit=None</string> </value>
<value> <string>form_id, selection_index=0, selection_name=\'\', dialog_id=\'\', ignore_layout=0, editable_mode=1, silent_mode=0, field_prefix=\'my_\', key_prefix=None, listbox_edit=None, message_only=False</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -12,7 +12,6 @@
<list>
<string>css_class</string>
<string>editable</string>
<string>enabled</string>
<string>height</string>
<string>title</string>
</list>
......@@ -64,12 +63,6 @@
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -105,10 +98,6 @@
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_lines_field</string> </value>
......@@ -135,17 +124,4 @@
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/hasErrorMessageList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>css_class</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,10 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string>ace_editor_validation_state</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_translated_workflow_state_title</string> </value>
......
2013-07-19 arnaud.fontaine
* Add save button to Ace Editor to save source code while staying on the same page.
2013-07-09 arnaud.fontaine
* ZODB COmponents: Cosmetic: Fix Component Validation Workflow description.
......
41117
\ No newline at end of file
41118
\ No newline at end of file
......@@ -282,14 +282,22 @@ class ComponentMixin(PropertyRecordableMixin, Base):
security.declareProtected(Permissions.AccessContentsInformation,
'getErrorMessageList')
def getErrorMessageList(self):
def getErrorMessageList(self, as_json=False):
"""
Return the checkConsistency errors which may have occurred when
the Component has been modified after being validated once
"""
current_workflow = self.workflow_history['component_validation_workflow'][-1]
return [error.translate()
for error in current_workflow.get('error_message', [])]
error_list = [error.translate()
for error in current_workflow.get('error_message', [])]
# Dirty hack until RenderJS is used to save the source code
# (erp5_ace_editor/ace_editor_support)
if as_json:
import json
return json.dumps(error_list)
return error_list
security.declareProtected(Permissions.ModifyPortalContent, 'load')
def load(self, namespace_dict, validated_only=False, text_content=None):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment