update online minifier
authoralexlamsl <alexlamsl@gmail.com>
Thu, 7 Apr 2016 17:13:16 +0000 (01:13 +0800)
committeralexlamsl <alexlamsl@gmail.com>
Thu, 7 Apr 2016 17:24:38 +0000 (01:24 +0800)
ease maintenance by using a single source for listing all available options

README.md
assets/master.css
assets/master.js
index.html

index a486ad7..ccf50c1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Pe
 | `caseSensitive`                | Treat attributes in case sensitive manner (useful for custom HTML tags) | `false` |
 | `collapseBooleanAttributes`    | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
 | `collapseInlineTagWhitespace`  | Don't leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=true` | `false` |
-| `collapseWhitespace`           | [Collapse white space that contributes to text nodes in a document tree.](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
+| `collapseWhitespace`           | [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
 | `conservativeCollapse`         | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
 | `customAttrAssign`             | Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[ ]` |
 | `customAttrCollapse`           | Regex that specifies custom attribute to strip newlines from (e.g. `/ng\-class/`) | |
index dcccfc2..875753e 100644 (file)
@@ -18,7 +18,6 @@ button { font-weight: bold; width: 100px; }
 #options input { margin-right: 0.5em; }
 #stats { margin-bottom: 2em; overflow: hidden; margin-top: 0; }
 #todo { font-family: monospace; margin-bottom: 2em; }
-#warning { background: #fee; padding: 0.25em; display: inline-block; margin-top: 0; font-size: 0.85em; }
 #lint-report { font-family: monospace; }
 #report { margin-bottom: 5em; }
 #report ul { margin: 0.5em; padding-left: 1em; list-style: none; }
@@ -33,7 +32,7 @@ button { font-weight: bold; width: 100px; }
 .controls a:focus, .controls a:hover { text-decoration: none; }
 
 .deprecated-element, .deprecated-attribute { color: red; }
-.presentational-element, .presentational-attribute, .inaccessible-attribute { color: #FF8C00; }
+.presentational-element, .presentational-attribute, .inaccessible-attribute, .repeating-attribute { color: #FF8C00; }
 
 .unsafe { color: #f33; }
 
index 50afd4e..22f5064 100644 (file)
     return (str + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
   }
 
+  function forEachOption(fn) {
+    [].forEach.call(byId('options').getElementsByTagName('input'), fn);
+  }
+
   function getOptions() {
-    return {
-      removeComments:                 byId('remove-comments').checked,
-      collapseWhitespace:             byId('collapse-whitespace').checked,
-      conservativeCollapse:           byId('conservative-collapse').checked,
-      collapseBooleanAttributes:      byId('collapse-boolean-attributes').checked,
-      removeTagWhitespace:            byId('remove-tag-whitespace').checked,
-      removeAttributeQuotes:          byId('remove-attribute-quotes').checked,
-      removeRedundantAttributes:      byId('remove-redundant-attributes').checked,
-      useShortDoctype:                byId('use-short-doctype').checked,
-      removeEmptyAttributes:          byId('remove-empty-attributes').checked,
-      removeEmptyElements:            byId('remove-empty-elements').checked,
-      removeOptionalTags:             byId('remove-optional-tags').checked,
-      removeScriptTypeAttributes:     byId('remove-script-type-attributes').checked,
-      removeStyleLinkTypeAttributes:  byId('remove-style-link-type-attributes').checked,
-      caseSensitive:                  byId('case-sensitive').checked,
-      keepClosingSlash:               byId('keep-closing-slash').checked,
-      minifyJS:                       byId('minify-js').checked,
-      processScripts:                 byId('minify-js-templates').checked ? byId('minify-js-templates-type').value : false,
-      minifyCSS:                      byId('minify-css').checked,
-      minifyURLs:                     byId('minify-urls').checked ? { site: byId('minify-urls-siteurl').value } : false,
-      lint:                           byId('use-htmllint').checked ? new HTMLLint() : null,
-      maxLineLength:                  parseInt(byId('max-line-length').value, 10)
-    };
+    var options = {};
+    forEachOption(function(element) {
+      var key = element.id;
+      var value;
+      if (element.type === 'checkbox') {
+        value = element.checked;
+      }
+      else {
+        value = element.value.replace(/^\s+|\s+$/, '');
+        if (!value) {
+          return;
+        }
+      }
+      switch (key) {
+        case 'lint':
+          if (!value) {
+            return;
+          }
+          value = new HTMLLint();
+          break;
+        case 'maxLineLength':
+          value = parseInt(value);
+          break;
+        case 'minifyURLs':
+          value = { site: value };
+          break;
+        case 'processScripts':
+          value = value.split(/\s*,\s*/);
+      }
+      options[key] = value;
+    });
+    return options;
   }
 
   function commify(str) {
@@ -45,7 +58,7 @@
       .split('').reverse().join('');
   }
 
-  function minifyTextarea() {
+  byId('minify-btn').onclick = function() {
     try {
       var options = getOptions(),
           lint = options.lint,
       byId('output').value = '';
       byId('stats').innerHTML = '<span class="failure">' + escapeHTML(err) + '</span>';
     }
-  }
-
-  byId('max-line-length').oninput = function() { minifyTextarea(); };
-  byId('minify-btn').onclick = function() { minifyTextarea(); };
-
-  function setCheckedAttrOnCheckboxes(attrValue) {
-    var checkboxes = byId('options').getElementsByTagName('input');
-    for (var i = checkboxes.length; i--;) {
-      checkboxes[i].checked = attrValue;
-    }
-  }
+  };
 
   byId('select-all').onclick = function() {
-    setCheckedAttrOnCheckboxes(true);
+    forEachOption(function(element) {
+      if (element.type === 'checkbox') {
+        element.checked = true;
+      }
+    });
     return false;
   };
 
   byId('select-none').onclick = function() {
-    setCheckedAttrOnCheckboxes(false);
+    forEachOption(function(element) {
+      if (element.type === 'checkbox') {
+        element.checked = false;
+      }
+      else {
+        element.value = '';
+      }
+    });
     return false;
   };
 
-  byId('select-safe').onclick = function() {
-    setCheckedAttrOnCheckboxes(true);
-    var inputEls = byId('options').getElementsByTagName('input');
-    inputEls[10].checked = false;
-    inputEls[11].checked = false;
-    inputEls[13].checked = false;
-    inputEls[18].checked = false;
+  var defaultOptions = getOptions();
+  byId('select-defaults').onclick = function() {
+    for (var key in defaultOptions) {
+      var element = byId(key);
+      element[element.type === 'checkbox' ? 'checked' : 'value'] = defaultOptions[key];
+    }
     return false;
   };
-
 })();
 /* eslint-disable */
 var _gaq = _gaq || [];
@@ -116,3 +128,14 @@ _gaq.push(['_trackPageview']);
   ga.src = (document.location.protocol === 'https:' ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
   document.getElementsByTagName('head')[0].appendChild(ga);
 })();
+
+(function(i){
+  var s = document.getElementById(i);
+  var f = document.createElement('iframe');
+  f.src = (document.location.protocol === 'https:' ? 'https' : 'http') + '://api.flattr.com/button/view/?uid=kangax&button=compact&url=' + encodeURIComponent(document.URL);
+  f.title = 'Flattr';
+  f.height = 20;
+  f.width = 110;
+  f.style.borderWidth = 0;
+  s.parentNode.insertBefore(f, s);
+})('wrapper');
index cb6e637..e612a33 100644 (file)
     <link rel="stylesheet" href="assets/master.css">
   </head>
   <body>
-    <div>
-      <div id="outer-wrapper">
-        <script id='fbyg2uy'>(function(i){var f,s=document.getElementById(i);f=document.createElement('iframe');f.src='//api.flattr.com/button/view/?uid=kangax&button=compact&url='+encodeURIComponent(document.URL);f.title='Flattr';f.height=20;f.width=110;f.style.borderWidth=0;s.parentNode.insertBefore(f,s);})('fbyg2uy');</script>
-        <div id="wrapper">
-          <h1>HTML Minifier <span>(v1.4.0)</span></h1>
-          <p id="warning">
-            Minifier is <strong>in beta</strong> and could be rough around the edges.
-            However, there's <a href="tests">an extensive test suite</a>.
-          </p>
-          <textarea rows="8" cols="40" id="input"></textarea>
-          <div class="minify-button">
-            <button type="button" id="minify-btn">Minify</button>
-          </div>
-          <textarea rows="8" cols="40" id="output" readonly></textarea>
-
-          <p id="stats"></p>
-          <div id="lint-report">
-            LINT REPORT:
-            <div id="report"></div>
-          </div>
+    <div id="outer-wrapper">
+      <div id="wrapper">
+        <h1>HTML Minifier <span>(v1.4.0)</span></h1>
+        <textarea rows="8" cols="40" id="input"></textarea>
+        <div class="minify-button">
+          <button type="button" id="minify-btn">Minify</button>
         </div>
-        <div id="options">
-          <ul>
-            <li>
-              <input type="checkbox" id="remove-comments" checked>
-              <label for="remove-comments">Remove comments
-                <br>
-                <span class="quiet short">
-                  Conditional comments are left intact, but their inner (insignificant) whitespace is removed.
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="collapse-whitespace" checked>
-              <label for="collapse-whitespace">Collapse whitespace</label>
-            </li>
-            <li>
-              <input type="checkbox" id="conservative-collapse">
-              <label for="conservative-collapse">Conservative whitespace collapse</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-tag-whitespace" checked>
-              <label for="remove-tag-whitespace">Remove space between attributes</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-optional-tags" checked>
-              <label for="remove-optional-tags">
-                Remove optional tags
-                <br>
-                <span class="quiet short">
-                  Currently, only:
-                  <code>&lt;/html></code>,
-                  <code>&lt;/head></code>,
-                  <code>&lt;/body></code>,
-                  <code>&lt;/option></code>
-                  <code>&lt;/thead></code>,
-                  <code>&lt;/tbody></code>,
-                  <code>&lt;/tfoot></code>,
-                  <code>&lt;/p></code>,
-                  and
-                  <code>&lt;/tr></code>
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-empty-elements">
-              <label for="remove-empty-elements" class="unsafe">
-                Remove empty elements
-                <br>
-                <span class="quiet short">
-                  All except <code>textarea</code>
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-script-type-attributes">
-              <label for="remove-script-type-attributes">
-                Remove <code>type="text/javascript"</code> from <code>script</code>'s
-                <br>
-                <span class="quiet short">
-                  Values other than "text/javascript" (e.g. "text/vbscript") are left intact.
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="remove-style-link-type-attributes">
-              <label for="remove-style-link-type-attributes">
-                Remove <code>type="text/css"</code> from <code>style</code>'s and <code>link</code>'s
-                <br>
-                <span class="quiet short">
-                  Values other than "text/css" (e.g. "text/plain" or "application/atom+xml") are left intact.
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="case-sensitive">
-              <label for="case-sensitive">
-                Case-sensitive attributes
-                <br>
-                <span class="quiet short">
-                  Useful when minifying SVG
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="keep-closing-slash">
-              <label for="keep-closing-slash">
-                Keep closing slash
-                <br>
-                <span class="quiet short">
-                  Useful when minifying SVG
-                </span>
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="minify-js" checked>
-              <label for="minify-js">
-                Minify JS
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="minify-js-templates">
-              <label for="minify-js-templates">
-                Minify JS Templates
-                <br>
-                <span class="quiet short">
-                  Minify HTML served inside script tag with a custom type attribute like "text/x-handlebars-template"
-                </span>
-              </label>
-            </li>
-            <li>
-              <label for="minify-js-templates-type" class="sub-option">
-                Template type
-              </label>
-              <input type="input" id="minify-js-templates-type">
-            </li>
-            <li>
-              <input type="checkbox" id="minify-css" checked>
-              <label for="minify-css">
-                Minify CSS
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="minify-urls">
-              <label for="minify-urls">
-                Minify URLs
-                <br>
-                <span class="quiet short">
-                  Convert absolute URLs to relative
-                </span>
-              </label>
-            </li>
-            <li>
-              <label for="minify-urls-siteurl" class="sub-option">
-                Site URL
-              </label>
-              <input type="input" id="minify-urls-siteurl">
-            </li>
-            <li>
-              <input type="checkbox" id="use-htmllint" checked>
-              <label for="use-htmllint">
-                Validate input through HTML lint
-              </label>
-            </li>
-            <li>
-              <label for="max-line-length" class="sub-option">
-                Max line length
-              </label>
-              <input type="number" id="max-line-length" value="0" min="0" max="10000">
-            </li>
-          </ul>
-          <div class="controls">
-            <span>Select:</span>
-            <a href="#" id="select-all">All</a>,
-            <a href="#" id="select-none">None</a>,
-            <a href="#" id="select-safe">Safe</a>
-          </div>
+        <textarea rows="8" cols="40" id="output" readonly></textarea>
+
+        <p id="stats"></p>
+        <div id="lint-report">
+          LINT REPORT:
+          <div id="report"></div>
         </div>
       </div>
-
-      <div class="footer">
-        <p class="quiet">
-          HTMLMinifier is made by <a href="http://perfectionkills.com/">kangax</a>,
-          using tweaked version of HTML parser by <a href="http://ejohn.org/">John Resig</a>
-          (which, in its turn, is based on work of <a href="http://erik.eae.net/">Erik Arvidsson</a>).
-          Source and bugtracker are <a href="https://github.com/kangax/html-minifier">hosted on GitHub</a>.
-        </p>
+      <div id="options">
+        <ul>
+          <li>
+            <input type="checkbox" id="caseSensitive">
+            <label for="caseSensitive">
+              Case-sensitive
+            </label>
+            <span class="quiet short">
+              Treat attributes in case sensitive manner (useful for custom HTML tags)
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="collapseBooleanAttributes" checked>
+            <label for="collapseBooleanAttributes">
+              Collapse boolean attributes
+            </label>
+            <span class="quiet short">
+              Omit attribute values from boolean attributes
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="collapseInlineTagWhitespace" class="unsafe">
+            <label for="collapseInlineTagWhitespace">
+              Collapse inline tag whitespace
+            </label>
+            <span class="quiet short">
+              Don't leave any spaces between <code>display:inline;</code> elements when collapsing.
+              Must be used in conjunction with <code>collapseWhitespace=true</code>
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="collapseWhitespace" checked>
+            <label for="collapseWhitespace">
+              Collapse whitespace
+            </label>
+            <span class="quiet short">
+              Collapse white space that contributes to text nodes in a document tree
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="conservativeCollapse">
+            <label for="conservativeCollapse">
+              Conservative collapse
+            </label>
+            <span class="quiet short">
+              Always collapse to 1 space (never remove it entirely).
+              Must be used in conjunction with <code>collapseWhitespace=true</code>
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="html5" checked>
+            <label for="html5">
+              HTML5
+            </label>
+            <span class="quiet short">
+              Parse input according to HTML5 specifications
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="includeAutoGeneratedTags">
+            <label for="includeAutoGeneratedTags">
+              Include auto-generated tags
+            </label>
+            <span class="quiet short">
+              Insert tags generated by HTML parser
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="keepClosingSlash">
+            <label for="keepClosingSlash">
+              Keep closing slash
+            </label>
+            <span class="quiet short">
+              Keep the trailing slash on singleton elements
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="lint" checked>
+            <label for="lint">
+              Toggle linting
+            </label>
+          </li>
+          <li>
+            <label for="maxLineLength">
+              Max. line length
+            </label>
+            <input type="text" id="maxLineLength">
+            <span class="quiet short">
+              Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="minifyCSS" checked>
+            <label for="minifyCSS">
+              Minify CSS
+            </label>
+            <span class="quiet short">
+              Minify CSS in style elements and style attributes (uses <code>clean-css</code>)
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="minifyJS" checked>
+            <label for="minifyJS">
+              Minify JavaScript
+            </label>
+            <span class="quiet short">
+              Minify JavaScript in script elements and event attributes (uses <code>UglifyJS</code>)
+            </span>
+          </li>
+          <li>
+            <label for="minifyURLs">
+              Minify URLs
+            </label>
+            <input type="text" id="minifyURLs">
+            <span class="quiet short">
+              Minify URLs in various attributes (uses <code>relateurl</code>)
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="preserveLineBreaks">
+            <label for="preserveLineBreaks">
+              Preserve line-breaks
+            </label>
+            <span class="quiet short">
+              Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break.
+              Must be used in conjunction with <code>collapseWhitespace=true</code>
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="preventAttributesEscaping" class="unsafe">
+            <label for="preventAttributesEscaping">
+              Prevent attributes escaping
+            </label>
+            <span class="quiet short">
+              Prevents the escaping of the values of attributes
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="processConditionalComments" checked>
+            <label for="processConditionalComments">
+              Process conditional comments
+            </label>
+            <span class="quiet short">
+              Process contents of conditional comments through minifier
+            </span>
+          </li>
+          <li>
+            <label for="processScripts">
+              Process scripts
+            </label>
+            <input type="text" id="processScripts" value="text/html">
+            <span class="quiet short">
+              Comma-delimited string corresponding to types of script elements to process through minifier (e.g. <code>text/ng-template, text/x-handlebars-template</code>)
+            </span>
+          </li>
+          <li>
+            <label for="quoteCharacter">
+              Quote character
+            </label>
+            <input type="text" id="quoteCharacter">
+            <span class="quiet short">
+              Type of quote to use for attribute values (<code>'</code> or <code>"</code>)
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeAttributeQuotes" checked>
+            <label for="removeAttributeQuotes">
+              Remove attribute quotes
+            </label>
+            <span class="quiet short">
+              Remove quotes around attributes when possible
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeComments" checked>
+            <label for="removeComments">
+              Remove comments
+            </label>
+            <span class="quiet short">
+              Strip HTML comments
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeEmptyAttributes" checked>
+            <label for="removeEmptyAttributes">
+              Remove empty attributes
+            </label>
+            <span class="quiet short">
+              Remove all attributes with whitespace-only values
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeEmptyElements" class="unsafe">
+            <label for="removeEmptyElements">
+              Remove empty elements
+            </label>
+            <span class="quiet short">
+              Remove all elements with empty contents
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeOptionalTags" checked>
+            <label for="removeOptionalTags">
+              Remove optional tags
+            </label>
+          </li>
+          <li>
+            <input type="checkbox" id="removeRedundantAttributes" checked>
+            <label for="removeRedundantAttributes">
+              Remove redundant attributes
+            </label>
+            <span class="quiet short">
+              Remove attributes when value matches default.
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeScriptTypeAttributes" checked>
+            <label for="removeScriptTypeAttributes">
+              Remove script type attributes
+            </label>
+            <span class="quiet short">
+              Remove <code>type="text/javascript"</code> from <code>script</code> tags.
+              Other <code>type</code> attribute values are left intact
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeStyleLinkTypeAttributes" checked>
+            <label for="removeStyleLinkTypeAttributes">
+              Remove style link type attributes
+            </label>
+            <span class="quiet short">
+              Remove <code>type="text/css"</code> from <code>style</code> and <code>link</code> tags.
+              Other <code>type</code> attribute values are left intact
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="removeTagWhitespace" class="unsafe" checked>
+            <label for="removeTagWhitespace">
+              Remove tag whitespace
+            </label>
+            <span class="quiet short">
+              Remove space between attributes whenever possible.
+              <i>Note that this will result in invalid HTML!</i>
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="sortAttributes" class="unsafe" checked>
+            <label for="sortAttributes">
+              Sort attributes
+            </label>
+            <span class="quiet short">
+              Sort attributes by frequency
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="sortClassName" class="unsafe" checked>
+            <label for="sortClassName">
+              Sort class name
+            </label>
+            <span class="quiet short">
+              Sort style classes by frequency
+            </span>
+          </li>
+          <li>
+            <input type="checkbox" id="useShortDoctype" checked>
+            <label for="useShortDoctype">
+              Use short <code>doctype</code>
+            </label>
+            <span class="quiet short">
+              Replaces the <code>doctype</code> with the short (HTML5) <code>doctype</code>
+            </span>
+          </li>
+        </ul>
+        <div class="controls">
+          <span>Select:</span>
+          <a href="#" id="select-all">All</a>,
+          <a href="#" id="select-none">None</a>,
+          <a href="#" id="select-defaults">Reset</a>
+        </div>
       </div>
+    </div>
 
+    <div class="footer">
+      <p class="quiet">
+        HTMLMinifier is made by <a href="http://perfectionkills.com/">kangax</a>,
+        using tweaked version of HTML parser by <a href="http://ejohn.org/">John Resig</a>
+        (which, in its turn, is based on work of <a href="http://erik.eae.net/">Erik Arvidsson</a>).
+        Source and bugtracker are <a href="https://github.com/kangax/html-minifier">hosted on GitHub</a>.
+      </p>
     </div>
+
     <script src="dist/htmlminifier.min.js"></script>
     <script src="assets/master.js"></script>
   </body>