From 9f54a65c88176abb850e39dcbff07fda159538b6 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 18 Mar 2013 17:40:18 +0000 Subject: [PATCH] refactored arrow keys now work after paste in chrome --- src/static/js/ace2_inner.js | 88 ++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 2dc6408b..905a7331 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -3722,29 +3722,44 @@ function Ace2Inner(){ var isPageUp = evt.which === 33; scheduler.setTimeout(function(){ - var newVisibleLineRange = getVisibleLineRange(); - var linesCount = rep.lines.length(); + var newVisibleLineRange = getVisibleLineRange(); // the visible lines IE 1,10 + var linesCount = rep.lines.length(); // total count of lines in pad IE 10 + var numberOfLinesInViewport = newVisibleLineRange[1] - newVisibleLineRange[0]; // How many lines are in the viewport right now? + + top.console.log(rep); + top.console.log("old vis", oldVisibleLineRange); - var newCaretRow = rep.selStart[0]; if(isPageUp){ - newCaretRow = oldVisibleLineRange[0]; + if(rep.selStart[0] == oldVisibleLineRange[0]+1 || rep.selStart[0] == oldVisibleLineRange[0] || rep.selStart[0] == oldVisibleLineRange[0] -1){ // if we're at the top of the document + rep.selEnd[0] = oldVisibleLineRange[0] - numberOfLinesInViewport; + } + else if(rep.selEnd[0] < (oldVisibleLineRange[0]+1)){ // If it's mostly near the bottom of a document + rep.selEnd[0] = oldVisibleLineRange[0]; // dont go further in the page up than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content + rep.selStart[0] = oldVisibleLineRange[0]; // dont go further in the page up than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content + } } - if(isPageDown){ - newCaretRow = newVisibleLineRange[0] + topOffset; + if(isPageDown){ // if we hit page down + if(rep.selEnd[0] > oldVisibleLineRange[0]){ + // top.console.log("new bottom", oldVisibleLineRange[1]); + rep.selStart[0] = oldVisibleLineRange[1] -1; // dont go further in the page down than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content + rep.selEnd[0] = oldVisibleLineRange[1] -1; // dont go further in the page down than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content + } } //ensure min and max - if(newCaretRow < 0){ - newCaretRow = 0; + if(rep.selEnd[0] < 0){ + rep.selEnd[0] = 0; } - if(newCaretRow >= linesCount){ - newCaretRow = linesCount-1; + if(rep.selEnd[0] >= linesCount){ + rep.selEnd[0] = linesCount-1; } - - rep.selStart[0] = newCaretRow; - rep.selEnd[0] = newCaretRow; +top.console.log(rep) updateBrowserSelectionFromRep(); + 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 + setScrollY(caretOffsetTop); // set the scrollY offset of the viewport on the document + }, 200); } @@ -3752,32 +3767,43 @@ function Ace2Inner(){ 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 */ if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){ - - var newVisibleLineRange = getVisibleLineRange(); // get the current visible range -- This works great. - var lineHeight = textLineHeight(); // what Is the height of each line? + 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 caretOffsetTop = myselection.focusNode.parentNode.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 caretOffsetTopBottom = caretOffsetTop + lineHeight; + 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 - var lineNum = Math.round(caretOffsetTop / lineHeight) ; // Get the current Line Number IE 84 - newVisibleLineRange[1] = newVisibleLineRange[1]-1; - var caretIsVisible = (lineNum > newVisibleLineRange[0] && lineNum < newVisibleLineRange[1]); // Is the cursor in the visible Range IE ie 84 > 14 and 84 < 90? - - if(!caretIsVisible){ // is the cursor no longer visible to the user? + var caretIsNotVisible = (caretOffsetTop <= viewport.top || caretOffsetTopBottom >= viewport.bottom); // Is the Caret Visible to the user? + if(caretIsNotVisible){ // is the cursor no longer visible to the user? // Oh boy the caret is out of the visible area, I need to scroll the browser window to lineNum. - // Get the new Y by getting the line number and multiplying by the height of each line. - if(evt.which == 37 || evt.which == 38){ // If left or up - var newY = lineHeight * (lineNum -1); // -1 to go to the line above - }else if(evt.which == 39 || evt.which == 40){ // if down or right - var newY = getScrollY() + (lineHeight*3); // the offset and one additional line + if(evt.which == 37 || evt.which == 38){ // If left or up arrow + var newY = caretOffsetTop; // That was easy! + } + if(evt.which == 39 || evt.which == 40){ // if down or right arrow + // 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 + var selection = getSelection(); + // 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("lastVisible", visibleLineRange[1]); // the last visible line + + // Holding down arrow after a paste can lose the cursor -- This is the best fix I can find + 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); + 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){ + setScrollY(newY); // set the scrollY offset of the viewport on the document } - setScrollY(newY); // set the scroll height of the browser } - } - } - } if (type == "keydown") @@ -5109,7 +5135,7 @@ function Ace2Inner(){ setLineListType(mod[0], mod[1]); }); } - + function doInsertUnorderedList(){ doInsertList('bullet'); }