{"version":3,"sources":["webpack:///./awards_handler.js","webpack:///./abuse_reports/components/constants.js","webpack:////build/source/node_modules/lodash/_arrayIncludesWith.js","webpack:////build/source/node_modules/lodash/_createSet.js","webpack:///./notes/i18n.js","webpack:///./abuse_reports/components/abuse_category_selector.vue","webpack:///./abuse_reports/components/abuse_category_selector.vue?5b67","webpack:///abuse_reports/components/abuse_category_selector.vue","webpack:///./abuse_reports/components/abuse_category_selector.vue?54dd","webpack:///./notes/components/comment_type_dropdown.vue","webpack:///./notes/components/comment_type_dropdown.vue?30de","webpack:///notes/components/comment_type_dropdown.vue","webpack:///./notes/components/comment_type_dropdown.vue?fa53","webpack:////build/source/node_modules/lodash/uniq.js","webpack:////build/source/node_modules/lodash/_baseUniq.js","webpack:///./deprecated_notes.js","webpack:///./init_deprecated_notes.js","webpack:///./autosave.js","webpack:///./projects/report_abuse/components/report_abuse_dropdown_item.vue?fd8f","webpack:///projects/report_abuse/components/report_abuse_dropdown_item.vue","webpack:///./projects/report_abuse/components/report_abuse_dropdown_item.vue?83c5","webpack:///./projects/report_abuse/components/report_abuse_dropdown_item.vue","webpack:///./projects/report_abuse/index.js"],"names":["transitionEndEventString","FROM_SENTENCE_REGEX","categoryLabelMap","activity","people","nature","food","travel","objects","symbols","flags","AwardsHandler","constructor","emoji","this","eventListeners","toggleButtonSelector","menuClass","bindEvents","_this","$parentEl","targetContainerEl","$","document","registerEventListener","length","requestAnimationFrame","createEmojiMenu","e","stopPropagation","preventDefault","showEmojiMenu","currentTarget","target","closest","removeClass","is","hideMenuElement","emojiButtonSelector","$target","$glEmojiElement","find","$spriteIconElement","emojiName","data","addClass","addAward","getVotesBlock","getAwardUrl","method","element","args","call","push","$addBtn","_this2","hasClass","$menu","blur","positionMenu","showMenuElement","focus","$createdMenu","setTimeout","callback","isCreatingEmojiMenu","categoryMap","getEmojiCategoryMap","categoryNameKey","Object","keys","emojisInCategory","firstCategory","renderCategory","frequentlyUsedEmojis","getFrequentlyUsedEmojis","frequentlyUsedCatgegory","frequentEmojis","emojiMenuMarkup","body","insertAdjacentHTML","addRemainingEmojiMenuCategories","setupSearch","_this3","isAddingRemainingEmojiMenuCategories","menu","querySelector","emojiContentElement","slice","reduce","promiseChain","then","Promise","resolve","categoryMarkup","dispatchEvent","CustomEvent","catch","err","Error","message","name","emojiList","opts","_this4","_escape","map","glEmojiTag","sprite","join","css","top","outerHeight","position","offset","bp","getBreakpointSize","left","outerWidth","votesBlock","awardUrl","_this5","isMainAwardsBlock","isInVueNoteablePage","id","attr","replace","toggleAwardEvent","detail","awardName","noteId","normalizedEmoji","normalizeEmojiName","$emojiButton","findEmojiIcon","postEmoji","addAwardToEmojiBar","undefined","addEmojiToFrequentlyUsedList","isActive","decrementCounter","counter","text","parseInt","addYouToUserList","animateEmoji","createEmoji","$el","currentBlock","resultantVotesBlock","eq","counterNumber","removeYouFromUserList","EMOJI_THUMBS_UP","EMOJI_THUMBS_DOWN","dispose","parents","removeEmoji","remove","$votesBlock","getAwardTooltip","$awardBlock","toSentence","list","sentence","awardBlock","authors","split","splice","indexOf","removeData","removeAttr","fixTitle","origTitle","users","trim","unshift","createAwardButtonForVotesBlock","buttonHtml","insertBefore","$emoji","_this6","axios","post","ok","createAlert","__","scrollToAwards","scrollToElement","isEmojiNameValid","_uniq","concat","localStorage","setItem","FREQUENTLY_USED_EMOJIS_STORAGE_KEY","_this7","getItem","filter","inputName","_this8","$search","term","val","searchEmojis","h5","foundEmojis","findMatchingEmojiElements","show","ul","append","hide","children","getEmojiScore","emojis","value","elem","get","x","dataset","score","sortEmojiElements","$elements","_this9","scores","WeakMap","sort","a","b","aScore","bScore","set","query","matchingEmoji","searchEmoji","getEmojiScoreWithIntent","matchingEmojiNames","$matchingElements","i","elm","clone","$emojiMenu","on","off","destroy","forEach","entry","awardsHandlerPromise","loadAwardsHandler","reload","Emoji","awardsHandler","CATEGORY_OPTIONS","s__","module","exports","array","comparator","index","Set","noop","setToArray","createSet","values","COMMENT_FORM","GENERIC_UNSUBMITTABLE_NETWORK","error","note","comment","wiki","internalComment","issue","startThread","startInternalThread","mergeRequest","epic","bodyPlaceholder","bodyPlaceholderInternal","internal","internalVisibility","discussionThatNeedsResolution","internalDiscussionThatNeedsResolution","discussion","internalDiscussion","actionButtonWithNote","actionButton","withNote","reopen","close","withoutNote","submitButton","commentHelp","internalCommentHelp","addToReviewButton","saveThread","saveComment","addToReview","startReview","addCommentNow","addThreadNow","EDITED_TEXT","actionWithAuthor","actionWithoutAuthor","UPDATE_COMMENT_FORM","defaultError","csrf","components","GlButton","GlDrawer","GlForm","GlFormGroup","GlFormRadioGroup","inject","reportAbusePath","default","props","reportedUserId","type","Number","required","reportedFromUrl","String","showDrawer","Boolean","i18n","title","label","next","selected","mounted","computed","getDrawerHeaderHeight","getContentWrapperHeight","methods","closeDrawer","$emit","component","_vm","_c","_self","attrs","scopedSlots","_u","key","fn","staticClass","_v","_s","$options","proxy","domProps","token","model","$$v","expression","toggleSrText","GlButtonGroup","GlCollapsibleListbox","prop","event","disabled","trackingLabel","discussionsRequireResolution","isInternalNote","noteableDisplayName","noteType","isReviewDropdown","isNoteTypeComment","constants","isNoteTypeDiscussion","dropdownCommentButtonTitle","dropdownStartThreadButtonTitle","commentButtonTitle","startDiscussionDescription","commentDescription","sprintf","dropdownItems","description","testid","handleClick","setNoteType","item","baseUniq","SetCache","arrayIncludes","arrayIncludesWith","cacheHas","iteratee","includes","isCommon","result","seen","outer","seenIndex","normalizeNewlines","str","window","autosize","Autosize","REGEX_QUICK_ACTIONS","Notes","notes_url","last_fetched_at","view","enableGFM","instance","defaultAutocompleteConfig","updateTargetButtons","bind","updateComment","visibilityChange","cancelDiscussionForm","onAddDiffNote","onAddImageDiffNote","setupDiscussionNoteForm","onReplyToDiscussionNote","removeNote","cancelEdit","updateNote","addDiscussionNote","addNoteError","addNote","resetMainTargetForm","refresh","keydownNoteText","toggleCommitList","postComment","clearAlertWrapper","clearAlert","onHashChange","note_ids","updatedNotesTrackingMap","noteable_url","URL","notesCountBadge","basePollingInterval","maxPollingSteps","$wrapperEl","isInMRPage","cleanBinding","addBinding","setPollingInterval","setupMainTargetNoteForm","taskList","TaskList","dataType","fieldName","selector","setViewType","getPagePath","insertAfter","hash","getLocationHash","$anchor","getElementById","loadLazyDiff","getCookie","showEditForm","removeAttachment","updateFormAttachment","onClickRetryLazyLoad","reenableTargetFormSubmitButton","form","el","noteableName","noteTypeInput","formHasContent","commentTypeComponent","Vue","render","createElement","CommentTypeDropdown","change","arg","discussionNoteForm","editNote","myLastNote","myLastNoteEditBtn","newText","originalText","isModifierKey","$textarea","which","gon","current_user_id","trigger","confirmAction","primaryBtnVariant","primaryBtnText","removeDiscussionNoteForm","removeNoteEditForm","initRefresh","interval","clearInterval","setInterval","pollingInterval","hidden","getContent","refreshing","headers","notes","each","renderNote","shouldReset","nthInterval","handleQuickActions","noteEntity","commands_changes","checkMergeRequestStatus","emoji_award","setupNewNote","$note","localTimeAgo","init","updateNoteTargetSelector","$noteToCleanHighlight","addTargetClass","toggleClass","$form","$notesList","discussion_html","renderDiscussionNote","_noteEntity$quick_act","valid","quick_actions_status","messages","addAlert","variant","VARIANT_INFO","parent","parentTimeline","isNewNote","$newNote","animateAppendNote","html","updateNotesCount","isUpdatedNote","isEditing","initialContent","currentContent","sanitizedNoteNote","isTextareaUntouched","putConflictEditWarningInPlace","$updatedNote","animateUpdateNote","isParallelView","discussionContainer","row","discussion_id","discussion_line_code","on_image","diff_discussion_html","internalNote","discussionElement","sanitize","RETURN_DOM","insertAdjacentElement","firstElementChild","renderGFM","$discussion","unwrap","classList","add","after","$notes","contentContainerClass","querySelectorAll","getLineHolder","changesDiscussionContainer","prevAll","first","click","$autosave","reset","createEvent","initEvent","formClone","setupNoteForm","initCommentTypeToggle","glForm","GLForm","textarea","textareaEl","Autosave","_error$response","formParentTimeline","serverErrorMessage","response","errors","alertMessage","reason","toLowerCase","updateNoteError","$editingNote","_error$response2","isNewDiffComment","discussionId","mergeRequestId","ResolveService","toggleResolveForDiscussion","$targetNote","$noteEntityEl","$noteAvatar","$targetNoteBadge","revertNoteEditForm","getNodeToRender","replaceWith","checkContentToAllowEditing","isAllowed","isInViewport","$editForm","getEditFormSelector","$currentlyEditing","putEditFormInPlace","enable","one","noteElId","notesTr","$diffFile","removeBadgeEvent","badgeNumber","replyToDiscussionNote","cleanForm","replyLink","dataHolder","diffFileData","discussionID","link","$link","showReplyInput","toggleDiffNote","lineType","currentUsername","current_username","currentUserAvatar","current_user_avatar_url","currentUserFullname","current_user_fullname","clickEvent","newForm","$noteContainer","appendTo","forceShow","addForm","noteForm","replyButton","rowCssToAdd","nextRow","targetRow","hasNotes","lineTypeSelector","notesContentSelector","notesContent","isCurrentlyShown","isForced","showNow","prev","blurEvent","filename","_form$get","closetext","reopentext","reopenbtn","closebtn","savebtn","disable","$originalContentEl","originalContent","postUrl","targetId","targetType","open_link","close_link","updateCount","$container","GlSkeletonLoader","lines","prepend","fileHolder","syntaxHighlight","$retryButton","renderPlaceholderComponent","url","$errorContainer","$successContainer","renderDiffContent","$element","$closestSystemCommitList","siblings","$svgChevronUpElement","$svgChevronDownElement","alertParams","alert","_this$alert","dismiss","getNotesIds","isNewEntry","inArray","noteItem","gl","mrWidget","checkStatus","noteHtml","last","$item","isNodeTypeElement","getFormData","content","formData","serialize","formContent","formAction","formContentOriginal","hasQuickActions","test","stripQuickActions","getQuickActionDescription","availableQuickActions","tempFormContent","executedCommands","command","RegExp","commandDescription","createPlaceholderNote","uniqueId","isDiscussionNote","discussionClass","$tempNote","createPlaceholderSystemNote","_$form$get","$submitBtn","$closeBtn","isMainForm","isDiscussionForm","isDiscussionResolve","noteUniqueId","systemNoteUniqueId","$notesContainer","supportsQuickActions","_uniqueId","AjaxCache","GfmAutoComplete","dataSources","commands","res","notePosition","y","width","height","JSON","parse","addBadgeEvent","closestDiffFile","$noteBodyText","cachedNoteBodyText","$timeAgo","empty","loadingIconForLegacyJS","inline","size","$node","nodeType","Node","ELEMENT_NODE","dataEl","notesUrl","now","diffView","innerHTML","initialize","field","fallbackKey","lockVersion","getAttribute","isLocalStorageAvailable","AccessorUtilities","canUseLocalStorage","Array","isArray","lockVersionKey","restore","saveAction","save","addEventListener","fallbackText","newValue","originalValue","checked","parseBoolean","triggerInputEvents","inputEvent","Event","bubbles","cancelable","changeEvent","getSavedLockVersion","removeItem","removeEventListener","GlDropdownItem","MountingPortal","AbuseCategorySelector","reportAbuse","open","toggleDrawer","$event","initReportAbuse","provide","ReportAbuseDropdownItem"],"mappings":"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","file":"commons-pages.projects.commit.show-pages.projects.snippets.show-pages.snippets.show.6c74c802.chunk.js","sourcesContent":["/* eslint-disable class-methods-use-this, @gitlab/require-i18n-strings */\n\nimport { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';\nimport $ from 'jquery';\nimport { uniq, escape } from 'lodash';\nimport { getEmojiScoreWithIntent } from '~/emoji/utils';\nimport { scrollToElement } from '~/lib/utils/common_utils';\nimport * as Emoji from '~/emoji';\nimport { dispose, fixTitle } from '~/tooltips';\nimport { createAlert } from '~/alert';\nimport {\n EMOJI_THUMBS_UP,\n EMOJI_THUMBS_DOWN,\n FREQUENTLY_USED_EMOJIS_STORAGE_KEY,\n} from '~/emoji/constants';\nimport axios from './lib/utils/axios_utils';\nimport { isInVueNoteablePage } from './lib/utils/dom_utils';\nimport { __ } from './locale';\n\nconst animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';\nconst transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';\n\nconst FROM_SENTENCE_REGEX = /(?:, and | and |, )/; // For separating lists produced by ruby's Array#toSentence\n\nconst categoryLabelMap = {\n activity: 'Activity',\n people: 'People',\n nature: 'Nature',\n food: 'Food',\n travel: 'Travel',\n objects: 'Objects',\n symbols: 'Symbols',\n flags: 'Flags',\n};\n\nconst IS_VISIBLE = 'is-visible';\nconst IS_RENDERED = 'is-rendered';\n\nexport class AwardsHandler {\n constructor(emoji) {\n this.emoji = emoji;\n this.eventListeners = [];\n this.toggleButtonSelector = '.js-add-award';\n this.menuClass = 'js-award-emoji-menu';\n }\n\n bindEvents() {\n const $parentEl = this.targetContainerEl ? $(this.targetContainerEl) : $(document);\n // If the user shows intent let's pre-build the menu\n this.registerEventListener(\n 'one',\n $parentEl,\n 'mouseenter focus',\n this.toggleButtonSelector,\n 'mouseenter focus',\n () => {\n const $menu = $(`.${this.menuClass}`);\n if ($menu.length === 0) {\n requestAnimationFrame(() => {\n this.createEmojiMenu();\n });\n }\n },\n );\n this.registerEventListener('on', $parentEl, 'click', this.toggleButtonSelector, (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.showEmojiMenu($(e.currentTarget));\n });\n\n this.registerEventListener('on', $('html'), 'click', (e) => {\n const $target = $(e.target);\n if (!$target.closest(`.${this.menuClass}`).length) {\n $('.js-awards-block.current').removeClass('current');\n if ($(`.${this.menuClass}`).is(':visible')) {\n $(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');\n this.hideMenuElement($(`.${this.menuClass}`));\n }\n }\n });\n\n const emojiButtonSelector = `.js-awards-block .js-emoji-btn, .${this.menuClass} .js-emoji-btn`;\n this.registerEventListener('on', $parentEl, 'click', emojiButtonSelector, (e) => {\n e.preventDefault();\n const $target = $(e.currentTarget);\n const $glEmojiElement = $target.find('gl-emoji');\n const $spriteIconElement = $target.find('.icon');\n const emojiName = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data(\n 'name',\n );\n\n $target.closest('.js-awards-block').addClass('current');\n this.addAward(this.getVotesBlock(), this.getAwardUrl(), emojiName);\n });\n }\n\n registerEventListener(method = 'on', element, ...args) {\n element[method].call(element, ...args);\n this.eventListeners.push({\n element,\n args,\n });\n }\n\n showEmojiMenu($addBtn) {\n if ($addBtn.hasClass('js-note-emoji')) {\n $addBtn.closest('.note').find('.js-awards-block').addClass('current');\n } else {\n $addBtn.closest('.js-awards-block').addClass('current');\n }\n\n const $menu = $(`.${this.menuClass}`);\n if ($menu.length) {\n if ($menu.is('.is-visible')) {\n $addBtn.removeClass('is-active');\n this.hideMenuElement($menu);\n $('.js-emoji-menu-search').blur();\n } else {\n $addBtn.addClass('is-active');\n this.positionMenu($menu, $addBtn);\n this.showMenuElement($menu);\n $('.js-emoji-menu-search').focus();\n }\n } else {\n $addBtn.addClass('is-loading is-active');\n this.createEmojiMenu(() => {\n const $createdMenu = $(`.${this.menuClass}`);\n $addBtn.removeClass('is-loading');\n this.positionMenu($createdMenu, $addBtn);\n return setTimeout(() => {\n this.showMenuElement($createdMenu);\n $('.js-emoji-menu-search').focus();\n }, 200);\n });\n }\n }\n\n // Create the emoji menu with the first category of emojis.\n // Then render the remaining categories of emojis one by one to avoid jank.\n createEmojiMenu(callback) {\n if (this.isCreatingEmojiMenu) {\n return;\n }\n this.isCreatingEmojiMenu = true;\n\n // Render the first category\n const categoryMap = this.emoji.getEmojiCategoryMap();\n const categoryNameKey = Object.keys(categoryMap)[0];\n const emojisInCategory = categoryMap[categoryNameKey];\n const firstCategory = this.renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory);\n\n // Render the frequently used\n const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();\n let frequentlyUsedCatgegory = '';\n if (frequentlyUsedEmojis.length > 0) {\n frequentlyUsedCatgegory = this.renderCategory('Frequently used', frequentlyUsedEmojis, {\n frequentEmojis: true,\n });\n }\n\n const emojiMenuMarkup = `\n <div class=\"emoji-menu ${this.menuClass}\">\n <input type=\"text\" name=\"emoji-menu-search\" value=\"\" class=\"js-emoji-menu-search emoji-search search-input form-control\" placeholder=\"Search emoji\" />\n\n <div class=\"emoji-menu-content\">\n ${frequentlyUsedCatgegory}\n ${firstCategory}\n </div>\n </div>\n `;\n\n const targetEl = this.targetContainerEl ? this.targetContainerEl : document.body;\n // eslint-disable-next-line no-unsanitized/method\n targetEl.insertAdjacentHTML('beforeend', emojiMenuMarkup);\n\n this.addRemainingEmojiMenuCategories();\n this.setupSearch();\n if (callback) {\n callback();\n }\n }\n\n addRemainingEmojiMenuCategories() {\n if (this.isAddingRemainingEmojiMenuCategories) {\n return;\n }\n this.isAddingRemainingEmojiMenuCategories = true;\n\n const categoryMap = this.emoji.getEmojiCategoryMap();\n\n // Avoid the jank and render the remaining categories separately\n // This will take more time, but makes UI more responsive\n const menu = document.querySelector(`.${this.menuClass}`);\n const emojiContentElement = menu.querySelector('.emoji-menu-content');\n const remainingCategories = Object.keys(categoryMap).slice(1);\n const allCategoriesAddedPromise = remainingCategories.reduce(\n (promiseChain, categoryNameKey) =>\n promiseChain.then(\n () =>\n new Promise((resolve) => {\n const emojisInCategory = categoryMap[categoryNameKey];\n const categoryMarkup = this.renderCategory(\n categoryLabelMap[categoryNameKey],\n emojisInCategory,\n );\n requestAnimationFrame(() => {\n // eslint-disable-next-line no-unsanitized/method\n emojiContentElement.insertAdjacentHTML('beforeend', categoryMarkup);\n resolve();\n });\n }),\n ),\n Promise.resolve(),\n );\n\n allCategoriesAddedPromise\n .then(() => {\n // Used for tests\n // We check for the menu in case it was destroyed in the meantime\n if (menu) {\n menu.dispatchEvent(new CustomEvent('build-emoji-menu-finish'));\n }\n })\n .catch((err) => {\n emojiContentElement.insertAdjacentHTML(\n 'beforeend',\n '<p>We encountered an error while adding the remaining categories</p>',\n );\n throw new Error(`Error occurred in addRemainingEmojiMenuCategories: ${err.message}`);\n });\n }\n\n renderCategory(name, emojiList, opts = {}) {\n return `\n <h5 class=\"emoji-menu-title\">\n ${escape(name)}\n </h5>\n <ul class=\"clearfix emoji-menu-list ${opts.frequentEmojis ? 'frequent-emojis' : ''}\">\n ${emojiList\n .map(\n (emojiName) => `\n <li class=\"emoji-menu-list-item\">\n <button class=\"emoji-menu-btn text-center js-emoji-btn\" type=\"button\">\n ${this.emoji.glEmojiTag(emojiName, {\n sprite: true,\n })}\n </button>\n </li>\n `,\n )\n .join('\\n')}\n </ul>\n `;\n }\n\n positionMenu($menu, $addBtn) {\n if (this.targetContainerEl) {\n return $menu.css({\n top: `${$addBtn.outerHeight()}px`,\n });\n }\n\n const position = $addBtn.data('position');\n // The menu could potentially be off-screen or in a hidden overflow element\n // So we position the element absolute in the body\n const css = {\n top: `${$addBtn.offset().top + $addBtn.outerHeight()}px`,\n };\n // for xs screen we position the element on center\n if (bp.getBreakpointSize() === 'xs' || bp.getBreakpointSize() === 'sm') {\n css.left = '5%';\n } else if (position === 'right') {\n css.left = `${$addBtn.offset().left - $menu.outerWidth() + 20}px`;\n $menu.addClass('is-aligned-right');\n } else {\n css.left = `${$addBtn.offset().left}px`;\n $menu.removeClass('is-aligned-right');\n }\n return $menu.css(css);\n }\n\n // eslint-disable-next-line max-params\n addAward(votesBlock, awardUrl, emoji, callback) {\n const isMainAwardsBlock = votesBlock.closest('.js-noteable-awards').length;\n\n if (isInVueNoteablePage() && !isMainAwardsBlock) {\n const id = votesBlock.attr('id').replace('note_', '');\n\n this.hideMenuElement($(`.${this.menuClass}`));\n\n $(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');\n const toggleAwardEvent = new CustomEvent('toggleAward', {\n detail: {\n awardName: emoji,\n noteId: id,\n },\n });\n\n document.querySelector('.js-vue-notes-event').dispatchEvent(toggleAwardEvent);\n }\n\n const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);\n const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).closest('button');\n\n this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {\n this.addAwardToEmojiBar(votesBlock, normalizedEmoji);\n return typeof callback === 'function' ? callback() : undefined;\n });\n\n this.hideMenuElement($(`.${this.menuClass}`));\n\n return $(`${this.toggleButtonSelector}.is-active`).removeClass('is-active');\n }\n\n addAwardToEmojiBar(votesBlock, emoji) {\n this.addEmojiToFrequentlyUsedList(emoji);\n const normalizedEmoji = this.emoji.normalizeEmojiName(emoji);\n const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).closest('button');\n if ($emojiButton.length > 0) {\n if (this.isActive($emojiButton)) {\n this.decrementCounter($emojiButton, normalizedEmoji);\n } else {\n const counter = $emojiButton.find('.js-counter');\n counter.text(parseInt(counter.text(), 10) + 1);\n $emojiButton.addClass('active');\n this.addYouToUserList(votesBlock, normalizedEmoji);\n this.animateEmoji($emojiButton);\n }\n } else {\n votesBlock.removeClass('hidden');\n this.createEmoji(votesBlock, normalizedEmoji);\n }\n }\n\n getVotesBlock() {\n if (isInVueNoteablePage()) {\n const $el = $(`${this.toggleButtonSelector}.is-active`).closest('.note.timeline-entry');\n\n if ($el.length) {\n return $el;\n }\n }\n\n const currentBlock = $('.js-awards-block.current');\n let resultantVotesBlock = currentBlock;\n if (currentBlock.length === 0) {\n resultantVotesBlock = $('.js-awards-block').eq(0);\n }\n\n return resultantVotesBlock;\n }\n\n getAwardUrl() {\n return this.getVotesBlock().data('awardUrl');\n }\n\n isActive($emojiButton) {\n return $emojiButton.hasClass('active');\n }\n\n decrementCounter($emojiButton, emoji) {\n const counter = $('.js-counter', $emojiButton);\n const counterNumber = parseInt(counter.text(), 10);\n if (counterNumber > 1) {\n counter.text(counterNumber - 1);\n this.removeYouFromUserList($emojiButton);\n } else if (emoji === EMOJI_THUMBS_UP || emoji === EMOJI_THUMBS_DOWN) {\n dispose($emojiButton);\n counter.text('0');\n this.removeYouFromUserList($emojiButton);\n if ($emojiButton.parents('.note').length) {\n this.removeEmoji($emojiButton);\n }\n } else {\n this.removeEmoji($emojiButton);\n }\n return $emojiButton.removeClass('active');\n }\n\n removeEmoji($emojiButton) {\n dispose($emojiButton);\n\n $emojiButton.remove();\n const $votesBlock = this.getVotesBlock();\n if ($votesBlock.find('.js-emoji-btn').length === 0) {\n $votesBlock.addClass('hidden');\n }\n }\n\n getAwardTooltip($awardBlock) {\n return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';\n }\n\n toSentence(list) {\n let sentence;\n if (list.length <= 2) {\n sentence = list.join(' and ');\n } else {\n sentence = `${list.slice(0, -1).join(', ')}, and ${list[list.length - 1]}`;\n }\n\n return sentence;\n }\n\n removeYouFromUserList($emojiButton) {\n const awardBlock = $emojiButton;\n const originalTitle = this.getAwardTooltip(awardBlock);\n const authors = originalTitle.split(FROM_SENTENCE_REGEX);\n authors.splice(authors.indexOf('You'), 1);\n\n awardBlock\n .closest('.js-emoji-btn')\n .removeData('title')\n .removeAttr('data-title')\n .removeAttr('data-original-title')\n .attr('title', this.toSentence(authors));\n\n fixTitle(awardBlock);\n\n return awardBlock;\n }\n\n addYouToUserList(votesBlock, emoji) {\n const awardBlock = this.findEmojiIcon(votesBlock, emoji).closest('button');\n const origTitle = this.getAwardTooltip(awardBlock);\n let users = [];\n if (origTitle) {\n users = origTitle.trim().split(FROM_SENTENCE_REGEX);\n }\n users.unshift('You');\n\n awardBlock.attr('title', this.toSentence(users));\n\n fixTitle(awardBlock);\n\n return awardBlock;\n }\n\n createAwardButtonForVotesBlock(votesBlock, emojiName) {\n const buttonHtml = `\n <button class=\"gl-button btn btn-default award-control js-emoji-btn has-tooltip active\" title=\"You\">\n ${this.emoji.glEmojiTag(emojiName)}\n <span class=\"award-control-text js-counter\">1</span>\n </button>\n `;\n const $emojiButton = $(buttonHtml);\n $emojiButton\n .insertBefore(votesBlock.find('.js-award-holder'))\n .find('.emoji-icon')\n .data('name', emojiName);\n this.animateEmoji($emojiButton);\n\n votesBlock.removeClass('current');\n }\n\n animateEmoji($emoji) {\n const className = 'pulse animated once short';\n $emoji.addClass(className);\n\n this.registerEventListener('on', $emoji, animationEndEventString, (e) => {\n $(e.currentTarget).removeClass(className);\n });\n }\n\n createEmoji(votesBlock, emoji) {\n if ($(`.${this.menuClass}`).length) {\n this.createAwardButtonForVotesBlock(votesBlock, emoji);\n }\n this.createEmojiMenu(() => {\n this.createAwardButtonForVotesBlock(votesBlock, emoji);\n });\n }\n\n // eslint-disable-next-line max-params\n postEmoji($emojiButton, awardUrl, emoji, callback) {\n axios\n .post(awardUrl, {\n name: emoji,\n })\n .then(({ data }) => {\n if (data.ok) {\n callback();\n }\n })\n .catch(() =>\n createAlert({\n message: __('Something went wrong on our end.'),\n }),\n );\n }\n\n findEmojiIcon(votesBlock, emoji) {\n return votesBlock.find(`.js-emoji-btn [data-name=\"${emoji}\"]`);\n }\n\n scrollToAwards() {\n scrollToElement('.awards', { offset: -110 });\n }\n\n addEmojiToFrequentlyUsedList(emoji) {\n if (this.emoji.isEmojiNameValid(emoji)) {\n this.frequentlyUsedEmojis = uniq(this.getFrequentlyUsedEmojis().concat(emoji));\n localStorage.setItem(FREQUENTLY_USED_EMOJIS_STORAGE_KEY, this.frequentlyUsedEmojis.join(','));\n }\n }\n\n getFrequentlyUsedEmojis() {\n return (\n this.frequentlyUsedEmojis ||\n (() => {\n const frequentlyUsedEmojis = uniq(\n (localStorage.getItem(FREQUENTLY_USED_EMOJIS_STORAGE_KEY) || '').split(','),\n );\n this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter((inputName) =>\n this.emoji.isEmojiNameValid(inputName),\n );\n\n return this.frequentlyUsedEmojis;\n })()\n );\n }\n\n setupSearch() {\n const $search = $('.js-emoji-menu-search');\n\n this.registerEventListener('on', $search, 'input', (e) => {\n const term = $(e.target).val().trim();\n this.searchEmojis(term);\n });\n\n const $menu = $(`.${this.menuClass}`);\n this.registerEventListener('on', $menu, transitionEndEventString, (e) => {\n if (e.target === e.currentTarget) {\n // Clear the search\n this.searchEmojis('');\n }\n });\n }\n\n searchEmojis(term) {\n const $search = $('.js-emoji-menu-search');\n $search.val(term);\n\n // Clean previous search results\n $('ul.emoji-menu-search, h5.emoji-search-title').remove();\n if (term.length > 0) {\n // Generate a search result block\n const h5 = $('<h5 class=\"emoji-search-title\"/>').text('Search results');\n const foundEmojis = this.findMatchingEmojiElements(term).show();\n const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);\n $('.emoji-menu-content ul, .emoji-menu-content h5').hide();\n $('.emoji-menu-content').append(h5).append(ul);\n } else {\n $('.emoji-menu-content').children().show();\n }\n }\n\n getEmojiScore(emojis, value) {\n const elem = $(value).find('[data-name]').get(0);\n const emoji = emojis.filter((x) => x.emoji.name === elem.dataset.name)[0];\n elem.dataset.score = emoji.score;\n\n return emoji.score;\n }\n\n sortEmojiElements(emojis, $elements) {\n const scores = new WeakMap();\n\n return $elements.sort((a, b) => {\n let aScore = scores.get(a);\n let bScore = scores.get(b);\n\n if (!aScore) {\n aScore = this.getEmojiScore(emojis, a);\n scores.set(a, aScore);\n }\n\n if (!bScore) {\n bScore = this.getEmojiScore(emojis, b);\n scores.set(b, bScore);\n }\n\n return aScore - bScore;\n });\n }\n\n findMatchingEmojiElements(query) {\n const matchingEmoji = this.emoji\n .searchEmoji(query)\n .map((x) => ({ ...x, score: getEmojiScoreWithIntent(x.emoji.name, x.score) }));\n const matchingEmojiNames = matchingEmoji.map((x) => x.emoji.name);\n const $emojiElements = $('.emoji-menu-list:not(.frequent-emojis) [data-name]');\n const $matchingElements = $emojiElements.filter(\n (i, elm) => matchingEmojiNames.indexOf(elm.dataset.name) >= 0,\n );\n return this.sortEmojiElements(matchingEmoji, $matchingElements.closest('li').clone());\n }\n\n /* showMenuElement and hideMenuElement are performance optimizations. We use\n * opacity to show/hide the emoji menu, because we can animate it. But opacity\n * leaves hidden elements in the render tree, which is unacceptable given the number\n * of emoji elements in the emoji menu (5k+). To get the best of both worlds, we separately\n * apply IS_RENDERED to add/remove the menu from the render tree and IS_VISIBLE to animate\n * the menu being opened and closed. */\n\n showMenuElement($emojiMenu) {\n $emojiMenu.addClass(IS_RENDERED);\n\n // enqueues animation as a microtask, so it begins ASAP once IS_RENDERED added\n return Promise.resolve().then(() => $emojiMenu.addClass(IS_VISIBLE));\n }\n\n hideMenuElement($emojiMenu) {\n $emojiMenu.on(transitionEndEventString, (e) => {\n if (e.currentTarget === e.target) {\n // eslint-disable-next-line @gitlab/no-global-event-off\n $emojiMenu.removeClass(IS_RENDERED).off(transitionEndEventString);\n }\n });\n\n $emojiMenu.removeClass(IS_VISIBLE);\n }\n\n destroy() {\n this.eventListeners.forEach((entry) => {\n entry.element.off.call(entry.element, ...entry.args);\n });\n $(`.${this.menuClass}`).remove();\n }\n}\n\nlet awardsHandlerPromise = null;\nexport default function loadAwardsHandler(reload = false) {\n if (!awardsHandlerPromise || reload) {\n awardsHandlerPromise = Emoji.initEmojiMap().then(() => {\n const awardsHandler = new AwardsHandler(Emoji);\n awardsHandler.bindEvents();\n return awardsHandler;\n });\n }\n return awardsHandlerPromise;\n}\n","import { s__ } from '~/locale';\n\nexport const CATEGORY_OPTIONS = [\n { value: 'spam', text: s__(\"ReportAbuse|They're posting spam.\") },\n { value: 'offensive', text: s__(\"ReportAbuse|They're being offensive or abusive.\") },\n { value: 'phishing', text: s__(\"ReportAbuse|They're phishing.\") },\n { value: 'crypto', text: s__(\"ReportAbuse|They're crypto mining.\") },\n {\n value: 'credentials',\n text: s__(\"ReportAbuse|They're posting personal information or credentials.\"),\n },\n { value: 'copyright', text: s__(\"ReportAbuse|They're violating a copyright or trademark.\") },\n { value: 'malware', text: s__(\"ReportAbuse|They're posting malware.\") },\n { value: 'other', text: s__('ReportAbuse|Something else.') },\n];\n","/**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n}\n\nmodule.exports = arrayIncludesWith;\n","var Set = require('./_Set'),\n noop = require('./noop'),\n setToArray = require('./_setToArray');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\nvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n};\n\nmodule.exports = createSet;\n","import { __, s__ } from '~/locale';\n\nexport const COMMENT_FORM = {\n GENERIC_UNSUBMITTABLE_NETWORK: __(\n 'Your comment could not be submitted! Please check your network connection and try again.',\n ),\n error: __('Comment could not be submitted: %{reason}.'),\n note: __('Note'),\n comment: __('Comment'),\n wiki: __('Wiki'),\n internalComment: __('Add internal note'),\n issue: __('issue'),\n startThread: __('Start thread'),\n startInternalThread: __('Start internal thread'),\n mergeRequest: __('merge request'),\n epic: __('epic'),\n bodyPlaceholder: __('Write a comment or drag your files here…'),\n bodyPlaceholderInternal: __('Write an internal note or drag your files here…'),\n internal: s__('Notes|Make this an internal note'),\n internalVisibility: s__(\n 'Notes|Internal notes are only visible to members with the role of Planner or higher',\n ),\n discussionThatNeedsResolution: __(\n 'Discuss a specific suggestion or question that needs to be resolved.',\n ),\n internalDiscussionThatNeedsResolution: __(\n 'Discuss a specific suggestion or question internally that needs to be resolved.',\n ),\n discussion: __('Discuss a specific suggestion or question.'),\n internalDiscussion: __('Discuss a specific suggestion or question internally.'),\n actionButtonWithNote: __('%{actionText} & %{openOrClose} %{noteable}'),\n actionButton: {\n withNote: {\n reopen: __('%{actionText} & reopen %{noteable}'),\n close: __('%{actionText} & close %{noteable}'),\n },\n withoutNote: {\n reopen: __('Reopen %{noteable}'),\n close: __('Close %{noteable}'),\n },\n },\n submitButton: {\n startThread: __('Start thread'),\n startInternalThread: __('Start internal thread'),\n comment: __('Comment'),\n internalComment: __('Add internal note'),\n commentHelp: __('Add a general comment to this %{noteableDisplayName}.'),\n internalCommentHelp: __('Add a confidential internal note to this %{noteableDisplayName}.'),\n },\n addToReviewButton: {\n saveThread: __('Add thread to review'),\n saveComment: __('Add comment to review'),\n },\n addToReview: __('Add to review'),\n startReview: __('Start review'),\n addCommentNow: __('Add comment now'),\n addThreadNow: __('Add thread now'),\n};\n\nexport const EDITED_TEXT = {\n actionWithAuthor: __('%{actionText} %{actionDetail} %{timeago} by %{author}'),\n actionWithoutAuthor: __('%{actionText} %{actionDetail}'),\n};\n\nexport const UPDATE_COMMENT_FORM = {\n error: __('Comment could not be updated: %{reason}.'),\n defaultError: __('Something went wrong while editing your comment. Please try again.'),\n};\n","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('gl-drawer',{attrs:{\"header-height\":_vm.getDrawerHeaderHeight,\"z-index\":300,\"open\":_vm.showDrawer && _vm.mounted},on:{\"close\":_vm.closeDrawer},scopedSlots:_vm._u([{key:\"title\",fn:function(){return [_c('h2',{staticClass:\"gl-mb-0 gl-mt-0 gl-text-size-h2 gl-leading-24\",attrs:{\"data-testid\":\"category-drawer-title\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$options.i18n.title)+\"\\n \")])]},proxy:true},{key:\"default\",fn:function(){return [_c('gl-form',{staticClass:\"gl-text-left\",attrs:{\"action\":_vm.reportAbusePath,\"method\":\"post\"}},[_c('input',{attrs:{\"type\":\"hidden\",\"name\":\"authenticity_token\"},domProps:{\"value\":_vm.$options.csrf.token}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"name\":\"user_id\",\"data-testid\":\"input-user-id\"},domProps:{\"value\":_vm.reportedUserId}}),_vm._v(\" \"),_c('input',{attrs:{\"type\":\"hidden\",\"name\":\"abuse_report[reported_from_url]\",\"data-testid\":\"input-referer\"},domProps:{\"value\":_vm.reportedFromUrl}}),_vm._v(\" \"),_c('gl-form-group',{attrs:{\"label\":_vm.$options.i18n.label,\"label-class\":\"gl-text-default\"}},[_c('gl-form-radio-group',{attrs:{\"options\":_vm.$options.CATEGORY_OPTIONS,\"name\":\"abuse_report[category]\",\"required\":\"\"},model:{value:(_vm.selected),callback:function ($$v) {_vm.selected=$$v},expression:\"selected\"}})],1),_vm._v(\" \"),_c('gl-button',{attrs:{\"type\":\"submit\",\"variant\":\"confirm\",\"data-testid\":\"submit-form-button\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$options.i18n.next)+\"\\n \")])],1)]},proxy:true}])})\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","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!./abuse_category_selector.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!./abuse_category_selector.vue?vue&type=script&lang=js\"","<script>\nimport { GlButton, GlDrawer, GlForm, GlFormGroup, GlFormRadioGroup } from '@gitlab/ui';\nimport { getContentWrapperHeight } from '~/lib/utils/dom_utils';\nimport { s__, __ } from '~/locale';\nimport csrf from '~/lib/utils/csrf';\nimport { CATEGORY_OPTIONS } from '~/abuse_reports/components/constants';\n\nexport default {\n name: 'AbuseCategorySelector',\n csrf,\n components: {\n GlButton,\n GlDrawer,\n GlForm,\n GlFormGroup,\n GlFormRadioGroup,\n },\n inject: {\n reportAbusePath: {\n default: '',\n },\n },\n props: {\n reportedUserId: {\n type: Number,\n required: true,\n },\n reportedFromUrl: {\n type: String,\n required: false,\n default: '',\n },\n showDrawer: {\n type: Boolean,\n required: true,\n },\n },\n i18n: {\n title: __('Report abuse to administrator'),\n close: __('Close'),\n label: s__('ReportAbuse|Why are you reporting this user?'),\n next: __('Next'),\n },\n CATEGORY_OPTIONS,\n data() {\n return {\n selected: '',\n mounted: false,\n };\n },\n computed: {\n getDrawerHeaderHeight() {\n // avoid calculating this in advance because it causes layout thrashing\n // https://gitlab.com/gitlab-org/gitlab/-/issues/331172#note_1269378396\n if (!this.showDrawer) return '0';\n return getContentWrapperHeight();\n },\n },\n mounted() {\n // this is required for the component to properly animate\n // when it is shown with v-if\n this.mounted = true;\n },\n methods: {\n closeDrawer() {\n this.$emit('close-drawer');\n },\n },\n};\n</script>\n<template>\n <gl-drawer\n :header-height=\"getDrawerHeaderHeight\"\n :z-index=\"300\"\n :open=\"showDrawer && mounted\"\n @close=\"closeDrawer\"\n >\n <template #title>\n <h2 class=\"gl-mb-0 gl-mt-0 gl-text-size-h2 gl-leading-24\" data-testid=\"category-drawer-title\">\n {{ $options.i18n.title }}\n </h2>\n </template>\n <template #default>\n <gl-form :action=\"reportAbusePath\" method=\"post\" class=\"gl-text-left\">\n <input :value=\"$options.csrf.token\" type=\"hidden\" name=\"authenticity_token\" />\n\n <input type=\"hidden\" name=\"user_id\" :value=\"reportedUserId\" data-testid=\"input-user-id\" />\n <input\n type=\"hidden\"\n name=\"abuse_report[reported_from_url]\"\n :value=\"reportedFromUrl\"\n data-testid=\"input-referer\"\n />\n\n <gl-form-group :label=\"$options.i18n.label\" label-class=\"gl-text-default\">\n <gl-form-radio-group\n v-model=\"selected\"\n :options=\"$options.CATEGORY_OPTIONS\"\n name=\"abuse_report[category]\"\n required\n />\n </gl-form-group>\n\n <gl-button type=\"submit\" variant=\"confirm\" data-testid=\"submit-form-button\">\n {{ $options.i18n.next }}\n </gl-button>\n </gl-form>\n </template>\n </gl-drawer>\n</template>\n","import { render, staticRenderFns } from \"./abuse_category_selector.vue?vue&type=template&id=4bfeb9fb\"\nimport script from \"./abuse_category_selector.vue?vue&type=script&lang=js\"\nexport * from \"./abuse_category_selector.vue?vue&type=script&lang=js\"\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 null,\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('gl-button-group',{staticClass:\"js-comment-button js-comment-submit-button comment-type-dropdown gl-mb-3 gl-w-full sm:gl-mb-0 sm:gl-w-auto\",attrs:{\"data-track-label\":_vm.trackingLabel,\"data-track-action\":\"click_button\",\"data-testid\":\"comment-button\"}},[_c('gl-button',{attrs:{\"type\":\"submit\",\"variant\":\"confirm\",\"disabled\":_vm.disabled},on:{\"click\":_vm.handleClick}},[_vm._v(\"\\n \"+_vm._s(_vm.commentButtonTitle)+\"\\n \")]),_vm._v(\" \"),_c('gl-collapsible-listbox',{attrs:{\"variant\":\"confirm\",\"text-sr-only\":\"\",\"toggle-text\":_vm.$options.i18n.toggleSrText,\"disabled\":_vm.disabled,\"items\":_vm.dropdownItems,\"selected\":_vm.noteType},on:{\"select\":_vm.setNoteType},scopedSlots:_vm._u([{key:\"list-item\",fn:function({ item }){return [_c('div',{attrs:{\"data-testid\":item.testid}},[_c('strong',[_vm._v(_vm._s(item.text))]),_vm._v(\" \"),_c('p',{staticClass:\"gl-m-0\"},[_vm._v(_vm._s(item.description))])])]}}])})],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","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!./comment_type_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!./comment_type_dropdown.vue?vue&type=script&lang=js\"","<script>\nimport { GlButtonGroup, GlButton, GlCollapsibleListbox } from '@gitlab/ui';\n\nimport { sprintf, __ } from '~/locale';\nimport { COMMENT_FORM } from '~/notes/i18n';\nimport * as constants from '../constants';\n\nexport default {\n name: 'CommentTypeDropdown',\n i18n: {\n ...COMMENT_FORM,\n toggleSrText: __('Comment type'),\n },\n components: {\n GlButtonGroup,\n GlButton,\n GlCollapsibleListbox,\n },\n model: {\n prop: 'noteType',\n event: 'change',\n },\n props: {\n disabled: {\n type: Boolean,\n required: false,\n default: false,\n },\n trackingLabel: {\n type: String,\n required: false,\n default: undefined,\n },\n discussionsRequireResolution: {\n type: Boolean,\n required: false,\n default: false,\n },\n isInternalNote: {\n type: Boolean,\n required: false,\n default: false,\n },\n noteableDisplayName: {\n type: String,\n required: true,\n },\n noteType: {\n type: String,\n required: true,\n },\n isReviewDropdown: {\n type: Boolean,\n required: false,\n default: false,\n },\n },\n computed: {\n isNoteTypeComment() {\n return this.noteType === constants.COMMENT;\n },\n isNoteTypeDiscussion() {\n return this.noteType === constants.DISCUSSION;\n },\n dropdownCommentButtonTitle() {\n const { comment, internalComment } = this.$options.i18n.submitButton;\n\n return this.isInternalNote ? internalComment : comment;\n },\n dropdownStartThreadButtonTitle() {\n const { startThread, startInternalThread } = this.$options.i18n.submitButton;\n\n return this.isInternalNote ? startInternalThread : startThread;\n },\n commentButtonTitle() {\n const { comment, internalComment, startThread, startInternalThread } = this.$options.i18n;\n const { saveThread, saveComment } = this.$options.i18n.addToReviewButton;\n\n if (this.isInternalNote) {\n return this.noteType === constants.COMMENT ? internalComment : startInternalThread;\n }\n\n if (this.isReviewDropdown) {\n return this.noteType === constants.COMMENT ? saveComment : saveThread;\n }\n\n return this.noteType === constants.COMMENT ? comment : startThread;\n },\n startDiscussionDescription() {\n const {\n discussionThatNeedsResolution,\n internalDiscussionThatNeedsResolution,\n discussion,\n internalDiscussion,\n } = this.$options.i18n;\n\n if (this.isInternalNote) {\n return this.discussionsRequireResolution\n ? internalDiscussionThatNeedsResolution\n : internalDiscussion;\n }\n return this.discussionsRequireResolution ? discussionThatNeedsResolution : discussion;\n },\n commentDescription() {\n const { commentHelp, internalCommentHelp } = this.$options.i18n.submitButton;\n\n return sprintf(this.isInternalNote ? internalCommentHelp : commentHelp, {\n noteableDisplayName: this.noteableDisplayName,\n });\n },\n dropdownItems() {\n return [\n {\n text: this.dropdownCommentButtonTitle,\n description: this.commentDescription,\n value: constants.COMMENT,\n },\n {\n text: this.dropdownStartThreadButtonTitle,\n description: this.startDiscussionDescription,\n value: constants.DISCUSSION,\n testid: 'discussion-menu-item',\n },\n ];\n },\n },\n methods: {\n handleClick() {\n this.$emit('click');\n },\n setNoteType(value) {\n this.$emit('change', value);\n },\n },\n};\n</script>\n\n<template>\n <gl-button-group\n class=\"js-comment-button js-comment-submit-button comment-type-dropdown gl-mb-3 gl-w-full sm:gl-mb-0 sm:gl-w-auto\"\n :data-track-label=\"trackingLabel\"\n data-track-action=\"click_button\"\n data-testid=\"comment-button\"\n >\n <gl-button type=\"submit\" variant=\"confirm\" :disabled=\"disabled\" @click=\"handleClick\">\n {{ commentButtonTitle }}\n </gl-button>\n <gl-collapsible-listbox\n variant=\"confirm\"\n text-sr-only\n :toggle-text=\"$options.i18n.toggleSrText\"\n :disabled=\"disabled\"\n :items=\"dropdownItems\"\n :selected=\"noteType\"\n @select=\"setNoteType\"\n >\n <template #list-item=\"{ item }\">\n <div :data-testid=\"item.testid\">\n <strong>{{ item.text }}</strong>\n <p class=\"gl-m-0\">{{ item.description }}</p>\n </div>\n </template>\n </gl-collapsible-listbox>\n </gl-button-group>\n</template>\n","import { render, staticRenderFns } from \"./comment_type_dropdown.vue?vue&type=template&id=63ac1d67\"\nimport script from \"./comment_type_dropdown.vue?vue&type=script&lang=js\"\nexport * from \"./comment_type_dropdown.vue?vue&type=script&lang=js\"\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 null,\n null\n \n)\n\nexport default component.exports","var baseUniq = require('./_baseUniq');\n\n/**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each element\n * is kept. The order of result values is determined by the order they occur\n * in the array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\nfunction uniq(array) {\n return (array && array.length) ? baseUniq(array) : [];\n}\n\nmodule.exports = uniq;\n","var SetCache = require('./_SetCache'),\n arrayIncludes = require('./_arrayIncludes'),\n arrayIncludesWith = require('./_arrayIncludesWith'),\n cacheHas = require('./_cacheHas'),\n createSet = require('./_createSet'),\n setToArray = require('./_setToArray');\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nmodule.exports = baseUniq;\n","/* eslint-disable camelcase,\nno-unused-expressions, default-case,\nconsistent-return, no-param-reassign,\nno-shadow, no-useless-escape,\nclass-methods-use-this */\n\n/* global ResolveService */\n\n/*\ndeprecated_notes_spec.js is the spec for the legacy, jQuery notes application. It has nothing to do with the new, fancy Vue notes app.\n */\n\nimport { GlSkeletonLoader } from '@gitlab/ui';\nimport Autosize from 'autosize';\nimport $ from 'jquery';\nimport { escape, uniqueId } from 'lodash';\nimport Vue from 'vue';\nimport { renderGFM } from '~/behaviors/markdown/render_gfm';\nimport { createAlert, VARIANT_INFO } from '~/alert';\nimport { sanitize } from '~/lib/dompurify';\nimport '~/lib/utils/jquery_at_who';\nimport AjaxCache from '~/lib/utils/ajax_cache';\nimport { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';\nimport syntaxHighlight from '~/syntax_highlight';\nimport CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue';\nimport * as constants from '~/notes/constants';\nimport { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';\nimport { COMMENT_FORM, UPDATE_COMMENT_FORM } from '~/notes/i18n';\nimport Autosave from './autosave';\nimport loadAwardsHandler from './awards_handler';\nimport { defaultAutocompleteConfig } from './gfm_auto_complete';\nimport GLForm from './gl_form';\nimport axios from './lib/utils/axios_utils';\nimport {\n getCookie,\n isInViewport,\n getPagePath,\n scrollToElement,\n isModifierKey,\n isInMRPage,\n} from './lib/utils/common_utils';\nimport { localTimeAgo } from './lib/utils/datetime_utility';\nimport { getLocationHash } from './lib/utils/url_utility';\nimport { sprintf, s__, __ } from './locale';\nimport TaskList from './task_list';\n\nwindow.autosize = Autosize;\n\nfunction normalizeNewlines(str) {\n return str.replace(/\\r\\n/g, '\\n');\n}\n\nconst REGEX_QUICK_ACTIONS = /^\\/\\w+.*$/gm;\n\nexport default class Notes {\n // eslint-disable-next-line max-params\n static initialize(notes_url, last_fetched_at, view, enableGFM) {\n if (!this.instance) {\n this.instance = new Notes(notes_url, last_fetched_at, view, enableGFM);\n }\n }\n\n static getInstance() {\n return this.instance;\n }\n\n // eslint-disable-next-line max-params\n constructor(notes_url, last_fetched_at, view, enableGFM = defaultAutocompleteConfig) {\n this.updateTargetButtons = this.updateTargetButtons.bind(this);\n this.updateComment = this.updateComment.bind(this);\n this.visibilityChange = this.visibilityChange.bind(this);\n this.cancelDiscussionForm = this.cancelDiscussionForm.bind(this);\n this.onAddDiffNote = this.onAddDiffNote.bind(this);\n this.onAddImageDiffNote = this.onAddImageDiffNote.bind(this);\n this.setupDiscussionNoteForm = this.setupDiscussionNoteForm.bind(this);\n this.onReplyToDiscussionNote = this.onReplyToDiscussionNote.bind(this);\n this.removeNote = this.removeNote.bind(this);\n this.cancelEdit = this.cancelEdit.bind(this);\n this.updateNote = this.updateNote.bind(this);\n this.addDiscussionNote = this.addDiscussionNote.bind(this);\n this.addNoteError = this.addNoteError.bind(this);\n this.addNote = this.addNote.bind(this);\n this.resetMainTargetForm = this.resetMainTargetForm.bind(this);\n this.refresh = this.refresh.bind(this);\n this.keydownNoteText = this.keydownNoteText.bind(this);\n this.toggleCommitList = this.toggleCommitList.bind(this);\n this.postComment = this.postComment.bind(this);\n this.clearAlertWrapper = this.clearAlert.bind(this);\n this.onHashChange = this.onHashChange.bind(this);\n this.note_ids = [];\n\n this.notes_url = notes_url;\n this.enableGFM = enableGFM;\n // Used to keep track of updated notes while people are editing things\n this.updatedNotesTrackingMap = {};\n this.last_fetched_at = last_fetched_at;\n this.noteable_url = document.URL;\n this.notesCountBadge ||\n (this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'));\n this.basePollingInterval = 15000;\n this.maxPollingSteps = 4;\n\n this.$wrapperEl = isInMRPage() ? $(document).find('.diffs') : $(document);\n this.cleanBinding();\n this.addBinding();\n this.setPollingInterval();\n this.setupMainTargetNoteForm(enableGFM);\n this.taskList = new TaskList({\n dataType: 'note',\n fieldName: 'note',\n selector: '.notes',\n });\n this.setViewType(view);\n\n // We are in the merge requests page so we need another edit form for Changes tab\n if (getPagePath(1) === 'merge_requests') {\n $('.note-edit-form').clone().addClass('mr-note-edit-form').insertAfter('.note-edit-form');\n }\n\n const hash = getLocationHash();\n const $anchor = hash && document.getElementById(hash);\n\n if ($anchor) {\n this.loadLazyDiff({ currentTarget: $anchor });\n }\n }\n\n setViewType(view) {\n this.view = getCookie('diff_view') || view;\n }\n\n addBinding() {\n // Edit note link\n this.$wrapperEl.on('click', '.js-note-edit', this.showEditForm.bind(this));\n this.$wrapperEl.on('click', '.note-edit-cancel', this.cancelEdit);\n // Reopen and close actions for Issue/MR combined with note form submit\n this.$wrapperEl.on(\n 'click',\n // this oddly written selector needs to match the old style (button with class) as\n // well as the new DOM styling from the Vue-based note form\n 'button.js-comment-submit-button, .js-comment-submit-button > button:first-child',\n this.postComment,\n );\n this.$wrapperEl.on('click', '.js-comment-save-button', this.updateComment);\n this.$wrapperEl.on('keyup input', '.js-note-text', this.updateTargetButtons);\n // resolve a discussion\n this.$wrapperEl.on('click', '.js-comment-resolve-button', this.postComment);\n // remove a note (in general)\n this.$wrapperEl.on('ajax:success', '.js-note-delete', this.removeNote);\n // delete note attachment\n this.$wrapperEl.on('click', '.js-note-attachment-delete', this.removeAttachment);\n // update the file name when an attachment is selected\n this.$wrapperEl.on('change', '.js-note-attachment-input', this.updateFormAttachment);\n // reply to diff/discussion notes\n this.$wrapperEl.on('focus', '.js-discussion-reply-button', this.onReplyToDiscussionNote);\n // add diff note\n this.$wrapperEl.on('click', '.js-add-diff-note-button', this.onAddDiffNote);\n // add diff note for images\n this.$wrapperEl.on('click', '.js-add-image-diff-note-button', this.onAddImageDiffNote);\n // hide diff note form\n this.$wrapperEl.on('click', '.js-close-discussion-note-form', this.cancelDiscussionForm);\n // toggle commit list\n this.$wrapperEl.on('click', '.system-note-commit-list-toggler', this.toggleCommitList);\n\n this.$wrapperEl.on('click', '.js-toggle-lazy-diff', this.loadLazyDiff);\n this.$wrapperEl.on(\n 'click',\n '.js-toggle-lazy-diff-retry-button',\n this.onClickRetryLazyLoad.bind(this),\n );\n\n // fetch notes when tab becomes visible\n this.$wrapperEl.on('visibilitychange', this.visibilityChange);\n // when issue status changes, we need to refresh data\n this.$wrapperEl.on('issuable:change', this.refresh);\n // ajax:events that happen on Form when actions like Reopen, Close are performed on Issues and MRs.\n this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.addNote);\n this.$wrapperEl.on('ajax:success', '.js-discussion-note-form', this.addDiscussionNote);\n this.$wrapperEl.on('ajax:success', '.js-main-target-form', this.resetMainTargetForm);\n this.$wrapperEl.on(\n 'ajax:complete',\n '.js-main-target-form',\n this.reenableTargetFormSubmitButton,\n );\n // when a key is clicked on the notes\n this.$wrapperEl.on('keydown', '.js-note-text', this.keydownNoteText);\n // When the URL fragment/hash has changed, `#note_xxx`\n $(window).on('hashchange', this.onHashChange);\n }\n\n cleanBinding() {\n this.$wrapperEl.off('click', '.js-note-edit');\n this.$wrapperEl.off('click', '.note-edit-cancel');\n this.$wrapperEl.off('ajax:success', '.js-note-delete');\n this.$wrapperEl.off('click', '.js-note-attachment-delete');\n this.$wrapperEl.off('click', '.js-discussion-reply-button');\n this.$wrapperEl.off('click', '.js-add-diff-note-button');\n this.$wrapperEl.off('click', '.js-add-image-diff-note-button');\n // eslint-disable-next-line @gitlab/no-global-event-off\n this.$wrapperEl.off('visibilitychange');\n this.$wrapperEl.off('keyup input', '.js-note-text');\n this.$wrapperEl.off('click', '.js-note-target-reopen');\n this.$wrapperEl.off('click', '.js-note-target-close');\n this.$wrapperEl.off('keydown', '.js-note-text');\n this.$wrapperEl.off('click', '.js-comment-resolve-button');\n this.$wrapperEl.off('click', '.system-note-commit-list-toggler');\n this.$wrapperEl.off('click', '.js-toggle-lazy-diff');\n this.$wrapperEl.off('click', '.js-toggle-lazy-diff-retry-button');\n this.$wrapperEl.off('ajax:success', '.js-main-target-form');\n this.$wrapperEl.off('ajax:success', '.js-discussion-note-form');\n this.$wrapperEl.off('ajax:complete', '.js-main-target-form');\n $(window).off('hashchange', this.onHashChange);\n }\n\n static initCommentTypeToggle(form) {\n const el = form.querySelector('.js-comment-type-dropdown');\n const { noteableName } = el.dataset;\n const noteTypeInput = form.querySelector('#note_type');\n const formHasContent = form.querySelector('.js-note-text').value.trim().length > 0;\n\n form.commentTypeComponent = new Vue({\n el,\n data() {\n return {\n noteType: constants.COMMENT,\n disabled: !formHasContent,\n };\n },\n render(createElement) {\n return createElement(CommentTypeDropdown, {\n props: {\n noteType: this.noteType,\n noteableDisplayName: noteableName,\n disabled: this.disabled,\n },\n on: {\n change: (arg) => {\n this.noteType = arg;\n if (this.noteType === constants.DISCUSSION) {\n noteTypeInput.value = constants.DISCUSSION_NOTE;\n } else {\n noteTypeInput.value = '';\n }\n },\n },\n });\n },\n });\n }\n\n async keydownNoteText(e) {\n let discussionNoteForm;\n let editNote;\n let myLastNote;\n let myLastNoteEditBtn;\n let newText;\n let originalText;\n\n if (isModifierKey(e)) {\n return;\n }\n\n const $textarea = $(e.target);\n // Edit previous note when UP arrow is hit\n switch (e.which) {\n case 38:\n if ($textarea.val() !== '') {\n return;\n }\n myLastNote = $(\n `li.note[data-author-id='${gon.current_user_id}'][data-editable]:last`,\n $textarea.closest('.note, .notes_holder, #notes'),\n );\n if (myLastNote.length) {\n myLastNoteEditBtn = myLastNote.find('.js-note-edit');\n return myLastNoteEditBtn.trigger('click', [true, myLastNote]);\n }\n break;\n // Cancel creating diff note or editing any note when ESCAPE is hit\n case 27:\n discussionNoteForm = $textarea.closest('.js-discussion-note-form');\n if (discussionNoteForm.length) {\n if ($textarea.val() !== '') {\n const confirmed = await confirmAction(__('Your comment will be discarded.'), {\n primaryBtnVariant: 'danger',\n primaryBtnText: __('Discard'),\n });\n if (!confirmed) return;\n }\n this.removeDiscussionNoteForm(discussionNoteForm);\n return;\n }\n editNote = $textarea.closest('.note');\n if (editNote.length) {\n originalText = $textarea.closest('form').data('originalNote');\n newText = $textarea.val();\n if (originalText !== newText) {\n const confirmed = await confirmAction(\n __('Are you sure you want to discard this comment?'),\n {\n primaryBtnVariant: 'danger',\n primaryBtnText: __('Discard'),\n },\n );\n if (!confirmed) return;\n }\n return this.removeNoteEditForm(editNote);\n }\n }\n }\n\n initRefresh() {\n if (Notes.interval) {\n clearInterval(Notes.interval);\n }\n Notes.interval = setInterval(() => this.refresh(), this.pollingInterval);\n }\n\n refresh() {\n if (!document.hidden) {\n return this.getContent();\n }\n }\n\n getContent() {\n if (this.refreshing) {\n return;\n }\n\n this.refreshing = true;\n\n axios\n .get(`${this.notes_url}?html=true`, {\n headers: {\n 'X-Last-Fetched-At': this.last_fetched_at,\n },\n })\n .then(({ data }) => {\n const { notes } = data;\n this.last_fetched_at = data.last_fetched_at;\n this.setPollingInterval(data.notes.length);\n $.each(notes, (i, note) => this.renderNote(note));\n\n this.refreshing = false;\n })\n .catch(() => {\n this.refreshing = false;\n });\n }\n\n /**\n * Increase @pollingInterval up to 120 seconds on every function call,\n * if `shouldReset` has a truthy value, 'null' or 'undefined' the variable\n * will reset to @basePollingInterval.\n *\n * Note: this function is used to gradually increase the polling interval\n * if there aren't new notes coming from the server\n */\n setPollingInterval(shouldReset) {\n if (shouldReset == null) {\n shouldReset = true;\n }\n const nthInterval = this.basePollingInterval * 2 ** (this.maxPollingSteps - 1);\n if (shouldReset) {\n this.pollingInterval = this.basePollingInterval;\n } else if (this.pollingInterval < nthInterval) {\n this.pollingInterval *= 2;\n }\n return this.initRefresh();\n }\n\n handleQuickActions(noteEntity) {\n let votesBlock;\n if (noteEntity.commands_changes) {\n if ('merge' in noteEntity.commands_changes) {\n Notes.checkMergeRequestStatus();\n }\n\n if ('emoji_award' in noteEntity.commands_changes) {\n votesBlock = $('.js-awards-block').eq(0);\n\n loadAwardsHandler()\n .then((awardsHandler) => {\n awardsHandler.addAwardToEmojiBar(votesBlock, noteEntity.commands_changes.emoji_award);\n awardsHandler.scrollToAwards();\n })\n .catch(() => {\n // ignore\n });\n }\n }\n }\n\n setupNewNote($note) {\n // Update datetime format on the recent note\n localTimeAgo($note.find('.js-timeago').get(), false);\n\n this.taskList.init();\n\n // This stops the note highlight, #note_xxx`, from being removed after real time update\n // The `:target` selector does not re-evaluate after we replace element in the DOM\n Notes.updateNoteTargetSelector($note);\n this.$noteToCleanHighlight = $note;\n }\n\n onHashChange() {\n if (this.$noteToCleanHighlight) {\n Notes.updateNoteTargetSelector(this.$noteToCleanHighlight);\n }\n\n this.$noteToCleanHighlight = null;\n }\n\n static updateNoteTargetSelector($note) {\n const hash = getLocationHash();\n // Needs to be an explicit true/false for the jQuery `toggleClass(force)`\n const addTargetClass = Boolean(hash && $note.filter(`#${hash}`).length > 0);\n $note.toggleClass('target', addTargetClass);\n }\n\n /**\n * Render note in main comments area.\n *\n * Note: for rendering inline notes use renderDiscussionNote\n */\n renderNote(noteEntity, $form, $notesList = $('.main-notes-list')) {\n if (noteEntity.discussion_html) {\n return this.renderDiscussionNote(noteEntity, $form);\n }\n\n if (!noteEntity.valid) {\n if (noteEntity?.quick_actions_status?.messages) {\n if (noteEntity.commands_changes && Object.keys(noteEntity.commands_changes).length > 0) {\n $notesList.find('.system-note.being-posted').remove();\n }\n this.addAlert({\n message: noteEntity.quick_actions_status.messages,\n variant: VARIANT_INFO,\n parent: this.parentTimeline.get(0),\n });\n this.refresh();\n }\n return;\n }\n\n const $note = $notesList.find(`#note_${noteEntity.id}`);\n if (Notes.isNewNote(noteEntity, this.note_ids)) {\n if (isInMRPage()) {\n return;\n }\n\n if ($notesList.length) {\n $notesList.find('.system-note.being-posted').remove();\n }\n const $newNote = Notes.animateAppendNote(noteEntity.html, $notesList);\n\n this.setupNewNote($newNote);\n this.refresh();\n return this.updateNotesCount(1);\n }\n if (Notes.isUpdatedNote(noteEntity, $note)) {\n // The server can send the same update multiple times so we need to make sure to only update once per actual update.\n const isEditing = $note.hasClass('is-editing');\n const initialContent = normalizeNewlines($note.find('.original-note-content').text().trim());\n const $textarea = $note.find('.js-note-text');\n const currentContent = $textarea.val();\n // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way\n const sanitizedNoteNote = normalizeNewlines(noteEntity.note);\n const isTextareaUntouched =\n currentContent === initialContent || currentContent === sanitizedNoteNote;\n\n if (isEditing && isTextareaUntouched) {\n $textarea.val(noteEntity.note);\n this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;\n } else if (isEditing && !isTextareaUntouched) {\n this.putConflictEditWarningInPlace(noteEntity, $note);\n this.updatedNotesTrackingMap[noteEntity.id] = noteEntity;\n } else {\n const $updatedNote = Notes.animateUpdateNote(noteEntity.html, $note);\n this.setupNewNote($updatedNote);\n }\n }\n }\n\n isParallelView() {\n return getCookie('diff_view') === 'parallel';\n }\n\n /**\n * Render note in discussion area. To render inline notes use renderDiscussionNote.\n */\n renderDiscussionNote(noteEntity, $form) {\n let discussionContainer;\n let row;\n\n if (!Notes.isNewNote(noteEntity, this.note_ids)) {\n return;\n }\n\n const form =\n $form || $(`.js-discussion-note-form[data-discussion-id=\"${noteEntity.discussion_id}\"]`);\n row =\n form.length || !noteEntity.discussion_line_code\n ? form.closest('tr')\n : $(`#${noteEntity.discussion_line_code}`);\n\n if (noteEntity.on_image) {\n row = form;\n }\n\n // is this the first note of discussion?\n discussionContainer = $(`.notes[data-discussion-id=\"${noteEntity.discussion_id}\"]`);\n if (!discussionContainer.length) {\n discussionContainer = form.closest('.discussion').find('.notes');\n }\n if (discussionContainer.length === 0) {\n if (noteEntity.diff_discussion_html) {\n let discussionElement = document.createElement('table');\n let internalNote;\n\n if (!noteEntity.on_image) {\n /*\n DOMPurify will strip table-less <tr>/<td>, so to get it to stop deleting\n nodes (since our note HTML starts with a table-less <tr>), we need to wrap\n the noteEntity discussion HTML in a <table> to perform the other\n sanitization.\n */\n internalNote = sanitize(`<table>${noteEntity.diff_discussion_html}</table>`, {\n RETURN_DOM: true,\n });\n /*\n Since we wrapped the <tr> in a <table>, we need to extract the <tr> back out.\n DOMPurify returns a Body Element, so we have to start there, then get the\n wrapping table, and then get the content we actually want.\n Curiously, DOMPurify **ADDS** a totally novel <tbody>, so we're actually\n inserting a completely as-yet-unseen <tbody> element here.\n */\n discussionElement = internalNote.querySelector('table').querySelector('.notes_holder');\n } else {\n // Image comments don't need <table> manipulation, they're already <div>s\n internalNote = sanitize(noteEntity.diff_discussion_html, {\n RETURN_DOM: true,\n });\n discussionElement.insertAdjacentElement('afterbegin', internalNote.firstElementChild);\n }\n\n renderGFM(discussionElement);\n const $discussion = $(discussionElement).unwrap();\n\n if (noteEntity.on_image) {\n discussionElement.classList.add('discussion-notes', 'gl-block');\n }\n\n if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) {\n // insert the note and the reply button after the temp row\n row.after($discussion);\n } else {\n // Merge new discussion HTML in\n const $notes = $discussion.find(\n `.notes[data-discussion-id=\"${noteEntity.discussion_id}\"]`,\n );\n const contentContainerClass = $notes\n .closest('.notes-content')\n .attr('class')\n .split(' ')\n .join('.');\n\n row\n .find(`.${contentContainerClass} .content`)\n .append($notes.closest('.content').children());\n }\n } else {\n Notes.animateAppendNote(noteEntity.discussion_html, $('.main-notes-list'));\n }\n } else {\n // append new note to all matching discussions\n Notes.animateAppendNote(noteEntity.html, discussionContainer);\n }\n\n localTimeAgo(document.querySelectorAll('.js-timeago'), false);\n Notes.checkMergeRequestStatus();\n return this.updateNotesCount(1);\n }\n\n getLineHolder(changesDiscussionContainer) {\n return $(changesDiscussionContainer)\n .closest('.notes_holder')\n .prevAll('.line_holder')\n .first()\n .get(0);\n }\n\n /**\n * Called in response the main target form has been successfully submitted.\n *\n * Removes any errors.\n * Resets text and preview.\n * Resets buttons.\n */\n resetMainTargetForm(e) {\n const form = $('.js-main-target-form');\n // remove validation errors\n form.find('.js-errors').remove();\n // reset text and preview\n if (form.find('.js-md-preview-button').val() === 'edit') {\n form.find('.js-md-preview-button').click();\n }\n\n form.find('.js-note-text').val('').trigger('input');\n form.find('.js-note-text').each(function reset() {\n this.$autosave.reset();\n });\n\n const event = document.createEvent('Event');\n event.initEvent('autosize:update', true, false);\n form.find('.js-autosize')[0].dispatchEvent(event);\n\n this.updateTargetButtons(e);\n }\n\n reenableTargetFormSubmitButton() {\n const form = $('.js-main-target-form');\n return form.find('.js-note-text').trigger('input');\n }\n\n /**\n * Shows the main form and does some setup on it.\n *\n * Sets some hidden fields in the form.\n */\n setupMainTargetNoteForm(enableGFM) {\n // find the form\n const form = $('.js-new-note-form');\n // Set a global clone of the form for later cloning\n this.formClone = form.clone();\n // show the form\n this.setupNoteForm(form, enableGFM);\n // fix classes\n form.removeClass('js-new-note-form');\n form.addClass('js-main-target-form');\n form.find('#note_line_code').remove();\n form.find('#note_position').remove();\n form.find('#note_type').val('');\n form.find('#note_project_id').remove();\n form.find('#in_reply_to_discussion_id').remove();\n this.parentTimeline = form.parents('.timeline');\n\n if (form.length) {\n Notes.initCommentTypeToggle(form.get(0));\n }\n }\n\n /**\n * General note form setup.\n *\n * deactivates the submit button when text is empty\n * hides the preview button when text is empty\n * set up GFM auto complete\n * show the form\n */\n setupNoteForm(form, enableGFM = defaultAutocompleteConfig) {\n this.glForm = new GLForm(form, enableGFM);\n const textarea = form.find('.js-note-text');\n const key = [\n s__('NoteForm|Note'),\n form.find('#note_noteable_type').val(),\n form.find('#note_noteable_id').val(),\n form.find('#note_commit_id').val(),\n form.find('#note_type').val(),\n form.find('#note_project_id').val(),\n form.find('#in_reply_to_discussion_id').val(),\n\n // LegacyDiffNote\n form.find('#note_line_code').val(),\n\n // DiffNote\n form.find('#note_position').val(),\n ];\n const textareaEl = textarea.get(0);\n // eslint-disable-next-line no-new\n if (textareaEl) new Autosave(textareaEl, key);\n }\n\n /**\n * Called in response to the new note form being submitted\n *\n * Adds new note to list.\n */\n addNote($form, note) {\n return this.renderNote(note);\n }\n\n addNoteError(error, $form) {\n let formParentTimeline;\n if ($form.hasClass('js-main-target-form')) {\n formParentTimeline = $form.parents('.timeline');\n } else if ($form.hasClass('js-discussion-note-form')) {\n formParentTimeline = $form.closest('.discussion-notes').find('.notes');\n }\n\n const serverErrorMessage = error?.response?.data?.errors;\n\n const alertMessage = serverErrorMessage\n ? sprintf(COMMENT_FORM.error, { reason: serverErrorMessage.toLowerCase() }, false)\n : COMMENT_FORM.GENERIC_UNSUBMITTABLE_NETWORK;\n\n return this.addAlert({\n message: alertMessage,\n parent: formParentTimeline.get(0),\n });\n }\n\n updateNoteError(error, $editingNote) {\n const serverErrorMessage = error?.response?.data?.errors;\n\n const alertMessage = serverErrorMessage\n ? sprintf(UPDATE_COMMENT_FORM.error, { reason: serverErrorMessage }, false)\n : UPDATE_COMMENT_FORM.defaultError;\n\n return this.addAlert({\n message: alertMessage,\n parent: $editingNote.get(0),\n });\n }\n\n /**\n * Called in response to the new note form being submitted\n *\n * Adds new note to list.\n */\n addDiscussionNote($form, note, isNewDiffComment) {\n if ($form.attr('data-resolve-all') != null) {\n const discussionId = $form.data('discussionId');\n const mergeRequestId = $form.data('noteableIid');\n\n if (ResolveService != null) {\n ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);\n }\n }\n\n this.renderNote(note, $form);\n // cleanup after successfully creating a diff/discussion note\n if (isNewDiffComment) {\n this.removeDiscussionNoteForm($form);\n }\n }\n\n /**\n * Called in response to the edit note form being submitted\n *\n * Updates the current note field.\n */\n updateNote(noteEntity, $targetNote) {\n // Convert returned HTML to a jQuery object so we can modify it further\n const $noteEntityEl = $(noteEntity.html);\n const $noteAvatar = $noteEntityEl.find('.image-diff-avatar-link');\n const $targetNoteBadge = $targetNote.find('.design-note-pin');\n\n $noteAvatar.append($targetNoteBadge);\n this.revertNoteEditForm($targetNote);\n renderGFM(Notes.getNodeToRender($noteEntityEl));\n // Find the note's `li` element by ID and replace it with the updated HTML\n const $note_li = $(`.note-row-${noteEntity.id}`);\n\n $note_li.replaceWith($noteEntityEl);\n this.setupNewNote($noteEntityEl);\n }\n\n checkContentToAllowEditing($el) {\n const initialContent = $el.find('.original-note-content').text().trim();\n const currentContent = $el.find('.js-note-text').val();\n let isAllowed = true;\n\n if (currentContent === initialContent) {\n this.removeNoteEditForm($el);\n } else {\n const isWidgetVisible = isInViewport($el.get(0));\n\n if (!isWidgetVisible) {\n scrollToElement($el);\n }\n\n $el.find('.js-finish-edit-warning').show();\n isAllowed = false;\n }\n\n return isAllowed;\n }\n\n /**\n * Called in response to clicking the edit note link\n *\n * Replaces the note text with the note edit form\n * Adds a data attribute to the form with the original content of the note for cancellations\n */\n showEditForm(e) {\n e.preventDefault();\n\n const $target = $(e.target);\n const $editForm = $(this.getEditFormSelector($target));\n const $note = $target.closest('.note');\n const $currentlyEditing = $('.note.is-editing:visible');\n\n this.clearAlertWrapper();\n\n if ($currentlyEditing.length) {\n const isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);\n\n if (!isEditAllowed) {\n return;\n }\n }\n\n $note.find('.js-note-attachment-delete').show();\n $editForm.addClass('current-note-edit-form');\n $note.addClass('is-editing');\n this.putEditFormInPlace($target);\n }\n\n /**\n * Called in response to clicking the edit note link\n *\n * Hides edit form and restores the original note text to the editor textarea.\n */\n cancelEdit(e) {\n e.preventDefault();\n const $target = $(e.target);\n const $note = $target.closest('.note');\n const noteId = $note.attr('data-note-id');\n\n this.revertNoteEditForm($target);\n\n if (this.updatedNotesTrackingMap[noteId]) {\n const $newNote = $(this.updatedNotesTrackingMap[noteId].html);\n $note.replaceWith($newNote);\n this.setupNewNote($newNote);\n // Now that we have taken care of the update, clear it out\n delete this.updatedNotesTrackingMap[noteId];\n } else {\n $note.find('.js-finish-edit-warning').hide();\n this.removeNoteEditForm($note);\n }\n }\n\n revertNoteEditForm($target) {\n $target = $target || $('.note.is-editing:visible');\n const selector = this.getEditFormSelector($target);\n const $editForm = $(selector);\n\n $editForm.insertBefore('.js-snippets-note-edit-form-holder');\n $editForm.find('.js-comment-save-button').enable();\n $editForm.find('.js-finish-edit-warning').hide();\n }\n\n getEditFormSelector($el) {\n let selector = '.note-edit-form:not(.mr-note-edit-form)';\n\n if ($el.parents('#diffs').length) {\n selector = '.note-edit-form.mr-note-edit-form';\n }\n\n return selector;\n }\n\n removeNoteEditForm($note) {\n const form = $note.find('.diffs .current-note-edit-form');\n\n $note.removeClass('is-editing');\n form.removeClass('current-note-edit-form');\n form.find('.js-finish-edit-warning').hide();\n // Replace markdown textarea text with original note text.\n return form.find('.js-note-text').val(form.find('form.edit-note').data('originalNote'));\n }\n\n /**\n * Called in response to deleting a note of any kind.\n *\n * Removes the actual note from view.\n * Removes the whole discussion if the last note is being removed.\n */\n removeNote(e) {\n const $note = $(e.currentTarget).closest('.note');\n\n $note.one('ajax:complete', () => {\n const noteElId = $note.attr('id');\n $(`.note[id=\"${noteElId}\"]`).each((i, el) => {\n // A same note appears in the \"Discussion\" and in the \"Changes\" tab, we have\n // to remove all. Using $('.note[id='noteId']') ensure we get all the notes,\n // where $('#noteId') would return only one.\n const $note = $(el);\n const $notes = $note.closest('.discussion-notes');\n const discussionId = $('.notes', $notes).data('discussionId');\n\n $note.remove();\n\n // check if this is the last note for this line\n if ($notes.find('.note').length === 0) {\n const notesTr = $notes.closest('tr');\n\n // \"Discussions\" tab\n $notes.closest('.timeline-entry').remove();\n\n $(`.js-diff-avatars-${discussionId}`).trigger('remove.vue');\n\n // The notes tr can contain multiple lists of notes, like on the parallel diff\n // notesTr does not exist for image diffs\n if (notesTr.find('.discussion-notes').length > 1 || notesTr.length === 0) {\n const $diffFile = $notes.closest('.diff-file');\n if ($diffFile.length > 0) {\n const removeBadgeEvent = new CustomEvent('removeBadge.imageDiff', {\n detail: {\n // badgeNumber's start with 1 and index starts with 0\n badgeNumber: $notes.index() + 1,\n },\n });\n\n $diffFile[0].dispatchEvent(removeBadgeEvent);\n }\n\n $notes.remove();\n } else if (notesTr.length > 0) {\n notesTr.remove();\n }\n }\n });\n\n Notes.checkMergeRequestStatus();\n return this.updateNotesCount(-1);\n });\n }\n\n /**\n * Called in response to clicking the delete attachment link\n *\n * Removes the attachment wrapper view, including image tag if it exists\n * Resets the note editing form\n */\n removeAttachment() {\n const $note = $(this).closest('.note');\n $note.find('.note-attachment').remove();\n $note.find('.note-body > .note-text').show();\n $note.find('.note-header').show();\n return $note.find('.diffs .current-note-edit-form').remove();\n }\n\n /**\n * Called when clicking on the \"reply\" button for a diff line.\n *\n * Shows the note form below the notes.\n */\n onReplyToDiscussionNote(e) {\n this.replyToDiscussionNote(e.target);\n }\n\n replyToDiscussionNote(target) {\n const form = this.cleanForm(this.formClone.clone());\n const replyLink = $(target).closest('.js-discussion-reply-button');\n // insert the form after the button\n replyLink.closest('.discussion-reply-holder').hide().after(form);\n\n // show the form\n return this.setupDiscussionNoteForm(replyLink, form);\n }\n\n /**\n * Shows the diff or discussion form and does some setup on it.\n *\n * Sets some hidden fields in the form.\n *\n * Note: dataHolder must have the \"discussionId\" and \"lineCode\" data attributes set.\n */\n setupDiscussionNoteForm(dataHolder, form) {\n // set up note target\n let diffFileData = dataHolder.closest('.text-file');\n\n if (diffFileData.length === 0) {\n diffFileData = dataHolder.closest('.image');\n }\n\n const discussionID = dataHolder.data('discussionId');\n\n if (discussionID) {\n form.attr('data-discussion-id', discussionID);\n form.find('#in_reply_to_discussion_id').val(discussionID);\n }\n\n form.find('#note_project_id').val(dataHolder.data('discussionProjectId'));\n\n form.attr('data-line-code', dataHolder.data('lineCode'));\n form.find('#line_type').val(dataHolder.data('lineType'));\n\n form.find('#note_noteable_type').val(diffFileData.data('noteableType'));\n form.find('#note_noteable_id').val(diffFileData.data('noteableId'));\n form.find('#note_commit_id').val(diffFileData.data('commitId'));\n\n form.find('#note_type').val(dataHolder.data('noteType'));\n\n // LegacyDiffNote\n form.find('#note_line_code').val(dataHolder.data('lineCode'));\n\n // DiffNote\n form.find('#note_position').val(dataHolder.attr('data-position'));\n\n form.append('</div>').find('.js-close-discussion-note-form').show().removeClass('hide');\n form.find('.js-note-target-close').remove();\n form.find('.js-note-new-discussion').remove();\n this.setupNoteForm(form);\n\n form.removeClass('js-main-target-form').addClass('discussion-form js-discussion-note-form');\n\n form.find('.js-note-text').focus();\n form.find('.js-comment-resolve-button').attr('data-discussion-id', discussionID);\n }\n\n /**\n * Called when clicking on the \"add a comment\" button on the side of a diff line.\n *\n * Inserts a temporary row for the form below the line.\n * Sets up the form and shows it.\n */\n onAddDiffNote(e) {\n e.preventDefault();\n const link = e.currentTarget || e.target;\n const $link = $(link);\n const showReplyInput = !$link.hasClass('js-diff-comment-avatar');\n this.toggleDiffNote({\n target: $link,\n lineType: link.dataset.lineType,\n showReplyInput,\n currentUsername: gon.current_username,\n currentUserAvatar: gon.current_user_avatar_url,\n currentUserFullname: gon.current_user_fullname,\n });\n }\n\n onAddImageDiffNote(e) {\n const $link = $(e.currentTarget || e.target);\n const $diffFile = $link.closest('.diff-file');\n\n const clickEvent = new CustomEvent('click.imageDiff', {\n detail: e,\n });\n\n $diffFile[0].dispatchEvent(clickEvent);\n\n // Set up comment form\n let newForm;\n const $noteContainer = $link.closest('.diff-viewer').find('.note-container');\n const $form = $noteContainer.find('> .discussion-form');\n\n if ($form.length === 0) {\n newForm = this.cleanForm(this.formClone.clone());\n newForm.appendTo($noteContainer);\n } else {\n newForm = $form;\n }\n\n this.setupDiscussionNoteForm($link, newForm);\n }\n\n toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) {\n let addForm;\n let newForm;\n let noteForm;\n let replyButton;\n let rowCssToAdd;\n const $link = $(target);\n const row = $link.closest('tr');\n const nextRow = row.next();\n let targetRow = row;\n if (nextRow.is('.notes_holder')) {\n targetRow = nextRow;\n }\n\n const hasNotes = nextRow.is('.notes_holder');\n addForm = false;\n let lineTypeSelector = '';\n rowCssToAdd =\n '<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes-content\" colspan=\"3\"><div class=\"content\"></div></td></tr>';\n // In parallel view, look inside the correct left/right pane\n if (this.isParallelView()) {\n lineTypeSelector = `.${lineType}`;\n rowCssToAdd =\n '<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line old\"></td><td class=\"notes-content parallel old\"><div class=\"content\"></div></td><td class=\"notes_line new\"></td><td class=\"notes-content parallel new\"><div class=\"content\"></div></td></tr>';\n }\n const notesContentSelector = `.notes-content${lineTypeSelector} .content`;\n let notesContent = targetRow.find(notesContentSelector);\n\n if (hasNotes && showReplyInput) {\n targetRow.show();\n notesContent = targetRow.find(notesContentSelector);\n if (notesContent.length) {\n notesContent.show();\n replyButton = notesContent.find('.js-discussion-reply-button:visible');\n if (replyButton.length) {\n this.replyToDiscussionNote(replyButton[0]);\n } else {\n // In parallel view, the form may not be present in one of the panes\n noteForm = notesContent.find('.js-discussion-note-form');\n if (noteForm.length === 0) {\n addForm = true;\n }\n }\n }\n } else if (showReplyInput) {\n // add a notes row and insert the form\n row.after(rowCssToAdd);\n targetRow = row.next();\n notesContent = targetRow.find(notesContentSelector);\n addForm = true;\n } else {\n const isCurrentlyShown = targetRow.find('.content:not(:empty)').is(':visible');\n const isForced = forceShow === true || forceShow === false;\n const showNow = forceShow === true || (!isCurrentlyShown && !isForced);\n\n targetRow.toggleClass('hide', !showNow);\n notesContent.toggleClass('hide', !showNow);\n }\n\n if (addForm) {\n newForm = this.cleanForm(this.formClone.clone());\n newForm.appendTo(notesContent);\n // show the form\n return this.setupDiscussionNoteForm($link, newForm);\n }\n }\n\n /**\n * Called in response to \"cancel\" on a diff note form.\n *\n * Shows the reply button again.\n * Removes the form and if necessary it's temporary row.\n */\n removeDiscussionNoteForm(form) {\n const row = form.closest('tr');\n const glForm = form.data('glForm');\n glForm.destroy();\n form.find('.js-note-text').each(function reset() {\n this.$autosave.reset();\n });\n // show the reply button (will only work for replies)\n form.prev('.discussion-reply-holder').show();\n if (row.is('.js-temp-notes-holder')) {\n // remove temporary row for diff lines\n return row.remove();\n }\n // only remove the form\n return form.remove();\n }\n\n cancelDiscussionForm(e) {\n e.preventDefault();\n const $form = $(e.target).closest('.js-discussion-note-form');\n const $discussionNote = $(e.target).closest('.discussion-notes');\n\n if ($discussionNote.length === 0) {\n // Only send blur event when the discussion form\n // is not part of a discussion note\n const $diffFile = $form.closest('.diff-file');\n\n if ($diffFile.length > 0) {\n const blurEvent = new CustomEvent('blur.imageDiff', {\n detail: e,\n });\n\n $diffFile[0].dispatchEvent(blurEvent);\n }\n }\n\n return this.removeDiscussionNoteForm($form);\n }\n\n /**\n * Called after an attachment file has been selected.\n *\n * Updates the file name for the selected attachment.\n */\n updateFormAttachment() {\n const form = $(this).closest('form');\n // get only the basename\n const filename = $(this)\n .val()\n .replace(/^.*[\\\\\\/]/, '');\n return form.find('.js-attachment-filename').text(filename);\n }\n\n /**\n * Called when the tab visibility changes\n */\n visibilityChange() {\n return this.refresh();\n }\n\n updateTargetButtons(e) {\n let closetext;\n let reopentext;\n const textarea = $(e.target);\n const form = textarea.parents('form');\n const reopenbtn = form.find('.js-note-target-reopen');\n const closebtn = form.find('.js-note-target-close');\n const savebtn = form.find('.js-comment-save-button');\n const commentTypeComponent = form.get(0)?.commentTypeComponent;\n\n if (textarea.val().trim().length > 0) {\n savebtn.enable();\n reopentext = reopenbtn.attr('data-alternative-text');\n closetext = closebtn.attr('data-alternative-text');\n if (reopenbtn.text() !== reopentext) {\n reopenbtn.text(reopentext);\n }\n if (closebtn.text() !== closetext) {\n closebtn.text(closetext);\n }\n if (reopenbtn.is(':not(.btn-comment-and-reopen)')) {\n reopenbtn.addClass('btn-comment-and-reopen');\n }\n if (closebtn.is(':not(.btn-comment-and-close)')) {\n closebtn.addClass('btn-comment-and-close');\n }\n if (commentTypeComponent) {\n commentTypeComponent.disabled = false;\n }\n } else {\n savebtn.disable();\n reopentext = reopenbtn.data('originalText');\n closetext = closebtn.data('originalText');\n if (reopenbtn.text() !== reopentext) {\n reopenbtn.text(reopentext);\n }\n if (closebtn.text() !== closetext) {\n closebtn.text(closetext);\n }\n if (reopenbtn.is('.btn-comment-and-reopen')) {\n reopenbtn.removeClass('btn-comment-and-reopen');\n }\n if (closebtn.is('.btn-comment-and-close')) {\n closebtn.removeClass('btn-comment-and-close');\n }\n if (commentTypeComponent) {\n commentTypeComponent.disabled = true;\n }\n }\n }\n\n putEditFormInPlace($el) {\n const $editForm = $(this.getEditFormSelector($el));\n const $note = $el.closest('.note');\n\n $editForm.insertAfter($note.find('.note-text'));\n\n const $originalContentEl = $note.find('.original-note-content');\n const originalContent = $originalContentEl.text().trim();\n const postUrl = $originalContentEl.data('postUrl');\n const targetId = $originalContentEl.data('targetId');\n const targetType = $originalContentEl.data('targetType');\n\n this.glForm = new GLForm($editForm.find('form'), this.enableGFM);\n\n $editForm.find('form').attr('action', `${postUrl}?html=true`).attr('data-remote', 'true');\n $editForm.find('.js-form-target-id').val(targetId);\n $editForm.find('.js-form-target-type').val(targetType);\n $editForm.find('.js-note-text').focus().val(originalContent);\n // reset preview\n if ($editForm.find('.js-md-preview-button').val() === 'edit') {\n $editForm.find('.js-md-preview-button').click();\n }\n $editForm.find('.referenced-users').hide();\n }\n\n putConflictEditWarningInPlace(noteEntity, $note) {\n if ($note.find('.js-conflict-edit-warning').length === 0) {\n const open_link = `<a href=\"#note_${noteEntity.id}\" target=\"_blank\" rel=\"noopener noreferrer\">`;\n const $alert = $(`<div class=\"js-conflict-edit-warning alert alert-danger\">\n ${sprintf(\n s__(\n 'Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost',\n ),\n {\n open_link,\n close_link: '</a>',\n },\n )}\n </div>`);\n $alert.insertAfter($note.find('.note-text'));\n }\n }\n\n updateNotesCount(updateCount) {\n return this.notesCountBadge.text(parseInt(this.notesCountBadge.text(), 10) + updateCount);\n }\n\n static renderPlaceholderComponent($container) {\n const el = $container.find('.js-code-placeholder').get(0);\n // eslint-disable-next-line no-new\n new Vue({\n el,\n components: {\n GlSkeletonLoader,\n },\n render(createElement) {\n return createElement('gl-skeleton-loader');\n },\n });\n }\n\n static renderDiffContent($container, data) {\n const { discussion_html } = data;\n const lines = $(discussion_html).find('.line_holder');\n lines.addClass('fade-in');\n $container.find('.diff-content > table > tbody').prepend(lines);\n const fileHolder = $container.find('.file-holder');\n $container.find('.line-holder-placeholder').remove();\n syntaxHighlight(fileHolder);\n }\n\n onClickRetryLazyLoad(e) {\n const $retryButton = $(e.currentTarget);\n\n $retryButton.prop('disabled', true);\n\n return this.loadLazyDiff(e).then(() => {\n $retryButton.prop('disabled', false);\n });\n }\n\n loadLazyDiff(e) {\n const $container = $(e.currentTarget).closest('.js-toggle-container');\n Notes.renderPlaceholderComponent($container);\n\n $container.find('.js-toggle-lazy-diff').removeClass('js-toggle-lazy-diff');\n\n const $tableEl = $container.find('tbody');\n if ($tableEl.length === 0) return;\n\n const fileHolder = $container.find('.file-holder');\n const url = fileHolder.data('linesPath');\n\n const $errorContainer = $container.find('.js-error-lazy-load-diff');\n const $successContainer = $container.find('.js-success-lazy-load');\n\n /**\n * We only fetch resolved discussions.\n * Unresolved discussions don't have an endpoint being provided.\n */\n if (url) {\n return axios\n .get(url)\n .then(({ data }) => {\n // Reset state in case last request returned error\n $successContainer.removeClass('hidden');\n $errorContainer.addClass('hidden');\n\n Notes.renderDiffContent($container, data);\n })\n .catch(() => {\n $successContainer.addClass('hidden');\n $errorContainer.removeClass('hidden');\n });\n }\n return Promise.resolve();\n }\n\n toggleCommitList(e) {\n const $element = $(e.currentTarget);\n const $closestSystemCommitList = $element.siblings('.system-note-commit-list');\n const $svgChevronUpElement = $element.find('svg.js-chevron-up');\n const $svgChevronDownElement = $element.find('svg.js-chevron-down');\n\n $svgChevronUpElement.toggleClass('gl-hidden');\n $svgChevronDownElement.toggleClass('gl-hidden');\n\n $closestSystemCommitList.toggleClass('hide-shade');\n }\n\n addAlert(...alertParams) {\n this.alert = createAlert(...alertParams);\n }\n\n clearAlert() {\n this.alert?.dismiss();\n }\n\n cleanForm($form) {\n // Remove dropdown\n $form.find('.dropdown-menu').remove();\n\n return $form;\n }\n\n /**\n * Check if note does not exist on page\n */\n static isNewNote(noteEntity, note_ids) {\n if (note_ids.length === 0) {\n note_ids = Notes.getNotesIds();\n }\n const isNewEntry = $.inArray(noteEntity.id, note_ids) === -1;\n if (isNewEntry) {\n note_ids.push(noteEntity.id);\n }\n return isNewEntry;\n }\n\n /**\n * Get notes ids\n */\n static getNotesIds() {\n /**\n * The selector covers following notes\n * - notes and thread below the snippets and commit page\n * - notes on the file of commit page\n * - notes on an image file of commit page\n */\n const notesList = [...document.querySelectorAll('.notes:not(.notes-form) li[id]')];\n return notesList.map((noteItem) => parseInt(noteItem.dataset.noteId, 10));\n }\n\n /**\n * Check if $note already contains the `noteEntity` content\n */\n static isUpdatedNote(noteEntity, $note) {\n // There can be CRLF vs LF mismatches if we don't sanitize and compare the same way\n const sanitizedNoteEntityText = normalizeNewlines(noteEntity.note.trim());\n const currentNoteText = normalizeNewlines(\n $note.find('.original-note-content').first().text().trim(),\n );\n return sanitizedNoteEntityText !== currentNoteText;\n }\n\n static checkMergeRequestStatus() {\n if (getPagePath(1) === 'merge_requests' && gl.mrWidget) {\n gl.mrWidget.checkStatus();\n }\n }\n\n static animateAppendNote(noteHtml, $notesList) {\n const $note = $(noteHtml);\n\n $note.addClass('fade-in-full');\n renderGFM(Notes.getNodeToRender($note));\n if ($notesList.find('.discussion-reply-holder').length) {\n $notesList.children('.timeline-entry').last().after($note);\n } else {\n $notesList.append($note);\n }\n return $note;\n }\n\n static animateUpdateNote(noteHtml, $note) {\n const $updatedNote = $(noteHtml);\n\n $updatedNote.addClass('fade-in');\n renderGFM(Notes.getNodeToRender($updatedNote));\n $note.replaceWith($updatedNote);\n return $updatedNote;\n }\n\n static getNodeToRender($note) {\n for (const $item of $note) {\n if (Notes.isNodeTypeElement($item)) {\n return $item;\n }\n }\n return '';\n }\n\n /**\n * Get data from Form attributes to use for saving/submitting comment.\n */\n getFormData($form) {\n const content = $form.find('.js-note-text').val();\n return {\n // eslint-disable-next-line no-jquery/no-serialize\n formData: $form.serialize(),\n formContent: escape(content),\n formAction: $form.attr('action'),\n formContentOriginal: content,\n };\n }\n\n /**\n * Identify if comment has any quick actions\n */\n hasQuickActions(formContent) {\n return REGEX_QUICK_ACTIONS.test(formContent);\n }\n\n /**\n * Remove quick actions and leave comment with pure message\n */\n stripQuickActions(formContent) {\n return formContent.replace(REGEX_QUICK_ACTIONS, '').trim();\n }\n\n /**\n * Gets appropriate description from quick actions found in provided `formContent`\n */\n getQuickActionDescription(formContent, availableQuickActions = []) {\n let tempFormContent;\n\n // Identify executed quick actions from `formContent`\n const executedCommands = availableQuickActions.filter((command) => {\n const commandRegex = new RegExp(`/${command.name}`);\n return commandRegex.test(formContent);\n });\n\n if (executedCommands && executedCommands.length) {\n if (executedCommands.length > 1) {\n tempFormContent = __('Applying multiple commands');\n } else {\n const commandDescription = executedCommands[0].description.toLowerCase();\n tempFormContent = sprintf(__('Applying command to %{commandDescription}'), {\n commandDescription,\n });\n }\n } else {\n tempFormContent = __('Applying command');\n }\n\n return tempFormContent;\n }\n\n /**\n * Create placeholder note DOM element populated with comment body\n * that we will show while comment is being posted.\n * Once comment is _actually_ posted on server, we will have final element\n * in response that we will show in place of this temporary element.\n */\n createPlaceholderNote({\n formContent,\n uniqueId,\n isDiscussionNote,\n currentUsername,\n currentUserFullname,\n currentUserAvatar,\n }) {\n const discussionClass = isDiscussionNote ? 'discussion' : '';\n const $tempNote = $(\n `<li id=\"${uniqueId}\" class=\"note being-posted fade-in-half timeline-entry\">\n <div class=\"timeline-entry-inner\">\n <div class=\"timeline-icon\">\n <a href=\"/${escape(currentUsername)}\">\n <img class=\"avatar s32\" src=\"${currentUserAvatar}\" />\n </a>\n </div>\n <div class=\"timeline-content ${discussionClass}\">\n <div class=\"note-header\">\n <div class=\"note-header-info\">\n <a href=\"/${escape(currentUsername)}\">\n <span class=\"gl-hidden sm:gl-inline-block gl-font-bold\">${escape(\n currentUsername,\n )}</span>\n <span class=\"note-headline-light\">${escape(currentUsername)}</span>\n </a>\n </div>\n </div>\n <div class=\"note-body\">\n <div class=\"note-text\">\n <p>${formContent}</p>\n </div>\n </div>\n </div>\n </div>\n </li>`,\n );\n\n $tempNote.find('.gl-hidden.sm:gl-inline-block').text(escape(currentUserFullname));\n $tempNote.find('.note-headline-light').text(`@${escape(currentUsername)}`);\n\n return $tempNote;\n }\n\n /**\n * Create Placeholder System Note DOM element populated with quick action description\n */\n createPlaceholderSystemNote({ formContent, uniqueId }) {\n const $tempNote = $(\n `<li id=\"${uniqueId}\" class=\"note system-note timeline-entry being-posted fade-in-half\">\n <div class=\"timeline-entry-inner\">\n <div class=\"timeline-content\">\n <i>${formContent}</i>\n </div>\n </div>\n </li>`,\n );\n\n return $tempNote;\n }\n\n /**\n * This method does following tasks step-by-step whenever a new comment\n * is submitted by user (both main thread comments as well as discussion comments).\n *\n * 1) Get Form metadata\n * 2) Identify comment type; a) Main thread b) Discussion thread c) Discussion resolve\n * 3) Build temporary placeholder element (using `createPlaceholderNote`)\n * 4) Show placeholder note on UI\n * 5) Perform network request to submit the note using `axios.post`\n * a) If request is successfully completed\n * 1. Remove placeholder element\n * 2. Show submitted Note element\n * 3. Perform post-submit errands\n * a. Mark discussion as resolved if comment submission was for resolve.\n * b. Reset comment form to original state.\n * b) If request failed\n * 1. Remove placeholder element\n * 2. Show error alert message about failure\n */\n postComment(e) {\n e.preventDefault();\n\n // Get Form metadata\n const $submitBtn = $(e.target);\n $submitBtn.prop('disabled', true);\n let $form = $submitBtn.parents('form');\n const commentTypeComponent = $form.get(0)?.commentTypeComponent;\n if (commentTypeComponent) commentTypeComponent.disabled = true;\n const $closeBtn = $form.find('.js-note-target-close');\n const isDiscussionNote =\n $submitBtn.parent().find('li.droplab-item-selected').attr('id') === 'discussion';\n const isMainForm = $form.hasClass('js-main-target-form');\n const isDiscussionForm = $form.hasClass('js-discussion-note-form');\n const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');\n const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);\n let noteUniqueId;\n let systemNoteUniqueId;\n let hasQuickActions = false;\n let $notesContainer;\n let tempFormContent;\n\n // Get reference to notes container based on type of comment\n if (isDiscussionForm) {\n $notesContainer = $form.parent('.discussion-notes').find('.notes');\n } else if (isMainForm) {\n $notesContainer = $('ul.main-notes-list');\n }\n\n // If comment is to resolve discussion, disable submit buttons while\n // comment posting is finished.\n if (isDiscussionResolve) {\n $form.find('.js-comment-submit-button').disable();\n }\n\n tempFormContent = formContent;\n if (this.glForm.supportsQuickActions && this.hasQuickActions(formContent)) {\n tempFormContent = this.stripQuickActions(formContent);\n hasQuickActions = true;\n }\n\n // Show placeholder note\n if (tempFormContent) {\n noteUniqueId = uniqueId('tempNote_');\n $notesContainer.append(\n this.createPlaceholderNote({\n formContent: tempFormContent,\n uniqueId: noteUniqueId,\n isDiscussionNote,\n currentUsername: gon.current_username,\n currentUserFullname: gon.current_user_fullname,\n currentUserAvatar: gon.current_user_avatar_url,\n }),\n );\n }\n\n // Show placeholder system note\n if (hasQuickActions) {\n systemNoteUniqueId = uniqueId('tempSystemNote_');\n $notesContainer.append(\n this.createPlaceholderSystemNote({\n formContent: this.getQuickActionDescription(\n formContent,\n AjaxCache.get(gl.GfmAutoComplete.dataSources.commands),\n ),\n uniqueId: systemNoteUniqueId,\n }),\n );\n }\n\n // Clear the form textarea\n if ($notesContainer.length) {\n if (isMainForm) {\n this.resetMainTargetForm(e);\n } else if (isDiscussionForm) {\n this.removeDiscussionNoteForm($form);\n }\n }\n\n $closeBtn.text($closeBtn.data('originalText'));\n\n // Make request to submit comment on server\n return axios\n .post(`${formAction}?html=true`, formData)\n .then((res) => {\n const note = res.data;\n\n $submitBtn.prop('disabled', false);\n if (commentTypeComponent) commentTypeComponent.disabled = false;\n\n // Submission successful! remove placeholder\n $notesContainer.find(`#${noteUniqueId}`).remove();\n\n const $diffFile = $form.closest('.diff-file');\n if ($diffFile.length > 0) {\n const blurEvent = new CustomEvent('blur.imageDiff', {\n detail: e,\n });\n\n $diffFile[0].dispatchEvent(blurEvent);\n }\n\n // Reset cached commands list when command is applied\n if (hasQuickActions) {\n $form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');\n }\n\n // Clear previous form errors\n this.clearAlertWrapper();\n\n // Check if this was discussion comment\n if (isDiscussionForm) {\n // Remove flash-container\n $notesContainer.find('.flash-container').remove();\n\n // If comment intends to resolve discussion, do the same.\n if (isDiscussionResolve) {\n $form\n .attr('data-discussion-id', $submitBtn.data('discussionId'))\n .attr('data-resolve-all', 'true')\n .attr('data-project-path', $submitBtn.data('projectPath'));\n }\n\n // Show final note element on UI\n const isNewDiffComment = $notesContainer.length === 0;\n this.addDiscussionNote($form, note, isNewDiffComment);\n\n if (isNewDiffComment) {\n // Add image badge, avatar badge and toggle discussion badge for new image diffs\n const notePosition = $form.find('#note_position').val();\n if ($diffFile.length > 0 && notePosition.length > 0) {\n const { x, y, width, height } = JSON.parse(notePosition);\n const addBadgeEvent = new CustomEvent('addBadge.imageDiff', {\n detail: {\n x,\n y,\n width,\n height,\n noteId: `note_${note.id}`,\n discussionId: note.discussion_id,\n },\n });\n\n $diffFile[0].dispatchEvent(addBadgeEvent);\n }\n }\n\n // append flash-container to the Notes list\n if ($notesContainer.length) {\n $notesContainer.append('<div class=\"flash-container\" style=\"display: none;\"></div>');\n }\n } else if (isMainForm) {\n // Check if this was main thread comment\n // Show final note element on UI and perform form and action buttons cleanup\n this.addNote($form, note);\n this.reenableTargetFormSubmitButton(e);\n }\n\n if (note.commands_changes) {\n this.handleQuickActions(note);\n }\n\n $form.trigger('ajax:success', [note]);\n })\n .catch((error) => {\n // Submission failed, remove placeholder note and show Flash error message\n $notesContainer.find(`#${noteUniqueId}`).remove();\n $submitBtn.prop('disabled', false);\n if (commentTypeComponent) commentTypeComponent.disabled = false;\n\n const blurEvent = new CustomEvent('blur.imageDiff', {\n detail: e,\n });\n\n const closestDiffFile = $form.closest('.diff-file');\n\n if (closestDiffFile.length) {\n closestDiffFile[0].dispatchEvent(blurEvent);\n }\n\n if (hasQuickActions) {\n $notesContainer.find(`#${systemNoteUniqueId}`).remove();\n }\n\n // Show form again on UI on failure\n if (isDiscussionForm && $notesContainer.length) {\n const replyButton = $notesContainer.parent().find('.js-discussion-reply-button');\n this.replyToDiscussionNote(replyButton[0]);\n $form = $notesContainer.parent().find('form');\n }\n\n $form.find('.js-note-text').val(formContentOriginal);\n this.reenableTargetFormSubmitButton(e);\n this.addNoteError(error, $form);\n });\n }\n\n /**\n * This method does following tasks step-by-step whenever an existing comment\n * is updated by user (both main thread comments as well as discussion comments).\n *\n * 1) Get Form metadata\n * 2) Update note element with new content\n * 3) Perform network request to submit the updated note using `axios.post`\n * a) If request is successfully completed\n * 1. Show submitted Note element\n * b) If request failed\n * 1. Revert Note element to original content\n * 2. Show error Flash message about failure\n */\n updateComment(e) {\n e.preventDefault();\n\n // Get Form metadata\n const $submitBtn = $(e.target);\n const $form = $submitBtn.parents('form');\n const $closeBtn = $form.find('.js-note-target-close');\n const $editingNote = $form.parents('.note.is-editing');\n const $noteBody = $editingNote.find('.js-task-list-container');\n const $noteBodyText = $noteBody.find('.note-text');\n const { formData, formContent, formAction } = this.getFormData($form);\n\n // Cache original comment content\n const cachedNoteBodyText = $noteBodyText.html();\n\n // Show updated comment content temporarily\n $noteBodyText.html(formContent);\n $editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half');\n\n const $timeAgo = $editingNote.find('.note-headline-meta a');\n\n $timeAgo.empty();\n $timeAgo.append(loadingIconForLegacyJS({ inline: true, size: 'sm' }));\n\n // Make request to update comment on server\n axios\n .post(`${formAction}?html=true`, formData)\n .then(({ data }) => {\n // Submission successful! render final note element\n this.updateNote(data, $editingNote);\n })\n .catch((error) => {\n $editingNote.addClass('is-editing fade-in-full').removeClass('being-posted fade-in-half');\n // Submission failed, revert back to original note\n $noteBodyText.html(cachedNoteBodyText);\n $editingNote.find('.gl-spinner').remove();\n\n // Show Flash message about failure\n this.updateNoteError(error, $editingNote);\n });\n\n return $closeBtn.text($closeBtn.data('originalText'));\n }\n\n /**\n * Function to check if node is element to avoid comment and text\n */\n static isNodeTypeElement($node) {\n return $node.nodeType === Node.ELEMENT_NODE;\n }\n}\n","import Notes from './deprecated_notes';\n\nexport default () => {\n const dataEl = document.querySelector('.js-notes-data');\n const { notesUrl, now, diffView, enableGFM } = JSON.parse(dataEl.innerHTML);\n\n // Create a singleton so that we don't need to assign\n // into the window object, we can just access the current isntance with Notes.instance\n Notes.initialize(notesUrl, now, diffView, enableGFM);\n};\n","import { parseBoolean } from '~/lib/utils/common_utils';\nimport AccessorUtilities from './lib/utils/accessor';\n\nexport default class Autosave {\n // eslint-disable-next-line max-params\n constructor(field, key, fallbackKey, lockVersion) {\n this.field = field;\n this.type = this.field.getAttribute('type');\n this.isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();\n this.key = Array.isArray(key) ? `autosave/${key.join('/')}` : `autosave/${key}`;\n this.fallbackKey = fallbackKey;\n this.lockVersionKey = `${this.key}/lockVersion`;\n this.lockVersion = lockVersion;\n this.restore();\n this.saveAction = this.save.bind(this);\n // used by app/assets/javascripts/deprecated_notes.js\n this.field.$autosave = this;\n this.field.addEventListener('input', this.saveAction);\n }\n\n restore() {\n if (!this.isLocalStorageAvailable) return;\n const text = window.localStorage.getItem(this.key);\n const fallbackText = window.localStorage.getItem(this.fallbackKey);\n const newValue = text || fallbackText;\n\n if (newValue == null) return;\n\n let originalValue = this.field.value;\n if (this.type === 'checkbox') {\n originalValue = this.field.checked;\n this.field.checked = parseBoolean(newValue);\n } else {\n this.field.value = newValue;\n }\n\n if (originalValue === newValue) return;\n this.triggerInputEvents();\n }\n\n triggerInputEvents() {\n // trigger events so @input, @change and v-model trigger in Vue components\n const inputEvent = new Event('input', { bubbles: true, cancelable: false });\n const changeEvent = new Event('change', { bubbles: true, cancelable: false });\n this.field.dispatchEvent(inputEvent);\n this.field.dispatchEvent(changeEvent);\n }\n\n getSavedLockVersion() {\n if (!this.isLocalStorageAvailable) return undefined;\n return window.localStorage.getItem(this.lockVersionKey);\n }\n\n save() {\n const value = this.type === 'checkbox' ? this.field.checked : this.field.value;\n\n if (this.isLocalStorageAvailable && value) {\n if (this.fallbackKey) {\n window.localStorage.setItem(this.fallbackKey, value);\n }\n if (this.lockVersion !== undefined) {\n window.localStorage.setItem(this.lockVersionKey, this.lockVersion);\n }\n return window.localStorage.setItem(this.key, value);\n }\n\n return this.reset();\n }\n\n reset() {\n if (!this.isLocalStorageAvailable) return undefined;\n\n window.localStorage.removeItem(this.lockVersionKey);\n window.localStorage.removeItem(this.fallbackKey);\n return window.localStorage.removeItem(this.key);\n }\n\n dispose() {\n delete this.field.$autosave;\n this.field.removeEventListener('input', this.saveAction);\n }\n}\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!./report_abuse_dropdown_item.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!./report_abuse_dropdown_item.vue?vue&type=script&lang=js\"","<script>\nimport { GlDropdownItem } from '@gitlab/ui';\nimport { MountingPortal } from 'portal-vue';\nimport { s__ } from '~/locale';\n\nimport AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue';\n\nexport default {\n name: 'ReportAbuseDropdownItem',\n components: {\n GlDropdownItem,\n MountingPortal,\n AbuseCategorySelector,\n },\n inject: ['reportedUserId', 'reportedFromUrl'],\n i18n: {\n reportAbuse: s__('ReportAbuse|Report abuse'),\n },\n data() {\n return {\n open: false,\n };\n },\n methods: {\n toggleDrawer(open) {\n this.open = open;\n },\n },\n};\n</script>\n<template>\n <span>\n <gl-dropdown-item @click=\"toggleDrawer(true)\">{{ $options.i18n.reportAbuse }}</gl-dropdown-item>\n\n <mounting-portal mount-to=\"#js-report-abuse-drawer\" name=\"abuse-category-selector\" append>\n <abuse-category-selector\n :reported-user-id=\"reportedUserId\"\n :reported-from-url=\"reportedFromUrl\"\n :show-drawer=\"open\"\n @close-drawer=\"toggleDrawer(false)\"\n />\n </mounting-portal>\n </span>\n</template>\n","import { render, staticRenderFns } from \"./report_abuse_dropdown_item.vue?vue&type=template&id=59e7af4a\"\nimport script from \"./report_abuse_dropdown_item.vue?vue&type=script&lang=js\"\nexport * from \"./report_abuse_dropdown_item.vue?vue&type=script&lang=js\"\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 null,\n null\n \n)\n\nexport default component.exports","var render = function render(){var _vm=this,_c=_vm._self._c;return _c('span',[_c('gl-dropdown-item',{on:{\"click\":function($event){return _vm.toggleDrawer(true)}}},[_vm._v(_vm._s(_vm.$options.i18n.reportAbuse))]),_vm._v(\" \"),_c('mounting-portal',{attrs:{\"mount-to\":\"#js-report-abuse-drawer\",\"name\":\"abuse-category-selector\",\"append\":\"\"}},[_c('abuse-category-selector',{attrs:{\"reported-user-id\":_vm.reportedUserId,\"reported-from-url\":_vm.reportedFromUrl,\"show-drawer\":_vm.open},on:{\"close-drawer\":function($event){return _vm.toggleDrawer(false)}}})],1)],1)\n}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import Vue from 'vue';\nimport ReportAbuseDropdownItem from './components/report_abuse_dropdown_item.vue';\n\nexport const initReportAbuse = () => {\n const items = document.querySelectorAll('.js-report-abuse-dropdown-item');\n\n items.forEach((el) => {\n if (!el) return false;\n\n const { reportAbusePath, reportedUserId, reportedFromUrl } = el.dataset;\n\n return new Vue({\n el,\n name: 'ReportAbuseDropdownItemRoot',\n provide: {\n reportAbusePath,\n reportedUserId: parseInt(reportedUserId, 10),\n reportedFromUrl,\n },\n render(createElement) {\n return createElement(ReportAbuseDropdownItem);\n },\n });\n });\n};\n"],"sourceRoot":""}