diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 71b6faae..244c1f0d 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -55,203 +55,18 @@ var Editor = require("ace/editor").Editor; var MultiSelect = require("ace/multi_select").MultiSelect; // workers do not work for file: -if (location.protocol == "file:") - EditSession.prototype.$useWorker = false; +/* if (location.protocol == "file:") + EditSession.prototype.$useWorker = false; */ -/************** modes ***********************/ -var modes = []; -function getModeFromPath(path) { - var mode = modesByName.text; - for (var i = 0; i < modes.length; i++) { - if (modes[i].supportsFile(path)) { - mode = modes[i]; - break; - } - } - return mode; -}; - -var Mode = function(name, desc, extensions) { - this.name = name; - this.desc = desc; - this.mode = "ace/mode/" + name; - this.extRe = new RegExp("^.*\\.(" + extensions + ")$", "g"); -}; - -Mode.prototype.supportsFile = function(filename) { - return filename.match(this.extRe); -}; - -var modesByName = { - c9search: ["C9Search" , "c9search_results"], - coffee: ["CoffeeScript" , "coffee|^Cakefile"], - coldfusion: ["ColdFusion" , "cfm"], - csharp: ["C#" , "cs"], - css: ["CSS" , "css"], - diff: ["Diff" , "diff|patch"], - glsl: ["Glsl" , "glsl|frag|vert"], - golang: ["Go" , "go"], - groovy: ["Groovy" , "groovy"], - haxe: ["haXe" , "hx"], - html: ["HTML" , "htm|html|xhtml"], - c_cpp: ["C/C++" , "c|cc|cpp|cxx|h|hh|hpp"], - clojure: ["Clojure" , "clj"], - jade: ["Jade" , "jade"], - java: ["Java" , "java"], - jsp: ["JSP" , "jsp"], - javascript: ["JavaScript" , "js"], - json: ["JSON" , "json"], - jsx: ["JSX" , "jsx"], - latex: ["LaTeX" , "latex|tex|ltx|bib"], - less: ["LESS" , "less"], - liquid: ["Liquid" , "liquid"], - lua: ["Lua" , "lua"], - luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates - markdown: ["Markdown" , "md|markdown"], - ocaml: ["OCaml" , "ml|mli"], - perl: ["Perl" , "pl|pm"], - pgsql: ["pgSQL" , "pgsql"], - php: ["PHP" , "php|phtml"], - powershell: ["Powershell" , "ps1"], - python: ["Python" , "py"], - ruby: ["Ruby" , "ru|gemspec|rake|rb"], - scad: ["OpenSCAD" , "scad"], - scala: ["Scala" , "scala"], - scss: ["SCSS" , "scss|sass"], - sh: ["SH" , "sh|bash|bat"], - sql: ["SQL" , "sql"], - svg: ["SVG" , "svg"], - tcl: ["Tcl" , "tcl"], - text: ["Text" , "txt"], - textile: ["Textile" , "textile"], - xml: ["XML" , "xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"], - xquery: ["XQuery" , "xq"], - yaml: ["YAML" , "yaml"] -}; - -for (var name in modesByName) { - var mode = modesByName[name]; - mode = new Mode(name, mode[0], mode[1]) - modesByName[name] = mode; - modes.push(mode); -} - - -/*********** demo documents ***************************/ -var fileCache = {}; - -function initDoc(file, path, doc) { - if (doc.prepare) - file = doc.prepare(file); - - var session = new EditSession(file); - session.setUndoManager(new UndoManager()); - doc.session = session; - doc.path = path; - if (doc.wrapped) { - session.setUseWrapMode(true); - session.setWrapLimitRange(80, 80); - } - var mode = getModeFromPath(path) - session.modeName = mode.name; - session.setMode(mode.mode); -} - - -function makeHuge(txt) { - for (var i = 0; i < 5; i++) - txt += txt; - return txt -} - -var docs = { - "docs/javascript.js": "JavaScript", - "docs/clojure.clj": "Clojure", - "docs/coffeescript.coffee": "Coffeescript", - "docs/coldfusion.cfm": "ColdFusion", - "docs/cpp.cpp": "C/C++", - "docs/csharp.cs": "C#", - "docs/css.css": "CSS", - "docs/diff.diff": "Diff", - "docs/glsl.glsl": "Glsl", - "docs/golang.go": "Go", - "docs/groovy.groovy": "Groovy", - "docs/Haxe.hx": "haXe", - "docs/html.html": "HTML", - "docs/jade.jade": "Jade", - "docs/java.java": "Java", - "docs/jsp.jsp": "JSP", - "docs/json.json": "JSON", - "docs/jsx.jsx": "JSX", - "docs/latex.tex": {name: "LaTeX", wrapped: true}, - "docs/less.less": "LESS", - "docs/liquid.liquid": "Liquid", - "docs/lua.lua": "Lua", - "docs/luapage.lp": "LuaPage", - "docs/markdown.md": {name: "Markdown", wrapped: true}, - "docs/ocaml.ml": "OCaml", - "docs/OpenSCAD.scad": "OpenSCAD", - "docs/perl.pl": "Perl", - "docs/pgsql.pgsql": {name: "pgSQL", wrapped: true}, - "docs/php.php": "PHP", - "docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true}, - "docs/powershell.ps1": "Powershell", - "docs/python.py": "Python", - "docs/ruby.rb": "Ruby", - "docs/scala.scala": "Scala", - "docs/scss.scss": "SCSS", - "docs/sh.sh": "SH", - "docs/sql.sql": {name: "SQL", wrapped: true}, - "docs/svg.svg": "SVG", - "docs/tcl.tcl": "Tcl", - "docs/textile.textile": {name: "Textile", wrapped: true}, - "docs/xml.xml": "XML", - "docs/xquery.xq": "XQuery", - "docs/yaml.yaml": "YAML", - "docs/c9search.c9search_results": "C9 Search Results" -} - -var ownSource = { - /* filled from require*/ -}; - -var hugeDocs = { - "build/src/ace.js": "", - "build/src-min/ace.js": "" -}; - -if (window.require && window.require.s) try { - for (var path in window.require.s.contexts._.loaded) { - if (path.indexOf("!") != -1) - path = path.split("!").pop(); - else - path = path + ".js"; - ownSource[path] = "" - } -} catch(e) {} - -function prepareDocList(docs) { - var list = [] - for (var path in docs) { - var doc = docs[path]; - if (typeof doc != "object") - doc = {name: doc || path}; - - doc.path = path; - doc.desc = doc.name.replace(/^(ace|docs|demo|build)\//, ""); - if (doc.desc.length > 18) - doc.desc = doc.desc.slice(0, 7) + ".." + doc.desc.slice(-9) - - fileCache[doc.name] = doc; - list.push(doc); - }; - - return list; -} - -docs = prepareDocList(docs); -ownSource = prepareDocList(ownSource); -hugeDocs = prepareDocList(hugeDocs); +var doclist = require("./doclist"); +var modelist = require("./modelist"); +var layout = require("./layout"); +var Autocompleter = require("./autocompleter").Autocompleter; +var util = require("./util"); +var saveOption = util.saveOption; +var fillDropdown = util.fillDropdown; +var bindCheckbox = util.bindCheckbox +var bindDropdown = util.bindDropdown; /*********** create editor ***************************/ var container = document.getElementById("editor"); @@ -269,6 +84,9 @@ window.env = env; window.ace = env.editor; env.editor.setAnimatedScroll(true); +// add multiple cursor support to editor +require("ace/multi_select").MultiSelect(env.editor); + var consoleEl = dom.createElement("div"); container.parentNode.appendChild(consoleEl); consoleEl.style.position="fixed" @@ -277,7 +95,7 @@ consoleEl.style.right = 0 consoleEl.style.background = "white" consoleEl.style.border = "1px solid #baf" consoleEl.style.zIndex = "100" -var cmdLine = new singleLineEditor(consoleEl); +var cmdLine = new layout.singleLineEditor(consoleEl); cmdLine.editor = env.editor; env.editor.cmdLine = cmdLine; @@ -314,6 +132,18 @@ env.editor.commands.addCommands([{ bindKey: "shift-esc", exec: function(editor, needle) { editor.cmdLine.focus(); }, readOnly: true +}, { + name: "execute", + bindKey: "ctrl+enter", + exec: function(editor) { + try{ + var r = eval(editor.getCopyText()||editor.getValue()) + }catch(e){ + r = e + } + editor.cmdLine.setValue(r + "") + }, + readOnly: true }]) cmdLine.commands.bindKeys({ @@ -358,12 +188,12 @@ var keybindings = { /*********** manage layout ***************************/ -var consoleHight = 20; +var consoleHeight = 20; 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 - consoleHight + "px"; + container.style.height = document.documentElement.clientHeight - consoleHeight + "px"; env.split.resize(); consoleEl.style.width = width + "px"; @@ -392,52 +222,33 @@ var behavioursEl = document.getElementById("enable_behaviours"); var group = document.createElement("optgroup"); group.setAttribute("label", "Mode Examples"); -fillDropdown(docs, group); +fillDropdown(group, doclist.docs); docEl.appendChild(group); var group = document.createElement("optgroup"); group.setAttribute("label", "Huge documents"); -fillDropdown(hugeDocs, group); +fillDropdown(group, doclist.hugeDocs); docEl.appendChild(group); var group = document.createElement("optgroup"); group.setAttribute("label", "own source"); -fillDropdown(ownSource, group); +fillDropdown(group, doclist.ownSource); docEl.appendChild(group); -fillDropdown(modes, modeEl); - +fillDropdown(modeEl, modelist.modes); +var modesByName = modelist.modesByName; bindDropdown("mode", function(value) { - env.editor.getSession().setMode(modesByName[value].mode || modesByName.text.mode); - env.editor.getSession().modeName = value; + env.editor.session.setMode(modesByName[value].mode || modesByName.text.mode); + env.editor.session.modeName = value; }); bindDropdown("doc", function(name) { - var doc = fileCache[name]; - if (!doc) - return; - - if (doc.session) - return setSession(doc.session) - - //@todo do something while waiting - // env.editor.setSession(emptySession || (emptySession = new EditSession(""))) - var path = doc.path; - var parts = path.split("/"); - if (parts[0] == "docs") - path = "demo/kitchen-sink/" + path; - else if (parts[0] == "ace") - path = "lib/" + path; - - net.get(path, function(x) { - initDoc(x, path, doc); - setSession(doc.session) - }) - - function setSession(session) { + doclist.loadDoc(name, function(session) { + if (!session) + return; var session = env.split.setSession(session); updateUIEditorOptions(); env.editor.focus(); - } + }); }); function updateUIEditorOptions() { @@ -463,24 +274,6 @@ function updateUIEditorOptions() { 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) @@ -514,33 +307,28 @@ bindDropdown("fontsize", function(value) { }); bindDropdown("folding", function(value) { - env.editor.getSession().setFoldStyle(value); + env.editor.session.setFoldStyle(value); env.editor.setShowFoldWidgets(value !== "manual"); }); bindDropdown("soft_wrap", function(value) { - var session = env.editor.getSession(); + var session = env.editor.session; 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; + default: + session.setUseWrapMode(true); + var col = parseInt(value, 10); + session.setWrapLimitRange(col, col); + renderer.setPrintMarginColumn(col); } }); @@ -581,7 +369,7 @@ bindCheckbox("animate_scroll", function(checked) { }); bindCheckbox("soft_tab", function(checked) { - env.editor.getSession().setUseSoftTabs(checked); + env.editor.session.setUseSoftTabs(checked); }); bindCheckbox("enable_behaviours", function(checked) { @@ -617,42 +405,6 @@ bindDropdown("split", function(value) { } }); -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 fillDropdown(list, el) { - list.forEach(function(item) { - var option = document.createElement("option"); - option.setAttribute("value", item.name); - option.innerHTML = item.desc; - el.appendChild(option); - }); -} - /************** dragover ***************************/ event.addListener(container, "dragover", function(e) { @@ -681,96 +433,10 @@ event.addListener(container, "drop", function(e) { } }); -// add multiple cursor support to editor -require("ace/multi_select").MultiSelect(env.editor); - -function singleLineEditor(el) { - var renderer = new Renderer(el); - renderer.scrollBar.element.style.display = "none"; - renderer.scrollBar.width = 0; - renderer.content.style.height = "auto"; - - renderer.screenToTextCoordinates = function(x, y) { - var pos = this.pixelToScreenCoordinates(x, y); - return this.session.screenToDocumentPosition( - Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)), - Math.max(pos.column, 0) - ); - }; - // todo size change event - renderer.$computeLayerConfig = function() { - var longestLine = this.$getLongestLine(); - var firstRow = 0; - var lastRow = this.session.getLength(); - var height = this.session.getScreenLength() * this.lineHeight; - - this.scrollTop = 0; - var config = this.layerConfig; - config.width = longestLine; - config.padding = this.$padding; - config.firstRow = 0; - config.firstRowScreen = 0; - config.lastRow = lastRow; - config.lineHeight = this.lineHeight; - config.characterWidth = this.characterWidth; - config.minHeight = height; - config.maxHeight = height; - config.offset = 0; - config.height = height; - - this.$gutterLayer.element.style.marginTop = 0 + "px"; - this.content.style.marginTop = 0 + "px"; - this.content.style.width = longestLine + 2 * this.$padding + "px"; - this.content.style.height = height + "px"; - this.scroller.style.height = height + "px"; - this.container.style.height = height + "px"; - }; - renderer.isScrollableBy=function(){return false}; - - var editor = new Editor(renderer); - new MultiSelect(editor); - editor.session.setUndoManager(new UndoManager()); - - editor.setHighlightActiveLine(false); - editor.setShowPrintMargin(false); - editor.renderer.setShowGutter(false); - editor.renderer.setHighlightGutterLine(false); - return editor; -}; - - -/** simple statusbar **/ -var editor = env.editor; -var statusBarEl = dom.createElement("div"); -statusBarEl.style.cssText = "color:gray;position:absolute;right:0;border-left:1px solid"; -cmdLine.container.appendChild(statusBarEl); -var statusUpdate = lang.deferredCall(function() { - var status = []; - function add(s, sep) {s && status.push(s, sep || "|")} - if (editor.$vimModeHandler) - add(editor.$vimModeHandler.getStatusText()); - else if (editor.commands.recording) - add("REC"); - - var c = editor.selection.lead; - add(c.row + ":" + c.column, " "); - if (!editor.selection.isEmpty()) { - var r = editor.getSelectionRange() - add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")"); - } - status.pop(); - statusBarEl.textContent = status.join(""); -}); - -env.editor.on("changeStatus", function() { - statusUpdate.schedule(50); -}); -env.editor.on("changeSelection", function() { - statusUpdate.schedule(50); -}); - +var StatusBar = require("./statusbar").StatusBar; +new StatusBar(env.editor, cmdLine.container); }); diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js new file mode 100644 index 00000000..cba77bbb --- /dev/null +++ b/demo/kitchen-sink/doclist.js @@ -0,0 +1,183 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + + define(function(require, exports, module) { +"use strict"; + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; +var net = require("ace/lib/net"); + +var modelist = require("./modelist"); +/*********** demo documents ***************************/ +var fileCache = {}; + +function initDoc(file, path, doc) { + if (doc.prepare) + file = doc.prepare(file); + + var session = new EditSession(file); + session.setUndoManager(new UndoManager()); + doc.session = session; + doc.path = path; + if (doc.wrapped) { + session.setUseWrapMode(true); + session.setWrapLimitRange(80, 80); + } + var mode = modelist.getModeFromPath(path) + session.modeName = mode.name; + session.setMode(mode.mode); +} + + +function makeHuge(txt) { + for (var i = 0; i < 5; i++) + txt += txt; + return txt +} + +var docs = { + "docs/javascript.js": "JavaScript", + "docs/clojure.clj": "Clojure", + "docs/coffeescript.coffee": "Coffeescript", + "docs/coldfusion.cfm": "ColdFusion", + "docs/cpp.cpp": "C/C++", + "docs/csharp.cs": "C#", + "docs/css.css": "CSS", + "docs/diff.diff": "Diff", + "docs/glsl.glsl": "Glsl", + "docs/golang.go": "Go", + "docs/groovy.groovy": "Groovy", + "docs/Haxe.hx": "haXe", + "docs/html.html": "HTML", + "docs/jade.jade": "Jade", + "docs/java.java": "Java", + "docs/jsp.jsp": "JSP", + "docs/json.json": "JSON", + "docs/jsx.jsx": "JSX", + "docs/latex.tex": {name: "LaTeX", wrapped: true}, + "docs/less.less": "LESS", + "docs/liquid.liquid": "Liquid", + "docs/lua.lua": "Lua", + "docs/luapage.lp": "LuaPage", + "docs/markdown.md": {name: "Markdown", wrapped: true}, + "docs/ocaml.ml": "OCaml", + "docs/OpenSCAD.scad": "OpenSCAD", + "docs/perl.pl": "Perl", + "docs/pgsql.pgsql": {name: "pgSQL", wrapped: true}, + "docs/php.php": "PHP", + "docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true}, + "docs/powershell.ps1": "Powershell", + "docs/python.py": "Python", + "docs/ruby.rb": "Ruby", + "docs/scala.scala": "Scala", + "docs/scss.scss": "SCSS", + "docs/sh.sh": "SH", + "docs/sql.sql": {name: "SQL", wrapped: true}, + "docs/svg.svg": "SVG", + "docs/tcl.tcl": "Tcl", + "docs/textile.textile": {name: "Textile", wrapped: true}, + "docs/xml.xml": "XML", + "docs/xquery.xq": "XQuery", + "docs/yaml.yaml": "YAML", + "docs/c9search.c9search_results": "C9 Search Results" +} + +var ownSource = { + /* filled from require*/ +}; + +var hugeDocs = { + "build/src/ace.js": "", + "build/src-min/ace.js": "" +}; + +if (window.require && window.require.s) try { + for (var path in window.require.s.contexts._.defined) { + if (path.indexOf("!") != -1) + path = path.split("!").pop(); + else + path = path + ".js"; + ownSource[path] = "" + } +} catch(e) {} + +function prepareDocList(docs) { + var list = [] + for (var path in docs) { + var doc = docs[path]; + if (typeof doc != "object") + doc = {name: doc || path}; + + doc.path = path; + doc.desc = doc.name.replace(/^(ace|docs|demo|build)\//, ""); + if (doc.desc.length > 18) + doc.desc = doc.desc.slice(0, 7) + ".." + doc.desc.slice(-9) + + fileCache[doc.name] = doc; + list.push(doc); + }; + + return list; +} + +function loadDoc(name, callback) { + var doc = fileCache[name]; + if (!doc) + return callback(null); + + if (doc.session) + return callback(doc.session) + + // TODO: show load screen while waiting + var path = doc.path; + var parts = path.split("/"); + if (parts[0] == "docs") + path = "demo/kitchen-sink/" + path; + else if (parts[0] == "ace") + path = "lib/" + path; + + net.get(path, function(x) { + initDoc(x, path, doc); + callback(doc.session) + }); +} + +module.exports = { + fileCache: fileCache, + docs: prepareDocList(docs), + ownSource: prepareDocList(ownSource), + hugeDocs: prepareDocList(hugeDocs), + initDoc: initDoc, + loadDoc: loadDoc +}; + +}); + diff --git a/demo/kitchen-sink/layout.js b/demo/kitchen-sink/layout.js new file mode 100644 index 00000000..619e8fdb --- /dev/null +++ b/demo/kitchen-sink/layout.js @@ -0,0 +1,194 @@ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("ace/lib/dom"); +var event = require("ace/lib/event"); + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; +var Renderer = require("ace/virtual_renderer").VirtualRenderer; +var Editor = require("ace/editor").Editor; +var MultiSelect = require("ace/multi_select").MultiSelect; + +dom.importCssString("\ +splitter {\ + border: 1px solid #C6C6D2;\ + width: 0px;\ + cursor: ew-resize;\ + z-index:10}\ +splitter:hover {\ + margin-left: -2px;\ + width:3px;\ + border-color: #B5B4E0;\ +}\ +", "splitEditor") + +exports.edit = function(el) { + if (typeof(el) == "string") + el = document.getElementById(el); + + var editor = new Editor(new Renderer(el, require("ace/theme/textmate"))); + + editor.resize(); + event.addListener(window, "resize", function() { + editor.resize(); + }); + return editor; +}; + + +var SplitRoot = function(el, theme, position, getSize) { + el.style.position = position || "relative"; + this.container = el + this.getSize = getSize || this.getSize + this.resize = this.$resize.bind(this) + + event.addListener(el.ownerDocument.defaultView, "resize", this.resize); + this.editor = this.createEditor() +}; + +(function(){ + this.createEditor = function() { + var el = document.createElement("div"); + el.className = this.$editorCSS; + el.style.cssText = "position: absolute; top:0px; bottom:0px"; + this.$container.appendChild(el); + var session = new EditSession(""); + var editor = new Editor(new Renderer(el, this.$theme)); + + /*editor.on("focus", function() { + this._emit("focus", editor); + }.bind(this));*/ + + this.$editors.push(editor); + editor.setFontSize(this.$fontSize); + return editor; + }; + this.$resize = function() { + var size = this.getSize(this.container); + this.rect = { + x: size.left, + y: size.top, + w: size.width, + h: size.height, + } + this.item.resize(this.rect) + }; + this.getSize = function(el) { + return el.getBoundingClientRect() + }; + this.destroy = function() { + var win = this.container.ownerDocument.defaultView; + event.removeListener(win, "resize", this.resize); + }; + + +}).call(SplitRoot.prototype); + + + +var Split = function(){ + +}; +(function(){ + this.execute = function(options) { + this.$u.execute(options); + }; + +}).call(Split.prototype); + + + +exports.singleLineEditor = function(el) { + var renderer = new Renderer(el); + el.style.overflow = "hidden"; + renderer.scrollBar.element.style.top = "0"; + renderer.scrollBar.element.style.display = "none"; + renderer.scrollBar.orginalWidth = renderer.scrollBar.width; + renderer.scrollBar.width = 0; + renderer.content.style.height = "auto"; + + renderer.screenToTextCoordinates = function(x, y) { + var pos = this.pixelToScreenCoordinates(x, y); + return this.session.screenToDocumentPosition( + Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)), + Math.max(pos.column, 0) + ); + }; + + renderer.maxLines = 4; + renderer.$computeLayerConfigWithScroll = renderer.$computeLayerConfig; + renderer.$computeLayerConfig = function() { + var config = this.layerConfig; + var height = this.session.getScreenLength() * this.lineHeight; + if (config.height != height) { + var vScroll = height > this.maxLines * this.lineHeight; + + if (vScroll != this.$vScroll) { + if (vScroll) { + this.scrollBar.element.style.display = ""; + this.scrollBar.width = this.scrollBar.orginalWidth; + this.container.style.height = config.height + "px"; + height = config.height; + this.scrollTop = height - this.maxLines * this.lineHeight; + } else { + this.scrollBar.element.style.display = "none"; + this.scrollBar.width = 0; + } + + this.onResize(); + this.$vScroll = vScroll; + } + + if (this.$vScroll) + return renderer.$computeLayerConfigWithScroll(); + + this.container.style.height = height + "px"; + this.scroller.style.height = height + "px"; + this.content.style.height = height + "px"; + this._emit("resize"); + } + + var longestLine = this.$getLongestLine(); + var firstRow = 0; + var lastRow = this.session.getLength(); + + this.scrollTop = 0; + config.width = longestLine; + config.padding = this.$padding; + config.firstRow = 0; + config.firstRowScreen = 0; + config.lastRow = lastRow; + config.lineHeight = this.lineHeight; + config.characterWidth = this.characterWidth; + config.minHeight = height; + config.maxHeight = height; + config.offset = 0; + config.height = height; + + this.$gutterLayer.element.style.marginTop = 0 + "px"; + this.content.style.marginTop = 0 + "px"; + this.content.style.width = longestLine + 2 * this.$padding + "px"; + }; + renderer.isScrollableBy=function(){return false}; + + renderer.setStyle("ace_one-line"); + var editor = new Editor(renderer); + new MultiSelect(editor); + editor.session.setUndoManager(new UndoManager()); + + editor.setHighlightActiveLine(false); + editor.setShowPrintMargin(false); + editor.renderer.setShowGutter(false); + editor.renderer.setHighlightGutterLine(false); + + editor.$mouseHandler.$focusWaitTimout = 0; + + return editor; +} + + + +}); + diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js new file mode 100644 index 00000000..3c6307a9 --- /dev/null +++ b/demo/kitchen-sink/modelist.js @@ -0,0 +1,89 @@ +define(function(require, exports, module) { +"use strict"; + +/************** modes ***********************/ +var modes = []; +function getModeFromPath(path) { + var mode = modesByName.text; + for (var i = 0; i < modes.length; i++) { + if (modes[i].supportsFile(path)) { + mode = modes[i]; + break; + } + } + return mode; +}; + +var Mode = function(name, desc, extensions) { + this.name = name; + this.desc = desc; + this.mode = "ace/mode/" + name; + this.extRe = new RegExp("^.*\\.(" + extensions + ")$", "g"); +}; + +Mode.prototype.supportsFile = function(filename) { + return filename.match(this.extRe); +}; + +var modesByName = { + c9search: ["C9Search" , "c9search_results"], + coffee: ["CoffeeScript" , "coffee|^Cakefile"], + coldfusion: ["ColdFusion" , "cfm"], + csharp: ["C#" , "cs"], + css: ["CSS" , "css"], + diff: ["Diff" , "diff|patch"], + glsl: ["Glsl" , "glsl|frag|vert"], + golang: ["Go" , "go"], + groovy: ["Groovy" , "groovy"], + haxe: ["haXe" , "hx"], + html: ["HTML" , "htm|html|xhtml"], + c_cpp: ["C/C++" , "c|cc|cpp|cxx|h|hh|hpp"], + clojure: ["Clojure" , "clj"], + jade: ["Jade" , "jade"], + java: ["Java" , "java"], + jsp: ["JSP" , "jsp"], + javascript: ["JavaScript" , "js"], + json: ["JSON" , "json"], + jsx: ["JSX" , "jsx"], + latex: ["LaTeX" , "latex|tex|ltx|bib"], + less: ["LESS" , "less"], + liquid: ["Liquid" , "liquid"], + lua: ["Lua" , "lua"], + luapage: ["LuaPage" , "lp"], // http://keplerproject.github.com/cgilua/manual.html#templates + markdown: ["Markdown" , "md|markdown"], + ocaml: ["OCaml" , "ml|mli"], + perl: ["Perl" , "pl|pm"], + pgsql: ["pgSQL" , "pgsql"], + php: ["PHP" , "php|phtml"], + powershell: ["Powershell" , "ps1"], + python: ["Python" , "py"], + ruby: ["Ruby" , "ru|gemspec|rake|rb"], + scad: ["OpenSCAD" , "scad"], + scala: ["Scala" , "scala"], + scss: ["SCSS" , "scss|sass"], + sh: ["SH" , "sh|bash|bat"], + sql: ["SQL" , "sql"], + svg: ["SVG" , "svg"], + tcl: ["Tcl" , "tcl"], + text: ["Text" , "txt"], + textile: ["Textile" , "textile"], + xml: ["XML" , "xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"], + xquery: ["XQuery" , "xq"], + yaml: ["YAML" , "yaml"] +}; + +for (var name in modesByName) { + var mode = modesByName[name]; + mode = new Mode(name, mode[0], mode[1]) + modesByName[name] = mode; + modes.push(mode); +} + +module.exports = { + getModeFromPath: getModeFromPath, + modes: modes, + modesByName: modesByName +} + +}); + diff --git a/demo/kitchen-sink/statusbar.js b/demo/kitchen-sink/statusbar.js new file mode 100644 index 00000000..5d89bda1 --- /dev/null +++ b/demo/kitchen-sink/statusbar.js @@ -0,0 +1,48 @@ +define(function(require, exports, module) { +"use strict"; +/** simple statusbar **/ +var dom = require("ace/lib/dom"); +var lang = require("ace/lib/lang"); + +var StatusBar = function(editor, parentNode) { + this.element = dom.createElement("div"); + this.element.style.cssText = "color: gray; position:absolute; right:0; border-left:1px solid"; + parentNode.appendChild(this.element); + + var statusUpdate = lang.deferredCall(function(){ + this.updateStatus(editor) + }.bind(this)); + editor.on("changeStatus", function() { + statusUpdate.schedule(50); + }); + editor.on("changeSelection", function() { + statusUpdate.schedule(50); + }); +}; + +(function(){ + this.updateStatus = function(editor) { + var status = []; + function add(str, separator) { + str && status.push(str, separator || "|") + } + + if (editor.$vimModeHandler) + add(editor.$vimModeHandler.getStatusText()); + else if (editor.commands.recording) + add("REC"); + + var c = editor.selection.lead; + add(c.row + ":" + c.column, " "); + if (!editor.selection.isEmpty()) { + var r = editor.getSelectionRange() + add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")"); + } + status.pop(); + this.element.textContent = status.join(""); + } +}).call(StatusBar.prototype) + +exports.StatusBar = StatusBar; + +}) \ No newline at end of file diff --git a/demo/kitchen-sink/util.js b/demo/kitchen-sink/util.js new file mode 100644 index 00000000..fcc34ef7 --- /dev/null +++ b/demo/kitchen-sink/util.js @@ -0,0 +1,192 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("ace/lib/dom"); +var event = require("ace/lib/event"); + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; +var Renderer = require("ace/virtual_renderer").VirtualRenderer; +var Editor = require("ace/editor").Editor; +var MultiSelect = require("ace/multi_select").MultiSelect; + +exports.createSplitEditor = function(el) { + if (typeof(el) == "string") + el = document.getElementById(el); + + var e0 = document.createElement("div"); + var s = document.createElement("splitter"); + var e1 = document.createElement("div"); + el.appendChild(e0) + el.appendChild(e1) + el.appendChild(s) + e0.style.position = e1.style.position = s.style.position = "absolute"; + el.style.position = "relative" + var split = {$container: el}; + + split.editor0 = split[0] = new Editor(new Renderer(e0, require("ace/theme/textmate"))); + split.editor1 = split[1] = new Editor(new Renderer(e1, require("ace/theme/textmate"))); + split.splitter = s + + MultiSelect(split.editor0); + MultiSelect(split.editor1); + + s.ratio = 0.5 + + split.resize = function resize(){ + var height = el.parentNode.clientHeight - el.offsetTop; + var total = el.clientWidth; + var w1 = total * s.ratio + var w2 = total * (1- s.ratio) + s.style.left = w1 - 1 + "px"; + s.style.height = el.style.height = height + "px"; + + var st0 = split[0].container.style + var st1 = split[1].container.style + st0.width = w1 + "px"; + st1.width = w2 + "px"; + st0.left = 0 + "px"; + st1.left = w1 + "px"; + + st0.top = st1.top = "0px"; + st0.height = st1.height = height + "px"; + + split[0].resize(); + split[1].resize(); + } + + split.onMouseDown = function(e) { + var rect = el.getBoundingClientRect() + var x = e.clientX; + var y = e.clientY; + + var button = e.button; + if (button !== 0) { + return; + } + + var onMouseMove = function(e) { + x = e.clientX; + y = e.clientY; + }; + var onResizeEnd = function(e) { + clearInterval(timerId); + }; + + var onResizeInterval = function() { + s.ratio = (x - rect.left) / rect.width + split.resize() + }; + + event.capture(s, onMouseMove, onResizeEnd); + var timerId = setInterval(onResizeInterval, 40); + + return e.preventDefault(); + }; + + + + event.addListener(s, "mousedown", split.onMouseDown); + event.addListener(window, "resize", split.resize); + split.resize() + return split; +} + +/***************************/ +exports.stripLeadingComments = function(str) { + if(str.slice(0,2)=='/*'){ + var j = str.indexOf('*/')+2 + str = str.substr(j) + } + return str.trim() + "\n" +}; + +/***************************/ +exports.saveOption = function(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); + } +} + +exports.bindCheckbox = function(id, callback, noInit) { + var el = document.getElementById(id); + if (localStorage && localStorage.getItem(id)) + el.checked = localStorage.getItem(id) == "1"; + + var onCheck = function() { + callback(!!el.checked); + exports.saveOption(el); + }; + el.onclick = onCheck; + noInit || onCheck(); +} + +exports.bindDropdown = function(id, callback, noInit) { + var el = document.getElementById(id); + if (localStorage && localStorage.getItem(id)) + el.value = localStorage.getItem(id); + + var onChange = function() { + callback(el.value); + exports.saveOption(el); + }; + + el.onchange = onChange; + noInit || onChange(); +}; + +exports.fillDropdown = function(el, list) { + if (typeof el == "string") + el = document.getElementById(el); + list.forEach(function(item) { + var option = document.createElement("option"); + option.setAttribute("value", item.name); + option.innerHTML = item.desc; + el.appendChild(option); + }); +}; + +}); +