koda 0.0.8

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 (161) hide show
  1. data/lib/helpers/app_helper.rb +40 -0
  2. data/lib/helpers/koda_helper.rb +105 -0
  3. data/lib/helpers/view_helper.rb +146 -0
  4. data/lib/koda.rb +123 -0
  5. data/lib/models/hash.rb +29 -0
  6. data/lib/models/mongo_collection.rb +144 -0
  7. data/lib/models/mongo_config.rb +22 -0
  8. data/lib/models/mongo_database.rb +136 -0
  9. data/lib/models/mongo_document.rb +124 -0
  10. data/lib/models/mongo_grid.rb +85 -0
  11. data/lib/models/mongo_media.rb +55 -0
  12. data/lib/models/user_access_provider.rb +135 -0
  13. data/lib/models/user_context.rb +19 -0
  14. data/lib/routes/koda_api.rb +392 -0
  15. data/lib/routes/koda_site.rb +57 -0
  16. data/lib/views/console.erb +139 -0
  17. data/lib/views/explorer.erb +119 -0
  18. data/lib/views/login.erb +77 -0
  19. data/lib/views/not_allowed.erb +75 -0
  20. data/public/koda/Help/DataTypes.txt +82 -0
  21. data/public/koda/Help/KodaType_Template.js +48 -0
  22. data/public/koda/apple-touch-icon-114x114-precomposed.png +0 -0
  23. data/public/koda/apple-touch-icon-144x144-precomposed.png +0 -0
  24. data/public/koda/apple-touch-icon-57x57-precomposed.png +0 -0
  25. data/public/koda/apple-touch-icon-72x72-precomposed.png +0 -0
  26. data/public/koda/apple-touch-icon-precomposed.png +0 -0
  27. data/public/koda/apple-touch-icon.png +0 -0
  28. data/public/koda/css/bootstrap-responsive.css +1058 -0
  29. data/public/koda/css/bootstrap.css +5774 -0
  30. data/public/koda/css/main.css +288 -0
  31. data/public/koda/favicon.ico +0 -0
  32. data/public/koda/fonts/angelina-webfont.eot +0 -0
  33. data/public/koda/fonts/angelina-webfont.svg +228 -0
  34. data/public/koda/fonts/angelina-webfont.ttf +0 -0
  35. data/public/koda/fonts/angelina-webfont.woff +0 -0
  36. data/public/koda/fonts/coolvetica_rg-webfont.eot +0 -0
  37. data/public/koda/fonts/coolvetica_rg-webfont.svg +232 -0
  38. data/public/koda/fonts/coolvetica_rg-webfont.ttf +0 -0
  39. data/public/koda/fonts/coolvetica_rg-webfont.woff +0 -0
  40. data/public/koda/fonts/ladyic__-webfont.eot +0 -0
  41. data/public/koda/fonts/ladyic__-webfont.svg +257 -0
  42. data/public/koda/fonts/ladyic__-webfont.ttf +0 -0
  43. data/public/koda/fonts/ladyic__-webfont.woff +0 -0
  44. data/public/koda/images/ajax-loader.gif +0 -0
  45. data/public/koda/images/back.png +0 -0
  46. data/public/koda/images/bg-table-thead.png +0 -0
  47. data/public/koda/images/big_folder.png +0 -0
  48. data/public/koda/images/box_file.png +0 -0
  49. data/public/koda/images/car_add.png +0 -0
  50. data/public/koda/images/compress.png +0 -0
  51. data/public/koda/images/database_table.png +0 -0
  52. data/public/koda/images/feed_add.png +0 -0
  53. data/public/koda/images/feed_link.png +0 -0
  54. data/public/koda/images/file.png +0 -0
  55. data/public/koda/images/folder.png +0 -0
  56. data/public/koda/images/folder_image.png +0 -0
  57. data/public/koda/images/glyphicons-halflings-white.png +0 -0
  58. data/public/koda/images/glyphicons-halflings.png +0 -0
  59. data/public/koda/images/group_add.png +0 -0
  60. data/public/koda/images/group_key.png +0 -0
  61. data/public/koda/images/image_add.png +0 -0
  62. data/public/koda/images/layout_add.png +0 -0
  63. data/public/koda/images/package.png +0 -0
  64. data/public/koda/images/page_white_edit.png +0 -0
  65. data/public/koda/images/page_white_text.png +0 -0
  66. data/public/koda/images/photo_add.png +0 -0
  67. data/public/koda/images/toggle-collapse-dark.png +0 -0
  68. data/public/koda/images/toggle-collapse-light.png +0 -0
  69. data/public/koda/images/toggle-expand-dark.png +0 -0
  70. data/public/koda/images/toggle-expand-light.png +0 -0
  71. data/public/koda/images/twitter.png +0 -0
  72. data/public/koda/koda-editors/KodaEditor.js +843 -0
  73. data/public/koda/koda-editors/collection-editor.html +56 -0
  74. data/public/koda/koda-editors/generic-editor.css +112 -0
  75. data/public/koda/koda-editors/generic-editor.html +74 -0
  76. data/public/koda/koda-editors/koda-editor.css +72 -0
  77. data/public/koda/koda-editors/twitterfeed-editor.html +90 -0
  78. data/public/koda/koda-types/_builtin_registration.json +62 -0
  79. data/public/koda/koda-types/koda-access.json +49 -0
  80. data/public/koda/koda-types/koda-collection.json +12 -0
  81. data/public/koda/koda-types/koda-generictext.json +50 -0
  82. data/public/koda/koda-types/koda-media.json +58 -0
  83. data/public/koda/koda-types/koda-twitterfeed.json +79 -0
  84. data/public/koda/koda-types/koda-user.json +71 -0
  85. data/public/koda/nicEditorIcons.gif +0 -0
  86. data/public/koda/scripts/Koda.js +1200 -0
  87. data/public/koda/scripts/lib/DOMAssistant.js +4 -0
  88. data/public/koda/scripts/lib/modernizr.js +4 -0
  89. data/public/koda/scripts/lib/respond.js +2 -0
  90. data/public/koda/scripts/lib/selectivizr.js +5 -0
  91. data/public/koda/scripts/plugins/bootstrap.js +2027 -0
  92. data/public/koda/scripts/plugins/box.js +8 -0
  93. data/public/koda/scripts/plugins/fancybox/blank.gif +0 -0
  94. data/public/koda/scripts/plugins/fancybox/fancy_close.png +0 -0
  95. data/public/koda/scripts/plugins/fancybox/fancy_loading.png +0 -0
  96. data/public/koda/scripts/plugins/fancybox/fancy_nav_left.png +0 -0
  97. data/public/koda/scripts/plugins/fancybox/fancy_nav_right.png +0 -0
  98. data/public/koda/scripts/plugins/fancybox/fancy_shadow_e.png +0 -0
  99. data/public/koda/scripts/plugins/fancybox/fancy_shadow_n.png +0 -0
  100. data/public/koda/scripts/plugins/fancybox/fancy_shadow_ne.png +0 -0
  101. data/public/koda/scripts/plugins/fancybox/fancy_shadow_nw.png +0 -0
  102. data/public/koda/scripts/plugins/fancybox/fancy_shadow_s.png +0 -0
  103. data/public/koda/scripts/plugins/fancybox/fancy_shadow_se.png +0 -0
  104. data/public/koda/scripts/plugins/fancybox/fancy_shadow_sw.png +0 -0
  105. data/public/koda/scripts/plugins/fancybox/fancy_shadow_w.png +0 -0
  106. data/public/koda/scripts/plugins/fancybox/fancy_title_left.png +0 -0
  107. data/public/koda/scripts/plugins/fancybox/fancy_title_main.png +0 -0
  108. data/public/koda/scripts/plugins/fancybox/fancy_title_over.png +0 -0
  109. data/public/koda/scripts/plugins/fancybox/fancy_title_right.png +0 -0
  110. data/public/koda/scripts/plugins/fancybox/fancybox-x.png +0 -0
  111. data/public/koda/scripts/plugins/fancybox/fancybox-y.png +0 -0
  112. data/public/koda/scripts/plugins/fancybox/fancybox.png +0 -0
  113. data/public/koda/scripts/plugins/fancybox/jquery.easing-1.3.pack.js +72 -0
  114. data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.css +359 -0
  115. data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.js +1155 -0
  116. data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.pack.js +46 -0
  117. data/public/koda/scripts/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js +14 -0
  118. data/public/koda/scripts/plugins/fileuploader.js +1527 -0
  119. data/public/koda/scripts/plugins/jquery-class.js +7 -0
  120. data/public/koda/scripts/plugins/jquery.contextmenu/images/cut.png +0 -0
  121. data/public/koda/scripts/plugins/jquery.contextmenu/images/door.png +0 -0
  122. data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_copy.png +0 -0
  123. data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_delete.png +0 -0
  124. data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_edit.png +0 -0
  125. data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_paste.png +0 -0
  126. data/public/koda/scripts/plugins/jquery.contextmenu/jquery.contextMenu.css +63 -0
  127. data/public/koda/scripts/plugins/jquery.contextmenu/jquery.contextMenu.js +211 -0
  128. data/public/koda/scripts/plugins/jquery.js +2 -0
  129. data/public/koda/scripts/plugins/json2.js +277 -0
  130. data/public/koda/scripts/plugins/modernizr.js +2 -0
  131. data/public/koda/scripts/plugins/nicEdit.js +183 -0
  132. data/public/koda/scripts/plugins/qunit.js +1448 -0
  133. data/public/koda/scripts/plugins/spin.js +2 -0
  134. data/public/koda/scripts/plugins/uploader/README.md +77 -0
  135. data/public/koda/scripts/plugins/uploader/README.txt +89 -0
  136. data/public/koda/scripts/plugins/uploader/example/application.js +20 -0
  137. data/public/koda/scripts/plugins/uploader/example/index.html +109 -0
  138. data/public/koda/scripts/plugins/uploader/example/style.css +22 -0
  139. data/public/koda/scripts/plugins/uploader/example/upload.php +313 -0
  140. data/public/koda/scripts/plugins/uploader/jquery.fileupload-ui.css +100 -0
  141. data/public/koda/scripts/plugins/uploader/jquery.fileupload-ui.js +642 -0
  142. data/public/koda/scripts/plugins/uploader/jquery.fileupload.js +711 -0
  143. data/public/koda/scripts/plugins/uploader/jquery.iframe-transport.js +133 -0
  144. data/public/koda/scripts/plugins/uploader/pbar-ani.gif +0 -0
  145. data/public/koda/scripts/plugins/uploader/tests/index.html +115 -0
  146. data/public/koda/scripts/plugins/uploader/tests/tests.js +1008 -0
  147. data/public/koda/scripts/require.js +32 -0
  148. data/public/koda/scripts/specs.js +12 -0
  149. data/public/koda/scripts/specs/cd-command-spec.js +51 -0
  150. data/public/koda/scripts/specs/controller-spec.js +95 -0
  151. data/public/koda/scripts/specs/doubles/mock-command.js +21 -0
  152. data/public/koda/scripts/specs/doubles/mock-jamservice.js +33 -0
  153. data/public/koda/scripts/specs/doubles/mock-prompt.js +30 -0
  154. data/public/koda/scripts/specs/doubles/uiobject-double.js +15 -0
  155. data/public/koda/scripts/specs/edit-command-spec.js +76 -0
  156. data/public/koda/scripts/specs/ls-command-spec.js +61 -0
  157. data/public/koda/scripts/specs/mkdir-command-spec.js +40 -0
  158. data/public/koda/scripts/specs/peek-command-spec.js +24 -0
  159. data/public/koda/scripts/specs/remove-command-spec.js +37 -0
  160. data/public/koda/scripts/specs/service-spec.js +85 -0
  161. metadata +402 -0
@@ -0,0 +1,100 @@
1
+ @charset 'UTF-8';
2
+ /*
3
+ * jQuery File Upload UI Plugin CSS 5.0.5
4
+ * https://github.com/blueimp/jQuery-File-Upload
5
+ *
6
+ * Copyright 2010, Sebastian Tschan
7
+ * https://blueimp.net
8
+ *
9
+ * Licensed under the MIT license:
10
+ * http://creativecommons.org/licenses/MIT/
11
+ */
12
+
13
+ .ui-button input {
14
+ position: absolute;
15
+ top: 0;
16
+ right: 0;
17
+ margin: 0;
18
+ border: solid transparent;
19
+ border-width: 0 0 100px 200px;
20
+ opacity: 0;
21
+ filter: alpha(opacity=0);
22
+ -o-transform: translate(250px, -50px) scale(1);
23
+ -moz-transform: translate(-300px, 0) scale(4);
24
+ direction: ltr;
25
+ cursor: pointer;
26
+ }
27
+
28
+ .fileinput-button {
29
+ overflow: hidden;
30
+ }
31
+
32
+ /* Fix for IE 6: */
33
+ *html .fileinput-button {
34
+ padding: 2px 0;
35
+ }
36
+
37
+ /* Fix for IE 7: */
38
+ *+html .fileinput-button {
39
+ padding: 2px 0;
40
+ }
41
+
42
+ .fileupload-buttonbar {
43
+ padding: 0.2em 0.4em;
44
+ }
45
+
46
+ .fileupload-buttonbar .ui-button {
47
+ vertical-align: middle;
48
+ }
49
+
50
+ .fileupload-content {
51
+ padding: 0.2em 0.4em;
52
+ border-top-width: 0;
53
+ }
54
+
55
+ .ui-progressbar {
56
+ width: 200px;
57
+ height: 20px;
58
+ }
59
+
60
+ .ui-progressbar-value {
61
+ background: url(pbar-ani.gif);
62
+ }
63
+
64
+ .fileupload-progressbar {
65
+ width: 400px;
66
+ margin: 10px 0;
67
+ }
68
+
69
+ .files {
70
+ margin: 10px 0;
71
+ border-collapse: collapse;
72
+ }
73
+
74
+ .files td {
75
+ padding: 5px;
76
+ border-spacing: 5px;
77
+ }
78
+
79
+ .files img {
80
+ border: none;
81
+ }
82
+
83
+ .files .name {
84
+ padding: 0 10px;
85
+ }
86
+
87
+ .files .size {
88
+ padding: 0 10px 0 0;
89
+ text-align: right;
90
+ white-space: nowrap;
91
+ }
92
+
93
+ .ui-state-disabled .ui-state-disabled {
94
+ opacity: 1;
95
+ filter: alpha(opacity=100);
96
+ }
97
+
98
+ .ui-state-disabled input {
99
+ cursor: default;
100
+ }
@@ -0,0 +1,642 @@
1
+ /*
2
+ * jQuery File Upload User Interface Plugin 5.0.12
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2010, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://creativecommons.org/licenses/MIT/
10
+ */
11
+
12
+ /*jslint nomen: false, unparam: true, regexp: false */
13
+ /*global window, document, URL, webkitURL, FileReader, jQuery */
14
+
15
+ (function ($) {
16
+ 'use strict';
17
+
18
+ // The UI version extends the basic fileupload widget and adds
19
+ // a complete user interface based on the given upload/download
20
+ // templates.
21
+ $.widget('blueimpUI.fileupload', $.blueimp.fileupload, {
22
+
23
+ options: {
24
+ // By default, files added to the widget are uploaded as soon
25
+ // as the user clicks on the start buttons. To enable automatic
26
+ // uploads, set the following option to true:
27
+ autoUpload: false,
28
+ // The following option limits the number of files that are
29
+ // allowed to be uploaded using this widget:
30
+ maxNumberOfFiles: undefined,
31
+ // The maximum allowed file size:
32
+ maxFileSize: undefined,
33
+ // The minimum allowed file size:
34
+ minFileSize: 1,
35
+ // The regular expression for allowed file types, matches
36
+ // against either file type or file name:
37
+ acceptFileTypes: /.+$/i,
38
+ // The regular expression to define for which files a preview
39
+ // image is shown, matched against the file type:
40
+ previewFileTypes: /^image\/(gif|jpeg|png)$/,
41
+ // The maximum width of the preview images:
42
+ previewMaxWidth: 80,
43
+ // The maximum height of the preview images:
44
+ previewMaxHeight: 80,
45
+ // By default, preview images are displayed as canvas elements
46
+ // if supported by the browser. Set the following option to false
47
+ // to always display preview images as img elements:
48
+ previewAsCanvas: true,
49
+ // The file upload template that is given as first argument to the
50
+ // jQuery.tmpl method to render the file uploads:
51
+ uploadTemplate: $('#template-upload'),
52
+ // The file download template, that is given as first argument to the
53
+ // jQuery.tmpl method to render the file downloads:
54
+ downloadTemplate: $('#template-download'),
55
+ // The expected data type of the upload response, sets the dataType
56
+ // option of the $.ajax upload requests:
57
+ dataType: 'json',
58
+
59
+ // The add callback is invoked as soon as files are added to the fileupload
60
+ // widget (via file input selection, drag & drop or add API call).
61
+ // See the basic file upload widget for more information:
62
+ add: function (e, data) {
63
+ var that = $(this).data('fileupload');
64
+ that._adjustMaxNumberOfFiles(-data.files.length);
65
+ data.isAdjusted = true;
66
+ data.isValidated = that._validate(data.files);
67
+ data.context = that._renderUpload(data.files)
68
+ .appendTo($(this).find('.files')).fadeIn(function () {
69
+ // Fix for IE7 and lower:
70
+ $(this).show();
71
+ }).data('data', data);
72
+ if ((that.options.autoUpload || data.autoUpload) &&
73
+ data.isValidated) {
74
+ data.jqXHR = data.submit();
75
+ }
76
+ },
77
+ // Callback for the start of each file upload request:
78
+ send: function (e, data) {
79
+ if (!data.isValidated) {
80
+ var that = $(this).data('fileupload');
81
+ if (!data.isAdjusted) {
82
+ that._adjustMaxNumberOfFiles(-data.files.length);
83
+ }
84
+ if (!that._validate(data.files)) {
85
+ return false;
86
+ }
87
+ }
88
+ if (data.context && data.dataType &&
89
+ data.dataType.substr(0, 6) === 'iframe') {
90
+ // Iframe Transport does not support progress events.
91
+ // In lack of an indeterminate progress bar, we set
92
+ // the progress to 100%, showing the full animated bar:
93
+ data.context.find('.ui-progressbar').progressbar(
94
+ 'value',
95
+ parseInt(100, 10)
96
+ );
97
+ }
98
+ },
99
+ // Callback for successful uploads:
100
+ done: function (e, data) {
101
+ var that = $(this).data('fileupload');
102
+ if (data.context) {
103
+ data.context.each(function (index) {
104
+ var file = ($.isArray(data.result) &&
105
+ data.result[index]) || {error: 'emptyResult'};
106
+ if (file.error) {
107
+ that._adjustMaxNumberOfFiles(1);
108
+ }
109
+ $(this).fadeOut(function () {
110
+ that._renderDownload([file])
111
+ .css('display', 'none')
112
+ .replaceAll(this)
113
+ .fadeIn(function () {
114
+ // Fix for IE7 and lower:
115
+ $(this).show();
116
+ });
117
+ });
118
+ });
119
+ } else {
120
+ that._renderDownload(data.result)
121
+ .css('display', 'none')
122
+ .appendTo($(this).find('.files'))
123
+ .fadeIn(function () {
124
+ // Fix for IE7 and lower:
125
+ $(this).show();
126
+ });
127
+ }
128
+ },
129
+ // Callback for failed (abort or error) uploads:
130
+ fail: function (e, data) {
131
+ var that = $(this).data('fileupload');
132
+ that._adjustMaxNumberOfFiles(data.files.length);
133
+ if (data.context) {
134
+ data.context.each(function (index) {
135
+ $(this).fadeOut(function () {
136
+ if (data.errorThrown !== 'abort') {
137
+ var file = data.files[index];
138
+ file.error = file.error || data.errorThrown
139
+ || true;
140
+ that._renderDownload([file])
141
+ .css('display', 'none')
142
+ .replaceAll(this)
143
+ .fadeIn(function () {
144
+ // Fix for IE7 and lower:
145
+ $(this).show();
146
+ });
147
+ } else {
148
+ data.context.remove();
149
+ }
150
+ });
151
+ });
152
+ } else if (data.errorThrown !== 'abort') {
153
+ that._adjustMaxNumberOfFiles(-data.files.length);
154
+ data.context = that._renderUpload(data.files)
155
+ .css('display', 'none')
156
+ .appendTo($(this).find('.files'))
157
+ .fadeIn(function () {
158
+ // Fix for IE7 and lower:
159
+ $(this).show();
160
+ }).data('data', data);
161
+ }
162
+ },
163
+ // Callback for upload progress events:
164
+ progress: function (e, data) {
165
+ if (data.context) {
166
+ data.context.find('.ui-progressbar').progressbar(
167
+ 'value',
168
+ parseInt(data.loaded / data.total * 100, 10)
169
+ );
170
+ }
171
+ },
172
+ // Callback for global upload progress events:
173
+ progressall: function (e, data) {
174
+ $(this).find('.fileupload-progressbar').progressbar(
175
+ 'value',
176
+ parseInt(data.loaded / data.total * 100, 10)
177
+ );
178
+ },
179
+ // Callback for uploads start, equivalent to the global ajaxStart event:
180
+ start: function () {
181
+ $(this).find('.fileupload-progressbar')
182
+ .progressbar('value', 0).fadeIn();
183
+ },
184
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
185
+ stop: function () {
186
+ $(this).find('.fileupload-progressbar').fadeOut();
187
+ },
188
+ // Callback for file deletion:
189
+ destroy: function (e, data) {
190
+ var that = $(this).data('fileupload');
191
+ if (data.url) {
192
+ $.ajax(data)
193
+ .success(function () {
194
+ that._adjustMaxNumberOfFiles(1);
195
+ $(this).fadeOut(function () {
196
+ $(this).remove();
197
+ });
198
+ });
199
+ } else {
200
+ data.context.fadeOut(function () {
201
+ $(this).remove();
202
+ });
203
+ }
204
+ }
205
+ },
206
+
207
+ // Scales the given image (img HTML element)
208
+ // using the given options.
209
+ // Returns a canvas object if the canvas option is true
210
+ // and the browser supports canvas, else the scaled image:
211
+ _scaleImage: function (img, options) {
212
+ options = options || {};
213
+ var canvas = document.createElement('canvas'),
214
+ scale = Math.min(
215
+ (options.maxWidth || img.width) / img.width,
216
+ (options.maxHeight || img.height) / img.height
217
+ );
218
+ if (scale >= 1) {
219
+ scale = Math.max(
220
+ (options.minWidth || img.width) / img.width,
221
+ (options.minHeight || img.height) / img.height
222
+ );
223
+ }
224
+ img.width = parseInt(img.width * scale, 10);
225
+ img.height = parseInt(img.height * scale, 10);
226
+ if (!options.canvas || !canvas.getContext) {
227
+ return img;
228
+ }
229
+ canvas.width = img.width;
230
+ canvas.height = img.height;
231
+ canvas.getContext('2d')
232
+ .drawImage(img, 0, 0, img.width, img.height);
233
+ return canvas;
234
+ },
235
+
236
+ _createObjectURL: function (file) {
237
+ var undef = 'undefined',
238
+ urlAPI = (typeof window.createObjectURL !== undef && window) ||
239
+ (typeof URL !== undef && URL) ||
240
+ (typeof webkitURL !== undef && webkitURL);
241
+ return urlAPI ? urlAPI.createObjectURL(file) : false;
242
+ },
243
+
244
+ _revokeObjectURL: function (url) {
245
+ var undef = 'undefined',
246
+ urlAPI = (typeof window.revokeObjectURL !== undef && window) ||
247
+ (typeof URL !== undef && URL) ||
248
+ (typeof webkitURL !== undef && webkitURL);
249
+ return urlAPI ? urlAPI.revokeObjectURL(url) : false;
250
+ },
251
+
252
+ // Loads a given File object via FileReader interface,
253
+ // invokes the callback with a data url:
254
+ _loadFile: function (file, callback) {
255
+ if (typeof FileReader !== 'undefined' &&
256
+ FileReader.prototype.readAsDataURL) {
257
+ var fileReader = new FileReader();
258
+ fileReader.onload = function (e) {
259
+ callback(e.target.result);
260
+ };
261
+ fileReader.readAsDataURL(file);
262
+ return true;
263
+ }
264
+ return false;
265
+ },
266
+
267
+ // Loads an image for a given File object.
268
+ // Invokes the callback with an img or optional canvas
269
+ // element (if supported by the browser) as parameter:
270
+ _loadImage: function (file, callback, options) {
271
+ var that = this,
272
+ url,
273
+ img;
274
+ if (!options || !options.fileTypes ||
275
+ options.fileTypes.test(file.type)) {
276
+ url = this._createObjectURL(file);
277
+ img = $('<img>').bind('load', function () {
278
+ $(this).unbind('load');
279
+ that._revokeObjectURL(url);
280
+ callback(that._scaleImage(img[0], options));
281
+ }).prop('src', url);
282
+ if (!url) {
283
+ this._loadFile(file, function (url) {
284
+ img.prop('src', url);
285
+ });
286
+ }
287
+ }
288
+ },
289
+
290
+ // Link handler, that allows to download files
291
+ // by drag & drop of the links to the desktop:
292
+ _enableDragToDesktop: function () {
293
+ var link = $(this),
294
+ url = link.prop('href'),
295
+ name = decodeURIComponent(url.split('/').pop())
296
+ .replace(/:/g, '-'),
297
+ type = 'application/octet-stream';
298
+ link.bind('dragstart', function (e) {
299
+ try {
300
+ e.originalEvent.dataTransfer.setData(
301
+ 'DownloadURL',
302
+ [type, name, url].join(':')
303
+ );
304
+ } catch (err) {}
305
+ });
306
+ },
307
+
308
+ _adjustMaxNumberOfFiles: function (operand) {
309
+ if (typeof this.options.maxNumberOfFiles === 'number') {
310
+ this.options.maxNumberOfFiles += operand;
311
+ if (this.options.maxNumberOfFiles < 1) {
312
+ this._disableFileInputButton();
313
+ } else {
314
+ this._enableFileInputButton();
315
+ }
316
+ }
317
+ },
318
+
319
+ _formatFileSize: function (file) {
320
+ if (typeof file.size !== 'number') {
321
+ return '';
322
+ }
323
+ if (file.size >= 1000000000) {
324
+ return (file.size / 1000000000).toFixed(2) + ' GB';
325
+ }
326
+ if (file.size >= 1000000) {
327
+ return (file.size / 1000000).toFixed(2) + ' MB';
328
+ }
329
+ return (file.size / 1000).toFixed(2) + ' KB';
330
+ },
331
+
332
+ _hasError: function (file) {
333
+ if (file.error) {
334
+ return file.error;
335
+ }
336
+ // The number of added files is subtracted from
337
+ // maxNumberOfFiles before validation, so we check if
338
+ // maxNumberOfFiles is below 0 (instead of below 1):
339
+ if (this.options.maxNumberOfFiles < 0) {
340
+ return 'maxNumberOfFiles';
341
+ }
342
+ // Files are accepted if either the file type or the file name
343
+ // matches against the acceptFileTypes regular expression, as
344
+ // only browsers with support for the File API report the type:
345
+ if (!(this.options.acceptFileTypes.test(file.type) ||
346
+ this.options.acceptFileTypes.test(file.name))) {
347
+ return 'acceptFileTypes';
348
+ }
349
+ if (this.options.maxFileSize &&
350
+ file.size > this.options.maxFileSize) {
351
+ return 'maxFileSize';
352
+ }
353
+ if (typeof file.size === 'number' &&
354
+ file.size < this.options.minFileSize) {
355
+ return 'minFileSize';
356
+ }
357
+ return null;
358
+ },
359
+
360
+ _validate: function (files) {
361
+ var that = this,
362
+ valid;
363
+ $.each(files, function (index, file) {
364
+ file.error = that._hasError(file);
365
+ valid = !file.error;
366
+ });
367
+ return valid;
368
+ },
369
+
370
+ _uploadTemplateHelper: function (file) {
371
+ file.sizef = this._formatFileSize(file);
372
+ return file;
373
+ },
374
+
375
+ _renderUploadTemplate: function (files) {
376
+ var that = this;
377
+ return $.tmpl(
378
+ this.options.uploadTemplate,
379
+ $.map(files, function (file) {
380
+ return that._uploadTemplateHelper(file);
381
+ })
382
+ );
383
+ },
384
+
385
+ _renderUpload: function (files) {
386
+ var that = this,
387
+ options = this.options,
388
+ tmpl = this._renderUploadTemplate(files);
389
+ if (!(tmpl instanceof $)) {
390
+ return $();
391
+ }
392
+ tmpl.css('display', 'none');
393
+ // .slice(1).remove().end().first() removes all but the first
394
+ // element and selects only the first for the jQuery collection:
395
+ tmpl.find('.progress div').slice(1).remove().end().first()
396
+ .progressbar();
397
+ tmpl.find('.start button').slice(
398
+ this.options.autoUpload ? 0 : 1
399
+ ).remove().end().first()
400
+ .button({
401
+ text: false,
402
+ icons: {primary: 'ui-icon-circle-arrow-e'}
403
+ });
404
+ tmpl.find('.cancel button').slice(1).remove().end().first()
405
+ .button({
406
+ text: false,
407
+ icons: {primary: 'ui-icon-cancel'}
408
+ });
409
+ tmpl.find('.preview').each(function (index, node) {
410
+ that._loadImage(
411
+ files[index],
412
+ function (img) {
413
+ $(img).hide().appendTo(node).fadeIn();
414
+ },
415
+ {
416
+ maxWidth: options.previewMaxWidth,
417
+ maxHeight: options.previewMaxHeight,
418
+ fileTypes: options.previewFileTypes,
419
+ canvas: options.previewAsCanvas
420
+ }
421
+ );
422
+ });
423
+ return tmpl;
424
+ },
425
+
426
+ _downloadTemplateHelper: function (file) {
427
+ file.sizef = this._formatFileSize(file);
428
+ return file;
429
+ },
430
+
431
+ _renderDownloadTemplate: function (files) {
432
+ var that = this;
433
+ return $.tmpl(
434
+ this.options.downloadTemplate,
435
+ $.map(files, function (file) {
436
+ return that._downloadTemplateHelper(file);
437
+ })
438
+ );
439
+ },
440
+
441
+ _renderDownload: function (files) {
442
+ var tmpl = this._renderDownloadTemplate(files);
443
+ if (!(tmpl instanceof $)) {
444
+ return $();
445
+ }
446
+ tmpl.css('display', 'none');
447
+ tmpl.find('.delete button').button({
448
+ text: false,
449
+ icons: {primary: 'ui-icon-trash'}
450
+ });
451
+ tmpl.find('a').each(this._enableDragToDesktop);
452
+ return tmpl;
453
+ },
454
+
455
+ _startHandler: function (e) {
456
+ e.preventDefault();
457
+ var tmpl = $(this).closest('.template-upload'),
458
+ data = tmpl.data('data');
459
+ if (data && data.submit && !data.jqXHR) {
460
+ data.jqXHR = data.submit();
461
+ $(this).fadeOut();
462
+ }
463
+ },
464
+
465
+ _cancelHandler: function (e) {
466
+ e.preventDefault();
467
+ var tmpl = $(this).closest('.template-upload'),
468
+ data = tmpl.data('data') || {};
469
+ if (!data.jqXHR) {
470
+ data.errorThrown = 'abort';
471
+ e.data.fileupload._trigger('fail', e, data);
472
+ } else {
473
+ data.jqXHR.abort();
474
+ }
475
+ },
476
+
477
+ _deleteHandler: function (e) {
478
+ e.preventDefault();
479
+ var button = $(this);
480
+ e.data.fileupload._trigger('destroy', e, {
481
+ context: button.closest('.template-download'),
482
+ url: button.attr('data-url'),
483
+ type: button.attr('data-type'),
484
+ dataType: e.data.fileupload.options.dataType
485
+ });
486
+ },
487
+
488
+ _initEventHandlers: function () {
489
+ $.blueimp.fileupload.prototype._initEventHandlers.call(this);
490
+ var filesList = this.element.find('.files'),
491
+ eventData = {fileupload: this};
492
+ filesList.find('.start button')
493
+ .live(
494
+ 'click.' + this.options.namespace,
495
+ eventData,
496
+ this._startHandler
497
+ );
498
+ filesList.find('.cancel button')
499
+ .live(
500
+ 'click.' + this.options.namespace,
501
+ eventData,
502
+ this._cancelHandler
503
+ );
504
+ filesList.find('.delete button')
505
+ .live(
506
+ 'click.' + this.options.namespace,
507
+ eventData,
508
+ this._deleteHandler
509
+ );
510
+ },
511
+
512
+ _destroyEventHandlers: function () {
513
+ var filesList = this.element.find('.files');
514
+ filesList.find('.start button')
515
+ .die('click.' + this.options.namespace);
516
+ filesList.find('.cancel button')
517
+ .die('click.' + this.options.namespace);
518
+ filesList.find('.delete button')
519
+ .die('click.' + this.options.namespace);
520
+ $.blueimp.fileupload.prototype._destroyEventHandlers.call(this);
521
+ },
522
+
523
+ _initFileUploadButtonBar: function () {
524
+ var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
525
+ filesList = this.element.find('.files'),
526
+ ns = this.options.namespace;
527
+ fileUploadButtonBar
528
+ .addClass('ui-widget-header ui-corner-top');
529
+ this.element.find('.fileinput-button').each(function () {
530
+ var fileInput = $(this).find('input:file').detach();
531
+ $(this).button({icons: {primary: 'ui-icon-plusthick'}})
532
+ .append(fileInput);
533
+ });
534
+ fileUploadButtonBar.find('.start')
535
+ .button({icons: {primary: 'ui-icon-circle-arrow-e'}})
536
+ .bind('click.' + ns, function (e) {
537
+ e.preventDefault();
538
+ filesList.find('.start button').click();
539
+ });
540
+ fileUploadButtonBar.find('.cancel')
541
+ .button({icons: {primary: 'ui-icon-cancel'}})
542
+ .bind('click.' + ns, function (e) {
543
+ e.preventDefault();
544
+ filesList.find('.cancel button').click();
545
+ });
546
+ fileUploadButtonBar.find('.delete')
547
+ .button({icons: {primary: 'ui-icon-trash'}})
548
+ .bind('click.' + ns, function (e) {
549
+ e.preventDefault();
550
+ filesList.find('.delete button').click();
551
+ });
552
+ },
553
+
554
+ _destroyFileUploadButtonBar: function () {
555
+ this.element.find('.fileupload-buttonbar')
556
+ .removeClass('ui-widget-header ui-corner-top');
557
+ this.element.find('.fileinput-button').each(function () {
558
+ var fileInput = $(this).find('input:file').detach();
559
+ $(this).button('destroy')
560
+ .append(fileInput);
561
+ });
562
+ this.element.find('.fileupload-buttonbar button')
563
+ .unbind('click.' + this.options.namespace)
564
+ .button('destroy');
565
+ },
566
+
567
+ _enableFileInputButton: function () {
568
+ this.element.find('.fileinput-button input:file:disabled')
569
+ .each(function () {
570
+ var fileInput = $(this),
571
+ button = fileInput.parent();
572
+ fileInput.detach().prop('disabled', false);
573
+ button.button('enable').append(fileInput);
574
+ });
575
+ },
576
+
577
+ _disableFileInputButton: function () {
578
+ this.element.find('.fileinput-button input:file:enabled')
579
+ .each(function () {
580
+ var fileInput = $(this),
581
+ button = fileInput.parent();
582
+ fileInput.detach().prop('disabled', true);
583
+ button.button('disable').append(fileInput);
584
+ });
585
+ },
586
+
587
+ _initTemplates: function () {
588
+ // Handle cases where the templates are defined
589
+ // after the widget library has been included:
590
+ if (this.options.uploadTemplate instanceof $ &&
591
+ !this.options.uploadTemplate.length) {
592
+ this.options.uploadTemplate = $(
593
+ this.options.uploadTemplate.selector
594
+ );
595
+ }
596
+ if (this.options.downloadTemplate instanceof $ &&
597
+ !this.options.downloadTemplate.length) {
598
+ this.options.downloadTemplate = $(
599
+ this.options.downloadTemplate.selector
600
+ );
601
+ }
602
+ },
603
+
604
+ _create: function () {
605
+ $.blueimp.fileupload.prototype._create.call(this);
606
+ this._initTemplates();
607
+ this.element
608
+ .addClass('ui-widget');
609
+ this._initFileUploadButtonBar();
610
+ this.element.find('.fileupload-content')
611
+ .addClass('ui-widget-content ui-corner-bottom');
612
+ this.element.find('.fileupload-progressbar')
613
+ .hide().progressbar();
614
+ },
615
+
616
+ destroy: function () {
617
+ this.element.find('.fileupload-progressbar')
618
+ .progressbar('destroy');
619
+ this.element.find('.fileupload-content')
620
+ .removeClass('ui-widget-content ui-corner-bottom');
621
+ this._destroyFileUploadButtonBar();
622
+ this.element.removeClass('ui-widget');
623
+ $.blueimp.fileupload.prototype.destroy.call(this);
624
+ },
625
+
626
+ enable: function () {
627
+ $.blueimp.fileupload.prototype.enable.call(this);
628
+ this.element.find(':ui-button').not('.fileinput-button')
629
+ .button('enable');
630
+ this._enableFileInputButton();
631
+ },
632
+
633
+ disable: function () {
634
+ this.element.find(':ui-button').not('.fileinput-button')
635
+ .button('disable');
636
+ this._disableFileInputButton();
637
+ $.blueimp.fileupload.prototype.disable.call(this);
638
+ }
639
+
640
+ });
641
+
642
+ }(jQuery));