Commit 7ae732b7 authored by Arnaud Fontaine's avatar Arnaud Fontaine Committed by Jérome Perrin

erp5_code_mirror: Add support for the ZMI.

Also, add Javascript and CSS linters.

(cherry picked from commit 1d4a9b67)
parent c15e7730
...@@ -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).
......
...@@ -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