summernote-rails 0.8.3.0 → 0.8.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/summernote-rails/version.rb +1 -1
- data/vendor/assets/fonts/summernote.eot +0 -0
- data/vendor/assets/fonts/summernote.ttf +0 -0
- data/vendor/assets/fonts/summernote.woff +0 -0
- data/vendor/assets/javascripts/summernote/locales/de-DE.js +1 -1
- data/vendor/assets/javascripts/summernote/locales/fr-FR.js +18 -8
- data/vendor/assets/javascripts/summernote/locales/mn-MN.js +118 -0
- data/vendor/assets/javascripts/summernote/locales/pt-BR.js +7 -1
- data/vendor/assets/javascripts/summernote/locales/tr-TR.js +8 -1
- data/vendor/assets/javascripts/summernote/locales/zh-CN.js +1 -1
- data/vendor/assets/javascripts/summernote/summernote-bs4.js +7990 -0
- data/vendor/assets/javascripts/summernote/summernote-lite.js +8598 -0
- data/vendor/assets/javascripts/summernote/summernote.js +1208 -270
- data/vendor/assets/stylesheets/summernote-bs4.css +1 -0
- data/vendor/assets/stylesheets/summernote-lite.css +1 -0
- data/vendor/assets/stylesheets/summernote.css +1 -1
- metadata +8 -4
@@ -1,12 +1,12 @@
|
|
1
1
|
/**
|
2
|
-
* Super simple wysiwyg editor v0.8.
|
2
|
+
* Super simple wysiwyg editor v0.8.8
|
3
3
|
* http://summernote.org/
|
4
4
|
*
|
5
5
|
* summernote.js
|
6
|
-
* Copyright 2013-
|
6
|
+
* Copyright 2013- Alan Hong. and other contributors
|
7
7
|
* summernote may be freely distributed under the MIT license./
|
8
8
|
*
|
9
|
-
* Date: 2017-
|
9
|
+
* Date: 2017-09-09T11:03Z
|
10
10
|
*/
|
11
11
|
(function (factory) {
|
12
12
|
/* global define */
|
@@ -23,6 +23,108 @@
|
|
23
23
|
}(function ($) {
|
24
24
|
'use strict';
|
25
25
|
|
26
|
+
var isSupportAmd = typeof define === 'function' && define.amd;
|
27
|
+
|
28
|
+
/**
|
29
|
+
* returns whether font is installed or not.
|
30
|
+
*
|
31
|
+
* @param {String} fontName
|
32
|
+
* @return {Boolean}
|
33
|
+
*/
|
34
|
+
var isFontInstalled = function (fontName) {
|
35
|
+
var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';
|
36
|
+
var $tester = $('<div>').css({
|
37
|
+
position: 'absolute',
|
38
|
+
left: '-9999px',
|
39
|
+
top: '-9999px',
|
40
|
+
fontSize: '200px'
|
41
|
+
}).text('mmmmmmmmmwwwwwww').appendTo(document.body);
|
42
|
+
|
43
|
+
var originalWidth = $tester.css('fontFamily', testFontName).width();
|
44
|
+
var width = $tester.css('fontFamily', fontName + ',' + testFontName).width();
|
45
|
+
|
46
|
+
$tester.remove();
|
47
|
+
|
48
|
+
return originalWidth !== width;
|
49
|
+
};
|
50
|
+
|
51
|
+
var userAgent = navigator.userAgent;
|
52
|
+
var isMSIE = /MSIE|Trident/i.test(userAgent);
|
53
|
+
var browserVersion;
|
54
|
+
if (isMSIE) {
|
55
|
+
var matches = /MSIE (\d+[.]\d+)/.exec(userAgent);
|
56
|
+
if (matches) {
|
57
|
+
browserVersion = parseFloat(matches[1]);
|
58
|
+
}
|
59
|
+
matches = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
|
60
|
+
if (matches) {
|
61
|
+
browserVersion = parseFloat(matches[1]);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
var isEdge = /Edge\/\d+/.test(userAgent);
|
66
|
+
|
67
|
+
var hasCodeMirror = !!window.CodeMirror;
|
68
|
+
if (!hasCodeMirror && isSupportAmd) {
|
69
|
+
// Webpack
|
70
|
+
if (typeof __webpack_require__ === 'function') { // jshint ignore:line
|
71
|
+
try {
|
72
|
+
// If CodeMirror can't be resolved, `require.resolve` will throw an
|
73
|
+
// exception and `hasCodeMirror` won't be set to `true`.
|
74
|
+
require.resolve('codemirror');
|
75
|
+
hasCodeMirror = true;
|
76
|
+
} catch (e) {
|
77
|
+
// do nothing
|
78
|
+
}
|
79
|
+
} else if (typeof require !== 'undefined') {
|
80
|
+
// Browserify
|
81
|
+
if (typeof require.resolve !== 'undefined') {
|
82
|
+
try {
|
83
|
+
// If CodeMirror can't be resolved, `require.resolve` will throw an
|
84
|
+
// exception and `hasCodeMirror` won't be set to `true`.
|
85
|
+
require.resolve('codemirror');
|
86
|
+
hasCodeMirror = true;
|
87
|
+
} catch (e) {
|
88
|
+
// do nothing
|
89
|
+
}
|
90
|
+
// Almond/Require
|
91
|
+
} else if (typeof require.specified !== 'undefined') {
|
92
|
+
hasCodeMirror = require.specified('codemirror');
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
var isSupportTouch =
|
98
|
+
(('ontouchstart' in window) ||
|
99
|
+
(navigator.MaxTouchPoints > 0) ||
|
100
|
+
(navigator.msMaxTouchPoints > 0));
|
101
|
+
|
102
|
+
/**
|
103
|
+
* @class core.agent
|
104
|
+
*
|
105
|
+
* Object which check platform and agent
|
106
|
+
*
|
107
|
+
* @singleton
|
108
|
+
* @alternateClassName agent
|
109
|
+
*/
|
110
|
+
var agent = {
|
111
|
+
isMac: navigator.appVersion.indexOf('Mac') > -1,
|
112
|
+
isMSIE: isMSIE,
|
113
|
+
isEdge: isEdge,
|
114
|
+
isFF: !isEdge && /firefox/i.test(userAgent),
|
115
|
+
isPhantom: /PhantomJS/i.test(userAgent),
|
116
|
+
isWebkit: !isEdge && /webkit/i.test(userAgent),
|
117
|
+
isChrome: !isEdge && /chrome/i.test(userAgent),
|
118
|
+
isSafari: !isEdge && /safari/i.test(userAgent),
|
119
|
+
browserVersion: browserVersion,
|
120
|
+
jqueryVersion: parseFloat($.fn.jquery),
|
121
|
+
isSupportAmd: isSupportAmd,
|
122
|
+
isSupportTouch: isSupportTouch,
|
123
|
+
hasCodeMirror: hasCodeMirror,
|
124
|
+
isFontInstalled: isFontInstalled,
|
125
|
+
isW3CRangeSupport: !!document.createRange
|
126
|
+
};
|
127
|
+
|
26
128
|
/**
|
27
129
|
* @class core.func
|
28
130
|
*
|
@@ -382,88 +484,6 @@
|
|
382
484
|
clusterBy: clusterBy, compact: compact, unique: unique };
|
383
485
|
})();
|
384
486
|
|
385
|
-
var isSupportAmd = typeof define === 'function' && define.amd;
|
386
|
-
|
387
|
-
/**
|
388
|
-
* returns whether font is installed or not.
|
389
|
-
*
|
390
|
-
* @param {String} fontName
|
391
|
-
* @return {Boolean}
|
392
|
-
*/
|
393
|
-
var isFontInstalled = function (fontName) {
|
394
|
-
var testFontName = fontName === 'Comic Sans MS' ? 'Courier New' : 'Comic Sans MS';
|
395
|
-
var $tester = $('<div>').css({
|
396
|
-
position: 'absolute',
|
397
|
-
left: '-9999px',
|
398
|
-
top: '-9999px',
|
399
|
-
fontSize: '200px'
|
400
|
-
}).text('mmmmmmmmmwwwwwww').appendTo(document.body);
|
401
|
-
|
402
|
-
var originalWidth = $tester.css('fontFamily', testFontName).width();
|
403
|
-
var width = $tester.css('fontFamily', fontName + ',' + testFontName).width();
|
404
|
-
|
405
|
-
$tester.remove();
|
406
|
-
|
407
|
-
return originalWidth !== width;
|
408
|
-
};
|
409
|
-
|
410
|
-
var userAgent = navigator.userAgent;
|
411
|
-
var isMSIE = /MSIE|Trident/i.test(userAgent);
|
412
|
-
var browserVersion;
|
413
|
-
if (isMSIE) {
|
414
|
-
var matches = /MSIE (\d+[.]\d+)/.exec(userAgent);
|
415
|
-
if (matches) {
|
416
|
-
browserVersion = parseFloat(matches[1]);
|
417
|
-
}
|
418
|
-
matches = /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
|
419
|
-
if (matches) {
|
420
|
-
browserVersion = parseFloat(matches[1]);
|
421
|
-
}
|
422
|
-
}
|
423
|
-
|
424
|
-
var isEdge = /Edge\/\d+/.test(userAgent);
|
425
|
-
|
426
|
-
var hasCodeMirror = !!window.CodeMirror;
|
427
|
-
if (!hasCodeMirror && isSupportAmd && typeof require !== 'undefined') {
|
428
|
-
if (typeof require.resolve !== 'undefined') {
|
429
|
-
try {
|
430
|
-
// If CodeMirror can't be resolved, `require.resolve` will throw an
|
431
|
-
// exception and `hasCodeMirror` won't be set to `true`.
|
432
|
-
require.resolve('codemirror');
|
433
|
-
hasCodeMirror = true;
|
434
|
-
} catch (e) {
|
435
|
-
// Do nothing.
|
436
|
-
}
|
437
|
-
} else if (typeof eval('require').specified !== 'undefined') {
|
438
|
-
hasCodeMirror = eval('require').specified('codemirror');
|
439
|
-
}
|
440
|
-
}
|
441
|
-
|
442
|
-
/**
|
443
|
-
* @class core.agent
|
444
|
-
*
|
445
|
-
* Object which check platform and agent
|
446
|
-
*
|
447
|
-
* @singleton
|
448
|
-
* @alternateClassName agent
|
449
|
-
*/
|
450
|
-
var agent = {
|
451
|
-
isMac: navigator.appVersion.indexOf('Mac') > -1,
|
452
|
-
isMSIE: isMSIE,
|
453
|
-
isEdge: isEdge,
|
454
|
-
isFF: !isEdge && /firefox/i.test(userAgent),
|
455
|
-
isPhantom: /PhantomJS/i.test(userAgent),
|
456
|
-
isWebkit: !isEdge && /webkit/i.test(userAgent),
|
457
|
-
isChrome: !isEdge && /chrome/i.test(userAgent),
|
458
|
-
isSafari: !isEdge && /safari/i.test(userAgent),
|
459
|
-
browserVersion: browserVersion,
|
460
|
-
jqueryVersion: parseFloat($.fn.jquery),
|
461
|
-
isSupportAmd: isSupportAmd,
|
462
|
-
hasCodeMirror: hasCodeMirror,
|
463
|
-
isFontInstalled: isFontInstalled,
|
464
|
-
isW3CRangeSupport: !!document.createRange
|
465
|
-
};
|
466
|
-
|
467
487
|
|
468
488
|
var NBSP_CHAR = String.fromCharCode(160);
|
469
489
|
var ZERO_WIDTH_NBSP_CHAR = '\ufeff';
|
@@ -545,7 +565,7 @@
|
|
545
565
|
* @see http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
|
546
566
|
*/
|
547
567
|
var isVoid = function (node) {
|
548
|
-
return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON/.test(node.nodeName.toUpperCase());
|
568
|
+
return node && /^BR|^IMG|^HR|^IFRAME|^BUTTON|^INPUT/.test(node.nodeName.toUpperCase());
|
549
569
|
};
|
550
570
|
|
551
571
|
var isPara = function (node) {
|
@@ -1455,6 +1475,18 @@
|
|
1455
1475
|
});
|
1456
1476
|
};
|
1457
1477
|
|
1478
|
+
/**
|
1479
|
+
* @method isCustomStyleTag
|
1480
|
+
*
|
1481
|
+
* assert if a node contains a "note-styletag" class,
|
1482
|
+
* which implies that's a custom-made style tag node
|
1483
|
+
*
|
1484
|
+
* @param {Node} an HTML DOM node
|
1485
|
+
*/
|
1486
|
+
var isCustomStyleTag = function (node) {
|
1487
|
+
return node && !dom.isText(node) && list.contains(node.classList, 'note-styletag');
|
1488
|
+
};
|
1489
|
+
|
1458
1490
|
return {
|
1459
1491
|
/** @property {String} NBSP_CHAR */
|
1460
1492
|
NBSP_CHAR: NBSP_CHAR,
|
@@ -1542,7 +1574,8 @@
|
|
1542
1574
|
value: value,
|
1543
1575
|
posFromPlaceholder: posFromPlaceholder,
|
1544
1576
|
attachEvents: attachEvents,
|
1545
|
-
detachEvents: detachEvents
|
1577
|
+
detachEvents: detachEvents,
|
1578
|
+
isCustomStyleTag: isCustomStyleTag
|
1546
1579
|
};
|
1547
1580
|
})();
|
1548
1581
|
|
@@ -1649,6 +1682,7 @@
|
|
1649
1682
|
this.enable = function () {
|
1650
1683
|
this.layoutInfo.editable.attr('contenteditable', true);
|
1651
1684
|
this.invoke('toolbar.activate', true);
|
1685
|
+
this.triggerEvent('disable', false);
|
1652
1686
|
};
|
1653
1687
|
|
1654
1688
|
this.disable = function () {
|
@@ -1658,6 +1692,8 @@
|
|
1658
1692
|
}
|
1659
1693
|
this.layoutInfo.editable.attr('contenteditable', false);
|
1660
1694
|
this.invoke('toolbar.deactivate', true);
|
1695
|
+
|
1696
|
+
this.triggerEvent('disable', true);
|
1661
1697
|
};
|
1662
1698
|
|
1663
1699
|
this.triggerEvent = function () {
|
@@ -1731,10 +1767,21 @@
|
|
1731
1767
|
delete this.memos[key];
|
1732
1768
|
};
|
1733
1769
|
|
1770
|
+
/**
|
1771
|
+
*Some buttons need to change their visual style immediately once they get pressed
|
1772
|
+
*/
|
1773
|
+
this.createInvokeHandlerAndUpdateState = function (namespace, value) {
|
1774
|
+
return function (event) {
|
1775
|
+
self.createInvokeHandler(namespace, value)(event);
|
1776
|
+
self.invoke('buttons.updateCurrentStyle');
|
1777
|
+
};
|
1778
|
+
};
|
1779
|
+
|
1734
1780
|
this.createInvokeHandler = function (namespace, value) {
|
1735
1781
|
return function (event) {
|
1736
1782
|
event.preventDefault();
|
1737
|
-
|
1783
|
+
var $target = $(event.target);
|
1784
|
+
self.invoke(namespace, value || $target.closest('[data-value]').data('value'), $target);
|
1738
1785
|
};
|
1739
1786
|
};
|
1740
1787
|
|
@@ -1773,8 +1820,11 @@
|
|
1773
1820
|
var options = hasInitOptions ? list.head(arguments) : {};
|
1774
1821
|
|
1775
1822
|
options = $.extend({}, $.summernote.options, options);
|
1823
|
+
|
1824
|
+
// Update options
|
1776
1825
|
options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);
|
1777
1826
|
options.icons = $.extend(true, {}, $.summernote.options.icons, options.icons);
|
1827
|
+
options.tooltip = options.tooltip === 'auto' ? !agent.isSupportTouch : options.tooltip;
|
1778
1828
|
|
1779
1829
|
this.each(function (idx, note) {
|
1780
1830
|
var $note = $(note);
|
@@ -1877,28 +1927,25 @@
|
|
1877
1927
|
var airEditable = renderer.create('<div class="note-editable" contentEditable="true"/>');
|
1878
1928
|
|
1879
1929
|
var buttonGroup = renderer.create('<div class="note-btn-group btn-group">');
|
1880
|
-
var button = renderer.create('<button type="button" class="note-btn btn btn-default btn-sm" tabindex="-1">', function ($node, options) {
|
1881
|
-
if (options && options.tooltip) {
|
1882
|
-
$node.attr({
|
1883
|
-
title: options.tooltip
|
1884
|
-
}).tooltip({
|
1885
|
-
container: 'body',
|
1886
|
-
trigger: 'hover',
|
1887
|
-
placement: 'bottom'
|
1888
|
-
});
|
1889
|
-
}
|
1890
|
-
});
|
1891
1930
|
|
1892
1931
|
var dropdown = renderer.create('<div class="dropdown-menu">', function ($node, options) {
|
1893
1932
|
var markup = $.isArray(options.items) ? options.items.map(function (item) {
|
1894
1933
|
var value = (typeof item === 'string') ? item : (item.value || '');
|
1895
1934
|
var content = options.template ? options.template(item) : item;
|
1896
|
-
|
1935
|
+
var option = (typeof item === 'object') ? item.option : undefined;
|
1936
|
+
|
1937
|
+
var dataValue = 'data-value="' + value + '"';
|
1938
|
+
var dataOption = (option !== undefined) ? ' data-option="' + option + '"' : '';
|
1939
|
+
return '<li><a href="#" ' + (dataValue + dataOption) + '>' + content + '</a></li>';
|
1897
1940
|
}).join('') : options.items;
|
1898
1941
|
|
1899
1942
|
$node.html(markup);
|
1900
1943
|
});
|
1901
1944
|
|
1945
|
+
var dropdownButtonContents = function (contents, options) {
|
1946
|
+
return contents + ' ' + icon(options.icons.caret, 'span');
|
1947
|
+
};
|
1948
|
+
|
1902
1949
|
var dropdownCheck = renderer.create('<div class="dropdown-menu note-check">', function ($node, options) {
|
1903
1950
|
var markup = $.isArray(options.items) ? options.items.map(function (item) {
|
1904
1951
|
var value = (typeof item === 'string') ? item : (item.value || '');
|
@@ -1929,11 +1976,13 @@
|
|
1929
1976
|
}
|
1930
1977
|
$node.html(contents.join(''));
|
1931
1978
|
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1979
|
+
if (options.tooltip) {
|
1980
|
+
$node.find('.note-color-btn').tooltip({
|
1981
|
+
container: 'body',
|
1982
|
+
trigger: 'hover',
|
1983
|
+
placement: 'bottom'
|
1984
|
+
});
|
1985
|
+
}
|
1937
1986
|
});
|
1938
1987
|
|
1939
1988
|
var dialog = renderer.create('<div class="modal" aria-hidden="false" tabindex="-1"/>', function ($node, options) {
|
@@ -1973,6 +2022,16 @@
|
|
1973
2022
|
}
|
1974
2023
|
});
|
1975
2024
|
|
2025
|
+
var checkbox = renderer.create('<div class="checkbox"></div>', function ($node, options) {
|
2026
|
+
$node.html([
|
2027
|
+
' <label' + (options.id ? ' for="' + options.id + '"' : '') + '>',
|
2028
|
+
' <input type="checkbox"' + (options.id ? ' id="' + options.id + '"' : ''),
|
2029
|
+
(options.checked ? ' checked' : '') + '/>',
|
2030
|
+
(options.text ? options.text : ''),
|
2031
|
+
'</label>'
|
2032
|
+
].join(''));
|
2033
|
+
});
|
2034
|
+
|
1976
2035
|
var icon = function (iconClassName, tagName) {
|
1977
2036
|
tagName = tagName || 'i';
|
1978
2037
|
return '<' + tagName + ' class="' + iconClassName + '"/>';
|
@@ -1988,13 +2047,29 @@
|
|
1988
2047
|
airEditor: airEditor,
|
1989
2048
|
airEditable: airEditable,
|
1990
2049
|
buttonGroup: buttonGroup,
|
1991
|
-
button: button,
|
1992
2050
|
dropdown: dropdown,
|
2051
|
+
dropdownButtonContents: dropdownButtonContents,
|
1993
2052
|
dropdownCheck: dropdownCheck,
|
1994
2053
|
palette: palette,
|
1995
2054
|
dialog: dialog,
|
1996
2055
|
popover: popover,
|
2056
|
+
checkbox: checkbox,
|
1997
2057
|
icon: icon,
|
2058
|
+
options: {},
|
2059
|
+
|
2060
|
+
button: function ($node, options) {
|
2061
|
+
return renderer.create('<button type="button" class="note-btn btn btn-default btn-sm" tabindex="-1">', function ($node, options) {
|
2062
|
+
if (options && options.tooltip && self.options.tooltip) {
|
2063
|
+
$node.attr({
|
2064
|
+
title: options.tooltip
|
2065
|
+
}).tooltip({
|
2066
|
+
container: 'body',
|
2067
|
+
trigger: 'hover',
|
2068
|
+
placement: 'bottom'
|
2069
|
+
});
|
2070
|
+
}
|
2071
|
+
})($node, options);
|
2072
|
+
},
|
1998
2073
|
|
1999
2074
|
toggleBtn: function ($btn, isEnable) {
|
2000
2075
|
$btn.toggleClass('disabled', !isEnable);
|
@@ -2022,6 +2097,7 @@
|
|
2022
2097
|
},
|
2023
2098
|
|
2024
2099
|
createLayout: function ($note, options) {
|
2100
|
+
self.options = options;
|
2025
2101
|
var $editor = (options.airMode ? ui.airEditor([
|
2026
2102
|
ui.editingArea([
|
2027
2103
|
ui.airEditable()
|
@@ -2111,7 +2187,14 @@
|
|
2111
2187
|
openInNewWindow: 'Open in new window'
|
2112
2188
|
},
|
2113
2189
|
table: {
|
2114
|
-
table: 'Table'
|
2190
|
+
table: 'Table',
|
2191
|
+
addRowAbove: 'Add row above',
|
2192
|
+
addRowBelow: 'Add row below',
|
2193
|
+
addColLeft: 'Add column left',
|
2194
|
+
addColRight: 'Add column right',
|
2195
|
+
delRow: 'Delete row',
|
2196
|
+
delCol: 'Delete column',
|
2197
|
+
delTable: 'Delete table'
|
2115
2198
|
},
|
2116
2199
|
hr: {
|
2117
2200
|
insert: 'Insert Horizontal Rule'
|
@@ -2220,6 +2303,7 @@
|
|
2220
2303
|
'TAB': 9,
|
2221
2304
|
'ENTER': 13,
|
2222
2305
|
'SPACE': 32,
|
2306
|
+
'DELETE': 46,
|
2223
2307
|
|
2224
2308
|
// Arrow
|
2225
2309
|
'LEFT': 37,
|
@@ -2270,7 +2354,8 @@
|
|
2270
2354
|
keyMap.BACKSPACE,
|
2271
2355
|
keyMap.TAB,
|
2272
2356
|
keyMap.ENTER,
|
2273
|
-
keyMap.SPACE
|
2357
|
+
keyMap.SPACE,
|
2358
|
+
keyMap.DELETE
|
2274
2359
|
], keyCode);
|
2275
2360
|
},
|
2276
2361
|
/**
|
@@ -3385,7 +3470,8 @@
|
|
3385
3470
|
'font-underline': document.queryCommandState('underline') ? 'underline' : 'normal',
|
3386
3471
|
'font-subscript': document.queryCommandState('subscript') ? 'subscript' : 'normal',
|
3387
3472
|
'font-superscript': document.queryCommandState('superscript') ? 'superscript' : 'normal',
|
3388
|
-
'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal'
|
3473
|
+
'font-strikethrough': document.queryCommandState('strikethrough') ? 'strikethrough' : 'normal',
|
3474
|
+
'font-family': document.queryCommandValue('fontname') || styleInfo['font-family']
|
3389
3475
|
});
|
3390
3476
|
} catch (e) {}
|
3391
3477
|
|
@@ -3687,8 +3773,8 @@
|
|
3687
3773
|
dom.remove(anchor);
|
3688
3774
|
});
|
3689
3775
|
|
3690
|
-
// replace empty heading or
|
3691
|
-
if ((dom.isHeading(nextPara) || dom.isPre(nextPara)) && dom.isEmpty(nextPara)) {
|
3776
|
+
// replace empty heading, pre or custom-made styleTag with P tag
|
3777
|
+
if ((dom.isHeading(nextPara) || dom.isPre(nextPara) || dom.isCustomStyleTag(nextPara)) && dom.isEmpty(nextPara)) {
|
3692
3778
|
nextPara = dom.replace(nextPara, 'p');
|
3693
3779
|
}
|
3694
3780
|
}
|
@@ -3707,62 +3793,581 @@
|
|
3707
3793
|
};
|
3708
3794
|
};
|
3709
3795
|
|
3796
|
+
|
3710
3797
|
/**
|
3711
|
-
* @class
|
3712
|
-
*
|
3713
|
-
*
|
3714
|
-
*
|
3798
|
+
* @class Create a virtual table to create what actions to do in change.
|
3799
|
+
* @param {object} startPoint Cell selected to apply change.
|
3800
|
+
* @param {enum} where Where change will be applied Row or Col. Use enum: TableResultAction.where
|
3801
|
+
* @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction
|
3802
|
+
* @param {object} domTable Dom element of table to make changes.
|
3715
3803
|
*/
|
3716
|
-
var
|
3804
|
+
var TableResultAction = function (startPoint, where, action, domTable) {
|
3805
|
+
var _startPoint = { 'colPos': 0, 'rowPos': 0 };
|
3806
|
+
var _virtualTable = [];
|
3807
|
+
var _actionCellList = [];
|
3808
|
+
|
3809
|
+
//////////////////////////////////////////////
|
3810
|
+
// Private functions
|
3811
|
+
//////////////////////////////////////////////
|
3812
|
+
|
3717
3813
|
/**
|
3718
|
-
*
|
3719
|
-
*
|
3720
|
-
* @param {WrappedRange} rng
|
3721
|
-
* @param {Boolean} isShift
|
3814
|
+
* Set the startPoint of action.
|
3722
3815
|
*/
|
3723
|
-
|
3724
|
-
|
3725
|
-
|
3726
|
-
|
3816
|
+
function setStartPoint() {
|
3817
|
+
if (!startPoint || !startPoint.tagName || (startPoint.tagName.toLowerCase() !== 'td' && startPoint.tagName.toLowerCase() !== 'th')) {
|
3818
|
+
console.error('Impossible to identify start Cell point.', startPoint);
|
3819
|
+
return;
|
3820
|
+
}
|
3821
|
+
_startPoint.colPos = startPoint.cellIndex;
|
3822
|
+
if (!startPoint.parentElement || !startPoint.parentElement.tagName || startPoint.parentElement.tagName.toLowerCase() !== 'tr') {
|
3823
|
+
console.error('Impossible to identify start Row point.', startPoint);
|
3824
|
+
return;
|
3825
|
+
}
|
3826
|
+
_startPoint.rowPos = startPoint.parentElement.rowIndex;
|
3827
|
+
}
|
3727
3828
|
|
3728
|
-
|
3729
|
-
|
3730
|
-
|
3829
|
+
/**
|
3830
|
+
* Define virtual table position info object.
|
3831
|
+
*
|
3832
|
+
* @param {int} rowIndex Index position in line of virtual table.
|
3833
|
+
* @param {int} cellIndex Index position in column of virtual table.
|
3834
|
+
* @param {object} baseRow Row affected by this position.
|
3835
|
+
* @param {object} baseCell Cell affected by this position.
|
3836
|
+
* @param {bool} isSpan Inform if it is an span cell/row.
|
3837
|
+
*/
|
3838
|
+
function setVirtualTablePosition(rowIndex, cellIndex, baseRow, baseCell, isRowSpan, isColSpan, isVirtualCell) {
|
3839
|
+
var objPosition = {
|
3840
|
+
'baseRow': baseRow,
|
3841
|
+
'baseCell': baseCell,
|
3842
|
+
'isRowSpan': isRowSpan,
|
3843
|
+
'isColSpan': isColSpan,
|
3844
|
+
'isVirtual': isVirtualCell
|
3845
|
+
};
|
3846
|
+
if (!_virtualTable[rowIndex]) {
|
3847
|
+
_virtualTable[rowIndex] = [];
|
3731
3848
|
}
|
3732
|
-
|
3849
|
+
_virtualTable[rowIndex][cellIndex] = objPosition;
|
3850
|
+
}
|
3733
3851
|
|
3734
3852
|
/**
|
3735
|
-
*
|
3736
|
-
*
|
3737
|
-
* @param {
|
3738
|
-
* @param {
|
3739
|
-
* @return {Node}
|
3853
|
+
* Create action cell object.
|
3854
|
+
*
|
3855
|
+
* @param {object} virtualTableCellObj Object of specific position on virtual table.
|
3856
|
+
* @param {enum} resultAction Action to be applied in that item.
|
3740
3857
|
*/
|
3741
|
-
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
3745
|
-
|
3746
|
-
|
3858
|
+
function getActionCell(virtualTableCellObj, resultAction, virtualRowPosition, virtualColPosition) {
|
3859
|
+
return {
|
3860
|
+
'baseCell': virtualTableCellObj.baseCell,
|
3861
|
+
'action': resultAction,
|
3862
|
+
'virtualTable': {
|
3863
|
+
'rowIndex': virtualRowPosition,
|
3864
|
+
'cellIndex': virtualColPosition
|
3865
|
+
}
|
3866
|
+
};
|
3867
|
+
}
|
3747
3868
|
|
3748
|
-
|
3749
|
-
|
3750
|
-
|
3869
|
+
/**
|
3870
|
+
* Recover free index of row to append Cell.
|
3871
|
+
*
|
3872
|
+
* @param {int} rowIndex Index of row to find free space.
|
3873
|
+
* @param {int} cellIndex Index of cell to find free space in table.
|
3874
|
+
*/
|
3875
|
+
function recoverCellIndex(rowIndex, cellIndex) {
|
3876
|
+
if (!_virtualTable[rowIndex]) {
|
3877
|
+
return cellIndex;
|
3751
3878
|
}
|
3752
|
-
|
3753
|
-
|
3754
|
-
if (options && options.tableClassName) {
|
3755
|
-
$table.addClass(options.tableClassName);
|
3879
|
+
if (!_virtualTable[rowIndex][cellIndex]) {
|
3880
|
+
return cellIndex;
|
3756
3881
|
}
|
3757
3882
|
|
3758
|
-
|
3759
|
-
|
3760
|
-
|
3883
|
+
var newCellIndex = cellIndex;
|
3884
|
+
while (_virtualTable[rowIndex][newCellIndex]) {
|
3885
|
+
newCellIndex++;
|
3886
|
+
if (!_virtualTable[rowIndex][newCellIndex]) {
|
3887
|
+
return newCellIndex;
|
3888
|
+
}
|
3889
|
+
}
|
3890
|
+
}
|
3761
3891
|
|
3892
|
+
/**
|
3893
|
+
* Recover info about row and cell and add information to virtual table.
|
3894
|
+
*
|
3895
|
+
* @param {object} row Row to recover information.
|
3896
|
+
* @param {object} cell Cell to recover information.
|
3897
|
+
*/
|
3898
|
+
function addCellInfoToVirtual(row, cell) {
|
3899
|
+
var cellIndex = recoverCellIndex(row.rowIndex, cell.cellIndex);
|
3900
|
+
var cellHasColspan = (cell.colSpan > 1);
|
3901
|
+
var cellHasRowspan = (cell.rowSpan > 1);
|
3902
|
+
var isThisSelectedCell = (row.rowIndex === _startPoint.rowPos && cell.cellIndex === _startPoint.colPos);
|
3903
|
+
setVirtualTablePosition(row.rowIndex, cellIndex, row, cell, cellHasRowspan, cellHasColspan, false);
|
3904
|
+
|
3905
|
+
// Add span rows to virtual Table.
|
3906
|
+
var rowspanNumber = cell.attributes.rowSpan ? parseInt(cell.attributes.rowSpan.value, 10) : 0;
|
3907
|
+
if (rowspanNumber > 1) {
|
3908
|
+
for (var rp = 1; rp < rowspanNumber; rp++) {
|
3909
|
+
var rowspanIndex = row.rowIndex + rp;
|
3910
|
+
adjustStartPoint(rowspanIndex, cellIndex, cell, isThisSelectedCell);
|
3911
|
+
setVirtualTablePosition(rowspanIndex, cellIndex, row, cell, true, cellHasColspan, true);
|
3912
|
+
}
|
3913
|
+
}
|
3762
3914
|
|
3763
|
-
|
3915
|
+
// Add span cols to virtual table.
|
3916
|
+
var colspanNumber = cell.attributes.colSpan ? parseInt(cell.attributes.colSpan.value, 10) : 0;
|
3917
|
+
if (colspanNumber > 1) {
|
3918
|
+
for (var cp = 1; cp < colspanNumber; cp++) {
|
3919
|
+
var cellspanIndex = recoverCellIndex(row.rowIndex, (cellIndex + cp));
|
3920
|
+
adjustStartPoint(row.rowIndex, cellspanIndex, cell, isThisSelectedCell);
|
3921
|
+
setVirtualTablePosition(row.rowIndex, cellspanIndex, row, cell, cellHasRowspan, true, true);
|
3922
|
+
}
|
3923
|
+
}
|
3924
|
+
}
|
3764
3925
|
|
3765
|
-
|
3926
|
+
/**
|
3927
|
+
* Process validation and adjust of start point if needed
|
3928
|
+
*
|
3929
|
+
* @param {int} rowIndex
|
3930
|
+
* @param {int} cellIndex
|
3931
|
+
* @param {object} cell
|
3932
|
+
* @param {bool} isSelectedCell
|
3933
|
+
*/
|
3934
|
+
function adjustStartPoint(rowIndex, cellIndex, cell, isSelectedCell) {
|
3935
|
+
if (rowIndex === _startPoint.rowPos && _startPoint.colPos >= cell.cellIndex && cell.cellIndex <= cellIndex && !isSelectedCell) {
|
3936
|
+
_startPoint.colPos++;
|
3937
|
+
}
|
3938
|
+
}
|
3939
|
+
|
3940
|
+
/**
|
3941
|
+
* Create virtual table of cells with all cells, including span cells.
|
3942
|
+
*/
|
3943
|
+
function createVirtualTable() {
|
3944
|
+
var rows = domTable.rows;
|
3945
|
+
for (var rowIndex = 0; rowIndex < rows.length; rowIndex++) {
|
3946
|
+
var cells = rows[rowIndex].cells;
|
3947
|
+
for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) {
|
3948
|
+
addCellInfoToVirtual(rows[rowIndex], cells[cellIndex]);
|
3949
|
+
}
|
3950
|
+
}
|
3951
|
+
}
|
3952
|
+
|
3953
|
+
/**
|
3954
|
+
* Get action to be applied on the cell.
|
3955
|
+
*
|
3956
|
+
* @param {object} cell virtual table cell to apply action
|
3957
|
+
*/
|
3958
|
+
function getDeleteResultActionToCell(cell) {
|
3959
|
+
switch (where) {
|
3960
|
+
case TableResultAction.where.Column:
|
3961
|
+
if (cell.isColSpan) {
|
3962
|
+
return TableResultAction.resultAction.SubtractSpanCount;
|
3963
|
+
}
|
3964
|
+
break;
|
3965
|
+
case TableResultAction.where.Row:
|
3966
|
+
if (!cell.isVirtual && cell.isRowSpan) {
|
3967
|
+
return TableResultAction.resultAction.AddCell;
|
3968
|
+
}
|
3969
|
+
else if (cell.isRowSpan) {
|
3970
|
+
return TableResultAction.resultAction.SubtractSpanCount;
|
3971
|
+
}
|
3972
|
+
break;
|
3973
|
+
}
|
3974
|
+
return TableResultAction.resultAction.RemoveCell;
|
3975
|
+
}
|
3976
|
+
|
3977
|
+
/**
|
3978
|
+
* Get action to be applied on the cell.
|
3979
|
+
*
|
3980
|
+
* @param {object} cell virtual table cell to apply action
|
3981
|
+
*/
|
3982
|
+
function getAddResultActionToCell(cell) {
|
3983
|
+
switch (where) {
|
3984
|
+
case TableResultAction.where.Column:
|
3985
|
+
if (cell.isColSpan) {
|
3986
|
+
return TableResultAction.resultAction.SumSpanCount;
|
3987
|
+
} else if (cell.isRowSpan && cell.isVirtual) {
|
3988
|
+
return TableResultAction.resultAction.Ignore;
|
3989
|
+
}
|
3990
|
+
break;
|
3991
|
+
case TableResultAction.where.Row:
|
3992
|
+
if (cell.isRowSpan) {
|
3993
|
+
return TableResultAction.resultAction.SumSpanCount;
|
3994
|
+
} else if (cell.isColSpan && cell.isVirtual) {
|
3995
|
+
return TableResultAction.resultAction.Ignore;
|
3996
|
+
}
|
3997
|
+
break;
|
3998
|
+
}
|
3999
|
+
return TableResultAction.resultAction.AddCell;
|
4000
|
+
}
|
4001
|
+
|
4002
|
+
function init() {
|
4003
|
+
setStartPoint();
|
4004
|
+
createVirtualTable();
|
4005
|
+
}
|
4006
|
+
|
4007
|
+
//////////////////////////////////////////////
|
4008
|
+
// Public functions
|
4009
|
+
//////////////////////////////////////////////
|
4010
|
+
|
4011
|
+
/**
|
4012
|
+
* Recover array os what to do in table.
|
4013
|
+
*/
|
4014
|
+
this.getActionList = function () {
|
4015
|
+
var fixedRow = (where === TableResultAction.where.Row) ? _startPoint.rowPos : -1;
|
4016
|
+
var fixedCol = (where === TableResultAction.where.Column) ? _startPoint.colPos : -1;
|
4017
|
+
|
4018
|
+
var actualPosition = 0;
|
4019
|
+
var canContinue = true;
|
4020
|
+
while (canContinue) {
|
4021
|
+
var rowPosition = (fixedRow >= 0) ? fixedRow : actualPosition;
|
4022
|
+
var colPosition = (fixedCol >= 0) ? fixedCol : actualPosition;
|
4023
|
+
var row = _virtualTable[rowPosition];
|
4024
|
+
if (!row) {
|
4025
|
+
canContinue = false;
|
4026
|
+
return _actionCellList;
|
4027
|
+
}
|
4028
|
+
var cell = row[colPosition];
|
4029
|
+
if (!cell) {
|
4030
|
+
canContinue = false;
|
4031
|
+
return _actionCellList;
|
4032
|
+
}
|
4033
|
+
|
4034
|
+
// Define action to be applied in this cell
|
4035
|
+
var resultAction = TableResultAction.resultAction.Ignore;
|
4036
|
+
switch (action) {
|
4037
|
+
case TableResultAction.requestAction.Add:
|
4038
|
+
resultAction = getAddResultActionToCell(cell);
|
4039
|
+
break;
|
4040
|
+
case TableResultAction.requestAction.Delete:
|
4041
|
+
resultAction = getDeleteResultActionToCell(cell);
|
4042
|
+
break;
|
4043
|
+
}
|
4044
|
+
_actionCellList.push(getActionCell(cell, resultAction, rowPosition, colPosition));
|
4045
|
+
actualPosition++;
|
4046
|
+
}
|
4047
|
+
|
4048
|
+
return _actionCellList;
|
4049
|
+
};
|
4050
|
+
|
4051
|
+
init();
|
4052
|
+
};
|
4053
|
+
/**
|
4054
|
+
*
|
4055
|
+
* Where action occours enum.
|
4056
|
+
*/
|
4057
|
+
TableResultAction.where = { 'Row': 0, 'Column': 1 };
|
4058
|
+
/**
|
4059
|
+
*
|
4060
|
+
* Requested action to apply enum.
|
4061
|
+
*/
|
4062
|
+
TableResultAction.requestAction = { 'Add': 0, 'Delete': 1 };
|
4063
|
+
/**
|
4064
|
+
*
|
4065
|
+
* Result action to be executed enum.
|
4066
|
+
*/
|
4067
|
+
TableResultAction.resultAction = { 'Ignore': 0, 'SubtractSpanCount': 1, 'RemoveCell': 2, 'AddCell': 3, 'SumSpanCount': 4 };
|
4068
|
+
|
4069
|
+
/**
|
4070
|
+
*
|
4071
|
+
* @class editing.Table
|
4072
|
+
*
|
4073
|
+
* Table
|
4074
|
+
*
|
4075
|
+
*/
|
4076
|
+
var Table = function () {
|
4077
|
+
/**
|
4078
|
+
* handle tab key
|
4079
|
+
*
|
4080
|
+
* @param {WrappedRange} rng
|
4081
|
+
* @param {Boolean} isShift
|
4082
|
+
*/
|
4083
|
+
this.tab = function (rng, isShift) {
|
4084
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4085
|
+
var table = dom.ancestor(cell, dom.isTable);
|
4086
|
+
var cells = dom.listDescendant(table, dom.isCell);
|
4087
|
+
|
4088
|
+
var nextCell = list[isShift ? 'prev' : 'next'](cells, cell);
|
4089
|
+
if (nextCell) {
|
4090
|
+
range.create(nextCell, 0).select();
|
4091
|
+
}
|
4092
|
+
};
|
4093
|
+
|
4094
|
+
/**
|
4095
|
+
* Add a new row
|
4096
|
+
*
|
4097
|
+
* @param {WrappedRange} rng
|
4098
|
+
* @param {String} position (top/bottom)
|
4099
|
+
* @return {Node}
|
4100
|
+
*/
|
4101
|
+
this.addRow = function (rng, position) {
|
4102
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4103
|
+
|
4104
|
+
var currentTr = $(cell).closest('tr');
|
4105
|
+
var trAttributes = this.recoverAttributes(currentTr);
|
4106
|
+
var html = $('<tr' + trAttributes + '></tr>');
|
4107
|
+
|
4108
|
+
var vTable = new TableResultAction(cell, TableResultAction.where.Row,
|
4109
|
+
TableResultAction.requestAction.Add, $(currentTr).closest('table')[0]);
|
4110
|
+
var actions = vTable.getActionList();
|
4111
|
+
|
4112
|
+
for (var idCell = 0; idCell < actions.length; idCell++) {
|
4113
|
+
var currentCell = actions[idCell];
|
4114
|
+
var tdAttributes = this.recoverAttributes(currentCell.baseCell);
|
4115
|
+
switch (currentCell.action) {
|
4116
|
+
case TableResultAction.resultAction.AddCell:
|
4117
|
+
html.append('<td' + tdAttributes + '>' + dom.blank + '</td>');
|
4118
|
+
break;
|
4119
|
+
case TableResultAction.resultAction.SumSpanCount:
|
4120
|
+
if (position === 'top') {
|
4121
|
+
var baseCellTr = currentCell.baseCell.parent;
|
4122
|
+
var isTopFromRowSpan = (!baseCellTr ? 0 : currentCell.baseCell.closest('tr').rowIndex) <= currentTr[0].rowIndex;
|
4123
|
+
if (isTopFromRowSpan) {
|
4124
|
+
var newTd = $('<div></div>').append($('<td' + tdAttributes + '>' + dom.blank + '</td>').removeAttr('rowspan')).html();
|
4125
|
+
html.append(newTd);
|
4126
|
+
break;
|
4127
|
+
}
|
4128
|
+
}
|
4129
|
+
var rowspanNumber = parseInt(currentCell.baseCell.rowSpan, 10);
|
4130
|
+
rowspanNumber++;
|
4131
|
+
currentCell.baseCell.setAttribute('rowSpan', rowspanNumber);
|
4132
|
+
break;
|
4133
|
+
}
|
4134
|
+
}
|
4135
|
+
|
4136
|
+
if (position === 'top') {
|
4137
|
+
currentTr.before(html);
|
4138
|
+
}
|
4139
|
+
else {
|
4140
|
+
var cellHasRowspan = (cell.rowSpan > 1);
|
4141
|
+
if (cellHasRowspan) {
|
4142
|
+
var lastTrIndex = currentTr[0].rowIndex + (cell.rowSpan - 2);
|
4143
|
+
$($(currentTr).parent().find('tr')[lastTrIndex]).after($(html));
|
4144
|
+
return;
|
4145
|
+
}
|
4146
|
+
currentTr.after(html);
|
4147
|
+
}
|
4148
|
+
};
|
4149
|
+
|
4150
|
+
/**
|
4151
|
+
* Add a new col
|
4152
|
+
*
|
4153
|
+
* @param {WrappedRange} rng
|
4154
|
+
* @param {String} position (left/right)
|
4155
|
+
* @return {Node}
|
4156
|
+
*/
|
4157
|
+
this.addCol = function (rng, position) {
|
4158
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4159
|
+
var row = $(cell).closest('tr');
|
4160
|
+
var rowsGroup = $(row).siblings();
|
4161
|
+
rowsGroup.push(row);
|
4162
|
+
|
4163
|
+
var vTable = new TableResultAction(cell, TableResultAction.where.Column,
|
4164
|
+
TableResultAction.requestAction.Add, $(row).closest('table')[0]);
|
4165
|
+
var actions = vTable.getActionList();
|
4166
|
+
|
4167
|
+
for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
|
4168
|
+
var currentCell = actions[actionIndex];
|
4169
|
+
var tdAttributes = this.recoverAttributes(currentCell.baseCell);
|
4170
|
+
switch (currentCell.action) {
|
4171
|
+
case TableResultAction.resultAction.AddCell:
|
4172
|
+
if (position === 'right') {
|
4173
|
+
$(currentCell.baseCell).after('<td' + tdAttributes + '>' + dom.blank + '</td>');
|
4174
|
+
} else {
|
4175
|
+
$(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');
|
4176
|
+
}
|
4177
|
+
break;
|
4178
|
+
case TableResultAction.resultAction.SumSpanCount:
|
4179
|
+
if (position === 'right') {
|
4180
|
+
var colspanNumber = parseInt(currentCell.baseCell.colSpan, 10);
|
4181
|
+
colspanNumber++;
|
4182
|
+
currentCell.baseCell.setAttribute('colSpan', colspanNumber);
|
4183
|
+
} else {
|
4184
|
+
$(currentCell.baseCell).before('<td' + tdAttributes + '>' + dom.blank + '</td>');
|
4185
|
+
}
|
4186
|
+
break;
|
4187
|
+
}
|
4188
|
+
}
|
4189
|
+
};
|
4190
|
+
|
4191
|
+
/*
|
4192
|
+
* Copy attributes from element.
|
4193
|
+
*
|
4194
|
+
* @param {object} Element to recover attributes.
|
4195
|
+
* @return {string} Copied string elements.
|
4196
|
+
*/
|
4197
|
+
this.recoverAttributes = function (el) {
|
4198
|
+
var resultStr = '';
|
4199
|
+
|
4200
|
+
if (!el) {
|
4201
|
+
return resultStr;
|
4202
|
+
}
|
4203
|
+
|
4204
|
+
var attrList = el.attributes || [];
|
4205
|
+
|
4206
|
+
for (var i = 0; i < attrList.length; i++) {
|
4207
|
+
if (attrList[i].name.toLowerCase() === 'id') {
|
4208
|
+
continue;
|
4209
|
+
}
|
4210
|
+
|
4211
|
+
if (attrList[i].specified) {
|
4212
|
+
resultStr += ' ' + attrList[i].name + '=\'' + attrList[i].value + '\'';
|
4213
|
+
}
|
4214
|
+
}
|
4215
|
+
|
4216
|
+
return resultStr;
|
4217
|
+
};
|
4218
|
+
|
4219
|
+
/**
|
4220
|
+
* Delete current row
|
4221
|
+
*
|
4222
|
+
* @param {WrappedRange} rng
|
4223
|
+
* @return {Node}
|
4224
|
+
*/
|
4225
|
+
this.deleteRow = function (rng) {
|
4226
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4227
|
+
var row = $(cell).closest('tr');
|
4228
|
+
var cellPos = row.children('td, th').index($(cell));
|
4229
|
+
var rowPos = row[0].rowIndex;
|
4230
|
+
|
4231
|
+
var vTable = new TableResultAction(cell, TableResultAction.where.Row,
|
4232
|
+
TableResultAction.requestAction.Delete, $(row).closest('table')[0]);
|
4233
|
+
var actions = vTable.getActionList();
|
4234
|
+
|
4235
|
+
for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
|
4236
|
+
if (!actions[actionIndex]) {
|
4237
|
+
continue;
|
4238
|
+
}
|
4239
|
+
|
4240
|
+
var baseCell = actions[actionIndex].baseCell;
|
4241
|
+
var virtualPosition = actions[actionIndex].virtualTable;
|
4242
|
+
var hasRowspan = (baseCell.rowSpan && baseCell.rowSpan > 1);
|
4243
|
+
var rowspanNumber = (hasRowspan) ? parseInt(baseCell.rowSpan, 10) : 0;
|
4244
|
+
switch (actions[actionIndex].action) {
|
4245
|
+
case TableResultAction.resultAction.Ignore:
|
4246
|
+
continue;
|
4247
|
+
case TableResultAction.resultAction.AddCell:
|
4248
|
+
var nextRow = row.next('tr')[0];
|
4249
|
+
if (!nextRow) { continue; }
|
4250
|
+
var cloneRow = row[0].cells[cellPos];
|
4251
|
+
if (hasRowspan) {
|
4252
|
+
if (rowspanNumber > 2) {
|
4253
|
+
rowspanNumber--;
|
4254
|
+
nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);
|
4255
|
+
nextRow.cells[cellPos].setAttribute('rowSpan', rowspanNumber);
|
4256
|
+
nextRow.cells[cellPos].innerHTML = '';
|
4257
|
+
} else if (rowspanNumber === 2) {
|
4258
|
+
nextRow.insertBefore(cloneRow, nextRow.cells[cellPos]);
|
4259
|
+
nextRow.cells[cellPos].removeAttribute('rowSpan');
|
4260
|
+
nextRow.cells[cellPos].innerHTML = '';
|
4261
|
+
}
|
4262
|
+
}
|
4263
|
+
continue;
|
4264
|
+
case TableResultAction.resultAction.SubtractSpanCount:
|
4265
|
+
if (hasRowspan) {
|
4266
|
+
if (rowspanNumber > 2) {
|
4267
|
+
rowspanNumber--;
|
4268
|
+
baseCell.setAttribute('rowSpan', rowspanNumber);
|
4269
|
+
if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }
|
4270
|
+
} else if (rowspanNumber === 2) {
|
4271
|
+
baseCell.removeAttribute('rowSpan');
|
4272
|
+
if (virtualPosition.rowIndex !== rowPos && baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }
|
4273
|
+
}
|
4274
|
+
}
|
4275
|
+
continue;
|
4276
|
+
case TableResultAction.resultAction.RemoveCell:
|
4277
|
+
// Do not need remove cell because row will be deleted.
|
4278
|
+
continue;
|
4279
|
+
}
|
4280
|
+
}
|
4281
|
+
row.remove();
|
4282
|
+
};
|
4283
|
+
|
4284
|
+
/**
|
4285
|
+
* Delete current col
|
4286
|
+
*
|
4287
|
+
* @param {WrappedRange} rng
|
4288
|
+
* @return {Node}
|
4289
|
+
*/
|
4290
|
+
this.deleteCol = function (rng) {
|
4291
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4292
|
+
var row = $(cell).closest('tr');
|
4293
|
+
var cellPos = row.children('td, th').index($(cell));
|
4294
|
+
|
4295
|
+
var vTable = new TableResultAction(cell, TableResultAction.where.Column,
|
4296
|
+
TableResultAction.requestAction.Delete, $(row).closest('table')[0]);
|
4297
|
+
var actions = vTable.getActionList();
|
4298
|
+
|
4299
|
+
for (var actionIndex = 0; actionIndex < actions.length; actionIndex++) {
|
4300
|
+
if (!actions[actionIndex]) {
|
4301
|
+
continue;
|
4302
|
+
}
|
4303
|
+
switch (actions[actionIndex].action) {
|
4304
|
+
case TableResultAction.resultAction.Ignore:
|
4305
|
+
continue;
|
4306
|
+
case TableResultAction.resultAction.SubtractSpanCount:
|
4307
|
+
var baseCell = actions[actionIndex].baseCell;
|
4308
|
+
var hasColspan = (baseCell.colSpan && baseCell.colSpan > 1);
|
4309
|
+
if (hasColspan) {
|
4310
|
+
var colspanNumber = (baseCell.colSpan) ? parseInt(baseCell.colSpan, 10) : 0;
|
4311
|
+
if (colspanNumber > 2) {
|
4312
|
+
colspanNumber--;
|
4313
|
+
baseCell.setAttribute('colSpan', colspanNumber);
|
4314
|
+
if (baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }
|
4315
|
+
} else if (colspanNumber === 2) {
|
4316
|
+
baseCell.removeAttribute('colSpan');
|
4317
|
+
if (baseCell.cellIndex === cellPos) { baseCell.innerHTML = ''; }
|
4318
|
+
}
|
4319
|
+
}
|
4320
|
+
continue;
|
4321
|
+
case TableResultAction.resultAction.RemoveCell:
|
4322
|
+
dom.remove(actions[actionIndex].baseCell, true);
|
4323
|
+
continue;
|
4324
|
+
}
|
4325
|
+
}
|
4326
|
+
};
|
4327
|
+
|
4328
|
+
/**
|
4329
|
+
* create empty table element
|
4330
|
+
*
|
4331
|
+
* @param {Number} rowCount
|
4332
|
+
* @param {Number} colCount
|
4333
|
+
* @return {Node}
|
4334
|
+
*/
|
4335
|
+
this.createTable = function (colCount, rowCount, options) {
|
4336
|
+
var tds = [], tdHTML;
|
4337
|
+
for (var idxCol = 0; idxCol < colCount; idxCol++) {
|
4338
|
+
tds.push('<td>' + dom.blank + '</td>');
|
4339
|
+
}
|
4340
|
+
tdHTML = tds.join('');
|
4341
|
+
|
4342
|
+
var trs = [], trHTML;
|
4343
|
+
for (var idxRow = 0; idxRow < rowCount; idxRow++) {
|
4344
|
+
trs.push('<tr>' + tdHTML + '</tr>');
|
4345
|
+
}
|
4346
|
+
trHTML = trs.join('');
|
4347
|
+
var $table = $('<table>' + trHTML + '</table>');
|
4348
|
+
if (options && options.tableClassName) {
|
4349
|
+
$table.addClass(options.tableClassName);
|
4350
|
+
}
|
4351
|
+
|
4352
|
+
return $table[0];
|
4353
|
+
};
|
4354
|
+
|
4355
|
+
/**
|
4356
|
+
* Delete current table
|
4357
|
+
*
|
4358
|
+
* @param {WrappedRange} rng
|
4359
|
+
* @return {Node}
|
4360
|
+
*/
|
4361
|
+
this.deleteTable = function (rng) {
|
4362
|
+
var cell = dom.ancestor(rng.commonAncestor(), dom.isCell);
|
4363
|
+
$(cell).closest('table').remove();
|
4364
|
+
};
|
4365
|
+
};
|
4366
|
+
|
4367
|
+
|
4368
|
+
var KEY_BOGUS = 'bogus';
|
4369
|
+
|
4370
|
+
/**
|
3766
4371
|
* @class Editor
|
3767
4372
|
*/
|
3768
4373
|
var Editor = function (context) {
|
@@ -3822,7 +4427,7 @@
|
|
3822
4427
|
var changeEventName = agent.isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';
|
3823
4428
|
$editable.on(changeEventName, func.debounce(function () {
|
3824
4429
|
context.triggerEvent('change', $editable.html());
|
3825
|
-
},
|
4430
|
+
}, 100));
|
3826
4431
|
|
3827
4432
|
$editor.on('focusin', function (event) {
|
3828
4433
|
context.triggerEvent('focusin', event);
|
@@ -3998,7 +4603,7 @@
|
|
3998
4603
|
var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',
|
3999
4604
|
'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',
|
4000
4605
|
'formatBlock', 'removeFormat',
|
4001
|
-
'backColor', '
|
4606
|
+
'backColor', 'fontName'];
|
4002
4607
|
|
4003
4608
|
for (var idx = 0, len = commands.length; idx < len; idx ++) {
|
4004
4609
|
this[commands[idx]] = (function (sCmd) {
|
@@ -4191,11 +4796,20 @@
|
|
4191
4796
|
*
|
4192
4797
|
* @param {String} tagName
|
4193
4798
|
*/
|
4194
|
-
this.formatBlock = this.wrapCommand(function (tagName) {
|
4799
|
+
this.formatBlock = this.wrapCommand(function (tagName, $target) {
|
4800
|
+
var onApplyCustomStyle = context.options.callbacks.onApplyCustomStyle;
|
4801
|
+
if (onApplyCustomStyle) {
|
4802
|
+
onApplyCustomStyle.call(this, $target, context, this.onFormatBlock);
|
4803
|
+
} else {
|
4804
|
+
this.onFormatBlock(tagName);
|
4805
|
+
}
|
4806
|
+
});
|
4807
|
+
|
4808
|
+
this.onFormatBlock = function (tagName) {
|
4195
4809
|
// [workaround] for MSIE, IE need `<`
|
4196
4810
|
tagName = agent.isMSIE ? '<' + tagName + '>' : tagName;
|
4197
4811
|
document.execCommand('FormatBlock', false, tagName);
|
4198
|
-
}
|
4812
|
+
};
|
4199
4813
|
|
4200
4814
|
this.formatPara = function () {
|
4201
4815
|
this.formatBlock('P');
|
@@ -4381,13 +4995,18 @@
|
|
4381
4995
|
|
4382
4996
|
// Get the first anchor on range(for edit).
|
4383
4997
|
var $anchor = $(list.head(rng.nodes(dom.isAnchor)));
|
4384
|
-
|
4385
|
-
return {
|
4998
|
+
var linkInfo = {
|
4386
4999
|
range: rng,
|
4387
5000
|
text: rng.toString(),
|
4388
|
-
isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : false,
|
4389
5001
|
url: $anchor.length ? $anchor.attr('href') : ''
|
4390
5002
|
};
|
5003
|
+
|
5004
|
+
// Define isNewWindow when anchor exists.
|
5005
|
+
if ($anchor.length) {
|
5006
|
+
linkInfo.isNewWindow = $anchor.attr('target') === '_blank';
|
5007
|
+
}
|
5008
|
+
|
5009
|
+
return linkInfo;
|
4391
5010
|
};
|
4392
5011
|
|
4393
5012
|
/**
|
@@ -4405,6 +5024,16 @@
|
|
4405
5024
|
if (backColor) { document.execCommand('backColor', false, backColor); }
|
4406
5025
|
});
|
4407
5026
|
|
5027
|
+
/**
|
5028
|
+
* Set foreground color
|
5029
|
+
*
|
5030
|
+
* @param {String} colorCode foreground color code
|
5031
|
+
*/
|
5032
|
+
this.foreColor = this.wrapCommand(function (colorInfo) {
|
5033
|
+
document.execCommand('styleWithCSS', false, true);
|
5034
|
+
document.execCommand('foreColor', false, colorInfo);
|
5035
|
+
});
|
5036
|
+
|
4408
5037
|
/**
|
4409
5038
|
* insert Table
|
4410
5039
|
*
|
@@ -4417,6 +5046,76 @@
|
|
4417
5046
|
rng.insertNode(table.createTable(dimension[0], dimension[1], options));
|
4418
5047
|
});
|
4419
5048
|
|
5049
|
+
/**
|
5050
|
+
* @method addRow
|
5051
|
+
*
|
5052
|
+
*
|
5053
|
+
*/
|
5054
|
+
this.addRow = function (position) {
|
5055
|
+
var rng = this.createRange($editable);
|
5056
|
+
if (rng.isCollapsed() && rng.isOnCell()) {
|
5057
|
+
beforeCommand();
|
5058
|
+
table.addRow(rng, position);
|
5059
|
+
afterCommand();
|
5060
|
+
}
|
5061
|
+
};
|
5062
|
+
|
5063
|
+
/**
|
5064
|
+
* @method addCol
|
5065
|
+
*
|
5066
|
+
*
|
5067
|
+
*/
|
5068
|
+
this.addCol = function (position) {
|
5069
|
+
var rng = this.createRange($editable);
|
5070
|
+
if (rng.isCollapsed() && rng.isOnCell()) {
|
5071
|
+
beforeCommand();
|
5072
|
+
table.addCol(rng, position);
|
5073
|
+
afterCommand();
|
5074
|
+
}
|
5075
|
+
};
|
5076
|
+
|
5077
|
+
/**
|
5078
|
+
* @method deleteRow
|
5079
|
+
*
|
5080
|
+
*
|
5081
|
+
*/
|
5082
|
+
this.deleteRow = function () {
|
5083
|
+
var rng = this.createRange($editable);
|
5084
|
+
if (rng.isCollapsed() && rng.isOnCell()) {
|
5085
|
+
beforeCommand();
|
5086
|
+
table.deleteRow(rng);
|
5087
|
+
afterCommand();
|
5088
|
+
}
|
5089
|
+
};
|
5090
|
+
|
5091
|
+
/**
|
5092
|
+
* @method deleteCol
|
5093
|
+
*
|
5094
|
+
*
|
5095
|
+
*/
|
5096
|
+
this.deleteCol = function () {
|
5097
|
+
var rng = this.createRange($editable);
|
5098
|
+
if (rng.isCollapsed() && rng.isOnCell()) {
|
5099
|
+
beforeCommand();
|
5100
|
+
table.deleteCol(rng);
|
5101
|
+
afterCommand();
|
5102
|
+
}
|
5103
|
+
};
|
5104
|
+
|
5105
|
+
/**
|
5106
|
+
* @method deleteTable
|
5107
|
+
*
|
5108
|
+
*
|
5109
|
+
*/
|
5110
|
+
this.deleteTable = function () {
|
5111
|
+
var rng = this.createRange($editable);
|
5112
|
+
if (rng.isCollapsed() && rng.isOnCell()) {
|
5113
|
+
beforeCommand();
|
5114
|
+
table.deleteTable(rng);
|
5115
|
+
afterCommand();
|
5116
|
+
}
|
5117
|
+
};
|
5118
|
+
|
4420
5119
|
/**
|
4421
5120
|
* float me
|
4422
5121
|
*
|
@@ -4424,6 +5123,8 @@
|
|
4424
5123
|
*/
|
4425
5124
|
this.floatMe = this.wrapCommand(function (value) {
|
4426
5125
|
var $target = $(this.restoreTarget());
|
5126
|
+
$target.toggleClass('note-float-left', value === 'left');
|
5127
|
+
$target.toggleClass('note-float-right', value === 'right');
|
4427
5128
|
$target.css('float', value);
|
4428
5129
|
});
|
4429
5130
|
|
@@ -4559,9 +5260,9 @@
|
|
4559
5260
|
this.pasteByHook = function () {
|
4560
5261
|
var node = this.$paste[0].firstChild;
|
4561
5262
|
|
4562
|
-
|
4563
|
-
|
4564
|
-
var decodedData = atob(
|
5263
|
+
var src = node && node.src;
|
5264
|
+
if (dom.isImg(node) && src.indexOf('data:') === 0) {
|
5265
|
+
var decodedData = atob(node.src.split(',')[1]);
|
4565
5266
|
var array = new Uint8Array(decodedData.length);
|
4566
5267
|
for (var i = 0; i < decodedData.length; i++) {
|
4567
5268
|
array[i] = decodedData.charCodeAt(i);
|
@@ -4844,17 +5545,20 @@
|
|
4844
5545
|
event.stopPropagation();
|
4845
5546
|
|
4846
5547
|
var editableTop = $editable.offset().top - $document.scrollTop();
|
4847
|
-
|
4848
|
-
$document.on('mousemove', function (event) {
|
5548
|
+
var onMouseMove = function (event) {
|
4849
5549
|
var height = event.clientY - (editableTop + EDITABLE_PADDING);
|
4850
5550
|
|
4851
5551
|
height = (options.minheight > 0) ? Math.max(height, options.minheight) : height;
|
4852
5552
|
height = (options.maxHeight > 0) ? Math.min(height, options.maxHeight) : height;
|
4853
5553
|
|
4854
5554
|
$editable.height(height);
|
4855
|
-
}
|
4856
|
-
|
4857
|
-
|
5555
|
+
};
|
5556
|
+
|
5557
|
+
$document
|
5558
|
+
.on('mousemove', onMouseMove)
|
5559
|
+
.one('mouseup', function () {
|
5560
|
+
$document.off('mousemove', onMouseMove);
|
5561
|
+
});
|
4858
5562
|
});
|
4859
5563
|
};
|
4860
5564
|
|
@@ -4865,6 +5569,7 @@
|
|
4865
5569
|
};
|
4866
5570
|
|
4867
5571
|
var Fullscreen = function (context) {
|
5572
|
+
var self = this;
|
4868
5573
|
var $editor = context.layoutInfo.editor;
|
4869
5574
|
var $toolbar = context.layoutInfo.toolbar;
|
4870
5575
|
var $editable = context.layoutInfo.editable;
|
@@ -4873,34 +5578,32 @@
|
|
4873
5578
|
var $window = $(window);
|
4874
5579
|
var $scrollbar = $('html, body');
|
4875
5580
|
|
5581
|
+
this.resizeTo = function (size) {
|
5582
|
+
$editable.css('height', size.h);
|
5583
|
+
$codable.css('height', size.h);
|
5584
|
+
if ($codable.data('cmeditor')) {
|
5585
|
+
$codable.data('cmeditor').setsize(null, size.h);
|
5586
|
+
}
|
5587
|
+
};
|
5588
|
+
|
5589
|
+
this.onResize = function () {
|
5590
|
+
self.resizeTo({
|
5591
|
+
h: $window.height() - $toolbar.outerHeight()
|
5592
|
+
});
|
5593
|
+
};
|
5594
|
+
|
4876
5595
|
/**
|
4877
5596
|
* toggle fullscreen
|
4878
5597
|
*/
|
4879
5598
|
this.toggle = function () {
|
4880
|
-
var resize = function (size) {
|
4881
|
-
$editable.css('height', size.h);
|
4882
|
-
$codable.css('height', size.h);
|
4883
|
-
if ($codable.data('cmeditor')) {
|
4884
|
-
$codable.data('cmeditor').setsize(null, size.h);
|
4885
|
-
}
|
4886
|
-
};
|
4887
|
-
|
4888
5599
|
$editor.toggleClass('fullscreen');
|
4889
5600
|
if (this.isFullscreen()) {
|
4890
5601
|
$editable.data('orgHeight', $editable.css('height'));
|
4891
|
-
|
4892
|
-
$window.on('resize', function () {
|
4893
|
-
resize({
|
4894
|
-
h: $window.height() - $toolbar.outerHeight()
|
4895
|
-
});
|
4896
|
-
}).trigger('resize');
|
4897
|
-
|
5602
|
+
$window.on('resize', this.onResize).trigger('resize');
|
4898
5603
|
$scrollbar.css('overflow', 'hidden');
|
4899
5604
|
} else {
|
4900
|
-
$window.off('resize');
|
4901
|
-
|
4902
|
-
h: $editable.data('orgHeight')
|
4903
|
-
});
|
5605
|
+
$window.off('resize', this.onResize);
|
5606
|
+
this.resizeTo({ h: $editable.data('orgHeight') });
|
4904
5607
|
$scrollbar.css('overflow', 'visible');
|
4905
5608
|
}
|
4906
5609
|
|
@@ -4927,6 +5630,12 @@
|
|
4927
5630
|
},
|
4928
5631
|
'summernote.keyup summernote.scroll summernote.change summernote.dialog.shown': function () {
|
4929
5632
|
self.update();
|
5633
|
+
},
|
5634
|
+
'summernote.disable': function () {
|
5635
|
+
self.hide();
|
5636
|
+
},
|
5637
|
+
'summernote.codeview.toggled': function () {
|
5638
|
+
self.update();
|
4930
5639
|
}
|
4931
5640
|
};
|
4932
5641
|
|
@@ -4955,24 +5664,34 @@
|
|
4955
5664
|
posStart = $target.offset(),
|
4956
5665
|
scrollTop = $document.scrollTop();
|
4957
5666
|
|
4958
|
-
|
5667
|
+
var onMouseMove = function (event) {
|
4959
5668
|
context.invoke('editor.resizeTo', {
|
4960
5669
|
x: event.clientX - posStart.left,
|
4961
5670
|
y: event.clientY - (posStart.top - scrollTop)
|
4962
5671
|
}, $target, !event.shiftKey);
|
4963
5672
|
|
4964
5673
|
self.update($target[0]);
|
4965
|
-
}
|
4966
|
-
|
4967
|
-
|
4968
|
-
|
4969
|
-
|
5674
|
+
};
|
5675
|
+
|
5676
|
+
$document
|
5677
|
+
.on('mousemove', onMouseMove)
|
5678
|
+
.one('mouseup', function (e) {
|
5679
|
+
e.preventDefault();
|
5680
|
+
$document.off('mousemove', onMouseMove);
|
5681
|
+
context.invoke('editor.afterCommand');
|
5682
|
+
});
|
4970
5683
|
|
4971
5684
|
if (!$target.data('ratio')) { // original ratio.
|
4972
5685
|
$target.data('ratio', $target.height() / $target.width());
|
4973
5686
|
}
|
4974
5687
|
}
|
4975
5688
|
});
|
5689
|
+
|
5690
|
+
// Listen for scrolling on the handle overlay.
|
5691
|
+
this.$handle.on('wheel', function (e) {
|
5692
|
+
e.preventDefault();
|
5693
|
+
self.update();
|
5694
|
+
});
|
4976
5695
|
};
|
4977
5696
|
|
4978
5697
|
this.destroy = function () {
|
@@ -4980,6 +5699,10 @@
|
|
4980
5699
|
};
|
4981
5700
|
|
4982
5701
|
this.update = function (target) {
|
5702
|
+
if (context.isDisabled()) {
|
5703
|
+
return false;
|
5704
|
+
}
|
5705
|
+
|
4983
5706
|
var isImage = dom.isImg(target);
|
4984
5707
|
var $selection = this.$handle.find('.note-control-selection');
|
4985
5708
|
|
@@ -4987,12 +5710,16 @@
|
|
4987
5710
|
|
4988
5711
|
if (isImage) {
|
4989
5712
|
var $image = $(target);
|
4990
|
-
var
|
5713
|
+
var position = $image.position();
|
5714
|
+
var pos = {
|
5715
|
+
left: position.left + parseInt($image.css('marginLeft'), 10),
|
5716
|
+
top: position.top + parseInt($image.css('marginTop'), 10)
|
5717
|
+
};
|
4991
5718
|
|
4992
|
-
//
|
5719
|
+
// exclude margin
|
4993
5720
|
var imageSize = {
|
4994
|
-
w: $image.outerWidth(
|
4995
|
-
h: $image.outerHeight(
|
5721
|
+
w: $image.outerWidth(false),
|
5722
|
+
h: $image.outerHeight(false)
|
4996
5723
|
};
|
4997
5724
|
|
4998
5725
|
$selection.css({
|
@@ -5121,6 +5848,8 @@
|
|
5121
5848
|
this.$placeholder.on('click', function () {
|
5122
5849
|
context.invoke('focus');
|
5123
5850
|
}).text(options.placeholder).prependTo($editingArea);
|
5851
|
+
|
5852
|
+
this.update();
|
5124
5853
|
};
|
5125
5854
|
|
5126
5855
|
this.destroy = function () {
|
@@ -5148,7 +5877,7 @@
|
|
5148
5877
|
if (!options.shortcuts || !shortcut) {
|
5149
5878
|
return '';
|
5150
5879
|
}
|
5151
|
-
|
5880
|
+
|
5152
5881
|
if (agent.isMac) {
|
5153
5882
|
shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');
|
5154
5883
|
}
|
@@ -5165,6 +5894,7 @@
|
|
5165
5894
|
this.addToolbarButtons();
|
5166
5895
|
this.addImagePopoverButtons();
|
5167
5896
|
this.addLinkPopoverButtons();
|
5897
|
+
this.addTablePopoverButtons();
|
5168
5898
|
this.fontInstalledMap = {};
|
5169
5899
|
};
|
5170
5900
|
|
@@ -5186,7 +5916,7 @@
|
|
5186
5916
|
return ui.buttonGroup([
|
5187
5917
|
ui.button({
|
5188
5918
|
className: 'dropdown-toggle',
|
5189
|
-
contents: ui.
|
5919
|
+
contents: ui.dropdownButtonContents(ui.icon(options.icons.magic), options),
|
5190
5920
|
tooltip: lang.style.style,
|
5191
5921
|
data: {
|
5192
5922
|
toggle: 'dropdown'
|
@@ -5218,7 +5948,7 @@
|
|
5218
5948
|
className: 'note-btn-bold',
|
5219
5949
|
contents: ui.icon(options.icons.bold),
|
5220
5950
|
tooltip: lang.font.bold + representShortcut('bold'),
|
5221
|
-
click: context.
|
5951
|
+
click: context.createInvokeHandlerAndUpdateState('editor.bold')
|
5222
5952
|
}).render();
|
5223
5953
|
});
|
5224
5954
|
|
@@ -5227,7 +5957,7 @@
|
|
5227
5957
|
className: 'note-btn-italic',
|
5228
5958
|
contents: ui.icon(options.icons.italic),
|
5229
5959
|
tooltip: lang.font.italic + representShortcut('italic'),
|
5230
|
-
click: context.
|
5960
|
+
click: context.createInvokeHandlerAndUpdateState('editor.italic')
|
5231
5961
|
}).render();
|
5232
5962
|
});
|
5233
5963
|
|
@@ -5236,7 +5966,7 @@
|
|
5236
5966
|
className: 'note-btn-underline',
|
5237
5967
|
contents: ui.icon(options.icons.underline),
|
5238
5968
|
tooltip: lang.font.underline + representShortcut('underline'),
|
5239
|
-
click: context.
|
5969
|
+
click: context.createInvokeHandlerAndUpdateState('editor.underline')
|
5240
5970
|
}).render();
|
5241
5971
|
});
|
5242
5972
|
|
@@ -5253,7 +5983,7 @@
|
|
5253
5983
|
className: 'note-btn-strikethrough',
|
5254
5984
|
contents: ui.icon(options.icons.strikethrough),
|
5255
5985
|
tooltip: lang.font.strikethrough + representShortcut('strikethrough'),
|
5256
|
-
click: context.
|
5986
|
+
click: context.createInvokeHandlerAndUpdateState('editor.strikethrough')
|
5257
5987
|
}).render();
|
5258
5988
|
});
|
5259
5989
|
|
@@ -5262,7 +5992,7 @@
|
|
5262
5992
|
className: 'note-btn-superscript',
|
5263
5993
|
contents: ui.icon(options.icons.superscript),
|
5264
5994
|
tooltip: lang.font.superscript,
|
5265
|
-
click: context.
|
5995
|
+
click: context.createInvokeHandlerAndUpdateState('editor.superscript')
|
5266
5996
|
}).render();
|
5267
5997
|
});
|
5268
5998
|
|
@@ -5271,7 +6001,7 @@
|
|
5271
6001
|
className: 'note-btn-subscript',
|
5272
6002
|
contents: ui.icon(options.icons.subscript),
|
5273
6003
|
tooltip: lang.font.subscript,
|
5274
|
-
click: context.
|
6004
|
+
click: context.createInvokeHandlerAndUpdateState('editor.subscript')
|
5275
6005
|
}).render();
|
5276
6006
|
});
|
5277
6007
|
|
@@ -5279,7 +6009,7 @@
|
|
5279
6009
|
return ui.buttonGroup([
|
5280
6010
|
ui.button({
|
5281
6011
|
className: 'dropdown-toggle',
|
5282
|
-
contents: '<span class="note-current-fontname"/>
|
6012
|
+
contents: ui.dropdownButtonContents('<span class="note-current-fontname"/>', options),
|
5283
6013
|
tooltip: lang.font.name,
|
5284
6014
|
data: {
|
5285
6015
|
toggle: 'dropdown'
|
@@ -5292,7 +6022,7 @@
|
|
5292
6022
|
template: function (item) {
|
5293
6023
|
return '<span style="font-family:' + item + '">' + item + '</span>';
|
5294
6024
|
},
|
5295
|
-
click: context.
|
6025
|
+
click: context.createInvokeHandlerAndUpdateState('editor.fontName')
|
5296
6026
|
})
|
5297
6027
|
]).render();
|
5298
6028
|
});
|
@@ -5301,7 +6031,7 @@
|
|
5301
6031
|
return ui.buttonGroup([
|
5302
6032
|
ui.button({
|
5303
6033
|
className: 'dropdown-toggle',
|
5304
|
-
contents: '<span class="note-current-fontsize"/>'
|
6034
|
+
contents: ui.dropdownButtonContents('<span class="note-current-fontsize"/>', options),
|
5305
6035
|
tooltip: lang.font.size,
|
5306
6036
|
data: {
|
5307
6037
|
toggle: 'dropdown'
|
@@ -5311,7 +6041,7 @@
|
|
5311
6041
|
className: 'dropdown-fontsize',
|
5312
6042
|
checkClassName: options.icons.menuCheck,
|
5313
6043
|
items: options.fontSizes,
|
5314
|
-
click: context.
|
6044
|
+
click: context.createInvokeHandlerAndUpdateState('editor.fontSize')
|
5315
6045
|
})
|
5316
6046
|
]).render();
|
5317
6047
|
});
|
@@ -5339,7 +6069,7 @@
|
|
5339
6069
|
}),
|
5340
6070
|
ui.button({
|
5341
6071
|
className: 'dropdown-toggle',
|
5342
|
-
contents: ui.
|
6072
|
+
contents: ui.dropdownButtonContents('', options),
|
5343
6073
|
tooltip: lang.color.more,
|
5344
6074
|
data: {
|
5345
6075
|
toggle: 'dropdown'
|
@@ -5347,33 +6077,32 @@
|
|
5347
6077
|
}),
|
5348
6078
|
ui.dropdown({
|
5349
6079
|
items: [
|
5350
|
-
'<
|
5351
|
-
'<div class="btn-group">',
|
6080
|
+
'<div class="note-palette">',
|
5352
6081
|
' <div class="note-palette-title">' + lang.color.background + '</div>',
|
5353
6082
|
' <div>',
|
5354
|
-
' <button type="button" class="note-color-reset btn btn-
|
6083
|
+
' <button type="button" class="note-color-reset btn btn-light" data-event="backColor" data-value="inherit">',
|
5355
6084
|
lang.color.transparent,
|
5356
6085
|
' </button>',
|
5357
6086
|
' </div>',
|
5358
6087
|
' <div class="note-holder" data-event="backColor"/>',
|
5359
6088
|
'</div>',
|
5360
|
-
'<div class="
|
6089
|
+
'<div class="note-palette">',
|
5361
6090
|
' <div class="note-palette-title">' + lang.color.foreground + '</div>',
|
5362
6091
|
' <div>',
|
5363
|
-
' <button type="button" class="note-color-reset btn btn-
|
6092
|
+
' <button type="button" class="note-color-reset btn btn-light" data-event="removeFormat" data-value="foreColor">',
|
5364
6093
|
lang.color.resetToDefault,
|
5365
6094
|
' </button>',
|
5366
6095
|
' </div>',
|
5367
6096
|
' <div class="note-holder" data-event="foreColor"/>',
|
5368
|
-
'</div>'
|
5369
|
-
'</li>'
|
6097
|
+
'</div>'
|
5370
6098
|
].join(''),
|
5371
6099
|
callback: function ($dropdown) {
|
5372
6100
|
$dropdown.find('.note-holder').each(function () {
|
5373
6101
|
var $holder = $(this);
|
5374
6102
|
$holder.append(ui.palette({
|
5375
6103
|
colors: options.colors,
|
5376
|
-
eventName: $holder.data('event')
|
6104
|
+
eventName: $holder.data('event'),
|
6105
|
+
tooltip: options.tooltip
|
5377
6106
|
}).render());
|
5378
6107
|
});
|
5379
6108
|
},
|
@@ -5460,7 +6189,7 @@
|
|
5460
6189
|
return ui.buttonGroup([
|
5461
6190
|
ui.button({
|
5462
6191
|
className: 'dropdown-toggle',
|
5463
|
-
contents: ui.
|
6192
|
+
contents: ui.dropdownButtonContents(ui.icon(options.icons.alignLeft), options),
|
5464
6193
|
tooltip: lang.paragraph.paragraph,
|
5465
6194
|
data: {
|
5466
6195
|
toggle: 'dropdown'
|
@@ -5483,7 +6212,7 @@
|
|
5483
6212
|
return ui.buttonGroup([
|
5484
6213
|
ui.button({
|
5485
6214
|
className: 'dropdown-toggle',
|
5486
|
-
contents: ui.
|
6215
|
+
contents: ui.dropdownButtonContents(ui.icon(options.icons.textHeight), options),
|
5487
6216
|
tooltip: lang.font.height,
|
5488
6217
|
data: {
|
5489
6218
|
toggle: 'dropdown'
|
@@ -5502,7 +6231,7 @@
|
|
5502
6231
|
return ui.buttonGroup([
|
5503
6232
|
ui.button({
|
5504
6233
|
className: 'dropdown-toggle',
|
5505
|
-
contents: ui.
|
6234
|
+
contents: ui.dropdownButtonContents(ui.icon(options.icons.table), options),
|
5506
6235
|
tooltip: lang.table.table,
|
5507
6236
|
data: {
|
5508
6237
|
toggle: 'dropdown'
|
@@ -5690,6 +6419,71 @@
|
|
5690
6419
|
});
|
5691
6420
|
};
|
5692
6421
|
|
6422
|
+
/**
|
6423
|
+
* table : [
|
6424
|
+
* ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
|
6425
|
+
* ['delete', ['deleteRow', 'deleteCol', 'deleteTable']]
|
6426
|
+
* ],
|
6427
|
+
*/
|
6428
|
+
this.addTablePopoverButtons = function () {
|
6429
|
+
context.memo('button.addRowUp', function () {
|
6430
|
+
return ui.button({
|
6431
|
+
className: 'btn-md',
|
6432
|
+
contents: ui.icon(options.icons.rowAbove),
|
6433
|
+
tooltip: lang.table.addRowAbove,
|
6434
|
+
click: context.createInvokeHandler('editor.addRow', 'top')
|
6435
|
+
}).render();
|
6436
|
+
});
|
6437
|
+
context.memo('button.addRowDown', function () {
|
6438
|
+
return ui.button({
|
6439
|
+
className: 'btn-md',
|
6440
|
+
contents: ui.icon(options.icons.rowBelow),
|
6441
|
+
tooltip: lang.table.addRowBelow,
|
6442
|
+
click: context.createInvokeHandler('editor.addRow', 'bottom')
|
6443
|
+
}).render();
|
6444
|
+
});
|
6445
|
+
context.memo('button.addColLeft', function () {
|
6446
|
+
return ui.button({
|
6447
|
+
className: 'btn-md',
|
6448
|
+
contents: ui.icon(options.icons.colBefore),
|
6449
|
+
tooltip: lang.table.addColLeft,
|
6450
|
+
click: context.createInvokeHandler('editor.addCol', 'left')
|
6451
|
+
}).render();
|
6452
|
+
});
|
6453
|
+
context.memo('button.addColRight', function () {
|
6454
|
+
return ui.button({
|
6455
|
+
className: 'btn-md',
|
6456
|
+
contents: ui.icon(options.icons.colAfter),
|
6457
|
+
tooltip: lang.table.addColRight,
|
6458
|
+
click: context.createInvokeHandler('editor.addCol', 'right')
|
6459
|
+
}).render();
|
6460
|
+
});
|
6461
|
+
context.memo('button.deleteRow', function () {
|
6462
|
+
return ui.button({
|
6463
|
+
className: 'btn-md',
|
6464
|
+
contents: ui.icon(options.icons.rowRemove),
|
6465
|
+
tooltip: lang.table.delRow,
|
6466
|
+
click: context.createInvokeHandler('editor.deleteRow')
|
6467
|
+
}).render();
|
6468
|
+
});
|
6469
|
+
context.memo('button.deleteCol', function () {
|
6470
|
+
return ui.button({
|
6471
|
+
className: 'btn-md',
|
6472
|
+
contents: ui.icon(options.icons.colRemove),
|
6473
|
+
tooltip: lang.table.delCol,
|
6474
|
+
click: context.createInvokeHandler('editor.deleteCol')
|
6475
|
+
}).render();
|
6476
|
+
});
|
6477
|
+
context.memo('button.deleteTable', function () {
|
6478
|
+
return ui.button({
|
6479
|
+
className: 'btn-md',
|
6480
|
+
contents: ui.icon(options.icons.trash),
|
6481
|
+
tooltip: lang.table.delTable,
|
6482
|
+
click: context.createInvokeHandler('editor.deleteTable')
|
6483
|
+
}).render();
|
6484
|
+
});
|
6485
|
+
};
|
6486
|
+
|
5693
6487
|
this.build = function ($container, groups) {
|
5694
6488
|
for (var groupIdx = 0, groupLen = groups.length; groupIdx < groupLen; groupIdx++) {
|
5695
6489
|
var group = groups[groupIdx];
|
@@ -5710,9 +6504,14 @@
|
|
5710
6504
|
}
|
5711
6505
|
};
|
5712
6506
|
|
5713
|
-
|
6507
|
+
/**
|
6508
|
+
* @param {jQuery} [$container]
|
6509
|
+
*/
|
6510
|
+
this.updateCurrentStyle = function ($container) {
|
6511
|
+
var $cont = $container || $toolbar;
|
6512
|
+
|
5714
6513
|
var styleInfo = context.invoke('editor.currentStyle');
|
5715
|
-
this.updateBtnStates({
|
6514
|
+
this.updateBtnStates($cont, {
|
5716
6515
|
'.note-btn-bold': function () {
|
5717
6516
|
return styleInfo['font-bold'] === 'bold';
|
5718
6517
|
},
|
@@ -5741,27 +6540,29 @@
|
|
5741
6540
|
});
|
5742
6541
|
var fontName = list.find(fontNames, self.isFontInstalled);
|
5743
6542
|
|
5744
|
-
$
|
6543
|
+
$cont.find('.dropdown-fontname a').each(function () {
|
6544
|
+
var $item = $(this);
|
5745
6545
|
// always compare string to avoid creating another func.
|
5746
|
-
var isChecked = ($
|
5747
|
-
|
6546
|
+
var isChecked = ($item.data('value') + '') === (fontName + '');
|
6547
|
+
$item.toggleClass('checked', isChecked);
|
5748
6548
|
});
|
5749
|
-
$
|
6549
|
+
$cont.find('.note-current-fontname').text(fontName);
|
5750
6550
|
}
|
5751
6551
|
|
5752
6552
|
if (styleInfo['font-size']) {
|
5753
6553
|
var fontSize = styleInfo['font-size'];
|
5754
|
-
$
|
6554
|
+
$cont.find('.dropdown-fontsize a').each(function () {
|
6555
|
+
var $item = $(this);
|
5755
6556
|
// always compare with string to avoid creating another func.
|
5756
|
-
var isChecked = ($
|
5757
|
-
|
6557
|
+
var isChecked = ($item.data('value') + '') === (fontSize + '');
|
6558
|
+
$item.toggleClass('checked', isChecked);
|
5758
6559
|
});
|
5759
|
-
$
|
6560
|
+
$cont.find('.note-current-fontsize').text(fontSize);
|
5760
6561
|
}
|
5761
6562
|
|
5762
6563
|
if (styleInfo['line-height']) {
|
5763
6564
|
var lineHeight = styleInfo['line-height'];
|
5764
|
-
$
|
6565
|
+
$cont.find('.dropdown-line-height li a').each(function () {
|
5765
6566
|
// always compare with string to avoid creating another func.
|
5766
6567
|
var isChecked = ($(this).data('value') + '') === (lineHeight + '');
|
5767
6568
|
this.className = isChecked ? 'checked' : '';
|
@@ -5769,9 +6570,9 @@
|
|
5769
6570
|
}
|
5770
6571
|
};
|
5771
6572
|
|
5772
|
-
this.updateBtnStates = function (infos) {
|
6573
|
+
this.updateBtnStates = function ($container, infos) {
|
5773
6574
|
$.each(infos, function (selector, pred) {
|
5774
|
-
ui.toggleBtnActive($
|
6575
|
+
ui.toggleBtnActive($container.find(selector), pred());
|
5775
6576
|
});
|
5776
6577
|
};
|
5777
6578
|
|
@@ -5822,6 +6623,7 @@
|
|
5822
6623
|
var ui = $.summernote.ui;
|
5823
6624
|
|
5824
6625
|
var $note = context.layoutInfo.note;
|
6626
|
+
var $editor = context.layoutInfo.editor;
|
5825
6627
|
var $toolbar = context.layoutInfo.toolbar;
|
5826
6628
|
var options = context.options;
|
5827
6629
|
|
@@ -5842,6 +6644,8 @@
|
|
5842
6644
|
$toolbar.appendTo(options.toolbarContainer);
|
5843
6645
|
}
|
5844
6646
|
|
6647
|
+
this.changeContainer(false);
|
6648
|
+
|
5845
6649
|
$note.on('summernote.keyup summernote.mouseup summernote.change', function () {
|
5846
6650
|
context.invoke('buttons.updateCurrentStyle');
|
5847
6651
|
});
|
@@ -5853,8 +6657,20 @@
|
|
5853
6657
|
$toolbar.children().remove();
|
5854
6658
|
};
|
5855
6659
|
|
6660
|
+
this.changeContainer = function (isFullscreen) {
|
6661
|
+
if (isFullscreen) {
|
6662
|
+
$toolbar.prependTo($editor);
|
6663
|
+
} else {
|
6664
|
+
if (options.toolbarContainer) {
|
6665
|
+
$toolbar.appendTo(options.toolbarContainer);
|
6666
|
+
}
|
6667
|
+
}
|
6668
|
+
};
|
6669
|
+
|
5856
6670
|
this.updateFullscreen = function (isFullscreen) {
|
5857
6671
|
ui.toggleBtnActive($toolbar.find('.btn-fullscreen'), isFullscreen);
|
6672
|
+
|
6673
|
+
this.changeContainer(isFullscreen);
|
5858
6674
|
};
|
5859
6675
|
|
5860
6676
|
this.updateCodeview = function (isCodeview) {
|
@@ -5894,20 +6710,22 @@
|
|
5894
6710
|
this.initialize = function () {
|
5895
6711
|
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
5896
6712
|
|
5897
|
-
var body = '<div class="form-group">' +
|
5898
|
-
'<label>' + lang.link.textToDisplay + '</label>' +
|
5899
|
-
'<input class="note-link-text form-control
|
6713
|
+
var body = '<div class="form-group note-form-group">' +
|
6714
|
+
'<label class="note-form-label">' + lang.link.textToDisplay + '</label>' +
|
6715
|
+
'<input class="note-link-text form-control '+
|
6716
|
+
' note-form-control note-input" type="text" />' +
|
5900
6717
|
'</div>' +
|
5901
|
-
'<div class="form-group">' +
|
5902
|
-
'<label>' + lang.link.url + '</label>' +
|
5903
|
-
'<input class="note-link-url form-control
|
6718
|
+
'<div class="form-group note-form-group">' +
|
6719
|
+
'<label class="note-form-label">' + lang.link.url + '</label>' +
|
6720
|
+
'<input class="note-link-url form-control note-form-control ' +
|
6721
|
+
'note-input" type="text" value="http://" />' +
|
5904
6722
|
'</div>' +
|
5905
|
-
|
5906
|
-
|
5907
|
-
|
5908
|
-
|
5909
|
-
|
5910
|
-
|
6723
|
+
(!options.disableLinkTarget ?
|
6724
|
+
$('<div/>').append(ui.checkbox({ id: 'sn-checkbox-open-in-new-window', text: lang.link.openInNewWindow, checked: true }).render())
|
6725
|
+
.html()
|
6726
|
+
: '');
|
6727
|
+
var footer = '<button href="#" class="btn btn-primary note-btn note-btn-primary ' +
|
6728
|
+
'note-link-btn disabled" disabled>' + lang.link.insert + '</button>';
|
5911
6729
|
|
5912
6730
|
this.$dialog = ui.dialog({
|
5913
6731
|
className: 'link-dialog',
|
@@ -5989,7 +6807,10 @@
|
|
5989
6807
|
self.bindEnterKey($linkUrl, $linkBtn);
|
5990
6808
|
self.bindEnterKey($linkText, $linkBtn);
|
5991
6809
|
|
5992
|
-
|
6810
|
+
var isChecked = linkInfo.isNewWindow !== undefined ?
|
6811
|
+
linkInfo.isNewWindow : context.options.linkTargetBlank;
|
6812
|
+
|
6813
|
+
$openInNewWindow.prop('checked', isChecked);
|
5993
6814
|
|
5994
6815
|
$linkBtn.one('click', function (event) {
|
5995
6816
|
event.preventDefault();
|
@@ -6000,7 +6821,7 @@
|
|
6000
6821
|
text: $linkText.val(),
|
6001
6822
|
isNewWindow: $openInNewWindow.is(':checked')
|
6002
6823
|
});
|
6003
|
-
self.$dialog
|
6824
|
+
ui.hideDialog(self.$dialog);
|
6004
6825
|
});
|
6005
6826
|
});
|
6006
6827
|
|
@@ -6046,7 +6867,7 @@
|
|
6046
6867
|
'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function () {
|
6047
6868
|
self.update();
|
6048
6869
|
},
|
6049
|
-
'summernote.dialog.shown': function () {
|
6870
|
+
'summernote.disable summernote.dialog.shown': function () {
|
6050
6871
|
self.hide();
|
6051
6872
|
}
|
6052
6873
|
};
|
@@ -6059,11 +6880,11 @@
|
|
6059
6880
|
this.$popover = ui.popover({
|
6060
6881
|
className: 'note-link-popover',
|
6061
6882
|
callback: function ($node) {
|
6062
|
-
var $content = $node.find('.popover-content');
|
6883
|
+
var $content = $node.find('.popover-content,.note-popover-content');
|
6063
6884
|
$content.prepend('<span><a target="_blank"></a> </span>');
|
6064
6885
|
}
|
6065
6886
|
}).render().appendTo('body');
|
6066
|
-
var $content = this.$popover.find('.popover-content');
|
6887
|
+
var $content = this.$popover.find('.popover-content,.note-popover-content');
|
6067
6888
|
|
6068
6889
|
context.invoke('buttons.build', $content, options.popover.link);
|
6069
6890
|
};
|
@@ -6120,16 +6941,19 @@
|
|
6120
6941
|
imageLimitation = '<small>' + lang.image.maximumFileSize + ' : ' + readableSize + '</small>';
|
6121
6942
|
}
|
6122
6943
|
|
6123
|
-
var body = '<div class="form-group note-group-select-from-files">' +
|
6124
|
-
'<label>' + lang.image.selectFromFiles + '</label>' +
|
6125
|
-
'<input class="note-image-input form-control
|
6944
|
+
var body = '<div class="form-group note-form-group note-group-select-from-files">' +
|
6945
|
+
'<label class="note-form-label">' + lang.image.selectFromFiles + '</label>' +
|
6946
|
+
'<input class="note-image-input form-control note-form-control note-input" '+
|
6947
|
+
' type="file" name="files" accept="image/*" multiple="multiple" />' +
|
6126
6948
|
imageLimitation +
|
6127
|
-
'</div>' +
|
6949
|
+
'</div>' +
|
6128
6950
|
'<div class="form-group note-group-image-url" style="overflow:auto;">' +
|
6129
|
-
'<label>' + lang.image.url + '</label>' +
|
6130
|
-
'<input class="note-image-url form-control
|
6951
|
+
'<label class="note-form-label">' + lang.image.url + '</label>' +
|
6952
|
+
'<input class="note-image-url form-control note-form-control note-input ' +
|
6953
|
+
' col-md-12" type="text" />' +
|
6131
6954
|
'</div>';
|
6132
|
-
var footer = '<button href="#" class="btn btn-primary note-
|
6955
|
+
var footer = '<button href="#" class="btn btn-primary note-btn note-btn-primary ' +
|
6956
|
+
'note-image-btn disabled" disabled>' + lang.image.insert + '</button>';
|
6133
6957
|
|
6134
6958
|
this.$dialog = ui.dialog({
|
6135
6959
|
title: lang.image.insert,
|
@@ -6220,11 +7044,26 @@
|
|
6220
7044
|
};
|
6221
7045
|
};
|
6222
7046
|
|
7047
|
+
|
7048
|
+
/**
|
7049
|
+
* Image popover module
|
7050
|
+
* mouse events that show/hide popover will be handled by Handle.js.
|
7051
|
+
* Handle.js will receive the events and invoke 'imagePopover.update'.
|
7052
|
+
*/
|
6223
7053
|
var ImagePopover = function (context) {
|
7054
|
+
var self = this;
|
6224
7055
|
var ui = $.summernote.ui;
|
6225
7056
|
|
7057
|
+
var $editable = context.layoutInfo.editable;
|
7058
|
+
var editable = $editable[0];
|
6226
7059
|
var options = context.options;
|
6227
7060
|
|
7061
|
+
this.events = {
|
7062
|
+
'summernote.disable': function () {
|
7063
|
+
self.hide();
|
7064
|
+
}
|
7065
|
+
};
|
7066
|
+
|
6228
7067
|
this.shouldInitialize = function () {
|
6229
7068
|
return !list.isEmpty(options.popover.image);
|
6230
7069
|
};
|
@@ -6233,7 +7072,7 @@
|
|
6233
7072
|
this.$popover = ui.popover({
|
6234
7073
|
className: 'note-image-popover'
|
6235
7074
|
}).render().appendTo('body');
|
6236
|
-
var $content = this.$popover.find('.popover-content');
|
7075
|
+
var $content = this.$popover.find('.popover-content,.note-popover-content');
|
6237
7076
|
|
6238
7077
|
context.invoke('buttons.build', $content, options.popover.image);
|
6239
7078
|
};
|
@@ -6244,6 +7083,72 @@
|
|
6244
7083
|
|
6245
7084
|
this.update = function (target) {
|
6246
7085
|
if (dom.isImg(target)) {
|
7086
|
+
var pos = dom.posFromPlaceholder(target);
|
7087
|
+
var posEditor = dom.posFromPlaceholder(editable);
|
7088
|
+
|
7089
|
+
this.$popover.css({
|
7090
|
+
display: 'block',
|
7091
|
+
left: pos.left,
|
7092
|
+
top: Math.min(pos.top, posEditor.top)
|
7093
|
+
});
|
7094
|
+
} else {
|
7095
|
+
this.hide();
|
7096
|
+
}
|
7097
|
+
};
|
7098
|
+
|
7099
|
+
this.hide = function () {
|
7100
|
+
this.$popover.hide();
|
7101
|
+
};
|
7102
|
+
};
|
7103
|
+
|
7104
|
+
var TablePopover = function (context) {
|
7105
|
+
var self = this;
|
7106
|
+
var ui = $.summernote.ui;
|
7107
|
+
|
7108
|
+
var options = context.options;
|
7109
|
+
|
7110
|
+
this.events = {
|
7111
|
+
'summernote.mousedown': function (we, e) {
|
7112
|
+
self.update(e.target);
|
7113
|
+
},
|
7114
|
+
'summernote.keyup summernote.scroll summernote.change': function () {
|
7115
|
+
self.update();
|
7116
|
+
},
|
7117
|
+
'summernote.disable': function () {
|
7118
|
+
self.hide();
|
7119
|
+
}
|
7120
|
+
};
|
7121
|
+
|
7122
|
+
this.shouldInitialize = function () {
|
7123
|
+
return !list.isEmpty(options.popover.table);
|
7124
|
+
};
|
7125
|
+
|
7126
|
+
this.initialize = function () {
|
7127
|
+
this.$popover = ui.popover({
|
7128
|
+
className: 'note-table-popover'
|
7129
|
+
}).render().appendTo('body');
|
7130
|
+
var $content = this.$popover.find('.popover-content,.note-popover-content');
|
7131
|
+
|
7132
|
+
context.invoke('buttons.build', $content, options.popover.table);
|
7133
|
+
|
7134
|
+
// [workaround] Disable Firefox's default table editor
|
7135
|
+
if (agent.isFF) {
|
7136
|
+
document.execCommand('enableInlineTableEditing', false, false);
|
7137
|
+
}
|
7138
|
+
};
|
7139
|
+
|
7140
|
+
this.destroy = function () {
|
7141
|
+
this.$popover.remove();
|
7142
|
+
};
|
7143
|
+
|
7144
|
+
this.update = function (target) {
|
7145
|
+
if (context.isDisabled()) {
|
7146
|
+
return false;
|
7147
|
+
}
|
7148
|
+
|
7149
|
+
var isCell = dom.isCell(target);
|
7150
|
+
|
7151
|
+
if (isCell) {
|
6247
7152
|
var pos = dom.posFromPlaceholder(target);
|
6248
7153
|
this.$popover.css({
|
6249
7154
|
display: 'block',
|
@@ -6253,6 +7158,8 @@
|
|
6253
7158
|
} else {
|
6254
7159
|
this.hide();
|
6255
7160
|
}
|
7161
|
+
|
7162
|
+
return isCell;
|
6256
7163
|
};
|
6257
7164
|
|
6258
7165
|
this.hide = function () {
|
@@ -6271,11 +7178,13 @@
|
|
6271
7178
|
this.initialize = function () {
|
6272
7179
|
var $container = options.dialogsInBody ? $(document.body) : $editor;
|
6273
7180
|
|
6274
|
-
var body = '<div class="form-group row-fluid">' +
|
6275
|
-
'<label>' + lang.video.url + ' <small class="text-muted">' + lang.video.providers + '</small></label>' +
|
6276
|
-
'<input class="note-video-url form-control span12"
|
7181
|
+
var body = '<div class="form-group note-form-group row-fluid">' +
|
7182
|
+
'<label class="note-form-label">' + lang.video.url + ' <small class="text-muted">' + lang.video.providers + '</small></label>' +
|
7183
|
+
'<input class="note-video-url form-control note-form-control note-input span12" ' +
|
7184
|
+
' type="text" />' +
|
6277
7185
|
'</div>';
|
6278
|
-
var footer = '<button href="#" class="btn btn-primary note-
|
7186
|
+
var footer = '<button href="#" class="btn btn-primary note-btn note-btn-primary ' +
|
7187
|
+
' note-video-btn disabled" disabled>' + lang.video.insert + '</button>';
|
6279
7188
|
|
6280
7189
|
this.$dialog = ui.dialog({
|
6281
7190
|
title: lang.video.insert,
|
@@ -6309,7 +7218,7 @@
|
|
6309
7218
|
var vRegExp = /\/\/vine\.co\/v\/([a-zA-Z0-9]+)/;
|
6310
7219
|
var vMatch = url.match(vRegExp);
|
6311
7220
|
|
6312
|
-
var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*(
|
7221
|
+
var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*(\d+)[?]?.*/;
|
6313
7222
|
var vimMatch = url.match(vimRegExp);
|
6314
7223
|
|
6315
7224
|
var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/;
|
@@ -6318,6 +7227,12 @@
|
|
6318
7227
|
var youkuRegExp = /\/\/v\.youku\.com\/v_show\/id_(\w+)=*\.html/;
|
6319
7228
|
var youkuMatch = url.match(youkuRegExp);
|
6320
7229
|
|
7230
|
+
var qqRegExp = /\/\/v\.qq\.com.*?vid=(.+)/;
|
7231
|
+
var qqMatch = url.match(qqRegExp);
|
7232
|
+
|
7233
|
+
var qqRegExp2 = /\/\/v\.qq\.com\/x?\/?(page|cover).*?\/([^\/]+)\.html\??.*/;
|
7234
|
+
var qqMatch2 = url.match(qqRegExp2);
|
7235
|
+
|
6321
7236
|
var mp4RegExp = /^.+.(mp4|m4v)$/;
|
6322
7237
|
var mp4Match = url.match(mp4RegExp);
|
6323
7238
|
|
@@ -6363,6 +7278,13 @@
|
|
6363
7278
|
.attr('height', '498')
|
6364
7279
|
.attr('width', '510')
|
6365
7280
|
.attr('src', '//player.youku.com/embed/' + youkuMatch[1]);
|
7281
|
+
} else if ((qqMatch && qqMatch[1].length) || (qqMatch2 && qqMatch2[2].length)) {
|
7282
|
+
var vid = ((qqMatch && qqMatch[1].length) ? qqMatch[1]:qqMatch2[2]);
|
7283
|
+
$video = $('<iframe webkitallowfullscreen mozallowfullscreen allowfullscreen>')
|
7284
|
+
.attr('frameborder', 0)
|
7285
|
+
.attr('height', '310')
|
7286
|
+
.attr('width', '500')
|
7287
|
+
.attr('src', 'http://v.qq.com/iframe/player.html?vid=' + vid + '&auto=0');
|
6366
7288
|
} else if (mp4Match || oggMatch || webmMatch) {
|
6367
7289
|
$video = $('<video controls>')
|
6368
7290
|
.attr('src', url)
|
@@ -6464,7 +7386,7 @@
|
|
6464
7386
|
|
6465
7387
|
var body = [
|
6466
7388
|
'<p class="text-center">',
|
6467
|
-
'<a href="http://summernote.org/" target="_blank">Summernote 0.8.
|
7389
|
+
'<a href="http://summernote.org/" target="_blank">Summernote 0.8.8</a> · ',
|
6468
7390
|
'<a href="https://github.com/summernote/summernote" target="_blank">Project</a> · ',
|
6469
7391
|
'<a href="https://github.com/summernote/summernote/issues" target="_blank">Issues</a>',
|
6470
7392
|
'</p>'
|
@@ -6476,7 +7398,7 @@
|
|
6476
7398
|
body: this.createShortCutList(),
|
6477
7399
|
footer: body,
|
6478
7400
|
callback: function ($node) {
|
6479
|
-
$node.find('.modal-body').css({
|
7401
|
+
$node.find('.modal-body,.note-modal-body').css({
|
6480
7402
|
'max-height': 300,
|
6481
7403
|
'overflow': 'scroll'
|
6482
7404
|
});
|
@@ -6524,7 +7446,7 @@
|
|
6524
7446
|
'summernote.keyup summernote.mouseup summernote.scroll': function () {
|
6525
7447
|
self.update();
|
6526
7448
|
},
|
6527
|
-
'summernote.change summernote.dialog.shown': function () {
|
7449
|
+
'summernote.disable summernote.change summernote.dialog.shown': function () {
|
6528
7450
|
self.hide();
|
6529
7451
|
},
|
6530
7452
|
'summernote.focusout': function (we, e) {
|
@@ -6568,6 +7490,7 @@
|
|
6568
7490
|
left: Math.max(bnd.left + bnd.width / 2, 0) - AIR_MODE_POPOVER_X_OFFSET,
|
6569
7491
|
top: bnd.top + bnd.height
|
6570
7492
|
});
|
7493
|
+
context.invoke('buttons.updateCurrentStyle', this.$popover);
|
6571
7494
|
}
|
6572
7495
|
} else {
|
6573
7496
|
this.hide();
|
@@ -6597,7 +7520,7 @@
|
|
6597
7520
|
'summernote.keydown': function (we, e) {
|
6598
7521
|
self.handleKeydown(e);
|
6599
7522
|
},
|
6600
|
-
'summernote.dialog.shown': function () {
|
7523
|
+
'summernote.disable summernote.dialog.shown': function () {
|
6601
7524
|
self.hide();
|
6602
7525
|
}
|
6603
7526
|
};
|
@@ -6616,7 +7539,7 @@
|
|
6616
7539
|
|
6617
7540
|
this.$popover.hide();
|
6618
7541
|
|
6619
|
-
this.$content = this.$popover.find('.popover-content');
|
7542
|
+
this.$content = this.$popover.find('.popover-content,.note-popover-content');
|
6620
7543
|
|
6621
7544
|
this.$content.on('click', '.note-hint-item', function () {
|
6622
7545
|
self.$content.find('.active').removeClass('active');
|
@@ -6675,11 +7598,13 @@
|
|
6675
7598
|
|
6676
7599
|
if ($item.length) {
|
6677
7600
|
var node = this.nodeFromItem($item);
|
7601
|
+
// XXX: consider to move codes to editor for recording redo/undo.
|
6678
7602
|
this.lastWordRange.insertNode(node);
|
6679
7603
|
range.createFromNode(node).collapse().select();
|
6680
7604
|
|
6681
7605
|
this.lastWordRange = null;
|
6682
7606
|
this.hide();
|
7607
|
+
context.triggerEvent('change', context.layoutInfo.editable.html(), context.layoutInfo.editable);
|
6683
7608
|
context.invoke('editor.focus');
|
6684
7609
|
}
|
6685
7610
|
|
@@ -6809,7 +7734,7 @@
|
|
6809
7734
|
|
6810
7735
|
|
6811
7736
|
$.summernote = $.extend($.summernote, {
|
6812
|
-
version: '0.8.
|
7737
|
+
version: '0.8.8',
|
6813
7738
|
ui: ui,
|
6814
7739
|
dom: dom,
|
6815
7740
|
|
@@ -6836,13 +7761,14 @@
|
|
6836
7761
|
'linkPopover': LinkPopover,
|
6837
7762
|
'imageDialog': ImageDialog,
|
6838
7763
|
'imagePopover': ImagePopover,
|
7764
|
+
'tablePopover': TablePopover,
|
6839
7765
|
'videoDialog': VideoDialog,
|
6840
7766
|
'helpDialog': HelpDialog,
|
6841
7767
|
'airPopover': AirPopover
|
6842
7768
|
},
|
6843
7769
|
|
6844
7770
|
buttons: {},
|
6845
|
-
|
7771
|
+
|
6846
7772
|
lang: 'en-US',
|
6847
7773
|
|
6848
7774
|
// toolbar
|
@@ -6867,6 +7793,10 @@
|
|
6867
7793
|
link: [
|
6868
7794
|
['link', ['linkDialogShow', 'unlink']]
|
6869
7795
|
],
|
7796
|
+
table: [
|
7797
|
+
['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
|
7798
|
+
['delete', ['deleteRow', 'deleteCol', 'deleteTable']]
|
7799
|
+
],
|
6870
7800
|
air: [
|
6871
7801
|
['color', ['color']],
|
6872
7802
|
['font', ['bold', 'underline', 'clear']],
|
@@ -6881,6 +7811,7 @@
|
|
6881
7811
|
|
6882
7812
|
width: null,
|
6883
7813
|
height: null,
|
7814
|
+
linkTargetBlank: true,
|
6884
7815
|
|
6885
7816
|
focus: false,
|
6886
7817
|
tabSize: 4,
|
@@ -6888,6 +7819,7 @@
|
|
6888
7819
|
shortcuts: true,
|
6889
7820
|
textareaAutoSync: true,
|
6890
7821
|
direction: null,
|
7822
|
+
tooltip: 'auto',
|
6891
7823
|
|
6892
7824
|
styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
|
6893
7825
|
|
@@ -7009,6 +7941,12 @@
|
|
7009
7941
|
'alignJustify': 'note-icon-align-justify',
|
7010
7942
|
'alignLeft': 'note-icon-align-left',
|
7011
7943
|
'alignRight': 'note-icon-align-right',
|
7944
|
+
'rowBelow': 'note-icon-row-below',
|
7945
|
+
'colBefore': 'note-icon-col-before',
|
7946
|
+
'colAfter': 'note-icon-col-after',
|
7947
|
+
'rowAbove': 'note-icon-row-above',
|
7948
|
+
'rowRemove': 'note-icon-row-remove',
|
7949
|
+
'colRemove': 'note-icon-col-remove',
|
7012
7950
|
'indent': 'note-icon-align-indent',
|
7013
7951
|
'outdent': 'note-icon-align-outdent',
|
7014
7952
|
'arrowsAlt': 'note-icon-arrows-alt',
|
@@ -7024,7 +7962,7 @@
|
|
7024
7962
|
'link': 'note-icon-link',
|
7025
7963
|
'unlink': 'note-icon-chain-broken',
|
7026
7964
|
'magic': 'note-icon-magic',
|
7027
|
-
'menuCheck': 'note-icon-check',
|
7965
|
+
'menuCheck': 'note-icon-menu-check',
|
7028
7966
|
'minus': 'note-icon-minus',
|
7029
7967
|
'orderedlist': 'note-icon-orderedlist',
|
7030
7968
|
'pencil': 'note-icon-pencil',
|