feat(cc-redirect): redirect URL hash and add redundant redirect method

This CL adds logic to redirect the URL hash to the Community Console,
so actions that are embedded in the URL like |#action=reply| will be
passed to the Community Console.

It also adds another method of redirecting to the Community Console
which will coexist with the old method.

Fixed: twpowertools:164
Change-Id: Ib3f770d7cbeec8f26cdd249e66f7f46ae94bb1c8
diff --git a/src/contentScripts/publicProfile.js b/src/contentScripts/publicProfile.js
index 6c3da8d..9c36ae1 100644
--- a/src/contentScripts/publicProfile.js
+++ b/src/contentScripts/publicProfile.js
@@ -1,10 +1,10 @@
 import {getOptions} from '../common/optionsUtils.js';
-import {correctArrayKeys} from '../common/protojs.js';
+import {parseView} from '../common/TWBasicUtils.js';
 
 import PerForumStatsSection from './communityConsole/utils/PerForumStatsSection.js';
 import {injectPreviousPostsLinksUnifiedProfile} from './utilsCommon/unifiedProfiles.js';
 
-const profileViewRegex = /var view ?= ?'([^']+)';/;
+const kProfileViewVar = 'view';
 
 getOptions(['history', 'perforumstats']).then(options => {
   if (options?.history)
@@ -20,27 +20,8 @@
       if (!chart) throw new Error('Couldn\'t find existing chart.');
 
       // Extract profile JSON information
-      const scripts = document.querySelectorAll('script');
-      let profileView = null;
-      for (let i = 0; i < scripts.length; ++i) {
-        const matches = scripts[i].textContent.match(profileViewRegex);
-        if (matches?.[1]) {
-          let rawJsonStringContents =
-              matches[1]
-                  .replace(
-                      /\\x([0-9a-f]{2})/ig,
-                      (_, pair) => {
-                        return String.fromCharCode(parseInt(pair, 16));
-                      })
-                  .replace(/\\'/g, `'`)
-                  .replace(/"/g, `\\"`);
-          let rawJsonString = `"${rawJsonStringContents}"`;
-          let rawJson = JSON.parse(rawJsonString);
-          profileView = JSON.parse(rawJson);
-          break;
-        }
-      }
-      const profileViewC = {'1': correctArrayKeys(profileView)};
+      const profileView = parseView(kProfileViewVar);
+      const profileViewC = {'1': profileView};
       if (!profileView) throw new Error('Could not find user view data.');
       new PerForumStatsSection(
           chart?.parentNode, profileViewC,