summernote-rails 0.6.9.0 → 0.6.10.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d45118cd2c6daef234a3b91115d357913e0d586e
|
4
|
+
data.tar.gz: 8784f964bfed64720568d152cda3a49945f8e4ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41334e91c1d3d7fa593ac98013c465e782ade847ebb2468b8fdee19dac878432433c6177b800c7bde754836fa76e8b94dd462f256a4f2d20e7a7e20c57478d40
|
7
|
+
data.tar.gz: af11b642c2fe451e5942ecb2a7ab9ecabc0e0161596b77b137b95bcbd10dc26323dc60fd821393f470019daa38023c8d4eecd40e558b1511df7bad667c046d04
|
@@ -8,8 +8,8 @@
|
|
8
8
|
factory(window.jQuery);
|
9
9
|
}
|
10
10
|
}(function ($) {
|
11
|
+
// import core class
|
11
12
|
var range = $.summernote.core.range;
|
12
|
-
var list = $.summernote.core.list;
|
13
13
|
|
14
14
|
var KEY = {
|
15
15
|
UP: 38,
|
@@ -17,17 +17,52 @@
|
|
17
17
|
ENTER: 13
|
18
18
|
};
|
19
19
|
|
20
|
-
var DROPDOWN_KEYCODES = [
|
20
|
+
var DROPDOWN_KEYCODES = [KEY.UP, KEY.DOWN, KEY.ENTER];
|
21
21
|
|
22
22
|
/**
|
23
23
|
* @class plugin.hint
|
24
|
-
*
|
25
|
-
*
|
24
|
+
*
|
25
|
+
* Hint Plugin
|
26
26
|
*/
|
27
27
|
$.summernote.addPlugin({
|
28
|
-
/**
|
28
|
+
/**
|
29
|
+
* name name of plugin
|
30
|
+
* @property {String}
|
31
|
+
**/
|
29
32
|
name: 'hint',
|
30
33
|
|
34
|
+
/**
|
35
|
+
* @property {Regex}
|
36
|
+
* @interface
|
37
|
+
*/
|
38
|
+
match: /[a-z]+/g,
|
39
|
+
|
40
|
+
/**
|
41
|
+
* create list item template
|
42
|
+
*
|
43
|
+
* @interface
|
44
|
+
* @param {Object} search
|
45
|
+
* @returns {Array} created item list
|
46
|
+
*/
|
47
|
+
template: null,
|
48
|
+
|
49
|
+
/**
|
50
|
+
* create inserted content to add in summernote
|
51
|
+
*
|
52
|
+
* @interface
|
53
|
+
* @param {String} html
|
54
|
+
* @param {String} keyword
|
55
|
+
* @return {HTMLEleemnt|String}
|
56
|
+
*/
|
57
|
+
content: null,
|
58
|
+
|
59
|
+
/**
|
60
|
+
* load search list
|
61
|
+
*
|
62
|
+
* @interface
|
63
|
+
*/
|
64
|
+
load: null,
|
65
|
+
|
31
66
|
/**
|
32
67
|
* @param {jQuery} $node
|
33
68
|
*/
|
@@ -76,7 +111,7 @@
|
|
76
111
|
replace: function ($popover) {
|
77
112
|
var wordRange = $popover.data('wordRange');
|
78
113
|
var $activeItem = $popover.find('.active');
|
79
|
-
var content = this.content($activeItem.
|
114
|
+
var content = this.content($activeItem.data('item'));
|
80
115
|
|
81
116
|
if (typeof content === 'string') {
|
82
117
|
content = document.createTextNode(content);
|
@@ -92,38 +127,24 @@
|
|
92
127
|
* @param {String} keyword
|
93
128
|
* @return {Object|null}
|
94
129
|
*/
|
95
|
-
searchKeyword: function (keyword) {
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
type: 'emoji',
|
102
|
-
list: $.grep(this.emojiKeys, function (item) {
|
103
|
-
return item.indexOf(trigger) === 0;
|
104
|
-
})
|
105
|
-
};
|
130
|
+
searchKeyword: function (keyword, callback) {
|
131
|
+
if (this.match.test(keyword)) {
|
132
|
+
var matches = this.match.exec(keyword);
|
133
|
+
this.search(matches[1], callback);
|
134
|
+
} else {
|
135
|
+
callback();
|
106
136
|
}
|
107
|
-
|
108
|
-
return null;
|
109
137
|
},
|
110
138
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
* @param {String} searchResult.type
|
116
|
-
* @param {String[]} searchResult.list
|
117
|
-
* @return {jQuery[]}
|
118
|
-
*/
|
119
|
-
createItems: function (searchResult) {
|
120
|
-
var items = [];
|
121
|
-
var list = searchResult.list;
|
139
|
+
|
140
|
+
createTemplate: function (list) {
|
141
|
+
var items = [];
|
142
|
+
list = list || [];
|
122
143
|
|
123
144
|
for (var i = 0, len = list.length; i < len; i++) {
|
124
145
|
var $item = $('<a class="list-group-item"></a>');
|
125
|
-
$item.append(this.
|
126
|
-
$item.data('
|
146
|
+
$item.append(this.template(list[i]));
|
147
|
+
$item.data('item', list[i]);
|
127
148
|
items.push($item);
|
128
149
|
}
|
129
150
|
|
@@ -134,74 +155,39 @@
|
|
134
155
|
return items;
|
135
156
|
},
|
136
157
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
* @param {Object} item
|
141
|
-
* @returns {String}
|
142
|
-
*/
|
143
|
-
createItem: function (item) {
|
144
|
-
var content = this.emojiInfo[item];
|
145
|
-
return '<img src="' + content + '" width="20" /> :' + item + ':';
|
146
|
-
},
|
147
|
-
|
148
|
-
/**
|
149
|
-
* create inserted content to add in summernote
|
150
|
-
*
|
151
|
-
* @param {String} html
|
152
|
-
* @param {String} keyword
|
153
|
-
* @return {Node|String}
|
154
|
-
*/
|
155
|
-
content: function (html, item) {
|
156
|
-
var url = this.emojiInfo[item];
|
157
|
-
|
158
|
-
if (url) {
|
159
|
-
var $img = $('<img />').attr('src', url).css({
|
160
|
-
width : 20
|
161
|
-
});
|
162
|
-
return $img[0];
|
163
|
-
}
|
164
|
-
|
165
|
-
return html;
|
166
|
-
},
|
167
|
-
|
168
|
-
/**
|
169
|
-
* @return {Promise}
|
170
|
-
*/
|
171
|
-
loadEmojis: function () {
|
172
|
-
var self = this;
|
173
|
-
return $.getJSON('https://api.github.com/emojis').then(function (data) {
|
174
|
-
self.emojiKeys = Object.keys(data);
|
175
|
-
self.emojiInfo = data;
|
176
|
-
});
|
158
|
+
search: function (keyword, callback) {
|
159
|
+
keyword = keyword || '';
|
160
|
+
callback();
|
177
161
|
},
|
178
162
|
|
179
|
-
init: function (layoutInfo) {
|
163
|
+
init : function (layoutInfo) {
|
180
164
|
var self = this;
|
181
165
|
|
182
166
|
var $note = layoutInfo.holder();
|
183
|
-
var $popover = $('<div
|
184
|
-
position: 'absolute',
|
185
|
-
'max-height':
|
186
|
-
'
|
187
|
-
'
|
167
|
+
var $popover = $('<div />').addClass('hint-group').css({
|
168
|
+
'position': 'absolute',
|
169
|
+
'max-height': 150,
|
170
|
+
'z-index' : 999,
|
171
|
+
'overflow' : 'hidden',
|
172
|
+
'display' : 'none',
|
173
|
+
'border' : '1px solid gray',
|
174
|
+
'border-radius' : '5px'
|
188
175
|
});
|
189
176
|
|
190
|
-
|
191
|
-
$popover.on('click', '.list-group-item', function () {
|
177
|
+
$popover.on('click', '.list-group-item', function HintItemClick() {
|
192
178
|
self.replace($popover);
|
193
179
|
|
194
180
|
$popover.hide();
|
195
181
|
$note.summernote('focus');
|
196
182
|
});
|
197
183
|
|
198
|
-
$(document).on('click', function () {
|
184
|
+
$(document).on('click', function HintClick() {
|
199
185
|
$popover.hide();
|
200
186
|
});
|
201
187
|
|
202
|
-
$note.on('summernote.keydown', function (customEvent, nativeEvent) {
|
188
|
+
$note.on('summernote.keydown', function HintKeyDown(customEvent, nativeEvent) {
|
203
189
|
if ($popover.css('display') !== 'block') {
|
204
|
-
return;
|
190
|
+
return true;
|
205
191
|
}
|
206
192
|
|
207
193
|
if (nativeEvent.keyCode === KEY.DOWN) {
|
@@ -219,34 +205,65 @@
|
|
219
205
|
}
|
220
206
|
});
|
221
207
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
208
|
+
var timer = null;
|
209
|
+
$note.on('summernote.keyup', function HintKeyUp(customEvent, nativeEvent) {
|
210
|
+
if (DROPDOWN_KEYCODES.indexOf(nativeEvent.keyCode) > -1) {
|
211
|
+
if (nativeEvent.keyCode === KEY.ENTER) {
|
212
|
+
if ($popover.css('display') === 'block') {
|
213
|
+
return false;
|
214
|
+
}
|
229
215
|
}
|
230
216
|
|
231
|
-
|
217
|
+
} else {
|
218
|
+
|
219
|
+
clearTimeout(timer);
|
220
|
+
timer = setTimeout(function () {
|
221
|
+
var range = $note.summernote('createRange');
|
222
|
+
var word = range.getWordRange();
|
223
|
+
|
224
|
+
self.searchKeyword(word.toString(), function (searchList) {
|
225
|
+
if (!searchList) {
|
226
|
+
$popover.hide();
|
227
|
+
return;
|
228
|
+
}
|
229
|
+
|
230
|
+
if (searchList && !searchList.length) {
|
231
|
+
$popover.hide();
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
|
235
|
+
layoutInfo.popover().append($popover);
|
236
|
+
|
237
|
+
// popover below placeholder.
|
238
|
+
var rects = word.getClientRects();
|
239
|
+
var rect = rects[rects.length - 1];
|
240
|
+
$popover.html(self.createTemplate(searchList)).css({
|
241
|
+
left: rect.left,
|
242
|
+
top: rect.top + rect.height
|
243
|
+
}).data('wordRange', word).show();
|
244
|
+
});
|
245
|
+
}, self.throttle);
|
232
246
|
|
233
|
-
var rect = list.last(wordRange.getClientRects());
|
234
|
-
$popover.html(self.createItems(result)).css({
|
235
|
-
left: rect.left,
|
236
|
-
top: rect.top + rect.height
|
237
|
-
}).data('wordRange', wordRange).show();
|
238
247
|
}
|
239
248
|
});
|
240
249
|
|
241
|
-
this.
|
250
|
+
this.load($popover);
|
242
251
|
},
|
243
252
|
|
253
|
+
throttle : 50,
|
254
|
+
|
244
255
|
// FIXME Summernote doesn't support event pipeline yet.
|
245
256
|
// - Plugin -> Base Code
|
246
257
|
events: {
|
247
|
-
ENTER: function () {
|
258
|
+
ENTER: function (e, editor, layoutInfo) {
|
259
|
+
|
260
|
+
if (layoutInfo.popover().find('.hint-group').css('display') !== 'block') {
|
261
|
+
// apply default enter key
|
262
|
+
layoutInfo.holder().summernote('insertParagraph');
|
263
|
+
}
|
264
|
+
|
248
265
|
// prevent ENTER key
|
249
|
-
return
|
266
|
+
return true;
|
250
267
|
}
|
251
268
|
}
|
252
269
|
});
|
@@ -1,12 +1,12 @@
|
|
1
1
|
/**
|
2
|
-
* Super simple wysiwyg editor on Bootstrap v0.6.
|
2
|
+
* Super simple wysiwyg editor on Bootstrap v0.6.10
|
3
3
|
* http://summernote.org/
|
4
4
|
*
|
5
5
|
* summernote.js
|
6
6
|
* Copyright 2013-2015 Alan Hong. and other contributors
|
7
7
|
* summernote may be freely distributed under the MIT license./
|
8
8
|
*
|
9
|
-
* Date: 2015-
|
9
|
+
* Date: 2015-07-12T14:23Z
|
10
10
|
*/
|
11
11
|
(function (factory) {
|
12
12
|
/* global define */
|
@@ -516,9 +516,14 @@
|
|
516
516
|
|
517
517
|
// frame mode
|
518
518
|
} else {
|
519
|
-
makeFinder = function (sClassName) {
|
520
|
-
|
519
|
+
makeFinder = function (sClassName, sBaseElement) {
|
520
|
+
var $baseElement = sBaseElement ? $(sBaseElement) : $editor;
|
521
|
+
return function () { return $baseElement.find(sClassName); };
|
521
522
|
};
|
523
|
+
|
524
|
+
var options = $editor.data('options');
|
525
|
+
var dialogHolder = (options && options.dialogsInBody) ? document.body : null;
|
526
|
+
|
522
527
|
return {
|
523
528
|
editor: function () { return $editor; },
|
524
529
|
holder : function () { return $editor.data('holder'); },
|
@@ -529,7 +534,7 @@
|
|
529
534
|
statusbar: makeFinder('.note-statusbar'),
|
530
535
|
popover: makeFinder('.note-popover'),
|
531
536
|
handle: makeFinder('.note-handle'),
|
532
|
-
dialog: makeFinder('.note-dialog')
|
537
|
+
dialog: makeFinder('.note-dialog', dialogHolder)
|
533
538
|
};
|
534
539
|
}
|
535
540
|
};
|
@@ -977,6 +982,26 @@
|
|
977
982
|
return true;
|
978
983
|
};
|
979
984
|
|
985
|
+
/**
|
986
|
+
* returns whether point is left edge of ancestor or not.
|
987
|
+
* @param {BoundaryPoint} point
|
988
|
+
* @param {Node} ancestor
|
989
|
+
* @return {Boolean}
|
990
|
+
*/
|
991
|
+
var isLeftEdgePointOf = function (point, ancestor) {
|
992
|
+
return isLeftEdgePoint(point) && isLeftEdgeOf(point.node, ancestor);
|
993
|
+
};
|
994
|
+
|
995
|
+
/**
|
996
|
+
* returns whether point is right edge of ancestor or not.
|
997
|
+
* @param {BoundaryPoint} point
|
998
|
+
* @param {Node} ancestor
|
999
|
+
* @return {Boolean}
|
1000
|
+
*/
|
1001
|
+
var isRightEdgePointOf = function (point, ancestor) {
|
1002
|
+
return isRightEdgePoint(point) && isRightEdgeOf(point.node, ancestor);
|
1003
|
+
};
|
1004
|
+
|
980
1005
|
/**
|
981
1006
|
* returns offset from parent.
|
982
1007
|
*
|
@@ -1485,6 +1510,8 @@
|
|
1485
1510
|
isEdgePoint: isEdgePoint,
|
1486
1511
|
isLeftEdgeOf: isLeftEdgeOf,
|
1487
1512
|
isRightEdgeOf: isRightEdgeOf,
|
1513
|
+
isLeftEdgePointOf: isLeftEdgePointOf,
|
1514
|
+
isRightEdgePointOf: isRightEdgePointOf,
|
1488
1515
|
prevPoint: prevPoint,
|
1489
1516
|
nextPoint: nextPoint,
|
1490
1517
|
isSamePoint: isSamePoint,
|
@@ -1710,21 +1737,37 @@
|
|
1710
1737
|
|
1711
1738
|
/**
|
1712
1739
|
* @param {BoundaryPoint} point
|
1740
|
+
* @param {Boolean} isLeftToRight
|
1713
1741
|
* @return {BoundaryPoint}
|
1714
1742
|
*/
|
1715
|
-
var getVisiblePoint = function (point) {
|
1716
|
-
if (
|
1717
|
-
|
1718
|
-
point
|
1719
|
-
|
1720
|
-
|
1743
|
+
var getVisiblePoint = function (point, isLeftToRight) {
|
1744
|
+
if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) ||
|
1745
|
+
(dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) ||
|
1746
|
+
(dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) ||
|
1747
|
+
(dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) {
|
1748
|
+
return point;
|
1749
|
+
}
|
1750
|
+
|
1751
|
+
// point on block's edge
|
1752
|
+
var block = dom.ancestor(point.node, dom.isBlock);
|
1753
|
+
if ((dom.isLeftEdgePointOf(point, block) && !isLeftToRight) ||
|
1754
|
+
(dom.isRightEdgePointOf(point, block) && isLeftToRight)) {
|
1755
|
+
|
1756
|
+
// returns point already on visible point
|
1757
|
+
if (dom.isVisiblePoint(point)) {
|
1758
|
+
return point;
|
1721
1759
|
}
|
1760
|
+
// reverse direction
|
1761
|
+
isLeftToRight = !isLeftToRight;
|
1722
1762
|
}
|
1723
|
-
|
1763
|
+
|
1764
|
+
var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) :
|
1765
|
+
dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint);
|
1766
|
+
return nextPoint || point;
|
1724
1767
|
};
|
1725
1768
|
|
1726
|
-
var
|
1727
|
-
var
|
1769
|
+
var endPoint = getVisiblePoint(this.getEndPoint(), false);
|
1770
|
+
var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true);
|
1728
1771
|
|
1729
1772
|
return new WrappedRange(
|
1730
1773
|
startPoint.node,
|
@@ -1958,20 +2001,26 @@
|
|
1958
2001
|
return new WrappedRange(sc.firstChild, 0, sc.firstChild, 0);
|
1959
2002
|
}
|
1960
2003
|
|
2004
|
+
/**
|
2005
|
+
* [workaround] firefox often create range on not visible point. so normalize here.
|
2006
|
+
* - firefox: |<p>text</p>|
|
2007
|
+
* - chrome: <p>|text|</p>
|
2008
|
+
*/
|
2009
|
+
var rng = this.normalize();
|
1961
2010
|
if (dom.isParaInline(sc) || dom.isPara(sc)) {
|
1962
|
-
return
|
2011
|
+
return rng;
|
1963
2012
|
}
|
1964
2013
|
|
1965
2014
|
// find inline top ancestor
|
1966
2015
|
var topAncestor;
|
1967
|
-
if (dom.isInline(sc)) {
|
1968
|
-
var ancestors = dom.listAncestor(sc, func.not(dom.isInline));
|
2016
|
+
if (dom.isInline(rng.sc)) {
|
2017
|
+
var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline));
|
1969
2018
|
topAncestor = list.last(ancestors);
|
1970
2019
|
if (!dom.isInline(topAncestor)) {
|
1971
|
-
topAncestor = ancestors[ancestors.length - 2] || sc.childNodes[so];
|
2020
|
+
topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so];
|
1972
2021
|
}
|
1973
2022
|
} else {
|
1974
|
-
topAncestor = sc.childNodes[so > 0 ? so - 1 : 0];
|
2023
|
+
topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0];
|
1975
2024
|
}
|
1976
2025
|
|
1977
2026
|
// siblings not in paragraph
|
@@ -2271,7 +2320,7 @@
|
|
2271
2320
|
*/
|
2272
2321
|
var defaults = {
|
2273
2322
|
/** @property */
|
2274
|
-
version: '0.6.
|
2323
|
+
version: '0.6.10',
|
2275
2324
|
|
2276
2325
|
/**
|
2277
2326
|
*
|
@@ -3386,6 +3435,7 @@
|
|
3386
3435
|
*/
|
3387
3436
|
var Editor = function (handler) {
|
3388
3437
|
|
3438
|
+
var self = this;
|
3389
3439
|
var style = new Style();
|
3390
3440
|
var table = new Table();
|
3391
3441
|
var typing = new Typing();
|
@@ -3474,7 +3524,7 @@
|
|
3474
3524
|
* @return {Boolean} false if range is no
|
3475
3525
|
*/
|
3476
3526
|
this.currentStyle = function (target) {
|
3477
|
-
var rng = range.create();
|
3527
|
+
var rng = range.create().normalize();
|
3478
3528
|
return rng ? rng.isOnEditable() && style.current(rng, target) : false;
|
3479
3529
|
};
|
3480
3530
|
|
@@ -3514,7 +3564,6 @@
|
|
3514
3564
|
triggerOnChange($editable);
|
3515
3565
|
};
|
3516
3566
|
|
3517
|
-
var self = this;
|
3518
3567
|
/**
|
3519
3568
|
* @method beforeCommand
|
3520
3569
|
* before command
|
@@ -3846,9 +3895,8 @@
|
|
3846
3895
|
*/
|
3847
3896
|
this.fontSize = function ($editable, value) {
|
3848
3897
|
var rng = range.create();
|
3849
|
-
var isCollapsed = rng.isCollapsed();
|
3850
3898
|
|
3851
|
-
if (isCollapsed) {
|
3899
|
+
if (rng.isCollapsed()) {
|
3852
3900
|
var spans = style.styleNodes(rng);
|
3853
3901
|
var firstSpan = list.head(spans);
|
3854
3902
|
|
@@ -3939,9 +3987,11 @@
|
|
3939
3987
|
var linkUrl = linkInfo.url;
|
3940
3988
|
var linkText = linkInfo.text;
|
3941
3989
|
var isNewWindow = linkInfo.newWindow;
|
3942
|
-
var rng = linkInfo.range;
|
3990
|
+
var rng = linkInfo.range || this.createRange($editable);
|
3943
3991
|
var isTextChanged = rng.toString() !== linkText;
|
3944
3992
|
|
3993
|
+
options = options || dom.makeLayoutInfo($editable).editor().data('options');
|
3994
|
+
|
3945
3995
|
beforeCommand($editable);
|
3946
3996
|
|
3947
3997
|
if (options.onCreateLink) {
|
@@ -4949,11 +4999,11 @@
|
|
4949
4999
|
$paste = $('<div />').attr('contenteditable', true).css({
|
4950
5000
|
position : 'absolute',
|
4951
5001
|
left : -100000,
|
4952
|
-
|
5002
|
+
opacity : 0
|
4953
5003
|
});
|
4954
5004
|
layoutInfo.editable().after($paste);
|
4955
|
-
$paste.
|
4956
|
-
|
5005
|
+
$paste.on('paste', hPasteClipboardImage);
|
5006
|
+
|
4957
5007
|
layoutInfo.editable().on('keydown', function (e) {
|
4958
5008
|
if (e.ctrlKey && e.keyCode === 86) { // CTRL+V
|
4959
5009
|
handler.invoke('saveRange', layoutInfo.editable());
|
@@ -4967,6 +5017,15 @@
|
|
4967
5017
|
layoutInfo.editable().on('paste', hPasteClipboardImage);
|
4968
5018
|
};
|
4969
5019
|
|
5020
|
+
var hPasteContent = function (handler, $paste, $editable) {
|
5021
|
+
var pasteContent = $('<div />').html($paste.html());
|
5022
|
+
|
5023
|
+
handler.invoke('restoreRange', $editable);
|
5024
|
+
handler.invoke('focus', $editable);
|
5025
|
+
handler.invoke('pasteHTML', $editable, pasteContent.html());
|
5026
|
+
$paste.empty();
|
5027
|
+
};
|
5028
|
+
|
4970
5029
|
/**
|
4971
5030
|
* paste clipboard image
|
4972
5031
|
*
|
@@ -4983,6 +5042,7 @@
|
|
4983
5042
|
var callbacks = $editable.data('callbacks');
|
4984
5043
|
// only can run if it has onImageUpload method
|
4985
5044
|
if (!callbacks.onImageUpload) {
|
5045
|
+
hPasteContent(handler, $paste, $editable);
|
4986
5046
|
return;
|
4987
5047
|
}
|
4988
5048
|
|
@@ -4993,13 +5053,14 @@
|
|
4993
5053
|
|
4994
5054
|
var imgNode = $paste[0].firstChild;
|
4995
5055
|
if (!imgNode) {
|
5056
|
+
hPasteContent(handler, $paste, $editable);
|
4996
5057
|
return;
|
4997
5058
|
}
|
4998
5059
|
|
4999
|
-
handler.invoke('restoreRange', $editable);
|
5000
5060
|
if (!dom.isImg(imgNode)) {
|
5001
|
-
handler
|
5061
|
+
hPasteContent(handler, $paste, $editable);
|
5002
5062
|
} else {
|
5063
|
+
handler.invoke('restoreRange', $editable);
|
5003
5064
|
var datauri = imgNode.src;
|
5004
5065
|
|
5005
5066
|
var data = atob(datauri.split(',')[1]);
|
@@ -5012,9 +5073,9 @@
|
|
5012
5073
|
blob.name = 'clipboard.png';
|
5013
5074
|
handler.invoke('focus', $editable);
|
5014
5075
|
handler.insertImages(layoutInfo, [blob]);
|
5015
|
-
}
|
5016
5076
|
|
5017
|
-
|
5077
|
+
$paste.empty();
|
5078
|
+
}
|
5018
5079
|
|
5019
5080
|
}, 0);
|
5020
5081
|
|
@@ -5865,7 +5926,7 @@
|
|
5865
5926
|
'<div class="popover-content">' +
|
5866
5927
|
'</div>' +
|
5867
5928
|
'</div>');
|
5868
|
-
|
5929
|
+
|
5869
5930
|
$popover.find('.popover-content').append(content);
|
5870
5931
|
return $popover;
|
5871
5932
|
};
|
@@ -5897,6 +5958,23 @@
|
|
5897
5958
|
'</div>';
|
5898
5959
|
};
|
5899
5960
|
|
5961
|
+
/**
|
5962
|
+
* bootstrap dropdown template
|
5963
|
+
*
|
5964
|
+
* @param {String|String[]} contents
|
5965
|
+
* @param {String} [className='']
|
5966
|
+
* @param {String} [nodeName='']
|
5967
|
+
*/
|
5968
|
+
var tplDropdown = function (contents, className, nodeName) {
|
5969
|
+
var classes = 'dropdown-menu' + (className ? ' ' + className : '');
|
5970
|
+
nodeName = nodeName || 'ul';
|
5971
|
+
if (contents instanceof Array) {
|
5972
|
+
contents = contents.join('');
|
5973
|
+
}
|
5974
|
+
|
5975
|
+
return '<' + nodeName + ' class="' + classes + '">' + contents + '</' + nodeName + '>';
|
5976
|
+
};
|
5977
|
+
|
5900
5978
|
var tplButtonInfo = {
|
5901
5979
|
picture: function (lang, options) {
|
5902
5980
|
return tplIconButton(options.iconPrefix + options.icons.image.image, {
|
@@ -5913,17 +5991,18 @@
|
|
5913
5991
|
});
|
5914
5992
|
},
|
5915
5993
|
table: function (lang, options) {
|
5916
|
-
var dropdown =
|
5917
|
-
|
5918
|
-
|
5919
|
-
|
5920
|
-
|
5921
|
-
|
5922
|
-
|
5923
|
-
|
5994
|
+
var dropdown = [
|
5995
|
+
'<div class="note-dimension-picker">',
|
5996
|
+
'<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>',
|
5997
|
+
'<div class="note-dimension-picker-highlighted"></div>',
|
5998
|
+
'<div class="note-dimension-picker-unhighlighted"></div>',
|
5999
|
+
'</div>',
|
6000
|
+
'<div class="note-dimension-display"> 1 x 1 </div>'
|
6001
|
+
];
|
6002
|
+
|
5924
6003
|
return tplIconButton(options.iconPrefix + options.icons.table.table, {
|
5925
6004
|
title: lang.table.table,
|
5926
|
-
dropdown: dropdown
|
6005
|
+
dropdown: tplDropdown(dropdown, 'note-table')
|
5927
6006
|
});
|
5928
6007
|
},
|
5929
6008
|
style: function (lang, options) {
|
@@ -5939,7 +6018,7 @@
|
|
5939
6018
|
|
5940
6019
|
return tplIconButton(options.iconPrefix + options.icons.style.style, {
|
5941
6020
|
title: lang.style.style,
|
5942
|
-
dropdown:
|
6021
|
+
dropdown: tplDropdown(items)
|
5943
6022
|
});
|
5944
6023
|
},
|
5945
6024
|
fontname: function (lang, options) {
|
@@ -5956,14 +6035,14 @@
|
|
5956
6035
|
|
5957
6036
|
var hasDefaultFont = agent.isFontInstalled(options.defaultFontName);
|
5958
6037
|
var defaultFontName = (hasDefaultFont) ? options.defaultFontName : realFontList[0];
|
5959
|
-
|
6038
|
+
|
5960
6039
|
var label = '<span class="note-current-fontname">' +
|
5961
6040
|
defaultFontName +
|
5962
6041
|
'</span>';
|
5963
6042
|
return tplButton(label, {
|
5964
6043
|
title: lang.font.name,
|
5965
6044
|
className: 'note-fontname',
|
5966
|
-
dropdown: '
|
6045
|
+
dropdown: tplDropdown(items, 'note-check')
|
5967
6046
|
});
|
5968
6047
|
},
|
5969
6048
|
fontsize: function (lang, options) {
|
@@ -5977,43 +6056,39 @@
|
|
5977
6056
|
return tplButton(label, {
|
5978
6057
|
title: lang.font.size,
|
5979
6058
|
className: 'note-fontsize',
|
5980
|
-
dropdown: '
|
6059
|
+
dropdown: tplDropdown(items, 'note-check')
|
5981
6060
|
});
|
5982
6061
|
},
|
5983
6062
|
color: function (lang, options) {
|
5984
6063
|
var colorButtonLabel = '<i class="' +
|
5985
6064
|
options.iconPrefix + options.icons.color.recent +
|
5986
|
-
'" style="color:black;background-color:yellow;"></i>'
|
5987
|
-
|
6065
|
+
'" style="color:black;background-color:yellow;"></i>';
|
6066
|
+
|
6067
|
+
var colorButton = tplButton(colorButtonLabel, {
|
5988
6068
|
className: 'note-recent-color',
|
5989
6069
|
title: lang.color.recent,
|
5990
6070
|
event: 'color',
|
5991
6071
|
value: '{"backColor":"yellow"}'
|
5992
6072
|
});
|
5993
6073
|
|
5994
|
-
var
|
5995
|
-
|
5996
|
-
|
5997
|
-
|
5998
|
-
|
5999
|
-
|
6000
|
-
|
6001
|
-
|
6002
|
-
|
6003
|
-
|
6004
|
-
|
6005
|
-
|
6006
|
-
|
6007
|
-
|
6008
|
-
'</div>' +
|
6009
|
-
'<div class="note-color-palette" data-target-event="foreColor"></div>' +
|
6010
|
-
'</div>' +
|
6011
|
-
'</li>' +
|
6012
|
-
'</ul>';
|
6074
|
+
var items = [
|
6075
|
+
'<li><div class="btn-group">',
|
6076
|
+
'<div class="note-palette-title">' + lang.color.background + '</div>',
|
6077
|
+
'<div class="note-color-reset" data-event="backColor"',
|
6078
|
+
' data-value="inherit" title="' + lang.color.transparent + '">' + lang.color.setTransparent + '</div>',
|
6079
|
+
'<div class="note-color-palette" data-target-event="backColor"></div>',
|
6080
|
+
'</div><div class="btn-group">',
|
6081
|
+
'<div class="note-palette-title">' + lang.color.foreground + '</div>',
|
6082
|
+
'<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="' + lang.color.reset + '">',
|
6083
|
+
lang.color.resetToDefault,
|
6084
|
+
'</div>',
|
6085
|
+
'<div class="note-color-palette" data-target-event="foreColor"></div>',
|
6086
|
+
'</div></li>'
|
6087
|
+
];
|
6013
6088
|
|
6014
6089
|
var moreButton = tplButton('', {
|
6015
6090
|
title: lang.color.more,
|
6016
|
-
dropdown:
|
6091
|
+
dropdown: tplDropdown(items)
|
6017
6092
|
});
|
6018
6093
|
|
6019
6094
|
return colorButton + moreButton;
|
@@ -6099,18 +6174,17 @@
|
|
6099
6174
|
event: 'indent'
|
6100
6175
|
});
|
6101
6176
|
|
6102
|
-
var dropdown =
|
6103
|
-
|
6104
|
-
|
6105
|
-
|
6106
|
-
|
6107
|
-
|
6108
|
-
|
6109
|
-
'</div>';
|
6177
|
+
var dropdown = [
|
6178
|
+
'<div class="note-align btn-group">',
|
6179
|
+
leftButton + centerButton + rightButton + justifyButton,
|
6180
|
+
'</div><div class="note-list btn-group">',
|
6181
|
+
indentButton + outdentButton,
|
6182
|
+
'</div>'
|
6183
|
+
];
|
6110
6184
|
|
6111
6185
|
return tplIconButton(options.iconPrefix + options.icons.paragraph.paragraph, {
|
6112
6186
|
title: lang.paragraph.paragraph,
|
6113
|
-
dropdown: dropdown
|
6187
|
+
dropdown: tplDropdown(dropdown, '', 'div')
|
6114
6188
|
});
|
6115
6189
|
},
|
6116
6190
|
height: function (lang, options) {
|
@@ -6122,7 +6196,7 @@
|
|
6122
6196
|
|
6123
6197
|
return tplIconButton(options.iconPrefix + options.icons.font.height, {
|
6124
6198
|
title: lang.font.height,
|
6125
|
-
dropdown: '
|
6199
|
+
dropdown: tplDropdown(items, 'note-check')
|
6126
6200
|
});
|
6127
6201
|
|
6128
6202
|
},
|
@@ -6254,13 +6328,13 @@
|
|
6254
6328
|
var $content = $('<div />');
|
6255
6329
|
for (var idx = 0, len = options.airPopover.length; idx < len; idx ++) {
|
6256
6330
|
var group = options.airPopover[idx];
|
6257
|
-
|
6331
|
+
|
6258
6332
|
var $group = $('<div class="note-' + group[0] + ' btn-group">');
|
6259
6333
|
for (var i = 0, lenGroup = group[1].length; i < lenGroup; i++) {
|
6260
6334
|
var $button = $(tplButtonInfo[group[1][i]](lang, options));
|
6261
6335
|
|
6262
6336
|
$button.attr('data-name', group[1][i]);
|
6263
|
-
|
6337
|
+
|
6264
6338
|
$group.append($button);
|
6265
6339
|
}
|
6266
6340
|
$content.append($group);
|
@@ -6270,14 +6344,14 @@
|
|
6270
6344
|
};
|
6271
6345
|
|
6272
6346
|
var $notePopover = $('<div class="note-popover" />');
|
6273
|
-
|
6347
|
+
|
6274
6348
|
$notePopover.append(tplLinkPopover());
|
6275
6349
|
$notePopover.append(tplImagePopover());
|
6276
|
-
|
6350
|
+
|
6277
6351
|
if (options.airMode) {
|
6278
6352
|
$notePopover.append(tplAirPopover());
|
6279
6353
|
}
|
6280
|
-
|
6354
|
+
|
6281
6355
|
return $notePopover;
|
6282
6356
|
};
|
6283
6357
|
|
@@ -6449,7 +6523,7 @@
|
|
6449
6523
|
'<div class="title">' + lang.shortcut.shortcuts + '</div>' +
|
6450
6524
|
(agent.isMac ? tplShortcutTable(lang, options) : replaceMacKeys(tplShortcutTable(lang, options))) +
|
6451
6525
|
'<p class="text-center">' +
|
6452
|
-
'<a href="//summernote.org/" target="_blank">Summernote 0.6.
|
6526
|
+
'<a href="//summernote.org/" target="_blank">Summernote 0.6.10</a> · ' +
|
6453
6527
|
'<a href="//github.com/summernote/summernote" target="_blank">Project</a> · ' +
|
6454
6528
|
'<a href="//github.com/summernote/summernote/issues" target="_blank">Issues</a>' +
|
6455
6529
|
'</p>';
|
@@ -6640,7 +6714,7 @@
|
|
6640
6714
|
}
|
6641
6715
|
$toolbar.append($group);
|
6642
6716
|
}
|
6643
|
-
|
6717
|
+
|
6644
6718
|
$toolbar.prependTo($editor);
|
6645
6719
|
var keyMap = options.keyMap[agent.isMac ? 'mac' : 'pc'];
|
6646
6720
|
createPalette($toolbar, options);
|
@@ -6654,8 +6728,10 @@
|
|
6654
6728
|
//06. handle(control selection, ...)
|
6655
6729
|
$(tplHandles()).prependTo($editor);
|
6656
6730
|
|
6731
|
+
var $dialogContainer = options.dialogsInBody ? document.body : $editor;
|
6732
|
+
|
6657
6733
|
//07. create Dialog
|
6658
|
-
var $dialog = $(tplDialogs(langInfo, options)).prependTo($
|
6734
|
+
var $dialog = $(tplDialogs(langInfo, options)).prependTo($dialogContainer);
|
6659
6735
|
$dialog.find('button.close, a.modal-close').click(function () {
|
6660
6736
|
$(this).closest('.modal').modal('hide');
|
6661
6737
|
});
|
@@ -6733,6 +6809,9 @@
|
|
6733
6809
|
} else {
|
6734
6810
|
$holder.html(layoutInfo.editable().html());
|
6735
6811
|
|
6812
|
+
if (options.dialogsInBody) {
|
6813
|
+
layoutInfo.dialog().remove();
|
6814
|
+
}
|
6736
6815
|
layoutInfo.editor().remove();
|
6737
6816
|
$holder.show();
|
6738
6817
|
}
|