Commit 3d5136bd authored by Romain Courteaud's avatar Romain Courteaud

[erp5_code_mirror] Clean up gadget

Remove full screen handling for now.
parent a61f8350
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Codemirror</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="codemirror/lib/codemirror.js"></script>
<link rel="stylesheet" href="codemirror/lib/codemirror.css" />
<!--script src="codemirror/mode/&dtml-mode;/&dtml-mode;.js"></script-->
<script src="codemirror/addon/cm_edit/matchbrackets.js"></script>
<!-- Trailing spaces -->
<script src="codemirror/addon/cm_edit/trailingspace.js"></script>
<style type="text/css">
.cm-trailingspace {
background-color: gray;
}
.CodeMirror {
height: 100%;
}
body {
padding: 0;
margin: 0;
}
</style>
<!-- Search addons -->
<link rel="stylesheet" href="codemirror/addon/dialog/dialog.css">
<script src="codemirror/addon/dialog/dialog.js"></script>
<script src="codemirror/addon/search/searchcursor.js"></script>
<script src="codemirror/addon/search/search.js"></script>
<script src="codemirror/addon/search/jump-to-line.js"></script>
<script src="codemirror/addon/selection/active-line.js"></script>
<!-- Python autocomplete (Ctrl-Space, see below)
TODO-arnau: Add ERP5 autocompletion?
-->
<link rel="stylesheet" href="codemirror/addon/hint/show-hint.css" />
<script src="codemirror/addon/hint/show-hint.js"></script>
<script src="codemirror/addon/hint/anyword-hint.js"></script>
<!-- Code folding -->
<link rel="stylesheet" href="codemirror/addon/fold/foldgutter.css" />
<script src="codemirror/addon/fold/foldcode.js"></script>
<script src="codemirror/addon/fold/foldgutter.js"></script>
<script src="codemirror/addon/fold/indent-fold.js"></script>
<script src="codemirror/addon/fold/comment-fold.js"></script>
<!-- Merge -->
<link rel="stylesheet" href="codemirror/addon/merge/merge.css" />
<script src="diff_match_patch/javascript/diff_match_patch_uncompressed.js"></script>
<script src="codemirror/addon/merge/merge.js"></script>
<!-- Linter -->
<link rel="stylesheet" href="codemirror/addon/lint/lint.css" />
<script src="codemirror/addon/lint/lint.js"></script>
<!--link rel="stylesheet" href="codemirror/lib/codemirror.css" />
<link rel="stylesheet" href="codemirror/addon/display/fullscreen.css" /-->
<!-- link rel="stylesheet" href="addon/dialog/dialog.css" / -->
<!-- script src="addon/search/searchcursor.js"></script>
<script src="addon/cm_edit/matchbrackets.js"></script -->
<!--script src="codemirror/addon/display/fullscreen.js"></script-->
<!-- script src="addon/dialog/dialog.js"></script>
<script src="mode/javascript/javascript.js"></script -->
<script src="codemirror.gadget.js"></script>
</head>
<body>
<textarea></textarea>
</body>
</html>
......@@ -6,10 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts57455860.13</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>codemirror.gadget.html</string> </value>
......@@ -22,10 +18,6 @@
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>865</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
......
/*jslint nomen: true, indent: 2 */
/*global window, rJS, CodeMirror*/
(function (window, rJS, CodeMirror) {
"use strict";
rJS(window)
.ready(function () {
this.editor = CodeMirror.fromTextArea(
this.element.querySelector('textarea'),
{
// mode: mode,
lineNumbers: true,
styleActiveLine: true,
showTrailingSpace: true,
tabSize: 2,
indentWithTabs: false,
matchBrackets: true,
extraKeys: {
"Ctrl-Space": "autocomplete",
"Alt-Space": "autocomplete",
"Ctrl-Q": function (cm) {
cm.foldCode(cm.getCursor());
},
"Tab": function (cm) {
// We want to insert spaces, not tab, and we also want to keep the behaviour of indenting selection.
if (cm.getSelection()) {
return cm.execCommand("defaultTab");
}
var spaces = new Array(cm.getOption("indentUnit") + 1).join(" ");
cm.replaceSelection(spaces);
},
"Ctrl-I": "indentAuto",
"Shift-Tab": "indentLess"
// "Ctrl-S": function(cm){saveDocument(cm, $.Event('click'))}
},
foldGutter: true,
lineWrapping: true,
gutters: ["CodeMirror-lint-markers",
"CodeMirror-linenumbers",
"CodeMirror-foldgutter"],
lint: false
}
);
window.editor = this.editor;
})
.declareMethod('render', function (options) {
return this.changeState({
key: options.key,
value: options.value || "",
editable: options.editable === undefined ? true : options.editable
});
})
.onStateChange(function (modification_dict) {
if (modification_dict.hasOwnProperty('value')) {
this.editor.setValue(this.state.value);
}
})
.declareMethod('getContent', function () {
var form_data = {};
if (this.state.editable) {
form_data[this.state.key] = this.editor.getValue();
}
return form_data;
});
}(window, rJS, CodeMirror));
......@@ -6,10 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts57608537.76</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>codemirror.gadget.js</string> </value>
......@@ -22,10 +18,6 @@
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>7916</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Codemirror</title>
<script src="../rsvp.js"></script>
<script src="../renderjs.js"></script>
<link rel="stylesheet" href="lib/codemirror.css" />
<link rel="stylesheet" href="addon/display/fullscreen.css" />
<!-- link rel="stylesheet" href="addon/dialog/dialog.css" / -->
<script src="lib/codemirror.js"></script>
<!-- script src="addon/search/searchcursor.js"></script>
<script src="addon/cm_edit/matchbrackets.js"></script -->
<script src="addon/display/fullscreen.js"></script>
<!-- script src="addon/dialog/dialog.js"></script>
<script src="mode/javascript/javascript.js"></script -->
<script src="codemirror.gadget.js"></script>
</head>
<body>
</body>
</html>
/*jslint nomen: true, indent: 2 */
/*global window, rJS, CodeMirror, document, RSVP, loopEventListener */
(function (window, rJS, CodeMirror, RSVP) { //, loopEventListener) {
"use strict";
// XXXXXXXXXXXXXXXXXXX REMOVE THIS FUNCTION AFTER ADDING IT ON ERP5 GLOBALS ON CLASSIC VIEWS
var loopEventListener = function (target, type, useCapture, callback, prevent_default) {
//////////////////////////
// Infinite event listener (promise is never resolved)
// eventListener is removed when promise is cancelled/rejected
//////////////////////////
var handle_event_callback, callback_promise;
if (prevent_default === undefined) {
prevent_default = true;
}
function cancelResolver() {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
}
}
function canceller() {
if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture);
}
cancelResolver();
}
function itsANonResolvableTrap(resolve, reject) {
var result;
handle_event_callback = function (evt) {
if (prevent_default) {
evt.stopPropagation();
evt.preventDefault();
}
cancelResolver();
try {
result = callback(evt);
} catch (e) {
result = RSVP.reject(e);
}
callback_promise = result;
new RSVP.Queue()
.push(function () {
return result;
})
.push(undefined, function (error) {
if (!(error instanceof RSVP.CancellationError)) {
canceller();
reject(error);
}
});
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(itsANonResolvableTrap, canceller);
};
function requestFullScreen(element) {
if ((document.fullScreenElement && document.fullScreenElement !== null) ||
(!document.mozFullScreen && !document.webkitIsFullScreen)) {
if (element.requestFullScreen) {
element.requestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullScreen) {
/*global Element */
element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
}
function multiAddEventListener(object, event_names, listener) {
event_names.forEach(function (event_name) {
object.addEventListener(event_name, listener); // XXX don't use addEventListener!
});
}
function multiRemoveEventListener(object, event_names, listener) {
event_names.forEach(function (event_name) {
object.removeEventListener(event_name, listener); // XXX don't use removeEventListener!
});
}
function gadgetRequestFullScreen(gadget) {
var cm = gadget.props.editor, event_names = ["webkitfullscreenchange", "mozfullscreenchange", "fullscreenchange"];
requestFullScreen(cm.getWrapperElement());
multiAddEventListener(document, event_names, function listener() {
multiRemoveEventListener(document, event_names, listener);
cm.setOption("fullScreen", true);
multiAddEventListener(document, event_names, function listener2() {
multiRemoveEventListener(document, event_names, listener2);
cm.setOption("fullScreen", false);
});
});
}
function gadgetRequestMaximize(gadget) { // put to a declared method ? (maximize)
return gadget.requestMaximize()
.push(function (accepted) {
if (accepted) {
if (gadget.props.maximizeButton) { // XXX display button on maximized ?
gadget.props.maximizeButton.textContent = "Unmaximize";
}
gadget.props.maximized = true;
gadget.props.editor.getWrapperElement().style.height = "100%";
gadget.props.editor.refresh();
}
});
}
function gadgetLeaveMaximize(gadget) { // put to a declared method ? (unmaximize)
return gadget.leaveMaximize()
.push(function (accepted) {
if (accepted) {
if (gadget.props.maximizeButton) { // XXX display button on maximized ?
gadget.props.maximizeButton.textContent = "Maximize";
}
gadget.props.maximized = false;
gadget.props.editor.getWrapperElement().style.height = "";
gadget.props.editor.refresh();
}
});
}
function cmFoldAtCursor(cm) {
cm.foldCode(cm.getCursor());
}
rJS(window)
//.declareAcquiredMethod("submitData", "triggerSubmit")
.declareAcquiredMethod("requestMaximize", "requestMaximize")
.declareAcquiredMethod("leaveMaximize", "leaveMaximize")
.ready(function (g) {
g.props = {};
g.options = null;
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
.declareMethod('render', function (options) {
var event_list = [], submit_data_deferred = RSVP.defer();
this.props.key = options.key;
this.props.value = options.value || "";
this.props.editable = options.editable === undefined ? true : options.editable;
if (this.props.editable) {
this.props.textarea = document.createElement("textarea");
this.props.textarea.value = this.props.value;
this.props.maximizeButton = document.createElement("button");
this.props.maximizeButton.textContent = "Maximize";
this.props.fullScreenButton = document.createElement("button");
this.props.fullScreenButton.textContent = "Fullscreen";
this.props.element.appendChild(this.props.maximizeButton);
this.props.element.appendChild(this.props.fullScreenButton);
this.props.element.appendChild(this.props.textarea);
this.props.editor = CodeMirror.fromTextArea(
this.props.textarea,
{
lineNumbers: true,
matchBrackets: true,
showCursorWhenSelecting: true,
autofocus: false,
indentWithTabs: false,
fullScreen: false,
extraKeys: {
"Ctrl-Space": "autocomplete",
"Ctrl-Q": cmFoldAtCursor,
"Ctrl-S": function (cm) {
this.submitData().push(null, submit_data_deferred.reject);
}.bind(this)
}
}
);
event_list.push(submit_data_deferred.promise);
event_list.push(loopEventListener(this.props.element, "keyup", false, function (event) {
if (this.props.maximized && event.keyCode === 27) {
event.preventDefault();
return gadgetLeaveMaximize(this);
}
}.bind(this), false));
event_list.push(loopEventListener(this.props.maximizeButton, "click", false, function (event) {
this.props.editor.focus();
if (this.props.maximized) { // XXX display button on maximized ?
return gadgetLeaveMaximize(this);
}
return gadgetRequestMaximize(this);
}.bind(this)));
event_list.push(loopEventListener(this.props.fullScreenButton, "click", false, function (event) {
this.props.editor.focus();
return gadgetRequestFullScreen(this);
}.bind(this)));
} else {
this.props.pre = document.createElement("pre");
this.props.pre.textContent = this.props.value;
this.props.element.appendChild(this.props.pre);
}
return RSVP.all([event_list]);
})
.declareMethod('getContent', function () {
var form_data = {};
if (this.props.editable) {
form_data[this.props.key] = this.props.editor.getValue();
} else {
form_data[this.props.key] = this.props.value;
}
return form_data;
});
}(window, rJS, CodeMirror, RSVP));//, loopEventListener));
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