vue_crud 0.1.9.6 → 0.1.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/vue_crud/froala_generator.rb +12 -0
  3. data/lib/generators/vue_crud/sortable.rb +10 -0
  4. data/lib/generators/vue_crud/templates/assets/images/froala_editor/color_picker.png +0 -0
  5. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/froala_editor.js +11089 -0
  6. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/languages/en_gb.js +178 -0
  7. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/languages/zh_cn.js +234 -0
  8. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/languages/zh_tw.js +234 -0
  9. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/align.js +119 -0
  10. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/char_counter.js +150 -0
  11. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/code_beautifier.js +3271 -0
  12. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/code_view.js +311 -0
  13. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/colors.js +350 -0
  14. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/draggable.js +379 -0
  15. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/emoticons.js +347 -0
  16. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/entities.js +113 -0
  17. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/file.js +609 -0
  18. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/font_family.js +178 -0
  19. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/font_size.js +116 -0
  20. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/forms.js +415 -0
  21. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/fullscreen.js +209 -0
  22. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/image.js +2401 -0
  23. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/image_manager.js +921 -0
  24. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/inline_style.js +86 -0
  25. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/line_breaker.js +435 -0
  26. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/link.js +997 -0
  27. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/lists.js +382 -0
  28. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/paragraph_format.js +293 -0
  29. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/paragraph_style.js +139 -0
  30. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/quick_insert.js +342 -0
  31. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/quote.js +138 -0
  32. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/save.js +176 -0
  33. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/table.js +3123 -0
  34. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/url.js +113 -0
  35. data/lib/generators/vue_crud/templates/assets/javascripts/froala_editor/plugins/video.js +1135 -0
  36. data/lib/generators/vue_crud/templates/assets/javascripts/sortable.js +1249 -0
  37. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/froala_editor.scss +1008 -0
  38. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/froala_style.scss +273 -0
  39. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/char_counter.scss +46 -0
  40. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/code_view.scss +102 -0
  41. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/colors.scss +129 -0
  42. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/draggable.scss +32 -0
  43. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/emoticons.scss +27 -0
  44. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/file.scss +135 -0
  45. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/fullscreen.scss +28 -0
  46. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/image.scss +233 -0
  47. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/image_manager.scss +370 -0
  48. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/line_breaker.scss +26 -0
  49. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/quick_insert.scss +56 -0
  50. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/table.scss +156 -0
  51. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/plugins/video.scss +136 -0
  52. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/themes/dark.scss +1087 -0
  53. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/themes/gray.scss +1087 -0
  54. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/themes/red.scss +1087 -0
  55. data/lib/generators/vue_crud/templates/assets/stylesheets/froala_editor/themes/royal.scss +1087 -0
  56. data/lib/generators/vue_crud/templates/vue_crud.html +54 -71
  57. data/lib/vue_crud/version.rb +1 -1
  58. data/vendor/assets/javascripts/vue_crud.js +212 -59
  59. metadata +56 -2
@@ -0,0 +1,921 @@
1
+ /*!
2
+ * froala_editor v2.3.3 (https://www.froala.com/wysiwyg-editor)
3
+ * License https://froala.com/wysiwyg-editor/terms/
4
+ * Copyright 2014-2016 Froala Labs
5
+ */
6
+
7
+ (function (factory) {
8
+ if (typeof define === 'function' && define.amd) {
9
+ // AMD. Register as an anonymous module.
10
+ define(['jquery'], factory);
11
+ } else if (typeof module === 'object' && module.exports) {
12
+ // Node/CommonJS
13
+ module.exports = function( root, jQuery ) {
14
+ if ( jQuery === undefined ) {
15
+ // require('jQuery') returns a factory that requires window to
16
+ // build a jQuery instance, we normalize how we use modules
17
+ // that require this pattern but the window provided is a noop
18
+ // if it's defined (how jquery works)
19
+ if ( typeof window !== 'undefined' ) {
20
+ jQuery = require('jquery');
21
+ }
22
+ else {
23
+ jQuery = require('jquery')(root);
24
+ }
25
+ }
26
+ factory(jQuery);
27
+ return jQuery;
28
+ };
29
+ } else {
30
+ // Browser globals
31
+ factory(jQuery);
32
+ }
33
+ }(function ($) {
34
+
35
+ 'use strict';
36
+
37
+ // Extend defaults.
38
+ $.extend($.FE.DEFAULTS, {
39
+ imageManagerLoadURL: 'https://i.froala.com/load-files',
40
+ imageManagerLoadMethod: 'get',
41
+ imageManagerLoadParams: {},
42
+ imageManagerPreloader: '',
43
+ imageManagerDeleteURL: '',
44
+ imageManagerDeleteMethod: 'post',
45
+ imageManagerDeleteParams: {},
46
+ imageManagerPageSize: 12,
47
+ imageManagerScrollOffset: 20,
48
+ imageManagerToggleTags: true
49
+ });
50
+
51
+ $.FE.PLUGINS.imageManager = function (editor) {
52
+ var $modal;
53
+ var $preloader;
54
+ var $media_files;
55
+ var $scroller;
56
+ var $image_tags;
57
+ var $modal_title;
58
+ var $overlay;
59
+ var images;
60
+ var page;
61
+ var image_count;
62
+ var loaded_images;
63
+ var column_number;
64
+
65
+ // Load errors.
66
+ var BAD_LINK = 10;
67
+ var ERROR_DURING_LOAD = 11;
68
+ var MISSING_LOAD_URL_OPTION = 12;
69
+ var LOAD_BAD_RESPONSE = 13;
70
+ var MISSING_IMG_THUMB = 14;
71
+ var MISSING_IMG_URL = 15;
72
+
73
+ // Delete errors
74
+ var ERROR_DURING_DELETE = 21;
75
+ var MISSING_DELETE_URL_OPTION = 22;
76
+
77
+ // Error Messages
78
+ var error_messages = {};
79
+ error_messages[BAD_LINK] = 'Image cannot be loaded from the passed link.';
80
+ error_messages[ERROR_DURING_LOAD] = 'Error during load images request.';
81
+ error_messages[MISSING_LOAD_URL_OPTION] = 'Missing imageManagerLoadURL option.';
82
+ error_messages[LOAD_BAD_RESPONSE] = 'Parsing load response failed.';
83
+ error_messages[MISSING_IMG_THUMB] = 'Missing image thumb.';
84
+ error_messages[MISSING_IMG_URL] = 'Missing image URL.';
85
+ error_messages[ERROR_DURING_DELETE] = 'Error during delete image request.';
86
+ error_messages[MISSING_DELETE_URL_OPTION] = 'Missing imageManagerDeleteURL option.';
87
+
88
+ var $current_image;
89
+
90
+ /*
91
+ * Show the media manager.
92
+ */
93
+ function show () {
94
+ // Build the media manager.
95
+ if (!$modal) _build();
96
+
97
+ $modal.data('instance', editor);
98
+
99
+ // Show modal.
100
+ $modal.show();
101
+ $overlay.show();
102
+
103
+ $current_image = editor.image.get();
104
+
105
+ if (!$preloader) {
106
+ _delayedInit();
107
+ }
108
+
109
+ // Load images.
110
+ _loadImages();
111
+
112
+ // Prevent scrolling in page.
113
+ editor.$doc.find('body').addClass('prevent-scroll');
114
+
115
+ // Mobile device
116
+ if (editor.helpers.isMobile()) {
117
+ editor.$doc.find('body').addClass('fr-mobile');
118
+ }
119
+ }
120
+
121
+ /*
122
+ * Hide the media manager.
123
+ */
124
+ function hide () {
125
+ var inst = $modal.data('instance') || editor;
126
+ inst.events.enableBlur();
127
+ $modal.hide();
128
+ $overlay.hide();
129
+ inst.$doc.find('body').removeClass('prevent-scroll fr-mobile');
130
+ }
131
+
132
+ /*
133
+ * Get the number of columns based on window width.
134
+ */
135
+ function _columnNumber () {
136
+ var window_width = $(window).outerWidth();
137
+
138
+ // Screen XS.
139
+ if (window_width < 768) {
140
+ return 2;
141
+ }
142
+
143
+ // Screen SM and MD.
144
+ else if (window_width < 1200) {
145
+ return 3;
146
+ }
147
+
148
+ // Screen LG.
149
+ else {
150
+ return 4;
151
+ }
152
+ }
153
+
154
+ /*
155
+ * Add the correct number of columns.
156
+ */
157
+ function _buildColumns () {
158
+ $media_files.empty();
159
+
160
+ for (var i = 0; i < column_number; i++) {
161
+ $media_files.append('<div class="fr-list-column"></div>');
162
+ }
163
+ }
164
+
165
+ /*
166
+ * The media manager modal HTML.
167
+ */
168
+ function _modalHTML () {
169
+ var cls = '';
170
+
171
+ if (editor.opts.theme) {
172
+ cls = ' ' + editor.opts.theme + '-theme';
173
+ }
174
+
175
+ // Modal wrapper.
176
+ var html = '<div class="fr-modal' + cls + '"><div class="fr-modal-wrapper">';
177
+
178
+ // Modal title.
179
+ html += '<div class="fr-modal-title"><div class="fr-modal-title-line"><i class="fa fa-bars fr-modal-more fr-not-available" id="fr-modal-more-' + editor.sid + '" title="' + editor.language.translate('Tags') + '"></i><h4 data-text="true">' + editor.language.translate('Manage Images') + '</h4><i title="' + editor.language.translate('Cancel') + '" class="fa fa-times fr-modal-close" id="fr-modal-close"></i></div>';
180
+
181
+ // Tags
182
+ html += '<div class="fr-modal-tags" id="fr-modal-tags"></div>';
183
+ html += '</div>';
184
+
185
+ // Preloader.
186
+ html += '<img class="fr-preloader" id="fr-preloader" alt="' + editor.language.translate('Loading') + '.." src="' + editor.opts.imageManagerPreloader + '" style="display: none;">';
187
+
188
+ // Modal scroller.
189
+ html += '<div class="fr-scroller" id="fr-scroller"><div class="fr-image-list" id="fr-image-list"></div></div>';
190
+
191
+ html += '</div></div>';
192
+
193
+ return $(html);
194
+ }
195
+
196
+ /*
197
+ * Build the image manager.
198
+ */
199
+ function _build () {
200
+ // Build modal.
201
+ if (!editor.shared.$modal) {
202
+ editor.shared.$modal = _modalHTML();
203
+
204
+ $modal = editor.shared.$modal;
205
+
206
+ // Desktop or mobile device.
207
+ if (!editor.helpers.isMobile()) {
208
+ $modal.addClass('fr-desktop');
209
+ }
210
+
211
+ // Append modal to body.
212
+ $modal.appendTo('body');
213
+
214
+ editor.shared.$overlay = $('<div class="fr-overlay">').appendTo('body');
215
+ $overlay = editor.shared.$overlay;
216
+
217
+ if (editor.opts.theme) {
218
+ $overlay.addClass(editor.opts.theme + '-theme');
219
+ }
220
+
221
+ // Finished building the media manager.
222
+ hide();
223
+ }
224
+ else {
225
+ $modal = editor.shared.$modal;
226
+ $overlay = editor.shared.$overlay;
227
+ }
228
+
229
+ // Editor destroy.
230
+ editor.events.on('shared.destroy', function () {
231
+ $modal.removeData().remove();
232
+ $overlay.removeData().remove();
233
+ }, true);
234
+ }
235
+
236
+ /*
237
+ * Load images from server.
238
+ */
239
+ function _loadImages () {
240
+ $preloader.show();
241
+ $media_files.find('.fr-list-column').empty();
242
+
243
+ // If the images load URL is set.
244
+ if (editor.opts.imageManagerLoadURL) {
245
+ // Make GET request to get the images.
246
+ $.ajax({
247
+ url: editor.opts.imageManagerLoadURL,
248
+ method: editor.opts.imageManagerLoadMethod,
249
+ data: editor.opts.imageManagerLoadParams,
250
+ dataType: 'json',
251
+ crossDomain: editor.opts.requestWithCORS,
252
+ xhrFields: {
253
+ withCredentials: editor.opts.requestWithCORS
254
+ },
255
+ headers: editor.opts.requestHeaders
256
+ })
257
+ // On success start processing the response.
258
+ .done(function (data, status, xhr) {
259
+ editor.events.trigger('imageManager.imagesLoaded', [data]);
260
+ _processLoadedImages(data, xhr.response);
261
+ $preloader.hide();
262
+ })
263
+
264
+ // On fail throw error during request.
265
+ .fail(function () {
266
+ var xhr = this.xhr();
267
+ _throwError(ERROR_DURING_LOAD, xhr.response || xhr.responseText);
268
+ });
269
+ }
270
+
271
+ // Throw missing imageManagerLoadURL option error.
272
+ else {
273
+ _throwError(MISSING_LOAD_URL_OPTION);
274
+ }
275
+ }
276
+
277
+ /*
278
+ * Process loaded images.
279
+ */
280
+ function _processLoadedImages (imgs, response) {
281
+ try {
282
+ $media_files.find('.fr-list-column').empty();
283
+ page = 0;
284
+ image_count = 0;
285
+ loaded_images = 0;
286
+ images = imgs;
287
+
288
+ // Load files.
289
+ _infiniteScroll();
290
+ }
291
+
292
+ // Throw error while parsing the response.
293
+ catch (ex) {
294
+ _throwError(LOAD_BAD_RESPONSE, response);
295
+ }
296
+ }
297
+
298
+ /*
299
+ * Load more images if necessary.
300
+ */
301
+ function _infiniteScroll () {
302
+ // If there aren't enough images in the modal or if the user scrolls down.
303
+ if (image_count < images.length &&
304
+ ($media_files.outerHeight() <= $scroller.outerHeight() + editor.opts.imageManagerScrollOffset ||
305
+ $scroller.scrollTop() + editor.opts.imageManagerScrollOffset > $media_files.outerHeight() - $scroller.outerHeight())) {
306
+ // Increase page number.
307
+ page++;
308
+
309
+ // Load each image on this page.
310
+ for (var i = editor.opts.imageManagerPageSize * (page - 1); i < Math.min(images.length, editor.opts.imageManagerPageSize * page); i++) {
311
+ _loadImage(images[i]);
312
+ }
313
+ }
314
+ }
315
+
316
+ /*
317
+ * Load file.
318
+ */
319
+ function _loadImage (image) {
320
+ var img = new Image();
321
+ var $img_container = $('<div class="fr-image-container fr-empty fr-image-' + (loaded_images++) + '" data-loading="' + editor.language.translate('Loading') + '.." data-deleting="' + editor.language.translate('Deleting') + '..">');
322
+
323
+ // After adding image empty container modal might change its height.
324
+ _resizeModal(false);
325
+
326
+ // Image has been loaded.
327
+ img.onload = function () {
328
+ // Update image container height.
329
+ $img_container.height(Math.floor($img_container.width() / img.width * img.height));
330
+
331
+ // Create image HTML.
332
+ var $img = $('<img/>');
333
+
334
+ // Use image thumb in image manager.
335
+ if (image.thumb) {
336
+ // Set image src attribute/
337
+ $img.attr('src', image.thumb);
338
+ }
339
+
340
+ // Image does not have thumb.
341
+ else {
342
+ // Throw missing image thumb error.
343
+ _throwError(MISSING_IMG_THUMB, image);
344
+
345
+ // Set image URL as src attribute.
346
+ if (image.url) {
347
+ $img.attr('src', image.url);
348
+ }
349
+ // Missing image URL.
350
+ else {
351
+ // Throw missing image url error.
352
+ _throwError(MISSING_IMG_URL, image);
353
+
354
+ // Don't go further if image does not have a src attribute.
355
+ return false;
356
+ }
357
+ }
358
+
359
+ // Save image URL.
360
+ if (image.url) $img.attr('data-url', image.url);
361
+
362
+ // Image tags.
363
+ if (image.tag) {
364
+ // Show tags only if there are any.
365
+ $modal_title.find('.fr-modal-more.fr-not-available').removeClass('fr-not-available');
366
+ $modal_title.find('.fr-modal-tags').show();
367
+
368
+ // Image has more than one tag.
369
+ if (image.tag.indexOf(',') >= 0) {
370
+ // Add tags to the image manager tag list.
371
+ var tags = image.tag.split(',');
372
+
373
+ for (var i = 0; i < tags.length; i++) {
374
+ // Remove trailing spaces.
375
+ tags[i] = tags[i].trim();
376
+
377
+ // Add tag.
378
+ if ($image_tags.find('a[title="' + tags[i] + '"]').length === 0) {
379
+ $image_tags.append('<a role="button" title="' + tags[i] + '">' + tags[i] + '</a>');
380
+ }
381
+ }
382
+
383
+ // Set img tag attribute.
384
+ $img.attr('data-tag', tags.join());
385
+ }
386
+
387
+ // Image has only one tag.
388
+ else {
389
+ // Add tag to the tag list.
390
+ if ($image_tags.find('a[title="' + image.tag.trim() + '"]').length === 0) {
391
+ $image_tags.append('<a role="button" title="' + image.tag.trim() + '">' + image.tag.trim() + '</a>');
392
+ }
393
+
394
+ // Set img tag attribute.
395
+ $img.attr('data-tag', image.tag.trim());
396
+ }
397
+ }
398
+
399
+ // Set image additional data.
400
+ for (var key in image) {
401
+ if (image.hasOwnProperty(key)) {
402
+ if (key != 'thumb' && key != 'url' && key != 'tag') {
403
+ $img.attr('data-' + key, image[key]);
404
+ }
405
+ }
406
+ }
407
+
408
+ // Add image and insert and delete buttons to the image container.
409
+ $img_container
410
+ .append($img)
411
+ .append($(editor.icon.create('imageManagerDelete')).addClass('fr-delete-img').attr('title', editor.language.translate('Delete')))
412
+ .append($(editor.icon.create('imageManagerInsert')).addClass('fr-insert-img').attr('title', editor.language.translate('Insert')))
413
+
414
+ // Show image only if it has selected tags.
415
+ $image_tags.find('.fr-selected-tag').each (function (index, tag) {
416
+ if (!_imageHasTag($img, tag.text)) {
417
+ $img_container.hide();
418
+ }
419
+ });
420
+
421
+ // After an image is loaded the modal may need to be resized.
422
+ $img.on('load', function () {
423
+ // Image container is no longer empty.
424
+ $img_container.removeClass('fr-empty');
425
+ $img_container.height('auto');
426
+
427
+ // Increase image counter.
428
+ image_count++;
429
+
430
+ // A loded image may break the images order. Reorder them starting with this image.
431
+ var imgs = _getImages(parseInt($img.parent().attr('class').match(/fr-image-(\d+)/)[1], 10) + 1);
432
+
433
+ // Reorder images.
434
+ _reorderImages(imgs);
435
+
436
+ // Image modal may need resizing.
437
+ _resizeModal(false);
438
+
439
+ // If this was the last image on page then we might need to load more.
440
+ if (image_count % editor.opts.imageManagerPageSize === 0) {
441
+ _infiniteScroll();
442
+ }
443
+ });
444
+
445
+ // Trigger imageLoaded event.
446
+ editor.events.trigger('imageManager.imageLoaded', [$img]);
447
+ };
448
+
449
+ // Error while loading the image.
450
+ img.onerror = function () {
451
+ image_count++;
452
+ $img_container.remove();
453
+
454
+ // Removing an image container may break image order.
455
+ var imgs = _getImages(parseInt($img_container.attr('class').match(/fr-image-(\d+)/)[1], 10) + 1);
456
+
457
+ // Reorder images.
458
+ _reorderImages(imgs);
459
+
460
+ _throwError(BAD_LINK, image);
461
+
462
+ // If this was the last image on page then we might need to load more.
463
+ if (image_count % editor.opts.imageManagerPageSize === 0) {
464
+ _infiniteScroll();
465
+ }
466
+ };
467
+
468
+ // Set the image object's src.
469
+ img.src = image.url;
470
+
471
+ // Add loaded or empty image to the media manager image list on the shortest column.
472
+ _shortestColumn().append($img_container);
473
+ }
474
+
475
+ /*
476
+ * Get the shortest image column.
477
+ */
478
+ function _shortestColumn () {
479
+ var $col;
480
+ var min_height;
481
+
482
+ $media_files.find('.fr-list-column').each (function (index, col) {
483
+ var $column = $(col);
484
+
485
+ // Assume that the first column is the shortest.
486
+ if (index === 0) {
487
+ min_height = $column.outerHeight();
488
+ $col = $column;
489
+ }
490
+
491
+ // Check if another column is shorter.
492
+ else {
493
+ if ($column.outerHeight() < min_height) {
494
+ min_height = $column.outerHeight();
495
+ $col = $column;
496
+ }
497
+ }
498
+ });
499
+
500
+ return $col;
501
+ }
502
+
503
+ /*
504
+ * Get all images from the image manager.
505
+ */
506
+ function _getImages (from) {
507
+ if (from === undefined) from = 0;
508
+ var get_images = [];
509
+
510
+ for (var i = loaded_images - 1; i >= from; i--) {
511
+ var $image = $media_files.find('.fr-image-' + i);
512
+
513
+ if ($image.length) {
514
+ get_images.push($image);
515
+
516
+ // Add images here before deleting them so the on load callback is triggered.
517
+ $('<div id="fr-image-hidden-container">').append($image);
518
+ $media_files.find('.fr-image-' + i).remove();
519
+ }
520
+ }
521
+
522
+ return get_images;
523
+ }
524
+
525
+ /*
526
+ * Add images back into the image manager.
527
+ */
528
+ function _reorderImages (imgs) {
529
+ for (var i = imgs.length - 1; i >= 0; i--) {
530
+ _shortestColumn().append(imgs[i]);
531
+ }
532
+ }
533
+
534
+ /*
535
+ * Resize the media manager modal and scroller if height changes.
536
+ */
537
+ function _resizeModal (infinite_scroll) {
538
+ if (infinite_scroll === undefined) infinite_scroll = true;
539
+ if (!$modal.is(':visible')) return true;
540
+
541
+ // If width changes, the number of columns may change.
542
+ var cols = _columnNumber();
543
+
544
+ if (cols != column_number) {
545
+ column_number = cols;
546
+
547
+ // Get all images.
548
+ var imgs = _getImages();
549
+
550
+ // Remove current columns and add new ones.
551
+ _buildColumns();
552
+
553
+ // Reorder images.
554
+ _reorderImages(imgs);
555
+ }
556
+
557
+ var height = editor.$win.height();
558
+
559
+ // The wrapper and scroller objects.
560
+ var $wrapper = $modal.find('.fr-modal-wrapper');
561
+
562
+ // Wrapper's top and bottom margins.
563
+ var wrapper_margins = parseFloat($wrapper.css('margin-top')) + parseFloat($wrapper.css('margin-bottom'));
564
+ var wrapper_padding = parseFloat($wrapper.css('padding-top')) + parseFloat($wrapper.css('padding-bottom'));
565
+ var wrapper_border_top = parseFloat($wrapper.css('border-top-width'));
566
+ var h4_height = $wrapper.find('h4').outerHeight();
567
+
568
+ // Change height.
569
+ $scroller.height(Math.min($media_files.outerHeight(), height - wrapper_margins - wrapper_padding - h4_height - wrapper_border_top));
570
+
571
+ // Load more photos when window is resized if necessary.
572
+ if (infinite_scroll) {
573
+ _infiniteScroll();
574
+ }
575
+ }
576
+
577
+ function _getImageAttrs ($img) {
578
+ var img_attributes = {};
579
+ var img_data = $img.data();
580
+
581
+ for (var key in img_data) {
582
+ if (img_data.hasOwnProperty(key)) {
583
+ if (key != 'url' && key != 'tag') {
584
+ img_attributes[key] = img_data[key];
585
+ }
586
+ }
587
+ }
588
+
589
+ return img_attributes;
590
+ }
591
+
592
+ /*
593
+ * Insert image into the editor.
594
+ */
595
+ function _insertImage (e) {
596
+ // Image to insert.
597
+ var $img = $(e.currentTarget).siblings('img');
598
+
599
+ var inst = $modal.data('instance') || editor;
600
+
601
+ hide();
602
+ inst.image.showProgressBar();
603
+
604
+ if (!$current_image) {
605
+ // Make sure we have focus.
606
+ inst.events.focus(true);
607
+ inst.selection.restore();
608
+
609
+ var rect = inst.position.getBoundingRect();
610
+
611
+ var left = rect.left + rect.width / 2;
612
+ var top = rect.top + rect.height;
613
+
614
+ // Show the image insert popup.
615
+ inst.popups.setContainer('image.insert', inst.$box || $('body'));
616
+ inst.popups.show('image.insert', left, top);
617
+ }
618
+ else {
619
+ $current_image.trigger('click');
620
+ }
621
+
622
+ inst.image.insert($img.data('url'), false, _getImageAttrs($img), $current_image);
623
+ }
624
+
625
+ /*
626
+ * Delete image.
627
+ */
628
+ function _deleteImage (e) {
629
+ // Image to delete.
630
+ var $img = $(e.currentTarget).siblings('img');
631
+
632
+ // Confirmation message.
633
+ var message = editor.language.translate('Are you sure? Image will be deleted.');
634
+
635
+ // Ask for confirmation.
636
+ if (confirm(message)) {
637
+ // If the images delete URL is set.
638
+ if (editor.opts.imageManagerDeleteURL) {
639
+ // Before delete image event.
640
+ if (editor.events.trigger('imageManager.beforeDeleteImage', [$img]) !== false) {
641
+ $img.parent().addClass('fr-image-deleting');
642
+
643
+ // Make request to delete image from server.
644
+ $.ajax({
645
+ method: editor.opts.imageManagerDeleteMethod,
646
+ url: editor.opts.imageManagerDeleteURL,
647
+ data: $.extend($.extend({ src: $img.attr('src') }, _getImageAttrs($img)), editor.opts.imageManagerDeleteParams),
648
+ crossDomain: editor.opts.requestWithCORS,
649
+ xhrFields: {
650
+ withCredentials: editor.opts.requestWithCORS
651
+ },
652
+ headers: editor.opts.requestHeaders
653
+ })
654
+
655
+ // On success remove the image from the image manager.
656
+ .done(function (data) {
657
+ editor.events.trigger('imageManager.imageDeleted', [data]);
658
+ // A deleted image may break the images order. Reorder them starting with this image.
659
+ var imgs = _getImages(parseInt($img.parent().attr('class').match(/fr-image-(\d+)/)[1], 10) + 1);
660
+
661
+ // Remove the image.
662
+ $img.parent().remove();
663
+
664
+ // Reorder images.
665
+ _reorderImages(imgs);
666
+
667
+ // Modal needs resizing.
668
+ _resizeModal(true);
669
+ })
670
+
671
+ // On fail throw error during request.
672
+ .fail(function () {
673
+ var xhr = this.xhr();
674
+ _throwError(ERROR_DURING_DELETE, xhr.response || xhr.responseText);
675
+ });
676
+ }
677
+ }
678
+
679
+ // Throw missing imageManagerDeleteURL option error.
680
+ else {
681
+ _throwError(MISSING_DELETE_URL_OPTION);
682
+ }
683
+ }
684
+ }
685
+
686
+ /*
687
+ * Throw image manager errors.
688
+ */
689
+ function _throwError (code, response) {
690
+ // Load images error.
691
+ if (10 <= code && code < 20) {
692
+ // Hide preloader.
693
+ $preloader.hide();
694
+ }
695
+
696
+ // Delete image error.
697
+ else if (20 <= code && code < 30) {
698
+ // Remove deleting overlay.
699
+ $('.fr-image-deleting').removeClass('fr-image-deleting');
700
+ }
701
+
702
+ // Trigger error event.
703
+ editor.events.trigger('imageManager.error', [{
704
+ code: code,
705
+ message: error_messages[code]
706
+ }, response]);
707
+ }
708
+
709
+ /*
710
+ * Toogle (show or hide) image tags.
711
+ */
712
+ function _toggleTags () {
713
+ var title_height = $modal_title.find('.fr-modal-title-line').outerHeight();
714
+ var tags_height = $image_tags.outerHeight();
715
+
716
+ // Use .fr-show-tags.
717
+ $modal_title.toggleClass('.fr-show-tags');
718
+
719
+ if ($modal_title.hasClass('.fr-show-tags')) {
720
+ // Show tags by changing height to have transition.
721
+ $modal_title.css('height', title_height + tags_height);
722
+ $image_tags.find('a').css('opacity', 1);
723
+ }
724
+
725
+ else {
726
+ // Hide tags by changing height to have transition.
727
+ $modal_title.css('height', title_height);
728
+ $image_tags.find('a').css('opacity', 0);
729
+ }
730
+ }
731
+
732
+ /*
733
+ * Show only images with selected tags.
734
+ */
735
+ function _showImagesByTags() {
736
+ // Get all selected tags.
737
+ var $tags = $image_tags.find('.fr-selected-tag');
738
+
739
+ // Show only images with selected tags.
740
+ if ($tags.length > 0) {
741
+ // Hide all images.
742
+ $media_files.find('img').parent().show();
743
+
744
+ // Show only images with tag.
745
+ $tags.each (function (index, tag) {
746
+ $media_files.find('img').each (function (index, img) {
747
+ var $img = $(img);
748
+
749
+ if (!_imageHasTag($img, tag.text)) {
750
+ $img.parent().hide();
751
+ }
752
+ });
753
+ });
754
+ }
755
+
756
+ // There are no more tags selected. Show all images.
757
+ else {
758
+ $media_files.find('img').parent().show();
759
+ }
760
+
761
+ // Rearrange images.
762
+ var imgs = _getImages();
763
+
764
+ // Reorder images.
765
+ _reorderImages(imgs);
766
+
767
+ // Load more images if necessary.
768
+ _infiniteScroll();
769
+ }
770
+
771
+ /*
772
+ * Select an image tag from the list.
773
+ */
774
+ function _selectTag (e) {
775
+ e.preventDefault();
776
+
777
+ // Toggle current tags class.
778
+ var $tag = $(e.currentTarget);
779
+ $tag.toggleClass('fr-selected-tag');
780
+
781
+ // Toggle selected tags.
782
+ if (editor.opts.imageManagerToggleTags) $tag.siblings('a').removeClass('fr-selected-tag');
783
+
784
+ // Change displayed images.
785
+ _showImagesByTags();
786
+ }
787
+
788
+ /*
789
+ * Method to check if an image has a specific tag.
790
+ */
791
+ function _imageHasTag ($image, tag) {
792
+ var tags = $image.attr('data-tag').split(',');
793
+
794
+ for (var i = 0; i < tags.length; i++) {
795
+ if (tags[i] == tag) {
796
+ return true;
797
+ }
798
+ }
799
+
800
+ return false;
801
+ }
802
+
803
+ function _delayedInit() {
804
+ $preloader = $modal.find('#fr-preloader');
805
+ $media_files = $modal.find('#fr-image-list');
806
+ $scroller = $modal.find('#fr-scroller');
807
+ $image_tags = $modal.find('#fr-modal-tags');
808
+ $modal_title = $image_tags.parent();
809
+
810
+ // Columns.
811
+ column_number = _columnNumber();
812
+ _buildColumns();
813
+
814
+ // Set height for title (we need this for show tags transition).
815
+ var title_height = $modal_title.find('.fr-modal-title-line').outerHeight();
816
+ $modal_title.css('height', title_height);
817
+ $scroller.css('margin-top', title_height);
818
+
819
+ // Close button.
820
+ editor.events.bindClick($modal, 'i#fr-modal-close', hide);
821
+
822
+ // Resize media manager modal on window resize.
823
+ editor.events.$on($(editor.o_win), 'resize', function () {
824
+ // Window resize with image manager opened.
825
+ if (images) {
826
+ _resizeModal(true);
827
+ }
828
+
829
+ // iOS window resize is triggered when modal first opens (no images loaded).
830
+ else {
831
+ _resizeModal(false);
832
+ }
833
+ });
834
+
835
+ // Delete and insert buttons for mobile.
836
+ if (editor.helpers.isMobile()) {
837
+ // Show image buttons on mobile.
838
+ editor.events.bindClick($media_files, 'div.fr-image-container', function (e) {
839
+ $modal.find('.fr-mobile-selected').removeClass('fr-mobile-selected');
840
+ $(e.currentTarget).addClass('fr-mobile-selected');
841
+ });
842
+
843
+ // Hide image buttons if we click outside it.
844
+ $modal.on(editor._mousedown, function () {
845
+ $modal.find('.fr-mobile-selected').removeClass('fr-mobile-selected');
846
+ });
847
+ }
848
+
849
+ // Insert image.
850
+ editor.events.bindClick($media_files, '.fr-insert-img', _insertImage);
851
+
852
+ // Delete image.
853
+ editor.events.bindClick($media_files, '.fr-delete-img', _deleteImage);
854
+
855
+ // Make sure we don't trigger blur.
856
+ $modal.on(editor._mousedown + ' ' + editor._mouseup, function (e) {
857
+ e.stopPropagation();
858
+ });
859
+
860
+ // Mouse down on anything.
861
+ $modal.on(editor._mousedown, '*', function () {
862
+ editor.events.disableBlur();
863
+ });
864
+
865
+ // Infinite scroll
866
+ $scroller.on('scroll', _infiniteScroll);
867
+
868
+ // Click on image tags button.
869
+ editor.events.bindClick($modal, 'i#fr-modal-more-' + editor.sid, _toggleTags);
870
+
871
+ // Select an image tag.
872
+ editor.events.bindClick($image_tags, 'a', _selectTag);
873
+ }
874
+
875
+ /*
876
+ * Init media manager.
877
+ */
878
+ function _init () {
879
+ if (!editor.$wp && editor.$el.get(0).tagName != 'IMG') return false;
880
+ }
881
+
882
+ return {
883
+ require: ['image'],
884
+ _init: _init,
885
+ show: show,
886
+ hide: hide
887
+ }
888
+ };
889
+
890
+ if (!$.FE.PLUGINS.image) {
891
+ throw new Error('Image manager plugin requires image plugin.');
892
+ }
893
+
894
+ $.FE.DEFAULTS.imageInsertButtons.push('imageManager');
895
+
896
+ $.FE.RegisterCommand('imageManager', {
897
+ title: 'Browse',
898
+ undo: false,
899
+ focus: false,
900
+ callback: function () {
901
+ this.imageManager.show();
902
+ },
903
+ plugin: 'imageManager'
904
+ })
905
+
906
+ // Add the font size icon.
907
+ $.FE.DefineIcon('imageManager', {
908
+ NAME: 'folder'
909
+ });
910
+
911
+ // Add the font size icon.
912
+ $.FE.DefineIcon('imageManagerInsert', {
913
+ NAME: 'plus'
914
+ });
915
+
916
+ // Add the font size icon.
917
+ $.FE.DefineIcon('imageManagerDelete', {
918
+ NAME: 'trash'
919
+ });
920
+
921
+ }));