tinymce-rails 3.5.4.1 → 3.5.5

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 (29) hide show
  1. data/lib/tinymce/rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/tinymce/plugins/advimage/js/image.js +5 -3
  3. data/vendor/assets/javascripts/tinymce/plugins/autolink/editor_plugin.js +1 -1
  4. data/vendor/assets/javascripts/tinymce/plugins/autolink/editor_plugin_src.js +184 -181
  5. data/vendor/assets/javascripts/tinymce/plugins/autoresize/editor_plugin_src.js +119 -119
  6. data/vendor/assets/javascripts/tinymce/plugins/emotions/langs/en_dlg.js +1 -1
  7. data/vendor/assets/javascripts/tinymce/plugins/example_dependency/editor_plugin_src.js +50 -50
  8. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/editor_plugin.js +1 -1
  9. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/editor_plugin_src.js +4 -4
  10. data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin.js +1 -1
  11. data/vendor/assets/javascripts/tinymce/plugins/lists/editor_plugin_src.js +956 -952
  12. data/vendor/assets/javascripts/tinymce/plugins/media/js/media.js +34 -1
  13. data/vendor/assets/javascripts/tinymce/plugins/media/langs/en_dlg.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/noneditable/editor_plugin.js +1 -1
  15. data/vendor/assets/javascripts/tinymce/plugins/noneditable/editor_plugin_src.js +1 -4
  16. data/vendor/assets/javascripts/tinymce/plugins/style/langs/en_dlg.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/style/props.htm +845 -845
  18. data/vendor/assets/javascripts/tinymce/plugins/style/readme.txt +19 -19
  19. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/editor_plugin_src.js +122 -122
  20. data/vendor/assets/javascripts/tinymce/plugins/table/editor_plugin_src.js +1449 -1449
  21. data/vendor/assets/javascripts/tinymce/themes/advanced/editor_template.js +1 -1
  22. data/vendor/assets/javascripts/tinymce/themes/advanced/editor_template_src.js +2 -1
  23. data/vendor/assets/javascripts/tinymce/themes/advanced/js/color_picker.js +345 -345
  24. data/vendor/assets/javascripts/tinymce/themes/advanced/langs/en_dlg.js +1 -1
  25. data/vendor/assets/javascripts/tinymce/tiny_mce.js +1 -1
  26. data/vendor/assets/javascripts/tinymce/tiny_mce_jquery.js +1 -1
  27. data/vendor/assets/javascripts/tinymce/tiny_mce_jquery_src.js +277 -75
  28. data/vendor/assets/javascripts/tinymce/tiny_mce_src.js +277 -75
  29. metadata +5 -7
@@ -6,9 +6,9 @@
6
6
  var tinymce = {
7
7
  majorVersion : '3',
8
8
 
9
- minorVersion : '5.4.1',
9
+ minorVersion : '5.5',
10
10
 
11
- releaseDate : '2012-06-24',
11
+ releaseDate : '2012-07-19',
12
12
 
13
13
  _init : function() {
14
14
  var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
@@ -1086,7 +1086,8 @@ tinymce.create('static tinymce.util.XHR', {
1086
1086
  },
1087
1087
 
1088
1088
  metaKeyPressed: function(e) {
1089
- return tinymce.isMac ? e.metaKey : e.ctrlKey;
1089
+ // Check if ctrl or meta key is pressed also check if alt is false for Polish users
1090
+ return tinymce.isMac ? e.metaKey : e.ctrlKey && !e.altKey;
1090
1091
  }
1091
1092
  };
1092
1093
  })(tinymce);
@@ -1180,7 +1181,7 @@ tinymce.util.Quirks = function(editor) {
1180
1181
  var allRng = dom.createRng();
1181
1182
  allRng.selectNode(editor.getBody());
1182
1183
 
1183
- var allSelection = serializeRng(allRng);//console.log(selection, "----", allSelection);
1184
+ var allSelection = serializeRng(allRng);
1184
1185
  return selection === allSelection;
1185
1186
  }
1186
1187
 
@@ -1632,77 +1633,237 @@ tinymce.util.Quirks = function(editor) {
1632
1633
  };
1633
1634
 
1634
1635
  function fakeImageResize() {
1635
- var mouseDownImg, startX, startY, startW, startH;
1636
+ var selectedElmX, selectedElmY, selectedElm, selectedElmGhost, selectedHandle, startX, startY, startW, startH,
1637
+ resizeHandles, width, height, rootDocument = document, editableDoc = editor.getDoc();
1636
1638
 
1637
1639
  if (!settings.object_resizing || settings.webkit_fake_resize === false) {
1638
1640
  return;
1639
1641
  }
1640
1642
 
1641
- editor.contentStyles.push('.mceResizeImages img {cursor: se-resize !important}');
1643
+ // Try disabling object resizing if WebKit implements resizing in the future
1644
+ setEditorCommandState("enableObjectResizing", false);
1645
+
1646
+ // Details about each resize handle how to scale etc
1647
+ resizeHandles = {
1648
+ // Name: x multiplier, y multiplier, delta size x, delta size y
1649
+ n: [.5, 0, 0, -1],
1650
+ e: [1, .5, 1, 0],
1651
+ s: [.5, 1, 0, 1],
1652
+ w: [0, .5, -1, 0],
1653
+ nw: [0, 0, -1, -1],
1654
+ ne: [1, 0, 1, -1],
1655
+ se: [1, 1, 1, 1],
1656
+ sw : [0, 1, -1, 1]
1657
+ };
1642
1658
 
1643
- function resizeImage(e) {
1644
- var deltaX, deltaY, ratio, width, height;
1659
+ function resizeElement(e) {
1660
+ var deltaX, deltaY, ratio;
1645
1661
 
1646
- if (mouseDownImg) {
1647
- deltaX = e.screenX - startX;
1648
- deltaY = e.screenY - startY;
1649
- ratio = Math.max((startW + deltaX) / startW, (startH + deltaY) / startH);
1662
+ // Calc new width/height
1663
+ deltaX = e.screenX - startX;
1664
+ deltaY = e.screenY - startY;
1665
+ ratio = Math.max((startW + deltaX) / startW, (startH + deltaY) / startH);
1650
1666
 
1651
- // Only update styles if the user draged one pixel or more
1652
- if (Math.abs(deltaX) > 1 || Math.abs(deltaY) > 1) {
1653
- // Constrain proportions
1654
- width = Math.round(startW * ratio);
1655
- height = Math.round(startH * ratio);
1667
+ if (VK.modifierPressed(e)) {
1668
+ // Constrain proportions
1669
+ width = Math.round(startW * ratio);
1670
+ height = Math.round(startH * ratio);
1671
+ } else {
1672
+ // Calc new size
1673
+ width = deltaX * selectedHandle[2] + startW;
1674
+ height = deltaY * selectedHandle[3] + startH;
1675
+ }
1656
1676
 
1657
- // Resize by using style or attribute
1658
- if (mouseDownImg.style.width) {
1659
- dom.setStyle(mouseDownImg, 'width', width);
1660
- } else {
1661
- dom.setAttrib(mouseDownImg, 'width', width);
1662
- }
1677
+ // Never scale down lower than 5 pixels
1678
+ width = width < 5 ? 5 : width;
1679
+ height = height < 5 ? 5 : height;
1663
1680
 
1681
+ // Update ghost size
1682
+ dom.setStyles(selectedElmGhost, {
1683
+ width: width,
1684
+ height: height
1685
+ });
1686
+
1687
+ // Update ghost X position if needed
1688
+ if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
1689
+ dom.setStyle(selectedElmGhost, 'left', selectedElmX + deltaX);
1690
+ }
1691
+
1692
+ // Update ghost Y position if needed
1693
+ if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
1694
+ dom.setStyle(selectedElmGhost, 'top', selectedElmY + deltaY);
1695
+ }
1696
+ }
1697
+
1698
+ function endResize() {
1699
+ function setSizeProp(name, value) {
1700
+ if (value) {
1664
1701
  // Resize by using style or attribute
1665
- if (mouseDownImg.style.height) {
1666
- dom.setStyle(mouseDownImg, 'height', height);
1702
+ if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) {
1703
+ dom.setStyle(selectedElm, name, value);
1667
1704
  } else {
1668
- dom.setAttrib(mouseDownImg, 'height', height);
1705
+ dom.setAttrib(selectedElm, name, value);
1669
1706
  }
1707
+ }
1708
+ }
1670
1709
 
1671
- if (!dom.hasClass(editor.getBody(), 'mceResizeImages')) {
1672
- dom.addClass(editor.getBody(), 'mceResizeImages');
1673
- }
1710
+ // Set width/height properties
1711
+ setSizeProp('width', width);
1712
+ setSizeProp('height', height);
1713
+
1714
+ dom.unbind(editableDoc, 'mousemove', resizeElement);
1715
+ dom.unbind(editableDoc, 'mouseup', endResize);
1716
+
1717
+ if (rootDocument != editableDoc) {
1718
+ dom.unbind(rootDocument, 'mousemove', resizeElement);
1719
+ dom.unbind(rootDocument, 'mouseup', endResize);
1720
+ }
1721
+
1722
+ // Remove ghost and update resize handle positions
1723
+ dom.remove(selectedElmGhost);
1724
+ showResizeRect(selectedElm);
1725
+ }
1726
+
1727
+ function showResizeRect(targetElm) {
1728
+ var position, targetWidth, targetHeight;
1729
+
1730
+ hideResizeRect();
1731
+
1732
+ // Get position and size of target
1733
+ position = dom.getPos(targetElm);
1734
+ selectedElmX = position.x;
1735
+ selectedElmY = position.y;
1736
+ targetWidth = targetElm.offsetWidth;
1737
+ targetHeight = targetElm.offsetHeight;
1738
+
1739
+ // Reset width/height if user selects a new image/table
1740
+ if (selectedElm != targetElm) {
1741
+ selectedElm = targetElm;
1742
+ width = height = 0;
1743
+ }
1744
+
1745
+ tinymce.each(resizeHandles, function(handle, name) {
1746
+ var handleElm;
1747
+
1748
+ // Get existing or render resize handle
1749
+ handleElm = dom.get('mceResizeHandle' + name);
1750
+ if (!handleElm) {
1751
+ handleElm = dom.add(editableDoc.documentElement, 'div', {
1752
+ id: 'mceResizeHandle' + name,
1753
+ 'class': 'mceResizeHandle',
1754
+ style: 'cursor:' + name + '-resize; margin:0; padding:0'
1755
+ });
1756
+
1757
+ dom.bind(handleElm, 'mousedown', function(e) {
1758
+ e.preventDefault();
1759
+
1760
+ endResize();
1761
+
1762
+ startX = e.screenX;
1763
+ startY = e.screenY;
1764
+ startW = selectedElm.clientWidth;
1765
+ startH = selectedElm.clientHeight;
1766
+ selectedHandle = handle;
1767
+
1768
+ selectedElmGhost = selectedElm.cloneNode(true);
1769
+ dom.addClass(selectedElmGhost, 'mceClonedResizable');
1770
+ dom.setStyles(selectedElmGhost, {
1771
+ left: selectedElmX,
1772
+ top: selectedElmY,
1773
+ margin: 0
1774
+ });
1775
+
1776
+ editableDoc.documentElement.appendChild(selectedElmGhost);
1777
+
1778
+ dom.bind(editableDoc, 'mousemove', resizeElement);
1779
+ dom.bind(editableDoc, 'mouseup', endResize);
1780
+
1781
+ if (rootDocument != editableDoc) {
1782
+ dom.bind(rootDocument, 'mousemove', resizeElement);
1783
+ dom.bind(rootDocument, 'mouseup', endResize);
1784
+ }
1785
+ });
1786
+ } else {
1787
+ dom.show(handleElm);
1674
1788
  }
1789
+
1790
+ // Position element
1791
+ dom.setStyles(handleElm, {
1792
+ left: (targetWidth * handle[0] + selectedElmX) - (handleElm.offsetWidth / 2),
1793
+ top: (targetHeight * handle[1] + selectedElmY) - (handleElm.offsetHeight / 2)
1794
+ });
1795
+ });
1796
+
1797
+ // Only add resize rectangle on WebKit and only on images
1798
+ if (!tinymce.isOpera && selectedElm.nodeName == "IMG") {
1799
+ selectedElm.setAttribute('data-mce-selected', '1');
1675
1800
  }
1676
- };
1801
+ }
1677
1802
 
1678
- editor.onMouseDown.add(function(editor, e) {
1679
- var target = e.target;
1680
-
1681
- if (target.nodeName == "IMG") {
1682
- mouseDownImg = target;
1683
- startX = e.screenX;
1684
- startY = e.screenY;
1685
- startW = mouseDownImg.clientWidth;
1686
- startH = mouseDownImg.clientHeight;
1687
- dom.bind(editor.getDoc(), 'mousemove', resizeImage);
1688
- e.preventDefault();
1803
+ function hideResizeRect() {
1804
+ if (selectedElm) {
1805
+ selectedElm.removeAttribute('data-mce-selected');
1689
1806
  }
1690
- });
1691
1807
 
1692
- // Unbind events on node change and restore resize cursor
1693
- editor.onNodeChange.add(function() {
1694
- if (mouseDownImg) {
1695
- mouseDownImg = null;
1696
- dom.unbind(editor.getDoc(), 'mousemove', resizeImage);
1808
+ for (var name in resizeHandles) {
1809
+ dom.hide('mceResizeHandle' + name);
1697
1810
  }
1811
+ }
1698
1812
 
1699
- if (selection.getNode().nodeName == "IMG") {
1700
- dom.addClass(editor.getBody(), 'mceResizeImages');
1813
+ // Add CSS for resize handles, cloned element and selected
1814
+ editor.contentStyles.push(
1815
+ '.mceResizeHandle {' +
1816
+ 'position: absolute;' +
1817
+ 'border: 1px solid black;' +
1818
+ 'background: #FFF;' +
1819
+ 'width: 5px;' +
1820
+ 'height: 5px;' +
1821
+ 'z-index: 10000' +
1822
+ '}' +
1823
+ '.mceResizeHandle:hover {' +
1824
+ 'background: #000' +
1825
+ '}' +
1826
+ 'img[data-mce-selected] {' +
1827
+ 'outline: 1px solid black' +
1828
+ '}' +
1829
+ 'img.mceClonedResizable, table.mceClonedResizable {' +
1830
+ 'position: absolute;' +
1831
+ 'outline: 1px dashed black;' +
1832
+ 'opacity: .5;' +
1833
+ 'z-index: 10000' +
1834
+ '}'
1835
+ );
1836
+
1837
+ function updateResizeRect() {
1838
+ var controlElm = dom.getParent(selection.getNode(), 'table,img');
1839
+
1840
+ // Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v
1841
+ tinymce.each(dom.select('img[data-mce-selected]'), function(img) {
1842
+ img.removeAttribute('data-mce-selected');
1843
+ });
1844
+
1845
+ if (controlElm) {
1846
+ showResizeRect(controlElm);
1701
1847
  } else {
1702
- dom.removeClass(editor.getBody(), 'mceResizeImages');
1848
+ hideResizeRect();
1849
+ }
1850
+ }
1851
+
1852
+ // Show/hide resize rect when image is selected
1853
+ editor.onNodeChange.add(updateResizeRect);
1854
+
1855
+ // Fixes WebKit quirk where it returns IMG on getNode if caret is after last image in container
1856
+ dom.bind(editableDoc, 'selectionchange', updateResizeRect);
1857
+
1858
+ // Remove the internal attribute when serializing the DOM
1859
+ editor.serializer.addAttributeFilter('data-mce-selected', function(nodes, name) {
1860
+ var i = nodes.length;
1861
+
1862
+ while (i--) {
1863
+ nodes[i].attr(name, null);
1703
1864
  }
1704
1865
  });
1705
- };
1866
+ }
1706
1867
 
1707
1868
  // All browsers
1708
1869
  disableBackspaceIntoATable();
@@ -1745,6 +1906,11 @@ tinymce.util.Quirks = function(editor) {
1745
1906
  addBrAfterLastLinks();
1746
1907
  removeGhostSelection();
1747
1908
  }
1909
+
1910
+ // Opera
1911
+ if (tinymce.isOpera) {
1912
+ fakeImageResize();
1913
+ }
1748
1914
  };
1749
1915
  (function(tinymce) {
1750
1916
  var namedEntities, baseEntities, reverseEntities,
@@ -7349,7 +7515,8 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
7349
7515
  };
7350
7516
 
7351
7517
  this.addRange = function(rng) {
7352
- var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, sibling, doc = selection.dom.doc, body = doc.body;
7518
+ var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, sibling,
7519
+ doc = selection.dom.doc, body = doc.body, nativeRng, ctrlElm;
7353
7520
 
7354
7521
  function setEndPoint(start) {
7355
7522
  var container, offset, marker, tmpRng, nodes;
@@ -7435,10 +7602,17 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
7435
7602
 
7436
7603
  if (startOffset == endOffset - 1) {
7437
7604
  try {
7605
+ ctrlElm = startContainer.childNodes[startOffset];
7438
7606
  ctrlRng = body.createControlRange();
7439
- ctrlRng.addElement(startContainer.childNodes[startOffset]);
7607
+ ctrlRng.addElement(ctrlElm);
7440
7608
  ctrlRng.select();
7441
- return;
7609
+
7610
+ // Check if the range produced is on the correct element and is a control range
7611
+ // On IE 8 it will select the parent contentEditable container if you select an inner element see: #5398
7612
+ nativeRng = selection.getRng();
7613
+ if (nativeRng.item && ctrlElm === nativeRng.item(0)) {
7614
+ return;
7615
+ }
7442
7616
  } catch (ex) {
7443
7617
  // Ignore
7444
7618
  }
@@ -10379,7 +10553,7 @@ window.tinymce.dom.Sizzle = Sizzle;
10379
10553
 
10380
10554
  // Replace all BOM characters for now until we can find a better solution
10381
10555
  if (!args.cleanup)
10382
- args.content = args.content.replace(/\uFEFF|\u200B/g, '');
10556
+ args.content = args.content.replace(/\uFEFF/g, '');
10383
10557
 
10384
10558
  // Post process
10385
10559
  if (!args.no_events)
@@ -13361,6 +13535,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
13361
13535
  });
13362
13536
  }
13363
13537
 
13538
+ // Load specified content CSS last
13539
+ if (s.content_style) {
13540
+ t.contentStyles.push(s.content_style);
13541
+ }
13542
+
13364
13543
  // Content editable mode ends here
13365
13544
  if (s.content_editable) {
13366
13545
  e = n = o = null; // Fix IE leak
@@ -14969,7 +15148,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
14969
15148
 
14970
15149
  // Insert bookmark node and get the parent
14971
15150
  selection.setContent(bookmarkHtml);
14972
- parentNode = editor.selection.getNode();
15151
+ parentNode = selection.getNode();
14973
15152
  rootNode = editor.getBody();
14974
15153
 
14975
15154
  // Opera will return the document node when selection is in root
@@ -15136,10 +15315,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
15136
15315
  selectAll : function() {
15137
15316
  var root = dom.getRoot(), rng = dom.createRng();
15138
15317
 
15139
- rng.setStart(root, 0);
15140
- rng.setEnd(root, root.childNodes.length);
15318
+ // Old IE does a better job with selectall than new versions
15319
+ if (selection.getRng().setStart) {
15320
+ rng.setStart(root, 0);
15321
+ rng.setEnd(root, root.childNodes.length);
15141
15322
 
15142
- editor.selection.setRng(rng);
15323
+ selection.setRng(rng);
15324
+ } else {
15325
+ execNativeCommand('SelectAll');
15326
+ }
15143
15327
  }
15144
15328
  });
15145
15329
 
@@ -15178,7 +15362,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
15178
15362
  },
15179
15363
 
15180
15364
  'InsertUnorderedList,InsertOrderedList' : function(command) {
15181
- return dom.getParent(selection.getNode(), command == 'insertunorderedlist' ? 'UL' : 'OL');
15365
+ var list = dom.getParent(selection.getNode(), 'ul,ol');
15366
+ return list &&
15367
+ (command === 'insertunorderedlist' && list.tagName === 'UL'
15368
+ || command === 'insertorderedlist' && list.tagName === 'OL');
15182
15369
  }
15183
15370
  }, 'state');
15184
15371
 
@@ -16049,7 +16236,7 @@ tinymce.ForceBlocks = function(editor) {
16049
16236
  isBlock = dom.isBlock,
16050
16237
  forcedRootBlock = ed.settings.forced_root_block,
16051
16238
  nodeIndex = dom.nodeIndex,
16052
- INVISIBLE_CHAR = tinymce.isGecko ? '\u200B' : '\uFEFF',
16239
+ INVISIBLE_CHAR = '\uFEFF',
16053
16240
  MCE_ATTR_RE = /^(src|href|style)$/,
16054
16241
  FALSE = false,
16055
16242
  TRUE = true,
@@ -16964,7 +17151,7 @@ tinymce.ForceBlocks = function(editor) {
16964
17151
  return FALSE;
16965
17152
  };
16966
17153
 
16967
- function formatChanged(formats, callback) {
17154
+ function formatChanged(formats, callback, similar) {
16968
17155
  var currentFormats;
16969
17156
 
16970
17157
  // Setup format node change logic
@@ -16978,7 +17165,7 @@ tinymce.ForceBlocks = function(editor) {
16978
17165
  // Check for new formats
16979
17166
  each(formatChangeData, function(callbacks, format) {
16980
17167
  each(parents, function(node) {
16981
- if (matchNode(node, format, {}, true)) {
17168
+ if (matchNode(node, format, {}, callbacks.similar)) {
16982
17169
  if (!currentFormats[format]) {
16983
17170
  // Execute callbacks
16984
17171
  each(callbacks, function(callback) {
@@ -17011,6 +17198,7 @@ tinymce.ForceBlocks = function(editor) {
17011
17198
  each(formats.split(','), function(format) {
17012
17199
  if (!formatChangeData[format]) {
17013
17200
  formatChangeData[format] = [];
17201
+ formatChangeData[format].similar = similar;
17014
17202
  }
17015
17203
 
17016
17204
  formatChangeData[format].push(callback);
@@ -18106,7 +18294,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18106
18294
  var dom = editor.dom, selection = editor.selection, settings = editor.settings, undoManager = editor.undoManager, nonEmptyElementsMap = editor.schema.getNonEmptyElements();
18107
18295
 
18108
18296
  function handleEnterKey(evt) {
18109
- var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode,
18297
+ var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey,
18110
18298
  newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
18111
18299
 
18112
18300
  // Returns true if the block can be split into two blocks or not
@@ -18151,6 +18339,11 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18151
18339
  node = firstChilds[i];
18152
18340
  if (!node.hasChildNodes() || (node.firstChild == node.lastChild && node.firstChild.nodeValue === '')) {
18153
18341
  dom.remove(node);
18342
+ } else {
18343
+ // Remove <a> </a> see #5381
18344
+ if (node.nodeName == "A" && (node.innerText || node.textContent) === ' ') {
18345
+ dom.remove(node);
18346
+ }
18154
18347
  }
18155
18348
  }
18156
18349
  };
@@ -18517,6 +18710,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18517
18710
  newBlockName = settings.forced_root_block;
18518
18711
  newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
18519
18712
  documentMode = dom.doc.documentMode;
18713
+ shiftKey = evt.shiftKey;
18520
18714
 
18521
18715
  // Resolve node index
18522
18716
  if (container.nodeType == 1 && container.hasChildNodes()) {
@@ -18541,7 +18735,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18541
18735
 
18542
18736
  // If editable root isn't block nor the root of the editor
18543
18737
  if (!dom.isBlock(editableRoot) && editableRoot != dom.getRoot()) {
18544
- if (!newBlockName || evt.shiftKey) {
18738
+ if (!newBlockName || shiftKey) {
18545
18739
  insertBr();
18546
18740
  }
18547
18741
 
@@ -18551,7 +18745,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18551
18745
  // Wrap the current node and it's sibling in a default block if it's needed.
18552
18746
  // for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td>
18553
18747
  // This won't happen if root blocks are disabled or the shiftKey is pressed
18554
- if ((newBlockName && !evt.shiftKey) || (!newBlockName && evt.shiftKey)) {
18748
+ if ((newBlockName && !shiftKey) || (!newBlockName && shiftKey)) {
18555
18749
  container = wrapSelfAndSiblingsInDefaultBlock(container, offset);
18556
18750
  }
18557
18751
 
@@ -18563,26 +18757,34 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
18563
18757
  parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
18564
18758
  containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
18565
18759
 
18566
- // Handle enter inside an empty list item
18567
- if (parentBlockName == 'LI' && dom.isEmpty(parentBlock)) {
18568
- // Let the list plugin or browser handle nested lists for now
18569
- if (/^(UL|OL|LI)$/.test(containerBlock.parentNode.nodeName)) {
18570
- return false;
18760
+ // Handle enter in LI
18761
+ if (parentBlockName == 'LI') {
18762
+ if (!newBlockName && shiftKey) {
18763
+ insertBr();
18764
+ return;
18571
18765
  }
18572
18766
 
18573
- handleEmptyListItem();
18574
- return;
18767
+ // Handle enter inside an empty list item
18768
+ if (dom.isEmpty(parentBlock)) {
18769
+ // Let the list plugin or browser handle nested lists for now
18770
+ if (/^(UL|OL|LI)$/.test(containerBlock.parentNode.nodeName)) {
18771
+ return false;
18772
+ }
18773
+
18774
+ handleEmptyListItem();
18775
+ return;
18776
+ }
18575
18777
  }
18576
18778
 
18577
18779
  // Don't split PRE tags but insert a BR instead easier when writing code samples etc
18578
18780
  if (parentBlockName == 'PRE' && settings.br_in_pre !== false) {
18579
- if (!evt.shiftKey) {
18781
+ if (!shiftKey) {
18580
18782
  insertBr();
18581
18783
  return;
18582
18784
  }
18583
18785
  } else {
18584
18786
  // If no root block is configured then insert a BR by default or if the shiftKey is pressed
18585
- if ((!newBlockName && !evt.shiftKey && parentBlockName != 'LI') || (newBlockName && evt.shiftKey)) {
18787
+ if ((!newBlockName && !shiftKey && parentBlockName != 'LI') || (newBlockName && shiftKey)) {
18586
18788
  insertBr();
18587
18789
  return;
18588
18790
  }