wysihtml5n-rails 0.0.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.
Files changed (64) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +57 -0
  3. data/lib/wysihtml5n-rails.rb +6 -0
  4. data/lib/wysihtml5n/rails.rb +2 -0
  5. data/lib/wysihtml5n/rails/engine.rb +10 -0
  6. data/lib/wysihtml5n/rails/version.rb +5 -0
  7. data/test/cases/usage_css_spec.rb +57 -0
  8. data/test/cases/usage_js_spec.rb +33 -0
  9. data/test/dummy/README.rdoc +261 -0
  10. data/test/dummy/Rakefile +7 -0
  11. data/test/dummy/app/assets/javascripts/application.js +3 -0
  12. data/test/dummy/app/assets/javascripts/individual.js +3 -0
  13. data/test/dummy/app/assets/stylesheets/application.css.scss +3 -0
  14. data/test/dummy/app/assets/stylesheets/individual.css.scss +3 -0
  15. data/test/dummy/app/assets/stylesheets/sprockets.css +3 -0
  16. data/test/dummy/app/controllers/application_controller.rb +3 -0
  17. data/test/dummy/app/helpers/application_helper.rb +2 -0
  18. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  19. data/test/dummy/config.ru +4 -0
  20. data/test/dummy/config/application.rb +69 -0
  21. data/test/dummy/config/boot.rb +10 -0
  22. data/test/dummy/config/environment.rb +5 -0
  23. data/test/dummy/config/environments/development.rb +31 -0
  24. data/test/dummy/config/environments/production.rb +64 -0
  25. data/test/dummy/config/environments/test.rb +35 -0
  26. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  27. data/test/dummy/config/initializers/inflections.rb +15 -0
  28. data/test/dummy/config/initializers/mime_types.rb +5 -0
  29. data/test/dummy/config/initializers/secret_token.rb +7 -0
  30. data/test/dummy/config/initializers/session_store.rb +8 -0
  31. data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
  32. data/test/dummy/config/locales/en.yml +5 -0
  33. data/test/dummy/config/routes.rb +58 -0
  34. data/test/dummy/log/test.log +224 -0
  35. data/test/dummy/public/404.html +26 -0
  36. data/test/dummy/public/422.html +26 -0
  37. data/test/dummy/public/500.html +25 -0
  38. data/test/dummy/public/favicon.ico +0 -0
  39. data/test/dummy/script/rails +6 -0
  40. data/test/dummy/tmp/cache/sass/5338c0058b360de616e31cc6c7da71b4f9557c8f/application.css.scssc +0 -0
  41. data/test/dummy/tmp/cache/sass/5338c0058b360de616e31cc6c7da71b4f9557c8f/individual.css.scssc +0 -0
  42. data/test/dummy/tmp/cache/sass/960125ced7e54163fe33c2547bbd2af7f2929975/wysihtml5n.css.scssc +0 -0
  43. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/_bootstrap.scssc +0 -0
  44. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/_editor.scssc +0 -0
  45. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/_font-awesome.scssc +0 -0
  46. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/bootstrap.scssc +0 -0
  47. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/editor.scssc +0 -0
  48. data/test/dummy/tmp/cache/sass/e2cd63e71b626fbbfe6aeea51f81580fd02e0076/font-awesome.scssc +0 -0
  49. data/test/spec_helper.rb +12 -0
  50. data/test/support/helpers.rb +33 -0
  51. data/vendor/assets/fonts/wysihtml5n/fontawesome-webfont.eot +0 -0
  52. data/vendor/assets/fonts/wysihtml5n/fontawesome-webfont.svg +255 -0
  53. data/vendor/assets/fonts/wysihtml5n/fontawesome-webfont.ttf +0 -0
  54. data/vendor/assets/fonts/wysihtml5n/fontawesome-webfont.woff +0 -0
  55. data/vendor/assets/images/wysihtml5n/Jcrop.gif +0 -0
  56. data/vendor/assets/javascripts/wysihtml5n.js +3 -0
  57. data/vendor/assets/javascripts/wysihtml5n/jcrop.js +1695 -0
  58. data/vendor/assets/javascripts/wysihtml5n/wysihtml5-0.3.0.js +9531 -0
  59. data/vendor/assets/javascripts/wysihtml5n/wysihtml5-enhanced.js +783 -0
  60. data/vendor/assets/stylesheets/wysihtml5n.css.scss +3 -0
  61. data/vendor/assets/stylesheets/wysihtml5n/_bootstrap.scss +1692 -0
  62. data/vendor/assets/stylesheets/wysihtml5n/_editor.scss +115 -0
  63. data/vendor/assets/stylesheets/wysihtml5n/_font-awesome.scss +303 -0
  64. metadata +223 -0
@@ -0,0 +1,783 @@
1
+ (function($){
2
+ "use strict";
3
+
4
+ // parser rules for editor
5
+ var parserRules = {
6
+ "classes": {
7
+ "wysiwyg-clear-both": 1,
8
+ "wysiwyg-clear-left": 1,
9
+ "wysiwyg-clear-right": 1,
10
+ "wysiwyg-float-left": 1,
11
+ "wysiwyg-float-right": 1
12
+ },
13
+ "tags": {
14
+ "tr": {
15
+ "add_class": {
16
+ "align": "align_text"
17
+ }
18
+ },
19
+ "strike": {
20
+ "remove": 1
21
+ },
22
+ "form": {
23
+ "rename_tag": "div"
24
+ },
25
+ "rt": {
26
+ "rename_tag": "span"
27
+ },
28
+ "code": {},
29
+ "acronym": {
30
+ "rename_tag": "span"
31
+ },
32
+ "br": {
33
+ "add_class": {
34
+ "clear": "clear_br"
35
+ }
36
+ },
37
+ "details": {
38
+ "rename_tag": "div"
39
+ },
40
+ "h4": {
41
+ "add_class": {
42
+ "align": "align_text"
43
+ }
44
+ },
45
+ "em": {},
46
+ "title": {
47
+ "remove": 1
48
+ },
49
+ "multicol": {
50
+ "rename_tag": "div"
51
+ },
52
+ "figure": {
53
+ "rename_tag": "div"
54
+ },
55
+ "xmp": {
56
+ "rename_tag": "span"
57
+ },
58
+ "small": {},
59
+ "area": {
60
+ "remove": 1
61
+ },
62
+ "time": {
63
+ "rename_tag": "span"
64
+ },
65
+ "dir": {
66
+ "rename_tag": "ul"
67
+ },
68
+ "bdi": {
69
+ "rename_tag": "span"
70
+ },
71
+ "command": {
72
+ "remove": 1
73
+ },
74
+ "ul": {},
75
+ "progress": {
76
+ "rename_tag": "span"
77
+ },
78
+ "dfn": {
79
+ "rename_tag": "span"
80
+ },
81
+ "iframe": {
82
+ "check_attributes": {
83
+ "src": "src",
84
+ "width": "numbers",
85
+ "height": "numbers"
86
+ }
87
+ },
88
+ "figcaption": {
89
+ "rename_tag": "div"
90
+ },
91
+ "a": {
92
+ "check_attributes": {
93
+ "href": "href"
94
+ },
95
+ "set_attributes": {
96
+ "rel": "nofollow",
97
+ "target": "_blank"
98
+ }
99
+ },
100
+ "img": {
101
+ "check_attributes": {
102
+ "width": "numbers",
103
+ "height": "numbers",
104
+ "src": "dataURI",
105
+ "alt": "alt"
106
+ },
107
+ "add_class": {
108
+ "align": "align_img"
109
+ }
110
+ },
111
+ "rb": {
112
+ "rename_tag": "span"
113
+ },
114
+ "footer": {
115
+ "rename_tag": "div"
116
+ },
117
+ "noframes": {
118
+ "remove": 1
119
+ },
120
+ "abbr": {},
121
+ "u": {
122
+ remove:1
123
+ },
124
+ "bgsound": {
125
+ "remove": 1
126
+ },
127
+ "sup": {
128
+ "rename_tag": "span"
129
+ },
130
+ "address": {
131
+ "rename_tag": "div"
132
+ },
133
+ "basefont": {
134
+ "remove": 1
135
+ },
136
+ "nav": {
137
+ "rename_tag": "div"
138
+ },
139
+ "h1": {
140
+ "add_class": {
141
+ "align": "align_text"
142
+ }
143
+ },
144
+ "head": {
145
+ "remove": 1
146
+ },
147
+ "tbody": {
148
+ "add_class": {
149
+ "align": "align_text"
150
+ }
151
+ },
152
+ "dd": {
153
+ "rename_tag": "div"
154
+ },
155
+ "s": {
156
+ "rename_tag": "span"
157
+ },
158
+ "li": {},
159
+ "td": {
160
+ "check_attributes": {
161
+ "rowspan": "numbers",
162
+ "colspan": "numbers"
163
+ },
164
+ "add_class": {
165
+ "align": "align_text"
166
+ }
167
+ },
168
+ "object": {},
169
+ "div": {
170
+ "add_class": {
171
+ "align": "align_text"
172
+ }
173
+ },
174
+ "option": {
175
+ "rename_tag": "span"
176
+ },
177
+ "select": {
178
+ "rename_tag": "span"
179
+ },
180
+ "i": {},
181
+ "track": {
182
+ "remove": 1
183
+ },
184
+ "wbr": {
185
+ "remove": 1
186
+ },
187
+ "fieldset": {
188
+ "rename_tag": "div"
189
+ },
190
+ "big": {
191
+ "rename_tag": "span",
192
+ "set_class": "wysiwyg-font-size-larger"
193
+ },
194
+ "button": {
195
+ "rename_tag": "span"
196
+ },
197
+ "noscript": {
198
+ "remove": 1
199
+ },
200
+ "svg": {
201
+ "remove": 1
202
+ },
203
+ "input": {
204
+ "remove": 1
205
+ },
206
+ "table": {},
207
+ "keygen": {
208
+ "remove": 1
209
+ },
210
+ "h5": {
211
+ "add_class": {
212
+ "align": "align_text"
213
+ }
214
+ },
215
+ "meta": {
216
+ "remove": 1
217
+ },
218
+ "map": {
219
+ "rename_tag": "div"
220
+ },
221
+ "isindex": {
222
+ "remove": 1
223
+ },
224
+ "mark": {
225
+ "rename_tag": "span"
226
+ },
227
+ "caption": {
228
+ "add_class": {
229
+ "align": "align_text"
230
+ }
231
+ },
232
+ "tfoot": {
233
+ "add_class": {
234
+ "align": "align_text"
235
+ }
236
+ },
237
+ "base": {
238
+ "remove": 1
239
+ },
240
+ "video": {
241
+ "remove": 1
242
+ },
243
+ "strong": {},
244
+ "canvas": {
245
+ "remove": 1
246
+ },
247
+ "output": {
248
+ "rename_tag": "span"
249
+ },
250
+ "marquee": {
251
+ "rename_tag": "span"
252
+ },
253
+ "b": {
254
+ "rename_tag": "strong"
255
+ },
256
+ "q": {
257
+ "check_attributes": {
258
+ "cite": "url"
259
+ }
260
+ },
261
+ "applet": {
262
+ "remove": 1
263
+ },
264
+ "span": {},
265
+ "rp": {
266
+ "rename_tag": "span"
267
+ },
268
+ "spacer": {
269
+ "remove": 1
270
+ },
271
+ "source": {
272
+ "remove": 1
273
+ },
274
+ "aside": {
275
+ "rename_tag": "div"
276
+ },
277
+ "frame": {
278
+ "remove": 1
279
+ },
280
+ "section": {
281
+ "rename_tag": "div"
282
+ },
283
+ "body": {
284
+ "rename_tag": "div"
285
+ },
286
+ "ol": {},
287
+ "nobr": {
288
+ "rename_tag": "span"
289
+ },
290
+ "html": {
291
+ "rename_tag": "div"
292
+ },
293
+ "summary": {
294
+ "rename_tag": "span"
295
+ },
296
+ "var": {
297
+ "rename_tag": "span"
298
+ },
299
+ "del": {
300
+ "remove": 1
301
+ },
302
+ "blockquote": {
303
+ "check_attributes": {
304
+ "cite": "url"
305
+ }
306
+ },
307
+ "style": {
308
+ "remove": 1
309
+ },
310
+ "device": {
311
+ "remove": 1
312
+ },
313
+ "meter": {
314
+ "rename_tag": "span"
315
+ },
316
+ "h3": {
317
+ "add_class": {
318
+ "align": "align_text"
319
+ }
320
+ },
321
+ "textarea": {
322
+ "rename_tag": "span"
323
+ },
324
+ "embed": {
325
+ "remove": 1
326
+ },
327
+ "hgroup": {
328
+ "rename_tag": "div"
329
+ },
330
+ "font": {
331
+ "rename_tag": "span",
332
+ "add_class": {
333
+ "size": "size_font"
334
+ }
335
+ },
336
+ "tt": {
337
+ "rename_tag": "span"
338
+ },
339
+ "noembed": {
340
+ "remove": 1
341
+ },
342
+ "thead": {
343
+ "add_class": {
344
+ "align": "align_text"
345
+ }
346
+ },
347
+ "blink": {
348
+ "rename_tag": "span"
349
+ },
350
+ "plaintext": {
351
+ "rename_tag": "span"
352
+ },
353
+ "xml": {
354
+ "remove": 1
355
+ },
356
+ "h6": {
357
+ "add_class": {
358
+ "align": "align_text"
359
+ }
360
+ },
361
+ "param": {},
362
+ "th": {
363
+ "check_attributes": {
364
+ "rowspan": "numbers",
365
+ "colspan": "numbers"
366
+ },
367
+ "add_class": {
368
+ "align": "align_text"
369
+ }
370
+ },
371
+ "legend": {
372
+ "rename_tag": "span"
373
+ },
374
+ "hr": {},
375
+ "label": {
376
+ "rename_tag": "span"
377
+ },
378
+ "dl": {
379
+ "rename_tag": "div"
380
+ },
381
+ "kbd": {
382
+ "rename_tag": "span"
383
+ },
384
+ "listing": {
385
+ "rename_tag": "div"
386
+ },
387
+ "dt": {
388
+ "rename_tag": "span"
389
+ },
390
+ "nextid": {
391
+ "remove": 1
392
+ },
393
+ "pre": {},
394
+ "center": {
395
+ "rename_tag": "div",
396
+ "set_class": "wysiwyg-text-align-center"
397
+ },
398
+ "audio": {
399
+ "remove": 1
400
+ },
401
+ "datalist": {
402
+ "rename_tag": "span"
403
+ },
404
+ "samp": {
405
+ "rename_tag": "span"
406
+ },
407
+ "col": {
408
+ "remove": 1
409
+ },
410
+ "article": {
411
+ "rename_tag": "div"
412
+ },
413
+ "cite": {},
414
+ "link": {
415
+ "remove": 1
416
+ },
417
+ "script": {
418
+ "remove": 1
419
+ },
420
+ "bdo": {
421
+ "rename_tag": "span"
422
+ },
423
+ "menu": {
424
+ "rename_tag": "ul"
425
+ },
426
+ "colgroup": {
427
+ "remove": 1
428
+ },
429
+ "ruby": {
430
+ "rename_tag": "span"
431
+ },
432
+ "h2": {
433
+ "add_class": {
434
+ "align": "align_text"
435
+ }
436
+ },
437
+ "ins": {
438
+ "rename_tag": "span"
439
+ },
440
+ "p": {
441
+ "add_class": {
442
+ "align": "align_text"
443
+ }
444
+ },
445
+ "sub": {
446
+ "rename_tag": "span"
447
+ },
448
+ "comment": {
449
+ "remove": 1
450
+ },
451
+ "frameset": {
452
+ "remove": 1
453
+ },
454
+ "optgroup": {
455
+ "rename_tag": "span"
456
+ },
457
+ "header": {
458
+ "rename_tag": "div"
459
+ }
460
+ }
461
+ };
462
+
463
+ /**
464
+ * Drag And Drop Image Editor. Enables a drop-able DOM elements,
465
+ * Generates an image from dropped image file and enables image cropping via Jcrop
466
+ * @param element - target drag and drop DOM element
467
+ * @param options - options for image editor
468
+ * @return {Object}
469
+ * @constructor ImageEditor
470
+ */
471
+ var ImageEditor = function(element, options){
472
+
473
+ var dataURI = null,
474
+ options = options,
475
+ jcrop_api = null,
476
+ $dom = {
477
+ $element: $(element),
478
+ $canvas: null,
479
+ $img: null,
480
+ $ctx: null,
481
+ $input: options.input
482
+ };
483
+
484
+ $dom.$element.css({
485
+ 'width':options.width,
486
+ 'height':options.height,
487
+ 'overflow':'hidden',
488
+ 'text-align':'center'
489
+ });
490
+
491
+ /**
492
+ * Bind drag and drop events to $element
493
+ */
494
+ var bindEvents = function(){
495
+
496
+ // handle No-Op events for drag and drop
497
+ var noOpEvent = function(evt){
498
+ evt.stopPropagation();
499
+ evt.preventDefault();
500
+ }
501
+
502
+ $dom.$element.on('dragenter.dropImage', noOpEvent);
503
+ $dom.$element.on('dragexit.dropImage', noOpEvent);
504
+ $dom.$element.on('dragover.dropImage', noOpEvent);
505
+ $dom.$element.on('drop.dropImage', onDrop );
506
+ }
507
+
508
+ /**
509
+ * Handle drop event on $element
510
+ * @param evt - DOM drop event (jQuery)
511
+ */
512
+ var onDrop = function( evt ){
513
+ evt.stopPropagation();
514
+ evt.preventDefault();
515
+
516
+ var files = evt.originalEvent.dataTransfer.files;
517
+ if(files.length > 0){
518
+ var reader = new FileReader();
519
+ // init the reader event handlers
520
+ reader.onload = onFileReaderLoad;
521
+ // begin the read operation
522
+ reader.readAsDataURL(files[0])
523
+ }
524
+ }
525
+
526
+ /**
527
+ * Handle file reader load event.
528
+ * Get image data from file reader
529
+ * @param evt - FileReader load event
530
+ */
531
+ var onFileReaderLoad = function( evt ){
532
+ clear();
533
+ dataURI = evt.target.result;
534
+ startImageEditor();
535
+ }
536
+
537
+ /**
538
+ * Render image to drop zone and start jCorp editor
539
+ */
540
+ var startImageEditor = function(){
541
+ $dom.$img = $('<img />').attr('src', dataURI).appendTo($dom.$element);
542
+ $dom.$input.val(dataURI);
543
+
544
+ $dom.$img.Jcrop({
545
+ onSelect:imgFromCrop,
546
+ aspectRatio: options.aspectRatio
547
+ }, function(){
548
+ jcrop_api = this;
549
+ });
550
+ }
551
+
552
+ /**
553
+ * Generate an image from crop coordinates
554
+ * @param coords
555
+ */
556
+ var imgFromCrop = function(coords){
557
+ $dom.$ctx.clearRect(0,0,$dom.$ctx.canvas.width,$dom.$ctx.canvas.height);
558
+
559
+ $dom.$canvas.attr('width',coords.w).attr('height',coords.h);
560
+ $dom.$ctx.drawImage($dom.$img[0], coords.x, coords.y, coords.w, coords.h, 0, 0, coords.w, coords.h); //sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight
561
+ dataURI = $dom.$canvas[0].toDataURL('image/jpeg');
562
+ $dom.$input.val(dataURI);
563
+ }
564
+
565
+ /**
566
+ * Clears image and saved dataURI
567
+ */
568
+ var clear = function(){
569
+ dataURI = null;
570
+ if($dom.$img !== null){
571
+ jcrop_api.destroy();
572
+ $dom.$img.remove();
573
+ $dom.$img = null;
574
+ $dom.$input.val('');
575
+ }
576
+ }
577
+
578
+ /**
579
+ * Handle editor reopen from Wysiwyg
580
+ */
581
+ var reopen = function(){
582
+ var url = $dom.$input.val();
583
+ if(url.trim() !== ''){
584
+ clear();
585
+ dataURI = url;
586
+ startImageEditor();
587
+ }
588
+ }
589
+
590
+ /**
591
+ * Initialize the drag and drop object
592
+ */
593
+ var init = function(){
594
+ $dom.$canvas = $('<canvas></canvas>').css({
595
+ display:'none'
596
+ }).appendTo($('body'));
597
+
598
+ $dom.$ctx = $dom.$canvas[0].getContext('2d');
599
+ bindEvents();
600
+ }
601
+
602
+ init(); //initialize the image editor
603
+
604
+ // revealing module pattern
605
+ // reveal clear and init methods
606
+ return {
607
+ clear: function(){
608
+ clear();
609
+ },
610
+ reopen: function(){
611
+ reopen();
612
+ }
613
+ }
614
+ }
615
+
616
+ ImageEditor.prototype = {
617
+ constructor: ImageEditor,
618
+ $dataURI: null,
619
+ $img: null
620
+ }
621
+
622
+ /**
623
+ * Bootstrap and Drag & Drop enabled wysihtml editor
624
+ * @param textarea - textarea DOM element to turn into WYSIWYG editor
625
+ * @param options - editor and drag & drop options
626
+ * @constructor WysiHTML5
627
+ */
628
+ var WysiHTML5N = function(textarea, options){
629
+
630
+ // define editor toolbar HTML components
631
+ var toolbar = {
632
+ h1: '<li data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="h1" title="Insert headline 1" class="command btn">H1</li>',
633
+ h2: '<li data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="h2" title="Insert headline 2" class="command btn">H2</li>',
634
+ h3: '<li data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="h3" title="Insert headline 3" class="command btn">H3</li>',
635
+ p: '<li data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="p" title="Insert paragraph" class="command btn">P</li>',
636
+ bold: '<li data-wysihtml5-command="bold" title="Make text bold (CTRL + B)" class="command btn"><i class="icon-bold"></i></li>',
637
+ italic: '<li data-wysihtml5-command="italic" title="Make text italic (CTRL + I)" class="command btn"><i class="icon-italic"></i></li>',
638
+ ol: '<li data-wysihtml5-command="insertOrderedList" title="Insert an ordered list" class="command btn"><i class="icon-list-ol"></i></li>',
639
+ ul: '<li data-wysihtml5-command="insertUnorderedList" title="Insert an unordered list" class="command btn"><i class="icon-list-ul"></i></li>',
640
+ insertLink: '<li data-wysihtml5-command="createLink" title="Insert a link" class="command btn"><i class="icon-link"></i></li>',
641
+ insertImage: '<li data-wysihtml5-command="insertImage" title="Insert an image" class="command btn"><i class="icon-picture"></i></li>',
642
+ changeView: '<li data-wysihtml5-action="change_view" title="Show HTML" class="action btn">&lt;/&gt;</li>',
643
+ modals: {
644
+ insertLink:'<div class="modal" data-wysihtml5-dialog="createLink" style="display: none;">' +
645
+ '<div class="modal-header">' +
646
+ '<button type="button" class="close" data-wysihtml5-dialog-action="cancel" data-dismiss="modal">×</button>' +
647
+ '<h3>Insert Link</h3>' +
648
+ '</div>' +
649
+ '<div class="modal-body">' +
650
+ '<label>Link: <input data-wysihtml5-dialog-field="href" type="url" class="input-xlarge" placeholder="http://"></label>' +
651
+ '</div>' +
652
+ '<div class="modal-footer">' +
653
+ '<a class="btn btn-primary" data-wysihtml5-dialog-action="save">OK</a>' +
654
+ '<a class="btn" data-wysihtml5-dialog-action="cancel" data-dismiss="modal">Cancel</a>' +
655
+ '</div>' +
656
+ '</div>',
657
+ insertImage:'<div class="modal" data-wysihtml5-dialog="insertImage" style="display: none;">' +
658
+ '<div class="modal-header">' +
659
+ '<button type="button" class="close" data-wysihtml5-dialog-action="cancel" data-dismiss="modal">×</button>' +
660
+ '<h3>Insert Image</h3>' +
661
+ '</div>' +
662
+ '<div class="modal-body">' +
663
+ '<div class="drop-image"></div>' +
664
+ '<input data-wysihtml5-dialog-field="src" class="image-src-field" type="hidden" />' +
665
+ '</div>' +
666
+ '<div class="modal-footer">' +
667
+ '<a class="btn btn-primary" data-wysihtml5-dialog-action="save" class="save-image">OK</a>' +
668
+ '<a class="btn" data-wysihtml5-dialog-action="cancel" data-dismiss="modal">Cancel</a>' +
669
+ '</div>' +
670
+ '</div>'
671
+ }
672
+ };
673
+
674
+ var imageEditor,
675
+ textEditor,
676
+ $dom = {
677
+ $textarea: $(textarea),
678
+ $toolbar: null
679
+ };
680
+
681
+ /**
682
+ * Build the toolbar and append before textarea
683
+ */
684
+ var buildToolbar = function(){
685
+ var toolbarHTML = ['<ul class="btn-group">'];
686
+ var modals = [];
687
+
688
+ options.toolbar.forEach(function(key){
689
+ if(toolbar[key]){
690
+ toolbarHTML.push(toolbar[key]);
691
+ }
692
+ if(toolbar.modals[key]){
693
+ modals.push(toolbar.modals[key]);
694
+ }
695
+ });
696
+
697
+ toolbarHTML.push('</ul>');
698
+
699
+ $dom.$toolbar = $('<div class="wysiHTML5-toolbar"></div>').html(toolbarHTML.concat(modals).join('')).insertBefore($dom.$textarea);
700
+ }
701
+
702
+ /**
703
+ * Initialize the WysiHTML5 Editor
704
+ */
705
+ var initEditor = function(){
706
+ textEditor = new wysihtml5.Editor($dom.$textarea[0], {
707
+ toolbar: $dom.$toolbar[0],
708
+ stylesheets: options.stylesheets,
709
+ parserRules: options.parserRules
710
+ });
711
+
712
+ if(options.toolbar.indexOf('insertImage') > -1){
713
+ initImageEditor();
714
+ }
715
+ }
716
+
717
+ /**
718
+ * Initialize the image editor for the Wysiwyg
719
+ */
720
+ var initImageEditor = function(){
721
+ var el = $dom.$toolbar.find('.drop-image');
722
+ var opts = $.extend({input: $dom.$toolbar.find('input.image-src-field')}, options.imageEditor);
723
+ imageEditor = new ImageEditor(el, opts);
724
+
725
+ // clear image editor on insertImage event
726
+ $dom.$toolbar.find('[data-wysihtml5-command="insertImage"]').click(function(){
727
+ imageEditor.clear();
728
+ });
729
+
730
+ textEditor.on('show:dialog', function(options){
731
+ if(options.command === 'insertImage'){
732
+ imageEditor.reopen();
733
+ }
734
+ }).on('cancel:dialog', function(options){
735
+ if(options.command === 'insertImage'){
736
+ imageEditor.clear();
737
+ }
738
+ });
739
+ }
740
+
741
+ /**
742
+ * Initialize the editor plugin
743
+ */
744
+ function init(){
745
+ buildToolbar();
746
+ initEditor();
747
+ }
748
+
749
+ init(); //initialize instance
750
+ }
751
+
752
+ WysiHTML5N.prototype = {
753
+ constructor: WysiHTML5N
754
+ }
755
+
756
+ $.fn.wysiHTML5N = function(option){
757
+ return this.each(function () {
758
+ var $this = $(this),
759
+ data = $this.data('wysiHTML5N'),
760
+ options = $.extend({}, $.fn.wysiHTML5N.defaults, typeof option == 'object' && option);
761
+ if (!data){
762
+ $this.data('wysiHTML5N', (data = new WysiHTML5N(this, options)))
763
+ }
764
+ if (typeof option == 'string'){
765
+ data[option]();
766
+ }
767
+ });
768
+ }
769
+
770
+ $.fn.wysiHTML5N.defaults = {
771
+ toolbar: [
772
+ 'h1', 'h2', 'h3', 'p', 'bold', 'italic', 'unordered', 'ordered', 'insertLink', 'insertImage', 'changeView'
773
+ ],
774
+ stylesheets: [],
775
+ parserRules: parserRules,
776
+ imageEditor: {
777
+ aspectRatio:null,
778
+ width:530,
779
+ height:300
780
+ }
781
+ }
782
+
783
+ }(window.jQuery));