Skip to content
Snippets Groups Projects
Commit 60ebd101 authored by Douwe Maan's avatar Douwe Maan
Browse files

Use blob viewers for snippets

parent c2059737
No related branches found
No related tags found
No related merge requests found
Showing
with 146 additions and 62 deletions
Loading
Loading
@@ -6,7 +6,7 @@ export default class BlobViewer {
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]');
this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]');
this.$blobContentHolder = $('#blob-content-holder');
this.$fileHolder = $('.file-holder');
 
let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type');
 
Loading
Loading
@@ -82,7 +82,7 @@ export default class BlobViewer {
 
viewer.setAttribute('data-loaded', 'true');
 
this.$blobContentHolder.trigger('highlight:line');
this.$fileHolder.trigger('highlight:line');
 
this.toggleCopyButtonState();
});
Loading
Loading
Loading
Loading
@@ -356,6 +356,10 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'users:show':
new UserCallout();
break;
case 'snippets:show':
new LineHighlighter();
new BlobViewer();
break;
}
switch (path.first()) {
case 'sessions':
Loading
Loading
@@ -434,6 +438,8 @@ const ShortcutsBlob = require('./shortcuts_blob');
shortcut_handler = new ShortcutsNavigation();
if (path[2] === 'show') {
new ZenMode();
new LineHighlighter();
new BlobViewer();
}
break;
case 'labels':
Loading
Loading
Loading
Loading
@@ -57,9 +57,9 @@ require('vendor/jquery.scrollTo');
}
 
LineHighlighter.prototype.bindEvents = function() {
const $blobContentHolder = $('#blob-content-holder');
$blobContentHolder.on('click', 'a[data-line-number]', this.clickHandler);
$blobContentHolder.on('highlight:line', this.highlightHash);
const $fileHolder = $('.file-holder');
$fileHolder.on('click', 'a[data-line-number]', this.clickHandler);
$fileHolder.on('highlight:line', this.highlightHash);
};
 
LineHighlighter.prototype.highlightHash = function() {
Loading
Loading
Loading
Loading
@@ -14,4 +14,8 @@ module RendersBlob
html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_asynchronously: false)
}
end
def override_max_blob_size(blob)
blob.override_max_size! if params[:override_max_size] == 'true'
end
end
Loading
Loading
@@ -35,7 +35,7 @@ class Projects::BlobController < Projects::ApplicationController
end
 
def show
@blob.override_max_size! if params[:override_max_size] == 'true'
override_max_blob_size(@blob)
 
respond_to do |format|
format.html do
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@ class Projects::SnippetsController < Projects::ApplicationController
include ToggleAwardEmoji
include SpammableActions
include SnippetsActions
include RendersBlob
 
before_action :module_enabled
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
Loading
Loading
@@ -55,11 +56,23 @@ class Projects::SnippetsController < Projects::ApplicationController
end
 
def show
@note = @project.notes.new(noteable: @snippet)
@noteable = @snippet
@discussions = @snippet.discussions
@notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
blob = @snippet.blob
override_max_blob_size(blob)
respond_to do |format|
format.html do
@note = @project.notes.new(noteable: @snippet)
@noteable = @snippet
@discussions = @snippet.discussions
@notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
render 'show'
end
format.json do
render_blob_json(blob)
end
end
end
 
def destroy
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@ class SnippetsController < ApplicationController
include SpammableActions
include SnippetsActions
include MarkdownPreview
include RendersBlob
 
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :download]
 
Loading
Loading
@@ -60,6 +61,18 @@ class SnippetsController < ApplicationController
end
 
def show
blob = @snippet.blob
override_max_blob_size(blob)
respond_to do |format|
format.html do
render 'show'
end
format.json do
render_blob_json(blob)
end
end
end
 
def destroy
Loading
Loading
Loading
Loading
@@ -119,7 +119,15 @@ module BlobHelper
end
 
def blob_raw_url
namespace_project_raw_path(@project.namespace, @project, @id)
if @snippet
if @snippet.project_id
raw_namespace_project_snippet_path(@project.namespace, @project, @snippet)
else
raw_snippet_path(@snippet)
end
elsif @blob
namespace_project_raw_path(@project.namespace, @project, @id)
end
end
 
# SVGs can contain malicious JavaScript; only include whitelisted
Loading
Loading
@@ -212,8 +220,8 @@ module BlobHelper
clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: "Copy source to clipboard")
end
 
def open_raw_file_button(path)
link_to icon('file-code-o'), path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw', data: { container: 'body' }
def open_raw_blob_button
link_to icon('file-code-o'), blob_raw_url, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw', data: { container: 'body' }
end
 
def blob_render_error_reason(viewer)
Loading
Loading
class Snippet < ActiveRecord::Base
include Gitlab::VisibilityLevel
include Linguist::BlobHelper
include CacheMarkdownField
include Noteable
include Participable
Loading
Loading
@@ -87,47 +86,26 @@ class Snippet < ActiveRecord::Base
]
end
 
def data
content
def blob
@blob ||= Blob.decorate(SnippetBlob.new(self), nil)
end
 
def hook_attrs
attributes
end
 
def size
0
end
def file_name
super.to_s
end
 
# alias for compatibility with blobs and highlighting
def path
file_name
end
def name
file_name
end
def sanitized_file_name
file_name.gsub(/[^a-zA-Z0-9_\-\.]+/, '')
end
 
def mode
nil
end
def visibility_level_field
:visibility_level
end
 
def no_highlighting?
content.lines.count > 1000
end
def notes_with_associations
notes.includes(:author)
end
Loading
Loading
class SnippetBlob
include Linguist::BlobHelper
attr_reader :snippet
def initialize(snippet)
@snippet = snippet
end
delegate :id, to: :snippet
def name
snippet.file_name
end
alias_method :path, :name
def size
data.bytesize
end
def data
snippet.content
end
def rendered_markup
return unless Gitlab::MarkupHelper.gitlab_markdown?(name)
Banzai.render_field(snippet, :content)
end
def mode
nil
end
def binary?
false
end
def load_all_data!(repository)
# No-op
end
def lfs_pointer?
false
end
def lfs_oid
nil
end
def lfs_size
nil
end
def truncated?
false
end
end
Loading
Loading
@@ -16,7 +16,7 @@
 
.btn-group{ role: "group" }<
= copy_blob_source_button(blob) if !blame && blob.rendered_as_text?(ignore_errors: false)
= open_raw_file_button(namespace_project_raw_path(@project.namespace, @project, @id))
= open_raw_blob_button
= view_on_environment_button(@commit.sha, @path, @environment) if @environment
 
.btn-group{ role: "group" }<
Loading
Loading
- blob = viewer.blob
- rendered_markup = blob.rendered_markup if blob.respond_to?(:rendered_markup)
.file-content.wiki
= markup(blob.name, blob.data)
= markup(blob.name, blob.data, rendered: rendered_markup)
Loading
Loading
@@ -4,7 +4,7 @@
 
.project-snippets
%article.file-holder.snippet-file-content
= render 'shared/snippets/blob', raw_path: raw_namespace_project_snippet_path(@project.namespace, @project, @snippet)
= render 'shared/snippets/blob'
 
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
Loading
Loading
Loading
Loading
@@ -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.no_highlighting?)
= highlight(snippet.file_name, chunk[:data], repository: nil, plain: snippet.blob.no_highlighting?)
- else
.file-content.code
.nothing-here-block Empty file
- blob = @snippet.blob
.js-file-title.file-title-flex-parent
.file-header-content
= blob_icon @snippet.mode, @snippet.path
= blob_icon blob.mode, blob.path
 
%strong.file-title-name
= @snippet.path
= blob.path
 
= copy_file_path_button(@snippet.path)
= copy_file_path_button(blob.path)
%small
= number_to_human_size(blob.raw_size)
 
.file-actions.hidden-xs
= render 'projects/blob/viewer_switcher', blob: blob
.btn-group{ role: "group" }<
= copy_blob_source_button(@snippet)
= open_raw_file_button(raw_path)
= copy_blob_source_button(blob)
= open_raw_blob_button
 
- if defined?(download_path) && download_path
= link_to icon('download'), download_path, class: "btn btn-sm has-tooltip", title: 'Download', data: { container: 'body' }
 
- if @snippet.content.empty?
.file-content.code
.nothing-here-block Empty file
- else
- if markup?(@snippet.file_name)
.file-content.wiki
- if gitlab_markdown?(@snippet.file_name)
= preserve(markdown_field(@snippet, :content))
- else
= markup(@snippet.file_name, @snippet.content)
- else
= render 'shared/file_highlight', blob: @snippet
= render 'projects/blob/content', blob: blob
Loading
Loading
@@ -3,7 +3,7 @@
= render 'shared/snippets/header'
 
%article.file-holder.snippet-file-content
= render 'shared/snippets/blob', raw_path: raw_snippet_path(@snippet), download_path: download_snippet_path(@snippet)
= render 'shared/snippets/blob', download_path: download_snippet_path(@snippet)
 
.row-content-block.top-block.content-component-block
= render 'award_emoji/awards_block', awardable: @snippet, inline: true
Loading
Loading
@@ -11,6 +11,7 @@ Feature: Project Snippets
Then I should see "Snippet one" in snippets
And I should not see "Snippet two" in snippets
 
@javascript
Scenario: I create new project snippet
Given I click link "New snippet"
And I submit new snippet "Snippet three"
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ Feature: Snippets
And I have public "Personal snippet one" snippet
And I have private "Personal snippet private" snippet
 
@javascript
Scenario: I create new snippet
Given I visit new snippet page
And I submit new snippet "Personal snippet three"
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
include SharedProject
include SharedNote
include SharedPaths
include WaitForAjax
 
step 'project "Shop" have "Snippet one" snippet' do
create(:project_snippet,
Loading
Loading
@@ -55,9 +56,10 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
fill_in "project_snippet_title", with: "Snippet three"
fill_in "project_snippet_file_name", with: "my_snippet.rb"
page.within('.file-editor') do
find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three'
find('.ace_editor').native.send_keys 'Content of snippet three'
end
click_button "Create snippet"
wait_for_ajax
end
 
step 'I should see snippet "Snippet three"' do
Loading
Loading
@@ -79,6 +81,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
fill_in "note_note", with: "Good snippet!"
click_button "Comment"
end
wait_for_ajax
end
 
step 'I should see comment "Good snippet!"' do
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps
include SharedPaths
include SharedProject
include SharedSnippet
include WaitForAjax
 
step 'I click link "Personal snippet one"' do
click_link "Personal snippet one"
Loading
Loading
@@ -26,9 +27,10 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps
fill_in "personal_snippet_title", with: "Personal snippet three"
fill_in "personal_snippet_file_name", with: "my_snippet.rb"
page.within('.file-editor') do
find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of snippet three'
find('.ace_editor').native.send_keys 'Content of snippet three'
end
click_button "Create snippet"
wait_for_ajax
end
 
step 'I submit new internal snippet' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment