bootsy_full_html 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +159 -0
  4. data/Rakefile +35 -0
  5. data/app/assets/images/bootsy/gallery-loader.gif +0 -0
  6. data/app/assets/images/bootsy/upload-loader.gif +0 -0
  7. data/app/assets/javascripts/bootsy.js +11 -0
  8. data/app/assets/javascripts/bootsy/area.js +89 -0
  9. data/app/assets/javascripts/bootsy/editor_options.js +47 -0
  10. data/app/assets/javascripts/bootsy/image_template.js +11 -0
  11. data/app/assets/javascripts/bootsy/init.js +38 -0
  12. data/app/assets/javascripts/bootsy/locales/en.js +54 -0
  13. data/app/assets/javascripts/bootsy/locales/pt-BR.js +54 -0
  14. data/app/assets/javascripts/bootsy/modal.js +192 -0
  15. data/app/assets/javascripts/bootsy/vendor/bootstrap-wysihtml5.js +530 -0
  16. data/app/assets/javascripts/bootsy/vendor/bootstrap.file-input.js +122 -0
  17. data/app/assets/javascripts/bootsy/vendor/polyfill.js +29 -0
  18. data/app/assets/javascripts/bootsy/vendor/wysihtml5.js +9565 -0
  19. data/app/assets/stylesheets/bootsy.css +337 -0
  20. data/app/controllers/bootsy/application_controller.rb +7 -0
  21. data/app/controllers/bootsy/images_controller.rb +96 -0
  22. data/app/helpers/bootsy/application_helper.rb +13 -0
  23. data/app/uploaders/bootsy/image_uploader.rb +39 -0
  24. data/app/views/bootsy/images/_image.html.erb +43 -0
  25. data/app/views/bootsy/images/_modal.html.erb +29 -0
  26. data/app/views/bootsy/images/_new.html.erb +17 -0
  27. data/config/locales/bootsy.en.yml +30 -0
  28. data/config/locales/bootsy.pt-BR.yml +30 -0
  29. data/config/routes.rb +11 -0
  30. data/db/migrate/20120624171333_create_bootsy_images.rb +9 -0
  31. data/db/migrate/20120628124845_create_bootsy_image_galleries.rb +8 -0
  32. data/lib/bootsy.rb +68 -0
  33. data/lib/bootsy/activerecord/image.rb +12 -0
  34. data/lib/bootsy/activerecord/image_gallery.rb +23 -0
  35. data/lib/bootsy/container.rb +52 -0
  36. data/lib/bootsy/core_ext.rb +4 -0
  37. data/lib/bootsy/engine.rb +34 -0
  38. data/lib/bootsy/form_builder.rb +18 -0
  39. data/lib/bootsy/form_helper.rb +114 -0
  40. data/lib/bootsy/simple_form/bootsy_input.rb +24 -0
  41. data/lib/bootsy/version.rb +4 -0
  42. data/lib/generators/bootsy/USAGE +12 -0
  43. data/lib/generators/bootsy/install_generator.rb +53 -0
  44. data/lib/generators/bootsy/templates/bootsy.rb +69 -0
  45. data/lib/tasks/bootsy_tasks.rake +4 -0
  46. metadata +130 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Brazilian portuguese translation for bootstrap-wysihtml5 and Bootsy
3
+ */
4
+ (function($){
5
+ $.fn.wysihtml5.locale['pt-BR'] = {
6
+ font_styles: {
7
+ normal: 'Texto normal',
8
+ h1: 'Título 1',
9
+ h2: 'Título 2',
10
+ h3: 'Título 3'
11
+ },
12
+ emphasis: {
13
+ bold: 'Negrito',
14
+ italic: 'Itálico',
15
+ underline: 'Sublinhado',
16
+ small: 'Pequeno'
17
+ },
18
+ lists: {
19
+ unordered: 'Lista',
20
+ ordered: 'Lista numerada',
21
+ outdent: 'Remover indentação',
22
+ indent: 'Indentar'
23
+ },
24
+ link: {
25
+ insert: 'Inserir link',
26
+ cancel: 'Cancelar',
27
+ target: 'Abrir link em um nova janela'
28
+ },
29
+ image: {
30
+ insert: 'Inserir imagem',
31
+ cancel: 'Cancelar'
32
+ },
33
+ html: {
34
+ edit: 'Editar HTML'
35
+ },
36
+ colours: {
37
+ black: 'Preto',
38
+ silver: 'Prata',
39
+ gray: 'Cinza',
40
+ maroon: 'Marrom',
41
+ red: 'Vermelho',
42
+ purple: 'Roxo',
43
+ green: 'Verde',
44
+ olive: 'Oliva',
45
+ navy: 'Marinho',
46
+ blue: 'Azul',
47
+ orange: 'Laranja'
48
+ },
49
+ bootsy: {
50
+ alertUnsaved: 'As suas modificações ainda não foram gravadas.',
51
+ error: 'Algo deu errado. Por favor, tente novamente.'
52
+ }
53
+ };
54
+ }(jQuery));
@@ -0,0 +1,192 @@
1
+ /* Bootsy modal */
2
+
3
+ window.Bootsy = window.Bootsy || {};
4
+
5
+ Bootsy.Modal = function(area) {
6
+ var self = this;
7
+
8
+ this.$el = area.$el.siblings('.bootsy-modal');
9
+ this.area = area;
10
+
11
+ // In order to avoid form nesting
12
+ this.$el.parents('form').after(this.$el);
13
+
14
+ this.$el.on('click', '.bootsy-image .insert', function(event) {
15
+ var img, imageObject;
16
+ var imagePrefix = '/' + $(this).attr('data-image-size') + '_';
17
+
18
+ event.preventDefault();
19
+
20
+ if ($(this).data('image-size') === 'original') {
21
+ imagePrefix = '/';
22
+ }
23
+
24
+ img = $(this).parents('.bootsy-image').find('img');
25
+
26
+ imageObject = {
27
+ src: img.attr('src').replace('/thumb_', imagePrefix),
28
+ alt: img.attr('alt').replace('Thumb_', '')
29
+ };
30
+
31
+ imageObject.align = $(this).data('position');
32
+
33
+ self.$el.modal('hide');
34
+
35
+ insert = self.area.insertImage.bind(self.area);
36
+ insert(imageObject);
37
+ });
38
+
39
+ this.$el.on('ajax:before', '.destroy-btn', this.showGalleryLoadingAnimation.bind(this));
40
+
41
+ this.$el.on('ajax:success', '.destroy-btn', function(_e, data) {
42
+ this.deleteImage(data.id);
43
+ }.bind(this));
44
+
45
+ this.$el.on('ajax:error', '.bootsy-upload-form', this.imageUploadFailed.bind(this));
46
+
47
+ this.$el.on('click', 'a[href="#refresh-gallery"]', this.requestImageGallery.bind(this));
48
+
49
+ this.$el.on('ajax:success', '.bootsy-upload-form', function(_e, data) {
50
+ this.area.setImageGalleryId(data.gallery_id);
51
+ this.addImage(data.image);
52
+ this.setUploadForm(data.form);
53
+ }.bind(this));
54
+
55
+ this.$el.modal({ show: false });
56
+
57
+ this.$el.on('shown.bs.modal', function() {
58
+ if (this.$el.data('gallery-loaded') !== true) {
59
+ this.requestImageGallery();
60
+ }
61
+ }.bind(this));
62
+
63
+ this.hideRefreshButton();
64
+ this.hideEmptyAlert();
65
+ };
66
+
67
+ // Show modal
68
+ Bootsy.Modal.prototype.show = function() {
69
+ this.$el.modal('show');
70
+ };
71
+
72
+ // Gallery loading
73
+ Bootsy.Modal.prototype.showGalleryLoadingAnimation = function() {
74
+ this.$el.find('.bootsy-gallery-loader').fadeIn(200);
75
+ };
76
+
77
+ Bootsy.Modal.prototype.hideGalleryLoadingAnimation = function() {
78
+ this.$el.find('.bootsy-gallery-loader').fadeOut(200);
79
+ };
80
+
81
+ // Upload loading animation
82
+ Bootsy.Modal.prototype.showUploadLoadingAnimation = function() {
83
+ this.$el.find('.bootsy-upload-loader').fadeIn(200);
84
+ };
85
+
86
+ Bootsy.Modal.prototype.hideUploadLoadingAnimation = function() {
87
+ this.$el.find('.bootsy-upload-loader').fadeOut(200);
88
+ };
89
+
90
+ // Alert for empty gallery
91
+ Bootsy.Modal.prototype.showEmptyAlert = function() {
92
+ this.$el.find('.bootsy-empty-alert').fadeIn(200);
93
+ };
94
+
95
+ Bootsy.Modal.prototype.hideEmptyAlert = function() {
96
+ this.$el.find('.bootsy-empty-alert').fadeOut(200);
97
+ };
98
+
99
+ // Manual refresh button
100
+ Bootsy.Modal.prototype.showRefreshButton = function() {
101
+ this.$el.find('.refresh-btn').fadeIn(200);
102
+ };
103
+
104
+ Bootsy.Modal.prototype.hideRefreshButton = function() {
105
+ this.$el.find('.refresh-btn').fadeOut(200);
106
+ };
107
+
108
+ // Set upload form
109
+ Bootsy.Modal.prototype.setUploadForm = function(html) {
110
+ var uploadInput;
111
+
112
+ this.$el.find('.modal-footer').html(html);
113
+ this.hideUploadLoadingAnimation();
114
+ this.$el.find('.bootsy-upload-form input[type="file"]').bootstrapFileInput();
115
+
116
+ uploadInput = this.$el.find('.bootsy-upload-form input[type="file"]');
117
+
118
+ uploadInput.change(function() {
119
+ this.showUploadLoadingAnimation();
120
+ uploadInput.closest('form').submit();
121
+ }.bind(this));
122
+ };
123
+
124
+ // The image upload failed
125
+ Bootsy.Modal.prototype.imageUploadFailed = function(_e, xhr, _status, error) {
126
+ var invalidErrors = xhr.responseJSON;
127
+
128
+ if (Number(xhr.status) === 422 && invalidErrors.image_file) {
129
+ this.hideUploadLoadingAnimation();
130
+
131
+ if (this.validation) this.validation.remove();
132
+
133
+ this.validation = $("<p class='text-danger'>");
134
+ this.validation.text(invalidErrors.image_file[0]);
135
+ this.$el.find('.bootsy-upload-form').append(this.validation);
136
+ } else {
137
+ alert($.fn.wysihtml5.locale[this.area.locale].bootsy.error);
138
+ }
139
+
140
+ this.showRefreshButton();
141
+ };
142
+
143
+ // Add image to gallery
144
+ Bootsy.Modal.prototype.addImage = function(html) {
145
+ this.hideEmptyAlert();
146
+
147
+ $(html).hide().appendTo(this.$el.find('.bootsy-gallery')).fadeIn(200);
148
+ };
149
+
150
+ // Set image gallery
151
+ Bootsy.Modal.prototype.requestImageGallery = function() {
152
+ this.showGalleryLoadingAnimation();
153
+
154
+ $.ajax({
155
+ url: '/bootsy/images',
156
+ type: 'GET',
157
+ cache: false,
158
+ data: {
159
+ image_gallery_id: this.area.$el.data('gallery-id')
160
+ },
161
+ dataType: 'json',
162
+ success: function(data) {
163
+ this.hideRefreshButton();
164
+ this.hideGalleryLoadingAnimation();
165
+ this.$el.find('.bootsy-gallery .bootsy-image').remove();
166
+
167
+ $.each(data.images, function(index, value) {
168
+ this.addImage(value);
169
+ }.bind(this));
170
+
171
+ if (data.images.length === 0) this.showEmptyAlert();
172
+
173
+ this.setUploadForm(data.form);
174
+
175
+ this.$el.data('gallery-loaded', true);
176
+ }.bind(this),
177
+ error: this.imageUploadFailed.bind(this)
178
+ });
179
+ };
180
+
181
+ // Delete image
182
+ Bootsy.Modal.prototype.deleteImage = function(id) {
183
+ var image = this.$el.find('.bootsy-image[data-id="' + id + '"]');
184
+
185
+ this.hideGalleryLoadingAnimation();
186
+
187
+ image.hide(200, function() {
188
+ image.remove();
189
+
190
+ if (this.$el.find('.bootsy-image').length === 0 ) this.showEmptyAlert();
191
+ }.bind(this));
192
+ };
@@ -0,0 +1,530 @@
1
+ !function($, wysi) {
2
+ "use strict";
3
+
4
+ var tpl = {
5
+ "font-styles": function(locale, options) {
6
+ var size = (options && options.size) ? ' btn-'+options.size : '';
7
+ return "<li class='dropdown'>" +
8
+ "<a class='btn btn-default dropdown-toggle" + size + "' data-toggle='dropdown' href='#' title='" + locale.font_styles.title + "'>" +
9
+ "<i class='glyphicon glyphicon-font'></i>&nbsp;<span class='current-font'>" + locale.font_styles.normal + "</span>&nbsp;<b class='caret'></b>" +
10
+ "</a>" +
11
+ "<ul class='dropdown-menu'>" +
12
+ "<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='div' tabindex='-1' role='menuitem'>" + locale.font_styles.normal + "</a></li>" +
13
+ "<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h1' tabindex='-1' role='menuitem'>" + locale.font_styles.h1 + "</a></li>" +
14
+ "<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h2' tabindex='-1' role='menuitem'>" + locale.font_styles.h2 + "</a></li>" +
15
+ "<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h3' tabindex='-1' role='menuitem'>" + locale.font_styles.h3 + "</a></li>" +
16
+ "</ul>" +
17
+ "</li>";
18
+ },
19
+
20
+ "emphasis": function(locale, options) {
21
+ var size = (options && options.size) ? ' btn-'+options.size : '';
22
+ return "<li>" +
23
+ "<div class='btn-group'>" +
24
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='bold' title='CTRL+B' tabindex='-1'>" + locale.emphasis.bold + "</a>" +
25
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='italic' title='CTRL+I' tabindex='-1'>" + locale.emphasis.italic + "</a>" +
26
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='underline' title='CTRL+U' tabindex='-1'>" + locale.emphasis.underline + "</a>" +
27
+ "</div>" +
28
+ "</li>";
29
+ },
30
+
31
+ "lists": function(locale, options) {
32
+ var size = (options && options.size) ? ' btn-'+options.size : '';
33
+ return "<li>" +
34
+ "<div class='btn-group'>" +
35
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='insertUnorderedList' title='" + locale.lists.unordered + "' tabindex='-1'><i class='glyphicon glyphicon-list'></i></a>" +
36
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='insertOrderedList' title='" + locale.lists.ordered + "' tabindex='-1'><i class='glyphicon glyphicon-th-list'></i></a>" +
37
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='Outdent' title='" + locale.lists.outdent + "' tabindex='-1'><i class='glyphicon glyphicon-indent-left'></i></a>" +
38
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='Indent' title='" + locale.lists.indent + "' tabindex='-1'><i class='glyphicon glyphicon-indent-right'></i></a>" +
39
+ "</div>" +
40
+ "</li>";
41
+ },
42
+
43
+ "link": function(locale, options) {
44
+ var size = (options && options.size) ? ' btn-'+options.size : '';
45
+ return "<li>" +
46
+ "<div class='bootstrap-wysihtml5-insert-link-modal modal fade' tabindex='-1' role='dialog' aria-hidden='true'>" +
47
+ "<div class='modal-dialog'>" +
48
+ "<div class='modal-content'>" +
49
+ "<div class='modal-header'>" +
50
+ "<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>" +
51
+ "<h3 class='modal-title'>" + locale.link.insert + "</h3>" +
52
+ "</div>" +
53
+ "<div class='modal-body'>" +
54
+ "<input value='http://' class='bootstrap-wysihtml5-insert-link-url form-control input-lg'>" +
55
+ "</div>" +
56
+ "<div class='modal-footer'>" +
57
+ "<a href='#' class='btn btn-default' data-dismiss='modal'>" + locale.link.cancel + "</a>" +
58
+ "<a href='#' class='btn btn-primary' data-dismiss='modal'>" + locale.link.insert + "</a>" +
59
+ "</div>" +
60
+ "</div>" +
61
+ "</div>" +
62
+ "</div>" +
63
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='createLink' title='" + locale.link.insert + "' tabindex='-1'><i class='glyphicon glyphicon-share'></i></a>" +
64
+ "</li>";
65
+ },
66
+
67
+ "image": function(locale, options) {
68
+ var size = (options && options.size) ? ' btn-'+options.size : '';
69
+ return "<li>" +
70
+ "<div class='bootstrap-wysihtml5-insert-image-modal modal fade' tabindex='-1' role='dialog' aria-hidden='true'>" +
71
+ "<div class='modal-dialog'>" +
72
+ "<div class='modal-content'>" +
73
+ "<div class='modal-header'>" +
74
+ "<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>" +
75
+ "<h3 class='modal-title'>" + locale.image.insert + "</h3>" +
76
+ "</div>" +
77
+ "<div class='modal-body'>" +
78
+ "<input value='http://' class='bootstrap-wysihtml5-insert-image-url form-control input-lg'>" +
79
+ "</div>" +
80
+ "<div class='modal-footer'>" +
81
+ "<a href='#' class='btn btn-default ' data-dismiss='modal'>" + locale.image.cancel + "</a>" +
82
+ "<a href='#' class='btn btn-primary' data-dismiss='modal'>" + locale.image.insert + "</a>" +
83
+ "</div>" +
84
+ "</div>" +
85
+ "</div>" +
86
+ "</div>" +
87
+ "<a class='btn btn-default " + size + "' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><i class='glyphicon glyphicon-picture'></i></a>" +
88
+ "</li>";
89
+ },
90
+
91
+ "html": function(locale, options) {
92
+ var size = (options && options.size) ? ' btn-'+options.size : '';
93
+ return "<li>" +
94
+ "<div class='btn-group'>" +
95
+ "<a class='btn btn-default " + size + "' data-wysihtml5-action='change_view' title='" + locale.html.edit + "' tabindex='-1'><i class='glyphicon glyphicon-pencil'></i></a>" +
96
+ "</div>" +
97
+ "</li>";
98
+ },
99
+
100
+ "color": function(locale, options) {
101
+ var size = (options && options.size) ? ' btn-'+options.size : '';
102
+ return "<li class='dropdown'>" +
103
+ "<a class='btn btn-default dropdown-toggle" + size + "' data-toggle='dropdown' href='#' tabindex='-1' title='" + locale.colours.title + "'>" +
104
+ "<span class='current-color'>" + locale.colours.black + "</span>&nbsp;<b class='caret'></b>" +
105
+ "</a>" +
106
+ "<ul class='dropdown-menu'>" +
107
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='black'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='black' role='menuitem'>" + locale.colours.black + "</a></li>" +
108
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='silver'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='silver' role='menuitem'>" + locale.colours.silver + "</a></li>" +
109
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='gray'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='gray' role='menuitem'>" + locale.colours.gray + "</a></li>" +
110
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='maroon'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='maroon' role='menuitem'>" + locale.colours.maroon + "</a></li>" +
111
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='red'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='red' role='menuitem'>" + locale.colours.red + "</a></li>" +
112
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='purple'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='purple' role='menuitem'>" + locale.colours.purple + "</a></li>" +
113
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='green'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='green' role='menuitem'>" + locale.colours.green + "</a></li>" +
114
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='olive'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='olive' role='menuitem'>" + locale.colours.olive + "</a></li>" +
115
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='navy'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='navy' role='menuitem'>" + locale.colours.navy + "</a></li>" +
116
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='blue'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='blue' role='menuitem'>" + locale.colours.blue + "</a></li>" +
117
+ "<li><div class='wysihtml5-colors' data-wysihtml5-command-value='orange'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='orange' role='menuitem'>" + locale.colours.orange + "</a></li>" +
118
+ "</ul>" +
119
+ "</li>";
120
+ }
121
+ };
122
+
123
+ var templates = function(key, locale, options) {
124
+ return tpl[key](locale, options);
125
+ };
126
+
127
+
128
+ var Wysihtml5 = function(el, options) {
129
+ this.el = el;
130
+ var toolbarOpts = options || defaultOptions;
131
+ for(var t in toolbarOpts.customTemplates) {
132
+ tpl[t] = toolbarOpts.customTemplates[t];
133
+ }
134
+ this.toolbar = this.createToolbar(el, toolbarOpts);
135
+ this.editor = this.createEditor(options);
136
+
137
+ window.editor = this.editor;
138
+
139
+ $('iframe.wysihtml5-sandbox').each(function(i, el){
140
+ $(el.contentWindow).off('focus.wysihtml5').on({
141
+ 'focus.wysihtml5' : function(){
142
+ $('li.dropdown').removeClass('open');
143
+ }
144
+ });
145
+ });
146
+ };
147
+
148
+ Wysihtml5.prototype = {
149
+
150
+ constructor: Wysihtml5,
151
+
152
+ createEditor: function(options) {
153
+ options = options || {};
154
+
155
+ // Add the toolbar to a clone of the options object so multiple instances
156
+ // of the WYISYWG don't break because "toolbar" is already defined
157
+ options = $.extend(true, {}, options);
158
+ options.toolbar = this.toolbar[0];
159
+
160
+ var editor = new wysi.Editor(this.el[0], options);
161
+
162
+ if(options && options.events) {
163
+ for(var eventName in options.events) {
164
+ editor.on(eventName, options.events[eventName]);
165
+ }
166
+ }
167
+ return editor;
168
+ },
169
+
170
+ createToolbar: function(el, options) {
171
+ var self = this;
172
+ var toolbar = $("<ul/>", {
173
+ 'class' : "wysihtml5-toolbar",
174
+ 'style': "display:none"
175
+ });
176
+ var culture = options.locale || defaultOptions.locale || "en";
177
+ for(var key in defaultOptions) {
178
+ var value = false;
179
+
180
+ if(options[key] !== undefined) {
181
+ if(options[key] === true) {
182
+ value = true;
183
+ }
184
+ } else {
185
+ value = defaultOptions[key];
186
+ }
187
+
188
+ if(value === true) {
189
+ toolbar.append(templates(key, locale[culture], options));
190
+
191
+ if(key === "html") {
192
+ this.initHtml(toolbar);
193
+ }
194
+
195
+ if(key === "link") {
196
+ this.initInsertLink(toolbar);
197
+ }
198
+
199
+ if(key === "image") {
200
+ this.initInsertImage(toolbar);
201
+ }
202
+
203
+ if(key == "customCommand") {
204
+ this.initCustomCommand(toolbar, options.customCommandCallback);
205
+ }
206
+ }
207
+ }
208
+
209
+ if(options.toolbar) {
210
+ for(key in options.toolbar) {
211
+ toolbar.append(options.toolbar[key]);
212
+ }
213
+ }
214
+
215
+ toolbar.find("a[data-wysihtml5-command='formatBlock']").click(function(e) {
216
+ var target = e.target || e.srcElement;
217
+ var el = $(target);
218
+ self.toolbar.find('.current-font').text(el.html());
219
+ });
220
+
221
+ toolbar.find("a[data-wysihtml5-command='foreColor']").click(function(e) {
222
+ var target = e.target || e.srcElement;
223
+ var el = $(target);
224
+ self.toolbar.find('.current-color').text(el.html());
225
+ });
226
+
227
+ this.el.before(toolbar);
228
+
229
+ return toolbar;
230
+ },
231
+
232
+ initHtml: function(toolbar) {
233
+ var changeViewSelector = "a[data-wysihtml5-action='change_view']";
234
+ toolbar.find(changeViewSelector).click(function(e) {
235
+ toolbar.find('a.btn').not(changeViewSelector).toggleClass('disabled');
236
+ });
237
+ },
238
+
239
+ initInsertImage: function(toolbar) {
240
+ var self = this;
241
+ var insertImageModal = toolbar.find('.bootstrap-wysihtml5-insert-image-modal');
242
+ var urlInput = insertImageModal.find('.bootstrap-wysihtml5-insert-image-url');
243
+ var insertButton = insertImageModal.find('a.btn-primary');
244
+ var initialValue = urlInput.val();
245
+ var caretBookmark;
246
+
247
+ var insertImage = function() {
248
+ var url = urlInput.val();
249
+ urlInput.val(initialValue);
250
+ self.editor.currentView.element.focus();
251
+ if (caretBookmark) {
252
+ self.editor.composer.selection.setBookmark(caretBookmark);
253
+ caretBookmark = null;
254
+ }
255
+ self.editor.composer.commands.exec("insertImage", url);
256
+ };
257
+
258
+ urlInput.keypress(function(e) {
259
+ if(e.which == 13) {
260
+ insertImage();
261
+ insertImageModal.modal('hide');
262
+ }
263
+ });
264
+
265
+ insertButton.click(insertImage);
266
+
267
+ insertImageModal.on('shown', function() {
268
+ urlInput.focus();
269
+ });
270
+
271
+ insertImageModal.on('hide', function() {
272
+ self.editor.currentView.element.focus();
273
+ });
274
+
275
+ toolbar.find('a[data-wysihtml5-command=insertImage]').click(function() {
276
+ var activeButton = $(this).hasClass("wysihtml5-command-active");
277
+
278
+ if (!activeButton) {
279
+ self.editor.currentView.element.focus(false);
280
+ caretBookmark = self.editor.composer.selection.getBookmark();
281
+ insertImageModal.appendTo('body').modal('show');
282
+ insertImageModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) {
283
+ e.stopPropagation();
284
+ });
285
+ return false;
286
+ }
287
+ else {
288
+ return true;
289
+ }
290
+ });
291
+ },
292
+
293
+ initCustomCommand: function(toolbar, callback) {
294
+ var self = this;
295
+
296
+ toolbar.find('a[data-wysihtml5-command=customCommand]').click(function() {
297
+ var activeButton = $(this).hasClass("wysihtml5-command-active");
298
+
299
+ if (!activeButton) {
300
+ callback(self.editor);
301
+ return false;
302
+ }
303
+ else {
304
+ return true;
305
+ }
306
+ });
307
+ },
308
+
309
+ initInsertLink: function(toolbar) {
310
+ var self = this;
311
+ var insertLinkModal = toolbar.find('.bootstrap-wysihtml5-insert-link-modal');
312
+ var urlInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-url');
313
+ var insertButton = insertLinkModal.find('a.btn-primary');
314
+ var initialValue = urlInput.val();
315
+ var caretBookmark;
316
+
317
+ var insertLink = function() {
318
+ var url = urlInput.val();
319
+ urlInput.val(initialValue);
320
+ self.editor.currentView.element.focus();
321
+ if (caretBookmark) {
322
+ self.editor.composer.selection.setBookmark(caretBookmark);
323
+ caretBookmark = null;
324
+ }
325
+ self.editor.composer.commands.exec("createLink", {
326
+ href: url,
327
+ target: "_blank",
328
+ rel: "nofollow"
329
+ });
330
+ };
331
+ var pressedEnter = false;
332
+
333
+ urlInput.keypress(function(e) {
334
+ if(e.which == 13) {
335
+ insertLink();
336
+ insertLinkModal.modal('hide');
337
+ }
338
+ });
339
+
340
+ insertButton.click(insertLink);
341
+
342
+ insertLinkModal.on('shown', function() {
343
+ urlInput.focus();
344
+ });
345
+
346
+ insertLinkModal.on('hide', function() {
347
+ self.editor.currentView.element.focus();
348
+ });
349
+
350
+ toolbar.find('a[data-wysihtml5-command=createLink]').click(function() {
351
+ var activeButton = $(this).hasClass("wysihtml5-command-active");
352
+
353
+ if (!activeButton) {
354
+ self.editor.currentView.element.focus(false);
355
+ caretBookmark = self.editor.composer.selection.getBookmark();
356
+ insertLinkModal.appendTo('body').modal('show');
357
+ insertLinkModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) {
358
+ e.stopPropagation();
359
+ });
360
+ return false;
361
+ }
362
+ else {
363
+ return true;
364
+ }
365
+ });
366
+ }
367
+ };
368
+
369
+ // these define our public api
370
+ var methods = {
371
+ resetDefaults: function() {
372
+ $.fn.wysihtml5.defaultOptions = $.extend(true, {}, $.fn.wysihtml5.defaultOptionsCache);
373
+ },
374
+ bypassDefaults: function(options) {
375
+ return this.each(function () {
376
+ var $this = $(this);
377
+ $this.data('wysihtml5', new Wysihtml5($this, options));
378
+ });
379
+ },
380
+ shallowExtend: function (options) {
381
+ var settings = $.extend({}, $.fn.wysihtml5.defaultOptions, options || {});
382
+ var that = this;
383
+ return methods.bypassDefaults.apply(that, [settings]);
384
+ },
385
+ deepExtend: function(options) {
386
+ var settings = $.extend(true, {}, $.fn.wysihtml5.defaultOptions, options || {});
387
+ var that = this;
388
+ return methods.bypassDefaults.apply(that, [settings]);
389
+ },
390
+ init: function(options) {
391
+ var that = this;
392
+ return methods.shallowExtend.apply(that, [options]);
393
+ }
394
+ };
395
+
396
+ $.fn.wysihtml5 = function ( method ) {
397
+ if ( methods[method] ) {
398
+ return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
399
+ } else if ( typeof method === 'object' || ! method ) {
400
+ return methods.init.apply( this, arguments );
401
+ } else {
402
+ $.error( 'Method ' + method + ' does not exist on jQuery.wysihtml5' );
403
+ }
404
+ };
405
+
406
+ $.fn.wysihtml5.Constructor = Wysihtml5;
407
+
408
+ var defaultOptions = $.fn.wysihtml5.defaultOptions = {
409
+ "font-styles": true,
410
+ "color": false,
411
+ "emphasis": true,
412
+ "lists": true,
413
+ "html": false,
414
+ "link": true,
415
+ "image": true,
416
+ customCommand: false,
417
+ events: {},
418
+ parserRules: {
419
+ classes: {
420
+ // (path_to_project/lib/css/wysiwyg-color.css)
421
+ "wysiwyg-color-silver" : 0,
422
+ "wysiwyg-color-gray" : 0,
423
+ "wysiwyg-color-white" : 0,
424
+ "wysiwyg-color-maroon" : 0,
425
+ "wysiwyg-color-red" : 0,
426
+ "wysiwyg-color-purple" : 0,
427
+ "wysiwyg-color-fuchsia" : 0,
428
+ "wysiwyg-color-green" : 0,
429
+ "wysiwyg-color-lime" : 0,
430
+ "wysiwyg-color-olive" : 0,
431
+ "wysiwyg-color-yellow" : 0,
432
+ "wysiwyg-color-navy" : 0,
433
+ "wysiwyg-color-blue" : 0,
434
+ "wysiwyg-color-teal" : 0,
435
+ "wysiwyg-color-aqua" : 0,
436
+ "wysiwyg-color-orange" : 0
437
+ },
438
+ tags: {
439
+ "b": {},
440
+ "i": {},
441
+ "br": {},
442
+ "ol": {},
443
+ "ul": {},
444
+ "li": {},
445
+ "h1": {},
446
+ "h2": {},
447
+ "h3": {},
448
+ "blockquote": {},
449
+ "u": 1,
450
+ "img": {
451
+ "check_attributes": {
452
+ "width": "numbers",
453
+ "alt": "alt",
454
+ "src": "url",
455
+ "height": "numbers"
456
+ }
457
+ },
458
+ "a": {
459
+ set_attributes: {
460
+ target: "_blank",
461
+ rel: "nofollow"
462
+ },
463
+ check_attributes: {
464
+ href: "url" // important to avoid XSS
465
+ }
466
+ },
467
+ "span": 0,
468
+ "div": 0,
469
+ // to allow save and edit files with code tag hacks
470
+ "code": 0,
471
+ "pre": 0
472
+ }
473
+ },
474
+ stylesheets: ["./lib/css/wysiwyg-color.css"], // (path_to_project/lib/css/wysiwyg-color.css)
475
+ locale: "en"
476
+ };
477
+
478
+ if (typeof $.fn.wysihtml5.defaultOptionsCache === 'undefined') {
479
+ $.fn.wysihtml5.defaultOptionsCache = $.extend(true, {}, $.fn.wysihtml5.defaultOptions);
480
+ }
481
+
482
+ var locale = $.fn.wysihtml5.locale = {
483
+ en: {
484
+ font_styles: {
485
+ title: "Font style",
486
+ normal: "Normal text",
487
+ h1: "Heading 1",
488
+ h2: "Heading 2",
489
+ h3: "Heading 3"
490
+ },
491
+ emphasis: {
492
+ bold: "Bold",
493
+ italic: "Italic",
494
+ underline: "Underline"
495
+ },
496
+ lists: {
497
+ unordered: "Unordered list",
498
+ ordered: "Ordered list",
499
+ outdent: "Outdent",
500
+ indent: "Indent"
501
+ },
502
+ link: {
503
+ insert: "Insert link",
504
+ cancel: "Cancel"
505
+ },
506
+ image: {
507
+ insert: "Insert image",
508
+ cancel: "Cancel"
509
+ },
510
+ html: {
511
+ edit: "Edit HTML"
512
+ },
513
+ colours: {
514
+ title: "Text color",
515
+ black: "Black",
516
+ silver: "Silver",
517
+ gray: "Grey",
518
+ maroon: "Maroon",
519
+ red: "Red",
520
+ purple: "Purple",
521
+ green: "Green",
522
+ olive: "Olive",
523
+ navy: "Navy",
524
+ blue: "Blue",
525
+ orange: "Orange"
526
+ }
527
+ }
528
+ };
529
+
530
+ }(window.jQuery, window.wysihtml5);