summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/code_block.js24
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue2
-rw-r--r--changelogs/unreleased/dm-copy-suggestion-as-gfm.yml5
-rw-r--r--lib/banzai/filter/suggestion_filter.rb1
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb62
5 files changed, 91 insertions, 3 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/code_block.js b/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
index b9b894b3348..1e0c05eff08 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
@@ -8,6 +8,7 @@ const PLAINTEXT_LANG = 'plaintext';
// - Banzai::Filter::SyntaxHighlightFilter
// - Banzai::Filter::MathFilter
// - Banzai::Filter::MermaidFilter
+// - Banzai::Filter::SuggestionFilter
export default class CodeBlock extends BaseCodeBlock {
get schema() {
return {
@@ -20,7 +21,7 @@ export default class CodeBlock extends BaseCodeBlock {
lang: { default: PLAINTEXT_LANG },
},
parseDOM: [
- // Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter or Banzai::Filter::MermaidFilter
+ // Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter, Banzai::Filter::MermaidFilter, or Banzai::Filter::SuggestionFilter
{
tag: 'pre.code.highlight',
preserveWhitespace: 'full',
@@ -39,7 +40,7 @@ export default class CodeBlock extends BaseCodeBlock {
contentElement: 'annotation[encoding="application/x-tex"]',
attrs: { lang: 'math' },
},
- // Matches HTML generated by Banzai::Filter::MathFilter,
+ // Matches HTML generated by Banzai::Filter::MermaidFilter,
// after being transformed by app/assets/javascripts/behaviors/markdown/render_mermaid.js
{
tag: 'svg.mermaid',
@@ -47,6 +48,25 @@ export default class CodeBlock extends BaseCodeBlock {
contentElement: 'text.source',
attrs: { lang: 'mermaid' },
},
+ // Matches HTML generated by Banzai::Filter::SuggestionFilter,
+ // after being transformed by app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
+ {
+ tag: '.md-suggestion',
+ skip: true,
+ },
+ {
+ tag: '.md-suggestion-header',
+ ignore: true,
+ },
+ {
+ tag: '.md-suggestion-diff',
+ preserveWhitespace: 'full',
+ getContent: (el, schema) =>
+ [...el.querySelectorAll('.line_content.new span')].map(span =>
+ schema.text(span.innerText),
+ ),
+ attrs: { lang: 'suggestion' },
+ },
],
toDOM: node => ['pre', { class: 'code highlight', lang: node.attrs.lang }, ['code', 0]],
};
diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
index b9f884074d0..a351ca62c94 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue
@@ -42,7 +42,7 @@ export default {
</script>
<template>
- <div>
+ <div class="md-suggestion">
<suggestion-diff-header
class="qa-suggestion-diff-header"
:can-apply="suggestion.appliable && suggestion.current_user.can_apply && !disabled"
diff --git a/changelogs/unreleased/dm-copy-suggestion-as-gfm.yml b/changelogs/unreleased/dm-copy-suggestion-as-gfm.yml
new file mode 100644
index 00000000000..96115e6ade1
--- /dev/null
+++ b/changelogs/unreleased/dm-copy-suggestion-as-gfm.yml
@@ -0,0 +1,5 @@
+---
+title: Allow suggestions to be copied and pasted as GFM
+merge_request:
+author:
+type: fixed
diff --git a/lib/banzai/filter/suggestion_filter.rb b/lib/banzai/filter/suggestion_filter.rb
index 307ea449140..9950db373d8 100644
--- a/lib/banzai/filter/suggestion_filter.rb
+++ b/lib/banzai/filter/suggestion_filter.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# Generated HTML is transformed back to GFM by app/assets/javascripts/behaviors/markdown/nodes/code_block.js
module Banzai
module Filter
class SuggestionFilter < HTML::Pipeline::Filter
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index 92dee494b7e..16754035076 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -403,6 +403,68 @@ describe 'Copy as GFM', :js do
end
verify(
+ 'SuggestionFilter: suggestion as converted from GFM to HTML',
+
+ <<~GFM
+ ```suggestion
+ New
+ And newer
+ ```
+ GFM
+ )
+
+ aggregate_failures('SuggestionFilter: suggestion as transformed from HTML to Vue component') do
+ gfm = <<~GFM
+ ```suggestion
+ New
+ And newer
+ ```
+ GFM
+
+ html = <<~HTML
+ <div class="md-suggestion">
+ <div class="md-suggestion-header border-bottom-0 mt-2 qa-suggestion-diff-header">
+ <div class="qa-suggestion-diff-header font-weight-bold">
+ Suggested change
+ <a href="/gitlab/help/user/discussions/index.md#suggest-changes" aria-label="Help" class="js-help-btn">
+ <svg aria-hidden="true" class="s16 ic-question-o link-highlight">
+ <use xlink:href="/gitlab/assets/icons.svg#question-o"></use>
+ </svg>
+ </a>
+ </div>
+ <!---->
+ <button type="button" class="btn qa-apply-btn">Apply suggestion</button>
+ </div>
+ <table class="mb-3 md-suggestion-diff js-syntax-highlight code white">
+ <tbody>
+ <tr class="line_holder old">
+ <td class="diff-line-num old_line qa-old-diff-line-number old">9</td>
+ <td class="diff-line-num new_line old"></td>
+ <td class="line_content old"><span>Old
+ </span></td>
+ </tr>
+ <tr class="line_holder new">
+ <td class="diff-line-num old_line new"></td>
+ <td class="diff-line-num new_line qa-new-diff-line-number new">9</td>
+ <td class="line_content new"><span>New
+ </span></td>
+ </tr>
+ <tr class="line_holder new">
+ <td class="diff-line-num old_line new"></td>
+ <td class="diff-line-num new_line qa-new-diff-line-number new">10</td>
+ <td class="line_content new"><span> And newer
+ </span></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ HTML
+
+ output_gfm = html_to_gfm(html)
+ expect(output_gfm.strip).to eq(gfm.strip)
+ end
+
+ verify(
'SanitizationFilter',
<<~GFM