ChiliProject is not maintained anymore. Please be advised that there will be no more updates.
We do not recommend that you setup new ChiliProject instances and we urge all existing users to migrate their data to a maintained system, e.g. Redmine. We will provide a migration script later. In the meantime, you can use the instructions by Christian Daehn.
mobile.js
1 | window.MobileJS = {} |
---|---|
2 | |
3 | MobileJS.cssua = function(html, userAgent) { |
4 | /** This block is taken from cssua.js
|
5 | User-agent specific CSS support |
6 | |
7 | Created: 2006-06-10-1635 |
8 | Modified: 2011-01-10-1101 |
9 | |
10 | Copyright (c)2006-2011 Stephen M. McKamey |
11 | Distributed under The MIT License */ |
12 | |
13 | /*const string*/ var PREFIX = " ua-"; |
14 | |
15 | var R_All = /[\w\-\.]+[\/][v]?\d+(\.\d+)*/g, |
16 | R_AOL = /\b(aol|america online browser)[\s\/]*(\d+(\.\d+)*)/,
|
17 | R_MSIE = /\b(msie|microsoft internet explorer)[\s\/]*(\d+(\.\d+)*)/,
|
18 | R_Gecko = /rv[:](\d+(\.\d+)*).*?\bgecko[\/]\d+/,
|
19 | R_Opera = /\bopera[\s\/]*(\d+(\.\d+)*)/,
|
20 | R_Android = /\bandroid[\s]+(\d+(\.\d+)*)/,
|
21 | R_iOS = /\bos[\s]+(\d+(\_\d+)*) like mac os x/,
|
22 | R_WinPhone = /\bwindows phone os (\d+(\_\d+)*)/,
|
23 | R_MSPIE = /\b(mspie|microsoft pocket internet explorer)[\s\/]*(\d+(\.\d+)*)/,
|
24 | R_iCab = /\bicab[\s\/]*(\d+(\.\d+)*)/,
|
25 | R_BlackBerry = /\bblackberry\w*[\s\/]+(\d+(\.\d+)*)/,
|
26 | R_mobile = /(\bandroid\b|\bipad\b|\bipod\b|\bblackberry|\bwebos\b|\bwindows ce\b|\bwindows phone os\b|\bwindows ce\b|\bpalm|\bsymbian|\bj2me\b|\bdocomo\b|\bpda\b|\bchtml\b|\bmidp\b|\bcldc\b|\w*?mobile\w*?|\w*?phone\w*?)/;
|
27 | |
28 | var cssua = {
|
29 | /*Map<string,string>*/
|
30 | parse : function(/*string*/ uaStr) { |
31 | /*Map<string,string>*/
|
32 | var ua = {};
|
33 | |
34 | uaStr = (""+uaStr).toLowerCase();
|
35 | if (!uaStr) {
|
36 | return ua;
|
37 | } |
38 | |
39 | // do this first for all (covers generic user-agents)
|
40 | var raw = uaStr.match(R_All);
|
41 | if (raw) {
|
42 | for (var i=0; i<raw.length; i++) { |
43 | var s = raw[i].indexOf('/'), |
44 | b = raw[i].substring(0, s);
|
45 | if (b && b !== "mozilla") { |
46 | // shorten this common engine
|
47 | if (b === "applewebkit") { |
48 | b = "webkit";
|
49 | } |
50 | ua[b] = raw[i].substr(s+1);
|
51 | } |
52 | } |
53 | } |
54 | |
55 | // aol uses multiple engines so continue checking
|
56 | if (R_AOL.exec(uaStr)) {
|
57 | ua.aol = RegExp.$2;
|
58 | } |
59 | |
60 | // order is important as user-agents spoof each other
|
61 | if (R_Opera.exec(uaStr)) {
|
62 | ua.opera = RegExp.$1;
|
63 | } else if (R_iCab.exec(uaStr)) { |
64 | ua.icab = RegExp.$1;
|
65 | } else if (R_MSIE.exec(uaStr)) { |
66 | ua.ie = RegExp.$2;
|
67 | } else if (R_MSPIE.exec(uaStr)) { |
68 | ua.mspie = RegExp.$2;
|
69 | } else if (R_Gecko.exec(uaStr)) { |
70 | ua.gecko = RegExp.$1;
|
71 | } else if (R_Android.exec(uaStr)) { |
72 | ua.android = RegExp.$1;
|
73 | } else if (R_iOS.exec(uaStr)) { |
74 | ua.ios = RegExp.$1.split('_').join('.'); |
75 | } else if (R_WinPhone.exec(uaStr)) { |
76 | ua.winphone = RegExp.$1;
|
77 | } |
78 | |
79 | // ensure that mobile devices have indication
|
80 | if (!ua.blackberry && R_BlackBerry.exec(uaStr)) {
|
81 | ua.blackberry = RegExp.$1;
|
82 | } |
83 | if (R_mobile.exec(uaStr)) {
|
84 | ua.mobile = RegExp.$1;
|
85 | } |
86 | |
87 | // version standardization
|
88 | if (ua.safari) {
|
89 | if (ua.chrome || (ua.mobile && !ua.ios)) {
|
90 | delete ua.safari;
|
91 | } else if (ua.version) { |
92 | ua.safari = ua.version; |
93 | } else {
|
94 | ua.safari = ({ |
95 | "419": "2.0.4", |
96 | "417": "2.0.3", |
97 | "416": "2.0.2", |
98 | "412": "2.0", |
99 | "312": "1.3", |
100 | "125": "1.2", |
101 | "85": "1.0" |
102 | })[parseInt(ua.safari, 10)] || ua.safari;
|
103 | } |
104 | } else if (ua.opera && ua.version) { |
105 | ua.opera = ua.version; |
106 | } |
107 | |
108 | if (ua.version) {
|
109 | delete ua.version;
|
110 | } |
111 | |
112 | return ua;
|
113 | }, |
114 | |
115 | /*string*/
|
116 | format : function (/*Map<string,string>*/ ua) { |
117 | /*string*/
|
118 | function format(/*string*/ b, /*string*/ v) { |
119 | b = b.split(' ').join('_').split('.').join('-'); |
120 | /*string*/ var css = PREFIX+b; |
121 | if (v) {
|
122 | v = v.split(' ').join('_').split('.').join('-'); |
123 | var i = v.indexOf('-'); |
124 | while (i > 0) { |
125 | // loop through chopping last '-' to end off
|
126 | // concat result onto return string
|
127 | css += PREFIX+b+'-'+v.substring(0, i); |
128 | i = v.indexOf('-', i+1); |
129 | } |
130 | css += PREFIX+b+'-'+v;
|
131 | } |
132 | return css;
|
133 | } |
134 | |
135 | var uaCss = ""; |
136 | for (var b in ua) { |
137 | if (b && ua.hasOwnProperty(b)) {
|
138 | uaCss += format(b, ua[b]); |
139 | } |
140 | } |
141 | |
142 | // user-agent classNames
|
143 | return uaCss;
|
144 | }, |
145 | |
146 | /* Encodes parsed userAgent object as a compact URI-Encoded key-value collection */
|
147 | /*string*/
|
148 | encode : function(/*Map<string,string>*/ ua) { |
149 | var query = ""; |
150 | for (var b in ua) { |
151 | if (b && ua.hasOwnProperty(b)) {
|
152 | if (query) {
|
153 | query += "&";
|
154 | } |
155 | query += encodeURIComponent(b)+"="+encodeURIComponent(ua[b]);
|
156 | } |
157 | } |
158 | return query;
|
159 | } |
160 | }; |
161 | |
162 | // calculate userAgent
|
163 | cssua.userAgent = cssua.ua = cssua.parse(userAgent); |
164 | |
165 | // append CSS classes to HTML node
|
166 | var ua = cssua.format(cssua.ua);
|
167 | if (html.className) {
|
168 | html.className += ua; |
169 | } else {
|
170 | html.className = ua.substr(1);
|
171 | } |
172 | |
173 | return cssua;
|
174 | } |
175 | |
176 | MobileJS.top_menu = function() { |
177 | $("top-menu").hide(); |
178 | $$('div.quick-search/h1').first().observe("click", function(event) { |
179 | $("top-menu").toggle(); |
180 | }); |
181 | } |
182 | |
183 | MobileJS.main_menu = function() { |
184 | // Get visible menu links
|
185 | menu_links = $('main-menu').select("a").collect(function(a) { |
186 | a.hide(); |
187 | return { name: a.innerHTML, target: a.getAttribute("href") }; |
188 | }); |
189 | // Build selectbox
|
190 | var selectbox = "<select id='main-menu-selectbox'>"; |
191 | menu_links.each(function(ary) {
|
192 | selectbox = selectbox + "<option value='" + ary.target + "'>" + ary.name + "</option>"; |
193 | }); |
194 | selectbox = selectbox + "<option value='quick-search'>" + $('quick-search').select("a").first().innerHTML + " ... </option>" |
195 | selectbox = selectbox + "</select>";
|
196 | // insert selectbox, set current page value and install onchange handler
|
197 | $('main-menu').innerHTML = selectbox; |
198 | var current_select_value = menu_links.select(function(ary) { |
199 | return ary.target.search(document.location.pathname) > -1; |
200 | }).first(); |
201 | if (current_select_value != undefined) { |
202 | $('main-menu-selectbox').value = current_select_value.target; |
203 | } |
204 | $('main-menu-selectbox').observe("change", function(event) { |
205 | if (this.value == "quick-search") { |
206 | $('quick-search').show(); |
207 | } else {
|
208 | $('quick-search').hide(); |
209 | document.location.pathname = this.value;
|
210 | } |
211 | }); |
212 | } |
213 | |
214 | MobileJS.issues_filter = function() { |
215 | var qf = $("query_form"); |
216 | if (qf == undefined) { |
217 | return false; |
218 | } |
219 | qf.hide(); |
220 | var headline = qf.up().select("h2").first(); |
221 | headline.observe("click", function(event) { |
222 | $("query_form").toggle(); |
223 | }); |
224 | } |
225 | |
226 | MobileJS.quick_search = function() { |
227 | $('quick-search').hide(); |
228 | } |
229 | |
230 | MobileJS.headline = function() { |
231 | var magic_header_width_factor = 1.5; |
232 | var current_width = $$("#header/h1").first().getWidth() * magic_header_width_factor; |
233 | var screen_width = document.width;
|
234 | if (current_width > screen_width) {
|
235 | // Try decreasing kerning, first
|
236 | $$("#header/h1").first().style.letterSpacing="-0.2ex" |
237 | current_width = $$("#header/h1").first().getWidth() * magic_header_width_factor; |
238 | } |
239 | if (current_width > screen_width) {
|
240 | // Try decreasing font size, but not too far
|
241 | for (i = 2.0; i > 1.0; i = i - 0.1) { |
242 | $$("#header/h1").first().style.fontSize = i + "em"; |
243 | current_width = $$("#header/h1").first().getWidth() * magic_header_width_factor; |
244 | if (current_width < screen_width) break; |
245 | } |
246 | } |
247 | } |
248 | |
249 | MobileJS.contextual_actions = function() { |
250 | var contextual = $$("#content").first().select(".contextual").first(); |
251 | if (contextual == undefined) { |
252 | return false; |
253 | } |
254 | var context_links = contextual.select("a"); |
255 | if (context_links.size() == 0) { |
256 | return false; |
257 | } |
258 | context_links.each(function(a) {
|
259 | a.observe("click", function() { |
260 | contextual.hide(); |
261 | return true; |
262 | }); |
263 | }); |
264 | contextual.hide(); |
265 | var headline = contextual.up().select("h2").first(); |
266 | headline.observe("click", function(event) { |
267 | contextual.toggle(); |
268 | }); |
269 | } |
270 | |
271 | MobileJS.hidden_sidebar = function() { |
272 | $("sidebar").hide(); |
273 | var sidebar_button = "<span id='sidebar-toggle-button'> </span>"; |
274 | $("main-menu").insert({before: sidebar_button}); |
275 | $("sidebar-toggle-button").observe("click", function() { |
276 | $("sidebar").toggle(); |
277 | }); |
278 | } |
279 | |
280 | MobileJS.screen_adjustment = function() { |
281 | var mobile_viewport_tag = '<meta name = "viewport" ' + |
282 | 'content = "width=device-width; initial-scale=1.0;' +
|
283 | 'maximum-scale=1.0; user-scalable=0;" />';
|
284 | $$('head').first().insert({bottom: mobile_viewport_tag}); |
285 | } |
286 | |
287 | document.observe("dom:loaded", function() { |
288 | if (cssua.userAgent.mobile) {
|
289 | MobileJS.headline(); |
290 | MobileJS.top_menu(); |
291 | MobileJS.quick_search(); |
292 | MobileJS.main_menu(); |
293 | MobileJS.issues_filter(); |
294 | MobileJS.contextual_actions(); |
295 | MobileJS.hidden_sidebar(); |
296 | MobileJS.screen_adjustment(); |
297 | } |
298 | }); |
299 | |
300 | window.cssua = MobileJS.cssua(document.documentElement, navigator.userAgent); |