tinymce-rails 4.0.26 → 4.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/assets/source/tinymce/tinymce.jquery.js +1111 -671
- data/app/assets/source/tinymce/tinymce.js +1108 -668
- data/lib/tinymce/rails/configuration.rb +28 -2
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/spellchecker/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/css/visualblocks.css +7 -0
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.jquery.js +10 -10
- data/vendor/assets/javascripts/tinymce/tinymce.js +11 -10
- metadata +2 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
// 4.0.
|
1
|
+
// 4.0.28 (2014-05-27)
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Compiled inline version. (Library mode)
|
@@ -97,6 +97,11 @@
|
|
97
97
|
/*jshint loopfunc:true*/
|
98
98
|
/*eslint no-loop-func:0 */
|
99
99
|
|
100
|
+
/**
|
101
|
+
* This class wraps the browsers native event logic with more convenient methods.
|
102
|
+
*
|
103
|
+
* @class tinymce.dom.EventUtils
|
104
|
+
*/
|
100
105
|
define("tinymce/dom/EventUtils", [], function() {
|
101
106
|
"use strict";
|
102
107
|
|
@@ -657,7 +662,7 @@ define("tinymce/dom/EventUtils", [], function() {
|
|
657
662
|
*/
|
658
663
|
|
659
664
|
/*jshint bitwise:false, expr:true, noempty:false, sub:true, eqnull:true, latedef:false, maxlen:255 */
|
660
|
-
/*eslint dot-notation:0, no-empty:0, no-cond-assign:0, no-unused-expressions:0, new-cap:0, no-nested-ternary:0, func-style:0, no-bitwise: 0 */
|
665
|
+
/*eslint dot-notation:0, no-empty:0, no-cond-assign:0, no-unused-expressions:0, new-cap:0, no-nested-ternary:0, func-style:0, no-bitwise:0, max-len:0, brace-style:0 */
|
661
666
|
|
662
667
|
/*
|
663
668
|
* Sizzle CSS Selector Engine
|
@@ -3344,10 +3349,15 @@ define("tinymce/html/Styles", [], function() {
|
|
3344
3349
|
urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,
|
3345
3350
|
styleRegExp = /\s*([^:]+):\s*([^;]+);?/g,
|
3346
3351
|
trimRightRegExp = /\s+$/,
|
3347
|
-
undef, i, encodingLookup = {}, encodingItems, invisibleChar = '\uFEFF';
|
3352
|
+
undef, i, encodingLookup = {}, encodingItems, validStyles, invalidStyles, invisibleChar = '\uFEFF';
|
3348
3353
|
|
3349
3354
|
settings = settings || {};
|
3350
3355
|
|
3356
|
+
if (schema) {
|
3357
|
+
validStyles = schema.getValidStyles();
|
3358
|
+
invalidStyles = schema.getInvalidStyles();
|
3359
|
+
}
|
3360
|
+
|
3351
3361
|
encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
|
3352
3362
|
for (i = 0; i < encodingItems.length; i++) {
|
3353
3363
|
encodingLookup[encodingItems[i]] = invisibleChar + i;
|
@@ -3605,16 +3615,16 @@ define("tinymce/html/Styles", [], function() {
|
|
3605
3615
|
*
|
3606
3616
|
* @method serialize
|
3607
3617
|
* @param {Object} styles Object to serialize as string for example: {border: '1px solid red'}
|
3608
|
-
* @param {String}
|
3618
|
+
* @param {String} elementName Optional element name, if specified only the styles that matches the schema will be serialized.
|
3609
3619
|
* @return {String} String representation of the style object for example: border: 1px solid red.
|
3610
3620
|
*/
|
3611
|
-
serialize: function(styles,
|
3621
|
+
serialize: function(styles, elementName) {
|
3612
3622
|
var css = '', name, value;
|
3613
3623
|
|
3614
3624
|
function serializeStyles(name) {
|
3615
3625
|
var styleList, i, l, value;
|
3616
3626
|
|
3617
|
-
styleList =
|
3627
|
+
styleList = validStyles[name];
|
3618
3628
|
if (styleList) {
|
3619
3629
|
for (i = 0, l = styleList.length; i < l; i++) {
|
3620
3630
|
name = styleList[i];
|
@@ -3627,18 +3637,36 @@ define("tinymce/html/Styles", [], function() {
|
|
3627
3637
|
}
|
3628
3638
|
}
|
3629
3639
|
|
3640
|
+
function isValid(name, elementName) {
|
3641
|
+
var styleMap;
|
3642
|
+
|
3643
|
+
styleMap = invalidStyles['*'];
|
3644
|
+
if (styleMap && styleMap[name]) {
|
3645
|
+
return false;
|
3646
|
+
}
|
3647
|
+
|
3648
|
+
styleMap = invalidStyles[elementName];
|
3649
|
+
if (styleMap && styleMap[name]) {
|
3650
|
+
return false;
|
3651
|
+
}
|
3652
|
+
|
3653
|
+
return true;
|
3654
|
+
}
|
3655
|
+
|
3630
3656
|
// Serialize styles according to schema
|
3631
|
-
if (
|
3657
|
+
if (elementName && validStyles) {
|
3632
3658
|
// Serialize global styles and element specific styles
|
3633
3659
|
serializeStyles('*');
|
3634
|
-
serializeStyles(
|
3660
|
+
serializeStyles(elementName);
|
3635
3661
|
} else {
|
3636
3662
|
// Output the styles in the order they are inside the object
|
3637
3663
|
for (name in styles) {
|
3638
3664
|
value = styles[name];
|
3639
3665
|
|
3640
3666
|
if (value !== undef && value.length > 0) {
|
3641
|
-
|
3667
|
+
if (!invalidStyles || isValid(name, elementName)) {
|
3668
|
+
css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
|
3669
|
+
}
|
3642
3670
|
}
|
3643
3671
|
}
|
3644
3672
|
}
|
@@ -5912,7 +5940,9 @@ define("tinymce/dom/DOMUtils", [
|
|
5912
5940
|
selectorVal = selector;
|
5913
5941
|
|
5914
5942
|
if (selector === '*') {
|
5915
|
-
selector = function(node) {
|
5943
|
+
selector = function(node) {
|
5944
|
+
return node.nodeType == 1;
|
5945
|
+
};
|
5916
5946
|
} else {
|
5917
5947
|
selector = function(node) {
|
5918
5948
|
return self.is(node, selectorVal);
|
@@ -6229,7 +6259,7 @@ define("tinymce/dom/DOMUtils", [
|
|
6229
6259
|
});
|
6230
6260
|
|
6231
6261
|
// Default px suffix on these
|
6232
|
-
if (typeof(value) === 'number' && !numericCssMap[name]) {
|
6262
|
+
if (((typeof(value) === 'number') || /^[\-0-9\.]+$/.test(value)) && !numericCssMap[name]) {
|
6233
6263
|
value += 'px';
|
6234
6264
|
}
|
6235
6265
|
|
@@ -8990,7 +9020,8 @@ define("tinymce/html/Schema", [
|
|
8990
9020
|
if (type != "html5-strict") {
|
8991
9021
|
addAttrs("script", "language xml:space");
|
8992
9022
|
addAttrs("style", "xml:space");
|
8993
|
-
addAttrs("object", "declare classid codebase codetype archive standby align border hspace vspace");
|
9023
|
+
addAttrs("object", "declare classid code codebase codetype archive standby align border hspace vspace");
|
9024
|
+
addAttrs("embed", "align name hspace vspace");
|
8994
9025
|
addAttrs("param", "valuetype type");
|
8995
9026
|
addAttrs("a", "charset name rev shape coords");
|
8996
9027
|
addAttrs("br", "clear");
|
@@ -9059,6 +9090,27 @@ define("tinymce/html/Schema", [
|
|
9059
9090
|
return schema;
|
9060
9091
|
}
|
9061
9092
|
|
9093
|
+
function compileElementMap(value, mode) {
|
9094
|
+
var styles;
|
9095
|
+
|
9096
|
+
if (value) {
|
9097
|
+
styles = {};
|
9098
|
+
|
9099
|
+
if (typeof value == 'string') {
|
9100
|
+
value = {
|
9101
|
+
'*': value
|
9102
|
+
};
|
9103
|
+
}
|
9104
|
+
|
9105
|
+
// Convert styles into a rule list
|
9106
|
+
each(value, function(value, key) {
|
9107
|
+
styles[key] = mode == 'map' ? makeMap(value, /[, ]/) : explode(value, /[, ]/);
|
9108
|
+
});
|
9109
|
+
}
|
9110
|
+
|
9111
|
+
return styles;
|
9112
|
+
}
|
9113
|
+
|
9062
9114
|
/**
|
9063
9115
|
* Constructs a new Schema instance.
|
9064
9116
|
*
|
@@ -9067,9 +9119,10 @@ define("tinymce/html/Schema", [
|
|
9067
9119
|
* @param {Object} settings Name/value settings object.
|
9068
9120
|
*/
|
9069
9121
|
return function(settings) {
|
9070
|
-
var self = this, elements = {}, children = {}, patternElements = [], validStyles, schemaItems;
|
9071
|
-
var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap;
|
9072
|
-
var blockElementsMap, nonEmptyElementsMap, textBlockElementsMap,
|
9122
|
+
var self = this, elements = {}, children = {}, patternElements = [], validStyles, invalidStyles, schemaItems;
|
9123
|
+
var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses;
|
9124
|
+
var blockElementsMap, nonEmptyElementsMap, textBlockElementsMap, textInlineElementsMap;
|
9125
|
+
var customElementsMap = {}, specialElements = {};
|
9073
9126
|
|
9074
9127
|
// Creates an lookup table map object for the specified option or the default value
|
9075
9128
|
function createLookupTable(option, default_value, extendWith) {
|
@@ -9101,15 +9154,9 @@ define("tinymce/html/Schema", [
|
|
9101
9154
|
settings.valid_elements = '*[*]';
|
9102
9155
|
}
|
9103
9156
|
|
9104
|
-
|
9105
|
-
|
9106
|
-
|
9107
|
-
|
9108
|
-
// Convert styles into a rule list
|
9109
|
-
each(settings.valid_styles, function(value, key) {
|
9110
|
-
validStyles[key] = explode(value);
|
9111
|
-
});
|
9112
|
-
}
|
9157
|
+
validStyles = compileElementMap(settings.valid_styles);
|
9158
|
+
invalidStyles = compileElementMap(settings.invalid_styles, 'map');
|
9159
|
+
validClasses = compileElementMap(settings.valid_classes, 'map');
|
9113
9160
|
|
9114
9161
|
// Setup map objects
|
9115
9162
|
whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object');
|
@@ -9124,6 +9171,8 @@ define("tinymce/html/Schema", [
|
|
9124
9171
|
blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' +
|
9125
9172
|
'th tr td li ol ul caption dl dt dd noscript menu isindex option ' +
|
9126
9173
|
'datalist select optgroup', textBlockElementsMap);
|
9174
|
+
textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' +
|
9175
|
+
'dfn code mark q sup sub samp');
|
9127
9176
|
|
9128
9177
|
each((settings.special || 'script noscript style textarea').split(' '), function(name) {
|
9129
9178
|
specialElements[name] = new RegExp('<\/' + name + '[^>]*>','gi');
|
@@ -9480,10 +9529,32 @@ define("tinymce/html/Schema", [
|
|
9480
9529
|
/**
|
9481
9530
|
* Name/value map object with valid styles for each element.
|
9482
9531
|
*
|
9483
|
-
* @
|
9532
|
+
* @method getValidStyles
|
9533
|
+
* @type Object
|
9534
|
+
*/
|
9535
|
+
self.getValidStyles = function() {
|
9536
|
+
return validStyles;
|
9537
|
+
};
|
9538
|
+
|
9539
|
+
/**
|
9540
|
+
* Name/value map object with valid styles for each element.
|
9541
|
+
*
|
9542
|
+
* @method getInvalidStyles
|
9484
9543
|
* @type Object
|
9485
9544
|
*/
|
9486
|
-
self.
|
9545
|
+
self.getInvalidStyles = function() {
|
9546
|
+
return invalidStyles;
|
9547
|
+
};
|
9548
|
+
|
9549
|
+
/**
|
9550
|
+
* Name/value map object with valid classes for each element.
|
9551
|
+
*
|
9552
|
+
* @method getValidClasses
|
9553
|
+
* @type Object
|
9554
|
+
*/
|
9555
|
+
self.getValidClasses = function() {
|
9556
|
+
return validClasses;
|
9557
|
+
};
|
9487
9558
|
|
9488
9559
|
/**
|
9489
9560
|
* Returns a map with boolean attributes.
|
@@ -9515,6 +9586,16 @@ define("tinymce/html/Schema", [
|
|
9515
9586
|
return textBlockElementsMap;
|
9516
9587
|
};
|
9517
9588
|
|
9589
|
+
/**
|
9590
|
+
* Returns a map of inline text format nodes for example strong/span or ins.
|
9591
|
+
*
|
9592
|
+
* @method getTextInlineElements
|
9593
|
+
* @return {Object} Name/value lookup map for text format elements.
|
9594
|
+
*/
|
9595
|
+
self.getTextInlineElements = function() {
|
9596
|
+
return textInlineElementsMap;
|
9597
|
+
};
|
9598
|
+
|
9518
9599
|
/**
|
9519
9600
|
* Returns a map with short ended elements such as BR or IMG.
|
9520
9601
|
*
|
@@ -9744,6 +9825,36 @@ define("tinymce/html/SaxParser", [
|
|
9744
9825
|
], function(Schema, Entities, Tools) {
|
9745
9826
|
var each = Tools.each;
|
9746
9827
|
|
9828
|
+
/**
|
9829
|
+
* Returns the index of the end tag for a specific start tag. This can be
|
9830
|
+
* used to skip all children of a parent element from being processed.
|
9831
|
+
*/
|
9832
|
+
function skipUntilEndTag(schema, html, startIndex) {
|
9833
|
+
var count = 1, matches, tokenRegExp, shortEndedElements;
|
9834
|
+
|
9835
|
+
shortEndedElements = schema.getShortEndedElements();
|
9836
|
+
tokenRegExp = /<([!?\/])?([A-Za-z0-9\-\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
|
9837
|
+
tokenRegExp.lastIndex = startIndex;
|
9838
|
+
|
9839
|
+
while ((matches = tokenRegExp.exec(html))) {
|
9840
|
+
if (matches[1] === '/') { // End element
|
9841
|
+
count--;
|
9842
|
+
} else if (!matches[1]) { // Start element
|
9843
|
+
if (matches[2] in shortEndedElements) {
|
9844
|
+
continue;
|
9845
|
+
}
|
9846
|
+
|
9847
|
+
count++;
|
9848
|
+
}
|
9849
|
+
|
9850
|
+
if (count === 0) {
|
9851
|
+
break;
|
9852
|
+
}
|
9853
|
+
}
|
9854
|
+
|
9855
|
+
return tokenRegExp.lastIndex;
|
9856
|
+
}
|
9857
|
+
|
9747
9858
|
/**
|
9748
9859
|
* Constructs a new SaxParser instance.
|
9749
9860
|
*
|
@@ -10025,7 +10136,13 @@ define("tinymce/html/SaxParser", [
|
|
10025
10136
|
}
|
10026
10137
|
|
10027
10138
|
// Invalidate element if it's marked as bogus
|
10028
|
-
if (attrList.map['data-mce-bogus']) {
|
10139
|
+
if ((attr = attrList.map['data-mce-bogus'])) {
|
10140
|
+
if (attr === 'all') {
|
10141
|
+
index = skipUntilEndTag(schema, html, tokenRegExp.lastIndex);
|
10142
|
+
tokenRegExp.lastIndex = index;
|
10143
|
+
continue;
|
10144
|
+
}
|
10145
|
+
|
10029
10146
|
isValidElement = false;
|
10030
10147
|
}
|
10031
10148
|
}
|
@@ -10688,7 +10805,7 @@ define("tinymce/html/DomParser", [
|
|
10688
10805
|
// Leave nodes that have a name like <a name="name">
|
10689
10806
|
if (!node.attributes.map.name && !node.attributes.map.id) {
|
10690
10807
|
tempNode = node.parent;
|
10691
|
-
node.
|
10808
|
+
node.unwrap();
|
10692
10809
|
node = tempNode;
|
10693
10810
|
return;
|
10694
10811
|
}
|
@@ -10867,6 +10984,48 @@ define("tinymce/html/DomParser", [
|
|
10867
10984
|
}
|
10868
10985
|
});
|
10869
10986
|
}
|
10987
|
+
|
10988
|
+
if (settings.validate && schema.getValidClasses()) {
|
10989
|
+
self.addAttributeFilter('class', function(nodes) {
|
10990
|
+
var i = nodes.length, node, classList, ci, className, classValue;
|
10991
|
+
var validClasses = schema.getValidClasses(), validClassesMap, valid;
|
10992
|
+
|
10993
|
+
while (i--) {
|
10994
|
+
node = nodes[i];
|
10995
|
+
classList = node.attr('class').split(' ');
|
10996
|
+
classValue = '';
|
10997
|
+
|
10998
|
+
for (ci = 0; ci < classList.length; ci++) {
|
10999
|
+
className = classList[ci];
|
11000
|
+
valid = false;
|
11001
|
+
|
11002
|
+
validClassesMap = validClasses['*'];
|
11003
|
+
if (validClassesMap && validClassesMap[className]) {
|
11004
|
+
valid = true;
|
11005
|
+
}
|
11006
|
+
|
11007
|
+
validClassesMap = validClasses[node.name];
|
11008
|
+
if (!valid && validClassesMap && !validClassesMap[className]) {
|
11009
|
+
valid = true;
|
11010
|
+
}
|
11011
|
+
|
11012
|
+
if (valid) {
|
11013
|
+
if (classValue) {
|
11014
|
+
classValue += ' ';
|
11015
|
+
}
|
11016
|
+
|
11017
|
+
classValue += className;
|
11018
|
+
}
|
11019
|
+
}
|
11020
|
+
|
11021
|
+
if (!classValue.length) {
|
11022
|
+
classValue = null;
|
11023
|
+
}
|
11024
|
+
|
11025
|
+
node.attr('class', classValue);
|
11026
|
+
}
|
11027
|
+
});
|
11028
|
+
}
|
10870
11029
|
};
|
10871
11030
|
});
|
10872
11031
|
|
@@ -11349,15 +11508,6 @@ define("tinymce/dom/Serializer", [
|
|
11349
11508
|
}
|
11350
11509
|
});
|
11351
11510
|
|
11352
|
-
// Remove expando attributes
|
11353
|
-
htmlParser.addAttributeFilter('data-mce-expando', function(nodes, name) {
|
11354
|
-
var i = nodes.length;
|
11355
|
-
|
11356
|
-
while (i--) {
|
11357
|
-
nodes[i].attr(name, null);
|
11358
|
-
}
|
11359
|
-
});
|
11360
|
-
|
11361
11511
|
htmlParser.addNodeFilter('noscript', function(nodes) {
|
11362
11512
|
var i = nodes.length, node;
|
11363
11513
|
|
@@ -11372,7 +11522,7 @@ define("tinymce/dom/Serializer", [
|
|
11372
11522
|
|
11373
11523
|
// Force script into CDATA sections and remove the mce- prefix also add comments around styles
|
11374
11524
|
htmlParser.addNodeFilter('script,style', function(nodes, name) {
|
11375
|
-
var i = nodes.length, node, value;
|
11525
|
+
var i = nodes.length, node, value, type;
|
11376
11526
|
|
11377
11527
|
function trim(value) {
|
11378
11528
|
/*jshint maxlen:255 */
|
@@ -11388,9 +11538,12 @@ define("tinymce/dom/Serializer", [
|
|
11388
11538
|
value = node.firstChild ? node.firstChild.value : '';
|
11389
11539
|
|
11390
11540
|
if (name === "script") {
|
11391
|
-
// Remove mce- prefix from script elements and remove default
|
11392
|
-
|
11393
|
-
node.attr('type'
|
11541
|
+
// Remove mce- prefix from script elements and remove default type since the user specified
|
11542
|
+
// a script element without type attribute
|
11543
|
+
type = node.attr('type');
|
11544
|
+
if (type) {
|
11545
|
+
node.attr('type', type == 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
|
11546
|
+
}
|
11394
11547
|
|
11395
11548
|
if (value.length > 0) {
|
11396
11549
|
node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
|
@@ -11457,13 +11610,19 @@ define("tinymce/dom/Serializer", [
|
|
11457
11610
|
}
|
11458
11611
|
|
11459
11612
|
// Remove internal data attributes
|
11460
|
-
htmlParser.addAttributeFilter(
|
11461
|
-
|
11613
|
+
htmlParser.addAttributeFilter(
|
11614
|
+
'data-mce-src,data-mce-href,data-mce-style,' +
|
11615
|
+
'data-mce-selected,data-mce-expando,' +
|
11616
|
+
'data-mce-type,data-mce-resize',
|
11462
11617
|
|
11463
|
-
|
11464
|
-
nodes
|
11618
|
+
function(nodes, name) {
|
11619
|
+
var i = nodes.length;
|
11620
|
+
|
11621
|
+
while (i--) {
|
11622
|
+
nodes[i].attr(name, null);
|
11623
|
+
}
|
11465
11624
|
}
|
11466
|
-
|
11625
|
+
);
|
11467
11626
|
|
11468
11627
|
// Return public methods
|
11469
11628
|
return {
|
@@ -11799,15 +11958,17 @@ define("tinymce/dom/TridentSelection", [], function() {
|
|
11799
11958
|
|
11800
11959
|
// Find the text node and offset
|
11801
11960
|
while (sibling) {
|
11802
|
-
|
11803
|
-
|
11804
|
-
|
11805
|
-
|
11806
|
-
|
11807
|
-
|
11808
|
-
|
11809
|
-
|
11810
|
-
|
11961
|
+
if (sibling.nodeType == 3) {
|
11962
|
+
nodeValue = sibling.nodeValue;
|
11963
|
+
textNodeOffset += nodeValue.length;
|
11964
|
+
|
11965
|
+
// We are at or passed the position we where looking for
|
11966
|
+
if (textNodeOffset >= offset) {
|
11967
|
+
container = sibling;
|
11968
|
+
textNodeOffset -= offset;
|
11969
|
+
textNodeOffset = nodeValue.length - textNodeOffset;
|
11970
|
+
break;
|
11971
|
+
}
|
11811
11972
|
}
|
11812
11973
|
|
11813
11974
|
sibling = sibling.nextSibling;
|
@@ -11832,13 +11993,15 @@ define("tinymce/dom/TridentSelection", [], function() {
|
|
11832
11993
|
}
|
11833
11994
|
|
11834
11995
|
while (sibling) {
|
11835
|
-
|
11996
|
+
if (sibling.nodeType == 3) {
|
11997
|
+
textNodeOffset += sibling.nodeValue.length;
|
11836
11998
|
|
11837
|
-
|
11838
|
-
|
11839
|
-
|
11840
|
-
|
11841
|
-
|
11999
|
+
// We are at or passed the position we where looking for
|
12000
|
+
if (textNodeOffset >= offset) {
|
12001
|
+
container = sibling;
|
12002
|
+
textNodeOffset -= offset;
|
12003
|
+
break;
|
12004
|
+
}
|
11842
12005
|
}
|
11843
12006
|
|
11844
12007
|
sibling = sibling.previousSibling;
|
@@ -12171,8 +12334,8 @@ define("tinymce/util/VK", [
|
|
12171
12334
|
},
|
12172
12335
|
|
12173
12336
|
metaKeyPressed: function(e) {
|
12174
|
-
// Check if ctrl or meta key is pressed
|
12175
|
-
return (Env.mac ? e.metaKey : e.ctrlKey
|
12337
|
+
// Check if ctrl or meta key is pressed. Edge case for AltGr on Windows where it produces ctrlKey+altKey states
|
12338
|
+
return (Env.mac ? e.metaKey : e.ctrlKey && !e.altKey);
|
12176
12339
|
}
|
12177
12340
|
};
|
12178
12341
|
});
|
@@ -12704,7 +12867,7 @@ define("tinymce/dom/ControlSelection", [
|
|
12704
12867
|
// Included from: js/tinymce/classes/dom/RangeUtils.js
|
12705
12868
|
|
12706
12869
|
/**
|
12707
|
-
*
|
12870
|
+
* RangeUtils.js
|
12708
12871
|
*
|
12709
12872
|
* Copyright, Moxiecode Systems AB
|
12710
12873
|
* Released under LGPL License.
|
@@ -12714,7 +12877,7 @@ define("tinymce/dom/ControlSelection", [
|
|
12714
12877
|
*/
|
12715
12878
|
|
12716
12879
|
/**
|
12717
|
-
*
|
12880
|
+
* This class contains a few utility methods for ranges.
|
12718
12881
|
*
|
12719
12882
|
* @class tinymce.dom.RangeUtils
|
12720
12883
|
* @private
|
@@ -12725,6 +12888,20 @@ define("tinymce/dom/RangeUtils", [
|
|
12725
12888
|
], function(Tools, TreeWalker) {
|
12726
12889
|
var each = Tools.each;
|
12727
12890
|
|
12891
|
+
function getEndChild(container, index) {
|
12892
|
+
var childNodes = container.childNodes;
|
12893
|
+
|
12894
|
+
index--;
|
12895
|
+
|
12896
|
+
if (index > childNodes.length - 1) {
|
12897
|
+
index = childNodes.length - 1;
|
12898
|
+
} else if (index < 0) {
|
12899
|
+
index = 0;
|
12900
|
+
}
|
12901
|
+
|
12902
|
+
return childNodes[index] || container;
|
12903
|
+
}
|
12904
|
+
|
12728
12905
|
function RangeUtils(dom) {
|
12729
12906
|
/**
|
12730
12907
|
* Walks the specified range like object and executes the callback for each sibling collection it finds.
|
@@ -12837,7 +13014,7 @@ define("tinymce/dom/RangeUtils", [
|
|
12837
13014
|
|
12838
13015
|
// If index based end position then resolve it
|
12839
13016
|
if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) {
|
12840
|
-
endContainer = endContainer
|
13017
|
+
endContainer = getEndChild(endContainer, endOffset);
|
12841
13018
|
}
|
12842
13019
|
|
12843
13020
|
// Same container
|
@@ -13184,6 +13361,398 @@ define("tinymce/dom/RangeUtils", [
|
|
13184
13361
|
return RangeUtils;
|
13185
13362
|
});
|
13186
13363
|
|
13364
|
+
// Included from: js/tinymce/classes/dom/BookmarkManager.js
|
13365
|
+
|
13366
|
+
/**
|
13367
|
+
* BookmarkManager.js
|
13368
|
+
*
|
13369
|
+
* Copyright, Moxiecode Systems AB
|
13370
|
+
* Released under LGPL License.
|
13371
|
+
*
|
13372
|
+
* License: http://www.tinymce.com/license
|
13373
|
+
* Contributing: http://www.tinymce.com/contributing
|
13374
|
+
*/
|
13375
|
+
|
13376
|
+
/**
|
13377
|
+
* This class handles selection bookmarks.
|
13378
|
+
*
|
13379
|
+
* @class tinymce.dom.BookmarkManager
|
13380
|
+
*/
|
13381
|
+
define("tinymce/dom/BookmarkManager", [
|
13382
|
+
"tinymce/Env",
|
13383
|
+
"tinymce/util/Tools"
|
13384
|
+
], function(Env, Tools) {
|
13385
|
+
/**
|
13386
|
+
* Constructs a new BookmarkManager instance for a specific selection instance.
|
13387
|
+
*
|
13388
|
+
* @constructor
|
13389
|
+
* @method BookmarkManager
|
13390
|
+
* @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
|
13391
|
+
*/
|
13392
|
+
function BookmarkManager(selection) {
|
13393
|
+
var dom = selection.dom;
|
13394
|
+
|
13395
|
+
/**
|
13396
|
+
* Returns a bookmark location for the current selection. This bookmark object
|
13397
|
+
* can then be used to restore the selection after some content modification to the document.
|
13398
|
+
*
|
13399
|
+
* @method getBookmark
|
13400
|
+
* @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
|
13401
|
+
* @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
|
13402
|
+
* @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
|
13403
|
+
* @example
|
13404
|
+
* // Stores a bookmark of the current selection
|
13405
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
13406
|
+
*
|
13407
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
13408
|
+
*
|
13409
|
+
* // Restore the selection bookmark
|
13410
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
13411
|
+
*/
|
13412
|
+
this.getBookmark = function(type, normalized) {
|
13413
|
+
var rng, rng2, id, collapsed, name, element, chr = '', styles;
|
13414
|
+
|
13415
|
+
function findIndex(name, element) {
|
13416
|
+
var index = 0;
|
13417
|
+
|
13418
|
+
Tools.each(dom.select(name), function(node, i) {
|
13419
|
+
if (node == element) {
|
13420
|
+
index = i;
|
13421
|
+
}
|
13422
|
+
});
|
13423
|
+
|
13424
|
+
return index;
|
13425
|
+
}
|
13426
|
+
|
13427
|
+
function normalizeTableCellSelection(rng) {
|
13428
|
+
function moveEndPoint(start) {
|
13429
|
+
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
13430
|
+
|
13431
|
+
container = rng[prefix + 'Container'];
|
13432
|
+
offset = rng[prefix + 'Offset'];
|
13433
|
+
|
13434
|
+
if (container.nodeType == 1 && container.nodeName == "TR") {
|
13435
|
+
childNodes = container.childNodes;
|
13436
|
+
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
13437
|
+
if (container) {
|
13438
|
+
offset = start ? 0 : container.childNodes.length;
|
13439
|
+
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
13440
|
+
}
|
13441
|
+
}
|
13442
|
+
}
|
13443
|
+
|
13444
|
+
moveEndPoint(true);
|
13445
|
+
moveEndPoint();
|
13446
|
+
|
13447
|
+
return rng;
|
13448
|
+
}
|
13449
|
+
|
13450
|
+
function getLocation() {
|
13451
|
+
var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
|
13452
|
+
|
13453
|
+
function getPoint(rng, start) {
|
13454
|
+
var container = rng[start ? 'startContainer' : 'endContainer'],
|
13455
|
+
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
13456
|
+
|
13457
|
+
if (container.nodeType == 3) {
|
13458
|
+
if (normalized) {
|
13459
|
+
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
13460
|
+
offset += node.nodeValue.length;
|
13461
|
+
}
|
13462
|
+
}
|
13463
|
+
|
13464
|
+
point.push(offset);
|
13465
|
+
} else {
|
13466
|
+
childNodes = container.childNodes;
|
13467
|
+
|
13468
|
+
if (offset >= childNodes.length && childNodes.length) {
|
13469
|
+
after = 1;
|
13470
|
+
offset = Math.max(0, childNodes.length - 1);
|
13471
|
+
}
|
13472
|
+
|
13473
|
+
point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
|
13474
|
+
}
|
13475
|
+
|
13476
|
+
for (; container && container != root; container = container.parentNode) {
|
13477
|
+
point.push(dom.nodeIndex(container, normalized));
|
13478
|
+
}
|
13479
|
+
|
13480
|
+
return point;
|
13481
|
+
}
|
13482
|
+
|
13483
|
+
bookmark.start = getPoint(rng, true);
|
13484
|
+
|
13485
|
+
if (!selection.isCollapsed()) {
|
13486
|
+
bookmark.end = getPoint(rng);
|
13487
|
+
}
|
13488
|
+
|
13489
|
+
return bookmark;
|
13490
|
+
}
|
13491
|
+
|
13492
|
+
if (type == 2) {
|
13493
|
+
element = selection.getNode();
|
13494
|
+
name = element ? element.nodeName : null;
|
13495
|
+
|
13496
|
+
if (name == 'IMG') {
|
13497
|
+
return {name: name, index: findIndex(name, element)};
|
13498
|
+
}
|
13499
|
+
|
13500
|
+
if (selection.tridentSel) {
|
13501
|
+
return selection.tridentSel.getBookmark(type);
|
13502
|
+
}
|
13503
|
+
|
13504
|
+
return getLocation();
|
13505
|
+
}
|
13506
|
+
|
13507
|
+
// Handle simple range
|
13508
|
+
if (type) {
|
13509
|
+
return {rng: selection.getRng()};
|
13510
|
+
}
|
13511
|
+
|
13512
|
+
rng = selection.getRng();
|
13513
|
+
id = dom.uniqueId();
|
13514
|
+
collapsed = selection.isCollapsed();
|
13515
|
+
styles = 'overflow:hidden;line-height:0px';
|
13516
|
+
|
13517
|
+
// Explorer method
|
13518
|
+
if (rng.duplicate || rng.item) {
|
13519
|
+
// Text selection
|
13520
|
+
if (!rng.item) {
|
13521
|
+
rng2 = rng.duplicate();
|
13522
|
+
|
13523
|
+
try {
|
13524
|
+
// Insert start marker
|
13525
|
+
rng.collapse();
|
13526
|
+
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
13527
|
+
|
13528
|
+
// Insert end marker
|
13529
|
+
if (!collapsed) {
|
13530
|
+
rng2.collapse(false);
|
13531
|
+
|
13532
|
+
// Detect the empty space after block elements in IE and move the
|
13533
|
+
// end back one character <p></p>] becomes <p>]</p>
|
13534
|
+
rng.moveToElementText(rng2.parentElement());
|
13535
|
+
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
13536
|
+
rng2.move('character', -1);
|
13537
|
+
}
|
13538
|
+
|
13539
|
+
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
13540
|
+
}
|
13541
|
+
} catch (ex) {
|
13542
|
+
// IE might throw unspecified error so lets ignore it
|
13543
|
+
return null;
|
13544
|
+
}
|
13545
|
+
} else {
|
13546
|
+
// Control selection
|
13547
|
+
element = rng.item(0);
|
13548
|
+
name = element.nodeName;
|
13549
|
+
|
13550
|
+
return {name: name, index: findIndex(name, element)};
|
13551
|
+
}
|
13552
|
+
} else {
|
13553
|
+
element = selection.getNode();
|
13554
|
+
name = element.nodeName;
|
13555
|
+
if (name == 'IMG') {
|
13556
|
+
return {name: name, index: findIndex(name, element)};
|
13557
|
+
}
|
13558
|
+
|
13559
|
+
// W3C method
|
13560
|
+
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
13561
|
+
|
13562
|
+
// Insert end marker
|
13563
|
+
if (!collapsed) {
|
13564
|
+
rng2.collapse(false);
|
13565
|
+
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
13566
|
+
}
|
13567
|
+
|
13568
|
+
rng = normalizeTableCellSelection(rng);
|
13569
|
+
rng.collapse(true);
|
13570
|
+
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
13571
|
+
}
|
13572
|
+
|
13573
|
+
selection.moveToBookmark({id: id, keep: 1});
|
13574
|
+
|
13575
|
+
return {id: id};
|
13576
|
+
};
|
13577
|
+
|
13578
|
+
/**
|
13579
|
+
* Restores the selection to the specified bookmark.
|
13580
|
+
*
|
13581
|
+
* @method moveToBookmark
|
13582
|
+
* @param {Object} bookmark Bookmark to restore selection from.
|
13583
|
+
* @return {Boolean} true/false if it was successful or not.
|
13584
|
+
* @example
|
13585
|
+
* // Stores a bookmark of the current selection
|
13586
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
13587
|
+
*
|
13588
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
13589
|
+
*
|
13590
|
+
* // Restore the selection bookmark
|
13591
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
13592
|
+
*/
|
13593
|
+
this.moveToBookmark = function(bookmark) {
|
13594
|
+
var rng, root, startContainer, endContainer, startOffset, endOffset;
|
13595
|
+
|
13596
|
+
function setEndPoint(start) {
|
13597
|
+
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
13598
|
+
|
13599
|
+
if (point) {
|
13600
|
+
offset = point[0];
|
13601
|
+
|
13602
|
+
// Find container node
|
13603
|
+
for (node = root, i = point.length - 1; i >= 1; i--) {
|
13604
|
+
children = node.childNodes;
|
13605
|
+
|
13606
|
+
if (point[i] > children.length - 1) {
|
13607
|
+
return;
|
13608
|
+
}
|
13609
|
+
|
13610
|
+
node = children[point[i]];
|
13611
|
+
}
|
13612
|
+
|
13613
|
+
// Move text offset to best suitable location
|
13614
|
+
if (node.nodeType === 3) {
|
13615
|
+
offset = Math.min(point[0], node.nodeValue.length);
|
13616
|
+
}
|
13617
|
+
|
13618
|
+
// Move element offset to best suitable location
|
13619
|
+
if (node.nodeType === 1) {
|
13620
|
+
offset = Math.min(point[0], node.childNodes.length);
|
13621
|
+
}
|
13622
|
+
|
13623
|
+
// Set offset within container node
|
13624
|
+
if (start) {
|
13625
|
+
rng.setStart(node, offset);
|
13626
|
+
} else {
|
13627
|
+
rng.setEnd(node, offset);
|
13628
|
+
}
|
13629
|
+
}
|
13630
|
+
|
13631
|
+
return true;
|
13632
|
+
}
|
13633
|
+
|
13634
|
+
function restoreEndPoint(suffix) {
|
13635
|
+
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
13636
|
+
|
13637
|
+
if (marker) {
|
13638
|
+
node = marker.parentNode;
|
13639
|
+
|
13640
|
+
if (suffix == 'start') {
|
13641
|
+
if (!keep) {
|
13642
|
+
idx = dom.nodeIndex(marker);
|
13643
|
+
} else {
|
13644
|
+
node = marker.firstChild;
|
13645
|
+
idx = 1;
|
13646
|
+
}
|
13647
|
+
|
13648
|
+
startContainer = endContainer = node;
|
13649
|
+
startOffset = endOffset = idx;
|
13650
|
+
} else {
|
13651
|
+
if (!keep) {
|
13652
|
+
idx = dom.nodeIndex(marker);
|
13653
|
+
} else {
|
13654
|
+
node = marker.firstChild;
|
13655
|
+
idx = 1;
|
13656
|
+
}
|
13657
|
+
|
13658
|
+
endContainer = node;
|
13659
|
+
endOffset = idx;
|
13660
|
+
}
|
13661
|
+
|
13662
|
+
if (!keep) {
|
13663
|
+
prev = marker.previousSibling;
|
13664
|
+
next = marker.nextSibling;
|
13665
|
+
|
13666
|
+
// Remove all marker text nodes
|
13667
|
+
Tools.each(Tools.grep(marker.childNodes), function(node) {
|
13668
|
+
if (node.nodeType == 3) {
|
13669
|
+
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
13670
|
+
}
|
13671
|
+
});
|
13672
|
+
|
13673
|
+
// Remove marker but keep children if for example contents where inserted into the marker
|
13674
|
+
// Also remove duplicated instances of the marker for example by a
|
13675
|
+
// split operation or by WebKit auto split on paste feature
|
13676
|
+
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
13677
|
+
dom.remove(marker, 1);
|
13678
|
+
}
|
13679
|
+
|
13680
|
+
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
13681
|
+
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
13682
|
+
// isn't worth the effort. Sorry, Opera but it's just a fact
|
13683
|
+
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
|
13684
|
+
idx = prev.nodeValue.length;
|
13685
|
+
prev.appendData(next.nodeValue);
|
13686
|
+
dom.remove(next);
|
13687
|
+
|
13688
|
+
if (suffix == 'start') {
|
13689
|
+
startContainer = endContainer = prev;
|
13690
|
+
startOffset = endOffset = idx;
|
13691
|
+
} else {
|
13692
|
+
endContainer = prev;
|
13693
|
+
endOffset = idx;
|
13694
|
+
}
|
13695
|
+
}
|
13696
|
+
}
|
13697
|
+
}
|
13698
|
+
}
|
13699
|
+
|
13700
|
+
function addBogus(node) {
|
13701
|
+
// Adds a bogus BR element for empty block elements
|
13702
|
+
if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
|
13703
|
+
node.innerHTML = '<br data-mce-bogus="1" />';
|
13704
|
+
}
|
13705
|
+
|
13706
|
+
return node;
|
13707
|
+
}
|
13708
|
+
|
13709
|
+
if (bookmark) {
|
13710
|
+
if (bookmark.start) {
|
13711
|
+
rng = dom.createRng();
|
13712
|
+
root = dom.getRoot();
|
13713
|
+
|
13714
|
+
if (selection.tridentSel) {
|
13715
|
+
return selection.tridentSel.moveToBookmark(bookmark);
|
13716
|
+
}
|
13717
|
+
|
13718
|
+
if (setEndPoint(true) && setEndPoint()) {
|
13719
|
+
selection.setRng(rng);
|
13720
|
+
}
|
13721
|
+
} else if (bookmark.id) {
|
13722
|
+
// Restore start/end points
|
13723
|
+
restoreEndPoint('start');
|
13724
|
+
restoreEndPoint('end');
|
13725
|
+
|
13726
|
+
if (startContainer) {
|
13727
|
+
rng = dom.createRng();
|
13728
|
+
rng.setStart(addBogus(startContainer), startOffset);
|
13729
|
+
rng.setEnd(addBogus(endContainer), endOffset);
|
13730
|
+
selection.setRng(rng);
|
13731
|
+
}
|
13732
|
+
} else if (bookmark.name) {
|
13733
|
+
selection.select(dom.select(bookmark.name)[bookmark.index]);
|
13734
|
+
} else if (bookmark.rng) {
|
13735
|
+
selection.setRng(bookmark.rng);
|
13736
|
+
}
|
13737
|
+
}
|
13738
|
+
};
|
13739
|
+
}
|
13740
|
+
|
13741
|
+
/**
|
13742
|
+
* Returns true/false if the specified node is a bookmark node or not.
|
13743
|
+
*
|
13744
|
+
* @static
|
13745
|
+
* @method isBookmarkNode
|
13746
|
+
* @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
|
13747
|
+
* @return {Boolean} true/false if the node is a bookmark node or not.
|
13748
|
+
*/
|
13749
|
+
BookmarkManager.isBookmarkNode = function(node) {
|
13750
|
+
return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
|
13751
|
+
};
|
13752
|
+
|
13753
|
+
return BookmarkManager;
|
13754
|
+
});
|
13755
|
+
|
13187
13756
|
// Included from: js/tinymce/classes/dom/Selection.js
|
13188
13757
|
|
13189
13758
|
/**
|
@@ -13210,11 +13779,12 @@ define("tinymce/dom/Selection", [
|
|
13210
13779
|
"tinymce/dom/TridentSelection",
|
13211
13780
|
"tinymce/dom/ControlSelection",
|
13212
13781
|
"tinymce/dom/RangeUtils",
|
13782
|
+
"tinymce/dom/BookmarkManager",
|
13213
13783
|
"tinymce/Env",
|
13214
13784
|
"tinymce/util/Tools"
|
13215
|
-
], function(TreeWalker, TridentSelection, ControlSelection, RangeUtils, Env, Tools) {
|
13216
|
-
var each = Tools.each,
|
13217
|
-
var isIE = Env.ie
|
13785
|
+
], function(TreeWalker, TridentSelection, ControlSelection, RangeUtils, BookmarkManager, Env, Tools) {
|
13786
|
+
var each = Tools.each, trim = Tools.trim;
|
13787
|
+
var isIE = Env.ie;
|
13218
13788
|
|
13219
13789
|
/**
|
13220
13790
|
* Constructs a new selection instance.
|
@@ -13232,7 +13802,7 @@ define("tinymce/dom/Selection", [
|
|
13232
13802
|
self.win = win;
|
13233
13803
|
self.serializer = serializer;
|
13234
13804
|
self.editor = editor;
|
13235
|
-
|
13805
|
+
self.bookmarkManager = new BookmarkManager(self);
|
13236
13806
|
self.controlSelection = new ControlSelection(self, editor);
|
13237
13807
|
|
13238
13808
|
// No W3C Range support
|
@@ -13532,169 +14102,7 @@ define("tinymce/dom/Selection", [
|
|
13532
14102
|
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
13533
14103
|
*/
|
13534
14104
|
getBookmark: function(type, normalized) {
|
13535
|
-
|
13536
|
-
|
13537
|
-
function findIndex(name, element) {
|
13538
|
-
var index = 0;
|
13539
|
-
|
13540
|
-
each(dom.select(name), function(node, i) {
|
13541
|
-
if (node == element) {
|
13542
|
-
index = i;
|
13543
|
-
}
|
13544
|
-
});
|
13545
|
-
|
13546
|
-
return index;
|
13547
|
-
}
|
13548
|
-
|
13549
|
-
function normalizeTableCellSelection(rng) {
|
13550
|
-
function moveEndPoint(start) {
|
13551
|
-
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
13552
|
-
|
13553
|
-
container = rng[prefix + 'Container'];
|
13554
|
-
offset = rng[prefix + 'Offset'];
|
13555
|
-
|
13556
|
-
if (container.nodeType == 1 && container.nodeName == "TR") {
|
13557
|
-
childNodes = container.childNodes;
|
13558
|
-
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
13559
|
-
if (container) {
|
13560
|
-
offset = start ? 0 : container.childNodes.length;
|
13561
|
-
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
13562
|
-
}
|
13563
|
-
}
|
13564
|
-
}
|
13565
|
-
|
13566
|
-
moveEndPoint(true);
|
13567
|
-
moveEndPoint();
|
13568
|
-
|
13569
|
-
return rng;
|
13570
|
-
}
|
13571
|
-
|
13572
|
-
function getLocation() {
|
13573
|
-
var rng = self.getRng(true), root = dom.getRoot(), bookmark = {};
|
13574
|
-
|
13575
|
-
function getPoint(rng, start) {
|
13576
|
-
var container = rng[start ? 'startContainer' : 'endContainer'],
|
13577
|
-
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
13578
|
-
|
13579
|
-
if (container.nodeType == 3) {
|
13580
|
-
if (normalized) {
|
13581
|
-
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
13582
|
-
offset += node.nodeValue.length;
|
13583
|
-
}
|
13584
|
-
}
|
13585
|
-
|
13586
|
-
point.push(offset);
|
13587
|
-
} else {
|
13588
|
-
childNodes = container.childNodes;
|
13589
|
-
|
13590
|
-
if (offset >= childNodes.length && childNodes.length) {
|
13591
|
-
after = 1;
|
13592
|
-
offset = Math.max(0, childNodes.length - 1);
|
13593
|
-
}
|
13594
|
-
|
13595
|
-
point.push(self.dom.nodeIndex(childNodes[offset], normalized) + after);
|
13596
|
-
}
|
13597
|
-
|
13598
|
-
for (; container && container != root; container = container.parentNode) {
|
13599
|
-
point.push(self.dom.nodeIndex(container, normalized));
|
13600
|
-
}
|
13601
|
-
|
13602
|
-
return point;
|
13603
|
-
}
|
13604
|
-
|
13605
|
-
bookmark.start = getPoint(rng, true);
|
13606
|
-
|
13607
|
-
if (!self.isCollapsed()) {
|
13608
|
-
bookmark.end = getPoint(rng);
|
13609
|
-
}
|
13610
|
-
|
13611
|
-
return bookmark;
|
13612
|
-
}
|
13613
|
-
|
13614
|
-
if (type == 2) {
|
13615
|
-
element = self.getNode();
|
13616
|
-
name = element ? element.nodeName : null;
|
13617
|
-
|
13618
|
-
if (name == 'IMG') {
|
13619
|
-
return {name: name, index: findIndex(name, element)};
|
13620
|
-
}
|
13621
|
-
|
13622
|
-
if (self.tridentSel) {
|
13623
|
-
return self.tridentSel.getBookmark(type);
|
13624
|
-
}
|
13625
|
-
|
13626
|
-
return getLocation();
|
13627
|
-
}
|
13628
|
-
|
13629
|
-
// Handle simple range
|
13630
|
-
if (type) {
|
13631
|
-
return {rng: self.getRng()};
|
13632
|
-
}
|
13633
|
-
|
13634
|
-
rng = self.getRng();
|
13635
|
-
id = dom.uniqueId();
|
13636
|
-
collapsed = self.isCollapsed();
|
13637
|
-
styles = 'overflow:hidden;line-height:0px';
|
13638
|
-
|
13639
|
-
// Explorer method
|
13640
|
-
if (rng.duplicate || rng.item) {
|
13641
|
-
// Text selection
|
13642
|
-
if (!rng.item) {
|
13643
|
-
rng2 = rng.duplicate();
|
13644
|
-
|
13645
|
-
try {
|
13646
|
-
// Insert start marker
|
13647
|
-
rng.collapse();
|
13648
|
-
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
13649
|
-
|
13650
|
-
// Insert end marker
|
13651
|
-
if (!collapsed) {
|
13652
|
-
rng2.collapse(false);
|
13653
|
-
|
13654
|
-
// Detect the empty space after block elements in IE and move the
|
13655
|
-
// end back one character <p></p>] becomes <p>]</p>
|
13656
|
-
rng.moveToElementText(rng2.parentElement());
|
13657
|
-
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
13658
|
-
rng2.move('character', -1);
|
13659
|
-
}
|
13660
|
-
|
13661
|
-
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
13662
|
-
}
|
13663
|
-
} catch (ex) {
|
13664
|
-
// IE might throw unspecified error so lets ignore it
|
13665
|
-
return null;
|
13666
|
-
}
|
13667
|
-
} else {
|
13668
|
-
// Control selection
|
13669
|
-
element = rng.item(0);
|
13670
|
-
name = element.nodeName;
|
13671
|
-
|
13672
|
-
return {name: name, index: findIndex(name, element)};
|
13673
|
-
}
|
13674
|
-
} else {
|
13675
|
-
element = self.getNode();
|
13676
|
-
name = element.nodeName;
|
13677
|
-
if (name == 'IMG') {
|
13678
|
-
return {name: name, index: findIndex(name, element)};
|
13679
|
-
}
|
13680
|
-
|
13681
|
-
// W3C method
|
13682
|
-
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
13683
|
-
|
13684
|
-
// Insert end marker
|
13685
|
-
if (!collapsed) {
|
13686
|
-
rng2.collapse(false);
|
13687
|
-
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
13688
|
-
}
|
13689
|
-
|
13690
|
-
rng = normalizeTableCellSelection(rng);
|
13691
|
-
rng.collapse(true);
|
13692
|
-
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
13693
|
-
}
|
13694
|
-
|
13695
|
-
self.moveToBookmark({id: id, keep: 1});
|
13696
|
-
|
13697
|
-
return {id: id};
|
14105
|
+
return this.bookmarkManager.getBookmark(type, normalized);
|
13698
14106
|
},
|
13699
14107
|
|
13700
14108
|
/**
|
@@ -13713,150 +14121,7 @@ define("tinymce/dom/Selection", [
|
|
13713
14121
|
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
13714
14122
|
*/
|
13715
14123
|
moveToBookmark: function(bookmark) {
|
13716
|
-
|
13717
|
-
|
13718
|
-
function setEndPoint(start) {
|
13719
|
-
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
13720
|
-
|
13721
|
-
if (point) {
|
13722
|
-
offset = point[0];
|
13723
|
-
|
13724
|
-
// Find container node
|
13725
|
-
for (node = root, i = point.length - 1; i >= 1; i--) {
|
13726
|
-
children = node.childNodes;
|
13727
|
-
|
13728
|
-
if (point[i] > children.length - 1) {
|
13729
|
-
return;
|
13730
|
-
}
|
13731
|
-
|
13732
|
-
node = children[point[i]];
|
13733
|
-
}
|
13734
|
-
|
13735
|
-
// Move text offset to best suitable location
|
13736
|
-
if (node.nodeType === 3) {
|
13737
|
-
offset = Math.min(point[0], node.nodeValue.length);
|
13738
|
-
}
|
13739
|
-
|
13740
|
-
// Move element offset to best suitable location
|
13741
|
-
if (node.nodeType === 1) {
|
13742
|
-
offset = Math.min(point[0], node.childNodes.length);
|
13743
|
-
}
|
13744
|
-
|
13745
|
-
// Set offset within container node
|
13746
|
-
if (start) {
|
13747
|
-
rng.setStart(node, offset);
|
13748
|
-
} else {
|
13749
|
-
rng.setEnd(node, offset);
|
13750
|
-
}
|
13751
|
-
}
|
13752
|
-
|
13753
|
-
return true;
|
13754
|
-
}
|
13755
|
-
|
13756
|
-
function restoreEndPoint(suffix) {
|
13757
|
-
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
13758
|
-
|
13759
|
-
if (marker) {
|
13760
|
-
node = marker.parentNode;
|
13761
|
-
|
13762
|
-
if (suffix == 'start') {
|
13763
|
-
if (!keep) {
|
13764
|
-
idx = dom.nodeIndex(marker);
|
13765
|
-
} else {
|
13766
|
-
node = marker.firstChild;
|
13767
|
-
idx = 1;
|
13768
|
-
}
|
13769
|
-
|
13770
|
-
startContainer = endContainer = node;
|
13771
|
-
startOffset = endOffset = idx;
|
13772
|
-
} else {
|
13773
|
-
if (!keep) {
|
13774
|
-
idx = dom.nodeIndex(marker);
|
13775
|
-
} else {
|
13776
|
-
node = marker.firstChild;
|
13777
|
-
idx = 1;
|
13778
|
-
}
|
13779
|
-
|
13780
|
-
endContainer = node;
|
13781
|
-
endOffset = idx;
|
13782
|
-
}
|
13783
|
-
|
13784
|
-
if (!keep) {
|
13785
|
-
prev = marker.previousSibling;
|
13786
|
-
next = marker.nextSibling;
|
13787
|
-
|
13788
|
-
// Remove all marker text nodes
|
13789
|
-
each(grep(marker.childNodes), function(node) {
|
13790
|
-
if (node.nodeType == 3) {
|
13791
|
-
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
13792
|
-
}
|
13793
|
-
});
|
13794
|
-
|
13795
|
-
// Remove marker but keep children if for example contents where inserted into the marker
|
13796
|
-
// Also remove duplicated instances of the marker for example by a
|
13797
|
-
// split operation or by WebKit auto split on paste feature
|
13798
|
-
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
13799
|
-
dom.remove(marker, 1);
|
13800
|
-
}
|
13801
|
-
|
13802
|
-
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
13803
|
-
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
13804
|
-
// isn't worth the effort. Sorry, Opera but it's just a fact
|
13805
|
-
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !isOpera) {
|
13806
|
-
idx = prev.nodeValue.length;
|
13807
|
-
prev.appendData(next.nodeValue);
|
13808
|
-
dom.remove(next);
|
13809
|
-
|
13810
|
-
if (suffix == 'start') {
|
13811
|
-
startContainer = endContainer = prev;
|
13812
|
-
startOffset = endOffset = idx;
|
13813
|
-
} else {
|
13814
|
-
endContainer = prev;
|
13815
|
-
endOffset = idx;
|
13816
|
-
}
|
13817
|
-
}
|
13818
|
-
}
|
13819
|
-
}
|
13820
|
-
}
|
13821
|
-
|
13822
|
-
function addBogus(node) {
|
13823
|
-
// Adds a bogus BR element for empty block elements
|
13824
|
-
if (dom.isBlock(node) && !node.innerHTML && !isIE) {
|
13825
|
-
node.innerHTML = '<br data-mce-bogus="1" />';
|
13826
|
-
}
|
13827
|
-
|
13828
|
-
return node;
|
13829
|
-
}
|
13830
|
-
|
13831
|
-
if (bookmark) {
|
13832
|
-
if (bookmark.start) {
|
13833
|
-
rng = dom.createRng();
|
13834
|
-
root = dom.getRoot();
|
13835
|
-
|
13836
|
-
if (self.tridentSel) {
|
13837
|
-
return self.tridentSel.moveToBookmark(bookmark);
|
13838
|
-
}
|
13839
|
-
|
13840
|
-
if (setEndPoint(true) && setEndPoint()) {
|
13841
|
-
self.setRng(rng);
|
13842
|
-
}
|
13843
|
-
} else if (bookmark.id) {
|
13844
|
-
// Restore start/end points
|
13845
|
-
restoreEndPoint('start');
|
13846
|
-
restoreEndPoint('end');
|
13847
|
-
|
13848
|
-
if (startContainer) {
|
13849
|
-
rng = dom.createRng();
|
13850
|
-
rng.setStart(addBogus(startContainer), startOffset);
|
13851
|
-
rng.setEnd(addBogus(endContainer), endOffset);
|
13852
|
-
self.setRng(rng);
|
13853
|
-
}
|
13854
|
-
} else if (bookmark.name) {
|
13855
|
-
self.select(dom.select(bookmark.name)[bookmark.index]);
|
13856
|
-
} else if (bookmark.rng) {
|
13857
|
-
self.setRng(bookmark.rng);
|
13858
|
-
}
|
13859
|
-
}
|
14124
|
+
return this.bookmarkManager.moveToBookmark(bookmark);
|
13860
14125
|
},
|
13861
14126
|
|
13862
14127
|
/**
|
@@ -14446,6 +14711,126 @@ define("tinymce/dom/Selection", [
|
|
14446
14711
|
return Selection;
|
14447
14712
|
});
|
14448
14713
|
|
14714
|
+
// Included from: js/tinymce/classes/dom/ElementUtils.js
|
14715
|
+
|
14716
|
+
/**
|
14717
|
+
* ElementUtils.js
|
14718
|
+
*
|
14719
|
+
* Copyright, Moxiecode Systems AB
|
14720
|
+
* Released under LGPL License.
|
14721
|
+
*
|
14722
|
+
* License: http://www.tinymce.com/license
|
14723
|
+
* Contributing: http://www.tinymce.com/contributing
|
14724
|
+
*/
|
14725
|
+
|
14726
|
+
/**
|
14727
|
+
* Utility class for various element specific functions.
|
14728
|
+
*
|
14729
|
+
* @private
|
14730
|
+
*/
|
14731
|
+
define("tinymce/dom/ElementUtils", [
|
14732
|
+
"tinymce/dom/BookmarkManager",
|
14733
|
+
"tinymce/util/Tools"
|
14734
|
+
], function(BookmarkManager, Tools) {
|
14735
|
+
var each = Tools.each;
|
14736
|
+
|
14737
|
+
function ElementUtils(dom) {
|
14738
|
+
/**
|
14739
|
+
* Compares two nodes and checks if it's attributes and styles matches.
|
14740
|
+
* This doesn't compare classes as items since their order is significant.
|
14741
|
+
*
|
14742
|
+
* @method compare
|
14743
|
+
* @param {Node} node1 First node to compare with.
|
14744
|
+
* @param {Node} node2 Second node to compare with.
|
14745
|
+
* @return {boolean} True/false if the nodes are the same or not.
|
14746
|
+
*/
|
14747
|
+
this.compare = function(node1, node2) {
|
14748
|
+
// Not the same name
|
14749
|
+
if (node1.nodeName != node2.nodeName) {
|
14750
|
+
return false;
|
14751
|
+
}
|
14752
|
+
|
14753
|
+
/**
|
14754
|
+
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
14755
|
+
*
|
14756
|
+
* @private
|
14757
|
+
* @param {Node} node Node to get attributes from.
|
14758
|
+
* @return {Object} Name/value object with attributes and attribute values.
|
14759
|
+
*/
|
14760
|
+
function getAttribs(node) {
|
14761
|
+
var attribs = {};
|
14762
|
+
|
14763
|
+
each(dom.getAttribs(node), function(attr) {
|
14764
|
+
var name = attr.nodeName.toLowerCase();
|
14765
|
+
|
14766
|
+
// Don't compare internal attributes or style
|
14767
|
+
if (name.indexOf('_') !== 0 && name !== 'style' && name !== 'data-mce-style') {
|
14768
|
+
attribs[name] = dom.getAttrib(node, name);
|
14769
|
+
}
|
14770
|
+
});
|
14771
|
+
|
14772
|
+
return attribs;
|
14773
|
+
}
|
14774
|
+
|
14775
|
+
/**
|
14776
|
+
* Compares two objects checks if it's key + value exists in the other one.
|
14777
|
+
*
|
14778
|
+
* @private
|
14779
|
+
* @param {Object} obj1 First object to compare.
|
14780
|
+
* @param {Object} obj2 Second object to compare.
|
14781
|
+
* @return {boolean} True/false if the objects matches or not.
|
14782
|
+
*/
|
14783
|
+
function compareObjects(obj1, obj2) {
|
14784
|
+
var value, name;
|
14785
|
+
|
14786
|
+
for (name in obj1) {
|
14787
|
+
// Obj1 has item obj2 doesn't have
|
14788
|
+
if (obj1.hasOwnProperty(name)) {
|
14789
|
+
value = obj2[name];
|
14790
|
+
|
14791
|
+
// Obj2 doesn't have obj1 item
|
14792
|
+
if (typeof value == "undefined") {
|
14793
|
+
return false;
|
14794
|
+
}
|
14795
|
+
|
14796
|
+
// Obj2 item has a different value
|
14797
|
+
if (obj1[name] != value) {
|
14798
|
+
return false;
|
14799
|
+
}
|
14800
|
+
|
14801
|
+
// Delete similar value
|
14802
|
+
delete obj2[name];
|
14803
|
+
}
|
14804
|
+
}
|
14805
|
+
|
14806
|
+
// Check if obj 2 has something obj 1 doesn't have
|
14807
|
+
for (name in obj2) {
|
14808
|
+
// Obj2 has item obj1 doesn't have
|
14809
|
+
if (obj2.hasOwnProperty(name)) {
|
14810
|
+
return false;
|
14811
|
+
}
|
14812
|
+
}
|
14813
|
+
|
14814
|
+
return true;
|
14815
|
+
}
|
14816
|
+
|
14817
|
+
// Attribs are not the same
|
14818
|
+
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
14819
|
+
return false;
|
14820
|
+
}
|
14821
|
+
|
14822
|
+
// Styles are not the same
|
14823
|
+
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
14824
|
+
return false;
|
14825
|
+
}
|
14826
|
+
|
14827
|
+
return !BookmarkManager.isBookmarkNode(node1) && !BookmarkManager.isBookmarkNode(node2);
|
14828
|
+
};
|
14829
|
+
}
|
14830
|
+
|
14831
|
+
return ElementUtils;
|
14832
|
+
});
|
14833
|
+
|
14449
14834
|
// Included from: js/tinymce/classes/fmt/Preview.js
|
14450
14835
|
|
14451
14836
|
/**
|
@@ -14629,9 +15014,11 @@ define("tinymce/fmt/Preview", [
|
|
14629
15014
|
define("tinymce/Formatter", [
|
14630
15015
|
"tinymce/dom/TreeWalker",
|
14631
15016
|
"tinymce/dom/RangeUtils",
|
15017
|
+
"tinymce/dom/BookmarkManager",
|
15018
|
+
"tinymce/dom/ElementUtils",
|
14632
15019
|
"tinymce/util/Tools",
|
14633
15020
|
"tinymce/fmt/Preview"
|
14634
|
-
], function(TreeWalker, RangeUtils, Tools, Preview) {
|
15021
|
+
], function(TreeWalker, RangeUtils, BookmarkManager, ElementUtils, Tools, Preview) {
|
14635
15022
|
/**
|
14636
15023
|
* Constructs a new formatter instance.
|
14637
15024
|
*
|
@@ -14655,7 +15042,8 @@ define("tinymce/Formatter", [
|
|
14655
15042
|
undef,
|
14656
15043
|
getContentEditable = dom.getContentEditable,
|
14657
15044
|
disableCaretContainer,
|
14658
|
-
markCaretContainersBogus
|
15045
|
+
markCaretContainersBogus,
|
15046
|
+
isBookmarkNode = BookmarkManager.isBookmarkNode;
|
14659
15047
|
|
14660
15048
|
var each = Tools.each,
|
14661
15049
|
grep = Tools.grep,
|
@@ -14680,7 +15068,6 @@ define("tinymce/Formatter", [
|
|
14680
15068
|
|
14681
15069
|
function defaultFormats() {
|
14682
15070
|
register({
|
14683
|
-
|
14684
15071
|
valigntop: [
|
14685
15072
|
{selector: 'td,th', styles: {'verticalAlign': 'top'}}
|
14686
15073
|
],
|
@@ -14971,7 +15358,7 @@ define("tinymce/Formatter", [
|
|
14971
15358
|
|
14972
15359
|
// get the index of the bookmarks
|
14973
15360
|
each(node.childNodes, function(n, index) {
|
14974
|
-
if (
|
15361
|
+
if (isBookmarkNode(n)) {
|
14975
15362
|
if (n.id == bookmark.id + "_start") {
|
14976
15363
|
startIndex = index;
|
14977
15364
|
} else if (n.id == bookmark.id + "_end") {
|
@@ -16547,17 +16934,6 @@ define("tinymce/Formatter", [
|
|
16547
16934
|
}
|
16548
16935
|
}
|
16549
16936
|
|
16550
|
-
/**
|
16551
|
-
* Checks if the specified node is a bookmark node or not.
|
16552
|
-
*
|
16553
|
-
* @private
|
16554
|
-
* @param {Node} node Node to check if it's a bookmark node or not.
|
16555
|
-
* @return {Boolean} true/false if the node is a bookmark node.
|
16556
|
-
*/
|
16557
|
-
function isBookmarkNode(node) {
|
16558
|
-
return node && node.nodeType == 1 && node.getAttribute('data-mce-type') == 'bookmark';
|
16559
|
-
}
|
16560
|
-
|
16561
16937
|
/**
|
16562
16938
|
* Merges the next/previous sibling element if they match.
|
16563
16939
|
*
|
@@ -16567,99 +16943,7 @@ define("tinymce/Formatter", [
|
|
16567
16943
|
* @return {Node} Next node if we didn't merge and prev node if we did.
|
16568
16944
|
*/
|
16569
16945
|
function mergeSiblings(prev, next) {
|
16570
|
-
var sibling, tmpSibling;
|
16571
|
-
|
16572
|
-
/**
|
16573
|
-
* Compares two nodes and checks if it's attributes and styles matches.
|
16574
|
-
* This doesn't compare classes as items since their order is significant.
|
16575
|
-
*
|
16576
|
-
* @private
|
16577
|
-
* @param {Node} node1 First node to compare with.
|
16578
|
-
* @param {Node} node2 Second node to compare with.
|
16579
|
-
* @return {boolean} True/false if the nodes are the same or not.
|
16580
|
-
*/
|
16581
|
-
function compareElements(node1, node2) {
|
16582
|
-
// Not the same name
|
16583
|
-
if (node1.nodeName != node2.nodeName) {
|
16584
|
-
return FALSE;
|
16585
|
-
}
|
16586
|
-
|
16587
|
-
/**
|
16588
|
-
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
16589
|
-
*
|
16590
|
-
* @private
|
16591
|
-
* @param {Node} node Node to get attributes from.
|
16592
|
-
* @return {Object} Name/value object with attributes and attribute values.
|
16593
|
-
*/
|
16594
|
-
function getAttribs(node) {
|
16595
|
-
var attribs = {};
|
16596
|
-
|
16597
|
-
each(dom.getAttribs(node), function(attr) {
|
16598
|
-
var name = attr.nodeName.toLowerCase();
|
16599
|
-
|
16600
|
-
// Don't compare internal attributes or style
|
16601
|
-
if (name.indexOf('_') !== 0 && name !== 'style' && name !== 'data-mce-style') {
|
16602
|
-
attribs[name] = dom.getAttrib(node, name);
|
16603
|
-
}
|
16604
|
-
});
|
16605
|
-
|
16606
|
-
return attribs;
|
16607
|
-
}
|
16608
|
-
|
16609
|
-
/**
|
16610
|
-
* Compares two objects checks if it's key + value exists in the other one.
|
16611
|
-
*
|
16612
|
-
* @private
|
16613
|
-
* @param {Object} obj1 First object to compare.
|
16614
|
-
* @param {Object} obj2 Second object to compare.
|
16615
|
-
* @return {boolean} True/false if the objects matches or not.
|
16616
|
-
*/
|
16617
|
-
function compareObjects(obj1, obj2) {
|
16618
|
-
var value, name;
|
16619
|
-
|
16620
|
-
for (name in obj1) {
|
16621
|
-
// Obj1 has item obj2 doesn't have
|
16622
|
-
if (obj1.hasOwnProperty(name)) {
|
16623
|
-
value = obj2[name];
|
16624
|
-
|
16625
|
-
// Obj2 doesn't have obj1 item
|
16626
|
-
if (value === undef) {
|
16627
|
-
return FALSE;
|
16628
|
-
}
|
16629
|
-
|
16630
|
-
// Obj2 item has a different value
|
16631
|
-
if (obj1[name] != value) {
|
16632
|
-
return FALSE;
|
16633
|
-
}
|
16634
|
-
|
16635
|
-
// Delete similar value
|
16636
|
-
delete obj2[name];
|
16637
|
-
}
|
16638
|
-
}
|
16639
|
-
|
16640
|
-
// Check if obj 2 has something obj 1 doesn't have
|
16641
|
-
for (name in obj2) {
|
16642
|
-
// Obj2 has item obj1 doesn't have
|
16643
|
-
if (obj2.hasOwnProperty(name)) {
|
16644
|
-
return FALSE;
|
16645
|
-
}
|
16646
|
-
}
|
16647
|
-
|
16648
|
-
return TRUE;
|
16649
|
-
}
|
16650
|
-
|
16651
|
-
// Attribs are not the same
|
16652
|
-
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
16653
|
-
return FALSE;
|
16654
|
-
}
|
16655
|
-
|
16656
|
-
// Styles are not the same
|
16657
|
-
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
16658
|
-
return FALSE;
|
16659
|
-
}
|
16660
|
-
|
16661
|
-
return !isBookmarkNode(node1) && !isBookmarkNode(node2);
|
16662
|
-
}
|
16946
|
+
var sibling, tmpSibling, elementUtils = new ElementUtils(dom);
|
16663
16947
|
|
16664
16948
|
function findElementSibling(node, sibling_name) {
|
16665
16949
|
for (sibling = node; sibling; sibling = sibling[sibling_name]) {
|
@@ -16682,7 +16966,7 @@ define("tinymce/Formatter", [
|
|
16682
16966
|
next = findElementSibling(next, 'nextSibling');
|
16683
16967
|
|
16684
16968
|
// Compare next and previous nodes
|
16685
|
-
if (
|
16969
|
+
if (elementUtils.compare(prev, next)) {
|
16686
16970
|
// Append nodes between
|
16687
16971
|
for (sibling = prev.nextSibling; sibling && sibling != next;) {
|
16688
16972
|
tmpSibling = sibling;
|
@@ -16885,7 +17169,7 @@ define("tinymce/Formatter", [
|
|
16885
17169
|
node = container;
|
16886
17170
|
|
16887
17171
|
if (container.nodeType == 3) {
|
16888
|
-
if (offset != container.nodeValue.length
|
17172
|
+
if (offset != container.nodeValue.length) {
|
16889
17173
|
hasContentAfter = true;
|
16890
17174
|
}
|
16891
17175
|
|
@@ -17467,6 +17751,10 @@ define("tinymce/EnterKey", [
|
|
17467
17751
|
function trimInlineElementsOnLeftSideOfBlock(block) {
|
17468
17752
|
var node = block, firstChilds = [], i;
|
17469
17753
|
|
17754
|
+
if (!node) {
|
17755
|
+
return;
|
17756
|
+
}
|
17757
|
+
|
17470
17758
|
// Find inner most first child ex: <p><i><b>*</b></i></p>
|
17471
17759
|
while ((node = node.firstChild)) {
|
17472
17760
|
if (dom.isBlock(node)) {
|
@@ -17507,6 +17795,10 @@ define("tinymce/EnterKey", [
|
|
17507
17795
|
}
|
17508
17796
|
}
|
17509
17797
|
|
17798
|
+
if (!root) {
|
17799
|
+
return;
|
17800
|
+
}
|
17801
|
+
|
17510
17802
|
// Old IE versions doesn't properly render blocks with br elements in them
|
17511
17803
|
// For example <p><br></p> wont be rendered correctly in a contentEditable area
|
17512
17804
|
// until you remove the br producing <p></p>
|
@@ -17516,16 +17808,23 @@ define("tinymce/EnterKey", [
|
|
17516
17808
|
}
|
17517
17809
|
}
|
17518
17810
|
|
17519
|
-
if (root.nodeName
|
17811
|
+
if (/^(LI|DT|DD)$/.test(root.nodeName)) {
|
17520
17812
|
var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
|
17521
17813
|
|
17522
|
-
if (firstChild && /^(UL|OL)$/.test(firstChild.nodeName)) {
|
17814
|
+
if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
|
17523
17815
|
root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
|
17524
17816
|
}
|
17525
17817
|
}
|
17526
17818
|
|
17527
17819
|
rng = dom.createRng();
|
17528
17820
|
|
17821
|
+
// Normalize whitespace to remove empty text nodes. Fix for: #6904
|
17822
|
+
// Gecko will be able to place the caret in empty text nodes but it won't render propery
|
17823
|
+
// Older IE versions will sometimes crash so for now ignore all IE versions
|
17824
|
+
if (!Env.ie) {
|
17825
|
+
root.normalize();
|
17826
|
+
}
|
17827
|
+
|
17529
17828
|
if (root.hasChildNodes()) {
|
17530
17829
|
walker = new TreeWalker(root, root);
|
17531
17830
|
|
@@ -17589,7 +17888,7 @@ define("tinymce/EnterKey", [
|
|
17589
17888
|
// Creates a new block element by cloning the current one or creating a new one if the name is specified
|
17590
17889
|
// This function will also copy any text formatting from the parent block and add it to the new one
|
17591
17890
|
function createNewBlock(name) {
|
17592
|
-
var node = container, block, clonedNode, caretNode;
|
17891
|
+
var node = container, block, clonedNode, caretNode, textInlineElements = schema.getTextInlineElements();
|
17593
17892
|
|
17594
17893
|
if (name || parentBlockName == "TABLE") {
|
17595
17894
|
block = dom.create(name || newBlockName);
|
@@ -17603,7 +17902,7 @@ define("tinymce/EnterKey", [
|
|
17603
17902
|
// Clone any parent styles
|
17604
17903
|
if (settings.keep_styles !== false) {
|
17605
17904
|
do {
|
17606
|
-
if (
|
17905
|
+
if (textInlineElements[node.nodeName]) {
|
17607
17906
|
// Never clone a caret containers
|
17608
17907
|
if (node.id == '_mce_caret') {
|
17609
17908
|
continue;
|
@@ -17764,7 +18063,7 @@ define("tinymce/EnterKey", [
|
|
17764
18063
|
function getContainerBlock() {
|
17765
18064
|
var containerBlockParent = containerBlock.parentNode;
|
17766
18065
|
|
17767
|
-
if (containerBlockParent.nodeName
|
18066
|
+
if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
|
17768
18067
|
return containerBlockParent;
|
17769
18068
|
}
|
17770
18069
|
|
@@ -17994,8 +18293,8 @@ define("tinymce/EnterKey", [
|
|
17994
18293
|
parentBlockName = containerBlockName;
|
17995
18294
|
}
|
17996
18295
|
|
17997
|
-
// Handle enter in
|
17998
|
-
if (
|
18296
|
+
// Handle enter in list item
|
18297
|
+
if (/^(LI|DT|DD)$/.test(parentBlockName)) {
|
17999
18298
|
if (!newBlockName && shiftKey) {
|
18000
18299
|
insertBr();
|
18001
18300
|
return;
|
@@ -18240,8 +18539,9 @@ define("tinymce/ForceBlocks", [], function() {
|
|
18240
18539
|
define("tinymce/EditorCommands", [
|
18241
18540
|
"tinymce/html/Serializer",
|
18242
18541
|
"tinymce/Env",
|
18243
|
-
"tinymce/util/Tools"
|
18244
|
-
|
18542
|
+
"tinymce/util/Tools",
|
18543
|
+
"tinymce/dom/ElementUtils"
|
18544
|
+
], function(Serializer, Env, Tools, ElementUtils) {
|
18245
18545
|
// Added for compression purposes
|
18246
18546
|
var each = Tools.each, extend = Tools.extend;
|
18247
18547
|
var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode;
|
@@ -18536,7 +18836,8 @@ define("tinymce/EditorCommands", [
|
|
18536
18836
|
|
18537
18837
|
mceInsertContent: function(command, ui, value) {
|
18538
18838
|
var parser, serializer, parentNode, rootNode, fragment, args;
|
18539
|
-
var marker, rng, node, node2, bookmarkHtml;
|
18839
|
+
var marker, rng, node, node2, bookmarkHtml, merge;
|
18840
|
+
var textInlineElements = editor.schema.getTextInlineElements();
|
18540
18841
|
|
18541
18842
|
function trimOrPaddLeftRight(html) {
|
18542
18843
|
var rng, container, offset;
|
@@ -18566,6 +18867,37 @@ define("tinymce/EditorCommands", [
|
|
18566
18867
|
return html;
|
18567
18868
|
}
|
18568
18869
|
|
18870
|
+
function markInlineFormatElements(fragment) {
|
18871
|
+
if (merge) {
|
18872
|
+
for (node = fragment.firstChild; node; node = node.walk(true)) {
|
18873
|
+
if (textInlineElements[node.name]) {
|
18874
|
+
node.attr('data-mce-new', "true");
|
18875
|
+
}
|
18876
|
+
}
|
18877
|
+
}
|
18878
|
+
}
|
18879
|
+
|
18880
|
+
function reduceInlineTextElements() {
|
18881
|
+
if (merge) {
|
18882
|
+
var root = editor.getBody(), elementUtils = new ElementUtils(dom);
|
18883
|
+
|
18884
|
+
each(dom.select('*[data-mce-new]'), function(node) {
|
18885
|
+
node.removeAttribute('data-mce-new');
|
18886
|
+
|
18887
|
+
for (var testNode = node.parentNode; testNode && testNode != root; testNode = testNode.parentNode) {
|
18888
|
+
if (elementUtils.compare(testNode, node)) {
|
18889
|
+
dom.remove(node, true);
|
18890
|
+
}
|
18891
|
+
}
|
18892
|
+
});
|
18893
|
+
}
|
18894
|
+
}
|
18895
|
+
|
18896
|
+
if (typeof(value) != 'string') {
|
18897
|
+
merge = value.merge;
|
18898
|
+
value = value.content;
|
18899
|
+
}
|
18900
|
+
|
18569
18901
|
// Check for whitespace before/after value
|
18570
18902
|
if (/^ | $/.test(value)) {
|
18571
18903
|
value = trimOrPaddLeftRight(value);
|
@@ -18613,6 +18945,8 @@ define("tinymce/EditorCommands", [
|
|
18613
18945
|
var parserArgs = {context: parentNode.nodeName.toLowerCase()};
|
18614
18946
|
fragment = parser.parse(value, parserArgs);
|
18615
18947
|
|
18948
|
+
markInlineFormatElements(fragment);
|
18949
|
+
|
18616
18950
|
// Move the caret to a more suitable location
|
18617
18951
|
node = fragment.lastChild;
|
18618
18952
|
if (node.attr('id') == 'mce_marker') {
|
@@ -18679,6 +19013,8 @@ define("tinymce/EditorCommands", [
|
|
18679
19013
|
}
|
18680
19014
|
}
|
18681
19015
|
|
19016
|
+
reduceInlineTextElements();
|
19017
|
+
|
18682
19018
|
marker = dom.get('mce_marker');
|
18683
19019
|
selection.scrollIntoView(marker);
|
18684
19020
|
|
@@ -18981,11 +19317,9 @@ define("tinymce/util/URI", [
|
|
18981
19317
|
function URI(url, settings) {
|
18982
19318
|
var self = this, baseUri, base_url;
|
18983
19319
|
|
18984
|
-
// Trim whitespace
|
18985
19320
|
url = trim(url);
|
18986
|
-
|
18987
|
-
// Default settings
|
18988
19321
|
settings = self.settings = settings || {};
|
19322
|
+
baseUri = settings.base_uri;
|
18989
19323
|
|
18990
19324
|
// Strange app protocol that isn't http/https or local anchor
|
18991
19325
|
// For example: mailto,skype,tel etc.
|
@@ -18998,7 +19332,7 @@ define("tinymce/util/URI", [
|
|
18998
19332
|
|
18999
19333
|
// Absolute path with no host, fake host and protocol
|
19000
19334
|
if (url.indexOf('/') === 0 && !isProtocolRelative) {
|
19001
|
-
url = (
|
19335
|
+
url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
|
19002
19336
|
}
|
19003
19337
|
|
19004
19338
|
// Relative path http:// or protocol relative //path
|
@@ -19007,7 +19341,8 @@ define("tinymce/util/URI", [
|
|
19007
19341
|
if (settings.base_uri.protocol === "") {
|
19008
19342
|
url = '//mce_host' + self.toAbsPath(base_url, url);
|
19009
19343
|
} else {
|
19010
|
-
url = ((
|
19344
|
+
url = /([^#?]*)([#?]?.*)/.exec(url);
|
19345
|
+
url = ((baseUri && baseUri.protocol) || 'http') + '://mce_host' + self.toAbsPath(base_url, url[1]) + url[2];
|
19011
19346
|
}
|
19012
19347
|
}
|
19013
19348
|
|
@@ -19029,7 +19364,6 @@ define("tinymce/util/URI", [
|
|
19029
19364
|
self[v] = part;
|
19030
19365
|
});
|
19031
19366
|
|
19032
|
-
baseUri = settings.base_uri;
|
19033
19367
|
if (baseUri) {
|
19034
19368
|
if (!self.protocol) {
|
19035
19369
|
self.protocol = baseUri.protocol;
|
@@ -19539,7 +19873,8 @@ define("tinymce/util/EventDispatcher", [
|
|
19539
19873
|
var nativeEvents = Tools.makeMap(
|
19540
19874
|
"focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange " +
|
19541
19875
|
"mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover " +
|
19542
|
-
"draggesture dragdrop drop drag submit"
|
19876
|
+
"draggesture dragdrop drop drag submit " +
|
19877
|
+
"compositionstart compositionend compositionupdate",
|
19543
19878
|
' '
|
19544
19879
|
);
|
19545
19880
|
|
@@ -20596,9 +20931,11 @@ define("tinymce/ui/DomUtils", [
|
|
20596
20931
|
], function(Tools, DOMUtils) {
|
20597
20932
|
"use strict";
|
20598
20933
|
|
20934
|
+
var count = 0;
|
20935
|
+
|
20599
20936
|
return {
|
20600
20937
|
id: function() {
|
20601
|
-
return
|
20938
|
+
return 'mceu_' + (count++);
|
20602
20939
|
},
|
20603
20940
|
|
20604
20941
|
createFragment: function(html) {
|
@@ -23832,9 +24169,117 @@ define("tinymce/ui/FloatPanel", [
|
|
23832
24169
|
], function(Panel, Movable, Resizable, DomUtils) {
|
23833
24170
|
"use strict";
|
23834
24171
|
|
23835
|
-
var documentClickHandler, documentScrollHandler, visiblePanels = [];
|
24172
|
+
var documentClickHandler, documentScrollHandler, windowResizeHandler, visiblePanels = [];
|
23836
24173
|
var zOrder = [], hasModal;
|
23837
24174
|
|
24175
|
+
function bindDocumentClickHandler() {
|
24176
|
+
function isChildOf(ctrl, parent) {
|
24177
|
+
while (ctrl) {
|
24178
|
+
if (ctrl == parent) {
|
24179
|
+
return true;
|
24180
|
+
}
|
24181
|
+
|
24182
|
+
ctrl = ctrl.parent();
|
24183
|
+
}
|
24184
|
+
}
|
24185
|
+
|
24186
|
+
if (!documentClickHandler) {
|
24187
|
+
documentClickHandler = function(e) {
|
24188
|
+
// Gecko fires click event and in the wrong order on Mac so lets normalize
|
24189
|
+
if (e.button == 2) {
|
24190
|
+
return;
|
24191
|
+
}
|
24192
|
+
|
24193
|
+
// Hide any float panel when a click is out side that float panel and the
|
24194
|
+
// float panels direct parent for example a click on a menu button
|
24195
|
+
var i = visiblePanels.length;
|
24196
|
+
while (i--) {
|
24197
|
+
var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
|
24198
|
+
|
24199
|
+
if (panel.settings.autohide) {
|
24200
|
+
if (clickCtrl) {
|
24201
|
+
if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
|
24202
|
+
continue;
|
24203
|
+
}
|
24204
|
+
}
|
24205
|
+
|
24206
|
+
e = panel.fire('autohide', {target: e.target});
|
24207
|
+
if (!e.isDefaultPrevented()) {
|
24208
|
+
panel.hide();
|
24209
|
+
}
|
24210
|
+
}
|
24211
|
+
}
|
24212
|
+
};
|
24213
|
+
|
24214
|
+
DomUtils.on(document, 'click', documentClickHandler);
|
24215
|
+
}
|
24216
|
+
}
|
24217
|
+
|
24218
|
+
function bindDocumentScrollHandler() {
|
24219
|
+
if (!documentScrollHandler) {
|
24220
|
+
documentScrollHandler = function() {
|
24221
|
+
var i;
|
24222
|
+
|
24223
|
+
i = visiblePanels.length;
|
24224
|
+
while (i--) {
|
24225
|
+
repositionPanel(visiblePanels[i]);
|
24226
|
+
}
|
24227
|
+
};
|
24228
|
+
|
24229
|
+
DomUtils.on(window, 'scroll', documentScrollHandler);
|
24230
|
+
}
|
24231
|
+
}
|
24232
|
+
|
24233
|
+
function bindWindowResizeHandler() {
|
24234
|
+
if (!windowResizeHandler) {
|
24235
|
+
windowResizeHandler = function() {
|
24236
|
+
FloatPanel.hideAll();
|
24237
|
+
};
|
24238
|
+
|
24239
|
+
DomUtils.on(window, 'resize', windowResizeHandler);
|
24240
|
+
}
|
24241
|
+
}
|
24242
|
+
|
24243
|
+
/**
|
24244
|
+
* Repositions the panel to the top of page if the panel is outside of the visual viewport. It will
|
24245
|
+
* also reposition all child panels of the current panel.
|
24246
|
+
*/
|
24247
|
+
function repositionPanel(panel) {
|
24248
|
+
var scrollY = DomUtils.getViewPort().y;
|
24249
|
+
|
24250
|
+
function toggleFixedChildPanels(fixed, deltaY) {
|
24251
|
+
var parent;
|
24252
|
+
|
24253
|
+
for (var i = 0; i < visiblePanels.length; i++) {
|
24254
|
+
if (visiblePanels[i] != panel) {
|
24255
|
+
parent = visiblePanels[i].parent();
|
24256
|
+
|
24257
|
+
while (parent && (parent = parent.parent())) {
|
24258
|
+
if (parent == panel) {
|
24259
|
+
visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
|
24260
|
+
}
|
24261
|
+
}
|
24262
|
+
}
|
24263
|
+
}
|
24264
|
+
}
|
24265
|
+
|
24266
|
+
if (panel.settings.autofix) {
|
24267
|
+
if (!panel._fixed) {
|
24268
|
+
panel._autoFixY = panel.layoutRect().y;
|
24269
|
+
|
24270
|
+
if (panel._autoFixY < scrollY) {
|
24271
|
+
panel.fixed(true).layoutRect({y: 0}).repaint();
|
24272
|
+
toggleFixedChildPanels(true, scrollY - panel._autoFixY);
|
24273
|
+
}
|
24274
|
+
} else {
|
24275
|
+
if (panel._autoFixY > scrollY) {
|
24276
|
+
panel.fixed(false).layoutRect({y: panel._autoFixY}).repaint();
|
24277
|
+
toggleFixedChildPanels(false, panel._autoFixY - scrollY);
|
24278
|
+
}
|
24279
|
+
}
|
24280
|
+
}
|
24281
|
+
}
|
24282
|
+
|
23838
24283
|
var FloatPanel = Panel.extend({
|
23839
24284
|
Mixins: [Movable, Resizable],
|
23840
24285
|
|
@@ -23876,56 +24321,6 @@ define("tinymce/ui/FloatPanel", [
|
|
23876
24321
|
FloatPanel.currentZIndex = zIndex;
|
23877
24322
|
}
|
23878
24323
|
|
23879
|
-
function isChildOf(ctrl, parent) {
|
23880
|
-
while (ctrl) {
|
23881
|
-
if (ctrl == parent) {
|
23882
|
-
return true;
|
23883
|
-
}
|
23884
|
-
|
23885
|
-
ctrl = ctrl.parent();
|
23886
|
-
}
|
23887
|
-
}
|
23888
|
-
|
23889
|
-
/**
|
23890
|
-
* Repositions the panel to the top of page if the panel is outside of the visual viewport. It will
|
23891
|
-
* also reposition all child panels of the current panel.
|
23892
|
-
*/
|
23893
|
-
function repositionPanel(panel) {
|
23894
|
-
var scrollY = DomUtils.getViewPort().y;
|
23895
|
-
|
23896
|
-
function toggleFixedChildPanels(fixed, deltaY) {
|
23897
|
-
var parent;
|
23898
|
-
|
23899
|
-
for (var i = 0; i < visiblePanels.length; i++) {
|
23900
|
-
if (visiblePanels[i] != panel) {
|
23901
|
-
parent = visiblePanels[i].parent();
|
23902
|
-
|
23903
|
-
while (parent && (parent = parent.parent())) {
|
23904
|
-
if (parent == panel) {
|
23905
|
-
visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
|
23906
|
-
}
|
23907
|
-
}
|
23908
|
-
}
|
23909
|
-
}
|
23910
|
-
}
|
23911
|
-
|
23912
|
-
if (panel.settings.autofix) {
|
23913
|
-
if (!panel._fixed) {
|
23914
|
-
panel._autoFixY = panel.layoutRect().y;
|
23915
|
-
|
23916
|
-
if (panel._autoFixY < scrollY) {
|
23917
|
-
panel.fixed(true).layoutRect({y: 0}).repaint();
|
23918
|
-
toggleFixedChildPanels(true, scrollY - panel._autoFixY);
|
23919
|
-
}
|
23920
|
-
} else {
|
23921
|
-
if (panel._autoFixY > scrollY) {
|
23922
|
-
panel.fixed(false).layoutRect({y: panel._autoFixY}).repaint();
|
23923
|
-
toggleFixedChildPanels(false, panel._autoFixY - scrollY);
|
23924
|
-
}
|
23925
|
-
}
|
23926
|
-
}
|
23927
|
-
}
|
23928
|
-
|
23929
24324
|
self._super(settings);
|
23930
24325
|
self._eventsRoot = self;
|
23931
24326
|
|
@@ -23933,48 +24328,13 @@ define("tinymce/ui/FloatPanel", [
|
|
23933
24328
|
|
23934
24329
|
// Hide floatpanes on click out side the root button
|
23935
24330
|
if (settings.autohide) {
|
23936
|
-
|
23937
|
-
|
23938
|
-
// Hide any float panel when a click is out side that float panel and the
|
23939
|
-
// float panels direct parent for example a click on a menu button
|
23940
|
-
var i = visiblePanels.length;
|
23941
|
-
while (i--) {
|
23942
|
-
var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
|
23943
|
-
|
23944
|
-
if (panel.settings.autohide) {
|
23945
|
-
if (clickCtrl) {
|
23946
|
-
if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
|
23947
|
-
continue;
|
23948
|
-
}
|
23949
|
-
}
|
23950
|
-
|
23951
|
-
e = panel.fire('autohide', {target: e.target});
|
23952
|
-
if (!e.isDefaultPrevented()) {
|
23953
|
-
panel.hide();
|
23954
|
-
}
|
23955
|
-
}
|
23956
|
-
}
|
23957
|
-
};
|
23958
|
-
|
23959
|
-
DomUtils.on(document, 'click', documentClickHandler);
|
23960
|
-
}
|
23961
|
-
|
24331
|
+
bindDocumentClickHandler();
|
24332
|
+
bindWindowResizeHandler();
|
23962
24333
|
visiblePanels.push(self);
|
23963
24334
|
}
|
23964
24335
|
|
23965
24336
|
if (settings.autofix) {
|
23966
|
-
|
23967
|
-
documentScrollHandler = function() {
|
23968
|
-
var i;
|
23969
|
-
|
23970
|
-
i = visiblePanels.length;
|
23971
|
-
while (i--) {
|
23972
|
-
repositionPanel(visiblePanels[i]);
|
23973
|
-
}
|
23974
|
-
};
|
23975
|
-
|
23976
|
-
DomUtils.on(window, 'scroll', documentScrollHandler);
|
23977
|
-
}
|
24337
|
+
bindDocumentScrollHandler();
|
23978
24338
|
|
23979
24339
|
self.on('move', function() {
|
23980
24340
|
repositionPanel(this);
|
@@ -24090,7 +24450,8 @@ define("tinymce/ui/FloatPanel", [
|
|
24090
24450
|
},
|
24091
24451
|
|
24092
24452
|
/**
|
24093
|
-
*
|
24453
|
+
* Hide all visible float panels with he autohide setting enabled. This is for
|
24454
|
+
* manually hiding floating menus or panels.
|
24094
24455
|
*
|
24095
24456
|
* @method hideAll
|
24096
24457
|
*/
|
@@ -24133,7 +24494,8 @@ define("tinymce/ui/FloatPanel", [
|
|
24133
24494
|
});
|
24134
24495
|
|
24135
24496
|
/**
|
24136
|
-
*
|
24497
|
+
* Hide all visible float panels with he autohide setting enabled. This is for
|
24498
|
+
* manually hiding floating menus or panels.
|
24137
24499
|
*
|
24138
24500
|
* @static
|
24139
24501
|
* @method hideAll
|
@@ -26539,8 +26901,13 @@ define("tinymce/Shortcuts", [
|
|
26539
26901
|
break;
|
26540
26902
|
|
26541
26903
|
default:
|
26542
|
-
|
26543
|
-
|
26904
|
+
// Allow numeric keycodes like ctrl+219 for ctrl+[
|
26905
|
+
if (/^[0-9]{2,}$/.test(value)) {
|
26906
|
+
shortcut.keyCode = parseInt(value, 10);
|
26907
|
+
} else {
|
26908
|
+
shortcut.charCode = value.charCodeAt(0);
|
26909
|
+
shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
|
26910
|
+
}
|
26544
26911
|
}
|
26545
26912
|
});
|
26546
26913
|
|
@@ -27347,7 +27714,14 @@ define("tinymce/Editor", [
|
|
27347
27714
|
// Add internal attribute if we need to we don't on a refresh of the document
|
27348
27715
|
if (!node.attributes.map[internalName]) {
|
27349
27716
|
if (name === "style") {
|
27350
|
-
|
27717
|
+
value = dom.serializeStyle(dom.parseStyle(value), node.name);
|
27718
|
+
|
27719
|
+
if (!value.length) {
|
27720
|
+
value = null;
|
27721
|
+
}
|
27722
|
+
|
27723
|
+
node.attr(internalName, value);
|
27724
|
+
node.attr(name, value);
|
27351
27725
|
} else if (name === "tabindex") {
|
27352
27726
|
node.attr(internalName, value);
|
27353
27727
|
node.attr(name, null);
|
@@ -27364,7 +27738,7 @@ define("tinymce/Editor", [
|
|
27364
27738
|
|
27365
27739
|
while (i--) {
|
27366
27740
|
node = nodes[i];
|
27367
|
-
node.attr('type', 'mce-' + (node.attr('type') || '
|
27741
|
+
node.attr('type', 'mce-' + (node.attr('type') || 'no/type'));
|
27368
27742
|
}
|
27369
27743
|
});
|
27370
27744
|
|
@@ -27978,8 +28352,18 @@ define("tinymce/Editor", [
|
|
27978
28352
|
}
|
27979
28353
|
|
27980
28354
|
// Browser commands
|
27981
|
-
|
27982
|
-
|
28355
|
+
try {
|
28356
|
+
state = self.getDoc().execCommand(cmd, ui, value);
|
28357
|
+
} catch (ex) {
|
28358
|
+
// Ignore old IE errors
|
28359
|
+
}
|
28360
|
+
|
28361
|
+
if (state) {
|
28362
|
+
self.fire('ExecCommand', {command: cmd, ui: ui, value: value});
|
28363
|
+
return true;
|
28364
|
+
}
|
28365
|
+
|
28366
|
+
return false;
|
27983
28367
|
},
|
27984
28368
|
|
27985
28369
|
/**
|
@@ -28001,8 +28385,8 @@ define("tinymce/Editor", [
|
|
28001
28385
|
if ((queryItem = self.queryStateCommands[cmd])) {
|
28002
28386
|
returnVal = queryItem.func.call(queryItem.scope);
|
28003
28387
|
|
28004
|
-
// Fall though on
|
28005
|
-
if (returnVal
|
28388
|
+
// Fall though on non boolean returns
|
28389
|
+
if (returnVal === true || returnVal === false) {
|
28006
28390
|
return returnVal;
|
28007
28391
|
}
|
28008
28392
|
}
|
@@ -28092,8 +28476,6 @@ define("tinymce/Editor", [
|
|
28092
28476
|
var self = this, doc = self.getDoc();
|
28093
28477
|
|
28094
28478
|
if (!self.hidden) {
|
28095
|
-
self.hidden = true;
|
28096
|
-
|
28097
28479
|
// Fixed bug where IE has a blinking cursor left from the editor
|
28098
28480
|
if (ie && doc && !self.inline) {
|
28099
28481
|
doc.execCommand('SelectAll');
|
@@ -28114,6 +28496,7 @@ define("tinymce/Editor", [
|
|
28114
28496
|
DOM.setStyle(self.id, 'display', self.orgDisplay);
|
28115
28497
|
}
|
28116
28498
|
|
28499
|
+
self.hidden = true;
|
28117
28500
|
self.fire('hide');
|
28118
28501
|
}
|
28119
28502
|
},
|
@@ -28377,8 +28760,13 @@ define("tinymce/Editor", [
|
|
28377
28760
|
*
|
28378
28761
|
* @method insertContent
|
28379
28762
|
* @param {String} content Content to insert.
|
28763
|
+
* @param {Object} args Optional args to pass to insert call.
|
28380
28764
|
*/
|
28381
|
-
insertContent: function(content) {
|
28765
|
+
insertContent: function(content, args) {
|
28766
|
+
if (args) {
|
28767
|
+
content = extend({content: content}, args);
|
28768
|
+
}
|
28769
|
+
|
28382
28770
|
this.execCommand('mceInsertContent', false, content);
|
28383
28771
|
},
|
28384
28772
|
|
@@ -29133,7 +29521,7 @@ define("tinymce/EditorManager", [
|
|
29133
29521
|
* @property minorVersion
|
29134
29522
|
* @type String
|
29135
29523
|
*/
|
29136
|
-
minorVersion : '0.
|
29524
|
+
minorVersion : '0.28',
|
29137
29525
|
|
29138
29526
|
/**
|
29139
29527
|
* Release date of TinyMCE build.
|
@@ -29141,7 +29529,7 @@ define("tinymce/EditorManager", [
|
|
29141
29529
|
* @property releaseDate
|
29142
29530
|
* @type String
|
29143
29531
|
*/
|
29144
|
-
releaseDate: '2014-05-
|
29532
|
+
releaseDate: '2014-05-27',
|
29145
29533
|
|
29146
29534
|
/**
|
29147
29535
|
* Collection of editor instances.
|
@@ -29177,9 +29565,16 @@ define("tinymce/EditorManager", [
|
|
29177
29565
|
var self = this, baseURL, documentBaseURL, suffix = "", preInit, src;
|
29178
29566
|
|
29179
29567
|
// Get base URL for the current document
|
29180
|
-
documentBaseURL = document.location.href
|
29181
|
-
|
29182
|
-
|
29568
|
+
documentBaseURL = document.location.href;
|
29569
|
+
|
29570
|
+
// Check if the URL is a document based format like: http://site/dir/file
|
29571
|
+
// leave other formats like applewebdata://... intact
|
29572
|
+
if (/^[^:]+:\/\/[^\/]+\//.test(documentBaseURL)) {
|
29573
|
+
documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
|
29574
|
+
|
29575
|
+
if (!/[\/\\]$/.test(documentBaseURL)) {
|
29576
|
+
documentBaseURL += '/';
|
29577
|
+
}
|
29183
29578
|
}
|
29184
29579
|
|
29185
29580
|
// If tinymce is defined and has a base use that or use the old tinyMCEPreInit
|
@@ -32113,13 +32508,19 @@ define("tinymce/ui/Form", [
|
|
32113
32508
|
* @private
|
32114
32509
|
*/
|
32115
32510
|
recalcLabels: function() {
|
32116
|
-
var self = this, maxLabelWidth = 0, labels = [], i, labelGap;
|
32511
|
+
var self = this, maxLabelWidth = 0, labels = [], i, labelGap, items;
|
32117
32512
|
|
32118
32513
|
if (self.settings.labelGapCalc === false) {
|
32119
32514
|
return;
|
32120
32515
|
}
|
32121
32516
|
|
32122
|
-
self.
|
32517
|
+
if (self.settings.labelGapCalc == "children") {
|
32518
|
+
items = self.find('formitem');
|
32519
|
+
} else {
|
32520
|
+
items = self.items();
|
32521
|
+
}
|
32522
|
+
|
32523
|
+
items.filter('formitem').each(function(item) {
|
32123
32524
|
var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth;
|
32124
32525
|
|
32125
32526
|
maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth;
|
@@ -32260,8 +32661,9 @@ define("tinymce/ui/FieldSet", [
|
|
32260
32661
|
* @extends tinymce.ui.ComboBox
|
32261
32662
|
*/
|
32262
32663
|
define("tinymce/ui/FilePicker", [
|
32263
|
-
"tinymce/ui/ComboBox"
|
32264
|
-
|
32664
|
+
"tinymce/ui/ComboBox",
|
32665
|
+
"tinymce/util/Tools"
|
32666
|
+
], function(ComboBox, Tools) {
|
32265
32667
|
"use strict";
|
32266
32668
|
|
32267
32669
|
return ComboBox.extend({
|
@@ -32272,12 +32674,17 @@ define("tinymce/ui/FilePicker", [
|
|
32272
32674
|
* @param {Object} settings Name/value object with settings.
|
32273
32675
|
*/
|
32274
32676
|
init: function(settings) {
|
32275
|
-
var self = this, editor = tinymce.activeEditor, fileBrowserCallback;
|
32677
|
+
var self = this, editor = tinymce.activeEditor, fileBrowserCallback, fileBrowserCallbackTypes;
|
32276
32678
|
|
32277
32679
|
settings.spellcheck = false;
|
32278
32680
|
|
32681
|
+
fileBrowserCallbackTypes = editor.settings.file_browser_callback_types;
|
32682
|
+
if (fileBrowserCallbackTypes) {
|
32683
|
+
fileBrowserCallbackTypes = Tools.makeMap(fileBrowserCallbackTypes, /[, ]/);
|
32684
|
+
}
|
32685
|
+
|
32279
32686
|
fileBrowserCallback = editor.settings.file_browser_callback;
|
32280
|
-
if (fileBrowserCallback) {
|
32687
|
+
if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[settings.filetype])) {
|
32281
32688
|
settings.icon = 'browse';
|
32282
32689
|
|
32283
32690
|
settings.onaction = function() {
|
@@ -32793,6 +33200,7 @@ define("tinymce/ui/FormatControls", [
|
|
32793
33200
|
}
|
32794
33201
|
|
32795
33202
|
menuItem.format = formatName;
|
33203
|
+
menuItem.cmd = format.cmd;
|
32796
33204
|
}
|
32797
33205
|
|
32798
33206
|
menu.push(menuItem);
|
@@ -32839,20 +33247,32 @@ define("tinymce/ui/FormatControls", [
|
|
32839
33247
|
},
|
32840
33248
|
|
32841
33249
|
onPostRender: function() {
|
32842
|
-
var self = this
|
33250
|
+
var self = this;
|
33251
|
+
|
33252
|
+
self.parent().on('show', function() {
|
33253
|
+
var formatName, command;
|
32843
33254
|
|
32844
|
-
|
32845
|
-
|
33255
|
+
formatName = self.settings.format;
|
33256
|
+
if (formatName) {
|
32846
33257
|
self.disabled(!editor.formatter.canApply(formatName));
|
32847
33258
|
self.active(editor.formatter.match(formatName));
|
32848
|
-
}
|
32849
|
-
|
33259
|
+
}
|
33260
|
+
|
33261
|
+
command = self.settings.cmd;
|
33262
|
+
if (command) {
|
33263
|
+
self.active(editor.queryCommandState(command));
|
33264
|
+
}
|
33265
|
+
});
|
32850
33266
|
},
|
32851
33267
|
|
32852
33268
|
onclick: function() {
|
32853
33269
|
if (this.settings.format) {
|
32854
33270
|
toggleFormat(this.settings.format);
|
32855
33271
|
}
|
33272
|
+
|
33273
|
+
if (this.settings.cmd) {
|
33274
|
+
editor.execCommand(this.settings.cmd);
|
33275
|
+
}
|
32856
33276
|
}
|
32857
33277
|
}
|
32858
33278
|
};
|
@@ -32947,30 +33367,21 @@ define("tinymce/ui/FormatControls", [
|
|
32947
33367
|
});
|
32948
33368
|
});
|
32949
33369
|
|
32950
|
-
function
|
32951
|
-
return
|
32952
|
-
|
32953
|
-
|
32954
|
-
function hasRedo() {
|
32955
|
-
return editor.undoManager ? editor.undoManager.hasRedo() : false;
|
32956
|
-
}
|
32957
|
-
|
32958
|
-
function toggleUndoState() {
|
32959
|
-
var self = this;
|
33370
|
+
function toggleUndoRedoState(type) {
|
33371
|
+
return function() {
|
33372
|
+
var self = this;
|
32960
33373
|
|
32961
|
-
|
32962
|
-
editor.on('Undo Redo AddUndo TypingUndo', function() {
|
32963
|
-
self.disabled(!hasUndo());
|
32964
|
-
});
|
32965
|
-
}
|
33374
|
+
type = type == 'redo' ? 'hasRedo' : 'hasUndo';
|
32966
33375
|
|
32967
|
-
|
32968
|
-
|
33376
|
+
function checkState() {
|
33377
|
+
return editor.undoManager ? editor.undoManager[type]() : false;
|
33378
|
+
}
|
32969
33379
|
|
32970
|
-
|
32971
|
-
|
32972
|
-
|
32973
|
-
|
33380
|
+
self.disabled(!checkState());
|
33381
|
+
editor.on('Undo Redo AddUndo TypingUndo ClearUndos', function() {
|
33382
|
+
self.disabled(!checkState());
|
33383
|
+
});
|
33384
|
+
};
|
32974
33385
|
}
|
32975
33386
|
|
32976
33387
|
function toggleVisualAidState() {
|
@@ -32985,13 +33396,13 @@ define("tinymce/ui/FormatControls", [
|
|
32985
33396
|
|
32986
33397
|
editor.addButton('undo', {
|
32987
33398
|
tooltip: 'Undo',
|
32988
|
-
onPostRender:
|
33399
|
+
onPostRender: toggleUndoRedoState('undo'),
|
32989
33400
|
cmd: 'undo'
|
32990
33401
|
});
|
32991
33402
|
|
32992
33403
|
editor.addButton('redo', {
|
32993
33404
|
tooltip: 'Redo',
|
32994
|
-
onPostRender:
|
33405
|
+
onPostRender: toggleUndoRedoState('redo'),
|
32995
33406
|
cmd: 'redo'
|
32996
33407
|
});
|
32997
33408
|
|
@@ -33006,7 +33417,7 @@ define("tinymce/ui/FormatControls", [
|
|
33006
33417
|
text: 'Undo',
|
33007
33418
|
icon: 'undo',
|
33008
33419
|
shortcut: 'Ctrl+Z',
|
33009
|
-
onPostRender:
|
33420
|
+
onPostRender: toggleUndoRedoState('undo'),
|
33010
33421
|
cmd: 'undo'
|
33011
33422
|
});
|
33012
33423
|
|
@@ -33014,7 +33425,7 @@ define("tinymce/ui/FormatControls", [
|
|
33014
33425
|
text: 'Redo',
|
33015
33426
|
icon: 'redo',
|
33016
33427
|
shortcut: 'Ctrl+Y',
|
33017
|
-
onPostRender:
|
33428
|
+
onPostRender: toggleUndoRedoState('redo'),
|
33018
33429
|
cmd: 'redo'
|
33019
33430
|
});
|
33020
33431
|
|
@@ -33149,7 +33560,14 @@ define("tinymce/ui/FormatControls", [
|
|
33149
33560
|
var fontsize_formats = editor.settings.fontsize_formats || defaultFontsizeFormats;
|
33150
33561
|
|
33151
33562
|
each(fontsize_formats.split(' '), function(item) {
|
33152
|
-
|
33563
|
+
var text = item, value = item;
|
33564
|
+
// Allow text=value font sizes.
|
33565
|
+
var values = item.split('=');
|
33566
|
+
if (values.length > 1) {
|
33567
|
+
text = values[0];
|
33568
|
+
value = values[1];
|
33569
|
+
}
|
33570
|
+
items.push({text: text, value: value});
|
33153
33571
|
});
|
33154
33572
|
|
33155
33573
|
return {
|
@@ -33991,19 +34409,29 @@ define("tinymce/ui/ListBox", [
|
|
33991
34409
|
* @setting {Array} values Array with values to add to list box.
|
33992
34410
|
*/
|
33993
34411
|
init: function(settings) {
|
33994
|
-
var self = this, values,
|
34412
|
+
var self = this, values, selected, selectedText, lastItemCtrl;
|
33995
34413
|
|
33996
|
-
|
33997
|
-
|
33998
|
-
for (i = 0; i <
|
33999
|
-
selected =
|
34414
|
+
function setSelected(menuValues) {
|
34415
|
+
// Try to find a selected value
|
34416
|
+
for (var i = 0; i < menuValues.length; i++) {
|
34417
|
+
selected = menuValues[i].selected || settings.value === menuValues[i].value;
|
34000
34418
|
|
34001
34419
|
if (selected) {
|
34002
|
-
selectedText = selectedText ||
|
34003
|
-
self._value =
|
34420
|
+
selectedText = selectedText || menuValues[i].text;
|
34421
|
+
self._value = menuValues[i].value;
|
34004
34422
|
break;
|
34005
34423
|
}
|
34424
|
+
|
34425
|
+
// If the value has a submenu, try to find the selected values in that menu
|
34426
|
+
if (menuValues[i].menu) {
|
34427
|
+
setSelected(menuValues[i].menu);
|
34428
|
+
}
|
34006
34429
|
}
|
34430
|
+
}
|
34431
|
+
|
34432
|
+
self._values = values = settings.values;
|
34433
|
+
if (values) {
|
34434
|
+
setSelected(values);
|
34007
34435
|
|
34008
34436
|
// Default with first item
|
34009
34437
|
if (!selected && values.length > 0) {
|
@@ -34044,7 +34472,7 @@ define("tinymce/ui/ListBox", [
|
|
34044
34472
|
* @return {Boolean/tinymce.ui.ListBox} Value or self if it's a set operation.
|
34045
34473
|
*/
|
34046
34474
|
value: function(value) {
|
34047
|
-
var self = this, active, selectedText, menu
|
34475
|
+
var self = this, active, selectedText, menu;
|
34048
34476
|
|
34049
34477
|
function activateByValue(menu, value) {
|
34050
34478
|
menu.items().each(function(ctrl) {
|
@@ -34062,20 +34490,28 @@ define("tinymce/ui/ListBox", [
|
|
34062
34490
|
});
|
34063
34491
|
}
|
34064
34492
|
|
34493
|
+
function setActiveValues(menuValues) {
|
34494
|
+
for (var i = 0; i < menuValues.length; i++) {
|
34495
|
+
active = menuValues[i].value == value;
|
34496
|
+
|
34497
|
+
if (active) {
|
34498
|
+
selectedText = selectedText || menuValues[i].text;
|
34499
|
+
}
|
34500
|
+
|
34501
|
+
menuValues[i].active = active;
|
34502
|
+
|
34503
|
+
if (menuValues[i].menu) {
|
34504
|
+
setActiveValues(menuValues[i].menu);
|
34505
|
+
}
|
34506
|
+
}
|
34507
|
+
}
|
34508
|
+
|
34065
34509
|
if (typeof(value) != "undefined") {
|
34066
34510
|
if (self.menu) {
|
34067
34511
|
activateByValue(self.menu, value);
|
34068
34512
|
} else {
|
34069
34513
|
menu = self.settings.menu;
|
34070
|
-
|
34071
|
-
active = menu[i].value == value;
|
34072
|
-
|
34073
|
-
if (active) {
|
34074
|
-
selectedText = selectedText || menu[i].text;
|
34075
|
-
}
|
34076
|
-
|
34077
|
-
menu[i].active = active;
|
34078
|
-
}
|
34514
|
+
setActiveValues(menu);
|
34079
34515
|
}
|
34080
34516
|
|
34081
34517
|
self.text(selectedText || this.settings.text);
|
@@ -34217,12 +34653,16 @@ define("tinymce/ui/MenuItem", [
|
|
34217
34653
|
|
34218
34654
|
menu = self.menu = Factory.create(menu).parent(self).renderTo();
|
34219
34655
|
menu.reflow();
|
34220
|
-
menu.fire('show');
|
34221
34656
|
menu.on('cancel', function(e) {
|
34222
34657
|
e.stopPropagation();
|
34223
34658
|
self.focus();
|
34224
34659
|
menu.hide();
|
34225
34660
|
});
|
34661
|
+
menu.on('show hide', function(e) {
|
34662
|
+
e.control.items().each(function(ctrl) {
|
34663
|
+
ctrl.active(ctrl.settings.selected);
|
34664
|
+
});
|
34665
|
+
}).fire('show');
|
34226
34666
|
|
34227
34667
|
menu.on('hide', function(e) {
|
34228
34668
|
if (e.control === menu) {
|
@@ -35319,5 +35759,5 @@ define("tinymce/ui/Throbber", [
|
|
35319
35759
|
};
|
35320
35760
|
});
|
35321
35761
|
|
35322
|
-
expose(["tinymce/dom/EventUtils","tinymce/dom/Sizzle","tinymce/dom/DomQuery","tinymce/html/Styles","tinymce/dom/TreeWalker","tinymce/util/Tools","tinymce/dom/Range","tinymce/html/Entities","tinymce/Env","tinymce/dom/
|
35762
|
+
expose(["tinymce/dom/EventUtils","tinymce/dom/Sizzle","tinymce/dom/DomQuery","tinymce/html/Styles","tinymce/dom/TreeWalker","tinymce/util/Tools","tinymce/dom/Range","tinymce/html/Entities","tinymce/Env","tinymce/dom/DOMUtils","tinymce/dom/ScriptLoader","tinymce/AddOnManager","tinymce/html/Node","tinymce/html/Schema","tinymce/html/SaxParser","tinymce/html/DomParser","tinymce/html/Writer","tinymce/html/Serializer","tinymce/dom/Serializer","tinymce/dom/TridentSelection","tinymce/util/VK","tinymce/dom/ControlSelection","tinymce/dom/BookmarkManager","tinymce/dom/Selection","tinymce/dom/ElementUtils","tinymce/Formatter","tinymce/UndoManager","tinymce/EnterKey","tinymce/ForceBlocks","tinymce/EditorCommands","tinymce/util/URI","tinymce/util/Class","tinymce/util/EventDispatcher","tinymce/ui/Selector","tinymce/ui/Collection","tinymce/ui/DomUtils","tinymce/ui/Control","tinymce/ui/Factory","tinymce/ui/KeyboardNavigation","tinymce/ui/Container","tinymce/ui/DragHelper","tinymce/ui/Scrollable","tinymce/ui/Panel","tinymce/ui/Movable","tinymce/ui/Resizable","tinymce/ui/FloatPanel","tinymce/ui/Window","tinymce/ui/MessageBox","tinymce/WindowManager","tinymce/util/Quirks","tinymce/util/Observable","tinymce/EditorObservable","tinymce/Shortcuts","tinymce/Editor","tinymce/util/I18n","tinymce/FocusManager","tinymce/EditorManager","tinymce/LegacyInput","tinymce/util/XHR","tinymce/util/JSON","tinymce/util/JSONRequest","tinymce/util/JSONP","tinymce/util/LocalStorage","tinymce/Compat","tinymce/ui/Layout","tinymce/ui/AbsoluteLayout","tinymce/ui/Tooltip","tinymce/ui/Widget","tinymce/ui/Button","tinymce/ui/ButtonGroup","tinymce/ui/Checkbox","tinymce/ui/PanelButton","tinymce/ui/ColorButton","tinymce/ui/ComboBox","tinymce/ui/Path","tinymce/ui/ElementPath","tinymce/ui/FormItem","tinymce/ui/Form","tinymce/ui/FieldSet","tinymce/ui/FilePicker","tinymce/ui/FitLayout","tinymce/ui/FlexLayout","tinymce/ui/FlowLayout","tinymce/ui/FormatControls","tinymce/ui/GridLayout","tinymce/ui/Iframe","tinymce/ui/Label","tinymce/ui/Toolbar","tinymce/ui/MenuBar","tinymce/ui/MenuButton","tinymce/ui/ListBox","tinymce/ui/MenuItem","tinymce/ui/Menu","tinymce/ui/Radio","tinymce/ui/ResizeHandle","tinymce/ui/Spacer","tinymce/ui/SplitButton","tinymce/ui/StackLayout","tinymce/ui/TabPanel","tinymce/ui/TextBox","tinymce/ui/Throbber"]);
|
35323
35763
|
})(this);
|