refactor: migrate infinite scroll feature to a new architecture

This CL introduces a new architecture for the features source code.

Bug: twpowertools:176
Change-Id: I9abc4df2fb67f9bb0c9114aaffc6916d34f1b7ff
diff --git a/src/common/architecture/scripts/Script.ts b/src/common/architecture/scripts/Script.ts
new file mode 100644
index 0000000..5cca2c4
--- /dev/null
+++ b/src/common/architecture/scripts/Script.ts
@@ -0,0 +1,66 @@
+export enum ScriptRunPhase {
+  /**
+   * Executed before any Javascript is executed.
+   */
+  Start,
+  /**
+   * Executed after the document is ready.
+   */
+  Main,
+}
+
+export enum ScriptEnvironment {
+  ContentScript,
+  InjectedScript,
+}
+
+export enum ScriptPage {
+  CommunityConsole,
+}
+
+export const ScriptRunPhaseToRunTime: Record<
+  ScriptRunPhase,
+  chrome.userScripts.RunAt
+> = {
+  [ScriptRunPhase.Start]: 'document_start',
+  [ScriptRunPhase.Main]: 'document_idle',
+};
+
+export const ScriptEnvironmentToExecutionWorld: Record<
+  ScriptEnvironment,
+  chrome.scripting.ExecutionWorld
+> = {
+  [ScriptEnvironment.ContentScript]: 'ISOLATED',
+  [ScriptEnvironment.InjectedScript]: 'MAIN',
+};
+
+export type ConcreteScript = { new (): Script };
+
+export default abstract class Script {
+  /**
+   * Priority with which the script is executed. Scripts with a lower value are
+   * executed first.
+   */
+  readonly priority: Number = 2 ** 31;
+
+  /**
+   * Page where the script should be executed.
+   */
+  abstract readonly page: ScriptPage;
+
+  /**
+   * Environment where the script should be executed.
+   */
+  abstract readonly environment: ScriptEnvironment;
+
+  /**
+   * If {@link environment} is {@link ScriptEnvironment.ContentScript}, phase of
+   * the page loading when the script should be executed.
+   */
+  abstract readonly runPhase?: ScriptRunPhase;
+
+  /**
+   * Method which contains the logic of the script.
+   */
+  abstract execute(): void;
+}