]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/layout/_ContentPaneResizeMixin.js.uncompressed.js
1 define("dijit/layout/_ContentPaneResizeMixin", [
2 "dojo/_base/array", // array.filter array.forEach
3 "dojo/_base/declare", // declare
4 "dojo/dom-attr", // domAttr.has
5 "dojo/dom-class", // domClass.contains domClass.toggle
6 "dojo/dom-geometry",// domGeometry.contentBox domGeometry.marginBox
7 "dojo/_base/lang", // lang.mixin
9 "dojo/_base/sniff", // has("ie")
10 "dojo/_base/window", // win.global
11 "../registry", // registry.byId
12 "./utils", // marginBox2contextBox
14 ], function(array
, declare
, domAttr
, domClass
, domGeometry
, lang
, query
, has
, win
,
15 registry
, layoutUtils
, _Contained
){
18 var _Contained = dijit._Contained;
22 // dijit/layout/_ContentPaneResizeMixin
24 // Resize() functionality of ContentPane. If there's a single layout widget
25 // child then it will call resize() with the same dimensions as the ContentPane.
26 // Otherwise just calls resize on each child.
29 return declare("dijit.layout._ContentPaneResizeMixin", null, {
31 // Resize() functionality of ContentPane. If there's a single layout widget
32 // child then it will call resize() with the same dimensions as the ContentPane.
33 // Otherwise just calls resize on each child.
35 // Also implements basic startup() functionality, where starting the parent
36 // will start the children
39 // - false - don't adjust size of children
40 // - true - if there is a single visible child widget, set it's size to
41 // however big the ContentPane is
44 // isLayoutContainer: [protected] Boolean
45 // Indicates that this widget will call resize() on it's child widgets
46 // when they become visible.
47 isLayoutContainer
: true,
51 // See `dijit.layout._LayoutWidget.startup` for description.
52 // Although ContentPane doesn't extend _LayoutWidget, it does implement
55 if(this._started
){ return; }
57 var parent
= this.getParent();
58 this._childOfLayoutWidget
= parent
&& parent
.isLayoutContainer
;
60 // I need to call resize() on my child/children (when I become visible), unless
61 // I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
62 this._needLayout
= !this._childOfLayoutWidget
;
64 this.inherited(arguments
);
70 if(!this._childOfLayoutWidget
){
71 // If my parent isn't a layout container, since my style *may be* width=height=100%
72 // or something similar (either set directly or via a CSS class),
73 // monitor when my size changes so that I can re-layout.
74 // For browsers where I can't directly monitor when my size changes,
75 // monitor when the viewport changes size, which *may* indicate a size change for me.
76 this.connect(has("ie") ? this.domNode
: win
.global
, 'onresize', function(){
77 // Using function(){} closure to ensure no arguments to resize.
78 this._needLayout
= !this._childOfLayoutWidget
;
84 _checkIfSingleChild: function(){
86 // Test if we have exactly one visible widget as a child,
87 // and if so assume that we are a container for that widget,
88 // and should propagate startup() and resize() calls to it.
89 // Skips over things like data stores since they aren't visible.
91 var childNodes
= query("> *", this.containerNode
).filter(function(node
){
92 return node
.tagName
!== "SCRIPT"; // or a regexp for hidden elements like script|area|map|etc..
94 childWidgetNodes
= childNodes
.filter(function(node
){
95 return domAttr
.has(node
, "data-dojo-type") || domAttr
.has(node
, "dojoType") || domAttr
.has(node
, "widgetId");
97 candidateWidgets
= array
.filter(childWidgetNodes
.map(registry
.byNode
), function(widget
){
98 return widget
&& widget
.domNode
&& widget
.resize
;
102 // all child nodes are widgets
103 childNodes
.length
== childWidgetNodes
.length
&&
105 // all but one are invisible (like dojo.data)
106 candidateWidgets
.length
== 1
108 this._singleChild
= candidateWidgets
[0];
110 delete this._singleChild
;
113 // So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
114 domClass
.toggle(this.containerNode
, this.baseClass
+ "SingleChild", !!this._singleChild
);
117 resize: function(changeSize
, resultSize
){
119 // See `dijit.layout._LayoutWidget.resize` for description.
120 // Although ContentPane doesn't extend _LayoutWidget, it does implement
123 // For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
124 // never called, so resize() is our trigger to do the initial href download (see [20099]).
125 // However, don't load href for closed TitlePanes.
126 if(!this._wasShown
&& this.open
!== false){
130 this._resizeCalled
= true;
132 this._scheduleLayout(changeSize
, resultSize
);
135 _scheduleLayout: function(changeSize
, resultSize
){
137 // Resize myself, and call resize() on each of my child layout widgets, either now
138 // (if I'm currently visible) or when I become visible
140 this._layout(changeSize
, resultSize
);
142 this._needLayout
= true;
143 this._changeSize
= changeSize
;
144 this._resultSize
= resultSize
;
148 _layout: function(changeSize
, resultSize
){
150 // Resize myself according to optional changeSize/resultSize parameters, like a layout widget.
151 // Also, since I am a Container widget, each of my children expects me to
152 // call resize() or layout() on them.
154 // Should be called on initialization and also whenever we get new content
155 // (from an href, or from set('content', ...))... but deferred until
156 // the ContentPane is visible
158 // Set margin box size, unless it wasn't specified, in which case use current size.
160 domGeometry
.setMarginBox(this.domNode
, changeSize
);
163 // Compute content box size of containerNode in case we [later] need to size our single child.
164 var cn
= this.containerNode
;
165 if(cn
=== this.domNode
){
166 // If changeSize or resultSize was passed to this method and this.containerNode ==
167 // this.domNode then we can compute the content-box size without querying the node,
168 // which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
169 var mb
= resultSize
|| {};
170 lang
.mixin(mb
, changeSize
|| {}); // changeSize overrides resultSize
171 if(!("h" in mb
) || !("w" in mb
)){
172 mb
= lang
.mixin(domGeometry
.getMarginBox(cn
), mb
); // just use domGeometry.setMarginBox() to fill in missing values
174 this._contentBox
= layoutUtils
.marginBox2contentBox(cn
, mb
);
176 this._contentBox
= domGeometry
.getContentBox(cn
);
179 this._layoutChildren();
181 delete this._needLayout
;
184 _layoutChildren: function(){
185 // Call _checkIfSingleChild() again in case app has manually mucked w/the content
186 // of the ContentPane (rather than changing it through the set("content", ...) API.
188 this._checkIfSingleChild();
191 if(this._singleChild
&& this._singleChild
.resize
){
192 var cb
= this._contentBox
|| domGeometry
.getContentBox(this.containerNode
);
194 // note: if widget has padding this._contentBox will have l and t set,
195 // but don't pass them to resize() or it will doubly-offset the child
196 this._singleChild
.resize({w
: cb
.w
, h
: cb
.h
});
198 // All my child widgets are independently sized (rather than matching my size),
199 // but I still need to call resize() on each child to make it layout.
200 array
.forEach(this.getChildren(), function(widget
){
208 _isShown: function(){
210 // Returns true if the content is currently shown.
212 // If I am a child of a layout widget then it actually returns true if I've ever been visible,
213 // not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
214 // tree every call, and at least solves the performance problem on page load by deferring loading
215 // hidden ContentPanes until they are first shown
217 if(this._childOfLayoutWidget
){
218 // If we are TitlePane, etc - we return that only *IF* we've been resized
219 if(this._resizeCalled
&& "open" in this){
222 return this._resizeCalled
;
223 }else if("open" in this){
224 return this.open
; // for TitlePane, etc.
226 var node
= this.domNode
, parent
= this.domNode
.parentNode
;
227 return (node
.style
.display
!= 'none') && (node
.style
.visibility
!= 'hidden') && !domClass
.contains(node
, "dijitHidden") &&
228 parent
&& parent
.style
&& (parent
.style
.display
!= 'none');
234 // Called when the ContentPane is made visible
236 // For a plain ContentPane, this is called on initialization, from startup().
237 // If the ContentPane is a hidden pane of a TabContainer etc., then it's
238 // called whenever the pane is made visible.
240 // Does layout/resize of child widget(s)
242 if(this._needLayout
){
243 // If a layout has been scheduled for when we become visible, do it now
244 this._layout(this._changeSize
, this._resultSize
);
247 this.inherited(arguments
);
249 // Need to keep track of whether ContentPane has been shown (which is different than
250 // whether or not it's currently visible).
251 this._wasShown
= true;