Add lit element based gr-diff elements

This is rolling forward change 330300, see there for a more detailed
description of the changes. The change 330300 had to be rolled back
just because of the 2-line-change to `_handleDown()` in
`gr-diff-selection`. Everything else in the change was fine and
already reviewed. So we are rolling forward without any changes
outside of the added files that could possibly affect the existing
rendering. We think this is absolutely safe to submit and release.

It is expected that the new diff elements may not yet be working
perfectly, but we want to separate the already reviewed changes from
the fixes. We believe that this change does not need a substantial
review.

Release-Notes: skip
Google-Bug-Id: b/237393560
Change-Id: I9cd6cf23de233719cf7da8e834179f98b5ea65bf
diff --git a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-utils.ts b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-utils.ts
index 2b61c8c..1f54a89 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-utils.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff-utils.ts
@@ -34,12 +34,20 @@
  *   Graphemes: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
  *   A proposed JS API: https://github.com/tc39/proposal-intl-segmenter
  */
-const REGEX_TAB_OR_SURROGATE_PAIR = /\t|[\uD800-\uDBFF][\uDC00-\uDFFF]/;
+export const REGEX_TAB_OR_SURROGATE_PAIR = /\t|[\uD800-\uDBFF][\uDC00-\uDFFF]/;
 
 // If any line of the diff is more than the character limit, then disable
 // syntax highlighting for the entire file.
 export const SYNTAX_MAX_LINE_LENGTH = 500;
 
+export function countLines(diff?: DiffInfo, side?: Side) {
+  if (!diff?.content || !side) return 0;
+  return diff.content.reduce((sum, chunk) => {
+    const sideChunk = side === Side.LEFT ? chunk.a : chunk.b;
+    return sum + (sideChunk?.length ?? chunk.ab?.length ?? chunk.skip ?? 0);
+  }, 0);
+}
+
 export function getResponsiveMode(
   prefs: DiffPreferencesInfo,
   renderPrefs?: RenderPreferences
@@ -54,7 +62,7 @@
   return 'NONE';
 }
 
-export function isResponsive(responsiveMode: DiffResponsiveMode) {
+export function isResponsive(responsiveMode?: DiffResponsiveMode) {
   return (
     responsiveMode === 'FULL_RESPONSIVE' || responsiveMode === 'SHRINK_ONLY'
   );
@@ -105,7 +113,12 @@
         return null;
       }
     }
-    node = node.previousSibling ?? node.parentElement ?? undefined;
+    node =
+      (node as Element).assignedSlot ??
+      (node as ShadowRoot).host ??
+      node.previousSibling ??
+      node.parentNode ??
+      undefined;
   }
   return null;
 }
@@ -184,6 +197,19 @@
 }
 
 /**
+ * Simple helper method for creating element classes in the context of
+ * gr-diff.
+ *
+ * We are adding 'style-scope', 'gr-diff' classes for compatibility with
+ * Shady DOM. TODO: Is that still required??
+ *
+ * Otherwise this is just a super simple convenience function.
+ */
+export function diffClasses(...additionalClasses: string[]) {
+  return ['style-scope', 'gr-diff', ...additionalClasses].join(' ');
+}
+
+/**
  * Simple helper method for creating elements in the context of gr-diff.
  *
  * Otherwise this is just a super simple convenience function.