Ghost/ghost/admin/app/mixins/ed-editor-scroll.js
Jason Williams 40a176c772 Fix up editor/preview scroll and post list loading
Refs #5381
- Invoke this._super() so mixed in lifecycle hooks run.
2015-06-22 11:35:17 -05:00

107 lines
3.2 KiB
JavaScript

import Ember from 'ember';
import setScrollClassName from 'ghost/utils/set-scroll-classname';
var EditorScroll = Ember.Mixin.create({
/**
* Determine if the cursor is at the end of the textarea
*/
isCursorAtEnd: function () {
var selection = this.$().getSelection(),
value = this.getValue(),
linesAtEnd = 3,
stringAfterCursor,
match;
stringAfterCursor = value.substring(selection.end);
/* jscs: disable */
match = stringAfterCursor.match(/\n/g);
/* jscs: enable */
if (!match || match.length < linesAtEnd) {
return true;
}
return false;
},
/**
* Build an object that represents the scroll state
*/
getScrollInfo: function () {
var scroller = this.get('element'),
scrollInfo = {
top: scroller.scrollTop,
height: scroller.scrollHeight,
clientHeight: scroller.clientHeight,
diff: scroller.scrollHeight - scroller.clientHeight,
padding: 50,
isCursorAtEnd: this.isCursorAtEnd()
};
return scrollInfo;
},
/**
* Calculate if we're within scrollInfo.padding of the end of the document, and scroll the rest of the way
*/
adjustScrollPosition: function () {
// If we're receiving change events from the end of the document, i.e the user is typing-at-the-end, update the
// scroll position to ensure both panels stay in view and in sync
var scrollInfo = this.getScrollInfo();
if (scrollInfo.isCursorAtEnd && (scrollInfo.diff >= scrollInfo.top) &&
(scrollInfo.diff < scrollInfo.top + scrollInfo.padding)) {
scrollInfo.top += scrollInfo.padding;
// Scroll the left pane
this.$().scrollTop(scrollInfo.top);
}
},
/**
* Send the scrollInfo for scrollEvents to the view so that the preview pane can be synced
*/
scrollHandler: function () {
this.set('scrollThrottle', Ember.run.throttle(this, function () {
this.set('scrollInfo', this.getScrollInfo());
}, 10));
},
/**
* once the element is in the DOM bind to the events which control scroll behaviour
*/
attachScrollHandlers: function () {
var $el = this.$();
$el.on('keypress', Ember.run.bind(this, this.adjustScrollPosition));
$el.on('scroll', Ember.run.bind(this, this.scrollHandler));
$el.on('scroll', Ember.run.bind($el, setScrollClassName, {
target: Ember.$('.js-entry-markdown'),
offset: 10
}));
},
/**
* once the element has been removed from the DOM unbind from the events which control scroll behaviour
*/
detachScrollHandlers: function () {
this.$().off('keypress');
this.$().off('scroll');
Ember.run.cancel(this.get('scrollThrottle'));
},
didInsertElement: function () {
this._super();
this.attachScrollHandlers();
},
willDestroyElement: function () {
this._super();
this.detachScrollHandlers();
}
});
export default EditorScroll;