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;
|
@@ -901,8 +901,11 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
901
901
|
|
902
902
|
v = '{';
|
903
903
|
|
904
|
-
for (i in o)
|
905
|
-
|
904
|
+
for (i in o) {
|
905
|
+
if (o.hasOwnProperty(i)) {
|
906
|
+
v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : '';
|
907
|
+
}
|
908
|
+
}
|
906
909
|
|
907
910
|
return v + '}';
|
908
911
|
}
|
@@ -923,6 +926,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
923
926
|
|
924
927
|
};
|
925
928
|
})();
|
929
|
+
|
926
930
|
tinymce.create('static tinymce.util.XHR', {
|
927
931
|
send : function(o) {
|
928
932
|
var x, t, w = window, c = 0;
|
@@ -1038,11 +1042,14 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1038
1042
|
}());
|
1039
1043
|
(function(tinymce){
|
1040
1044
|
tinymce.VK = {
|
1041
|
-
DELETE:46,
|
1042
|
-
BACKSPACE:8
|
1043
|
-
|
1045
|
+
DELETE: 46,
|
1046
|
+
BACKSPACE: 8,
|
1047
|
+
ENTER: 13,
|
1048
|
+
TAB: 9,
|
1049
|
+
SPACEBAR: 32,
|
1050
|
+
UP: 38,
|
1051
|
+
DOWN: 40
|
1044
1052
|
}
|
1045
|
-
|
1046
1053
|
})(tinymce);
|
1047
1054
|
|
1048
1055
|
(function(tinymce) {
|
@@ -1071,7 +1078,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1071
1078
|
node = blockElm.firstChild;
|
1072
1079
|
|
1073
1080
|
// Ignore empty text nodes
|
1074
|
-
while (node.nodeType == 3 && node.nodeValue.length == 0)
|
1081
|
+
while (node && node.nodeType == 3 && node.nodeValue.length == 0)
|
1075
1082
|
node = node.nextSibling;
|
1076
1083
|
|
1077
1084
|
if (node && node.nodeName === 'SPAN') {
|
@@ -1120,6 +1127,21 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1120
1127
|
});
|
1121
1128
|
};
|
1122
1129
|
|
1130
|
+
function removeHrOnBackspace(ed) {
|
1131
|
+
ed.onKeyDown.add(function(ed, e) {
|
1132
|
+
if (e.keyCode === BACKSPACE) {
|
1133
|
+
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
|
1134
|
+
var node = ed.selection.getNode();
|
1135
|
+
var previousSibling = node.previousSibling;
|
1136
|
+
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
|
1137
|
+
ed.dom.remove(previousSibling);
|
1138
|
+
tinymce.dom.Event.cancel(e);
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
}
|
1142
|
+
})
|
1143
|
+
}
|
1144
|
+
|
1123
1145
|
function focusBody(ed) {
|
1124
1146
|
// Fix for a focus bug in FF 3.x where the body element
|
1125
1147
|
// wouldn't get proper focus if the user clicked on the HTML element
|
@@ -1157,6 +1179,31 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1157
1179
|
});
|
1158
1180
|
};
|
1159
1181
|
|
1182
|
+
function selectionChangeNodeChanged(ed) {
|
1183
|
+
var lastRng, selectionTimer;
|
1184
|
+
|
1185
|
+
ed.dom.bind(ed.getDoc(), 'selectionchange', function() {
|
1186
|
+
if (selectionTimer) {
|
1187
|
+
clearTimeout(selectionTimer);
|
1188
|
+
selectionTimer = 0;
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
selectionTimer = window.setTimeout(function() {
|
1192
|
+
var rng = ed.selection.getRng();
|
1193
|
+
|
1194
|
+
// Compare the ranges to see if it was a real change or not
|
1195
|
+
if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) {
|
1196
|
+
ed.nodeChanged();
|
1197
|
+
lastRng = rng;
|
1198
|
+
}
|
1199
|
+
}, 50);
|
1200
|
+
});
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
function ensureBodyHasRoleApplication(ed) {
|
1204
|
+
document.body.setAttribute("role", "application");
|
1205
|
+
}
|
1206
|
+
|
1160
1207
|
tinymce.create('tinymce.util.Quirks', {
|
1161
1208
|
Quirks: function(ed) {
|
1162
1209
|
// WebKit
|
@@ -1165,24 +1212,33 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1165
1212
|
emptyEditorWhenDeleting(ed);
|
1166
1213
|
inputMethodFocus(ed);
|
1167
1214
|
selectControlElements(ed);
|
1215
|
+
|
1216
|
+
// iOS
|
1217
|
+
if (tinymce.isIDevice) {
|
1218
|
+
selectionChangeNodeChanged(ed);
|
1219
|
+
}
|
1168
1220
|
}
|
1169
1221
|
|
1170
1222
|
// IE
|
1171
1223
|
if (tinymce.isIE) {
|
1224
|
+
removeHrOnBackspace(ed);
|
1172
1225
|
emptyEditorWhenDeleting(ed);
|
1226
|
+
ensureBodyHasRoleApplication(ed);
|
1173
1227
|
}
|
1174
1228
|
|
1175
1229
|
// Gecko
|
1176
1230
|
if (tinymce.isGecko) {
|
1231
|
+
removeHrOnBackspace(ed);
|
1177
1232
|
focusBody(ed);
|
1178
1233
|
}
|
1179
1234
|
}
|
1180
1235
|
});
|
1181
1236
|
})(tinymce);
|
1237
|
+
|
1182
1238
|
(function(tinymce) {
|
1183
1239
|
var namedEntities, baseEntities, reverseEntities,
|
1184
|
-
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1185
|
-
textCharsRegExp = /[<>&\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1240
|
+
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1241
|
+
textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
1186
1242
|
rawCharsRegExp = /[<>&\"\']/g,
|
1187
1243
|
entityRegExp = /&(#x|#)?([\w]+);/g,
|
1188
1244
|
asciiMap = {
|
@@ -2168,7 +2224,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|
2168
2224
|
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
|
2169
2225
|
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
|
2170
2226
|
'(?:\\/([^>]+)>)|' + // End element
|
2171
|
-
'(?:([^\\s\\/<>]+)
|
2227
|
+
'(?:([^\\s\\/<>]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/)>)' + // Start element
|
2172
2228
|
')', 'g');
|
2173
2229
|
|
2174
2230
|
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
|
@@ -3873,48 +3929,48 @@ tinymce.html.Writer = function(settings) {
|
|
3873
3929
|
|
3874
3930
|
return this.run(e, function(e) {
|
3875
3931
|
var s = t.settings;
|
3932
|
+
if (v !== null) {
|
3933
|
+
switch (n) {
|
3934
|
+
case "style":
|
3935
|
+
if (!is(v, 'string')) {
|
3936
|
+
each(v, function(v, n) {
|
3937
|
+
t.setStyle(e, n, v);
|
3938
|
+
});
|
3876
3939
|
|
3877
|
-
|
3878
|
-
|
3879
|
-
if (!is(v, 'string')) {
|
3880
|
-
each(v, function(v, n) {
|
3881
|
-
t.setStyle(e, n, v);
|
3882
|
-
});
|
3883
|
-
|
3884
|
-
return;
|
3885
|
-
}
|
3940
|
+
return;
|
3941
|
+
}
|
3886
3942
|
|
3887
|
-
|
3888
|
-
|
3889
|
-
|
3890
|
-
|
3891
|
-
|
3892
|
-
|
3893
|
-
|
3943
|
+
// No mce_style for elements with these since they might get resized by the user
|
3944
|
+
if (s.keep_values) {
|
3945
|
+
if (v && !t._isRes(v))
|
3946
|
+
e.setAttribute('data-mce-style', v, 2);
|
3947
|
+
else
|
3948
|
+
e.removeAttribute('data-mce-style', 2);
|
3949
|
+
}
|
3894
3950
|
|
3895
|
-
|
3896
|
-
|
3951
|
+
e.style.cssText = v;
|
3952
|
+
break;
|
3897
3953
|
|
3898
|
-
|
3899
|
-
|
3900
|
-
|
3954
|
+
case "class":
|
3955
|
+
e.className = v || ''; // Fix IE null bug
|
3956
|
+
break;
|
3901
3957
|
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
3958
|
+
case "src":
|
3959
|
+
case "href":
|
3960
|
+
if (s.keep_values) {
|
3961
|
+
if (s.url_converter)
|
3962
|
+
v = s.url_converter.call(s.url_converter_scope || t, v, n, e);
|
3907
3963
|
|
3908
|
-
|
3909
|
-
|
3964
|
+
t.setAttrib(e, 'data-mce-' + n, v, 2);
|
3965
|
+
}
|
3910
3966
|
|
3911
|
-
|
3967
|
+
break;
|
3912
3968
|
|
3913
|
-
|
3914
|
-
|
3915
|
-
|
3969
|
+
case "shape":
|
3970
|
+
e.setAttribute('data-mce-style', v);
|
3971
|
+
break;
|
3972
|
+
}
|
3916
3973
|
}
|
3917
|
-
|
3918
3974
|
if (is(v) && v !== null && v.length !== 0)
|
3919
3975
|
e.setAttribute(n, '' + v, 2);
|
3920
3976
|
else
|
@@ -5690,7 +5746,7 @@ tinymce.html.Writer = function(settings) {
|
|
5690
5746
|
parent = node.parentNode;
|
5691
5747
|
root = dom.getRoot().parentNode;
|
5692
5748
|
|
5693
|
-
while (parent != root) {
|
5749
|
+
while (parent != root && parent.nodeType !== 9) {
|
5694
5750
|
children = parent.children;
|
5695
5751
|
|
5696
5752
|
i = children.length;
|
@@ -8069,7 +8125,8 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8069
8125
|
if (sb && eb && sb != eb) {
|
8070
8126
|
n = sb;
|
8071
8127
|
|
8072
|
-
|
8128
|
+
var walker = new tinymce.dom.TreeWalker(sb, dom.getRoot());
|
8129
|
+
while ((n = walker.next()) && n != eb) {
|
8073
8130
|
if (dom.isBlock(n))
|
8074
8131
|
bl.push(n);
|
8075
8132
|
}
|
@@ -8475,7 +8532,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8475
8532
|
|
8476
8533
|
// Replace all BOM characters for now until we can find a better solution
|
8477
8534
|
if (!args.cleanup)
|
8478
|
-
args.content = args.content.replace(/\uFEFF/g, '');
|
8535
|
+
args.content = args.content.replace(/\uFEFF|\u200B/g, '');
|
8479
8536
|
|
8480
8537
|
// Post process
|
8481
8538
|
if (!args.no_events)
|
@@ -8769,6 +8826,24 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8769
8826
|
return;
|
8770
8827
|
}
|
8771
8828
|
|
8829
|
+
function exclude(nodes) {
|
8830
|
+
var node;
|
8831
|
+
|
8832
|
+
// First node is excluded
|
8833
|
+
node = nodes[0];
|
8834
|
+
if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {
|
8835
|
+
nodes.splice(0, 1);
|
8836
|
+
}
|
8837
|
+
|
8838
|
+
// Last node is excluded
|
8839
|
+
node = nodes[nodes.length - 1];
|
8840
|
+
if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {
|
8841
|
+
nodes.splice(nodes.length - 1, 1);
|
8842
|
+
}
|
8843
|
+
|
8844
|
+
return nodes;
|
8845
|
+
};
|
8846
|
+
|
8772
8847
|
function collectSiblings(node, name, end_node) {
|
8773
8848
|
var siblings = [];
|
8774
8849
|
|
@@ -8798,7 +8873,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8798
8873
|
if (!next)
|
8799
8874
|
siblings.reverse();
|
8800
8875
|
|
8801
|
-
callback(siblings);
|
8876
|
+
callback(exclude(siblings));
|
8802
8877
|
}
|
8803
8878
|
}
|
8804
8879
|
};
|
@@ -8811,28 +8886,28 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8811
8886
|
if (endContainer.nodeType == 1 && endContainer.hasChildNodes())
|
8812
8887
|
endContainer = endContainer.childNodes[Math.min(endOffset - 1, endContainer.childNodes.length - 1)];
|
8813
8888
|
|
8814
|
-
// Find common ancestor and end points
|
8815
|
-
ancestor = dom.findCommonAncestor(startContainer, endContainer);
|
8816
|
-
|
8817
8889
|
// Same container
|
8818
8890
|
if (startContainer == endContainer)
|
8819
|
-
return callback([startContainer]);
|
8891
|
+
return callback(exclude([startContainer]));
|
8820
8892
|
|
8893
|
+
// Find common ancestor and end points
|
8894
|
+
ancestor = dom.findCommonAncestor(startContainer, endContainer);
|
8895
|
+
|
8821
8896
|
// Process left side
|
8822
8897
|
for (node = startContainer; node; node = node.parentNode) {
|
8823
|
-
if (node
|
8898
|
+
if (node === endContainer)
|
8824
8899
|
return walkBoundary(startContainer, ancestor, true);
|
8825
8900
|
|
8826
|
-
if (node
|
8901
|
+
if (node === ancestor)
|
8827
8902
|
break;
|
8828
8903
|
}
|
8829
8904
|
|
8830
8905
|
// Process right side
|
8831
8906
|
for (node = endContainer; node; node = node.parentNode) {
|
8832
|
-
if (node
|
8907
|
+
if (node === startContainer)
|
8833
8908
|
return walkBoundary(endContainer, ancestor);
|
8834
8909
|
|
8835
|
-
if (node
|
8910
|
+
if (node === ancestor)
|
8836
8911
|
break;
|
8837
8912
|
}
|
8838
8913
|
|
@@ -8851,48 +8926,46 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8851
8926
|
);
|
8852
8927
|
|
8853
8928
|
if (siblings.length)
|
8854
|
-
callback(siblings);
|
8929
|
+
callback(exclude(siblings));
|
8855
8930
|
|
8856
8931
|
// Walk right leaf
|
8857
8932
|
walkBoundary(endContainer, endPoint);
|
8858
8933
|
};
|
8859
8934
|
|
8860
|
-
|
8935
|
+
this.split = function(rng) {
|
8861
8936
|
var startContainer = rng.startContainer,
|
8862
8937
|
startOffset = rng.startOffset,
|
8863
8938
|
endContainer = rng.endContainer,
|
8864
8939
|
endOffset = rng.endOffset;
|
8865
8940
|
|
8866
8941
|
function splitText(node, offset) {
|
8867
|
-
|
8868
|
-
node.appendData(INVISIBLE_CHAR);
|
8869
|
-
|
8870
|
-
node = node.splitText(offset);
|
8871
|
-
|
8872
|
-
if (node.nodeValue === INVISIBLE_CHAR)
|
8873
|
-
node.nodeValue = '';
|
8874
|
-
|
8875
|
-
return node;
|
8942
|
+
return node.splitText(offset);
|
8876
8943
|
};
|
8877
8944
|
|
8878
8945
|
// Handle single text node
|
8879
|
-
if (startContainer == endContainer) {
|
8880
|
-
if (startContainer.
|
8881
|
-
|
8882
|
-
|
8883
|
-
|
8884
|
-
if (endOffset
|
8885
|
-
|
8946
|
+
if (startContainer == endContainer && startContainer.nodeType == 3) {
|
8947
|
+
if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
|
8948
|
+
endContainer = splitText(startContainer, startOffset);
|
8949
|
+
startContainer = endContainer.previousSibling;
|
8950
|
+
|
8951
|
+
if (endOffset > startOffset) {
|
8952
|
+
endOffset = endOffset - startOffset;
|
8953
|
+
startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
|
8954
|
+
endOffset = endContainer.nodeValue.length;
|
8955
|
+
startOffset = 0;
|
8956
|
+
} else {
|
8957
|
+
endOffset = 0;
|
8958
|
+
}
|
8886
8959
|
}
|
8887
8960
|
} else {
|
8888
8961
|
// Split startContainer text node if needed
|
8889
|
-
if (startContainer.nodeType == 3 && startOffset
|
8962
|
+
if (startContainer.nodeType == 3 && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
|
8890
8963
|
startContainer = splitText(startContainer, startOffset);
|
8891
8964
|
startOffset = 0;
|
8892
8965
|
}
|
8893
8966
|
|
8894
8967
|
// Split endContainer text node if needed
|
8895
|
-
if (endContainer.nodeType == 3 && endOffset
|
8968
|
+
if (endContainer.nodeType == 3 && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
|
8896
8969
|
endContainer = splitText(endContainer, endOffset).previousSibling;
|
8897
8970
|
endOffset = endContainer.nodeValue.length;
|
8898
8971
|
}
|
@@ -8905,7 +8978,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
|
|
8905
8978
|
endOffset : endOffset
|
8906
8979
|
};
|
8907
8980
|
};
|
8908
|
-
|
8981
|
+
|
8909
8982
|
};
|
8910
8983
|
|
8911
8984
|
tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {
|
@@ -11192,6 +11265,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11192
11265
|
visual_table_class : 'mceItemTable',
|
11193
11266
|
visual : 1,
|
11194
11267
|
font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
11268
|
+
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
|
11195
11269
|
apply_source_formatting : 1,
|
11196
11270
|
directionality : 'ltr',
|
11197
11271
|
forced_root_block : 'p',
|
@@ -11623,10 +11697,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11623
11697
|
|
11624
11698
|
// Keep scripts from executing
|
11625
11699
|
t.parser.addNodeFilter('script', function(nodes, name) {
|
11626
|
-
var i = nodes.length;
|
11700
|
+
var i = nodes.length, node;
|
11627
11701
|
|
11628
|
-
while (i--)
|
11629
|
-
nodes[i]
|
11702
|
+
while (i--) {
|
11703
|
+
node = nodes[i];
|
11704
|
+
node.attr('type', 'mce-' + (node.attr('type') || 'text/javascript'));
|
11705
|
+
}
|
11630
11706
|
});
|
11631
11707
|
|
11632
11708
|
t.parser.addNodeFilter('#cdata', function(nodes, name) {
|
@@ -12967,21 +13043,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12967
13043
|
});
|
12968
13044
|
}
|
12969
13045
|
|
12970
|
-
// Fire a nodeChanged when the selection is changed on WebKit this fixes selection issues on iOS5
|
12971
|
-
// It only fires the nodeChange event every 50ms since it would other wise update the UI when you type and it hogs the CPU
|
12972
|
-
if (tinymce.isWebKit) {
|
12973
|
-
dom.bind(t.getDoc(), 'selectionchange', function() {
|
12974
|
-
if (t.selectionTimer) {
|
12975
|
-
clearTimeout(t.selectionTimer);
|
12976
|
-
t.selectionTimer = 0;
|
12977
|
-
}
|
12978
|
-
|
12979
|
-
t.selectionTimer = window.setTimeout(function() {
|
12980
|
-
t.nodeChanged();
|
12981
|
-
}, 50);
|
12982
|
-
});
|
12983
|
-
}
|
12984
|
-
|
12985
13046
|
// Bug fix for FireFox keeping styles from end of selection instead of start.
|
12986
13047
|
if (tinymce.isGecko) {
|
12987
13048
|
function getAttributeApplyFunction() {
|
@@ -12991,7 +13052,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12991
13052
|
var target = t.selection.getStart();
|
12992
13053
|
|
12993
13054
|
if (target !== t.getBody()) {
|
12994
|
-
t.dom.
|
13055
|
+
t.dom.setAttrib(target, "style", null);
|
12995
13056
|
|
12996
13057
|
each(template, function(attr) {
|
12997
13058
|
target.setAttributeNode(attr.cloneNode(true));
|
@@ -14844,8 +14905,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14844
14905
|
MCE_ATTR_RE = /^(src|href|style)$/,
|
14845
14906
|
FALSE = false,
|
14846
14907
|
TRUE = true,
|
14847
|
-
undefined
|
14848
|
-
pendingFormats = {apply : [], remove : []};
|
14908
|
+
undefined;
|
14849
14909
|
|
14850
14910
|
function isArray(obj) {
|
14851
14911
|
return obj instanceof Array;
|
@@ -15061,7 +15121,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15061
15121
|
}
|
15062
15122
|
};
|
15063
15123
|
|
15064
|
-
function applyRngStyle(rng, bookmark) {
|
15124
|
+
function applyRngStyle(rng, bookmark, node_specific) {
|
15065
15125
|
var newWrappers = [], wrapName, wrapElm;
|
15066
15126
|
|
15067
15127
|
// Setup wrapper element
|
@@ -15125,7 +15185,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15125
15185
|
|
15126
15186
|
// Is it valid to wrap this item
|
15127
15187
|
if (isValid(wrapName, nodeName) && isValid(parentName, wrapName) &&
|
15128
|
-
!(node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279)) {
|
15188
|
+
!(!node_specific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && node.id !== '_mce_caret') {
|
15129
15189
|
// Start wrapping
|
15130
15190
|
if (!currentWrapElm) {
|
15131
15191
|
// Wrap the node
|
@@ -15280,12 +15340,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15280
15340
|
|
15281
15341
|
if (format) {
|
15282
15342
|
if (node) {
|
15283
|
-
|
15284
|
-
|
15285
|
-
|
15286
|
-
|
15287
|
-
|
15288
|
-
|
15343
|
+
if (node.nodeType) {
|
15344
|
+
rng = dom.createRng();
|
15345
|
+
rng.setStartBefore(node);
|
15346
|
+
rng.setEndAfter(node);
|
15347
|
+
applyRngStyle(expandRng(rng, formatList), null, true);
|
15348
|
+
} else {
|
15349
|
+
applyRngStyle(node, null, true);
|
15350
|
+
}
|
15289
15351
|
} else {
|
15290
15352
|
if (!isCollapsed || !format.inline || dom.select('td.mceSelected,th.mceSelected').length) {
|
15291
15353
|
// Obtain selection node before selection is unselected by applyRngStyle()
|
@@ -15499,10 +15561,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15499
15561
|
|
15500
15562
|
// Handle node
|
15501
15563
|
if (node) {
|
15502
|
-
|
15503
|
-
|
15504
|
-
|
15505
|
-
|
15564
|
+
if (node.nodeType) {
|
15565
|
+
rng = dom.createRng();
|
15566
|
+
rng.setStartBefore(node);
|
15567
|
+
rng.setEndAfter(node);
|
15568
|
+
removeRngStyle(rng);
|
15569
|
+
} else {
|
15570
|
+
removeRngStyle(node);
|
15571
|
+
}
|
15572
|
+
|
15506
15573
|
return;
|
15507
15574
|
}
|
15508
15575
|
|
@@ -15519,6 +15586,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15519
15586
|
ed.nodeChanged();
|
15520
15587
|
} else
|
15521
15588
|
performCaretAction('remove', name, vars);
|
15589
|
+
|
15590
|
+
// 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
|
15591
|
+
if (tinymce.isWebKit) {
|
15592
|
+
ed.execCommand('mceCleanup');
|
15593
|
+
}
|
15522
15594
|
};
|
15523
15595
|
|
15524
15596
|
function toggle(name, vars, node) {
|
@@ -15593,7 +15665,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15593
15665
|
};
|
15594
15666
|
|
15595
15667
|
function match(name, vars, node) {
|
15596
|
-
var startNode
|
15668
|
+
var startNode;
|
15597
15669
|
|
15598
15670
|
function matchParents(node) {
|
15599
15671
|
// Find first node with similar format settings
|
@@ -15609,21 +15681,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15609
15681
|
if (node)
|
15610
15682
|
return matchParents(node);
|
15611
15683
|
|
15612
|
-
// Check pending formats
|
15613
|
-
if (selection.isCollapsed()) {
|
15614
|
-
for (i = pendingFormats.apply.length - 1; i >= 0; i--) {
|
15615
|
-
if (pendingFormats.apply[i].name == name)
|
15616
|
-
return true;
|
15617
|
-
}
|
15618
|
-
|
15619
|
-
for (i = pendingFormats.remove.length - 1; i >= 0; i--) {
|
15620
|
-
if (pendingFormats.remove[i].name == name)
|
15621
|
-
return false;
|
15622
|
-
}
|
15623
|
-
|
15624
|
-
return matchParents(selection.getNode());
|
15625
|
-
}
|
15626
|
-
|
15627
15684
|
// Check selected node
|
15628
15685
|
node = selection.getNode();
|
15629
15686
|
if (matchParents(node))
|
@@ -15642,33 +15699,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15642
15699
|
function matchAll(names, vars) {
|
15643
15700
|
var startElement, matchedFormatNames = [], checkedMap = {}, i, ni, name;
|
15644
15701
|
|
15645
|
-
// If the selection is collapsed then check pending formats
|
15646
|
-
if (selection.isCollapsed()) {
|
15647
|
-
for (ni = 0; ni < names.length; ni++) {
|
15648
|
-
// If the name is to be removed, then stop it from being added
|
15649
|
-
for (i = pendingFormats.remove.length - 1; i >= 0; i--) {
|
15650
|
-
name = names[ni];
|
15651
|
-
|
15652
|
-
if (pendingFormats.remove[i].name == name) {
|
15653
|
-
checkedMap[name] = true;
|
15654
|
-
break;
|
15655
|
-
}
|
15656
|
-
}
|
15657
|
-
}
|
15658
|
-
|
15659
|
-
// If the format is to be applied
|
15660
|
-
for (i = pendingFormats.apply.length - 1; i >= 0; i--) {
|
15661
|
-
for (ni = 0; ni < names.length; ni++) {
|
15662
|
-
name = names[ni];
|
15663
|
-
|
15664
|
-
if (!checkedMap[name] && pendingFormats.apply[i].name == name) {
|
15665
|
-
checkedMap[name] = true;
|
15666
|
-
matchedFormatNames.push(name);
|
15667
|
-
}
|
15668
|
-
}
|
15669
|
-
}
|
15670
|
-
}
|
15671
|
-
|
15672
15702
|
// Check start of selection for formats
|
15673
15703
|
startElement = selection.getStart();
|
15674
15704
|
dom.getParent(startElement, function(node) {
|
@@ -15777,7 +15807,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15777
15807
|
};
|
15778
15808
|
|
15779
15809
|
function isWhiteSpaceNode(node) {
|
15780
|
-
return node && node.nodeType === 3 && /^([\
|
15810
|
+
return node && node.nodeType === 3 && /^([\t \r\n]+|)$/.test(node.nodeValue);
|
15781
15811
|
};
|
15782
15812
|
|
15783
15813
|
function wrap(node, name, attrs) {
|
@@ -15793,31 +15823,37 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15793
15823
|
var startContainer = rng.startContainer,
|
15794
15824
|
startOffset = rng.startOffset,
|
15795
15825
|
endContainer = rng.endContainer,
|
15796
|
-
endOffset = rng.endOffset, sibling, lastIdx, leaf;
|
15826
|
+
endOffset = rng.endOffset, sibling, lastIdx, leaf, endPoint;
|
15797
15827
|
|
15798
15828
|
// This function walks up the tree if there is no siblings before/after the node
|
15799
|
-
function findParentContainer(
|
15800
|
-
var parent, child;
|
15829
|
+
function findParentContainer(start) {
|
15830
|
+
var container, parent, child, sibling, siblingName;
|
15801
15831
|
|
15802
|
-
|
15832
|
+
container = parent = start ? startContainer : endContainer;
|
15833
|
+
siblingName = start ? 'previousSibling' : 'nextSibling';
|
15834
|
+
root = dom.getRoot();
|
15803
15835
|
|
15804
|
-
|
15805
|
-
|
15806
|
-
|
15836
|
+
// If it's a text node and the offset is inside the text
|
15837
|
+
if (container.nodeType == 3 && !isWhiteSpaceNode(container)) {
|
15838
|
+
if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
|
15839
|
+
return container;
|
15840
|
+
}
|
15841
|
+
}
|
15807
15842
|
|
15843
|
+
for (;;) {
|
15808
15844
|
// Stop expanding on block elements or root depending on format
|
15809
15845
|
if (parent == root || (!format[0].block_expand && isBlock(parent)))
|
15810
|
-
return
|
15846
|
+
return parent;
|
15811
15847
|
|
15812
|
-
|
15813
|
-
|
15814
|
-
|
15815
|
-
|
15816
|
-
|
15817
|
-
return container;
|
15848
|
+
// Walk left/right
|
15849
|
+
for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
|
15850
|
+
if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling)) {
|
15851
|
+
return parent;
|
15852
|
+
}
|
15818
15853
|
}
|
15819
15854
|
|
15820
|
-
|
15855
|
+
// Check if we can move up are we at root level or body level
|
15856
|
+
parent = parent.parentNode;
|
15821
15857
|
}
|
15822
15858
|
|
15823
15859
|
return container;
|
@@ -15855,23 +15891,103 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15855
15891
|
}
|
15856
15892
|
|
15857
15893
|
// Exclude bookmark nodes if possible
|
15858
|
-
if (isBookmarkNode(startContainer.parentNode))
|
15859
|
-
startContainer = startContainer.parentNode;
|
15860
|
-
|
15861
|
-
if (isBookmarkNode(startContainer))
|
15894
|
+
if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) {
|
15895
|
+
startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;
|
15862
15896
|
startContainer = startContainer.nextSibling || startContainer;
|
15863
15897
|
|
15864
|
-
|
15865
|
-
|
15866
|
-
endContainer = endContainer.parentNode;
|
15898
|
+
if (startContainer.nodeType == 3)
|
15899
|
+
startOffset = 0;
|
15867
15900
|
}
|
15868
15901
|
|
15869
|
-
if (isBookmarkNode(endContainer)
|
15870
|
-
endContainer = endContainer.
|
15871
|
-
|
15902
|
+
if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) {
|
15903
|
+
endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;
|
15904
|
+
endContainer = endContainer.previousSibling || endContainer;
|
15905
|
+
|
15906
|
+
if (endContainer.nodeType == 3)
|
15907
|
+
endOffset = endContainer.length;
|
15872
15908
|
}
|
15873
15909
|
|
15874
15910
|
if (format[0].inline) {
|
15911
|
+
if (rng.collapsed) {
|
15912
|
+
function findWordEndPoint(container, offset, start) {
|
15913
|
+
var walker, node, pos, lastTextNode;
|
15914
|
+
|
15915
|
+
function findSpace(node, offset) {
|
15916
|
+
var pos, pos2, str = node.nodeValue;
|
15917
|
+
|
15918
|
+
if (typeof(offset) == "undefined") {
|
15919
|
+
offset = start ? str.length : 0;
|
15920
|
+
}
|
15921
|
+
|
15922
|
+
if (start) {
|
15923
|
+
pos = str.lastIndexOf(' ', offset);
|
15924
|
+
pos2 = str.lastIndexOf('\u00a0', offset);
|
15925
|
+
pos = pos > pos2 ? pos : pos2;
|
15926
|
+
|
15927
|
+
// Include the space on remove to avoid tag soup
|
15928
|
+
if (pos !== -1 && !remove) {
|
15929
|
+
pos++;
|
15930
|
+
}
|
15931
|
+
} else {
|
15932
|
+
pos = str.indexOf(' ', offset);
|
15933
|
+
pos2 = str.indexOf('\u00a0', offset);
|
15934
|
+
pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;
|
15935
|
+
}
|
15936
|
+
|
15937
|
+
return pos;
|
15938
|
+
};
|
15939
|
+
|
15940
|
+
if (container.nodeType === 3) {
|
15941
|
+
pos = findSpace(container, offset);
|
15942
|
+
|
15943
|
+
if (pos !== -1) {
|
15944
|
+
return {container : container, offset : pos};
|
15945
|
+
}
|
15946
|
+
|
15947
|
+
lastTextNode = container;
|
15948
|
+
}
|
15949
|
+
|
15950
|
+
// Walk the nodes inside the block
|
15951
|
+
walker = new TreeWalker(container, dom.getParent(container, isBlock) || ed.getBody());
|
15952
|
+
while (node = walker[start ? 'prev' : 'next']()) {
|
15953
|
+
if (node.nodeType === 3) {
|
15954
|
+
lastTextNode = node;
|
15955
|
+
pos = findSpace(node);
|
15956
|
+
|
15957
|
+
if (pos !== -1) {
|
15958
|
+
return {container : node, offset : pos};
|
15959
|
+
}
|
15960
|
+
} else if (isBlock(node)) {
|
15961
|
+
break;
|
15962
|
+
}
|
15963
|
+
}
|
15964
|
+
|
15965
|
+
if (lastTextNode) {
|
15966
|
+
if (start) {
|
15967
|
+
offset = 0;
|
15968
|
+
} else {
|
15969
|
+
offset = lastTextNode.length;
|
15970
|
+
}
|
15971
|
+
|
15972
|
+
return {container: lastTextNode, offset: offset};
|
15973
|
+
}
|
15974
|
+
}
|
15975
|
+
|
15976
|
+
// Expand left to closest word boundery
|
15977
|
+
endPoint = findWordEndPoint(startContainer, startOffset, true);
|
15978
|
+
if (endPoint) {
|
15979
|
+
startContainer = endPoint.container;
|
15980
|
+
startOffset = endPoint.offset;
|
15981
|
+
}
|
15982
|
+
|
15983
|
+
// Expand right to closest word boundery
|
15984
|
+
endPoint = findWordEndPoint(endContainer, endOffset);
|
15985
|
+
if (endPoint) {
|
15986
|
+
endContainer = endPoint.container;
|
15987
|
+
endOffset = endPoint.offset;
|
15988
|
+
}
|
15989
|
+
}
|
15990
|
+
|
15875
15991
|
// Avoid applying formatting to a trailing space.
|
15876
15992
|
leaf = findLeaf(endContainer, endOffset);
|
15877
15993
|
if (leaf.node) {
|
@@ -15885,19 +16001,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15885
16001
|
endContainer = leaf.node;
|
15886
16002
|
endContainer.splitText(leaf.offset - 1);
|
15887
16003
|
} else if (leaf.node.previousSibling) {
|
15888
|
-
|
16004
|
+
// TODO: Figure out why this is in here
|
16005
|
+
//endContainer = leaf.node.previousSibling;
|
15889
16006
|
}
|
15890
16007
|
}
|
15891
16008
|
}
|
15892
16009
|
}
|
15893
|
-
|
16010
|
+
|
15894
16011
|
// Move start/end point up the tree if the leaves are sharp and if we are in different containers
|
15895
16012
|
// Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>!
|
15896
16013
|
// This will reduce the number of wrapper elements that needs to be created
|
15897
16014
|
// Move start point up the tree
|
15898
16015
|
if (format[0].inline || format[0].block_expand) {
|
15899
|
-
|
15900
|
-
|
16016
|
+
if (!format[0].inline || (startContainer.nodeType != 3 || startOffset === 0)) {
|
16017
|
+
startContainer = findParentContainer(true);
|
16018
|
+
}
|
16019
|
+
|
16020
|
+
if (!format[0].inline || (endContainer.nodeType != 3 || endOffset === endContainer.nodeValue.length)) {
|
16021
|
+
endContainer = findParentContainer();
|
16022
|
+
}
|
15901
16023
|
}
|
15902
16024
|
|
15903
16025
|
// Expand start/end container to matching selector
|
@@ -15971,10 +16093,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15971
16093
|
// Non block element then try to expand up the leaf
|
15972
16094
|
if (format[0].block) {
|
15973
16095
|
if (!isBlock(startContainer))
|
15974
|
-
startContainer = findParentContainer(
|
16096
|
+
startContainer = findParentContainer(true);
|
15975
16097
|
|
15976
16098
|
if (!isBlock(endContainer))
|
15977
|
-
endContainer = findParentContainer(
|
16099
|
+
endContainer = findParentContainer();
|
15978
16100
|
}
|
15979
16101
|
}
|
15980
16102
|
|
@@ -16267,7 +16389,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
16267
16389
|
};
|
16268
16390
|
|
16269
16391
|
function getContainer(rng, start) {
|
16270
|
-
var container, offset, lastIdx;
|
16392
|
+
var container, offset, lastIdx, walker;
|
16271
16393
|
|
16272
16394
|
container = rng[start ? 'startContainer' : 'endContainer'];
|
16273
16395
|
offset = rng[start ? 'startOffset' : 'endOffset'];
|
@@ -16281,140 +16403,267 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
16281
16403
|
container = container.childNodes[offset > lastIdx ? lastIdx : offset];
|
16282
16404
|
}
|
16283
16405
|
|
16406
|
+
// If start text node is excluded then walk to the next node
|
16407
|
+
if (container.nodeType === 3 && start && offset >= container.nodeValue.length) {
|
16408
|
+
container = new TreeWalker(container, ed.getBody()).next() || container;
|
16409
|
+
}
|
16410
|
+
|
16411
|
+
// If end text node is excluded then walk to the previous node
|
16412
|
+
if (container.nodeType === 3 && !start && offset == 0) {
|
16413
|
+
container = new TreeWalker(container, ed.getBody()).prev() || container;
|
16414
|
+
}
|
16415
|
+
|
16284
16416
|
return container;
|
16285
16417
|
};
|
16286
16418
|
|
16287
16419
|
function performCaretAction(type, name, vars) {
|
16288
|
-
var
|
16289
|
-
|
16420
|
+
var invisibleChar, caretContainerId = '_mce_caret', debug = ed.settings.caret_debug;
|
16421
|
+
|
16422
|
+
// Setup invisible character use zero width space on Gecko since it doesn't change the heigt of the container
|
16423
|
+
invisibleChar = tinymce.isGecko ? '\u200B' : INVISIBLE_CHAR;
|
16290
16424
|
|
16291
|
-
|
16292
|
-
|
16425
|
+
// Creates a caret container bogus element
|
16426
|
+
function createCaretContainer(fill) {
|
16427
|
+
var caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style: debug ? 'color:red' : ''});
|
16428
|
+
|
16429
|
+
if (fill) {
|
16430
|
+
caretContainer.appendChild(ed.getDoc().createTextNode(invisibleChar));
|
16431
|
+
}
|
16432
|
+
|
16433
|
+
return caretContainer;
|
16293
16434
|
};
|
16294
16435
|
|
16295
|
-
function
|
16296
|
-
|
16297
|
-
|
16436
|
+
function isCaretContainerEmpty(node, nodes) {
|
16437
|
+
while (node) {
|
16438
|
+
if ((node.nodeType === 3 && node.nodeValue !== invisibleChar) || node.childNodes.length > 1) {
|
16439
|
+
return false;
|
16440
|
+
}
|
16441
|
+
|
16442
|
+
// Collect nodes
|
16443
|
+
if (nodes && node.nodeType === 1) {
|
16444
|
+
nodes.push(node);
|
16445
|
+
}
|
16446
|
+
|
16447
|
+
node = node.firstChild;
|
16448
|
+
}
|
16449
|
+
|
16450
|
+
return true;
|
16298
16451
|
};
|
16452
|
+
|
16453
|
+
// Returns any parent caret container element
|
16454
|
+
function getParentCaretContainer(node) {
|
16455
|
+
while (node) {
|
16456
|
+
if (node.id === caretContainerId) {
|
16457
|
+
return node;
|
16458
|
+
}
|
16299
16459
|
|
16300
|
-
|
16301
|
-
|
16302
|
-
|
16303
|
-
apply(item.name, item.vars, caret_node);
|
16460
|
+
node = node.parentNode;
|
16461
|
+
}
|
16462
|
+
};
|
16304
16463
|
|
16305
|
-
|
16306
|
-
|
16307
|
-
|
16308
|
-
});
|
16464
|
+
// Finds the first text node in the specified node
|
16465
|
+
function findFirstTextNode(node) {
|
16466
|
+
var walker;
|
16309
16467
|
|
16310
|
-
|
16311
|
-
|
16312
|
-
|
16313
|
-
|
16468
|
+
if (node) {
|
16469
|
+
walker = new TreeWalker(node, node);
|
16470
|
+
|
16471
|
+
for (node = walker.current(); node; node = walker.next()) {
|
16472
|
+
if (node.nodeType === 3) {
|
16473
|
+
return node;
|
16474
|
+
}
|
16475
|
+
}
|
16476
|
+
}
|
16477
|
+
};
|
16478
|
+
|
16479
|
+
// Removes the caret container for the specified node or all on the current document
|
16480
|
+
function removeCaretContainer(node, move_caret) {
|
16481
|
+
var child, rng;
|
16482
|
+
|
16483
|
+
if (!node) {
|
16484
|
+
node = getParentCaretContainer(selection.getStart());
|
16485
|
+
|
16486
|
+
if (!node) {
|
16487
|
+
while (node = dom.get(caretContainerId)) {
|
16488
|
+
removeCaretContainer(node, false);
|
16489
|
+
}
|
16490
|
+
}
|
16491
|
+
} else {
|
16492
|
+
rng = selection.getRng(true);
|
16493
|
+
|
16494
|
+
if (isCaretContainerEmpty(node)) {
|
16495
|
+
if (move_caret !== false) {
|
16496
|
+
rng.setStartBefore(node);
|
16497
|
+
rng.setEndBefore(node);
|
16498
|
+
}
|
16499
|
+
|
16500
|
+
dom.remove(node);
|
16501
|
+
} else {
|
16502
|
+
child = findFirstTextNode(node);
|
16503
|
+
child = child.deleteData(0, 1);
|
16504
|
+
dom.remove(node, 1);
|
16505
|
+
}
|
16506
|
+
|
16507
|
+
selection.setRng(rng);
|
16508
|
+
}
|
16509
|
+
};
|
16510
|
+
|
16511
|
+
// Applies formatting to the caret postion
|
16512
|
+
function applyCaretFormat() {
|
16513
|
+
var rng, caretContainer, textNode, offset, bookmark, container, text;
|
16514
|
+
|
16515
|
+
rng = selection.getRng(true);
|
16516
|
+
offset = rng.startOffset;
|
16517
|
+
container = rng.startContainer;
|
16518
|
+
text = container.nodeValue;
|
16519
|
+
|
16520
|
+
caretContainer = getParentCaretContainer(selection.getStart());
|
16521
|
+
if (caretContainer) {
|
16522
|
+
textNode = findFirstTextNode(caretContainer);
|
16523
|
+
}
|
16524
|
+
|
16525
|
+
// Expand to word is caret is in the middle of a text node and the char before/after is a alpha numeric character
|
16526
|
+
if (text && offset > 0 && offset < text.length && /\w/.test(text.charAt(offset)) && /\w/.test(text.charAt(offset - 1))) {
|
16527
|
+
// Get bookmark of caret position
|
16528
|
+
bookmark = selection.getBookmark();
|
16529
|
+
|
16530
|
+
// Collapse bookmark range (WebKit)
|
16531
|
+
rng.collapse(true);
|
16532
|
+
|
16533
|
+
// Expand the range to the closest word and split it at those points
|
16534
|
+
rng = expandRng(rng, get(name));
|
16535
|
+
rng = rangeUtils.split(rng);
|
16536
|
+
|
16537
|
+
// Apply the format to the range
|
16538
|
+
apply(name, vars, rng);
|
16539
|
+
|
16540
|
+
// Move selection back to caret position
|
16541
|
+
selection.moveToBookmark(bookmark);
|
16542
|
+
} else {
|
16543
|
+
if (!caretContainer || textNode.nodeValue !== invisibleChar) {
|
16544
|
+
caretContainer = createCaretContainer(true);
|
16545
|
+
textNode = caretContainer.firstChild;
|
16546
|
+
|
16547
|
+
rng.insertNode(caretContainer);
|
16548
|
+
offset = 1;
|
16549
|
+
|
16550
|
+
apply(name, vars, caretContainer);
|
16551
|
+
} else {
|
16552
|
+
apply(name, vars, caretContainer);
|
16553
|
+
}
|
16314
16554
|
|
16315
|
-
|
16316
|
-
|
16555
|
+
// Move selection to text node
|
16556
|
+
selection.setCursorLocation(textNode, offset);
|
16557
|
+
}
|
16317
16558
|
};
|
16318
16559
|
|
16319
|
-
|
16320
|
-
|
16321
|
-
|
16560
|
+
function removeCaretFormat() {
|
16561
|
+
var rng = selection.getRng(true), container, offset, bookmark,
|
16562
|
+
hasContentAfter, node, formatNode, parents = [], i, caretContainer;
|
16563
|
+
|
16564
|
+
container = rng.startContainer;
|
16565
|
+
offset = rng.startOffset;
|
16566
|
+
node = container;
|
16567
|
+
|
16568
|
+
if (container.nodeType == 3) {
|
16569
|
+
if (offset != container.nodeValue.length || container.nodeValue === invisibleChar) {
|
16570
|
+
hasContentAfter = true;
|
16571
|
+
}
|
16572
|
+
|
16573
|
+
node = node.parentNode;
|
16574
|
+
}
|
16575
|
+
|
16576
|
+
while (node) {
|
16577
|
+
if (matchNode(node, name, vars)) {
|
16578
|
+
formatNode = node;
|
16579
|
+
break;
|
16580
|
+
}
|
16581
|
+
|
16582
|
+
if (node.nextSibling) {
|
16583
|
+
hasContentAfter = true;
|
16584
|
+
}
|
16585
|
+
|
16586
|
+
parents.push(node);
|
16587
|
+
node = node.parentNode;
|
16588
|
+
}
|
16589
|
+
|
16590
|
+
// Node doesn't have the specified format
|
16591
|
+
if (!formatNode) {
|
16322
16592
|
return;
|
16323
|
-
|
16593
|
+
}
|
16324
16594
|
|
16325
|
-
|
16595
|
+
// Is there contents after the caret then remove the format on the element
|
16596
|
+
if (hasContentAfter) {
|
16597
|
+
// Get bookmark of caret position
|
16598
|
+
bookmark = selection.getBookmark();
|
16326
16599
|
|
16327
|
-
|
16328
|
-
|
16329
|
-
if (otherPendingFormats[i].name == name)
|
16330
|
-
otherPendingFormats.splice(i, 1);
|
16331
|
-
}
|
16600
|
+
// Collapse bookmark range (WebKit)
|
16601
|
+
rng.collapse(true);
|
16332
16602
|
|
16333
|
-
|
16334
|
-
|
16335
|
-
|
16336
|
-
pendingFormats.lastRng = selection.getRng();
|
16603
|
+
// Expand the range to the closest word and split it at those points
|
16604
|
+
rng = expandRng(rng, get(name), true);
|
16605
|
+
rng = rangeUtils.split(rng);
|
16337
16606
|
|
16338
|
-
|
16339
|
-
|
16340
|
-
var bookmark;
|
16607
|
+
// Remove the format from the range
|
16608
|
+
remove(name, vars, rng);
|
16341
16609
|
|
16342
|
-
|
16343
|
-
|
16344
|
-
|
16345
|
-
|
16346
|
-
|
16610
|
+
// Move selection back to caret position
|
16611
|
+
selection.moveToBookmark(bookmark);
|
16612
|
+
} else {
|
16613
|
+
caretContainer = createCaretContainer();
|
16614
|
+
|
16615
|
+
node = caretContainer;
|
16616
|
+
for (i = parents.length - 1; i >= 0; i--) {
|
16617
|
+
node.appendChild(parents[i].cloneNode(false));
|
16618
|
+
node = node.firstChild;
|
16347
16619
|
}
|
16348
|
-
});
|
16349
16620
|
|
16350
|
-
|
16351
|
-
|
16352
|
-
|
16353
|
-
function performPendingFormat(node, textNode) {
|
16354
|
-
var rng = dom.createRng();
|
16355
|
-
perform(node);
|
16621
|
+
// Insert invisible character into inner most format element
|
16622
|
+
node.appendChild(dom.doc.createTextNode(invisibleChar));
|
16623
|
+
node = node.firstChild;
|
16356
16624
|
|
16357
|
-
|
16358
|
-
|
16359
|
-
|
16360
|
-
|
16625
|
+
// Insert caret container after the formated node
|
16626
|
+
dom.insertAfter(caretContainer, formatNode);
|
16627
|
+
|
16628
|
+
// Move selection to text node
|
16629
|
+
selection.setCursorLocation(node, 1);
|
16630
|
+
}
|
16631
|
+
};
|
16632
|
+
|
16633
|
+
// Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements
|
16634
|
+
ed.onBeforeGetContent.addToTop(function() {
|
16635
|
+
var nodes = [], i;
|
16636
|
+
|
16637
|
+
if (isCaretContainerEmpty(getParentCaretContainer(selection.getStart()), nodes)) {
|
16638
|
+
// Mark children
|
16639
|
+
i = nodes.length;
|
16640
|
+
while (i--) {
|
16641
|
+
dom.setAttrib(nodes[i], 'data-mce-bogus', '1');
|
16361
16642
|
}
|
16362
|
-
|
16643
|
+
}
|
16644
|
+
});
|
16363
16645
|
|
16364
|
-
|
16365
|
-
|
16366
|
-
|
16367
|
-
|
16368
|
-
|
16369
|
-
|
16370
|
-
// Do we have pending formats and is the selection moved has moved
|
16371
|
-
if (hasPending() && !tinymce.dom.RangeUtils.compareRanges(pendingFormats.lastRng, selection.getRng())) {
|
16372
|
-
var foundCaret = false;
|
16373
|
-
each(dom.select('font,span'), function(node) {
|
16374
|
-
var textNode, rng;
|
16375
|
-
|
16376
|
-
// Look for marker
|
16377
|
-
if (isCaretNode(node)) {
|
16378
|
-
foundCaret = true;
|
16379
|
-
textNode = node.firstChild;
|
16380
|
-
|
16381
|
-
// Find the first text node within node
|
16382
|
-
while (textNode && textNode.nodeType != 3)
|
16383
|
-
textNode = textNode.firstChild;
|
16384
|
-
|
16385
|
-
if (textNode)
|
16386
|
-
performPendingFormat(node, textNode);
|
16387
|
-
else
|
16388
|
-
dom.remove(node);
|
16389
|
-
}
|
16390
|
-
});
|
16391
|
-
|
16392
|
-
// no caret - so we are
|
16393
|
-
if (enterKeyPressed && !foundCaret) {
|
16394
|
-
var node = selection.getNode();
|
16395
|
-
var textNode = node;
|
16396
|
-
|
16397
|
-
// Find the first text node within node
|
16398
|
-
while (textNode && textNode.nodeType != 3)
|
16399
|
-
textNode = textNode.firstChild;
|
16400
|
-
if (textNode) {
|
16401
|
-
node=textNode.parentNode;
|
16402
|
-
while (!isBlock(node)){
|
16403
|
-
node=node.parentNode;
|
16404
|
-
}
|
16405
|
-
performPendingFormat(node, textNode);
|
16406
|
-
}
|
16407
|
-
}
|
16646
|
+
// Remove caret container on mouse up and on key up
|
16647
|
+
tinymce.each('onMouseUp onKeyUp'.split(' '), function(name) {
|
16648
|
+
ed[name].addToTop(function() {
|
16649
|
+
removeCaretContainer();
|
16650
|
+
});
|
16651
|
+
});
|
16408
16652
|
|
16409
|
-
|
16410
|
-
|
16411
|
-
|
16412
|
-
|
16413
|
-
|
16414
|
-
|
16415
|
-
});
|
16416
|
-
});
|
16653
|
+
// Remove caret container on keydown and it's a backspace, enter or left/right arrow keys
|
16654
|
+
ed.onKeyDown.addToTop(function(ed, e) {
|
16655
|
+
var keyCode = e.keyCode;
|
16656
|
+
|
16657
|
+
if (keyCode == 8 || keyCode == 37 || keyCode == 39) {
|
16658
|
+
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
16417
16659
|
}
|
16660
|
+
});
|
16661
|
+
|
16662
|
+
// Do apply or remove caret format
|
16663
|
+
if (type == "apply") {
|
16664
|
+
applyCaretFormat();
|
16665
|
+
} else {
|
16666
|
+
removeCaretFormat();
|
16418
16667
|
}
|
16419
16668
|
};
|
16420
16669
|
};
|
@@ -16424,7 +16673,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|
16424
16673
|
var filters, fontSizes, dom, settings = ed.settings;
|
16425
16674
|
|
16426
16675
|
if (settings.inline_styles) {
|
16427
|
-
fontSizes = tinymce.explode(settings.
|
16676
|
+
fontSizes = tinymce.explode(settings.font_size_legacy_values);
|
16428
16677
|
|
16429
16678
|
function replaceWithSpan(node, styles) {
|
16430
16679
|
tinymce.each(styles, function(value, name) {
|