summernote-rails 0.8.3.0 → 0.8.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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',
|