]> git.wh0rd.org - tt-rss.git/blob - lib/dijit/layout/_ContentPaneResizeMixin.js.uncompressed.js
modify dojo rebuild script to remove uncompressed files
[tt-rss.git] / 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-class", // domClass.contains domClass.toggle
5 "dojo/dom-geometry",// domGeometry.contentBox domGeometry.marginBox
6 "dojo/dom-style",
7 "dojo/_base/lang", // lang.mixin
8 "dojo/query", // query
9 "dojo/sniff", // has("ie")
10 "../registry", // registry.byId
11 "../Viewport",
12 "./utils" // marginBox2contextBox
13 ], function(array, declare, domClass, domGeometry, domStyle, lang, query, has,
14 registry, Viewport, layoutUtils){
15
16 // module:
17 // dijit/layout/_ContentPaneResizeMixin
18
19
20 return declare("dijit.layout._ContentPaneResizeMixin", null, {
21 // summary:
22 // Resize() functionality of ContentPane. If there's a single layout widget
23 // child then it will call resize() with the same dimensions as the ContentPane.
24 // Otherwise just calls resize on each child.
25 //
26 // Also implements basic startup() functionality, where starting the parent
27 // will start the children
28
29 // doLayout: Boolean
30 // - false - don't adjust size of children
31 // - true - if there is a single visible child widget, set it's size to however big the ContentPane is
32 doLayout: true,
33
34 // isLayoutContainer: [protected] Boolean
35 // Indicates that this widget will call resize() on it's child widgets
36 // when they become visible.
37 isLayoutContainer: true,
38
39 startup: function(){
40 // summary:
41 // See `dijit/layout/_LayoutWidget.startup()` for description.
42 // Although ContentPane doesn't extend _LayoutWidget, it does implement
43 // the same API.
44
45 if(this._started){ return; }
46
47 var parent = this.getParent();
48 this._childOfLayoutWidget = parent && parent.isLayoutContainer;
49
50 // I need to call resize() on my child/children (when I become visible), unless
51 // I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
52 this._needLayout = !this._childOfLayoutWidget;
53
54 this.inherited(arguments);
55
56 if(this._isShown()){
57 this._onShow();
58 }
59
60 if(!this._childOfLayoutWidget){
61 // Since my parent isn't a layout container, and my style *may be* width=height=100%
62 // or something similar (either set directly or via a CSS class),
63 // monitor when viewport size changes so that I can re-layout.
64 // This is more for subclasses of ContentPane than ContentPane itself, although it
65 // could be useful for a ContentPane if it has a single child widget inheriting ContentPane's size.
66 this.own(Viewport.on("resize", lang.hitch(this, "resize")));
67 }
68 },
69
70 _checkIfSingleChild: function(){
71 // summary:
72 // Test if we have exactly one visible widget as a child,
73 // and if so assume that we are a container for that widget,
74 // and should propagate startup() and resize() calls to it.
75 // Skips over things like data stores since they aren't visible.
76
77 var candidateWidgets = [],
78 otherVisibleNodes = false;
79
80 query("> *", this.containerNode).some(function(node){
81 var widget = registry.byNode(node);
82 if(widget && widget.resize){
83 candidateWidgets.push(widget);
84 }else if(node.offsetHeight){
85 otherVisibleNodes = true;
86 }
87 });
88
89 this._singleChild = candidateWidgets.length == 1 && !otherVisibleNodes ?
90 candidateWidgets[0] : null;
91
92 // So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
93 domClass.toggle(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
94 },
95
96 resize: function(changeSize, resultSize){
97 // summary:
98 // See `dijit/layout/_LayoutWidget.resize()` for description.
99 // Although ContentPane doesn't extend _LayoutWidget, it does implement
100 // the same API.
101
102 this._resizeCalled = true;
103
104 this._scheduleLayout(changeSize, resultSize);
105 },
106
107 _scheduleLayout: function(changeSize, resultSize){
108 // summary:
109 // Resize myself, and call resize() on each of my child layout widgets, either now
110 // (if I'm currently visible) or when I become visible
111 if(this._isShown()){
112 this._layout(changeSize, resultSize);
113 }else{
114 this._needLayout = true;
115 this._changeSize = changeSize;
116 this._resultSize = resultSize;
117 }
118 },
119
120 _layout: function(changeSize, resultSize){
121 // summary:
122 // Resize myself according to optional changeSize/resultSize parameters, like a layout widget.
123 // Also, since I am an isLayoutContainer widget, each of my children expects me to
124 // call resize() or layout() on it.
125 //
126 // Should be called on initialization and also whenever we get new content
127 // (from an href, or from set('content', ...))... but deferred until
128 // the ContentPane is visible
129
130 delete this._needLayout;
131
132 // For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
133 // never called directly, so resize() is our trigger to do the initial href download (see [20099]).
134 // However, don't load href for closed TitlePanes.
135 if(!this._wasShown && this.open !== false){
136 this._onShow();
137 }
138
139 // Set margin box size, unless it wasn't specified, in which case use current size.
140 if(changeSize){
141 domGeometry.setMarginBox(this.domNode, changeSize);
142 }
143
144 // Compute content box size of containerNode in case we [later] need to size our single child.
145 var cn = this.containerNode;
146 if(cn === this.domNode){
147 // If changeSize or resultSize was passed to this method and this.containerNode ==
148 // this.domNode then we can compute the content-box size without querying the node,
149 // which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
150 var mb = resultSize || {};
151 lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
152 if(!("h" in mb) || !("w" in mb)){
153 mb = lang.mixin(domGeometry.getMarginBox(cn), mb); // just use domGeometry.setMarginBox() to fill in missing values
154 }
155 this._contentBox = layoutUtils.marginBox2contentBox(cn, mb);
156 }else{
157 this._contentBox = domGeometry.getContentBox(cn);
158 }
159
160 this._layoutChildren();
161 },
162
163 _layoutChildren: function(){
164 // Call _checkIfSingleChild() again in case app has manually mucked w/the content
165 // of the ContentPane (rather than changing it through the set("content", ...) API.
166 if(this.doLayout){
167 this._checkIfSingleChild();
168 }
169
170 if(this._singleChild && this._singleChild.resize){
171 var cb = this._contentBox || domGeometry.getContentBox(this.containerNode);
172
173 // note: if widget has padding this._contentBox will have l and t set,
174 // but don't pass them to resize() or it will doubly-offset the child
175 this._singleChild.resize({w: cb.w, h: cb.h});
176 }else{
177 // All my child widgets are independently sized (rather than matching my size),
178 // but I still need to call resize() on each child to make it layout.
179 array.forEach(this.getChildren(), function(widget){
180 if(widget.resize){
181 widget.resize();
182 }
183 });
184 }
185 },
186
187 _isShown: function(){
188 // summary:
189 // Returns true if the content is currently shown.
190 // description:
191 // If I am a child of a layout widget then it actually returns true if I've ever been visible,
192 // not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
193 // tree every call, and at least solves the performance problem on page load by deferring loading
194 // hidden ContentPanes until they are first shown
195
196 if(this._childOfLayoutWidget){
197 // If we are TitlePane, etc - we return that only *IF* we've been resized
198 if(this._resizeCalled && "open" in this){
199 return this.open;
200 }
201 return this._resizeCalled;
202 }else if("open" in this){
203 return this.open; // for TitlePane, etc.
204 }else{
205 var node = this.domNode, parent = this.domNode.parentNode;
206 return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !domClass.contains(node, "dijitHidden") &&
207 parent && parent.style && (parent.style.display != 'none');
208 }
209 },
210
211 _onShow: function(){
212 // summary:
213 // Called when the ContentPane is made visible
214 // description:
215 // For a plain ContentPane, this is called on initialization, from startup().
216 // If the ContentPane is a hidden pane of a TabContainer etc., then it's
217 // called whenever the pane is made visible.
218 //
219 // Does layout/resize of child widget(s)
220
221 // Need to keep track of whether ContentPane has been shown (which is different than
222 // whether or not it's currently visible).
223 this._wasShown = true;
224
225 if(this._needLayout){
226 // If a layout has been scheduled for when we become visible, do it now
227 this._layout(this._changeSize, this._resultSize);
228 }
229
230 this.inherited(arguments);
231 }
232 });
233
234 });