Add "previous posts" support to unified profiles in CC

The Community Console used to embed profiles from TW via an iframe, so
the logic to add the "previous posts" link was only added to TW.

However, the CC now renders the profiles without an iframe, with the
exact same layout as TW. This change adds support to add the "previous
posts" link in the CC, which reuses existing code (which has been
abstracted).

Fixed: twpowertools:78
Change-Id: I511af1e8aab1292f34beb712f29d52df9409e352
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index d16a863..6b32496 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -1,5 +1,6 @@
 import {injectScript, injectStyles, injectStylesheet} from '../../common/contentScriptsUtils.js';
 import {getOptions, isOptionEnabled} from '../../common/optionsUtils.js';
+import {injectPreviousPostsLinksUnifiedProfileIfEnabled} from '../utilsCommon/unifiedProfiles.js';
 
 import AvatarsHandler from './avatars.js';
 import {batchLock} from './batchLock.js';
@@ -22,6 +23,7 @@
   // Username span/editor inside ec-user (user profile view)
   'ec-user .main-card .header > .name > span',
   'ec-user .main-card .header > .name > ec-display-name-editor',
+  'ec-unified-user .scTailwindUser_profileUsercarddetails',
 
   // Rich text editor
   'ec-movable-dialog',
@@ -89,12 +91,20 @@
 
     // Show the "previous posts" links if the option is currently enabled.
     //   Here we're selecting the 'ec-user > div' element (unique child)
+
+    // TODO(b/twpowertools/80): Remove this:
     if (node.matches('ec-user .main-card .header > .name > span') ||
         node.matches(
             'ec-user .main-card .header > .name > ec-display-name-editor')) {
       injectPreviousPostsLinksIfEnabled(node);
     }
 
+    if (node.matches(
+            'ec-unified-user .scTailwindUser_profileUsercarddetails')) {
+      injectPreviousPostsLinksUnifiedProfileIfEnabled(
+          /* isCommunityConsole = */ true);
+    }
+
     // Fix the drag&drop issue with the rich text editor if the option is
     // currently enabled.
     //
diff --git a/src/contentScripts/profile.js b/src/contentScripts/profile.js
index 49422a5..7bd6916 100644
--- a/src/contentScripts/profile.js
+++ b/src/contentScripts/profile.js
@@ -1,68 +1,9 @@
 import {escapeUsername} from '../common/communityConsoleUtils.js';
 import {getOptions} from '../common/optionsUtils.js';
 
-var authuser = (new URL(location.href)).searchParams.get('authuser') || '0';
+import {getSearchUrl, injectPreviousPostsLinksUnifiedProfile} from './utilsCommon/unifiedProfiles.js';
 
-function getSearchUrl(query) {
-  var urlpart = encodeURIComponent('query=' + encodeURIComponent(query));
-  var authuserpart =
-      (authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser));
-  return 'https://support.google.com/s/community/search/' + urlpart +
-      authuserpart;
-}
-
-function injectPreviousPostsLinksUnifiedProfile() {
-  var nameElement =
-      document.querySelector('.scTailwindUser_profileUsercardname');
-  if (nameElement === null) {
-    console.error('[previousposts] Can\'t find username.');
-    return;
-  }
-
-  var name = escapeUsername(nameElement.textContent);
-  var filter = '(creator:"' + name + '" | replier:"' + name + '") forum:any';
-  var url = getSearchUrl(filter);
-
-  var links = document.createElement('div');
-  links.classList.add('TWPT-user-profile__user-links');
-
-  var a = document.createElement('a');
-  a.classList.add('TWPT-user-profile__user-link', 'TWPT-user-link');
-  a.href = url;
-  a.target = '_parent';
-  a.setAttribute(
-      'data-stats-id', 'user-posts-link--tw-power-tools-by-avm99963');
-
-  var badge = document.createElement('span');
-  badge.classList.add('TWPT-badge');
-  badge.setAttribute(
-      'title', chrome.i18n.getMessage('inject_extension_badge_helper', [
-        chrome.i18n.getMessage('appName')
-      ]));
-
-  var badgeImg = document.createElement('img');
-  badgeImg.src =
-      'https://fonts.gstatic.com/s/i/materialicons/repeat/v6/24px.svg';
-
-  badge.appendChild(badgeImg);
-  a.appendChild(badge);
-
-  var span = document.createElement('span');
-  span.textContent = chrome.i18n.getMessage('inject_previousposts');
-
-  a.appendChild(span);
-  links.appendChild(a);
-
-  var userDetailsNode =
-      document.querySelector('.scTailwindUser_profileUsercarddetails');
-  if (userDetailsNode === null) {
-    console.error('[previousposts] Can\'t get user card details div.');
-    return;
-  }
-
-  userDetailsNode.parentNode.insertBefore(links, userDetailsNode.nextSibling);
-}
-
+// TODO(b/twpowertools/80): Remove this code.
 function injectPreviousPostsLinksOldProfile() {
   if (document.querySelector('.user-profile__user-links') === null) {
     var nameElement = document.querySelector('.user-profile__user-name');
@@ -141,7 +82,7 @@
 getOptions('history').then(options => {
   if (options?.history) {
     if (document.getElementById('unified-user-profile') !== null)
-      injectPreviousPostsLinksUnifiedProfile();
+      injectPreviousPostsLinksUnifiedProfile(/* isCommunityConsole = */ false);
     else
       injectPreviousPostsLinksOldProfile();
   }
diff --git a/src/contentScripts/utilsCommon/unifiedProfiles.js b/src/contentScripts/utilsCommon/unifiedProfiles.js
new file mode 100644
index 0000000..d3995ea
--- /dev/null
+++ b/src/contentScripts/utilsCommon/unifiedProfiles.js
@@ -0,0 +1,77 @@
+import {escapeUsername} from '../../common/communityConsoleUtils.js';
+import {isOptionEnabled} from '../../common/optionsUtils.js';
+import {createExtBadge} from '../communityConsole/utils/common.js';
+
+var authuser = (new URL(location.href)).searchParams.get('authuser') || '0';
+
+export function getSearchUrl(query) {
+  var urlpart = encodeURIComponent('query=' + encodeURIComponent(query));
+  var authuserpart =
+      (authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser));
+  return 'https://support.google.com/s/community/search/' + urlpart +
+      authuserpart;
+}
+
+export function injectPreviousPostsLinksUnifiedProfile(isCommunityConsole) {
+  var nameElement =
+      document.querySelector('.scTailwindUser_profileUsercardname');
+  if (nameElement === null) {
+    console.error('[previousposts] Can\'t find username.');
+    return;
+  }
+
+  var name = escapeUsername(nameElement.textContent);
+  var filter = '(creator:"' + name + '" | replier:"' + name + '") forum:any';
+  var url = getSearchUrl(filter);
+
+  var links = document.createElement('div');
+  links.classList.add('TWPT-user-profile__user-links');
+
+  var a = document.createElement('a');
+  a.classList.add('TWPT-user-profile__user-link', 'TWPT-user-link');
+  a.href = url;
+  a.target = '_parent';
+  a.setAttribute(
+      'data-stats-id', 'user-posts-link--tw-power-tools-by-avm99963');
+
+  let badge;
+  if (isCommunityConsole) {
+    badge = createExtBadge();
+  } else {
+    badge = document.createElement('span');
+    badge.classList.add('TWPT-badge');
+    badge.setAttribute(
+        'title', chrome.i18n.getMessage('inject_extension_badge_helper', [
+          chrome.i18n.getMessage('appName')
+        ]));
+
+    var badgeImg = document.createElement('img');
+    badgeImg.src =
+        'https://fonts.gstatic.com/s/i/materialicons/repeat/v6/24px.svg';
+
+    badge.appendChild(badgeImg);
+  }
+
+  a.appendChild(badge);
+
+  var span = document.createElement('span');
+  span.textContent = chrome.i18n.getMessage('inject_previousposts');
+
+  a.appendChild(span);
+  links.appendChild(a);
+
+  var userDetailsNode =
+      document.querySelector('.scTailwindUser_profileUsercarddetails');
+  if (userDetailsNode === null) {
+    console.error('[previousposts] Can\'t get user card details div.');
+    return;
+  }
+
+  userDetailsNode.parentNode.insertBefore(links, userDetailsNode.nextSibling);
+}
+
+export function injectPreviousPostsLinksUnifiedProfileIfEnabled(isCommunityConsole) {
+  isOptionEnabled('history').then(isEnabled => {
+    if (isEnabled) injectPreviousPostsLinksUnifiedProfile(isCommunityConsole);
+  });
+}
diff --git a/src/static/css/common/console.css b/src/static/css/common/console.css
index 2eba28f..e8a6cfc 100644
--- a/src/static/css/common/console.css
+++ b/src/static/css/common/console.css
@@ -42,6 +42,7 @@
   padding: 4px 8px!important;
 }
 
+/* TODO(b/twpowertools/80): Remove this code. */
 .TWPT-previous-posts {
   display: flex;
   flex-direction: row;
@@ -53,6 +54,20 @@
   margin-right: 8px;
 }
 
+/* Unified profiles "previous posts" link badge */
+.TWPT-user-link .TWPT-badge {
+  display: inline-flex;
+  margin: 4px;
+}
+
+.TWPT-user-link {
+  text-decoration: none!important;
+}
+
+.TWPT-user-link:hover span {
+  text-decoration: underline!important;
+}
+
 .TWPT-dialog {
   display: block!important;
   width: 600px;
diff --git a/src/static/css/common/forum.css b/src/static/css/common/forum.css
index 50316d7..6a2b6d9 100644
--- a/src/static/css/common/forum.css
+++ b/src/static/css/common/forum.css
@@ -22,15 +22,3 @@
   height: var(--icon-size, 16px);
   filter: invert(1);
 }
-
-.TWPT-user-profile__user-links {
-  margin-top: 8px;
-}
-
-.TWPT-user-link > * {
-  vertical-align: middle;
-}
-
-.TWPT-user-link .TWPT-badge {
-  margin-left: 0;
-}
diff --git a/src/static/css/unifiedprofile.css b/src/static/css/unifiedprofile.css
new file mode 100644
index 0000000..fda14c5
--- /dev/null
+++ b/src/static/css/unifiedprofile.css
@@ -0,0 +1,11 @@
+.TWPT-user-profile__user-links {
+  margin-top: 8px;
+}
+
+.TWPT-user-link > * {
+  vertical-align: middle;
+}
+
+.TWPT-user-link .TWPT-badge {
+  margin-left: 0;
+}
diff --git a/templates/manifest.gjson b/templates/manifest.gjson
index 957193f..7645800 100644
--- a/templates/manifest.gjson
+++ b/templates/manifest.gjson
@@ -23,7 +23,7 @@
     {
       "matches": ["https://support.google.com/s/community*"],
       "js": ["communityConsoleStart.bundle.js"],
-      "css": ["css/common/console.css"],
+      "css": ["css/common/console.css", "css/unifiedprofile.css"],
       "run_at": "document_start"
     },
     {
@@ -45,7 +45,7 @@
       "matches": ["https://support.google.com/*/profile/*", "https://support.google.com/profile/*"],
       "all_frames": true,
       "js": ["profile.bundle.js"],
-      "css": ["css/common/forum.css"]
+      "css": ["css/common/forum.css", "css/unifiedprofile.css"]
     }
   ],
   "permissions": [