diff --git a/7.html b/7.html
index 3ff47c4f22..7b44830447 100644
--- a/7.html
+++ b/7.html
@@ -6,7 +6,6 @@
- pretty-format.js
- 7.js
third_party_js:
-- https://unpkg.com/babel-standalone@7.0.0-alpha.15/babel.js
- https://unpkg.com/babel-polyfill@7.0.0-alpha.15/dist/polyfill.min.js
- https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js
- https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/base64-string.min.js
@@ -38,7 +37,7 @@
- Babel
+ Babel is loading...
diff --git a/_config.yml b/_config.yml
index ea224c403f..79e239ff14 100644
--- a/_config.yml
+++ b/_config.yml
@@ -19,6 +19,9 @@ exclude:
- Rakefile
- package.json
+include:
+ - _redirects
+
# Build settings
highlighter: rouge
markdown: kramdown
diff --git a/_redirects b/_redirects
new file mode 100644
index 0000000000..4f684a9f73
--- /dev/null
+++ b/_redirects
@@ -0,0 +1,8 @@
+---
+layout: null
+---
+
+# REPL builds, to preview pull requests
+/repl/build/:build /7/ 200
+# Previous versions of the REPL
+/repl/version/:version /7/ 200
diff --git a/scripts/7.js b/scripts/7.js
index ca34d3568f..69b9797bee 100644
--- a/scripts/7.js
+++ b/scripts/7.js
@@ -1,4 +1,4 @@
-(function(babel, $, _, ace, LZString, window) {
+(function($, _, ace, LZString, window) {
'use strict';
var UPDATE_DELAY = 500;
@@ -26,6 +26,8 @@
});
});
+ var loadingScripts = {};
+
/*
* Utils for working with the browser's URI (e.g. the query params)
*/
@@ -293,6 +295,7 @@
var state = this.storage.get('b7ReplState') || {};
_.assign(state, UriUtils.parseQuery());
this.options = _.assign(new Options(), state);
+ loadBabel(this.options);
this.input = new Editor('.babel-repl-input .ace_editor').editor;
this.input.setValue(UriUtils.decode(state.code || ''));
@@ -307,8 +310,6 @@
this.$consoleReporter = $('.babel-repl-console-output');
this.$toolBar = $('.babel-repl-toolbar');
this.$textareaWrapper = $('.dropdown-menu-container');
-
- document.getElementById('babel-repl-version').innerHTML = babel.version;
}
REPL.prototype.clearOutput = function () {
@@ -337,10 +338,16 @@
var code = this.getSource();
this.clearOutput();
+ if (!hasBabelLoaded()) {
+ this.setOutput('// Babel is loading, please wait...');
+ return;
+ }
+
var presets = options.presets.split(',');
try {
- transformed = babel.transform(code, {
+ document.getElementById('babel-repl-version').innerHTML = Babel.version;
+ transformed = Babel.transform(code, {
presets: presets.filter(Boolean),
filename: 'repl',
babelrc: false,
@@ -495,7 +502,110 @@
};
}
+ /**
+ * Checks if a script (such as Babel-standalone or Babili-standalone) has been
+ * loaded. If not, kicks off a load (if it hasn't already started) and returns
+ * false. Returns true if the script is ready to use.
+ */
+ function lazyLoadScript(name, checkFn, url) {
+ if (checkFn()) {
+ return true;
+ }
+ if (loadingScripts[name]) {
+ return false;
+ }
+
+ if (url) {
+ // Babili-standalone is exported as a UMD script, and thus hits the CommonJS
+ // error ("is not supported in the browser..."), temporarily disable it
+ // while loading.
+ enableCommonJSError = false;
+
+ var script = document.createElement('script');
+ script.async = true;
+ script.src = url;
+ script.onload = function() {
+ enableCommonJSError = true;
+ onSourceChange();
+ };
+ script.onerror = function() {
+ alert('Could not load ' + name + ' :(');
+ };
+ document.head.appendChild(script);
+ loadingScripts[name] = true;
+ }
+ return false;
+ }
+
+ function hasBabelLoaded() {
+ return lazyLoadScript('Babel', () => !!window.Babel);
+ }
+
+ function loadBabel(options) {
+ function doLoad(url) {
+ lazyLoadScript('Babel', () => !!window.Babel, url);
+ }
+
+ // See if a CircleCI build number was passed in the path
+ // Prod (with URL rewriting): /repl/build/12345/
+ // Dev: /repl/#?build=12345
+ var build = options.build;
+ var buildFromPath = window.location.pathname.match(/\/build\/([0-9]+)\/?$/);
+ if (buildFromPath) {
+ build = buildFromPath[1];
+ }
+ if (build) {
+ loadBuildArtifacts(options.circleci_repo, build, function(url) {
+ doLoad(url);
+ });
+ return;
+ }
+
+ // See if a released version of Babel was passed
+ // Prod (with URL rewriting): /repl/version/1.2.3/
+ // Dev: /repl/#?version=1.2.3
+ var version = options.version;
+ var versionFromPath = window.location.pathname.match(/\/version\/(.+)\/?$/);
+ if (versionFromPath) {
+ version = versionFromPath[1];
+ }
+
+ // No specific version passed, so just download the latest release.
+ if (!version) {
+ version = 'next'; // This should be changed to "latest" when Babel 7 is stable
+ }
+
+ doLoad('https://unpkg.com/babel-standalone@' + version + '/babel.js');
+ }
+
+ function loadBuildArtifacts(repo, build, cb) {
+ // Loading a build from CircleCI (eg. for a pull request). We need to
+ // first call CircleCI's API to get the URL to the artifact.
+ var buildURL = 'https://circleci.com/api/v1.1/project/github/{repo}/{build}/artifacts'
+ .replace('{repo}', repo || 'babel/babel')
+ .replace('{build}', build);
+ var xhr = new XMLHttpRequest();
+ xhr.open('get', buildURL, true);
+ xhr.onload = function() {
+ var response = JSON.parse(xhr.responseText);
+ if (response.message) {
+ alert('Could not load Babel build #' + build + ': ' + response.message);
+ return;
+ }
+ var artifacts = response.filter(x => /babel-standalone\/babel.js$/.test(x.path));
+ if (!artifacts || artifacts.length === 0) {
+ alert('Could not find valid babel-standalone artifact in build #' + build);
+ return;
+ }
+ cb(artifacts[0].url);
+ };
+ xhr.onerror = function() {
+ alert('Could not load Babel build #' + build + ' :(');
+ }
+ xhr.send();
+ }
+
initResizable('.babel-repl-resize');
onPresetChange();
onToolbarChange();
-}(Babel, $, _, ace, LZString, window));
+}($, _, ace, LZString, window));