Commit a9cce935 authored by Valeriy Sizov's avatar Valeriy Sizov

Merge pull request #1627 from tsigo/tree_performance

Tree performance improvements
parents 325569ac 332fc328
/**
* Tree slider for code browse
*
*/
var Tree = {
init:
function() {
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live("click", function() {
$("#tree-content-holder").hide("slide", { direction: "left" }, 150)
})
$('.project-refs-form').live({
"ajax:beforeSend": function() {
$("#tree-content-holder").hide("slide", { direction: "left" }, 150);
}
})
$("#tree-slider .tree-item").live('click', function(e){
if(e.target.nodeName != "A") {
link = $(this).find(".tree-item-file-name a");
link.trigger("click");
}
});
$('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live({
"ajax:beforeSend": function() { $('.tree_progress').addClass("loading"); },
"ajax:complete": function() { $('.tree_progress').removeClass("loading"); }
});
}
}
# Code browser tree slider
$ ->
if $('#tree-slider').length > 0
# Show the "Loading commit data" for only the first element
$('span.log_loading:first').removeClass('hide')
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live "click", ->
$("#tree-content-holder").hide("slide", { direction: "left" }, 150)
$('.project-refs-form').live
"ajax:beforeSend": -> $("#tree-content-holder").hide("slide", { direction: "left" }, 150)
# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$("#tree-slider .tree-item").live 'click', (e) ->
$('.tree-item-file-name a', this).trigger('click') if (e.target.nodeName != "A")
# Show/Hide the loading spinner
$('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
"ajax:complete": -> $('.tree_progress').removeClass("loading")
...@@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator ...@@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
#parts = parts[0...-1] if is_blob? #parts = parts[0...-1] if is_blob?
yield(h.link_to("..", "#", remote: :true)) if parts.count > max_links yield(h.link_to("..", "#", remote: true)) if parts.count > max_links
parts.each do |part| parts.each do |part|
part_path = File.join(part_path, part) unless part_path.empty? part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty? part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links next unless parts.last(2).include?(part) if parts.count > max_links
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: :true)) yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true))
end end
end end
end end
......
module TreeHelper module TreeHelper
def tree_icon(content) # Sorts a repository's tree so that folders are before files and renders
if content.is_a?(Grit::Blob) # their corresponding partials
if content.text? #
image_tag "file_txt.png" # contents - A Grit::Tree object for the current tree
elsif content.image? def render_tree(contents)
image_tag "file_img.png" # Render Folders before Files/Submodules
else folders, files = contents.partition { |v| v.kind_of?(Grit::Tree) }
image_tag "file_bin.png"
end tree = ""
# Render folders if we have any
tree += render partial: 'tree/tree_item', collection: folders, locals: {type: 'folder'} if folders.present?
files.each do |f|
if f.respond_to?(:url)
# Object is a Submodule
tree += render partial: 'tree/submodule_item', object: f
else else
image_tag "file_dir.png" # Object is a Blob
tree += render partial: 'tree/tree_item', object: f, locals: {type: 'file'}
end end
end end
def tree_hex_class(content) tree.html_safe
"file_#{hexdigest(content.name)}"
end end
def tree_full_path(content) # Return an image icon depending on the file type
content.name.force_encoding('utf-8') #
if params[:path] # type - String type of the tree item; either 'folder' or 'file'
File.join(params[:path], content.name) def tree_icon(type)
else image = type == 'folder' ? 'file_dir.png' : 'file_txt.png'
content.name image_tag(image, size: '16x16')
end end
def tree_hex_class(content)
"file_#{hexdigest(content.name)}"
end end
# Public: Determines if a given filename is compatible with GitHub::Markup. # Public: Determines if a given filename is compatible with GitHub::Markup.
......
- url = content.url(@ref) rescue nil - url = submodule_item.url(@ref) rescue nil
- name = content.basename - name = submodule_item.basename
- return unless url - return unless url
%tr{ class: "tree-item", url: url } %tr{ class: "tree-item", url: url }
%td.tree-item-file-name %td.tree-item-file-name
= image_tag "submodule.png" = image_tag "submodule.png"
%strong= truncate(name, length: 40) %strong= truncate(name, length: 40)
%td %td
%code= content.id[0..10] %code= submodule_item.id[0..10]
%td %td
= link_to truncate(url, length: 40), url = link_to truncate(url, length: 40), url
...@@ -6,13 +6,14 @@ ...@@ -6,13 +6,14 @@
- tree.breadcrumbs(6) do |link| - tree.breadcrumbs(6) do |link|
\/ \/
%li= link %li= link
.clear .clear
%div.tree_progress %div.tree_progress
%div#tree-content-holder.tree-content-holder %div#tree-content-holder.tree-content-holder
- if tree.is_blob? - if tree.is_blob?
= render partial: "tree/tree_file", locals: { name: tree.name, content: tree.data, file: tree } = render partial: "tree/tree_file", object: tree
- else - else
- contents = tree.contents
%table#tree-slider{class: "table_#{@hex_path} tree-table" } %table#tree-slider{class: "table_#{@hex_path} tree-table" }
%thead %thead
%th Name %th Name
...@@ -22,22 +23,16 @@ ...@@ -22,22 +23,16 @@
= link_to "History", tree.history_path, class: "right" = link_to "History", tree.history_path, class: "right"
- if tree.up_dir? - if tree.up_dir?
%tr{ class: "tree-item", url: tree.up_dir_path } %tr.tree-item
%td.tree-item-file-name %td.tree-item-file-name
= image_tag "file_empty.png" = image_tag "file_empty.png", size: '16x16'
= link_to "..", tree.up_dir_path, remote: :true = link_to "..", tree.up_dir_path, remote: true
%td %td
%td %td
- index = 0 = render_tree(tree.contents)
- contents.select{ |i| i.is_a?(Grit::Tree)}.each do |content|
= render partial: "tree/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Blob)}.each do |content|
= render partial: "tree/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Submodule)}.each do |content|
= render partial: "tree/submodule_item", locals: { content: content, index: (index += 1) }
- if content = contents.select{ |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }.first - if content = tree.contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
.file_holder#README .file_holder#README
.file_title .file_title
%i.icon-file %i.icon-file
......
...@@ -2,32 +2,32 @@ ...@@ -2,32 +2,32 @@
.file_title .file_title
%i.icon-file %i.icon-file
%span.file_name %span.file_name
= name.force_encoding('utf-8') = tree_file.name.force_encoding('utf-8')
%small #{file.mode} %small #{tree_file.mode}
%span.options %span.options
= link_to "raw", project_blob_path(@project, @id), class: "btn very_small", target: "_blank" = link_to "raw", project_blob_path(@project, @id), class: "btn very_small", target: "_blank"
= link_to "history", project_commits_path(@project, @id), class: "btn very_small" = link_to "history", project_commits_path(@project, @id), class: "btn very_small"
= link_to "blame", project_blame_path(@project, @id), class: "btn very_small" = link_to "blame", project_blame_path(@project, @id), class: "btn very_small"
- if file.text? - if tree_file.text?
- if gitlab_markdown?(name) - if gitlab_markdown?(tree_file.name)
.file_content.wiki .file_content.wiki
= preserve do = preserve do
= markdown(file.data) = markdown(tree_file.data)
- elsif markup?(name) - elsif markup?(tree_file.name)
.file_content.wiki .file_content.wiki
= raw GitHub::Markup.render(name, file.data) = raw GitHub::Markup.render(tree_file.name, tree_file.data)
- else - else
.file_content.code .file_content.code
- unless file.empty? - unless tree_file.empty?
%div{class: current_user.dark_scheme ? "black" : "white"} %div{class: current_user.dark_scheme ? "black" : "white"}
= preserve do = preserve do
= raw file.colorize(options: { linenos: 'True'}) = raw tree_file.colorize(options: { linenos: 'True'})
- else - else
%h4.nothing_here_message Empty file %h4.nothing_here_message Empty file
- elsif file.image? - elsif tree_file.image?
.file_content.image_file .file_content.image_file
%img{ src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %img{ src: "data:#{tree_file.mime_type};base64,#{Base64.encode64(tree_file.data)}"}
- else - else
.file_content.blob_file .file_content.blob_file
...@@ -37,4 +37,4 @@ ...@@ -37,4 +37,4 @@
%br %br
= image_tag "download.png", width: 64 = image_tag "download.png", width: 64
%h3 %h3
Download (#{file.mb_size}) Download (#{tree_file.mb_size})
- file = tree_full_path(content) %tr{ class: "tree-item #{tree_hex_class(tree_item)}" }
%tr{ class: "tree-item #{tree_hex_class(content)}", url: project_tree_path(@project, tree_join(@id, file)) }
%td.tree-item-file-name %td.tree-item-file-name
= tree_icon(content) = tree_icon(type)
%strong= link_to truncate(content.name, length: 40), project_tree_path(@project, tree_join(@id || @commit.id, file)), remote: :true %strong= link_to truncate(tree_item.name, length: 40), project_tree_path(@project, tree_join(@id || @commit.id, tree_item.name)), remote: true
%td.tree_time_ago.cgray %td.tree_time_ago.cgray
- if index == 1 %span.log_loading.hide
%span.log_loading Loading commit data...
Loading commit data..
= image_tag "ajax_loader_tree.gif", width: 14 = image_tag "ajax_loader_tree.gif", width: 14
%td.tree_commit %td.tree_commit
= render "head" = render "head"
%div#tree-holder.tree-holder %div#tree-holder.tree-holder
= render "tree", commit: @commit, tree: @tree = render "tree", tree: @tree
:javascript
$(function() {
Tree.init();
});
:plain :plain
// Load Files list // Load Files list
$("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {commit: @commit, tree: @tree}))}"); $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {tree: @tree}))}");
$("#tree-content-holder").show("slide", { direction: "right" }, 150); $("#tree-content-holder").show("slide", { direction: "right" }, 150);
$('.project-refs-form #path').val("#{@path}"); $('.project-refs-form #path').val("#{@path}");
......
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