tinymce-rails 3.4.3.2 → 3.4.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -91,11 +91,11 @@
91
91
  t.block = 1;
92
92
 
93
93
  setTimeout(function() {
94
+ if (!ed.destroyed) {
94
95
  var tc = t._getCount(ed);
95
-
96
96
  tinymce.DOM.setHTML(t.id, tc.toString());
97
-
98
97
  setTimeout(function() {t.block = 0;}, 2000);
98
+ }
99
99
  }, 1);
100
100
  },
101
101
 
@@ -870,7 +870,7 @@
870
870
 
871
871
 
872
872
  if (s.theme_advanced_resizing) {
873
- DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize'});
873
+ DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"});
874
874
 
875
875
  if (s.theme_advanced_resizing_use_cookie) {
876
876
  ed.onPostRender.add(function() {
@@ -43,5 +43,6 @@ font[face=mceinline] {font-family:inherit !important}
43
43
  .mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)}
44
44
  .mceItemRealMedia {background-image:url(../../img/realmedia.gif)}
45
45
  .mceItemVideo {background-image:url(../../img/video.gif)}
46
+ .mceItemAudio {background-image:url(../../img/video.gif)}
46
47
  .mceItemIframe {background-image:url(../../img/iframe.gif)}
47
48
  .mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;}
@@ -42,5 +42,6 @@ font[face=mceinline] {font-family:inherit !important}
42
42
  .mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)}
43
43
  .mceItemRealMedia {background-image:url(../../img/realmedia.gif)}
44
44
  .mceItemVideo {background-image:url(../../img/video.gif)}
45
+ .mceItemAudio {background-image:url(../../img/video.gif)}
45
46
  .mceItemIframe {background-image:url(../../img/iframe.gif)}
46
47
  .mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;}
@@ -5,9 +5,9 @@
5
5
  var tinymce = {
6
6
  majorVersion : '3',
7
7
 
8
- minorVersion : '4.3.2',
8
+ minorVersion : '4.4',
9
9
 
10
- releaseDate : '2011-06-30',
10
+ releaseDate : '2011-08-04',
11
11
 
12
12
  _init : function() {
13
13
  var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
@@ -20,6 +20,12 @@
20
20
 
21
21
  t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
22
22
 
23
+ t.isIE7 = t.isIE && /MSIE [7]/.test(ua);
24
+
25
+ t.isIE8 = t.isIE && /MSIE [8]/.test(ua);
26
+
27
+ t.isIE9 = t.isIE && /MSIE [9]/.test(ua);
28
+
23
29
  t.isGecko = !t.isWebKit && /Gecko/.test(ua);
24
30
 
25
31
  t.isMac = ua.indexOf('Mac') != -1;
@@ -1304,6 +1310,41 @@ tinymce.create('static tinymce.util.XHR', {
1304
1310
  }
1305
1311
  });
1306
1312
  }());
1313
+ (function(tinymce){
1314
+ tinymce.VK = {
1315
+ DELETE:46,
1316
+ BACKSPACE:8
1317
+
1318
+ }
1319
+
1320
+ })(tinymce);
1321
+
1322
+ (function(tinymce) {
1323
+ function cleanupStylesWhenDeleting(ed) {
1324
+ var dom = ed.dom, selection = ed.selection, VK= tinymce.VK;
1325
+ ed.onKeyUp.add(function(ed, e) {
1326
+ if (e.keyCode == VK.DELETE ||e.keyCode == VK.BACKSPACE) {
1327
+ var startContainer = selection.getRng().startContainer;
1328
+ var blockElement = startContainer;
1329
+ while (!dom.isBlock(blockElement)) {
1330
+ blockElement = blockElement.parentNode;
1331
+ }
1332
+ var spans = dom.select("span.Apple-style-span", blockElement);
1333
+ dom.remove(spans, true);
1334
+ }
1335
+ });
1336
+ }
1337
+
1338
+ tinymce.create('tinymce.util.Quirks', {
1339
+ Quirks: function(ed) {
1340
+ if (tinymce.isWebKit) {
1341
+ cleanupStylesWhenDeleting(ed);
1342
+ }
1343
+
1344
+ }
1345
+ });
1346
+ })(tinymce);
1347
+
1307
1348
  (function(tinymce) {
1308
1349
  var namedEntities, baseEntities, reverseEntities,
1309
1350
  attrsCharsRegExp = /[&<>\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
@@ -1876,10 +1917,10 @@ tinymce.html.Styles = function(settings, schema) {
1876
1917
  'body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]'
1877
1918
  );
1878
1919
 
1879
- boolAttrMap = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,preload,autoplay,loop,controls');
1920
+ boolAttrMap = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,autoplay,loop,controls');
1880
1921
  shortEndedElementsMap = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source');
1881
- nonEmptyElementsMap = tinymce.extend(makeMap('td,th,iframe,video,object'), shortEndedElementsMap);
1882
- whiteSpaceElementsMap = makeMap('pre,script,style');
1922
+ nonEmptyElementsMap = tinymce.extend(makeMap('td,th,iframe,video,audio,object'), shortEndedElementsMap);
1923
+ whiteSpaceElementsMap = makeMap('pre,script,style,textarea');
1883
1924
  selfClosingElementsMap = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
1884
1925
 
1885
1926
  tinymce.html.Schema = function(settings) {
@@ -2113,7 +2154,24 @@ tinymce.html.Styles = function(settings, schema) {
2113
2154
  }
2114
2155
  });
2115
2156
  }
2116
- }
2157
+ };
2158
+
2159
+ function getElementRule(name) {
2160
+ var element = elements[name], i;
2161
+
2162
+ // Exact match found
2163
+ if (element)
2164
+ return element;
2165
+
2166
+ // No exact match then try the patterns
2167
+ i = patternElements.length;
2168
+ while (i--) {
2169
+ element = patternElements[i];
2170
+
2171
+ if (element.pattern.test(name))
2172
+ return element;
2173
+ }
2174
+ };
2117
2175
 
2118
2176
  if (!settings.valid_elements) {
2119
2177
  // No valid elements defined then clone the elements from the transitional spec
@@ -2154,6 +2212,10 @@ tinymce.html.Styles = function(settings, schema) {
2154
2212
  // Todo: Remove this when we fix list handling to be valid
2155
2213
  addValidChildren('+ol[ul|ol],+ul[ul|ol]');
2156
2214
 
2215
+ // If the user didn't allow span only allow internal spans
2216
+ if (!getElementRule('span'))
2217
+ addValidElements('span[!data-mce-type|*]');
2218
+
2157
2219
  // Delete invalid elements
2158
2220
  if (settings.invalid_elements) {
2159
2221
  tinymce.each(tinymce.explode(settings.invalid_elements), function(item) {
@@ -2196,22 +2258,7 @@ tinymce.html.Styles = function(settings, schema) {
2196
2258
  return !!(parent && parent[child]);
2197
2259
  };
2198
2260
 
2199
- self.getElementRule = function(name) {
2200
- var element = elements[name], i;
2201
-
2202
- // Exact match found
2203
- if (element)
2204
- return element;
2205
-
2206
- // No exact match then try the patterns
2207
- i = patternElements.length;
2208
- while (i--) {
2209
- element = patternElements[i];
2210
-
2211
- if (element.pattern.test(name))
2212
- return element;
2213
- }
2214
- };
2261
+ self.getElementRule = getElementRule;
2215
2262
 
2216
2263
  self.getCustomElements = function() {
2217
2264
  return customElementsMap;
@@ -2248,7 +2295,7 @@ tinymce.html.Styles = function(settings, schema) {
2248
2295
  });
2249
2296
 
2250
2297
  self.parse = function(html) {
2251
- var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name,
2298
+ var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name, isInternalElement, removeInternalElements,
2252
2299
  shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue,
2253
2300
  validAttributesMap, validAttributePatterns, attributesRequired, attributesDefault, attributesForced, selfClosing,
2254
2301
  tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing;
@@ -2300,6 +2347,7 @@ tinymce.html.Styles = function(settings, schema) {
2300
2347
  selfClosing = schema.getSelfClosingElements();
2301
2348
  fillAttrsMap = schema.getBoolAttrs();
2302
2349
  validate = settings.validate;
2350
+ removeInternalElements = settings.remove_internals;
2303
2351
  fixSelfClosing = settings.fix_self_closing;
2304
2352
 
2305
2353
  while (matches = tokenRegExp.exec(html)) {
@@ -2329,6 +2377,12 @@ tinymce.html.Styles = function(settings, schema) {
2329
2377
 
2330
2378
  // Parse attributes
2331
2379
  if (attribsValue = matches[8]) {
2380
+ isInternalElement = attribsValue.indexOf('data-mce-type') !== -1; // Check if the element is an internal element
2381
+
2382
+ // If the element has internal attributes then remove it if we are told to do so
2383
+ if (isInternalElement && removeInternalElements)
2384
+ isValidElement = false;
2385
+
2332
2386
  attrList = [];
2333
2387
  attrList.map = {};
2334
2388
 
@@ -2339,7 +2393,7 @@ tinymce.html.Styles = function(settings, schema) {
2339
2393
  value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
2340
2394
 
2341
2395
  // Validate name and value
2342
- if (validate && name.indexOf('data-') !== 0) {
2396
+ if (validate && !isInternalElement && name.indexOf('data-') !== 0) {
2343
2397
  attrRule = validAttributesMap[name];
2344
2398
 
2345
2399
  // Find rule by pattern matching
@@ -2378,7 +2432,7 @@ tinymce.html.Styles = function(settings, schema) {
2378
2432
  }
2379
2433
 
2380
2434
  // Process attributes if validation is enabled
2381
- if (validate) {
2435
+ if (validate && !isInternalElement) {
2382
2436
  attributesRequired = elementRule.attributesRequired;
2383
2437
  attributesDefault = elementRule.attributesDefault;
2384
2438
  attributesForced = elementRule.attributesForced;
@@ -6364,6 +6418,13 @@ tinymce.html.Writer = function(settings) {
6364
6418
  tinymce.addUnload(t.destroy, t);
6365
6419
  },
6366
6420
 
6421
+ setCursorLocation: function(node, offset) {
6422
+ var t = this; var r = t.dom.createRng();
6423
+ r.setStart(node, offset);
6424
+ r.setEnd(node, offset);
6425
+ t.setRng(r);
6426
+ t.collapse(false);
6427
+ },
6367
6428
  getContent : function(s) {
6368
6429
  var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;
6369
6430
 
@@ -10503,7 +10564,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
10503
10564
  if ((!isIE || !tinymce.relaxedDomain) && !filled) {
10504
10565
  // We need to wait for the load event on Gecko
10505
10566
  if (isGecko && !s.readonly) {
10506
- t.getWin().onload = function() {
10567
+ t.getWin().addEventListener("DOMContentLoaded", function() {
10507
10568
  window.setTimeout(function() {
10508
10569
  var b = t.getBody(), undef;
10509
10570
 
@@ -10539,7 +10600,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
10539
10600
  // since the caret won't be rendered some times otherwise.
10540
10601
  t.setupIframe(true);
10541
10602
  }, 1);
10542
- };
10603
+ }, false);
10543
10604
  }
10544
10605
 
10545
10606
  d.open();
@@ -10765,6 +10826,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
10765
10826
  t.controlManager.onPostRender.dispatch(t, t.controlManager);
10766
10827
  t.onPostRender.dispatch(t);
10767
10828
 
10829
+ t.quirks = new tinymce.util.Quirks(this);
10830
+
10768
10831
  if (s.directionality)
10769
10832
  t.getBody().dir = s.directionality;
10770
10833
 
@@ -11751,6 +11814,35 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
11751
11814
  t.nodeChanged();
11752
11815
  });
11753
11816
 
11817
+
11818
+ // Add block quote deletion handler
11819
+ t.onKeyDown.add(function(ed, e) {
11820
+ // Was the BACKSPACE key pressed?
11821
+ if (e.keyCode != 8)
11822
+ return;
11823
+
11824
+ var n = ed.selection.getRng().startContainer;
11825
+ var offset = ed.selection.getRng().startOffset;
11826
+
11827
+ while (n && n.nodeType && n.nodeType != 1 && n.parentNode)
11828
+ n = n.parentNode;
11829
+
11830
+ // Is the cursor at the beginning of a blockquote?
11831
+ if (n && n.parentNode && n.parentNode.tagName === 'BLOCKQUOTE' && n.parentNode.firstChild == n && offset == 0) {
11832
+ // Remove the blockquote
11833
+ ed.formatter.toggle('blockquote', null, n.parentNode);
11834
+
11835
+ // Move the caret to the beginning of n
11836
+ var rng = ed.selection.getRng();
11837
+ rng.setStart(n, 0);
11838
+ rng.setEnd(n, 0);
11839
+ ed.selection.setRng(rng);
11840
+ ed.selection.collapse(false);
11841
+ }
11842
+ });
11843
+
11844
+
11845
+
11754
11846
  // Add reset handler
11755
11847
  t.onReset.add(function() {
11756
11848
  t.setContent(t.startContent, {format : 'raw'});
@@ -11772,9 +11864,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
11772
11864
  for (i=1; i<=6; i++)
11773
11865
  t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]);
11774
11866
 
11775
- t.addShortcut('ctrl+7', '', ['FormatBlock', false, '<p>']);
11776
- t.addShortcut('ctrl+8', '', ['FormatBlock', false, '<div>']);
11777
- t.addShortcut('ctrl+9', '', ['FormatBlock', false, '<address>']);
11867
+ t.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']);
11868
+ t.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']);
11869
+ t.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']);
11778
11870
 
11779
11871
  function find(e) {
11780
11872
  var v = null;
@@ -11967,10 +12059,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
11967
12059
 
11968
12060
  return function() {
11969
12061
  var target = t.selection.getStart();
11970
- t.dom.removeAllAttribs(target);
11971
- each(template, function(attr) {
11972
- target.setAttributeNode(attr.cloneNode(true));
11973
- });
12062
+
12063
+ if (target !== t.getBody()) {
12064
+ t.dom.removeAllAttribs(target);
12065
+
12066
+ each(template, function(attr) {
12067
+ target.setAttributeNode(attr.cloneNode(true));
12068
+ });
12069
+ }
11974
12070
  };
11975
12071
  }
11976
12072
 
@@ -12342,7 +12438,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
12342
12438
  value = serializer.serialize(
12343
12439
  parser.parse(
12344
12440
  // Need to replace by using a function since $ in the contents would otherwise be a problem
12345
- value.replace(/<span (id="mce_marker"|id=mce_marker).+<\/span>/i, function() {
12441
+ value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function() {
12346
12442
  return serializer.serialize(fragment);
12347
12443
  })
12348
12444
  )
@@ -13943,8 +14039,74 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
13943
14039
  });
13944
14040
  }
13945
14041
  };
14042
+ function adjustSelectionToVisibleSelection() {
14043
+
14044
+ function findSelectionEnd(start, end) {
14045
+ var walker = new TreeWalker(end);
14046
+ for (node = walker.current(); node; node = walker.prev()) {
14047
+ if (node.childNodes.length > 1 || node == start) {
14048
+ return node;
14049
+ }
14050
+ }
14051
+ }
13946
14052
 
13947
- function applyRngStyle(rng) {
14053
+ // Adjust selection so that a end container with a end offset of zero is not included in the selection
14054
+ // as this isn't visible to the user.
14055
+ var rng = ed.selection.getRng();
14056
+ var start = rng.startContainer;
14057
+ var end = rng.endContainer;
14058
+ if (start != end && rng.endOffset == 0) {
14059
+ var newEnd = findSelectionEnd(start, end);
14060
+ var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
14061
+ rng.setEnd(newEnd, endOffset);
14062
+ }
14063
+ return rng;
14064
+ }
14065
+
14066
+ function applyStyleToList(node, bookmark, wrapElm, newWrappers, process){
14067
+ var nodes =[], listIndex =-1, list, startIndex = -1, endIndex = -1, currentWrapElm;
14068
+
14069
+ // find the index of the first child list.
14070
+ each(node.childNodes, function(n, index) {
14071
+ if (n.nodeName==="UL"||n.nodeName==="OL") {listIndex = index; list=n; return false; }
14072
+ });
14073
+
14074
+ // get the index of the bookmarks
14075
+ each(node.childNodes, function(n, index) {
14076
+ if (n.nodeName==="SPAN" &&dom.getAttrib(n, "data-mce-type")=="bookmark" && n.id==bookmark.id+"_start") {startIndex=index}
14077
+ if (n.nodeName==="SPAN" &&dom.getAttrib(n, "data-mce-type")=="bookmark" && n.id==bookmark.id+"_end") {endIndex=index}
14078
+ });
14079
+
14080
+ // if the selection spans across an embedded list, or there isn't an embedded list - handle processing normally
14081
+ if (listIndex<=0 || (startIndex<listIndex&&endIndex>listIndex)) {
14082
+ each(tinymce.grep(node.childNodes), process);
14083
+ return 0;
14084
+ } else {
14085
+ currentWrapElm = wrapElm.cloneNode(FALSE);
14086
+
14087
+ // create a list of the nodes on the same side of the list as the selection
14088
+ each(tinymce.grep(node.childNodes), function(n, index) {
14089
+ if ((startIndex<listIndex && index <listIndex) || (startIndex>listIndex && index >listIndex)) {
14090
+ nodes.push(n);
14091
+ n.parentNode.removeChild(n);
14092
+ }
14093
+ });
14094
+
14095
+ // insert the wrapping element either before or after the list.
14096
+ if (startIndex<listIndex) {
14097
+ node.insertBefore(currentWrapElm, list);
14098
+ } else if (startIndex>listIndex) {
14099
+ node.insertBefore(currentWrapElm, list.nextSibling);
14100
+ }
14101
+
14102
+ // add the new nodes to the list.
14103
+ newWrappers.push(currentWrapElm);
14104
+ each(nodes, function(node){currentWrapElm.appendChild(node)});
14105
+ return currentWrapElm;
14106
+ }
14107
+ };
14108
+
14109
+ function applyRngStyle(rng, bookmark) {
13948
14110
  var newWrappers = [], wrapName, wrapElm;
13949
14111
 
13950
14112
  // Setup wrapper element
@@ -14018,19 +14180,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
14018
14180
  }
14019
14181
 
14020
14182
  currentWrapElm.appendChild(node);
14021
- } else if (nodeName == 'li') {
14022
- // Start wrapping
14023
- if (!currentWrapElm) {
14024
- // Wrap the node
14025
- liTextNode = node.ownerDocument.createTextNode('');
14026
- each(tinymce.grep(node.childNodes), function(n) { if (n.nodeType == 3) { liTextNode.nodeValue += n.nodeValue; n.parentNode.removeChild(n); } });
14027
- currentWrapElm = wrapElm.cloneNode(FALSE);
14028
- node.insertBefore(currentWrapElm, node.firstChild);
14029
- newWrappers.push(currentWrapElm);
14030
- }
14031
-
14032
- currentWrapElm.appendChild(liTextNode);
14033
-
14183
+ } else if (nodeName == 'li' && bookmark) {
14184
+ // Start wrapping - if we are in a list node and have a bookmark, then we will always begin by wrapping in a new element.
14185
+ currentWrapElm = applyStyleToList(node, bookmark, wrapElm, newWrappers, process);
14034
14186
  } else {
14035
14187
  // Start a new wrapper for possible children
14036
14188
  currentWrapElm = 0;
@@ -14185,8 +14337,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
14185
14337
  var curSelNode = ed.selection.getNode();
14186
14338
 
14187
14339
  // Apply formatting to selection
14340
+ ed.selection.setRng(adjustSelectionToVisibleSelection());
14188
14341
  bookmark = selection.getBookmark();
14189
- applyRngStyle(expandRng(selection.getRng(TRUE), formatList));
14342
+ applyRngStyle(expandRng(selection.getRng(TRUE), formatList), bookmark);
14190
14343
 
14191
14344
  // Colored nodes should be underlined so that the color of the underline matches the text color.
14192
14345
  if (format.styles && (format.styles.color || format.styles.textDecoration)) {
@@ -14205,7 +14358,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
14205
14358
 
14206
14359
  function remove(name, vars, node) {
14207
14360
  var formatList = get(name), format = formatList[0], bookmark, i, rng;
14208
-
14209
14361
  function moveStart(rng) {
14210
14362
  var container = rng.startContainer,
14211
14363
  offset = rng.startOffset,
@@ -15238,38 +15390,67 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
15238
15390
  // Only register listeners once if we need to
15239
15391
  if (!pendingFormats.isListening && hasPending()) {
15240
15392
  pendingFormats.isListening = true;
15393
+ function performPendingFormat(node, textNode) {
15394
+ var rng = dom.createRng();
15395
+ perform(node);
15396
+
15397
+ rng.setStart(textNode, textNode.nodeValue.length);
15398
+ rng.setEnd(textNode, textNode.nodeValue.length);
15399
+ selection.setRng(rng);
15400
+ ed.nodeChanged();
15401
+ }
15402
+ var enterKeyPressed = false;
15241
15403
 
15242
15404
  each('onKeyDown,onKeyUp,onKeyPress,onMouseUp'.split(','), function(event) {
15243
15405
  ed[event].addToTop(function(ed, e) {
15406
+ if (e.keyCode==13 && !e.shiftKey) {
15407
+ enterKeyPressed = true;
15408
+ return;
15409
+ }
15244
15410
  // Do we have pending formats and is the selection moved has moved
15245
15411
  if (hasPending() && !tinymce.dom.RangeUtils.compareRanges(pendingFormats.lastRng, selection.getRng())) {
15412
+ var foundCaret = false;
15246
15413
  each(dom.select('font,span'), function(node) {
15247
15414
  var textNode, rng;
15248
15415
 
15249
15416
  // Look for marker
15250
15417
  if (isCaretNode(node)) {
15418
+ foundCaret = true;
15251
15419
  textNode = node.firstChild;
15252
15420
 
15253
15421
  // Find the first text node within node
15254
15422
  while (textNode && textNode.nodeType != 3)
15255
15423
  textNode = textNode.firstChild;
15256
15424
 
15257
- if (textNode) {
15258
- perform(node);
15259
-
15260
- rng = dom.createRng();
15261
- rng.setStart(textNode, textNode.nodeValue.length);
15262
- rng.setEnd(textNode, textNode.nodeValue.length);
15263
- selection.setRng(rng);
15264
- ed.nodeChanged();
15265
- } else
15425
+ if (textNode)
15426
+ performPendingFormat(node, textNode);
15427
+ else
15266
15428
  dom.remove(node);
15267
15429
  }
15268
15430
  });
15431
+
15432
+ // no caret - so we are
15433
+ if (enterKeyPressed && !foundCaret) {
15434
+ var node = selection.getNode();
15435
+ var textNode = node;
15436
+
15437
+ // Find the first text node within node
15438
+ while (textNode && textNode.nodeType != 3)
15439
+ textNode = textNode.firstChild;
15440
+ if (textNode) {
15441
+ node=textNode.parentNode;
15442
+ while (!isBlock(node)){
15443
+ node=node.parentNode;
15444
+ }
15445
+ performPendingFormat(node, textNode);
15446
+ }
15447
+ }
15269
15448
 
15270
15449
  // Always unbind and clear pending styles on keyup
15271
- if (e.type == 'keyup' || e.type == 'mouseup')
15450
+ if (e.type == 'keyup' || e.type == 'mouseup') {
15272
15451
  resetPending();
15452
+ enterKeyPressed=false;
15453
+ }
15273
15454
  }
15274
15455
  });
15275
15456
  });