Merge "Show "+ Unrelated changes" button for delta groups"
diff --git a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
index e1fc2ed..79feca0 100644
--- a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
+++ b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls.ts
@@ -271,6 +271,16 @@
         .breadcrumbTooltip {
           white-space: nowrap;
         }
+        .unrelatedChanges {
+          color: var(--primary-button-text-color);
+          background-color: var(--primary-button-background-color);
+
+          &:hover {
+            // TODO(anuragpathak): Update hover colors as per specification.
+            color: var(--primary-button-text-color);
+            background-color: var(--primary-button-background-color);
+          }
+        }
       `,
     ];
   }
@@ -370,8 +380,14 @@
     let classes = 'contextControlButton showContext ';
 
     if (type === ContextButtonType.ALL) {
-      text = `+${pluralize(linesToExpand, 'common line')}`;
-      ariaLabel = `Show ${pluralize(linesToExpand, 'common line')}`;
+      if (this.group.hasDeltaGroup()) {
+        text = '+ Unrelated changes';
+        ariaLabel = 'Show unrelated changes';
+        classes += ' unrelatedChanges ';
+      } else {
+        text = `+${pluralize(linesToExpand, 'common line')}`;
+        ariaLabel = `Show ${pluralize(linesToExpand, 'common line')}`;
+      }
       classes += this.showBoth()
         ? 'centeredButton'
         : this.showAbove()
@@ -483,7 +499,7 @@
    * Creates a container div with partial (+10) expansion buttons (above and/or below).
    */
   private createPartialExpansionButtons() {
-    if (!this.showPartialLinks()) {
+    if (!this.showPartialLinks() || this.group?.hasDeltaGroup()) {
       return undefined;
     }
     let aboveButton;
@@ -515,7 +531,8 @@
     if (
       !this.showPartialLinks() ||
       !this.renderPreferences?.use_block_expansion ||
-      this.group?.hasSkipGroup()
+      this.group?.hasSkipGroup() ||
+      this.group?.hasDeltaGroup()
     ) {
       return undefined;
     }
diff --git a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls_test.ts b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls_test.ts
index 20fc9c4..74726bf 100644
--- a/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls_test.ts
+++ b/polygerrit-ui/app/embed/diff/gr-context-controls/gr-context-controls_test.ts
@@ -10,7 +10,10 @@
 import {SyntaxBlock} from '../../../api/diff';
 import {fixture, html, assert} from '@open-wc/testing';
 import {waitEventLoop} from '../../../test/test-utils';
-import {createContextGroup} from '../../../test/test-data-generators';
+import {
+  createContextGroup,
+  createContextGroupWithDelta,
+} from '../../../test/test-data-generators';
 
 suite('gr-context-control tests', () => {
   let element: GrContextControls;
@@ -333,4 +336,16 @@
     assert.equal(tooltipAbove.getAttribute('position'), 'top');
     assert.equal(tooltipBelow.getAttribute('position'), 'bottom');
   });
+
+  test('context control with delta group', async () => {
+    element.group = createContextGroupWithDelta();
+    await waitEventLoop();
+
+    const buttons = element.shadowRoot!.querySelectorAll(
+      'paper-button.showContext'
+    );
+    assert.equal(buttons.length, 1);
+    assert.equal(buttons[0].textContent!.trim(), '+ Unrelated changes');
+    assert.include([...buttons[0].classList.values()], 'unrelatedChanges');
+  });
 });
diff --git a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-group.ts b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-group.ts
index c5366e7..0739562 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-group.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-group.ts
@@ -438,6 +438,11 @@
     );
   }
 
+  /** Returns true if it contains a DELTA group. */
+  hasDeltaGroup() {
+    return this.contextGroups?.some(g => g.type === GrDiffGroupType.DELTA);
+  }
+
   containsLine(side: Side, line: LineNumber) {
     if (typeof line !== 'number') {
       // For FILE and LOST, beforeNumber and afterNumber are the same
diff --git a/polygerrit-ui/app/test/test-data-generators.ts b/polygerrit-ui/app/test/test-data-generators.ts
index 22dbe7c1..2309977 100644
--- a/polygerrit-ui/app/test/test-data-generators.ts
+++ b/polygerrit-ui/app/test/test-data-generators.ts
@@ -688,6 +688,27 @@
   });
 }
 
+export function createContextGroupWithDelta() {
+  return new GrDiffGroup({
+    type: GrDiffGroupType.CONTEXT_CONTROL,
+    contextGroups: [
+      new GrDiffGroup({
+        type: GrDiffGroupType.DELTA,
+        lines: [
+          new GrDiffLine(GrDiffLineType.REMOVE, 8),
+          new GrDiffLine(GrDiffLineType.ADD, 0, 10),
+          new GrDiffLine(GrDiffLineType.REMOVE, 9),
+          new GrDiffLine(GrDiffLineType.ADD, 0, 11),
+          new GrDiffLine(GrDiffLineType.REMOVE, 10),
+          new GrDiffLine(GrDiffLineType.ADD, 0, 12),
+          new GrDiffLine(GrDiffLineType.REMOVE, 11),
+          new GrDiffLine(GrDiffLineType.ADD, 0, 13),
+        ],
+      }),
+    ],
+  });
+}
+
 export function createBlame(): BlameInfo {
   return {
     author: 'test-author',