提交 d61dab91 编写于 作者: B Bob Van Landuyt

Merge branch '65152-selective-highlight' into 'master'

Support selective highlighting of lines

See merge request gitlab-org/gitlab-ce!31361
......@@ -3,12 +3,13 @@
class BlobPresenter < Gitlab::View::Presenter::Delegated
presents :blob
def highlight(plain: nil)
def highlight(since: nil, to: nil, plain: nil)
load_all_blob_data
Gitlab::Highlight.highlight(
blob.path,
blob.data,
limited_blob_data(since: since, to: to),
since: since,
language: blob.language_from_gitattributes,
plain: plain
)
......@@ -23,4 +24,18 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
def load_all_blob_data
blob.load_all_data! if blob.respond_to?(:load_all_data!)
end
def limited_blob_data(since: nil, to: nil)
return blob.data if since.blank? || to.blank?
limited_blob_lines(since, to).join
end
def limited_blob_lines(since, to)
all_lines[since - 1..to - 1]
end
def all_lines
@all_lines ||= blob.data.lines
end
end
......@@ -21,20 +21,19 @@ module Blobs
load_all_blob_data
@subject = blob
@all_lines = blob.data.lines
super(params)
if full?
self.attributes = { since: 1, to: @all_lines.size, bottom: false, unfold: false, offset: 0, indent: 0 }
self.attributes = { since: 1, to: all_lines.size, bottom: false, unfold: false, offset: 0, indent: 0 }
end
end
# Returns an array of Gitlab::Diff::Line with match line added
def diff_lines
diff_lines = lines.map.with_index do |line, index|
full_line = limited_blob_lines[index].delete("\n")
diff_lines = limited_blob_lines(since, to).map.with_index do |line, index|
full_line = line.delete("\n")
Gitlab::Diff::Line.new(full_line, nil, nil, nil, nil, rich_text: line)
Gitlab::Diff::Line.new(full_line, nil, nil, nil, nil, rich_text: lines[index])
end
add_match_line(diff_lines)
......@@ -43,7 +42,7 @@ module Blobs
end
def lines
@lines ||= limit(highlight.lines).map(&:html_safe)
@lines ||= highlight(since: since, to: to).lines.map(&:html_safe)
end
def match_line_text
......@@ -59,7 +58,7 @@ module Blobs
def add_match_line(diff_lines)
return unless unfold?
if bottom? && to < @all_lines.size
if bottom? && to < all_lines.size
old_pos = to - offset
new_pos = to
elsif since != 1
......@@ -73,15 +72,5 @@ module Blobs
bottom? ? diff_lines.push(match_line) : diff_lines.unshift(match_line)
end
def limited_blob_lines
@limited_blob_lines ||= limit(@all_lines)
end
def limit(lines)
return lines if full?
lines[since - 1..to - 1]
end
end
end
---
title: Support selective highlighting of lines
merge_request: 31361
author:
type: performance
......@@ -6,15 +6,16 @@ module Gitlab
TIMEOUT_FOREGROUND = 3.seconds
MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte
def self.highlight(blob_name, blob_content, language: nil, plain: false)
new(blob_name, blob_content, language: language)
def self.highlight(blob_name, blob_content, since: nil, language: nil, plain: false)
new(blob_name, blob_content, since: since, language: language)
.highlight(blob_content, continue: false, plain: plain)
end
attr_reader :blob_name
def initialize(blob_name, blob_content, language: nil)
def initialize(blob_name, blob_content, since: nil, language: nil)
@formatter = Rouge::Formatters::HTMLGitlab
@since = since
@language = language
@blob_name = blob_name
@blob_content = blob_content
......@@ -53,13 +54,13 @@ module Gitlab
end
def highlight_plain(text)
@formatter.format(Rouge::Lexers::PlainText.lex(text)).html_safe
@formatter.format(Rouge::Lexers::PlainText.lex(text), since: @since).html_safe
end
def highlight_rich(text, continue: true)
tag = lexer.tag
tokens = lexer.lex(text, continue: continue)
Timeout.timeout(timeout_time) { @formatter.format(tokens, tag: tag).html_safe }
Timeout.timeout(timeout_time) { @formatter.format(tokens, tag: tag, since: @since).html_safe }
rescue Timeout::Error => e
Gitlab::Sentry.track_exception(e)
highlight_plain(text)
......
......@@ -8,8 +8,8 @@ module Rouge
# Creates a new <tt>Rouge::Formatter::HTMLGitlab</tt> instance.
#
# [+tag+] The tag (language) of the lexer used to generate the formatted tokens
def initialize(tag: nil)
@line_number = 1
def initialize(tag: nil, since: nil)
@line_number = since || 1
@tag = tag
end
......
......@@ -62,6 +62,14 @@ describe Gitlab::Highlight do
expect(lines[2].text).to eq(' """')
end
context 'since param is present' do
it 'highlights with the LC starting from "since" param' do
lines = described_class.highlight(file_name, content, since: 2).lines
expect(lines[0]).to include('LC2')
end
end
context 'diff highlighting' do
let(:file_name) { 'test.diff' }
let(:content) { "+aaa\n+bbb\n- ccc\n ddd\n"}
......
......@@ -28,24 +28,70 @@ describe BlobPresenter, :seed_helper do
subject { described_class.new(blob) }
it 'returns highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: nil)
expect(Gitlab::Highlight)
.to receive(:highlight)
.with(
'files/ruby/regex.rb',
git_blob.data,
since: nil,
plain: nil,
language: nil
)
subject.highlight
end
it 'returns plain content when :plain is true' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: nil)
expect(Gitlab::Highlight)
.to receive(:highlight)
.with(
'files/ruby/regex.rb',
git_blob.data,
since: nil,
plain: true,
language: nil
)
subject.highlight(plain: true)
end
context '"since" and "to" are present' do
before do
allow(git_blob)
.to receive(:data)
.and_return("line one\nline two\nline 3\nline 4")
end
it 'returns limited highlighted content' do
expect(Gitlab::Highlight)
.to receive(:highlight)
.with(
'files/ruby/regex.rb',
"line two\nline 3\n",
since: 2,
language: nil,
plain: nil
)
subject.highlight(since: 2, to: 3)
end
end
context 'gitlab-language contains a match' do
before do
allow(blob).to receive(:language_from_gitattributes).and_return('ruby')
end
it 'passes language to inner call' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
expect(Gitlab::Highlight)
.to receive(:highlight)
.with(
'files/ruby/regex.rb',
git_blob.data,
since: nil,
plain: nil,
language: 'ruby'
)
subject.highlight
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册