OSDN Git Service

Version 0.6.90, performance fix for HTML5Audio & rename SilverLight -> Silverlight.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 14_XDomBoxModel.js
1 X.Dom.BoxModel = {\r
2         CONTENT_BOX      : 1,\r
3         PADDING_BOX      : 2,\r
4         BORDER_BOX       : 3,\r
5                 \r
6         defaultBoxModel  : 0,\r
7         boxSizingEnabled : false,\r
8         \r
9         // TODO: offsetLeft, offsetTop の基準位置\r
10         absoluteOffset   : 0,\r
11         \r
12         vScrollbarSize   : 0,\r
13         hScrollbarSize   : 0\r
14 };\r
15 \r
16 \r
17 \r
18 X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){\r
19 \r
20         var node = Node._systemNode,\r
21         \r
22                 // http://jsdo.it/imaya/kTYg\r
23                 body = document.body,\r
24                 defaultOverflow = document.body.style.overflow,\r
25                 width, height;\r
26 \r
27         body.style.overflow = 'hidden';\r
28         w = body.clientWidth;\r
29         h = body.clientHeight;\r
30 \r
31         body.style.overflow = 'scroll';\r
32         w -= body.clientWidth;\r
33         h -= body.clientHeight;\r
34 \r
35         if( !w ) w = body.offsetWidth  - body.clientWidth;\r
36         if( !h ) h = body.offsetHeight - body.clientHeight;\r
37         body.style.overflow = defaultOverflow; \r
38 \r
39         X.Dom.BoxModel.vScrollbarSize = w;\r
40         X.Dom.BoxModel.hScrollbarSize = h;\r
41         if( h <= 0 ){ // ie6, ie11, firefox で 負の値が返る\r
42                 console.log( 'invalid hScrollbarSize: ' + h );\r
43                 X.Dom.BoxModel.hScrollbarSize = w;\r
44         };\r
45         //\r
46         \r
47         node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );\r
48         \r
49         X.Dom.BoxModel.defaultBoxModel = node.width() === 10 ?\r
50                 X.Dom.BoxModel.BORDER_BOX :\r
51                 X.Dom.BoxModel.CONTENT_BOX;\r
52         \r
53         if( X.Dom.BoxModel.defaultBoxModel === X.Dom.BoxModel.CONTENT_BOX ){\r
54                 X.Dom.BoxModel.boxSizingEnabled = node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +\r
55                         'box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-o-box-sizing:border-box;-ms-box-sizing:border-box;' )\r
56                                                                                         .width() === 10;\r
57         };\r
58         // padding\r
59         // border\r
60         // margin\r
61         // top\r
62 \r
63         X.Dom.BoxModel.absoluteOffset =\r
64                 node.cssText( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )\r
65                         .append( '<div></div>' )\r
66                         .firstChild().cssText( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )\r
67                         .y();\r
68 \r
69         node.cssText( '' ).empty();\r
70 });\r
71 \r
72 /* --------------------------------------\r
73  * Width, Height\r
74  *  display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す\r
75  *  display:none なら 0\r
76  * \r
77  * getBoxObjectFor\r
78  * getBoundingClientRect\r
79  */\r
80 Node.prototype.width = function(){\r
81         if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
82                 console.log( 'xnode.width() : no parent' );\r
83                 return 0;\r
84         };\r
85         Node._body._updateTimerID && Node._body._startUpdate();\r
86         if( !this._root ){\r
87                 console.log( 'xnode.width() : not belong tree.' );\r
88                 return 0;\r
89         };\r
90         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
91         if( X.Dom.DOM_W3C ){\r
92                 // this.css( X.Dom.Style.Unit.px, 'width' );\r
93                 return this._rawObject.offsetWidth;\r
94         } else\r
95         if( X.Dom.DOM_IE4 ){\r
96                 return ( this._rawObject || this._ie4getRawNode() ).offsetWidth;\r
97         } else {\r
98                 \r
99         };\r
100 };\r
101 \r
102 Node.prototype.height = function(){\r
103         if( !this.parent ){\r
104                 console.log( 'xnode.height() : no parent' );\r
105                 return 0;\r
106         };\r
107         Node._body._updateTimerID && Node._body._startUpdate();\r
108         if( !this._root ){\r
109                 console.log( 'xnode.height() : not belong tree.' );\r
110                 return 0;\r
111         };\r
112         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
113         if( X.Dom.DOM_W3C ){\r
114                 // this.css( X.Dom.Style.Unit.px, 'height' );\r
115                 return this._rawObject.offsetHeight;\r
116         } else\r
117         if( X.Dom.DOM_IE4 ){\r
118                 return ( this._rawObject || this._ie4getRawNode() ).offsetHeight;\r
119         } else {\r
120                 \r
121         };\r
122 };\r
123 \r
124 Node.prototype.clientWidth = function(){\r
125         if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
126                 console.log( 'xnode.width() : no parent' );\r
127                 return 0;\r
128         };\r
129         Node._body._updateTimerID && Node._body._startUpdate();\r
130         if( !this._root ){\r
131                 console.log( 'xnode.width() : not belong tree.' );\r
132                 return 0;\r
133         };\r
134         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
135         if( X.Dom.DOM_W3C ){\r
136                 // this.css( X.Dom.Style.Unit.px, 'width' );\r
137                 return this._rawObject.clientWidth;\r
138         } else\r
139         if( X.Dom.DOM_IE4 ){\r
140                 return ( this._rawObject || this._ie4getRawNode() ).clientWidth;\r
141         } else {\r
142                 \r
143         };\r
144 };\r
145 \r
146 Node.prototype.clientHeight = function(){\r
147         if( !this.parent ){\r
148                 console.log( 'xnode.height() : no parent' );\r
149                 return 0;\r
150         };\r
151         Node._body._updateTimerID && Node._body._startUpdate();\r
152         if( !this._root ){\r
153                 console.log( 'xnode.height() : not belong tree.' );\r
154                 return 0;\r
155         };\r
156         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
157         if( X.Dom.DOM_W3C ){\r
158                 // this.css( X.Dom.Style.Unit.px, 'height' );\r
159                 return this._rawObject.clientHeight;\r
160         } else\r
161         if( X.Dom.DOM_IE4 ){\r
162                 return ( this._rawObject || this._ie4getRawNode() ).clientHeight;\r
163         } else {\r
164                 \r
165         };\r
166 };\r
167 \r
168 Node.prototype.scrollWidth = function(){\r
169         if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
170                 console.log( 'xnode.width() : no parent' );\r
171                 return 0;\r
172         };\r
173         Node._body._updateTimerID && Node._body._startUpdate();\r
174         if( !this._root ){\r
175                 console.log( 'xnode.width() : not belong tree.' );\r
176                 return 0;\r
177         };\r
178         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
179         if( X.Dom.DOM_W3C ){\r
180                 // this.css( X.Dom.Style.Unit.px, 'width' );\r
181                 return this._rawObject.scrollWidth;\r
182         } else\r
183         if( X.Dom.DOM_IE4 ){\r
184                 return ( this._rawObject || this._ie4getRawNode() ).scrollWidth;\r
185         } else {\r
186                 \r
187         };\r
188 };\r
189 \r
190 Node.prototype.scrollHeight = function(){\r
191         if( !this.parent ){\r
192                 console.log( 'xnode.height() : no parent' );\r
193                 return 0;\r
194         };\r
195         Node._body._updateTimerID && Node._body._startUpdate();\r
196         if( !this._root ){\r
197                 console.log( 'xnode.height() : not belong tree.' );\r
198                 return 0;\r
199         };\r
200         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
201         if( X.Dom.DOM_W3C ){\r
202                 // this.css( X.Dom.Style.Unit.px, 'height' );\r
203                 return this._rawObject.scrollHeight;\r
204         } else\r
205         if( X.Dom.DOM_IE4 ){\r
206                 return ( this._rawObject || this._ie4getRawNode() ).scrollHeight;\r
207         } else {\r
208                 \r
209         };\r
210 };\r
211 \r
212 Node.prototype.scrollLeft = function(){\r
213         if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
214                 console.log( 'xnode.scrollLeft() : no parent' );\r
215                 return 0;\r
216         };\r
217         Node._body._updateTimerID && Node._body._startUpdate();\r
218         if( !this._root ){\r
219                 console.log( 'xnode.scrollLeft() : not belong tree.' );\r
220                 return 0;\r
221         };\r
222         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
223         if( X.Dom.DOM_W3C ){\r
224                 // this.css( X.Dom.Style.Unit.px, 'width' );\r
225                 return this._rawObject.scrollLeft;\r
226         } else\r
227         if( X.Dom.DOM_IE4 ){\r
228                 return ( this._rawObject || this._ie4getRawNode() ).scrollLeft;\r
229         } else {\r
230                 \r
231         };\r
232 };\r
233 \r
234 Node.prototype.scrollTop = function(){\r
235         if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
236                 console.log( 'xnode.scrollTop() : no parent' );\r
237                 return 0;\r
238         };\r
239         Node._body._updateTimerID && Node._body._startUpdate();\r
240         if( !this._root ){\r
241                 console.log( 'xnode.scrollTop() : not belong tree.' );\r
242                 return 0;\r
243         };\r
244         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
245         if( X.Dom.DOM_W3C ){\r
246                 // this.css( X.Dom.Style.Unit.px, 'width' );\r
247                 return this._rawObject.scrollTop;\r
248         } else\r
249         if( X.Dom.DOM_IE4 ){\r
250                 return ( this._rawObject || this._ie4getRawNode() ).scrollTop;\r
251         } else {\r
252                 \r
253         };\r
254 };\r
255 \r
256 /* --------------------------------------\r
257  *  x, y\r
258  *  position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?\r
259  *  position:absolute の指定で自動で top,left を補う必要あり? -> X.Dom.Style\r
260  *  親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。\r
261  * transformX, Y は加える? アニメーション中は?\r
262  */\r
263 // X.Dom.Style.transform,\r
264 Node.prototype.x = function(){\r
265         if( !this.parent ){\r
266                 console.log( 'xnode.x() : no parent' );\r
267                 return 0;\r
268         };\r
269         Node._body._updateTimerID && Node._body._startUpdate();\r
270         if( !this._root ){\r
271                 console.log( 'xnode.x() : not belong tree.' );\r
272                 return 0;\r
273         };\r
274         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
275         if( X.Dom.DOM_W3C ){\r
276                 // this.css( X.Dom.Style.Unit.px, 'left' );\r
277                 // this.css( X.Dom.Style.Unit.px, 'translateX' );\r
278                 return this._rawObject.offsetLeft;\r
279         } else\r
280         if( X.Dom.DOM_IE4 ){\r
281                 return ( this._rawObject || this._ie4getRawNode() ).offsetLeft;\r
282         } else {\r
283                 \r
284         };\r
285 };\r
286 \r
287 Node.prototype.y = function(){\r
288         if( !this.parent ){\r
289                 console.log( 'xnode.y() : no parent' );\r
290                 return 0;\r
291         };\r
292         Node._body._updateTimerID && Node._body._startUpdate();\r
293         if( !this._root ){\r
294                 console.log( 'xnode.y() : not belong tree.' );\r
295                 return 0;\r
296         };\r
297         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
298         if( X.Dom.DOM_W3C ){\r
299                 // this.css( X.Dom.Style.Unit.px, 'top' );\r
300                 // this.css( X.Dom.Style.Unit.px, 'transisitonY' );\r
301                 return this._rawObject.offsetTop;\r
302         } else\r
303         if( X.Dom.DOM_IE4 ){\r
304                 return ( this._rawObject || this._ie4getRawNode() ).offsetTop;          \r
305         } else {\r
306                 \r
307         };\r
308 };\r
309 \r
310 Node.prototype.offset = function( /* xnodeParent */ ){\r
311         var x = 0, y = 0, elm;\r
312         \r
313         if( !this.parent ){\r
314                 console.log( 'xnode.offset() : no parent' );\r
315                 return { x : 0, y : 0 };\r
316         };\r
317         Node._body._updateTimerID && Node._body._startUpdate();\r
318         if( !this._root ){\r
319                 console.log( 'xnode.offset() : not belong tree.' );\r
320                 return { x : 0, y : 0 };\r
321         };\r
322         if( this._state & X.Dom.State.DISPLAY_NONE ) return 0;\r
323         \r
324         if( X.Dom.Node._body === this || X.Dom.Node._html === this ){\r
325                 return { x : 0, y : 0 };\r
326         };\r
327         \r
328         if( X.Dom.DOM_W3C ){\r
329                 elm = this._rawObject;\r
330         } else\r
331         if( X.Dom.DOM_IE4 ){\r
332                 elm = this._rawObject || this._ie4getRawNode();         \r
333         } else {\r
334                 \r
335         };\r
336         \r
337         while( elm && elm !== document.body ){\r
338                 x += elm.offsetLeft;\r
339                 y += elm.offsetTop;\r
340                 elm = elm.offsetParent || elm.parentNode || elm.parentElement;\r
341         };\r
342         return { x : x, y : y };\r
343 };\r