improve handling of optional table section tags (#914)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 18 Apr 2018 09:22:18 +0000 (17:22 +0800)
committerGitHub <noreply@github.com>
Wed, 18 Apr 2018 09:22:18 +0000 (17:22 +0800)
src/htmlparser.js
tests/minifier.js

index dc1eb53..78e8928 100644 (file)
@@ -267,12 +267,36 @@ function HTMLParser(html, handler) {
     }
   }
 
+  function closeIfFound(tagName) {
+    if (findTag(tagName) >= 0) {
+      parseEndTag('', tagName);
+      return true;
+    }
+  }
+
   function handleStartTag(match) {
     var tagName = match.tagName;
     var unarySlash = match.unarySlash;
 
-    if (handler.html5 && lastTag === 'p' && nonPhrasing(tagName)) {
-      parseEndTag('', lastTag);
+    if (handler.html5) {
+      if (lastTag === 'p' && nonPhrasing(tagName)) {
+        parseEndTag('', lastTag);
+      }
+      else if (tagName === 'tbody') {
+        closeIfFound('thead');
+      }
+      else if (tagName === 'tfoot') {
+        if (!closeIfFound('tbody')) {
+          closeIfFound('thead');
+        }
+      }
+      if (tagName === 'col' && findTag('colgroup') < 0) {
+        lastTag = 'colgroup';
+        stack.push({ tag: lastTag, attrs: [] });
+        if (handler.start) {
+          handler.start(lastTag, [], false, '');
+        }
+      }
     }
 
     if (!handler.html5 && !inline(tagName)) {
@@ -353,17 +377,23 @@ function HTMLParser(html, handler) {
     }
   }
 
+  function findTag(tagName) {
+    var pos;
+    var needle = tagName.toLowerCase();
+    for (pos = stack.length - 1; pos >= 0; pos--) {
+      if (stack[pos].tag.toLowerCase() === needle) {
+        break;
+      }
+    }
+    return pos;
+  }
+
   function parseEndTag(tag, tagName) {
     var pos;
 
     // Find the closest opened tag of the same type
     if (tagName) {
-      var needle = tagName.toLowerCase();
-      for (pos = stack.length - 1; pos >= 0; pos--) {
-        if (stack[pos].tag.toLowerCase() === needle) {
-          break;
-        }
-      }
+      pos = findTag(tagName);
     }
     // If no tag name is provided, clean shop
     else {
index e973c22..233d201 100644 (file)
@@ -1574,6 +1574,7 @@ QUnit.test('removing optional tags in tables', function(assert) {
              '<tfoot><tr><th>baz<th>qux<td>boo' +
            '</table>';
   assert.equal(minify(input, { collapseWhitespace: true, removeOptionalTags: true }), output);
+  assert.equal(minify(output, { collapseWhitespace: true, removeOptionalTags: true }), output);
 
   input = '<table>' +
             '<caption>foo</caption>' +
@@ -1592,6 +1593,7 @@ QUnit.test('removing optional tags in tables', function(assert) {
              '<tr><th>bar<td>baz<th>qux' +
            '</table>';
   assert.equal(minify(input, { removeOptionalTags: true }), output);
+  assert.equal(minify(output, { removeOptionalTags: true }), output);
 
   output = '<table>' +
              '<caption>foo' +