Unified · Split
| @@ -5,6 +5,7 @@ class app.Settings · 4 unmodified lines | |||
| 5 | 'manualUpdate' | 5 | 'manualUpdate' |
| 6 | 'fastScroll' | 6 | 'fastScroll' |
| 7 | 'arrowScroll' | 7 | 'arrowScroll' |
| 8 | 'bypassCache' | ||
| 8 | 'docs' | 9 | 'docs' |
| 9 | 'dark' | 10 | 'dark' |
| 10 | 'layout' | 11 | 'layout' |
| @@ -91,6 +92,11 @@ class app.Settings · 80 unmodified lines | |||
| 91 | @set 'size', value | 92 | @set 'size', value |
| 92 | return | 93 | return |
| 93 | 94 | ||
| 95 | setBypassCache: (value) -> | ||
| 96 | @set 'bypassCache', value | ||
| 97 | app.serviceWorker?.updateInBackground() | ||
| 98 | return | ||
| 99 | |||
| 94 | dump: -> | 100 | dump: -> |
| 95 | @store.dump() | 101 | @store.dump() |
| 96 | 102 | ||
| @@ -15,6 +15,10 @@ app.templates.settingsPage = (settings) -> """ · 14 unmodified lines | |||
| 15 | <input type="checkbox" form="settings" name="layout" value="_sidebar-hidden"#{if settings['_sidebar-hidden'] then ' checked' else ''}>Automatically hide and show the sidebar | 15 | <input type="checkbox" form="settings" name="layout" value="_sidebar-hidden"#{if settings['_sidebar-hidden'] then ' checked' else ''}>Automatically hide and show the sidebar |
| 16 | <small>Tip: drag the edge of the sidebar to resize it.</small> | 16 | <small>Tip: drag the edge of the sidebar to resize it.</small> |
| 17 | </label> | 17 | </label> |
| 18 | <label class="_settings-label"> | ||
| 19 | <input type="checkbox" form="settings" name="bypassCache" value="1"#{if settings.bypassCache then ' checked' else ''}>Bypass Service Worker cache | ||
| 20 | <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> | ||
| 21 | </label> | ||
| 18 | </div> | 22 | </div> |
| 19 | </div> | 23 | </div> |
| 20 | 24 | ||
| @@ -14,6 +14,7 @@ class app.views.SettingsPage extends app.View · 13 unmodified lines | |||
| 14 | settings.dark = app.settings.get('dark') | 14 | settings.dark = app.settings.get('dark') |
| 15 | settings.smoothScroll = !app.settings.get('fastScroll') | 15 | settings.smoothScroll = !app.settings.get('fastScroll') |
| 16 | settings.arrowScroll = app.settings.get('arrowScroll') | 16 | settings.arrowScroll = app.settings.get('arrowScroll') |
| 17 | settings.bypassCache = app.settings.get('bypassCache') | ||
| 17 | settings[layout] = app.settings.hasLayout(layout) for layout in app.settings.LAYOUTS | 18 | settings[layout] = app.settings.hasLayout(layout) for layout in app.settings.LAYOUTS |
| 18 | settings | 19 | settings |
| 19 | 20 | ||
| @@ -32,6 +33,10 @@ class app.views.SettingsPage extends app.View · 12 unmodified lines | |||
| 32 | app.settings.set('fastScroll', !enable) | 33 | app.settings.set('fastScroll', !enable) |
| 33 | return | 34 | return |
| 34 | 35 | ||
| 36 | toggleBypassCache: (enable) -> | ||
| 37 | app.settings.setBypassCache(!!enable) | ||
| 38 | return | ||
| 39 | |||
| 35 | toggle: (name, enable) -> | 40 | toggle: (name, enable) -> |
| 36 | app.settings.set(name, enable) | 41 | app.settings.set(name, enable) |
| 37 | return | 42 | return |
| @@ -75,6 +80,8 @@ class app.views.SettingsPage extends app.View · 37 unmodified lines | |||
| 75 | @toggleSmoothScroll input.checked | 80 | @toggleSmoothScroll input.checked |
| 76 | when 'import' | 81 | when 'import' |
| 77 | @import input.files[0], input | 82 | @import input.files[0], input |
| 83 | when 'bypassCache' | ||
| 84 | @toggleBypassCache input.checked | ||
| 78 | else | 85 | else |
| 79 | @toggle input.name, input.checked | 86 | @toggle input.name, input.checked |
| 80 | return | 87 | return |
| @@ -2,6 +2,8 @@ Adding a documentation may look like a daunting task but once you get the hang o · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | **Note:** please read the [contributing guidelines](../.github/CONTRIBUTING.md) before submitting a new documentation. | 3 | **Note:** please read the [contributing guidelines](../.github/CONTRIBUTING.md) before submitting a new documentation. |
| 4 | 4 | ||
| 5 | **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. | ||
| 6 | |||
| 5 | 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`) | 7 | 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`) |
| 6 | 2. Add the appropriate class attributes and filter options (see the [Scraper Reference](./scraper-reference.md) page). | 8 | 2. Add the appropriate class attributes and filter options (see the [Scraper Reference](./scraper-reference.md) page). |
| 7 | 3. Check that the scraper is listed in `thor docs:list`. | 9 | 3. Check that the scraper is listed in `thor docs:list`. |
| @@ -220,6 +220,10 @@ class App < Sinatra::Application · 219 unmodified lines | |||
| 220 | app_theme == 'dark' | 220 | app_theme == 'dark' |
| 221 | end | 221 | end |
| 222 | 222 | ||
| 223 | def bypass_cache? | ||
| 224 | !memoized_cookies['bypassCache'].nil? | ||
| 225 | end | ||
| 226 | |||
| 223 | def redirect_via_js(path) | 227 | def redirect_via_js(path) |
| 224 | response.set_cookie :initial_path, value: path, expires: Time.now + 15, path: '/' | 228 | response.set_cookie :initial_path, value: path, expires: Time.now + 15, path: '/' |
| 225 | redirect '/', 302 | 229 | redirect '/', 302 |
| @@ -31,13 +31,16 @@ self.addEventListener('activate', event => { · 30 unmodified lines | |||
| 31 | event.waitUntil((async () => { | 31 | event.waitUntil((async () => { |
| 32 | const keys = await caches.keys(); | 32 | const keys = await caches.keys(); |
| 33 | const jobs = keys.map(key => key !== cacheName ? caches.delete(key) : Promise.resolve()); | 33 | const jobs = keys.map(key => key !== cacheName ? caches.delete(key) : Promise.resolve()); |
| 34 | return await Promise.all(jobs); | 34 | return Promise.all(jobs); |
| 35 | })()); | 35 | })()); |
| 36 | }); | 36 | }); |
| 37 | 37 | ||
| 38 | <%# Handle HTTP requests %> | 38 | <%# Handle HTTP requests %> |
| 39 | self.addEventListener('fetch', event => { | 39 | self.addEventListener('fetch', event => { |
| 40 | event.respondWith((async () => { | 40 | event.respondWith((async () => { |
| 41 | <% if bypass_cache? %> | ||
| 42 | return fetch(event.request); | ||
| 43 | <% else %> | ||
| 41 | const cachedResponse = await caches.match(event.request); | 44 | const cachedResponse = await caches.match(event.request); |
| 42 | if (cachedResponse) return cachedResponse; | 45 | if (cachedResponse) return cachedResponse; |
| 43 | 46 | ||
| @@ -56,5 +59,6 @@ self.addEventListener('fetch', event => { · 12 unmodified lines | |||
| 56 | 59 | ||
| 57 | throw err; | 60 | throw err; |
| 58 | } | 61 | } |
| 62 | <% end %> | ||
| 59 | })()); | 63 | })()); |
| 60 | }); | 64 | }); |