refactor(extra-info): migrate to the new DI architecture

Bug: twpowertools:226
Change-Id: Icaf98068bf5a272bf00a2b6b71e7ee40e3845d76
diff --git a/src/entryPoints/communityConsole/contentScripts/main.ts b/src/entryPoints/communityConsole/contentScripts/main.ts
index 1cc7e21..4812d53 100644
--- a/src/entryPoints/communityConsole/contentScripts/main.ts
+++ b/src/entryPoints/communityConsole/contentScripts/main.ts
@@ -3,6 +3,7 @@
 
 import DependenciesProviderSingleton, {
   AutoRefreshDependency,
+  ExtraInfoDependency,
   OptionsProviderDependency,
   WorkflowsImportDependency,
 } from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
@@ -35,6 +36,15 @@
 import WorkflowsImportCRTagsHandler from '../../../features/workflows/presentation/nodeWatcherHandlers/crTags.handler';
 import Workflows from '../../../features/workflows/core/communityConsole/workflows';
 import WorkflowsImportStylesheetScript from '../../../features/workflows/presentation/scripts/importStylesheet';
+import CCExtraInfoProfileAbuseChipsHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler';
+import CCExtraInfoProfilePerForumStatsHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler';
+import CCExtraInfoThreadCommentHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler';
+import CCExtraInfoThreadListHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler';
+import CCExtraInfoThreadListToolbeltHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler';
+import CCExtraInfoThreadQuestionHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler';
+import CCExtraInfoThreadReplyHandler from '../../../features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler';
+import CCExtraInfoInjectScript from '../../../features/extraInfo/presentation/scripts/ccExtraInfoInject.script';
+import CCExtraInfoStylesScript from '../../../features/extraInfo/presentation/scripts/ccExtraInfoStyles.script';
 
 const scriptRunner = createScriptRunner();
 scriptRunner.run();
@@ -42,6 +52,7 @@
 function createScriptRunner() {
   const dependenciesProvider = DependenciesProviderSingleton.getInstance();
   const autoRefresh = dependenciesProvider.getDependency(AutoRefreshDependency);
+  const extraInfo = dependenciesProvider.getDependency(ExtraInfoDependency);
   const optionsProvider = dependenciesProvider.getDependency(
     OptionsProviderDependency,
   );
@@ -85,6 +96,34 @@
               new CCDarkThemeUnifiedProfilesIframeHandler(optionsProvider),
             ],
             [
+              'ccExtraInfoProfile',
+              new CCExtraInfoProfileAbuseChipsHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoProfilePerForumStats',
+              new CCExtraInfoProfilePerForumStatsHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoThreadComment',
+              new CCExtraInfoThreadCommentHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoThreadList',
+              new CCExtraInfoThreadListHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoThreadListToolbelt',
+              new CCExtraInfoThreadListToolbeltHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoThreadQuestion',
+              new CCExtraInfoThreadQuestionHandler(extraInfo),
+            ],
+            [
+              'ccExtraInfoThreadReply',
+              new CCExtraInfoThreadReplyHandler(extraInfo),
+            ],
+            [
               'ccInfiniteScrollSetUp',
               new CCInfiniteScrollSetUpHandler(ccInfiniteScroll),
             ],
@@ -109,6 +148,8 @@
 
         // Individual feature scripts
         new AutoRefreshStylesScript(),
+        new CCExtraInfoInjectScript(),
+        new CCExtraInfoStylesScript(),
         new WorkflowsImportStylesheetScript(),
 
         // Non-DI scripts (legacy, should be migrated to use a DI approach)
diff --git a/src/entryPoints/communityConsole/contentScripts/start.ts b/src/entryPoints/communityConsole/contentScripts/start.ts
index 9ffdd95..4cbfd9d 100644
--- a/src/entryPoints/communityConsole/contentScripts/start.ts
+++ b/src/entryPoints/communityConsole/contentScripts/start.ts
@@ -3,6 +3,7 @@
 
 import DependenciesProviderSingleton, {
   AutoRefreshDependency,
+  ExtraInfoDependency,
   OptionsProviderDependency,
   StartupDataStorageDependency,
   WorkflowsImportDependency,
@@ -24,6 +25,7 @@
 import StandaloneScripts from '../../../scripts/Scripts';
 import LoadDraftsSetupScript from '../../../features/loadDrafts/presentation/scripts/setup.script';
 import WorkflowsImportSetUpScript from '../../../features/workflows/presentation/scripts/importSetUp.script';
+import CCExtraInfoSetUpScript from '../../../features/extraInfo/presentation/scripts/ccExtraInfoSetUp.script';
 
 const scriptRunner = createScriptRunner();
 scriptRunner.run();
@@ -31,6 +33,7 @@
 function createScriptRunner() {
   const dependenciesProvider = DependenciesProviderSingleton.getInstance();
   const autoRefresh = dependenciesProvider.getDependency(AutoRefreshDependency);
+  const extraInfo = dependenciesProvider.getDependency(ExtraInfoDependency);
   const optionsProvider = dependenciesProvider.getDependency(
     OptionsProviderDependency,
   );
@@ -54,6 +57,7 @@
         new AutoRefreshSetUpScript(autoRefresh),
         new CCDarkThemeInjectAutoDarkTheme(),
         new CCDarkThemeInjectForcedDarkTheme(),
+        new CCExtraInfoSetUpScript(extraInfo),
         new InteropThreadPageSetupScript(),
         new LoadDraftsSetupScript(optionsProvider, startupDataStorage),
         new WorkflowsImportSetUpScript(workflowsImport),
diff --git a/src/features/Features.ts b/src/features/Features.ts
index b79d4fa..f3c9c98 100644
--- a/src/features/Features.ts
+++ b/src/features/Features.ts
@@ -1,13 +1,10 @@
 import Feature from '../common/architecture/features/Feature';
 import ScriptFilterListProvider from '../common/architecture/scripts/ScriptFilterListProvider';
-import ExtraInfoFeature from './extraInfo/extraInfo.feature';
 
 export type ConcreteFeatureClass = { new (): Feature };
 
 export default class Features extends ScriptFilterListProvider {
-  private features: ConcreteFeatureClass[] = [
-    ExtraInfoFeature,
-  ];
+  private features: ConcreteFeatureClass[] = [];
   private initializedFeatures: Feature[];
 
   protected getUnfilteredScriptsList() {
diff --git a/src/features/extraInfo/core/index.js b/src/features/extraInfo/core/index.js
index 29ae400..43268be 100644
--- a/src/features/extraInfo/core/index.js
+++ b/src/features/extraInfo/core/index.js
@@ -12,7 +12,7 @@
 import ThreadReplyExtraInfoInjection from './injections/threadReply.js';
 
 export default class ExtraInfo {
-  constructor() {
+  setUp() {
     const optionsWatcher = new PartialOptionsWatcher(['extrainfo', 'perforumstats']);
 
     const profileInfoHandler = new ProfileInfoHandler();
diff --git a/src/features/extraInfo/extraInfo.feature.ts b/src/features/extraInfo/extraInfo.feature.ts
deleted file mode 100644
index 0f2ccd7..0000000
--- a/src/features/extraInfo/extraInfo.feature.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import Feature from '../../common/architecture/features/Feature';
-import { ConcreteScript } from '../../common/architecture/scripts/Script';
-import { OptionCodename } from '../../common/options/optionsPrototype';
-import CCExtraInfoDependencySetUpScript from './scripts/ccExtraInfoDependencySetUp.script';
-import CCExtraInfoInjectScript from './scripts/ccExtraInfoInject.script';
-import CCExtraInfoMainScript from './scripts/ccExtraInfoMain.script';
-import CCExtraInfoStylesScript from './scripts/ccExtraInfoStyles.script';
-
-export default class ExtraInfoFeature extends Feature {
-  public readonly scripts: ConcreteScript[] = [
-    CCExtraInfoDependencySetUpScript,
-    CCExtraInfoInjectScript,
-    CCExtraInfoMainScript,
-    CCExtraInfoStylesScript,
-  ];
-
-  readonly codename = 'extraInfo';
-  readonly relatedOptions: OptionCodename[] = ['extrainfo', 'perforumstats'];
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts
deleted file mode 100644
index 482a456..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-export default class CCExtraInfoProfileAbuseChipsHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'ec-unified-user .scTailwindUser_profileUsercardmain';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAbuseChipsAtProfileIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts
deleted file mode 100644
index bd2bb1c..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-export default class CCExtraInfoProfilePerForumStatsHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector =
-    'ec-unified-user .scTailwindUser_profileUserprofilesection sc-tailwind-shared-activity-chart';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectPerForumStatsIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts
deleted file mode 100644
index 5527e1a..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-/**
- * Inject extra info to threads in the thread list.
- */
-export default class CCExtraInfoThreadCommentHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'sc-tailwind-thread-message-message-list sc-tailwind-thread-message-comment-card';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAtCommentIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts
deleted file mode 100644
index 028b9a3..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-/**
- * Inject extra info to threads in the thread list.
- */
-export default class CCExtraInfoThreadQuestionHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'sc-tailwind-thread-question-question-card sc-tailwind-thread-question-state-chips';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAtQuestionIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts
deleted file mode 100644
index 94ad753..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-/**
- * Inject extra info to threads in the thread list.
- */
-export default class CCExtraInfoThreadReplyHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'sc-tailwind-thread-message-message-list sc-tailwind-thread-message-message-card';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAtReplyIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts
deleted file mode 100644
index d2e7008..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-/**
- * Inject extra info to threads in the thread list.
- */
-export default class CCExtraInfoThreadListHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'li:has(ec-thread-summary)';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAtThreadListIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts b/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts
deleted file mode 100644
index d28f6f8..0000000
--- a/src/features/extraInfo/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import CssSelectorNodeWatcherScriptHandler from '../../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
-import { NodeMutation } from '../../../../presentation/nodeWatcher/NodeWatcherHandler';
-import { CCExtraInfoMainOptions } from '../../scripts/ccExtraInfoMain.script';
-
-/**
- * Inject extra info in the toolbelt of an expanded thread list item.
- */
-export default class CCExtraInfoThreadListToolbeltHandler extends CssSelectorNodeWatcherScriptHandler<CCExtraInfoMainOptions> {
-  cssSelector = 'ec-thread-summary .main .toolbelt';
-
-  onMutatedNode({ node }: NodeMutation) {
-    this.options.extraInfo.injectAtExpandedThreadListIfEnabled(node);
-  }
-}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts
new file mode 100644
index 0000000..98f40f4
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler.ts
@@ -0,0 +1,16 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject abuse info chip in profiles. */
+export default class CCExtraInfoProfileAbuseChipsHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector = 'ec-unified-user .scTailwindUser_profileUsercardmain';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAbuseChipsAtProfileIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts
new file mode 100644
index 0000000..8bc543e
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject a per-forum stats section in profiles. */
+export default class CCExtraInfoProfilePerForumStatsHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector =
+    'ec-unified-user .scTailwindUser_profileUserprofilesection sc-tailwind-shared-activity-chart';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectPerForumStatsIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts
new file mode 100644
index 0000000..f3e8c3c
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject extra info in comments. */
+export default class CCExtraInfoThreadCommentHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector =
+    'sc-tailwind-thread-message-message-list sc-tailwind-thread-message-comment-card';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAtCommentIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts
new file mode 100644
index 0000000..2a694c5
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject extra info in questions. */
+export default class CCExtraInfoThreadQuestionHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector =
+    'sc-tailwind-thread-question-question-card sc-tailwind-thread-question-state-chips';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAtQuestionIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts
new file mode 100644
index 0000000..dbfac69
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject extra info in replies. */
+export default class CCExtraInfoThreadReplyHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector =
+    'sc-tailwind-thread-message-message-list sc-tailwind-thread-message-message-card';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAtReplyIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts
new file mode 100644
index 0000000..71bf38a
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler.ts
@@ -0,0 +1,16 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject extra info to threads in the thread list. */
+export default class CCExtraInfoThreadListHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector = 'li:has(ec-thread-summary)';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAtThreadListIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts b/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts
new file mode 100644
index 0000000..bc1fe6a
--- /dev/null
+++ b/src/features/extraInfo/presentation/nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler.ts
@@ -0,0 +1,16 @@
+import CssSelectorNodeWatcherHandler from '../../../../../infrastructure/presentation/nodeWatcher/handlers/CssSelectorHandler.adapter';
+import { NodeMutation } from '../../../../../presentation/nodeWatcher/NodeWatcherHandler';
+import ExtraInfo from '../../../core';
+
+/** Inject extra info in the toolbelt of an expanded thread list item. */
+export default class CCExtraInfoThreadListToolbeltHandler extends CssSelectorNodeWatcherHandler {
+  cssSelector = 'ec-thread-summary .main .toolbelt';
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  onMutatedNode({ node }: NodeMutation) {
+    this.extraInfo.injectAtExpandedThreadListIfEnabled(node);
+  }
+}
diff --git a/src/features/extraInfo/presentation/scripts/ccExtraInfoInject.script.ts b/src/features/extraInfo/presentation/scripts/ccExtraInfoInject.script.ts
new file mode 100644
index 0000000..e268d28
--- /dev/null
+++ b/src/features/extraInfo/presentation/scripts/ccExtraInfoInject.script.ts
@@ -0,0 +1,14 @@
+import Script from '../../../../common/architecture/scripts/Script';
+import { injectScript } from '../../../../common/contentScriptsUtils';
+
+export default class CCExtraInfoInjectScript extends Script {
+  priority = 11;
+
+  page: never;
+  environment: never;
+  runPhase: never;
+
+  execute() {
+    injectScript(chrome.runtime.getURL('extraInfoInject.bundle.js'));
+  }
+}
diff --git a/src/features/extraInfo/presentation/scripts/ccExtraInfoSetUp.script.ts b/src/features/extraInfo/presentation/scripts/ccExtraInfoSetUp.script.ts
new file mode 100644
index 0000000..9c4df76
--- /dev/null
+++ b/src/features/extraInfo/presentation/scripts/ccExtraInfoSetUp.script.ts
@@ -0,0 +1,17 @@
+import Script from '../../../../common/architecture/scripts/Script';
+import ExtraInfo from '../../core';
+
+export default class CCExtraInfoSetUpScript extends Script {
+  public priority = 101;
+  public page: never;
+  public environment: never;
+  public runPhase: never;
+
+  constructor(private extraInfo: ExtraInfo) {
+    super();
+  }
+
+  execute() {
+    this.extraInfo.setUp();
+  }
+}
diff --git a/src/features/extraInfo/presentation/scripts/ccExtraInfoStyles.script.ts b/src/features/extraInfo/presentation/scripts/ccExtraInfoStyles.script.ts
new file mode 100644
index 0000000..9395895
--- /dev/null
+++ b/src/features/extraInfo/presentation/scripts/ccExtraInfoStyles.script.ts
@@ -0,0 +1,13 @@
+import Script from '../../../../common/architecture/scripts/Script';
+import { injectStylesheet } from '../../../../common/contentScriptsUtils';
+
+export default class CCExtraInfoStylesScript extends Script {
+  page: never;
+  environment: never;
+  runPhase: never;
+
+  execute() {
+    injectStylesheet(chrome.runtime.getURL('css/extrainfo.css'));
+    injectStylesheet(chrome.runtime.getURL('css/extrainfo_perforumstats.css'));
+  }
+}
diff --git a/src/features/extraInfo/scripts/ccExtraInfoDependencySetUp.script.ts b/src/features/extraInfo/scripts/ccExtraInfoDependencySetUp.script.ts
deleted file mode 100644
index cd595c5..0000000
--- a/src/features/extraInfo/scripts/ccExtraInfoDependencySetUp.script.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Dependency, ExtraInfoDependency } from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
-import {
-  ScriptEnvironment,
-  ScriptPage,
-  ScriptRunPhase,
-} from '../../../common/architecture/scripts/Script';
-import SetUpDependenciesScript from '../../../common/architecture/scripts/setUpDependencies/SetUpDependenciesScript';
-
-export default class CCExtraInfoDependencySetUpScript extends SetUpDependenciesScript {
-  public priority = 101;
-  public page = ScriptPage.CommunityConsole;
-  public environment = ScriptEnvironment.ContentScript;
-  public runPhase = ScriptRunPhase.Start;
-  public dependencies: Dependency[] = [ExtraInfoDependency];
-}
diff --git a/src/features/extraInfo/scripts/ccExtraInfoInject.script.ts b/src/features/extraInfo/scripts/ccExtraInfoInject.script.ts
deleted file mode 100644
index 2bd6364..0000000
--- a/src/features/extraInfo/scripts/ccExtraInfoInject.script.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Script, { ScriptEnvironment, ScriptPage, ScriptRunPhase } from "../../../common/architecture/scripts/Script";
-import { injectScript } from "../../../common/contentScriptsUtils";
-
-export default class CCExtraInfoInjectScript extends Script {
-  priority = 11;
-
-  page = ScriptPage.CommunityConsole;
-  environment = ScriptEnvironment.ContentScript;
-  runPhase = ScriptRunPhase.Start;
-
-  execute() {
-    injectScript(chrome.runtime.getURL('extraInfoInject.bundle.js'));
-  }
-}
diff --git a/src/features/extraInfo/scripts/ccExtraInfoMain.script.ts b/src/features/extraInfo/scripts/ccExtraInfoMain.script.ts
deleted file mode 100644
index 199ff18..0000000
--- a/src/features/extraInfo/scripts/ccExtraInfoMain.script.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import DependenciesProviderSingleton, {
-  ExtraInfoDependency,
-} from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
-import {
-  ScriptEnvironment,
-  ScriptPage,
-  ScriptRunPhase,
-} from '../../../common/architecture/scripts/Script';
-import LegacyNodeWatcherScript from '../../../common/architecture/scripts/nodeWatcher/LegacyNodeWatcherScript';
-import ExtraInfo from '../core';
-import CCExtraInfoProfileAbuseChipsHandler from '../nodeWatcherHandlers/profile/ccExtraInfoProfileAbuseChips.handler';
-import CCExtraInfoProfilePerForumStatsHandler from '../nodeWatcherHandlers/profile/ccExtraInfoProfilePerForumStats.handler';
-import CCExtraInfoThreadCommentHandler from '../nodeWatcherHandlers/thread/ccExtraInfoThreadComment.handler';
-import CCExtraInfoThreadListHandler from '../nodeWatcherHandlers/threadList/ccExtraInfoThreadList.handler';
-import CCExtraInfoThreadListToolbeltHandler from '../nodeWatcherHandlers/threadList/ccExtraInfoThreadListToolbelt.handler';
-import CCExtraInfoThreadQuestionHandler from '../nodeWatcherHandlers/thread/ccExtraInfoThreadQuestion.handler';
-import CCExtraInfoThreadReplyHandler from '../nodeWatcherHandlers/thread/ccExtraInfoThreadReply.handler';
-
-export interface CCExtraInfoMainOptions {
-  extraInfo: ExtraInfo;
-}
-
-export default class CCExtraInfoMainScript extends LegacyNodeWatcherScript<CCExtraInfoMainOptions> {
-  page = ScriptPage.CommunityConsole;
-  environment = ScriptEnvironment.ContentScript;
-  runPhase = ScriptRunPhase.Main;
-  handlers = new Map([
-    ['ccExtraInfoProfile', CCExtraInfoProfileAbuseChipsHandler],
-    ['ccExtraInfoProfilePerForumStats', CCExtraInfoProfilePerForumStatsHandler],
-    ['ccExtraInfoThreadComment', CCExtraInfoThreadCommentHandler],
-    ['ccExtraInfoThreadList', CCExtraInfoThreadListHandler],
-    ['ccExtraInfoThreadListToolbelt', CCExtraInfoThreadListToolbeltHandler],
-    ['ccExtraInfoThreadQuestion', CCExtraInfoThreadQuestionHandler],
-    ['ccExtraInfoThreadReply', CCExtraInfoThreadReplyHandler],
-  ]);
-
-  protected optionsFactory(): CCExtraInfoMainOptions {
-    const dependenciesProvider = DependenciesProviderSingleton.getInstance();
-    return {
-      extraInfo: dependenciesProvider.getDependency(ExtraInfoDependency),
-    };
-  }
-}
diff --git a/src/features/extraInfo/scripts/ccExtraInfoStyles.script.ts b/src/features/extraInfo/scripts/ccExtraInfoStyles.script.ts
deleted file mode 100644
index 4d806f6..0000000
--- a/src/features/extraInfo/scripts/ccExtraInfoStyles.script.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import Script, {
-  ScriptEnvironment,
-  ScriptPage,
-  ScriptRunPhase,
-} from '../../../common/architecture/scripts/Script';
-import { injectStylesheet } from '../../../common/contentScriptsUtils';
-
-export default class CCExtraInfoStylesScript extends Script {
-  page = ScriptPage.CommunityConsole;
-  environment = ScriptEnvironment.ContentScript;
-  runPhase = ScriptRunPhase.Main;
-
-  execute() {
-    injectStylesheet(chrome.runtime.getURL('css/extrainfo.css'));
-    injectStylesheet(chrome.runtime.getURL('css/extrainfo_perforumstats.css'));
-  }
-}