Add ability to remove optional tags (</body> and </html> for now);
authorJuriy Zaytsev <kangax@gmail.com>
Fri, 12 Feb 2010 05:54:00 +0000 (00:54 -0500)
committerJuriy Zaytsev <kangax@gmail.com>
Fri, 12 Feb 2010 05:54:00 +0000 (00:54 -0500)
Bump to version 0.3;
Reorganize main page slightly.

index.html
master.css
master.js
src/htmlminifier.js
tests/index.html

index 94f14f6..c25676b 100644 (file)
   <body>
     <div>
       <div id="wrapper">
-        <h1>HTML Minifier <span style="font-size:0.6em">(ver. 0.2)</span></h1>
+        <h1>HTML Minifier <span style="font-size:0.6em">(ver. 0.3)</span></h1>
         <textarea rows="8" cols="40" id="input"></textarea>
-        <div id="options">
-          <ul>
-            <li>
-              <input type="checkbox" id="remove-comments" checked>
-              <label for="remove-comments">Remove comments (</label>
-              <input type="checkbox" id="remove-comments-from-cdata" checked>
-              <label for="remove-comments-from-cdata">also from scripts and styles )</label>
-              <span class="quiet short" style="margin-left:1.5em">
-                Conditional comments are left intact.
+        <p style="width:65%">
+          <button type="button" id="convert-btn">Convert</button>
+        </p>
+        <textarea rows="8" cols="40" id="output" readonly></textarea>
+      </div>
+      <div id="options">
+        <ul>
+          <li>
+            <input type="checkbox" id="remove-comments" checked>
+            <label for="remove-comments">Remove comments (</label>
+            <input type="checkbox" id="remove-comments-from-cdata" checked>
+            <label for="remove-comments-from-cdata">also from scripts and styles )</label>
+            <span class="quiet short" style="margin-left:1.5em">
+              Conditional comments are left intact.
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-cdata-sections-from-cdata" checked>
+            <label for="remove-cdata-sections-from-cdata">Remove CDATA sections from scripts and styles</label>
+          </li>
+          <li>
+            <input type="checkbox" id="collapse-whitespace" checked>
+            <label for="collapse-whitespace">Collapse whitespace</label>
+          </li>
+          <li>
+            <input type="checkbox" id="collapse-boolean-attributes" checked>
+            <label for="collapse-boolean-attributes">
+              Collapse boolean attributes
+              <br>
+              <span class="quiet short">
+                (e.g. <code>&lt;... disabled="disabled"&gt; &rarr; &lt;... disabled&gt;</code>)
+              </span>
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-attribute-quotes" checked>
+            <label for="remove-attribute-quotes">
+              Remove attribute quotes
+              <br>
+              <span class="quiet">
+                (e.g. <code>&lt;p class="foo"&gt; &rarr; &lt;p class=foo&gt;</code>)
+              </span>
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-redundant-attributes" checked>
+            <label for="remove-redundant-attributes">Remove redundant attributes/values</label>
+            <div class="quiet">
+              <code>&lt;script language="Javascript" ...&gt;</code><br>
+              <code>&lt;form method="get" ...&gt;</code><br>
+              <code>&lt;input type="text" ...&gt;</code><br>
+              <code>&lt;script src="..." charset="..."&gt;</code><br>
+              <code>&lt;a id="..." name="..."&gt;</code><br>
+              <code>&lt;... onclick="javascript:..." ...&gt;</code>
+            </div>
+          </li>
+          <li>
+            <input type="checkbox" id="use-short-doctype" checked>
+            <label for="use-short-doctype" title="i.e. <!DOCTYPE html>">
+              Use short doctype
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-empty-attributes" checked>
+            <label for="remove-empty-attributes">
+              Remove empty (or blank) attributes
+              <br>
+              <span class="quiet short">
+                Valid attributes are: class, id, style, title, lang, dir, event attributes
               </span>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-cdata-sections-from-cdata" checked>
-              <label for="remove-cdata-sections-from-cdata">Remove CDATA sections from scripts and styles</label>
-            </li>
-            <li>
-              <input type="checkbox" id="collapse-whitespace" checked>
-              <label for="collapse-whitespace">Collapse whitespace</label>
-            </li>
-            <li>
-              <input type="checkbox" id="collapse-boolean-attributes" checked>
-              <label for="collapse-boolean-attributes">
-                Collapse boolean attributes
-                <br>
-                <span class="quiet short">
-                  (e.g. <code>&lt;... disabled="disabled"&gt; &rarr; &lt;... disabled&gt;</code>)
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-attribute-quotes" checked>
-              <label for="remove-attribute-quotes">
-                Remove attribute quotes
-                <br>
-                <span class="quiet">
-                  (e.g. <code>&lt;p class="foo"&gt; &rarr; &lt;p class=foo&gt;</code>)
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-redundant-attributes" checked>
-              <label for="remove-redundant-attributes">Remove redundant attributes/values</label>
-              <div class="quiet">
-                <code>&lt;script language="Javascript" ...&gt;</code><br>
-                <code>&lt;form method="get" ...&gt;</code><br>
-                <code>&lt;input type="text" ...&gt;</code><br>
-                <code>&lt;script src="..." charset="..."&gt;</code><br>
-                <code>&lt;a id="..." name="..."&gt;</code><br>
-                <code>&lt;... onclick="javascript:..." ...&gt;</code>
-              </div>
-            </li>
-            <li>
-              <input type="checkbox" id="use-short-doctype" checked>
-              <label for="use-short-doctype" title="i.e. <!DOCTYPE html>">
-                Use short doctype
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-empty-attributes" checked>
-              <label for="remove-empty-attributes">
-                Remove empty (or blank) attributes
-                <br>
-                <span class="quiet short">
-                  Valid attributes are: class, id, style, title, lang, dir, event attributes
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-empty-elements">
-              <label for="remove-empty-elements">
-                Remove empty elements
-                <br>
-                <span class="quiet short">
-                  All except <code>textarea</code>
-                </span>
-              </label>
-            </li>
-          </ul>
-        </div>
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-optional-tags" checked>
+            <label for="remove-optional-tags">
+              Remove optional tags
+              <br>
+              <span class="quiet short">
+                Currently, only <code>&lt;/html></code> and <code>&lt;/body></code>
+              </span>
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="remove-empty-elements">
+            <label for="remove-empty-elements">
+              Remove empty elements
+              <br>
+              <span class="quiet short">
+                All except <code>textarea</code>
+              </span>
+            </label>
+          </li>
+        </ul>
       </div>
-      <p><button type="button" id="convert-btn">Convert</button></p>
-      <textarea rows="8" cols="40" id="output" readonly></textarea>
+      
       <p id="stats"></p>
       <p id="warning">
         Minifier is <strong>very draft</strong> and is <strong>not yet thoroughly tested</strong>. Use at your own risk. 
index 32767f8..09f79f8 100644 (file)
@@ -3,17 +3,17 @@ textarea { height: 30em; }
 h1 { margin-top: 0.5em; font-size: 1.25em; }
 button { font-weight: bold; width: 100px; }
 
-#wrapper { overflow: hidden; min-width: 900px; }
-#input { width: 65%; }
-#output { width: 100%; height: 18em; margin-bottom: 2em; }
-#options { float: right; width: 33%; padding-left: 1em; }
+#wrapper { overflow: hidden; width: 65%; float: left; }
+#input { width: 99%; height: 18em; }
+#output { width: 99%; height: 18em; margin-bottom: 2em; }
+#options { float: right; width: 33%; padding-left: 1em; margin-top: 2.5em; min-height: 50em; }
 #options ul { list-style: none; padding: 0.5em; overflow: hidden; background: #ffe; margin-top: 0; }
 #options ul li { float: left; clear: both; padding-bottom: 0.5em; }
 #options ul li div { margin-left: 1.75em; }
 #options label, #options input { float: left; }
 #options input { margin-right: 0.5em; }
 #stats { margin-bottom: 2em; }
-#todo { font-family: monospace; }
+#todo { font-family: monospace; margin-bottom: 2em; }
 #warning { background: #fcc; padding: 0.25em; display: inline-block; }
 
 .success { color: green; }
index b4a2dbb..e020834 100644 (file)
--- a/master.js
+++ b/master.js
@@ -19,7 +19,8 @@
       removeRedundantAttributes:    byId('remove-redundant-attributes').checked,
       useShortDoctype:              byId('use-short-doctype').checked,
       removeEmptyAttributes:        byId('remove-empty-attributes').checked,
-      removeEmptyElements:          byId('remove-empty-elements').checked
+      removeEmptyElements:          byId('remove-empty-elements').checked,
+      removeOptionalTags:           byId('remove-optional-tags').checked,
     };
   }
   
index 8817099..ce57761 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * HTML Minifier v0.2
+ * HTML Minifier v0.3
  * http://kangax.github.com/html-minifier/
  *
  * Copyright (c) 2010 Juriy "kangax" Zaytsev
     return tag !== 'textarea';
   }
   
+  function isOptionalTag(tag) {
+    return (/^(?:body|html)$/).test(tag);
+  }
+  
   function canCollapseWhitespace(tag) {
     return !(/^(?:script|style|pre|textarea)$/.test(tag));
   }
       },
       end: function( tag ) {
         var isElementEmpty = currentChars === '' && tag === currentTag;
-        if (options.removeEmptyElements && isElementEmpty && canRemoveElement(tag)) {
+        if ((options.removeEmptyElements && isElementEmpty && canRemoveElement(tag)) ||
+            (options.removeOptionalTags && isOptionalTag(tag))) {
           // noop
         }
         else {
index 91e0b90..668ed14 100644 (file)
           input = '<option name="blah" selected="selected">moo</option>';
           equals(minify(input, { collapseBooleanAttributes: true }), '<option name="blah" selected>moo</option>');
         });
+        
+        test('removing optional tags', function(){
+          input = '<html><body><head><title>hello</title></head><p>foo<span>bar</span></p></body></html>';
+          output = '<html><body><head><title>hello</title></head><p>foo<span>bar</span></p>';
+          equals(minify(input, { removeOptionalTags: true }), output);
+          equals(minify(input), input);
+        });
+        
       })(this);
     </script>
   </body>