rails-bootstrap-markdown 1.0.0 → 2.6.0
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/.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('')
|
1046
|
+
e.replaceSelection('+'")')
|
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);
|