Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ac674f5c6 | ||
|
|
2b5a16be70 | ||
|
|
1fbe9df342 | ||
|
|
1217d2d05e | ||
|
|
432795026c | ||
|
|
ab23eaa6ff | ||
|
|
4583c0c713 | ||
|
|
d3a961f13f | ||
|
|
7a97af2c1d | ||
|
|
750cc59fd5 | ||
|
|
dfcf54d412 | ||
|
|
5fd1c35d85 | ||
|
|
21b61bd027 | ||
|
|
7fa28c6d8b | ||
|
|
97e396794a | ||
|
|
b096ef3606 | ||
|
|
74b0d86c36 | ||
|
|
319c509318 | ||
|
|
5703a040be | ||
|
|
6752b8ef50 | ||
|
|
7062560eaa | ||
|
|
3be433c910 | ||
|
|
bd0969e870 | ||
|
|
ffbac321a4 | ||
|
|
222f6589a9 | ||
|
|
a2245775a9 | ||
|
|
d594050166 | ||
|
|
2665055558 | ||
|
|
3e41afb0a6 | ||
|
|
f1ec4a2453 | ||
|
|
98f1ace910 | ||
|
|
401a3a7abb | ||
|
|
6a0cc816a9 | ||
|
|
4bafb3aaa1 | ||
|
|
782aac54e4 | ||
|
|
06dd46c24f | ||
|
|
bc50886250 | ||
|
|
4264c479ad | ||
|
|
b3afe9458e | ||
|
|
1382277c74 | ||
|
|
d1df67338d | ||
|
|
ccc5b9d30a | ||
|
|
86142ca5f1 | ||
|
|
b55fe4856c | ||
|
|
d5df587cc3 | ||
|
|
0665d10a7c | ||
|
|
43f7089106 | ||
|
|
fcb7722a55 | ||
|
|
7c5a005784 | ||
|
|
abd61689f1 | ||
|
|
acbe46b013 | ||
|
|
bbf169907a | ||
|
|
1d3af5c62d | ||
|
|
d095e6a5fe | ||
|
|
96df3ac91b | ||
|
|
38fe4fd85e | ||
|
|
95ac9b50e0 | ||
|
|
1f26ddaf3d | ||
|
|
64231d7f01 | ||
|
|
656c10e5cf | ||
|
|
f0d4ef75d3 | ||
|
|
ec27eb53bc | ||
|
|
6512d4895b | ||
|
|
de81341452 | ||
|
|
97e6906f17 | ||
|
|
feeb3907bf | ||
|
|
955d7714a2 | ||
|
|
e506d5a535 | ||
|
|
09ff2f279d | ||
|
|
e17a240661 | ||
|
|
a6e244a82f | ||
|
|
491fb4c243 | ||
|
|
ca46e36e5a | ||
|
|
09e3ece5a7 | ||
|
|
57e820501a | ||
|
|
1577118643 | ||
|
|
856a0c9f31 | ||
|
|
c621479709 | ||
|
|
b7769e6203 | ||
|
|
b1e27282a9 | ||
|
|
c19df45ec1 | ||
|
|
0ca29f9201 | ||
|
|
e208b45a88 | ||
|
|
b8f7be6376 | ||
|
|
5ae958e349 | ||
|
|
7237ef8c69 | ||
|
|
215a4ab362 | ||
|
|
8c83378b8b | ||
|
|
9d14ca1eb2 | ||
|
|
78067a8dec | ||
|
|
d12ea02c42 | ||
|
|
3ceb519b8a | ||
|
|
5508cd1074 | ||
|
|
d2bf52e5a3 | ||
|
|
f39b8e2a35 | ||
|
|
8c97be00dc | ||
|
|
83085c4c1f | ||
|
|
8adec9a48b | ||
|
|
c177374d23 | ||
|
|
334ced8627 | ||
|
|
d8229d79a5 | ||
|
|
c8665584e9 | ||
|
|
c56af14f52 | ||
|
|
ed8fb0dd67 | ||
|
|
f906b41cd2 | ||
|
|
1491e24039 | ||
|
|
30dbad53a7 | ||
|
|
b129bc39cb | ||
|
|
5ffba58802 | ||
|
|
3cd5b99edd | ||
|
|
89b1b51097 | ||
|
|
6b5c95fc3a |
@@ -1,29 +0,0 @@
|
||||
// TODO number prefixes
|
||||
(function() {
|
||||
// Really primitive kill-ring implementation.
|
||||
var killRing = [];
|
||||
function addToRing(str) {
|
||||
killRing.push(str);
|
||||
if (killRing.length > 50) killRing.shift();
|
||||
}
|
||||
function getFromRing() { return killRing[killRing.length - 1] || ""; }
|
||||
function popFromRing() { if (killRing.length > 1) killRing.pop(); return getFromRing(); }
|
||||
|
||||
CodeMirror.keyMap.emacs = {
|
||||
"Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
|
||||
"Ctrl-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
|
||||
"Ctrl-Alt-W": function(cm) {addToRing(cm.getSelection()); cm.replaceSelection("");},
|
||||
"Alt-W": function(cm) {addToRing(cm.getSelection());},
|
||||
"Ctrl-Y": function(cm) {cm.replaceSelection(getFromRing());},
|
||||
"Alt-Y": function(cm) {cm.replaceSelection(popFromRing());},
|
||||
"Ctrl-/": "undo", "Shift-Ctrl--": "undo", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
|
||||
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
|
||||
"Ctrl-Z": "undo", "Cmd-Z": "undo",
|
||||
fallthrough: ["basic", "emacsy"]
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["emacs-Ctrl-X"] = {
|
||||
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": "undo", "K": "close",
|
||||
auto: "emacs", catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
})();
|
||||
@@ -1,347 +0,0 @@
|
||||
(function() {
|
||||
var count = "";
|
||||
var sdir = "f";
|
||||
var buf = "";
|
||||
var yank = 0;
|
||||
var mark = [];
|
||||
function emptyBuffer() { buf = ""; }
|
||||
function pushInBuffer(str) { buf += str; };
|
||||
function pushCountDigit(digit) { return function(cm) {count += digit;} }
|
||||
function popCount() { var i = parseInt(count); count = ""; return i || 1; }
|
||||
function countTimes(func) {
|
||||
if (typeof func == "string") func = CodeMirror.commands[func];
|
||||
return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); }
|
||||
}
|
||||
|
||||
function iterObj(o, f) {
|
||||
for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
|
||||
}
|
||||
|
||||
var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
|
||||
function findWord(line, pos, dir, regexps) {
|
||||
var stop = 0, next = -1;
|
||||
if (dir > 0) { stop = line.length; next = 0; }
|
||||
var start = stop, end = stop;
|
||||
// Find bounds of next one.
|
||||
outer: for (; pos != stop; pos += dir) {
|
||||
for (var i = 0; i < regexps.length; ++i) {
|
||||
if (regexps[i].test(line.charAt(pos + next))) {
|
||||
start = pos;
|
||||
for (; pos != stop; pos += dir) {
|
||||
if (!regexps[i].test(line.charAt(pos + next))) break;
|
||||
}
|
||||
end = pos;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {from: Math.min(start, end), to: Math.max(start, end)};
|
||||
}
|
||||
function moveToWord(cm, regexps, dir, where) {
|
||||
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line), word;
|
||||
while (true) {
|
||||
word = findWord(line, ch, dir, regexps);
|
||||
ch = word[where == "end" ? "to" : "from"];
|
||||
if (ch == cur.ch && word.from != word.to) ch = word[dir < 0 ? "from" : "to"];
|
||||
else break;
|
||||
}
|
||||
cm.setCursor(cur.line, word[where == "end" ? "to" : "from"], true);
|
||||
}
|
||||
function joinLineNext(cm) {
|
||||
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
|
||||
CodeMirror.commands.goLineEnd(cm);
|
||||
if (cur.line != cm.lineCount()) {
|
||||
CodeMirror.commands.goLineEnd(cm);
|
||||
cm.replaceSelection(" ", "end");
|
||||
CodeMirror.commands.delCharRight(cm);
|
||||
}
|
||||
}
|
||||
function editCursor(mode) {
|
||||
if (mode == "vim-insert") {
|
||||
// put in your cursor css changing code
|
||||
} else if (mode == "vim") {
|
||||
// put in your cursor css changing code
|
||||
}
|
||||
}
|
||||
function delTillMark(cm, cHar) {
|
||||
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
|
||||
cm.setCursor(start);
|
||||
for (var c = start; c <= end; c++) {
|
||||
pushInBuffer("\n"+cm.getLine(start));
|
||||
cm.removeLine(start);
|
||||
}
|
||||
}
|
||||
function yankTillMark(cm, cHar) {
|
||||
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
|
||||
for (var c = start; c <= end; c++) {
|
||||
pushInBuffer("\n"+cm.getLine(c));
|
||||
}
|
||||
cm.setCursor(start);
|
||||
}
|
||||
|
||||
var map = CodeMirror.keyMap.vim = {
|
||||
"0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
|
||||
"A": function(cm) {popCount(); cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"Shift-A": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"Shift-I": function(cm) {popCount(); CodeMirror.commands.goLineStartSmart(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.replaceSelection("\n", "end"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");},
|
||||
"D": function(cm) {cm.setOption("keyMap", "vim-prefix-d"); emptyBuffer();},
|
||||
"M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
|
||||
"Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
|
||||
"/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
|
||||
"Shift-/": function(cm) {
|
||||
var f = CodeMirror.commands.find;
|
||||
if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
|
||||
},
|
||||
"N": function(cm) {
|
||||
var fn = CodeMirror.commands.findNext;
|
||||
if (fn) sdir != "r" ? fn(cm) : CodeMirror.commands.findPrev(cm);
|
||||
},
|
||||
"Shift-N": function(cm) {
|
||||
var fn = CodeMirror.commands.findNext;
|
||||
if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
|
||||
},
|
||||
"Shift-G": function(cm) {count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1); popCount(); CodeMirror.commands.goLineStart(cm);},
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
// Add bindings for number keys
|
||||
for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i);
|
||||
// Add bindings that are influenced by number keys
|
||||
iterObj({"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown", "K": "goLineUp",
|
||||
"Left": "goColumnLeft", "Right": "goColumnRight", "Down": "goLineDown", "Up": "goLineUp",
|
||||
"Backspace": "goCharLeft", "Space": "goCharRight",
|
||||
"B": function(cm) {moveToWord(cm, word, -1, "end");},
|
||||
"E": function(cm) {moveToWord(cm, word, 1, "end");},
|
||||
"W": function(cm) {moveToWord(cm, word, 1, "start");},
|
||||
"Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
|
||||
"Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
|
||||
"Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
|
||||
"X": function(cm) {CodeMirror.commands.delCharRight(cm)},
|
||||
"P": function(cm) {
|
||||
var cur = cm.getCursor().line;
|
||||
if (buf!= "") {
|
||||
CodeMirror.commands.goLineEnd(cm);
|
||||
cm.replaceSelection(buf, "end");
|
||||
}
|
||||
cm.setCursor(cur+1);
|
||||
},
|
||||
"Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm)},
|
||||
"Shift-J": function(cm) {joinLineNext(cm)},
|
||||
"Shift-`": function(cm) {
|
||||
var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
|
||||
cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
|
||||
cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
|
||||
cm.setCursor(cur.line, cur.ch+1);
|
||||
},
|
||||
"Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm)},
|
||||
"Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm)},
|
||||
"Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
|
||||
"U": "undo", "Ctrl-R": "redo", "Shift-4": "goLineEnd"},
|
||||
function(key, cmd) { map[key] = countTimes(cmd); });
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-g"] = {
|
||||
"E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}),
|
||||
"Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}),
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-m"] = {
|
||||
"A": function(cm) {mark["A"] = cm.getCursor().line;},
|
||||
"Shift-A": function(cm) {mark["Shift-A"] = cm.getCursor().line;},
|
||||
"B": function(cm) {mark["B"] = cm.getCursor().line;},
|
||||
"Shift-B": function(cm) {mark["Shift-B"] = cm.getCursor().line;},
|
||||
"C": function(cm) {mark["C"] = cm.getCursor().line;},
|
||||
"Shift-C": function(cm) {mark["Shift-C"] = cm.getCursor().line;},
|
||||
"D": function(cm) {mark["D"] = cm.getCursor().line;},
|
||||
"Shift-D": function(cm) {mark["Shift-D"] = cm.getCursor().line;},
|
||||
"E": function(cm) {mark["E"] = cm.getCursor().line;},
|
||||
"Shift-E": function(cm) {mark["Shift-E"] = cm.getCursor().line;},
|
||||
"F": function(cm) {mark["F"] = cm.getCursor().line;},
|
||||
"Shift-F": function(cm) {mark["Shift-F"] = cm.getCursor().line;},
|
||||
"G": function(cm) {mark["G"] = cm.getCursor().line;},
|
||||
"Shift-G": function(cm) {mark["Shift-G"] = cm.getCursor().line;},
|
||||
"H": function(cm) {mark["H"] = cm.getCursor().line;},
|
||||
"Shift-H": function(cm) {mark["Shift-H"] = cm.getCursor().line;},
|
||||
"I": function(cm) {mark["I"] = cm.getCursor().line;},
|
||||
"Shift-I": function(cm) {mark["Shift-I"] = cm.getCursor().line;},
|
||||
"J": function(cm) {mark["J"] = cm.getCursor().line;},
|
||||
"Shift-J": function(cm) {mark["Shift-J"] = cm.getCursor().line;},
|
||||
"K": function(cm) {mark["K"] = cm.getCursor().line;},
|
||||
"Shift-K": function(cm) {mark["Shift-K"] = cm.getCursor().line;},
|
||||
"L": function(cm) {mark["L"] = cm.getCursor().line;},
|
||||
"Shift-L": function(cm) {mark["Shift-L"] = cm.getCursor().line;},
|
||||
"M": function(cm) {mark["M"] = cm.getCursor().line;},
|
||||
"Shift-M": function(cm) {mark["Shift-M"] = cm.getCursor().line;},
|
||||
"N": function(cm) {mark["N"] = cm.getCursor().line;},
|
||||
"Shift-N": function(cm) {mark["Shift-N"] = cm.getCursor().line;},
|
||||
"O": function(cm) {mark["O"] = cm.getCursor().line;},
|
||||
"Shift-O": function(cm) {mark["Shift-O"] = cm.getCursor().line;},
|
||||
"P": function(cm) {mark["P"] = cm.getCursor().line;},
|
||||
"Shift-P": function(cm) {mark["Shift-P"] = cm.getCursor().line;},
|
||||
"Q": function(cm) {mark["Q"] = cm.getCursor().line;},
|
||||
"Shift-Q": function(cm) {mark["Shift-Q"] = cm.getCursor().line;},
|
||||
"R": function(cm) {mark["R"] = cm.getCursor().line;},
|
||||
"Shift-R": function(cm) {mark["Shift-R"] = cm.getCursor().line;},
|
||||
"S": function(cm) {mark["S"] = cm.getCursor().line;},
|
||||
"Shift-S": function(cm) {mark["Shift-S"] = cm.getCursor().line;},
|
||||
"T": function(cm) {mark["T"] = cm.getCursor().line;},
|
||||
"Shift-T": function(cm) {mark["Shift-T"] = cm.getCursor().line;},
|
||||
"U": function(cm) {mark["U"] = cm.getCursor().line;},
|
||||
"Shift-U": function(cm) {mark["Shift-U"] = cm.getCursor().line;},
|
||||
"V": function(cm) {mark["V"] = cm.getCursor().line;},
|
||||
"Shift-V": function(cm) {mark["Shift-V"] = cm.getCursor().line;},
|
||||
"W": function(cm) {mark["W"] = cm.getCursor().line;},
|
||||
"Shift-W": function(cm) {mark["Shift-W"] = cm.getCursor().line;},
|
||||
"X": function(cm) {mark["X"] = cm.getCursor().line;},
|
||||
"Shift-X": function(cm) {mark["Shift-X"] = cm.getCursor().line;},
|
||||
"Y": function(cm) {mark["Y"] = cm.getCursor().line;},
|
||||
"Shift-Y": function(cm) {mark["Shift-Y"] = cm.getCursor().line;},
|
||||
"Z": function(cm) {mark["Z"] = cm.getCursor().line;},
|
||||
"Shift-Z": function(cm) {mark["Shift-Z"] = cm.getCursor().line;},
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
}
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-d"] = {
|
||||
"D": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line)); cm.removeLine(cm.getCursor().line); }),
|
||||
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-d'"); emptyBuffer();},
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-d'"] = {
|
||||
"A": function(cm) {delTillMark(cm,"A");},
|
||||
"Shift-A": function(cm) {delTillMark(cm,"Shift-A");},
|
||||
"B": function(cm) {delTillMark(cm,"B");},
|
||||
"Shift-B": function(cm) {delTillMark(cm,"Shift-B");},
|
||||
"C": function(cm) {delTillMark(cm,"C");},
|
||||
"Shift-C": function(cm) {delTillMark(cm,"Shift-C");},
|
||||
"D": function(cm) {delTillMark(cm,"D");},
|
||||
"Shift-D": function(cm) {delTillMark(cm,"Shift-D");},
|
||||
"E": function(cm) {delTillMark(cm,"E");},
|
||||
"Shift-E": function(cm) {delTillMark(cm,"Shift-E");},
|
||||
"F": function(cm) {delTillMark(cm,"F");},
|
||||
"Shift-F": function(cm) {delTillMark(cm,"Shift-F");},
|
||||
"G": function(cm) {delTillMark(cm,"G");},
|
||||
"Shift-G": function(cm) {delTillMark(cm,"Shift-G");},
|
||||
"H": function(cm) {delTillMark(cm,"H");},
|
||||
"Shift-H": function(cm) {delTillMark(cm,"Shift-H");},
|
||||
"I": function(cm) {delTillMark(cm,"I");},
|
||||
"Shift-I": function(cm) {delTillMark(cm,"Shift-I");},
|
||||
"J": function(cm) {delTillMark(cm,"J");},
|
||||
"Shift-J": function(cm) {delTillMark(cm,"Shift-J");},
|
||||
"K": function(cm) {delTillMark(cm,"K");},
|
||||
"Shift-K": function(cm) {delTillMark(cm,"Shift-K");},
|
||||
"L": function(cm) {delTillMark(cm,"L");},
|
||||
"Shift-L": function(cm) {delTillMark(cm,"Shift-L");},
|
||||
"M": function(cm) {delTillMark(cm,"M");},
|
||||
"Shift-M": function(cm) {delTillMark(cm,"Shift-M");},
|
||||
"N": function(cm) {delTillMark(cm,"N");},
|
||||
"Shift-N": function(cm) {delTillMark(cm,"Shift-N");},
|
||||
"O": function(cm) {delTillMark(cm,"O");},
|
||||
"Shift-O": function(cm) {delTillMark(cm,"Shift-O");},
|
||||
"P": function(cm) {delTillMark(cm,"P");},
|
||||
"Shift-P": function(cm) {delTillMark(cm,"Shift-P");},
|
||||
"Q": function(cm) {delTillMark(cm,"Q");},
|
||||
"Shift-Q": function(cm) {delTillMark(cm,"Shift-Q");},
|
||||
"R": function(cm) {delTillMark(cm,"R");},
|
||||
"Shift-R": function(cm) {delTillMark(cm,"Shift-R");},
|
||||
"S": function(cm) {delTillMark(cm,"S");},
|
||||
"Shift-S": function(cm) {delTillMark(cm,"Shift-S");},
|
||||
"T": function(cm) {delTillMark(cm,"T");},
|
||||
"Shift-T": function(cm) {delTillMark(cm,"Shift-T");},
|
||||
"U": function(cm) {delTillMark(cm,"U");},
|
||||
"Shift-U": function(cm) {delTillMark(cm,"Shift-U");},
|
||||
"V": function(cm) {delTillMark(cm,"V");},
|
||||
"Shift-V": function(cm) {delTillMark(cm,"Shift-V");},
|
||||
"W": function(cm) {delTillMark(cm,"W");},
|
||||
"Shift-W": function(cm) {delTillMark(cm,"Shift-W");},
|
||||
"X": function(cm) {delTillMark(cm,"X");},
|
||||
"Shift-X": function(cm) {delTillMark(cm,"Shift-X");},
|
||||
"Y": function(cm) {delTillMark(cm,"Y");},
|
||||
"Shift-Y": function(cm) {delTillMark(cm,"Shift-Y");},
|
||||
"Z": function(cm) {delTillMark(cm,"Z");},
|
||||
"Shift-Z": function(cm) {delTillMark(cm,"Shift-Z");},
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-y'"] = {
|
||||
"A": function(cm) {yankTillMark(cm,"A");},
|
||||
"Shift-A": function(cm) {yankTillMark(cm,"Shift-A");},
|
||||
"B": function(cm) {yankTillMark(cm,"B");},
|
||||
"Shift-B": function(cm) {yankTillMark(cm,"Shift-B");},
|
||||
"C": function(cm) {yankTillMark(cm,"C");},
|
||||
"Shift-C": function(cm) {yankTillMark(cm,"Shift-C");},
|
||||
"D": function(cm) {yankTillMark(cm,"D");},
|
||||
"Shift-D": function(cm) {yankTillMark(cm,"Shift-D");},
|
||||
"E": function(cm) {yankTillMark(cm,"E");},
|
||||
"Shift-E": function(cm) {yankTillMark(cm,"Shift-E");},
|
||||
"F": function(cm) {yankTillMark(cm,"F");},
|
||||
"Shift-F": function(cm) {yankTillMark(cm,"Shift-F");},
|
||||
"G": function(cm) {yankTillMark(cm,"G");},
|
||||
"Shift-G": function(cm) {yankTillMark(cm,"Shift-G");},
|
||||
"H": function(cm) {yankTillMark(cm,"H");},
|
||||
"Shift-H": function(cm) {yankTillMark(cm,"Shift-H");},
|
||||
"I": function(cm) {yankTillMark(cm,"I");},
|
||||
"Shift-I": function(cm) {yankTillMark(cm,"Shift-I");},
|
||||
"J": function(cm) {yankTillMark(cm,"J");},
|
||||
"Shift-J": function(cm) {yankTillMark(cm,"Shift-J");},
|
||||
"K": function(cm) {yankTillMark(cm,"K");},
|
||||
"Shift-K": function(cm) {yankTillMark(cm,"Shift-K");},
|
||||
"L": function(cm) {yankTillMark(cm,"L");},
|
||||
"Shift-L": function(cm) {yankTillMark(cm,"Shift-L");},
|
||||
"M": function(cm) {yankTillMark(cm,"M");},
|
||||
"Shift-M": function(cm) {yankTillMark(cm,"Shift-M");},
|
||||
"N": function(cm) {yankTillMark(cm,"N");},
|
||||
"Shift-N": function(cm) {yankTillMark(cm,"Shift-N");},
|
||||
"O": function(cm) {yankTillMark(cm,"O");},
|
||||
"Shift-O": function(cm) {yankTillMark(cm,"Shift-O");},
|
||||
"P": function(cm) {yankTillMark(cm,"P");},
|
||||
"Shift-P": function(cm) {yankTillMark(cm,"Shift-P");},
|
||||
"Q": function(cm) {yankTillMark(cm,"Q");},
|
||||
"Shift-Q": function(cm) {yankTillMark(cm,"Shift-Q");},
|
||||
"R": function(cm) {yankTillMark(cm,"R");},
|
||||
"Shift-R": function(cm) {yankTillMark(cm,"Shift-R");},
|
||||
"S": function(cm) {yankTillMark(cm,"S");},
|
||||
"Shift-S": function(cm) {yankTillMark(cm,"Shift-S");},
|
||||
"T": function(cm) {yankTillMark(cm,"T");},
|
||||
"Shift-T": function(cm) {yankTillMark(cm,"Shift-T");},
|
||||
"U": function(cm) {yankTillMark(cm,"U");},
|
||||
"Shift-U": function(cm) {yankTillMark(cm,"Shift-U");},
|
||||
"V": function(cm) {yankTillMark(cm,"V");},
|
||||
"Shift-V": function(cm) {yankTillMark(cm,"Shift-V");},
|
||||
"W": function(cm) {yankTillMark(cm,"W");},
|
||||
"Shift-W": function(cm) {yankTillMark(cm,"Shift-W");},
|
||||
"X": function(cm) {yankTillMark(cm,"X");},
|
||||
"Shift-X": function(cm) {yankTillMark(cm,"Shift-X");},
|
||||
"Y": function(cm) {yankTillMark(cm,"Y");},
|
||||
"Shift-Y": function(cm) {yankTillMark(cm,"Shift-Y");},
|
||||
"Z": function(cm) {yankTillMark(cm,"Z");},
|
||||
"Shift-Z": function(cm) {yankTillMark(cm,"Shift-Z");},
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-y"] = {
|
||||
"Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
|
||||
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
|
||||
auto: "vim",
|
||||
catchall: function(cm) {/*ignore*/}
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-insert"] = {
|
||||
"Esc": function(cm) {
|
||||
cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
|
||||
cm.setOption("keyMap", "vim");
|
||||
editCursor("vim");
|
||||
},
|
||||
"Ctrl-N": function(cm) {/* Code to bring up autocomplete hint */},
|
||||
"Ctrl-P": function(cm) {/* Code to bring up autocomplete hint */},
|
||||
fallthrough: ["default"]
|
||||
};
|
||||
})();
|
||||
@@ -1,174 +0,0 @@
|
||||
/**
|
||||
* Tag-closer extension for CodeMirror.
|
||||
*
|
||||
* This extension adds a "closeTag" utility function that can be used with key bindings to
|
||||
* insert a matching end tag after the ">" character of a start tag has been typed. It can
|
||||
* also complete "</" if a matching start tag is found. It will correctly ignore signal
|
||||
* characters for empty tags, comments, CDATA, etc.
|
||||
*
|
||||
* The function depends on internal parser state to identify tags. It is compatible with the
|
||||
* following CodeMirror modes and will ignore all others:
|
||||
* - htmlmixed
|
||||
* - xml
|
||||
* - xmlpure
|
||||
*
|
||||
* See demos/closetag.html for a usage example.
|
||||
*
|
||||
* @author Nathan Williams <nathan@nlwillia.net>
|
||||
* Contributed under the same license terms as CodeMirror.
|
||||
*/
|
||||
(function() {
|
||||
/** Option that allows tag closing behavior to be toggled. Default is true. */
|
||||
CodeMirror.defaults['closeTagEnabled'] = true;
|
||||
|
||||
/** Array of tag names to add indentation after the start tag for. Default is the list of block-level html tags. */
|
||||
CodeMirror.defaults['closeTagIndent'] = ['applet', 'blockquote', 'body', 'button', 'div', 'dl', 'fieldset', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'iframe', 'layer', 'legend', 'object', 'ol', 'p', 'select', 'table', 'ul'];
|
||||
|
||||
/**
|
||||
* Call during key processing to close tags. Handles the key event if the tag is closed, otherwise throws CodeMirror.Pass.
|
||||
* - cm: The editor instance.
|
||||
* - ch: The character being processed.
|
||||
* - indent: Optional. Omit or pass true to use the default indentation tag list defined in the 'closeTagIndent' option.
|
||||
* Pass false to disable indentation. Pass an array to override the default list of tag names.
|
||||
*/
|
||||
CodeMirror.defineExtension("closeTag", function(cm, ch, indent) {
|
||||
if (!cm.getOption('closeTagEnabled')) {
|
||||
throw CodeMirror.Pass;
|
||||
}
|
||||
|
||||
var mode = cm.getOption('mode');
|
||||
|
||||
if (mode == 'text/html') {
|
||||
|
||||
/*
|
||||
* Relevant structure of token:
|
||||
*
|
||||
* htmlmixed
|
||||
* className
|
||||
* state
|
||||
* htmlState
|
||||
* type
|
||||
* context
|
||||
* tagName
|
||||
* mode
|
||||
*
|
||||
* xml
|
||||
* className
|
||||
* state
|
||||
* tagName
|
||||
* type
|
||||
*/
|
||||
|
||||
var pos = cm.getCursor();
|
||||
var tok = cm.getTokenAt(pos);
|
||||
var state = tok.state;
|
||||
|
||||
if (state.mode && state.mode != 'html') {
|
||||
throw CodeMirror.Pass; // With htmlmixed, we only care about the html sub-mode.
|
||||
}
|
||||
|
||||
if (ch == '>') {
|
||||
var type = state.htmlState ? state.htmlState.type : state.type; // htmlmixed : xml
|
||||
|
||||
if (tok.className == 'tag' && type == 'closeTag') {
|
||||
throw CodeMirror.Pass; // Don't process the '>' at the end of an end-tag.
|
||||
}
|
||||
|
||||
cm.replaceSelection('>'); // Mode state won't update until we finish the tag.
|
||||
pos = {line: pos.line, ch: pos.ch + 1};
|
||||
cm.setCursor(pos);
|
||||
|
||||
tok = cm.getTokenAt(cm.getCursor());
|
||||
state = tok.state;
|
||||
type = state.htmlState ? state.htmlState.type : state.type; // htmlmixed : xml
|
||||
|
||||
if (tok.className == 'tag' && type != 'selfcloseTag') {
|
||||
var tagName = state.htmlState ? state.htmlState.context.tagName : state.tagName; // htmlmixed : xml
|
||||
if (tagName.length > 0) {
|
||||
insertEndTag(cm, indent, pos, tagName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Undo the '>' insert and allow cm to handle the key instead.
|
||||
cm.setSelection({line: pos.line, ch: pos.ch - 1}, pos);
|
||||
cm.replaceSelection("");
|
||||
|
||||
} else if (ch == '/') {
|
||||
if (tok.className == 'tag' && tok.string == '<') {
|
||||
var tagName = state.htmlState ? (state.htmlState.context ? state.htmlState.context.tagName : '') : state.context.tagName; // htmlmixed : xml # extra htmlmized check is for '</' edge case
|
||||
if (tagName.length > 0) {
|
||||
completeEndTag(cm, pos, tagName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (mode == 'xmlpure') {
|
||||
|
||||
var pos = cm.getCursor();
|
||||
var tok = cm.getTokenAt(pos);
|
||||
var tagName = tok.state.context.tagName;
|
||||
|
||||
if (ch == '>') {
|
||||
// <foo> tagName=foo, string=foo
|
||||
// <foo /> tagName=foo, string=/ # ignore
|
||||
// <foo></foo> tagName=foo, string=/foo # ignore
|
||||
if (tok.string == tagName) {
|
||||
cm.replaceSelection('>'); // parity w/html modes
|
||||
pos = {line: pos.line, ch: pos.ch + 1};
|
||||
cm.setCursor(pos);
|
||||
|
||||
insertEndTag(cm, indent, pos, tagName);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (ch == '/') {
|
||||
// <foo / tagName=foo, string= # ignore
|
||||
// <foo></ tagName=foo, string=<
|
||||
if (tok.string == '<') {
|
||||
completeEndTag(cm, pos, tagName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw CodeMirror.Pass; // Bubble if not handled
|
||||
});
|
||||
|
||||
function insertEndTag(cm, indent, pos, tagName) {
|
||||
if (shouldIndent(cm, indent, tagName)) {
|
||||
cm.replaceSelection('\n\n</' + tagName + '>', 'end');
|
||||
cm.indentLine(pos.line + 1);
|
||||
cm.indentLine(pos.line + 2);
|
||||
cm.setCursor({line: pos.line + 1, ch: cm.getLine(pos.line + 1).length});
|
||||
} else {
|
||||
cm.replaceSelection('</' + tagName + '>');
|
||||
cm.setCursor(pos);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldIndent(cm, indent, tagName) {
|
||||
if (typeof indent == 'undefined' || indent == null || indent == true) {
|
||||
indent = cm.getOption('closeTagIndent');
|
||||
}
|
||||
if (!indent) {
|
||||
indent = [];
|
||||
}
|
||||
return indexOf(indent, tagName.toLowerCase()) != -1;
|
||||
}
|
||||
|
||||
// C&P from codemirror.js...would be nice if this were visible to utilities.
|
||||
function indexOf(collection, elt) {
|
||||
if (collection.indexOf) return collection.indexOf(elt);
|
||||
for (var i = 0, e = collection.length; i < e; ++i)
|
||||
if (collection[i] == elt) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
function completeEndTag(cm, pos, tagName) {
|
||||
cm.replaceSelection('/' + tagName + '>');
|
||||
cm.setCursor({line: pos.line, ch: pos.ch + tagName.length + 2 });
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,23 +0,0 @@
|
||||
.CodeMirror-dialog {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog > div {
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0;
|
||||
background: white;
|
||||
border-bottom: 1px solid #eee;
|
||||
z-index: 15;
|
||||
padding: .1em .8em;
|
||||
overflow: hidden;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
width: 20em;
|
||||
color: inherit;
|
||||
font-family: monospace;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// Open simple dialogs on top of an editor. Relies on dialog.css.
|
||||
|
||||
(function() {
|
||||
function dialogDiv(cm, template) {
|
||||
var wrap = cm.getWrapperElement();
|
||||
var dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
|
||||
dialog.className = "CodeMirror-dialog";
|
||||
dialog.innerHTML = '<div>' + template + '</div>';
|
||||
return dialog;
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("openDialog", function(template, callback) {
|
||||
var dialog = dialogDiv(this, template);
|
||||
var closed = false, me = this;
|
||||
function close() {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
dialog.parentNode.removeChild(dialog);
|
||||
}
|
||||
var inp = dialog.getElementsByTagName("input")[0];
|
||||
if (inp) {
|
||||
CodeMirror.connect(inp, "keydown", function(e) {
|
||||
if (e.keyCode == 13 || e.keyCode == 27) {
|
||||
CodeMirror.e_stop(e);
|
||||
close();
|
||||
me.focus();
|
||||
if (e.keyCode == 13) callback(inp.value);
|
||||
}
|
||||
});
|
||||
inp.focus();
|
||||
CodeMirror.connect(inp, "blur", close);
|
||||
}
|
||||
return close;
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("openConfirm", function(template, callbacks) {
|
||||
var dialog = dialogDiv(this, template);
|
||||
var buttons = dialog.getElementsByTagName("button");
|
||||
var closed = false, me = this, blurring = 1;
|
||||
function close() {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
dialog.parentNode.removeChild(dialog);
|
||||
me.focus();
|
||||
}
|
||||
buttons[0].focus();
|
||||
for (var i = 0; i < buttons.length; ++i) {
|
||||
var b = buttons[i];
|
||||
(function(callback) {
|
||||
CodeMirror.connect(b, "click", function(e) {
|
||||
CodeMirror.e_preventDefault(e);
|
||||
close();
|
||||
if (callback) callback(me);
|
||||
});
|
||||
})(callbacks[i]);
|
||||
CodeMirror.connect(b, "blur", function() {
|
||||
--blurring;
|
||||
setTimeout(function() { if (blurring <= 0) close(); }, 200);
|
||||
});
|
||||
CodeMirror.connect(b, "focus", function() { ++blurring; });
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -1,294 +0,0 @@
|
||||
// ============== Formatting extensions ============================
|
||||
// A common storage for all mode-specific formatting features
|
||||
if (!CodeMirror.modeExtensions) CodeMirror.modeExtensions = {};
|
||||
|
||||
// Returns the extension of the editor's current mode
|
||||
CodeMirror.defineExtension("getModeExt", function () {
|
||||
var mname = CodeMirror.resolveMode(this.getOption("mode")).name;
|
||||
var ext = CodeMirror.modeExtensions[mname];
|
||||
if (!ext) throw new Error("No extensions found for mode " + mname);
|
||||
return ext;
|
||||
});
|
||||
|
||||
// If the current mode is 'htmlmixed', returns the extension of a mode located at
|
||||
// the specified position (can be htmlmixed, css or javascript). Otherwise, simply
|
||||
// returns the extension of the editor's current mode.
|
||||
CodeMirror.defineExtension("getModeExtAtPos", function (pos) {
|
||||
var token = this.getTokenAt(pos);
|
||||
if (token && token.state && token.state.mode)
|
||||
return CodeMirror.modeExtensions[token.state.mode == "html" ? "htmlmixed" : token.state.mode];
|
||||
else
|
||||
return this.getModeExt();
|
||||
});
|
||||
|
||||
// Comment/uncomment the specified range
|
||||
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
||||
var curMode = this.getModeExtAtPos(this.getCursor());
|
||||
if (isComment) { // Comment range
|
||||
var commentedText = this.getRange(from, to);
|
||||
this.replaceRange(curMode.commentStart + this.getRange(from, to) + curMode.commentEnd
|
||||
, from, to);
|
||||
if (from.line == to.line && from.ch == to.ch) { // An empty comment inserted - put cursor inside
|
||||
this.setCursor(from.line, from.ch + curMode.commentStart.length);
|
||||
}
|
||||
}
|
||||
else { // Uncomment range
|
||||
var selText = this.getRange(from, to);
|
||||
var startIndex = selText.indexOf(curMode.commentStart);
|
||||
var endIndex = selText.lastIndexOf(curMode.commentEnd);
|
||||
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
||||
// Take string till comment start
|
||||
selText = selText.substr(0, startIndex)
|
||||
// From comment start till comment end
|
||||
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
|
||||
// From comment end till string end
|
||||
+ selText.substr(endIndex + curMode.commentEnd.length);
|
||||
}
|
||||
this.replaceRange(selText, from, to);
|
||||
}
|
||||
});
|
||||
|
||||
// Applies automatic mode-aware indentation to the specified range
|
||||
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
|
||||
var cmInstance = this;
|
||||
this.operation(function () {
|
||||
for (var i = from.line; i <= to.line; i++) {
|
||||
cmInstance.indentLine(i, "smart");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Applies automatic formatting to the specified range
|
||||
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
|
||||
var absStart = this.indexFromPos(from);
|
||||
var absEnd = this.indexFromPos(to);
|
||||
// Insert additional line breaks where necessary according to the
|
||||
// mode's syntax
|
||||
var res = this.getModeExt().autoFormatLineBreaks(this.getValue(), absStart, absEnd);
|
||||
var cmInstance = this;
|
||||
|
||||
// Replace and auto-indent the range
|
||||
this.operation(function () {
|
||||
cmInstance.replaceRange(res, from, to);
|
||||
var startLine = cmInstance.posFromIndex(absStart).line;
|
||||
var endLine = cmInstance.posFromIndex(absStart + res.length).line;
|
||||
for (var i = startLine; i <= endLine; i++) {
|
||||
cmInstance.indentLine(i, "smart");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Define extensions for a few modes
|
||||
|
||||
CodeMirror.modeExtensions["css"] = {
|
||||
commentStart: "/*",
|
||||
commentEnd: "*/",
|
||||
wordWrapChars: [";", "\\{", "\\}"],
|
||||
autoFormatLineBreaks: function (text) {
|
||||
return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.modeExtensions["javascript"] = {
|
||||
commentStart: "/*",
|
||||
commentEnd: "*/",
|
||||
wordWrapChars: [";", "\\{", "\\}"],
|
||||
|
||||
getNonBreakableBlocks: function (text) {
|
||||
var nonBreakableRegexes = [
|
||||
new RegExp("for\\s*?\\(([\\s\\S]*?)\\)"),
|
||||
new RegExp("'([\\s\\S]*?)('|$)"),
|
||||
new RegExp("\"([\\s\\S]*?)(\"|$)"),
|
||||
new RegExp("//.*([\r\n]|$)")
|
||||
];
|
||||
var nonBreakableBlocks = new Array();
|
||||
for (var i = 0; i < nonBreakableRegexes.length; i++) {
|
||||
var curPos = 0;
|
||||
while (curPos < text.length) {
|
||||
var m = text.substr(curPos).match(nonBreakableRegexes[i]);
|
||||
if (m != null) {
|
||||
nonBreakableBlocks.push({
|
||||
start: curPos + m.index,
|
||||
end: curPos + m.index + m[0].length
|
||||
});
|
||||
curPos += m.index + Math.max(1, m[0].length);
|
||||
}
|
||||
else { // No more matches
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nonBreakableBlocks.sort(function (a, b) {
|
||||
return a.start - b.start;
|
||||
});
|
||||
|
||||
return nonBreakableBlocks;
|
||||
},
|
||||
|
||||
autoFormatLineBreaks: function (text) {
|
||||
var curPos = 0;
|
||||
var reLinesSplitter = new RegExp("(;|\\{|\\})([^\r\n])", "g");
|
||||
var nonBreakableBlocks = this.getNonBreakableBlocks(text);
|
||||
if (nonBreakableBlocks != null) {
|
||||
var res = "";
|
||||
for (var i = 0; i < nonBreakableBlocks.length; i++) {
|
||||
if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
|
||||
res += text.substring(curPos, nonBreakableBlocks[i].start).replace(reLinesSplitter, "$1\n$2");
|
||||
curPos = nonBreakableBlocks[i].start;
|
||||
}
|
||||
if (nonBreakableBlocks[i].start <= curPos
|
||||
&& nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
|
||||
res += text.substring(curPos, nonBreakableBlocks[i].end);
|
||||
curPos = nonBreakableBlocks[i].end;
|
||||
}
|
||||
}
|
||||
if (curPos < text.length - 1) {
|
||||
res += text.substr(curPos).replace(reLinesSplitter, "$1\n$2");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
return text.replace(reLinesSplitter, "$1\n$2");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.modeExtensions["xml"] = {
|
||||
commentStart: "<!--",
|
||||
commentEnd: "-->",
|
||||
wordWrapChars: [">"],
|
||||
|
||||
autoFormatLineBreaks: function (text) {
|
||||
var lines = text.split("\n");
|
||||
var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
|
||||
var reOpenBrackets = new RegExp("<", "g");
|
||||
var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var mToProcess = lines[i].match(reProcessedPortion);
|
||||
if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
|
||||
lines[i] = mToProcess[1]
|
||||
+ mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
|
||||
+ mToProcess[3];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.modeExtensions["htmlmixed"] = {
|
||||
commentStart: "<!--",
|
||||
commentEnd: "-->",
|
||||
wordWrapChars: [">", ";", "\\{", "\\}"],
|
||||
|
||||
getModeInfos: function (text, absPos) {
|
||||
var modeInfos = new Array();
|
||||
modeInfos[0] =
|
||||
{
|
||||
pos: 0,
|
||||
modeExt: CodeMirror.modeExtensions["xml"],
|
||||
modeName: "xml"
|
||||
};
|
||||
|
||||
var modeMatchers = new Array();
|
||||
modeMatchers[0] =
|
||||
{
|
||||
regex: new RegExp("<style[^>]*>([\\s\\S]*?)(</style[^>]*>|$)", "i"),
|
||||
modeExt: CodeMirror.modeExtensions["css"],
|
||||
modeName: "css"
|
||||
};
|
||||
modeMatchers[1] =
|
||||
{
|
||||
regex: new RegExp("<script[^>]*>([\\s\\S]*?)(</script[^>]*>|$)", "i"),
|
||||
modeExt: CodeMirror.modeExtensions["javascript"],
|
||||
modeName: "javascript"
|
||||
};
|
||||
|
||||
var lastCharPos = (typeof (absPos) !== "undefined" ? absPos : text.length - 1);
|
||||
// Detect modes for the entire text
|
||||
for (var i = 0; i < modeMatchers.length; i++) {
|
||||
var curPos = 0;
|
||||
while (curPos <= lastCharPos) {
|
||||
var m = text.substr(curPos).match(modeMatchers[i].regex);
|
||||
if (m != null) {
|
||||
if (m.length > 1 && m[1].length > 0) {
|
||||
// Push block begin pos
|
||||
var blockBegin = curPos + m.index + m[0].indexOf(m[1]);
|
||||
modeInfos.push(
|
||||
{
|
||||
pos: blockBegin,
|
||||
modeExt: modeMatchers[i].modeExt,
|
||||
modeName: modeMatchers[i].modeName
|
||||
});
|
||||
// Push block end pos
|
||||
modeInfos.push(
|
||||
{
|
||||
pos: blockBegin + m[1].length,
|
||||
modeExt: modeInfos[0].modeExt,
|
||||
modeName: modeInfos[0].modeName
|
||||
});
|
||||
curPos += m.index + m[0].length;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
curPos += m.index + Math.max(m[0].length, 1);
|
||||
}
|
||||
}
|
||||
else { // No more matches
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort mode infos
|
||||
modeInfos.sort(function sortModeInfo(a, b) {
|
||||
return a.pos - b.pos;
|
||||
});
|
||||
|
||||
return modeInfos;
|
||||
},
|
||||
|
||||
autoFormatLineBreaks: function (text, startPos, endPos) {
|
||||
var modeInfos = this.getModeInfos(text);
|
||||
var reBlockStartsWithNewline = new RegExp("^\\s*?\n");
|
||||
var reBlockEndsWithNewline = new RegExp("\n\\s*?$");
|
||||
var res = "";
|
||||
// Use modes info to break lines correspondingly
|
||||
if (modeInfos.length > 1) { // Deal with multi-mode text
|
||||
for (var i = 1; i <= modeInfos.length; i++) {
|
||||
var selStart = modeInfos[i - 1].pos;
|
||||
var selEnd = (i < modeInfos.length ? modeInfos[i].pos : endPos);
|
||||
|
||||
if (selStart >= endPos) { // The block starts later than the needed fragment
|
||||
break;
|
||||
}
|
||||
if (selStart < startPos) {
|
||||
if (selEnd <= startPos) { // The block starts earlier than the needed fragment
|
||||
continue;
|
||||
}
|
||||
selStart = startPos;
|
||||
}
|
||||
if (selEnd > endPos) {
|
||||
selEnd = endPos;
|
||||
}
|
||||
var textPortion = text.substring(selStart, selEnd);
|
||||
if (modeInfos[i - 1].modeName != "xml") { // Starting a CSS or JavaScript block
|
||||
if (!reBlockStartsWithNewline.test(textPortion)
|
||||
&& selStart > 0) { // The block does not start with a line break
|
||||
textPortion = "\n" + textPortion;
|
||||
}
|
||||
if (!reBlockEndsWithNewline.test(textPortion)
|
||||
&& selEnd < text.length - 1) { // The block does not end with a line break
|
||||
textPortion += "\n";
|
||||
}
|
||||
}
|
||||
res += modeInfos[i - 1].modeExt.autoFormatLineBreaks(textPortion);
|
||||
}
|
||||
}
|
||||
else { // Single-mode text
|
||||
res = modeInfos[0].modeExt.autoFormatLineBreaks(text.substring(startPos, endPos));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
@@ -1,134 +0,0 @@
|
||||
(function () {
|
||||
function forEach(arr, f) {
|
||||
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
|
||||
}
|
||||
|
||||
function arrayContains(arr, item) {
|
||||
if (!Array.prototype.indexOf) {
|
||||
var i = arr.length;
|
||||
while (i--) {
|
||||
if (arr[i] === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return arr.indexOf(item) != -1;
|
||||
}
|
||||
|
||||
function scriptHint(editor, keywords, getToken) {
|
||||
// Find the token at the cursor
|
||||
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
|
||||
// If it's not a 'word-style' token, ignore the token.
|
||||
if (!/^[\w$_]*$/.test(token.string)) {
|
||||
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
||||
className: token.string == "." ? "property" : null};
|
||||
}
|
||||
// If it is a property, find out what it is a property of.
|
||||
while (tprop.className == "property") {
|
||||
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
||||
if (tprop.string != ".") return;
|
||||
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
||||
if (tprop.string == ')') {
|
||||
var level = 1;
|
||||
do {
|
||||
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
||||
switch (tprop.string) {
|
||||
case ')': level++; break;
|
||||
case '(': level--; break;
|
||||
default: break;
|
||||
}
|
||||
} while (level > 0)
|
||||
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
|
||||
if (tprop.className == 'variable')
|
||||
tprop.className = 'function';
|
||||
else return; // no clue
|
||||
}
|
||||
if (!context) var context = [];
|
||||
context.push(tprop);
|
||||
}
|
||||
return {list: getCompletions(token, context, keywords),
|
||||
from: {line: cur.line, ch: token.start},
|
||||
to: {line: cur.line, ch: token.end}};
|
||||
}
|
||||
|
||||
CodeMirror.javascriptHint = function(editor) {
|
||||
return scriptHint(editor, javascriptKeywords,
|
||||
function (e, cur) {return e.getTokenAt(cur);});
|
||||
}
|
||||
|
||||
function getCoffeeScriptToken(editor, cur) {
|
||||
// This getToken, it is for coffeescript, imitates the behavior of
|
||||
// getTokenAt method in javascript.js, that is, returning "property"
|
||||
// type and treat "." as indepenent token.
|
||||
var token = editor.getTokenAt(cur);
|
||||
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
||||
token.end = token.start;
|
||||
token.string = '.';
|
||||
token.className = "property";
|
||||
}
|
||||
else if (/^\.[\w$_]*$/.test(token.string)) {
|
||||
token.className = "property";
|
||||
token.start++;
|
||||
token.string = token.string.replace(/\./, '');
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
CodeMirror.coffeescriptHint = function(editor) {
|
||||
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
|
||||
}
|
||||
|
||||
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
||||
"toUpperCase toLowerCase split concat match replace search").split(" ");
|
||||
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
|
||||
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
|
||||
var funcProps = "prototype apply call bind".split(" ");
|
||||
var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
|
||||
"if in instanceof new null return switch throw true try typeof var void while with").split(" ");
|
||||
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
||||
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
||||
|
||||
function getCompletions(token, context, keywords) {
|
||||
var found = [], start = token.string;
|
||||
function maybeAdd(str) {
|
||||
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
}
|
||||
function gatherCompletions(obj) {
|
||||
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
||||
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
||||
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
||||
for (var name in obj) maybeAdd(name);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
// If this is a property, see if it belongs to some object we can
|
||||
// find in the current environment.
|
||||
var obj = context.pop(), base;
|
||||
if (obj.className == "variable")
|
||||
base = window[obj.string];
|
||||
else if (obj.className == "string")
|
||||
base = "";
|
||||
else if (obj.className == "atom")
|
||||
base = 1;
|
||||
else if (obj.className == "function") {
|
||||
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
||||
(typeof window.jQuery == 'function'))
|
||||
base = window.jQuery();
|
||||
else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
|
||||
base = window._();
|
||||
}
|
||||
while (base != null && context.length)
|
||||
base = base[context.pop().string];
|
||||
if (base != null) gatherCompletions(base);
|
||||
}
|
||||
else {
|
||||
// If not, just look in the window object and any local scope
|
||||
// (reading into JS mode internals to get at the local variables)
|
||||
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
||||
gatherCompletions(window);
|
||||
forEach(keywords, maybeAdd);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
})();
|
||||
@@ -1,51 +0,0 @@
|
||||
// Utility function that allows modes to be combined. The mode given
|
||||
// as the base argument takes care of most of the normal mode
|
||||
// functionality, but a second (typically simple) mode is used, which
|
||||
// can override the style of text. Both modes get to parse all of the
|
||||
// text, but when both assign a non-null style to a piece of code, the
|
||||
// overlay wins, unless the combine argument was true, in which case
|
||||
// the styles are combined.
|
||||
|
||||
CodeMirror.overlayParser = function(base, overlay, combine) {
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
base: CodeMirror.startState(base),
|
||||
overlay: CodeMirror.startState(overlay),
|
||||
basePos: 0, baseCur: null,
|
||||
overlayPos: 0, overlayCur: null
|
||||
};
|
||||
},
|
||||
copyState: function(state) {
|
||||
return {
|
||||
base: CodeMirror.copyState(base, state.base),
|
||||
overlay: CodeMirror.copyState(overlay, state.overlay),
|
||||
basePos: state.basePos, baseCur: null,
|
||||
overlayPos: state.overlayPos, overlayCur: null
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.start == state.basePos) {
|
||||
state.baseCur = base.token(stream, state.base);
|
||||
state.basePos = stream.pos;
|
||||
}
|
||||
if (stream.start == state.overlayPos) {
|
||||
stream.pos = stream.start;
|
||||
state.overlayCur = overlay.token(stream, state.overlay);
|
||||
state.overlayPos = stream.pos;
|
||||
}
|
||||
stream.pos = Math.min(state.basePos, state.overlayPos);
|
||||
if (stream.eol()) state.basePos = state.overlayPos = 0;
|
||||
|
||||
if (state.overlayCur == null) return state.baseCur;
|
||||
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
|
||||
else return state.overlayCur;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
return base.indent(state.base, textAfter);
|
||||
},
|
||||
electricChars: base.electricChars
|
||||
};
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
CodeMirror.runMode = function(string, modespec, callback, options) {
|
||||
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
|
||||
var isNode = callback.nodeType == 1;
|
||||
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
|
||||
if (isNode) {
|
||||
var node = callback, accum = [], col = 0;
|
||||
callback = function(text, style) {
|
||||
if (text == "\n") {
|
||||
accum.push("<br>");
|
||||
col = 0;
|
||||
return;
|
||||
}
|
||||
var escaped = "";
|
||||
// HTML-escape and replace tabs
|
||||
for (var pos = 0;;) {
|
||||
var idx = text.indexOf("\t", pos);
|
||||
if (idx == -1) {
|
||||
escaped += CodeMirror.htmlEscape(text.slice(pos));
|
||||
col += text.length - pos;
|
||||
break;
|
||||
} else {
|
||||
col += idx - pos;
|
||||
escaped += CodeMirror.htmlEscape(text.slice(pos, idx));
|
||||
var size = tabSize - col % tabSize;
|
||||
col += size;
|
||||
for (var i = 0; i < size; ++i) escaped += " ";
|
||||
pos = idx + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (style)
|
||||
accum.push("<span class=\"cm-" + CodeMirror.htmlEscape(style) + "\">" + escaped + "</span>");
|
||||
else
|
||||
accum.push(escaped);
|
||||
}
|
||||
}
|
||||
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
|
||||
for (var i = 0, e = lines.length; i < e; ++i) {
|
||||
if (i) callback("\n");
|
||||
var stream = new CodeMirror.StringStream(lines[i]);
|
||||
while (!stream.eol()) {
|
||||
var style = mode.token(stream, state);
|
||||
callback(stream.current(), style, i, stream.start);
|
||||
stream.start = stream.pos;
|
||||
}
|
||||
}
|
||||
if (isNode)
|
||||
node.innerHTML = accum.join("");
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
// Define search commands. Depends on dialog.js or another
|
||||
// implementation of the openDialog method.
|
||||
|
||||
// Replace works a little oddly -- it will do the replace on the next
|
||||
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
|
||||
// replace by making sure the match is no longer selected when hitting
|
||||
// Ctrl-G.
|
||||
|
||||
(function() {
|
||||
function SearchState() {
|
||||
this.posFrom = this.posTo = this.query = null;
|
||||
this.marked = [];
|
||||
}
|
||||
function getSearchState(cm) {
|
||||
return cm._searchState || (cm._searchState = new SearchState());
|
||||
}
|
||||
function dialog(cm, text, shortText, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f);
|
||||
else f(prompt(shortText, ""));
|
||||
}
|
||||
function confirmDialog(cm, text, shortText, fs) {
|
||||
if (cm.openConfirm) cm.openConfirm(text, fs);
|
||||
else if (confirm(shortText)) fs[0]();
|
||||
}
|
||||
function parseQuery(query) {
|
||||
var isRE = query.match(/^\/(.*)\/$/);
|
||||
return isRE ? new RegExp(isRE[1]) : query;
|
||||
}
|
||||
var queryDialog =
|
||||
'Search: <input type="text" style="width: 10em"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
|
||||
function doSearch(cm, rev) {
|
||||
var state = getSearchState(cm);
|
||||
if (state.query) return findNext(cm, rev);
|
||||
dialog(cm, queryDialog, "Search for:", function(query) {
|
||||
cm.operation(function() {
|
||||
if (!query || state.query) return;
|
||||
state.query = parseQuery(query);
|
||||
if (cm.lineCount() < 2000) { // This is too expensive on big documents.
|
||||
for (var cursor = cm.getSearchCursor(query); cursor.findNext();)
|
||||
state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching"));
|
||||
}
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
findNext(cm, rev);
|
||||
});
|
||||
});
|
||||
}
|
||||
function findNext(cm, rev) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
var cursor = cm.getSearchCursor(state.query, rev ? state.posFrom : state.posTo);
|
||||
if (!cursor.find(rev)) {
|
||||
cursor = cm.getSearchCursor(state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
|
||||
if (!cursor.find(rev)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
||||
})}
|
||||
function clearSearch(cm) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
if (!state.query) return;
|
||||
state.query = null;
|
||||
for (var i = 0; i < state.marked.length; ++i) state.marked[i].clear();
|
||||
state.marked.length = 0;
|
||||
})}
|
||||
|
||||
var replaceQueryDialog =
|
||||
'Replace: <input type="text" style="width: 10em"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
|
||||
var replacementQueryDialog = 'With: <input type="text" style="width: 10em">';
|
||||
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
|
||||
function replace(cm, all) {
|
||||
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
|
||||
if (!query) return;
|
||||
query = parseQuery(query);
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
|
||||
if (all) {
|
||||
cm.operation(function() {
|
||||
for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
|
||||
if (typeof query != "string") {
|
||||
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
|
||||
cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
|
||||
} else cursor.replace(text);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
clearSearch(cm);
|
||||
var cursor = cm.getSearchCursor(query, cm.getCursor());
|
||||
function advance() {
|
||||
var start = cursor.from(), match;
|
||||
if (!(match = cursor.findNext())) {
|
||||
cursor = cm.getSearchCursor(query);
|
||||
if (!(match = cursor.findNext()) ||
|
||||
(cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
confirmDialog(cm, doReplaceConfirm, "Replace?",
|
||||
[function() {doReplace(match);}, advance]);
|
||||
}
|
||||
function doReplace(match) {
|
||||
cursor.replace(typeof query == "string" ? text :
|
||||
text.replace(/\$(\d)/, function(w, i) {return match[i];}));
|
||||
advance();
|
||||
}
|
||||
advance();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
||||
CodeMirror.commands.findNext = doSearch;
|
||||
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
|
||||
CodeMirror.commands.clearSearch = clearSearch;
|
||||
CodeMirror.commands.replace = replace;
|
||||
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
|
||||
})();
|
||||
@@ -1,16 +0,0 @@
|
||||
.CodeMirror-completions {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
overflow: hidden;
|
||||
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
}
|
||||
.CodeMirror-completions select {
|
||||
background: #fafafa;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: monospace;
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
(function() {
|
||||
CodeMirror.simpleHint = function(editor, getHints) {
|
||||
// We want a single cursor position.
|
||||
if (editor.somethingSelected()) return;
|
||||
var result = getHints(editor);
|
||||
if (!result || !result.list.length) return;
|
||||
var completions = result.list;
|
||||
function insert(str) {
|
||||
editor.replaceRange(str, result.from, result.to);
|
||||
}
|
||||
// When there is only one completion, use it directly.
|
||||
if (completions.length == 1) {insert(completions[0]); return true;}
|
||||
|
||||
// Build the select widget
|
||||
var complete = document.createElement("div");
|
||||
complete.className = "CodeMirror-completions";
|
||||
var sel = complete.appendChild(document.createElement("select"));
|
||||
// Opera doesn't move the selection when pressing up/down in a
|
||||
// multi-select, but it does properly support the size property on
|
||||
// single-selects, so no multi-select is necessary.
|
||||
if (!window.opera) sel.multiple = true;
|
||||
for (var i = 0; i < completions.length; ++i) {
|
||||
var opt = sel.appendChild(document.createElement("option"));
|
||||
opt.appendChild(document.createTextNode(completions[i]));
|
||||
}
|
||||
sel.firstChild.selected = true;
|
||||
sel.size = Math.min(10, completions.length);
|
||||
var pos = editor.cursorCoords();
|
||||
complete.style.left = pos.x + "px";
|
||||
complete.style.top = pos.yBot + "px";
|
||||
document.body.appendChild(complete);
|
||||
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
||||
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
|
||||
if(winW - pos.x < sel.clientWidth)
|
||||
complete.style.left = (pos.x - sel.clientWidth) + "px";
|
||||
// Hack to hide the scrollbar.
|
||||
if (completions.length <= 10)
|
||||
complete.style.width = (sel.clientWidth - 1) + "px";
|
||||
|
||||
var done = false;
|
||||
function close() {
|
||||
if (done) return;
|
||||
done = true;
|
||||
complete.parentNode.removeChild(complete);
|
||||
}
|
||||
function pick() {
|
||||
insert(completions[sel.selectedIndex]);
|
||||
close();
|
||||
setTimeout(function(){editor.focus();}, 50);
|
||||
}
|
||||
CodeMirror.connect(sel, "blur", close);
|
||||
CodeMirror.connect(sel, "keydown", function(event) {
|
||||
var code = event.keyCode;
|
||||
// Enter
|
||||
if (code == 13) {CodeMirror.e_stop(event); pick();}
|
||||
// Escape
|
||||
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
|
||||
else if (code != 38 && code != 40) {
|
||||
close(); editor.focus();
|
||||
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
|
||||
editor.triggerOnKeyDown(event);
|
||||
setTimeout(function(){CodeMirror.simpleHint(editor, getHints);}, 50);
|
||||
}
|
||||
});
|
||||
CodeMirror.connect(sel, "dblclick", pick);
|
||||
|
||||
sel.focus();
|
||||
// Opera sometimes ignores focusing a freshly created node
|
||||
if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100);
|
||||
return true;
|
||||
};
|
||||
})();
|
||||
@@ -1,101 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: C-like mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="clike.js"></script>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
<style>.CodeMirror {border: 2px inset #dee;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: C-like mode</h1>
|
||||
|
||||
<form><textarea id="code" name="code">
|
||||
/* C demo code */
|
||||
|
||||
#include <zmq.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
|
||||
typedef struct {
|
||||
void* arg_socket;
|
||||
zmq_msg_t* arg_msg;
|
||||
char* arg_string;
|
||||
unsigned long arg_len;
|
||||
int arg_int, arg_command;
|
||||
|
||||
int signal_fd;
|
||||
int pad;
|
||||
void* context;
|
||||
sem_t sem;
|
||||
} acl_zmq_context;
|
||||
|
||||
#define p(X) (context->arg_##X)
|
||||
|
||||
void* zmq_thread(void* context_pointer) {
|
||||
acl_zmq_context* context = (acl_zmq_context*)context_pointer;
|
||||
char ok = 'K', err = 'X';
|
||||
int res;
|
||||
|
||||
while (1) {
|
||||
while ((res = sem_wait(&context->sem)) == EINTR);
|
||||
if (res) {write(context->signal_fd, &err, 1); goto cleanup;}
|
||||
switch(p(command)) {
|
||||
case 0: goto cleanup;
|
||||
case 1: p(socket) = zmq_socket(context->context, p(int)); break;
|
||||
case 2: p(int) = zmq_close(p(socket)); break;
|
||||
case 3: p(int) = zmq_bind(p(socket), p(string)); break;
|
||||
case 4: p(int) = zmq_connect(p(socket), p(string)); break;
|
||||
case 5: p(int) = zmq_getsockopt(p(socket), p(int), (void*)p(string), &p(len)); break;
|
||||
case 6: p(int) = zmq_setsockopt(p(socket), p(int), (void*)p(string), p(len)); break;
|
||||
case 7: p(int) = zmq_send(p(socket), p(msg), p(int)); break;
|
||||
case 8: p(int) = zmq_recv(p(socket), p(msg), p(int)); break;
|
||||
case 9: p(int) = zmq_poll(p(socket), p(int), p(len)); break;
|
||||
}
|
||||
p(command) = errno;
|
||||
write(context->signal_fd, &ok, 1);
|
||||
}
|
||||
cleanup:
|
||||
close(context->signal_fd);
|
||||
free(context_pointer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* zmq_thread_init(void* zmq_context, int signal_fd) {
|
||||
acl_zmq_context* context = malloc(sizeof(acl_zmq_context));
|
||||
pthread_t thread;
|
||||
|
||||
context->context = zmq_context;
|
||||
context->signal_fd = signal_fd;
|
||||
sem_init(&context->sem, 1, 0);
|
||||
pthread_create(&thread, 0, &zmq_thread, context);
|
||||
pthread_detach(thread);
|
||||
return context;
|
||||
}
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-csrc"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Simple mode that tries to handle C-like languages as well as it
|
||||
can. Takes two configuration parameters: <code>keywords</code>, an
|
||||
object whose property names are the keywords in the language,
|
||||
and <code>useCPP</code>, which determines whether C preprocessor
|
||||
directives are recognized.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-csrc</code>
|
||||
(C code), <code>text/x-c++src</code> (C++
|
||||
code), <code>text/x-java</code> (Java
|
||||
code), <code>text/x-csharp</code> (C#).</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,55 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: CSS mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="css.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: CSS mode</h1>
|
||||
<form><textarea id="code" name="code">
|
||||
/* Some example CSS */
|
||||
|
||||
@import url("something.css");
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 3em 6em;
|
||||
font-family: tahoma, arial, sans-serif;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#navigation a {
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
h1:before, h2:before {
|
||||
content: "::";
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: courier, monospace;
|
||||
font-size: 80%;
|
||||
color: #418A8A;
|
||||
}
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/css</code>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,77 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: JavaScript mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="javascript.js"></script>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: JavaScript mode</h1>
|
||||
|
||||
<div><textarea id="code" name="code">
|
||||
// Demo code (the actual new parser character stream implementation)
|
||||
|
||||
function StringStream(string) {
|
||||
this.pos = 0;
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
StringStream.prototype = {
|
||||
done: function() {return this.pos >= this.string.length;},
|
||||
peek: function() {return this.string.charAt(this.pos);},
|
||||
next: function() {
|
||||
if (this.pos < this.string.length)
|
||||
return this.string.charAt(this.pos++);
|
||||
},
|
||||
eat: function(match) {
|
||||
var ch = this.string.charAt(this.pos);
|
||||
if (typeof match == "string") var ok = ch == match;
|
||||
else var ok = ch && match.test ? match.test(ch) : match(ch);
|
||||
if (ok) {this.pos++; return ch;}
|
||||
},
|
||||
eatWhile: function(match) {
|
||||
var start = this.pos;
|
||||
while (this.eat(match));
|
||||
if (this.pos > start) return this.string.slice(start, this.pos);
|
||||
},
|
||||
backUp: function(n) {this.pos -= n;},
|
||||
column: function() {return this.pos;},
|
||||
eatSpace: function() {
|
||||
var start = this.pos;
|
||||
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
|
||||
return this.pos - start;
|
||||
},
|
||||
match: function(pattern, consume, caseInsensitive) {
|
||||
if (typeof pattern == "string") {
|
||||
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
|
||||
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
|
||||
if (consume !== false) this.pos += str.length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var match = this.string.slice(this.pos).match(pattern);
|
||||
if (match && consume !== false) this.pos += match[0].length;
|
||||
return match;
|
||||
}
|
||||
}
|
||||
};
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>JavaScript mode supports a single configuration
|
||||
option, <code>json</code>, which will set the mode to expect JSON
|
||||
data rather than a JavaScript program.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,48 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: PHP mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="../javascript/javascript.js"></script>
|
||||
<script src="../css/css.js"></script>
|
||||
<script src="../clike/clike.js"></script>
|
||||
<script src="php.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: PHP mode</h1>
|
||||
|
||||
<form><textarea id="code" name="code">
|
||||
<?php
|
||||
function hello($who) {
|
||||
return "Hello " . $who;
|
||||
}
|
||||
?>
|
||||
<p>The program says <?= hello("World") ?>.</p>
|
||||
<script>
|
||||
alert("And here is some JS code"); // also colored
|
||||
</script>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "application/x-httpd-php",
|
||||
indentUnit: 4,
|
||||
indentWithTabs: true,
|
||||
enterMode: "keep",
|
||||
tabMode: "shift"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Simple HTML/PHP mode based on
|
||||
the <a href="../clike/">C-like</a> mode. Depends on XML,
|
||||
JavaScript, CSS, and C-like modes.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/x-httpd-php</code> (HTML with PHP code), <code>text/x-php</code> (plain, non-wrapped PHP code).</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,171 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: Ruby mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="ruby.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.cm-s-default span.cm-arrow { color: red; }
|
||||
</style>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: Ruby mode</h1>
|
||||
<form><textarea id="code" name="code">
|
||||
# Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
|
||||
#
|
||||
# This program evaluates polynomials. It first asks for the coefficients
|
||||
# of a polynomial, which must be entered on one line, highest-order first.
|
||||
# It then requests values of x and will compute the value of the poly for
|
||||
# each x. It will repeatly ask for x values, unless you the user enters
|
||||
# a blank line. It that case, it will ask for another polynomial. If the
|
||||
# user types quit for either input, the program immediately exits.
|
||||
#
|
||||
|
||||
#
|
||||
# Function to evaluate a polynomial at x. The polynomial is given
|
||||
# as a list of coefficients, from the greatest to the least.
|
||||
def polyval(x, coef)
|
||||
sum = 0
|
||||
coef = coef.clone # Don't want to destroy the original
|
||||
while true
|
||||
sum += coef.shift # Add and remove the next coef
|
||||
break if coef.empty? # If no more, done entirely.
|
||||
sum *= x # This happens the right number of times.
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
#
|
||||
# Function to read a line containing a list of integers and return
|
||||
# them as an array of integers. If the string conversion fails, it
|
||||
# throws TypeError. If the input line is the word 'quit', then it
|
||||
# converts it to an end-of-file exception
|
||||
def readints(prompt)
|
||||
# Read a line
|
||||
print prompt
|
||||
line = readline.chomp
|
||||
raise EOFError.new if line == 'quit' # You can also use a real EOF.
|
||||
|
||||
# Go through each item on the line, converting each one and adding it
|
||||
# to retval.
|
||||
retval = [ ]
|
||||
for str in line.split(/\s+/)
|
||||
if str =~ /^\-?\d+$/
|
||||
retval.push(str.to_i)
|
||||
else
|
||||
raise TypeError.new
|
||||
end
|
||||
end
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
#
|
||||
# Take a coeff and an exponent and return the string representation, ignoring
|
||||
# the sign of the coefficient.
|
||||
def term_to_str(coef, exp)
|
||||
ret = ""
|
||||
|
||||
# Show coeff, unless it's 1 or at the right
|
||||
coef = coef.abs
|
||||
ret = coef.to_s unless coef == 1 && exp > 0
|
||||
ret += "x" if exp > 0 # x if exponent not 0
|
||||
ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
#
|
||||
# Create a string of the polynomial in sort-of-readable form.
|
||||
def polystr(p)
|
||||
# Get the exponent of first coefficient, plus 1.
|
||||
exp = p.length
|
||||
|
||||
# Assign exponents to each term, making pairs of coeff and exponent,
|
||||
# Then get rid of the zero terms.
|
||||
p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
|
||||
|
||||
# If there's nothing left, it's a zero
|
||||
return "0" if p.empty?
|
||||
|
||||
# *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
|
||||
|
||||
# Convert the first term, preceded by a "-" if it's negative.
|
||||
result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])
|
||||
|
||||
# Convert the rest of the terms, in each case adding the appropriate
|
||||
# + or - separating them.
|
||||
for term in p[1...p.length]
|
||||
# Add the separator then the rep. of the term.
|
||||
result += (if term[0] < 0 then " - " else " + " end) +
|
||||
term_to_str(*term)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
#
|
||||
# Run until some kind of endfile.
|
||||
begin
|
||||
# Repeat until an exception or quit gets us out.
|
||||
while true
|
||||
# Read a poly until it works. An EOF will except out of the
|
||||
# program.
|
||||
print "\n"
|
||||
begin
|
||||
poly = readints("Enter a polynomial coefficients: ")
|
||||
rescue TypeError
|
||||
print "Try again.\n"
|
||||
retry
|
||||
end
|
||||
break if poly.empty?
|
||||
|
||||
# Read and evaluate x values until the user types a blank line.
|
||||
# Again, an EOF will except out of the pgm.
|
||||
while true
|
||||
# Request an integer.
|
||||
print "Enter x value or blank line: "
|
||||
x = readline.chomp
|
||||
break if x == ''
|
||||
raise EOFError.new if x == 'quit'
|
||||
|
||||
# If it looks bad, let's try again.
|
||||
if x !~ /^\-?\d+$/
|
||||
print "That doesn't look like an integer. Please try again.\n"
|
||||
next
|
||||
end
|
||||
|
||||
# Convert to an integer and print the result.
|
||||
x = x.to_i
|
||||
print "p(x) = ", polystr(poly), "\n"
|
||||
print "p(", x, ") = ", polyval(x, poly), "\n"
|
||||
end
|
||||
end
|
||||
rescue EOFError
|
||||
print "\n=== EOF ===\n"
|
||||
rescue Interrupt, SignalException
|
||||
print "\n=== Interrupted ===\n"
|
||||
else
|
||||
print "--- Bye ---\n"
|
||||
end
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/x-ruby",
|
||||
tabMode: "indent",
|
||||
matchBrackets: true,
|
||||
indentUnit: 4
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>
|
||||
|
||||
<p>Development of the CodeMirror Ruby mode was kindly sponsored
|
||||
by <a href="http://ubalo.com/">Ubalo</a>, who hold
|
||||
the <a href="LICENSE">license</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,44 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CodeMirror: XML mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="xml.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: XML mode</h1>
|
||||
<form><textarea id="code" name="code">
|
||||
<html style="color: green">
|
||||
<!-- this is a comment -->
|
||||
<head>
|
||||
<title>HTML Example</title>
|
||||
</head>
|
||||
<body>
|
||||
The indentation tries to be <em>somewhat &quot;do what
|
||||
I mean&quot;</em>... but might not match your style.
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: {name: "xml", alignCDATA: true},
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
<p>The XML mode supports two configuration parameters:</p>
|
||||
<dl>
|
||||
<dt><code>htmlMode (boolean)</code></dt>
|
||||
<dd>This switches the mode to parse HTML instead of XML. This
|
||||
means attributes do not have to be quoted, and some elements
|
||||
(such as <code>br</code>) do not require a closing tag.</dd>
|
||||
<dt><code>alignCDATA (boolean)</code></dt>
|
||||
<dd>Setting this to true will force the opening tag of CDATA
|
||||
blocks to not be indented.</dd>
|
||||
</dl>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.com>
|
||||
Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -42,11 +42,14 @@
|
||||
padding: 0; margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
.CodeMirror-wrap .CodeMirror-scroll {
|
||||
overflow-x: hidden;
|
||||
@@ -61,8 +64,19 @@
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
border-left: 1px solid black;
|
||||
border-right:none;
|
||||
width:0;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
.cm-keymap-fat-cursor pre.CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
background: rgba(0, 200, 0, .4);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
|
||||
}
|
||||
/* Kludge to turn off filter in ie9+, which also accepts rgba */
|
||||
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
|
||||
.CodeMirror-focused pre.CodeMirror-cursor {
|
||||
@@ -98,7 +112,7 @@ div.CodeMirror-selected { background: #d9d9d9; }
|
||||
.cm-s-default span.cm-bracket {color: #cc7;}
|
||||
.cm-s-default span.cm-tag {color: #170;}
|
||||
.cm-s-default span.cm-attribute {color: #00c;}
|
||||
.cm-s-default span.cm-header {color: #a0a;}
|
||||
.cm-s-default span.cm-header {color: blue;}
|
||||
.cm-s-default span.cm-quote {color: #090;}
|
||||
.cm-s-default span.cm-hr {color: #999;}
|
||||
.cm-s-default span.cm-link {color: #00c;}
|
||||
@@ -1,4 +1,4 @@
|
||||
// CodeMirror version 2.23
|
||||
// CodeMirror version 2.25
|
||||
//
|
||||
// All functions that need access to the editor's state live inside
|
||||
// the CodeMirror function. Below that, at the bottom of the file,
|
||||
@@ -41,7 +41,7 @@ var CodeMirror = (function() {
|
||||
lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
|
||||
cursor = measure.nextSibling, selectionDiv = cursor.nextSibling,
|
||||
lineDiv = selectionDiv.nextSibling;
|
||||
themeChanged();
|
||||
themeChanged(); keyMapChanged();
|
||||
// Needed to hide big blue blinking cursor on Mobile Safari
|
||||
if (ios) input.style.width = "0px";
|
||||
if (!webkit) lineSpace.draggable = true;
|
||||
@@ -80,7 +80,7 @@ var CodeMirror = (function() {
|
||||
// Variables used by startOperation/endOperation to track what
|
||||
// happened during the operation.
|
||||
var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,
|
||||
gutterDirty, callbacks;
|
||||
gutterDirty, callbacks, maxLengthChanged;
|
||||
// Current visible range (may be bigger than the view window).
|
||||
var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
|
||||
// bracketHighlighted is used to remember that a bracket has been
|
||||
@@ -98,7 +98,6 @@ var CodeMirror = (function() {
|
||||
// Register our event handlers.
|
||||
connect(scroller, "mousedown", operation(onMouseDown));
|
||||
connect(scroller, "dblclick", operation(onDoubleClick));
|
||||
connect(lineSpace, "dragstart", onDragStart);
|
||||
connect(lineSpace, "selectstart", e_preventDefault);
|
||||
// Gecko browsers fire contextmenu *after* opening the menu, at
|
||||
// which point we can't mess with it anymore. Context menu is
|
||||
@@ -118,9 +117,16 @@ var CodeMirror = (function() {
|
||||
connect(input, "focus", onFocus);
|
||||
connect(input, "blur", onBlur);
|
||||
|
||||
connect(scroller, "dragenter", e_stop);
|
||||
connect(scroller, "dragover", e_stop);
|
||||
connect(scroller, "drop", operation(onDrop));
|
||||
if (options.dragDrop) {
|
||||
connect(lineSpace, "dragstart", onDragStart);
|
||||
function drag_(e) {
|
||||
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
||||
e_stop(e);
|
||||
}
|
||||
connect(scroller, "dragenter", drag_);
|
||||
connect(scroller, "dragover", drag_);
|
||||
connect(scroller, "drop", operation(onDrop));
|
||||
}
|
||||
connect(scroller, "paste", function(){focusInput(); fastPoll();});
|
||||
connect(input, "paste", fastPoll);
|
||||
connect(input, "cut", operation(function(){
|
||||
@@ -160,6 +166,7 @@ var CodeMirror = (function() {
|
||||
else if (option == "theme") themeChanged();
|
||||
else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
|
||||
else if (option == "tabSize") updateDisplay(true);
|
||||
else if (option == "keyMap") keyMapChanged();
|
||||
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") {
|
||||
gutterChanged();
|
||||
updateDisplay(true);
|
||||
@@ -312,6 +319,7 @@ var CodeMirror = (function() {
|
||||
},
|
||||
|
||||
operation: function(f){return operation(f)();},
|
||||
compoundChange: function(f){return compoundChange(f);},
|
||||
refresh: function(){
|
||||
updateDisplay(true);
|
||||
if (scroller.scrollHeight > lastScrollPos)
|
||||
@@ -336,7 +344,7 @@ var CodeMirror = (function() {
|
||||
splitLines(code), top, top);
|
||||
updateInput = true;
|
||||
}
|
||||
function getValue(code) {
|
||||
function getValue() {
|
||||
var text = [];
|
||||
doc.iter(0, doc.size, function(line) { text.push(line.text); });
|
||||
return text.join("\n");
|
||||
@@ -364,6 +372,7 @@ var CodeMirror = (function() {
|
||||
return;
|
||||
case 2:
|
||||
if (start) setCursor(start.line, start.ch, true);
|
||||
setTimeout(focusInput, 20);
|
||||
return;
|
||||
}
|
||||
// For button 1, if it was clicked inside the editor
|
||||
@@ -385,20 +394,22 @@ var CodeMirror = (function() {
|
||||
} else { lastClick = {time: now, pos: start}; }
|
||||
|
||||
var last = start, going;
|
||||
if (dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
||||
if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
|
||||
!posLess(start, sel.from) && !posLess(sel.to, start)) {
|
||||
// Let the drag handler handle this.
|
||||
if (webkit) lineSpace.draggable = true;
|
||||
var up = connect(document, "mouseup", operation(function(e2) {
|
||||
function dragEnd(e2) {
|
||||
if (webkit) lineSpace.draggable = false;
|
||||
draggingText = false;
|
||||
up();
|
||||
up(); drop();
|
||||
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
|
||||
e_preventDefault(e2);
|
||||
setCursor(start.line, start.ch, true);
|
||||
focusInput();
|
||||
}
|
||||
}), true);
|
||||
}
|
||||
var up = connect(document, "mouseup", operation(dragEnd), true);
|
||||
var drop = connect(scroller, "drop", operation(dragEnd), true);
|
||||
draggingText = true;
|
||||
// IE's approach to draggable
|
||||
if (lineSpace.dragDrop) lineSpace.dragDrop();
|
||||
@@ -447,6 +458,7 @@ var CodeMirror = (function() {
|
||||
selectWordAt(start);
|
||||
}
|
||||
function onDrop(e) {
|
||||
if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
|
||||
e.preventDefault();
|
||||
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
|
||||
if (!pos || options.readOnly) return;
|
||||
@@ -456,12 +468,12 @@ var CodeMirror = (function() {
|
||||
reader.onload = function() {
|
||||
text[i] = reader.result;
|
||||
if (++read == n) {
|
||||
pos = clipPos(pos);
|
||||
operation(function() {
|
||||
pos = clipPos(pos);
|
||||
operation(function() {
|
||||
var end = replaceRange(text.join(""), pos, pos);
|
||||
setSelectionUser(pos, end);
|
||||
})();
|
||||
}
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
@@ -472,12 +484,14 @@ var CodeMirror = (function() {
|
||||
try {
|
||||
var text = e.dataTransfer.getData("Text");
|
||||
if (text) {
|
||||
var curFrom = sel.from, curTo = sel.to;
|
||||
setSelectionUser(pos, pos);
|
||||
if (draggingText) replaceRange("", curFrom, curTo);
|
||||
replaceSelection(text);
|
||||
focusInput();
|
||||
}
|
||||
compoundChange(function() {
|
||||
var curFrom = sel.from, curTo = sel.to;
|
||||
setSelectionUser(pos, pos);
|
||||
if (draggingText) replaceRange("", curFrom, curTo);
|
||||
replaceSelection(text);
|
||||
focusInput();
|
||||
});
|
||||
}
|
||||
}
|
||||
catch(e){}
|
||||
}
|
||||
@@ -529,25 +543,33 @@ var CodeMirror = (function() {
|
||||
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
||||
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
||||
|
||||
var stopped = false;
|
||||
function stop() { stopped = true; }
|
||||
|
||||
if (e_prop(e, "shiftKey")) {
|
||||
handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
|
||||
function(b) {return doHandleBinding(b, true);})
|
||||
function(b) {return doHandleBinding(b, true);}, stop)
|
||||
|| lookupKey(name, options.extraKeys, options.keyMap, function(b) {
|
||||
if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
|
||||
});
|
||||
}, stop);
|
||||
} else {
|
||||
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding);
|
||||
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
|
||||
}
|
||||
if (stopped) handled = false;
|
||||
if (handled) {
|
||||
e_preventDefault(e);
|
||||
restartBlink();
|
||||
if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
function handleCharBinding(e, ch) {
|
||||
var handled = lookupKey("'" + ch + "'", options.extraKeys,
|
||||
options.keyMap, doHandleBinding);
|
||||
if (handled) e_preventDefault(e);
|
||||
options.keyMap, function(b) { return doHandleBinding(b, true); });
|
||||
if (handled) {
|
||||
e_preventDefault(e);
|
||||
restartBlink();
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
@@ -574,7 +596,7 @@ var CodeMirror = (function() {
|
||||
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
||||
var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
|
||||
if (window.opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
||||
if (((window.opera && !e.which) || khtml) && handleKeyBinding(e)) return;
|
||||
if (((window.opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(e)) return;
|
||||
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
|
||||
if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
|
||||
if (mode.electricChars.indexOf(ch) > -1)
|
||||
@@ -648,8 +670,8 @@ var CodeMirror = (function() {
|
||||
if (suppressEdits) return;
|
||||
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
||||
if (!options.lineWrapping)
|
||||
doc.iter(from.line, to.line, function(line) {
|
||||
if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
||||
doc.iter(from.line, to.line + 1, function(line) {
|
||||
if (!line.hidden && line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
||||
});
|
||||
if (from.line != to.line || newText.length > 1) gutterDirty = true;
|
||||
|
||||
@@ -696,29 +718,21 @@ var CodeMirror = (function() {
|
||||
doc.insert(from.line + 1, added);
|
||||
}
|
||||
if (options.lineWrapping) {
|
||||
var perLine = scroller.clientWidth / charWidth() - 3;
|
||||
var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
|
||||
doc.iter(from.line, from.line + newText.length, function(line) {
|
||||
if (line.hidden) return;
|
||||
var guess = Math.ceil(line.text.length / perLine) || 1;
|
||||
if (guess != line.height) updateLineHeight(line, guess);
|
||||
});
|
||||
} else {
|
||||
doc.iter(from.line, i + newText.length, function(line) {
|
||||
doc.iter(from.line, from.line + newText.length, function(line) {
|
||||
var l = line.text;
|
||||
if (l.length > maxLineLength) {
|
||||
if (!line.hidden && l.length > maxLineLength) {
|
||||
maxLine = l; maxLineLength = l.length; maxWidth = null;
|
||||
recomputeMaxLength = false;
|
||||
}
|
||||
});
|
||||
if (recomputeMaxLength) {
|
||||
maxLineLength = 0; maxLine = ""; maxWidth = null;
|
||||
doc.iter(0, doc.size, function(line) {
|
||||
var l = line.text;
|
||||
if (l.length > maxLineLength) {
|
||||
maxLineLength = l.length; maxLine = l;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (recomputeMaxLength) maxLengthChanged = true;
|
||||
}
|
||||
|
||||
// Add these lines to the work array, so that they will be
|
||||
@@ -750,6 +764,18 @@ var CodeMirror = (function() {
|
||||
if (scroller.clientHeight)
|
||||
code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
|
||||
}
|
||||
|
||||
function computeMaxLength() {
|
||||
var maxLineLength = 0;
|
||||
maxLine = ""; maxWidth = null;
|
||||
doc.iter(0, doc.size, function(line) {
|
||||
var l = line.text;
|
||||
if (!line.hidden && l.length > maxLineLength) {
|
||||
maxLineLength = l.length; maxLine = l;
|
||||
}
|
||||
});
|
||||
maxLengthChanged = false;
|
||||
}
|
||||
|
||||
function replaceRange(code, from, to) {
|
||||
from = clipPos(from);
|
||||
@@ -837,7 +863,8 @@ var CodeMirror = (function() {
|
||||
else if (overwrite && posEq(sel.from, sel.to))
|
||||
sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
|
||||
replaceSelection(text.slice(same), "end");
|
||||
prevInput = text;
|
||||
if (text.length > 1000) { input.value = prevInput = ""; }
|
||||
else prevInput = text;
|
||||
return true;
|
||||
}
|
||||
function resetInput(user) {
|
||||
@@ -874,8 +901,9 @@ var CodeMirror = (function() {
|
||||
|
||||
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
|
||||
var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
|
||||
if (x1 < screenleft + gutterw) {
|
||||
if (x1 < 50) x1 = 0;
|
||||
var atLeft = x1 < gutterw + pl + 10;
|
||||
if (x1 < screenleft + gutterw || atLeft) {
|
||||
if (atLeft) x1 = 0;
|
||||
scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
|
||||
scrolled = true;
|
||||
}
|
||||
@@ -890,10 +918,10 @@ var CodeMirror = (function() {
|
||||
|
||||
function visibleLines() {
|
||||
var lh = textHeight(), top = scroller.scrollTop - paddingTop();
|
||||
var from_height = Math.max(0, Math.floor(top / lh));
|
||||
var to_height = Math.ceil((top + scroller.clientHeight) / lh);
|
||||
return {from: lineAtHeight(doc, from_height),
|
||||
to: lineAtHeight(doc, to_height)};
|
||||
var fromHeight = Math.max(0, Math.floor(top / lh));
|
||||
var toHeight = Math.ceil((top + scroller.clientHeight) / lh);
|
||||
return {from: lineAtHeight(doc, fromHeight),
|
||||
to: lineAtHeight(doc, toHeight)};
|
||||
}
|
||||
// Uses a set of changes plus the current scroll position to
|
||||
// determine which DOM updates have to be made, and makes the
|
||||
@@ -924,7 +952,7 @@ var CodeMirror = (function() {
|
||||
if (range.from >= range.to) intact.splice(i--, 1);
|
||||
else intactLines += range.to - range.from;
|
||||
}
|
||||
if (intactLines == to - from) return;
|
||||
if (intactLines == to - from && from == showingFrom && to == showingTo) return;
|
||||
intact.sort(function(a, b) {return a.domStart - b.domStart;});
|
||||
|
||||
var th = textHeight(), gutterDisplay = gutter.style.display;
|
||||
@@ -1108,12 +1136,14 @@ var CodeMirror = (function() {
|
||||
selectionDiv.style.display = "none";
|
||||
} else {
|
||||
var sameLine = fromPos.y == toPos.y, html = "";
|
||||
function add(left, top, right, height) {
|
||||
html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
|
||||
'px; top: ' + top + 'px; right: ' + right + 'px; height: ' + height + 'px"></div>';
|
||||
}
|
||||
var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
||||
var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
||||
function add(left, top, right, height) {
|
||||
var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
|
||||
: "right: " + right + "px";
|
||||
html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
|
||||
'px; top: ' + top + 'px; ' + rstyle + '; height: ' + height + 'px"></div>';
|
||||
}
|
||||
if (sel.from.ch && fromPos.y >= 0) {
|
||||
var right = sameLine ? clientWidth - toPos.x : 0;
|
||||
add(fromPos.x, fromPos.y, right, th);
|
||||
@@ -1189,13 +1219,14 @@ var CodeMirror = (function() {
|
||||
var line = getLine(lNo);
|
||||
if (!line.hidden) {
|
||||
var ch = pos.ch;
|
||||
if (ch > oldCh || ch > line.text.length) ch = line.text.length;
|
||||
if (toEnd || ch > oldCh || ch > line.text.length) ch = line.text.length;
|
||||
return {line: lNo, ch: ch};
|
||||
}
|
||||
lNo += dir;
|
||||
}
|
||||
}
|
||||
var line = getLine(pos.line);
|
||||
var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
|
||||
if (!line.hidden) return pos;
|
||||
if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
|
||||
else return getNonHidden(-1) || getNonHidden(1);
|
||||
@@ -1355,9 +1386,14 @@ var CodeMirror = (function() {
|
||||
return (tabCache[w] = {html: str + "</span>", width: w});
|
||||
}
|
||||
function themeChanged() {
|
||||
scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
|
||||
scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
|
||||
options.theme.replace(/(^|\s)\s*/g, " cm-s-");
|
||||
}
|
||||
function keyMapChanged() {
|
||||
var style = keyMap[options.keyMap].style;
|
||||
wrapper.className = wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
|
||||
(style ? " cm-keymap-" + style : "");
|
||||
}
|
||||
|
||||
function TextMarker() { this.set = []; }
|
||||
TextMarker.prototype.clear = operation(function() {
|
||||
@@ -1465,6 +1501,16 @@ var CodeMirror = (function() {
|
||||
return changeLine(handle, function(line, no) {
|
||||
if (line.hidden != hidden) {
|
||||
line.hidden = hidden;
|
||||
if (!options.lineWrapping) {
|
||||
var l = line.text;
|
||||
if (hidden && l.length == maxLine.length) {
|
||||
maxLengthChanged = true;
|
||||
}
|
||||
else if (!hidden && l.length > maxLine.length) {
|
||||
maxLine = l; maxWidth = null;
|
||||
maxLengthChanged = false;
|
||||
}
|
||||
}
|
||||
updateLineHeight(line, hidden ? 0 : 1);
|
||||
var fline = sel.from.line, tline = sel.to.line;
|
||||
if (hidden && (fline == no || tline == no)) {
|
||||
@@ -1506,8 +1552,7 @@ var CodeMirror = (function() {
|
||||
if (x <= 0) return 0;
|
||||
var lineObj = getLine(line), text = lineObj.text;
|
||||
function getX(len) {
|
||||
measure.innerHTML = "<pre><span>" + lineObj.getHTML(makeTab, len) + "</span></pre>";
|
||||
return measure.firstChild.firstChild.offsetWidth;
|
||||
return measureLine(lineObj, len).left;
|
||||
}
|
||||
var from = 0, fromX = 0, to = text.length, toX;
|
||||
// Guess a suitable upper bound for our search.
|
||||
@@ -1530,19 +1575,13 @@ var CodeMirror = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
|
||||
var tempId = "CodeMirror-temp-" + Math.floor(Math.random() * 0xffffff).toString(16);
|
||||
function measureLine(line, ch) {
|
||||
if (ch == 0) return {top: 0, left: 0};
|
||||
var extra = "";
|
||||
// Include extra text at the end to make sure the measured line is wrapped in the right way.
|
||||
if (options.lineWrapping) {
|
||||
var end = line.text.indexOf(" ", ch + 6);
|
||||
extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
|
||||
}
|
||||
measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch) +
|
||||
'<span id="CodeMirror-temp-' + tempId + '">' + htmlEscape(line.text.charAt(ch) || " ") + "</span>" +
|
||||
extra + "</pre>";
|
||||
var elt = document.getElementById("CodeMirror-temp-" + tempId);
|
||||
var wbr = options.lineWrapping && ch < line.text.length &&
|
||||
spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1));
|
||||
measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch, tempId, wbr) + "</pre>";
|
||||
var elt = document.getElementById(tempId);
|
||||
var top = elt.offsetTop, left = elt.offsetLeft;
|
||||
// Older IEs report zero offsets for spans directly after a wrap
|
||||
if (ie && top == 0 && left == 0) {
|
||||
@@ -1790,13 +1829,17 @@ var CodeMirror = (function() {
|
||||
var changed = line.highlight(mode, state, options.tabSize);
|
||||
if (changed) realChange = true;
|
||||
line.stateAfter = copyState(mode, state);
|
||||
var done = null;
|
||||
if (compare) {
|
||||
if (hadState && compare(hadState, state)) return true;
|
||||
} else {
|
||||
var same = hadState && compare(hadState, state);
|
||||
if (same != Pass) done = !!same;
|
||||
}
|
||||
if (done == null) {
|
||||
if (changed !== false || !hadState) unchanged = 0;
|
||||
else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
|
||||
return true;
|
||||
done = true;
|
||||
}
|
||||
if (done) return true;
|
||||
++i;
|
||||
});
|
||||
if (bail) return;
|
||||
@@ -1820,6 +1863,7 @@ var CodeMirror = (function() {
|
||||
}
|
||||
function endOperation() {
|
||||
var reScroll = false, updated;
|
||||
if (maxLengthChanged) computeMaxLength();
|
||||
if (selectionChanged) reScroll = !scrollCursorIntoView();
|
||||
if (changes.length) updated = updateDisplay(changes, true);
|
||||
else {
|
||||
@@ -1856,6 +1900,11 @@ var CodeMirror = (function() {
|
||||
};
|
||||
}
|
||||
|
||||
function compoundChange(f) {
|
||||
history.startCompound();
|
||||
try { return f(); } finally { history.endCompound(); }
|
||||
}
|
||||
|
||||
for (var ext in extensions)
|
||||
if (extensions.propertyIsEnumerable(ext) &&
|
||||
!instance.propertyIsEnumerable(ext))
|
||||
@@ -1877,12 +1926,14 @@ var CodeMirror = (function() {
|
||||
electricChars: true,
|
||||
autoClearEmptyLines: false,
|
||||
onKeyEvent: null,
|
||||
onDragEvent: null,
|
||||
lineWrapping: false,
|
||||
lineNumbers: false,
|
||||
gutter: false,
|
||||
fixedGutter: false,
|
||||
firstLineNumber: 1,
|
||||
readOnly: false,
|
||||
dragDrop: true,
|
||||
onChange: null,
|
||||
onCursorActivity: null,
|
||||
onGutterClick: null,
|
||||
@@ -1906,6 +1957,10 @@ var CodeMirror = (function() {
|
||||
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
||||
CodeMirror.defineMode = function(name, mode) {
|
||||
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
||||
if (arguments.length > 2) {
|
||||
mode.dependencies = [];
|
||||
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
|
||||
}
|
||||
modes[name] = mode;
|
||||
};
|
||||
CodeMirror.defineMIME = function(mime, spec) {
|
||||
@@ -1922,10 +1977,7 @@ var CodeMirror = (function() {
|
||||
CodeMirror.getMode = function(options, spec) {
|
||||
var spec = CodeMirror.resolveMode(spec);
|
||||
var mfactory = modes[spec.name];
|
||||
if (!mfactory) {
|
||||
if (window.console) console.warn("No mode " + spec.name + " found, falling back to plain text.");
|
||||
return CodeMirror.getMode(options, "text/plain");
|
||||
}
|
||||
if (!mfactory) return CodeMirror.getMode(options, "text/plain");
|
||||
return mfactory(options, spec);
|
||||
};
|
||||
CodeMirror.listModes = function() {
|
||||
@@ -1983,6 +2035,10 @@ var CodeMirror = (function() {
|
||||
indentMore: function(cm) {cm.indentSelection("add");},
|
||||
indentLess: function(cm) {cm.indentSelection("subtract");},
|
||||
insertTab: function(cm) {cm.replaceSelection("\t", "end");},
|
||||
defaultTab: function(cm) {
|
||||
if (cm.somethingSelected()) cm.indentSelection("add");
|
||||
else cm.replaceSelection("\t", "end");
|
||||
},
|
||||
transposeChars: function(cm) {
|
||||
var cur = cm.getCursor(), line = cm.getLine(cur.line);
|
||||
if (cur.ch > 0 && cur.ch < line.length - 1)
|
||||
@@ -2000,7 +2056,7 @@ var CodeMirror = (function() {
|
||||
keyMap.basic = {
|
||||
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
|
||||
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
|
||||
"Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "insertTab", "Shift-Tab": "indentAuto",
|
||||
"Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
|
||||
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
|
||||
};
|
||||
// Note that the save and find-related commands aren't defined by
|
||||
@@ -2035,12 +2091,15 @@ var CodeMirror = (function() {
|
||||
if (typeof val == "string") return keyMap[val];
|
||||
else return val;
|
||||
}
|
||||
function lookupKey(name, extraMap, map, handle) {
|
||||
function lookupKey(name, extraMap, map, handle, stop) {
|
||||
function lookup(map) {
|
||||
map = getKeyMap(map);
|
||||
var found = map[name];
|
||||
if (found != null && handle(found)) return true;
|
||||
if (map.catchall) return handle(map.catchall);
|
||||
if (map.nofallthrough) {
|
||||
if (stop) stop();
|
||||
return true;
|
||||
}
|
||||
var fallthrough = map.fallthrough;
|
||||
if (fallthrough == null) return false;
|
||||
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
|
||||
@@ -2402,9 +2461,9 @@ var CodeMirror = (function() {
|
||||
indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
|
||||
// Produces an HTML fragment for the line, taking selection,
|
||||
// marking, and highlighting into account.
|
||||
getHTML: function(makeTab, endAt) {
|
||||
getHTML: function(makeTab, wrapAt, wrapId, wrapWBR) {
|
||||
var html = [], first = true, col = 0;
|
||||
function span(text, style) {
|
||||
function span_(text, style) {
|
||||
if (!text) return;
|
||||
// Work around a bug where, in some compat modes, IE ignores leading spaces
|
||||
if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
|
||||
@@ -2432,24 +2491,52 @@ var CodeMirror = (function() {
|
||||
if (style) html.push('<span class="', style, '">', escaped, "</span>");
|
||||
else html.push(escaped);
|
||||
}
|
||||
var span = span_;
|
||||
if (wrapAt != null) {
|
||||
var outPos = 0, open = "<span id=\"" + wrapId + "\">";
|
||||
span = function(text, style) {
|
||||
var l = text.length;
|
||||
if (wrapAt >= outPos && wrapAt < outPos + l) {
|
||||
if (wrapAt > outPos) {
|
||||
span_(text.slice(0, wrapAt - outPos), style);
|
||||
// See comment at the definition of spanAffectsWrapping
|
||||
if (wrapWBR) html.push("<wbr>");
|
||||
}
|
||||
html.push(open);
|
||||
var cut = wrapAt - outPos;
|
||||
span_(window.opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
|
||||
html.push("</span>");
|
||||
if (window.opera) span_(text.slice(cut + 1), style);
|
||||
wrapAt--;
|
||||
outPos += l;
|
||||
} else {
|
||||
outPos += l;
|
||||
span_(text, style);
|
||||
// Output empty wrapper when at end of line
|
||||
if (outPos == wrapAt && outPos == len) html.push(open + " </span>");
|
||||
// Stop outputting HTML when gone sufficiently far beyond measure
|
||||
else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var st = this.styles, allText = this.text, marked = this.marked;
|
||||
var len = allText.length;
|
||||
if (endAt != null) len = Math.min(endAt, len);
|
||||
function styleToClass(style) {
|
||||
if (!style) return null;
|
||||
return "cm-" + style.replace(/ +/g, " cm-");
|
||||
}
|
||||
|
||||
if (!allText && endAt == null)
|
||||
if (!allText && wrapAt == null) {
|
||||
span(" ");
|
||||
else if (!marked || !marked.length)
|
||||
} else if (!marked || !marked.length) {
|
||||
for (var i = 0, ch = 0; ch < len; i+=2) {
|
||||
var str = st[i], style = st[i+1], l = str.length;
|
||||
if (ch + l > len) str = str.slice(0, len - ch);
|
||||
ch += l;
|
||||
span(str, styleToClass(style));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
var pos = 0, i = 0, text = "", style, sg = 0;
|
||||
var nextChange = marked[0].from || 0, marks = [], markpos = 0;
|
||||
function advanceMarks() {
|
||||
@@ -2535,7 +2622,7 @@ var CodeMirror = (function() {
|
||||
},
|
||||
insertHeight: function(at, lines, height) {
|
||||
this.height += height;
|
||||
this.lines.splice.apply(this.lines, [at, 0].concat(lines));
|
||||
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
|
||||
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
|
||||
},
|
||||
iterN: function(at, n, op) {
|
||||
@@ -2701,33 +2788,36 @@ var CodeMirror = (function() {
|
||||
function History() {
|
||||
this.time = 0;
|
||||
this.done = []; this.undone = [];
|
||||
this.compound = 0;
|
||||
this.closed = false;
|
||||
}
|
||||
History.prototype = {
|
||||
addChange: function(start, added, old) {
|
||||
this.undone.length = 0;
|
||||
var time = +new Date, cur = this.done[this.done.length - 1], last = cur && cur[cur.length - 1];
|
||||
var dtime = time - this.time;
|
||||
if (dtime > 400 || !last) {
|
||||
this.done.push([{start: start, added: added, old: old}]);
|
||||
} else if (last.start > start + old.length || last.start + last.added < start - last.added + last.old.length) {
|
||||
|
||||
if (this.compound && cur && !this.closed) {
|
||||
cur.push({start: start, added: added, old: old});
|
||||
} else if (dtime > 400 || !last || this.closed ||
|
||||
last.start > start + old.length || last.start + last.added < start) {
|
||||
this.done.push([{start: start, added: added, old: old}]);
|
||||
this.closed = false;
|
||||
} else {
|
||||
var oldoff = 0;
|
||||
if (start < last.start) {
|
||||
for (var i = last.start - start - 1; i >= 0; --i)
|
||||
last.old.unshift(old[i]);
|
||||
oldoff = Math.min(0, added - old.length);
|
||||
last.added += last.start - start + oldoff;
|
||||
last.start = start;
|
||||
} else if (last.start < start) {
|
||||
oldoff = start - last.start;
|
||||
added += oldoff;
|
||||
}
|
||||
for (var i = last.added - oldoff, e = old.length; i < e; ++i)
|
||||
last.old.push(old[i]);
|
||||
if (last.added < added) last.added = added;
|
||||
var startBefore = Math.max(0, last.start - start),
|
||||
endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
|
||||
for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
|
||||
for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
|
||||
if (startBefore) last.start = start;
|
||||
last.added += added - (old.length - startBefore - endAfter);
|
||||
}
|
||||
this.time = time;
|
||||
},
|
||||
startCompound: function() {
|
||||
if (!this.compound++) this.closed = true;
|
||||
},
|
||||
endCompound: function() {
|
||||
if (!--this.compound) this.closed = true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2789,8 +2879,10 @@ var CodeMirror = (function() {
|
||||
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
||||
var ie = /MSIE \d/.test(navigator.userAgent);
|
||||
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
||||
var quirksMode = ie && document.documentMode == 5;
|
||||
var webkit = /WebKit\//.test(navigator.userAgent);
|
||||
var chrome = /Chrome\//.test(navigator.userAgent);
|
||||
var safari = /Apple Computer/.test(navigator.vendor);
|
||||
var khtml = /KHTML\//.test(navigator.userAgent);
|
||||
|
||||
// Detect drag-and-drop
|
||||
@@ -2802,13 +2894,25 @@ var CodeMirror = (function() {
|
||||
return "draggable" in div || "dragDrop" in div;
|
||||
}();
|
||||
|
||||
var lineSep = "\n";
|
||||
// Feature-detect whether newlines in textareas are converted to \r\n
|
||||
(function () {
|
||||
var lineSep = function () {
|
||||
var te = document.createElement("textarea");
|
||||
te.value = "foo\nbar";
|
||||
if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
|
||||
}());
|
||||
if (te.value.indexOf("\r") > -1) return "\r\n";
|
||||
return "\n";
|
||||
}();
|
||||
|
||||
// For a reason I have yet to figure out, some browsers disallow
|
||||
// word wrapping between certain characters *only* if a new inline
|
||||
// element is started between them. This makes it hard to reliably
|
||||
// measure the position of things, since that requires inserting an
|
||||
// extra span. This terribly fragile set of regexps matches the
|
||||
// character combinations that suffer from this phenomenon on the
|
||||
// various browsers.
|
||||
var spanAffectsWrapping = /^$/; // Won't match any two-character string
|
||||
if (gecko) spanAffectsWrapping = /$'/;
|
||||
else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
|
||||
else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
|
||||
|
||||
// Counts the column offset in a string, taking tabs into account.
|
||||
// Used mostly to find indentation.
|
||||
@@ -1,7 +1,7 @@
|
||||
// the tagRangeFinder function is
|
||||
// Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
|
||||
// released under the MIT license (../../LICENSE) like the rest of CodeMirror
|
||||
CodeMirror.tagRangeFinder = function(cm, line) {
|
||||
CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
|
||||
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
|
||||
var nameChar = nameStartChar + "\-\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
|
||||
var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
|
||||
@@ -36,8 +36,10 @@ CodeMirror.tagRangeFinder = function(cm, line) {
|
||||
var slash = lt.lastIndexOf("/", gt);
|
||||
if (-1 != slash && slash < gt) {
|
||||
var str = lineText.substr(slash, gt - slash + 1);
|
||||
if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag
|
||||
if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag
|
||||
if (hideEnd === true) l++;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
l++;
|
||||
@@ -95,8 +97,10 @@ CodeMirror.tagRangeFinder = function(cm, line) {
|
||||
depth--;
|
||||
else
|
||||
depth++;
|
||||
if (!depth)
|
||||
if (!depth) {
|
||||
if (hideEnd === true) l++;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
l++;
|
||||
@@ -105,7 +109,7 @@ CodeMirror.tagRangeFinder = function(cm, line) {
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.braceRangeFinder = function(cm, line) {
|
||||
CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
|
||||
var lineText = cm.getLine(line);
|
||||
var startChar = lineText.lastIndexOf("{");
|
||||
if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
|
||||
@@ -127,6 +131,7 @@ CodeMirror.braceRangeFinder = function(cm, line) {
|
||||
}
|
||||
}
|
||||
if (end == null || end == line + 1) return;
|
||||
if (hideEnd === true) end++;
|
||||
return end;
|
||||
};
|
||||
|
||||
@@ -169,9 +174,7 @@ CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) {
|
||||
folded.splice(known.pos, 1);
|
||||
expand(cm, known.region);
|
||||
} else {
|
||||
var end = rangeFinder(cm, line);
|
||||
if (rangeFinder !== CodeMirror.indentRangeFinder && hideEnd === true) end++;
|
||||
console.log(rangeFinder !== CodeMirror.indentRangeFinder);
|
||||
var end = rangeFinder(cm, line, hideEnd);
|
||||
if (end == null) return;
|
||||
var hidden = [];
|
||||
for (var i = line + 1; i < end; ++i) {
|
||||
@@ -23,7 +23,7 @@
|
||||
function markDocument(cm, className, minChars) {
|
||||
clearMarks(cm);
|
||||
minChars = (typeof minChars !== 'undefined' ? minChars : DEFAULT_MIN_CHARS);
|
||||
if (cm.somethingSelected() && cm.getSelection().length >= minChars) {
|
||||
if (cm.somethingSelected() && cm.getSelection().replace(/^\s+|\s+$/g, "").length >= minChars) {
|
||||
var state = getMatchHighlightState(cm);
|
||||
var query = cm.getSelection();
|
||||
cm.operation(function() {
|
||||
@@ -1,7 +1,7 @@
|
||||
(function(){
|
||||
function SearchCursor(cm, query, pos, caseFold) {
|
||||
this.atOccurrence = false; this.cm = cm;
|
||||
if (caseFold == null) caseFold = typeof query == "string" && query == query.toLowerCase();
|
||||
if (caseFold == null && typeof query == "string") caseFold = false;
|
||||
|
||||
pos = pos ? cm.clipPos(pos) : {line: 0, ch: 0};
|
||||
this.pos = {from: pos, to: pos};
|
||||
@@ -21,7 +21,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
22
CodeMirror-2.25/mode/coffeescript/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2011 Jeff Pickhardt
|
||||
Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
347
CodeMirror-2.25/mode/coffeescript/coffeescript.js
Normal file
@@ -0,0 +1,347 @@
|
||||
/**
|
||||
* Link to the project's GitHub page:
|
||||
* https://github.com/pickhardt/coffeescript-codemirror-mode
|
||||
*/
|
||||
CodeMirror.defineMode('coffeescript', function(conf) {
|
||||
var ERRORCLASS = 'error';
|
||||
|
||||
function wordRegexp(words) {
|
||||
return new RegExp("^((" + words.join(")|(") + "))\\b");
|
||||
}
|
||||
|
||||
var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
|
||||
var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
|
||||
var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
|
||||
var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
|
||||
var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
|
||||
var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
|
||||
|
||||
var wordOperators = wordRegexp(['and', 'or', 'not',
|
||||
'is', 'isnt', 'in',
|
||||
'instanceof', 'typeof']);
|
||||
var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else',
|
||||
'switch', 'try', 'catch', 'finally', 'class'];
|
||||
var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete',
|
||||
'do', 'in', 'of', 'new', 'return', 'then',
|
||||
'this', 'throw', 'when', 'until'];
|
||||
|
||||
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
|
||||
|
||||
indentKeywords = wordRegexp(indentKeywords);
|
||||
|
||||
|
||||
var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])");
|
||||
var regexPrefixes = new RegExp("^(/{3}|/)");
|
||||
var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no'];
|
||||
var constants = wordRegexp(commonConstants);
|
||||
|
||||
// Tokenizers
|
||||
function tokenBase(stream, state) {
|
||||
// Handle scope changes
|
||||
if (stream.sol()) {
|
||||
var scopeOffset = state.scopes[0].offset;
|
||||
if (stream.eatSpace()) {
|
||||
var lineOffset = stream.indentation();
|
||||
if (lineOffset > scopeOffset) {
|
||||
return 'indent';
|
||||
} else if (lineOffset < scopeOffset) {
|
||||
return 'dedent';
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
if (scopeOffset > 0) {
|
||||
dedent(stream, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var ch = stream.peek();
|
||||
|
||||
// Handle docco title comment (single line)
|
||||
if (stream.match("####")) {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
}
|
||||
|
||||
// Handle multi line comments
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = longComment;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Single line comment
|
||||
if (ch === '#') {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
}
|
||||
|
||||
// Handle number literals
|
||||
if (stream.match(/^-?[0-9\.]/, false)) {
|
||||
var floatLiteral = false;
|
||||
// Floats
|
||||
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\d+\.\d*/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\.\d+/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
|
||||
if (floatLiteral) {
|
||||
// prevent from getting extra . on 1..
|
||||
if (stream.peek() == "."){
|
||||
stream.backUp(1);
|
||||
}
|
||||
return 'number';
|
||||
}
|
||||
// Integers
|
||||
var intLiteral = false;
|
||||
// Hex
|
||||
if (stream.match(/^-?0x[0-9a-f]+/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Decimal
|
||||
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Zero by itself with no other piece of number.
|
||||
if (stream.match(/^-?0(?![\dx])/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
if (intLiteral) {
|
||||
return 'number';
|
||||
}
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (stream.match(stringPrefixes)) {
|
||||
state.tokenize = tokenFactory(stream.current(), 'string');
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
// Handle regex literals
|
||||
if (stream.match(regexPrefixes)) {
|
||||
if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
|
||||
state.tokenize = tokenFactory(stream.current(), 'string-2');
|
||||
return state.tokenize(stream, state);
|
||||
} else {
|
||||
stream.backUp(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle operators and delimiters
|
||||
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
|
||||
return 'punctuation';
|
||||
}
|
||||
if (stream.match(doubleOperators)
|
||||
|| stream.match(singleOperators)
|
||||
|| stream.match(wordOperators)) {
|
||||
return 'operator';
|
||||
}
|
||||
if (stream.match(singleDelimiters)) {
|
||||
return 'punctuation';
|
||||
}
|
||||
|
||||
if (stream.match(constants)) {
|
||||
return 'atom';
|
||||
}
|
||||
|
||||
if (stream.match(keywords)) {
|
||||
return 'keyword';
|
||||
}
|
||||
|
||||
if (stream.match(identifiers)) {
|
||||
return 'variable';
|
||||
}
|
||||
|
||||
// Handle non-detected items
|
||||
stream.next();
|
||||
return ERRORCLASS;
|
||||
}
|
||||
|
||||
function tokenFactory(delimiter, outclass) {
|
||||
var singleline = delimiter.length == 1;
|
||||
return function tokenString(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^'"\/\\]/);
|
||||
if (stream.eat('\\')) {
|
||||
stream.next();
|
||||
if (singleline && stream.eol()) {
|
||||
return outclass;
|
||||
}
|
||||
} else if (stream.match(delimiter)) {
|
||||
state.tokenize = tokenBase;
|
||||
return outclass;
|
||||
} else {
|
||||
stream.eat(/['"\/]/);
|
||||
}
|
||||
}
|
||||
if (singleline) {
|
||||
if (conf.mode.singleLineStringErrors) {
|
||||
outclass = ERRORCLASS
|
||||
} else {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
}
|
||||
return outclass;
|
||||
};
|
||||
}
|
||||
|
||||
function longComment(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^#]/);
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
stream.eatWhile("#");
|
||||
}
|
||||
return "comment"
|
||||
}
|
||||
|
||||
function indent(stream, state, type) {
|
||||
type = type || 'coffee';
|
||||
var indentUnit = 0;
|
||||
if (type === 'coffee') {
|
||||
for (var i = 0; i < state.scopes.length; i++) {
|
||||
if (state.scopes[i].type === 'coffee') {
|
||||
indentUnit = state.scopes[i].offset + conf.indentUnit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
indentUnit = stream.column() + stream.current().length;
|
||||
}
|
||||
state.scopes.unshift({
|
||||
offset: indentUnit,
|
||||
type: type
|
||||
});
|
||||
}
|
||||
|
||||
function dedent(stream, state) {
|
||||
if (state.scopes.length == 1) return;
|
||||
if (state.scopes[0].type === 'coffee') {
|
||||
var _indent = stream.indentation();
|
||||
var _indent_index = -1;
|
||||
for (var i = 0; i < state.scopes.length; ++i) {
|
||||
if (_indent === state.scopes[i].offset) {
|
||||
_indent_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_indent_index === -1) {
|
||||
return true;
|
||||
}
|
||||
while (state.scopes[0].offset !== _indent) {
|
||||
state.scopes.shift();
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
state.scopes.shift();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tokenLexer(stream, state) {
|
||||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
// Handle '.' connected identifiers
|
||||
if (current === '.') {
|
||||
style = state.tokenize(stream, state);
|
||||
current = stream.current();
|
||||
if (style === 'variable') {
|
||||
return 'variable';
|
||||
} else {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle properties
|
||||
if (current === '@') {
|
||||
stream.eat('@');
|
||||
return 'keyword';
|
||||
}
|
||||
|
||||
// Handle scope changes.
|
||||
if (current === 'return') {
|
||||
state.dedent += 1;
|
||||
}
|
||||
if (((current === '->' || current === '=>') &&
|
||||
!state.lambda &&
|
||||
state.scopes[0].type == 'coffee' &&
|
||||
stream.peek() === '')
|
||||
|| style === 'indent') {
|
||||
indent(stream, state);
|
||||
}
|
||||
var delimiter_index = '[({'.indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
|
||||
}
|
||||
if (indentKeywords.exec(current)){
|
||||
indent(stream, state);
|
||||
}
|
||||
if (current == 'then'){
|
||||
dedent(stream, state);
|
||||
}
|
||||
|
||||
|
||||
if (style === 'dedent') {
|
||||
if (dedent(stream, state)) {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
delimiter_index = '])}'.indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
if (dedent(stream, state)) {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
|
||||
if (state.scopes.length > 1) state.scopes.shift();
|
||||
state.dedent -= 1;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
var external = {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
scopes: [{offset:basecolumn || 0, type:'coffee'}],
|
||||
lastToken: null,
|
||||
lambda: false,
|
||||
dedent: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var style = tokenLexer(stream, state);
|
||||
|
||||
state.lastToken = {style:style, content: stream.current()};
|
||||
|
||||
if (stream.eol() && stream.lambda) {
|
||||
state.lambda = false;
|
||||
}
|
||||
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state.scopes[0].offset;
|
||||
}
|
||||
|
||||
};
|
||||
return external;
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript');
|
||||
@@ -54,7 +54,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
@@ -243,7 +243,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
function maybeoperator(type, value) {
|
||||
if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
|
||||
if (type == "operator") return cont(expression);
|
||||
if (type == "operator" || type == ":") return cont(expression);
|
||||
if (type == ";") return;
|
||||
if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
||||
if (type == ".") return cont(property, maybeoperator);
|
||||
@@ -341,8 +341,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != jsTokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
|
||||
type = lexical.type, closing = firstChar == type;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
||||
var type = lexical.type, closing = firstChar == type;
|
||||
if (type == "vardef") return lexical.indented + 4;
|
||||
else if (type == "form" && firstChar == "{") return lexical.indented;
|
||||
else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
|
||||
@@ -143,7 +143,7 @@
|
||||
|
||||
electricChars: "/{}:"
|
||||
}
|
||||
});
|
||||
}, "xml", "clike", "javascript", "css");
|
||||
CodeMirror.defineMIME("application/x-httpd-php", "php");
|
||||
CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
|
||||
CodeMirror.defineMIME("text/x-php", phpConfig);
|
||||
@@ -1,12 +1,44 @@
|
||||
CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var Kludges = parserConfig.htmlMode ? {
|
||||
autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
|
||||
"meta": true, "col": true, "frame": true, "base": true, "area": true},
|
||||
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
|
||||
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
|
||||
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
|
||||
'track': true, 'wbr': true},
|
||||
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
|
||||
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
|
||||
'th': true, 'tr': true},
|
||||
contextGrabbers: {
|
||||
'dd': {'dd': true, 'dt': true},
|
||||
'dt': {'dd': true, 'dt': true},
|
||||
'li': {'li': true},
|
||||
'option': {'option': true, 'optgroup': true},
|
||||
'optgroup': {'optgroup': true},
|
||||
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
|
||||
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
|
||||
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
|
||||
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
|
||||
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
|
||||
'rp': {'rp': true, 'rt': true},
|
||||
'rt': {'rp': true, 'rt': true},
|
||||
'tbody': {'tbody': true, 'tfoot': true},
|
||||
'td': {'td': true, 'th': true},
|
||||
'tfoot': {'tbody': true},
|
||||
'th': {'td': true, 'th': true},
|
||||
'thead': {'tbody': true, 'tfoot': true},
|
||||
'tr': {'tr': true}
|
||||
},
|
||||
doNotIndent: {"pre": true},
|
||||
allowUnquoted: true,
|
||||
allowMissing: false
|
||||
} : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false, allowMissing: false};
|
||||
} : {
|
||||
autoSelfClosers: {},
|
||||
implicitlyClosed: {},
|
||||
contextGrabbers: {},
|
||||
doNotIndent: {},
|
||||
allowUnquoted: false,
|
||||
allowMissing: false
|
||||
};
|
||||
var alignCDATA = parserConfig.alignCDATA;
|
||||
|
||||
// Return variables for tokenizers
|
||||
@@ -162,7 +194,12 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
} else if (type == "closeTag") {
|
||||
var err = false;
|
||||
if (curState.context) {
|
||||
err = curState.context.tagName != tagName;
|
||||
if (curState.context.tagName != tagName) {
|
||||
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
|
||||
popContext();
|
||||
}
|
||||
err = !curState.context || curState.context.tagName != tagName;
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
}
|
||||
@@ -174,9 +211,15 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
function endtag(startOfLine) {
|
||||
return function(type) {
|
||||
if (type == "selfcloseTag" ||
|
||||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
|
||||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
|
||||
maybePopContext(curState.tagName.toLowerCase());
|
||||
return cont();
|
||||
if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
|
||||
}
|
||||
if (type == "endTag") {
|
||||
maybePopContext(curState.tagName.toLowerCase());
|
||||
pushContext(curState.tagName, startOfLine);
|
||||
return cont();
|
||||
}
|
||||
return cont();
|
||||
};
|
||||
}
|
||||
@@ -188,6 +231,20 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
return cont(arguments.callee);
|
||||
}
|
||||
}
|
||||
function maybePopContext(nextTagName) {
|
||||
var parentTagName;
|
||||
while (true) {
|
||||
if (!curState.context) {
|
||||
return;
|
||||
}
|
||||
parentTagName = curState.context.tagName.toLowerCase();
|
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
return;
|
||||
}
|
||||
popContext();
|
||||
}
|
||||
}
|
||||
|
||||
function attributes(type) {
|
||||
if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
|
||||
@@ -22,4 +22,4 @@
|
||||
.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-header { color: #FF6400; }
|
||||
.cm-s-blackboard .cm-hr { color: #AEAEAE; }
|
||||
.cm-s-blackboard .cm-link { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-link { color: #8DA6CE; }
|
||||
21
CodeMirror-2.25/theme/erlang-dark.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.cm-s-erlang-dark { background: #002240; color: white; }
|
||||
.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539 !important; }
|
||||
.cm-s-erlang-dark .CodeMirror-gutter { background: #002240; border-right: 1px solid #aaa; }
|
||||
.cm-s-erlang-dark .CodeMirror-gutter-text { color: #d0d0d0; }
|
||||
.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
|
||||
|
||||
.cm-s-erlang-dark span.cm-atom { color: #845dc4; }
|
||||
.cm-s-erlang-dark span.cm-attribute { color: #ff80e1; }
|
||||
.cm-s-erlang-dark span.cm-bracket { color: #ff9d00; }
|
||||
.cm-s-erlang-dark span.cm-builtin { color: #eeaaaa; }
|
||||
.cm-s-erlang-dark span.cm-comment { color: #7777ff; }
|
||||
.cm-s-erlang-dark span.cm-def { color: #ee77aa; }
|
||||
.cm-s-erlang-dark span.cm-error { color: #9d1e15; }
|
||||
.cm-s-erlang-dark span.cm-keyword { color: #ffee80; }
|
||||
.cm-s-erlang-dark span.cm-meta { color: #50fefe; }
|
||||
.cm-s-erlang-dark span.cm-number { color: #ffd0d0; }
|
||||
.cm-s-erlang-dark span.cm-operator { color: #dd1111; }
|
||||
.cm-s-erlang-dark span.cm-string { color: #3ad900; }
|
||||
.cm-s-erlang-dark span.cm-tag { color: #9effff; }
|
||||
.cm-s-erlang-dark span.cm-variable { color: #50fe50; }
|
||||
.cm-s-erlang-dark span.cm-variable-2 { color: #ee00ee; }
|
||||
@@ -23,7 +23,7 @@ div.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/
|
||||
.cm-s-lesser-dark span.cm-keyword { color: #599eff; }
|
||||
.cm-s-lesser-dark span.cm-atom { color: #C2B470; }
|
||||
.cm-s-lesser-dark span.cm-number { color: #B35E4D; }
|
||||
.cm-s-lesser-dark span.cm-def {color: color: white;}
|
||||
.cm-s-lesser-dark span.cm-def {color: white;}
|
||||
.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
|
||||
.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
|
||||
.cm-s-lesser-dark span.cm-variable-3 { color: white; }
|
||||
30
LICENSE.md
Normal file
@@ -0,0 +1,30 @@
|
||||
Copyright (C) 2012 Matt Pass
|
||||
Website: mattpass.com
|
||||
Email: matt@mattpass.com
|
||||
Twitter: @mattpass
|
||||
|
||||
#ICEcoder License
|
||||
##Standard Open Source Initiative MIT License
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
```
|
||||
Please note that this LICENSE file covers the ICEcoder shell IDE only and 3rd
|
||||
party code, in subfolders such as CodeMirror and plugins, may contain their
|
||||
own LICENSE files, and may not also be an MIT licence.
|
||||
```
|
||||
76
README.md
@@ -1,27 +1,65 @@
|
||||
ICE coder :: Matt Pass
|
||||
#ICEcoder
|
||||
##Web based IDE for smart web development
|
||||
|
||||
Demo: http://www.mattpass.com/_coder
|
||||
Early version of the web based IDE which allows for creation of websites in the web browser. Uses the brilliant CodeMirror for code highlighting & editing, with a slick IDE wrapped around it to make the whole thing work.
|
||||
|
||||
Early version of the web based IDE which allows for creation of websites in the web browser.
|
||||
###Features you'd expect
|
||||
* Context aware code highlighting
|
||||
* Supports HTML, CSS, JavaScript, PHP & Ruby
|
||||
* Smart tab key system (selected text indents line)
|
||||
* File manager
|
||||
* Find & replace/replace all
|
||||
* Document tabs indicate current doc & changes made
|
||||
* Code folding
|
||||
* Open last files on load
|
||||
* Web based, access from anywhere
|
||||
* Free, open source & customisable
|
||||
|
||||
Uses the brilliant CodeMirror plus some other PHP & JS code to deal with file handling and make the whole thing work. Also has the extra plugin 'Adminer' for DB management.
|
||||
###Cool features you wouldn't expect
|
||||
* Find & replace in current doc, open docs, files & filenames
|
||||
* Found match & current position counter
|
||||
* Indicates content type cursor is on
|
||||
* Account login to keep certain files secure
|
||||
* Restrict files, ban files and restrict by IP
|
||||
* Settings to change functionality & editor theme
|
||||
* Code Assist system
|
||||
* Displays nest position of text cursor, hover to select, click to set cursor
|
||||
* Nest structure OK/broken indicator
|
||||
* Highlight word and press CTRL+I to Google search that
|
||||
* Adds end tags as you type and in a context aware way
|
||||
* Can rename open files (whoaah!)
|
||||
* CTRL+Enter open current webpage in new tab
|
||||
* CTRL+S+Enter opens a sticky tab to show live edits
|
||||
* ESC = Comment/Uncomment line, incl partial lines
|
||||
* Image viewer
|
||||
* Colour preview block on CSS colours, ie red, #ff0000 or RGBA(255,0,0,0.5)
|
||||
* MySQL Database management via Adminer plugin
|
||||
* Backs up files every 10 mins or on click of backup plugin icon
|
||||
|
||||
###Installation
|
||||
|
||||
####Step 1: Clone the repo
|
||||
|
||||
```
|
||||
$ git clone git@github:mattpass/ICEcoder
|
||||
```
|
||||
|
||||
####Step 2: Upload the files (Linux or Windows hosting OK)
|
||||
```
|
||||
Upload to a new sub-dir URL such as yourdomain.com/_coder
|
||||
Set public write permissions on the lib/config.php file
|
||||
```
|
||||
|
||||
####Step 3: Start coding
|
||||
```
|
||||
Visit the sub-dir URL in your browser and enter a password
|
||||
Now you're setup, auto-logged in and ready to code!
|
||||
```
|
||||
|
||||
Suitable for commercial & non-commercial projects, just let me know if it's useful to you and any cool customisations you make to it. I take no responsibility for anything, your usage is all down to you.
|
||||
|
||||
Is fully open source and I'd encourage you to take it, make it your own and customise to your hearts content! :)
|
||||
|
||||
Suitable for commercial & non-commercial projects, just let me know if it's useful to you and any cool customisations you make to it.
|
||||
|
||||
Please feel free to assist with the development of this and maybe in time we can produce a fantastic web based IDE for web devs.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
1.Open /lib/settings.php and adjust variables to suit
|
||||
|
||||
2.Upload all the files to a Linux or Windows host under a new sub-dir URL such as yourdomain.com/_coder. Set public write permissions on the settings.php file
|
||||
|
||||
3.Visit this URL in your browser and set a password
|
||||
|
||||
4.Now you have top level access and can save (CTRL+S), delete (DEL) etc
|
||||
|
||||
Plenty of comments included in the code to assist with understanding.
|
||||
Plenty of comments included in the code to assist with understanding, customising etc.
|
||||
|
||||
Comments, improvements & feedback welcomed!
|
||||
83
editor.php
@@ -1,15 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html style="margin: 0px">
|
||||
<html style="margin: 0">
|
||||
<head>
|
||||
<title>CodeMirror 2: ICE Coders Editor of Choice</title>
|
||||
<?php include("lib/settings.php");?>
|
||||
<link rel="stylesheet" href="<?php echo $codeMirrorDir; ?>/lib/codemirror.css">
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/codemirror.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/xml/xml.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/javascript/javascript.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/css/css.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/clike/clike.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/css/css.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/javascript/javascript.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/xml/xml.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/coffeescript/coffeescript.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/php/php.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/ruby/ruby.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/util/searchcursor.js"></script>
|
||||
@@ -23,26 +24,69 @@ if ($theme=="default") {
|
||||
}
|
||||
?>
|
||||
<style type="text/css">
|
||||
.CodeMirror {position: absolute; width: 0px; background-color: #ffffff}
|
||||
.CodeMirror {position: absolute; width: 0; background-color: #fff; top: 0px; z-index: 1}
|
||||
.CodeMirror-scroll {width: 100px; height: 100px;}
|
||||
.cm-s-visible {display: block; top: 0px}
|
||||
.cm-s-visible {display: block; top: 0}
|
||||
.cm-s-hidden {display: none; top: 4000px}
|
||||
.cm-s-activeLine {background: #002 !important;}
|
||||
<?php if ($visibleTabs) {?>
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0px; left: -1.4em; overflow: visible; color: #aaa; content: "\21e5";}
|
||||
<?;};?>
|
||||
span.CodeMirror-matchhighlight {background: #555555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
|
||||
// Make sure this next one remains the 5th item, updated with JS
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if ($visibleTabs) {?>\21e5<?;};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000; background: #555; !important}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="margin: 0px" onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
<body onLoad="top.ICEcoder.updateFileFolderCount()" style="color: #fff; margin: 0" onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
|
||||
<div style="margin: 32px 43px; font-family: arial; font-size: 10px; color: #dddddd">
|
||||
<?php if($_SESSION['userLevel'] == 10) {
|
||||
echo '<div style="float: left; margin-right: 50px">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">server</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Server name, OS & IP:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['SERVER_NAME'].' '.$_SERVER['SERVER_SOFTWARE'].' '.$_SERVER['SERVER_ADDR'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Root:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['DOCUMENT_ROOT'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">PHP version:</span><br>'.PHP_EOL;
|
||||
echo phpversion().'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">File & folder count:</span><br>'.PHP_EOL;
|
||||
echo '<div id="fileFolderCounts"></div><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Date & time:</span><br>'.PHP_EOL;
|
||||
echo '<span id="serverDT"></span><br><br><br>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
|
||||
echo '<div style="float: left">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">files</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Last 10 files opened:</span><br>'.PHP_EOL;
|
||||
echo str_replace("|","/",str_replace(",","<br>",$last10Files)).'<br><br><br>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
|
||||
echo '<div style="clear: both">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">your device</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Browser:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['HTTP_USER_AGENT'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Your IP:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['REMOTE_ADDR'].PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
}; ?>
|
||||
<script>
|
||||
var nDT=<?php echo time()*1000;?>;
|
||||
setInterval(function(){
|
||||
var s=(new Date(nDT+=1000)+'').split(' '),
|
||||
d=s[2]*1,
|
||||
t=s[4].split(':'),
|
||||
p=t[0]>11?'pm':'am',
|
||||
e=d%20==1|d==31?'st':d%20==2?'nd':d%20==3?'rd':'th';
|
||||
t[0]=--t[0]%12+1;
|
||||
document.getElementById('serverDT').innerHTML=[s[0],d+e,s[1],s[3],t.join(':')+p].join(' ');
|
||||
},1000);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function createNewCMInstance(num) {
|
||||
var fileName = top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1];
|
||||
var codeFold = CodeMirror.newFoldFunction(CodeMirror.tagRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #bb0000; color: #ffffff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
|
||||
var codeFold_JS_PHP_Ruby = CodeMirror.newFoldFunction(CodeMirror.braceRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #bb0000; color: #ffffff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
|
||||
var codeFold = CodeMirror.newFoldFunction(CodeMirror.tagRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #b00; color: #fff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
|
||||
var codeFold_JS_Coffee_PHP_Ruby = CodeMirror.newFoldFunction(CodeMirror.braceRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #b00; color: #fff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
|
||||
|
||||
window['cM'+num] = CodeMirror(document.body, {
|
||||
mode: "application/x-httpd-php",
|
||||
@@ -79,8 +123,8 @@ function createNewCMInstance(num) {
|
||||
}
|
||||
},
|
||||
onKeyEvent: function(instance, e) {
|
||||
top.ICEcoder.redoChangedContent(event);
|
||||
top.ICEcoder.findReplace('find',true);
|
||||
top.ICEcoder.redoChangedContent(e);
|
||||
top.ICEcoder.findReplace('find',true,false);
|
||||
top.ICEcoder.getCaretPosition();
|
||||
top.ICEcoder.updateCharDisplay();
|
||||
tok = window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].getTokenAt(window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].getCursor());
|
||||
@@ -123,8 +167,11 @@ function createNewCMInstance(num) {
|
||||
};
|
||||
lastKeyCode = e.keyCode;
|
||||
},
|
||||
onGutterClick: !fileName || (fileName && fileName.indexOf(".js") == -1 && fileName.indexOf(".php") && fileName.indexOf(".rb") == -1) ? codeFold : codeFold_JS_PHP_Ruby,
|
||||
extraKeys: {"Tab": "indentMore", "Shift-Tab": "indentLess"}
|
||||
onGutterClick: !fileName || (fileName && fileName.indexOf(".js") == -1 && fileName.indexOf(".coffee") == -1 && fileName.indexOf(".php") && fileName.indexOf(".rb") == -1) ? codeFold : codeFold_JS_Coffee_PHP_Ruby,
|
||||
extraKeys: {
|
||||
"Tab": function(cm) {CodeMirror.commands[top.tabsIndent ? "defaultTab" : "insertTab"](cm);},
|
||||
"Shift-Tab": "indentLess"
|
||||
}
|
||||
});
|
||||
|
||||
// Now create the active line for this CodeMirror object
|
||||
|
||||
31
files.php
@@ -54,7 +54,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
|
||||
if ($serverType=="Linux") {
|
||||
$chmodInfo = substr(sprintf('%o', fileperms($link)), -4);
|
||||
$fileAtts = '<span style="color: #888888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
$fileAtts = '<span style="color: #888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
}
|
||||
$fileManager = "<ul class=\"fileManager\">";
|
||||
$fileManager .= "<li class=\"pft-directory\"><a href=\"#\" onMouseOver=\"top.ICEcoder.overFileFolder('folder','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('folder','')\" style=\"position: relative; left:-22px\"> <span id=\"|\">/ [ROOT]</span> ".$fileAtts."</a>";
|
||||
@@ -74,6 +74,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
if( $this_file != "." && $this_file != ".." && $bannedFile == false) {
|
||||
if( is_dir("$directory/$this_file") ) {
|
||||
// Directory
|
||||
$dirCount++;
|
||||
$dirRep = str_replace("\\","/",$directory);
|
||||
$link = str_replace("[link]", "$dirRep/" . urlencode($this_file), $return_link);
|
||||
$link = str_replace("//","/",$link);
|
||||
@@ -88,17 +89,19 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
$fileAtts = "";
|
||||
if ($serverType=="Linux") {
|
||||
$chmodInfo = substr(sprintf('%o', fileperms($link)), -4);
|
||||
$fileAtts = '<span style="color: #888888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
$fileAtts = '<span style="color: #888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
}
|
||||
if ($_SESSION['userLevel'] == 10 || ($_SESSION['userLevel'] < 10 && $restrictedFile==false)) {
|
||||
$fileManager .= "<li class=\"pft-directory\"><a href=\"#\" onMouseOver=\"top.ICEcoder.overFileFolder('folder','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('folder','')\" style=\"position: relative; left:-22px\"> <span id=\"".str_replace("/","|",str_replace($docRoot,"",$link))."\">" . htmlspecialchars($this_file) . "</span> ".$fileAtts."</a>";
|
||||
$fileManager .= fileManager_dir("$directory/$this_file", $return_link , false);
|
||||
$fileManager .= "</li>";
|
||||
} else {
|
||||
$fileManager .= "<li class=\"pft-directory\" style=\"cursor: pointer\"><span style=\"position: relative; left:-22px; color: #888888\"> [HIDDEN] ".$fileAtts."</span></li>";
|
||||
$fileManager .= "<li class=\"pft-directory\" style=\"cursor: pointer\"><span style=\"position: relative; left:-22px; color: #888\"> [HIDDEN] ".$fileAtts."</span></li>";
|
||||
}
|
||||
} else {
|
||||
// File
|
||||
$fileCount++;
|
||||
$fileBytes+=filesize($link);
|
||||
// Get extension (prefix 'ext-' to prevent invalid classes from extensions that begin with numbers)
|
||||
$ext = "ext-" . substr($this_file, strrpos($this_file, ".") + 1);
|
||||
$dirRep = str_replace("\\","/",$directory);
|
||||
@@ -115,19 +118,24 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
$fileAtts = "";
|
||||
if ($serverType=="Linux") {
|
||||
$chmodInfo = substr(sprintf('%o', fileperms($link)), -4);
|
||||
$fileAtts = '<span style="color: #888888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
$fileAtts = '<span style="color: #888; font-size: 8px">'.$chmodInfo.'</span>';
|
||||
}
|
||||
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\"><a nohref onMouseOver=\"top.ICEcoder.overFileFolder('file','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('file','')\" style=\"position: relative; left:-22px; cursor: pointer\"> <span id=\"".str_replace("/","|",str_replace($docRoot,"",$link))."\">" . htmlspecialchars($this_file) . "</span> ".$fileAtts."</a></li>";
|
||||
} else {
|
||||
$fileAtts = "<img src=\"images/file-manager-icons/padlock.png\" style=\"cursor: pointer\" onClick=\"alert('Sorry, you need higher admin level rights to view.')\">";
|
||||
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\" style=\"cursor: default\"><span style=\"position: relative; left:-22px; color: #888888\"> [HIDDEN] ".$fileAtts."</span></li>";
|
||||
$fileAtts = "<img src=\"images/padlock.png\" style=\"cursor: pointer\" onClick=\"alert('Sorry, you need higher admin level rights to view.')\">";
|
||||
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\" style=\"cursor: default\"><span style=\"position: relative; left:-22px; color: #888\"> [HIDDEN] ".$fileAtts."</span></li>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$fileManager .= "</ul>";
|
||||
}
|
||||
return $fileManager;
|
||||
$varOutput = "";
|
||||
if ($dirCount) {$varOutput .= "top.ICEcoder.dirCount+=".$dirCount.";".PHP_EOL;};
|
||||
if ($fileCount) {$varOutput .= "top.ICEcoder.fileCount+=".$fileCount.";".PHP_EOL;};
|
||||
if ($fileBytes) {$varOutput .= "top.ICEcoder.fileBytes+=".$fileBytes.";".PHP_EOL;};
|
||||
// After outputting the fileManager, output the JS vars, but only the first time
|
||||
return $fileManager."<script>if (top.ICEcoder.dirCount==0) {".PHP_EOL.$varOutput."}</script>";
|
||||
}
|
||||
|
||||
// For PHP4 compatibility
|
||||
@@ -146,12 +154,19 @@ function php4_scandir($dir) {
|
||||
<head>
|
||||
<title>ICE Coder File Manager</title>
|
||||
<link rel="stylesheet" type="text/css" href="lib/files.css">
|
||||
|
||||
<script src="lib/coder.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<body onLoad="top.ICEcoder.fileManager()" onDblClick="top.ICEcoder.openFile()" onKeyDown="return top.ICEcoder.interceptKeys('files', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
<div onClick="top.ICEcoder.refreshFileManager()" class="refresh"><img src="images/file-manager-icons/refresh.png"></div>
|
||||
<div onClick="top.ICEcoder.refreshFileManager()" class="refresh"><img src="images/refresh.png"></div>
|
||||
<script>
|
||||
top.ICEcoder.dirCount = 0;
|
||||
top.ICEcoder.fileCount = 0;
|
||||
top.ICEcoder.fileBytes = 0;
|
||||
</script>
|
||||
<?php
|
||||
|
||||
echo fileManager($_SERVER['DOCUMENT_ROOT'], "[link]");
|
||||
?>
|
||||
|
||||
|
||||
BIN
images/Thumbs.db
BIN
images/blank.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/file-manager-icons.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 603 B |
|
Before Width: | Height: | Size: 618 B |
|
Before Width: | Height: | Size: 579 B |
|
Before Width: | Height: | Size: 537 B |
|
Before Width: | Height: | Size: 651 B |
|
Before Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 653 B |
|
Before Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 734 B |
|
Before Width: | Height: | Size: 633 B |
|
Before Width: | Height: | Size: 668 B |
|
Before Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 606 B |
|
Before Width: | Height: | Size: 588 B |
|
Before Width: | Height: | Size: 856 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 626 B |
|
Before Width: | Height: | Size: 859 B |
|
Before Width: | Height: | Size: 342 B |
|
Before Width: | Height: | Size: 663 B |
|
Before Width: | Height: | Size: 386 B |
BIN
images/full-screen.gif
Normal file
|
After Width: | Height: | Size: 73 B |
BIN
images/ice-coder.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 56 B After Width: | Height: | Size: 56 B |
|
Before Width: | Height: | Size: 377 B After Width: | Height: | Size: 1.2 KiB |
BIN
images/padlock-disabled.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
BIN
images/refresh.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
images/restored-screen.gif
Normal file
|
After Width: | Height: | Size: 65 B |
92
index.php
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
include("lib/settings.php");
|
||||
$allowedIP = false;
|
||||
for($i=0;$i<count($allowedIPs);$i++) {
|
||||
if ($allowedIPs[$i]==$_SERVER["REMOTE_ADDR"]||$allowedIPs[$i]=="*") {
|
||||
for($i=0;$i<count($_SESSION['allowedIPs']);$i++) {
|
||||
if ($_SESSION['allowedIPs'][$i]==$_SERVER["REMOTE_ADDR"]||$_SESSION['allowedIPs'][$i]=="*") {
|
||||
$allowedIP = true;
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,12 @@ if ($testcMVersion) {
|
||||
<html>
|
||||
<head>
|
||||
<title>ICE Coder - <?php echo $versionNo;?></title>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link rel="stylesheet" type="text/css" href="lib/coder.css">
|
||||
<script>
|
||||
shortURLStarts = "<?php echo $shortURLStarts;?>";
|
||||
theme = "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;};?>";
|
||||
tabsIndent = <?php if ($tabsIndent) {echo 'true';} else {echo 'false';};?>;
|
||||
<?
|
||||
$docRoot = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']);
|
||||
if (strrpos($docRoot,"/")==strlen($docRoot)-1) {$docRoot = substr($docRoot,0,strlen($docRoot)-1);};
|
||||
@@ -41,9 +43,9 @@ window.onbeforeunload = function() {
|
||||
}
|
||||
}
|
||||
|
||||
lastOpenFiles = [<?php
|
||||
if ($lastOpenedFiles!="" && $_SESSION['userLevel'] == 10) {
|
||||
$openFilesArray = explode(",",$lastOpenedFiles);
|
||||
previousFiles = [<?php
|
||||
if ($previousFiles!="" && $_SESSION['userLevel'] == 10) {
|
||||
$openFilesArray = explode(",",$previousFiles);
|
||||
for ($i=0;$i<count($openFilesArray);$i++) {
|
||||
echo "'".$openFilesArray[$i]."'";
|
||||
if ($i<count($openFilesArray)-1) {echo ",";};
|
||||
@@ -52,18 +54,9 @@ lastOpenFiles = [<?php
|
||||
?>];
|
||||
</script>
|
||||
<script language="JavaScript" src="lib/coder.js"></script>
|
||||
</head><?php
|
||||
$onLoadExtras = "";
|
||||
for ($i=0;$i<count($plugins);$i++) {
|
||||
if ($plugins[$i][5]!="") {
|
||||
$onLoadExtras .= ";ICEcoder.startPluginIntervals('".$plugins[$i][3]."','".$plugins[$i][4]."','".$plugins[$i][5]."')";
|
||||
};
|
||||
};
|
||||
if ($openLastFiles) {
|
||||
$onLoadExtras .= ";ICEcoder.autoOpenFiles()";
|
||||
}
|
||||
?>
|
||||
<body onLoad="ICEcoder.init()<?php echo $onLoadExtras;?>" onResize="ICEcoder.setLayout()" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onKeyDown="return ICEcoder.interceptKeys('coder', event);" onKeyUp="parent.ICEcoder.resetKeys(event);">
|
||||
</head>
|
||||
|
||||
<body onLoad="ICEcoder.init(<?php if ($_SESSION['userLevel'] == 10) {echo "'login'";} ?>)<?php echo $onLoadExtras;?>" onResize="ICEcoder.setLayout()" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onKeyDown="return ICEcoder.interceptKeys('coder', event);" onKeyUp="parent.ICEcoder.resetKeys(event);">
|
||||
|
||||
<div id="blackMask" class="blackMask" onClick="ICEcoder.showHide('hide',this)">
|
||||
<div class="popupVCenter">
|
||||
@@ -78,7 +71,7 @@ lastOpenFiles = [<?php
|
||||
<div class="popup">
|
||||
<div class="circleOutside"></div>
|
||||
<div class="circleInside"></div>
|
||||
loading...
|
||||
working...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,39 +89,33 @@ lastOpenFiles = [<?php
|
||||
</div>
|
||||
|
||||
<div id="header" class="header" onContextMenu="return false">
|
||||
<div class="plugins">
|
||||
<?php
|
||||
for ($i=0;$i<count($plugins);$i++) {
|
||||
$target = explode(":",$plugins[$i][4]);
|
||||
echo '<a href="'.$plugins[$i][3].'" target="'.$target[0].'"><img src="'.$plugins[$i][1].'" style="'.$plugins[$i][2].'" alt="'.$plugins[$i][0].'"></a>';
|
||||
};
|
||||
?>
|
||||
<div class="plugins" id="pluginsContainer">
|
||||
<?php echo $pluginsDisplay; ?>
|
||||
</div>
|
||||
<div class="version"><?php echo $versionNo;?></div>
|
||||
<img src="images/ice-coder.gif" class="logo">
|
||||
<div class="version"><?php echo $versionNo;?></div><img src="images/full-screen.gif" id="screenMode" class="screenModeIcon" onClick="top.ICEcoder.fullScreenSwitcher()">
|
||||
<img src="images/ice-coder.png" class="logo" onClick="ICEcoder.helpScreen('show')" onContextMenu="ICEcoder.settingsScreen('show')">
|
||||
</div>
|
||||
|
||||
<div id="files" class="files" onMouseOver="ICEcoder.changeFilesW('expand')" onMouseOut="ICEcoder.changeFilesW('contract'); top.document.getElementById('fileMenu').style.display='none';">
|
||||
<div class="account" id="account">
|
||||
<?php if($_SESSION['userLevel']<10) {?>
|
||||
<form name="login" action="index.php" method="POST">
|
||||
<input type="password" name="loginPassword" class="accountPassword">
|
||||
<input type="submit" name="submit" value="Login" class="button">
|
||||
</form>
|
||||
<?php } else {
|
||||
$lockStyleExtra = ' style="margin-top: -22px"';
|
||||
?>
|
||||
<div class="accountOptions">
|
||||
<div class="accountLoginContainer" id="accountLoginContainer">
|
||||
<div class="accountLogin" id="accountLogin">
|
||||
<form name="login" action="lib/settings.php" method="POST" target="ff">
|
||||
<input type="password" name="loginPassword" class="accountPassword">
|
||||
<input type="submit" name="submit" value="Login" class="button">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accountOptions">
|
||||
<a nohref title="Save" onClick="ICEcoder.fMIcon('save')"><img src="images/save.png" alt="Save" id="fMSave" style="opacity: 0.3"></a>
|
||||
<a nohref title="Open" onClick="ICEcoder.fMIcon('open')"><img src="images/open.png" alt="Open" id="fMOpen" style="margin-left: 7px; opacity: 0.3"></a>
|
||||
<a nohref title="New File" onClick="ICEcoder.fMIcon('newFile')"><img src="images/new-file.png" alt="New File" id="fMNewFile" style="margin: 8px 0px 0px 10px; opacity: 0.3"></a>
|
||||
<a nohref title="New Folder" onClick="ICEcoder.fMIcon('newFolder')"><img src="images/new-folder.png" alt="New Folder" id="fMNewFolder" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
|
||||
<a nohref title="Delete" onClick="ICEcoder.fMIcon('delete')"><img src="images/delete.png" alt="Delete" id="fMDelete" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
|
||||
<a nohref title="Rename" onClick="ICEcoder.fMIcon('rename')"><img src="images/rename.png" alt="Rename" id="fMRename" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
|
||||
<a nohref title="View" onClick="ICEcoder.fMIcon('view')"><img src="images/view.png" alt="View" id="fMView" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
|
||||
</div>
|
||||
<?php ;};?>
|
||||
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/file-manager-icons/padlock.png" id="fmLock" class="lock"<?php echo $lockStyleExtra; ?>></a>
|
||||
<a nohref title="New File" onClick="ICEcoder.fMIcon('newFile')"><img src="images/new-file.png" alt="New File" id="fMNewFile" style="margin: 8px 0 0 10px; opacity: 0.3"></a>
|
||||
<a nohref title="New Folder" onClick="ICEcoder.fMIcon('newFolder')"><img src="images/new-folder.png" alt="New Folder" id="fMNewFolder" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
<a nohref title="Delete" onClick="ICEcoder.fMIcon('delete')"><img src="images/delete.png" alt="Delete" id="fMDelete" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
<a nohref title="Rename" onClick="ICEcoder.fMIcon('rename')"><img src="images/rename.png" alt="Rename" id="fMRename" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
<a nohref title="View" onClick="ICEcoder.fMIcon('view')"><img src="images/view.png" alt="View" id="fMView" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
</div>
|
||||
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/padlock.png" id="fmLock" class="lock"></a>
|
||||
</div>
|
||||
<iframe id="filesFrame" class="frame" name="ff" src="files.php" style="opacity: 0" onLoad="this.style.opacity='1'"></iframe>
|
||||
<div class="serverMessage" id="serverMessage"></div>
|
||||
@@ -146,27 +133,33 @@ lastOpenFiles = [<?php
|
||||
<form name="findAndReplace">
|
||||
<div class="findReplace">
|
||||
<div class="findText">Find</div>
|
||||
<input type="text" name="find" value="" id="find" class="textbox find" onKeyUp="ICEcoder.findReplace('find',true)">
|
||||
<input type="text" name="find" value="" id="find" class="textbox find" onKeyUp="ICEcoder.findReplace('find',true,false)">
|
||||
<div class="findTextPlural">'s</div>
|
||||
<select name="connector" onChange="ICEcoder.findReplaceOptions()">
|
||||
<option>in</option>
|
||||
<option>and</option>
|
||||
</select>
|
||||
<div class="replaceText" id="rText" style="display: none">replace with</div>
|
||||
<div class="replaceText" id="rText" style="display: none">
|
||||
<select name="replaceAction" class="replaceAction">
|
||||
<option>replace</option>
|
||||
<option>replace all</option>
|
||||
</select>
|
||||
with
|
||||
</div>
|
||||
<input type="text" name="replace" value="" id="replace" class="textbox replace" style="display: none">
|
||||
<div class="targetText" id="rTarget" style="display: none">in</div>
|
||||
<select name="target">
|
||||
<select name="target" onChange="ICEcoder.updateResultsDisplay(this.value=='this document' ? 'show' : 'hide')">
|
||||
<option>this document</option>
|
||||
<option>open documents</option>
|
||||
<option>all files</option>
|
||||
<option>all filenames</option>
|
||||
</select>
|
||||
<input type="button" name="submit" value=">>" class="submit" onClick="ICEcoder.findReplace('findReplace',false)">
|
||||
<input type="button" name="submit" value=">>" class="submit" onClick="ICEcoder.findReplace('findReplace',false,true)">
|
||||
<div class="results" id="results"></div>
|
||||
</div>
|
||||
</form>
|
||||
<form onSubmit="return ICEcoder.goToLine()">
|
||||
<div class="codeAssist"><input type="checkbox" name="codeAssist" checked onClick="top.ICEcoder.codeAssistToggle()">Code Assist</div>
|
||||
<div class="codeAssist"><input type="checkbox" name="codeAssist" id="codeAssist" checked onClick="top.ICEcoder.codeAssistToggle()">Code Assist</div>
|
||||
<div class="goLine">Go to Line<input type="text" name="goToLine" value="" id="goToLineNo" class="textbox goToLine">
|
||||
</form>
|
||||
</div>
|
||||
@@ -182,6 +175,7 @@ lastOpenFiles = [<?php
|
||||
</div>
|
||||
|
||||
<script>
|
||||
ICEcoder.initAliases();
|
||||
ICEcoder.setLayout('dontSetEditor');
|
||||
</script>
|
||||
|
||||
|
||||
142
lib/coder.css
@@ -9,24 +9,33 @@ dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
font-family: arial, verdana, helvetica, sans-serif;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
outline: 0px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
body {overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.blackMask {position: fixed; display: table; width: 100%; height: 100%; top: 0px; left: 0px; visibility: hidden; background-color: rgba(0,0,0,0.8); text-align: center; z-index: 100}
|
||||
h1 {font-size: 36px; font-weight: normal; color: #888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #fff}
|
||||
|
||||
.blackMask {position: fixed; display: table; width: 100%; height: 100%; top: 0; left: 0; visibility: hidden; background-color: rgba(0,0,0,0.8); text-align: center; z-index: 100}
|
||||
.blackMask .popupVCenter {#position: absolute; display: table-cell; #top: 50%; vertical-align: middle; text-align: center}
|
||||
.popupVCenter .popup {#position: relative; #top: -50%; text-align: center; color: #ffffff; font-size: 10px}
|
||||
.popupVCenter .popup {#position: relative; #top: -50%; text-align: center; color: #fff; font-size: 10px}
|
||||
.whiteGlow {
|
||||
-webkit-box-shadow: 0 0 8px 2px rgba(255,255,255,0.6);
|
||||
-moz-box-shadow: 0 0 8px 2px rgba(255,255,255,0.6);
|
||||
box-shadow: 0 0 8px 2px rgba(255,255,255,0.6);
|
||||
}
|
||||
|
||||
.circleOutside {background-color: rgba(0,0,0,0); border:5px solid rgba(0,183,229,0.9); opacity:.9; border-top:5px solid rgba(0,0,0,0); border-left:5px solid rgba(0,0,0,0); border-radius:50px; box-shadow: 0 0 35px #2187e7;
|
||||
width:50px; height:50px; margin:0 auto; -moz-animation:spin .5s infinite linear; -webkit-animation:spin .5s infinite linear;
|
||||
@@ -51,38 +60,52 @@ body {overflow: hidden;
|
||||
100% { -webkit-transform:rotate(-360deg);}
|
||||
}
|
||||
|
||||
.progressBar {top: 0px; left: 0px; width:100%; height:1px; margin:2px 0; background:#2187e7; position:absolute; box-shadow:0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
.progressBar {top: 0; left: 0; width:100%; height:1px; margin:2px 0; background:#2187e7; position:absolute; box-shadow:0 0 10px 1px rgba(0,198,255,0.7);
|
||||
-moz-animation:fullexpand 10s ease-out; -webkit-animation:fullexpand 10s ease-out;
|
||||
}
|
||||
@-moz-keyframes fullexpand {
|
||||
0% { width:0px;}
|
||||
0% { width:0;}
|
||||
100%{ width:100%;}
|
||||
}
|
||||
@-webkit-keyframes fullexpand {
|
||||
0% { width:0px;}
|
||||
0% { width:0;}
|
||||
100%{ width:100%;}
|
||||
}
|
||||
|
||||
.header {position: absolute; display: inline-block; width: 100%; height: 40px; background-color: #ffffff; text-align: right; z-index: 2}
|
||||
.header {position: absolute; display: inline-block; top: 0; left: 0; width: 100%; height: 40px; background-color: #fff; text-align: right; z-index: 2}
|
||||
.header .plugins {position: absolute; display: inline-block; left: 15px; top: 3px}
|
||||
.header .plugins img {position: relative; display: inline-block; margin-right: 15px}
|
||||
.header .version {position: relative; display: inline-block; margin-top: 25px; font-size: 10px; color: #bbbbbb}
|
||||
.header .logo {position: relative; margin: 5px 10px 0px 5px}
|
||||
.header .screenModeIcon {position: absolute; top: 5px; right: 178px; cursor: pointer}
|
||||
.header .version {position: relative; display: inline-block; margin-top: 25px; font-size: 10px; color: #bbb}
|
||||
.header .logo {position: relative; margin: 5px 10px 0 5px; cursor: pointer}
|
||||
|
||||
.files {position: absolute; display: inline-block; height: 100%; width: 250px; background-color: #e0e0e0; background-image: url('../images/files-arrow.gif'); background-repeat: no-repeat; background-position: 100% 50%; overflow: hidden; z-index: 1;
|
||||
-webkit-box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
|
||||
box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
|
||||
.files {position: absolute; display: inline-block; top: 0; left: 0; height: 100%; width: 250px; background-color: #444; background-image: url('../images/files-arrow.gif'); background-repeat: no-repeat; background-position: 100% 50%; overflow: hidden; z-index: 1;
|
||||
-webkit-box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
}
|
||||
.files .account {display: inline-block; height: 50px; width: 250px; margin-top: 40px; background-color: #888}
|
||||
.files .accountLoginContainer {position: absolute; width: 250px; height: 50px; z-index: 1}
|
||||
.files .accountLoginContainer .accountLogin {position: absolute; width: 250px; height: 50px; top: 0; background-color: #666;
|
||||
-webkit-transition: top 0.3s;
|
||||
-moz-transition: top 0.3s;
|
||||
-o-transition: top 0.3s;
|
||||
transition: top 0.3s;
|
||||
}
|
||||
.files .account {display: inline-block; height: 50px; width: 250px; margin-top: 40px; background-color: #888888}
|
||||
.files .accountOptions {position: relative; height: 31px; width: 200px; margin-left: 15px; margin-top: 8px}
|
||||
.files .accountOptions img {cursor: pointer}
|
||||
.files .accountPassword {position: relative; border: 1px solid #888888; background-color: #999999; height: 18px; width: 140px; margin-left: 14px; margin-top: 15px}
|
||||
.files .button {position: absolute; border: 0px; background: #999999; color: #555555; height:20px; margin-top: 16px; margin-left: 5px; font-size: 11px; cursor: pointer}
|
||||
.files .button:hover {background-color: #444444; color: #eeeeee}
|
||||
.files .lock {margin-left: 225px; margin-top: -20px}
|
||||
.files .accountPassword {position: relative; border: 1px solid #888; background-color: #999; height: 18px; width: 140px; margin-left: 14px; margin-top: 15px}
|
||||
.files input:focus, .findReplace input:focus, .findReplace select:focus, .accountPassword:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
-moz-box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
}
|
||||
.files .button {position: absolute; border: 0; background: #999; color: #555; height:20px; margin-top: 16px; margin-left: 5px; font-size: 11px; cursor: pointer}
|
||||
.files .button:hover {background-color: #444; color: #eee}
|
||||
.files .lock {position: relative; margin-left: 225px; margin-top: -20px; z-index: 1}
|
||||
.files .frame {display: inline-block; width: 250px}
|
||||
.files .serverMessage {position: absolute; display: inline-block; width: 180px; bottom: 0px; margin-bottom: 30px; background-color: rgba(255,255,255,0.8); font-size: 10px; padding: 7px 12px; opacity: 0;
|
||||
.files .serverMessage {position: absolute; display: inline-block; width: 450px; bottom: 0; margin-bottom: 30px; background-color: rgba(255,255,255,0.8); font-size: 10px; padding: 7px 12px; opacity: 0;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
-o-transition: all 0.2s;
|
||||
@@ -90,52 +113,53 @@ body {overflow: hidden;
|
||||
}
|
||||
.files .serverMessage b {font-size: 10px}
|
||||
|
||||
.editor {position: absolute; display: inline-block; top: 0px; left: 15px; width: 2400px; background-color: #fbfbfb;}
|
||||
.editor .tabsBar {display: inline-block; height: 21px; width: 2400px; margin-top: 40px; padding-left: 41px; border-bottom: solid 1px #888888; background-color: #eeeeee;}
|
||||
.tabsBar .tab {display: inline-block; display: none; background-image: url('../images/nav-bg.gif'); background-repeat: repeat-x; background-position: 0px 0px; padding: 4px 8px 2px 8px; font-size: 10px; border-left: solid 1px #ffffff; border-right: solid 1px #bbbbbb; color: #ffffff; cursor: pointer;
|
||||
-webkit-transition: all 0.2s;
|
||||
-moz-transition: all 0.2s;
|
||||
-o-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
.editor {position: absolute; display: inline-block; top: 0; left: 15px; width: 2400px}
|
||||
.editor .tabsBar {display: inline-block; height: 22px; width: 2400px; margin-top: 40px; padding-left: 41px; background-color: #888;}
|
||||
.tabsBar .tab {display: inline-block; display: none; background-image: url('../images/nav-bg.gif'); background-repeat: repeat-x; background-position: 0 0; padding: 5px 8px 2px 8px; font-size: 10px; border-left: solid 1px #fff; border-right: solid 1px #777; color: #fff; cursor: pointer;
|
||||
-webkit-transition: all 0.15s;
|
||||
-moz-transition: all 0.15s;
|
||||
-o-transition: all 0.15s;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.tabsBar .tab img {margin: 1px 0px 0px 5px}
|
||||
.tabsBar .newTab {display: inline-block; background-image: url('../images/nav-bg.gif'); background-repeat: repeat-x; background-position: 0px 0px; padding: 5px 5px 1px 5px; border-left: solid 1px #ffffff; border-right: solid 1px #bbbbbb; cursor: pointer;}
|
||||
.editor .findBar {display: inline-block; height: 28px; width: 2400px; background-color: #eeeeee}
|
||||
.tabsBar .tab .closeTab {margin: 1px 0 0 5px; border-radius: 6px}
|
||||
.tabsBar .newTab {display: inline-block; background-image: url('../images/nav-bg.gif'); background-repeat: repeat-x; background-position: 0 0; padding: 6px 5px 1px 5px; border-left: solid 1px #fff; border-right: solid 1px #777; cursor: pointer;}
|
||||
.editor .findBar {display: inline-block; height: 28px; width: 2400px; color: #fff; background-color: #141414}
|
||||
.findBar .findReplace {position: absolute; z-index: 1}
|
||||
.findReplace select {position: relative; font-size: 10px; margin: 8px 2px 0px 2px; top: -2px;}
|
||||
.findReplace .findText {display: inline-block; height: 21px; font-size: 10px; margin: 8px 2px 0px 2px; margin-left: 43px}
|
||||
.findReplace select {position: relative; font-size: 10px; margin: 8px 2px 0 2px; top: -2px;}
|
||||
.findReplace .findText {display: inline-block; height: 21px; font-size: 10px; margin: 8px 2px 0 2px; margin-left: 43px}
|
||||
.findReplace .find {position: relative; width: 120px; height: 16px; border: 0; top: -2px; font-size: 10px; padding-left: 5px}
|
||||
.findReplace .findTextPlural {display: inline-block; height: 21px; font-size: 10px; margin: 8px 2px 0px 0px}
|
||||
.findReplace .replaceText {height: 21px; font-size: 10px; margin: 8px 2px 0px 2px}
|
||||
.findReplace .findTextPlural {display: inline-block; height: 21px; font-size: 10px; margin: 8px 2px 0 0}
|
||||
.findReplace .replaceAction {margin: 0 2px 0 0; top: -2px}
|
||||
.findReplace .replaceText {height: 21px; font-size: 10px; margin: 8px 2px 0 2px}
|
||||
.findReplace .replace {position: relative; width: 120px; height: 16px; border: 0; top: -2px; font-size: 10px; padding-left: 5px}
|
||||
.findReplace .targetText {height: 21px; font-size: 10px; margin: 8px 2px 0px 2px}
|
||||
.findReplace .submit {position: relative; top: -2px; height: 17px; border: 1px solid #bbbbbb; background-color: #f8f8f8; font-size: 10px; cursor: pointer}
|
||||
.findReplace .results {position: relative; display: inline-block; width: 200px; height: 20px; font-size: 10px; margin: 8px 0px 0px 20px}
|
||||
.findReplace .targetText {height: 21px; font-size: 10px; margin: 8px 2px 0 2px}
|
||||
.findReplace .submit {position: relative; top: -2px; height: 17px; border: 1px solid #bbb; background-color: #f8f8f8; font-size: 10px; cursor: pointer}
|
||||
.findReplace .results {position: relative; display: inline-block; width: 200px; height: 20px; font-size: 10px; margin: 8px 0 0 20px}
|
||||
.findBar .codeAssist {position: fixed; display: inline-block; width: 100px; right: 74px; top: 70px; height: 21px; font-size: 10px; z-index: 1}
|
||||
.findBar .codeAssist input {margin-top: -1px}
|
||||
.findBar .goLine {position: fixed; display: inline-block; width: 100px; right: -10px; top: 70px; height: 21px; font-size: 10px; z-index: 1}
|
||||
.goLine .goToLine {width: 25px; height: 16px; border: 0; font-size: 10px; margin: -3px 0px 0px 3px}
|
||||
.goLine .goToLine {width: 25px; height: 16px; border: 0; font-size: 10px; margin: -3px 0 0 3px}
|
||||
.editor .code {position: relative; display: inline-block; top: 28px; width: 600px; height: 600px; visibility: hidden}
|
||||
|
||||
.footer {position: fixed; display: inline-block; width: 100%; height: 30px; bottom: 0px; background-color: rgba(0,0,0,0.7); left: 0px; z-index: 2}
|
||||
.footer .nesting {display: inline-block; padding: 5px 8px; margin: 4px 0px 0px 15px; font-weight: bold; font-size: 10px; color: #ffffff; background-color: #00bb00}
|
||||
.footer .nestLoc {position: absolute; display: inline-block; width: 120px; padding: 5px 0px 0px 8px; margin-top: 3px; left: 112px; font-weight: bold; font-size: 12px; color: #ffffff; text-align: right}
|
||||
.footer .nestDisplay {position: absolute; display: inline-block; padding: 5px 0px 0px 8px; margin-top: 3px; left: 255px; font-size: 12px; color: #ffffff; text-align: right}
|
||||
.footer .charDisplay {position: absolute; display: inline-block; padding: 5px 0px 0px 8px; margin-top: 3px; left: 100%; font-weight: bold; font-size: 12px; color: #ffffff; text-align: right; width: 200px; text-align: right; margin-left: -220px}
|
||||
.footer {position: fixed; display: inline-block; width: 100%; height: 30px; bottom: 0; background-color: rgba(0,0,0,0.7); left: 0; z-index: 2}
|
||||
.footer .nesting {display: inline-block; padding: 5px 8px; margin: 4px 0 0 15px; font-weight: bold; font-size: 10px; color: #fff; background-color: #0b0}
|
||||
.footer .nestLoc {position: absolute; display: inline-block; width: 120px; padding: 5px 0 0 8px; margin-top: 3px; left: 112px; font-weight: bold; font-size: 12px; color: #fff; text-align: right}
|
||||
.footer .nestDisplay {position: absolute; display: inline-block; padding: 5px 0 0 8px; margin-top: 3px; left: 255px; font-size: 12px; color: #fff; text-align: right}
|
||||
.footer .charDisplay {position: absolute; display: inline-block; padding: 5px 0 0 8px; margin-top: 3px; left: 100%; font-weight: bold; font-size: 12px; color: #fff; text-align: right; width: 200px; text-align: right; margin-left: -220px}
|
||||
|
||||
.textbox {
|
||||
-webkit-box-shadow: inset 1px 1px 2px 0px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: inset 1px 1px 2px 0px rgba(0,0,0,0.4);
|
||||
box-shadow: inset 1px 1px 2px 0px rgba(0,0,0,0.4);
|
||||
-webkit-box-shadow: inset 1px 1px 2px 0 rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: inset 1px 1px 2px 0 rgba(0,0,0,0.4);
|
||||
box-shadow: inset 1px 1px 2px 0 rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.fileMenu {position: absolute; display: none; left: 0px; top: 0px; background-color: #333333; z-index: 10}
|
||||
.fileMenu a {display: block; padding: 2px 5px; background-color: #444444; color: #eeeeee; text-decoration: none}
|
||||
.fileMenu a:hover {background-color: #666666}
|
||||
.fileMenu {position: absolute; display: none; left: 0; top: 0; background-color: #333; z-index: 10}
|
||||
.fileMenu a {display: block; padding: 2px 5px; background-color: #444; color: #eee; text-decoration: none}
|
||||
.fileMenu a:hover {background-color: #666}
|
||||
|
||||
.screenContainer {position: absolute; display: table; width: 100%; height: 100%; top: 0px; left: 0px; text-align: center}
|
||||
.screenContainer {position: absolute; display: table; width: 100%; height: 100%; top: 0; left: 0; text-align: center}
|
||||
.screenContainer .screenVCenter {#position: absolute; display: table-cell; #top: 50%; vertical-align: middle; text-align: center}
|
||||
.screenVCenter .screenCenter {#position: relative; #top: -50%; text-align: center; display: inline}
|
||||
.screenCenter .version {position: relative; display: block; margin: 5px 0px 15px 0px; font-size: 10px; color: #bbbbbb}
|
||||
.screenCenter .accountPassword {border: 1px solid #888888; height: 18px}
|
||||
.screenCenter .button {border: 0px; background: #666666; color: #ffffff; height: 22px}
|
||||
.screenCenter .version {position: relative; display: block; margin: 5px 0 15px 0; font-size: 10px; color: #bbb}
|
||||
.screenCenter .accountPassword {border: 1px solid #888; height: 18px}
|
||||
.screenCenter .button {border: 0; background: #666; color: #fff; height: 22px; cursor: pointer}
|
||||
417
lib/coder.js
@@ -1,9 +1,3 @@
|
||||
// ICE coder by Matt Pass
|
||||
// Free to use it for your own purposes, commercial or not, just let me know of any cool uses or customisations. :)
|
||||
// No warranty or liability accepted for anything, all responsibility of use is your own.
|
||||
// Latest version: https://github.com/mattpass/ICEcoder
|
||||
// Twitter: @mattpass
|
||||
|
||||
var ICEcoder = {
|
||||
// Define settings
|
||||
filesW: 250, // Initial width of the files pane
|
||||
@@ -16,6 +10,7 @@ var ICEcoder = {
|
||||
delKeyDown: false, // Indicates if DEL keydown
|
||||
canSwitchTabs: true, // Stops switching of tabs when trying to close
|
||||
openFiles: [], // Array of open file URLs
|
||||
openFileMDTs: [], // Array of open file modification datetimes
|
||||
cMInstances: [], // List of CodeMirror instance no's
|
||||
nextcMInstance: 1, // Next available CodeMirror instance no
|
||||
selectedFiles: [], // Array of selected files
|
||||
@@ -25,24 +20,36 @@ var ICEcoder = {
|
||||
mouseDown: false, // If the mouse is down or not
|
||||
draggingFilesW: false, // If we're dragging the file manager width or not
|
||||
serverQueueItems: [], // Array of URLs to call in order
|
||||
stickyTab: false, // If we have a sticky tab open or not
|
||||
stickyTabWindow: false, // Target variable for the sticky tab window
|
||||
pluginIntervalRefs: [], // Array of plugin interval refs
|
||||
|
||||
// Don't consider these tags as part of nesting as they're singles, JS, PHP or Ruby code blocks
|
||||
tagNestExceptions: ["!DOCTYPE","meta","link","img","br","hr","input","script","?php","?","%"],
|
||||
|
||||
// On load, set aliases, set the layout and get the nest location
|
||||
init: function() {
|
||||
var aliasArray = ["header","files","account","fmLock","filesFrame","editor","tabsBar","findBar","content","footer","nestValid","nestDisplay","charDisplay"];
|
||||
// Set our aliases
|
||||
initAliases: function() {
|
||||
var aliasArray = ["header","files","account","accountLogin","fmLock","filesFrame","editor","tabsBar","findBar","content","footer","nestValid","nestDisplay","charDisplay"];
|
||||
|
||||
// Create our ID aliases
|
||||
for (var i=0;i<aliasArray.length;i++) {
|
||||
ICEcoder[aliasArray[i]] = top.document.getElementById(aliasArray[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// On load, set the layout and get the nest location
|
||||
init: function(login) {
|
||||
// Set layout & the nest location
|
||||
ICEcoder.setLayout();
|
||||
|
||||
// Hide the loading screen
|
||||
top.document.getElementById('loadingMask').style.visibility = "hidden";
|
||||
|
||||
// If we're logging in, slide the login area to reveal the icons
|
||||
if (login) {
|
||||
top.document.getElementById('accountLogin').style.top = "-50px";
|
||||
setTimeout(function() {top.document.getElementById('accountLoginContainer').style.display = "none";},300);
|
||||
}
|
||||
},
|
||||
|
||||
// Set our layout according to the browser size
|
||||
@@ -55,15 +62,15 @@ var ICEcoder = {
|
||||
|
||||
// Apply sizes to various elements of the page
|
||||
headerH = 40, footerH = 30, accountH = 50, tabsBarH = 21, findBarH = 28;
|
||||
header.style.width = tabsBar.style.width = findBar.style.width = winW + "px";
|
||||
files.style.width = editor.style.left = this.filesW + "px";
|
||||
account.style.height = accountH + "px";
|
||||
fmLock.style.marginLeft = (this.filesW-27) + "px";
|
||||
filesFrame.style.height = (winH-headerH-accountH-footerH) + "px";
|
||||
this.header.style.width = this.tabsBar.style.width = this.findBar.style.width = winW + "px";
|
||||
this.files.style.width = this.accountLogin.style.width = this.editor.style.left = this.filesW + "px";
|
||||
this.account.style.height = this.accountH + "px";
|
||||
this.fmLock.style.marginLeft = (this.filesW-27) + "px";
|
||||
this.filesFrame.style.height = (winH-headerH-accountH-footerH) + "px";
|
||||
|
||||
// If we need to set the editor sizes
|
||||
if (!dontSetEditor) {
|
||||
editor.style.width = ICEcoder.content.style.width = (winW-this.filesW) + "px";
|
||||
this.editor.style.width = ICEcoder.content.style.width = (winW-this.filesW) + "px";
|
||||
ICEcoder.content.style.height = (winH-headerH-footerH-tabsBarH-findBarH) + "px";
|
||||
|
||||
// Resize the CodeMirror instances to match the window size
|
||||
@@ -79,12 +86,11 @@ var ICEcoder = {
|
||||
contentCleanUp: function() {
|
||||
var fileName, cM, content;
|
||||
|
||||
// If it's not a JS, Ruby or CSS file, replace & and our temp </textarea> value
|
||||
// If it's not a JS, CoffeeScript Ruby or CSS file, replace & and our temp </textarea> value
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf(".js")<0&&fileName.indexOf(".rb")&&fileName.indexOf(".css")<0) {
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0) {
|
||||
cM = ICEcoder.getcMInstance();
|
||||
content = cM.getValue();
|
||||
if (top.ICEcoder.codeAssist) {content = content.replace(/ & /g,' & ');};
|
||||
content = content.replace(/<ICEcoder:\/:textarea>/g,'</textarea>');
|
||||
|
||||
// Then set the content in the editor & clear the history
|
||||
@@ -169,12 +175,13 @@ var ICEcoder = {
|
||||
|
||||
// Now we've built up our nest depth array, if we're due to show it in the display
|
||||
if (updateNestDisplay && !top.ICEcoder.dontUpdateNest) {
|
||||
|
||||
// Clear the display
|
||||
ICEcoder.nestDisplay.innerHTML = "";
|
||||
if ("undefined" != typeof ICEcoder.openFiles[ICEcoder.selectedTab-1]) {
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf(".js")<0&&fileName.indexOf(".rb")<0&&fileName.indexOf(".css")<0) {
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0&&
|
||||
(nestCheck.indexOf("include(")==-1)&&(nestCheck.indexOf("include_once(")==-1)&&
|
||||
(nestCheck.indexOf("<html")>-1||nestCheck.indexOf("<body")>-1)) {
|
||||
|
||||
// Then for all the array items, output as the nest display
|
||||
for (var i=0;i<ICEcoder.htmlTagArray.length;i++) {
|
||||
@@ -238,12 +245,17 @@ var ICEcoder = {
|
||||
} else {
|
||||
top.ICEcoder.saveFile();
|
||||
}
|
||||
top.ICEcoder.ctrlKeyDown = false;
|
||||
top.ICEcoder.stickyTabMaybe = true;
|
||||
return false;
|
||||
|
||||
// CTRL+Enter (Open Webpage)
|
||||
} else if(key==13 && top.ICEcoder.ctrlKeyDown==true && top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1] != "/[NEW]") {
|
||||
window.open(top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]);
|
||||
if (top.ICEcoder.stickyTabMaybe) {
|
||||
top.ICEcoder.stickyTabWindow = window.open(top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1],"stickyTab");
|
||||
top.ICEcoder.stickyTab = true;
|
||||
} else {
|
||||
window.open(top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1]);
|
||||
}
|
||||
top.ICEcoder.ctrlKeyDown = false;
|
||||
return false;
|
||||
|
||||
@@ -269,7 +281,7 @@ var ICEcoder = {
|
||||
|
||||
key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode;
|
||||
|
||||
if (key==17) {top.ICEcoder.ctrlKeyDown = false;}
|
||||
if (key==17) {top.ICEcoder.ctrlKeyDown = false; top.ICEcoder.stickyTabMaybe = false;}
|
||||
if (key==16) {top.ICEcoder.shiftKeyDown = false;}
|
||||
if (key==46) {top.ICEcoder.delKeyDown = false;}
|
||||
},
|
||||
@@ -277,7 +289,7 @@ var ICEcoder = {
|
||||
// Set the width of the file manager on demand
|
||||
changeFilesW: function(expandContract) {
|
||||
|
||||
if (!ICEcoder.lockedNav) {
|
||||
if (!ICEcoder.lockedNav||(ICEcoder.lockedNav && ICEcoder.filesW==ICEcoder.minFilesW)) {
|
||||
if ("undefined" != typeof ICEcoder.changeFilesInt) {clearInterval(ICEcoder.changeFilesInt)};
|
||||
ICEcoder.changeFilesInt = setInterval(function() {ICEcoder.changeFilesWStep(expandContract)},10);
|
||||
}
|
||||
@@ -328,31 +340,50 @@ var ICEcoder = {
|
||||
ICEcoder.selectedTab = newTab;
|
||||
cM = ICEcoder.getcMInstance();
|
||||
|
||||
// Switch mode to HTML, PHP, CSS etc
|
||||
ICEcoder.switchMode();
|
||||
if (cM) {
|
||||
// Switch mode to HTML, PHP, CSS etc
|
||||
ICEcoder.switchMode();
|
||||
|
||||
// Set all cM instances to be hidden, then make our selected instance visable
|
||||
for (var i=0;i<ICEcoder.cMInstances.length;i++) {
|
||||
ICEcoder.content.contentWindow['cM'+ICEcoder.cMInstances[i]].setOption('theme',top.theme+' hidden');
|
||||
// Set all cM instances to be hidden, then make our selected instance visable
|
||||
for (var i=0;i<ICEcoder.cMInstances.length;i++) {
|
||||
ICEcoder.content.contentWindow['cM'+ICEcoder.cMInstances[i]].setOption('theme',top.theme+' hidden');
|
||||
}
|
||||
cM.setOption('theme',top.theme+' visible');
|
||||
|
||||
// Focus on & refresh our selected instance
|
||||
cM.focus();
|
||||
cM.refresh();
|
||||
|
||||
// Highlight the selected tab
|
||||
ICEcoder.redoTabHighlight(ICEcoder.selectedTab);
|
||||
|
||||
// Redo our find display
|
||||
top.ICEcoder.findMode = false;
|
||||
ICEcoder.findReplace('find',true,false);
|
||||
|
||||
// Finally, update the cursor display
|
||||
top.ICEcoder.getCaretPosition();
|
||||
top.ICEcoder.updateCharDisplay();
|
||||
}
|
||||
cM.setOption('theme',top.theme+' visible');
|
||||
|
||||
// Focus on & refresh our selected instance
|
||||
cM.focus();
|
||||
cM.refresh();
|
||||
|
||||
// Highlight the selected tab
|
||||
ICEcoder.redoTabHighlight(ICEcoder.selectedTab);
|
||||
},
|
||||
|
||||
// Reset all tabs to be without a highlight and then highlight the selected
|
||||
redoTabHighlight: function(selectedTab) {
|
||||
var bgVPos;
|
||||
var cM, bgVPos, tColor, fileLink;
|
||||
|
||||
cM = ICEcoder.getcMInstance();
|
||||
for(var i=1;i<=ICEcoder.changedContent.length;i++) {
|
||||
ICEcoder.changedContent[i-1]==1 ? bgVPos = -44 : bgVPos = 0;
|
||||
i==selectedTab ? ICEcoder.changedContent[selectedTab-1]==1 ? bgVPos = -33 : bgVPos = -22 : bgVPos = bgVPos;
|
||||
document.getElementById('tab'+i).style.backgroundPosition = "0px "+bgVPos+"px";
|
||||
if (document.getElementById('closeTabButton'+i)) {
|
||||
ICEcoder.changedContent[i-1]==1 && cM.historySize().undo>0 ? document.getElementById('closeTabButton'+i).style.backgroundColor = "#b00" : document.getElementById('closeTabButton'+i).style.backgroundColor = "rgba(255,255,255,0.3)";
|
||||
}
|
||||
i==selectedTab ? tColor = "#000" : tColor = "#fff";
|
||||
if ("undefined" != typeof top.ICEcoder.openFiles[i-1] && top.ICEcoder.openFiles[i-1] != "/[NEW]") {
|
||||
fileLink = top.ICEcoder.filesFrame.contentWindow.document.getElementById(top.ICEcoder.openFiles[i-1].replace(/\//g,"|"));
|
||||
i==selectedTab ? fileLink.style.backgroundColor = "#4499dd" : fileLink.style.backgroundColor = "rgba(255,255,255,0.15)";
|
||||
}
|
||||
document.getElementById('tab'+i).style.color = tColor;
|
||||
i==selectedTab ? bgVPos = -22 : bgVPos = 0;
|
||||
document.getElementById('tab'+i).style.backgroundPosition = "0 "+bgVPos+"px";
|
||||
}
|
||||
ICEcoder.changedContent[selectedTab-1]==1 ? top.ICEcoder.fMIconVis('fMSave',1) : top.ICEcoder.fMIconVis('fMSave',0.3);
|
||||
},
|
||||
@@ -371,7 +402,6 @@ var ICEcoder = {
|
||||
|
||||
cM = ICEcoder.getcMInstance('new');
|
||||
ICEcoder.switchTab(ICEcoder.openFiles.length);
|
||||
ICEcoder.content.style.visibility='visible';
|
||||
|
||||
cM.setLineClass(ICEcoder['cMActiveLine'+ICEcoder.selectedTab], null);
|
||||
ICEcoder['cMActiveLine'+ICEcoder.selectedTab] = cM.setLineClass(0, "cm-s-activeLine");
|
||||
@@ -386,7 +416,7 @@ var ICEcoder = {
|
||||
top.ICEcoder.openFiles.push(top.ICEcoder.shortURL);
|
||||
|
||||
// Setup a new tab
|
||||
closeTabLink = '<a nohref onClick="parent.ICEcoder.closeTab('+(top.ICEcoder.openFiles.length)+')"><img src="images/nav-close.gif"></a>';
|
||||
closeTabLink = '<a nohref onClick="top.ICEcoder.closeTab('+(top.ICEcoder.openFiles.length)+')"><img src="images/nav-close.gif" id="closeTabButton'+(top.ICEcoder.openFiles.length)+'" class="closeTab"></a>';
|
||||
top.document.getElementById('tab'+(top.ICEcoder.openFiles.length)).style.display = "inline-block";
|
||||
top.document.getElementById('tab'+(top.ICEcoder.openFiles.length)).innerHTML = top.ICEcoder.openFiles[top.ICEcoder.openFiles.length-1] + " " + closeTabLink;
|
||||
|
||||
@@ -397,7 +427,7 @@ var ICEcoder = {
|
||||
// Add a new value ready to indicate if this content has been changed
|
||||
top.ICEcoder.changedContent.push(0);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
},
|
||||
|
||||
// Create a new tab for a file
|
||||
@@ -408,7 +438,7 @@ var ICEcoder = {
|
||||
top.ICEcoder.openFiles[tabNum] = newName;
|
||||
|
||||
// Setup a new tab
|
||||
closeTabLink = '<a nohref onClick="parent.ICEcoder.closeTab('+tabNum+')"><img src="images/nav-close.gif"></a>';
|
||||
closeTabLink = '<a nohref onClick="parent.ICEcoder.closeTab('+tabNum+')"><img src="images/nav-close.gif" id="closeTabButton'+tabNum+'" class="closeTab"></a>';
|
||||
top.document.getElementById('tab'+tabNum).innerHTML = top.ICEcoder.openFiles[tabNum] + " " + closeTabLink;
|
||||
},
|
||||
|
||||
@@ -421,11 +451,11 @@ var ICEcoder = {
|
||||
ICEcoder.caretPos=cM.getValue().length;
|
||||
ICEcoder.getNestLocation();
|
||||
// Nesting is OK if at the end of the file we have no nests left, or it's a JS, Ruby or CSS file
|
||||
if (ICEcoder.htmlTagArray.length==0||fileName.indexOf(".js")>0||fileName.indexOf(".rb")>0||fileName.indexOf(".css")>0) {
|
||||
ICEcoder.nestValid.style.backgroundColor="#00bb00";
|
||||
if (ICEcoder.htmlTagArray.length==0||fileName.indexOf(".js")>0||fileName.indexOf(".coffee")>0||fileName.indexOf(".rb")>0||fileName.indexOf(".css")>0) {
|
||||
ICEcoder.nestValid.style.backgroundColor="#0b0";
|
||||
ICEcoder.nestValid.innerHTML = "Nesting OK";
|
||||
} else {
|
||||
ICEcoder.nestValid.style.backgroundColor="#ff0000";
|
||||
ICEcoder.nestValid.style.backgroundColor="#f00";
|
||||
ICEcoder.nestValid.innerHTML = "Nesting Broken";
|
||||
}
|
||||
},
|
||||
@@ -471,13 +501,14 @@ var ICEcoder = {
|
||||
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf(".js")>0) {caretLocType="JavaScript"};
|
||||
if (fileName.indexOf(".coffee")>0) {caretLocType="CoffeeScript"};
|
||||
if (fileName.indexOf(".rb")>0) {caretLocType="Ruby"};
|
||||
if (fileName.indexOf(".css")>0) {caretLocType="CSS"};
|
||||
|
||||
ICEcoder.caretLocType = caretLocType;
|
||||
|
||||
// If we're in a JS, PHP or Ruby code block, add that to the nest display
|
||||
if (caretLocType=="JavaScript"||caretLocType=="PHP"||caretLocType=="Ruby") {
|
||||
// If we're in a JS, CoffeeScript PHP or Ruby code block, add that to the nest display
|
||||
if (caretLocType=="JavaScript"||caretLocType=="CoffeeScript"||caretLocType=="PHP"||caretLocType=="Ruby") {
|
||||
ICEcoder.nestDisplay.innerHTML += " > " + caretLocType;
|
||||
}
|
||||
},
|
||||
@@ -485,7 +516,7 @@ var ICEcoder = {
|
||||
// Alter array indicating which files have changed
|
||||
redoChangedContent: function(evt) {
|
||||
var key;
|
||||
|
||||
|
||||
key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode;
|
||||
// Exclude a few keys such as Escape...
|
||||
if (top.ICEcoder.ctrlKeyDown==false && key!=27 && key!=20 && (key<16||key>19) && (key<37||key>40) && (key!=144||key!=145) && (key!=44||key!=45) && (key<33||key>36) && (key!=91||key!=92) && (key<112||key>123)) {
|
||||
@@ -511,38 +542,35 @@ var ICEcoder = {
|
||||
ICEcoder.openFiles[i-1] = ICEcoder.openFiles[i];
|
||||
|
||||
// reduce the tab reference number on the closeTab link by 1
|
||||
top.document.getElementById('tab'+i).innerHTML = top.document.getElementById('tab'+i).innerHTML.replace(("closeTab("+(i+1)+")"),"closeTab("+i+")");
|
||||
top.document.getElementById('tab'+i).innerHTML = top.document.getElementById('tab'+i).innerHTML.replace(("closeTab("+(i+1)+")"),"closeTab("+i+")").replace(("closeTabButton("+(i+1)+")"),"closeTabButton("+i+")");
|
||||
}
|
||||
|
||||
// hide the instance we're closing by setting the hide class, clear the value & remove from the array
|
||||
// hide the instance we're closing by setting the hide class and removing from the array
|
||||
ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[closeTabNum-1]].setOption('theme',top.theme+' hidden');
|
||||
ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[closeTabNum-1]].setValue('');
|
||||
top.ICEcoder.cMInstances.splice(closeTabNum-1,1);
|
||||
|
||||
// clear the rightmost tab (or only one left in a 1 tab scenario) & remove from the array
|
||||
top.document.getElementById('tab'+ICEcoder.openFiles.length).style.display = "none";
|
||||
top.document.getElementById('tab'+ICEcoder.openFiles.length).innerHTML = "";
|
||||
ICEcoder.openFiles.pop();
|
||||
|
||||
// Determin the new selectedTab number, reduced by 1 if we have some tabs, 0 for a reset state
|
||||
ICEcoder.openFiles.length>0 ? ICEcoder.selectedTab-=1 : ICEcoder.selectedTab = 0;
|
||||
ICEcoder.openFileMDTs.pop();
|
||||
// If we're closing the selected tab, determin the new selectedTab number, reduced by 1 if we have some tabs, 0 for a reset state
|
||||
if (ICEcoder.selectedTab==closeTabNum) {
|
||||
ICEcoder.openFiles.length>0 ? ICEcoder.selectedTab-=1 : ICEcoder.selectedTab = 0;
|
||||
}
|
||||
if (ICEcoder.openFiles.length>0 && ICEcoder.selectedTab==0) {ICEcoder.selectedTab=1};
|
||||
|
||||
// hide the content area if we have no tabs open
|
||||
if (ICEcoder.openFiles.length==0) {
|
||||
top.document.getElementById('content').style.visibility = "hidden";
|
||||
top.ICEcoder.fMIconVis('fMView',0.3);
|
||||
} else {
|
||||
// Switch the mode & the tab
|
||||
ICEcoder.switchMode();
|
||||
ICEcoder.switchTab(ICEcoder.selectedTab);
|
||||
}
|
||||
|
||||
// Highlight the selected tab after splicing the change state out of the array
|
||||
top.ICEcoder.changedContent.splice(closeTabNum-1,1);
|
||||
top.parent.ICEcoder.redoTabHighlight(ICEcoder.selectedTab);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
}
|
||||
// Lastly, stop it from trying to also switch tab
|
||||
top.ICEcoder.canSwitchTabs=false;
|
||||
@@ -565,7 +593,7 @@ var ICEcoder = {
|
||||
while (1) {
|
||||
if (node != null) {
|
||||
if (node.tagName == "UL") {
|
||||
var d = (node.style.display == "none")
|
||||
var d = (node.style.display == "none");
|
||||
node.style.display = (d) ? "block" : "none";
|
||||
this.className = (d) ? "open" : "closed";
|
||||
return false;
|
||||
@@ -585,6 +613,8 @@ var ICEcoder = {
|
||||
}
|
||||
}
|
||||
}
|
||||
aMenus[0].childNodes[0].className = "open";
|
||||
aMenus[0].childNodes[1].style.display = "block";
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -668,8 +698,20 @@ var ICEcoder = {
|
||||
|
||||
// Select or deselect file
|
||||
selectDeselectFile: function(action,file) {
|
||||
action == "select" ? file.style.backgroundColor="#888888" : file.style.backgroundColor="#dddddd";
|
||||
action == "select" ? file.style.color="#f8f8f8" : file.style.color="#000000";
|
||||
var isOpen;
|
||||
|
||||
top.ICEcoder.openFiles.indexOf(file.id.replace(/\|/g,"/")) > -1 ? isOpen = true : isOpen = false;
|
||||
|
||||
if (top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1] == file.id.replace(/\|/g,"/")) {
|
||||
file.style.backgroundColor="#4499dd";
|
||||
} else {
|
||||
if (action=="select") {
|
||||
file.style.backgroundColor="#888";
|
||||
} else {
|
||||
isOpen ? file.style.backgroundColor = "rgba(255,255,255,0.15)" : file.style.backgroundColor="transparent";
|
||||
}
|
||||
}
|
||||
action == "select" ? file.style.color="#fff" : file.style.color="#eee";
|
||||
},
|
||||
|
||||
// Create a new file (start & instant save)
|
||||
@@ -741,8 +783,8 @@ var ICEcoder = {
|
||||
var saveType;
|
||||
|
||||
saveAs ? saveType = "saveAs" : saveType = "save";
|
||||
|
||||
top.ICEcoder.serverQueue("add","lib/file-control.php?action=save&file="+ICEcoder.openFiles[ICEcoder.selectedTab-1].replace(/\//g,"|")+"&saveType="+saveType);
|
||||
|
||||
top.ICEcoder.serverQueue("add","lib/file-control.php?action=save&file="+ICEcoder.openFiles[ICEcoder.selectedTab-1].replace(/\//g,"|")+"&fileMDT="+ICEcoder.openFileMDTs[ICEcoder.selectedTab-1]+"&saveType="+saveType);
|
||||
top.ICEcoder.serverMessage('<b>Saving</b><br>'+ICEcoder.openFiles[ICEcoder.selectedTab-1]);
|
||||
},
|
||||
|
||||
@@ -757,14 +799,14 @@ var ICEcoder = {
|
||||
if(top.ICEcoder.openFiles[i]==shortURL.replace(/\|/g,"/")) {
|
||||
// rename array item and the tab
|
||||
top.ICEcoder.openFiles[i] = renamedFile;
|
||||
closeTabLink = '<a nohref onClick="top.ICEcoder.files.contentWindow.closeTab('+(i+1)+')"><img src="images/nav-close.gif"></a>';
|
||||
closeTabLink = '<a nohref onClick="top.ICEcoder.files.contentWindow.closeTab('+(i+1)+')"><img src="images/nav-close.gif" id="closeTabButton'+(i+1)+'" class="closeTab"></a>';
|
||||
top.document.getElementById('tab'+(i+1)).innerHTML = top.ICEcoder.openFiles[i] + " " + closeTabLink;
|
||||
}
|
||||
}
|
||||
top.ICEcoder.serverQueue("add","lib/file-control.php?action=rename&file="+renamedFile+"&oldFileName="+top.ICEcoder.rightClickedFile.replace(/\|/g,"/"));
|
||||
top.ICEcoder.serverMessage('<b>Renaming to</b><br>'+renamedFile);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -798,7 +840,7 @@ var ICEcoder = {
|
||||
if (!foundFile) {top.ICEcoder.selectFileFolder()};
|
||||
|
||||
if ("undefined" != typeof top.ICEcoder.thisFileFolderLink && top.ICEcoder.thisFileFolderLink!="") {
|
||||
top.ICEcoder.selectedFiles[0].indexOf(".")>0 ? menuType = "file" : menuType = "folder";
|
||||
top.ICEcoder.selectedFiles[0].indexOf(".")>-1 ? menuType = "file" : menuType = "folder";
|
||||
folderMenuItems = top.document.getElementById('folderMenuItems');
|
||||
menuType == "folder" && top.ICEcoder.selectedFiles.length == 1 ? folderMenuItems.style.display = "block" : folderMenuItems.style.display = "none";
|
||||
top.ICEcoder.selectedFiles.length > 1 ? singleFileMenuItems.style.display = "none" : singleFileMenuItems.style.display = "block";
|
||||
@@ -826,30 +868,42 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// Find & replace text according to user selections
|
||||
findReplace: function(action,resultsOnly) {
|
||||
var find, findLen, cM, content, lineCount, numChars, charsToCursor, charCount, startPos, endPos;
|
||||
findReplace: function(action,resultsOnly,buttonClick) {
|
||||
var find, findLen, replaceLen, cM, content, lineCount, numChars, charsToCursor, charCount, startPos, endPos, replaceQS;
|
||||
|
||||
// Determine our find string, in lowercase and the length of that
|
||||
find = parent.parent.document.getElementById('find').value.toLowerCase();
|
||||
find = top.document.getElementById('find').value;
|
||||
findLen = find.length;
|
||||
replaceLen = top.document.getElementById('replace').value.length;
|
||||
|
||||
// If we have something to find
|
||||
if (findLen>0) {
|
||||
// If we have something to find in currrent document
|
||||
if (findLen>0 && document.findAndReplace.target.value=="this document") {
|
||||
cM = ICEcoder.getcMInstance();
|
||||
content = cM.getValue().toLowerCase();
|
||||
content = cM.getValue();
|
||||
|
||||
// Find & replace the next instance?
|
||||
if (document.findAndReplace.connector.value=="and" && cM.getSelection()==find) {
|
||||
cM.replaceSelection(document.getElementById('replace').value);
|
||||
// Find & replace the next instance, or all?
|
||||
if (document.findAndReplace.connector.value=="and") {
|
||||
if (document.findAndReplace.replaceAction.value=="replace" && cM.getSelection()==find) {
|
||||
cM.replaceSelection(document.getElementById('replace').value);
|
||||
}
|
||||
if (document.findAndReplace.replaceAction.value=="replace all" && buttonClick) {
|
||||
var rExp = new RegExp(find,"g");
|
||||
cM.setValue(cM.getValue().replace(rExp,document.getElementById('replace').value));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the content again, as it might of changed
|
||||
content = cM.getValue();
|
||||
if (!top.ICEcoder.findMode||parent.parent.document.getElementById('find').value!=ICEcoder.lastsearch) {
|
||||
ICEcoder.results = [];
|
||||
|
||||
for (var i=0;i<content.length;i++) {
|
||||
if (content.substr(i,findLen)==find) {
|
||||
if (content.substr(i,findLen)==find && i!= ICEcoder.findResult) {
|
||||
ICEcoder.results.push(i);
|
||||
i+=findLen-1;
|
||||
}
|
||||
}
|
||||
|
||||
// Also remember the last search term made
|
||||
ICEcoder.lastsearch = find;
|
||||
}
|
||||
@@ -874,7 +928,7 @@ var ICEcoder = {
|
||||
charsToCursor = numChars+cM.getCursor().ch;
|
||||
ICEcoder.findResult = 0;
|
||||
for (var i=0;i<ICEcoder.results.length;i++) {
|
||||
if (ICEcoder.results[i]<=charsToCursor) {
|
||||
if (ICEcoder.results[i]<charsToCursor) {
|
||||
ICEcoder.findResult++;
|
||||
}
|
||||
}
|
||||
@@ -889,13 +943,17 @@ var ICEcoder = {
|
||||
}
|
||||
}
|
||||
|
||||
charCount = ICEcoder.results[ICEcoder.findResult]-content.lastIndexOf('\n',ICEcoder.results[ICEcoder.findResult])-1;
|
||||
charCount = ICEcoder.results[ICEcoder.findResult];
|
||||
startPos = new Object();
|
||||
startPos.line = lineCount;
|
||||
startPos.ch = charCount;
|
||||
endPos = new Object();
|
||||
endPos.line = lineCount;
|
||||
endPos.ch = charCount+findLen;
|
||||
if (document.findAndReplace.connector.value=="and" && document.findAndReplace.replaceAction.value=="replace all" && buttonClick) {
|
||||
endPos.ch = charCount+replaceLen;
|
||||
} else {
|
||||
endPos.ch = charCount+findLen;
|
||||
}
|
||||
|
||||
// Finally, highlight our selection
|
||||
cM = ICEcoder.getcMInstance();
|
||||
@@ -907,7 +965,14 @@ var ICEcoder = {
|
||||
parent.parent.document.getElementById('results').innerHTML = "No results";
|
||||
}
|
||||
} else {
|
||||
parent.parent.document.getElementById('results').innerHTML = "";
|
||||
// Show the relevant multiple results popup
|
||||
if (find != "" && buttonClick) {
|
||||
replaceQS = "";
|
||||
if (document.findAndReplace.connector.value=="and") {
|
||||
replaceQS = "&replace="+document.getElementById('replace').value;
|
||||
}
|
||||
top.document.getElementById('mediaContainer').innerHTML = '<iframe src="lib/multiple-results.php?find='+find+replaceQS+'" class="whiteGlow" style="width: 700px; height: 500px"></iframe>';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -927,14 +992,18 @@ var ICEcoder = {
|
||||
|
||||
cM = ICEcoder.getcMInstance();
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf('.js')>0) {
|
||||
cM.setOption("mode","javascript");
|
||||
} else if (fileName.indexOf('.rb')>0) {
|
||||
cM.setOption("mode","ruby");
|
||||
} else if (fileName.indexOf('.css')>0) {
|
||||
cM.setOption("mode","css");
|
||||
} else {
|
||||
cM.setOption("mode","application/x-httpd-php");
|
||||
if (fileName) {
|
||||
if (fileName.indexOf('.js')>0) {
|
||||
cM.setOption("mode","javascript");
|
||||
} else if (fileName.indexOf('.coffee')>0) {
|
||||
cM.setOption("mode","coffeescript");
|
||||
} else if (fileName.indexOf('.rb')>0) {
|
||||
cM.setOption("mode","ruby");
|
||||
} else if (fileName.indexOf('.css')>0) {
|
||||
cM.setOption("mode","css");
|
||||
} else {
|
||||
cM.setOption("mode","application/x-httpd-php");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -944,7 +1013,7 @@ var ICEcoder = {
|
||||
|
||||
lockIcon = top.document.getElementById('fmLock');
|
||||
ICEcoder.lockedNav ? ICEcoder.lockedNav = false : ICEcoder.lockedNav = true;
|
||||
ICEcoder.lockedNav ? lockIcon.src="images/file-manager-icons/padlock.png" : lockIcon.src="images/file-manager-icons/padlock-disabled.png";
|
||||
ICEcoder.lockedNav ? lockIcon.src="images/padlock.png" : lockIcon.src="images/padlock-disabled.png";
|
||||
},
|
||||
|
||||
// Determine the CodeMirror instance we're using on demand
|
||||
@@ -960,19 +1029,22 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// Start running plugin intervals according to given specifics
|
||||
startPluginIntervals: function(plugURL,plugTarget,plugTimer) {
|
||||
startPluginIntervals: function(plugRef,plugURL,plugTarget,plugTimer) {
|
||||
// For this window instances
|
||||
if (plugTarget=="_parent"||plugTarget=="_top"||plugTarget=="_self"||plugTarget=="") {
|
||||
setInterval('window.location=\''+plugURL+'\'',plugTimer*1000*60);
|
||||
top.ICEcoder['plugTimer'+plugRef] = setInterval('window.location=\''+plugURL+'\'',plugTimer*1000*60);
|
||||
|
||||
// for fileControl iframe instances
|
||||
} else if (plugTarget.indexOf("fileControl")==0) {
|
||||
setInterval(function() {top.ICEcoder.serverQueue("add",plugURL);top.ICEcoder.serverMessage(plugTarget.split(":")[1]);},plugTimer*1000*60);
|
||||
top.ICEcoder['plugTimer'+plugRef] = setInterval(function() {top.ICEcoder.serverQueue("add",plugURL);top.ICEcoder.serverMessage(plugTarget.split(":")[1]);},plugTimer*1000*60);
|
||||
|
||||
// for _blank or named target window instances
|
||||
} else {
|
||||
setInterval('window.open(\''+plugURL+'\',\''+plugTarget+'\')',plugTimer*1000*60);
|
||||
top.ICEcoder['plugTimer'+plugRef] = setInterval('window.open(\''+plugURL+'\',\''+plugTarget+'\')',plugTimer*1000*60);
|
||||
}
|
||||
|
||||
// push the plugin ref into our array
|
||||
top.ICEcoder.pluginIntervalRefs.push(plugRef);
|
||||
},
|
||||
|
||||
// Comment or uncomment line on keypress
|
||||
@@ -986,7 +1058,7 @@ var ICEcoder = {
|
||||
lCLen = lineContent.length;
|
||||
adjustCursor = 3;
|
||||
|
||||
if (ICEcoder.caretLocType=="JavaScript"||ICEcoder.caretLocType=="PHP"||ICEcoder.caretLocType=="Ruby"||ICEcoder.caretLocType=="CSS") {
|
||||
if (ICEcoder.caretLocType=="JavaScript"||ICEcoder.caretLocType=="CoffeeScript"||ICEcoder.caretLocType=="PHP"||ICEcoder.caretLocType=="Ruby"||ICEcoder.caretLocType=="CSS") {
|
||||
if (cM.somethingSelected()) {
|
||||
if (ICEcoder.caretLocType=="Ruby") {
|
||||
startLine = cM.getCursor(true).line;
|
||||
@@ -1002,7 +1074,7 @@ var ICEcoder = {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ICEcoder.caretLocType=="CSS") {
|
||||
if (ICEcoder.caretLocType=="CSS"||ICEcoder.caretLocType=="CoffeeScript") {
|
||||
lineContent.slice(0,3)!="/* " ? cM.setLine(linePos, "/* " + lineContent + " */") : cM.setLine(linePos, lineContent.slice(3,lCLen).slice(0,lCLen-5));
|
||||
if (lineContent.slice(0,3)=="/* ") {adjustCursor = -adjustCursor};
|
||||
} else if (ICEcoder.caretLocType=="Ruby") {
|
||||
@@ -1033,11 +1105,11 @@ var ICEcoder = {
|
||||
var tempX, tempY, scrollTop, IE;
|
||||
|
||||
IE = document.all ? true : false;
|
||||
if (!IE) {document.captureEvents(Event.MOUSEMOVE)};
|
||||
if (IE) {
|
||||
top.ICEcoder.mouseX = event.clientX + document.body.scrollLeft;
|
||||
top.ICEcoder.mouseY = event.clientY + document.body.scrollTop;
|
||||
top.ICEcoder.mouseX = e.clientX + document.body.scrollLeft;
|
||||
top.ICEcoder.mouseY = e.clientY + document.body.scrollTop;
|
||||
} else {
|
||||
document.captureEvents(Event.MOUSEMOVE);
|
||||
top.ICEcoder.mouseX = e.pageX;
|
||||
top.ICEcoder.mouseY = e.pageY;
|
||||
}
|
||||
@@ -1066,7 +1138,7 @@ var ICEcoder = {
|
||||
if (action=="add") {
|
||||
|
||||
// Determin if this is a file or folder and based on that, set the CSS styling & link
|
||||
file.indexOf(".")>0 ? actionElemType = "file" : actionElemType = "folder";
|
||||
file.indexOf(".")>-1 ? actionElemType = "file" : actionElemType = "folder";
|
||||
actionElemType=="file" ? cssStyle = "pft-file ext-" + file.substr(file.indexOf(".")+1,file.length) : cssStyle = "pft-directory";
|
||||
actionElemType=="file" ? hrefLink = "nohref" : hrefLink = "href=\"#\"";
|
||||
|
||||
@@ -1238,7 +1310,7 @@ var ICEcoder = {
|
||||
if (ICEcoder.selectedFiles.length==1) {
|
||||
top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.fullPath+top.ICEcoder.selectedFiles[0].replace('|','/');
|
||||
|
||||
if (action=="open" && ICEcoder.selectedFiles[0].indexOf(".")>0) {
|
||||
if (action=="open" && ICEcoder.selectedFiles[0].indexOf(".")>-1) {
|
||||
top.ICEcoder.thisFileFolderType='file';
|
||||
top.ICEcoder.openFile();
|
||||
}
|
||||
@@ -1271,7 +1343,7 @@ var ICEcoder = {
|
||||
ICEcoder.serverQueueItems.splice(1,ICEcoder.serverQueueItems.length);
|
||||
}
|
||||
top.document.getElementById('loadingMask').style.visibility = "hidden";
|
||||
top.ICEcoder.serverMessage('<b style="color: #dd0000">Cancelled tasks</b>');
|
||||
top.ICEcoder.serverMessage('<b style="color: #d00">Cancelled tasks</b>');
|
||||
setTimeout(function() {top.ICEcoder.serverMessage();},2000);
|
||||
},
|
||||
|
||||
@@ -1337,39 +1409,152 @@ var ICEcoder = {
|
||||
top.ICEcoder.dontSelect = true;
|
||||
},
|
||||
|
||||
// Set the current lastOpenedFiles in the settings file
|
||||
setLastOpenedFiles: function() {
|
||||
var lastOpenedFiles;
|
||||
// Set the current previousFiles in the settings file
|
||||
setPreviousFiles: function() {
|
||||
var previousFiles;
|
||||
|
||||
lastOpenedFiles = "";
|
||||
previousFiles = "";
|
||||
// Generate a comma seperated list
|
||||
for (var i=0;i<top.ICEcoder.openFiles.length;i++) {
|
||||
if (top.ICEcoder.openFiles[i]!="/[NEW]") {
|
||||
lastOpenedFiles += top.ICEcoder.openFiles[i].replace(/\//g,"|");
|
||||
if (i<top.ICEcoder.openFiles.length-1) {lastOpenedFiles += ","};
|
||||
if (top.ICEcoder.openFiles[i]!="" && top.ICEcoder.openFiles[i].indexOf("[NEW]")==-1) {
|
||||
previousFiles += top.ICEcoder.openFiles[i].replace(/\//g,"|");
|
||||
if (i<top.ICEcoder.openFiles.length-1) {previousFiles += ","};
|
||||
}
|
||||
}
|
||||
if (previousFiles=="") {previousFiles="CLEAR"};
|
||||
// Then send through to the settings page to update setting
|
||||
top.ICEcoder.serverQueue("add","lib/settings.php?saveFiles="+lastOpenedFiles);
|
||||
top.ICEcoder.serverQueue("add","lib/settings.php?saveFiles="+previousFiles);
|
||||
},
|
||||
|
||||
// Opens the last files we had open
|
||||
autoOpenFiles: function() {
|
||||
for (var i=0;i<=top.lastOpenFiles.length-1;i++) {
|
||||
top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.fullPath+top.lastOpenFiles[i].replace('|','/');
|
||||
for (var i=0;i<=top.previousFiles.length-1;i++) {
|
||||
top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.fullPath+top.previousFiles[i].replace('|','/');
|
||||
top.ICEcoder.thisFileFolderType='file';
|
||||
top.ICEcoder.openFile();
|
||||
}
|
||||
},
|
||||
|
||||
// Refresh file manager on demand
|
||||
refreshFileManager: function() {
|
||||
refreshFileManager: function(loginAttempt) {
|
||||
top.document.getElementById('loadingMask').style.visibility = "visible";
|
||||
top.ICEcoder.filesFrame.src="files.php";
|
||||
top.ICEcoder.filesFrame.style.opacity="0";
|
||||
top.ICEcoder.filesFrame.onload = function() {
|
||||
top.ICEcoder.filesFrame.style.opacity="1";
|
||||
top.document.getElementById('loadingMask').style.visibility = "hidden";
|
||||
if (loginAttempt) {
|
||||
if (loginAttempt == "loginOK") {
|
||||
if (top.ICEcoder.openFiles.length==0) {
|
||||
top.ICEcoder.content.style.visibility='visible';
|
||||
top.ICEcoder.content.src = "editor.php";
|
||||
}
|
||||
top.document.getElementById('accountLogin').style.top = "-50px";
|
||||
setTimeout(function() {top.document.getElementById('accountLoginContainer').style.display = "none";},300);
|
||||
} else {
|
||||
alert('Sorry, that\'s not correct.');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Show the settings screen
|
||||
settingsScreen: function(vis) {
|
||||
if (vis=="show") {
|
||||
top.document.getElementById('mediaContainer').innerHTML = '<iframe src="lib/settings-screen.php" class="whiteGlow" style="width: 970px; height: 600px"></iframe>';
|
||||
}
|
||||
top.ICEcoder.showHide(vis,top.document.getElementById('blackMask'));
|
||||
},
|
||||
|
||||
// Show the help screen
|
||||
helpScreen: function(vis) {
|
||||
if (vis=="show") {
|
||||
top.document.getElementById('mediaContainer').innerHTML = '<iframe src="lib/help.php" class="whiteGlow" style="width: 400px; height: 400px"></iframe>';
|
||||
}
|
||||
top.ICEcoder.showHide(vis,top.document.getElementById('blackMask'));
|
||||
},
|
||||
|
||||
// Update the settings used when we make a change to them
|
||||
useNewSettings: function(themeURL,tabsIndent,codeAssist,lockedNav,visibleTabs,refreshFM) {
|
||||
var styleNode, strCSS, cMCSS;
|
||||
|
||||
// Add new stylesheet for selected theme
|
||||
top.theme = themeURL.slice(themeURL.lastIndexOf("/")+1,themeURL.lastIndexOf("."));
|
||||
if (top.theme=="editor") {top.theme="icecoder"};
|
||||
styleNode = document.createElement('link');
|
||||
styleNode.setAttribute('rel', 'stylesheet');
|
||||
styleNode.setAttribute('type', 'text/css');
|
||||
styleNode.setAttribute('href', themeURL);
|
||||
top.ICEcoder.content.contentWindow.document.getElementsByTagName('head')[0].appendChild(styleNode);
|
||||
top.ICEcoder.switchTab(top.ICEcoder.selectedTab);
|
||||
|
||||
// Tabs indent setting
|
||||
top.tabsIndent = tabsIndent;
|
||||
|
||||
// Check/uncheck Code Assist setting
|
||||
top.document.getElementById('codeAssist').checked = codeAssist;
|
||||
|
||||
// Unlock/lock the file manager
|
||||
if (lockedNav != top.ICEcoder.lockedNav) {top.ICEcoder.lockUnlockNav()};
|
||||
if (!lockedNav) {
|
||||
ICEcoder.changeFilesW('contract');
|
||||
top.document.getElementById('fileMenu').style.display='none';
|
||||
}
|
||||
|
||||
// Show visible tabs or not
|
||||
document.all ? strCSS = 'rules' : strCSS = 'cssRules';
|
||||
cMCSS = ICEcoder.content.contentWindow.document;
|
||||
visibleTabs ? cMCSS.styleSheets[2][strCSS][5].style['content'] = '"\\21e5"' : cMCSS.styleSheets[2][strCSS][5].style['content'] = '" "';
|
||||
|
||||
// Finally, refresh the file manager if we need to
|
||||
if (refreshFM) {top.ICEcoder.refreshFileManager()};
|
||||
},
|
||||
|
||||
// Update and show/hide found results display?
|
||||
updateResultsDisplay: function(showHide) {
|
||||
ICEcoder.findReplace('find',true,false);
|
||||
document.getElementById('results').style.display = showHide == "show" ? 'inline-block' : 'none';
|
||||
},
|
||||
|
||||
// Show file & folder count in server info screen
|
||||
updateFileFolderCount: function() {
|
||||
var fileText, dirText, unitSize, unitText, dContainer;
|
||||
|
||||
top.ICEcoder.dirCount > 1 ? dirText = "folders" : dirText = "folder";
|
||||
top.ICEcoder.fileCount > 1 ? fileText = "files" : fileText = "file";
|
||||
// Change into kilobytes
|
||||
unitSize = Math.ceil(top.ICEcoder.fileBytes/1024);
|
||||
unitText = "kb";
|
||||
// Maybe we should show in megabytes?
|
||||
if (unitSize >= 1024) {
|
||||
unitSize = unitSize / 1024;
|
||||
unitText = "mb";
|
||||
}
|
||||
// Update the display
|
||||
dContainer = top.ICEcoder.content.contentWindow.document.getElementById('fileFolderCounts');
|
||||
if (dContainer) {
|
||||
dContainer.innerHTML = top.ICEcoder.fileCount+" "+fileText+", "+top.ICEcoder.dirCount+" "+dirText+"<br>~ "+unitSize+" "+unitText;
|
||||
}
|
||||
},
|
||||
|
||||
// Toggle full screen on/off
|
||||
fullScreenSwitcher: function() {
|
||||
var screenIcon;
|
||||
|
||||
screenIcon = top.document.getElementById('screenMode');
|
||||
|
||||
// Future use
|
||||
if ("undefined" != typeof document.cancelFullScreen) {
|
||||
document.fullScreen ? document.cancelFullScreen() : document.body.requestFullScreen();
|
||||
// Moz specific
|
||||
} else if ("undefined" != typeof document.mozCancelFullScreen) {
|
||||
document.mozFullScreen ? document.mozCancelFullScreen() : document.body.mozRequestFullScreen();
|
||||
// Chrome specific
|
||||
} else if ("undefined" != typeof document.webkitCancelFullScreen) {
|
||||
document.webkitIsFullScreen ? document.webkitCancelFullScreen() : document.body.webkitRequestFullScreen();
|
||||
}
|
||||
|
||||
screenIcon.src.indexOf("images/full-screen.gif") > -1 ? screenIcon.src = "images/restored-screen.gif" : screenIcon.src = "images/full-screen.gif";
|
||||
|
||||
}
|
||||
};
|
||||
24
lib/config.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
$versionNo = "v 0.7.2";
|
||||
$codeMirrorDir = "CodeMirror-2.25";
|
||||
$cMThisVer = 2.25;
|
||||
$tabsIndent = true;
|
||||
$testcMVersion = false;
|
||||
$openLastFiles = true;
|
||||
$findFilesExclude = array("_coder",".doc",".gif",".jpg",".jpeg",".pdf",".png",".swf",".xml",".zip");
|
||||
$codeAssist = true;
|
||||
$visibleTabs = false;
|
||||
$lockedNav = true;
|
||||
$accountPassword = "";
|
||||
$restrictedFiles = array("wp-",".php",".rb",".sql");
|
||||
$bannedFiles = array("_coder","wp-",".exe");
|
||||
$allowedIPs = array("*");
|
||||
$plugins = array(
|
||||
array("Database Admin","images/database.png","margin-top: 3px","plugins/adminer/adminer-3.3.3-mysql-en.php","_blank",""),
|
||||
array("Batch Image Processor","images/images.png","margin-top: 5px","http://birme.net","_blank",""),
|
||||
array("Backup","images/backup-open-files.png","margin-top: 3px","plugins/backupOpenFiles/index.php","fileControl:<b>Zipping Open Files</b>","10")
|
||||
);
|
||||
$theme = "default";
|
||||
$previousFiles = "";
|
||||
$last10Files = "";
|
||||
?>
|
||||
@@ -138,21 +138,52 @@ if ($_GET['action']=="save") {
|
||||
$saveFile = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']).$file;
|
||||
$saveFile = str_replace("//","/",$saveFile);
|
||||
if ((file_exists($saveFile) && is_writable($saveFile)) || $_POST['newFileName']!="") {
|
||||
$fh = fopen($saveFile, 'w') or die("can't open file");
|
||||
fwrite($fh, $_POST['contents']);
|
||||
fclose($fh);
|
||||
if (filemtime($saveFile)==$_GET['fileMDT']||!(isset($_GET['fileMDT']))) {
|
||||
$fh = fopen($saveFile, 'w') or die("Sorry, cannot save");
|
||||
fwrite($fh, $_POST['contents']);
|
||||
fclose($fh);
|
||||
clearstatcache();
|
||||
echo '<script>top.ICEcoder.openFileMDTs[top.ICEcoder.selectedTab-1]="'.filemtime($saveFile).'";</script>';
|
||||
|
||||
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
|
||||
// Reload file manager & stop CTRL+s being sticky
|
||||
$fileName = substr($file,strrpos($file,"/")+1);
|
||||
$fileLoc = substr($file,0,strrpos($file,"/"));
|
||||
if ($fileLoc=="") {$fileLoc = "/";};
|
||||
echo '<script>top.ICEcoder.selectedFiles=[];top.ICEcoder.updateFileManagerList(\'add\',\''.$fileLoc.'\',\''.$fileName.'\')</script>';
|
||||
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
|
||||
// Reload file manager & stop CTRL+s being sticky
|
||||
$fileName = substr($file,strrpos($file,"/")+1);
|
||||
$fileLoc = substr($file,0,strrpos($file,"/"));
|
||||
if ($fileLoc=="") {$fileLoc = "/";};
|
||||
echo '<script>top.ICEcoder.selectedFiles=[];top.ICEcoder.updateFileManagerList(\'add\',\''.$fileLoc.'\',\''.$fileName.'\')</script>';
|
||||
}
|
||||
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
|
||||
echo '<script>top.ICEcoder.renameTab(top.ICEcoder.selectedTab,\''.$file.'\');</script>';
|
||||
}
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);if (top.ICEcoder.stickyTabWindow.location) {top.ICEcoder.stickyTabWindow.location.reload()};action="doneSave";</script>';
|
||||
} else {
|
||||
$loadedFile = file_get_contents($saveFile);
|
||||
echo '<textarea name="loadedFile" id="loadedFile">'.str_replace("</textarea>","<ICEcoder:/:textarea>",$loadedFile).'</textarea>';
|
||||
echo '<textarea name="userVersionFile" id="userVersionFile"></textarea>';
|
||||
?>
|
||||
<script>
|
||||
var refreshFile = confirm('Sorry, this file has changed, cannot save\n<?php echo $file;?>\n\nReload this file and copy your version to a new document?');
|
||||
if (refreshFile) {
|
||||
var cM = top.ICEcoder.getcMInstance();
|
||||
var thisTab = top.ICEcoder.selectedTab;
|
||||
document.getElementById('userVersionFile').value = cM.getValue();
|
||||
// Revert back to original
|
||||
cM.setValue(document.getElementById('loadedFile').value);
|
||||
top.ICEcoder.changedContent[thisTab-1] = 0;
|
||||
top.ICEcoder.openFileMDTs[top.ICEcoder.selectedTab-1] = "<?php echo filemtime($saveFile); ?>";
|
||||
cM.clearHistory();
|
||||
// Now for the new file
|
||||
top.ICEcoder.newTab();
|
||||
cM = top.ICEcoder.getcMInstance();
|
||||
cM.setValue(document.getElementById('userVersionFile').value);
|
||||
cM.clearHistory();
|
||||
// Finally, switch back to original tab
|
||||
top.ICEcoder.switchTab(thisTab);
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="nothing";</script>';
|
||||
}
|
||||
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
|
||||
echo '<script>top.ICEcoder.renameTab(top.ICEcoder.selectedTab,\''.$file.'\');</script>';
|
||||
}
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="doneSave";</script>';
|
||||
} else {
|
||||
echo "<script>alert('Sorry, cannot write\\n".$file."');</script>";
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="nothing";</script>';
|
||||
@@ -193,19 +224,21 @@ if (action=="load") {
|
||||
top.ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab], null);
|
||||
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = top.ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(0, "cm-s-activeLine");
|
||||
top.ICEcoder.nextcMInstance++;
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
top.ICEcoder.openFileMDTs.push('<?php echo filemtime($file); ?>');
|
||||
top.ICEcoder.loadingFile = false;
|
||||
}
|
||||
|
||||
if (fileType=="image") {
|
||||
top.document.getElementById('blackMask').style.visibility = "visible";
|
||||
top.document.getElementById('mediaContainer').innerHTML = "<img src=\"<?php echo str_replace($docRoot,"",$file);?>\" style=\"border: solid 10px #ffffff; max-width: 700px; max-height: 500px\" onClick=\"return false\"><br><span style=\"border: solid 10px #ffffff; background-color: #ffffff\" onClick=\"return false\"><?php echo str_replace($docRoot,"",$file);?></span>";
|
||||
top.document.getElementById('mediaContainer').innerHTML = "<img src=\"<?php echo str_replace($docRoot,"",$file);?>\" class=\"whiteGlow\" style=\"border: solid 10px #fff; max-width: 700px; max-height: 500px\" onClick=\"return false\"><br><span class=\"whiteGlow\" style=\"border: solid 10px #fff; color: #000; background-color: #fff\" onClick=\"return false\"><?php echo str_replace($docRoot,"",$file);?></span>";
|
||||
}
|
||||
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<form name="saveFile" action="file-control.php?action=save&file=<?php if (isset($file)) {echo $file;};?>" method="POST">
|
||||
<form name="saveFile" action="file-control.php?action=save&file=<?php if (isset($file)) {echo $file;}; if (isset($_GET['fileMDT']) && $_GET['fileMDT']!="undefined") {echo "&fileMDT=".$_GET['fileMDT'];};?>" method="POST">
|
||||
<textarea name="contents"></textarea>
|
||||
<input type="hidden" name="newFileName" value="">
|
||||
</form>
|
||||
@@ -230,7 +263,7 @@ if (action=="save") {
|
||||
if ("undefined" != typeof newFileName) {
|
||||
top.ICEcoder.serverMessage('<b>Saving</b><br>'+newFileName);
|
||||
}
|
||||
document.saveFile.contents.innerHTML = top.document.getElementById('saveTemp1').value;
|
||||
document.saveFile.contents.value = top.document.getElementById('saveTemp1').value;
|
||||
document.saveFile.submit();
|
||||
} else {
|
||||
top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);
|
||||
|
||||
112
lib/files.css
@@ -9,92 +9,62 @@ dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
font-family: arial, verdana, helvetica, sans-serif;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
outline: 0px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
body {margin: 0px; overflow: auto}
|
||||
body {margin: 0; overflow: auto}
|
||||
|
||||
.refresh {float: right; margin-right: 15px; cursor: pointer}
|
||||
|
||||
.fileManager {
|
||||
margin: 15px 0px 15px 22px;
|
||||
margin: 15px 0 15px 22px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fileManager span {font-family: helvetica, arial, swiss, verdana;}
|
||||
.fileManager a {color: #000000; text-decoration: none;}
|
||||
.fileManager .open {font-style: italic;}
|
||||
.fileManager .closed {font-style: normal;}
|
||||
.fileManager .pft-directory {list-style-image: url(../images/file-manager-icons/directory.png);}
|
||||
.fileManager li {margin-left: 15px;}
|
||||
.fileManager span {font-family: helvetica, arial, swiss, verdana}
|
||||
.fileManager a {color: #eee; text-decoration: none}
|
||||
.fileManager .open {font-style: italic}
|
||||
.fileManager .closed {font-style: normal}
|
||||
.fileManager .pft-directory, .fileManager .pft-file {list-style-image: url(../images/blank.gif)}
|
||||
.fileManager li {margin-left: 15px}
|
||||
|
||||
/* Default file */
|
||||
.fileManager LI.pft-file { list-style-image: url(../images/file-manager-icons/file.png); }
|
||||
.fileManager LI.pft-directory:before, .fileManager LI.pft-file:before {
|
||||
position: absolute; display: block; width: 16px; height: 16px; content: ""; margin-top: -2px; margin-left: -23px; background:url(../images/file-manager-icons.png) no-repeat 0 0;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) { /* hacked for chrome and safari */
|
||||
.fileManager LI.pft-directory:before, .fileManager LI.pft-file:before {
|
||||
margin-top: -19px;
|
||||
}
|
||||
}
|
||||
.fileManager LI.pft-file:before {background-position: -16px 0}
|
||||
|
||||
/* Additional file types */
|
||||
.fileManager LI.ext-3gp { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-afp { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-afpa { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-asp { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-aspx { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-avi { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-bat { list-style-image: url(../images/file-manager-icons/application.png); }
|
||||
.fileManager LI.ext-bmp { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-c { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-cfm { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-cgi { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-com { list-style-image: url(../images/file-manager-icons/application.png); }
|
||||
.fileManager LI.ext-cpp { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-css { list-style-image: url(../images/file-manager-icons/css.png); }
|
||||
.fileManager LI.ext-doc { list-style-image: url(../images/file-manager-icons/doc.png); }
|
||||
.fileManager LI.ext-exe { list-style-image: url(../images/file-manager-icons/application.png); }
|
||||
.fileManager LI.ext-gif { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-fla { list-style-image: url(../images/file-manager-icons/flash.png); }
|
||||
.fileManager LI.ext-h { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-htm { list-style-image: url(../images/file-manager-icons/html.png); }
|
||||
.fileManager LI.ext-html { list-style-image: url(../images/file-manager-icons/html.png); }
|
||||
.fileManager LI.ext-jar { list-style-image: url(../images/file-manager-icons/java.png); }
|
||||
.fileManager LI.ext-jpg { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-jpeg { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-js { list-style-image: url(../images/file-manager-icons/script.png); }
|
||||
.fileManager LI.ext-lasso { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-log { list-style-image: url(../images/file-manager-icons/txt.png); }
|
||||
.fileManager LI.ext-m4p { list-style-image: url(../images/file-manager-icons/music.png); }
|
||||
.fileManager LI.ext-mov { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-mp3 { list-style-image: url(../images/file-manager-icons/music.png); }
|
||||
.fileManager LI.ext-mp4 { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-mpg { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-mpeg { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-ogg { list-style-image: url(../images/file-manager-icons/music.png); }
|
||||
.fileManager LI.ext-pcx { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-pdf { list-style-image: url(../images/file-manager-icons/pdf.png); }
|
||||
.fileManager LI.ext-php { list-style-image: url(../images/file-manager-icons/php.png); }
|
||||
.fileManager LI.ext-png { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-ppt { list-style-image: url(../images/file-manager-icons/ppt.png); }
|
||||
.fileManager LI.ext-psd { list-style-image: url(../images/file-manager-icons/psd.png); }
|
||||
.fileManager LI.ext-pl { list-style-image: url(../images/file-manager-icons/script.png); }
|
||||
.fileManager LI.ext-py { list-style-image: url(../images/file-manager-icons/script.png); }
|
||||
.fileManager LI.ext-rb { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-rbx { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-rhtml { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-rpm { list-style-image: url(../images/file-manager-icons/linux.png); }
|
||||
.fileManager LI.ext-ruby { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-sql { list-style-image: url(../images/file-manager-icons/db.png); }
|
||||
.fileManager LI.ext-swf { list-style-image: url(../images/file-manager-icons/flash.png); }
|
||||
.fileManager LI.ext-tif { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-tiff { list-style-image: url(../images/file-manager-icons/picture.png); }
|
||||
.fileManager LI.ext-txt { list-style-image: url(../images/file-manager-icons/txt.png); }
|
||||
.fileManager LI.ext-vb { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-wav { list-style-image: url(../images/file-manager-icons/music.png); }
|
||||
.fileManager LI.ext-wmv { list-style-image: url(../images/file-manager-icons/film.png); }
|
||||
.fileManager LI.ext-xls { list-style-image: url(../images/file-manager-icons/xls.png); }
|
||||
.fileManager LI.ext-xml { list-style-image: url(../images/file-manager-icons/code.png); }
|
||||
.fileManager LI.ext-zip { list-style-image: url(../images/file-manager-icons/zip.png); }
|
||||
.fileManager LI.ext-coffee:before {background-position: -32px 0}
|
||||
.fileManager LI.ext-css:before {background-position: -48px 0}
|
||||
.fileManager LI.ext-gif:before {background-position: -64px 0}
|
||||
.fileManager LI.ext-htm:before {background-position: -80px 0}
|
||||
.fileManager LI.ext-html:before {background-position: -80px 0}
|
||||
.fileManager LI.ext-jpg:before {background-position: -96px 0}
|
||||
.fileManager LI.ext-jpeg:before {background-position: -96px 0}
|
||||
.fileManager LI.ext-js:before {background-position: -112px 0}
|
||||
/*.fileManager LI.ext-pdf:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-php:before {background-position: -128px 0}
|
||||
.fileManager LI.ext-png:before {background-position: -144px 0}
|
||||
.fileManager LI.ext-rb:before {background-position: -160px 0}
|
||||
.fileManager LI.ext-rbx:before {background-position: -160px 0}
|
||||
.fileManager LI.ext-rhtml:before {background-position: -160px 0}
|
||||
.fileManager LI.ext-ruby:before {background-position: -160px 0}
|
||||
/*.fileManager LI.ext-sql:before {background-position: -???px 0} */
|
||||
/*.fileManager LI.ext-swf:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-txt:before {background-position: -176px 0}
|
||||
/*.fileManager LI.ext-xml:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-zip:before {background-position: -192px 0}
|
||||
31
lib/help.css
Normal file
@@ -0,0 +1,31 @@
|
||||
/* First, reset everything to a standard */
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
body {overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
h1 {font-size: 36px; font-weight: normal; color: #888; margin-bottom: 20px}
|
||||
|
||||
.help {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #fff; padding: 20px}
|
||||
.help .key {display: inline-block; width: 175px; text-align: right; margin-right: 5px; float: left}
|
||||
.help .key .plus {color: #888}
|
||||
.help .shortcut {display: inline-block; width: 175px; color: #888; margin-left: 5px; float: left}
|
||||
38
lib/help.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php include("settings.php");?>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>ICE Coder - <?php echo $versionNo;?> :: Help & Shortcuts</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="help.css">
|
||||
</head>
|
||||
|
||||
<body class="help">
|
||||
|
||||
<h1 id="title">help</h1>
|
||||
|
||||
<h2>In file manager</h2>
|
||||
<span class="key">Delete</span> <span class="shortcut">Delete file</span><br><br>
|
||||
|
||||
<h2>Within document</h2>
|
||||
<span class="key">CTRL <span class="plus">+</span> I</span> <span class="shortcut">Search selected text</span><br>
|
||||
<span class="key">Esc</span> <span class="shortcut">Comment / uncomment text</span><br>
|
||||
<span class="key">Tab</span> <span class="shortcut">Insert tab / indent selected text</span><br><br>
|
||||
|
||||
<h2>Anywhere</h2>
|
||||
<span class="key">CTRL <span class="plus">+</span> F</span> <span class="shortcut">Find</span><br>
|
||||
<span class="key">CTRL <span class="plus">+</span> G</span> <span class="shortcut">Go to line</span><br>
|
||||
<span class="key">CTRL <span class="plus">+</span> S</span> <span class="shortcut">Save</span><br>
|
||||
<span class="key">CTRL <span class="plus">+</span> Shift <span class="plus">+</span> S</span> <span class="shortcut">Save as...</span><br>
|
||||
<span class="key">CTRL <span class="plus">+</span> Enter</span> <span class="shortcut">View webpage</span><br>
|
||||
<span class="key">CTRL <span class="plus">+</span> S <span class="plus">+</span> Enter</span> <span class="shortcut">Save & create sticky tab</span><br>
|
||||
<span class="key">Esc</span> <span class="shortcut">Cancel tasks</span><br><br>
|
||||
|
||||
<h2>Clicking logo</h2>
|
||||
<span class="key">Left click</span> <span class="shortcut">Help</span><br>
|
||||
<span class="key">Right click</span> <span class="shortcut">Settings</span><br>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
35
lib/multiple-results.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/* First, reset everything to a standard */
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
body {overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
h1 {font-size: 36px; font-weight: normal; color: #888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #fff}
|
||||
hr {border: 0; height: 1px; background-color: #888}
|
||||
|
||||
.results {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #fff}
|
||||
.results .resultsPane {position: relative; width: 660px; height: 560px; font-size: 10px; padding: 20px; float: left}
|
||||
.results .resultsPane a {color: rgba(0,198,255,0.7); text-decoration: none}
|
||||
.results .resultsPane a:hover {text-decoration: underline}
|
||||
.replace {position: absolute; margin-top: -28px; right: 20px; padding: 5px 10px; font-size: 14px; background-color: rgba(0,198,255,0.7); cursor: pointer}
|
||||
.replaceAll {position: absolute; bottom: 0; right: 20px; padding: 5px 10px; font-size: 18px; background-color: rgba(0,198,255,0.7); cursor: pointer}
|
||||
75
lib/multiple-results.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php include("settings.php");?>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>ICE Coder - <?php echo $versionNo;?> :: Multiple Results Screen</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="multiple-results.css">
|
||||
</head>
|
||||
|
||||
<body class="results">
|
||||
|
||||
<div class="resultsPane">
|
||||
<h1 id="title"></h1>
|
||||
<div id="results"></div>
|
||||
</div>
|
||||
<?php if (isset($_GET['replace'])) { ?>
|
||||
<div class="replaceAll" id="replaceAll" onClick="replaceAll()" style="opacity: 0.1">replace all</div>
|
||||
<?php ;}; ?>
|
||||
|
||||
<script>
|
||||
var resultsDisplay = "";
|
||||
var foundTabArray = [];
|
||||
var startTab = top.ICEcoder.selectedTab;
|
||||
var rExp = new RegExp("<?php echo $_GET['find']; ?>","g");
|
||||
for (var i=1;i<=top.ICEcoder.openFiles.length;i++) {
|
||||
top.ICEcoder.switchTab(i);
|
||||
var cM = top.ICEcoder.getcMInstance();
|
||||
var content = cM.getValue();
|
||||
if (content.match(rExp)) {
|
||||
resultsDisplay += '<a href="javascript:gotoTab('+i+')">'+ top.ICEcoder.openFiles[i-1]+ '</a><br><div id="foundCount'+i+'">Found '+content.match(rExp).length+' times</div>';
|
||||
<?php if (isset($_GET['replace'])) { ?>
|
||||
resultsDisplay += '<div class="replace" id="replace" onClick="replaceSingle('+i+');this.style.display=\'none\'">replace</div>';
|
||||
<?php ;}; ?>
|
||||
resultsDisplay += '<hr>';
|
||||
foundTabArray.push(i);
|
||||
}
|
||||
}
|
||||
if (startTab!=top.ICEcoder.selectedTab) {
|
||||
top.ICEcoder.switchTab(startTab);
|
||||
}
|
||||
foundTabArray.length==0 ? showHide = "hide" : showHide = "show";
|
||||
top.ICEcoder.showHide(showHide,top.document.getElementById('blackMask'));
|
||||
if (foundTabArray.length==0) {alert('No matches found')};
|
||||
<?php if (isset($_GET['replace'])) { ?>
|
||||
if (foundTabArray.length!=0) {document.getElementById('replaceAll').style.opacity = 1};
|
||||
<?php ;}; ?>
|
||||
foundTabArray.length >= 2 ? plural = "s" : plural = "";
|
||||
document.getElementById('title').innerHTML = "'<?php echo $_GET['find']; ?>' found in "+foundTabArray.length+" file"+plural;
|
||||
document.getElementById('results').innerHTML = resultsDisplay;
|
||||
|
||||
var gotoTab = function(tab) {
|
||||
top.ICEcoder.switchTab(tab);
|
||||
top.ICEcoder.showHide('hide',top.document.getElementById('blackMask'));
|
||||
}
|
||||
|
||||
var replaceSingle = function(tab) {
|
||||
top.ICEcoder.switchTab(tab);
|
||||
cM = top.ICEcoder.getcMInstance();
|
||||
content = cM.getValue();
|
||||
cM.setValue(cM.getValue().replace(rExp,top.document.getElementById('replace').value));
|
||||
document.getElementById('foundCount'+tab).innerHTML = document.getElementById('foundCount'+tab).innerHTML.replace('Found','Replaced');
|
||||
}
|
||||
|
||||
var replaceAll = function() {
|
||||
for (var i=0;i<=foundTabArray.length-1;i++) {
|
||||
replaceSingle(foundTabArray[i]);
|
||||
}
|
||||
top.ICEcoder.showHide('hide',top.document.getElementById('blackMask'));
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
45
lib/settings-screen.css
Normal file
@@ -0,0 +1,45 @@
|
||||
/* First, reset everything to a standard */
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
body {overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select:none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
h1 {font-size: 36px; font-weight: normal; color: #888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #fff}
|
||||
|
||||
.settings {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #fff}
|
||||
.settings .infoPane {position: relative; width: 230px; height: 560px; font-size: 10px; color: #bbb; background-color: #fff; padding: 20px; float: left}
|
||||
.settings .infoPane a {color: #888; text-decoration: none}
|
||||
.settings .infoPane a:hover {text-decoration: underline}
|
||||
.settings .logo {position: relative; margin-top: 2px}
|
||||
.settings .version {position: relative; display: block; margin-top: 5px; margin-bottom: 10px; font-size: 10px; color: #bbb}
|
||||
.settings .settingsColumn1 {width: 220px; height: 560px; padding: 20px; float: left}
|
||||
.settings .settingsColumn2 {width: 420px; height: 560px; padding: 20px 20px 20px 0; float: left}
|
||||
.settings input, .settings textarea {border: 1px solid #555; background-color: #444; color: #fff}
|
||||
.settings input:focus, .settings textarea:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
-moz-box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
box-shadow: 0 0 10px 1px rgba(0,198,255,0.7);
|
||||
}
|
||||
.settings .plugins {font-family: arial, verdana, helvetica, sans-serif; width: 410px; height: 123px; overflow: hidden}
|
||||
.settings .update {position: absolute; bottom: 0; right: 20px; padding: 5px 10px; font-size: 18px; background-color: rgba(0,198,255,0.7); opacity: 0.1; cursor: pointer}
|
||||
208
lib/settings-screen.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php include("settings.php");?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>ICE Coder - <?php echo $versionNo;?> :: Settings Screen</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="settings-screen.css">
|
||||
<link rel="stylesheet" href="../<?php echo $codeMirrorDir; ?>/lib/codemirror.css">
|
||||
<script src="../<?php echo $codeMirrorDir; ?>/lib/codemirror.js"></script>
|
||||
<script src="../<?php echo $codeMirrorDir; ?>/mode/javascript/javascript.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
.CodeMirror {position: absolute; width: 0; background-color: #fff; font-family: monospace}
|
||||
.CodeMirror-scroll {height: 220px; width: 420px; overflow: hidden}
|
||||
.cm-s-visible {display: block; top: 0}
|
||||
.cm-s-hidden {display: none; top: 4000px}
|
||||
.cm-s-activeLine {background: #002 !important;}
|
||||
// Make sure this next one remains the 5th item, updated with JS
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if($visibleTabs) {echo '\21e5';};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000; background: #555; !important}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="editor.css">
|
||||
<?php
|
||||
$themeArray = array("ambiance","blackboard","cobalt","eclipse","elegant","erlang-dark","lesser-dark","monokai","neat","night","rubyblue","xq-dark");
|
||||
for ($i=0;$i<count($themeArray)-1;$i++) {
|
||||
echo '<link rel="stylesheet" href="../'.$codeMirrorDir.'/theme/'.$themeArray[$i].'.css">'.PHP_EOL;
|
||||
}
|
||||
?>
|
||||
</head>
|
||||
|
||||
<body class="settings">
|
||||
|
||||
<div class="infoPane">
|
||||
<img src="../images/ice-coder.gif" class="logo">
|
||||
<div class="version"><?php echo $versionNo;?></div>
|
||||
|
||||
<p>
|
||||
git:<br>
|
||||
<a href="http://github.com/mattpass/ICEcoder" target="_blank">http://github.com/mattpass/ICEcoder</a>
|
||||
<br><br>
|
||||
|
||||
codemirror dir:<br>
|
||||
<?php echo $codeMirrorDir; ?>
|
||||
<br><br>
|
||||
|
||||
codemirror version:<br>
|
||||
<?php echo $cMThisVer; ?>
|
||||
<br><br>
|
||||
|
||||
doc root:<br>
|
||||
<?php if($_SESSION['userLevel']==10) { echo $_SERVER['DOCUMENT_ROOT']; } else { echo '[HIDDEN]'; }; ?>
|
||||
<br><br><br><br>
|
||||
|
||||
<div style="font-size: 10px; line-height: 12px">ICE coder by Matt Pass (<a href="http://www.twitter.com/mattpass" style="font-size: 10px" target="_blank">@mattpass</a>)<br><br>
|
||||
Free to use it for your own purposes, commercial or not, just let me know of any cool uses or customisations. :)<br><br>
|
||||
No warranty or liability accepted for anything, all responsibility of use is your own.<br><br>
|
||||
|
||||
Thanks go to the following people who have inspired me to create this and in the odd case, provided feedback or code:<br>
|
||||
<?php
|
||||
$peopleArray = array("marijnjh", "maettig", "wimtibackx", "jakubvrana", "davidwalshblog", "kuvos", "paul_irish", "mathias", "rem");
|
||||
for ($i=0;$i<count($peopleArray)-1;$i++) {
|
||||
echo '<a href="http://www.twitter.com/'.$peopleArray[$i].'" style="font-size: 10px" target="_blank">@'.$peopleArray[$i].'</a>';
|
||||
if ($i<count($peopleArray)-2) {
|
||||
echo ", ";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form name="settings" action="settings.php" method="POST">
|
||||
<div class="settingsColumn1">
|
||||
<h1>settings</h1>
|
||||
<h2>functionality</h2>
|
||||
<input type="checkbox" onclick="showButton()" name="tabsIndent" value="true"<?php if($tabsIndent) {echo ' checked';};?>> tab indents selection<br>
|
||||
<input type="checkbox" onclick="showButton()" name="testcMVersion" value="true"<?php if($testcMVersion) {echo ' checked';};?>> test codemirror version on load<br>
|
||||
<input type="checkbox" onclick="showButton()" name="openLastFiles" value="true"<?php if($openLastFiles) {echo ' checked';};?>> auto open last files on login<br>
|
||||
<br>
|
||||
when finding in files, exclude:<br>
|
||||
<input type="text" onkeydown="showButton()" name="findFilesExclude" value="<?php for($i=0;$i<=count($findFilesExclude)-1;$i++) {echo $findFilesExclude[$i]; if ($i<count($findFilesExclude)-1) {echo ', ';};}; ?>"><br>
|
||||
<br>
|
||||
|
||||
<h2>assisting</h2>
|
||||
<input type="checkbox" onclick="showButton()" name="codeAssist" value="true"<?php if($codeAssist) {echo ' checked';};?>> code assist<br>
|
||||
<input type="checkbox" onclick="showButton();showHideTabs()" name="visibleTabs" value="true"<?php if($visibleTabs) {echo ' checked';};?>> visible tabs<br>
|
||||
<input type="checkbox" onclick="showButton()" name="lockedNav" value="true"<?php if($lockedNav) {echo ' checked';};?>> locked nav<br>
|
||||
<br>
|
||||
|
||||
<h2>security</h2>
|
||||
new password <span style="font-size: 10px; color: #888">8 chars</span><br>
|
||||
<input type="password" name="accountPassword" onkeydown="showButton()"><br>
|
||||
confirm password<br>
|
||||
<input type="password" name="confirmPassword" onkeydown="showButton()"><br>
|
||||
<input type="hidden" name="oldPassword" value="<?php echo $accountPassword; ?>">
|
||||
<br>
|
||||
restricted files/folders<br>
|
||||
<input type="text" onkeydown="document.settings.changedFileSettings.value='true';showButton()" name="restrictedFiles" value="<?php for($i=0;$i<=count($restrictedFiles)-1;$i++) {echo $restrictedFiles[$i]; if ($i<count($restrictedFiles)-1) {echo ', ';};}; ?>"><br>
|
||||
banned files/folders<br>
|
||||
<input type="text" onkeydown="document.settings.changedFileSettings.value='true';showButton()" name="bannedFiles" value="<?php for($i=0;$i<=count($bannedFiles)-1;$i++) {echo $bannedFiles[$i]; if ($i<count($bannedFiles)-1) {echo ', ';};}; ?>"><br>
|
||||
<input type="hidden" name="changedFileSettings" value="false">
|
||||
<br>
|
||||
ip addresses<br>
|
||||
<input type="text" onkeydown="showButton()" name="allowedIPs" value="<?php for($i=0;$i<=count($allowedIPs)-1;$i++) {echo $allowedIPs[$i]; if ($i<count($allowedIPs)-1) {echo ', ';};}; ?>"><br>
|
||||
</div>
|
||||
|
||||
<div class="settingsColumn2">
|
||||
<h2>plugins</h2>
|
||||
plugins array <span style="font-size: 10px; color: #888">name, img src, style, url, target, setInterval (mins)</span><br>
|
||||
<textarea name="plugins" class="plugins" onkeydown="showButton()"><?php
|
||||
for($i=0;$i<count($plugins);$i++) {
|
||||
for($j=0;$j<count($plugins[$i]);$j++) {
|
||||
echo '"'.$plugins[$i][$j].'"';
|
||||
if ($j<count($plugins[$i])-1) {
|
||||
echo ',';
|
||||
};
|
||||
if (!($i==count($plugins)-1 && $j==count($plugins[$i])-1)) {
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if (($i<count($plugins)-1 && $j==count($plugins[$i])-1)) {
|
||||
echo "====================".PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
?></textarea>
|
||||
<br><br>
|
||||
|
||||
<h2>style</h2>
|
||||
theme<br>
|
||||
<select onchange="selectTheme();showButton()" id="select" name="theme">
|
||||
<option<?php if ($theme=="default") {echo ' selected';}; ?>>default</option>
|
||||
<?php
|
||||
for ($i=0;$i<count($themeArray)-1;$i++) {
|
||||
if ($theme==$themeArray[$i]) {$optionSelected = ' selected';} else {$optionSelected = '';};
|
||||
echo '<option'.$optionSelected.'>'.$themeArray[$i].'</option>'.PHP_EOL;
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<textarea id="code" name="code">
|
||||
function findSequence(goal) {
|
||||
function find(start,history) {
|
||||
if (start==goal)
|
||||
return history;
|
||||
else if (start>goal)
|
||||
return null;
|
||||
else
|
||||
return find(start+5,"("+history+"+5)") ||
|
||||
find(start*3,"("+history+"*3)");
|
||||
}
|
||||
return find(1,"1");
|
||||
}</textarea>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
readOnly: "nocursor",
|
||||
theme: "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;}; ?>"
|
||||
});
|
||||
|
||||
var input = document.getElementById("select");
|
||||
function selectTheme() {
|
||||
var theme = input.options[input.selectedIndex].innerHTML;
|
||||
if (theme=="default") {theme = "icecoder"};
|
||||
editor.setOption("theme", theme);
|
||||
}
|
||||
|
||||
var showButton = function() {
|
||||
document.getElementById('updateButton').style.opacity = 1;
|
||||
}
|
||||
|
||||
var showHideTabs = function() {
|
||||
document.all ? strCSS = 'rules' : strCSS = 'cssRules';
|
||||
document.settings.visibleTabs.checked ? document.styleSheets[2][strCSS][5].style['content'] = '"\\21e5"' : document.styleSheets[2][strCSS][5].style['content'] = '" "';
|
||||
}
|
||||
|
||||
var validatePasswords = function() {
|
||||
<?php if($_SESSION['userLevel']==10) { ?>
|
||||
if (document.settings.accountPassword.value != 0 && document.settings.accountPassword.value.length<8) {
|
||||
alert('Please use at least 8 chars in the password');
|
||||
} else {
|
||||
if (document.settings.accountPassword.value != document.settings.confirmPassword.value) {
|
||||
alert('Sorry, your passwords don\'t match')
|
||||
} else {
|
||||
document.settings.submit();
|
||||
}
|
||||
}
|
||||
<?php } else { ?>
|
||||
alert('Sorry, you need to be logged in to change settings');
|
||||
<?php ;}; ?>
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="update" id="updateButton" onClick="validatePasswords()">update</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||