{"version":3,"file":"UnresolvedFileHunksRenderer.js","names":["row: MergeConflictInjectedRowData","before: InjectedRow[]","after: InjectedRow[]","contentChildren: HASTElement[]"],"sources":["../../src/renderers/UnresolvedFileHunksRenderer.ts"],"sourcesContent":["import type { Element as HASTElement, Properties } from 'hast';\n\nimport { DEFAULT_RENDER_RANGE, DEFAULT_THEMES } from '../constants';\nimport type {\n  FileDiffMetadata,\n  MergeConflictMarkerRow,\n  MergeConflictResolution,\n  RenderRange,\n} from '../types';\nimport { getMergeConflictActionSlotName } from '../utils/getMergeConflictActionSlotName';\nimport {\n  createGutterGap,\n  createHastElement,\n  createTextNodeElement,\n} from '../utils/hast_utils';\nimport {\n  getMergeConflictActionAnchor,\n  type MergeConflictDiffAction,\n} from '../utils/parseMergeConflictDiffFromFile';\nimport type { WorkerPoolManager } from '../worker';\nimport {\n  DiffHunksRenderer,\n  type DiffHunksRendererOptions,\n  type DiffHunksRendererOptionsWithDefaults,\n  type HunksRenderResult,\n  type InjectedRow,\n  type LineDecoration,\n  type RenderedLineContext,\n  type SplitLineDecorationProps,\n  type UnifiedInjectedRowPlacement,\n  type UnifiedLineDecorationProps,\n} from './DiffHunksRenderer';\n\ntype MergeConflictMarkerType =\n  | 'marker-start'\n  | 'marker-base'\n  | 'marker-separator'\n  | 'marker-end'\n  | 'current'\n  | 'incoming';\n\ninterface MergeConflictActionRowData {\n  hunkIndex: number;\n  lineIndex: number;\n  conflictIndex: number;\n}\n\ninterface MergeConflictMarkerInjectedRow extends MergeConflictMarkerRow {\n  type: Extract<\n    MergeConflictMarkerRow['type'],\n    'marker-start' | 'marker-base' | 'marker-separator' | 'marker-end'\n  >;\n  lineText: string;\n  lineIndex: number;\n}\n\n// NOTE(amadeus): Don't love this, should probably rework into an\n// interface/extender\ntype MergeConflictInjectedRowData =\n  | ({ type: 'actions' } & MergeConflictActionRowData)\n  | MergeConflictMarkerInjectedRow;\n\ninterface BaseUnresolvedOptionsWithDefaults extends DiffHunksRendererOptionsWithDefaults {\n  mergeConflictActionsType: MergeConflictActionsType;\n}\n\ntype MergeConflictActionsType = 'none' | 'default' | 'custom';\n\nexport interface UnresolvedFileHunksRendererOptions extends DiffHunksRendererOptions {\n  mergeConflictActionsType?: MergeConflictActionsType;\n}\n\nexport class UnresolvedFileHunksRenderer<\n  LAnnotation = undefined,\n> extends DiffHunksRenderer<LAnnotation> {\n  private pendingConflictActions: (MergeConflictDiffAction | undefined)[] = [];\n  private pendingMarkerRows: MergeConflictMarkerRow[] = [];\n  private injectedRows = new Map<string, MergeConflictInjectedRowData[]>();\n  public override options: UnresolvedFileHunksRendererOptions;\n\n  constructor(\n    options: UnresolvedFileHunksRendererOptions = {\n      theme: DEFAULT_THEMES,\n    },\n    onRenderUpdate?: () => unknown,\n    workerManager?: WorkerPoolManager | undefined\n  ) {\n    super(undefined, onRenderUpdate, workerManager);\n    this.options = options;\n  }\n\n  // SELF_REVIEW: I don't love how this is hooked up with `renderDiff` right\n  // now, so we definitely need to figure out what the fuck we are gonna do\n  // about it...\n  // I think at the very least we should keep it like annotations, and just\n  // sorta assume there's a disconnect there\n  public setConflictState(\n    conflictActions: (MergeConflictDiffAction | undefined)[],\n    markerRows: MergeConflictMarkerRow[],\n    diff: FileDiffMetadata\n  ): void {\n    this.pendingConflictActions = conflictActions;\n    this.pendingMarkerRows = markerRows;\n    this.syncInjectedRows(conflictActions, markerRows, diff);\n  }\n\n  private syncInjectedRows(\n    conflictActions: (MergeConflictDiffAction | undefined)[],\n    markerRows: MergeConflictMarkerRow[],\n    diff: FileDiffMetadata\n  ): void {\n    this.injectedRows.clear();\n    for (const action of conflictActions) {\n      const anchor =\n        action != null ? getMergeConflictActionAnchor(action, diff) : undefined;\n      if (action == null || anchor == null) {\n        continue;\n      }\n      const row: MergeConflictInjectedRowData = {\n        type: 'actions',\n        hunkIndex: anchor.hunkIndex,\n        lineIndex: anchor.lineIndex,\n        conflictIndex: action.conflictIndex,\n      };\n      this.addInjectedRow(row);\n    }\n\n    for (const row of markerRows) {\n      this.addInjectedRow(row);\n    }\n  }\n\n  private addInjectedRow(row: MergeConflictInjectedRowData): void {\n    const key = `${row.hunkIndex}:${row.lineIndex}`;\n    const rows = this.injectedRows.get(key);\n    if (rows == null) {\n      this.injectedRows.set(key, [row]);\n    } else {\n      rows.push(row);\n    }\n  }\n\n  public override renderDiff(\n    diff?: FileDiffMetadata | undefined,\n    renderRange: RenderRange = DEFAULT_RENDER_RANGE\n  ): HunksRenderResult | undefined {\n    if (diff != null) {\n      this.syncInjectedRows(\n        this.pendingConflictActions,\n        this.pendingMarkerRows,\n        diff\n      );\n    }\n    return super.renderDiff(diff, renderRange);\n  }\n\n  public override async asyncRender(\n    diff: FileDiffMetadata,\n    renderRange: RenderRange = DEFAULT_RENDER_RANGE\n  ): Promise<HunksRenderResult> {\n    this.syncInjectedRows(\n      this.pendingConflictActions,\n      this.pendingMarkerRows,\n      diff\n    );\n    return super.asyncRender(diff, renderRange);\n  }\n\n  protected override createPreElement(\n    split: boolean,\n    totalLines: number\n  ): HASTElement {\n    return super.createPreElement(split, totalLines, {\n      'data-has-merge-conflict': '',\n    });\n  }\n\n  protected override getUnifiedLineDecoration({\n    type,\n    lineType,\n  }: UnifiedLineDecorationProps): LineDecoration {\n    const mergeConflictType =\n      type === 'change'\n        ? lineType === 'change-deletion'\n          ? 'current'\n          : 'incoming'\n        : undefined;\n    return {\n      gutterLineType: type === 'change' ? 'context' : lineType,\n      gutterProperties: getMergeConflictGutterProperties(mergeConflictType),\n      contentProperties: getMergeConflictContentProperties(\n        type,\n        mergeConflictType\n      ),\n    };\n  }\n\n  protected override getSplitLineDecoration({\n    side,\n    type,\n  }: SplitLineDecorationProps): LineDecoration {\n    const mergeConflictType =\n      type === 'change'\n        ? side === 'deletions'\n          ? 'current'\n          : 'incoming'\n        : undefined;\n    return {\n      gutterLineType: type === 'change' ? 'context' : type,\n      gutterProperties: getMergeConflictGutterProperties(mergeConflictType),\n      contentProperties: getMergeConflictContentProperties(\n        type,\n        mergeConflictType\n      ),\n    };\n  }\n\n  protected override getUnifiedInjectedRowsForLine = (\n    ctx: RenderedLineContext\n  ): UnifiedInjectedRowPlacement | undefined => {\n    const rows = this.injectedRows.get(`${ctx.hunkIndex}:${ctx.lineIndex}`);\n    if (rows == null || rows.length === 0) {\n      return undefined;\n    }\n    const { mergeConflictActionsType } = this.getOptionsWithDefaults();\n    const before: InjectedRow[] = [];\n    const after: InjectedRow[] = [];\n    for (const row of rows) {\n      if (row.type === 'actions') {\n        before.push({\n          content: createMergeConflictActionsRowElement({\n            row,\n            includeDefaultActions: mergeConflictActionsType === 'default',\n            includeSlot: true,\n          }),\n          gutter: createMergeConflictGutterGap('action'),\n        });\n        continue;\n      }\n      const target = row.type === 'marker-end' ? after : before;\n      target.push({\n        content: createMergeConflictMarkerRowElement(row),\n        gutter: createMergeConflictGutterGap('marker', row.type),\n      });\n    }\n    return {\n      before: before.length > 0 ? before : undefined,\n      after: after.length > 0 ? after : undefined,\n    };\n  };\n\n  protected override getOptionsWithDefaults(): BaseUnresolvedOptionsWithDefaults {\n    const options = super.getOptionsWithDefaults();\n    options.diffStyle = 'unified';\n    options.lineDiffType = 'none';\n    // NOTE(amadeus): Aint nobody got time for a spread\n    (options as BaseUnresolvedOptionsWithDefaults).mergeConflictActionsType =\n      this.options.mergeConflictActionsType ?? 'default';\n    return options as BaseUnresolvedOptionsWithDefaults;\n  }\n}\n\nfunction getMergeConflictGutterProperties(\n  mergeConflictType: MergeConflictMarkerType | undefined\n): Properties | undefined {\n  return mergeConflictType != null\n    ? { 'data-merge-conflict': mergeConflictType }\n    : undefined;\n}\n\nfunction getMergeConflictContentProperties(\n  type: 'change' | 'context' | 'context-expanded',\n  mergeConflictType: MergeConflictMarkerType | undefined\n): Properties | undefined {\n  if (mergeConflictType == null) {\n    return undefined;\n  }\n  if (type === 'change') {\n    if (mergeConflictType === 'current' || mergeConflictType === 'incoming') {\n      return {\n        'data-line-type': 'context',\n        'data-merge-conflict': mergeConflictType,\n      };\n    }\n    return undefined;\n  }\n  if (\n    mergeConflictType === 'marker-start' ||\n    mergeConflictType === 'marker-base' ||\n    mergeConflictType === 'marker-separator' ||\n    mergeConflictType === 'marker-end'\n  ) {\n    return { 'data-merge-conflict': mergeConflictType };\n  }\n  return undefined;\n}\n\nfunction createMergeConflictGutterGap(\n  type: 'action' | 'marker',\n  markerType?: MergeConflictMarkerInjectedRow['type']\n): HASTElement {\n  const gap = createGutterGap(undefined, 'annotation', 1);\n  gap.properties['data-gutter-buffer'] =\n    type === 'action'\n      ? 'merge-conflict-action'\n      : `merge-conflict-${markerType ?? 'marker'}`;\n  return gap;\n}\n\ninterface CreateMergeConflictActionsRowElementProps {\n  row: MergeConflictActionRowData;\n  includeDefaultActions: boolean;\n  includeSlot: boolean;\n}\n\nfunction createMergeConflictActionsRowElement({\n  row,\n  includeDefaultActions,\n  includeSlot,\n}: CreateMergeConflictActionsRowElementProps): HASTElement {\n  const contentChildren: HASTElement[] = includeDefaultActions\n    ? createMergeConflictActionsContent(row.conflictIndex)\n    : [];\n  if (includeSlot) {\n    contentChildren.push(\n      createHastElement({\n        tagName: 'slot',\n        properties: {\n          name: getMergeConflictActionSlotName({\n            hunkIndex: row.hunkIndex,\n            lineIndex: row.lineIndex,\n            conflictIndex: row.conflictIndex,\n          }),\n          'data-merge-conflict-action-slot': '',\n        },\n      })\n    );\n  }\n  return createHastElement({\n    tagName: 'div',\n    properties: {\n      'data-merge-conflict-actions': '',\n    },\n    children: [\n      createHastElement({\n        tagName: 'div',\n        properties: { 'data-merge-conflict-actions-content': '' },\n        children: contentChildren,\n      }),\n    ],\n  });\n}\n\nfunction createMergeConflictMarkerRowElement(\n  row: MergeConflictMarkerInjectedRow\n): HASTElement {\n  return createHastElement({\n    tagName: 'div',\n    properties: {\n      'data-merge-conflict': row.type,\n      'data-merge-conflict-marker-row': '',\n    },\n    children: [\n      createTextNodeElement(row.lineText.replace(/(?:\\r\\n|\\n|\\r)$/, '')),\n    ],\n  });\n}\n\nfunction createMergeConflictActionsContent(\n  conflictIndex: number\n): HASTElement[] {\n  return [\n    createMergeConflictActionButton({\n      resolution: 'current',\n      label: 'Accept current change',\n      conflictIndex,\n    }),\n    createMergeConflictActionSeparator(),\n    createMergeConflictActionButton({\n      resolution: 'incoming',\n      label: 'Accept incoming change',\n      conflictIndex,\n    }),\n    createMergeConflictActionSeparator(),\n    createMergeConflictActionButton({\n      resolution: 'both',\n      label: 'Accept both',\n      conflictIndex,\n    }),\n  ];\n}\n\ninterface CreateMergeConflictActionButtonProps {\n  resolution: MergeConflictResolution;\n  label: string;\n  conflictIndex: number;\n}\n\nfunction createMergeConflictActionButton({\n  resolution,\n  label,\n  conflictIndex,\n}: CreateMergeConflictActionButtonProps): HASTElement {\n  return createHastElement({\n    tagName: 'button',\n    properties: {\n      type: 'button',\n      'data-merge-conflict-action': resolution,\n      'data-merge-conflict-conflict-index': `${conflictIndex}`,\n    },\n    children: [createTextNodeElement(label)],\n  });\n}\n\nfunction createMergeConflictActionSeparator(): HASTElement {\n  return createHastElement({\n    tagName: 'span',\n    properties: { 'data-merge-conflict-action-separator': '' },\n    children: [createTextNodeElement('|')],\n  });\n}\n"],"mappings":";;;;;;;AAwEA,IAAa,8BAAb,cAEU,kBAA+B;CACvC,AAAQ,yBAAkE,EAAE;CAC5E,AAAQ,oBAA8C,EAAE;CACxD,AAAQ,+BAAe,IAAI,KAA6C;CACxE,AAAgB;CAEhB,YACE,UAA8C,EAC5C,OAAO,gBACR,EACD,gBACA,eACA;AACA,QAAM,QAAW,gBAAgB,cAAc;AAC/C,OAAK,UAAU;;CAQjB,AAAO,iBACL,iBACA,YACA,MACM;AACN,OAAK,yBAAyB;AAC9B,OAAK,oBAAoB;AACzB,OAAK,iBAAiB,iBAAiB,YAAY,KAAK;;CAG1D,AAAQ,iBACN,iBACA,YACA,MACM;AACN,OAAK,aAAa,OAAO;AACzB,OAAK,MAAM,UAAU,iBAAiB;GACpC,MAAM,SACJ,UAAU,OAAO,6BAA6B,QAAQ,KAAK,GAAG;AAChE,OAAI,UAAU,QAAQ,UAAU,KAC9B;GAEF,MAAMA,MAAoC;IACxC,MAAM;IACN,WAAW,OAAO;IAClB,WAAW,OAAO;IAClB,eAAe,OAAO;IACvB;AACD,QAAK,eAAe,IAAI;;AAG1B,OAAK,MAAM,OAAO,WAChB,MAAK,eAAe,IAAI;;CAI5B,AAAQ,eAAe,KAAyC;EAC9D,MAAM,MAAM,GAAG,IAAI,UAAU,GAAG,IAAI;EACpC,MAAM,OAAO,KAAK,aAAa,IAAI,IAAI;AACvC,MAAI,QAAQ,KACV,MAAK,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC;MAEjC,MAAK,KAAK,IAAI;;CAIlB,AAAgB,WACd,MACA,cAA2B,sBACI;AAC/B,MAAI,QAAQ,KACV,MAAK,iBACH,KAAK,wBACL,KAAK,mBACL,KACD;AAEH,SAAO,MAAM,WAAW,MAAM,YAAY;;CAG5C,MAAsB,YACpB,MACA,cAA2B,sBACC;AAC5B,OAAK,iBACH,KAAK,wBACL,KAAK,mBACL,KACD;AACD,SAAO,MAAM,YAAY,MAAM,YAAY;;CAG7C,AAAmB,iBACjB,OACA,YACa;AACb,SAAO,MAAM,iBAAiB,OAAO,YAAY,EAC/C,2BAA2B,IAC5B,CAAC;;CAGJ,AAAmB,yBAAyB,EAC1C,MACA,YAC6C;EAC7C,MAAM,oBACJ,SAAS,WACL,aAAa,oBACX,YACA,aACF;AACN,SAAO;GACL,gBAAgB,SAAS,WAAW,YAAY;GAChD,kBAAkB,iCAAiC,kBAAkB;GACrE,mBAAmB,kCACjB,MACA,kBACD;GACF;;CAGH,AAAmB,uBAAuB,EACxC,MACA,QAC2C;EAC3C,MAAM,oBACJ,SAAS,WACL,SAAS,cACP,YACA,aACF;AACN,SAAO;GACL,gBAAgB,SAAS,WAAW,YAAY;GAChD,kBAAkB,iCAAiC,kBAAkB;GACrE,mBAAmB,kCACjB,MACA,kBACD;GACF;;CAGH,AAAmB,iCACjB,QAC4C;EAC5C,MAAM,OAAO,KAAK,aAAa,IAAI,GAAG,IAAI,UAAU,GAAG,IAAI,YAAY;AACvE,MAAI,QAAQ,QAAQ,KAAK,WAAW,EAClC;EAEF,MAAM,EAAE,6BAA6B,KAAK,wBAAwB;EAClE,MAAMC,SAAwB,EAAE;EAChC,MAAMC,QAAuB,EAAE;AAC/B,OAAK,MAAM,OAAO,MAAM;AACtB,OAAI,IAAI,SAAS,WAAW;AAC1B,WAAO,KAAK;KACV,SAAS,qCAAqC;MAC5C;MACA,uBAAuB,6BAA6B;MACpD,aAAa;MACd,CAAC;KACF,QAAQ,6BAA6B,SAAS;KAC/C,CAAC;AACF;;AAGF,IADe,IAAI,SAAS,eAAe,QAAQ,QAC5C,KAAK;IACV,SAAS,oCAAoC,IAAI;IACjD,QAAQ,6BAA6B,UAAU,IAAI,KAAK;IACzD,CAAC;;AAEJ,SAAO;GACL,QAAQ,OAAO,SAAS,IAAI,SAAS;GACrC,OAAO,MAAM,SAAS,IAAI,QAAQ;GACnC;;CAGH,AAAmB,yBAA4D;EAC7E,MAAM,UAAU,MAAM,wBAAwB;AAC9C,UAAQ,YAAY;AACpB,UAAQ,eAAe;AAEvB,EAAC,QAA8C,2BAC7C,KAAK,QAAQ,4BAA4B;AAC3C,SAAO;;;AAIX,SAAS,iCACP,mBACwB;AACxB,QAAO,qBAAqB,OACxB,EAAE,uBAAuB,mBAAmB,GAC5C;;AAGN,SAAS,kCACP,MACA,mBACwB;AACxB,KAAI,qBAAqB,KACvB;AAEF,KAAI,SAAS,UAAU;AACrB,MAAI,sBAAsB,aAAa,sBAAsB,WAC3D,QAAO;GACL,kBAAkB;GAClB,uBAAuB;GACxB;AAEH;;AAEF,KACE,sBAAsB,kBACtB,sBAAsB,iBACtB,sBAAsB,sBACtB,sBAAsB,aAEtB,QAAO,EAAE,uBAAuB,mBAAmB;;AAKvD,SAAS,6BACP,MACA,YACa;CACb,MAAM,MAAM,gBAAgB,QAAW,cAAc,EAAE;AACvD,KAAI,WAAW,wBACb,SAAS,WACL,0BACA,kBAAkB,cAAc;AACtC,QAAO;;AAST,SAAS,qCAAqC,EAC5C,KACA,uBACA,eACyD;CACzD,MAAMC,kBAAiC,wBACnC,kCAAkC,IAAI,cAAc,GACpD,EAAE;AACN,KAAI,YACF,iBAAgB,KACd,kBAAkB;EAChB,SAAS;EACT,YAAY;GACV,MAAM,+BAA+B;IACnC,WAAW,IAAI;IACf,WAAW,IAAI;IACf,eAAe,IAAI;IACpB,CAAC;GACF,mCAAmC;GACpC;EACF,CAAC,CACH;AAEH,QAAO,kBAAkB;EACvB,SAAS;EACT,YAAY,EACV,+BAA+B,IAChC;EACD,UAAU,CACR,kBAAkB;GAChB,SAAS;GACT,YAAY,EAAE,uCAAuC,IAAI;GACzD,UAAU;GACX,CAAC,CACH;EACF,CAAC;;AAGJ,SAAS,oCACP,KACa;AACb,QAAO,kBAAkB;EACvB,SAAS;EACT,YAAY;GACV,uBAAuB,IAAI;GAC3B,kCAAkC;GACnC;EACD,UAAU,CACR,sBAAsB,IAAI,SAAS,QAAQ,mBAAmB,GAAG,CAAC,CACnE;EACF,CAAC;;AAGJ,SAAS,kCACP,eACe;AACf,QAAO;EACL,gCAAgC;GAC9B,YAAY;GACZ,OAAO;GACP;GACD,CAAC;EACF,oCAAoC;EACpC,gCAAgC;GAC9B,YAAY;GACZ,OAAO;GACP;GACD,CAAC;EACF,oCAAoC;EACpC,gCAAgC;GAC9B,YAAY;GACZ,OAAO;GACP;GACD,CAAC;EACH;;AASH,SAAS,gCAAgC,EACvC,YACA,OACA,iBACoD;AACpD,QAAO,kBAAkB;EACvB,SAAS;EACT,YAAY;GACV,MAAM;GACN,8BAA8B;GAC9B,sCAAsC,GAAG;GAC1C;EACD,UAAU,CAAC,sBAAsB,MAAM,CAAC;EACzC,CAAC;;AAGJ,SAAS,qCAAkD;AACzD,QAAO,kBAAkB;EACvB,SAAS;EACT,YAAY,EAAE,wCAAwC,IAAI;EAC1D,UAAU,CAAC,sBAAsB,IAAI,CAAC;EACvC,CAAC"}