diff --git a/.env_sample b/.env_sample
index 54734e893..178cb5ed8 100644
--- a/.env_sample
+++ b/.env_sample
@@ -1,5 +1,4 @@
# Development options
-SKIP_SERVICEWORKERS="true"
# App core values
APP_DOMAIN="localhost:3000"
diff --git a/app/assets/javascripts/base.js.erb b/app/assets/javascripts/base.js.erb
index 9158b558f..d10fa6328 100644
--- a/app/assets/javascripts/base.js.erb
+++ b/app/assets/javascripts/base.js.erb
@@ -5,7 +5,6 @@
//= require utilities/getImageForLink
//= require honeybadger-js/dist/honeybadger.js
//= require ahoy.js/dist/ahoy.js
-//= require serviceworker-companion
var instantClick
, InstantClick = instantClick = function(document, location, $userAgent) {
diff --git a/app/assets/javascripts/serviceworker-companion.js b/app/assets/javascripts/serviceworker-companion.js
deleted file mode 100644
index a1aaab448..000000000
--- a/app/assets/javascripts/serviceworker-companion.js
+++ /dev/null
@@ -1,36 +0,0 @@
-'use strict';
-
-if ('serviceWorker' in navigator) {
- // Safari has issues with the service worker, so we'll just skip it on those browsers, and unregister it if it's loaded
- if (
- /Safari/i.test(navigator.userAgent) &&
- /Apple Computer/.test(navigator.vendor)
- ) {
- //unregister serviceworker
- navigator.serviceWorker
- .getRegistration('/serviceworker.js')
- .then(function (registration) {
- if (registration) {
- registration.unregister();
- }
- });
- } else {
- navigator.serviceWorker
- .register('/serviceworker.js', { scope: '/' })
- .then(function swStart(registration) {
- // registered!
- })
- .catch((error) => {
- // eslint-disable-next-line no-console
- console.log('ServiceWorker registration failed: ', error);
- });
- }
-}
-
-window.addEventListener('beforeinstallprompt', (e) => {
- // beforeinstallprompt Event fired
- // e.userChoice will return a Promise.
- e.userChoice.then((choiceResult) => {
- ga('send', 'event', 'PWA-install', choiceResult.outcome);
- });
-});
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 4bfa8c03a..329c47b4c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -41,14 +41,8 @@ class ApplicationController < ActionController::Base
health_checks].freeze
private_constant :PUBLIC_CONTROLLERS
- # TODO: Remove the "shell" endpoints, because they are for service worker
- # functionality we no longer need. We are keeping these around mid-March
- # 2021 because previously-installed service workers may still expect them.
CONTENT_CHANGE_PATHS = [
"/tags/onboarding", # Needs to change when suggested_tags is edited.
- "/shell_top", # Cached at edge, sent to service worker.
- "/shell_bottom", # Cached at edge, sent to service worker.
- "/async_info/shell_version", # Checks if current users should be busted.
"/onboarding", # Page is cached at edge.
"/", # Page is cached at edge.
].freeze
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
index 714765244..6fb9e3411 100644
--- a/app/controllers/pages_controller.rb
+++ b/app/controllers/pages_controller.rb
@@ -83,8 +83,7 @@ class PagesController < ApplicationController
end
def report_abuse
- referer = URL.sanitized_referer(request.referer)
- reported_url = params[:reported_url] || params[:url] || referer
+ reported_url = params[:reported_url] || params[:url] || request.referer.presence
@feedback_message = FeedbackMessage.new(
reported_url: reported_url&.chomp("?i=i"),
)
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 9ce064fc2..7852342e9 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -5,8 +5,7 @@ class RegistrationsController < Devise::RegistrationsController
if user_signed_in?
redirect_to root_path(signin: "true")
else
- referer_path = URI(request.referer || "").path
- if URI(request.referer || "").host == URI(request.base_url).host && referer_path != "/serviceworker.js"
+ if URI(request.referer || "").host == URI(request.base_url).host
store_location_for(:user, request.referer)
end
super
diff --git a/app/controllers/service_worker_controller.rb b/app/controllers/service_worker_controller.rb
index d7a6c6bbd..bbbedd577 100644
--- a/app/controllers/service_worker_controller.rb
+++ b/app/controllers/service_worker_controller.rb
@@ -1,14 +1,9 @@
class ServiceWorkerController < ApplicationController
skip_before_action :verify_authenticity_token
- before_action :set_cache_control_headers, only: %i[index manifest]
+ before_action :set_cache_control_headers, only: %i[index]
def index
set_surrogate_key_header "serviceworker-js"
render formats: [:js]
end
-
- def manifest
- set_surrogate_key_header "manifest-json"
- render formats: [:json]
- end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 201561287..68f5d0ddc 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -261,10 +261,6 @@ module ApplicationHelper
URL.organization(organization)
end
- def sanitized_referer(referer)
- URL.sanitized_referer(referer)
- end
-
def sanitize_and_decode(str)
# using to_str instead of to_s to prevent removal of html entity code
HTMLEntities.new.decode(sanitize(str).to_str)
diff --git a/app/lib/url.rb b/app/lib/url.rb
index b82512488..af1f6f283 100644
--- a/app/lib/url.rb
+++ b/app/lib/url.rb
@@ -1,7 +1,5 @@
# Utilities methods to safely build app wide URLs
module URL
- SERVICE_WORKER = "/serviceworker.js".freeze
-
def self.protocol
ApplicationConfig["APP_PROTOCOL"]
end
@@ -72,19 +70,4 @@ module URL
def self.organization(organization)
url(organization.slug)
end
-
- # Ensures we don't consider serviceworker.js as referer
- #
- # @param referer [String] the unsanitized referer
- # @example A safe referer
- # sanitized_referer("/some/path") #=> "/some/path"
- # @example serviceworker.js as referer
- # sanitized_referer("serviceworker.js") #=> nil
- # @example An empty string
- # sanitized_referer("") #=> nil
- def self.sanitized_referer(referer)
- return if referer.blank? || URI(referer).path == SERVICE_WORKER
-
- referer
- end
end
diff --git a/app/views/articles/show.html.erb b/app/views/articles/show.html.erb
index 71c20fa82..1b3a2f84d 100644
--- a/app/views/articles/show.html.erb
+++ b/app/views/articles/show.html.erb
@@ -48,7 +48,8 @@
<% end %>
<% if internal_navigation? %>
-
+
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index e85f1e26d..b8a2cb155 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,4 +1,86 @@
-<%= render "shell/top" %>
+
+
+
+
+ <% title = yield(:title) %>
+ <%= title || community_name.to_s %>
+ <% unless internal_navigation? %>
+
+
+
+ <% if SiteConfig.payment_pointer.present? %>
+
+
+
+
+
+
+ <% end %>
+
+ <%= render "layouts/styles", qualifier: "main" %>
+ <% unless user_signed_in? %>
+ <%= javascript_packs_with_chunks_tag "base", "Search", defer: true %>
+ <% end %>
+ <%= javascript_include_tag "base", defer: true %>
+ <% if user_signed_in? %>
+ <%= javascript_packs_with_chunks_tag "base", "Search", "onboardingRedirectCheck", "contentDisplayPolicy", defer: true %>
+ <% end %>
+ <%= yield(:page_meta) %>
+
+ <%= favicon_link_tag Images::Optimizer.call(SiteConfig.favicon_url, width: 32) %>
+ ">
+ ">
+ ">
+ ">
+ " rel="icon" sizes="192x192" />
+ " rel="icon" sizes="128x128" />
+
+
+
+ " type="application/opensearchdescription+xml" title="<%= community_name %>" />
+
+
+ " />
+
+ <% end %>
+
+ <% unless internal_navigation? %>
+ <% cache(release_adjusted_cache_key("top-html-and-config--#{user_signed_in?}")) do %>
+ -article-body default-header"
+ data-pusher-key="<%= ApplicationConfig["PUSHER_KEY"] %>"
+ data-app-domain="<%= ChatChannel.urlsafe_encoded_app_domain %>"
+ data-honeybadger-key="<%= ApplicationConfig["HONEYBADGER_JS_API_KEY"] %>"
+ data-deployed-at="<%= ForemInstance.deployed_at %>"
+ data-latest-commit-id="<%= ForemInstance.latest_commit_id %>"
+ data-ga-tracking="<%= SiteConfig.ga_tracking_id %>">
+ <%# Repeat of stylesheets in to fix rendering glitch: https://github.com/forem/forem/issues/12377 %>
+ <%= render "layouts/styles", qualifier: "secondary" %>
+
+
+
+ <% if user_signed_in? %>
+ <%= render "layouts/user_config" %>
+ <% end %>
+
+ <%= yield(:audio) %>
+
+ <%= render "layouts/top_bar" %>
+
+
+
+ loading...
+
+ <% end %>
+ <% end %>
<% if SiteConfig.payment_pointer.present? %>
<% end %>
@@ -24,4 +106,18 @@
<%= yield %>
-<%= render "shell/bottom" %>
+<% unless internal_navigation? %>
+ <% cache("footer-and-signup-modal-#{user_signed_in?}-#{ForemInstance.deployed_at}-#{SiteConfig.admin_action_taken_at&.rfc3339}", expires_in: 24.hours) do %>
+ <%= render "layouts/footer" %>
+ <%= render "layouts/signup_modal" unless user_signed_in? %>
+ <% end %>
+ <% if @shell %>
+
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/service_worker/index.js.erb b/app/views/service_worker/index.js.erb
index 94586bccd..f15a0a651 100644
--- a/app/views/service_worker/index.js.erb
+++ b/app/views/service_worker/index.js.erb
@@ -1,91 +1,21 @@
// Service worker file. Renders as serviceworker.js
+// This is now a self-destructing service worker. See https://github.com/NekR/self-destroying-sw
-<% unless Rails.env.test? || ENV["SKIP_SERVICEWORKERS"] == "true" %>
- const VERSION = "1.0" // Increment to invalidate old assets.
- const OFFLINE_URL = "offline.html";
- const OFFLINE_NAME = OFFLINE_URL + VERSION
-
- self.addEventListener("install", (event) => {
- event.waitUntil(
- (async () => {
-
- // Setting {cache: 'reload'} in the new request will ensure that the
- // response isn't fulfilled from the HTTP cache; i.e., it will be from
- // the network.
- const offlineCache = await caches.open(OFFLINE_NAME);
- await offlineCache.add(new Request(OFFLINE_URL, { cache: "reload" }));
- })()
- );
- // Force the waiting service worker to become the active service worker.
+<% unless Rails.env.test? %>
+ self.addEventListener('install', function(e) {
self.skipWaiting();
});
- self.addEventListener("activate", (event) => {
- event.waitUntil(
- (async () => {
- // Enable navigation preload if it's supported.
- // See https://developers.google.com/web/updates/2017/02/navigation-preload
- if ("navigationPreload" in self.registration) {
- await self.registration.navigationPreload.enable();
- }
- })()
- );
-
- // Tell the active service worker to take control of the page immediately.
- self.clients.claim();
- });
-
- function includesUnsupportedPath(url) {
- return [
- '/%F0%9F%92%B8', // 💸 (hiring)
- '/admin', // Don't run on admin dashboard.
- '/new', // Don't run on editor.
- '/enter', // Don't run on sign in page.
- '/oauth/', // Skip oauth apps
- '/onboarding', // Don't run on onboarding.
- '/shop', // Don't run on Shop
- '/sidekiq', // Skip for Sidekiq dashboard
- '/users/auth', // Don't run on authentication.
- '/users/sign_in', // Don't run on sign in page.
- '/welcome', // Don't run on welcome reroutes.
- ].some(path => url.includes(path))
- }
-
- self.addEventListener("fetch", (event) => {
- // We only want to call event.respondWith() if this is a navigation request
- // for an HTML page with a few exceptions.
- if (event.request.mode === "navigate" && !includesUnsupportedPath(event.request.url)) {
- event.respondWith(
- (async () => {
- try {
- // First, try to use the navigation preload response if it's supported.
- const preloadResponse = await event.preloadResponse;
- if (preloadResponse) {
- return preloadResponse;
- }
-
- // Always try the network first.
- const networkResponse = await fetch(event.request);
- return networkResponse;
- } catch (error) {
- // catch is only triggered if an exception is thrown, which is likely
- // due to a network error.
- // If fetch() returns a valid HTTP response with a response code in
- // the 4xx or 5xx range, the catch() will NOT be called.
- console.log("Fetch failed; returning offline page instead.", error);
-
- const cache = await caches.open(OFFLINE_NAME);
- const cachedResponse = await cache.match(OFFLINE_URL);
- return cachedResponse;
- }
- })()
- );
- }
-
- // If our if() condition is false, then this fetch handler won't intercept the
- // request. If there are any other fetch handlers registered, they will get a
- // chance to call event.respondWith(). If no fetch handlers call
- // event.respondWith(), the request will be handled by the browser as if there
- // were no service worker involvement.
+ self.addEventListener('activate', function(e) {
+ self.registration.unregister()
+ .then(function() {
+ return self.clients.matchAll();
+ })
+ .then(function(clients) {
+ clients.forEach(client => {
+ // Check if client.navigate is supported before running it.
+ client.navigate && client.navigate(client.url);
+ })
+ });
});
<% end %>
diff --git a/app/views/service_worker/manifest.json.erb b/app/views/service_worker/manifest.json.erb
deleted file mode 100644
index cd204a184..000000000
--- a/app/views/service_worker/manifest.json.erb
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "<%= community_name %>",
- "short_name": "<%= SiteConfig.app_domain %>",
- "description": "<%= SiteConfig.community_description %>",
- "start_url": "/",
- "display": "standalone",
- "background_color": "#000000",
- "theme_color": "#000000",
- "homepage_url": "<%= app_url %>",
- "icons": [{
- "src": "<%= optimized_image_url(SiteConfig.logo_png, width: 192, fetch_format: "png") %>",
- "sizes": "192x192",
- "type": "image/png",
- "purpose": "any maskable"
- }, {
- "src": "<%= optimized_image_url(SiteConfig.logo_png, width: 128, fetch_format: "png") %>",
- "sizes": "128x128",
- "type": "image/png",
- "purpose": "any maskable"
- }, {
- "src": "<%= optimized_image_url(SiteConfig.logo_png, width: 512, fetch_format: "png") %>",
- "sizes": "512x512",
- "type": "image/png",
- "purpose": "any maskable"
- }]
-}
diff --git a/app/views/shell/_bottom.html.erb b/app/views/shell/_bottom.html.erb
deleted file mode 100644
index 111d4a33e..000000000
--- a/app/views/shell/_bottom.html.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-<% # TODO: This file supports removed service worker functionality. We are keeping it around until mid-March to support previously downloaded service workers. %>
-<% # After that, these contents can be moved right into application.html. %>
-
-
-<% unless internal_navigation? %>
- <% cache("footer-and-signup-modal-#{user_signed_in?}-#{ForemInstance.deployed_at}-#{SiteConfig.admin_action_taken_at&.rfc3339}", expires_in: 24.hours) do %>
- <%= render "layouts/footer" %>
- <%= render "layouts/signup_modal" unless user_signed_in? %>
- <% end %>
- <% if @shell %>
-
- <% end %>
-
-