{"version":3,"sources":["webpack:///vue_shared/components/diff_stats_dropdown.vue","webpack:///./vue_shared/components/diff_stats_dropdown.vue?cc39","webpack:///./vue_shared/components/diff_stats_dropdown.vue?add1","webpack:///./vue_shared/components/diff_stats_dropdown.vue?9b09","webpack:///./vue_shared/components/diff_stats_dropdown.vue","webpack:///./init_diff_stats_dropdown.js","webpack:///./files_comment_button.js","webpack:///./commit/image_file.js","webpack:///./image_diff/helpers/badge_helper.js","webpack:///./image_diff/helpers/comment_indicator_helper.js","webpack:///./image_diff/image_badge.js","webpack:///./image_diff/helpers/index.js","webpack:///./image_diff/helpers/dom_helper.js","webpack:///./image_diff/helpers/utils_helper.js","webpack:///./image_diff/image_diff.js","webpack:///./lib/utils/image_utility.js","webpack:///./image_diff/view_types.js","webpack:///./image_diff/replaced_image_diff.js","webpack:///./image_diff/helpers/init_image_diff.js","webpack:///./single_file_diff.js","webpack:///./diff.js","webpack:///./vue_shared/components/diff_stats_dropdown.vue?c602"],"names":["i18n","messageAdditionsDeletions","s__","noFilesFound","__","noFileNameAvailable","searchFiles","variantCssColorMap","success","danger","components","GlDisclosureDropdown","GlIcon","GlSearchBoxByType","GlSprintf","props","changed","type","Number","required","added","deleted","files","Array","data","search","computed","filteredFiles","length","fuzzaldrinPlus","filter","key","dropdownItems","_this","map","file","text","name","$options","iconColor","messageChanged","sprintf","n__","count","methods","focusInput","$refs","focusFirstItem","$el","querySelector","focus","additionsText","numberOfChanges","deletionsText","options","locals","_vm","this","_c","_self","attrs","scopedSlots","_u","fn","content","dropdownText","staticClass","on","ref","$event","indexOf","_k","keyCode","apply","arguments","model","value","callback","$$v","trim","expression","_v","_e","_s","proxy","item","class","icon","removed","path","initDiffStatsDropdown","el","document","dataset","Vue","render","createElement","DiffStatsDropdown","parseInt","JSON","parse","init","$diffFile","userCanCreateNote","closest","isParallelView","getCookie","e","showButton","hideButton","buttonParentElement","getButtonParent","currentTarget","validateButtonParent","classList","add","nextElementSibling","remove","hoveredElement","contains","previousElementSibling","parentNode","viewModes","ImageFile","constructor","_this4","_defineProperty","$","each","index","wrap","width","availWidth","requestImageInfo","height","removeClass","swipe","_this2","maxWidth","maxHeight","view","prepareFrames","$swipeFrame","$swipeWrap","$swipeBar","css","left","wrapPadding","replace","initDraggable","_this3","dragTrackWidth","$frame","$frameAdded","$track","$dragger","framePadding","opacity","initViewModes","initView","_this5","viewMode","event","hasClass","activateViewMode","className","addClass","views","call","padding","dragging","$body","$offsetEl","parent","dragStart","dragStop","dragMove","pageX","touches","offset","off","frame","img","_this6","domImg","get","complete","naturalWidth","naturalHeight","createImageBadge","noteId","x","y","classNames","buttonEl","concat","forEach","setAttribute","style","top","addCommentIndicator","containerEl","innerHTML","spriteIcon","appendChild","defaultMeta","ImageBadge","discussionId","actual","browser","imageEl","imageDiffHelper","resizeCoordinatesToImageElement","commentIndicatorHelper","removeCommentIndicator","imageFrameEl","commentIndicatorEl","willRemove","Boolean","meta","image","showCommentIndicator","coordinate","commentIndicatorOnClick","stopPropagation","addImageBadge","badgeText","textContent","addImageCommentBadge","addAvatarBadge","badgeNumber","detail","avatarBadgeEl","setPositionDataAttribute","position","positionObject","stringify","updateDiscussionAvatarBadgeNumber","discussionEl","newBadgeNumber","updateDiscussionBadgeNumber","toggleCollapsed","discussionNotesEl","formEl","isCollapsed","display","imageWidth","imageHeight","widthRatio","heightRatio","Math","round","generateBadgeFromDiscussionDOM","firstNoteEl","id","getTargetSelection","offsetX","offsetY","actualWidth","actualHeight","normalizedX","max","min","normalizedY","ImageDiff","canCreateNote","renderCommentBadge","$noteContainer","imageBadges","bindEvents","element","imageClickedWrapper","imageClicked","bind","imageBlurredWrapper","addBadgeWrapper","addBadge","removeBadgeWrapper","removeBadge","renderBadgesWrapper","renderBadges","addEventListener","customEvent","selection","querySelectorAll","renderBadge","imageBadge","push","numberBadgeOptions","indexToRemove","imageBadgeEls","badge","updatedBadgeNumber","splice","viewTypes","TWO_UP","SWIPE","ONION_SKIN","ReplacedImageDiff","defaultViewType","imageFrameEls","viewModesEl","viewModesEls","currentView","generateImageEls","imageEls","Object","getOwnPropertyNames","viewType","super","changeToViewTwoUp","changeView","changeToViewSwipe","changeToViewOnionSkin","newView","validate","find","indicator","setTimeout","renderNewView","normalizedIndicator","initImageDiff","fileEl","diff","WRAPPER","LOADING_HTML","loadingIconForLegacyJS","outerHTML","ERROR_HTML","COLLAPSED_HTML","renderVueComponentForLegacyJS","GlButton","variant","SingleFileDiff","toggleDiff","$chevronRightIcon","$chevronDownIcon","diffForPath","isOpen","collapsedContent","loadingContent","html","hide","after","target","$target","cb","hasError","getContentHTML","show","axios","then","syntaxHighlight","$file","FilesCommentButton","is","initImageDiffHelper","catch","createAlert","message","isBound","Diff","mergeRequestEventHub","attributes","$elements","toArray","formatElementToObject","reduce","_merge","fileHash","elements","undefined","rawButton","renderedButton","renderedViewer","rawViewer","mrHub","tab","getElementById","isLocked","firstFile","first","prototype","hasOwnProperty","handleClickUnfold","handleClickLineNum","handleParallelLineDown","$e","viewTypeSwitch","getLocationHash","highlightSelectedLine","openAnchoredDiff","prepareRenderedDiff","oldLineNumber","newLineNumber","lineNumbers","bottom","since","to","unfold","lineNumber","prevNewLine","prev","parents","link","params","replaceWith","locationHash","anchoredDiff","split","diffFile","clickTarget","hash","attr","preventDefault","window","history","pushState","location","line","table","lineClass","diffViewType","click","originalEvent","diffSource","URL","getAttribute","href","pathname","$emit","source","toString","children","elm","$diffFiles","allElements","elementsForRenderedDiff","fileElements","entries","onclick","showRawViewer","showRenderedViewer","module","exports","i"],"mappings":"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","file":"commons-pages.groups.wikis.diff-pages.projects.commit.show-pages.projects.compare.show-pages.project-e73dea2d.f5a03386.chunk.js","sourcesContent":["<script>\nimport { GlDisclosureDropdown, GlIcon, GlSearchBoxByType, GlSprintf } from '@gitlab/ui';\nimport fuzzaldrinPlus from 'fuzzaldrin-plus';\nimport { __, n__, s__, sprintf } from '~/locale';\n\nexport const i18n = {\n messageAdditionsDeletions: s__('Diffs|with %{additions} and %{deletions}'),\n noFilesFound: __('No files found.'),\n noFileNameAvailable: s__('Diffs|No file name available'),\n searchFiles: __('Search files'),\n};\n\nconst variantCssColorMap = {\n success: 'gl-text-success',\n danger: 'gl-text-danger',\n};\n\nexport default {\n i18n,\n components: {\n GlDisclosureDropdown,\n GlIcon,\n GlSearchBoxByType,\n GlSprintf,\n },\n props: {\n changed: {\n type: Number,\n required: true,\n },\n added: {\n type: Number,\n required: true,\n },\n deleted: {\n type: Number,\n required: true,\n },\n files: {\n type: Array,\n required: true,\n },\n },\n data() {\n return {\n search: '',\n };\n },\n computed: {\n filteredFiles() {\n return this.search.length > 0\n ? fuzzaldrinPlus.filter(this.files, this.search, { key: 'name' })\n : this.files;\n },\n dropdownItems() {\n return this.filteredFiles.map((file) => {\n return {\n ...file,\n text: file.name || this.$options.i18n.noFileNameAvailable,\n iconColor: variantCssColorMap[file.iconColor],\n };\n });\n },\n messageChanged() {\n return sprintf(\n n__(\n 'Diffs|Showing %{dropdownStart}%{count} changed file%{dropdownEnd}',\n 'Diffs|Showing %{dropdownStart}%{count} changed files%{dropdownEnd}',\n this.changed,\n ),\n { count: this.changed },\n );\n },\n },\n methods: {\n focusInput() {\n this.$refs.search.focusInput();\n },\n focusFirstItem() {\n if (!this.filteredFiles.length) return;\n this.$el.querySelector('.gl-new-dropdown-item:first-child').focus();\n },\n additionsText(numberOfChanges = this.added) {\n return n__('Diffs|%d addition', 'Diffs|%d additions', numberOfChanges);\n },\n deletionsText(numberOfChanges = this.deleted) {\n return n__('Diffs|%d deletion', 'Diffs|%d deletions', numberOfChanges);\n },\n },\n};\n</script>\n\n<template>\n <div>\n <gl-sprintf :message=\"messageChanged\">\n <template #dropdown=\"{ content: dropdownText }\">\n <gl-disclosure-dropdown\n :toggle-text=\"dropdownText\"\n :items=\"dropdownItems\"\n category=\"tertiary\"\n variant=\"confirm\"\n data-testid=\"diff-stats-dropdown\"\n class=\"gl-align-baseline\"\n toggle-class=\"!gl-px-0 !gl-font-bold\"\n fluid-width\n @shown=\"focusInput\"\n >\n <template #header>\n <gl-search-box-by-type\n ref=\"search\"\n v-model.trim=\"search\"\n :placeholder=\"$options.i18n.searchFiles\"\n class=\"gl-mx-3 gl-my-4\"\n @keydown.down=\"focusFirstItem\"\n />\n <span v-if=\"!filteredFiles.length\" class=\"gl-mx-3\">\n {{ $options.i18n.noFilesFound }}\n </span>\n </template>\n <template #list-item=\"{ item }\">\n <div class=\"gl-flex gl-items-center gl-gap-3 gl-overflow-hidden\">\n <gl-icon :name=\"item.icon\" :class=\"item.iconColor\" class=\"gl-shrink-0\" />\n <div class=\"gl-grow gl-overflow-hidden\">\n <div class=\"gl-flex\">\n <span\n class=\"gl-mr-3 gl-grow gl-font-bold\"\n :class=\"item.name ? 'gl-truncate' : 'gl-italic gl-text-subtle'\"\n >{{ item.text }}</span\n >\n <span class=\"gl-ml-auto gl-whitespace-nowrap\" aria-hidden=\"true\">\n <span class=\"gl-text-success\">+{{ item.added }}</span>\n <span class=\"gl-text-danger\">-{{ item.removed }}</span>\n </span>\n <span class=\"gl-sr-only\"\n >{{ additionsText(item.added) }}, {{ deletionsText(item.removed) }}</span\n >\n </div>\n <div class=\"gl-overflow-hidden gl-text-ellipsis gl-text-subtle\">\n {{ item.path }}\n </div>\n </div>\n </div>\n </template>\n </gl-disclosure-dropdown>\n </template>\n </gl-sprintf>\n <span\n class=\"diff-stats-additions-deletions-expanded\"\n data-testid=\"diff-stats-additions-deletions-expanded\"\n >\n <gl-sprintf :message=\"$options.i18n.messageAdditionsDeletions\">\n <template #additions>\n <span class=\"gl-font-bold gl-text-success\">{{ additionsText() }}</span>\n </template>\n <template #deletions>\n <span class=\"gl-font-bold gl-text-danger\">{{ deletionsText() }}</span>\n </template>\n </gl-sprintf>\n </span>\n </div>\n</template>\n\n<style scoped>\n/* TODO: Use max-height prop when gitlab-ui got updated.\nSee https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2374 */\n::v-deep .gl-new-dropdown-inner {\n max-height: 310px;\n}\n</style>\n","import mod from \"-!../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./diff_stats_dropdown.vue?vue&type=script&lang=js\"; export default mod; export * from \"-!../../../../../node_modules/thread-loader/dist/cjs.js??ref--13-0!../../../../../node_modules/babel-loader/lib/index.js??ref--13-1!../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./diff_stats_dropdown.vue?vue&type=script&lang=js\"","import api from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../../../node_modules/css-loader/dist/cjs.js??ref--20-1!../../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./diff_stats_dropdown.vue?vue&type=style&index=0&id=5fa5a073&prod&scoped=true&lang=css\";\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import { render, staticRenderFns } from \"./diff_stats_dropdown.vue?vue&type=template&id=5fa5a073&scoped=true\"\nimport script from \"./diff_stats_dropdown.vue?vue&type=script&lang=js\"\nexport * from \"./diff_stats_dropdown.vue?vue&type=script&lang=js\"\nimport style0 from \"./diff_stats_dropdown.vue?vue&type=style&index=0&id=5fa5a073&prod&scoped=true&lang=css\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"5fa5a073\",\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',[_c('gl-sprintf',{attrs:{\"message\":_vm.messageChanged},scopedSlots:_vm._u([{key:\"dropdown\",fn:function({ content: dropdownText }){return [_c('gl-disclosure-dropdown',{staticClass:\"gl-align-baseline\",attrs:{\"toggle-text\":dropdownText,\"items\":_vm.dropdownItems,\"category\":\"tertiary\",\"variant\":\"confirm\",\"data-testid\":\"diff-stats-dropdown\",\"toggle-class\":\"!gl-px-0 !gl-font-bold\",\"fluid-width\":\"\"},on:{\"shown\":_vm.focusInput},scopedSlots:_vm._u([{key:\"header\",fn:function(){return [_c('gl-search-box-by-type',{ref:\"search\",staticClass:\"gl-mx-3 gl-my-4\",attrs:{\"placeholder\":_vm.$options.i18n.searchFiles},on:{\"keydown\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"down\",40,$event.key,[\"Down\",\"ArrowDown\"]))return null;return _vm.focusFirstItem.apply(null, arguments)}},model:{value:(_vm.search),callback:function ($$v) {_vm.search=(typeof $$v === 'string'? $$v.trim(): $$v)},expression:\"search\"}}),_vm._v(\" \"),(!_vm.filteredFiles.length)?_c('span',{staticClass:\"gl-mx-3\"},[_vm._v(\"\\n \"+_vm._s(_vm.$options.i18n.noFilesFound)+\"\\n \")]):_vm._e()]},proxy:true},{key:\"list-item\",fn:function({ item }){return [_c('div',{staticClass:\"gl-flex gl-items-center gl-gap-3 gl-overflow-hidden\"},[_c('gl-icon',{staticClass:\"gl-shrink-0\",class:item.iconColor,attrs:{\"name\":item.icon}}),_vm._v(\" \"),_c('div',{staticClass:\"gl-grow gl-overflow-hidden\"},[_c('div',{staticClass:\"gl-flex\"},[_c('span',{staticClass:\"gl-mr-3 gl-grow gl-font-bold\",class:item.name ? 'gl-truncate' : 'gl-italic gl-text-subtle'},[_vm._v(_vm._s(item.text))]),_vm._v(\" \"),_c('span',{staticClass:\"gl-ml-auto gl-whitespace-nowrap\",attrs:{\"aria-hidden\":\"true\"}},[_c('span',{staticClass:\"gl-text-success\"},[_vm._v(\"+\"+_vm._s(item.added))]),_vm._v(\" \"),_c('span',{staticClass:\"gl-text-danger\"},[_vm._v(\"-\"+_vm._s(item.removed))])]),_vm._v(\" \"),_c('span',{staticClass:\"gl-sr-only\"},[_vm._v(_vm._s(_vm.additionsText(item.added))+\", \"+_vm._s(_vm.deletionsText(item.removed)))])]),_vm._v(\" \"),_c('div',{staticClass:\"gl-overflow-hidden gl-text-ellipsis gl-text-subtle\"},[_vm._v(\"\\n \"+_vm._s(item.path)+\"\\n \")])])],1)]}}],null,true)})]}}])}),_vm._v(\" \"),_c('span',{staticClass:\"diff-stats-additions-deletions-expanded\",attrs:{\"data-testid\":\"diff-stats-additions-deletions-expanded\"}},[_c('gl-sprintf',{attrs:{\"message\":_vm.$options.i18n.messageAdditionsDeletions},scopedSlots:_vm._u([{key:\"additions\",fn:function(){return [_c('span',{staticClass:\"gl-font-bold gl-text-success\"},[_vm._v(_vm._s(_vm.additionsText()))])]},proxy:true},{key:\"deletions\",fn:function(){return [_c('span',{staticClass:\"gl-font-bold gl-text-danger\"},[_vm._v(_vm._s(_vm.deletionsText()))])]},proxy:true}])})],1)],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import Vue from 'vue';\nimport DiffStatsDropdown from '~/vue_shared/components/diff_stats_dropdown.vue';\n\nexport const initDiffStatsDropdown = () => {\n const el = document.querySelector('.js-diff-stats-dropdown');\n\n if (!el) {\n return false;\n }\n\n const { changed, added, deleted, files } = el.dataset;\n\n return new Vue({\n el,\n render: (createElement) =>\n createElement(DiffStatsDropdown, {\n props: {\n changed: parseInt(changed, 10),\n added: parseInt(added, 10),\n deleted: parseInt(deleted, 10),\n files: JSON.parse(files),\n },\n }),\n });\n};\n","/* Developer beware! Do not add logic to showButton or hideButton\n * that will force a reflow. Doing so will create a significant performance\n * bottleneck for pages with large diffs. For a comprehensive list of what\n * causes reflows, visit https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n */\n\nimport { getCookie } from '~/lib/utils/common_utils';\n\nconst LINE_NUMBER_CLASS = 'diff-line-num';\nconst UNFOLDABLE_LINE_CLASS = 'js-unfold';\nconst NO_COMMENT_CLASS = 'no-comment-btn';\nconst EMPTY_CELL_CLASS = 'empty-cell';\nconst OLD_LINE_CLASS = 'old_line';\nconst LINE_COLUMN_CLASSES = `.${LINE_NUMBER_CLASS}, .line_content`;\nconst DIFF_CONTAINER_SELECTOR = '.files';\nconst DIFF_EXPANDED_CLASS = 'diff-expanded';\n\nexport default {\n init($diffFile) {\n /* Caching is used only when the following members are *true*.\n * This is because there are likely to be\n * differently configured versions of diffs in the same session.\n * However if these values are true, they\n * will be true in all cases */\n\n if (!this.userCanCreateNote) {\n // data-can-create-note is an empty string when true, otherwise undefined\n this.userCanCreateNote =\n $diffFile.closest(DIFF_CONTAINER_SELECTOR).data('canCreateNote') === '';\n }\n\n this.isParallelView = getCookie('diff_view') === 'parallel';\n\n if (this.userCanCreateNote) {\n $diffFile\n .on('mouseover', LINE_COLUMN_CLASSES, (e) => this.showButton(this.isParallelView, e))\n .on('mouseleave', LINE_COLUMN_CLASSES, (e) => this.hideButton(this.isParallelView, e));\n }\n },\n\n showButton(isParallelView, e) {\n const buttonParentElement = this.getButtonParent(e.currentTarget, isParallelView);\n\n if (!this.validateButtonParent(buttonParentElement)) return;\n\n buttonParentElement.classList.add('is-over');\n buttonParentElement.nextElementSibling.classList.add('is-over');\n },\n\n hideButton(isParallelView, e) {\n const buttonParentElement = this.getButtonParent(e.currentTarget, isParallelView);\n\n buttonParentElement.classList.remove('is-over');\n buttonParentElement.nextElementSibling.classList.remove('is-over');\n },\n\n getButtonParent(hoveredElement, isParallelView) {\n if (isParallelView) {\n if (!hoveredElement.classList.contains(LINE_NUMBER_CLASS)) {\n return hoveredElement.previousElementSibling;\n }\n } else if (!hoveredElement.classList.contains(OLD_LINE_CLASS)) {\n return hoveredElement.parentNode.querySelector(`.${OLD_LINE_CLASS}`);\n }\n return hoveredElement;\n },\n\n validateButtonParent(buttonParentElement) {\n return (\n !buttonParentElement.classList.contains(EMPTY_CELL_CLASS) &&\n !buttonParentElement.classList.contains(UNFOLDABLE_LINE_CLASS) &&\n !buttonParentElement.classList.contains(NO_COMMENT_CLASS) &&\n !buttonParentElement.parentNode.classList.contains(DIFF_EXPANDED_CLASS)\n );\n },\n};\n","/* eslint-disable func-names, consistent-return, one-var, no-return-assign */\n\nimport $ from 'jquery';\n\n// Width where images must fits in, for 2-up this gets divided by 2\nconst availWidth = 900;\nconst viewModes = ['two-up', 'swipe'];\n\nexport default class ImageFile {\n constructor(file) {\n this.file = file;\n this.requestImageInfo($('.two-up.view .frame.deleted img', this.file), () =>\n this.requestImageInfo($('.two-up.view .frame.added img', this.file), () => {\n this.initViewModes();\n\n // Load two-up view after images are loaded\n // so that we can display the correct width and height information\n this.initView('two-up');\n }),\n );\n }\n\n initViewModes() {\n const viewMode = viewModes[0];\n $('.view-modes', this.file).removeClass('gl-hidden');\n $('.view-modes-menu', this.file).on('click', 'li', (event) => {\n if (!$(event.currentTarget).hasClass('active')) {\n return this.activateViewMode(event.currentTarget.className);\n }\n });\n return this.activateViewMode(viewMode);\n }\n\n activateViewMode(viewMode) {\n $('.view-modes-menu li', this.file)\n .removeClass('active')\n .filter(`.${viewMode}`)\n .addClass('active');\n\n $(`.view:visible:not(.${viewMode})`, this.file).addClass('gl-hidden');\n $(`.view.${viewMode}`, this.file).removeClass('gl-hidden');\n\n return this.initView(viewMode);\n }\n\n initView(viewMode) {\n return this.views[viewMode].call(this);\n }\n // eslint-disable-next-line class-methods-use-this\n initDraggable($el, padding, callback) {\n let dragging = false;\n const $body = $('body');\n const $offsetEl = $el.parent();\n const dragStart = function () {\n dragging = true;\n $body.css('user-select', 'none');\n };\n const dragStop = function () {\n dragging = false;\n $body.css('user-select', '');\n };\n const dragMove = function (e) {\n const moveX = e.pageX || e.touches[0].pageX;\n const left = moveX - ($offsetEl.offset().left + padding);\n if (!dragging) return;\n\n callback(e, left);\n };\n\n // eslint-disable-next-line @gitlab/no-global-event-off\n $el.off('mousedown').off('touchstart').on('mousedown', dragStart).on('touchstart', dragStart);\n\n // eslint-disable-next-line @gitlab/no-global-event-off\n $body\n .off('mouseup')\n .off('mousemove')\n .off('touchend')\n .off('touchmove')\n .on('mouseup', dragStop)\n .on('touchend', dragStop)\n .on('mousemove', dragMove)\n .on('touchmove', dragMove);\n }\n\n static prepareFrames(view) {\n let maxWidth = 0;\n let maxHeight = 0;\n $('.frame', view)\n .each((index, frame) => {\n const width = $(frame).width();\n const height = $(frame).height();\n maxWidth = width > maxWidth ? width : maxWidth;\n return (maxHeight = height > maxHeight ? height : maxHeight);\n })\n .css({\n width: maxWidth,\n height: maxHeight,\n });\n return [maxWidth, maxHeight];\n }\n\n views = {\n 'two-up': function () {\n return $('.two-up.view .wrap', this.file).each((index, wrap) => {\n $('img', wrap).each(function () {\n const currentWidth = $(this).width();\n if (currentWidth > availWidth / 2) {\n return $(this).width(availWidth / 2);\n }\n });\n return this.requestImageInfo($('img', wrap), (width, height) => {\n $('.image-info .meta-width', wrap).text(`${width}px`);\n $('.image-info .meta-height', wrap).text(`${height}px`);\n return $('.image-info', wrap).removeClass('gl-hidden');\n });\n });\n },\n swipe() {\n let maxWidth = 0;\n let maxHeight = 0;\n return $('.swipe.view', this.file).each((index, view) => {\n const ref = ImageFile.prepareFrames(view);\n [maxWidth, maxHeight] = ref;\n const $swipeFrame = $('.swipe-frame', view);\n const $swipeWrap = $('.swipe-wrap', view);\n const $swipeBar = $('.swipe-bar', view);\n\n $swipeFrame.css({\n width: maxWidth + 16,\n height: maxHeight + 28,\n });\n $swipeWrap.css({\n width: maxWidth + 1,\n height: maxHeight + 2,\n });\n // Set swipeBar left position to match image frame\n $swipeBar.css({\n left: 1,\n });\n\n const wrapPadding = parseInt($swipeWrap.css('right').replace('px', ''), 10);\n\n this.initDraggable($swipeBar, wrapPadding, (e, left) => {\n if (left > 0 && left < $swipeFrame.width() - wrapPadding * 2) {\n $swipeWrap.width(maxWidth + 1 - left);\n $swipeBar.css('left', left);\n }\n });\n });\n },\n 'onion-skin': function () {\n let maxHeight, maxWidth;\n maxWidth = 0;\n maxHeight = 0;\n const dragTrackWidth = $('.drag-track', this.file).width() - $('.dragger', this.file).width();\n return $('.onion-skin.view', this.file).each((index, view) => {\n const ref = ImageFile.prepareFrames(view);\n [maxWidth, maxHeight] = ref;\n const $frame = $('.onion-skin-frame', view);\n const $frameAdded = $('.frame.added', view);\n const $track = $('.drag-track', view);\n const $dragger = $('.dragger', $track);\n\n $frame.css({\n width: maxWidth + 16,\n height: maxHeight + 28,\n });\n $('.swipe-wrap', view).css({\n width: maxWidth + 1,\n height: maxHeight + 2,\n });\n $dragger.css({\n left: dragTrackWidth,\n });\n\n $frameAdded.css('opacity', 1);\n const framePadding = parseInt($frameAdded.css('right').replace('px', ''), 10);\n\n this.initDraggable($dragger, framePadding, (e, left) => {\n const opacity = left / dragTrackWidth;\n\n if (opacity >= 0 && opacity <= 1) {\n $dragger.css('left', left);\n $frameAdded.css('opacity', opacity);\n }\n });\n });\n },\n };\n\n requestImageInfo(img, callback) {\n const domImg = img.get(0);\n if (domImg) {\n if (domImg.complete) {\n return callback.call(this, domImg.naturalWidth, domImg.naturalHeight);\n }\n return img.on('load', () => callback.call(this, domImg.naturalWidth, domImg.naturalHeight));\n }\n }\n}\n","import { spriteIcon } from '~/lib/utils/common_utils';\n\nexport function createImageBadge(noteId, { x, y }, classNames = []) {\n const buttonEl = document.createElement('button');\n const classList = classNames.concat(['js-image-badge']);\n classList.forEach((className) => buttonEl.classList.add(className));\n buttonEl.setAttribute('type', 'button');\n buttonEl.setAttribute('disabled', true);\n buttonEl.dataset.noteId = noteId;\n buttonEl.style.left = `${x}px`;\n buttonEl.style.top = `${y}px`;\n\n return buttonEl;\n}\n\nexport function addImageBadge(containerEl, { coordinate, badgeText, noteId }) {\n const buttonEl = createImageBadge(noteId, coordinate, [\n 'gl-flex',\n 'gl-items-center',\n 'gl-justify-center',\n 'gl-text-sm',\n 'design-note-pin',\n 'on-image',\n 'gl-absolute',\n ]);\n buttonEl.textContent = badgeText;\n\n containerEl.appendChild(buttonEl);\n}\n\nexport function addImageCommentBadge(containerEl, { coordinate, noteId }) {\n const buttonEl = createImageBadge(noteId, coordinate, ['image-comment-badge']);\n // eslint-disable-next-line no-unsanitized/property\n buttonEl.innerHTML = spriteIcon('image-comment-dark');\n\n containerEl.appendChild(buttonEl);\n}\n\nexport function addAvatarBadge(el, event) {\n const { noteId, badgeNumber } = event.detail;\n\n // Add design pin to new comment\n const avatarBadgeEl = el.querySelector(`#${noteId} .design-note-pin`);\n avatarBadgeEl.textContent = badgeNumber;\n avatarBadgeEl.classList.remove('hidden');\n}\n","import { spriteIcon } from '~/lib/utils/common_utils';\n\nexport function addCommentIndicator(containerEl, { x, y }) {\n const buttonEl = document.createElement('button');\n buttonEl.classList.add('gl-border-0');\n buttonEl.classList.add('gl-bg-transparent');\n buttonEl.classList.add('comment-indicator');\n buttonEl.setAttribute('type', 'button');\n buttonEl.style.left = `${x}px`;\n buttonEl.style.top = `${y}px`;\n\n // eslint-disable-next-line no-unsanitized/property\n buttonEl.innerHTML = spriteIcon('image-comment-dark');\n\n containerEl.appendChild(buttonEl);\n}\n\nexport function removeCommentIndicator(imageFrameEl) {\n const commentIndicatorEl = imageFrameEl.querySelector('.comment-indicator');\n const imageEl = imageFrameEl.querySelector('img');\n const willRemove = Boolean(commentIndicatorEl);\n let meta = {};\n\n if (willRemove) {\n meta = {\n x: parseInt(commentIndicatorEl.style.left, 10),\n y: parseInt(commentIndicatorEl.style.top, 10),\n image: {\n width: imageEl.width,\n height: imageEl.height,\n },\n };\n\n commentIndicatorEl.remove();\n }\n\n return { ...meta, removed: willRemove };\n}\n\nexport function showCommentIndicator(imageFrameEl, coordinate) {\n const { x, y } = coordinate;\n const commentIndicatorEl = imageFrameEl.querySelector('.comment-indicator');\n\n if (commentIndicatorEl) {\n commentIndicatorEl.style.left = `${x}px`;\n commentIndicatorEl.style.top = `${y}px`;\n } else {\n addCommentIndicator(imageFrameEl, coordinate);\n }\n}\n\nexport function commentIndicatorOnClick(event) {\n // Prevent from triggering onAddImageDiffNote in notes.js\n event.stopPropagation();\n\n const buttonEl = event.currentTarget;\n const diffViewerEl = buttonEl.closest('.diff-viewer');\n const textareaEl = diffViewerEl.querySelector('.note-container .note-textarea');\n textareaEl.focus();\n}\n","import imageDiffHelper from './helpers/index';\n\nconst defaultMeta = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n};\n\nexport default class ImageBadge {\n constructor(options) {\n const { noteId, discussionId } = options;\n\n this.actual = options.actual || defaultMeta;\n this.browser = options.browser || defaultMeta;\n this.noteId = noteId;\n this.discussionId = discussionId;\n\n if (options.imageEl && !options.browser) {\n this.browser = imageDiffHelper.resizeCoordinatesToImageElement(options.imageEl, this.actual);\n }\n }\n}\n","import * as badgeHelper from './badge_helper';\nimport * as commentIndicatorHelper from './comment_indicator_helper';\nimport * as domHelper from './dom_helper';\nimport * as utilsHelper from './utils_helper';\n\nexport default {\n addCommentIndicator: commentIndicatorHelper.addCommentIndicator,\n removeCommentIndicator: commentIndicatorHelper.removeCommentIndicator,\n showCommentIndicator: commentIndicatorHelper.showCommentIndicator,\n commentIndicatorOnClick: commentIndicatorHelper.commentIndicatorOnClick,\n\n addImageBadge: badgeHelper.addImageBadge,\n addImageCommentBadge: badgeHelper.addImageCommentBadge,\n addAvatarBadge: badgeHelper.addAvatarBadge,\n\n setPositionDataAttribute: domHelper.setPositionDataAttribute,\n updateDiscussionAvatarBadgeNumber: domHelper.updateDiscussionAvatarBadgeNumber,\n updateDiscussionBadgeNumber: domHelper.updateDiscussionBadgeNumber,\n toggleCollapsed: domHelper.toggleCollapsed,\n\n resizeCoordinatesToImageElement: utilsHelper.resizeCoordinatesToImageElement,\n generateBadgeFromDiscussionDOM: utilsHelper.generateBadgeFromDiscussionDOM,\n getTargetSelection: utilsHelper.getTargetSelection,\n};\n","export function setPositionDataAttribute(el, options) {\n // Update position data attribute so that the\n // new comment form can use this data for ajax request\n const { x, y, width, height } = options;\n const { position } = el.dataset;\n\n const positionObject = { ...JSON.parse(position), x, y, width, height };\n\n el.dataset.position = JSON.stringify(positionObject);\n}\n\nexport function updateDiscussionAvatarBadgeNumber(discussionEl, newBadgeNumber) {\n const avatarBadgeEl = discussionEl.querySelector('.image-diff-avatar-link .design-note-pin');\n avatarBadgeEl.textContent = newBadgeNumber;\n}\n\nexport function updateDiscussionBadgeNumber(discussionEl, newBadgeNumber) {\n const discussionBadgeEl = discussionEl.querySelector('.design-note-pin');\n discussionBadgeEl.textContent = newBadgeNumber;\n}\n\nexport function toggleCollapsed(event) {\n const toggleButtonEl = event.currentTarget;\n const discussionNotesEl = toggleButtonEl.closest('.discussion-notes');\n const formEl = discussionNotesEl.querySelector('.discussion-form');\n const isCollapsed = discussionNotesEl.classList.contains('collapsed');\n\n if (isCollapsed) {\n discussionNotesEl.classList.remove('collapsed');\n } else {\n discussionNotesEl.classList.add('collapsed');\n }\n\n // Override the inline display style set in notes.js\n if (formEl && !isCollapsed) {\n formEl.style.display = 'none';\n } else if (formEl && isCollapsed) {\n formEl.style.display = 'block';\n }\n}\n","import ImageBadge from '../image_badge';\n\nexport function resizeCoordinatesToImageElement(imageEl, meta) {\n const { x, y, width, height } = meta;\n\n const imageWidth = imageEl.width;\n const imageHeight = imageEl.height;\n\n const widthRatio = imageWidth / width;\n const heightRatio = imageHeight / height;\n\n return {\n x: Math.round(x * widthRatio),\n y: Math.round(y * heightRatio),\n width: imageWidth,\n height: imageHeight,\n };\n}\n\nexport function generateBadgeFromDiscussionDOM(imageFrameEl, discussionEl) {\n const position = JSON.parse(discussionEl.dataset.position);\n const firstNoteEl = discussionEl.querySelector('.note');\n const badge = new ImageBadge({\n actual: position,\n imageEl: imageFrameEl.querySelector('img'),\n noteId: firstNoteEl.id,\n discussionId: discussionEl.dataset.discussionId,\n });\n\n return badge;\n}\n\nexport function getTargetSelection(event) {\n const containerEl = event.currentTarget;\n const imageEl = containerEl.querySelector('img');\n\n const x = event.offsetX;\n const y = event.offsetY;\n\n const { width, height } = imageEl;\n\n const actualWidth = imageEl.naturalWidth;\n const actualHeight = imageEl.naturalHeight;\n\n const widthRatio = actualWidth / width;\n const heightRatio = actualHeight / height;\n\n // Browser will include the frame as a clickable target,\n // which would result in potential 1px out of bounds value\n // This bound the coordinates to inside the frame\n const normalizedX = Math.max(0, x) && Math.min(x, width);\n const normalizedY = Math.max(0, y) && Math.min(y, height);\n\n return {\n browser: {\n x: normalizedX,\n y: normalizedY,\n width,\n height,\n },\n actual: {\n // Round x, y so that we don't need to deal with decimals\n x: Math.round(normalizedX * widthRatio),\n y: Math.round(normalizedY * heightRatio),\n width: actualWidth,\n height: actualHeight,\n },\n };\n}\n","import $ from 'jquery';\nimport { isImageLoaded } from '../lib/utils/image_utility';\nimport imageDiffHelper from './helpers/index';\nimport ImageBadge from './image_badge';\n\nexport default class ImageDiff {\n constructor(el, options) {\n this.el = el;\n this.canCreateNote = Boolean(options && options.canCreateNote);\n this.renderCommentBadge = Boolean(options && options.renderCommentBadge);\n this.$noteContainer = $('.note-container', this.el);\n this.imageBadges = [];\n }\n\n init() {\n this.imageFrameEl = this.el.querySelector('.diff-file .js-image-frame');\n this.imageEl = this.imageFrameEl.querySelector('img');\n\n this.bindEvents();\n }\n\n bindEvents() {\n this.imageClickedWrapper = this.imageClicked.bind(this);\n this.imageBlurredWrapper = imageDiffHelper.removeCommentIndicator.bind(null, this.imageFrameEl);\n this.addBadgeWrapper = this.addBadge.bind(this);\n this.removeBadgeWrapper = this.removeBadge.bind(this);\n this.renderBadgesWrapper = this.renderBadges.bind(this);\n\n // Render badges\n if (isImageLoaded(this.imageEl)) {\n this.renderBadges();\n } else {\n this.imageEl.addEventListener('load', this.renderBadgesWrapper);\n }\n\n // jquery makes the event delegation here much simpler\n this.$noteContainer.on('click', '.js-diff-notes-toggle', imageDiffHelper.toggleCollapsed);\n $(this.el).on('click', '.comment-indicator', imageDiffHelper.commentIndicatorOnClick);\n\n if (this.canCreateNote) {\n this.el.addEventListener('click.imageDiff', this.imageClickedWrapper);\n this.el.addEventListener('blur.imageDiff', this.imageBlurredWrapper);\n this.el.addEventListener('addBadge.imageDiff', this.addBadgeWrapper);\n this.el.addEventListener('removeBadge.imageDiff', this.removeBadgeWrapper);\n }\n }\n\n imageClicked(event) {\n const customEvent = event.detail;\n const selection = imageDiffHelper.getTargetSelection(customEvent);\n const el = customEvent.currentTarget;\n\n imageDiffHelper.setPositionDataAttribute(el, selection.actual);\n imageDiffHelper.showCommentIndicator(this.imageFrameEl, selection.browser);\n }\n\n renderBadges() {\n const discussionsEls = this.el.querySelectorAll('.note-container .discussion-notes .notes');\n [...discussionsEls].forEach(this.renderBadge.bind(this));\n }\n\n renderBadge(discussionEl, index) {\n const imageBadge = imageDiffHelper.generateBadgeFromDiscussionDOM(\n this.imageFrameEl,\n discussionEl,\n );\n\n this.imageBadges.push(imageBadge);\n\n const options = {\n coordinate: imageBadge.browser,\n noteId: imageBadge.noteId,\n };\n\n if (this.renderCommentBadge) {\n imageDiffHelper.addImageCommentBadge(this.imageFrameEl, options);\n } else {\n const numberBadgeOptions = { ...options, badgeText: index + 1 };\n\n imageDiffHelper.addImageBadge(this.imageFrameEl, numberBadgeOptions);\n }\n }\n\n addBadge(event) {\n const { x, y, width, height, noteId, discussionId } = event.detail;\n const badgeText = this.imageBadges.length + 1;\n const imageBadge = new ImageBadge({\n actual: {\n x,\n y,\n width,\n height,\n },\n imageEl: this.imageFrameEl.querySelector('img'),\n noteId,\n discussionId,\n });\n\n this.imageBadges.push(imageBadge);\n\n imageDiffHelper.addImageBadge(this.imageFrameEl, {\n coordinate: imageBadge.browser,\n badgeText,\n noteId,\n });\n\n imageDiffHelper.addAvatarBadge(this.el, {\n detail: {\n noteId,\n badgeNumber: badgeText,\n },\n });\n\n const discussionEl = this.el.querySelector(`#discussion_${discussionId}`);\n imageDiffHelper.updateDiscussionBadgeNumber(discussionEl, badgeText);\n }\n\n removeBadge(event) {\n const { badgeNumber } = event.detail;\n const indexToRemove = badgeNumber - 1;\n const imageBadgeEls = this.imageFrameEl.querySelectorAll('.design-note-pin');\n\n if (this.imageBadges.length !== badgeNumber) {\n // Cascade badges count numbers for (avatar badges + image badges)\n this.imageBadges.forEach((badge, index) => {\n if (index > indexToRemove) {\n const { discussionId } = badge;\n const updatedBadgeNumber = index;\n const discussionEl = this.el.querySelector(`#discussion_${discussionId}`);\n\n imageBadgeEls[index].textContent = updatedBadgeNumber;\n\n imageDiffHelper.updateDiscussionBadgeNumber(discussionEl, updatedBadgeNumber);\n imageDiffHelper.updateDiscussionAvatarBadgeNumber(discussionEl, updatedBadgeNumber);\n }\n });\n }\n\n this.imageBadges.splice(indexToRemove, 1);\n\n const imageBadgeEl = imageBadgeEls[indexToRemove];\n imageBadgeEl.remove();\n }\n}\n","export function isImageLoaded(element) {\n return element.complete && element.naturalHeight !== 0;\n}\n","export const viewTypes = {\n TWO_UP: 'TWO_UP',\n SWIPE: 'SWIPE',\n ONION_SKIN: 'ONION_SKIN',\n};\n\nexport function isValidViewType(validate) {\n return Boolean(Object.getOwnPropertyNames(viewTypes).find((viewType) => viewType === validate));\n}\n","import imageDiffHelper from './helpers/index';\nimport ImageDiff from './image_diff';\nimport { viewTypes, isValidViewType } from './view_types';\n\nexport default class ReplacedImageDiff extends ImageDiff {\n init(defaultViewType = viewTypes.TWO_UP) {\n this.imageFrameEls = {\n [viewTypes.TWO_UP]: this.el.querySelector('.two-up .js-image-frame'),\n [viewTypes.SWIPE]: this.el.querySelector('.swipe .js-image-frame'),\n [viewTypes.ONION_SKIN]: this.el.querySelector('.onion-skin .js-image-frame'),\n };\n\n const viewModesEl = this.el.querySelector('.view-modes-menu');\n this.viewModesEls = {\n [viewTypes.TWO_UP]: viewModesEl.querySelector('.two-up'),\n [viewTypes.SWIPE]: viewModesEl.querySelector('.swipe'),\n [viewTypes.ONION_SKIN]: viewModesEl.querySelector('.onion-skin'),\n };\n\n this.currentView = defaultViewType;\n this.generateImageEls();\n this.bindEvents();\n }\n\n generateImageEls() {\n this.imageEls = {};\n\n const viewTypeNames = Object.getOwnPropertyNames(viewTypes);\n viewTypeNames.forEach((viewType) => {\n this.imageEls[viewType] = this.imageFrameEls[viewType].querySelector('img');\n });\n }\n\n bindEvents() {\n super.bindEvents();\n\n this.changeToViewTwoUp = this.changeView.bind(this, viewTypes.TWO_UP);\n this.changeToViewSwipe = this.changeView.bind(this, viewTypes.SWIPE);\n this.changeToViewOnionSkin = this.changeView.bind(this, viewTypes.ONION_SKIN);\n\n this.viewModesEls[viewTypes.TWO_UP].addEventListener('click', this.changeToViewTwoUp);\n this.viewModesEls[viewTypes.SWIPE].addEventListener('click', this.changeToViewSwipe);\n this.viewModesEls[viewTypes.ONION_SKIN].addEventListener('click', this.changeToViewOnionSkin);\n }\n\n get imageEl() {\n return this.imageEls[this.currentView];\n }\n\n get imageFrameEl() {\n return this.imageFrameEls[this.currentView];\n }\n\n changeView(newView) {\n if (!isValidViewType(newView)) {\n return;\n }\n\n const indicator = imageDiffHelper.removeCommentIndicator(this.imageFrameEl);\n\n this.currentView = newView;\n\n // Clear existing badges on new view\n const existingBadges = this.imageFrameEl.querySelectorAll('.design-note-pin');\n [...existingBadges].map((badge) => badge.remove());\n\n // Remove existing references to old view image badges\n this.imageBadges = [];\n\n // Image_file.js has a fade animation of 200ms for loading the view\n // Need to wait an additional 250ms for the images to be displayed\n // on window in order to re-normalize their dimensions\n setTimeout(this.renderNewView.bind(this, indicator), 250);\n }\n\n renderNewView(indicator) {\n // Generate badge coordinates on new view\n this.renderBadges();\n\n // Re-render indicator in new view\n if (indicator.removed) {\n const normalizedIndicator = imageDiffHelper.resizeCoordinatesToImageElement(this.imageEl, {\n x: indicator.x,\n y: indicator.y,\n width: indicator.image.width,\n height: indicator.image.height,\n });\n imageDiffHelper.showCommentIndicator(this.imageFrameEl, normalizedIndicator);\n }\n }\n}\n","import ImageFile from '~/commit/image_file';\nimport ImageDiff from '../image_diff';\nimport ReplacedImageDiff from '../replaced_image_diff';\n\nfunction initImageDiff(fileEl, canCreateNote, renderCommentBadge) {\n const options = {\n canCreateNote,\n renderCommentBadge,\n };\n let diff;\n\n // ImageFile needs to be invoked before initImageDiff so that badges\n // can mount to the correct location\n new ImageFile(fileEl); // eslint-disable-line no-new\n\n if (fileEl.querySelector('.diff-file .js-single-image')) {\n diff = new ImageDiff(fileEl, options);\n diff.init();\n } else if (fileEl.querySelector('.diff-file .js-replaced-image')) {\n diff = new ReplacedImageDiff(fileEl, options);\n diff.init();\n }\n\n return diff;\n}\n\nexport default { initImageDiff };\n","import $ from 'jquery';\nimport { GlButton } from '@gitlab/ui';\nimport { createAlert } from '~/alert';\nimport { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';\nimport { renderVueComponentForLegacyJS } from '~/render_vue_component_for_legacy_js';\nimport { spriteIcon } from '~/lib/utils/common_utils';\nimport FilesCommentButton from './files_comment_button';\nimport initImageDiffHelper from './image_diff/helpers/init_image_diff';\nimport axios from './lib/utils/axios_utils';\nimport { __ } from './locale';\nimport syntaxHighlight from './syntax_highlight';\n\nconst WRAPPER = '<div class=\"diff-content\"></div>';\nconst LOADING_HTML = loadingIconForLegacyJS().outerHTML;\nconst ERROR_HTML = `<div class=\"nothing-here-block\">${spriteIcon(\n 'warning-solid',\n 's16',\n)} Could not load diff</div>`;\nconst CLICK_TO_EXPAND_BUTTON_HTML = renderVueComponentForLegacyJS(\n GlButton,\n {\n class: 'click-to-expand',\n props: { variant: 'link' },\n },\n __('Click to expand it.'),\n).outerHTML;\nconst COLLAPSED_HTML = `<div class=\"nothing-here-block diff-collapsed\">This diff is collapsed. ${CLICK_TO_EXPAND_BUTTON_HTML}</div>`;\n\nexport default class SingleFileDiff {\n constructor(file) {\n this.file = file;\n this.toggleDiff = this.toggleDiff.bind(this);\n this.content = $('.diff-content', this.file);\n this.$chevronRightIcon = $('.diff-toggle-caret .chevron-right', this.file);\n this.$chevronDownIcon = $('.diff-toggle-caret .chevron-down', this.file);\n this.diffForPath = this.content\n .find('div:not(.note-text)[data-diff-for-path]')\n .data('diffForPath');\n this.isOpen = !this.diffForPath;\n if (this.diffForPath) {\n this.collapsedContent = this.content;\n this.loadingContent = $(WRAPPER).addClass('loading').html(LOADING_HTML).hide();\n this.content = null;\n this.collapsedContent.after(this.loadingContent);\n this.$chevronRightIcon.removeClass('gl-hidden');\n } else {\n this.collapsedContent = $(WRAPPER).html(COLLAPSED_HTML).hide();\n this.content.after(this.collapsedContent);\n this.$chevronDownIcon.removeClass('gl-hidden');\n }\n\n $('.js-file-title', this.file).on('click', (e) => {\n this.toggleDiff($(e.target));\n });\n $('.click-to-expand', this.file).on('click', (e) => {\n this.toggleDiff($(e.currentTarget));\n });\n }\n\n toggleDiff($target, cb) {\n if (\n !$target.hasClass('js-file-title') &&\n !$target.hasClass('click-to-expand') &&\n !$target.closest('.diff-toggle-caret').length > 0\n )\n return;\n this.isOpen = !this.isOpen;\n if (!this.isOpen && !this.hasError) {\n this.content.hide();\n this.$chevronRightIcon.removeClass('gl-hidden');\n this.$chevronDownIcon.addClass('gl-hidden');\n this.collapsedContent.show();\n } else if (this.content) {\n this.collapsedContent.hide();\n this.content.show();\n this.$chevronDownIcon.removeClass('gl-hidden');\n this.$chevronRightIcon.addClass('gl-hidden');\n } else {\n this.$chevronDownIcon.removeClass('gl-hidden');\n this.$chevronRightIcon.addClass('gl-hidden');\n return this.getContentHTML(cb); // eslint-disable-line consistent-return\n }\n }\n\n getContentHTML(cb) {\n this.collapsedContent.hide();\n this.loadingContent.show();\n\n return axios\n .get(this.diffForPath)\n .then(({ data }) => {\n this.loadingContent.hide();\n if (data.html) {\n this.content = $(data.html);\n syntaxHighlight(this.content);\n } else {\n this.hasError = true;\n this.content = $(ERROR_HTML);\n }\n this.collapsedContent.after(this.content);\n\n const $file = $(this.file);\n FilesCommentButton.init($file);\n\n const canCreateNote = $file.closest('.files').is('[data-can-create-note]');\n initImageDiffHelper.initImageDiff($file[0], canCreateNote);\n\n if (cb) cb();\n })\n .catch(() => {\n createAlert({\n message: __('An error occurred while retrieving diff'),\n });\n });\n }\n}\n","import $ from 'jquery';\nimport { merge } from 'lodash';\nimport { createAlert } from '~/alert';\nimport axios from '~/lib/utils/axios_utils';\nimport { __ } from '~/locale';\nimport FilesCommentButton from './files_comment_button';\nimport initImageDiffHelper from './image_diff/helpers/init_image_diff';\nimport { getLocationHash } from './lib/utils/url_utility';\nimport SingleFileDiff from './single_file_diff';\n\nconst UNFOLD_COUNT = 20;\nlet isBound = false;\n\nexport default class Diff {\n constructor({ mergeRequestEventHub } = {}) {\n const $diffFile = $('.files .diff-file');\n\n if (mergeRequestEventHub) {\n this.mrHub = mergeRequestEventHub;\n }\n\n $diffFile.each((index, file) => {\n if (!$.data(file, 'singleFileDiff')) {\n $.data(file, 'singleFileDiff', new SingleFileDiff(file));\n }\n });\n\n const tab = document.getElementById('diffs');\n if (!tab || (tab && tab.dataset && tab.dataset.isLocked !== ''))\n FilesCommentButton.init($diffFile);\n\n const firstFile = $('.files').first().get(0);\n const canCreateNote =\n firstFile && Object.prototype.hasOwnProperty.call(firstFile.dataset, 'canCreateNote');\n $diffFile.each((index, file) => initImageDiffHelper.initImageDiff(file, canCreateNote));\n\n if (!isBound) {\n $(document)\n .on('click', '.js-unfold', this.handleClickUnfold.bind(this))\n .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this))\n .on('mousedown', 'td.line_content.parallel', this.handleParallelLineDown.bind(this))\n .on('click', '.inline-parallel-buttons a', ($e) => this.viewTypeSwitch($e));\n isBound = true;\n }\n\n if (getLocationHash()) {\n this.highlightSelectedLine();\n }\n\n this.openAnchoredDiff();\n\n this.prepareRenderedDiff();\n }\n\n handleClickUnfold(e) {\n const $target = $(e.target);\n const [oldLineNumber, newLineNumber] = this.lineNumbers($target.parent());\n const offset = newLineNumber - oldLineNumber;\n const bottom = $target.hasClass('js-unfold-bottom');\n let since;\n let to;\n let unfold = true;\n\n if (bottom) {\n const lineNumber = newLineNumber + 1;\n since = lineNumber;\n to = lineNumber + UNFOLD_COUNT;\n } else {\n const lineNumber = newLineNumber - 1;\n since = lineNumber - UNFOLD_COUNT;\n to = lineNumber;\n\n // make sure we aren't loading more than we need\n const prevNewLine = this.lineNumbers($target.parent().prev())[1];\n if (since <= prevNewLine + 1) {\n since = prevNewLine + 1;\n unfold = false;\n }\n }\n\n const file = $target.parents('.diff-file');\n const link = file.data('blobDiffPath');\n const view = file.data('view');\n\n const params = { since, to, bottom, offset, unfold, view };\n axios\n .get(link, { params })\n .then(({ data }) => $target.parent().replaceWith(data))\n .catch(() =>\n createAlert({\n message: __('An error occurred while loading diff'),\n }),\n );\n }\n\n openAnchoredDiff(cb) {\n const locationHash = getLocationHash();\n const anchoredDiff = locationHash && locationHash.split('_')[0];\n\n if (!anchoredDiff) return;\n\n const diffTitle = $(`#${anchoredDiff}`);\n const diffFile = diffTitle.closest('.diff-file');\n const nothingHereBlock = $('.nothing-here-block:visible', diffFile);\n if (nothingHereBlock.length) {\n const clickTarget = $('.js-file-title, .click-to-expand', diffFile);\n diffFile.data('singleFileDiff').toggleDiff(clickTarget, () => {\n this.highlightSelectedLine();\n this.prepareRenderedDiff();\n if (cb) cb();\n });\n } else if (cb) {\n cb();\n }\n }\n\n handleClickLineNum(e) {\n const hash = $(e.currentTarget).attr('href');\n e.preventDefault();\n if (window.history.pushState) {\n window.history.pushState(null, null, hash);\n } else {\n window.location.hash = hash;\n }\n this.highlightSelectedLine();\n }\n // eslint-disable-next-line class-methods-use-this\n handleParallelLineDown(e) {\n const line = $(e.currentTarget);\n const table = line.closest('table');\n\n table.removeClass('left-side-selected right-side-selected');\n\n const lineClass = ['left-side', 'right-side'].filter((name) => line.hasClass(name))[0];\n if (lineClass) {\n table.addClass(`${lineClass}-selected`);\n }\n }\n // eslint-disable-next-line class-methods-use-this\n diffViewType() {\n return $('.inline-parallel-buttons a.active').data('viewType');\n }\n viewTypeSwitch(event) {\n const click = event.originalEvent;\n const diffSource = new URL(event.currentTarget.getAttribute('href'), document.location.href);\n\n if (this.mrHub) {\n click.preventDefault();\n click.stopPropagation();\n\n diffSource.pathname = `${diffSource.pathname}.json`;\n\n this.mrHub.$emit('diff:switch-view-type', { source: diffSource.toString() });\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n lineNumbers(line) {\n const children = line.find('.diff-line-num').toArray();\n if (children.length !== 2) {\n return [0, 0];\n }\n return children.map((elm) => parseInt($(elm).data('linenumber'), 10) || 0);\n }\n // eslint-disable-next-line class-methods-use-this\n highlightSelectedLine() {\n const hash = getLocationHash();\n const $diffFiles = $('.diff-file');\n $diffFiles.find('.hll').removeClass('hll');\n\n if (hash) {\n $diffFiles\n .find(`tr#${hash}:not(.match) td, td#${hash}, td[data-line-code=\"${hash}\"]`)\n .addClass('hll');\n }\n }\n\n prepareRenderedDiff() {\n const allElements = this.elementsForRenderedDiff();\n const diff = this;\n\n for (const [fileHash, fileElements] of Object.entries(allElements)) {\n // eslint-disable no-param-reassign\n fileElements.rawButton.onclick = () => {\n diff.showRawViewer(fileHash, diff.elementsForRenderedDiff()[fileHash]);\n };\n\n fileElements.renderedButton.onclick = () => {\n diff.showRenderedViewer(fileHash, diff.elementsForRenderedDiff()[fileHash]);\n };\n // eslint-enable no-param-reassign\n\n diff.showRenderedViewer(fileHash, fileElements);\n }\n }\n\n // eslint-disable-next-line class-methods-use-this\n formatElementToObject = (element) => {\n const key = element.attributes['data-file-hash'].value;\n const name = element.attributes['data-diff-toggle-entity'].value;\n\n return { [key]: { [name]: element } };\n };\n\n elementsForRenderedDiff = () => {\n const $elements = $('[data-diff-toggle-entity]');\n\n if ($elements.length === 0) return {};\n\n const diff = this;\n\n return $elements.toArray().map(diff.formatElementToObject).reduce(merge);\n };\n\n // eslint-disable-next-line class-methods-use-this\n showRawViewer = (fileHash, elements) => {\n if (elements === undefined) return;\n\n elements.rawButton.classList.add('selected');\n elements.renderedButton.classList.remove('selected');\n\n elements.renderedViewer.classList.add('hidden');\n elements.rawViewer.classList.remove('hidden');\n };\n\n // eslint-disable-next-line class-methods-use-this\n showRenderedViewer = (fileHash, elements) => {\n if (elements === undefined) return;\n\n elements.rawButton.classList.remove('selected');\n elements.rawViewer.classList.add('hidden');\n\n elements.renderedButton.classList.add('selected');\n elements.renderedViewer.classList.remove('hidden');\n };\n}\n","exports = module.exports = require(\"../../../../../node_modules/css-loader/dist/runtime/api.js\")(false);\n// Module\nexports.push([module.id, \"\\n/* TODO: Use max-height prop when gitlab-ui got updated.\\nSee https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2374 */\\n[data-v-5fa5a073] .gl-new-dropdown-inner {\\n max-height: 310px;\\n}\\n\", \"\"]);\n\n"],"sourceRoot":""}