Allow suggestions to be copied and pasted as GFM

Supports both suggestions transformed from GFM to HTML and from GFM to
HTML to Vue component.
This commit is contained in:
Douwe Maan 2019-01-21 18:26:11 +01:00
parent 25429c6367
commit 43005f2df2
No known key found for this signature in database
GPG Key ID: 5976703F65143D36
5 changed files with 91 additions and 3 deletions

View File

@ -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]],
};

View File

@ -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"

View File

@ -0,0 +1,5 @@
---
title: Allow suggestions to be copied and pasted as GFM
merge_request:
author:
type: fixed

View File

@ -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

View File

@ -402,6 +402,68 @@ describe 'Copy as GFM', :js do
expect(output_gfm.strip).to eq(gfm.strip)
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',