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)
@@ -253,7 +253,11 @@ define("tinymce/dom/EventUtils", [], function() {
253
253
 
254
254
  // Use W3C method
255
255
  if (doc.addEventListener) {
256
- addEvent(win, 'DOMContentLoaded', readyHandler);
256
+ if (doc.readyState === "complete") {
257
+ readyHandler();
258
+ } else {
259
+ addEvent(win, 'DOMContentLoaded', readyHandler);
260
+ }
257
261
  } else {
258
262
  // Use IE method
259
263
  addEvent(doc, "readystatechange", waitForDomLoaded);
@@ -2549,12 +2553,14 @@ setDocument();
2549
2553
  [0, 0].sort( sortOrder );
2550
2554
  support.detectDuplicates = hasDuplicate;
2551
2555
 
2556
+ /*
2552
2557
  // EXPOSE
2553
2558
  if ( typeof define === "function" && define.amd ) {
2554
2559
  define(function() { return Sizzle; });
2555
2560
  } else {
2556
2561
  window.Sizzle = Sizzle;
2557
2562
  }
2563
+ */
2558
2564
 
2559
2565
  // EXPOSE
2560
2566
  return Sizzle;
@@ -3366,7 +3372,8 @@ define("tinymce/html/Styles", [], function() {
3366
3372
  * @return {Object} Object representation of that style like {border: '1px solid red'}
3367
3373
  */
3368
3374
  parse: function(css) {
3369
- var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this;
3375
+ var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter;
3376
+ var urlConverterScope = settings.url_converter_scope || this;
3370
3377
 
3371
3378
  function compress(prefix, suffix) {
3372
3379
  var top, right, bottom, left;
@@ -3487,6 +3494,10 @@ define("tinymce/html/Styles", [], function() {
3487
3494
 
3488
3495
  url = decode(url || url2 || url3);
3489
3496
 
3497
+ if (!settings.allow_script_urls && /(java|vb)script:/i.test(url.replace(/[\s\r\n]+/, ''))) {
3498
+ return "";
3499
+ }
3500
+
3490
3501
  // Convert the URL to relative/absolute depending on config
3491
3502
  if (urlConverter) {
3492
3503
  url = urlConverter.call(urlConverterScope, url, 'style');
@@ -3497,6 +3508,8 @@ define("tinymce/html/Styles", [], function() {
3497
3508
  }
3498
3509
 
3499
3510
  if (css) {
3511
+ css = css.replace(/[\u0000-\u001F]/g, '');
3512
+
3500
3513
  // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
3501
3514
  css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) {
3502
3515
  return str.replace(/[;:]/g, encode);
@@ -3508,6 +3521,10 @@ define("tinymce/html/Styles", [], function() {
3508
3521
  value = matches[2].replace(trimRightRegExp, '');
3509
3522
 
3510
3523
  if (name && value.length > 0) {
3524
+ if (!settings.allow_script_urls && (name == "behavior" || /expression\s*\(/.test(value))) {
3525
+ continue;
3526
+ }
3527
+
3511
3528
  // Opera will produce 700 instead of bold in their style values
3512
3529
  if (name === 'font-weight' && value === '700') {
3513
3530
  value = 'bold';
@@ -5254,9 +5271,9 @@ define("tinymce/Env", [], function() {
5254
5271
  webkit = /WebKit/.test(userAgent);
5255
5272
  ie = !webkit && !opera && (/MSIE/gi).test(userAgent) && (/Explorer/gi).test(nav.appName);
5256
5273
  ie = ie && /MSIE (\w+)\./.exec(userAgent)[1];
5257
- ie11 = userAgent.indexOf('Trident') != -1 ? 11 : false;
5274
+ ie11 = userAgent.indexOf('Trident/') != -1 && (userAgent.indexOf('rv:') != -1 || nav.appName.indexOf('Netscape') != -1) ? 11 : false;
5258
5275
  ie = ie || ie11;
5259
- gecko = !webkit && /Gecko/.test(userAgent);
5276
+ gecko = !webkit && !ie11 && /Gecko/.test(userAgent);
5260
5277
  mac = userAgent.indexOf('Mac') != -1;
5261
5278
  iDevice = /(iPad|iPhone)/.test(userAgent);
5262
5279
 
@@ -7382,6 +7399,12 @@ define("tinymce/dom/DOMUtils", [
7382
7399
  self.boundEvents = null;
7383
7400
  }
7384
7401
 
7402
+ // Restore sizzle document to window.document
7403
+ // Since the current document might be removed producing "Permission denied" on IE see #6325
7404
+ if (Sizzle.setDocument) {
7405
+ Sizzle.setDocument();
7406
+ }
7407
+
7385
7408
  self.win = self.doc = self.root = self.events = self.frag = null;
7386
7409
  },
7387
7410
 
@@ -9129,6 +9152,12 @@ define("tinymce/html/Schema", [
9129
9152
  each(split('span'), function(name) {
9130
9153
  elements[name].removeEmptyAttrs = true;
9131
9154
  });
9155
+
9156
+ // Remove these by default
9157
+ // TODO: Reenable in 4.1
9158
+ /*each(split('script style'), function(name) {
9159
+ delete elements[name];
9160
+ });*/
9132
9161
  } else {
9133
9162
  setValidElements(settings.valid_elements);
9134
9163
  }
@@ -9470,7 +9499,7 @@ define("tinymce/html/SaxParser", [
9470
9499
  var validate, elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
9471
9500
  var attributesRequired, attributesDefault, attributesForced;
9472
9501
  var anyAttributesRequired, selfClosing, tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0;
9473
- var decode = Entities.decode, fixSelfClosing;
9502
+ var decode = Entities.decode, fixSelfClosing, filteredAttrs = Tools.makeMap('src,href');
9474
9503
 
9475
9504
  function processEndTag(name) {
9476
9505
  var pos, i;
@@ -9500,7 +9529,7 @@ define("tinymce/html/SaxParser", [
9500
9529
  }
9501
9530
 
9502
9531
  function parseAttribute(match, name, value, val2, val3) {
9503
- var attrRule, i;
9532
+ var attrRule, i, trimRegExp = /[\s\u0000-\u001F]+/g;
9504
9533
 
9505
9534
  name = name.toLowerCase();
9506
9535
  value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
@@ -9536,6 +9565,12 @@ define("tinymce/html/SaxParser", [
9536
9565
  }
9537
9566
  }
9538
9567
 
9568
+ if (filteredAttrs[name] && !settings.allow_script_urls) {
9569
+ if (/(java|vb)script:/i.test(decodeURIComponent(value.replace(trimRegExp, '')))) {
9570
+ return;
9571
+ }
9572
+ }
9573
+
9539
9574
  // Add attribute to list and map
9540
9575
  attrList.map[name] = value;
9541
9576
  attrList.push({
@@ -9736,6 +9771,15 @@ define("tinymce/html/SaxParser", [
9736
9771
  }
9737
9772
  }
9738
9773
  } else if ((value = matches[1])) { // Comment
9774
+ // Padd comment value to avoid browsers from parsing invalid comments as HTML
9775
+ if (value.charAt(0) === '>') {
9776
+ value = ' ' + value;
9777
+ }
9778
+
9779
+ if (!settings.allow_conditional_comments && value.substr(0, 3) === '[if') {
9780
+ value = ' ' + value;
9781
+ }
9782
+
9739
9783
  self.comment(value);
9740
9784
  } else if ((value = matches[2])) { // CDATA
9741
9785
  self.cdata(value);
@@ -10088,6 +10132,7 @@ define("tinymce/html/DomParser", [
10088
10132
  if (!rootBlockNode) {
10089
10133
  // Create a new root block element
10090
10134
  rootBlockNode = createNode(rootBlockName, 1);
10135
+ rootBlockNode.attr(settings.forced_root_block_attrs);
10091
10136
  rootNode.insert(rootBlockNode, node);
10092
10137
  rootBlockNode.append(node);
10093
10138
  } else {
@@ -10151,6 +10196,8 @@ define("tinymce/html/DomParser", [
10151
10196
 
10152
10197
  parser = new SaxParser({
10153
10198
  validate: validate,
10199
+ allow_script_urls: settings.allow_script_urls,
10200
+ allow_conditional_comments: settings.allow_conditional_comments,
10154
10201
 
10155
10202
  // Exclude P and LI from DOM parsing since it's treated better by the DOM parser
10156
10203
  self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
@@ -11983,10 +12030,7 @@ define("tinymce/dom/ControlSelection", [
11983
12030
  }
11984
12031
 
11985
12032
  function showResizeRect(targetElm, mouseDownHandleName, mouseDownEvent) {
11986
- var position, targetWidth, targetHeight, e, rect;
11987
-
11988
- // Fix when inline element is within a relaive container
11989
- var offsetParent = editor.getBody().offsetParent || editor.getBody();
12033
+ var position, targetWidth, targetHeight, e, rect, offsetParent = editor.getBody();
11990
12034
 
11991
12035
  // Get position and size of target
11992
12036
  position = dom.getPos(targetElm, offsetParent);
@@ -12254,16 +12298,24 @@ define("tinymce/dom/ControlSelection", [
12254
12298
 
12255
12299
  if (Env.ie >= 11) {
12256
12300
  // TODO: Drag/drop doesn't work
12257
- editor.on('mouseup mousedown', function(e) {
12258
- if (e.target.nodeName == 'IMG' || editor.selection.getNode().nodeName == 'IMG') {
12301
+ editor.on('mouseup', function(e) {
12302
+ var nodeName = e.target.nodeName;
12303
+
12304
+ if (/^(TABLE|IMG|HR)$/.test(nodeName)) {
12305
+ editor.selection.select(e.target, nodeName == 'TABLE');
12306
+ editor.nodeChanged();
12307
+ }
12308
+ });
12309
+
12310
+ editor.dom.bind(editor.getBody(), 'mscontrolselect', function(e) {
12311
+ if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
12259
12312
  e.preventDefault();
12260
- editor.selection.select(e.target);
12261
12313
  }
12262
12314
  });
12263
12315
  }
12264
12316
  }
12265
12317
 
12266
- editor.on('nodechange mousedown ResizeEditor', updateResizeRect);
12318
+ editor.on('nodechange mousedown mouseup ResizeEditor', updateResizeRect);
12267
12319
 
12268
12320
  // Update resize rect while typing in a table
12269
12321
  editor.on('keydown keyup', function(e) {
@@ -13270,7 +13322,7 @@ define("tinymce/dom/Selection", [
13270
13322
  getNode: function() {
13271
13323
  var self = this, rng = self.getRng(), elm;
13272
13324
  var startContainer = rng.startContainer, endContainer = rng.endContainer;
13273
- var startOffset = rng.startOffset, endOffset = rng.endOffset;
13325
+ var startOffset = rng.startOffset, endOffset = rng.endOffset, root = self.dom.getRoot();
13274
13326
 
13275
13327
  function skipEmptyTextNodes(node, forwards) {
13276
13328
  var orig = node;
@@ -13284,7 +13336,7 @@ define("tinymce/dom/Selection", [
13284
13336
 
13285
13337
  // Range maybe lost after the editor is made visible again
13286
13338
  if (!rng) {
13287
- return self.dom.getRoot();
13339
+ return root;
13288
13340
  }
13289
13341
 
13290
13342
  if (rng.setStart) {
@@ -13332,7 +13384,14 @@ define("tinymce/dom/Selection", [
13332
13384
  return elm;
13333
13385
  }
13334
13386
 
13335
- return rng.item ? rng.item(0) : rng.parentElement();
13387
+ elm = rng.item ? rng.item(0) : rng.parentElement();
13388
+
13389
+ // IE 7 might return elements outside the iframe
13390
+ if (elm.ownerDocument !== self.win.document) {
13391
+ elm = root;
13392
+ }
13393
+
13394
+ return elm;
13336
13395
  },
13337
13396
 
13338
13397
  getSelectedBlocks: function(startElm, endElm) {
@@ -14780,6 +14839,7 @@ define("tinymce/Formatter", [
14780
14839
 
14781
14840
  function removeRngStyle(rng) {
14782
14841
  var startContainer, endContainer;
14842
+ var commonAncestorContainer = rng.commonAncestorContainer;
14783
14843
 
14784
14844
  rng = expandRng(rng, formatList, TRUE);
14785
14845
 
@@ -14788,17 +14848,24 @@ define("tinymce/Formatter", [
14788
14848
  endContainer = getContainer(rng);
14789
14849
 
14790
14850
  if (startContainer != endContainer) {
14791
- // WebKit will render the table incorrectly if we wrap a TD in a SPAN
14792
- // so lets see if the can use the first child instead
14793
- // This will happen if you tripple click a table cell and use remove formatting
14794
- if (/^(TR|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
14795
- if (startContainer.nodeName == "TD") {
14796
- startContainer = startContainer.firstChild || startContainer;
14797
- } else {
14851
+ // WebKit will render the table incorrectly if we wrap a TH or TD in a SPAN
14852
+ // so let's see if we can use the first child instead
14853
+ // This will happen if you triple click a table cell and use remove formatting
14854
+ if (/^(TR|TH|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
14855
+ if (startContainer.nodeName == "TR") {
14798
14856
  startContainer = startContainer.firstChild.firstChild || startContainer;
14857
+ } else {
14858
+ startContainer = startContainer.firstChild || startContainer;
14799
14859
  }
14800
14860
  }
14801
14861
 
14862
+ // Try to adjust endContainer as well if cells on the same row were selected - bug #6410
14863
+ if (commonAncestorContainer &&
14864
+ /^T(HEAD|BODY|FOOT|R)$/.test(commonAncestorContainer.nodeName) &&
14865
+ /^(TH|TD)$/.test(endContainer.nodeName) && endContainer.firstChild) {
14866
+ endContainer = endContainer.firstChild || endContainer;
14867
+ }
14868
+
14802
14869
  // Wrap start/end nodes in span element since these might be cloned/moved
14803
14870
  startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'});
14804
14871
  endContainer = wrap(endContainer, 'span', {id: '_end', 'data-mce-type': 'bookmark'});
@@ -15812,6 +15879,7 @@ define("tinymce/Formatter", [
15812
15879
  if (isValid(forcedRootBlock, node.nodeName.toLowerCase())) {
15813
15880
  if (!rootBlockElm) {
15814
15881
  rootBlockElm = wrap(node, forcedRootBlock);
15882
+ dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
15815
15883
  } else {
15816
15884
  rootBlockElm.appendChild(node);
15817
15885
  }
@@ -16799,6 +16867,24 @@ define("tinymce/EnterKey", [
16799
16867
  function moveToCaretPosition(root) {
16800
16868
  var walker, node, rng, lastNode = root, tempElm;
16801
16869
 
16870
+ function firstNonWhiteSpaceNodeSibling(node) {
16871
+ while (node) {
16872
+ if (node.nodeType == 1 || (node.nodeType == 3 && node.data && /[\r\n\s]/.test(node.data))) {
16873
+ return node;
16874
+ }
16875
+
16876
+ node = node.nextSibling;
16877
+ }
16878
+ }
16879
+
16880
+ if (root.nodeName == 'LI') {
16881
+ var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
16882
+
16883
+ if (firstChild && /^(UL|OL)$/.test(firstChild.nodeName)) {
16884
+ root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
16885
+ }
16886
+ }
16887
+
16802
16888
  rng = dom.createRng();
16803
16889
 
16804
16890
  if (root.hasChildNodes()) {
@@ -16853,12 +16939,26 @@ define("tinymce/EnterKey", [
16853
16939
  selection.scrollIntoView(root);
16854
16940
  }
16855
16941
 
16942
+ function setForcedBlockAttrs(node) {
16943
+ var forcedRootBlockName = settings.forced_root_block;
16944
+
16945
+ if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
16946
+ dom.setAttribs(node, settings.forced_root_block_attrs);
16947
+ }
16948
+ }
16949
+
16856
16950
  // Creates a new block element by cloning the current one or creating a new one if the name is specified
16857
16951
  // This function will also copy any text formatting from the parent block and add it to the new one
16858
16952
  function createNewBlock(name) {
16859
16953
  var node = container, block, clonedNode, caretNode;
16860
16954
 
16861
- block = name || parentBlockName == "TABLE" ? dom.create(name || newBlockName) : parentBlock.cloneNode(false);
16955
+ if (name || parentBlockName == "TABLE") {
16956
+ block = dom.create(name || newBlockName);
16957
+ setForcedBlockAttrs(block);
16958
+ } else {
16959
+ block = parentBlock.cloneNode(false);
16960
+ }
16961
+
16862
16962
  caretNode = block;
16863
16963
 
16864
16964
  // Clone any parent styles
@@ -16964,6 +17064,7 @@ define("tinymce/EnterKey", [
16964
17064
 
16965
17065
  if (!parentBlock.hasChildNodes()) {
16966
17066
  newBlock = dom.create(blockName);
17067
+ setForcedBlockAttrs(newBlock);
16967
17068
  parentBlock.appendChild(newBlock);
16968
17069
  rng.setStart(newBlock, 0);
16969
17070
  rng.setEnd(newBlock, 0);
@@ -16984,6 +17085,7 @@ define("tinymce/EnterKey", [
16984
17085
 
16985
17086
  if (startNode && schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
16986
17087
  newBlock = dom.create(blockName);
17088
+ setForcedBlockAttrs(newBlock);
16987
17089
  startNode.parentNode.insertBefore(newBlock, startNode);
16988
17090
 
16989
17091
  // Start wrapping until we hit a block
@@ -17068,8 +17170,14 @@ define("tinymce/EnterKey", [
17068
17170
  tmpRng.setStartAfter(parentBlock);
17069
17171
  tmpRng.setEndAfter(containerBlock);
17070
17172
  fragment = tmpRng.extractContents();
17071
- dom.insertAfter(fragment, containerBlock);
17072
- dom.insertAfter(newBlock, containerBlock);
17173
+
17174
+ if (newBlockName == 'LI' && fragment.firstChild.nodeName == 'LI') {
17175
+ newBlock = fragment.firstChild;
17176
+ dom.insertAfter(fragment, containerBlock);
17177
+ } else {
17178
+ dom.insertAfter(fragment, containerBlock);
17179
+ dom.insertAfter(newBlock, containerBlock);
17180
+ }
17073
17181
  }
17074
17182
 
17075
17183
  dom.remove(parentBlock);
@@ -17420,7 +17528,7 @@ define("tinymce/ForceBlocks", [], function() {
17420
17528
  }
17421
17529
 
17422
17530
  if (!rootBlockNode) {
17423
- rootBlockNode = dom.create(forcedRootBlock);
17531
+ rootBlockNode = dom.create(forcedRootBlock, editor.settings.forced_root_block_attrs);
17424
17532
  node.parentNode.insertBefore(rootBlockNode, node);
17425
17533
  wrapped = true;
17426
17534
  }
@@ -17775,7 +17883,7 @@ define("tinymce/EditorCommands", [
17775
17883
 
17776
17884
  mceInsertContent: function(command, ui, value) {
17777
17885
  var parser, serializer, parentNode, rootNode, fragment, args;
17778
- var marker, nodeRect, viewPortRect, rng, node, node2, bookmarkHtml, viewportBodyElement;
17886
+ var marker, rng, node, node2, bookmarkHtml;
17779
17887
 
17780
17888
  function trimOrPaddLeftRight(html) {
17781
17889
  var rng, container, offset;
@@ -17828,6 +17936,14 @@ define("tinymce/EditorCommands", [
17828
17936
  // Replace the caret marker with a span bookmark element
17829
17937
  value = value.replace(/\{\$caret\}/, bookmarkHtml);
17830
17938
 
17939
+ // If selection is at <body>|<p></p> then move it into <body><p>|</p>
17940
+ var body = editor.getBody();
17941
+ if (dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) {
17942
+ body.firstChild.appendChild(dom.doc.createTextNode('\u00a0'));
17943
+ selection.select(body.firstChild, true);
17944
+ dom.remove(body.firstChild.lastChild);
17945
+ }
17946
+
17831
17947
  // Insert node maker where we will insert the new HTML and get it's parent
17832
17948
  if (!selection.isCollapsed()) {
17833
17949
  editor.getDoc().execCommand('Delete', false, null);
@@ -17906,18 +18022,7 @@ define("tinymce/EditorCommands", [
17906
18022
  }
17907
18023
 
17908
18024
  marker = dom.get('mce_marker');
17909
-
17910
- // Scroll range into view scrollIntoView on element can't be used since it will scroll the main view port as well
17911
- nodeRect = dom.getRect(marker);
17912
- viewPortRect = dom.getViewPort(editor.getWin());
17913
-
17914
- // Check if node is out side the viewport if it is then scroll to it
17915
- if ((nodeRect.y + nodeRect.h > viewPortRect.y + viewPortRect.h || nodeRect.y < viewPortRect.y) ||
17916
- (nodeRect.x > viewPortRect.x + viewPortRect.w || nodeRect.x < viewPortRect.x)) {
17917
- viewportBodyElement = isIE ? editor.getDoc().documentElement : editor.getBody();
17918
- viewportBodyElement.scrollLeft = nodeRect.x;
17919
- viewportBodyElement.scrollTop = nodeRect.y - viewPortRect.h + 25;
17920
- }
18025
+ selection.scrollIntoView(marker);
17921
18026
 
17922
18027
  // Move selection before marker and remove it
17923
18028
  rng = dom.createRng();
@@ -18717,9 +18822,8 @@ define("tinymce/util/Class", [
18717
18822
  * @class tinymce.ui.Selector
18718
18823
  */
18719
18824
  define("tinymce/ui/Selector", [
18720
- "tinymce/util/Class",
18721
- "tinymce/util/Tools"
18722
- ], function(Class, Tools) {
18825
+ "tinymce/util/Class"
18826
+ ], function(Class) {
18723
18827
  "use strict";
18724
18828
 
18725
18829
  /**
@@ -18938,8 +19042,12 @@ define("tinymce/ui/Selector", [
18938
19042
  // Find the index and length since a psuedo filter like :first needs it
18939
19043
  if (filters.psuedo) {
18940
19044
  siblings = item.parent().items();
18941
- index = Tools.inArray(item, siblings);
18942
- length = siblings.length;
19045
+ index = length = siblings.length;
19046
+ while (index--) {
19047
+ if (siblings[index] === item) {
19048
+ break;
19049
+ }
19050
+ }
18943
19051
  }
18944
19052
 
18945
19053
  for (fi = 0, fl = filters.length; fi < fl; fi++) {
@@ -19609,7 +19717,8 @@ define("tinymce/ui/Control", [
19609
19717
 
19610
19718
  var Control = Class.extend({
19611
19719
  Statics: {
19612
- controlIdLookup: {}
19720
+ controlIdLookup: {},
19721
+ elementIdCache: elementIdCache
19613
19722
  },
19614
19723
 
19615
19724
  isRtl: function() {
@@ -23108,7 +23217,7 @@ define("tinymce/ui/Window", [
23108
23217
  * @method recalc
23109
23218
  */
23110
23219
  recalc: function() {
23111
- var self = this, statusbar = self.statusbar, layoutRect, width, needsRecalc;
23220
+ var self = this, statusbar = self.statusbar, layoutRect, width, x, needsRecalc;
23112
23221
 
23113
23222
  if (self._fullscreen) {
23114
23223
  self.layoutRect(DomUtils.getWindowSize());
@@ -23123,7 +23232,8 @@ define("tinymce/ui/Window", [
23123
23232
  if (self.settings.title && !self._fullscreen) {
23124
23233
  width = layoutRect.headerW;
23125
23234
  if (width > layoutRect.w) {
23126
- self.layoutRect({w: width});
23235
+ x = layoutRect.x - Math.max(0, width / 2);
23236
+ self.layoutRect({w: width, x: x});
23127
23237
  needsRecalc = true;
23128
23238
  }
23129
23239
  }
@@ -23134,7 +23244,8 @@ define("tinymce/ui/Window", [
23134
23244
 
23135
23245
  width = statusbar.layoutRect().minW + layoutRect.deltaW;
23136
23246
  if (width > layoutRect.w) {
23137
- self.layoutRect({w: width});
23247
+ x = layoutRect.x - Math.max(0, width - layoutRect.w);
23248
+ self.layoutRect({w: width, x: x});
23138
23249
  needsRecalc = true;
23139
23250
  }
23140
23251
  }
@@ -25942,6 +26053,10 @@ define("tinymce/Editor", [
25942
26053
  body.disabled = true;
25943
26054
 
25944
26055
  if (!settings.readonly) {
26056
+ if (self.inline && DOM.getStyle(body, 'position', true) == 'static') {
26057
+ body.style.position = 'relative';
26058
+ }
26059
+
25945
26060
  body.contentEditable = self.getParam('content_editable_state', true);
25946
26061
  }
25947
26062
 
@@ -26228,7 +26343,7 @@ define("tinymce/Editor", [
26228
26343
  body = self.getBody();
26229
26344
 
26230
26345
  // Check for setActive since it doesn't scroll to the element
26231
- if (body.setActive) {
26346
+ if (body.setActive && Env.ie < 11) {
26232
26347
  body.setActive();
26233
26348
  } else {
26234
26349
  body.focus();
@@ -26903,13 +27018,9 @@ define("tinymce/Editor", [
26903
27018
 
26904
27019
  // Check if forcedRootBlock is configured and that the block is a valid child of the body
26905
27020
  if (forcedRootBlockName && self.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
26906
- if (ie && ie < 11) {
26907
- // IE renders BR elements in blocks so lets just add an empty block
26908
- content = '<' + forcedRootBlockName + '></' + forcedRootBlockName + '>';
26909
- } else {
26910
- content = '<' + forcedRootBlockName + '><br data-mce-bogus="1"></' + forcedRootBlockName + '>';
26911
- }
26912
- } else if (!ie) {
27021
+ content = ie && ie < 11 ? '' : '<br data-mce-bogus="1">';
27022
+ content = self.dom.createHTML(forcedRootBlockName, self.settings.forced_root_block_attrs, content);
27023
+ } else if (!ie || ie < 11) {
26913
27024
  // We need to add a BR when forced_root_block is disabled on non IE browsers to place the caret
26914
27025
  content = '<br data-mce-bogus="1">';
26915
27026
  }
@@ -26941,22 +27052,6 @@ define("tinymce/Editor", [
26941
27052
  }*/
26942
27053
  }
26943
27054
 
26944
- // Move selection to start of body if it's a after init setContent call
26945
- // This prevents IE 7/8 from moving focus to empty editors
26946
- if (!args.initial) {
26947
- var dom = self.dom, selection = self.selection;
26948
-
26949
- // IE can't have the caret inside <body><p>|</p></body> unless we do some magic
26950
- if (ie < 11 && dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) {
26951
- body.firstChild.appendChild(dom.doc.createTextNode('\u00a0'));
26952
- selection.select(body.firstChild, true);
26953
- dom.remove(body.firstChild.lastChild);
26954
- } else {
26955
- selection.select(body, true);
26956
- selection.collapse(true);
26957
- }
26958
- }
26959
-
26960
27055
  return args.content;
26961
27056
  },
26962
27057
 
@@ -27610,6 +27705,10 @@ define("tinymce/FocusManager", [
27610
27705
  }
27611
27706
  });
27612
27707
 
27708
+ editor.on('setcontent', function() {
27709
+ lastRng = null;
27710
+ });
27711
+
27613
27712
  // Remove last selection bookmark on mousedown see #6305
27614
27713
  editor.on('mousedown', function() {
27615
27714
  editor.selection.lastFocusBookmark = null;
@@ -27633,6 +27732,8 @@ define("tinymce/FocusManager", [
27633
27732
  editor.focus(false);
27634
27733
  editorManager.focusedEditor = editor;
27635
27734
  }
27735
+
27736
+ lastRng = null;
27636
27737
  });
27637
27738
 
27638
27739
  editor.on('focusout', function() {
@@ -27724,7 +27825,7 @@ define("tinymce/EditorManager", [
27724
27825
  * @property minorVersion
27725
27826
  * @type String
27726
27827
  */
27727
- minorVersion : '0.8',
27828
+ minorVersion : '0.10',
27728
27829
 
27729
27830
  /**
27730
27831
  * Release date of TinyMCE build.
@@ -27732,7 +27833,7 @@ define("tinymce/EditorManager", [
27732
27833
  * @property releaseDate
27733
27834
  * @type String
27734
27835
  */
27735
- releaseDate: '2013-10-10',
27836
+ releaseDate: '2013-10-28',
27736
27837
 
27737
27838
  /**
27738
27839
  * Collection of editor instances.
@@ -28770,10 +28871,23 @@ define("tinymce/util/LocalStorage", [], function() {
28770
28871
  data = storageElm.getAttribute(userDataKey) || '';
28771
28872
 
28772
28873
  do {
28773
- key = next(parseInt(next(), 32) || 0);
28874
+ var offset = next();
28875
+ if (offset === null) {
28876
+ break;
28877
+ }
28878
+
28879
+ key = next(parseInt(offset, 32) || 0);
28774
28880
  if (key !== null) {
28775
- value = next(parseInt(next(), 32) || 0);
28776
- items[key] = value;
28881
+ offset = next();
28882
+ if (offset === null) {
28883
+ break;
28884
+ }
28885
+
28886
+ value = next(parseInt(offset, 32) || 0);
28887
+
28888
+ if (key) {
28889
+ items[key] = value;
28890
+ }
28777
28891
  }
28778
28892
  } while (key !== null);
28779
28893
 
@@ -28797,7 +28911,13 @@ define("tinymce/util/LocalStorage", [], function() {
28797
28911
  }
28798
28912
 
28799
28913
  storageElm.setAttribute(userDataKey, data);
28800
- storageElm.save(userDataKey);
28914
+
28915
+ try {
28916
+ storageElm.save(userDataKey);
28917
+ } catch (ex) {
28918
+ // Ignore disk full
28919
+ }
28920
+
28801
28921
  updateKeys();
28802
28922
  }
28803
28923
 
@@ -30313,8 +30433,18 @@ define("tinymce/ui/ElementPath", [
30313
30433
  postRender: function() {
30314
30434
  var self = this, editor = EditorManager.activeEditor;
30315
30435
 
30316
- function isBogus(elm) {
30317
- return elm.nodeType === 1 && (elm.nodeName == "BR" || !!elm.getAttribute('data-mce-bogus'));
30436
+ function isHidden(elm) {
30437
+ if (elm.nodeType === 1) {
30438
+ if (elm.nodeName == "BR" || !!elm.getAttribute('data-mce-bogus')) {
30439
+ return true;
30440
+ }
30441
+
30442
+ if (elm.getAttribute('data-mce-type') === 'bookmark') {
30443
+ return true;
30444
+ }
30445
+ }
30446
+
30447
+ return false;
30318
30448
  }
30319
30449
 
30320
30450
  self.on('select', function(e) {
@@ -30324,7 +30454,7 @@ define("tinymce/ui/ElementPath", [
30324
30454
 
30325
30455
  node = editor.selection.getStart();
30326
30456
  while (node && node != body) {
30327
- if (!isBogus(node)) {
30457
+ if (!isHidden(node)) {
30328
30458
  parents.push(node);
30329
30459
  }
30330
30460
 
@@ -30339,7 +30469,7 @@ define("tinymce/ui/ElementPath", [
30339
30469
  var parents = [], selectionParents = e.parents, i = selectionParents.length;
30340
30470
 
30341
30471
  while (i--) {
30342
- if (selectionParents[i].nodeType == 1 && !isBogus(selectionParents[i])) {
30472
+ if (selectionParents[i].nodeType == 1 && !isHidden(selectionParents[i])) {
30343
30473
  var args = editor.fire('ResolveName', {
30344
30474
  name: selectionParents[i].nodeName.toLowerCase(),
30345
30475
  target: selectionParents[i]
@@ -31872,7 +32002,7 @@ define("tinymce/ui/GridLayout", [
31872
32002
  // Get control settings and calculate x, y
31873
32003
  ctrlSettings = ctrl.settings;
31874
32004
  ctrlLayoutRect = ctrl.layoutRect();
31875
- width = colWidths[x];
32005
+ width = Math.max(colWidths[x], ctrlLayoutRect.startMinWidth);
31876
32006
  alignX = alignY = 0;
31877
32007
  ctrlLayoutRect.x = posX;
31878
32008
  ctrlLayoutRect.y = posY;
@@ -32760,6 +32890,7 @@ define("tinymce/ui/MenuItem", [
32760
32890
  );
32761
32891
 
32762
32892
  menu.moveRel(self.getEl(), rel);
32893
+ menu.rel = rel;
32763
32894
 
32764
32895
  rel = 'menu-sub-' + rel;
32765
32896
  menu.removeClass(menu._lastRel);
@@ -33203,7 +33334,7 @@ define("tinymce/ui/SplitButton", [
33203
33334
  * @method repaint
33204
33335
  */
33205
33336
  repaint: function() {
33206
- var self = this, elm = self.getEl(), rect = self.layoutRect(), mainButtonElm, menuButtonElm, btnStyle;
33337
+ var self = this, elm = self.getEl(), rect = self.layoutRect(), mainButtonElm, menuButtonElm;
33207
33338
 
33208
33339
  self._super();
33209
33340
 
@@ -33219,12 +33350,6 @@ define("tinymce/ui/SplitButton", [
33219
33350
  height: rect.h - 2
33220
33351
  });
33221
33352
 
33222
- btnStyle = mainButtonElm.firstChild.style;
33223
- btnStyle.width = btnStyle.height = "100%";
33224
-
33225
- btnStyle = menuButtonElm.firstChild.style;
33226
- btnStyle.width = btnStyle.height = "100%";
33227
-
33228
33353
  return self;
33229
33354
  },
33230
33355