tinymce-rails 4.0.8 → 4.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/app/assets/source/tinymce/tinymce.jquery.js +217 -104
  2. data/app/assets/source/tinymce/tinymce.js +218 -93
  3. data/lib/tinymce/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/tinymce/jquery.tinymce.js +1 -1
  5. data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
  6. data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
  7. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
  8. data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
  9. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
  10. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
  11. data/vendor/assets/javascripts/tinymce/plugins/contextmenu/plugin.js +1 -1
  12. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
  13. data/vendor/assets/javascripts/tinymce/plugins/example/plugin.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/fullpage/plugin.js +1 -1
  15. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +1 -1
  16. data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
  19. data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
  20. data/vendor/assets/javascripts/tinymce/plugins/layer/plugin.js +1 -1
  21. data/vendor/assets/javascripts/tinymce/plugins/legacyoutput/plugin.js +1 -1
  22. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
  23. data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
  24. data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
  25. data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tinymce/plugins/noneditable/plugin.js +1 -1
  27. data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
  28. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
  29. data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
  30. data/vendor/assets/javascripts/tinymce/plugins/print/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
  32. data/vendor/assets/javascripts/tinymce/plugins/spellchecker/plugin.js +1 -1
  33. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.js +1 -1
  34. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
  35. data/vendor/assets/javascripts/tinymce/plugins/template/plugin.js +1 -1
  36. data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
  37. data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
  38. data/vendor/assets/javascripts/tinymce/skins/lightgray/content.min.css +1 -1
  39. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon-small.eot → tinymce-small.eot} +0 -0
  40. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon-small.svg → tinymce-small.svg} +4 -4
  41. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon-small.ttf → tinymce-small.ttf} +0 -0
  42. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
  43. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon.eot → tinymce.eot} +0 -0
  44. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon.svg → tinymce.svg} +3 -3
  45. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/{icomoon.ttf → tinymce.ttf} +0 -0
  46. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  47. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
  48. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
  49. data/vendor/assets/javascripts/tinymce/tinymce.jquery.js +9 -9
  50. data/vendor/assets/javascripts/tinymce/tinymce.js +10 -10
  51. metadata +11 -10
  52. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/icomoon-small.woff +0 -0
  53. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/icomoon.woff +0 -0
@@ -1,4 +1,4 @@
1
- // 4.0.8 (2013-10-10)
1
+ // 4.0.10 (2013-10-28)
2
2
 
3
3
  /**
4
4
  * Compiled inline version. (Library mode)
@@ -105,17 +105,7 @@ define("tinymce/dom/Sizzle", [], function() {
105
105
  throw new Error("Load jQuery first");
106
106
  }
107
107
 
108
- var $ = jQuery;
109
-
110
- function Sizzle(selector, context, results, seed) {
111
- return $.find(selector, context, results, seed);
112
- }
113
-
114
- Sizzle.matches = function(expr, elements) {
115
- return $(elements).is(expr) ? elements : [];
116
- };
117
-
118
- return Sizzle;
108
+ return jQuery.find;
119
109
  });
120
110
 
121
111
  // Included from: js/tinymce/classes/html/Styles.js
@@ -197,7 +187,8 @@ define("tinymce/html/Styles", [], function() {
197
187
  * @return {Object} Object representation of that style like {border: '1px solid red'}
198
188
  */
199
189
  parse: function(css) {
200
- var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this;
190
+ var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter;
191
+ var urlConverterScope = settings.url_converter_scope || this;
201
192
 
202
193
  function compress(prefix, suffix) {
203
194
  var top, right, bottom, left;
@@ -318,6 +309,10 @@ define("tinymce/html/Styles", [], function() {
318
309
 
319
310
  url = decode(url || url2 || url3);
320
311
 
312
+ if (!settings.allow_script_urls && /(java|vb)script:/i.test(url.replace(/[\s\r\n]+/, ''))) {
313
+ return "";
314
+ }
315
+
321
316
  // Convert the URL to relative/absolute depending on config
322
317
  if (urlConverter) {
323
318
  url = urlConverter.call(urlConverterScope, url, 'style');
@@ -328,6 +323,8 @@ define("tinymce/html/Styles", [], function() {
328
323
  }
329
324
 
330
325
  if (css) {
326
+ css = css.replace(/[\u0000-\u001F]/g, '');
327
+
331
328
  // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
332
329
  css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) {
333
330
  return str.replace(/[;:]/g, encode);
@@ -339,6 +336,10 @@ define("tinymce/html/Styles", [], function() {
339
336
  value = matches[2].replace(trimRightRegExp, '');
340
337
 
341
338
  if (name && value.length > 0) {
339
+ if (!settings.allow_script_urls && (name == "behavior" || /expression\s*\(/.test(value))) {
340
+ continue;
341
+ }
342
+
342
343
  // Opera will produce 700 instead of bold in their style values
343
344
  if (name === 'font-weight' && value === '700') {
344
345
  value = 'bold';
@@ -595,7 +596,11 @@ define("tinymce/dom/EventUtils", [], function() {
595
596
 
596
597
  // Use W3C method
597
598
  if (doc.addEventListener) {
598
- addEvent(win, 'DOMContentLoaded', readyHandler);
599
+ if (doc.readyState === "complete") {
600
+ readyHandler();
601
+ } else {
602
+ addEvent(win, 'DOMContentLoaded', readyHandler);
603
+ }
599
604
  } else {
600
605
  // Use IE method
601
606
  addEvent(doc, "readystatechange", waitForDomLoaded);
@@ -2635,9 +2640,9 @@ define("tinymce/Env", [], function() {
2635
2640
  webkit = /WebKit/.test(userAgent);
2636
2641
  ie = !webkit && !opera && (/MSIE/gi).test(userAgent) && (/Explorer/gi).test(nav.appName);
2637
2642
  ie = ie && /MSIE (\w+)\./.exec(userAgent)[1];
2638
- ie11 = userAgent.indexOf('Trident') != -1 ? 11 : false;
2643
+ ie11 = userAgent.indexOf('Trident/') != -1 && (userAgent.indexOf('rv:') != -1 || nav.appName.indexOf('Netscape') != -1) ? 11 : false;
2639
2644
  ie = ie || ie11;
2640
- gecko = !webkit && /Gecko/.test(userAgent);
2645
+ gecko = !webkit && !ie11 && /Gecko/.test(userAgent);
2641
2646
  mac = userAgent.indexOf('Mac') != -1;
2642
2647
  iDevice = /(iPad|iPhone)/.test(userAgent);
2643
2648
 
@@ -4763,6 +4768,12 @@ define("tinymce/dom/DOMUtils", [
4763
4768
  self.boundEvents = null;
4764
4769
  }
4765
4770
 
4771
+ // Restore sizzle document to window.document
4772
+ // Since the current document might be removed producing "Permission denied" on IE see #6325
4773
+ if (Sizzle.setDocument) {
4774
+ Sizzle.setDocument();
4775
+ }
4776
+
4766
4777
  self.win = self.doc = self.root = self.events = self.frag = null;
4767
4778
  },
4768
4779
 
@@ -6510,6 +6521,12 @@ define("tinymce/html/Schema", [
6510
6521
  each(split('span'), function(name) {
6511
6522
  elements[name].removeEmptyAttrs = true;
6512
6523
  });
6524
+
6525
+ // Remove these by default
6526
+ // TODO: Reenable in 4.1
6527
+ /*each(split('script style'), function(name) {
6528
+ delete elements[name];
6529
+ });*/
6513
6530
  } else {
6514
6531
  setValidElements(settings.valid_elements);
6515
6532
  }
@@ -6851,7 +6868,7 @@ define("tinymce/html/SaxParser", [
6851
6868
  var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
6852
6869
  var attributesRequired, attributesDefault, attributesForced;
6853
6870
  var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0;
6854
- var decode = Entities.decode, fixSelfClosing;
6871
+ var decode = Entities.decode, fixSelfClosing, filteredAttrs = Tools.makeMap('src,href');
6855
6872
 
6856
6873
  function processEndTag(name) {
6857
6874
  var pos, i;
@@ -6881,7 +6898,7 @@ define("tinymce/html/SaxParser", [
6881
6898
  }
6882
6899
 
6883
6900
  function parseAttribute(match, name, value, val2, val3) {
6884
- var attrRule, i;
6901
+ var attrRule, i, trimRegExp = /[\s\u0000-\u001F]+/g;
6885
6902
 
6886
6903
  name = name.toLowerCase();
6887
6904
  value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
@@ -6917,6 +6934,12 @@ define("tinymce/html/SaxParser", [
6917
6934
  }
6918
6935
  }
6919
6936
 
6937
+ if (filteredAttrs[name] && !settings.allow_script_urls) {
6938
+ if (/(java|vb)script:/i.test(decodeURIComponent(value.replace(trimRegExp, '')))) {
6939
+ return;
6940
+ }
6941
+ }
6942
+
6920
6943
  // Add attribute to list and map
6921
6944
  attrList.map[name] = value;
6922
6945
  attrList.push({
@@ -7117,6 +7140,15 @@ define("tinymce/html/SaxParser", [
7117
7140
  }
7118
7141
  }
7119
7142
  } else if ((value = matches[1])) { // Comment
7143
+ // Padd comment value to avoid browsers from parsing invalid comments as HTML
7144
+ if (value.charAt(0) === '>') {
7145
+ value = ' ' + value;
7146
+ }
7147
+
7148
+ if (!settings.allow_conditional_comments && value.substr(0, 3) === '[if') {
7149
+ value = ' ' + value;
7150
+ }
7151
+
7120
7152
  self.comment(value);
7121
7153
  } else if ((value = matches[2])) { // CDATA
7122
7154
  self.cdata(value);
@@ -7469,6 +7501,7 @@ define("tinymce/html/DomParser", [
7469
7501
  if (!rootBlockNode) {
7470
7502
  // Create a new root block element
7471
7503
  rootBlockNode = createNode(rootBlockName, 1);
7504
+ rootBlockNode.attr(settings.forced_root_block_attrs);
7472
7505
  rootNode.insert(rootBlockNode, node);
7473
7506
  rootBlockNode.append(node);
7474
7507
  } else {
@@ -7532,6 +7565,8 @@ define("tinymce/html/DomParser", [
7532
7565
 
7533
7566
  parser = new SaxParser({
7534
7567
  validate: validate,
7568
+ allow_script_urls: settings.allow_script_urls,
7569
+ allow_conditional_comments: settings.allow_conditional_comments,
7535
7570
 
7536
7571
  // Exclude P and LI from DOM parsing since it's treated better by the DOM parser
7537
7572
  self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
@@ -9364,10 +9399,7 @@ define("tinymce/dom/ControlSelection", [
9364
9399
  }
9365
9400
 
9366
9401
  function showResizeRect(targetElm, mouseDownHandleName, mouseDownEvent) {
9367
- var position, targetWidth, targetHeight, e, rect;
9368
-
9369
- // Fix when inline element is within a relaive container
9370
- var offsetParent = editor.getBody().offsetParent || editor.getBody();
9402
+ var position, targetWidth, targetHeight, e, rect, offsetParent = editor.getBody();
9371
9403
 
9372
9404
  // Get position and size of target
9373
9405
  position = dom.getPos(targetElm, offsetParent);
@@ -9635,16 +9667,24 @@ define("tinymce/dom/ControlSelection", [
9635
9667
 
9636
9668
  if (Env.ie >= 11) {
9637
9669
  // TODO: Drag/drop doesn't work
9638
- editor.on('mouseup mousedown', function(e) {
9639
- if (e.target.nodeName == 'IMG' || editor.selection.getNode().nodeName == 'IMG') {
9670
+ editor.on('mouseup', function(e) {
9671
+ var nodeName = e.target.nodeName;
9672
+
9673
+ if (/^(TABLE|IMG|HR)$/.test(nodeName)) {
9674
+ editor.selection.select(e.target, nodeName == 'TABLE');
9675
+ editor.nodeChanged();
9676
+ }
9677
+ });
9678
+
9679
+ editor.dom.bind(editor.getBody(), 'mscontrolselect', function(e) {
9680
+ if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
9640
9681
  e.preventDefault();
9641
- editor.selection.select(e.target);
9642
9682
  }
9643
9683
  });
9644
9684
  }
9645
9685
  }
9646
9686
 
9647
- editor.on('nodechange mousedown ResizeEditor', updateResizeRect);
9687
+ editor.on('nodechange mousedown mouseup ResizeEditor', updateResizeRect);
9648
9688
 
9649
9689
  // Update resize rect while typing in a table
9650
9690
  editor.on('keydown keyup', function(e) {
@@ -10651,7 +10691,7 @@ define("tinymce/dom/Selection", [
10651
10691
  getNode: function() {
10652
10692
  var self = this, rng = self.getRng(), elm;
10653
10693
  var startContainer = rng.startContainer, endContainer = rng.endContainer;
10654
- var startOffset = rng.startOffset, endOffset = rng.endOffset;
10694
+ var startOffset = rng.startOffset, endOffset = rng.endOffset, root = self.dom.getRoot();
10655
10695
 
10656
10696
  function skipEmptyTextNodes(node, forwards) {
10657
10697
  var orig = node;
@@ -10665,7 +10705,7 @@ define("tinymce/dom/Selection", [
10665
10705
 
10666
10706
  // Range maybe lost after the editor is made visible again
10667
10707
  if (!rng) {
10668
- return self.dom.getRoot();
10708
+ return root;
10669
10709
  }
10670
10710
 
10671
10711
  if (rng.setStart) {
@@ -10713,7 +10753,14 @@ define("tinymce/dom/Selection", [
10713
10753
  return elm;
10714
10754
  }
10715
10755
 
10716
- return rng.item ? rng.item(0) : rng.parentElement();
10756
+ elm = rng.item ? rng.item(0) : rng.parentElement();
10757
+
10758
+ // IE 7 might return elements outside the iframe
10759
+ if (elm.ownerDocument !== self.win.document) {
10760
+ elm = root;
10761
+ }
10762
+
10763
+ return elm;
10717
10764
  },
10718
10765
 
10719
10766
  getSelectedBlocks: function(startElm, endElm) {
@@ -12161,6 +12208,7 @@ define("tinymce/Formatter", [
12161
12208
 
12162
12209
  function removeRngStyle(rng) {
12163
12210
  var startContainer, endContainer;
12211
+ var commonAncestorContainer = rng.commonAncestorContainer;
12164
12212
 
12165
12213
  rng = expandRng(rng, formatList, TRUE);
12166
12214
 
@@ -12169,17 +12217,24 @@ define("tinymce/Formatter", [
12169
12217
  endContainer = getContainer(rng);
12170
12218
 
12171
12219
  if (startContainer != endContainer) {
12172
- // WebKit will render the table incorrectly if we wrap a TD in a SPAN
12173
- // so lets see if the can use the first child instead
12174
- // This will happen if you tripple click a table cell and use remove formatting
12175
- if (/^(TR|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
12176
- if (startContainer.nodeName == "TD") {
12177
- startContainer = startContainer.firstChild || startContainer;
12178
- } else {
12220
+ // WebKit will render the table incorrectly if we wrap a TH or TD in a SPAN
12221
+ // so let's see if we can use the first child instead
12222
+ // This will happen if you triple click a table cell and use remove formatting
12223
+ if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
12224
+ if (startContainer.nodeName == "TR") {
12179
12225
  startContainer = startContainer.firstChild.firstChild || startContainer;
12226
+ } else {
12227
+ startContainer = startContainer.firstChild || startContainer;
12180
12228
  }
12181
12229
  }
12182
12230
 
12231
+ // Try to adjust endContainer as well if cells on the same row were selected - bug #6410
12232
+ if (commonAncestorContainer &&
12233
+ /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) &&
12234
+ /^(TH|TD)$/.test(endContainer.nodeName) && endContainer.firstChild) {
12235
+ endContainer = endContainer.firstChild || endContainer;
12236
+ }
12237
+
12183
12238
  // Wrap start/end nodes in span element since these might be cloned/moved
12184
12239
  startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'});
12185
12240
  endContainer = wrap(endContainer, 'span', {id: '_end', 'data-mce-type': 'bookmark'});
@@ -13193,6 +13248,7 @@ define("tinymce/Formatter", [
13193
13248
  if (isValid(forcedRootBlock, node.nodeName.toLowerCase())) {
13194
13249
  if (!rootBlockElm) {
13195
13250
  rootBlockElm = wrap(node, forcedRootBlock);
13251
+ dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
13196
13252
  } else {
13197
13253
  rootBlockElm.appendChild(node);
13198
13254
  }
@@ -14180,6 +14236,24 @@ define("tinymce/EnterKey", [
14180
14236
  function moveToCaretPosition(root) {
14181
14237
  var walker, node, rng, lastNode = root, tempElm;
14182
14238
 
14239
+ function firstNonWhiteSpaceNodeSibling(node) {
14240
+ while (node) {
14241
+ if (node.nodeType == 1 || (node.nodeType == 3 && node.data && /[\r\n\s]/.test(node.data))) {
14242
+ return node;
14243
+ }
14244
+
14245
+ node = node.nextSibling;
14246
+ }
14247
+ }
14248
+
14249
+ if (root.nodeName == 'LI') {
14250
+ var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
14251
+
14252
+ if (firstChild && /^(UL|OL)$/.test(firstChild.nodeName)) {
14253
+ root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
14254
+ }
14255
+ }
14256
+
14183
14257
  rng = dom.createRng();
14184
14258
 
14185
14259
  if (root.hasChildNodes()) {
@@ -14234,12 +14308,26 @@ define("tinymce/EnterKey", [
14234
14308
  selection.scrollIntoView(root);
14235
14309
  }
14236
14310
 
14311
+ function setForcedBlockAttrs(node) {
14312
+ var forcedRootBlockName = settings.forced_root_block;
14313
+
14314
+ if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
14315
+ dom.setAttribs(node, settings.forced_root_block_attrs);
14316
+ }
14317
+ }
14318
+
14237
14319
  // Creates a new block element by cloning the current one or creating a new one if the name is specified
14238
14320
  // This function will also copy any text formatting from the parent block and add it to the new one
14239
14321
  function createNewBlock(name) {
14240
14322
  var node = container, block, clonedNode, caretNode;
14241
14323
 
14242
- block = name || parentBlockName == "TABLE" ? dom.create(name || newBlockName) : parentBlock.cloneNode(false);
14324
+ if (name || parentBlockName == "TABLE") {
14325
+ block = dom.create(name || newBlockName);
14326
+ setForcedBlockAttrs(block);
14327
+ } else {
14328
+ block = parentBlock.cloneNode(false);
14329
+ }
14330
+
14243
14331
  caretNode = block;
14244
14332
 
14245
14333
  // Clone any parent styles
@@ -14345,6 +14433,7 @@ define("tinymce/EnterKey", [
14345
14433
 
14346
14434
  if (!parentBlock.hasChildNodes()) {
14347
14435
  newBlock = dom.create(blockName);
14436
+ setForcedBlockAttrs(newBlock);
14348
14437
  parentBlock.appendChild(newBlock);
14349
14438
  rng.setStart(newBlock, 0);
14350
14439
  rng.setEnd(newBlock, 0);
@@ -14365,6 +14454,7 @@ define("tinymce/EnterKey", [
14365
14454
 
14366
14455
  if (startNode && schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
14367
14456
  newBlock = dom.create(blockName);
14457
+ setForcedBlockAttrs(newBlock);
14368
14458
  startNode.parentNode.insertBefore(newBlock, startNode);
14369
14459
 
14370
14460
  // Start wrapping until we hit a block
@@ -14449,8 +14539,14 @@ define("tinymce/EnterKey", [
14449
14539
  tmpRng.setStartAfter(parentBlock);
14450
14540
  tmpRng.setEndAfter(containerBlock);
14451
14541
  fragment = tmpRng.extractContents();
14452
- dom.insertAfter(fragment, containerBlock);
14453
- dom.insertAfter(newBlock, containerBlock);
14542
+
14543
+ if (newBlockName == 'LI' && fragment.firstChild.nodeName == 'LI') {
14544
+ newBlock = fragment.firstChild;
14545
+ dom.insertAfter(fragment, containerBlock);
14546
+ } else {
14547
+ dom.insertAfter(fragment, containerBlock);
14548
+ dom.insertAfter(newBlock, containerBlock);
14549
+ }
14454
14550
  }
14455
14551
 
14456
14552
  dom.remove(parentBlock);
@@ -14801,7 +14897,7 @@ define("tinymce/ForceBlocks", [], function() {
14801
14897
  }
14802
14898
 
14803
14899
  if (!rootBlockNode) {
14804
- rootBlockNode = dom.create(forcedRootBlock);
14900
+ rootBlockNode = dom.create(forcedRootBlock, editor.settings.forced_root_block_attrs);
14805
14901
  node.parentNode.insertBefore(rootBlockNode, node);
14806
14902
  wrapped = true;
14807
14903
  }
@@ -15156,7 +15252,7 @@ define("tinymce/EditorCommands", [
15156
15252
 
15157
15253
  mceInsertContent: function(command, ui, value) {
15158
15254
  var parser, serializer, parentNode, rootNode, fragment, args;
15159
- var marker, nodeRect, viewPortRect, rng, node, node2, bookmarkHtml, viewportBodyElement;
15255
+ var marker, rng, node, node2, bookmarkHtml;
15160
15256
 
15161
15257
  function trimOrPaddLeftRight(html) {
15162
15258
  var rng, container, offset;
@@ -15209,6 +15305,14 @@ define("tinymce/EditorCommands", [
15209
15305
  // Replace the caret marker with a span bookmark element
15210
15306
  value = value.replace(/\{\$caret\}/, bookmarkHtml);
15211
15307
 
15308
+ // If selection is at <body>|<p></p> then move it into <body><p>|</p>
15309
+ var body = editor.getBody();
15310
+ if (dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) {
15311
+ body.firstChild.appendChild(dom.doc.createTextNode('\u00a0'));
15312
+ selection.select(body.firstChild, true);
15313
+ dom.remove(body.firstChild.lastChild);
15314
+ }
15315
+
15212
15316
  // Insert node maker where we will insert the new HTML and get it's parent
15213
15317
  if (!selection.isCollapsed()) {
15214
15318
  editor.getDoc().execCommand('Delete', false, null);
@@ -15287,18 +15391,7 @@ define("tinymce/EditorCommands", [
15287
15391
  }
15288
15392
 
15289
15393
  marker = dom.get('mce_marker');
15290
-
15291
- // Scroll range into view scrollIntoView on element can't be used since it will scroll the main view port as well
15292
- nodeRect = dom.getRect(marker);
15293
- viewPortRect = dom.getViewPort(editor.getWin());
15294
-
15295
- // Check if node is out side the viewport if it is then scroll to it
15296
- if ((nodeRect.y + nodeRect.h > viewPortRect.y + viewPortRect.h || nodeRect.y < viewPortRect.y) ||
15297
- (nodeRect.x > viewPortRect.x + viewPortRect.w || nodeRect.x < viewPortRect.x)) {
15298
- viewportBodyElement = isIE ? editor.getDoc().documentElement : editor.getBody();
15299
- viewportBodyElement.scrollLeft = nodeRect.x;
15300
- viewportBodyElement.scrollTop = nodeRect.y - viewPortRect.h + 25;
15301
- }
15394
+ selection.scrollIntoView(marker);
15302
15395
 
15303
15396
  // Move selection before marker and remove it
15304
15397
  rng = dom.createRng();
@@ -16098,9 +16191,8 @@ define("tinymce/util/Class", [
16098
16191
  * @class tinymce.ui.Selector
16099
16192
  */
16100
16193
  define("tinymce/ui/Selector", [
16101
- "tinymce/util/Class",
16102
- "tinymce/util/Tools"
16103
- ], function(Class, Tools) {
16194
+ "tinymce/util/Class"
16195
+ ], function(Class) {
16104
16196
  "use strict";
16105
16197
 
16106
16198
  /**
@@ -16319,8 +16411,12 @@ define("tinymce/ui/Selector", [
16319
16411
  // Find the index and length since a psuedo filter like :first needs it
16320
16412
  if (filters.psuedo) {
16321
16413
  siblings = item.parent().items();
16322
- index = Tools.inArray(item, siblings);
16323
- length = siblings.length;
16414
+ index = length = siblings.length;
16415
+ while (index--) {
16416
+ if (siblings[index] === item) {
16417
+ break;
16418
+ }
16419
+ }
16324
16420
  }
16325
16421
 
16326
16422
  for (fi = 0, fl = filters.length; fi < fl; fi++) {
@@ -16990,7 +17086,8 @@ define("tinymce/ui/Control", [
16990
17086
 
16991
17087
  var Control = Class.extend({
16992
17088
  Statics: {
16993
- controlIdLookup: {}
17089
+ controlIdLookup: {},
17090
+ elementIdCache: elementIdCache
16994
17091
  },
16995
17092
 
16996
17093
  isRtl: function() {
@@ -20489,7 +20586,7 @@ define("tinymce/ui/Window", [
20489
20586
  * @method recalc
20490
20587
  */
20491
20588
  recalc: function() {
20492
- var self = this, statusbar = self.statusbar, layoutRect, width, needsRecalc;
20589
+ var self = this, statusbar = self.statusbar, layoutRect, width, x, needsRecalc;
20493
20590
 
20494
20591
  if (self._fullscreen) {
20495
20592
  self.layoutRect(DomUtils.getWindowSize());
@@ -20504,7 +20601,8 @@ define("tinymce/ui/Window", [
20504
20601
  if (self.settings.title && !self._fullscreen) {
20505
20602
  width = layoutRect.headerW;
20506
20603
  if (width > layoutRect.w) {
20507
- self.layoutRect({w: width});
20604
+ x = layoutRect.x - Math.max(0, width / 2);
20605
+ self.layoutRect({w: width, x: x});
20508
20606
  needsRecalc = true;
20509
20607
  }
20510
20608
  }
@@ -20515,7 +20613,8 @@ define("tinymce/ui/Window", [
20515
20613
 
20516
20614
  width = statusbar.layoutRect().minW + layoutRect.deltaW;
20517
20615
  if (width > layoutRect.w) {
20518
- self.layoutRect({w: width});
20616
+ x = layoutRect.x - Math.max(0, width - layoutRect.w);
20617
+ self.layoutRect({w: width, x: x});
20519
20618
  needsRecalc = true;
20520
20619
  }
20521
20620
  }
@@ -23323,6 +23422,10 @@ define("tinymce/Editor", [
23323
23422
  body.disabled = true;
23324
23423
 
23325
23424
  if (!settings.readonly) {
23425
+ if (self.inline && DOM.getStyle(body, 'position', true) == 'static') {
23426
+ body.style.position = 'relative';
23427
+ }
23428
+
23326
23429
  body.contentEditable = self.getParam('content_editable_state', true);
23327
23430
  }
23328
23431
 
@@ -23609,7 +23712,7 @@ define("tinymce/Editor", [
23609
23712
  body = self.getBody();
23610
23713
 
23611
23714
  // Check for setActive since it doesn't scroll to the element
23612
- if (body.setActive) {
23715
+ if (body.setActive && Env.ie < 11) {
23613
23716
  body.setActive();
23614
23717
  } else {
23615
23718
  body.focus();
@@ -24284,13 +24387,9 @@ define("tinymce/Editor", [
24284
24387
 
24285
24388
  // Check if forcedRootBlock is configured and that the block is a valid child of the body
24286
24389
  if (forcedRootBlockName && self.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
24287
- if (ie && ie < 11) {
24288
- // IE renders BR elements in blocks so lets just add an empty block
24289
- content = '<' + forcedRootBlockName + '></' + forcedRootBlockName + '>';
24290
- } else {
24291
- content = '<' + forcedRootBlockName + '><br data-mce-bogus="1"></' + forcedRootBlockName + '>';
24292
- }
24293
- } else if (!ie) {
24390
+ content = ie && ie < 11 ? '' : '<br data-mce-bogus="1">';
24391
+ content = self.dom.createHTML(forcedRootBlockName, self.settings.forced_root_block_attrs, content);
24392
+ } else if (!ie || ie < 11) {
24294
24393
  // We need to add a BR when forced_root_block is disabled on non IE browsers to place the caret
24295
24394
  content = '<br data-mce-bogus="1">';
24296
24395
  }
@@ -24322,22 +24421,6 @@ define("tinymce/Editor", [
24322
24421
  }*/
24323
24422
  }
24324
24423
 
24325
- // Move selection to start of body if it's a after init setContent call
24326
- // This prevents IE 7/8 from moving focus to empty editors
24327
- if (!args.initial) {
24328
- var dom = self.dom, selection = self.selection;
24329
-
24330
- // IE can't have the caret inside <body><p>|</p></body> unless we do some magic
24331
- if (ie < 11 && dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) {
24332
- body.firstChild.appendChild(dom.doc.createTextNode('\u00a0'));
24333
- selection.select(body.firstChild, true);
24334
- dom.remove(body.firstChild.lastChild);
24335
- } else {
24336
- selection.select(body, true);
24337
- selection.collapse(true);
24338
- }
24339
- }
24340
-
24341
24424
  return args.content;
24342
24425
  },
24343
24426
 
@@ -24991,6 +25074,10 @@ define("tinymce/FocusManager", [
24991
25074
  }
24992
25075
  });
24993
25076
 
25077
+ editor.on('setcontent', function() {
25078
+ lastRng = null;
25079
+ });
25080
+
24994
25081
  // Remove last selection bookmark on mousedown see #6305
24995
25082
  editor.on('mousedown', function() {
24996
25083
  editor.selection.lastFocusBookmark = null;
@@ -25014,6 +25101,8 @@ define("tinymce/FocusManager", [
25014
25101
  editor.focus(false);
25015
25102
  editorManager.focusedEditor = editor;
25016
25103
  }
25104
+
25105
+ lastRng = null;
25017
25106
  });
25018
25107
 
25019
25108
  editor.on('focusout', function() {
@@ -25105,7 +25194,7 @@ define("tinymce/EditorManager", [
25105
25194
  * @property minorVersion
25106
25195
  * @type String
25107
25196
  */
25108
- minorVersion : '0.8',
25197
+ minorVersion : '0.10',
25109
25198
 
25110
25199
  /**
25111
25200
  * Release date of TinyMCE build.
@@ -25113,7 +25202,7 @@ define("tinymce/EditorManager", [
25113
25202
  * @property releaseDate
25114
25203
  * @type String
25115
25204
  */
25116
- releaseDate: '2013-10-10',
25205
+ releaseDate: '2013-10-28',
25117
25206
 
25118
25207
  /**
25119
25208
  * Collection of editor instances.
@@ -26151,10 +26240,23 @@ define("tinymce/util/LocalStorage", [], function() {
26151
26240
  data = storageElm.getAttribute(userDataKey) || '';
26152
26241
 
26153
26242
  do {
26154
- key = next(parseInt(next(), 32) || 0);
26243
+ var offset = next();
26244
+ if (offset === null) {
26245
+ break;
26246
+ }
26247
+
26248
+ key = next(parseInt(offset, 32) || 0);
26155
26249
  if (key !== null) {
26156
- value = next(parseInt(next(), 32) || 0);
26157
- items[key] = value;
26250
+ offset = next();
26251
+ if (offset === null) {
26252
+ break;
26253
+ }
26254
+
26255
+ value = next(parseInt(offset, 32) || 0);
26256
+
26257
+ if (key) {
26258
+ items[key] = value;
26259
+ }
26158
26260
  }
26159
26261
  } while (key !== null);
26160
26262
 
@@ -26178,7 +26280,13 @@ define("tinymce/util/LocalStorage", [], function() {
26178
26280
  }
26179
26281
 
26180
26282
  storageElm.setAttribute(userDataKey, data);
26181
- storageElm.save(userDataKey);
26283
+
26284
+ try {
26285
+ storageElm.save(userDataKey);
26286
+ } catch (ex) {
26287
+ // Ignore disk full
26288
+ }
26289
+
26182
26290
  updateKeys();
26183
26291
  }
26184
26292
 
@@ -27694,8 +27802,18 @@ define("tinymce/ui/ElementPath", [
27694
27802
  postRender: function() {
27695
27803
  var self = this, editor = EditorManager.activeEditor;
27696
27804
 
27697
- function isBogus(elm) {
27698
- return elm.nodeType === 1 && (elm.nodeName == "BR" || !!elm.getAttribute('data-mce-bogus'));
27805
+ function isHidden(elm) {
27806
+ if (elm.nodeType === 1) {
27807
+ if (elm.nodeName == "BR" || !!elm.getAttribute('data-mce-bogus')) {
27808
+ return true;
27809
+ }
27810
+
27811
+ if (elm.getAttribute('data-mce-type') === 'bookmark') {
27812
+ return true;
27813
+ }
27814
+ }
27815
+
27816
+ return false;
27699
27817
  }
27700
27818
 
27701
27819
  self.on('select', function(e) {
@@ -27705,7 +27823,7 @@ define("tinymce/ui/ElementPath", [
27705
27823
 
27706
27824
  node = editor.selection.getStart();
27707
27825
  while (node && node != body) {
27708
- if (!isBogus(node)) {
27826
+ if (!isHidden(node)) {
27709
27827
  parents.push(node);
27710
27828
  }
27711
27829
 
@@ -27720,7 +27838,7 @@ define("tinymce/ui/ElementPath", [
27720
27838
  var parents = [], selectionParents = e.parents, i = selectionParents.length;
27721
27839
 
27722
27840
  while (i--) {
27723
- if (selectionParents[i].nodeType == 1 && !isBogus(selectionParents[i])) {
27841
+ if (selectionParents[i].nodeType == 1 && !isHidden(selectionParents[i])) {
27724
27842
  var args = editor.fire('ResolveName', {
27725
27843
  name: selectionParents[i].nodeName.toLowerCase(),
27726
27844
  target: selectionParents[i]
@@ -29253,7 +29371,7 @@ define("tinymce/ui/GridLayout", [
29253
29371
  // Get control settings and calculate x, y
29254
29372
  ctrlSettings = ctrl.settings;
29255
29373
  ctrlLayoutRect = ctrl.layoutRect();
29256
- width = colWidths[x];
29374
+ width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth);
29257
29375
  alignX = alignY = 0;
29258
29376
  ctrlLayoutRect.x = posX;
29259
29377
  ctrlLayoutRect.y = posY;
@@ -30141,6 +30259,7 @@ define("tinymce/ui/MenuItem", [
30141
30259
  );
30142
30260
 
30143
30261
  menu.moveRel(self.getEl(), rel);
30262
+ menu.rel = rel;
30144
30263
 
30145
30264
  rel = 'menu-sub-' + rel;
30146
30265
  menu.removeClass(menu._lastRel);
@@ -30584,7 +30703,7 @@ define("tinymce/ui/SplitButton", [
30584
30703
  * @method repaint
30585
30704
  */
30586
30705
  repaint: function() {
30587
- var self = this, elm = self.getEl(), rect = self.layoutRect(), mainButtonElm, menuButtonElm, btnStyle;
30706
+ var self = this, elm = self.getEl(), rect = self.layoutRect(), mainButtonElm, menuButtonElm;
30588
30707
 
30589
30708
  self._super();
30590
30709
 
@@ -30600,12 +30719,6 @@ define("tinymce/ui/SplitButton", [
30600
30719
  height: rect.h - 2
30601
30720
  });
30602
30721
 
30603
- btnStyle = mainButtonElm.firstChild.style;
30604
- btnStyle.width = btnStyle.height = "100%";
30605
-
30606
- btnStyle = menuButtonElm.firstChild.style;
30607
- btnStyle.width = btnStyle.height = "100%";
30608
-
30609
30722
  return self;
30610
30723
  },
30611
30724