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: f5cb15d8591364b1ceb1017edf2162d29900cee9
4
- data.tar.gz: 7c2d869058695740d1346e0be7fbbf424ac2a4df
3
+ metadata.gz: d45118cd2c6daef234a3b91115d357913e0d586e
4
+ data.tar.gz: 8784f964bfed64720568d152cda3a49945f8e4ee
5
5
  SHA512:
6
- metadata.gz: f1f5990ca679cb884e949d73b2bbc8c1dc5e944f17d9e632b42e52ff90e3910051f122315685704e3345d8b139b2613282ab11e08bc61d1a09e461657a61ad4e
7
- data.tar.gz: 962edc4c209758d9aee11d4a6a948163a203ebf482f2112b0bdd7394e737f7ddebf1b2a16366fc3bf1f5109d7880b03f29ca271e4b204e3b0cb5ba80f1996f8b
6
+ metadata.gz: 41334e91c1d3d7fa593ac98013c465e782ade847ebb2468b8fdee19dac878432433c6177b800c7bde754836fa76e8b94dd462f256a4f2d20e7a7e20c57478d40
7
+ data.tar.gz: af11b642c2fe451e5942ecb2a7ab9ecabc0e0161596b77b137b95bcbd10dc26323dc60fd821393f470019daa38023c8d4eecd40e558b1511df7bad667c046d04
@@ -1,5 +1,5 @@
1
1
  module SummernoteRails
2
2
  module Rails
3
- VERSION = "0.6.9.0"
3
+ VERSION = "0.6.10.0"
4
4
  end
5
5
  end
@@ -9,8 +9,8 @@
9
9
  height: 'Satır yüksekliği',
10
10
  name: 'Yazı Tipi',
11
11
  strikethrough: 'Üstü çizili',
12
- subscript: 'Subscript',
13
- superscript: 'Superscript',
12
+ subscript: 'Alt Simge',
13
+ superscript: 'Üst Simge',
14
14
  size: 'Yazı tipi boyutu'
15
15
  },
16
16
  image: {
@@ -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 = [38, 40, 13];
20
+ var DROPDOWN_KEYCODES = [KEY.UP, KEY.DOWN, KEY.ENTER];
21
21
 
22
22
  /**
23
23
  * @class plugin.hint
24
- *
25
- * Hello Plugin
24
+ *
25
+ * Hint Plugin
26
26
  */
27
27
  $.summernote.addPlugin({
28
- /** @property {String} name name of plugin */
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.html(), $activeItem.data('keyword'));
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
- var triggerChar = keyword.charAt(0);
97
-
98
- if (triggerChar === ':' && keyword.length > 1) {
99
- var trigger = keyword.toLowerCase().replace(':', '');
100
- return {
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
- * create items
113
- *
114
- * @param {Object} searchResult
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.createItem(list[i]));
126
- $item.data('keyword', list[i]);
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
- * create list item template
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 class="list-group" />').css({
184
- position: 'absolute',
185
- 'max-height': 300,
186
- 'overflow-y': 'scroll',
187
- 'display': 'none'
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
- // FIXME We need a handler for unload resources.
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
- $note.on('summernote.keyup', function (customEvent, nativeEvent) {
223
- if (DROPDOWN_KEYCODES.indexOf(nativeEvent.keyCode) === -1) {
224
- var wordRange = $(this).summernote('createRange').getWordRange();
225
- var result = self.searchKeyword(wordRange.toString());
226
- if (!result || !result.list.length) {
227
- $popover.hide();
228
- return;
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
- layoutInfo.popover().append($popover);
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.loadEmojis();
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 false;
266
+ return true;
250
267
  }
251
268
  }
252
269
  });
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Super simple wysiwyg editor on Bootstrap v0.6.8
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-06-21T11:34Z
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
- return function () { return $editor.find(sClassName); };
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 (!dom.isVisiblePoint(point)) {
1717
- if (dom.isLeftEdgePoint(point)) {
1718
- point = dom.nextPointUntil(point, dom.isVisiblePoint);
1719
- } else {
1720
- point = dom.prevPointUntil(point, dom.isVisiblePoint);
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
- return point;
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 startPoint = getVisiblePoint(this.getStartPoint());
1727
- var endPoint = getVisiblePoint(this.getEndPoint());
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 this.normalize();
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.8',
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
- 'opacity' : 0
5002
+ opacity : 0
4953
5003
  });
4954
5004
  layoutInfo.editable().after($paste);
4955
- $paste.one('paste', hPasteClipboardImage);
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.invoke('pasteHTML', $editable, $paste.html());
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
- $paste.remove();
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 = '<ul class="note-table dropdown-menu">' +
5917
- '<div class="note-dimension-picker">' +
5918
- '<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>' +
5919
- '<div class="note-dimension-picker-highlighted"></div>' +
5920
- '<div class="note-dimension-picker-unhighlighted"></div>' +
5921
- '</div>' +
5922
- '<div class="note-dimension-display"> 1 x 1 </div>' +
5923
- '</ul>';
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: '<ul class="dropdown-menu">' + items + '</ul>'
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: '<ul class="dropdown-menu note-check">' + items + '</ul>'
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: '<ul class="dropdown-menu note-check">' + items + '</ul>'
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
- colorButton = tplButton(colorButtonLabel, {
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 dropdown = '<ul class="dropdown-menu">' +
5995
- '<li>' +
5996
- '<div class="btn-group">' +
5997
- '<div class="note-palette-title">' + lang.color.background + '</div>' +
5998
- '<div class="note-color-reset" data-event="backColor"' +
5999
- ' data-value="inherit" title="' + lang.color.transparent + '">' +
6000
- lang.color.setTransparent +
6001
- '</div>' +
6002
- '<div class="note-color-palette" data-target-event="backColor"></div>' +
6003
- '</div>' +
6004
- '<div class="btn-group">' +
6005
- '<div class="note-palette-title">' + lang.color.foreground + '</div>' +
6006
- '<div class="note-color-reset" data-event="foreColor" data-value="inherit" title="' + lang.color.reset + '">' +
6007
- lang.color.resetToDefault +
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: 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 = '<div class="dropdown-menu">' +
6103
- '<div class="note-align btn-group">' +
6104
- leftButton + centerButton + rightButton + justifyButton +
6105
- '</div>' +
6106
- '<div class="note-list btn-group">' +
6107
- indentButton + outdentButton +
6108
- '</div>' +
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: '<ul class="dropdown-menu note-check">' + items + '</ul>'
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.8</a> · ' +
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($editor);
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
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: summernote-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.9.0
4
+ version: 0.6.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hyo Seong Choi