Show More
@@ -382,6 +382,11 b' def make_map(config):' | |||
|
382 | 382 | controller='files', action='archivefile', |
|
383 | 383 | conditions=dict(function=check_repo)) |
|
384 | 384 | |
|
385 | rmap.connect('files_nodelist_home', | |
|
386 | '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}', | |
|
387 | controller='files', action='nodelist', | |
|
388 | conditions=dict(function=check_repo)) | |
|
389 | ||
|
385 | 390 | rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings', |
|
386 | 391 | controller='settings', action="delete", |
|
387 | 392 | conditions=dict(method=["DELETE"], function=check_repo)) |
@@ -25,12 +25,14 b'' | |||
|
25 | 25 | |
|
26 | 26 | import os |
|
27 | 27 | import logging |
|
28 | import mimetypes | |
|
29 | 28 | import traceback |
|
30 | 29 | |
|
30 | from os.path import join as jn | |
|
31 | ||
|
31 | 32 | from pylons import request, response, session, tmpl_context as c, url |
|
32 | 33 | from pylons.i18n.translation import _ |
|
33 | 34 | from pylons.controllers.util import redirect |
|
35 | from pylons.decorators import jsonify | |
|
34 | 36 | |
|
35 | 37 | from vcs.backends import ARCHIVE_SPECS |
|
36 | 38 | from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \ |
@@ -95,6 +97,26 b' class FilesController(BaseRepoController' | |||
|
95 | 97 | |
|
96 | 98 | return file_node |
|
97 | 99 | |
|
100 | ||
|
101 | def __get_paths(self, changeset, starting_path): | |
|
102 | """recursive walk in root dir and return a set of all path in that dir | |
|
103 | based on repository walk function | |
|
104 | """ | |
|
105 | _files = list() | |
|
106 | _dirs = list() | |
|
107 | ||
|
108 | try: | |
|
109 | tip = changeset | |
|
110 | for topnode, dirs, files in tip.walk(starting_path): | |
|
111 | for f in files: | |
|
112 | _files.append(f.path) | |
|
113 | for d in dirs: | |
|
114 | _dirs.append(d.path) | |
|
115 | except RepositoryError, e: | |
|
116 | log.debug(traceback.format_exc()) | |
|
117 | pass | |
|
118 | return _dirs, _files | |
|
119 | ||
|
98 | 120 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
99 | 121 | 'repository.admin') |
|
100 | 122 | def index(self, repo_name, revision, f_path): |
@@ -413,3 +435,13 b' class FilesController(BaseRepoController' | |||
|
413 | 435 | hist_l.append(tags_group) |
|
414 | 436 | |
|
415 | 437 | return hist_l |
|
438 | ||
|
439 | @jsonify | |
|
440 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
|
441 | 'repository.admin') | |
|
442 | def nodelist(self, repo_name, revision, f_path): | |
|
443 | if request.environ.get('HTTP_X_PARTIAL_XHR'): | |
|
444 | cs = self.__get_cs_or_redirect(revision, repo_name) | |
|
445 | _d, _f = self.__get_paths(cs, f_path) | |
|
446 | return _d + _f | |
|
447 |
@@ -52,7 +52,6 b' a {' | |||
|
52 | 52 | color:#003367; |
|
53 | 53 | text-decoration:none; |
|
54 | 54 | cursor:pointer; |
|
55 | font-weight:700; | |
|
56 | 55 | } |
|
57 | 56 | |
|
58 | 57 | a:hover { |
@@ -1863,7 +1862,7 b' padding:0;' | |||
|
1863 | 1862 | |
|
1864 | 1863 | div.browserblock .browser-header { |
|
1865 | 1864 | background:#FFF; |
|
1866 |
padding:10px 0px |
|
|
1865 | padding:10px 0px 15px 0px; | |
|
1867 | 1866 | width: 100%; |
|
1868 | 1867 | } |
|
1869 | 1868 | div.browserblock .browser-nav { |
@@ -1884,6 +1883,25 b' margin-left:5px;' | |||
|
1884 | 1883 | font-weight:700; |
|
1885 | 1884 | } |
|
1886 | 1885 | |
|
1886 | div.browserblock .browser-search{ | |
|
1887 | clear:both; | |
|
1888 | padding:8px 8px 0px 5px; | |
|
1889 | } | |
|
1890 | ||
|
1891 | div.browserblock .search_activate #filter_activate{ | |
|
1892 | vertical-align: sub; | |
|
1893 | border: 1px solid; | |
|
1894 | padding:2px; | |
|
1895 | border-radius: 4px 4px 4px 4px; | |
|
1896 | background: url("../images/button.png") repeat-x scroll 0 0 #E5E3E3; | |
|
1897 | border-color: #DDDDDD #DDDDDD #C6C6C6 #C6C6C6; | |
|
1898 | color: #515151; | |
|
1899 | } | |
|
1900 | ||
|
1901 | div.browserblock .search_activate a:hover{ | |
|
1902 | text-decoration: none !important; | |
|
1903 | } | |
|
1904 | ||
|
1887 | 1905 | div.browserblock .browser-body { |
|
1888 | 1906 | background:#EEE; |
|
1889 | 1907 | border-top:1px solid #CCC; |
@@ -2719,3 +2737,8 b' margin-top:-4px;' | |||
|
2719 | 2737 | padding-left:3px; |
|
2720 | 2738 | } |
|
2721 | 2739 | |
|
2740 | #node_filter{ | |
|
2741 | border:0px solid #545454; | |
|
2742 | color:#AAAAAA; | |
|
2743 | padding-left:3px; | |
|
2744 | } |
@@ -12,7 +12,7 b'' | |||
|
12 | 12 | <div class="info_box"> |
|
13 | 13 | <span class="rev">${_('view')}@rev</span> |
|
14 | 14 | <a class="rev" href="${c.url_prev}" title="${_('previous revision')}">«</a> |
|
15 |
${h.text('at_rev',value=c.changeset.revision,size= |
|
|
15 | ${h.text('at_rev',value=c.changeset.revision,size=5)} | |
|
16 | 16 | <a class="rev" href="${c.url_next}" title="${_('next revision')}">»</a> |
|
17 | 17 | ## ${h.submit('view',_('view'),class_="ui-button-small")} |
|
18 | 18 | </div> |
@@ -21,7 +21,20 b'' | |||
|
21 | 21 | <div class="browser-branch"> |
|
22 | 22 | ${h.checkbox('stay_at_branch',c.changeset.branch,c.changeset.branch==c.branch)} |
|
23 | 23 | <label>${_('follow current branch')}</label> |
|
24 | </div> | |
|
25 | <div class="browser-search"> | |
|
26 | <div class="search_activate"> | |
|
27 | <a id="filter_activate" href="#">${_('search file list')}</a> | |
|
28 | </div> | |
|
29 | ||
|
30 | ||
|
31 | <div> | |
|
32 | <div id="node_filter_box_loading" style="display:none">${_('Loading file list...')}</div> | |
|
33 | <div id="node_filter_box" style="display:none"> | |
|
34 | ${h.files_breadcrumbs(c.repo_name,c.changeset.raw_id,c.files_list.path)}/<input type="text" value="type to search..." name="filter" size="25" id="node_filter" autocomplete="off"> | |
|
35 | ||
|
24 | 36 |
|
|
37 | ||
|
25 | 38 |
|
|
26 | 39 |
|
|
27 | 40 |
|
@@ -33,7 +46,107 b'' | |||
|
33 | 46 |
|
|
34 | 47 |
|
|
35 | 48 | }) |
|
49 | ||
|
50 | var n_filter = YUD.get('node_filter'); | |
|
51 | var F = YAHOO.namespace('node_filter'); | |
|
52 | ||
|
53 | var url = '${h.url("files_nodelist_home",repo_name="__REPO__",revision="__REVISION__",f_path="__FPATH__")}'; | |
|
54 | var node_url = '${h.url("files_home",repo_name="__REPO__",revision="__REVISION__",f_path="__FPATH__")}'; | |
|
55 | ||
|
56 | url = url.replace('__REPO__','${c.repo_name}'); | |
|
57 | url = url.replace('__REVISION__','${c.changeset.raw_id}'); | |
|
58 | url = url.replace('__FPATH__','${c.files_list.path}'); | |
|
59 | ||
|
60 | node_url = node_url.replace('__REPO__','${c.repo_name}'); | |
|
61 | node_url = node_url.replace('__REVISION__','${c.changeset.raw_id}'); | |
|
62 | ||
|
63 | ||
|
64 | F.filterTimeout = null; | |
|
65 | var nodes = null; | |
|
66 | ||
|
67 | ||
|
68 | F.initFilter = function(){ | |
|
69 | YUD.setStyle('node_filter_box_loading','display',''); | |
|
70 | YUD.setStyle('filter_activate','display','none'); | |
|
71 | YUC.initHeader('X-PARTIAL-XHR',true); | |
|
72 | YUC.asyncRequest('GET',url,{ | |
|
73 | success:function(o){ | |
|
74 | nodes = JSON.parse(o.responseText); | |
|
75 | YUD.setStyle('node_filter_box_loading','display','none'); | |
|
76 | YUD.setStyle('node_filter_box','display',''); | |
|
77 | }, | |
|
78 | failure:function(o){ | |
|
79 | console.log('failed to load'); | |
|
80 | } | |
|
81 | },null); | |
|
82 | } | |
|
83 | ||
|
84 | F.updateFilter = function(e) { | |
|
85 | ||
|
86 | return function(){ | |
|
87 | // Reset timeout | |
|
88 | F.filterTimeout = null; | |
|
89 | var query = e.target.value; | |
|
90 | var match = []; | |
|
91 | var matches = 0; | |
|
92 | var matches_max = 20; | |
|
93 | if (query != ""){ | |
|
94 | for(var i=0;i<nodes.length;i++){ | |
|
95 | var pos = nodes[i].toLowerCase().indexOf(query) | |
|
96 | if(query && pos != -1){ | |
|
97 | ||
|
98 | matches++ | |
|
99 | //show only certain amount to not kill browser | |
|
100 | if (matches > matches_max){ | |
|
101 | break; | |
|
102 | } | |
|
103 | ||
|
104 | var n = nodes[i]; | |
|
105 | var n_hl = n.substring(0,pos) | |
|
106 | +"<b>{0}</b>".format(n.substring(pos,pos+query.length)) | |
|
107 | +n.substring(pos+query.length) | |
|
108 | match.push('<tr><td><a class="browser-file" href="{0}">{1}</a></td><td colspan="5"></td></tr>'.format(node_url.replace('__FPATH__',n),n_hl)); | |
|
109 | } | |
|
110 | if(match.length >= matches_max){ | |
|
111 | match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('search truncated')}")); | |
|
112 | } | |
|
113 | ||
|
114 | } | |
|
115 | } | |
|
116 | ||
|
117 | if(query != ""){ | |
|
118 | YUD.setStyle('tbody','display','none'); | |
|
119 | YUD.setStyle('tbody_filtered','display',''); | |
|
120 | ||
|
121 | if (match.length==0){ | |
|
122 | match.push('<tr><td>{0}</td><td colspan="5"></td></tr>'.format("${_('no matching files')}")); | |
|
123 | } | |
|
124 | ||
|
125 | YUD.get('tbody_filtered').innerHTML = match.join(""); | |
|
126 | } | |
|
127 | else{ | |
|
128 | YUD.setStyle('tbody','display',''); | |
|
129 | YUD.setStyle('tbody_filtered','display','none'); | |
|
130 | } | |
|
131 | ||
|
132 | } | |
|
133 | } | |
|
134 | ||
|
135 | ||
|
136 | YUE.on(YUD.get('filter_activate'),'click',function(){ | |
|
137 | F.initFilter(); | |
|
138 | }) | |
|
139 | YUE.on(n_filter,'click',function(){ | |
|
140 | n_filter.value = ''; | |
|
141 | }); | |
|
142 | YUE.on(n_filter,'keyup',function(e){ | |
|
143 | clearTimeout(F.filterTimeout); | |
|
144 | F.filterTimeout = setTimeout(F.updateFilter(e),600); | |
|
145 | }); | |
|
36 | 146 |
|
|
147 | ||
|
148 | </div> | |
|
149 | </div> | |
|
37 | 150 |
|
|
38 | 151 | </div> |
|
39 | 152 | |
@@ -50,6 +163,7 b'' | |||
|
50 | 163 | </tr> |
|
51 | 164 | </thead> |
|
52 | 165 | |
|
166 | <tbody id="tbody"> | |
|
53 | 167 | %if c.files_list.parent: |
|
54 | 168 | <tr class="parity0"> |
|
55 | 169 | <td> |
@@ -97,6 +211,9 b'' | |||
|
97 | 211 | </td> |
|
98 | 212 | </tr> |
|
99 | 213 | %endfor |
|
214 | </tbody> | |
|
215 | <tbody id="tbody_filtered" style="display:none"> | |
|
216 | </tbody> | |
|
100 | 217 | </table> |
|
101 | 218 | </div> |
|
102 | 219 | </div> No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now