提交 | 用户 | 时间
|
58d006
|
1 |
/** |
A |
2 |
<b>Wysiwyg</b>. A wrapper for Bootstrap wyswiwyg plugin. |
|
3 |
It's just a wrapper so you still need to include Bootstrap wysiwyg script first. |
|
4 |
*/ |
|
5 |
(function($ , undefined) { |
|
6 |
$.fn.ace_wysiwyg = function($options , undefined) { |
|
7 |
var options = $.extend( { |
|
8 |
speech_button:true, |
|
9 |
wysiwyg:{} |
|
10 |
}, $options); |
|
11 |
|
|
12 |
var color_values = [ |
|
13 |
'#ac725e','#d06b64','#f83a22','#fa573c','#ff7537','#ffad46', |
|
14 |
'#42d692','#16a765','#7bd148','#b3dc6c','#fbe983','#fad165', |
|
15 |
'#92e1c0','#9fe1e7','#9fc6e7','#4986e7','#9a9cff','#b99aff', |
|
16 |
'#c2c2c2','#cabdbf','#cca6ac','#f691b2','#cd74e6','#a47ae2', |
|
17 |
'#444444' |
|
18 |
] |
|
19 |
|
|
20 |
var button_defaults = |
|
21 |
{ |
|
22 |
'font' : { |
|
23 |
values:['Arial', 'Courier', 'Comic Sans MS', 'Helvetica', 'Open Sans', 'Tahoma', 'Verdana'], |
|
24 |
icon:'fa fa-font', |
|
25 |
title:'Font' |
|
26 |
}, |
|
27 |
'fontSize' : { |
|
28 |
values:{5:'Huge', 3:'Normal', 1:'Small'}, |
|
29 |
icon:'fa fa-text-height', |
|
30 |
title:'Font Size' |
|
31 |
}, |
|
32 |
'bold' : { |
|
33 |
icon : 'fa fa-bold', |
|
34 |
title : 'Bold (Ctrl/Cmd+B)' |
|
35 |
}, |
|
36 |
'italic' : { |
|
37 |
icon : 'fa fa-italic', |
|
38 |
title : 'Italic (Ctrl/Cmd+I)' |
|
39 |
}, |
|
40 |
'strikethrough' : { |
|
41 |
icon : 'fa fa-strikethrough', |
|
42 |
title : 'Strikethrough' |
|
43 |
}, |
|
44 |
'underline' : { |
|
45 |
icon : 'fa fa-underline', |
|
46 |
title : 'Underline' |
|
47 |
}, |
|
48 |
'insertunorderedlist' : { |
|
49 |
icon : 'fa fa-list-ul', |
|
50 |
title : 'Bullet list' |
|
51 |
}, |
|
52 |
'insertorderedlist' : { |
|
53 |
icon : 'fa fa-list-ol', |
|
54 |
title : 'Number list' |
|
55 |
}, |
|
56 |
'outdent' : { |
|
57 |
icon : 'fa fa-outdent', |
|
58 |
title : 'Reduce indent (Shift+Tab)' |
|
59 |
}, |
|
60 |
'indent' : { |
|
61 |
icon : 'fa fa-indent', |
|
62 |
title : 'Indent (Tab)' |
|
63 |
}, |
|
64 |
'justifyleft' : { |
|
65 |
icon : 'fa fa-align-left', |
|
66 |
title : 'Align Left (Ctrl/Cmd+L)' |
|
67 |
}, |
|
68 |
'justifycenter' : { |
|
69 |
icon : 'fa fa-align-center', |
|
70 |
title : 'Center (Ctrl/Cmd+E)' |
|
71 |
}, |
|
72 |
'justifyright' : { |
|
73 |
icon : 'fa fa-align-right', |
|
74 |
title : 'Align Right (Ctrl/Cmd+R)' |
|
75 |
}, |
|
76 |
'justifyfull' : { |
|
77 |
icon : 'fa fa-align-justify', |
|
78 |
title : 'Justify (Ctrl/Cmd+J)' |
|
79 |
}, |
|
80 |
'createLink' : { |
|
81 |
icon : 'fa fa-link', |
|
82 |
title : 'Hyperlink', |
|
83 |
button_text : 'Add', |
|
84 |
placeholder : 'URL', |
|
85 |
button_class : 'btn-primary' |
|
86 |
}, |
|
87 |
'unlink' : { |
|
88 |
icon : 'fa fa-chain-broken', |
|
89 |
title : 'Remove Hyperlink' |
|
90 |
}, |
|
91 |
'insertImage' : { |
|
92 |
icon : 'fa fa-picture-o', |
|
93 |
title : 'Insert picture', |
|
94 |
button_text : '<i class="'+ ace.vars['icon'] + 'fa fa-file"></i> Choose Image …', |
|
95 |
placeholder : 'Image URL', |
|
96 |
button_insert : 'Insert', |
|
97 |
button_class : 'btn-success', |
|
98 |
button_insert_class : 'btn-primary', |
|
99 |
choose_file: true //show the choose file button? |
|
100 |
}, |
|
101 |
'foreColor' : { |
|
102 |
values : color_values, |
|
103 |
title : 'Change Color' |
|
104 |
}, |
|
105 |
'backColor' : { |
|
106 |
values : color_values, |
|
107 |
title : 'Change Background Color' |
|
108 |
}, |
|
109 |
'undo' : { |
|
110 |
icon : 'fa fa-undo', |
|
111 |
title : 'Undo (Ctrl/Cmd+Z)' |
|
112 |
}, |
|
113 |
'redo' : { |
|
114 |
icon : 'fa fa-repeat', |
|
115 |
title : 'Redo (Ctrl/Cmd+Y)' |
|
116 |
}, |
|
117 |
'viewSource' : { |
|
118 |
icon : 'fa fa-code', |
|
119 |
title : 'View Source' |
|
120 |
} |
|
121 |
} |
|
122 |
|
|
123 |
var toolbar_buttons = |
|
124 |
options.toolbar || |
|
125 |
[ |
|
126 |
'font', |
|
127 |
null, |
|
128 |
'fontSize', |
|
129 |
null, |
|
130 |
'bold', |
|
131 |
'italic', |
|
132 |
'strikethrough', |
|
133 |
'underline', |
|
134 |
null, |
|
135 |
'insertunorderedlist', |
|
136 |
'insertorderedlist', |
|
137 |
'outdent', |
|
138 |
'indent', |
|
139 |
null, |
|
140 |
'justifyleft', |
|
141 |
'justifycenter', |
|
142 |
'justifyright', |
|
143 |
'justifyfull', |
|
144 |
null, |
|
145 |
'createLink', |
|
146 |
'unlink', |
|
147 |
null, |
|
148 |
'insertImage', |
|
149 |
null, |
|
150 |
'foreColor', |
|
151 |
null, |
|
152 |
'undo', |
|
153 |
'redo', |
|
154 |
null, |
|
155 |
'viewSource' |
|
156 |
] |
|
157 |
|
|
158 |
|
|
159 |
this.each(function() { |
|
160 |
var toolbar = ' <div class="wysiwyg-toolbar btn-toolbar center"> <div class="btn-group"> '; |
|
161 |
|
|
162 |
for(var tb in toolbar_buttons) if(toolbar_buttons.hasOwnProperty(tb)) { |
|
163 |
var button = toolbar_buttons[tb]; |
|
164 |
if(button === null){ |
|
165 |
toolbar += ' </div> <div class="btn-group"> '; |
|
166 |
continue; |
|
167 |
} |
|
168 |
|
|
169 |
if(typeof button == "string" && button in button_defaults) { |
|
170 |
button = button_defaults[button]; |
|
171 |
button.name = toolbar_buttons[tb]; |
|
172 |
} else if(typeof button == "object" && button.name in button_defaults) { |
|
173 |
button = $.extend(button_defaults[button.name] , button); |
|
174 |
} |
|
175 |
else continue; |
|
176 |
|
|
177 |
var className = "className" in button ? button.className : 'btn-default'; |
|
178 |
switch(button.name) { |
|
179 |
case 'font': |
|
180 |
toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i><i class="' + ace.vars['icon'] + 'fa fa-angle-down icon-on-right"></i></a> '; |
|
181 |
toolbar += ' <ul class="dropdown-menu dropdown-light dropdown-caret">'; |
|
182 |
for(var font in button.values) |
|
183 |
if(button.values.hasOwnProperty(font)) |
|
184 |
toolbar += ' <li><a data-edit="fontName ' + button.values[font] +'" style="font-family:\''+ button.values[font] +'\'">'+button.values[font] + '</a></li> ' |
|
185 |
toolbar += ' </ul>'; |
|
186 |
break; |
|
187 |
|
|
188 |
case 'fontSize': |
|
189 |
toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i> <i class="'+ ace.vars['icon'] + 'fa fa-angle-down icon-on-right"></i></a> '; |
|
190 |
toolbar += ' <ul class="dropdown-menu dropdown-light dropdown-caret"> '; |
|
191 |
for(var size in button.values) |
|
192 |
if(button.values.hasOwnProperty(size)) |
|
193 |
toolbar += ' <li><a data-edit="fontSize '+size+'"><font size="'+size+'">'+ button.values[size] +'</font></a></li> ' |
|
194 |
toolbar += ' </ul> '; |
|
195 |
break; |
|
196 |
|
|
197 |
case 'createLink': |
|
198 |
toolbar += ' <div class="btn-group"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> '; |
|
199 |
toolbar += ' <div class="dropdown-menu dropdown-caret dropdown-menu-right">\ |
|
200 |
<div class="input-group">\ |
|
201 |
<input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\ |
|
202 |
<span class="input-group-btn">\ |
|
203 |
<button class="btn btn-sm '+button.button_class+'" type="button">'+button.button_text+'</button>\ |
|
204 |
</span>\ |
|
205 |
</div>\ |
|
206 |
</div> </div>'; |
|
207 |
break; |
|
208 |
|
|
209 |
case 'insertImage': |
|
210 |
toolbar += ' <div class="btn-group"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> '; |
|
211 |
toolbar += ' <div class="dropdown-menu dropdown-caret dropdown-menu-right">\ |
|
212 |
<div class="input-group">\ |
|
213 |
<input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\ |
|
214 |
<span class="input-group-btn">\ |
|
215 |
<button class="btn btn-sm '+button.button_insert_class+'" type="button">'+button.button_insert+'</button>\ |
|
216 |
</span>\ |
|
217 |
</div>'; |
|
218 |
if( button.choose_file && 'FileReader' in window ) toolbar += |
|
219 |
'<div class="space-2"></div>\ |
|
220 |
<label class="center block no-margin-bottom">\ |
|
221 |
<button class="btn btn-sm '+button.button_class+' wysiwyg-choose-file" type="button">'+button.button_text+'</button>\ |
|
222 |
<input type="file" data-edit="'+button.name+'" />\ |
|
223 |
</label>' |
|
224 |
toolbar += ' </div> </div>'; |
|
225 |
break; |
|
226 |
|
|
227 |
case 'foreColor': |
|
228 |
case 'backColor': |
|
229 |
toolbar += ' <select class="hide wysiwyg_colorpicker" title="'+button.title+'"> '; |
|
230 |
$.each(button.values, function (_, color) { |
|
231 |
toolbar += ' <option value="' + color + '">' + color + '</option> '; |
|
232 |
}); |
|
233 |
toolbar += ' </select> '; |
|
234 |
toolbar += ' <input style="display:none;" disabled class="hide" type="text" data-edit="'+button.name+'" /> '; |
|
235 |
break; |
|
236 |
|
|
237 |
case 'viewSource': |
|
238 |
toolbar += ' <a class="btn btn-sm '+className+'" data-view="source" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> '; |
|
239 |
break; |
|
240 |
default: |
|
241 |
toolbar += ' <a class="btn btn-sm '+className+'" data-edit="'+button.name+'" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> '; |
|
242 |
break; |
|
243 |
} |
|
244 |
} |
|
245 |
toolbar += ' </div> '; |
|
246 |
//////////// |
|
247 |
var speech_input; |
|
248 |
if (options.speech_button && 'onwebkitspeechchange' in (speech_input = document.createElement('input'))) { |
|
249 |
toolbar += ' <input class="wysiwyg-speech-input" type="text" data-edit="inserttext" x-webkit-speech />'; |
|
250 |
} |
|
251 |
speech_input = null; |
|
252 |
//////////// |
|
253 |
toolbar += ' </div> '; |
|
254 |
|
|
255 |
|
|
256 |
//if we have a function to decide where to put the toolbar, then call that |
|
257 |
if(options.toolbar_place) toolbar = options.toolbar_place.call(this, toolbar); |
|
258 |
//otherwise put it just before our DIV |
|
259 |
else toolbar = $(this).before(toolbar).prev(); |
|
260 |
|
|
261 |
toolbar.find('a[title]').tooltip({animation:false, container:'body'}); |
|
262 |
toolbar.find('.dropdown-menu input[type=text]').on('click', function() {return false}) |
|
263 |
.on('change', function() {$(this).closest('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle')}) |
|
264 |
.on('keydown', function (e) { |
|
265 |
if(e.which == 27) { |
|
266 |
this.value = ''; |
|
267 |
$(this).change(); |
|
268 |
} |
|
269 |
else if(e.which == 13) { |
|
270 |
e.preventDefault(); |
|
271 |
e.stopPropagation(); |
|
272 |
$(this).change(); |
|
273 |
} |
|
274 |
}); |
|
275 |
|
|
276 |
toolbar.find('input[type=file]').prev().on(ace.click_event, function (e) { |
|
277 |
$(this).next().click(); |
|
278 |
}); |
|
279 |
toolbar.find('.wysiwyg_colorpicker').each(function() { |
|
280 |
$(this).ace_colorpicker({pull_right:true}).change(function(){ |
|
281 |
$(this).nextAll('input').eq(0).val(this.value).change(); |
|
282 |
}).next().find('.btn-colorpicker').tooltip({title: this.title, animation:false, container:'body'}) |
|
283 |
}); |
|
284 |
|
|
285 |
|
|
286 |
var self = $(this); |
|
287 |
//view source |
|
288 |
var view_source = false; |
|
289 |
toolbar.find('a[data-view=source]').on('click', function(e){ |
|
290 |
e.preventDefault(); |
|
291 |
|
|
292 |
if(!view_source) { |
|
293 |
$('<textarea />') |
|
294 |
.css({'width':self.outerWidth(), 'height':self.outerHeight()}) |
|
295 |
.val(self.html()) |
|
296 |
.insertAfter(self) |
|
297 |
self.hide(); |
|
298 |
|
|
299 |
$(this).addClass('active'); |
|
300 |
} |
|
301 |
else { |
|
302 |
var textarea = self.next(); |
|
303 |
self.html(textarea.val()).show(); |
|
304 |
textarea.remove(); |
|
305 |
|
|
306 |
$(this).removeClass('active'); |
|
307 |
} |
|
308 |
|
|
309 |
view_source = !view_source; |
|
310 |
}); |
|
311 |
|
|
312 |
|
|
313 |
var $options = $.extend({}, { activeToolbarClass: 'active' , toolbarSelector : toolbar }, options.wysiwyg || {}) |
|
314 |
$(this).wysiwyg( $options ); |
|
315 |
}); |
|
316 |
|
|
317 |
return this; |
|
318 |
} |
|
319 |
|
|
320 |
|
|
321 |
})(window.jQuery); |
|
322 |
|