tinymce-rails 3.4.6 → 3.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/assets/precompiled/tinymce/plugins/emotions/emotions.htm +18 -17
- data/assets/precompiled/tinymce/plugins/emotions/js/emotions.js +21 -0
- data/assets/precompiled/tinymce/plugins/emotions/langs/en_dlg.js +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin_src.js +198 -54
- data/assets/precompiled/tinymce/plugins/media/js/media.js +27 -16
- data/assets/precompiled/tinymce/plugins/media/langs/en_dlg.js +1 -1
- data/assets/precompiled/tinymce/plugins/media/moxieplayer.swf +0 -0
- data/assets/precompiled/tinymce/plugins/table/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/table/editor_plugin_src.js +90 -46
- data/assets/precompiled/tinymce/plugins/table/js/table.js +44 -10
- data/assets/precompiled/tinymce/plugins/table/table.htm +1 -1
- data/assets/precompiled/tinymce/themes/advanced/charmap.htm +5 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template.js +1 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template_src.js +6 -2
- data/assets/precompiled/tinymce/themes/advanced/js/charmap.js +11 -3
- data/assets/precompiled/tinymce/themes/advanced/js/color_picker.js +4 -4
- data/assets/precompiled/tinymce/themes/advanced/langs/en_dlg.js +1 -1
- 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 +544 -295
- data/assets/precompiled/tinymce/tiny_mce_src.js +544 -295
- data/assets/vendor/tinymce/tiny_mce.js +544 -295
- data/assets/vendor/tinymce/tiny_mce_jquery.js +544 -295
- data/lib/tinymce/railtie.rb +2 -2
- data/lib/tinymce/version.rb +2 -2
- metadata +5 -5
@@ -5,9 +5,9 @@
|
|
5
5
|
var tinymce = {
|
6
6
|
majorVersion : '3',
|
7
7
|
|
8
|
-
minorVersion : '4.
|
8
|
+
minorVersion : '4.7',
|
9
9
|
|
10
|
-
releaseDate : '2011-
|
10
|
+
releaseDate : '2011-11-03',
|
11
11
|
|
12
12
|
_init : function() {
|
13
13
|
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
@@ -1176,8 +1176,11 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
1176
1176
|
|
1177
1177
|
v = '{';
|
1178
1178
|
|
1179
|
-
for (i in o)
|
1180
|
-
|
1179
|
+
for (i in o) {
|
1180
|
+
if (o.hasOwnProperty(i)) {
|
1181
|
+
v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : '';
|
1182
|
+
}
|
1183
|
+
}
|
1181
1184
|
|
1182
1185
|
return v + '}';
|
1183
1186
|
}
|
@@ -1198,6 +1201,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
1198
1201
|
|
1199
1202
|
};
|
1200
1203
|
})();
|
1204
|
+
|
1201
1205
|
tinymce.create('static tinymce.util.XHR', {
|
1202
1206
|
send : function(o) {
|
1203
1207
|
var x, t, w = window, c = 0;
|
@@ -1313,11 +1317,14 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1313
1317
|
}());
|
1314
1318
|
(function(tinymce){
|
1315
1319
|
tinymce.VK = {
|
1316
|
-
DELETE:46,
|
1317
|
-
BACKSPACE:8
|
1318
|
-
|
1320
|
+
DELETE: 46,
|
1321
|
+
BACKSPACE: 8,
|
1322
|
+
ENTER: 13,
|
1323
|
+
TAB: 9,
|
1324
|
+
SPACEBAR: 32,
|
1325
|
+
UP: 38,
|
1326
|
+
DOWN: 40
|
1319
1327
|
}
|
1320
|
-
|
1321
1328
|
})(tinymce);
|
1322
1329
|
|
1323
1330
|
(function(tinymce) {
|
@@ -1346,7 +1353,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1346
1353
|
node = blockElm.firstChild;
|
1347
1354
|
|
1348
1355
|
// Ignore empty text nodes
|
1349
|
-
while (node.nodeType == 3 && node.nodeValue.length == 0)
|
1356
|
+
while (node && node.nodeType == 3 && node.nodeValue.length == 0)
|
1350
1357
|
node = node.nextSibling;
|
1351
1358
|
|
1352
1359
|
if (node && node.nodeName === 'SPAN') {
|
@@ -1395,6 +1402,21 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1395
1402
|
});
|
1396
1403
|
};
|
1397
1404
|
|
1405
|
+
function removeHrOnBackspace(ed) {
|
1406
|
+
ed.onKeyDown.add(function(ed, e) {
|
1407
|
+
if (e.keyCode === BACKSPACE) {
|
1408
|
+
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
|
1409
|
+
var node = ed.selection.getNode();
|
1410
|
+
var previousSibling = node.previousSibling;
|
1411
|
+
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
|
1412
|
+
ed.dom.remove(previousSibling);
|
1413
|
+
tinymce.dom.Event.cancel(e);
|
1414
|
+
}
|
1415
|
+
}
|
1416
|
+
}
|
1417
|
+
})
|
1418
|
+
}
|
1419
|
+
|
1398
1420
|
function focusBody(ed) {
|
1399
1421
|
// Fix for a focus bug in FF 3.x where the body element
|
1400
1422
|
// wouldn't get proper focus if the user clicked on the HTML element
|
@@ -1432,6 +1454,31 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1432
1454
|
});
|
1433
1455
|
};
|
1434
1456
|
|
1457
|
+
function selectionChangeNodeChanged(ed) {
|
1458
|
+
var lastRng, selectionTimer;
|
1459
|
+
|
1460
|
+
ed.dom.bind(ed.getDoc(), 'selectionchange', function() {
|
1461
|
+
if (selectionTimer) {
|
1462
|
+
clearTimeout(selectionTimer);
|
1463
|
+
selectionTimer = 0;
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
selectionTimer = window.setTimeout(function() {
|
1467
|
+
var rng = ed.selection.getRng();
|
1468
|
+
|
1469
|
+
// Compare the ranges to see if it was a real change or not
|
1470
|
+
if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) {
|
1471
|
+
ed.nodeChanged();
|
1472
|
+
lastRng = rng;
|
1473
|
+
}
|
1474
|
+
}, 50);
|
1475
|
+
});
|
1476
|
+
}
|
1477
|
+
|
1478
|
+
function ensureBodyHasRoleApplication(ed) {
|
1479
|
+
document.body.setAttribute("role", "application");
|
1480
|
+
}
|
1481
|
+
|
1435
1482
|
tinymce.create('tinymce.util.Quirks', {
|
1436
1483
|
Quirks: function(ed) {
|
1437
1484
|
// WebKit
|
@@ -1440,24 +1487,33 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1440
1487
|
emptyEditorWhenDeleting(ed);
|
1441
1488
|
inputMethodFocus(ed);
|
1442
1489
|
selectControlElements(ed);
|
1490
|
+
|
1491
|
+
// iOS
|
1492
|
+
if (tinymce.isIDevice) {
|
1493
|
+
selectionChangeNodeChanged(ed);
|
1494
|
+
}
|
1443
1495
|
}
|
1444
1496
|
|
1445
1497
|
// IE
|
1446
1498
|
if (tinymce.isIE) {
|
1499
|
+
removeHrOnBackspace(ed);
|
1447
1500
|
emptyEditorWhenDeleting(ed);
|
1501
|
+
ensureBodyHasRoleApplication(ed);
|
1448
1502
|
}
|
1449
1503
|
|
1450
1504
|
// Gecko
|
1451
1505
|
if (tinymce.isGecko) {
|
1506
|
+
removeHrOnBackspace(ed);
|
1452
1507
|
focusBody(ed);
|
1453
1508
|
}
|
1454
1509
|
}
|
1455
1510
|
});
|
1456
1511
|
})(tinymce);
|
1512
|
+
|
1457
1513
|
(function(tinymce) {
|
1458
1514
|
var namedEntities, baseEntities, reverseEntities,
|
1459
|
-
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1460
|
-
textCharsRegExp = /[<>&\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1515
|
+
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1516
|
+
textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1461
1517
|
rawCharsRegExp = /[<>&\"\']/g,
|
1462
1518
|
entityRegExp = /&(#x|#)?([\w]+);/g,
|
1463
1519
|
asciiMap = {
|
@@ -2443,7 +2499,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|
2443
2499
|
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
|
2444
2500
|
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
|
2445
2501
|
'(?:\\/([^>]+)>)|' + // End element
|
2446
|
-
'(?:([^\\s\\/<>]+)
|
2502
|
+
'(?:([^\\s\\/<>]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/)>)' + // Start element
|
2447
2503
|
')', 'g');
|
2448
2504
|
|
2449
2505
|
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
|
@@ -4115,48 +4171,48 @@ tinymce.html.Writer = function(settings) {
|
|
4115
4171
|
|
4116
4172
|
return this.run(e, function(e) {
|
4117
4173
|
var s = t.settings;
|
4174
|
+
if (v !== null) {
|
4175
|
+
switch (n) {
|
4176
|
+
case "style":
|
4177
|
+
if (!is(v, 'string')) {
|
4178
|
+
each(v, function(v, n) {
|
4179
|
+
t.setStyle(e, n, v);
|
4180
|
+
});
|
4118
4181
|
|
4119
|
-
|
4120
|
-
|
4121
|
-
if (!is(v, 'string')) {
|
4122
|
-
each(v, function(v, n) {
|
4123
|
-
t.setStyle(e, n, v);
|
4124
|
-
});
|
4125
|
-
|
4126
|
-
return;
|
4127
|
-
}
|
4182
|
+
return;
|
4183
|
+
}
|
4128
4184
|
|
4129
|
-
|
4130
|
-
|
4131
|
-
|
4132
|
-
|
4133
|
-
|
4134
|
-
|
4135
|
-
|
4185
|
+
// No mce_style for elements with these since they might get resized by the user
|
4186
|
+
if (s.keep_values) {
|
4187
|
+
if (v && !t._isRes(v))
|
4188
|
+
e.setAttribute('data-mce-style', v, 2);
|
4189
|
+
else
|
4190
|
+
e.removeAttribute('data-mce-style', 2);
|
4191
|
+
}
|
4136
4192
|
|
4137
|
-
|
4138
|
-
|
4193
|
+
e.style.cssText = v;
|
4194
|
+
break;
|
4139
4195
|
|
4140
|
-
|
4141
|
-
|
4142
|
-
|
4196
|
+
case "class":
|
4197
|
+
e.className = v || ''; // Fix IE null bug
|
4198
|
+
break;
|
4143
4199
|
|
4144
|
-
|
4145
|
-
|
4146
|
-
|
4147
|
-
|
4148
|
-
|
4200
|
+
case "src":
|
4201
|
+
case "href":
|
4202
|
+
if (s.keep_values) {
|
4203
|
+
if (s.url_converter)
|
4204
|
+
v = s.url_converter.call(s.url_converter_scope || t, v, n, e);
|
4149
4205
|
|
4150
|
-
|
4151
|
-
|
4206
|
+
t.setAttrib(e, 'data-mce-' + n, v, 2);
|
4207
|
+
}
|
4152
4208
|
|
4153
|
-
|
4209
|
+
break;
|
4154
4210
|
|
4155
|
-
|
4156
|
-
|
4157
|
-
|
4211
|
+
case "shape":
|
4212
|
+
e.setAttribute('data-mce-style', v);
|
4213
|
+
break;
|
4214
|
+
}
|
4158
4215
|
}
|
4159
|
-
|
4160
4216
|
if (is(v) && v !== null && v.length !== 0)
|
4161
4217
|
e.setAttribute(n, '' + v, 2);
|
4162
4218
|
else
|
@@ -5932,7 +5988,7 @@ tinymce.html.Writer = function(settings) {
|
|
5932
5988
|
parent = node.parentNode;
|
5933
5989
|
root = dom.getRoot().parentNode;
|
5934
5990
|
|
5935
|
-
while (parent != root) {
|
5991
|
+
while (parent != root && parent.nodeType !== 9) {
|
5936
5992
|
children = parent.children;
|
5937
5993
|
|
5938
5994
|
i = children.length;
|
@@ -7241,7 +7297,8 @@ tinymce.html.Writer = function(settings) {
|
|
7241
7297
|
if (sb && eb && sb != eb) {
|
7242
7298
|
n = sb;
|
7243
7299
|
|
7244
|
-
|
7300
|
+
var walker = new tinymce.dom.TreeWalker(sb, dom.getRoot());
|
7301
|
+
while ((n = walker.next()) && n != eb) {
|
7245
7302
|
if (dom.isBlock(n))
|
7246
7303
|
bl.push(n);
|
7247
7304
|
}
|
@@ -7647,7 +7704,7 @@ tinymce.html.Writer = function(settings) {
|
|
7647
7704
|
|
7648
7705
|
// Replace all BOM characters for now until we can find a better solution
|
7649
7706
|
if (!args.cleanup)
|
7650
|
-
args.content = args.content.replace(/\uFEFF/g, '');
|
7707
|
+
args.content = args.content.replace(/\uFEFF|\u200B/g, '');
|
7651
7708
|
|
7652
7709
|
// Post process
|
7653
7710
|
if (!args.no_events)
|
@@ -7941,6 +7998,24 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
7941
7998
|
return;
|
7942
7999
|
}
|
7943
8000
|
|
8001
|
+
function exclude(nodes) {
|
8002
|
+
var node;
|
8003
|
+
|
8004
|
+
// First node is excluded
|
8005
|
+
node = nodes[0];
|
8006
|
+
if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {
|
8007
|
+
nodes.splice(0, 1);
|
8008
|
+
}
|
8009
|
+
|
8010
|
+
// Last node is excluded
|
8011
|
+
node = nodes[nodes.length - 1];
|
8012
|
+
if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {
|
8013
|
+
nodes.splice(nodes.length - 1, 1);
|
8014
|
+
}
|
8015
|
+
|
8016
|
+
return nodes;
|
8017
|
+
};
|
8018
|
+
|
7944
8019
|
function collectSiblings(node, name, end_node) {
|
7945
8020
|
var siblings = [];
|
7946
8021
|
|
@@ -7970,7 +8045,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
7970
8045
|
if (!next)
|
7971
8046
|
siblings.reverse();
|
7972
8047
|
|
7973
|
-
callback(siblings);
|
8048
|
+
callback(exclude(siblings));
|
7974
8049
|
}
|
7975
8050
|
}
|
7976
8051
|
};
|
@@ -7983,28 +8058,28 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
7983
8058
|
if (endContainer.nodeType == 1 && endContainer.hasChildNodes())
|
7984
8059
|
endContainer = endContainer.childNodes[Math.min(endOffset - 1, endContainer.childNodes.length - 1)];
|
7985
8060
|
|
7986
|
-
// Find common ancestor and end points
|
7987
|
-
ancestor = dom.findCommonAncestor(startContainer, endContainer);
|
7988
|
-
|
7989
8061
|
// Same container
|
7990
8062
|
if (startContainer == endContainer)
|
7991
|
-
return callback([startContainer]);
|
8063
|
+
return callback(exclude([startContainer]));
|
7992
8064
|
|
8065
|
+
// Find common ancestor and end points
|
8066
|
+
ancestor = dom.findCommonAncestor(startContainer, endContainer);
|
8067
|
+
|
7993
8068
|
// Process left side
|
7994
8069
|
for (node = startContainer; node; node = node.parentNode) {
|
7995
|
-
if (node
|
8070
|
+
if (node === endContainer)
|
7996
8071
|
return walkBoundary(startContainer, ancestor, true);
|
7997
8072
|
|
7998
|
-
if (node
|
8073
|
+
if (node === ancestor)
|
7999
8074
|
break;
|
8000
8075
|
}
|
8001
8076
|
|
8002
8077
|
// Process right side
|
8003
8078
|
for (node = endContainer; node; node = node.parentNode) {
|
8004
|
-
if (node
|
8079
|
+
if (node === startContainer)
|
8005
8080
|
return walkBoundary(endContainer, ancestor);
|
8006
8081
|
|
8007
|
-
if (node
|
8082
|
+
if (node === ancestor)
|
8008
8083
|
break;
|
8009
8084
|
}
|
8010
8085
|
|
@@ -8023,48 +8098,46 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8023
8098
|
);
|
8024
8099
|
|
8025
8100
|
if (siblings.length)
|
8026
|
-
callback(siblings);
|
8101
|
+
callback(exclude(siblings));
|
8027
8102
|
|
8028
8103
|
// Walk right leaf
|
8029
8104
|
walkBoundary(endContainer, endPoint);
|
8030
8105
|
};
|
8031
8106
|
|
8032
|
-
|
8107
|
+
this.split = function(rng) {
|
8033
8108
|
var startContainer = rng.startContainer,
|
8034
8109
|
startOffset = rng.startOffset,
|
8035
8110
|
endContainer = rng.endContainer,
|
8036
8111
|
endOffset = rng.endOffset;
|
8037
8112
|
|
8038
8113
|
function splitText(node, offset) {
|
8039
|
-
|
8040
|
-
node.appendData(INVISIBLE_CHAR);
|
8041
|
-
|
8042
|
-
node = node.splitText(offset);
|
8043
|
-
|
8044
|
-
if (node.nodeValue === INVISIBLE_CHAR)
|
8045
|
-
node.nodeValue = '';
|
8046
|
-
|
8047
|
-
return node;
|
8114
|
+
return node.splitText(offset);
|
8048
8115
|
};
|
8049
8116
|
|
8050
8117
|
// Handle single text node
|
8051
|
-
if (startContainer == endContainer) {
|
8052
|
-
if (startContainer.
|
8053
|
-
|
8054
|
-
|
8055
|
-
|
8056
|
-
if (endOffset
|
8057
|
-
|
8118
|
+
if (startContainer == endContainer && startContainer.nodeType == 3) {
|
8119
|
+
if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
|
8120
|
+
endContainer = splitText(startContainer, startOffset);
|
8121
|
+
startContainer = endContainer.previousSibling;
|
8122
|
+
|
8123
|
+
if (endOffset > startOffset) {
|
8124
|
+
endOffset = endOffset - startOffset;
|
8125
|
+
startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
|
8126
|
+
endOffset = endContainer.nodeValue.length;
|
8127
|
+
startOffset = 0;
|
8128
|
+
} else {
|
8129
|
+
endOffset = 0;
|
8130
|
+
}
|
8058
8131
|
}
|
8059
8132
|
} else {
|
8060
8133
|
// Split startContainer text node if needed
|
8061
|
-
if (startContainer.nodeType == 3 && startOffset
|
8134
|
+
if (startContainer.nodeType == 3 && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
|
8062
8135
|
startContainer = splitText(startContainer, startOffset);
|
8063
8136
|
startOffset = 0;
|
8064
8137
|
}
|
8065
8138
|
|
8066
8139
|
// Split endContainer text node if needed
|
8067
|
-
if (endContainer.nodeType == 3 && endOffset
|
8140
|
+
if (endContainer.nodeType == 3 && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
|
8068
8141
|
endContainer = splitText(endContainer, endOffset).previousSibling;
|
8069
8142
|
endOffset = endContainer.nodeValue.length;
|
8070
8143
|
}
|
@@ -8077,7 +8150,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8077
8150
|
endOffset : endOffset
|
8078
8151
|
};
|
8079
8152
|
};
|
8080
|
-
|
8153
|
+
|
8081
8154
|
};
|
8082
8155
|
|
8083
8156
|
tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {
|
@@ -10369,6 +10442,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10369
10442
|
visual_table_class : 'mceItemTable',
|
10370
10443
|
visual : 1,
|
10371
10444
|
font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
10445
|
+
font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
10372
10446
|
apply_source_formatting : 1,
|
10373
10447
|
directionality : 'ltr',
|
10374
10448
|
forced_root_block : 'p',
|
@@ -10800,10 +10874,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
10800
10874
|
|
10801
10875
|
// Keep scripts from executing
|
10802
10876
|
t.parser.addNodeFilter('script', function(nodes, name) {
|
10803
|
-
var i = nodes.length;
|
10877
|
+
var i = nodes.length, node;
|
10804
10878
|
|
10805
|
-
while (i--)
|
10806
|
-
nodes[i]
|
10879
|
+
while (i--) {
|
10880
|
+
node = nodes[i];
|
10881
|
+
node.attr('type', 'mce-' + (node.attr('type') || 'text/javascript'));
|
10882
|
+
}
|
10807
10883
|
});
|
10808
10884
|
|
10809
10885
|
t.parser.addNodeFilter('#cdata', function(nodes, name) {
|
@@ -12144,21 +12220,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12144
12220
|
});
|
12145
12221
|
}
|
12146
12222
|
|
12147
|
-
// Fire a nodeChanged when the selection is changed on WebKit this fixes selection issues on iOS5
|
12148
|
-
// It only fires the nodeChange event every 50ms since it would other wise update the UI when you type and it hogs the CPU
|
12149
|
-
if (tinymce.isWebKit) {
|
12150
|
-
dom.bind(t.getDoc(), 'selectionchange', function() {
|
12151
|
-
if (t.selectionTimer) {
|
12152
|
-
clearTimeout(t.selectionTimer);
|
12153
|
-
t.selectionTimer = 0;
|
12154
|
-
}
|
12155
|
-
|
12156
|
-
t.selectionTimer = window.setTimeout(function() {
|
12157
|
-
t.nodeChanged();
|
12158
|
-
}, 50);
|
12159
|
-
});
|
12160
|
-
}
|
12161
|
-
|
12162
12223
|
// Bug fix for FireFox keeping styles from end of selection instead of start.
|
12163
12224
|
if (tinymce.isGecko) {
|
12164
12225
|
function getAttributeApplyFunction() {
|
@@ -12168,7 +12229,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12168
12229
|
var target = t.selection.getStart();
|
12169
12230
|
|
12170
12231
|
if (target !== t.getBody()) {
|
12171
|
-
t.dom.
|
12232
|
+
t.dom.setAttrib(target, "style", null);
|
12172
12233
|
|
12173
12234
|
each(template, function(attr) {
|
12174
12235
|
target.setAttributeNode(attr.cloneNode(true));
|
@@ -14021,8 +14082,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14021
14082
|
MCE_ATTR_RE = /^(src|href|style)$/,
|
14022
14083
|
FALSE = false,
|
14023
14084
|
TRUE = true,
|
14024
|
-
undefined
|
14025
|
-
pendingFormats = {apply : [], remove : []};
|
14085
|
+
undefined;
|
14026
14086
|
|
14027
14087
|
function isArray(obj) {
|
14028
14088
|
return obj instanceof Array;
|
@@ -14238,7 +14298,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14238
14298
|
}
|
14239
14299
|
};
|
14240
14300
|
|
14241
|
-
function applyRngStyle(rng, bookmark) {
|
14301
|
+
function applyRngStyle(rng, bookmark, node_specific) {
|
14242
14302
|
var newWrappers = [], wrapName, wrapElm;
|
14243
14303
|
|
14244
14304
|
// Setup wrapper element
|
@@ -14302,7 +14362,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14302
14362
|
|
14303
14363
|
// Is it valid to wrap this item
|
14304
14364
|
if (isValid(wrapName, nodeName) && isValid(parentName, wrapName) &&
|
14305
|
-
!(node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279)) {
|
14365
|
+
!(!node_specific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && node.id !== '_mce_caret') {
|
14306
14366
|
// Start wrapping
|
14307
14367
|
if (!currentWrapElm) {
|
14308
14368
|
// Wrap the node
|
@@ -14457,12 +14517,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14457
14517
|
|
14458
14518
|
if (format) {
|
14459
14519
|
if (node) {
|
14460
|
-
|
14461
|
-
|
14462
|
-
|
14463
|
-
|
14464
|
-
|
14465
|
-
|
14520
|
+
if (node.nodeType) {
|
14521
|
+
rng = dom.createRng();
|
14522
|
+
rng.setStartBefore(node);
|
14523
|
+
rng.setEndAfter(node);
|
14524
|
+
applyRngStyle(expandRng(rng, formatList), null, true);
|
14525
|
+
} else {
|
14526
|
+
applyRngStyle(node, null, true);
|
14527
|
+
}
|
14466
14528
|
} else {
|
14467
14529
|
if (!isCollapsed || !format.inline || dom.select('td.mceSelected,th.mceSelected').length) {
|
14468
14530
|
// Obtain selection node before selection is unselected by applyRngStyle()
|
@@ -14676,10 +14738,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14676
14738
|
|
14677
14739
|
// Handle node
|
14678
14740
|
if (node) {
|
14679
|
-
|
14680
|
-
|
14681
|
-
|
14682
|
-
|
14741
|
+
if (node.nodeType) {
|
14742
|
+
rng = dom.createRng();
|
14743
|
+
rng.setStartBefore(node);
|
14744
|
+
rng.setEndAfter(node);
|
14745
|
+
removeRngStyle(rng);
|
14746
|
+
} else {
|
14747
|
+
removeRngStyle(node);
|
14748
|
+
}
|
14749
|
+
|
14683
14750
|
return;
|
14684
14751
|
}
|
14685
14752
|
|
@@ -14696,6 +14763,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14696
14763
|
ed.nodeChanged();
|
14697
14764
|
} else
|
14698
14765
|
performCaretAction('remove', name, vars);
|
14766
|
+
|
14767
|
+
// When you remove formatting from a table cell in WebKit (cell, not the contents of a cell) there is a rendering issue with column width
|
14768
|
+
if (tinymce.isWebKit) {
|
14769
|
+
ed.execCommand('mceCleanup');
|
14770
|
+
}
|
14699
14771
|
};
|
14700
14772
|
|
14701
14773
|
function toggle(name, vars, node) {
|
@@ -14770,7 +14842,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14770
14842
|
};
|
14771
14843
|
|
14772
14844
|
function match(name, vars, node) {
|
14773
|
-
var startNode
|
14845
|
+
var startNode;
|
14774
14846
|
|
14775
14847
|
function matchParents(node) {
|
14776
14848
|
// Find first node with similar format settings
|
@@ -14786,21 +14858,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14786
14858
|
if (node)
|
14787
14859
|
return matchParents(node);
|
14788
14860
|
|
14789
|
-
// Check pending formats
|
14790
|
-
if (selection.isCollapsed()) {
|
14791
|
-
for (i = pendingFormats.apply.length - 1; i >= 0; i--) {
|
14792
|
-
if (pendingFormats.apply[i].name == name)
|
14793
|
-
return true;
|
14794
|
-
}
|
14795
|
-
|
14796
|
-
for (i = pendingFormats.remove.length - 1; i >= 0; i--) {
|
14797
|
-
if (pendingFormats.remove[i].name == name)
|
14798
|
-
return false;
|
14799
|
-
}
|
14800
|
-
|
14801
|
-
return matchParents(selection.getNode());
|
14802
|
-
}
|
14803
|
-
|
14804
14861
|
// Check selected node
|
14805
14862
|
node = selection.getNode();
|
14806
14863
|
if (matchParents(node))
|
@@ -14819,33 +14876,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14819
14876
|
function matchAll(names, vars) {
|
14820
14877
|
var startElement, matchedFormatNames = [], checkedMap = {}, i, ni, name;
|
14821
14878
|
|
14822
|
-
// If the selection is collapsed then check pending formats
|
14823
|
-
if (selection.isCollapsed()) {
|
14824
|
-
for (ni = 0; ni < names.length; ni++) {
|
14825
|
-
// If the name is to be removed, then stop it from being added
|
14826
|
-
for (i = pendingFormats.remove.length - 1; i >= 0; i--) {
|
14827
|
-
name = names[ni];
|
14828
|
-
|
14829
|
-
if (pendingFormats.remove[i].name == name) {
|
14830
|
-
checkedMap[name] = true;
|
14831
|
-
break;
|
14832
|
-
}
|
14833
|
-
}
|
14834
|
-
}
|
14835
|
-
|
14836
|
-
// If the format is to be applied
|
14837
|
-
for (i = pendingFormats.apply.length - 1; i >= 0; i--) {
|
14838
|
-
for (ni = 0; ni < names.length; ni++) {
|
14839
|
-
name = names[ni];
|
14840
|
-
|
14841
|
-
if (!checkedMap[name] && pendingFormats.apply[i].name == name) {
|
14842
|
-
checkedMap[name] = true;
|
14843
|
-
matchedFormatNames.push(name);
|
14844
|
-
}
|
14845
|
-
}
|
14846
|
-
}
|
14847
|
-
}
|
14848
|
-
|
14849
14879
|
// Check start of selection for formats
|
14850
14880
|
startElement = selection.getStart();
|
14851
14881
|
dom.getParent(startElement, function(node) {
|
@@ -14954,7 +14984,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14954
14984
|
};
|
14955
14985
|
|
14956
14986
|
function isWhiteSpaceNode(node) {
|
14957
|
-
return node && node.nodeType === 3 && /^([\
|
14987
|
+
return node && node.nodeType === 3 && /^([\t \r\n]+|)$/.test(node.nodeValue);
|
14958
14988
|
};
|
14959
14989
|
|
14960
14990
|
function wrap(node, name, attrs) {
|
@@ -14970,31 +15000,37 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14970
15000
|
var startContainer = rng.startContainer,
|
14971
15001
|
startOffset = rng.startOffset,
|
14972
15002
|
endContainer = rng.endContainer,
|
14973
|
-
endOffset = rng.endOffset, sibling, lastIdx, leaf;
|
15003
|
+
endOffset = rng.endOffset, sibling, lastIdx, leaf, endPoint;
|
14974
15004
|
|
14975
15005
|
// This function walks up the tree if there is no siblings before/after the node
|
14976
|
-
function findParentContainer(
|
14977
|
-
var parent, child;
|
15006
|
+
function findParentContainer(start) {
|
15007
|
+
var container, parent, child, sibling, siblingName;
|
14978
15008
|
|
14979
|
-
|
15009
|
+
container = parent = start ? startContainer : endContainer;
|
15010
|
+
siblingName = start ? 'previousSibling' : 'nextSibling';
|
15011
|
+
root = dom.getRoot();
|
14980
15012
|
|
14981
|
-
|
14982
|
-
|
14983
|
-
|
15013
|
+
// If it's a text node and the offset is inside the text
|
15014
|
+
if (container.nodeType == 3 && !isWhiteSpaceNode(container)) {
|
15015
|
+
if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
|
15016
|
+
return container;
|
15017
|
+
}
|
15018
|
+
}
|
14984
15019
|
|
15020
|
+
for (;;) {
|
14985
15021
|
// Stop expanding on block elements or root depending on format
|
14986
15022
|
if (parent == root || (!format[0].block_expand && isBlock(parent)))
|
14987
|
-
return
|
14988
|
-
|
14989
|
-
for (sibling = parent[child_name]; sibling && sibling != container; sibling = sibling[sibling_name]) {
|
14990
|
-
if (sibling.nodeType == 1 && !isBookmarkNode(sibling))
|
14991
|
-
return container;
|
15023
|
+
return parent;
|
14992
15024
|
|
14993
|
-
|
14994
|
-
|
15025
|
+
// Walk left/right
|
15026
|
+
for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
|
15027
|
+
if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling)) {
|
15028
|
+
return parent;
|
15029
|
+
}
|
14995
15030
|
}
|
14996
15031
|
|
14997
|
-
|
15032
|
+
// Check if we can move up are we at root level or body level
|
15033
|
+
parent = parent.parentNode;
|
14998
15034
|
}
|
14999
15035
|
|
15000
15036
|
return container;
|
@@ -15032,23 +15068,103 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15032
15068
|
}
|
15033
15069
|
|
15034
15070
|
// Exclude bookmark nodes if possible
|
15035
|
-
if (isBookmarkNode(startContainer.parentNode))
|
15036
|
-
startContainer = startContainer.parentNode;
|
15037
|
-
|
15038
|
-
if (isBookmarkNode(startContainer))
|
15071
|
+
if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) {
|
15072
|
+
startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;
|
15039
15073
|
startContainer = startContainer.nextSibling || startContainer;
|
15040
15074
|
|
15041
|
-
|
15042
|
-
|
15043
|
-
endContainer = endContainer.parentNode;
|
15075
|
+
if (startContainer.nodeType == 3)
|
15076
|
+
startOffset = 0;
|
15044
15077
|
}
|
15045
15078
|
|
15046
|
-
if (isBookmarkNode(endContainer)
|
15047
|
-
endContainer = endContainer.
|
15048
|
-
|
15079
|
+
if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) {
|
15080
|
+
endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;
|
15081
|
+
endContainer = endContainer.previousSibling || endContainer;
|
15082
|
+
|
15083
|
+
if (endContainer.nodeType == 3)
|
15084
|
+
endOffset = endContainer.length;
|
15049
15085
|
}
|
15050
15086
|
|
15051
15087
|
if (format[0].inline) {
|
15088
|
+
if (rng.collapsed) {
|
15089
|
+
function findWordEndPoint(container, offset, start) {
|
15090
|
+
var walker, node, pos, lastTextNode;
|
15091
|
+
|
15092
|
+
function findSpace(node, offset) {
|
15093
|
+
var pos, pos2, str = node.nodeValue;
|
15094
|
+
|
15095
|
+
if (typeof(offset) == "undefined") {
|
15096
|
+
offset = start ? str.length : 0;
|
15097
|
+
}
|
15098
|
+
|
15099
|
+
if (start) {
|
15100
|
+
pos = str.lastIndexOf(' ', offset);
|
15101
|
+
pos2 = str.lastIndexOf('\u00a0', offset);
|
15102
|
+
pos = pos > pos2 ? pos : pos2;
|
15103
|
+
|
15104
|
+
// Include the space on remove to avoid tag soup
|
15105
|
+
if (pos !== -1 && !remove) {
|
15106
|
+
pos++;
|
15107
|
+
}
|
15108
|
+
} else {
|
15109
|
+
pos = str.indexOf(' ', offset);
|
15110
|
+
pos2 = str.indexOf('\u00a0', offset);
|
15111
|
+
pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;
|
15112
|
+
}
|
15113
|
+
|
15114
|
+
return pos;
|
15115
|
+
};
|
15116
|
+
|
15117
|
+
if (container.nodeType === 3) {
|
15118
|
+
pos = findSpace(container, offset);
|
15119
|
+
|
15120
|
+
if (pos !== -1) {
|
15121
|
+
return {container : container, offset : pos};
|
15122
|
+
}
|
15123
|
+
|
15124
|
+
lastTextNode = container;
|
15125
|
+
}
|
15126
|
+
|
15127
|
+
// Walk the nodes inside the block
|
15128
|
+
walker = new TreeWalker(container, dom.getParent(container, isBlock) || ed.getBody());
|
15129
|
+
while (node = walker[start ? 'prev' : 'next']()) {
|
15130
|
+
if (node.nodeType === 3) {
|
15131
|
+
lastTextNode = node;
|
15132
|
+
pos = findSpace(node);
|
15133
|
+
|
15134
|
+
if (pos !== -1) {
|
15135
|
+
return {container : node, offset : pos};
|
15136
|
+
}
|
15137
|
+
} else if (isBlock(node)) {
|
15138
|
+
break;
|
15139
|
+
}
|
15140
|
+
}
|
15141
|
+
|
15142
|
+
if (lastTextNode) {
|
15143
|
+
if (start) {
|
15144
|
+
offset = 0;
|
15145
|
+
} else {
|
15146
|
+
offset = lastTextNode.length;
|
15147
|
+
}
|
15148
|
+
|
15149
|
+
return {container: lastTextNode, offset: offset};
|
15150
|
+
}
|
15151
|
+
}
|
15152
|
+
|
15153
|
+
// Expand left to closest word boundery
|
15154
|
+
endPoint = findWordEndPoint(startContainer, startOffset, true);
|
15155
|
+
if (endPoint) {
|
15156
|
+
startContainer = endPoint.container;
|
15157
|
+
startOffset = endPoint.offset;
|
15158
|
+
}
|
15159
|
+
|
15160
|
+
// Expand right to closest word boundery
|
15161
|
+
endPoint = findWordEndPoint(endContainer, endOffset);
|
15162
|
+
if (endPoint) {
|
15163
|
+
endContainer = endPoint.container;
|
15164
|
+
endOffset = endPoint.offset;
|
15165
|
+
}
|
15166
|
+
}
|
15167
|
+
|
15052
15168
|
// Avoid applying formatting to a trailing space.
|
15053
15169
|
leaf = findLeaf(endContainer, endOffset);
|
15054
15170
|
if (leaf.node) {
|
@@ -15062,19 +15178,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15062
15178
|
endContainer = leaf.node;
|
15063
15179
|
endContainer.splitText(leaf.offset - 1);
|
15064
15180
|
} else if (leaf.node.previousSibling) {
|
15065
|
-
|
15181
|
+
// TODO: Figure out why this is in here
|
15182
|
+
//endContainer = leaf.node.previousSibling;
|
15066
15183
|
}
|
15067
15184
|
}
|
15068
15185
|
}
|
15069
15186
|
}
|
15070
|
-
|
15187
|
+
|
15071
15188
|
// Move start/end point up the tree if the leaves are sharp and if we are in different containers
|
15072
15189
|
// Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>!
|
15073
15190
|
// This will reduce the number of wrapper elements that needs to be created
|
15074
15191
|
// Move start point up the tree
|
15075
15192
|
if (format[0].inline || format[0].block_expand) {
|
15076
|
-
|
15077
|
-
|
15193
|
+
if (!format[0].inline || (startContainer.nodeType != 3 || startOffset === 0)) {
|
15194
|
+
startContainer = findParentContainer(true);
|
15195
|
+
}
|
15196
|
+
|
15197
|
+
if (!format[0].inline || (endContainer.nodeType != 3 || endOffset === endContainer.nodeValue.length)) {
|
15198
|
+
endContainer = findParentContainer();
|
15199
|
+
}
|
15078
15200
|
}
|
15079
15201
|
|
15080
15202
|
// Expand start/end container to matching selector
|
@@ -15148,10 +15270,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15148
15270
|
// Non block element then try to expand up the leaf
|
15149
15271
|
if (format[0].block) {
|
15150
15272
|
if (!isBlock(startContainer))
|
15151
|
-
startContainer = findParentContainer(
|
15273
|
+
startContainer = findParentContainer(true);
|
15152
15274
|
|
15153
15275
|
if (!isBlock(endContainer))
|
15154
|
-
endContainer = findParentContainer(
|
15276
|
+
endContainer = findParentContainer();
|
15155
15277
|
}
|
15156
15278
|
}
|
15157
15279
|
|
@@ -15444,7 +15566,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15444
15566
|
};
|
15445
15567
|
|
15446
15568
|
function getContainer(rng, start) {
|
15447
|
-
var container, offset, lastIdx;
|
15569
|
+
var container, offset, lastIdx, walker;
|
15448
15570
|
|
15449
15571
|
container = rng[start ? 'startContainer' : 'endContainer'];
|
15450
15572
|
offset = rng[start ? 'startOffset' : 'endOffset'];
|
@@ -15458,140 +15580,267 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15458
15580
|
container = container.childNodes[offset > lastIdx ? lastIdx : offset];
|
15459
15581
|
}
|
15460
15582
|
|
15583
|
+
// If start text node is excluded then walk to the next node
|
15584
|
+
if (container.nodeType === 3 && start && offset >= container.nodeValue.length) {
|
15585
|
+
container = new TreeWalker(container, ed.getBody()).next() || container;
|
15586
|
+
}
|
15587
|
+
|
15588
|
+
// If end text node is excluded then walk to the previous node
|
15589
|
+
if (container.nodeType === 3 && !start && offset == 0) {
|
15590
|
+
container = new TreeWalker(container, ed.getBody()).prev() || container;
|
15591
|
+
}
|
15592
|
+
|
15461
15593
|
return container;
|
15462
15594
|
};
|
15463
15595
|
|
15464
15596
|
function performCaretAction(type, name, vars) {
|
15465
|
-
var
|
15466
|
-
|
15597
|
+
var invisibleChar, caretContainerId = '_mce_caret', debug = ed.settings.caret_debug;
|
15598
|
+
|
15599
|
+
// Setup invisible character use zero width space on Gecko since it doesn't change the heigt of the container
|
15600
|
+
invisibleChar = tinymce.isGecko ? '\u200B' : INVISIBLE_CHAR;
|
15601
|
+
|
15602
|
+
// Creates a caret container bogus element
|
15603
|
+
function createCaretContainer(fill) {
|
15604
|
+
var caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style: debug ? 'color:red' : ''});
|
15467
15605
|
|
15468
|
-
|
15469
|
-
|
15606
|
+
if (fill) {
|
15607
|
+
caretContainer.appendChild(ed.getDoc().createTextNode(invisibleChar));
|
15608
|
+
}
|
15609
|
+
|
15610
|
+
return caretContainer;
|
15470
15611
|
};
|
15471
15612
|
|
15472
|
-
function
|
15473
|
-
|
15474
|
-
|
15613
|
+
function isCaretContainerEmpty(node, nodes) {
|
15614
|
+
while (node) {
|
15615
|
+
if ((node.nodeType === 3 && node.nodeValue !== invisibleChar) || node.childNodes.length > 1) {
|
15616
|
+
return false;
|
15617
|
+
}
|
15618
|
+
|
15619
|
+
// Collect nodes
|
15620
|
+
if (nodes && node.nodeType === 1) {
|
15621
|
+
nodes.push(node);
|
15622
|
+
}
|
15623
|
+
|
15624
|
+
node = node.firstChild;
|
15625
|
+
}
|
15626
|
+
|
15627
|
+
return true;
|
15475
15628
|
};
|
15629
|
+
|
15630
|
+
// Returns any parent caret container element
|
15631
|
+
function getParentCaretContainer(node) {
|
15632
|
+
while (node) {
|
15633
|
+
if (node.id === caretContainerId) {
|
15634
|
+
return node;
|
15635
|
+
}
|
15476
15636
|
|
15477
|
-
|
15478
|
-
|
15479
|
-
|
15480
|
-
apply(item.name, item.vars, caret_node);
|
15637
|
+
node = node.parentNode;
|
15638
|
+
}
|
15639
|
+
};
|
15481
15640
|
|
15482
|
-
|
15483
|
-
|
15484
|
-
|
15485
|
-
});
|
15641
|
+
// Finds the first text node in the specified node
|
15642
|
+
function findFirstTextNode(node) {
|
15643
|
+
var walker;
|
15486
15644
|
|
15487
|
-
|
15488
|
-
|
15489
|
-
|
15490
|
-
|
15645
|
+
if (node) {
|
15646
|
+
walker = new TreeWalker(node, node);
|
15647
|
+
|
15648
|
+
for (node = walker.current(); node; node = walker.next()) {
|
15649
|
+
if (node.nodeType === 3) {
|
15650
|
+
return node;
|
15651
|
+
}
|
15652
|
+
}
|
15653
|
+
}
|
15654
|
+
};
|
15655
|
+
|
15656
|
+
// Removes the caret container for the specified node or all on the current document
|
15657
|
+
function removeCaretContainer(node, move_caret) {
|
15658
|
+
var child, rng;
|
15659
|
+
|
15660
|
+
if (!node) {
|
15661
|
+
node = getParentCaretContainer(selection.getStart());
|
15662
|
+
|
15663
|
+
if (!node) {
|
15664
|
+
while (node = dom.get(caretContainerId)) {
|
15665
|
+
removeCaretContainer(node, false);
|
15666
|
+
}
|
15667
|
+
}
|
15668
|
+
} else {
|
15669
|
+
rng = selection.getRng(true);
|
15670
|
+
|
15671
|
+
if (isCaretContainerEmpty(node)) {
|
15672
|
+
if (move_caret !== false) {
|
15673
|
+
rng.setStartBefore(node);
|
15674
|
+
rng.setEndBefore(node);
|
15675
|
+
}
|
15676
|
+
|
15677
|
+
dom.remove(node);
|
15678
|
+
} else {
|
15679
|
+
child = findFirstTextNode(node);
|
15680
|
+
child = child.deleteData(0, 1);
|
15681
|
+
dom.remove(node, 1);
|
15682
|
+
}
|
15491
15683
|
|
15492
|
-
|
15493
|
-
|
15684
|
+
selection.setRng(rng);
|
15685
|
+
}
|
15494
15686
|
};
|
15687
|
+
|
15688
|
+
// Applies formatting to the caret postion
|
15689
|
+
function applyCaretFormat() {
|
15690
|
+
var rng, caretContainer, textNode, offset, bookmark, container, text;
|
15691
|
+
|
15692
|
+
rng = selection.getRng(true);
|
15693
|
+
offset = rng.startOffset;
|
15694
|
+
container = rng.startContainer;
|
15695
|
+
text = container.nodeValue;
|
15696
|
+
|
15697
|
+
caretContainer = getParentCaretContainer(selection.getStart());
|
15698
|
+
if (caretContainer) {
|
15699
|
+
textNode = findFirstTextNode(caretContainer);
|
15700
|
+
}
|
15701
|
+
|
15702
|
+
// Expand to word is caret is in the middle of a text node and the char before/after is a alpha numeric character
|
15703
|
+
if (text && offset > 0 && offset < text.length && /\w/.test(text.charAt(offset)) && /\w/.test(text.charAt(offset - 1))) {
|
15704
|
+
// Get bookmark of caret position
|
15705
|
+
bookmark = selection.getBookmark();
|
15706
|
+
|
15707
|
+
// Collapse bookmark range (WebKit)
|
15708
|
+
rng.collapse(true);
|
15709
|
+
|
15710
|
+
// Expand the range to the closest word and split it at those points
|
15711
|
+
rng = expandRng(rng, get(name));
|
15712
|
+
rng = rangeUtils.split(rng);
|
15713
|
+
|
15714
|
+
// Apply the format to the range
|
15715
|
+
apply(name, vars, rng);
|
15716
|
+
|
15717
|
+
// Move selection back to caret position
|
15718
|
+
selection.moveToBookmark(bookmark);
|
15719
|
+
} else {
|
15720
|
+
if (!caretContainer || textNode.nodeValue !== invisibleChar) {
|
15721
|
+
caretContainer = createCaretContainer(true);
|
15722
|
+
textNode = caretContainer.firstChild;
|
15723
|
+
|
15724
|
+
rng.insertNode(caretContainer);
|
15725
|
+
offset = 1;
|
15726
|
+
|
15727
|
+
apply(name, vars, caretContainer);
|
15728
|
+
} else {
|
15729
|
+
apply(name, vars, caretContainer);
|
15730
|
+
}
|
15731
|
+
|
15732
|
+
// Move selection to text node
|
15733
|
+
selection.setCursorLocation(textNode, offset);
|
15734
|
+
}
|
15735
|
+
};
|
15736
|
+
|
15737
|
+
function removeCaretFormat() {
|
15738
|
+
var rng = selection.getRng(true), container, offset, bookmark,
|
15739
|
+
hasContentAfter, node, formatNode, parents = [], i, caretContainer;
|
15740
|
+
|
15741
|
+
container = rng.startContainer;
|
15742
|
+
offset = rng.startOffset;
|
15743
|
+
node = container;
|
15744
|
+
|
15745
|
+
if (container.nodeType == 3) {
|
15746
|
+
if (offset != container.nodeValue.length || container.nodeValue === invisibleChar) {
|
15747
|
+
hasContentAfter = true;
|
15748
|
+
}
|
15749
|
+
|
15750
|
+
node = node.parentNode;
|
15751
|
+
}
|
15752
|
+
|
15753
|
+
while (node) {
|
15754
|
+
if (matchNode(node, name, vars)) {
|
15755
|
+
formatNode = node;
|
15756
|
+
break;
|
15757
|
+
}
|
15758
|
+
|
15759
|
+
if (node.nextSibling) {
|
15760
|
+
hasContentAfter = true;
|
15761
|
+
}
|
15762
|
+
|
15763
|
+
parents.push(node);
|
15764
|
+
node = node.parentNode;
|
15765
|
+
}
|
15495
15766
|
|
15496
|
-
|
15497
|
-
|
15498
|
-
if (currentPendingFormats[i].name == name)
|
15767
|
+
// Node doesn't have the specified format
|
15768
|
+
if (!formatNode) {
|
15499
15769
|
return;
|
15500
|
-
|
15770
|
+
}
|
15501
15771
|
|
15502
|
-
|
15772
|
+
// Is there contents after the caret then remove the format on the element
|
15773
|
+
if (hasContentAfter) {
|
15774
|
+
// Get bookmark of caret position
|
15775
|
+
bookmark = selection.getBookmark();
|
15503
15776
|
|
15504
|
-
|
15505
|
-
|
15506
|
-
if (otherPendingFormats[i].name == name)
|
15507
|
-
otherPendingFormats.splice(i, 1);
|
15508
|
-
}
|
15777
|
+
// Collapse bookmark range (WebKit)
|
15778
|
+
rng.collapse(true);
|
15509
15779
|
|
15510
|
-
|
15511
|
-
|
15512
|
-
|
15513
|
-
pendingFormats.lastRng = selection.getRng();
|
15780
|
+
// Expand the range to the closest word and split it at those points
|
15781
|
+
rng = expandRng(rng, get(name), true);
|
15782
|
+
rng = rangeUtils.split(rng);
|
15514
15783
|
|
15515
|
-
|
15516
|
-
|
15517
|
-
var bookmark;
|
15784
|
+
// Remove the format from the range
|
15785
|
+
remove(name, vars, rng);
|
15518
15786
|
|
15519
|
-
|
15520
|
-
|
15521
|
-
|
15522
|
-
|
15523
|
-
|
15787
|
+
// Move selection back to caret position
|
15788
|
+
selection.moveToBookmark(bookmark);
|
15789
|
+
} else {
|
15790
|
+
caretContainer = createCaretContainer();
|
15791
|
+
|
15792
|
+
node = caretContainer;
|
15793
|
+
for (i = parents.length - 1; i >= 0; i--) {
|
15794
|
+
node.appendChild(parents[i].cloneNode(false));
|
15795
|
+
node = node.firstChild;
|
15524
15796
|
}
|
15525
|
-
});
|
15526
15797
|
|
15527
|
-
|
15528
|
-
|
15529
|
-
|
15530
|
-
function performPendingFormat(node, textNode) {
|
15531
|
-
var rng = dom.createRng();
|
15532
|
-
perform(node);
|
15798
|
+
// Insert invisible character into inner most format element
|
15799
|
+
node.appendChild(dom.doc.createTextNode(invisibleChar));
|
15800
|
+
node = node.firstChild;
|
15533
15801
|
|
15534
|
-
|
15535
|
-
|
15536
|
-
|
15537
|
-
|
15802
|
+
// Insert caret container after the formated node
|
15803
|
+
dom.insertAfter(caretContainer, formatNode);
|
15804
|
+
|
15805
|
+
// Move selection to text node
|
15806
|
+
selection.setCursorLocation(node, 1);
|
15807
|
+
}
|
15808
|
+
};
|
15809
|
+
|
15810
|
+
// Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements
|
15811
|
+
ed.onBeforeGetContent.addToTop(function() {
|
15812
|
+
var nodes = [], i;
|
15813
|
+
|
15814
|
+
if (isCaretContainerEmpty(getParentCaretContainer(selection.getStart()), nodes)) {
|
15815
|
+
// Mark children
|
15816
|
+
i = nodes.length;
|
15817
|
+
while (i--) {
|
15818
|
+
dom.setAttrib(nodes[i], 'data-mce-bogus', '1');
|
15538
15819
|
}
|
15539
|
-
|
15820
|
+
}
|
15821
|
+
});
|
15540
15822
|
|
15541
|
-
|
15542
|
-
|
15543
|
-
|
15544
|
-
|
15545
|
-
|
15546
|
-
|
15547
|
-
// Do we have pending formats and is the selection moved has moved
|
15548
|
-
if (hasPending() && !tinymce.dom.RangeUtils.compareRanges(pendingFormats.lastRng, selection.getRng())) {
|
15549
|
-
var foundCaret = false;
|
15550
|
-
each(dom.select('font,span'), function(node) {
|
15551
|
-
var textNode, rng;
|
15552
|
-
|
15553
|
-
// Look for marker
|
15554
|
-
if (isCaretNode(node)) {
|
15555
|
-
foundCaret = true;
|
15556
|
-
textNode = node.firstChild;
|
15557
|
-
|
15558
|
-
// Find the first text node within node
|
15559
|
-
while (textNode && textNode.nodeType != 3)
|
15560
|
-
textNode = textNode.firstChild;
|
15561
|
-
|
15562
|
-
if (textNode)
|
15563
|
-
performPendingFormat(node, textNode);
|
15564
|
-
else
|
15565
|
-
dom.remove(node);
|
15566
|
-
}
|
15567
|
-
});
|
15568
|
-
|
15569
|
-
// no caret - so we are
|
15570
|
-
if (enterKeyPressed && !foundCaret) {
|
15571
|
-
var node = selection.getNode();
|
15572
|
-
var textNode = node;
|
15573
|
-
|
15574
|
-
// Find the first text node within node
|
15575
|
-
while (textNode && textNode.nodeType != 3)
|
15576
|
-
textNode = textNode.firstChild;
|
15577
|
-
if (textNode) {
|
15578
|
-
node=textNode.parentNode;
|
15579
|
-
while (!isBlock(node)){
|
15580
|
-
node=node.parentNode;
|
15581
|
-
}
|
15582
|
-
performPendingFormat(node, textNode);
|
15583
|
-
}
|
15584
|
-
}
|
15823
|
+
// Remove caret container on mouse up and on key up
|
15824
|
+
tinymce.each('onMouseUp onKeyUp'.split(' '), function(name) {
|
15825
|
+
ed[name].addToTop(function() {
|
15826
|
+
removeCaretContainer();
|
15827
|
+
});
|
15828
|
+
});
|
15585
15829
|
|
15586
|
-
|
15587
|
-
|
15588
|
-
|
15589
|
-
|
15590
|
-
|
15591
|
-
|
15592
|
-
});
|
15593
|
-
});
|
15830
|
+
// Remove caret container on keydown and it's a backspace, enter or left/right arrow keys
|
15831
|
+
ed.onKeyDown.addToTop(function(ed, e) {
|
15832
|
+
var keyCode = e.keyCode;
|
15833
|
+
|
15834
|
+
if (keyCode == 8 || keyCode == 37 || keyCode == 39) {
|
15835
|
+
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
15594
15836
|
}
|
15837
|
+
});
|
15838
|
+
|
15839
|
+
// Do apply or remove caret format
|
15840
|
+
if (type == "apply") {
|
15841
|
+
applyCaretFormat();
|
15842
|
+
} else {
|
15843
|
+
removeCaretFormat();
|
15595
15844
|
}
|
15596
15845
|
};
|
15597
15846
|
};
|
@@ -15601,7 +15850,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|
15601
15850
|
var filters, fontSizes, dom, settings = ed.settings;
|
15602
15851
|
|
15603
15852
|
if (settings.inline_styles) {
|
15604
|
-
fontSizes = tinymce.explode(settings.
|
15853
|
+
fontSizes = tinymce.explode(settings.font_size_legacy_values);
|
15605
15854
|
|
15606
15855
|
function replaceWithSpan(node, styles) {
|
15607
15856
|
tinymce.each(styles, function(value, name) {
|