diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -534,6 +534,11 @@ def make_map(config): controller='files', revision='tip', f_path='', conditions=dict(function=check_repo)) + rmap.connect('files_history_home', + '/{repo_name:.*?}/history/{revision}/{f_path:.*}', + controller='files', action='history', revision='tip', f_path='', + conditions=dict(function=check_repo)) + rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}', controller='files', action='diff', revision='tip', f_path='', conditions=dict(function=check_repo)) diff --git a/rhodecode/controllers/files.py b/rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py +++ b/rhodecode/controllers/files.py @@ -155,12 +155,16 @@ class FilesController(BaseRepoController c.file = c.changeset.get_node(f_path) if c.file.is_file(): - c.file_history, _hist = self._get_node_history(c.changeset, f_path) - c.file_changeset = c.changeset - if _hist: - c.file_changeset = (c.changeset - if c.changeset.revision < _hist[0].revision - else _hist[0]) + c.load_full_history = False + file_last_cs = c.file.last_changeset + c.file_changeset = (c.changeset + if c.changeset.revision < file_last_cs.revision + else file_last_cs) + _hist = [] + c.file_history = [] + if c.load_full_history: + c.file_history, _hist = self._get_node_history(c.changeset, f_path) + c.authors = [] for a in set([x.author for x in _hist]): c.authors.append((h.email(a), h.person(a))) @@ -176,6 +180,23 @@ class FilesController(BaseRepoController return render('files/files.html') + def history(self, repo_name, revision, f_path, annotate=False): + if request.environ.get('HTTP_X_PARTIAL_XHR'): + c.changeset = self.__get_cs_or_redirect(revision, repo_name) + c.f_path = f_path + c.annotate = annotate + c.file = c.changeset.get_node(f_path) + if c.file.is_file(): + file_last_cs = c.file.last_changeset + c.file_changeset = (c.changeset + if c.changeset.revision < file_last_cs.revision + else file_last_cs) + c.file_history, _hist = self._get_node_history(c.changeset, f_path) + c.authors = [] + for a in set([x.author for x in _hist]): + c.authors.append((h.email(a), h.person(a))) + return render('files/files_history_box.html') + @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') @@ -530,6 +551,8 @@ class FilesController(BaseRepoController :param changesets: if passed don't calculate history and take changesets defined in this list """ + import time + s = time.time() # calculate history based on tip tip_cs = c.rhodecode_repo.get_changeset() if changesets is None: @@ -538,7 +561,7 @@ class FilesController(BaseRepoController except (NodeDoesNotExistError, ChangesetError): #this node is not present at tip ! changesets = cs.get_file_history(f_path) - + print time.time()-s hist_l = [] changesets_group = ([], _("Changesets")) @@ -546,10 +569,11 @@ class FilesController(BaseRepoController tags_group = ([], _("Tags")) _hg = cs.repository.alias == 'hg' for chs in changesets: - _branch = '(%s)' % chs.branch if _hg else '' + #_branch = '(%s)' % chs.branch if _hg else '' + _branch = chs.branch n_desc = 'r%s:%s %s' % (chs.revision, chs.short_id, _branch) changesets_group[0].append((chs.raw_id, n_desc,)) - + print time.time()-s hist_l.append(changesets_group) for name, chs in c.rhodecode_repo.branches.items(): @@ -559,7 +583,7 @@ class FilesController(BaseRepoController for name, chs in c.rhodecode_repo.tags.items(): tags_group[0].append((chs, name),) hist_l.append(tags_group) - + print time.time()-s return hist_l, changesets @LoginRequired() diff --git a/rhodecode/public/js/rhodecode.js b/rhodecode/public/js/rhodecode.js --- a/rhodecode/public/js/rhodecode.js +++ b/rhodecode/public/js/rhodecode.js @@ -951,54 +951,53 @@ var getIdentNode = function(n){ } }; -var getSelectionLink = function(selection_link_label) { - return function(){ - //get selection from start/to nodes - if (typeof window.getSelection != "undefined") { - s = window.getSelection(); +var getSelectionLink = function(e) { + + //get selection from start/to nodes + if (typeof window.getSelection != "undefined") { + s = window.getSelection(); - from = getIdentNode(s.anchorNode); - till = getIdentNode(s.focusNode); - - f_int = parseInt(from.id.replace('L','')); - t_int = parseInt(till.id.replace('L','')); - - if (f_int > t_int){ - //highlight from bottom - offset = -35; - ranges = [t_int,f_int]; - + from = getIdentNode(s.anchorNode); + till = getIdentNode(s.focusNode); + + f_int = parseInt(from.id.replace('L','')); + t_int = parseInt(till.id.replace('L','')); + + if (f_int > t_int){ + //highlight from bottom + offset = -35; + ranges = [t_int,f_int]; + + } + else{ + //highligth from top + offset = 35; + ranges = [f_int,t_int]; + } + + if (ranges[0] != ranges[1]){ + if(YUD.get('linktt') == null){ + hl_div = document.createElement('div'); + hl_div.id = 'linktt'; } - else{ - //highligth from top - offset = 35; - ranges = [f_int,t_int]; - } + anchor = '#L'+ranges[0]+'-'+ranges[1]; + hl_div.innerHTML = ''; + l = document.createElement('a'); + l.href = location.href.substring(0,location.href.indexOf('#'))+anchor; + l.innerHTML = _TM['Selection link']; + hl_div.appendChild(l); - if (ranges[0] != ranges[1]){ - if(YUD.get('linktt') == null){ - hl_div = document.createElement('div'); - hl_div.id = 'linktt'; - } - anchor = '#L'+ranges[0]+'-'+ranges[1]; - hl_div.innerHTML = ''; - l = document.createElement('a'); - l.href = location.href.substring(0,location.href.indexOf('#'))+anchor; - l.innerHTML = selection_link_label; - hl_div.appendChild(l); - - YUD.get('body').appendChild(hl_div); - - xy = YUD.getXY(till.id); - - YUD.addClass('linktt','yui-tt'); - YUD.setStyle('linktt','top',xy[1]+offset+'px'); - YUD.setStyle('linktt','left',xy[0]+'px'); - YUD.setStyle('linktt','visibility','visible'); - } - else{ - YUD.setStyle('linktt','visibility','hidden'); - } + YUD.get('body').appendChild(hl_div); + + xy = YUD.getXY(till.id); + + YUD.addClass('linktt','yui-tt'); + YUD.setStyle('linktt','top',xy[1]+offset+'px'); + YUD.setStyle('linktt','left',xy[0]+'px'); + YUD.setStyle('linktt','visibility','visible'); + } + else{ + YUD.setStyle('linktt','visibility','hidden'); } } }; diff --git a/rhodecode/templates/base/root.html b/rhodecode/templates/base/root.html --- a/rhodecode/templates/base/root.html +++ b/rhodecode/templates/base/root.html @@ -50,6 +50,7 @@ 'Open new pull request': "${_('Open new pull request')}", 'Open new pull request for selected changesets': "${_('Open new pull request for selected changesets')}", 'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}", + 'Selection link': "${_('Selection link')}", }; var _TM = TRANSLATION_MAP; diff --git a/rhodecode/templates/files/files.html b/rhodecode/templates/files/files.html --- a/rhodecode/templates/files/files.html +++ b/rhodecode/templates/files/files.html @@ -39,11 +39,13 @@