/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var App = require('app');
/**
* @typedef {Object} InfiniteScrollMixinOptions
* @property {String} appendHtml html to append when scroll ends and callback executed. It's common
* that root node has unique id
or class
attributes.
* @property {Function} callback function to execute when scroll ends. This function should return
* $.Deferred().promise()
instance
* @property {Function} onReject function to execute when callback
rejected.
*/
/**
* @mixin App.InfiniteScrollMixin
* This mixin provides methods to attach infinite scroll to specific scrollable element.
*
* Usage:
*
* // mix it
* var myView = Em.View.extend(App.InfiniteScrollMixin, {
* didInsertElement: function() {
* // call method infiniteScrollInit
* this.infiniteScrollInit($('.some-scrollable'), {
* callback: this.someCallbacOnEndReached
* });
* }
* });
*
*
*/
App.InfiniteScrollMixin = Ember.Mixin.create({
/**
* Stores callback execution progress.
*
* @type {Boolean}
*/
_infiniteScrollCallbackInProgress: false,
/**
* Stores HTMLElement infinite scroll initiated on.
*
* @type {HTMLElement}
*/
_infiniteScrollEl: null,
/**
* Default options for infinite scroll.
*
* @type {InfiniteScrollMixinOptions}
*/
_infiniteScrollDefaults: {
appendHtml: '
id
or class
attribute to avoid removing additional
* elements.
*
* @param {String} htmlString string to remove
*/
_infiniteScrollRemoveHtml: function(htmlString) {
this.get('_infiniteScrollEl').find(this._infiniteScrollGetSelector(htmlString)).remove();
},
/**
* Get root node selector.
* id
attribute has higher priority and will return if found.
* class
if no id
attribute found class
attribute
* will be used.
*
* @param {String} htmlString string processed as HTML
* @return {[type]} [description]
*/
_infiniteScrollGetSelector: function(htmlString) {
var html = $(htmlString);
var elId = html.attr('id');
var elClass = (html.attr('class') || '').split(' ').join('.');
html = null;
return !!elId ? '#' + elId : '.' + elClass;
},
/**
* Remove infinite scroll.
* Unbind all listeners.
*/
infiniteScrollDestroy: function() {
this.get('_infiniteScrollEl').off('scroll', this._infiniteScrollHandler);
this.get('_infiniteScrollEl').off('infinite-scroll-end', this._infiniteScrollHandler);
this.set('_infiniteScrollEl', null);
},
/**
* Set if there is more data to load on next scroll end event.
* @param {boolean} isAvailable true
when there are more data to fetch
*/
infiniteScrollSetDataAvailable: function(isAvailable) {
this.set('_infiniteScrollMoreData', isAvailable);
}
});