tinymce-rails 3.4.6 → 3.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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) {
|