##// END OF EJS Templates
assets: add javascript static file route generator
dan -
r464:00a55384 default
parent child Browse files
Show More
@@ -1,227 +1,235 b''
1 1 // # Copyright (C) 2010-2016 RhodeCode GmbH
2 2 // #
3 3 // # This program is free software: you can redistribute it and/or modify
4 4 // # it under the terms of the GNU Affero General Public License, version 3
5 5 // # (only), as published by the Free Software Foundation.
6 6 // #
7 7 // # This program is distributed in the hope that it will be useful,
8 8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 // # GNU General Public License for more details.
11 11 // #
12 12 // # You should have received a copy of the GNU Affero General Public License
13 13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 // #
15 15 // # This program is dual-licensed. If you wish to learn more about the
16 16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 /**
20 20 * Object holding the registered pyroutes.
21 21 * Routes will be registered with the generated script
22 22 * rhodecode/public/js/rhodecode/base/pyroutes.js
23 23 */
24 24 var PROUTES_MAP = {};
25 25
26 26 /**
27 27 * PyRoutesJS
28 28 *
29 29 * Usage pyroutes.url('mark_error_fixed',{"error_id":error_id}) // /mark_error_fixed/<error_id>
30 30 */
31 31 var pyroutes = (function() {
32 32 // access global map defined in special file pyroutes
33 33 var matchlist = PROUTES_MAP;
34 34 var sprintf = (function() {
35 35 function get_type(variable) {
36 36 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
37 37 }
38 38 function str_repeat(input, multiplier) {
39 39 for (var output = []; multiplier > 0; output[--multiplier] = input) {
40 40 /* do nothing */
41 41 }
42 42 return output.join('');
43 43 }
44 44 var str_format = function() {
45 45 if (!str_format.cache.hasOwnProperty(arguments[0])) {
46 46 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
47 47 }
48 48 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
49 49 };
50
50
51 51 str_format.format = function(parse_tree, argv) {
52 52 var cursor = 1,
53 53 tree_length = parse_tree.length,
54 54 node_type = '',
55 55 arg,
56 56 output = [],
57 57 i, k,
58 58 match,
59 59 pad,
60 60 pad_character,
61 61 pad_length;
62 62 for (i = 0; i < tree_length; i++) {
63 63 node_type = get_type(parse_tree[i]);
64 64 if (node_type === 'string') {
65 65 output.push(parse_tree[i]);
66 66 }
67 67 else if (node_type === 'array') {
68 68 match = parse_tree[i]; // convenience purposes only
69 69 if (match[2]) { // keyword argument
70 70 arg = argv[cursor];
71 71 for (k = 0; k < match[2].length; k++) {
72 72 if (!arg.hasOwnProperty(match[2][k])) {
73 73 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
74 74 }
75 75 arg = arg[match[2][k]];
76 76 }
77 77 }
78 78 else if (match[1]) { // positional argument (explicit)
79 79 arg = argv[match[1]];
80 80 }
81 81 else { // positional argument (implicit)
82 82 arg = argv[cursor++];
83 83 }
84
84
85 85 if (/[^s]/.test(match[8]) && (get_type(arg) !== 'number')) {
86 86 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
87 87 }
88 88 switch (match[8]) {
89 89 case 'b': arg = arg.toString(2); break;
90 90 case 'c': arg = String.fromCharCode(arg); break;
91 91 case 'd': arg = parseInt(arg, 10); break;
92 92 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
93 93 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
94 94 case 'o': arg = arg.toString(8); break;
95 95 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg);
96 96 break;
97 97 case 'u': arg = Math.abs(arg); break;
98 98 case 'x': arg = arg.toString(16); break;
99 99 case 'X': arg = arg.toString(16).toUpperCase(); break;
100 100 }
101 101 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
102 102 pad_character =
103 103 match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' ';
104 104 pad_length = match[6] - String(arg).length;
105 105 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
106 106 output.push(match[5] ? arg + pad : pad + arg);
107 107 }
108 108 }
109 109 return output.join('');
110 110 };
111
111
112 112 str_format.cache = {};
113
113
114 114 str_format.parse = function(fmt) {
115 115 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
116 116 while (_fmt) {
117 117 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
118 118 parse_tree.push(match[0]);
119 119 }
120 120 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
121 121 parse_tree.push('%');
122 122 }
123 123 else if (
124 124 (match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
125 125 if (match[2]) {
126 126 arg_names |= 1;
127 127 var field_list = [], replacement_field = match[2], field_match = [];
128 128 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
129 129 field_list.push(field_match[1]);
130 130 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
131 131 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
132 132 field_list.push(field_match[1]);
133 133 }
134 134 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
135 135 field_list.push(field_match[1]);
136 136 }
137 137 else {
138 138 throw('[sprintf] huh?');
139 139 }
140 140 }
141 141 }
142 142 else {
143 143 throw('[sprintf] huh?');
144 144 }
145 145 match[2] = field_list;
146 146 }
147 147 else {
148 148 arg_names |= 2;
149 149 }
150 150 if (arg_names === 3) {
151 151 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
152 152 }
153 153 parse_tree.push(match);
154 154 }
155 155 else {
156 156 throw('[sprintf] huh?');
157 157 }
158 158 _fmt = _fmt.substring(match[0].length);
159 159 }
160 160 return parse_tree;
161 161 };
162 162 return str_format;
163 163 })();
164
164
165 165 var vsprintf = function(fmt, argv) {
166 166 argv.unshift(fmt);
167 167 return sprintf.apply(null, argv);
168 168 };
169 169 return {
170 'asset': function(path, ver) {
171 var asset_url = ASSET_URL || '/_static/';
172 var ret = asset_url + path;
173 if (ver !== undefined) {
174 ret += '?ver=' + ver;
175 }
176 return ret;
177 },
170 178 'url': function(route_name, params) {
171 179 var result = route_name;
172 180 if (typeof(params) !== 'object'){
173 181 params = {};
174 182 }
175 183 if (matchlist.hasOwnProperty(route_name)) {
176 184 var route = matchlist[route_name];
177 185 // param substitution
178 186 for(var i=0; i < route[1].length; i++) {
179 187 var param_name = route[1][i];
180 188 if (!params.hasOwnProperty(param_name))
181 189 throw new Error(
182 'parameter '+
183 param_name +
184 ' is missing in route"' +
190 'parameter '+
191 param_name +
192 ' is missing in route"' +
185 193 route_name + '" generation');
186 194 }
187 195 result = sprintf(route[0], params);
188
196
189 197 var ret = [];
190 198 // extra params => GET
191 199 for (var param in params){
192 200 if (route[1].indexOf(param) === -1){
193 ret.push(encodeURIComponent(param) + "=" +
201 ret.push(encodeURIComponent(param) + "=" +
194 202 encodeURIComponent(params[param]));
195 203 }
196 204 }
197 205 var _parts = ret.join("&");
198 206 if(_parts){
199 207 result = result +'?'+ _parts;
200 208 }
201 209 if(APPLICATION_URL) {
202 210 result = APPLICATION_URL + result;
203 211 }
204 212 }
205
213
206 214 return result;
207 215 },
208 216 'register': function(route_name, route_tmpl, req_params) {
209 217 if (typeof(req_params) !== 'object') {
210 218 req_params = [];
211 219 }
212 220 // fix escape
213 221 route_tmpl = unescape(route_tmpl);
214 222 keys = [];
215 223 for(var i=0; i < req_params.length; i++) {
216 224 keys.push(req_params[i]);
217 225 }
218 226 matchlist[route_name] = [
219 227 route_tmpl,
220 228 keys
221 229 ];
222 230 },
223 231 '_routes': function(){
224 232 return matchlist;
225 233 }
226 234 };
227 235 })();
@@ -1,135 +1,136 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <!DOCTYPE html>
3 3
4 4 <%
5 5 c.template_context['repo_name'] = getattr(c, 'repo_name', '')
6 6
7 7 if hasattr(c, 'rhodecode_db_repo'):
8 8 c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
9 9 c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_rev[1]
10 10
11 11 if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
12 12 c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
13 13 c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
14 14
15 15 c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
16 16 %>
17 17
18 18 <html xmlns="http://www.w3.org/1999/xhtml">
19 19 <head>
20 20 <title>${self.title()}</title>
21 21 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
22 22 <%def name="robots()">
23 23 <meta name="robots" content="index, nofollow"/>
24 24 </%def>
25 25 ${self.robots()}
26 26 <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
27 27
28 28 ## CSS definitions
29 29 <%def name="css()">
30 30 <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
31 31 <!--[if lt IE 9]>
32 32 <link rel="stylesheet" type="text/css" href="${h.asset('css/ie.css', ver=c.rhodecode_version_hash)}" media="screen"/>
33 33 <![endif]-->
34 34 ## EXTRA FOR CSS
35 35 ${self.css_extra()}
36 36 </%def>
37 37 ## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
38 38 <%def name="css_extra()">
39 39 </%def>
40 40
41 41 ${self.css()}
42 42
43 43 ## JAVASCRIPT
44 44 <%def name="js()">
45 45 <script src="${h.asset('js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
46 46 <script type="text/javascript">
47 47 // register templateContext to pass template variables to JS
48 48 var templateContext = ${h.json.dumps(c.template_context)|n};
49 49
50 50 var REPO_NAME = "${getattr(c, 'repo_name', '')}";
51 51 %if hasattr(c, 'rhodecode_db_repo'):
52 52 var REPO_LANDING_REV = '${c.rhodecode_db_repo.landing_rev[1]}';
53 53 var REPO_TYPE = '${c.rhodecode_db_repo.repo_type}';
54 54 %else:
55 55 var REPO_LANDING_REV = '';
56 56 var REPO_TYPE = '';
57 57 %endif
58 58 var APPLICATION_URL = "${h.url('home').rstrip('/')}";
59 var ASSET_URL = "${h.asset('')}";
59 60 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
60 61 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
61 62 % if getattr(c, 'rhodecode_user', None):
62 63 var USER = {name:'${c.rhodecode_user.username}'};
63 64 % else:
64 65 var USER = {name:null};
65 66 % endif
66 67
67 68 var APPENLIGHT = {
68 69 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
69 70 key: '${getattr(c, "appenlight_api_public_key", "")}',
70 71 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
71 72 requestInfo: {
72 73 % if getattr(c, 'rhodecode_user', None):
73 74 ip: '${c.rhodecode_user.ip_addr}',
74 75 username: '${c.rhodecode_user.username}'
75 76 % endif
76 77 }
77 78 };
78 79 </script>
79 80
80 81 <!--[if lt IE 9]>
81 82 <script language="javascript" type="text/javascript" src="${h.asset('js/excanvas.min.js')}"></script>
82 83 <![endif]-->
83 84 <script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
84 85 <script language="javascript" type="text/javascript" src="${h.asset('js/scripts.js', ver=c.rhodecode_version_hash)}"></script>
85 86 <script>CodeMirror.modeURL = "${h.asset('js/mode/%N/%N.js')}";</script>
86 87
87 88 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
88 89 ${self.js_extra()}
89 90
90 91 <script type="text/javascript">
91 92 $(document).ready(function(){
92 93 show_more_event();
93 94 timeagoActivate();
94 95 })
95 96 </script>
96 97
97 98 </%def>
98 99
99 100 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
100 101 <%def name="js_extra()"></%def>
101 102 ${self.js()}
102 103
103 104 <%def name="head_extra()"></%def>
104 105 ${self.head_extra()}
105 106
106 107 <%include file="/base/plugins_base.html"/>
107 108
108 109 ## extra stuff
109 110 %if c.pre_code:
110 111 ${c.pre_code|n}
111 112 %endif
112 113 </head>
113 114 <body id="body">
114 115 <noscript>
115 116 <div class="noscript-error">
116 117 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
117 118 </div>
118 119 </noscript>
119 120 ## IE hacks
120 121 <!--[if IE 7]>
121 122 <script>$(document.body).addClass('ie7')</script>
122 123 <![endif]-->
123 124 <!--[if IE 8]>
124 125 <script>$(document.body).addClass('ie8')</script>
125 126 <![endif]-->
126 127 <!--[if IE 9]>
127 128 <script>$(document.body).addClass('ie9')</script>
128 129 <![endif]-->
129 130
130 131 ${next.body()}
131 132 %if c.post_code:
132 133 ${c.post_code|n}
133 134 %endif
134 135 </body>
135 136 </html>
General Comments 0
You need to be logged in to leave comments. Login now