summernote-rails 0.6.9.0 → 0.6.10.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 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