@@ -754,144 +754,148 module ApplicationHelper | |||
|
754 | 754 | # identifier:version:1.0.0 |
|
755 | 755 | # identifier:source:some/file |
|
756 | 756 | def parse_redmine_links(text, default_project, obj, attr, only_path, options) |
|
757 | text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m| | |
|
758 |
leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, |
|
|
759 | link = nil | |
|
760 | project = default_project | |
|
761 | if project_identifier | |
|
762 | project = Project.visible.find_by_identifier(project_identifier) | |
|
763 | end | |
|
764 | if esc.nil? | |
|
765 | if prefix.nil? && sep == 'r' | |
|
766 | if project | |
|
767 | repository = nil | |
|
768 | if repo_identifier | |
|
769 | repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} | |
|
770 | else | |
|
771 | repository = project.repository | |
|
772 | end | |
|
773 | # project.changesets.visible raises an SQL error because of a double join on repositories | |
|
774 | if repository && | |
|
775 | (changeset = Changeset.visible. | |
|
776 | find_by_repository_id_and_revision(repository.id, identifier)) | |
|
777 | link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), | |
|
778 | {:only_path => only_path, :controller => 'repositories', | |
|
779 | :action => 'revision', :id => project, | |
|
780 | :repository_id => repository.identifier_param, | |
|
781 | :rev => changeset.revision}, | |
|
782 | :class => 'changeset', | |
|
783 | :title => truncate_single_line_raw(changeset.comments, 100)) | |
|
784 | end | |
|
785 | end | |
|
786 | elsif sep == '#' | |
|
787 | oid = identifier.to_i | |
|
788 | case prefix | |
|
789 | when nil | |
|
790 | if oid.to_s == identifier && | |
|
791 | issue = Issue.visible.includes(:status).find_by_id(oid) | |
|
792 | anchor = comment_id ? "note-#{comment_id}" : nil | |
|
793 | link = link_to(h("##{oid}#{comment_suffix}"), | |
|
794 | {:only_path => only_path, :controller => 'issues', | |
|
795 | :action => 'show', :id => oid, :anchor => anchor}, | |
|
796 | :class => issue.css_classes, | |
|
797 | :title => "#{issue.subject.truncate(100)} (#{issue.status.name})") | |
|
798 | end | |
|
799 | when 'document' | |
|
800 | if document = Document.visible.find_by_id(oid) | |
|
801 | link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, | |
|
802 | :class => 'document' | |
|
803 | end | |
|
804 | when 'version' | |
|
805 | if version = Version.visible.find_by_id(oid) | |
|
806 | link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, | |
|
807 | :class => 'version' | |
|
808 | end | |
|
809 | when 'message' | |
|
810 | if message = Message.visible.includes(:parent).find_by_id(oid) | |
|
811 | link = link_to_message(message, {:only_path => only_path}, :class => 'message') | |
|
812 | end | |
|
813 | when 'forum' | |
|
814 | if board = Board.visible.find_by_id(oid) | |
|
815 | link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, | |
|
816 | :class => 'board' | |
|
817 | end | |
|
818 | when 'news' | |
|
819 | if news = News.visible.find_by_id(oid) | |
|
820 | link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, | |
|
821 | :class => 'news' | |
|
822 | end | |
|
823 | when 'project' | |
|
824 | if p = Project.visible.find_by_id(oid) | |
|
825 | link = link_to_project(p, {:only_path => only_path}, :class => 'project') | |
|
826 | end | |
|
827 | end | |
|
828 | elsif sep == ':' | |
|
829 | # removes the double quotes if any | |
|
830 | name = identifier.gsub(%r{^"(.*)"$}, "\\1") | |
|
831 | name = CGI.unescapeHTML(name) | |
|
832 | case prefix | |
|
833 | when 'document' | |
|
834 | if project && document = project.documents.visible.find_by_title(name) | |
|
835 | link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, | |
|
836 | :class => 'document' | |
|
837 | end | |
|
838 | when 'version' | |
|
839 | if project && version = project.versions.visible.find_by_name(name) | |
|
840 | link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, | |
|
841 | :class => 'version' | |
|
842 | end | |
|
843 | when 'forum' | |
|
844 | if project && board = project.boards.visible.find_by_name(name) | |
|
845 | link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, | |
|
846 | :class => 'board' | |
|
847 | end | |
|
848 | when 'news' | |
|
849 | if project && news = project.news.visible.find_by_title(name) | |
|
850 | link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, | |
|
851 | :class => 'news' | |
|
852 | end | |
|
853 | when 'commit', 'source', 'export' | |
|
757 | text.gsub!(%r{<a( [^>]+?)?>(.*?)</a>|([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m| | |
|
758 | tag_content, leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $3, $4, $5, $6, $7, $12, $13, $10 || $14 || $20, $16 || $21, $17, $19 | |
|
759 | if tag_content | |
|
760 | $& | |
|
761 | else | |
|
762 | link = nil | |
|
763 | project = default_project | |
|
764 | if project_identifier | |
|
765 | project = Project.visible.find_by_identifier(project_identifier) | |
|
766 | end | |
|
767 | if esc.nil? | |
|
768 | if prefix.nil? && sep == 'r' | |
|
854 | 769 | if project |
|
855 | 770 | repository = nil |
|
856 | if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$} | |
|
857 | repo_prefix, repo_identifier, name = $1, $2, $3 | |
|
771 | if repo_identifier | |
|
858 | 772 | repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} |
|
859 | 773 | else |
|
860 | 774 | repository = project.repository |
|
861 | 775 | end |
|
862 | if prefix == 'commit' | |
|
863 | if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first) | |
|
864 | link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier}, | |
|
865 | :class => 'changeset', | |
|
866 | :title => truncate_single_line_raw(changeset.comments, 100) | |
|
867 | end | |
|
868 | else | |
|
869 | if repository && User.current.allowed_to?(:browse_repository, project) | |
|
870 | name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$} | |
|
871 | path, rev, anchor = $1, $3, $5 | |
|
872 | link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, | |
|
873 | :path => to_path_param(path), | |
|
874 | :rev => rev, | |
|
875 | :anchor => anchor}, | |
|
876 | :class => (prefix == 'export' ? 'source download' : 'source') | |
|
877 | end | |
|
776 | # project.changesets.visible raises an SQL error because of a double join on repositories | |
|
777 | if repository && | |
|
778 | (changeset = Changeset.visible. | |
|
779 | find_by_repository_id_and_revision(repository.id, identifier)) | |
|
780 | link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), | |
|
781 | {:only_path => only_path, :controller => 'repositories', | |
|
782 | :action => 'revision', :id => project, | |
|
783 | :repository_id => repository.identifier_param, | |
|
784 | :rev => changeset.revision}, | |
|
785 | :class => 'changeset', | |
|
786 | :title => truncate_single_line_raw(changeset.comments, 100)) | |
|
878 | 787 | end |
|
879 | repo_prefix = nil | |
|
880 | 788 | end |
|
881 | when 'attachment' | |
|
882 | attachments = options[:attachments] || [] | |
|
883 | attachments += obj.attachments if obj.respond_to?(:attachments) | |
|
884 | if attachments && attachment = Attachment.latest_attach(attachments, name) | |
|
885 | link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') | |
|
789 | elsif sep == '#' | |
|
790 | oid = identifier.to_i | |
|
791 | case prefix | |
|
792 | when nil | |
|
793 | if oid.to_s == identifier && | |
|
794 | issue = Issue.visible.includes(:status).find_by_id(oid) | |
|
795 | anchor = comment_id ? "note-#{comment_id}" : nil | |
|
796 | link = link_to(h("##{oid}#{comment_suffix}"), | |
|
797 | {:only_path => only_path, :controller => 'issues', | |
|
798 | :action => 'show', :id => oid, :anchor => anchor}, | |
|
799 | :class => issue.css_classes, | |
|
800 | :title => "#{issue.subject.truncate(100)} (#{issue.status.name})") | |
|
801 | end | |
|
802 | when 'document' | |
|
803 | if document = Document.visible.find_by_id(oid) | |
|
804 | link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, | |
|
805 | :class => 'document' | |
|
806 | end | |
|
807 | when 'version' | |
|
808 | if version = Version.visible.find_by_id(oid) | |
|
809 | link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, | |
|
810 | :class => 'version' | |
|
811 | end | |
|
812 | when 'message' | |
|
813 | if message = Message.visible.includes(:parent).find_by_id(oid) | |
|
814 | link = link_to_message(message, {:only_path => only_path}, :class => 'message') | |
|
815 | end | |
|
816 | when 'forum' | |
|
817 | if board = Board.visible.find_by_id(oid) | |
|
818 | link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, | |
|
819 | :class => 'board' | |
|
820 | end | |
|
821 | when 'news' | |
|
822 | if news = News.visible.find_by_id(oid) | |
|
823 | link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, | |
|
824 | :class => 'news' | |
|
825 | end | |
|
826 | when 'project' | |
|
827 | if p = Project.visible.find_by_id(oid) | |
|
828 | link = link_to_project(p, {:only_path => only_path}, :class => 'project') | |
|
829 | end | |
|
886 | 830 | end |
|
887 | when 'project' | |
|
888 | if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first | |
|
889 | link = link_to_project(p, {:only_path => only_path}, :class => 'project') | |
|
831 | elsif sep == ':' | |
|
832 | # removes the double quotes if any | |
|
833 | name = identifier.gsub(%r{^"(.*)"$}, "\\1") | |
|
834 | name = CGI.unescapeHTML(name) | |
|
835 | case prefix | |
|
836 | when 'document' | |
|
837 | if project && document = project.documents.visible.find_by_title(name) | |
|
838 | link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, | |
|
839 | :class => 'document' | |
|
840 | end | |
|
841 | when 'version' | |
|
842 | if project && version = project.versions.visible.find_by_name(name) | |
|
843 | link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, | |
|
844 | :class => 'version' | |
|
845 | end | |
|
846 | when 'forum' | |
|
847 | if project && board = project.boards.visible.find_by_name(name) | |
|
848 | link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, | |
|
849 | :class => 'board' | |
|
850 | end | |
|
851 | when 'news' | |
|
852 | if project && news = project.news.visible.find_by_title(name) | |
|
853 | link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, | |
|
854 | :class => 'news' | |
|
855 | end | |
|
856 | when 'commit', 'source', 'export' | |
|
857 | if project | |
|
858 | repository = nil | |
|
859 | if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$} | |
|
860 | repo_prefix, repo_identifier, name = $1, $2, $3 | |
|
861 | repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} | |
|
862 | else | |
|
863 | repository = project.repository | |
|
864 | end | |
|
865 | if prefix == 'commit' | |
|
866 | if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first) | |
|
867 | link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier}, | |
|
868 | :class => 'changeset', | |
|
869 | :title => truncate_single_line_raw(changeset.comments, 100) | |
|
870 | end | |
|
871 | else | |
|
872 | if repository && User.current.allowed_to?(:browse_repository, project) | |
|
873 | name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$} | |
|
874 | path, rev, anchor = $1, $3, $5 | |
|
875 | link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, | |
|
876 | :path => to_path_param(path), | |
|
877 | :rev => rev, | |
|
878 | :anchor => anchor}, | |
|
879 | :class => (prefix == 'export' ? 'source download' : 'source') | |
|
880 | end | |
|
881 | end | |
|
882 | repo_prefix = nil | |
|
883 | end | |
|
884 | when 'attachment' | |
|
885 | attachments = options[:attachments] || [] | |
|
886 | attachments += obj.attachments if obj.respond_to?(:attachments) | |
|
887 | if attachments && attachment = Attachment.latest_attach(attachments, name) | |
|
888 | link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') | |
|
889 | end | |
|
890 | when 'project' | |
|
891 | if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first | |
|
892 | link = link_to_project(p, {:only_path => only_path}, :class => 'project') | |
|
893 | end | |
|
890 | 894 | end |
|
891 | 895 | end |
|
892 | 896 | end |
|
897 | (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) | |
|
893 | 898 | end |
|
894 | (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) | |
|
895 | 899 | end |
|
896 | 900 | end |
|
897 | 901 |
@@ -363,6 +363,12 RAW | |||
|
363 | 363 | to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" } |
|
364 | 364 | end |
|
365 | 365 | |
|
366 | def test_should_not_parse_redmine_links_inside_link | |
|
367 | raw = "r1 should not be parsed in http://example.com/url-r1/" | |
|
368 | assert_match %r{<p><a class="changeset".*>r1</a> should not be parsed in <a class="external" href="http://example.com/url-r1/">http://example.com/url-r1/</a></p>}, | |
|
369 | textilizable(raw, :project => Project.find(1)) | |
|
370 | end | |
|
371 | ||
|
366 | 372 | def test_redmine_links_with_a_different_project_before_current_project |
|
367 | 373 | vp1 = Version.generate!(:project_id => 1, :name => '1.4.4') |
|
368 | 374 | vp3 = Version.generate!(:project_id => 3, :name => '1.4.4') |
General Comments 0
You need to be logged in to leave comments.
Login now