miscelaneous fixes from c9

This commit is contained in:
nightwing 2013-11-05 20:54:38 +04:00
commit 8443991f13
12 changed files with 234 additions and 81 deletions

View file

@ -209,6 +209,9 @@ var AcePopup = function(parentNode) {
} }
// public // public
popup.isOpen = false;
popup.isTopdown = false;
popup.data = []; popup.data = [];
popup.setData = function(list) { popup.setData = function(list) {
popup.data = list || []; popup.data = list || [];
@ -233,26 +236,33 @@ var AcePopup = function(parentNode) {
popup._signal("select"); popup._signal("select");
} }
}; };
popup.on("changeSelection", function() {
if (popup.isOpen)
popup.setRow(popup.selection.lead.row);
});
popup.hide = function() { popup.hide = function() {
this.container.style.display = "none"; this.container.style.display = "none";
this._signal("hide"); this._signal("hide");
popup.isOpen = false; popup.isOpen = false;
}; };
popup.show = function(pos, lineHeight) { popup.show = function(pos, lineHeight, topdownOnly) {
var el = this.container; var el = this.container;
var screenHeight = window.innerHeight; var screenHeight = window.innerHeight;
var renderer = this.renderer; var renderer = this.renderer;
// var maxLines = Math.min(renderer.$maxLines, this.session.getLength()); // var maxLines = Math.min(renderer.$maxLines, this.session.getLength());
var maxH = renderer.$maxLines * lineHeight * 1.4; var maxH = renderer.$maxLines * lineHeight * 1.4;
var top = pos.top + this.$borderSize; var top = pos.top + this.$borderSize;
if (top + maxH > screenHeight - lineHeight) { if (top + maxH > screenHeight - lineHeight && !topdownOnly) {
el.style.top = ""; el.style.top = "";
el.style.bottom = screenHeight - top + "px"; el.style.bottom = screenHeight - top + "px";
popup.isTopdown = false;
} else { } else {
top += lineHeight; top += lineHeight;
el.style.top = top + "px"; el.style.top = top + "px";
el.style.bottom = ""; el.style.bottom = "";
popup.isTopdown = true;
} }
el.style.left = pos.left + "px"; el.style.left = pos.left + "px";

View file

@ -158,7 +158,7 @@
z-index: 1; z-index: 1;
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: pre;
height: 100%; height: 100%;
width: 100%; width: 100%;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;

View file

@ -119,6 +119,9 @@ function HashHandler(config, platform) {
if (typeof command === "function") if (typeof command === "function")
command = { exec: command }; command = { exec: command };
if (typeof command !== "object")
return;
if (!command.name) if (!command.name)
command.name = name; command.name = name;

View file

@ -75,8 +75,7 @@ var Gutter = function(parentEl) {
this.setAnnotations = function(annotations) { this.setAnnotations = function(annotations) {
// iterate over sparse array // iterate over sparse array
this.$annotations = [] this.$annotations = [];
var rowInfo, row;
for (var i = 0; i < annotations.length; i++) { for (var i = 0; i < annotations.length; i++) {
var annotation = annotations[i]; var annotation = annotations[i];
var row = annotation.row; var row = annotation.row;
@ -112,7 +111,7 @@ var Gutter = function(parentEl) {
} else if (delta.action == "removeText" || delta.action == "removeLines") { } else if (delta.action == "removeText" || delta.action == "removeLines") {
this.$annotations.splice(firstRow, len + 1, null); this.$annotations.splice(firstRow, len + 1, null);
} else { } else {
var args = Array(len + 1); var args = new Array(len + 1);
args.unshift(firstRow, 1); args.unshift(firstRow, 1);
this.$annotations.splice.apply(this.$annotations, args); this.$annotations.splice.apply(this.$annotations, args);
} }
@ -121,13 +120,16 @@ var Gutter = function(parentEl) {
this.update = function(config) { this.update = function(config) {
var firstRow = config.firstRow; var firstRow = config.firstRow;
var lastRow = config.lastRow; var lastRow = config.lastRow;
var fold = this.session.getNextFoldLine(firstRow); var session = this.session;
var fold = session.getNextFoldLine(firstRow);
var foldStart = fold ? fold.start.row : Infinity; var foldStart = fold ? fold.start.row : Infinity;
var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets; var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
var breakpoints = this.session.$breakpoints; var breakpoints = session.$breakpoints;
var decorations = this.session.$decorations; var decorations = session.$decorations;
var firstLineNumber = this.session.$firstLineNumber; var firstLineNumber = session.$firstLineNumber;
var lastLineNumber = 0; var lastLineNumber = 0;
var gutterRenderer = session.gutterRenderer;
var cell = null; var cell = null;
var index = -1; var index = -1;
@ -135,7 +137,7 @@ var Gutter = function(parentEl) {
while (true) { while (true) {
if (row > foldStart) { if (row > foldStart) {
row = fold.end.row + 1; row = fold.end.row + 1;
fold = this.session.getNextFoldLine(row, fold); fold = session.getNextFoldLine(row, fold);
foldStart = fold ? fold.start.row : Infinity; foldStart = fold ? fold.start.row : Infinity;
} }
if (row > lastRow) { if (row > lastRow) {
@ -166,19 +168,15 @@ var Gutter = function(parentEl) {
if (cell.element.className != className) if (cell.element.className != className)
cell.element.className = className; cell.element.className = className;
var height = this.session.getRowLength(row) * config.lineHeight + "px"; var height = session.getRowLength(row) * config.lineHeight + "px";
if (height != cell.element.style.height) if (height != cell.element.style.height)
cell.element.style.height = height; cell.element.style.height = height;
var text = lastLineNumber = row + firstLineNumber;
if (text != cell.textNode.data)
cell.textNode.data = text;
if (foldWidgets) { if (foldWidgets) {
var c = foldWidgets[row]; var c = foldWidgets[row];
// check if cached value is invalidated and we need to recompute // check if cached value is invalidated and we need to recompute
if (c == null) if (c == null)
c = foldWidgets[row] = this.session.getFoldWidget(row); c = foldWidgets[row] = session.getFoldWidget(row);
} }
if (c) { if (c) {
@ -198,21 +196,30 @@ var Gutter = function(parentEl) {
if (cell.foldWidget.style.height != height) if (cell.foldWidget.style.height != height)
cell.foldWidget.style.height = height; cell.foldWidget.style.height = height;
} else { } else {
if (cell.foldWidget != null) { if (cell.foldWidget) {
cell.element.removeChild(cell.foldWidget); cell.element.removeChild(cell.foldWidget);
cell.foldWidget = null; cell.foldWidget = null;
} }
} }
var text = lastLineNumber = gutterRenderer
? gutterRenderer.getText(session, row)
: row + firstLineNumber;
if (text != cell.textNode.data)
cell.textNode.data = text;
row++; row++;
} }
this.element.style.height = config.minHeight + "px"; this.element.style.height = config.minHeight + "px";
if (this.$fixedWidth || this.session.$useWrapMode) if (this.$fixedWidth || session.$useWrapMode)
lastLineNumber = this.session.getLength(); lastLineNumber = session.getLength();
var gutterWidth = lastLineNumber.toString().length * config.characterWidth; var gutterWidth = gutterRenderer
? gutterRenderer.getWidth(session, lastLineNumber, config)
: lastLineNumber.toString().length * config.characterWidth;
var padding = this.$padding || this.$computePadding(); var padding = this.$padding || this.$computePadding();
gutterWidth += padding.left + padding.right; gutterWidth += padding.left + padding.right;
if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {

View file

@ -172,6 +172,10 @@ exports.deferredCall = function(fcn) {
timer = null; timer = null;
return deferred; return deferred;
}; };
deferred.isPending = function() {
return timer;
};
return deferred; return deferred;
}; };
@ -185,15 +189,15 @@ exports.delayedCall = function(fcn, defaultTimeout) {
}; };
var _self = function(timeout) { var _self = function(timeout) {
if (timer == null)
timer = setTimeout(callback, timeout || defaultTimeout);
};
_self.delay = function(timeout) {
timer && clearTimeout(timer); timer && clearTimeout(timer);
timer = setTimeout(callback, timeout || defaultTimeout); timer = setTimeout(callback, timeout || defaultTimeout);
}; };
_self.schedule = _self;
_self.delay = _self;
_self.schedule = function(timeout) {
if (timer == null)
timer = setTimeout(callback, timeout || 0);
};
_self.call = function() { _self.call = function() {
this.cancel(); this.cancel();

View file

@ -32,8 +32,15 @@ define(function(require, exports, module) {
"use strict"; "use strict";
var oop = require("../lib/oop"); var oop = require("../lib/oop");
var lang = require("../lib/lang");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
function safeCreateRegexp(source, flag) {
try {
return new RegExp(source, flag);
} catch(e) {}
}
var C9SearchHighlightRules = function() { var C9SearchHighlightRules = function() {
// regexp must not have capturing parentheses. Use (?:) instead. // regexp must not have capturing parentheses. Use (?:) instead.
@ -41,12 +48,120 @@ var C9SearchHighlightRules = function() {
this.$rules = { this.$rules = {
"start" : [ "start" : [
{ {
token : ["c9searchresults.constant.numeric", "c9searchresults.text", "c9searchresults.text"], tokenNames : ["c9searchresults.constant.numeric", "c9searchresults.text", "c9searchresults.text", "c9searchresults.keyword"],
regex : "(^\\s+[0-9]+)(:\\s*)(.+)" regex : "(^\\s+[0-9]+)(:\\s)(.+)",
onMatch : function(val, state, stack) {
var values = this.splitRegex.exec(val);
var types = this.tokenNames;
var tokens = [{
type: types[0],
value: values[1]
},{
type: types[1],
value: values[2]
}];
var regex = stack[1];
var str = values[3];
if (regex && str)
values = str.split(regex); // this doesn't work on ie8 but we don't care:)
else
values = [str];
for (var i = 0, l = values.length; i < l; i+=2) {
if (values[i])
tokens.push({
type: types[2],
value: values[i]
});
if (values[i+1])
tokens.push({
type: types[3],
value: values[i + 1]
});
}
return tokens;
}
}, },
{ {
token : ["string", "text"], // single line token : ["string", "text"], // single line
regex : "(.+)(:$)" regex : "(\\S.*)(:$)"
},
{
regex : "Searching for .*$",
onMatch: function(val, state, stack) {
var parts = val.split("\x01");
var search = parts[1];
if (parts.length < 3)
return "text";
var options = parts[2] == " in" ? parts[5] : parts[6];
if (!/regex/.test(options))
search = lang.escapeRegExp(search);
if (/whole/.test(options))
search = "\\b" + search + "\\b";
var regex = safeCreateRegexp(
"(" + search + ")",
/ sensitive/.test(options) ? "" : "i"
);
if (regex) {
stack[0] = state;
stack[1] = regex;
}
var i = 0;
var tokens = [
{
value: parts[i++] + "'",
type: "text"
},
{
value: parts[i++],
type: "text" // "c9searchresults.keyword"
},
{
value: "'" + parts[i++],
type: "text"
}
];
// replaced
if (parts[2] !== " in") {
tokens.push({
value: "'" + parts[i++] + "'",
type: "text"
}, {
value: parts[i++],
type: "text"
});
}
// path
tokens.push({
value: " " + parts[i++] + " ",
type: "text"
});
// options
if (parts[i+1]) {
tokens.push({
value: "(" + parts[i+1] + ")",
type: "text"
});
i += 1;
} else {
i -= 1;
}
while (i++ < parts.length)
parts[i] && tokens.push({
value: parts[i],
type: "text"
});
return tokens;
}
},
{
regex : "\\d+",
token: "constant.numeric"
} }
] ]
}; };
@ -56,4 +171,4 @@ oop.inherits(C9SearchHighlightRules, TextHighlightRules);
exports.C9SearchHighlightRules = C9SearchHighlightRules; exports.C9SearchHighlightRules = C9SearchHighlightRules;
}); });

View file

@ -32,7 +32,14 @@
.ace-tomorrow-night-bright .ace_marker-layer .ace_bracket { .ace-tomorrow-night-bright .ace_marker-layer .ace_bracket {
margin: -1px 0 0 -1px; margin: -1px 0 0 -1px;
border: 1px solid #343434 border: 1px solid #888888
}
.ace-tomorrow-night-bright .ace_marker-layer .ace_highlight {
border: 1px solid rgb(110, 119, 0);
border-bottom: 0;
box-shadow: inset 0 -1px rgb(110, 119, 0);
margin: -1px 0 0 -1px;
background: rgba(255, 235, 0, 0.1);
} }
.ace-tomorrow-night-bright .ace_marker-layer .ace_active-line { .ace-tomorrow-night-bright .ace_marker-layer .ace_active-line {
@ -48,7 +55,7 @@
} }
.ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word { .ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word {
border: 1px solid #424242 border: 1px solid #888888
} }
.ace-tomorrow-night-bright .ace_invisible { .ace-tomorrow-night-bright .ace_invisible {
@ -123,6 +130,10 @@
color: #969896 color: #969896
} }
.ace-tomorrow-night-bright .ace_c9searchresults.ace_keyword {
color: #C2C280;
}
.ace-tomorrow-night-bright .ace_indent-guide { .ace-tomorrow-night-bright .ace_indent-guide {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y;
} }

View file

@ -310,7 +310,7 @@ var Tokenizer = function(rules) {
token = { token = {
value: line.substring(lastIndex, lastIndex += 2000), value: line.substring(lastIndex, lastIndex += 2000),
type: "overflow" type: "overflow"
} };
} }
currentState = "start"; currentState = "start";
stack = []; stack = [];

View file

@ -52,14 +52,14 @@ var UndoManager = function() {
(function() { (function() {
/** /**
* Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements: * Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements:
* *
* - `args[0]` is an array of deltas * - `args[0]` is an array of deltas
* - `args[1]` is the document to associate with * - `args[1]` is the document to associate with
* *
* @param {Object} options Contains additional properties * @param {Object} options Contains additional properties
* *
**/ **/
this.execute = function(options) { this.execute = function(options) {
var deltas = options.args[0]; var deltas = options.args[0];
this.$doc = options.args[1]; this.$doc = options.args[1];
@ -78,12 +78,12 @@ var UndoManager = function() {
}; };
/** /**
* [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo} * [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo}
* @param {Boolean} dontSelect {:dontSelect} * @param {Boolean} dontSelect {:dontSelect}
* *
* *
* @returns {Range} The range of the undo. * @returns {Range} The range of the undo.
**/ **/
this.undo = function(dontSelect) { this.undo = function(dontSelect) {
var deltas = this.$undoStack.pop(); var deltas = this.$undoStack.pop();
var undoSelectionRange = null; var undoSelectionRange = null;
@ -98,11 +98,11 @@ var UndoManager = function() {
}; };
/** /**
* [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo} * [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo}
* @param {Boolean} dontSelect {:dontSelect} * @param {Boolean} dontSelect {:dontSelect}
* *
* *
**/ **/
this.redo = function(dontSelect) { this.redo = function(dontSelect) {
var deltas = this.$redoStack.pop(); var deltas = this.$redoStack.pop();
var redoSelectionRange = null; var redoSelectionRange = null;
@ -117,9 +117,9 @@ var UndoManager = function() {
}; };
/** /**
* *
* Destroys the stack of undo and redo redo operations. * Destroys the stack of undo and redo redo operations.
**/ **/
this.reset = function() { this.reset = function() {
this.$undoStack = []; this.$undoStack = [];
this.$redoStack = []; this.$redoStack = [];
@ -127,36 +127,36 @@ var UndoManager = function() {
}; };
/** /**
* *
* Returns `true` if there are undo operations left to perform. * Returns `true` if there are undo operations left to perform.
* @returns {Boolean} * @returns {Boolean}
**/ **/
this.hasUndo = function() { this.hasUndo = function() {
return this.$undoStack.length > 0; return this.$undoStack.length > 0;
}; };
/** /**
* *
* Returns `true` if there are redo operations left to perform. * Returns `true` if there are redo operations left to perform.
* @returns {Boolean} * @returns {Boolean}
**/ **/
this.hasRedo = function() { this.hasRedo = function() {
return this.$redoStack.length > 0; return this.$redoStack.length > 0;
}; };
/** /**
* *
* Marks the current status clean * Marks the current status clean
**/ **/
this.markClean = function() { this.markClean = function() {
this.dirtyCounter = 0; this.dirtyCounter = 0;
}; };
/** /**
* *
* Returns if the current status is clean * Returns if the current status is clean
* @returns {Boolean} * @returns {Boolean}
**/ **/
this.isClean = function() { this.isClean = function() {
return this.dirtyCounter === 0; return this.dirtyCounter === 0;
}; };

View file

@ -13,7 +13,9 @@ var Mirror = exports.Mirror = function(sender) {
var _self = this; var _self = this;
sender.on("change", function(e) { sender.on("change", function(e) {
doc.applyDeltas(e.data); doc.applyDeltas(e.data);
deferredUpdate.schedule(_self.$timeout); if (_self.$timeout)
return deferredUpdate.schedule(_self.$timeout);
_self.onUpdate();
}); });
}; };
@ -38,6 +40,10 @@ var Mirror = exports.Mirror = function(sender) {
// abstract method // abstract method
}; };
this.isPending = function() {
return this.deferredUpdate.isPending();
};
}).call(Mirror.prototype); }).call(Mirror.prototype);
}); });

View file

@ -16,6 +16,10 @@ window.console.trace = window.console;
window.window = window; window.window = window;
window.ace = window; window.ace = window;
window.onerror = function(message, file, line, col, err) {
console.error("Worker " + err.stack);
};
window.normalizeModule = function(parentId, moduleName) { window.normalizeModule = function(parentId, moduleName) {
// normalize plugin requires // normalize plugin requires
if (moduleName.indexOf("!") !== -1) { if (moduleName.indexOf("!") !== -1) {

View file

@ -39,7 +39,6 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) {
this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
this.changeListener = this.changeListener.bind(this); this.changeListener = this.changeListener.bind(this);
this.onMessage = this.onMessage.bind(this); this.onMessage = this.onMessage.bind(this);
this.onError = this.onError.bind(this);
// nameToUrl is renamed to toUrl in requirejs 2 // nameToUrl is renamed to toUrl in requirejs 2
if (require.nameToUrl && !require.toUrl) if (require.nameToUrl && !require.toUrl)
@ -69,7 +68,6 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) {
this.callbackId = 1; this.callbackId = 1;
this.callbacks = {}; this.callbacks = {};
this.$worker.onerror = this.onError;
this.$worker.onmessage = this.onMessage; this.$worker.onmessage = this.onMessage;
}; };
@ -77,11 +75,6 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) {
oop.implement(this, EventEmitter); oop.implement(this, EventEmitter);
this.onError = function(e) {
window.console && console.log && console.log(e);
throw e;
};
this.onMessage = function(e) { this.onMessage = function(e) {
var msg = e.data; var msg = e.data;
switch(msg.type) { switch(msg.type) {
@ -157,7 +150,7 @@ var WorkerClient = function(topLevelNamespaces, mod, classname) {
this.changeListener = function(e) { this.changeListener = function(e) {
if (!this.deltaQueue) { if (!this.deltaQueue) {
this.deltaQueue = [e.data]; this.deltaQueue = [e.data];
setTimeout(this.$sendDeltaQueue, 1); setTimeout(this.$sendDeltaQueue, 0);
} else } else
this.deltaQueue.push(e.data); this.deltaQueue.push(e.data);
}; };