Add prefix, suffix, text parameters to comment links.

The backend support for them was added in
https://gerrit-review.googlesource.com/c/gerrit/+/345817

We are planning to deprecate html option for the commentLinks.
Most common usecase for raw html matches is to make links not extend
over token boundaries or to configure the text of the link. In order
to fill the gap in functionality we are adding prefix, suffix and text
fields. The generated link will look like this:

  PREFIX<a href="LINK">TEXT</a>SUFFIX

Release-Notes: Add ability to specify prefix, suffix and text fields for commentLinks of type `link`.
Google-Bug-Id: b/216788721
Change-Id: Ia9e7dc88b719d31c5572b3047428bab3a55d0be0
diff --git a/polygerrit-ui/app/api/rest-api.ts b/polygerrit-ui/app/api/rest-api.ts
index a7af005..3c06eb0 100644
--- a/polygerrit-ui/app/api/rest-api.ts
+++ b/polygerrit-ui/app/api/rest-api.ts
@@ -453,6 +453,9 @@
 export declare interface CommentLinkInfo {
   match: string;
   link?: string;
+  prefix?: string;
+  suffix?: string;
+  text?: string;
   enabled?: boolean;
   html?: string;
 }
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
index f3c9d9c..b405e6b 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
@@ -51,7 +51,15 @@
         match: 'HTMLRewriteMe',
         html: '<div>HTMLRewritten</div>',
       },
+      complexLinkRewrite: {
+        match: '(^|\\s)A Link (\\d+)($|\\s)',
+        link: '/page?id=$2',
+        text: 'Link $2',
+        prefix: '$1A ',
+        suffix: '$3',
+      },
     });
+    self.CANONICAL_PATH = 'http://localhost';
     element = (
       await fixture(
         wrapInProvider(
@@ -72,6 +80,7 @@
     test('renders text with links and rewrites', async () => {
       element.content = `text with plain link: google.com
         \ntext with config link: LinkRewriteMe
+        \ntext with complex link: A Link 12
         \ntext with config html: HTMLRewriteMe`;
       await element.updateComplete;
 
@@ -91,6 +100,14 @@
             >
               LinkRewriteMe
             </a>
+            text with complex link: A
+            <a
+              href="http://localhost/page?id=12"
+              rel="noopener"
+              target="_blank"
+            >
+              Link 12
+            </a>
             text with config html:
             <div>HTMLRewritten</div>
           </pre>
@@ -129,6 +146,8 @@
       element.content = `text
         \ntext with plain link: google.com
         \ntext with config link: LinkRewriteMe
+        \ntext without a link: NotA Link 15 cats
+        \ntext with complex link: A Link 12
         \ntext with config html: HTMLRewriteMe`;
       await element.updateComplete;
 
@@ -154,6 +173,17 @@
                   LinkRewriteMe
                 </a>
               </p>
+              <p>text without a link: NotA Link 15 cats</p>
+              <p>
+                text with complex link: A
+                <a
+                  href="http://localhost/page?id=12"
+                  rel="noopener"
+                  target="_blank"
+                >
+                  Link 12
+                </a>
+              </p>
               <p>text with config html:</p>
               <div>HTMLRewritten</div>
               <p></p>
diff --git a/polygerrit-ui/app/utils/link-util.ts b/polygerrit-ui/app/utils/link-util.ts
index fd5965b..9079f4c 100644
--- a/polygerrit-ui/app/utils/link-util.ts
+++ b/polygerrit-ui/app/utils/link-util.ts
@@ -18,7 +18,7 @@
   const parts: string[] = [];
   window.linkify(baseWithZeroWidthSpace, {
     callback: (text, href) => {
-      const result = href ? createLinkTemplate(text, href) : text;
+      const result = href ? createLinkTemplate(href, text) : text;
       const resultWithoutZeroWidthSpace = result.replace(/\u200B/g, '');
       parts.push(resultWithoutZeroWidthSpace);
     },
@@ -39,7 +39,12 @@
       : rewrite.link!;
     return {
       match: new RegExp(rewrite.match, 'g'),
-      replace: createLinkTemplate('$&', replacementHref),
+      replace: createLinkTemplate(
+        replacementHref,
+        rewrite.text ?? '$&',
+        rewrite.prefix,
+        rewrite.suffix
+      ),
     };
   });
   return applyRewrites(base, rewrites);
@@ -71,6 +76,15 @@
   );
 }
 
-function createLinkTemplate(displayText: string, href: string) {
-  return `<a href="${href}" rel="noopener" target="_blank">${displayText}</a>`;
+function createLinkTemplate(
+  href: string,
+  displayText: string,
+  prefix?: string,
+  suffix?: string
+) {
+  return `${
+    prefix ?? ''
+  }<a href="${href}" rel="noopener" target="_blank">${displayText}</a>${
+    suffix ?? ''
+  }`;
 }
diff --git a/polygerrit-ui/app/utils/link-util_test.ts b/polygerrit-ui/app/utils/link-util_test.ts
index c491e35..a1ec2fa 100644
--- a/polygerrit-ui/app/utils/link-util_test.ts
+++ b/polygerrit-ui/app/utils/link-util_test.ts
@@ -30,11 +30,13 @@
       '<h1>Change 12345 is the best change</h1> <div>FOO</div>'
     );
   });
+
   test('applyLinkRewritesFromConfig', () => {
     const linkedNumber = link('#12345', 'google.com/12345');
     const linkedFoo = link('foo', 'foo.gov');
+    const linkedBar = link('Bar Page: 300', 'bar.com/page?id=300');
     assert.equal(
-      applyLinkRewritesFromConfig('#12345 foo', {
+      applyLinkRewritesFromConfig('#12345 foo crowbar:12 bar:300', {
         'number-linker': {
           match: '#(\\d+)',
           link: 'google.com/$1',
@@ -43,8 +45,15 @@
           match: 'foo',
           link: 'foo.gov',
         },
+        'advanced-link': {
+          match: '(^|\\s)bar:(\\d+)($|\\s)',
+          link: 'bar.com/page?id=$2',
+          text: 'Bar Page: $2',
+          prefix: '$1',
+          suffix: '$3',
+        },
       }),
-      `${linkedNumber} ${linkedFoo}`
+      `${linkedNumber} ${linkedFoo} crowbar:12 ${linkedBar}`
     );
   });