card-mod-script 0.11.0

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 (126) hide show
  1. checksums.yaml +7 -0
  2. data/lib/javascript/decko/autosave.js.coffee +30 -0
  3. data/lib/javascript/decko/bridge.js.coffee +31 -0
  4. data/lib/javascript/decko/card_menu.js.coffee +26 -0
  5. data/lib/javascript/decko/components.js.coffee +51 -0
  6. data/lib/javascript/decko/decko.js.coffee +100 -0
  7. data/lib/javascript/decko/doubleclick.js.coffee +30 -0
  8. data/lib/javascript/decko/editor.js.coffee +55 -0
  9. data/lib/javascript/decko/filter.js.coffee +176 -0
  10. data/lib/javascript/decko/filter_items.js.coffee +128 -0
  11. data/lib/javascript/decko/filter_links.js.coffee +81 -0
  12. data/lib/javascript/decko/follow.js.coffee +22 -0
  13. data/lib/javascript/decko/layout.js.coffee +76 -0
  14. data/lib/javascript/decko/link_editor.js.coffee +61 -0
  15. data/lib/javascript/decko/mod.js.coffee +85 -0
  16. data/lib/javascript/decko/modal.js.coffee +110 -0
  17. data/lib/javascript/decko/name_editor.js.coffee +51 -0
  18. data/lib/javascript/decko/navbox.js.coffee +74 -0
  19. data/lib/javascript/decko/nest_editor.js.coffee +166 -0
  20. data/lib/javascript/decko/nest_editor_name.js.coffee +102 -0
  21. data/lib/javascript/decko/nest_editor_options.js.coffee +93 -0
  22. data/lib/javascript/decko/nest_editor_rules.js.coffee +3 -0
  23. data/lib/javascript/decko/overlay.js.coffee +57 -0
  24. data/lib/javascript/decko/recaptcha.js.coffee +19 -0
  25. data/lib/javascript/decko/selectable_filtered_content.js.coffee +12 -0
  26. data/lib/javascript/decko/slot.js.coffee +172 -0
  27. data/lib/javascript/decko/slot_ready.js.coffee +11 -0
  28. data/lib/javascript/decko/slotter.js.coffee +269 -0
  29. data/lib/javascript/decko/upload.js.coffee +57 -0
  30. data/lib/javascript/jquery-ui.js +10 -0
  31. data/lib/javascript/jquery.autosize.js +274 -0
  32. data/lib/javascript/jquery.iframe-transport.js +185 -0
  33. data/lib/javascript/script_html5shiv_printshiv.js +1 -0
  34. data/lib/javascript/script_pointer_config.js.coffee +80 -0
  35. data/lib/javascript/script_pointer_list_editor.js.coffee +67 -0
  36. data/lib/javascript/theme-textmate.js +130 -0
  37. data/set/abstract/script.rb +85 -0
  38. data/set/right/script.rb +19 -0
  39. data/set/self/01_script_libraries.rb +1 -0
  40. data/set/self/script.rb +1 -0
  41. data/set/self/script_decko.rb +12 -0
  42. data/set/self/script_editors.rb +1 -0
  43. data/set/self/script_html5shiv_printshiv.rb +11 -0
  44. data/set/self/script_jquery.rb +10 -0
  45. data/set/self/script_jquery_helper.rb +14 -0
  46. data/set/self/script_mods.rb +1 -0
  47. data/set/self/script_pointer_config.rb +9 -0
  48. data/set/type/coffee_script.rb +25 -0
  49. data/set/type/java_script.rb +9 -0
  50. data/vendor/jquery_file_upload/CONTRIBUTING.md +15 -0
  51. data/vendor/jquery_file_upload/LICENSE.txt +21 -0
  52. data/vendor/jquery_file_upload/README.md +107 -0
  53. data/vendor/jquery_file_upload/angularjs.html +211 -0
  54. data/vendor/jquery_file_upload/basic-plus.html +226 -0
  55. data/vendor/jquery_file_upload/basic.html +136 -0
  56. data/vendor/jquery_file_upload/bower-version-update.js +16 -0
  57. data/vendor/jquery_file_upload/bower.json +64 -0
  58. data/vendor/jquery_file_upload/cors/postmessage.html +75 -0
  59. data/vendor/jquery_file_upload/cors/result.html +24 -0
  60. data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +21 -0
  61. data/vendor/jquery_file_upload/css/jquery-ui-demo.css +67 -0
  62. data/vendor/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  63. data/vendor/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  64. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +57 -0
  65. data/vendor/jquery_file_upload/css/jquery.fileupload.css +37 -0
  66. data/vendor/jquery_file_upload/css/style.css +15 -0
  67. data/vendor/jquery_file_upload/img/loading.gif +0 -0
  68. data/vendor/jquery_file_upload/img/progressbar.gif +0 -0
  69. data/vendor/jquery_file_upload/index.html +255 -0
  70. data/vendor/jquery_file_upload/jquery-ui.html +252 -0
  71. data/vendor/jquery_file_upload/js/app.js +101 -0
  72. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +126 -0
  73. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +89 -0
  74. data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +437 -0
  75. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +113 -0
  76. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +326 -0
  77. data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +161 -0
  78. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +178 -0
  79. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +714 -0
  80. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +125 -0
  81. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +113 -0
  82. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1486 -0
  83. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +224 -0
  84. data/vendor/jquery_file_upload/js/main.js +75 -0
  85. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +748 -0
  86. data/vendor/jquery_file_upload/package.json +55 -0
  87. data/vendor/jquery_file_upload/server/gae-go/app.yaml +12 -0
  88. data/vendor/jquery_file_upload/server/gae-go/app/main.go +361 -0
  89. data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  90. data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +2 -0
  91. data/vendor/jquery_file_upload/server/gae-python/app.yaml +17 -0
  92. data/vendor/jquery_file_upload/server/gae-python/main.py +204 -0
  93. data/vendor/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  94. data/vendor/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  95. data/vendor/jquery_file_upload/server/php/Dockerfile +38 -0
  96. data/vendor/jquery_file_upload/server/php/UploadHandler.php +1411 -0
  97. data/vendor/jquery_file_upload/server/php/docker-compose.yml +9 -0
  98. data/vendor/jquery_file_upload/server/php/index.php +15 -0
  99. data/vendor/jquery_file_upload/test/index.html +172 -0
  100. data/vendor/jquery_file_upload/test/test.js +1292 -0
  101. data/vendor/jquery_rails/CHANGELOG.md +359 -0
  102. data/vendor/jquery_rails/CONTRIBUTING.md +132 -0
  103. data/vendor/jquery_rails/Gemfile +22 -0
  104. data/vendor/jquery_rails/MIT-LICENSE +21 -0
  105. data/vendor/jquery_rails/README.md +75 -0
  106. data/vendor/jquery_rails/Rakefile +59 -0
  107. data/vendor/jquery_rails/VERSIONS.md +62 -0
  108. data/vendor/jquery_rails/jquery-rails.gemspec +26 -0
  109. data/vendor/jquery_rails/lib/jquery-rails.rb +1 -0
  110. data/vendor/jquery_rails/lib/jquery/assert_select.rb +149 -0
  111. data/vendor/jquery_rails/lib/jquery/rails.rb +8 -0
  112. data/vendor/jquery_rails/lib/jquery/rails/engine.rb +6 -0
  113. data/vendor/jquery_rails/lib/jquery/rails/version.rb +9 -0
  114. data/vendor/jquery_rails/test/assert_select_jquery_test.rb +85 -0
  115. data/vendor/jquery_rails/test/test_helper.rb +6 -0
  116. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.js +11008 -0
  117. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.js +5 -0
  118. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.map +1 -0
  119. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.js +9814 -0
  120. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.js +4 -0
  121. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.map +1 -0
  122. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.js +10364 -0
  123. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.js +2 -0
  124. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.map +1 -0
  125. data/vendor/jquery_rails/vendor/assets/javascripts/jquery_ujs.js +555 -0
  126. metadata +212 -0
@@ -0,0 +1,101 @@
1
+ /*
2
+ * jQuery File Upload Plugin Angular JS Example
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * https://opensource.org/licenses/MIT
10
+ */
11
+
12
+ /* jshint nomen:false */
13
+ /* global window, angular */
14
+
15
+ ;(function () {
16
+ 'use strict';
17
+
18
+ var isOnGitHub = window.location.hostname === 'blueimp.github.io',
19
+ url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/';
20
+
21
+ angular.module('demo', [
22
+ 'blueimp.fileupload'
23
+ ])
24
+ .config([
25
+ '$httpProvider', 'fileUploadProvider',
26
+ function ($httpProvider, fileUploadProvider) {
27
+ delete $httpProvider.defaults.headers.common['X-Requested-With'];
28
+ fileUploadProvider.defaults.redirect = window.location.href.replace(
29
+ /\/[^\/]*$/,
30
+ '/cors/result.html?%s'
31
+ );
32
+ if (isOnGitHub) {
33
+ // Demo settings:
34
+ angular.extend(fileUploadProvider.defaults, {
35
+ // Enable image resizing, except for Android and Opera,
36
+ // which actually support image resizing, but fail to
37
+ // send Blob objects via XHR requests:
38
+ disableImageResize: /Android(?!.*Chrome)|Opera/
39
+ .test(window.navigator.userAgent),
40
+ maxFileSize: 999000,
41
+ acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
42
+ });
43
+ }
44
+ }
45
+ ])
46
+
47
+ .controller('DemoFileUploadController', [
48
+ '$scope', '$http', '$filter', '$window',
49
+ function ($scope, $http) {
50
+ $scope.options = {
51
+ url: url
52
+ };
53
+ if (!isOnGitHub) {
54
+ $scope.loadingFiles = true;
55
+ $http.get(url)
56
+ .then(
57
+ function (response) {
58
+ $scope.loadingFiles = false;
59
+ $scope.queue = response.data.files || [];
60
+ },
61
+ function () {
62
+ $scope.loadingFiles = false;
63
+ }
64
+ );
65
+ }
66
+ }
67
+ ])
68
+
69
+ .controller('FileDestroyController', [
70
+ '$scope', '$http',
71
+ function ($scope, $http) {
72
+ var file = $scope.file,
73
+ state;
74
+ if (file.url) {
75
+ file.$state = function () {
76
+ return state;
77
+ };
78
+ file.$destroy = function () {
79
+ state = 'pending';
80
+ return $http({
81
+ url: file.deleteUrl,
82
+ method: file.deleteType
83
+ }).then(
84
+ function () {
85
+ state = 'resolved';
86
+ $scope.clear(file);
87
+ },
88
+ function () {
89
+ state = 'rejected';
90
+ }
91
+ );
92
+ };
93
+ } else if (!file.$cancel && !file._index) {
94
+ file.$cancel = function () {
95
+ $scope.clear(file);
96
+ };
97
+ }
98
+ }
99
+ ]);
100
+
101
+ }());
@@ -0,0 +1,126 @@
1
+ /*
2
+ * jQuery postMessage Transport Plugin
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * https://opensource.org/licenses/MIT
10
+ */
11
+
12
+ /* global define, require, window, document */
13
+
14
+ ;(function (factory) {
15
+ 'use strict';
16
+ if (typeof define === 'function' && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define(['jquery'], factory);
19
+ } else if (typeof exports === 'object') {
20
+ // Node/CommonJS:
21
+ factory(require('jquery'));
22
+ } else {
23
+ // Browser globals:
24
+ factory(window.jQuery);
25
+ }
26
+ }(function ($) {
27
+ 'use strict';
28
+
29
+ var counter = 0,
30
+ names = [
31
+ 'accepts',
32
+ 'cache',
33
+ 'contents',
34
+ 'contentType',
35
+ 'crossDomain',
36
+ 'data',
37
+ 'dataType',
38
+ 'headers',
39
+ 'ifModified',
40
+ 'mimeType',
41
+ 'password',
42
+ 'processData',
43
+ 'timeout',
44
+ 'traditional',
45
+ 'type',
46
+ 'url',
47
+ 'username'
48
+ ],
49
+ convert = function (p) {
50
+ return p;
51
+ };
52
+
53
+ $.ajaxSetup({
54
+ converters: {
55
+ 'postmessage text': convert,
56
+ 'postmessage json': convert,
57
+ 'postmessage html': convert
58
+ }
59
+ });
60
+
61
+ $.ajaxTransport('postmessage', function (options) {
62
+ if (options.postMessage && window.postMessage) {
63
+ var iframe,
64
+ loc = $('<a>').prop('href', options.postMessage)[0],
65
+ target = loc.protocol + '//' + loc.host,
66
+ xhrUpload = options.xhr().upload;
67
+ // IE always includes the port for the host property of a link
68
+ // element, but not in the location.host or origin property for the
69
+ // default http port 80 and https port 443, so we strip it:
70
+ if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
71
+ target = target.replace(/:(80|443)$/, '');
72
+ }
73
+ return {
74
+ send: function (_, completeCallback) {
75
+ counter += 1;
76
+ var message = {
77
+ id: 'postmessage-transport-' + counter
78
+ },
79
+ eventName = 'message.' + message.id;
80
+ iframe = $(
81
+ '<iframe style="display:none;" src="' +
82
+ options.postMessage + '" name="' +
83
+ message.id + '"></iframe>'
84
+ ).bind('load', function () {
85
+ $.each(names, function (i, name) {
86
+ message[name] = options[name];
87
+ });
88
+ message.dataType = message.dataType.replace('postmessage ', '');
89
+ $(window).bind(eventName, function (e) {
90
+ e = e.originalEvent;
91
+ var data = e.data,
92
+ ev;
93
+ if (e.origin === target && data.id === message.id) {
94
+ if (data.type === 'progress') {
95
+ ev = document.createEvent('Event');
96
+ ev.initEvent(data.type, false, true);
97
+ $.extend(ev, data);
98
+ xhrUpload.dispatchEvent(ev);
99
+ } else {
100
+ completeCallback(
101
+ data.status,
102
+ data.statusText,
103
+ {postmessage: data.result},
104
+ data.headers
105
+ );
106
+ iframe.remove();
107
+ $(window).unbind(eventName);
108
+ }
109
+ }
110
+ });
111
+ iframe[0].contentWindow.postMessage(
112
+ message,
113
+ target
114
+ );
115
+ }).appendTo(document.body);
116
+ },
117
+ abort: function () {
118
+ if (iframe) {
119
+ iframe.remove();
120
+ }
121
+ }
122
+ };
123
+ }
124
+ });
125
+
126
+ }));
@@ -0,0 +1,89 @@
1
+ /*
2
+ * jQuery XDomainRequest Transport Plugin
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * https://opensource.org/licenses/MIT
10
+ *
11
+ * Based on Julian Aubourg's ajaxHooks xdr.js:
12
+ * https://github.com/jaubourg/ajaxHooks/
13
+ */
14
+
15
+ /* global define, require, window, XDomainRequest */
16
+
17
+ ;(function (factory) {
18
+ 'use strict';
19
+ if (typeof define === 'function' && define.amd) {
20
+ // Register as an anonymous AMD module:
21
+ define(['jquery'], factory);
22
+ } else if (typeof exports === 'object') {
23
+ // Node/CommonJS:
24
+ factory(require('jquery'));
25
+ } else {
26
+ // Browser globals:
27
+ factory(window.jQuery);
28
+ }
29
+ }(function ($) {
30
+ 'use strict';
31
+ if (window.XDomainRequest && !$.support.cors) {
32
+ $.ajaxTransport(function (s) {
33
+ if (s.crossDomain && s.async) {
34
+ if (s.timeout) {
35
+ s.xdrTimeout = s.timeout;
36
+ delete s.timeout;
37
+ }
38
+ var xdr;
39
+ return {
40
+ send: function (headers, completeCallback) {
41
+ var addParamChar = /\?/.test(s.url) ? '&' : '?';
42
+ function callback(status, statusText, responses, responseHeaders) {
43
+ xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
44
+ xdr = null;
45
+ completeCallback(status, statusText, responses, responseHeaders);
46
+ }
47
+ xdr = new XDomainRequest();
48
+ // XDomainRequest only supports GET and POST:
49
+ if (s.type === 'DELETE') {
50
+ s.url = s.url + addParamChar + '_method=DELETE';
51
+ s.type = 'POST';
52
+ } else if (s.type === 'PUT') {
53
+ s.url = s.url + addParamChar + '_method=PUT';
54
+ s.type = 'POST';
55
+ } else if (s.type === 'PATCH') {
56
+ s.url = s.url + addParamChar + '_method=PATCH';
57
+ s.type = 'POST';
58
+ }
59
+ xdr.open(s.type, s.url);
60
+ xdr.onload = function () {
61
+ callback(
62
+ 200,
63
+ 'OK',
64
+ {text: xdr.responseText},
65
+ 'Content-Type: ' + xdr.contentType
66
+ );
67
+ };
68
+ xdr.onerror = function () {
69
+ callback(404, 'Not Found');
70
+ };
71
+ if (s.xdrTimeout) {
72
+ xdr.ontimeout = function () {
73
+ callback(0, 'timeout');
74
+ };
75
+ xdr.timeout = s.xdrTimeout;
76
+ }
77
+ xdr.send((s.hasContent && s.data) || null);
78
+ },
79
+ abort: function () {
80
+ if (xdr) {
81
+ xdr.onerror = $.noop();
82
+ xdr.abort();
83
+ }
84
+ }
85
+ };
86
+ }
87
+ });
88
+ }
89
+ }));
@@ -0,0 +1,437 @@
1
+ /*
2
+ * jQuery File Upload AngularJS Plugin
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2013, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * https://opensource.org/licenses/MIT
10
+ */
11
+
12
+ /* jshint nomen:false */
13
+ /* global define, angular, require */
14
+
15
+ ;(function (factory) {
16
+ 'use strict';
17
+ if (typeof define === 'function' && define.amd) {
18
+ // Register as an anonymous AMD module:
19
+ define([
20
+ 'jquery',
21
+ 'angular',
22
+ './jquery.fileupload-image',
23
+ './jquery.fileupload-audio',
24
+ './jquery.fileupload-video',
25
+ './jquery.fileupload-validate'
26
+ ], factory);
27
+ } else if (typeof exports === 'object') {
28
+ // Node/CommonJS:
29
+ factory(
30
+ require('jquery'),
31
+ require('angular'),
32
+ require('./jquery.fileupload-image'),
33
+ require('./jquery.fileupload-audio'),
34
+ require('./jquery.fileupload-video'),
35
+ require('./jquery.fileupload-validate')
36
+ );
37
+ } else {
38
+ factory();
39
+ }
40
+ }(function () {
41
+ 'use strict';
42
+
43
+ angular.module('blueimp.fileupload', [])
44
+
45
+ // The fileUpload service provides configuration options
46
+ // for the fileUpload directive and default handlers for
47
+ // File Upload events:
48
+ .provider('fileUpload', function () {
49
+ var scopeEvalAsync = function (expression) {
50
+ var scope = angular.element(this)
51
+ .fileupload('option', 'scope');
52
+ // Schedule a new $digest cycle if not already inside of one
53
+ // and evaluate the given expression:
54
+ scope.$evalAsync(expression);
55
+ },
56
+ addFileMethods = function (scope, data) {
57
+ var files = data.files,
58
+ file = files[0];
59
+ angular.forEach(files, function (file, index) {
60
+ file._index = index;
61
+ file.$state = function () {
62
+ return data.state();
63
+ };
64
+ file.$processing = function () {
65
+ return data.processing();
66
+ };
67
+ file.$progress = function () {
68
+ return data.progress();
69
+ };
70
+ file.$response = function () {
71
+ return data.response();
72
+ };
73
+ });
74
+ file.$submit = function () {
75
+ if (!file.error) {
76
+ return data.submit();
77
+ }
78
+ };
79
+ file.$cancel = function () {
80
+ return data.abort();
81
+ };
82
+ },
83
+ $config;
84
+ $config = this.defaults = {
85
+ handleResponse: function (e, data) {
86
+ var files = data.result && data.result.files;
87
+ if (files) {
88
+ data.scope.replace(data.files, files);
89
+ } else if (data.errorThrown ||
90
+ data.textStatus === 'error') {
91
+ data.files[0].error = data.errorThrown ||
92
+ data.textStatus;
93
+ }
94
+ },
95
+ add: function (e, data) {
96
+ if (e.isDefaultPrevented()) {
97
+ return false;
98
+ }
99
+ var scope = data.scope,
100
+ filesCopy = [];
101
+ angular.forEach(data.files, function (file) {
102
+ filesCopy.push(file);
103
+ });
104
+ scope.$parent.$applyAsync(function () {
105
+ addFileMethods(scope, data);
106
+ var method = scope.option('prependFiles') ?
107
+ 'unshift' : 'push';
108
+ Array.prototype[method].apply(scope.queue, data.files);
109
+ });
110
+ data.process(function () {
111
+ return scope.process(data);
112
+ }).always(function () {
113
+ scope.$parent.$applyAsync(function () {
114
+ addFileMethods(scope, data);
115
+ scope.replace(filesCopy, data.files);
116
+ });
117
+ }).then(function () {
118
+ if ((scope.option('autoUpload') ||
119
+ data.autoUpload) &&
120
+ data.autoUpload !== false) {
121
+ data.submit();
122
+ }
123
+ });
124
+ },
125
+ done: function (e, data) {
126
+ if (e.isDefaultPrevented()) {
127
+ return false;
128
+ }
129
+ var that = this;
130
+ data.scope.$apply(function () {
131
+ data.handleResponse.call(that, e, data);
132
+ });
133
+ },
134
+ fail: function (e, data) {
135
+ if (e.isDefaultPrevented()) {
136
+ return false;
137
+ }
138
+ var that = this,
139
+ scope = data.scope;
140
+ if (data.errorThrown === 'abort') {
141
+ scope.clear(data.files);
142
+ return;
143
+ }
144
+ scope.$apply(function () {
145
+ data.handleResponse.call(that, e, data);
146
+ });
147
+ },
148
+ stop: scopeEvalAsync,
149
+ processstart: scopeEvalAsync,
150
+ processstop: scopeEvalAsync,
151
+ getNumberOfFiles: function () {
152
+ var scope = this.scope;
153
+ return scope.queue.length - scope.processing();
154
+ },
155
+ dataType: 'json',
156
+ autoUpload: false
157
+ };
158
+ this.$get = [
159
+ function () {
160
+ return {
161
+ defaults: $config
162
+ };
163
+ }
164
+ ];
165
+ })
166
+
167
+ // Format byte numbers to readable presentations:
168
+ .provider('formatFileSizeFilter', function () {
169
+ var $config = {
170
+ // Byte units following the IEC format
171
+ // http://en.wikipedia.org/wiki/Kilobyte
172
+ units: [
173
+ {size: 1000000000, suffix: ' GB'},
174
+ {size: 1000000, suffix: ' MB'},
175
+ {size: 1000, suffix: ' KB'}
176
+ ]
177
+ };
178
+ this.defaults = $config;
179
+ this.$get = function () {
180
+ return function (bytes) {
181
+ if (!angular.isNumber(bytes)) {
182
+ return '';
183
+ }
184
+ var unit = true,
185
+ i = 0,
186
+ prefix,
187
+ suffix;
188
+ while (unit) {
189
+ unit = $config.units[i];
190
+ prefix = unit.prefix || '';
191
+ suffix = unit.suffix || '';
192
+ if (i === $config.units.length - 1 || bytes >= unit.size) {
193
+ return prefix + (bytes / unit.size).toFixed(2) + suffix;
194
+ }
195
+ i += 1;
196
+ }
197
+ };
198
+ };
199
+ })
200
+
201
+ // The FileUploadController initializes the fileupload widget and
202
+ // provides scope methods to control the File Upload functionality:
203
+ .controller('FileUploadController', [
204
+ '$scope', '$element', '$attrs', '$window', 'fileUpload','$q',
205
+ function ($scope, $element, $attrs, $window, fileUpload, $q) {
206
+ var uploadMethods = {
207
+ progress: function () {
208
+ return $element.fileupload('progress');
209
+ },
210
+ active: function () {
211
+ return $element.fileupload('active');
212
+ },
213
+ option: function (option, data) {
214
+ if (arguments.length === 1) {
215
+ return $element.fileupload('option', option);
216
+ }
217
+ $element.fileupload('option', option, data);
218
+ },
219
+ add: function (data) {
220
+ return $element.fileupload('add', data);
221
+ },
222
+ send: function (data) {
223
+ return $element.fileupload('send', data);
224
+ },
225
+ process: function (data) {
226
+ return $element.fileupload('process', data);
227
+ },
228
+ processing: function (data) {
229
+ return $element.fileupload('processing', data);
230
+ }
231
+ };
232
+ $scope.disabled = !$window.jQuery.support.fileInput;
233
+ $scope.queue = $scope.queue || [];
234
+ $scope.clear = function (files) {
235
+ var queue = this.queue,
236
+ i = queue.length,
237
+ file = files,
238
+ length = 1;
239
+ if (angular.isArray(files)) {
240
+ file = files[0];
241
+ length = files.length;
242
+ }
243
+ while (i) {
244
+ i -= 1;
245
+ if (queue[i] === file) {
246
+ return queue.splice(i, length);
247
+ }
248
+ }
249
+ };
250
+ $scope.replace = function (oldFiles, newFiles) {
251
+ var queue = this.queue,
252
+ file = oldFiles[0],
253
+ i,
254
+ j;
255
+ for (i = 0; i < queue.length; i += 1) {
256
+ if (queue[i] === file) {
257
+ for (j = 0; j < newFiles.length; j += 1) {
258
+ queue[i + j] = newFiles[j];
259
+ }
260
+ return;
261
+ }
262
+ }
263
+ };
264
+ $scope.applyOnQueue = function (method) {
265
+ var list = this.queue.slice(0),
266
+ i,
267
+ file,
268
+ promises = [];
269
+ for (i = 0; i < list.length; i += 1) {
270
+ file = list[i];
271
+ if (file[method]) {
272
+ promises.push(file[method]());
273
+ }
274
+ }
275
+ return $q.all(promises);
276
+ };
277
+ $scope.submit = function () {
278
+ return this.applyOnQueue('$submit');
279
+ };
280
+ $scope.cancel = function () {
281
+ return this.applyOnQueue('$cancel');
282
+ };
283
+ // Add upload methods to the scope:
284
+ angular.extend($scope, uploadMethods);
285
+ // The fileupload widget will initialize with
286
+ // the options provided via "data-"-parameters,
287
+ // as well as those given via options object:
288
+ $element.fileupload(angular.extend(
289
+ {scope: $scope},
290
+ fileUpload.defaults
291
+ )).on('fileuploadadd', function (e, data) {
292
+ data.scope = $scope;
293
+ }).on('fileuploadfail', function (e, data) {
294
+ if (data.errorThrown === 'abort') {
295
+ return;
296
+ }
297
+ if (data.dataType &&
298
+ data.dataType.indexOf('json') === data.dataType.length - 4) {
299
+ try {
300
+ data.result = angular.fromJson(data.jqXHR.responseText);
301
+ } catch (ignore) {}
302
+ }
303
+ }).on([
304
+ 'fileuploadadd',
305
+ 'fileuploadsubmit',
306
+ 'fileuploadsend',
307
+ 'fileuploaddone',
308
+ 'fileuploadfail',
309
+ 'fileuploadalways',
310
+ 'fileuploadprogress',
311
+ 'fileuploadprogressall',
312
+ 'fileuploadstart',
313
+ 'fileuploadstop',
314
+ 'fileuploadchange',
315
+ 'fileuploadpaste',
316
+ 'fileuploaddrop',
317
+ 'fileuploaddragover',
318
+ 'fileuploadchunksend',
319
+ 'fileuploadchunkdone',
320
+ 'fileuploadchunkfail',
321
+ 'fileuploadchunkalways',
322
+ 'fileuploadprocessstart',
323
+ 'fileuploadprocess',
324
+ 'fileuploadprocessdone',
325
+ 'fileuploadprocessfail',
326
+ 'fileuploadprocessalways',
327
+ 'fileuploadprocessstop'
328
+ ].join(' '), function (e, data) {
329
+ $scope.$parent.$applyAsync(function () {
330
+ if ($scope.$emit(e.type, data).defaultPrevented) {
331
+ e.preventDefault();
332
+ }
333
+ });
334
+ }).on('remove', function () {
335
+ // Remove upload methods from the scope,
336
+ // when the widget is removed:
337
+ var method;
338
+ for (method in uploadMethods) {
339
+ if (uploadMethods.hasOwnProperty(method)) {
340
+ delete $scope[method];
341
+ }
342
+ }
343
+ });
344
+ // Observe option changes:
345
+ $scope.$watch(
346
+ $attrs.fileUpload,
347
+ function (newOptions) {
348
+ if (newOptions) {
349
+ $element.fileupload('option', newOptions);
350
+ }
351
+ }
352
+ );
353
+ }
354
+ ])
355
+
356
+ // Provide File Upload progress feedback:
357
+ .controller('FileUploadProgressController', [
358
+ '$scope', '$attrs', '$parse',
359
+ function ($scope, $attrs, $parse) {
360
+ var fn = $parse($attrs.fileUploadProgress),
361
+ update = function () {
362
+ var progress = fn($scope);
363
+ if (!progress || !progress.total) {
364
+ return;
365
+ }
366
+ $scope.num = Math.floor(
367
+ progress.loaded / progress.total * 100
368
+ );
369
+ };
370
+ update();
371
+ $scope.$watch(
372
+ $attrs.fileUploadProgress + '.loaded',
373
+ function (newValue, oldValue) {
374
+ if (newValue !== oldValue) {
375
+ update();
376
+ }
377
+ }
378
+ );
379
+ }
380
+ ])
381
+
382
+ // Display File Upload previews:
383
+ .controller('FileUploadPreviewController', [
384
+ '$scope', '$element', '$attrs',
385
+ function ($scope, $element, $attrs) {
386
+ $scope.$watch(
387
+ $attrs.fileUploadPreview + '.preview',
388
+ function (preview) {
389
+ $element.empty();
390
+ if (preview) {
391
+ $element.append(preview);
392
+ }
393
+ }
394
+ );
395
+ }
396
+ ])
397
+
398
+ .directive('fileUpload', function () {
399
+ return {
400
+ controller: 'FileUploadController',
401
+ scope: true
402
+ };
403
+ })
404
+
405
+ .directive('fileUploadProgress', function () {
406
+ return {
407
+ controller: 'FileUploadProgressController',
408
+ scope: true
409
+ };
410
+ })
411
+
412
+ .directive('fileUploadPreview', function () {
413
+ return {
414
+ controller: 'FileUploadPreviewController'
415
+ };
416
+ })
417
+
418
+ // Enhance the HTML5 download attribute to
419
+ // allow drag&drop of files to the desktop:
420
+ .directive('download', function () {
421
+ return function (scope, elm) {
422
+ elm.on('dragstart', function (e) {
423
+ try {
424
+ e.originalEvent.dataTransfer.setData(
425
+ 'DownloadURL',
426
+ [
427
+ 'application/octet-stream',
428
+ elm.prop('download'),
429
+ elm.prop('href')
430
+ ].join(':')
431
+ );
432
+ } catch (ignore) {}
433
+ });
434
+ };
435
+ });
436
+
437
+ }));