tjadmin 0.0.3 → 0.0.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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tjadmin/version.rb +1 -1
  3. data/vendor/assets/font/DXI1ORHCpsQm3Vp6mXoaTXhCUOGz7vYGh680lGh-uXM.woff +0 -0
  4. data/vendor/assets/font/FontAwesome.otf +0 -0
  5. data/vendor/assets/font/cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff +0 -0
  6. data/vendor/assets/font/fontawesome-webfont.eot +0 -0
  7. data/vendor/assets/font/fontawesome-webfont.svg +399 -0
  8. data/vendor/assets/font/fontawesome-webfont.ttf +0 -0
  9. data/vendor/assets/font/fontawesome-webfont.woff +0 -0
  10. data/vendor/assets/javascripts/tjadmin/ace-elements.js +866 -0
  11. data/vendor/assets/javascripts/tjadmin/ace-extra.js +374 -0
  12. data/vendor/assets/javascripts/tjadmin/ace.js +310 -0
  13. data/vendor/assets/javascripts/tjadmin/additional-methods.js +617 -0
  14. data/vendor/assets/javascripts/tjadmin/bootbox.js +660 -0
  15. data/vendor/assets/javascripts/tjadmin/bootstrap-colorpicker.js +540 -0
  16. data/vendor/assets/javascripts/tjadmin/bootstrap-tag.js +206 -0
  17. data/vendor/assets/javascripts/tjadmin/bootstrap-wysiwyg.js +206 -0
  18. data/vendor/assets/javascripts/tjadmin/bootstrap.js +2280 -0
  19. data/vendor/assets/javascripts/tjadmin/chosen.jquery.js +1166 -0
  20. data/vendor/assets/javascripts/tjadmin/date-time/bootstrap-datepicker.js +1016 -0
  21. data/vendor/assets/javascripts/tjadmin/date-time/bootstrap-timepicker.js +888 -0
  22. data/vendor/assets/javascripts/tjadmin/date-time/daterangepicker.js +854 -0
  23. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.bg.js +14 -0
  24. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.ca.js +14 -0
  25. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.cs.js +15 -0
  26. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.da.js +14 -0
  27. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.de.js +16 -0
  28. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.el.js +13 -0
  29. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.es.js +14 -0
  30. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.fi.js +14 -0
  31. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.fr.js +16 -0
  32. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.he.js +15 -0
  33. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.hr.js +13 -0
  34. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.hu.js +16 -0
  35. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.id.js +13 -0
  36. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.is.js +14 -0
  37. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.it.js +16 -0
  38. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.ja.js +15 -0
  39. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.kr.js +13 -0
  40. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.lt.js +16 -0
  41. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.lv.js +16 -0
  42. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.ms.js +14 -0
  43. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.nb.js +14 -0
  44. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.nl.js +14 -0
  45. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.pl.js +15 -0
  46. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.pt-BR.js +14 -0
  47. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.pt.js +14 -0
  48. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.ro.js +15 -0
  49. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.rs-latin.js +14 -0
  50. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.rs.js +14 -0
  51. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.ru.js +14 -0
  52. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.sk.js +15 -0
  53. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.sl.js +14 -0
  54. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.sv.js +14 -0
  55. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.sw.js +15 -0
  56. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.th.js +14 -0
  57. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.tr.js +15 -0
  58. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.uk.js +14 -0
  59. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.zh-CN.js +14 -0
  60. data/vendor/assets/javascripts/tjadmin/date-time/locales/bootstrap-datepicker.zh-TW.js +13 -0
  61. data/vendor/assets/javascripts/tjadmin/date-time/moment.js +1400 -0
  62. data/vendor/assets/javascripts/tjadmin/excanvas.js +1428 -0
  63. data/vendor/assets/javascripts/tjadmin/flot/jquery.flot.js +3061 -0
  64. data/vendor/assets/javascripts/tjadmin/flot/jquery.flot.pie.js +817 -0
  65. data/vendor/assets/javascripts/tjadmin/flot/jquery.flot.resize.js +60 -0
  66. data/vendor/assets/javascripts/tjadmin/fuelux/data/fuelux.tree-sampledata.js +174 -0
  67. data/vendor/assets/javascripts/tjadmin/fuelux/fuelux.spinner.js +201 -0
  68. data/vendor/assets/javascripts/tjadmin/fuelux/fuelux.tree.js +173 -0
  69. data/vendor/assets/javascripts/tjadmin/fuelux/fuelux.wizard.js +172 -0
  70. data/vendor/assets/javascripts/tjadmin/fullcalendar.js +5973 -0
  71. data/vendor/assets/javascripts/tjadmin/jquery-1.10.2.js +9789 -0
  72. data/vendor/assets/javascripts/tjadmin/jquery-2.0.3.js +8829 -0
  73. data/vendor/assets/javascripts/tjadmin/jquery-ui-1.10.3.custom.js +5423 -0
  74. data/vendor/assets/javascripts/tjadmin/jquery.autosize.js +242 -0
  75. data/vendor/assets/javascripts/tjadmin/jquery.colorbox.js +1063 -0
  76. data/vendor/assets/javascripts/tjadmin/jquery.dataTables.js +12099 -0
  77. data/vendor/assets/javascripts/tjadmin/jquery.easy-pie-chart.js +200 -0
  78. data/vendor/assets/javascripts/tjadmin/jquery.gritter.js +418 -0
  79. data/vendor/assets/javascripts/tjadmin/jquery.hotkeys.js +113 -0
  80. data/vendor/assets/javascripts/tjadmin/jquery.inputlimiter.1.3.1.js +172 -0
  81. data/vendor/assets/javascripts/tjadmin/jquery.knob.js +656 -0
  82. data/vendor/assets/javascripts/tjadmin/jquery.maskedinput.js +338 -0
  83. data/vendor/assets/javascripts/tjadmin/jquery.mobile.custom.js +1081 -0
  84. data/vendor/assets/javascripts/tjadmin/jquery.slimscroll.js +448 -0
  85. data/vendor/assets/javascripts/tjadmin/jquery.sparkline.js +3054 -0
  86. data/vendor/assets/javascripts/tjadmin/jquery.ui.touch-punch.js +160 -0
  87. data/vendor/assets/javascripts/tjadmin/jquery.validate.js +1231 -0
  88. data/vendor/assets/javascripts/tjadmin/markdown/bootstrap-markdown.js +993 -0
  89. data/vendor/assets/javascripts/tjadmin/markdown/markdown.js +1616 -0
  90. data/vendor/assets/javascripts/tjadmin/markdown/to-markdown.js +184 -0
  91. data/vendor/assets/javascripts/tjadmin/select2.js +3168 -0
  92. data/vendor/assets/javascripts/tjadmin/spin.js +349 -0
  93. data/vendor/assets/javascripts/tjadmin/x-editable/ace-editable.js +368 -0
  94. data/vendor/assets/javascripts/tjadmin/x-editable/bootstrap-editable.js +6827 -0
  95. data/vendor/assets/javascripts/tjadmin.js +5 -0
  96. data/vendor/assets/stylesheets/tjadmin/ace-fonts.css.scss +13 -0
  97. data/vendor/assets/stylesheets/tjadmin/ace-ie.css +293 -0
  98. data/vendor/assets/stylesheets/tjadmin/ace-responsive.css +1113 -0
  99. data/vendor/assets/stylesheets/tjadmin/ace-skins.css +1301 -0
  100. data/vendor/assets/stylesheets/tjadmin/ace.css +14701 -0
  101. data/vendor/assets/stylesheets/tjadmin/bootstrap-responsive.css +1109 -0
  102. data/vendor/assets/stylesheets/tjadmin/bootstrap.css +6167 -0
  103. data/vendor/assets/stylesheets/tjadmin/chosen.css +430 -0
  104. data/vendor/assets/stylesheets/tjadmin/font-awesome-ie7.css +1203 -0
  105. data/vendor/assets/stylesheets/tjadmin/font-awesome.css +1479 -0
  106. data/vendor/assets/stylesheets/tjadmin/jquery-ui-1.10.3.custom.css +223 -0
  107. data/vendor/assets/stylesheets/tjadmin.css +9 -0
  108. metadata +106 -1
@@ -0,0 +1,866 @@
1
+ if(! ('ace' in window) ) window['ace'] = {}
2
+ jQuery(function() {
3
+ //at some places we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
4
+ window['ace'].click_event = $.fn.tap ? "tap" : "click";
5
+ });
6
+
7
+ (function($ , undefined) {
8
+ var multiplible = 'multiple' in document.createElement('INPUT');
9
+ var hasFileList = 'FileList' in window;//file list enabled in modern browsers
10
+ var hasFileReader = 'FileReader' in window;
11
+
12
+ var Ace_File_Input = function(element , settings) {
13
+ var self = this;
14
+ this.settings = $.extend({}, $.fn.ace_file_input.defaults, settings);
15
+
16
+ this.$element = $(element);
17
+ this.element = element;
18
+ this.disabled = false;
19
+ this.can_reset = true;
20
+
21
+ this.$element.on('change.ace_inner_call', function(e , ace_inner_call){
22
+ if(ace_inner_call === true) return;//this change event is called from above drop event
23
+ return handle_on_change.call(self);
24
+ });
25
+
26
+ this.$element.wrap('<div class="ace-file-input" />');
27
+
28
+ this.apply_settings();
29
+ }
30
+ Ace_File_Input.error = {
31
+ 'FILE_LOAD_FAILED' : 1,
32
+ 'IMAGE_LOAD_FAILED' : 2,
33
+ 'THUMBNAIL_FAILED' : 3
34
+ };
35
+
36
+
37
+ Ace_File_Input.prototype.apply_settings = function() {
38
+ var self = this;
39
+ var remove_btn = !!this.settings.icon_remove;
40
+
41
+ this.multi = this.$element.attr('multiple') && multiplible;
42
+ this.well_style = this.settings.style == 'well';
43
+
44
+ if(this.well_style) this.$element.parent().addClass('ace-file-multiple');
45
+ else this.$element.parent().removeClass('ace-file-multiple');
46
+
47
+ this.$element.parent().find(':not(input[type=file])').remove();//remove all except our input, good for when changing settings
48
+ this.$element.after('<label data-title="'+this.settings.btn_choose+'"><span data-title="'+this.settings.no_file+'">'+(this.settings.no_icon ? '<i class="'+this.settings.no_icon+'"></i>' : '')+'</span></label>'+(remove_btn ? '<a class="remove" href="#"><i class="'+this.settings.icon_remove+'"></i></a>' : ''));
49
+ this.$label = this.$element.next();
50
+
51
+ this.$label.on('click', function(){//firefox mobile doesn't allow 'tap'!
52
+ if(!this.disabled && !self.element.disabled && !self.$element.attr('readonly'))
53
+ self.$element.click();
54
+ })
55
+
56
+ if(remove_btn) this.$label.next('a').on(ace.click_event, function(){
57
+ if(! self.can_reset ) return false;
58
+
59
+ var ret = true;
60
+ if(self.settings.before_remove) ret = self.settings.before_remove.call(self.element);
61
+ if(!ret) return false;
62
+ return self.reset_input();
63
+ });
64
+
65
+
66
+ if(this.settings.droppable && hasFileList) {
67
+ enable_drop_functionality.call(this);
68
+ }
69
+ }
70
+
71
+ Ace_File_Input.prototype.show_file_list = function($files) {
72
+ var files = typeof $files === "undefined" ? this.$element.data('ace_input_files') : $files;
73
+ if(!files || files.length == 0) return;
74
+
75
+ //////////////////////////////////////////////////////////////////
76
+
77
+ if(this.well_style) {
78
+ this.$label.find('span').remove();
79
+ if(!this.settings.btn_change) this.$label.addClass('hide-placeholder');
80
+ }
81
+ this.$label.attr('data-title', this.settings.btn_change).addClass('selected');
82
+
83
+ for (var i = 0; i < files.length; i++) {
84
+ var filename = typeof files[i] === "string" ? files[i] : $.trim( files[i].name );
85
+ var index = filename.lastIndexOf("\\") + 1;
86
+ if(index == 0)index = filename.lastIndexOf("/") + 1;
87
+ filename = filename.substr(index);
88
+
89
+ var fileIcon = 'icon-file';
90
+ if((/\.(jpe?g|png|gif|svg|bmp|tiff?)$/i).test(filename)) {
91
+ fileIcon = 'icon-picture';
92
+ }
93
+ else if((/\.(mpe?g|flv|mov|avi|swf|mp4|mkv|webm|wmv|3gp)$/i).test(filename)) fileIcon = 'icon-film';
94
+ else if((/\.(mp3|ogg|wav|wma|amr|aac)$/i).test(filename)) fileIcon = 'icon-music';
95
+
96
+
97
+ if(!this.well_style) this.$label.find('span').attr({'data-title':filename}).find('[class*="icon-"]').attr('class', fileIcon);
98
+ else {
99
+ this.$label.append('<span data-title="'+filename+'"><i class="'+fileIcon+'"></i></span>');
100
+ var type = $.trim(files[i].type);
101
+ var can_preview = hasFileReader && this.settings.thumbnail
102
+ &&
103
+ ( (type.length > 0 && type.match('image')) || (type.length == 0 && fileIcon == 'icon-picture') )//the second one is for Android's default browser which gives an empty text for file.type
104
+ if(can_preview) {
105
+ var self = this;
106
+ $.when(preview_image.call(this, files[i])).fail(function(result){
107
+ //called on failure to load preview
108
+ if(self.settings.preview_error) self.settings.preview_error.call(self, filename, result.code);
109
+ });
110
+ }
111
+ }
112
+
113
+ }
114
+
115
+ return true;
116
+ }
117
+
118
+ Ace_File_Input.prototype.reset_input = function() {
119
+ this.$label.attr({'data-title':this.settings.btn_choose, 'class':''})
120
+ .find('span:first').attr({'data-title':this.settings.no_file , 'class':''})
121
+ .find('[class*="icon-"]').attr('class', this.settings.no_icon)
122
+ .prev('img').remove();
123
+ if(!this.settings.no_icon) this.$label.find('[class*="icon-"]').remove();
124
+
125
+ this.$label.find('span').not(':first').remove();
126
+
127
+ if(this.$element.data('ace_input_files')) {
128
+ this.$element.removeData('ace_input_files');
129
+ this.$element.removeData('ace_input_method');
130
+ }
131
+
132
+ this.reset_input_field();
133
+
134
+ return false;
135
+ }
136
+
137
+ Ace_File_Input.prototype.reset_input_field = function() {
138
+ //http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery/13351234#13351234
139
+ this.$element.wrap('<form>').closest('form').get(0).reset();
140
+ this.$element.unwrap();
141
+ }
142
+
143
+ Ace_File_Input.prototype.enable_reset = function(can_reset) {
144
+ this.can_reset = can_reset;
145
+ }
146
+
147
+ Ace_File_Input.prototype.disable = function() {
148
+ this.disabled = true;
149
+ this.$element.attr('disabled', 'disabled').addClass('disabled');
150
+ }
151
+ Ace_File_Input.prototype.enable = function() {
152
+ this.disabled = false;
153
+ this.$element.removeAttr('disabled').removeClass('disabled');
154
+ }
155
+
156
+ Ace_File_Input.prototype.files = function() {
157
+ return $(this).data('ace_input_files') || null;
158
+ }
159
+ Ace_File_Input.prototype.method = function() {
160
+ return $(this).data('ace_input_method') || '';
161
+ }
162
+
163
+ Ace_File_Input.prototype.update_settings = function(new_settings) {
164
+ this.settings = $.extend({}, this.settings, new_settings);
165
+ this.apply_settings();
166
+ }
167
+
168
+
169
+
170
+ var enable_drop_functionality = function() {
171
+ var self = this;
172
+ var dropbox = this.element.parentNode;
173
+ $(dropbox).on('dragenter', function(e){
174
+ e.preventDefault();
175
+ e.stopPropagation();
176
+ }).on('dragover', function(e){
177
+ e.preventDefault();
178
+ e.stopPropagation();
179
+ }).on('drop', function(e){
180
+ e.preventDefault();
181
+ e.stopPropagation();
182
+
183
+ var dt = e.originalEvent.dataTransfer;
184
+ var files = dt.files;
185
+ if(!self.multi && files.length > 1) {//single file upload, but dragged multiple files
186
+ var tmpfiles = [];
187
+ tmpfiles.push(files[0]);
188
+ files = tmpfiles;//keep only first file
189
+ }
190
+
191
+ var ret = true;
192
+ if(self.settings.before_change) ret = self.settings.before_change.call(self.element, files, true);//true means files have been dropped
193
+ if(!ret || ret.length == 0) {
194
+ return false;
195
+ }
196
+
197
+ //user can return a modified File Array as result
198
+ if(ret instanceof Array || (hasFileList && ret instanceof FileList)) files = ret;
199
+
200
+
201
+ self.$element.data('ace_input_files', files);//save files data to be used later by user
202
+ self.$element.data('ace_input_method', 'drop');
203
+
204
+
205
+ self.show_file_list(files);
206
+
207
+
208
+ self.$element.triggerHandler('change' , [true]);//true means inner_call
209
+ return true;
210
+ });
211
+ }
212
+
213
+
214
+ var handle_on_change = function() {
215
+ var ret = true;
216
+ if(this.settings.before_change) ret = this.settings.before_change.call(this.element, this.element.files || [this.element.value]/*make it an array*/, false);//false means files have been selected, not dropped
217
+ if(!ret || ret.length == 0) {
218
+ if(!this.$element.data('ace_input_files')) this.reset_input_field();//if nothing selected before, reset because of the newly unacceptable (ret=false||length=0) selection
219
+ return false;
220
+ }
221
+
222
+
223
+ //user can return a modified File Array as result
224
+ var files = !hasFileList ? null ://for old IE, etc
225
+ ((ret instanceof Array || ret instanceof FileList) ? ret : this.element.files);
226
+ this.$element.data('ace_input_method', 'select');
227
+
228
+
229
+ if(files && files.length > 0) {//html5
230
+ this.$element.data('ace_input_files', files);
231
+ }
232
+ else {
233
+ var name = $.trim( this.element.value );
234
+ if(name && name.length > 0) {
235
+ files = []
236
+ files.push(name);
237
+ this.$element.data('ace_input_files', files);
238
+ }
239
+ }
240
+
241
+ if(!files || files.length == 0) return false;
242
+ this.show_file_list(files);
243
+
244
+ return true;
245
+ }
246
+
247
+
248
+
249
+
250
+ var preview_image = function(file) {
251
+ var self = this;
252
+ var $span = self.$label.find('span:last');//it should be out of onload, otherwise all onloads may target the same span because of delays
253
+
254
+ var deferred = new $.Deferred
255
+ var reader = new FileReader();
256
+ reader.onload = function (e) {
257
+ $span.prepend("<img class='middle' style='display:none;' />");
258
+ var img = $span.find('img:last').get(0);
259
+
260
+ $(img).one('load', function() {
261
+ //if image loaded successfully
262
+ var size = 50;
263
+ if(self.settings.thumbnail == 'large') size = 150;
264
+ else if(self.settings.thumbnail == 'fit') size = $span.width();
265
+ $span.addClass(size > 50 ? 'large' : '');
266
+
267
+ var thumb = get_thumbnail(img, size, file.type);
268
+ if(thumb == null) {
269
+ //if making thumbnail fails
270
+ $(this).remove();
271
+ deferred.reject({code:Ace_File_Input.error['THUMBNAIL_FAILED']});
272
+ return;
273
+ }
274
+
275
+ var w = thumb.w, h = thumb.h;
276
+ if(self.settings.thumbnail == 'small') {w=h=size;};
277
+ $(img).css({'background-image':'url('+thumb.src+')' , width:w, height:h})
278
+ .data('thumb', thumb.src)
279
+ .attr({src:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=='})
280
+ .show()
281
+
282
+ ///////////////////
283
+ deferred.resolve();
284
+ }).one('error', function() {
285
+ //for example when a file has image extenstion, but format is something else
286
+ $span.find('img').remove();
287
+ deferred.reject({code:Ace_File_Input.error['IMAGE_LOAD_FAILED']});
288
+ });
289
+
290
+ img.src = e.target.result;
291
+ }
292
+ reader.onerror = function (e) {
293
+ deferred.reject({code:Ace_File_Input.error['FILE_LOAD_FAILED']});
294
+ }
295
+ reader.readAsDataURL(file);
296
+
297
+ return deferred.promise();
298
+ }
299
+
300
+ var get_thumbnail = function(img, size, type) {
301
+
302
+ var w = img.width, h = img.height;
303
+ if(w > size || h > size) {
304
+ if(w > h) {
305
+ h = parseInt(size/w * h);
306
+ w = size;
307
+ } else {
308
+ w = parseInt(size/h * w);
309
+ h = size;
310
+ }
311
+ }
312
+
313
+ var dataURL
314
+ try {
315
+ var canvas = document.createElement('canvas');
316
+ canvas.width = w; canvas.height = h;
317
+ var context = canvas.getContext('2d');
318
+ context.drawImage(img, 0, 0, img.width, img.height, 0, 0, w, h);
319
+ dataURL = canvas.toDataURL(/*type == 'image/jpeg' ? type : 'image/png', 10*/)
320
+ } catch(e) {
321
+ dataURL = null;
322
+ }
323
+
324
+ //there was only one image that failed in firefox completely randomly! so let's double check it
325
+ if(!( /^data\:image\/(png|jpe?g|gif);base64,[0-9A-Za-z\+\/\=]+$/.test(dataURL)) ) dataURL = null;
326
+ if(! dataURL) return null;
327
+
328
+ return {src: dataURL, w:w, h:h};
329
+ }
330
+
331
+
332
+
333
+ ///////////////////////////////////////////
334
+ $.fn.ace_file_input = function (option,value) {
335
+ var retval;
336
+
337
+ var $set = this.each(function () {
338
+ var $this = $(this);
339
+ var data = $this.data('ace_file_input');
340
+ var options = typeof option === 'object' && option;
341
+
342
+ if (!data) $this.data('ace_file_input', (data = new Ace_File_Input(this, options)));
343
+ if (typeof option === 'string') retval = data[option](value);
344
+ });
345
+
346
+ return (retval === undefined) ? $set : retval;
347
+ };
348
+
349
+
350
+ $.fn.ace_file_input.defaults = {
351
+ style:false,
352
+ no_file:'No File ...',
353
+ no_icon:'icon-upload-alt',
354
+ btn_choose:'Choose',
355
+ btn_change:'Change',
356
+ icon_remove:'icon-remove',
357
+ droppable:false,
358
+ thumbnail:false,//large, fit, small
359
+
360
+ //callbacks
361
+ before_change:null,
362
+ before_remove:null,
363
+ preview_error:null
364
+ }
365
+
366
+
367
+ })(window.jQuery);
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+ (function($ , undefined) {
377
+ $.fn.ace_spinner = function(options) {
378
+
379
+ //when min is negative, the input maxlength does not account for the extra minus sign
380
+ this.each(function() {
381
+ var icon_up = options.icon_up || 'icon-chevron-up';
382
+ var icon_down = options.icon_down || 'icon-chevron-down';
383
+
384
+ var btn_up_class = options.btn_up_class || '';
385
+ var btn_down_class = options.btn_down_class || '';
386
+
387
+ var max = options.max || 999;
388
+ max = (''+max).length;
389
+ var $parent_div =
390
+ $(this).addClass('spinner-input').css('width' , (max*10)+'px').wrap('<div class="ace-spinner">')
391
+ .after('<div class="spinner-buttons btn-group btn-group-vertical">\
392
+ <button type="button" class="btn spinner-up btn-mini '+btn_up_class+'">\
393
+ <i class="'+icon_up+'"></i>\
394
+ </button>\
395
+ <button type="button" class="btn spinner-down btn-mini '+btn_down_class+'">\
396
+ <i class="'+icon_down+'"></i>\
397
+ </button>\
398
+ </div>')
399
+ .closest('.ace-spinner').spinner(options).wrapInner("<div class='input-append'></div>");
400
+
401
+
402
+
403
+ $(this).on('mousewheel DOMMouseScroll', function(event){
404
+ var delta = event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0 ? 1 : -1;
405
+ $parent_div.spinner('step', delta > 0);//accepts true or false as second param
406
+ $parent_div.spinner('triggerChangedEvent');
407
+ return false;
408
+ });
409
+ var that = $(this);
410
+ $parent_div.on('changed', function(){
411
+ that.trigger('change');//trigger the input's change event
412
+ });
413
+
414
+ });
415
+
416
+ return this;
417
+ }
418
+
419
+
420
+ })(window.jQuery);
421
+
422
+
423
+
424
+
425
+
426
+
427
+ (function($ , undefined) {
428
+ $.fn.ace_wizard = function(options) {
429
+
430
+ this.each(function() {
431
+ var $this = $(this);
432
+ var steps = $this.find('li');
433
+ var numSteps = steps.length;
434
+ var width = (100 / numSteps)+"";
435
+ if(width.length > 6) width = width.substr(0, 6);
436
+ width += '%';
437
+ steps.css({'min-width':width , 'max-width':width});
438
+
439
+ $this.show().wizard();
440
+
441
+ var buttons = $this.siblings('.wizard-actions').eq(0);
442
+ var $wizard = $this.data('wizard');
443
+ $wizard.$prevBtn.remove();
444
+ $wizard.$nextBtn.remove();
445
+
446
+ $wizard.$prevBtn = buttons.find('.btn-prev').eq(0).on(ace.click_event, function(){
447
+ $this.wizard('previous');
448
+ }).attr('disabled', 'disabled');
449
+ $wizard.$nextBtn = buttons.find('.btn-next').eq(0).on(ace.click_event, function(){
450
+ $this.wizard('next');
451
+ }).removeAttr('disabled');
452
+ $wizard.nextText = $wizard.$nextBtn.text();
453
+ });
454
+
455
+ return this;
456
+ }
457
+
458
+
459
+ })(window.jQuery);
460
+
461
+
462
+
463
+
464
+
465
+ (function($ , undefined) {
466
+ $.fn.ace_colorpicker = function(options) {
467
+
468
+ var settings = $.extend( {
469
+ pull_right:false,
470
+ caret:true
471
+ }, options);
472
+
473
+ this.each(function() {
474
+
475
+ var $that = $(this);
476
+ var colors = '';
477
+ var color = '';
478
+ $(this).hide().find('option').each(function() {
479
+ var $class = 'colorpick-btn';
480
+ if(this.selected) {
481
+ $class += ' selected';
482
+ color = this.value;
483
+ }
484
+ colors += '<li><a class="'+$class+'" href="#" style="background-color:'+this.value+';" data-color="'+this.value+'"></a></li>';
485
+ }).end().on('change.ace_inner_call', function(){
486
+ $(this).next().find('.btn-colorpicker').css('background-color', this.value);
487
+ })
488
+ .after('<div class="dropdown dropdown-colorpicker"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><span class="btn-colorpicker" style="background-color:'+color+'"></span></a><ul class="dropdown-menu'+(settings.caret? ' dropdown-caret' : '')+(settings.pull_right ? ' pull-right' : '')+'">'+colors+'</ul></div>')
489
+ .next().find('.dropdown-menu').on(ace.click_event, function(e) {
490
+ var a = $(e.target);
491
+ if(!a.is('.colorpick-btn')) return false;
492
+ a.closest('ul').find('.selected').removeClass('selected');
493
+ a.addClass('selected');
494
+ var color = a.data('color');
495
+
496
+ $that.val(color).change();
497
+
498
+ e.preventDefault();
499
+ return true;//if false, dropdown won't hide!
500
+ });
501
+
502
+
503
+ });
504
+ return this;
505
+
506
+ }
507
+
508
+
509
+ })(window.jQuery);
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+ (function($ , undefined) {
523
+ $.fn.ace_tree = function(options) {
524
+ var $options = {
525
+ 'open-icon' : 'icon-folder-open',
526
+ 'close-icon' : 'icon-folder-close',
527
+ 'selectable' : true,
528
+ 'selected-icon' : 'icon-ok',
529
+ 'unselected-icon' : 'tree-dot'
530
+ }
531
+
532
+ $options = $.extend({}, $options, options)
533
+
534
+ this.each(function() {
535
+ var $this = $(this);
536
+ $this.html('<div class = "tree-folder" style="display:none;">\
537
+ <div class="tree-folder-header">\
538
+ <i class="'+$options['close-icon']+'"></i>\
539
+ <div class="tree-folder-name"></div>\
540
+ </div>\
541
+ <div class="tree-folder-content"></div>\
542
+ <div class="tree-loader" style="display:none"></div>\
543
+ </div>\
544
+ <div class="tree-item" style="display:none;">\
545
+ '+($options['unselected-icon'] == null ? '' : '<i class="'+$options['unselected-icon']+'"></i>')+'\
546
+ <div class="tree-item-name"></div>\
547
+ </div>');
548
+ $this.addClass($options['selectable'] == true ? 'tree-selectable' : 'tree-unselectable');
549
+
550
+ $this.tree($options);
551
+ });
552
+
553
+ return this;
554
+ }
555
+
556
+
557
+ })(window.jQuery);
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+ (function($ , undefined) {
571
+ $.fn.ace_wysiwyg = function($options , undefined) {
572
+ var options = $.extend( {
573
+ speech_button:true,
574
+ wysiwyg:{}
575
+ }, $options);
576
+
577
+ var color_values = [
578
+ '#ac725e','#d06b64','#f83a22','#fa573c','#ff7537','#ffad46',
579
+ '#42d692','#16a765','#7bd148','#b3dc6c','#fbe983','#fad165',
580
+ '#92e1c0','#9fe1e7','#9fc6e7','#4986e7','#9a9cff','#b99aff',
581
+ '#c2c2c2','#cabdbf','#cca6ac','#f691b2','#cd74e6','#a47ae2',
582
+ '#444444'
583
+ ]
584
+
585
+ var button_defaults =
586
+ {
587
+ 'font' : {
588
+ values:['Arial', 'Courier', 'Comic Sans MS', 'Helvetica', 'Open Sans', 'Tahoma', 'Verdana'],
589
+ icon:'icon-font',
590
+ title:'Font'
591
+ },
592
+ 'fontSize' : {
593
+ values:{5:'Huge', 3:'Normal', 1:'Small'},
594
+ icon:'icon-text-height',
595
+ title:'Font Size'
596
+ },
597
+ 'bold' : {
598
+ icon : 'icon-bold',
599
+ title : 'Bold (Ctrl/Cmd+B)'
600
+ },
601
+ 'italic' : {
602
+ icon : 'icon-italic',
603
+ title : 'Italic (Ctrl/Cmd+I)'
604
+ },
605
+ 'strikethrough' : {
606
+ icon : 'icon-strikethrough',
607
+ title : 'Strikethrough'
608
+ },
609
+ 'underline' : {
610
+ icon : 'icon-underline',
611
+ title : 'Underline'
612
+ },
613
+ 'insertunorderedlist' : {
614
+ icon : 'icon-list-ul',
615
+ title : 'Bullet list'
616
+ },
617
+ 'insertorderedlist' : {
618
+ icon : 'icon-list-ol',
619
+ title : 'Number list'
620
+ },
621
+ 'outdent' : {
622
+ icon : 'icon-indent-left',
623
+ title : 'Reduce indent (Shift+Tab)'
624
+ },
625
+ 'indent' : {
626
+ icon : 'icon-indent-right',
627
+ title : 'Indent (Tab)'
628
+ },
629
+ 'justifyleft' : {
630
+ icon : 'icon-align-left',
631
+ title : 'Align Left (Ctrl/Cmd+L)'
632
+ },
633
+ 'justifycenter' : {
634
+ icon : 'icon-align-center',
635
+ title : 'Center (Ctrl/Cmd+E)'
636
+ },
637
+ 'justifyright' : {
638
+ icon : 'icon-align-right',
639
+ title : 'Align Right (Ctrl/Cmd+R)'
640
+ },
641
+ 'justifyfull' : {
642
+ icon : 'icon-align-justify',
643
+ title : 'Justify (Ctrl/Cmd+J)'
644
+ },
645
+ 'createLink' : {
646
+ icon : 'icon-link',
647
+ title : 'Hyperlink',
648
+ button_text : 'Add',
649
+ placeholder : 'URL',
650
+ button_class : 'btn-primary'
651
+ },
652
+ 'unlink' : {
653
+ icon : 'icon-unlink',
654
+ title : 'Remove Hyperlink'
655
+ },
656
+ 'insertImage' : {
657
+ icon : 'icon-picture',
658
+ title : 'Insert picture',
659
+ button_text : '<i class="icon-file"></i> Choose Image &hellip;',
660
+ placeholder : 'Image URL',
661
+ button_insert : 'Insert',
662
+ button_class : 'btn-success',
663
+ button_insert_class : 'btn-primary',
664
+ choose_file: true //show the choose file button?
665
+ },
666
+ 'foreColor' : {
667
+ values : color_values,
668
+ title : 'Change Color'
669
+ },
670
+ 'backColor' : {
671
+ values : color_values,
672
+ title : 'Change Background Color'
673
+ },
674
+ 'undo' : {
675
+ icon : 'icon-undo',
676
+ title : 'Undo (Ctrl/Cmd+Z)'
677
+ },
678
+ 'redo' : {
679
+ icon : 'icon-repeat',
680
+ title : 'Redo (Ctrl/Cmd+Y)'
681
+ },
682
+ 'viewSource' : {
683
+ icon : 'icon-code',
684
+ title : 'View Source'
685
+ }
686
+ }
687
+
688
+ var toolbar_buttons =
689
+ options.toolbar ||
690
+ [
691
+ 'font',
692
+ null,
693
+ 'fontSize',
694
+ null,
695
+ 'bold',
696
+ 'italic',
697
+ 'strikethrough',
698
+ 'underline',
699
+ null,
700
+ 'insertunorderedlist',
701
+ 'insertorderedlist',
702
+ 'outdent',
703
+ 'indent',
704
+ null,
705
+ 'justifyleft',
706
+ 'justifycenter',
707
+ 'justifyright',
708
+ 'justifyfull',
709
+ null,
710
+ 'createLink',
711
+ 'unlink',
712
+ null,
713
+ 'insertImage',
714
+ null,
715
+ 'foreColor',
716
+ null,
717
+ 'undo',
718
+ 'redo',
719
+ null,
720
+ 'viewSource'
721
+ ]
722
+
723
+
724
+ this.each(function() {
725
+ var toolbar = ' <div class="wysiwyg-toolbar btn-toolbar center"> <div class="btn-group"> ';
726
+
727
+ for(var tb in toolbar_buttons) if(toolbar_buttons.hasOwnProperty(tb)) {
728
+ var button = toolbar_buttons[tb];
729
+ if(button === null){
730
+ toolbar += ' </div> <div class="btn-group"> ';
731
+ continue;
732
+ }
733
+
734
+ if(typeof button == "string" && button in button_defaults) {
735
+ button = button_defaults[button];
736
+ button.name = toolbar_buttons[tb];
737
+ } else if(typeof button == "object" && button.name in button_defaults) {
738
+ button = $.extend(button_defaults[button.name] , button);
739
+ }
740
+ else continue;
741
+
742
+ var className = "className" in button ? button.className : '';
743
+ switch(button.name) {
744
+ case 'font':
745
+ toolbar += ' <a class="btn btn-small '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i><i class="icon-angle-down icon-on-right"></i></a> ';
746
+ toolbar += ' <ul class="dropdown-menu dropdown-light">';
747
+ for(var font in button.values)
748
+ if(button.values.hasOwnProperty(font))
749
+ toolbar += ' <li><a data-edit="fontName ' + button.values[font] +'" style="font-family:\''+ button.values[font] +'\'">'+button.values[font] + '</a></li> '
750
+ toolbar += ' </ul>';
751
+ break;
752
+
753
+ case 'fontSize':
754
+ toolbar += ' <a class="btn btn-small '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i>&nbsp;<i class="icon-angle-down icon-on-right"></i></a> ';
755
+ toolbar += ' <ul class="dropdown-menu dropdown-light"> ';
756
+ for(var size in button.values)
757
+ if(button.values.hasOwnProperty(size))
758
+ toolbar += ' <li><a data-edit="fontSize '+size+'"><font size="'+size+'">'+ button.values[size] +'</font></a></li> '
759
+ toolbar += ' </ul> ';
760
+ break;
761
+
762
+ case 'createLink':
763
+ toolbar += ' <div class="inline position-relative"> <a class="btn btn-small '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
764
+ toolbar += ' <div class="dropdown-menu dropdown-caret pull-right">\
765
+ <input placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
766
+ <button class="btn btn-small '+button.button_class+'" type="button">'+button.button_text+'</button>\
767
+ </div> </div>';
768
+ break;
769
+
770
+ case 'insertImage':
771
+ toolbar += ' <div class="inline position-relative"> <a class="btn btn-small '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
772
+ toolbar += ' <div class="dropdown-menu dropdown-caret pull-right">\
773
+ <input placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
774
+ <button class="btn btn-small '+button.button_insert_class+'" type="button">'+button.button_insert+'</button> ';
775
+ if( button.choose_file && 'FileReader' in window ) toolbar +=
776
+ '<div class="center">\
777
+ <button class="btn btn-small '+button.button_class+' wysiwyg-choose-file" type="button">'+button.button_text+'</button>\
778
+ <input type="file" data-edit="'+button.name+'" />\
779
+ </div>'
780
+ toolbar += ' </div> </div>';
781
+ break;
782
+
783
+ case 'foreColor':
784
+ case 'backColor':
785
+ toolbar += ' <select class="hide wysiwyg_colorpicker" title="'+button.title+'"> ';
786
+ for(var color in button.values)
787
+ toolbar += ' <option value="'+button.values[color]+'">'+button.values[color]+'</option> ';
788
+ toolbar += ' </select> ';
789
+ toolbar += ' <input style="display:none;" disabled class="hide" type="text" data-edit="'+button.name+'" /> ';
790
+ break;
791
+
792
+ case 'viewSource':
793
+ toolbar += ' <a class="btn btn-small '+className+'" data-view="source" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
794
+ break;
795
+ default:
796
+ toolbar += ' <a class="btn btn-small '+className+'" data-edit="'+button.name+'" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
797
+ break;
798
+ }
799
+ }
800
+ toolbar += ' </div> </div> ';
801
+
802
+
803
+
804
+ //if we have a function to decide where to put the toolbar, then call that
805
+ if(options.toolbar_place) toolbar = options.toolbar_place.call(this, toolbar);
806
+ //otherwise put it just before our DIV
807
+ else toolbar = $(this).before(toolbar).prev();
808
+
809
+ toolbar.find('a[title]').tooltip({animation:false});
810
+ toolbar.find('.dropdown-menu input:not([type=file])').on(ace.click_event, function() {return false})
811
+ .on('change', function() {$(this).closest('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle')})
812
+ .on('keydown', function (e) {if(e.which == 27) {this.value='';$(this).change()}});
813
+ toolbar.find('input[type=file]').prev().on(ace.click_event, function (e) {
814
+ $(this).next().click();
815
+ });
816
+ toolbar.find('.wysiwyg_colorpicker').each(function() {
817
+ $(this).ace_colorpicker({pull_right:true}).change(function(){
818
+ $(this).nextAll('input').eq(0).val(this.value).change();
819
+ }).next().find('.btn-colorpicker').tooltip({title: this.title, animation:false})
820
+ });
821
+
822
+ var speech_input;
823
+ if (options.speech_button && 'onwebkitspeechchange' in (speech_input = document.createElement('input'))) {
824
+ var editorOffset = $(this).offset();
825
+ toolbar.append(speech_input);
826
+ $(speech_input).attr({type:'text', 'data-edit':'inserttext','x-webkit-speech':''}).addClass('wysiwyg-speech-input')
827
+ .css({'position':'absolute'}).offset({top: editorOffset.top, left: editorOffset.left+$(this).innerWidth()-35});
828
+ } else speech_input = null
829
+
830
+
831
+ //view source
832
+ var self = $(this);
833
+ var view_source = false;
834
+ toolbar.find('a[data-view=source]').on('click', function(e){
835
+ e.preventDefault();
836
+
837
+ if(!view_source) {
838
+ $('<textarea />')
839
+ .css({'width':self.width()-3, 'height':self.height()-1})
840
+ .val(self.html())
841
+ .insertAfter(self)
842
+ self.hide();
843
+
844
+ $(this).addClass('active');
845
+ }
846
+ else {
847
+ var textarea = self.next();
848
+ self.html(textarea.val()).show();
849
+ textarea.remove();
850
+
851
+ $(this).removeClass('active');
852
+ }
853
+
854
+ view_source = !view_source;
855
+ });
856
+
857
+
858
+ var $options = $.extend({}, { activeToolbarClass: 'active' , toolbarSelector : toolbar }, options.wysiwyg || {})
859
+ $(this).wysiwyg( $options );
860
+ });
861
+
862
+ return this;
863
+ }
864
+
865
+
866
+ })(window.jQuery);