Commit 6fd216fb authored by Douwe Maan's avatar Douwe Maan
Browse files

Merge branch 'add-language-param-to-highlight' into 'master'

Add language param to highlight

See merge request gitlab-org/gitlab-ce!21584
......@@ -61,7 +61,7 @@ def usage_data
format.html do
usage_data_json = JSON.pretty_generate(Gitlab::UsageData.data)
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json)
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
end
format.json { render json: Gitlab::UsageData.to_json }
end
......
......@@ -92,7 +92,7 @@ def diff
apply_diff_view_cookie!
@blob.load_all_data!
@lines = Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: @repository).lines
@lines = @blob.present.highlight.lines
@form = UnfoldForm.new(params)
......
# frozen_string_literal: true
module BlobHelper
def highlight(blob_name, blob_content, repository: nil, plain: false)
plain ||= blob_content.length > Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE
highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository)
def highlight(file_name, file_content, language: nil, plain: false)
highlighted = Gitlab::Highlight.highlight(file_name, file_content, plain: plain, language: language)
raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
end
......
# frozen_string_literal: true
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob, SnippetBlob and Ci::ArtifactBlob
class Blob < SimpleDelegator
include Presentable
include BlobLanguageFromGitAttributes
CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute
CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour
MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte
# Finding a viewer for a blob happens based only on extension and whether the
# blob is binary or text, which means 1 blob should only be matched by 1 viewer,
# and the order of these viewers doesn't really matter.
......@@ -121,10 +122,6 @@ def load_all_data!
end
end
def no_highlighting?
raw_size && raw_size > MAXIMUM_TEXT_HIGHLIGHT_SIZE
end
def empty?
raw_size == 0
end
......
# frozen_string_literal: true
# Applicable for blob classes with project attribute
module BlobLanguageFromGitAttributes
extend ActiveSupport::Concern
def language_from_gitattributes
return nil unless project
repository = project.repository
repository.gitattribute(path, 'gitlab-language')
end
end
# frozen_string_literal: true
class BlobPresenter < Gitlab::View::Presenter::Simple
presents :blob
def highlight(plain: nil)
blob.load_all_data! if blob.respond_to?(:load_all_data!)
Gitlab::Highlight.highlight(
blob.path,
blob.data,
language: blob.language_from_gitattributes,
plain: plain
)
end
end
......@@ -4,4 +4,6 @@
- blob.data.each_line.each_with_index do |_, index|
%span.diff-line-num= index + 1
.blob-content{ data: { blob_id: blob.id } }
= highlight(blob.path, blob.data, repository: nil, plain: blob.no_highlighting?)
%pre.code.highlight
%code
= blob.present.highlight
= render 'shared/file_highlight', blob: viewer.blob, repository: @repository
= render 'shared/file_highlight', blob: viewer.blob
......@@ -15,14 +15,14 @@
.col-md-2.text-center
Markdown
.col-md-10.code.js-syntax-highlight
= highlight('.md', badge.to_markdown)
= highlight('.md', badge.to_markdown, language: 'markdown')
.row
%hr
.row
.col-md-2.text-center
HTML
.col-md-10.code.js-syntax-highlight
= highlight('.html', badge.to_html)
= highlight('.html', badge.to_html, language: 'html')
.row
%hr
.row
......
......@@ -39,7 +39,7 @@
.blob-content
- snippet_chunks.each do |chunk|
- unless chunk[:data].empty?
= highlight(snippet.file_name, chunk[:data], repository: nil, plain: snippet.blob.no_highlighting?)
= highlight(snippet.file_name, chunk[:data])
- else
.file-content.code
.nothing-here-block Empty file
- repository = nil unless local_assigns.key?(:repository)
.file-content.code.js-syntax-highlight
.line-numbers
- if blob.data.present?
......@@ -13,4 +11,6 @@
= link_icon
= i
.blob-content{ data: { blob_id: blob.id } }
= highlight(blob.path, blob.data, repository: repository, plain: blob.no_highlighting?)
%pre.code.highlight
%code
= blob.present.highlight
......@@ -36,7 +36,7 @@
%li
.code.js-syntax-highlight.sherlock-code
:preserve
#{highlight("#{@query.id}.sql", @query.formatted_query)}
#{highlight("#{@query.id}.sql", @query.formatted_query, language: 'sql')}
.card
.card-header
......
......@@ -17,7 +17,7 @@
= t('sherlock.milliseconds')
%td
.code.js-syntax-highlight.sherlock-code
= highlight("#{query.id}.sql", query.formatted_query)
= highlight("#{query.id}.sql", query.formatted_query, language: 'sql')
%td
= link_to(t('sherlock.view'),
sherlock_transaction_query_path(@transaction, query),
......
......@@ -43,8 +43,7 @@ def blame
def highlighted_lines
@blob.load_all_data!
@highlighted_lines ||=
Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: repository).lines
@highlighted_lines ||= @blob.present.highlight.lines
end
def project
......
......@@ -3,6 +3,7 @@ module Conflict
class File
include Gitlab::Routing
include IconsHelper
include Gitlab::Utils::StrongMemoize
CONTEXT_LINES = 3
......@@ -30,11 +31,8 @@ def resolve_lines(resolution)
end
def highlight_lines!
their_file = lines.reject { |line| line.type == 'new' }.map(&:text).join("\n")
our_file = lines.reject { |line| line.type == 'old' }.map(&:text).join("\n")
their_highlight = Gitlab::Highlight.highlight(their_path, their_file, repository: repository).lines
our_highlight = Gitlab::Highlight.highlight(our_path, our_file, repository: repository).lines
their_highlight = Gitlab::Highlight.highlight(their_path, their_lines, language: their_language).lines
our_highlight = Gitlab::Highlight.highlight(our_path, our_lines, language: our_language).lines
lines.each do |line|
line.rich_text =
......@@ -182,6 +180,34 @@ def map_raw_lines(raw_lines)
raw_line[:line_new], parent_file: self)
end
end
def their_language
strong_memoize(:their_language) do
repository.gitattribute(their_path, 'gitlab-language')
end
end
def our_language
strong_memoize(:our_language) do
if our_path == their_path
their_language
else
repository.gitattribute(our_path, 'gitlab-language')
end
end
end
def their_lines
strong_memoize(:their_lines) do
lines.reject { |line| line.type == 'new' }.map(&:text).join("\n")
end
end
def our_lines
strong_memoize(:our_lines) do
lines.reject { |line| line.type == 'old' }.map(&:text).join("\n")
end
end
end
end
end
......@@ -79,7 +79,7 @@ def highlighted_blob_lines(blob)
return [] unless blob
blob.load_all_data!
Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines
blob.present.highlight.lines
end
end
end
......
......@@ -4,22 +4,25 @@ module Gitlab
class Highlight
TIMEOUT_BACKGROUND = 30.seconds
TIMEOUT_FOREGROUND = 3.seconds
MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte
def self.highlight(blob_name, blob_content, repository: nil, plain: false)
new(blob_name, blob_content, repository: repository)
def self.highlight(blob_name, blob_content, language: nil, plain: false)
new(blob_name, blob_content, language: language)
.highlight(blob_content, continue: false, plain: plain)
end
attr_reader :blob_name
def initialize(blob_name, blob_content, repository: nil)
def initialize(blob_name, blob_content, language: nil)
@formatter = Rouge::Formatters::HTMLGitlab
@repository = repository
@language = language
@blob_name = blob_name
@blob_content = blob_content
end
def highlight(text, continue: true, plain: false)
plain ||= text.length > MAXIMUM_TEXT_HIGHLIGHT_SIZE
highlighted_text = highlight_text(text, continue: continue, plain: plain)
highlighted_text = link_dependencies(text, highlighted_text) if blob_name
highlighted_text
......@@ -36,11 +39,9 @@ def lexer
private
def custom_language
language_name = @repository && @repository.gitattribute(@blob_name, 'gitlab-language')
return nil unless language_name
return nil unless @language
Rouge::Lexer.find_fancy(language_name)
Rouge::Lexer.find_fancy(@language)
end
def highlight_text(text, continue: true, plain: false)
......
......@@ -82,7 +82,7 @@ def self.parse_search_result(result, project = nil)
ref: ref,
startline: startline,
data: data.join,
project_id: project ? project.id : nil
project: project
)
end
......
......@@ -4,8 +4,10 @@ module Gitlab
class SearchResults
class FoundBlob
include EncodingHelper
include Presentable
include BlobLanguageFromGitAttributes
attr_reader :id, :filename, :basename, :ref, :startline, :data, :project_id
attr_reader :id, :filename, :basename, :ref, :startline, :data, :project
def initialize(opts = {})
@id = opts.fetch(:id, nil)
......@@ -15,6 +17,11 @@ def initialize(opts = {})
@startline = opts.fetch(:startline, nil)
@data = encode_utf8(opts.fetch(:data, nil))
@per_page = opts.fetch(:per_page, 20)
@project = opts.fetch(:project, nil)
# Some caller does not have project object (e.g. elastic search),
# yet they can trigger many calls in one go,
# causing duplicated queries.
# Allow those to just pass project_id instead.
@project_id = opts.fetch(:project_id, nil)
end
......@@ -22,8 +29,12 @@ def path
filename
end
def no_highlighting?
false
def project_id
@project_id || @project&.id
end
def present
super(presenter_class: BlobPresenter)
end
end
......
......@@ -2,7 +2,7 @@
describe 'User searches for wiki pages', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) }
let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'test_wiki', content: 'Some Wiki content' }) }
before do
......
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