tinymce-rails 4.0.8 → 4.0.10

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 (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