tinymce-rails 3.4.7.0.2 → 3.4.8
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.
- data/Rakefile +2 -2
- data/assets/integration/tinymce/preinit.js.erb +1 -1
- data/assets/precompiled/tinymce/jquery.tinymce.js +1 -1
- data/assets/precompiled/tinymce/plugins/advlink/js/advlink.js +8 -1
- data/assets/precompiled/tinymce/plugins/autoresize/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/autoresize/editor_plugin_src.js +20 -38
- data/assets/precompiled/tinymce/plugins/contextmenu/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/contextmenu/editor_plugin_src.js +1 -0
- data/assets/precompiled/tinymce/plugins/emotions/emotions.htm +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin_src.js +21 -0
- data/assets/precompiled/tinymce/plugins/media/js/media.js +5 -5
- data/assets/precompiled/tinymce/plugins/table/js/table.js +5 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template.js +1 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template_src.js +2 -2
- data/assets/precompiled/tinymce/tiny_mce.js +1 -1
- data/assets/precompiled/tinymce/tiny_mce_jquery.js +1 -1
- data/assets/precompiled/tinymce/tiny_mce_jquery_src.js +202 -128
- data/assets/precompiled/tinymce/tiny_mce_src.js +202 -128
- data/assets/vendor/tinymce/jquery-tinymce.js +1 -1
- data/assets/vendor/tinymce/tiny_mce.js +202 -128
- data/assets/vendor/tinymce/tiny_mce_jquery.js +202 -128
- data/lib/tinymce/railtie.rb +6 -0
- data/lib/tinymce/version.rb +1 -2
- metadata +5 -6
@@ -5,9 +5,9 @@
|
|
5
5
|
var tinymce = {
|
6
6
|
majorVersion : '3',
|
7
7
|
|
8
|
-
minorVersion : '4.
|
8
|
+
minorVersion : '4.8',
|
9
9
|
|
10
|
-
releaseDate : '
|
10
|
+
releaseDate : '2012-02-02',
|
11
11
|
|
12
12
|
_init : function() {
|
13
13
|
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
@@ -810,7 +810,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
810
810
|
// And this is also more efficient
|
811
811
|
for (i = 0; i<li.length; i++) {
|
812
812
|
c = li[i];
|
813
|
-
s = c.cb.apply(c.scope, a);
|
813
|
+
s = c.cb.apply(c.scope, a.length > 0 ? a : [c.scope]);
|
814
814
|
|
815
815
|
if (s === false)
|
816
816
|
break;
|
@@ -853,7 +853,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
853
853
|
|
854
854
|
// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
|
855
855
|
u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
|
856
|
-
u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([
|
856
|
+
u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
|
857
857
|
each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
|
858
858
|
var s = u[i];
|
859
859
|
|
@@ -1323,7 +1323,10 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1323
1323
|
TAB: 9,
|
1324
1324
|
SPACEBAR: 32,
|
1325
1325
|
UP: 38,
|
1326
|
-
DOWN: 40
|
1326
|
+
DOWN: 40,
|
1327
|
+
modifierPressed: function (e) {
|
1328
|
+
return e.shiftKey || e.ctrlKey || e.altKey;
|
1329
|
+
}
|
1327
1330
|
}
|
1328
1331
|
})(tinymce);
|
1329
1332
|
|
@@ -1337,7 +1340,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1337
1340
|
var rng, blockElm, node, clonedSpan, isDelete;
|
1338
1341
|
|
1339
1342
|
isDelete = e.keyCode == DELETE;
|
1340
|
-
if (isDelete || e.keyCode == BACKSPACE) {
|
1343
|
+
if ((isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
|
1341
1344
|
e.preventDefault();
|
1342
1345
|
rng = selection.getRng();
|
1343
1346
|
|
@@ -1454,6 +1457,26 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1454
1457
|
});
|
1455
1458
|
};
|
1456
1459
|
|
1460
|
+
function removeStylesOnPTagsInheritedFromHeadingTag(ed) {
|
1461
|
+
ed.onKeyDown.add(function(ed, event) {
|
1462
|
+
function checkInHeadingTag(ed) {
|
1463
|
+
var currentNode = ed.selection.getNode();
|
1464
|
+
var headingTags = 'h1,h2,h3,h4,h5,h6';
|
1465
|
+
return ed.dom.is(currentNode, headingTags) || ed.dom.getParent(currentNode, headingTags) !== null;
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
if (event.keyCode === VK.ENTER && !VK.modifierPressed(event) && checkInHeadingTag(ed)) {
|
1469
|
+
setTimeout(function() {
|
1470
|
+
var currentNode = ed.selection.getNode();
|
1471
|
+
if (ed.dom.is(currentNode, 'p')) {
|
1472
|
+
ed.dom.setAttrib(currentNode, 'style', null);
|
1473
|
+
// While tiny's content is correct after this method call, the content shown is not representative of it and needs to be 'repainted'
|
1474
|
+
ed.execCommand('mceCleanup');
|
1475
|
+
}
|
1476
|
+
}, 0);
|
1477
|
+
}
|
1478
|
+
});
|
1479
|
+
}
|
1457
1480
|
function selectionChangeNodeChanged(ed) {
|
1458
1481
|
var lastRng, selectionTimer;
|
1459
1482
|
|
@@ -1478,7 +1501,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1478
1501
|
function ensureBodyHasRoleApplication(ed) {
|
1479
1502
|
document.body.setAttribute("role", "application");
|
1480
1503
|
}
|
1481
|
-
|
1504
|
+
|
1482
1505
|
tinymce.create('tinymce.util.Quirks', {
|
1483
1506
|
Quirks: function(ed) {
|
1484
1507
|
// WebKit
|
@@ -1499,6 +1522,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1499
1522
|
removeHrOnBackspace(ed);
|
1500
1523
|
emptyEditorWhenDeleting(ed);
|
1501
1524
|
ensureBodyHasRoleApplication(ed);
|
1525
|
+
removeStylesOnPTagsInheritedFromHeadingTag(ed)
|
1502
1526
|
}
|
1503
1527
|
|
1504
1528
|
// Gecko
|
@@ -4171,6 +4195,7 @@ tinymce.html.Writer = function(settings) {
|
|
4171
4195
|
|
4172
4196
|
return this.run(e, function(e) {
|
4173
4197
|
var s = t.settings;
|
4198
|
+
var originalValue = e.getAttribute(n);
|
4174
4199
|
if (v !== null) {
|
4175
4200
|
switch (n) {
|
4176
4201
|
case "style":
|
@@ -4217,6 +4242,12 @@ tinymce.html.Writer = function(settings) {
|
|
4217
4242
|
e.setAttribute(n, '' + v, 2);
|
4218
4243
|
else
|
4219
4244
|
e.removeAttribute(n, 2);
|
4245
|
+
|
4246
|
+
// fire onChangeAttrib event for attributes that have changed
|
4247
|
+
if (tinyMCE.activeEditor && originalValue != v) {
|
4248
|
+
var ed = tinyMCE.activeEditor;
|
4249
|
+
ed.onSetAttrib.dispatch(ed, e, n, v);
|
4250
|
+
}
|
4220
4251
|
});
|
4221
4252
|
},
|
4222
4253
|
|
@@ -4922,6 +4953,12 @@ tinymce.html.Writer = function(settings) {
|
|
4922
4953
|
function trim(node) {
|
4923
4954
|
var i, children = node.childNodes, type = node.nodeType;
|
4924
4955
|
|
4956
|
+
function surroundedBySpans(node) {
|
4957
|
+
var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN';
|
4958
|
+
var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN';
|
4959
|
+
return previousIsSpan && nextIsSpan;
|
4960
|
+
}
|
4961
|
+
|
4925
4962
|
if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark')
|
4926
4963
|
return;
|
4927
4964
|
|
@@ -4932,7 +4969,10 @@ tinymce.html.Writer = function(settings) {
|
|
4932
4969
|
// Keep non whitespace text nodes
|
4933
4970
|
if (type == 3 && node.nodeValue.length > 0) {
|
4934
4971
|
// If parent element isn't a block or there isn't any useful contents for example "<p> </p>"
|
4935
|
-
if
|
4972
|
+
// Also keep text nodes with only spaces if surrounded by spans.
|
4973
|
+
// eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
|
4974
|
+
var trimmedLength = tinymce.trim(node.nodeValue).length;
|
4975
|
+
if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength == 0 && surroundedBySpans(node))
|
4936
4976
|
return;
|
4937
4977
|
} else if (type == 1) {
|
4938
4978
|
// If the only child is a bookmark then move it up
|
@@ -4969,9 +5009,9 @@ tinymce.html.Writer = function(settings) {
|
|
4969
5009
|
|
4970
5010
|
// Insert middle chunk
|
4971
5011
|
if (re)
|
4972
|
-
|
4973
|
-
|
4974
|
-
|
5012
|
+
pa.replaceChild(re, e);
|
5013
|
+
else
|
5014
|
+
pa.insertBefore(e, pe);
|
4975
5015
|
|
4976
5016
|
// Insert after chunk
|
4977
5017
|
pa.insertBefore(trim(aft), pe);
|
@@ -7201,7 +7241,8 @@ tinymce.html.Writer = function(settings) {
|
|
7201
7241
|
}
|
7202
7242
|
|
7203
7243
|
s.addRange(r);
|
7204
|
-
t
|
7244
|
+
// adding range isn't always successful so we need to check range count otherwise an exception can occur
|
7245
|
+
t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;
|
7205
7246
|
}
|
7206
7247
|
} else {
|
7207
7248
|
// Is W3C Range
|
@@ -7313,6 +7354,11 @@ tinymce.html.Writer = function(settings) {
|
|
7313
7354
|
normalize : function() {
|
7314
7355
|
var self = this, rng, normalized;
|
7315
7356
|
|
7357
|
+
// TODO:
|
7358
|
+
// Retain selection direction.
|
7359
|
+
// Lean left/right on Gecko for inline elements.
|
7360
|
+
// Run this on mouse up/key up when the user manually moves the selection
|
7361
|
+
|
7316
7362
|
// Normalize only on non IE browsers for now
|
7317
7363
|
if (tinymce.isIE)
|
7318
7364
|
return;
|
@@ -7347,18 +7393,24 @@ tinymce.html.Writer = function(settings) {
|
|
7347
7393
|
if (node.nodeType === 3) {
|
7348
7394
|
offset = start ? 0 : node.nodeValue.length - 1;
|
7349
7395
|
container = node;
|
7396
|
+
normalized = true;
|
7350
7397
|
break;
|
7351
7398
|
}
|
7352
7399
|
|
7353
|
-
// Found a BR element that we can place the caret before
|
7354
|
-
if (node.nodeName
|
7400
|
+
// Found a BR/IMG element that we can place the caret before
|
7401
|
+
if (/^(BR|IMG)$/.test(node.nodeName)) {
|
7355
7402
|
offset = dom.nodeIndex(node);
|
7356
7403
|
container = node.parentNode;
|
7404
|
+
|
7405
|
+
// Put caret after image when moving the end point
|
7406
|
+
if (node.nodeName == "IMG" && !start) {
|
7407
|
+
offset++;
|
7408
|
+
}
|
7409
|
+
|
7410
|
+
normalized = true;
|
7357
7411
|
break;
|
7358
7412
|
}
|
7359
7413
|
} while (node = (start ? walker.next() : walker.prev()));
|
7360
|
-
|
7361
|
-
normalized = true;
|
7362
7414
|
}
|
7363
7415
|
}
|
7364
7416
|
}
|
@@ -7373,7 +7425,7 @@ tinymce.html.Writer = function(settings) {
|
|
7373
7425
|
// Normalize the end points
|
7374
7426
|
normalizeEndPoint(true);
|
7375
7427
|
|
7376
|
-
if (rng.collapsed)
|
7428
|
+
if (!rng.collapsed)
|
7377
7429
|
normalizeEndPoint();
|
7378
7430
|
|
7379
7431
|
// Set the selection if it was normalized
|
@@ -7485,12 +7537,11 @@ tinymce.html.Writer = function(settings) {
|
|
7485
7537
|
if (!settings.apply_source_formatting)
|
7486
7538
|
settings.indent = false;
|
7487
7539
|
|
7488
|
-
settings.remove_trailing_brs = true;
|
7489
|
-
|
7490
7540
|
// Default DOM and Schema if they are undefined
|
7491
7541
|
dom = dom || tinymce.DOM;
|
7492
7542
|
schema = schema || new tinymce.html.Schema(settings);
|
7493
7543
|
settings.entity_encoding = settings.entity_encoding || 'named';
|
7544
|
+
settings.remove_trailing_brs = "remove_trailing_brs" in settings ? settings.remove_trailing_brs : true;
|
7494
7545
|
|
7495
7546
|
onPreProcess = new tinymce.util.Dispatcher(self);
|
7496
7547
|
|
@@ -7554,8 +7605,8 @@ tinymce.html.Writer = function(settings) {
|
|
7554
7605
|
function trim(value) {
|
7555
7606
|
return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n')
|
7556
7607
|
.replace(/^[\r\n]*|[\r\n]*$/g, '')
|
7557
|
-
.replace(/^\s*(
|
7558
|
-
.replace(/\s*(
|
7608
|
+
.replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '')
|
7609
|
+
.replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, '');
|
7559
7610
|
};
|
7560
7611
|
|
7561
7612
|
while (i--) {
|
@@ -8856,7 +8907,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
8856
8907
|
// Internal functions
|
8857
8908
|
_setupKeyboardNav : function(){
|
8858
8909
|
var contextMenu, menuItems, t=this;
|
8859
|
-
contextMenu = DOM.
|
8910
|
+
contextMenu = DOM.get('menu_' + t.id);
|
8860
8911
|
menuItems = DOM.select('a[role=option]', 'menu_' + t.id);
|
8861
8912
|
menuItems.splice(0,0,contextMenu);
|
8862
8913
|
t.keyboardNav = new tinymce.ui.KeyboardNavigation({
|
@@ -8963,10 +9014,26 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
8963
9014
|
},
|
8964
9015
|
|
8965
9016
|
postRender : function() {
|
8966
|
-
var t = this, s = t.settings;
|
9017
|
+
var t = this, s = t.settings, bookmark;
|
8967
9018
|
|
9019
|
+
// In IE a large image that occupies the entire editor area will be deselected when a button is clicked, so
|
9020
|
+
// need to keep the selection in case the selection is lost
|
9021
|
+
if (tinymce.isIE && t.editor) {
|
9022
|
+
tinymce.dom.Event.add(t.id, 'mousedown', function(e) {
|
9023
|
+
bookmark = t.editor.selection.getBookmark();
|
9024
|
+
});
|
9025
|
+
}
|
8968
9026
|
tinymce.dom.Event.add(t.id, 'click', function(e) {
|
8969
|
-
if (!t.isDisabled())
|
9027
|
+
if (!t.isDisabled()) {
|
9028
|
+
// restore the selection in case the selection is lost in IE
|
9029
|
+
if (tinymce.isIE && t.editor && bookmark) {
|
9030
|
+
tinymce.activeEditor.selection.moveToBookmark(bookmark);
|
9031
|
+
}
|
9032
|
+
return s.onclick.call(s.scope, e);
|
9033
|
+
}
|
9034
|
+
});
|
9035
|
+
tinymce.dom.Event.add(t.id, 'keyup', function(e) {
|
9036
|
+
if (!t.isDisabled() && e.keyCode==tinymce.VK.SPACEBAR)
|
8970
9037
|
return s.onclick.call(s.scope, e);
|
8971
9038
|
});
|
8972
9039
|
}
|
@@ -9673,15 +9740,21 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
9673
9740
|
}
|
9674
9741
|
|
9675
9742
|
n = DOM.add(tr, 'td');
|
9676
|
-
|
9677
|
-
role : 'option',
|
9743
|
+
var settings = {
|
9678
9744
|
href : 'javascript:;',
|
9679
9745
|
style : {
|
9680
9746
|
backgroundColor : '#' + c
|
9681
9747
|
},
|
9682
9748
|
'title': t.editor.getLang('colors.' + c, c),
|
9683
9749
|
'data-mce-color' : '#' + c
|
9684
|
-
}
|
9750
|
+
};
|
9751
|
+
|
9752
|
+
// adding a proper ARIA role = button causes JAWS to read things incorrectly on IE.
|
9753
|
+
if (!tinymce.isIE ) {
|
9754
|
+
settings['role']= 'option';
|
9755
|
+
}
|
9756
|
+
|
9757
|
+
n = DOM.add(n, 'a', settings);
|
9685
9758
|
|
9686
9759
|
if (t.editor.forcedHighContrastMode) {
|
9687
9760
|
n = DOM.add(n, 'canvas', { width: 16, height: 16, 'aria-hidden': 'true' });
|
@@ -10322,7 +10395,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10322
10395
|
Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko,
|
10323
10396
|
isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
|
10324
10397
|
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
|
10325
|
-
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
|
10398
|
+
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode, VK = tinymce.VK;
|
10326
10399
|
|
10327
10400
|
tinymce.create('tinymce.Editor', {
|
10328
10401
|
Editor : function(id, s) {
|
@@ -10346,6 +10419,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10346
10419
|
|
10347
10420
|
'onPostRender',
|
10348
10421
|
|
10422
|
+
'onLoad',
|
10423
|
+
|
10349
10424
|
'onInit',
|
10350
10425
|
|
10351
10426
|
'onRemove',
|
@@ -10408,7 +10483,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10408
10483
|
|
10409
10484
|
'onVisualAid',
|
10410
10485
|
|
10411
|
-
'onSetProgressState'
|
10486
|
+
'onSetProgressState',
|
10487
|
+
|
10488
|
+
'onSetAttrib'
|
10412
10489
|
], function(e) {
|
10413
10490
|
t[e] = new Dispatcher(t);
|
10414
10491
|
});
|
@@ -10760,7 +10837,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10760
10837
|
bc = bc[t.id] || '';
|
10761
10838
|
}
|
10762
10839
|
|
10763
|
-
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"><br></body></html>';
|
10840
|
+
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '" onload="window.parent.tinyMCE.get(\'' + t.id + '\').onLoad.dispatch();"><br></body></html>';
|
10764
10841
|
|
10765
10842
|
// Domain relaxing enabled, then set document domain
|
10766
10843
|
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
|
@@ -11228,7 +11305,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11228
11305
|
}
|
11229
11306
|
|
11230
11307
|
t._refreshContentEditable();
|
11231
|
-
selection.normalize();
|
11232
11308
|
|
11233
11309
|
// Is not content editable
|
11234
11310
|
if (!ce)
|
@@ -12000,30 +12076,32 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12000
12076
|
|
12001
12077
|
// Add block quote deletion handler
|
12002
12078
|
t.onKeyDown.add(function(ed, e) {
|
12003
|
-
|
12004
|
-
|
12079
|
+
if (e.keyCode != VK.BACKSPACE)
|
12080
|
+
return;
|
12081
|
+
|
12082
|
+
var rng = ed.selection.getRng();
|
12083
|
+
if (!rng.collapsed)
|
12005
12084
|
return;
|
12006
12085
|
|
12007
|
-
var n =
|
12008
|
-
var offset =
|
12086
|
+
var n = rng.startContainer;
|
12087
|
+
var offset = rng.startOffset;
|
12009
12088
|
|
12010
12089
|
while (n && n.nodeType && n.nodeType != 1 && n.parentNode)
|
12011
12090
|
n = n.parentNode;
|
12012
|
-
|
12091
|
+
|
12013
12092
|
// Is the cursor at the beginning of a blockquote?
|
12014
12093
|
if (n && n.parentNode && n.parentNode.tagName === 'BLOCKQUOTE' && n.parentNode.firstChild == n && offset == 0) {
|
12015
12094
|
// Remove the blockquote
|
12016
12095
|
ed.formatter.toggle('blockquote', null, n.parentNode);
|
12017
12096
|
|
12018
12097
|
// Move the caret to the beginning of n
|
12019
|
-
var rng = ed.selection.getRng();
|
12020
12098
|
rng.setStart(n, 0);
|
12021
12099
|
rng.setEnd(n, 0);
|
12022
12100
|
ed.selection.setRng(rng);
|
12023
12101
|
ed.selection.collapse(false);
|
12024
12102
|
}
|
12025
12103
|
});
|
12026
|
-
|
12104
|
+
|
12027
12105
|
|
12028
12106
|
|
12029
12107
|
// Add reset handler
|
@@ -12231,9 +12309,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12231
12309
|
if (target !== t.getBody()) {
|
12232
12310
|
t.dom.setAttrib(target, "style", null);
|
12233
12311
|
|
12234
|
-
|
12235
|
-
|
12236
|
-
|
12312
|
+
each(template, function(attr) {
|
12313
|
+
target.setAttributeNode(attr.cloneNode(true));
|
12314
|
+
});
|
12237
12315
|
}
|
12238
12316
|
};
|
12239
12317
|
}
|
@@ -12545,6 +12623,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12545
12623
|
var parser, serializer, parentNode, rootNode, fragment, args,
|
12546
12624
|
marker, nodeRect, viewPortRect, rng, node, node2, bookmarkHtml, viewportBodyElement;
|
12547
12625
|
|
12626
|
+
//selection.normalize();
|
12627
|
+
|
12548
12628
|
// Setup parser and serializer
|
12549
12629
|
parser = editor.parser;
|
12550
12630
|
serializer = new tinymce.html.Serializer({}, editor.schema);
|
@@ -12771,7 +12851,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12771
12851
|
addCommands({
|
12772
12852
|
// Override justify commands
|
12773
12853
|
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) {
|
12774
|
-
|
12854
|
+
var name = 'align' + command.substring(7);
|
12855
|
+
// Use Formatter.matchNode instead of Formatter.match so that we don't match on parent node. This fixes bug where for both left
|
12856
|
+
// and right align buttons can be active. This could occur when selected nodes have align right and the parent has align left.
|
12857
|
+
var nodes = selection.isCollapsed() ? [selection.getNode()] : selection.getSelectedBlocks();
|
12858
|
+
var matches = tinymce.map(nodes, function(node) {
|
12859
|
+
return !!formatter.matchNode(node, name);
|
12860
|
+
});
|
12861
|
+
return tinymce.inArray(matches, TRUE) !== -1;
|
12775
12862
|
},
|
12776
12863
|
|
12777
12864
|
'Bold,Italic,Underline,Strikethrough,Superscript,Subscript' : function(command) {
|
@@ -14168,30 +14255,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14168
14255
|
function apply(name, vars, node) {
|
14169
14256
|
var formatList = get(name), format = formatList[0], bookmark, rng, i, isCollapsed = selection.isCollapsed();
|
14170
14257
|
|
14171
|
-
function moveStart(rng) {
|
14172
|
-
var container = rng.startContainer,
|
14173
|
-
offset = rng.startOffset,
|
14174
|
-
walker, node;
|
14175
|
-
|
14176
|
-
// Move startContainer/startOffset in to a suitable node
|
14177
|
-
if (container.nodeType == 1 || container.nodeValue === "") {
|
14178
|
-
container = container.nodeType == 1 ? container.childNodes[offset] : container;
|
14179
|
-
|
14180
|
-
// Might fail if the offset is behind the last element in it's container
|
14181
|
-
if (container) {
|
14182
|
-
walker = new TreeWalker(container, container.parentNode);
|
14183
|
-
for (node = walker.current(); node; node = walker.next()) {
|
14184
|
-
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
14185
|
-
rng.setStart(node, 0);
|
14186
|
-
break;
|
14187
|
-
}
|
14188
|
-
}
|
14189
|
-
}
|
14190
|
-
}
|
14191
|
-
|
14192
|
-
return rng;
|
14193
|
-
};
|
14194
|
-
|
14195
14258
|
function setElementFormat(elm, fmt) {
|
14196
14259
|
fmt = fmt || format;
|
14197
14260
|
|
@@ -14542,7 +14605,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14542
14605
|
}
|
14543
14606
|
|
14544
14607
|
selection.moveToBookmark(bookmark);
|
14545
|
-
|
14608
|
+
moveStart(selection.getRng(TRUE));
|
14546
14609
|
ed.nodeChanged();
|
14547
14610
|
} else
|
14548
14611
|
performCaretAction('apply', name, vars);
|
@@ -14552,44 +14615,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14552
14615
|
|
14553
14616
|
function remove(name, vars, node) {
|
14554
14617
|
var formatList = get(name), format = formatList[0], bookmark, i, rng;
|
14555
|
-
function moveStart(rng) {
|
14556
|
-
var container = rng.startContainer,
|
14557
|
-
offset = rng.startOffset,
|
14558
|
-
walker, node, nodes, tmpNode;
|
14559
|
-
|
14560
|
-
// Convert text node into index if possible
|
14561
|
-
if (container.nodeType == 3 && offset >= container.nodeValue.length - 1) {
|
14562
|
-
container = container.parentNode;
|
14563
|
-
offset = nodeIndex(container) + 1;
|
14564
|
-
}
|
14565
|
-
|
14566
|
-
// Move startContainer/startOffset in to a suitable node
|
14567
|
-
if (container.nodeType == 1) {
|
14568
|
-
nodes = container.childNodes;
|
14569
|
-
container = nodes[Math.min(offset, nodes.length - 1)];
|
14570
|
-
walker = new TreeWalker(container);
|
14571
|
-
|
14572
|
-
// If offset is at end of the parent node walk to the next one
|
14573
|
-
if (offset > nodes.length - 1)
|
14574
|
-
walker.next();
|
14575
|
-
|
14576
|
-
for (node = walker.current(); node; node = walker.next()) {
|
14577
|
-
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
14578
|
-
// IE has a "neat" feature where it moves the start node into the closest element
|
14579
|
-
// we can avoid this by inserting an element before it and then remove it after we set the selection
|
14580
|
-
tmpNode = dom.create('a', null, INVISIBLE_CHAR);
|
14581
|
-
node.parentNode.insertBefore(tmpNode, node);
|
14582
|
-
|
14583
|
-
// Set selection and remove tmpNode
|
14584
|
-
rng.setStart(node, 0);
|
14585
|
-
selection.setRng(rng);
|
14586
|
-
dom.remove(tmpNode);
|
14587
|
-
|
14588
|
-
return;
|
14589
|
-
}
|
14590
|
-
}
|
14591
|
-
}
|
14592
|
-
};
|
14593
14618
|
|
14594
14619
|
// Merges the styles for each node
|
14595
14620
|
function process(node) {
|
@@ -15677,7 +15702,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15677
15702
|
dom.remove(node);
|
15678
15703
|
} else {
|
15679
15704
|
child = findFirstTextNode(node);
|
15680
|
-
|
15705
|
+
|
15706
|
+
if (child.nodeValue.charAt(0) === INVISIBLE_CHAR) {
|
15707
|
+
child = child.deleteData(0, 1);
|
15708
|
+
}
|
15709
|
+
|
15681
15710
|
dom.remove(node, 1);
|
15682
15711
|
}
|
15683
15712
|
|
@@ -15807,34 +15836,39 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15807
15836
|
}
|
15808
15837
|
};
|
15809
15838
|
|
15810
|
-
//
|
15811
|
-
|
15812
|
-
|
15839
|
+
// Only bind the caret events once
|
15840
|
+
if (!self._hasCaretEvents) {
|
15841
|
+
// Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements
|
15842
|
+
ed.onBeforeGetContent.addToTop(function() {
|
15843
|
+
var nodes = [], i;
|
15813
15844
|
|
15814
|
-
|
15815
|
-
|
15816
|
-
|
15817
|
-
|
15818
|
-
|
15845
|
+
if (isCaretContainerEmpty(getParentCaretContainer(selection.getStart()), nodes)) {
|
15846
|
+
// Mark children
|
15847
|
+
i = nodes.length;
|
15848
|
+
while (i--) {
|
15849
|
+
dom.setAttrib(nodes[i], 'data-mce-bogus', '1');
|
15850
|
+
}
|
15819
15851
|
}
|
15820
|
-
}
|
15821
|
-
});
|
15852
|
+
});
|
15822
15853
|
|
15823
|
-
|
15824
|
-
|
15825
|
-
|
15826
|
-
|
15854
|
+
// Remove caret container on mouse up and on key up
|
15855
|
+
tinymce.each('onMouseUp onKeyUp'.split(' '), function(name) {
|
15856
|
+
ed[name].addToTop(function() {
|
15857
|
+
removeCaretContainer();
|
15858
|
+
});
|
15827
15859
|
});
|
15828
|
-
});
|
15829
15860
|
|
15830
|
-
|
15831
|
-
|
15832
|
-
|
15861
|
+
// Remove caret container on keydown and it's a backspace, enter or left/right arrow keys
|
15862
|
+
ed.onKeyDown.addToTop(function(ed, e) {
|
15863
|
+
var keyCode = e.keyCode;
|
15833
15864
|
|
15834
|
-
|
15835
|
-
|
15836
|
-
|
15837
|
-
|
15865
|
+
if (keyCode == 8 || keyCode == 37 || keyCode == 39) {
|
15866
|
+
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
15867
|
+
}
|
15868
|
+
});
|
15869
|
+
|
15870
|
+
self._hasCaretEvents = true;
|
15871
|
+
}
|
15838
15872
|
|
15839
15873
|
// Do apply or remove caret format
|
15840
15874
|
if (type == "apply") {
|
@@ -15843,6 +15877,46 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15843
15877
|
removeCaretFormat();
|
15844
15878
|
}
|
15845
15879
|
};
|
15880
|
+
|
15881
|
+
function moveStart(rng) {
|
15882
|
+
var container = rng.startContainer,
|
15883
|
+
offset = rng.startOffset,
|
15884
|
+
walker, node, nodes, tmpNode;
|
15885
|
+
|
15886
|
+
// Convert text node into index if possible
|
15887
|
+
if (container.nodeType == 3 && offset >= container.nodeValue.length - 1) {
|
15888
|
+
container = container.parentNode;
|
15889
|
+
offset = nodeIndex(container) + 1;
|
15890
|
+
}
|
15891
|
+
|
15892
|
+
// Move startContainer/startOffset in to a suitable node
|
15893
|
+
if (container.nodeType == 1) {
|
15894
|
+
nodes = container.childNodes;
|
15895
|
+
container = nodes[Math.min(offset, nodes.length - 1)];
|
15896
|
+
walker = new TreeWalker(container);
|
15897
|
+
|
15898
|
+
// If offset is at end of the parent node walk to the next one
|
15899
|
+
if (offset > nodes.length - 1)
|
15900
|
+
walker.next();
|
15901
|
+
|
15902
|
+
for (node = walker.current(); node; node = walker.next()) {
|
15903
|
+
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
15904
|
+
// IE has a "neat" feature where it moves the start node into the closest element
|
15905
|
+
// we can avoid this by inserting an element before it and then remove it after we set the selection
|
15906
|
+
tmpNode = dom.create('a', null, INVISIBLE_CHAR);
|
15907
|
+
node.parentNode.insertBefore(tmpNode, node);
|
15908
|
+
|
15909
|
+
// Set selection and remove tmpNode
|
15910
|
+
rng.setStart(node, 0);
|
15911
|
+
selection.setRng(rng);
|
15912
|
+
dom.remove(tmpNode);
|
15913
|
+
|
15914
|
+
return;
|
15915
|
+
}
|
15916
|
+
}
|
15917
|
+
}
|
15918
|
+
};
|
15919
|
+
|
15846
15920
|
};
|
15847
15921
|
})(tinymce);
|
15848
15922
|
|