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