##// END OF EJS Templates
frontend: prepare for plugin registration and life-cycle handling
ergo -
r373:379025d6 default
parent child Browse files
Show More
@@ -0,0 +1,14 b''
1 <%
2 from pyramid.renderers import render as pyramid_render
3 from pyramid.threadlocal import get_current_registry, get_current_request
4 pyramid_registry = get_current_registry()
5 %>
6 % for plugin, config in pyramid_registry.rhodecode_plugins.items():
7 % if config['template_hooks'].get('plugin_init_template'):
8 ${pyramid_render(config['template_hooks'].get('plugin_init_template'),
9 {'config':config}, request=get_current_request(), package='rc_ae')|n}
10 % endif
11 % endfor
12 <script>
13 $.Topic('/plugins/__REGISTER__').publish({});
14 </script>
@@ -1,65 +1,57 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 def get_plugin_settings(prefix, settings):
22 def get_plugin_settings(prefix, settings):
23 """
23 """
24 Returns plugin settings. Use::
24 Returns plugin settings. Use::
25
25
26
27
28 :param prefix:
26 :param prefix:
29 :param settings:
27 :param settings:
30 :return:
28 :return:
31 """
29 """
32 prefix = prefix + '.' if not prefix.endswith('.') else prefix
30 prefix = prefix + '.' if not prefix.endswith('.') else prefix
33 plugin_settings = {}
31 plugin_settings = {}
34 for k, v in settings.items():
32 for k, v in settings.items():
35 if k.startswith(prefix):
33 if k.startswith(prefix):
36 plugin_settings[k[len(prefix):]] = v
34 plugin_settings[k[len(prefix):]] = v
37
35
38 return plugin_settings
36 return plugin_settings
39
37
40
38
41 def register_rhodecode_plugin(config, plugin_name, plugin_config):
39 def register_rhodecode_plugin(config, plugin_name, plugin_config):
42 def register():
40 def register():
43 if plugin_name not in config.registry.rhodecode_plugins:
41 if plugin_name not in config.registry.rhodecode_plugins:
44 config.registry.rhodecode_plugins[plugin_name] = {
42 config.registry.rhodecode_plugins[plugin_name] = {
45 'javascript': None,
43 'javascript': None,
46 'static': None,
44 'static': None,
47 'css': None,
45 'css': None,
48 'top_nav': None,
46 'nav': None,
49 'fulltext_indexer': None,
47 'fulltext_indexer': None,
50 'sqlalchemy_migrations': None,
48 'sqlalchemy_migrations': None,
51 'default_values_setter': None,
49 'default_values_setter': None,
52 'resource_types': [],
50 'url_gen': None,
53 'url_gen': None
51 'template_hooks': {}
54 }
52 }
55 config.registry.rhodecode_plugins[plugin_name].update(
53 config.registry.rhodecode_plugins[plugin_name].update(
56 plugin_config)
54 plugin_config)
57 # inform RC what kind of resource types we have available
58 # so we can avoid failing when a plugin is removed but data
59 # is still present in the db
60 if plugin_config.get('resource_types'):
61 config.registry.resource_types.extend(
62 plugin_config['resource_types'])
63
55
64 config.action(
56 config.action(
65 'register_rhodecode_plugin={}'.format(plugin_name), register)
57 'register_rhodecode_plugin={}'.format(plugin_name), register)
@@ -1,401 +1,400 b''
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
2 // #
2 // #
3 // # This program is free software: you can redistribute it and/or modify
3 // # This program is free software: you can redistribute it and/or modify
4 // # it under the terms of the GNU Affero General Public License, version 3
4 // # it under the terms of the GNU Affero General Public License, version 3
5 // # (only), as published by the Free Software Foundation.
5 // # (only), as published by the Free Software Foundation.
6 // #
6 // #
7 // # This program is distributed in the hope that it will be useful,
7 // # This program is distributed in the hope that it will be useful,
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // # GNU General Public License for more details.
10 // # GNU General Public License for more details.
11 // #
11 // #
12 // # You should have received a copy of the GNU Affero General Public License
12 // # You should have received a copy of the GNU Affero General Public License
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 // #
14 // #
15 // # This program is dual-licensed. If you wish to learn more about the
15 // # This program is dual-licensed. If you wish to learn more about the
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 /**
19 /**
20 RhodeCode JS Files
20 RhodeCode JS Files
21 **/
21 **/
22
22
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
24 console = { log: function() {} }
24 console = { log: function() {} }
25 }
25 }
26
26
27 // TODO: move the following function to submodules
27 // TODO: move the following function to submodules
28
28
29 /**
29 /**
30 * show more
30 * show more
31 */
31 */
32 var show_more_event = function(){
32 var show_more_event = function(){
33 $('table .show_more').click(function(e) {
33 $('table .show_more').click(function(e) {
34 var cid = e.target.id.substring(1);
34 var cid = e.target.id.substring(1);
35 var button = $(this);
35 var button = $(this);
36 if (button.hasClass('open')) {
36 if (button.hasClass('open')) {
37 $('#'+cid).hide();
37 $('#'+cid).hide();
38 button.removeClass('open');
38 button.removeClass('open');
39 } else {
39 } else {
40 $('#'+cid).show();
40 $('#'+cid).show();
41 button.addClass('open one');
41 button.addClass('open one');
42 }
42 }
43 });
43 });
44 };
44 };
45
45
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
47 $('#compare_action').on('click', function(e){
47 $('#compare_action').on('click', function(e){
48 e.preventDefault();
48 e.preventDefault();
49
49
50 var source = $('input[name=compare_source]:checked').val();
50 var source = $('input[name=compare_source]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
52 if(source && target){
52 if(source && target){
53 var url_data = {
53 var url_data = {
54 repo_name: repo_name,
54 repo_name: repo_name,
55 source_ref: source,
55 source_ref: source,
56 source_ref_type: compare_ref_type,
56 source_ref_type: compare_ref_type,
57 target_ref: target,
57 target_ref: target,
58 target_ref_type: compare_ref_type,
58 target_ref_type: compare_ref_type,
59 merge: 1
59 merge: 1
60 };
60 };
61 window.location = pyroutes.url('compare_url', url_data);
61 window.location = pyroutes.url('compare_url', url_data);
62 }
62 }
63 });
63 });
64 $('.compare-radio-button').on('click', function(e){
64 $('.compare-radio-button').on('click', function(e){
65 var source = $('input[name=compare_source]:checked').val();
65 var source = $('input[name=compare_source]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
67 if(source && target){
67 if(source && target){
68 $('#compare_action').removeAttr("disabled");
68 $('#compare_action').removeAttr("disabled");
69 $('#compare_action').removeClass("disabled");
69 $('#compare_action').removeClass("disabled");
70 }
70 }
71 })
71 })
72 };
72 };
73
73
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
75 var container = $('#' + target);
75 var container = $('#' + target);
76 var url = pyroutes.url('repo_stats',
76 var url = pyroutes.url('repo_stats',
77 {"repo_name": repo_name, "commit_id": commit_id});
77 {"repo_name": repo_name, "commit_id": commit_id});
78
78
79 if (!container.hasClass('loaded')) {
79 if (!container.hasClass('loaded')) {
80 $.ajax({url: url})
80 $.ajax({url: url})
81 .complete(function (data) {
81 .complete(function (data) {
82 var responseJSON = data.responseJSON;
82 var responseJSON = data.responseJSON;
83 container.addClass('loaded');
83 container.addClass('loaded');
84 container.html(responseJSON.size);
84 container.html(responseJSON.size);
85 callback(responseJSON.code_stats)
85 callback(responseJSON.code_stats)
86 })
86 })
87 .fail(function (data) {
87 .fail(function (data) {
88 console.log('failed to load repo stats');
88 console.log('failed to load repo stats');
89 });
89 });
90 }
90 }
91
91
92 };
92 };
93
93
94 var showRepoStats = function(target, data){
94 var showRepoStats = function(target, data){
95 var container = $('#' + target);
95 var container = $('#' + target);
96
96
97 if (container.hasClass('loaded')) {
97 if (container.hasClass('loaded')) {
98 return
98 return
99 }
99 }
100
100
101 var total = 0;
101 var total = 0;
102 var no_data = true;
102 var no_data = true;
103 var tbl = document.createElement('table');
103 var tbl = document.createElement('table');
104 tbl.setAttribute('class', 'trending_language_tbl');
104 tbl.setAttribute('class', 'trending_language_tbl');
105
105
106 $.each(data, function(key, val){
106 $.each(data, function(key, val){
107 total += val.count;
107 total += val.count;
108 });
108 });
109
109
110 var sortedStats = [];
110 var sortedStats = [];
111 for (var obj in data){
111 for (var obj in data){
112 sortedStats.push([obj, data[obj]])
112 sortedStats.push([obj, data[obj]])
113 }
113 }
114 var sortedData = sortedStats.sort(function (a, b) {
114 var sortedData = sortedStats.sort(function (a, b) {
115 return b[1].count - a[1].count
115 return b[1].count - a[1].count
116 });
116 });
117 var cnt = 0;
117 var cnt = 0;
118 $.each(sortedData, function(idx, val){
118 $.each(sortedData, function(idx, val){
119 cnt += 1;
119 cnt += 1;
120 no_data = false;
120 no_data = false;
121
121
122 var hide = cnt > 2;
122 var hide = cnt > 2;
123 var tr = document.createElement('tr');
123 var tr = document.createElement('tr');
124 if (hide) {
124 if (hide) {
125 tr.setAttribute('style', 'display:none');
125 tr.setAttribute('style', 'display:none');
126 tr.setAttribute('class', 'stats_hidden');
126 tr.setAttribute('class', 'stats_hidden');
127 }
127 }
128
128
129 var key = val[0];
129 var key = val[0];
130 var obj = {"desc": val[1].desc, "count": val[1].count};
130 var obj = {"desc": val[1].desc, "count": val[1].count};
131
131
132 var percentage = Math.round((obj.count / total * 100), 2);
132 var percentage = Math.round((obj.count / total * 100), 2);
133
133
134 var td1 = document.createElement('td');
134 var td1 = document.createElement('td');
135 td1.width = 300;
135 td1.width = 300;
136 var trending_language_label = document.createElement('div');
136 var trending_language_label = document.createElement('div');
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
138 td1.appendChild(trending_language_label);
138 td1.appendChild(trending_language_label);
139
139
140 var td2 = document.createElement('td');
140 var td2 = document.createElement('td');
141 var trending_language = document.createElement('div');
141 var trending_language = document.createElement('div');
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
143
143
144 trending_language.title = key + " " + nr_files;
144 trending_language.title = key + " " + nr_files;
145
145
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
148
148
149 trending_language.setAttribute("class", 'trending_language');
149 trending_language.setAttribute("class", 'trending_language');
150 $('b', trending_language)[0].style.width = percentage + "%";
150 $('b', trending_language)[0].style.width = percentage + "%";
151 td2.appendChild(trending_language);
151 td2.appendChild(trending_language);
152
152
153 tr.appendChild(td1);
153 tr.appendChild(td1);
154 tr.appendChild(td2);
154 tr.appendChild(td2);
155 tbl.appendChild(tr);
155 tbl.appendChild(tr);
156 if (cnt == 3) {
156 if (cnt == 3) {
157 var show_more = document.createElement('tr');
157 var show_more = document.createElement('tr');
158 var td = document.createElement('td');
158 var td = document.createElement('td');
159 lnk = document.createElement('a');
159 lnk = document.createElement('a');
160
160
161 lnk.href = '#';
161 lnk.href = '#';
162 lnk.innerHTML = _ngettext('Show more');
162 lnk.innerHTML = _ngettext('Show more');
163 lnk.id = 'code_stats_show_more';
163 lnk.id = 'code_stats_show_more';
164 td.appendChild(lnk);
164 td.appendChild(lnk);
165
165
166 show_more.appendChild(td);
166 show_more.appendChild(td);
167 show_more.appendChild(document.createElement('td'));
167 show_more.appendChild(document.createElement('td'));
168 tbl.appendChild(show_more);
168 tbl.appendChild(show_more);
169 }
169 }
170 });
170 });
171
171
172 $(container).html(tbl);
172 $(container).html(tbl);
173 $(container).addClass('loaded');
173 $(container).addClass('loaded');
174
174
175 $('#code_stats_show_more').on('click', function (e) {
175 $('#code_stats_show_more').on('click', function (e) {
176 e.preventDefault();
176 e.preventDefault();
177 $('.stats_hidden').each(function (idx) {
177 $('.stats_hidden').each(function (idx) {
178 $(this).css("display", "");
178 $(this).css("display", "");
179 });
179 });
180 $('#code_stats_show_more').hide();
180 $('#code_stats_show_more').hide();
181 });
181 });
182
182
183 };
183 };
184
184
185
185
186 // Toggle Collapsable Content
186 // Toggle Collapsable Content
187 function collapsableContent() {
187 function collapsableContent() {
188
188
189 $('.collapsable-content').not('.no-hide').hide();
189 $('.collapsable-content').not('.no-hide').hide();
190
190
191 $('.btn-collapse').unbind(); //in case we've been here before
191 $('.btn-collapse').unbind(); //in case we've been here before
192 $('.btn-collapse').click(function() {
192 $('.btn-collapse').click(function() {
193 var button = $(this);
193 var button = $(this);
194 var togglename = $(this).data("toggle");
194 var togglename = $(this).data("toggle");
195 $('.collapsable-content[data-toggle='+togglename+']').toggle();
195 $('.collapsable-content[data-toggle='+togglename+']').toggle();
196 if ($(this).html()=="Show Less")
196 if ($(this).html()=="Show Less")
197 $(this).html("Show More");
197 $(this).html("Show More");
198 else
198 else
199 $(this).html("Show Less");
199 $(this).html("Show Less");
200 });
200 });
201 };
201 };
202
202
203 var timeagoActivate = function() {
203 var timeagoActivate = function() {
204 $("time.timeago").timeago();
204 $("time.timeago").timeago();
205 };
205 };
206
206
207 // Formatting values in a Select2 dropdown of commit references
207 // Formatting values in a Select2 dropdown of commit references
208 var formatSelect2SelectionRefs = function(commit_ref){
208 var formatSelect2SelectionRefs = function(commit_ref){
209 var tmpl = '';
209 var tmpl = '';
210 if (!commit_ref.text || commit_ref.type === 'sha'){
210 if (!commit_ref.text || commit_ref.type === 'sha'){
211 return commit_ref.text;
211 return commit_ref.text;
212 }
212 }
213 if (commit_ref.type === 'branch'){
213 if (commit_ref.type === 'branch'){
214 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
214 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
215 } else if (commit_ref.type === 'tag'){
215 } else if (commit_ref.type === 'tag'){
216 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
216 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
217 } else if (commit_ref.type === 'book'){
217 } else if (commit_ref.type === 'book'){
218 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
218 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
219 }
219 }
220 return tmpl.concat(commit_ref.text);
220 return tmpl.concat(commit_ref.text);
221 };
221 };
222
222
223 // takes a given html element and scrolls it down offset pixels
223 // takes a given html element and scrolls it down offset pixels
224 function offsetScroll(element, offset){
224 function offsetScroll(element, offset){
225 setTimeout(function(){
225 setTimeout(function(){
226 console.log(element);
226 console.log(element);
227 var location = element.offset().top;
227 var location = element.offset().top;
228 // some browsers use body, some use html
228 // some browsers use body, some use html
229 $('html, body').animate({ scrollTop: (location - offset) });
229 $('html, body').animate({ scrollTop: (location - offset) });
230 }, 100);
230 }, 100);
231 }
231 }
232
232
233 /**
233 /**
234 * global hooks after DOM is loaded
234 * global hooks after DOM is loaded
235 */
235 */
236 $(document).ready(function() {
236 $(document).ready(function() {
237 firefoxAnchorFix();
237 firefoxAnchorFix();
238
238
239 $('.navigation a.menulink').on('click', function(e){
239 $('.navigation a.menulink').on('click', function(e){
240 var menuitem = $(this).parent('li');
240 var menuitem = $(this).parent('li');
241 if (menuitem.hasClass('open')) {
241 if (menuitem.hasClass('open')) {
242 menuitem.removeClass('open');
242 menuitem.removeClass('open');
243 } else {
243 } else {
244 menuitem.addClass('open');
244 menuitem.addClass('open');
245 $(document).on('click', function(event) {
245 $(document).on('click', function(event) {
246 if (!$(event.target).closest(menuitem).length) {
246 if (!$(event.target).closest(menuitem).length) {
247 menuitem.removeClass('open');
247 menuitem.removeClass('open');
248 }
248 }
249 });
249 });
250 }
250 }
251 });
251 });
252 // Add tooltips
252 // Add tooltips
253 $('tr.line .lineno a').attr("title","Click to select line").addClass('tooltip');
253 $('tr.line .lineno a').attr("title","Click to select line").addClass('tooltip');
254 $('tr.line .add-comment-line a').attr("title","Click to comment").addClass('tooltip');
254 $('tr.line .add-comment-line a').attr("title","Click to comment").addClass('tooltip');
255
255
256 // Set colors and styles
256 // Set colors and styles
257 $('tr.line .lineno a').hover(
257 $('tr.line .lineno a').hover(
258 function(){
258 function(){
259 $(this).parents('tr.line').addClass('hover');
259 $(this).parents('tr.line').addClass('hover');
260 }, function(){
260 }, function(){
261 $(this).parents('tr.line').removeClass('hover');
261 $(this).parents('tr.line').removeClass('hover');
262 }
262 }
263 );
263 );
264
264
265 $('tr.line .lineno a').click(
265 $('tr.line .lineno a').click(
266 function(){
266 function(){
267 if ($(this).text() != ""){
267 if ($(this).text() != ""){
268 $('tr.line').removeClass('selected');
268 $('tr.line').removeClass('selected');
269 $(this).parents("tr.line").addClass('selected');
269 $(this).parents("tr.line").addClass('selected');
270
270
271 // Replace URL without jumping to it if browser supports.
271 // Replace URL without jumping to it if browser supports.
272 // Default otherwise
272 // Default otherwise
273 if (history.pushState) {
273 if (history.pushState) {
274 var new_location = location.href
274 var new_location = location.href
275 if (location.hash){
275 if (location.hash){
276 new_location = new_location.replace(location.hash, "");
276 new_location = new_location.replace(location.hash, "");
277 }
277 }
278
278
279 // Make new anchor url
279 // Make new anchor url
280 var new_location = new_location+$(this).attr('href');
280 var new_location = new_location+$(this).attr('href');
281 history.pushState(true, document.title, new_location);
281 history.pushState(true, document.title, new_location);
282
282
283 return false;
283 return false;
284 }
284 }
285 }
285 }
286 }
286 }
287 );
287 );
288
288
289 $('tr.line .add-comment-line a').hover(
289 $('tr.line .add-comment-line a').hover(
290 function(){
290 function(){
291 $(this).parents('tr.line').addClass('commenting');
291 $(this).parents('tr.line').addClass('commenting');
292 }, function(){
292 }, function(){
293 $(this).parents('tr.line').removeClass('commenting');
293 $(this).parents('tr.line').removeClass('commenting');
294 }
294 }
295 );
295 );
296
296
297 $('tr.line .add-comment-line a').on('click', function(e){
297 $('tr.line .add-comment-line a').on('click', function(e){
298 var tr = $(e.currentTarget).parents('tr.line')[0];
298 var tr = $(e.currentTarget).parents('tr.line')[0];
299 injectInlineForm(tr);
299 injectInlineForm(tr);
300 return false;
300 return false;
301 });
301 });
302
302
303
303
304 $('.collapse_file').on('click', function(e) {
304 $('.collapse_file').on('click', function(e) {
305 e.stopPropagation();
305 e.stopPropagation();
306 if ($(e.target).is('a')) { return; }
306 if ($(e.target).is('a')) { return; }
307 var node = $(e.delegateTarget).first();
307 var node = $(e.delegateTarget).first();
308 var icon = $($(node.children().first()).children().first());
308 var icon = $($(node.children().first()).children().first());
309 var id = node.attr('fid');
309 var id = node.attr('fid');
310 var target = $('#'+id);
310 var target = $('#'+id);
311 var tr = $('#tr_'+id);
311 var tr = $('#tr_'+id);
312 var diff = $('#diff_'+id);
312 var diff = $('#diff_'+id);
313 if(node.hasClass('expand_file')){
313 if(node.hasClass('expand_file')){
314 node.removeClass('expand_file');
314 node.removeClass('expand_file');
315 icon.removeClass('expand_file_icon');
315 icon.removeClass('expand_file_icon');
316 node.addClass('collapse_file');
316 node.addClass('collapse_file');
317 icon.addClass('collapse_file_icon');
317 icon.addClass('collapse_file_icon');
318 diff.show();
318 diff.show();
319 tr.show();
319 tr.show();
320 target.show();
320 target.show();
321 } else {
321 } else {
322 node.removeClass('collapse_file');
322 node.removeClass('collapse_file');
323 icon.removeClass('collapse_file_icon');
323 icon.removeClass('collapse_file_icon');
324 node.addClass('expand_file');
324 node.addClass('expand_file');
325 icon.addClass('expand_file_icon');
325 icon.addClass('expand_file_icon');
326 diff.hide();
326 diff.hide();
327 tr.hide();
327 tr.hide();
328 target.hide();
328 target.hide();
329 }
329 }
330 });
330 });
331
331
332 $('#expand_all_files').click(function() {
332 $('#expand_all_files').click(function() {
333 $('.expand_file').each(function() {
333 $('.expand_file').each(function() {
334 var node = $(this);
334 var node = $(this);
335 var icon = $($(node.children().first()).children().first());
335 var icon = $($(node.children().first()).children().first());
336 var id = $(this).attr('fid');
336 var id = $(this).attr('fid');
337 var target = $('#'+id);
337 var target = $('#'+id);
338 var tr = $('#tr_'+id);
338 var tr = $('#tr_'+id);
339 var diff = $('#diff_'+id);
339 var diff = $('#diff_'+id);
340 node.removeClass('expand_file');
340 node.removeClass('expand_file');
341 icon.removeClass('expand_file_icon');
341 icon.removeClass('expand_file_icon');
342 node.addClass('collapse_file');
342 node.addClass('collapse_file');
343 icon.addClass('collapse_file_icon');
343 icon.addClass('collapse_file_icon');
344 diff.show();
344 diff.show();
345 tr.show();
345 tr.show();
346 target.show();
346 target.show();
347 });
347 });
348 });
348 });
349
349
350 $('#collapse_all_files').click(function() {
350 $('#collapse_all_files').click(function() {
351 $('.collapse_file').each(function() {
351 $('.collapse_file').each(function() {
352 var node = $(this);
352 var node = $(this);
353 var icon = $($(node.children().first()).children().first());
353 var icon = $($(node.children().first()).children().first());
354 var id = $(this).attr('fid');
354 var id = $(this).attr('fid');
355 var target = $('#'+id);
355 var target = $('#'+id);
356 var tr = $('#tr_'+id);
356 var tr = $('#tr_'+id);
357 var diff = $('#diff_'+id);
357 var diff = $('#diff_'+id);
358 node.removeClass('collapse_file');
358 node.removeClass('collapse_file');
359 icon.removeClass('collapse_file_icon');
359 icon.removeClass('collapse_file_icon');
360 node.addClass('expand_file');
360 node.addClass('expand_file');
361 icon.addClass('expand_file_icon');
361 icon.addClass('expand_file_icon');
362 diff.hide();
362 diff.hide();
363 tr.hide();
363 tr.hide();
364 target.hide();
364 target.hide();
365 });
365 });
366 });
366 });
367
367
368 // Mouse over behavior for comments and line selection
368 // Mouse over behavior for comments and line selection
369
369
370 // Select the line that comes from the url anchor
370 // Select the line that comes from the url anchor
371 // At the time of development, Chrome didn't seem to support jquery's :target
371 // At the time of development, Chrome didn't seem to support jquery's :target
372 // element, so I had to scroll manually
372 // element, so I had to scroll manually
373 if (location.hash) {
373 if (location.hash) {
374 var splitIx = location.hash.indexOf('/?/');
374 var splitIx = location.hash.indexOf('/?/');
375 if (splitIx !== -1){
375 if (splitIx !== -1){
376 var loc = location.hash.slice(0, splitIx);
376 var loc = location.hash.slice(0, splitIx);
377 var remainder = location.hash.slice(splitIx + 2);
377 var remainder = location.hash.slice(splitIx + 2);
378 }
378 }
379 else{
379 else{
380 var loc = location.hash;
380 var loc = location.hash;
381 var remainder = null;
381 var remainder = null;
382 }
382 }
383 if (loc.length > 1){
383 if (loc.length > 1){
384 var lineno = $(loc+'.lineno');
384 var lineno = $(loc+'.lineno');
385 if (lineno.length > 0){
385 if (lineno.length > 0){
386 var tr = lineno.parents('tr.line');
386 var tr = lineno.parents('tr.line');
387 tr.addClass('selected');
387 tr.addClass('selected');
388 $.Topic('/ui/plugins/code/anchor_focus').prepare({
388 $.Topic('/ui/plugins/code/anchor_focus').prepare({
389 tr:tr,
389 tr:tr,
390 remainder:remainder});
390 remainder:remainder});
391
391
392 if (!remainder){
392 if (!remainder){
393 tr[0].scrollIntoView();
393 tr[0].scrollIntoView();
394 }
394 }
395 }
395 }
396 }
396 }
397 }
397 }
398
398
399 collapsableContent();
399 collapsableContent();
400 $.Topic('/plugins/__REGISTER__').prepare({});
401 });
400 });
@@ -1,170 +1,172 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <!DOCTYPE html>
2 <!DOCTYPE html>
3
3
4 <%def name="get_template_context()" filter="n, trim">{
4 <%def name="get_template_context()" filter="n, trim">{
5
5
6 ## repo data
6 ## repo data
7 repo_name: "${getattr(c, 'repo_name', '')}",
7 repo_name: "${getattr(c, 'repo_name', '')}",
8 % if hasattr(c, 'rhodecode_db_repo'):
8 % if hasattr(c, 'rhodecode_db_repo'):
9 repo_type: "${c.rhodecode_db_repo.repo_type}",
9 repo_type: "${c.rhodecode_db_repo.repo_type}",
10 repo_landing_commit: "${c.rhodecode_db_repo.landing_rev[1]}",
10 repo_landing_commit: "${c.rhodecode_db_repo.landing_rev[1]}",
11 % else:
11 % else:
12 repo_type: null,
12 repo_type: null,
13 repo_landing_commit: null,
13 repo_landing_commit: null,
14 % endif
14 % endif
15
15
16 ## user data
16 ## user data
17 % if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
17 % if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
18 rhodecode_user: {
18 rhodecode_user: {
19 username: "${c.rhodecode_user.username}",
19 username: "${c.rhodecode_user.username}",
20 email: "${c.rhodecode_user.email}",
20 email: "${c.rhodecode_user.email}",
21 },
21 },
22 % else:
22 % else:
23 rhodecode_user: {
23 rhodecode_user: {
24 username: null,
24 username: null,
25 email: null,
25 email: null,
26 },
26 },
27 % endif
27 % endif
28
28
29 ## visual settings
29 ## visual settings
30 visual: {
30 visual: {
31 default_renderer: "${h.get_visual_attr(c, 'default_renderer')}"
31 default_renderer: "${h.get_visual_attr(c, 'default_renderer')}"
32 },
32 },
33
33
34 ## current commit context, filled inside templates that expose that
34 ## current commit context, filled inside templates that expose that
35 commit_data: {
35 commit_data: {
36 commit_id: null,
36 commit_id: null,
37 },
37 },
38
38
39 ## current pr context, filled inside templates that expose that
39 ## current pr context, filled inside templates that expose that
40 pull_request_data: {
40 pull_request_data: {
41 pull_request_id: null,
41 pull_request_id: null,
42 },
42 },
43
43
44 ## timeago settings, can be overwritten by custom user settings later
44 ## timeago settings, can be overwritten by custom user settings later
45 timeago: {
45 timeago: {
46 refresh_time: ${120 * 1000},
46 refresh_time: ${120 * 1000},
47 cutoff_limit: ${1000*60*60*24*7}
47 cutoff_limit: ${1000*60*60*24*7}
48 }
48 }
49 }
49 }
50
50
51 </%def>
51 </%def>
52
52
53 <html xmlns="http://www.w3.org/1999/xhtml">
53 <html xmlns="http://www.w3.org/1999/xhtml">
54 <head>
54 <head>
55 <title>${self.title()}</title>
55 <title>${self.title()}</title>
56 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
56 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
57 <%def name="robots()">
57 <%def name="robots()">
58 <meta name="robots" content="index, nofollow"/>
58 <meta name="robots" content="index, nofollow"/>
59 </%def>
59 </%def>
60 ${self.robots()}
60 ${self.robots()}
61 <link rel="icon" href="${h.url('/images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
61 <link rel="icon" href="${h.url('/images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
62
62
63 ## CSS definitions
63 ## CSS definitions
64 <%def name="css()">
64 <%def name="css()">
65 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
65 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
66 <!--[if lt IE 9]>
66 <!--[if lt IE 9]>
67 <link rel="stylesheet" type="text/css" href="${h.url('/css/ie.css', ver=c.rhodecode_version_hash)}" media="screen"/>
67 <link rel="stylesheet" type="text/css" href="${h.url('/css/ie.css', ver=c.rhodecode_version_hash)}" media="screen"/>
68 <![endif]-->
68 <![endif]-->
69 ## EXTRA FOR CSS
69 ## EXTRA FOR CSS
70 ${self.css_extra()}
70 ${self.css_extra()}
71 </%def>
71 </%def>
72 ## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
72 ## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
73 <%def name="css_extra()">
73 <%def name="css_extra()">
74 </%def>
74 </%def>
75
75
76 ${self.css()}
76 ${self.css()}
77
77
78 ## JAVASCRIPT
78 ## JAVASCRIPT
79 <%def name="js()">
79 <%def name="js()">
80 <script src="${h.url('/js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
80 <script src="${h.url('/js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
81 <script type="text/javascript">
81 <script type="text/javascript">
82 // register templateContext to pass template variables to JS
82 // register templateContext to pass template variables to JS
83 var templateContext = ${get_template_context()};
83 var templateContext = ${get_template_context()};
84
84
85 var REPO_NAME = "${getattr(c, 'repo_name', '')}";
85 var REPO_NAME = "${getattr(c, 'repo_name', '')}";
86 %if hasattr(c, 'rhodecode_db_repo'):
86 %if hasattr(c, 'rhodecode_db_repo'):
87 var REPO_LANDING_REV = '${c.rhodecode_db_repo.landing_rev[1]}';
87 var REPO_LANDING_REV = '${c.rhodecode_db_repo.landing_rev[1]}';
88 var REPO_TYPE = '${c.rhodecode_db_repo.repo_type}';
88 var REPO_TYPE = '${c.rhodecode_db_repo.repo_type}';
89 %else:
89 %else:
90 var REPO_LANDING_REV = '';
90 var REPO_LANDING_REV = '';
91 var REPO_TYPE = '';
91 var REPO_TYPE = '';
92 %endif
92 %endif
93 var APPLICATION_URL = "${h.url('home').rstrip('/')}";
93 var APPLICATION_URL = "${h.url('home').rstrip('/')}";
94 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
94 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
95 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
95 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
96 % if getattr(c, 'rhodecode_user', None):
96 % if getattr(c, 'rhodecode_user', None):
97 var USER = {name:'${c.rhodecode_user.username}'};
97 var USER = {name:'${c.rhodecode_user.username}'};
98 % else:
98 % else:
99 var USER = {name:null};
99 var USER = {name:null};
100 % endif
100 % endif
101
101
102 var APPENLIGHT = {
102 var APPENLIGHT = {
103 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
103 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
104 key: '${getattr(c, "appenlight_api_public_key", "")}',
104 key: '${getattr(c, "appenlight_api_public_key", "")}',
105 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
105 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
106 requestInfo: {
106 requestInfo: {
107 % if getattr(c, 'rhodecode_user', None):
107 % if getattr(c, 'rhodecode_user', None):
108 ip: '${c.rhodecode_user.ip_addr}',
108 ip: '${c.rhodecode_user.ip_addr}',
109 username: '${c.rhodecode_user.username}'
109 username: '${c.rhodecode_user.username}'
110 % endif
110 % endif
111 }
111 }
112 };
112 };
113 </script>
113 </script>
114
114
115 <!--[if lt IE 9]>
115 <!--[if lt IE 9]>
116 <script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script>
116 <script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script>
117 <![endif]-->
117 <![endif]-->
118 <script language="javascript" type="text/javascript" src="${h.url('/js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
118 <script language="javascript" type="text/javascript" src="${h.url('/js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
119 <script language="javascript" type="text/javascript" src="${h.url('/js/scripts.js', ver=c.rhodecode_version_hash)}"></script>
119 <script language="javascript" type="text/javascript" src="${h.url('/js/scripts.js', ver=c.rhodecode_version_hash)}"></script>
120 <script>CodeMirror.modeURL = "${h.url('/js/mode/%N/%N.js')}";</script>
120 <script>CodeMirror.modeURL = "${h.url('/js/mode/%N/%N.js')}";</script>
121
121
122 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
122 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
123 ${self.js_extra()}
123 ${self.js_extra()}
124
124
125 <script type="text/javascript">
125 <script type="text/javascript">
126 $(document).ready(function(){
126 $(document).ready(function(){
127 tooltip_activate();
127 tooltip_activate();
128 show_more_event();
128 show_more_event();
129 show_changeset_tooltip();
129 show_changeset_tooltip();
130 timeagoActivate();
130 timeagoActivate();
131 })
131 })
132 </script>
132 </script>
133
133
134 </%def>
134 </%def>
135
135
136 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
136 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
137 <%def name="js_extra()"></%def>
137 <%def name="js_extra()"></%def>
138 ${self.js()}
138 ${self.js()}
139
139
140 <%def name="head_extra()"></%def>
140 <%def name="head_extra()"></%def>
141 ${self.head_extra()}
141 ${self.head_extra()}
142
142
143 <%include file="/base/plugins_base.html"/>
144
143 ## extra stuff
145 ## extra stuff
144 %if c.pre_code:
146 %if c.pre_code:
145 ${c.pre_code|n}
147 ${c.pre_code|n}
146 %endif
148 %endif
147 </head>
149 </head>
148 <body id="body">
150 <body id="body">
149 <noscript>
151 <noscript>
150 <div class="noscript-error">
152 <div class="noscript-error">
151 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
153 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
152 </div>
154 </div>
153 </noscript>
155 </noscript>
154 ## IE hacks
156 ## IE hacks
155 <!--[if IE 7]>
157 <!--[if IE 7]>
156 <script>$(document.body).addClass('ie7')</script>
158 <script>$(document.body).addClass('ie7')</script>
157 <![endif]-->
159 <![endif]-->
158 <!--[if IE 8]>
160 <!--[if IE 8]>
159 <script>$(document.body).addClass('ie8')</script>
161 <script>$(document.body).addClass('ie8')</script>
160 <![endif]-->
162 <![endif]-->
161 <!--[if IE 9]>
163 <!--[if IE 9]>
162 <script>$(document.body).addClass('ie9')</script>
164 <script>$(document.body).addClass('ie9')</script>
163 <![endif]-->
165 <![endif]-->
164
166
165 ${next.body()}
167 ${next.body()}
166 %if c.post_code:
168 %if c.post_code:
167 ${c.post_code|n}
169 ${c.post_code|n}
168 %endif
170 %endif
169 </body>
171 </body>
170 </html>
172 </html>
General Comments 0
You need to be logged in to leave comments. Login now