1 var _Node = X.Class.create(
\r
3 X.Class.PRIVATE_DATA | X.Class.POOL_OBJECT,
\r
16 boxSizingOffsetLR : 0,
\r
17 boxSizingOffsetTB : 0,
\r
19 minContentWidth : 0,
\r
20 maxContentWidth : AUTO,
\r
21 lastContentWidth : -1,
\r
23 minContentHeight : 0,
\r
24 maxContentHeight : AUTO,
\r
25 Constructor : function( __root, __parent ){
\r
26 this.__root = __root;
\r
27 if( __parent ) this.__parent = __parent;
\r
29 style : function( v ){
\r
30 if( v instanceof NodeStyle ){
\r
31 if( v !== this._style ){
\r
32 this.__style && this.__style.unRegister( this );
\r
34 this.__style = X.Class._getPrivate( v );
\r
35 this.__style.register( this );
\r
40 this.__style && this.__style.unRegister( this );
\r
42 delete this.__style;
\r
47 content : function( v ){
\r
48 if( Type.isString( v ) === true ){
\r
49 if( !this.textNode || ( this.textNode && this.textNode.data !== v ) ){
\r
51 this.updateContent = true;
\r
56 if( this._content !== v && this.textNode ){
\r
58 this.updateContent = true;
\r
62 if( this._content ) return this._content;
\r
63 if( this._content === null ) return null;
\r
64 if( this.textNode ) return this.textNode.data;
\r
69 * 1. ペイントがある // 予約のみ
\r
70 * 2. コンテンツがある // 予約のみ *
\r
71 * 3. コンテンツを削除 // 予約のみ
\r
78 * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持
\r
80 * contentSize, scrollSize の決定
\r
82 musure : function( dirty ){
\r
83 var content = this._content,
\r
85 style = this.__style,
\r
86 w = this.contentWidth,
\r
87 h = this.contentHeight;
\r
88 switch( this.updateContent === true ? X.Css.Dirty.CONTENT : dirty ){
\r
89 case X.Css.Dirty.CONTENT : // コンテンツが変更された
\r
91 this.lastContentWidth = -1;
\r
92 case X.Css.Dirty.FONT : // フォントサイズが変更された
\r
93 case X.Css.Dirty.REFLOW : // レイアウトの再計算が必要
\r
94 /* http://web-designs.seesaa.net/article/188400668.html
\r
95 * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。
\r
98 * 1. contentWidth === AUTO
\r
99 * style を更新して contentWidth の決定
\r
100 * min or max に引っかかったら style 更新
\r
101 * contentHeight === AUTO の場合
\r
103 * contentHeight !== AUTO の場合 scrollHeight のみ更新
\r
104 * 2. contentHeight === AUTO かつ
\r
105 * コンテンツの高さの再取得が必要( contentWidth が最終計測時の contentWidth と一致 かつ フォント・コンテンツに変更無し の場合再取得不要)
\r
106 * style を更新して contentHeight の決定
\r
108 * 3. content のサイズがすでに決定している
\r
112 if( this.textNode ){
\r
114 this.commitStyle();
\r
115 w = this.contentWidth = this.textNode.offsetWidth;
\r
116 this.scrollWidth = w + this.contentL + this.contentR;
\r
117 if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR;
\r
118 if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR;
\r
119 this.lastContentWidth = this.contentWidth;
\r
121 w !== this.contentWidth && this.commitStyle();
\r
124 h = this.conetntHeight = this.textNode.offsetHeight;
\r
125 this.scrollHeight = h + this.contentT + this.contentB;
\r
126 if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB;
\r
127 if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB;
\r
129 this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB;
\r
133 if( w !== this.lastContentWidth || dirty !== X.Css.Dirty.REFLOW ){
\r
134 this.commitStyle();
\r
135 this.lastContentWidth = w;
\r
136 h = this.conetntHeight = this.textNode.offsetHeight;
\r
137 this.scrollWidth = w + this.contentL + this.contentR;
\r
138 this.scrollHeight = h + this.contentT + this.contentB;
\r
139 if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB;
\r
140 if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB;
\r
142 this.scrollWidth = w + this.contentL + this.contentR;
\r
143 this.scrollHeight = h + this.contentT + this.contentB;
\r
144 root.paintReserve( this );
\r
147 if( dirty !== X.Css.Dirty.REFLOW ){
\r
148 this.commitStyle();
\r
149 this.scrollWidth = this.textNode.offsetWidth + this.contentL + this.contentR;
\r
150 this.scrollHeight = this.textNode.offsetHeight + this.contentT + this.contentB;
\r
152 root.paintReserve( this );
\r
153 this.scrollWidth = w + this.contentL + this.contentR;
\r
154 this.scrollHeight = h + this.contentT + this.contentB;
\r
158 if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0;
\r
159 if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0;
\r
160 this.scrollWidth = w + this.contentL + this.contentR;
\r
161 this.scrollHeight = h + this.contentT + this.contentB;
\r
162 root.paintReserve( this );
\r
165 case X.Css.Dirty.PAINT : // 再描画のみ必要
\r
166 root.paintReserve( this );
\r
170 paint : function( dirty ){
\r
171 var content = this._content,
\r
172 style = this.__style;
\r
173 if( this.updateContent === true || ( style && style.hasPaint === true ) ){
\r
174 if( !this.elmWrap ){
\r
175 this.elmWrap = DOM.createDiv();
\r
176 this.__parent.addDisplayElement( this );
\r
178 dirty !== 0 && this.commitStyle();
\r
179 if( this.updateContent === true ){
\r
180 if( content !== null ){
\r
181 if( !this.textNode ){
\r
182 this.textNode = DOM.cerateText();
\r
183 this.elmWrap.appendChild( this.textNode );
\r
185 this.textNode.data = content;
\r
187 if( this.textNode ){
\r
188 DOM.correct( this.textNode );
\r
189 delete this.textNode;
\r
190 delete this.contentWidth;
\r
191 delete this.conetntHeight;
\r
192 delete this.scrollWidth;
\r
193 delete this.scrollHeight;
\r
197 if( this.elmWrap && content === null && ( !style || style.hasPaint === false ) ){
\r
198 this.__parent.removeDisplayElement( this );
\r
199 DOM.correct( this.elmWrap );
\r
200 delete this.contentWidth;
\r
201 delete this.conetntHeight;
\r
204 commitStyle : function(){
\r
206 if( this.elmWrap ){
\r
207 css = this.__style ? this.__style.cssText( this ) : '';
\r
208 if( this.contentWidth !== AUTO ) css += 'width:' + this.contentWidth + 'px';
\r
209 if( this.contentHeight !== AUTO ) css += 'height:' + this.contentHeight + 'px';
\r
210 this.elmWrap.style.cssText = css;
\r
214 * 親の サイズを元に自身のサイズを計算していく
\r
216 preMesure : function( allowW, allowH ){
\r
217 var style = this.__style,
\r
218 styles, calc, box, min, max,
\r
219 contentW, contentH, allowSize, boxMinus,
\r
220 paddingT, paddingR, paddingB, paddingL,
\r
221 borderT, borderR, borderB, borderL,
\r
222 marginT, marginR, marginB, marginL;
\r
225 styles = style.data;
\r
226 calc = BasicLayoutManager.calcValue;
\r
227 box = styles[ X.Css.AttrNo.sizing ];
\r
230 // 自身が constraintW の場合 親が AUTO ではない
\r
231 // 自身が constraintW でない場合自身が AUTO はなくかつ親 が AUTO の場合 or 自身は % でない
\r
232 if( style.constraintW ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.percentWidth ) ){
\r
233 if( style.constraintW ){
\r
234 contentW = allowW;// - calc( styles[ X.Css.AttrNo.left ], allowW ) - calc( styles[ X.Css.AttrNo.right ], allowW );
\r
236 contentW = BasicLayoutManager.finalValue( styles[ X.Css.AttrNo.width ], styles[ X.Css.AttrNo.minWidth ], styles[ X.Css.AttrNo.maxWidth ], allowW );
\r
238 paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], allowW );
\r
239 paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], allowW );
\r
240 borderR = styles[ X.Css.AttrNo.border + 1 ];
\r
241 borderL = styles[ X.Css.AttrNo.margin + 3 ];
\r
242 marginR = calc( styles[ X.Css.AttrNo.margin + 1 ], allowW );
\r
243 marginL = calc( styles[ X.Css.AttrNo.margin + 3 ], allowW );
\r
244 this.boxWidth = contentW;
\r
247 case 3 : // margin-box
\r
248 boxMinus = - marginR - marginL;
\r
249 case 2 : // border-box
\r
250 boxMinus -= borderR + borderL;
\r
251 case 1 : // padding-box
\r
252 boxMinus -= paddingR + paddingL;
\r
253 // case 0 : // content-box
\r
255 this.contentL = marginL + borderL + paddingL;
\r
256 this.contentR = marginR + borderR + paddingR;
\r
257 this.contentWidth = contentW + boxMinus;
\r
258 this.boxSizingOffsetLR = boxMinus;
\r
260 this.boxWidth = this.contentWidth = AUTO;
\r
261 min = styles[ X.Css.AttrNo.minWidth ];
\r
262 max = styles[ X.Css.AttrNo.maxWidth ];
\r
263 this.minContentWidth = 1 <= min ? min : 0;
\r
264 this.maxContentWidth = 1 <= max ? max : AUTO;
\r
265 delete this.boxSizingOffsetLR;
\r
269 if( style.constraintH ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.percentHeight ) ){
\r
270 if( style.constraintH ){
\r
271 contentH = allowH; // - calc( styles[ X.Css.AttrNo.top ], allowH ) - calc( styles[ X.Css.AttrNo.bottom ], allowH );
\r
273 contentH = BasicLayoutManager.finalValue( styles[ X.Css.AttrNo.height ], styles[ X.Css.AttrNo.minHeight ], styles[ X.Css.AttrNo.maxHeight ], allowH );
\r
275 allowSize = styles[ X.Css.AttrNo.pageBox ] === true ? allowH : allowW;
\r
276 paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], allowSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して
\r
277 paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], allowSize );
\r
278 borderT = styles[ X.Css.AttrNo.border + 0 ];
\r
279 borderB = styles[ X.Css.AttrNo.border + 2 ];
\r
280 marginT = calc( styles[ X.Css.AttrNo.margin + 0 ], allowSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して
\r
281 marginB = calc( styles[ X.Css.AttrNo.margin + 2 ], allowSize );
\r
282 this.boxHeight = contentH;
\r
285 case 3 : // margin-box
\r
286 boxMinus = - marginT - marginR;
\r
287 case 2 : // border-box
\r
288 boxMinus -= borderT + borderR;
\r
289 case 1 : // padding-box
\r
290 boxMinus -= paddingT + paddingR;
\r
291 // case 0 : // content-box
\r
293 this.contentT = marginT + borderT + paddingT;
\r
294 this.conetntB = marginB + borderB + paddingB;
\r
295 this.contentHeight = contentH + boxMinus;
\r
296 this.boxSizingOffsetTB = boxMinus;
\r
298 this.boxHeight = this.contentHeight = AUTO;
\r
299 min = styles[ X.Css.AttrNo.minHeight ];
\r
300 max = styles[ X.Css.AttrNo.maxHeight ];
\r
301 this.minContentHeight = 1 <= min ? min : 0;
\r
302 this.maxContentHeight = 1 <= max ? max : AUTO;
\r
303 delete this.boxSizingOffsetTB;
\r
306 this.boxWidth = this.contentWidth = allowW;
\r
307 this.boxHeight = this.contentHeight = allowH;
\r
308 delete this.minContentHeight;
\r
309 delete this.maxContentHeight;
\r
310 delete this.contentL;
\r
311 delete this.contentT;
\r
312 delete this.contentR;
\r
313 delete this.contentB;
\r
317 * 自身のコンテンツサイズを元に AUTO な width, height を確定していく
\r
319 postMesure : function(){
\r
320 var style = this.__style,
\r
322 contentW, contentH, w, h
\r
323 contentSize, contentPlus;
\r
325 styles = style.data;
\r
326 calc = BasicLayoutManager.advancedCalcValue;
\r
327 contentW = this.contentWidth;
\r
328 box = styles[ X.Css.AttrNo.sizing ];
\r
331 if( this.boxWidth === AUTO ){
\r
332 paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], contentW );
\r
333 paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], contentW );
\r
334 borderR = styles[ X.Css.AttrNo.border + 1 ];
\r
335 borderL = styles[ X.Css.AttrNo.border + 3 ];
\r
336 marginR = calc( styles[ X.Css.AttrNo.margin + 1 ], contentW );
\r
337 marginL = calc( styles[ X.Css.AttrNo.margin + 3 ], contentW );
\r
340 case 3 : // margin-box
\r
341 contentPlus = ( marginR + marginL );
\r
342 case 2 : // border-box
\r
343 contentPlus += ( borderR + borderL );
\r
344 case 1 : // padding-box
\r
345 contentPlus += ( paddingR + paddingL );
\r
346 // case 0 : // content-box
\r
348 contentW += contentPlus;
\r
349 if( !style.constraintW ){
\r
350 min = styles[ X.Css.AttrNo.minWidth ];
\r
351 max = styles[ X.Css.AttrNo.maxWidth ];
\r
352 if( contentW < min && 1 <= min && contentPlus < min ){
\r
353 this.contentWidth = min - contentPlus;
\r
355 if( max < contentW && 1 <= max && contentPlus < max ){
\r
356 this.contentWidth = max - contentPlus;
\r
359 this.contentL = marginL + borderL + paddingL;
\r
360 this.contentR = marginR + borderR + paddingR;
\r
361 this.boxWidth = this.contentWidth + this.contentL + this.contentR;
\r
364 if( this.boxHeight === AUTO ){
\r
365 contentH = this.contentHeight;
\r
366 contentSize = styles[ X.Css.AttrNo.pageBox ] === true ? contentH : contentW;
\r
367 paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], contentSize );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して
\r
368 paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], contentSize );
\r
369 borderT = styles[ X.Css.AttrNo.border + 0 ];
\r
370 borderB = styles[ X.Css.AttrNo.border + 2 ];
\r
371 marginT = calc( styles[ X.Css.AttrNo.margin + 0 ], contentSize );// marginTRBL の % 指定は 最大幅に対して TB でも幅に対して
\r
372 marginB = calc( styles[ X.Css.AttrNo.margin + 2 ], contentSize );
\r
375 case 3 : // margin-box
\r
376 contentPlus = ( marginT + marginB );
\r
377 case 2 : // border-box
\r
378 contentPlus += ( borderT + borderB );
\r
379 case 1 : // padding-box
\r
380 contentPlus += ( paddingT + paddingB );
\r
381 // case 0 : // content-box
\r
383 contentH += contentPlus;
\r
384 if( !style.constraintH ){
\r
385 min = styles[ X.Css.AttrNo.minHeight ];
\r
386 max = styles[ X.Css.AttrNo.maxHeight ];
\r
387 if( contentH < min && 1 <= min && contentPlus < min ){
\r
388 this.contentHeight = min - contentPlus;
\r
390 if( max < contentH && 1 <= max && contentPlus < max ){
\r
391 this.contentHeight = max - contentPlus;
\r
394 this.contentT = marginT + borderT + paddingT;
\r
395 this.contentB = marginB + borderB + paddingB;
\r
396 this.boxHeight = this.contentHeight + this.contentT + this.contentB;
\r
399 this.boxWidth = this.contentWidth;
\r
400 this.boxHeight = this.contentHeight;
\r
401 delete this.minContentHeight;
\r
402 delete this.maxContentHeight;
\r
403 delete this.contentL;
\r
404 delete this.contentT;
\r
405 delete this.contentR;
\r
406 delete this.contentB;
\r
409 addDisplayElement : function( nodeData ){
\r
412 removeDisplayElement : function( nodeData ){
\r
414 DOM.correct( nodeData.elmWrap );
\r
415 delete nodeData.elmWrap;
\r
416 delete nodeData.textNode;
\r
417 delete nodeData.contentWidth;
\r
418 delete nodeData.conetntHeight;
\r
419 delete nodeData.currentWidth;
\r
420 delete nodeData.currentHeight;
\r
424 var Node = X.Class.create(
\r
426 X.Class.POOL_OBJECT,
\r
429 Constructor : function( root, parent ){
\r
430 X.Class._newPrivate( this, X.Class._getPrivate( root ), parent ? X.Class._getPrivate( parent ) : undefined, this );
\r
432 content : function( v ){
\r
433 return X.Class._getPrivate( this ).content( v );
\r
435 style : function( v ){
\r
436 return X.Class._getPrivate( this ).paint( v );
\r
438 remove : function(){
\r
439 X.Class._getPrivate( this ).remove();
\r
441 nodeIndex : function( v ){
\r
442 return X.Class._getPrivate( this ).nodeIndex( v );
\r
444 displayIndex : function(){
\r
447 disabled : function( v ){
\r
448 return X.Class._getPrivate( this ).disabled( v );
\r
450 cursor : function( v ){
\r
451 return X.Class._getPrivate( this ).cursor( v );
\r
459 getWidth : function(){
\r
462 getHeight : function(){
\r
465 getAbsolutePositionX : function(){
\r
466 return X.Class._getPrivate( this ).getAbsolutePositionX();
\r
468 getAbsolutePositionY : function(){
\r
469 return X.Class._getPrivate( this ).getAbsolutePositionY();
\r
471 scrollTo : function( x, y ){
\r
472 X.Class._getPrivate( this ).scrollTo( x, y );
\r
474 scrollX : function( v ){
\r
475 return X.Class._getPrivate( this ).scrollX( v );
\r
477 scrollY : function( v ){
\r
478 return X.Class._getPrivate( this ).scrollY( v );
\r
480 addEventListener : function( type, handler, opt_thisObject ){
\r
481 X.Class._getPrivate( this ).addEventListener( type, handler, opt_thisObject );
\r
483 removeEventListener : function( type, handler ){
\r
484 X.Class._getPrivate( this ).removeEventListener( type, handler );
\r