comfortable_mexican_sofa 1.12.8 → 1.12.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/app/assets/fonts/comfy/admin/cms/lib/redactor-font.eot +0 -0
- data/app/assets/javascripts/comfy/admin/cms/base.js.coffee +46 -11
- data/app/assets/javascripts/comfy/admin/cms/lib/redactor.js +1807 -570
- data/app/assets/stylesheets/comfy/admin/cms/bootstrap_overrides.sass +6 -1
- data/app/assets/stylesheets/comfy/admin/cms/lib/redactor.css +79 -52
- data/app/controllers/comfy/admin/cms/base_controller.rb +2 -1
- data/app/controllers/comfy/admin/cms/pages_controller.rb +4 -1
- data/app/controllers/comfy/cms/base_controller.rb +5 -5
- data/app/controllers/comfy/cms/content_controller.rb +4 -0
- data/app/helpers/comfy/cms_helper.rb +72 -70
- data/app/models/comfy/cms/file.rb +0 -1
- data/app/views/comfy/admin/cms/files/_file.html.haml +1 -1
- data/app/views/comfy/admin/cms/layouts/_index_branch.html.haml +2 -1
- data/config/environments/test.rb +2 -0
- data/config/initializers/comfortable_mexican_sofa.rb +12 -0
- data/config/locales/cs.yml +2 -3
- data/config/locales/da.yml +2 -3
- data/config/locales/de.yml +2 -3
- data/config/locales/en.yml +2 -3
- data/config/locales/es.yml +2 -3
- data/config/locales/fr.yml +2 -3
- data/config/locales/it.yml +2 -3
- data/config/locales/ja.yml +2 -3
- data/config/locales/nb.yml +2 -3
- data/config/locales/nl.yml +2 -3
- data/config/locales/pl.yml +40 -41
- data/config/locales/pt-BR.yml +2 -3
- data/config/locales/ru.yml +2 -3
- data/config/locales/sv.yml +2 -3
- data/config/locales/uk.yml +2 -3
- data/config/locales/zh-CN.yml +2 -3
- data/config/locales/zh-TW.yml +16 -17
- data/db/migrate/01_create_cms.rb +18 -25
- data/db/upgrade_migrations/08_upgrade_to_1_12_0.rb +2 -2
- data/doc/preview.png +0 -0
- data/lib/comfortable_mexican_sofa.rb +1 -0
- data/lib/comfortable_mexican_sofa/access_control/admin_authentication.rb +3 -2
- data/lib/comfortable_mexican_sofa/access_control/public_authorization.rb +8 -0
- data/lib/comfortable_mexican_sofa/configuration.rb +4 -0
- data/lib/comfortable_mexican_sofa/engine.rb +5 -1
- data/lib/comfortable_mexican_sofa/fixture/file.rb +22 -22
- data/lib/comfortable_mexican_sofa/tags/asset.rb +8 -3
- data/lib/comfortable_mexican_sofa/version.rb +1 -1
- data/test/controllers/comfy/admin/cms/pages_controller_test.rb +22 -0
- data/test/controllers/comfy/cms/content_controller_test.rb +12 -0
- data/test/integration/access_control_test.rb +24 -1
- data/test/lib/fixtures/files_test.rb +29 -27
- data/test/lib/tags/asset_test.rb +42 -9
- data/test/test_helper.rb +8 -3
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 178be176b760152af88ef7cef977ec69828f3dbb
|
4
|
+
data.tar.gz: 08daec455e2fbad3665e8a5b2f900992c207a644
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a65fa0ac1accefe11d47a9694e18c2b6cd8064cd09249190d44663e1c81f7d78d310c57ae953c50555a6127df99b48d7039f4d077f57022e0c415c6ddeee58c
|
7
|
+
data.tar.gz: 8ce4ec49478f8691bdab4ced394f8eee45fbfbcc2d9deee7c83eaadff3fb03746436316fcdd4b237643deca222614d81b4ce350b6f17faa3226f814e0c95e851
|
data/.travis.yml
CHANGED
Binary file
|
@@ -23,15 +23,50 @@ window.CMS.init = ->
|
|
23
23
|
|
24
24
|
window.CMS.slugify = ->
|
25
25
|
slugify = (str) ->
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
# Trim string and lower case.
|
27
|
+
str = str.replace(/^\s+|\s+$/g, '').toLowerCase()
|
28
|
+
|
29
|
+
# Replace special chars.
|
30
|
+
replacements = [
|
31
|
+
['à', 'a'],
|
32
|
+
['á', 'a'],
|
33
|
+
['ä', 'ae'],
|
34
|
+
['â', 'a'],
|
35
|
+
['ã', 'a'],
|
36
|
+
['è', 'e'],
|
37
|
+
['é', 'e'],
|
38
|
+
['ë', 'e'],
|
39
|
+
['ê', 'e'],
|
40
|
+
['ì', 'i'],
|
41
|
+
['í', 'i'],
|
42
|
+
['ï', 'i'],
|
43
|
+
['î', 'i'],
|
44
|
+
['ò', 'o'],
|
45
|
+
['ó', 'o'],
|
46
|
+
['ö', 'oe'],
|
47
|
+
['ô', 'o'],
|
48
|
+
['õ', 'o'],
|
49
|
+
['ù', 'u'],
|
50
|
+
['ú', 'u'],
|
51
|
+
['ü', 'ue'],
|
52
|
+
['û', 'u'],
|
53
|
+
['ñ', 'n'],
|
54
|
+
['ç', 'c'],
|
55
|
+
['ß', 'ss'],
|
56
|
+
['·', '-'],
|
57
|
+
['/', '-'],
|
58
|
+
[',', '-'],
|
59
|
+
[':', '-'],
|
60
|
+
[';', '-'],
|
61
|
+
['_', '-'],
|
62
|
+
[' ', '-'],
|
63
|
+
]
|
64
|
+
|
65
|
+
for replacement in replacements
|
66
|
+
str = str.replace(new RegExp(replacement[0], 'g'), replacement[1])
|
67
|
+
|
68
|
+
# Remove any other URL incompatible characters and replace multiple dashes with just a single one.
|
69
|
+
str = str.replace(/[^a-z0-9-]/g, '').replace(/-+/g, '-')
|
35
70
|
|
36
71
|
$('input[data-slugify=true]').bind 'keyup.cms', ->
|
37
72
|
$('input[data-slug=true]').val(slugify($(this).val()))
|
@@ -71,7 +106,7 @@ window.CMS.codemirror = ->
|
|
71
106
|
cm.setSize($(@).width(), $(@).height())
|
72
107
|
cm.refresh()
|
73
108
|
|
74
|
-
$('a[data-toggle="tab"]').on 'shown', ->
|
109
|
+
$('a[data-toggle="tab"]').on 'shown.bs.tab', ->
|
75
110
|
for cm in CMS.code_mirror_instances
|
76
111
|
cm.refresh()
|
77
112
|
|
@@ -124,7 +159,7 @@ window.CMS.page_update_preview = ->
|
|
124
159
|
$('input[name=commit]').click ->
|
125
160
|
$(this).parents('form').attr('target', '')
|
126
161
|
$('input[name=preview]').click ->
|
127
|
-
$(this).parents('form').attr('target', '
|
162
|
+
$(this).parents('form').attr('target', 'comfy-cms-preview')
|
128
163
|
|
129
164
|
|
130
165
|
window.CMS.page_update_publish = ->
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
|
-
Redactor
|
3
|
-
Updated:
|
2
|
+
Redactor 10.2.5
|
3
|
+
Updated: October 1, 2015
|
4
4
|
|
5
5
|
http://imperavi.com/redactor/
|
6
6
|
|
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
(function($)
|
14
14
|
{
|
15
|
+
|
15
16
|
'use strict';
|
16
17
|
|
17
18
|
if (!Function.prototype.bind)
|
@@ -28,9 +29,6 @@
|
|
28
29
|
|
29
30
|
var uuid = 0;
|
30
31
|
|
31
|
-
var reUrlYoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig;
|
32
|
-
var reUrlVimeo = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/;
|
33
|
-
|
34
32
|
// Plugin
|
35
33
|
$.fn.redactor = function(options)
|
36
34
|
{
|
@@ -94,11 +92,11 @@
|
|
94
92
|
|
95
93
|
// Functionality
|
96
94
|
$.Redactor = Redactor;
|
97
|
-
$.Redactor.VERSION = '10.
|
95
|
+
$.Redactor.VERSION = '10.2.5';
|
98
96
|
$.Redactor.modules = ['alignment', 'autosave', 'block', 'buffer', 'build', 'button',
|
99
97
|
'caret', 'clean', 'code', 'core', 'dropdown', 'file', 'focus',
|
100
98
|
'image', 'indent', 'inline', 'insert', 'keydown', 'keyup',
|
101
|
-
'lang', 'line', 'link', 'list', 'modal', 'observe', 'paragraphize',
|
99
|
+
'lang', 'line', 'link', 'linkify', 'list', 'modal', 'observe', 'paragraphize',
|
102
100
|
'paste', 'placeholder', 'progress', 'selection', 'shortcuts',
|
103
101
|
'tabifier', 'tidy', 'toolbar', 'upload', 'utils'];
|
104
102
|
|
@@ -135,6 +133,7 @@
|
|
135
133
|
autosaveName: false,
|
136
134
|
autosaveInterval: 60, // seconds
|
137
135
|
autosaveOnChange: false,
|
136
|
+
autosaveFields: false,
|
138
137
|
|
139
138
|
linkTooltip: true,
|
140
139
|
linkProtocol: 'http',
|
@@ -191,12 +190,17 @@
|
|
191
190
|
|
192
191
|
tabifier: true,
|
193
192
|
|
194
|
-
deniedTags: ['
|
193
|
+
deniedTags: ['script', 'style'],
|
195
194
|
allowedTags: false, // or array
|
196
195
|
|
196
|
+
paragraphizeBlocks: ['table', 'div', 'pre', 'form', 'ul', 'ol', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dl', 'blockquote', 'figcaption',
|
197
|
+
'address', 'section', 'header', 'footer', 'aside', 'article', 'object', 'style', 'script', 'iframe', 'select', 'input', 'textarea',
|
198
|
+
'button', 'option', 'map', 'area', 'math', 'hr', 'fieldset', 'legend', 'hgroup', 'nav', 'figure', 'details', 'menu', 'summary', 'p'],
|
199
|
+
|
197
200
|
removeComments: false,
|
198
201
|
replaceTags: [
|
199
|
-
['strike', 'del']
|
202
|
+
['strike', 'del'],
|
203
|
+
['b', 'strong']
|
200
204
|
],
|
201
205
|
replaceStyles: [
|
202
206
|
['font-weight:\\s?bold', "strong"],
|
@@ -249,7 +253,10 @@
|
|
249
253
|
inlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'],
|
250
254
|
alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DL', 'DT', 'DD', 'DIV', 'TD', 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'],
|
251
255
|
blockLevelElements: ['PRE', 'UL', 'OL', 'LI'],
|
252
|
-
|
256
|
+
highContrast: false,
|
257
|
+
observe: {
|
258
|
+
dropdowns: []
|
259
|
+
},
|
253
260
|
|
254
261
|
// lang
|
255
262
|
langs: {
|
@@ -323,9 +330,21 @@
|
|
323
330
|
underline: 'Underline',
|
324
331
|
alignment: 'Alignment',
|
325
332
|
filename: 'Name (optional)',
|
326
|
-
edit: 'Edit'
|
333
|
+
edit: 'Edit',
|
334
|
+
upload_label: 'Drop file here or '
|
327
335
|
}
|
328
|
-
}
|
336
|
+
},
|
337
|
+
|
338
|
+
linkify: {
|
339
|
+
regexps: {
|
340
|
+
youtube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig,
|
341
|
+
vimeo: /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,
|
342
|
+
image: /((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/ig,
|
343
|
+
url: /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/ig,
|
344
|
+
}
|
345
|
+
},
|
346
|
+
|
347
|
+
codemirror: false
|
329
348
|
};
|
330
349
|
|
331
350
|
// Functionality
|
@@ -334,6 +353,7 @@
|
|
334
353
|
keyCode: {
|
335
354
|
BACKSPACE: 8,
|
336
355
|
DELETE: 46,
|
356
|
+
UP: 38,
|
337
357
|
DOWN: 40,
|
338
358
|
ENTER: 13,
|
339
359
|
SPACE: 32,
|
@@ -371,6 +391,16 @@
|
|
371
391
|
// setup allowed and denied tags
|
372
392
|
this.tidy.setupAllowed();
|
373
393
|
|
394
|
+
// setup denied tags
|
395
|
+
if (this.opts.deniedTags !== false)
|
396
|
+
{
|
397
|
+
var tags = ['html', 'head', 'link', 'body', 'meta', 'applet'];
|
398
|
+
for (var i = 0; i < tags.length; i++)
|
399
|
+
{
|
400
|
+
this.opts.deniedTags.push(tags[i]);
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
374
404
|
// load lang
|
375
405
|
this.lang.load();
|
376
406
|
|
@@ -425,7 +455,6 @@
|
|
425
455
|
this[module][methods[z]] = this[module][methods[z]].bind(this);
|
426
456
|
}
|
427
457
|
},
|
428
|
-
|
429
458
|
alignment: function()
|
430
459
|
{
|
431
460
|
return {
|
@@ -448,15 +477,18 @@
|
|
448
477
|
set: function(type)
|
449
478
|
{
|
450
479
|
// focus
|
451
|
-
if (!this.utils.browser('msie')
|
452
|
-
|
453
|
-
|
454
|
-
|
480
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
481
|
+
{
|
482
|
+
this.$editor.focus();
|
483
|
+
}
|
455
484
|
|
456
485
|
// get blocks
|
457
486
|
this.alignment.blocks = this.selection.getBlocks();
|
458
487
|
this.alignment.type = type;
|
459
488
|
|
489
|
+
this.buffer.set();
|
490
|
+
this.selection.save();
|
491
|
+
|
460
492
|
// set alignment
|
461
493
|
if (this.alignment.isLinebreaksOrNoBlocks())
|
462
494
|
{
|
@@ -516,11 +548,11 @@
|
|
516
548
|
autosave: function()
|
517
549
|
{
|
518
550
|
return {
|
551
|
+
html: false,
|
519
552
|
enable: function()
|
520
553
|
{
|
521
554
|
if (!this.opts.autosave) return;
|
522
555
|
|
523
|
-
this.autosave.html = false;
|
524
556
|
this.autosave.name = (this.opts.autosaveName) ? this.opts.autosaveName : this.$textarea.attr('name');
|
525
557
|
|
526
558
|
if (this.opts.autosaveOnChange) return;
|
@@ -533,15 +565,17 @@
|
|
533
565
|
},
|
534
566
|
load: function()
|
535
567
|
{
|
568
|
+
if (!this.opts.autosave) return;
|
569
|
+
|
536
570
|
this.autosave.source = this.code.get();
|
537
571
|
|
538
572
|
if (this.autosave.html === this.autosave.source) return;
|
539
|
-
if (this.utils.isEmpty(this.autosave.source)) return;
|
540
573
|
|
541
574
|
// data
|
542
575
|
var data = {};
|
543
576
|
data['name'] = this.autosave.name;
|
544
|
-
data[this.autosave.name] =
|
577
|
+
data[this.autosave.name] = this.autosave.source;
|
578
|
+
data = this.autosave.getHiddenFields(data);
|
545
579
|
|
546
580
|
// ajax
|
547
581
|
var jsxhr = $.ajax({
|
@@ -552,6 +586,23 @@
|
|
552
586
|
|
553
587
|
jsxhr.done(this.autosave.success);
|
554
588
|
},
|
589
|
+
getHiddenFields: function(data)
|
590
|
+
{
|
591
|
+
if (this.opts.autosaveFields === false || typeof this.opts.autosaveFields !== 'object')
|
592
|
+
{
|
593
|
+
return data;
|
594
|
+
}
|
595
|
+
|
596
|
+
$.each(this.opts.autosaveFields, $.proxy(function(k, v)
|
597
|
+
{
|
598
|
+
if (v !== null && v.toString().indexOf('#') === 0) v = $(v).val();
|
599
|
+
data[k] = v;
|
600
|
+
|
601
|
+
}, this));
|
602
|
+
|
603
|
+
return data;
|
604
|
+
|
605
|
+
},
|
555
606
|
success: function(data)
|
556
607
|
{
|
557
608
|
var json;
|
@@ -586,7 +637,7 @@
|
|
586
637
|
|
587
638
|
if (typeof this.formatting[name].data != 'undefined') type = 'data';
|
588
639
|
else if (typeof this.formatting[name].attr != 'undefined') type = 'attr';
|
589
|
-
else if (typeof this.formatting[name]
|
640
|
+
else if (typeof this.formatting[name]['class'] != 'undefined') type = 'class';
|
590
641
|
|
591
642
|
if (typeof this.formatting[name].clear != 'undefined')
|
592
643
|
{
|
@@ -610,6 +661,23 @@
|
|
610
661
|
// focus
|
611
662
|
if (!this.utils.browser('msie')) this.$editor.focus();
|
612
663
|
|
664
|
+
var html = $.trim(this.$editor.html());
|
665
|
+
this.block.isEmpty = this.utils.isEmpty(html);
|
666
|
+
|
667
|
+
// FF focus
|
668
|
+
if (this.utils.browser('mozilla') && !this.focus.isFocused())
|
669
|
+
{
|
670
|
+
if (this.block.isEmpty)
|
671
|
+
{
|
672
|
+
var $first;
|
673
|
+
if (!this.opts.linebreaks)
|
674
|
+
{
|
675
|
+
$first = this.$editor.children().first();
|
676
|
+
this.caret.setEnd($first);
|
677
|
+
}
|
678
|
+
}
|
679
|
+
}
|
680
|
+
|
613
681
|
this.block.blocks = this.selection.getBlocks();
|
614
682
|
|
615
683
|
this.block.blocksSize = this.block.blocks.length;
|
@@ -623,10 +691,12 @@
|
|
623
691
|
|
624
692
|
this.selection.restore();
|
625
693
|
this.code.sync();
|
694
|
+
this.observe.load();
|
626
695
|
|
627
696
|
},
|
628
697
|
set: function(tag)
|
629
698
|
{
|
699
|
+
|
630
700
|
this.selection.get();
|
631
701
|
this.block.containerTag = this.range.commonAncestorContainer.tagName;
|
632
702
|
|
@@ -641,6 +711,15 @@
|
|
641
711
|
},
|
642
712
|
setCollapsed: function(tag)
|
643
713
|
{
|
714
|
+
if (this.opts.linebreaks && this.block.isEmpty && tag != 'p')
|
715
|
+
{
|
716
|
+
var node = document.createElement(tag);
|
717
|
+
this.$editor.html(node);
|
718
|
+
this.caret.setEnd(node);
|
719
|
+
|
720
|
+
return;
|
721
|
+
}
|
722
|
+
|
644
723
|
var block = this.block.blocks[0];
|
645
724
|
if (block === false) return;
|
646
725
|
|
@@ -655,7 +734,6 @@
|
|
655
734
|
var isContainerTable = (this.block.containerTag == 'TD' || this.block.containerTag == 'TH');
|
656
735
|
if (isContainerTable && !this.opts.linebreaks)
|
657
736
|
{
|
658
|
-
|
659
737
|
document.execCommand('formatblock', false, '<' + tag + '>');
|
660
738
|
|
661
739
|
block = this.selection.getBlock();
|
@@ -666,7 +744,7 @@
|
|
666
744
|
{
|
667
745
|
if (this.opts.linebreaks && tag == 'p')
|
668
746
|
{
|
669
|
-
$(block).
|
747
|
+
$(block).append('<br>');
|
670
748
|
this.utils.replaceWithContents(block);
|
671
749
|
}
|
672
750
|
else
|
@@ -687,7 +765,7 @@
|
|
687
765
|
// blockquote off
|
688
766
|
if (this.opts.linebreaks)
|
689
767
|
{
|
690
|
-
$(block).
|
768
|
+
$(block).append('<br>');
|
691
769
|
this.utils.replaceWithContents(block);
|
692
770
|
}
|
693
771
|
else
|
@@ -701,10 +779,16 @@
|
|
701
779
|
this.block.toggle($(block));
|
702
780
|
}
|
703
781
|
|
782
|
+
|
783
|
+
if (typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
|
784
|
+
{
|
785
|
+
$(block).removeAttr('class').removeAttr('style');
|
786
|
+
}
|
704
787
|
},
|
705
788
|
setMultiple: function(tag)
|
706
789
|
{
|
707
790
|
var block = this.block.blocks[0];
|
791
|
+
|
708
792
|
var isContainerTable = (this.block.containerTag == 'TD' || this.block.containerTag == 'TH');
|
709
793
|
|
710
794
|
if (block !== false && this.block.blocksSize === 1)
|
@@ -714,7 +798,7 @@
|
|
714
798
|
// blockquote off
|
715
799
|
if (this.opts.linebreaks)
|
716
800
|
{
|
717
|
-
$(block).
|
801
|
+
$(block).append('<br>');
|
718
802
|
this.utils.replaceWithContents(block);
|
719
803
|
}
|
720
804
|
else
|
@@ -761,7 +845,6 @@
|
|
761
845
|
}
|
762
846
|
else
|
763
847
|
{
|
764
|
-
|
765
848
|
if (this.opts.linebreaks || tag != 'p')
|
766
849
|
{
|
767
850
|
if (tag == 'blockquote')
|
@@ -777,14 +860,20 @@
|
|
777
860
|
{
|
778
861
|
$.each(this.block.blocks, $.proxy(function(i,s)
|
779
862
|
{
|
863
|
+
var $formatted = false;
|
780
864
|
if (this.opts.linebreaks)
|
781
865
|
{
|
782
866
|
$(s).prepend('<br>').append('<br>');
|
783
|
-
this.utils.replaceWithContents(s);
|
867
|
+
$formatted = this.utils.replaceWithContents(s);
|
784
868
|
}
|
785
869
|
else
|
786
870
|
{
|
787
|
-
this.utils.replaceToTag(s, 'p');
|
871
|
+
$formatted = this.utils.replaceToTag(s, 'p');
|
872
|
+
}
|
873
|
+
|
874
|
+
if ($formatted && typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
|
875
|
+
{
|
876
|
+
$formatted.removeAttr('class').removeAttr('style');
|
788
877
|
}
|
789
878
|
|
790
879
|
}, this));
|
@@ -794,7 +883,6 @@
|
|
794
883
|
|
795
884
|
}
|
796
885
|
|
797
|
-
|
798
886
|
this.block.formatWrap(tag);
|
799
887
|
}
|
800
888
|
else
|
@@ -831,6 +919,11 @@
|
|
831
919
|
if (this.block.isRemoveInline) this.utils.removeInlineTags($formatted);
|
832
920
|
if (tag == 'p' || this.block.headTag) $formatted.find('p').contents().unwrap();
|
833
921
|
|
922
|
+
if (typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
|
923
|
+
{
|
924
|
+
$formatted.removeAttr('class').removeAttr('style');
|
925
|
+
}
|
926
|
+
|
834
927
|
|
835
928
|
}, this));
|
836
929
|
}
|
@@ -893,7 +986,7 @@
|
|
893
986
|
},
|
894
987
|
formatListToBlockquote: function()
|
895
988
|
{
|
896
|
-
var block = $(this.block.blocks[0]).closest('ul, ol');
|
989
|
+
var block = $(this.block.blocks[0]).closest('ul, ol', this.$editor[0]);
|
897
990
|
|
898
991
|
$(block).find('ul, ol').contents().unwrap();
|
899
992
|
$(block).find('li').append($('<br>')).contents().unwrap();
|
@@ -952,11 +1045,6 @@
|
|
952
1045
|
|
953
1046
|
var $elements = $formatted.find(this.opts.blockLevelElements.join(',') + ', td, table, thead, tbody, tfoot, th, tr');
|
954
1047
|
|
955
|
-
if ((this.opts.linebreaks && tag == 'p') || tag == 'pre' || tag == 'blockquote')
|
956
|
-
{
|
957
|
-
$elements.append('<br />');
|
958
|
-
}
|
959
|
-
|
960
1048
|
$elements.contents().unwrap();
|
961
1049
|
|
962
1050
|
if (tag != 'p' && tag != 'blockquote') $formatted.find('img').remove();
|
@@ -983,13 +1071,24 @@
|
|
983
1071
|
this.utils.replaceWithContents($formatted);
|
984
1072
|
}
|
985
1073
|
|
1074
|
+
if (this.opts.linebreaks)
|
1075
|
+
{
|
1076
|
+
var $next = $formatted.next().next();
|
1077
|
+
if ($next.size() != 0 && $next[0].tagName === 'BR')
|
1078
|
+
{
|
1079
|
+
$next.remove();
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
|
1084
|
+
|
986
1085
|
},
|
987
1086
|
formatTableWrapping: function($formatted)
|
988
1087
|
{
|
989
|
-
if ($formatted.closest('table').length === 0) return;
|
1088
|
+
if ($formatted.closest('table', this.$editor[0]).length === 0) return;
|
990
1089
|
|
991
|
-
if ($formatted.closest('tr').length === 0) $formatted.wrap('<tr>');
|
992
|
-
if ($formatted.closest('td').length === 0 && $formatted.closest('th').length === 0)
|
1090
|
+
if ($formatted.closest('tr', this.$editor[0]).length === 0) $formatted.wrap('<tr>');
|
1091
|
+
if ($formatted.closest('td', this.$editor[0]).length === 0 && $formatted.closest('th').length === 0)
|
993
1092
|
{
|
994
1093
|
$formatted.wrap('<td>');
|
995
1094
|
}
|
@@ -1142,6 +1241,8 @@
|
|
1142
1241
|
build: function()
|
1143
1242
|
{
|
1144
1243
|
return {
|
1244
|
+
focused: false,
|
1245
|
+
blured: true,
|
1145
1246
|
run: function()
|
1146
1247
|
{
|
1147
1248
|
this.build.createContainerBox();
|
@@ -1156,7 +1257,7 @@
|
|
1156
1257
|
},
|
1157
1258
|
createContainerBox: function()
|
1158
1259
|
{
|
1159
|
-
this.$box = $('<div class="redactor-box" />');
|
1260
|
+
this.$box = $('<div class="redactor-box" role="application" />');
|
1160
1261
|
},
|
1161
1262
|
createTextarea: function()
|
1162
1263
|
{
|
@@ -1213,6 +1314,7 @@
|
|
1213
1314
|
callEditor: function()
|
1214
1315
|
{
|
1215
1316
|
this.build.disableMozillaEditing();
|
1317
|
+
this.build.disableIeLinks();
|
1216
1318
|
this.build.setEvents();
|
1217
1319
|
this.build.setHelpers();
|
1218
1320
|
|
@@ -1252,7 +1354,8 @@
|
|
1252
1354
|
{
|
1253
1355
|
e.preventDefault();
|
1254
1356
|
|
1255
|
-
if (!this.opts.dragImageUpload
|
1357
|
+
if (!this.opts.dragImageUpload && !this.opts.dragFileUpload) return;
|
1358
|
+
if (this.opts.imageUpload === null && this.opts.fileUpload === null) return;
|
1256
1359
|
|
1257
1360
|
var files = e.dataTransfer.files;
|
1258
1361
|
this.upload.directUpload(files[0], e);
|
@@ -1266,6 +1369,12 @@
|
|
1266
1369
|
setEvents: function()
|
1267
1370
|
{
|
1268
1371
|
// drop
|
1372
|
+
this.$editor.on('dragover.redactor dragenter.redactor', function(e)
|
1373
|
+
{
|
1374
|
+
e.preventDefault();
|
1375
|
+
e.stopPropagation();
|
1376
|
+
});
|
1377
|
+
|
1269
1378
|
this.$editor.on('drop.redactor', $.proxy(function(e)
|
1270
1379
|
{
|
1271
1380
|
e = e.originalEvent || e;
|
@@ -1302,6 +1411,9 @@
|
|
1302
1411
|
// paste
|
1303
1412
|
this.$editor.on('paste.redactor', $.proxy(this.paste.init, this));
|
1304
1413
|
|
1414
|
+
// cut
|
1415
|
+
this.$editor.on('cut.redactor', $.proxy(this.code.sync, this));
|
1416
|
+
|
1305
1417
|
// keydown
|
1306
1418
|
this.$editor.on('keydown.redactor', $.proxy(this.keydown.init, this));
|
1307
1419
|
|
@@ -1321,35 +1433,58 @@
|
|
1321
1433
|
}
|
1322
1434
|
|
1323
1435
|
// focus
|
1324
|
-
|
1436
|
+
this.$editor.on('focus.redactor', $.proxy(function(e)
|
1325
1437
|
{
|
1326
|
-
|
1327
|
-
|
1438
|
+
if ($.isFunction(this.opts.focusCallback))
|
1439
|
+
{
|
1440
|
+
this.core.setCallback('focus', e);
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
this.build.focused = true;
|
1444
|
+
this.build.blured = false;
|
1445
|
+
|
1446
|
+
if (this.selection.getCurrent() === false)
|
1447
|
+
{
|
1448
|
+
this.selection.get();
|
1449
|
+
this.range.setStart(this.$editor[0], 0);
|
1450
|
+
this.range.setEnd(this.$editor[0], 0);
|
1451
|
+
this.selection.addRange();
|
1452
|
+
}
|
1453
|
+
|
1454
|
+
|
1455
|
+
}, this));
|
1328
1456
|
|
1329
|
-
var clickedElement;
|
1330
|
-
$(document).on('mousedown', function(e) { clickedElement = e.target; });
|
1331
1457
|
|
1332
1458
|
// blur
|
1333
|
-
|
1459
|
+
$(document).on('mousedown.redactor-blur.' + this.uuid, $.proxy(function(e)
|
1334
1460
|
{
|
1461
|
+
if (this.start) return;
|
1335
1462
|
if (this.rtePaste) return;
|
1336
|
-
|
1463
|
+
|
1464
|
+
if ($(e.target).closest('.redactor-editor, .redactor-toolbar, .redactor-dropdown').size() !== 0)
|
1465
|
+
{
|
1466
|
+
return;
|
1467
|
+
}
|
1337
1468
|
|
1338
1469
|
this.utils.disableSelectAll();
|
1339
|
-
if ($.isFunction(this.opts.blurCallback))
|
1470
|
+
if (!this.build.blured && $.isFunction(this.opts.blurCallback))
|
1471
|
+
{
|
1472
|
+
this.core.setCallback('blur', e);
|
1473
|
+
}
|
1474
|
+
|
1475
|
+
this.build.focused = false;
|
1476
|
+
this.build.blured = true;
|
1340
1477
|
|
1341
1478
|
}, this));
|
1342
|
-
},
|
1343
|
-
isBlured: function(clickedElement)
|
1344
|
-
{
|
1345
|
-
var $el = $(clickedElement);
|
1346
1479
|
|
1347
|
-
return (!$el.hasClass('redactor-toolbar, redactor-dropdown') && !$el.is('#redactor-modal') && $el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').length === 0);
|
1348
1480
|
},
|
1349
1481
|
setHelpers: function()
|
1350
1482
|
{
|
1351
|
-
//
|
1352
|
-
this.
|
1483
|
+
// linkify
|
1484
|
+
if (this.linkify.isEnabled())
|
1485
|
+
{
|
1486
|
+
this.linkify.format();
|
1487
|
+
}
|
1353
1488
|
|
1354
1489
|
// placeholder
|
1355
1490
|
this.placeholder.enable();
|
@@ -1362,21 +1497,17 @@
|
|
1362
1497
|
plugins: function()
|
1363
1498
|
{
|
1364
1499
|
if (!this.opts.plugins) return;
|
1365
|
-
if (!RedactorPlugins) return;
|
1366
1500
|
|
1367
1501
|
$.each(this.opts.plugins, $.proxy(function(i, s)
|
1368
1502
|
{
|
1369
|
-
|
1503
|
+
var func = (typeof RedactorPlugins !== 'undefined' && typeof RedactorPlugins[s] !== 'undefined') ? RedactorPlugins : Redactor.fn;
|
1370
1504
|
|
1371
|
-
if (
|
1505
|
+
if (!$.isFunction(func[s]))
|
1372
1506
|
{
|
1373
|
-
$.error('Plugin name "' + s + '" matches the name of the Redactor\'s module.');
|
1374
1507
|
return;
|
1375
1508
|
}
|
1376
1509
|
|
1377
|
-
|
1378
|
-
|
1379
|
-
this[s] = RedactorPlugins[s]();
|
1510
|
+
this[s] = func[s]();
|
1380
1511
|
|
1381
1512
|
// get methods
|
1382
1513
|
var methods = this.getModuleMethods(this[s]);
|
@@ -1388,7 +1519,10 @@
|
|
1388
1519
|
this[s][methods[z]] = this[s][methods[z]].bind(this);
|
1389
1520
|
}
|
1390
1521
|
|
1391
|
-
if ($.isFunction(this[s].init))
|
1522
|
+
if ($.isFunction(this[s].init))
|
1523
|
+
{
|
1524
|
+
this[s].init();
|
1525
|
+
}
|
1392
1526
|
|
1393
1527
|
|
1394
1528
|
}, this));
|
@@ -1403,6 +1537,13 @@
|
|
1403
1537
|
document.execCommand('enableObjectResizing', false, false);
|
1404
1538
|
document.execCommand('enableInlineTableEditing', false, false);
|
1405
1539
|
} catch (e) {}
|
1540
|
+
},
|
1541
|
+
disableIeLinks: function()
|
1542
|
+
{
|
1543
|
+
if (!this.utils.browser('msie')) return;
|
1544
|
+
|
1545
|
+
// IE prevent converting links
|
1546
|
+
document.execCommand("AutoUrlDetect", false, false);
|
1406
1547
|
}
|
1407
1548
|
};
|
1408
1549
|
},
|
@@ -1411,7 +1552,7 @@
|
|
1411
1552
|
return {
|
1412
1553
|
build: function(btnName, btnObject)
|
1413
1554
|
{
|
1414
|
-
var $button = $('<a href="#" class="re-icon re-' + btnName + '" rel="' + btnName + '" />').attr('
|
1555
|
+
var $button = $('<a href="#" class="re-icon re-' + btnName + '" rel="' + btnName + '" />').attr({'role': 'button', 'aria-label': btnObject.title, 'tabindex': '-1'});
|
1415
1556
|
|
1416
1557
|
// click
|
1417
1558
|
if (btnObject.func || btnObject.command || btnObject.dropdown)
|
@@ -1422,7 +1563,9 @@
|
|
1422
1563
|
// dropdown
|
1423
1564
|
if (btnObject.dropdown)
|
1424
1565
|
{
|
1425
|
-
|
1566
|
+
$button.addClass('redactor-toolbar-link-dropdown').attr('aria-haspopup', true);
|
1567
|
+
|
1568
|
+
var $dropdown = $('<div class="redactor-dropdown redactor-dropdown-' + this.uuid + ' redactor-dropdown-box-' + btnName + '" style="display: none;">');
|
1426
1569
|
$button.data('dropdown', $dropdown);
|
1427
1570
|
this.dropdown.build(btnName, $dropdown, btnObject.dropdown);
|
1428
1571
|
}
|
@@ -1461,20 +1604,24 @@
|
|
1461
1604
|
},
|
1462
1605
|
createTooltip: function($button, name, title)
|
1463
1606
|
{
|
1464
|
-
var $tooltip = $('<span>').addClass('redactor-toolbar-tooltip redactor-toolbar-tooltip-' + name).hide().html(title);
|
1607
|
+
var $tooltip = $('<span>').addClass('redactor-toolbar-tooltip redactor-toolbar-tooltip-' + this.uuid + ' redactor-toolbar-tooltip-' + name).hide().html(title);
|
1465
1608
|
$tooltip.appendTo('body');
|
1466
1609
|
|
1467
1610
|
$button.on('mouseover', function()
|
1468
1611
|
{
|
1469
|
-
if ($(this).hasClass('redactor-button-disabled'))
|
1612
|
+
if ($(this).hasClass('redactor-button-disabled'))
|
1613
|
+
{
|
1614
|
+
return;
|
1615
|
+
}
|
1470
1616
|
|
1471
1617
|
var pos = $button.offset();
|
1472
1618
|
|
1473
|
-
$tooltip.show();
|
1474
1619
|
$tooltip.css({
|
1475
1620
|
top: (pos.top + $button.innerHeight()) + 'px',
|
1476
1621
|
left: (pos.left + $button.innerWidth()/2 - $tooltip.innerWidth()/2) + 'px'
|
1477
1622
|
});
|
1623
|
+
$tooltip.show();
|
1624
|
+
|
1478
1625
|
});
|
1479
1626
|
|
1480
1627
|
$button.on('mouseout', function()
|
@@ -1489,6 +1636,8 @@
|
|
1489
1636
|
|
1490
1637
|
e.preventDefault();
|
1491
1638
|
|
1639
|
+
$(document).find('.redactor-toolbar-tooltip').hide();
|
1640
|
+
|
1492
1641
|
if (this.utils.browser('msie')) e.returnValue = false;
|
1493
1642
|
|
1494
1643
|
if (type == 'command') this.inline.format(callback);
|
@@ -1525,7 +1674,7 @@
|
|
1525
1674
|
},
|
1526
1675
|
setInactiveAll: function(key)
|
1527
1676
|
{
|
1528
|
-
if (typeof key
|
1677
|
+
if (typeof key === 'undefined')
|
1529
1678
|
{
|
1530
1679
|
this.$toolbar.find('a.re-icon').removeClass('redactor-act');
|
1531
1680
|
}
|
@@ -1536,11 +1685,11 @@
|
|
1536
1685
|
},
|
1537
1686
|
setActiveInVisual: function()
|
1538
1687
|
{
|
1539
|
-
this.$toolbar.find('a.re-icon').not('a.re-html').removeClass('redactor-button-disabled');
|
1688
|
+
this.$toolbar.find('a.re-icon').not('a.re-html, a.re-fullscreen').removeClass('redactor-button-disabled');
|
1540
1689
|
},
|
1541
1690
|
setInactiveInCode: function()
|
1542
1691
|
{
|
1543
|
-
this.$toolbar.find('a.re-icon').not('a.re-html').addClass('redactor-button-disabled');
|
1692
|
+
this.$toolbar.find('a.re-icon').not('a.re-html, a.re-fullscreen').addClass('redactor-button-disabled');
|
1544
1693
|
},
|
1545
1694
|
changeIcon: function(key, classname)
|
1546
1695
|
{
|
@@ -1558,6 +1707,8 @@
|
|
1558
1707
|
},
|
1559
1708
|
addCallback: function($btn, callback)
|
1560
1709
|
{
|
1710
|
+
if ($btn == "buffer") return;
|
1711
|
+
|
1561
1712
|
var type = (callback == 'dropdown') ? 'dropdown' : 'func';
|
1562
1713
|
var key = $btn.attr('rel');
|
1563
1714
|
$btn.on('touchstart click', $.proxy(function(e)
|
@@ -1569,10 +1720,12 @@
|
|
1569
1720
|
},
|
1570
1721
|
addDropdown: function($btn, dropdown)
|
1571
1722
|
{
|
1723
|
+
$btn.addClass('redactor-toolbar-link-dropdown').attr('aria-haspopup', true);
|
1724
|
+
|
1572
1725
|
var key = $btn.attr('rel');
|
1573
1726
|
this.button.addCallback($btn, 'dropdown');
|
1574
1727
|
|
1575
|
-
var $dropdown = $('<div class="redactor-dropdown redactor-dropdown-box-' + key + '" style="display: none;">');
|
1728
|
+
var $dropdown = $('<div class="redactor-dropdown redactor-dropdown-' + this.uuid + ' redactor-dropdown-box-' + key + '" style="display: none;">');
|
1576
1729
|
$btn.data('dropdown', $dropdown);
|
1577
1730
|
|
1578
1731
|
// build dropdown
|
@@ -1584,6 +1737,8 @@
|
|
1584
1737
|
{
|
1585
1738
|
if (!this.opts.toolbar) return;
|
1586
1739
|
|
1740
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1741
|
+
|
1587
1742
|
var btn = this.button.build(key, { title: title });
|
1588
1743
|
btn.addClass('redactor-btn-image');
|
1589
1744
|
|
@@ -1595,7 +1750,10 @@
|
|
1595
1750
|
{
|
1596
1751
|
if (!this.opts.toolbar) return;
|
1597
1752
|
|
1753
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1754
|
+
|
1598
1755
|
var btn = this.button.build(key, { title: title });
|
1756
|
+
btn.addClass('redactor-btn-image');
|
1599
1757
|
this.$toolbar.prepend($('<li>').append(btn));
|
1600
1758
|
|
1601
1759
|
return btn;
|
@@ -1604,7 +1762,10 @@
|
|
1604
1762
|
{
|
1605
1763
|
if (!this.opts.toolbar) return;
|
1606
1764
|
|
1765
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1766
|
+
|
1607
1767
|
var btn = this.button.build(key, { title: title });
|
1768
|
+
btn.addClass('redactor-btn-image');
|
1608
1769
|
var $btn = this.button.get(afterkey);
|
1609
1770
|
|
1610
1771
|
if ($btn.length !== 0) $btn.parent().after($('<li>').append(btn));
|
@@ -1616,7 +1777,10 @@
|
|
1616
1777
|
{
|
1617
1778
|
if (!this.opts.toolbar) return;
|
1618
1779
|
|
1780
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1781
|
+
|
1619
1782
|
var btn = this.button.build(key, { title: title });
|
1783
|
+
btn.addClass('redactor-btn-image');
|
1620
1784
|
var $btn = this.button.get(beforekey);
|
1621
1785
|
|
1622
1786
|
if ($btn.length !== 0) $btn.parent().before($('<li>').append(btn));
|
@@ -1627,6 +1791,10 @@
|
|
1627
1791
|
remove: function(key)
|
1628
1792
|
{
|
1629
1793
|
this.button.get(key).remove();
|
1794
|
+
},
|
1795
|
+
isMobileUndoRedo: function(key)
|
1796
|
+
{
|
1797
|
+
return (key == "undo" || key == "redo") && !this.utils.isDesktop();
|
1630
1798
|
}
|
1631
1799
|
};
|
1632
1800
|
},
|
@@ -1650,7 +1818,14 @@
|
|
1650
1818
|
},
|
1651
1819
|
setEnd: function(node)
|
1652
1820
|
{
|
1821
|
+
node = node[0] || node;
|
1822
|
+
if (node.lastChild.nodeType == 1)
|
1823
|
+
{
|
1824
|
+
return this.caret.setAfter(node.lastChild);
|
1825
|
+
}
|
1826
|
+
|
1653
1827
|
this.caret.set(node, 1, node, 1);
|
1828
|
+
|
1654
1829
|
},
|
1655
1830
|
set: function(orgn, orgo, focn, foco)
|
1656
1831
|
{
|
@@ -1840,11 +2015,11 @@
|
|
1840
2015
|
|
1841
2016
|
// replace dollar sign to entity
|
1842
2017
|
html = html.replace(/\$/g, '$');
|
1843
|
-
html = html.replace(/”/g, '"');
|
1844
|
-
html = html.replace(/‘/g, '\'');
|
1845
|
-
html = html.replace(/’/g, '\'');
|
1846
2018
|
|
1847
|
-
|
2019
|
+
// replace special characters in links
|
2020
|
+
html = html.replace(/<a href="(.*?[^>]?)®(.*?[^>]?)">/gi, '<a href="$1®$2">');
|
2021
|
+
|
2022
|
+
if (this.opts.replaceDivs && !this.opts.linebreaks) html = this.clean.replaceDivs(html);
|
1848
2023
|
if (this.opts.linebreaks) html = this.clean.replaceParagraphsToBr(html);
|
1849
2024
|
|
1850
2025
|
// save form tag
|
@@ -1865,10 +2040,11 @@
|
|
1865
2040
|
|
1866
2041
|
html = $div.html();
|
1867
2042
|
}
|
2043
|
+
|
1868
2044
|
$div.remove();
|
1869
2045
|
|
1870
2046
|
// remove font tag
|
1871
|
-
html = html.replace(/<font(.*?
|
2047
|
+
html = html.replace(/<font(.*?)>/gi, '');
|
1872
2048
|
html = html.replace(/<\/font>/gi, '');
|
1873
2049
|
|
1874
2050
|
// tidy html
|
@@ -1883,12 +2059,14 @@
|
|
1883
2059
|
// convert inline tags
|
1884
2060
|
html = this.clean.convertInline(html);
|
1885
2061
|
|
2062
|
+
html = html.replace(/&/g, '&');
|
2063
|
+
|
1886
2064
|
return html;
|
1887
2065
|
},
|
1888
2066
|
onSync: function(html)
|
1889
2067
|
{
|
1890
2068
|
// remove spaces
|
1891
|
-
html = html.replace(
|
2069
|
+
html = html.replace(/\u200B/g, '');
|
1892
2070
|
html = html.replace(/​/gi, '');
|
1893
2071
|
|
1894
2072
|
if (this.opts.cleanSpaces)
|
@@ -1920,17 +2098,41 @@
|
|
1920
2098
|
html = html.replace(new RegExp(i, 'g'), s);
|
1921
2099
|
});
|
1922
2100
|
|
1923
|
-
// remove br in
|
2101
|
+
// remove last br in FF
|
2102
|
+
if (this.utils.browser('mozilla'))
|
2103
|
+
{
|
2104
|
+
html = html.replace(/<br\s?\/?>$/gi, '');
|
2105
|
+
}
|
2106
|
+
|
2107
|
+
// remove br in|of li tags
|
1924
2108
|
html = html.replace(new RegExp('<br\\s?/?></li>', 'gi'), '</li>');
|
1925
2109
|
html = html.replace(new RegExp('</li><br\\s?/?>', 'gi'), '</li>');
|
2110
|
+
|
2111
|
+
// remove empty attributes
|
2112
|
+
html = html.replace(/<(.*?)rel="\s*?"(.*?[^>]?)>/gi, '<$1$2">');
|
2113
|
+
html = html.replace(/<(.*?)style="\s*?"(.*?[^>]?)>/gi, '<$1$2">');
|
2114
|
+
html = html.replace(/="">/gi, '>');
|
2115
|
+
html = html.replace(/""">/gi, '">');
|
2116
|
+
html = html.replace(/"">/gi, '">');
|
2117
|
+
|
1926
2118
|
// remove verified
|
1927
|
-
html = html.replace(
|
1928
|
-
html = html.replace(
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
2119
|
+
html = html.replace(/<div(.*?)data-tagblock="redactor"(.*?[^>])>/gi, '<div$1$2>');
|
2120
|
+
html = html.replace(/<(.*?) data-verified="redactor"(.*?[^>])>/gi, '<$1$2>');
|
2121
|
+
|
2122
|
+
var $div = $("<div/>").html($.parseHTML(html, document, true));
|
2123
|
+
$div.find("span").removeAttr("rel");
|
2124
|
+
|
2125
|
+
$div.find('pre .redactor-invisible-space').each(function()
|
2126
|
+
{
|
2127
|
+
$(this).contents().unwrap();
|
2128
|
+
});
|
2129
|
+
|
2130
|
+
html = $div.html();
|
2131
|
+
|
2132
|
+
// remove rel attribute from img
|
2133
|
+
html = html.replace(/<img(.*?[^>])rel="(.*?[^>])"(.*?[^>])>/gi, '<img$1$3>');
|
2134
|
+
html = html.replace(/<span class="redactor-invisible-space">(.*?)<\/span>/gi, '$1');
|
2135
|
+
|
1934
2136
|
html = html.replace(/ data-save-url="(.*?[^>])"/gi, '');
|
1935
2137
|
|
1936
2138
|
// remove image resize
|
@@ -1939,7 +2141,7 @@
|
|
1939
2141
|
html = html.replace(/<span(.*?)id="redactor-image-editter"(.*?[^>])>(.*?)<\/span>/gi, '');
|
1940
2142
|
|
1941
2143
|
// remove font tag
|
1942
|
-
html = html.replace(/<font(.*?
|
2144
|
+
html = html.replace(/<font(.*?)>/gi, '');
|
1943
2145
|
html = html.replace(/<\/font>/gi, '');
|
1944
2146
|
|
1945
2147
|
// tidy html
|
@@ -1957,18 +2159,17 @@
|
|
1957
2159
|
html = html.replace(new RegExp('<(.*?) data-verified="redactor"(.*?[^>])>', 'gi'), '<$1$2>');
|
1958
2160
|
html = html.replace(new RegExp('<(.*?) data-verified="redactor">', 'gi'), '<$1>');
|
1959
2161
|
|
2162
|
+
html = html.replace(/&/g, '&');
|
2163
|
+
|
1960
2164
|
return html;
|
1961
2165
|
},
|
1962
2166
|
onPaste: function(html, setMode)
|
1963
2167
|
{
|
1964
2168
|
html = $.trim(html);
|
1965
|
-
|
1966
2169
|
html = html.replace(/\$/g, '$');
|
1967
|
-
html = html.replace(/‘/g, '\'');
|
1968
|
-
html = html.replace(/’/g, '\'');
|
1969
2170
|
|
1970
2171
|
// convert dirty spaces
|
1971
|
-
html = html.replace(/<span class="
|
2172
|
+
html = html.replace(/<span class="s[0-9]">/gi, '<span>');
|
1972
2173
|
html = html.replace(/<span class="Apple-converted-space"> <\/span>/gi, ' ');
|
1973
2174
|
html = html.replace(/<span class="Apple-tab-span"[^>]*>\t<\/span>/gi, '\t');
|
1974
2175
|
html = html.replace(/<span[^>]*>(\s| )<\/span>/gi, ' ');
|
@@ -1989,6 +2190,8 @@
|
|
1989
2190
|
{
|
1990
2191
|
html = html.replace(/”/g, '"');
|
1991
2192
|
html = html.replace(/“/g, '"');
|
2193
|
+
html = html.replace(/‘/g, '\'');
|
2194
|
+
html = html.replace(/’/g, '\'');
|
1992
2195
|
|
1993
2196
|
return this.clean.getPreCode(html);
|
1994
2197
|
}
|
@@ -2055,6 +2258,7 @@
|
|
2055
2258
|
html = this.clean.onPasteRemoveSpans(html);
|
2056
2259
|
html = this.clean.onPasteRemoveEmpty(html);
|
2057
2260
|
|
2261
|
+
|
2058
2262
|
html = this.clean.convertInline(html);
|
2059
2263
|
|
2060
2264
|
return html;
|
@@ -2067,20 +2271,108 @@
|
|
2067
2271
|
// style
|
2068
2272
|
html = html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
|
2069
2273
|
|
2070
|
-
|
2274
|
+
// op
|
2275
|
+
html = html.replace(/<o\:p[^>]*>[\s\S]*?<\/o\:p>/gi, '');
|
2276
|
+
|
2277
|
+
if (html.match(/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i))
|
2071
2278
|
{
|
2279
|
+
// comments
|
2280
|
+
html = html.replace(/<!--[\s\S]+?-->/gi, '');
|
2281
|
+
|
2282
|
+
// scripts
|
2283
|
+
html = html.replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, '');
|
2284
|
+
|
2285
|
+
// Convert <s> into <strike>
|
2286
|
+
html = html.replace(/<(\/?)s>/gi, "<$1strike>");
|
2287
|
+
|
2288
|
+
// Replace nbsp entites to char since it's easier to handle
|
2289
|
+
html = html.replace(/ /gi, ' ');
|
2290
|
+
|
2291
|
+
// Convert <span style="mso-spacerun:yes">___</span> to string of alternating
|
2292
|
+
// breaking/non-breaking spaces of same length
|
2293
|
+
html = html.replace(/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function(str, spaces) {
|
2294
|
+
return (spaces.length > 0) ? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : '';
|
2295
|
+
});
|
2296
|
+
|
2072
2297
|
html = this.clean.onPasteIeFixLinks(html);
|
2073
2298
|
|
2074
2299
|
// shapes
|
2075
2300
|
html = html.replace(/<img(.*?)v:shapes=(.*?)>/gi, '');
|
2076
2301
|
html = html.replace(/src="file\:\/\/(.*?)"/, 'src=""');
|
2077
2302
|
|
2078
|
-
//
|
2079
|
-
|
2080
|
-
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2303
|
+
// lists
|
2304
|
+
var $div = $("<div/>").html(html);
|
2305
|
+
|
2306
|
+
var lastList = false;
|
2307
|
+
var lastLevel = 1;
|
2308
|
+
var listsIds = [];
|
2309
|
+
|
2310
|
+
$div.find("p[style]").each(function()
|
2311
|
+
{
|
2312
|
+
var matches = $(this).attr('style').match(/mso\-list\:l([0-9]+)\slevel([0-9]+)/);
|
2313
|
+
|
2314
|
+
if (matches)
|
2315
|
+
{
|
2316
|
+
var currentList = parseInt(matches[1]);
|
2317
|
+
var currentLevel = parseInt(matches[2]);
|
2318
|
+
var listType = $(this).html().match(/^[\w]+\./) ? "ol" : "ul";
|
2319
|
+
|
2320
|
+
var $li = $("<li/>").html($(this).html());
|
2321
|
+
|
2322
|
+
$li.html($li.html().replace(/^([\w\.]+)</, '<'));
|
2323
|
+
$li.find("span:first").remove();
|
2324
|
+
|
2325
|
+
if (currentLevel == 1 && $.inArray(currentList, listsIds) == -1)
|
2326
|
+
{
|
2327
|
+
var $list = $("<" + listType + "/>").attr({"data-level": currentLevel,
|
2328
|
+
"data-list": currentList})
|
2329
|
+
.html($li);
|
2330
|
+
|
2331
|
+
$(this).replaceWith($list);
|
2332
|
+
|
2333
|
+
lastList = currentList;
|
2334
|
+
listsIds.push(currentList);
|
2335
|
+
}
|
2336
|
+
else
|
2337
|
+
{
|
2338
|
+
if (currentLevel > lastLevel)
|
2339
|
+
{
|
2340
|
+
var $prevList = $div.find('[data-level="' + lastLevel + '"][data-list="' + lastList + '"]');
|
2341
|
+
|
2342
|
+
var $lastList = $prevList;
|
2343
|
+
|
2344
|
+
for(var i = lastLevel; i < currentLevel; i++)
|
2345
|
+
{
|
2346
|
+
$list = $("<" + listType + "/>");
|
2347
|
+
|
2348
|
+
$list.appendTo($lastList.find("li").last());
|
2349
|
+
|
2350
|
+
$lastList = $list;
|
2351
|
+
}
|
2352
|
+
|
2353
|
+
$lastList.attr({"data-level": currentLevel,
|
2354
|
+
"data-list": currentList})
|
2355
|
+
.html($li);
|
2356
|
+
|
2357
|
+
}
|
2358
|
+
else
|
2359
|
+
{
|
2360
|
+
var $prevList = $div.find('[data-level="' + currentLevel + '"][data-list="' + currentList + '"]').last();
|
2361
|
+
|
2362
|
+
$prevList.append($li);
|
2363
|
+
}
|
2364
|
+
|
2365
|
+
lastLevel = currentLevel;
|
2366
|
+
lastList = currentList;
|
2367
|
+
|
2368
|
+
$(this).remove();
|
2369
|
+
}
|
2370
|
+
}
|
2371
|
+
});
|
2372
|
+
|
2373
|
+
$div.find('[data-level][data-list]').removeAttr('data-level data-list');
|
2374
|
+
html = $div.html();
|
2375
|
+
|
2084
2376
|
// remove ms word's bullet
|
2085
2377
|
html = html.replace(/·/g, '');
|
2086
2378
|
html = html.replace(/<p class="Mso(.*?)"/gi, '<p');
|
@@ -2099,12 +2391,6 @@
|
|
2099
2391
|
html = html.replace(/<p>\n?<li>/gi, '<li>');
|
2100
2392
|
}
|
2101
2393
|
|
2102
|
-
// remove nbsp
|
2103
|
-
if (this.opts.cleanSpaces)
|
2104
|
-
{
|
2105
|
-
html = html.replace(/(\s| )+/g, ' ');
|
2106
|
-
}
|
2107
|
-
|
2108
2394
|
return html;
|
2109
2395
|
},
|
2110
2396
|
onPasteExtra: function(html)
|
@@ -2199,23 +2485,16 @@
|
|
2199
2485
|
}
|
2200
2486
|
|
2201
2487
|
var options = {
|
2202
|
-
deniedTags: false,
|
2203
|
-
allowedTags: tags,
|
2488
|
+
deniedTags: (this.opts.deniedTags) ? this.opts.deniedTags : false,
|
2489
|
+
allowedTags: (this.opts.allowedTags) ? this.opts.allowedTags : tags,
|
2204
2490
|
removeComments: true,
|
2205
2491
|
removePhp: true,
|
2206
|
-
removeAttr: false,
|
2207
|
-
allowedAttr: attrAllowed,
|
2492
|
+
removeAttr: (this.opts.removeAttr) ? this.opts.removeAttr : false,
|
2493
|
+
allowedAttr: (this.opts.allowedAttr) ? this.opts.allowedAttr : attrAllowed,
|
2208
2494
|
removeEmpty: tagsEmpty
|
2209
2495
|
};
|
2210
2496
|
|
2211
|
-
// denied tags
|
2212
|
-
if (this.opts.deniedTags)
|
2213
|
-
{
|
2214
|
-
options.deniedTags = this.opts.deniedTags;
|
2215
|
-
}
|
2216
|
-
|
2217
2497
|
return this.tidy.load(html, options);
|
2218
|
-
|
2219
2498
|
},
|
2220
2499
|
onPasteRemoveEmpty: function(html)
|
2221
2500
|
{
|
@@ -2259,8 +2538,8 @@
|
|
2259
2538
|
if (!matchBlocks && (matchContainers === null || (matchContainers && matchContainers.length <= 1)))
|
2260
2539
|
{
|
2261
2540
|
var matchBR = html.match(/<br\s?\/?>/gi);
|
2262
|
-
var matchIMG = html.match(/<img(.*?[^>])>/gi);
|
2263
|
-
if (!matchBR
|
2541
|
+
//var matchIMG = html.match(/<img(.*?[^>])>/gi);
|
2542
|
+
if (!matchBR)
|
2264
2543
|
{
|
2265
2544
|
this.clean.singleLine = true;
|
2266
2545
|
html = html.replace(/<\/?(p|div)(.*?)>/gi, '');
|
@@ -2281,33 +2560,69 @@
|
|
2281
2560
|
},
|
2282
2561
|
savePreCode: function(html)
|
2283
2562
|
{
|
2284
|
-
|
2563
|
+
html = this.clean.savePreFormatting(html);
|
2564
|
+
html = this.clean.saveCodeFormatting(html);
|
2565
|
+
|
2566
|
+
html = this.clean.restoreSelectionMarker(html);
|
2567
|
+
|
2568
|
+
return html;
|
2569
|
+
},
|
2570
|
+
savePreFormatting: function(html)
|
2571
|
+
{
|
2572
|
+
var pre = html.match(/<pre(.*?)>([\w\W]*?)<\/pre>/gi);
|
2573
|
+
|
2285
2574
|
if (pre !== null)
|
2286
2575
|
{
|
2287
2576
|
$.each(pre, $.proxy(function(i,s)
|
2288
2577
|
{
|
2289
|
-
var arr = s.match(/<
|
2578
|
+
var arr = s.match(/<pre(.*?)>([\w\W]*?)<\/pre>/i);
|
2290
2579
|
|
2291
|
-
arr[
|
2292
|
-
arr[
|
2580
|
+
arr[2] = arr[2].replace(/<br\s?\/?>/g, '\n');
|
2581
|
+
arr[2] = arr[2].replace(/ /g, ' ');
|
2293
2582
|
|
2294
2583
|
if (this.opts.preSpaces)
|
2295
2584
|
{
|
2296
|
-
arr[
|
2585
|
+
arr[2] = arr[2].replace(/\t/g, Array(this.opts.preSpaces + 1).join(' '));
|
2297
2586
|
}
|
2298
2587
|
|
2299
|
-
arr[
|
2588
|
+
arr[2] = this.clean.encodeEntities(arr[2]);
|
2300
2589
|
|
2301
2590
|
// $ fix
|
2302
|
-
arr[
|
2591
|
+
arr[2] = arr[2].replace(/\$/g, '$');
|
2592
|
+
|
2593
|
+
html = html.replace(s, '<pre' + arr[1] + '>' + arr[2] + '</pre>');
|
2594
|
+
|
2595
|
+
}, this));
|
2596
|
+
}
|
2303
2597
|
|
2304
|
-
|
2598
|
+
return html;
|
2599
|
+
},
|
2600
|
+
saveCodeFormatting: function(html)
|
2601
|
+
{
|
2602
|
+
var code = html.match(/<code(.*?)>([\w\W]*?)<\/code>/gi);
|
2603
|
+
|
2604
|
+
if (code !== null)
|
2605
|
+
{
|
2606
|
+
$.each(code, $.proxy(function(i,s)
|
2607
|
+
{
|
2608
|
+
var arr = s.match(/<code(.*?)>([\w\W]*?)<\/code>/i);
|
2305
2609
|
|
2610
|
+
arr[2] = arr[2].replace(/ /g, ' ');
|
2611
|
+
arr[2] = this.clean.encodeEntities(arr[2]);
|
2612
|
+
arr[2] = arr[2].replace(/\$/g, '$');
|
2613
|
+
|
2614
|
+
html = html.replace(s, '<code' + arr[1] + '>' + arr[2] + '</code>');
|
2306
2615
|
}, this));
|
2307
2616
|
}
|
2308
2617
|
|
2309
2618
|
return html;
|
2310
2619
|
},
|
2620
|
+
restoreSelectionMarker: function(html)
|
2621
|
+
{
|
2622
|
+
html = html.replace(/<span id="selection-marker-([0-9])" class="redactor-selection-marker" data-verified="redactor"><\/span>/g, '<span id="selection-marker-$1" class="redactor-selection-marker" data-verified="redactor"></span>');
|
2623
|
+
|
2624
|
+
return html;
|
2625
|
+
},
|
2311
2626
|
getTextFromHtml: function(html)
|
2312
2627
|
{
|
2313
2628
|
html = html.replace(/<br\s?\/?>|<\/H[1-6]>|<\/p>|<\/div>|<\/li>|<\/td>/gi, '\n');
|
@@ -2321,9 +2636,11 @@
|
|
2321
2636
|
getPlainText: function(html, paragraphize)
|
2322
2637
|
{
|
2323
2638
|
html = this.clean.getTextFromHtml(html);
|
2639
|
+
html = html.replace(/\n\s*\n/g, "\n");
|
2640
|
+
html = html.replace(/\n\n/g, "\n");
|
2324
2641
|
html = html.replace(/\n/g, '<br />');
|
2325
2642
|
|
2326
|
-
if (this.opts.paragraphize && typeof paragraphize == 'undefined')
|
2643
|
+
if (this.opts.paragraphize && typeof paragraphize == 'undefined' && !this.utils.browser('mozilla'))
|
2327
2644
|
{
|
2328
2645
|
html = this.paragraphize.load(html);
|
2329
2646
|
}
|
@@ -2411,23 +2728,30 @@
|
|
2411
2728
|
$s.attr('style', $s.attr('rel'));
|
2412
2729
|
});
|
2413
2730
|
|
2731
|
+
},
|
2732
|
+
cleanEmptyParagraph: function()
|
2733
|
+
{
|
2734
|
+
|
2414
2735
|
},
|
2415
2736
|
setVerified: function(html)
|
2416
2737
|
{
|
2417
2738
|
if (this.utils.browser('msie')) return html;
|
2418
2739
|
|
2419
2740
|
html = html.replace(new RegExp('<img(.*?[^>])>', 'gi'), '<img$1 data-verified="redactor">');
|
2420
|
-
html = html.replace(new RegExp('<span(.*?)>', 'gi'), '<span$1 data-verified="redactor">');
|
2741
|
+
html = html.replace(new RegExp('<span(.*?[^>])>', 'gi'), '<span$1 data-verified="redactor">');
|
2421
2742
|
|
2422
2743
|
var matches = html.match(new RegExp('<(span|img)(.*?)style="(.*?)"(.*?[^>])>', 'gi'));
|
2744
|
+
|
2423
2745
|
if (matches)
|
2424
2746
|
{
|
2425
2747
|
var len = matches.length;
|
2426
2748
|
for (var i = 0; i < len; i++)
|
2427
2749
|
{
|
2428
2750
|
try {
|
2751
|
+
|
2429
2752
|
var newTag = matches[i].replace(/style="(.*?)"/i, 'style="$1" rel="$1"');
|
2430
|
-
html = html.replace(
|
2753
|
+
html = html.replace(matches[i], newTag);
|
2754
|
+
|
2431
2755
|
}
|
2432
2756
|
catch (e) {}
|
2433
2757
|
}
|
@@ -2482,7 +2806,7 @@
|
|
2482
2806
|
html = html.replace(/[\s\n]*$/g, ' ');
|
2483
2807
|
html = html.replace( />\s{2,}</g, '> <'); // between inline tags can be only one space
|
2484
2808
|
html = html.replace(/\n\n/g, "\n");
|
2485
|
-
html = html.replace(
|
2809
|
+
html = html.replace(/\u200B/g, '');
|
2486
2810
|
|
2487
2811
|
return html;
|
2488
2812
|
},
|
@@ -2498,6 +2822,9 @@
|
|
2498
2822
|
html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p$1>$2</p>');
|
2499
2823
|
}
|
2500
2824
|
|
2825
|
+
html = html.replace(/<div(.*?[^>])>/gi, '');
|
2826
|
+
html = html.replace(/<\/div>/gi, '');
|
2827
|
+
|
2501
2828
|
return html;
|
2502
2829
|
},
|
2503
2830
|
replaceDivsToBr: function(html)
|
@@ -2537,9 +2864,17 @@
|
|
2537
2864
|
// clean
|
2538
2865
|
html = this.clean.onSet(html);
|
2539
2866
|
|
2867
|
+
|
2868
|
+
if (this.utils.browser('msie'))
|
2869
|
+
{
|
2870
|
+
html = html.replace(/<span(.*?)id="selection-marker-(1|2)"(.*?)><\/span>/gi, '');
|
2871
|
+
}
|
2872
|
+
|
2540
2873
|
this.$editor.html(html);
|
2541
2874
|
this.code.sync();
|
2542
2875
|
|
2876
|
+
if (html !== '') this.placeholder.remove();
|
2877
|
+
|
2543
2878
|
setTimeout($.proxy(this.buffer.add, this), 15);
|
2544
2879
|
if (this.start === false) this.observe.load();
|
2545
2880
|
|
@@ -2548,6 +2883,9 @@
|
|
2548
2883
|
{
|
2549
2884
|
var code = this.$textarea.val();
|
2550
2885
|
|
2886
|
+
if (this.opts.replaceDivs) code = this.clean.replaceDivs(code);
|
2887
|
+
if (this.opts.linebreaks) code = this.clean.replaceParagraphsToBr(code);
|
2888
|
+
|
2551
2889
|
// indent code
|
2552
2890
|
code = this.tabifier.get(code);
|
2553
2891
|
|
@@ -2562,7 +2900,7 @@
|
|
2562
2900
|
var html = this.$editor.html();
|
2563
2901
|
|
2564
2902
|
// is there a need to synchronize
|
2565
|
-
if (this.code.syncCode && this.code.syncCode == html)
|
2903
|
+
if (this.code.syncCode && this.code.syncCode == html || (this.start && html == '' ))
|
2566
2904
|
{
|
2567
2905
|
// do not sync
|
2568
2906
|
return;
|
@@ -2590,11 +2928,25 @@
|
|
2590
2928
|
|
2591
2929
|
this.start = false;
|
2592
2930
|
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
|
2597
|
-
|
2931
|
+
if (this.autosave.html == false)
|
2932
|
+
{
|
2933
|
+
this.autosave.html = this.code.get();
|
2934
|
+
}
|
2935
|
+
|
2936
|
+
if (this.opts.codemirror)
|
2937
|
+
{
|
2938
|
+
this.$textarea.next('.CodeMirror').each(function(i, el)
|
2939
|
+
{
|
2940
|
+
el.CodeMirror.setValue(html);
|
2941
|
+
});
|
2942
|
+
}
|
2943
|
+
|
2944
|
+
//autosave
|
2945
|
+
this.autosave.onChange();
|
2946
|
+
this.autosave.enable();
|
2947
|
+
},
|
2948
|
+
toggle: function()
|
2949
|
+
{
|
2598
2950
|
if (this.opts.visual)
|
2599
2951
|
{
|
2600
2952
|
this.code.showCode();
|
@@ -2606,30 +2958,85 @@
|
|
2606
2958
|
},
|
2607
2959
|
showCode: function()
|
2608
2960
|
{
|
2961
|
+
this.selection.save();
|
2962
|
+
|
2609
2963
|
this.code.offset = this.caret.getOffset();
|
2610
2964
|
var scroll = $(window).scrollTop();
|
2611
2965
|
|
2612
|
-
var
|
2966
|
+
var width = this.$editor.innerWidth(),
|
2967
|
+
height = this.$editor.innerHeight();
|
2613
2968
|
|
2614
2969
|
this.$editor.hide();
|
2615
2970
|
|
2616
2971
|
var html = this.$textarea.val();
|
2972
|
+
|
2617
2973
|
this.modified = this.clean.removeSpaces(html);
|
2618
2974
|
|
2619
2975
|
// indent code
|
2620
2976
|
html = this.tabifier.get(html);
|
2621
2977
|
|
2622
|
-
|
2623
|
-
|
2978
|
+
// caret position sync
|
2979
|
+
var start = 0, end = 0;
|
2980
|
+
var $editorDiv = $("<div/>").append($.parseHTML(this.clean.onSync(this.$editor.html()), document, true));
|
2981
|
+
var $selectionMarkers = $editorDiv.find("span.redactor-selection-marker");
|
2624
2982
|
|
2625
|
-
$
|
2983
|
+
if ($selectionMarkers.length > 0)
|
2984
|
+
{
|
2985
|
+
var editorHtml = this.tabifier.get($editorDiv.html()).replace(/&/g, '&');
|
2986
|
+
|
2987
|
+
if ($selectionMarkers.length == 1)
|
2988
|
+
{
|
2989
|
+
start = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-1").prop("outerHTML"));
|
2990
|
+
end = start;
|
2991
|
+
}
|
2992
|
+
else if ($selectionMarkers.length == 2)
|
2993
|
+
{
|
2994
|
+
start = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-1").prop("outerHTML"));
|
2995
|
+
end = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-2").prop("outerHTML")) - $editorDiv.find("#selection-marker-1").prop("outerHTML").toString().length;
|
2996
|
+
}
|
2997
|
+
}
|
2998
|
+
|
2999
|
+
this.selection.removeMarkers();
|
3000
|
+
this.$textarea.val(html);
|
2626
3001
|
|
2627
|
-
if (this
|
3002
|
+
if (this.opts.codemirror)
|
2628
3003
|
{
|
2629
|
-
this.$textarea
|
3004
|
+
this.$textarea.next('.CodeMirror').each(function(i, el)
|
3005
|
+
{
|
3006
|
+
$(el).show();
|
3007
|
+
el.CodeMirror.setValue(html);
|
3008
|
+
el.CodeMirror.setSize('100%', height);
|
3009
|
+
el.CodeMirror.refresh();
|
3010
|
+
|
3011
|
+
if (start == end)
|
3012
|
+
{
|
3013
|
+
el.CodeMirror.setCursor(el.CodeMirror.posFromIndex(start).line, el.CodeMirror.posFromIndex(end).ch);
|
3014
|
+
}
|
3015
|
+
else
|
3016
|
+
{
|
3017
|
+
el.CodeMirror.setSelection({line: el.CodeMirror.posFromIndex(start).line,
|
3018
|
+
ch: el.CodeMirror.posFromIndex(start).ch},
|
3019
|
+
{line: el.CodeMirror.posFromIndex(end).line,
|
3020
|
+
ch: el.CodeMirror.posFromIndex(end).ch});
|
3021
|
+
}
|
3022
|
+
|
3023
|
+
el.CodeMirror.focus();
|
3024
|
+
});
|
2630
3025
|
}
|
3026
|
+
else
|
3027
|
+
{
|
3028
|
+
this.$textarea.height(height).show().focus();
|
3029
|
+
this.$textarea.on('keydown.redactor-textarea-indenting', this.code.textareaIndenting);
|
3030
|
+
|
3031
|
+
$(window).scrollTop(scroll);
|
3032
|
+
|
3033
|
+
if (this.$textarea[0].setSelectionRange)
|
3034
|
+
{
|
3035
|
+
this.$textarea[0].setSelectionRange(start, end);
|
3036
|
+
}
|
2631
3037
|
|
2632
|
-
|
3038
|
+
this.$textarea[0].scrollTop = 0;
|
3039
|
+
}
|
2633
3040
|
|
2634
3041
|
this.opts.visual = false;
|
2635
3042
|
|
@@ -2639,13 +3046,67 @@
|
|
2639
3046
|
},
|
2640
3047
|
showVisual: function()
|
2641
3048
|
{
|
3049
|
+
var html;
|
3050
|
+
|
2642
3051
|
if (this.opts.visual) return;
|
2643
3052
|
|
2644
|
-
var
|
3053
|
+
var start = 0, end = 0;
|
3054
|
+
|
3055
|
+
if (this.opts.codemirror)
|
3056
|
+
{
|
3057
|
+
var selection;
|
3058
|
+
|
3059
|
+
this.$textarea.next('.CodeMirror').each(function(i, el)
|
3060
|
+
{
|
3061
|
+
selection = el.CodeMirror.listSelections();
|
3062
|
+
|
3063
|
+
start = el.CodeMirror.indexFromPos(selection[0].anchor);
|
3064
|
+
end = el.CodeMirror.indexFromPos(selection[0].head);
|
3065
|
+
|
3066
|
+
html = el.CodeMirror.getValue();
|
3067
|
+
});
|
3068
|
+
}
|
3069
|
+
else
|
3070
|
+
{
|
3071
|
+
start = this.$textarea.get(0).selectionStart;
|
3072
|
+
end = this.$textarea.get(0).selectionEnd;
|
3073
|
+
|
3074
|
+
html = this.$textarea.hide().val();
|
3075
|
+
}
|
3076
|
+
|
3077
|
+
// if selection starts from end
|
3078
|
+
if (start > end && end > 0)
|
3079
|
+
{
|
3080
|
+
var tempStart = end;
|
3081
|
+
var tempEnd = start;
|
3082
|
+
|
3083
|
+
start = tempStart;
|
3084
|
+
end = tempEnd;
|
3085
|
+
}
|
3086
|
+
|
3087
|
+
start = this.code.enlargeOffset(html, start);
|
3088
|
+
end = this.code.enlargeOffset(html, end);
|
3089
|
+
|
3090
|
+
html = html.substr(0, start) + this.selection.getMarkerAsHtml(1) + html.substr(start);
|
3091
|
+
|
3092
|
+
if (end > start)
|
3093
|
+
{
|
3094
|
+
var markerLength = this.selection.getMarkerAsHtml(1).toString().length;
|
3095
|
+
|
3096
|
+
html = html.substr(0, end + markerLength) + this.selection.getMarkerAsHtml(2) + html.substr(end + markerLength);
|
3097
|
+
}
|
3098
|
+
|
3099
|
+
|
2645
3100
|
|
2646
3101
|
if (this.modified !== this.clean.removeSpaces(html))
|
2647
3102
|
{
|
2648
3103
|
this.code.set(html);
|
3104
|
+
|
3105
|
+
}
|
3106
|
+
|
3107
|
+
if (this.opts.codemirror)
|
3108
|
+
{
|
3109
|
+
this.$textarea.next('.CodeMirror').hide();
|
2649
3110
|
}
|
2650
3111
|
|
2651
3112
|
this.$editor.show();
|
@@ -2655,15 +3116,15 @@
|
|
2655
3116
|
this.placeholder.remove();
|
2656
3117
|
}
|
2657
3118
|
|
2658
|
-
this.
|
3119
|
+
this.selection.restore();
|
2659
3120
|
|
2660
3121
|
this.$textarea.off('keydown.redactor-textarea-indenting');
|
2661
3122
|
|
2662
3123
|
this.button.setActiveInVisual();
|
2663
3124
|
this.button.setInactive('html');
|
2664
|
-
|
2665
3125
|
this.observe.load();
|
2666
3126
|
this.opts.visual = true;
|
3127
|
+
this.core.setCallback('visual', html);
|
2667
3128
|
},
|
2668
3129
|
textareaIndenting: function(e)
|
2669
3130
|
{
|
@@ -2675,6 +3136,35 @@
|
|
2675
3136
|
$el.get(0).selectionStart = $el.get(0).selectionEnd = start + 1;
|
2676
3137
|
|
2677
3138
|
return false;
|
3139
|
+
},
|
3140
|
+
enlargeOffset: function(html, offset)
|
3141
|
+
{
|
3142
|
+
var htmlLength = html.length;
|
3143
|
+
var c = 0;
|
3144
|
+
|
3145
|
+
if (html[offset] == '>')
|
3146
|
+
{
|
3147
|
+
c++;
|
3148
|
+
}
|
3149
|
+
else
|
3150
|
+
{
|
3151
|
+
for(var i = offset; i <= htmlLength; i++)
|
3152
|
+
{
|
3153
|
+
c++;
|
3154
|
+
|
3155
|
+
if (html[i] == '>')
|
3156
|
+
{
|
3157
|
+
break;
|
3158
|
+
}
|
3159
|
+
else if (html[i] == '<' || i == htmlLength)
|
3160
|
+
{
|
3161
|
+
c = 0;
|
3162
|
+
break;
|
3163
|
+
}
|
3164
|
+
}
|
3165
|
+
}
|
3166
|
+
|
3167
|
+
return offset + c;
|
2678
3168
|
}
|
2679
3169
|
};
|
2680
3170
|
},
|
@@ -2715,7 +3205,31 @@
|
|
2715
3205
|
},
|
2716
3206
|
setCallback: function(type, e, data)
|
2717
3207
|
{
|
2718
|
-
var
|
3208
|
+
var eventName = type + 'Callback';
|
3209
|
+
var eventNamespace = 'redactor';
|
3210
|
+
var callback = this.opts[eventName];
|
3211
|
+
|
3212
|
+
if (this.$textarea)
|
3213
|
+
{
|
3214
|
+
var returnValue = false;
|
3215
|
+
var events = $._data(this.$textarea[0], 'events');
|
3216
|
+
|
3217
|
+
if (typeof events != 'undefined' && typeof events[eventName] != 'undefined')
|
3218
|
+
{
|
3219
|
+
$.each(events[eventName], $.proxy(function(key, value)
|
3220
|
+
{
|
3221
|
+
if (value['namespace'] == eventNamespace)
|
3222
|
+
{
|
3223
|
+
var data = (typeof data == 'undefined') ? [e] : [e, data];
|
3224
|
+
|
3225
|
+
returnValue = (typeof data == 'undefined') ? value.handler.call(this, e) : value.handler.call(this, e, data);
|
3226
|
+
}
|
3227
|
+
}, this));
|
3228
|
+
}
|
3229
|
+
|
3230
|
+
if (returnValue) return returnValue;
|
3231
|
+
}
|
3232
|
+
|
2719
3233
|
if ($.isFunction(callback))
|
2720
3234
|
{
|
2721
3235
|
return (typeof data == 'undefined') ? callback.call(this, e) : callback.call(this, e, data);
|
@@ -2727,18 +3241,42 @@
|
|
2727
3241
|
},
|
2728
3242
|
destroy: function()
|
2729
3243
|
{
|
3244
|
+
this.opts.destroyed = true;
|
3245
|
+
|
2730
3246
|
this.core.setCallback('destroy');
|
2731
3247
|
|
2732
3248
|
// off events and remove data
|
2733
3249
|
this.$element.off('.redactor').removeData('redactor');
|
2734
3250
|
this.$editor.off('.redactor');
|
2735
3251
|
|
3252
|
+
$(document).off('mousedown.redactor-blur.' + this.uuid);
|
3253
|
+
$(document).off('mousedown.redactor.' + this.uuid);
|
3254
|
+
$(document).off('click.redactor-image-delete.' + this.uuid);
|
3255
|
+
$(document).off('click.redactor-image-resize-hide.' + this.uuid);
|
3256
|
+
$(document).off('touchstart.redactor.' + this.uuid + ' click.redactor.' + this.uuid);
|
3257
|
+
$("body").off('scroll.redactor.' + this.uuid);
|
3258
|
+
$(this.opts.toolbarFixedTarget).off('scroll.redactor.' + this.uuid);
|
3259
|
+
|
2736
3260
|
// common
|
2737
3261
|
this.$editor.removeClass('redactor-editor redactor-linebreaks redactor-placeholder');
|
2738
3262
|
this.$editor.removeAttr('contenteditable');
|
2739
3263
|
|
2740
3264
|
var html = this.code.get();
|
2741
3265
|
|
3266
|
+
if (this.opts.toolbar)
|
3267
|
+
{
|
3268
|
+
// dropdowns off
|
3269
|
+
this.$toolbar.find('a').each(function()
|
3270
|
+
{
|
3271
|
+
var $el = $(this);
|
3272
|
+
if ($el.data('dropdown'))
|
3273
|
+
{
|
3274
|
+
$el.data('dropdown').remove();
|
3275
|
+
$el.data('dropdown', {});
|
3276
|
+
}
|
3277
|
+
});
|
3278
|
+
}
|
3279
|
+
|
2742
3280
|
if (this.build.isTextarea())
|
2743
3281
|
{
|
2744
3282
|
this.$box.after(this.$element);
|
@@ -2760,11 +3298,10 @@
|
|
2760
3298
|
if (this.$modalOverlay) this.$modalOverlay.remove();
|
2761
3299
|
|
2762
3300
|
// buttons tooltip
|
2763
|
-
$('.redactor-toolbar-tooltip').remove();
|
3301
|
+
$('.redactor-toolbar-tooltip-' + this.uuid).remove();
|
2764
3302
|
|
2765
3303
|
// autosave
|
2766
3304
|
clearInterval(this.autosaveInterval);
|
2767
|
-
|
2768
3305
|
}
|
2769
3306
|
};
|
2770
3307
|
},
|
@@ -2777,21 +3314,31 @@
|
|
2777
3314
|
{
|
2778
3315
|
$.each(this.opts.formattingAdd, $.proxy(function(i,s)
|
2779
3316
|
{
|
2780
|
-
var name = s.tag
|
2781
|
-
|
3317
|
+
var name = s.tag,
|
3318
|
+
func;
|
3319
|
+
|
3320
|
+
if (typeof s['class'] != 'undefined')
|
2782
3321
|
{
|
2783
|
-
name = name + '-' + s
|
3322
|
+
name = name + '-' + s['class'];
|
2784
3323
|
}
|
2785
3324
|
|
2786
3325
|
s.type = (this.utils.isBlockTag(s.tag)) ? 'block' : 'inline';
|
2787
|
-
|
3326
|
+
|
3327
|
+
if (typeof s.func !== "undefined")
|
3328
|
+
{
|
3329
|
+
func = s.func;
|
3330
|
+
}
|
3331
|
+
else
|
3332
|
+
{
|
3333
|
+
func = (s.type == 'inline') ? 'inline.formatting' : 'block.formatting';
|
3334
|
+
}
|
2788
3335
|
|
2789
3336
|
if (this.opts.linebreaks && s.type == 'block' && s.tag == 'p') return;
|
2790
3337
|
|
2791
3338
|
this.formatting[name] = {
|
2792
3339
|
tag: s.tag,
|
2793
3340
|
style: s.style,
|
2794
|
-
'class': s
|
3341
|
+
'class': s['class'],
|
2795
3342
|
attr: s.attr,
|
2796
3343
|
data: s.data,
|
2797
3344
|
clear: s.clear
|
@@ -2803,12 +3350,11 @@
|
|
2803
3350
|
};
|
2804
3351
|
|
2805
3352
|
}, this));
|
2806
|
-
|
2807
3353
|
}
|
2808
3354
|
|
2809
3355
|
$.each(dropdownObject, $.proxy(function(btnName, btnObject)
|
2810
3356
|
{
|
2811
|
-
var $item = $('<a href="#" class="redactor-dropdown-' + btnName + '">' + btnObject.title + '</a>');
|
3357
|
+
var $item = $('<a href="#" class="redactor-dropdown-' + btnName + '" role="button">' + btnObject.title + '</a>');
|
2812
3358
|
if (name == 'formatting') $item.addClass('redactor-formatting-' + btnName);
|
2813
3359
|
|
2814
3360
|
$item.on('click', $.proxy(function(e)
|
@@ -2828,11 +3374,15 @@
|
|
2828
3374
|
callback = btnObject.dropdown;
|
2829
3375
|
}
|
2830
3376
|
|
3377
|
+
if ($(e.target).hasClass('redactor-dropdown-link-inactive')) return;
|
3378
|
+
|
2831
3379
|
this.button.onClick(e, btnName, type, callback);
|
2832
3380
|
this.dropdown.hideAll();
|
2833
3381
|
|
2834
3382
|
}, this));
|
2835
3383
|
|
3384
|
+
this.observe.addDropdown($item, btnName, btnObject);
|
3385
|
+
|
2836
3386
|
$dropdown.append($item);
|
2837
3387
|
|
2838
3388
|
}, this));
|
@@ -2850,10 +3400,9 @@
|
|
2850
3400
|
// Always re-append it to the end of <body> so it always has the highest sub-z-index.
|
2851
3401
|
var $dropdown = $button.data('dropdown').appendTo(document.body);
|
2852
3402
|
|
2853
|
-
|
2854
|
-
if (this.utils.isMobile() && !this.utils.browser('msie'))
|
3403
|
+
if (this.opts.highContrast)
|
2855
3404
|
{
|
2856
|
-
|
3405
|
+
$dropdown.addClass("redactor-dropdown-contrast");
|
2857
3406
|
}
|
2858
3407
|
|
2859
3408
|
if ($button.hasClass('dropact'))
|
@@ -2863,6 +3412,8 @@
|
|
2863
3412
|
else
|
2864
3413
|
{
|
2865
3414
|
this.dropdown.hideAll();
|
3415
|
+
this.observe.dropdowns();
|
3416
|
+
|
2866
3417
|
this.core.setCallback('dropdownShow', { dropdown: $dropdown, key: key, button: $button });
|
2867
3418
|
|
2868
3419
|
this.button.setActive(key);
|
@@ -2898,47 +3449,58 @@
|
|
2898
3449
|
$dropdown.css({ position: 'absolute', left: left, top: top }).show();
|
2899
3450
|
}
|
2900
3451
|
|
2901
|
-
|
2902
3452
|
this.core.setCallback('dropdownShown', { dropdown: $dropdown, key: key, button: $button });
|
2903
|
-
}
|
2904
|
-
|
2905
|
-
$(document).one('click', $.proxy(this.dropdown.hide, this));
|
2906
|
-
this.$editor.one('click', $.proxy(this.dropdown.hide, this));
|
2907
3453
|
|
2908
|
-
|
2909
|
-
|
2910
|
-
var width = $body.width();
|
2911
|
-
|
2912
|
-
$dropdown.on('mouseover', function() {
|
2913
|
-
|
2914
|
-
$body.addClass('body-redactor-hidden');
|
2915
|
-
$body.css('margin-right', ($body.width() - width) + 'px');
|
2916
|
-
|
2917
|
-
});
|
2918
|
-
|
2919
|
-
$dropdown.on('mouseout', function() {
|
3454
|
+
this.$dropdown = $dropdown;
|
3455
|
+
}
|
2920
3456
|
|
2921
|
-
$body.removeClass('body-redactor-hidden').css('margin-right', 0);
|
2922
3457
|
|
2923
|
-
|
3458
|
+
$(document).one('click.redactor-dropdown', $.proxy(this.dropdown.hide, this));
|
3459
|
+
this.$editor.one('click.redactor-dropdown', $.proxy(this.dropdown.hide, this));
|
3460
|
+
$(document).one('keyup.redactor-dropdown', $.proxy(this.dropdown.closeHandler, this));
|
2924
3461
|
|
3462
|
+
// disable scroll whan dropdown scroll
|
3463
|
+
$dropdown.on('mouseover.redactor-dropdown', $.proxy(this.utils.disableBodyScroll, this)).on('mouseout.redactor-dropdown', $.proxy(this.utils.enableBodyScroll, this));
|
2925
3464
|
|
2926
3465
|
e.stopPropagation();
|
2927
3466
|
},
|
3467
|
+
closeHandler: function(e)
|
3468
|
+
{
|
3469
|
+
if (e.which != this.keyCode.ESC) return;
|
3470
|
+
|
3471
|
+
this.dropdown.hideAll();
|
3472
|
+
this.$editor.focus();
|
3473
|
+
},
|
2928
3474
|
hideAll: function()
|
2929
3475
|
{
|
2930
3476
|
this.$toolbar.find('a.dropact').removeClass('redactor-act').removeClass('dropact');
|
2931
3477
|
|
2932
|
-
|
2933
|
-
|
2934
|
-
this.
|
3478
|
+
this.utils.enableBodyScroll();
|
3479
|
+
|
3480
|
+
$('.redactor-dropdown-' + this.uuid).hide();
|
3481
|
+
$('.redactor-dropdown-link-selected').removeClass('redactor-dropdown-link-selected');
|
3482
|
+
|
3483
|
+
|
3484
|
+
if (this.$dropdown)
|
3485
|
+
{
|
3486
|
+
this.$dropdown.off('.redactor-dropdown');
|
3487
|
+
this.core.setCallback('dropdownHide', this.$dropdown);
|
3488
|
+
|
3489
|
+
this.$dropdown = false;
|
3490
|
+
}
|
2935
3491
|
},
|
2936
3492
|
hide: function (e)
|
2937
3493
|
{
|
2938
3494
|
var $dropdown = $(e.target);
|
2939
|
-
|
3495
|
+
|
3496
|
+
if (!$dropdown.hasClass('dropact') && !$dropdown.hasClass('redactor-dropdown-link-inactive'))
|
2940
3497
|
{
|
2941
|
-
$dropdown.
|
3498
|
+
if ($dropdown.hasClass('redactor-dropdown'))
|
3499
|
+
{
|
3500
|
+
$dropdown.removeClass('dropact');
|
3501
|
+
$dropdown.off('mouseover mouseout');
|
3502
|
+
}
|
3503
|
+
|
2942
3504
|
this.dropdown.hideAll();
|
2943
3505
|
}
|
2944
3506
|
}
|
@@ -3032,8 +3594,7 @@
|
|
3032
3594
|
|
3033
3595
|
if (first[0].tagName == 'UL' || first[0].tagName == 'OL')
|
3034
3596
|
{
|
3035
|
-
|
3036
|
-
var child = first.children().first();
|
3597
|
+
var child = first.find('li').first();
|
3037
3598
|
if (!this.utils.isBlock(child) && child.text() === '')
|
3038
3599
|
{
|
3039
3600
|
// empty inline tag in li
|
@@ -3057,34 +3618,31 @@
|
|
3057
3618
|
},
|
3058
3619
|
setEnd: function()
|
3059
3620
|
{
|
3060
|
-
|
3621
|
+
var last = this.$editor.children().last();
|
3622
|
+
this.$editor.focus();
|
3623
|
+
|
3624
|
+
if (last.size() === 0) return;
|
3625
|
+
if (this.utils.isEmpty(this.$editor.html()))
|
3061
3626
|
{
|
3062
|
-
|
3063
|
-
this.
|
3627
|
+
|
3628
|
+
this.selection.get();
|
3629
|
+
this.range.collapse(true);
|
3630
|
+
this.range.setStartAfter(last[0]);
|
3631
|
+
this.range.setEnd(last[0], 0);
|
3632
|
+
this.selection.addRange();
|
3064
3633
|
}
|
3065
3634
|
else
|
3066
3635
|
{
|
3067
3636
|
this.selection.get();
|
3637
|
+
this.range.selectNodeContents(last[0]);
|
3638
|
+
this.range.collapse(false);
|
3639
|
+
this.selection.addRange();
|
3068
3640
|
|
3069
|
-
try {
|
3070
|
-
this.range.selectNodeContents(this.$editor[0]);
|
3071
|
-
this.range.collapse(false);
|
3072
|
-
|
3073
|
-
this.selection.addRange();
|
3074
|
-
}
|
3075
|
-
catch (e) {}
|
3076
3641
|
}
|
3077
|
-
|
3078
3642
|
},
|
3079
3643
|
isFocused: function()
|
3080
3644
|
{
|
3081
|
-
|
3082
|
-
if (focusNode === null) return false;
|
3083
|
-
|
3084
|
-
if (this.opts.linebreaks && $(focusNode.parentNode).hasClass('redactor-linebreaks')) return true;
|
3085
|
-
else if (!this.utils.isRedactorParent(focusNode.parentNode)) return false;
|
3086
|
-
|
3087
|
-
return this.$editor.is(':focus');
|
3645
|
+
return this.$editor[0] === document.activeElement;
|
3088
3646
|
}
|
3089
3647
|
};
|
3090
3648
|
},
|
@@ -3102,7 +3660,7 @@
|
|
3102
3660
|
},
|
3103
3661
|
showEdit: function($image)
|
3104
3662
|
{
|
3105
|
-
var $link = $image.closest('a');
|
3663
|
+
var $link = $image.closest('a', this.$editor[0]);
|
3106
3664
|
|
3107
3665
|
this.modal.load('imageEdit', this.lang.get('edit'), 705);
|
3108
3666
|
|
@@ -3122,6 +3680,9 @@
|
|
3122
3680
|
|
3123
3681
|
}, this));
|
3124
3682
|
|
3683
|
+
// hide link's tooltip
|
3684
|
+
$('.redactor-link-tooltip').remove();
|
3685
|
+
|
3125
3686
|
$('#redactor-image-title').val($image.attr('alt'));
|
3126
3687
|
|
3127
3688
|
if (!this.opts.imageLink) $('.redactor-image-link-option').hide();
|
@@ -3145,6 +3706,7 @@
|
|
3145
3706
|
}
|
3146
3707
|
|
3147
3708
|
this.modal.show();
|
3709
|
+
$('#redactor-image-title').focus();
|
3148
3710
|
|
3149
3711
|
},
|
3150
3712
|
setFloating: function($image)
|
@@ -3179,14 +3741,16 @@
|
|
3179
3741
|
this.image.hideResize();
|
3180
3742
|
this.buffer.set();
|
3181
3743
|
|
3182
|
-
var $link = $image.closest('a');
|
3744
|
+
var $link = $image.closest('a', this.$editor[0]);
|
3183
3745
|
|
3184
|
-
|
3746
|
+
var title = $('#redactor-image-title').val().replace(/(<([^>]+)>)/ig,"");
|
3747
|
+
$image.attr('alt', title);
|
3185
3748
|
|
3186
3749
|
this.image.setFloating($image);
|
3187
3750
|
|
3188
3751
|
// as link
|
3189
3752
|
var link = $.trim($('#redactor-image-link').val());
|
3753
|
+
var link = link.replace(/(<([^>]+)>)/ig,"");
|
3190
3754
|
if (link !== '')
|
3191
3755
|
{
|
3192
3756
|
// test url (add protocol)
|
@@ -3240,17 +3804,14 @@
|
|
3240
3804
|
$image.on('dragstart', $.proxy(this.image.onDrag, this));
|
3241
3805
|
}
|
3242
3806
|
|
3243
|
-
|
3244
|
-
$image.on('click touchstart', $.proxy(function(e)
|
3807
|
+
var handler = $.proxy(function(e)
|
3245
3808
|
{
|
3246
|
-
this.observe.image = $image;
|
3247
3809
|
|
3248
|
-
|
3810
|
+
this.observe.image = $image;
|
3249
3811
|
|
3250
3812
|
this.image.resizer = this.image.loadEditableControls($image);
|
3251
3813
|
|
3252
|
-
$(document).on('
|
3253
|
-
this.$editor.on('click.redactor-image-resize-hide', $.proxy(this.image.hideResize, this));
|
3814
|
+
$(document).on('mousedown.redactor-image-resize-hide.' + this.uuid, $.proxy(this.image.hideResize, this));
|
3254
3815
|
|
3255
3816
|
// resize
|
3256
3817
|
if (!this.opts.imageResizable) return;
|
@@ -3260,8 +3821,11 @@
|
|
3260
3821
|
this.image.setResizable(e, $image);
|
3261
3822
|
}, this));
|
3262
3823
|
|
3824
|
+
}, this);
|
3825
|
+
|
3263
3826
|
|
3264
|
-
|
3827
|
+
$image.off('mousedown.redactor').on('mousedown.redactor', $.proxy(this.image.hideResize, this));
|
3828
|
+
$image.off('click.redactor touchstart.redactor').on('click.redactor touchstart.redactor', handler);
|
3265
3829
|
},
|
3266
3830
|
setResizable: function(e, $image)
|
3267
3831
|
{
|
@@ -3307,8 +3871,11 @@
|
|
3307
3871
|
|
3308
3872
|
if (height < 50 || width < 100) return;
|
3309
3873
|
|
3874
|
+
var height = Math.round(this.image.resizeHandle.el.width() / this.image.resizeHandle.ratio);
|
3875
|
+
|
3876
|
+
this.image.resizeHandle.el.attr({width: width, height: height});
|
3310
3877
|
this.image.resizeHandle.el.width(width);
|
3311
|
-
this.image.resizeHandle.el.height(
|
3878
|
+
this.image.resizeHandle.el.height(height);
|
3312
3879
|
|
3313
3880
|
this.code.sync();
|
3314
3881
|
},
|
@@ -3352,7 +3919,7 @@
|
|
3352
3919
|
},
|
3353
3920
|
hideResize: function(e)
|
3354
3921
|
{
|
3355
|
-
if (e && $(e.target).closest('#redactor-image-box').length !== 0) return;
|
3922
|
+
if (e && $(e.target).closest('#redactor-image-box', this.$editor[0]).length !== 0) return;
|
3356
3923
|
if (e && e.target.tagName == 'IMG')
|
3357
3924
|
{
|
3358
3925
|
var $image = $(e.target);
|
@@ -3362,12 +3929,8 @@
|
|
3362
3929
|
var imageBox = this.$editor.find('#redactor-image-box');
|
3363
3930
|
if (imageBox.length === 0) return;
|
3364
3931
|
|
3365
|
-
|
3366
|
-
|
3367
|
-
this.image.editter.remove();
|
3368
|
-
}
|
3369
|
-
|
3370
|
-
$(this.image.resizer).remove();
|
3932
|
+
$('#redactor-image-editter').remove();
|
3933
|
+
$('#redactor-image-resizer').remove();
|
3371
3934
|
|
3372
3935
|
imageBox.find('img').css({
|
3373
3936
|
marginTop: imageBox[0].style.marginTop,
|
@@ -3383,8 +3946,8 @@
|
|
3383
3946
|
return $(this).contents();
|
3384
3947
|
});
|
3385
3948
|
|
3386
|
-
$(document).off('
|
3387
|
-
|
3949
|
+
$(document).off('mousedown.redactor-image-resize-hide.' + this.uuid);
|
3950
|
+
|
3388
3951
|
|
3389
3952
|
if (typeof this.image.resizeHandle !== 'undefined')
|
3390
3953
|
{
|
@@ -3464,8 +4027,8 @@
|
|
3464
4027
|
remove: function(image)
|
3465
4028
|
{
|
3466
4029
|
var $image = $(image);
|
3467
|
-
var $link = $image.closest('a');
|
3468
|
-
var $figure = $image.closest('figure');
|
4030
|
+
var $link = $image.closest('a', this.$editor[0]);
|
4031
|
+
var $figure = $image.closest('figure', this.$editor[0]);
|
3469
4032
|
var $parent = $image.parent();
|
3470
4033
|
if ($('#redactor-image-box').length !== 0)
|
3471
4034
|
{
|
@@ -3560,7 +4123,12 @@
|
|
3560
4123
|
}
|
3561
4124
|
else if (this.opts.linebreaks)
|
3562
4125
|
{
|
3563
|
-
|
4126
|
+
if (!this.utils.isEmpty(this.code.get()))
|
4127
|
+
{
|
4128
|
+
$image.before('<br>');
|
4129
|
+
}
|
4130
|
+
|
4131
|
+
$image.after('<br>');
|
3564
4132
|
}
|
3565
4133
|
|
3566
4134
|
if (typeof json == 'string') return;
|
@@ -3644,18 +4212,12 @@
|
|
3644
4212
|
this.selection.restore();
|
3645
4213
|
this.code.sync();
|
3646
4214
|
},
|
3647
|
-
decreaseLists: function
|
4215
|
+
decreaseLists: function()
|
3648
4216
|
{
|
3649
4217
|
document.execCommand('outdent');
|
3650
4218
|
|
3651
4219
|
var current = this.selection.getCurrent();
|
3652
|
-
|
3653
|
-
var $item = $(current).closest('li');
|
3654
|
-
var $parent = $item.parent();
|
3655
|
-
if ($item.length !== 0 && $parent.length !== 0 && $parent[0].tagName == 'LI')
|
3656
|
-
{
|
3657
|
-
$parent.after($item);
|
3658
|
-
}
|
4220
|
+
var $item = $(current).closest('li', this.$editor[0]);
|
3659
4221
|
|
3660
4222
|
this.indent.fixEmptyIndent();
|
3661
4223
|
|
@@ -3714,7 +4276,7 @@
|
|
3714
4276
|
var type, value;
|
3715
4277
|
|
3716
4278
|
if (typeof this.formatting[name].style != 'undefined') type = 'style';
|
3717
|
-
else if (typeof this.formatting[name]
|
4279
|
+
else if (typeof this.formatting[name]['class'] != 'undefined') type = 'class';
|
3718
4280
|
|
3719
4281
|
if (type) value = this.formatting[name][type];
|
3720
4282
|
|
@@ -3723,6 +4285,9 @@
|
|
3723
4285
|
},
|
3724
4286
|
format: function(tag, type, value)
|
3725
4287
|
{
|
4288
|
+
var current = this.selection.getCurrent();
|
4289
|
+
if (current && current.tagName === 'TR') return;
|
4290
|
+
|
3726
4291
|
// Stop formatting pre and headers
|
3727
4292
|
if (this.utils.isCurrentOrParent('PRE') || this.utils.isCurrentOrParentHeader()) return;
|
3728
4293
|
|
@@ -3734,11 +4299,25 @@
|
|
3734
4299
|
if (tag == tags[i]) tag = replaced[i];
|
3735
4300
|
}
|
3736
4301
|
|
4302
|
+
|
4303
|
+
if (this.opts.allowedTags)
|
4304
|
+
{
|
4305
|
+
if ($.inArray(tag, this.opts.allowedTags) == -1) return;
|
4306
|
+
}
|
4307
|
+
else
|
4308
|
+
{
|
4309
|
+
if ($.inArray(tag, this.opts.deniedTags) !== -1) return;
|
4310
|
+
}
|
4311
|
+
|
3737
4312
|
this.inline.type = type || false;
|
3738
4313
|
this.inline.value = value || false;
|
3739
4314
|
|
3740
4315
|
this.buffer.set();
|
3741
|
-
|
4316
|
+
|
4317
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
4318
|
+
{
|
4319
|
+
this.$editor.focus();
|
4320
|
+
}
|
3742
4321
|
|
3743
4322
|
this.selection.get();
|
3744
4323
|
|
@@ -3754,19 +4333,23 @@
|
|
3754
4333
|
formatCollapsed: function(tag)
|
3755
4334
|
{
|
3756
4335
|
var current = this.selection.getCurrent();
|
3757
|
-
var $parent = $(current).closest(tag + '[data-redactor-tag=' + tag + ']');
|
4336
|
+
var $parent = $(current).closest(tag + '[data-redactor-tag=' + tag + ']', this.$editor[0]);
|
3758
4337
|
|
3759
4338
|
// inline there is
|
3760
4339
|
if ($parent.length !== 0 && (this.inline.type != 'style' && $parent[0].tagName != 'SPAN'))
|
3761
4340
|
{
|
3762
|
-
this.caret.setAfter($parent[0]);
|
3763
|
-
|
3764
4341
|
// remove empty
|
3765
|
-
if (
|
4342
|
+
if (this.utils.isEmpty($parent.text()))
|
3766
4343
|
{
|
4344
|
+
this.caret.setAfter($parent[0]);
|
4345
|
+
|
3767
4346
|
$parent.remove();
|
3768
4347
|
this.code.sync();
|
3769
4348
|
}
|
4349
|
+
else if (this.utils.isEndOfElement($parent))
|
4350
|
+
{
|
4351
|
+
this.caret.setAfter($parent[0]);
|
4352
|
+
}
|
3770
4353
|
|
3771
4354
|
return;
|
3772
4355
|
}
|
@@ -3807,11 +4390,17 @@
|
|
3807
4390
|
}
|
3808
4391
|
|
3809
4392
|
$el.replaceWith($span.html($el.contents()));
|
4393
|
+
var $parent = $span.parent();
|
4394
|
+
|
4395
|
+
// remove U tag if selected link + node
|
4396
|
+
if ($span[0].tagName === 'A' && $parent && $parent[0].tagName === 'U')
|
4397
|
+
{
|
4398
|
+
$span.parent().replaceWith($span);
|
4399
|
+
}
|
3810
4400
|
|
3811
4401
|
if (tag == 'span')
|
3812
4402
|
{
|
3813
|
-
|
3814
|
-
if ($parent && $parent[0].tagName == 'SPAN' && this.inline.type == 'style')
|
4403
|
+
if ($parent && $parent[0].tagName === 'SPAN' && this.inline.type === 'style')
|
3815
4404
|
{
|
3816
4405
|
var arr = this.inline.value.split(';');
|
3817
4406
|
|
@@ -3839,8 +4428,16 @@
|
|
3839
4428
|
this.$editor.find(this.opts.inlineTags.join(', ')).each($.proxy(function(i,s)
|
3840
4429
|
{
|
3841
4430
|
var $el = $(s);
|
4431
|
+
|
4432
|
+
|
4433
|
+
if (s.tagName === 'U' && s.attributes.length === 0)
|
4434
|
+
{
|
4435
|
+
$el.replaceWith($el.contents());
|
4436
|
+
return;
|
4437
|
+
}
|
4438
|
+
|
3842
4439
|
var property = $el.css('text-decoration');
|
3843
|
-
if (property
|
4440
|
+
if (property === 'line-through')
|
3844
4441
|
{
|
3845
4442
|
$el.css('text-decoration', '');
|
3846
4443
|
this.utils.removeEmptyAttr($el, 'style');
|
@@ -3857,6 +4454,15 @@
|
|
3857
4454
|
});
|
3858
4455
|
}
|
3859
4456
|
|
4457
|
+
if (tag != 'u')
|
4458
|
+
{
|
4459
|
+
var _this = this;
|
4460
|
+
this.$editor.find('unline').each(function(i,s)
|
4461
|
+
{
|
4462
|
+
_this.utils.replaceToTag(s, 'u');
|
4463
|
+
});
|
4464
|
+
}
|
4465
|
+
|
3860
4466
|
this.selection.restore();
|
3861
4467
|
this.code.sync();
|
3862
4468
|
|
@@ -3916,6 +4522,14 @@
|
|
3916
4522
|
});
|
3917
4523
|
}
|
3918
4524
|
|
4525
|
+
if (tag != 'u')
|
4526
|
+
{
|
4527
|
+
this.$editor.find('u').each(function(i,s)
|
4528
|
+
{
|
4529
|
+
self.utils.replaceToTag(s, 'unline');
|
4530
|
+
});
|
4531
|
+
}
|
4532
|
+
|
3919
4533
|
if (tag != 'span')
|
3920
4534
|
{
|
3921
4535
|
this.$editor.find(tag).each(function()
|
@@ -4155,7 +4769,10 @@
|
|
4155
4769
|
|
4156
4770
|
if (typeof clean == 'undefined') clean = true;
|
4157
4771
|
|
4158
|
-
this
|
4772
|
+
if (!this.opts.linebreaks)
|
4773
|
+
{
|
4774
|
+
this.$editor.focus();
|
4775
|
+
}
|
4159
4776
|
|
4160
4777
|
html = this.clean.setVerified(html);
|
4161
4778
|
|
@@ -4250,6 +4867,7 @@
|
|
4250
4867
|
{
|
4251
4868
|
node = node[0] || node;
|
4252
4869
|
|
4870
|
+
var offset = this.caret.getOffset();
|
4253
4871
|
var html = this.utils.getOuterHtml(node);
|
4254
4872
|
html = this.clean.setVerified(html);
|
4255
4873
|
|
@@ -4269,6 +4887,8 @@
|
|
4269
4887
|
this.range.collapse(false);
|
4270
4888
|
this.selection.addRange();
|
4271
4889
|
|
4890
|
+
this.caret.setOffset(offset);
|
4891
|
+
|
4272
4892
|
return node;
|
4273
4893
|
},
|
4274
4894
|
nodeToPoint: function(node, x, y)
|
@@ -4341,6 +4961,7 @@
|
|
4341
4961
|
var parHtml = $(parent).html();
|
4342
4962
|
|
4343
4963
|
parHtml = '<p>' + parHtml.replace(/<span class="redactor-ie-paste"><\/span>/gi, '</p>' + html + '<p>') + '</p>';
|
4964
|
+
parHtml = parHtml.replace(/<p><\/p>/gi, '');
|
4344
4965
|
$(parent).replaceWith(parHtml);
|
4345
4966
|
},
|
4346
4967
|
ie11PasteFrag: function(html)
|
@@ -4358,6 +4979,8 @@
|
|
4358
4979
|
}
|
4359
4980
|
|
4360
4981
|
this.range.insertNode(frag);
|
4982
|
+
this.range.collapse(false);
|
4983
|
+
this.selection.addRange();
|
4361
4984
|
}
|
4362
4985
|
};
|
4363
4986
|
},
|
@@ -4384,8 +5007,12 @@
|
|
4384
5007
|
// shortcuts setup
|
4385
5008
|
this.shortcuts.init(e, key);
|
4386
5009
|
|
4387
|
-
this.
|
4388
|
-
|
5010
|
+
if (this.utils.isDesktop())
|
5011
|
+
{
|
5012
|
+
this.keydown.checkEvents(arrow, key);
|
5013
|
+
this.keydown.setupBuffer(e, key);
|
5014
|
+
}
|
5015
|
+
|
4389
5016
|
this.keydown.addArrowsEvent(arrow);
|
4390
5017
|
this.keydown.setupSelectAll(e, key);
|
4391
5018
|
|
@@ -4404,7 +5031,7 @@
|
|
4404
5031
|
var $table = false;
|
4405
5032
|
if (this.keydown.block && this.keydown.block.tagName === 'TD')
|
4406
5033
|
{
|
4407
|
-
$table = $(this.keydown.block).closest('table');
|
5034
|
+
$table = $(this.keydown.block).closest('table', this.$editor[0]);
|
4408
5035
|
}
|
4409
5036
|
|
4410
5037
|
if ($table && $table.find('td').last()[0] === this.keydown.block)
|
@@ -4478,41 +5105,63 @@
|
|
4478
5105
|
current = this.selection.getCurrent();
|
4479
5106
|
$next = $(this.keydown.current).next();
|
4480
5107
|
|
4481
|
-
if (
|
5108
|
+
if ($next.length !== 0 && $next[0].tagName == 'BR')
|
5109
|
+
{
|
5110
|
+
return this.keydown.insertBreakLine(e);
|
5111
|
+
}
|
5112
|
+
else if (current !== false && $(current).hasClass('redactor-invisible-space'))
|
4482
5113
|
{
|
4483
5114
|
this.caret.setAfter(current);
|
4484
5115
|
$(current).contents().unwrap();
|
5116
|
+
|
4485
5117
|
return this.keydown.insertDblBreakLine(e);
|
4486
5118
|
}
|
4487
5119
|
else
|
4488
5120
|
{
|
4489
|
-
if (
|
5121
|
+
if (this.utils.isEndOfEditor())
|
4490
5122
|
{
|
4491
5123
|
return this.keydown.insertDblBreakLine(e);
|
4492
5124
|
}
|
4493
|
-
else if (
|
5125
|
+
else if ($next.length === 0 && current === false && typeof $next.context != 'undefined')
|
4494
5126
|
{
|
4495
|
-
return this.keydown.
|
5127
|
+
return this.keydown.insertBreakLine(e);
|
4496
5128
|
}
|
4497
5129
|
|
4498
5130
|
return this.keydown.insertBreakLine(e);
|
4499
5131
|
}
|
5132
|
+
|
4500
5133
|
}
|
4501
5134
|
else if (this.opts.linebreaks && this.keydown.block)
|
4502
5135
|
{
|
4503
5136
|
setTimeout($.proxy(this.keydown.replaceDivToBreakLine, this), 1);
|
4504
5137
|
}
|
4505
5138
|
// paragraphs
|
4506
|
-
else if (!this.opts.linebreaks && this.keydown.block
|
5139
|
+
else if (!this.opts.linebreaks && this.keydown.block)
|
4507
5140
|
{
|
4508
5141
|
setTimeout($.proxy(this.keydown.replaceDivToParagraph, this), 1);
|
5142
|
+
|
5143
|
+
if (this.keydown.block.tagName === 'LI')
|
5144
|
+
{
|
5145
|
+
current = this.selection.getCurrent();
|
5146
|
+
var $parent = $(current).closest('li', this.$editor[0]);
|
5147
|
+
var $list = $parent.closest('ul,ol', this.$editor[0]);
|
5148
|
+
|
5149
|
+
if ($parent.length !== 0 && this.utils.isEmpty($parent.html()) && $list.next().length === 0 && this.utils.isEmpty($list.find("li").last().html()))
|
5150
|
+
{
|
5151
|
+
$list.find("li").last().remove();
|
5152
|
+
|
5153
|
+
var node = $(this.opts.emptyHtml);
|
5154
|
+
$list.after(node);
|
5155
|
+
this.caret.setStart(node);
|
5156
|
+
|
5157
|
+
return false;
|
5158
|
+
}
|
5159
|
+
}
|
4509
5160
|
}
|
4510
5161
|
else if (!this.opts.linebreaks && !this.keydown.block)
|
4511
5162
|
{
|
4512
5163
|
return this.keydown.insertParagraph(e);
|
4513
5164
|
}
|
4514
|
-
|
4515
|
-
|
4516
5165
|
}
|
4517
5166
|
|
4518
5167
|
// Shift+Enter or Ctrl+Enter
|
@@ -4532,6 +5181,7 @@
|
|
4532
5181
|
if (key === this.keyCode.BACKSPACE || key === this.keyCode.DELETE)
|
4533
5182
|
{
|
4534
5183
|
var nodes = this.selection.getNodes();
|
5184
|
+
|
4535
5185
|
if (nodes)
|
4536
5186
|
{
|
4537
5187
|
var len = nodes.length;
|
@@ -4568,9 +5218,28 @@
|
|
4568
5218
|
// backspace
|
4569
5219
|
if (key === this.keyCode.BACKSPACE)
|
4570
5220
|
{
|
4571
|
-
|
4572
|
-
this.
|
4573
|
-
|
5221
|
+
// backspace as outdent
|
5222
|
+
var block = this.selection.getBlock();
|
5223
|
+
var indented = ($(block).css('margin-left') !== '0px');
|
5224
|
+
if (block && indented && this.range.collapsed && this.utils.isStartOfElement())
|
5225
|
+
{
|
5226
|
+
this.indent.decrease();
|
5227
|
+
e.preventDefault();
|
5228
|
+
return;
|
5229
|
+
}
|
5230
|
+
|
5231
|
+
// remove hr in FF
|
5232
|
+
if (this.utils.browser('mozilla'))
|
5233
|
+
{
|
5234
|
+
var prev = this.selection.getPrev();
|
5235
|
+
var prev2 = $(prev).prev()[0];
|
5236
|
+
if (prev && prev.tagName === 'HR') $(prev).remove();
|
5237
|
+
if (prev2 && prev2.tagName === 'HR') $(prev2).remove();
|
5238
|
+
}
|
5239
|
+
|
5240
|
+
this.keydown.removeInvisibleSpace();
|
5241
|
+
this.keydown.removeEmptyListInTable(e);
|
5242
|
+
}
|
4574
5243
|
|
4575
5244
|
this.code.sync();
|
4576
5245
|
},
|
@@ -4589,7 +5258,7 @@
|
|
4589
5258
|
checkKeyEvents: function(key)
|
4590
5259
|
{
|
4591
5260
|
var k = this.keyCode;
|
4592
|
-
var keys = [k.BACKSPACE, k.DELETE, k.ENTER, k.
|
5261
|
+
var keys = [k.BACKSPACE, k.DELETE, k.ENTER, k.ESC, k.TAB, k.CTRL, k.META, k.ALT, k.SHIFT];
|
4593
5262
|
|
4594
5263
|
return ($.inArray(key, keys) == -1) ? true : false;
|
4595
5264
|
|
@@ -4623,7 +5292,7 @@
|
|
4623
5292
|
}
|
4624
5293
|
else if (!this.keydown.ctrl)
|
4625
5294
|
{
|
4626
|
-
if (key == this.keyCode.BACKSPACE || key == this.keyCode.DELETE || (key == this.keyCode.ENTER && !e.ctrlKey && !e.shiftKey)
|
5295
|
+
if (key == this.keyCode.BACKSPACE || key == this.keyCode.DELETE || (key == this.keyCode.ENTER && !e.ctrlKey && !e.shiftKey))
|
4627
5296
|
{
|
4628
5297
|
this.buffer.set();
|
4629
5298
|
}
|
@@ -4714,7 +5383,7 @@
|
|
4714
5383
|
{
|
4715
5384
|
var blockElem = this.selection.getBlock();
|
4716
5385
|
var blockHtml = blockElem.innerHTML.replace(/<br\s?\/?>/gi, '');
|
4717
|
-
if (blockElem.tagName === 'DIV' && blockHtml
|
5386
|
+
if (blockElem.tagName === 'DIV' && this.utils.isEmpty(blockHtml) && !$(blockElem).hasClass('redactor-editor'))
|
4718
5387
|
{
|
4719
5388
|
var p = document.createElement('p');
|
4720
5389
|
p.innerHTML = this.opts.invisibleSpace;
|
@@ -4841,24 +5510,71 @@
|
|
4841
5510
|
e.stopPropagation();
|
4842
5511
|
|
4843
5512
|
this.selection.get();
|
5513
|
+
|
4844
5514
|
var br1 = document.createElement('br');
|
4845
5515
|
|
4846
|
-
this.
|
5516
|
+
if (this.utils.browser('msie'))
|
5517
|
+
{
|
5518
|
+
this.range.collapse(false);
|
5519
|
+
this.range.setEnd(this.range.endContainer, this.range.endOffset);
|
5520
|
+
}
|
5521
|
+
else
|
5522
|
+
{
|
5523
|
+
this.range.deleteContents();
|
5524
|
+
}
|
5525
|
+
|
4847
5526
|
this.range.insertNode(br1);
|
4848
5527
|
|
5528
|
+
// move br outside A tag
|
5529
|
+
var $parentA = $(br1).parent("a");
|
5530
|
+
|
5531
|
+
if ($parentA.length > 0)
|
5532
|
+
{
|
5533
|
+
$parentA.find(br1).remove();
|
5534
|
+
$parentA.after(br1);
|
5535
|
+
}
|
5536
|
+
|
4849
5537
|
if (dbl === true)
|
4850
5538
|
{
|
5539
|
+
var $next = $(br1).next();
|
5540
|
+
if ($next.length !== 0 && $next[0].tagName === 'BR' && this.utils.isEndOfEditor())
|
5541
|
+
{
|
5542
|
+
this.caret.setAfter(br1);
|
5543
|
+
this.code.sync();
|
5544
|
+
return false;
|
5545
|
+
}
|
5546
|
+
|
4851
5547
|
var br2 = document.createElement('br');
|
5548
|
+
|
4852
5549
|
this.range.insertNode(br2);
|
4853
5550
|
this.caret.setAfter(br2);
|
4854
5551
|
}
|
4855
5552
|
else
|
4856
5553
|
{
|
4857
|
-
|
5554
|
+
// caret does not move after the br visual
|
5555
|
+
if (this.utils.browser('msie'))
|
5556
|
+
{
|
5557
|
+
var space = document.createElement('span');
|
5558
|
+
space.innerHTML = '​';
|
5559
|
+
|
5560
|
+
$(br1).after(space);
|
5561
|
+
|
5562
|
+
this.range.setStartAfter(space);
|
5563
|
+
this.range.setEndAfter(space);
|
5564
|
+
$(space).remove();
|
5565
|
+
}
|
5566
|
+
else
|
5567
|
+
{
|
5568
|
+
var range = document.createRange();
|
5569
|
+
range.setStartAfter(br1);
|
5570
|
+
range.collapse(true);
|
5571
|
+
var selection = window.getSelection();
|
5572
|
+
selection.removeAllRanges();
|
5573
|
+
selection.addRange(range);
|
5574
|
+
}
|
4858
5575
|
}
|
4859
5576
|
|
4860
5577
|
this.code.sync();
|
4861
|
-
|
4862
5578
|
return false;
|
4863
5579
|
},
|
4864
5580
|
removeInvisibleSpace: function()
|
@@ -4873,9 +5589,9 @@
|
|
4873
5589
|
{
|
4874
5590
|
var $current = $(this.keydown.current);
|
4875
5591
|
var $parent = $(this.keydown.parent);
|
4876
|
-
var td = $current.closest('td');
|
5592
|
+
var td = $current.closest('td', this.$editor[0]);
|
4877
5593
|
|
4878
|
-
if (td.length !== 0 && $current.closest('li') && $parent.children('li').length === 1)
|
5594
|
+
if (td.length !== 0 && $current.closest('li', this.$editor[0]) && $parent.children('li').length === 1)
|
4879
5595
|
{
|
4880
5596
|
if (!this.utils.isEmpty($current.text())) return;
|
4881
5597
|
|
@@ -4894,6 +5610,7 @@
|
|
4894
5610
|
return {
|
4895
5611
|
init: function(e)
|
4896
5612
|
{
|
5613
|
+
|
4897
5614
|
if (this.rtePaste) return;
|
4898
5615
|
|
4899
5616
|
var key = e.which;
|
@@ -4902,7 +5619,6 @@
|
|
4902
5619
|
this.keyup.parent = this.selection.getParent();
|
4903
5620
|
var $parent = this.utils.isRedactorParent($(this.keyup.parent).parent());
|
4904
5621
|
|
4905
|
-
|
4906
5622
|
// callback
|
4907
5623
|
var keyupStop = this.core.setCallback('keyup', e);
|
4908
5624
|
if (keyupStop === false)
|
@@ -4912,7 +5628,7 @@
|
|
4912
5628
|
}
|
4913
5629
|
|
4914
5630
|
// replace to p before / after the table or body
|
4915
|
-
if (!this.opts.linebreaks && this.keyup.current.nodeType
|
5631
|
+
if (!this.opts.linebreaks && this.keyup.current.nodeType === 3 && this.keyup.current.length <= 1 && (this.keyup.parent === false || this.keyup.parent.tagName == 'BODY'))
|
4916
5632
|
{
|
4917
5633
|
this.keyup.replaceToParagraph();
|
4918
5634
|
}
|
@@ -4931,16 +5647,20 @@
|
|
4931
5647
|
}
|
4932
5648
|
|
4933
5649
|
// linkify
|
4934
|
-
if (this.
|
4935
|
-
{
|
4936
|
-
this.formatLinkify(this.opts.linkProtocol, this.opts.convertLinks, this.opts.convertUrlLinks, this.opts.convertImageLinks, this.opts.convertVideoLinks, this.opts.linkSize);
|
4937
|
-
|
4938
|
-
this.observe.load();
|
4939
|
-
this.code.sync();
|
4940
|
-
}
|
5650
|
+
if (this.linkify.isEnabled() && this.linkify.isKey(key)) this.linkify.format();
|
4941
5651
|
|
4942
5652
|
if (key === this.keyCode.DELETE || key === this.keyCode.BACKSPACE)
|
4943
5653
|
{
|
5654
|
+
if (this.utils.browser('mozilla'))
|
5655
|
+
{
|
5656
|
+
var td = $(this.keydown.current).closest('td', this.$editor[0]);
|
5657
|
+
if (td.size() !== 0 && td.text() !== '')
|
5658
|
+
{
|
5659
|
+
e.preventDefault();
|
5660
|
+
return false;
|
5661
|
+
}
|
5662
|
+
}
|
5663
|
+
|
4944
5664
|
// clear unverified
|
4945
5665
|
this.clean.clearUnverified();
|
4946
5666
|
|
@@ -4958,7 +5678,10 @@
|
|
4958
5678
|
}
|
4959
5679
|
|
4960
5680
|
// remove empty paragraphs
|
4961
|
-
this.$editor.find('p').each($.proxy(
|
5681
|
+
this.$editor.find('p').each($.proxy(function(i, s)
|
5682
|
+
{
|
5683
|
+
this.utils.removeEmpty(i, $(s).html());
|
5684
|
+
}, this));
|
4962
5685
|
|
4963
5686
|
// remove invisible space
|
4964
5687
|
if (this.opts.linebreaks && this.keyup.current && this.keyup.current.tagName == 'DIV' && this.utils.isEmpty(this.keyup.current.innerHTML))
|
@@ -4968,14 +5691,12 @@
|
|
4968
5691
|
$(this.keyup.current).remove();
|
4969
5692
|
}
|
4970
5693
|
|
5694
|
+
this.keyup.removeEmptyLists();
|
5695
|
+
|
4971
5696
|
// if empty
|
4972
5697
|
return this.keyup.formatEmpty(e);
|
4973
5698
|
}
|
4974
5699
|
},
|
4975
|
-
isLinkify: function(key)
|
4976
|
-
{
|
4977
|
-
return this.opts.convertLinks && (this.opts.convertUrlLinks || this.opts.convertImageLinks || this.opts.convertVideoLinks) && key === this.keyCode.ENTER && !this.utils.isCurrentOrParent('PRE');
|
4978
|
-
},
|
4979
5700
|
replaceToParagraph: function(clone)
|
4980
5701
|
{
|
4981
5702
|
var $current = $(this.keyup.current);
|
@@ -4999,6 +5720,20 @@
|
|
4999
5720
|
|
5000
5721
|
this.caret.setEnd(node);
|
5001
5722
|
},
|
5723
|
+
removeEmptyLists: function()
|
5724
|
+
{
|
5725
|
+
var removeIt = function()
|
5726
|
+
{
|
5727
|
+
var html = $.trim(this.innerHTML).replace(/\/t\/n/g, '');
|
5728
|
+
if (html === '')
|
5729
|
+
{
|
5730
|
+
$(this).remove();
|
5731
|
+
}
|
5732
|
+
};
|
5733
|
+
|
5734
|
+
this.$editor.find('li').each(removeIt);
|
5735
|
+
this.$editor.find('ul, ol').each(removeIt);
|
5736
|
+
},
|
5002
5737
|
formatEmpty: function(e)
|
5003
5738
|
{
|
5004
5739
|
var html = $.trim(this.$editor.html());
|
@@ -5014,9 +5749,7 @@
|
|
5014
5749
|
}
|
5015
5750
|
else
|
5016
5751
|
{
|
5017
|
-
html
|
5018
|
-
|
5019
|
-
this.$editor.html(html);
|
5752
|
+
this.$editor.html(this.opts.emptyHtml);
|
5020
5753
|
this.focus.setStart();
|
5021
5754
|
}
|
5022
5755
|
|
@@ -5096,7 +5829,7 @@
|
|
5096
5829
|
var extra = '<p id="redactor-insert-line"><br /></p>';
|
5097
5830
|
if (this.opts.linebreaks) extra = '<br id="redactor-insert-line">';
|
5098
5831
|
|
5099
|
-
document.execCommand('
|
5832
|
+
document.execCommand('insertHtml', false, '<hr>' + extra);
|
5100
5833
|
|
5101
5834
|
this.line.setFocus();
|
5102
5835
|
this.code.sync();
|
@@ -5105,16 +5838,43 @@
|
|
5105
5838
|
{
|
5106
5839
|
var node = this.$editor.find('#redactor-insert-line');
|
5107
5840
|
var next = $(node).next()[0];
|
5841
|
+
var target = next;
|
5842
|
+
if (this.utils.browser('mozilla') && next && next.innerHTML === '')
|
5843
|
+
{
|
5844
|
+
target = $(next).next()[0];
|
5845
|
+
$(next).remove();
|
5846
|
+
}
|
5108
5847
|
|
5109
|
-
if (
|
5848
|
+
if (target)
|
5110
5849
|
{
|
5111
|
-
this.caret.setAfter(node);
|
5112
5850
|
node.remove();
|
5851
|
+
|
5852
|
+
if (!this.opts.linebreaks)
|
5853
|
+
{
|
5854
|
+
this.$editor.focus();
|
5855
|
+
this.line.setStart(target);
|
5856
|
+
}
|
5857
|
+
|
5113
5858
|
}
|
5114
5859
|
else
|
5115
5860
|
{
|
5861
|
+
|
5116
5862
|
node.removeAttr('id');
|
5863
|
+
this.line.setStart(node[0]);
|
5117
5864
|
}
|
5865
|
+
},
|
5866
|
+
setStart: function(node)
|
5867
|
+
{
|
5868
|
+
if (typeof node === 'undefined') return;
|
5869
|
+
|
5870
|
+
var textNode = document.createTextNode('\u200B');
|
5871
|
+
|
5872
|
+
this.selection.get();
|
5873
|
+
this.range.setStart(node, 0);
|
5874
|
+
this.range.insertNode(textNode);
|
5875
|
+
this.range.collapse(true);
|
5876
|
+
this.selection.addRange();
|
5877
|
+
|
5118
5878
|
}
|
5119
5879
|
};
|
5120
5880
|
},
|
@@ -5125,10 +5885,20 @@
|
|
5125
5885
|
{
|
5126
5886
|
if (typeof e != 'undefined' && e.preventDefault) e.preventDefault();
|
5127
5887
|
|
5128
|
-
|
5888
|
+
if (!this.observe.isCurrent('a'))
|
5889
|
+
{
|
5890
|
+
this.modal.load('link', this.lang.get('link_insert'), 600);
|
5891
|
+
}
|
5892
|
+
else
|
5893
|
+
{
|
5894
|
+
this.modal.load('link', this.lang.get('link_edit'), 600);
|
5895
|
+
}
|
5129
5896
|
|
5130
5897
|
this.modal.createCancelButton();
|
5131
|
-
|
5898
|
+
|
5899
|
+
var buttonText = !this.observe.isCurrent('a') ? this.lang.get('insert') : this.lang.get('edit');
|
5900
|
+
|
5901
|
+
this.link.buttonInsert = this.modal.createActionButton(buttonText);
|
5132
5902
|
|
5133
5903
|
this.selection.get();
|
5134
5904
|
|
@@ -5156,23 +5926,26 @@
|
|
5156
5926
|
cleanUrl: function()
|
5157
5927
|
{
|
5158
5928
|
var thref = self.location.href.replace(/\/$/i, '');
|
5159
|
-
this.link.url = this.link.url.replace(thref, '');
|
5160
|
-
this.link.url = this.link.url.replace(/^\/#/, '#');
|
5161
|
-
this.link.url = this.link.url.replace('mailto:', '');
|
5162
5929
|
|
5163
|
-
|
5164
|
-
if (!this.opts.linkProtocol)
|
5930
|
+
if (typeof this.link.url !== "undefined")
|
5165
5931
|
{
|
5166
|
-
|
5167
|
-
this.link.url = this.link.url.replace(
|
5168
|
-
|
5932
|
+
this.link.url = this.link.url.replace(thref, '');
|
5933
|
+
this.link.url = this.link.url.replace(/^\/#/, '#');
|
5934
|
+
this.link.url = this.link.url.replace('mailto:', '');
|
5169
5935
|
|
5936
|
+
// remove host from href
|
5937
|
+
if (!this.opts.linkProtocol)
|
5938
|
+
{
|
5939
|
+
var re = new RegExp('^(http|ftp|https)://' + self.location.host, 'i');
|
5940
|
+
this.link.url = this.link.url.replace(re, '');
|
5941
|
+
}
|
5942
|
+
}
|
5170
5943
|
},
|
5171
5944
|
getData: function()
|
5172
5945
|
{
|
5173
5946
|
this.link.$node = false;
|
5174
5947
|
|
5175
|
-
var $el = $(this.selection.getCurrent()).closest('a');
|
5948
|
+
var $el = $(this.selection.getCurrent()).closest('a', this.$editor[0]);
|
5176
5949
|
if ($el.length !== 0 && $el[0].tagName === 'A')
|
5177
5950
|
{
|
5178
5951
|
this.link.$node = $el;
|
@@ -5191,9 +5964,11 @@
|
|
5191
5964
|
},
|
5192
5965
|
insert: function()
|
5193
5966
|
{
|
5967
|
+
this.placeholder.remove();
|
5968
|
+
|
5194
5969
|
var target = '';
|
5195
5970
|
var link = this.link.$inputUrl.val();
|
5196
|
-
var text = this.link.$inputText.val();
|
5971
|
+
var text = this.link.$inputText.val().replace(/(<([^>]+)>)/ig,"");
|
5197
5972
|
|
5198
5973
|
if ($.trim(link) === '')
|
5199
5974
|
{
|
@@ -5210,6 +5985,7 @@
|
|
5210
5985
|
// mailto
|
5211
5986
|
if (link.search('@') != -1 && /(http|ftp|https):\/\//i.test(link) === false)
|
5212
5987
|
{
|
5988
|
+
link = link.replace('mailto:', '');
|
5213
5989
|
link = 'mailto:' + link;
|
5214
5990
|
}
|
5215
5991
|
// url, not anchor
|
@@ -5239,6 +6015,7 @@
|
|
5239
6015
|
text = $.trim(text.replace(/<|>/g, ''));
|
5240
6016
|
|
5241
6017
|
this.selection.restore();
|
6018
|
+
var blocks = this.selection.getBlocks();
|
5242
6019
|
|
5243
6020
|
if (text === '' && link === '') return;
|
5244
6021
|
if (text === '' && link !== '') text = link;
|
@@ -5247,16 +6024,37 @@
|
|
5247
6024
|
{
|
5248
6025
|
this.buffer.set();
|
5249
6026
|
|
5250
|
-
this.link.$node
|
6027
|
+
var $link = this.link.$node,
|
6028
|
+
$el = $link.children();
|
6029
|
+
|
6030
|
+
if ($el.length > 0)
|
6031
|
+
{
|
6032
|
+
while ($el.length)
|
6033
|
+
{
|
6034
|
+
$el = $el.children();
|
6035
|
+
}
|
6036
|
+
|
6037
|
+
$el = $el.end();
|
6038
|
+
}
|
6039
|
+
else
|
6040
|
+
{
|
6041
|
+
$el = $link;
|
6042
|
+
}
|
6043
|
+
|
6044
|
+
$link.attr('href', link);
|
6045
|
+
$el.text(text);
|
6046
|
+
|
5251
6047
|
if (target !== '')
|
5252
6048
|
{
|
5253
|
-
|
6049
|
+
$link.attr('target', target);
|
5254
6050
|
}
|
5255
6051
|
else
|
5256
6052
|
{
|
5257
|
-
|
6053
|
+
$link.removeAttr('target');
|
5258
6054
|
}
|
5259
6055
|
|
6056
|
+
this.selection.selectElement($link);
|
6057
|
+
|
5260
6058
|
this.code.sync();
|
5261
6059
|
}
|
5262
6060
|
else
|
@@ -5266,7 +6064,13 @@
|
|
5266
6064
|
var $a = $('<a />').attr('href', link).text(text);
|
5267
6065
|
if (target !== '') $a.attr('target', target);
|
5268
6066
|
|
5269
|
-
this.insert.node($a);
|
6067
|
+
$a = $(this.insert.node($a));
|
6068
|
+
|
6069
|
+
if (this.opts.linebreaks)
|
6070
|
+
{
|
6071
|
+
$a.after(' ');
|
6072
|
+
}
|
6073
|
+
|
5270
6074
|
this.selection.selectElement($a);
|
5271
6075
|
}
|
5272
6076
|
else
|
@@ -5278,20 +6082,43 @@
|
|
5278
6082
|
if (target !== '') $a.attr('target', target);
|
5279
6083
|
|
5280
6084
|
$a = $(this.insert.node($a));
|
6085
|
+
|
6086
|
+
if (this.selection.getText().match(/\s$/))
|
6087
|
+
{
|
6088
|
+
$a.after(" ");
|
6089
|
+
}
|
6090
|
+
|
5281
6091
|
this.selection.selectElement($a);
|
5282
6092
|
}
|
5283
6093
|
else
|
5284
6094
|
{
|
5285
6095
|
document.execCommand('createLink', false, link);
|
5286
6096
|
|
5287
|
-
$a = $(this.selection.getCurrent()).closest('a');
|
6097
|
+
$a = $(this.selection.getCurrent()).closest('a', this.$editor[0]);
|
6098
|
+
if (this.utils.browser('mozilla'))
|
6099
|
+
{
|
6100
|
+
$a = $('a[_moz_dirty=""]');
|
6101
|
+
}
|
5288
6102
|
|
5289
6103
|
if (target !== '') $a.attr('target', target);
|
5290
|
-
$a.removeAttr('style');
|
6104
|
+
$a.removeAttr('style').removeAttr('_moz_dirty');
|
5291
6105
|
|
5292
|
-
if (this.
|
6106
|
+
if (this.selection.getText().match(/\s$/))
|
5293
6107
|
{
|
5294
|
-
$a.
|
6108
|
+
$a.after(" ");
|
6109
|
+
}
|
6110
|
+
|
6111
|
+
if (this.link.text !== '' || this.link.text != text)
|
6112
|
+
{
|
6113
|
+
if (!this.opts.linebreaks && blocks && blocks.length <= 1)
|
6114
|
+
{
|
6115
|
+
$a.text(text);
|
6116
|
+
}
|
6117
|
+
else if (this.opts.linebreaks)
|
6118
|
+
{
|
6119
|
+
$a.text(text);
|
6120
|
+
}
|
6121
|
+
|
5295
6122
|
this.selection.selectElement($a);
|
5296
6123
|
}
|
5297
6124
|
}
|
@@ -5311,7 +6138,10 @@
|
|
5311
6138
|
},
|
5312
6139
|
unlink: function(e)
|
5313
6140
|
{
|
5314
|
-
if (typeof e != 'undefined' && e.preventDefault)
|
6141
|
+
if (typeof e != 'undefined' && e.preventDefault)
|
6142
|
+
{
|
6143
|
+
e.preventDefault();
|
6144
|
+
}
|
5315
6145
|
|
5316
6146
|
var nodes = this.selection.getNodes();
|
5317
6147
|
if (!nodes) return;
|
@@ -5319,20 +6149,201 @@
|
|
5319
6149
|
this.buffer.set();
|
5320
6150
|
|
5321
6151
|
var len = nodes.length;
|
6152
|
+
var links = [];
|
5322
6153
|
for (var i = 0; i < len; i++)
|
5323
6154
|
{
|
5324
|
-
if (nodes[i].tagName
|
6155
|
+
if (nodes[i].tagName === 'A')
|
5325
6156
|
{
|
5326
|
-
|
5327
|
-
$node.replaceWith($node.contents());
|
6157
|
+
links.push(nodes[i]);
|
5328
6158
|
}
|
6159
|
+
|
6160
|
+
var $node = $(nodes[i]).closest('a', this.$editor[0]);
|
6161
|
+
$node.replaceWith($node.contents());
|
5329
6162
|
}
|
5330
6163
|
|
6164
|
+
this.core.setCallback('deletedLink', links);
|
6165
|
+
|
5331
6166
|
// hide link's tooltip
|
5332
6167
|
$('.redactor-link-tooltip').remove();
|
5333
6168
|
|
5334
6169
|
this.code.sync();
|
5335
6170
|
|
6171
|
+
},
|
6172
|
+
toggleClass: function(className)
|
6173
|
+
{
|
6174
|
+
this.link.setClass(className, 'toggleClass');
|
6175
|
+
},
|
6176
|
+
addClass: function(className)
|
6177
|
+
{
|
6178
|
+
this.link.setClass(className, 'addClass');
|
6179
|
+
},
|
6180
|
+
removeClass: function(className)
|
6181
|
+
{
|
6182
|
+
this.link.setClass(className, 'removeClass');
|
6183
|
+
},
|
6184
|
+
setClass: function(className, func)
|
6185
|
+
{
|
6186
|
+
var links = this.selection.getInlinesTags(['a']);
|
6187
|
+
if (links === false) return;
|
6188
|
+
|
6189
|
+
$.each(links, function()
|
6190
|
+
{
|
6191
|
+
$(this)[func](className);
|
6192
|
+
});
|
6193
|
+
}
|
6194
|
+
};
|
6195
|
+
},
|
6196
|
+
linkify: function()
|
6197
|
+
{
|
6198
|
+
return {
|
6199
|
+
isKey: function(key)
|
6200
|
+
{
|
6201
|
+
return key == this.keyCode.ENTER || key == this.keyCode.SPACE;
|
6202
|
+
},
|
6203
|
+
isEnabled: function()
|
6204
|
+
{
|
6205
|
+
return this.opts.convertLinks && (this.opts.convertUrlLinks || this.opts.convertImageLinks || this.opts.convertVideoLinks) && !this.utils.isCurrentOrParent('PRE');
|
6206
|
+
},
|
6207
|
+
format: function()
|
6208
|
+
{
|
6209
|
+
var linkify = this.linkify,
|
6210
|
+
opts = this.opts;
|
6211
|
+
|
6212
|
+
this.$editor
|
6213
|
+
.find(":not(iframe,img,a,pre)")
|
6214
|
+
.addBack()
|
6215
|
+
.contents()
|
6216
|
+
.filter(function()
|
6217
|
+
{
|
6218
|
+
return this.nodeType === 3 && $.trim(this.nodeValue) != "" && !$(this).parent().is("pre") && (this.nodeValue.match(opts.linkify.regexps.youtube) || this.nodeValue.match(opts.linkify.regexps.vimeo) || this.nodeValue.match(opts.linkify.regexps.image) || this.nodeValue.match(opts.linkify.regexps.url));
|
6219
|
+
})
|
6220
|
+
.each(function()
|
6221
|
+
{
|
6222
|
+
var text = $(this).text(),
|
6223
|
+
html = text;
|
6224
|
+
|
6225
|
+
if (opts.convertVideoLinks && (html.match(opts.linkify.regexps.youtube) || html.match(opts.linkify.regexps.vimeo)) )
|
6226
|
+
{
|
6227
|
+
html = linkify.convertVideoLinks(html);
|
6228
|
+
}
|
6229
|
+
else if (opts.convertImageLinks && html.match(opts.linkify.regexps.image))
|
6230
|
+
{
|
6231
|
+
html = linkify.convertImages(html);
|
6232
|
+
}
|
6233
|
+
else if (opts.convertUrlLinks)
|
6234
|
+
{
|
6235
|
+
html = linkify.convertLinks(html);
|
6236
|
+
}
|
6237
|
+
|
6238
|
+
$(this).before(text.replace(text, html))
|
6239
|
+
.remove();
|
6240
|
+
});
|
6241
|
+
|
6242
|
+
|
6243
|
+
var objects = this.$editor.find('.redactor-linkify-object').each(function()
|
6244
|
+
{
|
6245
|
+
var $el = $(this);
|
6246
|
+
$el.removeClass('redactor-linkify-object');
|
6247
|
+
if ($el.attr('class') === '') $el.removeAttr('class');
|
6248
|
+
|
6249
|
+
return $el[0];
|
6250
|
+
|
6251
|
+
});
|
6252
|
+
|
6253
|
+
// callback
|
6254
|
+
setTimeout($.proxy(function()
|
6255
|
+
{
|
6256
|
+
this.observe.load();
|
6257
|
+
this.core.setCallback('linkify', objects);
|
6258
|
+
}, this), 100);
|
6259
|
+
|
6260
|
+
// sync
|
6261
|
+
this.code.sync();
|
6262
|
+
},
|
6263
|
+
convertVideoLinks: function(html)
|
6264
|
+
{
|
6265
|
+
var iframeStart = '<iframe class="redactor-linkify-object" width="500" height="281" src="',
|
6266
|
+
iframeEnd = '" frameborder="0" allowfullscreen></iframe>';
|
6267
|
+
|
6268
|
+
if (html.match(this.opts.linkify.regexps.youtube))
|
6269
|
+
{
|
6270
|
+
html = html.replace(this.opts.linkify.regexps.youtube, iframeStart + '//www.youtube.com/embed/$1' + iframeEnd);
|
6271
|
+
}
|
6272
|
+
|
6273
|
+
if (html.match(this.opts.linkify.regexps.vimeo))
|
6274
|
+
{
|
6275
|
+
html = html.replace(this.opts.linkify.regexps.vimeo, iframeStart + '//player.vimeo.com/video/$2' + iframeEnd);
|
6276
|
+
}
|
6277
|
+
|
6278
|
+
return html;
|
6279
|
+
},
|
6280
|
+
convertImages: function(html)
|
6281
|
+
{
|
6282
|
+
var matches = html.match(this.opts.linkify.regexps.image);
|
6283
|
+
|
6284
|
+
if (matches)
|
6285
|
+
{
|
6286
|
+
html = html.replace(html, '<img src="' + matches + '" class="redactor-linkify-object" />');
|
6287
|
+
|
6288
|
+
if (this.opts.linebreaks)
|
6289
|
+
{
|
6290
|
+
if (!this.utils.isEmpty(this.code.get()))
|
6291
|
+
{
|
6292
|
+
html = '<br>' + html;
|
6293
|
+
}
|
6294
|
+
}
|
6295
|
+
|
6296
|
+
html += '<br>';
|
6297
|
+
}
|
6298
|
+
|
6299
|
+
return html;
|
6300
|
+
},
|
6301
|
+
convertLinks: function(html)
|
6302
|
+
{
|
6303
|
+
var matches = html.match(this.opts.linkify.regexps.url);
|
6304
|
+
|
6305
|
+
if (matches)
|
6306
|
+
{
|
6307
|
+
matches = $.grep(matches, function(v, k) { return $.inArray(v, matches) === k; });
|
6308
|
+
|
6309
|
+
var length = matches.length;
|
6310
|
+
|
6311
|
+
for (var i = 0; i < length; i++)
|
6312
|
+
{
|
6313
|
+
var href = matches[i],
|
6314
|
+
text = href,
|
6315
|
+
linkProtocol = this.opts.linkProtocol + '://';
|
6316
|
+
|
6317
|
+
if (href.match(/(https?|ftp):\/\//i) !== null)
|
6318
|
+
{
|
6319
|
+
linkProtocol = "";
|
6320
|
+
}
|
6321
|
+
|
6322
|
+
if (text.length > this.opts.linkSize)
|
6323
|
+
{
|
6324
|
+
text = text.substring(0, this.opts.linkSize) + '...';
|
6325
|
+
}
|
6326
|
+
|
6327
|
+
if (text.search('%') === -1)
|
6328
|
+
{
|
6329
|
+
text = decodeURIComponent(text);
|
6330
|
+
}
|
6331
|
+
|
6332
|
+
var regexB = "\\b";
|
6333
|
+
|
6334
|
+
if ($.inArray(href.slice(-1), ["/", "&", "="]) != -1)
|
6335
|
+
{
|
6336
|
+
regexB = "";
|
6337
|
+
}
|
6338
|
+
|
6339
|
+
// escaping url
|
6340
|
+
var regexp = new RegExp('(' + href.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + regexB + ')', 'g');
|
6341
|
+
|
6342
|
+
html = html.replace(regexp, '<a href="' + linkProtocol + $.trim(href) + '" class="redactor-linkify-object">' + $.trim(text) + '</a>');
|
6343
|
+
}
|
6344
|
+
}
|
6345
|
+
|
6346
|
+
return html;
|
5336
6347
|
}
|
5337
6348
|
};
|
5338
6349
|
},
|
@@ -5342,13 +6353,17 @@
|
|
5342
6353
|
toggle: function(cmd)
|
5343
6354
|
{
|
5344
6355
|
this.placeholder.remove();
|
5345
|
-
|
6356
|
+
|
6357
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
6358
|
+
{
|
6359
|
+
this.$editor.focus();
|
6360
|
+
}
|
5346
6361
|
|
5347
6362
|
this.buffer.set();
|
5348
6363
|
this.selection.save();
|
5349
6364
|
|
5350
6365
|
var parent = this.selection.getParent();
|
5351
|
-
var $list = $(parent).closest('ol, ul');
|
6366
|
+
var $list = $(parent).closest('ol, ul', this.$editor[0]);
|
5352
6367
|
|
5353
6368
|
if (!this.utils.isRedactorParent($list) && $list.length !== 0)
|
5354
6369
|
{
|
@@ -5378,7 +6393,7 @@
|
|
5378
6393
|
{
|
5379
6394
|
if (remove)
|
5380
6395
|
{
|
5381
|
-
this.list.remove(cmd);
|
6396
|
+
this.list.remove(cmd, $list);
|
5382
6397
|
}
|
5383
6398
|
else
|
5384
6399
|
{
|
@@ -5386,15 +6401,14 @@
|
|
5386
6401
|
}
|
5387
6402
|
}
|
5388
6403
|
|
5389
|
-
|
5390
6404
|
this.selection.restore();
|
5391
6405
|
this.code.sync();
|
6406
|
+
|
5392
6407
|
},
|
5393
6408
|
insert: function(cmd)
|
5394
6409
|
{
|
5395
|
-
var parent = this.selection.getParent();
|
5396
6410
|
var current = this.selection.getCurrent();
|
5397
|
-
var $td = $(current).closest('td, th');
|
6411
|
+
var $td = $(current).closest('td, th', this.$editor[0]);
|
5398
6412
|
|
5399
6413
|
if (this.utils.browser('msie') && this.opts.linebreaks)
|
5400
6414
|
{
|
@@ -5405,30 +6419,25 @@
|
|
5405
6419
|
document.execCommand('insert' + cmd);
|
5406
6420
|
}
|
5407
6421
|
|
5408
|
-
var
|
5409
|
-
|
6422
|
+
var parent = this.selection.getParent();
|
6423
|
+
var $list = $(parent).closest('ol, ul', this.$editor[0]);
|
5410
6424
|
if ($td.length !== 0)
|
5411
6425
|
{
|
5412
|
-
var
|
5413
|
-
|
5414
|
-
$td.html('');
|
5415
|
-
if (prev && prev.length === 1 && (prev[0].tagName === 'TD' || prev[0].tagName === 'TH'))
|
5416
|
-
{
|
5417
|
-
$(prev).after($td);
|
5418
|
-
}
|
5419
|
-
else
|
5420
|
-
{
|
5421
|
-
$(parent).prepend($td);
|
5422
|
-
}
|
5423
|
-
|
5424
|
-
$td.html(html);
|
6426
|
+
var newTd = $td.clone();
|
6427
|
+
$td.after(newTd).remove('');
|
5425
6428
|
}
|
5426
6429
|
|
6430
|
+
|
5427
6431
|
if (this.utils.isEmpty($list.find('li').text()))
|
5428
6432
|
{
|
5429
6433
|
var $children = $list.children('li');
|
5430
6434
|
$children.find('br').remove();
|
5431
6435
|
$children.append(this.selection.getMarkerAsHtml());
|
6436
|
+
|
6437
|
+
if (this.opts.linebreaks && this.utils.browser('mozilla') && $children.size() == 2 && this.utils.isEmpty($children.eq(1).text()))
|
6438
|
+
{
|
6439
|
+
$children.eq(1).remove();
|
6440
|
+
}
|
5432
6441
|
}
|
5433
6442
|
|
5434
6443
|
if ($list.length)
|
@@ -5446,6 +6455,7 @@
|
|
5446
6455
|
this.$editor.focus();
|
5447
6456
|
}
|
5448
6457
|
|
6458
|
+
|
5449
6459
|
this.clean.clearUnverified();
|
5450
6460
|
},
|
5451
6461
|
insertInIe: function(cmd)
|
@@ -5484,21 +6494,22 @@
|
|
5484
6494
|
$(wrapper).replaceWith(tmpList);
|
5485
6495
|
}
|
5486
6496
|
},
|
5487
|
-
remove: function(cmd)
|
6497
|
+
remove: function(cmd, $list)
|
5488
6498
|
{
|
6499
|
+
if ($.inArray('ul', this.selection.getBlocks())) cmd = 'unorderedlist';
|
6500
|
+
|
5489
6501
|
document.execCommand('insert' + cmd);
|
5490
6502
|
|
5491
6503
|
var $current = $(this.selection.getCurrent());
|
5492
|
-
|
5493
6504
|
this.indent.fixEmptyIndent();
|
5494
6505
|
|
5495
|
-
if (!this.opts.linebreaks && $current.closest('li, th, td').length === 0)
|
6506
|
+
if (!this.opts.linebreaks && $current.closest('li, th, td', this.$editor[0]).length === 0)
|
5496
6507
|
{
|
5497
6508
|
document.execCommand('formatblock', false, 'p');
|
5498
6509
|
this.$editor.find('ul, ol, blockquote').each($.proxy(this.utils.removeEmpty, this));
|
5499
6510
|
}
|
5500
6511
|
|
5501
|
-
var $table = $(this.selection.getCurrent()).closest('table');
|
6512
|
+
var $table = $(this.selection.getCurrent()).closest('table', this.$editor[0]);
|
5502
6513
|
var $prev = $table.prev();
|
5503
6514
|
if (!this.opts.linebreaks && $table.length !== 0 && $prev.length !== 0 && $prev[0].tagName == 'BR')
|
5504
6515
|
{
|
@@ -5507,6 +6518,7 @@
|
|
5507
6518
|
|
5508
6519
|
this.clean.clearUnverified();
|
5509
6520
|
|
6521
|
+
|
5510
6522
|
}
|
5511
6523
|
};
|
5512
6524
|
},
|
@@ -5522,10 +6534,10 @@
|
|
5522
6534
|
+ '<label>' + this.lang.get('title') + '</label>'
|
5523
6535
|
+ '<input type="text" id="redactor-image-title" />'
|
5524
6536
|
+ '<label class="redactor-image-link-option">' + this.lang.get('link') + '</label>'
|
5525
|
-
+ '<input type="text" id="redactor-image-link" class="redactor-image-link-option" />'
|
5526
|
-
+ '<label class="redactor-image-link-option"><input type="checkbox" id="redactor-image-link-blank"> ' + this.lang.get('link_new_tab') + '</label>'
|
6537
|
+
+ '<input type="text" id="redactor-image-link" class="redactor-image-link-option" aria-label="' + this.lang.get('link') + '" />'
|
6538
|
+
+ '<label class="redactor-image-link-option"><input type="checkbox" id="redactor-image-link-blank" aria-label="' + this.lang.get('link_new_tab') + '"> ' + this.lang.get('link_new_tab') + '</label>'
|
5527
6539
|
+ '<label class="redactor-image-position-option">' + this.lang.get('image_position') + '</label>'
|
5528
|
-
+ '<select class="redactor-image-position-option" id="redactor-image-align">'
|
6540
|
+
+ '<select class="redactor-image-position-option" id="redactor-image-align" aria-label="' + this.lang.get('image_position') + '">'
|
5529
6541
|
+ '<option value="none">' + this.lang.get('none') + '</option>'
|
5530
6542
|
+ '<option value="left">' + this.lang.get('left') + '</option>'
|
5531
6543
|
+ '<option value="center">' + this.lang.get('center') + '</option>'
|
@@ -5542,7 +6554,7 @@
|
|
5542
6554
|
+ '<section id="redactor-modal-file-insert">'
|
5543
6555
|
+ '<div id="redactor-modal-file-upload-box">'
|
5544
6556
|
+ '<label>' + this.lang.get('filename') + '</label>'
|
5545
|
-
+ '<input type="text" id="redactor-filename" /><br><br>'
|
6557
|
+
+ '<input type="text" id="redactor-filename" aria-label="' + this.lang.get('filename') + '" /><br><br>'
|
5546
6558
|
+ '<div id="redactor-modal-file-upload"></div>'
|
5547
6559
|
+ '</div>'
|
5548
6560
|
+ '</section>',
|
@@ -5550,9 +6562,9 @@
|
|
5550
6562
|
link: String()
|
5551
6563
|
+ '<section id="redactor-modal-link-insert">'
|
5552
6564
|
+ '<label>URL</label>'
|
5553
|
-
+ '<input type="url" id="redactor-link-url" />'
|
6565
|
+
+ '<input type="url" id="redactor-link-url" aria-label="URL" />'
|
5554
6566
|
+ '<label>' + this.lang.get('text') + '</label>'
|
5555
|
-
+ '<input type="text" id="redactor-link-url-text" />'
|
6567
|
+
+ '<input type="text" id="redactor-link-url-text" aria-label="' + this.lang.get('text') + '" />'
|
5556
6568
|
+ '<label><input type="checkbox" id="redactor-link-blank"> ' + this.lang.get('link_new_tab') + '</label>'
|
5557
6569
|
+ '</section>'
|
5558
6570
|
};
|
@@ -5625,15 +6637,7 @@
|
|
5625
6637
|
},
|
5626
6638
|
show: function()
|
5627
6639
|
{
|
5628
|
-
|
5629
|
-
if (this.utils.isMobile() && !this.utils.browser('msie'))
|
5630
|
-
{
|
5631
|
-
document.activeElement.blur();
|
5632
|
-
}
|
5633
|
-
|
5634
|
-
$(document.body).removeClass('body-redactor-hidden');
|
5635
|
-
this.modal.bodyOveflow = $(document.body).css('overflow');
|
5636
|
-
$(document.body).css('overflow', 'hidden');
|
6640
|
+
this.utils.disableBodyScroll();
|
5637
6641
|
|
5638
6642
|
if (this.utils.isMobile())
|
5639
6643
|
{
|
@@ -5644,9 +6648,17 @@
|
|
5644
6648
|
this.modal.showOnDesktop();
|
5645
6649
|
}
|
5646
6650
|
|
6651
|
+
if (this.opts.highContrast)
|
6652
|
+
{
|
6653
|
+
this.$modalBox.addClass("redactor-modal-contrast");
|
6654
|
+
}
|
6655
|
+
|
5647
6656
|
this.$modalOverlay.show();
|
5648
6657
|
this.$modalBox.show();
|
5649
6658
|
|
6659
|
+
this.$modal.attr('tabindex', '-1');
|
6660
|
+
this.$modal.focus();
|
6661
|
+
|
5650
6662
|
this.modal.setButtonsWidth();
|
5651
6663
|
|
5652
6664
|
this.utils.saveScroll();
|
@@ -5772,10 +6784,10 @@
|
|
5772
6784
|
{
|
5773
6785
|
this.modal.buildOverlay();
|
5774
6786
|
|
5775
|
-
this.$modalBox = $('<div id="redactor-modal-box"
|
5776
|
-
this.$modal = $('<div id="redactor-modal" />');
|
5777
|
-
this.$modalHeader = $('<header />');
|
5778
|
-
this.$modalClose = $('<
|
6787
|
+
this.$modalBox = $('<div id="redactor-modal-box"/>').hide();
|
6788
|
+
this.$modal = $('<div id="redactor-modal" role="dialog" aria-labelledby="redactor-modal-header" />');
|
6789
|
+
this.$modalHeader = $('<header id="redactor-modal-header"/>');
|
6790
|
+
this.$modalClose = $('<button type="button" id="redactor-modal-close" tabindex="1" aria-label="Close" />').html('×');
|
5779
6791
|
this.$modalBody = $('<div id="redactor-modal-body" />');
|
5780
6792
|
this.$modalFooter = $('<footer />');
|
5781
6793
|
|
@@ -5824,42 +6836,157 @@
|
|
5824
6836
|
e.preventDefault();
|
5825
6837
|
}
|
5826
6838
|
|
5827
|
-
if (!this.$modalBox) return;
|
5828
|
-
|
5829
|
-
this.modal.disableEvents();
|
5830
|
-
|
5831
|
-
|
5832
|
-
|
5833
|
-
|
6839
|
+
if (!this.$modalBox) return;
|
6840
|
+
|
6841
|
+
this.modal.disableEvents();
|
6842
|
+
this.utils.enableBodyScroll();
|
6843
|
+
|
6844
|
+
this.$modalOverlay.remove();
|
6845
|
+
|
6846
|
+
this.$modalBox.fadeOut('fast', $.proxy(function()
|
6847
|
+
{
|
6848
|
+
this.$modalBox.remove();
|
6849
|
+
|
6850
|
+
setTimeout($.proxy(this.utils.restoreScroll, this), 0);
|
6851
|
+
|
6852
|
+
if (e !== undefined) this.selection.restore();
|
6853
|
+
|
6854
|
+
$(document.body).css('overflow', this.modal.bodyOveflow);
|
6855
|
+
this.core.setCallback('modalClosed', this.modal.templateName);
|
6856
|
+
|
6857
|
+
}, this));
|
6858
|
+
|
6859
|
+
}
|
6860
|
+
};
|
6861
|
+
},
|
6862
|
+
observe: function()
|
6863
|
+
{
|
6864
|
+
return {
|
6865
|
+
load: function()
|
6866
|
+
{
|
6867
|
+
if (typeof this.opts.destroyed != "undefined") return;
|
6868
|
+
|
6869
|
+
if (this.utils.browser('msie'))
|
6870
|
+
{
|
6871
|
+
var self = this;
|
6872
|
+
this.$editor.find('pre, code').on('mouseover',function()
|
6873
|
+
{
|
6874
|
+
self.$editor.attr('contenteditable', false);
|
6875
|
+
$(this).attr('contenteditable', true);
|
6876
|
+
|
6877
|
+
}).on('mouseout',function()
|
6878
|
+
{
|
6879
|
+
self.$editor.attr('contenteditable', true);
|
6880
|
+
$(this).removeAttr('contenteditable');
|
6881
|
+
|
6882
|
+
});
|
6883
|
+
}
|
6884
|
+
|
6885
|
+
this.observe.images();
|
6886
|
+
this.observe.links();
|
6887
|
+
},
|
6888
|
+
toolbar: function(e, btnName)
|
6889
|
+
{
|
6890
|
+
this.observe.buttons(e, btnName);
|
6891
|
+
this.observe.dropdowns();
|
6892
|
+
},
|
6893
|
+
isCurrent: function($el, $current)
|
6894
|
+
{
|
6895
|
+
if (typeof $current == 'undefined')
|
6896
|
+
{
|
6897
|
+
var $current = $(this.selection.getCurrent());
|
6898
|
+
}
|
6899
|
+
|
6900
|
+
return $current.is($el) || $current.parents($el).length > 0;
|
6901
|
+
},
|
6902
|
+
dropdowns: function()
|
6903
|
+
{
|
6904
|
+
var $current = $(this.selection.getCurrent());
|
6905
|
+
|
6906
|
+
$.each(this.opts.observe.dropdowns, $.proxy(function(key, value)
|
6907
|
+
{
|
6908
|
+
var observe = value.observe,
|
6909
|
+
element = observe.element,
|
6910
|
+
$item = value.item,
|
6911
|
+
inValues = typeof observe['in'] != 'undefined' ? observe['in'] : false,
|
6912
|
+
outValues = typeof observe['out'] != 'undefined' ? observe['out'] : false;
|
6913
|
+
|
6914
|
+
if ($current.closest(element).size() > 0)
|
6915
|
+
{
|
6916
|
+
this.observe.setDropdownProperties($item, inValues, outValues);
|
6917
|
+
}
|
6918
|
+
else
|
6919
|
+
{
|
6920
|
+
this.observe.setDropdownProperties($item, outValues, inValues);
|
6921
|
+
}
|
6922
|
+
}, this));
|
6923
|
+
},
|
6924
|
+
setDropdownProperties: function($item, addProperties, deleteProperties)
|
6925
|
+
{
|
6926
|
+
if (deleteProperties && typeof deleteProperties['attr'] != 'undefined')
|
6927
|
+
{
|
6928
|
+
this.observe.setDropdownAttr($item, deleteProperties.attr, true);
|
6929
|
+
}
|
6930
|
+
|
6931
|
+
if (typeof addProperties['attr'] != 'undefined')
|
5834
6932
|
{
|
5835
|
-
this
|
5836
|
-
|
5837
|
-
setTimeout($.proxy(this.utils.restoreScroll, this), 0);
|
5838
|
-
|
5839
|
-
if (e !== undefined) this.selection.restore();
|
6933
|
+
this.observe.setDropdownAttr($item, addProperties.attr);
|
6934
|
+
}
|
5840
6935
|
|
5841
|
-
|
5842
|
-
|
6936
|
+
if (typeof addProperties['title'] != 'undefined')
|
6937
|
+
{
|
6938
|
+
$item.text(addProperties['title']);
|
6939
|
+
}
|
6940
|
+
},
|
6941
|
+
setDropdownAttr: function($item, properties, isDelete)
|
6942
|
+
{
|
6943
|
+
$.each(properties, function(key, value)
|
6944
|
+
{
|
6945
|
+
if (key == 'class')
|
6946
|
+
{
|
6947
|
+
if (!isDelete)
|
6948
|
+
{
|
6949
|
+
$item.addClass(value);
|
6950
|
+
}
|
6951
|
+
else
|
6952
|
+
{
|
6953
|
+
$item.removeClass(value);
|
6954
|
+
}
|
6955
|
+
}
|
6956
|
+
else
|
6957
|
+
{
|
6958
|
+
if (!isDelete)
|
6959
|
+
{
|
6960
|
+
$item.attr(key, value);
|
6961
|
+
}
|
6962
|
+
else
|
6963
|
+
{
|
6964
|
+
$item.removeAttr(key);
|
6965
|
+
}
|
6966
|
+
}
|
6967
|
+
});
|
6968
|
+
},
|
6969
|
+
addDropdown: function($item, btnName, btnObject)
|
6970
|
+
{
|
6971
|
+
if (typeof btnObject.observe == "undefined") return;
|
5843
6972
|
|
5844
|
-
|
6973
|
+
btnObject.item = $item;
|
5845
6974
|
|
5846
|
-
|
5847
|
-
};
|
5848
|
-
},
|
5849
|
-
observe: function()
|
5850
|
-
{
|
5851
|
-
return {
|
5852
|
-
load: function()
|
5853
|
-
{
|
5854
|
-
this.observe.images();
|
5855
|
-
this.observe.links();
|
6975
|
+
this.opts.observe.dropdowns.push(btnObject);
|
5856
6976
|
},
|
5857
6977
|
buttons: function(e, btnName)
|
5858
6978
|
{
|
5859
6979
|
var current = this.selection.getCurrent();
|
5860
6980
|
var parent = this.selection.getParent();
|
5861
6981
|
|
5862
|
-
|
6982
|
+
if (e !== false)
|
6983
|
+
{
|
6984
|
+
this.button.setInactiveAll();
|
6985
|
+
}
|
6986
|
+
else
|
6987
|
+
{
|
6988
|
+
this.button.setInactiveAll(btnName);
|
6989
|
+
}
|
5863
6990
|
|
5864
6991
|
if (e === false && btnName !== 'html')
|
5865
6992
|
{
|
@@ -5872,19 +6999,19 @@
|
|
5872
6999
|
|
5873
7000
|
$.each(this.opts.activeButtonsStates, $.proxy(function(key, value)
|
5874
7001
|
{
|
5875
|
-
var parentEl = $(parent).closest(key);
|
5876
|
-
var currentEl = $(current).closest(key);
|
7002
|
+
var parentEl = $(parent).closest(key, this.$editor[0]);
|
7003
|
+
var currentEl = $(current).closest(key, this.$editor[0]);
|
5877
7004
|
|
5878
7005
|
if (parentEl.length !== 0 && !this.utils.isRedactorParent(parentEl)) return;
|
5879
7006
|
if (!this.utils.isRedactorParent(currentEl)) return;
|
5880
|
-
if (parentEl.length !== 0 || currentEl.closest(key).length !== 0)
|
7007
|
+
if (parentEl.length !== 0 || currentEl.closest(key, this.$editor[0]).length !== 0)
|
5881
7008
|
{
|
5882
7009
|
this.button.setActive(value);
|
5883
7010
|
}
|
5884
7011
|
|
5885
7012
|
}, this));
|
5886
7013
|
|
5887
|
-
var $parent = $(parent).closest(this.opts.alignmentTags.toString().toLowerCase());
|
7014
|
+
var $parent = $(parent).closest(this.opts.alignmentTags.toString().toLowerCase(), this.$editor[0]);
|
5888
7015
|
if (this.utils.isRedactorParent(parent) && $parent.length)
|
5889
7016
|
{
|
5890
7017
|
var align = ($parent.css('text-align') === '') ? 'left' : $parent.css('text-align');
|
@@ -5903,7 +7030,7 @@
|
|
5903
7030
|
var $img = $(img);
|
5904
7031
|
|
5905
7032
|
// IE fix (when we clicked on an image and then press backspace IE does goes to image's url)
|
5906
|
-
$img.closest('a').on('click', function(e) { e.preventDefault(); });
|
7033
|
+
$img.closest('a', this.$editor[0]).on('click', function(e) { e.preventDefault(); });
|
5907
7034
|
|
5908
7035
|
if (this.utils.browser('msie')) $img.attr('unselectable', 'on');
|
5909
7036
|
|
@@ -5911,7 +7038,7 @@
|
|
5911
7038
|
|
5912
7039
|
}, this));
|
5913
7040
|
|
5914
|
-
$(document).on('click.redactor-image-delete', $.proxy(function(e)
|
7041
|
+
$(document).on('click.redactor-image-delete.' + this.uuid, $.proxy(function(e)
|
5915
7042
|
{
|
5916
7043
|
this.observe.image = false;
|
5917
7044
|
if (e.target.tagName == 'IMG' && this.utils.isRedactorParent(e.target))
|
@@ -5926,9 +7053,9 @@
|
|
5926
7053
|
{
|
5927
7054
|
if (!this.opts.linkTooltip) return;
|
5928
7055
|
|
5929
|
-
this.$editor.find('a').on('touchstart click', $.proxy(this.observe.showTooltip, this));
|
5930
|
-
this.$editor.on('touchstart click.redactor', $.proxy(this.observe.closeTooltip, this));
|
5931
|
-
$(document).on('touchstart click.redactor', $.proxy(this.observe.closeTooltip, this));
|
7056
|
+
this.$editor.find('a').on('touchstart.redactor.' + this.uuid + ' click.redactor.' + this.uuid, $.proxy(this.observe.showTooltip, this));
|
7057
|
+
this.$editor.on('touchstart.redactor.' + this.uuid + ' click.redactor.' + this.uuid, $.proxy(this.observe.closeTooltip, this));
|
7058
|
+
$(document).on('touchstart.redactor.' + this.uuid + ' click.redactor.' + this.uuid, $.proxy(this.observe.closeTooltip, this));
|
5932
7059
|
},
|
5933
7060
|
getTooltipPosition: function($link)
|
5934
7061
|
{
|
@@ -5936,20 +7063,18 @@
|
|
5936
7063
|
},
|
5937
7064
|
showTooltip: function(e)
|
5938
7065
|
{
|
5939
|
-
var $
|
5940
|
-
var $parent = $link.closest('a');
|
5941
|
-
var tag = ($link.length !== 0) ? $link[0].tagName : false;
|
7066
|
+
var $el = $(e.target);
|
5942
7067
|
|
5943
|
-
if ($
|
5944
|
-
|
5945
|
-
if (tag === 'IMG') return;
|
5946
|
-
else if (tag !== 'A') $link = $parent;
|
5947
|
-
}
|
7068
|
+
if ($el[0].tagName == 'IMG')
|
7069
|
+
return;
|
5948
7070
|
|
5949
|
-
if (
|
5950
|
-
|
7071
|
+
if ($el[0].tagName !== 'A')
|
7072
|
+
$el = $el.closest('a', this.$editor[0]);
|
7073
|
+
|
7074
|
+
if ($el[0].tagName !== 'A')
|
5951
7075
|
return;
|
5952
|
-
|
7076
|
+
|
7077
|
+
var $link = $el;
|
5953
7078
|
|
5954
7079
|
var pos = this.observe.getTooltipPosition($link);
|
5955
7080
|
var tooltip = $('<span class="redactor-link-tooltip"></span>');
|
@@ -5980,7 +7105,7 @@
|
|
5980
7105
|
e = e.originalEvent || e;
|
5981
7106
|
|
5982
7107
|
var target = e.target;
|
5983
|
-
var $parent = $(target).closest('a');
|
7108
|
+
var $parent = $(target).closest('a', this.$editor[0]);
|
5984
7109
|
if ($parent.length !== 0 && $parent[0].tagName === 'A' && target.tagName !== 'A')
|
5985
7110
|
{
|
5986
7111
|
return;
|
@@ -6003,10 +7128,6 @@
|
|
6003
7128
|
if (this.opts.linebreaks) return html;
|
6004
7129
|
if (html === '' || html === '<p></p>') return this.opts.emptyHtml;
|
6005
7130
|
|
6006
|
-
this.paragraphize.blocks = ['table', 'div', 'pre', 'form', 'ul', 'ol', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dl', 'blockquote', 'figcaption',
|
6007
|
-
'address', 'section', 'header', 'footer', 'aside', 'article', 'object', 'style', 'script', 'iframe', 'select', 'input', 'textarea',
|
6008
|
-
'button', 'option', 'map', 'area', 'math', 'hr', 'fieldset', 'legend', 'hgroup', 'nav', 'figure', 'details', 'menu', 'summary', 'p'];
|
6009
|
-
|
6010
7131
|
html = html + "\n";
|
6011
7132
|
|
6012
7133
|
this.paragraphize.safes = [];
|
@@ -6021,7 +7142,7 @@
|
|
6021
7142
|
html = this.paragraphize.clear(html);
|
6022
7143
|
html = this.paragraphize.restoreSafes(html);
|
6023
7144
|
|
6024
|
-
html = html.replace(new RegExp('<br\\s?/?>\n?<(' + this.
|
7145
|
+
html = html.replace(new RegExp('<br\\s?/?>\n?<(' + this.opts.paragraphizeBlocks.join('|') + ')(.*?[^>])>', 'gi'), '<p><br /></p>\n<$1$2>');
|
6025
7146
|
|
6026
7147
|
return $.trim(html);
|
6027
7148
|
},
|
@@ -6037,7 +7158,7 @@
|
|
6037
7158
|
|
6038
7159
|
html = $div.html();
|
6039
7160
|
|
6040
|
-
$div.find(this.
|
7161
|
+
$div.find(this.opts.paragraphizeBlocks.join(', ')).each($.proxy(function(i,s)
|
6041
7162
|
{
|
6042
7163
|
this.paragraphize.z++;
|
6043
7164
|
this.paragraphize.safes[this.paragraphize.z] = s.outerHTML;
|
@@ -6066,7 +7187,9 @@
|
|
6066
7187
|
{
|
6067
7188
|
$.each(this.paragraphize.safes, function(i,s)
|
6068
7189
|
{
|
7190
|
+
s = (typeof s !== 'undefined') ? s.replace(/\$/g, '$') : s;
|
6069
7191
|
html = html.replace('{replace' + i + '}', s);
|
7192
|
+
|
6070
7193
|
});
|
6071
7194
|
|
6072
7195
|
return html;
|
@@ -6134,7 +7257,11 @@
|
|
6134
7257
|
return {
|
6135
7258
|
init: function(e)
|
6136
7259
|
{
|
6137
|
-
if (!this.opts.cleanOnPaste)
|
7260
|
+
if (!this.opts.cleanOnPaste)
|
7261
|
+
{
|
7262
|
+
setTimeout($.proxy(this.code.sync, this), 1);
|
7263
|
+
return;
|
7264
|
+
}
|
6138
7265
|
|
6139
7266
|
this.rtePaste = true;
|
6140
7267
|
|
@@ -6163,15 +7290,36 @@
|
|
6163
7290
|
|
6164
7291
|
$(window).off('scroll.redactor-freeze');
|
6165
7292
|
|
6166
|
-
|
7293
|
+
if (this.linkify.isEnabled())
|
7294
|
+
{
|
7295
|
+
this.linkify.format();
|
7296
|
+
}
|
6167
7297
|
|
7298
|
+
}, this), 1);
|
6168
7299
|
},
|
6169
7300
|
createPasteBox: function()
|
6170
7301
|
{
|
6171
7302
|
this.$pasteBox = $('<div>').html('').attr('contenteditable', 'true').css({ position: 'fixed', width: 0, top: 0, left: '-9999px' });
|
6172
7303
|
|
6173
|
-
this
|
6174
|
-
|
7304
|
+
if (this.utils.browser('msie'))
|
7305
|
+
{
|
7306
|
+
this.$box.append(this.$pasteBox);
|
7307
|
+
}
|
7308
|
+
else
|
7309
|
+
{
|
7310
|
+
// bootstrap modal
|
7311
|
+
var $visibleModals = $('.modal-body:visible');
|
7312
|
+
if ($visibleModals.length > 0)
|
7313
|
+
{
|
7314
|
+
$visibleModals.append(this.$pasteBox);
|
7315
|
+
}
|
7316
|
+
else
|
7317
|
+
{
|
7318
|
+
$('body').append(this.$pasteBox);
|
7319
|
+
}
|
7320
|
+
}
|
7321
|
+
|
7322
|
+
this.$pasteBox.get(0).focus();
|
6175
7323
|
},
|
6176
7324
|
insert: function(html)
|
6177
7325
|
{
|
@@ -6202,12 +7350,13 @@
|
|
6202
7350
|
var spans = this.$editor.find('span');
|
6203
7351
|
$.each(spans, function(i,s)
|
6204
7352
|
{
|
6205
|
-
var html = s.innerHTML.replace(
|
7353
|
+
var html = s.innerHTML.replace(/\u200B/, '');
|
6206
7354
|
if (html === '' && s.attributes.length === 0) $(s).remove();
|
6207
7355
|
|
6208
7356
|
});
|
6209
7357
|
|
6210
7358
|
}, this), 10);
|
7359
|
+
|
6211
7360
|
}
|
6212
7361
|
};
|
6213
7362
|
},
|
@@ -6221,14 +7370,16 @@
|
|
6221
7370
|
this.$editor.attr('placeholder', this.$element.attr('placeholder'));
|
6222
7371
|
|
6223
7372
|
this.placeholder.toggle();
|
6224
|
-
this.$editor.on('
|
6225
|
-
|
7373
|
+
this.$editor.on('keydown.redactor-placeholder', $.proxy(this.placeholder.toggle, this));
|
6226
7374
|
},
|
6227
7375
|
toggle: function()
|
6228
7376
|
{
|
6229
|
-
|
6230
|
-
|
6231
|
-
|
7377
|
+
setTimeout($.proxy(function()
|
7378
|
+
{
|
7379
|
+
var func = this.utils.isEmpty(this.$editor.html(), false) ? 'addClass' : 'removeClass';
|
7380
|
+
this.$editor[func]('redactor-placeholder');
|
7381
|
+
|
7382
|
+
}, this), 5);
|
6232
7383
|
},
|
6233
7384
|
remove: function()
|
6234
7385
|
{
|
@@ -6292,6 +7443,7 @@
|
|
6292
7443
|
getCurrent: function()
|
6293
7444
|
{
|
6294
7445
|
var el = false;
|
7446
|
+
|
6295
7447
|
this.selection.get();
|
6296
7448
|
|
6297
7449
|
if (this.sel && this.sel.rangeCount > 0)
|
@@ -6311,6 +7463,14 @@
|
|
6311
7463
|
|
6312
7464
|
return false;
|
6313
7465
|
},
|
7466
|
+
getPrev: function()
|
7467
|
+
{
|
7468
|
+
return window.getSelection().anchorNode.previousSibling;
|
7469
|
+
},
|
7470
|
+
getNext: function()
|
7471
|
+
{
|
7472
|
+
return window.getSelection().anchorNode.nextSibling;
|
7473
|
+
},
|
6314
7474
|
getBlock: function(node)
|
6315
7475
|
{
|
6316
7476
|
node = node || this.selection.getCurrent();
|
@@ -6327,7 +7487,7 @@
|
|
6327
7487
|
|
6328
7488
|
return false;
|
6329
7489
|
},
|
6330
|
-
getInlines: function(nodes)
|
7490
|
+
getInlines: function(nodes, tags)
|
6331
7491
|
{
|
6332
7492
|
this.selection.get();
|
6333
7493
|
|
@@ -6337,9 +7497,18 @@
|
|
6337
7497
|
}
|
6338
7498
|
|
6339
7499
|
var inlines = [];
|
6340
|
-
nodes = (typeof nodes == 'undefined') ? this.selection.getNodes() : nodes;
|
7500
|
+
nodes = (typeof nodes == 'undefined' || nodes === false) ? this.selection.getNodes() : nodes;
|
6341
7501
|
var inlineTags = this.opts.inlineTags;
|
6342
7502
|
inlineTags.push('span');
|
7503
|
+
|
7504
|
+
if (typeof tags !== 'undefined')
|
7505
|
+
{
|
7506
|
+
for (var i = 0; i < tags.length; i++)
|
7507
|
+
{
|
7508
|
+
inlineTags.push(tags[i]);
|
7509
|
+
}
|
7510
|
+
}
|
7511
|
+
|
6343
7512
|
$.each(nodes, $.proxy(function(i,node)
|
6344
7513
|
{
|
6345
7514
|
if ($.inArray(node.tagName.toLowerCase(), inlineTags) != -1)
|
@@ -6351,6 +7520,28 @@
|
|
6351
7520
|
|
6352
7521
|
return (inlines.length === 0) ? false : inlines;
|
6353
7522
|
},
|
7523
|
+
getInlinesTags: function(tags)
|
7524
|
+
{
|
7525
|
+
this.selection.get();
|
7526
|
+
|
7527
|
+
if (this.range && this.range.collapsed)
|
7528
|
+
{
|
7529
|
+
return false;
|
7530
|
+
}
|
7531
|
+
|
7532
|
+
var inlines = [];
|
7533
|
+
var nodes = this.selection.getNodes();
|
7534
|
+
$.each(nodes, $.proxy(function(i,node)
|
7535
|
+
{
|
7536
|
+
if ($.inArray(node.tagName.toLowerCase(), tags) != -1)
|
7537
|
+
{
|
7538
|
+
inlines.push(node);
|
7539
|
+
}
|
7540
|
+
|
7541
|
+
}, this));
|
7542
|
+
|
7543
|
+
return (inlines.length === 0) ? false : inlines;
|
7544
|
+
},
|
6354
7545
|
getBlocks: function(nodes)
|
6355
7546
|
{
|
6356
7547
|
this.selection.get();
|
@@ -6362,11 +7553,11 @@
|
|
6362
7553
|
|
6363
7554
|
var blocks = [];
|
6364
7555
|
nodes = (typeof nodes == 'undefined') ? this.selection.getNodes() : nodes;
|
7556
|
+
|
6365
7557
|
$.each(nodes, $.proxy(function(i,node)
|
6366
7558
|
{
|
6367
7559
|
if (this.utils.isBlock(node))
|
6368
7560
|
{
|
6369
|
-
this.selection.lastBlock = node;
|
6370
7561
|
blocks.push(node);
|
6371
7562
|
}
|
6372
7563
|
|
@@ -6384,23 +7575,34 @@
|
|
6384
7575
|
|
6385
7576
|
var startNode = this.selection.getNodesMarker(1);
|
6386
7577
|
var endNode = this.selection.getNodesMarker(2);
|
6387
|
-
var range = this.range.cloneRange();
|
6388
7578
|
|
6389
7579
|
if (this.range.collapsed === false)
|
6390
7580
|
{
|
6391
|
-
|
6392
|
-
|
6393
|
-
|
6394
|
-
|
6395
|
-
|
6396
|
-
|
6397
|
-
|
6398
|
-
|
6399
|
-
|
7581
|
+
if (window.getSelection) {
|
7582
|
+
var sel = window.getSelection();
|
7583
|
+
if (sel.rangeCount > 0) {
|
7584
|
+
|
7585
|
+
var range = sel.getRangeAt(0);
|
7586
|
+
var startPointNode = range.startContainer, startOffset = range.startOffset;
|
7587
|
+
|
7588
|
+
var boundaryRange = range.cloneRange();
|
7589
|
+
boundaryRange.collapse(false);
|
7590
|
+
boundaryRange.insertNode(endNode);
|
7591
|
+
boundaryRange.setStart(startPointNode, startOffset);
|
7592
|
+
boundaryRange.collapse(true);
|
7593
|
+
boundaryRange.insertNode(startNode);
|
7594
|
+
|
7595
|
+
// Reselect the original text
|
7596
|
+
range.setStartAfter(startNode);
|
7597
|
+
range.setEndBefore(endNode);
|
7598
|
+
sel.removeAllRanges();
|
7599
|
+
sel.addRange(range);
|
7600
|
+
}
|
7601
|
+
}
|
6400
7602
|
}
|
6401
7603
|
else
|
6402
7604
|
{
|
6403
|
-
this.selection.setNodesMarker(range, startNode, true);
|
7605
|
+
this.selection.setNodesMarker(this.range, startNode, true);
|
6404
7606
|
endNode = startNode;
|
6405
7607
|
}
|
6406
7608
|
|
@@ -6458,6 +7660,8 @@
|
|
6458
7660
|
},
|
6459
7661
|
setNodesMarker: function(range, node, type)
|
6460
7662
|
{
|
7663
|
+
var range = range.cloneRange();
|
7664
|
+
|
6461
7665
|
try {
|
6462
7666
|
range.collapse(type);
|
6463
7667
|
range.insertNode(node);
|
@@ -6487,7 +7691,17 @@
|
|
6487
7691
|
},
|
6488
7692
|
selectElement: function(node)
|
6489
7693
|
{
|
6490
|
-
this.
|
7694
|
+
if (this.utils.browser('mozilla'))
|
7695
|
+
{
|
7696
|
+
node = node[0] || node;
|
7697
|
+
|
7698
|
+
var range = document.createRange();
|
7699
|
+
range.selectNodeContents(node);
|
7700
|
+
}
|
7701
|
+
else
|
7702
|
+
{
|
7703
|
+
this.caret.set(node, 0, node, 1);
|
7704
|
+
}
|
6491
7705
|
},
|
6492
7706
|
selectAll: function()
|
6493
7707
|
{
|
@@ -6511,7 +7725,6 @@
|
|
6511
7725
|
var node1 = this.selection.getMarker(1);
|
6512
7726
|
|
6513
7727
|
this.selection.setMarker(this.range, node1, true);
|
6514
|
-
|
6515
7728
|
if (this.range.collapsed === false)
|
6516
7729
|
{
|
6517
7730
|
var node2 = this.selection.getMarker(2);
|
@@ -6537,17 +7750,24 @@
|
|
6537
7750
|
try {
|
6538
7751
|
range.collapse(type);
|
6539
7752
|
range.insertNode(node);
|
7753
|
+
|
6540
7754
|
}
|
6541
7755
|
catch (e)
|
6542
7756
|
{
|
6543
7757
|
this.focus.setStart();
|
6544
7758
|
}
|
7759
|
+
|
6545
7760
|
},
|
6546
7761
|
restore: function()
|
6547
7762
|
{
|
6548
7763
|
var node1 = this.$editor.find('span#selection-marker-1');
|
6549
7764
|
var node2 = this.$editor.find('span#selection-marker-2');
|
6550
7765
|
|
7766
|
+
if (this.utils.browser('mozilla'))
|
7767
|
+
{
|
7768
|
+
this.$editor.focus();
|
7769
|
+
}
|
7770
|
+
|
6551
7771
|
if (node1.length !== 0 && node2.length !== 0)
|
6552
7772
|
{
|
6553
7773
|
this.caret.set(node1, 0, node2, 0);
|
@@ -6567,7 +7787,12 @@
|
|
6567
7787
|
},
|
6568
7788
|
removeMarkers: function()
|
6569
7789
|
{
|
6570
|
-
this.$editor.find('span.redactor-selection-marker').
|
7790
|
+
this.$editor.find('span.redactor-selection-marker').each(function(i,s)
|
7791
|
+
{
|
7792
|
+
var text = $(s).text().replace(/\u200B/g, '');
|
7793
|
+
if (text === '') $(s).remove();
|
7794
|
+
else $(s).replaceWith(function() { return $(this).contents(); });
|
7795
|
+
});
|
6571
7796
|
},
|
6572
7797
|
getText: function()
|
6573
7798
|
{
|
@@ -6593,6 +7818,37 @@
|
|
6593
7818
|
}
|
6594
7819
|
|
6595
7820
|
return this.clean.onSync(html);
|
7821
|
+
},
|
7822
|
+
replaceSelection: function(html)
|
7823
|
+
{
|
7824
|
+
this.selection.get();
|
7825
|
+
this.range.deleteContents();
|
7826
|
+
var div = document.createElement("div");
|
7827
|
+
div.innerHTML = html;
|
7828
|
+
var frag = document.createDocumentFragment(), child;
|
7829
|
+
while ((child = div.firstChild)) {
|
7830
|
+
frag.appendChild(child);
|
7831
|
+
}
|
7832
|
+
|
7833
|
+
this.range.insertNode(frag);
|
7834
|
+
},
|
7835
|
+
replaceWithHtml: function(html)
|
7836
|
+
{
|
7837
|
+
html = this.selection.getMarkerAsHtml(1) + html + this.selection.getMarkerAsHtml(2);
|
7838
|
+
|
7839
|
+
this.selection.get();
|
7840
|
+
|
7841
|
+
if (window.getSelection && window.getSelection().getRangeAt)
|
7842
|
+
{
|
7843
|
+
this.selection.replaceSelection(html);
|
7844
|
+
}
|
7845
|
+
else if (document.selection && document.selection.createRange)
|
7846
|
+
{
|
7847
|
+
this.range.pasteHTML(html);
|
7848
|
+
}
|
7849
|
+
|
7850
|
+
this.selection.restore();
|
7851
|
+
this.code.sync();
|
6596
7852
|
}
|
6597
7853
|
};
|
6598
7854
|
},
|
@@ -6710,7 +7966,7 @@
|
|
6710
7966
|
// clean setup
|
6711
7967
|
var ownLine = ['area', 'body', 'head', 'hr', 'i?frame', 'link', 'meta', 'noscript', 'style', 'script', 'table', 'tbody', 'thead', 'tfoot'];
|
6712
7968
|
var contOwnLine = ['li', 'dt', 'dt', 'h[1-6]', 'option', 'script'];
|
6713
|
-
var newLevel = ['blockquote', 'div', 'dl', 'fieldset', 'form', 'frameset', 'map', 'ol', '
|
7969
|
+
var newLevel = ['p', 'blockquote', 'div', 'dl', 'fieldset', 'form', 'frameset', 'map', 'ol', 'pre', 'select', 'td', 'th', 'tr', 'ul'];
|
6714
7970
|
|
6715
7971
|
this.tabifier.lineBefore = new RegExp('^<(/?' + ownLine.join('|/?' ) + '|' + contOwnLine.join('|') + ')[ >]');
|
6716
7972
|
this.tabifier.lineAfter = new RegExp('^<(br|/?' + ownLine.join('|/?' ) + '|/' + contOwnLine.join('|/') + ')[ >]');
|
@@ -6875,6 +8131,7 @@
|
|
6875
8131
|
placeTag: function (tag, out)
|
6876
8132
|
{
|
6877
8133
|
var nl = tag.match(this.tabifier.newLevel);
|
8134
|
+
|
6878
8135
|
if (tag.match(this.tabifier.lineBefore) || nl)
|
6879
8136
|
{
|
6880
8137
|
out = out.replace(/\s*$/, '');
|
@@ -6890,7 +8147,7 @@
|
|
6890
8147
|
if (tag.match(this.tabifier.lineAfter) || tag.match(this.tabifier.newLevel))
|
6891
8148
|
{
|
6892
8149
|
out = out.replace(/ *$/, '');
|
6893
|
-
out += '\n';
|
8150
|
+
//out += '\n';
|
6894
8151
|
}
|
6895
8152
|
|
6896
8153
|
return out;
|
@@ -6902,6 +8159,12 @@
|
|
6902
8159
|
return {
|
6903
8160
|
setupAllowed: function()
|
6904
8161
|
{
|
8162
|
+
var index = $.inArray('span', this.opts.removeEmpty);
|
8163
|
+
if (index !== -1)
|
8164
|
+
{
|
8165
|
+
this.opts.removeEmpty.splice(index, 1);
|
8166
|
+
}
|
8167
|
+
|
6905
8168
|
if (this.opts.allowedTags) this.opts.deniedTags = false;
|
6906
8169
|
if (this.opts.allowedAttr) this.opts.removeAttr = false;
|
6907
8170
|
|
@@ -6991,24 +8254,13 @@
|
|
6991
8254
|
replacement.push(this.tidy.settings.replaceTags[i][0]);
|
6992
8255
|
}
|
6993
8256
|
|
6994
|
-
|
8257
|
+
$.each(replacement, $.proxy(function(key, value)
|
6995
8258
|
{
|
6996
|
-
|
6997
|
-
$(s).replaceWith(function()
|
8259
|
+
this.tidy.$div.find(value).replaceWith(function()
|
6998
8260
|
{
|
6999
|
-
|
7000
|
-
|
7001
|
-
for (var i = 0; i < this.attributes.length; i++)
|
7002
|
-
{
|
7003
|
-
replaced.attr(this.attributes[i].name, this.attributes[i].value);
|
7004
|
-
}
|
7005
|
-
|
7006
|
-
return replaced;
|
8261
|
+
return $("<" + rTags[key] + " />", {html: $(this).html()});
|
7007
8262
|
});
|
7008
|
-
|
7009
8263
|
}, this));
|
7010
|
-
|
7011
|
-
return html;
|
7012
8264
|
},
|
7013
8265
|
replaceStyles: function()
|
7014
8266
|
{
|
@@ -7050,6 +8302,8 @@
|
|
7050
8302
|
{
|
7051
8303
|
this.tidy.$div.find(this.tidy.settings.deniedTags.join(',')).each(function(i, s)
|
7052
8304
|
{
|
8305
|
+
if ($(s).hasClass('redactor-script-tag') || $(s).hasClass('redactor-selection-marker')) return;
|
8306
|
+
|
7053
8307
|
if (s.innerHTML === '') $(s).remove();
|
7054
8308
|
else $(s).contents().unwrap();
|
7055
8309
|
});
|
@@ -7163,7 +8417,7 @@
|
|
7163
8417
|
{
|
7164
8418
|
var $el = $(this);
|
7165
8419
|
var text = $el.text();
|
7166
|
-
text = text.replace(
|
8420
|
+
text = text.replace(/\u200B/g, '');
|
7167
8421
|
text = text.replace(/ /gi, '');
|
7168
8422
|
text = text.replace(/\s/g, '');
|
7169
8423
|
|
@@ -7317,12 +8571,30 @@
|
|
7317
8571
|
link:
|
7318
8572
|
{
|
7319
8573
|
title: this.lang.get('link_insert'),
|
7320
|
-
func: 'link.show'
|
8574
|
+
func: 'link.show',
|
8575
|
+
observe: {
|
8576
|
+
element: 'a',
|
8577
|
+
in: {
|
8578
|
+
title: this.lang.get('link_edit'),
|
8579
|
+
},
|
8580
|
+
out: {
|
8581
|
+
title: this.lang.get('link_insert')
|
8582
|
+
}
|
8583
|
+
}
|
7321
8584
|
},
|
7322
8585
|
unlink:
|
7323
8586
|
{
|
7324
8587
|
title: this.lang.get('unlink'),
|
7325
|
-
func: 'link.unlink'
|
8588
|
+
func: 'link.unlink',
|
8589
|
+
observe: {
|
8590
|
+
element: 'a',
|
8591
|
+
out: {
|
8592
|
+
attr: {
|
8593
|
+
'class': 'redactor-dropdown-link-inactive',
|
8594
|
+
'aria-disabled': true
|
8595
|
+
}
|
8596
|
+
}
|
8597
|
+
}
|
7326
8598
|
}
|
7327
8599
|
}
|
7328
8600
|
},
|
@@ -7379,13 +8651,13 @@
|
|
7379
8651
|
// buttons response
|
7380
8652
|
if (this.opts.activeButtons)
|
7381
8653
|
{
|
7382
|
-
this.$editor.on('mouseup.redactor keyup.redactor focus.redactor', $.proxy(this.observe.
|
8654
|
+
this.$editor.on('mouseup.redactor keyup.redactor focus.redactor', $.proxy(this.observe.toolbar, this));
|
7383
8655
|
}
|
7384
8656
|
|
7385
8657
|
},
|
7386
8658
|
createContainer: function()
|
7387
8659
|
{
|
7388
|
-
return $('<ul>').addClass('redactor-toolbar').attr('id'
|
8660
|
+
return $('<ul>').addClass('redactor-toolbar').attr({'id': 'redactor-toolbar-' + this.uuid, 'role': 'toolbar'});
|
7389
8661
|
},
|
7390
8662
|
setFormattingTags: function()
|
7391
8663
|
{
|
@@ -7437,7 +8709,7 @@
|
|
7437
8709
|
if (!this.opts.toolbarFixed) return;
|
7438
8710
|
|
7439
8711
|
this.toolbar.observeScroll();
|
7440
|
-
$(this.opts.toolbarFixedTarget).on('scroll.redactor', $.proxy(this.toolbar.observeScroll, this));
|
8712
|
+
$(this.opts.toolbarFixedTarget).on('scroll.redactor.' + this.uuid, $.proxy(this.toolbar.observeScroll, this));
|
7441
8713
|
|
7442
8714
|
},
|
7443
8715
|
setOverflow: function()
|
@@ -7489,7 +8761,7 @@
|
|
7489
8761
|
boxTop = this.$box.offset().top;
|
7490
8762
|
}
|
7491
8763
|
|
7492
|
-
if (scrollTop > boxTop)
|
8764
|
+
if ((scrollTop + this.opts.toolbarFixedTopOffset) > boxTop)
|
7493
8765
|
{
|
7494
8766
|
this.toolbar.observeScrollEnable(scrollTop, boxTop);
|
7495
8767
|
}
|
@@ -7502,7 +8774,7 @@
|
|
7502
8774
|
{
|
7503
8775
|
var top = this.opts.toolbarFixedTopOffset + scrollTop - boxTop;
|
7504
8776
|
var left = 0;
|
7505
|
-
var end = boxTop + this.$box.height()
|
8777
|
+
var end = boxTop + this.$box.height() - 32;
|
7506
8778
|
var width = this.$box.innerWidth();
|
7507
8779
|
|
7508
8780
|
this.$toolbar.addClass('toolbar-fixed-box');
|
@@ -7513,6 +8785,9 @@
|
|
7513
8785
|
left: left
|
7514
8786
|
});
|
7515
8787
|
|
8788
|
+
if (scrollTop > end)
|
8789
|
+
$('.redactor-dropdown-' + this.uuid + ':visible').hide();
|
8790
|
+
|
7516
8791
|
this.toolbar.setDropdownsFixed();
|
7517
8792
|
this.$toolbar.css('visibility', (scrollTop < end) ? 'visible' : 'hidden');
|
7518
8793
|
},
|
@@ -7528,7 +8803,6 @@
|
|
7528
8803
|
|
7529
8804
|
this.toolbar.unsetDropdownsFixed();
|
7530
8805
|
this.$toolbar.removeClass('toolbar-fixed-box');
|
7531
|
-
|
7532
8806
|
},
|
7533
8807
|
setDropdownsFixed: function()
|
7534
8808
|
{
|
@@ -7540,7 +8814,7 @@
|
|
7540
8814
|
position = 'absolute';
|
7541
8815
|
}
|
7542
8816
|
|
7543
|
-
$('.redactor-dropdown').each(function()
|
8817
|
+
$('.redactor-dropdown-' + this.uuid).each(function()
|
7544
8818
|
{
|
7545
8819
|
$(this).css({ position: position, top: top + 'px' });
|
7546
8820
|
});
|
@@ -7548,7 +8822,7 @@
|
|
7548
8822
|
unsetDropdownsFixed: function()
|
7549
8823
|
{
|
7550
8824
|
var top = (this.$toolbar.innerHeight() + this.$toolbar.offset().top);
|
7551
|
-
$('.redactor-dropdown').each(function()
|
8825
|
+
$('.redactor-dropdown-' + this.uuid).each(function()
|
7552
8826
|
{
|
7553
8827
|
$(this).css({ position: 'absolute', top: top + 'px' });
|
7554
8828
|
});
|
@@ -7566,7 +8840,7 @@
|
|
7566
8840
|
this.upload.$el = $(id);
|
7567
8841
|
this.upload.$droparea = $('<div id="redactor-droparea" />');
|
7568
8842
|
|
7569
|
-
this.upload.$placeholdler = $('<div id="redactor-droparea-placeholder" />').text('
|
8843
|
+
this.upload.$placeholdler = $('<div id="redactor-droparea-placeholder" />').text(this.lang.get('upload_label'));
|
7570
8844
|
this.upload.$input = $('<input type="file" name="file" />');
|
7571
8845
|
|
7572
8846
|
this.upload.$placeholdler.append(this.upload.$input);
|
@@ -7627,6 +8901,7 @@
|
|
7627
8901
|
}
|
7628
8902
|
|
7629
8903
|
this.progress.show();
|
8904
|
+
this.core.setCallback('uploadStart', e, formData);
|
7630
8905
|
this.upload.sendData(formData, e);
|
7631
8906
|
},
|
7632
8907
|
setConfig: function(file)
|
@@ -7646,6 +8921,12 @@
|
|
7646
8921
|
{
|
7647
8922
|
this.upload.type = 'file';
|
7648
8923
|
}
|
8924
|
+
|
8925
|
+
if (this.opts.imageUpload === null && this.opts.fileUpload !== null)
|
8926
|
+
{
|
8927
|
+
this.upload.type = 'file';
|
8928
|
+
}
|
8929
|
+
|
7649
8930
|
},
|
7650
8931
|
getHiddenFields: function(obj, fd)
|
7651
8932
|
{
|
@@ -7677,6 +8958,7 @@
|
|
7677
8958
|
|
7678
8959
|
var xhr = new XMLHttpRequest();
|
7679
8960
|
xhr.open('POST', this.upload.url);
|
8961
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
7680
8962
|
|
7681
8963
|
// complete
|
7682
8964
|
xhr.onreadystatechange = $.proxy(function()
|
@@ -7775,9 +9057,7 @@
|
|
7775
9057
|
s3executeOnSignedUrl: function(file, callback)
|
7776
9058
|
{
|
7777
9059
|
var xhr = new XMLHttpRequest();
|
7778
|
-
|
7779
|
-
var mark = '?';
|
7780
|
-
if (this.opts.s3.search(/\?/) != '-1') mark = '&';
|
9060
|
+
var mark = (this.opts.s3.search(/\?/) !== '-1') ? '?' : '&';
|
7781
9061
|
|
7782
9062
|
xhr.open('GET', this.opts.s3 + mark + 'name=' + file.name + '&type=' + file.type, true);
|
7783
9063
|
|
@@ -7867,21 +9147,9 @@
|
|
7867
9147
|
}
|
7868
9148
|
}, this);
|
7869
9149
|
|
7870
|
-
xhr.onerror = function()
|
7871
|
-
{
|
7872
|
-
//setProgress(0, 'XHR error.');
|
7873
|
-
};
|
9150
|
+
xhr.onerror = function() {};
|
7874
9151
|
|
7875
|
-
xhr.upload.onprogress = function(e)
|
7876
|
-
{
|
7877
|
-
/*
|
7878
|
-
if (e.lengthComputable)
|
7879
|
-
{
|
7880
|
-
var percentLoaded = Math.round((e.loaded / e.total) * 100);
|
7881
|
-
setProgress(percentLoaded, percentLoaded == 100 ? 'Finalizing.' : 'Uploading.');
|
7882
|
-
}
|
7883
|
-
*/
|
7884
|
-
};
|
9152
|
+
xhr.upload.onprogress = function(e) {};
|
7885
9153
|
|
7886
9154
|
xhr.setRequestHeader('Content-Type', file.type);
|
7887
9155
|
xhr.setRequestHeader('x-amz-acl', 'public-read');
|
@@ -7914,6 +9182,7 @@
|
|
7914
9182
|
html = html.replace(/\s/g, '');
|
7915
9183
|
html = html.replace(/^<p>[^\W\w\D\d]*?<\/p>$/i, '');
|
7916
9184
|
html = html.replace(/<iframe(.*?[^>])>$/i, 'iframe');
|
9185
|
+
html = html.replace(/<source(.*?[^>])>$/i, 'source');
|
7917
9186
|
|
7918
9187
|
// remove empty tags
|
7919
9188
|
if (removeEmptyTags !== false)
|
@@ -7978,12 +9247,13 @@
|
|
7978
9247
|
},
|
7979
9248
|
removeEmpty: function(i, s)
|
7980
9249
|
{
|
7981
|
-
var $s = $(s);
|
9250
|
+
var $s = $($.parseHTML(s));
|
7982
9251
|
|
7983
9252
|
$s.find('.redactor-invisible-space').removeAttr('style').removeAttr('class');
|
7984
9253
|
|
7985
|
-
if ($s.find('hr, br, img, iframe').length !== 0) return;
|
9254
|
+
if ($s.find('hr, br, img, iframe, source').length !== 0) return;
|
7986
9255
|
var text = $.trim($s.text());
|
9256
|
+
|
7987
9257
|
if (this.utils.isEmpty(text, false))
|
7988
9258
|
{
|
7989
9259
|
$s.remove();
|
@@ -7993,8 +9263,6 @@
|
|
7993
9263
|
// save and restore scroll
|
7994
9264
|
saveScroll: function()
|
7995
9265
|
{
|
7996
|
-
if (this.utils.isSelectAll()) return;
|
7997
|
-
|
7998
9266
|
this.saveEditorScroll = this.$editor.scrollTop();
|
7999
9267
|
this.saveBodyScroll = $(window).scrollTop();
|
8000
9268
|
|
@@ -8039,6 +9307,8 @@
|
|
8039
9307
|
|
8040
9308
|
return $(this).contents();
|
8041
9309
|
});
|
9310
|
+
|
9311
|
+
return $(node);
|
8042
9312
|
},
|
8043
9313
|
replaceToTag: function(node, tag, removeInlineTags)
|
8044
9314
|
{
|
@@ -8071,22 +9341,31 @@
|
|
8071
9341
|
|
8072
9342
|
return (offset === 0) ? true : false;
|
8073
9343
|
},
|
8074
|
-
isEndOfElement: function()
|
9344
|
+
isEndOfElement: function(element)
|
8075
9345
|
{
|
8076
|
-
|
8077
|
-
|
9346
|
+
if (typeof element == 'undefined')
|
9347
|
+
{
|
9348
|
+
var element = this.selection.getBlock();
|
9349
|
+
if (!element) return false;
|
9350
|
+
}
|
8078
9351
|
|
8079
|
-
var offset = this.caret.getOffsetOfElement(
|
8080
|
-
var text = $.trim($(
|
9352
|
+
var offset = this.caret.getOffsetOfElement(element);
|
9353
|
+
var text = $.trim($(element).text()).replace(/\n\r\n/g, '');
|
8081
9354
|
|
8082
9355
|
return (offset == text.length) ? true : false;
|
8083
9356
|
},
|
9357
|
+
isStartOfEditor: function()
|
9358
|
+
{
|
9359
|
+
var offset = this.caret.getOffsetOfElement(this.$editor[0]);
|
9360
|
+
|
9361
|
+
return (offset === 0) ? true : false;
|
9362
|
+
},
|
8084
9363
|
isEndOfEditor: function()
|
8085
9364
|
{
|
8086
9365
|
var block = this.$editor[0];
|
8087
9366
|
|
8088
9367
|
var offset = this.caret.getOffsetOfElement(block);
|
8089
|
-
var text = $.trim($(block).
|
9368
|
+
var text = $.trim($(block).html().replace(/(<([^>]+)>)/gi,''));
|
8090
9369
|
|
8091
9370
|
return (offset == text.length) ? true : false;
|
8092
9371
|
},
|
@@ -8108,7 +9387,7 @@
|
|
8108
9387
|
// tag detection
|
8109
9388
|
isTag: function(current, tag)
|
8110
9389
|
{
|
8111
|
-
var element = $(current).closest(tag);
|
9390
|
+
var element = $(current).closest(tag, this.$editor[0]);
|
8112
9391
|
if (element.length == 1)
|
8113
9392
|
{
|
8114
9393
|
return element[0];
|
@@ -8209,104 +9488,62 @@
|
|
8209
9488
|
|
8210
9489
|
if (browser == 'safari') return (typeof match[3] != 'undefined') ? match[3] == 'safari' : false;
|
8211
9490
|
if (browser == 'version') return match[2];
|
8212
|
-
if (browser == 'webkit') return (match[1] == 'chrome' || match[1] == 'webkit');
|
9491
|
+
if (browser == 'webkit') return (match[1] == 'chrome' || match[1] == 'opr' || match[1] == 'webkit');
|
8213
9492
|
if (match[1] == 'rv') return browser == 'msie';
|
8214
9493
|
if (match[1] == 'opr') return browser == 'webkit';
|
8215
9494
|
|
8216
9495
|
return browser == match[1];
|
8217
|
-
}
|
8218
|
-
|
8219
|
-
|
8220
|
-
|
8221
|
-
|
8222
|
-
|
8223
|
-
|
8224
|
-
$('[data-tools="redactor"]').redactor();
|
8225
|
-
});
|
8226
|
-
|
8227
|
-
// constructor
|
8228
|
-
Redactor.prototype.init.prototype = Redactor.prototype;
|
8229
|
-
|
8230
|
-
// LINKIFY
|
8231
|
-
$.Redactor.fn.formatLinkify = function(protocol, convertLinks, convertUrlLinks, convertImageLinks, convertVideoLinks, linkSize)
|
8232
|
-
{
|
8233
|
-
var urlCheck = '((?:http[s]?:\\/\\/(?:www\\.)?|www\\.){1}(?:[0-9A-Za-z\\-%_]+\\.)+[a-zA-Z]{2,}(?::[0-9]+)?(?:(?:/[0-9A-Za-z\\-#\\.%\+_]*)+)?(?:\\?(?:[0-9A-Za-z\\-\\.%_]+(?:=[0-9A-Za-z\\-\\.%_\\+]*)?)?(?:&(?:[0-9A-Za-z\\-\\.%_]+(?:=[0-9A-Za-z\\-\\.%_\\+]*)?)?)*)?(?:#[0-9A-Za-z\\-\\.%_\\+=\\?&;]*)?)';
|
8234
|
-
var regex = new RegExp(urlCheck, 'gi');
|
8235
|
-
var rProtocol = /(https?|ftp):\/\//i;
|
8236
|
-
var urlImage = /(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/gi;
|
8237
|
-
|
8238
|
-
var childNodes = (this.$editor ? this.$editor[0] : this).childNodes, i = childNodes.length;
|
8239
|
-
while (i--)
|
8240
|
-
{
|
8241
|
-
var n = childNodes[i];
|
8242
|
-
|
8243
|
-
if (n.nodeType === 3 && n.parentNode !== 'PRE')
|
8244
|
-
{
|
8245
|
-
var html = n.nodeValue;
|
8246
|
-
|
8247
|
-
// youtube & vimeo
|
8248
|
-
if (convertVideoLinks && html)
|
9496
|
+
},
|
9497
|
+
strpos: function(haystack, needle, offset)
|
9498
|
+
{
|
9499
|
+
var i = haystack.indexOf(needle, offset);
|
9500
|
+
return i >= 0 ? i : false;
|
9501
|
+
},
|
9502
|
+
disableBodyScroll: function()
|
8249
9503
|
{
|
8250
|
-
var iframeStart = '<iframe width="500" height="281" src="',
|
8251
|
-
iframeEnd = '" frameborder="0" allowfullscreen></iframe>';
|
8252
9504
|
|
8253
|
-
|
8254
|
-
|
8255
|
-
|
8256
|
-
$(n).after(html).remove();
|
8257
|
-
}
|
8258
|
-
else if (html.match(reUrlVimeo))
|
9505
|
+
var $body = $('html');
|
9506
|
+
var windowWidth = window.innerWidth;
|
9507
|
+
if (!windowWidth)
|
8259
9508
|
{
|
8260
|
-
|
8261
|
-
|
9509
|
+
var documentElementRect = document.documentElement.getBoundingClientRect();
|
9510
|
+
windowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
|
8262
9511
|
}
|
8263
|
-
}
|
8264
9512
|
|
8265
|
-
|
8266
|
-
|
8267
|
-
{
|
8268
|
-
html = html.replace(urlImage, '<img src="$1" />');
|
9513
|
+
var isOverflowing = document.body.clientWidth < windowWidth;
|
9514
|
+
var scrollbarWidth = this.utils.measureScrollbar();
|
8269
9515
|
|
8270
|
-
$
|
8271
|
-
|
8272
|
-
}
|
9516
|
+
$body.css('overflow', 'hidden');
|
9517
|
+
if (isOverflowing) $body.css('padding-right', scrollbarWidth);
|
8273
9518
|
|
8274
|
-
// link
|
8275
|
-
if (html.search(/\$/g) != -1) html = html.replace(/\$/g, '$');
|
8276
9519
|
|
8277
|
-
|
8278
|
-
|
9520
|
+
},
|
9521
|
+
measureScrollbar: function()
|
8279
9522
|
{
|
9523
|
+
var $body = $('body');
|
9524
|
+
var scrollDiv = document.createElement('div');
|
9525
|
+
scrollDiv.className = 'redactor-scrollbar-measure';
|
8280
9526
|
|
8281
|
-
|
8282
|
-
|
8283
|
-
|
8284
|
-
|
8285
|
-
|
8286
|
-
|
8287
|
-
|
8288
|
-
|
8289
|
-
|
8290
|
-
var space = '';
|
8291
|
-
if (href.match(/\s$/) !== null) space = ' ';
|
8292
|
-
|
8293
|
-
var addProtocol = protocol + '://';
|
8294
|
-
if (href.match(rProtocol) !== null) addProtocol = '';
|
8295
|
-
|
8296
|
-
if (text.length > linkSize) text = text.substring(0, linkSize) + '...';
|
8297
|
-
text = text.replace(/$/g, '$').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
8298
|
-
|
8299
|
-
html = html.replace(href, '<a href=\"' + addProtocol + $.trim(href) + '\">' + $.trim(text) + '</a>' + space);
|
8300
|
-
}
|
8301
|
-
|
8302
|
-
$(n).after(html).remove();
|
9527
|
+
$body.append(scrollDiv);
|
9528
|
+
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
9529
|
+
$body[0].removeChild(scrollDiv);
|
9530
|
+
return scrollbarWidth;
|
9531
|
+
},
|
9532
|
+
enableBodyScroll: function()
|
9533
|
+
{
|
9534
|
+
$('html').css({ 'overflow': '', 'padding-right': '' });
|
9535
|
+
$('body').remove('redactor-scrollbar-measure');
|
8303
9536
|
}
|
8304
|
-
}
|
8305
|
-
else if (n.nodeType === 1 && !/^(pre|a|button|textarea)$/i.test(n.tagName))
|
8306
|
-
{
|
8307
|
-
$.Redactor.fn.formatLinkify.call(n, protocol, convertLinks, convertUrlLinks, convertImageLinks, convertVideoLinks, linkSize);
|
8308
|
-
}
|
9537
|
+
};
|
8309
9538
|
}
|
8310
9539
|
};
|
8311
9540
|
|
9541
|
+
$(window).on('load.tools.redactor', function()
|
9542
|
+
{
|
9543
|
+
$('[data-tools="redactor"]').redactor();
|
9544
|
+
});
|
9545
|
+
|
9546
|
+
// constructor
|
9547
|
+
Redactor.prototype.init.prototype = Redactor.prototype;
|
9548
|
+
|
8312
9549
|
})(jQuery);
|