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.
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).
......
...@@ -3,3 +3,9 @@ http://codemirror.net ...@@ -3,3 +3,9 @@ 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
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
...@@ -6,3 +6,9 @@ Copyright (c) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others ...@@ -6,3 +6,9 @@ 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.
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,6 +67,9 @@ def manage_page_footer(self): ...@@ -67,6 +67,9 @@ 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:
if editor == 'codemirror':
mode = 'htmlmixed'
else:
mode = 'html' mode = 'html'
else: else:
mode = 'xml' mode = 'xml'
...@@ -74,6 +77,17 @@ def manage_page_footer(self): ...@@ -74,6 +77,17 @@ def manage_page_footer(self):
if not textarea_selector: if not textarea_selector:
return default return default
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 ''' 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>
......
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