JSFiddle - React, Tailwind, and code Playground

by Renoir Boulanger

HTML

<script src="https://crypto-js.googlecode.com/files/2.0.0-crypto-sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<div class="container">
 <section class="row">
   <h1>How to refer to a feature in BrowserCompat</h1>
   <p>This is a follow up <a href="https://groups.google.com/d/msg/mozilla.dev.mdn/SBiFR6oQVcQ/fkxgknJpGQAJ">on the idea shared in this thread</a> to improve the slug scheme for <abbr title="Browser Compatibility">BC</abbr>.</p>
 </section>
 <section class="row">
    <div id="outcome">
      <p>Each row of the following table illustrate changes made from an MDN URL. The <em>Slugified</em> column shows the result of transformations. <button id="show-rules">Show transformation rules</button></p>
      <ul>
      </ul>
    </div>
    <table class="table table-condensed">
      <thead>
        <tr>
          <th>#</th>
          <th title="Is a duplicate?">Dup?</th>
          <th>URL</th>
          <th>Slugified</th>
        </tr>
      </thead>
      <tbody id="uris">
      </tbody>
    </table>
 </section>
</div>

JavaScript

/**
 * Libraries
 *  - https://code.google.com/p/crypto-js/#SHA-1
 **/

var slugification = [],
    maxIter = 0,
    processed = new Set(),
    erroneous = [];

// RegExes to modify the input
slugification.push([ /^\/web/, '']);
slugification.push([/%[0-9a-z]{2}/ig, '']);
slugification.push([/_{2,}/g, '_']);
slugification.push([/\.\.\./g, '_']);

/**
 * Mute (or rewrite) words that are present in MDN
 * URLs that we don't need as a way to represent structured
 * compatibility data.
 * 
 * For example, "tutorials" in an MDN URL is about categorizing
 * learning content, we wouldn't have an User-Agent supporting
 * a "Tutorial" feature.
 */
slugification.push(['accessibility', 'a11y']);
slugification.push(['javascript', 'js']);
slugification.push(['xmlhttprequest', 'xhr']);
slugification.push(['css_object_model', 'cssom']);

slugification.push(['/security/do_not_track_field_guide', '/http/dnt']);
slugification.push(['/security/transport_layer_security', '/http/tls']);
slugification.push(['/security/csp', '/http/csp']);

slugification.push(['/http/headers/content-security-policy', '/http/csp/headers']);
slugification.push(['/http/csp/csp_policy_directives', '/http/csp/directives']);
slugification.push(['/http/csp/default_csp_restrictions', '/http/csp/restrictions']);
slugification.push(['/http/csp/using_csp_violation_reports', '/http/csp/reports']);

slugification.push(['/http/access_control_cors', '/http/cors/access-control']);
slugification.push(['/html/cors_enabled_image', '/http/cors/img']);
slugification.push(['/html/cors_settings_attributes', '/http/cors/attributes']);
slugification.push(['/security/same-origin_policy', '/http/cors/origin']);

slugification.push(['/security/public_key_pinning', '/http/sts/public-key-pins']);
slugification.push(['/security/http_strict_transport_security', '/http/sts']);

slugification.push(['/html/controlling_spell_checking_in_html_forms',...