From 64a66cf82bb13d491ab47588955cf3fa931b1043 Mon Sep 17 00:00:00 2001
From: David Taylor <david@taylorhq.com>
Date: Mon, 15 Aug 2022 15:15:15 +0100
Subject: [PATCH] UX: Improve safe-mode usability (#17929)

- `no_custom` -> `no_themes` (history: before themes existed, we had a similar tool called 'customizations')
- `only_official` -> `no_unofficial_plugins` (matches format of `no_themes` and `no_plugins`, and makes it clear that this doesn't affect themes)
- `?safe_mode=no_themes%2C%no_plugins` -> `?safe_mode=no_themes,no_plugins` (the query portion of a URL does not require commas to be encoded. This is much nicer to read)
- If `no_plugins` is chosen from `/safe-mode` the URL generated will omit the superfluous `no_unofficial_plugins` flag
- Some tweaks to copy on `/safe-mode`
---
 .../discourse/app/lib/source-identifier.js     |  2 +-
 app/controllers/application_controller.rb      | 18 +++++++++++-------
 app/controllers/safe_mode_controller.rb        | 15 ++++++++++-----
 app/helpers/application_helper.rb              |  8 ++++----
 app/views/safe_mode/index.html.erb             |  8 ++++----
 config/locales/server.en.yml                   |  6 +++---
 6 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/app/assets/javascripts/discourse/app/lib/source-identifier.js b/app/assets/javascripts/discourse/app/lib/source-identifier.js
index 1294fec6d39..555c1cac8c0 100644
--- a/app/assets/javascripts/discourse/app/lib/source-identifier.js
+++ b/app/assets/javascripts/discourse/app/lib/source-identifier.js
@@ -58,7 +58,7 @@ export function getThemeInfo(id) {
   return {
     id,
     name,
-    path: getURL(`/admin/customize/themes/${id}?safe_mode=no_custom`),
+    path: getURL(`/admin/customize/themes/${id}?safe_mode=no_themes`),
   };
 }
 
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 94e3808bc1d..7e6857625b8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -444,19 +444,23 @@ class ApplicationController < ActionController::Base
     session[:mobile_view] = params[:mobile_view] if params.has_key?(:mobile_view)
   end
 
-  NO_CUSTOM = "no_custom"
+  NO_THEMES = "no_themes"
   NO_PLUGINS = "no_plugins"
-  ONLY_OFFICIAL = "only_official"
+  NO_UNOFFICIAL_PLUGINS = "no_unofficial_plugins"
   SAFE_MODE = "safe_mode"
 
+  LEGACY_NO_THEMES = "no_custom"
+  LEGACY_NO_UNOFFICIAL_PLUGINS = "only_official"
+
   def resolve_safe_mode
     return unless guardian.can_enable_safe_mode?
 
     safe_mode = params[SAFE_MODE]
-    if safe_mode
-      request.env[NO_CUSTOM] = !!safe_mode.include?(NO_CUSTOM)
-      request.env[NO_PLUGINS] = !!safe_mode.include?(NO_PLUGINS)
-      request.env[ONLY_OFFICIAL] = !!safe_mode.include?(ONLY_OFFICIAL)
+    if safe_mode&.is_a?(String)
+      safe_mode = safe_mode.split(",")
+      request.env[NO_THEMES] = safe_mode.include?(NO_THEMES) || safe_mode.include?(LEGACY_NO_THEMES)
+      request.env[NO_PLUGINS] = safe_mode.include?(NO_PLUGINS)
+      request.env[NO_UNOFFICIAL_PLUGINS] = safe_mode.include?(NO_UNOFFICIAL_PLUGINS) || safe_mode.include?(LEGACY_NO_UNOFFICIAL_PLUGINS)
     end
   end
 
@@ -464,7 +468,7 @@ class ApplicationController < ActionController::Base
     return if request.format == "js"
 
     resolve_safe_mode
-    return if request.env[NO_CUSTOM]
+    return if request.env[NO_THEMES]
 
     theme_id = nil
 
diff --git a/app/controllers/safe_mode_controller.rb b/app/controllers/safe_mode_controller.rb
index d0742eba102..3ffe891d173 100644
--- a/app/controllers/safe_mode_controller.rb
+++ b/app/controllers/safe_mode_controller.rb
@@ -12,12 +12,17 @@ class SafeModeController < ApplicationController
 
   def enter
     safe_mode = []
-    safe_mode << "no_custom" if params["no_customizations"] == "true"
-    safe_mode << "no_plugins" if params["no_plugins"] == "true"
-    safe_mode << "only_official" if params["only_official"] == "true"
+
+    safe_mode << "no_themes" if params["no_themes"] == "true"
+
+    if params["no_plugins"] == "true"
+      safe_mode << "no_plugins"
+    elsif params["no_unofficial_plugins"] == "true"
+      safe_mode << "no_unofficial_plugins"
+    end
 
     if safe_mode.length > 0
-      redirect_to path("/?safe_mode=#{safe_mode.join("%2C")}")
+      redirect_to path("/?safe_mode=#{safe_mode.join(",")}")
     else
       flash[:must_select] = true
       redirect_to safe_mode_path
@@ -31,7 +36,7 @@ class SafeModeController < ApplicationController
   end
 
   def force_safe_mode_for_route
-    request.env[ApplicationController::NO_CUSTOM] = true
+    request.env[ApplicationController::NO_THEMES] = true
     request.env[ApplicationController::NO_PLUGINS] = true
   end
 
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index b478e56a309..43c5418baf9 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -418,7 +418,7 @@ module ApplicationHelper
   end
 
   def customization_disabled?
-    request.env[ApplicationController::NO_CUSTOM]
+    request.env[ApplicationController::NO_THEMES]
   end
 
   def include_ios_native_app_banner?
@@ -441,15 +441,15 @@ module ApplicationHelper
   end
 
   def allow_third_party_plugins?
-    allow_plugins? && !request.env[ApplicationController::ONLY_OFFICIAL]
+    allow_plugins? && !request.env[ApplicationController::NO_UNOFFICIAL_PLUGINS]
   end
 
   def normalized_safe_mode
     safe_mode = []
 
-    safe_mode << ApplicationController::NO_CUSTOM if customization_disabled?
+    safe_mode << ApplicationController::NO_THEMES if customization_disabled?
     safe_mode << ApplicationController::NO_PLUGINS if !allow_plugins?
-    safe_mode << ApplicationController::ONLY_OFFICIAL if !allow_third_party_plugins?
+    safe_mode << ApplicationController::NO_UNOFFICIAL_PLUGINS if !allow_third_party_plugins?
 
     safe_mode.join(",")
   end
diff --git a/app/views/safe_mode/index.html.erb b/app/views/safe_mode/index.html.erb
index 0405a079462..c6ee82531f6 100644
--- a/app/views/safe_mode/index.html.erb
+++ b/app/views/safe_mode/index.html.erb
@@ -6,14 +6,14 @@
     </p>
     <p>
     <label>
-    <%= check_box_tag 'no_customizations', true, !flash[:must_select]%>
-    <%= t 'safe_mode.no_customizations' %>
+    <%= check_box_tag 'no_themes', true, !flash[:must_select]%>
+    <%= t 'safe_mode.no_themes' %>
     </label>
     </p>
     <p>
     <label>
-    <%= check_box_tag 'only_official', true, !flash[:must_select] %>
-    <%= t 'safe_mode.only_official' %>
+    <%= check_box_tag 'no_unofficial_plugins', true, !flash[:must_select] %>
+    <%= t 'safe_mode.no_unofficial_plugins' %>
     </label>
     </p>
     <p>
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 23d38246a53..c966b7c8097 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -4885,9 +4885,9 @@ en:
 
   safe_mode:
     title: "Enter safe mode"
-    description: "Safe mode allows you to test your site without loading plugins or site customizations."
-    no_customizations: "Disable current theme"
-    only_official: "Disable unofficial plugins"
+    description: "Safe mode allows you to test your site without loading plugins or themes."
+    no_themes: "Disable themes and theme components"
+    no_unofficial_plugins: "Disable unofficial plugins"
     no_plugins: "Disable all plugins"
     enter: "Enter Safe Mode"
     must_select: "You must select at least one option to enter safe mode."