refactor: migrate CC dark theme feature to the new architecture

Bug: twpowertools:176
Change-Id: Iaea1015a788038a8a31acbdd33b267b551e0b6a1
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts
new file mode 100644
index 0000000..12d50bb
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts
@@ -0,0 +1,26 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { injectDarkThemeButton } from '../core/logic/darkTheme';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Injects the dark theme button.
+ */
+export default class CCDarkThemeEcAppHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+  cssSelector = 'ec-app';
+
+  async onMutatedNode(mutation: NodeMutation) {
+    if (!(mutation.node instanceof Element)) return;
+
+    const optionsProvider = this.options.optionsProvider;
+    const isEnabled = await optionsProvider.isEnabled('ccdarktheme');
+    const mode = await optionsProvider.getOptionValue('ccdarktheme_mode');
+
+    // TODO(avm99963): make this feature dynamic.
+    if (isEnabled && mode === 'switch') {
+      const rightControl = mutation.node.querySelector('header .right-control');
+      if (rightControl === null) return;
+      injectDarkThemeButton(rightControl);
+    }
+  }
+}
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts
new file mode 100644
index 0000000..83942e5
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Sets the report dialog iframe's theme to the appropriate theme.
+ */
+export default class CCDarkThemeReportDialogHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+  cssSelector = 'iframe';
+
+  onMutatedNode(mutation: NodeMutation) {
+    this.options.reportDialogColorThemeFix.fixThemeIfReportDialogIframeAndApplicable(
+      mutation.node,
+      this.options.optionsProvider,
+    );
+  }
+}
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts
new file mode 100644
index 0000000..b71b9a7
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts
@@ -0,0 +1,23 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { isDarkThemeOn } from '../core/logic/darkTheme';
+import { unifiedProfilesFix } from '../core/logic/unifiedProfiles';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Redirect unified profile iframe to dark version if applicable
+ */
+export default class CCDarkThemeUnifiedProfilesIframeHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+  cssSelector = 'iframe';
+
+  async onMutatedNode(mutation: NodeMutation) {
+    const optionsValues = await this.options.optionsProvider.getOptionsValues();
+
+    if (
+      isDarkThemeOn(optionsValues) &&
+      unifiedProfilesFix.checkIframe(mutation.node)
+    ) {
+      unifiedProfilesFix.fixIframe(mutation.node);
+    }
+  }
+}