# encoding: utf-8
#--
# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
# Copyright (C) 2007, 2008 Johan Sørensen
# Copyright (C) 2008 August Lilleaas
# Copyright (C) 2008 David A. Cuadrado
# Copyright (C) 2008 Tor Arne Vestbø
# Copyright (C) 2009 Fabio Akita
# Copyright (C) 2009 Bill Marquette
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#++
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
include TagsHelper
include UsersHelper
include BreadcrumbsHelper
include EventRenderingHelper
GREETINGS = ["Hello", "Hi", "Greetings", "Howdy", "Heya", "G'day"]
def random_greeting
GREETINGS[rand(GREETINGS.length)]
end
def help_box(style = :side, icon = :help, options = {}, &block)
out = %Q{
}
out << capture(&block)
out << "
"
concat(out)
end
def pull_box(title, options = {}, &block)
css_class = options.delete(:class)
out = %Q{
}
out << %Q{
#{title}
} if title
out << %Q{
}
out << capture(&block)
out << "
"
concat(out)
end
def dialog_box(title, options = {}, &block)
css_class = options.delete(:class)
out = %Q{
}
out << %Q{
#{title}
} if title
out << %Q{
}
out << capture(&block)
out << "
"
concat(out)
end
def markdown(text, options = [:smart])
renderer = MarkupRenderer.new(text, :markdown => options)
renderer.to_html
end
def render_markdown(text, *options)
# RDiscount < 1.4 doesn't support the :auto_link, use Rails' instead
auto_link = options.delete(:auto_link)
markdown_options = [:smart] + options
markdownized_text = markdown(text, markdown_options)
if auto_link
markdownized_text = auto_link(markdownized_text, :urls)
end
sanitize(markdownized_text)
end
def feed_icon(url, alt_title = "Atom feed", size = :small)
link_to image_tag("silk/feed.png", :class => "feed_icon"), url,
:alt => alt_title, :title => alt_title
end
def default_css_tag_sizes
%w(tag_size_1 tag_size_2 tag_size_3 tag_size_4)
end
def linked_tag_list_as_sentence(tags)
tags.map do |tag|
link_to(h(tag.name), search_path(:q => "category:#{h(tag.name)}"))
end.to_sentence
end
def build_notice_for(object, options = {})
out = %Q{
If this message persist beyond what's reasonable, feel free to #{link_to("contact us", contact_path)}
}
out << %Q{
}
out
end
def render_if_ready(object, options = {})
if object.respond_to?(:ready?) && object.ready?
yield
else
concat(build_notice_for(object, options))
end
end
def selected_if_current_page(url_options, slack = false)
if slack
if controller.request.request_uri.index(CGI.escapeHTML(url_for(url_options))) == 0
"selected"
end
else
"selected" if current_page?(url_options)
end
end
def submenu_selected_class_if_current?(section)
case section
when :overview
if %w[projects].include?(controller.controller_name )
return "selected"
end
when :repositories
if %w[repositories trees logs commits comitters comments merge_requests
blobs committers].include?(controller.controller_name )
return "selected"
end
when :pages
if %w[pages].include?(controller.controller_name )
return "selected"
end
end
end
def link_to_with_selected(name, options = {}, html_options = nil)
html_options = current_page?(options) ? {:class => "selected"} : nil
link_to(name, options = {}, html_options)
end
def syntax_themes_css
out = []
if @load_syntax_themes
# %w[ active4d all_hallows_eve amy blackboard brilliance_black brilliance_dull
# cobalt dawn eiffel espresso_libre idle iplastic lazy mac_classic
# magicwb_amiga pastels_on_dark slush_poppies spacecadet sunburst
# twilight zenburnesque
# ].each do |syntax|
# out << stylesheet_link_tag("syntax_themes/#{syntax}")
# end
return stylesheet_link_tag("syntax_themes/idle")
end
out.join("\n")
end
def base_url(full_url)
URI.parse(full_url).host
end
def gravatar_url_for(email, options = {})
options.reverse_merge!(:default => "images/default_face.gif")
port_string = [443, 80].include?(request.port) ? "" : ":#{request.port}"
"http://www.gravatar.com/avatar.php?gravatar_id=" +
(email.nil? ? "" : Digest::MD5.hexdigest(email)) + "&default=" +
u("http://#{GitoriousConfig['gitorious_host']}#{port_string}" +
"/#{options.delete(:default)}") +
options.map { |k,v| "&#{k}=#{v}" }.join
end
# For a User object, return either his/her avatar or the gravatar for her email address
# Options
# - Pass on :size for the height+width of the image in pixels
# - Pass on :version for a named version/style of the avatar
def avatar(user, options={})
if user.avatar?
avatar_style = options.delete(:version) || :thumb
image_options = { :alt => 'avatar'}.merge(:width => options[:size], :height => options[:size])
image_tag(user.avatar.url(avatar_style), image_options)
else
gravatar(user.email, options)
end
end
# Returns an avatar from an email address (for instance from a commit) where we don't have an actual User object
def avatar_from_email(email, options={})
return if email.blank?
avatar_style = options.delete(:version) || :thumb
image = User.find_avatar_for_email(email, avatar_style)
if image == :nil
gravatar(email, options)
else
image_options = { :alt => 'avatar'}.merge(:width => options[:size], :height => options[:size])
image_tag(image, image_options)
end
end
def gravatar(email, options = {})
size = options[:size]
image_options = { :alt => "avatar" }
if size
image_options.merge!(:width => size, :height => size)
end
image_tag(gravatar_url_for(email, options), image_options)
end
def gravatar_frame(email, options = {})
extra_css_class = options[:style] ? " gravatar_#{options[:style]}" : ""
%{
#{gravatar(email, options)}
}
end
def flashes
flash.map do |type, content|
content_tag(:div, content_tag(:p, content), :class => "flash_message #{type}")
end.join("\n")
end
def commit_graph_tag(repository, ref = "master")
end
def commit_graph_by_author_tag(repository, ref = "master")
end
def action_and_body_for_event(event)
target = event.target
if target.nil?
return ["", "", ""]
end
# These are defined in event_rendering_helper.rb:
action, body, category = self.send("render_event_#{Action::css_class(event.action)}", event)
body = sanitize(body, :tags => %w[a em i strong b])
[action, body, category]
end
def link_to_remote_if(condition, name, options, html_options = {})
if condition
link_to_remote(name, options, html_options)
else
content_tag(:span, name)
end
end
def sidebar_content?
!@content_for_sidebar.blank?
end
def render_readme(repository)
possibilities = []
repository.git.git.ls_tree({:name_only => true}, "master").each do |line|
possibilities << line[0, line.length-1] if line =~ /README.*/
end
return "" if possibilities.empty?
text = repository.git.git.show({}, "master:#{possibilities.first}")
markdown(text) rescue simple_format(sanitize(text))
end
def render_markdown_help
render :partial => '/site/markdown_help'
end
def file_path(repository, filename, head = "master")
project_repository_blob_path(repository.project, repository, branch_with_tree(head, filename))
end
def link_to_help_toggle(dom_id, style = :image)
if style == :image
link_to_function(image_tag("help_grey.png", {
:alt => t("application_helper.more_info")
}), "$('##{dom_id}').toggle()", :class => "more_info")
else
%Q{(} +
link_to_function("?", "$('##{dom_id}').toggle()", :class => "more_info") +
")"
end
end
FILE_EXTN_MAPPINGS = {
'.cpp' => 'cplusplus-file',
'.c' => 'c-file',
'.h' => 'header-file',
'.java' => 'java-file',
'.sh' => 'exec-file',
'.exe' => 'exec-file',
'.rb' => 'ruby-file',
'.png' => 'image-file',
'.jpg' => 'image-file',
'.gif' => 'image-file',
'jpeg' => 'image-file',
'.zip' => 'compressed-file',
'.gz' => 'compressed-file'}
def class_for_filename(filename)
return FILE_EXTN_MAPPINGS[File.extname(filename)] || 'file'
end
def render_download_links(project, repository, head, options={})
links = []
exceptions = Array(options[:except])
unless exceptions.include?(:source_tree)
links << content_tag(:li, link_to("View source tree for #{desplat_path(head)}",
tree_path(head)), :class => "tree")
end
head = desplat_path(head) if head.is_a?(Array)
if head =~ /^[a-z0-9]{40}$/ # it looks like a SHA1
head = head[0..7]
end
{
'tar.gz' => 'tar',
# 'zip' => 'zip',
}.each do |extension, url_key|
archive_path = self.send("project_repository_archive_#{url_key}_path", project, repository, head)
link_html = link_to("Download #{head} as #{extension}", archive_path,
:onclick => "Gitorious.DownloadChecker.checkURL('#{archive_path}?format=js', 'archive-box-#{head}');return false",
:class => "download-link")
link_callback_box = content_tag(:div, "", :class => "archive-download-box round-5 shadow-2",
:id => "archive-box-#{head}", :style => "display:none;")
links << content_tag(:li, link_html+link_callback_box, :class => extension.split('.').last)
end
if options.delete(:only_list_items)
links.join("\n")
else
css_classes = options[:class] || "meta"
content_tag(:ul, links.join("\n"), :class => "links #{css_classes}")
end
end
def paragraphs_with_more(text, identifier)
return if text.blank?
first, rest = text.split("
", 2)
if rest.blank?
first + ""
else
%Q{#{first}
more…
#{rest}
}
end
end
def markdown_hint
t("views.common.format_using_markdown",
:markdown => %(Markdown))
end
def current_site
@controller.current_site
end
def new_polymorphic_comment_path(parent, comment)
if parent
repo_owner_path(@repository, [@project, @repository, parent, comment])
else
repo_owner_path(@repository, [@project, @repository, comment])
end
end
def force_utf8(str)
if str.respond_to?(:force_encoding)
str.force_encoding("UTF-8")
if str.valid_encoding?
str
else
str.encode("binary", :invalid => :replace, :undef => :replace).encode("utf-8")
end
else
str.mb_chars
end
end
# Creates a CSS styled