define("dojox/mobile/ScrollableView", [ "dojo/_base/array", "dojo/_base/declare", "dojo/dom-class", "dojo/dom-construct", "dijit/registry", // registry.byNode "./View", "./_ScrollableMixin" ], function(array, declare, domClass, domConstruct, registry, View, ScrollableMixin){ // module: // dojox/mobile/ScrollableView return declare("dojox.mobile.ScrollableView", [View, ScrollableMixin], { // summary: // A container that has a touch scrolling capability. // description: // ScrollableView is a subclass of View (dojox/mobile/View). // Unlike the base View class, ScrollableView's domNode always stays // at the top of the screen and its height is "100%" of the screen. // Inside this fixed domNode, the containerNode scrolls. The browser's // default scrolling behavior is disabled, and the scrolling mechanism is // reimplemented in JavaScript. Thus the user does not need to use the // two-finger operation to scroll the inner DIV (containerNode). // The main purpose of this widget is to realize fixed-positioned header // and/or footer bars. // scrollableParams: Object // Parameters for dojox/mobile/scrollable.init(). scrollableParams: null, // keepScrollPos: Boolean // Overrides dojox/mobile/View/keepScrollPos. keepScrollPos: false, constructor: function(){ // summary: // Creates a new instance of the class. this.scrollableParams = {noResize: true}; }, buildRendering: function(){ this.inherited(arguments); domClass.add(this.domNode, "mblScrollableView"); this.domNode.style.overflow = "hidden"; this.domNode.style.top = "0px"; this.containerNode = domConstruct.create("div", {className:"mblScrollableViewContainer"}, this.domNode); this.containerNode.style.position = "absolute"; this.containerNode.style.top = "0px"; // view bar is relative if(this.scrollDir === "v"){ this.containerNode.style.width = "100%"; } }, startup: function(){ if(this._started){ return; } this.reparent(); this.inherited(arguments); }, resize: function(){ // summary: // Calls resize() of each child widget. this.inherited(arguments); // scrollable#resize() will be called array.forEach(this.getChildren(), function(child){ if(child.resize){ child.resize(); } }); }, isTopLevel: function(/*Event*/e){ // summary: // Returns true if this is a top-level widget. // Overrides dojox/mobile/scrollable.isTopLevel. var parent = this.getParent && this.getParent(); return (!parent || !parent.resize); // top level widget }, addFixedBar: function(/*Widget*/widget){ // summary: // Adds a view local fixed bar to this widget. // description: // This method can be used to programmatically add a view local // fixed bar to ScrollableView. The bar is appended to this // widget's domNode. The addChild API cannot be used for this // purpose, because it adds the given widget to containerNode. var c = widget.domNode; var fixed = this.checkFixedBar(c, true); if(!fixed){ return; } // Fixed bar has to be added to domNode, not containerNode. this.domNode.appendChild(c); if(fixed === "top"){ this.fixedHeaderHeight = c.offsetHeight; this.isLocalHeader = true; }else if(fixed === "bottom"){ this.fixedFooterHeight = c.offsetHeight; this.isLocalFooter = true; c.style.bottom = "0px"; } this.resize(); }, reparent: function(){ // summary: // Moves all the children, except header and footer, to // containerNode. var i, idx, len, c; for(i = 0, idx = 0, len = this.domNode.childNodes.length; i < len; i++){ c = this.domNode.childNodes[idx]; // search for view-specific header or footer if(c === this.containerNode || this.checkFixedBar(c, true)){ idx++; continue; } this.containerNode.appendChild(this.domNode.removeChild(c)); } }, onAfterTransitionIn: function(moveTo, dir, transition, context, method){ // summary: // Overrides View.onAfterTransitionIn to flash the scroll bar // after performing a view transition. this.flashScrollBar(); }, getChildren: function(){ // summary: // Overrides _WidgetBase.getChildren to add local fixed bars, // which are not under containerNode, to the children array. var children = this.inherited(arguments); if(this.fixedHeader && this.fixedHeader.parentNode === this.domNode){ children.push(registry.byNode(this.fixedHeader)); } if(this.fixedFooter && this.fixedFooter.parentNode === this.domNode){ children.push(registry.byNode(this.fixedFooter)); } return children; } }); });