{"version":3,"sources":["webpack:///./blob/line_highlighter.js","webpack:///./blob/utils.js","webpack:///./blob/blob_fork_suggestion.js","webpack:///./pages/projects/init_blob.js","webpack:///./blob/blob_line_permalink_updater.js","webpack:///./behaviors/shortcuts/shortcuts_blob.js","webpack:///./blame/blame_redirect.js","webpack:///./pages/projects/blame/show/index.js","webpack:////build/source/ee/app/assets/javascripts/pages/projects/blame/show/index.js","webpack:///./repository/utils/title.js","webpack:////build/source/ee/app/assets/javascripts/pages/projects/shared/init_blob.js","webpack:////build/source/ee/app/assets/javascripts/path_locks.js"],"names":["LineHighlighter","options","highlightLineClass","fileHolderSelector","scrollFileHolder","hash","window","location","scrollBehavior","this","_hash","setHash","bind","highlightLine","clickHandler","highlightHash","bindEvents","prototype","_this","fileHolder","document","querySelector","addEventListener","e","target","newHash","scrollEnabled","range","clearHighlight","hashToRange","highlightRange","lineSelector","scrollToElement","offset","behavior","event","matches","preventDefault","lineNumber","parseInt","dataset","current","shiftKey","highlightedLines","getElementsByClassName","Array","from","forEach","line","classList","remove","match","length","lineElement","getElementById","add","results","ref","reverse","push","firstLineNumber","lastLineNumber","__setLocationHash__","value","history","pushState","url","title","blameLinesPerPage","_document$querySelect","blamePerPage","getPageParamValue","lineNum","page","Math","ceil","getPageSearchString","path","URL","getBaseURL","searchParams","set","search","moveToFilePermalink","fileBlobPermalinkUrlElement","permalink","getAttribute","urlIsDifferent","updateHistory","urlContainsSha","updateRefPortionOfTitle","getShaFromUrl","shortcircuitPermalinkButton","ctrlKey","metaKey","defaults","openButtons","forkButtons","cancelButtons","suggestionSections","actionTextPieces","BlobForkSuggestion","constructor","elementMap","onOpenButtonClick","onCancelButtonClick","init","$","on","showSuggestionSection","forkPath","action","removeClass","attr","text","hideSuggestionSection","addClass","currentTarget","destroy","off","BlobLinePermalinkUpdater","querySelectorAll","addShortcutsExtension","ShortcutsNavigation","ShortcutsBlob","lineNumberRe","blobContentHolder","lineNumberSelector","elementsToUpdate","updateBlameAndBlobPermalinkCb","setTimeout","linksToUpdate","getLocationHash","test","hashUrlString","concat","slice","call","permalinkButton","baseHref","originalHref","href","split","searchString","setAttribute","updateLineNumbersOnBlobPermalinks","shortcuts","PROJECT_FILES_GO_TO_PERMALINK","linesPerPage","perPage","params","URLSearchParams","currentPage","get","isPaginationDisabled","pageToRedirect","createAlert","message","__","setUrlParams","redirectToCorrectPage","initBlob","setTitle","pathMatch","project","replace","isEmpty","sha","doc","titleParts","join","dataEl","toggle_path","JSON","parse","innerHTML","async","state","confirmAction","sprintf","axios","post","then","reload","catch","initPathLocks"],"mappings":"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","file":"pages.projects.blame.show.6e00abf6.chunk.js","sourcesContent":["/* eslint-disable func-names, no-underscore-dangle, no-param-reassign, consistent-return */\n\nimport { scrollToElement } from '~/lib/utils/common_utils';\n\n// LineHighlighter\n//\n// Handles single- and multi-line selection and highlight for blob views.\n//\n//\n// ### Example Markup\n//\n//   <div id=\"blob-content-holder\">\n//     <div class=\"file-content\">\n//       <div class=\"line-numbers\">\n//         <a href=\"#L1\" id=\"L1\" data-line-number=\"1\">1</a>\n//         <a href=\"#L2\" id=\"L2\" data-line-number=\"2\">2</a>\n//         <a href=\"#L3\" id=\"L3\" data-line-number=\"3\">3</a>\n//         <a href=\"#L4\" id=\"L4\" data-line-number=\"4\">4</a>\n//         <a href=\"#L5\" id=\"L5\" data-line-number=\"5\">5</a>\n//       </div>\n//       <pre class=\"code highlight\">\n//         <code>\n//           <span id=\"LC1\" class=\"line\">...</span>\n//           <span id=\"LC2\" class=\"line\">...</span>\n//           <span id=\"LC3\" class=\"line\">...</span>\n//           <span id=\"LC4\" class=\"line\">...</span>\n//           <span id=\"LC5\" class=\"line\">...</span>\n//         </code>\n//       </pre>\n//     </div>\n//   </div>\n//\n\nconst LineHighlighter = function (options = {}) {\n  options.highlightLineClass = options.highlightLineClass || 'hll';\n  options.fileHolderSelector = options.fileHolderSelector || '.file-holder';\n  options.scrollFileHolder = options.scrollFileHolder || false;\n  options.hash = options.hash || window.location.hash;\n  options.scrollBehavior = options.scrollBehavior || 'smooth';\n\n  this.options = options;\n  this._hash = options.hash;\n  this.highlightLineClass = options.highlightLineClass;\n  this.setHash = this.setHash.bind(this);\n  this.highlightLine = this.highlightLine.bind(this);\n  this.clickHandler = this.clickHandler.bind(this);\n  this.highlightHash = this.highlightHash.bind(this);\n\n  this.bindEvents();\n  this.highlightHash();\n};\n\nLineHighlighter.prototype.bindEvents = function () {\n  const fileHolder = document.querySelector(this.options.fileHolderSelector);\n  if (fileHolder) {\n    fileHolder.addEventListener('click', this.clickHandler);\n    fileHolder.addEventListener('highlight:line', this.highlightHash);\n    window.addEventListener('hashchange', (e) => this.highlightHash(e.target.location.hash));\n  }\n};\n\nLineHighlighter.prototype.highlightHash = function (newHash, scrollEnabled = true) {\n  let range;\n  if (newHash && typeof newHash === 'string') this._hash = newHash;\n\n  this.clearHighlight();\n\n  if (this._hash !== '') {\n    range = this.hashToRange(this._hash);\n    if (range[0]) {\n      this.highlightRange(range);\n      const lineSelector = `#L${range[0]}`;\n\n      if (scrollEnabled) {\n        scrollToElement(lineSelector, {\n          // Scroll to the first highlighted line on initial load\n          // Add an offset of -100 for some context\n          offset: -100,\n          behavior: this.options.scrollBehavior,\n        });\n      }\n    }\n  }\n};\n\nLineHighlighter.prototype.clickHandler = function (event) {\n  const isLine = event.target.matches('a[data-line-number]');\n  if (isLine) {\n    let range;\n    event.preventDefault();\n    this.clearHighlight();\n    const lineNumber = parseInt(event.target.dataset.lineNumber, 10);\n    const current = this.hashToRange(this._hash);\n    if (!(current[0] && event.shiftKey)) {\n      // If there's no current selection, or there is but Shift wasn't held,\n      // treat this like a single-line selection.\n      this.setHash(lineNumber);\n      return this.highlightLine(lineNumber);\n    }\n    if (event.shiftKey) {\n      if (lineNumber < current[0]) {\n        range = [lineNumber, current[0]];\n      } else {\n        range = [current[0], lineNumber];\n      }\n      this.setHash(range[0], range[1]);\n      return this.highlightRange(range);\n    }\n  }\n};\n\nLineHighlighter.prototype.clearHighlight = function () {\n  const highlightedLines = document.getElementsByClassName(this.highlightLineClass);\n  Array.from(highlightedLines).forEach(function (line) {\n    line.classList.remove(this.highlightLineClass);\n  }, this);\n};\n\n// Convert a URL hash String into line numbers\n//\n// hash - Hash String\n//\n// Examples:\n//\n//   hashToRange('#L5')    # => [5, null]\n//   hashToRange('#L5-15') # => [5, 15]\n//   hashToRange('#foo')   # => [null, null]\n//\n// Returns an Array\nLineHighlighter.prototype.hashToRange = function (hash) {\n  // ?L(\\d+)(?:-L?(\\d+))?$/)\n  const matches = hash.match(/^#?L(\\d+)(?:-L?(\\d+))?$/);\n  if (matches && matches.length) {\n    const first = parseInt(matches[1], 10);\n    const last = matches[2] ? parseInt(matches[2], 10) : null;\n    return [first, last];\n  }\n  return [null, null];\n};\n\n// Highlight a single line\n//\n// lineNumber - Line number to highlight\nLineHighlighter.prototype.highlightLine = function (lineNumber) {\n  const lineElement = document.getElementById(`LC${lineNumber}`);\n  if (lineElement) {\n    lineElement.classList.add(this.highlightLineClass);\n  }\n};\n\n// Highlight all lines within a range\n//\n// range - Array containing the starting and ending line numbers\nLineHighlighter.prototype.highlightRange = function (range) {\n  if (range[1]) {\n    const results = [];\n    const ref = range[0] <= range[1] ? range : range.reverse();\n\n    for (let lineNumber = range[0]; lineNumber <= ref[1]; lineNumber += 1) {\n      results.push(this.highlightLine(lineNumber));\n    }\n\n    return results;\n  }\n  return this.highlightLine(range[0]);\n};\n\n// Set the URL hash string\nLineHighlighter.prototype.setHash = function (firstLineNumber, lastLineNumber) {\n  let hash;\n  if (lastLineNumber) {\n    hash = `#L${firstLineNumber}-${lastLineNumber}`;\n  } else {\n    hash = `#L${firstLineNumber}`;\n  }\n  this._hash = hash;\n  return this.__setLocationHash__(hash);\n};\n\n// Make the actual hash change in the browser\n//\n// This method is stubbed in tests.\nLineHighlighter.prototype.__setLocationHash__ = function (value) {\n  return window.history.pushState(\n    {\n      url: value,\n      // We're using pushState instead of assigning location.hash directly to\n      // prevent the page from scrolling on the hashchange event\n    },\n    document.title,\n    value,\n  );\n};\n\nexport default LineHighlighter;\n","import {\n  getBaseURL,\n  updateHistory,\n  urlIsDifferent,\n  urlContainsSha,\n  getShaFromUrl,\n} from '~/lib/utils/url_utility';\nimport { updateRefPortionOfTitle } from '~/repository/utils/title';\n\nconst blameLinesPerPage = document.querySelector('.js-per-page')?.dataset?.blamePerPage;\n\nexport const getPageParamValue = (lineNum, blamePerPage = blameLinesPerPage) => {\n  if (!blamePerPage) return '';\n  const page = Math.ceil(parseInt(lineNum, 10) / parseInt(blamePerPage, 10));\n  return page <= 1 ? '' : page;\n};\n\nexport const getPageSearchString = (path, page) => {\n  if (!page) return '';\n  const url = new URL(path, getBaseURL());\n  url.searchParams.set('page', page);\n  return url.search;\n};\n\nexport function moveToFilePermalink() {\n  const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url');\n  const permalink = fileBlobPermalinkUrlElement?.getAttribute('href');\n\n  if (!permalink) {\n    return;\n  }\n\n  if (urlIsDifferent(permalink)) {\n    updateHistory({\n      url: permalink,\n      title: document.title,\n    });\n\n    if (urlContainsSha({ url: permalink })) {\n      updateRefPortionOfTitle(getShaFromUrl({ url: permalink }));\n    }\n  }\n}\n\nfunction eventHasModifierKeys(event) {\n  // We ignore alt because I don't think alt clicks normally do anything special?\n  return event.ctrlKey || event.metaKey || event.shiftKey;\n}\n\nexport function shortcircuitPermalinkButton() {\n  const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url');\n\n  fileBlobPermalinkUrlElement?.addEventListener('click', (e) => {\n    if (!eventHasModifierKeys(e)) {\n      e.preventDefault();\n      moveToFilePermalink();\n    }\n  });\n}\n\nexport default () => ({});\n","import $ from 'jquery';\n\nconst defaults = {\n  // Buttons that will show the `suggestionSections`\n  // has `data-fork-path`, and `data-action`\n  openButtons: [],\n  // Update the href(from `openButton` -> `data-fork-path`)\n  // whenever a `openButton` is clicked\n  forkButtons: [],\n  // Buttons to hide the `suggestionSections`\n  cancelButtons: [],\n  // Section to show/hide\n  suggestionSections: [],\n  // Pieces of text that need updating depending on the action, `edit`, `replace`, `delete`\n  actionTextPieces: [],\n};\n\nclass BlobForkSuggestion {\n  constructor(options) {\n    this.elementMap = { ...defaults, ...options };\n    this.onOpenButtonClick = this.onOpenButtonClick.bind(this);\n    this.onCancelButtonClick = this.onCancelButtonClick.bind(this);\n  }\n\n  init() {\n    this.bindEvents();\n\n    return this;\n  }\n\n  bindEvents() {\n    $(this.elementMap.openButtons).on('click', this.onOpenButtonClick);\n    $(this.elementMap.cancelButtons).on('click', this.onCancelButtonClick);\n  }\n\n  showSuggestionSection(forkPath, action = 'edit') {\n    $(this.elementMap.suggestionSections).removeClass('hidden');\n    $(this.elementMap.forkButtons).attr('href', forkPath);\n    $(this.elementMap.actionTextPieces).text(action);\n  }\n\n  hideSuggestionSection() {\n    $(this.elementMap.suggestionSections).addClass('hidden');\n  }\n\n  onOpenButtonClick(e) {\n    const forkPath = $(e.currentTarget).attr('data-fork-path');\n    const action = $(e.currentTarget).attr('data-action');\n    this.showSuggestionSection(forkPath, action);\n  }\n\n  onCancelButtonClick() {\n    this.hideSuggestionSection();\n  }\n\n  destroy() {\n    $(this.elementMap.openButtons).off('click', this.onOpenButtonClick);\n    $(this.elementMap.cancelButtons).off('click', this.onCancelButtonClick);\n  }\n}\n\nexport default BlobForkSuggestion;\n","import { addShortcutsExtension } from '~/behaviors/shortcuts';\nimport ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob';\nimport { shortcircuitPermalinkButton } from '~/blob/utils';\nimport ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';\nimport BlobForkSuggestion from '~/blob/blob_fork_suggestion';\nimport BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';\nimport LineHighlighter from '~/blob/line_highlighter';\n\nexport default () => {\n  new LineHighlighter(); // eslint-disable-line no-new\n\n  // eslint-disable-next-line no-new\n  new BlobLinePermalinkUpdater(\n    document.querySelector('#blob-content-holder'),\n    '.file-line-num[data-line-number], .file-line-num[data-line-number] *',\n    document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'),\n  );\n\n  shortcircuitPermalinkButton();\n\n  addShortcutsExtension(ShortcutsNavigation);\n  addShortcutsExtension(ShortcutsBlob);\n\n  new BlobForkSuggestion({\n    openButtons: document.querySelectorAll('.js-edit-blob-link-fork-toggler'),\n    forkButtons: document.querySelectorAll('.js-fork-suggestion-button'),\n    cancelButtons: document.querySelectorAll('.js-cancel-fork-suggestion-button'),\n    suggestionSections: document.querySelectorAll('.js-file-fork-suggestion-section'),\n    actionTextPieces: document.querySelectorAll('.js-file-fork-suggestion-section-action'),\n  }).init();\n};\n","import { getLocationHash } from '../lib/utils/url_utility';\nimport { getPageParamValue, getPageSearchString } from './utils';\n\nconst lineNumberRe = /^(L|LC)[0-9]+/;\n\nconst updateLineNumbersOnBlobPermalinks = (linksToUpdate) => {\n  const hash = getLocationHash();\n  if (hash && lineNumberRe.test(hash)) {\n    const hashUrlString = `#${hash}`;\n\n    [].concat(Array.prototype.slice.call(linksToUpdate)).forEach((permalinkButton) => {\n      const baseHref =\n        permalinkButton.dataset.originalHref ||\n        (() => {\n          const href = permalinkButton.getAttribute('href');\n          // eslint-disable-next-line no-param-reassign\n          permalinkButton.dataset.originalHref = href;\n          return href;\n        })();\n      const lineNum = parseInt(hash.split('L')[1], 10);\n      const page = getPageParamValue(lineNum);\n      const searchString = getPageSearchString(baseHref, page);\n      permalinkButton.setAttribute('href', `${baseHref}${searchString}${hashUrlString}`);\n    });\n  }\n};\n\nfunction BlobLinePermalinkUpdater(blobContentHolder, lineNumberSelector, elementsToUpdate) {\n  if (!blobContentHolder) return;\n  const updateBlameAndBlobPermalinkCb = () => {\n    // Wait for the hash to update from the LineHighlighter callback\n    setTimeout(() => {\n      updateLineNumbersOnBlobPermalinks(elementsToUpdate);\n    }, 0);\n  };\n\n  blobContentHolder.addEventListener('click', (e) => {\n    if (e.target.matches(lineNumberSelector)) {\n      updateBlameAndBlobPermalinkCb();\n    }\n  });\n  updateBlameAndBlobPermalinkCb();\n}\n\nexport default BlobLinePermalinkUpdater;\n","import { PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings';\nimport { moveToFilePermalink } from '~/blob/utils';\n\nexport default class ShortcutsBlob {\n  constructor(shortcuts) {\n    shortcuts.add(PROJECT_FILES_GO_TO_PERMALINK, moveToFilePermalink);\n  }\n}\n","import { setUrlParams } from '~/lib/utils/url_utility';\nimport { createAlert } from '~/alert';\nimport { __ } from '~/locale';\n\nexport default function redirectToCorrectBlamePage() {\n  const { hash } = window.location;\n  const linesPerPage = parseInt(document.querySelector('.js-per-page').dataset.perPage, 10);\n  const params = new URLSearchParams(window.location.search);\n  const currentPage = parseInt(params.get('page'), 10);\n  const isPaginationDisabled = params.get('no_pagination');\n  if (hash && linesPerPage && !isPaginationDisabled) {\n    const lineNumber = parseInt(hash.split('#L')[1], 10);\n    const pageToRedirect = Math.ceil(lineNumber / linesPerPage);\n    const isRedirectNeeded =\n      (pageToRedirect > 1 && pageToRedirect !== currentPage) || pageToRedirect < currentPage;\n    if (isRedirectNeeded) {\n      createAlert({\n        message: __('Please wait a few moments while we load the file history for this line.'),\n      });\n      window.location.href = setUrlParams({ page: pageToRedirect });\n    }\n  }\n}\n","import initBlob from '~/pages/projects/init_blob';\nimport redirectToCorrectPage from '~/blame/blame_redirect';\n\nredirectToCorrectPage();\ninitBlob();\n","import '~/pages/projects/blame/show/index';\nimport initBlob from '../../shared/init_blob';\n\ninitBlob();\n","const DEFAULT_TITLE = '· GitLab';\n\nexport const setTitle = (pathMatch, ref, project) => {\n  if (!pathMatch) {\n    document.title = `${project} ${DEFAULT_TITLE}`;\n    return;\n  }\n\n  const path = pathMatch.replace(/^\\//, '');\n  const isEmpty = path === '';\n\n  /* eslint-disable-next-line @gitlab/require-i18n-strings */\n  document.title = `${isEmpty ? 'Files' : path} · ${ref} · ${project} ${DEFAULT_TITLE}`;\n};\n\nexport function updateRefPortionOfTitle(sha, doc = document) {\n  const { title = '' } = doc;\n  const titleParts = title.split(' · ');\n\n  if (titleParts.length > 1) {\n    titleParts[1] = sha;\n\n    /* eslint-disable-next-line no-param-reassign */\n    doc.title = titleParts.join(' · ');\n  }\n}\n","import initPathLocks from 'ee/path_locks';\n\nexport default () => {\n  const dataEl = document.getElementById('js-file-lock');\n\n  if (dataEl) {\n    const { toggle_path, path } = JSON.parse(dataEl.innerHTML);\n\n    initPathLocks(toggle_path, path);\n  }\n};\n","import $ from 'jquery';\nimport { createAlert } from '~/alert';\nimport axios from '~/lib/utils/axios_utils';\nimport { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';\nimport { sprintf, __ } from '~/locale';\n\nexport default function initPathLocks(url, path) {\n  $('a.path-lock').on('click', async (e) => {\n    e.preventDefault();\n\n    const { dataset } = e.target;\n    const message =\n      dataset.state === 'lock'\n        ? __('Are you sure you want to lock %{path}?')\n        : __('Are you sure you want to unlock %{path}?');\n\n    const confirmed = await confirmAction(sprintf(message, { path }));\n    if (!confirmed) {\n      return;\n    }\n\n    axios\n      .post(url, {\n        path,\n      })\n      .then(() => {\n        window.location.reload();\n      })\n      .catch(() =>\n        createAlert({\n          message: __('An error occurred while initializing path locks'),\n        }),\n      );\n  });\n}\n"],"sourceRoot":""}