OSDN Git Service

Version 0.6.38, fix for safari2-.
authoritozyun <itozyun@user.sourceforge.jp>
Sat, 10 May 2014 07:25:16 +0000 (16:25 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Sat, 10 May 2014 07:25:16 +0000 (16:25 +0900)
0.6.x/js/core/00_X.js
0.6.x/js/core/01_XUa.js
0.6.x/js/core/04_XClass.js
0.6.x/js/core/07_XNotification.js
0.6.x/js/dom/10_XDom.js
0.6.x/js/dom/11_XDomNode.js
0.6.x/js/dom/12_XDomEvent.js
0.6.x/js/dom/15_XDomStyle.js
0.6.x/js/dom/20_XDomImage.js
0.6.x/js/dom/22_XDomBuilder.js

index 68f25c3..b758632 100644 (file)
@@ -12,10 +12,11 @@ X.bootTime = + new Date;
 X.getTime = Date.now ? new Function( 'return Date.now()' ) : new Function( 'return +new Date' );\r
                \r
 X.emptyFunction = new Function;\r
-               \r
+\r
                // defer の場合もあるので、document.readyState を見る\r
 X.inHead = (function( s ){\r
        if( !s ) return false;\r
+       if( !s.length ) return false; // Safari1.3 312.8 でerror\r
        s = s[ s.length - 1 ];\r
        // Dom0 || Dom1\r
        return ( s.parentElement || s.parentNode ).tagName.toLowerCase() === 'head';\r
@@ -80,5 +81,5 @@ X.matchTest = function( array1, array2 ){
        \r
 // bonus: hotfix for IE6 SP1 (bug KB823727)\r
 document.execCommand && document.execCommand( 'BackgroundImageCache', false, true );\r
-document.execCommand && document.execCommand( 'LiveResize', false, false );\r
-document.execCommand && document.execCommand( 'SizeToControl', false, false );
\ No newline at end of file
+//document.execCommand && document.execCommand( 'LiveResize', false, false );\r
+//document.execCommand && document.execCommand( 'SizeToControl', false, false );\r
index 064cb3b..7296b60 100644 (file)
@@ -1,7 +1,7 @@
+\r
 /*\r
  * UA\r
  */\r
-\r
 X.UA = (function( n, undefined ){\r
        var acme = {},\r
                dua  = n.userAgent,\r
@@ -28,7 +28,20 @@ X.UA = (function( n, undefined ){
        i = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);\r
        if( i && !acme.Chrome ){\r
                acme.Safari = parseFloat( dav.split("Version/")[1] );\r
-               if( !acme.Safari || parseFloat(dav.substr( i + 7 )) <= 419.3 ){\r
+               i = parseFloat(dav.substr( i + 7 ));\r
+               if( !acme.Safari && i < 100 ){\r
+                       acme.Safari = 1;\r
+               };\r
+               if( !acme.Safari && i < 125 ){\r
+                       acme.Safari = 1.1;\r
+               };\r
+               if( !acme.Safari && i < 312 ){\r
+                       acme.Safari = 1.2;\r
+               };\r
+               if( !acme.Safari && i < 412 ){\r
+                       acme.Safari = 1.3;\r
+               };\r
+               if( !acme.Safari && i <= 419.3 ){\r
                        acme.Safari = 2;\r
                };\r
        };\r
@@ -66,4 +79,17 @@ X.inObject = X.UA.IE && X.UA.IE < 5 ?
                };\r
                return false;\r
        }) :\r
-       new Function( 'a,b', 'return a in b' );
\ No newline at end of file
+       new Function( 'a,b', 'return a in b' );\r
+       \r
+\r
+// Safari 3.1 未満は開発コンソールがない!\r
+// http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
+if( X.UA.Safari && X.UA.WebKit < 525.13 ){     \r
+       window.onerror = function( x, y, z ){\r
+               var n = String.fromCharCode( 10 );\r
+           alert('window.onerrorによるエラーの捕捉:' + n + x + n + y + 'の' + z + '行目付近です。');\r
+           return true;\r
+       };\r
+};\r
+\r
+\r
index e87daa3..be5f431 100644 (file)
@@ -230,18 +230,23 @@ X.Class = ( function(){
                                // サブクラスの場合、クラス定義の上書きがなくても作成可能\r
                                if( !traits ){\r
                                        X.Notification.critical( 'No Class Def!' );\r
-                                       return;                                 \r
+                                       return;\r
                                };\r
                                props = {};\r
                        } else\r
                        if( props[ CONSTRUCTOR ] && X.Type.isFunction( props[ CONSTRUCTOR ] ) ){\r
                                classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ];\r
                        };\r
-                       \r
+\r
                        klass = new Function( 'var a=arguments,f=a.callee;if(f.__new)return f.__new(a)' );\r
                        klass.__new = C;\r
-                       klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
-                       klass.prototype.constructor = klass;\r
+                       if( X.UA.Safari && X.UA.Safari < 2 ){\r
+                               traits && X.Class._override( klass.prototype, traits, false );\r
+                               X.Class._override( X.Class._override( klass.prototype, CommonProps, false ), props, true );\r
+                       } else {\r
+                               klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
+                               klass.prototype.constructor = klass;\r
+                       };\r
                        klass.name = displayName;\r
                        \r
                        if( opt_abstract === true ){\r
@@ -334,12 +339,13 @@ X.Class = ( function(){
                },\r
                /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
                _override : function ( target, src, force ){\r
-                       for( var p in src ){\r
+                       var p;\r
+                       for( p in src ){\r
                                if( p === 'Super' || p === 'SuperConstructor' ){\r
                                        X.Notification.critical( 'Super & SuperConstructor is reserved!' );\r
                                        return;\r
                                };\r
-                               if( force === true || target[ p ] === void 0 ){\r
+                               if( force || target[ p ] === void 0 ){\r
                                        target[ p ] = src[ p ];\r
                                };\r
                        };\r
index 50204c3..9c148e6 100644 (file)
@@ -48,3 +48,4 @@ notice        通知メッセージ
 info   サーバ情報\r
 debug  デバック用の情報\r
 */\r
+\r
index acd55f8..4fe822d 100644 (file)
@@ -102,7 +102,7 @@ X.Dom = X.Class._override(
                                        Node._systemNode = Node.create( 'div', { 'class' : 'hidden-system-node' } ),\r
                                        Node._fontSizeNode = Node.create( 'div', { 'class' : 'hidden-system-node' } ).cssText( 'line-height:1;height:1em;' ).text( 'X' )\r
                                )._startUpdate();\r
-                               \r
+\r
                                X.Dom.asyncDispatch( 0, { type : X.Dom.Event.DOM_INIT } );\r
                        } );\r
 \r
@@ -128,6 +128,9 @@ X.Dom = X.Class._override(
                                .listen( 'beforeunload', X.Dom )\r
                                .listenOnce( 'unload', X.Dom );\r
 \r
+//ブラウザの戻るボタンで戻ったときに呼ばれるイベントとかキャッシュとかそこらへんのこと\r
+//http://d.hatena.ne.jp/koumiya/20080916/1221580149\r
+\r
                        if( document[ 'hidden' ] !== undefined ) {// iOS 7+\r
                                Node._document.listen( 'visibilitychange', X.Dom );\r
                        } else\r
@@ -240,7 +243,8 @@ X.Dom = X.Class._override(
                                } ) :\r
                                ( function(){\r
                                        Node.root._updateTimerID && Node.root._startUpdate();\r
-                                       return[ X.Dom._root.scrollLeft, X.Dom._root.scrollTop ];\r
+                                       // body は Safari2-\r
+                                       return[ X.Dom._root.scrollLeft || document.body.scrollLeft, X.Dom._root.scrollTop || document.body.scrollTop ];\r
                                } ),\r
 \r
                getScrollbarSize : function(){\r
index 36a7ffb..1d8733b 100644 (file)
@@ -108,7 +108,7 @@ X.Dom.Node = X.EventDispatcher.inherits(
                                                // X.Dom.Dirty.CSS を落とす\r
                                                this._dirty = 0;\r
                                                // attr の回収は不可能、、、\r
-                                               if( X.UA.IE && X.UA.IE < 5 ){\r
+                                               if( X.Dom.DOM_IE4 ){\r
                                                        v.setAttribute( 'UID', '' + uid );\r
                                                } else {\r
                                                        v.UID = uid;\r
@@ -132,8 +132,10 @@ X.Dom.Node = X.EventDispatcher.inherits(
                                                return Node.none;\r
                                        case Node.IS_IMAGE :\r
                                                v.UID = uid;\r
+                                               this._isImage = true;\r
                                        case Node.IS_WINDOW :\r
                                        case Node.IS_DOCUMENT :\r
+                                               if( xnode = Node._getXNode( v ) ) return xnode;\r
                                                this._rawNode   = v;\r
                                                this._xnodeType = 2;\r
                                                this._state     = X.Dom.State.DISPLAY_BLOCK;\r
@@ -170,6 +172,11 @@ Node._getType = function( v ){
        if( v === window ) return Node.IS_WINDOW;\r
        if( v === document ) return Node.IS_DOCUMENT;\r
        if( v.constructor === window.Image ) return Node.IS_IMAGE;\r
+       if( X.UA.Safari && X.UA.Safari < 3 ){\r
+               if( v.src !== undefined && v.onload !== undefined && X.Type.isNumber( v.height ) && X.Type.isNumber( v.width ) && X.Type.isBoolean( v.complete ) ){\r
+                       return Node.IS_IMAGE;\r
+               };\r
+       };      \r
        if( v.constructor === Node ) return Node.IS_XNODE;\r
        if( v.constructor === X.Dom.NodeList ) return Node.IS_XNODE_LIST;\r
        if( v.tagName ) return Node.IS_RAW_HTML;\r
@@ -189,7 +196,7 @@ Node._getXNode = function( v ){
                case Node.IS_RAW_HTML :\r
                case Node.IS_IMAGE :\r
                        // fake TextNode too.\r
-                       if( X.UA.IE && X.UA.IE < 5 ){\r
+                       if( X.Dom.DOM_IE4 ){\r
                                uid = v.getAttribute( 'UID' );\r
                                return uid && Node._chashe[ uid ];\r
                        };\r
@@ -232,7 +239,7 @@ Node.getRoot = function( xnode ){
 };\r
        // XMLかどうかを判別する\r
 Node.isXmlDocument =\r
-       X.UA.IE && X.UA.IE < 5 ?\r
+       X.Dom.DOM_IE4 ?\r
                X.emptyFunction :\r
                (function( root ){\r
                        return root._rawNode.createElement( 'p' ).tagName !== root._rawNode.createElement( 'P' ).tagName;\r
@@ -1207,7 +1214,8 @@ Node.prototype._afterActualCreate =
                                xnodes[ i ]._afterActualCreate();\r
                        };\r
                };\r
-               \r
+               // src の onload があるので先ではないか?\r
+               // ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
                this._restoreEvent();// イベントの復帰\r
        }) :\r
        X.Dom.DOM_IE4 ? (function(){\r
index 0c3a820..87f7b37 100644 (file)
@@ -11,10 +11,14 @@ if( window.addEventListener ){
                this.type          = X.Dom.Event.RenameTo[ e.type ] || e.type;\r
                \r
                //http://www.quirksmode.org/js/events_properties.html\r
-               this.target        = Node._getXNode( e.target.nodeType === 3 ? e.target.parentNode : e.target );// defeat Safari bug // xnode\r
+               if( e.target ){\r
+                       this.target        = Node._getXNode( e.target.nodeType === 3 ? e.target.parentNode : e.target );// defeat Safari bug // xnode\r
+               };\r
+               if( e.relatedTarget ){\r
+                       this.relatedTarget = Node._getXNode( e.relatedTarget.nodeType === 3 ? e.relatedTarget.parentNode : e.relatedTarget ); // xnode\r
+               };\r
                \r
                this.currentTarget = xnode; // xnode\r
-               this.relatedTarget = Node._getXNode( e.relatedTarget ); // xnode\r
                this.eventPhase    = e.eventPhase;\r
                \r
                this.clientX       = e.clientX;\r
@@ -191,7 +195,7 @@ X.Dom.Node.prototype.listen = function( type, arg1, arg2, arg3 /* [ listener ||
        \r
        if( this._xnodeType === 0 || this._xnodeType === 3 || !arg1 ) return this;\r
        \r
-       ( !this._listeners || !this._listeners[ type ] ) && this._addEvent( type );\r
+       ( !this._listeners || !this._listeners[ type ] ) && X.Type.isString( type ) && this._addEvent( type );\r
        \r
        return typeof arg1 === 'function' ?\r
                X.EventDispatcher.prototype.listen.call( this, type, this, arg1, arg2 ) :\r
@@ -199,6 +203,20 @@ X.Dom.Node.prototype.listen = function( type, arg1, arg2, arg3 /* [ listener ||
 };\r
 \r
 X.Dom.Node.prototype._addEvent =\r
+       // Days on the Moon DOM Events とブラウザの実装 \r
+       // http://nanto.asablo.jp/blog/2007/03/23/1339502\r
+       // Safari 2 では関数オブジェクトしか EventListener として使えませんが、Safari のナイトリービルドでは handleEvent メソッドを持つオブジェクトも EventListener として使えるようです。\r
+       X.Dom.EVENT_W3C && X.UA.Safari && X.UA.Safari < 3 ?\r
+               (function( type ){\r
+                       var raw = this._rawNode;\r
+                       if( !raw ) return;\r
+                       this._handleEvent = this._handleEvent || X.Callback.create( this );\r
+                       if( this._isImage ){\r
+                               raw[ 'on' + type ] = this._handleEvent;\r
+                       } else {\r
+                               raw.addEventListener( type, this._handleEvent, false );\r
+                       };\r
+               }) :\r
        X.Dom.EVENT_W3C ?\r
                (function( type ){\r
                        this._rawNode && this._rawNode.addEventListener( X.Dom.Event.Rename[ type ] || type, this, false );\r
@@ -222,12 +240,27 @@ X.Dom.Node.prototype.unlisten = function( type /* , arg1, arg2, arg3 */ ){
        \r
        X.EventDispatcher.prototype.unlisten.apply( this, arguments );\r
        \r
-       l && !list[ type ] && this._removeEvent( type );\r
+       l && !list[ type ] && X.Type.isString( type ) && this._removeEvent( type );\r
        \r
        return this;\r
 };\r
 \r
 X.Dom.Node.prototype._removeEvent =\r
+       X.Dom.EVENT_W3C && X.UA.Safari && X.UA.Safari < 3 ?\r
+               (function( type ){\r
+                       var raw = this._rawNode;\r
+                       if( !raw ) return;\r
+                       \r
+                       if( raw.constructor === Image ){\r
+                               raw[ 'on' + type ] = '';\r
+                       } else {\r
+                               raw.removeEventListener( type, this._handleEvent, false );\r
+                       };\r
+                       if( !this._listeners ){\r
+                               X.Callback._correct( this._handleEvent );\r
+                               delete this._handleEvent;\r
+                       };\r
+               }) :\r
        X.Dom.EVENT_W3C ?\r
                (function( type ){\r
                        var elm = this._rawNode;\r
@@ -255,18 +288,25 @@ X.Dom.Node.prototype._removeEvent =
                        };\r
                });\r
 \r
+// Is this in regard to the Safari 1.x preventDefault bug on click/dblclick?\r
+// https://groups.google.com/forum/#!msg/comp.lang.javascript/uYEuCHjHxnw/yKoHtZJPa1QJ\r
 \r
 X.Dom.Node.prototype.handleEvent =\r
        X.Dom.EVENT_W3C ?\r
                (function( e ){\r
                        var ret = X.EventDispatcher.prototype.dispatch.call( this, new X.Dom.Event( e, this ) );\r
-\r
+                       \r
                        if( ret & X.Callback.STOP_PROPAGATION ){\r
                                e.stopPropagation();\r
                        };\r
                        if( ret & X.Callback.PREVENT_DEFAULT ){\r
                                this._tag === 'A' && this._rawNode.blur();\r
                                e.preventDefault();\r
+                               if( X.UA.Safari && X.UA.Safari < 3 ){\r
+                                       if( e.type === 'click' || e.type === 'dbclick' ){\r
+                                               X.Dom._safariPreventDefault = true;\r
+                                       };\r
+                               };\r
                                return false;\r
                        };\r
                }) :\r
@@ -303,15 +343,27 @@ X.Dom.Node.prototype._restoreEvent = function(){
        };\r
 };\r
 \r
-\r
-\r
 /* -----------------------------------------------\r
  * Document Ready\r
  *  Dean Edwards/Matthias Miller/John Resig\r
  */\r
+\r
+// SafariでJavaScriptのデバッグをする方法\r
+// safari1.3 可\r
+// http://shimax.cocolog-nifty.com/search/2006/09/safarijavascrip_c54d.html\r
+\r
+// Re: onLoad doesn't work with Safari?\r
+// http://lists.apple.com/archives/web-dev/2003/Oct/msg00036.html\r
+if( X.UA.Safari && X.UA.Safari < 3 ){\r
+       X.Timer.add( 10, function(){\r
+               if( !X.Dom._init ) return X.Callback.UN_LISTEN;\r
+               if( 'loaded|complete'.indexOf( document.readyState ) !== -1 ) return X.Dom._init();\r
+       } );\r
+} else\r
+\r
 /* for ie9+/Mozilla/Opera9 */\r
 if( X.Dom.DOM_W3C ){\r
-       X.Dom.Node._document.listenOnce( 'DOMContentLoaded', X.Dom._init );\r
+       Node._document.listenOnce( 'DOMContentLoaded', X.Dom._init );\r
 } else\r
 if( 5 <= X.UA.IE && X.inHead ){\r
        // if this script in Head\r
@@ -327,12 +379,27 @@ if( X.UA.WebKit ){ // sniff
                if( 'loaded|complete'.indexOf( document.readyState ) !== -1 ) return X.Dom._init();\r
        });\r
 };\r
+       /* for other browsers */\r
+       Node._window.listenOnce( 'load', X.Dom._init ); \r
+\r
+\r
 \r
-/* for other browsers */\r
-X.Dom.Node._window.listenOnce( 'load', X.Dom._init );\r
 \r
 //\r
-X.Dom.listenOnce( X.Dom.Event.XDOM_READY, function(e){ console.log( 'X.Dom XDomReady ' + X.Dom.readyState ); } );\r
+X.Dom.listenOnce( X.Dom.Event.XDOM_READY, function(e){\r
+       console.log( 'X.Dom XDomReady ' + X.Dom.readyState );\r
+} );\r
+\r
+if( X.UA.Safari && X.UA.Safari < 3 ){\r
+       document.documentElement.onclick =\r
+       document.documentElement.ondbclick = function( e ){\r
+                       if( X.Dom._safariPreventDefault ){\r
+                               X.Dom._safariPreventDefault = false;\r
+                               e.preventDefault();\r
+                               return false;\r
+                       };\r
+               };\r
+};\r
 \r
 X.Dom.listenOnce( X.Dom.Event.VIEW_RESIZED, function(e){ console.log( 'X.Dom VIEW_RESIZED ' + e.w + 'x' + e.h ); } );\r
 \r
index 20c879a..ef2fc7e 100644 (file)
@@ -1258,7 +1258,7 @@ X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
        
        for( i = list.length; i; ){
                unit = list[ --i ];
-               output[ unit ] = xnode.css( 'width', 100 + unit ).width() / 100;
+               output[ unit ] = xnode.css( 'width', 10 + unit ).width() / 10;
        };
 
        output = X.Dom.Style._FONT_SIZE_RATIO = {},
index 7de759a..5881448 100644 (file)
@@ -37,7 +37,7 @@ X.Dom.Image = {
                        };\r
                        if( ret = X.Dom.Image._actualSize[ img.src ] ) return ret;\r
                };\r
-       \r
+\r
                // for Firefox, Safari, Google Chrome\r
                if( img.naturalWidth ) return [ img.naturalWidth, img.naturalHeight ];\r
        \r
@@ -56,17 +56,22 @@ X.Dom.Image = {
                        // restore\r
                        run.height = memH;\r
                } else {// for Opera and Other\r
-       \r
-                       memW = img.width;\r
-                       memH = img.height;\r
-                       // keep current style\r
-                       img.removeAttribute( 'width' );\r
-                       img.removeAttribute( 'height' );\r
-                       w = img.width;\r
-                       h = img.height;\r
-                       img.width  = memW;\r
-                       // restore\r
-                       img.height = memH;\r
+                       \r
+                       memW = w = img.width;\r
+                       memH = h = img.height;\r
+                       \r
+                       if( img.removeAttribute ){ // Safari1.3 の Image は removeAttribute がない\r
+                               // keep current style\r
+                               img.removeAttribute( 'width' );\r
+                               img.removeAttribute( 'height' );\r
+                               \r
+                               w = img.width;\r
+                               h = img.height;\r
+                               \r
+                               // restore\r
+                               img.width  = memW;\r
+                               img.height = memH;\r
+                       };\r
                };\r
                \r
                ret = X.Dom.Image._actualSize[ img.src ] = [ w, h ];\r
@@ -96,14 +101,14 @@ X.Dom.Image = {
                        delay   : null,\r
                        timeout : 0,\r
                        Constructor : function( abspath, delay, timeout ){\r
-                               var img;\r
+                               var img, s, p;\r
                                \r
                                this.abspath = abspath;\r
                                this.delay   = delay || 100;\r
                                this.timeout = timeout || 10000;\r
                                this.xnode =\r
                                        (\r
-                                               window.Image ?\r
+                                               window[ 'Image' ] ?\r
                                                        X.Dom.Node( img = new Image() ) :\r
                                                        X.Dom.Node._systemNode.create( 'img', { src : abspath } )\r
                                        )\r
@@ -112,9 +117,7 @@ X.Dom.Image = {
                                        .listen( 'abort', this )\r
                                        .listen( X.Dom.Event.LOAD_ASSET_COMPLETE, this )\r
                                        .listen( X.Dom.Event.LOAD_ASSET_ERROR, this );\r
-       \r
                                img && ( img.src = abspath );\r
-\r
                                this._detect();\r
                        },\r
                        handleEvent : function( e ){\r
@@ -152,7 +155,7 @@ X.Dom.Image = {
                        },      \r
                        _detect : function(){\r
                                if( this.finish === true ) return;\r
-                               if( this.xnode._rawNode.complete ){\r
+                               if( this.xnode._rawNode && this.xnode._rawNode.complete ){\r
                                        this.finish = true;\r
                                        if( this.xnode._rawNode.width ) return;\r
                                        this.timerID = this.asyncDispatch( 0, { type : X.Dom.Event.LOAD_ASSET_ERROR } );\r
@@ -160,7 +163,7 @@ X.Dom.Image = {
                                };\r
                                if( ( this.tick += this.delay ) > this.timeout ){\r
                                        this.finish = true;\r
-                                       this.timerID = this.asyncDispatch( 0, { type : X.Dom.Event.LOAD_ASSET_ERROR } );\r
+                                       this.timerID = this.asyncDispatch( 0, { type : X.Dom.Event.LOAD_ASSET_ERROR, msg : 'timeout' } );\r
                                        return;\r
                                };\r
                                this.timerID = X.Timer.once( this.delay, this, this._detect );\r
index 7def580..a49b069 100644 (file)
@@ -16,7 +16,7 @@ X.Dom.listenOnce( X.Dom.Event.DOM_PRE_INIT,
        // textarea の内容を控えて、消す。xnode tree 構築後に復帰。でないと、html パースでこける\r
        \r
        // cleanup tree \r
-       (function cleanUpTree( elm, skip, head ){\r
+       (function/*cleanUpTree*/( elm, skip, head ){\r
                var moveToHead = 'style,bgsound,area,base,meta'.split( ',' ),\r
                        remove     = 'script,noscript,noframes,comment,!,noembed,nolayer'.split( ',' ),\r
                        noncleanup = 'pre,textarea,code,kbd,samp,xmp,plaintext,listing'.split( ',' ),\r
@@ -39,7 +39,7 @@ X.Dom.listenOnce( X.Dom.Event.DOM_PRE_INIT,
                                                continue;\r
                                        } else {\r
                                                // pre タグ以下はスペースの置換は行わない\r
-                                               node.childNodes && node.childNodes.length &&  cleanUpTree( node, skip || noncleanup.indexOf( tag ) !== -1, head );\r
+                                               node.childNodes && node.childNodes.length && /*cleanUpTree*/arguments.callee( node, skip || noncleanup.indexOf( tag ) !== -1, head );\r
                                        };\r
                                        textNode = null;\r
                                        break;\r