define(function(require, exports, module) { "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; }, /** * disable the plugin * @memberOf PullUp * @override Base * @return {PullUp} */ pluginDisable: function() { var self = this; self.userConfig.container || 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; if (!self.userConfig.container) { 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"; pullup.style.textAlign = "center"; self.xscroll.container.appendChild(pullup); Util.addClass(pullup, clsPrefix + self.status); pullup.innerHTML = self.userConfig[self.status + "Content"] || self.userConfig.content; } else { self.pullup = self.userConfig.container } self.xscroll.boundry.expandBottom(self.userConfig.height); self.status = 'up'; 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; if (!this.userConfig.container) { 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; }, stop: function() { var xscroll = this.xscroll; this.isLoading = false; this._changeStatus("stop"); this.pluginDisable() return this; }, restart: function() { var xscroll = this.xscroll; this.isLoading = false; this._changeStatus("default"); this.render() return this; } }); if (typeof module == 'object' && module.exports) { module.exports = PullUp; } /** ignored by jsdoc **/ else if (window.XScroll && window.XScroll.Plugins) { return XScroll.Plugins.PullUp = PullUp; } });