OSDN Git Service

Version 0.6.134, add comments for closure compiler.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 04_XBoxModel.js
1 var X_Node_BoxModel = {\r
2                 CONTENT_BOX      : 1,\r
3                 PADDING_BOX      : 2,\r
4                 BORDER_BOX       : 3\r
5         },\r
6         \r
7         X_Node_BoxModel_defaultBoxModel,\r
8         \r
9         X_Node_BoxModel_boxSizingEnabled,\r
10         // TODO: offsetLeft, offsetTop の基準位置\r
11         X_Node_BoxModel_absoluteOffset;\r
12 \r
13 \r
14 \r
15 \r
16 \r
17 X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){\r
18         var node = X_Node_systemNode;\r
19         \r
20         node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );\r
21         \r
22         X_Node_BoxModel_defaultBoxModel = node[ 'width' ]() === 10 ?\r
23                 X_Node_BoxModel.BORDER_BOX :\r
24                 X_Node_BoxModel.CONTENT_BOX;\r
25         \r
26         if( X_Node_BoxModel_defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){\r
27                 X_Node_BoxModel_boxSizingEnabled = node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +\r
28                         '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
29                                                                                         [ 'width' ]() === 10;\r
30         };\r
31         \r
32         /*\r
33          * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。\r
34          * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)\r
35          */\r
36         if( X_Node_CSS_Support[ 'boxShadow' ] &&\r
37                 node[ 'cssText' ](\r
38                                 X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'\r
39                         )[ 'width' ]() !== 10\r
40         ){\r
41                 console.log( node[ 'cssText' ]() + node[ 'width' ]() );\r
42                 X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;\r
43         };\r
44 \r
45         // padding\r
46         // border\r
47         // margin\r
48         // top\r
49 \r
50         X_Node_BoxModel_absoluteOffset =\r
51                 node[ 'cssText' ]( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )\r
52                         [ 'append' ]( '<div></div>' )\r
53                         [ 'firstChild' ]()\r
54                                 [ 'cssText' ]( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )\r
55                                 [ 'y' ]();\r
56 \r
57         node[ 'cssText' ]( '' )[ 'empty' ]();\r
58 });\r
59 \r
60 /* --------------------------------------\r
61  * Width, Height\r
62  *  display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す\r
63  *  display:none なら 0\r
64  * \r
65  * getBoxObjectFor\r
66  * getBoundingClientRect\r
67  */\r
68 Node.prototype[ 'width' ] = function(){\r
69         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
70         \r
71         X_Node_updateTimerID && X_Node_startUpdate();\r
72         \r
73         if( X_UA_DOM.W3C ){\r
74                 // TODO width : length + overflow : hidden ならそれを返す? <- block or inline\r
75                 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetWidth : 0;\r
76         } else\r
77         if( X_UA_DOM.IE4 ){\r
78                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetWidth;\r
79         } else {\r
80                 \r
81         };\r
82 };\r
83 \r
84 Node.prototype[ 'height' ] = function(){\r
85         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
86         \r
87         X_Node_updateTimerID && X_Node_startUpdate();\r
88         \r
89         if( X_UA_DOM.W3C ){\r
90                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );\r
91                 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetHeight : 0;\r
92         } else\r
93         if( X_UA_DOM.IE4 ){\r
94                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetHeight;\r
95         } else {\r
96                 \r
97         };\r
98 };\r
99 \r
100 Node.prototype[ 'clientWidth' ] = function(){\r
101         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
102         \r
103         X_Node_updateTimerID && X_Node_startUpdate();\r
104         \r
105         if( X_UA_DOM.W3C ){\r
106                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );\r
107                 return this[ '_rawObject' ] ? this[ '_rawObject' ].clientWidth : 0;\r
108         } else\r
109         if( X_UA_DOM.IE4 ){\r
110                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientWidth;\r
111         } else {\r
112                 \r
113         };\r
114 };\r
115 \r
116 Node.prototype[ 'clientHeight' ] = function(){\r
117         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
118         \r
119         X_Node_updateTimerID && X_Node_startUpdate();\r
120 \r
121         if( X_UA_DOM.W3C ){\r
122                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );\r
123                 return this[ '_rawObject' ] ? this[ '_rawObject' ].clientHeight : 0;\r
124         } else\r
125         if( X_UA_DOM.IE4 ){\r
126                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientHeight;\r
127         } else {\r
128                 \r
129         };\r
130 };\r
131 \r
132 Node.prototype[ 'scrollWidth' ] = function(){\r
133         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
134         \r
135         X_Node_updateTimerID && X_Node_startUpdate();\r
136 \r
137         if( X_UA_DOM.W3C ){\r
138                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );\r
139                 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollWidth : 0;\r
140         } else\r
141         if( X_UA_DOM.IE4 ){\r
142                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollWidth;\r
143         } else {\r
144                 \r
145         };\r
146 };\r
147 \r
148 Node.prototype[ 'scrollHeight' ] = function(){\r
149         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
150         \r
151         X_Node_updateTimerID && X_Node_startUpdate();\r
152 \r
153         if( X_UA_DOM.W3C ){\r
154                 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollHeight : 0;\r
155         } else\r
156         if( X_UA_DOM.IE4 ){\r
157                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollHeight;\r
158         } else {\r
159                 \r
160         };\r
161 };\r
162 \r
163 Node.prototype[ 'scrollLeft' ] = function(){\r
164         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
165         \r
166         X_Node_updateTimerID && X_Node_startUpdate();\r
167 \r
168         if( X_UA_DOM.W3C ){\r
169                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );\r
170                 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollLeft : 0;\r
171         } else\r
172         if( X_UA_DOM.IE4 ){\r
173                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollLeft;\r
174         } else {\r
175                 \r
176         };\r
177 };\r
178 \r
179 Node.prototype[ 'scrollTop' ] = function(){\r
180         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
181         \r
182         X_Node_updateTimerID && X_Node_startUpdate();\r
183         \r
184         if( X_UA_DOM.W3C ){\r
185                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );\r
186                 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollTop : 0;\r
187         } else\r
188         if( X_UA_DOM.IE4 ){\r
189                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollTop;\r
190         } else {\r
191                 \r
192         };\r
193 };\r
194 \r
195 /* --------------------------------------\r
196  *  x, y\r
197  *  position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?\r
198  *  position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS\r
199  *  親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。\r
200  * transformX, Y は加える? アニメーション中は?\r
201  */\r
202 // X_Node_CSS_transform,\r
203 Node.prototype[ 'x' ] = function(){\r
204         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
205         \r
206         X_Node_updateTimerID && X_Node_startUpdate();\r
207         \r
208         if( X_UA_DOM.W3C ){\r
209                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'left' );\r
210                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'translateX' );\r
211                 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetLeft : 0;\r
212         } else\r
213         if( X_UA_DOM.IE4 ){\r
214                 // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm\r
215                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetLeft;\r
216         } else {\r
217                 \r
218         };\r
219 };\r
220 \r
221 Node.prototype[ 'y' ] = function(){\r
222         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
223         \r
224         X_Node_updateTimerID && X_Node_startUpdate();\r
225         \r
226         if( X_UA_DOM.W3C ){\r
227                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'top' );\r
228                 // this[ 'css' ]( X_Node_CSS_Unit.px, 'transisitonY' );\r
229                 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetTop : 0;\r
230         } else\r
231         if( X_UA_DOM.IE4 ){\r
232                 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetTop;             \r
233         } else {\r
234                 \r
235         };\r
236 };\r
237 \r
238 Node.prototype[ 'offset' ] = function( /* xnodeParent */ ){\r
239 \r
240         if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 };\r
241         \r
242         if( X.Doc.body === this || X.Doc.html === this ){\r
243                 return { x : 0, y : 0 };\r
244         };\r
245         \r
246         X_Node_updateTimerID && X_Node_startUpdate();\r
247         \r
248         if( X_UA_DOM.W3C ){\r
249                 return this[ '_rawObject' ] ? X_Node_getPosition( this[ '_rawObject' ] ) : { x : 0, y : 0 };\r
250         } else\r
251         if( X_UA_DOM.IE4 ){\r
252                 return X_Node_getPosition( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) );\r
253         } else {\r
254                 \r
255         };\r
256 };\r
257 \r
258 // エレメントの座標取得 ~スクロール要素~\r
259 // http://n-yagi.0r2.net/script/2009/06/post_14.html\r
260 \r
261 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
262 //  エレメントの絶対座標を得たい\r
263 //------------------------------------------------------------------------------\r
264 //  座標取得\r
265 var X_Node_getPosition =\r
266         document.documentElement && document.documentElement.getBoundingClientRect ?\r
267                 function( el ){\r
268                 var pos  = el.getBoundingClientRect(),\r
269                         html = document.documentElement,\r
270                         body = document.body;\r
271                 return  {   x:(pos.left +   (body.scrollLeft||html.scrollLeft)  -   html.clientLeft)\r
272                         ,   y:(pos.top  +   (body.scrollTop||html.scrollTop)    -   html.clientTop) };\r
273                 } :\r
274         X_UA[ 'Opera' ] < 10 ?\r
275                 function( el ){\r
276             var ex  =   0;\r
277             var ey  =   0;\r
278             do\r
279             { \r
280                 ex  +=  el.offsetLeft;\r
281                 ey  +=  el.offsetTop;\r
282             }\r
283             while(  el  =   el.offsetParent );\r
284             //\r
285             return  {x:ex,y:ey};\r
286                 } :\r
287                 function(target)\r
288         {\r
289             var ex  =   0;\r
290             var ey  =   0;\r
291             //\r
292             var el  =   target;\r
293             var bd  =   document.body;\r
294             \r
295             do\r
296             { \r
297                 ex  +=  el.offsetLeft   ||  0;\r
298                 ey  +=  el.offsetTop    ||  0;\r
299             }\r
300             while(  el  =   el.offsetParent );\r
301             //  要素内スクロール対応\r
302             el  =   target;\r
303             do\r
304             {\r
305                 ex  -=  el.scrollLeft   ||  0;\r
306                 ey  -=  el.scrollTop    ||  0;\r
307                 el  =   el.parentNode;\r
308             }\r
309             while(  el!=bd  );\r
310             //\r
311             return  {x:ex,y:ey};\r
312         };\r
313 \r
314 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
315 \r