Commit 1d4a9b67 authored by Arnaud Fontaine's avatar Arnaud Fontaine

erp5_code_mirror: Add support for the ZMI.

Also, add Javascript and CSS linters.
parent 40c1fe3f
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<script type="text/javascript" src="&dtml-portal_url;/codemirror/lib/codemirror.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/codemirror/lib/codemirror.js"></script>\n
<link rel="stylesheet" href="&dtml-portal_url;/codemirror/lib/codemirror.css">\n <link rel="stylesheet" href="&dtml-portal_url;/codemirror/lib/codemirror.css">\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/mode/python/python.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/codemirror/mode/&dtml-mode;/&dtml-mode;.js"></script>\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/edit/matchbrackets.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/edit/matchbrackets.js"></script>\n
\n \n
<!-- Trailing spaces -->\n <!-- Trailing spaces -->\n
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
-->\n -->\n
<link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/hint/show-hint.css">\n <link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/hint/show-hint.css">\n
<script src="&dtml-portal_url;/codemirror/addon/hint/show-hint.js"></script>\n <script src="&dtml-portal_url;/codemirror/addon/hint/show-hint.js"></script>\n
<script src="&dtml-portal_url;/codemirror/addon/hint/anyword-hint.js"></script>\n
\n \n
<!-- Code folding -->\n <!-- Code folding -->\n
<link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/fold/foldgutter.css">\n <link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/fold/foldgutter.css">\n
...@@ -63,11 +64,18 @@ ...@@ -63,11 +64,18 @@
<script type="text/javascript" src="&dtml-portal_url;/diff_match_patch/javascript/diff_match_patch_uncompressed.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/diff_match_patch/javascript/diff_match_patch_uncompressed.js"></script>\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/merge/merge.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/merge/merge.js"></script>\n
\n \n
<!-- Lint\n <!-- Linter -->\n
TODO: Only support Python for now -->\n
<link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/lint/lint.css">\n <link rel="stylesheet" href="&dtml-portal_url;/codemirror/addon/lint/lint.css">\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/lint/lint.js"></script>\n <script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/lint/lint.js"></script>\n
\n \n
<dtml-if expr="mode == \'javascript\'">\n
<script type="text/javascript" src="&dtml-portal_url;/jshint.js"></script>\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/lint/javascript-lint.js"></script>\n
<dtml-elif expr="mode == \'css\'">\n
<script type="text/javascript" src="&dtml-portal_url;/csslint.js"></script>\n
<script type="text/javascript" src="&dtml-portal_url;/codemirror/addon/lint/css-lint.js"></script>\n
</dtml-if>\n
\n
<style type="text/css">\n <style type="text/css">\n
.maximize_fullscreen_message {\n .maximize_fullscreen_message {\n
display: table;\n display: table;\n
...@@ -134,6 +142,8 @@ ...@@ -134,6 +142,8 @@
}\n }\n
</style>\n </style>\n
\n \n
<!-- TODO: Only supported for ZODB Components -->\n
<dtml-unless bound_names>\n
<input type="button" value="Maximize" onclick="maximize()"\n <input type="button" value="Maximize" onclick="maximize()"\n
class="editor_action_button" />\n class="editor_action_button" />\n
<input type="button" value="Fullscreen" onclick="switchToFullScreen(cm)"\n <input type="button" value="Fullscreen" onclick="switchToFullScreen(cm)"\n
...@@ -141,11 +151,8 @@ ...@@ -141,11 +151,8 @@
\n \n
<div id="merge" style="height: 100%; width: 100%">\n <div id="merge" style="height: 100%; width: 100%">\n
<div id="view" style="display: none;"></div>\n <div id="view" style="display: none;"></div>\n
\n
<textarea id="&dtml-field_id;" name="&dtml-field_id;" style="display: none;">\n
<dtml-var content>\n
</textarea>\n
</div>\n </div>\n
</dtml-unless>\n
\n \n
<script type="text/javascript">\n <script type="text/javascript">\n
error_element = $(\'div.input > .error\');\n error_element = $(\'div.input > .error\');\n
...@@ -155,6 +162,29 @@ ...@@ -155,6 +162,29 @@
merge_mode_elem = null;\n merge_mode_elem = null;\n
\n \n
maximize_mode_message = $(\'<span id="maximize_message">Press ESC to leave maximize mode</span>\');\n maximize_mode_message = $(\'<span id="maximize_message">Press ESC to leave maximize mode</span>\');\n
\n
function getTextareaField() {\n
// When the textarea does not exist yet (eg ERP5Form EditorField)\n
<dtml-if field_id>\n
textarea = $(\'#&dtml-field_id;\');\n
if(!textarea.length) {\n
$(\'#merge\').append(\n
\'<textarea id="&dtml-field_id;" name="&dtml-field_id;" style="display: none;">\' + \n
`&dtml-content;` +\n
\'</textarea>\');\n
\n
textarea = $(\'#&dtml-field_id;\');\n
}\n
<dtml-elif textarea_selector>\n
textarea = $(\'<dtml-var name="textarea_selector">\');\n
<dtml-else>\n
<dtml-raise NameError>\n
Either \'textarea_selector\' or \'field_id\' (ID of the textarea field to be\n
created) must be passed.\n
</dtml-raise>\n
</dtml-if>\n
return textarea;\n
}\n
\n \n
function maximizeFullscreenRemoveSaveMessage() {\n function maximizeFullscreenRemoveSaveMessage() {\n
$(\'.maximize_fullscreen_message\').remove();\n $(\'.maximize_fullscreen_message\').remove();\n
...@@ -291,7 +321,7 @@ ...@@ -291,7 +321,7 @@
\n \n
if(merge_mode_elem)\n if(merge_mode_elem)\n
// TODO: Hack, \'cm\' should work!\n // TODO: Hack, \'cm\' should work!\n
$(\'#&dtml-field_id;\').val(merge_mode_elem.edit.getValue());\n getTextareaField().val(merge_mode_elem.edit.getValue());\n
else\n else\n
cm.save();\n cm.save();\n
\n \n
...@@ -401,9 +431,14 @@ ...@@ -401,9 +431,14 @@
}\n }\n
\n \n
function checkPythonSourceCode(text, updateLinting, options, cm) {\n function checkPythonSourceCode(text, updateLinting, options, cm) {\n
checker_parameters = {code: text};\n
<dtml-if bound_names>\n
checker_parameters[\'bound_names\'] = <dtml-var name="bound_names">;\n
checker_parameters[\'params\'] = $(\'input[name="params"]\').val();\n
</dtml-if>\n
$.post(\n $.post(\n
\'&dtml-portal_url;/ERP5Site_checkPythonSourceCodeAsJSON\',\n \'&dtml-portal_url;/ERP5Site_checkPythonSourceCodeAsJSON\',\n
{\'data\': JSON.stringify({code: text})},\n {\'data\': JSON.stringify(checker_parameters)},\n
function(data){\n function(data){\n
var messages = data.annotations;\n var messages = data.annotations;\n
var found = [];\n var found = [];\n
...@@ -420,11 +455,20 @@ ...@@ -420,11 +455,20 @@
updateLinting(cm, found);\n updateLinting(cm, found);\n
});\n });\n
}\n }\n
\n
<dtml-if expr="mode == \'python\'">\n
lint_option = {"getAnnotations": checkPythonSourceCode,\n
"async": true};\n
<dtml-elif expr="mode in (\'css\', \'javascript\')">\n
lint_option = true;\n
<dtml-else>\n
lint_option = false;\n
</dtml-if>\n
\n \n
// CodeMirror expects a DOM element, not a JQuery Object\n // CodeMirror expects a DOM element, not a JQuery Object\n
var cm = CodeMirror.fromTextArea(\n var cm = CodeMirror.fromTextArea(\n
$(\'#&dtml-field_id;\')[0],\n getTextareaField()[0],\n
{mode: "python",\n {mode: "&dtml-mode;",\n
lineNumbers: true,\n lineNumbers: true,\n
showTrailingSpace: true,\n showTrailingSpace: true,\n
tabSize: 2,\n tabSize: 2,\n
...@@ -439,8 +483,7 @@ ...@@ -439,8 +483,7 @@
gutters: ["CodeMirror-lint-markers",\n gutters: ["CodeMirror-lint-markers",\n
"CodeMirror-linenumbers",\n "CodeMirror-linenumbers",\n
"CodeMirror-foldgutter"],\n "CodeMirror-foldgutter"],\n
lint: {"getAnnotations": checkPythonSourceCode,\n lint: lint_option\n
"async": true}\n
});\n });\n
//cm.foldCode(CodeMirror.Pos(8, 0));\n //cm.foldCode(CodeMirror.Pos(8, 0));\n
\n \n
...@@ -475,7 +518,7 @@ ...@@ -475,7 +518,7 @@
{value: cm.getValue(),\n {value: cm.getValue(),\n
orig: data,\n orig: data,\n
highlightDifferences: true,\n highlightDifferences: true,\n
mode: "python",\n mode: "&dtml-mode;",\n
lineNumbers: true,\n lineNumbers: true,\n
showTrailingSpace: true,\n showTrailingSpace: true,\n
matchBrackets: true,\n matchBrackets: true,\n
...@@ -630,7 +673,10 @@ ...@@ -630,7 +673,10 @@
success: successHandler});\n success: successHandler});\n
}\n }\n
\n \n
<dtml-unless bound_names>\n
<!-- TODO: Not supported for Python Scripts yet -->\n
generateHistorySelectElement();\n generateHistorySelectElement();\n
</dtml-unless>\n
</script>\n </script>\n
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
2015-04-23 arnaud.fontaine
* Add support for the ZMI.
2015-01-22 arnaud.fontaine 2015-01-22 arnaud.fontaine
* Gutter and source code separator line was not displayed because of erp5.css (df7eb0f). * Gutter and source code separator line was not displayed because of erp5.css (df7eb0f).
......
...@@ -2,4 +2,10 @@ CodeMirror is available at: ...@@ -2,4 +2,10 @@ CodeMirror is available at:
http://codemirror.net http://codemirror.net
diff_match_patch (used by CodeMirror Merge addon): diff_match_patch (used by CodeMirror Merge addon):
https://code.google.com/p/google-diff-match-patch https://code.google.com/p/google-diff-match-patch
\ No newline at end of file
jshint.js (used by CodeMirror Javascript lint addon):
http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js
csslint.js (used by CodeMirror CSS lint addon):
https://rawgit.com/stubbornella/csslint/master/release/csslint.js
...@@ -5,4 +5,10 @@ CodeMirror (under MIT license): ...@@ -5,4 +5,10 @@ CodeMirror (under MIT license):
Copyright (c) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others Copyright (c) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others
diff_match_patch (under Apache 2.0 license) diff_match_patch (under Apache 2.0 license)
Copyright (c) 2006 Google Inc. Copyright (c) 2006 Google Inc.
\ No newline at end of file
jshint.js (under modified MIT license):
Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
csslint.js (under MIT license):
Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
...@@ -126,7 +126,8 @@ class EditorWidget(Widget.TextAreaWidget): ...@@ -126,7 +126,8 @@ class EditorWidget(Widget.TextAreaWidget):
return code_mirror_support(field=field, return code_mirror_support(field=field,
content=value, content=value,
field_id=key, field_id=key,
portal_url=site_root.absolute_url()) portal_url=site_root.absolute_url(),
mode='python')
elif text_editor != 'text_area': elif text_editor != 'text_area':
return here.fckeditor_wysiwyg_support.pt_render( return here.fckeditor_wysiwyg_support.pt_render(
extra_context= { extra_context= {
......
...@@ -19,7 +19,7 @@ def manage_page_footer(self): ...@@ -19,7 +19,7 @@ def manage_page_footer(self):
except: except:
editor = None editor = None
if editor != 'ace': if editor not in ('ace', 'codemirror'):
return default return default
# REQUEST['PUBLISHED'] can be the form in the acquisition context of the # REQUEST['PUBLISHED'] can be the form in the acquisition context of the
...@@ -67,14 +67,28 @@ def manage_page_footer(self): ...@@ -67,14 +67,28 @@ def manage_page_footer(self):
textarea_selector = 'textarea[name="template:text"]' textarea_selector = 'textarea[name="template:text"]'
elif document.meta_type in ('Page Template', 'ERP5 OOo Template', ): elif document.meta_type in ('Page Template', 'ERP5 OOo Template', ):
if 'html' in document.content_type: if 'html' in document.content_type:
mode = 'html' if editor == 'codemirror':
mode = 'htmlmixed'
else:
mode = 'html'
else: else:
mode = 'xml' mode = 'xml'
textarea_selector = 'textarea[name="text:text"]' textarea_selector = 'textarea[name="text:text"]'
if not textarea_selector: if not textarea_selector:
return default return default
return '''
if editor == 'codemirror' and getattr(portal, 'code_mirror_support', None) is not None:
return '''<script type="text/javascript" src="%s/jquery/core/jquery.min.js"></script>
%s
</body>
</html>''' % (portal_url,
portal.code_mirror_support(textarea_selector=textarea_selector,
portal_url=portal_url,
bound_names=bound_names,
mode=mode))
else:
return '''
<script type="text/javascript" src="%(portal_url)s/jquery/core/jquery.min.js"></script> <script type="text/javascript" src="%(portal_url)s/jquery/core/jquery.min.js"></script>
<script type="text/javascript" src="%(portal_url)s/ace/ace.js"></script> <script type="text/javascript" src="%(portal_url)s/ace/ace.js"></script>
<script type="text/javascript" src="%(portal_url)s/ace/mode-%(mode)s.js"></script> <script type="text/javascript" src="%(portal_url)s/ace/mode-%(mode)s.js"></script>
......
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