godmin-redactor 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 746d8e6fbdef09a044815e075466dde6835d6f09
|
4
|
+
data.tar.gz: 1ead471ad25a0eb497ce86832af2ff0da436427c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5379c58b111a937492e9a4faad39859f36d1b0c17013b7d0de970b0770604895674ef9dc3a204c84711c911eefd198a5954fb35e8327fdbc03488a48931b90c1
|
7
|
+
data.tar.gz: 6ef4c885723a269d439bb7af2f260e4794182e4299d66ba51fdd2ad5773d674f13af5063941f517376dc2d8b03befc1e861eb6e48976b44143c9148464d8e2df
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 1.0.2 - 2017-11-02
|
4
|
+
Features
|
5
|
+
- Update to [Redactor version 10.2.5](http://imperavi.com/redactor/log/)
|
6
|
+
|
7
|
+
Issues
|
8
|
+
- Fixes Redactor bug with Chrome 58 (https://github.com/varvet/godmin-redactor/pull/8)
|
9
|
+
|
10
|
+
### 1.0.1 - 2016-03-10
|
11
|
+
Issues
|
12
|
+
- Multiple redactor boxes on same page (https://github.com/varvet/godmin-redactor/pull/6)
|
13
|
+
|
3
14
|
### 1.0.0 - 2016-02-01
|
4
15
|
Features
|
5
16
|
- Compatible with Godmin 1.0
|
@@ -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)
|
@@ -91,13 +92,13 @@
|
|
91
92
|
|
92
93
|
// Functionality
|
93
94
|
$.Redactor = Redactor;
|
94
|
-
$.Redactor.VERSION = '10.
|
95
|
+
$.Redactor.VERSION = '10.2.5';
|
95
96
|
$.Redactor.modules = ['alignment', 'autosave', 'block', 'buffer', 'build', 'button',
|
96
97
|
'caret', 'clean', 'code', 'core', 'dropdown', 'file', 'focus',
|
97
98
|
'image', 'indent', 'inline', 'insert', 'keydown', 'keyup',
|
98
|
-
'lang', 'line', 'link', 'list', 'modal', 'observe', 'paragraphize',
|
99
|
+
'lang', 'line', 'link', 'linkify', 'list', 'modal', 'observe', 'paragraphize',
|
99
100
|
'paste', 'placeholder', 'progress', 'selection', 'shortcuts',
|
100
|
-
'tabifier', 'tidy', 'toolbar', 'upload', 'utils'
|
101
|
+
'tabifier', 'tidy', 'toolbar', 'upload', 'utils'];
|
101
102
|
|
102
103
|
$.Redactor.opts = {
|
103
104
|
|
@@ -198,7 +199,8 @@
|
|
198
199
|
|
199
200
|
removeComments: false,
|
200
201
|
replaceTags: [
|
201
|
-
['strike', 'del']
|
202
|
+
['strike', 'del'],
|
203
|
+
['b', 'strong']
|
202
204
|
],
|
203
205
|
replaceStyles: [
|
204
206
|
['font-weight:\\s?bold', "strong"],
|
@@ -251,7 +253,10 @@
|
|
251
253
|
inlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'],
|
252
254
|
alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DL', 'DT', 'DD', 'DIV', 'TD', 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'],
|
253
255
|
blockLevelElements: ['PRE', 'UL', 'OL', 'LI'],
|
254
|
-
|
256
|
+
highContrast: false,
|
257
|
+
observe: {
|
258
|
+
dropdowns: []
|
259
|
+
},
|
255
260
|
|
256
261
|
// lang
|
257
262
|
langs: {
|
@@ -327,7 +332,6 @@
|
|
327
332
|
filename: 'Name (optional)',
|
328
333
|
edit: 'Edit',
|
329
334
|
upload_label: 'Drop file here or '
|
330
|
-
|
331
335
|
}
|
332
336
|
},
|
333
337
|
|
@@ -349,6 +353,7 @@
|
|
349
353
|
keyCode: {
|
350
354
|
BACKSPACE: 8,
|
351
355
|
DELETE: 46,
|
356
|
+
UP: 38,
|
352
357
|
DOWN: 40,
|
353
358
|
ENTER: 13,
|
354
359
|
SPACE: 32,
|
@@ -450,7 +455,6 @@
|
|
450
455
|
this[module][methods[z]] = this[module][methods[z]].bind(this);
|
451
456
|
}
|
452
457
|
},
|
453
|
-
|
454
458
|
alignment: function()
|
455
459
|
{
|
456
460
|
return {
|
@@ -473,15 +477,18 @@
|
|
473
477
|
set: function(type)
|
474
478
|
{
|
475
479
|
// focus
|
476
|
-
if (!this.utils.browser('msie')
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
481
|
+
{
|
482
|
+
this.$editor.focus();
|
483
|
+
}
|
480
484
|
|
481
485
|
// get blocks
|
482
486
|
this.alignment.blocks = this.selection.getBlocks();
|
483
487
|
this.alignment.type = type;
|
484
488
|
|
489
|
+
this.buffer.set();
|
490
|
+
this.selection.save();
|
491
|
+
|
485
492
|
// set alignment
|
486
493
|
if (this.alignment.isLinebreaksOrNoBlocks())
|
487
494
|
{
|
@@ -558,10 +565,11 @@
|
|
558
565
|
},
|
559
566
|
load: function()
|
560
567
|
{
|
568
|
+
if (!this.opts.autosave) return;
|
569
|
+
|
561
570
|
this.autosave.source = this.code.get();
|
562
571
|
|
563
572
|
if (this.autosave.html === this.autosave.source) return;
|
564
|
-
//if (this.utils.isEmpty(this.autosave.source)) return;
|
565
573
|
|
566
574
|
// data
|
567
575
|
var data = {};
|
@@ -653,6 +661,23 @@
|
|
653
661
|
// focus
|
654
662
|
if (!this.utils.browser('msie')) this.$editor.focus();
|
655
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
|
+
|
656
681
|
this.block.blocks = this.selection.getBlocks();
|
657
682
|
|
658
683
|
this.block.blocksSize = this.block.blocks.length;
|
@@ -666,10 +691,12 @@
|
|
666
691
|
|
667
692
|
this.selection.restore();
|
668
693
|
this.code.sync();
|
694
|
+
this.observe.load();
|
669
695
|
|
670
696
|
},
|
671
697
|
set: function(tag)
|
672
698
|
{
|
699
|
+
|
673
700
|
this.selection.get();
|
674
701
|
this.block.containerTag = this.range.commonAncestorContainer.tagName;
|
675
702
|
|
@@ -684,6 +711,15 @@
|
|
684
711
|
},
|
685
712
|
setCollapsed: function(tag)
|
686
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
|
+
|
687
723
|
var block = this.block.blocks[0];
|
688
724
|
if (block === false) return;
|
689
725
|
|
@@ -698,7 +734,6 @@
|
|
698
734
|
var isContainerTable = (this.block.containerTag == 'TD' || this.block.containerTag == 'TH');
|
699
735
|
if (isContainerTable && !this.opts.linebreaks)
|
700
736
|
{
|
701
|
-
|
702
737
|
document.execCommand('formatblock', false, '<' + tag + '>');
|
703
738
|
|
704
739
|
block = this.selection.getBlock();
|
@@ -709,7 +744,7 @@
|
|
709
744
|
{
|
710
745
|
if (this.opts.linebreaks && tag == 'p')
|
711
746
|
{
|
712
|
-
$(block).
|
747
|
+
$(block).append('<br>');
|
713
748
|
this.utils.replaceWithContents(block);
|
714
749
|
}
|
715
750
|
else
|
@@ -730,7 +765,7 @@
|
|
730
765
|
// blockquote off
|
731
766
|
if (this.opts.linebreaks)
|
732
767
|
{
|
733
|
-
$(block).
|
768
|
+
$(block).append('<br>');
|
734
769
|
this.utils.replaceWithContents(block);
|
735
770
|
}
|
736
771
|
else
|
@@ -744,15 +779,16 @@
|
|
744
779
|
this.block.toggle($(block));
|
745
780
|
}
|
746
781
|
|
782
|
+
|
747
783
|
if (typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
|
748
784
|
{
|
749
785
|
$(block).removeAttr('class').removeAttr('style');
|
750
786
|
}
|
751
|
-
|
752
787
|
},
|
753
788
|
setMultiple: function(tag)
|
754
789
|
{
|
755
790
|
var block = this.block.blocks[0];
|
791
|
+
|
756
792
|
var isContainerTable = (this.block.containerTag == 'TD' || this.block.containerTag == 'TH');
|
757
793
|
|
758
794
|
if (block !== false && this.block.blocksSize === 1)
|
@@ -762,7 +798,7 @@
|
|
762
798
|
// blockquote off
|
763
799
|
if (this.opts.linebreaks)
|
764
800
|
{
|
765
|
-
$(block).
|
801
|
+
$(block).append('<br>');
|
766
802
|
this.utils.replaceWithContents(block);
|
767
803
|
}
|
768
804
|
else
|
@@ -809,7 +845,6 @@
|
|
809
845
|
}
|
810
846
|
else
|
811
847
|
{
|
812
|
-
|
813
848
|
if (this.opts.linebreaks || tag != 'p')
|
814
849
|
{
|
815
850
|
if (tag == 'blockquote')
|
@@ -848,7 +883,6 @@
|
|
848
883
|
|
849
884
|
}
|
850
885
|
|
851
|
-
|
852
886
|
this.block.formatWrap(tag);
|
853
887
|
}
|
854
888
|
else
|
@@ -1011,11 +1045,6 @@
|
|
1011
1045
|
|
1012
1046
|
var $elements = $formatted.find(this.opts.blockLevelElements.join(',') + ', td, table, thead, tbody, tfoot, th, tr');
|
1013
1047
|
|
1014
|
-
if ((this.opts.linebreaks && tag == 'p') || tag == 'pre' || tag == 'blockquote')
|
1015
|
-
{
|
1016
|
-
$elements.append('<br />');
|
1017
|
-
}
|
1018
|
-
|
1019
1048
|
$elements.contents().unwrap();
|
1020
1049
|
|
1021
1050
|
if (tag != 'p' && tag != 'blockquote') $formatted.find('img').remove();
|
@@ -1042,6 +1071,17 @@
|
|
1042
1071
|
this.utils.replaceWithContents($formatted);
|
1043
1072
|
}
|
1044
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
|
+
|
1045
1085
|
},
|
1046
1086
|
formatTableWrapping: function($formatted)
|
1047
1087
|
{
|
@@ -1201,6 +1241,8 @@
|
|
1201
1241
|
build: function()
|
1202
1242
|
{
|
1203
1243
|
return {
|
1244
|
+
focused: false,
|
1245
|
+
blured: true,
|
1204
1246
|
run: function()
|
1205
1247
|
{
|
1206
1248
|
this.build.createContainerBox();
|
@@ -1215,7 +1257,7 @@
|
|
1215
1257
|
},
|
1216
1258
|
createContainerBox: function()
|
1217
1259
|
{
|
1218
|
-
this.$box = $('<div class="redactor-box" />');
|
1260
|
+
this.$box = $('<div class="redactor-box" role="application" />');
|
1219
1261
|
},
|
1220
1262
|
createTextarea: function()
|
1221
1263
|
{
|
@@ -1272,6 +1314,7 @@
|
|
1272
1314
|
callEditor: function()
|
1273
1315
|
{
|
1274
1316
|
this.build.disableMozillaEditing();
|
1317
|
+
this.build.disableIeLinks();
|
1275
1318
|
this.build.setEvents();
|
1276
1319
|
this.build.setHelpers();
|
1277
1320
|
|
@@ -1311,7 +1354,8 @@
|
|
1311
1354
|
{
|
1312
1355
|
e.preventDefault();
|
1313
1356
|
|
1314
|
-
if (!this.opts.dragImageUpload
|
1357
|
+
if (!this.opts.dragImageUpload && !this.opts.dragFileUpload) return;
|
1358
|
+
if (this.opts.imageUpload === null && this.opts.fileUpload === null) return;
|
1315
1359
|
|
1316
1360
|
var files = e.dataTransfer.files;
|
1317
1361
|
this.upload.directUpload(files[0], e);
|
@@ -1325,6 +1369,12 @@
|
|
1325
1369
|
setEvents: function()
|
1326
1370
|
{
|
1327
1371
|
// drop
|
1372
|
+
this.$editor.on('dragover.redactor dragenter.redactor', function(e)
|
1373
|
+
{
|
1374
|
+
e.preventDefault();
|
1375
|
+
e.stopPropagation();
|
1376
|
+
});
|
1377
|
+
|
1328
1378
|
this.$editor.on('drop.redactor', $.proxy(function(e)
|
1329
1379
|
{
|
1330
1380
|
e = e.originalEvent || e;
|
@@ -1383,30 +1433,50 @@
|
|
1383
1433
|
}
|
1384
1434
|
|
1385
1435
|
// focus
|
1386
|
-
|
1436
|
+
this.$editor.on('focus.redactor', $.proxy(function(e)
|
1387
1437
|
{
|
1388
|
-
|
1389
|
-
|
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));
|
1390
1456
|
|
1391
|
-
var clickedElement;
|
1392
|
-
$(document).on('mousedown', function(e) { clickedElement = e.target; });
|
1393
1457
|
|
1394
1458
|
// blur
|
1395
|
-
|
1459
|
+
$(document).on('mousedown.redactor-blur.' + this.uuid, $.proxy(function(e)
|
1396
1460
|
{
|
1461
|
+
if (this.start) return;
|
1397
1462
|
if (this.rtePaste) return;
|
1398
|
-
|
1463
|
+
|
1464
|
+
if ($(e.target).closest('.redactor-editor, .redactor-toolbar, .redactor-dropdown').size() !== 0)
|
1465
|
+
{
|
1466
|
+
return;
|
1467
|
+
}
|
1399
1468
|
|
1400
1469
|
this.utils.disableSelectAll();
|
1401
|
-
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;
|
1402
1477
|
|
1403
1478
|
}, this));
|
1404
|
-
},
|
1405
|
-
isBlured: function(clickedElement)
|
1406
|
-
{
|
1407
|
-
var $el = $(clickedElement);
|
1408
1479
|
|
1409
|
-
return (!$el.hasClass('redactor-toolbar, redactor-dropdown') && !$el.is('#redactor-modal') && $el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').length === 0);
|
1410
1480
|
},
|
1411
1481
|
setHelpers: function()
|
1412
1482
|
{
|
@@ -1427,21 +1497,17 @@
|
|
1427
1497
|
plugins: function()
|
1428
1498
|
{
|
1429
1499
|
if (!this.opts.plugins) return;
|
1430
|
-
if (!RedactorPlugins) return;
|
1431
1500
|
|
1432
1501
|
$.each(this.opts.plugins, $.proxy(function(i, s)
|
1433
1502
|
{
|
1434
|
-
|
1503
|
+
var func = (typeof RedactorPlugins !== 'undefined' && typeof RedactorPlugins[s] !== 'undefined') ? RedactorPlugins : Redactor.fn;
|
1435
1504
|
|
1436
|
-
if (
|
1505
|
+
if (!$.isFunction(func[s]))
|
1437
1506
|
{
|
1438
|
-
$.error('Plugin name "' + s + '" matches the name of the Redactor\'s module.');
|
1439
1507
|
return;
|
1440
1508
|
}
|
1441
1509
|
|
1442
|
-
|
1443
|
-
|
1444
|
-
this[s] = RedactorPlugins[s]();
|
1510
|
+
this[s] = func[s]();
|
1445
1511
|
|
1446
1512
|
// get methods
|
1447
1513
|
var methods = this.getModuleMethods(this[s]);
|
@@ -1453,7 +1519,10 @@
|
|
1453
1519
|
this[s][methods[z]] = this[s][methods[z]].bind(this);
|
1454
1520
|
}
|
1455
1521
|
|
1456
|
-
if ($.isFunction(this[s].init))
|
1522
|
+
if ($.isFunction(this[s].init))
|
1523
|
+
{
|
1524
|
+
this[s].init();
|
1525
|
+
}
|
1457
1526
|
|
1458
1527
|
|
1459
1528
|
}, this));
|
@@ -1468,6 +1537,13 @@
|
|
1468
1537
|
document.execCommand('enableObjectResizing', false, false);
|
1469
1538
|
document.execCommand('enableInlineTableEditing', false, false);
|
1470
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);
|
1471
1547
|
}
|
1472
1548
|
};
|
1473
1549
|
},
|
@@ -1476,7 +1552,7 @@
|
|
1476
1552
|
return {
|
1477
1553
|
build: function(btnName, btnObject)
|
1478
1554
|
{
|
1479
|
-
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'});
|
1480
1556
|
|
1481
1557
|
// click
|
1482
1558
|
if (btnObject.func || btnObject.command || btnObject.dropdown)
|
@@ -1487,6 +1563,8 @@
|
|
1487
1563
|
// dropdown
|
1488
1564
|
if (btnObject.dropdown)
|
1489
1565
|
{
|
1566
|
+
$button.addClass('redactor-toolbar-link-dropdown').attr('aria-haspopup', true);
|
1567
|
+
|
1490
1568
|
var $dropdown = $('<div class="redactor-dropdown redactor-dropdown-' + this.uuid + ' redactor-dropdown-box-' + btnName + '" style="display: none;">');
|
1491
1569
|
$button.data('dropdown', $dropdown);
|
1492
1570
|
this.dropdown.build(btnName, $dropdown, btnObject.dropdown);
|
@@ -1526,20 +1604,24 @@
|
|
1526
1604
|
},
|
1527
1605
|
createTooltip: function($button, name, title)
|
1528
1606
|
{
|
1529
|
-
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);
|
1530
1608
|
$tooltip.appendTo('body');
|
1531
1609
|
|
1532
1610
|
$button.on('mouseover', function()
|
1533
1611
|
{
|
1534
|
-
if ($(this).hasClass('redactor-button-disabled'))
|
1612
|
+
if ($(this).hasClass('redactor-button-disabled'))
|
1613
|
+
{
|
1614
|
+
return;
|
1615
|
+
}
|
1535
1616
|
|
1536
1617
|
var pos = $button.offset();
|
1537
1618
|
|
1538
|
-
$tooltip.show();
|
1539
1619
|
$tooltip.css({
|
1540
1620
|
top: (pos.top + $button.innerHeight()) + 'px',
|
1541
1621
|
left: (pos.left + $button.innerWidth()/2 - $tooltip.innerWidth()/2) + 'px'
|
1542
1622
|
});
|
1623
|
+
$tooltip.show();
|
1624
|
+
|
1543
1625
|
});
|
1544
1626
|
|
1545
1627
|
$button.on('mouseout', function()
|
@@ -1554,6 +1636,8 @@
|
|
1554
1636
|
|
1555
1637
|
e.preventDefault();
|
1556
1638
|
|
1639
|
+
$(document).find('.redactor-toolbar-tooltip').hide();
|
1640
|
+
|
1557
1641
|
if (this.utils.browser('msie')) e.returnValue = false;
|
1558
1642
|
|
1559
1643
|
if (type == 'command') this.inline.format(callback);
|
@@ -1601,11 +1685,11 @@
|
|
1601
1685
|
},
|
1602
1686
|
setActiveInVisual: function()
|
1603
1687
|
{
|
1604
|
-
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');
|
1605
1689
|
},
|
1606
1690
|
setInactiveInCode: function()
|
1607
1691
|
{
|
1608
|
-
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');
|
1609
1693
|
},
|
1610
1694
|
changeIcon: function(key, classname)
|
1611
1695
|
{
|
@@ -1623,6 +1707,8 @@
|
|
1623
1707
|
},
|
1624
1708
|
addCallback: function($btn, callback)
|
1625
1709
|
{
|
1710
|
+
if ($btn == "buffer") return;
|
1711
|
+
|
1626
1712
|
var type = (callback == 'dropdown') ? 'dropdown' : 'func';
|
1627
1713
|
var key = $btn.attr('rel');
|
1628
1714
|
$btn.on('touchstart click', $.proxy(function(e)
|
@@ -1634,6 +1720,8 @@
|
|
1634
1720
|
},
|
1635
1721
|
addDropdown: function($btn, dropdown)
|
1636
1722
|
{
|
1723
|
+
$btn.addClass('redactor-toolbar-link-dropdown').attr('aria-haspopup', true);
|
1724
|
+
|
1637
1725
|
var key = $btn.attr('rel');
|
1638
1726
|
this.button.addCallback($btn, 'dropdown');
|
1639
1727
|
|
@@ -1649,6 +1737,8 @@
|
|
1649
1737
|
{
|
1650
1738
|
if (!this.opts.toolbar) return;
|
1651
1739
|
|
1740
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1741
|
+
|
1652
1742
|
var btn = this.button.build(key, { title: title });
|
1653
1743
|
btn.addClass('redactor-btn-image');
|
1654
1744
|
|
@@ -1660,6 +1750,8 @@
|
|
1660
1750
|
{
|
1661
1751
|
if (!this.opts.toolbar) return;
|
1662
1752
|
|
1753
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1754
|
+
|
1663
1755
|
var btn = this.button.build(key, { title: title });
|
1664
1756
|
btn.addClass('redactor-btn-image');
|
1665
1757
|
this.$toolbar.prepend($('<li>').append(btn));
|
@@ -1670,6 +1762,8 @@
|
|
1670
1762
|
{
|
1671
1763
|
if (!this.opts.toolbar) return;
|
1672
1764
|
|
1765
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1766
|
+
|
1673
1767
|
var btn = this.button.build(key, { title: title });
|
1674
1768
|
btn.addClass('redactor-btn-image');
|
1675
1769
|
var $btn = this.button.get(afterkey);
|
@@ -1683,6 +1777,8 @@
|
|
1683
1777
|
{
|
1684
1778
|
if (!this.opts.toolbar) return;
|
1685
1779
|
|
1780
|
+
if (this.button.isMobileUndoRedo(key)) return "buffer";
|
1781
|
+
|
1686
1782
|
var btn = this.button.build(key, { title: title });
|
1687
1783
|
btn.addClass('redactor-btn-image');
|
1688
1784
|
var $btn = this.button.get(beforekey);
|
@@ -1695,6 +1791,10 @@
|
|
1695
1791
|
remove: function(key)
|
1696
1792
|
{
|
1697
1793
|
this.button.get(key).remove();
|
1794
|
+
},
|
1795
|
+
isMobileUndoRedo: function(key)
|
1796
|
+
{
|
1797
|
+
return (key == "undo" || key == "redo") && !this.utils.isDesktop();
|
1698
1798
|
}
|
1699
1799
|
};
|
1700
1800
|
},
|
@@ -1718,7 +1818,14 @@
|
|
1718
1818
|
},
|
1719
1819
|
setEnd: function(node)
|
1720
1820
|
{
|
1821
|
+
node = node[0] || node;
|
1822
|
+
if (node.lastChild.nodeType == 1)
|
1823
|
+
{
|
1824
|
+
return this.caret.setAfter(node.lastChild);
|
1825
|
+
}
|
1826
|
+
|
1721
1827
|
this.caret.set(node, 1, node, 1);
|
1828
|
+
|
1722
1829
|
},
|
1723
1830
|
set: function(orgn, orgo, focn, foco)
|
1724
1831
|
{
|
@@ -1912,7 +2019,7 @@
|
|
1912
2019
|
// replace special characters in links
|
1913
2020
|
html = html.replace(/<a href="(.*?[^>]?)®(.*?[^>]?)">/gi, '<a href="$1®$2">');
|
1914
2021
|
|
1915
|
-
if (this.opts.replaceDivs) html = this.clean.replaceDivs(html);
|
2022
|
+
if (this.opts.replaceDivs && !this.opts.linebreaks) html = this.clean.replaceDivs(html);
|
1916
2023
|
if (this.opts.linebreaks) html = this.clean.replaceParagraphsToBr(html);
|
1917
2024
|
|
1918
2025
|
// save form tag
|
@@ -1933,10 +2040,11 @@
|
|
1933
2040
|
|
1934
2041
|
html = $div.html();
|
1935
2042
|
}
|
2043
|
+
|
1936
2044
|
$div.remove();
|
1937
2045
|
|
1938
2046
|
// remove font tag
|
1939
|
-
html = html.replace(/<font(.*?
|
2047
|
+
html = html.replace(/<font(.*?)>/gi, '');
|
1940
2048
|
html = html.replace(/<\/font>/gi, '');
|
1941
2049
|
|
1942
2050
|
// tidy html
|
@@ -1951,12 +2059,14 @@
|
|
1951
2059
|
// convert inline tags
|
1952
2060
|
html = this.clean.convertInline(html);
|
1953
2061
|
|
2062
|
+
html = html.replace(/&/g, '&');
|
2063
|
+
|
1954
2064
|
return html;
|
1955
2065
|
},
|
1956
2066
|
onSync: function(html)
|
1957
2067
|
{
|
1958
2068
|
// remove spaces
|
1959
|
-
html = html.replace(
|
2069
|
+
html = html.replace(/\u200B/g, '');
|
1960
2070
|
html = html.replace(/​/gi, '');
|
1961
2071
|
|
1962
2072
|
if (this.opts.cleanSpaces)
|
@@ -1988,17 +2098,41 @@
|
|
1988
2098
|
html = html.replace(new RegExp(i, 'g'), s);
|
1989
2099
|
});
|
1990
2100
|
|
1991
|
-
// 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
|
1992
2108
|
html = html.replace(new RegExp('<br\\s?/?></li>', 'gi'), '</li>');
|
1993
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
|
+
|
1994
2118
|
// remove verified
|
1995
|
-
html = html.replace(/<div(.*?
|
2119
|
+
html = html.replace(/<div(.*?)data-tagblock="redactor"(.*?[^>])>/gi, '<div$1$2>');
|
1996
2120
|
html = html.replace(/<(.*?) data-verified="redactor"(.*?[^>])>/gi, '<$1$2>');
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
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>');
|
2001
2134
|
html = html.replace(/<span class="redactor-invisible-space">(.*?)<\/span>/gi, '$1');
|
2135
|
+
|
2002
2136
|
html = html.replace(/ data-save-url="(.*?[^>])"/gi, '');
|
2003
2137
|
|
2004
2138
|
// remove image resize
|
@@ -2007,7 +2141,7 @@
|
|
2007
2141
|
html = html.replace(/<span(.*?)id="redactor-image-editter"(.*?[^>])>(.*?)<\/span>/gi, '');
|
2008
2142
|
|
2009
2143
|
// remove font tag
|
2010
|
-
html = html.replace(/<font(.*?
|
2144
|
+
html = html.replace(/<font(.*?)>/gi, '');
|
2011
2145
|
html = html.replace(/<\/font>/gi, '');
|
2012
2146
|
|
2013
2147
|
// tidy html
|
@@ -2025,16 +2159,17 @@
|
|
2025
2159
|
html = html.replace(new RegExp('<(.*?) data-verified="redactor"(.*?[^>])>', 'gi'), '<$1$2>');
|
2026
2160
|
html = html.replace(new RegExp('<(.*?) data-verified="redactor">', 'gi'), '<$1>');
|
2027
2161
|
|
2162
|
+
html = html.replace(/&/g, '&');
|
2163
|
+
|
2028
2164
|
return html;
|
2029
2165
|
},
|
2030
2166
|
onPaste: function(html, setMode)
|
2031
2167
|
{
|
2032
2168
|
html = $.trim(html);
|
2033
|
-
|
2034
2169
|
html = html.replace(/\$/g, '$');
|
2035
2170
|
|
2036
2171
|
// convert dirty spaces
|
2037
|
-
html = html.replace(/<span class="
|
2172
|
+
html = html.replace(/<span class="s[0-9]">/gi, '<span>');
|
2038
2173
|
html = html.replace(/<span class="Apple-converted-space"> <\/span>/gi, ' ');
|
2039
2174
|
html = html.replace(/<span class="Apple-tab-span"[^>]*>\t<\/span>/gi, '\t');
|
2040
2175
|
html = html.replace(/<span[^>]*>(\s| )<\/span>/gi, ' ');
|
@@ -2136,20 +2271,108 @@
|
|
2136
2271
|
// style
|
2137
2272
|
html = html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
|
2138
2273
|
|
2139
|
-
|
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))
|
2140
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
|
+
|
2141
2297
|
html = this.clean.onPasteIeFixLinks(html);
|
2142
2298
|
|
2143
2299
|
// shapes
|
2144
2300
|
html = html.replace(/<img(.*?)v:shapes=(.*?)>/gi, '');
|
2145
2301
|
html = html.replace(/src="file\:\/\/(.*?)"/, 'src=""');
|
2146
2302
|
|
2147
|
-
//
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
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
|
+
|
2153
2376
|
// remove ms word's bullet
|
2154
2377
|
html = html.replace(/·/g, '');
|
2155
2378
|
html = html.replace(/<p class="Mso(.*?)"/gi, '<p');
|
@@ -2168,12 +2391,6 @@
|
|
2168
2391
|
html = html.replace(/<p>\n?<li>/gi, '<li>');
|
2169
2392
|
}
|
2170
2393
|
|
2171
|
-
// remove nbsp
|
2172
|
-
if (this.opts.cleanSpaces)
|
2173
|
-
{
|
2174
|
-
html = html.replace(/(\s| )+/g, ' ');
|
2175
|
-
}
|
2176
|
-
|
2177
2394
|
return html;
|
2178
2395
|
},
|
2179
2396
|
onPasteExtra: function(html)
|
@@ -2321,8 +2538,8 @@
|
|
2321
2538
|
if (!matchBlocks && (matchContainers === null || (matchContainers && matchContainers.length <= 1)))
|
2322
2539
|
{
|
2323
2540
|
var matchBR = html.match(/<br\s?\/?>/gi);
|
2324
|
-
var matchIMG = html.match(/<img(.*?[^>])>/gi);
|
2325
|
-
if (!matchBR
|
2541
|
+
//var matchIMG = html.match(/<img(.*?[^>])>/gi);
|
2542
|
+
if (!matchBR)
|
2326
2543
|
{
|
2327
2544
|
this.clean.singleLine = true;
|
2328
2545
|
html = html.replace(/<\/?(p|div)(.*?)>/gi, '');
|
@@ -2346,11 +2563,14 @@
|
|
2346
2563
|
html = this.clean.savePreFormatting(html);
|
2347
2564
|
html = this.clean.saveCodeFormatting(html);
|
2348
2565
|
|
2566
|
+
html = this.clean.restoreSelectionMarker(html);
|
2567
|
+
|
2349
2568
|
return html;
|
2350
2569
|
},
|
2351
2570
|
savePreFormatting: function(html)
|
2352
2571
|
{
|
2353
2572
|
var pre = html.match(/<pre(.*?)>([\w\W]*?)<\/pre>/gi);
|
2573
|
+
|
2354
2574
|
if (pre !== null)
|
2355
2575
|
{
|
2356
2576
|
$.each(pre, $.proxy(function(i,s)
|
@@ -2379,26 +2599,30 @@
|
|
2379
2599
|
},
|
2380
2600
|
saveCodeFormatting: function(html)
|
2381
2601
|
{
|
2382
|
-
var code = html.match(/<code(.*?
|
2602
|
+
var code = html.match(/<code(.*?)>([\w\W]*?)<\/code>/gi);
|
2603
|
+
|
2383
2604
|
if (code !== null)
|
2384
2605
|
{
|
2385
2606
|
$.each(code, $.proxy(function(i,s)
|
2386
2607
|
{
|
2387
|
-
var arr = s.match(/<code(.*?
|
2608
|
+
var arr = s.match(/<code(.*?)>([\w\W]*?)<\/code>/i);
|
2388
2609
|
|
2389
2610
|
arr[2] = arr[2].replace(/ /g, ' ');
|
2390
2611
|
arr[2] = this.clean.encodeEntities(arr[2]);
|
2391
|
-
|
2392
|
-
// $ fix
|
2393
2612
|
arr[2] = arr[2].replace(/\$/g, '$');
|
2394
2613
|
|
2395
2614
|
html = html.replace(s, '<code' + arr[1] + '>' + arr[2] + '</code>');
|
2396
|
-
|
2397
2615
|
}, this));
|
2398
2616
|
}
|
2399
2617
|
|
2400
2618
|
return html;
|
2401
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
|
+
},
|
2402
2626
|
getTextFromHtml: function(html)
|
2403
2627
|
{
|
2404
2628
|
html = html.replace(/<br\s?\/?>|<\/H[1-6]>|<\/p>|<\/div>|<\/li>|<\/td>/gi, '\n');
|
@@ -2412,6 +2636,8 @@
|
|
2412
2636
|
getPlainText: function(html, paragraphize)
|
2413
2637
|
{
|
2414
2638
|
html = this.clean.getTextFromHtml(html);
|
2639
|
+
html = html.replace(/\n\s*\n/g, "\n");
|
2640
|
+
html = html.replace(/\n\n/g, "\n");
|
2415
2641
|
html = html.replace(/\n/g, '<br />');
|
2416
2642
|
|
2417
2643
|
if (this.opts.paragraphize && typeof paragraphize == 'undefined' && !this.utils.browser('mozilla'))
|
@@ -2505,12 +2731,7 @@
|
|
2505
2731
|
},
|
2506
2732
|
cleanEmptyParagraph: function()
|
2507
2733
|
{
|
2508
|
-
var p = this.$editor.find("p").first();
|
2509
2734
|
|
2510
|
-
if (this.utils.isEmpty(p.html()))
|
2511
|
-
{
|
2512
|
-
p.remove();
|
2513
|
-
}
|
2514
2735
|
},
|
2515
2736
|
setVerified: function(html)
|
2516
2737
|
{
|
@@ -2585,7 +2806,7 @@
|
|
2585
2806
|
html = html.replace(/[\s\n]*$/g, ' ');
|
2586
2807
|
html = html.replace( />\s{2,}</g, '> <'); // between inline tags can be only one space
|
2587
2808
|
html = html.replace(/\n\n/g, "\n");
|
2588
|
-
html = html.replace(
|
2809
|
+
html = html.replace(/\u200B/g, '');
|
2589
2810
|
|
2590
2811
|
return html;
|
2591
2812
|
},
|
@@ -2643,6 +2864,12 @@
|
|
2643
2864
|
// clean
|
2644
2865
|
html = this.clean.onSet(html);
|
2645
2866
|
|
2867
|
+
|
2868
|
+
if (this.utils.browser('msie'))
|
2869
|
+
{
|
2870
|
+
html = html.replace(/<span(.*?)id="selection-marker-(1|2)"(.*?)><\/span>/gi, '');
|
2871
|
+
}
|
2872
|
+
|
2646
2873
|
this.$editor.html(html);
|
2647
2874
|
this.code.sync();
|
2648
2875
|
|
@@ -2656,6 +2883,9 @@
|
|
2656
2883
|
{
|
2657
2884
|
var code = this.$textarea.val();
|
2658
2885
|
|
2886
|
+
if (this.opts.replaceDivs) code = this.clean.replaceDivs(code);
|
2887
|
+
if (this.opts.linebreaks) code = this.clean.replaceParagraphsToBr(code);
|
2888
|
+
|
2659
2889
|
// indent code
|
2660
2890
|
code = this.tabifier.get(code);
|
2661
2891
|
|
@@ -2670,7 +2900,7 @@
|
|
2670
2900
|
var html = this.$editor.html();
|
2671
2901
|
|
2672
2902
|
// is there a need to synchronize
|
2673
|
-
if (this.code.syncCode && this.code.syncCode == html)
|
2903
|
+
if (this.code.syncCode && this.code.syncCode == html || (this.start && html == '' ))
|
2674
2904
|
{
|
2675
2905
|
// do not sync
|
2676
2906
|
return;
|
@@ -2728,6 +2958,8 @@
|
|
2728
2958
|
},
|
2729
2959
|
showCode: function()
|
2730
2960
|
{
|
2961
|
+
this.selection.save();
|
2962
|
+
|
2731
2963
|
this.code.offset = this.caret.getOffset();
|
2732
2964
|
var scroll = $(window).scrollTop();
|
2733
2965
|
|
@@ -2737,11 +2969,34 @@
|
|
2737
2969
|
this.$editor.hide();
|
2738
2970
|
|
2739
2971
|
var html = this.$textarea.val();
|
2972
|
+
|
2740
2973
|
this.modified = this.clean.removeSpaces(html);
|
2741
2974
|
|
2742
2975
|
// indent code
|
2743
2976
|
html = this.tabifier.get(html);
|
2744
2977
|
|
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");
|
2982
|
+
|
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();
|
2745
3000
|
this.$textarea.val(html);
|
2746
3001
|
|
2747
3002
|
if (this.opts.codemirror)
|
@@ -2750,8 +3005,21 @@
|
|
2750
3005
|
{
|
2751
3006
|
$(el).show();
|
2752
3007
|
el.CodeMirror.setValue(html);
|
2753
|
-
el.CodeMirror.setSize(
|
3008
|
+
el.CodeMirror.setSize('100%', height);
|
2754
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
|
+
|
2755
3023
|
el.CodeMirror.focus();
|
2756
3024
|
});
|
2757
3025
|
}
|
@@ -2764,7 +3032,7 @@
|
|
2764
3032
|
|
2765
3033
|
if (this.$textarea[0].setSelectionRange)
|
2766
3034
|
{
|
2767
|
-
this.$textarea[0].setSelectionRange(
|
3035
|
+
this.$textarea[0].setSelectionRange(start, end);
|
2768
3036
|
}
|
2769
3037
|
|
2770
3038
|
this.$textarea[0].scrollTop = 0;
|
@@ -2782,21 +3050,58 @@
|
|
2782
3050
|
|
2783
3051
|
if (this.opts.visual) return;
|
2784
3052
|
|
3053
|
+
var start = 0, end = 0;
|
3054
|
+
|
2785
3055
|
if (this.opts.codemirror)
|
2786
3056
|
{
|
3057
|
+
var selection;
|
3058
|
+
|
2787
3059
|
this.$textarea.next('.CodeMirror').each(function(i, el)
|
2788
3060
|
{
|
3061
|
+
selection = el.CodeMirror.listSelections();
|
3062
|
+
|
3063
|
+
start = el.CodeMirror.indexFromPos(selection[0].anchor);
|
3064
|
+
end = el.CodeMirror.indexFromPos(selection[0].head);
|
3065
|
+
|
2789
3066
|
html = el.CodeMirror.getValue();
|
2790
3067
|
});
|
2791
3068
|
}
|
2792
3069
|
else
|
2793
3070
|
{
|
3071
|
+
start = this.$textarea.get(0).selectionStart;
|
3072
|
+
end = this.$textarea.get(0).selectionEnd;
|
3073
|
+
|
2794
3074
|
html = this.$textarea.hide().val();
|
2795
3075
|
}
|
2796
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
|
+
|
3100
|
+
|
2797
3101
|
if (this.modified !== this.clean.removeSpaces(html))
|
2798
3102
|
{
|
2799
3103
|
this.code.set(html);
|
3104
|
+
|
2800
3105
|
}
|
2801
3106
|
|
2802
3107
|
if (this.opts.codemirror)
|
@@ -2811,13 +3116,12 @@
|
|
2811
3116
|
this.placeholder.remove();
|
2812
3117
|
}
|
2813
3118
|
|
2814
|
-
this.
|
3119
|
+
this.selection.restore();
|
2815
3120
|
|
2816
3121
|
this.$textarea.off('keydown.redactor-textarea-indenting');
|
2817
3122
|
|
2818
3123
|
this.button.setActiveInVisual();
|
2819
3124
|
this.button.setInactive('html');
|
2820
|
-
|
2821
3125
|
this.observe.load();
|
2822
3126
|
this.opts.visual = true;
|
2823
3127
|
this.core.setCallback('visual', html);
|
@@ -2832,6 +3136,35 @@
|
|
2832
3136
|
$el.get(0).selectionStart = $el.get(0).selectionEnd = start + 1;
|
2833
3137
|
|
2834
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;
|
2835
3168
|
}
|
2836
3169
|
};
|
2837
3170
|
},
|
@@ -2872,24 +3205,52 @@
|
|
2872
3205
|
},
|
2873
3206
|
setCallback: function(type, e, data)
|
2874
3207
|
{
|
2875
|
-
var
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
else
|
3208
|
+
var eventName = type + 'Callback';
|
3209
|
+
var eventNamespace = 'redactor';
|
3210
|
+
var callback = this.opts[eventName];
|
3211
|
+
|
3212
|
+
if (this.$textarea)
|
2881
3213
|
{
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
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
|
+
|
3233
|
+
if ($.isFunction(callback))
|
3234
|
+
{
|
3235
|
+
return (typeof data == 'undefined') ? callback.call(this, e) : callback.call(this, e, data);
|
3236
|
+
}
|
3237
|
+
else
|
3238
|
+
{
|
3239
|
+
return (typeof data == 'undefined') ? e : data;
|
3240
|
+
}
|
3241
|
+
},
|
3242
|
+
destroy: function()
|
3243
|
+
{
|
3244
|
+
this.opts.destroyed = true;
|
3245
|
+
|
2887
3246
|
this.core.setCallback('destroy');
|
2888
3247
|
|
2889
3248
|
// off events and remove data
|
2890
3249
|
this.$element.off('.redactor').removeData('redactor');
|
2891
3250
|
this.$editor.off('.redactor');
|
2892
3251
|
|
3252
|
+
$(document).off('mousedown.redactor-blur.' + this.uuid);
|
3253
|
+
$(document).off('mousedown.redactor.' + this.uuid);
|
2893
3254
|
$(document).off('click.redactor-image-delete.' + this.uuid);
|
2894
3255
|
$(document).off('click.redactor-image-resize-hide.' + this.uuid);
|
2895
3256
|
$(document).off('touchstart.redactor.' + this.uuid + ' click.redactor.' + this.uuid);
|
@@ -2902,17 +3263,19 @@
|
|
2902
3263
|
|
2903
3264
|
var html = this.code.get();
|
2904
3265
|
|
2905
|
-
|
2906
|
-
this.$toolbar.find('a').each(function()
|
3266
|
+
if (this.opts.toolbar)
|
2907
3267
|
{
|
2908
|
-
|
2909
|
-
|
3268
|
+
// dropdowns off
|
3269
|
+
this.$toolbar.find('a').each(function()
|
2910
3270
|
{
|
2911
|
-
$el
|
2912
|
-
$el.data('dropdown'
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
3271
|
+
var $el = $(this);
|
3272
|
+
if ($el.data('dropdown'))
|
3273
|
+
{
|
3274
|
+
$el.data('dropdown').remove();
|
3275
|
+
$el.data('dropdown', {});
|
3276
|
+
}
|
3277
|
+
});
|
3278
|
+
}
|
2916
3279
|
|
2917
3280
|
if (this.build.isTextarea())
|
2918
3281
|
{
|
@@ -2935,11 +3298,10 @@
|
|
2935
3298
|
if (this.$modalOverlay) this.$modalOverlay.remove();
|
2936
3299
|
|
2937
3300
|
// buttons tooltip
|
2938
|
-
$('.redactor-toolbar-tooltip').remove();
|
3301
|
+
$('.redactor-toolbar-tooltip-' + this.uuid).remove();
|
2939
3302
|
|
2940
3303
|
// autosave
|
2941
3304
|
clearInterval(this.autosaveInterval);
|
2942
|
-
|
2943
3305
|
}
|
2944
3306
|
};
|
2945
3307
|
},
|
@@ -2988,12 +3350,11 @@
|
|
2988
3350
|
};
|
2989
3351
|
|
2990
3352
|
}, this));
|
2991
|
-
|
2992
3353
|
}
|
2993
3354
|
|
2994
3355
|
$.each(dropdownObject, $.proxy(function(btnName, btnObject)
|
2995
3356
|
{
|
2996
|
-
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>');
|
2997
3358
|
if (name == 'formatting') $item.addClass('redactor-formatting-' + btnName);
|
2998
3359
|
|
2999
3360
|
$item.on('click', $.proxy(function(e)
|
@@ -3013,11 +3374,15 @@
|
|
3013
3374
|
callback = btnObject.dropdown;
|
3014
3375
|
}
|
3015
3376
|
|
3377
|
+
if ($(e.target).hasClass('redactor-dropdown-link-inactive')) return;
|
3378
|
+
|
3016
3379
|
this.button.onClick(e, btnName, type, callback);
|
3017
3380
|
this.dropdown.hideAll();
|
3018
3381
|
|
3019
3382
|
}, this));
|
3020
3383
|
|
3384
|
+
this.observe.addDropdown($item, btnName, btnObject);
|
3385
|
+
|
3021
3386
|
$dropdown.append($item);
|
3022
3387
|
|
3023
3388
|
}, this));
|
@@ -3035,10 +3400,9 @@
|
|
3035
3400
|
// Always re-append it to the end of <body> so it always has the highest sub-z-index.
|
3036
3401
|
var $dropdown = $button.data('dropdown').appendTo(document.body);
|
3037
3402
|
|
3038
|
-
|
3039
|
-
if (this.utils.isMobile() && !this.utils.browser('msie'))
|
3403
|
+
if (this.opts.highContrast)
|
3040
3404
|
{
|
3041
|
-
|
3405
|
+
$dropdown.addClass("redactor-dropdown-contrast");
|
3042
3406
|
}
|
3043
3407
|
|
3044
3408
|
if ($button.hasClass('dropact'))
|
@@ -3048,6 +3412,8 @@
|
|
3048
3412
|
else
|
3049
3413
|
{
|
3050
3414
|
this.dropdown.hideAll();
|
3415
|
+
this.observe.dropdowns();
|
3416
|
+
|
3051
3417
|
this.core.setCallback('dropdownShow', { dropdown: $dropdown, key: key, button: $button });
|
3052
3418
|
|
3053
3419
|
this.button.setActive(key);
|
@@ -3084,45 +3450,57 @@
|
|
3084
3450
|
}
|
3085
3451
|
|
3086
3452
|
this.core.setCallback('dropdownShown', { dropdown: $dropdown, key: key, button: $button });
|
3087
|
-
}
|
3088
|
-
|
3089
|
-
$(document).one('click', $.proxy(this.dropdown.hide, this));
|
3090
|
-
this.$editor.one('click', $.proxy(this.dropdown.hide, this));
|
3091
|
-
|
3092
|
-
// disable scroll whan dropdown scroll
|
3093
|
-
var $body = $(document.body);
|
3094
|
-
var width = $body.width();
|
3095
3453
|
|
3096
|
-
|
3097
|
-
|
3098
|
-
$body.addClass('body-redactor-hidden');
|
3099
|
-
$body.css('margin-right', ($body.width() - width) + 'px');
|
3100
|
-
|
3101
|
-
});
|
3102
|
-
|
3103
|
-
$dropdown.on('mouseout', function() {
|
3454
|
+
this.$dropdown = $dropdown;
|
3455
|
+
}
|
3104
3456
|
|
3105
|
-
$body.removeClass('body-redactor-hidden').css('margin-right', 0);
|
3106
3457
|
|
3107
|
-
|
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));
|
3108
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));
|
3109
3464
|
|
3110
3465
|
e.stopPropagation();
|
3111
3466
|
},
|
3467
|
+
closeHandler: function(e)
|
3468
|
+
{
|
3469
|
+
if (e.which != this.keyCode.ESC) return;
|
3470
|
+
|
3471
|
+
this.dropdown.hideAll();
|
3472
|
+
this.$editor.focus();
|
3473
|
+
},
|
3112
3474
|
hideAll: function()
|
3113
3475
|
{
|
3114
3476
|
this.$toolbar.find('a.dropact').removeClass('redactor-act').removeClass('dropact');
|
3115
3477
|
|
3116
|
-
|
3478
|
+
this.utils.enableBodyScroll();
|
3479
|
+
|
3117
3480
|
$('.redactor-dropdown-' + this.uuid).hide();
|
3118
|
-
|
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
|
+
}
|
3119
3491
|
},
|
3120
3492
|
hide: function (e)
|
3121
3493
|
{
|
3122
3494
|
var $dropdown = $(e.target);
|
3123
|
-
|
3495
|
+
|
3496
|
+
if (!$dropdown.hasClass('dropact') && !$dropdown.hasClass('redactor-dropdown-link-inactive'))
|
3124
3497
|
{
|
3125
|
-
$dropdown.
|
3498
|
+
if ($dropdown.hasClass('redactor-dropdown'))
|
3499
|
+
{
|
3500
|
+
$dropdown.removeClass('dropact');
|
3501
|
+
$dropdown.off('mouseover mouseout');
|
3502
|
+
}
|
3503
|
+
|
3126
3504
|
this.dropdown.hideAll();
|
3127
3505
|
}
|
3128
3506
|
}
|
@@ -3240,36 +3618,31 @@
|
|
3240
3618
|
},
|
3241
3619
|
setEnd: function()
|
3242
3620
|
{
|
3243
|
-
|
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()))
|
3244
3626
|
{
|
3245
|
-
var last = this.$editor.children().last();
|
3246
3627
|
|
3247
|
-
this
|
3248
|
-
this.
|
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();
|
3249
3633
|
}
|
3250
3634
|
else
|
3251
3635
|
{
|
3252
3636
|
this.selection.get();
|
3637
|
+
this.range.selectNodeContents(last[0]);
|
3638
|
+
this.range.collapse(false);
|
3639
|
+
this.selection.addRange();
|
3253
3640
|
|
3254
|
-
try {
|
3255
|
-
this.range.selectNodeContents(this.$editor[0]);
|
3256
|
-
this.range.collapse(false);
|
3257
|
-
|
3258
|
-
this.selection.addRange();
|
3259
|
-
}
|
3260
|
-
catch (e) {}
|
3261
3641
|
}
|
3262
|
-
|
3263
3642
|
},
|
3264
3643
|
isFocused: function()
|
3265
3644
|
{
|
3266
|
-
|
3267
|
-
if (focusNode === null) return false;
|
3268
|
-
|
3269
|
-
if (this.opts.linebreaks && $(focusNode.parentNode).hasClass('redactor-linebreaks')) return true;
|
3270
|
-
else if (!this.utils.isRedactorParent(focusNode.parentNode)) return false;
|
3271
|
-
|
3272
|
-
return this.$editor.is(':focus');
|
3645
|
+
return this.$editor[0] === document.activeElement;
|
3273
3646
|
}
|
3274
3647
|
};
|
3275
3648
|
},
|
@@ -3307,6 +3680,9 @@
|
|
3307
3680
|
|
3308
3681
|
}, this));
|
3309
3682
|
|
3683
|
+
// hide link's tooltip
|
3684
|
+
$('.redactor-link-tooltip').remove();
|
3685
|
+
|
3310
3686
|
$('#redactor-image-title').val($image.attr('alt'));
|
3311
3687
|
|
3312
3688
|
if (!this.opts.imageLink) $('.redactor-image-link-option').hide();
|
@@ -3330,6 +3706,7 @@
|
|
3330
3706
|
}
|
3331
3707
|
|
3332
3708
|
this.modal.show();
|
3709
|
+
$('#redactor-image-title').focus();
|
3333
3710
|
|
3334
3711
|
},
|
3335
3712
|
setFloating: function($image)
|
@@ -3366,12 +3743,14 @@
|
|
3366
3743
|
|
3367
3744
|
var $link = $image.closest('a', this.$editor[0]);
|
3368
3745
|
|
3369
|
-
|
3746
|
+
var title = $('#redactor-image-title').val().replace(/(<([^>]+)>)/ig,"");
|
3747
|
+
$image.attr('alt', title);
|
3370
3748
|
|
3371
3749
|
this.image.setFloating($image);
|
3372
3750
|
|
3373
3751
|
// as link
|
3374
3752
|
var link = $.trim($('#redactor-image-link').val());
|
3753
|
+
var link = link.replace(/(<([^>]+)>)/ig,"");
|
3375
3754
|
if (link !== '')
|
3376
3755
|
{
|
3377
3756
|
// test url (add protocol)
|
@@ -3425,17 +3804,14 @@
|
|
3425
3804
|
$image.on('dragstart', $.proxy(this.image.onDrag, this));
|
3426
3805
|
}
|
3427
3806
|
|
3428
|
-
|
3429
|
-
$image.on('click.redactor touchstart', $.proxy(function(e)
|
3807
|
+
var handler = $.proxy(function(e)
|
3430
3808
|
{
|
3431
|
-
this.observe.image = $image;
|
3432
3809
|
|
3433
|
-
|
3810
|
+
this.observe.image = $image;
|
3434
3811
|
|
3435
3812
|
this.image.resizer = this.image.loadEditableControls($image);
|
3436
3813
|
|
3437
|
-
$(document).on('
|
3438
|
-
this.$editor.on('click.redactor-image-resize-hide.' + this.uuid, $.proxy(this.image.hideResize, this));
|
3814
|
+
$(document).on('mousedown.redactor-image-resize-hide.' + this.uuid, $.proxy(this.image.hideResize, this));
|
3439
3815
|
|
3440
3816
|
// resize
|
3441
3817
|
if (!this.opts.imageResizable) return;
|
@@ -3445,8 +3821,11 @@
|
|
3445
3821
|
this.image.setResizable(e, $image);
|
3446
3822
|
}, this));
|
3447
3823
|
|
3824
|
+
}, this);
|
3448
3825
|
|
3449
|
-
|
3826
|
+
|
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);
|
3450
3829
|
},
|
3451
3830
|
setResizable: function(e, $image)
|
3452
3831
|
{
|
@@ -3550,12 +3929,8 @@
|
|
3550
3929
|
var imageBox = this.$editor.find('#redactor-image-box');
|
3551
3930
|
if (imageBox.length === 0) return;
|
3552
3931
|
|
3553
|
-
|
3554
|
-
|
3555
|
-
this.image.editter.remove();
|
3556
|
-
}
|
3557
|
-
|
3558
|
-
$(this.image.resizer).remove();
|
3932
|
+
$('#redactor-image-editter').remove();
|
3933
|
+
$('#redactor-image-resizer').remove();
|
3559
3934
|
|
3560
3935
|
imageBox.find('img').css({
|
3561
3936
|
marginTop: imageBox[0].style.marginTop,
|
@@ -3571,8 +3946,8 @@
|
|
3571
3946
|
return $(this).contents();
|
3572
3947
|
});
|
3573
3948
|
|
3574
|
-
$(document).off('
|
3575
|
-
|
3949
|
+
$(document).off('mousedown.redactor-image-resize-hide.' + this.uuid);
|
3950
|
+
|
3576
3951
|
|
3577
3952
|
if (typeof this.image.resizeHandle !== 'undefined')
|
3578
3953
|
{
|
@@ -3748,7 +4123,12 @@
|
|
3748
4123
|
}
|
3749
4124
|
else if (this.opts.linebreaks)
|
3750
4125
|
{
|
3751
|
-
|
4126
|
+
if (!this.utils.isEmpty(this.code.get()))
|
4127
|
+
{
|
4128
|
+
$image.before('<br>');
|
4129
|
+
}
|
4130
|
+
|
4131
|
+
$image.after('<br>');
|
3752
4132
|
}
|
3753
4133
|
|
3754
4134
|
if (typeof json == 'string') return;
|
@@ -3832,18 +4212,12 @@
|
|
3832
4212
|
this.selection.restore();
|
3833
4213
|
this.code.sync();
|
3834
4214
|
},
|
3835
|
-
decreaseLists: function
|
4215
|
+
decreaseLists: function()
|
3836
4216
|
{
|
3837
4217
|
document.execCommand('outdent');
|
3838
4218
|
|
3839
4219
|
var current = this.selection.getCurrent();
|
3840
|
-
|
3841
4220
|
var $item = $(current).closest('li', this.$editor[0]);
|
3842
|
-
var $parent = $item.parent();
|
3843
|
-
if ($item.length !== 0 && $parent.length !== 0 && $parent[0].tagName == 'LI')
|
3844
|
-
{
|
3845
|
-
$parent.after($item);
|
3846
|
-
}
|
3847
4221
|
|
3848
4222
|
this.indent.fixEmptyIndent();
|
3849
4223
|
|
@@ -3911,6 +4285,9 @@
|
|
3911
4285
|
},
|
3912
4286
|
format: function(tag, type, value)
|
3913
4287
|
{
|
4288
|
+
var current = this.selection.getCurrent();
|
4289
|
+
if (current && current.tagName === 'TR') return;
|
4290
|
+
|
3914
4291
|
// Stop formatting pre and headers
|
3915
4292
|
if (this.utils.isCurrentOrParent('PRE') || this.utils.isCurrentOrParentHeader()) return;
|
3916
4293
|
|
@@ -3922,6 +4299,7 @@
|
|
3922
4299
|
if (tag == tags[i]) tag = replaced[i];
|
3923
4300
|
}
|
3924
4301
|
|
4302
|
+
|
3925
4303
|
if (this.opts.allowedTags)
|
3926
4304
|
{
|
3927
4305
|
if ($.inArray(tag, this.opts.allowedTags) == -1) return;
|
@@ -3936,7 +4314,7 @@
|
|
3936
4314
|
|
3937
4315
|
this.buffer.set();
|
3938
4316
|
|
3939
|
-
if (!this.utils.browser('msie'))
|
4317
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
3940
4318
|
{
|
3941
4319
|
this.$editor.focus();
|
3942
4320
|
}
|
@@ -4012,11 +4390,17 @@
|
|
4012
4390
|
}
|
4013
4391
|
|
4014
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
|
+
}
|
4015
4400
|
|
4016
4401
|
if (tag == 'span')
|
4017
4402
|
{
|
4018
|
-
|
4019
|
-
if ($parent && $parent[0].tagName == 'SPAN' && this.inline.type == 'style')
|
4403
|
+
if ($parent && $parent[0].tagName === 'SPAN' && this.inline.type === 'style')
|
4020
4404
|
{
|
4021
4405
|
var arr = this.inline.value.split(';');
|
4022
4406
|
|
@@ -4044,8 +4428,16 @@
|
|
4044
4428
|
this.$editor.find(this.opts.inlineTags.join(', ')).each($.proxy(function(i,s)
|
4045
4429
|
{
|
4046
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
|
+
|
4047
4439
|
var property = $el.css('text-decoration');
|
4048
|
-
if (property
|
4440
|
+
if (property === 'line-through')
|
4049
4441
|
{
|
4050
4442
|
$el.css('text-decoration', '');
|
4051
4443
|
this.utils.removeEmptyAttr($el, 'style');
|
@@ -4062,6 +4454,15 @@
|
|
4062
4454
|
});
|
4063
4455
|
}
|
4064
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
|
+
|
4065
4466
|
this.selection.restore();
|
4066
4467
|
this.code.sync();
|
4067
4468
|
|
@@ -4121,6 +4522,14 @@
|
|
4121
4522
|
});
|
4122
4523
|
}
|
4123
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
|
+
|
4124
4533
|
if (tag != 'span')
|
4125
4534
|
{
|
4126
4535
|
this.$editor.find(tag).each(function()
|
@@ -4360,7 +4769,10 @@
|
|
4360
4769
|
|
4361
4770
|
if (typeof clean == 'undefined') clean = true;
|
4362
4771
|
|
4363
|
-
this
|
4772
|
+
if (!this.opts.linebreaks)
|
4773
|
+
{
|
4774
|
+
this.$editor.focus();
|
4775
|
+
}
|
4364
4776
|
|
4365
4777
|
html = this.clean.setVerified(html);
|
4366
4778
|
|
@@ -4455,6 +4867,7 @@
|
|
4455
4867
|
{
|
4456
4868
|
node = node[0] || node;
|
4457
4869
|
|
4870
|
+
var offset = this.caret.getOffset();
|
4458
4871
|
var html = this.utils.getOuterHtml(node);
|
4459
4872
|
html = this.clean.setVerified(html);
|
4460
4873
|
|
@@ -4474,6 +4887,8 @@
|
|
4474
4887
|
this.range.collapse(false);
|
4475
4888
|
this.selection.addRange();
|
4476
4889
|
|
4890
|
+
this.caret.setOffset(offset);
|
4891
|
+
|
4477
4892
|
return node;
|
4478
4893
|
},
|
4479
4894
|
nodeToPoint: function(node, x, y)
|
@@ -4546,6 +4961,7 @@
|
|
4546
4961
|
var parHtml = $(parent).html();
|
4547
4962
|
|
4548
4963
|
parHtml = '<p>' + parHtml.replace(/<span class="redactor-ie-paste"><\/span>/gi, '</p>' + html + '<p>') + '</p>';
|
4964
|
+
parHtml = parHtml.replace(/<p><\/p>/gi, '');
|
4549
4965
|
$(parent).replaceWith(parHtml);
|
4550
4966
|
},
|
4551
4967
|
ie11PasteFrag: function(html)
|
@@ -4591,8 +5007,12 @@
|
|
4591
5007
|
// shortcuts setup
|
4592
5008
|
this.shortcuts.init(e, key);
|
4593
5009
|
|
4594
|
-
this.
|
4595
|
-
|
5010
|
+
if (this.utils.isDesktop())
|
5011
|
+
{
|
5012
|
+
this.keydown.checkEvents(arrow, key);
|
5013
|
+
this.keydown.setupBuffer(e, key);
|
5014
|
+
}
|
5015
|
+
|
4596
5016
|
this.keydown.addArrowsEvent(arrow);
|
4597
5017
|
this.keydown.setupSelectAll(e, key);
|
4598
5018
|
|
@@ -4709,6 +5129,7 @@
|
|
4709
5129
|
|
4710
5130
|
return this.keydown.insertBreakLine(e);
|
4711
5131
|
}
|
5132
|
+
|
4712
5133
|
}
|
4713
5134
|
else if (this.opts.linebreaks && this.keydown.block)
|
4714
5135
|
{
|
@@ -4717,11 +5138,9 @@
|
|
4717
5138
|
// paragraphs
|
4718
5139
|
else if (!this.opts.linebreaks && this.keydown.block)
|
4719
5140
|
{
|
4720
|
-
|
4721
|
-
|
4722
|
-
|
4723
|
-
}
|
4724
|
-
else
|
5141
|
+
setTimeout($.proxy(this.keydown.replaceDivToParagraph, this), 1);
|
5142
|
+
|
5143
|
+
if (this.keydown.block.tagName === 'LI')
|
4725
5144
|
{
|
4726
5145
|
current = this.selection.getCurrent();
|
4727
5146
|
var $parent = $(current).closest('li', this.$editor[0]);
|
@@ -4761,13 +5180,8 @@
|
|
4761
5180
|
// image delete and backspace
|
4762
5181
|
if (key === this.keyCode.BACKSPACE || key === this.keyCode.DELETE)
|
4763
5182
|
{
|
4764
|
-
if (this.utils.browser('mozilla') && this.keydown.current && this.keydown.current.tagName === 'TD')
|
4765
|
-
{
|
4766
|
-
e.preventDefault();
|
4767
|
-
return false;
|
4768
|
-
}
|
4769
|
-
|
4770
5183
|
var nodes = this.selection.getNodes();
|
5184
|
+
|
4771
5185
|
if (nodes)
|
4772
5186
|
{
|
4773
5187
|
var len = nodes.length;
|
@@ -4804,6 +5218,25 @@
|
|
4804
5218
|
// backspace
|
4805
5219
|
if (key === this.keyCode.BACKSPACE)
|
4806
5220
|
{
|
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
|
+
|
4807
5240
|
this.keydown.removeInvisibleSpace();
|
4808
5241
|
this.keydown.removeEmptyListInTable(e);
|
4809
5242
|
}
|
@@ -4825,7 +5258,7 @@
|
|
4825
5258
|
checkKeyEvents: function(key)
|
4826
5259
|
{
|
4827
5260
|
var k = this.keyCode;
|
4828
|
-
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];
|
4829
5262
|
|
4830
5263
|
return ($.inArray(key, keys) == -1) ? true : false;
|
4831
5264
|
|
@@ -4859,7 +5292,7 @@
|
|
4859
5292
|
}
|
4860
5293
|
else if (!this.keydown.ctrl)
|
4861
5294
|
{
|
4862
|
-
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))
|
4863
5296
|
{
|
4864
5297
|
this.buffer.set();
|
4865
5298
|
}
|
@@ -4950,7 +5383,7 @@
|
|
4950
5383
|
{
|
4951
5384
|
var blockElem = this.selection.getBlock();
|
4952
5385
|
var blockHtml = blockElem.innerHTML.replace(/<br\s?\/?>/gi, '');
|
4953
|
-
if (blockElem.tagName === 'DIV' && blockHtml
|
5386
|
+
if (blockElem.tagName === 'DIV' && this.utils.isEmpty(blockHtml) && !$(blockElem).hasClass('redactor-editor'))
|
4954
5387
|
{
|
4955
5388
|
var p = document.createElement('p');
|
4956
5389
|
p.innerHTML = this.opts.invisibleSpace;
|
@@ -5097,9 +5530,7 @@
|
|
5097
5530
|
|
5098
5531
|
if ($parentA.length > 0)
|
5099
5532
|
{
|
5100
|
-
$parentA.find(br1)
|
5101
|
-
.remove();
|
5102
|
-
|
5533
|
+
$parentA.find(br1).remove();
|
5103
5534
|
$parentA.after(br1);
|
5104
5535
|
}
|
5105
5536
|
|
@@ -5120,23 +5551,32 @@
|
|
5120
5551
|
}
|
5121
5552
|
else
|
5122
5553
|
{
|
5123
|
-
|
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
|
+
}
|
5124
5575
|
}
|
5125
5576
|
|
5126
5577
|
this.code.sync();
|
5127
5578
|
return false;
|
5128
5579
|
},
|
5129
|
-
insertBreakLineProcessingAfter: function(node)
|
5130
|
-
{
|
5131
|
-
var space = this.utils.createSpaceElement();
|
5132
|
-
$(node).after(space);
|
5133
|
-
this.selection.selectElement(space);
|
5134
|
-
|
5135
|
-
$(space).replaceWith(function()
|
5136
|
-
{
|
5137
|
-
return $(this).contents();
|
5138
|
-
});
|
5139
|
-
},
|
5140
5580
|
removeInvisibleSpace: function()
|
5141
5581
|
{
|
5142
5582
|
var $current = $(this.keydown.current);
|
@@ -5170,6 +5610,7 @@
|
|
5170
5610
|
return {
|
5171
5611
|
init: function(e)
|
5172
5612
|
{
|
5613
|
+
|
5173
5614
|
if (this.rtePaste) return;
|
5174
5615
|
|
5175
5616
|
var key = e.which;
|
@@ -5187,7 +5628,7 @@
|
|
5187
5628
|
}
|
5188
5629
|
|
5189
5630
|
// replace to p before / after the table or body
|
5190
|
-
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'))
|
5191
5632
|
{
|
5192
5633
|
this.keyup.replaceToParagraph();
|
5193
5634
|
}
|
@@ -5206,11 +5647,20 @@
|
|
5206
5647
|
}
|
5207
5648
|
|
5208
5649
|
// linkify
|
5209
|
-
if (this.linkify.isEnabled() && this.linkify.isKey(key))
|
5210
|
-
this.linkify.format();
|
5650
|
+
if (this.linkify.isEnabled() && this.linkify.isKey(key)) this.linkify.format();
|
5211
5651
|
|
5212
5652
|
if (key === this.keyCode.DELETE || key === this.keyCode.BACKSPACE)
|
5213
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
|
+
|
5214
5664
|
// clear unverified
|
5215
5665
|
this.clean.clearUnverified();
|
5216
5666
|
|
@@ -5241,6 +5691,8 @@
|
|
5241
5691
|
$(this.keyup.current).remove();
|
5242
5692
|
}
|
5243
5693
|
|
5694
|
+
this.keyup.removeEmptyLists();
|
5695
|
+
|
5244
5696
|
// if empty
|
5245
5697
|
return this.keyup.formatEmpty(e);
|
5246
5698
|
}
|
@@ -5268,6 +5720,20 @@
|
|
5268
5720
|
|
5269
5721
|
this.caret.setEnd(node);
|
5270
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
|
+
},
|
5271
5737
|
formatEmpty: function(e)
|
5272
5738
|
{
|
5273
5739
|
var html = $.trim(this.$editor.html());
|
@@ -5283,9 +5749,7 @@
|
|
5283
5749
|
}
|
5284
5750
|
else
|
5285
5751
|
{
|
5286
|
-
html
|
5287
|
-
|
5288
|
-
this.$editor.html(html);
|
5752
|
+
this.$editor.html(this.opts.emptyHtml);
|
5289
5753
|
this.focus.setStart();
|
5290
5754
|
}
|
5291
5755
|
|
@@ -5365,7 +5829,7 @@
|
|
5365
5829
|
var extra = '<p id="redactor-insert-line"><br /></p>';
|
5366
5830
|
if (this.opts.linebreaks) extra = '<br id="redactor-insert-line">';
|
5367
5831
|
|
5368
|
-
document.execCommand('
|
5832
|
+
document.execCommand('insertHtml', false, '<hr>' + extra);
|
5369
5833
|
|
5370
5834
|
this.line.setFocus();
|
5371
5835
|
this.code.sync();
|
@@ -5374,16 +5838,43 @@
|
|
5374
5838
|
{
|
5375
5839
|
var node = this.$editor.find('#redactor-insert-line');
|
5376
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
|
+
}
|
5377
5847
|
|
5378
|
-
if (
|
5848
|
+
if (target)
|
5379
5849
|
{
|
5380
|
-
this.caret.setAfter(node);
|
5381
5850
|
node.remove();
|
5851
|
+
|
5852
|
+
if (!this.opts.linebreaks)
|
5853
|
+
{
|
5854
|
+
this.$editor.focus();
|
5855
|
+
this.line.setStart(target);
|
5856
|
+
}
|
5857
|
+
|
5382
5858
|
}
|
5383
5859
|
else
|
5384
5860
|
{
|
5861
|
+
|
5385
5862
|
node.removeAttr('id');
|
5863
|
+
this.line.setStart(node[0]);
|
5386
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
|
+
|
5387
5878
|
}
|
5388
5879
|
};
|
5389
5880
|
},
|
@@ -5394,10 +5885,20 @@
|
|
5394
5885
|
{
|
5395
5886
|
if (typeof e != 'undefined' && e.preventDefault) e.preventDefault();
|
5396
5887
|
|
5397
|
-
|
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
|
+
}
|
5398
5896
|
|
5399
5897
|
this.modal.createCancelButton();
|
5400
|
-
|
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);
|
5401
5902
|
|
5402
5903
|
this.selection.get();
|
5403
5904
|
|
@@ -5467,7 +5968,7 @@
|
|
5467
5968
|
|
5468
5969
|
var target = '';
|
5469
5970
|
var link = this.link.$inputUrl.val();
|
5470
|
-
var text = this.link.$inputText.val();
|
5971
|
+
var text = this.link.$inputText.val().replace(/(<([^>]+)>)/ig,"");
|
5471
5972
|
|
5472
5973
|
if ($.trim(link) === '')
|
5473
5974
|
{
|
@@ -5484,6 +5985,7 @@
|
|
5484
5985
|
// mailto
|
5485
5986
|
if (link.search('@') != -1 && /(http|ftp|https):\/\//i.test(link) === false)
|
5486
5987
|
{
|
5988
|
+
link = link.replace('mailto:', '');
|
5487
5989
|
link = 'mailto:' + link;
|
5488
5990
|
}
|
5489
5991
|
// url, not anchor
|
@@ -5513,6 +6015,7 @@
|
|
5513
6015
|
text = $.trim(text.replace(/<|>/g, ''));
|
5514
6016
|
|
5515
6017
|
this.selection.restore();
|
6018
|
+
var blocks = this.selection.getBlocks();
|
5516
6019
|
|
5517
6020
|
if (text === '' && link === '') return;
|
5518
6021
|
if (text === '' && link !== '') text = link;
|
@@ -5561,7 +6064,13 @@
|
|
5561
6064
|
var $a = $('<a />').attr('href', link).text(text);
|
5562
6065
|
if (target !== '') $a.attr('target', target);
|
5563
6066
|
|
5564
|
-
this.insert.node($a);
|
6067
|
+
$a = $(this.insert.node($a));
|
6068
|
+
|
6069
|
+
if (this.opts.linebreaks)
|
6070
|
+
{
|
6071
|
+
$a.after(' ');
|
6072
|
+
}
|
6073
|
+
|
5565
6074
|
this.selection.selectElement($a);
|
5566
6075
|
}
|
5567
6076
|
else
|
@@ -5601,7 +6110,14 @@
|
|
5601
6110
|
|
5602
6111
|
if (this.link.text !== '' || this.link.text != text)
|
5603
6112
|
{
|
5604
|
-
|
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
|
+
}
|
5605
6121
|
|
5606
6122
|
this.selection.selectElement($a);
|
5607
6123
|
}
|
@@ -5633,12 +6149,20 @@
|
|
5633
6149
|
this.buffer.set();
|
5634
6150
|
|
5635
6151
|
var len = nodes.length;
|
6152
|
+
var links = [];
|
5636
6153
|
for (var i = 0; i < len; i++)
|
5637
6154
|
{
|
6155
|
+
if (nodes[i].tagName === 'A')
|
6156
|
+
{
|
6157
|
+
links.push(nodes[i]);
|
6158
|
+
}
|
6159
|
+
|
5638
6160
|
var $node = $(nodes[i]).closest('a', this.$editor[0]);
|
5639
6161
|
$node.replaceWith($node.contents());
|
5640
6162
|
}
|
5641
6163
|
|
6164
|
+
this.core.setCallback('deletedLink', links);
|
6165
|
+
|
5642
6166
|
// hide link's tooltip
|
5643
6167
|
$('.redactor-link-tooltip').remove();
|
5644
6168
|
|
@@ -5669,13 +6193,171 @@
|
|
5669
6193
|
}
|
5670
6194
|
};
|
5671
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;
|
6347
|
+
}
|
6348
|
+
};
|
6349
|
+
},
|
5672
6350
|
list: function()
|
5673
6351
|
{
|
5674
6352
|
return {
|
5675
6353
|
toggle: function(cmd)
|
5676
6354
|
{
|
5677
6355
|
this.placeholder.remove();
|
5678
|
-
|
6356
|
+
|
6357
|
+
if (!this.utils.browser('msie') && !this.opts.linebreaks)
|
6358
|
+
{
|
6359
|
+
this.$editor.focus();
|
6360
|
+
}
|
5679
6361
|
|
5680
6362
|
this.buffer.set();
|
5681
6363
|
this.selection.save();
|
@@ -5711,7 +6393,7 @@
|
|
5711
6393
|
{
|
5712
6394
|
if (remove)
|
5713
6395
|
{
|
5714
|
-
this.list.remove(cmd);
|
6396
|
+
this.list.remove(cmd, $list);
|
5715
6397
|
}
|
5716
6398
|
else
|
5717
6399
|
{
|
@@ -5721,10 +6403,10 @@
|
|
5721
6403
|
|
5722
6404
|
this.selection.restore();
|
5723
6405
|
this.code.sync();
|
6406
|
+
|
5724
6407
|
},
|
5725
6408
|
insert: function(cmd)
|
5726
6409
|
{
|
5727
|
-
var parent = this.selection.getParent();
|
5728
6410
|
var current = this.selection.getCurrent();
|
5729
6411
|
var $td = $(current).closest('td, th', this.$editor[0]);
|
5730
6412
|
|
@@ -5737,30 +6419,25 @@
|
|
5737
6419
|
document.execCommand('insert' + cmd);
|
5738
6420
|
}
|
5739
6421
|
|
5740
|
-
var
|
5741
|
-
|
6422
|
+
var parent = this.selection.getParent();
|
6423
|
+
var $list = $(parent).closest('ol, ul', this.$editor[0]);
|
5742
6424
|
if ($td.length !== 0)
|
5743
6425
|
{
|
5744
|
-
var
|
5745
|
-
|
5746
|
-
$td.html('');
|
5747
|
-
if (prev && prev.length === 1 && (prev[0].tagName === 'TD' || prev[0].tagName === 'TH'))
|
5748
|
-
{
|
5749
|
-
$(prev).after($td);
|
5750
|
-
}
|
5751
|
-
else
|
5752
|
-
{
|
5753
|
-
$(parent).prepend($td);
|
5754
|
-
}
|
5755
|
-
|
5756
|
-
$td.html(html);
|
6426
|
+
var newTd = $td.clone();
|
6427
|
+
$td.after(newTd).remove('');
|
5757
6428
|
}
|
5758
6429
|
|
6430
|
+
|
5759
6431
|
if (this.utils.isEmpty($list.find('li').text()))
|
5760
6432
|
{
|
5761
6433
|
var $children = $list.children('li');
|
5762
6434
|
$children.find('br').remove();
|
5763
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
|
+
}
|
5764
6441
|
}
|
5765
6442
|
|
5766
6443
|
if ($list.length)
|
@@ -5778,6 +6455,7 @@
|
|
5778
6455
|
this.$editor.focus();
|
5779
6456
|
}
|
5780
6457
|
|
6458
|
+
|
5781
6459
|
this.clean.clearUnverified();
|
5782
6460
|
},
|
5783
6461
|
insertInIe: function(cmd)
|
@@ -5816,12 +6494,13 @@
|
|
5816
6494
|
$(wrapper).replaceWith(tmpList);
|
5817
6495
|
}
|
5818
6496
|
},
|
5819
|
-
remove: function(cmd)
|
6497
|
+
remove: function(cmd, $list)
|
5820
6498
|
{
|
6499
|
+
if ($.inArray('ul', this.selection.getBlocks())) cmd = 'unorderedlist';
|
6500
|
+
|
5821
6501
|
document.execCommand('insert' + cmd);
|
5822
6502
|
|
5823
6503
|
var $current = $(this.selection.getCurrent());
|
5824
|
-
|
5825
6504
|
this.indent.fixEmptyIndent();
|
5826
6505
|
|
5827
6506
|
if (!this.opts.linebreaks && $current.closest('li, th, td', this.$editor[0]).length === 0)
|
@@ -5839,6 +6518,7 @@
|
|
5839
6518
|
|
5840
6519
|
this.clean.clearUnverified();
|
5841
6520
|
|
6521
|
+
|
5842
6522
|
}
|
5843
6523
|
};
|
5844
6524
|
},
|
@@ -5854,10 +6534,10 @@
|
|
5854
6534
|
+ '<label>' + this.lang.get('title') + '</label>'
|
5855
6535
|
+ '<input type="text" id="redactor-image-title" />'
|
5856
6536
|
+ '<label class="redactor-image-link-option">' + this.lang.get('link') + '</label>'
|
5857
|
-
+ '<input type="text" id="redactor-image-link" class="redactor-image-link-option" />'
|
5858
|
-
+ '<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>'
|
5859
6539
|
+ '<label class="redactor-image-position-option">' + this.lang.get('image_position') + '</label>'
|
5860
|
-
+ '<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') + '">'
|
5861
6541
|
+ '<option value="none">' + this.lang.get('none') + '</option>'
|
5862
6542
|
+ '<option value="left">' + this.lang.get('left') + '</option>'
|
5863
6543
|
+ '<option value="center">' + this.lang.get('center') + '</option>'
|
@@ -5874,7 +6554,7 @@
|
|
5874
6554
|
+ '<section id="redactor-modal-file-insert">'
|
5875
6555
|
+ '<div id="redactor-modal-file-upload-box">'
|
5876
6556
|
+ '<label>' + this.lang.get('filename') + '</label>'
|
5877
|
-
+ '<input type="text" id="redactor-filename" /><br><br>'
|
6557
|
+
+ '<input type="text" id="redactor-filename" aria-label="' + this.lang.get('filename') + '" /><br><br>'
|
5878
6558
|
+ '<div id="redactor-modal-file-upload"></div>'
|
5879
6559
|
+ '</div>'
|
5880
6560
|
+ '</section>',
|
@@ -5882,9 +6562,9 @@
|
|
5882
6562
|
link: String()
|
5883
6563
|
+ '<section id="redactor-modal-link-insert">'
|
5884
6564
|
+ '<label>URL</label>'
|
5885
|
-
+ '<input type="url" id="redactor-link-url" />'
|
6565
|
+
+ '<input type="url" id="redactor-link-url" aria-label="URL" />'
|
5886
6566
|
+ '<label>' + this.lang.get('text') + '</label>'
|
5887
|
-
+ '<input type="text" id="redactor-link-url-text" />'
|
6567
|
+
+ '<input type="text" id="redactor-link-url-text" aria-label="' + this.lang.get('text') + '" />'
|
5888
6568
|
+ '<label><input type="checkbox" id="redactor-link-blank"> ' + this.lang.get('link_new_tab') + '</label>'
|
5889
6569
|
+ '</section>'
|
5890
6570
|
};
|
@@ -5957,15 +6637,7 @@
|
|
5957
6637
|
},
|
5958
6638
|
show: function()
|
5959
6639
|
{
|
5960
|
-
|
5961
|
-
if (this.utils.isMobile() && !this.utils.browser('msie'))
|
5962
|
-
{
|
5963
|
-
document.activeElement.blur();
|
5964
|
-
}
|
5965
|
-
|
5966
|
-
$(document.body).removeClass('body-redactor-hidden');
|
5967
|
-
this.modal.bodyOveflow = $(document.body).css('overflow');
|
5968
|
-
$(document.body).css('overflow', 'hidden');
|
6640
|
+
this.utils.disableBodyScroll();
|
5969
6641
|
|
5970
6642
|
if (this.utils.isMobile())
|
5971
6643
|
{
|
@@ -5976,9 +6648,17 @@
|
|
5976
6648
|
this.modal.showOnDesktop();
|
5977
6649
|
}
|
5978
6650
|
|
6651
|
+
if (this.opts.highContrast)
|
6652
|
+
{
|
6653
|
+
this.$modalBox.addClass("redactor-modal-contrast");
|
6654
|
+
}
|
6655
|
+
|
5979
6656
|
this.$modalOverlay.show();
|
5980
6657
|
this.$modalBox.show();
|
5981
6658
|
|
6659
|
+
this.$modal.attr('tabindex', '-1');
|
6660
|
+
this.$modal.focus();
|
6661
|
+
|
5982
6662
|
this.modal.setButtonsWidth();
|
5983
6663
|
|
5984
6664
|
this.utils.saveScroll();
|
@@ -6104,10 +6784,10 @@
|
|
6104
6784
|
{
|
6105
6785
|
this.modal.buildOverlay();
|
6106
6786
|
|
6107
|
-
this.$modalBox = $('<div id="redactor-modal-box"
|
6108
|
-
this.$modal = $('<div id="redactor-modal" />');
|
6109
|
-
this.$modalHeader = $('<header />');
|
6110
|
-
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('×');
|
6111
6791
|
this.$modalBody = $('<div id="redactor-modal-body" />');
|
6112
6792
|
this.$modalFooter = $('<footer />');
|
6113
6793
|
|
@@ -6159,6 +6839,7 @@
|
|
6159
6839
|
if (!this.$modalBox) return;
|
6160
6840
|
|
6161
6841
|
this.modal.disableEvents();
|
6842
|
+
this.utils.enableBodyScroll();
|
6162
6843
|
|
6163
6844
|
this.$modalOverlay.remove();
|
6164
6845
|
|
@@ -6183,9 +6864,116 @@
|
|
6183
6864
|
return {
|
6184
6865
|
load: function()
|
6185
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', fa |