Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79bd665b92 | ||
|
|
0de026fc2b | ||
|
|
cb3f87d4d9 | ||
|
|
f9ec7b7138 | ||
|
|
77e0e1d51f | ||
|
|
c28cd3506e | ||
|
|
7dd3c36867 | ||
|
|
4dd36c5130 | ||
|
|
f00628539a | ||
|
|
fcc5896926 | ||
|
|
75881d1c9f | ||
|
|
9597b057a6 | ||
|
|
7d209a1c58 | ||
|
|
490ca1c1c3 | ||
|
|
95c0aa1812 | ||
|
|
9cbb9f7529 | ||
|
|
c8a73fa56e | ||
|
|
29dff39bf1 | ||
|
|
ef8190612f | ||
|
|
55d547d947 | ||
|
|
e80825ac3a | ||
|
|
8d8edc171c | ||
|
|
c1f4740b68 | ||
|
|
d6a5f486d7 | ||
|
|
807cc53fa8 | ||
|
|
2237c91067 | ||
|
|
98a08fddf8 | ||
|
|
21cdcb20b4 | ||
|
|
47547b2ae8 | ||
|
|
6e9af92471 | ||
|
|
cc7df4222a | ||
|
|
25b5af50c2 | ||
|
|
7c8c728ad4 | ||
|
|
655fef4baa | ||
|
|
a27db58031 | ||
|
|
7c0cb2d1c3 | ||
|
|
229a089d45 | ||
|
|
49ca9d75f9 | ||
|
|
745903d133 | ||
|
|
54bf805548 | ||
|
|
2ac674f5c6 | ||
|
|
2b5a16be70 | ||
|
|
1fbe9df342 | ||
|
|
1217d2d05e | ||
|
|
432795026c | ||
|
|
ab23eaa6ff | ||
|
|
4583c0c713 | ||
|
|
d3a961f13f | ||
|
|
7a97af2c1d | ||
|
|
750cc59fd5 | ||
|
|
dfcf54d412 | ||
|
|
5fd1c35d85 | ||
|
|
21b61bd027 | ||
|
|
7fa28c6d8b | ||
|
|
97e396794a | ||
|
|
b096ef3606 | ||
|
|
74b0d86c36 | ||
|
|
319c509318 | ||
|
|
5703a040be | ||
|
|
6752b8ef50 | ||
|
|
7062560eaa | ||
|
|
3be433c910 | ||
|
|
bd0969e870 | ||
|
|
ffbac321a4 | ||
|
|
222f6589a9 | ||
|
|
a2245775a9 | ||
|
|
d594050166 | ||
|
|
2665055558 | ||
|
|
3e41afb0a6 | ||
|
|
f1ec4a2453 | ||
|
|
98f1ace910 | ||
|
|
401a3a7abb | ||
|
|
6a0cc816a9 | ||
|
|
4bafb3aaa1 | ||
|
|
782aac54e4 | ||
|
|
06dd46c24f | ||
|
|
bc50886250 |
1
CodeMirror-2.25/lib/codemirror-compressed.js
Normal file
@@ -1,234 +0,0 @@
|
||||
CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit,
|
||||
keywords = parserConfig.keywords || {},
|
||||
blockKeywords = parserConfig.blockKeywords || {},
|
||||
atoms = parserConfig.atoms || {},
|
||||
hooks = parserConfig.hooks || {},
|
||||
multiLineStrings = parserConfig.multiLineStrings;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
||||
|
||||
var curPunc;
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
var result = hooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == '"' || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
}
|
||||
if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenComment(stream, state);
|
||||
}
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
}
|
||||
if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return "operator";
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var cur = stream.current();
|
||||
if (keywords.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
return "keyword";
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
return "word";
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) {end = true; break;}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (end || !(escaped || multiLineStrings))
|
||||
state.tokenize = null;
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
|
||||
function Context(indented, column, type, align, prev) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.align = align;
|
||||
this.prev = prev;
|
||||
}
|
||||
function pushContext(state, col, type) {
|
||||
return state.context = new Context(state.indented, col, type, null, state.context);
|
||||
}
|
||||
function popContext(state) {
|
||||
var t = state.context.type;
|
||||
if (t == ")" || t == "]" || t == "}")
|
||||
state.indented = state.context.indented;
|
||||
return state.context = state.context.prev;
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: null,
|
||||
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
|
||||
indented: 0,
|
||||
startOfLine: true
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var ctx = state.context;
|
||||
if (stream.sol()) {
|
||||
if (ctx.align == null) ctx.align = false;
|
||||
state.indented = stream.indentation();
|
||||
state.startOfLine = true;
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
curPunc = null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
|
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
||||
else if (curPunc == "}") {
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
if (ctx.type == "}") ctx = popContext(state);
|
||||
while (ctx.type == "statement") ctx = popContext(state);
|
||||
}
|
||||
else if (curPunc == ctx.type) popContext(state);
|
||||
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
|
||||
pushContext(state, stream.column(), "statement");
|
||||
state.startOfLine = false;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
|
||||
var closing = firstChar == ctx.type;
|
||||
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
|
||||
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
|
||||
else return ctx.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: "{}"
|
||||
};
|
||||
});
|
||||
|
||||
(function() {
|
||||
function words(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
|
||||
"double static else struct entry switch extern typedef float union for unsigned " +
|
||||
"goto while enum void const signed volatile";
|
||||
|
||||
function cppHook(stream, state) {
|
||||
if (!state.startOfLine) return false;
|
||||
stream.skipToEnd();
|
||||
return "meta";
|
||||
}
|
||||
|
||||
// C#-style strings where "" escapes a quote.
|
||||
function tokenAtString(stream, state) {
|
||||
var next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == '"' && !stream.eat('"')) {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
CodeMirror.defineMIME("text/x-csrc", {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords),
|
||||
blockKeywords: words("case do else for if switch while struct"),
|
||||
atoms: words("null"),
|
||||
hooks: {"#": cppHook}
|
||||
});
|
||||
CodeMirror.defineMIME("text/x-c++src", {
|
||||
name: "clike",
|
||||
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
|
||||
"static_cast typeid catch operator template typename class friend private " +
|
||||
"this using const_cast inline public throw virtual delete mutable protected " +
|
||||
"wchar_t"),
|
||||
blockKeywords: words("catch class do else finally for if struct switch try while"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {"#": cppHook}
|
||||
});
|
||||
CodeMirror.defineMIME("text/x-java", {
|
||||
name: "clike",
|
||||
keywords: words("abstract assert boolean break byte case catch char class const continue default " +
|
||||
"do double else enum extends final finally float for goto if implements import " +
|
||||
"instanceof int interface long native new package private protected public " +
|
||||
"return short static strictfp super switch synchronized this throw throws transient " +
|
||||
"try void volatile while"),
|
||||
blockKeywords: words("catch class do else finally for if switch try while"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {
|
||||
"@": function(stream, state) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
}
|
||||
});
|
||||
CodeMirror.defineMIME("text/x-csharp", {
|
||||
name: "clike",
|
||||
keywords: words("abstract as base bool break byte case catch char checked class const continue decimal" +
|
||||
" default delegate do double else enum event explicit extern finally fixed float for" +
|
||||
" foreach goto if implicit in int interface internal is lock long namespace new object" +
|
||||
" operator out override params private protected public readonly ref return sbyte sealed short" +
|
||||
" sizeof stackalloc static string struct switch this throw try typeof uint ulong unchecked" +
|
||||
" unsafe ushort using virtual void volatile while add alias ascending descending dynamic from get" +
|
||||
" global group into join let orderby partial remove select set value var yield"),
|
||||
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
|
||||
atoms: words("true false null"),
|
||||
hooks: {
|
||||
"@": function(stream, state) {
|
||||
if (stream.eat('"')) {
|
||||
state.tokenize = tokenAtString;
|
||||
return tokenAtString(stream, state);
|
||||
}
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
||||
@@ -1,22 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2011 Jeff Pickhardt
|
||||
Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,347 +0,0 @@
|
||||
/**
|
||||
* Link to the project's GitHub page:
|
||||
* https://github.com/pickhardt/coffeescript-codemirror-mode
|
||||
*/
|
||||
CodeMirror.defineMode('coffeescript', function(conf) {
|
||||
var ERRORCLASS = 'error';
|
||||
|
||||
function wordRegexp(words) {
|
||||
return new RegExp("^((" + words.join(")|(") + "))\\b");
|
||||
}
|
||||
|
||||
var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
|
||||
var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
|
||||
var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
|
||||
var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
|
||||
var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
|
||||
var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
|
||||
|
||||
var wordOperators = wordRegexp(['and', 'or', 'not',
|
||||
'is', 'isnt', 'in',
|
||||
'instanceof', 'typeof']);
|
||||
var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else',
|
||||
'switch', 'try', 'catch', 'finally', 'class'];
|
||||
var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete',
|
||||
'do', 'in', 'of', 'new', 'return', 'then',
|
||||
'this', 'throw', 'when', 'until'];
|
||||
|
||||
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
|
||||
|
||||
indentKeywords = wordRegexp(indentKeywords);
|
||||
|
||||
|
||||
var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])");
|
||||
var regexPrefixes = new RegExp("^(/{3}|/)");
|
||||
var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no'];
|
||||
var constants = wordRegexp(commonConstants);
|
||||
|
||||
// Tokenizers
|
||||
function tokenBase(stream, state) {
|
||||
// Handle scope changes
|
||||
if (stream.sol()) {
|
||||
var scopeOffset = state.scopes[0].offset;
|
||||
if (stream.eatSpace()) {
|
||||
var lineOffset = stream.indentation();
|
||||
if (lineOffset > scopeOffset) {
|
||||
return 'indent';
|
||||
} else if (lineOffset < scopeOffset) {
|
||||
return 'dedent';
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
if (scopeOffset > 0) {
|
||||
dedent(stream, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var ch = stream.peek();
|
||||
|
||||
// Handle docco title comment (single line)
|
||||
if (stream.match("####")) {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
}
|
||||
|
||||
// Handle multi line comments
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = longComment;
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
|
||||
// Single line comment
|
||||
if (ch === '#') {
|
||||
stream.skipToEnd();
|
||||
return 'comment';
|
||||
}
|
||||
|
||||
// Handle number literals
|
||||
if (stream.match(/^-?[0-9\.]/, false)) {
|
||||
var floatLiteral = false;
|
||||
// Floats
|
||||
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\d+\.\d*/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
if (stream.match(/^-?\.\d+/)) {
|
||||
floatLiteral = true;
|
||||
}
|
||||
|
||||
if (floatLiteral) {
|
||||
// prevent from getting extra . on 1..
|
||||
if (stream.peek() == "."){
|
||||
stream.backUp(1);
|
||||
}
|
||||
return 'number';
|
||||
}
|
||||
// Integers
|
||||
var intLiteral = false;
|
||||
// Hex
|
||||
if (stream.match(/^-?0x[0-9a-f]+/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Decimal
|
||||
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
// Zero by itself with no other piece of number.
|
||||
if (stream.match(/^-?0(?![\dx])/i)) {
|
||||
intLiteral = true;
|
||||
}
|
||||
if (intLiteral) {
|
||||
return 'number';
|
||||
}
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (stream.match(stringPrefixes)) {
|
||||
state.tokenize = tokenFactory(stream.current(), 'string');
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
// Handle regex literals
|
||||
if (stream.match(regexPrefixes)) {
|
||||
if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
|
||||
state.tokenize = tokenFactory(stream.current(), 'string-2');
|
||||
return state.tokenize(stream, state);
|
||||
} else {
|
||||
stream.backUp(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle operators and delimiters
|
||||
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
|
||||
return 'punctuation';
|
||||
}
|
||||
if (stream.match(doubleOperators)
|
||||
|| stream.match(singleOperators)
|
||||
|| stream.match(wordOperators)) {
|
||||
return 'operator';
|
||||
}
|
||||
if (stream.match(singleDelimiters)) {
|
||||
return 'punctuation';
|
||||
}
|
||||
|
||||
if (stream.match(constants)) {
|
||||
return 'atom';
|
||||
}
|
||||
|
||||
if (stream.match(keywords)) {
|
||||
return 'keyword';
|
||||
}
|
||||
|
||||
if (stream.match(identifiers)) {
|
||||
return 'variable';
|
||||
}
|
||||
|
||||
// Handle non-detected items
|
||||
stream.next();
|
||||
return ERRORCLASS;
|
||||
}
|
||||
|
||||
function tokenFactory(delimiter, outclass) {
|
||||
var singleline = delimiter.length == 1;
|
||||
return function tokenString(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^'"\/\\]/);
|
||||
if (stream.eat('\\')) {
|
||||
stream.next();
|
||||
if (singleline && stream.eol()) {
|
||||
return outclass;
|
||||
}
|
||||
} else if (stream.match(delimiter)) {
|
||||
state.tokenize = tokenBase;
|
||||
return outclass;
|
||||
} else {
|
||||
stream.eat(/['"\/]/);
|
||||
}
|
||||
}
|
||||
if (singleline) {
|
||||
if (conf.mode.singleLineStringErrors) {
|
||||
outclass = ERRORCLASS
|
||||
} else {
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
}
|
||||
return outclass;
|
||||
};
|
||||
}
|
||||
|
||||
function longComment(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
stream.eatWhile(/[^#]/);
|
||||
if (stream.match("###")) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
stream.eatWhile("#");
|
||||
}
|
||||
return "comment"
|
||||
}
|
||||
|
||||
function indent(stream, state, type) {
|
||||
type = type || 'coffee';
|
||||
var indentUnit = 0;
|
||||
if (type === 'coffee') {
|
||||
for (var i = 0; i < state.scopes.length; i++) {
|
||||
if (state.scopes[i].type === 'coffee') {
|
||||
indentUnit = state.scopes[i].offset + conf.indentUnit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
indentUnit = stream.column() + stream.current().length;
|
||||
}
|
||||
state.scopes.unshift({
|
||||
offset: indentUnit,
|
||||
type: type
|
||||
});
|
||||
}
|
||||
|
||||
function dedent(stream, state) {
|
||||
if (state.scopes.length == 1) return;
|
||||
if (state.scopes[0].type === 'coffee') {
|
||||
var _indent = stream.indentation();
|
||||
var _indent_index = -1;
|
||||
for (var i = 0; i < state.scopes.length; ++i) {
|
||||
if (_indent === state.scopes[i].offset) {
|
||||
_indent_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_indent_index === -1) {
|
||||
return true;
|
||||
}
|
||||
while (state.scopes[0].offset !== _indent) {
|
||||
state.scopes.shift();
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
state.scopes.shift();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tokenLexer(stream, state) {
|
||||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
// Handle '.' connected identifiers
|
||||
if (current === '.') {
|
||||
style = state.tokenize(stream, state);
|
||||
current = stream.current();
|
||||
if (style === 'variable') {
|
||||
return 'variable';
|
||||
} else {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle properties
|
||||
if (current === '@') {
|
||||
stream.eat('@');
|
||||
return 'keyword';
|
||||
}
|
||||
|
||||
// Handle scope changes.
|
||||
if (current === 'return') {
|
||||
state.dedent += 1;
|
||||
}
|
||||
if (((current === '->' || current === '=>') &&
|
||||
!state.lambda &&
|
||||
state.scopes[0].type == 'coffee' &&
|
||||
stream.peek() === '')
|
||||
|| style === 'indent') {
|
||||
indent(stream, state);
|
||||
}
|
||||
var delimiter_index = '[({'.indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
|
||||
}
|
||||
if (indentKeywords.exec(current)){
|
||||
indent(stream, state);
|
||||
}
|
||||
if (current == 'then'){
|
||||
dedent(stream, state);
|
||||
}
|
||||
|
||||
|
||||
if (style === 'dedent') {
|
||||
if (dedent(stream, state)) {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
delimiter_index = '])}'.indexOf(current);
|
||||
if (delimiter_index !== -1) {
|
||||
if (dedent(stream, state)) {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
|
||||
if (state.scopes.length > 1) state.scopes.shift();
|
||||
state.dedent -= 1;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
var external = {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: tokenBase,
|
||||
scopes: [{offset:basecolumn || 0, type:'coffee'}],
|
||||
lastToken: null,
|
||||
lambda: false,
|
||||
dedent: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
var style = tokenLexer(stream, state);
|
||||
|
||||
state.lastToken = {style:style, content: stream.current()};
|
||||
|
||||
if (stream.eol() && stream.lambda) {
|
||||
state.lambda = false;
|
||||
}
|
||||
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != tokenBase) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state.scopes[0].offset;
|
||||
}
|
||||
|
||||
};
|
||||
return external;
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript');
|
||||
@@ -1,124 +0,0 @@
|
||||
CodeMirror.defineMode("css", function(config) {
|
||||
var indentUnit = config.indentUnit, type;
|
||||
function ret(style, tp) {type = tp; return style;}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
|
||||
else if (ch == "/" && stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
else if (ch == "<" && stream.eat("!")) {
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
}
|
||||
else if (ch == "=") ret(null, "compare");
|
||||
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
else if (ch == "#") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("atom", "hash");
|
||||
}
|
||||
else if (ch == "!") {
|
||||
stream.match(/^\s*\w*/);
|
||||
return ret("keyword", "important");
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
}
|
||||
else if (/[,.+>*\/]/.test(ch)) {
|
||||
return ret(null, "select-op");
|
||||
}
|
||||
else if (/[;{}:\[\]]/.test(ch)) {
|
||||
return ret(null, ch);
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("variable", "variable");
|
||||
}
|
||||
}
|
||||
|
||||
function tokenCComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (maybeEnd && ch == "/") {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
function tokenSGMLComment(stream, state) {
|
||||
var dashes = 0, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (dashes >= 2 && ch == ">") {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
dashes = (ch == "-") ? dashes + 1 : 0;
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && !escaped)
|
||||
break;
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
if (!escaped) state.tokenize = tokenBase;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: tokenBase,
|
||||
baseIndent: base || 0,
|
||||
stack: []};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
|
||||
var context = state.stack[state.stack.length-1];
|
||||
if (type == "hash" && context != "rule") style = "string-2";
|
||||
else if (style == "variable") {
|
||||
if (context == "rule") style = "number";
|
||||
else if (!context || context == "@media{") style = "tag";
|
||||
}
|
||||
|
||||
if (context == "rule" && /^[\{\};]$/.test(type))
|
||||
state.stack.pop();
|
||||
if (type == "{") {
|
||||
if (context == "@media") state.stack[state.stack.length-1] = "@media{";
|
||||
else state.stack.push("{");
|
||||
}
|
||||
else if (type == "}") state.stack.pop();
|
||||
else if (type == "@media") state.stack.push("@media");
|
||||
else if (context == "{" && type != "comment") state.stack.push("rule");
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var n = state.stack.length;
|
||||
if (/^\}/.test(textAfter))
|
||||
n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
|
||||
return state.baseIndent + n * indentUnit;
|
||||
},
|
||||
|
||||
electricChars: "}"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/css", "css");
|
||||
@@ -1,361 +0,0 @@
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var jsonMode = parserConfig.json;
|
||||
|
||||
// Tokenizer
|
||||
|
||||
var keywords = function(){
|
||||
function kw(type) {return {type: type, style: "keyword"};}
|
||||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
||||
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
||||
return {
|
||||
"if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
||||
"function": kw("function"), "catch": kw("catch"),
|
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
||||
};
|
||||
}();
|
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
function nextUntilUnescaped(stream, end) {
|
||||
var escaped = false, next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content;
|
||||
function ret(tp, style, cont) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
|
||||
function jsTokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == '"' || ch == "'")
|
||||
return chain(stream, state, jsTokenString(ch));
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
return ret(ch);
|
||||
else if (ch == "0" && stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
return chain(stream, state, jsTokenComment);
|
||||
}
|
||||
else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
else if (state.reAllowed) {
|
||||
nextUntilUnescaped(stream, "/");
|
||||
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
||||
return ret("regexp", "string-2");
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
}
|
||||
else if (ch == "#") {
|
||||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
}
|
||||
else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
|
||||
ret("variable", "variable", word);
|
||||
}
|
||||
}
|
||||
|
||||
function jsTokenString(quote) {
|
||||
return function(stream, state) {
|
||||
if (!nextUntilUnescaped(stream, quote))
|
||||
state.tokenize = jsTokenBase;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function jsTokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = jsTokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
||||
|
||||
function JSLexical(indented, column, type, align, prev, info) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.prev = prev;
|
||||
this.info = info;
|
||||
if (align != null) this.align = align;
|
||||
}
|
||||
|
||||
function inScope(state, varname) {
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
}
|
||||
|
||||
function parseJS(state, style, type, content, stream) {
|
||||
var cc = state.cc;
|
||||
// Communicate our context to the combinators.
|
||||
// (Less wasteful than consing up a hundred closures on every call.)
|
||||
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
|
||||
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = true;
|
||||
|
||||
while(true) {
|
||||
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
|
||||
if (combinator(type, content)) {
|
||||
while(cc.length && cc[cc.length - 1].lex)
|
||||
cc.pop()();
|
||||
if (cx.marked) return cx.marked;
|
||||
if (type == "variable" && inScope(state, content)) return "variable-2";
|
||||
return style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Combinator utils
|
||||
|
||||
var cx = {state: null, column: null, marked: null, cc: null};
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
}
|
||||
function register(varname) {
|
||||
var state = cx.state;
|
||||
if (state.context) {
|
||||
cx.marked = "def";
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return;
|
||||
state.localVars = {name: varname, next: state.localVars};
|
||||
}
|
||||
}
|
||||
|
||||
// Combinators
|
||||
|
||||
var defaultVars = {name: "this", next: {name: "arguments"}};
|
||||
function pushcontext() {
|
||||
if (!cx.state.context) cx.state.localVars = defaultVars;
|
||||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
|
||||
}
|
||||
function popcontext() {
|
||||
cx.state.localVars = cx.state.context.vars;
|
||||
cx.state.context = cx.state.context.prev;
|
||||
}
|
||||
function pushlex(type, info) {
|
||||
var result = function() {
|
||||
var state = cx.state;
|
||||
state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
|
||||
};
|
||||
result.lex = true;
|
||||
return result;
|
||||
}
|
||||
function poplex() {
|
||||
var state = cx.state;
|
||||
if (state.lexical.prev) {
|
||||
if (state.lexical.type == ")")
|
||||
state.indented = state.lexical.indented;
|
||||
state.lexical = state.lexical.prev;
|
||||
}
|
||||
}
|
||||
poplex.lex = true;
|
||||
|
||||
function expect(wanted) {
|
||||
return function expecting(type) {
|
||||
if (type == wanted) return cont();
|
||||
else if (wanted == ";") return pass();
|
||||
else return cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
|
||||
function statement(type) {
|
||||
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
||||
poplex, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
if (type == "case") return cont(expression, expect(":"));
|
||||
if (type == "default") return cont(expect(":"));
|
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
||||
statement, poplex, popcontext);
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "keyword c") return cont(maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
|
||||
if (type == "operator") return cont(expression);
|
||||
if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
||||
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
||||
return cont();
|
||||
}
|
||||
function maybeexpression(type) {
|
||||
if (type.match(/[;\}\)\],]/)) return pass();
|
||||
return pass(expression);
|
||||
}
|
||||
|
||||
function maybeoperator(type, value) {
|
||||
if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
|
||||
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);
|
||||
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
||||
}
|
||||
function maybelabel(type) {
|
||||
if (type == ":") return cont(poplex, statement);
|
||||
return pass(maybeoperator, expect(";"), poplex);
|
||||
}
|
||||
function property(type) {
|
||||
if (type == "variable") {cx.marked = "property"; return cont();}
|
||||
}
|
||||
function objprop(type) {
|
||||
if (type == "variable") cx.marked = "property";
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
if (type == ",") return cont(what, proceed);
|
||||
if (type == end) return cont();
|
||||
return cont(expect(end));
|
||||
}
|
||||
return function commaSeparated(type) {
|
||||
if (type == end) return cont();
|
||||
else return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
function block(type) {
|
||||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function vardef1(type, value) {
|
||||
if (type == "variable"){register(value); return cont(vardef2);}
|
||||
return cont();
|
||||
}
|
||||
function vardef2(type, value) {
|
||||
if (value == "=") return cont(expression, vardef2);
|
||||
if (type == ",") return cont(vardef1);
|
||||
}
|
||||
function forspec1(type) {
|
||||
if (type == "var") return cont(vardef1, forspec2);
|
||||
if (type == ";") return pass(forspec2);
|
||||
if (type == "variable") return cont(formaybein);
|
||||
return pass(forspec2);
|
||||
}
|
||||
function formaybein(type, value) {
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(maybeoperator, forspec2);
|
||||
}
|
||||
function forspec2(type, value) {
|
||||
if (type == ";") return cont(forspec3);
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type != ")") cont(expression);
|
||||
}
|
||||
function functiondef(type, value) {
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
}
|
||||
function funarg(type, value) {
|
||||
if (type == "variable") {register(value); return cont();}
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: jsTokenBase,
|
||||
reAllowed: true,
|
||||
kwAllowed: true,
|
||||
cc: [],
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = false;
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type == "comment") return style;
|
||||
state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
|
||||
state.kwAllowed = type != '.';
|
||||
return parseJS(state, style, type, content, stream);
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != jsTokenBase) return 0;
|
||||
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;
|
||||
else if (lexical.info == "switch" && !closing)
|
||||
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
||||
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
||||
else return lexical.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: ":{}"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/javascript", "javascript");
|
||||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
||||
@@ -1,150 +0,0 @@
|
||||
(function() {
|
||||
function keywords(str) {
|
||||
var obj = {}, words = str.split(" ");
|
||||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
function heredoc(delim) {
|
||||
return function(stream, state) {
|
||||
if (stream.match(delim)) state.tokenize = null;
|
||||
else stream.skipToEnd();
|
||||
return "string";
|
||||
}
|
||||
}
|
||||
var phpConfig = {
|
||||
name: "clike",
|
||||
keywords: keywords("abstract and array as break case catch class clone const continue declare default " +
|
||||
"do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
|
||||
"for foreach function global goto if implements interface instanceof namespace " +
|
||||
"new or private protected public static switch throw trait try use var while xor " +
|
||||
"die echo empty exit eval include include_once isset list require require_once return " +
|
||||
"print unset __halt_compiler self static parent"),
|
||||
blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
|
||||
atoms: keywords("true false null TRUE FALSE NULL"),
|
||||
multiLineStrings: true,
|
||||
hooks: {
|
||||
"$": function(stream, state) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "variable-2";
|
||||
},
|
||||
"<": function(stream, state) {
|
||||
if (stream.match(/<</)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
state.tokenize = heredoc(stream.current().slice(3));
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
"#": function(stream, state) {
|
||||
while (!stream.eol() && !stream.match("?>", false)) stream.next();
|
||||
return "comment";
|
||||
},
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
while (!stream.eol() && !stream.match("?>", false)) stream.next();
|
||||
return "comment";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.defineMode("php", function(config, parserConfig) {
|
||||
var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
|
||||
var jsMode = CodeMirror.getMode(config, "javascript");
|
||||
var cssMode = CodeMirror.getMode(config, "css");
|
||||
var phpMode = CodeMirror.getMode(config, phpConfig);
|
||||
|
||||
function dispatch(stream, state) { // TODO open PHP inside text/css
|
||||
var isPHP = state.mode == "php";
|
||||
if (stream.sol() && state.pending != '"') state.pending = null;
|
||||
if (state.curMode == htmlMode) {
|
||||
if (stream.match(/^<\?\w*/)) {
|
||||
state.curMode = phpMode;
|
||||
state.curState = state.php;
|
||||
state.curClose = "?>";
|
||||
state.mode = "php";
|
||||
return "meta";
|
||||
}
|
||||
if (state.pending == '"') {
|
||||
while (!stream.eol() && stream.next() != '"') {}
|
||||
var style = "string";
|
||||
} else if (state.pending && stream.pos < state.pending.end) {
|
||||
stream.pos = state.pending.end;
|
||||
var style = state.pending.style;
|
||||
} else {
|
||||
var style = htmlMode.token(stream, state.curState);
|
||||
}
|
||||
state.pending = null;
|
||||
var cur = stream.current(), openPHP = cur.search(/<\?/);
|
||||
if (openPHP != -1) {
|
||||
if (style == "string" && /\"$/.test(cur) && !/\?>/.test(cur)) state.pending = '"';
|
||||
else state.pending = {end: stream.pos, style: style};
|
||||
stream.backUp(cur.length - openPHP);
|
||||
} else if (style == "tag" && stream.current() == ">" && state.curState.context) {
|
||||
if (/^script$/i.test(state.curState.context.tagName)) {
|
||||
state.curMode = jsMode;
|
||||
state.curState = jsMode.startState(htmlMode.indent(state.curState, ""));
|
||||
state.curClose = /^<\/\s*script\s*>/i;
|
||||
state.mode = "javascript";
|
||||
}
|
||||
else if (/^style$/i.test(state.curState.context.tagName)) {
|
||||
state.curMode = cssMode;
|
||||
state.curState = cssMode.startState(htmlMode.indent(state.curState, ""));
|
||||
state.curClose = /^<\/\s*style\s*>/i;
|
||||
state.mode = "css";
|
||||
}
|
||||
}
|
||||
return style;
|
||||
} else if ((!isPHP || state.php.tokenize == null) &&
|
||||
stream.match(state.curClose, isPHP)) {
|
||||
state.curMode = htmlMode;
|
||||
state.curState = state.html;
|
||||
state.curClose = null;
|
||||
state.mode = "html";
|
||||
if (isPHP) return "meta";
|
||||
else return dispatch(stream, state);
|
||||
} else {
|
||||
return state.curMode.token(stream, state.curState);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
var html = htmlMode.startState();
|
||||
return {html: html,
|
||||
php: phpMode.startState(),
|
||||
curMode: parserConfig.startOpen ? phpMode : htmlMode,
|
||||
curState: parserConfig.startOpen ? phpMode.startState() : html,
|
||||
curClose: parserConfig.startOpen ? /^\?>/ : null,
|
||||
mode: parserConfig.startOpen ? "php" : "html",
|
||||
pending: null}
|
||||
},
|
||||
|
||||
copyState: function(state) {
|
||||
var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
|
||||
php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
|
||||
if (state.curState == html) cur = htmlNew;
|
||||
else if (state.curState == php) cur = phpNew;
|
||||
else cur = CodeMirror.copyState(state.curMode, state.curState);
|
||||
return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
|
||||
curClose: state.curClose, mode: state.mode,
|
||||
pending: state.pending};
|
||||
},
|
||||
|
||||
token: dispatch,
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
|
||||
(state.curMode == phpMode && /^\?>/.test(textAfter)))
|
||||
return htmlMode.indent(state.html, textAfter);
|
||||
return state.curMode.indent(state.curState, textAfter);
|
||||
},
|
||||
|
||||
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,24 +0,0 @@
|
||||
Copyright (c) 2011, Ubalo, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Ubalo, Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL UBALO, INC BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,200 +0,0 @@
|
||||
CodeMirror.defineMode("ruby", function(config, parserConfig) {
|
||||
function wordObj(words) {
|
||||
var o = {};
|
||||
for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
|
||||
return o;
|
||||
}
|
||||
var keywords = wordObj([
|
||||
"alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
|
||||
"elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
|
||||
"redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
|
||||
"until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
|
||||
"caller", "lambda", "proc", "public", "protected", "private", "require", "load",
|
||||
"require_relative", "extend", "autoload"
|
||||
]);
|
||||
var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
|
||||
"catch", "loop", "proc", "begin"]);
|
||||
var dedentWords = wordObj(["end", "until"]);
|
||||
var matching = {"[": "]", "{": "}", "(": ")"};
|
||||
var curPunc;
|
||||
|
||||
function chain(newtok, stream, state) {
|
||||
state.tokenize.push(newtok);
|
||||
return newtok(stream, state);
|
||||
}
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
curPunc = null;
|
||||
if (stream.sol() && stream.match("=begin") && stream.eol()) {
|
||||
state.tokenize.push(readBlockComment);
|
||||
return "comment";
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
var ch = stream.next();
|
||||
if (ch == "`" || ch == "'" || ch == '"' ||
|
||||
(ch == "/" && !stream.eol() && stream.peek() != " ")) {
|
||||
return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
|
||||
} else if (ch == "%") {
|
||||
var style, embed = false;
|
||||
if (stream.eat("s")) style = "atom";
|
||||
else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
|
||||
else if (stream.eat(/[wxqr]/)) style = "string";
|
||||
var delim = stream.eat(/[^\w\s]/);
|
||||
if (!delim) return "operator";
|
||||
if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
|
||||
return chain(readQuoted(delim, style, embed, true), stream, state);
|
||||
} else if (ch == "#") {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else if (ch == "<" && stream.eat("<")) {
|
||||
stream.eat("-");
|
||||
stream.eat(/[\'\"\`]/);
|
||||
var match = stream.match(/^\w+/);
|
||||
stream.eat(/[\'\"\`]/);
|
||||
if (match) return chain(readHereDoc(match[0]), stream, state);
|
||||
return null;
|
||||
} else if (ch == "0") {
|
||||
if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
|
||||
else if (stream.eat("b")) stream.eatWhile(/[01]/);
|
||||
else stream.eatWhile(/[0-7]/);
|
||||
return "number";
|
||||
} else if (/\d/.test(ch)) {
|
||||
stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
|
||||
return "number";
|
||||
} else if (ch == "?") {
|
||||
while (stream.match(/^\\[CM]-/)) {}
|
||||
if (stream.eat("\\")) stream.eatWhile(/\w/);
|
||||
else stream.next();
|
||||
return "string";
|
||||
} else if (ch == ":") {
|
||||
if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
|
||||
if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
|
||||
stream.eatWhile(/[\w\?]/);
|
||||
return "atom";
|
||||
} else if (ch == "@") {
|
||||
stream.eat("@");
|
||||
stream.eatWhile(/[\w\?]/);
|
||||
return "variable-2";
|
||||
} else if (ch == "$") {
|
||||
stream.next();
|
||||
stream.eatWhile(/[\w\?]/);
|
||||
return "variable-3";
|
||||
} else if (/\w/.test(ch)) {
|
||||
stream.eatWhile(/[\w\?]/);
|
||||
if (stream.eat(":")) return "atom";
|
||||
return "ident";
|
||||
} else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
|
||||
curPunc = "|";
|
||||
return null;
|
||||
} else if (/[\(\)\[\]{}\\;]/.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
} else if (ch == "-" && stream.eat(">")) {
|
||||
return "arrow";
|
||||
} else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
|
||||
stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
|
||||
return "operator";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function tokenBaseUntilBrace() {
|
||||
var depth = 1;
|
||||
return function(stream, state) {
|
||||
if (stream.peek() == "}") {
|
||||
depth--;
|
||||
if (depth == 0) {
|
||||
state.tokenize.pop();
|
||||
return state.tokenize[state.tokenize.length-1](stream, state);
|
||||
}
|
||||
} else if (stream.peek() == "{") {
|
||||
depth++;
|
||||
}
|
||||
return tokenBase(stream, state);
|
||||
};
|
||||
}
|
||||
function readQuoted(quote, style, embed, unescaped) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && (unescaped || !escaped)) {
|
||||
state.tokenize.pop();
|
||||
break;
|
||||
}
|
||||
if (embed && ch == "#" && !escaped && stream.eat("{")) {
|
||||
state.tokenize.push(tokenBaseUntilBrace(arguments.callee));
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
function readHereDoc(phrase) {
|
||||
return function(stream, state) {
|
||||
if (stream.match(phrase)) state.tokenize.pop();
|
||||
else stream.skipToEnd();
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
function readBlockComment(stream, state) {
|
||||
if (stream.sol() && stream.match("=end") && stream.eol())
|
||||
state.tokenize.pop();
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: [tokenBase],
|
||||
indented: 0,
|
||||
context: {type: "top", indented: -config.indentUnit},
|
||||
continuedLine: false,
|
||||
lastTok: null,
|
||||
varList: false};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) state.indented = stream.indentation();
|
||||
var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
|
||||
if (style == "ident") {
|
||||
var word = stream.current();
|
||||
style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
|
||||
: /^[A-Z]/.test(word) ? "tag"
|
||||
: (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
|
||||
: "variable";
|
||||
if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
|
||||
else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
|
||||
else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
|
||||
kwtype = "indent";
|
||||
}
|
||||
if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
|
||||
if (curPunc == "|") state.varList = !state.varList;
|
||||
|
||||
if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
|
||||
state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
|
||||
else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
|
||||
state.context = state.context.prev;
|
||||
|
||||
if (stream.eol())
|
||||
state.continuedLine = (curPunc == "\\" || style == "operator");
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0);
|
||||
var ct = state.context;
|
||||
var closing = ct.type == matching[firstChar] ||
|
||||
ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
|
||||
return ct.indented + (closing ? 0 : config.indentUnit) +
|
||||
(state.continuedLine ? config.indentUnit : 0);
|
||||
},
|
||||
electricChars: "}de" // enD and rescuE
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-ruby", "ruby");
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var Kludges = parserConfig.htmlMode ? {
|
||||
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: {},
|
||||
implicitlyClosed: {},
|
||||
contextGrabbers: {},
|
||||
doNotIndent: {},
|
||||
allowUnquoted: false,
|
||||
allowMissing: false
|
||||
};
|
||||
var alignCDATA = parserConfig.alignCDATA;
|
||||
|
||||
// Return variables for tokenizers
|
||||
var tagName, type;
|
||||
|
||||
function inText(stream, state) {
|
||||
function chain(parser) {
|
||||
state.tokenize = parser;
|
||||
return parser(stream, state);
|
||||
}
|
||||
|
||||
var ch = stream.next();
|
||||
if (ch == "<") {
|
||||
if (stream.eat("!")) {
|
||||
if (stream.eat("[")) {
|
||||
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
|
||||
else return null;
|
||||
}
|
||||
else if (stream.match("--")) return chain(inBlock("comment", "-->"));
|
||||
else if (stream.match("DOCTYPE", true, true)) {
|
||||
stream.eatWhile(/[\w\._\-]/);
|
||||
return chain(doctype(1));
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
else if (stream.eat("?")) {
|
||||
stream.eatWhile(/[\w\._\-]/);
|
||||
state.tokenize = inBlock("meta", "?>");
|
||||
return "meta";
|
||||
}
|
||||
else {
|
||||
type = stream.eat("/") ? "closeTag" : "openTag";
|
||||
stream.eatSpace();
|
||||
tagName = "";
|
||||
var c;
|
||||
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
|
||||
state.tokenize = inTag;
|
||||
return "tag";
|
||||
}
|
||||
}
|
||||
else if (ch == "&") {
|
||||
var ok;
|
||||
if (stream.eat("#")) {
|
||||
if (stream.eat("x")) {
|
||||
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
|
||||
} else {
|
||||
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
|
||||
}
|
||||
} else {
|
||||
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
|
||||
}
|
||||
return ok ? "atom" : "error";
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[^&<]/);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function inTag(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
|
||||
state.tokenize = inText;
|
||||
type = ch == ">" ? "endTag" : "selfcloseTag";
|
||||
return "tag";
|
||||
}
|
||||
else if (ch == "=") {
|
||||
type = "equals";
|
||||
return null;
|
||||
}
|
||||
else if (/[\'\"]/.test(ch)) {
|
||||
state.tokenize = inAttribute(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
|
||||
return "word";
|
||||
}
|
||||
}
|
||||
|
||||
function inAttribute(quote) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
if (stream.next() == quote) {
|
||||
state.tokenize = inTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function inBlock(style, terminator) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
if (stream.match(terminator)) {
|
||||
state.tokenize = inText;
|
||||
break;
|
||||
}
|
||||
stream.next();
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
function doctype(depth) {
|
||||
return function(stream, state) {
|
||||
var ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == "<") {
|
||||
state.tokenize = doctype(depth + 1);
|
||||
return state.tokenize(stream, state);
|
||||
} else if (ch == ">") {
|
||||
if (depth == 1) {
|
||||
state.tokenize = inText;
|
||||
break;
|
||||
} else {
|
||||
state.tokenize = doctype(depth - 1);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
return "meta";
|
||||
};
|
||||
}
|
||||
|
||||
var curState, setStyle;
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
}
|
||||
|
||||
function pushContext(tagName, startOfLine) {
|
||||
var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
|
||||
curState.context = {
|
||||
prev: curState.context,
|
||||
tagName: tagName,
|
||||
indent: curState.indented,
|
||||
startOfLine: startOfLine,
|
||||
noIndent: noIndent
|
||||
};
|
||||
}
|
||||
function popContext() {
|
||||
if (curState.context) curState.context = curState.context.prev;
|
||||
}
|
||||
|
||||
function element(type) {
|
||||
if (type == "openTag") {
|
||||
curState.tagName = tagName;
|
||||
return cont(attributes, endtag(curState.startOfLine));
|
||||
} else if (type == "closeTag") {
|
||||
var err = false;
|
||||
if (curState.context) {
|
||||
if (curState.context.tagName != tagName) {
|
||||
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
|
||||
popContext();
|
||||
}
|
||||
err = !curState.context || curState.context.tagName != tagName;
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
}
|
||||
if (err) setStyle = "error";
|
||||
return cont(endclosetag(err));
|
||||
}
|
||||
return cont();
|
||||
}
|
||||
function endtag(startOfLine) {
|
||||
return function(type) {
|
||||
if (type == "selfcloseTag" ||
|
||||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
|
||||
maybePopContext(curState.tagName.toLowerCase());
|
||||
return cont();
|
||||
}
|
||||
if (type == "endTag") {
|
||||
maybePopContext(curState.tagName.toLowerCase());
|
||||
pushContext(curState.tagName, startOfLine);
|
||||
return cont();
|
||||
}
|
||||
return cont();
|
||||
};
|
||||
}
|
||||
function endclosetag(err) {
|
||||
return function(type) {
|
||||
if (err) setStyle = "error";
|
||||
if (type == "endTag") { popContext(); return cont(); }
|
||||
setStyle = "error";
|
||||
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);}
|
||||
if (type == "endTag" || type == "selfcloseTag") return pass();
|
||||
setStyle = "error";
|
||||
return cont(attributes);
|
||||
}
|
||||
function attribute(type) {
|
||||
if (type == "equals") return cont(attvalue, attributes);
|
||||
if (!Kludges.allowMissing) setStyle = "error";
|
||||
return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
|
||||
}
|
||||
function attvalue(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
|
||||
setStyle = "error";
|
||||
return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
|
||||
}
|
||||
function attvaluemaybe(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
else return pass();
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
state.startOfLine = true;
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
|
||||
setStyle = type = tagName = null;
|
||||
var style = state.tokenize(stream, state);
|
||||
state.type = type;
|
||||
if ((style || type) && style != "comment") {
|
||||
curState = state;
|
||||
while (true) {
|
||||
var comb = state.cc.pop() || element;
|
||||
if (comb(type || style)) break;
|
||||
}
|
||||
}
|
||||
state.startOfLine = false;
|
||||
return setStyle || style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter, fullLine) {
|
||||
var context = state.context;
|
||||
if ((state.tokenize != inTag && state.tokenize != inText) ||
|
||||
context && context.noIndent)
|
||||
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
|
||||
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
||||
if (context && /^<\//.test(textAfter))
|
||||
context = context.prev;
|
||||
while (context && !context.startOfLine)
|
||||
context = context.prev;
|
||||
if (context) return context.indent + indentUnit;
|
||||
else return 0;
|
||||
},
|
||||
|
||||
compareStates: function(a, b) {
|
||||
if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
|
||||
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
||||
if (!ca || !cb) return ca == cb;
|
||||
if (ca.tagName != cb.tagName) return false;
|
||||
}
|
||||
},
|
||||
|
||||
electricChars: "/"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("application/xml", "xml");
|
||||
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
|
||||
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
|
||||
@@ -5,7 +5,7 @@ Early version of the web based IDE which allows for creation of websites in the
|
||||
|
||||
###Features you'd expect
|
||||
* Context aware code highlighting
|
||||
* Supports HTML, CSS, JavaScript, PHP & Ruby
|
||||
* Supports HTML, CSS, LESS, JavaScript, CoffeeScript, PHP & Ruby
|
||||
* Smart tab key system (selected text indents line)
|
||||
* File manager
|
||||
* Find & replace/replace all
|
||||
@@ -44,17 +44,16 @@ Early version of the web based IDE which allows for creation of websites in the
|
||||
$ git clone git@github:mattpass/ICEcoder
|
||||
```
|
||||
|
||||
####Step 2: Upload all the files
|
||||
####Step 2: Upload the files (Linux or Windows hosting OK)
|
||||
```
|
||||
Linux or Windows hosting OK
|
||||
Upload to a new sub-dir URL such as yourdomain.com/_coder
|
||||
Set public write permissions on the lib/settings.php file
|
||||
Set public write permissions on the lib/config.php file
|
||||
```
|
||||
|
||||
####Step 3: Start coding
|
||||
```
|
||||
Visit the sub-dir URL in your browser and enter a password
|
||||
Now you're setup, auto-logged in too and ready to code
|
||||
Now you're setup, auto-logged in and ready to code!
|
||||
```
|
||||
|
||||
Suitable for commercial & non-commercial projects, just let me know if it's useful to you and any cool customisations you make to it. I take no responsibility for anything, your usage is all down to you.
|
||||
|
||||
89
editor.php
@@ -1,3 +1,4 @@
|
||||
<?php include("lib/config.php");?>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html style="margin: 0">
|
||||
@@ -5,14 +6,8 @@
|
||||
<title>CodeMirror 2: ICE Coders Editor of Choice</title>
|
||||
<?php include("lib/settings.php");?>
|
||||
<link rel="stylesheet" href="<?php echo $codeMirrorDir; ?>/lib/codemirror.css">
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/codemirror.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/clike/clike.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/css/css.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/javascript/javascript.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/xml/xml.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/coffeescript/coffeescript.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/php/php.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/mode/ruby/ruby.js"></script>
|
||||
<!--codemirror-compressed.js includes codemirror.js plus the mode files for clike, coffeescript, css, javascript, less, php, ruby & xml //-->
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/codemirror-compressed.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/util/searchcursor.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/util/match-highlighter.js"></script>
|
||||
<script src="<?php echo $codeMirrorDir; ?>/lib/util/foldcode.js"></script>
|
||||
@@ -24,11 +19,11 @@ if ($theme=="default") {
|
||||
}
|
||||
?>
|
||||
<style type="text/css">
|
||||
.CodeMirror {position: absolute; width: 0; background-color: #fff}
|
||||
.CodeMirror {position: absolute; width: 0; background-color: #fff; top: 0px; z-index: 1}
|
||||
.CodeMirror-scroll {width: 100px; height: 100px;}
|
||||
.cm-s-visible {display: block; top: 0}
|
||||
.cm-s-hidden {display: none; top: 4000px}
|
||||
.cm-s-activeLine {background: #002 !important;}
|
||||
.cm-s-activeLine {background: #000 !important;}
|
||||
// Make sure this next one remains the 5th item, updated with JS
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if ($visibleTabs) {?>\21e5<?;};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555}
|
||||
@@ -36,7 +31,63 @@ span.CodeMirror-matchhighlight {background: #555}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="margin: 0" onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
<body onLoad="top.ICEcoder.updateFileFolderCount()" style="color: #fff; margin: 0" onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
|
||||
<div style="margin: 32px 43px; font-family: arial; font-size: 10px; color: #dddddd">
|
||||
<?php if($_SESSION['userLevel'] == 10) {
|
||||
echo '<div style="float: left; margin-right: 50px">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">server</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Server name, OS & IP:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['SERVER_NAME'].' '.$_SERVER['SERVER_SOFTWARE'].' '.$_SERVER['SERVER_ADDR'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Root:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['DOCUMENT_ROOT'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">PHP version:</span><br>'.PHP_EOL;
|
||||
echo phpversion().'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Date & time:</span><br>'.PHP_EOL;
|
||||
echo '<span id="serverDT"></span><br><br><br>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
|
||||
echo '<div style="float: left">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">files</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Last 10 files opened:</span><br>'.PHP_EOL;
|
||||
$last10FilesArray = explode(",",$last10Files);
|
||||
for ($i=0;$i<count($last10FilesArray);$i++) {
|
||||
if ($last10Files=="") {
|
||||
echo '[none]<br><br>';
|
||||
} else {
|
||||
echo '<a style="cursor:pointer" onClick="top.ICEcoder.openFile(top.fullPath+\''.str_replace("|","/",$last10FilesArray[$i]).'\')">';
|
||||
echo str_replace("|","/",$last10FilesArray[$i]);
|
||||
echo '</a><br>'.PHP_EOL;
|
||||
if ($i==count($last10FilesArray)-1) {echo '<br>'.PHP_EOL;};
|
||||
}
|
||||
}
|
||||
echo '<span style="color:#888">File & folder count:</span><br>'.PHP_EOL;
|
||||
echo '<div id="fileFolderCounts"></div><br><br><br>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
|
||||
echo '<div style="clear: both">'.PHP_EOL;
|
||||
echo '<h2 style="color: rgba(0,198,255,0.7)">your device</h2>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Browser:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['HTTP_USER_AGENT'].'<br><br>'.PHP_EOL;
|
||||
echo '<span style="color:#888">Your IP:</span><br>'.PHP_EOL;
|
||||
echo $_SERVER['REMOTE_ADDR'].PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
}; ?>
|
||||
<script>
|
||||
var nDT=<?php echo time()*1000;?>;
|
||||
setInterval(function(){
|
||||
var s=(new Date(nDT+=1e3)+'').split(' '),
|
||||
d=s[2]*1,
|
||||
t=s[4].split(':'),
|
||||
p=t[0]>11?'pm':'am',
|
||||
e=d%20==1|d>30?'st':d%20==2?'nd':d%20==3?'rd':'th';
|
||||
t[0]=--t[0]%12+1;
|
||||
if (document.getElementById('serverDT')) {
|
||||
document.getElementById('serverDT').innerHTML=[s[0],d+e,s[1],s[3],t.join(':')+p].join(' ');
|
||||
}
|
||||
},1000);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function createNewCMInstance(num) {
|
||||
@@ -48,16 +99,16 @@ function createNewCMInstance(num) {
|
||||
mode: "application/x-httpd-php",
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
indentUnit: 4,
|
||||
tabSize: 4,
|
||||
indentUnit: top.tabWidth,
|
||||
tabSize: top.tabWidth,
|
||||
indentWithTabs: true,
|
||||
electricChars: false,
|
||||
onCursorActivity: function() {
|
||||
top.ICEcoder.getCaretPosition();
|
||||
top.ICEcoder.updateCharDisplay();
|
||||
window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab], null);
|
||||
if(!window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].somethingSelected()) {
|
||||
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].getCursor().line, "cm-s-activeLine");
|
||||
window['cM'+num].setLineClass(top.ICEcoder['cMActiveLine'+num], null);
|
||||
if(!window['cM'+num].somethingSelected()) {
|
||||
top.ICEcoder['cMActiveLine'+num] = window['cM'+num].setLineClass(window['cM'+num].getCursor().line, "cm-s-activeLine");
|
||||
}
|
||||
window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].matchHighlight("CodeMirror-matchhighlight");
|
||||
top.ICEcoder.cssColorPreview();
|
||||
@@ -79,7 +130,7 @@ function createNewCMInstance(num) {
|
||||
}
|
||||
},
|
||||
onKeyEvent: function(instance, e) {
|
||||
top.ICEcoder.redoChangedContent(event);
|
||||
top.ICEcoder.redoChangedContent(e);
|
||||
top.ICEcoder.findReplace('find',true,false);
|
||||
top.ICEcoder.getCaretPosition();
|
||||
top.ICEcoder.updateCharDisplay();
|
||||
@@ -95,7 +146,7 @@ function createNewCMInstance(num) {
|
||||
if(top.ICEcoder.tagString.slice(0,1)=="/"||top.ICEcoder.tagString.slice(0,1)=="?") {
|
||||
canDoEndTag=false;
|
||||
}
|
||||
if (!top.ICEcoder.codeAssist||fileName.indexOf(".js")>0||fileName.indexOf(".css")>0) {
|
||||
if (!top.ICEcoder.codeAssist||fileName.indexOf(".js")>0||fileName.indexOf(".css")>0||fileName.indexOf(".less")>0) {
|
||||
canDoEndTag=false;
|
||||
}
|
||||
contentType = top.ICEcoder.caretLocType;
|
||||
@@ -131,7 +182,7 @@ function createNewCMInstance(num) {
|
||||
});
|
||||
|
||||
// Now create the active line for this CodeMirror object
|
||||
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(0, "cm-s-activeLine");
|
||||
top.ICEcoder['cMActiveLine'+num] = window['cM'+num].setLineClass(0, "cm-s-activeLine");
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
21
files.php
@@ -74,6 +74,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
if( $this_file != "." && $this_file != ".." && $bannedFile == false) {
|
||||
if( is_dir("$directory/$this_file") ) {
|
||||
// Directory
|
||||
$dirCount++;
|
||||
$dirRep = str_replace("\\","/",$directory);
|
||||
$link = str_replace("[link]", "$dirRep/" . urlencode($this_file), $return_link);
|
||||
$link = str_replace("//","/",$link);
|
||||
@@ -99,6 +100,8 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
}
|
||||
} else {
|
||||
// File
|
||||
$fileCount++;
|
||||
$fileBytes+=filesize($link);
|
||||
// Get extension (prefix 'ext-' to prevent invalid classes from extensions that begin with numbers)
|
||||
$ext = "ext-" . substr($this_file, strrpos($this_file, ".") + 1);
|
||||
$dirRep = str_replace("\\","/",$directory);
|
||||
@@ -119,7 +122,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
}
|
||||
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\"><a nohref onMouseOver=\"top.ICEcoder.overFileFolder('file','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('file','')\" style=\"position: relative; left:-22px; cursor: pointer\"> <span id=\"".str_replace("/","|",str_replace($docRoot,"",$link))."\">" . htmlspecialchars($this_file) . "</span> ".$fileAtts."</a></li>";
|
||||
} else {
|
||||
$fileAtts = "<img src=\"images/file-manager-icons/padlock.png\" style=\"cursor: pointer\" onClick=\"alert('Sorry, you need higher admin level rights to view.')\">";
|
||||
$fileAtts = "<img src=\"images/padlock.png\" style=\"cursor: pointer\" onClick=\"alert('Sorry, you need higher admin level rights to view.')\">";
|
||||
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\" style=\"cursor: default\"><span style=\"position: relative; left:-22px; color: #888\"> [HIDDEN] ".$fileAtts."</span></li>";
|
||||
}
|
||||
}
|
||||
@@ -127,7 +130,12 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
|
||||
}
|
||||
$fileManager .= "</ul>";
|
||||
}
|
||||
return $fileManager;
|
||||
$varOutput = "";
|
||||
if ($dirCount) {$varOutput .= "top.ICEcoder.dirCount+=".$dirCount.";".PHP_EOL;};
|
||||
if ($fileCount) {$varOutput .= "top.ICEcoder.fileCount+=".$fileCount.";".PHP_EOL;};
|
||||
if ($fileBytes) {$varOutput .= "top.ICEcoder.fileBytes+=".$fileBytes.";".PHP_EOL;};
|
||||
// After outputting the fileManager, output the JS vars, but only the first time
|
||||
return $fileManager."<script>if (top.ICEcoder.dirCount==0) {".PHP_EOL.$varOutput."}</script>";
|
||||
}
|
||||
|
||||
// For PHP4 compatibility
|
||||
@@ -146,12 +154,19 @@ function php4_scandir($dir) {
|
||||
<head>
|
||||
<title>ICE Coder File Manager</title>
|
||||
<link rel="stylesheet" type="text/css" href="lib/files.css">
|
||||
|
||||
<script src="lib/coder.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<body onLoad="top.ICEcoder.fileManager()" onDblClick="top.ICEcoder.openFile()" onKeyDown="return top.ICEcoder.interceptKeys('files', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
|
||||
<div onClick="top.ICEcoder.refreshFileManager()" class="refresh"><img src="images/file-manager-icons/refresh.png"></div>
|
||||
<div onClick="top.ICEcoder.refreshFileManager()" class="refresh"><img src="images/refresh.png"></div>
|
||||
<script>
|
||||
top.ICEcoder.dirCount = 0;
|
||||
top.ICEcoder.fileCount = 0;
|
||||
top.ICEcoder.fileBytes = 0;
|
||||
</script>
|
||||
<?php
|
||||
|
||||
echo fileManager($_SERVER['DOCUMENT_ROOT'], "[link]");
|
||||
?>
|
||||
|
||||
|
||||
BIN
images/blank.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/file-manager-icons.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 954 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 342 B |
|
Before Width: | Height: | Size: 386 B |
BIN
images/full-screen.gif
Normal file
|
After Width: | Height: | Size: 73 B |
BIN
images/ice-coder.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
images/restored-screen.gif
Normal file
|
After Width: | Height: | Size: 65 B |
|
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 551 B |
35
index.php
@@ -10,12 +10,18 @@ if (!$allowedIP) {
|
||||
header('Location: /');
|
||||
};
|
||||
|
||||
// Test for latest CodeMirror version
|
||||
if ($testcMVersion) {
|
||||
$cMLatestVer = json_encode(file_get_contents("http://codemirror.net/latest-version.txt"));
|
||||
$cMLatestVer = rtrim(ltrim($cMLatestVer,"\""),"\"\\n");
|
||||
if ($cMThisVer<$cMLatestVer) {
|
||||
echo '<script>alert(\'Code Mirror '.$cMLatestVer.' now released\n\nPlease upgrade\');</script>';
|
||||
// Check for updates of ICEcoder & CodeMirror
|
||||
if ($checkUpdates) {
|
||||
$ICEcoderLatestVer = json_encode(file_get_contents("http://icecoder.net/latest-version.txt"));
|
||||
$ICEcoderLatestVer = rtrim(ltrim($ICEcoderLatestVer,"\""),"\"\\n");
|
||||
if (ltrim($versionNo,"v ")<ltrim($ICEcoderLatestVer,"v ")) {
|
||||
echo '<script>alert(\'ICEcoder '.$ICEcoderLatestVer.' now released\n\nPlease upgrade\');</script>';
|
||||
} else {
|
||||
$cMLatestVer = json_encode(file_get_contents("http://codemirror.net/latest-version.txt"));
|
||||
$cMLatestVer = rtrim(ltrim($cMLatestVer,"\""),"\"\\n");
|
||||
if ($cMThisVer<$cMLatestVer) {
|
||||
echo '<script>alert(\'Code Mirror '.$cMLatestVer.' now released\n\nPlease upgrade\');</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -30,6 +36,7 @@ if ($testcMVersion) {
|
||||
shortURLStarts = "<?php echo $shortURLStarts;?>";
|
||||
theme = "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;};?>";
|
||||
tabsIndent = <?php if ($tabsIndent) {echo 'true';} else {echo 'false';};?>;
|
||||
tabWidth = <?php echo $tabWidth; ?>;
|
||||
<?
|
||||
$docRoot = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']);
|
||||
if (strrpos($docRoot,"/")==strlen($docRoot)-1) {$docRoot = substr($docRoot,0,strlen($docRoot)-1);};
|
||||
@@ -43,9 +50,9 @@ window.onbeforeunload = function() {
|
||||
}
|
||||
}
|
||||
|
||||
lastOpenFiles = [<?php
|
||||
if ($lastOpenedFiles!="" && $_SESSION['userLevel'] == 10) {
|
||||
$openFilesArray = explode(",",$lastOpenedFiles);
|
||||
previousFiles = [<?php
|
||||
if ($previousFiles!="" && $_SESSION['userLevel'] == 10) {
|
||||
$openFilesArray = explode(",",$previousFiles);
|
||||
for ($i=0;$i<count($openFilesArray);$i++) {
|
||||
echo "'".$openFilesArray[$i]."'";
|
||||
if ($i<count($openFilesArray)-1) {echo ",";};
|
||||
@@ -86,14 +93,15 @@ lastOpenFiles = [<?php
|
||||
<a href="javascript:top.ICEcoder.renameFile(top.ICEcoder.rightClickedFile)" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">Rename</a>
|
||||
<a href="javascript:window.open(top.ICEcoder.rightClickedFile.substr((top.ICEcoder.rightClickedFile.indexOf(shortURLStarts)+top.shortURLStarts.length),top.ICEcoder.rightClickedFile.length))" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">View Webpage</a>
|
||||
</span>
|
||||
<a href="javascript:top.ICEcoder.zipIt(top.ICEcoder.rightClickedFile)" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">Zip It!</a>
|
||||
</div>
|
||||
|
||||
<div id="header" class="header" onContextMenu="return false">
|
||||
<div class="plugins" id="pluginsContainer">
|
||||
<?php echo $pluginsDisplay; ?>
|
||||
</div>
|
||||
<div class="version"><?php echo $versionNo;?></div>
|
||||
<img src="images/ice-coder.gif" class="logo" onClick="ICEcoder.helpScreen('show')" onContextMenu="ICEcoder.settingsScreen('show')">
|
||||
<div class="version"><?php echo $versionNo;?></div><img src="images/full-screen.gif" id="screenMode" class="screenModeIcon" onClick="top.ICEcoder.fullScreenSwitcher()">
|
||||
<img src="images/ice-coder.png" class="logo" onClick="ICEcoder.helpScreen('show')" onContextMenu="ICEcoder.settingsScreen('show')">
|
||||
</div>
|
||||
|
||||
<div id="files" class="files" onMouseOver="ICEcoder.changeFilesW('expand')" onMouseOut="ICEcoder.changeFilesW('contract'); top.document.getElementById('fileMenu').style.display='none';">
|
||||
@@ -115,7 +123,7 @@ lastOpenFiles = [<?php
|
||||
<a nohref title="Rename" onClick="ICEcoder.fMIcon('rename')"><img src="images/rename.png" alt="Rename" id="fMRename" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
<a nohref title="View" onClick="ICEcoder.fMIcon('view')"><img src="images/view.png" alt="View" id="fMView" style="margin: 9px 0 0 5px; opacity: 0.3"></a>
|
||||
</div>
|
||||
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/file-manager-icons/padlock.png" id="fmLock" class="lock"></a>
|
||||
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/padlock.png" id="fmLock" class="lock"></a>
|
||||
</div>
|
||||
<iframe id="filesFrame" class="frame" name="ff" src="files.php" style="opacity: 0" onLoad="this.style.opacity='1'"></iframe>
|
||||
<div class="serverMessage" id="serverMessage"></div>
|
||||
@@ -125,7 +133,7 @@ lastOpenFiles = [<?php
|
||||
<div id="tabsBar" class="tabsBar" onContextMenu="return false">
|
||||
<?php
|
||||
for ($i=1;$i<=10;$i++) {
|
||||
echo '<div id="tab'.$i.'" class="tab" onClick="if(ICEcoder.canSwitchTabs) {ICEcoder.switchTab('.$i.')} else {ICEcoder.canSwitchTabs=true}"></div>';
|
||||
echo '<div id="tab'.$i.'" class="tab" draggable="true" onClick="if(ICEcoder.canSwitchTabs) {ICEcoder.switchTab('.$i.')} else {ICEcoder.canSwitchTabs=true}"></div>';
|
||||
}
|
||||
?><div class="newTab" onClick="ICEcoder.newTab()"><img src="images/nav-new.png"></div>
|
||||
</div>
|
||||
@@ -175,6 +183,7 @@ lastOpenFiles = [<?php
|
||||
</div>
|
||||
|
||||
<script>
|
||||
ICEcoder.initAliases();
|
||||
ICEcoder.setLayout('dontSetEditor');
|
||||
</script>
|
||||
|
||||
|
||||
@@ -72,13 +72,14 @@ h2 {font-size: 18px; font-weight: normal; color: #fff}
|
||||
100%{ width:100%;}
|
||||
}
|
||||
|
||||
.header {position: absolute; display: inline-block; width: 100%; height: 40px; background-color: #fff; text-align: right; z-index: 2}
|
||||
.header {position: absolute; display: inline-block; top: 0; left: 0; width: 100%; height: 40px; background-color: #fff; text-align: right; z-index: 2}
|
||||
.header .plugins {position: absolute; display: inline-block; left: 15px; top: 3px}
|
||||
.header .plugins img {position: relative; display: inline-block; margin-right: 15px}
|
||||
.header .screenModeIcon {position: absolute; top: 5px; right: 178px; cursor: pointer}
|
||||
.header .version {position: relative; display: inline-block; margin-top: 25px; font-size: 10px; color: #bbb}
|
||||
.header .logo {position: relative; margin: 5px 10px 0 5px; cursor: pointer}
|
||||
|
||||
.files {position: absolute; display: inline-block; height: 100%; width: 250px; background-color: #444; background-image: url('../images/files-arrow.gif'); background-repeat: no-repeat; background-position: 100% 50%; overflow: hidden; z-index: 1;
|
||||
.files {position: absolute; display: inline-block; top: 0; left: 0; height: 100%; width: 250px; background-color: #444; background-image: url('../images/files-arrow.gif'); background-repeat: no-repeat; background-position: 100% 50%; overflow: hidden; z-index: 1;
|
||||
-webkit-box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
box-shadow: 0 0 10px 4px rgba(0,0,0,0.4);
|
||||
@@ -153,7 +154,7 @@ h2 {font-size: 18px; font-weight: normal; color: #fff}
|
||||
}
|
||||
|
||||
.fileMenu {position: absolute; display: none; left: 0; top: 0; background-color: #333; z-index: 10}
|
||||
.fileMenu a {display: block; padding: 2px 5px; background-color: #444; color: #eee; text-decoration: none}
|
||||
.fileMenu a {display: block; padding: 2px 5px; background-color: #333; color: #eee; text-decoration: none}
|
||||
.fileMenu a:hover {background-color: #666}
|
||||
|
||||
.screenContainer {position: absolute; display: table; width: 100%; height: 100%; top: 0; left: 0; text-align: center}
|
||||
|
||||
254
lib/coder.js
@@ -1,9 +1,3 @@
|
||||
// ICE coder by Matt Pass
|
||||
// Free to use it for your own purposes, commercial or not, just let me know of any cool uses or customisations. :)
|
||||
// No warranty or liability accepted for anything, all responsibility of use is your own.
|
||||
// Latest version: https://github.com/mattpass/ICEcoder
|
||||
// Twitter: @mattpass
|
||||
|
||||
var ICEcoder = {
|
||||
// Define settings
|
||||
filesW: 250, // Initial width of the files pane
|
||||
@@ -29,19 +23,23 @@ var ICEcoder = {
|
||||
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
|
||||
dragSrcEl: null, // Tab element being dragged
|
||||
|
||||
// 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(login) {
|
||||
// Set our aliases
|
||||
initAliases: function() {
|
||||
var aliasArray = ["header","files","account","accountLogin","fmLock","filesFrame","editor","tabsBar","findBar","content","footer","nestValid","nestDisplay","charDisplay"];
|
||||
|
||||
// Create our ID aliases
|
||||
for (var i=0;i<aliasArray.length;i++) {
|
||||
ICEcoder[aliasArray[i]] = top.document.getElementById(aliasArray[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// On load, set the layout and get the nest location
|
||||
init: function(login) {
|
||||
// Set layout & the nest location
|
||||
ICEcoder.setLayout();
|
||||
|
||||
@@ -53,6 +51,16 @@ var ICEcoder = {
|
||||
top.document.getElementById('accountLogin').style.top = "-50px";
|
||||
setTimeout(function() {top.document.getElementById('accountLoginContainer').style.display = "none";},300);
|
||||
}
|
||||
|
||||
// Add drag based events to our tabs
|
||||
var tabs = document.querySelectorAll('.tab');
|
||||
[].forEach.call(tabs, function(tab) {
|
||||
// not used: dragenter, dragleave
|
||||
tab.addEventListener('dragstart', ICEcoder.handleDragStart, false);
|
||||
tab.addEventListener('dragover', ICEcoder.handleDragOver, false);
|
||||
tab.addEventListener('drop', ICEcoder.handleDrop, false);
|
||||
tab.addEventListener('dragend', ICEcoder.handleDragEnd, false);
|
||||
});
|
||||
},
|
||||
|
||||
// Set our layout according to the browser size
|
||||
@@ -65,23 +73,29 @@ 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 = 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";
|
||||
this.header.style.width = this.tabsBar.style.width = this.findBar.style.width = winW + "px";
|
||||
this.files.style.width = this.accountLogin.style.width = this.editor.style.left = this.filesW + "px";
|
||||
this.account.style.height = this.accountH + "px";
|
||||
this.fmLock.style.marginLeft = (this.filesW-27) + "px";
|
||||
this.filesFrame.style.height = (winH-headerH-accountH-footerH) + "px";
|
||||
|
||||
// If we need to set the editor sizes
|
||||
if (!dontSetEditor) {
|
||||
editor.style.width = ICEcoder.content.style.width = (winW-this.filesW) + "px";
|
||||
this.editor.style.width = ICEcoder.content.style.width = (winW-this.filesW) + "px";
|
||||
ICEcoder.content.style.height = (winH-headerH-footerH-tabsBarH-findBarH) + "px";
|
||||
|
||||
// Resize the CodeMirror instances to match the window size
|
||||
document.all ? strCSS = 'rules' : strCSS = 'cssRules';
|
||||
cMCSS = ICEcoder.content.contentWindow.document;
|
||||
cMCSS.styleSheets[2][strCSS][1].style['width'] = ICEcoder.content.style.width;
|
||||
cMCSS.styleSheets[2][strCSS][1].style['height'] = ICEcoder.content.style.height;
|
||||
cMCSS.styleSheets[2][strCSS][2].style['width'] = ICEcoder.content.style.width;
|
||||
cMCSS = ICEcoder.content.contentWindow.document.styleSheets[2];
|
||||
cMCSS.rules ? strCSS = 'rules' : strCSS = 'cssRules';
|
||||
for(var i=0;i<cMCSS[strCSS].length;i++) {
|
||||
if(cMCSS[strCSS][i].selectorText==".CodeMirror-scroll") {
|
||||
cMCSS[strCSS][i].style['width'] = ICEcoder.content.style.width;
|
||||
cMCSS[strCSS][i].style['height'] = ICEcoder.content.style.height;
|
||||
}
|
||||
if(cMCSS[strCSS][i].selectorText==".cm-s-visible") {
|
||||
cMCSS[strCSS][i].style['width'] = ICEcoder.content.style.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -89,9 +103,9 @@ var ICEcoder = {
|
||||
contentCleanUp: function() {
|
||||
var fileName, cM, content;
|
||||
|
||||
// If it's not a JS, CoffeeScript Ruby or CSS file, replace & and our temp </textarea> value
|
||||
// If it's not a JS, CoffeeScript Ruby, CSS or LESS file, replace & and our temp </textarea> value
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0) {
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0 && fileName.indexOf(".less")<0) {
|
||||
cM = ICEcoder.getcMInstance();
|
||||
content = cM.getValue();
|
||||
content = content.replace(/<ICEcoder:\/:textarea>/g,'</textarea>');
|
||||
@@ -182,7 +196,7 @@ var ICEcoder = {
|
||||
ICEcoder.nestDisplay.innerHTML = "";
|
||||
if ("undefined" != typeof ICEcoder.openFiles[ICEcoder.selectedTab-1]) {
|
||||
fileName = ICEcoder.openFiles[ICEcoder.selectedTab-1];
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0&&
|
||||
if (fileName.indexOf(".js")<0 && fileName.indexOf(".coffee")<0 && fileName.indexOf(".rb")<0 && fileName.indexOf(".css")<0 && fileName.indexOf(".less")<0 &&
|
||||
(nestCheck.indexOf("include(")==-1)&&(nestCheck.indexOf("include_once(")==-1)&&
|
||||
(nestCheck.indexOf("<html")>-1||nestCheck.indexOf("<body")>-1)) {
|
||||
|
||||
@@ -372,13 +386,18 @@ var ICEcoder = {
|
||||
|
||||
// Reset all tabs to be without a highlight and then highlight the selected
|
||||
redoTabHighlight: function(selectedTab) {
|
||||
var bgVPos, tColor;
|
||||
var cM, bgVPos, tColor, fileLink;
|
||||
|
||||
cM = ICEcoder.getcMInstance();
|
||||
for(var i=1;i<=ICEcoder.changedContent.length;i++) {
|
||||
if (document.getElementById('closeTabButton'+i)) {
|
||||
ICEcoder.changedContent[i-1]==1 ? document.getElementById('closeTabButton'+i).style.backgroundColor = "#b00" : document.getElementById('closeTabButton'+i).style.backgroundColor = "rgba(255,255,255,0.3)";
|
||||
ICEcoder.changedContent[i-1]==1 && cM.historySize().undo>0 ? document.getElementById('closeTabButton'+i).style.backgroundColor = "#b00" : document.getElementById('closeTabButton'+i).style.backgroundColor = "rgba(255,255,255,0.3)";
|
||||
}
|
||||
i==selectedTab ? tColor = "#000" : tColor = "#fff";
|
||||
if ("undefined" != typeof top.ICEcoder.openFiles[i-1] && top.ICEcoder.openFiles[i-1] != "/[NEW]") {
|
||||
fileLink = top.ICEcoder.filesFrame.contentWindow.document.getElementById(top.ICEcoder.openFiles[i-1].replace(/\//g,"|"));
|
||||
i==selectedTab ? fileLink.style.backgroundColor = "#4499dd" : fileLink.style.backgroundColor = "rgba(255,255,255,0.15)";
|
||||
}
|
||||
document.getElementById('tab'+i).style.color = tColor;
|
||||
i==selectedTab ? bgVPos = -22 : bgVPos = 0;
|
||||
document.getElementById('tab'+i).style.backgroundPosition = "0 "+bgVPos+"px";
|
||||
@@ -400,7 +419,6 @@ var ICEcoder = {
|
||||
|
||||
cM = ICEcoder.getcMInstance('new');
|
||||
ICEcoder.switchTab(ICEcoder.openFiles.length);
|
||||
ICEcoder.content.style.visibility='visible';
|
||||
|
||||
cM.setLineClass(ICEcoder['cMActiveLine'+ICEcoder.selectedTab], null);
|
||||
ICEcoder['cMActiveLine'+ICEcoder.selectedTab] = cM.setLineClass(0, "cm-s-activeLine");
|
||||
@@ -426,7 +444,7 @@ var ICEcoder = {
|
||||
// Add a new value ready to indicate if this content has been changed
|
||||
top.ICEcoder.changedContent.push(0);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
},
|
||||
|
||||
// Create a new tab for a file
|
||||
@@ -450,7 +468,7 @@ var ICEcoder = {
|
||||
ICEcoder.caretPos=cM.getValue().length;
|
||||
ICEcoder.getNestLocation();
|
||||
// Nesting is OK if at the end of the file we have no nests left, or it's a JS, Ruby or CSS file
|
||||
if (ICEcoder.htmlTagArray.length==0||fileName.indexOf(".js")>0||fileName.indexOf(".coffee")>0||fileName.indexOf(".rb")>0||fileName.indexOf(".css")>0) {
|
||||
if (ICEcoder.htmlTagArray.length==0||fileName.indexOf(".js")>0||fileName.indexOf(".coffee")>0||fileName.indexOf(".rb")>0||fileName.indexOf(".css")>0||fileName.indexOf(".less")>0) {
|
||||
ICEcoder.nestValid.style.backgroundColor="#0b0";
|
||||
ICEcoder.nestValid.innerHTML = "Nesting OK";
|
||||
} else {
|
||||
@@ -503,6 +521,7 @@ var ICEcoder = {
|
||||
if (fileName.indexOf(".coffee")>0) {caretLocType="CoffeeScript"};
|
||||
if (fileName.indexOf(".rb")>0) {caretLocType="Ruby"};
|
||||
if (fileName.indexOf(".css")>0) {caretLocType="CSS"};
|
||||
if (fileName.indexOf(".less")>0) {caretLocType="LESS"};
|
||||
|
||||
ICEcoder.caretLocType = caretLocType;
|
||||
|
||||
@@ -559,7 +578,6 @@ var ICEcoder = {
|
||||
|
||||
// hide the content area if we have no tabs open
|
||||
if (ICEcoder.openFiles.length==0) {
|
||||
top.document.getElementById('content').style.visibility = "hidden";
|
||||
top.ICEcoder.fMIconVis('fMView',0.3);
|
||||
} else {
|
||||
// Switch the mode & the tab
|
||||
@@ -570,7 +588,7 @@ var ICEcoder = {
|
||||
top.ICEcoder.changedContent.splice(closeTabNum-1,1);
|
||||
top.parent.ICEcoder.redoTabHighlight(ICEcoder.selectedTab);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
}
|
||||
// Lastly, stop it from trying to also switch tab
|
||||
top.ICEcoder.canSwitchTabs=false;
|
||||
@@ -698,7 +716,19 @@ var ICEcoder = {
|
||||
|
||||
// Select or deselect file
|
||||
selectDeselectFile: function(action,file) {
|
||||
action == "select" ? file.style.backgroundColor="#888" : file.style.backgroundColor="transparent";
|
||||
var isOpen;
|
||||
|
||||
top.ICEcoder.openFiles.indexOf(file.id.replace(/\|/g,"/")) > -1 ? isOpen = true : isOpen = false;
|
||||
|
||||
if (top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1] == file.id.replace(/\|/g,"/")) {
|
||||
file.style.backgroundColor="#4499dd";
|
||||
} else {
|
||||
if (action=="select") {
|
||||
file.style.backgroundColor="#888";
|
||||
} else {
|
||||
isOpen ? file.style.backgroundColor = "rgba(255,255,255,0.15)" : file.style.backgroundColor="transparent";
|
||||
}
|
||||
}
|
||||
action == "select" ? file.style.color="#fff" : file.style.color="#eee";
|
||||
},
|
||||
|
||||
@@ -722,7 +752,11 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// Open a file on demand
|
||||
openFile: function() {
|
||||
openFile: function(fileLink) {
|
||||
if (fileLink) {
|
||||
top.ICEcoder.thisFileFolderLink=fileLink;
|
||||
top.ICEcoder.thisFileFolderType="file";
|
||||
}
|
||||
if (top.ICEcoder.thisFileFolderLink!="" && top.ICEcoder.thisFileFolderType=="file") {
|
||||
var shortURL, canOpenFile;
|
||||
|
||||
@@ -794,7 +828,7 @@ var ICEcoder = {
|
||||
top.ICEcoder.serverQueue("add","lib/file-control.php?action=rename&file="+renamedFile+"&oldFileName="+top.ICEcoder.rightClickedFile.replace(/\|/g,"/"));
|
||||
top.ICEcoder.serverMessage('<b>Renaming to</b><br>'+renamedFile);
|
||||
|
||||
top.ICEcoder.setLastOpenedFiles();
|
||||
top.ICEcoder.setPreviousFiles();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -965,11 +999,11 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// Go to a specific line number
|
||||
goToLine: function() {
|
||||
goToLine: function(lineNo) {
|
||||
var cM;
|
||||
|
||||
cM = ICEcoder.getcMInstance();
|
||||
cM.setCursor(document.getElementById('goToLineNo').value-1);
|
||||
cM.setCursor(lineNo ? lineNo-1 : document.getElementById('goToLineNo').value-1);
|
||||
cM.focus();
|
||||
return false;
|
||||
},
|
||||
@@ -989,6 +1023,8 @@ var ICEcoder = {
|
||||
cM.setOption("mode","ruby");
|
||||
} else if (fileName.indexOf('.css')>0) {
|
||||
cM.setOption("mode","css");
|
||||
} else if (fileName.indexOf('.less')>0) {
|
||||
cM.setOption("mode","less");
|
||||
} else {
|
||||
cM.setOption("mode","application/x-httpd-php");
|
||||
}
|
||||
@@ -1001,7 +1037,7 @@ var ICEcoder = {
|
||||
|
||||
lockIcon = top.document.getElementById('fmLock');
|
||||
ICEcoder.lockedNav ? ICEcoder.lockedNav = false : ICEcoder.lockedNav = true;
|
||||
ICEcoder.lockedNav ? lockIcon.src="images/file-manager-icons/padlock.png" : lockIcon.src="images/file-manager-icons/padlock-disabled.png";
|
||||
ICEcoder.lockedNav ? lockIcon.src="images/padlock.png" : lockIcon.src="images/padlock-disabled.png";
|
||||
},
|
||||
|
||||
// Determine the CodeMirror instance we're using on demand
|
||||
@@ -1092,12 +1128,12 @@ var ICEcoder = {
|
||||
getMouseXY: function(e) {
|
||||
var tempX, tempY, scrollTop, IE;
|
||||
|
||||
IE = document.all ? true : false;
|
||||
if (!IE) {document.captureEvents(Event.MOUSEMOVE)};
|
||||
IE = !e.pageX ? true : false;
|
||||
if (IE) {
|
||||
top.ICEcoder.mouseX = event.clientX + document.body.scrollLeft;
|
||||
top.ICEcoder.mouseY = event.clientY + document.body.scrollTop;
|
||||
top.ICEcoder.mouseX = e.clientX + document.body.scrollLeft;
|
||||
top.ICEcoder.mouseY = e.clientY + document.body.scrollTop;
|
||||
} else {
|
||||
document.captureEvents(Event.MOUSEMOVE);
|
||||
top.ICEcoder.mouseX = e.pageX;
|
||||
top.ICEcoder.mouseY = e.pageY;
|
||||
}
|
||||
@@ -1397,31 +1433,27 @@ var ICEcoder = {
|
||||
top.ICEcoder.dontSelect = true;
|
||||
},
|
||||
|
||||
// Set the current lastOpenedFiles in the settings file
|
||||
setLastOpenedFiles: function() {
|
||||
var lastOpenedFiles;
|
||||
// Set the current previousFiles in the settings file
|
||||
setPreviousFiles: function() {
|
||||
var previousFiles;
|
||||
|
||||
lastOpenedFiles = "";
|
||||
previousFiles = "";
|
||||
// Generate a comma seperated list
|
||||
for (var i=0;i<top.ICEcoder.openFiles.length;i++) {
|
||||
if (top.ICEcoder.openFiles[i]!="" && top.ICEcoder.openFiles[i].indexOf("[NEW]")==-1) {
|
||||
lastOpenedFiles += top.ICEcoder.openFiles[i].replace(/\//g,"|");
|
||||
if (i<top.ICEcoder.openFiles.length-1) {lastOpenedFiles += ","};
|
||||
previousFiles += top.ICEcoder.openFiles[i].replace(/\//g,"|");
|
||||
if (i<top.ICEcoder.openFiles.length-1) {previousFiles += ","};
|
||||
}
|
||||
}
|
||||
if (lastOpenedFiles!="") {
|
||||
// Then send through to the settings page to update setting
|
||||
top.ICEcoder.serverQueue("add","lib/settings.php?saveFiles="+lastOpenedFiles);
|
||||
} else {
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
}
|
||||
if (previousFiles=="") {previousFiles="CLEAR"};
|
||||
// Then send through to the settings page to update setting
|
||||
top.ICEcoder.serverQueue("add","lib/settings.php?saveFiles="+previousFiles);
|
||||
},
|
||||
|
||||
// Opens the last files we had open
|
||||
autoOpenFiles: function() {
|
||||
for (var i=0;i<=top.lastOpenFiles.length-1;i++) {
|
||||
top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.fullPath+top.lastOpenFiles[i].replace('|','/');
|
||||
for (var i=0;i<=top.previousFiles.length-1;i++) {
|
||||
top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=top.fullPath+top.previousFiles[i].replace('|','/');
|
||||
top.ICEcoder.thisFileFolderType='file';
|
||||
top.ICEcoder.openFile();
|
||||
}
|
||||
@@ -1437,6 +1469,10 @@ var ICEcoder = {
|
||||
top.document.getElementById('loadingMask').style.visibility = "hidden";
|
||||
if (loginAttempt) {
|
||||
if (loginAttempt == "loginOK") {
|
||||
if (top.ICEcoder.openFiles.length==0) {
|
||||
top.ICEcoder.content.style.visibility='visible';
|
||||
top.ICEcoder.content.src = "editor.php";
|
||||
}
|
||||
top.document.getElementById('accountLogin').style.top = "-50px";
|
||||
setTimeout(function() {top.document.getElementById('accountLoginContainer').style.display = "none";},300);
|
||||
} else {
|
||||
@@ -1463,7 +1499,7 @@ var ICEcoder = {
|
||||
},
|
||||
|
||||
// Update the settings used when we make a change to them
|
||||
useNewSettings: function(themeURL,tabsIndent,codeAssist,lockedNav,visibleTabs,refreshFM) {
|
||||
useNewSettings: function(themeURL,tabsIndent,codeAssist,lockedNav,visibleTabs,tabWidth,refreshFM) {
|
||||
var styleNode, strCSS, cMCSS;
|
||||
|
||||
// Add new stylesheet for selected theme
|
||||
@@ -1489,10 +1525,17 @@ var ICEcoder = {
|
||||
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'] = '" "';
|
||||
console.log('TO FIX');
|
||||
//cMCSS = ICEcoder.content.contentWindow.document;
|
||||
//cMCSS.styleSheets[2].rules ? strCSS = 'rules' : strCSS = 'cssRules';
|
||||
//document.settings.visibleTabs.checked ? document.styleSheets[2][strCSS][5].style['content'] = '"\\21e5"' : document.styleSheets[2][strCSS][5].style['content'] = '" "';
|
||||
|
||||
|
||||
top.tabWidth = tabWidth;
|
||||
for (var i=0;i<ICEcoder.cMInstances.length;i++) {
|
||||
ICEcoder.content.contentWindow['cM'+ICEcoder.cMInstances[i]].setOption("indentUnit", top.tabWidth);
|
||||
ICEcoder.content.contentWindow['cM'+ICEcoder.cMInstances[i]].setOption("tabSize", top.tabWidth);
|
||||
}
|
||||
|
||||
// Finally, refresh the file manager if we need to
|
||||
if (refreshFM) {top.ICEcoder.refreshFileManager()};
|
||||
@@ -1502,5 +1545,98 @@ var ICEcoder = {
|
||||
updateResultsDisplay: function(showHide) {
|
||||
ICEcoder.findReplace('find',true,false);
|
||||
document.getElementById('results').style.display = showHide == "show" ? 'inline-block' : 'none';
|
||||
},
|
||||
|
||||
// Show file & folder count in server info screen
|
||||
updateFileFolderCount: function() {
|
||||
var fileText, dirText, unitSize, unitText, dContainer;
|
||||
|
||||
top.ICEcoder.dirCount > 1 ? dirText = "folders" : dirText = "folder";
|
||||
top.ICEcoder.fileCount > 1 ? fileText = "files" : fileText = "file";
|
||||
// Change into kilobytes
|
||||
unitSize = Math.ceil(top.ICEcoder.fileBytes/1024);
|
||||
unitText = "kb";
|
||||
// Maybe we should show in megabytes?
|
||||
if (unitSize >= 1024) {
|
||||
unitSize = unitSize / 1024;
|
||||
unitText = "mb";
|
||||
}
|
||||
// Update the display
|
||||
dContainer = top.ICEcoder.content.contentWindow.document.getElementById('fileFolderCounts');
|
||||
if (dContainer) {
|
||||
dContainer.innerHTML = top.ICEcoder.fileCount+" "+fileText+", "+top.ICEcoder.dirCount+" "+dirText+"<br>~ "+unitSize+" "+unitText;
|
||||
}
|
||||
},
|
||||
|
||||
// Toggle full screen on/off
|
||||
fullScreenSwitcher: function() {
|
||||
var screenIcon;
|
||||
|
||||
screenIcon = top.document.getElementById('screenMode');
|
||||
|
||||
// Future use
|
||||
if ("undefined" != typeof document.cancelFullScreen) {
|
||||
document.fullScreen ? document.cancelFullScreen() : document.body.requestFullScreen();
|
||||
// Moz specific
|
||||
} else if ("undefined" != typeof document.mozCancelFullScreen) {
|
||||
document.mozFullScreen ? document.mozCancelFullScreen() : document.body.mozRequestFullScreen();
|
||||
// Chrome specific
|
||||
} else if ("undefined" != typeof document.webkitCancelFullScreen) {
|
||||
document.webkitIsFullScreen ? document.webkitCancelFullScreen() : document.body.webkitRequestFullScreen();
|
||||
}
|
||||
|
||||
screenIcon.src.indexOf("images/full-screen.gif") > -1 ? screenIcon.src = "images/restored-screen.gif" : screenIcon.src = "images/full-screen.gif";
|
||||
|
||||
},
|
||||
|
||||
// Pass target file/folder to Zip It!
|
||||
zipIt: function(tgt) {
|
||||
tgt=tgt.replace(top.fullPath+"/","").replace(/\//g,"|");
|
||||
top.ICEcoder.filesFrame.contentWindow.frames['fileControl'].location.href="plugins/zip-it/index.php?zip="+tgt;
|
||||
},
|
||||
|
||||
// Tab dragging start
|
||||
handleDragStart: function(e) {
|
||||
this.style.opacity = '0.2';
|
||||
ICEcoder.dragSrcEl = this;
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/html', this.innerHTML);
|
||||
},
|
||||
|
||||
// Tab dragging over tabs
|
||||
handleDragOver: function(e) {
|
||||
if (e.preventDefault) {e.preventDefault()}
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
return false;
|
||||
},
|
||||
|
||||
// Tab dropping on target
|
||||
handleDrop: function(e) {
|
||||
if (e.stopPropagation) {e.stopPropagation()}
|
||||
if (ICEcoder.dragSrcEl != this) {
|
||||
ICEcoder.dragSrcEl.innerHTML = this.innerHTML.split(" ")[0] + ICEcoder.dragSrcEl.innerHTML.substr(ICEcoder.dragSrcEl.innerHTML.indexOf(" "),ICEcoder.dragSrcEl.innerHTML.length);
|
||||
this.innerHTML = e.dataTransfer.getData('text/html').split(" ")[0] + this.innerHTML.substr(this.innerHTML.indexOf(" "),this.innerHTML.length);
|
||||
var dragID = ICEcoder.dragSrcEl.id.substr(3,ICEcoder.dragSrcEl.id.length)*1;
|
||||
var dropID = this.id.substr(3,this.id.length)*1;
|
||||
if(dragID==top.ICEcoder.selectedTab) {
|
||||
var a; // array value
|
||||
var b = dragID-1;
|
||||
var c = dropID-1;
|
||||
|
||||
// Swap values for switched tabs in these arrays
|
||||
a = [ICEcoder.changedContent, ICEcoder.openFiles, ICEcoder.openFileMDTs, ICEcoder.cMInstances];
|
||||
for (var i=0;i<a.length;i++) {
|
||||
a[i][b]=[a[i][c],a[i][c]=a[i][b]][0];
|
||||
}
|
||||
|
||||
top.ICEcoder.switchTab(dropID);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Tab drag ending
|
||||
handleDragEnd: function(e) {
|
||||
this.style.opacity = '1';
|
||||
}
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
$versionNo = "v 0.6.9";
|
||||
$versionNo = "v 0.7.5";
|
||||
$codeMirrorDir = "CodeMirror-2.25";
|
||||
$cMThisVer = 2.25;
|
||||
$tabsIndent = true;
|
||||
$testcMVersion = false;
|
||||
$checkUpdates = false;
|
||||
$openLastFiles = true;
|
||||
$findFilesExclude = array("_coder",".doc",".gif",".jpg",".jpeg",".pdf",".png",".swf",".xml",".zip");
|
||||
$codeAssist = true;
|
||||
@@ -16,8 +16,10 @@ $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")
|
||||
array("Zip It!","images/zip-it.png","margin-top: 3px","plugins/zip-it/?zip=|&exclude=.doc,.gif,.jpg,.jpeg,.pdf,.png,.swf,.xml,.zip","fileControl:<b>Zipping Open Files</b>","10")
|
||||
);
|
||||
$theme = "default";
|
||||
$lastOpenedFiles = "";
|
||||
$tabWidth = 4;
|
||||
$previousFiles = "";
|
||||
$last10Files = "";
|
||||
?>
|
||||
@@ -2,8 +2,8 @@
|
||||
<?php
|
||||
|
||||
// Establish the full file path reference
|
||||
$file=$_GET['file'];
|
||||
if (isset($_GET['saveType'])) {$saveType = $_GET['saveType'];};
|
||||
$file=strClean($_GET['file']);
|
||||
if (isset($_GET['saveType'])) {$saveType = strClean($_GET['saveType']);};
|
||||
$docRoot = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']);
|
||||
|
||||
// Not done the first time we are on the save loop (ie, before the form posting reload)
|
||||
@@ -66,7 +66,7 @@ if ($_GET['action']=="newFolder") {
|
||||
// If we're due to rename a file...
|
||||
if ($_GET['action']=="rename") {
|
||||
if ($_SESSION['userLevel'] > 0 && is_writable($_GET['oldFileName'])) {
|
||||
rename($_GET['oldFileName'],$docRoot.$file);
|
||||
rename(strClean($_GET['oldFileName']),$docRoot.$file);
|
||||
// Reload file manager
|
||||
$fileName = substr($file,strrpos($file,"/")+1);
|
||||
$fileLoc = substr($file,0,strrpos($file,"/"));
|
||||
@@ -74,7 +74,7 @@ if ($_GET['action']=="rename") {
|
||||
echo '<script>top.ICEcoder.selectedFiles=[];top.ICEcoder.updateFileManagerList(\'rename\',\''.$fileLoc.'\',\''.$fileName.'\');top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="rename";</script>';
|
||||
} else {
|
||||
if (!is_writable($_GET['oldFileName'])) {
|
||||
echo "<script>alert('Sorry, cannot rename\\n".$_GET['oldFileName']."');</script>";
|
||||
echo "<script>alert('Sorry, cannot rename\\n".strClean($_GET['oldFileName'])."');</script>";
|
||||
} else {
|
||||
echo '<script>alert(\'Sorry, you need to be logged in to rename\');</script>';
|
||||
}
|
||||
@@ -133,7 +133,7 @@ if ($_GET['action']=="save") {
|
||||
if (isset($_POST['contents'])) {
|
||||
if ($_SESSION['userLevel'] > 0) {
|
||||
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
|
||||
$file = $_POST['newFileName'];
|
||||
$file = strClean($_POST['newFileName']);
|
||||
}
|
||||
$saveFile = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']).$file;
|
||||
$saveFile = str_replace("//","/",$saveFile);
|
||||
@@ -238,7 +238,7 @@ if (action=="load") {
|
||||
}
|
||||
</script>
|
||||
|
||||
<form name="saveFile" action="file-control.php?action=save&file=<?php if (isset($file)) {echo $file;}; if (isset($_GET['fileMDT']) && $_GET['fileMDT']!="undefined") {echo "&fileMDT=".$_GET['fileMDT'];};?>" method="POST">
|
||||
<form name="saveFile" action="file-control.php?action=save&file=<?php if (isset($file)) {echo $file;}; if (isset($_GET['fileMDT']) && $_GET['fileMDT']!="undefined") {echo "&fileMDT=".numClean($_GET['fileMDT']);};?>" method="POST">
|
||||
<textarea name="contents"></textarea>
|
||||
<input type="hidden" name="newFileName" value="">
|
||||
</form>
|
||||
@@ -263,7 +263,7 @@ if (action=="save") {
|
||||
if ("undefined" != typeof newFileName) {
|
||||
top.ICEcoder.serverMessage('<b>Saving</b><br>'+newFileName);
|
||||
}
|
||||
document.saveFile.contents.innerHTML = top.document.getElementById('saveTemp1').value;
|
||||
document.saveFile.contents.value = top.document.getElementById('saveTemp1').value;
|
||||
document.saveFile.submit();
|
||||
} else {
|
||||
top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);
|
||||
|
||||
@@ -29,36 +29,43 @@ body {margin: 0; overflow: auto}
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fileManager span {font-family: helvetica, arial, swiss, verdana;}
|
||||
.fileManager a {color: #eee; text-decoration: none;}
|
||||
.fileManager .open {font-style: italic;}
|
||||
.fileManager .closed {font-style: normal;}
|
||||
.fileManager .pft-directory {list-style-image: url(../images/file-manager-icons/directory.png);}
|
||||
.fileManager li {margin-left: 15px;}
|
||||
.fileManager span {font-family: helvetica, arial, swiss, verdana}
|
||||
.fileManager a {color: #eee; text-decoration: none}
|
||||
.fileManager .open {font-style: italic}
|
||||
.fileManager .closed {font-style: normal}
|
||||
.fileManager .pft-directory, .fileManager .pft-file {list-style-image: url(../images/blank.gif)}
|
||||
.fileManager li {margin-left: 15px}
|
||||
|
||||
/* Default file */
|
||||
.fileManager LI.pft-file { list-style-image: url(../images/file-manager-icons/file.png); }
|
||||
.fileManager LI.pft-directory:before, .fileManager LI.pft-file:before {
|
||||
position: absolute; display: block; width: 16px; height: 16px; content: ""; margin-top: -2px; margin-left: -23px; background:url(../images/file-manager-icons.png) no-repeat 0 0;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) { /* hacked for chrome and safari */
|
||||
.fileManager LI.pft-directory:before, .fileManager LI.pft-file:before {
|
||||
margin-top: -19px;
|
||||
}
|
||||
}
|
||||
.fileManager LI.pft-file:before {background-position: -16px 0}
|
||||
|
||||
/* Additional file types */
|
||||
.fileManager LI.ext-coffee { list-style-image: url(../images/file-manager-icons/coffee.png); }
|
||||
.fileManager LI.ext-css { list-style-image: url(../images/file-manager-icons/css.png); }
|
||||
.fileManager LI.ext-doc { list-style-image: url(../images/file-manager-icons/doc.png); }
|
||||
.fileManager LI.ext-gif { list-style-image: url(../images/file-manager-icons/gif.png); }
|
||||
.fileManager LI.ext-htm { list-style-image: url(../images/file-manager-icons/html.png); }
|
||||
.fileManager LI.ext-html { list-style-image: url(../images/file-manager-icons/html.png); }
|
||||
.fileManager LI.ext-jpg { list-style-image: url(../images/file-manager-icons/jpg.png); }
|
||||
.fileManager LI.ext-jpeg { list-style-image: url(../images/file-manager-icons/jpg.png); }
|
||||
.fileManager LI.ext-js { list-style-image: url(../images/file-manager-icons/js.png); }
|
||||
/*.fileManager LI.ext-pdf { list-style-image: url(../images/file-manager-icons/pdf.png); } */
|
||||
.fileManager LI.ext-php { list-style-image: url(../images/file-manager-icons/php.png); }
|
||||
.fileManager LI.ext-png { list-style-image: url(../images/file-manager-icons/png.png); }
|
||||
.fileManager LI.ext-rb { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-rbx { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-rhtml { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
.fileManager LI.ext-ruby { list-style-image: url(../images/file-manager-icons/ruby.png); }
|
||||
/*.fileManager LI.ext-sql { list-style-image: url(../images/file-manager-icons/sql.png); } */
|
||||
/*.fileManager LI.ext-swf { list-style-image: url(../images/file-manager-icons/swf.png); } */
|
||||
.fileManager LI.ext-txt { list-style-image: url(../images/file-manager-icons/txt.png); }
|
||||
/*.fileManager LI.ext-xls { list-style-image: url(../images/file-manager-icons/xls.png); } */
|
||||
/*.fileManager LI.ext-xml { list-style-image: url(../images/file-manager-icons/xml.png); } */
|
||||
/*.fileManager LI.ext-zip { list-style-image: url(../images/file-manager-icons/zip.png); } */
|
||||
.fileManager LI.ext-coffee:before {background-position: -32px 0}
|
||||
.fileManager LI.ext-css:before {background-position: -48px 0}
|
||||
.fileManager LI.ext-gif:before {background-position: -64px 0}
|
||||
.fileManager LI.ext-htm:before {background-position: -80px 0}
|
||||
.fileManager LI.ext-html:before {background-position: -80px 0}
|
||||
.fileManager LI.ext-jpg:before {background-position: -96px 0}
|
||||
.fileManager LI.ext-jpeg:before {background-position: -96px 0}
|
||||
.fileManager LI.ext-js:before {background-position: -112px 0}
|
||||
/*.fileManager LI.ext-pdf:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-less:before {background-position: -128px 0}
|
||||
.fileManager LI.ext-php:before {background-position: -144px 0}
|
||||
.fileManager LI.ext-png:before {background-position: -160px 0}
|
||||
.fileManager LI.ext-rb:before {background-position: -176px 0}
|
||||
.fileManager LI.ext-rbx:before {background-position: -176px 0}
|
||||
.fileManager LI.ext-rhtml:before {background-position: -176px 0}
|
||||
.fileManager LI.ext-ruby:before {background-position: -176px 0}
|
||||
/*.fileManager LI.ext-sql:before {background-position: -???px 0} */
|
||||
/*.fileManager LI.ext-swf:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-txt:before {background-position: -192px 0}
|
||||
/*.fileManager LI.ext-xml:before {background-position: -???px 0} */
|
||||
.fileManager LI.ext-zip:before {background-position: -208px 0}
|
||||
@@ -22,7 +22,7 @@
|
||||
var resultsDisplay = "";
|
||||
var foundTabArray = [];
|
||||
var startTab = top.ICEcoder.selectedTab;
|
||||
var rExp = new RegExp("<?php echo $_GET['find']; ?>","g");
|
||||
var rExp = new RegExp("<?php echo strClean($_GET['find']); ?>","g");
|
||||
for (var i=1;i<=top.ICEcoder.openFiles.length;i++) {
|
||||
top.ICEcoder.switchTab(i);
|
||||
var cM = top.ICEcoder.getcMInstance();
|
||||
@@ -46,7 +46,7 @@ if (foundTabArray.length==0) {alert('No matches found')};
|
||||
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('title').innerHTML = "'<?php echo strClean($_GET['find']); ?>' found in "+foundTabArray.length+" file"+plural;
|
||||
document.getElementById('results').innerHTML = resultsDisplay;
|
||||
|
||||
var gotoTab = function(tab) {
|
||||
|
||||
@@ -8,19 +8,12 @@
|
||||
<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>
|
||||
<script src="../<?php echo $codeMirrorDir; ?>/lib/codemirror-compressed.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
.CodeMirror {position: absolute; width: 0; background-color: #fff; font-family: monospace}
|
||||
.CodeMirror-scroll {height: 220px; width: 420px; overflow: hidden}
|
||||
.cm-s-visible {display: block; top: 0}
|
||||
.cm-s-hidden {display: none; top: 4000px}
|
||||
.cm-s-activeLine {background: #002 !important;}
|
||||
// Make sure this next one remains the 5th item, updated with JS
|
||||
.cm-tab:after {position: relative; display: inline-block; width: 0; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if($visibleTabs) {echo '\21e5';};?>";}
|
||||
span.CodeMirror-matchhighlight {background: #555}
|
||||
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000; background: #555; !important}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="editor.css">
|
||||
@@ -61,7 +54,7 @@ for ($i=0;$i<count($themeArray)-1;$i++) {
|
||||
|
||||
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");
|
||||
$peopleArray = array("marijnjh", "maettig", "wimtibackx", "jakubvrana", "_higg_", "yandle", "davidwalshblog", "kuvos", "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) {
|
||||
@@ -79,7 +72,7 @@ for ($i=0;$i<count($themeArray)-1;$i++) {
|
||||
<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="checkUpdates" value="true"<?php if($checkUpdates) {echo ' checked';};?>> check for updates on load<br>
|
||||
<input type="checkbox" onclick="showButton()" name="openLastFiles" value="true"<?php if($openLastFiles) {echo ' checked';};?>> auto open last files on login<br>
|
||||
<br>
|
||||
when finding in files, exclude:<br>
|
||||
@@ -97,7 +90,6 @@ new password <span style="font-size: 10px; color: #888">8 chars</span><br>
|
||||
<input type="password" name="accountPassword" onkeydown="showButton()"><br>
|
||||
confirm password<br>
|
||||
<input type="password" name="confirmPassword" onkeydown="showButton()"><br>
|
||||
<input type="hidden" name="oldPassword" value="<?php echo $accountPassword; ?>">
|
||||
<br>
|
||||
restricted files/folders<br>
|
||||
<input type="text" onkeydown="document.settings.changedFileSettings.value='true';showButton()" name="restrictedFiles" value="<?php for($i=0;$i<=count($restrictedFiles)-1;$i++) {echo $restrictedFiles[$i]; if ($i<count($restrictedFiles)-1) {echo ', ';};}; ?>"><br>
|
||||
@@ -156,11 +148,20 @@ function findSequence(goal) {
|
||||
}
|
||||
return find(1,"1");
|
||||
}</textarea>
|
||||
<br>
|
||||
|
||||
<span style="position: absolute; top: 520px">
|
||||
tab width <span style="font-size: 10px; color: #888">chars</span><br>
|
||||
<input type="text" name="tabWidth" id="tabWidth" style="width: 30px" onkeydown="showButton()" onkeyup="changeTabWidth()" value="<?php echo $tabWidth;?>">
|
||||
</span>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
readOnly: "nocursor",
|
||||
indentUnit: top.tabWidth,
|
||||
tabSize: top.tabWidth,
|
||||
mode: "javascript",
|
||||
theme: "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;}; ?>"
|
||||
});
|
||||
|
||||
@@ -171,13 +172,21 @@ function selectTheme() {
|
||||
editor.setOption("theme", theme);
|
||||
}
|
||||
|
||||
function changeTabWidth() {
|
||||
var tabWidth = document.getElementById("tabWidth").value;
|
||||
editor.setOption("indentUnit", tabWidth);
|
||||
editor.setOption("tabSize", tabWidth);
|
||||
}
|
||||
|
||||
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'] = '" "';
|
||||
console.log('TO FIX');
|
||||
//cMCSS = ICEcoder.content.contentWindow.document;
|
||||
//cMCSS.styleSheets[2].rules ? 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() {
|
||||
|
||||
@@ -12,6 +12,16 @@ function generateHash($plainText,$salt=null) {
|
||||
return $salt.sha1($salt.$plainText);
|
||||
}
|
||||
|
||||
// returns converted entities which have HTML entity equivalents
|
||||
function strClean($var) {
|
||||
return htmlentities($var, ENT_QUOTES, "UTF-8");
|
||||
}
|
||||
|
||||
// returns a number, whole or decimal or null
|
||||
function numClean($var) {
|
||||
return is_numeric($var) ? floatval($var) : false;
|
||||
}
|
||||
|
||||
// Settings are stored in this file
|
||||
include("config.php");
|
||||
|
||||
@@ -19,27 +29,28 @@ include("config.php");
|
||||
if (isset($_POST["theme"]) && $_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
$settingsFile = 'config.php';
|
||||
$settingsContents = file_get_contents($settingsFile);
|
||||
// Replace our lastOpenedFiles var with the the current
|
||||
// Replace our settings vars
|
||||
$repPosStart = strpos($settingsContents,'$tabsIndent');
|
||||
$repPosEnd = strpos($settingsContents,'$lastOpenedFiles');
|
||||
$repPosEnd = strpos($settingsContents,'$previousFiles');
|
||||
|
||||
// Prepare all our vars
|
||||
if ($_POST['tabsIndent']) {$tabsIndent = "true";} else {$tabsIndent = "false";};
|
||||
if ($_POST['testcMVersion']) {$testcMVersion = "true";} else {$testcMVersion = "false";};
|
||||
if ($_POST['checkUpdates']) {$checkUpdates = "true";} else {$checkUpdates = "false";};
|
||||
if ($_POST['openLastFiles']) {$openLastFiles = "true";} else {$openLastFiles = "false";};
|
||||
$findFilesExclude = 'array("'.str_replace(', ','","',$_POST['findFilesExclude']).'")';
|
||||
$findFilesExclude = 'array("'.str_replace(', ','","',strClean($_POST['findFilesExclude'])).'")';
|
||||
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']).'")';
|
||||
if ($_POST['accountPassword']!="") {$accountPassword = generateHash(strClean($_POST['accountPassword']));};
|
||||
$restrictedFiles = 'array("'.str_replace(', ','","',strClean($_POST['restrictedFiles'])).'")';
|
||||
$bannedFiles = 'array("'.str_replace(', ','","',strClean($_POST['bannedFiles'])).'")';
|
||||
$allowedIPs = 'array("'.str_replace(', ','","',strClean($_POST['allowedIPs'])).'")';
|
||||
$plugins = 'array('.PHP_EOL.' array('.PHP_EOL.' '.str_replace('====================','),'.PHP_EOL.' array(',$_POST['plugins']).'))';
|
||||
$theme = $_POST['theme'];
|
||||
$theme = strClean($_POST['theme']);
|
||||
$tabWidth = numClean($_POST['tabWidth']);
|
||||
|
||||
$settingsNew = '$tabsIndent = '.$tabsIndent.';'.PHP_EOL;
|
||||
$settingsNew .= '$testcMVersion = '.$testcMVersion.';'.PHP_EOL;
|
||||
$settingsNew .= '$checkUpdates = '.$checkUpdates.';'.PHP_EOL;
|
||||
$settingsNew .= '$openLastFiles = '.$openLastFiles.';'.PHP_EOL;
|
||||
$settingsNew .= '$findFilesExclude = '.$findFilesExclude.';'.PHP_EOL;
|
||||
$settingsNew .= '$codeAssist = '.$codeAssist.';'.PHP_EOL;
|
||||
@@ -51,25 +62,26 @@ if (isset($_POST["theme"]) && $_POST["theme"] && $_SESSION['userLevel'] == 10) {
|
||||
$settingsNew .= '$allowedIPs = '.$allowedIPs.';'.PHP_EOL;
|
||||
$settingsNew .= '$plugins = '.$plugins.';'.PHP_EOL;
|
||||
$settingsNew .= '$theme = "'.$theme.'";'.PHP_EOL;
|
||||
$settingsNew .= '$tabWidth = '.$tabWidth.';'.PHP_EOL;
|
||||
|
||||
// Compile our new settings
|
||||
$settingsContents = substr($settingsContents,0,$repPosStart).$settingsNew.substr($settingsContents,($repPosEnd),strlen($settingsContents));
|
||||
// Now update the config file
|
||||
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
|
||||
$fh = fopen($settingsFile, 'w') or die("Can't update config file. Please set public write permissions on lib/config.php");
|
||||
fwrite($fh, $settingsContents);
|
||||
fclose($fh);
|
||||
|
||||
// OK, now the config file has been updated, update our current session with new arrays
|
||||
$_SESSION['findFilesExclude'] = $findFilesExclude = explode(", ",$_POST['findFilesExclude']);
|
||||
$_SESSION['restrictedFiles'] = $restrictedFiles = explode(", ",$_POST['restrictedFiles']);
|
||||
$_SESSION['bannedFiles'] = $bannedFiles = explode(", ",$_POST['bannedFiles']);
|
||||
$_SESSION['allowedIPs'] = $allowedIPs = explode(", ",$_POST['allowedIPs']);
|
||||
$_SESSION['findFilesExclude'] = $findFilesExclude = explode(", ",strClean($_POST['findFilesExclude']));
|
||||
$_SESSION['restrictedFiles'] = $restrictedFiles = explode(", ",strClean($_POST['restrictedFiles']));
|
||||
$_SESSION['bannedFiles'] = $bannedFiles = explode(", ",strClean($_POST['bannedFiles']));
|
||||
$_SESSION['allowedIPs'] = $allowedIPs = explode(", ",strClean($_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>";
|
||||
echo "<script>top.ICEcoder.settingsScreen('hide');top.ICEcoder.useNewSettings('".$themeURL."',".$tabsIndent.",".$codeAssist.",".$lockedNav.",".$visibleTabs.",".$tabWidth.",".$refreshFM.");</script>";
|
||||
}
|
||||
|
||||
// Save the currently opened files for next time
|
||||
@@ -77,13 +89,32 @@ if (isset($_GET["saveFiles"]) && $_GET['saveFiles']) {
|
||||
if ($_SESSION['userLevel'] == 10) {
|
||||
$settingsFile = 'config.php';
|
||||
$settingsContents = file_get_contents($settingsFile);
|
||||
// Replace our lastOpenedFiles var with the the current
|
||||
$repPosStart = strpos($settingsContents,'lastOpenedFiles = "')+19;
|
||||
|
||||
// Replace our previousFiles var with the the current
|
||||
$repPosStart = strpos($settingsContents,'previousFiles = "')+18;
|
||||
$repPosEnd = strpos($settingsContents,'";',$repPosStart)-$repPosStart;
|
||||
$settingsContents = substr($settingsContents,0,$repPosStart).$_GET['saveFiles'].substr($settingsContents,($repPosStart+$repPosEnd),strlen($settingsContents));
|
||||
if ($_GET['saveFiles']!="CLEAR") {$saveFiles=strClean($_GET['saveFiles']);} else {$saveFiles="";};
|
||||
$settingsContents1 = substr($settingsContents,0,$repPosStart).$saveFiles.substr($settingsContents,($repPosStart+$repPosEnd),strlen($settingsContents));
|
||||
// Now update the config file
|
||||
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
|
||||
fwrite($fh, $settingsContents);
|
||||
$fh = fopen($settingsFile, 'w') or die("Can't update config file. Please set public write permissions on lib/config.php");
|
||||
fwrite($fh, $settingsContents1);
|
||||
|
||||
// Update our top10Files var?
|
||||
$saveFilesArray = explode(",",$saveFiles);
|
||||
$last10FilesArray = explode(",",$last10Files);
|
||||
for ($i=0;$i<count($saveFilesArray);$i++) {
|
||||
$inLast10Files = in_array($saveFilesArray[$i],$last10FilesArray);
|
||||
if (!$inLast10Files && $saveFilesArray[$i] !="") {
|
||||
$repPosStart = strpos($settingsContents1,'last10Files = "')+16;
|
||||
$repPosEnd = strpos($settingsContents1,'";',$repPosStart)-$repPosStart;
|
||||
if ($last10Files!="") {$commaExtra=",";} else {$commaExtra="";};
|
||||
if (count($last10FilesArray)>=10) {$last10Files=substr($last10Files,0,strrpos($last10Files,','));};
|
||||
$settingsContents2 = substr($settingsContents1,0,$repPosStart).$saveFilesArray[$i].$commaExtra.$last10Files.substr($settingsContents1,($repPosStart+$repPosEnd),strlen($settingsContents1));
|
||||
// Now update the config file
|
||||
$fh = fopen($settingsFile, 'w') or die("Can't update config file. Please set public write permissions on lib/config.php");
|
||||
fwrite($fh, $settingsContents2);
|
||||
}
|
||||
}
|
||||
fclose($fh);
|
||||
}
|
||||
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);</script>';
|
||||
@@ -91,7 +122,7 @@ if (isset($_GET["saveFiles"]) && $_GET['saveFiles']) {
|
||||
|
||||
// Establish our user level
|
||||
if (!isset($_SESSION['userLevel'])) {$_SESSION['userLevel'] = 0;};
|
||||
if(isset($_POST['loginPassword']) && generateHash($_POST['loginPassword'],$accountPassword)==$accountPassword) {$_SESSION['userLevel'] = 10;};
|
||||
if(isset($_POST['loginPassword']) && generateHash(strClean($_POST['loginPassword']),$accountPassword)==$accountPassword) {$_SESSION['userLevel'] = 10;};
|
||||
$_SESSION['userLevel'] = $_SESSION['userLevel'];
|
||||
|
||||
if (!isset($_SESSION['findFilesExclude'])) {$_SESSION['findFilesExclude'] = $findFilesExclude;}
|
||||
@@ -135,7 +166,7 @@ if ((isset($_POST["theme"]) && $_POST["theme"] && $_SESSION['userLevel'] == 10)
|
||||
$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>';
|
||||
$pluginsDisplay .= '<a href="'.$plugins[$i][3].'" title="'.$plugins[$i][0].'" 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
|
||||
@@ -168,6 +199,11 @@ if ((isset($_POST["theme"]) && $_POST["theme"] && $_SESSION['userLevel'] == 10)
|
||||
if ($openLastFiles) {
|
||||
$onLoadExtras .= ";top.ICEcoder.autoOpenFiles()";
|
||||
}
|
||||
|
||||
// Show server data if we're logged in
|
||||
if ($_SESSION['userLevel'] == 10) {
|
||||
$onLoadExtras .= ";top.ICEcoder.content.style.visibility='visible'";
|
||||
}
|
||||
}
|
||||
|
||||
// If we're due to show the settings screen
|
||||
@@ -186,7 +222,7 @@ if ($accountPassword == "" && isset($_GET['settings'])) {
|
||||
<div class="screenContainer">
|
||||
<div class="screenVCenter">
|
||||
<div class="screenCenter">
|
||||
<img src="../images/ice-coder.gif">
|
||||
<img src="../images/ice-coder.png">
|
||||
<div class="version"><?php echo $versionNo;?></div>
|
||||
<form name="settingsUpdate" action="../index.php" method="POST">
|
||||
<input type="password" name="accountPassword" class="accountPassword">
|
||||
@@ -206,13 +242,13 @@ if ($accountPassword == "" && isset($_GET['settings'])) {
|
||||
if ($accountPassword == "" && strpos($_SERVER['PHP_SELF'],"index.php")>0) {
|
||||
// If we're setting a password
|
||||
if (isset($_POST['accountPassword'])) {
|
||||
$password = generateHash($_POST['accountPassword']);
|
||||
$password = generateHash(strClean($_POST['accountPassword']));
|
||||
$settingsFile = 'lib/config.php';
|
||||
$settingsContents = file_get_contents($settingsFile);
|
||||
// Replace our empty password with the one submitted by user
|
||||
$settingsContents = str_replace('$accountPassword = "";','$accountPassword = "'.$password.'";',$settingsContents);
|
||||
// Now update the config file
|
||||
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
|
||||
$fh = fopen($settingsFile, 'w') or die("Can't update config file. Please set public write permissions on lib/config.php");
|
||||
fwrite($fh, $settingsContents);
|
||||
fclose($fh);
|
||||
// Set the session user level
|
||||
@@ -227,7 +263,7 @@ if ($accountPassword == "" && isset($_GET['settings'])) {
|
||||
|
||||
// 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) {
|
||||
if(isset($_POST['loginPassword']) && generateHash(strClean($_POST['loginPassword']),$accountPassword)==$accountPassword) {
|
||||
$loginAttempt = 'loginOK';
|
||||
} else {
|
||||
$loginAttempt = 'loginFailed';
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
top.ICEcoder.serverMessage("<b>Zipping Open Files</b>");
|
||||
</script>
|
||||
<?php
|
||||
// ------------------------------------
|
||||
// backupOpenFiles by Matt Pass
|
||||
// Will backups open files in ICE coder
|
||||
// ------------------------------------
|
||||
|
||||
// If we have no post data for the 1st item, set a form up ready to post back
|
||||
if (!isset($_POST['fileName1'])) {
|
||||
echo '<form name="zipFiles" id="zipFiles" action="index.php" method="POST">'.PHP_EOL;
|
||||
for ($i=1;$i<=10;$i++) {
|
||||
echo '<input type="hidden" name="fileName'.$i.'" id="fName'.$i.'" value="" style="display: none">'.PHP_EOL;
|
||||
echo '<textarea name="fileContent'.$i.'" id="fContent'.$i.'" style="display: none"></textarea>'.PHP_EOL;
|
||||
}
|
||||
echo '</form>'.PHP_EOL;
|
||||
?>
|
||||
<script>
|
||||
// Populate values for file names & contents
|
||||
for (i=1;i<=top.ICEcoder.openFiles.length;i++) {
|
||||
document.getElementById('fName'+i).value = top.ICEcoder.openFiles[i-1];
|
||||
document.getElementById('fContent'+i).value = top.ICEcoder.content.contentWindow['cM'+i].getValue();
|
||||
}
|
||||
if (top.ICEcoder.openFiles.length>0) {
|
||||
document.zipFiles.submit();
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
;} else {
|
||||
// Folder name & filename of the zip
|
||||
$zipItSaveLocation = '../../backups/';
|
||||
$zipItFileName = time().'.zip';
|
||||
|
||||
// Make the dir if it doesn't exist
|
||||
if (!is_dir($zipItSaveLocation)) {
|
||||
mkdir($zipItSaveLocation, 0777);
|
||||
}
|
||||
|
||||
// Start a class
|
||||
Class zipIt {
|
||||
public function zipFilesUp($zipName='') {
|
||||
// OK, if we've got at least one file to add
|
||||
if($_POST['fileName1']!=="") {
|
||||
$zip = new ZipArchive();
|
||||
// Return if we have a problem creating/overwriting our zip
|
||||
if($zip->open($zipName,$overwriteZip ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we're OK to add our string into a new file (incl dirs) in the zip, so do that
|
||||
for($i=1;$i<=10;$i++) {
|
||||
$fName = 'fileName'.$i;
|
||||
if($_POST[$fName]!=="") {
|
||||
$zip->addFromString(ltrim($_POST[$fName],"/"), $_POST['fileContent'.$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
// We've been successful, so return with a positive response
|
||||
return file_exists($zipName);
|
||||
|
||||
} else {
|
||||
// If we had 0 files, return
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the class
|
||||
$zipItDoZip = new zipIt();
|
||||
$zipItAddToZip = $zipItDoZip->zipFilesUp($zipItSaveLocation.$zipItFileName);
|
||||
if (!$zipItAddToZip) {echo '<script>alert("Could not zip files up!");</script>';};
|
||||
;};
|
||||
?>
|
||||
|
||||
<script>
|
||||
top.ICEcoder.serverMessage();
|
||||
top.ICEcoder.serverQueue("del",0);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
74
plugins/zip-it/index.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// -----------------------------------------------
|
||||
// Zip-It! for ICEcoder v0.9.1 by Matt Pass
|
||||
// Will backup requested files/folders in ICEcoder
|
||||
// -----------------------------------------------
|
||||
include("../../lib/settings.php");
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Zip It! for ICEcoder</title>
|
||||
</head>
|
||||
<body>
|
||||
<?
|
||||
$zipItSaveLocation = '../../backups/';
|
||||
if ($_GET['zip']=="|") {$zipItFileName = "root";} else {$zipItFileName = str_replace("|","_",strClean($_GET['zip']));};
|
||||
$zipItFileName .= '-'.time().'.zip';
|
||||
|
||||
if (!is_dir($zipItSaveLocation)) {mkdir($zipItSaveLocation, 0777);}
|
||||
Class zipIt {
|
||||
public function zipFilesUp($zipName='') {
|
||||
$zipFiles = array();
|
||||
$_GET['zip']=="|" ? $zipTgt = "" : $zipTgt = str_replace("|","/",strClean($_GET['zip']));
|
||||
if (strpos($_GET['zip'],"/")!==0) {$zipTgt = "/".$zipTgt;};
|
||||
$addItem = $_SERVER['DOCUMENT_ROOT'].$zipTgt;
|
||||
if (is_dir($addItem)) {
|
||||
$dirStack = array($addItem);
|
||||
while (!empty($dirStack)) {
|
||||
$currentDir = array_pop($dirStack);
|
||||
$dir = dir($currentDir);
|
||||
while (false !== ($node = $dir->read())) {
|
||||
if (($node == '.') || ($node == '..')) {continue;}
|
||||
if (is_dir($currentDir.$node) && !strpos($currentDir.$node,"_coder")) {
|
||||
array_push($dirStack,$currentDir.$node.'/');
|
||||
}
|
||||
if (is_file($currentDir.$node)) {$zipFiles[] = $currentDir.$node;}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(file_exists($addItem)) {$zipFiles[] = $addItem;}
|
||||
}
|
||||
if(count($zipFiles)) {
|
||||
$zip = new ZipArchive();
|
||||
if($zip->open($zipName,ZIPARCHIVE::CREATE)!== true) {return false;}
|
||||
$excludeFilesFolders = explode(",",strClean($_GET['exclude']));
|
||||
foreach($zipFiles as $file) {
|
||||
$canAdd=true;
|
||||
for ($i=0;$i<count($excludeFilesFolders);$i++) {
|
||||
if(strpos($file,$excludeFilesFolders[$i])!==false) {$canAdd=false;};
|
||||
}
|
||||
if ($canAdd==true) {
|
||||
$zip->addFile($file,str_replace($_SERVER['DOCUMENT_ROOT']."/","",$file));
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
return file_exists($zipName);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($_SESSION['userLevel']==10) {
|
||||
$zipItDoZip = new zipIt();
|
||||
echo '<script>top.ICEcoder.serverMessage("<b>Zipping Files</b>");</script>';
|
||||
$zipItAddToZip = $zipItDoZip->zipFilesUp($zipItSaveLocation.$zipItFileName);
|
||||
if (!$zipItAddToZip) {
|
||||
echo '<script>alert("Could not zip files up!");</script>';
|
||||
} else {
|
||||
echo '<script>setTimeout(function(){top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);},500);</script>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||