ui: new file tree switcher

- removed the pjax implementation
- pjax isn't really a better choice here, and removing it simplifies a lot of logic.
This commit is contained in:
Marcin Kuzminski 2019-05-07 13:02:36 +02:00
parent cd670577e5
commit fc24585f04
13 changed files with 74 additions and 106 deletions

View file

@ -225,8 +225,7 @@ class RepoFilesView(RepoAppView):
return branch_name, sha_commit_id, is_head
def _get_tree_at_commit(
self, c, commit_id, f_path, full_load=False):
def _get_tree_at_commit(self, c, commit_id, f_path, full_load=False):
repo_id = self.db_repo.repo_id
force_recache = self.get_recache_flag()
@ -632,8 +631,7 @@ class RepoFilesView(RepoAppView):
c.authors = []
# this loads a simple tree without metadata to speed things up
# later via ajax we call repo_nodetree_full and fetch whole
c.file_tree = self._get_tree_at_commit(
c, c.commit.raw_id, f_path)
c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path)
except RepositoryError as e:
h.flash(safe_str(h.escape(e)), category='error')

View file

@ -367,8 +367,7 @@ class RepoSummaryView(RepoAppView):
})
return result
def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
format_ref_id):
def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id):
result = []
is_svn = h.is_svn(repo)
for ref_name, raw_id in refs.iteritems():
@ -380,6 +379,7 @@ class RepoSummaryView(RepoAppView):
'raw_id': raw_id,
'type': ref_type,
'files_url': files_url,
'idx': 0,
})
return result

View file

@ -217,9 +217,10 @@ class _ToolTip(object):
tooltip = _ToolTip()
def files_breadcrumbs(repo_name, commit_id, file_path):
def files_breadcrumbs(repo_name, commit_id, file_path, at_ref=None):
if isinstance(file_path, str):
file_path = safe_unicode(file_path)
route_qry = {'at': at_ref} if at_ref else None
# TODO: johbo: Is this always a url like path, or is this operating
# system dependent?
@ -236,8 +237,9 @@ def files_breadcrumbs(repo_name, commit_id, file_path):
'repo_files',
repo_name=repo_name,
commit_id=commit_id,
f_path=''),
class_='pjax-link')]
f_path='',
_query=route_qry),
)]
last_cnt = len(path_segments) - 1
for cnt, segment in enumerate(path_segments):
@ -253,8 +255,9 @@ def files_breadcrumbs(repo_name, commit_id, file_path):
'repo_files',
repo_name=repo_name,
commit_id=commit_id,
f_path='/'.join(path_segments[:cnt + 1])),
class_='pjax-link'))
f_path='/'.join(path_segments[:cnt + 1]),
_query=route_qry),
))
else:
url_segments.append(segment_html)

View file

@ -142,7 +142,7 @@ var fileBrowserListeners = function(node_list_url, url_base){
};
var typeIcon = '<i class="{0}"></i>'.format(typeObj[t]);
match.push('<tr class="browser-result"><td><a class="pjax-link" href="{0}">{1}{2}</a></td><td colspan="5"></td></tr>'.format(new_url,typeIcon, n_hl));
match.push('<tr class="browser-result"><td><a class="match-link" href="{0}">{1}{2}</a></td><td colspan="5"></td></tr>'.format(new_url,typeIcon, n_hl));
}
}
if(results.length > limit){
@ -231,8 +231,8 @@ var fileBrowserListeners = function(node_list_url, url_base){
}
if (e.keyCode === 13){ // Enter
if ($('.browser-highlight').length !== 0){
var url = $('.browser-highlight').find('.pjax-link').attr('href');
$.pjax({url: url, container: '#pjax-container', timeout: pjaxTimeout});
var url = $('.browser-highlight').find('.match-link').attr('href');
window.location = url;
}
}
if (e.keyCode === 27){ // Esc

View file

@ -18,7 +18,7 @@
<a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=book))}"><i class="icon-bookmark"></i>${h.shorter(book)}</a>
</span>
<script>
fileTreeRefs["${book}"] = {raw_id: "${commit.raw_id}", type:"book"};
fileTreeRefs["${book}"] = {raw_id: "${commit.raw_id}", type:"book", text: "${book}"};
</script>
%endfor
%endif
@ -28,7 +28,7 @@
<a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=tag))}"><i class="icon-tag"></i>${tag}</a>
</span>
<script>
fileTreeRefs["${tag}"] = {raw_id: "${commit.raw_id}", type:"tag"};
fileTreeRefs["${tag}"] = {raw_id: "${commit.raw_id}", type:"tag", text: "${tag}"};
</script>
%endfor
@ -37,7 +37,7 @@
<a href="${h.route_path('repo_files:default_path',repo_name=c.repo_name,commit_id=commit.raw_id,_query=dict(at=commit.branch))}"><i class="icon-code-fork"></i>${h.shorter(commit.branch)}</a>
</span>
<script>
fileTreeRefs["${commit.branch}"] = {raw_id: "${commit.raw_id}", type:"branch"};
fileTreeRefs["${commit.branch}"] = {raw_id: "${commit.raw_id}", type:"branch", text: "${commit.branch}"};
</script>
%endif

View file

@ -1,9 +1,9 @@
<%inherit file="/base/base.mako"/>
<%def name="title(*args)">
${_('%s Files') % c.repo_name}
${_('{} Files').format(c.repo_name)}
%if hasattr(c,'file'):
&middot; ${h.safe_unicode(c.file.path) or '\\'}
&middot; ${(h.safe_unicode(c.file.path) or '\\')}
%endif
%if c.rhodecode_name:
@ -27,17 +27,16 @@
</%def>
<%def name="main()">
<div id="pjax-container">
<div>
<div id="files_data">
<%include file='files_pjax.mako'/>
</div>
</div>
<script>
var pjaxTimeout = 5000;
var curState = {
commit_id: "${c.commit.raw_id}"
};
var metadataRequest = null;
var fileSourcePage = ${c.file_source_page};
var atRef = '${request.GET.get('at', '')}';
var getState = function(context) {
var url = $(location).attr('href');
@ -65,23 +64,30 @@
var f_path = parts2.join('/');
}
var url_params = {
repo_name: templateContext.repo_name,
commit_id: rev,
f_path:'__FPATH__'
};
if (atRef !== '') {
url_params['at'] = atRef
}
var _url_base = pyroutes.url('repo_files', url_params);
var _node_list_url = pyroutes.url('repo_files_nodelist',
{repo_name: templateContext.repo_name,
commit_id: rev, f_path: f_path});
var _url_base = pyroutes.url('repo_files',
{repo_name: templateContext.repo_name,
commit_id: rev, f_path:'__FPATH__'});
return {
url: url,
f_path: f_path,
rev: rev,
commit_id: curState.commit_id,
commit_id: "${c.commit.raw_id}",
node_list_url: _node_list_url,
url_base: _url_base
};
};
var metadataRequest = null;
var getFilesMetadata = function() {
if (metadataRequest && metadataRequest.readyState != 4) {
metadataRequest.abort();
@ -120,7 +126,6 @@
};
var callbacks = function() {
var state = getState('callbacks');
timeagoActivate();
if ($('#trimmed_message_box').height() < 50) {
@ -132,6 +137,8 @@
$(this).hide();
});
var state = getState('callbacks');
// VIEW FOR FILE SOURCE
if (fileSourcePage) {
// variants for with source code, not tree view
@ -147,6 +154,7 @@
raw_id: null,
files_url: null
};
select2FileHistorySwitcher('#diff1', initialCommitData, state);
// show at, diff to actions handlers
@ -200,7 +208,7 @@
$.pjax({
url: url,
data: 'annotate=${"1" if c.annotate else "0"}',
data: 'annotate=${("1" if c.annotate else "0")}',
container: '#file_authors',
push: false,
timeout: pjaxTimeout
@ -240,9 +248,8 @@
fileBrowserListeners(state.node_list_url, state.url_base);
// switch to widget
console.log(state)
var initialCommitData = {
at_ref: '${request.GET.get('at')}',
at_ref: atRef,
id: null,
text: '${c.commit.raw_id}',
type: 'sha',
@ -251,6 +258,12 @@
files_url: null,
};
// check if we have ref info.
var selectedRef = fileTreeRefs[atRef];
if (selectedRef !== undefined) {
$.extend(initialCommitData, selectedRef)
}
var loadUrl = pyroutes.url('repo_refs_data', {'repo_name': templateContext.repo_name});
var select2RefFileSwitcher = function (targetElement, loadUrl, initialData) {
@ -260,7 +273,6 @@
var formatSelection = function (data, container) {
var commit_ref = data;
console.log(data)
var tmpl = '';
if (commit_ref.type === 'sha') {
@ -319,60 +331,12 @@
$('#refs_filter').on('change', function(e) {
var data = $('#refs_filter').select2('data');
curState.commit_id = data.raw_id;
$.pjax({url: data.files_url, container: '#pjax-container', timeout: pjaxTimeout});
});
$("#prev_commit_link").on('click', function(e) {
var data = $(this).data();
curState.commit_id = data.commitId;
});
$("#next_commit_link").on('click', function(e) {
var data = $(this).data();
curState.commit_id = data.commitId;
window.location = data.files_url
});
}
};
$(document).pjax(".pjax-link", "#pjax-container", {
"fragment": "#pjax-content",
"maxCacheLength": 1000,
"timeout": pjaxTimeout
});
// define global back/forward states
var isPjaxPopState = false;
$(document).on('pjax:popstate', function() {
isPjaxPopState = true;
});
$(document).on('pjax:end', function(xhr, options) {
if (isPjaxPopState) {
isPjaxPopState = false;
callbacks();
_NODEFILTER.resetFilter();
}
// run callback for tracking if defined for google analytics etc.
// this is used to trigger tracking on pjax
if (typeof window.rhodecode_statechange_callback !== 'undefined') {
var state = getState('statechange');
rhodecode_statechange_callback(state.url, null)
}
});
$(document).on('pjax:success', function(event, xhr, options) {
if (event.target.id == "file_history_container") {
$('#file_history_overview').hide();
$('#file_history_overview_full').show();
timeagoActivate();
} else {
callbacks();
}
});
$(document).ready(function() {
callbacks();
var search_GET = "${request.GET.get('search','')}";
@ -383,4 +347,4 @@
</script>
</%def>
</%def>

View file

@ -33,7 +33,7 @@
</div>
<div class="right-content">
<div id="specify-custom-path-container">
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path, request.GET.get('at'))}</span>
<a class="custom-path-link" id="specify-custom-path" href="#">${_('Specify Custom Path')}</a>
</div>
<div id="remove-custom-path-container" style="display: none;">

View file

@ -6,13 +6,13 @@
<div class="info_box">
<div class="info_box_elem previous">
<a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class="pjax-link ${'disabled' if c.url_prev == '#' else ''}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a>
<a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class=" ${'disabled' if c.url_prev == '#' else ''}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a>
</div>
${h.hidden('refs_filter')}
<div class="info_box_elem next">
<a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class="pjax-link ${'disabled' if c.url_next == '#' else ''}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
<a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class=" ${'disabled' if c.url_next == '#' else ''}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a>
</div>
</div>

View file

@ -1,4 +1,10 @@
<div id="file-tree-wrapper" class="browser-body ${'full-load' if c.full_load else ''}">
<%
if request.GET.get('at'):
query={'at': request.GET.get('at')}
else:
query=None
%>
<div id="file-tree-wrapper" class="browser-body ${('full-load' if c.full_load else '')}">
<table class="code-browser rctable repo_summary">
<thead>
<tr>
@ -14,7 +20,7 @@
%if c.file.parent:
<tr class="parity0">
<td class="td-componentname">
<a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.file.parent.path)}" class="pjax-link">
<a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.file.parent.path, _query=query)}">
<i class="icon-directory"></i>..
</a>
</td>
@ -38,8 +44,9 @@
% endif
</span>
% else:
<a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=h.safe_unicode(node.path))}" class="pjax-link">
<i class="${'icon-file-text browser-file' if node.is_file() else 'icon-directory browser-dir'}"></i>${node.name}
<a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=h.safe_unicode(node.path), _query=query)}">
<i class="${('icon-file-text browser-file' if node.is_file() else 'icon-directory browser-dir')}"></i>${node.name}
</a>
% endif
</td>

View file

@ -31,7 +31,7 @@
${_('Path')}:
</div>
<div class="right-content">
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path, request.GET.get('at'))}</span>
</div>
</div>
</div>

View file

@ -32,7 +32,7 @@
</div>
<div class="right-content">
<div id="specify-custom-path-container">
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path)}</span>
<span id="path-breadcrumbs">${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.f_path, request.GET.get('at'))}</span>
</div>
</div>
</div>

View file

@ -9,17 +9,13 @@
%endif
</%def>
<div id="pjax-content" data-title="${self.title()}">
<script>
// set the pageSource variable
var fileSourcePage = ${c.file_source_page};
</script>
<div>
<div class="summary-detail">
<div class="summary-detail-header">
<div class="breadcrumbs files_location">
<h4>
${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path)}
${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'))}
%if c.annotate:
- ${_('annotation')}
%endif

View file

@ -41,19 +41,19 @@ def test_urlify_text(url, expected_url):
@pytest.mark.parametrize('repo_name, commit_id, path, expected_result', [
('rX<X', 'cX<X', 'pX<X/aX<X/bX<X',
'<a class="pjax-link" href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/'
'<a class="pjax-link" href="/rX%3CX/files/cX%3CX/pX%3CX">pX&lt;X</a>/'
'<a class="pjax-link" href="/rX%3CX/files/cX%3CX/pX%3CX/aX%3CX">aX&lt;X'
'<a href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/'
'<a href="/rX%3CX/files/cX%3CX/pX%3CX">pX&lt;X</a>/'
'<a href="/rX%3CX/files/cX%3CX/pX%3CX/aX%3CX">aX&lt;X'
'</a>/bX&lt;X'),
# Path with only one segment
('rX<X', 'cX<X', 'pX<X',
'<a class="pjax-link" href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/pX&lt;X'),
'<a href="/rX%3CX/files/cX%3CX/">rX&lt;X</a>/pX&lt;X'),
# Empty path
('rX<X', 'cX<X', '', 'rX&lt;X'),
('rX"X', 'cX"X', 'pX"X/aX"X/bX"X',
'<a class="pjax-link" href="/rX%22X/files/cX%22X/">rX&#34;X</a>/'
'<a class="pjax-link" href="/rX%22X/files/cX%22X/pX%22X">pX&#34;X</a>/'
'<a class="pjax-link" href="/rX%22X/files/cX%22X/pX%22X/aX%22X">aX&#34;X'
'<a href="/rX%22X/files/cX%22X/">rX&#34;X</a>/'
'<a href="/rX%22X/files/cX%22X/pX%22X">pX&#34;X</a>/'
'<a href="/rX%22X/files/cX%22X/pX%22X/aX%22X">aX&#34;X'
'</a>/bX&#34;X'),
], ids=['simple', 'one_segment', 'empty_path', 'simple_quote'])
def test_files_breadcrumbs_xss(