[devdocsgjs/main: 649/1867] Make service worker opt-in in development




commit 576f32dae1ef2d987eb4c3f1d810a249729ff20e
Author: Jasper van Merle <jaspervmerle gmail com>
Date:   Wed Jul 10 19:48:36 2019 +0200

    Make service worker opt-in in development

 Dockerfile                                         |  1 +
 Dockerfile-alpine                                  |  1 +
 assets/javascripts/app/config.coffee.erb           |  1 +
 assets/javascripts/app/serviceworker.coffee        |  2 +-
 assets/javascripts/app/settings.coffee             |  6 ------
 .../templates/pages/offline_tmpl.coffee            |  7 ++++++-
 .../templates/pages/root_tmpl.coffee.erb           |  2 +-
 .../templates/pages/settings_tmpl.coffee           |  4 ----
 .../javascripts/views/content/settings_page.coffee |  7 -------
 docs/adding-docs.md                                |  2 --
 lib/app.rb                                         | 24 ++++++++++++++++++++--
 views/service-worker.js.erb                        | 10 +++------
 12 files changed, 36 insertions(+), 31 deletions(-)
---
diff --git a/Dockerfile b/Dockerfile
index 77443edd..420bd195 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,7 @@
 FROM ruby:2.6.0
 
 ENV LANG=C.UTF-8
+ENV ENABLE_SERVICE_WORKER=true
 
 WORKDIR /devdocs
 
diff --git a/Dockerfile-alpine b/Dockerfile-alpine
index 5bd25afe..a5d993f7 100644
--- a/Dockerfile-alpine
+++ b/Dockerfile-alpine
@@ -1,6 +1,7 @@
 FROM ruby:2.6.0-alpine
 
 ENV LANG=C.UTF-8
+ENV ENABLE_SERVICE_WORKER=true
 
 WORKDIR /devdocs
 
diff --git a/assets/javascripts/app/config.coffee.erb b/assets/javascripts/app/config.coffee.erb
index 765da0b5..9b28b5a5 100644
--- a/assets/javascripts/app/config.coffee.erb
+++ b/assets/javascripts/app/config.coffee.erb
@@ -14,3 +14,4 @@ app.config =
   release: <%= Time.now.utc.httpdate.to_json %>
   mathml_stylesheet: '<%= App.cdn_origin %>/mathml.css'
   service_worker_path: '/service-worker.js'
+  service_worker_enabled: <%= App.environment == 'production' || !ENV["ENABLE_SERVICE_WORKER"].nil? %>
diff --git a/assets/javascripts/app/serviceworker.coffee b/assets/javascripts/app/serviceworker.coffee
index 7a58f304..188a7e42 100644
--- a/assets/javascripts/app/serviceworker.coffee
+++ b/assets/javascripts/app/serviceworker.coffee
@@ -2,7 +2,7 @@ class app.ServiceWorker
   $.extend @prototype, Events
 
   @isEnabled: ->
-    !!navigator.serviceWorker
+    !!navigator.serviceWorker and app.config.service_worker_enabled
 
   constructor: ->
     @registration = null
diff --git a/assets/javascripts/app/settings.coffee b/assets/javascripts/app/settings.coffee
index 58875f42..0540bfb7 100644
--- a/assets/javascripts/app/settings.coffee
+++ b/assets/javascripts/app/settings.coffee
@@ -5,7 +5,6 @@ class app.Settings
     'manualUpdate'
     'fastScroll'
     'arrowScroll'
-    'bypassCache'
     'docs'
     'dark'
     'layout'
@@ -92,11 +91,6 @@ class app.Settings
     @set 'size', value
     return
 
-  setBypassCache: (value) ->
-    @set 'bypassCache', value
-    app.serviceWorker?.updateInBackground()
-    return
-
   dump: ->
     @store.dump()
 
diff --git a/assets/javascripts/templates/pages/offline_tmpl.coffee 
b/assets/javascripts/templates/pages/offline_tmpl.coffee
index 52705605..52f64839 100644
--- a/assets/javascripts/templates/pages/offline_tmpl.coffee
+++ b/assets/javascripts/templates/pages/offline_tmpl.coffee
@@ -44,7 +44,12 @@ canICloseTheTab = ->
   if app.ServiceWorker.isEnabled()
     """ Yes! Even offline, you can open a new tab, go to <a href="//devdocs.io">devdocs.io</a>, and 
everything will work as if you were online (provided you installed all the documentations you want to use 
beforehand). """
   else
-    """ No. Service Workers aren't available in your browser (or are disabled), so loading <a 
href="//devdocs.io">devdocs.io</a> offline won't work.<br>
+    reason = "aren't available in your browser (or are disabled)"
+
+    if app.config.env != 'production'
+      reason = "are disabled in your development instance of DevDocs (enable them by setting the 
ENABLE_SERVICE_WORKERS environment variable)"
+
+    """ No. Service Workers #{reason}, so loading <a href="//devdocs.io">devdocs.io</a> offline won't 
work.<br>
         The current tab will continue to function even when you go offline (provided you installed all the 
documentations beforehand). """
 
 app.templates.offlineDoc = (doc, status) ->
diff --git a/assets/javascripts/templates/pages/root_tmpl.coffee.erb 
b/assets/javascripts/templates/pages/root_tmpl.coffee.erb
index 7adce7fd..a94a99a0 100644
--- a/assets/javascripts/templates/pages/root_tmpl.coffee.erb
+++ b/assets/javascripts/templates/pages/root_tmpl.coffee.erb
@@ -8,7 +8,7 @@ app.templates.intro = """
     <p>Thanks for downloading DevDocs. Here are a few things you should know:
     <ol class="_intro-list">
       <li>Your local version of DevDocs won't self-update. Unless you're modifying the code,
-          I&nbsp;recommend using the hosted version at <a href="https://devdocs.io";>devdocs.io</a>.
+          we&nbsp;recommend using the hosted version at <a href="https://devdocs.io";>devdocs.io</a>.
       <li>Run <code>thor docs:list</code> to see all available documentations.
       <li>Run <code>thor docs:download &lt;name&gt;</code> to download documentations.
       <li>Run <code>thor docs:download --installed</code> to update all downloaded documentations.
diff --git a/assets/javascripts/templates/pages/settings_tmpl.coffee 
b/assets/javascripts/templates/pages/settings_tmpl.coffee
index 4a2066f1..1d439edb 100644
--- a/assets/javascripts/templates/pages/settings_tmpl.coffee
+++ b/assets/javascripts/templates/pages/settings_tmpl.coffee
@@ -15,10 +15,6 @@ app.templates.settingsPage = (settings) -> """
         <input type="checkbox" form="settings" name="layout" value="_sidebar-hidden"#{if 
settings['_sidebar-hidden'] then ' checked' else ''}>Automatically hide and show the sidebar
         <small>Tip: drag the edge of the sidebar to resize it.</small>
       </label>
-      <label class="_settings-label">
-        <input type="checkbox" form="settings" name="bypassCache" value="1"#{if settings.bypassCache then ' 
checked' else ''}>Bypass Service Worker cache
-        <small>When this is checked, the Service Worker will always fetch the latest version of requested 
files. Useful when making changes to the DevDocs source code.</small>
-      </label>
     </div>
   </div>
 
diff --git a/assets/javascripts/views/content/settings_page.coffee 
b/assets/javascripts/views/content/settings_page.coffee
index 96904a13..af2e9a9d 100644
--- a/assets/javascripts/views/content/settings_page.coffee
+++ b/assets/javascripts/views/content/settings_page.coffee
@@ -14,7 +14,6 @@ class app.views.SettingsPage extends app.View
     settings.dark = app.settings.get('dark')
     settings.smoothScroll = !app.settings.get('fastScroll')
     settings.arrowScroll = app.settings.get('arrowScroll')
-    settings.bypassCache = app.settings.get('bypassCache')
     settings[layout] = app.settings.hasLayout(layout) for layout in app.settings.LAYOUTS
     settings
 
@@ -33,10 +32,6 @@ class app.views.SettingsPage extends app.View
     app.settings.set('fastScroll', !enable)
     return
 
-  toggleBypassCache: (enable) ->
-    app.settings.setBypassCache(!!enable)
-    return
-
   toggle: (name, enable) ->
     app.settings.set(name, enable)
     return
@@ -80,8 +75,6 @@ class app.views.SettingsPage extends app.View
         @toggleSmoothScroll input.checked
       when 'import'
         @import input.files[0], input
-      when 'bypassCache'
-        @toggleBypassCache input.checked
       else
         @toggle input.name, input.checked
     return
diff --git a/docs/adding-docs.md b/docs/adding-docs.md
index 4b34b045..dfc96cb1 100644
--- a/docs/adding-docs.md
+++ b/docs/adding-docs.md
@@ -2,8 +2,6 @@ Adding a documentation may look like a daunting task but once you get the hang o
 
 **Note:** please read the [contributing guidelines](../.github/CONTRIBUTING.md) before submitting a new 
documentation.
 
-**Note:** when editing any of the files in the `assets` directory or the `public` directory, you'll have to 
bypass the service worker cache. To do this, go to the Preferences page on your local instance of DevDocs, 
check "Bypass Service Worker cache" and refresh the page.
-
 1. Create a subclass of `Docs::UrlScraper` or `Docs::FileScraper` in the `lib/docs/scrapers/` directory. Its 
name should be the [PascalCase](http://api.rubyonrails.org/classes/String.html#method-i-camelize) equivalent 
of the filename (e.g. `my_doc` → `MyDoc`)
 2. Add the appropriate class attributes and filter options (see the [Scraper 
Reference](./scraper-reference.md) page).
 3. Check that the scraper is listed in `thor docs:list`.
diff --git a/lib/app.rb b/lib/app.rb
index 83e646e4..a0063e49 100644
--- a/lib/app.rb
+++ b/lib/app.rb
@@ -205,8 +205,28 @@ class App < Sinatra::Application
       ].compact
     end
 
-    def bypass_cache?
-      !memoized_cookies['bypassCache'].nil?
+    def service_worker_cache_name
+      # Returns the digest of the last modified asset
+      # When a manifest exist, this digest is only calculated once based on the asset manifest because it 
never changes without a server restart
+      # If a manifest does not exist, it is calculated every time this method is called because the assets 
can change while the server is running
+      if File.exist?(App.assets_manifest_path)
+        return @@service_worker_cache_name ||=
+          Sprockets::Manifest
+            .new(nil, App.assets_manifest_path)
+            .files
+            .values
+            .sort_by {|file| file["mtime"]}
+            .reverse
+            .first["digest"]
+      else
+        last_modified_file = App.sprockets
+          .each_file
+          .to_a
+          .reject {|file| file.start_with?(App.docs_path)}
+          .max_by {|file| File.mtime(file)}
+
+        return App.sprockets.pack_base64digest(App.sprockets.file_digest(last_modified_file))
+      end
     end
 
     def redirect_via_js(path)
diff --git a/views/service-worker.js.erb b/views/service-worker.js.erb
index 20de7bbe..d9eb4a6c 100644
--- a/views/service-worker.js.erb
+++ b/views/service-worker.js.erb
@@ -1,6 +1,6 @@
-<%# Use the hash of the application.js file as cache name or 'app' if not running in production %>
-<%# This ensures that the cache is always updated if the hash of the application.js file changes %>
-const cacheName = '<%= javascript_path('application', asset_host: 
false).scan(/application-([^\.]+)\.js/).last&.first || 'app' %>';
+<%# The name of the cache to store responses in %>
+<%# If the cache name changes DevDocs is assumed to be updated %>
+const cacheName = '<%= service_worker_cache_name %>';
 
 <%# Url's to cache when the service worker is installed %>
 const urlsToCache = [
@@ -32,9 +32,6 @@ self.addEventListener('activate', event => {
 <%# Handle HTTP requests %>
 self.addEventListener('fetch', event => {
   event.respondWith((async () => {
-    <% if bypass_cache? %>
-    return fetch(event.request);
-    <% else %>
     const cachedResponse = await caches.match(event.request);
     if (cachedResponse) return cachedResponse;
 
@@ -53,6 +50,5 @@ self.addEventListener('fetch', event => {
 
       throw err;
     }
-    <% end %>
   })());
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]