Skip to content
This repository
Browse code

Ensure `Element#update` works with string content that includes a LIN…

…K tag in Internet Explorer. [#264 state:resolved] (Tobias H. Michaelsen, Andrew Dupont)
  • Loading branch information...
commit 7c26a1e7cf891d74e2d2c32b238979e44e3cee19 1 parent e65e921
Andrew Dupont authored November 02, 2010
2  CHANGELOG
... ...
@@ -1,3 +1,5 @@
  1
+* Ensure `Element#update` works with string content that includes a LINK tag in Internet Explorer. [#264 state:resolved] (Tobias H. Michaelsen, Andrew Dupont)
  2
+
1 3
 * Treat a 304 HTTP status as a successful response. [#331 state:resolved] (Kenneth Kin Lum, Andrew Dupont)
2 4
 
3 5
 * Handle sparse arrays properly in `Array#_each` to match behavior with browsers' built-in `Array#forEach` (and ES5). [#790 state:resolved] (Andriy Tyurnikov, Yaffle, Andrew Dupont)
45  src/dom/dom.js
@@ -568,6 +568,21 @@ Element.Methods = {
568 568
         return true;
569 569
       }
570 570
     })();
  571
+    
  572
+    var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
  573
+      try {
  574
+        var el = document.createElement('div');
  575
+        el.innerHTML = "<link>";
  576
+        var isBuggy = (el.childNodes.length === 0);
  577
+        el = null;
  578
+        return isBuggy;
  579
+      } catch(e) {
  580
+        return true;
  581
+      }
  582
+    })();
  583
+    
  584
+    var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
  585
+     TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;    
571 586
 
572 587
     var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
573 588
       var s = document.createElement("script"),
@@ -582,6 +597,7 @@ Element.Methods = {
582 597
       s = null;
583 598
       return isBuggy;
584 599
     })();
  600
+    
585 601
 
586 602
     function update(element, content) {
587 603
       element = $(element);
@@ -610,7 +626,7 @@ Element.Methods = {
610 626
         return element;
611 627
       }
612 628
 
613  
-      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
  629
+      if (ANY_INNERHTML_BUGGY) {
614 630
         if (tagName in Element._insertionTranslations.tags) {
615 631
           while (element.firstChild) {
616 632
             element.removeChild(element.firstChild);
@@ -619,6 +635,16 @@ Element.Methods = {
619 635
             .each(function(node) {
620 636
               element.appendChild(node)
621 637
             });
  638
+        } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
  639
+          // IE barfs when inserting a string that beings with a LINK
  640
+          // element. The workaround is to add any content to the beginning
  641
+          // of the string; we'll be inserting a text node (see
  642
+          // Element._getContentFromAnonymousElement below).
  643
+          while (element.firstChild) {
  644
+            element.removeChild(element.firstChild);
  645
+          }
  646
+          var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
  647
+          nodes.each(function(node) { element.appendChild(node) });          
622 648
         }
623 649
         else {
624 650
           element.innerHTML = content.stripScripts();
@@ -2966,11 +2992,22 @@ Element._returnOffset = function(l, t) {
2966 2992
   return result;
2967 2993
 };
2968 2994
 
2969  
-Element._getContentFromAnonymousElement = function(tagName, html) {
  2995
+Element._getContentFromAnonymousElement = function(tagName, html, force) {
2970 2996
   var div = new Element('div'), 
2971 2997
       t = Element._insertionTranslations.tags[tagName];
2972  
-  if (t) {
2973  
-    div.innerHTML = t[0] + html + t[1];
  2998
+  
  2999
+  var workaround = false;
  3000
+  if (t) workaround = true;
  3001
+  else if (force) {
  3002
+    workaround = true;
  3003
+    t = ['', '', 0];
  3004
+  }
  3005
+      
  3006
+  if (workaround) {
  3007
+    // Adding a text node to the beginning of the string (then removing it)
  3008
+    // fixes an issue in Internet Explorer. See Element#update above.
  3009
+    div.innerHTML = '&nbsp;' + t[0] + html + t[1];
  3010
+    div.removeChild(div.firstChild);
2974 3011
     for (var i = t[2]; i--; ) {
2975 3012
       div = div.firstChild;
2976 3013
     }
17  test/unit/dom_test.js
@@ -362,6 +362,23 @@ new Test.Unit.Runner({
362 362
     select.update('<option value="3">option 3</option><option selected="selected">option 4</option>');
363 363
     this.assertEqual('option 4', select.getValue());
364 364
   },
  365
+  
  366
+  testElementUpdateWithLinkTag: function() {
  367
+    var div = new Element('div');
  368
+    div.update('<link rel="stylesheet" />');
  369
+    this.assertEqual(1, div.childNodes.length);
  370
+    var link = div.down('link');
  371
+    this.assert(link);
  372
+    this.assert(link.rel === 'stylesheet');
  373
+    
  374
+    div.update('<p><link rel="stylesheet"></p>')
  375
+    this.assertEqual(1, div.childNodes.length);
  376
+    this.assertEqual(1, div.firstChild.childNodes.length);
  377
+
  378
+    var link = div.down('link');
  379
+    this.assert(link);
  380
+    this.assert(link.rel === 'stylesheet');
  381
+  },
365 382
 
366 383
   testElementUpdateWithDOMNode: function() {
367 384
     $('testdiv').update(new Element('div').insert('bla'));

0 notes on commit 7c26a1e

Please sign in to comment.
Something went wrong with that request. Please try again.