kopia lustrzana https://github.com/c9/core
Merge remote-tracking branch 'origin/master' into restore-profile
Conflicts: plugins/c9.api/project.jspull/39/head^2
commit
e59f86a9c7
|
@ -403,7 +403,8 @@ module.exports = function(options) {
|
|||
"plugins/c9.ide.theme.flat/flat-light",
|
||||
{
|
||||
packagePath: "plugins/c9.ide.layout.classic/preload",
|
||||
themePrefix: options.themePrefix
|
||||
themePrefix: options.themePrefix,
|
||||
defaultTheme: "dark"
|
||||
},
|
||||
{
|
||||
packagePath: "plugins/c9.ide.tree/tree",
|
||||
|
|
|
@ -93,7 +93,7 @@ module.exports = function(config, optimist) {
|
|||
if (!/:/.test(argv.auth) && !isLocalhost) {
|
||||
console.log("Authentication is required when not running on localhost.\nPlease use -a user:pass or --listen localhost to listen locally.");
|
||||
console.log("switching to localhost");
|
||||
host == "127.0.0.1";
|
||||
host = config.host = "127.0.0.1";
|
||||
}
|
||||
var auth = (argv.auth || ":").split(":");
|
||||
|
||||
|
@ -102,7 +102,8 @@ module.exports = function(config, optimist) {
|
|||
packagePath: "connect-architect/connect",
|
||||
port: port,
|
||||
host: host,
|
||||
websocket: true
|
||||
websocket: true,
|
||||
showRealIP: !config.mode
|
||||
},
|
||||
{
|
||||
packagePath: "connect-architect/connect.basicauth",
|
||||
|
|
|
@ -69,18 +69,14 @@ exports.iSearchCommands = [{
|
|||
bindKey: {win: "Ctrl-F", mac: "Command-F"},
|
||||
exec: function(iSearch) {
|
||||
iSearch.cancelSearch(true);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "searchForward",
|
||||
bindKey: {win: "Ctrl-S|Ctrl-K", mac: "Ctrl-S|Command-G"},
|
||||
exec: function(iSearch, options) {
|
||||
options.useCurrentOrPrevSearch = true;
|
||||
iSearch.next(options);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "searchBackward",
|
||||
bindKey: {win: "Ctrl-R|Ctrl-Shift-K", mac: "Ctrl-R|Command-Shift-G"},
|
||||
|
@ -88,42 +84,30 @@ exports.iSearchCommands = [{
|
|||
options.useCurrentOrPrevSearch = true;
|
||||
options.backwards = true;
|
||||
iSearch.next(options);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "extendSearchTerm",
|
||||
exec: function(iSearch, string) {
|
||||
iSearch.addString(string);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "extendSearchTermSpace",
|
||||
bindKey: "space",
|
||||
exec: function(iSearch) { iSearch.addString(' '); },
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
exec: function(iSearch) { iSearch.addString(' '); }
|
||||
}, {
|
||||
name: "shrinkSearchTerm",
|
||||
bindKey: "backspace",
|
||||
exec: function(iSearch) {
|
||||
iSearch.removeChar();
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: 'confirmSearch',
|
||||
bindKey: 'return',
|
||||
exec: function(iSearch) { iSearch.deactivate(); },
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
exec: function(iSearch) { iSearch.deactivate(); }
|
||||
}, {
|
||||
name: 'cancelSearch',
|
||||
bindKey: 'esc|Ctrl-G',
|
||||
exec: function(iSearch) { iSearch.deactivate(true); },
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
exec: function(iSearch) { iSearch.deactivate(true); }
|
||||
}, {
|
||||
name: 'occurisearch',
|
||||
bindKey: 'Ctrl-O',
|
||||
|
@ -131,9 +115,7 @@ exports.iSearchCommands = [{
|
|||
var options = oop.mixin({}, iSearch.$options);
|
||||
iSearch.deactivate();
|
||||
occurStartCommand.exec(iSearch.$editor, options);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "yankNextWord",
|
||||
bindKey: "Ctrl-w",
|
||||
|
@ -142,9 +124,7 @@ exports.iSearchCommands = [{
|
|||
range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorWordRight(); }),
|
||||
string = ed.session.getTextRange(range);
|
||||
iSearch.addString(string);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: "yankNextChar",
|
||||
bindKey: "Ctrl-Alt-y",
|
||||
|
@ -153,15 +133,11 @@ exports.iSearchCommands = [{
|
|||
range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorRight(); }),
|
||||
string = ed.session.getTextRange(range);
|
||||
iSearch.addString(string);
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: 'recenterTopBottom',
|
||||
bindKey: 'Ctrl-l',
|
||||
exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); },
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); }
|
||||
}, {
|
||||
name: 'selectAllMatches',
|
||||
bindKey: 'Ctrl-space',
|
||||
|
@ -173,18 +149,19 @@ exports.iSearchCommands = [{
|
|||
return ranges.concat(ea ? ea : []); }, []) : [];
|
||||
iSearch.deactivate(false);
|
||||
ranges.forEach(ed.selection.addRange.bind(ed.selection));
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}
|
||||
}, {
|
||||
name: 'searchAsRegExp',
|
||||
bindKey: 'Alt-r',
|
||||
exec: function(iSearch) {
|
||||
iSearch.convertNeedleToRegExp();
|
||||
},
|
||||
readOnly: true,
|
||||
isIncrementalSearchCommand: true
|
||||
}];
|
||||
}
|
||||
}].map(function(cmd) {
|
||||
cmd.readOnly = true;
|
||||
cmd.isIncrementalSearchCommand = true;
|
||||
cmd.scrollIntoView = "animate-cursor";
|
||||
return cmd;
|
||||
});
|
||||
|
||||
function IncrementalSearchKeyboardHandler(iSearch) {
|
||||
this.$iSearch = iSearch;
|
||||
|
@ -192,7 +169,7 @@ function IncrementalSearchKeyboardHandler(iSearch) {
|
|||
|
||||
oop.inherits(IncrementalSearchKeyboardHandler, HashHandler);
|
||||
|
||||
;(function() {
|
||||
(function() {
|
||||
|
||||
this.attach = function(editor) {
|
||||
var iSearch = this.$iSearch;
|
||||
|
@ -201,15 +178,19 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler);
|
|||
if (!e.command.isIncrementalSearchCommand) return undefined;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return e.command.exec(iSearch, e.args || {});
|
||||
var scrollTop = editor.session.getScrollTop();
|
||||
var result = e.command.exec(iSearch, e.args || {});
|
||||
editor.renderer.scrollCursorIntoView(null, 0.5);
|
||||
editor.renderer.animateScrolling(scrollTop);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.detach = function(editor) {
|
||||
if (!this.$commandExecHandler) return;
|
||||
editor.commands.removeEventListener('exec', this.$commandExecHandler);
|
||||
delete this.$commandExecHandler;
|
||||
}
|
||||
};
|
||||
|
||||
var handleKeyboard$super = this.handleKeyboard;
|
||||
this.handleKeyboard = function(data, hashId, key, keyCode) {
|
||||
|
@ -222,7 +203,7 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler);
|
|||
if (extendCmd) { return {command: extendCmd, args: key}; }
|
||||
}
|
||||
return {command: "null", passEvent: hashId == 0 || hashId == 4};
|
||||
}
|
||||
};
|
||||
|
||||
}).call(IncrementalSearchKeyboardHandler.prototype);
|
||||
|
||||
|
|
|
@ -46,19 +46,20 @@ exports.$detectIndentation = function(lines, fallback) {
|
|||
if (!/^\s*[^*+\-\s]/.test(line))
|
||||
continue;
|
||||
|
||||
if (line[0] == "\t")
|
||||
if (line[0] == "\t") {
|
||||
tabIndents++;
|
||||
|
||||
var spaces = line.match(/^ */)[0].length;
|
||||
if (spaces && line[spaces] != "\t") {
|
||||
var diff = spaces - prevSpaces;
|
||||
if (diff > 0 && !(prevSpaces%diff) && !(spaces%diff))
|
||||
changes[diff] = (changes[diff] || 0) + 1;
|
||||
|
||||
stats[spaces] = (stats[spaces] || 0) + 1;
|
||||
prevSpaces = -Number.MAX_VALUE;
|
||||
} else {
|
||||
var spaces = line.match(/^ */)[0].length;
|
||||
if (spaces && line[spaces] != "\t") {
|
||||
var diff = spaces - prevSpaces;
|
||||
if (diff > 0 && !(prevSpaces%diff) && !(spaces%diff))
|
||||
changes[diff] = (changes[diff] || 0) + 1;
|
||||
|
||||
stats[spaces] = (stats[spaces] || 0) + 1;
|
||||
}
|
||||
prevSpaces = spaces;
|
||||
}
|
||||
prevSpaces = spaces;
|
||||
|
||||
// ignore lines ending with backslash
|
||||
while (i < max && line[line.length - 1] == "\\")
|
||||
line = lines[i++];
|
||||
|
@ -81,7 +82,7 @@ exports.$detectIndentation = function(lines, fallback) {
|
|||
spaceIndents = score;
|
||||
score = stats[1] ? 0.9 : 0.8;
|
||||
if (!stats.length)
|
||||
score = 0
|
||||
score = 0;
|
||||
} else
|
||||
score /= spaceIndents;
|
||||
|
||||
|
@ -95,9 +96,11 @@ exports.$detectIndentation = function(lines, fallback) {
|
|||
if (first.score && first.score > 1.4)
|
||||
var tabLength = first.length;
|
||||
|
||||
if (tabIndents > spaceIndents + 1)
|
||||
if (tabIndents > spaceIndents + 1) {
|
||||
if (tabLength == 1 || spaceIndents < tabIndents / 4 || first.score < 1.8)
|
||||
tabLength = undefined;
|
||||
return {ch: "\t", length: tabLength};
|
||||
|
||||
}
|
||||
if (spaceIndents > tabIndents + 1)
|
||||
return {ch: " ", length: tabLength};
|
||||
};
|
||||
|
|
|
@ -29,7 +29,13 @@ module.exports = {
|
|||
assert.equal(indent.ch, "\t");
|
||||
assert.equal(indent.length, undefined);
|
||||
|
||||
s.insert({row: 0, column: 0}, " ");
|
||||
s.insert({row: 0, column: 0}, " ");
|
||||
indent = whitespace.$detectIndentation(s.doc.$lines);
|
||||
assert.equal(indent.ch, "\t");
|
||||
assert.equal(indent.length, undefined);
|
||||
s.doc.removeInLine(0, 0, 1);
|
||||
|
||||
s.insert({row: 0, column: 0}, "x\n y\n");
|
||||
indent = whitespace.$detectIndentation(s.doc.$lines);
|
||||
assert.equal(indent.ch, "\t");
|
||||
assert.equal(indent.length, 4);
|
||||
|
|
|
@ -105,7 +105,7 @@ function objectToRegExp(obj) {
|
|||
this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this));
|
||||
this.selectionFix(ed);
|
||||
this.statusMessage(true);
|
||||
}
|
||||
};
|
||||
|
||||
this.deactivate = function(reset) {
|
||||
this.cancelSearch(reset);
|
||||
|
@ -117,7 +117,7 @@ function objectToRegExp(obj) {
|
|||
}
|
||||
ed.onPaste = this.$originalEditorOnPaste;
|
||||
this.message('');
|
||||
}
|
||||
};
|
||||
|
||||
this.selectionFix = function(editor) {
|
||||
// Fix selection bug: When clicked inside the editor
|
||||
|
@ -128,7 +128,7 @@ function objectToRegExp(obj) {
|
|||
if (editor.selection.isEmpty() && !editor.session.$emacsMark) {
|
||||
editor.clearSelection();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.highlight = function(regexp) {
|
||||
var sess = this.$editor.session,
|
||||
|
@ -136,7 +136,7 @@ function objectToRegExp(obj) {
|
|||
new SearchHighlight(null, "ace_isearch-result", "text"));
|
||||
hl.setRegexp(regexp);
|
||||
sess._emit("changeBackMarker"); // force highlight layer redraw
|
||||
}
|
||||
};
|
||||
|
||||
this.cancelSearch = function(reset) {
|
||||
var e = this.$editor;
|
||||
|
@ -150,7 +150,7 @@ function objectToRegExp(obj) {
|
|||
}
|
||||
this.highlight(null);
|
||||
return Range.fromPoints(this.$currentPos, this.$currentPos);
|
||||
}
|
||||
};
|
||||
|
||||
this.highlightAndFindWithNeedle = function(moveToNext, needleUpdateFunc) {
|
||||
if (!this.$editor) return null;
|
||||
|
@ -163,7 +163,7 @@ function objectToRegExp(obj) {
|
|||
if (options.needle.length === 0) {
|
||||
this.statusMessage(true);
|
||||
return this.cancelSearch(true);
|
||||
};
|
||||
}
|
||||
|
||||
// try to find the next occurence and enable highlighting marker
|
||||
options.start = this.$currentPos;
|
||||
|
@ -176,13 +176,13 @@ function objectToRegExp(obj) {
|
|||
this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end));
|
||||
if (moveToNext) this.$currentPos = found.end;
|
||||
// highlight after cursor move, so selection works properly
|
||||
this.highlight(options.re)
|
||||
this.highlight(options.re);
|
||||
}
|
||||
|
||||
this.statusMessage(found);
|
||||
|
||||
return found;
|
||||
}
|
||||
};
|
||||
|
||||
this.addString = function(s) {
|
||||
return this.highlightAndFindWithNeedle(false, function(needle) {
|
||||
|
@ -192,7 +192,7 @@ function objectToRegExp(obj) {
|
|||
reObj.expression += s;
|
||||
return objectToRegExp(reObj);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.removeChar = function(c) {
|
||||
return this.highlightAndFindWithNeedle(false, function(needle) {
|
||||
|
@ -202,7 +202,7 @@ function objectToRegExp(obj) {
|
|||
reObj.expression = reObj.expression.substring(0, reObj.expression.length-1);
|
||||
return objectToRegExp(reObj);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.next = function(options) {
|
||||
// try to find the next occurence of whatever we have searched for
|
||||
|
@ -215,29 +215,29 @@ function objectToRegExp(obj) {
|
|||
return options.useCurrentOrPrevSearch && needle.length === 0 ?
|
||||
this.$prevNeedle || '' : needle;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.onMouseDown = function(evt) {
|
||||
// when mouse interaction happens then we quit incremental search
|
||||
this.deactivate();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
this.onPaste = function(text) {
|
||||
this.addString(text);
|
||||
}
|
||||
};
|
||||
|
||||
this.convertNeedleToRegExp = function() {
|
||||
return this.highlightAndFindWithNeedle(false, function(needle) {
|
||||
return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.convertNeedleToString = function() {
|
||||
return this.highlightAndFindWithNeedle(false, function(needle) {
|
||||
return isRegExp(needle) ? regExpToObject(needle).expression : needle;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.statusMessage = function(found) {
|
||||
var options = this.$options, msg = '';
|
||||
|
@ -245,7 +245,7 @@ function objectToRegExp(obj) {
|
|||
msg += 'isearch: ' + options.needle;
|
||||
msg += found ? '' : ' (not found)';
|
||||
this.message(msg);
|
||||
}
|
||||
};
|
||||
|
||||
this.message = function(msg) {
|
||||
if (this.$editor.showCommandLine) {
|
||||
|
@ -254,7 +254,7 @@ function objectToRegExp(obj) {
|
|||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}).call(IncrementalSearch.prototype);
|
||||
|
||||
|
|
|
@ -428,7 +428,7 @@ exports.emacsKeys = {
|
|||
"M-;": "togglecomment",
|
||||
|
||||
"C-/|C-x u|S-C--|C-z": "undo",
|
||||
"S-C-/|S-C-x u|C--|S-C-z": "redo", //infinite undo?
|
||||
"S-C-/|S-C-x u|C--|S-C-z": "redo", // infinite undo?
|
||||
// vertical editing
|
||||
"C-x r": "selectRectangularRegion",
|
||||
"M-x": {command: "focusCommandLine", args: "M-x "}
|
||||
|
@ -483,7 +483,7 @@ exports.handler.addCommands({
|
|||
// different. Deactivate the mark when setMark is run with active
|
||||
// mark
|
||||
if (transientMarkModeActive && (mark || !hasNoSelection)) {
|
||||
if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)})
|
||||
if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)});
|
||||
else editor.clearSelection();
|
||||
if (mark) editor.pushEmacsMark(null);
|
||||
return;
|
||||
|
|
|
@ -236,10 +236,18 @@ MultiHashHandler.prototype = HashHandler.prototype;
|
|||
}
|
||||
}
|
||||
|
||||
if (data.$keyChain && keyCode > 0)
|
||||
data.$keyChain = "";
|
||||
if (data.$keyChain) {
|
||||
if ((!hashId || hashId == 4) && keyString.length == 1)
|
||||
data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input
|
||||
else if (hashId == -1 || keyCode > 0)
|
||||
data.$keyChain = ""; // reset keyChain
|
||||
}
|
||||
return {command: command};
|
||||
};
|
||||
|
||||
this.getStatusText = function(editor, data) {
|
||||
return data.$keyChain || "";
|
||||
};
|
||||
|
||||
}).call(HashHandler.prototype);
|
||||
|
||||
|
|
|
@ -127,7 +127,10 @@ module.exports = function startup(options, imports, register) {
|
|||
if (err)
|
||||
return register(err);
|
||||
|
||||
console.log("Connect server listening at " + proto + "://" + host + ":" + port);
|
||||
console.log("Connect server listening at " + proto + "://"
|
||||
+ (host == "0.0.0.0" && options.showRealIP
|
||||
? getLocalIPs()[0]
|
||||
: host) + ":" + port);
|
||||
|
||||
register(null, {
|
||||
"onDestruct": function(callback) {
|
||||
|
@ -210,6 +213,22 @@ module.exports = function startup(options, imports, register) {
|
|||
|
||||
return handle;
|
||||
}
|
||||
|
||||
function getLocalIPs() {
|
||||
var os = require("os");
|
||||
|
||||
var interfaces = os.networkInterfaces ? os.networkInterfaces() : {};
|
||||
var addresses = [];
|
||||
for (var k in interfaces) {
|
||||
for (var k2 in interfaces[k]) {
|
||||
var address = interfaces[k][k2];
|
||||
if (address.family === "IPv4" && !address.internal) {
|
||||
addresses.push(address.address);
|
||||
}
|
||||
}
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
};
|
||||
|
||||
function merge(objects) {
|
||||
|
|
|
@ -32,7 +32,11 @@ var ReliableSocket = module.exports = function(socket, options) {
|
|||
this.retransmissionTimeout = 3000;
|
||||
this.maxRtt = options.maxRtt || 10000;
|
||||
this.minRtt = options.minRtt || 2000;
|
||||
|
||||
|
||||
this.duplicateCount = 0;
|
||||
this.missCount = 0;
|
||||
this.connectTs = 0;
|
||||
|
||||
this.debug = options.debug || false;
|
||||
this.seq = options.seq || 1;
|
||||
this.recId = -1;
|
||||
|
@ -47,17 +51,9 @@ var ReliableSocket = module.exports = function(socket, options) {
|
|||
socket.on("message", this.onMessage.bind(this));
|
||||
socket.on("away", this.onAway.bind(this));
|
||||
socket.on("back", this.onBack.bind(this));
|
||||
this.on("stats", this.onStats.bind(this));
|
||||
this.on("stats_reply", this.onStatsReply.bind(this));
|
||||
socket.on("error", function(e){ console.error(e.message); });
|
||||
|
||||
// var that = this;
|
||||
// setInterval(function() {
|
||||
// console.log({
|
||||
// retransmissionTimeout: that.retransmissionTimeout,
|
||||
// congestionWindowSize: that.congestionWindowSize,
|
||||
// srtt: that.srtt,
|
||||
// rttVar: that.rttVar
|
||||
// });
|
||||
// }, 2000);
|
||||
};
|
||||
|
||||
util.inherits(ReliableSocket, EventEmitter);
|
||||
|
@ -99,17 +95,22 @@ ReliableSocket.prototype.onMessage = function(msg) {
|
|||
} else if (recId < expectedId) {
|
||||
this.debug && console.log("dupe", recId, expectedId);
|
||||
// we already saw this packet. Make sure the other side knows it
|
||||
this.duplicateCount += 1;
|
||||
this._ack();
|
||||
return;
|
||||
} else {
|
||||
this.debug && console.log("miss", recId, expectedId);
|
||||
// we miss packets in between
|
||||
this.missCount += 1;
|
||||
this._ack();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.d) {
|
||||
if (msg.t) {
|
||||
this.emit(msg.t, msg);
|
||||
}
|
||||
else if (msg.d) {
|
||||
try {
|
||||
this.emit("message", msg.d);
|
||||
} catch (e) {
|
||||
|
@ -121,6 +122,60 @@ ReliableSocket.prototype.onMessage = function(msg) {
|
|||
}
|
||||
};
|
||||
|
||||
ReliableSocket.prototype.onStats = function(msg) {
|
||||
var data = msg.d || {};
|
||||
data.remote = this._getStats();
|
||||
this.send(data, "stats_reply");
|
||||
};
|
||||
|
||||
ReliableSocket.prototype.onStatsReply = function(msg) {
|
||||
var data = msg.d || {};
|
||||
data.localEnd = this._getStats();
|
||||
var id = data.id;
|
||||
|
||||
if (this.statsCallbacks[id]) {
|
||||
this.statsCallbacks[id](null, data);
|
||||
delete this.statsCallbacks[id];
|
||||
}
|
||||
};
|
||||
|
||||
ReliableSocket.prototype.stats = function(callback) {
|
||||
if (!this.statsCallbacks) this.statsCallbacks = {};
|
||||
var id = this.seq;
|
||||
|
||||
this.statsCallbacks[id] = callback;
|
||||
var data = {
|
||||
id: id,
|
||||
localStart: this._getStats()
|
||||
};
|
||||
this.send(data, "stats");
|
||||
};
|
||||
|
||||
ReliableSocket.prototype._getStats = function() {
|
||||
var wsBuffer = -1;
|
||||
try {
|
||||
if (this.socket.socket.transport.ws)
|
||||
wsBuffer = this.socket.socket.transport.ws.bufferedAmount;
|
||||
else if (this.socket.socket.transport.socket)
|
||||
wsBuffer = this.socket.socket.transport.socket._socket.bufferSize;
|
||||
} catch(e) {}
|
||||
|
||||
return {
|
||||
livetime: Date.now() - this.connectTs,
|
||||
ts: Date.now(),
|
||||
retransmissionTimeout: this.retransmissionTimeout,
|
||||
congestionWindowSize: this.congestionWindowSize,
|
||||
srtt: this.srtt,
|
||||
rttVar: this.rttVar,
|
||||
duplicateCount: this.duplicateCount,
|
||||
missCount: this.missCount,
|
||||
buffered: this.buffer.length,
|
||||
unacked: Object.keys(this.unacked).length,
|
||||
eioBuffer: this.socket.socket.writeBuffer.length,
|
||||
wsBuffer: wsBuffer
|
||||
};
|
||||
};
|
||||
|
||||
ReliableSocket.prototype.onAway = function() {
|
||||
this.debug && console.log("away");
|
||||
this._scheduleDisconnect("client connection went away");
|
||||
|
@ -131,6 +186,7 @@ ReliableSocket.prototype.onBack = function() {
|
|||
this.debug && console.log("back");
|
||||
this._cancelDisconnect();
|
||||
|
||||
this.connectTs = Date.now();
|
||||
if (!this.connected) {
|
||||
this.connected = true;
|
||||
this.emit("connect");
|
||||
|
@ -161,7 +217,7 @@ ReliableSocket.prototype._delayedAck = function() {
|
|||
var that = this;
|
||||
this._cancelDelayedAck();
|
||||
this._ackTimer = setTimeout(function() {
|
||||
that._ack();
|
||||
that._ack();
|
||||
}, this.ackTimeout);
|
||||
};
|
||||
|
||||
|
@ -188,7 +244,7 @@ ReliableSocket.prototype._flush = function() {
|
|||
this.debug && console.log("flush", toSend, "messages");
|
||||
for (var i=0; i<toSend; i++) {
|
||||
var msg = this.buffer.shift();
|
||||
this._sendMessage(msg);
|
||||
this._sendMessage(msg[0], msg[1]);
|
||||
}
|
||||
if (!this.buffer.length)
|
||||
this.emit("drain");
|
||||
|
@ -199,7 +255,9 @@ ReliableSocket.prototype.disconnect = function(reason) {
|
|||
this.debug && console.log("disconnect");
|
||||
this.connected = false;
|
||||
this.recId = -1;
|
||||
|
||||
this.duplicateCount = 0;
|
||||
this.missCount = 0;
|
||||
|
||||
this.buffer = [];
|
||||
for (var key in this.unacked) {
|
||||
this.unacked[key].abort();
|
||||
|
@ -218,20 +276,20 @@ ReliableSocket.prototype.close = function() {
|
|||
return this.socket.close();
|
||||
};
|
||||
|
||||
ReliableSocket.prototype.send = function(msg) {
|
||||
ReliableSocket.prototype.send = function(msg, type) {
|
||||
this._cancelDelayedAck();
|
||||
if (this.socket.readyState == "open" && Object.keys(this.unacked).length < this.congestionWindowSize) {
|
||||
this._sendMessage(msg);
|
||||
this._sendMessage(msg, type);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
this.debug && console.log("buffer");
|
||||
this.buffer.push(msg);
|
||||
this.buffer.push([msg, type]);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ReliableSocket.prototype._sendMessage = function(data) {
|
||||
ReliableSocket.prototype._sendMessage = function(data, type) {
|
||||
var that = this;
|
||||
|
||||
var msg = {
|
||||
|
@ -269,7 +327,8 @@ ReliableSocket.prototype._sendMessage = function(data) {
|
|||
return escape(JSON.stringify({
|
||||
ack: that.recId,
|
||||
seq: msg.seq,
|
||||
d: data
|
||||
d: data,
|
||||
t: type
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
"use server";
|
||||
"use mocha";
|
||||
|
||||
require("c9/inline-mocha")(module);
|
||||
|
||||
var expect = require('chai').expect;
|
||||
|
||||
describe('vfs-local', function () {
|
||||
|
||||
this.timeout(5000);
|
||||
|
||||
var root = __dirname + "/mock2/";
|
||||
var base = root.substr(0, root.length - 1);
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ function Worker(vfs) {
|
|||
streams[id] = stream;
|
||||
stream.id = id;
|
||||
stream.on("error", function(err) {
|
||||
remote.onError(id, err);
|
||||
remote.onError && remote.onError(id, err);
|
||||
});
|
||||
if (stream.readable) {
|
||||
stream.on("data", function (chunk) {
|
||||
|
@ -322,10 +322,30 @@ function Worker(vfs) {
|
|||
delete watchers[id];
|
||||
watcher.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional timing info to any "ping" call.
|
||||
*/
|
||||
function wrapPingCall(name, fnName, args) {
|
||||
if (name === "ping" && fnName === "ping" && args[0] === "serverTime" && args.length === 2) {
|
||||
var start = Date.now();
|
||||
var cb = args[1];
|
||||
|
||||
args[1] = function(err, payload) {
|
||||
if (err) return cb(err);
|
||||
cb(null, {
|
||||
payload: payload,
|
||||
serverTime: Date.now() - start
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function call(name, fnName, args) {
|
||||
var api = apis[name];
|
||||
if (!api) return;
|
||||
|
||||
wrapPingCall(name, fnName, args);
|
||||
|
||||
// If the last arg is a function, assume it's a callback and process it.
|
||||
if (typeof args[args.length - 1] == "function") {
|
||||
|
|
10
package.json
10
package.json
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"acorn": ">=0.11.0",
|
||||
"amd-loader": "~0.0.5",
|
||||
"async": "~0.2.7",
|
||||
"async": "^0.9.0",
|
||||
"base64id": "~0.1.0",
|
||||
"c9": "0.1.0",
|
||||
"connect": "~2.12.0",
|
||||
|
@ -60,15 +60,15 @@
|
|||
"c9.ide.language.javascript.tern": "#a65ad88dd9",
|
||||
"c9.ide.language.javascript.infer": "#ebb2daf81a",
|
||||
"c9.ide.language.jsonalyzer": "#5262f6b4b9",
|
||||
"c9.ide.collab": "#51b8b72e0f",
|
||||
"c9.ide.collab": "#e2a500a964",
|
||||
"c9.ide.local": "#2bfd7ff051",
|
||||
"c9.ide.find": "#989c06e6a7",
|
||||
"c9.ide.find.infiles": "#28b3cfcb47",
|
||||
"c9.ide.find.replace": "#43a6b95e6a",
|
||||
"c9.ide.run.debug": "#789019f9a7",
|
||||
"c9.ide.find.replace": "#e4daf722b8",
|
||||
"c9.ide.run.debug": "#36245ee2aa",
|
||||
"c9.ide.ace.emmet": "#e5f1a92ac3",
|
||||
"c9.ide.ace.gotoline": "#4d1a93172c",
|
||||
"c9.ide.ace.keymaps": "#2477fd8ac6",
|
||||
"c9.ide.ace.keymaps": "#6c4bb65b1f",
|
||||
"c9.ide.ace.repl": "#ada99852fa",
|
||||
"c9.ide.ace.split": "#0ae0151c78",
|
||||
"c9.ide.ace.statusbar": "#d7b45bb7c3",
|
||||
|
|
|
@ -29,6 +29,18 @@ function plugin(options, imports, register) {
|
|||
warning: new raygun.Client().init({ apiKey: options.keys.warning })
|
||||
};
|
||||
|
||||
for (var client in clients) {
|
||||
client = clients[client];
|
||||
client._send = client.send;
|
||||
client.send = function(exception, customData, callback, request) {
|
||||
var ex = exception;
|
||||
if (!exception.stack)
|
||||
ex = new Error(exception.message || exception);
|
||||
|
||||
return this._send(ex, customData, callback, request);
|
||||
};
|
||||
}
|
||||
|
||||
clients.error.setVersion(options.version + ".0");
|
||||
clients.warning.setVersion(options.version + ".0");
|
||||
|
||||
|
|
|
@ -614,6 +614,17 @@ define(function(require, exports, module) {
|
|||
settings.set("user/ace/@fontSize", --currSize < 1 ? 1 : currSize);
|
||||
}
|
||||
}), handle);
|
||||
|
||||
commands.addCommand({
|
||||
name: "toggleWordWrap",
|
||||
bindKey: {win: "Ctrl-Q", mac: "Ctrl-W"},
|
||||
exec: function(editor) {
|
||||
editor.setOption("wrap", editor.getOption("wrap") == "off");
|
||||
},
|
||||
isAvailable: function(editor) {
|
||||
return editor && editor.type == "ace";
|
||||
}
|
||||
}, handle);
|
||||
}
|
||||
|
||||
/***** Preferences *****/
|
||||
|
@ -632,6 +643,11 @@ define(function(require, exports, module) {
|
|||
max: "64",
|
||||
position: 100
|
||||
},
|
||||
"Autodetect Tab Size on Load" : {
|
||||
type: "checkbox",
|
||||
path: "project/ace/@guessTabSize",
|
||||
position: 150
|
||||
},
|
||||
"New File Line Endings" : {
|
||||
type: "dropdown",
|
||||
path: "project/ace/@newLineMode",
|
||||
|
@ -1977,6 +1993,7 @@ define(function(require, exports, module) {
|
|||
}
|
||||
|
||||
function hideProgress(){
|
||||
if (!ace) return; // ace was destroyed during timeout
|
||||
var style = progress.background.style;
|
||||
function hide() {
|
||||
style.display = "none";
|
||||
|
@ -1993,7 +2010,6 @@ define(function(require, exports, module) {
|
|||
style.opacity = 0;
|
||||
|
||||
ace.renderer.unfreeze();
|
||||
// ace.resize(true);
|
||||
}
|
||||
|
||||
function showProgress(value, upload, t) {
|
||||
|
@ -2052,7 +2068,8 @@ define(function(require, exports, module) {
|
|||
|
||||
function detectSettingsOnLoad(c9Session) {
|
||||
var session = c9Session.session;
|
||||
whitespaceUtil.detectIndentation(session);
|
||||
if (settings.get("project/ace/@guessTabSize"))
|
||||
whitespaceUtil.detectIndentation(session);
|
||||
if (!session.syntax) {
|
||||
var syntax = detectSyntax(c9Session);
|
||||
if (syntax)
|
||||
|
|
|
@ -39,13 +39,16 @@ define(function(require, module, exports) {
|
|||
|
||||
// Listen to changes and detect when the value of the editor
|
||||
// is different from what is on disk
|
||||
undoManager.on("change", function(e) {
|
||||
var c = !undoManager.isAtBookmark();
|
||||
if (changed !== c || undoManager.position == -1) {
|
||||
changed = c;
|
||||
emit("changed", { changed: c });
|
||||
}
|
||||
});
|
||||
function initUndo(){
|
||||
undoManager.on("change", function(e) {
|
||||
var c = !undoManager.isAtBookmark();
|
||||
if (changed !== c || undoManager.position == -1) {
|
||||
changed = c;
|
||||
emit("changed", { changed: c });
|
||||
}
|
||||
});
|
||||
}
|
||||
initUndo();
|
||||
|
||||
/***** Methods *****/
|
||||
|
||||
|
@ -401,6 +404,11 @@ define(function(require, module, exports) {
|
|||
* @property {UndoManager} undoManager
|
||||
*/
|
||||
get undoManager(){ return undoManager; },
|
||||
set undoManager(newUndo){
|
||||
undoManager.unload();
|
||||
undoManager = newUndo;
|
||||
initUndo();
|
||||
},
|
||||
|
||||
_events: [
|
||||
/**
|
||||
|
|
|
@ -326,7 +326,6 @@ define(function(require, exports, module) {
|
|||
commands.find,
|
||||
commands.openterminal,
|
||||
commands.navigate,
|
||||
commands.navigate_altkey,
|
||||
commands.searchinfiles,
|
||||
commands.close_term_pane,
|
||||
commands.closeallbutme,
|
||||
|
|
|
@ -30,7 +30,7 @@ define(function(require, exports, module) {
|
|||
|
||||
function preload(callback) {
|
||||
settings.setDefaults("user/general", [
|
||||
["skin", "dark"] // "flat-light"
|
||||
["skin", options.defaultTheme || "dark"] // "flat-light"
|
||||
]);
|
||||
if (!packed || options.loadTheme) return callback();
|
||||
try {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
define(function(require, exports, module) {
|
||||
var isWindows = require("ace/lib/useragent").isWindows;
|
||||
module.exports = function initInput(ace) {
|
||||
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
|
||||
var KEY_MODS = require("ace/lib/keys").KEY_MODS;
|
||||
|
@ -156,6 +157,9 @@ define(function(require, exports, module) {
|
|||
passEvent: !hashId || hashId === KEY_MODS.shift || (
|
||||
// on mac key combos without ctrl or cmd trigger textinput
|
||||
specialKeys.platform === "mac" && !(hashId & (KEY_MODS.ctrl | KEY_MODS.cmd))
|
||||
) || (
|
||||
// on windows 8+ calling preventDefault on win+space breaks textinput
|
||||
specialKeys.platform === "win" && hashId == KEY_MODS.cmd && (keyCode == 32 || keyCode == -1)
|
||||
)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,18 +12,19 @@ define(function(require, exports, module) {
|
|||
var c9 = imports.c9;
|
||||
var util = imports.util;
|
||||
var Panel = imports.Panel;
|
||||
var fs = imports.fs;
|
||||
var panels = imports.panels;
|
||||
var settings = imports.settings;
|
||||
var layout = imports.layout;
|
||||
var fs = imports.fs;
|
||||
var ui = imports.ui;
|
||||
var menus = imports.menus;
|
||||
var tabs = imports.tabManager;
|
||||
var menus = imports.menus;
|
||||
var layout = imports.layout;
|
||||
var clipboard = imports.clipboard;
|
||||
var commands = imports.commands;
|
||||
var watcher = imports.watcher;
|
||||
var prefs = imports.preferences;
|
||||
var fsCache = imports["fs.cache"];
|
||||
var alert = imports["dialog.alert"].show;
|
||||
var fsCache = imports["fs.cache"];
|
||||
var confirmRemove = imports["dialog.fileremove"].show;
|
||||
var confirmRename = imports["dialog.fileoverwrite"].show;
|
||||
var showError = imports["dialog.error"].show;
|
||||
|
@ -99,6 +100,15 @@ define(function(require, exports, module) {
|
|||
if (panels.isActive("tree"))
|
||||
tree && tree.resize();
|
||||
});
|
||||
commands.addCommand({
|
||||
name: "focusTree",
|
||||
// shortcut can be modified here
|
||||
bindKey: { mac: "Shift-Esc", win: "Shift-Esc"},
|
||||
exec: function() {
|
||||
panels.activate("tree");
|
||||
plugin.focus();
|
||||
}
|
||||
}, plugin);
|
||||
|
||||
// On Ready Resize initially
|
||||
c9.once("ready", function(){ tree && tree.resize(); });
|
||||
|
|
|
@ -211,28 +211,27 @@ define(function(require, exports, module) {
|
|||
var editor = emit("getEditor");
|
||||
|
||||
var nodes = this.childNodes;
|
||||
for (var start = 0, a, fn, cmd, n, i = nodes.length - 1; i >= 0; i--) {
|
||||
cmd = (n = nodes[i]).command;
|
||||
|
||||
if (start == i && !n.visible)
|
||||
start = i + 1;
|
||||
for (var n, prev, i = nodes.length - 1; i >= 0; i--) {
|
||||
var cmd = (n = nodes[i]).command;
|
||||
|
||||
if (!n.visible) continue;
|
||||
|
||||
|
||||
// prevent dividers two consecutive dividers and dividers
|
||||
// at bottom and top
|
||||
if (n.localName == "divider") {
|
||||
if (i === start || i == nodes.length -1
|
||||
|| nodes[i - 1].localName == "divider")
|
||||
if (!prev || prev.localName == "divider")
|
||||
n.hide();
|
||||
else
|
||||
n.show();
|
||||
|
||||
prev = n;
|
||||
continue;
|
||||
}
|
||||
prev = n;
|
||||
|
||||
var c = cmd && commands.commands[cmd];
|
||||
fn = c && c.isAvailable;
|
||||
a = (!n.isAvailable || n.isAvailable(editor))
|
||||
var fn = c && c.isAvailable;
|
||||
var a = (!n.isAvailable || n.isAvailable(editor))
|
||||
&& (!fn || fn(editor));
|
||||
|
||||
if (!cmd)
|
||||
|
@ -242,6 +241,9 @@ define(function(require, exports, module) {
|
|||
|
||||
n[a ? "enable" : "disable"]();
|
||||
}
|
||||
if (prev && prev.localName == "divider") {
|
||||
prev.hide();
|
||||
}
|
||||
}
|
||||
|
||||
toggleIframes(e);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module.exports = function(vfs, options, register) {
|
||||
register(null, {
|
||||
ping: function (payload, callback) {
|
||||
// We simply return the payload, while vfs-socket adds a time stamp
|
||||
callback(null, payload);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -60,11 +60,13 @@ define(function(require, exports, module) {
|
|||
if (!api) return callback(new Error("Client is offline"));
|
||||
|
||||
var start = Date.now();
|
||||
api.ping("ping", function(err) {
|
||||
var took = Date.now() - start;
|
||||
api.ping("serverTime", function(err, response) {
|
||||
if (err) return callback(err);
|
||||
|
||||
callback(null, took);
|
||||
callback(null, {
|
||||
serverTime: response.serverTime,
|
||||
total: Date.now() - start
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Runner</title>
|
||||
<link rel="stylesheet" href="lib/mocha/mocha.css" />
|
||||
<style> HTML { overflow: auto !important } </style>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Runner</title>
|
||||
<link rel="stylesheet" href="lib/mocha/mocha.css" />
|
||||
<style>
|
||||
HTML { overflow: auto !important }
|
||||
body {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
padding: 60px 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
|
@ -88,11 +94,17 @@
|
|||
};
|
||||
Storage.create(window, "localStorage");
|
||||
Storage.create(window, "sessionStorage");
|
||||
|
||||
|
||||
/*global Mocha, mocha*/
|
||||
mocha.reporter(function(runner) {
|
||||
Mocha.reporters.Base.call(this, runner);
|
||||
Mocha.reporters.HTML.call(this, runner);
|
||||
function extend(target, BaseFn, arg) {
|
||||
var base = BaseFn.prototype;
|
||||
for (var i in base) if (!target[i]) target[i] = base[i];
|
||||
BaseFn.call(target, arg);
|
||||
}
|
||||
|
||||
extend(this, Mocha.reporters.Base, runner);
|
||||
extend(this, Mocha.reporters.HTML, runner);
|
||||
|
||||
var tests = [];
|
||||
var stats = this.stats;
|
||||
|
|
|
@ -364,7 +364,8 @@ require([
|
|||
})(),
|
||||
util: {
|
||||
alert: function() {},
|
||||
escapeXml: function(s) { return s; }
|
||||
escapeXml: function(s) { return s; },
|
||||
stableStringify: function(s) { return JSON.stringify(s); },
|
||||
},
|
||||
gotoline: {
|
||||
toggle: function(){ }
|
||||
|
|
|
@ -110,4 +110,3 @@ updateNodeModules
|
|||
|
||||
echo "Success!"
|
||||
echo "run '${yellow}node server.js -p 8181 -l 0.0.0.0 -a :${resetColor}' to launch Cloud9"
|
||||
"$NODE" server.js -p 8181 -l 0.0.0.0 -a :
|
||||
|
|
Ładowanie…
Reference in New Issue