tinymce-rails 3.4.7.0.2 → 3.4.8
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/Rakefile +2 -2
- data/assets/integration/tinymce/preinit.js.erb +1 -1
- data/assets/precompiled/tinymce/jquery.tinymce.js +1 -1
- data/assets/precompiled/tinymce/plugins/advlink/js/advlink.js +8 -1
- data/assets/precompiled/tinymce/plugins/autoresize/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/autoresize/editor_plugin_src.js +20 -38
- data/assets/precompiled/tinymce/plugins/contextmenu/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/contextmenu/editor_plugin_src.js +1 -0
- data/assets/precompiled/tinymce/plugins/emotions/emotions.htm +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin.js +1 -1
- data/assets/precompiled/tinymce/plugins/lists/editor_plugin_src.js +21 -0
- data/assets/precompiled/tinymce/plugins/media/js/media.js +5 -5
- data/assets/precompiled/tinymce/plugins/table/js/table.js +5 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template.js +1 -1
- data/assets/precompiled/tinymce/themes/advanced/editor_template_src.js +2 -2
- data/assets/precompiled/tinymce/tiny_mce.js +1 -1
- data/assets/precompiled/tinymce/tiny_mce_jquery.js +1 -1
- data/assets/precompiled/tinymce/tiny_mce_jquery_src.js +202 -128
- data/assets/precompiled/tinymce/tiny_mce_src.js +202 -128
- data/assets/vendor/tinymce/jquery-tinymce.js +1 -1
- data/assets/vendor/tinymce/tiny_mce.js +202 -128
- data/assets/vendor/tinymce/tiny_mce_jquery.js +202 -128
- data/lib/tinymce/railtie.rb +6 -0
- data/lib/tinymce/version.rb +1 -2
- metadata +5 -6
@@ -5,9 +5,9 @@
|
|
5
5
|
var tinymce = {
|
6
6
|
majorVersion : '3',
|
7
7
|
|
8
|
-
minorVersion : '4.
|
8
|
+
minorVersion : '4.8',
|
9
9
|
|
10
|
-
releaseDate : '
|
10
|
+
releaseDate : '2012-02-02',
|
11
11
|
|
12
12
|
_init : function() {
|
13
13
|
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
@@ -535,7 +535,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
535
535
|
// And this is also more efficient
|
536
536
|
for (i = 0; i<li.length; i++) {
|
537
537
|
c = li[i];
|
538
|
-
s = c.cb.apply(c.scope, a);
|
538
|
+
s = c.cb.apply(c.scope, a.length > 0 ? a : [c.scope]);
|
539
539
|
|
540
540
|
if (s === false)
|
541
541
|
break;
|
@@ -578,7 +578,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|
578
578
|
|
579
579
|
// Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)
|
580
580
|
u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something
|
581
|
-
u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([
|
581
|
+
u = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);
|
582
582
|
each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], function(v, i) {
|
583
583
|
var s = u[i];
|
584
584
|
|
@@ -1048,7 +1048,10 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1048
1048
|
TAB: 9,
|
1049
1049
|
SPACEBAR: 32,
|
1050
1050
|
UP: 38,
|
1051
|
-
DOWN: 40
|
1051
|
+
DOWN: 40,
|
1052
|
+
modifierPressed: function (e) {
|
1053
|
+
return e.shiftKey || e.ctrlKey || e.altKey;
|
1054
|
+
}
|
1052
1055
|
}
|
1053
1056
|
})(tinymce);
|
1054
1057
|
|
@@ -1062,7 +1065,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1062
1065
|
var rng, blockElm, node, clonedSpan, isDelete;
|
1063
1066
|
|
1064
1067
|
isDelete = e.keyCode == DELETE;
|
1065
|
-
if (isDelete || e.keyCode == BACKSPACE) {
|
1068
|
+
if ((isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
|
1066
1069
|
e.preventDefault();
|
1067
1070
|
rng = selection.getRng();
|
1068
1071
|
|
@@ -1179,6 +1182,26 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1179
1182
|
});
|
1180
1183
|
};
|
1181
1184
|
|
1185
|
+
function removeStylesOnPTagsInheritedFromHeadingTag(ed) {
|
1186
|
+
ed.onKeyDown.add(function(ed, event) {
|
1187
|
+
function checkInHeadingTag(ed) {
|
1188
|
+
var currentNode = ed.selection.getNode();
|
1189
|
+
var headingTags = 'h1,h2,h3,h4,h5,h6';
|
1190
|
+
return ed.dom.is(currentNode, headingTags) || ed.dom.getParent(currentNode, headingTags) !== null;
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
if (event.keyCode === VK.ENTER && !VK.modifierPressed(event) && checkInHeadingTag(ed)) {
|
1194
|
+
setTimeout(function() {
|
1195
|
+
var currentNode = ed.selection.getNode();
|
1196
|
+
if (ed.dom.is(currentNode, 'p')) {
|
1197
|
+
ed.dom.setAttrib(currentNode, 'style', null);
|
1198
|
+
// While tiny's content is correct after this method call, the content shown is not representative of it and needs to be 'repainted'
|
1199
|
+
ed.execCommand('mceCleanup');
|
1200
|
+
}
|
1201
|
+
}, 0);
|
1202
|
+
}
|
1203
|
+
});
|
1204
|
+
}
|
1182
1205
|
function selectionChangeNodeChanged(ed) {
|
1183
1206
|
var lastRng, selectionTimer;
|
1184
1207
|
|
@@ -1203,7 +1226,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1203
1226
|
function ensureBodyHasRoleApplication(ed) {
|
1204
1227
|
document.body.setAttribute("role", "application");
|
1205
1228
|
}
|
1206
|
-
|
1229
|
+
|
1207
1230
|
tinymce.create('tinymce.util.Quirks', {
|
1208
1231
|
Quirks: function(ed) {
|
1209
1232
|
// WebKit
|
@@ -1224,6 +1247,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|
1224
1247
|
removeHrOnBackspace(ed);
|
1225
1248
|
emptyEditorWhenDeleting(ed);
|
1226
1249
|
ensureBodyHasRoleApplication(ed);
|
1250
|
+
removeStylesOnPTagsInheritedFromHeadingTag(ed)
|
1227
1251
|
}
|
1228
1252
|
|
1229
1253
|
// Gecko
|
@@ -3929,6 +3953,7 @@ tinymce.html.Writer = function(settings) {
|
|
3929
3953
|
|
3930
3954
|
return this.run(e, function(e) {
|
3931
3955
|
var s = t.settings;
|
3956
|
+
var originalValue = e.getAttribute(n);
|
3932
3957
|
if (v !== null) {
|
3933
3958
|
switch (n) {
|
3934
3959
|
case "style":
|
@@ -3975,6 +4000,12 @@ tinymce.html.Writer = function(settings) {
|
|
3975
4000
|
e.setAttribute(n, '' + v, 2);
|
3976
4001
|
else
|
3977
4002
|
e.removeAttribute(n, 2);
|
4003
|
+
|
4004
|
+
// fire onChangeAttrib event for attributes that have changed
|
4005
|
+
if (tinyMCE.activeEditor && originalValue != v) {
|
4006
|
+
var ed = tinyMCE.activeEditor;
|
4007
|
+
ed.onSetAttrib.dispatch(ed, e, n, v);
|
4008
|
+
}
|
3978
4009
|
});
|
3979
4010
|
},
|
3980
4011
|
|
@@ -4680,6 +4711,12 @@ tinymce.html.Writer = function(settings) {
|
|
4680
4711
|
function trim(node) {
|
4681
4712
|
var i, children = node.childNodes, type = node.nodeType;
|
4682
4713
|
|
4714
|
+
function surroundedBySpans(node) {
|
4715
|
+
var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN';
|
4716
|
+
var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN';
|
4717
|
+
return previousIsSpan && nextIsSpan;
|
4718
|
+
}
|
4719
|
+
|
4683
4720
|
if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark')
|
4684
4721
|
return;
|
4685
4722
|
|
@@ -4690,7 +4727,10 @@ tinymce.html.Writer = function(settings) {
|
|
4690
4727
|
// Keep non whitespace text nodes
|
4691
4728
|
if (type == 3 && node.nodeValue.length > 0) {
|
4692
4729
|
// If parent element isn't a block or there isn't any useful contents for example "<p> </p>"
|
4693
|
-
if
|
4730
|
+
// Also keep text nodes with only spaces if surrounded by spans.
|
4731
|
+
// eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
|
4732
|
+
var trimmedLength = tinymce.trim(node.nodeValue).length;
|
4733
|
+
if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength == 0 && surroundedBySpans(node))
|
4694
4734
|
return;
|
4695
4735
|
} else if (type == 1) {
|
4696
4736
|
// If the only child is a bookmark then move it up
|
@@ -4727,9 +4767,9 @@ tinymce.html.Writer = function(settings) {
|
|
4727
4767
|
|
4728
4768
|
// Insert middle chunk
|
4729
4769
|
if (re)
|
4730
|
-
|
4731
|
-
|
4732
|
-
|
4770
|
+
pa.replaceChild(re, e);
|
4771
|
+
else
|
4772
|
+
pa.insertBefore(e, pe);
|
4733
4773
|
|
4734
4774
|
// Insert after chunk
|
4735
4775
|
pa.insertBefore(trim(aft), pe);
|
@@ -8029,7 +8069,8 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8029
8069
|
}
|
8030
8070
|
|
8031
8071
|
s.addRange(r);
|
8032
|
-
t
|
8072
|
+
// adding range isn't always successful so we need to check range count otherwise an exception can occur
|
8073
|
+
t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;
|
8033
8074
|
}
|
8034
8075
|
} else {
|
8035
8076
|
// Is W3C Range
|
@@ -8141,6 +8182,11 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8141
8182
|
normalize : function() {
|
8142
8183
|
var self = this, rng, normalized;
|
8143
8184
|
|
8185
|
+
// TODO:
|
8186
|
+
// Retain selection direction.
|
8187
|
+
// Lean left/right on Gecko for inline elements.
|
8188
|
+
// Run this on mouse up/key up when the user manually moves the selection
|
8189
|
+
|
8144
8190
|
// Normalize only on non IE browsers for now
|
8145
8191
|
if (tinymce.isIE)
|
8146
8192
|
return;
|
@@ -8175,18 +8221,24 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8175
8221
|
if (node.nodeType === 3) {
|
8176
8222
|
offset = start ? 0 : node.nodeValue.length - 1;
|
8177
8223
|
container = node;
|
8224
|
+
normalized = true;
|
8178
8225
|
break;
|
8179
8226
|
}
|
8180
8227
|
|
8181
|
-
// Found a BR element that we can place the caret before
|
8182
|
-
if (node.nodeName
|
8228
|
+
// Found a BR/IMG element that we can place the caret before
|
8229
|
+
if (/^(BR|IMG)$/.test(node.nodeName)) {
|
8183
8230
|
offset = dom.nodeIndex(node);
|
8184
8231
|
container = node.parentNode;
|
8232
|
+
|
8233
|
+
// Put caret after image when moving the end point
|
8234
|
+
if (node.nodeName == "IMG" && !start) {
|
8235
|
+
offset++;
|
8236
|
+
}
|
8237
|
+
|
8238
|
+
normalized = true;
|
8185
8239
|
break;
|
8186
8240
|
}
|
8187
8241
|
} while (node = (start ? walker.next() : walker.prev()));
|
8188
|
-
|
8189
|
-
normalized = true;
|
8190
8242
|
}
|
8191
8243
|
}
|
8192
8244
|
}
|
@@ -8201,7 +8253,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8201
8253
|
// Normalize the end points
|
8202
8254
|
normalizeEndPoint(true);
|
8203
8255
|
|
8204
|
-
if (rng.collapsed)
|
8256
|
+
if (!rng.collapsed)
|
8205
8257
|
normalizeEndPoint();
|
8206
8258
|
|
8207
8259
|
// Set the selection if it was normalized
|
@@ -8313,12 +8365,11 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8313
8365
|
if (!settings.apply_source_formatting)
|
8314
8366
|
settings.indent = false;
|
8315
8367
|
|
8316
|
-
settings.remove_trailing_brs = true;
|
8317
|
-
|
8318
8368
|
// Default DOM and Schema if they are undefined
|
8319
8369
|
dom = dom || tinymce.DOM;
|
8320
8370
|
schema = schema || new tinymce.html.Schema(settings);
|
8321
8371
|
settings.entity_encoding = settings.entity_encoding || 'named';
|
8372
|
+
settings.remove_trailing_brs = "remove_trailing_brs" in settings ? settings.remove_trailing_brs : true;
|
8322
8373
|
|
8323
8374
|
onPreProcess = new tinymce.util.Dispatcher(self);
|
8324
8375
|
|
@@ -8382,8 +8433,8 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|
8382
8433
|
function trim(value) {
|
8383
8434
|
return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n')
|
8384
8435
|
.replace(/^[\r\n]*|[\r\n]*$/g, '')
|
8385
|
-
.replace(/^\s*(
|
8386
|
-
.replace(/\s*(
|
8436
|
+
.replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '')
|
8437
|
+
.replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, '');
|
8387
8438
|
};
|
8388
8439
|
|
8389
8440
|
while (i--) {
|
@@ -9684,7 +9735,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
9684
9735
|
// Internal functions
|
9685
9736
|
_setupKeyboardNav : function(){
|
9686
9737
|
var contextMenu, menuItems, t=this;
|
9687
|
-
contextMenu = DOM.
|
9738
|
+
contextMenu = DOM.get('menu_' + t.id);
|
9688
9739
|
menuItems = DOM.select('a[role=option]', 'menu_' + t.id);
|
9689
9740
|
menuItems.splice(0,0,contextMenu);
|
9690
9741
|
t.keyboardNav = new tinymce.ui.KeyboardNavigation({
|
@@ -9791,10 +9842,26 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
9791
9842
|
},
|
9792
9843
|
|
9793
9844
|
postRender : function() {
|
9794
|
-
var t = this, s = t.settings;
|
9845
|
+
var t = this, s = t.settings, bookmark;
|
9795
9846
|
|
9847
|
+
// In IE a large image that occupies the entire editor area will be deselected when a button is clicked, so
|
9848
|
+
// need to keep the selection in case the selection is lost
|
9849
|
+
if (tinymce.isIE && t.editor) {
|
9850
|
+
tinymce.dom.Event.add(t.id, 'mousedown', function(e) {
|
9851
|
+
bookmark = t.editor.selection.getBookmark();
|
9852
|
+
});
|
9853
|
+
}
|
9796
9854
|
tinymce.dom.Event.add(t.id, 'click', function(e) {
|
9797
|
-
if (!t.isDisabled())
|
9855
|
+
if (!t.isDisabled()) {
|
9856
|
+
// restore the selection in case the selection is lost in IE
|
9857
|
+
if (tinymce.isIE && t.editor && bookmark) {
|
9858
|
+
tinymce.activeEditor.selection.moveToBookmark(bookmark);
|
9859
|
+
}
|
9860
|
+
return s.onclick.call(s.scope, e);
|
9861
|
+
}
|
9862
|
+
});
|
9863
|
+
tinymce.dom.Event.add(t.id, 'keyup', function(e) {
|
9864
|
+
if (!t.isDisabled() && e.keyCode==tinymce.VK.SPACEBAR)
|
9798
9865
|
return s.onclick.call(s.scope, e);
|
9799
9866
|
});
|
9800
9867
|
}
|
@@ -10501,15 +10568,21 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|
10501
10568
|
}
|
10502
10569
|
|
10503
10570
|
n = DOM.add(tr, 'td');
|
10504
|
-
|
10505
|
-
role : 'option',
|
10571
|
+
var settings = {
|
10506
10572
|
href : 'javascript:;',
|
10507
10573
|
style : {
|
10508
10574
|
backgroundColor : '#' + c
|
10509
10575
|
},
|
10510
10576
|
'title': t.editor.getLang('colors.' + c, c),
|
10511
10577
|
'data-mce-color' : '#' + c
|
10512
|
-
}
|
10578
|
+
};
|
10579
|
+
|
10580
|
+
// adding a proper ARIA role = button causes JAWS to read things incorrectly on IE.
|
10581
|
+
if (!tinymce.isIE ) {
|
10582
|
+
settings['role']= 'option';
|
10583
|
+
}
|
10584
|
+
|
10585
|
+
n = DOM.add(n, 'a', settings);
|
10513
10586
|
|
10514
10587
|
if (t.editor.forcedHighContrastMode) {
|
10515
10588
|
n = DOM.add(n, 'canvas', { width: 16, height: 16, 'aria-hidden': 'true' });
|
@@ -11145,7 +11218,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11145
11218
|
Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko,
|
11146
11219
|
isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
|
11147
11220
|
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
|
11148
|
-
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
|
11221
|
+
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode, VK = tinymce.VK;
|
11149
11222
|
|
11150
11223
|
tinymce.create('tinymce.Editor', {
|
11151
11224
|
Editor : function(id, s) {
|
@@ -11169,6 +11242,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11169
11242
|
|
11170
11243
|
'onPostRender',
|
11171
11244
|
|
11245
|
+
'onLoad',
|
11246
|
+
|
11172
11247
|
'onInit',
|
11173
11248
|
|
11174
11249
|
'onRemove',
|
@@ -11231,7 +11306,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11231
11306
|
|
11232
11307
|
'onVisualAid',
|
11233
11308
|
|
11234
|
-
'onSetProgressState'
|
11309
|
+
'onSetProgressState',
|
11310
|
+
|
11311
|
+
'onSetAttrib'
|
11235
11312
|
], function(e) {
|
11236
11313
|
t[e] = new Dispatcher(t);
|
11237
11314
|
});
|
@@ -11583,7 +11660,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
11583
11660
|
bc = bc[t.id] || '';
|
11584
11661
|
}
|
11585
11662
|
|
11586
|
-
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"><br></body></html>';
|
11663
|
+
t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '" onload="window.parent.tinyMCE.get(\'' + t.id + '\').onLoad.dispatch();"><br></body></html>';
|
11587
11664
|
|
11588
11665
|
// Domain relaxing enabled, then set document domain
|
11589
11666
|
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
|
@@ -12051,7 +12128,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12051
12128
|
}
|
12052
12129
|
|
12053
12130
|
t._refreshContentEditable();
|
12054
|
-
selection.normalize();
|
12055
12131
|
|
12056
12132
|
// Is not content editable
|
12057
12133
|
if (!ce)
|
@@ -12823,30 +12899,32 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
12823
12899
|
|
12824
12900
|
// Add block quote deletion handler
|
12825
12901
|
t.onKeyDown.add(function(ed, e) {
|
12826
|
-
|
12827
|
-
|
12902
|
+
if (e.keyCode != VK.BACKSPACE)
|
12903
|
+
return;
|
12904
|
+
|
12905
|
+
var rng = ed.selection.getRng();
|
12906
|
+
if (!rng.collapsed)
|
12828
12907
|
return;
|
12829
12908
|
|
12830
|
-
var n =
|
12831
|
-
var offset =
|
12909
|
+
var n = rng.startContainer;
|
12910
|
+
var offset = rng.startOffset;
|
12832
12911
|
|
12833
12912
|
while (n && n.nodeType && n.nodeType != 1 && n.parentNode)
|
12834
12913
|
n = n.parentNode;
|
12835
|
-
|
12914
|
+
|
12836
12915
|
// Is the cursor at the beginning of a blockquote?
|
12837
12916
|
if (n && n.parentNode && n.parentNode.tagName === 'BLOCKQUOTE' && n.parentNode.firstChild == n && offset == 0) {
|
12838
12917
|
// Remove the blockquote
|
12839
12918
|
ed.formatter.toggle('blockquote', null, n.parentNode);
|
12840
12919
|
|
12841
12920
|
// Move the caret to the beginning of n
|
12842
|
-
var rng = ed.selection.getRng();
|
12843
12921
|
rng.setStart(n, 0);
|
12844
12922
|
rng.setEnd(n, 0);
|
12845
12923
|
ed.selection.setRng(rng);
|
12846
12924
|
ed.selection.collapse(false);
|
12847
12925
|
}
|
12848
12926
|
});
|
12849
|
-
|
12927
|
+
|
12850
12928
|
|
12851
12929
|
|
12852
12930
|
// Add reset handler
|
@@ -13054,9 +13132,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13054
13132
|
if (target !== t.getBody()) {
|
13055
13133
|
t.dom.setAttrib(target, "style", null);
|
13056
13134
|
|
13057
|
-
|
13058
|
-
|
13059
|
-
|
13135
|
+
each(template, function(attr) {
|
13136
|
+
target.setAttributeNode(attr.cloneNode(true));
|
13137
|
+
});
|
13060
13138
|
}
|
13061
13139
|
};
|
13062
13140
|
}
|
@@ -13368,6 +13446,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13368
13446
|
var parser, serializer, parentNode, rootNode, fragment, args,
|
13369
13447
|
marker, nodeRect, viewPortRect, rng, node, node2, bookmarkHtml, viewportBodyElement;
|
13370
13448
|
|
13449
|
+
//selection.normalize();
|
13450
|
+
|
13371
13451
|
// Setup parser and serializer
|
13372
13452
|
parser = editor.parser;
|
13373
13453
|
serializer = new tinymce.html.Serializer({}, editor.schema);
|
@@ -13594,7 +13674,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
13594
13674
|
addCommands({
|
13595
13675
|
// Override justify commands
|
13596
13676
|
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) {
|
13597
|
-
|
13677
|
+
var name = 'align' + command.substring(7);
|
13678
|
+
// Use Formatter.matchNode instead of Formatter.match so that we don't match on parent node. This fixes bug where for both left
|
13679
|
+
// and right align buttons can be active. This could occur when selected nodes have align right and the parent has align left.
|
13680
|
+
var nodes = selection.isCollapsed() ? [selection.getNode()] : selection.getSelectedBlocks();
|
13681
|
+
var matches = tinymce.map(nodes, function(node) {
|
13682
|
+
return !!formatter.matchNode(node, name);
|
13683
|
+
});
|
13684
|
+
return tinymce.inArray(matches, TRUE) !== -1;
|
13598
13685
|
},
|
13599
13686
|
|
13600
13687
|
'Bold,Italic,Underline,Strikethrough,Superscript,Subscript' : function(command) {
|
@@ -14991,30 +15078,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
14991
15078
|
function apply(name, vars, node) {
|
14992
15079
|
var formatList = get(name), format = formatList[0], bookmark, rng, i, isCollapsed = selection.isCollapsed();
|
14993
15080
|
|
14994
|
-
function moveStart(rng) {
|
14995
|
-
var container = rng.startContainer,
|
14996
|
-
offset = rng.startOffset,
|
14997
|
-
walker, node;
|
14998
|
-
|
14999
|
-
// Move startContainer/startOffset in to a suitable node
|
15000
|
-
if (container.nodeType == 1 || container.nodeValue === "") {
|
15001
|
-
container = container.nodeType == 1 ? container.childNodes[offset] : container;
|
15002
|
-
|
15003
|
-
// Might fail if the offset is behind the last element in it's container
|
15004
|
-
if (container) {
|
15005
|
-
walker = new TreeWalker(container, container.parentNode);
|
15006
|
-
for (node = walker.current(); node; node = walker.next()) {
|
15007
|
-
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
15008
|
-
rng.setStart(node, 0);
|
15009
|
-
break;
|
15010
|
-
}
|
15011
|
-
}
|
15012
|
-
}
|
15013
|
-
}
|
15014
|
-
|
15015
|
-
return rng;
|
15016
|
-
};
|
15017
|
-
|
15018
15081
|
function setElementFormat(elm, fmt) {
|
15019
15082
|
fmt = fmt || format;
|
15020
15083
|
|
@@ -15365,7 +15428,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15365
15428
|
}
|
15366
15429
|
|
15367
15430
|
selection.moveToBookmark(bookmark);
|
15368
|
-
|
15431
|
+
moveStart(selection.getRng(TRUE));
|
15369
15432
|
ed.nodeChanged();
|
15370
15433
|
} else
|
15371
15434
|
performCaretAction('apply', name, vars);
|
@@ -15375,44 +15438,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
15375
15438
|
|
15376
15439
|
function remove(name, vars, node) {
|
15377
15440
|
var formatList = get(name), format = formatList[0], bookmark, i, rng;
|
15378
|
-
function moveStart(rng) {
|
15379
|
-
var container = rng.startContainer,
|
15380
|
-
offset = rng.startOffset,
|
15381
|
-
walker, node, nodes, tmpNode;
|
15382
|
-
|
15383
|
-
// Convert text node into index if possible
|
15384
|
-
if (container.nodeType == 3 && offset >= container.nodeValue.length - 1) {
|
15385
|
-
container = container.parentNode;
|
15386
|
-
offset = nodeIndex(container) + 1;
|
15387
|
-
}
|
15388
|
-
|
15389
|
-
// Move startContainer/startOffset in to a suitable node
|
15390
|
-
if (container.nodeType == 1) {
|
15391
|
-
nodes = container.childNodes;
|
15392
|
-
container = nodes[Math.min(offset, nodes.length - 1)];
|
15393
|
-
walker = new TreeWalker(container);
|
15394
|
-
|
15395
|
-
// If offset is at end of the parent node walk to the next one
|
15396
|
-
if (offset > nodes.length - 1)
|
15397
|
-
walker.next();
|
15398
|
-
|
15399
|
-
for (node = walker.current(); node; node = walker.next()) {
|
15400
|
-
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
15401
|
-
// IE has a "neat" feature where it moves the start node into the closest element
|
15402
|
-
// we can avoid this by inserting an element before it and then remove it after we set the selection
|
15403
|
-
tmpNode = dom.create('a', null, INVISIBLE_CHAR);
|
15404
|
-
node.parentNode.insertBefore(tmpNode, node);
|
15405
|
-
|
15406
|
-
// Set selection and remove tmpNode
|
15407
|
-
rng.setStart(node, 0);
|
15408
|
-
selection.setRng(rng);
|
15409
|
-
dom.remove(tmpNode);
|
15410
|
-
|
15411
|
-
return;
|
15412
|
-
}
|
15413
|
-
}
|
15414
|
-
}
|
15415
|
-
};
|
15416
15441
|
|
15417
15442
|
// Merges the styles for each node
|
15418
15443
|
function process(node) {
|
@@ -16500,7 +16525,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
16500
16525
|
dom.remove(node);
|
16501
16526
|
} else {
|
16502
16527
|
child = findFirstTextNode(node);
|
16503
|
-
|
16528
|
+
|
16529
|
+
if (child.nodeValue.charAt(0) === INVISIBLE_CHAR) {
|
16530
|
+
child = child.deleteData(0, 1);
|
16531
|
+
}
|
16532
|
+
|
16504
16533
|
dom.remove(node, 1);
|
16505
16534
|
}
|
16506
16535
|
|
@@ -16630,34 +16659,39 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
16630
16659
|
}
|
16631
16660
|
};
|
16632
16661
|
|
16633
|
-
//
|
16634
|
-
|
16635
|
-
|
16662
|
+
// Only bind the caret events once
|
16663
|
+
if (!self._hasCaretEvents) {
|
16664
|
+
// Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements
|
16665
|
+
ed.onBeforeGetContent.addToTop(function() {
|
16666
|
+
var nodes = [], i;
|
16636
16667
|
|
16637
|
-
|
16638
|
-
|
16639
|
-
|
16640
|
-
|
16641
|
-
|
16668
|
+
if (isCaretContainerEmpty(getParentCaretContainer(selection.getStart()), nodes)) {
|
16669
|
+
// Mark children
|
16670
|
+
i = nodes.length;
|
16671
|
+
while (i--) {
|
16672
|
+
dom.setAttrib(nodes[i], 'data-mce-bogus', '1');
|
16673
|
+
}
|
16642
16674
|
}
|
16643
|
-
}
|
16644
|
-
});
|
16675
|
+
});
|
16645
16676
|
|
16646
|
-
|
16647
|
-
|
16648
|
-
|
16649
|
-
|
16677
|
+
// Remove caret container on mouse up and on key up
|
16678
|
+
tinymce.each('onMouseUp onKeyUp'.split(' '), function(name) {
|
16679
|
+
ed[name].addToTop(function() {
|
16680
|
+
removeCaretContainer();
|
16681
|
+
});
|
16650
16682
|
});
|
16651
|
-
});
|
16652
16683
|
|
16653
|
-
|
16654
|
-
|
16655
|
-
|
16684
|
+
// Remove caret container on keydown and it's a backspace, enter or left/right arrow keys
|
16685
|
+
ed.onKeyDown.addToTop(function(ed, e) {
|
16686
|
+
var keyCode = e.keyCode;
|
16656
16687
|
|
16657
|
-
|
16658
|
-
|
16659
|
-
|
16660
|
-
|
16688
|
+
if (keyCode == 8 || keyCode == 37 || keyCode == 39) {
|
16689
|
+
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
16690
|
+
}
|
16691
|
+
});
|
16692
|
+
|
16693
|
+
self._hasCaretEvents = true;
|
16694
|
+
}
|
16661
16695
|
|
16662
16696
|
// Do apply or remove caret format
|
16663
16697
|
if (type == "apply") {
|
@@ -16666,6 +16700,46 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|
16666
16700
|
removeCaretFormat();
|
16667
16701
|
}
|
16668
16702
|
};
|
16703
|
+
|
16704
|
+
function moveStart(rng) {
|
16705
|
+
var container = rng.startContainer,
|
16706
|
+
offset = rng.startOffset,
|
16707
|
+
walker, node, nodes, tmpNode;
|
16708
|
+
|
16709
|
+
// Convert text node into index if possible
|
16710
|
+
if (container.nodeType == 3 && offset >= container.nodeValue.length - 1) {
|
16711
|
+
container = container.parentNode;
|
16712
|
+
offset = nodeIndex(container) + 1;
|
16713
|
+
}
|
16714
|
+
|
16715
|
+
// Move startContainer/startOffset in to a suitable node
|
16716
|
+
if (container.nodeType == 1) {
|
16717
|
+
nodes = container.childNodes;
|
16718
|
+
container = nodes[Math.min(offset, nodes.length - 1)];
|
16719
|
+
walker = new TreeWalker(container);
|
16720
|
+
|
16721
|
+
// If offset is at end of the parent node walk to the next one
|
16722
|
+
if (offset > nodes.length - 1)
|
16723
|
+
walker.next();
|
16724
|
+
|
16725
|
+
for (node = walker.current(); node; node = walker.next()) {
|
16726
|
+
if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {
|
16727
|
+
// IE has a "neat" feature where it moves the start node into the closest element
|
16728
|
+
// we can avoid this by inserting an element before it and then remove it after we set the selection
|
16729
|
+
tmpNode = dom.create('a', null, INVISIBLE_CHAR);
|
16730
|
+
node.parentNode.insertBefore(tmpNode, node);
|
16731
|
+
|
16732
|
+
// Set selection and remove tmpNode
|
16733
|
+
rng.setStart(node, 0);
|
16734
|
+
selection.setRng(rng);
|
16735
|
+
dom.remove(tmpNode);
|
16736
|
+
|
16737
|
+
return;
|
16738
|
+
}
|
16739
|
+
}
|
16740
|
+
}
|
16741
|
+
};
|
16742
|
+
|
16669
16743
|
};
|
16670
16744
|
})(tinymce);
|
16671
16745
|
|