refactor(thread-page-design-warning): migrate to the new DI architecture

Bug: twpowertools:176
Change-Id: I0f349e4dfe6fb4c13ff4b087f82529b1bdf66728
diff --git a/src/common/architecture/dependenciesProvider/DependenciesProvider.ts b/src/common/architecture/dependenciesProvider/DependenciesProvider.ts
index 02e25ce..ae50e33 100644
--- a/src/common/architecture/dependenciesProvider/DependenciesProvider.ts
+++ b/src/common/architecture/dependenciesProvider/DependenciesProvider.ts
@@ -4,6 +4,7 @@
 import WorkflowsImport from '../../../features/workflows/core/communityConsole/import';
 import StartupDataStorageAdapter from '../../../infrastructure/services/communityConsole/StartupDataStorage.adapter';
 import ReportDialogColorThemeFix from '../../../features/ccDarkTheme/core/logic/reportDialog';
+import ThreadPageDesignWarning from '../../../features/threadPageDesignWarning/core/threadPageDesignWarning';
 
 export const AutoRefreshDependency = 'autoRefresh';
 export const ExtraInfoDependency = 'extraInfo';
@@ -11,6 +12,7 @@
 export const ReportDialogColorThemeFixDependency =
   'report-dialog-color-theme-fix';
 export const StartupDataStorageDependency = 'startupDataStorage';
+export const ThreadPageDesignWarningDependency = 'threadPageDesignWarning';
 export const WorkflowsImportDependency = 'workflowsImport';
 export const DependenciesToClass = {
   [AutoRefreshDependency]: AutoRefresh,
@@ -18,6 +20,7 @@
   [OptionsProviderDependency]: OptionsProviderAdapter,
   [ReportDialogColorThemeFixDependency]: ReportDialogColorThemeFix,
   [StartupDataStorageDependency]: StartupDataStorageAdapter,
+  [ThreadPageDesignWarningDependency]: ThreadPageDesignWarning,
   [WorkflowsImportDependency]: WorkflowsImport,
 };
 
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index f5d5a47..890f3b0 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -43,9 +43,6 @@
   // Thread list (used for the autorefresh feature)
   'ec-thread-list',
 
-  // Thread page main content
-  'ec-thread > .page > .material-content > div[role="list"]',
-
   // Thread page reply section (for the thread page toolbar)
   kRepliesSectionSelector,
 
@@ -93,12 +90,6 @@
       avatars.injectIfEnabled(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);
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index 64bc2a0..f890bd0 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -2,13 +2,8 @@
 import {getOptions} from '../../common/options/optionsUtils.js';
 
 import FlattenThreadsReplyActionHandler from './flattenThreads/replyActionHandler.js';
-import ThreadPageDesignWarning from './threadPageDesignWarning.js';
 
 getOptions(null).then(options => {
-  // Initialized here instead of in main.js so the first event is received if it
-  // happens when the page loads.
-  window.TWPTThreadPageDesignWarning = new ThreadPageDesignWarning();
-
   if (options.uispacing) {
     injectStylesheet(chrome.runtime.getURL('css/ui_spacing/shared.css'));
     injectStylesheet(chrome.runtime.getURL('css/ui_spacing/console.css'));
diff --git a/src/entryPoints/communityConsole/contentScripts/main.ts b/src/entryPoints/communityConsole/contentScripts/main.ts
index 47ec269..35088ea 100644
--- a/src/entryPoints/communityConsole/contentScripts/main.ts
+++ b/src/entryPoints/communityConsole/contentScripts/main.ts
@@ -6,6 +6,7 @@
   ExtraInfoDependency,
   OptionsProviderDependency,
   StartupDataStorageDependency,
+  ThreadPageDesignWarningDependency,
   WorkflowsImportDependency,
 } from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
 import AutoRefreshThreadListHideHandler from '../../../features/autoRefresh/presentation/nodeWatcherHandlers/threadListHide.handler';
@@ -40,6 +41,7 @@
 import CCExtraInfoStylesScript from '../../../features/extraInfo/presentation/scripts/ccExtraInfoStyles.script';
 import InjectLitComponentsScript from '../../../presentation/standaloneScripts/litComponents/injectLitComponents.script';
 import ApplyStartupDataModificationsOnMainScript from '../../../presentation/standaloneScripts/startupDataStorage/applyStartupDataModificationsOnMain.script';
+import ThreadPageDesignWarningInjectHandler from '../../../features/threadPageDesignWarning/presentation/nodeWatcherHandlers/inject.handler';
 
 const scriptRunner = createScriptRunner();
 scriptRunner.run();
@@ -54,6 +56,9 @@
   const startupDataStorage = dependenciesProvider.getDependency(
     StartupDataStorageDependency,
   );
+  const threadPageDesignWarning = dependenciesProvider.getDependency(
+    ThreadPageDesignWarningDependency,
+  );
   const workflowsImport = dependenciesProvider.getDependency(
     WorkflowsImportDependency,
   );
@@ -128,6 +133,10 @@
               new CCInfiniteScrollLoadMoreBtnHandler(ccInfiniteScroll),
             ],
             [
+              'threadPageDesignWarningInject',
+              new ThreadPageDesignWarningInjectHandler(threadPageDesignWarning),
+            ],
+            [
               'workflowsImportCRTags',
               new WorkflowsImportCRTagsHandler(workflowsImport),
             ],
diff --git a/src/entryPoints/communityConsole/contentScripts/start.ts b/src/entryPoints/communityConsole/contentScripts/start.ts
index 1d02a6b..72302ff 100644
--- a/src/entryPoints/communityConsole/contentScripts/start.ts
+++ b/src/entryPoints/communityConsole/contentScripts/start.ts
@@ -6,6 +6,7 @@
   ExtraInfoDependency,
   OptionsProviderDependency,
   StartupDataStorageDependency,
+  ThreadPageDesignWarningDependency,
   WorkflowsImportDependency,
 } from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
 import AutoRefreshSetUpScript from '../../../features/autoRefresh/presentation/scripts/setUp.script';
@@ -22,6 +23,7 @@
 import MWOptionsWatcherServerScript from '../../../presentation/standaloneScripts/mainWorldServers/MWOptionsWatcherServerScript.script';
 import ApplyStartupDataModificationsOnStartScript from '../../../presentation/standaloneScripts/startupDataStorage/applyStartupDataModificationsOnStart.script';
 import XHRInterceptorScript from '../../../presentation/standaloneScripts/xhrInterceptor/xhrInterceptor.script';
+import ThreadPageDesignWarningSetUpScript from '../../../features/threadPageDesignWarning/presentation/scripts/setUp.script';
 
 const scriptRunner = createScriptRunner();
 scriptRunner.run();
@@ -36,6 +38,9 @@
   const startupDataStorage = dependenciesProvider.getDependency(
     StartupDataStorageDependency,
   );
+  const threadPageDesignWarning = dependenciesProvider.getDependency(
+    ThreadPageDesignWarningDependency,
+  );
   const workflowsImport = dependenciesProvider.getDependency(
     WorkflowsImportDependency,
   );
@@ -49,6 +54,9 @@
         new CCDarkThemeInjectForcedDarkTheme(),
         new CCExtraInfoSetUpScript(extraInfo),
         new InteropThreadPageSetupScript(),
+        new ThreadPageDesignWarningSetUpScript(
+          threadPageDesignWarning,
+        ),
         new LoadDraftsSetupScript(optionsProvider, startupDataStorage),
         new WorkflowsImportSetUpScript(workflowsImport),
 
diff --git a/src/contentScripts/communityConsole/threadPageDesignWarning.js b/src/features/threadPageDesignWarning/core/threadPageDesignWarning.js
similarity index 87%
rename from src/contentScripts/communityConsole/threadPageDesignWarning.js
rename to src/features/threadPageDesignWarning/core/threadPageDesignWarning.js
index 955108a..dca9201 100644
--- a/src/contentScripts/communityConsole/threadPageDesignWarning.js
+++ b/src/features/threadPageDesignWarning/core/threadPageDesignWarning.js
@@ -1,18 +1,25 @@
 import {MDCTooltip} from '@material/tooltip';
 import {waitFor} from 'poll-until-promise';
 
-import {parseUrl} from '../../common/commonUtils.js';
-import {injectStylesheet} from '../../common/contentScriptsUtils';
-import {getDocURL} from '../../common/extUtils.js';
-import {getOptions} from '../../common/options/optionsUtils.js';
+import {parseUrl} from '../../../common/commonUtils.js';
+import {injectStylesheet} from '../../../common/contentScriptsUtils';
+import {getDocURL} from '../../../common/extUtils.js';
+import {getOptions} from '../../../common/options/optionsUtils.js';
 
-import {createExtBadge} from './utils/common.js';
+import {createExtBadge} from '../../../contentScripts/communityConsole/utils/common.js';
 
 const kSMEINestedReplies = 15;
 const kViewThreadResponse = 'TWPT_ViewThreadResponse';
 
 export default class ThreadPageDesignWarning {
   constructor() {
+    this.isSetUp = false;
+  }
+
+  setUp() {
+    if (this.isSetUp) return;
+
+    this.isSetUp = true;
     this.lastThread = {
       body: {},
       id: -1,
@@ -110,9 +117,15 @@
   injectWarningIfApplicable(content) {
     return waitFor(
                () => {
-                 if (this.shouldShowWarning === undefined)
+                 if (!this.setUp) {
+                   return Promise.reject(new Error(
+                       'ThreadPageDesignWarning hasn\'t been set up yet.'));
+                 }
+
+                 if (this.shouldShowWarning === undefined) {
                    return Promise.reject(
                        new Error('shouldShowWarning is not defined.'));
+                 }
 
                  return Promise.resolve({result: this.shouldShowWarning});
                },
diff --git a/src/features/threadPageDesignWarning/presentation/nodeWatcherHandlers/inject.handler.ts b/src/features/threadPageDesignWarning/presentation/nodeWatcherHandlers/inject.handler.ts
new file mode 100644
index 0000000..1a016fc
--- /dev/null
+++ b/src/features/threadPageDesignWarning/presentation/nodeWatcherHandlers/inject.handler.ts
@@ -0,0 +1,16 @@
+import CssSelectorNodeWatcherHandler from '../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ThreadPageDesignWarning from '../../core/threadPageDesignWarning';
+
+/** Inject old thread page design warning if applicable */
+export default class ThreadPageDesignWarningInjectHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector = 'ec-thread > .page > .material-content > div[role="list"]';
+
+  constructor(private threadPageDesignWarning: ThreadPageDesignWarning) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.threadPageDesignWarning.injectWarningIfApplicable(node);
+  }
+}
diff --git a/src/features/threadPageDesignWarning/presentation/scripts/setUp.script.ts b/src/features/threadPageDesignWarning/presentation/scripts/setUp.script.ts
new file mode 100644
index 0000000..5dc600e
--- /dev/null
+++ b/src/features/threadPageDesignWarning/presentation/scripts/setUp.script.ts
@@ -0,0 +1,17 @@
+import Script from '../../../../common/architecture/scripts/Script';
+import ThreadPageDesignWarning from '../../core/threadPageDesignWarning';
+
+export default class ThreadPageDesignWarningSetUpScript extends Script {
+  priority = 102;
+  page: never;
+  environment: never;
+  runPhase: never;
+
+  constructor(private threadPageDesignWarning: ThreadPageDesignWarning) {
+    super();
+  }
+
+  execute() {
+    this.threadPageDesignWarning.setUp();
+  }
+}
diff --git a/src/features/workflows/presentation/scripts/importSetUp.script.ts b/src/features/workflows/presentation/scripts/importSetUp.script.ts
index 73edf50..3f0807c 100644
--- a/src/features/workflows/presentation/scripts/importSetUp.script.ts
+++ b/src/features/workflows/presentation/scripts/importSetUp.script.ts
@@ -2,7 +2,7 @@
 import WorkflowsImport from '../../core/communityConsole/import';
 
 export default class WorkflowsImportSetUpScript extends Script {
-  priority = 102;
+  priority = 103;
   page: never;
   environment: never;
   runPhase: never;