UNPKG

dijit

Version:

Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u

191 lines (166 loc) 7.06 kB
define([ "dojo/_base/lang", // lang.mixin "../_Widget", "../_Container", "../_Contained", "../Viewport", "dojo/_base/declare", // declare "dojo/dom-class", // domClass.add domClass.remove "dojo/dom-geometry", // domGeometry.marginBox "dojo/dom-style" // domStyle.getComputedStyle ], function(lang, _Widget, _Container, _Contained, Viewport, declare, domClass, domGeometry, domStyle){ // module: // dijit/layout/_LayoutWidget return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], { // summary: // Base class for a _Container widget which is responsible for laying out its children. // Widgets which mixin this code must define layout() to manage placement and sizing of the children. // baseClass: [protected extension] String // This class name is applied to the widget's domNode // and also may be used to generate names for sub nodes, // for example dijitTabContainer-content. baseClass: "dijitLayoutContainer", // isLayoutContainer: [protected] Boolean // Indicates that this widget is going to call resize() on its // children widgets, setting their size, when they become visible. isLayoutContainer: true, // Cancel _WidgetBase's _setTitleAttr because we don't want the title property (used to specify // tab labels) to be set as an attribute on this.domNode... otherwise a tooltip shows up over the // entire widget. _setTitleAttr: null, buildRendering: function(){ this.inherited(arguments); domClass.add(this.domNode, "dijitContainer"); }, startup: function(){ // summary: // Called after all the widgets have been instantiated and their // dom nodes have been inserted somewhere under <body>. // // Widgets should override this method to do any initialization // dependent on other widgets existing, and then call // this superclass method to finish things off. // // startup() in subclasses shouldn't do anything // size related because the size of the widget hasn't been set yet. if(this._started){ return; } // Need to call inherited first - so that child widgets get started // up correctly this.inherited(arguments); // If I am a not being controlled by a parent layout widget... var parent = this.getParent && this.getParent(); if(!(parent && parent.isLayoutContainer)){ // Do recursive sizing and layout of all my descendants // (passing in no argument to resize means that it has to glean the size itself) this.resize(); // Since my parent isn't a layout container, and my style *may be* width=height=100% // or something similar (either set directly or via a CSS class), // monitor when viewport size changes so that I can re-layout. this.own(Viewport.on("resize", lang.hitch(this, "resize"))); } }, resize: function(changeSize, resultSize){ // summary: // Call this to resize a widget, or after its size has changed. // description: // ####Change size mode: // // When changeSize is specified, changes the marginBox of this widget // and forces it to re-layout its contents accordingly. // changeSize may specify height, width, or both. // // If resultSize is specified it indicates the size the widget will // become after changeSize has been applied. // // ####Notification mode: // // When changeSize is null, indicates that the caller has already changed // the size of the widget, or perhaps it changed because the browser // window was resized. Tells widget to re-layout its contents accordingly. // // If resultSize is also specified it indicates the size the widget has // become. // // In either mode, this method also: // // 1. Sets this._borderBox and this._contentBox to the new size of // the widget. Queries the current domNode size if necessary. // 2. Calls layout() to resize contents (and maybe adjust child widgets). // changeSize: Object? // Sets the widget to this margin-box size and position. // May include any/all of the following properties: // | {w: int, h: int, l: int, t: int} // resultSize: Object? // The margin-box size of this widget after applying changeSize (if // changeSize is specified). If caller knows this size and // passes it in, we don't need to query the browser to get the size. // | {w: int, h: int} var node = this.domNode; // set margin box size, unless it wasn't specified, in which case use current size if(changeSize){ domGeometry.setMarginBox(node, changeSize); } // If either height or width wasn't specified by the user, then query node for it. // But note that setting the margin box and then immediately querying dimensions may return // inaccurate results, so try not to depend on it. var mb = resultSize || {}; lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize if( !("h" in mb) || !("w" in mb) ){ mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values } // Compute and save the size of my border box and content box // (w/out calling domGeometry.getContentBox() since that may fail if size was recently set) var cs = domStyle.getComputedStyle(node); var me = domGeometry.getMarginExtents(node, cs); var be = domGeometry.getBorderExtents(node, cs); var bb = (this._borderBox = { w: mb.w - (me.w + be.w), h: mb.h - (me.h + be.h) }); var pe = domGeometry.getPadExtents(node, cs); this._contentBox = { l: domStyle.toPixelValue(node, cs.paddingLeft), t: domStyle.toPixelValue(node, cs.paddingTop), w: bb.w - pe.w, h: bb.h - pe.h }; // Callback for widget to adjust size of its children this.layout(); }, layout: function(){ // summary: // Widgets override this method to size and position their contents/children. // When this is called this._contentBox is guaranteed to be set (see resize()). // // This is called after startup(), and also when the widget's size has been // changed. // tags: // protected extension }, _setupChild: function(/*dijit/_WidgetBase*/child){ // summary: // Common setup for initial children and children which are added after startup // tags: // protected extension var cls = this.baseClass + "-child " + (child.baseClass ? this.baseClass + "-" + child.baseClass : ""); domClass.add(child.domNode, cls); }, addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){ // Overrides _Container.addChild() to call _setupChild() this.inherited(arguments); if(this._started){ this._setupChild(child); } }, removeChild: function(/*dijit/_WidgetBase*/ child){ // Overrides _Container.removeChild() to remove class added by _setupChild() var cls = this.baseClass + "-child" + (child.baseClass ? " " + this.baseClass + "-" + child.baseClass : ""); domClass.remove(child.domNode, cls); this.inherited(arguments); } }); });