bootsy 2.2.0 → 2.2.1
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 +4 -4
- data/app/assets/javascripts/bootsy.js +2 -1
- data/app/assets/javascripts/bootsy/area.js +26 -28
- data/app/assets/javascripts/bootsy/editor_options.js +4 -4
- data/app/assets/javascripts/bootsy/image_template.js +11 -0
- data/app/assets/javascripts/bootsy/locales/en.js +1 -6
- data/app/assets/javascripts/bootsy/locales/pt-BR.js +1 -6
- data/app/assets/javascripts/bootsy/modal.js +30 -5
- data/app/assets/javascripts/bootsy/vendor/bootstrap-wysihtml5.js +530 -0
- data/app/assets/javascripts/bootsy/vendor/wysihtml5.js +9565 -0
- data/app/assets/stylesheets/bootsy.css +0 -14
- data/app/helpers/bootsy/application_helper.rb +6 -0
- data/app/views/bootsy/images/_image.html.erb +1 -3
- data/app/views/bootsy/images/_modal.html.erb +29 -0
- data/config/locales/bootsy.en.yml +2 -0
- data/config/locales/bootsy.pt-BR.yml +2 -0
- data/lib/bootsy.rb +4 -5
- data/lib/bootsy/form_helper.rb +6 -0
- data/lib/bootsy/version.rb +1 -1
- data/lib/generators/bootsy/templates/bootsy.rb +4 -5
- metadata +7 -5
- data/app/assets/javascripts/bootsy/image_template.js.erb +0 -45
- data/app/assets/javascripts/bootsy/vendor/bootstrap3-wysihtml5.all.js +0 -14975
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc0d3d886ed83b6d649b9fb22d4a6298a59f0254
|
4
|
+
data.tar.gz: d85216d19292829dcc8a2eae22bef6e558f561c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dcce405cb0d224ea4c9fde9577df2b99bc8c69e1b6bf702978a5cfbfcee3c93818b673bf16e0b681cfce3dcd0e84b13d2961c4fc60796d2e4d8a6f516772a54
|
7
|
+
data.tar.gz: f011a536e7034442c36d268913539475a4a64baf5b2487ece5d0f72ec5a72cb15bae2a464b10a7214d462dcb6b6793cc34d690c7795ada05514ac54325b2b57c
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
[](https://coveralls.io/r/volmer/bootsy)
|
8
8
|
|
9
9
|
*Bootsy* is a WYSIWYG editor for Rails based on
|
10
|
-
[
|
10
|
+
[Bootstrap-wysihtml5](https://github.com/jhollingworth/bootstrap-wysihtml5) with image uploads using
|
11
11
|
[CarrierWave](https://github.com/carrierwaveuploader/carrierwave).
|
12
12
|
|
13
13
|
### Live demo
|
@@ -37,7 +37,7 @@
|
|
37
37
|
|
38
38
|
3. Run the install generator:
|
39
39
|
```console
|
40
|
-
rails generate bootsy:install
|
40
|
+
bundle exec rails generate bootsy:install
|
41
41
|
```
|
42
42
|
It will include the javascripts and stylesheets in the assets pipeline,
|
43
43
|
create the `bootsy.rb` initializer and add a copy of the english translations.
|
@@ -48,8 +48,8 @@
|
|
48
48
|
|
49
49
|
4. Add and run migrations:
|
50
50
|
```console
|
51
|
-
rake bootsy:install:migrations
|
52
|
-
rake db:migrate
|
51
|
+
bundle exec rake bootsy:install:migrations
|
52
|
+
bundle exec rake db:migrate
|
53
53
|
```
|
54
54
|
|
55
55
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
//= require jquery.remotipart
|
2
2
|
//= require bootsy/vendor/polyfill
|
3
|
-
//= require bootsy/vendor/
|
3
|
+
//= require bootsy/vendor/wysihtml5
|
4
|
+
//= require bootsy/vendor/bootstrap-wysihtml5
|
4
5
|
//= require bootsy/vendor/bootstrap.file-input
|
5
6
|
//= require bootsy/area
|
6
7
|
//= require bootsy/editor_options
|
@@ -14,20 +14,14 @@ Bootsy.Area = function($el) {
|
|
14
14
|
locale: this.locale,
|
15
15
|
alertUnsavedChanges: $el.data('bootsy-alert-unsaved'),
|
16
16
|
uploader: $el.data('bootsy-uploader'),
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
'lists': $el.data('bootsy-lists')
|
25
|
-
},
|
17
|
+
color: $el.data('bootsy-color'),
|
18
|
+
emphasis: $el.data('bootsy-emphasis'),
|
19
|
+
'font-styles': $el.data('bootsy-font-styles'),
|
20
|
+
html: $el.data('bootsy-html'),
|
21
|
+
image: $el.data('bootsy-image'),
|
22
|
+
link: $el.data('bootsy-link'),
|
23
|
+
lists: $el.data('bootsy-lists'),
|
26
24
|
events: {
|
27
|
-
load: function() {
|
28
|
-
self.editor = this;
|
29
|
-
self.onEditorLoad();
|
30
|
-
},
|
31
25
|
change: function() {
|
32
26
|
self.unsavedChanges = true;
|
33
27
|
}
|
@@ -54,26 +48,18 @@ Bootsy.Area.prototype.setImageGalleryId = function(id) {
|
|
54
48
|
this.$el.siblings('.bootsy_image_gallery_id').val(id);
|
55
49
|
};
|
56
50
|
|
57
|
-
Bootsy.Area.prototype.onEditorLoad = function() {};
|
58
|
-
|
59
|
-
Bootsy.Area.prototype.setupModal = function() {
|
60
|
-
this.modal = new Bootsy.Modal(
|
61
|
-
this.editor.toolbar.commandMapping['insertImage:null'].dialog.container, this
|
62
|
-
);
|
63
|
-
};
|
64
|
-
|
65
51
|
// Init components
|
66
52
|
Bootsy.Area.prototype.init = function() {
|
67
53
|
if (!this.$el.data('bootsy-initialized')) {
|
68
|
-
if ((this.options.
|
69
|
-
this.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
this.
|
54
|
+
if ((this.options.image === true) && (this.options.uploader === true)) {
|
55
|
+
this.modal = new Bootsy.Modal(this);
|
56
|
+
this.options.image = false;
|
57
|
+
this.options.customCommand = true;
|
58
|
+
this.options.customCommandCallback = this.modal.show.bind(this.modal);
|
59
|
+
this.options.customTemplates = { customCommand: Bootsy.imageTemplate };
|
74
60
|
}
|
75
61
|
|
76
|
-
this.$el.wysihtml5($.extend(true, Bootsy.options, this.options));
|
62
|
+
this.editor = this.$el.wysihtml5($.extend(true, {}, Bootsy.options, this.options)).data('wysihtml5').editor;
|
77
63
|
|
78
64
|
// Mechanism for unsaved changes alert
|
79
65
|
if (this.options.alertUnsavedChanges !== false) {
|
@@ -89,3 +75,15 @@ Bootsy.Area.prototype.init = function() {
|
|
89
75
|
this.$el.data('bootsy-initialized', true);
|
90
76
|
}
|
91
77
|
};
|
78
|
+
|
79
|
+
// Insert image in the text
|
80
|
+
Bootsy.Area.prototype.insertImage = function(image) {
|
81
|
+
this.editor.currentView.element.focus();
|
82
|
+
|
83
|
+
if (this.caretBookmark) {
|
84
|
+
this.editor.composer.selection.setBookmark(this.caretBookmark);
|
85
|
+
this.caretBookmark = null;
|
86
|
+
}
|
87
|
+
|
88
|
+
this.editor.composer.commands.exec('insertImage', image);
|
89
|
+
};
|
@@ -5,7 +5,9 @@ $('link[rel="stylesheet"]').each(function () {
|
|
5
5
|
pageStylesheets.push($(this).attr('href'));
|
6
6
|
});
|
7
7
|
|
8
|
-
window.Bootsy.options =
|
8
|
+
window.Bootsy.options = {};
|
9
|
+
|
10
|
+
$.extend(true, window.Bootsy.options, $.fn.wysihtml5.defaultOptions, {
|
9
11
|
parserRules: {
|
10
12
|
classes: {
|
11
13
|
"wysiwyg-float-left": 1,
|
@@ -40,8 +42,6 @@ window.Bootsy.options = $.extend(true, $.fn.wysihtml5.defaultOptions, {
|
|
40
42
|
}
|
41
43
|
}
|
42
44
|
},
|
43
|
-
|
44
|
-
color: true
|
45
|
-
},
|
45
|
+
color: true,
|
46
46
|
stylesheets: pageStylesheets
|
47
47
|
});
|
@@ -0,0 +1,11 @@
|
|
1
|
+
window.Bootsy = window.Bootsy || {};
|
2
|
+
|
3
|
+
window.Bootsy.imageTemplate = function(locale, options) {
|
4
|
+
var size = (options && options.size) ? ' btn-' + options.size : '';
|
5
|
+
|
6
|
+
return '<li>' +
|
7
|
+
'<a class="btn btn-default ' + size + '" data-wysihtml5-command="customCommand" title="' + locale.image.insert + '" tabindex="-1">' +
|
8
|
+
'<span class="glyphicon glyphicon-picture"></span>' +
|
9
|
+
'</a>' +
|
10
|
+
'</li>';
|
11
|
+
};
|
@@ -7,10 +7,7 @@
|
|
7
7
|
normal: 'Normal text',
|
8
8
|
h1: 'Heading 1',
|
9
9
|
h2: 'Heading 2',
|
10
|
-
h3: 'Heading 3'
|
11
|
-
h4: 'Heading 4',
|
12
|
-
h5: 'Heading 5',
|
13
|
-
h6: 'Heading 6'
|
10
|
+
h3: 'Heading 3'
|
14
11
|
},
|
15
12
|
emphasis: {
|
16
13
|
bold: 'Bold',
|
@@ -50,8 +47,6 @@
|
|
50
47
|
orange: 'Orange'
|
51
48
|
},
|
52
49
|
bootsy: {
|
53
|
-
empty: 'There are currently no uploaded images.',
|
54
|
-
refresh: 'Refresh',
|
55
50
|
alertUnsaved: 'You have unsaved changes.',
|
56
51
|
error: 'Something went wrong. Please try again later.'
|
57
52
|
}
|
@@ -7,10 +7,7 @@
|
|
7
7
|
normal: 'Texto normal',
|
8
8
|
h1: 'Título 1',
|
9
9
|
h2: 'Título 2',
|
10
|
-
h3: 'Título 3'
|
11
|
-
h4: 'Título 4',
|
12
|
-
h5: 'Título 5',
|
13
|
-
h6: 'Título 6'
|
10
|
+
h3: 'Título 3'
|
14
11
|
},
|
15
12
|
emphasis: {
|
16
13
|
bold: 'Negrito',
|
@@ -50,8 +47,6 @@
|
|
50
47
|
orange: 'Laranja'
|
51
48
|
},
|
52
49
|
bootsy: {
|
53
|
-
empty: 'Não existem imagens salvas.',
|
54
|
-
refresh: 'Atualizar',
|
55
50
|
alertUnsaved: 'As suas modificações ainda não foram gravadas.',
|
56
51
|
error: 'Algo deu errado. Por favor, tente novamente.'
|
57
52
|
}
|
@@ -2,18 +2,38 @@
|
|
2
2
|
|
3
3
|
window.Bootsy = window.Bootsy || {};
|
4
4
|
|
5
|
-
Bootsy.Modal = function(
|
5
|
+
Bootsy.Modal = function(area) {
|
6
6
|
var self = this;
|
7
7
|
|
8
|
-
this.$el =
|
8
|
+
this.$el = area.$el.siblings('.bootsy-modal');
|
9
9
|
this.area = area;
|
10
10
|
|
11
11
|
// In order to avoid form nesting
|
12
12
|
this.$el.parents('form').after(this.$el);
|
13
13
|
|
14
|
-
this.$el.on('click', '.bootsy-image .insert', function() {
|
15
|
-
|
16
|
-
|
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);
|
17
37
|
});
|
18
38
|
|
19
39
|
this.$el.on('ajax:before', '.destroy-btn', this.showGalleryLoadingAnimation.bind(this));
|
@@ -44,6 +64,11 @@ Bootsy.Modal = function(el, area) {
|
|
44
64
|
this.hideEmptyAlert();
|
45
65
|
};
|
46
66
|
|
67
|
+
// Show modal
|
68
|
+
Bootsy.Modal.prototype.show = function() {
|
69
|
+
this.$el.modal('show');
|
70
|
+
};
|
71
|
+
|
47
72
|
// Gallery loading
|
48
73
|
Bootsy.Modal.prototype.showGalleryLoadingAnimation = function() {
|
49
74
|
this.$el.find('.bootsy-gallery-loader').fadeIn(200);
|
@@ -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> <span class='current-font'>" + locale.font_styles.normal + "</span> <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'>×</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'>×</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> <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" : 1,
|
422
|
+
"wysiwyg-color-gray" : 1,
|
423
|
+
"wysiwyg-color-white" : 1,
|
424
|
+
"wysiwyg-color-maroon" : 1,
|
425
|
+
"wysiwyg-color-red" : 1,
|
426
|
+
"wysiwyg-color-purple" : 1,
|
427
|
+
"wysiwyg-color-fuchsia" : 1,
|
428
|
+
"wysiwyg-color-green" : 1,
|
429
|
+
"wysiwyg-color-lime" : 1,
|
430
|
+
"wysiwyg-color-olive" : 1,
|
431
|
+
"wysiwyg-color-yellow" : 1,
|
432
|
+
"wysiwyg-color-navy" : 1,
|
433
|
+
"wysiwyg-color-blue" : 1,
|
434
|
+
"wysiwyg-color-teal" : 1,
|
435
|
+
"wysiwyg-color-aqua" : 1,
|
436
|
+
"wysiwyg-color-orange" : 1
|
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": 1,
|
468
|
+
"div": 1,
|
469
|
+
// to allow save and edit files with code tag hacks
|
470
|
+
"code": 1,
|
471
|
+
"pre": 1
|
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);
|