diff --git a/static/resources_list.txt b/static/resources_list.txt
index b9ecb268e..755fc5942 100644
--- a/static/resources_list.txt
+++ b/static/resources_list.txt
@@ -17,6 +17,7 @@ skin/fonts/Poppins.ttf
skin/fonts/Roboto.ttf
skin/search_results.css
skin/blank.html
+skin/polyfills.js
skin/viewer.js
skin/i18n.js
skin/languages.js
diff --git a/static/skin/polyfills.js b/static/skin/polyfills.js
new file mode 100644
index 000000000..96e6a8e13
--- /dev/null
+++ b/static/skin/polyfills.js
@@ -0,0 +1,21 @@
+// A few browsers do not support the use of String.prototype.replaceAll method.
+// Hence we define it once we verify that it isn't supported. For documentation
+// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
+if (!String.prototype.replaceAll) {
+ String.prototype.replaceAll = function (pattern, replacement) {
+ // verify parameter: It must either be a string or a RegExp with a global flag.
+ if (typeof pattern[Symbol.replace] === 'function') {
+ // the pattern is a RegExp check for the presence of g flag.
+ if (pattern.global) {
+ return this.replace(pattern, replacement);
+ } else {
+ throw new TypeError('Global flag for regular expressions')
+ }
+ }
+ // the pattern is not a RegExp, hence it must be a string.
+ if (typeof pattern !== 'string') {
+ throw new TypeError('pattern must either be a string or a RegExp with a global (g) flag.')
+ }
+ return this.replace(new RegExp(pattern, 'g'), replacement);
+ }
+}
diff --git a/static/templates/index.html b/static/templates/index.html
index 46be2d7f9..3c8c931be 100644
--- a/static/templates/index.html
+++ b/static/templates/index.html
@@ -31,6 +31,7 @@
+
diff --git a/static/viewer.html b/static/viewer.html
index 1b3e14043..d0f10562a 100644
--- a/static/viewer.html
+++ b/static/viewer.html
@@ -11,6 +11,7 @@
+
diff --git a/test/server.cpp b/test/server.cpp
index fb9d577ea..1841f132b 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -146,6 +146,8 @@ const ResourceCollection resources200Uncompressible{
{ STATIC_CONTENT, "/ROOT%23%3F/skin/hash.png?cacheid=f836e872" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/magnet.png" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/magnet.png?cacheid=73b6bddf" },
+ { DYNAMIC_CONTENT, "/ROOT%23%3F/skin/polyfills.js" },
+ { STATIC_CONTENT, "/ROOT%23%3F/skin/polyfills.js?cacheid=a0e0343d" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/search-icon.svg" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/search-icon.svg?cacheid=b10ae7ed" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/search_results.css" },
@@ -285,6 +287,7 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/kiwix.css?cacheid=2158fad9"
+
@@ -318,6 +321,7 @@ R"EXPECTEDRESULT(
+