rails-bootstrap-markdown 1.0.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +4 -1
- data/app/assets/javascripts/bootstrap-markdown-bundle.js +5 -0
- data/app/assets/javascripts/bootstrap-markdown.js +482 -100
- data/app/assets/javascripts/he.js +329 -0
- data/app/assets/javascripts/markdown.js +1477 -1379
- data/app/assets/javascripts/to-markdown.js +10 -5
- data/app/assets/stylesheets/bootstrap-markdown.css.scss +168 -7
- data/lib/rails-bootstrap-markdown/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d90f4705ea4630c7e176d8d07efcb18e4faf4ce
|
4
|
+
data.tar.gz: 84096cdc58399fc311942bc9a0483bfe59fe4d83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86a34516bbadc8ec866f3663b24f7796d07c37d6738487dd5447c9c2f43b859f1f15480c1cc542cac3733ca47896d227f619fb5b21bac05b3143811b2043748d
|
7
|
+
data.tar.gz: dd2221974b223e8a2a9b74c07a18564bf18900dd6ecf189626a6b47bde0354e960dc98b75fe160e0ddb966493b6deae84163c4c4e561bb011c2499021b751f6f
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -7,6 +7,7 @@ A rails gem for [Bootstrap Markdown](http://toopay.github.io/bootstrap-markdown/
|
|
7
7
|
- http://toopay.github.io/bootstrap-markdown/
|
8
8
|
- https://github.com/domchristie/to-markdown
|
9
9
|
- https://github.com/evilstreak/markdown-js
|
10
|
+
- https://github.com/mathiasbynens/he
|
10
11
|
|
11
12
|
## Installation
|
12
13
|
|
@@ -32,8 +33,10 @@ Or install it yourself as:
|
|
32
33
|
|
33
34
|
### Javascript
|
34
35
|
|
36
|
+
To require all 3rd party libraries at once, use:
|
37
|
+
|
35
38
|
```
|
36
|
-
//= require bootstrap-markdown
|
39
|
+
//= require bootstrap-markdown-bundle
|
37
40
|
```
|
38
41
|
|
39
42
|
## Contributing
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/* ===================================================
|
2
|
-
* bootstrap-markdown.js v2.
|
2
|
+
* bootstrap-markdown.js v2.6.0
|
3
3
|
* http://github.com/toopay/bootstrap-markdown
|
4
4
|
* ===================================================
|
5
|
-
* Copyright 2013 Taufan Aditya
|
5
|
+
* Copyright 2013-2014 Taufan Aditya
|
6
6
|
*
|
7
7
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
* you may not use this file except in compliance with the License.
|
@@ -17,9 +17,6 @@
|
|
17
17
|
* limitations under the License.
|
18
18
|
* ========================================================== */
|
19
19
|
|
20
|
-
//= require markdown
|
21
|
-
//= require to-markdown
|
22
|
-
|
23
20
|
!function ($) {
|
24
21
|
|
25
22
|
"use strict"; // jshint ;_;
|
@@ -30,17 +27,18 @@
|
|
30
27
|
|
31
28
|
var Markdown = function (element, options) {
|
32
29
|
// Class Properties
|
33
|
-
this.$ns
|
34
|
-
this.$element
|
35
|
-
this.$editable
|
36
|
-
this.$options
|
37
|
-
this.$oldContent
|
38
|
-
this.$isPreview
|
39
|
-
this.$
|
40
|
-
this.$
|
41
|
-
this.$
|
42
|
-
this.$
|
43
|
-
this.$
|
30
|
+
this.$ns = 'bootstrap-markdown'
|
31
|
+
this.$element = $(element)
|
32
|
+
this.$editable = {el:null, type:null,attrKeys:[], attrValues:[], content:null}
|
33
|
+
this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data(), this.$element.data('options'))
|
34
|
+
this.$oldContent = null
|
35
|
+
this.$isPreview = false
|
36
|
+
this.$isFullscreen = false
|
37
|
+
this.$editor = null
|
38
|
+
this.$textarea = null
|
39
|
+
this.$handler = []
|
40
|
+
this.$callback = []
|
41
|
+
this.$nextTab = []
|
44
42
|
|
45
43
|
this.showEditor()
|
46
44
|
}
|
@@ -87,31 +85,37 @@
|
|
87
85
|
var button = buttons[z],
|
88
86
|
buttonToggle = '',
|
89
87
|
buttonHandler = ns+'-'+button.name,
|
88
|
+
buttonIcon = this.__getIcon(button.icon),
|
90
89
|
btnText = button.btnText ? button.btnText : '',
|
91
90
|
btnClass = button.btnClass ? button.btnClass : 'btn',
|
92
|
-
tabIndex = button.tabIndex ? button.tabIndex : '-1'
|
91
|
+
tabIndex = button.tabIndex ? button.tabIndex : '-1',
|
92
|
+
hotkey = typeof button.hotkey !== 'undefined' ? button.hotkey : '',
|
93
|
+
hotkeyCaption = typeof jQuery.hotkeys !== 'undefined' && hotkey !== '' ? ' ('+hotkey+')' : ''
|
93
94
|
|
94
95
|
if (button.toggle == true) {
|
95
96
|
buttonToggle = ' data-toggle="button"'
|
96
97
|
}
|
97
98
|
|
98
99
|
// Attach the button object
|
99
|
-
btnGroupContainer.append('<button class="'
|
100
|
+
btnGroupContainer.append('<button type="button" class="'
|
100
101
|
+btnClass
|
101
102
|
+' btn-default btn-sm" title="'
|
102
|
-
+button.title
|
103
|
+
+this.__localize(button.title)
|
104
|
+
+hotkeyCaption
|
103
105
|
+'" tabindex="'
|
104
106
|
+tabIndex
|
105
107
|
+'" data-provider="'
|
106
108
|
+ns
|
107
109
|
+'" data-handler="'
|
108
110
|
+buttonHandler
|
111
|
+
+'" data-hotkey="'
|
112
|
+
+hotkey
|
109
113
|
+'"'
|
110
114
|
+buttonToggle
|
111
115
|
+'><span class="'
|
112
|
-
+
|
116
|
+
+buttonIcon
|
113
117
|
+'"></span> '
|
114
|
-
+btnText
|
118
|
+
+this.__localize(btnText)
|
115
119
|
+'</button>')
|
116
120
|
|
117
121
|
// Register handler and callback
|
@@ -133,12 +137,15 @@
|
|
133
137
|
rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows
|
134
138
|
|
135
139
|
this.$textarea.attr('rows',rowsVal)
|
136
|
-
this.$
|
140
|
+
if (this.$options.resize) {
|
141
|
+
this.$textarea.css('resize',this.$options.resize)
|
142
|
+
}
|
137
143
|
|
138
144
|
this.$textarea
|
139
145
|
.on('focus', $.proxy(this.focus, this))
|
140
146
|
.on('keypress', $.proxy(this.keypress, this))
|
141
147
|
.on('keyup', $.proxy(this.keyup, this))
|
148
|
+
.on('change', $.proxy(this.change, this))
|
142
149
|
|
143
150
|
if (this.eventSupported('keydown')) {
|
144
151
|
this.$textarea.on('keydown', $.proxy(this.keydown, this))
|
@@ -161,6 +168,9 @@
|
|
161
168
|
|
162
169
|
callbackHandler(this)
|
163
170
|
|
171
|
+
// Trigger onChange for each button handle
|
172
|
+
this.change(this);
|
173
|
+
|
164
174
|
// Unless it was the save handler,
|
165
175
|
// focusin the textarea
|
166
176
|
if (handlerName.indexOf('cmdSave') < 0) {
|
@@ -170,6 +180,40 @@
|
|
170
180
|
e.preventDefault()
|
171
181
|
}
|
172
182
|
|
183
|
+
, __localize: function(string) {
|
184
|
+
var messages = $.fn.markdown.messages,
|
185
|
+
language = this.$options.language
|
186
|
+
if (
|
187
|
+
typeof messages !== 'undefined' &&
|
188
|
+
typeof messages[language] !== 'undefined' &&
|
189
|
+
typeof messages[language][string] !== 'undefined'
|
190
|
+
) {
|
191
|
+
return messages[language][string];
|
192
|
+
}
|
193
|
+
return string;
|
194
|
+
}
|
195
|
+
|
196
|
+
, __getIcon: function(src) {
|
197
|
+
return typeof src == 'object' ? src[this.$options.iconlibrary] : src;
|
198
|
+
}
|
199
|
+
|
200
|
+
, setFullscreen: function(mode) {
|
201
|
+
var $editor = this.$editor,
|
202
|
+
$textarea = this.$textarea
|
203
|
+
|
204
|
+
if (mode === true) {
|
205
|
+
$editor.addClass('md-fullscreen-mode')
|
206
|
+
$('body').addClass('md-nooverflow')
|
207
|
+
this.$options.onFullscreen(this)
|
208
|
+
} else {
|
209
|
+
$editor.removeClass('md-fullscreen-mode')
|
210
|
+
$('body').removeClass('md-nooverflow')
|
211
|
+
}
|
212
|
+
|
213
|
+
this.$isFullscreen = mode;
|
214
|
+
$textarea.focus()
|
215
|
+
}
|
216
|
+
|
173
217
|
, showEditor: function() {
|
174
218
|
var instance = this,
|
175
219
|
textarea,
|
@@ -195,14 +239,34 @@
|
|
195
239
|
'class': 'md-header btn-toolbar'
|
196
240
|
})
|
197
241
|
|
198
|
-
//
|
199
|
-
|
200
|
-
|
242
|
+
// Merge the main & additional button groups together
|
243
|
+
var allBtnGroups = []
|
244
|
+
if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0])
|
245
|
+
if (options.additionalButtons.length > 0) allBtnGroups = allBtnGroups.concat(options.additionalButtons[0])
|
246
|
+
|
247
|
+
// Reduce and/or reorder the button groups
|
248
|
+
if (options.reorderButtonGroups.length > 0) {
|
249
|
+
allBtnGroups = allBtnGroups
|
250
|
+
.filter(function(btnGroup) {
|
251
|
+
return options.reorderButtonGroups.indexOf(btnGroup.name) > -1
|
252
|
+
})
|
253
|
+
.sort(function(a, b) {
|
254
|
+
if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1
|
255
|
+
if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1
|
256
|
+
return 0
|
257
|
+
})
|
258
|
+
}
|
259
|
+
|
260
|
+
// Build the buttons
|
261
|
+
if (allBtnGroups.length > 0) {
|
262
|
+
editorHeader = this.__buildButtons([allBtnGroups], editorHeader)
|
201
263
|
}
|
202
264
|
|
203
|
-
|
204
|
-
|
205
|
-
|
265
|
+
if (options.fullscreen.enable) {
|
266
|
+
editorHeader.append('<div class="md-controls"><a class="md-control md-control-fullscreen" href="#"><span class="'+this.__getIcon(options.fullscreen.icons.fullscreenOn)+'"></span></a></div>').on('click', '.md-control-fullscreen', function(e) {
|
267
|
+
e.preventDefault();
|
268
|
+
instance.setFullscreen(true)
|
269
|
+
})
|
206
270
|
}
|
207
271
|
|
208
272
|
editor.append(editorHeader)
|
@@ -239,12 +303,15 @@
|
|
239
303
|
container.replaceWith(editor)
|
240
304
|
}
|
241
305
|
|
242
|
-
|
243
|
-
if (options.savable) {
|
244
|
-
var editorFooter = $('<div/>', {
|
306
|
+
var editorFooter = $('<div/>', {
|
245
307
|
'class': 'md-footer'
|
246
308
|
}),
|
247
|
-
|
309
|
+
createFooter = false,
|
310
|
+
footer = ''
|
311
|
+
// Create the footer if savable
|
312
|
+
if (options.savable) {
|
313
|
+
createFooter = true;
|
314
|
+
var saveHandler = 'cmdSave'
|
248
315
|
|
249
316
|
// Register handler and callback
|
250
317
|
handler.push(saveHandler)
|
@@ -254,21 +321,43 @@
|
|
254
321
|
+ns
|
255
322
|
+'" data-handler="'
|
256
323
|
+saveHandler
|
257
|
-
+'"><i class="icon icon-white icon-ok"></i>
|
324
|
+
+'"><i class="icon icon-white icon-ok"></i> '
|
325
|
+
+this.__localize('Save')
|
326
|
+
+'</button>')
|
327
|
+
|
258
328
|
|
259
|
-
editor.append(editorFooter)
|
260
329
|
}
|
261
330
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
331
|
+
footer = typeof options.footer === 'function' ? options.footer(this) : options.footer
|
332
|
+
|
333
|
+
if ($.trim(footer) !== '') {
|
334
|
+
createFooter = true;
|
335
|
+
editorFooter.append(footer);
|
336
|
+
}
|
337
|
+
|
338
|
+
if (createFooter) editor.append(editorFooter)
|
339
|
+
|
340
|
+
// Set width
|
341
|
+
if (options.width && options.width !== 'inherit') {
|
342
|
+
if (jQuery.isNumeric(options.width)) {
|
343
|
+
editor.css('display', 'table')
|
344
|
+
textarea.css('width', options.width + 'px')
|
345
|
+
} else {
|
346
|
+
editor.addClass(options.width)
|
270
347
|
}
|
271
|
-
}
|
348
|
+
}
|
349
|
+
|
350
|
+
// Set height
|
351
|
+
if (options.height && options.height !== 'inherit') {
|
352
|
+
if (jQuery.isNumeric(options.height)) {
|
353
|
+
var height = options.height
|
354
|
+
if (editorHeader) height = Math.max(0, height - editorHeader.outerHeight())
|
355
|
+
if (editorFooter) height = Math.max(0, height - editorFooter.outerHeight())
|
356
|
+
textarea.css('height', height + 'px')
|
357
|
+
} else {
|
358
|
+
editor.addClass(options.height)
|
359
|
+
}
|
360
|
+
}
|
272
361
|
|
273
362
|
// Reference
|
274
363
|
this.$editor = editor
|
@@ -282,6 +371,30 @@
|
|
282
371
|
this.$editor.attr('id',(new Date).getTime())
|
283
372
|
this.$editor.on('click', '[data-provider="bootstrap-markdown"]', $.proxy(this.__handle, this))
|
284
373
|
|
374
|
+
if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
|
375
|
+
this.$editor.addClass('md-editor-disabled');
|
376
|
+
this.disableButtons('all');
|
377
|
+
}
|
378
|
+
|
379
|
+
if (this.eventSupported('keydown') && typeof jQuery.hotkeys === 'object') {
|
380
|
+
editorHeader.find('[data-provider="bootstrap-markdown"]').each(function() {
|
381
|
+
var $button = $(this),
|
382
|
+
hotkey = $button.attr('data-hotkey')
|
383
|
+
if (hotkey.toLowerCase() !== '') {
|
384
|
+
textarea.bind('keydown', hotkey, function() {
|
385
|
+
$button.trigger('click')
|
386
|
+
return false;
|
387
|
+
})
|
388
|
+
}
|
389
|
+
})
|
390
|
+
}
|
391
|
+
|
392
|
+
if (options.initialstate === 'preview') {
|
393
|
+
this.showPreview();
|
394
|
+
} else if (options.initialstate === 'fullscreen' && options.fullscreen.enable) {
|
395
|
+
this.setFullscreen(true)
|
396
|
+
}
|
397
|
+
|
285
398
|
} else {
|
286
399
|
this.$editor.show()
|
287
400
|
}
|
@@ -291,15 +404,60 @@
|
|
291
404
|
this.$editor.addClass('active')
|
292
405
|
}
|
293
406
|
|
407
|
+
if (options.fullscreen.enable && options.fullscreen !== false) {
|
408
|
+
this.$editor.append('\
|
409
|
+
<div class="md-fullscreen-controls">\
|
410
|
+
<a href="#" class="switch-theme" title="Switch themes"><span class="'+this.__getIcon(options.fullscreen.icons.switchTheme)+'"></span></a>\
|
411
|
+
<a href="#" class="exit-fullscreen" title="Exit fullscreen"><span class="'+this.__getIcon(options.fullscreen.icons.fullscreenOff)+'"></span></a>\
|
412
|
+
</div>')
|
413
|
+
|
414
|
+
this.$editor.on('click', '.exit-fullscreen', function(e) {
|
415
|
+
e.preventDefault()
|
416
|
+
instance.setFullscreen(false)
|
417
|
+
})
|
418
|
+
|
419
|
+
this.$editor.on('click', '.switch-theme', function(e) {
|
420
|
+
e.preventDefault()
|
421
|
+
instance.$editor.toggleClass('theme-dark')
|
422
|
+
})
|
423
|
+
}
|
424
|
+
|
425
|
+
// hide hidden buttons from options
|
426
|
+
this.hideButtons(options.hiddenButtons)
|
427
|
+
|
428
|
+
// disable disabled buttons from options
|
429
|
+
this.disableButtons(options.disabledButtons)
|
430
|
+
|
294
431
|
// Trigger the onShow hook
|
295
432
|
options.onShow(this)
|
296
433
|
|
297
434
|
return this
|
298
435
|
}
|
299
436
|
|
437
|
+
, parseContent: function() {
|
438
|
+
var content,
|
439
|
+
callbackContent = this.$options.onPreview(this) // Try to get the content from callback
|
440
|
+
|
441
|
+
if (typeof callbackContent == 'string') {
|
442
|
+
// Set the content based by callback content
|
443
|
+
content = callbackContent
|
444
|
+
} else {
|
445
|
+
// Set the content
|
446
|
+
var val = this.$textarea.val();
|
447
|
+
if(typeof markdown == 'object') {
|
448
|
+
content = markdown.toHTML(val);
|
449
|
+
}else if(typeof marked == 'function') {
|
450
|
+
content = marked(val);
|
451
|
+
} else {
|
452
|
+
content = val;
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
return content;
|
457
|
+
}
|
458
|
+
|
300
459
|
, showPreview: function() {
|
301
460
|
var options = this.$options,
|
302
|
-
callbackContent = options.onPreview(this), // Try to get the content from callback
|
303
461
|
container = this.$textarea,
|
304
462
|
afterContainer = container.next(),
|
305
463
|
replacementContainer = $('<div/>',{'class':'md-preview','data-provider':'markdown-preview'}),
|
@@ -310,13 +468,7 @@
|
|
310
468
|
// Disable all buttons
|
311
469
|
this.disableButtons('all').enableButtons('cmdPreview')
|
312
470
|
|
313
|
-
|
314
|
-
// Set the content based by callback content
|
315
|
-
content = callbackContent
|
316
|
-
} else {
|
317
|
-
// Set the content
|
318
|
-
content = (typeof markdown == 'object') ? markdown.toHTML(container.val()) : container.val()
|
319
|
-
}
|
471
|
+
content = this.parseContent()
|
320
472
|
|
321
473
|
// Build preview element
|
322
474
|
replacementContainer.html(content)
|
@@ -329,12 +481,27 @@
|
|
329
481
|
container.parent().append(replacementContainer)
|
330
482
|
}
|
331
483
|
|
484
|
+
// Set the preview element dimensions
|
485
|
+
replacementContainer.css({
|
486
|
+
width: container.outerWidth() + 'px',
|
487
|
+
height: container.outerHeight() + 'px'
|
488
|
+
})
|
489
|
+
|
490
|
+
if (this.$options.resize) {
|
491
|
+
replacementContainer.css('resize',this.$options.resize)
|
492
|
+
}
|
493
|
+
|
332
494
|
// Hide the last-active textarea
|
333
495
|
container.hide()
|
334
496
|
|
335
497
|
// Attach the editor instances
|
336
498
|
replacementContainer.data('markdown',this)
|
337
499
|
|
500
|
+
if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
|
501
|
+
this.$editor.addClass('md-editor-disabled');
|
502
|
+
this.disableButtons('all');
|
503
|
+
}
|
504
|
+
|
338
505
|
return this
|
339
506
|
}
|
340
507
|
|
@@ -350,6 +517,8 @@
|
|
350
517
|
|
351
518
|
// Enable all buttons
|
352
519
|
this.enableButtons('all')
|
520
|
+
// Disable configured disabled buttons
|
521
|
+
this.disableButtons(this.$options.disabledButtons)
|
353
522
|
|
354
523
|
// Back to the editor
|
355
524
|
this.$textarea.show()
|
@@ -477,7 +646,7 @@
|
|
477
646
|
this.$nextTab.push(function(){
|
478
647
|
return that.findSelection(start)
|
479
648
|
})
|
480
|
-
} else if (typeof start == '
|
649
|
+
} else if (typeof start == 'number' && typeof end == 'number') {
|
481
650
|
var oldSelection = this.getSelection()
|
482
651
|
|
483
652
|
this.setSelection(start,end)
|
@@ -489,24 +658,70 @@
|
|
489
658
|
return
|
490
659
|
}
|
491
660
|
|
492
|
-
,
|
493
|
-
var
|
494
|
-
|
661
|
+
, __parseButtonNameParam: function(nameParam) {
|
662
|
+
var buttons = []
|
663
|
+
|
664
|
+
if (typeof nameParam == 'string') {
|
665
|
+
buttons.push(nameParam)
|
666
|
+
} else {
|
667
|
+
buttons = nameParam
|
495
668
|
}
|
496
669
|
|
497
|
-
|
670
|
+
return buttons
|
671
|
+
}
|
498
672
|
|
499
|
-
|
673
|
+
, enableButtons: function(name) {
|
674
|
+
var buttons = this.__parseButtonNameParam(name),
|
675
|
+
that = this
|
676
|
+
|
677
|
+
$.each(buttons, function(i, v) {
|
678
|
+
that.__alterButtons(buttons[i], function (el) {
|
679
|
+
el.removeAttr('disabled')
|
680
|
+
});
|
681
|
+
})
|
682
|
+
|
683
|
+
return this;
|
500
684
|
}
|
501
685
|
|
502
686
|
, disableButtons: function(name) {
|
503
|
-
var
|
504
|
-
|
505
|
-
}
|
687
|
+
var buttons = this.__parseButtonNameParam(name),
|
688
|
+
that = this
|
506
689
|
|
507
|
-
|
690
|
+
$.each(buttons, function(i, v) {
|
691
|
+
that.__alterButtons(buttons[i], function (el) {
|
692
|
+
el.attr('disabled','disabled')
|
693
|
+
});
|
694
|
+
})
|
695
|
+
|
696
|
+
return this;
|
697
|
+
}
|
698
|
+
|
699
|
+
, hideButtons: function(name) {
|
700
|
+
var buttons = this.__parseButtonNameParam(name),
|
701
|
+
that = this
|
702
|
+
|
703
|
+
$.each(buttons, function(i, v) {
|
704
|
+
that.__alterButtons(buttons[i], function (el) {
|
705
|
+
el.addClass('hidden');
|
706
|
+
});
|
707
|
+
})
|
708
|
+
|
709
|
+
return this;
|
710
|
+
|
711
|
+
}
|
712
|
+
|
713
|
+
, showButtons: function(name) {
|
714
|
+
var buttons = this.__parseButtonNameParam(name),
|
715
|
+
that = this
|
716
|
+
|
717
|
+
$.each(buttons, function(i, v) {
|
718
|
+
that.__alterButtons(buttons[i], function (el) {
|
719
|
+
el.removeClass('hidden');
|
720
|
+
});
|
721
|
+
})
|
722
|
+
|
723
|
+
return this;
|
508
724
|
|
509
|
-
return this
|
510
725
|
}
|
511
726
|
|
512
727
|
, eventSupported: function(eventName) {
|
@@ -518,16 +733,6 @@
|
|
518
733
|
return isSupported
|
519
734
|
}
|
520
735
|
|
521
|
-
, keydown: function (e) {
|
522
|
-
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
|
523
|
-
this.keyup(e)
|
524
|
-
}
|
525
|
-
|
526
|
-
, keypress: function (e) {
|
527
|
-
if (this.suppressKeyPressRepeat) return
|
528
|
-
this.keyup(e)
|
529
|
-
}
|
530
|
-
|
531
736
|
, keyup: function (e) {
|
532
737
|
var blocked = false
|
533
738
|
switch(e.keyCode) {
|
@@ -568,7 +773,10 @@
|
|
568
773
|
break
|
569
774
|
|
570
775
|
case 13: // enter
|
776
|
+
blocked = false
|
777
|
+
break
|
571
778
|
case 27: // escape
|
779
|
+
if (this.$isFullscreen) this.setFullscreen(false)
|
572
780
|
blocked = false
|
573
781
|
break
|
574
782
|
|
@@ -580,7 +788,14 @@
|
|
580
788
|
e.stopPropagation()
|
581
789
|
e.preventDefault()
|
582
790
|
}
|
583
|
-
|
791
|
+
|
792
|
+
this.$options.onChange(this)
|
793
|
+
}
|
794
|
+
|
795
|
+
, change: function(e) {
|
796
|
+
this.$options.onChange(this);
|
797
|
+
return this;
|
798
|
+
}
|
584
799
|
|
585
800
|
, focus: function (e) {
|
586
801
|
var options = this.$options,
|
@@ -605,6 +820,9 @@
|
|
605
820
|
}
|
606
821
|
})
|
607
822
|
|
823
|
+
// Trigger the onFocus hook
|
824
|
+
options.onFocus(this);
|
825
|
+
|
608
826
|
return this
|
609
827
|
}
|
610
828
|
|
@@ -663,6 +881,8 @@
|
|
663
881
|
})
|
664
882
|
}
|
665
883
|
|
884
|
+
$.fn.markdown.messages = {}
|
885
|
+
|
666
886
|
$.fn.markdown.defaults = {
|
667
887
|
/* Editor Properties */
|
668
888
|
autofocus: false,
|
@@ -670,6 +890,10 @@
|
|
670
890
|
savable:false,
|
671
891
|
width: 'inherit',
|
672
892
|
height: 'inherit',
|
893
|
+
resize: 'none',
|
894
|
+
iconlibrary: 'glyph',
|
895
|
+
language: 'en',
|
896
|
+
initialstate: 'editor',
|
673
897
|
|
674
898
|
/* Buttons Properties */
|
675
899
|
buttons: [
|
@@ -677,15 +901,16 @@
|
|
677
901
|
name: 'groupFont',
|
678
902
|
data: [{
|
679
903
|
name: 'cmdBold',
|
904
|
+
hotkey: 'Ctrl+B',
|
680
905
|
title: 'Bold',
|
681
|
-
icon: 'glyphicon glyphicon-bold',
|
906
|
+
icon: { glyph: 'glyphicon glyphicon-bold', fa: 'fa fa-bold', 'fa-3': 'icon-bold' },
|
682
907
|
callback: function(e){
|
683
908
|
// Give/remove ** surround the selection
|
684
909
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
685
910
|
|
686
911
|
if (selected.length == 0) {
|
687
912
|
// Give extra word
|
688
|
-
chunk = 'strong text'
|
913
|
+
chunk = e.__localize('strong text')
|
689
914
|
} else {
|
690
915
|
chunk = selected.text
|
691
916
|
}
|
@@ -707,14 +932,15 @@
|
|
707
932
|
},{
|
708
933
|
name: 'cmdItalic',
|
709
934
|
title: 'Italic',
|
710
|
-
|
935
|
+
hotkey: 'Ctrl+I',
|
936
|
+
icon: { glyph: 'glyphicon glyphicon-italic', fa: 'fa fa-italic', 'fa-3': 'icon-italic' },
|
711
937
|
callback: function(e){
|
712
938
|
// Give/remove * surround the selection
|
713
939
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
714
940
|
|
715
941
|
if (selected.length == 0) {
|
716
942
|
// Give extra word
|
717
|
-
chunk = 'emphasized text'
|
943
|
+
chunk = e.__localize('emphasized text')
|
718
944
|
} else {
|
719
945
|
chunk = selected.text
|
720
946
|
}
|
@@ -736,16 +962,17 @@
|
|
736
962
|
},{
|
737
963
|
name: 'cmdHeading',
|
738
964
|
title: 'Heading',
|
739
|
-
|
965
|
+
hotkey: 'Ctrl+H',
|
966
|
+
icon: { glyph: 'glyphicon glyphicon-header', fa: 'fa fa-font', 'fa-3': 'icon-font' },
|
740
967
|
callback: function(e){
|
741
968
|
// Append/remove ### surround the selection
|
742
969
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent(), pointer, prevChar
|
743
970
|
|
744
971
|
if (selected.length == 0) {
|
745
972
|
// Give extra word
|
746
|
-
chunk = 'heading text'
|
973
|
+
chunk = e.__localize('heading text')
|
747
974
|
} else {
|
748
|
-
chunk = selected.text
|
975
|
+
chunk = selected.text + '\n';
|
749
976
|
}
|
750
977
|
|
751
978
|
// transform selection and set the cursor into chunked text
|
@@ -754,12 +981,12 @@
|
|
754
981
|
e.setSelection(selected.start-pointer,selected.end)
|
755
982
|
e.replaceSelection(chunk)
|
756
983
|
cursor = selected.start-pointer
|
757
|
-
} else if (prevChar = content.substr(selected.start-1,1), !!prevChar && prevChar != '\n') {
|
758
|
-
e.replaceSelection('\n\n### '+chunk
|
984
|
+
} else if (selected.start > 0 && (prevChar = content.substr(selected.start-1,1), !!prevChar && prevChar != '\n')) {
|
985
|
+
e.replaceSelection('\n\n### '+chunk)
|
759
986
|
cursor = selected.start+6
|
760
987
|
} else {
|
761
988
|
// Empty string before element
|
762
|
-
e.replaceSelection('### '+chunk
|
989
|
+
e.replaceSelection('### '+chunk)
|
763
990
|
cursor = selected.start+4
|
764
991
|
}
|
765
992
|
|
@@ -772,21 +999,22 @@
|
|
772
999
|
data: [{
|
773
1000
|
name: 'cmdUrl',
|
774
1001
|
title: 'URL/Link',
|
775
|
-
|
1002
|
+
hotkey: 'Ctrl+L',
|
1003
|
+
icon: { glyph: 'glyphicon glyphicon-link', fa: 'fa fa-link', 'fa-3': 'icon-link' },
|
776
1004
|
callback: function(e){
|
777
1005
|
// Give [] surround the selection and prepend the link
|
778
1006
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent(), link
|
779
1007
|
|
780
1008
|
if (selected.length == 0) {
|
781
1009
|
// Give extra word
|
782
|
-
chunk = 'enter link description here'
|
1010
|
+
chunk = e.__localize('enter link description here')
|
783
1011
|
} else {
|
784
1012
|
chunk = selected.text
|
785
1013
|
}
|
786
1014
|
|
787
|
-
link = prompt('Insert Hyperlink','http://')
|
1015
|
+
link = prompt(e.__localize('Insert Hyperlink'),'http://')
|
788
1016
|
|
789
|
-
if (link != null) {
|
1017
|
+
if (link != null && link != '' && link != 'http://') {
|
790
1018
|
// transform selection and set the cursor into chunked text
|
791
1019
|
e.replaceSelection('['+chunk+']('+link+')')
|
792
1020
|
cursor = selected.start+1
|
@@ -798,27 +1026,28 @@
|
|
798
1026
|
},{
|
799
1027
|
name: 'cmdImage',
|
800
1028
|
title: 'Image',
|
801
|
-
|
1029
|
+
hotkey: 'Ctrl+G',
|
1030
|
+
icon: { glyph: 'glyphicon glyphicon-picture', fa: 'fa fa-picture-o', 'fa-3': 'icon-picture' },
|
802
1031
|
callback: function(e){
|
803
1032
|
// Give ![] surround the selection and prepend the image link
|
804
1033
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent(), link
|
805
1034
|
|
806
1035
|
if (selected.length == 0) {
|
807
1036
|
// Give extra word
|
808
|
-
chunk = 'enter image description here'
|
1037
|
+
chunk = e.__localize('enter image description here')
|
809
1038
|
} else {
|
810
1039
|
chunk = selected.text
|
811
1040
|
}
|
812
1041
|
|
813
|
-
link = prompt('Insert Image Hyperlink','http://')
|
1042
|
+
link = prompt(e.__localize('Insert Image Hyperlink'),'http://')
|
814
1043
|
|
815
1044
|
if (link != null) {
|
816
1045
|
// transform selection and set the cursor into chunked text
|
817
|
-
e.replaceSelection('!['+chunk+']('+link+' "enter image title here")')
|
1046
|
+
e.replaceSelection('!['+chunk+']('+link+' "'+e.__localize('enter image title here')+'")')
|
818
1047
|
cursor = selected.start+2
|
819
1048
|
|
820
1049
|
// Set the next tab
|
821
|
-
e.setNextTab('enter image title here')
|
1050
|
+
e.setNextTab(e.__localize('enter image title here'))
|
822
1051
|
|
823
1052
|
// Set the cursor
|
824
1053
|
e.setSelection(cursor,cursor+chunk.length)
|
@@ -829,8 +1058,9 @@
|
|
829
1058
|
name: 'groupMisc',
|
830
1059
|
data: [{
|
831
1060
|
name: 'cmdList',
|
832
|
-
|
833
|
-
|
1061
|
+
hotkey: 'Ctrl+U',
|
1062
|
+
title: 'Unordered List',
|
1063
|
+
icon: { glyph: 'glyphicon glyphicon-list', fa: 'fa fa-list', 'fa-3': 'icon-list-ul' },
|
834
1064
|
callback: function(e){
|
835
1065
|
// Prepend/Give - surround the selection
|
836
1066
|
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
@@ -838,12 +1068,12 @@
|
|
838
1068
|
// transform selection and set the cursor into chunked text
|
839
1069
|
if (selected.length == 0) {
|
840
1070
|
// Give extra word
|
841
|
-
chunk = 'list text here'
|
1071
|
+
chunk = e.__localize('list text here')
|
842
1072
|
|
843
1073
|
e.replaceSelection('- '+chunk)
|
844
|
-
|
845
1074
|
// Set the cursor
|
846
1075
|
cursor = selected.start+2
|
1076
|
+
|
847
1077
|
} else {
|
848
1078
|
if (selected.text.indexOf('\n') < 0) {
|
849
1079
|
chunk = selected.text
|
@@ -869,7 +1099,130 @@
|
|
869
1099
|
}
|
870
1100
|
}
|
871
1101
|
|
1102
|
+
// Set the cursor
|
1103
|
+
e.setSelection(cursor,cursor+chunk.length)
|
1104
|
+
}
|
1105
|
+
},
|
1106
|
+
{
|
1107
|
+
name: 'cmdListO',
|
1108
|
+
hotkey: 'Ctrl+O',
|
1109
|
+
title: 'Ordered List',
|
1110
|
+
icon: { glyph: 'glyphicon glyphicon-th-list', fa: 'fa fa-list-ol', 'fa-3': 'icon-list-ol' },
|
1111
|
+
callback: function(e) {
|
1112
|
+
|
1113
|
+
// Prepend/Give - surround the selection
|
1114
|
+
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
1115
|
+
|
1116
|
+
// transform selection and set the cursor into chunked text
|
1117
|
+
if (selected.length == 0) {
|
1118
|
+
// Give extra word
|
1119
|
+
chunk = e.__localize('list text here')
|
1120
|
+
e.replaceSelection('1. '+chunk)
|
1121
|
+
// Set the cursor
|
1122
|
+
cursor = selected.start+3
|
1123
|
+
|
1124
|
+
} else {
|
1125
|
+
if (selected.text.indexOf('\n') < 0) {
|
1126
|
+
chunk = selected.text
|
1127
|
+
|
1128
|
+
e.replaceSelection('1. '+chunk)
|
1129
|
+
|
1130
|
+
// Set the cursor
|
1131
|
+
cursor = selected.start+3
|
1132
|
+
} else {
|
1133
|
+
var list = []
|
1134
|
+
|
1135
|
+
list = selected.text.split('\n')
|
1136
|
+
chunk = list[0]
|
1137
|
+
|
1138
|
+
$.each(list,function(k,v) {
|
1139
|
+
list[k] = '1. '+v
|
1140
|
+
})
|
1141
|
+
|
1142
|
+
e.replaceSelection('\n\n'+list.join('\n'))
|
872
1143
|
|
1144
|
+
// Set the cursor
|
1145
|
+
cursor = selected.start+5
|
1146
|
+
}
|
1147
|
+
}
|
1148
|
+
|
1149
|
+
// Set the cursor
|
1150
|
+
e.setSelection(cursor,cursor+chunk.length)
|
1151
|
+
}
|
1152
|
+
},
|
1153
|
+
{
|
1154
|
+
name: 'cmdCode',
|
1155
|
+
hotkey: 'Ctrl+K',
|
1156
|
+
title: 'Code',
|
1157
|
+
icon: { glyph: 'glyphicon glyphicon-asterisk', fa: 'fa fa-code', 'fa-3': 'icon-code' },
|
1158
|
+
callback: function(e) {
|
1159
|
+
|
1160
|
+
// Give/remove ** surround the selection
|
1161
|
+
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
1162
|
+
|
1163
|
+
if (selected.length == 0) {
|
1164
|
+
// Give extra word
|
1165
|
+
chunk = e.__localize('code text here')
|
1166
|
+
} else {
|
1167
|
+
chunk = selected.text
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
// transform selection and set the cursor into chunked text
|
1171
|
+
if (content.substr(selected.start-1,1) == '`'
|
1172
|
+
&& content.substr(selected.end,1) == '`' ) {
|
1173
|
+
e.setSelection(selected.start-1,selected.end+1)
|
1174
|
+
e.replaceSelection(chunk)
|
1175
|
+
cursor = selected.start-1
|
1176
|
+
} else {
|
1177
|
+
e.replaceSelection('`'+chunk+'`')
|
1178
|
+
cursor = selected.start+1
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
// Set the cursor
|
1182
|
+
e.setSelection(cursor,cursor+chunk.length)
|
1183
|
+
}
|
1184
|
+
},
|
1185
|
+
{
|
1186
|
+
name: 'cmdQuote',
|
1187
|
+
hotkey: 'Ctrl+Q',
|
1188
|
+
title: 'Quote',
|
1189
|
+
icon: { glyph: 'glyphicon glyphicon-comment', fa: 'fa fa-quote-left', 'fa-3': 'icon-quote-left' },
|
1190
|
+
callback: function(e) {
|
1191
|
+
// Prepend/Give - surround the selection
|
1192
|
+
var chunk, cursor, selected = e.getSelection(), content = e.getContent()
|
1193
|
+
|
1194
|
+
// transform selection and set the cursor into chunked text
|
1195
|
+
if (selected.length == 0) {
|
1196
|
+
// Give extra word
|
1197
|
+
chunk = e.__localize('quote here')
|
1198
|
+
e.replaceSelection('> '+chunk)
|
1199
|
+
// Set the cursor
|
1200
|
+
cursor = selected.start+2
|
1201
|
+
|
1202
|
+
} else {
|
1203
|
+
if (selected.text.indexOf('\n') < 0) {
|
1204
|
+
chunk = selected.text
|
1205
|
+
|
1206
|
+
e.replaceSelection('> '+chunk)
|
1207
|
+
|
1208
|
+
// Set the cursor
|
1209
|
+
cursor = selected.start+2
|
1210
|
+
} else {
|
1211
|
+
var list = []
|
1212
|
+
|
1213
|
+
list = selected.text.split('\n')
|
1214
|
+
chunk = list[0]
|
1215
|
+
|
1216
|
+
$.each(list,function(k,v) {
|
1217
|
+
list[k] = '> '+v
|
1218
|
+
})
|
1219
|
+
|
1220
|
+
e.replaceSelection('\n\n'+list.join('\n'))
|
1221
|
+
|
1222
|
+
// Set the cursor
|
1223
|
+
cursor = selected.start+4
|
1224
|
+
}
|
1225
|
+
}
|
873
1226
|
|
874
1227
|
// Set the cursor
|
875
1228
|
e.setSelection(cursor,cursor+chunk.length)
|
@@ -880,10 +1233,11 @@
|
|
880
1233
|
data: [{
|
881
1234
|
name: 'cmdPreview',
|
882
1235
|
toggle: true,
|
1236
|
+
hotkey: 'Ctrl+P',
|
883
1237
|
title: 'Preview',
|
884
1238
|
btnText: 'Preview',
|
885
1239
|
btnClass: 'btn btn-primary btn-sm',
|
886
|
-
icon: 'glyphicon glyphicon-search',
|
1240
|
+
icon: { glyph: 'glyphicon glyphicon-search', fa: 'fa fa-search', 'fa-3': 'icon-search' },
|
887
1241
|
callback: function(e){
|
888
1242
|
// Check the preview mode and toggle based on this flag
|
889
1243
|
var isPreview = e.$isPreview,content
|
@@ -899,12 +1253,39 @@
|
|
899
1253
|
}]
|
900
1254
|
],
|
901
1255
|
additionalButtons:[], // Place to hook more buttons by code
|
1256
|
+
reorderButtonGroups:[],
|
1257
|
+
hiddenButtons:[], // Default hidden buttons
|
1258
|
+
disabledButtons:[], // Default disabled buttons
|
1259
|
+
footer: '',
|
1260
|
+
fullscreen: {
|
1261
|
+
enable: true,
|
1262
|
+
icons: {
|
1263
|
+
fullscreenOn: {
|
1264
|
+
fa: 'fa fa-expand',
|
1265
|
+
glyph: 'glyphicon glyphicon-fullscreen',
|
1266
|
+
'fa-3': 'icon-resize-full'
|
1267
|
+
},
|
1268
|
+
fullscreenOff: {
|
1269
|
+
fa: 'fa fa-compress',
|
1270
|
+
glyph: 'glyphicon glyphicon-fullscreen',
|
1271
|
+
'fa-3': 'icon-resize-small'
|
1272
|
+
},
|
1273
|
+
switchTheme: {
|
1274
|
+
fa: 'fa fa-adjust',
|
1275
|
+
glyph: 'glyphicon glyphicon-adjust',
|
1276
|
+
'fa-3': 'icon-adjust'
|
1277
|
+
}
|
1278
|
+
}
|
1279
|
+
},
|
902
1280
|
|
903
1281
|
/* Events hook */
|
904
1282
|
onShow: function (e) {},
|
905
1283
|
onPreview: function (e) {},
|
906
1284
|
onSave: function (e) {},
|
907
|
-
onBlur: function (e) {}
|
1285
|
+
onBlur: function (e) {},
|
1286
|
+
onFocus: function (e) {},
|
1287
|
+
onChange: function(e) {},
|
1288
|
+
onFullscreen: function(e) {}
|
908
1289
|
}
|
909
1290
|
|
910
1291
|
$.fn.markdown.Constructor = Markdown
|
@@ -927,7 +1308,8 @@
|
|
927
1308
|
$this.data('markdown').showEditor()
|
928
1309
|
return
|
929
1310
|
}
|
930
|
-
|
1311
|
+
|
1312
|
+
$this.markdown()
|
931
1313
|
}
|
932
1314
|
|
933
1315
|
var analyzeMarkdown = function(e) {
|
@@ -993,4 +1375,4 @@
|
|
993
1375
|
})
|
994
1376
|
})
|
995
1377
|
|
996
|
-
}(window.jQuery);
|
1378
|
+
}(window.jQuery);
|