typo 5.4.1 → 5.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGELOG +10 -24
  2. data/app/controllers/accounts_controller.rb +18 -1
  3. data/app/controllers/admin/content_controller.rb +1 -0
  4. data/app/controllers/admin/resources_controller.rb +17 -3
  5. data/app/controllers/application_controller.rb +2 -5
  6. data/app/helpers/admin/base_helper.rb +16 -6
  7. data/app/helpers/admin/resources_helper.rb +6 -0
  8. data/app/helpers/application_helper.rb +7 -8
  9. data/app/models/article.rb +8 -10
  10. data/app/models/blog.rb +26 -24
  11. data/app/models/content.rb +17 -10
  12. data/app/models/feedback.rb +1 -1
  13. data/app/models/page.rb +1 -1
  14. data/app/models/resource.rb +14 -0
  15. data/app/models/user.rb +1 -0
  16. data/app/views/accounts/login.html.erb +2 -1
  17. data/app/views/accounts/recover_password.html.erb +18 -0
  18. data/app/views/admin/content/_form.html.erb +8 -5
  19. data/app/views/admin/content/_images.html.erb +14 -0
  20. data/app/views/admin/content/_visual_editor.html.erb +5 -0
  21. data/app/views/admin/pages/_visual_editor.html.erb +9 -5
  22. data/app/views/admin/resources/_upload.html.erb +10 -0
  23. data/app/views/admin/resources/get_thumbnails.html.erb +5 -0
  24. data/app/views/admin/resources/images.html.erb +28 -0
  25. data/app/views/admin/resources/index.html.erb +42 -11
  26. data/app/views/layouts/administration.html.erb +1 -1
  27. data/app/views/notification_mailer/notif_user.html.erb +1 -1
  28. data/config/environment.rb +1 -1
  29. data/config/initializers/access_rules.rb +2 -1
  30. data/config/initializers/inflector.rb +4 -1
  31. data/db/schema.rb +26 -32
  32. data/lib/tasks/release.rake +1 -1
  33. data/lib/typo_version.rb +1 -1
  34. data/public/images/thumb_blank.jpg +0 -0
  35. data/public/javascripts/base_packaged.js +377 -0
  36. data/public/javascripts/ckeditor/config.bak +27 -11
  37. data/public/javascripts/quicktags.js +11 -0
  38. data/public/javascripts/typo_carousel.js +340 -0
  39. data/public/stylesheets/administration.css +16 -0
  40. data/public/stylesheets/base_packaged.css +100 -0
  41. data/script/about +3 -2
  42. data/script/console +1 -1
  43. data/script/dbconsole +1 -1
  44. data/script/destroy +1 -1
  45. data/script/generate +1 -1
  46. data/script/performance/benchmarker +1 -1
  47. data/script/performance/profiler +1 -1
  48. data/script/plugin +2 -2
  49. data/script/runner +2 -2
  50. data/script/server +2 -2
  51. data/spec/controllers/accounts_controller_spec.rb +47 -0
  52. data/spec/controllers/admin/content_controller_spec.rb +4 -0
  53. data/spec/controllers/admin/resources_controller_spec.rb +8 -0
  54. data/spec/controllers/xml_controller_spec.rb +13 -16
  55. data/spec/factories.rb +14 -1
  56. data/spec/models/article_spec.rb +57 -14
  57. data/spec/models/blog_spec.rb +50 -3
  58. data/spec/models/trackback_spec.rb +1 -1
  59. data/spec/models/user_spec.rb +7 -12
  60. data/spec/spec_helper.rb +1 -1
  61. data/test/fixtures/users.yml +15 -8
  62. data/themes/true-blue-3/images/background.gif +0 -0
  63. data/vendor/plugins/easy-ckeditor/lib/ckeditor.rb +1 -2
  64. data/vendor/plugins/easy-ckeditor/lib/ckeditor_file_utils.rb +2 -2
  65. metadata +11 -11
  66. data/app/views/admin/resources/_resources.html.erb +0 -41
  67. data/script/benchmarker +0 -19
  68. data/script/performance/request +0 -3
  69. data/script/process/inspector +0 -3
  70. data/script/process/reaper +0 -3
  71. data/script/process/spawner +0 -3
  72. data/script/process/spinner +0 -3
  73. data/script/profiler +0 -34
  74. data/script/spec_server +0 -9
@@ -0,0 +1,340 @@
1
+ /*
2
+ Copyright (c) 2009 Victor Stanciu - http://www.victorstanciu.ro
3
+
4
+ Permission is hereby granted, free of charge, to any person
5
+ obtaining a copy of this software and associated documentation
6
+ files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ Carousel = Class.create(Abstract, {
27
+ initialize: function (scroller, slides, controls, options) {
28
+ this.scrolling = false;
29
+ this.scroller = $(scroller);
30
+ this.slides = slides;
31
+ this.controls = controls;
32
+
33
+ this.options = Object.extend({
34
+ duration: 1,
35
+ auto: false,
36
+ frequency: 3,
37
+ visibleSlides: 1,
38
+ controlClassName: 'carousel-control',
39
+ jumperClassName: 'carousel-jumper',
40
+ disabledClassName: 'carousel-disabled',
41
+ selectedClassName: 'carousel-selected',
42
+ circular: false,
43
+ wheel: true,
44
+ effect: 'scroll',
45
+ transition: 'sinoidal'
46
+ }, options || {});
47
+
48
+ if (this.options.effect == 'fade') {
49
+ this.options.circular = true;
50
+ }
51
+
52
+ this.slides.each(function(slide, index) {
53
+ slide._index = index;
54
+ });
55
+
56
+ if (this.controls) {
57
+ this.controls.invoke('observe', 'click', this.click.bind(this));
58
+ }
59
+
60
+ if (this.options.wheel) {
61
+ this.scroller.observe('mousewheel', this.wheel.bindAsEventListener(this)).observe('DOMMouseScroll', this.wheel.bindAsEventListener(this));;
62
+ }
63
+
64
+ if (this.options.auto) {
65
+ this.start();
66
+ }
67
+
68
+ if (this.options.initial) {
69
+ var initialIndex = this.slides.indexOf($(this.options.initial));
70
+ if (initialIndex > (this.options.visibleSlides - 1) && this.options.visibleSlides > 1) {
71
+ if (initialIndex > this.slides.length - (this.options.visibleSlides + 1)) {
72
+ initialIndex = this.slides.length - this.options.visibleSlides;
73
+ }
74
+ }
75
+ this.moveTo(this.slides[initialIndex]);
76
+ }
77
+ },
78
+
79
+ click: function (event) {
80
+ this.stop();
81
+
82
+ var element = event.findElement('a');
83
+
84
+ if (!element.hasClassName(this.options.disabledClassName)) {
85
+ if (element.hasClassName(this.options.controlClassName)) {
86
+ eval("this." + element.rel + "()");
87
+ } else if (element.hasClassName(this.options.jumperClassName)) {
88
+ this.moveTo(element.rel);
89
+ if (this.options.selectedClassName) {
90
+ this.controls.invoke('removeClassName', this.options.selectedClassName);
91
+ element.addClassName(this.options.selectedClassName);
92
+ }
93
+ }
94
+ }
95
+
96
+ this.deactivateControls();
97
+
98
+ event.stop();
99
+ },
100
+
101
+ moveTo: function (element) {
102
+ if (this.options.beforeMove && (typeof this.options.beforeMove == 'function')) {
103
+ this.options.beforeMove();
104
+ }
105
+ this.previous = this.current ? this.current : this.slides[0];
106
+ this.current = $(element);
107
+
108
+ var scrollerOffset = this.scroller.cumulativeOffset();
109
+ var elementOffset = this.current.cumulativeOffset();
110
+
111
+ if (this.scrolling) {
112
+ this.scrolling.cancel();
113
+ }
114
+
115
+ switch (this.options.effect) {
116
+ case 'fade':
117
+ this.scrolling = new Effect.Opacity(this.scroller, {
118
+ from: 1.0,
119
+ to: 0,
120
+ duration: this.options.duration,
121
+ afterFinish: (function () {
122
+ this.scroller.scrollLeft = elementOffset[0] - scrollerOffset[0];
123
+ this.scroller.scrollTop = elementOffset[1] - scrollerOffset[1];
124
+
125
+ new Effect.Opacity(this.scroller, {
126
+ from: 0,
127
+ to: 1.0,
128
+ duration: this.options.duration,
129
+ afterFinish: (function () {
130
+ if (this.controls) {
131
+ this.activateControls();
132
+ }
133
+ if (this.options.afterMove && (typeof this.options.afterMove == 'function')) {
134
+ this.options.afterMove();
135
+ }
136
+ }).bind(this)
137
+ });
138
+ }
139
+ ).bind(this)});
140
+ break;
141
+ case 'scroll':
142
+ default:
143
+ var transition;
144
+ switch (this.options.transition) {
145
+ case 'spring':
146
+ transition = Effect.Transitions.spring;
147
+ break;
148
+ case 'sinoidal':
149
+ default:
150
+ transition = Effect.Transitions.sinoidal;
151
+ break;
152
+ }
153
+
154
+ this.scrolling = new Effect.SmoothScroll(this.scroller, {
155
+ duration: this.options.duration,
156
+ x: (elementOffset[0] - scrollerOffset[0]),
157
+ y: (elementOffset[1] - scrollerOffset[1]),
158
+ transition: transition,
159
+ afterFinish: (function () {
160
+ if (this.controls) {
161
+ this.activateControls();
162
+ }
163
+ if (this.options.afterMove && (typeof this.options.afterMove == 'function')) {
164
+ this.options.afterMove();
165
+ }
166
+ this.scrolling = false;
167
+ }).bind(this)});
168
+ break;
169
+ }
170
+
171
+ return false;
172
+ },
173
+
174
+ prev: function () {
175
+ if (this.current) {
176
+ var currentIndex = this.current._index;
177
+ var prevIndex = (currentIndex == 0) ? (this.options.circular ? this.slides.length - 1 : 0) : currentIndex - 1;
178
+ } else {
179
+ var prevIndex = (this.options.circular ? this.slides.length - 1 : 0);
180
+ }
181
+
182
+ if (prevIndex == (this.slides.length - 1) && this.options.circular && this.options.effect != 'fade') {
183
+ this.scroller.scrollLeft = (this.slides.length - 1) * this.slides.first().getWidth();
184
+ this.scroller.scrollTop = (this.slides.length - 1) * this.slides.first().getHeight();
185
+ prevIndex = this.slides.length - 2;
186
+ }
187
+
188
+ this.moveTo(this.slides[prevIndex]);
189
+ },
190
+
191
+ next: function () {
192
+ if (this.current) {
193
+ var currentIndex = this.current._index;
194
+ var nextIndex = (this.slides.length - 1 == currentIndex) ? (this.options.circular ? 0 : currentIndex) : currentIndex + 1;
195
+ } else {
196
+ var nextIndex = 1;
197
+ }
198
+
199
+ if (nextIndex == 0 && this.options.circular && this.options.effect != 'fade') {
200
+ this.scroller.scrollLeft = 0;
201
+ this.scroller.scrollTop = 0;
202
+ nextIndex = 1;
203
+ }
204
+
205
+ var max = $('editor').getWidth() / 140 | 0;
206
+
207
+ if (nextIndex == this.slides.length - (max - 1)) {
208
+ new Ajax.Request('/admin/resources/get_thumbnails?position=' + this.slides.length,
209
+ {
210
+ method:'get',
211
+ onSuccess: function(transport){
212
+ var response = transport.responseText || "no response text";
213
+ $('carousel-content').innerHTML += response;
214
+ this.slides = $$('#carousel-content .slide');
215
+ $('carousel-content').style.width = 140 * this.slides.length;
216
+ }
217
+ });
218
+ }
219
+ if (nextIndex > this.slides.length - (this.options.visibleSlides + 1)) {
220
+ nextIndex = this.slides.length - this.options.visibleSlides;
221
+ }
222
+
223
+ this.moveTo(this.slides[nextIndex]);
224
+ },
225
+
226
+ first: function () {
227
+ this.moveTo(this.slides[0]);
228
+ },
229
+
230
+ last: function () {
231
+ this.moveTo(this.slides[this.slides.length - 1]);
232
+ },
233
+
234
+ toggle: function () {
235
+ if (this.previous) {
236
+ this.moveTo(this.slides[this.previous._index]);
237
+ } else {
238
+ return false;
239
+ }
240
+ },
241
+
242
+ stop: function () {
243
+ if (this.timer) {
244
+ clearTimeout(this.timer);
245
+ }
246
+ },
247
+
248
+ start: function () {
249
+ this.periodicallyUpdate();
250
+ },
251
+
252
+ pause: function () {
253
+ this.stop();
254
+ this.activateControls();
255
+ },
256
+
257
+ resume: function (event) {
258
+ if (event) {
259
+ var related = event.relatedTarget || event.toElement;
260
+ if (!related || (!this.slides.include(related) && !this.slides.any(function (slide) { return related.descendantOf(slide); }))) {
261
+ this.start();
262
+ }
263
+ } else {
264
+ this.start();
265
+ }
266
+ },
267
+
268
+ periodicallyUpdate: function () {
269
+ if (this.timer != null) {
270
+ clearTimeout(this.timer);
271
+ this.next();
272
+ }
273
+ this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency * 1000);
274
+ },
275
+
276
+ wheel: function (event) {
277
+ event.cancelBubble = true;
278
+ event.stop();
279
+
280
+ var delta = 0;
281
+ if (!event) {
282
+ event = window.event;
283
+ }
284
+ if (event.wheelDelta) {
285
+ delta = event.wheelDelta / 120;
286
+ } else if (event.detail) {
287
+ delta = -event.detail / 3;
288
+ }
289
+
290
+ if (!this.scrolling) {
291
+ this.deactivateControls();
292
+ if (delta > 0) {
293
+ this.prev();
294
+ } else {
295
+ this.next();
296
+ }
297
+ }
298
+
299
+ return Math.round(delta); //Safari Round
300
+ },
301
+
302
+ deactivateControls: function () {
303
+ this.controls.invoke('addClassName', this.options.disabledClassName);
304
+ },
305
+
306
+ activateControls: function () {
307
+ this.controls.invoke('removeClassName', this.options.disabledClassName);
308
+ }
309
+ });
310
+
311
+
312
+ Effect.SmoothScroll = Class.create();
313
+ Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
314
+ initialize: function (element) {
315
+ this.element = $(element);
316
+ var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {});
317
+ this.start(options);
318
+ },
319
+
320
+ setup: function () {
321
+ if (this.options.continuous && !this.element._ext) {
322
+ this.element.cleanWhitespace();
323
+ this.element._ext = true;
324
+ this.element.appendChild(this.element.firstChild);
325
+ }
326
+
327
+ this.originalLeft = this.element.scrollLeft;
328
+ this.originalTop = this.element.scrollTop;
329
+
330
+ if (this.options.mode == 'absolute') {
331
+ this.options.x -= this.originalLeft;
332
+ this.options.y -= this.originalTop;
333
+ }
334
+ },
335
+
336
+ update: function (position) {
337
+ this.element.scrollLeft = this.options.x * position + this.originalLeft;
338
+ this.element.scrollTop = this.options.y * position + this.originalTop;
339
+ }
340
+ });
@@ -670,3 +670,19 @@ td.paginate {
670
670
  background: #a7eafe;
671
671
  }
672
672
 
673
+ #carousel-wrapper {
674
+ width: 100%;
675
+ height: 150px;
676
+ overflow: hidden;
677
+ }
678
+ #carousel-content {
679
+ width: 1400px;
680
+ }
681
+ #carousel-content .slide {
682
+ float: left;
683
+ width: 140px;
684
+ height: 125px;
685
+ padding: 10px 0;
686
+ background: #8AE3F9;
687
+ text-align: center;
688
+ }
@@ -0,0 +1,100 @@
1
+ .CodeRay {background-color: #f8f8f8; border: 1px solid silver; font-family: 'Courier New', 'Terminal', monospace; color: #100}
2
+ .CodeRay pre {margin: 0px }
3
+ div.CodeRay {overflow: auto}
4
+ span.CodeRay {white-space: pre; border: 0px; padding: 2px }
5
+ table.CodeRay {border-collapse: collapse; width: 100%; padding: 2px }
6
+ table.CodeRay td {padding: 2px 4px; vertical-align: top }
7
+ .CodeRay .line_numbers, .CodeRay .no {background-color: #def; color: gray; text-align: right}
8
+ .CodeRay .line_numbers tt {font-weight: bold }
9
+ .CodeRay .no {padding: 0px 4px }
10
+ .CodeRay .code {width: 100% }
11
+ ol.CodeRay {font-size: 10pt }
12
+ ol.CodeRay li {white-space: pre }
13
+ .CodeRay .code pre {overflow: auto }
14
+ .CodeRay .debug {color:white ! important; background:blue ! important}
15
+ .CodeRay .af {color:#00C }
16
+ .CodeRay .an {color:#007 }
17
+ .CodeRay .at {color:#f08 }
18
+ .CodeRay .av {color:#700 }
19
+ .CodeRay .aw {color:#C00 }
20
+ .CodeRay .bi {color:#509; font-weight:bold }
21
+ .CodeRay .c {color:#666}
22
+ .CodeRay .ch {color:#04D }
23
+ .CodeRay .ch .k {color:#04D }
24
+ .CodeRay .ch .dl {color:#039 }
25
+ .CodeRay .cl {color:#B06; font-weight:bold }
26
+ .CodeRay .co {color:#036; font-weight:bold }
27
+ .CodeRay .cr {color:#0A0 }
28
+ .CodeRay .cv {color:#369 }
29
+ .CodeRay .df {color:#099; font-weight:bold }
30
+ .CodeRay .di {color:#088; font-weight:bold }
31
+ .CodeRay .dl {color:black }
32
+ .CodeRay .do {color:#970 }
33
+ .CodeRay .ds {color:#D42; font-weight:bold }
34
+ .CodeRay .e {color:#666; font-weight:bold }
35
+ .CodeRay .en {color:#800; font-weight:bold }
36
+ .CodeRay .er {color:#F00; background-color:#FAA }
37
+ .CodeRay .ex {color:#F00; font-weight:bold }
38
+ .CodeRay .fl {color:#60E; font-weight:bold }
39
+ .CodeRay .fu {color:#06B; font-weight:bold }
40
+ .CodeRay .gv {color:#d70; font-weight:bold }
41
+ .CodeRay .hx {color:#058; font-weight:bold }
42
+ .CodeRay .i {color:#00D; font-weight:bold }
43
+ .CodeRay .ic {color:#B44; font-weight:bold }
44
+ .CodeRay .il {background: #eee }
45
+ .CodeRay .il .il {background: #ddd }
46
+ .CodeRay .il .il .il {background: #ccc }
47
+ .CodeRay .il .idl {font-weight: bold; color: #888 }
48
+ .CodeRay .im {color:#f00}
49
+ .CodeRay .in {color:#B2B; font-weight:bold }
50
+ .CodeRay .iv {color:#33B }
51
+ .CodeRay .la {color:#970; font-weight:bold }
52
+ .CodeRay .lv {color:#963 }
53
+ .CodeRay .oc {color:#40E; font-weight:bold }
54
+ .CodeRay .of {color:#000; font-weight:bold }
55
+ .CodeRay .op {}
56
+ .CodeRay .pc {color:#038; font-weight:bold }
57
+ .CodeRay .pd {color:#369; font-weight:bold }
58
+ .CodeRay .pp {color:#579}
59
+ .CodeRay .ps {color:#00C; font-weight: bold}
60
+ .CodeRay .pt {color:#339; font-weight:bold }
61
+ .CodeRay .r, .kw {color:#080; font-weight:bold }
62
+ .CodeRay .ke {color: #808}
63
+ .CodeRay .ke .dl {color: #606}
64
+ .CodeRay .ke .ch {color: #80f}
65
+ .CodeRay .vl {color: #088}
66
+ .CodeRay .rx {background-color:#fff0ff }
67
+ .CodeRay .rx .k {color:#808 }
68
+ .CodeRay .rx .dl {color:#404 }
69
+ .CodeRay .rx .mod {color:#C2C }
70
+ .CodeRay .rx .fu {color:#404; font-weight: bold }
71
+ .CodeRay .s {background-color:#fff0f0; color: #D20}
72
+ .CodeRay .s .s {background-color:#ffe0e0 }
73
+ .CodeRay .s .s .s {background-color:#ffd0d0 }
74
+ .CodeRay .s .k {}
75
+ .CodeRay .s .ch {color: #b0b}
76
+ .CodeRay .s .dl {color: #710}
77
+ .CodeRay .sh {background-color:#f0fff0; color:#2B2 }
78
+ .CodeRay .sh .k {}
79
+ .CodeRay .sh .dl {color:#161 }
80
+ .CodeRay .sy {color:#A60 }
81
+ .CodeRay .sy .k {color:#A60 }
82
+ .CodeRay .sy .dl {color:#630 }
83
+ .CodeRay .ta {color:#070 }
84
+ .CodeRay .tf {color:#070; font-weight:bold }
85
+ .CodeRay .ts {color:#D70; font-weight:bold }
86
+ .CodeRay .ty {color:#339; font-weight:bold }
87
+ .CodeRay .v {color:#036 }
88
+ .CodeRay .xt {color:#444 }
89
+ .CodeRay .ins {background: #afa}
90
+ .CodeRay .del {background: #faa}
91
+ .CodeRay .chg {color: #aaf; background: #007}
92
+ .CodeRay .head {color: #f8f; background: #505 }
93
+ .CodeRay .ins .ins {color: #080; font-weight:bold }
94
+ .CodeRay .del .del {color: #800; font-weight:bold }
95
+ .CodeRay .chg .chg {color: #66f}
96
+ .CodeRay .head .head {color: #f4f}
97
+ .alignleft, img.left {float: left; margin: 0 5px 5px 0}
98
+ .alignright, img.right {float: right; margin: 0 0 5px 5px}
99
+ .centered {margin-left: auto; margin-right: auto; display: block; padding: 8px}
100
+ .gravatar {float: left; margin-right: 3px; margin-bottom: 3px}