push_type_wysiwyg 0.2.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +3 -0
  4. data/app/assets/javascripts/push_type/froala_overrides/file_upload.js +133 -0
  5. data/app/assets/javascripts/push_type/froala_overrides/froala_editor.js +34 -0
  6. data/app/assets/javascripts/push_type/froala_overrides/image_editor.js +215 -0
  7. data/app/assets/javascripts/push_type/froala_overrides/media_manager.js +184 -0
  8. data/app/assets/javascripts/push_type/media_styles.js.coffee.erb +5 -0
  9. data/app/assets/javascripts/push_type/wysiwyg.js.coffee +50 -0
  10. data/app/assets/stylesheets/push_type/froala_overrides.scss +77 -0
  11. data/app/assets/stylesheets/push_type/pt_theme.scss +373 -0
  12. data/app/assets/stylesheets/push_type/wysiwyg.scss +36 -0
  13. data/app/controllers/push_type/wysiwyg_media_controller.rb +43 -0
  14. data/app/fields/push_type/wysiwyg_field.rb +10 -0
  15. data/app/helpers/push_type/wysiwyg_media_helper.rb +34 -0
  16. data/config/routes.rb +3 -0
  17. data/lib/push_type/wysiwyg/engine.rb +16 -0
  18. data/lib/push_type/wysiwyg.rb +14 -0
  19. data/lib/push_type_wysiwyg.rb +2 -0
  20. data/lib/tasks/push_type_tasks.rake +4 -0
  21. data/test/controllers/push_type/wysiwyg_media_controller_test.rb +58 -0
  22. data/test/dummy/README.rdoc +28 -0
  23. data/test/dummy/Rakefile +6 -0
  24. data/test/dummy/app/assets/javascripts/application.js +16 -0
  25. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/test/dummy/app/controllers/application_controller.rb +5 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/models/page.rb +10 -0
  29. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  30. data/test/dummy/app/views/nodes/page.html.erb +3 -0
  31. data/test/dummy/bin/bundle +3 -0
  32. data/test/dummy/bin/rails +4 -0
  33. data/test/dummy/bin/rake +4 -0
  34. data/test/dummy/bin/setup +29 -0
  35. data/test/dummy/config/application.rb +14 -0
  36. data/test/dummy/config/boot.rb +4 -0
  37. data/test/dummy/config/database.yml +85 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +41 -0
  40. data/test/dummy/config/environments/production.rb +79 -0
  41. data/test/dummy/config/environments/test.rb +42 -0
  42. data/test/dummy/config/initializers/assets.rb +11 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  44. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  45. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  46. data/test/dummy/config/initializers/inflections.rb +16 -0
  47. data/test/dummy/config/initializers/mime_types.rb +4 -0
  48. data/test/dummy/config/initializers/push_type.rb +15 -0
  49. data/test/dummy/config/initializers/session_store.rb +3 -0
  50. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  51. data/test/dummy/config/locales/en.yml +23 -0
  52. data/test/dummy/config/routes.rb +59 -0
  53. data/test/dummy/config/secrets.yml +22 -0
  54. data/test/dummy/config.ru +4 -0
  55. data/test/dummy/db/migrate/20150208150336_create_push_type_users.push_type.rb +13 -0
  56. data/test/dummy/db/migrate/20150208150337_create_push_type_nodes.push_type.rb +25 -0
  57. data/test/dummy/db/migrate/20150208150338_create_push_type_node_hierarchies.push_type.rb +17 -0
  58. data/test/dummy/db/migrate/20150208150339_create_push_type_assets.push_type.rb +19 -0
  59. data/test/dummy/db/schema.rb +67 -0
  60. data/test/dummy/db/seeds.rb +7 -0
  61. data/test/dummy/log/test.log +1309 -0
  62. data/test/dummy/public/404.html +67 -0
  63. data/test/dummy/public/422.html +67 -0
  64. data/test/dummy/public/500.html +66 -0
  65. data/test/dummy/public/favicon.ico +0 -0
  66. data/test/dummy/public/robots.txt +5 -0
  67. data/test/dummy/tmp/cache/assets/test/sprockets/0a170bcd46595a69e9181ea5eb52ec6f +0 -0
  68. data/test/dummy/tmp/cache/assets/test/sprockets/853c1095ab6e7f4eba1f3406f0f3bba6 +0 -0
  69. data/test/helpers/push_type/wysiwyg_media_helper_test.rb +41 -0
  70. data/test/models/push_type/wysiwyg_field_test.rb +9 -0
  71. data/test/test_helper.rb +21 -0
  72. data/vendor/assets/javascripts/jquery.simplePagination.js +334 -0
  73. metadata +252 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 53a41e1f5039820e921d517c59b75829c446f62f
4
+ data.tar.gz: 34fc5ae82f747a0c73b6e3bcee2a33371b9190c0
5
+ SHA512:
6
+ metadata.gz: 2a8445aa224978e5a16c40f25c8576f09d5c55531dcdbd4df4748e028b6a2c2b6198d10abb45d86cb4734955c305596f3888744809cfa6d4615acdbbb933b988
7
+ data.tar.gz: 5c9ffe9f80c720b720892a1734389ded25ad8254b43a484ac143efbaa5312f8fcc93767f63551337970b8109921aecde6a9dea4c7f57648d830fec36f09d7ce8
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Push Code Ltd
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # PushType-Wysiwyg
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,133 @@
1
+ $.Editable.prototype.fileUploadHTML = function () {
2
+ var html = '<div class="froala-popup froala-file-popup" style="display: none;"><h4><span data-text="true">Upload file</span><i title="Cancel" class="fa fa-times" id="f-file-close-' + this._id + '"></i></h4>';
3
+
4
+ html += '<div id="f-file-list-' + this._id + '">';
5
+
6
+ html += '<div class="f-popup-line drop-upload">';
7
+ html += '<div class="f-upload" id="f-file-upload-div-' + this._id + '"><strong data-text="true">Drop File</strong><br>(<span data-text="true">or click</span>)<form target="file-frame-' + this._id + '" enctype="multipart/form-data" encoding="multipart/form-data" action="' + this.options.fileUploadURL + '" method="post" id="f-file-form-' + this._id + '"><input id="f-file-upload-' + this._id + '" type="file" name="' + this.options.fileUploadParam + '" accept="/*"></form></div>';
8
+
9
+ if (this.browser.msie && $.Editable.getIEversion() <= 9) {
10
+ html += '<iframe id="file-frame-' + this._id + '" name="file-frame-' + this._id + '" src="javascript:false;" style="width:0; height:0; border:0px solid #FFF; position: fixed; z-index: -1;" data-loaded="true"></iframe>';
11
+ }
12
+
13
+ html += '</div>';
14
+
15
+ if (this.options.fileLink) {
16
+ html += '<div class="f-popup-line"><label><span data-text="true">Enter URL</span>: </label><input id="f-file-url-' + this._id + '" type="text" placeholder="http://example.com"><button class="f-browse fr-p-bttn" id="f-browser-' + this._id + '"><i class="fa fa-search"></i></button><button data-text="true" class="f-ok fr-p-bttn" id="f-file-ok-' + this._id + '">OK</button></div>';
17
+ }
18
+
19
+ html += '</div>';
20
+ html += '<p class="f-progress" id="f-file-progress-' + this._id + '"><span></span></p>';
21
+ html += '</div>';
22
+
23
+ return html;
24
+ }
25
+
26
+
27
+ /**
28
+ * Build file upload.
29
+ */
30
+ $.Editable.prototype.buildFileUpload = function () {
31
+ // Add file wrapper to editor.
32
+ this.$file_wrapper = $(this.fileUploadHTML());
33
+ this.$popup_editor.append(this.$file_wrapper);
34
+
35
+ this.buildFileDrag();
36
+
37
+ var that = this;
38
+
39
+ // Stop event propagation in file.
40
+ this.$file_wrapper.on('mouseup touchend', $.proxy(function (e) {
41
+ if (!this.isResizing()) {
42
+ e.stopPropagation();
43
+ }
44
+ }, this));
45
+
46
+ this.addListener('hidePopups', $.proxy(function () {
47
+ this.hideFileWrapper();
48
+ }), this);
49
+
50
+ // Init progress bar.
51
+ this.$file_progress_bar = this.$file_wrapper.find('p#f-file-progress-' + this._id);
52
+
53
+ // Build upload frame.
54
+ if (this.browser.msie && $.Editable.getIEversion() <= 9) {
55
+ var iFrame = this.$file_wrapper.find('iframe').get(0);
56
+
57
+ if (iFrame.attachEvent) {
58
+ iFrame.attachEvent('onload', function () { that.iFrameLoad() });
59
+ } else {
60
+ iFrame.onload = function () { that.iFrameLoad() };
61
+ }
62
+ }
63
+
64
+ // File was picked.
65
+ this.$file_wrapper.on('change', 'input[type="file"]', function () {
66
+ // Files were picked.
67
+ if (this.files !== undefined) {
68
+ that.uploadFile(this.files);
69
+ }
70
+
71
+ // IE 9 upload.
72
+ else {
73
+ var $form = $(this).parents('form');
74
+ $form.find('input[type="hidden"]').remove();
75
+ var key;
76
+ for (key in that.options.fileUploadParams) {
77
+ $form.prepend('<input type="hidden" name="' + key + '" value="' + that.options.fileUploadParams[key] + '" />');
78
+ }
79
+
80
+ that.$file_wrapper.find('#f-file-list-' + that._id).hide();
81
+ that.$file_progress_bar.show();
82
+ that.$file_progress_bar.find('span').css('width', '100%').text('Please wait!');
83
+ that.showFileUpload();
84
+
85
+ $form.submit();
86
+ }
87
+
88
+ // Chrome fix.
89
+ $(this).val('');
90
+ });
91
+
92
+ // Create a list with all the items from the popup.
93
+ this.$file_wrapper.on('click', '#f-file-ok-' + this._id, $.proxy(function () {
94
+ var file = this.$file_wrapper.find('#f-file-url-' + this._id).val();
95
+ if (file !== '') {
96
+ this.writeFile(file, file);
97
+ }
98
+ }, this));
99
+
100
+ // Wrap things in file wrapper.
101
+ this.$file_wrapper.on(this.mouseup, '#f-file-close-' + this._id, $.proxy(function () {
102
+ e.stopPropagation();
103
+ e.preventDefault();
104
+
105
+ this.$bttn_wrapper.show();
106
+ this.hideFileWrapper();
107
+
108
+ this.restoreSelection();
109
+ this.focus();
110
+
111
+ this.hide();
112
+ }, this))
113
+
114
+ this.$file_wrapper
115
+ .on('click', '#f-browser-' + this._id, $.proxy(function () {
116
+ this.showMediaManager('file');
117
+ }, this))
118
+ .on('click', '#f-browser-' + this._id + ' i', $.proxy(function () {
119
+ this.showMediaManager('file');
120
+ }, this));
121
+
122
+ this.$file_wrapper.find('#f-browser-' + this._id).show();
123
+
124
+ this.$file_wrapper.on('click', function (e) {
125
+ e.stopPropagation();
126
+ });
127
+
128
+ this.$file_wrapper.on('click', '*', function (e) {
129
+ e.stopPropagation();
130
+ });
131
+ };
132
+
133
+ $.Editable.initializers.push($.Editable.prototype.buildFileUpload);
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Override so the popup is never too bar below bottom of editor element
3
+ */
4
+ $.Editable.prototype.showByCoordinates = function (x, y) {
5
+
6
+ var editor_width = Math.max(this.$popup_editor.width(), 250),
7
+ bottom = this.$element.offset().top + this.$element.outerHeight();
8
+
9
+ y = Math.min(y, bottom);
10
+
11
+ x = x - 20;
12
+ y = y + 15;
13
+
14
+
15
+ if (x + editor_width >= $(window).width() - 50 && (x + 40) - editor_width > 0) {
16
+ this.$popup_editor.addClass('right-side');
17
+ x = $(window).width() - (x + 40);
18
+ this.$popup_editor.css('top', y);
19
+ this.$popup_editor.css('right', x);
20
+ this.$popup_editor.css('left', 'auto');
21
+ } else if (x + editor_width < $(window).width() - 50) {
22
+ this.$popup_editor.removeClass('right-side');
23
+ this.$popup_editor.css('top', y);
24
+ this.$popup_editor.css('left', x);
25
+ this.$popup_editor.css('right', 'auto');
26
+ } else {
27
+ this.$popup_editor.removeClass('right-side');
28
+ this.$popup_editor.css('top', y);
29
+ this.$popup_editor.css('left', Math.max(($(window).width() - editor_width), 10) / 2);
30
+ this.$popup_editor.css('right', 'auto');
31
+ }
32
+
33
+ this.$popup_editor.show();
34
+ };
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Init popup for image.
3
+ */
4
+ $.Editable.prototype.initImagePopup = function () {
5
+ this.$image_editor = $('<div class="froala-popup froala-image-editor-popup" style="display: none">');
6
+
7
+ var $buttons = $('<div class="f-popup-line f-popup-toolbar">').appendTo(this.$image_editor);
8
+ for (var i = 0; i < this.options.imageButtons.length; i++) {
9
+ var cmd = this.options.imageButtons[i];
10
+ if ($.Editable.image_commands[cmd] === undefined) {
11
+ continue;
12
+ }
13
+ var button = $.Editable.image_commands[cmd];
14
+
15
+ var btn = '<button class="fr-bttn" data-callback="' + cmd + '" data-cmd="' + cmd + '" title="' + button.title + '">';
16
+
17
+ if (this.options.icons[cmd] !== undefined) {
18
+ btn += this.prepareIcon(this.options.icons[cmd], button.title);
19
+ } else {
20
+ btn += this.prepareIcon(button.icon, button.title);
21
+ }
22
+
23
+ btn += '</button>';
24
+
25
+ $buttons.append(btn);
26
+ }
27
+
28
+ this.addListener('hidePopups', this.hideImageEditorPopup);
29
+
30
+ if (this.options.imageStyle) {
31
+ $('<div class="f-popup-line f-image-style">').appendTo(this.$image_editor);
32
+ $('<div class="f-popup-line f-image-custom-style">').hide().appendTo(this.$image_editor);
33
+ }
34
+
35
+ if (this.options.imageTitle) {
36
+ $('<div class="f-popup-line f-image-alt">')
37
+ .append('<label><span data-text="true">Title</span>: </label>')
38
+ .append($('<input type="text">').on('mouseup keydown', function (e) {
39
+ var keyCode = e.which;
40
+ if (!keyCode || keyCode !== 27) {
41
+ e.stopPropagation();
42
+ }
43
+ }))
44
+ .append('<button class="fr-p-bttn f-ok" data-text="true" data-callback="setImageAlt" data-cmd="setImageAlt" title="OK">OK</button>')
45
+ .appendTo(this.$image_editor);
46
+ }
47
+
48
+ this.$popup_editor.append(this.$image_editor);
49
+
50
+ this.bindCommandEvents(this.$image_editor);
51
+ };
52
+
53
+
54
+ /**
55
+ * Show image editor popup.
56
+ */
57
+ $.Editable.prototype.showImageEditorPopup = function () {
58
+ if (this.$image_editor) {
59
+ var _self = this;
60
+ setTimeout( function(){
61
+ _self.$image_editor.find('.f-image-style')
62
+ .html('<label><span data-text="true">Style</span>: </label>')
63
+ .append( $('<select />').append( _self.mediaStyleOptions() ).on('change', function(e) {
64
+ _self.setImageStyle();
65
+ }));
66
+
67
+ currentStyle = _self.currentMediaStyle();
68
+ $customRow = _self.$image_editor.find('.f-image-custom-style')
69
+ .html('<label><span data-text="true">Size</span>: </label>')
70
+ .append($('<input type="text" value="'+ ( $.inArray(currentStyle, _self.options.mediaStyles) === -1 ? currentStyle : '' ) +'">').on('mouseup keydown', function(e) {
71
+ var keyCode = e.which;
72
+ if (!keyCode || keyCode !== 27) {
73
+ e.stopPropagation();
74
+ }
75
+ }))
76
+ .append('<button class="fr-p-bttn f-ok" data-text="true" data-callback="setImageCustomStyle" data-cmd="setImageCustomStyle" title="OK">OK</button>');
77
+ $.inArray(currentStyle, _self.options.mediaStyles) === -1 ? $customRow.show() : $customRow.hide();
78
+ }, 0);
79
+ this.$image_editor.show();
80
+ }
81
+
82
+ if (!this.options.imageMove) {
83
+ this.$element.attr('contenteditable', false);
84
+ }
85
+ };
86
+
87
+
88
+ /**
89
+ * Media style options for select
90
+ */
91
+ $.Editable.prototype.mediaStyleOptions = function() {
92
+ var currentStyle = this.currentMediaStyle();
93
+
94
+ var options = $.map(this.options.mediaStyles, function(style) {
95
+ var label = style.charAt(0).toUpperCase() + style.substring(1).replace(/_/, ' ');
96
+ return '<option value="'+ style +'"'+ (style == currentStyle ? ' selected' : '') +'>'+ label + '</option>';
97
+ });
98
+ options.push('<option value="_custom"'+ ( $.inArray(currentStyle, this.options.mediaStyles) === -1 ? ' selected' : '' ) +'>Custom</option>');
99
+
100
+ return options.join();
101
+ }
102
+
103
+
104
+ /**
105
+ * Get the current media style
106
+ */
107
+ $.Editable.prototype.currentMediaStyle = function() {
108
+ var $image_editor = this.$element.find('span.f-img-editor');
109
+ var image_src = $image_editor.find('img').attr('src'),
110
+ mediaMatch = image_src != 'undefined' ? image_src.match(/\?.*style=(\w+[%0-9a-z!]*)/i) : false;
111
+
112
+ return mediaMatch ? decodeURIComponent(mediaMatch[1]) : 'original';
113
+ }
114
+
115
+
116
+ /**
117
+ * Set image styke.
118
+ */
119
+ $.Editable.prototype.setImageStyle = function () {
120
+ var $image_editor = this.$element.find('span.f-img-editor'),
121
+ style = this.$image_editor.find('.f-image-style select').val(),
122
+ image_src = $image_editor.find('img').attr('src').split('?')[0] + '?style=' + encodeURIComponent(style);
123
+
124
+ if (style == '_custom') {
125
+ this.$image_editor.find('.f-image-custom-style').slideDown();
126
+ } else {
127
+ this.$image_editor.find('.f-image-custom-style').slideUp();
128
+ $image_editor.find('img').attr('src', image_src).removeAttr('width').on('load', function(){
129
+ $(this).click();
130
+ });
131
+
132
+ this.triggerEvent('imageStyleSet');
133
+ }
134
+ };
135
+
136
+
137
+ /**
138
+ * Set image styke.
139
+ */
140
+ $.Editable.prototype.setImageCustomStyle = function () {
141
+ var $image_editor = this.$element.find('span.f-img-editor'),
142
+ style = this.$image_editor.find('.f-image-custom-style input').val(),
143
+ image_src = $image_editor.find('img').attr('src').split('?')[0] + '?style=' + encodeURIComponent(style);
144
+
145
+ $image_editor.find('img').attr('src', image_src).removeAttr('width');
146
+
147
+ this.hide();
148
+ this.closeImageMode();
149
+
150
+ this.triggerEvent('imageStyleSet');
151
+ };
152
+
153
+
154
+ /**
155
+ * Insert image command.
156
+ * Override so the image_link is manipulated to add default style
157
+ * an image title is grabbed from $media_images
158
+ * @param image_link
159
+ */
160
+ $.Editable.prototype.writeImage = function (image_link, sanitize) {
161
+ if (sanitize) {
162
+ image_link = this.sanitizeURL(image_link);
163
+ if (image_link === '') {
164
+ return false;
165
+ }
166
+ }
167
+
168
+ var image_data = this.$media_images.find('img[data-src="'+ image_link +'"]').data();
169
+ if ( typeof image_data != 'undefined' && 'title' in image_data ) {
170
+ image_title = image_data.title;
171
+ } else {
172
+ image_title = this.options.defaultImageTitle;
173
+ }
174
+
175
+ var img = new Image();
176
+ img.onerror = $.proxy(function () {
177
+ this.hideImageLoader();
178
+ this.throwImageError(1);
179
+ }, this);
180
+
181
+ if (this.imageMode) {
182
+ img.onload = $.proxy(function () {
183
+ var $img = this.$element.find('.f-img-editor > img');
184
+ $img.attr({
185
+ src: image_link,
186
+ alt: image_title
187
+ }).removeAttr('title');
188
+
189
+ this.hide();
190
+ this.hideImageLoader();
191
+ this.$image_editor.show();
192
+
193
+ this.enable();
194
+
195
+ // call with (image HTML)
196
+ this.triggerEvent('imageReplaced', [$img]);
197
+
198
+ setTimeout(function () {
199
+ $img.trigger('click');
200
+ }, 0);
201
+ }, this);
202
+ }
203
+
204
+ else {
205
+ img.onload = $.proxy(function () {
206
+ this.insertLoadedImage(image_link);
207
+ var $img = this.$element.find('.f-img-editor > img');
208
+ $img.attr('alt', image_title);
209
+ }, this);
210
+ }
211
+
212
+ this.showImageLoader(true);
213
+
214
+ img.src = image_link;
215
+ };
@@ -0,0 +1,184 @@
1
+ $.Editable.prototype.showMediaManager = function (kind) {
2
+ this.$image_modal.data('context', kind);
3
+ this.$image_modal.find('h4 span').text('Manage '+ kind +'s');
4
+ this.$image_modal.show();
5
+ this.$overlay.show();
6
+ this.loadImages();
7
+ $('body').css('overflow','hidden');
8
+ }
9
+
10
+ $.Editable.prototype.mediaModalHTML = function () {
11
+ var html = '<div class="froala-modal"><div class="f-modal-wrapper"><h4><span data-text="true">Manage images</span><i title="Cancel" class="fa fa-times" id="f-modal-close-' + this._id + '"></i></h4>'
12
+
13
+ html += '<img class="f-preloader" id="f-preloader-' + this._id + '" alt="Loading..." src="' + this.options.preloaderSrc + '" style="display: none;">';
14
+
15
+ if (WYSIWYGModernizr.touch) {
16
+ html += '<div class="f-image-list f-touch" id="f-image-list-' + this._id + '"></div>';
17
+ } else {
18
+ html += '<div class="f-image-list" id="f-image-list-' + this._id + '"></div>';
19
+ }
20
+
21
+ html += '<div class="pagination-centered" id="f-pagination-' + this._id + '"></div>';
22
+
23
+ html += '</div></div>';
24
+
25
+ return html;
26
+ }
27
+
28
+ $.Editable.prototype.buildMediaManager = function () {
29
+ this.$image_modal = $(this.mediaModalHTML()).appendTo('body');
30
+ this.$preloader = this.$image_modal.find('#f-preloader-' + this._id);
31
+ this.$media_images = this.$image_modal.find('#f-image-list-' + this._id);
32
+ this.$overlay = $('<div class="froala-overlay">').appendTo('body');
33
+
34
+ // Stop event propagation on overlay.
35
+ this.$overlay.on('mouseup', $.proxy(function (e) {
36
+ if (!this.isResizing()) {
37
+ e.stopPropagation();
38
+ }
39
+ }, this));
40
+
41
+
42
+ // Stop event propagation in modal.
43
+ this.$image_modal.on('mouseup', $.proxy(function (e) {
44
+ if (!this.isResizing()) {
45
+ e.stopPropagation();
46
+ }
47
+ }, this));
48
+
49
+ // Close button.
50
+ this.$image_modal.find('i#f-modal-close-' + this._id)
51
+ .click($.proxy(function () {
52
+ this.hideMediaManager();
53
+ }, this));
54
+
55
+ // Select image.
56
+ this.$media_images.on(this.mouseup, 'img', $.proxy(function (e) {
57
+ e.stopPropagation();
58
+ var img = e.currentTarget;
59
+ if ( $(img).data('kind') == 'image' ) {
60
+ this.writeImage($(img).data('src'));
61
+ } else {
62
+ this.writeFile($(img).data('src'), $(img).data('title'));
63
+ }
64
+ this.hideMediaManager();
65
+ }, this));
66
+
67
+ // Delete image.
68
+ this.$media_images.on(this.mouseup, '.f-delete-img', $.proxy(function (e) {
69
+ e.stopPropagation();
70
+ var img = $(e.currentTarget).prev();
71
+ var message = 'Are you sure? Image will be deleted.';
72
+ if ($.Editable.LANGS[this.options.language]) {
73
+ message = $.Editable.LANGS[this.options.language].translation[message];
74
+ }
75
+
76
+ // Ask for confirmation.
77
+ if (confirm(message)) {
78
+ if (this.triggerEvent('beforeDeleteImage', [$(img)], false) !== false) {
79
+ $(img).parent().addClass('f-img-deleting');
80
+ this.deleteImage($(img));
81
+ }
82
+ }
83
+ }, this));
84
+
85
+ // Add button for media manager to image.
86
+ if (this.options.mediaManager) {
87
+ this.$image_wrapper
88
+ .on('click', '#f-browser-' + this._id, $.proxy(function () {
89
+ this.showMediaManager('image');
90
+ }, this))
91
+ .on('click', '#f-browser-' + this._id + ' i', $.proxy(function () {
92
+ this.showMediaManager('image');
93
+ }, this));
94
+
95
+ this.$image_wrapper.find('#f-browser-' + this._id).show();
96
+ }
97
+
98
+ this.hideMediaManager();
99
+ };
100
+
101
+ $.Editable.prototype.initPagination = function(data) {
102
+ var mm = this;
103
+ this.$image_modal.find('#f-pagination-' + this._id).pagination({
104
+ pages: data.meta.total_pages,
105
+ currentPage: data.meta.current_page,
106
+ hrefTextPrefix: '#/media/page-',
107
+ onPageClick: function(page, e) {
108
+ e.preventDefault();
109
+ mm.loadImages(page);
110
+ }
111
+ });
112
+ }
113
+
114
+ // Load images from server.
115
+ $.Editable.prototype.loadImages = function (page) {
116
+ var isPaginated = (typeof page !== 'undefined');
117
+
118
+ this.$preloader.show();
119
+ this.$media_images.empty();
120
+
121
+ if (this.$image_modal.data('context') == 'file') {
122
+ ajax = {
123
+ url: this.options.filesLoadURL,
124
+ opts: this.options.filesLoadParams
125
+ }
126
+ } else {
127
+ ajax = {
128
+ url: this.options.imagesLoadURL,
129
+ opts: this.options.imagesLoadParams
130
+ }
131
+ }
132
+ if (isPaginated) {
133
+ ajax.opts.page = page;
134
+ }
135
+
136
+ if (ajax.url) {
137
+ $.support.cors = true;
138
+ $.getJSON(ajax.url, ajax.opts, $.proxy(function (data) {
139
+ // data
140
+ this.triggerEvent('imagesLoaded', [data], false);
141
+ this.processLoadedImages(data.assets);
142
+ if (!isPaginated && data.meta.total_pages > 1) {
143
+ this.initPagination(data);
144
+ }
145
+ this.$preloader.hide();
146
+ }, this))
147
+ .fail($.proxy(function () {
148
+ this.throwLoadImagesError(2);
149
+ }, this));
150
+ }
151
+ else {
152
+ this.throwLoadImagesError(3);
153
+ }
154
+ };
155
+
156
+ $.Editable.prototype.loadImage = function (src, info) {
157
+ var img = new Image();
158
+ var $li = $('<div>').addClass('f-empty');
159
+ img.onload = $.proxy(function () {
160
+ var delete_msg = 'Delete';
161
+ if ($.Editable.LANGS[this.options.language]) {
162
+ delete_msg = $.Editable.LANGS[this.options.language].translation[delete_msg];
163
+ }
164
+
165
+ var $img = $('<img src="' + src + '"/>');
166
+ for (var k in info) {
167
+ $img.attr('data-' + k, info[k]);
168
+ }
169
+
170
+ $li.append($img).append('<span class="f-media-title">'+ info.title +'</span>');
171
+ $li.removeClass('f-empty');
172
+ this.$media_images.hide();
173
+ this.$media_images.show();
174
+ this.triggerEvent('imageLoaded', [src], false);
175
+ }, this);
176
+
177
+ img.onerror = $.proxy(function () {
178
+ $li.remove();
179
+ this.throwLoadImagesError(1);
180
+ }, this)
181
+
182
+ img.src = src;
183
+ this.$media_images.append($li);
184
+ };
@@ -0,0 +1,5 @@
1
+ $.Editable.DEFAULTS = $.extend $.Editable.DEFAULTS,
2
+ defaultImageWidth: 0
3
+ imageStyle: true
4
+ mediaStyles: [ 'original', <%= PushType.config.media_styles.map { |style, _| "'#{ style }'" }.join(', ') %> ]
5
+ fileLink: true
@@ -0,0 +1,50 @@
1
+ # This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ # listed below.
3
+ #
4
+ # Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ # or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ #
7
+ # It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ # compiled file.
9
+ #
10
+ # Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ # about supported directives.
12
+ #
13
+ #= require froala_editor.min
14
+ #= require plugins/lists.min
15
+ #= require plugins/file_upload.min
16
+ #= require plugins/media_manager.min
17
+ #= require plugins/video.min
18
+ #= require jquery.simplePagination
19
+ #= require_self
20
+ #= require_tree .
21
+
22
+ # jQuery init
23
+ $(document).on 'ready page:load', ->
24
+
25
+ $('textarea.froala', '.wysiwyg').editable
26
+ inlineMode: false
27
+ buttons: ['bold', 'italic', 'underline', 'sep', 'formatBlock', 'align', 'insertOrderedList', 'insertUnorderedList', 'sep', 'createLink', 'insertImage', 'uploadFile', 'insertVideo', 'table', 'sep', 'removeFormat', 'undo', 'redo', 'sep' ,'html']
28
+ blockTags:
29
+ n: 'Normal'
30
+ h1: 'Heading 1'
31
+ h2: 'Heading 2'
32
+ height: 400
33
+ filesLoadURL: '/push_type/wysiwyg_media'
34
+ filesLoadParams: { filter: 'file' }
35
+ fileUploadURL: '/push_type/wysiwyg_media'
36
+ fileUploadParam: 'asset[file]'
37
+ imagesLoadURL: '/push_type/wysiwyg_media'
38
+ imagesLoadParams: { filter: 'image' }
39
+ imageUploadURL: '/push_type/wysiwyg_media'
40
+ imageUploadParam: 'asset[file]'
41
+ theme: 'pt'
42
+
43
+ $('textarea.froala', '.wysiwyg').on 'editable.focus', (e, editor) ->
44
+ editor.$box.addClass 'focus'
45
+
46
+ $('textarea.froala', '.wysiwyg').on 'editable.blur', (e, editor) ->
47
+ editor.$box.removeClass 'focus'
48
+
49
+ $('textarea.froala', '.wysiwyg').on 'editable.imageError', (e, editor, error) ->
50
+ alert error.message