Fixed adjust scroll

This commit is contained in:
benweet 2014-05-21 23:54:50 +01:00
parent 0e64598127
commit 1a50f117f1

View File

@ -145,27 +145,42 @@ define([
range.setEnd(offset.container, offset.offset); range.setEnd(offset.container, offset.offset);
return range; return range;
}; };
var updateCursorCoordinates = utils.debounce(_.bind(function() { var adjustScroll;
var debouncedUpdateCursorCoordinates = utils.debounce(function() {
$inputElt.toggleClass('has-selection', this.selectionStart !== this.selectionEnd); $inputElt.toggleClass('has-selection', this.selectionStart !== this.selectionEnd);
var coordinates = this.getCoordinates(this.selectionEnd, this.selectionEndContainer, this.selectionEndOffset); var coordinates = this.getCoordinates(this.selectionEnd, this.selectionEndContainer, this.selectionEndOffset);
if(this.cursorY !== coordinates.y) { if(this.cursorY !== coordinates.y) {
this.cursorY = coordinates.y; this.cursorY = coordinates.y;
eventMgr.onCursorCoordinates(coordinates.x, coordinates.y); eventMgr.onCursorCoordinates(coordinates.x, coordinates.y);
} if(adjustScroll && settings.cursorFocusRatio) {
if(this.adjustScroll && settings.cursorFocusRatio) { var adjust = inputElt.offsetHeight / 2 * settings.cursorFocusRatio;
var adjust = inputElt.offsetHeight / 2 * settings.cursorFocusRatio; var cursorMinY = inputElt.scrollTop + adjust;
var cursorMinY = inputElt.scrollTop + adjust; var cursorMaxY = inputElt.scrollTop + inputElt.offsetHeight - adjust;
var cursorMaxY = inputElt.scrollTop + inputElt.offsetHeight - adjust; if(selectionMgr.cursorY < cursorMinY) {
if(selectionMgr.cursorY < cursorMinY) { inputElt.scrollTop += selectionMgr.cursorY - cursorMinY;
inputElt.scrollTop += selectionMgr.cursorY - cursorMinY; }
else if(selectionMgr.cursorY > cursorMaxY) {
inputElt.scrollTop += selectionMgr.cursorY - cursorMaxY;
}
} }
else if(selectionMgr.cursorY > cursorMaxY) {
inputElt.scrollTop += selectionMgr.cursorY - cursorMaxY;
}
this.adjustScroll = false;
} }
}, this)); adjustScroll = false;
this.setSelectionStartEnd = function(start, end, range, skipSelectionUpdate) { }, this);
this.updateCursorCoordinates = function(adjustScrollParam) {
adjustScroll = adjustScroll || adjustScrollParam;
debouncedUpdateCursorCoordinates();
};
this.updateSelectionRange = function(range) {
var min = Math.min(this.selectionStart, this.selectionEnd);
var max = Math.max(this.selectionStart, this.selectionEnd);
if(!range) {
range = this.createRange(min, max);
}
var selection = rangy.getSelection();
selection.removeAllRanges();
selection.addRange(range, this.selectionStart > this.selectionEnd);
};
this.setSelectionStartEnd = function(start, end) {
if(start === undefined) { if(start === undefined) {
start = this.selectionStart; start = this.selectionStart;
} }
@ -180,26 +195,11 @@ define([
} }
this.selectionStart = start; this.selectionStart = start;
this.selectionEnd = end; this.selectionEnd = end;
var min = Math.min(start, end); fileDesc.editorStart = start;
var max = Math.max(start, end); fileDesc.editorEnd = end;
range = range || this.createRange(min, max);
if(!skipSelectionUpdate) {
var selection = rangy.getSelection();
selection.removeAllRanges();
selection.addRange(range, start > end);
}
fileDesc.editorStart = this.selectionStart;
fileDesc.editorEnd = this.selectionEnd;
updateCursorCoordinates();
return range;
}; };
this.saveSelectionState = (function() { this.saveSelectionState = (function() {
var timeoutId; function save() {
function save(adjustScroll) {
clearTimeout(timeoutId);
timeoutId = undefined;
self.adjustScroll = adjustScroll;
if(fileChanged === false) { if(fileChanged === false) {
var selectionStart = self.selectionStart; var selectionStart = self.selectionStart;
var selectionEnd = self.selectionEnd; var selectionEnd = self.selectionEnd;
@ -231,19 +231,24 @@ define([
} }
} }
} }
self.setSelectionStartEnd(selectionStart, selectionEnd, range, true); self.setSelectionStartEnd(selectionStart, selectionEnd);
} }
undoMgr.saveSelectionState(); undoMgr.saveSelectionState();
} }
var nextTickAdjustScroll = false;
var debouncedSave = utils.debounce(function() {
save();
self.updateCursorCoordinates(nextTickAdjustScroll);
nextTickAdjustScroll = false;
});
return function(debounced, adjustScroll) { return function(debounced, adjustScroll) {
adjustScroll = _.isBoolean(adjustScroll) ? adjustScroll : false;
if(debounced) { if(debounced) {
clearTimeout(timeoutId); nextTickAdjustScroll = nextTickAdjustScroll || adjustScroll;
timeoutId = _.delay(save, 5, adjustScroll); return debouncedSave();
} }
else { else {
save(adjustScroll); save();
} }
}; };
})(); })();
@ -317,7 +322,7 @@ define([
var selectionMgr = new SelectionMgr(); var selectionMgr = new SelectionMgr();
editor.selectionMgr = selectionMgr; editor.selectionMgr = selectionMgr;
$(document).on('selectionchange', '.editor-content', _.bind(selectionMgr.saveSelectionState, selectionMgr, true)); $(document).on('selectionchange', '.editor-content', _.bind(selectionMgr.saveSelectionState, selectionMgr, true, false));
function adjustCursorPosition() { function adjustCursorPosition() {
if(inputElt === undefined) { if(inputElt === undefined) {
@ -361,6 +366,8 @@ define([
range.insertNode(document.createTextNode(replacement)); range.insertNode(document.createTextNode(replacement));
offset = offset - text.length + replacement.length; offset = offset - text.length + replacement.length;
selectionMgr.setSelectionStartEnd(offset, offset); selectionMgr.setSelectionStartEnd(offset, offset);
selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
return true; return true;
} }
@ -381,7 +388,7 @@ define([
function focus() { function focus() {
$contentElt.focus(); $contentElt.focus();
selectionMgr.setSelectionStartEnd(); selectionMgr.updateSelectionRange();
inputElt.scrollTop = scrollTop; inputElt.scrollTop = scrollTop;
} }
@ -405,14 +412,15 @@ define([
this.saveState = utils.debounce(function() { this.saveState = utils.debounce(function() {
redoStack = []; redoStack = [];
var currentTime = Date.now(); var currentTime = Date.now();
if(this.currentMode == 'comment' || (this.currentMode != lastMode && lastMode != 'newlines') || currentTime - lastTime > 1000) { if(this.currentMode == 'comment' || lastMode == 'newlines' || this.currentMode != lastMode || currentTime - lastTime > 1000) {
undoStack.push(currentState); undoStack.push(currentState);
// Limit the size of the stack // Limit the size of the stack
if(undoStack.length === 100) { while(undoStack.length > 100) {
undoStack.shift(); undoStack.shift();
} }
} }
else { else {
// Restore selectionBefore that has potentially been modified by saveSelectionState
selectionStartBefore = currentState.selectionStartBefore; selectionStartBefore = currentState.selectionStartBefore;
selectionEndBefore = currentState.selectionEndBefore; selectionEndBefore = currentState.selectionEndBefore;
} }
@ -450,6 +458,8 @@ define([
eventMgr.onContentChanged(fileDesc, state.content); eventMgr.onContentChanged(fileDesc, state.content);
} }
selectionMgr.setSelectionStartEnd(selectionStart, selectionEnd); selectionMgr.setSelectionStartEnd(selectionStart, selectionEnd);
selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
var discussionListJSON = fileDesc.discussionListJSON; var discussionListJSON = fileDesc.discussionListJSON;
if(discussionListJSON != state.discussionListJSON) { if(discussionListJSON != state.discussionListJSON) {
var oldDiscussionList = fileDesc.discussionList; var oldDiscussionList = fileDesc.discussionList;
@ -569,7 +579,9 @@ define([
textContent = newTextContent; textContent = newTextContent;
fileDesc.content = textContent; fileDesc.content = textContent;
selectionMgr.setSelectionStartEnd(fileDesc.editorStart, fileDesc.editorEnd); selectionMgr.setSelectionStartEnd(fileDesc.editorStart, fileDesc.editorEnd);
selectionMgr.saveSelectionState(); selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
undoMgr.saveSelectionState();
eventMgr.onFileOpen(fileDesc, textContent); eventMgr.onFileOpen(fileDesc, textContent);
previewElt.scrollTop = fileDesc.previewScrollTop; previewElt.scrollTop = fileDesc.previewScrollTop;
scrollTop = fileDesc.editorScrollTop; scrollTop = fileDesc.editorScrollTop;
@ -676,6 +688,8 @@ define([
}, },
set: function(value) { set: function(value) {
selectionMgr.setSelectionStartEnd(value); selectionMgr.setSelectionStartEnd(value);
selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
}, },
enumerable: true, enumerable: true,
@ -688,6 +702,8 @@ define([
}, },
set: function(value) { set: function(value) {
selectionMgr.setSelectionStartEnd(undefined, value); selectionMgr.setSelectionStartEnd(undefined, value);
selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
}, },
enumerable: true, enumerable: true,
@ -706,11 +722,9 @@ define([
return; return;
} }
selectionMgr.saveSelectionState(); selectionMgr.saveSelectionState();
adjustCursorPosition();
var cmdOrCtrl = evt.metaKey || evt.ctrlKey; var cmdOrCtrl = evt.metaKey || evt.ctrlKey;
if(!cmdOrCtrl) {
adjustCursorPosition();
}
switch(evt.which) { switch(evt.which) {
case 9: // Tab case 9: // Tab
@ -738,7 +752,7 @@ define([
isComposing--; isComposing--;
}, 0); }, 0);
}) })
.on('mouseup', _.bind(selectionMgr.saveSelectionState, selectionMgr, true)) .on('mouseup', _.bind(selectionMgr.saveSelectionState, selectionMgr, true, false))
.on('paste', function() { .on('paste', function() {
undoMgr.currentMode = 'paste'; undoMgr.currentMode = 'paste';
adjustCursorPosition(); adjustCursorPosition();
@ -765,7 +779,7 @@ define([
actions[action](state, options); actions[action](state, options);
setValue(state.before + state.selection + state.after); setValue(state.before + state.selection + state.after);
selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd); selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd);
selectionMgr.updateSelectionRange();
}; };
var actions = { var actions = {
@ -934,7 +948,8 @@ define([
} }
} }
addTrailingLfNode(); addTrailingLfNode();
selectionMgr.setSelectionStartEnd(); selectionMgr.updateSelectionRange();
selectionMgr.updateCursorCoordinates();
}); });
} }