Merge pull request #1527 from ajaxorg/nc

renderer fixes backported from newClient
This commit is contained in:
Lennart Kats 2013-07-22 12:30:02 -07:00
commit 5bc96b69fc
7 changed files with 139 additions and 72 deletions

View file

@ -119,7 +119,6 @@ exports.singleLineEditor = function(el) {
new MultiSelect(editor);
editor.session.setUndoManager(new UndoManager());
editor.setHighlightActiveLine(false);
editor.setShowPrintMargin(false);
editor.renderer.setShowGutter(false);
editor.renderer.setHighlightGutterLine(false);

View file

@ -624,6 +624,8 @@ var Editor = function(renderer, session) {
if (this.$highlightActiveLine) {
if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
highlight = this.getCursorPosition();
if (this.renderer.$maxLines && this.session.getLength() === 1)
highlight = false;
}
if (session.$highlightLineMarker && !highlight) {

View file

@ -150,7 +150,8 @@ function GutterHandler(mouseHandler) {
hideTooltip();
}, 50);
});
editor.on("changeSession", hideTooltip);
}
exports.GutterHandler = GutterHandler;

View file

@ -46,11 +46,6 @@ var MouseHandler = function(editor) {
new DefaultGutterHandler(this);
new DragdropHandler(this);
event.addListener(editor.container, "mousedown", function(e) {
editor.focus();
return event.preventDefault(e);
});
var mouseTarget = editor.renderer.getMouseEventTarget();
event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
@ -62,6 +57,16 @@ var MouseHandler = function(editor) {
event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
event.addListener(mouseTarget, "mousedown", function(e) {
editor.focus();
return event.preventDefault(e);
});
event.addListener(gutterEl, "mousedown", function(e) {
editor.focus();
return event.preventDefault(e);
});
};
(function() {

View file

@ -867,13 +867,16 @@ exports.onSessionChange = function(e) {
// adds multiple selection support to the editor
// (note: should be called only once for each editor instance)
function MultiSelect(editor) {
if (editor.$multiselectOnSessionChange)
return;
editor.$onAddRange = editor.$onAddRange.bind(editor);
editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
exports.onSessionChange.call(editor, editor);
editor.on("changeSession", exports.onSessionChange.bind(editor));
editor.$multiselectOnSessionChange(editor);
editor.on("changeSession", editor.$multiselectOnSessionChange);
editor.on("mousedown", onMouseDown);
editor.commands.addCommands(commands.defaultCommands);
@ -908,4 +911,23 @@ function addAltCursorListeners(editor){
exports.MultiSelect = MultiSelect;
require("./config").defineOptions(Editor.prototype, "editor", {
enableMultiselect: {
set: function(val) {
MultiSelect(this);
if (val) {
this.on("changeSession", this.$multiselectOnSessionChange);
this.on("mousedown", onMouseDown);
} else {
this.off("changeSession", this.$multiselectOnSessionChange);
this.off("mousedown", onMouseDown);
}
},
value: true
}
})
});

View file

@ -47,7 +47,7 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
*
* @constructor
**/
var ScrollBarV = function(parent) {
var ScrollBarV = function(parent, renderer) {
this.element = dom.createElement("div");
this.element.className = "ace_scrollbar";
@ -62,6 +62,7 @@ var ScrollBarV = function(parent) {
// of 0px
// in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
// make element a little bit wider to retain scrollbar when page is zoomed
renderer.$scrollbarWidth =
this.width = dom.scrollbarWidth(parent.ownerDocument);
this.fullWidth = this.width;
this.element.style.width = (this.width || 15) + 5 + "px";
@ -71,7 +72,7 @@ var ScrollBarV = function(parent) {
event.addListener(this.element, "scroll", this.onScrollV.bind(this));
};
var ScrollBarH = function(parent) {
var ScrollBarH = function(parent, renderer) {
this.element = dom.createElement("div");
this.element.className = "ace_scrollbar-h";
@ -86,7 +87,7 @@ var ScrollBarH = function(parent) {
// of 0px
// in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
// make element a little bit wider to retain scrollbar when page is zoomed
this.height = dom.scrollbarWidth(parent.ownerDocument);
this.height = renderer.$scrollbarWidth;
this.fullHeight = this.height;
this.element.style.height = (this.height || 15) + 5 + "px";
this.setVisible(false);

View file

@ -105,8 +105,8 @@ var VirtualRenderer = function(container, theme) {
this.$vScroll = false;
this.scrollBar =
this.scrollBarV = new ScrollBarV(this.container);
this.scrollBarH = new ScrollBarH(this.container);
this.scrollBarV = new ScrollBarV(this.container, this);
this.scrollBarH = new ScrollBarH(this.container, this);
this.scrollBarV.addEventListener("scroll", function(e) {
if (!_self.$scrollAnimation)
_self.session.setScrollTop(e.data - _self.scrollMargin.top);
@ -210,7 +210,9 @@ var VirtualRenderer = function(container, theme) {
this.setStyle("ace_nobold", !this.$allowBoldFonts);
}
this.layerConfig.characterWidth =
this.characterWidth = this.$textLayer.getCharacterWidth();
this.layerConfig.lineHeight =
this.lineHeight = this.$textLayer.getLineHeight();
this.$updatePrintMargin();
};
@ -308,32 +310,44 @@ var VirtualRenderer = function(container, theme) {
*
**/
this.onResize = function(force, gutterWidth, width, height) {
// if (force)
// console.log("force resize requested", width, height)
if (this.resizing > 2)
return;
else if (this.resizing > 0)
this.resizing++;
else
this.resizing = force ? 1 : 0;
// `|| el.scrollHeight` is required for outosizing editors on ie
// where elements with clientHeight = 0 alsoe have clientWidth = 0
var el = this.container;
if (!height)
height = this.container.clientHeight;
height = el.clientHeight || el.scrollHeight;
if (!width)
width = this.container.clientWidth;
width = el.clientWidth || el.scrollWidth;
var changes = this.$updateCachedSize(force, gutterWidth, width, height);
// console.log("resizing to", width, height, JSON.stringify(this.$size))
// setTimeout(function() {
// console.log("actual size ", this.container.clientWidth, this.container.clientHeight)
// }.bind(this), 500)
if (!this.$size.scrollerHeight)
return;
return this.resizing = 0;
if (force)
this.$gutterLayer.$padding = null;
if (force)
this.$renderChanges(changes, true);
else
this.$loop.schedule(changes);
if (force)
this.$gutterLayer.$padding = null;
if (force)
delete this.resizing;
if (this.resizing)
this.resizing = 0;
};
this.$updateCachedSize = function(force, gutterWidth, width, height) {
@ -347,7 +361,8 @@ var VirtualRenderer = function(container, theme) {
if (this.$horizScroll)
size.scrollerHeight -= this.scrollBarH.getHeight();
this.scrollBarV.setHeight(size.scrollerHeight);
// this.scrollBarV.setHeight(size.scrollerHeight);
this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px";
if (this.session) {
this.session.setScrollTop(this.getScrollTop());
@ -355,19 +370,24 @@ var VirtualRenderer = function(container, theme) {
}
}
if (width && (force || this.resizing > 1 || size.width != width)) {
if (width && (force || size.width != width)) {
changes = this.CHANGE_SIZE;
size.width = width;
gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
if (gutterWidth == null)
gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
this.gutterWidth = gutterWidth;
this.scrollBarH.element.style.left =
this.scroller.style.left = gutterWidth + "px";
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
this.scrollBarH.element.style.right =
this.scroller.style.right = this.scrollBarV.getWidth() + "px";
this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
this.scrollBarH.setWidth(size.scrollerWidth);
// this.scrollBarH.element.style.setWidth(size.scrollerWidth);
if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
changes = changes | this.CHANGE_FULL;
@ -376,17 +396,13 @@ var VirtualRenderer = function(container, theme) {
if (changes)
this._signal("resize");
if (this.$changes) {
changes |= this.$changes;
this.$changes = 0;
}
return changes;
};
this.onGutterResize = function() {
var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
if (gutterWidth != this.gutterWidth)
this.$changes != this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
if (this.session.getUseWrapMode() && this.adjustWrapLimit())
this.$loop.schedule(this.CHANGE_FULL);
@ -714,10 +730,14 @@ var VirtualRenderer = function(container, theme) {
};
this.$renderChanges = function(changes, force) {
if (!force && (!changes || !this.session || !this.container.offsetWidth)) {
this.$changes = changes;
if ((!this.session || !this.container.offsetWidth) || (!changes && !force)) {
this.$changes |= changes;
return;
}
if (this.$changes) {
changes |= this.$changes;
this.$changes = 0;
}
// this.$logChanges(changes);
@ -730,7 +750,7 @@ var VirtualRenderer = function(container, theme) {
changes & this.CHANGE_SCROLL ||
changes & this.CHANGE_H_SCROLL
)
this.$computeLayerConfig();
changes |= this.$computeLayerConfig();
// horizontal scrolling
if (changes & this.CHANGE_H_SCROLL) {
@ -841,9 +861,6 @@ var VirtualRenderer = function(container, theme) {
if (this.$maxLines && this.lineHeight > 1)
this.$autosize();
if (!this.$size.scrollerHeight)
return this.onResize(true);
var session = this.session;
var hideScrollbars = this.$size.height <= 2 * this.lineHeight;
@ -911,6 +928,16 @@ var VirtualRenderer = function(container, theme) {
offset = this.scrollTop - firstRowScreen * lineHeight;
var changes = 0;
// Horizontal scrollbar visibility may have changed, which changes
// the client height of the scroller
if (hScrollChanged || vScrollChanged) {
changes = this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height);
this._signal("scrollbarVisibilityChanged");
if (vScrollChanged)
longestLine = this.$getLongestLine();
}
this.layerConfig = {
width : longestLine,
padding : this.$padding,
@ -933,12 +960,7 @@ var VirtualRenderer = function(container, theme) {
this.content.style.width = longestLine + 2 * this.$padding + "px";
this.content.style.height = minHeight + "px";
// Horizontal scrollbar visibility may have changed, which changes
// the client height of the scroller
if (hScrollChanged || vScrollChanged) {
this.onResize(true);
this._signal("scrollbarVisibilityChanged");
}
return changes;
};
this.$updateLines = function() {
@ -1070,8 +1092,10 @@ var VirtualRenderer = function(container, theme) {
var left = pos.left;
var top = pos.top;
var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
if (this.scrollTop > top) {
if (scrollTop > top) {
if (offset)
top -= offset * this.$size.scrollerHeight;
if (top == 0)
@ -1079,7 +1103,7 @@ var VirtualRenderer = function(container, theme) {
else if (top == 0)
top = + this.scrollMargin.bottom;
this.session.setScrollTop(top);
} else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
} else if (scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
if (offset)
top += offset * this.$size.scrollerHeight;
this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
@ -1196,31 +1220,44 @@ var VirtualRenderer = function(container, theme) {
this.animateScrolling = function(fromValue, callback) {
var toValue = this.scrollTop;
if (this.$animatedScroll) {
var _self = this;
var steps = _self.$calcSteps(fromValue, toValue);
this.$scrollAnimation = {from: fromValue, to: toValue};
clearInterval(this.$timer);
_self.session.setScrollTop(steps.shift());
this.$timer = setInterval(function() {
if (steps.length) {
_self.session.setScrollTop(steps.shift());
// trick session to think it's already scrolled to not loose toValue
_self.session.$scrollTop = toValue;
} else if (toValue != null) {
_self.session.$scrollTop = -1;
_self.session.setScrollTop(toValue);
toValue = null;
} else {
// do this on separate step to not get spurious scroll event from scrollbar
_self.$timer = clearInterval(_self.$timer);
_self.$scrollAnimation = null;
callback && callback();
}
}, 10);
if (!this.$animatedScroll)
return;
var _self = this;
if (fromValue == toValue)
return;
if (this.$scrollAnimation) {
var oldSteps = this.$scrollAnimation.steps;
if (oldSteps.length) {
fromValue = oldSteps[0];
if (fromValue == toValue)
return;
}
}
var steps = _self.$calcSteps(fromValue, toValue);
this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};
clearInterval(this.$timer);
_self.session.setScrollTop(steps.shift());
this.$timer = setInterval(function() {
if (steps.length) {
_self.session.setScrollTop(steps.shift());
// trick session to think it's already scrolled to not loose toValue
_self.session.$scrollTop = toValue;
} else if (toValue != null) {
_self.session.$scrollTop = -1;
_self.session.setScrollTop(toValue);
toValue = null;
} else {
// do this on separate step to not get spurious scroll event from scrollbar
_self.$timer = clearInterval(_self.$timer);
_self.$scrollAnimation = null;
callback && callback();
}
}, 10);
};
/**