summernote-rails 0.8.1.1 → 0.8.2.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/summernote-rails/engine.rb +7 -1
  3. data/lib/summernote-rails/version.rb +1 -1
  4. data/vendor/assets/fonts/summernote.eot +0 -0
  5. data/vendor/assets/fonts/summernote.ttf +0 -0
  6. data/vendor/assets/fonts/summernote.woff +0 -0
  7. data/vendor/assets/javascripts/summernote/locales/ar-AR.js +1 -1
  8. data/vendor/assets/javascripts/summernote/locales/bg-BG.js +1 -1
  9. data/vendor/assets/javascripts/summernote/locales/ca-ES.js +3 -3
  10. data/vendor/assets/javascripts/summernote/locales/cs-CZ.js +1 -1
  11. data/vendor/assets/javascripts/summernote/locales/da-DK.js +1 -1
  12. data/vendor/assets/javascripts/summernote/locales/de-DE.js +2 -2
  13. data/vendor/assets/javascripts/summernote/locales/es-ES.js +3 -3
  14. data/vendor/assets/javascripts/summernote/locales/es-EU.js +2 -2
  15. data/vendor/assets/javascripts/summernote/locales/fa-IR.js +2 -2
  16. data/vendor/assets/javascripts/summernote/locales/fi-FI.js +1 -1
  17. data/vendor/assets/javascripts/summernote/locales/fr-FR.js +1 -1
  18. data/vendor/assets/javascripts/summernote/locales/gl-ES.js +147 -0
  19. data/vendor/assets/javascripts/summernote/locales/he-IL.js +1 -1
  20. data/vendor/assets/javascripts/summernote/locales/hr-HR.js +104 -0
  21. data/vendor/assets/javascripts/summernote/locales/hu-HU.js +2 -2
  22. data/vendor/assets/javascripts/summernote/locales/id-ID.js +2 -2
  23. data/vendor/assets/javascripts/summernote/locales/it-IT.js +1 -1
  24. data/vendor/assets/javascripts/summernote/locales/ja-JP.js +30 -1
  25. data/vendor/assets/javascripts/summernote/locales/ko-KR.js +1 -1
  26. data/vendor/assets/javascripts/summernote/locales/lt-LT.js +1 -1
  27. data/vendor/assets/javascripts/summernote/locales/lt-LV.js +135 -0
  28. data/vendor/assets/javascripts/summernote/locales/nb-NO.js +1 -1
  29. data/vendor/assets/javascripts/summernote/locales/nl-NL.js +1 -1
  30. data/vendor/assets/javascripts/summernote/locales/pl-PL.js +2 -2
  31. data/vendor/assets/javascripts/summernote/locales/pt-BR.js +37 -8
  32. data/vendor/assets/javascripts/summernote/locales/pt-PT.js +8 -1
  33. data/vendor/assets/javascripts/summernote/locales/ro-RO.js +2 -2
  34. data/vendor/assets/javascripts/summernote/locales/ru-RU.js +1 -1
  35. data/vendor/assets/javascripts/summernote/locales/sk-SK.js +1 -1
  36. data/vendor/assets/javascripts/summernote/locales/sl-SI.js +1 -1
  37. data/vendor/assets/javascripts/summernote/locales/sr-RS-Latin.js +1 -1
  38. data/vendor/assets/javascripts/summernote/locales/sr-RS.js +1 -1
  39. data/vendor/assets/javascripts/summernote/locales/sv-SE.js +1 -1
  40. data/vendor/assets/javascripts/summernote/locales/th-TH.js +1 -1
  41. data/vendor/assets/javascripts/summernote/locales/tr-TR.js +40 -4
  42. data/vendor/assets/javascripts/summernote/locales/uk-UA.js +1 -1
  43. data/vendor/assets/javascripts/summernote/locales/vi-VN.js +51 -51
  44. data/vendor/assets/javascripts/summernote/locales/zh-CN.js +1 -1
  45. data/vendor/assets/javascripts/summernote/locales/zh-TW.js +1 -1
  46. data/vendor/assets/javascripts/summernote/plugin/databasic/summernote-ext-databasic.css +16 -0
  47. data/vendor/assets/javascripts/summernote/plugin/databasic/summernote-ext-databasic.js +303 -0
  48. data/vendor/assets/javascripts/summernote/plugin/specialchars/summernote-ext-specialchars.js +3 -4
  49. data/vendor/assets/javascripts/summernote/summernote.js +175 -70
  50. data/vendor/assets/stylesheets/summernote.css +1 -1
  51. metadata +7 -2
@@ -85,14 +85,14 @@
85
85
  var $tr = (idx % COLUMN_LENGTH === 0) ? $('<tr/>') : $table.find('tr').last();
86
86
 
87
87
  var $button = ui.button({
88
- callback : function ($node) {
88
+ callback: function ($node) {
89
89
  $node.html(text);
90
90
  $node.attr('title', text);
91
91
  $node.attr('data-value', encodeURIComponent(text));
92
92
  $node.css({
93
93
  width: COLUMN_WIDTH,
94
- 'margin-right' : '2px',
95
- 'margin-bottom' : '2px'
94
+ 'margin-right': '2px',
95
+ 'margin-bottom': '2px'
96
96
  });
97
97
  }
98
98
  }).render();
@@ -293,7 +293,6 @@
293
293
  ui.hideDialog(self.$dialog);
294
294
  });
295
295
 
296
-
297
296
  });
298
297
 
299
298
  ui.onDialogHidden(self.$dialog, function () {
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Super simple wysiwyg editor v0.8.1
2
+ * Super simple wysiwyg editor v0.8.2
3
3
  * http://summernote.org/
4
4
  *
5
5
  * summernote.js
6
- * Copyright 2013-2015 Alan Hong. and other contributors
6
+ * Copyright 2013-2016 Alan Hong. and other contributors
7
7
  * summernote may be freely distributed under the MIT license./
8
8
  *
9
- * Date: 2016-02-15T18:35Z
9
+ * Date: 2016-08-08T01:21Z
10
10
  */
11
11
  (function (factory) {
12
12
  /* global define */
@@ -140,6 +140,35 @@
140
140
  }).join('');
141
141
  };
142
142
 
143
+ /**
144
+ * Returns a function, that, as long as it continues to be invoked, will not
145
+ * be triggered. The function will be called after it stops being called for
146
+ * N milliseconds. If `immediate` is passed, trigger the function on the
147
+ * leading edge, instead of the trailing.
148
+ * @param {Function} func
149
+ * @param {Number} wait
150
+ * @param {Boolean} immediate
151
+ * @return {Function}
152
+ */
153
+ var debounce = function (func, wait, immediate) {
154
+ var timeout;
155
+ return function () {
156
+ var context = this, args = arguments;
157
+ var later = function () {
158
+ timeout = null;
159
+ if (!immediate) {
160
+ func.apply(context, args);
161
+ }
162
+ };
163
+ var callNow = immediate && !timeout;
164
+ clearTimeout(timeout);
165
+ timeout = setTimeout(later, wait);
166
+ if (callNow) {
167
+ func.apply(context, args);
168
+ }
169
+ };
170
+ };
171
+
143
172
  return {
144
173
  eq: eq,
145
174
  eq2: eq2,
@@ -153,7 +182,8 @@
153
182
  uniqueId: uniqueId,
154
183
  rect2bnd: rect2bnd,
155
184
  invertObject: invertObject,
156
- namespaceToCamel: namespaceToCamel
185
+ namespaceToCamel: namespaceToCamel,
186
+ debounce: debounce
157
187
  };
158
188
  })();
159
189
 
@@ -294,7 +324,7 @@
294
324
  };
295
325
 
296
326
  /**
297
- * returns a copy of the array with all falsy values removed
327
+ * returns a copy of the array with all false values removed
298
328
  *
299
329
  * @param {Array} array - array
300
330
  * @param {Function} fn - predicate function for cluster rule
@@ -394,18 +424,18 @@
394
424
  var isEdge = /Edge\/\d+/.test(userAgent);
395
425
 
396
426
  var hasCodeMirror = !!window.CodeMirror;
397
- if (!hasCodeMirror && isSupportAmd && require) {
398
- if (require.hasOwnProperty('resolve')) {
427
+ if (!hasCodeMirror && isSupportAmd && typeof require !== 'undefined') {
428
+ if (typeof require.resolve !== 'undefined') {
399
429
  try {
400
430
  // If CodeMirror can't be resolved, `require.resolve` will throw an
401
431
  // exception and `hasCodeMirror` won't be set to `true`.
402
432
  require.resolve('codemirror');
403
433
  hasCodeMirror = true;
404
434
  } catch (e) {
405
- hasCodeMirror = false;
435
+ // Do nothing.
406
436
  }
407
- } else if (require.hasOwnProperty('specified')) {
408
- hasCodeMirror = require.specified('codemirror');
437
+ } else if (typeof eval('require').specified !== 'undefined') {
438
+ hasCodeMirror = eval('require').specified('codemirror');
409
439
  }
410
440
  }
411
441
 
@@ -541,13 +571,16 @@
541
571
 
542
572
  var isTable = makePredByNodeName('TABLE');
543
573
 
574
+ var isData = makePredByNodeName('DATA');
575
+
544
576
  var isInline = function (node) {
545
577
  return !isBodyContainer(node) &&
546
578
  !isList(node) &&
547
579
  !isHr(node) &&
548
580
  !isPara(node) &&
549
581
  !isTable(node) &&
550
- !isBlockquote(node);
582
+ !isBlockquote(node) &&
583
+ !isData(node);
551
584
  };
552
585
 
553
586
  var isList = function (node) {
@@ -629,8 +662,13 @@
629
662
  if (isText(node)) {
630
663
  return node.nodeValue.length;
631
664
  }
632
-
633
- return node.childNodes.length;
665
+
666
+ if (node) {
667
+ return node.childNodes.length;
668
+ }
669
+
670
+ return 0;
671
+
634
672
  };
635
673
 
636
674
  /**
@@ -902,6 +940,9 @@
902
940
  * @return {Boolean}
903
941
  */
904
942
  var isRightEdgeOf = function (node, ancestor) {
943
+ if (!ancestor) {
944
+ return false;
945
+ }
905
946
  while (node && node !== ancestor) {
906
947
  if (position(node) !== nodeLength(node.parentNode) - 1) {
907
948
  return false;
@@ -1024,7 +1065,7 @@
1024
1065
 
1025
1066
  /**
1026
1067
  * returns whether point is visible (can set cursor) or not.
1027
- *
1068
+ *
1028
1069
  * @param {BoundaryPoint} point
1029
1070
  * @return {Boolean}
1030
1071
  */
@@ -1440,6 +1481,7 @@
1440
1481
  isPre: isPre,
1441
1482
  isList: isList,
1442
1483
  isTable: isTable,
1484
+ isData: isData,
1443
1485
  isCell: isCell,
1444
1486
  isBlockquote: isBlockquote,
1445
1487
  isBodyContainer: isBodyContainer,
@@ -1730,6 +1772,7 @@
1730
1772
 
1731
1773
  options = $.extend({}, $.summernote.options, options);
1732
1774
  options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]);
1775
+ options.icons = $.extend(true, {}, $.summernote.options.icons, options.icons);
1733
1776
 
1734
1777
  this.each(function (idx, note) {
1735
1778
  var $note = $(note);
@@ -1832,7 +1875,7 @@
1832
1875
  var airEditable = renderer.create('<div class="note-editable" contentEditable="true"/>');
1833
1876
 
1834
1877
  var buttonGroup = renderer.create('<div class="note-btn-group btn-group">');
1835
- var button = renderer.create('<button type="button" class="note-btn btn btn-default btn-sm">', function ($node, options) {
1878
+ var button = renderer.create('<button type="button" class="note-btn btn btn-default btn-sm" tabindex="-1">', function ($node, options) {
1836
1879
  if (options && options.tooltip) {
1837
1880
  $node.attr({
1838
1881
  title: options.tooltip
@@ -2684,8 +2727,10 @@
2684
2727
  this.isOnList = makeIsOn(dom.isList);
2685
2728
  // isOnAnchor: judge whether range is on anchor node or not
2686
2729
  this.isOnAnchor = makeIsOn(dom.isAnchor);
2687
- // isOnAnchor: judge whether range is on cell node or not
2730
+ // isOnCell: judge whether range is on cell node or not
2688
2731
  this.isOnCell = makeIsOn(dom.isCell);
2732
+ // isOnData: judge whether range is on data node or not
2733
+ this.isOnData = makeIsOn(dom.isData);
2689
2734
 
2690
2735
  /**
2691
2736
  * @param {Function} pred
@@ -3744,8 +3789,12 @@
3744
3789
  }
3745
3790
  context.triggerEvent('keydown', event);
3746
3791
 
3747
- if (options.shortcuts && !event.isDefaultPrevented()) {
3748
- self.handleKeyMap(event);
3792
+ if (!event.isDefaultPrevented()) {
3793
+ if (options.shortcuts) {
3794
+ self.handleKeyMap(event);
3795
+ } else {
3796
+ self.preventDefaultEditableShortCuts(event);
3797
+ }
3749
3798
  }
3750
3799
  }).on('keyup', function (event) {
3751
3800
  context.triggerEvent('keyup', event);
@@ -3769,9 +3818,9 @@
3769
3818
  // [workaround] IE doesn't have input events for contentEditable
3770
3819
  // - see: https://goo.gl/4bfIvA
3771
3820
  var changeEventName = agent.isMSIE ? 'DOMCharacterDataModified DOMSubtreeModified DOMNodeInserted' : 'input';
3772
- $editable.on(changeEventName, function () {
3821
+ $editable.on(changeEventName, func.debounce(function () {
3773
3822
  context.triggerEvent('change', $editable.html());
3774
- });
3823
+ }, 250));
3775
3824
 
3776
3825
  $editor.on('focusin', function (event) {
3777
3826
  context.triggerEvent('focusin', event);
@@ -3779,14 +3828,19 @@
3779
3828
  context.triggerEvent('focusout', event);
3780
3829
  });
3781
3830
 
3782
- if (!options.airMode && options.height) {
3783
- this.setHeight(options.height);
3784
- }
3785
- if (!options.airMode && options.maxHeight) {
3786
- $editable.css('max-height', options.maxHeight);
3787
- }
3788
- if (!options.airMode && options.minHeight) {
3789
- $editable.css('min-height', options.minHeight);
3831
+ if (!options.airMode) {
3832
+ if (options.width) {
3833
+ $editor.outerWidth(options.width);
3834
+ }
3835
+ if (options.height) {
3836
+ $editable.outerHeight(options.height);
3837
+ }
3838
+ if (options.maxHeight) {
3839
+ $editable.css('max-height', options.maxHeight);
3840
+ }
3841
+ if (options.minHeight) {
3842
+ $editable.css('min-height', options.minHeight);
3843
+ }
3790
3844
  }
3791
3845
 
3792
3846
  history.recordUndo();
@@ -3818,6 +3872,14 @@
3818
3872
  }
3819
3873
  };
3820
3874
 
3875
+ this.preventDefaultEditableShortCuts = function (event) {
3876
+ // B(Bold, 66) / I(Italic, 73) / U(Underline, 85)
3877
+ if ((event.ctrlKey || event.metaKey) &&
3878
+ list.contains([66, 73, 85], event.keyCode)) {
3879
+ event.preventDefault();
3880
+ }
3881
+ };
3882
+
3821
3883
  /**
3822
3884
  * create range
3823
3885
  * @return {WrappedRange}
@@ -4255,6 +4317,11 @@
4255
4317
  var rng = linkInfo.range || this.createRange();
4256
4318
  var isTextChanged = rng.toString() !== linkText;
4257
4319
 
4320
+ // handle spaced urls from input
4321
+ if (typeof linkUrl === 'string') {
4322
+ linkUrl = linkUrl.trim();
4323
+ }
4324
+
4258
4325
  if (options.onCreateLink) {
4259
4326
  linkUrl = options.onCreateLink(linkUrl);
4260
4327
  }
@@ -4273,6 +4340,10 @@
4273
4340
  }
4274
4341
 
4275
4342
  $.each(anchors, function (idx, anchor) {
4343
+ // if url doesn't match an URL schema, set http:// as default
4344
+ linkUrl = /^[A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?/.test(linkUrl) ?
4345
+ linkUrl : 'http://' + linkUrl;
4346
+
4276
4347
  $(anchor).attr('href', linkUrl);
4277
4348
  if (isNewWindow) {
4278
4349
  $(anchor).attr('target', '_blank');
@@ -4430,13 +4501,6 @@
4430
4501
  this.empty = function () {
4431
4502
  context.invoke('code', dom.emptyPara);
4432
4503
  };
4433
-
4434
- /**
4435
- * set height for editable
4436
- */
4437
- this.setHeight = function (height) {
4438
- $editable.outerHeight(height);
4439
- };
4440
4504
  };
4441
4505
 
4442
4506
  var Clipboard = function (context) {
@@ -4468,7 +4532,7 @@
4468
4532
  // - IE11 and Firefox: CTRL+v hook
4469
4533
  // - Webkit: event.clipboardData
4470
4534
  if (this.needKeydownHook()) {
4471
- this.$paste = $('<div />').attr('contenteditable', true).css({
4535
+ this.$paste = $('<div tabindex="-1" />').attr('contenteditable', true).css({
4472
4536
  position: 'absolute',
4473
4537
  left: -100000,
4474
4538
  opacity: 0
@@ -4543,6 +4607,7 @@
4543
4607
  var $editable = context.layoutInfo.editable;
4544
4608
  var options = context.options;
4545
4609
  var lang = options.langInfo;
4610
+ var documentEventHandlers = {};
4546
4611
 
4547
4612
  var $dropzone = $([
4548
4613
  '<div class="note-dropzone">',
@@ -4550,15 +4615,23 @@
4550
4615
  '</div>'
4551
4616
  ].join('')).prependTo($editor);
4552
4617
 
4618
+ var detachDocumentEvent = function () {
4619
+ Object.keys(documentEventHandlers).forEach(function (key) {
4620
+ $document.off(key.substr(2).toLowerCase(), documentEventHandlers[key]);
4621
+ });
4622
+ documentEventHandlers = {};
4623
+ };
4624
+
4553
4625
  /**
4554
4626
  * attach Drag and Drop Events
4555
4627
  */
4556
4628
  this.initialize = function () {
4557
4629
  if (options.disableDragAndDrop) {
4558
4630
  // prevent default drop event
4559
- $document.on('drop', function (e) {
4631
+ documentEventHandlers.onDrop = function (e) {
4560
4632
  e.preventDefault();
4561
- });
4633
+ };
4634
+ $document.on('drop', documentEventHandlers.onDrop);
4562
4635
  } else {
4563
4636
  this.attachDragAndDropEvent();
4564
4637
  }
@@ -4571,9 +4644,7 @@
4571
4644
  var collection = $(),
4572
4645
  $dropzoneMessage = $dropzone.find('.note-dropzone-message');
4573
4646
 
4574
- // show dropzone on dragenter when dragging a object to document
4575
- // -but only if the editor is visible, i.e. has a positive width and height
4576
- $document.on('dragenter', function (e) {
4647
+ documentEventHandlers.onDragenter = function (e) {
4577
4648
  var isCodeview = context.invoke('codeview.isActivated');
4578
4649
  var hasEditorSize = $editor.width() > 0 && $editor.height() > 0;
4579
4650
  if (!isCodeview && !collection.length && hasEditorSize) {
@@ -4583,15 +4654,25 @@
4583
4654
  $dropzoneMessage.text(lang.image.dragImageHere);
4584
4655
  }
4585
4656
  collection = collection.add(e.target);
4586
- }).on('dragleave', function (e) {
4657
+ };
4658
+
4659
+ documentEventHandlers.onDragleave = function (e) {
4587
4660
  collection = collection.not(e.target);
4588
4661
  if (!collection.length) {
4589
4662
  $editor.removeClass('dragover');
4590
4663
  }
4591
- }).on('drop', function () {
4664
+ };
4665
+
4666
+ documentEventHandlers.onDrop = function () {
4592
4667
  collection = $();
4593
4668
  $editor.removeClass('dragover');
4594
- });
4669
+ };
4670
+
4671
+ // show dropzone on dragenter when dragging a object to document
4672
+ // -but only if the editor is visible, i.e. has a positive width and height
4673
+ $document.on('dragenter', documentEventHandlers.onDragenter)
4674
+ .on('dragleave', documentEventHandlers.onDragleave)
4675
+ .on('drop', documentEventHandlers.onDrop);
4595
4676
 
4596
4677
  // change dropzone's message on hover.
4597
4678
  $dropzone.on('dragenter', function () {
@@ -4625,6 +4706,10 @@
4625
4706
  }
4626
4707
  }).on('dragover', false); // prevent default dragover event
4627
4708
  };
4709
+
4710
+ this.destroy = function () {
4711
+ detachDocumentEvent();
4712
+ };
4628
4713
  };
4629
4714
 
4630
4715
 
@@ -4772,6 +4857,7 @@
4772
4857
 
4773
4858
  this.destroy = function () {
4774
4859
  $statusbar.off();
4860
+ $statusbar.remove();
4775
4861
  };
4776
4862
  };
4777
4863
 
@@ -4938,7 +5024,7 @@
4938
5024
  var AutoLink = function (context) {
4939
5025
  var self = this;
4940
5026
  var defaultScheme = 'http://';
4941
- var linkPattern = /^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|mailto:[A-Z0-9._%+-]+@)?(www\.)?(.+)$/i;
5027
+ var linkPattern = /^([A-Za-z][A-Za-z0-9+-.]*\:[\/\/]?|mailto:[A-Z0-9._%+-]+@)?(www\.)?(.+)$/i;
4942
5028
 
4943
5029
  this.events = {
4944
5030
  'summernote.keyup': function (we, e) {
@@ -5056,6 +5142,10 @@
5056
5142
 
5057
5143
  var representShortcut = this.representShortcut = function (editorMethod) {
5058
5144
  var shortcut = invertedKeyMap[editorMethod];
5145
+ if (!options.shortcuts || !shortcut) {
5146
+ return '';
5147
+ }
5148
+
5059
5149
  if (agent.isMac) {
5060
5150
  shortcut = shortcut.replace('CMD', '⌘').replace('SHIFT', '⇧');
5061
5151
  }
@@ -5105,13 +5195,13 @@
5105
5195
  template: function (item) {
5106
5196
 
5107
5197
  if (typeof item === 'string') {
5108
- item = { tag: item, title: item };
5198
+ item = { tag: item, title: (lang.style.hasOwnProperty(item) ? lang.style[item] : item) };
5109
5199
  }
5110
5200
 
5111
5201
  var tag = item.tag;
5112
5202
  var title = item.title;
5113
5203
  var style = item.style ? ' style="' + item.style + '" ' : '';
5114
- var className = item.className ? ' className="' + item.className + '"' : '';
5204
+ var className = item.className ? ' class="' + item.className + '"' : '';
5115
5205
 
5116
5206
  return '<' + tag + style + className + '>' + title + '</' + tag + '>';
5117
5207
  },
@@ -5441,7 +5531,7 @@
5441
5531
  context.memo('button.link', function () {
5442
5532
  return ui.button({
5443
5533
  contents: ui.icon(options.icons.link),
5444
- tooltip: lang.link.link,
5534
+ tooltip: lang.link.link + representShortcut('linkDialog.show'),
5445
5535
  click: context.createInvokeHandler('linkDialog.show')
5446
5536
  }).render();
5447
5537
  });
@@ -5838,6 +5928,13 @@
5838
5928
  });
5839
5929
  };
5840
5930
 
5931
+ /**
5932
+ * toggle update button
5933
+ */
5934
+ this.toggleLinkBtn = function ($linkBtn, $linkText, $linkUrl) {
5935
+ ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());
5936
+ };
5937
+
5841
5938
  /**
5842
5939
  * Show link dialog and set event handlers on dialog controls.
5843
5940
  *
@@ -5854,30 +5951,38 @@
5854
5951
  ui.onDialogShown(self.$dialog, function () {
5855
5952
  context.triggerEvent('dialog.shown');
5856
5953
 
5954
+ // if no url was given, copy text to url
5955
+ if (!linkInfo.url) {
5956
+ linkInfo.url = linkInfo.text;
5957
+ }
5958
+
5857
5959
  $linkText.val(linkInfo.text);
5858
5960
 
5859
- $linkText.on('input', function () {
5860
- ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());
5961
+ var handleLinkTextUpdate = function () {
5962
+ self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
5861
5963
  // if linktext was modified by keyup,
5862
5964
  // stop cloning text from linkUrl
5863
5965
  linkInfo.text = $linkText.val();
5864
- });
5966
+ };
5865
5967
 
5866
- // if no url was given, copy text to url
5867
- if (!linkInfo.url) {
5868
- linkInfo.url = linkInfo.text || 'http://';
5869
- ui.toggleBtn($linkBtn, linkInfo.text);
5870
- }
5968
+ $linkText.on('input', handleLinkTextUpdate).on('paste', function () {
5969
+ setTimeout(handleLinkTextUpdate, 0);
5970
+ });
5871
5971
 
5872
- $linkUrl.on('input', function () {
5873
- ui.toggleBtn($linkBtn, $linkText.val() && $linkUrl.val());
5972
+ var handleLinkUrlUpdate = function () {
5973
+ self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
5874
5974
  // display same link on `Text to display` input
5875
5975
  // when create a new link
5876
5976
  if (!linkInfo.text) {
5877
5977
  $linkText.val($linkUrl.val());
5878
5978
  }
5979
+ };
5980
+
5981
+ $linkUrl.on('input', handleLinkUrlUpdate).on('paste', function () {
5982
+ setTimeout(handleLinkUrlUpdate, 0);
5879
5983
  }).val(linkInfo.url).trigger('focus');
5880
5984
 
5985
+ self.toggleLinkBtn($linkBtn, $linkText, $linkUrl);
5881
5986
  self.bindEnterKey($linkUrl, $linkBtn);
5882
5987
  self.bindEnterKey($linkText, $linkBtn);
5883
5988
 
@@ -5898,8 +6003,8 @@
5898
6003
 
5899
6004
  ui.onDialogHidden(self.$dialog, function () {
5900
6005
  // detach events
5901
- $linkText.off('input keypress');
5902
- $linkUrl.off('input keypress');
6006
+ $linkText.off('input paste keypress');
6007
+ $linkUrl.off('input paste keypress');
5903
6008
  $linkBtn.off('click');
5904
6009
 
5905
6010
  if (deferred.state() === 'pending') {
@@ -6017,7 +6122,7 @@
6017
6122
  '<input class="note-image-input form-control" type="file" name="files" accept="image/*" multiple="multiple" />' +
6018
6123
  imageLimitation +
6019
6124
  '</div>' +
6020
- '<div class="form-group" style="overflow:auto;">' +
6125
+ '<div class="form-group note-group-image-url" style="overflow:auto;">' +
6021
6126
  '<label>' + lang.image.url + '</label>' +
6022
6127
  '<input class="note-image-url form-control col-md-12" type="text" />' +
6023
6128
  '</div>';
@@ -6195,13 +6300,13 @@
6195
6300
  var ytRegExp = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
6196
6301
  var ytMatch = url.match(ytRegExp);
6197
6302
 
6198
- var igRegExp = /\/\/instagram.com\/p\/(.[a-zA-Z0-9_-]*)/;
6303
+ var igRegExp = /(?:www\.|\/\/)instagram\.com\/p\/(.[a-zA-Z0-9_-]*)/;
6199
6304
  var igMatch = url.match(igRegExp);
6200
6305
 
6201
- var vRegExp = /\/\/vine.co\/v\/(.[a-zA-Z0-9]*)/;
6306
+ var vRegExp = /\/\/vine\.co\/v\/([a-zA-Z0-9]+)/;
6202
6307
  var vMatch = url.match(vRegExp);
6203
6308
 
6204
- var vimRegExp = /\/\/(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
6309
+ var vimRegExp = /\/\/(player\.)?vimeo\.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
6205
6310
  var vimMatch = url.match(vimRegExp);
6206
6311
 
6207
6312
  var dmRegExp = /.+dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/;
@@ -6229,7 +6334,7 @@
6229
6334
  } else if (igMatch && igMatch[0].length) {
6230
6335
  $video = $('<iframe>')
6231
6336
  .attr('frameborder', 0)
6232
- .attr('src', igMatch[0] + '/embed/')
6337
+ .attr('src', 'https://instagram.com/p/' + igMatch[1] + '/embed/')
6233
6338
  .attr('width', '612').attr('height', '710')
6234
6339
  .attr('scrolling', 'no')
6235
6340
  .attr('allowtransparency', 'true');
@@ -6356,9 +6461,9 @@
6356
6461
 
6357
6462
  var body = [
6358
6463
  '<p class="text-center">',
6359
- '<a href="//summernote.org/" target="_blank">Summernote 0.8.1</a> · ',
6360
- '<a href="//github.com/summernote/summernote" target="_blank">Project</a> · ',
6361
- '<a href="//github.com/summernote/summernote/issues" target="_blank">Issues</a>',
6464
+ '<a href="http://summernote.org/" target="_blank">Summernote 0.8.2</a> · ',
6465
+ '<a href="https://github.com/summernote/summernote" target="_blank">Project</a> · ',
6466
+ '<a href="https://github.com/summernote/summernote/issues" target="_blank">Issues</a>',
6362
6467
  '</p>'
6363
6468
  ].join('');
6364
6469
 
@@ -6701,8 +6806,9 @@
6701
6806
 
6702
6807
 
6703
6808
  $.summernote = $.extend($.summernote, {
6704
- version: '0.8.1',
6809
+ version: '0.8.2',
6705
6810
  ui: ui,
6811
+ dom: dom,
6706
6812
 
6707
6813
  plugins: {},
6708
6814
 
@@ -6823,7 +6929,6 @@
6823
6929
  onEnter: null,
6824
6930
  onKeyup: null,
6825
6931
  onKeydown: null,
6826
- onSubmit: null,
6827
6932
  onImageUpload: null,
6828
6933
  onImageUploadError: null
6829
6934
  },