"use strict";
var Util = require('../util');
var Base = require('../base');
var clsPrefix;
var containerCls;
var loadingContent = "Loading...";
var upContent = "Pull Up To Refresh";
var downContent = "Release To Refresh";
var PULL_UP_HEIGHT = 60;
var HEIGHT = 40;
/**
* A pullup to load plugin for xscroll.
* @constructor
* @param {object} cfg
* @param {number} cfg.height
* @param {string} cfg.downContent
* @param {string} cfg.upContent
* @param {string} cfg.loadingContent
* @param {string} cfg.clsPrefix class prefix which default value is "xs-plugin-pullup-"
* @param {number} cfg.bufferHeight preload data before scrolling to the bottom of the boundry
* @extends {Base}
*/
var PullUp = function(cfg) {
PullUp.superclass.constructor.call(this);
this.userConfig = Util.mix({
upContent: upContent,
downContent: downContent,
pullUpHeight: PULL_UP_HEIGHT,
height: HEIGHT,
loadingContent: loadingContent,
bufferHeight: 0,
clsPrefix: "xs-plugin-pullup-"
}, cfg);
}
Util.extend(PullUp, Base, {
/**
* a pluginId
* @memberOf PullUp
* @type {string}
*/
pluginId: "pullup",
/**
* plugin initializer
* @memberOf PullUp
* @override Base
* @return {PullUp}
*/
pluginInitializer: function(xscroll) {
var self = this;
self.xscroll = xscroll.render();
clsPrefix = self.userConfig.clsPrefix;
self.render();
return self;
},
/**
* detroy the plugin
* @memberOf PullUp
* @override Base
* @return {PullUp}
*/
pluginDestructor: function() {
var self = this;
Util.remove(self.pullup);
self.xscroll.off("scrollend", self._scrollEndHandler, self);
self.xscroll.off("scroll", self._scrollHandler, self);
self.xscroll.off("pan", self._panHandler, self);
self.xscroll.boundry.resetBottom();
self.__isRender = false;
self._evtBinded = false;
},
/**
* render pullup plugin
* @memberOf PullUp
* @return {PullUp}
*/
render: function() {
var self = this;
if (self.__isRender) return;
self.__isRender = true;
var containerCls = clsPrefix + "container";
var height = self.userConfig.height;
var pullup = self.pullup = document.createElement("div");
pullup.className = containerCls;
pullup.style.position = "absolute";
pullup.style.width = "100%";
pullup.style.height = height + "px";
pullup.style.bottom = -height + "px";
self.xscroll.container.appendChild(pullup);
self.xscroll.boundry.expandBottom(self.userConfig.height);
self.status = 'up';
Util.addClass(pullup, clsPrefix + self.status);
pullup.innerHTML = self.userConfig[self.status + "Content"] || self.userConfig.content;
self._bindEvt();
return self;
},
_bindEvt: function() {
var self = this;
if (self._evtBinded) return;
self._evtBinded = true;
var pullup = self.pullup;
var xscroll = self.xscroll;
xscroll.on("pan", self._panHandler, self);
//load width a buffer
if (self.userConfig.bufferHeight > 0) {
xscroll.on("scroll", self._scrollHandler, self);
}
//bounce bottom
xscroll.on("scrollend", self._scrollEndHandler, self);
return self;
},
_scrollEndHandler: function(e) {
var self = this,
xscroll = self.xscroll,
scrollTop = xscroll.getScrollTop();
if (scrollTop == xscroll.containerHeight - xscroll.height + self.userConfig.height) {
self._changeStatus("loading");
}
return self;
},
_scrollHandler: function(e) {
var self = this,
xscroll = self.xscroll;
if (!self.isLoading && Math.abs(e.scrollTop) + xscroll.height + self.userConfig.height + self.userConfig.bufferHeight >= xscroll.containerHeight + xscroll.boundry._xtop + xscroll.boundry._xbottom) {
self._changeStatus("loading");
}
return self;
},
_panHandler: function(e) {
var self = this;
var xscroll = self.xscroll;
var offsetTop = -xscroll.getScrollTop();
if (offsetTop < xscroll.height - xscroll.containerHeight - self.userConfig.pullUpHeight) {
self._changeStatus("down")
} else {
self._changeStatus("up");
}
return self;
},
_changeStatus: function(status) {
if (status != "loading" && this.isLoading) return;
var prevVal = this.status;
this.status = status;
Util.removeClass(this.pullup, clsPrefix + prevVal)
Util.addClass(this.pullup, clsPrefix + status);
this.pullup.innerHTML = this.userConfig[status + "Content"];
if (prevVal != status) {
this.trigger("statuschange", {
prevVal: prevVal,
newVal: status
});
if (status == "loading") {
this.isLoading = true;
this.trigger("loading");
}
}
return this;
},
/**
* notify pullup plugin to complete state after a remote data request
* @memberOf PullUp
* @return {PullUp}
*/
complete: function() {
var self = this;
var xscroll = self.xscroll;
self.isLoading = false;
self._changeStatus("up");
return self;
}
});
if (typeof module == 'object' && module.exports) {
module.exports = PullUp;
}