Commit 697459c1 authored by David O'Regan's avatar David O'Regan

Merge branch '220647-add-prefix-to-CSS-class-of-syntax-highlighting-blocks' into 'master'

Add language- prefix to CSS class of syntax highlighting blocks in markdown

See merge request gitlab-org/gitlab!55076
parents efd68424 23d95f17
---
title: Add language- prefix to CSS class of markdown code blocks
merge_request: 55076
author: Camil Staps
type: fixed
...@@ -39,7 +39,7 @@ module Banzai ...@@ -39,7 +39,7 @@ module Banzai
end end
end end
doc.css('pre.code.math').each do |el| doc.css('pre.code.language-math').each do |el|
el[STYLE_ATTRIBUTE] = 'display' el[STYLE_ATTRIBUTE] = 'display'
el[:class] += " #{TAG_CLASS}" el[:class] += " #{TAG_CLASS}"
end end
......
...@@ -10,7 +10,7 @@ module Banzai ...@@ -10,7 +10,7 @@ module Banzai
def call def call
return doc unless suggestions_filter_enabled? return doc unless suggestions_filter_enabled?
doc.search('pre.suggestion > code').each do |node| doc.search('pre.language-suggestion > code').each do |node|
node.add_class(TAG_CLASS) node.add_class(TAG_CLASS)
end end
......
...@@ -37,7 +37,7 @@ module Banzai ...@@ -37,7 +37,7 @@ module Banzai
begin begin
code = Rouge::Formatters::HTMLGitlab.format(lex(lexer, node.text), tag: language) code = Rouge::Formatters::HTMLGitlab.format(lex(lexer, node.text), tag: language)
css_classes << " #{language}" if language css_classes << " language-#{language}" if language
rescue rescue
# Gracefully handle syntax highlighter bugs/errors to ensure users can # Gracefully handle syntax highlighter bugs/errors to ensure users can
# still access an issue/comment/etc. First, retry with the plain text # still access an issue/comment/etc. First, retry with the plain text
......
...@@ -17,7 +17,7 @@ module Gitlab ...@@ -17,7 +17,7 @@ module Gitlab
no_original_data: true, no_original_data: true,
suggestions_filter_enabled: supports_suggestion) suggestions_filter_enabled: supports_suggestion)
doc = Nokogiri::HTML(html) doc = Nokogiri::HTML(html)
suggestion_nodes = doc.search('pre.suggestion') suggestion_nodes = doc.search('pre.language-suggestion')
return [] if suggestion_nodes.empty? return [] if suggestion_nodes.empty?
......
...@@ -63,8 +63,8 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do ...@@ -63,8 +63,8 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
end end
aggregate_failures 'parses fenced code blocks' do aggregate_failures 'parses fenced code blocks' do
expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.c') expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.language-c')
expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.python') expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.language-python')
end end
aggregate_failures 'parses mermaid code block' do aggregate_failures 'parses mermaid code block' do
......
...@@ -575,7 +575,7 @@ FooBar ...@@ -575,7 +575,7 @@ FooBar
it 'preserves code color scheme' do it 'preserves code color scheme' do
object = create_object("```ruby\ndef test\n 'hello world'\nend\n```") object = create_object("```ruby\ndef test\n 'hello world'\nend\n```")
expected = "<pre class=\"code highlight js-syntax-highlight ruby\">" \ expected = "<pre class=\"code highlight js-syntax-highlight language-ruby\">" \
"<code><span class=\"line\"><span class=\"k\">def</span> <span class=\"nf\">test</span>...</span>\n" \ "<code><span class=\"line\"><span class=\"k\">def</span> <span class=\"nf\">test</span>...</span>\n" \
"</code></pre>" "</code></pre>"
......
...@@ -91,35 +91,35 @@ RSpec.describe Banzai::Filter::MathFilter do ...@@ -91,35 +91,35 @@ RSpec.describe Banzai::Filter::MathFilter do
# Display math # Display math
it 'adds data-math-style display attribute to display math' do it 'adds data-math-style display attribute to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight math" v-pre="true"><code>2+2</code></pre>') doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first pre = doc.xpath('descendant-or-self::pre').first
expect(pre['data-math-style']).to eq 'display' expect(pre['data-math-style']).to eq 'display'
end end
it 'adds js-render-math class to display math' do it 'adds js-render-math class to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight math" v-pre="true"><code>2+2</code></pre>') doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first pre = doc.xpath('descendant-or-self::pre').first
expect(pre[:class]).to include("js-render-math") expect(pre[:class]).to include("js-render-math")
end end
it 'ignores code blocks that are not math' do it 'ignores code blocks that are not math' do
input = '<pre class="code highlight js-syntax-highlight plaintext" v-pre="true"><code>2+2</code></pre>' input = '<pre class="code highlight js-syntax-highlight language-plaintext" v-pre="true"><code>2+2</code></pre>'
doc = filter(input) doc = filter(input)
expect(doc.to_s).to eq input expect(doc.to_s).to eq input
end end
it 'requires the pre to contain both code and math' do it 'requires the pre to contain both code and math' do
input = '<pre class="highlight js-syntax-highlight plaintext math" v-pre="true"><code>2+2</code></pre>' input = '<pre class="highlight js-syntax-highlight language-plaintext language-math" v-pre="true"><code>2+2</code></pre>'
doc = filter(input) doc = filter(input)
expect(doc.to_s).to eq input expect(doc.to_s).to eq input
end end
it 'dollar signs around to display math' do it 'dollar signs around to display math' do
doc = filter('$<pre class="code highlight js-syntax-highlight math" v-pre="true"><code>2+2</code></pre>$') doc = filter('$<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>$')
before = doc.xpath('descendant-or-self::text()[1]').first before = doc.xpath('descendant-or-self::text()[1]').first
after = doc.xpath('descendant-or-self::text()[3]').first after = doc.xpath('descendant-or-self::text()[3]').first
......
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Banzai::Filter::SuggestionFilter do RSpec.describe Banzai::Filter::SuggestionFilter do
include FilterSpecHelper include FilterSpecHelper
let(:input) { %(<pre class="code highlight js-syntax-highlight suggestion"><code>foo\n</code></pre>) } let(:input) { %(<pre class="code highlight js-syntax-highlight language-suggestion"><code>foo\n</code></pre>) }
let(:default_context) do let(:default_context) do
{ suggestions_filter_enabled: true } { suggestions_filter_enabled: true }
end end
...@@ -26,7 +26,7 @@ RSpec.describe Banzai::Filter::SuggestionFilter do ...@@ -26,7 +26,7 @@ RSpec.describe Banzai::Filter::SuggestionFilter do
context 'multi-line suggestions' do context 'multi-line suggestions' do
let(:data_attr) { Banzai::Filter::SyntaxHighlightFilter::LANG_PARAMS_ATTR } let(:data_attr) { Banzai::Filter::SyntaxHighlightFilter::LANG_PARAMS_ATTR }
let(:input) { %(<pre class="code highlight js-syntax-highlight suggestion" #{data_attr}="-3+2"><code>foo\n</code></pre>) } let(:input) { %(<pre class="code highlight js-syntax-highlight language-suggestion" #{data_attr}="-3+2"><code>foo\n</code></pre>) }
it 'element has correct data-lang-params' do it 'element has correct data-lang-params' do
doc = filter(input, default_context) doc = filter(input, default_context)
......
...@@ -20,7 +20,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -20,7 +20,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "highlights as plaintext" do it "highlights as plaintext" do
result = filter('<pre><code>def fun end</code></pre>') result = filter('<pre><code>def fun end</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre>') expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre>')
end end
include_examples "XSS prevention", "" include_examples "XSS prevention", ""
...@@ -38,7 +38,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -38,7 +38,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "highlights as that language" do it "highlights as that language" do
result = filter('<pre><code lang="ruby">def fun end</code></pre>') result = filter('<pre><code lang="ruby">def fun end</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>') expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>')
end end
include_examples "XSS prevention", "ruby" include_examples "XSS prevention", "ruby"
...@@ -48,7 +48,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -48,7 +48,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "highlights as plaintext" do it "highlights as plaintext" do
result = filter('<pre><code lang="gnuplot">This is a test</code></pre>') result = filter('<pre><code lang="gnuplot">This is a test</code></pre>')
expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>') expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>')
end end
include_examples "XSS prevention", "gnuplot" include_examples "XSS prevention", "gnuplot"
...@@ -63,7 +63,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -63,7 +63,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "highlights as plaintext but with the correct language attribute and class" do it "highlights as plaintext but with the correct language attribute and class" do
result = filter(%{<pre><code lang="#{lang}">This is a test</code></pre>}) result = filter(%{<pre><code lang="#{lang}">This is a test</code></pre>})
expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight #{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>}) expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
end end
include_examples "XSS prevention", lang include_examples "XSS prevention", lang
...@@ -75,7 +75,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -75,7 +75,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "includes data-lang-params tag with extra information" do it "includes data-lang-params tag with extra information" do
result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}">This is a test</code></pre>}) result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}">This is a test</code></pre>})
expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight #{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>}) expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
end end
include_examples "XSS prevention", lang include_examples "XSS prevention", lang
...@@ -93,7 +93,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do ...@@ -93,7 +93,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "delimits on the first appearance" do it "delimits on the first appearance" do
result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}#{delimiter}more-things">This is a test</code></pre>}) result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}#{delimiter}more-things">This is a test</code></pre>})
expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight #{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>}) expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
end end
end end
end end
......
...@@ -83,7 +83,7 @@ module Gitlab ...@@ -83,7 +83,7 @@ module Gitlab
}, },
'fenced code with inline script' => { 'fenced code with inline script' => {
input: '```mypre"><script>alert(3)</script>', input: '```mypre"><script>alert(3)</script>',
output: "<div>\n<div>\n<pre class=\"code highlight js-syntax-highlight plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">\"&gt;</span></code></pre>\n</div>\n</div>" output: "<div>\n<div>\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">\"&gt;</span></code></pre>\n</div>\n</div>"
} }
} }
...@@ -353,7 +353,7 @@ module Gitlab ...@@ -353,7 +353,7 @@ module Gitlab
output = <<~HTML output = <<~HTML
<div> <div>
<div> <div>
<pre class="code highlight js-syntax-highlight javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre> <pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre>
</div> </div>
</div> </div>
HTML HTML
...@@ -380,7 +380,7 @@ module Gitlab ...@@ -380,7 +380,7 @@ module Gitlab
<div> <div>
<div>class.cpp</div> <div>class.cpp</div>
<div> <div>
<pre class="code highlight js-syntax-highlight cpp" lang="cpp" v-pre="true"><code><span id="LC1" class="line" lang="cpp"><span class="cp">#include &lt;stdio.h&gt;</span></span> <pre class="code highlight js-syntax-highlight language-cpp" lang="cpp" v-pre="true"><code><span id="LC1" class="line" lang="cpp"><span class="cp">#include &lt;stdio.h&gt;</span></span>
<span id="LC2" class="line" lang="cpp"></span> <span id="LC2" class="line" lang="cpp"></span>
<span id="LC3" class="line" lang="cpp"><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span> <span id="LC3" class="line" lang="cpp"><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC4" class="line" lang="cpp"> <span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"*"</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span></span> <span id="LC4" class="line" lang="cpp"> <span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"*"</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span></span>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment