1. #1
    Ext JS Premium Member
    Join Date
    Mar 2007
    Location
    Virginia, USA
    Posts
    504
    Vote Rating
    0
    vtswingkid is on a distinguished road

      0  

    Default Element.js -- update bugs

    Element.js -- update bugs


    The following bugs were found when testing with IE6, FIREFOX, OPERA, NETCSAPE
    CSS doesn't dynamically load in ie6.
    JS scripts would not load dynamically in all browsers.
    Duplicates of CSS and JS in DOM.
    Removal of whitespace broke CSS loads and JS loads in all browsers
    i.e. <script>...</script><script>...</script>

    I propose the following changes to update within element.js:
    Code:
    update:function(msg,loadScripts){
    	var cssFragment='(?:<style>)((\n|\r|.)*?)(?:</style>)';
    	var jsFragment='(?:<script>)((\n|\r|.)*?)(?:</script>)';
    	var docHead=document.getElementsByTagName("head")[0];
    	var html=msg.replace(new RegExp(cssFragment, 'img'),"");
    	if(html){
    		html=html.toString();
    		html=html.replace(new RegExp(jsFragment, 'img'),"");
    		if(html){
    			html=html.toString();
    			this.dom.innerHTML=html;
    		}
    	}
    	var css=msg.match(new RegExp(cssFragment, 'img'));
    	if(css){
    		css=css.toString();
    		var re = /(?:<style.*?id=[\"\'](.*?)[\"\'].*?>)([\S\s]*?)(?:</style>)|(?:<style>)([\S\s]*?)(?:</style>)/ig;
    		var match;
    		while(match = re.exec(css)){
    			if(match[2]||match[3]){
    				var s0 = document.createElement("style");
    				var t;
    				if(match[1]){
    					var e=document.getElementById(match[1]);
    					if(e)e.parentNode.removeChild(e);
    					s0.setAttribute("id", match[1]);
    				}
    				s0.setAttribute("type","text/css");
    				if(match[2])t=match[2];
    				if(match[3])t=match[3];
    				if(s0.styleSheet)s0.styleSheet.cssText=t;//IE
    				else s0.appendChild(document.createTextNode(t));//W3C
    				docHead.appendChild(s0);
    			}
    		}
    	}
    	
    	if(!loadScripts)return this;
    	var js=msg.match(new RegExp(jsFragment, 'img'));
    	if(!js)return this;
    	js=js.toString();
    	var dom = this.dom;        
    	var _parseScripts = function(){
    		var re = /(?:<script.*?src=[\"\'](.*?)[\"\'].*?>)[\S\s]*?(?:</script>)|(?:<script>)([\S\s]*?)(?:</script>)/ig;
    		var match;
    		while(match=re.exec(js)){
    			if(match[2])eval(match[2]);
    			else if(match[1]){
    				var s0=document.createElement("script");			
    				s0.src=match[1];
    				docHead.appendChild(s0);
    			}
    		}
    	}
    	setTimeout(_parseScripts,10);
    	return this;
    }
    [/code]

  2. #2
    Ext JS Premium Member
    Join Date
    Mar 2007
    Location
    Virginia, USA
    Posts
    504
    Vote Rating
    0
    vtswingkid is on a distinguished road

      0  

    Default prototype overide suggestion please?

    prototype overide suggestion please?


    Thanks again for you hardwork on extensions, Jack.

    If you or anyone has any improvements or sees any problems with this code please post your solutions. I am an unseasoned javascript user. So I imagine there are some inherent problems.
    I also have not tested this in Safari, Konquer, older versions, etc... So I am very interested in such results.

    By the way if this does not make it into the code what is the suggested method for overriding prototypes so as not to modify the ext code base directly?

    Cheers!

    Oh and please bare with my lousy coding as I come up to speed with the rest of you. :wink:

  3. #3
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    17
    jack.slocum will become famous soon enough jack.slocum will become famous soon enough

      0  

    Default


    The preferred may to override functions without modifying the base code is to use prototyping. You just include it after the yui-ext.js file.

    YAHOO.ext.Element.prototype.update = function(html, loadScripts){
    .. insert your code..
    };

  4. #4
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    17
    jack.slocum will become famous soon enough jack.slocum will become famous soon enough

      0  

    Default


    BTW, I have a different solution I will be putting in. There's been so many issues with this particular functionality I've decided to address it myself.

  5. #5
    Ext User
    Join Date
    Mar 2007
    Posts
    1
    Vote Rating
    0
    kevinyao is on a distinguished road

      0  

    Default


    Jack,
    I don't know how your new implementation is going to look, but for Safari, I had to make the following change to your function:

    Code:
    update : function(html, loadScripts){
            this.dom.innerHTML = html;
            if(!loadScripts) return this;
    
            var dom = this.dom;
            var _parseScripts = function(){
                var s = dom.getElementsByTagName("script");
                var docHead = document.getElementsByTagName("head")[0];
    
                //   For browsers which discard scripts when inserting innerHTML, extract the scripts using a RegExp
                if(s.length == 0){
                    var re = /(?:<script.*(?:src=[\"\'](.*)[\"\']).*>.*</script>)|(?:<script>([\S\s]*?)</script>)/ig; // assumes HTML well formed \
    and then loop through it.
                    var match;
                    while(match = re.exec(html)){
                         var s0 = document.createElement("script");
                         if (match[1])
                            s0.src = match[1];
                         else if (match[2])
                            s0.text = match[2];
                         else
                              continue;
                         docHead.appendChild(s0);
                    }
                }else {
                  for(var i = 0; i < s.length; i++){
                     var s0 = document.createElement("script");
                     s0.type = s[i].type;
                     if (s[i].text) {
                        s0.text = s[i].text;
                     }
    
    /**********************************
    Added these lines for Safari
    ***********************************/
                    else if (s[i].innerHTML) {
                        s0.innerHTML = s[i].innerHTML;
                     }
    /**********************************/
    
                     else {
                        s0.src = s[i].src;
                     }
                     docHead.appendChild(s0);
                  }
                }
            }
            // set timeout to give DOM opportunity to catch up
            setTimeout(_parseScripts, 10);
            return this;
        },

  6. #6
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,502
    Vote Rating
    47
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    The version I have says:

    Code:
    		         var s0 = document.createElement("script");
    		         s0.type = s[i].type;
    		         if (s[i].text) {
    		         	if (YAHOO.util.Dom.isSafari)
    				    s0.innerHTML = s[i].text;
    		       		else
    			            s0.text = s[i].text;
    		         } else {
    		            s0.src = s[i].src;
    		         }
    		         docHead.appendChild(s0);
    so best make it:

    Code:
    		         var s0 = document.createElement("script");
    		         s0.type = s[i].type;
    		         if (s[i].text) {
    		         	if (YAHOO.util.Dom.isSafari)
    				    s0.innerHTML = s[i].innerHTML;
    		       		else
    			            s0.text = s[i].text;
    		         } else {
    		            s0.src = s[i].src;
    		         }
    		         docHead.appendChild(s0);

  7. #7
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    17
    jack.slocum will become famous soon enough jack.slocum will become famous soon enough

      0  

    Default


    Actually this method can't be used at all. IE7 drops some, and allows others.

    For example this:

    el.update('<sc'+'ript type="text/javascript">alert("wtf1");</s'+'cript>kjhjkhkjhkjhkj lkhkjlhjkhkjhlkj <sc'+'ript language="javascript">alert("wtf2");</s'+'cript> <sc'+'ript src="test.js"></s'+'cript>', true);

    test.js alerts "wtf 3"

    You will see wtf 2 and then wtf 3. The first one is dropped.

    If you load:
    el.update('<sc'+'ript type="text/javascript">alert("wtf1");</s'+'cript><sc'+'ript src="test.js"></s'+'cript>', true);

    Then IE will strip them both and you go to regex. It appears IE strips some and not others. Because of this, we are going to have to regex for them.

  8. #8
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    17
    jack.slocum will become famous soon enough jack.slocum will become famous soon enough

      0  

    Default


    It appears some times the src of the old RE wasn't matching either, I changed it to this nasty regex:

    Code:
    var re = /(?:<script\s(?:(?:src=[\"\'](.*?)[\"\'])?|.*?).*?>(.*?)?<\/script>)/ig;

Similar Threads

  1. Element.update() && styles
    By vtswingkid in forum Ext 1.x: Bugs
    Replies: 11
    Last Post: 21 Jun 2007, 5:29 AM
  2. Element.update() and loadScripts...
    By Animal in forum Ext 1.x: Bugs
    Replies: 11
    Last Post: 20 Apr 2007, 3:38 PM
  3. Element.update()
    By Animal in forum Ext 1.x: Bugs
    Replies: 1
    Last Post: 23 Oct 2006, 12:59 PM

Thread Participants: 3