/* Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. Available via Academic Free License >= 2.1 OR the modified BSD license. see: http://dojotoolkit.org/license for details */ if(!dojo._hasResource["dijit.layout._ContentPaneResizeMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dijit.layout._ContentPaneResizeMixin"] = true; dojo.provide("dijit.layout._ContentPaneResizeMixin"); dojo.require("dijit._Contained"); dojo.declare("dijit.layout._ContentPaneResizeMixin", null, { // summary: // Resize() functionality of ContentPane. If there's a single layout widget // child then it will call resize() with the same dimensions as the ContentPane. // Otherwise just calls resize on each child. // // Also implements basic startup() functionality, where starting the parent // will start the children // doLayout: Boolean // - false - don't adjust size of children // - true - if there is a single visible child widget, set it's size to // however big the ContentPane is doLayout: true, // isContainer: [protected] Boolean // Indicates that this widget acts as a "parent" to the descendant widgets. // When the parent is started it will call startup() on the child widgets. // See also `isLayoutContainer`. isContainer: true, // isLayoutContainer: [protected] Boolean // Indicates that this widget will call resize() on it's child widgets // when they become visible. isLayoutContainer: true, _startChildren: function(){ // summary: // Call startup() on all children including non _Widget ones like dojo.dnd.Source objects // This starts all the widgets dojo.forEach(this.getChildren(), function(child){ child.startup(); child._started = true; }); }, startup: function(){ // summary: // See `dijit.layout._LayoutWidget.startup` for description. // Although ContentPane doesn't extend _LayoutWidget, it does implement // the same API. if(this._started){ return; } var parent = dijit._Contained.prototype.getParent.call(this); this._childOfLayoutWidget = parent && parent.isLayoutContainer; // I need to call resize() on my child/children (when I become visible), unless // I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then. this._needLayout = !this._childOfLayoutWidget; this.inherited(arguments); this._startChildren(); }, _checkIfSingleChild: function(){ // summary: // Test if we have exactly one visible widget as a child, // and if so assume that we are a container for that widget, // and should propagate startup() and resize() calls to it. // Skips over things like data stores since they aren't visible. var childNodes = dojo.query("> *", this.containerNode).filter(function(node){ return node.tagName !== "SCRIPT"; // or a regexp for hidden elements like script|area|map|etc.. }), childWidgetNodes = childNodes.filter(function(node){ return dojo.hasAttr(node, "data-dojo-type") || dojo.hasAttr(node, "dojoType") || dojo.hasAttr(node, "widgetId"); }), candidateWidgets = dojo.filter(childWidgetNodes.map(dijit.byNode), function(widget){ return widget && widget.domNode && widget.resize; }); if( // all child nodes are widgets childNodes.length == childWidgetNodes.length && // all but one are invisible (like dojo.data) candidateWidgets.length == 1 ){ this._singleChild = candidateWidgets[0]; }else{ delete this._singleChild; } // So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449) dojo.toggleClass(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild); }, resize: function(changeSize, resultSize){ // summary: // See `dijit.layout._LayoutWidget.resize` for description. // Although ContentPane doesn't extend _LayoutWidget, it does implement // the same API. this._layout(changeSize, resultSize); }, _layout: function(changeSize, resultSize){ // summary: // Resize myself according to optional changeSize/resultSize parameters, like a layout widget. // Also, since I am a Container widget, each of my children expects me to // call resize() or layout() on them. // // Should be called on initialization and also whenever we get new content // (from an href, or from set('content', ...))... but deferred until // the ContentPane is visible // Set margin box size, unless it wasn't specified, in which case use current size. if(changeSize){ dojo.marginBox(this.domNode, changeSize); } // Compute content box size of containerNode in case we [later] need to size our single child. var cn = this.containerNode; if(cn === this.domNode){ // If changeSize or resultSize was passed to this method and this.containerNode == // this.domNode then we can compute the content-box size without querying the node, // which is more reliable (similar to LayoutWidget.resize) (see for example #9449). var mb = resultSize || {}; dojo.mixin(mb, changeSize || {}); // changeSize overrides resultSize if(!("h" in mb) || !("w" in mb)){ mb = dojo.mixin(dojo.marginBox(cn), mb); // just use dojo.marginBox() to fill in missing values } this._contentBox = dijit.layout.marginBox2contentBox(cn, mb); }else{ this._contentBox = dojo.contentBox(cn); } this._layoutChildren(); delete this._needLayout; }, _layoutChildren: function(){ // Call _checkIfSingleChild() again in case app has manually mucked w/the content // of the ContentPane (rather than changing it through the set("content", ...) API. if(this.doLayout){ this._checkIfSingleChild(); } if(this._singleChild && this._singleChild.resize){ var cb = this._contentBox || dojo.contentBox(this.containerNode); // note: if widget has padding this._contentBox will have l and t set, // but don't pass them to resize() or it will doubly-offset the child this._singleChild.resize({w: cb.w, h: cb.h}); }else{ // All my child widgets are independently sized (rather than matching my size), // but I still need to call resize() on each child to make it layout. dojo.forEach(this.getChildren(), function(widget){ if(widget.resize){ widget.resize(); } }); } } }); }