Permalink
Browse files

Automatically replace `master` with latest commit hash in CDN URLs

Also ditched ancient browser compat in url-format.js.
  • Loading branch information...
1 parent 104a8ff commit 7c507d1095e066a94681dfcfd5af0f1969b4e945 @rgrove committed Jan 9, 2017
Showing with 100 additions and 52 deletions.
  1. +97 −50 public/js/url-formatter.js
  2. +3 −2 views/index.handlebars
@@ -1,19 +1,43 @@
/* global Clipboard, cdnDomain, devDomain */
(function (doc) {
- "use strict";
+ 'use strict';
- var GITHUB_API_URL = 'https://api.github.com';
+ // -- Constants --------------------------------------------------------------
+ const GITHUB_API_URL = 'https://api.github.com';
- var REGEX_GIST_URL = /^https?:\/\/gist\.github\.com\/.+?\/([0-9a-f]+)(?:\/([0-9a-f]+))?/i;
- var REGEX_RAW_GIST_URL = /^https?:\/\/gist\.githubusercontent\.com\/(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+\..+)$/i;
- var REGEX_RAW_REPO_URL = /^https?:\/\/raw\.github(?:usercontent)?\.com\/([^/]+\/[^/]+\/[^/]+|[0-9A-Za-z-]+\/[0-9a-f]+\/raw)\/(.+\..+)/i;
- var REGEX_REPO_URL = /^https?:\/\/github\.com\/(.[^/]+?)\/(.[^/]+?)\/(?!releases\/)(?:(?:blob|raw)\/)?(.+?\/.+)/i;
+ const REGEX_GIST_URL = /^https?:\/\/gist\.github\.com\/.+?\/([0-9a-f]+)(?:\/([0-9a-f]+))?/i;
+ const REGEX_RAW_GIST_URL = /^https?:\/\/gist\.githubusercontent\.com\/(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+\..+)$/i;
- var copyButtonDev = doc.getElementById('url-dev-copy');
- var copyButtonProd = doc.getElementById('url-prod-copy');
- var inputDev = doc.getElementById('url-dev');
- var inputProd = doc.getElementById('url-prod');
- var inputUrl = doc.getElementById('url');
+ /**
+ Matches a GitHub raw URL.
+
+ Captures:
+
+ 1. Username
+ 2. Repo
+ 3. Ref
+ 4. File path
+ **/
+ const REGEX_RAW_REPO_URL = /^https?:\/\/raw\.github(?:usercontent)?\.com\/(.+?)\/(.+?)\/(.+?)\/(.+)/i;
+
+ /**
+ Matches a GitHub repo URL.
+
+ Captures:
+
+ 1. Username
+ 2. Repo
+ 3. Ref
+ 4. File path
+ **/
+ const REGEX_REPO_URL = /^https?:\/\/github\.com\/(.+?)\/(.+?)\/(?!releases\/)(?:(?:blob|raw)\/)?(.+?)\/(.+)/i;
+
+ // -- Init -------------------------------------------------------------------
+ let copyButtonDev = doc.getElementById('url-dev-copy');
+ let copyButtonProd = doc.getElementById('url-prod-copy');
+ let inputDev = doc.getElementById('url-dev');
+ let inputProd = doc.getElementById('url-prod');
+ let inputUrl = doc.getElementById('url');
new Clipboard('.url-copy-button');
@@ -28,33 +52,7 @@
formatUrl();
- window.handleGistResponse = function (res) {
- if (!res) {
- return void setInvalid();
- }
-
- var status = res.meta && res.meta.status;
-
- if (status !== 200) {
- return void setInvalid();
- }
-
- var files = res.data && res.data.files;
- var filenames = files && Object.keys(res.data.files);
-
- if (!filenames || !filenames.length) {
- return void setInvalid();
- }
-
- var rawUrl = files[filenames[0]] && files[filenames[0]].raw_url;
-
- if (rawUrl) {
- formatRawGistUrl(rawUrl);
- } else {
- setInvalid();
- }
- };
-
+ // -- Functions --------------------------------------------------------------
function formatRawGistUrl(url) {
inputDev.value = url.replace(REGEX_RAW_GIST_URL, 'https://' + devDomain + '/$1');
inputProd.value = url.replace(REGEX_RAW_GIST_URL, 'https://' + cdnDomain + '/$1');
@@ -63,21 +61,47 @@
}
function formatRawRepoUrl(url) {
- inputDev.value = url.replace(REGEX_RAW_REPO_URL, 'https://' + devDomain + '/$1/$2');
- inputProd.value = url.replace(REGEX_RAW_REPO_URL, 'https://' + cdnDomain + '/$1/$2');
+ inputDev.value = url.replace(REGEX_RAW_REPO_URL, 'https://' + devDomain + '/$1/$2/$3/$4');
+ inputProd.value = url.replace(REGEX_RAW_REPO_URL, 'https://' + cdnDomain + '/$1/$2/$3/$4');
setValid();
}
function formatRepoUrl(url) {
- inputDev.value = url.replace(REGEX_REPO_URL, 'https://' + devDomain + '/$1/$2/$3');
- inputProd.value = url.replace(REGEX_REPO_URL, 'https://' + cdnDomain + '/$1/$2/$3');
+ inputDev.value = url.replace(REGEX_REPO_URL, 'https://' + devDomain + '/$1/$2/$3/$4');
- setValid();
+ let matches = url.match(REGEX_REPO_URL);
+
+ if (matches[3] !== 'master') {
+ inputProd.value = url.replace(REGEX_REPO_URL, 'https://' + cdnDomain + '/$1/$2/$3/$4');
+ setValid();
+ return;
+ }
+
+ let apiUrl = `${GITHUB_API_URL}/repos/${matches[1]}/${matches[2]}/commits/${matches[3]}`;
+
+ fetch(apiUrl)
+ .then(res => {
+ if (!res.ok) {
+ console.error('Failed to fetch latest repo commit from GitHub API');
+ return;
+ }
+
+ return res.json();
+ })
+
+ .then(data => {
+ let ref = data && data.sha
+ ? data.sha.slice(0, 8)
+ : matches[3];
+
+ inputProd.value = url.replace(REGEX_REPO_URL, `https://${cdnDomain}/$1/$2/${ref}/$4`);
+ setValid();
+ });
}
function formatUrl() {
- var url = inputUrl.value.trim();
+ let url = inputUrl.value.trim();
if (REGEX_RAW_REPO_URL.test(url)) {
formatRawRepoUrl(url);
@@ -99,14 +123,37 @@
}
function requestGistUrl(url) {
- var matches = url.match(REGEX_GIST_URL);
- var script = doc.createElement('script');
+ let matches = url.match(REGEX_GIST_URL);
+
+ let apiUrl = GITHUB_API_URL + '/gists/' + matches[1]
+ + (matches[2] ? '/' + matches[2] : '');
+
+ return fetch(apiUrl)
+ .then(res => {
+ if (!res.ok) {
+ setInvalid();
+ throw new Error('Failed to fetch gist URL from GitHub API');
+ }
+
+ return res.json();
+ })
+
+ .then(data => {
+ let files = data && data.files;
+ let filenames = files && Object.keys(data.files);
+
+ if (!filenames || !filenames.length) {
+ return void setInvalid();
+ }
- script.src = GITHUB_API_URL + '/gists/' + matches[1]
- + (matches[2] ? '/' + matches[2] : '')
- + '?callback=handleGistResponse';
+ let rawUrl = files[filenames[0]] && files[filenames[0]].raw_url;
- doc.head.appendChild(script);
+ if (rawUrl) {
+ formatRawGistUrl(rawUrl);
+ } else {
+ setInvalid();
+ }
+ });
}
function setInvalid() {
@@ -51,6 +51,7 @@ var cdnDomain = '{{config.cdnDomain}}';
var devDomain = '{{config.devDomain}}';
</script>
-<script src="//cdn.rawgit.com/zenorocha/document.queryCommandSupported/v1.0.0/dist/queryCommandSupported.min.js"></script>
-<script src="//cdn.rawgit.com/zenorocha/clipboard.js/v1.5.10/dist/clipboard.min.js"></script>
+<script src="https://cdn.rawgit.com/cdnjs/cdnjs/0971b44/ajax/libs/fetch/2.0.1/fetch.min.js"></script>
+<script src="https://cdn.rawgit.com/zenorocha/document.queryCommandSupported/v1.0.0/dist/queryCommandSupported.min.js"></script>
+<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/v1.5.10/dist/clipboard.min.js"></script>
<script src="{{{assetUrl "/js/url-formatter.js"}}}"></script>

0 comments on commit 7c507d1

Please sign in to comment.