##// END OF EJS Templates
deform: add deform.js to compiled scripts.js
dan -
r524:a0b14eeb default
parent child Browse files
Show More
@@ -0,0 +1,194 b''
1 /*
2 * Register a top-level callback to the deform.load() function
3 * this will be called when the DOM has finished loading. No need
4 * to include the call at the end of the page.
5 */
6
7 $(document).ready(function(){
8 deform.load();
9 });
10
11
12 var deform_loaded = false;
13
14 var deform = {
15 callbacks: [],
16
17 addCallback: function (oid, callback) {
18 deform.callbacks.push([oid, callback]);
19 },
20
21 clearCallbacks: function () {
22 deform.callbacks = [];
23 },
24
25 load: function() {
26 $(function() {
27 if (!deform_loaded) {
28 deform.processCallbacks();
29 deform.focusFirstInput();
30 deform_loaded = true;
31 }});
32 },
33
34
35 processCallbacks: function () {
36 $(deform.callbacks).each(function(num, item) {
37 var oid = item[0];
38 var callback = item[1];
39 callback(oid);
40 }
41 );
42 deform.clearCallbacks();
43 },
44
45 addSequenceItem: function (protonode, before) {
46 // - Clone the prototype node and add it before the "before" node.
47 // Also ensure any callbacks are run for the widget.
48
49 // In order to avoid breaking accessibility:
50 //
51 // - Find each tag within the prototype node with an id
52 // that has the string ``deformField(\d+)`` within it, and modify
53 // its id to have a random component.
54 // - For each label referencing an change id, change the label's
55 // for attribute to the new id.
56
57 var fieldmatch = /deformField(\d+)/;
58 var namematch = /(.+)?-[#]{3}/;
59 var code = protonode.attr('prototype');
60 var html = decodeURIComponent(code);
61 var $htmlnode = $(html);
62 var $idnodes = $htmlnode.find('[id]');
63 var $namednodes = $htmlnode.find('[name]');
64 var genid = deform.randomString(6);
65 var idmap = {};
66
67 // replace ids containing ``deformField`` and associated label for=
68 // items which point at them
69
70 $idnodes.each(function(idx, node) {
71 var $node = $(node);
72 var oldid = $node.attr('id');
73 var newid = oldid.replace(fieldmatch, "deformField$1-" + genid);
74 $node.attr('id', newid);
75 idmap[oldid] = newid;
76 var labelselector = 'label[for=' + oldid + ']';
77 var $fornodes = $htmlnode.find(labelselector);
78 $fornodes.attr('for', newid);
79 });
80
81 // replace names a containing ```deformField`` like we do for ids
82
83 $namednodes.each(function(idx, node) {
84 var $node = $(node);
85 var oldname = $node.attr('name');
86 var newname = oldname.replace(fieldmatch, "deformField$1-" + genid);
87 $node.attr('name', newname);
88 });
89
90 $htmlnode.insertBefore(before);
91
92 $(deform.callbacks).each(function(num, item) {
93 var oid = item[0];
94 var callback = item[1];
95 var newid = idmap[oid];
96 if (newid) {
97 callback(newid);
98 }
99 });
100
101 deform.clearCallbacks();
102 var old_len = parseInt(before.attr('now_len')||'0', 10);
103 before.attr('now_len', old_len + 1);
104 // we added something to the dom, trigger a change event
105 var e = jQuery.Event("change");
106 $('#deform').trigger(e);
107 },
108
109 appendSequenceItem: function(node) {
110 var $oid_node = $(node).closest('.deform-seq');
111 var $proto_node = $oid_node.find('.deform-proto').first();
112 var $before_node = $oid_node.find('.deform-insert-before').last();
113 var min_len = parseInt($before_node.attr('min_len')||'0', 10);
114 var max_len = parseInt($before_node.attr('max_len')||'9999', 10);
115 var now_len = parseInt($before_node.attr('now_len')||'0', 10);
116 var orderable = parseInt($before_node.attr('orderable')||'0', 10);
117
118 if (now_len < max_len) {
119 deform.addSequenceItem($proto_node, $before_node);
120 deform.processSequenceButtons($oid_node, min_len, max_len,
121 now_len + 1, orderable);
122 }
123 return false;
124 },
125
126 removeSequenceItem: function(clicked) {
127 var $item_node = $(clicked).closest('.deform-seq-item');
128 var $oid_node = $item_node.closest('.deform-seq');
129 var $before_node = $oid_node.find('.deform-insert-before').last();
130 var min_len = parseInt($before_node.attr('min_len')||'0', 10);
131 var max_len = parseInt($before_node.attr('max_len')||'9999', 10);
132 var now_len = parseInt($before_node.attr('now_len')||'0', 10);
133 var orderable = parseInt($before_node.attr('orderable')||'0', 10);
134 if (now_len > min_len) {
135 $before_node.attr('now_len', now_len - 1);
136 $item_node.remove();
137 deform.processSequenceButtons($oid_node, min_len, max_len,
138 now_len-1, orderable);
139 }
140 // we removed something from the dom, trigger a change event
141 var e = jQuery.Event("change");
142 $('#deform').trigger(e);
143 return false;
144 },
145
146 processSequenceButtons: function(oid_node, min_len, max_len, now_len,
147 orderable) {
148 orderable = !!orderable; // convert to bool
149 var has_multiple = now_len > 1;
150 var $ul = oid_node.find('.deform-seq-container').not(oid_node.find('.deform-seq-container .deform-seq-container'));
151 var $lis = $ul.find('.deform-seq-item').not($ul.find('.deform-seq-container .deform-seq-item'));
152 var show_closebutton = now_len > min_len;
153 var show_addbutton = now_len < max_len;
154 $lis.find('.deform-close-button').not($lis.find('.deform-seq-container .deform-close-button')).toggle(show_closebutton);
155 oid_node.find('.deform-seq-add').not(oid_node.find('.deform-seq-container .deform-seq-add')).toggle(show_addbutton);
156 $lis.find('.deform-order-button').not($lis.find('.deform-seq-container .deform-order-button')).toggle(orderable && has_multiple);
157 },
158
159 focusFirstInput: function (el) {
160 el = el || document.body;
161 var input = $(el).find(':input')
162 .filter('[id ^= deformField]')
163 .filter('[type != hidden]')
164 .first();
165 if (input) {
166 var raw = input.get(0);
167 if (raw) {
168 if (raw.type === 'text' || raw.type === 'file' ||
169 raw.type == 'password' || raw.type == 'text' ||
170 raw.type == 'textarea') {
171 if (!input.hasClass("hasDatepicker")) {
172 input.focus();
173 }
174 }
175 }
176 }
177 },
178
179 randomString: function (length) {
180 var chr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
181 chr = chr.split('');
182
183 if (! length) {
184 length = Math.floor(Math.random() * chr.length);
185 }
186
187 var str = '';
188 for (var i = 0; i < length; i++) {
189 str += chr[Math.floor(Math.random() * chr.length)];
190 }
191 return str;
192 }
193
194 };
@@ -1,140 +1,141 b''
1 1 module.exports = function(grunt) {
2 2 grunt.initConfig({
3 3
4 4 dirs: {
5 5 css: "rhodecode/public/css",
6 6 js: {
7 7 "src": "rhodecode/public/js/src",
8 8 "dest": "rhodecode/public/js"
9 9 }
10 10 },
11 11
12 12 concat: {
13 13 dist: {
14 14 src: [
15 15 // Base libraries
16 16 '<%= dirs.js.src %>/jquery-1.11.1.min.js',
17 17 '<%= dirs.js.src %>/logging.js',
18 18 '<%= dirs.js.src %>/bootstrap.js',
19 19 '<%= dirs.js.src %>/mousetrap.js',
20 20 '<%= dirs.js.src %>/moment.js',
21 21 '<%= dirs.js.src %>/appenlight-client-0.4.1.min.js',
22 22 '<%= dirs.js.src %>/i18n_utils.js',
23 '<%= dirs.js.src %>/deform.js',
23 24
24 25 // Plugins
25 26 '<%= dirs.js.src %>/plugins/jquery.pjax.js',
26 27 '<%= dirs.js.src %>/plugins/jquery.dataTables.js',
27 28 '<%= dirs.js.src %>/plugins/flavoured_checkbox.js',
28 29 '<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js',
29 30 '<%= dirs.js.src %>/plugins/jquery.autocomplete.js',
30 31 '<%= dirs.js.src %>/plugins/jquery.debounce.js',
31 32 '<%= dirs.js.src %>/plugins/jquery.mark.js',
32 33 '<%= dirs.js.src %>/plugins/jquery.timeago.js',
33 34 '<%= dirs.js.src %>/plugins/jquery.timeago-extension.js',
34 35
35 36 // Select2
36 37 '<%= dirs.js.src %>/select2/select2.js',
37 38
38 39 // Code-mirror
39 40 '<%= dirs.js.src %>/codemirror/codemirror.js',
40 41 '<%= dirs.js.src %>/codemirror/codemirror_loadmode.js',
41 42 '<%= dirs.js.src %>/codemirror/codemirror_hint.js',
42 43 '<%= dirs.js.src %>/codemirror/codemirror_overlay.js',
43 44 '<%= dirs.js.src %>/codemirror/codemirror_placeholder.js',
44 45 // TODO: mikhail: this is an exception. Since the code mirror modes
45 46 // are loaded "on the fly", we need to keep them in a public folder
46 47 '<%= dirs.js.dest %>/mode/meta.js',
47 48 '<%= dirs.js.dest %>/mode/meta_ext.js',
48 49 '<%= dirs.js.dest %>/rhodecode/i18n/select2/translations.js',
49 50
50 51 // Rhodecode utilities
51 52 '<%= dirs.js.src %>/rhodecode/utils/array.js',
52 53 '<%= dirs.js.src %>/rhodecode/utils/string.js',
53 54 '<%= dirs.js.src %>/rhodecode/utils/pyroutes.js',
54 55 '<%= dirs.js.src %>/rhodecode/utils/ajax.js',
55 56 '<%= dirs.js.src %>/rhodecode/utils/autocomplete.js',
56 57 '<%= dirs.js.src %>/rhodecode/utils/colorgenerator.js',
57 58 '<%= dirs.js.src %>/rhodecode/utils/ie.js',
58 59 '<%= dirs.js.src %>/rhodecode/utils/os.js',
59 60 '<%= dirs.js.src %>/rhodecode/utils/topics.js',
60 61
61 62 // Rhodecode widgets
62 63 '<%= dirs.js.src %>/rhodecode/widgets/multiselect.js',
63 64
64 65 // Rhodecode components
65 66 '<%= dirs.js.src %>/rhodecode/init.js',
66 67 '<%= dirs.js.src %>/rhodecode/codemirror.js',
67 68 '<%= dirs.js.src %>/rhodecode/comments.js',
68 69 '<%= dirs.js.src %>/rhodecode/constants.js',
69 70 '<%= dirs.js.src %>/rhodecode/files.js',
70 71 '<%= dirs.js.src %>/rhodecode/followers.js',
71 72 '<%= dirs.js.src %>/rhodecode/menus.js',
72 73 '<%= dirs.js.src %>/rhodecode/notifications.js',
73 74 '<%= dirs.js.src %>/rhodecode/permissions.js',
74 75 '<%= dirs.js.src %>/rhodecode/pjax.js',
75 76 '<%= dirs.js.src %>/rhodecode/pullrequests.js',
76 77 '<%= dirs.js.src %>/rhodecode/settings.js',
77 78 '<%= dirs.js.src %>/rhodecode/select2_widgets.js',
78 79 '<%= dirs.js.src %>/rhodecode/tooltips.js',
79 80 '<%= dirs.js.src %>/rhodecode/users.js',
80 81 '<%= dirs.js.src %>/rhodecode/appenlight.js',
81 82
82 83 // Rhodecode main module
83 84 '<%= dirs.js.src %>/rhodecode.js'
84 85 ],
85 86 dest: '<%= dirs.js.dest %>/scripts.js',
86 87 nonull: true
87 88 }
88 89 },
89 90
90 91 less: {
91 92 development: {
92 93 options: {
93 94 compress: false,
94 95 yuicompress: false,
95 96 optimization: 0
96 97 },
97 98 files: {
98 99 "<%= dirs.css %>/style.css": "<%= dirs.css %>/main.less"
99 100 }
100 101 },
101 102 production: {
102 103 options: {
103 104 compress: true,
104 105 yuicompress: true,
105 106 optimization: 2
106 107 },
107 108 files: {
108 109 "<%= dirs.css %>/style.css": "<%= dirs.css %>/main.less"
109 110 }
110 111 }
111 112 },
112 113
113 114 watch: {
114 115 less: {
115 116 files: ["<%= dirs.css %>/*.less"],
116 117 tasks: ["less:production"]
117 118 },
118 119 js: {
119 120 files: ["<%= dirs.js.src %>/**/*.js"],
120 121 tasks: ["concat:dist"]
121 122 }
122 123 },
123 124
124 125 jshint: {
125 126 rhodecode: {
126 127 src: '<%= dirs.js.src %>/rhodecode/**/*.js',
127 128 options: {
128 129 jshintrc: '.jshintrc'
129 130 }
130 131 }
131 132 }
132 133 });
133 134
134 135 grunt.loadNpmTasks('grunt-contrib-less');
135 136 grunt.loadNpmTasks('grunt-contrib-concat');
136 137 grunt.loadNpmTasks('grunt-contrib-watch');
137 138 grunt.loadNpmTasks('grunt-contrib-jshint');
138 139
139 140 grunt.registerTask('default', ['less:production', 'concat:dist']);
140 141 };
@@ -1,139 +1,138 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 59 var ASSET_URL = "${h.asset('')}";
60 60 var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
61 61 var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
62 62 % if getattr(c, 'rhodecode_user', None):
63 63 var USER = {name:'${c.rhodecode_user.username}'};
64 64 % else:
65 65 var USER = {name:null};
66 66 % endif
67 67
68 68 var APPENLIGHT = {
69 69 enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
70 70 key: '${getattr(c, "appenlight_api_public_key", "")}',
71 71 serverUrl: '${getattr(c, "appenlight_server_url", "")}',
72 72 requestInfo: {
73 73 % if getattr(c, 'rhodecode_user', None):
74 74 ip: '${c.rhodecode_user.ip_addr}',
75 75 username: '${c.rhodecode_user.username}'
76 76 % endif
77 77 }
78 78 };
79 79 </script>
80 80
81 81 <!--[if lt IE 9]>
82 82 <script language="javascript" type="text/javascript" src="${h.asset('js/excanvas.min.js')}"></script>
83 83 <![endif]-->
84 84 <script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
85 85 <script language="javascript" type="text/javascript" src="${h.asset('js/scripts.js', ver=c.rhodecode_version_hash)}"></script>
86 <script language="javascript" type="text/javascript" src="${h.static_url('deform:static/scripts/deform.js')}"></script>
87 86 ## avoide esaping the %N
88 87 <script>CodeMirror.modeURL = "${h.asset('') + 'js/mode/%N/%N.js'}";</script>
89 88
90 89
91 90 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
92 91 ${self.js_extra()}
93 92
94 93 <script type="text/javascript">
95 94 $(document).ready(function(){
96 95 show_more_event();
97 96 timeagoActivate();
98 97 })
99 98 </script>
100 99
101 100 </%def>
102 101
103 102 ## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
104 103 <%def name="js_extra()"></%def>
105 104 ${self.js()}
106 105
107 106 <%def name="head_extra()"></%def>
108 107 ${self.head_extra()}
109 108
110 109 <%include file="/base/plugins_base.html"/>
111 110
112 111 ## extra stuff
113 112 %if c.pre_code:
114 113 ${c.pre_code|n}
115 114 %endif
116 115 </head>
117 116 <body id="body">
118 117 <noscript>
119 118 <div class="noscript-error">
120 119 ${_('Please enable JavaScript to use RhodeCode Enterprise')}
121 120 </div>
122 121 </noscript>
123 122 ## IE hacks
124 123 <!--[if IE 7]>
125 124 <script>$(document.body).addClass('ie7')</script>
126 125 <![endif]-->
127 126 <!--[if IE 8]>
128 127 <script>$(document.body).addClass('ie8')</script>
129 128 <![endif]-->
130 129 <!--[if IE 9]>
131 130 <script>$(document.body).addClass('ie9')</script>
132 131 <![endif]-->
133 132
134 133 ${next.body()}
135 134 %if c.post_code:
136 135 ${c.post_code|n}
137 136 %endif
138 137 </body>
139 138 </html>
General Comments 0
You need to be logged in to leave comments. Login now