tinymce-rails 3.4.7.0.2 → 3.4.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|