almanac 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +76 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/images/almanac/background.jpg +0 -0
  5. data/app/assets/images/almanac/icons/compose.png +0 -0
  6. data/app/assets/images/almanac/icons/feed.png +0 -0
  7. data/app/assets/images/almanac/icons/gear.png +0 -0
  8. data/app/assets/images/almanac/icons/glyphicons-halflings-white.png +0 -0
  9. data/app/assets/images/almanac/icons/glyphicons-halflings.png +0 -0
  10. data/app/assets/images/almanac/icons/upload.png +0 -0
  11. data/app/assets/images/almanac/logo.jpg +0 -0
  12. data/app/assets/javascripts/almanac/2-jquery.backstretch.js +357 -0
  13. data/app/assets/javascripts/almanac/3-pixastic.js +637 -0
  14. data/app/assets/javascripts/almanac/4-bootstrap-datepicker.js +454 -0
  15. data/app/assets/javascripts/almanac/5-main.coffee.erb +46 -0
  16. data/app/assets/javascripts/almanac/application.js +16 -0
  17. data/app/assets/stylesheets/almanac/1-datepicker.css +7 -0
  18. data/app/assets/stylesheets/almanac/2-main.css.scss +279 -0
  19. data/app/assets/stylesheets/almanac/application.css +15 -0
  20. data/app/controllers/almanac/application_controller.rb +24 -0
  21. data/app/controllers/almanac/blogs_controller.rb +64 -0
  22. data/app/controllers/almanac/comments_controller.rb +41 -0
  23. data/app/controllers/almanac/images_controller.rb +29 -0
  24. data/app/controllers/almanac/posts_controller.rb +109 -0
  25. data/app/helpers/almanac/application_helper.rb +4 -0
  26. data/app/models/almanac/blog.rb +32 -0
  27. data/app/models/almanac/comment.rb +20 -0
  28. data/app/models/almanac/image.rb +10 -0
  29. data/app/models/almanac/post.rb +55 -0
  30. data/app/views/almanac/blogs/_form.html.haml +76 -0
  31. data/app/views/almanac/blogs/_topbar.html.haml +5 -0
  32. data/app/views/almanac/blogs/edit.html.haml +4 -0
  33. data/app/views/almanac/blogs/new.html.haml +3 -0
  34. data/app/views/almanac/blogs/spam.html.haml +15 -0
  35. data/app/views/almanac/posts/_form.html.haml +52 -0
  36. data/app/views/almanac/posts/_post.html.haml +59 -0
  37. data/app/views/almanac/posts/edit.html.haml +1 -0
  38. data/app/views/almanac/posts/index.html.haml +30 -0
  39. data/app/views/almanac/posts/index.rss.builder +18 -0
  40. data/app/views/almanac/posts/new.html.haml +1 -0
  41. data/app/views/almanac/posts/show.html.haml +4 -0
  42. data/app/views/almanac/posts/tag.html.haml +22 -0
  43. data/app/views/layouts/almanac/_ga.html.haml +10 -0
  44. data/app/views/layouts/almanac/_twitter_follow.html.haml +2 -0
  45. data/app/views/layouts/almanac/application.html.haml +52 -0
  46. data/config/routes.rb +22 -0
  47. data/db/migrate/20121009222451_create_almanac_posts.rb +17 -0
  48. data/db/migrate/20121010033555_create_almanac_blogs.rb +14 -0
  49. data/db/migrate/20121017032059_add_excerpt_to_almanac_posts.rb +11 -0
  50. data/db/migrate/20121017210007_create_almanac_files.rb +15 -0
  51. data/db/migrate/20121017221819_rename_file_to_image.rb +9 -0
  52. data/db/migrate/20121025223403_add_image_fields_to_almanac_blogs.rb +13 -0
  53. data/db/migrate/20121029211221_add_new_fields_to_blogs.rb +15 -0
  54. data/db/migrate/20121029221815_acts_as_taggable_on_migration.rb +30 -0
  55. data/db/migrate/20121101030836_create_almanac_comments.rb +16 -0
  56. data/db/migrate/20121102181941_add_rakismet_fields_to_blogs.rb +13 -0
  57. data/db/migrate/20121102185130_add_spam_to_comments.rb +11 -0
  58. data/db/migrate/20121110000024_add_written_at_to_posts.rb +11 -0
  59. data/db/migrate/20121112205256_add_background_fields_to_blogs.rb +13 -0
  60. data/db/migrate/20121113010557_add_footer_to_almanac_blogs.rb +11 -0
  61. data/db/migrate/20121114043648_change_default_value_for_background_tiles_in_almanac_blogs.rb +9 -0
  62. data/lib/almanac.rb +16 -0
  63. data/lib/almanac/MarkdownParser.rb +18 -0
  64. data/lib/almanac/engine.rb +9 -0
  65. data/lib/almanac/version.rb +3 -0
  66. data/lib/tasks/almanac_tasks.rake +4 -0
  67. data/spec/controllers/blogs_controller_spec.rb +80 -0
  68. data/spec/controllers/comments_controller_spec.rb +51 -0
  69. data/spec/controllers/posts_controller_spec.rb +120 -0
  70. data/spec/dummy/README.rdoc +261 -0
  71. data/spec/dummy/Rakefile +7 -0
  72. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  73. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  74. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  75. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  76. data/spec/dummy/app/models/ability.rb +13 -0
  77. data/spec/dummy/app/models/user.rb +11 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  79. data/spec/dummy/config.ru +4 -0
  80. data/spec/dummy/config/application.rb +59 -0
  81. data/spec/dummy/config/boot.rb +10 -0
  82. data/spec/dummy/config/database.yml +25 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +37 -0
  85. data/spec/dummy/config/environments/production.rb +67 -0
  86. data/spec/dummy/config/environments/test.rb +37 -0
  87. data/spec/dummy/config/initializers/almanac.rb +1 -0
  88. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  89. data/spec/dummy/config/initializers/devise.rb +233 -0
  90. data/spec/dummy/config/initializers/dragonfly.rb +7 -0
  91. data/spec/dummy/config/initializers/inflections.rb +15 -0
  92. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  93. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  94. data/spec/dummy/config/initializers/session_store.rb +8 -0
  95. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  96. data/spec/dummy/config/locales/en.yml +5 -0
  97. data/spec/dummy/config/routes.rb +14 -0
  98. data/spec/dummy/db/migrate/20121009230705_create_almanac_posts.rb +18 -0
  99. data/spec/dummy/db/migrate/20121010033827_create_almanac_blogs.rb +15 -0
  100. data/spec/dummy/db/migrate/20121102224650_add_excerpt_to_almanac_posts.rb +12 -0
  101. data/spec/dummy/db/migrate/20121102224651_create_almanac_files..rb +16 -0
  102. data/spec/dummy/db/migrate/20121102224652_rename_file_to_image.rb +10 -0
  103. data/spec/dummy/db/migrate/20121102224653_add_image_fields_to_almanac_blogs.rb +14 -0
  104. data/spec/dummy/db/migrate/20121102224654_add_new_fields_to_almanac_blogs.rb +16 -0
  105. data/spec/dummy/db/migrate/20121102224655_acts_as_taggable_on_migration.rb +31 -0
  106. data/spec/dummy/db/migrate/20121102224656_create_almanac_comments.rb +17 -0
  107. data/spec/dummy/db/migrate/20121102224657_add_rakismet_fields_to_almanac_blogs.rb +14 -0
  108. data/spec/dummy/db/migrate/20121102224658_add_spam_to_almanac_comments.rb +12 -0
  109. data/spec/dummy/db/migrate/20121106220325_devise_create_users.rb +46 -0
  110. data/spec/dummy/db/migrate/20121114032144_add_written_at_to_almanac_posts.rb +12 -0
  111. data/spec/dummy/db/migrate/20121114032145_add_background_fields_to_almanac_blogs.rb +14 -0
  112. data/spec/dummy/db/migrate/20121114032146_add_footer_to_almanac_blogs.rb +12 -0
  113. data/spec/dummy/db/schema.rb +98 -0
  114. data/spec/dummy/db/test.sqlite3 +0 -0
  115. data/spec/dummy/log/production.log +1 -0
  116. data/spec/dummy/log/test.log +2930 -0
  117. data/spec/dummy/public/404.html +26 -0
  118. data/spec/dummy/public/422.html +26 -0
  119. data/spec/dummy/public/500.html +25 -0
  120. data/spec/dummy/public/favicon.ico +0 -0
  121. data/spec/dummy/script/rails +6 -0
  122. data/spec/factories.rb +72 -0
  123. data/spec/models/blog_spec.rb +16 -0
  124. data/spec/models/comment_spec.rb +35 -0
  125. data/spec/models/post_spec.rb +79 -0
  126. data/spec/spec_helper.rb +37 -0
  127. metadata +485 -0
@@ -0,0 +1,637 @@
1
+ /*
2
+ * Pixastic Lib - Core Functions - v0.1.3
3
+ * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
4
+ * License: [http://www.pixastic.com/lib/license.txt]
5
+ */
6
+
7
+ var Pixastic = (function() {
8
+
9
+
10
+ function addEvent(el, event, handler) {
11
+ if (el.addEventListener)
12
+ el.addEventListener(event, handler, false);
13
+ else if (el.attachEvent)
14
+ el.attachEvent("on" + event, handler);
15
+ }
16
+
17
+ function onready(handler) {
18
+ var handlerDone = false;
19
+ var execHandler = function() {
20
+ if (!handlerDone) {
21
+ handlerDone = true;
22
+ handler();
23
+ }
24
+ }
25
+ document.write("<"+"script defer src=\"//:\" id=\"__onload_ie_pixastic__\"></"+"script>");
26
+ var script = document.getElementById("__onload_ie_pixastic__");
27
+ script.onreadystatechange = function() {
28
+ if (script.readyState == "complete") {
29
+ script.parentNode.removeChild(script);
30
+ execHandler();
31
+ }
32
+ }
33
+ if (document.addEventListener)
34
+ document.addEventListener("DOMContentLoaded", execHandler, false);
35
+ addEvent(window, "load", execHandler);
36
+ }
37
+
38
+ function init() {
39
+ var imgEls = getElementsByClass("pixastic", null, "img");
40
+ var canvasEls = getElementsByClass("pixastic", null, "canvas");
41
+ var elements = imgEls.concat(canvasEls);
42
+ for (var i=0;i<elements.length;i++) {
43
+ (function() {
44
+
45
+ var el = elements[i];
46
+ var actions = [];
47
+ var classes = el.className.split(" ");
48
+ for (var c=0;c<classes.length;c++) {
49
+ var cls = classes[c];
50
+ if (cls.substring(0,9) == "pixastic-") {
51
+ var actionName = cls.substring(9);
52
+ if (actionName != "")
53
+ actions.push(actionName);
54
+ }
55
+ }
56
+ if (actions.length) {
57
+ if (el.tagName.toLowerCase() == "img") {
58
+ var dataImg = new Image();
59
+ dataImg.src = el.src;
60
+ if (dataImg.complete) {
61
+ for (var a=0;a<actions.length;a++) {
62
+ var res = Pixastic.applyAction(el, el, actions[a], null);
63
+ if (res)
64
+ el = res;
65
+ }
66
+ } else {
67
+ dataImg.onload = function() {
68
+ for (var a=0;a<actions.length;a++) {
69
+ var res = Pixastic.applyAction(el, el, actions[a], null)
70
+ if (res)
71
+ el = res;
72
+ }
73
+ }
74
+ }
75
+ } else {
76
+ setTimeout(function() {
77
+ for (var a=0;a<actions.length;a++) {
78
+ var res = Pixastic.applyAction(
79
+ el, el, actions[a], null
80
+ );
81
+ if (res)
82
+ el = res;
83
+ }
84
+ },1);
85
+ }
86
+ }
87
+
88
+ })();
89
+ }
90
+ }
91
+
92
+ if (typeof pixastic_parseonload != "undefined" && pixastic_parseonload)
93
+ onready(init);
94
+
95
+ // getElementsByClass by Dustin Diaz, http://www.dustindiaz.com/getelementsbyclass/
96
+ function getElementsByClass(searchClass,node,tag) {
97
+ var classElements = new Array();
98
+ if ( node == null )
99
+ node = document;
100
+ if ( tag == null )
101
+ tag = '*';
102
+
103
+ var els = node.getElementsByTagName(tag);
104
+ var elsLen = els.length;
105
+ var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
106
+ for (i = 0, j = 0; i < elsLen; i++) {
107
+ if ( pattern.test(els[i].className) ) {
108
+ classElements[j] = els[i];
109
+ j++;
110
+ }
111
+ }
112
+ return classElements;
113
+ }
114
+
115
+ var debugElement;
116
+
117
+ function writeDebug(text, level) {
118
+ if (!Pixastic.debug) return;
119
+ try {
120
+ switch (level) {
121
+ case "warn" :
122
+ console.warn("Pixastic:", text);
123
+ break;
124
+ case "error" :
125
+ console.error("Pixastic:", text);
126
+ break;
127
+ default:
128
+ console.log("Pixastic:", text);
129
+ }
130
+ } catch(e) {
131
+ }
132
+ if (!debugElement) {
133
+
134
+ }
135
+ }
136
+
137
+ // canvas capability checks
138
+
139
+ var hasCanvas = (function() {
140
+ var c = document.createElement("canvas");
141
+ var val = false;
142
+ try {
143
+ val = !!((typeof c.getContext == "function") && c.getContext("2d"));
144
+ } catch(e) {}
145
+ return function() {
146
+ return val;
147
+ }
148
+ })();
149
+
150
+ var hasCanvasImageData = (function() {
151
+ var c = document.createElement("canvas");
152
+ var val = false;
153
+ var ctx;
154
+ try {
155
+ if (typeof c.getContext == "function" && (ctx = c.getContext("2d"))) {
156
+ val = (typeof ctx.getImageData == "function");
157
+ }
158
+ } catch(e) {}
159
+ return function() {
160
+ return val;
161
+ }
162
+ })();
163
+
164
+ var hasGlobalAlpha = (function() {
165
+ var hasAlpha = false;
166
+ var red = document.createElement("canvas");
167
+ if (hasCanvas() && hasCanvasImageData()) {
168
+ red.width = red.height = 1;
169
+ var redctx = red.getContext("2d");
170
+ redctx.fillStyle = "rgb(255,0,0)";
171
+ redctx.fillRect(0,0,1,1);
172
+
173
+ var blue = document.createElement("canvas");
174
+ blue.width = blue.height = 1;
175
+ var bluectx = blue.getContext("2d");
176
+ bluectx.fillStyle = "rgb(0,0,255)";
177
+ bluectx.fillRect(0,0,1,1);
178
+
179
+ redctx.globalAlpha = 0.5;
180
+ redctx.drawImage(blue, 0, 0);
181
+ var reddata = redctx.getImageData(0,0,1,1).data;
182
+
183
+ hasAlpha = (reddata[2] != 255);
184
+ }
185
+ return function() {
186
+ return hasAlpha;
187
+ }
188
+ })();
189
+
190
+
191
+ // return public interface
192
+
193
+ return {
194
+
195
+ parseOnLoad : false,
196
+
197
+ debug : false,
198
+
199
+ applyAction : function(img, dataImg, actionName, options) {
200
+
201
+ options = options || {};
202
+
203
+ var imageIsCanvas = (img.tagName.toLowerCase() == "canvas");
204
+ if (imageIsCanvas && Pixastic.Client.isIE()) {
205
+ if (Pixastic.debug) writeDebug("Tried to process a canvas element but browser is IE.");
206
+ return false;
207
+ }
208
+
209
+ var canvas, ctx;
210
+ var hasOutputCanvas = false;
211
+ if (Pixastic.Client.hasCanvas()) {
212
+ hasOutputCanvas = !!options.resultCanvas;
213
+ canvas = options.resultCanvas || document.createElement("canvas");
214
+ ctx = canvas.getContext("2d");
215
+ }
216
+
217
+ var w = img.offsetWidth;
218
+ var h = img.offsetHeight;
219
+
220
+ if (imageIsCanvas) {
221
+ w = img.width;
222
+ h = img.height;
223
+ }
224
+
225
+ // offsetWidth/Height might be 0 if the image is not in the document
226
+ if (w == 0 || h == 0) {
227
+ if (img.parentNode == null) {
228
+ // add the image to the doc (way out left), read its dimensions and remove it again
229
+ var oldpos = img.style.position;
230
+ var oldleft = img.style.left;
231
+ img.style.position = "absolute";
232
+ img.style.left = "-9999px";
233
+ document.body.appendChild(img);
234
+ w = img.offsetWidth;
235
+ h = img.offsetHeight;
236
+ document.body.removeChild(img);
237
+ img.style.position = oldpos;
238
+ img.style.left = oldleft;
239
+ } else {
240
+ if (Pixastic.debug) writeDebug("Image has 0 width and/or height.");
241
+ return;
242
+ }
243
+ }
244
+
245
+ if (actionName.indexOf("(") > -1) {
246
+ var tmp = actionName;
247
+ actionName = tmp.substr(0, tmp.indexOf("("));
248
+ var arg = tmp.match(/\((.*?)\)/);
249
+ if (arg[1]) {
250
+ arg = arg[1].split(";");
251
+ for (var a=0;a<arg.length;a++) {
252
+ thisArg = arg[a].split("=");
253
+ if (thisArg.length == 2) {
254
+ if (thisArg[0] == "rect") {
255
+ var rectVal = thisArg[1].split(",");
256
+ options[thisArg[0]] = {
257
+ left : parseInt(rectVal[0],10)||0,
258
+ top : parseInt(rectVal[1],10)||0,
259
+ width : parseInt(rectVal[2],10)||0,
260
+ height : parseInt(rectVal[3],10)||0
261
+ }
262
+ } else {
263
+ options[thisArg[0]] = thisArg[1];
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+
270
+ if (!options.rect) {
271
+ options.rect = {
272
+ left : 0, top : 0, width : w, height : h
273
+ };
274
+ } else {
275
+ options.rect.left = Math.round(options.rect.left);
276
+ options.rect.top = Math.round(options.rect.top);
277
+ options.rect.width = Math.round(options.rect.width);
278
+ options.rect.height = Math.round(options.rect.height);
279
+ }
280
+
281
+ var validAction = false;
282
+ if (Pixastic.Actions[actionName] && typeof Pixastic.Actions[actionName].process == "function") {
283
+ validAction = true;
284
+ }
285
+ if (!validAction) {
286
+ if (Pixastic.debug) writeDebug("Invalid action \"" + actionName + "\". Maybe file not included?");
287
+ return false;
288
+ }
289
+ if (!Pixastic.Actions[actionName].checkSupport()) {
290
+ if (Pixastic.debug) writeDebug("Action \"" + actionName + "\" not supported by this browser.");
291
+ return false;
292
+ }
293
+
294
+ if (Pixastic.Client.hasCanvas()) {
295
+ if (canvas !== img) {
296
+ canvas.width = w;
297
+ canvas.height = h;
298
+ }
299
+ if (!hasOutputCanvas) {
300
+ canvas.style.width = w+"px";
301
+ canvas.style.height = h+"px";
302
+ }
303
+ ctx.drawImage(dataImg,0,0,w,h);
304
+
305
+ if (!img.__pixastic_org_image) {
306
+ canvas.__pixastic_org_image = img;
307
+ canvas.__pixastic_org_width = w;
308
+ canvas.__pixastic_org_height = h;
309
+ } else {
310
+ canvas.__pixastic_org_image = img.__pixastic_org_image;
311
+ canvas.__pixastic_org_width = img.__pixastic_org_width;
312
+ canvas.__pixastic_org_height = img.__pixastic_org_height;
313
+ }
314
+
315
+ } else if (Pixastic.Client.isIE() && typeof img.__pixastic_org_style == "undefined") {
316
+ img.__pixastic_org_style = img.style.cssText;
317
+ }
318
+
319
+ var params = {
320
+ image : img,
321
+ canvas : canvas,
322
+ width : w,
323
+ height : h,
324
+ useData : true,
325
+ options : options
326
+ }
327
+
328
+ // Ok, let's do it!
329
+
330
+ var res = Pixastic.Actions[actionName].process(params);
331
+
332
+ if (!res) {
333
+ return false;
334
+ }
335
+
336
+ if (Pixastic.Client.hasCanvas()) {
337
+ if (params.useData) {
338
+ if (Pixastic.Client.hasCanvasImageData()) {
339
+ canvas.getContext("2d").putImageData(params.canvasData, options.rect.left, options.rect.top);
340
+
341
+ // Opera doesn't seem to update the canvas until we draw something on it, lets draw a 0x0 rectangle.
342
+ // Is this still so?
343
+ canvas.getContext("2d").fillRect(0,0,0,0);
344
+ }
345
+ }
346
+
347
+ if (!options.leaveDOM) {
348
+ // copy properties and stuff from the source image
349
+ canvas.title = img.title;
350
+ canvas.imgsrc = img.imgsrc;
351
+ if (!imageIsCanvas) canvas.alt = img.alt;
352
+ if (!imageIsCanvas) canvas.imgsrc = img.src;
353
+ canvas.className = img.className;
354
+ canvas.style.cssText = img.style.cssText;
355
+ canvas.name = img.name;
356
+ canvas.tabIndex = img.tabIndex;
357
+ canvas.id = img.id;
358
+ if (img.parentNode && img.parentNode.replaceChild) {
359
+ img.parentNode.replaceChild(canvas, img);
360
+ }
361
+ }
362
+
363
+ options.resultCanvas = canvas;
364
+
365
+ return canvas;
366
+ }
367
+
368
+ return img;
369
+ },
370
+
371
+ prepareData : function(params, getCopy) {
372
+ var ctx = params.canvas.getContext("2d");
373
+ var rect = params.options.rect;
374
+ var dataDesc = ctx.getImageData(rect.left, rect.top, rect.width, rect.height);
375
+ var data = dataDesc.data;
376
+ if (!getCopy) params.canvasData = dataDesc;
377
+ return data;
378
+ },
379
+
380
+ // load the image file
381
+ process : function(img, actionName, options, callback) {
382
+ if (img.tagName.toLowerCase() == "img") {
383
+ var dataImg = new Image();
384
+ dataImg.src = img.src;
385
+ if (dataImg.complete) {
386
+ var res = Pixastic.applyAction(img, dataImg, actionName, options);
387
+ if (callback) callback(res);
388
+ return res;
389
+ } else {
390
+ dataImg.onload = function() {
391
+ var res = Pixastic.applyAction(img, dataImg, actionName, options)
392
+ if (callback) callback(res);
393
+ }
394
+ }
395
+ }
396
+ if (img.tagName.toLowerCase() == "canvas") {
397
+ var res = Pixastic.applyAction(img, img, actionName, options);
398
+ if (callback) callback(res);
399
+ return res;
400
+ }
401
+ },
402
+
403
+ revert : function(img) {
404
+ if (Pixastic.Client.hasCanvas()) {
405
+ if (img.tagName.toLowerCase() == "canvas" && img.__pixastic_org_image) {
406
+ img.width = img.__pixastic_org_width;
407
+ img.height = img.__pixastic_org_height;
408
+ img.getContext("2d").drawImage(img.__pixastic_org_image, 0, 0);
409
+
410
+ if (img.parentNode && img.parentNode.replaceChild) {
411
+ img.parentNode.replaceChild(img.__pixastic_org_image, img);
412
+ }
413
+
414
+ return img;
415
+ }
416
+ } else if (Pixastic.Client.isIE()) {
417
+ if (typeof img.__pixastic_org_style != "undefined")
418
+ img.style.cssText = img.__pixastic_org_style;
419
+ }
420
+ },
421
+
422
+ Client : {
423
+ hasCanvas : hasCanvas,
424
+ hasCanvasImageData : hasCanvasImageData,
425
+ hasGlobalAlpha : hasGlobalAlpha,
426
+ isIE : function() {
427
+ return !!document.all && !!window.attachEvent && !window.opera;
428
+ }
429
+ },
430
+
431
+ Actions : {}
432
+ }
433
+
434
+
435
+ })();
436
+ /*
437
+ * Pixastic Lib - Blur filter - v0.1.0
438
+ * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
439
+ * License: [http://www.pixastic.com/lib/license.txt]
440
+ */
441
+
442
+ Pixastic.Actions.blur = {
443
+ process : function(params) {
444
+
445
+ if (typeof params.options.fixMargin == "undefined")
446
+ params.options.fixMargin = true;
447
+
448
+ if (Pixastic.Client.hasCanvasImageData()) {
449
+ var data = Pixastic.prepareData(params);
450
+ var dataCopy = Pixastic.prepareData(params, true)
451
+
452
+ /*
453
+ var kernel = [
454
+ [0.5, 1, 0.5],
455
+ [1, 2, 1],
456
+ [0.5, 1, 0.5]
457
+ ];
458
+ */
459
+
460
+ var kernel = [
461
+ [0, 1, 0],
462
+ [1, 2, 1],
463
+ [0, 1, 0]
464
+ ];
465
+
466
+ var weight = 0;
467
+ for (var i=0;i<3;i++) {
468
+ for (var j=0;j<3;j++) {
469
+ weight += kernel[i][j];
470
+ }
471
+ }
472
+
473
+ weight = 1 / (weight*2);
474
+
475
+ var rect = params.options.rect;
476
+ var w = rect.width;
477
+ var h = rect.height;
478
+
479
+ var w4 = w*4;
480
+ var y = h;
481
+ do {
482
+ var offsetY = (y-1)*w4;
483
+
484
+ var prevY = (y == 1) ? 0 : y-2;
485
+ var nextY = (y == h) ? y - 1 : y;
486
+
487
+ var offsetYPrev = prevY*w*4;
488
+ var offsetYNext = nextY*w*4;
489
+
490
+ var x = w;
491
+ do {
492
+ var offset = offsetY + (x*4-4);
493
+
494
+ var offsetPrev = offsetYPrev + ((x == 1) ? 0 : x-2) * 4;
495
+ var offsetNext = offsetYNext + ((x == w) ? x-1 : x) * 4;
496
+
497
+ data[offset] = (
498
+ /*
499
+ dataCopy[offsetPrev - 4]
500
+ + dataCopy[offsetPrev+4]
501
+ + dataCopy[offsetNext - 4]
502
+ + dataCopy[offsetNext+4]
503
+ +
504
+ */
505
+ (dataCopy[offsetPrev]
506
+ + dataCopy[offset-4]
507
+ + dataCopy[offset+4]
508
+ + dataCopy[offsetNext]) * 2
509
+ + dataCopy[offset] * 4
510
+ ) * weight;
511
+
512
+ data[offset+1] = (
513
+ /*
514
+ dataCopy[offsetPrev - 3]
515
+ + dataCopy[offsetPrev+5]
516
+ + dataCopy[offsetNext - 3]
517
+ + dataCopy[offsetNext+5]
518
+ +
519
+ */
520
+ (dataCopy[offsetPrev+1]
521
+ + dataCopy[offset-3]
522
+ + dataCopy[offset+5]
523
+ + dataCopy[offsetNext+1]) * 2
524
+ + dataCopy[offset+1] * 4
525
+ ) * weight;
526
+
527
+ data[offset+2] = (
528
+ /*
529
+ dataCopy[offsetPrev - 2]
530
+ + dataCopy[offsetPrev+6]
531
+ + dataCopy[offsetNext - 2]
532
+ + dataCopy[offsetNext+6]
533
+ +
534
+ */
535
+ (dataCopy[offsetPrev+2]
536
+ + dataCopy[offset-2]
537
+ + dataCopy[offset+6]
538
+ + dataCopy[offsetNext+2]) * 2
539
+ + dataCopy[offset+2] * 4
540
+ ) * weight;
541
+
542
+ } while (--x);
543
+ } while (--y);
544
+
545
+ return true;
546
+
547
+ } else if (Pixastic.Client.isIE()) {
548
+ params.image.style.filter += " progid:DXImageTransform.Microsoft.Blur(pixelradius=1.5)";
549
+
550
+ if (params.options.fixMargin) {
551
+ params.image.style.marginLeft = (parseInt(params.image.style.marginLeft,10)||0) - 2 + "px";
552
+ params.image.style.marginTop = (parseInt(params.image.style.marginTop,10)||0) - 2 + "px";
553
+ }
554
+
555
+ return true;
556
+ }
557
+ },
558
+ checkSupport : function() {
559
+ return (Pixastic.Client.hasCanvasImageData() || Pixastic.Client.isIE());
560
+ }
561
+ }/*
562
+ * Pixastic Lib - Blur Fast - v0.1.1
563
+ * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
564
+ * License: [http://www.pixastic.com/lib/license.txt]
565
+ */
566
+
567
+ Pixastic.Actions.blurfast = {
568
+ process : function(params) {
569
+
570
+ var amount = parseFloat(params.options.amount)||0;
571
+ var clear = !!(params.options.clear && params.options.clear != "false");
572
+
573
+ amount = Math.max(0,Math.min(5,amount));
574
+
575
+ if (Pixastic.Client.hasCanvas()) {
576
+ var rect = params.options.rect;
577
+
578
+ var ctx = params.canvas.getContext("2d");
579
+ ctx.save();
580
+ ctx.beginPath();
581
+ ctx.rect(rect.left, rect.top, rect.width, rect.height);
582
+ ctx.clip();
583
+
584
+ var scale = 1;
585
+ var smallWidth = Math.round(params.width / scale);
586
+ var smallHeight = Math.round(params.height / scale);
587
+
588
+ var copy = document.createElement("canvas");
589
+ copy.width = smallWidth;
590
+ copy.height = smallHeight;
591
+
592
+ var clear = false;
593
+ var steps = Math.round(amount * 60);
594
+
595
+ var copyCtx = copy.getContext("2d");
596
+ for (var i=0;i<steps;i++) {
597
+ var scaledWidth = Math.max(1,Math.round(smallWidth - i));
598
+ var scaledHeight = Math.max(1,Math.round(smallHeight - i));
599
+
600
+ copyCtx.clearRect(0,0,smallWidth,smallHeight);
601
+
602
+ copyCtx.drawImage(
603
+ params.canvas,
604
+ 0,0,params.width,params.height,
605
+ 0,0,scaledWidth,scaledHeight
606
+ );
607
+
608
+ if (clear)
609
+ ctx.clearRect(rect.left,rect.top,rect.width,rect.height);
610
+
611
+ ctx.drawImage(
612
+ copy,
613
+ 0,0,scaledWidth,scaledHeight,
614
+ 0,0,params.width,params.height
615
+ );
616
+ }
617
+
618
+ ctx.restore();
619
+
620
+ params.useData = false;
621
+ return true;
622
+ } else if (Pixastic.Client.isIE()) {
623
+ var radius = 10 * amount;
624
+ params.image.style.filter += " progid:DXImageTransform.Microsoft.Blur(pixelradius=" + radius + ")";
625
+
626
+ if (params.options.fixMargin || 1) {
627
+ params.image.style.marginLeft = (parseInt(params.image.style.marginLeft,10)||0) - Math.round(radius) + "px";
628
+ params.image.style.marginTop = (parseInt(params.image.style.marginTop,10)||0) - Math.round(radius) + "px";
629
+ }
630
+
631
+ return true;
632
+ }
633
+ },
634
+ checkSupport : function() {
635
+ return (Pixastic.Client.hasCanvas() || Pixastic.Client.isIE());
636
+ }
637
+ }