OSDN Git Service

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