feat!: remove features related to the old thread page view

The old thread page view has been unusable for some time since the
introduction of nested replies in threads (since the old view doesn't
display them).

This CL removes all features related to that view:

- Block draft messages from being saved in Google servers.
- Activate the enableLoadingDraftMessages Community Console flag.
- Show the old thread page in the Community Console.

Fixed: twpowertools:124
Change-Id: I7fb815b7e1bf536a15a7bf76bcb2c1f3accdb648
diff --git a/src/common/optionsPermissions.js b/src/common/optionsPermissions.js
index bb84a88..2fa298b 100644
--- a/src/common/optionsPermissions.js
+++ b/src/common/optionsPermissions.js
@@ -9,9 +9,6 @@
 const requiredPermissions = {
   permissions: new Set([
     'storage', 'alarms',
-    // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-    'declarativeNetRequestWithHostAccess',
-    // #!endif
     // #!if browser_target == 'chromium_mv3'
     'scripting',
     // #!endif
diff --git a/src/common/optionsPrototype.ts b/src/common/optionsPrototype.ts
index 6ba534a..17e9056 100644
--- a/src/common/optionsPrototype.ts
+++ b/src/common/optionsPrototype.ts
@@ -49,11 +49,6 @@
     context: "options",
     killSwitchType: "option",
   },
-  loaddrafts: {
-    defaultValue: false,
-    context: "options",
-    killSwitchType: "option",
-  },
   increasecontrast: {
     defaultValue: false,
     context: "options",
@@ -131,28 +126,11 @@
     context: "options",
     killSwitchType: "option",
   },
-  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-  blockdrafts: {
-    defaultValue: false,
-    context: "options",
-    killSwitchType: "option",
-  },
-  // #!endif
   perforumstats: {
     defaultValue: false,
     context: "options",
     killSwitchType: "option",
   },
-  interopthreadpage: {
-    defaultValue: false,
-    context: "options",
-    killSwitchType: "option",
-  },
-  interopthreadpage_mode: {
-    defaultValue: "previous",
-    context: "options",
-    killSwitchType: "ignore",
-  },
   uispacing: {
     defaultValue: false,
     context: "options",
@@ -235,4 +213,26 @@
     context: "deprecated",
     killSwitchType: "deprecated",
   },
+  loaddrafts: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
+  blockdrafts: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  // #!endif
+  interopthreadpage: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  interopthreadpage_mode: {
+    defaultValue: "previous",
+    context: "deprecated",
+    killSwitchType: "ignore",
+  },
 };
diff --git a/src/common/specialOptions.json5 b/src/common/specialOptions.json5
index 58d330c..37b69fa 100644
--- a/src/common/specialOptions.json5
+++ b/src/common/specialOptions.json5
@@ -2,5 +2,4 @@
   'profileindicatoralt_months',
   'ccdarktheme_mode',
   'ccdarktheme_switch_enabled',
-  'interopthreadpage_mode',
 ]
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index 637e061..309e41b 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -58,9 +58,6 @@
   // Canned response tags (for the "import CR" popup for the workflows feature)
   'ec-canned-response-row .tags',
 
-  // Thread page main content
-  'ec-thread > .page > .material-content > div[role="list"]',
-
   // Thread page reply section (for the thread page toolbar)
   kRepliesSectionSelector,
 
@@ -141,12 +138,6 @@
       window.TWPTWorkflowsImport.addButtonIfEnabled(node);
     }
 
-    // Inject old thread page design warning if applicable
-    if (node.matches(
-            'ec-thread > .page > .material-content > div[role="list"]')) {
-      window.TWPTThreadPageDesignWarning.injectWarningIfApplicable(node);
-    }
-
     // Inject thread toolbar
     if (threadToolbar.shouldInject(node)) {
       threadToolbar.injectIfApplicable(node);
@@ -208,8 +199,7 @@
   flattenThreads = new FlattenThreads();
   reportDialogColorThemeFix = new ReportDialogColorThemeFix(options);
 
-  // threadPageDesignWarning and workflowsImport are
-  // initialized in start.js
+  // workflowsImport is initialized in start.js
 
   // Before starting the mutation Observer, check whether we missed any
   // mutations by manually checking whether some watched nodes already
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index 063f58a..cc54540 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -2,15 +2,11 @@
 import {getOptions} from '../../common/optionsUtils.js';
 
 import FlattenThreadsReplyActionHandler from './flattenThreads/replyActionHandler.js';
-import ThreadPageDesignWarning from './threadPageDesignWarning.js';
 import WorkflowsImport from './workflows/import.js';
 
-const SMEI_RCE_THREAD_INTEROP = 22;
-
 getOptions(null).then(options => {
   /* IMPORTANT NOTE: Remember to change this when changing the "ifs" below!! */
-  if (options.loaddrafts || options.interopthreadpage ||
-      options.fixpekb269560789) {
+  if (options.fixpekb269560789) {
     var startup =
         JSON.parse(document.querySelector('html').getAttribute('data-startup'));
 
@@ -20,31 +16,12 @@
       }
     }
 
-    if (options.loaddrafts) {
-      startup[4][13] = true;
-    }
-
-    if (options.interopthreadpage) {
-      var index = startup[1][6].indexOf(SMEI_RCE_THREAD_INTEROP);
-
-      switch (options.interopthreadpage_mode) {
-        case 'previous':
-          if (index > -1) startup[1][6].splice(index, 1);
-          break;
-
-        case 'next':
-          if (index == -1) startup[1][6].push(SMEI_RCE_THREAD_INTEROP);
-          break;
-      }
-    }
-
     document.querySelector('html').setAttribute(
         'data-startup', JSON.stringify(startup));
   }
 
   // Initialized here instead of in main.js so the first event is received if it
   // happens when the page loads.
-  window.TWPTThreadPageDesignWarning = new ThreadPageDesignWarning();
   window.TWPTWorkflowsImport = new WorkflowsImport();
 
   if (options.ccdarktheme) {
diff --git a/src/contentScripts/communityConsole/threadPageDesignWarning.js b/src/contentScripts/communityConsole/threadPageDesignWarning.js
deleted file mode 100644
index 155d916..0000000
--- a/src/contentScripts/communityConsole/threadPageDesignWarning.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import {MDCTooltip} from '@material/tooltip';
-import {waitFor} from 'poll-until-promise';
-
-import {parseUrl} from '../../common/commonUtils.js';
-import {injectStylesheet} from '../../common/contentScriptsUtils.js';
-import {getDocURL} from '../../common/extUtils.js';
-import {getOptions} from '../../common/optionsUtils.js';
-
-import {createExtBadge} from './utils/common.js';
-
-const kSMEINestedReplies = 15;
-const kViewThreadResponse = 'TWPT_ViewThreadResponse';
-
-export default class ThreadPageDesignWarning {
-  constructor() {
-    this.lastThread = {
-      body: {},
-      id: -1,
-      timestamp: 0,
-    };
-    this.setUpHandler();
-
-    // We have to save whether the old UI was enabled at startup, since that's
-    // the moment when it takes effect. If the option changes while the tab is
-    // open, it won't take effect.
-    getOptions([
-      'interopthreadpage', 'interopthreadpage_mode'
-    ]).then(options => {
-      this.shouldShowWarning = options.interopthreadpage &&
-          options.interopthreadpage_mode == 'previous';
-
-      if (this.shouldShowWarning) {
-        injectStylesheet(
-            chrome.runtime.getURL('css/thread_page_design_warning.css'));
-      } else {
-        this.removeHandler();
-      }
-    });
-
-    this.isExperimentEnabled = this.isNestedRepliesExperimentEnabled();
-  }
-
-  isNestedRepliesExperimentEnabled() {
-    if (!document.documentElement.hasAttribute('data-startup')) return false;
-
-    let startup =
-        JSON.parse(document.documentElement.getAttribute('data-startup'));
-    return startup?.[1]?.[6]?.includes?.(kSMEINestedReplies);
-  }
-
-  eventHandler(e) {
-    if (e.detail.id < this.lastThread.id) return;
-
-    this.lastThread = {
-      body: e.detail.body,
-      id: e.detail.id,
-      timestamp: Date.now(),
-    };
-  }
-
-  setUpHandler() {
-    window.addEventListener(kViewThreadResponse, this.eventHandler.bind(this));
-  }
-
-  removeHandler() {
-    window.removeEventListener(
-        kViewThreadResponse, this.eventHandler.bind(this));
-  }
-
-  injectWarning(content) {
-    let div = document.createElement('div');
-    div.classList.add('TWPT-warning');
-
-    let icon = document.createElement('material-icon');
-    icon.classList.add('TWPT-warning--icon');
-
-    let iconContent = document.createElement('i');
-    iconContent.classList.add('material-icon-i', 'material-icons-extended');
-    iconContent.setAttribute('role', 'img');
-    iconContent.setAttribute('aria-hidden', 'true');
-    iconContent.textContent = 'warning';
-
-    icon.append(iconContent);
-
-    let text = document.createElement('div');
-    text.classList.add('TWPT-warning--text');
-    text.textContent =
-        chrome.i18n.getMessage('inject_threadpagedesign_warning');
-
-    let btn = document.createElement('a');
-    btn.classList.add('TWPT-warning--btn');
-    btn.href =
-        getDocURL('features.md#Thread-page-design-in-the-Community-Console');
-    btn.setAttribute('target', '_blank');
-    btn.setAttribute('rel', 'noopener noreferrer');
-
-    const [badge, badgeTooltip] = createExtBadge();
-
-    let btnText = document.createElement('div');
-    btnText.textContent = chrome.i18n.getMessage('btn_learnmore');
-
-    btn.append(badge, btnText);
-
-    div.append(icon, text, btn);
-    content.prepend(div);
-
-    new MDCTooltip(badgeTooltip);
-  }
-
-  injectWarningIfApplicable(content) {
-    return waitFor(
-               () => {
-                 if (this.shouldShowWarning === undefined)
-                   return Promise.reject(
-                       new Error('shouldShowWarning is not defined.'));
-
-                 return Promise.resolve({result: this.shouldShowWarning});
-               },
-               {
-                 interval: 500,
-                 timeout: 10 * 1000,
-               })
-        .then(preShouldShowWarning => {
-          if (!preShouldShowWarning.result) return;
-
-          // If the global SMEI experiment is enabled, all threads use nested
-          // replies, so we'll skip the per-thread check and always show the
-          // warning banner.
-          if (this.isExperimentEnabled) return Promise.resolve({result: true});
-
-          let currentThread = parseUrl(location.href);
-          if (currentThread === false)
-            throw new Error('current thread id cannot be parsed.');
-
-          return waitFor(() => {
-            let now = Date.now();
-            let lastThreadInfo = this.lastThread.body['1']?.['2']?.['1'];
-            if (now - this.lastThread.timestamp > 30 * 1000 ||
-                lastThreadInfo?.['1'] != currentThread.thread ||
-                lastThreadInfo?.['3'] != currentThread.forum)
-              throw new Error(
-                  'cannot obtain information about current thread.');
-
-            // If the messageOrGap field contains any items, the thread is using
-            // nested replies. Otherwise, it probably isn't using them.
-            return Promise.resolve(
-                {result: this.lastThread.body['1']?.['40']?.length > 0});
-          }, {
-            interval: 500,
-            timeout: 10 * 1000,
-          });
-        })
-        .then(shouldShowWarning => {
-          if (shouldShowWarning.result) this.injectWarning(content);
-        })
-        .catch(err => {
-          console.error(
-              '[threadPageDesignWarning] An error ocurred while trying to decide whether to show warning: ',
-              err);
-        });
-  }
-}
diff --git a/src/options/bgHandler.js b/src/options/bgHandler.js
index a9d80ab..52f0d10 100644
--- a/src/options/bgHandler.js
+++ b/src/options/bgHandler.js
@@ -3,42 +3,23 @@
 // content scripts or injected scripts but instead in the background
 // script/service worker.
 //
-// An example is the "blockdrafts" feature, which when enabled should enable the
+// An example was the "blockdrafts" feature, which when enabled enabled the
 // static ruleset blocking *DraftMessages requests.
+//
+// The "blockdrafts" feature was removed, but this logic has been kept in case
+// it is needed in the future.
 
 import {isOptionEnabled} from '../common/optionsUtils.js';
 
 // List of features controled in the background:
-export var bgFeatures = [
-  'blockdrafts',
-];
-
-const blockDraftsRuleset = 'blockDrafts';
+export var bgFeatures = [];
 
 export function handleBgOptionChange(feature) {
   isOptionEnabled(feature)
+      // eslint-disable-next-line no-unused-vars
       .then(enabled => {
-        switch (feature) {
-          // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-          case 'blockdrafts':
-            chrome.declarativeNetRequest.getEnabledRulesets(rulesets => {
-              if (rulesets === undefined) {
-                throw new Error(
-                    chrome.runtime.lastError.message ??
-                    'Unknown error in chrome.declarativeNetRequest.getEnabledRulesets()');
-              }
-
-              let isRulesetEnabled = rulesets.includes(blockDraftsRuleset);
-              if (!isRulesetEnabled && enabled)
-                chrome.declarativeNetRequest.updateEnabledRulesets(
-                    {enableRulesetIds: [blockDraftsRuleset]});
-              if (isRulesetEnabled && !enabled)
-                chrome.declarativeNetRequest.updateEnabledRulesets(
-                    {disableRulesetIds: [blockDraftsRuleset]});
-            });
-            break;
-            // #!endif
-        }
+        // eslint-disable-next-line no-empty
+        switch (feature) {}
       })
       .catch(err => {
         console.error(
diff --git a/src/options/optionsCommon.js b/src/options/optionsCommon.js
index 557f6aa..f8d5c14 100644
--- a/src/options/optionsCommon.js
+++ b/src/options/optionsCommon.js
@@ -19,9 +19,6 @@
       case 'ccdarktheme_mode':
         return document.getElementById(opt).value || 'switch';
 
-      case 'interopthreadpage_mode':
-        return document.getElementById(opt).value || 'previous';
-
       default:
         console.warn('Unrecognized option: ' + opt);
         return undefined;
@@ -226,25 +223,6 @@
                 .appendChild(select);
             break;
 
-          case 'interopthreadpage_mode':
-            var select = document.createElement('select');
-            select.id = 'interopthreadpage_mode';
-
-            const threadPageModes = ['previous', 'next'];
-            for (const mode of threadPageModes) {
-              let modeOption = document.createElement('option');
-              modeOption.value = mode;
-              modeOption.textContent = chrome.i18n.getMessage(
-                  'options_interopthreadpage_mode_' + mode);
-              if (items.interopthreadpage_mode == mode)
-                modeOption.selected = true;
-              select.appendChild(modeOption);
-            }
-
-            document.getElementById('interopthreadpage_mode--container')
-                .appendChild(select);
-            break;
-
           default:
             console.warn('Unrecognized option: ' + opt);
             break;
diff --git a/src/options/optionsPage.json5 b/src/options/optionsPage.json5
index 92a554f..f3ea342 100644
--- a/src/options/optionsPage.json5
+++ b/src/options/optionsPage.json5
@@ -17,9 +17,6 @@
         {codename: 'perforumstats'},
         {codename: 'batchlock'},
         {codename: 'autorefreshlist'},
-        // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-        {codename: 'blockdrafts'},
-        // #!endif
       ],
     },
     {
@@ -35,7 +32,6 @@
       options: [
         {codename: 'fixedtoolbar'},
         {codename: 'redirect'},
-        {codename: 'loaddrafts', experimental: true},
         {codename: 'increasecontrast'},
         {codename: 'stickysidebarheaders'},
         {codename: 'ccforcehidedrawer'},
@@ -45,7 +41,6 @@
         {codename: 'enhancedannouncementsdot'},
         {codename: 'repositionexpandthread', experimental: true},
         {codename: 'imagemaxheight'},
-        {codename: 'interopthreadpage'},
         {codename: 'uispacing'},
       ],
     },
diff --git a/src/static/_locales/en/messages.json b/src/static/_locales/en/messages.json
index 4c655f7..27c732c 100644
--- a/src/static/_locales/en/messages.json
+++ b/src/static/_locales/en/messages.json
@@ -63,10 +63,6 @@
     "message": "Redirect all threads opened in TW to the Community Console.",
     "description": "Feature checkbox in the options page"
   },
-  "options_loaddrafts": {
-    "message": "Activate the <code class=\"help\" title=\"This flag allows the Community Console to load a previously autosaved reply when loading a thread and clicking the reply button.\">enableLoadingDraftMessages<\/code> Community Console flag.",
-    "description": "Feature checkbox in the options page"
-  },
   "options_experimental_label": {
     "message": "(experimental)",
     "description": "Label which is placed next to an option to indicate that it may not work well or may break at any time"
@@ -139,10 +135,6 @@
     "message": "Show the number of questions and replies written by the OP within the last <span id='profileindicatoralt_months--container'></span> months next to their username.",
     "description": "Feature checkbox in the options page"
   },
-  "options_blockdrafts": {
-    "message": "Block the sending of your replies as you type to Google servers in the Community Console.",
-    "description": "Feature checkbox in the options page"
-  },
   "options_workflows": {
     "message": "Enable the workflows feature.",
     "description": "Feature checkbox in the options page"
@@ -159,18 +151,6 @@
     "message": "Show per-forum activity in profiles.",
     "description": "Feature checkbox in the options page"
   },
-  "options_interopthreadpage": {
-    "message": "Show <span id='interopthreadpage_mode--container'></span> in the Community Console.",
-    "description": "Feature checkbox in the options page. \"<span id='interopthreadpage_mode--container'></span>\" will be substituted with a selector which allows users to select whether they want the new thread page design or the old one."
-  },
-  "options_interopthreadpage_mode_previous": {
-    "message": "the old thread page design",
-    "description": "Select option added in #interopthreadpage_mode--container, in the options_interopthreadpage string"
-  },
-  "options_interopthreadpage_mode_next": {
-    "message": "the new thread page design",
-    "description": "Select option added in #interopthreadpage_mode--container, in the options_interopthreadpage string"
-  },
   "options_uispacing": {
     "message": "Reduce the whitespace in the Community Console and TW.",
     "description": "Feature checkbox in the options page"
diff --git a/templates/manifest.gjson b/templates/manifest.gjson
index 2f3f4cf..80c86a9 100644
--- a/templates/manifest.gjson
+++ b/templates/manifest.gjson
@@ -76,9 +76,6 @@
 #if defined(CHROMIUM || GECKO)
     "https://support.google.com/*",
 #endif
-#if defined(CHROMIUM || CHROMIUM_MV3)
-    "declarativeNetRequestWithHostAccess",
-#endif
 #if defined(CHROMIUM_MV3)
     "scripting",
 #endif
@@ -141,15 +138,6 @@
     }
 #endif
   ],
-#if defined(CHROMIUM || CHROMIUM_MV3)
-  "declarative_net_request": {
-    "rule_resources": [{
-      "id": "blockDrafts",
-      "enabled": false,
-      "path": "rulesets/blockDrafts.json"
-    }]
-  },
-#endif
 #if defined(CHROMIUM || GECKO)
   "browser_action": {},
 #endif