push_type_wysiwyg 0.2.0.beta2

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 (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