tinymce-rails 3.4.4.0.2 → 3.4.5
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/langs/en.js +1 -223
- data/assets/precompiled/tinymce/plugins/advhr/langs/en_dlg.js +1 -7
- data/assets/precompiled/tinymce/plugins/advimage/js/image.js +7 -3
- data/assets/precompiled/tinymce/plugins/advimage/langs/en_dlg.js +1 -45
- data/assets/precompiled/tinymce/plugins/advlink/langs/en_dlg.js +1 -54
- data/assets/precompiled/tinymce/plugins/autolink/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/autolink/editor_plugin_src.js +1 -1
- data/assets/precompiled/tinymce/plugins/emotions/langs/en_dlg.js +1 -20
- data/assets/precompiled/tinymce/plugins/fullpage/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/fullpage/editor_plugin_src.js +9 -3
- data/assets/precompiled/tinymce/plugins/fullpage/langs/en_dlg.js +1 -85
- data/assets/precompiled/tinymce/plugins/fullscreen/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/fullscreen/editor_plugin_src.js +2 -2
- data/assets/precompiled/tinymce/plugins/fullscreen/fullscreen.htm +2 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin_src.js +12 -0
- data/assets/precompiled/tinymce/plugins/media/langs/en_dlg.js +1 -112
- data/assets/precompiled/tinymce/plugins/media/media.htm +1 -1
- data/assets/precompiled/tinymce/plugins/nonbreaking/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/nonbreaking/editor_plugin_src.js +3 -2
- data/assets/precompiled/tinymce/plugins/paste/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/paste/editor_plugin_src.js +21 -102
- data/assets/precompiled/tinymce/plugins/paste/langs/en_dlg.js +1 -5
- data/assets/precompiled/tinymce/plugins/searchreplace/langs/en_dlg.js +1 -16
- data/assets/precompiled/tinymce/plugins/style/langs/en_dlg.js +1 -70
- data/assets/precompiled/tinymce/plugins/table/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/table/editor_plugin_src.js +3 -2
- data/assets/precompiled/tinymce/plugins/table/langs/en_dlg.js +1 -75
- data/assets/precompiled/tinymce/plugins/template/langs/en_dlg.js +1 -15
- data/assets/precompiled/tinymce/plugins/xhtmlxtras/langs/en_dlg.js +1 -32
- data/assets/precompiled/tinymce/themes/advanced/js/image.js +7 -3
- data/assets/precompiled/tinymce/themes/advanced/langs/en.js +1 -68
- data/assets/precompiled/tinymce/themes/advanced/langs/en_dlg.js +1 -54
- data/assets/precompiled/tinymce/themes/advanced/skins/default/content.css +1 -0
- data/assets/precompiled/tinymce/themes/advanced/skins/highcontrast/content.css +1 -0
- data/assets/precompiled/tinymce/themes/advanced/skins/o2k7/content.css +1 -0
- data/assets/precompiled/tinymce/themes/simple/langs/en.js +1 -11
- 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 +269 -171
- data/assets/precompiled/tinymce/tiny_mce_src.js +269 -171
- data/assets/precompiled/tinymce/utils/editable_selects.js +1 -1
- data/assets/vendor/tinymce/tiny_mce.js +269 -171
- data/assets/vendor/tinymce/tiny_mce_jquery.js +269 -171
- data/lib/tinymce/version.rb +2 -2
- metadata +6 -6
@@ -5,9 +5,9 @@
|
|
5
5
|
var tinymce = {
|
6
6
|
majorVersion : '3',
|
7
7
|
|
8
|
-
minorVersion : '4.
|
8
|
+
minorVersion : '4.5',
|
9
9
|
|
10
|
-
releaseDate : '2011-
|
10
|
+
releaseDate : '2011-09-06',
|
11
11
|
|
12
12
|
_init : function() {
|
13
13
|
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
@@ -559,8 +559,9 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
559
559
|
// Default settings
|
560
560
|
s = t.settings = s || {};
|
561
561
|
|
562
|
-
// Strange app protocol or local anchor
|
563
|
-
|
562
|
+
// Strange app protocol that isn't http/https or local anchor
|
563
|
+
// For example: mailto,skype,tel etc.
|
564
|
+
if (/^([\w\-]+):([^\/]{2})/i.test(u) || /^\s*#/.test(u)) {
|
564
565
|
t.source = u;
|
565
566
|
return;
|
566
567
|
}
|
@@ -1045,31 +1046,89 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1045
1046
|
})(tinymce);
|
1046
1047
|
|
1047
1048
|
(function(tinymce) {
|
1049
|
+
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE;
|
1050
|
+
|
1048
1051
|
function cleanupStylesWhenDeleting(ed) {
|
1049
|
-
var dom = ed.dom, selection = ed.selection
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1052
|
+
var dom = ed.dom, selection = ed.selection;
|
1053
|
+
|
1054
|
+
ed.onKeyDown.add(function(ed, e) {
|
1055
|
+
var rng, blockElm, node, clonedSpan, isDelete;
|
1056
|
+
|
1057
|
+
isDelete = e.keyCode == DELETE;
|
1058
|
+
if (isDelete || e.keyCode == BACKSPACE) {
|
1059
|
+
e.preventDefault();
|
1060
|
+
rng = selection.getRng();
|
1061
|
+
|
1062
|
+
// Find root block
|
1063
|
+
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
1064
|
+
|
1065
|
+
// On delete clone the root span of the next block element
|
1066
|
+
if (isDelete)
|
1067
|
+
blockElm = dom.getNext(blockElm, dom.isBlock);
|
1068
|
+
|
1069
|
+
// Locate root span element and clone it since it would otherwise get merged by the "apple-style-span" on delete/backspace
|
1070
|
+
if (blockElm) {
|
1071
|
+
node = blockElm.firstChild;
|
1072
|
+
|
1073
|
+
if (node && node.nodeName === 'SPAN') {
|
1074
|
+
clonedSpan = node.cloneNode(false);
|
1056
1075
|
}
|
1057
|
-
var spans = dom.select("span.Apple-style-span", blockElement);
|
1058
|
-
dom.remove(spans, true);
|
1059
1076
|
}
|
1060
|
-
});
|
1061
|
-
}
|
1062
1077
|
|
1078
|
+
// Do the backspace/delete actiopn
|
1079
|
+
ed.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
|
1080
|
+
|
1081
|
+
// Find all odd apple-style-spans
|
1082
|
+
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
1083
|
+
tinymce.each(dom.select('span.Apple-style-span,font.Apple-style-span', blockElm), function(span) {
|
1084
|
+
var rng = dom.createRng();
|
1085
|
+
|
1086
|
+
// Set range selection before the span we are about to remove
|
1087
|
+
rng.setStartBefore(span);
|
1088
|
+
rng.setEndBefore(span);
|
1089
|
+
|
1090
|
+
if (clonedSpan) {
|
1091
|
+
dom.replace(clonedSpan.cloneNode(false), span, true);
|
1092
|
+
} else {
|
1093
|
+
dom.remove(span, true);
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
// Restore the selection
|
1097
|
+
selection.setRng(rng);
|
1098
|
+
});
|
1099
|
+
}
|
1100
|
+
});
|
1101
|
+
};
|
1102
|
+
|
1103
|
+
function emptyEditorWhenDeleting(ed) {
|
1104
|
+
ed.onKeyUp.add(function(ed, e) {
|
1105
|
+
var keyCode = e.keyCode;
|
1106
|
+
|
1107
|
+
if (keyCode == DELETE || keyCode == BACKSPACE) {
|
1108
|
+
if (ed.dom.isEmpty(ed.getBody())) {
|
1109
|
+
ed.setContent('', {format : 'raw'});
|
1110
|
+
ed.nodeChanged();
|
1111
|
+
return;
|
1112
|
+
}
|
1113
|
+
}
|
1114
|
+
});
|
1115
|
+
};
|
1116
|
+
|
1063
1117
|
tinymce.create('tinymce.util.Quirks', {
|
1064
1118
|
Quirks: function(ed) {
|
1119
|
+
// Load WebKit specific fixed
|
1065
1120
|
if (tinymce.isWebKit) {
|
1066
1121
|
cleanupStylesWhenDeleting(ed);
|
1122
|
+
emptyEditorWhenDeleting(ed);
|
1123
|
+
}
|
1124
|
+
|
1125
|
+
// Load IE specific fixes
|
1126
|
+
if (tinymce.isIE) {
|
1127
|
+
emptyEditorWhenDeleting(ed);
|
1067
1128
|
}
|
1068
|
-
|
1069
1129
|
}
|
1070
1130
|
});
|
1071
|
-
})(tinymce);
|
1072
|
-
|
1131
|
+
})(tinymce);
|
1073
1132
|
(function(tinymce) {
|
1074
1133
|
var namedEntities, baseEntities, reverseEntities,
|
1075
1134
|
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
@@ -1481,7 +1540,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|
1481
1540
|
|
1482
1541
|
(function(tinymce) {
|
1483
1542
|
var transitional = {}, boolAttrMap, blockElementsMap, shortEndedElementsMap, nonEmptyElementsMap, customElementsMap = {},
|
1484
|
-
|
1543
|
+
defaultWhiteSpaceElementsMap, selfClosingElementsMap, makeMap = tinymce.makeMap, each = tinymce.each;
|
1485
1544
|
|
1486
1545
|
function split(str, delim) {
|
1487
1546
|
return str.split(delim || ',');
|
@@ -1645,11 +1704,11 @@ tinymce.html.Styles = function(settings, schema) {
|
|
1645
1704
|
boolAttrMap = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,autoplay,loop,controls');
|
1646
1705
|
shortEndedElementsMap = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source');
|
1647
1706
|
nonEmptyElementsMap = tinymce.extend(makeMap('td,th,iframe,video,audio,object'), shortEndedElementsMap);
|
1648
|
-
|
1707
|
+
defaultWhiteSpaceElementsMap = makeMap('pre,script,style,textarea');
|
1649
1708
|
selfClosingElementsMap = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
|
1650
1709
|
|
1651
1710
|
tinymce.html.Schema = function(settings) {
|
1652
|
-
var self = this, elements = {}, children = {}, patternElements = [], validStyles;
|
1711
|
+
var self = this, elements = {}, children = {}, patternElements = [], validStyles, whiteSpaceElementsMap;
|
1653
1712
|
|
1654
1713
|
settings = settings || {};
|
1655
1714
|
|
@@ -1667,6 +1726,8 @@ tinymce.html.Styles = function(settings, schema) {
|
|
1667
1726
|
});
|
1668
1727
|
}
|
1669
1728
|
|
1729
|
+
whiteSpaceElementsMap = settings.whitespace_elements ? makeMap(settings.whitespace_elements) : defaultWhiteSpaceElementsMap;
|
1730
|
+
|
1670
1731
|
// Converts a wildcard expression string to a regexp for example *a will become /.*a/.
|
1671
1732
|
function patternToRegExp(str) {
|
1672
1733
|
return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');
|
@@ -2021,9 +2082,9 @@ tinymce.html.Styles = function(settings, schema) {
|
|
2021
2082
|
|
2022
2083
|
self.parse = function(html) {
|
2023
2084
|
var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name, isInternalElement, removeInternalElements,
|
2024
|
-
shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue,
|
2085
|
+
shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue, invalidPrefixRegExp,
|
2025
2086
|
validAttributesMap, validAttributePatterns, attributesRequired, attributesDefault, attributesForced, selfClosing,
|
2026
|
-
tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing;
|
2087
|
+
tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing, isIE;
|
2027
2088
|
|
2028
2089
|
function processEndTag(name) {
|
2029
2090
|
var pos, i;
|
@@ -2074,6 +2135,8 @@ tinymce.html.Styles = function(settings, schema) {
|
|
2074
2135
|
validate = settings.validate;
|
2075
2136
|
removeInternalElements = settings.remove_internals;
|
2076
2137
|
fixSelfClosing = settings.fix_self_closing;
|
2138
|
+
isIE = tinymce.isIE;
|
2139
|
+
invalidPrefixRegExp = /^:/;
|
2077
2140
|
|
2078
2141
|
while (matches = tokenRegExp.exec(html)) {
|
2079
2142
|
// Text
|
@@ -2081,9 +2144,20 @@ tinymce.html.Styles = function(settings, schema) {
|
|
2081
2144
|
self.text(decode(html.substr(index, matches.index - index)));
|
2082
2145
|
|
2083
2146
|
if (value = matches[6]) { // End element
|
2084
|
-
|
2147
|
+
value = value.toLowerCase();
|
2148
|
+
|
2149
|
+
// IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements
|
2150
|
+
if (isIE && invalidPrefixRegExp.test(value))
|
2151
|
+
value = value.substr(1);
|
2152
|
+
|
2153
|
+
processEndTag(value);
|
2085
2154
|
} else if (value = matches[7]) { // Start element
|
2086
2155
|
value = value.toLowerCase();
|
2156
|
+
|
2157
|
+
// IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements
|
2158
|
+
if (isIE && invalidPrefixRegExp.test(value))
|
2159
|
+
value = value.substr(1);
|
2160
|
+
|
2087
2161
|
isShortEnded = value in shortEndedElements;
|
2088
2162
|
|
2089
2163
|
// Is self closing tag for example an <li> after an open <li>
|
@@ -3097,11 +3171,13 @@ tinymce.html.Styles = function(settings, schema) {
|
|
3097
3171
|
elementRule = schema.getElementRule(parent.name);
|
3098
3172
|
|
3099
3173
|
// Remove or padd the element depending on schema rule
|
3100
|
-
if (elementRule
|
3101
|
-
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3174
|
+
if (elementRule) {
|
3175
|
+
if (elementRule.removeEmpty)
|
3176
|
+
parent.remove();
|
3177
|
+
else if (elementRule.paddEmpty)
|
3178
|
+
parent.empty().append(new tinymce.html.Node('#text', 3)).value = '\u00a0';
|
3179
|
+
}
|
3180
|
+
}
|
3105
3181
|
}
|
3106
3182
|
}
|
3107
3183
|
}
|
@@ -4399,7 +4475,7 @@ tinymce.html.Writer = function(settings) {
|
|
4399
4475
|
},
|
4400
4476
|
|
4401
4477
|
isEmpty : function(node, elements) {
|
4402
|
-
var self = this, i, attributes, type, walker, name;
|
4478
|
+
var self = this, i, attributes, type, walker, name, parentNode;
|
4403
4479
|
|
4404
4480
|
node = node.firstChild;
|
4405
4481
|
if (node) {
|
@@ -4415,8 +4491,16 @@ tinymce.html.Writer = function(settings) {
|
|
4415
4491
|
continue;
|
4416
4492
|
|
4417
4493
|
// Keep empty elements like <img />
|
4418
|
-
|
4494
|
+
name = node.nodeName.toLowerCase();
|
4495
|
+
if (elements && elements[name]) {
|
4496
|
+
// Ignore single BR elements in blocks like <p><br /></p>
|
4497
|
+
parentNode = node.parentNode;
|
4498
|
+
if (name === 'br' && self.isBlock(parentNode) && parentNode.firstChild === node && parentNode.lastChild === node) {
|
4499
|
+
continue;
|
4500
|
+
}
|
4501
|
+
|
4419
4502
|
return false;
|
4503
|
+
}
|
4420
4504
|
|
4421
4505
|
// Keep elements with data-bookmark attributes or name attribute like <a name="1"></a>
|
4422
4506
|
attributes = self.getAttribs(node);
|
@@ -7271,9 +7355,13 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
7271
7355
|
|
7272
7356
|
if (n)
|
7273
7357
|
e.appendChild(n);
|
7274
|
-
} else if (is(r.item) || is(r.htmlText))
|
7275
|
-
|
7276
|
-
|
7358
|
+
} else if (is(r.item) || is(r.htmlText)) {
|
7359
|
+
// IE will produce invalid markup if elements are present that
|
7360
|
+
// it doesn't understand like custom elements or HTML5 elements.
|
7361
|
+
// Adding a BR in front of the contents and then remoiving it seems to fix it though.
|
7362
|
+
e.innerHTML = '<br>' + (r.item ? r.item(0).outerHTML : r.htmlText);
|
7363
|
+
e.removeChild(e.firstChild);
|
7364
|
+
} else
|
7277
7365
|
e.innerHTML = r.toString();
|
7278
7366
|
|
7279
7367
|
// Keep whitespace before and after
|
@@ -7358,7 +7446,12 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
7358
7446
|
rng = self.getRng();
|
7359
7447
|
}
|
7360
7448
|
|
7361
|
-
|
7449
|
+
// Explorer removes spaces from the beginning of pasted contents
|
7450
|
+
if (/^\s+/.test(content)) {
|
7451
|
+
rng.pasteHTML('<span id="__mce_tmp">_</span>' + content);
|
7452
|
+
self.dom.remove('__mce_tmp');
|
7453
|
+
} else
|
7454
|
+
rng.pasteHTML(content);
|
7362
7455
|
}
|
7363
7456
|
|
7364
7457
|
// Dispatch set content event
|
@@ -7965,26 +8058,29 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
7965
8058
|
container = container.childNodes[Math.min(!start && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1)];
|
7966
8059
|
offset = 0;
|
7967
8060
|
|
7968
|
-
//
|
7969
|
-
|
7970
|
-
|
7971
|
-
|
7972
|
-
|
7973
|
-
|
7974
|
-
|
7975
|
-
|
7976
|
-
|
7977
|
-
|
8061
|
+
// Don't walk into elements that doesn't have any child nodes like a IMG
|
8062
|
+
if (container.hasChildNodes()) {
|
8063
|
+
// Walk the DOM to find a text node to place the caret at or a BR
|
8064
|
+
node = container;
|
8065
|
+
walker = new tinymce.dom.TreeWalker(container, body);
|
8066
|
+
do {
|
8067
|
+
// Found a text node use that position
|
8068
|
+
if (node.nodeType === 3) {
|
8069
|
+
offset = start ? 0 : node.nodeValue.length - 1;
|
8070
|
+
container = node;
|
8071
|
+
break;
|
8072
|
+
}
|
7978
8073
|
|
7979
|
-
|
7980
|
-
|
7981
|
-
|
7982
|
-
|
7983
|
-
|
7984
|
-
|
7985
|
-
|
8074
|
+
// Found a BR element that we can place the caret before
|
8075
|
+
if (node.nodeName === 'BR') {
|
8076
|
+
offset = dom.nodeIndex(node);
|
8077
|
+
container = node.parentNode;
|
8078
|
+
break;
|
8079
|
+
}
|
8080
|
+
} while (node = (start ? walker.next() : walker.prev()));
|
7986
8081
|
|
7987
|
-
|
8082
|
+
normalized = true;
|
8083
|
+
}
|
7988
8084
|
}
|
7989
8085
|
}
|
7990
8086
|
|
@@ -8278,7 +8374,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8278
8374
|
|
8279
8375
|
// Explorer won't clone contents of script and style and the
|
8280
8376
|
// selected index of select elements are cleared on a clone operation.
|
8281
|
-
if (isIE && dom.select('script,style,select').length > 0) {
|
8377
|
+
if (isIE && dom.select('script,style,select,map').length > 0) {
|
8282
8378
|
content = node.innerHTML;
|
8283
8379
|
node = node.cloneNode(false);
|
8284
8380
|
dom.setHTML(node, content);
|
@@ -9979,6 +10075,11 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
9979
10075
|
Event.remove(t.id, 'blur', bf);
|
9980
10076
|
});
|
9981
10077
|
|
10078
|
+
//prevent default left and right keys on chrome - so that the keyboard navigation is used.
|
10079
|
+
if (tinymce.isWebKit && (e.keyCode==37 ||e.keyCode==39)) {
|
10080
|
+
return Event.prevent(e);
|
10081
|
+
}
|
10082
|
+
|
9982
10083
|
if (e.keyCode == 13 || e.keyCode == 32) {
|
9983
10084
|
onChange(e);
|
9984
10085
|
return Event.cancel(e);
|
@@ -9989,6 +10090,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
9989
10090
|
}
|
9990
10091
|
});
|
9991
10092
|
})(tinymce);
|
10093
|
+
|
9992
10094
|
(function(tinymce) {
|
9993
10095
|
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;
|
9994
10096
|
|
@@ -10244,6 +10346,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
10244
10346
|
}
|
10245
10347
|
|
10246
10348
|
t.isMenuVisible = 0;
|
10349
|
+
t.onHideMenu.dispatch();
|
10247
10350
|
}
|
10248
10351
|
},
|
10249
10352
|
|
@@ -11327,14 +11430,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11327
11430
|
|
11328
11431
|
t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
|
11329
11432
|
|
11330
|
-
// Firefox 2 doesn't load stylesheets correctly this way
|
11331
|
-
if (!isGecko || !/Firefox\/2/.test(navigator.userAgent)) {
|
11332
|
-
for (i = 0; i < t.contentCSS.length; i++)
|
11333
|
-
t.iframeHTML += '<link type="text/css" rel="stylesheet" href="' + t.contentCSS[i] + '" />';
|
11334
|
-
|
11335
|
-
t.contentCSS = [];
|
11336
|
-
}
|
11337
|
-
|
11338
11433
|
bi = s.body_id || 'tinymce';
|
11339
11434
|
if (bi.indexOf('=') != -1) {
|
11340
11435
|
bi = t.getParam('body_id', '', 'hash');
|
@@ -11347,7 +11442,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11347
11442
|
bc = bc[t.id] || '';
|
11348
11443
|
}
|
11349
11444
|
|
11350
|
-
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';
|
11445
|
+
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"><br></body></html>';
|
11351
11446
|
|
11352
11447
|
// Domain relaxing enabled, then set document domain
|
11353
11448
|
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
|
@@ -11365,7 +11460,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11365
11460
|
title : s.aria_label,
|
11366
11461
|
style : {
|
11367
11462
|
width : '100%',
|
11368
|
-
height : h
|
11463
|
+
height : h,
|
11464
|
+
display : 'block' // Important for Gecko to render the iframe correctly
|
11369
11465
|
}
|
11370
11466
|
});
|
11371
11467
|
|
@@ -11380,50 +11476,27 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11380
11476
|
e = n = o = null; // Cleanup
|
11381
11477
|
},
|
11382
11478
|
|
11383
|
-
setupIframe : function(
|
11479
|
+
setupIframe : function() {
|
11384
11480
|
var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
|
11385
11481
|
|
11386
11482
|
// Setup iframe body
|
11387
|
-
if (
|
11388
|
-
//
|
11389
|
-
if
|
11390
|
-
|
11391
|
-
|
11392
|
-
|
11393
|
-
|
11394
|
-
|
11395
|
-
|
11396
|
-
|
11397
|
-
|
11398
|
-
|
11399
|
-
|
11400
|
-
|
11401
|
-
|
11402
|
-
|
11403
|
-
|
11404
|
-
t.onMouseDown.add(function(ed, e) {
|
11405
|
-
if (e.target.nodeName === "HTML") {
|
11406
|
-
// Setting the contentEditable off/on seems to force caret mode in the editor and enabled auto focus
|
11407
|
-
b.contentEditable = false;
|
11408
|
-
b.contentEditable = true;
|
11409
|
-
|
11410
|
-
d.designMode = 'on'; // Render the caret
|
11411
|
-
|
11412
|
-
// Remove design mode again after a while so it has some time to execute
|
11413
|
-
window.setTimeout(function() {
|
11414
|
-
d.designMode = 'off';
|
11415
|
-
t.getBody().focus();
|
11416
|
-
}, 1);
|
11417
|
-
}
|
11418
|
-
});
|
11419
|
-
} else
|
11420
|
-
d.designMode = 'on';
|
11421
|
-
|
11422
|
-
// Call setup frame once the contentEditable/designMode has been initialized
|
11423
|
-
// since the caret won't be rendered some times otherwise.
|
11424
|
-
t.setupIframe(true);
|
11425
|
-
}, 1);
|
11426
|
-
}, false);
|
11483
|
+
if (!isIE || !tinymce.relaxedDomain) {
|
11484
|
+
// Fix for a focus bug in FF 3.x where the body element
|
11485
|
+
// wouldn't get proper focus if the user clicked on the HTML element
|
11486
|
+
if (isGecko && !Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
|
11487
|
+
t.onMouseDown.add(function(ed, e) {
|
11488
|
+
if (e.target.nodeName === "HTML") {
|
11489
|
+
var body = t.getBody();
|
11490
|
+
|
11491
|
+
// Blur the body it's focused but not correctly focused
|
11492
|
+
body.blur();
|
11493
|
+
|
11494
|
+
// Refocus the body after a little while
|
11495
|
+
setTimeout(function() {
|
11496
|
+
body.focus();
|
11497
|
+
}, 0);
|
11498
|
+
}
|
11499
|
+
});
|
11427
11500
|
}
|
11428
11501
|
|
11429
11502
|
d.open();
|
@@ -11432,17 +11505,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11432
11505
|
|
11433
11506
|
if (tinymce.relaxedDomain)
|
11434
11507
|
d.domain = tinymce.relaxedDomain;
|
11435
|
-
|
11436
|
-
// Wait for iframe onload event on Gecko
|
11437
|
-
if (isGecko && !s.readonly)
|
11438
|
-
return;
|
11439
11508
|
}
|
11440
11509
|
|
11441
11510
|
// It will not steal focus while setting contentEditable
|
11442
11511
|
b = t.getBody();
|
11443
11512
|
b.disabled = true;
|
11444
11513
|
|
11445
|
-
if (!
|
11514
|
+
if (!s.readonly)
|
11446
11515
|
b.contentEditable = true;
|
11447
11516
|
|
11448
11517
|
b.disabled = false;
|
@@ -11592,6 +11661,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11592
11661
|
subscript : {inline : 'sub'},
|
11593
11662
|
superscript : {inline : 'sup'},
|
11594
11663
|
|
11664
|
+
link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true,
|
11665
|
+
onmatch : function(node) {
|
11666
|
+
return true;
|
11667
|
+
},
|
11668
|
+
|
11669
|
+
onformat : function(elm, fmt, vars) {
|
11670
|
+
each(vars, function(value, key) {
|
11671
|
+
t.dom.setAttrib(elm, key, value);
|
11672
|
+
});
|
11673
|
+
}
|
11674
|
+
},
|
11675
|
+
|
11595
11676
|
removeformat : [
|
11596
11677
|
{selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},
|
11597
11678
|
{selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true},
|
@@ -11844,6 +11925,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11844
11925
|
controlElm = ieRng.item(0);
|
11845
11926
|
}
|
11846
11927
|
|
11928
|
+
t._refreshContentEditable();
|
11847
11929
|
selection.normalize();
|
11848
11930
|
|
11849
11931
|
// Is not content editable
|
@@ -12580,16 +12662,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12580
12662
|
var t = this, d = t.getDoc(), s = t.settings;
|
12581
12663
|
|
12582
12664
|
if (isGecko && !s.readonly) {
|
12583
|
-
|
12584
|
-
try {
|
12585
|
-
if (!s.content_editable) {
|
12586
|
-
d.body.contentEditable = false;
|
12587
|
-
d.body.contentEditable = true;
|
12588
|
-
}
|
12589
|
-
} catch (ex) {
|
12590
|
-
// Fails if it's hidden
|
12591
|
-
}
|
12592
|
-
}
|
12665
|
+
t._refreshContentEditable();
|
12593
12666
|
|
12594
12667
|
try {
|
12595
12668
|
// Try new Gecko method
|
@@ -12865,7 +12938,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12865
12938
|
if (tinymce.isWebKit) {
|
12866
12939
|
dom.bind(t.getDoc(), 'selectionchange', function() {
|
12867
12940
|
if (t.selectionTimer) {
|
12868
|
-
|
12941
|
+
clearTimeout(t.selectionTimer);
|
12869
12942
|
t.selectionTimer = 0;
|
12870
12943
|
}
|
12871
12944
|
|
@@ -12927,6 +13000,21 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12927
13000
|
}
|
12928
13001
|
},
|
12929
13002
|
|
13003
|
+
_refreshContentEditable : function() {
|
13004
|
+
var self = this, body, parent;
|
13005
|
+
|
13006
|
+
// Check if the editor was hidden and the re-initalize contentEditable mode by removing and adding the body again
|
13007
|
+
if (self._isHidden()) {
|
13008
|
+
body = self.getBody();
|
13009
|
+
parent = body.parentNode;
|
13010
|
+
|
13011
|
+
parent.removeChild(body);
|
13012
|
+
parent.appendChild(body);
|
13013
|
+
|
13014
|
+
body.focus();
|
13015
|
+
}
|
13016
|
+
},
|
13017
|
+
|
12930
13018
|
_isHidden : function() {
|
12931
13019
|
var s;
|
12932
13020
|
|
@@ -12949,6 +13037,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12949
13037
|
selection = editor.selection,
|
12950
13038
|
commands = {state: {}, exec : {}, value : {}},
|
12951
13039
|
settings = editor.settings,
|
13040
|
+
formatter = editor.formatter,
|
12952
13041
|
bookmark;
|
12953
13042
|
|
12954
13043
|
function execCommand(command, ui, value) {
|
@@ -13014,11 +13103,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13014
13103
|
};
|
13015
13104
|
|
13016
13105
|
function isFormatMatch(name) {
|
13017
|
-
return
|
13106
|
+
return formatter.match(name);
|
13018
13107
|
};
|
13019
13108
|
|
13020
13109
|
function toggleFormat(name, value) {
|
13021
|
-
|
13110
|
+
formatter.toggle(name, value ? {value : value} : undefined);
|
13022
13111
|
};
|
13023
13112
|
|
13024
13113
|
function storeSelection(type) {
|
@@ -13078,7 +13167,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13078
13167
|
// Remove all other alignments first
|
13079
13168
|
each('left,center,right,full'.split(','), function(name) {
|
13080
13169
|
if (align != name)
|
13081
|
-
|
13170
|
+
formatter.remove('align' + name);
|
13082
13171
|
});
|
13083
13172
|
|
13084
13173
|
toggleFormat('align' + align);
|
@@ -13135,7 +13224,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13135
13224
|
},
|
13136
13225
|
|
13137
13226
|
RemoveFormat : function(command) {
|
13138
|
-
|
13227
|
+
formatter.remove(command);
|
13139
13228
|
},
|
13140
13229
|
|
13141
13230
|
mceBlockQuote : function(command) {
|
@@ -13358,7 +13447,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13358
13447
|
},
|
13359
13448
|
|
13360
13449
|
mceToggleFormat : function(command, ui, value) {
|
13361
|
-
|
13450
|
+
formatter.toggle(value);
|
13362
13451
|
},
|
13363
13452
|
|
13364
13453
|
InsertHorizontalRule : function() {
|
@@ -13375,47 +13464,27 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13375
13464
|
},
|
13376
13465
|
|
13377
13466
|
mceInsertLink : function(command, ui, value) {
|
13378
|
-
var
|
13467
|
+
var anchor;
|
13379
13468
|
|
13380
|
-
if (
|
13469
|
+
if (typeof(value) == 'string')
|
13381
13470
|
value = {href : value};
|
13382
13471
|
|
13472
|
+
anchor = dom.getParent(selection.getNode(), 'a');
|
13473
|
+
|
13383
13474
|
// Spaces are never valid in URLs and it's a very common mistake for people to make so we fix it here.
|
13384
13475
|
value.href = value.href.replace(' ', '%20');
|
13385
13476
|
|
13386
|
-
if
|
13387
|
-
|
13388
|
-
|
13389
|
-
|
13390
|
-
img = dom.getParent(selection.getNode(), 'img');
|
13391
|
-
|
13392
|
-
if (img) {
|
13393
|
-
style = img.style.cssText;
|
13394
|
-
cls = img.className;
|
13395
|
-
img.style.cssText = null;
|
13396
|
-
img.className = null;
|
13397
|
-
}
|
13398
|
-
}
|
13399
|
-
|
13400
|
-
execNativeCommand('CreateLink', FALSE, 'javascript:mctmp(0);');
|
13477
|
+
// Remove existing links if there could be child links or that the href isn't specified
|
13478
|
+
if (!anchor || !value.href) {
|
13479
|
+
formatter.remove('link');
|
13480
|
+
}
|
13401
13481
|
|
13402
|
-
|
13403
|
-
|
13404
|
-
|
13405
|
-
if (cls)
|
13406
|
-
img.className = cls;
|
13407
|
-
|
13408
|
-
each(dom.select("a[href='javascript:mctmp(0);']"), function(link) {
|
13409
|
-
dom.setAttribs(link, value);
|
13410
|
-
});
|
13411
|
-
} else {
|
13412
|
-
if (value.href)
|
13413
|
-
dom.setAttribs(link, value);
|
13414
|
-
else
|
13415
|
-
editor.dom.remove(link, TRUE);
|
13482
|
+
// Apply new link to selection
|
13483
|
+
if (value.href) {
|
13484
|
+
formatter.apply('link', value, anchor);
|
13416
13485
|
}
|
13417
13486
|
},
|
13418
|
-
|
13487
|
+
|
13419
13488
|
selectAll : function() {
|
13420
13489
|
var root = dom.getRoot(), rng = dom.createRng();
|
13421
13490
|
|
@@ -13987,6 +14056,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13987
14056
|
ra.setStart(en, 0);
|
13988
14057
|
}
|
13989
14058
|
|
14059
|
+
// If the body is totally empty add a BR element this might happen on webkit
|
14060
|
+
if (!d.body.hasChildNodes()) {
|
14061
|
+
d.body.appendChild(dom.create('br'));
|
14062
|
+
}
|
14063
|
+
|
13990
14064
|
// Never use body as start or end node
|
13991
14065
|
sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes
|
13992
14066
|
sn = sn.nodeName == "BODY" ? sn.firstChild : sn;
|
@@ -14846,6 +14920,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14846
14920
|
fmt = fmt || format;
|
14847
14921
|
|
14848
14922
|
if (elm) {
|
14923
|
+
if (fmt.onformat) {
|
14924
|
+
fmt.onformat(elm, fmt, vars, node);
|
14925
|
+
}
|
14926
|
+
|
14849
14927
|
each(fmt.styles, function(value, name) {
|
14850
14928
|
dom.setStyle(elm, name, replaceVars(value, vars));
|
14851
14929
|
});
|
@@ -14863,7 +14941,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14863
14941
|
}
|
14864
14942
|
};
|
14865
14943
|
function adjustSelectionToVisibleSelection() {
|
14866
|
-
|
14867
14944
|
function findSelectionEnd(start, end) {
|
14868
14945
|
var walker = new TreeWalker(end);
|
14869
14946
|
for (node = walker.current(); node; node = walker.prev()) {
|
@@ -14871,37 +14948,49 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14871
14948
|
return node;
|
14872
14949
|
}
|
14873
14950
|
}
|
14874
|
-
}
|
14951
|
+
};
|
14875
14952
|
|
14876
14953
|
// Adjust selection so that a end container with a end offset of zero is not included in the selection
|
14877
14954
|
// as this isn't visible to the user.
|
14878
14955
|
var rng = ed.selection.getRng();
|
14879
14956
|
var start = rng.startContainer;
|
14880
14957
|
var end = rng.endContainer;
|
14958
|
+
|
14881
14959
|
if (start != end && rng.endOffset == 0) {
|
14882
14960
|
var newEnd = findSelectionEnd(start, end);
|
14883
14961
|
var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
|
14962
|
+
|
14884
14963
|
rng.setEnd(newEnd, endOffset);
|
14885
14964
|
}
|
14965
|
+
|
14886
14966
|
return rng;
|
14887
14967
|
}
|
14888
14968
|
|
14889
14969
|
function applyStyleToList(node, bookmark, wrapElm, newWrappers, process){
|
14890
|
-
var nodes =[], listIndex
|
14970
|
+
var nodes = [], listIndex = -1, list, startIndex = -1, endIndex = -1, currentWrapElm;
|
14891
14971
|
|
14892
14972
|
// find the index of the first child list.
|
14893
14973
|
each(node.childNodes, function(n, index) {
|
14894
|
-
if (n.nodeName==="UL"||n.nodeName==="OL") {
|
14974
|
+
if (n.nodeName === "UL" || n.nodeName === "OL") {
|
14975
|
+
listIndex = index;
|
14976
|
+
list = n;
|
14977
|
+
return false;
|
14978
|
+
}
|
14895
14979
|
});
|
14896
14980
|
|
14897
14981
|
// get the index of the bookmarks
|
14898
14982
|
each(node.childNodes, function(n, index) {
|
14899
|
-
if (n.nodeName==="SPAN" &&dom.getAttrib(n, "data-mce-type")=="bookmark"
|
14900
|
-
|
14983
|
+
if (n.nodeName === "SPAN" && dom.getAttrib(n, "data-mce-type") == "bookmark") {
|
14984
|
+
if (n.id == bookmark.id + "_start") {
|
14985
|
+
startIndex = index;
|
14986
|
+
} else if (n.id == bookmark.id + "_end") {
|
14987
|
+
endIndex = index;
|
14988
|
+
}
|
14989
|
+
}
|
14901
14990
|
});
|
14902
14991
|
|
14903
14992
|
// if the selection spans across an embedded list, or there isn't an embedded list - handle processing normally
|
14904
|
-
if (listIndex<=0 || (startIndex<listIndex&&endIndex>listIndex)) {
|
14993
|
+
if (listIndex <= 0 || (startIndex < listIndex && endIndex > listIndex)) {
|
14905
14994
|
each(tinymce.grep(node.childNodes), process);
|
14906
14995
|
return 0;
|
14907
14996
|
} else {
|
@@ -14909,22 +14998,26 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14909
14998
|
|
14910
14999
|
// create a list of the nodes on the same side of the list as the selection
|
14911
15000
|
each(tinymce.grep(node.childNodes), function(n, index) {
|
14912
|
-
if ((startIndex<listIndex && index <listIndex) || (startIndex>listIndex && index >listIndex)) {
|
15001
|
+
if ((startIndex < listIndex && index < listIndex) || (startIndex > listIndex && index > listIndex)) {
|
14913
15002
|
nodes.push(n);
|
14914
|
-
n.parentNode.removeChild(n);
|
15003
|
+
n.parentNode.removeChild(n);
|
14915
15004
|
}
|
14916
15005
|
});
|
14917
15006
|
|
14918
15007
|
// insert the wrapping element either before or after the list.
|
14919
|
-
if (startIndex<listIndex) {
|
15008
|
+
if (startIndex < listIndex) {
|
14920
15009
|
node.insertBefore(currentWrapElm, list);
|
14921
|
-
} else if (startIndex>listIndex) {
|
15010
|
+
} else if (startIndex > listIndex) {
|
14922
15011
|
node.insertBefore(currentWrapElm, list.nextSibling);
|
14923
15012
|
}
|
14924
15013
|
|
14925
15014
|
// add the new nodes to the list.
|
14926
15015
|
newWrappers.push(currentWrapElm);
|
14927
|
-
|
15016
|
+
|
15017
|
+
each(nodes, function(node) {
|
15018
|
+
currentWrapElm.appendChild(node);
|
15019
|
+
});
|
15020
|
+
|
14928
15021
|
return currentWrapElm;
|
14929
15022
|
}
|
14930
15023
|
};
|
@@ -15138,7 +15231,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15138
15231
|
}
|
15139
15232
|
|
15140
15233
|
// Merge next and previous siblings if they are similar <b>text</b><b>text</b> becomes <b>texttext</b>
|
15141
|
-
if (node) {
|
15234
|
+
if (node && format.merge_siblings !== false) {
|
15142
15235
|
node = mergeSiblings(getNonWhiteSpaceSibling(node), node);
|
15143
15236
|
node = mergeSiblings(node, getNonWhiteSpaceSibling(node, TRUE));
|
15144
15237
|
}
|
@@ -15404,6 +15497,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15404
15497
|
function matchItems(node, format, item_name) {
|
15405
15498
|
var key, value, items = format[item_name], i;
|
15406
15499
|
|
15500
|
+
// Custom match
|
15501
|
+
if (format.onmatch) {
|
15502
|
+
return format.onmatch(node, format, item_name);
|
15503
|
+
}
|
15504
|
+
|
15407
15505
|
// Check all items
|
15408
15506
|
if (items) {
|
15409
15507
|
// Non indexed object
|