Description:
fixed javascript/css assets, fixed link_to_remote in problems page
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r322:c744bb196ba4 - - The requested commit is too big and content was truncated. 30 files changed. Show full diff

@@ -0,0 +1,41
1 +
2 + var Announcement = {
3 +
4 + mostRecentId: 0,
5 +
6 + refreshUrl: '/main/announcements',
7 +
8 + setMostRecentId: function(id) {
9 + Announcement.mostRecentId = id;
10 + },
11 +
12 + updateRecentId: function(id) {
13 + if(Announcement.mostRecentId < id)
14 + Announcement.mostRecentId = id;
15 + },
16 +
17 + refreshAnnouncement: function() {
18 + var url = Announcement.refreshUrl;
19 + new Ajax.Request(url, {
20 + method: 'get',
21 + parameters: { recent: Announcement.mostRecentId },
22 + onSuccess: function(transport) {
23 + if((transport.status == 200) &&
24 + (transport.responseText.match(/\S/)!=null)) {
25 + var announcementBody = $("announcementbox-body");
26 + announcementBody.insert({ top: transport.responseText });
27 + var announcementBoxes = $$(".announcementbox");
28 + if(announcementBoxes.length!=0)
29 + announcementBoxes[0].show();
30 + Announcement.registerRefreshEventTimer();
31 + }
32 + }
33 + });
34 + },
35 +
36 + registerRefreshEventTimer: function() {
37 + setTimeout(function () {
38 + Announcement.refreshAnnouncement();
39 + }, 30000);
40 + }
41 + };
This diff has been collapsed as it changes many lines, (1128 lines changed) Show them Hide them
@@ -0,0 +1,1128
1 + // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2 + // Contributors:
3 + // Justin Palmer (http://encytemedia.com/)
4 + // Mark Pilgrim (http://diveintomark.org/)
5 + // Martin Bialasinki
6 + //
7 + // script.aculo.us is freely distributable under the terms of an MIT-style license.
8 + // For details, see the script.aculo.us web site: http://script.aculo.us/
9 +
10 + // converts rgb() and #xxx to #xxxxxx format,
11 + // returns self (or first argument) if not convertable
12 + String.prototype.parseColor = function() {
13 + var color = '#';
14 + if (this.slice(0,4) == 'rgb(') {
15 + var cols = this.slice(4,this.length-1).split(',');
16 + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
17 + } else {
18 + if (this.slice(0,1) == '#') {
19 + if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
20 + if (this.length==7) color = this.toLowerCase();
21 + }
22 + }
23 + return (color.length==7 ? color : (arguments[0] || this));
24 + };
25 +
26 + /*--------------------------------------------------------------------------*/
27 +
28 + Element.collectTextNodes = function(element) {
29 + return $A($(element).childNodes).collect( function(node) {
30 + return (node.nodeType==3 ? node.nodeValue :
31 + (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
32 + }).flatten().join('');
33 + };
34 +
35 + Element.collectTextNodesIgnoreClass = function(element, className) {
36 + return $A($(element).childNodes).collect( function(node) {
37 + return (node.nodeType==3 ? node.nodeValue :
38 + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
39 + Element.collectTextNodesIgnoreClass(node, className) : ''));
40 + }).flatten().join('');
41 + };
42 +
43 + Element.setContentZoom = function(element, percent) {
44 + element = $(element);
45 + element.setStyle({fontSize: (percent/100) + 'em'});
46 + if (Prototype.Browser.WebKit) window.scrollBy(0,0);
47 + return element;
48 + };
49 +
50 + Element.getInlineOpacity = function(element){
51 + return $(element).style.opacity || '';
52 + };
53 +
54 + Element.forceRerendering = function(element) {
55 + try {
56 + element = $(element);
57 + var n = document.createTextNode(' ');
58 + element.appendChild(n);
59 + element.removeChild(n);
60 + } catch(e) { }
61 + };
62 +
63 + /*--------------------------------------------------------------------------*/
64 +
65 + var Effect = {
66 + _elementDoesNotExistError: {
67 + name: 'ElementDoesNotExistError',
68 + message: 'The specified DOM element does not exist, but is required for this effect to operate'
69 + },
70 + Transitions: {
71 + linear: Prototype.K,
72 + sinoidal: function(pos) {
73 + return (-Math.cos(pos*Math.PI)/2) + .5;
74 + },
75 + reverse: function(pos) {
76 + return 1-pos;
77 + },
78 + flicker: function(pos) {
79 + var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
80 + return pos > 1 ? 1 : pos;
81 + },
82 + wobble: function(pos) {
83 + return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
84 + },
85 + pulse: function(pos, pulses) {
86 + return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
87 + },
88 + spring: function(pos) {
89 + return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
90 + },
91 + none: function(pos) {
92 + return 0;
93 + },
94 + full: function(pos) {
95 + return 1;
96 + }
97 + },
98 + DefaultOptions: {
99 + duration: 1.0, // seconds
100 + fps: 100, // 100= assume 66fps max.
101 + sync: false, // true for combining
102 + from: 0.0,
103 + to: 1.0,
104 + delay: 0.0,
105 + queue: 'parallel'
106 + },
107 + tagifyText: function(element) {
108 + var tagifyStyle = 'position:relative';
109 + if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
110 +
111 + element = $(element);
112 + $A(element.childNodes).each( function(child) {
113 + if (child.nodeType==3) {
114 + child.nodeValue.toArray().each( function(character) {
115 + element.insertBefore(
116 + new Element('span', {style: tagifyStyle}).update(
117 + character == ' ' ? String.fromCharCode(160) : character),
118 + child);
119 + });
120 + Element.remove(child);
121 + }
122 + });
123 + },
124 + multiple: function(element, effect) {
125 + var elements;
126 + if (((typeof element == 'object') ||
127 + Object.isFunction(element)) &&
128 + (element.length))
129 + elements = element;
130 + else
131 + elements = $(element).childNodes;
132 +
133 + var options = Object.extend({
134 + speed: 0.1,
135 + delay: 0.0
136 + }, arguments[2] || { });
137 + var masterDelay = options.delay;
138 +
139 + $A(elements).each( function(element, index) {
140 + new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
141 + });
142 + },
143 + PAIRS: {
144 + 'slide': ['SlideDown','SlideUp'],
145 + 'blind': ['BlindDown','BlindUp'],
146 + 'appear': ['Appear','Fade']
147 + },
148 + toggle: function(element, effect) {
149 + element = $(element);
150 + effect = (effect || 'appear').toLowerCase();
151 + var options = Object.extend({
152 + queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
153 + }, arguments[2] || { });
154 + Effect[element.visible() ?
155 + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
156 + }
157 + };
158 +
159 + Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
160 +
161 + /* ------------- core effects ------------- */
162 +
163 + Effect.ScopedQueue = Class.create(Enumerable, {
164 + initialize: function() {
165 + this.effects = [];
166 + this.interval = null;
167 + },
168 + _each: function(iterator) {
169 + this.effects._each(iterator);
170 + },
171 + add: function(effect) {
172 + var timestamp = new Date().getTime();
173 +
174 + var position = Object.isString(effect.options.queue) ?
175 + effect.options.queue : effect.options.queue.position;
176 +
177 + switch(position) {
178 + case 'front':
179 + // move unstarted effects after this effect
180 + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
181 + e.startOn += effect.finishOn;
182 + e.finishOn += effect.finishOn;
183 + });
184 + break;
185 + case 'with-last':
186 + timestamp = this.effects.pluck('startOn').max() || timestamp;
187 + break;
188 + case 'end':
189 + // start effect after last queued effect has finished
190 + timestamp = this.effects.pluck('finishOn').max() || timestamp;
191 + break;
192 + }
193 +
194 + effect.startOn += timestamp;
195 + effect.finishOn += timestamp;
196 +
197 + if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
198 + this.effects.push(effect);
199 +
200 + if (!this.interval)
201 + this.interval = setInterval(this.loop.bind(this), 15);
202 + },
203 + remove: function(effect) {
204 + this.effects = this.effects.reject(function(e) { return e==effect });
205 + if (this.effects.length == 0) {
206 + clearInterval(this.interval);
207 + this.interval = null;
208 + }
209 + },
210 + loop: function() {
211 + var timePos = new Date().getTime();
212 + for(var i=0, len=this.effects.length;i<len;i++)
213 + this.effects[i] && this.effects[i].loop(timePos);
214 + }
215 + });
216 +
217 + Effect.Queues = {
218 + instances: $H(),
219 + get: function(queueName) {
220 + if (!Object.isString(queueName)) return queueName;
221 +
222 + return this.instances.get(queueName) ||
223 + this.instances.set(queueName, new Effect.ScopedQueue());
224 + }
225 + };
226 + Effect.Queue = Effect.Queues.get('global');
227 +
228 + Effect.Base = Class.create({
229 + position: null,
230 + start: function(options) {
231 + function codeForEvent(options,eventName){
232 + return (
233 + (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
234 + (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
235 + );
236 + }
237 + if (options && options.transition === false) options.transition = Effect.Transitions.linear;
238 + this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
239 + this.currentFrame = 0;
240 + this.state = 'idle';
241 + this.startOn = this.options.delay*1000;
242 + this.finishOn = this.startOn+(this.options.duration*1000);
243 + this.fromToDelta = this.options.to-this.options.from;
244 + this.totalTime = this.finishOn-this.startOn;
245 + this.totalFrames = this.options.fps*this.options.duration;
246 +
247 + this.render = (function() {
248 + function dispatch(effect, eventName) {
249 + if (effect.options[eventName + 'Internal'])
250 + effect.options[eventName + 'Internal'](effect);
251 + if (effect.options[eventName])
252 + effect.options[eventName](effect);
253 + }
254 +
255 + return function(pos) {
256 + if (this.state === "idle") {
257 + this.state = "running";
258 + dispatch(this, 'beforeSetup');
259 + if (this.setup) this.setup();
260 + dispatch(this, 'afterSetup');
261 + }
262 + if (this.state === "running") {
263 + pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
264 + this.position = pos;
265 + dispatch(this, 'beforeUpdate');
266 + if (this.update) this.update(pos);
267 + dispatch(this, 'afterUpdate');
268 + }
269 + };
270 + })();
271 +
272 + this.event('beforeStart');
273 + if (!this.options.sync)
274 + Effect.Queues.get(Object.isString(this.options.queue) ?
275 + 'global' : this.options.queue.scope).add(this);
276 + },
277 + loop: function(timePos) {
278 + if (timePos >= this.startOn) {
279 + if (timePos >= this.finishOn) {
280 + this.render(1.0);
281 + this.cancel();
282 + this.event('beforeFinish');
283 + if (this.finish) this.finish();
284 + this.event('afterFinish');
285 + return;
286 + }
287 + var pos = (timePos - this.startOn) / this.totalTime,
288 + frame = (pos * this.totalFrames).round();
289 + if (frame > this.currentFrame) {
290 + this.render(pos);
291 + this.currentFrame = frame;
292 + }
293 + }
294 + },
295 + cancel: function() {
296 + if (!this.options.sync)
297 + Effect.Queues.get(Object.isString(this.options.queue) ?
298 + 'global' : this.options.queue.scope).remove(this);
299 + this.state = 'finished';
300 + },
301 + event: function(eventName) {
302 + if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
303 + if (this.options[eventName]) this.options[eventName](this);
304 + },
305 + inspect: function() {
306 + var data = $H();
307 + for(property in this)
308 + if (!Object.isFunction(this[property])) data.set(property, this[property]);
309 + return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
310 + }
311 + });
312 +
313 + Effect.Parallel = Class.create(Effect.Base, {
314 + initialize: function(effects) {
315 + this.effects = effects || [];
316 + this.start(arguments[1]);
317 + },
318 + update: function(position) {
319 + this.effects.invoke('render', position);
320 + },
321 + finish: function(position) {
322 + this.effects.each( function(effect) {
323 + effect.render(1.0);
324 + effect.cancel();
325 + effect.event('beforeFinish');
326 + if (effect.finish) effect.finish(position);
327 + effect.event('afterFinish');
328 + });
329 + }
330 + });
331 +
332 + Effect.Tween = Class.create(Effect.Base, {
333 + initialize: function(object, from, to) {
334 + object = Object.isString(object) ? $(object) : object;
335 + var args = $A(arguments), method = args.last(),
336 + options = args.length == 5 ? args[3] : null;
337 + this.method = Object.isFunction(method) ? method.bind(object) :
338 + Object.isFunction(object[method]) ? object[method].bind(object) :
339 + function(value) { object[method] = value };
340 + this.start(Object.extend({ from: from, to: to }, options || { }));
341 + },
342 + update: function(position) {
343 + this.method(position);
344 + }
345 + });
346 +
347 + Effect.Event = Class.create(Effect.Base, {
348 + initialize: function() {
349 + this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
350 + },
351 + update: Prototype.emptyFunction
352 + });
353 +
354 + Effect.Opacity = Class.create(Effect.Base, {
355 + initialize: function(element) {
356 + this.element = $(element);
357 + if (!this.element) throw(Effect._elementDoesNotExistError);
358 + // make this work on IE on elements without 'layout'
359 + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
360 + this.element.setStyle({zoom: 1});
361 + var options = Object.extend({
362 + from: this.element.getOpacity() || 0.0,
363 + to: 1.0
364 + }, arguments[1] || { });
365 + this.start(options);
366 + },
367 + update: function(position) {
368 + this.element.setOpacity(position);
369 + }
370 + });
371 +
372 + Effect.Move = Class.create(Effect.Base, {
373 + initialize: function(element) {
374 + this.element = $(element);
375 + if (!this.element) throw(Effect._elementDoesNotExistError);
376 + var options = Object.extend({
377 + x: 0,
378 + y: 0,
379 + mode: 'relative'
380 + }, arguments[1] || { });
381 + this.start(options);
382 + },
383 + setup: function() {
384 + this.element.makePositioned();
385 + this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
386 + this.originalTop = parseFloat(this.element.getStyle('top') || '0');
387 + if (this.options.mode == 'absolute') {
388 + this.options.x = this.options.x - this.originalLeft;
389 + this.options.y = this.options.y - this.originalTop;
390 + }
391 + },
392 + update: function(position) {
393 + this.element.setStyle({
394 + left: (this.options.x * position + this.originalLeft).round() + 'px',
395 + top: (this.options.y * position + this.originalTop).round() + 'px'
396 + });
397 + }
398 + });
399 +
400 + // for backwards compatibility
401 + Effect.MoveBy = function(element, toTop, toLeft) {
402 + return new Effect.Move(element,
403 + Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
404 + };
405 +
406 + Effect.Scale = Class.create(Effect.Base, {
407 + initialize: function(element, percent) {
408 + this.element = $(element);
409 + if (!this.element) throw(Effect._elementDoesNotExistError);
410 + var options = Object.extend({
411 + scaleX: true,
412 + scaleY: true,
413 + scaleContent: true,
414 + scaleFromCenter: false,
415 + scaleMode: 'box', // 'box' or 'contents' or { } with provided values
416 + scaleFrom: 100.0,
417 + scaleTo: percent
418 + }, arguments[2] || { });
419 + this.start(options);
420 + },
421 + setup: function() {
422 + this.restoreAfterFinish = this.options.restoreAfterFinish || false;
423 + this.elementPositioning = this.element.getStyle('position');
424 +
425 + this.originalStyle = { };
426 + ['top','left','width','height','fontSize'].each( function(k) {
427 + this.originalStyle[k] = this.element.style[k];
428 + }.bind(this));
429 +
430 + this.originalTop = this.element.offsetTop;
431 + this.originalLeft = this.element.offsetLeft;
432 +
433 + var fontSize = this.element.getStyle('font-size') || '100%';
434 + ['em','px','%','pt'].each( function(fontSizeType) {
435 + if (fontSize.indexOf(fontSizeType)>0) {
436 + this.fontSize = parseFloat(fontSize);
437 + this.fontSizeType = fontSizeType;
438 + }
439 + }.bind(this));
440 +
441 + this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
442 +
443 + this.dims = null;
444 + if (this.options.scaleMode=='box')
445 + this.dims = [this.element.offsetHeight, this.element.offsetWidth];
446 + if (/^content/.test(this.options.scaleMode))
447 + this.dims = [this.element.scrollHeight, this.element.scrollWidth];
448 + if (!this.dims)
449 + this.dims = [this.options.scaleMode.originalHeight,
450 + this.options.scaleMode.originalWidth];
451 + },
452 + update: function(position) {
453 + var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
454 + if (this.options.scaleContent && this.fontSize)
455 + this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
456 + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
457 + },
458 + finish: function(position) {
459 + if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
460 + },
461 + setDimensions: function(height, width) {
462 + var d = { };
463 + if (this.options.scaleX) d.width = width.round() + 'px';
464 + if (this.options.scaleY) d.height = height.round() + 'px';
465 + if (this.options.scaleFromCenter) {
466 + var topd = (height - this.dims[0])/2;
467 + var leftd = (width - this.dims[1])/2;
468 + if (this.elementPositioning == 'absolute') {
469 + if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
470 + if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
471 + } else {
472 + if (this.options.scaleY) d.top = -topd + 'px';
473 + if (this.options.scaleX) d.left = -leftd + 'px';
474 + }
475 + }
476 + this.element.setStyle(d);
477 + }
478 + });
479 +
480 + Effect.Highlight = Class.create(Effect.Base, {
481 + initialize: function(element) {
482 + this.element = $(element);
483 + if (!this.element) throw(Effect._elementDoesNotExistError);
484 + var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
485 + this.start(options);
486 + },
487 + setup: function() {
488 + // Prevent executing on elements not in the layout flow
489 + if (this.element.getStyle('display')=='none') { this.cancel(); return; }
490 + // Disable background image during the effect
491 + this.oldStyle = { };
492 + if (!this.options.keepBackgroundImage) {
493 + this.oldStyle.backgroundImage = this.element.getStyle('background-image');
494 + this.element.setStyle({backgroundImage: 'none'});
495 + }
496 + if (!this.options.endcolor)
497 + this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
498 + if (!this.options.restorecolor)
499 + this.options.restorecolor = this.element.getStyle('background-color');
500 + // init color calculations
501 + this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
502 + this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
503 + },
504 + update: function(position) {
505 + this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
506 + return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
507 + },
508 + finish: function() {
509 + this.element.setStyle(Object.extend(this.oldStyle, {
510 + backgroundColor: this.options.restorecolor
511 + }));
512 + }
513 + });
514 +
515 + Effect.ScrollTo = function(element) {
516 + var options = arguments[1] || { },
517 + scrollOffsets = document.viewport.getScrollOffsets(),
518 + elementOffsets = $(element).cumulativeOffset();
519 +
520 + if (options.offset) elementOffsets[1] += options.offset;
521 +
522 + return new Effect.Tween(null,
523 + scrollOffsets.top,
524 + elementOffsets[1],
525 + options,
526 + function(p){ scrollTo(scrollOffsets.left, p.round()); }
527 + );
528 + };
529 +
530 + /* ------------- combination effects ------------- */
531 +
532 + Effect.Fade = function(element) {
533 + element = $(element);
534 + var oldOpacity = element.getInlineOpacity();
535 + var options = Object.extend({
536 + from: element.getOpacity() || 1.0,
537 + to: 0.0,
538 + afterFinishInternal: function(effect) {
539 + if (effect.options.to!=0) return;
540 + effect.element.hide().setStyle({opacity: oldOpacity});
541 + }
542 + }, arguments[1] || { });
543 + return new Effect.Opacity(element,options);
544 + };
545 +
546 + Effect.Appear = function(element) {
547 + element = $(element);
548 + var options = Object.extend({
549 + from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
550 + to: 1.0,
551 + // force Safari to render floated elements properly
552 + afterFinishInternal: function(effect) {
553 + effect.element.forceRerendering();
554 + },
555 + beforeSetup: function(effect) {
556 + effect.element.setOpacity(effect.options.from).show();
557 + }}, arguments[1] || { });
558 + return new Effect.Opacity(element,options);
559 + };
560 +
561 + Effect.Puff = function(element) {
562 + element = $(element);
563 + var oldStyle = {
564 + opacity: element.getInlineOpacity(),
565 + position: element.getStyle('position'),
566 + top: element.style.top,
567 + left: element.style.left,
568 + width: element.style.width,
569 + height: element.style.height
570 + };
571 + return new Effect.Parallel(
572 + [ new Effect.Scale(element, 200,
573 + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
574 + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
575 + Object.extend({ duration: 1.0,
576 + beforeSetupInternal: function(effect) {
577 + Position.absolutize(effect.effects[0].element);
578 + },
579 + afterFinishInternal: function(effect) {
580 + effect.effects[0].element.hide().setStyle(oldStyle); }
581 + }, arguments[1] || { })
582 + );
583 + };
584 +
585 + Effect.BlindUp = function(element) {
586 + element = $(element);
587 + element.makeClipping();
588 + return new Effect.Scale(element, 0,
589 + Object.extend({ scaleContent: false,
590 + scaleX: false,
591 + restoreAfterFinish: true,
592 + afterFinishInternal: function(effect) {
593 + effect.element.hide().undoClipping();
594 + }
595 + }, arguments[1] || { })
596 + );
597 + };
598 +
599 + Effect.BlindDown = function(element) {
600 + element = $(element);
601 + var elementDimensions = element.getDimensions();
602 + return new Effect.Scale(element, 100, Object.extend({
603 + scaleContent: false,
604 + scaleX: false,
605 + scaleFrom: 0,
606 + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
607 + restoreAfterFinish: true,
608 + afterSetup: function(effect) {
609 + effect.element.makeClipping().setStyle({height: '0px'}).show();
610 + },
611 + afterFinishInternal: function(effect) {
612 + effect.element.undoClipping();
613 + }
614 + }, arguments[1] || { }));
615 + };
616 +
617 + Effect.SwitchOff = function(element) {
618 + element = $(element);
619 + var oldOpacity = element.getInlineOpacity();
620 + return new Effect.Appear(element, Object.extend({
621 + duration: 0.4,
622 + from: 0,
623 + transition: Effect.Transitions.flicker,
624 + afterFinishInternal: function(effect) {
625 + new Effect.Scale(effect.element, 1, {
626 + duration: 0.3, scaleFromCenter: true,
627 + scaleX: false, scaleContent: false, restoreAfterFinish: true,
628 + beforeSetup: function(effect) {
629 + effect.element.makePositioned().makeClipping();
630 + },
631 + afterFinishInternal: function(effect) {
632 + effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
633 + }
634 + });
635 + }
636 + }, arguments[1] || { }));
637 + };
638 +
639 + Effect.DropOut = function(element) {
640 + element = $(element);
641 + var oldStyle = {
642 + top: element.getStyle('top'),
643 + left: element.getStyle('left'),
644 + opacity: element.getInlineOpacity() };
645 + return new Effect.Parallel(
646 + [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
647 + new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
648 + Object.extend(
649 + { duration: 0.5,
650 + beforeSetup: function(effect) {
651 + effect.effects[0].element.makePositioned();
652 + },
653 + afterFinishInternal: function(effect) {
654 + effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
655 + }
656 + }, arguments[1] || { }));
657 + };
658 +
659 + Effect.Shake = function(element) {
660 + element = $(element);
661 + var options = Object.extend({
662 + distance: 20,
663 + duration: 0.5
664 + }, arguments[1] || {});
665 + var distance = parseFloat(options.distance);
666 + var split = parseFloat(options.duration) / 10.0;
667 + var oldStyle = {
668 + top: element.getStyle('top'),
669 + left: element.getStyle('left') };
670 + return new Effect.Move(element,
671 + { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
672 + new Effect.Move(effect.element,
673 + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
674 + new Effect.Move(effect.element,
675 + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
676 + new Effect.Move(effect.element,
677 + { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
678 + new Effect.Move(effect.element,
679 + { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
680 + new Effect.Move(effect.element,
681 + { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
682 + effect.element.undoPositioned().setStyle(oldStyle);
683 + }}); }}); }}); }}); }}); }});
684 + };
685 +
686 + Effect.SlideDown = function(element) {
687 + element = $(element).cleanWhitespace();
688 + // SlideDown need to have the content of the element wrapped in a container element with fixed height!
689 + var oldInnerBottom = element.down().getStyle('bottom');
690 + var elementDimensions = element.getDimensions();
691 + return new Effect.Scale(element, 100, Object.extend({
692 + scaleContent: false,
693 + scaleX: false,
694 + scaleFrom: window.opera ? 0 : 1,
695 + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
696 + restoreAfterFinish: true,
697 + afterSetup: function(effect) {
698 + effect.element.makePositioned();
699 + effect.element.down().makePositioned();
700 + if (window.opera) effect.element.setStyle({top: ''});
701 + effect.element.makeClipping().setStyle({height: '0px'}).show();
702 + },
703 + afterUpdateInternal: function(effect) {
704 + effect.element.down().setStyle({bottom:
705 + (effect.dims[0] - effect.element.clientHeight) + 'px' });
706 + },
707 + afterFinishInternal: function(effect) {
708 + effect.element.undoClipping().undoPositioned();
709 + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
710 + }, arguments[1] || { })
711 + );
712 + };
713 +
714 + Effect.SlideUp = function(element) {
715 + element = $(element).cleanWhitespace();
716 + var oldInnerBottom = element.down().getStyle('bottom');
717 + var elementDimensions = element.getDimensions();
718 + return new Effect.Scale(element, window.opera ? 0 : 1,
719 + Object.extend({ scaleContent: false,
720 + scaleX: false,
721 + scaleMode: 'box',
722 + scaleFrom: 100,
723 + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
724 + restoreAfterFinish: true,
725 + afterSetup: function(effect) {
726 + effect.element.makePositioned();
727 + effect.element.down().makePositioned();
728 + if (window.opera) effect.element.setStyle({top: ''});
729 + effect.element.makeClipping().show();
730 + },
731 + afterUpdateInternal: function(effect) {
732 + effect.element.down().setStyle({bottom:
733 + (effect.dims[0] - effect.element.clientHeight) + 'px' });
734 + },
735 + afterFinishInternal: function(effect) {
736 + effect.element.hide().undoClipping().undoPositioned();
737 + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
738 + }
739 + }, arguments[1] || { })
740 + );
741 + };
742 +
743 + // Bug in opera makes the TD containing this element expand for a instance after finish
744 + Effect.Squish = function(element) {
745 + return new Effect.Scale(element, window.opera ? 1 : 0, {
746 + restoreAfterFinish: true,
747 + beforeSetup: function(effect) {
748 + effect.element.makeClipping();
749 + },
750 + afterFinishInternal: function(effect) {
751 + effect.element.hide().undoClipping();
752 + }
753 + });
754 + };
755 +
756 + Effect.Grow = function(element) {
757 + element = $(element);
758 + var options = Object.extend({
759 + direction: 'center',
760 + moveTransition: Effect.Transitions.sinoidal,
761 + scaleTransition: Effect.Transitions.sinoidal,
762 + opacityTransition: Effect.Transitions.full
763 + }, arguments[1] || { });
764 + var oldStyle = {
765 + top: element.style.top,
766 + left: element.style.left,
767 + height: element.style.height,
768 + width: element.style.width,
769 + opacity: element.getInlineOpacity() };
770 +
771 + var dims = element.getDimensions();
772 + var initialMoveX, initialMoveY;
773 + var moveX, moveY;
774 +
775 + switch (options.direction) {
776 + case 'top-left':
777 + initialMoveX = initialMoveY = moveX = moveY = 0;
778 + break;
779 + case 'top-right':
780 + initialMoveX = dims.width;
781 + initialMoveY = moveY = 0;
782 + moveX = -dims.width;
783 + break;
784 + case 'bottom-left':
785 + initialMoveX = moveX = 0;
786 + initialMoveY = dims.height;
787 + moveY = -dims.height;
788 + break;
789 + case 'bottom-right':
790 + initialMoveX = dims.width;
791 + initialMoveY = dims.height;
792 + moveX = -dims.width;
793 + moveY = -dims.height;
794 + break;
795 + case 'center':
796 + initialMoveX = dims.width / 2;
797 + initialMoveY = dims.height / 2;
798 + moveX = -dims.width / 2;
799 + moveY = -dims.height / 2;
800 + break;
801 + }
802 +
803 + return new Effect.Move(element, {
804 + x: initialMoveX,
805 + y: initialMoveY,
806 + duration: 0.01,
807 + beforeSetup: function(effect) {
808 + effect.element.hide().makeClipping().makePositioned();
809 + },
810 + afterFinishInternal: function(effect) {
811 + new Effect.Parallel(
812 + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
813 + new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
814 + new Effect.Scale(effect.element, 100, {
815 + scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
816 + sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
817 + ], Object.extend({
818 + beforeSetup: function(effect) {
819 + effect.effects[0].element.setStyle({height: '0px'}).show();
820 + },
821 + afterFinishInternal: function(effect) {
822 + effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
823 + }
824 + }, options)
825 + );
826 + }
827 + });
828 + };
829 +
830 + Effect.Shrink = function(element) {
831 + element = $(element);
832 + var options = Object.extend({
833 + direction: 'center',
834 + moveTransition: Effect.Transitions.sinoidal,
835 + scaleTransition: Effect.Transitions.sinoidal,
836 + opacityTransition: Effect.Transitions.none
837 + }, arguments[1] || { });
838 + var oldStyle = {
839 + top: element.style.top,
840 + left: element.style.left,
841 + height: element.style.height,
842 + width: element.style.width,
843 + opacity: element.getInlineOpacity() };
844 +
845 + var dims = element.getDimensions();
846 + var moveX, moveY;
847 +
848 + switch (options.direction) {
849 + case 'top-left':
850 + moveX = moveY = 0;
851 + break;
852 + case 'top-right':
853 + moveX = dims.width;
854 + moveY = 0;
855 + break;
856 + case 'bottom-left':
857 + moveX = 0;
858 + moveY = dims.height;
859 + break;
860 + case 'bottom-right':
861 + moveX = dims.width;
862 + moveY = dims.height;
863 + break;
864 + case 'center':
865 + moveX = dims.width / 2;
866 + moveY = dims.height / 2;
867 + break;
868 + }
869 +
870 + return new Effect.Parallel(
871 + [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
872 + new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
873 + new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
874 + ], Object.extend({
875 + beforeStartInternal: function(effect) {
876 + effect.effects[0].element.makePositioned().makeClipping();
877 + },
878 + afterFinishInternal: function(effect) {
879 + effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
880 + }, options)
881 + );
882 + };
883 +
884 + Effect.Pulsate = function(element) {
885 + element = $(element);
886 + var options = arguments[1] || { },
887 + oldOpacity = element.getInlineOpacity(),
888 + transition = options.transition || Effect.Transitions.linear,
889 + reverser = function(pos){
890 + return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
891 + };
892 +
893 + return new Effect.Opacity(element,
894 + Object.extend(Object.extend({ duration: 2.0, from: 0,
895 + afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
896 + }, options), {transition: reverser}));
897 + };
898 +
899 + Effect.Fold = function(element) {
900 + element = $(element);
901 + var oldStyle = {
902 + top: element.style.top,
903 + left: element.style.left,
904 + width: element.style.width,
905 + height: element.style.height };
906 + element.makeClipping();
907 + return new Effect.Scale(element, 5, Object.extend({
908 + scaleContent: false,
909 + scaleX: false,
910 + afterFinishInternal: function(effect) {
911 + new Effect.Scale(element, 1, {
912 + scaleContent: false,
913 + scaleY: false,
914 + afterFinishInternal: function(effect) {
915 + effect.element.hide().undoClipping().setStyle(oldStyle);
916 + } });
917 + }}, arguments[1] || { }));
918 + };
919 +
920 + Effect.Morph = Class.create(Effect.Base, {
921 + initialize: function(element) {
922 + this.element = $(element);
923 + if (!this.element) throw(Effect._elementDoesNotExistError);
924 + var options = Object.extend({
925 + style: { }
926 + }, arguments[1] || { });
927 +
928 + if (!Object.isString(options.style)) this.style = $H(options.style);
929 + else {
930 + if (options.style.include(':'))
931 + this.style = options.style.parseStyle();
932 + else {
933 + this.element.addClassName(options.style);
934 + this.style = $H(this.element.getStyles());
935 + this.element.removeClassName(options.style);
936 + var css = this.element.getStyles();
937 + this.style = this.style.reject(function(style) {
938 + return style.value == css[style.key];
939 + });
940 + options.afterFinishInternal = function(effect) {
941 + effect.element.addClassName(effect.options.style);
942 + effect.transforms.each(function(transform) {
943 + effect.element.style[transform.style] = '';
944 + });
945 + };
946 + }
947 + }
948 + this.start(options);
949 + },
950 +
951 + setup: function(){
952 + function parseColor(color){
953 + if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
954 + color = color.parseColor();
955 + return $R(0,2).map(function(i){
956 + return parseInt( color.slice(i*2+1,i*2+3), 16 );
957 + });
958 + }
959 + this.transforms = this.style.map(function(pair){
960 + var property = pair[0], value = pair[1], unit = null;
961 +
962 + if (value.parseColor('#zzzzzz') != '#zzzzzz') {
963 + value = value.parseColor();
964 + unit = 'color';
965 + } else if (property == 'opacity') {
966 + value = parseFloat(value);
967 + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
968 + this.element.setStyle({zoom: 1});
969 + } else if (Element.CSS_LENGTH.test(value)) {
970 + var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
971 + value = parseFloat(components[1]);
972 + unit = (components.length == 3) ? components[2] : null;
973 + }
974 +
975 + var originalValue = this.element.getStyle(property);
976 + return {
977 + style: property.camelize(),
978 + originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
979 + targetValue: unit=='color' ? parseColor(value) : value,
980 + unit: unit
981 + };
982 + }.bind(this)).reject(function(transform){
983 + return (
984 + (transform.originalValue == transform.targetValue) ||
985 + (
986 + transform.unit != 'color' &&
987 + (isNaN(transform.originalValue) || isNaN(transform.targetValue))
988 + )
989 + );
990 + });
991 + },
992 + update: function(position) {
993 + var style = { }, transform, i = this.transforms.length;
994 + while(i--)
995 + style[(transform = this.transforms[i]).style] =
996 + transform.unit=='color' ? '#'+
997 + (Math.round(transform.originalValue[0]+
998 + (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
999 + (Math.round(transform.originalValue[1]+
1000 + (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
1001 + (Math.round(transform.originalValue[2]+
1002 + (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
1003 + (transform.originalValue +
1004 + (transform.targetValue - transform.originalValue) * position).toFixed(3) +
1005 + (transform.unit === null ? '' : transform.unit);
1006 + this.element.setStyle(style, true);
1007 + }
1008 + });
1009 +
1010 + Effect.Transform = Class.create({
1011 + initialize: function(tracks){
1012 + this.tracks = [];
1013 + this.options = arguments[1] || { };
1014 + this.addTracks(tracks);
1015 + },
1016 + addTracks: function(tracks){
1017 + tracks.each(function(track){
1018 + track = $H(track);
1019 + var data = track.values().first();
1020 + this.tracks.push($H({
1021 + ids: track.keys().first(),
1022 + effect: Effect.Morph,
1023 + options: { style: data }
1024 + }));
1025 + }.bind(this));
1026 + return this;
1027 + },
1028 + play: function(){
1029 + return new Effect.Parallel(
1030 + this.tracks.map(function(track){
1031 + var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
1032 + var elements = [$(ids) || $$(ids)].flatten();
1033 + return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
1034 + }).flatten(),
1035 + this.options
1036 + );
1037 + }
1038 + });
1039 +
1040 + Element.CSS_PROPERTIES = $w(
1041 + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
1042 + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
1043 + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
1044 + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
1045 + 'fontSize fontWeight height left letterSpacing lineHeight ' +
1046 + 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
1047 + 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
1048 + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
1049 + 'right textIndent top width wordSpacing zIndex');
1050 +
1051 + Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
1052 +
1053 + String.__parseStyleElement = document.createElement('div');
1054 + String.prototype.parseStyle = function(){
1055 + var style, styleRules = $H();
1056 + if (Prototype.Browser.WebKit)
1057 + style = new Element('div',{style:this}).style;
1058 + else {
1059 + String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
1060 + style = String.__parseStyleElement.childNodes[0].style;
1061 + }
1062 +
1063 + Element.CSS_PROPERTIES.each(function(property){
1064 + if (style[property]) styleRules.set(property, style[property]);
1065 + });
1066 +
1067 + if (Prototype.Browser.IE && this.include('opacity'))
1068 + styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
1069 +
1070 + return styleRules;
1071 + };
1072 +
1073 + if (document.defaultView && document.defaultView.getComputedStyle) {
1074 + Element.getStyles = function(element) {
1075 + var css = document.defaultView.getComputedStyle($(element), null);
1076 + return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
1077 + styles[property] = css[property];
1078 + return styles;
1079 + });
1080 + };
1081 + } else {
1082 + Element.getStyles = function(element) {
1083 + element = $(element);
1084 + var css = element.currentStyle, styles;
1085 + styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
1086 + results[property] = css[property];
1087 + return results;
1088 + });
1089 + if (!styles.opacity) styles.opacity = element.getOpacity();
1090 + return styles;
1091 + };
1092 + }
1093 +
1094 + Effect.Methods = {
1095 + morph: function(element, style) {
1096 + element = $(element);
1097 + new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
1098 + return element;
1099 + },
1100 + visualEffect: function(element, effect, options) {
1101 + element = $(element);
1102 + var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
1103 + new Effect[klass](element, options);
1104 + return element;
1105 + },
1106 + highlight: function(element, options) {
1107 + element = $(element);
1108 + new Effect.Highlight(element, options);
1109 + return element;
1110 + }
1111 + };
1112 +
1113 + $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
1114 + 'pulsate shake puff squish switchOff dropOut').each(
1115 + function(effect) {
1116 + Effect.Methods[effect] = function(element, options){
1117 + element = $(element);
1118 + Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
1119 + return element;
1120 + };
1121 + }
1122 + );
1123 +
1124 + $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
1125 + function(f) { Effect.Methods[f] = Element[f]; }
1126 + );
1127 +
1128 + Element.addMethods(Effect.Methods); No newline at end of file
@@ -0,0 +1,32
1 + function updateSiteList() {
2 + currentCountry = document.getElementById("site_country_id").value;
3 +
4 + sites = siteList[currentCountry];
5 + siteSelect = document.getElementById("login_site_id");
6 + old_len = siteSelect.length;
7 + // clear old box
8 + for(i=0; i<old_len; i++) siteSelect.remove(0);
9 +
10 + if(currentCountry==0) {
11 + for(i=0; i<allSiteList.length; i++) {
12 + if(allSiteList[i]!=null) {
13 + try {
14 + siteSelect.add(new Option(allSiteList[i],""+i,false,false),null);
15 + } catch(ex) {
16 + siteSelect.add(new Option(allSiteList[i],""+i,false,false));
17 + }
18 + }
19 + }
20 + } else {
21 + for(i=0; i<sites.length; i++) {
22 + if(sites[i]!=null) {
23 + try {
24 + siteSelect.add(new Option(sites[i],""+i,false,false),null);
25 + } catch(ex) {
26 + siteSelect.add(new Option(sites[i],""+i,false,false));
27 + }
28 + }
29 + }
30 + }
31 + }
32 + No newline at end of file
@@ -0,0 +1,17
1 +
2 + table.graders tr.active {
3 + border: 1px solid black;
4 + background: lightgreen;
5 + text-align: center;
6 + }
7 +
8 + table.graders tr.inactive {
9 + border: 1px solid black;
10 + background: #ffcccc;
11 + text-align: center;
12 + }
13 +
14 + .submitbox .item {
15 + padding-right: 5px;
16 + float: left;
17 + }
@@ -0,0 +1,14
1 +
2 + tr.available {
3 + background: #c0ffc0;
4 + }
5 +
6 + tr.not-available {
7 + background: #ffc0c0;
8 + }
9 +
10 + .import-log {
11 + background: lightgray;
12 + border: solid black 1px;
13 + padding: 10px;
14 + } No newline at end of file
@@ -29,20 +29,20
29 29
30 30 # Use unicorn as the app server
31 31 # gem 'unicorn'
32 32
33 33 # Deploy with Capistrano
34 34 # gem 'capistrano'
35 35
36 36 # To use debugger
37 37 # gem 'debugger'
38 38
39 39 gem "haml"
40 40 gem "tmail"
41 - gem "rdiscount", :require => "rdiscount"
41 + gem "rdiscount"
42 42 gem "test-unit"
43 43 gem 'will_paginate', '~> 3.0.0'
44 44 gem 'dynamic_form'
45 45
46 46 group :test, :development do
47 47 gem "rspec-rails", "~> 2.0"
48 48 end
@@ -3,13 +3,13
3 3 //
4 4 // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 5 // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 6 //
7 7 // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 8 // the compiled file.
9 9 //
10 10 // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 11 // GO AFTER THE REQUIRES BELOW.
12 12 //
13 13 //= require prototype
14 14 //= require prototype_ujs
15 - //= require_tree .
15 +
@@ -1,13 +1,255
1 1 /*
2 - * This is a manifest file that'll be compiled into application.css, which will include all the files
3 - * listed below.
4 - *
5 - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7 - *
8 - * You're free to add application-wide styles to this file and they'll appear at the top of the
9 - * compiled file, but it's generally better to create a new file per style scope.
10 - *
11 - *= require_self
12 - *= require_tree .
13 - */
2 + * This is a manifest file that'll be compiled into application.css, which will include all the
3 + * listed below.
4 + *
5 + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheet
6 + * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path
7 + *
8 + * You're free to add application-wide styles to this file and they'll appear at the top of the
9 + * compiled file, but it's generally better to create a new file per style scope.
10 + *
11 + *= require_self
12 + */
13 +
14 + body {
15 + background: white url(../images/topbg.jpg) repeat-x top center;
16 + font-size: 13px;
17 + font-family: Tahoma, "sans-serif";
18 + margin: 10px;
19 + padding: 10px; }
20 +
21 + input {
22 + font-family: Tahoma, "sans-serif"; }
23 +
24 + h1 {
25 + font-size: 24px;
26 + color: #334488;
27 + line-height: 2em; }
28 +
29 + h2 {
30 + font-size: 18px;
31 + color: #5566bb;
32 + line-height: 1.5em; }
33 +
34 + hr {
35 + border-top: 1px solid #dddddd;
36 + border-bottom: 1px solid #eeeeee; }
37 +
38 + a {
39 + color: #6666cc;
40 + text-decoration: none; }
41 + a:link, a:visited {
42 + color: #6666cc;
43 + text-decoration: none; }
44 + a:hover, a:focus {
45 + color: #111166;
46 + text-decoration: none; }
47 +
48 + div.userbar {
49 + line-height: 1.5em;
50 + text-align: right;
51 + font-size: 12px; }
52 + div.title {
53 + padding: 10px 0px;
54 + line-height: 1.5em;
55 + font-size: 13px; }
56 + div.title span.contest-over-msg {
57 + font-size: 15px;
58 + color: red; }
59 + div.title table {
60 + width: 100%;
61 + font-weight: bold; }
62 + div.title td.left-col {
63 + text-align: left;
64 + vertical-align: top;
65 + color: #444444; }
66 + div.title td.right-col {
67 + text-align: right;
68 + vertical-align: top;
69 + font-size: 18px;
70 + color: #116699; }
71 +
72 + table.info {
73 + margin: 10px 0;
74 + border: 1px solid #666666;
75 + border-collapse: collapse;
76 + font-size: 12px; }
77 + table.info th {
78 + border: 1px solid #666666;
79 + line-height: 1.5em;
80 + padding: 0 0.5em; }
81 + table.info td {
82 + border-left: 1px solid #666666;
83 + border-right: 1px solid #666666;
84 + line-height: 1.5em;
85 + padding: 0 0.5em; }
86 +
87 + tr.info-head {
88 + background: #777777;
89 + color: white; }
90 + tr.info-odd {
91 + background: #eeeeee; }
92 + tr.info-even {
93 + background: #fcfcfc; }
94 +
95 + .infobox {
96 + background: #eeeeff;
97 + border: 1px dotted #99aaee;
98 + padding: 5px;
99 + margin: 10px 0px;
100 + color: black;
101 + font-size: 13px; }
102 +
103 + .submitbox {
104 + background: #eeeeff;
105 + border: 1px dotted #99aaee;
106 + padding: 5px;
107 + margin: 10px 0px;
108 + color: black;
109 + font-size: 13px; }
110 +
111 + .errorExplanation {
112 + border: 1px dotted gray;
113 + color: #bb2222;
114 + padding: 5px 15px 5px 15px;
115 + margin-bottom: 5px;
116 + background-color: white;
117 + font-weight: normal; }
118 + .errorExplanation h2 {
119 + color: #cc1111;
120 + font-weight: bold; }
121 +
122 + table.uinfo {
123 + border-collapse: collapse;
124 + border: 1px solid black;
125 + font-size: 13px; }
126 +
127 + td.uinfo {
128 + vertical-align: top;
129 + border: 1px solid black;
130 + padding: 5px; }
131 +
132 + th.uinfo {
133 + background: lightgreen;
134 + vertical-align: top;
135 + text-align: right;
136 + border: 1px solid black;
137 + padding: 5px; }
138 +
139 + div.compilermsgbody {
140 + font-family: monospace; }
141 + div.task-menu {
142 + text-align: center;
143 + font-size: 13px;
144 + line-height: 1.75em;
145 + font-weight: bold;
146 + border-top: 1px dashed gray;
147 + border-bottom: 1px dashed gray;
148 + margin-top: 2px;
149 + margin-bottom: 4px; }
150 +
151 + table.taskdesc {
152 + border: 2px solid #dddddd;
153 + border-collapse: collapse;
154 + margin: 10px auto;
155 + width: 90%;
156 + font-size: 13px; }
157 + table.taskdesc p {
158 + font-size: 13px; }
159 + table.taskdesc tr.name {
160 + border: 2px solid #dddddd;
161 + background: #dddddd;
162 + color: #333333;
163 + font-weight: bold;
164 + font-size: 14px;
165 + line-height: 1.5em;
166 + text-align: center; }
167 + table.taskdesc td.desc-odd {
168 + padding: 5px;
169 + padding-left: 20px;
170 + background: #fefeee; }
171 + table.taskdesc td.desc-even {
172 + padding: 5px;
173 + padding-left: 20px;
174 + background: #feeefe; }
175 +
176 + .announcementbox {
177 + margin: 10px 0px;
178 + background: #bbddee;
179 + padding: 1px; }
180 + .announcementbox span.title {
181 + font-weight: bold;
182 + color: #224455;
183 + padding-left: 10px;
184 + line-height: 1.6em; }
185 +
186 + .announcement {
187 + margin: 2px;
188 + background: white;
189 + padding: 1px;
190 + padding-left: 10px;
191 + padding-right: 10px;
192 + padding-top: 5px;
193 + padding-bottom: 5px; }
194 +
195 + .announcement p {
196 + font-size: 12px;
197 + margin: 2px; }
198 +
199 + .pub-info {
200 + text-align: right;
201 + font-style: italic;
202 + font-size: 9px; }
203 + .pub-info p {
204 + text-align: right;
205 + font-style: italic;
206 + font-size: 9px; }
207 +
208 + .announcement .toggles {
209 + font-weight: normal;
210 + float: right;
211 + font-size: 80%; }
212 + .announcement .announcement-title {
213 + font-weight: bold; }
214 +
215 + div.message {
216 + margin: 10px 0 0; }
217 + div.message div.message {
218 + margin: 0 0 0 30px; }
219 + div.message div.body {
220 + border: 2px solid #dddddd;
221 + background: #fff8f8;
222 + padding-left: 5px; }
223 + div.message div.reply-body {
224 + border: 2px solid #bbbbbb;
225 + background: #fffff8;
226 + padding-left: 5px; }
227 + div.message div.stat {
228 + font-size: 10px;
229 + line-height: 1.75em;
230 + padding: 0 5px;
231 + color: #333333;
232 + background: #dddddd;
233 + font-weight: bold; }
234 + div.message div.message div.stat {
235 + font-size: 10px;
236 + line-height: 1.75em;
237 + padding: 0 5px;
238 + color: #444444;
239 + background: #bbbbbb;
240 + font-weight: bold; }
241 + div.contest-title {
242 + color: white;
243 + text-align: center;
244 + line-height: 2em; }
245 + div.registration-desc, div.test-desc {
246 + border: 1px dotted gray;
247 + background: #f5f5f5;
248 + padding: 5px;
249 + margin: 10px 0;
250 + font-size: 12px;
251 + line-height: 1.5em; }
252 +
253 + h2.contest-title {
254 + margin-top: 5px;
255 + margin-bottom: 5px; }
@@ -116,13 +116,18
116 116 #{t 'title_bar.current_time'} #{format_short_time(Time.new)}
117 117 #{time_left}
118 118 <br/>
119 119 </td>
120 120 <td class="right-col">#{contest_name}</td>
121 121 </tr>
122 122 </table>
123 123 </div>
124 124 TITLEBAR
125 125 result.html_safe
126 126 end
127 127
128 + def markdown(text)
129 + markdown = RDiscount.new(text)
130 + markdown.to_html.html_safe
131 + end
132 +
128 133 end
@@ -1,16 +1,12
1 - <% content_for :head do %>
2 - <%= javascript_include_tag :defaults %>
3 - <% end %>
4 -
5 1 <h1>Listing announcements</h1>
6 2
7 3 <%= link_to 'New announcement', new_announcement_path %>
8 4
9 5 <table class="info">
10 6 <tr class="info-head">
11 7 <th>Updated</th>
12 8 <th>Announcement</th>
13 9 <th>Author</th>
14 10 <th>Published</th>
15 11 <th></th>
16 12 <th></th>
@@ -1,15 +1,12
1 - - content_for :head do
2 - = javascript_include_tag :defaults
3 -
4 1 %h1 System configuration
5 2
6 3 %table.info
7 4 %tr.info-head
8 5 %th Key
9 6 %th Type
10 7 %th Value
11 8 %th Description
12 9 - @configurations.each do |conf|
13 10 - @configuration = conf
14 11 %tr{:class => cycle("info-odd", "info-even")}
15 12 %td
@@ -1,31 +1,31
1 1 %h1 Contest management
2 2
3 3 .infobox
4 4
5 5 - if @num_contests>1
6 6 %b Multiple contests:
7 7 = "There are #{@num_contests} contests running."
8 8 - else
9 9 %b Single contest:
10 - = "[#{link_to 'Add/remove contests', :controller => 'contests', :action => 'index'}]"
10 + =raw "[#{link_to 'Add/remove contests', :controller => 'contests', :action => 'index'}]"
11 11
12 12 .infobox
13 13 %b Web interface mode:
14 14 - if (not GraderConfiguration.contest_mode?) and (not GraderConfiguration.indv_contest_mode?)
15 15 standard mode
16 16 - elsif GraderConfiguration.contest_mode?
17 17 normal contest mode.
18 18 - else
19 19 individual contest mode.
20 20
21 21 %br/
22 22 Change mode to:
23 - = "[#{link_to 'standard', :action => 'change_contest_mode', :id => 'standard'}]"
24 - = "[#{link_to 'contest', :action => 'change_contest_mode', :id => 'contest'}]"
25 - = "[#{link_to 'individual contest', :action => 'change_contest_mode', :id => 'indv-contest'}]"
23 + =raw "[#{link_to 'standard', :action => 'change_contest_mode', :id => 'standard'}]"
24 + =raw "[#{link_to 'contest', :action => 'change_contest_mode', :id => 'contest'}]"
25 + =raw "[#{link_to 'individual contest', :action => 'change_contest_mode', :id => 'indv-contest'}]"
26 26
27 27 - if GraderConfiguration.indv_contest_mode?
28 28 = render :partial => 'indv_contest_mode_index'
29 29
30 30 %br/
31 31
@@ -1,16 +1,12
1 - <% content_for :head do %>
2 - <%= javascript_include_tag :defaults %>
3 - <% end %>
4 -
5 1 <h1>Listing contests</h1>
6 2
7 3 <div class="infobox">
8 4 <b>Go back to:</b> [<%= link_to 'contest management', :controller => 'contest_management', :action => 'index' %>]
9 5 </div>
10 6
11 7 <table>
12 8 <tr>
13 9 <th>Name</th>
14 10 <th>Title</th>
15 11 <th>Enabled</th>
16 12 </tr>
@@ -2,50 +2,50
2 2 = stylesheet_link_tag 'graders'
3 3 <meta http-equiv ="refresh" content="60"/>
4 4
5 5 %h1 Grader information
6 6
7 7 = link_to '[Refresh]', :action => 'list'
8 8 %br/
9 9
10 10 .submitbox
11 11 .item
12 12 Grader control:
13 13 .item
14 - = form_for :clear, nil, :url => {:action => 'start_grading'} do |f|
14 + = form_for :clear, :url => {:action => 'start_grading'} do |f|
15 15 = submit_tag 'Start graders in grading env'
16 16 .item
17 - = form_for :clear, nil, :url => {:action => 'start_exam'} do |f|
17 + = form_for :clear, :url => {:action => 'start_exam'} do |f|
18 18 = submit_tag 'Start graders in exam env'
19 19 .item
20 - = form_for :clear, nil, :url => {:action => 'stop_all'} do |f|
20 + = form_for :clear, :url => {:action => 'stop_all'} do |f|
21 21 = submit_tag 'Stop all running graders'
22 22 .item
23 - = form_for :clear, nil, :url => {:action => 'clear_all'} do |f|
23 + = form_for :clear, :url => {:action => 'clear_all'} do |f|
24 24 = submit_tag 'Clear all data'
25 25 %br{:style => 'clear:both'}/
26 26
27 27 - if @last_task
28 28 Last task:
29 29 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
30 30
31 31 %br/
32 32
33 33 - if @last_test_request
34 34 Last test_request:
35 35 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
36 36
37 37
38 38 %h2 Current graders
39 39
40 40 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
41 41
42 42 %h2 Stalled graders
43 43
44 44 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
45 45
46 46 %h2 Terminated graders
47 47
48 - = form_for :clear, nil, :url => {:action => 'clear_terminated'} do |f|
48 + = form_for :clear, :url => {:action => 'clear_terminated'} do |f|
49 49 = submit_tag 'Clear data for terminated graders'
50 50
51 51 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
@@ -1,15 +1,15
1 1 - content_for :head do
2 - = javascript_include_tag :defaults
3 - = javascript_include_tag 'announcement_refresh.js'
2 + = javascript_include_tag "effects"
3 + = javascript_include_tag "announcement_refresh"
4 4
5 5 = user_title_bar(@user)
6 6
7 7 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 8 %span{:class => 'title'}
9 9 Announcements
10 10 #announcementbox-body
11 11 = render :partial => 'announcement', :collection => @announcements
12 12
13 13 - if GraderConfiguration.show_submitbox_to?(@user)
14 14 .submitbox
15 15 = error_messages_for 'submission'
@@ -5,22 +5,22
5 5 How to submit clarification requests
6 6 .announcement
7 7 %p
8 8 :markdown
9 9 The clarification requests should be phrased as yes/no questions.
10 10 The answers will be one of the following:
11 11 (1) **YES**,
12 12 (2) <b>NO</b>,
13 13 (3) **ANSWERED IN TASK DESCRIPTION (EXPLICITLY OR IMPLICITLY)**,
14 14 (4) **INVALID QUESTION**, and
15 15 (5) **NO COMMENT**.
16 16
17 - = form_for 'message', nil, :url => { :action => 'create'} do |f|
17 + = form_for 'message', :url => { :action => 'create'} do |f|
18 18 %p
19 19 %b New clarification request
20 20 = submit_tag "Post"
21 21 %br/
22 22 = f.text_area :body, :rows => 5, :cols => 100
23 23
24 24 %hr/
25 25
26 26 = render :partial => 'message', :collection => @messages, :locals => {:reply => false}
@@ -1,15 +1,14
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 - = javascript_include_tag :defaults
4 3
5 4 %h1 Import problems: successful
6 5
7 6 %p
8 7 %b Problem:
9 8 = "#{@problem.full_name} (#{@problem.name})"
10 9 %br/
11 10 Note that the full score has be assigned to the default value, 100.
12 11 You should change it to the correct full score.
13 12
14 13 %p
15 14 = link_to '[Back to problem list]', :action => 'list'
@@ -1,15 +1,14
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 - = javascript_include_tag :defaults
4 3
5 4 %h1 Import problems
6 5
7 6 %p= link_to '[Back to problem list]', :action => 'list'
8 7
9 8 - if @problem and @problem.errors
10 9 =error_messages_for 'problem'
11 10
12 11 = form_tag({:action => 'do_import'}, :multipart => true) do
13 12 .submitbox
14 13 %table
15 14 %tr
@@ -1,15 +1,14
1 1 <% content_for :head do %>
2 2 <%= stylesheet_link_tag 'problems' %>
3 - <%= javascript_include_tag :defaults %>
4 3 <% end %>
5 4
6 5 <h1>Listing problems</h1>
7 6
8 7 <p>
9 8 <%= link_to '[New problem]', :action => 'new' %>
10 9 <%= link_to '[Manage problems]', :action => 'manage' %>
11 10 <%= link_to '[Import problems]', :action => 'import' %>
12 11 <%= link_to '[Turn off all problems]', :action => 'turn_all_off' %>
13 12 <%= link_to '[Turn on all problems]', :action => 'turn_all_on' %>
14 13 </p>
15 14
@@ -44,24 +43,24
44 43 <td><%= in_place_editor_field :problem, :full_name, {}, :rows=>1 %></td>
45 44 <td><%= in_place_editor_field :problem, :full_score, {}, :rows=>1 %></td>
46 45 <td><%= problem.date_added %></td>
47 46 <td id="prob-<%= problem.id %>-avail"><%= problem.available %></td>
48 47 <td><%= problem.test_allowed %></td>
49 48
50 49 <% if GraderConfiguration.multicontests? %>
51 50 <td>
52 51 <%= problem.contests.collect { |c| c.name }.join(', ') %>
53 52 </td>
54 53 <% end %>
55 54
56 - <td><%= link_to_remote '[Toggle]', :url => {:action => 'toggle', :id => problem.id } %></td>
55 + <td><%= link_to '[Toggle]', {:action => 'toggle', :id => problem.id }, :remote => true %></td>
57 56 <td><%= link_to '[Stat]', :action => 'stat', :id => problem.id %></td>
58 57 <td><%= link_to '[Show]', :action => 'show', :id => problem %></td>
59 58 <td><%= link_to '[Edit]', :action => 'edit', :id => problem %></td>
60 59 <td><%= link_to '[Destroy]', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :post %></td>
61 60 </tr>
62 61 <% end %>
63 62 </table>
64 63
65 64 <br />
66 65
67 66 <%= link_to '[New problem]', :action => 'new' %>
@@ -1,15 +1,14
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 - = javascript_include_tag :defaults
4 3
5 4 %h1 Manage problems
6 5
7 6 %p= link_to '[Back to problem list]', :action => 'list'
8 7
9 8 = form_tag :action=>'do_manage' do
10 9 .submitbox
11 10 What do you want to do?
12 11 %br/
13 12 %ul
14 13 %li
15 14 Change date added to
@@ -31,25 +31,25
31 31 try {
32 32 submissionSelect.add(new Option(""+i,""+i,false,false),null);
33 33 } catch(ex) {
34 34 submissionSelect.add(new Option(""+i,""+i,false,false));
35 35 }
36 36 }
37 37 }
38 38 </script>
39 39
40 40 <% if GraderConfiguration.show_submitbox_to?(@user) and GraderConfiguration.allow_test_request(@user) %>
41 41 <div class="submitbox">
42 42 <%= error_messages_for 'submitted_test_request' %>
43 - <%= form_for :test_request, nil,
43 + <%= form_for :test_request,
44 44 :url => { :action => 'submit'},
45 45 :html => { :multipart => true } do |f| %>
46 46 <table>
47 47 <tr>
48 48 <td>Task:</td>
49 49 <td>
50 50 <%= select(:test_request,
51 51 :problem_id,
52 52 @problems.collect {|p| [p.name, p.id]}, {},
53 53 { :onclick => "updateSubmissionList();" }) %>
54 54 </td>
55 55 </tr>
@@ -1,15 +1,12
1 - - content_for :head do
2 - = javascript_include_tag :defaults
3 -
4 1 = user_title_bar(@user)
5 2
6 3 %h1 Your account settings
7 4
8 5 -#%p
9 6 -#You can edit your alias and e-mails. Just click on the text and edit it.
10 7
11 8 %table.uinfo
12 9 %tr
13 10 %th.uinfo Login
14 11 %td.uinfo= @user.login
15 12 %tr
@@ -45,18 +45,18
45 45 # Use SQL instead of Active Record's schema dumper when creating the database.
46 46 # This is necessary if your schema can't be completely dumped by the schema dumper,
47 47 # like if you have constraints or database-specific column types
48 48 # config.active_record.schema_format = :sql
49 49
50 50 # Enforce whitelist mode for mass assignment.
51 51 # This will create an empty whitelist of attributes available for mass-assignment for all models
52 52 # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 53 # parameters by using an attr_accessible or attr_protected declaration.
54 54 config.active_record.whitelist_attributes = false
55 55
56 56 # Enable the asset pipeline
57 - config.assets.enabled = false
57 + config.assets.enabled = true
58 58
59 59 # Version of your assets, change this if you want to expire all your assets
60 60 config.assets.version = '1.0'
61 61 end
62 62 end
deleted file
deleted file
deleted file
This diff has been collapsed as it changes many lines, (963 lines changed) Show them Hide them
deleted file
This diff has been collapsed as it changes many lines, (973 lines changed) Show them Hide them
deleted file
This diff has been collapsed as it changes many lines, (1128 lines changed) Show them Hide them
deleted file
deleted file
You need to be logged in to leave comments. Login now