/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Skywriter. * * The Initial Developer of the Original Code is * Mozilla. * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Fabian Jakobs * Kevin Dangoor (kdangoor@mozilla.com) * Julian Viereck * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { "use strict"; require("ace/lib/fixoldbrowsers"); require("ace/config").init(); var env = {}; var event = require("ace/lib/event"); var theme = require("ace/theme/textmate"); var EditSession = require("ace/edit_session").EditSession; var UndoManager = require("ace/undomanager").UndoManager; var vim = require("ace/keyboard/keybinding/vim").Vim; var emacs = require("ace/keyboard/keybinding/emacs").Emacs; var HashHandler = require("ace/keyboard/hash_handler").HashHandler; var modesByName; // workers do not work for file: if (location.protocol == "file:") EditSession.prototype.$useWorker = false; var Doc = function(name, desc, file) { this.name = name; this.desc = desc; this.doc = new EditSession(file); this.doc.modeName = name; this.doc.setUndoManager(new UndoManager()); }; var WrappedDoc = function(name, desc, file) { Doc.apply(this, arguments); this.doc.setUseWrapMode(true); this.doc.setWrapLimitRange(80, 80); }; var Mode = function(name, desc, extensions) { this.name = name; this.desc = desc; this.mode = "ace/mode/" + name; this.extRe = new RegExp("^.*\\.(" + extensions.join("|") + ")$", "g"); }; Mode.prototype.supportsFile = function(filename) { return filename.match(this.extRe); }; var modes = [ new Mode("c_cpp", "C/C++", ["c", "cpp", "cxx", "h", "hpp"]), new Mode("clojure", "Clojure", ["clj"]), new Mode("coffee", "CoffeeScript", ["coffee"]), new Mode("coldfusion", "ColdFusion", ["cfm"]), new Mode("csharp", "C#", ["cs"]), new Mode("css", "CSS", ["css"]), new Mode("golang", "Go", ["go"]), new Mode("groovy", "Groovy", ["groovy"]), new Mode("haxe", "haXe", ["hx"]), new Mode("html", "HTML", ["html", "htm"]), new Mode("java", "Java", ["java"]), new Mode("javascript", "JavaScript", ["js"]), new Mode("json", "JSON", ["json"]), new Mode("latex", "LaTeX", ["tex"]), new Mode("less", "LESS", ["less"]), new Mode("lua", "Lua", ["lua"]), new Mode("liquid", "Liquid", ["liquid"]), new Mode("markdown", "Markdown", ["md", "markdown"]), new Mode("ocaml", "OCaml", ["ml", "mli"]), new Mode("perl", "Perl", ["pl", "pm"]), new Mode("pgsql", "pgSQL", ["pgsql", "sql"]), new Mode("php", "PHP", ["php"]), new Mode("powershell", "Powershell", ["ps1"]), new Mode("python", "Python", ["py"]), new Mode("scala", "Scala", ["scala"]), new Mode("scss", "SCSS", ["scss"]), new Mode("ruby", "Ruby", ["rb"]), new Mode("sql", "SQL", ["sql"]), new Mode("svg", "SVG", ["svg"]), new Mode("text", "Text", ["txt"]), new Mode("textile", "Textile", ["textile"]), new Mode("xml", "XML", ["xml"]), new Mode("sh", "SH", ["sh"]), new Mode("xquery", "XQuery", ["xq"]) ]; modesByName = {}; modes.forEach(function(m) { modesByName[m.name] = m; }); var loreIpsum = require("ace/requirejs/text!./docs/plaintext.txt"); for (var i = 0; i < 5; i++) { loreIpsum += loreIpsum; } var docs = [ new Doc( "javascript", "JavaScript", require("ace/requirejs/text!./docs/javascript.js") ), new WrappedDoc("text", "Plain Text", loreIpsum), new Doc( "coffee", "Coffeescript", require("ace/requirejs/text!./docs/coffeescript.coffee") ), new Doc( "json", "JSON", require("ace/requirejs/text!./docs/json.json") ), new Doc( "css", "CSS", require("ace/requirejs/text!./docs/css.css") ), new Doc( "scss", "SCSS", require("ace/requirejs/text!./docs/scss.scss") ), new Doc( "less", "LESS", require("ace/requirejs/text!./docs/less.less") ), new Doc( "html", "HTML", require("ace/requirejs/text!./docs/html.html") ), new Doc( "xml", "XML", require("ace/requirejs/text!./docs/xml.xml") ), new Doc( "svg", "SVG", require("ace/requirejs/text!./docs/svg.svg") ), new Doc( "php", "PHP", require("ace/requirejs/text!./docs/php.php") ), new Doc( "coldfusion", "ColdFusion", require("ace/requirejs/text!./docs/coldfusion.cfm") ), new Doc( "python", "Python", require("ace/requirejs/text!./docs/python.py") ), new Doc( "ruby", "Ruby", require("ace/requirejs/text!./docs/ruby.rb") ), new Doc( "perl", "Perl", require("ace/requirejs/text!./docs/perl.pl") ), new Doc( "ocaml", "OCaml", require("ace/requirejs/text!./docs/ocaml.ml") ), new Doc( "lua", "Lua", require("ace/requirejs/text!./docs/lua.lua") ), new Doc( "liquid", "Liquid", require("ace/requirejs/text!./docs/liquid.liquid") ), new Doc( "java", "Java", require("ace/requirejs/text!./docs/java.java") ), new Doc( "clojure", "Clojure", require("ace/requirejs/text!./docs/clojure.clj") ), new Doc( "groovy", "Groovy", require("ace/requirejs/text!./docs/groovy.groovy") ), new Doc( "scala", "Scala", require("ace/requirejs/text!./docs/scala.scala") ), new Doc( "csharp", "C#", require("ace/requirejs/text!./docs/csharp.cs") ), new Doc( "powershell", "Powershell", require("ace/requirejs/text!./docs/powershell.ps1") ), new Doc( "c_cpp", "C/C++", require("ace/requirejs/text!./docs/cpp.cpp") ), new Doc( "haxe", "haXe", require("ace/requirejs/text!./docs/Haxe.hx") ), new Doc( "sh", "SH", require("ace/requirejs/text!./docs/sh.sh") ), new Doc( "xquery", "XQuery", require("ace/requirejs/text!./docs/xquery.xq") ), new WrappedDoc( "markdown", "Markdown", require("ace/requirejs/text!./docs/markdown.md") ), new WrappedDoc( "textile", "Textile", require("ace/requirejs/text!./docs/textile.textile") ), new WrappedDoc( "latex", "LaTeX", require("ace/requirejs/text!./docs/latex.tex") ), new WrappedDoc( "sql", "SQL", require("ace/requirejs/text!./docs/sql.sql") ), new WrappedDoc( "pgsql", "pgSQL", require("ace/requirejs/text!./docs/pgsql.pgsql") ), new Doc( "golang", "Go", require("ace/requirejs/text!./docs/golang.go") ) ]; var docsByName = {}; docs.forEach(function(d) { docsByName[d.name] = d; }); var keybindings = { // Null = use "default" keymapping ace: null, vim: vim, emacs: emacs, // This is a way to define simple keyboard remappings custom: new HashHandler({ "gotoright": "Tab", "indent": "]", "outdent": "[", "gotolinestart": "^", "gotolineend": "$" }) }; var container = document.getElementById("editor"); // Splitting. var Split = require("ace/split").Split; var split = new Split(container, theme, 1); env.editor = split.getEditor(0); split.on("focus", function(editor) { env.editor = editor; updateUIEditorOptions(); }); env.split = split; window.env = env; window.editor = window.ace = env.editor; env.editor.setAnimatedScroll(true); var docEl = document.getElementById("doc"); var modeEl = document.getElementById("mode"); var wrapModeEl = document.getElementById("soft_wrap"); var themeEl = document.getElementById("theme"); var foldingEl = document.getElementById("folding"); var selectStyleEl = document.getElementById("select_style"); var highlightActiveEl = document.getElementById("highlight_active"); var showHiddenEl = document.getElementById("show_hidden"); var showGutterEl = document.getElementById("show_gutter"); var showPrintMarginEl = document.getElementById("show_print_margin"); var highlightSelectedWordE = document.getElementById("highlight_selected_word"); var showHScrollEl = document.getElementById("show_hscroll"); var animateScrollEl = document.getElementById("animate_scroll"); var softTabEl = document.getElementById("soft_tab"); var behavioursEl = document.getElementById("enable_behaviours"); docs.forEach(function(doc) { var option = document.createElement("option"); option.setAttribute("value", doc.name); option.innerHTML = doc.desc; docEl.appendChild(option); }); modes.forEach(function(mode) { var option = document.createElement("option"); option.setAttribute("value", mode.name); option.innerHTML = mode.desc; modeEl.appendChild(option); }); bindDropdown("mode", function(value) { env.editor.getSession().setMode(modesByName[value].mode || modesByName.text.mode); env.editor.getSession().modeName = value; }); bindDropdown("doc", function(value) { var doc = docsByName[value].doc; if (!docsByName[value].initialized) { docsByName[value].initialized = true; doc.setMode(modesByName[docsByName[value].name].mode); } var session = env.split.setSession(doc); session.name = doc.name; updateUIEditorOptions(); env.editor.focus(); }); function updateUIEditorOptions() { var editor = env.editor; var session = editor.session; session.setFoldStyle(foldingEl.value); saveOption(docEl, session.name); saveOption(modeEl, session.modeName || "text"); saveOption(wrapModeEl, session.getUseWrapMode() ? session.getWrapLimitRange().min || "free" : "off"); saveOption(selectStyleEl, editor.getSelectionStyle() == "line"); saveOption(themeEl, editor.getTheme()); saveOption(highlightActiveEl, editor.getHighlightActiveLine()); saveOption(showHiddenEl, editor.getShowInvisibles()); saveOption(showGutterEl, editor.renderer.getShowGutter()); saveOption(showPrintMarginEl, editor.renderer.getShowPrintMargin()); saveOption(highlightSelectedWordE, editor.getHighlightSelectedWord()); saveOption(showHScrollEl, editor.renderer.getHScrollBarAlwaysVisible()); saveOption(animateScrollEl, editor.getAnimatedScroll()); saveOption(softTabEl, session.getUseSoftTabs()); saveOption(behavioursEl, editor.getBehavioursEnabled()); } function saveOption(el, val) { if (!el.onchange || el.onclick) return; if ("checked" in el) { if (val !== undefined) el.checked = val; localStorage && localStorage.setItem(el.id, el.checked ? 1 : 0); } else { if (val !== undefined) el.value = val; localStorage && localStorage.setItem(el.id, el.value); } } event.addListener(themeEl, "mouseover", function(e){ this.desiredValue = e.target.value; if (!this.$timer) this.$timer = setTimeout(this.updateTheme); }) event.addListener(themeEl, "mouseout", function(e){ this.desiredValue = null; if (!this.$timer) this.$timer = setTimeout(this.updateTheme, 20); }) themeEl.updateTheme = function(){ env.split.setTheme(themeEl.desiredValue || themeEl.selectedValue); themeEl.$timer = null; } bindDropdown("theme", function(value) { if (!value) return; env.editor.setTheme(value); themeEl.selectedValue = value; }); bindDropdown("keybinding", function(value) { env.editor.setKeyboardHandler(keybindings[value]); }); bindDropdown("fontsize", function(value) { env.split.setFontSize(value); }); bindDropdown("folding", function(value) { env.editor.getSession().setFoldStyle(value); env.editor.setShowFoldWidgets(value !== "manual"); }); bindDropdown("soft_wrap", function(value) { var session = env.editor.getSession(); var renderer = env.editor.renderer; switch (value) { case "off": session.setUseWrapMode(false); renderer.setPrintMarginColumn(80); break; case "40": session.setUseWrapMode(true); session.setWrapLimitRange(40, 40); renderer.setPrintMarginColumn(40); break; case "80": session.setUseWrapMode(true); session.setWrapLimitRange(80, 80); renderer.setPrintMarginColumn(80); break; case "free": session.setUseWrapMode(true); session.setWrapLimitRange(null, null); renderer.setPrintMarginColumn(80); break; } }); bindCheckbox("select_style", function(checked) { env.editor.setSelectionStyle(checked ? "line" : "text"); }); bindCheckbox("highlight_active", function(checked) { env.editor.setHighlightActiveLine(checked); }); bindCheckbox("show_hidden", function(checked) { env.editor.setShowInvisibles(checked); }); bindCheckbox("show_gutter", function(checked) { env.editor.renderer.setShowGutter(checked); }); bindCheckbox("show_print_margin", function(checked) { env.editor.renderer.setShowPrintMargin(checked); }); bindCheckbox("highlight_selected_word", function(checked) { env.editor.setHighlightSelectedWord(checked); }); bindCheckbox("show_hscroll", function(checked) { env.editor.renderer.setHScrollBarAlwaysVisible(checked); }); bindCheckbox("animate_scroll", function(checked) { env.editor.setAnimatedScroll(checked); }); bindCheckbox("soft_tab", function(checked) { env.editor.getSession().setUseSoftTabs(checked); }); bindCheckbox("enable_behaviours", function(checked) { env.editor.setBehavioursEnabled(checked); }); bindCheckbox("fade_fold_widgets", function(checked) { env.editor.setFadeFoldWidgets(checked); }); var secondSession = null; bindDropdown("split", function(value) { var sp = env.split; if (value == "none") { if (sp.getSplits() == 2) { secondSession = sp.getEditor(1).session; } sp.setSplits(1); } else { var newEditor = (sp.getSplits() == 1); if (value == "below") { sp.setOrientation(sp.BELOW); } else { sp.setOrientation(sp.BESIDE); } sp.setSplits(2); if (newEditor) { var session = secondSession || sp.getEditor(0).session; var newSession = sp.setSession(session, 1); newSession.name = session.name; } } }); function bindCheckbox(id, callback) { var el = document.getElementById(id); if (localStorage && localStorage.getItem(id)) el.checked = localStorage.getItem(id) == "1"; var onCheck = function() { callback(!!el.checked); saveOption(el); }; el.onclick = onCheck; onCheck(); } function bindDropdown(id, callback) { var el = document.getElementById(id); if (localStorage && localStorage.getItem(id)) el.value = localStorage.getItem(id); var onChange = function() { callback(el.value); saveOption(el); }; el.onchange = onChange; onChange(); } function onResize() { var left = env.split.$container.offsetLeft; var width = document.documentElement.clientWidth - left; container.style.width = width + "px"; container.style.height = document.documentElement.clientHeight + "px"; env.split.resize(); } window.onresize = onResize; env.editor.renderer.onResize(true); event.addListener(container, "dragover", function(e) { return event.preventDefault(e); }); event.addListener(container, "drop", function(e) { var file; try { file = e.dataTransfer.files[0]; } catch(err) { return event.stopEvent(); } if (window.FileReader) { var reader = new FileReader(); reader.onload = function() { env.editor.getSelection().selectAll(); var mode = modesByName.text; for (var i = 0; i < modes.length; i++) { if (modes[i].supportsFile(file.name)) { mode = modes[i]; break; } } env.editor.onTextInput(reader.result); modeEl.value = mode.name; env.editor.getSession().setMode(mode.mode); env.editor.getSession().modeName = mode.name; }; reader.readAsText(file); } return event.preventDefault(e); }); /** * This demonstrates how you can define commands and bind shortcuts to them. */ // Fake-Save, works from the editor and the command line. var commands = env.editor.commands; commands.addCommand({ name: "save", bindKey: { win: "Ctrl-S", mac: "Command-S", sender: "editor" }, exec: function() { alert("Fake Save File"); } }); // Fake-Print with custom lookup-sender-match function. commands.addCommand({ name: "print", bindKey: { win: "Ctrl-P", mac: "Command-P", sender: function(env, sender, hashId, keyString) { if (sender == "editor") { return true; } else { alert("Sorry, can only print from the editor"); } } }, exec: function() { alert("Fake Print File"); } }); // add multiple cursor support to editor require("ace/multi_select").MultiSelect(env.editor); });