tinymce-rails 4.3.3 → 4.3.7

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +2 -3
  4. data/app/assets/javascripts/tinymce-jquery.js +1 -1
  5. data/app/assets/source/tinymce/tinymce.js +913 -264
  6. data/lib/tinymce/rails/version.rb +2 -2
  7. data/vendor/assets/javascripts/tinymce/jquery.tinymce.js +1 -1
  8. data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
  9. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
  10. data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
  11. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
  12. data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
  13. data/vendor/assets/javascripts/tinymce/plugins/bbcode/plugin.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
  15. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
  16. data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/colorpicker/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tinymce/plugins/contextmenu/plugin.js +1 -1
  19. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
  20. data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
  21. data/vendor/assets/javascripts/tinymce/plugins/example/plugin.js +1 -1
  22. data/vendor/assets/javascripts/tinymce/plugins/fullpage/plugin.js +1 -1
  23. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +1 -1
  24. data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.js +1 -1
  25. data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tinymce/plugins/imagetools/plugin.js +1 -1
  27. data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
  28. data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
  29. data/vendor/assets/javascripts/tinymce/plugins/layer/plugin.js +1 -1
  30. data/vendor/assets/javascripts/tinymce/plugins/legacyoutput/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
  32. data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
  33. data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
  34. data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
  35. data/vendor/assets/javascripts/tinymce/plugins/noneditable/plugin.js +1 -1
  36. data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
  37. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
  38. data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
  39. data/vendor/assets/javascripts/tinymce/plugins/print/plugin.js +1 -1
  40. data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
  41. data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
  42. data/vendor/assets/javascripts/tinymce/plugins/spellchecker/plugin.js +1 -1
  43. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.js +1 -1
  44. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +2 -2
  45. data/vendor/assets/javascripts/tinymce/plugins/template/plugin.js +1 -1
  46. data/vendor/assets/javascripts/tinymce/plugins/textcolor/plugin.js +1 -1
  47. data/vendor/assets/javascripts/tinymce/plugins/textpattern/plugin.js +1 -1
  48. data/vendor/assets/javascripts/tinymce/plugins/visualblocks/css/visualblocks.css +1 -1
  49. data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
  50. data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
  51. data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
  52. data/vendor/assets/javascripts/tinymce/skins/lightgray/content.inline.min.css +1 -154
  53. data/vendor/assets/javascripts/tinymce/skins/lightgray/content.min.css +1 -1
  54. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
  55. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce.svg +35 -4
  56. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
  57. data/vendor/assets/javascripts/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  58. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
  59. data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
  60. data/vendor/assets/javascripts/tinymce/themes/modern/theme.js +1 -1
  61. data/vendor/assets/javascripts/tinymce/tinymce.js +13 -13
  62. metadata +3 -4
  63. data/app/assets/source/tinymce/tinymce.jquery.js +0 -43162
  64. data/vendor/assets/javascripts/tinymce/tinymce.jquery.js +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19d9d9d09e14d2445b7df336a8f878f5d91bdb9b
4
- data.tar.gz: 5353f2e6f6288d22994dfe65fec1e27d9bbc1988
3
+ metadata.gz: 7c9f2676e96cc3a5dad5574f8ab53d712cf89871
4
+ data.tar.gz: adac5380dc67f0f9460a8b871e80dac9bb77da4a
5
5
  SHA512:
6
- metadata.gz: 3ad619d2cb0e3e8598c77354440aed573ba168d2777be3040982330f8a944c6a94153e9f1cf21753659de894e543da67b41d0fc8ae9c503f36e543b0e9d385ae
7
- data.tar.gz: 668b0d9ac8df83016f5862d702b40433e9231d6d6b6f4d1a6e89e4a5b36f215c058ee1cd1ef79e1ecd24f5d67c0a41cbb4b0d3902cd817327f043a19229a069b
6
+ metadata.gz: 3d941436b663ba7487505ebf2c6e65dac9123c223e6ba7636d87199b719394c8338704b10193a67a110077c255b6b53b2e14d2d0512838ca4f420abcafb81387
7
+ data.tar.gz: 0ec890ac6b33b76bd862cf061dde2659897bdc0f1263d849be630d90a82f2583151c9fcb2f9021c65db288555ae9d0c65ba778b315333e2012a1ac841dc528a0
data/README.md CHANGED
@@ -51,7 +51,7 @@ alternate:
51
51
  - table
52
52
  ```
53
53
 
54
- See the [TinyMCE 4 Documentation](http://www.tinymce.com/wiki.php/Configuration) for a full list of configuration options.
54
+ See the [TinyMCE 4 Documentation](https://www.tinymce.com/docs/configure/) for a full list of configuration options.
55
55
 
56
56
 
57
57
  **3. Include the TinyMCE assets**
data/Rakefile CHANGED
@@ -16,8 +16,8 @@ desc "Update TinyMCE to version #{TinyMCE::Rails::TINYMCE_VERSION}"
16
16
  task :update => [ :fetch, :extract, :rename ]
17
17
 
18
18
  task :fetch do
19
- download("http://download.moxiecode.com/tinymce/tinymce_#{TinyMCE::Rails::TINYMCE_VERSION}.zip", "tinymce.zip")
20
- download("http://download.moxiecode.com/tinymce/tinymce_#{TinyMCE::Rails::TINYMCE_VERSION}_dev.zip", "tinymce.dev.zip")
19
+ download("http://download.ephox.com/tinymce/community/tinymce_#{TinyMCE::Rails::TINYMCE_VERSION}.zip", "tinymce.zip")
20
+ download("http://download.ephox.com/tinymce/community/tinymce_#{TinyMCE::Rails::TINYMCE_VERSION}_dev.zip", "tinymce.dev.zip")
21
21
  end
22
22
 
23
23
  task :extract do
@@ -36,7 +36,6 @@ task :extract do
36
36
  `mv tmp/tinymce/js/tinymce/tinymce.jquery.min.js vendor/assets/javascripts/tinymce/tinymce.jquery.js`
37
37
  `mkdir -p app/assets/source/tinymce`
38
38
  `mv tmp/tinymce/js/tinymce/tinymce.js app/assets/source/tinymce/tinymce.js`
39
- `mv tmp/tinymce/js/tinymce/tinymce.jquery.js app/assets/source/tinymce/tinymce.jquery.js`
40
39
  end
41
40
  end
42
41
 
@@ -1,3 +1,3 @@
1
1
  //= require tinymce/preinit.js
2
- //= require tinymce/tinymce.jquery.js
2
+ //= require tinymce/tinymce.js
3
3
  //= require tinymce/jquery.tinymce.js
@@ -1,4 +1,4 @@
1
- // 4.3.3 (2016-01-14)
1
+ // 4.3.7 (2016-03-02)
2
2
 
3
3
  /**
4
4
  * Compiled inline version. (Library mode)
@@ -676,9 +676,9 @@ define("tinymce/util/Delay", [
676
676
  * @return {Function} Throttled function callback.
677
677
  */
678
678
  throttle: function(callback, time) {
679
- var timer;
679
+ var timer, func;
680
680
 
681
- return function() {
681
+ func = function() {
682
682
  var args = arguments;
683
683
 
684
684
  clearTimeout(timer);
@@ -687,6 +687,12 @@ define("tinymce/util/Delay", [
687
687
  callback.apply(this, args);
688
688
  }, time);
689
689
  };
690
+
691
+ func.stop = function() {
692
+ clearTimeout(timer);
693
+ };
694
+
695
+ return func;
690
696
  },
691
697
 
692
698
  /**
@@ -787,6 +793,19 @@ define("tinymce/dom/EventUtils", [
787
793
  event.target = event.srcElement || document;
788
794
  }
789
795
 
796
+ // When target element is inside Shadow DOM we need to take first element from path
797
+ // otherwise we'll get Shadow Root parent, not actual target element
798
+
799
+ // Normalize target for WebComponents v0 implementation (in Chrome)
800
+ if (event.path) {
801
+ event.target = event.path[0];
802
+ }
803
+
804
+ // Normalize target for WebComponents v1 implementation (standard)
805
+ if (event.deepPath) {
806
+ event.target = event.deepPath[0];
807
+ }
808
+
790
809
  // Calculate pageX/Y if missing and clientX/Y available
791
810
  if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undef && originalEvent.clientX !== undef) {
792
811
  var eventDoc = event.target.ownerDocument || document;
@@ -3344,7 +3363,7 @@ return Sizzle;
3344
3363
  */
3345
3364
  define("tinymce/Env", [], function() {
3346
3365
  var nav = navigator, userAgent = nav.userAgent;
3347
- var opera, webkit, ie, ie11, ie12, gecko, mac, iDevice, android, fileApi, phone, tablet;
3366
+ var opera, webkit, ie, ie11, ie12, gecko, mac, iDevice, android, fileApi, phone, tablet, windowsPhone;
3348
3367
 
3349
3368
  function matchMediaQuery(query) {
3350
3369
  return "matchMedia" in window ? matchMedia(query).matches : false;
@@ -3364,6 +3383,7 @@ define("tinymce/Env", [], function() {
3364
3383
  fileApi = "FormData" in window && "FileReader" in window && "URL" in window && !!URL.createObjectURL;
3365
3384
  phone = matchMediaQuery("only screen and (max-device-width: 480px)") && (android || iDevice);
3366
3385
  tablet = matchMediaQuery("only screen and (min-width: 800px)") && (android || iDevice);
3386
+ windowsPhone = userAgent.indexOf('Windows Phone') != -1;
3367
3387
 
3368
3388
  if (ie12) {
3369
3389
  webkit = false;
@@ -3496,7 +3516,8 @@ define("tinymce/Env", [], function() {
3496
3516
  */
3497
3517
  ceFalse: (ie === false || ie > 8),
3498
3518
 
3499
- desktop: !phone && !tablet
3519
+ desktop: !phone && !tablet,
3520
+ windowsPhone: windowsPhone
3500
3521
  };
3501
3522
  });
3502
3523
 
@@ -4748,7 +4769,8 @@ define("tinymce/dom/DomQuery", [
4748
4769
  */
4749
4770
  append: function() {
4750
4771
  return domManipulate(this, arguments, function(node) {
4751
- if (this.nodeType === 1) {
4772
+ // Either element or Shadow Root
4773
+ if (this.nodeType === 1 || (this.host && this.host.nodeType === 1)) {
4752
4774
  this.appendChild(node);
4753
4775
  }
4754
4776
  });
@@ -4763,7 +4785,8 @@ define("tinymce/dom/DomQuery", [
4763
4785
  */
4764
4786
  prepend: function() {
4765
4787
  return domManipulate(this, arguments, function(node) {
4766
- if (this.nodeType === 1) {
4788
+ // Either element or Shadow Root
4789
+ if (this.nodeType === 1 || (this.host && this.host.nodeType === 1)) {
4767
4790
  this.insertBefore(node, this.firstChild);
4768
4791
  }
4769
4792
  }, true);
@@ -6108,6 +6131,35 @@ define("tinymce/dom/TreeWalker", [], function() {
6108
6131
  }
6109
6132
  }
6110
6133
 
6134
+ function findPreviousNode(node, startName, siblingName, shallow) {
6135
+ var sibling, parent, child;
6136
+
6137
+ if (node) {
6138
+ sibling = node[siblingName];
6139
+ if (rootNode && sibling === rootNode) {
6140
+ return;
6141
+ }
6142
+
6143
+ if (sibling) {
6144
+ if (!shallow) {
6145
+ // Walk up the parents to look for siblings
6146
+ for (child = sibling[startName]; child; child = child[startName]) {
6147
+ if (!child[startName]) {
6148
+ return child;
6149
+ }
6150
+ }
6151
+ }
6152
+
6153
+ return sibling;
6154
+ }
6155
+
6156
+ parent = node.parentNode;
6157
+ if (parent && parent !== rootNode) {
6158
+ return parent;
6159
+ }
6160
+ }
6161
+ }
6162
+
6111
6163
  /**
6112
6164
  * Returns the current node.
6113
6165
  *
@@ -6139,6 +6191,11 @@ define("tinymce/dom/TreeWalker", [], function() {
6139
6191
  node = findSibling(node, 'lastChild', 'previousSibling', shallow);
6140
6192
  return node;
6141
6193
  };
6194
+
6195
+ this.prev2 = function(shallow) {
6196
+ node = findPreviousNode(node, 'lastChild', 'previousSibling', shallow);
6197
+ return node;
6198
+ };
6142
6199
  };
6143
6200
  });
6144
6201
 
@@ -10141,7 +10198,7 @@ define("tinymce/dom/RangeUtils", [
10141
10198
 
10142
10199
  // Handle table cell selection the table plugin enables
10143
10200
  // you to fake select table cells and perform formatting actions on them
10144
- nodes = dom.select('td.mce-item-selected,th.mce-item-selected');
10201
+ nodes = dom.select('td[data-mce-selected],th[data-mce-selected]');
10145
10202
  if (nodes.length > 0) {
10146
10203
  each(nodes, function(node) {
10147
10204
  callback([node]);
@@ -14071,11 +14128,7 @@ define("tinymce/dom/Serializer", [
14071
14128
  "tinymce/text/Zwsp"
14072
14129
  ], function(DOMUtils, DomParser, SaxParser, Entities, Serializer, Node, Schema, Env, Tools, Zwsp) {
14073
14130
  var each = Tools.each, trim = Tools.trim;
14074
- var DOM = DOMUtils.DOM;
14075
- var trimContentRegExp = new RegExp([
14076
- '<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\\/span>', // Trim bogus spans like caret containers
14077
- '\\s?data-mce-selected="[^"]+"' // Trim temporaty data-mce prefixed attributes like data-mce-selected
14078
- ].join('|'), 'gi');
14131
+ var DOM = DOMUtils.DOM, tempAttrs = ["data-mce-selected"];
14079
14132
 
14080
14133
  /**
14081
14134
  * IE 11 has a fantastic bug where it will produce two trailing BR elements to iframe bodies when
@@ -14120,6 +14173,17 @@ define("tinymce/dom/Serializer", [
14120
14173
  schema = editor.schema;
14121
14174
  }
14122
14175
 
14176
+ function trimHtml(html) {
14177
+ var trimContentRegExp = new RegExp([
14178
+ '<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\\/span>', // Trim bogus spans like caret containers
14179
+ '\\s?(' + tempAttrs.join('|') + ')="[^"]+"' // Trim temporaty data-mce prefixed attributes like data-mce-selected
14180
+ ].join('|'), 'gi');
14181
+
14182
+ html = Zwsp.trim(html.replace(trimContentRegExp, ''));
14183
+
14184
+ return html;
14185
+ }
14186
+
14123
14187
  /**
14124
14188
  * Returns a trimmed version of the editor contents to be used for the undo level. This
14125
14189
  * will remove any data-mce-bogus="all" marked elements since these are used for UI it will also
@@ -14135,7 +14199,7 @@ define("tinymce/dom/Serializer", [
14135
14199
  var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
14136
14200
  var endTagIndex, index, matchLength, matches, shortEndedElements, schema = editor.schema;
14137
14201
 
14138
- content = Zwsp.trim(content.replace(trimContentRegExp, ''));
14202
+ content = trimHtml(content);
14139
14203
  shortEndedElements = schema.getShortEndedElements();
14140
14204
 
14141
14205
  // Remove all bogus elements marked with "all"
@@ -14156,6 +14220,20 @@ define("tinymce/dom/Serializer", [
14156
14220
  return trim(content);
14157
14221
  }
14158
14222
 
14223
+ function addTempAttr(name) {
14224
+ if (Tools.inArray(tempAttrs, name) === -1) {
14225
+ htmlParser.addAttributeFilter(name, function(nodes, name) {
14226
+ var i = nodes.length;
14227
+
14228
+ while (i--) {
14229
+ nodes[i].attr(name, null);
14230
+ }
14231
+ });
14232
+
14233
+ tempAttrs.push(name);
14234
+ }
14235
+ }
14236
+
14159
14237
  // Default DOM and Schema if they are undefined
14160
14238
  dom = dom || DOM;
14161
14239
  schema = schema || new Schema(settings);
@@ -14512,6 +14590,17 @@ define("tinymce/dom/Serializer", [
14512
14590
  }
14513
14591
  },
14514
14592
 
14593
+ /**
14594
+ * Adds a temporary internal attribute these attributes will get removed on undo and
14595
+ * when getting contents out of the editor.
14596
+ *
14597
+ * @method addTempAttr
14598
+ * @param {String} name string
14599
+ */
14600
+ addTempAttr: addTempAttr,
14601
+
14602
+ // Internal
14603
+ trimHtml: trimHtml,
14515
14604
  getTrimmedContent: getTrimmedContent
14516
14605
  };
14517
14606
  };
@@ -15130,7 +15219,7 @@ define("tinymce/dom/ControlSelection", [
15130
15219
  rootClass + ' .mce-resizehandle:hover {' +
15131
15220
  'background: #000' +
15132
15221
  '}' +
15133
- rootClass + ' *[data-mce-selected] {' +
15222
+ rootClass + ' img[data-mce-selected],' + rootClass + ' hr[data-mce-selected] {' +
15134
15223
  'outline: 1px solid black;' +
15135
15224
  'resize: none' + // Have been talks about implementing this in browsers
15136
15225
  '}' +
@@ -15663,11 +15752,16 @@ define("tinymce/dom/ControlSelection", [
15663
15752
 
15664
15753
  var throttledUpdateResizeRect = Delay.throttle(updateResizeRect);
15665
15754
 
15666
- editor.on('nodechange ResizeEditor ResizeWindow drop', throttledUpdateResizeRect);
15755
+ editor.on('nodechange ResizeEditor ResizeWindow drop', function(e) {
15756
+ if (!editor.composing) {
15757
+ throttledUpdateResizeRect(e);
15758
+ }
15759
+ });
15667
15760
 
15668
15761
  // Update resize rect while typing in a table
15669
- editor.on('keydown keyup', function(e) {
15670
- if (selectedElm && selectedElm.nodeName == "TABLE") {
15762
+ editor.on('keydown keyup compositionend', function(e) {
15763
+ // Don't update the resize rect while composing since it blows away the IME see: #2710
15764
+ if (selectedElm && selectedElm.nodeName == "TABLE" && !editor.composing) {
15671
15765
  throttledUpdateResizeRect(e);
15672
15766
  }
15673
15767
  });
@@ -15996,6 +16090,15 @@ define("tinymce/geom/ClientRect", [], function() {
15996
16090
  return 0;
15997
16091
  }
15998
16092
 
16093
+ function containsXY(clientRect, clientX, clientY) {
16094
+ return (
16095
+ clientX >= clientRect.left &&
16096
+ clientX <= clientRect.right &&
16097
+ clientY >= clientRect.top &&
16098
+ clientY <= clientRect.bottom
16099
+ );
16100
+ }
16101
+
15999
16102
  return {
16000
16103
  clone: clone,
16001
16104
  collapse: collapse,
@@ -16004,7 +16107,8 @@ define("tinymce/geom/ClientRect", [], function() {
16004
16107
  isBelow: isBelow,
16005
16108
  isLeft: isLeft,
16006
16109
  isRight: isRight,
16007
- compare: compare
16110
+ compare: compare,
16111
+ containsXY: containsXY
16008
16112
  };
16009
16113
  });
16010
16114
 
@@ -18449,6 +18553,75 @@ define("tinymce/fmt/Preview", [
18449
18553
  };
18450
18554
  });
18451
18555
 
18556
+ // Included from: js/tinymce/classes/fmt/Hooks.js
18557
+
18558
+ /**
18559
+ * Hooks.js
18560
+ *
18561
+ * Released under LGPL License.
18562
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
18563
+ *
18564
+ * License: http://www.tinymce.com/license
18565
+ * Contributing: http://www.tinymce.com/contributing
18566
+ */
18567
+
18568
+ /**
18569
+ * Internal class for overriding formatting.
18570
+ *
18571
+ * @private
18572
+ * @class tinymce.fmt.Hooks
18573
+ */
18574
+ define("tinymce/fmt/Hooks", [
18575
+ "tinymce/util/Arr",
18576
+ "tinymce/dom/NodeType",
18577
+ "tinymce/dom/DomQuery"
18578
+ ], function(Arr, NodeType, $) {
18579
+ var postProcessHooks = [], filter = Arr.filter, each = Arr.each;
18580
+
18581
+ function addPostProcessHook(name, hook) {
18582
+ var hooks = postProcessHooks[name];
18583
+
18584
+ if (!hooks) {
18585
+ postProcessHooks[name] = hooks = [];
18586
+ }
18587
+
18588
+ postProcessHooks[name].push(hook);
18589
+ }
18590
+
18591
+ function postProcess(name, editor) {
18592
+ each(postProcessHooks[name], function(hook) {
18593
+ hook(editor);
18594
+ });
18595
+ }
18596
+
18597
+ addPostProcessHook("pre", function(editor) {
18598
+ var rng = editor.selection.getRng(), isPre, blocks;
18599
+
18600
+ function hasPreSibling(pre) {
18601
+ return isPre(pre.previousSibling) && Arr.indexOf(blocks, pre.previousSibling) != -1;
18602
+ }
18603
+
18604
+ function joinPre(pre1, pre2) {
18605
+ $(pre2).remove();
18606
+ $(pre1).append('<br><br>').append(pre2.childNodes);
18607
+ }
18608
+
18609
+ isPre = NodeType.matchNodeNames('pre');
18610
+
18611
+ if (!rng.collapsed) {
18612
+ blocks = editor.selection.getSelectedBlocks();
18613
+
18614
+ each(filter(filter(blocks, isPre), hasPreSibling), function(pre) {
18615
+ joinPre(pre.previousSibling, pre);
18616
+ });
18617
+ }
18618
+ });
18619
+
18620
+ return {
18621
+ postProcess: postProcess
18622
+ };
18623
+ });
18624
+
18452
18625
  // Included from: js/tinymce/classes/Formatter.js
18453
18626
 
18454
18627
  /**
@@ -18481,8 +18654,9 @@ define("tinymce/Formatter", [
18481
18654
  "tinymce/dom/BookmarkManager",
18482
18655
  "tinymce/dom/ElementUtils",
18483
18656
  "tinymce/util/Tools",
18484
- "tinymce/fmt/Preview"
18485
- ], function(TreeWalker, RangeUtils, BookmarkManager, ElementUtils, Tools, Preview) {
18657
+ "tinymce/fmt/Preview",
18658
+ "tinymce/fmt/Hooks"
18659
+ ], function(TreeWalker, RangeUtils, BookmarkManager, ElementUtils, Tools, Preview, Hooks) {
18486
18660
  /**
18487
18661
  * Constructs a new formatter instance.
18488
18662
  *
@@ -19082,7 +19256,7 @@ define("tinymce/Formatter", [
19082
19256
  applyRngStyle(node, null, true);
19083
19257
  }
19084
19258
  } else {
19085
- if (!isCollapsed || !format.inline || dom.select('td.mce-item-selected,th.mce-item-selected').length) {
19259
+ if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
19086
19260
  // Obtain selection node before selection is unselected by applyRngStyle()
19087
19261
  var curSelNode = ed.selection.getNode();
19088
19262
 
@@ -19111,6 +19285,8 @@ define("tinymce/Formatter", [
19111
19285
  performCaretAction('apply', name, vars);
19112
19286
  }
19113
19287
  }
19288
+
19289
+ Hooks.postProcess(name, ed);
19114
19290
  }
19115
19291
  }
19116
19292
 
@@ -19360,7 +19536,7 @@ define("tinymce/Formatter", [
19360
19536
  return;
19361
19537
  }
19362
19538
 
19363
- if (!selection.isCollapsed() || !format.inline || dom.select('td.mce-item-selected,th.mce-item-selected').length) {
19539
+ if (!selection.isCollapsed() || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) {
19364
19540
  bookmark = selection.getBookmark();
19365
19541
  removeRngStyle(selection.getRng(TRUE));
19366
19542
  selection.moveToBookmark(bookmark);
@@ -22523,6 +22699,10 @@ define("tinymce/EditorCommands", [
22523
22699
  }
22524
22700
  }
22525
22701
 
22702
+ function canHaveChildren(node) {
22703
+ return node && !editor.schema.getShortEndedElements()[node.nodeName];
22704
+ }
22705
+
22526
22706
  function moveSelectionToMarker(marker) {
22527
22707
  var parentEditableFalseElm;
22528
22708
 
@@ -22615,7 +22795,7 @@ define("tinymce/EditorCommands", [
22615
22795
  var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);
22616
22796
  var body = editor.getBody();
22617
22797
  if (caretElement === body && selection.isCollapsed()) {
22618
- if (dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) {
22798
+ if (dom.isBlock(body.firstChild) && canHaveChildren(body.firstChild) && dom.isEmpty(body.firstChild)) {
22619
22799
  rng = dom.createRng();
22620
22800
  rng.setStart(body.firstChild, 0);
22621
22801
  rng.setEnd(body.firstChild, 0);
@@ -23529,8 +23709,6 @@ define("tinymce/util/Class", [
23529
23709
  // Add mixins
23530
23710
  if (prop.Mixins) {
23531
23711
  each(prop.Mixins, function(mixin) {
23532
- mixin = mixin;
23533
-
23534
23712
  for (var name in mixin) {
23535
23713
  if (name !== "init") {
23536
23714
  prop[name] = mixin[name];
@@ -24392,7 +24570,7 @@ define("tinymce/ui/Selector", [
24392
24570
  return uniqueItems;
24393
24571
  }
24394
24572
 
24395
- var expression = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i;
24573
+ var expression = /^([\w\\*]+)?(?:#([\w\-\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i;
24396
24574
 
24397
24575
  /*jshint maxlen:255 */
24398
24576
  /*eslint max-len:0 */
@@ -26011,6 +26189,20 @@ define("tinymce/ui/Control", [
26011
26189
  self.fire('repaint', {}, false);
26012
26190
  },
26013
26191
 
26192
+ /**
26193
+ * Updates the controls layout rect by re-measuing it.
26194
+ */
26195
+ updateLayoutRect: function() {
26196
+ var self = this;
26197
+
26198
+ self.parent()._lastRect = null;
26199
+
26200
+ DomUtils.css(self.getEl(), {width: '', height: ''});
26201
+
26202
+ self._layoutRect = self._lastRepaintRect = self._lastLayoutRect = null;
26203
+ self.initLayoutRect();
26204
+ },
26205
+
26014
26206
  /**
26015
26207
  * Binds a callback to the specified event. This event can both be
26016
26208
  * native browser events like "click" or custom ones like PostRender.
@@ -27079,7 +27271,7 @@ define("tinymce/ui/KeyboardNavigation", [
27079
27271
 
27080
27272
  // Notice: since type can be "email" etc we don't check the type
27081
27273
  // So all input elements gets treated as text input elements
27082
- return tagName == "INPUT" || tagName == "TEXTAREA";
27274
+ return tagName == "INPUT" || tagName == "TEXTAREA" || tagName == "SELECT";
27083
27275
  }
27084
27276
 
27085
27277
  /**
@@ -28709,7 +28901,7 @@ define("tinymce/ui/FloatPanel", [
28709
28901
  }
28710
28902
  }
28711
28903
 
28712
- var modalBlockEl = document.getElementById(ctrl.classPrefix + 'modal-block');
28904
+ var modalBlockEl = $('#' + ctrl.classPrefix + 'modal-block', ctrl.getContainerElm())[0];
28713
28905
 
28714
28906
  if (topModal) {
28715
28907
  $(modalBlockEl).css('z-index', topModal.zIndex - 1);
@@ -28759,7 +28951,7 @@ define("tinymce/ui/FloatPanel", [
28759
28951
  var $modalBlockEl, prefix = self.classPrefix;
28760
28952
 
28761
28953
  if (self.modal && !hasModal) {
28762
- $modalBlockEl = $('#' + prefix + 'modal-block');
28954
+ $modalBlockEl = $('#' + prefix + 'modal-block', self.getContainerElm());
28763
28955
  if (!$modalBlockEl[0]) {
28764
28956
  $modalBlockEl = $(
28765
28957
  '<div id="' + prefix + 'modal-block" class="' + prefix + 'reset ' + prefix + 'fade"></div>'
@@ -29098,7 +29290,9 @@ define("tinymce/ui/Window", [
29098
29290
  }
29099
29291
 
29100
29292
  self.on('click', function(e) {
29101
- if (e.target.className.indexOf(self.classPrefix + 'close') != -1) {
29293
+ var closeClass = self.classPrefix + 'close';
29294
+
29295
+ if (e.target.className.indexOf(closeClass) != -1 || e.target.parentNode.className.indexOf(closeClass) != -1) {
29102
29296
  self.close();
29103
29297
  }
29104
29298
  });
@@ -29216,8 +29410,10 @@ define("tinymce/ui/Window", [
29216
29410
  headerHtml = (
29217
29411
  '<div id="' + id + '-head" class="' + prefix + 'window-head">' +
29218
29412
  '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' +
29219
- '<button type="button" class="' + prefix + 'close" aria-hidden="true">\u00d7</button>' +
29220
29413
  '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' +
29414
+ '<button type="button" class="' + prefix + 'close" aria-hidden="true">' +
29415
+ '<i class="mce-ico mce-i-remove"></i>' +
29416
+ '</button>' +
29221
29417
  '</div>'
29222
29418
  );
29223
29419
  }
@@ -29667,6 +29863,18 @@ define("tinymce/WindowManager", [
29667
29863
  }
29668
29864
  }
29669
29865
 
29866
+ function fireOpenEvent(win) {
29867
+ editor.fire('OpenWindow', {
29868
+ win: win
29869
+ });
29870
+ }
29871
+
29872
+ function fireCloseEvent(win) {
29873
+ editor.fire('CloseWindow', {
29874
+ win: win
29875
+ });
29876
+ }
29877
+
29670
29878
  self.windows = windows;
29671
29879
 
29672
29880
  editor.on('remove', function() {
@@ -29709,7 +29917,9 @@ define("tinymce/WindowManager", [
29709
29917
  args.items = {
29710
29918
  defaults: args.defaults,
29711
29919
  type: args.bodyType || 'form',
29712
- items: args.body
29920
+ items: args.body,
29921
+ data: args.data,
29922
+ callbacks: args.commands
29713
29923
  };
29714
29924
  }
29715
29925
 
@@ -29740,6 +29950,8 @@ define("tinymce/WindowManager", [
29740
29950
  if (!windows.length) {
29741
29951
  editor.focus();
29742
29952
  }
29953
+
29954
+ fireCloseEvent(win);
29743
29955
  });
29744
29956
 
29745
29957
  // Handle data
@@ -29764,7 +29976,11 @@ define("tinymce/WindowManager", [
29764
29976
  editor.nodeChanged();
29765
29977
  }
29766
29978
 
29767
- return win.renderTo().reflow();
29979
+ win = win.renderTo().reflow();
29980
+
29981
+ fireOpenEvent(win);
29982
+
29983
+ return win;
29768
29984
  };
29769
29985
 
29770
29986
  /**
@@ -29780,13 +29996,21 @@ define("tinymce/WindowManager", [
29780
29996
  * tinymce.activeEditor.windowManager.alert('Hello world!');
29781
29997
  */
29782
29998
  self.alert = function(message, callback, scope) {
29783
- MessageBox.alert(message, function() {
29999
+ var win;
30000
+
30001
+ win = MessageBox.alert(message, function() {
29784
30002
  if (callback) {
29785
30003
  callback.call(scope || this);
29786
30004
  } else {
29787
30005
  editor.focus();
29788
30006
  }
29789
30007
  });
30008
+
30009
+ win.on('close', function() {
30010
+ fireCloseEvent(win);
30011
+ });
30012
+
30013
+ fireOpenEvent(win);
29790
30014
  };
29791
30015
 
29792
30016
  /**
@@ -29807,9 +30031,17 @@ define("tinymce/WindowManager", [
29807
30031
  * });
29808
30032
  */
29809
30033
  self.confirm = function(message, callback, scope) {
29810
- MessageBox.confirm(message, function(state) {
30034
+ var win;
30035
+
30036
+ win = MessageBox.confirm(message, function(state) {
29811
30037
  callback.call(scope || this, state);
29812
30038
  });
30039
+
30040
+ win.on('close', function() {
30041
+ fireCloseEvent(win);
30042
+ });
30043
+
30044
+ fireOpenEvent(win);
29813
30045
  };
29814
30046
 
29815
30047
  /**
@@ -30198,8 +30430,9 @@ define("tinymce/ui/Progress", [
30198
30430
  define("tinymce/ui/Notification", [
30199
30431
  "tinymce/ui/Control",
30200
30432
  "tinymce/ui/Movable",
30201
- "tinymce/ui/Progress"
30202
- ], function(Control, Movable, Progress) {
30433
+ "tinymce/ui/Progress",
30434
+ "tinymce/util/Delay"
30435
+ ], function(Control, Movable, Progress, Delay) {
30203
30436
  return Control.extend({
30204
30437
  Mixins: [Movable],
30205
30438
 
@@ -30281,6 +30514,16 @@ define("tinymce/ui/Notification", [
30281
30514
  );
30282
30515
  },
30283
30516
 
30517
+ postRender: function() {
30518
+ var self = this;
30519
+
30520
+ Delay.setTimeout(function() {
30521
+ self.$el.addClass(self.classPrefix + 'in');
30522
+ });
30523
+
30524
+ return self._super();
30525
+ },
30526
+
30284
30527
  bindStates: function() {
30285
30528
  var self = this;
30286
30529
 
@@ -30463,6 +30706,19 @@ define("tinymce/NotificationManager", [
30463
30706
  return notifications;
30464
30707
  };
30465
30708
 
30709
+ editor.on('SkinLoaded', function() {
30710
+ var serviceMessage = editor.settings.service_message;
30711
+
30712
+ if (serviceMessage) {
30713
+ editor.notificationManager.open({
30714
+ text: serviceMessage,
30715
+ type: 'warning',
30716
+ timeout: 0,
30717
+ icon: ''
30718
+ });
30719
+ }
30720
+ });
30721
+
30466
30722
  //self.positionNotifications = positionNotifications;
30467
30723
  };
30468
30724
  });
@@ -30737,7 +30993,7 @@ define("tinymce/util/Quirks", [
30737
30993
  return false;
30738
30994
  }
30739
30995
 
30740
- for (node = node; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
30996
+ for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
30741
30997
  if (node.nextSibling) {
30742
30998
  return false;
30743
30999
  }
@@ -32159,7 +32415,12 @@ define("tinymce/util/Quirks", [
32159
32415
  // All browsers
32160
32416
  removeBlockQuoteOnBackSpace();
32161
32417
  emptyEditorWhenDeleting();
32162
- normalizeSelection();
32418
+
32419
+ // Windows phone will return a range like [body, 0] on mousedown so
32420
+ // it will always normalize to the wrong location
32421
+ if (!Env.windowsPhone) {
32422
+ normalizeSelection();
32423
+ }
32163
32424
 
32164
32425
  // WebKit
32165
32426
  if (isWebKit) {
@@ -32743,6 +33004,11 @@ define("tinymce/file/Uploader", [
32743
33004
  notification.progressBar.value(percentLoaded);
32744
33005
  };
32745
33006
 
33007
+ xhr.onerror = function() {
33008
+ notification.close();
33009
+ failure("Image upload failed due to a XHR Transport error. Code: " + xhr.status);
33010
+ };
33011
+
32746
33012
  xhr.onload = function() {
32747
33013
  var json;
32748
33014
 
@@ -32803,20 +33069,29 @@ define("tinymce/file/Uploader", [
32803
33069
  return new Promise(function(resolve) {
32804
33070
  var handler = settings.handler;
32805
33071
 
32806
- handler(blobInfoToData(blobInfo), function(url) {
32807
- resolve({
32808
- url: url,
32809
- blobInfo: blobInfo,
32810
- status: true
32811
- });
32812
- }, function(failure) {
33072
+ try {
33073
+ handler(blobInfoToData(blobInfo), function(url) {
33074
+ resolve({
33075
+ url: url,
33076
+ blobInfo: blobInfo,
33077
+ status: true
33078
+ });
33079
+ }, function(failure) {
33080
+ resolve({
33081
+ url: '',
33082
+ blobInfo: blobInfo,
33083
+ status: false,
33084
+ error: failure
33085
+ });
33086
+ }, openNotification);
33087
+ } catch (ex) {
32813
33088
  resolve({
32814
33089
  url: '',
32815
33090
  blobInfo: blobInfo,
32816
33091
  status: false,
32817
- error: failure
33092
+ error: ex.message
32818
33093
  });
32819
- }, openNotification);
33094
+ }
32820
33095
  });
32821
33096
  }
32822
33097
 
@@ -33268,12 +33543,14 @@ define("tinymce/EditorUpload", [
33268
33543
  result = Arr.map(result, function(uploadInfo, index) {
33269
33544
  var image = imageInfos[index].image;
33270
33545
 
33271
- replaceUrlInUndoStack(image.src, uploadInfo.url);
33546
+ if (uploadInfo.status) {
33547
+ replaceUrlInUndoStack(image.src, uploadInfo.url);
33272
33548
 
33273
- editor.$(image).attr({
33274
- src: uploadInfo.url,
33275
- 'data-mce-src': editor.convertURL(uploadInfo.url, 'src')
33276
- });
33549
+ editor.$(image).attr({
33550
+ src: uploadInfo.url,
33551
+ 'data-mce-src': editor.convertURL(uploadInfo.url, 'src')
33552
+ });
33553
+ }
33277
33554
 
33278
33555
  return {
33279
33556
  element: image,
@@ -34475,11 +34752,16 @@ define("tinymce/caret/LineUtils", [
34475
34752
  * @class tinymce.DragDropOverrides
34476
34753
  */
34477
34754
  define("tinymce/DragDropOverrides", [
34478
- "tinymce/dom/NodeType"
34755
+ "tinymce/dom/NodeType",
34756
+ "tinymce/util/Arr",
34757
+ "tinymce/util/Fun"
34479
34758
  ], function(
34480
- NodeType
34759
+ NodeType,
34760
+ Arr,
34761
+ Fun
34481
34762
  ) {
34482
- var isContentEditableFalse = NodeType.isContentEditableFalse;
34763
+ var isContentEditableFalse = NodeType.isContentEditableFalse,
34764
+ isContentEditableTrue = NodeType.isContentEditableTrue;
34483
34765
 
34484
34766
  function init(editor) {
34485
34767
  var $ = editor.$, rootDocument = document,
@@ -34585,13 +34867,24 @@ define("tinymce/DragDropOverrides", [
34585
34867
  }
34586
34868
 
34587
34869
  function drop() {
34870
+ var evt;
34871
+
34588
34872
  if (state.dragging) {
34589
34873
  // Hack for IE since it doesn't sync W3C Range with IE Specific range
34590
34874
  editor.selection.setRng(editor.selection.getSel().getRangeAt(0));
34591
34875
 
34592
34876
  if (isValidDropTarget(editor.selection.getNode())) {
34877
+ var targetClone = state.element;
34878
+
34879
+ evt = editor.fire('drop', {targetClone: targetClone});
34880
+ if (evt.isDefaultPrevented()) {
34881
+ return;
34882
+ }
34883
+
34884
+ targetClone = evt.targetClone;
34885
+
34593
34886
  editor.undoManager.transact(function() {
34594
- editor.insertContent(dom.getOuterHTML(state.element));
34887
+ editor.insertContent(dom.getOuterHTML(targetClone));
34595
34888
  $(state.element).remove();
34596
34889
  });
34597
34890
  }
@@ -34601,10 +34894,19 @@ define("tinymce/DragDropOverrides", [
34601
34894
  }
34602
34895
 
34603
34896
  function start(e) {
34897
+ var ceElm, evt;
34898
+
34604
34899
  stop();
34605
34900
 
34606
- if (isDraggable(e.target)) {
34607
- if (editor.fire('dragstart', {target: e.target}).isDefaultPrevented()) {
34901
+ if (e.button !== 0) {
34902
+ return;
34903
+ }
34904
+
34905
+ ceElm = Arr.find(editor.dom.getParents(e.target), Fun.or(isContentEditableFalse, isContentEditableTrue));
34906
+
34907
+ if (isDraggable(ceElm)) {
34908
+ evt = editor.fire('dragstart', {target: ceElm});
34909
+ if (evt.isDefaultPrevented()) {
34608
34910
  return;
34609
34911
  }
34610
34912
 
@@ -34621,7 +34923,7 @@ define("tinymce/DragDropOverrides", [
34621
34923
  screenY: e.screenY,
34622
34924
  clientX: e.clientX,
34623
34925
  clientY: e.clientY,
34624
- element: e.target
34926
+ element: ceElm
34625
34927
  };
34626
34928
  }
34627
34929
  }
@@ -34676,7 +34978,7 @@ define("tinymce/DragDropOverrides", [
34676
34978
  *
34677
34979
  * @example
34678
34980
  * // Disable the default cE=false selection
34679
- * tinymce.activeEditor.on('ShowCaret ObjectSelected', function(e) {
34981
+ * tinymce.activeEditor.on('ShowCaret BeforeObjectSelected', function(e) {
34680
34982
  * e.preventDefault();
34681
34983
  * });
34682
34984
  *
@@ -34694,14 +34996,16 @@ define("tinymce/SelectionOverrides", [
34694
34996
  "tinymce/caret/LineUtils",
34695
34997
  "tinymce/dom/NodeType",
34696
34998
  "tinymce/dom/RangeUtils",
34999
+ "tinymce/geom/ClientRect",
34697
35000
  "tinymce/util/VK",
34698
35001
  "tinymce/util/Fun",
34699
35002
  "tinymce/util/Arr",
34700
35003
  "tinymce/util/Delay",
34701
- "tinymce/DragDropOverrides"
35004
+ "tinymce/DragDropOverrides",
35005
+ "tinymce/text/Zwsp"
34702
35006
  ], function(
34703
35007
  Env, CaretWalker, CaretPosition, CaretContainer, CaretUtils, FakeCaret, LineWalker,
34704
- LineUtils, NodeType, RangeUtils, VK, Fun, Arr, Delay, DragDropOverrides
35008
+ LineUtils, NodeType, RangeUtils, ClientRect, VK, Fun, Arr, Delay, DragDropOverrides, Zwsp
34705
35009
  ) {
34706
35010
  var curry = Fun.curry,
34707
35011
  isContentEditableTrue = NodeType.isContentEditableTrue,
@@ -34769,12 +35073,13 @@ define("tinymce/SelectionOverrides", [
34769
35073
  function selectNode(node) {
34770
35074
  var e;
34771
35075
 
34772
- e = editor.fire('ObjectSelected', {target: node});
35076
+ fakeCaret.hide();
35077
+
35078
+ e = editor.fire('BeforeObjectSelected', {target: node});
34773
35079
  if (e.isDefaultPrevented()) {
34774
35080
  return null;
34775
35081
  }
34776
35082
 
34777
- fakeCaret.hide();
34778
35083
  return getNodeRange(node);
34779
35084
  }
34780
35085
 
@@ -34998,7 +35303,7 @@ define("tinymce/SelectionOverrides", [
34998
35303
  }
34999
35304
 
35000
35305
  function renderCaretAtRange(range) {
35001
- var caretPosition;
35306
+ var caretPosition, ceRoot;
35002
35307
 
35003
35308
  range = CaretUtils.normalizeRange(1, rootNode, range);
35004
35309
  caretPosition = CaretPosition.fromRangeStart(range);
@@ -35011,6 +35316,12 @@ define("tinymce/SelectionOverrides", [
35011
35316
  return showCaret(1, caretPosition.getNode(true), false);
35012
35317
  }
35013
35318
 
35319
+ // TODO: Should render caret before/after depending on where you click on the page forces after now
35320
+ ceRoot = editor.dom.getParent(caretPosition.getNode(), Fun.or(isContentEditableFalse, isContentEditableTrue));
35321
+ if (isContentEditableFalse(ceRoot)) {
35322
+ return showCaret(1, ceRoot, false);
35323
+ }
35324
+
35014
35325
  fakeCaret.hide();
35015
35326
 
35016
35327
  return null;
@@ -35106,15 +35417,13 @@ define("tinymce/SelectionOverrides", [
35106
35417
  var up = curry(moveV, -1, LineWalker.upUntil);
35107
35418
  var down = curry(moveV, 1, LineWalker.downUntil);
35108
35419
 
35109
- function override(moveFn) {
35420
+ function override(evt, moveFn) {
35110
35421
  var range = moveFn(getRange());
35111
35422
 
35112
- if (range) {
35423
+ if (range && !evt.isDefaultPrevented()) {
35424
+ evt.preventDefault();
35113
35425
  setRange(range);
35114
- return true;
35115
35426
  }
35116
-
35117
- return false;
35118
35427
  }
35119
35428
 
35120
35429
  function getContentEditableRoot(node) {
@@ -35131,6 +35440,16 @@ define("tinymce/SelectionOverrides", [
35131
35440
  return null;
35132
35441
  }
35133
35442
 
35443
+ function isXYWithinRange(clientX, clientY, range) {
35444
+ if (range.collapsed) {
35445
+ return false;
35446
+ }
35447
+
35448
+ return Arr.reduce(range.getClientRects(), function(state, rect) {
35449
+ return state || ClientRect.containsXY(rect, clientX, clientY);
35450
+ }, false);
35451
+ }
35452
+
35134
35453
  // Some browsers (Chrome) lets you place the caret after a cE=false
35135
35454
  // Make sure we render the caret container in this case
35136
35455
  editor.on('mouseup', function() {
@@ -35148,9 +35467,13 @@ define("tinymce/SelectionOverrides", [
35148
35467
  if (contentEditableRoot) {
35149
35468
  if (isContentEditableFalse(contentEditableRoot)) {
35150
35469
  e.preventDefault();
35151
- setContentEditableSelection(selectNode(contentEditableRoot), false);
35470
+ setContentEditableSelection(selectNode(contentEditableRoot));
35152
35471
  } else {
35153
- editor.selection.placeCaretAt(e.clientX, e.clientY);
35472
+ clearContentEditableSelection();
35473
+
35474
+ if (!isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {
35475
+ editor.selection.placeCaretAt(e.clientX, e.clientY);
35476
+ }
35154
35477
  }
35155
35478
  } else {
35156
35479
  clearContentEditableSelection();
@@ -35166,45 +35489,41 @@ define("tinymce/SelectionOverrides", [
35166
35489
  });
35167
35490
 
35168
35491
  editor.on('keydown', function(e) {
35169
- var prevent;
35170
-
35171
35492
  if (VK.modifierPressed(e)) {
35172
35493
  return;
35173
35494
  }
35174
35495
 
35175
35496
  switch (e.keyCode) {
35176
35497
  case VK.RIGHT:
35177
- prevent = override(right);
35498
+ override(e, right);
35178
35499
  break;
35179
35500
 
35180
35501
  case VK.DOWN:
35181
- prevent = override(down);
35502
+ override(e, down);
35182
35503
  break;
35183
35504
 
35184
35505
  case VK.LEFT:
35185
- prevent = override(left);
35506
+ override(e, left);
35186
35507
  break;
35187
35508
 
35188
35509
  case VK.UP:
35189
- prevent = override(up);
35510
+ override(e, up);
35190
35511
  break;
35191
35512
 
35192
35513
  case VK.DELETE:
35193
- prevent = override(deleteForward);
35514
+ override(e, deleteForward);
35194
35515
  break;
35195
35516
 
35196
35517
  case VK.BACKSPACE:
35197
- prevent = override(backspace);
35518
+ override(e, backspace);
35198
35519
  break;
35199
35520
 
35200
35521
  default:
35201
- prevent = isContentEditableFalse(editor.selection.getNode());
35522
+ if (isContentEditableFalse(editor.selection.getNode())) {
35523
+ e.preventDefault();
35524
+ }
35202
35525
  break;
35203
35526
  }
35204
-
35205
- if (prevent) {
35206
- e.preventDefault();
35207
- }
35208
35527
  });
35209
35528
 
35210
35529
  function paddEmptyContentEditableArea() {
@@ -35298,7 +35617,7 @@ define("tinymce/SelectionOverrides", [
35298
35617
  // Make sure we have a proper fake caret on focus
35299
35618
  Delay.setEditorTimeout(editor, function() {
35300
35619
  editor.selection.setRng(renderRangeCaret(editor.selection.getRng()));
35301
- });
35620
+ }, 0);
35302
35621
  });
35303
35622
 
35304
35623
  DragDropOverrides.init(editor);
@@ -35328,9 +35647,9 @@ define("tinymce/SelectionOverrides", [
35328
35647
  return CaretContainer.isCaretContainer(rng.startContainer) || CaretContainer.isCaretContainer(rng.endContainer);
35329
35648
  }
35330
35649
 
35331
- function setContentEditableSelection(range, fireEvent) {
35650
+ function setContentEditableSelection(range) {
35332
35651
  var node, $ = editor.$, dom = editor.dom, $realSelectionContainer, sel,
35333
- startContainer, startOffset, endOffset, e, caretPosition;
35652
+ startContainer, startOffset, endOffset, e, caretPosition, targetClone, origTargetClone;
35334
35653
 
35335
35654
  if (!range) {
35336
35655
  clearContentEditableSelection();
@@ -35375,47 +35694,56 @@ define("tinymce/SelectionOverrides", [
35375
35694
  node = startContainer.childNodes[startOffset];
35376
35695
  }
35377
35696
 
35378
- if (isContentEditableFalse(node)) {
35379
- if (fireEvent !== false) {
35380
- e = editor.fire('ObjectSelected', {target: node});
35381
- if (e.isDefaultPrevented()) {
35382
- clearContentEditableSelection();
35383
- return null;
35384
- }
35385
- }
35697
+ if (!isContentEditableFalse(node)) {
35698
+ clearContentEditableSelection();
35699
+ return null;
35700
+ }
35386
35701
 
35387
- $realSelectionContainer = $('#' + realSelectionId);
35388
- if ($realSelectionContainer.length === 0) {
35389
- $realSelectionContainer = $(
35390
- '<div data-mce-bogus="all" class="mce-offscreen-selection"></div>'
35391
- ).attr('id', realSelectionId);
35702
+ targetClone = origTargetClone = node.cloneNode(true);
35703
+ e = editor.fire('ObjectSelected', {target: node, targetClone: targetClone});
35704
+ if (e.isDefaultPrevented()) {
35705
+ clearContentEditableSelection();
35706
+ return null;
35707
+ }
35392
35708
 
35393
- $realSelectionContainer.appendTo(editor.getBody());
35394
- }
35709
+ targetClone = e.targetClone;
35710
+ $realSelectionContainer = $('#' + realSelectionId);
35711
+ if ($realSelectionContainer.length === 0) {
35712
+ $realSelectionContainer = $(
35713
+ '<div data-mce-bogus="all" class="mce-offscreen-selection"></div>'
35714
+ ).attr('id', realSelectionId);
35395
35715
 
35396
- $realSelectionContainer.empty().append('\u00a0').append(node.cloneNode(true)).append('\u00a0').css({
35397
- top: dom.getPos(node, editor.getBody()).y
35398
- });
35716
+ $realSelectionContainer.appendTo(editor.getBody());
35717
+ }
35399
35718
 
35400
- range = editor.dom.createRng();
35719
+ range = editor.dom.createRng();
35720
+
35721
+ // WHY is IE making things so hard! Copy on <i contentEditable="false">x</i> produces: <em>x</em>
35722
+ if (targetClone === origTargetClone && Env.ie) {
35723
+ $realSelectionContainer.empty().append(Zwsp.ZWSP).append(targetClone).append(Zwsp.ZWSP);
35724
+ range.setStart($realSelectionContainer[0].firstChild, 0);
35725
+ range.setEnd($realSelectionContainer[0].lastChild, 1);
35726
+ } else {
35727
+ $realSelectionContainer.empty().append('\u00a0').append(targetClone).append('\u00a0');
35401
35728
  range.setStart($realSelectionContainer[0].firstChild, 1);
35402
35729
  range.setEnd($realSelectionContainer[0].lastChild, 0);
35730
+ }
35403
35731
 
35404
- editor.getBody().focus();
35405
- $realSelectionContainer[0].focus();
35406
- sel = editor.selection.getSel();
35407
- sel.removeAllRanges();
35408
- sel.addRange(range);
35732
+ $realSelectionContainer.css({
35733
+ top: dom.getPos(node, editor.getBody()).y
35734
+ });
35409
35735
 
35410
- editor.$('*[data-mce-selected]').removeAttr('data-mce-selected');
35411
- node.setAttribute('data-mce-selected', 1);
35412
- selectedContentEditableNode = node;
35736
+ editor.getBody().focus();
35737
+ $realSelectionContainer[0].focus();
35738
+ sel = editor.selection.getSel();
35739
+ sel.removeAllRanges();
35740
+ sel.addRange(range);
35413
35741
 
35414
- return range;
35415
- }
35742
+ editor.$('*[data-mce-selected]').removeAttr('data-mce-selected');
35743
+ node.setAttribute('data-mce-selected', 1);
35744
+ selectedContentEditableNode = node;
35416
35745
 
35417
- clearContentEditableSelection();
35418
- return null;
35746
+ return range;
35419
35747
  }
35420
35748
 
35421
35749
  function clearContentEditableSelection() {
@@ -35601,7 +35929,7 @@ define("tinymce/Editor", [
35601
35929
  url_converter: self.convertURL,
35602
35930
  url_converter_scope: self,
35603
35931
  ie7_compat: true
35604
- }, settings);
35932
+ }, editorManager.defaultSettings, settings);
35605
35933
 
35606
35934
  AddOnManager.language = settings.language || 'en';
35607
35935
  AddOnManager.languageLoad = settings.language_load;
@@ -36083,14 +36411,17 @@ define("tinymce/Editor", [
36083
36411
  self.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
36084
36412
 
36085
36413
  // Load the CSS by injecting them into the HTML this will reduce "flicker"
36086
- for (i = 0; i < self.contentCSS.length; i++) {
36087
- var cssUrl = self.contentCSS[i];
36088
- self.iframeHTML += (
36089
- '<link type="text/css" ' +
36090
- 'rel="stylesheet" ' +
36091
- 'href="' + Tools._addCacheSuffix(cssUrl) + '" />'
36092
- );
36093
- self.loadedCSS[cssUrl] = true;
36414
+ // However we can't do that on Chrome since # will scroll to the editor for some odd reason see #2427
36415
+ if (!/#$/.test(document.location.href)) {
36416
+ for (i = 0; i < self.contentCSS.length; i++) {
36417
+ var cssUrl = self.contentCSS[i];
36418
+ self.iframeHTML += (
36419
+ '<link type="text/css" ' +
36420
+ 'rel="stylesheet" ' +
36421
+ 'href="' + Tools._addCacheSuffix(cssUrl) + '" />'
36422
+ );
36423
+ self.loadedCSS[cssUrl] = true;
36424
+ }
36094
36425
  }
36095
36426
 
36096
36427
  bodyId = settings.body_id || 'tinymce';
@@ -36466,6 +36797,10 @@ define("tinymce/Editor", [
36466
36797
  self.nodeChanged({initial: true});
36467
36798
  self.execCallback('init_instance_callback', self);
36468
36799
 
36800
+ self.on('compositionstart compositionend', function(e) {
36801
+ self.composing = e.type === 'compositionstart';
36802
+ });
36803
+
36469
36804
  // Add editor specific CSS styles
36470
36805
  if (self.contentStyles.length > 0) {
36471
36806
  contentCssText = '';
@@ -38079,10 +38414,11 @@ define("tinymce/EditorManager", [
38079
38414
  "tinymce/util/URI",
38080
38415
  "tinymce/Env",
38081
38416
  "tinymce/util/Tools",
38417
+ "tinymce/util/Promise",
38082
38418
  "tinymce/util/Observable",
38083
38419
  "tinymce/util/I18n",
38084
38420
  "tinymce/FocusManager"
38085
- ], function(Editor, $, DOMUtils, URI, Env, Tools, Observable, I18n, FocusManager) {
38421
+ ], function(Editor, $, DOMUtils, URI, Env, Tools, Promise, Observable, I18n, FocusManager) {
38086
38422
  var DOM = DOMUtils.DOM;
38087
38423
  var explode = Tools.explode, each = Tools.each, extend = Tools.extend;
38088
38424
  var instanceCounter = 0, beforeUnloadDelegate, EditorManager, boundGlobalEvents = false;
@@ -38166,7 +38502,7 @@ define("tinymce/EditorManager", [
38166
38502
  * @property minorVersion
38167
38503
  * @type String
38168
38504
  */
38169
- minorVersion: '3.3',
38505
+ minorVersion: '3.7',
38170
38506
 
38171
38507
  /**
38172
38508
  * Release date of TinyMCE build.
@@ -38174,7 +38510,7 @@ define("tinymce/EditorManager", [
38174
38510
  * @property releaseDate
38175
38511
  * @type String
38176
38512
  */
38177
- releaseDate: '2016-01-14',
38513
+ releaseDate: '2016-03-02',
38178
38514
 
38179
38515
  /**
38180
38516
  * Collection of editor instances.
@@ -38296,24 +38632,50 @@ define("tinymce/EditorManager", [
38296
38632
  self.focusManager = new FocusManager(self);
38297
38633
  },
38298
38634
 
38635
+ /**
38636
+ * Overrides the default settings for editor instances.
38637
+ *
38638
+ * @method overrideDefaults
38639
+ * @param {Object} defaultSettings Defaults settings object.
38640
+ */
38641
+ overrideDefaults: function(defaultSettings) {
38642
+ var baseUrl, suffix;
38643
+
38644
+ baseUrl = defaultSettings.base_url;
38645
+ if (baseUrl) {
38646
+ this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, ''));
38647
+ this.baseURI = new URI(this.baseURL);
38648
+ }
38649
+
38650
+ suffix = defaultSettings.suffix;
38651
+ if (defaultSettings.suffix) {
38652
+ this.suffix = suffix;
38653
+ }
38654
+
38655
+ this.defaultSettings = defaultSettings;
38656
+ },
38657
+
38299
38658
  /**
38300
38659
  * Initializes a set of editors. This method will create editors based on various settings.
38301
38660
  *
38302
38661
  * @method init
38303
38662
  * @param {Object} settings Settings object to be passed to each editor instance.
38663
+ * @return {tinymce.util.Promise} Promise that gets resolved with an array of editors when all editor instances are initialized.
38304
38664
  * @example
38305
38665
  * // Initializes a editor using the longer method
38306
38666
  * tinymce.EditorManager.init({
38307
38667
  * some_settings : 'some value'
38308
38668
  * });
38309
38669
  *
38310
- * // Initializes a editor instance using the shorter version
38311
- * tinyMCE.init({
38670
+ * // Initializes a editor instance using the shorter version and with a promise
38671
+ * tinymce.init({
38312
38672
  * some_settings : 'some value'
38673
+ * }).then(function(editors) {
38674
+ * ...
38313
38675
  * });
38314
38676
  */
38315
38677
  init: function(settings) {
38316
- var self = this, editors = [];
38678
+ var self = this, result;
38317
38679
 
38318
38680
  function createId(elm) {
38319
38681
  var id = elm.id;
@@ -38335,16 +38697,6 @@ define("tinymce/EditorManager", [
38335
38697
  return id;
38336
38698
  }
38337
38699
 
38338
- function createEditor(id, settings, targetElm) {
38339
- if (!purgeDestroyedEditor(self.get(id))) {
38340
- var editor = new Editor(id, settings, self);
38341
-
38342
- editor.targetElm = editor.targetElm || targetElm;
38343
- editors.push(editor);
38344
- editor.render();
38345
- }
38346
- }
38347
-
38348
38700
  function execCallback(name) {
38349
38701
  var callback = settings[name];
38350
38702
 
@@ -38359,31 +38711,19 @@ define("tinymce/EditorManager", [
38359
38711
  return className.constructor === RegExp ? className.test(elm.className) : DOM.hasClass(elm, className);
38360
38712
  }
38361
38713
 
38362
- function readyHandler() {
38363
- var l, co;
38364
-
38365
- DOM.unbind(window, 'ready', readyHandler);
38366
-
38367
- execCallback('onpageload');
38714
+ function findTargets(settings) {
38715
+ var l, targets = [];
38368
38716
 
38369
38717
  if (settings.types) {
38370
- // Process type specific selector
38371
38718
  each(settings.types, function(type) {
38372
- each(DOM.select(type.selector), function(elm) {
38373
- createEditor(createId(elm), extend({}, settings, type), elm);
38374
- });
38719
+ targets = targets.concat(DOM.select(type.selector));
38375
38720
  });
38376
38721
 
38377
- return;
38722
+ return targets;
38378
38723
  } else if (settings.selector) {
38379
- // Process global selector
38380
- each(DOM.select(settings.selector), function(elm) {
38381
- createEditor(createId(elm), settings, elm);
38382
- });
38383
-
38384
- return;
38724
+ return DOM.select(settings.selector);
38385
38725
  } else if (settings.target) {
38386
- createEditor(createId(settings.target), settings);
38726
+ return [settings.target];
38387
38727
  }
38388
38728
 
38389
38729
  // Fallback to old setting
@@ -38396,14 +38736,14 @@ define("tinymce/EditorManager", [
38396
38736
  var elm;
38397
38737
 
38398
38738
  if ((elm = DOM.get(id))) {
38399
- createEditor(id, settings, elm);
38739
+ targets.push(elm);
38400
38740
  } else {
38401
38741
  each(document.forms, function(f) {
38402
38742
  each(f.elements, function(e) {
38403
38743
  if (e.name === id) {
38404
38744
  id = 'mce_editor_' + instanceCounter++;
38405
38745
  DOM.setAttrib(e, 'id', id);
38406
- createEditor(id, settings, e);
38746
+ targets.push(e);
38407
38747
  }
38408
38748
  });
38409
38749
  });
@@ -38420,44 +38760,77 @@ define("tinymce/EditorManager", [
38420
38760
  }
38421
38761
 
38422
38762
  if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
38423
- createEditor(createId(elm), settings, elm);
38763
+ targets.push(elm);
38424
38764
  }
38425
38765
  });
38426
38766
  break;
38427
38767
  }
38428
38768
 
38429
- // Call onInit when all editors are initialized
38430
- if (settings.oninit) {
38431
- l = co = 0;
38769
+ return targets;
38770
+ }
38432
38771
 
38433
- each(editors, function(ed) {
38434
- co++;
38772
+ var provideResults = function(editors) {
38773
+ result = editors;
38774
+ };
38435
38775
 
38436
- if (!ed.initialized) {
38437
- // Wait for it
38438
- ed.on('init', function() {
38439
- l++;
38776
+ function initEditors() {
38777
+ var initCount = 0, editors = [], targets;
38440
38778
 
38441
- // All done
38442
- if (l == co) {
38443
- execCallback('oninit');
38444
- }
38445
- });
38446
- } else {
38447
- l++;
38448
- }
38779
+ function createEditor(id, settings, targetElm) {
38780
+ if (!purgeDestroyedEditor(self.get(id))) {
38781
+ var editor = new Editor(id, settings, self);
38449
38782
 
38450
- // All done
38451
- if (l == co) {
38452
- execCallback('oninit');
38453
- }
38783
+ editors.push(editor);
38784
+
38785
+ editor.on('init', function() {
38786
+ if (++initCount === targets.length) {
38787
+ provideResults(editors);
38788
+ }
38789
+ });
38790
+
38791
+ editor.targetElm = editor.targetElm || targetElm;
38792
+ editor.render();
38793
+ }
38794
+ }
38795
+
38796
+ DOM.unbind(window, 'ready', initEditors);
38797
+ execCallback('onpageload');
38798
+
38799
+ targets = $.unique(findTargets(settings));
38800
+
38801
+ // TODO: Deprecate this one
38802
+ if (settings.types) {
38803
+ each(settings.types, function(type) {
38804
+ Tools.each(targets, function(elm) {
38805
+ if (DOM.is(elm, type.selector)) {
38806
+ createEditor(createId(elm), extend({}, settings, type), elm);
38807
+ return false;
38808
+ }
38809
+
38810
+ return true;
38811
+ });
38454
38812
  });
38813
+
38814
+ return;
38455
38815
  }
38816
+
38817
+ each(targets, function(elm) {
38818
+ createEditor(createId(elm), settings, elm);
38819
+ });
38456
38820
  }
38457
38821
 
38458
38822
  self.settings = settings;
38823
+ DOM.bind(window, 'ready', initEditors);
38459
38824
 
38460
- DOM.bind(window, 'ready', readyHandler);
38825
+ return new Promise(function(resolve) {
38826
+ if (result) {
38827
+ resolve(result);
38828
+ } else {
38829
+ provideResults = function(editors) {
38830
+ resolve(editors);
38831
+ };
38832
+ }
38833
+ });
38461
38834
  },
38462
38835
 
38463
38836
  /**
@@ -42991,6 +43364,102 @@ define("tinymce/ui/Iframe", [
42991
43364
  });
42992
43365
  });
42993
43366
 
43367
+ // Included from: js/tinymce/classes/ui/InfoBox.js
43368
+
43369
+ /**
43370
+ * InfoBox.js
43371
+ *
43372
+ * Released under LGPL License.
43373
+ * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
43374
+ *
43375
+ * License: http://www.tinymce.com/license
43376
+ * Contributing: http://www.tinymce.com/contributing
43377
+ */
43378
+
43379
+ /**
43380
+ * ....
43381
+ *
43382
+ * @-x-less InfoBox.less
43383
+ * @class tinymce.ui.InfoBox
43384
+ * @extends tinymce.ui.Widget
43385
+ */
43386
+ define("tinymce/ui/InfoBox", [
43387
+ "tinymce/ui/Widget"
43388
+ ], function(Widget) {
43389
+ "use strict";
43390
+
43391
+ return Widget.extend({
43392
+ /**
43393
+ * Constructs a instance with the specified settings.
43394
+ *
43395
+ * @constructor
43396
+ * @param {Object} settings Name/value object with settings.
43397
+ * @setting {Boolean} multiline Multiline label.
43398
+ */
43399
+ init: function(settings) {
43400
+ var self = this;
43401
+
43402
+ self._super(settings);
43403
+ self.classes.add('widget').add('infobox');
43404
+ self.canFocus = false;
43405
+ },
43406
+
43407
+ severity: function(level) {
43408
+ this.classes.remove('error');
43409
+ this.classes.remove('warning');
43410
+ this.classes.remove('success');
43411
+ this.classes.add(level);
43412
+ },
43413
+
43414
+ help: function(state) {
43415
+ this.state.set('help', state);
43416
+ },
43417
+
43418
+ /**
43419
+ * Renders the control as a HTML string.
43420
+ *
43421
+ * @method renderHtml
43422
+ * @return {String} HTML representing the control.
43423
+ */
43424
+ renderHtml: function() {
43425
+ var self = this, prefix = self.classPrefix;
43426
+
43427
+ return (
43428
+ '<div id="' + self._id + '" class="' + self.classes + '">' +
43429
+ '<div id="' + self._id + '-body">' +
43430
+ self.encode(self.state.get('text')) +
43431
+ '<button role="button" tabindex="-1">' +
43432
+ '<i class="' + prefix + 'ico ' + prefix + 'i-help"></i>' +
43433
+ '</button>' +
43434
+ '</div>' +
43435
+ '</div>'
43436
+ );
43437
+ },
43438
+
43439
+ bindStates: function() {
43440
+ var self = this;
43441
+
43442
+ self.state.on('change:text', function(e) {
43443
+ self.getEl('body').firstChild.data = self.encode(e.value);
43444
+
43445
+ if (self.state.get('rendered')) {
43446
+ self.updateLayoutRect();
43447
+ }
43448
+ });
43449
+
43450
+ self.state.on('change:help', function(e) {
43451
+ self.classes.toggle('has-help', e.value);
43452
+
43453
+ if (self.state.get('rendered')) {
43454
+ self.updateLayoutRect();
43455
+ }
43456
+ });
43457
+
43458
+ return self._super();
43459
+ }
43460
+ });
43461
+ });
43462
+
42994
43463
  // Included from: js/tinymce/classes/ui/Label.js
42995
43464
 
42996
43465
  /**
@@ -43083,6 +43552,13 @@ define("tinymce/ui/Label", [
43083
43552
  return self._super();
43084
43553
  },
43085
43554
 
43555
+ severity: function(level) {
43556
+ this.classes.remove('error');
43557
+ this.classes.remove('warning');
43558
+ this.classes.remove('success');
43559
+ this.classes.add(level);
43560
+ },
43561
+
43086
43562
  /**
43087
43563
  * Renders the control as a HTML string.
43088
43564
  *
@@ -43090,12 +43566,28 @@ define("tinymce/ui/Label", [
43090
43566
  * @return {String} HTML representing the control.
43091
43567
  */
43092
43568
  renderHtml: function() {
43093
- var self = this, forId = self.settings.forId;
43569
+ var self = this, targetCtrl, forName, forId = self.settings.forId;
43570
+
43571
+ if (!forId && (forName = self.settings.forName)) {
43572
+ targetCtrl = self.getRoot().find('#' + forName)[0];
43573
+
43574
+ if (targetCtrl) {
43575
+ forId = targetCtrl._id;
43576
+ }
43577
+ }
43578
+
43579
+ if (forId) {
43580
+ return (
43581
+ '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' +
43582
+ self.encode(self.state.get('text')) +
43583
+ '</label>'
43584
+ );
43585
+ }
43094
43586
 
43095
43587
  return (
43096
- '<label id="' + self._id + '" class="' + self.classes + '"' + (forId ? ' for="' + forId + '"' : '') + '>' +
43588
+ '<span id="' + self._id + '" class="' + self.classes + '">' +
43097
43589
  self.encode(self.state.get('text')) +
43098
- '</label>'
43590
+ '</span>'
43099
43591
  );
43100
43592
  },
43101
43593
 
@@ -43104,6 +43596,10 @@ define("tinymce/ui/Label", [
43104
43596
 
43105
43597
  self.state.on('change:text', function(e) {
43106
43598
  self.innerHtml(self.encode(e.value));
43599
+
43600
+ if (self.state.get('rendered')) {
43601
+ self.updateLayoutRect();
43602
+ }
43107
43603
  });
43108
43604
 
43109
43605
  return self._super();
@@ -43499,8 +43995,9 @@ define("tinymce/ui/MenuButton", [
43499
43995
  define("tinymce/ui/MenuItem", [
43500
43996
  "tinymce/ui/Widget",
43501
43997
  "tinymce/ui/Factory",
43502
- "tinymce/Env"
43503
- ], function(Widget, Factory, Env) {
43998
+ "tinymce/Env",
43999
+ "tinymce/util/Delay"
44000
+ ], function(Widget, Factory, Env, Delay) {
43504
44001
  "use strict";
43505
44002
 
43506
44003
  return Widget.extend({
@@ -43760,7 +44257,11 @@ define("tinymce/ui/MenuItem", [
43760
44257
  if (e.control === self) {
43761
44258
  if (!settings.menu && e.type === 'click') {
43762
44259
  self.fire('select');
43763
- self.parent().hideAll();
44260
+
44261
+ // Edge will crash if you stress it see #2660
44262
+ Delay.requestAnimationFrame(function() {
44263
+ self.parent().hideAll();
44264
+ });
43764
44265
  } else {
43765
44266
  self.showMenu();
43766
44267
 
@@ -43776,6 +44277,18 @@ define("tinymce/ui/MenuItem", [
43776
44277
  return self;
43777
44278
  },
43778
44279
 
44280
+ hover: function() {
44281
+ var self = this;
44282
+
44283
+ self.parent().items().each(function(ctrl) {
44284
+ ctrl.classes.remove('selected');
44285
+ });
44286
+
44287
+ self.classes.toggle('selected', true);
44288
+
44289
+ return self;
44290
+ },
44291
+
43779
44292
  active: function(state) {
43780
44293
  if (typeof state != "undefined") {
43781
44294
  this.aria('checked', state);
@@ -43799,6 +44312,97 @@ define("tinymce/ui/MenuItem", [
43799
44312
  });
43800
44313
  });
43801
44314
 
44315
+ // Included from: js/tinymce/classes/ui/Throbber.js
44316
+
44317
+ /**
44318
+ * Throbber.js
44319
+ *
44320
+ * Released under LGPL License.
44321
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
44322
+ *
44323
+ * License: http://www.tinymce.com/license
44324
+ * Contributing: http://www.tinymce.com/contributing
44325
+ */
44326
+
44327
+ /**
44328
+ * This class enables you to display a Throbber for any element.
44329
+ *
44330
+ * @-x-less Throbber.less
44331
+ * @class tinymce.ui.Throbber
44332
+ */
44333
+ define("tinymce/ui/Throbber", [
44334
+ "tinymce/dom/DomQuery",
44335
+ "tinymce/ui/Control",
44336
+ "tinymce/util/Delay"
44337
+ ], function($, Control, Delay) {
44338
+ "use strict";
44339
+
44340
+ /**
44341
+ * Constructs a new throbber.
44342
+ *
44343
+ * @constructor
44344
+ * @param {Element} elm DOM Html element to display throbber in.
44345
+ * @param {Boolean} inline Optional true/false state if the throbber should be appended to end of element for infinite scroll.
44346
+ */
44347
+ return function(elm, inline) {
44348
+ var self = this, state, classPrefix = Control.classPrefix, timer;
44349
+
44350
+ /**
44351
+ * Shows the throbber.
44352
+ *
44353
+ * @method show
44354
+ * @param {Number} [time] Time to wait before showing.
44355
+ * @param {function} [callback] Optional callback to execute when the throbber is shown.
44356
+ * @return {tinymce.ui.Throbber} Current throbber instance.
44357
+ */
44358
+ self.show = function(time, callback) {
44359
+ function render() {
44360
+ if (state) {
44361
+ $(elm).append(
44362
+ '<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>'
44363
+ );
44364
+
44365
+ if (callback) {
44366
+ callback();
44367
+ }
44368
+ }
44369
+ }
44370
+
44371
+ self.hide();
44372
+
44373
+ state = true;
44374
+
44375
+ if (time) {
44376
+ timer = Delay.setTimeout(render, time);
44377
+ } else {
44378
+ render();
44379
+ }
44380
+
44381
+ return self;
44382
+ };
44383
+
44384
+ /**
44385
+ * Hides the throbber.
44386
+ *
44387
+ * @method hide
44388
+ * @return {tinymce.ui.Throbber} Current throbber instance.
44389
+ */
44390
+ self.hide = function() {
44391
+ var child = elm.lastChild;
44392
+
44393
+ Delay.clearTimeout(timer);
44394
+
44395
+ if (child && child.className.indexOf('throbber') != -1) {
44396
+ child.parentNode.removeChild(child);
44397
+ }
44398
+
44399
+ state = false;
44400
+
44401
+ return self;
44402
+ };
44403
+ };
44404
+ });
44405
+
43802
44406
  // Included from: js/tinymce/classes/ui/Menu.js
43803
44407
 
43804
44408
  /**
@@ -43821,8 +44425,9 @@ define("tinymce/ui/MenuItem", [
43821
44425
  define("tinymce/ui/Menu", [
43822
44426
  "tinymce/ui/FloatPanel",
43823
44427
  "tinymce/ui/MenuItem",
44428
+ "tinymce/ui/Throbber",
43824
44429
  "tinymce/util/Tools"
43825
- ], function(FloatPanel, MenuItem, Tools) {
44430
+ ], function(FloatPanel, MenuItem, Throbber, Tools) {
43826
44431
  "use strict";
43827
44432
 
43828
44433
  return FloatPanel.extend({
@@ -43847,6 +44452,11 @@ define("tinymce/ui/Menu", [
43847
44452
  settings.autohide = true;
43848
44453
  settings.constrainToViewport = true;
43849
44454
 
44455
+ if (typeof settings.items === 'function') {
44456
+ settings.itemsFactory = settings.items;
44457
+ settings.items = [];
44458
+ }
44459
+
43850
44460
  if (settings.itemDefaults) {
43851
44461
  var items = settings.items, i = items.length;
43852
44462
 
@@ -43887,6 +44497,67 @@ define("tinymce/ui/Menu", [
43887
44497
  self.fire('select');
43888
44498
  },
43889
44499
 
44500
+ /**
44501
+ * Loads new items from the factory items function.
44502
+ *
44503
+ * @method load
44504
+ */
44505
+ load: function() {
44506
+ var self = this, time, factory;
44507
+
44508
+ function hideThrobber() {
44509
+ if (self.throbber) {
44510
+ self.throbber.hide();
44511
+ self.throbber = null;
44512
+ }
44513
+ }
44514
+
44515
+ factory = self.settings.itemsFactory;
44516
+ if (!factory) {
44517
+ return;
44518
+ }
44519
+
44520
+ if (!self.throbber) {
44521
+ self.throbber = new Throbber(self.getEl('body'), true);
44522
+
44523
+ if (self.items().length === 0) {
44524
+ self.throbber.show();
44525
+ self.fire('loading');
44526
+ } else {
44527
+ self.throbber.show(100, function() {
44528
+ self.items().remove();
44529
+ self.fire('loading');
44530
+ });
44531
+ }
44532
+
44533
+ self.on('hide close', hideThrobber);
44534
+ }
44535
+
44536
+ self.requestTime = time = new Date().getTime();
44537
+
44538
+ self.settings.itemsFactory(function(items) {
44539
+ if (items.length === 0) {
44540
+ self.hide();
44541
+ return;
44542
+ }
44543
+
44544
+ if (self.requestTime !== time) {
44545
+ return;
44546
+ }
44547
+
44548
+ self.getEl().style.width = '';
44549
+ self.getEl('body').style.width = '';
44550
+
44551
+ hideThrobber();
44552
+ self.items().remove();
44553
+ self.getEl('body').innerHTML = '';
44554
+
44555
+ self.add(items);
44556
+ self.renderNew();
44557
+ self.fire('loaded');
44558
+ });
44559
+ },
44560
+
43890
44561
  /**
43891
44562
  * Hide menu and all sub menus.
43892
44563
  *
@@ -43917,6 +44588,14 @@ define("tinymce/ui/Menu", [
43917
44588
  }
43918
44589
  });
43919
44590
 
44591
+ if (self.settings.itemsFactory) {
44592
+ self.on('postrender', function() {
44593
+ if (self.settings.itemsFactory) {
44594
+ self.load();
44595
+ }
44596
+ });
44597
+ }
44598
+
43920
44599
  return self._super();
43921
44600
  }
43922
44601
  });
@@ -44251,15 +44930,31 @@ define("tinymce/ui/SelectBox", [
44251
44930
  self._super(settings);
44252
44931
 
44253
44932
  if (self.settings.size) {
44254
-
44255
44933
  self.size = self.settings.size;
44256
-
44257
44934
  }
44258
44935
 
44259
44936
  if (self.settings.options) {
44260
44937
  self._options = self.settings.options;
44261
44938
  }
44262
44939
 
44940
+ self.on('keydown', function(e) {
44941
+ var rootControl;
44942
+
44943
+ if (e.keyCode == 13) {
44944
+ e.preventDefault();
44945
+
44946
+ // Find root control that we can do toJSON on
44947
+ self.parents().reverse().each(function(ctrl) {
44948
+ if (ctrl.toJSON) {
44949
+ rootControl = ctrl;
44950
+ return false;
44951
+ }
44952
+ });
44953
+
44954
+ // Fire event on current text box with the serialized data of the whole form
44955
+ self.fire('submit', {data: rootControl.toJSON()});
44956
+ }
44957
+ });
44263
44958
  },
44264
44959
 
44265
44960
  /**
@@ -45091,10 +45786,10 @@ define("tinymce/ui/TextBox", [
45091
45786
  });
45092
45787
  });
45093
45788
 
45094
- // Included from: js/tinymce/classes/ui/Throbber.js
45789
+ // Included from: js/tinymce/classes/Register.js
45095
45790
 
45096
45791
  /**
45097
- * Throbber.js
45792
+ * Register.js
45098
45793
  *
45099
45794
  * Released under LGPL License.
45100
45795
  * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
@@ -45104,75 +45799,29 @@ define("tinymce/ui/TextBox", [
45104
45799
  */
45105
45800
 
45106
45801
  /**
45107
- * This class enables you to display a Throbber for any element.
45802
+ * This registers tinymce in common module loaders.
45108
45803
  *
45109
- * @-x-less Throbber.less
45110
- * @class tinymce.ui.Throbber
45804
+ * @private
45805
+ * @class tinymce.Register
45111
45806
  */
45112
- define("tinymce/ui/Throbber", [
45113
- "tinymce/dom/DomQuery",
45114
- "tinymce/ui/Control",
45115
- "tinymce/util/Delay"
45116
- ], function($, Control, Delay) {
45117
- "use strict";
45118
-
45119
- /**
45120
- * Constructs a new throbber.
45121
- *
45122
- * @constructor
45123
- * @param {Element} elm DOM Html element to display throbber in.
45124
- * @param {Boolean} inline Optional true/false state if the throbber should be appended to end of element for infinite scroll.
45125
- */
45126
- return function(elm, inline) {
45127
- var self = this, state, classPrefix = Control.classPrefix;
45128
-
45129
- /**
45130
- * Shows the throbber.
45131
- *
45132
- * @method show
45133
- * @param {Number} [time] Time to wait before showing.
45134
- * @param {function} [callback] Optional callback to execute when the throbber is shown.
45135
- * @return {tinymce.ui.Throbber} Current throbber instance.
45136
- */
45137
- self.show = function(time, callback) {
45138
- self.hide();
45139
-
45140
- state = true;
45141
-
45142
- Delay.setTimeout(function() {
45143
- if (state) {
45144
- $(elm).append(
45145
- '<div class="' + classPrefix + 'throbber' + (inline ? ' ' + classPrefix + 'throbber-inline' : '') + '"></div>'
45146
- );
45147
-
45148
- if (callback) {
45149
- callback();
45150
- }
45151
- }
45152
- }, time);
45153
-
45154
- return self;
45155
- };
45156
-
45157
- /**
45158
- * Hides the throbber.
45159
- *
45160
- * @method hide
45161
- * @return {tinymce.ui.Throbber} Current throbber instance.
45162
- */
45163
- self.hide = function() {
45164
- var child = elm.lastChild;
45807
+ define("tinymce/Register", [
45808
+ ], function() {
45809
+ /*eslint consistent-this: 0 */
45810
+ var context = this || window;
45165
45811
 
45166
- if (child && child.className.indexOf('throbber') != -1) {
45167
- child.parentNode.removeChild(child);
45168
- }
45812
+ var tinymce = function() {
45813
+ return context.tinymce;
45814
+ };
45169
45815
 
45170
- state = false;
45816
+ if (typeof context.define === "function") {
45817
+ // Bolt
45818
+ if (!context.define.amd) {
45819
+ context.define("ephox/tinymce", [], tinymce);
45820
+ }
45821
+ }
45171
45822
 
45172
- return self;
45173
- };
45174
- };
45823
+ return {};
45175
45824
  });
45176
45825
 
45177
- expose(["tinymce/geom/Rect","tinymce/util/Promise","tinymce/util/Delay","tinymce/dom/EventUtils","tinymce/dom/Sizzle","tinymce/Env","tinymce/util/Tools","tinymce/dom/DomQuery","tinymce/html/Styles","tinymce/dom/TreeWalker","tinymce/html/Entities","tinymce/dom/DOMUtils","tinymce/dom/ScriptLoader","tinymce/AddOnManager","tinymce/dom/RangeUtils","tinymce/html/Node","tinymce/html/Schema","tinymce/html/SaxParser","tinymce/html/DomParser","tinymce/html/Writer","tinymce/html/Serializer","tinymce/dom/Serializer","tinymce/util/VK","tinymce/dom/ControlSelection","tinymce/dom/BookmarkManager","tinymce/dom/Selection","tinymce/Formatter","tinymce/UndoManager","tinymce/EditorCommands","tinymce/util/URI","tinymce/util/Class","tinymce/util/EventDispatcher","tinymce/util/Observable","tinymce/ui/Selector","tinymce/ui/Collection","tinymce/ui/ReflowQueue","tinymce/ui/Control","tinymce/ui/Factory","tinymce/ui/KeyboardNavigation","tinymce/ui/Container","tinymce/ui/DragHelper","tinymce/ui/Scrollable","tinymce/ui/Panel","tinymce/ui/Movable","tinymce/ui/Resizable","tinymce/ui/FloatPanel","tinymce/ui/Window","tinymce/ui/MessageBox","tinymce/WindowManager","tinymce/ui/Tooltip","tinymce/ui/Widget","tinymce/ui/Progress","tinymce/ui/Notification","tinymce/NotificationManager","tinymce/EditorObservable","tinymce/Shortcuts","tinymce/Editor","tinymce/util/I18n","tinymce/FocusManager","tinymce/EditorManager","tinymce/util/XHR","tinymce/util/JSON","tinymce/util/JSONRequest","tinymce/util/JSONP","tinymce/util/LocalStorage","tinymce/Compat","tinymce/ui/Layout","tinymce/ui/AbsoluteLayout","tinymce/ui/Button","tinymce/ui/ButtonGroup","tinymce/ui/Checkbox","tinymce/ui/ComboBox","tinymce/ui/ColorBox","tinymce/ui/PanelButton","tinymce/ui/ColorButton","tinymce/util/Color","tinymce/ui/ColorPicker","tinymce/ui/Path","tinymce/ui/ElementPath","tinymce/ui/FormItem","tinymce/ui/Form","tinymce/ui/FieldSet","tinymce/ui/FilePicker","tinymce/ui/FitLayout","tinymce/ui/FlexLayout","tinymce/ui/FlowLayout","tinymce/ui/FormatControls","tinymce/ui/GridLayout","tinymce/ui/Iframe","tinymce/ui/Label","tinymce/ui/Toolbar","tinymce/ui/MenuBar","tinymce/ui/MenuButton","tinymce/ui/MenuItem","tinymce/ui/Menu","tinymce/ui/ListBox","tinymce/ui/Radio","tinymce/ui/ResizeHandle","tinymce/ui/SelectBox","tinymce/ui/Slider","tinymce/ui/Spacer","tinymce/ui/SplitButton","tinymce/ui/StackLayout","tinymce/ui/TabPanel","tinymce/ui/TextBox","tinymce/ui/Throbber"]);
45826
+ expose(["tinymce/geom/Rect","tinymce/util/Promise","tinymce/util/Delay","tinymce/dom/EventUtils","tinymce/dom/Sizzle","tinymce/Env","tinymce/util/Tools","tinymce/dom/DomQuery","tinymce/html/Styles","tinymce/dom/TreeWalker","tinymce/html/Entities","tinymce/dom/DOMUtils","tinymce/dom/ScriptLoader","tinymce/AddOnManager","tinymce/dom/RangeUtils","tinymce/html/Node","tinymce/html/Schema","tinymce/html/SaxParser","tinymce/html/DomParser","tinymce/html/Writer","tinymce/html/Serializer","tinymce/dom/Serializer","tinymce/util/VK","tinymce/dom/ControlSelection","tinymce/dom/BookmarkManager","tinymce/dom/Selection","tinymce/Formatter","tinymce/UndoManager","tinymce/EditorCommands","tinymce/util/URI","tinymce/util/Class","tinymce/util/EventDispatcher","tinymce/util/Observable","tinymce/ui/Selector","tinymce/ui/Collection","tinymce/ui/ReflowQueue","tinymce/ui/Control","tinymce/ui/Factory","tinymce/ui/KeyboardNavigation","tinymce/ui/Container","tinymce/ui/DragHelper","tinymce/ui/Scrollable","tinymce/ui/Panel","tinymce/ui/Movable","tinymce/ui/Resizable","tinymce/ui/FloatPanel","tinymce/ui/Window","tinymce/ui/MessageBox","tinymce/WindowManager","tinymce/ui/Tooltip","tinymce/ui/Widget","tinymce/ui/Progress","tinymce/ui/Notification","tinymce/NotificationManager","tinymce/EditorObservable","tinymce/Shortcuts","tinymce/Editor","tinymce/util/I18n","tinymce/FocusManager","tinymce/EditorManager","tinymce/util/XHR","tinymce/util/JSON","tinymce/util/JSONRequest","tinymce/util/JSONP","tinymce/util/LocalStorage","tinymce/Compat","tinymce/ui/Layout","tinymce/ui/AbsoluteLayout","tinymce/ui/Button","tinymce/ui/ButtonGroup","tinymce/ui/Checkbox","tinymce/ui/ComboBox","tinymce/ui/ColorBox","tinymce/ui/PanelButton","tinymce/ui/ColorButton","tinymce/util/Color","tinymce/ui/ColorPicker","tinymce/ui/Path","tinymce/ui/ElementPath","tinymce/ui/FormItem","tinymce/ui/Form","tinymce/ui/FieldSet","tinymce/ui/FilePicker","tinymce/ui/FitLayout","tinymce/ui/FlexLayout","tinymce/ui/FlowLayout","tinymce/ui/FormatControls","tinymce/ui/GridLayout","tinymce/ui/Iframe","tinymce/ui/InfoBox","tinymce/ui/Label","tinymce/ui/Toolbar","tinymce/ui/MenuBar","tinymce/ui/MenuButton","tinymce/ui/MenuItem","tinymce/ui/Throbber","tinymce/ui/Menu","tinymce/ui/ListBox","tinymce/ui/Radio","tinymce/ui/ResizeHandle","tinymce/ui/SelectBox","tinymce/ui/Slider","tinymce/ui/Spacer","tinymce/ui/SplitButton","tinymce/ui/StackLayout","tinymce/ui/TabPanel","tinymce/ui/TextBox"]);
45178
45827
  })(this);