Add option to choose the thread page design in the CC

This feature allows users to choose whether to show the old thread page
design or the new one.

This CL also adds an experimental feature to activate the nested replies
experiment in the Community Console (only available in the Canary
channel). It has been added as an experimental feature because the
nested replies feature doesn't work yet in the Community Console.

Change-Id: Ifc371848b55f450bedf22d8e35fb4348fffa6c63
diff --git a/src/common/optionsPrototype.json5 b/src/common/optionsPrototype.json5
index 5866b0e..6b6e01b 100644
--- a/src/common/optionsPrototype.json5
+++ b/src/common/optionsPrototype.json5
@@ -124,6 +124,16 @@
     context: 'options',
     killSwitchType: 'option',
   },
+  'interopthreadpage': {
+    defaultValue: false,
+    context: 'options',
+    killSwitchType: 'option',
+  },
+  'interopthreadpage_mode': {
+    defaultValue: 'previous',
+    context: 'options',
+    killSwitchType: 'ignore',
+  },
 
   // Experiments:
   'workflows': {
@@ -136,6 +146,11 @@
     context: 'experiments',
     killSwitchType: 'experiment',
   },
+  'nestedreplies': {
+    defaultValue: false,
+    context: 'experiments',
+    killSwitchType: 'experiment',
+  },
 
   // Internal options:
   'ccdarktheme_switch_enabled': {
diff --git a/src/common/specialOptions.json5 b/src/common/specialOptions.json5
index 37b69fa..58d330c 100644
--- a/src/common/specialOptions.json5
+++ b/src/common/specialOptions.json5
@@ -2,4 +2,5 @@
   'profileindicatoralt_months',
   'ccdarktheme_mode',
   'ccdarktheme_switch_enabled',
+  'interopthreadpage_mode',
 ]
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index 250df78..d30a113 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -4,9 +4,12 @@
 import AutoRefresh from './autoRefresh.js';
 import ExtraInfo from './extraInfo.js';
 
+const SMEI_NESTED_REPLIES = 15;
+const SMEI_RCE_THREAD_INTEROP = 22;
+
 getOptions(null).then(options => {
   /* IMPORTANT NOTE: Remember to change this when changing the "ifs" below!! */
-  if (options.loaddrafts) {
+  if (options.loaddrafts || options.interopthreadpage) {
     var startup =
         JSON.parse(document.querySelector('html').getAttribute('data-startup'));
 
@@ -14,6 +17,25 @@
       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;
+      }
+    }
+
+    if (options.nestedreplies) {
+      if (!startup[1][6].includes(SMEI_NESTED_REPLIES))
+        startup[1][6].push(SMEI_NESTED_REPLIES);
+    }
+
     document.querySelector('html').setAttribute(
         'data-startup', JSON.stringify(startup));
   }
diff --git a/src/options/optionsCommon.js b/src/options/optionsCommon.js
index abfc306..99874e5 100644
--- a/src/options/optionsCommon.js
+++ b/src/options/optionsCommon.js
@@ -35,6 +35,9 @@
       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;
@@ -239,6 +242,24 @@
                 .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 0de4df5..a5c9ff5 100644
--- a/src/options/optionsPage.json5
+++ b/src/options/optionsPage.json5
@@ -43,6 +43,7 @@
         {codename: 'enhancedannouncementsdot'},
         {codename: 'repositionexpandthread', experimental: true},
         {codename: 'imagemaxheight'},
+        {codename: 'interopthreadpage'},
       ],
     },
   ],
diff --git a/src/static/_locales/en/messages.json b/src/static/_locales/en/messages.json
index f6ac4be..23e03f6 100644
--- a/src/static/_locales/en/messages.json
+++ b/src/static/_locales/en/messages.json
@@ -159,6 +159,22 @@
     "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_nestedreplies": {
+    "message": "Turn on the nested replies feature in the Community Console.",
+    "description": "Feature checkbox in the options page"
+  },
   "options_save": {
     "message": "Save",
     "description": "Button in the options page to save the settings"
diff --git a/src/static/options/experiments.html b/src/static/options/experiments.html
index 9a21fdf..615d5ec 100644
--- a/src/static/options/experiments.html
+++ b/src/static/options/experiments.html
@@ -15,6 +15,7 @@
         <div id="optional-permissions-warning" hidden data-i18n="optionalpermissionswarning_header"></div>
         <div class="option"><input type="checkbox" id="workflows"> <label for="workflows" data-i18n="workflows"></label> <button id="manage-workflows" data-i18n="workflows_manage"></button></div>
         <div class="option"><input type="checkbox" id="extrainfo"> <label for="extrainfo" data-i18n="extrainfo"></label></div>
+        <div class="option"><input type="checkbox" id="nestedreplies"> <label for="nestedreplies" data-i18n="nestedreplies"></label></div>
         <div class="actions"><button id="save" data-i18n="save"></button></div>
       </form>
       <div id="save-indicator"></div>