mirror of
				https://github.com/ether/etherpad-lite.git
				synced 2025-10-31 16:21:11 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			669 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			669 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| describe('scroll when focus line is out of viewport', function () {
 | |
|   before(function (done) {
 | |
|     helper.newPad(function(){
 | |
|       cleanPad(function(){
 | |
|         forceUseMonospacedFont();
 | |
|         scrollWhenPlaceCaretInTheLastLineOfViewport();
 | |
|         createPadWithSeveralLines(function(){
 | |
|           resizeEditorHeight();
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
|     });
 | |
|     this.timeout(20000);
 | |
|   });
 | |
| 
 | |
|   context('when user presses any arrow keys on a line above the viewport', function(){
 | |
|     context('and scroll percentage config is set to 0.2 on settings.json', function(){
 | |
|       var lineCloseOfTopOfPad = 10;
 | |
|       before(function (done) {
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.2, true);
 | |
|         scrollEditorToBottomOfPad();
 | |
| 
 | |
|         placeCaretInTheBeginningOfLine(lineCloseOfTopOfPad, function(){ // place caret in the 10th line
 | |
|           // warning: even pressing right arrow, the caret does not change of position
 | |
|           // the column where the caret is, it has not importance, only the line
 | |
|           pressAndReleaseRightArrow(); // I don't think this is working in Edge.
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('keeps the focus line scrolled 20% from the top of the viewport', function (done) {
 | |
|         // default behavior is to put the line in the top of viewport, but as
 | |
|         // scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.2, we have an extra 20% of lines scrolled
 | |
|         // (2 lines, which are the 20% of the 10 that are visible on viewport)
 | |
|         var firstLineOfViewport = getFirstLineVisibileOfViewport();
 | |
|         expect(lineCloseOfTopOfPad).to.be(firstLineOfViewport + 2);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   context('when user presses any arrow keys on a line below the viewport', function(){
 | |
|     context('and scroll percentage config is set to 0.7 on settings.json', function(){
 | |
|       var lineCloseToBottomOfPad = 50;
 | |
|       before(function (done) {
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.7);
 | |
| 
 | |
|         // firstly, scroll to make the lineCloseToBottomOfPad visible. After that, scroll to make it out of viewport
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lineCloseToBottomOfPad); // place caret in the 50th line
 | |
|         setTimeout(function() {
 | |
|           // warning: even pressing right arrow, the caret does not change of position
 | |
|           pressAndReleaseLeftArrow();
 | |
|           done();
 | |
|         }, 1000);
 | |
|       });
 | |
| 
 | |
|       it('keeps the focus line scrolled 70% from the bottom of the viewport', function (done) {
 | |
|         // default behavior is to put the line in the top of viewport, but as
 | |
|         // scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.7, we have an extra 70% of lines scrolled
 | |
|         // (7 lines, which are the 70% of the 10 that are visible on viewport)
 | |
|         var lastLineOfViewport = getLastLineVisibleOfViewport();
 | |
|         expect(lineCloseToBottomOfPad).to.be(lastLineOfViewport - 7);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   context('when user presses arrow up on the first line of the viewport', function(){
 | |
|     context('and percentageToScrollWhenUserPressesArrowUp is set to 0.3 -- Broken in All browsers??', function () {
 | |
|       var lineOnTopOfViewportWhenThePadIsScrolledDown;
 | |
|       before(function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test
 | |
| 
 | |
|         setPercentageToScrollWhenUserPressesArrowUp(0.3);
 | |
| 
 | |
|         // we need some room to make the scroll up
 | |
|         scrollEditorToBottomOfPad();
 | |
|         lineOnTopOfViewportWhenThePadIsScrolledDown = 91;
 | |
|         placeCaretAtTheEndOfLine(lineOnTopOfViewportWhenThePadIsScrolledDown);
 | |
|         // setTimeout(function() {
 | |
|           // warning: even pressing up arrow, the caret does not change of position
 | |
|           pressAndReleaseUpArrow();
 | |
|           done();
 | |
|         // }, 2000);
 | |
|       });
 | |
| 
 | |
|       it('keeps the focus line scrolled 30% of the top of the viewport', function (done) {
 | |
|         // if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         return done(); // skip this test
 | |
|         // default behavior is to put the line in the top of viewport, but as
 | |
|         // PercentageToScrollWhenUserPressesArrowUp is set to 0.3, we have an extra 30% of lines scrolled
 | |
|         // (3 lines, which are the 30% of the 10 that are visible on viewport)
 | |
|         var firstLineOfViewport = getFirstLineVisibileOfViewport();
 | |
|         expect(firstLineOfViewport).to.be(lineOnTopOfViewportWhenThePadIsScrolledDown - 3);
 | |
|         done();
 | |
|       })
 | |
|     });
 | |
|   });
 | |
| 
 | |
| // Below tests are broken in Edge
 | |
| 
 | |
|   context('when user edits the last line of viewport -- Known Broken in Edge', function(){
 | |
| 
 | |
|     context('and scroll percentage config is set to 0 on settings.json -- Broken in Edge', function(){
 | |
|       var lastLineOfViewportBeforeEnter = 10;
 | |
|       before(function () {
 | |
|         // the default value
 | |
|         resetScrollPercentageWhenFocusLineIsOutOfViewport();
 | |
| 
 | |
|         // make sure the last line on viewport is the 10th one
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lastLineOfViewportBeforeEnter);
 | |
|         pressEnter(); // doesn't work in Edge
 | |
|       });
 | |
| 
 | |
|       it('keeps the focus line on the bottom of the viewport', function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         var lastLineOfViewportAfterEnter = getLastLineVisibleOfViewport();
 | |
|         expect(lastLineOfViewportAfterEnter).to.be(lastLineOfViewportBeforeEnter + 1);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     context('and scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.3 -- Broken in Edge', function(){ // this value is arbitrary
 | |
|       var lastLineOfViewportBeforeEnter = 9;
 | |
|       before(function () {
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.3);
 | |
| 
 | |
|         // make sure the last line on viewport is the 10th one
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lastLineOfViewportBeforeEnter);
 | |
|         pressBackspace();
 | |
|       });
 | |
| 
 | |
|       it('scrolls 30% of viewport up', function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         var lastLineOfViewportAfterEnter = getLastLineVisibleOfViewport();
 | |
|         // default behavior is to scroll one line at the bottom of viewport, but as
 | |
|         // scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.3, we have an extra 30% of lines scrolled
 | |
|         // (3 lines, which are the 30% of the 10 that are visible on viewport)
 | |
|         expect(lastLineOfViewportAfterEnter).to.be(lastLineOfViewportBeforeEnter + 3);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     context('and it is set to a value that overflow the interval [0, 1] -- Broken in Edge', function(){
 | |
|       var lastLineOfViewportBeforeEnter = 10;
 | |
|       before(function(){
 | |
|         var scrollPercentageWhenFocusLineIsOutOfViewport = 1.5;
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lastLineOfViewportBeforeEnter);
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(scrollPercentageWhenFocusLineIsOutOfViewport);
 | |
|         pressEnter(); // doesn't work in Edge
 | |
|       });
 | |
| 
 | |
|       it('keeps the default behavior of moving the focus line on the bottom of the viewport -- Broken in Edge', function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         var lastLineOfViewportAfterEnter = getLastLineVisibleOfViewport();
 | |
|         expect(lastLineOfViewportAfterEnter).to.be(lastLineOfViewportBeforeEnter + 1);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   context('when user edits a line above the viewport -- Broken in Edge', function(){
 | |
|     context('and scroll percentage config is set to 0 on settings.json -- Broken in Edge', function(){
 | |
|       var lineCloseOfTopOfPad = 10;
 | |
|       before(function () {
 | |
|         // the default value
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0);
 | |
| 
 | |
|         // firstly, scroll to make the lineCloseOfTopOfPad visible. After that, scroll to make it out of viewport
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lineCloseOfTopOfPad); // place caret in the 10th line
 | |
|         scrollEditorToBottomOfPad();
 | |
|         pressBackspace(); // edit the line where the caret is, which is above the viewport
 | |
|       });
 | |
| 
 | |
|       it('keeps the focus line on the top of the viewport -- Broken in Edge', function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         var firstLineOfViewportAfterEnter = getFirstLineVisibileOfViewport();
 | |
|         expect(firstLineOfViewportAfterEnter).to.be(lineCloseOfTopOfPad);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     context('and scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.2 -- Broken in Edge', function(){ // this value is arbitrary
 | |
|       var lineCloseToBottomOfPad = 50;
 | |
|       before(function () {
 | |
|         // we force the line edited to be above the top of the viewport
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.2, true); // set scroll jump to 20%
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretAtTheEndOfLine(lineCloseToBottomOfPad);
 | |
|         scrollEditorToBottomOfPad();
 | |
|         pressBackspace(); // edit line
 | |
|       });
 | |
| 
 | |
|       it('scrolls 20% of viewport down', function (done) {
 | |
|         if(window.navigator.userAgent.indexOf("Edge") > -1) return done(); // Skip the test if we're in Edge
 | |
|         // default behavior is to scroll one line at the top of viewport, but as
 | |
|         // scrollPercentageWhenFocusLineIsOutOfViewport is set to 0.2, we have an extra 20% of lines scrolled
 | |
|         // (2 lines, which are the 20% of the 10 that are visible on viewport)
 | |
|         var firstLineVisibileOfViewport = getFirstLineVisibileOfViewport();
 | |
|         expect(lineCloseToBottomOfPad).to.be(firstLineVisibileOfViewport + 2);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   // End of tests that are broken in Edge
 | |
| 
 | |
|   context('when user places the caret at the last line visible of viewport', function(){
 | |
|     var lastLineVisible;
 | |
|     context('and scroll percentage config is set to 0 on settings.json', function(){
 | |
|       before(function (done) {
 | |
|         // reset to the default value
 | |
|         resetScrollPercentageWhenFocusLineIsOutOfViewport();
 | |
| 
 | |
|         placeCaretInTheBeginningOfLine(0, function(){ // reset caret position
 | |
|           scrollEditorToTopOfPad();
 | |
|           lastLineVisible = getLastLineVisibleOfViewport();
 | |
|           placeCaretInTheBeginningOfLine(lastLineVisible, done); // place caret in the 9th line
 | |
|         });
 | |
| 
 | |
|       });
 | |
| 
 | |
|       it('does not scroll', function(done){
 | |
|         setTimeout(function() {
 | |
|           var lastLineOfViewport = getLastLineVisibleOfViewport();
 | |
|           var lineDoesNotScroll = lastLineOfViewport === lastLineVisible;
 | |
|           expect(lineDoesNotScroll).to.be(true);
 | |
|           done();
 | |
|         }, 1000);
 | |
|       });
 | |
|     });
 | |
|     context('and scroll percentage config is set to 0.5 on settings.json', function(){
 | |
|       before(function (done) {
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.5);
 | |
|         scrollEditorToTopOfPad();
 | |
|         placeCaretInTheBeginningOfLine(0, function(){ // reset caret position
 | |
|           // this timeout inside a callback is ugly but it necessary to give time to aceSelectionChange
 | |
|           // realizes that the selection has been changed
 | |
|           setTimeout(function() {
 | |
|             lastLineVisible = getLastLineVisibleOfViewport();
 | |
|             placeCaretInTheBeginningOfLine(lastLineVisible, done); // place caret in the 9th line
 | |
|           }, 1000);
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('scrolls line to 50% of the viewport', function(done){
 | |
|         helper.waitFor(function(){
 | |
|           var lastLineOfViewport = getLastLineVisibleOfViewport();
 | |
|           var lastLinesScrolledFiveLinesUp = lastLineOfViewport - 5 === lastLineVisible;
 | |
|           return lastLinesScrolledFiveLinesUp;
 | |
|         }).done(done);
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   // This is a special case. When user is selecting a text with arrow down or arrow left we have
 | |
|   // to keep the last line selected on focus
 | |
|   context('when the first line selected is out of the viewport and user presses shift arrow down', function(){
 | |
|     var lastLineOfPad = 99;
 | |
|     before(function (done) {
 | |
|       scrollEditorToTopOfPad();
 | |
| 
 | |
|       // make a selection bigger than the viewport height
 | |
|       var $firstLineOfSelection = getLine(0);
 | |
|       var $lastLineOfSelection = getLine(lastLineOfPad);
 | |
|       var lengthOfLastLine = $lastLineOfSelection.text().length;
 | |
|       helper.selectLines($firstLineOfSelection, $lastLineOfSelection, 0, lengthOfLastLine);
 | |
| 
 | |
|       // place the last line selected on the viewport
 | |
|       scrollEditorToBottomOfPad();
 | |
| 
 | |
|       // press a key to make the selection goes down
 | |
|       // although we can't simulate the extending of selection. It's possible to send a key event
 | |
|       // which is captured on ace2_inner scroll function.
 | |
|       pressAndReleaseLeftArrow(true);
 | |
|       done();
 | |
|     });
 | |
| 
 | |
|     it('keeps the last line selected on focus', function (done) {
 | |
|       var lastLineOfSelectionIsVisible = isLineOnViewport(lastLineOfPad);
 | |
|       expect(lastLineOfSelectionIsVisible).to.be(true);
 | |
|       done();
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   // In this scenario we avoid the bouncing scroll. E.g Let's suppose we have a big line that is
 | |
|   // the size of the viewport, and its top is above the viewport. When user presses '<-', this line
 | |
|   // will scroll down because the top is out of the viewport. When it scrolls down, the bottom of
 | |
|   // line gets below the viewport so when user presses '<-' again it scrolls up to make the bottom
 | |
|   // of line visible. If user presses arrow keys more than one time, the editor will keep scrolling up and down
 | |
|   context('when the line height is bigger than the scroll amount percentage * viewport height', function(){
 | |
|     var scrollOfEditorBeforePressKey;
 | |
|     var BIG_LINE_NUMBER = 0;
 | |
|     var MIDDLE_OF_BIG_LINE = 51;
 | |
|     before(function (done) {
 | |
|       createPadWithALineHigherThanViewportHeight(this, BIG_LINE_NUMBER, function(){
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(0.5); // set any value to force scroll to outside to viewport
 | |
|         var $bigLine = getLine(BIG_LINE_NUMBER);
 | |
| 
 | |
|         // each line has about 5 chars, we place the caret in the middle of the line
 | |
|         helper.selectLines($bigLine, $bigLine, MIDDLE_OF_BIG_LINE, MIDDLE_OF_BIG_LINE);
 | |
| 
 | |
|         scrollEditorToLeaveTopAndBottomOfBigLineOutOfViewport($bigLine);
 | |
|         scrollOfEditorBeforePressKey = getEditorScroll();
 | |
| 
 | |
|         // press a key to force to scroll
 | |
|         pressAndReleaseRightArrow();
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     // reset pad to the original text
 | |
|     after(function (done) {
 | |
|       this.timeout(5000);
 | |
|       cleanPad(function(){
 | |
|         createPadWithSeveralLines(function(){
 | |
|           resetEditorWidth();
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     // as the editor.line is inside of the viewport, it should not scroll
 | |
|     it('should not scroll', function (done) {
 | |
|       var scrollOfEditorAfterPressKey = getEditorScroll();
 | |
|       expect(scrollOfEditorAfterPressKey).to.be(scrollOfEditorBeforePressKey);
 | |
|       done();
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   // Some plugins, for example the ep_page_view, change the editor dimensions. This plugin, for example,
 | |
|   // adds padding-top to the ace_outer, which changes the viewport height
 | |
|   describe('integration with plugins which changes the margin of editor', function(){
 | |
|     context('when editor dimensions changes', function(){
 | |
|       before(function () {
 | |
|         // reset the size of editor. Now we show more than 10 lines as in the other tests
 | |
|         resetResizeOfEditorHeight();
 | |
|         scrollEditorToTopOfPad();
 | |
| 
 | |
|         // height of the editor viewport
 | |
|         var editorHeight = getEditorHeight();
 | |
| 
 | |
|         // add a big padding-top, 50% of the viewport
 | |
|         var paddingTopOfAceOuter = editorHeight/2;
 | |
|         var chrome$ = helper.padChrome$;
 | |
|         var $outerIframe = chrome$('iframe');
 | |
|         $outerIframe.css('padding-top', paddingTopOfAceOuter);
 | |
| 
 | |
|         // we set a big value to check if the scroll is made
 | |
|         setScrollPercentageWhenFocusLineIsOutOfViewport(1);
 | |
|       });
 | |
| 
 | |
|       context('and user places the caret in the last line visible of the pad', function(){
 | |
|         var lastLineVisible;
 | |
|         beforeEach(function (done) {
 | |
|           lastLineVisible = getLastLineVisibleOfViewport();
 | |
|           placeCaretInTheBeginningOfLine(lastLineVisible, done);
 | |
|         });
 | |
| 
 | |
|         it('scrolls the line where caret is', function(done){
 | |
|           helper.waitFor(function(){
 | |
|             var firstLineVisibileOfViewport = getFirstLineVisibileOfViewport();
 | |
|             var linesScrolled = firstLineVisibileOfViewport !== 0;
 | |
|             return linesScrolled;
 | |
|           }).done(done);
 | |
|         });
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   /* ********************* Helper functions/constants ********************* */
 | |
|   var TOP_OF_PAGE = 0;
 | |
|   var BOTTOM_OF_PAGE = 5000; // we use a big value to force the page to be scrolled all the way down
 | |
|   var LINES_OF_PAD = 100;
 | |
|   var ENTER = 13;
 | |
|   var BACKSPACE = 8;
 | |
|   var LEFT_ARROW = 37;
 | |
|   var UP_ARROW = 38;
 | |
|   var RIGHT_ARROW = 39;
 | |
|   var LINES_ON_VIEWPORT = 10;
 | |
|   var WIDTH_OF_EDITOR_RESIZED = 100;
 | |
|   var LONG_TEXT_CHARS = 100;
 | |
| 
 | |
|   var cleanPad = function(callback) {
 | |
|     var inner$ = helper.padInner$;
 | |
|     var $padContent = inner$('#innerdocbody');
 | |
|     $padContent.html('');
 | |
| 
 | |
|     // wait for Etherpad to re-create first line
 | |
|     helper.waitFor(function(){
 | |
|       var lineNumber = inner$('div').length;
 | |
|       return lineNumber === 1;
 | |
|     }, 2000).done(callback);
 | |
|   };
 | |
| 
 | |
|   var createPadWithSeveralLines = function(done) {
 | |
|     var line = '<span>a</span><br>';
 | |
|     var $firstLine = helper.padInner$('div').first();
 | |
|     var lines = line.repeat(LINES_OF_PAD); //arbitrary number, we need to create lines that is over the viewport
 | |
|     $firstLine.html(lines);
 | |
| 
 | |
|     helper.waitFor(function(){
 | |
|       var linesCreated = helper.padInner$('div').length;
 | |
|       return linesCreated === LINES_OF_PAD;
 | |
|     }, 4000).done(done);
 | |
|   };
 | |
| 
 | |
|   var createPadWithALineHigherThanViewportHeight = function(test, line, done) {
 | |
|     var viewportHeight = 160; //10 lines * 16px (height of line)
 | |
|     test.timeout(5000);
 | |
|     cleanPad(function(){
 | |
|       // make the editor smaller to make test easier
 | |
|       // with that width the each line has about 5 chars
 | |
|       resizeEditorWidth();
 | |
| 
 | |
|       // we create a line with 100 chars, which makes about 20 lines
 | |
|       setLongTextOnLine(line);
 | |
|       helper.waitFor(function () {
 | |
|         var $firstLine = getLine(line);
 | |
| 
 | |
|         var heightOfLine = $firstLine.get(0).getBoundingClientRect().height;
 | |
|         return heightOfLine >= viewportHeight;
 | |
|       }, 4000).done(done);
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   var setLongTextOnLine = function(line) {
 | |
|     var $line = getLine(line);
 | |
|     var longText = 'a'.repeat(LONG_TEXT_CHARS);
 | |
|     $line.html(longText);
 | |
|   };
 | |
| 
 | |
|   // resize the editor to make the tests easier
 | |
|   var resizeEditorHeight = function() {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     chrome$('#editorcontainer').css('height', getSizeOfViewport());
 | |
|   };
 | |
| 
 | |
|   // this makes about 5 chars per line
 | |
|   var resizeEditorWidth = function() {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     chrome$('#editorcontainer').css('width', WIDTH_OF_EDITOR_RESIZED);
 | |
|   };
 | |
| 
 | |
|   var resetResizeOfEditorHeight = function() {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     chrome$('#editorcontainer').css('height', '');
 | |
|   };
 | |
| 
 | |
|   var resetEditorWidth = function () {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     chrome$('#editorcontainer').css('width', '');
 | |
|   };
 | |
| 
 | |
|   var getEditorHeight = function() {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     var $editor = chrome$('#editorcontainer');
 | |
|     var editorHeight = $editor.get(0).clientHeight;
 | |
|     return editorHeight;
 | |
|   };
 | |
| 
 | |
|   var getSizeOfViewport = function() {
 | |
|     return getLinePositionOnViewport(LINES_ON_VIEWPORT) - getLinePositionOnViewport(0);
 | |
|   };
 | |
| 
 | |
|   var scrollPageTo = function(value) {
 | |
|     var outer$ = helper.padOuter$;
 | |
|     var $ace_outer = outer$('#outerdocbody').parent();
 | |
|     $ace_outer.parent().scrollTop(value);
 | |
|   };
 | |
| 
 | |
|   var scrollEditorToTopOfPad = function() {
 | |
|     scrollPageTo(TOP_OF_PAGE);
 | |
|   };
 | |
| 
 | |
|   var scrollEditorToBottomOfPad = function() {
 | |
|     scrollPageTo(BOTTOM_OF_PAGE);
 | |
|   };
 | |
| 
 | |
|   var scrollEditorToLeaveTopAndBottomOfBigLineOutOfViewport = function ($bigLine) {
 | |
|     var lineHeight = $bigLine.get(0).getBoundingClientRect().height;
 | |
|     var middleOfLine = lineHeight/2;
 | |
|     scrollPageTo(middleOfLine);
 | |
|   };
 | |
| 
 | |
|   var getLine = function(lineNum) {
 | |
|     var inner$ = helper.padInner$;
 | |
|     var $line = inner$('div').eq(lineNum);
 | |
|     return $line;
 | |
|   };
 | |
| 
 | |
|   var placeCaretAtTheEndOfLine = function(lineNum) {
 | |
|     var $targetLine = getLine(lineNum);
 | |
|     var lineLength = $targetLine.text().length;
 | |
|     helper.selectLines($targetLine, $targetLine, lineLength, lineLength);
 | |
|   };
 | |
| 
 | |
|   var placeCaretInTheBeginningOfLine = function(lineNum, cb) {
 | |
|     var $targetLine = getLine(lineNum);
 | |
|     helper.selectLines($targetLine, $targetLine, 0, 0);
 | |
|     helper.waitFor(function() {
 | |
|       var $lineWhereCaretIs = getLineWhereCaretIs();
 | |
|       return $targetLine.get(0) === $lineWhereCaretIs.get(0);
 | |
|     }).done(cb);
 | |
|   };
 | |
| 
 | |
|   var getLineWhereCaretIs = function() {
 | |
|     var inner$ = helper.padInner$;
 | |
|     var nodeWhereCaretIs = inner$.document.getSelection().anchorNode;
 | |
|     var $lineWhereCaretIs = $(nodeWhereCaretIs).closest('div');
 | |
|     return $lineWhereCaretIs;
 | |
|   };
 | |
| 
 | |
|   var getFirstLineVisibileOfViewport = function() {
 | |
|     return _.find(_.range(0, LINES_OF_PAD - 1), isLineOnViewport);
 | |
|   };
 | |
| 
 | |
|   var getLastLineVisibleOfViewport = function() {
 | |
|     return _.find(_.range(LINES_OF_PAD - 1, 0, -1), isLineOnViewport);
 | |
|   };
 | |
| 
 | |
|   var pressKey = function(keyCode, shiftIsPressed){
 | |
|     var inner$ = helper.padInner$;
 | |
| 
 | |
|     /*
 | |
|      * These events use keydown and up, not keypress.
 | |
|      * Do not change. Changing to keypress will break Edge.
 | |
|      */
 | |
|     var e = inner$.Event("keydown");
 | |
| 
 | |
|     e.shiftKey = shiftIsPressed || false;
 | |
|     e.keyCode = keyCode;
 | |
|     e.which = keyCode; // etherpad listens to 'which'
 | |
|     inner$('#innerdocbody').trigger(e);
 | |
|   };
 | |
| 
 | |
|   var releaseKey = function(keyCode){
 | |
|     var inner$ = helper.padInner$;
 | |
| 
 | |
|     /*
 | |
|      * These events use keydown and up, not keypress.
 | |
|      * Do not change. Changing to keypress will break Edge.
 | |
|      */
 | |
|     var e = inner$.Event("keyup");
 | |
| 
 | |
|     e.keyCode = keyCode;
 | |
|     e.which = keyCode; // etherpad listens to 'which'
 | |
|     inner$('#innerdocbody').trigger(e);
 | |
|   };
 | |
| 
 | |
|   var pressEnter = function() {
 | |
|     pressKey(ENTER); // This doesn't work in Edge
 | |
|   };
 | |
| 
 | |
|   var pressBackspace = function() {
 | |
|     pressKey(BACKSPACE);
 | |
|   };
 | |
| 
 | |
|   var pressAndReleaseUpArrow = function() {
 | |
|     pressKey(UP_ARROW);
 | |
|     releaseKey(UP_ARROW);
 | |
|   };
 | |
| 
 | |
|   var pressAndReleaseRightArrow = function() {
 | |
|     pressKey(RIGHT_ARROW);
 | |
|     releaseKey(RIGHT_ARROW);
 | |
|   };
 | |
| 
 | |
|   var pressAndReleaseLeftArrow = function(shiftIsPressed) {
 | |
|     pressKey(LEFT_ARROW, shiftIsPressed);
 | |
|     releaseKey(LEFT_ARROW);
 | |
|   };
 | |
| 
 | |
|   var isLineOnViewport = function(lineNumber) {
 | |
|     // in the function scrollNodeVerticallyIntoView from ace2_inner.js, iframePadTop is used to calculate
 | |
|     // how much scroll is needed. Although the name refers to padding-top, this value is not set on the
 | |
|     // padding-top.
 | |
|     var iframePadTop = 8;
 | |
|     var $line = getLine(lineNumber);
 | |
|     var linePosition = $line.get(0).getBoundingClientRect();
 | |
| 
 | |
|     // position relative to the current viewport
 | |
|     var linePositionTopOnViewport = linePosition.top - getEditorScroll() + iframePadTop;
 | |
|     var linePositionBottomOnViewport = linePosition.bottom - getEditorScroll();
 | |
| 
 | |
|     var lineBellowTop = linePositionBottomOnViewport > 0;
 | |
|     var lineAboveBottom = linePositionTopOnViewport < getClientHeightVisible();
 | |
|     var isVisible = lineBellowTop && lineAboveBottom;
 | |
| 
 | |
|     return isVisible;
 | |
|   };
 | |
| 
 | |
|   var getEditorScroll = function () {
 | |
|     var outer$ = helper.padOuter$;
 | |
|     var scrollTopFirefox = outer$('#outerdocbody').parent().scrollTop(); // works only on firefox
 | |
|     var scrollTop = outer$('#outerdocbody').scrollTop() || scrollTopFirefox;
 | |
|     return scrollTop;
 | |
|   };
 | |
| 
 | |
|   // clientHeight includes padding, so we have to subtract it and consider only the visible viewport
 | |
|   var getClientHeightVisible = function () {
 | |
|     var outer$ = helper.padOuter$;
 | |
|     var $ace_outer = outer$('#outerdocbody').parent();
 | |
|     var ace_outerHeight = $ace_outer.get(0).clientHeight;
 | |
|     var ace_outerPaddingTop = getIntValueOfCSSProperty($ace_outer, 'padding-top');
 | |
|     var paddingAddedWhenPageViewIsEnable = getPaddingAddedWhenPageViewIsEnable();
 | |
|     var clientHeight = ace_outerHeight - ( ace_outerPaddingTop + paddingAddedWhenPageViewIsEnable);
 | |
| 
 | |
|     return clientHeight;
 | |
|   };
 | |
| 
 | |
|   // ep_page_view changes the dimensions of the editor. We have to guarantee
 | |
|   // the viewport height is calculated right
 | |
|   var getPaddingAddedWhenPageViewIsEnable = function () {
 | |
|     var chrome$ = helper.padChrome$;
 | |
|     var $outerIframe = chrome$('iframe');
 | |
|     var paddingAddedWhenPageViewIsEnable = parseInt($outerIframe.css('padding-top'));
 | |
|     return paddingAddedWhenPageViewIsEnable;
 | |
|   };
 | |
| 
 | |
|   var getIntValueOfCSSProperty = function($element, property){
 | |
|     var valueString = $element.css(property);
 | |
|     return parseInt(valueString) || 0;
 | |
|   };
 | |
| 
 | |
|   var forceUseMonospacedFont = function () {
 | |
|     helper.padChrome$.window.clientVars.padOptions.useMonospaceFont = true;
 | |
|   };
 | |
| 
 | |
|   var setScrollPercentageWhenFocusLineIsOutOfViewport = function(value, editionAboveViewport) {
 | |
|     var scrollSettings = helper.padChrome$.window.clientVars.scrollWhenFocusLineIsOutOfViewport;
 | |
|     if (editionAboveViewport) {
 | |
|       scrollSettings.percentage.editionAboveViewport = value;
 | |
|     }else{
 | |
|       scrollSettings.percentage.editionBelowViewport = value;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   var resetScrollPercentageWhenFocusLineIsOutOfViewport = function() {
 | |
|     var scrollSettings = helper.padChrome$.window.clientVars.scrollWhenFocusLineIsOutOfViewport;
 | |
|     scrollSettings.percentage.editionAboveViewport = 0;
 | |
|     scrollSettings.percentage.editionBelowViewport = 0;
 | |
|   };
 | |
| 
 | |
|   var setPercentageToScrollWhenUserPressesArrowUp = function (value) {
 | |
|     var scrollSettings = helper.padChrome$.window.clientVars.scrollWhenFocusLineIsOutOfViewport;
 | |
|     scrollSettings.percentageToScrollWhenUserPressesArrowUp = value;
 | |
|   };
 | |
| 
 | |
|   var scrollWhenPlaceCaretInTheLastLineOfViewport = function() {
 | |
|     var scrollSettings = helper.padChrome$.window.clientVars.scrollWhenFocusLineIsOutOfViewport;
 | |
|     scrollSettings.scrollWhenCaretIsInTheLastLineOfViewport = true;
 | |
|   };
 | |
| 
 | |
|   var getLinePositionOnViewport = function(lineNumber) {
 | |
|     var $line = getLine(lineNumber);
 | |
|     var linePosition = $line.get(0).getBoundingClientRect();
 | |
| 
 | |
|     // position relative to the current viewport
 | |
|     return linePosition.top - getEditorScroll();
 | |
|   };
 | |
| });
 | |
| 
 |