/* (C) 2014 Michael Murtaugh and Active Archives contributors This software is part of Active Archives http://activearchives.org/ Released under a GPL3 license. Please include this message when redistributing. Requires: Ace */ function aa_aceeditor (ace) { ace = ace || window.ace; var factory = {name: 'aceeditor'}, sessionsByHref = {}, modelist = ace.require("ace/ext/modelist"); factory.get_session = function (href) { return sessionsByHref[href]; } // editor.get_element () factory.get_editor = function () { var editor = { factory: factory }, tokenclicks, current_href, highlightLineStart, highlightLineEnd, _save, _reload; editor.elt = document.createElement("div"); var root = d3.select(editor.elt) .attr("class", "editor"), body = root.append("div") .attr("class", "editorbody"), foot = root.append("div") .attr("class", "editorfoot"); editor.aceeditor = ace.edit(body[0][0]); editor.save = function (callback) { _save = callback; } editor.reload = function (callback) { _reload = callback; } // a bit of a brutal solution but... $(document).bind("resize", function (e) { // console.log("ace.resize"); editor.aceeditor.resize(); }); // MODE SELECTOR var modeselector = foot .append("select") .attr("class", "editormode"); modeselector .on("change", function () { // console.log("change", this, this.value); editor.aceeditor.getSession().setMode(this.value); }) .selectAll("option") .data(modelist.modes) .enter() .append("option") .attr("value", function (d) { return d.mode; }) .text(function (d) { return d.caption; }); var save = foot .append("button") .text("save") .on("click", function () { var text = editor.aceeditor.getValue(); if (_save) { _save.call(editor, { text: text, href: current_href }); } }); var reload = foot .append("button") .text("reload") .on("click", function () { var text; if (_reload) { text = editor.aceeditor.getValue(); _reload.call(editor, { text: text, href: current_href }); } else { editor.href(current_href, null, true); aceeditor.focus(); } }); function highlight(s, e) { var session = editor.aceeditor.getSession(); if (highlightLineStart) { for (var i=(highlightLineStart-1); i<=(highlightLineEnd-1); i++) { session.removeGutterDecoration(i, 'ace_gutter_active_annotation'); } } highlightLineStart = s; highlightLineEnd = e; if (highlightLineStart) { for (var i=(highlightLineStart-1); i<=(highlightLineEnd-1); i++) { session.addGutterDecoration(i, 'ace_gutter_active_annotation'); } editor.aceeditor.scrollToLine(highlightLineStart, true, true); } } editor.href = function (href, done, forceReload) { if (arguments.length == 0) { var ret = current_href; if (highlightLineStart) { ret = aa.lineRangeHref(current_href, highlightLineStart, highlightLineEnd); } return ret; } var href = aa.href(href), session = sessionsByHref[href.nofrag]; current_href = href.nofrag; if (session == "loading") { return false; } // todo, improve this.. now commented out to force reload if (!forceReload && (session != undefined)) { if (done) { window.setTimeout(function () { done.call(session); }, 0); } editor.aceeditor.setSession(session.acesession); // deal with eventual changed fragment if (href.lineStart) { highlight(href.lineStart, href.lineEnd); $(editor.elt).trigger("fragmentupdate", {editor: editor}); } return true; } sessionsByHref[href.nofrag] = "loading"; $.ajax({ url: href.nofrag, data: { f: (new Date()).getTime() }, success: function (data) { // console.log("got data", data); var mode = modelist.getModeForPath(href.nofrag).mode || "ace/mode/text", session = { href: href.nofrag, editor: editor }; session.acesession = ace.createEditSession(data, mode); // index(href.nofrag, data); modeselector[0][0].value = mode; editor.aceeditor.setSession(session.acesession); // editor.setOption("showLineNumbers", false); editor.aceeditor.setHighlightActiveLine(false); session.acesession.setUseWrapMode(true); sessionsByHref[href.nofrag] = session; if (done) { window.setTimeout(function () { done.call(session); }, 0); } }, error: function (code) { console.log("aceeditor: error loading", href.nofrag, code); } }); } var observed_href = null; $(document).on("fragmentupdate", function (e, data) { if ((e.target !== editor.elt) && data.editor) { observed_href = data.editor.href(); // console.log("ace.fragmentupdate", e.target, observed_href); } }); editor.newSession = function () { var session = ace.createEditSession("", "ace/mode/srt-md"); editor.aceeditor.setSession(session); } function bind_keys (e) { return; /* e.commands.addCommand({ name: 'pasteTimecode', bindKey: {win: 'ctrl-shift-down', mac: 'command-shift-down'}, exec: function () { if (observed_href) { var href = aa.href(observed_href), mode = editor.aceeditor.getSession().getMode().$id, link; // console.log("pasteTimecode", mode); if (mode == "ace/mode/srtmd") { link = aa.secondsToTimecode(href.start)+" -->\n"; } else if (mode == "ace/mode/markdown") { link = "["+href.basename+"]("+href.href+")"; } else { link = href.href; } editor.aceeditor.insert(link); } }, readOnly: false }); */ } bind_keys(editor.aceeditor); return editor; }; return factory; };