Merge remote-tracking branch 'remotes/origin/master'
This commit is contained in:
commit
8c4173ba11
58 changed files with 7233 additions and 923 deletions
|
|
@ -31,13 +31,15 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
var dom = require("ace/lib/dom");
|
var dom = require("ace/lib/dom");
|
||||||
var Range = require("ace/range").Range;
|
var Range = require("ace/range").Range;
|
||||||
// allow easy access to ace in console, but not in ace code which uses strict
|
|
||||||
function isStrict() {
|
|
||||||
try { return !arguments.callee.caller.caller.caller}
|
|
||||||
catch(e){ return true }
|
|
||||||
}
|
|
||||||
function warn() {
|
function warn() {
|
||||||
if (isStrict()) {
|
var s = (new Error()).stack || "";
|
||||||
|
s = s.split("\n");
|
||||||
|
if (s[1] == "Error") s.shift(); // remove error description on chrome
|
||||||
|
s.shift(); // remove warn
|
||||||
|
s.shift(); // remove the getter
|
||||||
|
s = s.join("\n");
|
||||||
|
// allow easy access to ace in console, but not in ace code
|
||||||
|
if (!/at Object.InjectedScript.|@debugger eval|snippets:\/{3}/.test(s)) {
|
||||||
console.error("trying to access to global variable");
|
console.error("trying to access to global variable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,13 +169,44 @@ function loadDoc(name, callback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveDoc(name, callback) {
|
||||||
|
var doc = fileCache[name] || name;
|
||||||
|
if (!doc || !doc.session)
|
||||||
|
return callback("Unknown document: " + name);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
upload(path, doc.session.getValue(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload(url, data, callback) {
|
||||||
|
url = net.qualifyURL(url);
|
||||||
|
if (!/https?:/.test(url))
|
||||||
|
return callback(new Error("Unsupported url scheme"));
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("PUT", url, true);
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
callback(!/^2../.test(xhr.status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
fileCache: fileCache,
|
fileCache: fileCache,
|
||||||
docs: sort(prepareDocList(docs)),
|
docs: sort(prepareDocList(docs)),
|
||||||
ownSource: prepareDocList(ownSource),
|
ownSource: prepareDocList(ownSource),
|
||||||
hugeDocs: prepareDocList(hugeDocs),
|
hugeDocs: prepareDocList(hugeDocs),
|
||||||
initDoc: initDoc,
|
initDoc: initDoc,
|
||||||
loadDoc: loadDoc
|
loadDoc: loadDoc,
|
||||||
|
saveDoc: saveDoc,
|
||||||
};
|
};
|
||||||
module.exports.all = {
|
module.exports.all = {
|
||||||
"Mode Examples": module.exports.docs,
|
"Mode Examples": module.exports.docs,
|
||||||
|
|
|
||||||
171
demo/kitchen-sink/docs/abc.abc
Normal file
171
demo/kitchen-sink/docs/abc.abc
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
%abc-2.1
|
||||||
|
H:This file contains some example English tunes
|
||||||
|
% note that the comments (like this one) are to highlight usages
|
||||||
|
% and would not normally be included in such detail
|
||||||
|
O:England % the origin of all tunes is England
|
||||||
|
|
||||||
|
X:1 % tune no 1
|
||||||
|
T:Dusty Miller, The % title
|
||||||
|
T:Binny's Jig % an alternative title
|
||||||
|
C:Trad. % traditional
|
||||||
|
R:DH % double hornpipe
|
||||||
|
M:3/4 % meter
|
||||||
|
K:G % key
|
||||||
|
B>cd BAG|FA Ac BA|B>cd BAG|DG GB AG:|
|
||||||
|
Bdd gfg|aA Ac BA|Bdd gfa|gG GB AG:|
|
||||||
|
BG G/2G/2G BG|FA Ac BA|BG G/2G/2G BG|DG GB AG:|
|
||||||
|
W:Hey, the dusty miller, and his dusty coat;
|
||||||
|
W:He will win a shilling, or he spend a groat.
|
||||||
|
W:Dusty was the coat, dusty was the colour;
|
||||||
|
W:Dusty was the kiss, that I got frae the miller.
|
||||||
|
|
||||||
|
X:2
|
||||||
|
T:Old Sir Simon the King
|
||||||
|
C:Trad.
|
||||||
|
S:Offord MSS % from Offord manuscript
|
||||||
|
N:see also Playford % reference note
|
||||||
|
M:9/8
|
||||||
|
R:SJ % slip jig
|
||||||
|
N:originally in C % transcription note
|
||||||
|
K:G
|
||||||
|
D|GFG GAG G2D|GFG GAG F2D|EFE EFE EFG|A2G F2E D2:|
|
||||||
|
D|GAG GAB d2D|GAG GAB c2D|[1 EFE EFE EFG|[A2G] F2E D2:|\ % no line-break in score
|
||||||
|
M:12/8 % change of meter
|
||||||
|
[2 E2E EFE E2E EFG|\ % no line-break in score
|
||||||
|
M:9/8 % change of meter
|
||||||
|
A2G F2E D2|]
|
||||||
|
|
||||||
|
X:3
|
||||||
|
T:William and Nancy
|
||||||
|
T:New Mown Hay
|
||||||
|
T:Legacy, The
|
||||||
|
C:Trad.
|
||||||
|
O:England; Gloucs; Bledington % place of origin
|
||||||
|
B:Sussex Tune Book % can be found in these books
|
||||||
|
B:Mally's Cotswold Morris vol.1 2
|
||||||
|
D:Morris On % can be heard on this record
|
||||||
|
P:(AB)2(AC)2A % play the parts in this order
|
||||||
|
M:6/8
|
||||||
|
K:G
|
||||||
|
[P:A] D|"G"G2G GBd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
|
||||||
|
[P:B] d|"G"e2d B2d|"C"gfe "G"d2d| "G"e2d B2d|"C"gfe "D7"d2c|
|
||||||
|
"G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
|
||||||
|
% changes of meter, using inline fields
|
||||||
|
[T:Slows][M:4/4][L:1/4][P:C]"G"d2|"C"e2 "G"d2|B2 d2|"Em"gf "A7"e2|"D7"d2 "G"d2|\
|
||||||
|
"C"e2 "G"d2|[M:3/8][L:1/8] "G"B2 d |[M:6/8] "C"gfe "D7"d2c|
|
||||||
|
"G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
|
||||||
|
|
||||||
|
X:4
|
||||||
|
T:South Downs Jig
|
||||||
|
R:jig
|
||||||
|
S:Robert Harbron
|
||||||
|
M:6/8
|
||||||
|
L:1/8
|
||||||
|
K:G
|
||||||
|
|: d | dcA G3 | EFG AFE | DEF GAB | cde d2d |
|
||||||
|
dcA G3 | EFG AFE | DEF GAB | cAF G2 :|
|
||||||
|
B | Bcd e2c | d2B c2A | Bcd e2c | [M:9/8]d2B c2B A3 |
|
||||||
|
[M:6/8]DGF E3 | cBA FED | DEF GAB |1 cAF G2 :|2 cAF G3 |]
|
||||||
|
|
||||||
|
X:5
|
||||||
|
T:Atholl Brose
|
||||||
|
% in this example, which reproduces Highland Bagpipe gracing,
|
||||||
|
% the large number of grace notes mean that it is more convenient to be specific about
|
||||||
|
% score line-breaks (using the $ symbol), rather than using code line breaks to indicate them
|
||||||
|
I:linebreak $
|
||||||
|
K:D
|
||||||
|
{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
|
||||||
|
{gcd}c<{e}A {gAGAG}A>e {ag}a>f {gef}e>d|
|
||||||
|
{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
|
||||||
|
{g}c/d/e {g}G>{d}B {gf}gG {dc}d>B:|$
|
||||||
|
{g}c<e {gf}g>e {ag}a>e {gf}g>e|
|
||||||
|
{g}c<e {gf}g>e {ag}a2 {GdG}a>d|
|
||||||
|
{g}c<e {gf}g>e {ag}a>e {gf}g>f|
|
||||||
|
{gef}e>d {gf}g>d {gBd}B<{e}G {dc}d>B|
|
||||||
|
{g}c<e {gf}g>e {ag}a>e {gf}g>e|
|
||||||
|
{g}c<e {gf}g>e {ag}a2 {GdG}ad|
|
||||||
|
{g}c<{GdG}e {gf}ga {f}g>e {g}f>d|
|
||||||
|
{g}e/f/g {Gdc}d>c {gBd}B<{e}G {dc}d2|]
|
||||||
|
|
||||||
|
X:6
|
||||||
|
T:Untitled Reel
|
||||||
|
C:Trad.
|
||||||
|
K:D
|
||||||
|
eg|a2ab ageg|agbg agef|g2g2 fgag|f2d2 d2:|\
|
||||||
|
ed|cecA B2ed|cAcA E2ed|cecA B2ed|c2A2 A2:|
|
||||||
|
K:G
|
||||||
|
AB|cdec BcdB|ABAF GFE2|cdec BcdB|c2A2 A2:|
|
||||||
|
|
||||||
|
X:7
|
||||||
|
T:Kitchen Girl
|
||||||
|
C:Trad.
|
||||||
|
K:D
|
||||||
|
[c4a4] [B4g4]|efed c2cd|e2f2 gaba|g2e2 e2fg|
|
||||||
|
a4 g4|efed cdef|g2d2 efed|c2A2 A4:|
|
||||||
|
K:G
|
||||||
|
ABcA BAGB|ABAG EDEG|A2AB c2d2|e3f edcB|ABcA BAGB|
|
||||||
|
ABAG EGAB|cBAc BAG2|A4 A4:|
|
||||||
|
|
||||||
|
%abc-2.1
|
||||||
|
%%pagewidth 21cm
|
||||||
|
%%pageheight 29.7cm
|
||||||
|
%%topspace 0.5cm
|
||||||
|
%%topmargin 1cm
|
||||||
|
%%botmargin 0cm
|
||||||
|
%%leftmargin 1cm
|
||||||
|
%%rightmargin 1cm
|
||||||
|
%%titlespace 0cm
|
||||||
|
%%titlefont Times-Bold 32
|
||||||
|
%%subtitlefont Times-Bold 24
|
||||||
|
%%composerfont Times 16
|
||||||
|
%%vocalfont Times-Roman 14
|
||||||
|
%%staffsep 60pt
|
||||||
|
%%sysstaffsep 20pt
|
||||||
|
%%musicspace 1cm
|
||||||
|
%%vocalspace 5pt
|
||||||
|
%%measurenb 0
|
||||||
|
%%barsperstaff 5
|
||||||
|
%%scale 0.7
|
||||||
|
X: 1
|
||||||
|
T: Canzonetta a tre voci
|
||||||
|
C: Claudio Monteverdi (1567-1643)
|
||||||
|
M: C
|
||||||
|
L: 1/4
|
||||||
|
Q: "Andante mosso" 1/4 = 110
|
||||||
|
%%score [1 2 3]
|
||||||
|
V: 1 clef=treble name="Soprano"sname="A"
|
||||||
|
V: 2 clef=treble name="Alto" sname="T"
|
||||||
|
V: 3 clef=bass middle=d name="Tenor" sname="B"
|
||||||
|
%%MIDI program 1 75 % recorder
|
||||||
|
%%MIDI program 2 75
|
||||||
|
%%MIDI program 3 75
|
||||||
|
K: Eb
|
||||||
|
% 1 - 4
|
||||||
|
[V: 1] |:z4 |z4 |f2ec |_ddcc |
|
||||||
|
w: Son que-sti~i cre-spi cri-ni~e
|
||||||
|
w: Que-sti son gli~oc-chi che mi-
|
||||||
|
[V: 2] |:c2BG|AAGc|(F/G/A/B/)c=A|B2AA |
|
||||||
|
w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e
|
||||||
|
w: Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-
|
||||||
|
[V: 3] |:z4 |f2ec|_ddcf |(B/c/_d/e/)ff|
|
||||||
|
w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il
|
||||||
|
w: Que-sti son~gli oc-chi che mi-ran - - - - do
|
||||||
|
% 5 - 9
|
||||||
|
[V: 1] cAB2 |cAAA |c3B|G2!fermata!Gz ::e4|
|
||||||
|
w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
|
||||||
|
w: ran-do fi-so, tut-to re-stai con-qui-so.
|
||||||
|
[V: 2] AAG2 |AFFF |A3F|=E2!fermata!Ez::c4|
|
||||||
|
w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
|
||||||
|
w: ran-do fi-so tut-to re-stai con-qui-so.
|
||||||
|
[V: 3] (ag/f/e2)|A_ddd|A3B|c2!fermata!cz ::A4|
|
||||||
|
w: vi - - - so ond' io ti-man-go~uc-ci-so. Deh,
|
||||||
|
w: fi - - - so tut-to re-stai con-qui-so.
|
||||||
|
% 10 - 15
|
||||||
|
[V: 1] f_dec |B2c2|zAGF |\
|
||||||
|
w: dim-me-lo ben mi-o, che que-sto\
|
||||||
|
=EFG2 |1F2z2:|2F8|] % more notes
|
||||||
|
w: sol de-si-o_. % more lyrics
|
||||||
|
[V: 2] ABGA |G2AA|GF=EF |(GF3/2=E//D//E)|1F2z2:|2F8|]
|
||||||
|
w: dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_.
|
||||||
|
[V: 3] _dBc>d|e2AF|=EFc_d|c4 |1F2z2:|2F8|]
|
||||||
|
w: dim-me-lo ben mi-o, che que-sto sol de-si-o_.
|
||||||
|
|
@ -20,7 +20,7 @@ class Range
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
{:id => 34, :key => "value"}
|
{:id => ?", :key => "value"}
|
||||||
|
|
||||||
|
|
||||||
herDocs = [<<'FOO', <<BAR, <<-BAZ, <<-`EXEC`] #comment
|
herDocs = [<<'FOO', <<BAR, <<-BAZ, <<-`EXEC`] #comment
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ require("ace/commands/default_commands").commands.push({
|
||||||
// rowCount: rowCount,
|
// rowCount: rowCount,
|
||||||
fixedWidth: true,
|
fixedWidth: true,
|
||||||
el: dom.createElement("div"),
|
el: dom.createElement("div"),
|
||||||
editor: editor
|
editor: inlineEditor
|
||||||
};
|
};
|
||||||
var el = w.el;
|
var el = w.el;
|
||||||
el.appendChild(inlineEditor.container);
|
el.appendChild(inlineEditor.container);
|
||||||
|
|
|
||||||
|
|
@ -196,8 +196,7 @@ console.log(addResult);
|
||||||
<p><span class="expand_arrow">></span> <a href="https://github.com/ajaxorg/ace/tree/master/lib/ace/theme" target="_blank">See all themes</a></p>
|
<p><span class="expand_arrow">></span> <a href="https://github.com/ajaxorg/ace/tree/master/lib/ace/theme" target="_blank">See all themes</a></p>
|
||||||
<h2>Setting the Programming Language Mode</h2>
|
<h2>Setting the Programming Language Mode</h2>
|
||||||
<p>By default, the editor supports plain text mode. All other language modes are available as separate modules, loaded on demand like this:</p>
|
<p>By default, the editor supports plain text mode. All other language modes are available as separate modules, loaded on demand like this:</p>
|
||||||
<pre><code class="javascript">editor.getSession().setMode("ace/mode/javascript");
|
<pre><code class="javascript">editor.getSession().setMode("ace/mode/javascript");</code></pre>
|
||||||
</code></pre>
|
|
||||||
<!--h2>One Editor, Multiple Sessions</h2>
|
<!--h2>One Editor, Multiple Sessions</h2>
|
||||||
<p>Ace keeps everything about the state of the editor (selection, scroll position, etc.)
|
<p>Ace keeps everything about the state of the editor (selection, scroll position, etc.)
|
||||||
in <code class="javascript">editor.session</code>. This means you can grab the
|
in <code class="javascript">editor.session</code>. This means you can grab the
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,10 @@ var dom = require("./lib/dom");
|
||||||
var snippetManager = require("./snippets").snippetManager;
|
var snippetManager = require("./snippets").snippetManager;
|
||||||
|
|
||||||
var Autocomplete = function() {
|
var Autocomplete = function() {
|
||||||
this.autoInsert = true;
|
this.autoInsert = false;
|
||||||
this.autoSelect = true;
|
this.autoSelect = true;
|
||||||
this.exactMatch = false;
|
this.exactMatch = false;
|
||||||
|
this.gatherCompletionsId = 0;
|
||||||
this.keyboardHandler = new HashHandler();
|
this.keyboardHandler = new HashHandler();
|
||||||
this.keyboardHandler.bindKeys(this.commands);
|
this.keyboardHandler.bindKeys(this.commands);
|
||||||
|
|
||||||
|
|
@ -59,7 +60,6 @@ var Autocomplete = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
this.gatherCompletionsId = 0;
|
|
||||||
|
|
||||||
this.$init = function() {
|
this.$init = function() {
|
||||||
this.popup = new AcePopup(document.body || document.documentElement);
|
this.popup = new AcePopup(document.body || document.documentElement);
|
||||||
|
|
@ -84,6 +84,8 @@ var Autocomplete = function() {
|
||||||
|
|
||||||
this.popup.setData(this.completions.filtered);
|
this.popup.setData(this.completions.filtered);
|
||||||
|
|
||||||
|
editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
||||||
|
|
||||||
var renderer = editor.renderer;
|
var renderer = editor.renderer;
|
||||||
this.popup.setRow(this.autoSelect ? 0 : -1);
|
this.popup.setRow(this.autoSelect ? 0 : -1);
|
||||||
if (!keepPopupPosition) {
|
if (!keepPopupPosition) {
|
||||||
|
|
@ -115,10 +117,9 @@ var Autocomplete = function() {
|
||||||
this.changeTimer.cancel();
|
this.changeTimer.cancel();
|
||||||
this.hideDocTooltip();
|
this.hideDocTooltip();
|
||||||
|
|
||||||
if (this.popup && this.popup.isOpen) {
|
|
||||||
this.gatherCompletionsId += 1;
|
this.gatherCompletionsId += 1;
|
||||||
|
if (this.popup && this.popup.isOpen)
|
||||||
this.popup.hide();
|
this.popup.hide();
|
||||||
}
|
|
||||||
|
|
||||||
if (this.base)
|
if (this.base)
|
||||||
this.base.detach();
|
this.base.detach();
|
||||||
|
|
@ -261,7 +262,6 @@ var Autocomplete = function() {
|
||||||
editor.completer = this;
|
editor.completer = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
|
|
||||||
editor.on("changeSelection", this.changeListener);
|
editor.on("changeSelection", this.changeListener);
|
||||||
editor.on("blur", this.blurListener);
|
editor.on("blur", this.blurListener);
|
||||||
editor.on("mousedown", this.mousedownListener);
|
editor.on("mousedown", this.mousedownListener);
|
||||||
|
|
@ -408,10 +408,10 @@ Autocomplete.startCommand = {
|
||||||
exec: function(editor) {
|
exec: function(editor) {
|
||||||
if (!editor.completer)
|
if (!editor.completer)
|
||||||
editor.completer = new Autocomplete();
|
editor.completer = new Autocomplete();
|
||||||
editor.completer.autoInsert =
|
editor.completer.autoInsert = false;
|
||||||
editor.completer.autoSelect = true;
|
editor.completer.autoSelect = true;
|
||||||
editor.completer.showPopup(editor);
|
editor.completer.showPopup(editor);
|
||||||
// needed for firefox on mac
|
// prevent ctrl-space opening context menu on firefox on mac
|
||||||
editor.completer.cancelContextMenu();
|
editor.completer.cancelContextMenu();
|
||||||
},
|
},
|
||||||
bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
|
bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
|
||||||
|
|
|
||||||
|
|
@ -892,17 +892,17 @@ var EditSession = function(text, mode) {
|
||||||
config.loadModule(["mode", path], function(m) {
|
config.loadModule(["mode", path], function(m) {
|
||||||
if (this.$modeId !== path)
|
if (this.$modeId !== path)
|
||||||
return cb && cb();
|
return cb && cb();
|
||||||
if (this.$modes[path] && !options)
|
if (this.$modes[path] && !options) {
|
||||||
return this.$onChangeMode(this.$modes[path]);
|
this.$onChangeMode(this.$modes[path]);
|
||||||
if (m && m.Mode) {
|
} else if (m && m.Mode) {
|
||||||
m = new m.Mode(options);
|
m = new m.Mode(options);
|
||||||
if (!options) {
|
if (!options) {
|
||||||
this.$modes[path] = m;
|
this.$modes[path] = m;
|
||||||
m.$id = path;
|
m.$id = path;
|
||||||
}
|
}
|
||||||
this.$onChangeMode(m);
|
this.$onChangeMode(m);
|
||||||
cb && cb();
|
|
||||||
}
|
}
|
||||||
|
cb && cb();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
// set mode to text until loading is finished
|
// set mode to text until loading is finished
|
||||||
|
|
|
||||||
|
|
@ -545,8 +545,11 @@ var Editor = function(renderer, session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.type.indexOf("tag-open") != -1)
|
if (token.type.indexOf("tag-open") != -1) {
|
||||||
token = iterator.stepForward();
|
token = iterator.stepForward();
|
||||||
|
if (!token)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var tag = token.value;
|
var tag = token.value;
|
||||||
var depth = 0;
|
var depth = 0;
|
||||||
|
|
@ -1284,7 +1287,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
|
* Removes the current selection or one character.
|
||||||
* @param {String} dir The direction of the deletion to occur, either "left" or "right"
|
* @param {String} dir The direction of the deletion to occur, either "left" or "right"
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ var loadSnippetFile = function(id) {
|
||||||
function getCompletionPrefix(editor) {
|
function getCompletionPrefix(editor) {
|
||||||
var pos = editor.getCursorPosition();
|
var pos = editor.getCursorPosition();
|
||||||
var line = editor.session.getLine(pos.row);
|
var line = editor.session.getLine(pos.row);
|
||||||
var prefix = util.retrievePrecedingIdentifier(line, pos.column);
|
var prefix;
|
||||||
// Try to find custom prefixes on the completers
|
// Try to find custom prefixes on the completers
|
||||||
editor.completers.forEach(function(completer) {
|
editor.completers.forEach(function(completer) {
|
||||||
if (completer.identifierRegexps) {
|
if (completer.identifierRegexps) {
|
||||||
|
|
@ -150,7 +150,7 @@ function getCompletionPrefix(editor) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return prefix;
|
return prefix || util.retrievePrecedingIdentifier(line, pos.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
var doLiveAutocomplete = function(e) {
|
var doLiveAutocomplete = function(e) {
|
||||||
|
|
@ -158,8 +158,6 @@ var doLiveAutocomplete = function(e) {
|
||||||
var text = e.args || "";
|
var text = e.args || "";
|
||||||
var hasCompleter = editor.completer && editor.completer.activated;
|
var hasCompleter = editor.completer && editor.completer.activated;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We don't want to autocomplete with no prefix
|
// We don't want to autocomplete with no prefix
|
||||||
if (e.command.name === "backspace") {
|
if (e.command.name === "backspace") {
|
||||||
if (hasCompleter && !getCompletionPrefix(editor))
|
if (hasCompleter && !getCompletionPrefix(editor))
|
||||||
|
|
@ -174,7 +172,6 @@ var doLiveAutocomplete = function(e) {
|
||||||
editor.completer = new Autocomplete();
|
editor.completer = new Autocomplete();
|
||||||
}
|
}
|
||||||
// Disable autoInsert
|
// Disable autoInsert
|
||||||
editor.completer.autoSelect = false;
|
|
||||||
editor.completer.autoInsert = false;
|
editor.completer.autoInsert = false;
|
||||||
editor.completer.showPopup(editor);
|
editor.completer.showPopup(editor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ Mode.prototype.supportsFile = function(filename) {
|
||||||
// todo firstlinematch
|
// todo firstlinematch
|
||||||
var supportedModes = {
|
var supportedModes = {
|
||||||
ABAP: ["abap"],
|
ABAP: ["abap"],
|
||||||
|
ABC: ["abc"],
|
||||||
ActionScript:["as"],
|
ActionScript:["as"],
|
||||||
ADA: ["ada|adb"],
|
ADA: ["ada|adb"],
|
||||||
Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],
|
Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,11 @@ var TextInput = function(parentNode, host) {
|
||||||
function resetSelection(isEmpty) {
|
function resetSelection(isEmpty) {
|
||||||
if (inComposition)
|
if (inComposition)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// this prevents infinite recursion on safari 8
|
||||||
|
// see https://github.com/ajaxorg/ace/issues/2114
|
||||||
|
inComposition = true;
|
||||||
|
|
||||||
if (inputHandler) {
|
if (inputHandler) {
|
||||||
selectionStart = 0;
|
selectionStart = 0;
|
||||||
selectionEnd = isEmpty ? 0 : text.value.length - 1;
|
selectionEnd = isEmpty ? 0 : text.value.length - 1;
|
||||||
|
|
@ -113,6 +118,8 @@ var TextInput = function(parentNode, host) {
|
||||||
try {
|
try {
|
||||||
text.setSelectionRange(selectionStart, selectionEnd);
|
text.setSelectionRange(selectionStart, selectionEnd);
|
||||||
} catch(e){}
|
} catch(e){}
|
||||||
|
|
||||||
|
inComposition = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetValue() {
|
function resetValue() {
|
||||||
|
|
|
||||||
|
|
@ -2110,7 +2110,9 @@ dom.importCssString(".normal-mode .ace_cursor{\
|
||||||
newHead = copyCursor(origHead);
|
newHead = copyCursor(origHead);
|
||||||
}
|
}
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
|
if (!(vim.visualBlock && newHead.ch === Infinity)) {
|
||||||
newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
|
newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
|
||||||
|
}
|
||||||
if (newAnchor) {
|
if (newAnchor) {
|
||||||
newAnchor = clipCursorToContent(cm, newAnchor, true);
|
newAnchor = clipCursorToContent(cm, newAnchor, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1957,6 +1957,14 @@ testVim('visual_line', function(cm, vim, helpers) {
|
||||||
helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
|
helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
|
||||||
eq(' 4\n 5', cm.getValue());
|
eq(' 4\n 5', cm.getValue());
|
||||||
}, { value: ' 1\n 2\n 3\n 4\n 5' });
|
}, { value: ' 1\n 2\n 3\n 4\n 5' });
|
||||||
|
testVim('visual_block_move_to_eol', function(cm, vim, helpers) {
|
||||||
|
// moveToEol should move all block cursors to end of line
|
||||||
|
cm.setCursor(0, 0);
|
||||||
|
helpers.doKeys('<C-v>', 'G', '$');
|
||||||
|
var selections = cm.getSelections().join();
|
||||||
|
console.log(selections);
|
||||||
|
eq("123,45,6", selections);
|
||||||
|
}, {value: '123\n45\n6'});
|
||||||
testVim('visual_block_different_line_lengths', function(cm, vim, helpers) {
|
testVim('visual_block_different_line_lengths', function(cm, vim, helpers) {
|
||||||
// test the block selection with lines of different length
|
// test the block selection with lines of different length
|
||||||
// i.e. extending the selection
|
// i.e. extending the selection
|
||||||
|
|
|
||||||
|
|
@ -253,20 +253,6 @@ function normalizeCommandKeys(callback, e, keyCode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyCode in keys.MODIFIER_KEYS) {
|
if (keyCode in keys.MODIFIER_KEYS) {
|
||||||
switch (keys.MODIFIER_KEYS[keyCode]) {
|
|
||||||
case "Alt":
|
|
||||||
hashId = 2;
|
|
||||||
break;
|
|
||||||
case "Shift":
|
|
||||||
hashId = 4;
|
|
||||||
break;
|
|
||||||
case "Ctrl":
|
|
||||||
hashId = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
hashId = 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
keyCode = -1;
|
keyCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ var Keys = (function() {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
ret.KEY_MODS[0] = "";
|
ret.KEY_MODS[0] = "";
|
||||||
ret.KEY_MODS[-1] = "input";
|
ret.KEY_MODS[-1] = "input-";
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
[1, +1, -1, 12_345, 0.000_1,
|
[1, +1, -1, 12_345, 0.000_1,
|
||||||
_, 3_1, 1_2, 1_.0, 0._1];
|
_, 3_1, 1_2, 1_.0, 0._1];
|
||||||
|
|
||||||
{:id => 34, :key => "value"}
|
{:id => ?", :key => "value", anotherKey: [x, y?]}
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
=end
|
=end
|
||||||
|
|
|
||||||
2207
lib/ace/mode/_test/tokens_abc.json
Normal file
2207
lib/ace/mode/_test/tokens_abc.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -137,7 +137,12 @@
|
||||||
"start",
|
"start",
|
||||||
["text"," "],
|
["text"," "],
|
||||||
["keyword","#if"],
|
["keyword","#if"],
|
||||||
["constant.other"," VERBOSE >= 2"]
|
["text"," "],
|
||||||
|
["identifier","VERBOSE"],
|
||||||
|
["text"," "],
|
||||||
|
["keyword.operator",">="],
|
||||||
|
["text"," "],
|
||||||
|
["constant.numeric","2"]
|
||||||
],[
|
],[
|
||||||
"start",
|
"start",
|
||||||
["text"," "],
|
["text"," "],
|
||||||
|
|
|
||||||
|
|
@ -727,7 +727,8 @@
|
||||||
],[
|
],[
|
||||||
"start",
|
"start",
|
||||||
["keyword","#ifndef"],
|
["keyword","#ifndef"],
|
||||||
["constant.other"," Nil"]
|
["text"," "],
|
||||||
|
["constant.language.objc","Nil"]
|
||||||
],[
|
],[
|
||||||
"start",
|
"start",
|
||||||
["keyword","#define"],
|
["keyword","#define"],
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@
|
||||||
["text"," "],
|
["text"," "],
|
||||||
["punctuation.separator.key-value","=>"],
|
["punctuation.separator.key-value","=>"],
|
||||||
["text"," "],
|
["text"," "],
|
||||||
["constant.numeric","34"],
|
["string.character","?\""],
|
||||||
["text",", "],
|
["text",", "],
|
||||||
["constant.other.symbol.ruby",":key"],
|
["constant.other.symbol.ruby",":key"],
|
||||||
["text"," "],
|
["text"," "],
|
||||||
|
|
@ -148,7 +148,15 @@
|
||||||
["string.start","\""],
|
["string.start","\""],
|
||||||
["string","value"],
|
["string","value"],
|
||||||
["string.end","\""],
|
["string.end","\""],
|
||||||
["paren.rparen","}"]
|
["text",", "],
|
||||||
|
["identifier","anotherKey"],
|
||||||
|
["text",": "],
|
||||||
|
["paren.lparen","["],
|
||||||
|
["identifier","x"],
|
||||||
|
["text",", "],
|
||||||
|
["identifier","y"],
|
||||||
|
["text","?"],
|
||||||
|
["paren.rparen","]}"]
|
||||||
],[
|
],[
|
||||||
"start"
|
"start"
|
||||||
],[
|
],[
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ var AbapHighlightRules = function() {
|
||||||
{token : "string", regex : "`", next : "start"},
|
{token : "string", regex : "`", next : "start"},
|
||||||
{defaultToken : "string"}
|
{defaultToken : "string"}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
oop.inherits(AbapHighlightRules, TextHighlightRules);
|
oop.inherits(AbapHighlightRules, TextHighlightRules);
|
||||||
|
|
||||||
|
|
|
||||||
58
lib/ace/mode/abc.js
Normal file
58
lib/ace/mode/abc.js
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Distributed under the BSD license:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012, 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 ***** */
|
||||||
|
|
||||||
|
/*
|
||||||
|
THIS FILE WAS AUTOGENERATED BY mode.tmpl.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(function (require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../lib/oop");
|
||||||
|
var TextMode = require("./text").Mode;
|
||||||
|
var ABCHighlightRules = require("./abc_highlight_rules").ABCHighlightRules;
|
||||||
|
// TODO: pick appropriate fold mode
|
||||||
|
var FoldMode = require("./folding/cstyle").FoldMode;
|
||||||
|
|
||||||
|
var Mode = function () {
|
||||||
|
this.HighlightRules = ABCHighlightRules;
|
||||||
|
this.foldingRules = new FoldMode();
|
||||||
|
};
|
||||||
|
oop.inherits(Mode, TextMode);
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
// this.lineCommentStart = ""%.*"";
|
||||||
|
// this.blockComment = {start: ""/*"", end: ""*/""};
|
||||||
|
// Extra logic goes here.
|
||||||
|
this.$id = "ace/mode/abc"
|
||||||
|
}).call(Mode.prototype);
|
||||||
|
|
||||||
|
exports.Mode = Mode;
|
||||||
|
});
|
||||||
114
lib/ace/mode/abc_highlight_rules.js
Normal file
114
lib/ace/mode/abc_highlight_rules.js
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/* This file was partially autogenerated from https://github.com/jimhawkridge/SublimeABC
|
||||||
|
|
||||||
|
Modifications
|
||||||
|
|
||||||
|
- more classes to express the abc semantic
|
||||||
|
- added syntax highlighting for Zupfnoter conventions (https://github.com/bwl21/zupfnoter)
|
||||||
|
- separate note pitch and note duration - even if it looks the same
|
||||||
|
|
||||||
|
***********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
define(function (require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var oop = require("../lib/oop");
|
||||||
|
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
|
||||||
|
|
||||||
|
var ABCHighlightRules = function () {
|
||||||
|
// regexp must not have capturing parentheses. Use (?:) instead.
|
||||||
|
// regexps are ordered -> the first match is used
|
||||||
|
|
||||||
|
this.$rules = {
|
||||||
|
start: [
|
||||||
|
{
|
||||||
|
token: ['zupfnoter.information.comment.line.percentage', 'information.keyword', 'in formation.keyword.embedded'],
|
||||||
|
regex: '(%%%%)(hn\\.[a-z]*)(.*)',
|
||||||
|
comment: 'Instruction Comment'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: ['information.comment.line.percentage', 'information.keyword.embedded'],
|
||||||
|
regex: '(%%)(.*)',
|
||||||
|
comment: 'Instruction Comment'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
token: 'comment.line.percentage',
|
||||||
|
regex: '%.*',
|
||||||
|
comment: 'Comments'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
token: 'barline.keyword.operator',
|
||||||
|
regex: '[\\[:]*[|:][|\\]:]*(?:\\[?[0-9]+)?|\\[[0-9]+',
|
||||||
|
comment: 'Bar lines'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: ['information.keyword.embedded', 'information.argument.string.unquoted'],
|
||||||
|
regex: '(\\[[A-Za-z]:)([^\\]]*\\])',
|
||||||
|
comment: 'embedded Header lines'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: ['information.keyword', 'information.argument.string.unquoted'],
|
||||||
|
regex: '^([A-Za-z]:)([^%\\\\]*)',
|
||||||
|
comment: 'Header lines'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: ['text', 'entity.name.function', 'string.unquoted', 'text'],
|
||||||
|
regex: '(\\[)([A-Z]:)(.*?)(\\])',
|
||||||
|
comment: 'Inline fields'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: ['accent.constant.language', 'pitch.constant.numeric', 'duration.constant.numeric'],
|
||||||
|
regex: '([\\^=_]*)([A-Ga-gz][,\']*)([0-9]*/*[><0-9]*)',
|
||||||
|
comment: 'Notes'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: 'zupfnoter.jumptarget.string.quoted',
|
||||||
|
regex: '[\\"!]\\^\\:.*?[\\"!]',
|
||||||
|
comment: 'Zupfnoter jumptarget'
|
||||||
|
}, {
|
||||||
|
token: 'zupfnoter.goto.string.quoted',
|
||||||
|
regex: '[\\"!]\\^\\@.*?[\\"!]',
|
||||||
|
comment: 'Zupfnoter goto'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: 'zupfnoter.annotation.string.quoted',
|
||||||
|
regex: '[\\"!]\\^\\!.*?[\\"!]',
|
||||||
|
comment: 'Zupfnoter annoation'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: 'zupfnoter.annotationref.string.quoted',
|
||||||
|
regex: '[\\"!]\\^\\#.*?[\\"!]',
|
||||||
|
comment: 'Zupfnoter annotation reference'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: 'chordname.string.quoted',
|
||||||
|
regex: '[\\"!]\\^.*?[\\"!]',
|
||||||
|
comment: 'abc chord'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: 'string.quoted',
|
||||||
|
regex: '[\\"!].*?[\\"!]',
|
||||||
|
comment: 'abc annotation'
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// this.embedRules(JsonHighlightRules, "json-")
|
||||||
|
|
||||||
|
this.normalizeRules();
|
||||||
|
};
|
||||||
|
|
||||||
|
ABCHighlightRules.metaData = {
|
||||||
|
fileTypes: ['abc'],
|
||||||
|
name: 'ABC',
|
||||||
|
scopeName: 'text.abcnotation'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
oop.inherits(ABCHighlightRules, TextHighlightRules);
|
||||||
|
|
||||||
|
exports.ABCHighlightRules = ABCHighlightRules;
|
||||||
|
});
|
||||||
|
|
@ -84,11 +84,11 @@ var c_cppHighlightRules = function() {
|
||||||
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
|
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
|
||||||
}, {
|
}, {
|
||||||
token : "keyword", // pre-compiler directives
|
token : "keyword", // pre-compiler directives
|
||||||
regex : "#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",
|
regex : "#\\s*(?:include|import|pragma|line|define|undef)\\b",
|
||||||
next : "directive"
|
next : "directive"
|
||||||
}, {
|
}, {
|
||||||
token : "keyword", // special case pre-compiler directive
|
token : "keyword", // special case pre-compiler directive
|
||||||
regex : "(?:#\\s*endif)\\b"
|
regex : "#\\s*(?:endif|if|ifdef|else|elif|ifndef)\\b"
|
||||||
}, {
|
}, {
|
||||||
token : "support.function.C99.c",
|
token : "support.function.C99.c",
|
||||||
regex : cFunctions
|
regex : cFunctions
|
||||||
|
|
|
||||||
|
|
@ -116,11 +116,11 @@ oop.inherits(Mode, TextMode);
|
||||||
var worker = new WorkerClient(["ace"], "ace/mode/coffee_worker", "Worker");
|
var worker = new WorkerClient(["ace"], "ace/mode/coffee_worker", "Worker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("error", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
session.setAnnotations([e.data]);
|
session.setAnnotations(e.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.on("ok", function(e) {
|
worker.on("terminate", function() {
|
||||||
session.clearAnnotations();
|
session.clearAnnotations();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,13 @@ oop.inherits(Worker, Mirror);
|
||||||
|
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
|
var errors = [];
|
||||||
try {
|
try {
|
||||||
coffee.parse(value).compile();
|
coffee.parse(value).compile();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
var loc = e.location;
|
var loc = e.location;
|
||||||
if (loc) {
|
if (loc) {
|
||||||
this.sender.emit("error", {
|
errors.push({
|
||||||
row: loc.first_line,
|
row: loc.first_line,
|
||||||
column: loc.first_column,
|
column: loc.first_column,
|
||||||
endRow: loc.last_line,
|
endRow: loc.last_line,
|
||||||
|
|
@ -64,9 +64,8 @@ oop.inherits(Worker, Mirror);
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.sender.emit("ok");
|
this.sender.emit("annotate", errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(Worker.prototype);
|
}).call(Worker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ oop.inherits(Mode, TextMode);
|
||||||
var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker");
|
var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("csslint", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
session.setAnnotations(e.data);
|
session.setAnnotations(e.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,11 @@ oop.inherits(Worker, Mirror);
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
if (!value)
|
if (!value)
|
||||||
return this.sender.emit("csslint", []);
|
return this.sender.emit("annotate", []);
|
||||||
var infoRules = this.infoRules;
|
var infoRules = this.infoRules;
|
||||||
|
|
||||||
var result = CSSLint.verify(value, this.ruleset);
|
var result = CSSLint.verify(value, this.ruleset);
|
||||||
this.sender.emit("csslint", result.messages.map(function(msg) {
|
this.sender.emit("annotate", result.messages.map(function(msg) {
|
||||||
return {
|
return {
|
||||||
row: msg.line - 1,
|
row: msg.line - 1,
|
||||||
column: msg.col - 1,
|
column: msg.col - 1,
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ module.exports = {
|
||||||
assert.equal(session.getFoldWidget(3), "end");
|
assert.equal(session.getFoldWidget(3), "end");
|
||||||
assert.equal(session.getFoldWidget(4), "end");
|
assert.equal(session.getFoldWidget(4), "end");
|
||||||
|
|
||||||
assert.range(session.getFoldWidgetRange(0), 0, 8, 4, 0);
|
assert.range(session.getFoldWidgetRange(0), 0, 31, 4, 0);
|
||||||
assert.range(session.getFoldWidgetRange(4), 0, 8, 4, 0);
|
assert.range(session.getFoldWidgetRange(4), 0, 31, 4, 0);
|
||||||
|
|
||||||
assert.range(session.getFoldWidgetRange(1), 1, 16, 3, 0);
|
assert.range(session.getFoldWidgetRange(1), 1, 16, 3, 0);
|
||||||
assert.range(session.getFoldWidgetRange(3), 1, 16, 3, 0);
|
assert.range(session.getFoldWidgetRange(3), 1, 16, 3, 0);
|
||||||
|
|
@ -85,8 +85,8 @@ module.exports = {
|
||||||
assert.equal(session.getFoldWidget(3), "end");
|
assert.equal(session.getFoldWidget(3), "end");
|
||||||
assert.equal(session.getFoldWidget(4), "end");
|
assert.equal(session.getFoldWidget(4), "end");
|
||||||
|
|
||||||
assert.range(session.getFoldWidgetRange(0), 0, 7, 4, 0);
|
assert.range(session.getFoldWidgetRange(0), 0, 23, 4, 0);
|
||||||
assert.range(session.getFoldWidgetRange(4), 0, 7, 4, 0);
|
assert.range(session.getFoldWidgetRange(4), 0, 23, 4, 0);
|
||||||
|
|
||||||
assert.range(session.getFoldWidgetRange(1), 1, 17, 3, 4);
|
assert.range(session.getFoldWidgetRange(1), 1, 17, 3, 4);
|
||||||
assert.range(session.getFoldWidgetRange(3), 1, 17, 3, 4);
|
assert.range(session.getFoldWidgetRange(3), 1, 17, 3, 4);
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,8 @@ function is(token, type) {
|
||||||
row: row,
|
row: row,
|
||||||
column: firstTag.start.column + firstTag.tagName.length + 2
|
column: firstTag.start.column + firstTag.tagName.length + 2
|
||||||
};
|
};
|
||||||
|
if (firstTag.start.row == firstTag.end.row)
|
||||||
|
start.column = firstTag.end.column;
|
||||||
while (tag = this._readTagForward(iterator)) {
|
while (tag = this._readTagForward(iterator)) {
|
||||||
if (tag.selfClosing) {
|
if (tag.selfClosing) {
|
||||||
if (!stack.length) {
|
if (!stack.length) {
|
||||||
|
|
@ -258,6 +260,8 @@ function is(token, type) {
|
||||||
this._pop(stack, tag);
|
this._pop(stack, tag);
|
||||||
if (stack.length == 0) {
|
if (stack.length == 0) {
|
||||||
tag.start.column += tag.tagName.length + 2;
|
tag.start.column += tag.tagName.length + 2;
|
||||||
|
if (tag.start.row == tag.end.row && tag.start.column < tag.end.column)
|
||||||
|
tag.start.column = tag.end.column;
|
||||||
return Range.fromPoints(tag.start, end);
|
return Range.fromPoints(tag.start, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,9 @@ var HaskellHighlightRules = function() {
|
||||||
{ token: 'constant.language.empty-list.haskell',
|
{ token: 'constant.language.empty-list.haskell',
|
||||||
regex: '\\[\\]' },
|
regex: '\\[\\]' },
|
||||||
{ token: 'keyword.other.haskell',
|
{ token: 'keyword.other.haskell',
|
||||||
regex: 'module',
|
regex: '\\bmodule\\b',
|
||||||
push:
|
push:
|
||||||
[ { token: 'keyword.other.haskell', regex: 'where', next: 'pop' },
|
[ { token: 'keyword.other.haskell', regex: '\\bwhere\\b', next: 'pop' },
|
||||||
{ include: '#module_name' },
|
{ include: '#module_name' },
|
||||||
{ include: '#module_exports' },
|
{ include: '#module_exports' },
|
||||||
{ token: 'invalid', regex: '[a-z]+' },
|
{ token: 'invalid', regex: '[a-z]+' },
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ oop.inherits(Mode, TextMode);
|
||||||
var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker");
|
var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("jslint", function(results) {
|
worker.on("annotate", function(results) {
|
||||||
session.setAnnotations(results.data);
|
session.setAnnotations(results.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -116,12 +116,10 @@ oop.inherits(JavaScriptWorker, Mirror);
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
value = value.replace(/^#!.*\n/, "\n");
|
value = value.replace(/^#!.*\n/, "\n");
|
||||||
if (!value) {
|
if (!value)
|
||||||
this.sender.emit("jslint", []);
|
return this.sender.emit("annotate", []);
|
||||||
return;
|
|
||||||
}
|
|
||||||
var errors = [];
|
|
||||||
|
|
||||||
|
var errors = [];
|
||||||
// jshint reports many false errors
|
// jshint reports many false errors
|
||||||
// report them as error only if code is actually invalid
|
// report them as error only if code is actually invalid
|
||||||
var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
|
var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
|
||||||
|
|
@ -179,7 +177,7 @@ oop.inherits(JavaScriptWorker, Mirror);
|
||||||
}
|
}
|
||||||
// console.log("lint time: " + (new Date() - start));
|
// console.log("lint time: " + (new Date() - start));
|
||||||
|
|
||||||
this.sender.emit("jslint", errors);
|
this.sender.emit("annotate", errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(JavaScriptWorker.prototype);
|
}).call(JavaScriptWorker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -74,11 +74,11 @@ oop.inherits(Mode, TextMode);
|
||||||
var worker = new WorkerClient(["ace"], "ace/mode/json_worker", "JsonWorker");
|
var worker = new WorkerClient(["ace"], "ace/mode/json_worker", "JsonWorker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("error", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
session.setAnnotations([e.data]);
|
session.setAnnotations(e.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.on("ok", function() {
|
worker.on("terminate", function() {
|
||||||
session.clearAnnotations();
|
session.clearAnnotations();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,21 +46,20 @@ oop.inherits(JsonWorker, Mirror);
|
||||||
|
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
|
var errors = [];
|
||||||
try {
|
try {
|
||||||
if (value)
|
if (value)
|
||||||
parse(value);
|
parse(value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var pos = this.doc.indexToPosition(e.at-1);
|
var pos = this.doc.indexToPosition(e.at-1);
|
||||||
this.sender.emit("error", {
|
errors.push({
|
||||||
row: pos.row,
|
row: pos.row,
|
||||||
column: pos.column,
|
column: pos.column,
|
||||||
text: e.message,
|
text: e.message,
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.sender.emit("ok");
|
this.sender.emit("annotate", errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(JsonWorker.prototype);
|
}).call(JsonWorker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ module.exports = {
|
||||||
worker.setValue("{}");
|
worker.setValue("{}");
|
||||||
worker.deferredUpdate.call();
|
worker.deferredUpdate.call();
|
||||||
|
|
||||||
assert.equal(this.sender.events[0][0], "ok");
|
assert.equal(this.sender.events[0][1].length, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test check for syntax error": function() {
|
"test check for syntax error": function() {
|
||||||
|
|
@ -71,11 +71,12 @@ module.exports = {
|
||||||
worker.deferredUpdate.call();
|
worker.deferredUpdate.call();
|
||||||
|
|
||||||
var event = this.sender.events[0];
|
var event = this.sender.events[0];
|
||||||
assert.equal(event[0], "error");
|
assert.equal(event[0], "annotate");
|
||||||
assert.equal(event[1].type, "error");
|
assert.equal(event[1].length, 1);
|
||||||
assert.equal(event[1].text, "Bad string");
|
assert.equal(event[1][0].type, "error");
|
||||||
assert.equal(event[1].row, 1);
|
assert.equal(event[1][0].text, "Bad string");
|
||||||
assert.equal(event[1].column, 0);
|
assert.equal(event[1][0].row, 1);
|
||||||
|
assert.equal(event[1][0].column, 0);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -85,11 +86,11 @@ module.exports = {
|
||||||
worker.deferredUpdate.call();
|
worker.deferredUpdate.call();
|
||||||
|
|
||||||
var event = this.sender.events[0];
|
var event = this.sender.events[0];
|
||||||
assert.equal(event[0], "error");
|
assert.equal(event[0], "annotate");
|
||||||
assert.equal(event[1].type, "error");
|
assert.equal(event[1][0].type, "error");
|
||||||
assert.equal(event[1].text, "Unexpected 'x'");
|
assert.equal(event[1][0].text, "Unexpected 'x'");
|
||||||
assert.equal(event[1].row, 0);
|
assert.equal(event[1][0].row, 0);
|
||||||
assert.equal(event[1].column, 0);
|
assert.equal(event[1][0].column, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@ define(function(require, exports, module){
|
||||||
}(require('../mode/text').Mode));
|
}(require('../mode/text').Mode));
|
||||||
keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
|
keywordend = '(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))';
|
||||||
stringfill = {
|
stringfill = {
|
||||||
token: 'string',
|
defaultToken: 'string'
|
||||||
regex: '.+'
|
|
||||||
};
|
};
|
||||||
LiveScriptMode.Rules = {
|
LiveScriptMode.Rules = {
|
||||||
start: [
|
start: [
|
||||||
|
|
@ -146,7 +145,7 @@ define(function(require, exports, module){
|
||||||
next: 'key'
|
next: 'key'
|
||||||
}, {
|
}, {
|
||||||
token: 'keyword.operator',
|
token: 'keyword.operator',
|
||||||
regex: '\\S+'
|
regex: '[\\^!|&%+\\-]+'
|
||||||
}, {
|
}, {
|
||||||
token: 'text',
|
token: 'text',
|
||||||
regex: '\\s+'
|
regex: '\\s+'
|
||||||
|
|
@ -164,8 +163,7 @@ define(function(require, exports, module){
|
||||||
token: 'comment.regex',
|
token: 'comment.regex',
|
||||||
regex: '\\s+(?:#.*)?'
|
regex: '\\s+(?:#.*)?'
|
||||||
}, {
|
}, {
|
||||||
token: 'string.regex',
|
defaultToken: 'string.regex'
|
||||||
regex: '\\S+'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
key: [
|
key: [
|
||||||
|
|
@ -178,7 +176,7 @@ define(function(require, exports, module){
|
||||||
next: 'start'
|
next: 'start'
|
||||||
}, {
|
}, {
|
||||||
token: 'text',
|
token: 'text',
|
||||||
regex: '.',
|
regex: '',
|
||||||
next: 'start'
|
next: 'start'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -188,8 +186,7 @@ define(function(require, exports, module){
|
||||||
regex: '.*?\\*/',
|
regex: '.*?\\*/',
|
||||||
next: 'start'
|
next: 'start'
|
||||||
}, {
|
}, {
|
||||||
token: 'comment.doc',
|
defaultToken: 'comment.doc'
|
||||||
regex: '.+'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
qdoc: [
|
qdoc: [
|
||||||
|
|
|
||||||
|
|
@ -148,11 +148,11 @@ oop.inherits(Mode, TextMode);
|
||||||
var worker = new WorkerClient(["ace"], "ace/mode/lua_worker", "Worker");
|
var worker = new WorkerClient(["ace"], "ace/mode/lua_worker", "Worker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("error", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
session.setAnnotations([e.data]);
|
session.setAnnotations(e.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.on("ok", function(e) {
|
worker.on("terminate", function() {
|
||||||
session.clearAnnotations();
|
session.clearAnnotations();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,24 +46,23 @@ oop.inherits(Worker, Mirror);
|
||||||
|
|
||||||
this.onUpdate = function() {
|
this.onUpdate = function() {
|
||||||
var value = this.doc.getValue();
|
var value = this.doc.getValue();
|
||||||
|
var errors = [];
|
||||||
|
|
||||||
// var t=Date.now()
|
// var t=Date.now()
|
||||||
try {
|
try {
|
||||||
luaparse.parse(value);
|
luaparse.parse(value);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (e instanceof SyntaxError) {
|
if (e instanceof SyntaxError) {
|
||||||
this.sender.emit("error", {
|
errors.push({
|
||||||
row: e.line - 1,
|
row: e.line - 1,
|
||||||
column: e.column,
|
column: e.column,
|
||||||
text: e.message,
|
text: e.message,
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// console.log( t-Date.now())
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// console.log( t-Date.now())
|
// console.log( t-Date.now())
|
||||||
this.sender.emit("ok");
|
this.sender.emit("annotate", errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(Worker.prototype);
|
}).call(Worker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -143,11 +143,11 @@ oop.inherits(Mode, HtmlMode);
|
||||||
if (this.inlinePhp)
|
if (this.inlinePhp)
|
||||||
worker.call("setOptions", [{inline: true}]);
|
worker.call("setOptions", [{inline: true}]);
|
||||||
|
|
||||||
worker.on("error", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
session.setAnnotations(e.data);
|
session.setAnnotations(e.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
worker.on("ok", function() {
|
worker.on("terminate", function() {
|
||||||
session.clearAnnotations();
|
session.clearAnnotations();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,7 @@ oop.inherits(PhpWorker, Mirror);
|
||||||
|
|
||||||
// console.log("lint time: " + (new Date() - start));
|
// console.log("lint time: " + (new Date() - start));
|
||||||
|
|
||||||
if (errors.length) {
|
this.sender.emit("annotate", errors);
|
||||||
this.sender.emit("error", errors);
|
|
||||||
} else {
|
|
||||||
this.sender.emit("ok");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}).call(PhpWorker.prototype);
|
}).call(PhpWorker.prototype);
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,9 @@ var RubyHighlightRules = function() {
|
||||||
return stack[0];
|
return stack[0];
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
token : "string.character",
|
||||||
|
regex : "\\B\\?."
|
||||||
}, {
|
}, {
|
||||||
token : "keyword.operator",
|
token : "keyword.operator",
|
||||||
regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
|
regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ var TextMode = require("./text").Mode;
|
||||||
var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
|
var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
|
||||||
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
|
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
|
||||||
var XmlFoldMode = require("./folding/xml").FoldMode;
|
var XmlFoldMode = require("./folding/xml").FoldMode;
|
||||||
|
var WorkerClient = require("../worker/worker_client").WorkerClient;
|
||||||
|
|
||||||
var Mode = function() {
|
var Mode = function() {
|
||||||
this.HighlightRules = XmlHighlightRules;
|
this.HighlightRules = XmlHighlightRules;
|
||||||
|
|
@ -52,6 +53,21 @@ oop.inherits(Mode, TextMode);
|
||||||
|
|
||||||
this.blockComment = {start: "<!--", end: "-->"};
|
this.blockComment = {start: "<!--", end: "-->"};
|
||||||
|
|
||||||
|
this.createWorker = function(session) {
|
||||||
|
var worker = new WorkerClient(["ace"], "ace/mode/xml_worker", "Worker");
|
||||||
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
|
worker.on("error", function(e) {
|
||||||
|
session.setAnnotations(e.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
worker.on("terminate", function() {
|
||||||
|
session.clearAnnotations();
|
||||||
|
});
|
||||||
|
|
||||||
|
return worker;
|
||||||
|
};
|
||||||
|
|
||||||
this.$id = "ace/mode/xml";
|
this.$id = "ace/mode/xml";
|
||||||
}).call(Mode.prototype);
|
}).call(Mode.prototype);
|
||||||
|
|
||||||
|
|
|
||||||
260
lib/ace/mode/xml/dom-parser.js
Normal file
260
lib/ace/mode/xml/dom-parser.js
Normal file
|
|
@ -0,0 +1,260 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var XMLReader = require('./sax'),
|
||||||
|
DOMImplementation = require('./dom');
|
||||||
|
|
||||||
|
function DOMParser(options){
|
||||||
|
this.options = options ||{locator:{}};
|
||||||
|
|
||||||
|
}
|
||||||
|
DOMParser.prototype.parseFromString = function(source,mimeType){
|
||||||
|
var options = this.options;
|
||||||
|
var sax = new XMLReader();
|
||||||
|
var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
|
||||||
|
var errorHandler = options.errorHandler;
|
||||||
|
var locator = options.locator;
|
||||||
|
var defaultNSMap = options.xmlns||{};
|
||||||
|
var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
|
||||||
|
if(locator){
|
||||||
|
domBuilder.setDocumentLocator(locator)
|
||||||
|
}
|
||||||
|
|
||||||
|
sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
|
||||||
|
sax.domBuilder = options.domBuilder || domBuilder;
|
||||||
|
if(/\/x?html?$/.test(mimeType)){
|
||||||
|
entityMap.nbsp = '\xa0';
|
||||||
|
entityMap.copy = '\xa9';
|
||||||
|
defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
|
||||||
|
}
|
||||||
|
if(source){
|
||||||
|
sax.parse(source,defaultNSMap,entityMap);
|
||||||
|
}else{
|
||||||
|
sax.errorHandler.error("invalid document source");
|
||||||
|
}
|
||||||
|
return domBuilder.document;
|
||||||
|
}
|
||||||
|
function buildErrorHandler(errorImpl,domBuilder,locator){
|
||||||
|
if(!errorImpl){
|
||||||
|
if(domBuilder instanceof DOMHandler){
|
||||||
|
return domBuilder;
|
||||||
|
}
|
||||||
|
errorImpl = domBuilder ;
|
||||||
|
}
|
||||||
|
var errorHandler = {}
|
||||||
|
var isCallback = errorImpl instanceof Function;
|
||||||
|
locator = locator||{}
|
||||||
|
function build(key){
|
||||||
|
var fn = errorImpl[key];
|
||||||
|
if(!fn){
|
||||||
|
if(isCallback){
|
||||||
|
fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
|
||||||
|
}else{
|
||||||
|
var i=arguments.length;
|
||||||
|
while(--i){
|
||||||
|
if(fn = errorImpl[arguments[i]]){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errorHandler[key] = fn && function(msg){
|
||||||
|
fn(msg+_locator(locator), msg, locator);
|
||||||
|
}||function(){};
|
||||||
|
}
|
||||||
|
build('warning','warn');
|
||||||
|
build('error','warn','warning');
|
||||||
|
build('fatalError','warn','warning','error');
|
||||||
|
return errorHandler;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* +ContentHandler+ErrorHandler
|
||||||
|
* +LexicalHandler+EntityResolver2
|
||||||
|
* -DeclHandler-DTDHandler
|
||||||
|
*
|
||||||
|
* DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
|
||||||
|
* DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
|
||||||
|
*/
|
||||||
|
function DOMHandler() {
|
||||||
|
this.cdata = false;
|
||||||
|
}
|
||||||
|
function position(locator,node){
|
||||||
|
node.lineNumber = locator.lineNumber;
|
||||||
|
node.columnNumber = locator.columnNumber;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @see org.xml.sax.ContentHandler#startDocument
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
|
||||||
|
*/
|
||||||
|
DOMHandler.prototype = {
|
||||||
|
startDocument : function() {
|
||||||
|
this.document = new DOMImplementation().createDocument(null, null, null);
|
||||||
|
if (this.locator) {
|
||||||
|
this.document.documentURI = this.locator.systemId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startElement:function(namespaceURI, localName, qName, attrs) {
|
||||||
|
var doc = this.document;
|
||||||
|
var el = doc.createElementNS(namespaceURI, qName||localName);
|
||||||
|
var len = attrs.length;
|
||||||
|
appendElement(this, el);
|
||||||
|
this.currentElement = el;
|
||||||
|
|
||||||
|
this.locator && position(this.locator,el)
|
||||||
|
for (var i = 0 ; i < len; i++) {
|
||||||
|
var namespaceURI = attrs.getURI(i);
|
||||||
|
var value = attrs.getValue(i);
|
||||||
|
var qName = attrs.getQName(i);
|
||||||
|
var attr = doc.createAttributeNS(namespaceURI, qName);
|
||||||
|
if( attr.getOffset){
|
||||||
|
position(attr.getOffset(1),attr)
|
||||||
|
}
|
||||||
|
attr.value = attr.nodeValue = value;
|
||||||
|
el.setAttributeNode(attr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endElement:function(namespaceURI, localName, qName) {
|
||||||
|
var current = this.currentElement
|
||||||
|
var tagName = current.tagName;
|
||||||
|
this.currentElement = current.parentNode;
|
||||||
|
},
|
||||||
|
startPrefixMapping:function(prefix, uri) {
|
||||||
|
},
|
||||||
|
endPrefixMapping:function(prefix) {
|
||||||
|
},
|
||||||
|
processingInstruction:function(target, data) {
|
||||||
|
var ins = this.document.createProcessingInstruction(target, data);
|
||||||
|
this.locator && position(this.locator,ins)
|
||||||
|
appendElement(this, ins);
|
||||||
|
},
|
||||||
|
ignorableWhitespace:function(ch, start, length) {
|
||||||
|
},
|
||||||
|
characters:function(chars, start, length) {
|
||||||
|
chars = _toString.apply(this,arguments)
|
||||||
|
//console.log(chars)
|
||||||
|
if(this.currentElement && chars){
|
||||||
|
if (this.cdata) {
|
||||||
|
var charNode = this.document.createCDATASection(chars);
|
||||||
|
this.currentElement.appendChild(charNode);
|
||||||
|
} else {
|
||||||
|
var charNode = this.document.createTextNode(chars);
|
||||||
|
this.currentElement.appendChild(charNode);
|
||||||
|
}
|
||||||
|
this.locator && position(this.locator,charNode)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
skippedEntity:function(name) {
|
||||||
|
},
|
||||||
|
endDocument:function() {
|
||||||
|
this.document.normalize();
|
||||||
|
},
|
||||||
|
setDocumentLocator:function (locator) {
|
||||||
|
if(this.locator = locator){// && !('lineNumber' in locator)){
|
||||||
|
locator.lineNumber = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//LexicalHandler
|
||||||
|
comment:function(chars, start, length) {
|
||||||
|
chars = _toString.apply(this,arguments)
|
||||||
|
var comm = this.document.createComment(chars);
|
||||||
|
this.locator && position(this.locator,comm)
|
||||||
|
appendElement(this, comm);
|
||||||
|
},
|
||||||
|
|
||||||
|
startCDATA:function() {
|
||||||
|
//used in characters() methods
|
||||||
|
this.cdata = true;
|
||||||
|
},
|
||||||
|
endCDATA:function() {
|
||||||
|
this.cdata = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
startDTD:function(name, publicId, systemId) {
|
||||||
|
var impl = this.document.implementation;
|
||||||
|
if (impl && impl.createDocumentType) {
|
||||||
|
var dt = impl.createDocumentType(name, publicId, systemId);
|
||||||
|
this.locator && position(this.locator,dt)
|
||||||
|
appendElement(this, dt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @see org.xml.sax.ErrorHandler
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
||||||
|
*/
|
||||||
|
warning:function(error) {
|
||||||
|
console.warn(error,_locator(this.locator));
|
||||||
|
},
|
||||||
|
error:function(error) {
|
||||||
|
console.error(error,_locator(this.locator));
|
||||||
|
},
|
||||||
|
fatalError:function(error) {
|
||||||
|
console.error(error,_locator(this.locator));
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _locator(l){
|
||||||
|
if(l){
|
||||||
|
return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _toString(chars,start,length){
|
||||||
|
if(typeof chars == 'string'){
|
||||||
|
return chars.substr(start,length)
|
||||||
|
}else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
|
||||||
|
if(chars.length >= start+length || start){
|
||||||
|
return new java.lang.String(chars,start,length)+'';
|
||||||
|
}
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
|
||||||
|
* used method of org.xml.sax.ext.LexicalHandler:
|
||||||
|
* #comment(chars, start, length)
|
||||||
|
* #startCDATA()
|
||||||
|
* #endCDATA()
|
||||||
|
* #startDTD(name, publicId, systemId)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IGNORED method of org.xml.sax.ext.LexicalHandler:
|
||||||
|
* #endDTD()
|
||||||
|
* #startEntity(name)
|
||||||
|
* #endEntity(name)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
|
||||||
|
* IGNORED method of org.xml.sax.ext.DeclHandler
|
||||||
|
* #attributeDecl(eName, aName, type, mode, value)
|
||||||
|
* #elementDecl(name, model)
|
||||||
|
* #externalEntityDecl(name, publicId, systemId)
|
||||||
|
* #internalEntityDecl(name, value)
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
|
||||||
|
* IGNORED method of org.xml.sax.EntityResolver2
|
||||||
|
* #resolveEntity(String name,String publicId,String baseURI,String systemId)
|
||||||
|
* #resolveEntity(publicId, systemId)
|
||||||
|
* #getExternalSubset(name, baseURI)
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
|
||||||
|
* IGNORED method of org.xml.sax.DTDHandler
|
||||||
|
* #notationDecl(name, publicId, systemId) {};
|
||||||
|
* #unparsedEntityDecl(name, publicId, systemId, notationName) {};
|
||||||
|
*/
|
||||||
|
"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
|
||||||
|
DOMHandler.prototype[key] = function(){return null}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
|
||||||
|
function appendElement (hander,node) {
|
||||||
|
if (!hander.currentElement) {
|
||||||
|
hander.document.appendChild(node);
|
||||||
|
} else {
|
||||||
|
hander.currentElement.appendChild(node);
|
||||||
|
}
|
||||||
|
}//appendChild and setAttributeNS are preformance key
|
||||||
|
|
||||||
|
return {
|
||||||
|
DOMParser: DOMParser
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
1138
lib/ace/mode/xml/dom.js
Normal file
1138
lib/ace/mode/xml/dom.js
Normal file
File diff suppressed because it is too large
Load diff
592
lib/ace/mode/xml/sax.js
Normal file
592
lib/ace/mode/xml/sax.js
Normal file
|
|
@ -0,0 +1,592 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
||||||
|
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
||||||
|
//[5] Name ::= NameStartChar (NameChar)*
|
||||||
|
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
|
||||||
|
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\ux203F-\u2040]");
|
||||||
|
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
|
||||||
|
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
|
||||||
|
//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
|
||||||
|
|
||||||
|
//S_TAG, S_ATTR, S_EQ, S_V
|
||||||
|
//S_ATTR_S, S_E, S_S, S_C
|
||||||
|
var S_TAG = 0;//tag name offerring
|
||||||
|
var S_ATTR = 1;//attr name offerring
|
||||||
|
var S_ATTR_S=2;//attr name end and space offer
|
||||||
|
var S_EQ = 3;//=space?
|
||||||
|
var S_V = 4;//attr value(no quot value only)
|
||||||
|
var S_E = 5;//attr value end and no space(quot end)
|
||||||
|
var S_S = 6;//(attr value end || tag end ) && (space offer)
|
||||||
|
var S_C = 7;//closed el<el />
|
||||||
|
|
||||||
|
function XMLReader(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLReader.prototype = {
|
||||||
|
parse:function(source,defaultNSMap,entityMap){
|
||||||
|
var domBuilder = this.domBuilder;
|
||||||
|
domBuilder.startDocument();
|
||||||
|
_copy(defaultNSMap ,defaultNSMap = {})
|
||||||
|
parse(source,defaultNSMap,entityMap,
|
||||||
|
domBuilder,this.errorHandler);
|
||||||
|
domBuilder.endDocument();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
|
||||||
|
function fixedFromCharCode(code) {
|
||||||
|
// String.prototype.fromCharCode does not supports
|
||||||
|
// > 2 bytes unicode chars directly
|
||||||
|
if (code > 0xffff) {
|
||||||
|
code -= 0x10000;
|
||||||
|
var surrogate1 = 0xd800 + (code >> 10)
|
||||||
|
, surrogate2 = 0xdc00 + (code & 0x3ff);
|
||||||
|
|
||||||
|
return String.fromCharCode(surrogate1, surrogate2);
|
||||||
|
} else {
|
||||||
|
return String.fromCharCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function entityReplacer(a){
|
||||||
|
var k = a.slice(1,-1);
|
||||||
|
if(k in entityMap){
|
||||||
|
return entityMap[k];
|
||||||
|
}else if(k.charAt(0) === '#'){
|
||||||
|
return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
|
||||||
|
}else{
|
||||||
|
errorHandler.error('entity not found:'+a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function appendText(end){//has some bugs
|
||||||
|
var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
locator&&position(start);
|
||||||
|
domBuilder.characters(xt,0,end-start);
|
||||||
|
start = end
|
||||||
|
}
|
||||||
|
function position(start,m){
|
||||||
|
while(start>=endPos && (m = linePattern.exec(source))){
|
||||||
|
startPos = m.index;
|
||||||
|
endPos = startPos + m[0].length;
|
||||||
|
locator.lineNumber++;
|
||||||
|
//console.log('line++:',locator,startPos,endPos)
|
||||||
|
}
|
||||||
|
locator.columnNumber = start-startPos+1;
|
||||||
|
}
|
||||||
|
var startPos = 0;
|
||||||
|
var endPos = 0;
|
||||||
|
var linePattern = /.+(?:\r\n?|\n)|.*$/g
|
||||||
|
var locator = domBuilder.locator;
|
||||||
|
|
||||||
|
var parseStack = [{currentNSMap:defaultNSMapCopy}]
|
||||||
|
var closeMap = {};
|
||||||
|
var start = 0;
|
||||||
|
while(true){
|
||||||
|
var i = source.indexOf('<',start);
|
||||||
|
if(i<0){
|
||||||
|
if(!source.substr(start).match(/^\s*$/)){
|
||||||
|
var doc = domBuilder.document;
|
||||||
|
var text = doc.createTextNode(source.substr(start));
|
||||||
|
doc.appendChild(text);
|
||||||
|
domBuilder.currentElement = text;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(i>start){
|
||||||
|
appendText(i);
|
||||||
|
}
|
||||||
|
switch(source.charAt(i+1)){
|
||||||
|
case '/':
|
||||||
|
var end = source.indexOf('>',i+3);
|
||||||
|
var tagName = source.substring(i+2,end);
|
||||||
|
var config;
|
||||||
|
if (parseStack.length > 1) {
|
||||||
|
config = parseStack.pop();
|
||||||
|
} else {
|
||||||
|
errorHandler.fatalError("end tag name not found for: "+tagName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var localNSMap = config.localNSMap;
|
||||||
|
|
||||||
|
if(config.tagName != tagName){
|
||||||
|
errorHandler.fatalError("end tag name: " + tagName + " does not match the current start tagName: "+config.tagName );
|
||||||
|
}
|
||||||
|
domBuilder.endElement(config.uri,config.localName,tagName);
|
||||||
|
if(localNSMap){
|
||||||
|
for(var prefix in localNSMap){
|
||||||
|
domBuilder.endPrefixMapping(prefix) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end++;
|
||||||
|
break;
|
||||||
|
// end elment
|
||||||
|
case '?':// <?...?>
|
||||||
|
locator&&position(i);
|
||||||
|
end = parseInstruction(source,i,domBuilder);
|
||||||
|
break;
|
||||||
|
case '!':// <!doctype,<![CDATA,<!--
|
||||||
|
locator&&position(i);
|
||||||
|
end = parseDCC(source,i,domBuilder,errorHandler);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
try{
|
||||||
|
locator&&position(i);
|
||||||
|
|
||||||
|
var el = new ElementAttributes();
|
||||||
|
|
||||||
|
//elStartEnd
|
||||||
|
var end = parseElementStartPart(source,i,el,entityReplacer,errorHandler);
|
||||||
|
var len = el.length;
|
||||||
|
//position fixed
|
||||||
|
if(len && locator){
|
||||||
|
var backup = copyLocator(locator,{});
|
||||||
|
for(var i = 0;i<len;i++){
|
||||||
|
var a = el[i];
|
||||||
|
position(a.offset);
|
||||||
|
a.offset = copyLocator(locator,{});
|
||||||
|
}
|
||||||
|
copyLocator(backup,locator);
|
||||||
|
}
|
||||||
|
if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
|
||||||
|
el.closed = true;
|
||||||
|
if(!entityMap.nbsp){
|
||||||
|
errorHandler.warning('unclosed xml attribute');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendElement(el,domBuilder,parseStack);
|
||||||
|
|
||||||
|
|
||||||
|
if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
|
||||||
|
end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
|
||||||
|
}else{
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
errorHandler.error('element parse error: '+e);
|
||||||
|
end = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(end<0){
|
||||||
|
//TODO: 这里有可能sax回退,有位置错误风险
|
||||||
|
appendText(i+1);
|
||||||
|
}else{
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function copyLocator(f,t){
|
||||||
|
t.lineNumber = f.lineNumber;
|
||||||
|
t.columnNumber = f.columnNumber;
|
||||||
|
return t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
|
||||||
|
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
||||||
|
*/
|
||||||
|
function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
|
||||||
|
var attrName;
|
||||||
|
var value;
|
||||||
|
var p = ++start;
|
||||||
|
var s = S_TAG;//status
|
||||||
|
while(true){
|
||||||
|
var c = source.charAt(p);
|
||||||
|
switch(c){
|
||||||
|
case '=':
|
||||||
|
if(s === S_ATTR){//attrName
|
||||||
|
attrName = source.slice(start,p);
|
||||||
|
s = S_EQ;
|
||||||
|
}else if(s === S_ATTR_S){
|
||||||
|
s = S_EQ;
|
||||||
|
}else{
|
||||||
|
//fatalError: equal must after attrName or space after attrName
|
||||||
|
throw new Error('attribute equal must after attrName');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
case '"':
|
||||||
|
if(s === S_EQ){//equal
|
||||||
|
start = p+1;
|
||||||
|
p = source.indexOf(c,start)
|
||||||
|
if(p>0){
|
||||||
|
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
el.add(attrName,value,start-1);
|
||||||
|
s = S_E;
|
||||||
|
}else{
|
||||||
|
//fatalError: no end quot match
|
||||||
|
throw new Error('attribute value no end \''+c+'\' match');
|
||||||
|
}
|
||||||
|
}else if(s == S_V){
|
||||||
|
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
//console.log(attrName,value,start,p)
|
||||||
|
el.add(attrName,value,start);
|
||||||
|
//console.dir(el)
|
||||||
|
errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
|
||||||
|
start = p+1;
|
||||||
|
s = S_E
|
||||||
|
}else{
|
||||||
|
//fatalError: no equal before
|
||||||
|
throw new Error('attribute value must after "="');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));
|
||||||
|
case S_E:
|
||||||
|
case S_S:
|
||||||
|
case S_C:
|
||||||
|
s = S_C;
|
||||||
|
el.closed = true;
|
||||||
|
case S_V:
|
||||||
|
case S_ATTR:
|
||||||
|
case S_ATTR_S:
|
||||||
|
break;
|
||||||
|
//case S_EQ:
|
||||||
|
default:
|
||||||
|
throw new Error("attribute invalid close char('/')")
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ''://end document
|
||||||
|
//throw new Error('unexpected end of input')
|
||||||
|
errorHandler.error('unexpected end of input');
|
||||||
|
case '>':
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));
|
||||||
|
case S_E:
|
||||||
|
case S_S:
|
||||||
|
case S_C:
|
||||||
|
break;//normal
|
||||||
|
case S_V://Compatible state
|
||||||
|
case S_ATTR:
|
||||||
|
value = source.slice(start,p);
|
||||||
|
if(value.slice(-1) === '/'){
|
||||||
|
el.closed = true;
|
||||||
|
value = value.slice(0,-1)
|
||||||
|
}
|
||||||
|
case S_ATTR_S:
|
||||||
|
if(s === S_ATTR_S){
|
||||||
|
value = attrName;
|
||||||
|
}
|
||||||
|
if(s == S_V){
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
||||||
|
el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
|
||||||
|
}else{
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
|
||||||
|
el.add(value,value,start)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_EQ:
|
||||||
|
throw new Error('attribute value missed!!');
|
||||||
|
}
|
||||||
|
// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
|
||||||
|
return p;
|
||||||
|
/*xml space '\x20' | #x9 | #xD | #xA; */
|
||||||
|
case '\u0080':
|
||||||
|
c = ' ';
|
||||||
|
default:
|
||||||
|
if(c<= ' '){//space
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));//tagName
|
||||||
|
s = S_S;
|
||||||
|
break;
|
||||||
|
case S_ATTR:
|
||||||
|
attrName = source.slice(start,p)
|
||||||
|
s = S_ATTR_S;
|
||||||
|
break;
|
||||||
|
case S_V:
|
||||||
|
var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
||||||
|
el.add(attrName,value,start)
|
||||||
|
case S_E:
|
||||||
|
s = S_S;
|
||||||
|
break;
|
||||||
|
//case S_S:
|
||||||
|
//case S_EQ:
|
||||||
|
//case S_ATTR_S:
|
||||||
|
// void();break;
|
||||||
|
//case S_C:
|
||||||
|
//ignore warning
|
||||||
|
}
|
||||||
|
}else{//not space
|
||||||
|
//S_TAG, S_ATTR, S_EQ, S_V
|
||||||
|
//S_ATTR_S, S_E, S_S, S_C
|
||||||
|
switch(s){
|
||||||
|
//case S_TAG:void();break;
|
||||||
|
//case S_ATTR:void();break;
|
||||||
|
//case S_V:void();break;
|
||||||
|
case S_ATTR_S:
|
||||||
|
errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!')
|
||||||
|
el.add(attrName,attrName,start);
|
||||||
|
start = p;
|
||||||
|
s = S_ATTR;
|
||||||
|
break;
|
||||||
|
case S_E:
|
||||||
|
errorHandler.warning('attribute space is required"'+attrName+'"!!')
|
||||||
|
case S_S:
|
||||||
|
s = S_ATTR;
|
||||||
|
start = p;
|
||||||
|
break;
|
||||||
|
case S_EQ:
|
||||||
|
s = S_V;
|
||||||
|
start = p;
|
||||||
|
break;
|
||||||
|
case S_C:
|
||||||
|
throw new Error("elements closed character '/' and '>' must be connected to");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
||||||
|
*/
|
||||||
|
function appendElement(el,domBuilder,parseStack){
|
||||||
|
var tagName = el.tagName;
|
||||||
|
var localNSMap = null;
|
||||||
|
var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
|
||||||
|
var i = el.length;
|
||||||
|
while(i--){
|
||||||
|
var a = el[i];
|
||||||
|
var qName = a.qName;
|
||||||
|
var value = a.value;
|
||||||
|
var nsp = qName.indexOf(':');
|
||||||
|
if(nsp>0){
|
||||||
|
var prefix = a.prefix = qName.slice(0,nsp);
|
||||||
|
var localName = qName.slice(nsp+1);
|
||||||
|
var nsPrefix = prefix === 'xmlns' && localName
|
||||||
|
}else{
|
||||||
|
localName = qName;
|
||||||
|
prefix = null
|
||||||
|
nsPrefix = qName === 'xmlns' && ''
|
||||||
|
}
|
||||||
|
//can not set prefix,because prefix !== ''
|
||||||
|
a.localName = localName ;
|
||||||
|
//prefix == null for no ns prefix attribute
|
||||||
|
if(nsPrefix !== false){//hack!!
|
||||||
|
if(localNSMap == null){
|
||||||
|
localNSMap = {}
|
||||||
|
//console.log(currentNSMap,0)
|
||||||
|
_copy(currentNSMap,currentNSMap={})
|
||||||
|
//console.log(currentNSMap,1)
|
||||||
|
}
|
||||||
|
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
||||||
|
a.uri = 'http://www.w3.org/2000/xmlns/'
|
||||||
|
domBuilder.startPrefixMapping(nsPrefix, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var i = el.length;
|
||||||
|
while(i--){
|
||||||
|
a = el[i];
|
||||||
|
var prefix = a.prefix;
|
||||||
|
if(prefix){//no prefix attribute has no namespace
|
||||||
|
if(prefix === 'xml'){
|
||||||
|
a.uri = 'http://www.w3.org/XML/1998/namespace';
|
||||||
|
}if(prefix !== 'xmlns'){
|
||||||
|
a.uri = currentNSMap[prefix]
|
||||||
|
|
||||||
|
//{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nsp = tagName.indexOf(':');
|
||||||
|
if(nsp>0){
|
||||||
|
prefix = el.prefix = tagName.slice(0,nsp);
|
||||||
|
localName = el.localName = tagName.slice(nsp+1);
|
||||||
|
}else{
|
||||||
|
prefix = null;//important!!
|
||||||
|
localName = el.localName = tagName;
|
||||||
|
}
|
||||||
|
//no prefix element has default namespace
|
||||||
|
var ns = el.uri = currentNSMap[prefix || ''];
|
||||||
|
domBuilder.startElement(ns,localName,tagName,el);
|
||||||
|
//endPrefixMapping and startPrefixMapping have not any help for dom builder
|
||||||
|
//localNSMap = null
|
||||||
|
if(el.closed){
|
||||||
|
domBuilder.endElement(ns,localName,tagName);
|
||||||
|
if(localNSMap){
|
||||||
|
for(prefix in localNSMap){
|
||||||
|
domBuilder.endPrefixMapping(prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
el.currentNSMap = currentNSMap;
|
||||||
|
el.localNSMap = localNSMap;
|
||||||
|
parseStack.push(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
|
||||||
|
if(/^(?:script|textarea)$/i.test(tagName)){
|
||||||
|
var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
|
||||||
|
var text = source.substring(elStartEnd+1,elEndStart);
|
||||||
|
if(/[&<]/.test(text)){
|
||||||
|
if(/^script$/i.test(tagName)){
|
||||||
|
//if(!/\]\]>/.test(text)){
|
||||||
|
//lexHandler.startCDATA();
|
||||||
|
domBuilder.characters(text,0,text.length);
|
||||||
|
//lexHandler.endCDATA();
|
||||||
|
return elEndStart;
|
||||||
|
//}
|
||||||
|
}//}else{//text area
|
||||||
|
text = text.replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
domBuilder.characters(text,0,text.length);
|
||||||
|
return elEndStart;
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elStartEnd+1;
|
||||||
|
}
|
||||||
|
function fixSelfClosed(source,elStartEnd,tagName,closeMap){
|
||||||
|
//if(tagName in closeMap){
|
||||||
|
var pos = closeMap[tagName];
|
||||||
|
if(pos == null){
|
||||||
|
//console.log(tagName)
|
||||||
|
pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>')
|
||||||
|
}
|
||||||
|
return pos<elStartEnd;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
function _copy(source,target){
|
||||||
|
for(var n in source){target[n] = source[n]}
|
||||||
|
}
|
||||||
|
function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
|
||||||
|
var next= source.charAt(start+2)
|
||||||
|
switch(next){
|
||||||
|
case '-':
|
||||||
|
if(source.charAt(start + 3) === '-'){
|
||||||
|
var end = source.indexOf('-->',start+4);
|
||||||
|
//append comment source.substring(4,end)//<!--
|
||||||
|
if(end>start){
|
||||||
|
domBuilder.comment(source,start+4,end-start-4);
|
||||||
|
return end+3;
|
||||||
|
}else{
|
||||||
|
errorHandler.error("Unclosed comment");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if(source.substr(start+3,6) == 'CDATA['){
|
||||||
|
var end = source.indexOf(']]>',start+9);
|
||||||
|
domBuilder.startCDATA();
|
||||||
|
domBuilder.characters(source,start+9,end-start-9);
|
||||||
|
domBuilder.endCDATA()
|
||||||
|
return end+3;
|
||||||
|
}
|
||||||
|
//<!DOCTYPE
|
||||||
|
//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
|
||||||
|
var matchs = split(source,start);
|
||||||
|
var len = matchs.length;
|
||||||
|
if(len>1 && /!doctype/i.test(matchs[0][0])){
|
||||||
|
var name = matchs[1][0];
|
||||||
|
var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
|
||||||
|
var sysid = len>4 && matchs[4][0];
|
||||||
|
var lastMatch = matchs[len-1]
|
||||||
|
domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
|
||||||
|
sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
|
||||||
|
domBuilder.endDTD();
|
||||||
|
|
||||||
|
return lastMatch.index+lastMatch[0].length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function parseInstruction(source,start,domBuilder){
|
||||||
|
var end = source.indexOf('?>',start);
|
||||||
|
if(end){
|
||||||
|
var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
|
||||||
|
if(match){
|
||||||
|
var len = match[0].length;
|
||||||
|
domBuilder.processingInstruction(match[1], match[2]) ;
|
||||||
|
return end+2;
|
||||||
|
}else{//error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source
|
||||||
|
*/
|
||||||
|
function ElementAttributes(source){
|
||||||
|
|
||||||
|
}
|
||||||
|
ElementAttributes.prototype = {
|
||||||
|
setTagName:function(tagName){
|
||||||
|
if(!tagNamePattern.test(tagName)){
|
||||||
|
throw new Error('invalid tagName:'+tagName)
|
||||||
|
}
|
||||||
|
this.tagName = tagName
|
||||||
|
},
|
||||||
|
add:function(qName,value,offset){
|
||||||
|
if(!tagNamePattern.test(qName)){
|
||||||
|
throw new Error('invalid attribute:'+qName)
|
||||||
|
}
|
||||||
|
this[this.length++] = {qName:qName,value:value,offset:offset}
|
||||||
|
},
|
||||||
|
length:0,
|
||||||
|
getLocalName:function(i){return this[i].localName},
|
||||||
|
getOffset:function(i){return this[i].offset},
|
||||||
|
getQName:function(i){return this[i].qName},
|
||||||
|
getURI:function(i){return this[i].uri},
|
||||||
|
getValue:function(i){return this[i].value}
|
||||||
|
// ,getIndex:function(uri, localName)){
|
||||||
|
// if(localName){
|
||||||
|
//
|
||||||
|
// }else{
|
||||||
|
// var qName = uri
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
|
||||||
|
// getType:function(uri,localName){}
|
||||||
|
// getType:function(i){},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function _set_proto_(thiz,parent){
|
||||||
|
thiz.__proto__ = parent;
|
||||||
|
return thiz;
|
||||||
|
}
|
||||||
|
if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
|
||||||
|
_set_proto_ = function(thiz,parent){
|
||||||
|
function p(){};
|
||||||
|
p.prototype = parent;
|
||||||
|
p = new p();
|
||||||
|
for(parent in thiz){
|
||||||
|
p[parent] = thiz[parent];
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function split(source,start){
|
||||||
|
var match;
|
||||||
|
var buf = [];
|
||||||
|
var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
|
||||||
|
reg.lastIndex = start;
|
||||||
|
reg.exec(source);//skip <
|
||||||
|
while(match = reg.exec(source)){
|
||||||
|
buf.push(match);
|
||||||
|
if(match[1])return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return XMLReader;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
92
lib/ace/mode/xml_worker.js
Normal file
92
lib/ace/mode/xml_worker.js
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* ***** 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 oop = require("../lib/oop");
|
||||||
|
var lang = require("../lib/lang");
|
||||||
|
var Mirror = require("../worker/mirror").Mirror;
|
||||||
|
var DOMParser = require("./xml/dom-parser").DOMParser;
|
||||||
|
|
||||||
|
var Worker = exports.Worker = function(sender) {
|
||||||
|
Mirror.call(this, sender);
|
||||||
|
this.setTimeout(400);
|
||||||
|
this.context = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
oop.inherits(Worker, Mirror);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
this.setOptions = function(options) {
|
||||||
|
this.context = options.context;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onUpdate = function() {
|
||||||
|
var value = this.doc.getValue();
|
||||||
|
if (!value)
|
||||||
|
return;
|
||||||
|
var parser = new DOMParser();
|
||||||
|
var errors = [];
|
||||||
|
parser.options.errorHandler = {
|
||||||
|
fatalError: function(fullMsg, errorMsg, locator) {
|
||||||
|
errors.push({
|
||||||
|
row: locator.lineNumber,
|
||||||
|
column: locator.columnNumber,
|
||||||
|
text: errorMsg,
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(fullMsg, errorMsg, locator) {
|
||||||
|
errors.push({
|
||||||
|
row: locator.lineNumber,
|
||||||
|
column: locator.columnNumber,
|
||||||
|
text: errorMsg,
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
warning: function(fullMsg, errorMsg, locator) {
|
||||||
|
errors.push({
|
||||||
|
row: locator.lineNumber,
|
||||||
|
column: locator.columnNumber,
|
||||||
|
text: errorMsg,
|
||||||
|
type: "warning"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.parseFromString(value);
|
||||||
|
this.sender.emit("error", errors);
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(Worker.prototype);
|
||||||
|
|
||||||
|
});
|
||||||
7
lib/ace/snippets/abc.js
Normal file
7
lib/ace/snippets/abc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
define(function(require, exports, module) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
exports.snippetText = require("../requirejs/text!./abc.snippets");
|
||||||
|
exports.scope = "abc";
|
||||||
|
|
||||||
|
});
|
||||||
31
lib/ace/snippets/abc.snippets
Normal file
31
lib/ace/snippets/abc.snippets
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
snippet zupfnoter.print
|
||||||
|
%%%%hn.print {"startpos": ${1:pos_y}, "t":"${2:title}", "v":[${3:voices}], "s":[[${4:syncvoices}1,2]], "f":[${5:flowlines}], "sf":[${6:subflowlines}], "j":[${7:jumplines}]}
|
||||||
|
|
||||||
|
snippet zupfnoter.note
|
||||||
|
%%%%hn.note {"pos": [${1:pos_x},${2:pos_y}], "text": "${3:text}", "style": "${4:style}"}
|
||||||
|
|
||||||
|
snippet zupfnoter.annotation
|
||||||
|
%%%%hn.annotation {"id": "${1:id}", "pos": [${2:pos}], "text": "${3:text}"}
|
||||||
|
|
||||||
|
snippet zupfnoter.lyrics
|
||||||
|
%%%%hn.lyrics {"pos": [${1:x_pos},${2:y_pos}]}
|
||||||
|
|
||||||
|
snippet zupfnoter.legend
|
||||||
|
%%%%hn.legend {"pos": [${1:x_pos},${2:y_pos}]}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
snippet zupfnoter.target
|
||||||
|
"^:${1:target}"
|
||||||
|
|
||||||
|
snippet zupfnoter.goto
|
||||||
|
"^@${1:target}@${2:distance}"
|
||||||
|
|
||||||
|
snippet zupfnoter.annotationref
|
||||||
|
"^#${1:target}"
|
||||||
|
|
||||||
|
snippet zupfnoter.annotation
|
||||||
|
"^!${1:text}@${2:x_offset},${3:y_offset}"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -750,7 +750,7 @@ var VirtualRenderer = function(container, theme) {
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.getVScrollBarAlwaysVisible = function() {
|
this.getVScrollBarAlwaysVisible = function() {
|
||||||
return this.$hScrollBarAlwaysVisible;
|
return this.$vScrollBarAlwaysVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
95
static.js
95
static.js
|
|
@ -12,35 +12,98 @@ var http = require("http")
|
||||||
if (!fs.exists)
|
if (!fs.exists)
|
||||||
fs.exists = path.exists;
|
fs.exists = path.exists;
|
||||||
|
|
||||||
http.createServer(function(request, response) {
|
var allowSave = process.argv.indexOf("--allow-save") != -1;
|
||||||
|
|
||||||
var uri = url.parse(request.url).pathname
|
http.createServer(function(req, res) {
|
||||||
|
var uri = url.parse(req.url).pathname
|
||||||
, filename = path.join(process.cwd(), uri);
|
, filename = path.join(process.cwd(), uri);
|
||||||
|
|
||||||
|
if (req.method == "PUT") {
|
||||||
|
if (!allowSave)
|
||||||
|
return error(res, 404, "Saving not allowed pass --allow-save to enable");
|
||||||
|
save(req, res, filename);
|
||||||
|
}
|
||||||
|
|
||||||
fs.exists(filename, function(exists) {
|
fs.exists(filename, function(exists) {
|
||||||
if(!exists) {
|
if (!exists)
|
||||||
response.writeHead(404, {"Content-Type": "text/plain"});
|
return error(res, 404, "404 Not Found\n");
|
||||||
response.write("404 Not Found\n");
|
|
||||||
response.end();
|
if (fs.statSync(filename).isDirectory()) {
|
||||||
|
var files = fs.readdirSync(filename);
|
||||||
|
res.writeHead(200, {"Content-Type": "text/html"});
|
||||||
|
|
||||||
|
files.push(".", "..");
|
||||||
|
var html = files.map(function(name) {
|
||||||
|
var href = uri + "/" + name;
|
||||||
|
href = href.replace(/[\/\\]+/g, "/").replace(/\/$/g, "");
|
||||||
|
if (fs.statSync(filename + "/" + name + "/").isDirectory())
|
||||||
|
href += "/";
|
||||||
|
return "<a href='" + href + "'>" + name + "</a><br>";
|
||||||
|
});
|
||||||
|
|
||||||
|
res._hasBody && res.write(html.join(""));
|
||||||
|
res.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
|
|
||||||
|
|
||||||
fs.readFile(filename, "binary", function(err, file) {
|
fs.readFile(filename, "binary", function(err, file) {
|
||||||
if(err) {
|
if (err) {
|
||||||
response.writeHead(500, {"Content-Type": "text/plain"});
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
||||||
response.write(err + "\n");
|
res.write(err + "\n");
|
||||||
response.end();
|
res.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentType = mime.lookup(filename) || "text/plain";
|
var contentType = mime.lookup(filename) || "text/plain";
|
||||||
response.writeHead(200, {"Content-Type": contentType});
|
res.writeHead(200, { "Content-Type": contentType });
|
||||||
response.write(file, "binary");
|
res.write(file, "binary");
|
||||||
response.end();
|
res.end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).listen(port, ip);
|
}).listen(port, ip);
|
||||||
|
|
||||||
console.log("http://localhost:" + port);
|
function error(res, status, message, error) {
|
||||||
|
console.error(error || message);
|
||||||
|
res.writeHead(status, { "Content-Type": "text/plain" });
|
||||||
|
res.write(message);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(req, res, filePath) {
|
||||||
|
var data = "";
|
||||||
|
req.on("data", function(chunk) {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
req.on("error", function() {
|
||||||
|
error(res, 404, "Could't save file");
|
||||||
|
});
|
||||||
|
req.on("end", function() {
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(filePath, data);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return error(res, 404, "Could't save file", e);
|
||||||
|
}
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.end("OK");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalIps() {
|
||||||
|
var os = require("os");
|
||||||
|
|
||||||
|
var interfaces = os.networkInterfaces ? os.networkInterfaces() : {};
|
||||||
|
var addresses = [];
|
||||||
|
for (var k in interfaces) {
|
||||||
|
for (var k2 in interfaces[k]) {
|
||||||
|
var address = interfaces[k][k2];
|
||||||
|
if (address.family === "IPv4" && !address.internal) {
|
||||||
|
addresses.push(address.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("http://" + (ip == "0.0.0.0" ? getLocalIps()[0] : ip) + ":" + port);
|
||||||
|
|
||||||
|
|
|
||||||
112
static.py
112
static.py
|
|
@ -32,7 +32,9 @@ import time
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
from os import path, stat, getcwd
|
from os import path, stat, getcwd
|
||||||
|
from fnmatch import fnmatch
|
||||||
from wsgiref import util
|
from wsgiref import util
|
||||||
|
from wsgiref.validate import validator
|
||||||
from wsgiref.headers import Headers
|
from wsgiref.headers import Headers
|
||||||
from wsgiref.simple_server import make_server
|
from wsgiref.simple_server import make_server
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
@ -84,6 +86,8 @@ class Cling(object):
|
||||||
not_modified = StatusApp('304 Not Modified', "")
|
not_modified = StatusApp('304 Not Modified', "")
|
||||||
moved_permanently = StatusApp('301 Moved Permanently')
|
moved_permanently = StatusApp('301 Moved Permanently')
|
||||||
method_not_allowed = StatusApp('405 Method Not Allowed')
|
method_not_allowed = StatusApp('405 Method Not Allowed')
|
||||||
|
success_no_content = StatusApp('204 No Content', "")
|
||||||
|
server_error = StatusApp('500 Internal Server Error')
|
||||||
|
|
||||||
def __init__(self, root, **kw):
|
def __init__(self, root, **kw):
|
||||||
"""Just set the root and any other attribs passes via **kw."""
|
"""Just set the root and any other attribs passes via **kw."""
|
||||||
|
|
@ -93,9 +97,6 @@ class Cling(object):
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
"""Respond to a request when called in the usual WSGI way."""
|
"""Respond to a request when called in the usual WSGI way."""
|
||||||
if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'):
|
|
||||||
headers = [('Allow', 'GET, HEAD')]
|
|
||||||
return self.method_not_allowed(environ, start_response, headers)
|
|
||||||
path_info = environ.get('PATH_INFO', '')
|
path_info = environ.get('PATH_INFO', '')
|
||||||
full_path = self._full_path(path_info)
|
full_path = self._full_path(path_info)
|
||||||
if not self._is_under_root(full_path):
|
if not self._is_under_root(full_path):
|
||||||
|
|
@ -109,6 +110,23 @@ class Cling(object):
|
||||||
return self.moved_permanently(environ, start_response, headers)
|
return self.moved_permanently(environ, start_response, headers)
|
||||||
else:
|
else:
|
||||||
full_path = self._full_path(path_info + self.index_file)
|
full_path = self._full_path(path_info + self.index_file)
|
||||||
|
try:
|
||||||
|
sz = int(environ['CONTENT_LENGTH'])
|
||||||
|
except:
|
||||||
|
sz = 0
|
||||||
|
if environ['REQUEST_METHOD'] == 'PUT' and sz > 0:
|
||||||
|
for putglob in self.puttable:
|
||||||
|
if fnmatch(path_info, putglob):
|
||||||
|
data = environ['wsgi.input'].read(sz)
|
||||||
|
try:
|
||||||
|
with open(full_path, "wb") as f: f.write(data)
|
||||||
|
return self.success_no_content(environ, start_response)
|
||||||
|
except:
|
||||||
|
print sys.exc_info()[1]
|
||||||
|
return self.server_error(environ, start_response)
|
||||||
|
if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'):
|
||||||
|
headers = [('Allow', 'GET, HEAD')]
|
||||||
|
return self.method_not_allowed(environ, start_response, headers)
|
||||||
content_type = self._guess_type(full_path)
|
content_type = self._guess_type(full_path)
|
||||||
try:
|
try:
|
||||||
etag, last_modified = self._conditions(full_path, environ)
|
etag, last_modified = self._conditions(full_path, environ)
|
||||||
|
|
@ -191,52 +209,90 @@ def cling_wrap(package_name, dir_name, **kw):
|
||||||
|
|
||||||
|
|
||||||
def command():
|
def command():
|
||||||
parser = OptionParser(usage="%prog DIR [HOST][:][PORT]",
|
usage = "%prog [--help] [-d DIR] [-l [HOST][:PORT]] [-p GLOB[,GLOB...]]"
|
||||||
version="static 0.3.6")
|
parser = OptionParser(usage=usage, version="static 0.3.6")
|
||||||
|
parser.add_option("-d", "--dir", dest="rootdir", default=".",
|
||||||
|
help="Root directory to serve. Defaults to '.' .", metavar="DIR")
|
||||||
|
parser.add_option("-l", "--listen", dest="listen", default="127.0.0.1:8888",
|
||||||
|
help="Listen on this interface (given by its hostname or IP) and port."+
|
||||||
|
" HOST defaults to 127.0.0.1. PORT defaults to 8888. "+
|
||||||
|
"Leave HOST empty to listen on all interfaces (INSECURE!).",
|
||||||
|
metavar="[HOST][:PORT]")
|
||||||
|
parser.add_option("-p", "--puttable", dest="puttable", default="",
|
||||||
|
help="Comma or space-separated list of request paths for which to"+
|
||||||
|
" permit PUT requests. Each path is a glob pattern that may "+
|
||||||
|
"contain wildcard characters '*' and/or '?'. "+
|
||||||
|
"'*' matches any sequence of characters, including the empty"+
|
||||||
|
" string. '?' matches exactly 1 arbitrary character. "+
|
||||||
|
"NOTE: Both '*' and '?' match slashes and dots. "+
|
||||||
|
"I.e. --puttable=* makes every file under DIR writable!",
|
||||||
|
metavar="GLOB[,GLOB...]")
|
||||||
|
parser.add_option("--validate", dest="validate", action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="Enable HTTP validation. You don't need this unless "+
|
||||||
|
"you're developing static.py itself.")
|
||||||
|
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
if len(args) in (1, 2):
|
if len(args) > 0:
|
||||||
if len(args) == 2:
|
parser.print_help(sys.stderr)
|
||||||
parts = args[1].split(":")
|
sys.exit(1)
|
||||||
|
|
||||||
|
parts = options.listen.split(":")
|
||||||
if len(parts) == 1:
|
if len(parts) == 1:
|
||||||
|
try: # if the the listen argument consists only of a port number
|
||||||
|
port = int(parts[0])
|
||||||
|
host = None
|
||||||
|
except: # could not parse as port number => must be a host IP or name
|
||||||
host = parts[0]
|
host = parts[0]
|
||||||
port = None
|
port = None
|
||||||
elif len(parts) == 2:
|
elif len(parts) == 2:
|
||||||
host, port = parts
|
host, port = parts
|
||||||
else:
|
else:
|
||||||
sys.exit("Invalid host:port specification.")
|
sys.exit("Invalid host:port specification.")
|
||||||
elif len(args) == 1:
|
|
||||||
host, port = None, None
|
|
||||||
if not host:
|
if not host:
|
||||||
host = '0.0.0.0'
|
host = '0.0.0.0'
|
||||||
if not port:
|
if not port:
|
||||||
port = 8888
|
port = 8888
|
||||||
try:
|
try:
|
||||||
port = int(port)
|
port = int(port)
|
||||||
|
if port <= 0 or port > 65535: raise ValueError
|
||||||
except:
|
except:
|
||||||
sys.exit("Invalid host:port specification.")
|
sys.exit("Invalid host:port specification.")
|
||||||
app = Cling(args[0])
|
|
||||||
|
puttable = set(path.abspath(p) for p in
|
||||||
|
options.puttable.replace(","," ").split())
|
||||||
|
if puttable and host not in ('127.0.0.1', 'localhost'):
|
||||||
|
print("Permitting PUT access for non-localhost connections may be unwise.")
|
||||||
|
|
||||||
|
options.rootdir = path.abspath(options.rootdir)
|
||||||
|
|
||||||
|
for p in puttable:
|
||||||
|
if not p.startswith(options.rootdir):
|
||||||
|
sys.exit("puttable path '%s' not under root '%s'" % (p, options.rootdir))
|
||||||
|
|
||||||
|
# cut off root prefix from puttable paths
|
||||||
|
puttable = set(p[len(options.rootdir):] for p in puttable)
|
||||||
|
|
||||||
|
app = Cling(options.rootdir, puttable=puttable)
|
||||||
|
|
||||||
|
if options.validate:
|
||||||
|
app = validator(app)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
print "Serving %s to http://%s:%d" % (options.rootdir, host, port)
|
||||||
|
if puttable:
|
||||||
|
print("The following paths (relative to server root) may be "+
|
||||||
|
"OVERWRITTEN via HTTP PUT.")
|
||||||
|
for p in puttable:
|
||||||
|
print p
|
||||||
make_server(host, port, app).serve_forever()
|
make_server(host, port, app).serve_forever()
|
||||||
except KeyboardInterrupt, ki:
|
except KeyboardInterrupt, ki:
|
||||||
print "Cio, baby!"
|
|
||||||
except:
|
|
||||||
sys.exit("Problem initializing server.")
|
|
||||||
else:
|
|
||||||
parser.print_help(sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def test():
|
|
||||||
from wsgiref.validate import validator
|
|
||||||
app = Cling(getcwd())
|
|
||||||
try:
|
|
||||||
print "Serving " + getcwd() + " to http://localhost:8888"
|
|
||||||
make_server('0.0.0.0', 8888, validator(app)).serve_forever()
|
|
||||||
except KeyboardInterrupt, ki:
|
|
||||||
print ""
|
|
||||||
print "Ciao, baby!"
|
print "Ciao, baby!"
|
||||||
|
except:
|
||||||
|
sys.exit("Problem initializing server: %s" % sys.exc_info()[1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test()
|
command()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ function main(displayName, extRe) {
|
||||||
var demoFileExt = extRe.split("|")[0] || name;
|
var demoFileExt = extRe.split("|")[0] || name;
|
||||||
var demoFileName = demoFileExt[0] == "^" ? demoFileExt.substr(1) : name + "." + demoFileExt;
|
var demoFileName = demoFileExt[0] == "^" ? demoFileExt.substr(1) : name + "." + demoFileExt;
|
||||||
var demoFilePath = lib.AceRoot + "demo/kitchen-sink/docs/" + demoFileName;
|
var demoFilePath = lib.AceRoot + "demo/kitchen-sink/docs/" + demoFileName;
|
||||||
fs.writeFileSync(demoFilePath, "TODO add a nice demo!", "utf8");
|
fs.writeFileSync(demoFilePath, "TODO add a nice demo!\nTry to keep it short!", "utf8");
|
||||||
console.log("Created demo file at: " + path.normalize(demoFilePath));
|
console.log("Created demo file at: " + path.normalize(demoFilePath));
|
||||||
|
|
||||||
/** mode **/
|
/** mode **/
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
border-bottom: solid 1px;
|
border-bottom: solid 1px;
|
||||||
}
|
}
|
||||||
.separator-h {
|
.separator-h {
|
||||||
padding: 0 20px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
#closeBtn {
|
#closeBtn {
|
||||||
background: rgba(245, 146, 146, 0.5);
|
background: rgba(245, 146, 146, 0.5);
|
||||||
|
|
@ -59,6 +59,7 @@
|
||||||
<select id="modeEl" size="1"></select>
|
<select id="modeEl" size="1"></select>
|
||||||
<input type="button" value="⟳" title="sync" id="syncToMode"></select>
|
<input type="button" value="⟳" title="sync" id="syncToMode"></select>
|
||||||
<span id="tablist"></span>
|
<span id="tablist"></span>
|
||||||
|
<input type="button" value="Save" id="saveButton1"></select>
|
||||||
<span class="separator-h"></span>
|
<span class="separator-h"></span>
|
||||||
<label for="autorunEl">live preview</label>
|
<label for="autorunEl">live preview</label>
|
||||||
<input type="checkbox" label="autorun" id="autorunEl" checked>
|
<input type="checkbox" label="autorun" id="autorunEl" checked>
|
||||||
|
|
@ -70,6 +71,7 @@
|
||||||
<label for="themeEl">Theme</label>
|
<label for="themeEl">Theme</label>
|
||||||
<select id="themeEl" size="1" value="textmate"></select>
|
<select id="themeEl" size="1" value="textmate"></select>
|
||||||
<span class="separator-h"></span>
|
<span class="separator-h"></span>
|
||||||
|
<input type="button" value="Save" id="saveButton2"></select>
|
||||||
<label for="doc">Document</label>
|
<label for="doc">Document</label>
|
||||||
<select id="doc" size="1"></select>
|
<select id="doc" size="1"></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ util.bindDropdown("doc", function(value) {
|
||||||
doclist.loadDoc(value, function(session) {
|
doclist.loadDoc(value, function(session) {
|
||||||
if (session) {
|
if (session) {
|
||||||
editor2.setSession(session);
|
editor2.setSession(session);
|
||||||
|
updateSaveButtonState(null, editor2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -60,6 +61,7 @@ util.bindDropdown("doc", function(value) {
|
||||||
var modeEl = document.getElementById("modeEl");
|
var modeEl = document.getElementById("modeEl");
|
||||||
util.fillDropdown(modeEl, modelist.modes);
|
util.fillDropdown(modeEl, modelist.modes);
|
||||||
var modeSessions = {};
|
var modeSessions = {};
|
||||||
|
|
||||||
util.bindDropdown(modeEl, function(value) {
|
util.bindDropdown(modeEl, function(value) {
|
||||||
if (modeSessions[value]) {
|
if (modeSessions[value]) {
|
||||||
editor1.setSession(modeSessions[value]);
|
editor1.setSession(modeSessions[value]);
|
||||||
|
|
@ -68,14 +70,17 @@ util.bindDropdown(modeEl, function(value) {
|
||||||
}
|
}
|
||||||
var hp = "./lib/ace/mode/" + value + "_highlight_rules.js";
|
var hp = "./lib/ace/mode/" + value + "_highlight_rules.js";
|
||||||
net.get(hp, function(text) {
|
net.get(hp, function(text) {
|
||||||
text = util.stripLeadingComments(text);
|
|
||||||
|
|
||||||
var session = new EditSession(text);
|
var session = new EditSession(text);
|
||||||
session.setUndoManager(new UndoManager());
|
session.setUndoManager(new UndoManager());
|
||||||
|
|
||||||
modeSessions[value] = session;
|
modeSessions[value] = session;
|
||||||
session.setMode("ace/mode/javascript");
|
session.setMode("ace/mode/javascript", function() {
|
||||||
|
if (session.getLine(0).match(/^\s*\//))
|
||||||
|
session.toggleFoldWidget(0); // fold licence comment
|
||||||
|
});
|
||||||
|
|
||||||
editor1.setSession(modeSessions[value]);
|
editor1.setSession(modeSessions[value]);
|
||||||
|
updateSaveButtonState(null, editor1);
|
||||||
schedule();
|
schedule();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -85,6 +90,50 @@ document.getElementById("syncToMode").onclick = function() {
|
||||||
docEl.onchange();
|
docEl.onchange();
|
||||||
run();
|
run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
editor1.saveButton = document.getElementById("saveButton1");
|
||||||
|
editor2.saveButton = document.getElementById("saveButton2");
|
||||||
|
editor1.saveButton.editor = editor1;
|
||||||
|
editor2.saveButton.editor = editor2;
|
||||||
|
|
||||||
|
editor1.saveButton.onclick = function() {
|
||||||
|
doclist.saveDoc({
|
||||||
|
path: "./lib/ace/mode/" + modeEl.value + "_highlight_rules.js",
|
||||||
|
session: editor1.session
|
||||||
|
}, function(err) {
|
||||||
|
handleSaveResult(err, editor1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
editor1.commands.bindKey({
|
||||||
|
win: "Ctrl-S", mac: "Cmd-s"
|
||||||
|
}, editor1.saveButton.onclick);
|
||||||
|
editor2.saveButton.onclick = function() {
|
||||||
|
doclist.saveDoc(docEl.value, function(err) {
|
||||||
|
handleSaveResult(err, editor2);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
editor2.commands.bindKey({
|
||||||
|
win: "Ctrl-S", mac: "Cmd-s"
|
||||||
|
}, editor2.saveButton.onclick);
|
||||||
|
function updateSaveButtonState(e, editor){
|
||||||
|
editor.saveButton.disabled = editor.session.getUndoManager().isClean();
|
||||||
|
}
|
||||||
|
editor1.on("input", updateSaveButtonState);
|
||||||
|
editor2.on("input", updateSaveButtonState);
|
||||||
|
|
||||||
|
function handleSaveResult(err, editor) {
|
||||||
|
if (err) {
|
||||||
|
return log(
|
||||||
|
"Write access to this file is disabled.\n"+
|
||||||
|
"To enable saving your changes to disk, clone the Ace repository\n"+
|
||||||
|
"and run the included web server with the --allow-write option\n"+
|
||||||
|
"`node static.js --allow-write` or `static.py --puttable=*`"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
editor.session.getUndoManager().markClean();
|
||||||
|
updateSaveButtonState(null, editor);
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById("perfTest").onclick = function() {
|
document.getElementById("perfTest").onclick = function() {
|
||||||
var lines = editor2.session.doc.getAllLines();
|
var lines = editor2.session.doc.getAllLines();
|
||||||
if (!lines.length)
|
if (!lines.length)
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,10 @@ var deps = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
liveScript: {
|
||||||
|
path: "mode/livescript.js",
|
||||||
|
url: "https://raw.githubusercontent.com/gkz/LiveScript/master/lib/mode-ls.js"
|
||||||
|
},
|
||||||
coffee: {
|
coffee: {
|
||||||
fetch: function(){
|
fetch: function(){
|
||||||
var rootHref = "https://raw.github.com/jashkenas/coffee-script/master/";
|
var rootHref = "https://raw.github.com/jashkenas/coffee-script/master/";
|
||||||
|
|
@ -200,7 +204,24 @@ var deps = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
xmldom: {
|
||||||
|
fetch: function() {
|
||||||
|
var rootHref = "https://raw.githubusercontent.com/iDeBugger/xmldom/master/"
|
||||||
|
var fileMap = {
|
||||||
|
"sax.js": "mode/xml/sax.js",
|
||||||
|
"dom-parser.js": "mode/xml/dom-parser.js",
|
||||||
|
"dom.js": "mode/xml/dom.js"
|
||||||
|
};
|
||||||
|
async.forEach(Object.keys(fileMap), function(x, next) {
|
||||||
|
download(rootHref + x, function(e, d) {
|
||||||
|
fs.writeFile(rootDir + fileMap[x], d, next)
|
||||||
|
})
|
||||||
|
}, function() {
|
||||||
|
console.log("XmlDOM updating done")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var download = function(href, callback) {
|
var download = function(href, callback) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue