diff --git a/site/_static/scripts/browser-support.js b/site/_static/scripts/browser-support.js
index d966785..9012e49 100644
--- a/site/_static/scripts/browser-support.js
+++ b/site/_static/scripts/browser-support.js
@@ -1,4 +1,4 @@
-function test_webp_feature(feature, callback) {
+function webpFeatureSupport(feature, callback) {
// Test webp feature.
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, isSupported)' will be passed back the detection result (in an asynchronous way!).
@@ -20,7 +20,7 @@ function test_webp_feature(feature, callback) {
img.src = "data:image/webp;base64," + kTestImages[feature];
}
-function create_announcement(innerHtml) {
+function createAnnouncement(innerHtml) {
// Return an announcement element.
// Format was reverse-engineered from pydata-sphinx-theme v0.13.3 generated index.html with
// html_theme_options["announcement"] set in conf.py.
@@ -34,69 +34,158 @@ function create_announcement(innerHtml) {
return ann;
}
-var webpSupport = null;
+var webpSupported = null;
-function test_webp_support() {
+function webpSupport() {
// General test for webp support over features. Adds an announcement if any feature not
// supported.
- webpSupport = true;
+ webpSupported = true;
var webp_callback = function (feature, isSupported) {
- if (!isSupported && webpSupport != false) {
- webpSupport = false;
- document.body.insertBefore(create_announcement(), document.body.firstChild);
+ if (!isSupported && webpSupported != false) {
+ webpSupported = false;
+ document.body.insertBefore(createAnnouncement(), document.body.firstChild);
}
}
var features = ["lossy", "lossless", "alpha"];
features.forEach(function (feature, index) {
- test_webp_feature(feature, webp_callback);
+ webpFeatureSupport(feature, webp_callback);
});
}
+function disableSearch() {
+ var searchElems = document.getElementsByClassName("search-button");
+ for (var i = 0; i < searchElems.length; i++) {
+ searchElems[i].style.backgroundColor = "red";
+ // searchElems[i].style.display = "none";
+ }
+ console.log("Search disabled");
+}
+
+function disableTheme() {
+ var themeElems = document.getElementsByClassName("theme-switch-button");
+ for (var i = 0; i < themeElems.length; i++) {
+ themeElems[i].style.backgroundColor = "red";
+ // searchElems[i].style.display = "none";
+ }
+ console.log("Themes disabled");
+}
+
+function createScript(scriptFile, scriptLoaded) {
+ // adapted from https://humanwhocodes.com/blog/2009/06/23/loading-javascript-without-blocking/
+ var script = document.createElement("script")
+ script.type = "text/javascript";
+ if (script.readyState) { //IE
+ script.onreadystatechange = function() {
+ if (script.readyState == "loaded" || script.readyState == "complete") {
+ script.onreadystatechange = null;
+ scriptLoaded();
+ }
+ };
+ } else { //Others
+ script.addEventListener("load", scriptLoaded);
+ }
+ script.src = scriptFile;
+ document.body.appendChild(script);
+ return script;
+}
+
+function searchSupport() {
+
+ // dictionary of scripts that need to successfully load for search to be supported
+ var searchDict = {
+ "_static/searchtools.js": {
+ scriptElement: null,
+ loaded: false,
+ },
+ // TODO: include these last 2, or assume sphinx has included them?
+ // "_static/doctools.js": {
+ // scriptElement: null,
+ // loaded: false,
+ // },
+ // "_static/sphinx_highlight.js": {
+ // scriptElement: null,
+ // loaded: false,
+ // },
+ };
-function test_search_support() {
- // Disable search button(s) if search not supported.
- // Support is tested with a basic check for existence of searchtools.js, doctools.js &
- // sphinx_highlight.js modules.
- try {
- // try create Search and dependent modules
- var checkList = [Search, Documentation, SphinxHighlight, _ready];
-
- // var msg = "Search ok.";
- // var searchElems = document.getElementsByClassName("search-button");
- // for (var i = 0; i < searchElems.length; i++) {
- // searchElems[i].style.backgroundColor = "green";
- // }
- // document.body.insertBefore(create_announcement(msg), document.body.firstChild);
- }
- catch (ex) {
- // hide search buttons
- var searchElems = document.getElementsByClassName("search-button");
- for (var i = 0; i < searchElems.length; i++) {
- // searchElems[i].style.backgroundColor = "red";
- searchElems[i].style.display = "none";
+ var scriptLoaded = function(event) {
+ // Script onload handler. Tests for existence of (selected) search objects once all
+ // scripts loaded, then disables search button on failure.
+
+ var allLoaded = true;
+ console.log("Script loaded:" + event.srcElement.src);
+ for (var scriptFile in searchDict) {
+ if (event.srcElement.src.indexOf(scriptFile) >= 0) {
+ searchDict[scriptFile].loaded = true;
+ }
+ allLoaded = allLoaded && searchDict[scriptFile].loaded;
}
+ if (allLoaded) {
+ // Test search and dependent objects created successfully
+ try {
+ var testList = [Search, Documentation, SphinxHighlight, _ready];
+ console.log("Search supported");
+ }
+ catch (ex) {
+ disableSearch();
+ console.log("Search not supported: " + String(ex));
+ }
+ // remove test script elements
+ for (var scriptFile in searchDict) {
+ // IE does not support element.remove();
+ searchDict[scriptFile].scriptElement.parentNode.removeChild(searchDict[scriptFile].scriptElement);
+ console.log("Script removed:" + searchDict[scriptFile].scriptElement.src);
+ }
+ }
+ }
+
+ // create and append test script elements
+ for (var scriptFile in searchDict) {
+ var script = createScript(scriptFile, scriptLoaded);
+ searchDict[scriptFile].scriptElement = script;
+ }
+}
- // msg = "Search not ok.";
- // document.body.insertBefore(create_announcement(msg), document.body.firstChild);
- console.log("Search not supported: " + String(ex));
- // throw(ex);
+function themeSupport() {
+ var themeFile = "_static/scripts/pydata-sphinx-theme.js";
+ var supported = true;
+
+ var winError = function (event) {
+ console.log("Got error: " + String(event.message) + ", " + String(event.filename));
+ // console.log("File: " + String(event.filename));
+ // console.log(event);
+ if (event.filename.indexOf(themeFile) >= 0) {
+ disableSearch();
+ disableTheme();
+ supported = false;
+ console.log("Themes not supported.")
+ }
+ }
+ var scriptLoaded = function(event) {
+ // Script onload handler that removes script.
+ console.log("Script loaded:" + event.srcElement.src);
+ event.srcElement.parentNode.removeChild(event.srcElement);
+ console.log("Script removed:" + event.srcElement.src);
+ window.removeEventListener("error", winError);
+ console.log("window.onerror removed");
+ if (supported) console.log("Themes supported.")
}
+
+ window.addEventListener("error", winError);
+ createScript(themeFile, scriptLoaded);
}
-// Override splitQuery in searchtools.js which specifies a unicode regex not supported by all
-// browsers
-// var splitQuery = function(query) {
-// // change "/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu" to ascii only expression
-// return query.split(/[^A-Za-z0-9_]+/g).filter(function(term) { return term; });
-// }
+function browserSupport() {
+ webpSupport();
+ searchSupport();
+ themeSupport();
+}
if (document.readyState !== "loading") {
- test_webp_support();
- test_search_support();
+ browserSupport();
} else {
- document.addEventListener("DOMContentLoaded", test_webp_support);
- document.addEventListener("DOMContentLoaded", test_search_support);
+ document.addEventListener("DOMContentLoaded", browserSupport);
}
diff --git a/site/conf.py b/site/conf.py
index b4e19ca..ef8eb68 100644
--- a/site/conf.py
+++ b/site/conf.py
@@ -40,7 +40,7 @@
html_css_files = ['styles/leftfield.css']
# searchtools.js is a theme script that is always incuded, but is specified here to make sure it is
# listed in the html before browser-support.js, which uses it.
-html_js_files = ['searchtools.js', 'scripts/browser-support.js']
+html_js_files = ['scripts/browser-support.js']
html_context = {'default_mode': 'auto'} # use the system/browser light/dark theme setting
# html_favicon = '_static/favicons/favicon.svg'
html_sourcelink_suffix = ''