Mercurial > kallithea
changeset 3001:37c7abd34d44 beta
implements #636, lazy loading of history and authors to speed up page responsiveness.
- loading full history is not always needed, and it's very heavy operation. Now this is lazy loaded
when clicking on button
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Tue, 13 Nov 2012 22:26:06 +0100 |
parents | 4034eb731b33 |
children | dec78aee1d53 |
files | rhodecode/config/routing.py rhodecode/controllers/files.py rhodecode/public/js/rhodecode.js rhodecode/templates/base/root.html rhodecode/templates/files/files.html rhodecode/templates/files/files_history_box.html rhodecode/templates/files/files_source.html |
diffstat | 7 files changed, 148 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/config/routing.py Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/config/routing.py Tue Nov 13 22:26:06 2012 +0100 @@ -534,6 +534,11 @@ 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))
--- a/rhodecode/controllers/files.py Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/controllers/files.py Tue Nov 13 22:26:06 2012 +0100 @@ -155,12 +155,16 @@ 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 @@ 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 @@ :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 @@ 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 @@ 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 @@ 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()
--- a/rhodecode/public/js/rhodecode.js Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/public/js/rhodecode.js Tue Nov 13 22:26:06 2012 +0100 @@ -951,54 +951,53 @@ } }; -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'); } } };
--- a/rhodecode/templates/base/root.html Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/templates/base/root.html Tue Nov 13 22:26:06 2012 +0100 @@ -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; </script>
--- a/rhodecode/templates/files/files.html Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/templates/files/files.html Tue Nov 13 22:26:06 2012 +0100 @@ -39,11 +39,13 @@ <script type="text/javascript"> var CACHE = {}; -var CACHE_EXPIRE = 60*1000; //cache for 60s +var CACHE_EXPIRE = 5*60*1000; //cache for 5*60s //used to construct links from the search list var url_base = '${h.url("files_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}'; //send the nodelist request to this url var node_list_url = '${h.url("files_nodelist_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}'; +// send the node history requst to this url +var node_history_url = '${h.url("files_history_home",repo_name=c.repo_name,revision='__REV__',f_path='__FPATH__')}'; var ypjax_links = function(){ YUE.on(YUQ('.ypjax-link'), 'click',function(e){ @@ -76,7 +78,7 @@ // Change our States and save some data for handling events var data = {url:url,title:title, url_base:_url_base, - node_list_url:_node_list_url}; + node_list_url:_node_list_url, rev:rev, f_path:f_path}; History.pushState(data, title, url); //now we're sure that we can do ypjax things @@ -89,8 +91,19 @@ ypjax_links(); tooltip_activate(); fileBrowserListeners(State.url, State.data.node_list_url, State.data.url_base); - YUE.on('hlcode','mouseup',getSelectionLink("${_('Selection link')}")); - + + if(YUD.get('hlcode')){ + YUE.on('hlcode', 'mouseup', getSelectionLink); + } + //console.log(State); + if(YUD.get('load_node_history')){ + //remove all listeners due to problems of history state + YUE.removeListener('load_node_history', 'click'); + YUE.on('load_node_history', 'click', function(e){ + var _url = node_history_url.replace('__REV__',State.data.rev).replace('__FPATH__', State.data.f_path); + ypjax(_url, 'node_history', function(o){}) + }); + } // Inform Google Analytics of the change if ( typeof window.pageTracker !== 'undefined' ) { window.pageTracker._trackPageview(State.url); @@ -133,7 +146,9 @@ url: "${h.url.current()}", data: { node_list_url: node_list_url.replace('__REV__',"${c.changeset.raw_id}").replace('__FPATH__', "${h.safe_unicode(c.file.path)}"), - url_base: url_base.replace('__REV__',"${c.changeset.raw_id}") + url_base: url_base.replace('__REV__',"${c.changeset.raw_id}"), + rev:"${c.changeset.raw_id}", + f_path: "${h.safe_unicode(c.file.path)}" } } fileBrowserListeners(_State.url, _State.data.node_list_url, _State.data.url_base);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/templates/files/files_history_box.html Tue Nov 13 22:26:06 2012 +0100 @@ -0,0 +1,25 @@ +<dl> + <dt class="file_history">${_('History')}</dt> + <dd> + <div> + <div style="float:left"> + ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} + ${h.hidden('diff2',c.file_changeset.raw_id)} + ${h.select('diff1',c.file_changeset.raw_id,c.file_history)} + ${h.submit('diff',_('diff to revision'),class_="ui-btn")} + ${h.submit('show_rev',_('show at revision'),class_="ui-btn")} + ${h.hidden('annotate', c.annotate)} + ${h.end_form()} + </div> + <div class="file_author"> + <div class="item">${h.literal(ungettext(u'%s author',u'%s authors',len(c.authors)) % ('<b>%s</b>' % len(c.authors))) }</div> + %for email, user in c.authors: + <div class="contributor tooltip" style="float:left" title="${h.tooltip(user)}"> + <div class="gravatar" style="margin:1px"><img alt="gravatar" src="${h.gravatar_url(email, 20)}"/> </div> + </div> + %endfor + </div> + </div> + <div style="clear:both"></div> + </dd> +</dl> \ No newline at end of file
--- a/rhodecode/templates/files/files_source.html Sat Nov 10 19:04:23 2012 +0100 +++ b/rhodecode/templates/files/files_source.html Tue Nov 13 22:26:06 2012 +0100 @@ -1,29 +1,13 @@ -<dl> - <dt class="file_history">${_('History')}</dt> - <dd> - <div> - <div style="float:left"> - ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')} - ${h.hidden('diff2',c.file_changeset.raw_id)} - ${h.select('diff1',c.file_changeset.raw_id,c.file_history)} - ${h.submit('diff',_('diff to revision'),class_="ui-btn")} - ${h.submit('show_rev',_('show at revision'),class_="ui-btn")} - ${h.hidden('annotate', c.annotate)} - ${h.end_form()} - </div> - <div class="file_author"> - <div class="item">${h.literal(ungettext(u'%s author',u'%s authors',len(c.authors)) % ('<b>%s</b>' % len(c.authors))) }</div> - %for email, user in c.authors: - <div class="contributor tooltip" style="float:left" title="${h.tooltip(user)}"> - <div class="gravatar" style="margin:1px"><img alt="gravatar" src="${h.gravatar_url(email, 20)}"/> </div> - </div> - %endfor - </div> - </div> - <div style="clear:both"></div> - </dd> +<div id="node_history"> +%if c.load_full_history: + <%include file='files_history_box.html'/> +%else: + <div style="padding-bottom:10px"> + <span id="load_node_history" class="ui-btn">${_('Load file history')}</span> + </div> +%endif +</div> -</dl> <div id="body" class="codeblock"> <div class="code-header"> @@ -113,6 +97,15 @@ } - YUE.on('hlcode','mouseup',getSelectionLink("${_('Selection link')}")) + // select code link event + YUE.on('hlcode', 'mouseup', getSelectionLink); + + //load history of file + YUE.on('load_node_history', 'click', function(e){ + var _url = node_history_url.replace('__REV__','${c.file_changeset.raw_id}').replace('__FPATH__', '${c.f_path}'); + ypjax(_url, 'node_history', function(o){}) + }); + }); + </script>