bootsy 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![image](https://f.cloud.github.com/assets/301187/1365250/e1b7ba80-3854-11e3-9bfe-8bd1e090aca8.png)
|
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
|
};
|