diff --git a/assets/javascripts/templates/pages/offline_tmpl.js b/assets/javascripts/templates/pages/offline_tmpl.js index ad46753195..0ecac8c3ea 100644 --- a/assets/javascripts/templates/pages/offline_tmpl.js +++ b/assets/javascripts/templates/pages/offline_tmpl.js @@ -1,4 +1,4 @@ -app.templates.offlinePage = (docs) => `\ +app.templates.offlinePage = (docs, hasPersistence, isPersistent) => `\
Note: your browser may delete DevDocs's offline data if your computer is running low on disk space and you haven't used the app in a while. Load this page before going offline to make sure the data is still there. +
${exception.name}: ${exception.message}`
+ : "Bookmark this site and try again.";
+
+ return `Persistent storage was denied by your browser. ${reason}`; +}; + +var offlinePersistenceNote = function (hasPersistence, isPersistent) { + if (isPersistent) { + return ""; + } + + let html = + "
Note: your browser may delete DevDocs's offline data if your computer is running low on disk space and you haven't used the app in a while."; + + if (hasPersistence) { + html += + ' .'; + } else { + html += + " Load this page before going offline to make sure the data is still there."; + } + + return html; +}; + var canICloseTheTab = function () { if (app.ServiceWorker.isEnabled()) { return ' Yes! Even offline, you can open a new tab, go to devdocs.io, and everything will work as if you were online (provided you installed all the documentations you want to use beforehand). '; diff --git a/assets/javascripts/views/content/offline_page.js b/assets/javascripts/views/content/offline_page.js index 5fe4f21d86..10852485d9 100644 --- a/assets/javascripts/views/content/offline_page.js +++ b/assets/javascripts/views/content/offline_page.js @@ -25,12 +25,19 @@ app.views.OfflinePage = class OfflinePage extends app.View { if (statuses === false) { this.html(this.tmpl("offlineError", app.db.reason, app.db.error)); } else { - let html = ""; - for (var doc of app.docs.all()) { - html += this.renderDoc(doc, statuses[doc.slug]); - } - this.html(this.tmpl("offlinePage", html)); - this.refreshLinks(); + this.checkPersistence((hasPersistence, isPersistent) => { + if (!this.activated) { + return; + } + let html = ""; + for (var doc of app.docs.all()) { + html += this.renderDoc(doc, statuses[doc.slug]); + } + this.html( + this.tmpl("offlinePage", html, hasPersistence, isPersistent) + ); + this.refreshLinks(); + }); } }); } @@ -93,6 +100,8 @@ app.views.OfflinePage = class OfflinePage extends app.View { for (el of Array.from(this.findAll(`[data-action='${action}']`))) { $.click(el); } + } else if (el.hasAttribute("data-enable-persistence")) { + this.requestPersistence(); } } @@ -142,4 +151,37 @@ app.views.OfflinePage = class OfflinePage extends app.View { app.settings.set("manualUpdate", !event.target.checked); } } + + checkPersistence(callback) { + if (navigator.storage && navigator.storage.persisted) { + navigator.storage + .persisted() + .then((persisted) => callback(true, persisted)) + .catch(() => callback(false, false)); + } else { + callback(false, false); + } + } + + requestPersistence() { + navigator.storage + .persist() + .then((success) => this.onPersistenceRequestCompleted(success)) + .catch((exception) => + this.onPersistenceRequestCompleted(false, exception) + ); + } + + onPersistenceRequestCompleted(success, exception) { + if (!this.activated) { + return; + } + const note = this.find("#_offline-persistence-note"); + if (!note) { + return; + } + // Granting persistence retires the note, which is what a fresh render of + // the page would produce; the disappearing button is the confirmation. + note.innerHTML = success ? "" : this.tmpl("persistenceError", exception); + } }; diff --git a/assets/stylesheets/components/_content.scss b/assets/stylesheets/components/_content.scss index b25956e6d2..e4dd033f37 100644 --- a/assets/stylesheets/components/_content.scss +++ b/assets/stylesheets/components/_content.scss @@ -385,6 +385,7 @@ ._bold { font-weight: var(--boldFontWeight); } ._note { @extend %note; } ._note-green { @extend %note-green; } +._note-red { @extend %note-red; } ._label { @extend %label; } ._code { @extend %code; } ._highlight, ._highlight > td { background: var(--highlightBackground) !important; }