Gracefully handle lack of HLJS
Throw an exception when gr-app.html cannot be used to locate the
JS path root. Handle the case where HLJS is independently loaded.
Change-Id: Idd669907abff0bfc213ed8531a75380b1ad1d34a
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
index 75b00e8..bfd8e90 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
@@ -26,7 +26,6 @@
// NOTE: intended singleton.
value: {
- loaded: false,
loading: false,
callbacks: [],
},
@@ -34,9 +33,9 @@
},
get() {
- return new Promise(resolve => {
+ return new Promise((resolve, reject) => {
// If the lib is totally loaded, resolve immediately.
- if (this._state.loaded) {
+ if (this._getHighlightLib()) {
resolve(this._getHighlightLib());
return;
}
@@ -44,7 +43,7 @@
// If the library is not currently being loaded, then start loading it.
if (!this._state.loading) {
this._state.loading = true;
- this._loadHLJS().then(this._onLibLoaded.bind(this));
+ this._loadHLJS().then(this._onLibLoaded.bind(this)).catch(reject);
}
this._state.callbacks.push(resolve);
@@ -53,7 +52,6 @@
_onLibLoaded() {
const lib = this._getHighlightLib();
- this._state.loaded = true;
this._state.loading = false;
for (const cb of this._state.callbacks) {
cb(lib);
@@ -73,17 +71,28 @@
_getLibRoot() {
if (this._cachedLibRoot) { return this._cachedLibRoot; }
- return this._cachedLibRoot = document.head
- .querySelector('link[rel=import][href$="gr-app.html"]')
+ const appLink = document.head
+ .querySelector('link[rel=import][href$="gr-app.html"]');
+
+ if (!appLink) { return null; }
+
+ return this._cachedLibRoot = appLink
.href
.match(LIB_ROOT_PATTERN)[1];
},
_cachedLibRoot: null,
_loadHLJS() {
- return new Promise(resolve => {
+ return new Promise((resolve, reject) => {
const script = document.createElement('script');
- script.src = this._getLibRoot() + HLJS_PATH;
+ const src = this._getHLJSUrl();
+
+ if (!src) {
+ reject(new Error('Unable to load blank HLJS url.'));
+ return;
+ }
+
+ script.src = src;
script.onload = function() {
this._configureHighlightLib();
resolve();
@@ -91,5 +100,11 @@
Polymer.dom(document.head).appendChild(script);
});
},
+
+ _getHLJSUrl() {
+ const root = this._getLibRoot();
+ if (!root) { return null; }
+ return root + HLJS_PATH;
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
index b46910a..6ddde46 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
@@ -45,7 +45,6 @@
);
// Assert preconditions:
- assert.isFalse(element._state.loaded);
assert.isFalse(element._state.loading);
});
@@ -57,7 +56,6 @@
// Because the element state is a singleton, clean it up.
element._state.loading = false;
- element._state.loaded = false;
element._state.callbacks = [];
});
@@ -68,7 +66,6 @@
// It should now be in the loading state.
assert.isTrue(loadStub.called);
assert.isTrue(element._state.loading);
- assert.isFalse(element._state.loaded);
assert.isFalse(firstCallHandler.called);
const secondCallHandler = sinon.stub();
@@ -76,7 +73,6 @@
// No change in state.
assert.isTrue(element._state.loading);
- assert.isFalse(element._state.loaded);
assert.isFalse(firstCallHandler.called);
assert.isFalse(secondCallHandler.called);
@@ -85,11 +81,55 @@
flush(() => {
// The state should be loaded and both handlers called.
assert.isFalse(element._state.loading);
- assert.isTrue(element._state.loaded);
assert.isTrue(firstCallHandler.called);
assert.isTrue(secondCallHandler.called);
done();
});
});
+
+ suite('preloaded', () => {
+ setup(() => {
+ window.hljs = 'test-object';
+ });
+
+ teardown(() => {
+ delete window.hljs;
+ });
+
+ test('returns hljs', done => {
+ const firstCallHandler = sinon.stub();
+ element.get().then(firstCallHandler);
+ flush(() => {
+ assert.isTrue(firstCallHandler.called);
+ assert.isTrue(firstCallHandler.calledWith('test-object'));
+ done();
+ });
+ });
+ });
+
+ suite('_getHLJSUrl', () => {
+ suite('checking _getLibRoot', () => {
+ let libRootStub;
+ let root;
+
+ setup(() => {
+ libRootStub = sinon.stub(element, '_getLibRoot', () => root);
+ });
+
+ teardown(() => {
+ libRootStub.restore();
+ });
+
+ test('with no root', () => {
+ assert.isNull(element._getHLJSUrl());
+ });
+
+ test('with root', () => {
+ root = 'test-root.com/';
+ assert.equal(element._getHLJSUrl(),
+ 'test-root.com/bower_components/highlightjs/highlight.min.js');
+ });
+ });
+ });
});
</script>