Merge pull request #1906 from ether/down-arrow-dont-be-weird

Down arrow dont be weird
This commit is contained in:
John McLear 2013-09-28 23:38:45 -07:00
commit 6e4d94069f

View file

@ -3745,6 +3745,7 @@ function Ace2Inner(){
doDeleteKey(); doDeleteKey();
specialHandled = true; specialHandled = true;
} }
if((evt.which == 36 && evt.ctrlKey == true)){ setScrollY(0); } // Control Home send to Y = 0
if((evt.which == 33 || evt.which == 34) && type == 'keydown'){ if((evt.which == 33 || evt.which == 34) && type == 'keydown'){
evt.preventDefault(); // This is required, browsers will try to do normal default behavior on page up / down and the default behavior SUCKS evt.preventDefault(); // This is required, browsers will try to do normal default behavior on page up / down and the default behavior SUCKS
@ -3793,21 +3794,35 @@ function Ace2Inner(){
}, 200); }, 200);
} }
/* Attempt to apply some sanity to cursor handling in Chrome after a copy / paste event /* Attempt to apply some sanity to cursor handling in Chrome after a copy / paste event
We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user
presses and holds the arrow key */ presses and holds the arrow key .. Sorry if this is ugly, blame Chrome's weird handling of viewports after new content is added*/
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){ if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){
var viewport = getViewPortTopBottom(); var viewport = getViewPortTopBottom();
var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop; // get the carets selection offset in px IE 214 var caretOffsetTop = myselection.focusNode.parentNode.offsetTop || myselection.focusNode.offsetTop; // get the carets selection offset in px IE 214
var lineHeight = $(myselection.focusNode.parentNode).parent().height(); // get the line height of the caret line var lineHeight = $(myselection.focusNode.parentNode).parent("div").height(); // get the line height of the caret line
// top.console.log("offsetTop", myselection.focusNode.parentNode.parentNode.offsetTop);
try {
lineHeight = $(myselection.focusNode).height() // needed for how chrome handles line heights of null objects
// console.log("lineHeight now", lineHeight);
}catch(e){}
var caretOffsetTopBottom = caretOffsetTop + lineHeight; var caretOffsetTopBottom = caretOffsetTop + lineHeight;
var visibleLineRange = getVisibleLineRange(); // the visible lines IE 1,10 var visibleLineRange = getVisibleLineRange(); // the visible lines IE 1,10
if(caretOffsetTop){ // sometimes caretOffsetTop bugs out and returns 0, not sure why, possible Chrome bug? Either way if it does we don't wanna mess with it if(caretOffsetTop){ // sometimes caretOffsetTop bugs out and returns 0, not sure why, possible Chrome bug? Either way if it does we don't wanna mess with it
var caretIsNotVisible = (caretOffsetTop <= viewport.top || caretOffsetTopBottom >= viewport.bottom); // Is the Caret Visible to the user? // top.console.log(caretOffsetTop, viewport.top, caretOffsetTopBottom, viewport.bottom);
var caretIsNotVisible = (caretOffsetTop < viewport.top || caretOffsetTopBottom >= viewport.bottom); // Is the Caret Visible to the user?
// Expect some weird behavior caretOffsetTopBottom is greater than viewport.bottom on a keypress down
var offsetTopSamePlace = caretOffsetTop == viewport.top; // sometimes moving key left & up leaves the caret at the same point as the viewport.top, technically the caret is visible but it's not fully visible so we should move to it
if(offsetTopSamePlace && (evt.which == 37 || evt.which == 38)){
var newY = caretOffsetTop;
setScrollY(newY);
}
if(caretIsNotVisible){ // is the cursor no longer visible to the user? if(caretIsNotVisible){ // is the cursor no longer visible to the user?
// top.console.log("Caret is NOT visible to the user");
// top.console.log(caretOffsetTop,viewport.top,caretOffsetTopBottom,viewport.bottom);
// Oh boy the caret is out of the visible area, I need to scroll the browser window to lineNum. // Oh boy the caret is out of the visible area, I need to scroll the browser window to lineNum.
if(evt.which == 37 || evt.which == 38){ // If left or up arrow if(evt.which == 37 || evt.which == 38){ // If left or up arrow
var newY = caretOffsetTop; // That was easy! var newY = caretOffsetTop; // That was easy!
@ -3816,19 +3831,11 @@ function Ace2Inner(){
// only move the viewport if we're at the bottom of the viewport, if we hit down any other time the viewport shouldn't change // only move the viewport if we're at the bottom of the viewport, if we hit down any other time the viewport shouldn't change
// NOTE: This behavior only fires if Chrome decides to break the page layout after a paste, it's annoying but nothing I can do // NOTE: This behavior only fires if Chrome decides to break the page layout after a paste, it's annoying but nothing I can do
var selection = getSelection(); var selection = getSelection();
// top.console.log("line #", rep.selStart[0]); // the line our caret is on top.console.log("line #", rep.selStart[0]); // the line our caret is on
// top.console.log("firstvisible", visibleLineRange[0]); // the first visiblel ine top.console.log("firstvisible", visibleLineRange[0]); // the first visiblel ine
// top.console.log("lastVisible", visibleLineRange[1]); // the last visible line top.console.log("lastVisible", visibleLineRange[1]); // the last visible line
top.console.log(rep.selStart[0], visibleLineRange[1], rep.selStart[0], visibleLineRange[0]);
// Holding down arrow after a paste can lose the cursor -- This is the best fix I can find var newY = viewport.top + lineHeight;
if(rep.selStart[0] >= visibleLineRange[1] || rep.selStart[0] < visibleLineRange[0] ){ // if we're not at the bottom of the viewport
// top.console.log(viewport, lineHeight, myselection);
// TODO: Make it so chrome doesnt need to redraw the page by only applying this technique if required
var newY = caretOffsetTop;
}else{ // we're at the bottom of the viewport so snap to a "new viewport"
// top.console.log(viewport, lineHeight, myselection);
var newY = caretOffsetTopBottom; // Allow continuous holding of down arrow to redraw the screen so we can see what we are going to highlight
}
} }
if(newY){ if(newY){
setScrollY(newY); // set the scrollY offset of the viewport on the document setScrollY(newY); // set the scrollY offset of the viewport on the document