ColorAnimが動かない(続編)。

昨日に引き続き「DataTable Control; Complex Example of Multiple Features」の調査。

YUI2.6.0では、右端の編集可能(editable)な列のセルを更新すると、更新した行が黄色く光るようになっていた。

これが、YUI2.7.0だと光らない。(Official Exampleも光らない)
昨日は適当に探ってみたが、本日はキチンと調査してみた。

カラー・アニメーションのインスタンスを生成する際の

    var rowColorAnim = new YAHOO.util.ColorAnim(elRow.cells, ...

の部分の"elRow.cells"の引渡しがうまくいっていない模様。
ためしに、

    var rowColorAnim = new YAHOO.util.ColorAnim(elRow.cells[0], ...

とすると、(その行の)先頭の列は黄色くひかる。

"elRow.cells[0]"はHTMLTableCellElementオブジェクトだが、"elRow.cells"はHTMLCollectionオブジェクト。
ちなみに、"elRow"はHTMLTableRowElementだが、これでも動かない。(YUI2.6.0でも同様)

うーーん。修行が甘い。。。

ということで、ただしく、YUI2.7.0のRelease Noteを読んでもAnimationに変更がかかったとは書いてないので、ダウンロードファイル中にある、README_animation.txtを見てみる。
すると

version 2.7.0
Updated set/getAttribute to fall back to element.attribute
  element.atributeへのフォールバックのために、set/getAttributeメソッドを直した。
  (README_animation.txtより引用)

と書いてある。

修正してあったのは、animation.jsにあるAnimクラスのset/getAttributeメソッド。Animクラスは、ColorAnimクラスのスーパークラスになっている。
修正されたsetAttributeメソッドは、以下の部分(90行目付近)となる。

    setAttribute: function(attr, val, unit) {
    	var el = this.getEl();
    
        if ( this.patterns.noNegatives.test(attr) ) {
            val = (val > 0) ? val : 0;
        }

    // ここ(A)から
        if ('style' in el) {
       			Y.Dom.setStyle(el, attr, val + unit);
        } else if (attr in el.getAttributeKeys()) {
        		el[attr] = val;
        }
    // ここ(B)まで。
    },                        

修正されたgetAttributeメソッドは、以下の部分(110行目付近)が該当する。

    getAttribute: function(attr) {
        var el = this.getEl();
        var val = Y.Dom.getStyle(el, attr);

        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
            return parseFloat(val);
        }
        
        var a = this.patterns.offsetAttribute.exec(attr) || [];
        var pos = !!( a[3] ); // top or left
        var box = !!( a[2] ); // width or height

    // ここ(C)から
        if ('style' in el) {
            // use offsets for width/height and abs pos top/left
            if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
            	val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
            } else { // default to zero for other 'auto'
                val = 0;
            }
        } else if (attr in el) {
            val = el[attr];
        }
    // ここ(D)まで

        return val;
    },

いずれも、styleという属性の有無をエレメントから探すようにif文が追加されている。

これでは、HTMLCollectionの場合はうまくない。(死んで終わってたんだろうな)

なんのためのフォールバックなんだろう、と思いつつも、フォールバックなんだからいいかと、YUI2.6.0の状態に戻してしまった(何故、YUI2.7.0で修正した真意が分からないので、直せない。<= 「ちゃんと調べろ」という話もあるかな)。

まず、setAttributeは、以下のように変更。

    setAttribute: function(attr, val, unit) {
    	// el could be HTMLCollection.
    	var el = this.getEl();
    
    	// attr means a kind of style(ex. backgoundColor)
        if ( this.patterns.noNegatives.test(attr) ) {
            val = (val > 0) ? val : 0;
        }

// t.odaka
//  this 'if' is incorrect when el is HTMLCollection.
//        if ('style' in el) {
       			Y.Dom.setStyle(el, attr, val + unit);
//  this 'else if' may be incorrect, too.
//        } else if (attr in el) {
//            el[attr] = val;
//        }
    },                        

getAttributeは、以下のように変更。

    getAttribute: function(attr) {
    alert("test-1");
        var el = this.getEl();
        var val = Y.Dom.getStyle(el, attr);

        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
            return parseFloat(val);
        }
        
        var a = this.patterns.offsetAttribute.exec(attr) || [];
        var pos = !!( a[3] ); // top or left
        var box = !!( a[2] ); // width or height

// t.odaka
//  this 'if' is incorrect when el is HTMLCollection.
//        if ('style' in el) {
            // use offsets for width/height and abs pos top/left
            if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
            	val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
            } else { // default to zero for other 'auto'
                val = 0;
            }
//  this 'else if' may be incorrect, too.
//        } else if (attr in el) {
//            val = el[attr];
//        }

        return val;
    },

とりあえず、これで動くことは確認。