add simple page for live editing highlighters
This commit is contained in:
parent
5630688576
commit
854f21595b
5 changed files with 422 additions and 186 deletions
|
|
@ -151,6 +151,12 @@ exports.saveOption = function(el, val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.bindCheckbox = function(id, callback, noInit) {
|
exports.bindCheckbox = function(id, callback, noInit) {
|
||||||
|
if (typeof id == "string")
|
||||||
|
var el = document.getElementById(id);
|
||||||
|
else {
|
||||||
|
var el = id;
|
||||||
|
id = el.id;
|
||||||
|
}
|
||||||
var el = document.getElementById(id);
|
var el = document.getElementById(id);
|
||||||
if (localStorage && localStorage.getItem(id))
|
if (localStorage && localStorage.getItem(id))
|
||||||
el.checked = localStorage.getItem(id) == "1";
|
el.checked = localStorage.getItem(id) == "1";
|
||||||
|
|
@ -164,7 +170,12 @@ exports.bindCheckbox = function(id, callback, noInit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.bindDropdown = function(id, callback, noInit) {
|
exports.bindDropdown = function(id, callback, noInit) {
|
||||||
var el = document.getElementById(id);
|
if (typeof id == "string")
|
||||||
|
var el = document.getElementById(id);
|
||||||
|
else {
|
||||||
|
var el = id;
|
||||||
|
id = el.id;
|
||||||
|
}
|
||||||
if (localStorage && localStorage.getItem(id))
|
if (localStorage && localStorage.getItem(id))
|
||||||
el.value = localStorage.getItem(id);
|
el.value = localStorage.getItem(id);
|
||||||
|
|
||||||
|
|
@ -190,7 +201,7 @@ function elt(tag, attributes, content) {
|
||||||
var el = dom.createElement(tag);
|
var el = dom.createElement(tag);
|
||||||
if (typeof content == "string") {
|
if (typeof content == "string") {
|
||||||
el.textContent = content;
|
el.textContent = content;
|
||||||
} else {
|
} else if (content) {
|
||||||
content.forEach(function(ch) {
|
content.forEach(function(ch) {
|
||||||
el.appendChild(ch);
|
el.appendChild(ch);
|
||||||
});
|
});
|
||||||
|
|
@ -203,6 +214,8 @@ function elt(tag, attributes, content) {
|
||||||
|
|
||||||
function optgroup(values) {
|
function optgroup(values) {
|
||||||
return values.map(function(item) {
|
return values.map(function(item) {
|
||||||
|
if (typeof item == "string")
|
||||||
|
item = {name: item, desc: item};
|
||||||
return elt("option", {value: item.name}, item.desc);
|
return elt("option", {value: item.name}, item.desc);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
205
lib/ace/tokenizer_dev.js
Normal file
205
lib/ace/tokenizer_dev.js
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
/* ***** 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) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* version of Tokenizer with additional logging
|
||||||
|
* and infinite loop checks
|
||||||
|
* can be used for developing/testing new modes
|
||||||
|
**/
|
||||||
|
var Tokenizer = function(rules, flag) {
|
||||||
|
flag = flag ? "g" + flag : "g";
|
||||||
|
this.rules = rules;
|
||||||
|
|
||||||
|
this.regExps = {};
|
||||||
|
this.matchMappings = {};
|
||||||
|
for ( var key in this.rules) {
|
||||||
|
var rule = this.rules[key];
|
||||||
|
var state = rule;
|
||||||
|
var ruleRegExps = [];
|
||||||
|
var matchTotal = 0;
|
||||||
|
var mapping = this.matchMappings[key] = {};
|
||||||
|
|
||||||
|
for ( var i = 0; i < state.length; i++) {
|
||||||
|
|
||||||
|
if (state[i].regex instanceof RegExp)
|
||||||
|
state[i].regex = state[i].regex.toString().slice(1, -1);
|
||||||
|
|
||||||
|
// Count number of matching groups. 2 extra groups from the full match
|
||||||
|
// And the catch-all on the end (used to force a match);
|
||||||
|
var matchcount = new RegExp("(?:(" + state[i].regex + ")|(.))").exec("a").length - 2;
|
||||||
|
|
||||||
|
// Replace any backreferences and offset appropriately.
|
||||||
|
var adjustedregex = state[i].regex.replace(/\\([0-9]+)/g, function (match, digit) {
|
||||||
|
return "\\" + (parseInt(digit, 10) + matchTotal + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchcount > 1 && state[i].token.length !== matchcount-1)
|
||||||
|
throw new Error("For " + state[i].regex + " the matching groups and length of the token array don't match (rule #" + i + " of state " + key + ")");
|
||||||
|
|
||||||
|
mapping[matchTotal] = {
|
||||||
|
rule: i,
|
||||||
|
len: matchcount
|
||||||
|
};
|
||||||
|
matchTotal += matchcount;
|
||||||
|
|
||||||
|
ruleRegExps.push(adjustedregex);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + ")|(.))", flag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
this.getLineTokens = function(line, startState) {
|
||||||
|
var currentState = startState || "start";
|
||||||
|
var state = this.rules[currentState];
|
||||||
|
var mapping = this.matchMappings[currentState];
|
||||||
|
var re = this.regExps[currentState];
|
||||||
|
re.lastIndex = 0;
|
||||||
|
|
||||||
|
var match, tokens = [];
|
||||||
|
|
||||||
|
var lastIndex = 0;
|
||||||
|
|
||||||
|
var stateTransitions = [];
|
||||||
|
function onStateChange() {
|
||||||
|
stateTransitions.push(startState+"@"+lastIndex);
|
||||||
|
}
|
||||||
|
function initState() {
|
||||||
|
onStateChange();
|
||||||
|
stateTransitions = [];
|
||||||
|
onStateChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
var token = {
|
||||||
|
type: null,
|
||||||
|
value: "",
|
||||||
|
state: currentState,
|
||||||
|
};
|
||||||
|
initState();
|
||||||
|
|
||||||
|
var maxRecur = 10000;
|
||||||
|
|
||||||
|
while (match = re.exec(line)) {
|
||||||
|
var type = "default.text";
|
||||||
|
var rule = null;
|
||||||
|
var value = [match[0]];
|
||||||
|
|
||||||
|
for (var i = 0; i < match.length-2; i++) {
|
||||||
|
if (match[i + 1] === undefined)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!maxRecur--) {
|
||||||
|
throw "infinite" + mapping[i].rule + currentState
|
||||||
|
}
|
||||||
|
|
||||||
|
rule = state[mapping[i].rule];
|
||||||
|
|
||||||
|
if (mapping[i].len > 1)
|
||||||
|
value = match.slice(i+2, i+1+mapping[i].len);
|
||||||
|
|
||||||
|
// compute token type
|
||||||
|
if (typeof rule.token == "function")
|
||||||
|
type = rule.token.apply(this, value);
|
||||||
|
else
|
||||||
|
type = rule.token;
|
||||||
|
|
||||||
|
if (rule.next) {
|
||||||
|
currentState = rule.next;
|
||||||
|
state = this.rules[currentState];
|
||||||
|
mapping = this.matchMappings[currentState];
|
||||||
|
lastIndex = re.lastIndex;
|
||||||
|
|
||||||
|
re = this.regExps[currentState];
|
||||||
|
|
||||||
|
if (re === undefined) {
|
||||||
|
throw new Error("You indicated a state of " + rule.next + " to go to, but it doesn't exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
re.lastIndex = lastIndex;
|
||||||
|
|
||||||
|
onStateChange();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value[0]) {
|
||||||
|
if (typeof type == "string") {
|
||||||
|
value = [value.join("")];
|
||||||
|
type = [type];
|
||||||
|
}
|
||||||
|
for (var i = 0; i < value.length; i++) {
|
||||||
|
if (!value[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var mergeable = (!rule || rule.merge || type[i] === "text") && token.type === type[i];
|
||||||
|
|
||||||
|
if (false && mergeable) {
|
||||||
|
token.value += value[i];
|
||||||
|
} else {
|
||||||
|
if (token.type) {
|
||||||
|
token.stateTransitions = stateTransitions;
|
||||||
|
tokens.push(token);
|
||||||
|
initState()
|
||||||
|
}
|
||||||
|
|
||||||
|
token = {
|
||||||
|
type: type[i],
|
||||||
|
value: value[i],
|
||||||
|
state: currentState,
|
||||||
|
mergeable: mergeable
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastIndex == line.length)
|
||||||
|
break;
|
||||||
|
|
||||||
|
lastIndex = re.lastIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.type) {
|
||||||
|
token.stateTransitions = stateTransitions;
|
||||||
|
tokens.push(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
tokens : tokens,
|
||||||
|
state : currentState
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(Tokenizer.prototype);
|
||||||
|
|
||||||
|
exports.Tokenizer = Tokenizer;
|
||||||
|
});
|
||||||
64
tool/mode_creator.html
Normal file
64
tool/mode_creator.html
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<base href="../">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>Ace Mode Creator</title>
|
||||||
|
<meta name="author" content="Harutyun Amirjanyan">
|
||||||
|
<style type="text/css" >
|
||||||
|
body, html {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
border-bottom: solid 1px;
|
||||||
|
}
|
||||||
|
.separator-h {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="header">
|
||||||
|
<label for="modeEl">mode</label>
|
||||||
|
<select id="modeEl" size="1"></select>
|
||||||
|
<span id="tablist"></span>
|
||||||
|
<span class="separator-h"></span>
|
||||||
|
<label for="autorunEl">live preview</label>
|
||||||
|
<input type="checkbox" label="autorun" id="autorunEl" checked>
|
||||||
|
|
||||||
|
|
||||||
|
<div style='float:right'>
|
||||||
|
<label for="themeEl">Theme</label>
|
||||||
|
<select id="themeEl" size="1" value="textmate"></select>
|
||||||
|
<span class="separator-h"></span>
|
||||||
|
<label for="doc">Document</label>
|
||||||
|
<select id="doc" size="1"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="editor"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var require = {
|
||||||
|
baseUrl: window.location.protocol + "//" + window.location.host + window.location.pathname.split("/").slice(0, -1).join("/"),
|
||||||
|
paths: {
|
||||||
|
ace: "../lib/ace",
|
||||||
|
demo: "../demo",
|
||||||
|
tool: "../tool"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="./demo/kitchen-sink/require.js" data-main="mode_creator"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
138
tool/mode_creator.js
Normal file
138
tool/mode_creator.js
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
/** creates globals intentionally to make things easily accessible from console **/
|
||||||
|
|
||||||
|
var net = require("ace/lib/net");
|
||||||
|
var Range = require("ace/range").Range;
|
||||||
|
var util = require("demo/kitchen-sink/util");
|
||||||
|
var layout = require("demo/kitchen-sink/layout");
|
||||||
|
var modelist = require("demo/kitchen-sink/modelist");
|
||||||
|
var doclist = require("demo/kitchen-sink/doclist");
|
||||||
|
var TokenTooltip = require("demo/kitchen-sink/token_tooltip").TokenTooltip;
|
||||||
|
|
||||||
|
var EditSession = require("ace/edit_session").EditSession;
|
||||||
|
var UndoManager = require("ace/undomanager").UndoManager;
|
||||||
|
|
||||||
|
var DebugTokenizer = require("ace/tokenizer_dev").Tokenizer;
|
||||||
|
|
||||||
|
// createEditor
|
||||||
|
var splitEditor = window.splitEditor = util.createSplitEditor("editor");
|
||||||
|
|
||||||
|
var editor1 = window.editor1 = splitEditor.editor0;
|
||||||
|
var editor2 = window.editor2 = splitEditor.editor1;
|
||||||
|
new TokenTooltip(editor2);
|
||||||
|
|
||||||
|
timeout = null
|
||||||
|
schedule = function() {
|
||||||
|
if(timeout != null) {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
}
|
||||||
|
timeout = setTimeout(run, 800)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setAutorunEnabled = function(val) {
|
||||||
|
if (val)
|
||||||
|
editor1.on('change', schedule)
|
||||||
|
else
|
||||||
|
editor1.removeEventListener('change', schedule)
|
||||||
|
}
|
||||||
|
|
||||||
|
util.bindCheckbox("autorunEl", setAutorunEnabled)
|
||||||
|
|
||||||
|
|
||||||
|
docEl = document.getElementById("doc")
|
||||||
|
util.fillDropdown(docEl, doclist.docs)
|
||||||
|
util.bindDropdown("doc", function(value) {
|
||||||
|
doclist.loadDoc(value, function(session) {
|
||||||
|
if (session) {
|
||||||
|
editor2.setSession(session)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
modeEl = document.getElementById("modeEl");
|
||||||
|
util.fillDropdown(modeEl, modelist.modes)
|
||||||
|
var modeSessions = {}
|
||||||
|
util.bindDropdown(modeEl, function(value) {
|
||||||
|
if (modeSessions[value])
|
||||||
|
editor1.setSession(modeSessions[value])
|
||||||
|
var hp = "./lib/ace/mode/" + value + "_highlight_rules.js"
|
||||||
|
net.get(hp, function(text) {
|
||||||
|
text = util.stripLeadingComments(text)
|
||||||
|
var desc = value
|
||||||
|
modePath = "ace/mode/" + value
|
||||||
|
|
||||||
|
var session = new EditSession(text)
|
||||||
|
session.setUndoManager(new UndoManager())
|
||||||
|
modeSessions[value] = session;
|
||||||
|
session.setMode("ace/mode/javascript")
|
||||||
|
|
||||||
|
editor1.setSession(modeSessions[value])
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
util.fillDropdown("themeEl", {
|
||||||
|
bright: [
|
||||||
|
"chrome", "clouds", "crimson_editor", "dawn", "dreamweaver", "eclipse", "github",
|
||||||
|
"solarized_light", "textmate", "tomorrow", "xcode"],
|
||||||
|
dark: [ "clouds_midnight", "cobalt", "idle_fingers", "kr_theme", "merbivore", "merbivore_soft",
|
||||||
|
"mono_industrial", "monokai", "pastel_on_dark", "solarized_dark", "tomorrow_night",
|
||||||
|
"tomorrow_night_blue", "tomorrow_night_bright", "tomorrow_night_eighties", "twilight", "vibrant_ink"]
|
||||||
|
})
|
||||||
|
|
||||||
|
util.bindDropdown("themeEl", function(value) {
|
||||||
|
if (!value)
|
||||||
|
return;
|
||||||
|
editor1.setTheme("ace/theme/" + value);
|
||||||
|
editor2.setTheme("ace/theme/" + value);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function getDeps(src, path) {
|
||||||
|
var deps = []
|
||||||
|
src.replace(/require\((['"])(.*?)\1/g, function(a,b,c){
|
||||||
|
if (c[0] == ".") {
|
||||||
|
var base = path.split("/")
|
||||||
|
c.split("/").forEach(function(part) {
|
||||||
|
if (part == ".") {
|
||||||
|
base.pop()
|
||||||
|
} else if (part == "..") {
|
||||||
|
base.pop();
|
||||||
|
base.pop()
|
||||||
|
} else {
|
||||||
|
base.push(part)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
c = base.join("/")
|
||||||
|
}
|
||||||
|
deps.push('"' + c + '"')
|
||||||
|
})
|
||||||
|
|
||||||
|
return deps
|
||||||
|
}
|
||||||
|
function run() {
|
||||||
|
var src = editor1.getValue();
|
||||||
|
var path = "ace/mode/new";
|
||||||
|
var deps = getDeps(src, path)
|
||||||
|
src = src.replace("define(", 'define("' + path +'", ["require","exports","module",' + deps +'],');
|
||||||
|
src += ';require(["ace/mode/new"], continueRun, function(e){console.log(e);require.undef("ace/mode/new")})'
|
||||||
|
try {
|
||||||
|
eval(src)
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var continueRun = function(rules) {
|
||||||
|
rules = rules[Object.keys(rules)[0]]
|
||||||
|
var Tokenizer = DebugTokenizer
|
||||||
|
|
||||||
|
var tk = new Tokenizer(new rules().getRules())
|
||||||
|
editor2.session.bgTokenizer.setTokenizer(tk)
|
||||||
|
editor2.renderer.updateText()
|
||||||
|
}
|
||||||
|
|
||||||
|
editor1.commands.bindKey("ctrl-Return", run)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
||||||
<title>Editor</title>
|
|
||||||
<style type="text/css" media="screen">
|
|
||||||
body {
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editor {
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="toolbar"></div>
|
|
||||||
<pre id="editor"></pre>
|
|
||||||
|
|
||||||
<script src="../build/src/ace.js" type="text/javascript"></script>
|
|
||||||
<script src="../build/kitchen-sink/demo.js" type="text/javascript"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var $ = document.getElementById.bind(document);
|
|
||||||
function bindDropdown(el, callback) {
|
|
||||||
var onChange = function() {
|
|
||||||
callback(el.value);
|
|
||||||
};
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/************** 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"],
|
|
||||||
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"],
|
|
||||||
java: ["Java" , "java"],
|
|
||||||
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"],
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var container = document.getElementById("editor");
|
|
||||||
container.style.position = "absolute";
|
|
||||||
// Splitting.
|
|
||||||
var Split = require("ace/split").Split;
|
|
||||||
var split = new Split(container, null, 1);
|
|
||||||
split.setOrientation(split.BESIDE);
|
|
||||||
split.setSplits(2);
|
|
||||||
|
|
||||||
var editor1 = split.getEditor(0);
|
|
||||||
var editor2 = split.getEditor(1);
|
|
||||||
|
|
||||||
var toolbar = $("toolbar");
|
|
||||||
var modeEl = document.createElement("select");
|
|
||||||
fillDropdown(modes, modeEl);
|
|
||||||
|
|
||||||
bindDropdown(modeEl, function(value) {
|
|
||||||
editor1.session.setMode((modesByName[value] || modesByName.text).mode);
|
|
||||||
});
|
|
||||||
toolbar.appendChild(modeEl);
|
|
||||||
var button = document.createElement("input");
|
|
||||||
button.setAttribute("type", "button");
|
|
||||||
button.value = "generate test";
|
|
||||||
toolbar.appendChild(button)
|
|
||||||
|
|
||||||
function onResize() {
|
|
||||||
var top = toolbar.clientHeight;
|
|
||||||
var width = document.documentElement.clientWidth;
|
|
||||||
container.style.top = top + "px";
|
|
||||||
container.style.width = width + "px";
|
|
||||||
container.style.height = document.documentElement.clientHeight - top + "px";
|
|
||||||
split.resize();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onresize = onResize;
|
|
||||||
onResize();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
button.onclick = function() {
|
|
||||||
var s = editor1.session
|
|
||||||
tok = s.bgTokenizer
|
|
||||||
var data = []
|
|
||||||
for (var i = 0; i < s.getLength(); i++) {
|
|
||||||
data.push({
|
|
||||||
text: s.getLine(i),
|
|
||||||
state: [tok.getState(i - 1), tok.getState(i)],
|
|
||||||
tokens: tok.getTokens(i)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
data = JSON.stringify(data, null, 4);
|
|
||||||
data = data.replace(/(\n\s*)"(\w+)":/g, "$1$2:");
|
|
||||||
editor2.insert(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue