mirror of
https://github.com/icecoder/ICEcoder.git
synced 2026-03-16 05:17:01 +01:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2bf52e5a3 | ||
|
|
f39b8e2a35 | ||
|
|
8c97be00dc | ||
|
|
83085c4c1f | ||
|
|
8adec9a48b | ||
|
|
c177374d23 | ||
|
|
334ced8627 | ||
|
|
d8229d79a5 | ||
|
|
c8665584e9 | ||
|
|
c56af14f52 | ||
|
|
ed8fb0dd67 | ||
|
|
f906b41cd2 | ||
|
|
1491e24039 | ||
|
|
30dbad53a7 | ||
|
|
b129bc39cb | ||
|
|
5ffba58802 | ||
|
|
3cd5b99edd | ||
|
|
89b1b51097 | ||
|
|
6b5c95fc3a |
@@ -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,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
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
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*/}
|
||||
auto: "emacs", nofallthrough: true
|
||||
};
|
||||
})();
|
||||
230
CodeMirror-2.24/keymap/vim.js
Normal file
230
CodeMirror-2.24/keymap/vim.js
Normal file
@@ -0,0 +1,230 @@
|
||||
(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);
|
||||
}
|
||||
function goLineStartText(cm) {
|
||||
// Go to the start of the line where the text begins, or the end for whitespace-only lines
|
||||
var cur = cm.getCursor(), firstNonWS = cm.getLine(cur.line).search(/\S/);
|
||||
cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
|
||||
}
|
||||
|
||||
var map = CodeMirror.keyMap.vim = {
|
||||
"0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
|
||||
// Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
|
||||
"'|'": function(cm) {cm.setCursor(cm.getCursor().line, popCount() - 1, true);},
|
||||
"'^'": function(cm) {popCount(); goLineStartText(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(); goLineStartText(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); CodeMirror.commands.newlineAndIndent(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
|
||||
"Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.indentLine(cm.getCursor().line); 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();},
|
||||
"Shift-D": function(cm) {
|
||||
emptyBuffer();
|
||||
mark["Shift-D"] = cm.getCursor(false).line;
|
||||
cm.setCursor(cm.getCursor(true).line);
|
||||
delTillMark(cm,"Shift-D"); mark = [];
|
||||
},
|
||||
"M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
|
||||
"Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
|
||||
"Shift-Y": function(cm) {
|
||||
emptyBuffer();
|
||||
mark["Shift-D"] = cm.getCursor(false).line;
|
||||
cm.setCursor(cm.getCursor(true).line);
|
||||
yankTillMark(cm,"Shift-D"); mark = [];
|
||||
},
|
||||
"/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
|
||||
"'?'": 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);},
|
||||
nofallthrough: true
|
||||
};
|
||||
// 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)},
|
||||
"'~'": 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", "'$'": "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",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-m"] = {
|
||||
auto: "vim",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
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",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-d'"] = {
|
||||
auto: "vim",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-prefix-y'"] = {
|
||||
auto: "vim",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
// iterate through uppercase alphabet char codes
|
||||
for (var i = 65; i < 65 + 26; i++) {
|
||||
// apply for `letter` and 'Shift-' + `letter`
|
||||
for (var m = String.fromCharCode(i); m.length < 8; m = "Shift-" + m) {
|
||||
CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
|
||||
mark[m] = cm.getCursor().line;
|
||||
};
|
||||
CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
|
||||
delTillMark(cm,m);
|
||||
};
|
||||
CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
|
||||
yankTillMark(cm,m);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
nofallthrough: true
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["vim-insert"] = {
|
||||
// TODO: override navigation keys so that Esc will cancel automatic indentation from o, O, i_<CR>
|
||||
"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"]
|
||||
};
|
||||
})();
|
||||
@@ -42,11 +42,13 @@
|
||||
padding: 0; margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
.CodeMirror-wrap .CodeMirror-scroll {
|
||||
overflow-x: hidden;
|
||||
@@ -1,5 +1,3 @@
|
||||
// CodeMirror version 2.23
|
||||
//
|
||||
// All functions that need access to the editor's state live inside
|
||||
// the CodeMirror function. Below that, at the bottom of the file,
|
||||
// some utilities are defined.
|
||||
@@ -41,7 +39,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;
|
||||
@@ -98,7 +96,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 +115,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 +164,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 +317,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 +342,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");
|
||||
@@ -385,20 +391,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 +455,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 +465,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 +481,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 +540,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;
|
||||
}
|
||||
|
||||
@@ -648,7 +667,7 @@ var CodeMirror = (function() {
|
||||
if (suppressEdits) return;
|
||||
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
||||
if (!options.lineWrapping)
|
||||
doc.iter(from.line, to.line, function(line) {
|
||||
doc.iter(from.line, to.line + 1, function(line) {
|
||||
if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
|
||||
});
|
||||
if (from.line != to.line || newText.length > 1) gutterDirty = true;
|
||||
@@ -696,14 +715,14 @@ 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) {
|
||||
maxLine = l; maxLineLength = l.length; maxWidth = null;
|
||||
@@ -874,8 +893,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 +910,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 +944,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 +1128,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 +1211,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 +1378,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() {
|
||||
@@ -1506,8 +1534,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 +1557,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 +1811,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;
|
||||
@@ -1856,6 +1881,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 +1907,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 +1938,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 +1958,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 +2016,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 +2037,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 +2072,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 +2442,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 +2472,50 @@ 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);
|
||||
span_(text.slice(wrapAt - outPos), style);
|
||||
html.push("</span>");
|
||||
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 +2601,11 @@ var CodeMirror = (function() {
|
||||
},
|
||||
insertHeight: function(at, lines, height) {
|
||||
this.height += height;
|
||||
this.lines.splice.apply(this.lines, [at, 0].concat(lines));
|
||||
// The trick below is apparently too advanced for IE, which
|
||||
// occasionally corrupts this.lines (duplicating elements) when
|
||||
// it is used.
|
||||
if (ie) this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
|
||||
else this.lines.splice.apply(this.lines, [at, 0].concat(lines));
|
||||
for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
|
||||
},
|
||||
iterN: function(at, n, op) {
|
||||
@@ -2701,33 +2771,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 +2862,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 +2877,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.
|
||||
@@ -2969,4 +3056,4 @@ var CodeMirror = (function() {
|
||||
})();
|
||||
|
||||
return CodeMirror;
|
||||
})();
|
||||
})();
|
||||
@@ -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) {
|
||||
50
CodeMirror-2.24/lib/util/loadmode.js
Normal file
50
CodeMirror-2.24/lib/util/loadmode.js
Normal file
@@ -0,0 +1,50 @@
|
||||
(function() {
|
||||
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
|
||||
|
||||
var loading = {};
|
||||
function splitCallback(cont, n) {
|
||||
var countDown = n;
|
||||
return function() { if (--countDown == 0) cont(); }
|
||||
}
|
||||
function ensureDeps(mode, cont) {
|
||||
var deps = CodeMirror.modes[mode].dependencies;
|
||||
if (!deps) return cont();
|
||||
var missing = [];
|
||||
for (var i = 0; i < deps.length; ++i) {
|
||||
if (!CodeMirror.modes.hasOwnProperty(deps[i]))
|
||||
missing.push(deps[i]);
|
||||
}
|
||||
if (!missing.length) return cont();
|
||||
var split = splitCallback(cont, missing.length);
|
||||
for (var i = 0; i < missing.length; ++i)
|
||||
CodeMirror.requireMode(missing[i], split);
|
||||
}
|
||||
|
||||
CodeMirror.requireMode = function(mode, cont) {
|
||||
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont());
|
||||
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
|
||||
|
||||
var script = document.createElement("script");
|
||||
script.src = CodeMirror.modeURL.replace(/%N/g, mode);
|
||||
var others = document.getElementsByTagName("script")[0];
|
||||
others.parentNode.insertBefore(script, others);
|
||||
var list = loading[mode] = [cont];
|
||||
var count = 0, poll = setInterval(function() {
|
||||
if (++count > 100) return clearInterval(poll);
|
||||
if (CodeMirror.modes.hasOwnProperty(mode)) {
|
||||
clearInterval(poll);
|
||||
loading[mode] = null;
|
||||
ensureDeps(mode, function() {
|
||||
for (var i = 0; i < list.length; ++i) list[i]();
|
||||
});
|
||||
}
|
||||
}, 200);
|
||||
};
|
||||
|
||||
CodeMirror.autoLoadMode = function(instance, mode) {
|
||||
if (!CodeMirror.modes.hasOwnProperty(mode))
|
||||
CodeMirror.requireMode(mode, function() {
|
||||
instance.setOption("mode", instance.getOption("mode"));
|
||||
});
|
||||
};
|
||||
}());
|
||||
@@ -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() {
|
||||
@@ -43,7 +43,7 @@ CodeMirror.overlayParser = function(base, overlay, combine) {
|
||||
else return state.overlayCur;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
indent: base.indent && function(state, textAfter) {
|
||||
return base.indent(state.base, textAfter);
|
||||
},
|
||||
electricChars: base.electricChars
|
||||
@@ -72,14 +72,14 @@
|
||||
query = parseQuery(query);
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
|
||||
if (all) {
|
||||
cm.operation(function() {
|
||||
cm.compoundChange(function() { 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());
|
||||
@@ -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\.]/);
|
||||
@@ -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);}
|
||||
File diff suppressed because one or more lines are too long
@@ -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; }
|
||||
@@ -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; }
|
||||
12
editor.php
12
editor.php
@@ -28,9 +28,8 @@ if ($theme=="default") {
|
||||
.cm-s-visible {display: block; top: 0px}
|
||||
.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";}
|
||||
<?;};?>
|
||||
// Make sure this next one remains the 5th item, updated with JS
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0px; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if ($visibleTabs) {?>\21e5<?;};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
|
||||
</style>
|
||||
@@ -80,7 +79,7 @@ function createNewCMInstance(num) {
|
||||
},
|
||||
onKeyEvent: function(instance, e) {
|
||||
top.ICEcoder.redoChangedContent(event);
|
||||
top.ICEcoder.findReplace('find',true);
|
||||
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());
|
||||
@@ -124,7 +123,10 @@ 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"}
|
||||
extraKeys: {
|
||||
"Tab": function(cm) {CodeMirror.commands[top.tabsIndent ? "defaultTab" : "insertTab"](cm);},
|
||||
"Shift-Tab": "indentLess"
|
||||
}
|
||||
});
|
||||
|
||||
// Now create the active line for this CodeMirror object
|
||||
|
||||
72
index.php
72
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;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ if ($testcMVersion) {
|
||||
<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);};
|
||||
@@ -52,18 +53,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 +70,7 @@ lastOpenFiles = [<?php
|
||||
<div class="popup">
|
||||
<div class="circleOutside"></div>
|
||||
<div class="circleInside"></div>
|
||||
loading...
|
||||
working...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,29 +88,24 @@ 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">
|
||||
<img src="images/ice-coder.gif" class="logo" 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>
|
||||
@@ -126,9 +113,8 @@ lastOpenFiles = [<?php
|
||||
<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>
|
||||
</div>
|
||||
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/file-manager-icons/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 +132,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>
|
||||
|
||||
@@ -24,9 +24,17 @@ body {overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
h1 {font-size: 36px; font-weight: normal; color: #888888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #ffffff}
|
||||
|
||||
.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}
|
||||
.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}
|
||||
.whiteGlow {
|
||||
-webkit-box-shadow: 0px 0px 8px 2px rgba(255,255,255,0.6);
|
||||
-moz-box-shadow: 0px 0px 8px 2px rgba(255,255,255,0.6);
|
||||
box-shadow: 0px 0px 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;
|
||||
@@ -67,7 +75,7 @@ body {overflow: hidden;
|
||||
.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 .logo {position: relative; margin: 5px 10px 0px 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);
|
||||
@@ -75,12 +83,25 @@ body {overflow: hidden;
|
||||
box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
|
||||
}
|
||||
.files .account {display: inline-block; height: 50px; width: 250px; margin-top: 40px; background-color: #888888}
|
||||
.files .accountLoginContainer {position: absolute; width: 250px; height: 50px; z-index: 1}
|
||||
.files .accountLoginContainer .accountLogin {position: absolute; width: 250px; height: 50px; top: 0px; background-color: #666666;
|
||||
-webkit-transition: top 0.3s;
|
||||
-moz-transition: top 0.3s;
|
||||
-o-transition: top 0.3s;
|
||||
transition: top 0.3s;
|
||||
}
|
||||
.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 input:focus, .findReplace input:focus, .findReplace select:focus, .accountPassword:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
-moz-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
}
|
||||
.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 .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;
|
||||
-webkit-transition: all 0.2s;
|
||||
@@ -106,6 +127,7 @@ body {overflow: hidden;
|
||||
.findReplace .findText {display: inline-block; height: 21px; font-size: 10px; margin: 8px 2px 0px 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 .replaceAction {margin: 0px 2px 0px 0px; top: -2px}
|
||||
.findReplace .replaceText {height: 21px; font-size: 10px; margin: 8px 2px 0px 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}
|
||||
@@ -138,4 +160,4 @@ body {overflow: hidden;
|
||||
.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 .button {border: 0px; background: #666666; color: #ffffff; height: 22px; cursor: pointer}
|
||||
206
lib/coder.js
206
lib/coder.js
@@ -25,13 +25,16 @@ 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"];
|
||||
init: function(login) {
|
||||
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++) {
|
||||
@@ -43,6 +46,12 @@ var ICEcoder = {
|
||||
|
||||
// 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
|
||||
@@ -56,7 +65,7 @@ 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";
|
||||
files.style.width = accountLogin.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";
|
||||
@@ -84,7 +93,6 @@ var ICEcoder = {
|
||||
if (fileName.indexOf(".js")<0&&fileName.indexOf(".rb")&&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 +177,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(".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 +247,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 +283,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 +291,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,21 +342,27 @@ 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);
|
||||
}
|
||||
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
|
||||
@@ -826,30 +846,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 +906,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 +921,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 +943,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 +970,16 @@ 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('.rb')>0) {
|
||||
cM.setOption("mode","ruby");
|
||||
} else if (fileName.indexOf('.css')>0) {
|
||||
cM.setOption("mode","css");
|
||||
} else {
|
||||
cM.setOption("mode","application/x-httpd-php");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -960,19 +1005,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
|
||||
@@ -1363,13 +1411,71 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// 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") {
|
||||
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'));
|
||||
},
|
||||
|
||||
// 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';
|
||||
}
|
||||
};
|
||||
@@ -152,7 +152,7 @@ if ($_GET['action']=="save") {
|
||||
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>';
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);if (top.ICEcoder.stickyTabWindow.location) {top.ICEcoder.stickyTabWindow.location.reload()};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,15 +193,16 @@ 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.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 #ffffff; max-width: 700px; max-height: 500px\" onClick=\"return false\"><br><span class=\"whiteGlow\" style=\"border: solid 10px #ffffff; color: #000000; background-color: #ffffff\" onClick=\"return false\"><?php echo str_replace($docRoot,"",$file);?></span>";
|
||||
}
|
||||
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
35
lib/multiple-results.css
Normal file
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: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
outline: 0px;
|
||||
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: #888888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #ffffff}
|
||||
hr {border: 0; height: 1px; background-color: #888888}
|
||||
|
||||
.results {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #ffffff}
|
||||
.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: 0px; 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
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
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: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
outline: 0px;
|
||||
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: #888888; margin-bottom: 20px}
|
||||
h2 {font-size: 18px; font-weight: normal; color: #ffffff}
|
||||
|
||||
.settings {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #ffffff}
|
||||
.settings .infoPane {position: relative; width: 230px; height: 560px; font-size: 10px; color: #bbbbbb; background-color: #ffffff; padding: 20px; float: left}
|
||||
.settings .infoPane a {color: #888888; 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: #bbbbbb}
|
||||
.settings .settingsColumn1 {width: 220px; height: 560px; padding: 20px; float: left}
|
||||
.settings .settingsColumn2 {width: 420px; height: 560px; padding: 20px 20px 20px 0px; float: left}
|
||||
.settings input, .settings textarea {border: 1px solid #555555; background-color: #444444; color: #ffffff}
|
||||
.settings input:focus, .settings textarea:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
-moz-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
|
||||
box-shadow: 0px 0px 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: 0px; right: 20px; padding: 5px 10px; font-size: 18px; background-color: rgba(0,198,255,0.7); opacity: 0.1; cursor: pointer}
|
||||
205
lib/settings-screen.php
Normal file
205
lib/settings-screen.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?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: 0px; background-color: #ffffff; font-family: monospace}
|
||||
.CodeMirror-scroll {height: 220px; width: 420px; overflow: hidden}
|
||||
.cm-s-visible {display: block; top: 0px}
|
||||
.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: 0px; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if($visibleTabs) {echo '\21e5';};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="editor.css">
|
||||
<?php
|
||||
$themeArray = array("ambiance","blackboard","cobalt","eclipse","elegant","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>
|
||||
|
||||
<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: #888888">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: #888888">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>
|
||||
186
lib/settings.php
186
lib/settings.php
@@ -1,24 +1,102 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
$versionNo = "v 0.6.4";
|
||||
$codeMirrorDir = "CodeMirror-2.23";
|
||||
$cMThisVer = 2.23;
|
||||
$testcMVersion = false; // test if we're using the latest CodeMirror version
|
||||
$visibleTabs = true;
|
||||
// Function to handle salted hashing
|
||||
define('SALT_LENGTH',9);
|
||||
function generateHash($plainText,$salt=null) {
|
||||
if ($salt === null) {
|
||||
$salt = substr(md5(uniqid(rand(), true)),0,SALT_LENGTH);
|
||||
} else {
|
||||
$salt = substr($salt,0,SALT_LENGTH);
|
||||
}
|
||||
return $salt.sha1($salt.$plainText);
|
||||
}
|
||||
|
||||
// -----------------
|
||||
// Start of settings
|
||||
// -----------------
|
||||
|
||||
$versionNo = "v 0.6.6";
|
||||
$codeMirrorDir = "CodeMirror-2.24";
|
||||
$cMThisVer = 2.24;
|
||||
$tabsIndent = true;
|
||||
$testcMVersion = false;
|
||||
$openLastFiles = true;
|
||||
$codeAssist = true;
|
||||
$visibleTabs = false;
|
||||
$lockedNav = true;
|
||||
$accountPassword = "";
|
||||
$restrictedFiles = array("wp-",".php",".asp",".aspx");
|
||||
$bannedFiles = array("_coder","wp-",".exe");
|
||||
$allowedIPs = array("*"); // allowed IPs, * for any
|
||||
$bannedFiles = array("_coder","wp-",".exe",".sql");
|
||||
$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")
|
||||
);
|
||||
$accountPassword = "";
|
||||
$lastOpenedFiles = "";
|
||||
$openLastFiles = true;
|
||||
$theme = "default";
|
||||
$lastOpenedFiles = "";
|
||||
|
||||
// ---------------
|
||||
// End of settings
|
||||
// ---------------
|
||||
|
||||
|
||||
// Update this settings file?
|
||||
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
$settingsFile = 'settings.php';
|
||||
$settingsContents = file_get_contents($settingsFile);
|
||||
// Replace our lastOpenedFiles var with the the current
|
||||
$repPosStart = strpos($settingsContents,'$tabsIndent');
|
||||
$repPosEnd = strpos($settingsContents,'$lastOpenedFiles');
|
||||
|
||||
// Prepare all our vars
|
||||
if ($_POST['tabsIndent']) {$tabsIndent = "true";} else {$tabsIndent = "false";};
|
||||
if ($_POST['testcMVersion']) {$testcMVersion = "true";} else {$testcMVersion = "false";};
|
||||
if ($_POST['openLastFiles']) {$openLastFiles = "true";} else {$openLastFiles = "false";};
|
||||
if ($_POST['codeAssist']) {$codeAssist = "true";} else {$codeAssist = "false";};
|
||||
if ($_POST['visibleTabs']) {$visibleTabs = "true";} else {$visibleTabs = "false";};
|
||||
if ($_POST['lockedNav']) {$lockedNav = "true";} else {$lockedNav = "false";};
|
||||
if ($_POST['accountPassword']!="") {$accountPassword = generateHash($_POST['accountPassword']);} else {$accountPassword = $_POST['oldPassword'];};
|
||||
$restrictedFiles = 'array("'.str_replace(', ','","',$_POST['restrictedFiles']).'")';
|
||||
$bannedFiles = 'array("'.str_replace(', ','","',$_POST['bannedFiles']).'")';
|
||||
$allowedIPs = 'array("'.str_replace(', ','","',$_POST['allowedIPs']).'")';
|
||||
$plugins = 'array('.PHP_EOL.' array('.PHP_EOL.' '.str_replace('====================','),'.PHP_EOL.' array(',$_POST['plugins']).'))';
|
||||
$theme = $_POST['theme'];
|
||||
|
||||
$settingsNew = '$tabsIndent = '.$tabsIndent.';'.PHP_EOL;
|
||||
$settingsNew .= '$testcMVersion = '.$testcMVersion.';'.PHP_EOL;
|
||||
$settingsNew .= '$openLastFiles = '.$openLastFiles.';'.PHP_EOL;
|
||||
$settingsNew .= '$codeAssist = '.$codeAssist.';'.PHP_EOL;
|
||||
$settingsNew .= '$visibleTabs = '.$visibleTabs.';'.PHP_EOL;
|
||||
$settingsNew .= '$lockedNav = '.$lockedNav.';'.PHP_EOL;
|
||||
$settingsNew .= '$accountPassword = "'.$accountPassword.'";'.PHP_EOL;
|
||||
$settingsNew .= '$restrictedFiles = '.$restrictedFiles.';'.PHP_EOL;
|
||||
$settingsNew .= '$bannedFiles = '.$bannedFiles.';'.PHP_EOL;
|
||||
$settingsNew .= '$allowedIPs = '.$allowedIPs.';'.PHP_EOL;
|
||||
$settingsNew .= '$plugins = '.$plugins.';'.PHP_EOL;
|
||||
$settingsNew .= '$theme = "'.$theme.'";'.PHP_EOL;
|
||||
|
||||
// Compile our new settings
|
||||
$settingsContents = substr($settingsContents,0,$repPosStart).$settingsNew.substr($settingsContents,($repPosEnd),strlen($settingsContents));
|
||||
// Now update this file
|
||||
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
|
||||
fwrite($fh, $settingsContents);
|
||||
fclose($fh);
|
||||
|
||||
// OK, now this file is updated, update our current session with new arrays
|
||||
$_SESSION['restrictedFiles'] = $restrictedFiles = explode(", ",$_POST['restrictedFiles']);
|
||||
$_SESSION['bannedFiles'] = $bannedFiles = explode(", ",$_POST['bannedFiles']);
|
||||
$_SESSION['allowedIPs'] = $allowedIPs = explode(", ",$_POST['allowedIPs']);
|
||||
// Work out the theme to use now
|
||||
if ($theme=="default") {$themeURL="lib/editor.css";} else {$themeURL=$codeMirrorDir."/theme/".$theme.".css";};
|
||||
// Do we need a file manager refresh?
|
||||
if ($_POST['changedFileSettings']=="true") {$refreshFM="true";} else {$refreshFM="false";};
|
||||
// With all that worked out, we can now hide the settings screen and apply the new settings
|
||||
echo "<script>top.ICEcoder.settingsScreen('hide');top.ICEcoder.useNewSettings('".$themeURL."',".$tabsIndent.",".$codeAssist.",".$lockedNav.",".$visibleTabs.",".$refreshFM.");</script>";
|
||||
}
|
||||
|
||||
// Save the currently opened files for next time
|
||||
if ($_GET['saveFiles']) {
|
||||
if ($_SESSION['userLevel'] == 10) {
|
||||
$settingsFile = 'settings.php';
|
||||
@@ -35,21 +113,6 @@ if ($_GET['saveFiles']) {
|
||||
echo '<script>top.ICEcoder.serverQueue("del",0);</script>';
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// End of settings
|
||||
// ---------------
|
||||
|
||||
// Function to handle salted hashing
|
||||
define('SALT_LENGTH',9);
|
||||
function generateHash($plainText,$salt=null) {
|
||||
if ($salt === null) {
|
||||
$salt = substr(md5(uniqid(rand(), true)),0,SALT_LENGTH);
|
||||
} else {
|
||||
$salt = substr($salt,0,SALT_LENGTH);
|
||||
}
|
||||
return $salt.sha1($salt.$plainText);
|
||||
}
|
||||
|
||||
// Establish our user level
|
||||
if (!isset($_SESSION['userLevel'])) {$_SESSION['userLevel'] = 0;};
|
||||
if(isset($_POST['loginPassword']) && generateHash($_POST['loginPassword'],$accountPassword)==$accountPassword) {$_SESSION['userLevel'] = 10;};
|
||||
@@ -57,6 +120,19 @@ $_SESSION['userLevel'] = $_SESSION['userLevel'];
|
||||
|
||||
if (!isset($_SESSION['restrictedFiles'])) {$_SESSION['restrictedFiles'] = $restrictedFiles;}
|
||||
if (!isset($_SESSION['bannedFiles'])) {$_SESSION['bannedFiles'] = $bannedFiles;}
|
||||
if (!isset($_SESSION['allowedIPs'])) {$_SESSION['allowedIPs'] = $allowedIPs;}
|
||||
|
||||
// Determin our allowed IP addresses
|
||||
$allowedIP = false;
|
||||
for($i=0;$i<count($_SESSION['allowedIPs']);$i++) {
|
||||
if ($_SESSION['allowedIPs'][$i]==$_SERVER["REMOTE_ADDR"]||$_SESSION['allowedIPs'][$i]=="*") {
|
||||
$allowedIP = true;
|
||||
}
|
||||
}
|
||||
// If user not allowed to view, boot to site root
|
||||
if (!$allowedIP) {
|
||||
echo '<script>top.window.location="/";</script>';
|
||||
};
|
||||
|
||||
// Establish our shortened URL, explode the path based on server type (Linux or Windows)
|
||||
if (strpos($_SERVER['DOCUMENT_ROOT'],"/")>-1) {$slashType = "/";} else {$slashType = "\\";};
|
||||
@@ -67,6 +143,56 @@ $shortURLStarts = explode($slashType,$_SERVER['DOCUMENT_ROOT']);
|
||||
if ($shortURLStarts[count($shortURLStarts)-1]!="") {$trimArray=1;} else {$trimArray=2;}
|
||||
$shortURLStarts = $shortURLStarts[count($shortURLStarts)-$trimArray];
|
||||
|
||||
// If we're updating or calling from the index.php page, do/redo plugins & last opened files
|
||||
if (($_POST["theme"] && $_SESSION['userLevel'] == 10) || strpos($_SERVER['PHP_SELF'],"index.php")>0) {
|
||||
// If we're updating, we need to recreate the plugins array
|
||||
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
$plugins = array();
|
||||
$pluginsArray = explode("====================",str_replace("\"","",str_replace("\r","",str_replace("\n","",$_POST['plugins']))));
|
||||
for ($i=0;$i<count($pluginsArray);$i++) {
|
||||
array_push($plugins, explode(",",$pluginsArray[$i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Work out the plugins to display to the user
|
||||
$pluginsDisplay = "";
|
||||
for ($i=0;$i<count($plugins);$i++) {
|
||||
$target = explode(":",$plugins[$i][4]);
|
||||
$pluginsDisplay .= '<a href="'.$plugins[$i][3].'" target="'.$target[0].'"><img src="'.$plugins[$i][1].'" style="'.$plugins[$i][2].'" alt="'.$plugins[$i][0].'"></a>';
|
||||
};
|
||||
|
||||
// If we're updating, replace the plugin display with our newly established one
|
||||
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
echo "<script>top.document.getElementById('pluginsContainer').innerHTML = '".$pluginsDisplay."';</script>";
|
||||
}
|
||||
|
||||
// Work out what plugins we'll need to set on a setInterval
|
||||
$onLoadExtras = "";
|
||||
for ($i=0;$i<count($plugins);$i++) {
|
||||
if ($plugins[$i][5]!="") {
|
||||
$onLoadExtras .= ";top.ICEcoder.startPluginIntervals(".$i.",'".$plugins[$i][3]."','".$plugins[$i][4]."','".$plugins[$i][5]."')";
|
||||
};
|
||||
};
|
||||
|
||||
// If we're updating our settings, clear existing setIntervals & the array refs, then start new ones
|
||||
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
?>
|
||||
<script>
|
||||
for (i=0;i<=top.ICEcoder.pluginIntervalRefs.length-1;i++) {
|
||||
clearInterval(top.ICEcoder['plugTimer'+top.ICEcoder.pluginIntervalRefs[i]]);
|
||||
}
|
||||
top.ICEcoder.pluginIntervalRefs = [];
|
||||
<?php echo $onLoadExtras.PHP_EOL; ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Finally, open last opened files if we need to (applies to index.php only)
|
||||
if ($openLastFiles) {
|
||||
$onLoadExtras .= ";top.ICEcoder.autoOpenFiles()";
|
||||
}
|
||||
}
|
||||
|
||||
// If we're due to show the settings screen
|
||||
if ($accountPassword == "" && isset($_GET['settings'])) {
|
||||
?>
|
||||
@@ -121,5 +247,15 @@ if ($accountPassword == "" && isset($_GET['settings'])) {
|
||||
header('Location: lib/settings.php?settings=set');
|
||||
}
|
||||
}
|
||||
|
||||
// If we're logging in, refresh the file manager and show icons if login is correct
|
||||
if(isset($_POST['loginPassword'])) {
|
||||
if(isset($_POST['loginPassword']) && generateHash($_POST['loginPassword'],$accountPassword)==$accountPassword) {
|
||||
$loginAttempt = 'loginOK';
|
||||
} else {
|
||||
$loginAttempt = 'loginFailed';
|
||||
}
|
||||
echo "<script>top.ICEcoder.refreshFileManager('".$loginAttempt."');</script>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -74,9 +74,14 @@ Class zipIt {
|
||||
// Trigger the class
|
||||
$zipItDoZip = new zipIt();
|
||||
$zipItAddToZip = $zipItDoZip->zipFilesUp($zipItSaveLocation.$zipItFileName);
|
||||
if ($zipItAddToZip) {echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);</script>';};
|
||||
if (!$zipItAddToZip) {echo '<script>alert("Could not zip files up!");</script>';};
|
||||
;};
|
||||
?>
|
||||
|
||||
<script>
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user