bootsy 1.2.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/README.md +38 -14
- data/app/assets/images/bootsy/gallery-loader.gif +0 -0
- data/app/assets/images/bootsy/{ajax-loader.gif → upload-loader.gif} +0 -0
- data/app/assets/javascripts/bootsy/bootstrap-wysihtml5.js +59 -51
- data/app/assets/javascripts/bootsy/bootstrap.file-input.js +1 -1
- data/app/assets/javascripts/bootsy/bootsy.js +242 -185
- data/app/assets/javascripts/bootsy/editor_options.js +4 -4
- data/app/assets/javascripts/bootsy/init.js +4 -1
- data/app/assets/javascripts/bootsy/locales/bootsy.pt-BR.js +3 -2
- data/app/assets/javascripts/bootsy/translations.js +1 -1
- data/app/assets/stylesheets/bootsy/bootstrap-submenu.css +47 -0
- data/app/assets/stylesheets/bootsy/bootsy.css +20 -31
- data/app/controllers/bootsy/images_controller.rb +23 -9
- data/app/helpers/bootsy/application_helper.rb +1 -1
- data/app/views/bootsy/images/_image.html.erb +43 -0
- data/app/views/bootsy/images/_modal.html.erb +25 -10
- data/app/views/bootsy/images/_new.html.erb +4 -12
- data/lib/bootsy.rb +9 -1
- data/lib/bootsy/form_helper.rb +10 -10
- data/lib/bootsy/version.rb +1 -1
- metadata +13 -14
- data/app/views/bootsy/images/_index.html.erb +0 -48
- data/app/views/bootsy/images/create.js.erb +0 -2
- data/app/views/bootsy/images/destroy.js.erb +0 -1
- data/config/bootsy.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b7b61a6335378da2590cdd884b0f7b5b7aa5840
|
4
|
+
data.tar.gz: c1f5549e531f7e423576602a0f611fb0ff96bb26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e9ff624b3d22b75b597c461b0161cbfc6346448a0e04dd2f21dc7c9b5ebb10c813ae780d8c00e2c477134c4b7cbbfe1736bad339991bc4e91db0df578ab3ecc
|
7
|
+
data.tar.gz: 02ac8fd962645345fac9236095a6ba41a64029706b13e467e1978318f0401356bb254100c56f78b3fbd9de2e0aaf636d15e6a2b3e8f907e2dac297fb8495c390
|
data/README.md
CHANGED
@@ -8,13 +8,15 @@
|
|
8
8
|
|
9
9
|
*Bootsy* is a WYSIWYG solution for Rails based on [Bootstrap-wysihtml5](https://github.com/jhollingworth/bootstrap-wysihtml5) which includes image uploads via [CarrierWave](https://github.com/carrierwaveuploader/carrierwave).
|
10
10
|
|
11
|
+

|
12
|
+
|
11
13
|
|
12
14
|
## Requirements
|
13
15
|
|
14
16
|
* Ruby `2.0` or `1.9.3`;
|
15
17
|
* ImageMagick or GraphicsMagick (for MiniMagick);
|
16
|
-
* Rails `4.0
|
17
|
-
* [
|
18
|
+
* Rails `4.0`;
|
19
|
+
* [Bootstrap `3`](http://getbootstrap.com/) properly added to your application.
|
18
20
|
|
19
21
|
|
20
22
|
## Installation
|
@@ -31,8 +33,10 @@ bundle install
|
|
31
33
|
|
32
34
|
3. Run the install generator:
|
33
35
|
```console
|
34
|
-
rails
|
36
|
+
rails generate bootsy:install
|
35
37
|
```
|
38
|
+
It will include the javascripts and stylesheets in the assets pipeline,
|
39
|
+
create the `bootsy.rb` initializer and add a copy of the english translations.
|
36
40
|
|
37
41
|
4. Add and run migrations (if you're using ActiveRecord):
|
38
42
|
```console
|
@@ -43,7 +47,8 @@ rake db:migrate
|
|
43
47
|
|
44
48
|
## Usage
|
45
49
|
|
46
|
-
Just call the brand new method `bootsy_area` in your `FormBuilder` instances, the
|
50
|
+
Just call the brand new method `bootsy_area` in your `FormBuilder` instances, the
|
51
|
+
same way you'd call the basic `textarea` method. Example:
|
47
52
|
```erb
|
48
53
|
<%= form_for(@post) do |f| %>
|
49
54
|
<%= f.label :title %>
|
@@ -56,7 +61,9 @@ Just call the brand new method `bootsy_area` in your `FormBuilder` instances, th
|
|
56
61
|
<% end %>
|
57
62
|
```
|
58
63
|
|
59
|
-
Bootsy will group the uploaded images as galleries and associate them to one of
|
64
|
+
Bootsy will group the uploaded images as galleries and associate them to one of
|
65
|
+
your models. For example, if you have a `Post` model and you want to use `bootsy_area`
|
66
|
+
with it, then you should include the `Bootsy::Container` module:
|
60
67
|
```ruby
|
61
68
|
class Post < ActiveRecord::Base
|
62
69
|
include Bootsy::Container
|
@@ -65,7 +72,9 @@ class Post < ActiveRecord::Base
|
|
65
72
|
end
|
66
73
|
```
|
67
74
|
|
68
|
-
Don't forget to ensure the association of new instances of your model with Bootsy
|
75
|
+
Don't forget to ensure the association of new instances of your model with Bootsy
|
76
|
+
image galleries. For `strong_parameters`, you must allow the parameter `bootsy_image_gallery_id`
|
77
|
+
in your controllers. Example:
|
69
78
|
```ruby
|
70
79
|
private
|
71
80
|
# Never trust parameters from the scary internet, only allow the white list through.
|
@@ -75,9 +84,10 @@ end
|
|
75
84
|
```
|
76
85
|
|
77
86
|
|
78
|
-
## Bootsy with
|
87
|
+
## Bootsy with [Simple Form](https://github.com/plataformatec/simple_form) builders
|
79
88
|
|
80
|
-
Just use the brand new input type `bootsy` in your `SimpleForm::FormBuilder` instances,
|
89
|
+
Just use the brand new input type `bootsy` in your `SimpleForm::FormBuilder` instances,
|
90
|
+
in the same way you would use the basic `text` input. Example:
|
81
91
|
```erb
|
82
92
|
<%= simple_form_for @post do |f| %>
|
83
93
|
<%= f.input :title %>
|
@@ -91,12 +101,14 @@ Just use the brand new input type `bootsy` in your `SimpleForm::FormBuilder` ins
|
|
91
101
|
|
92
102
|
## Editor options
|
93
103
|
|
94
|
-
It is possible to customize how the editor is displayed and its behavior by passing
|
104
|
+
It is possible to customize how the editor is displayed and its behavior by passing
|
105
|
+
a hash `editor_options` to your `bootsy_area`.
|
95
106
|
|
96
107
|
|
97
108
|
### Buttons
|
98
109
|
|
99
|
-
You can enable/disable the buttons available on the editor. For example, if you
|
110
|
+
You can enable/disable the buttons available on the editor. For example, if you
|
111
|
+
want to disable the link and color buttons:
|
100
112
|
```erb
|
101
113
|
<%= f.bootsy_area :my_attribute, editor_options: {link: false, color: false} %>
|
102
114
|
```
|
@@ -105,24 +117,36 @@ Available options are: `:font_styles`, `:emphasis`, `:lists`, `:html`, `:link`,
|
|
105
117
|
|
106
118
|
### Alert for usaved changes
|
107
119
|
|
108
|
-
By default, Bootsy alerts for unsaved changes if the user attempts to unload
|
120
|
+
By default, Bootsy alerts for unsaved changes if the user attempts to unload
|
121
|
+
the window. You can disable this behaviour by doing:
|
109
122
|
```erb
|
110
123
|
<%= f.bootsy_area :my_attribute, editor_options: {alert_unsaved: false} %>
|
111
124
|
```
|
112
125
|
|
113
126
|
## Uploader
|
114
127
|
|
115
|
-
It's also possible to use Bootsy without the image upload feature. Just call
|
128
|
+
It's also possible to use Bootsy without the image upload feature. Just call
|
129
|
+
`bootsy_area` in a form builder not associated to a `Bootsy::Container` model.
|
130
|
+
This way users can insert images in their texts by providing an image url.
|
116
131
|
|
117
132
|
|
118
133
|
## Configuration
|
119
134
|
|
120
|
-
You can set the default editor options, image sizes available (small, medium,
|
135
|
+
You can set the default editor options, image sizes available (small, medium,
|
136
|
+
large and/or its original), its dimensions and more. Take a look at the initalizer
|
137
|
+
file, `/config/initializers/bootsy.rb`.
|
121
138
|
|
122
139
|
|
123
140
|
## I18n
|
124
141
|
|
125
|
-
Bootsy defines some i18n keys. The english translation is automatically added
|
142
|
+
Bootsy defines some i18n keys. The english translation is automatically added
|
143
|
+
to your `config/locales` directory as `bootsy.en.yml`. You can follow that template
|
144
|
+
in order to translate Bootsy to your language. You can find some examples
|
145
|
+
[here](https://github.com/volmer/bootsy/tree/master/config/locales). It is also
|
146
|
+
necessary to add a translation for Bootstrap-wysihtml5, the javascript editor, in
|
147
|
+
your assets pipeline. Instructions [here](https://github.com/jhollingworth/bootstrap-wysihtml5#i18n).
|
148
|
+
If you are using the alert for unsaved changes, you have to define a translation
|
149
|
+
for it as well. Just follow [this example](https://github.com/volmer/bootsy/tree/master/app/assets/bootsy/locales/bootsy.pt-BR.js).
|
126
150
|
|
127
151
|
|
128
152
|
## License
|
Binary file
|
File without changes
|
@@ -5,14 +5,14 @@
|
|
5
5
|
"font-styles": function(locale, options) {
|
6
6
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
7
7
|
return "<li class='dropdown'>" +
|
8
|
-
"<a class='btn dropdown-toggle" + size + "' data-toggle='dropdown' href='#' title='" + locale.font_styles.title + "'>" +
|
8
|
+
"<a class='btn btn-default dropdown-toggle" + size + "' data-toggle='dropdown' href='#' title='" + locale.font_styles.title + "'>" +
|
9
9
|
"<i class='icon-font'></i> <span class='current-font'>" + locale.font_styles.normal + "</span> <b class='caret'></b>" +
|
10
10
|
"</a>" +
|
11
11
|
"<ul class='dropdown-menu'>" +
|
12
|
-
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='div' tabindex='-1'>" + locale.font_styles.normal + "</a></li>" +
|
13
|
-
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h1' tabindex='-1'>" + locale.font_styles.h1 + "</a></li>" +
|
14
|
-
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h2' tabindex='-1'>" + locale.font_styles.h2 + "</a></li>" +
|
15
|
-
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h3' tabindex='-1'>" + locale.font_styles.h3 + "</a></li>" +
|
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
16
|
"</ul>" +
|
17
17
|
"</li>";
|
18
18
|
},
|
@@ -21,9 +21,9 @@
|
|
21
21
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
22
22
|
return "<li>" +
|
23
23
|
"<div class='btn-group'>" +
|
24
|
-
"<a class='btn" + size + "' data-wysihtml5-command='bold' title='CTRL+B' tabindex='-1'>" + locale.emphasis.bold + "</a>" +
|
25
|
-
"<a class='btn" + size + "' data-wysihtml5-command='italic' title='CTRL+I' tabindex='-1'>" + locale.emphasis.italic + "</a>" +
|
26
|
-
"<a class='btn" + size + "' data-wysihtml5-command='underline' title='CTRL+U' tabindex='-1'>" + locale.emphasis.underline + "</a>" +
|
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
27
|
"</div>" +
|
28
28
|
"</li>";
|
29
29
|
},
|
@@ -32,10 +32,10 @@
|
|
32
32
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
33
33
|
return "<li>" +
|
34
34
|
"<div class='btn-group'>" +
|
35
|
-
"<a class='btn" + size + "' data-wysihtml5-command='insertUnorderedList' title='" + locale.lists.unordered + "' tabindex='-1'><i class='icon-list'></i></a>" +
|
36
|
-
"<a class='btn" + size + "' data-wysihtml5-command='insertOrderedList' title='" + locale.lists.ordered + "' tabindex='-1'><i class='icon-th-list'></i></a>" +
|
37
|
-
"<a class='btn" + size + "' data-wysihtml5-command='Outdent' title='" + locale.lists.outdent + "' tabindex='-1'><i class='icon-indent-left'></i></a>" +
|
38
|
-
"<a class='btn" + size + "' data-wysihtml5-command='Indent' title='" + locale.lists.indent + "' tabindex='-1'><i class='icon-indent-right'></i></a>" +
|
35
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='insertUnorderedList' title='" + locale.lists.unordered + "' tabindex='-1'><i class='icon-list'></i></a>" +
|
36
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='insertOrderedList' title='" + locale.lists.ordered + "' tabindex='-1'><i class='icon-th-list'></i></a>" +
|
37
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='Outdent' title='" + locale.lists.outdent + "' tabindex='-1'><i class='icon-indent-left'></i></a>" +
|
38
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='Indent' title='" + locale.lists.indent + "' tabindex='-1'><i class='icon-indent-right'></i></a>" +
|
39
39
|
"</div>" +
|
40
40
|
"</li>";
|
41
41
|
},
|
@@ -43,40 +43,48 @@
|
|
43
43
|
"link": function(locale, options) {
|
44
44
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
45
45
|
return "<li>" +
|
46
|
-
"<div class='bootstrap-wysihtml5-insert-link-modal modal
|
47
|
-
"<div class='modal-
|
48
|
-
"<
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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'>×</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>" +
|
57
61
|
"</div>" +
|
58
62
|
"</div>" +
|
59
|
-
"<a class='btn" + size + "' data-wysihtml5-command='createLink' title='" + locale.link.insert + "' tabindex='-1'><i class='icon-share'></i></a>" +
|
63
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='createLink' title='" + locale.link.insert + "' tabindex='-1'><i class='icon-share'></i></a>" +
|
60
64
|
"</li>";
|
61
65
|
},
|
62
66
|
|
63
67
|
"image": function(locale, options) {
|
64
68
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
65
69
|
return "<li>" +
|
66
|
-
"<div class='bootstrap-wysihtml5-insert-image-modal modal
|
67
|
-
"<div class='modal-
|
68
|
-
"<
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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'>×</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>" +
|
77
85
|
"</div>" +
|
78
86
|
"</div>" +
|
79
|
-
"<a class='btn" + size + "' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><i class='icon-picture'></i></a>" +
|
87
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><i class='icon-picture'></i></a>" +
|
80
88
|
"</li>";
|
81
89
|
},
|
82
90
|
|
@@ -84,7 +92,7 @@
|
|
84
92
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
85
93
|
return "<li>" +
|
86
94
|
"<div class='btn-group'>" +
|
87
|
-
"<a class='btn" + size + "' data-wysihtml5-action='change_view' title='" + locale.html.edit + "' tabindex='-1'><i class='icon-pencil'></i></a>" +
|
95
|
+
"<a class='btn btn-default " + size + "' data-wysihtml5-action='change_view' title='" + locale.html.edit + "' tabindex='-1'><i class='icon-pencil'></i></a>" +
|
88
96
|
"</div>" +
|
89
97
|
"</li>";
|
90
98
|
},
|
@@ -92,21 +100,21 @@
|
|
92
100
|
"color": function(locale, options) {
|
93
101
|
var size = (options && options.size) ? ' btn-'+options.size : '';
|
94
102
|
return "<li class='dropdown'>" +
|
95
|
-
"<a class='btn dropdown-toggle" + size + "' data-toggle='dropdown' href='#' tabindex='-1' title='" + locale.colours.title + "'>" +
|
103
|
+
"<a class='btn btn-default dropdown-toggle" + size + "' data-toggle='dropdown' href='#' tabindex='-1' title='" + locale.colours.title + "'>" +
|
96
104
|
"<span class='current-color'>" + locale.colours.black + "</span> <b class='caret'></b>" +
|
97
105
|
"</a>" +
|
98
106
|
"<ul class='dropdown-menu'>" +
|
99
|
-
"<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'>" + locale.colours.black + "</a></li>" +
|
100
|
-
"<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'>" + locale.colours.silver + "</a></li>" +
|
101
|
-
"<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'>" + locale.colours.gray + "</a></li>" +
|
102
|
-
"<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'>" + locale.colours.maroon + "</a></li>" +
|
103
|
-
"<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'>" + locale.colours.red + "</a></li>" +
|
104
|
-
"<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'>" + locale.colours.purple + "</a></li>" +
|
105
|
-
"<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'>" + locale.colours.green + "</a></li>" +
|
106
|
-
"<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'>" + locale.colours.olive + "</a></li>" +
|
107
|
-
"<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'>" + locale.colours.navy + "</a></li>" +
|
108
|
-
"<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'>" + locale.colours.blue + "</a></li>" +
|
109
|
-
"<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'>" + locale.colours.orange + "</a></li>" +
|
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>" +
|
110
118
|
"</ul>" +
|
111
119
|
"</li>";
|
112
120
|
}
|
@@ -143,7 +151,7 @@
|
|
143
151
|
|
144
152
|
createEditor: function(options) {
|
145
153
|
options = options || {};
|
146
|
-
|
154
|
+
|
147
155
|
// Add the toolbar to a clone of the options object so multiple instances
|
148
156
|
// of the WYISYWG don't break because "toolbar" is already defined
|
149
157
|
options = $.extend(true, {}, options);
|
@@ -392,7 +400,7 @@
|
|
392
400
|
return methods.init.apply( this, arguments );
|
393
401
|
} else {
|
394
402
|
$.error( 'Method ' + method + ' does not exist on jQuery.wysihtml5' );
|
395
|
-
}
|
403
|
+
}
|
396
404
|
};
|
397
405
|
|
398
406
|
$.fn.wysihtml5.Constructor = Wysihtml5;
|
@@ -41,7 +41,7 @@ $.fn.bootstrapFileInput = function() {
|
|
41
41
|
|
42
42
|
// Now we're going to replace that input field with a Bootstrap button.
|
43
43
|
// The input will actually still be there, it will just be float above and transparent (done with the CSS).
|
44
|
-
$elem.replaceWith('<a class="file-input-wrapper btn' + className + '">'+buttonWord+input+'</a>');
|
44
|
+
$elem.replaceWith('<a class="file-input-wrapper btn btn-default ' + className + '">'+buttonWord+input+'</a>');
|
45
45
|
})
|
46
46
|
|
47
47
|
// After we have found all of the file inputs let's apply a listener for tracking the mouse movement.
|
@@ -1,221 +1,278 @@
|
|
1
1
|
window.Bootsy = window.Bootsy || {};
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
Bootsy.Area = function($el) {
|
4
|
+
this.$el = $el;
|
5
|
+
this.modal = $el.siblings('.bootsy-modal');
|
6
|
+
this.locale = $el.data('bootsy-locale') || $('html').attr('lang') || 'en';
|
7
|
+
this.unsavedChanges = false;
|
6
8
|
|
7
|
-
this.
|
8
|
-
|
9
|
-
$('
|
9
|
+
this.options = {
|
10
|
+
locale: this.locale,
|
11
|
+
alertUnsavedChanges: $el.data('bootsy-alert-unsaved'),
|
12
|
+
image: $el.data('bootsy-image'),
|
13
|
+
uploader: $el.data('bootsy-uploader'),
|
10
14
|
};
|
11
15
|
|
12
|
-
this.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
if ($el.data('bootsy-font-styles') === false) this.options['font-styles'] = false;
|
17
|
+
if ($el.data('bootsy-emphasis') === false) this.options.emphasis = false;
|
18
|
+
if ($el.data('bootsy-lists') === false) this.options.lists = false;
|
19
|
+
if ($el.data('bootsy-html') === true) this.options.html = true;
|
20
|
+
if ($el.data('bootsy-link') === false) this.options.link = false;
|
21
|
+
if ($el.data('bootsy-color') === false) this.options.color = false;
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
// Delegate find to the modal
|
24
|
+
this.find = this.modal.find.bind(this.modal);
|
25
|
+
};
|
26
|
+
|
27
|
+
|
28
|
+
// Gallery loading
|
29
|
+
Bootsy.Area.prototype.showGalleryLoadingAnimation = function() {
|
30
|
+
this.find('.bootsy-gallery-loader').fadeIn(200);
|
31
|
+
};
|
32
|
+
|
33
|
+
Bootsy.Area.prototype.hideGalleryLoadingAnimation = function() {
|
34
|
+
this.find('.bootsy-gallery-loader').fadeOut(200);
|
35
|
+
};
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
37
|
+
|
38
|
+
// Upload loading animation
|
39
|
+
Bootsy.Area.prototype.showUploadLoadingAnimation = function() {
|
40
|
+
this.find('.bootsy-upload-loader').fadeIn(200);
|
41
|
+
};
|
42
|
+
|
43
|
+
Bootsy.Area.prototype.hideUploadLoadingAnimation = function() {
|
44
|
+
this.find('.bootsy-upload-loader').fadeOut(200);
|
45
|
+
};
|
46
|
+
|
47
|
+
// Alert for empty gallery
|
48
|
+
Bootsy.Area.prototype.showEmptyAlert = function() {
|
49
|
+
this.find('.bootsy-empty-alert').fadeIn(200);
|
50
|
+
};
|
51
|
+
|
52
|
+
Bootsy.Area.prototype.hideEmptyAlert = function() {
|
53
|
+
this.find('.bootsy-empty-alert').fadeOut(200);
|
54
|
+
};
|
55
|
+
|
56
|
+
// Manual refresh button
|
57
|
+
Bootsy.Area.prototype.showRefreshButton = function() {
|
58
|
+
this.find('.refresh-btn').fadeIn(200);
|
59
|
+
};
|
60
|
+
|
61
|
+
Bootsy.Area.prototype.hideRefreshButton = function() {
|
62
|
+
this.find('.refresh-btn').fadeOut(200);
|
63
|
+
};
|
64
|
+
|
65
|
+
|
66
|
+
// Set upload form
|
67
|
+
Bootsy.Area.prototype.setUploadForm = function(html) {
|
68
|
+
var form;
|
69
|
+
|
70
|
+
this.find('.modal-footer').html(html);
|
71
|
+
|
72
|
+
this.hideUploadLoadingAnimation();
|
73
|
+
|
74
|
+
this.find('.bootsy-upload-form input[type="file"]').bootstrapFileInput();
|
75
|
+
|
76
|
+
this.uploadInput = this.find('.bootsy-upload-form input[type="file"]');
|
77
|
+
|
78
|
+
this.uploadInput.change(function() {
|
79
|
+
this.showUploadLoadingAnimation();
|
80
|
+
|
81
|
+
this.uploadInput.closest('form').submit();
|
82
|
+
}.bind(this));
|
83
|
+
};
|
84
|
+
|
85
|
+
|
86
|
+
// Set image gallery
|
87
|
+
Bootsy.Area.prototype.setImageGallery = function() {
|
88
|
+
this.showGalleryLoadingAnimation();
|
89
|
+
|
90
|
+
$.ajax({
|
91
|
+
url: '/bootsy/images',
|
92
|
+
type: 'GET',
|
93
|
+
cache: false,
|
94
|
+
data: {
|
95
|
+
image_gallery_id: this.modal.data('gallery-id')
|
96
|
+
},
|
97
|
+
dataType: 'json',
|
98
|
+
success: function(data) {
|
99
|
+
this.hideGalleryLoadingAnimation();
|
100
|
+
|
101
|
+
$.each(data.images, function(index, value) {
|
102
|
+
this.addImage(value);
|
103
|
+
}.bind(this));
|
104
|
+
|
105
|
+
if (data.images.length == 0) {
|
106
|
+
this.showEmptyAlert();
|
84
107
|
}
|
85
|
-
});
|
86
|
-
};
|
87
108
|
|
88
|
-
|
89
|
-
editor.currentView.element.focus(false);
|
90
|
-
self.caretBookmark = editor.composer.selection.getBookmark();
|
91
|
-
$('#bootsy_image_gallery').modal('show');
|
92
|
-
};
|
109
|
+
this.setUploadForm(data.form);
|
93
110
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
self.editor.composer.selection.setBookmark(self.caretBookmark);
|
99
|
-
self.caretBookmark = null;
|
100
|
-
}
|
101
|
-
self.editor.composer.commands.exec('insertImage', image);
|
102
|
-
};
|
111
|
+
this.modal.data('gallery-loaded', true);
|
112
|
+
}.bind(this),
|
113
|
+
error: function(e) {
|
114
|
+
alert(Bootsy.translations[this.locale].error);
|
103
115
|
|
104
|
-
|
105
|
-
|
106
|
-
};
|
116
|
+
this.showRefreshButton();
|
117
|
+
}.bind(this)
|
118
|
+
});
|
119
|
+
};
|
107
120
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
callbacks[i]();
|
112
|
-
}
|
113
|
-
self.triggeredEvents.push(eventName);
|
114
|
-
};
|
121
|
+
// Delete image
|
122
|
+
Bootsy.Area.prototype.deleteImage = function (id) {
|
123
|
+
var image = this.find('.bootsy-image[data-id="' + id + '"]');
|
115
124
|
|
116
|
-
this.
|
117
|
-
if(self.triggeredEvents.indexOf(eventName) != -1) {
|
118
|
-
callback();
|
119
|
-
}else{
|
120
|
-
self.on(eventName, callback);
|
121
|
-
}
|
122
|
-
};
|
125
|
+
this.hideGalleryLoadingAnimation();
|
123
126
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
+
image.hide(200, function() {
|
128
|
+
image.remove();
|
129
|
+
|
130
|
+
// Put message back if 0 images
|
131
|
+
if (this.find('.bootsy-image').length == 0 ) {
|
132
|
+
this.showEmptyAlert();
|
127
133
|
}
|
128
|
-
};
|
134
|
+
}.bind(this));
|
135
|
+
};
|
129
136
|
|
130
|
-
this.clear = function () {
|
131
|
-
self.editor.clear();
|
132
|
-
self.setImageGalleryId('');
|
133
|
-
};
|
134
137
|
|
135
|
-
|
136
|
-
|
137
|
-
this.
|
138
|
-
|
139
|
-
this.
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
if (
|
149
|
-
|
150
|
-
|
151
|
-
window.onbeforeunload = this.alertUnsavedChanges;
|
138
|
+
// Add image to gallery
|
139
|
+
Bootsy.Area.prototype.addImage = function(html) {
|
140
|
+
this.hideEmptyAlert();
|
141
|
+
|
142
|
+
$(html).hide().appendTo(this.find('.bootsy-gallery')).fadeIn(200);
|
143
|
+
};
|
144
|
+
|
145
|
+
// Insert image in the text
|
146
|
+
Bootsy.Area.prototype.insertImage = function(image) {
|
147
|
+
this.modal.modal('hide');
|
148
|
+
|
149
|
+
this.editor.currentView.element.focus();
|
150
|
+
|
151
|
+
if (this.caretBookmark) {
|
152
|
+
this.editor.composer.selection.setBookmark(this.caretBookmark);
|
153
|
+
this.caretBookmark = null;
|
152
154
|
}
|
153
155
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
156
|
+
this.editor.composer.commands.exec('insertImage', image);
|
157
|
+
};
|
158
|
+
|
159
|
+
// Open Bootsy modal
|
160
|
+
Bootsy.Area.prototype.openImagesModal = function(editor) {
|
161
|
+
editor.currentView.element.focus(false);
|
162
|
+
|
163
|
+
this.caretBookmark = editor.composer.selection.getBookmark();
|
164
|
+
|
165
|
+
this.modal.modal('show');
|
166
|
+
};
|
167
|
+
|
168
|
+
// Alert for unsaved changes
|
169
|
+
Bootsy.Area.prototype.unsavedChangesAlert = function () {
|
170
|
+
if (this.unsavedChanges) {
|
171
|
+
return Bootsy.translations[this.locale].alertUnsaved;
|
172
|
+
}
|
173
|
+
};
|
174
|
+
|
175
|
+
// Clear everything
|
176
|
+
Bootsy.Area.prototype.clear = function () {
|
177
|
+
this.editor.clear();
|
178
|
+
this.setImageGalleryId('');
|
179
|
+
this.modal.data('gallery-loaded', false);
|
180
|
+
};
|
181
|
+
|
182
|
+
// Set the image gallery id
|
183
|
+
Bootsy.Area.prototype.setImageGalleryId = function(id) {
|
184
|
+
this.modal.data('gallery-id', id);
|
185
|
+
|
186
|
+
this.$el.siblings('.bootsy_image_gallery_id').val(id);
|
187
|
+
};
|
188
|
+
|
189
|
+
|
190
|
+
// Init components
|
191
|
+
Bootsy.Area.prototype.init = function() {
|
192
|
+
var insert = this.insertImage.bind(this);
|
193
|
+
|
194
|
+
if ((this.options.image === true) && (this.options.uploader === true)) {
|
195
|
+
this.modal.on('click', '.bootsy-image .insert', function(e) {
|
196
|
+
var img, imageObject;
|
197
|
+
var imagePrefix = '/' + $(this).attr('data-image-size') + '_';
|
198
|
+
|
199
|
+
if ($(this).data('image-size') === 'original') {
|
200
|
+
imagePrefix = '/';
|
201
|
+
}
|
202
|
+
|
203
|
+
img = $(this).parents('.bootsy-image').find('img');
|
158
204
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
this.editorOptions.customCommand = true;
|
163
|
-
this.editorOptions.customCommandCallback = this.openImageGallery;
|
164
|
-
this.editorOptions.customTemplates = {
|
165
|
-
customCommand: function (locale, options) {
|
166
|
-
var size = (options && options.size) ? ' btn-'+options.size : '';
|
167
|
-
return "<li>" +
|
168
|
-
"<a class='btn" + size + "' data-wysihtml5-command='customCommand' title='" + locale.image.insert + "' tabindex='-1'><i class='icon-picture'></i></a>" +
|
169
|
-
"</li>";
|
170
|
-
}
|
205
|
+
imageObject = {
|
206
|
+
src: img.attr('src').replace('/thumb_', imagePrefix),
|
207
|
+
alt: img.attr('alt').replace('Thumb_', '')
|
171
208
|
};
|
172
209
|
|
173
|
-
|
174
|
-
this.imageGalleryModal.find('a.refresh-btn').hide();
|
210
|
+
imageObject.align = $(this).data('position');
|
175
211
|
|
176
|
-
|
212
|
+
insert(imageObject);
|
213
|
+
});
|
177
214
|
|
178
|
-
|
215
|
+
// Let's use the uploader, not the static image modal
|
216
|
+
this.options.image = false;
|
217
|
+
this.options.customCommand = true;
|
218
|
+
this.options.customCommandCallback = this.openImagesModal.bind(this);
|
219
|
+
this.options.customTemplates = {
|
220
|
+
customCommand: function(locale, options) {
|
221
|
+
var size = (options && options.size) ? ' btn-'+options.size : '';
|
222
|
+
|
223
|
+
return '<li>' +
|
224
|
+
'<a class="btn btn-default ' + size + '" data-wysihtml5-command="customCommand" title="' + locale.image.insert + '" tabindex="-1">' +
|
225
|
+
'<i class="icon-picture"></i>' +
|
226
|
+
'</a>' +
|
227
|
+
'</li>';
|
228
|
+
}
|
229
|
+
};
|
179
230
|
|
180
|
-
|
231
|
+
// In order to avoid form nesting
|
232
|
+
this.modal.parents('form').after(this.modal);
|
181
233
|
|
182
|
-
|
183
|
-
this.imageGalleryModal.on('shown', this.refreshGallery);
|
234
|
+
this.modal.on('click', 'a[href="#refresh-gallery"]', this.setImageGallery.bind(this));
|
184
235
|
|
185
|
-
|
186
|
-
self.progressBar();
|
187
|
-
self.editor.currentView.element.focus();
|
188
|
-
});
|
236
|
+
this.modal.on('ajax:before', '.destroy-btn', this.showGalleryLoadingAnimation.bind(this));
|
189
237
|
|
190
|
-
|
191
|
-
|
192
|
-
|
238
|
+
this.modal.on('ajax:success', '.destroy-btn', function(evt, data) {
|
239
|
+
this.deleteImage(data.id);
|
240
|
+
}.bind(this));
|
193
241
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
var obj = {
|
201
|
-
src: img.attr('src').replace("/thumb_", imagePrefix),
|
202
|
-
alt: img.attr('alt').replace("Thumb_", "")
|
203
|
-
};
|
242
|
+
this.modal.on('ajax:success', '.bootsy-upload-form', function(evt, data) {
|
243
|
+
this.setImageGalleryId(data.gallery_id);
|
244
|
+
this.addImage(data.image);
|
245
|
+
this.setUploadForm(data.form);
|
246
|
+
}.bind(this));
|
247
|
+
}
|
204
248
|
|
205
|
-
|
249
|
+
this.editor = this.$el.wysihtml5($.extend(Bootsy.options, this.options)).data('wysihtml5').editor;
|
206
250
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
} else {
|
211
|
-
this.editorOptions.image = false;
|
251
|
+
// Mechanism for unsaved changes alert
|
252
|
+
if (this.options.alertUnsavedChanges !== false) {
|
253
|
+
window.onbeforeunload = this.unsavedChangesAlert.bind(this);
|
212
254
|
}
|
213
255
|
|
214
|
-
this
|
256
|
+
this.$el.closest('form').submit(function(e) {
|
257
|
+
this.unsavedChanges = false;
|
215
258
|
|
216
|
-
|
217
|
-
|
218
|
-
|
259
|
+
return true;
|
260
|
+
}.bind(this));
|
261
|
+
|
262
|
+
this.editor.on('change', function() {
|
263
|
+
this.unsavedChanges = true;
|
264
|
+
}.bind(this));
|
265
|
+
|
266
|
+
this.modal.modal({ show: false });
|
267
|
+
|
268
|
+
this.modal.on('shown.bs.modal', function() {
|
269
|
+
if (this.modal.data('gallery-loaded') !== true) {
|
270
|
+
this.setImageGallery();
|
271
|
+
}
|
272
|
+
}.bind(this));
|
273
|
+
|
274
|
+
this.modal.on('hide.bs.modal', this.editor.currentView.element.focus);
|
219
275
|
|
220
|
-
this.
|
276
|
+
this.hideRefreshButton();
|
277
|
+
this.hideEmptyAlert();
|
221
278
|
};
|