tinymce-rails 4.0.26 → 4.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/assets/source/tinymce/tinymce.jquery.js +1111 -671
- data/app/assets/source/tinymce/tinymce.js +1108 -668
- data/lib/tinymce/rails/configuration.rb +28 -2
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/spellchecker/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/css/visualblocks.css +7 -0
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.jquery.js +10 -10
- data/vendor/assets/javascripts/tinymce/tinymce.js +11 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d61de30fa04cae313a1896b6cb9326acb089427
|
4
|
+
data.tar.gz: c505df76105015340cc701707fda4801201756ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43bd86134162aa09da12d021d390f0795a1eeaa064b4eaa7b9a3daa5ce07cca60a777ac350c9cde96d495acd094a4a116f7020067c1b71a4cf2aec8513659399
|
7
|
+
data.tar.gz: cdf88d954d3b887f44a2a4f4e9834c5657a87659e9e9440a44d748dc52150957bc5d63dcb4a5cac3fe2d5543c4e930890d2870917e4e30435e46209d7c08ee0e
|
data/README.md
CHANGED
@@ -25,8 +25,9 @@ Be sure to add to the global group, not the `assets` group. Then run `bundle ins
|
|
25
25
|
**2. Create a `config/tinymce.yml` file with your global configuration options:**
|
26
26
|
|
27
27
|
```yml
|
28
|
-
|
29
|
-
|
28
|
+
toolbar:
|
29
|
+
- styleselect | bold italic | link image | undo redo
|
30
|
+
- table | fullscreen
|
30
31
|
plugins:
|
31
32
|
- table
|
32
33
|
- fullscreen
|
@@ -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)
|
@@ -146,10 +146,15 @@ define("tinymce/html/Styles", [], function() {
|
|
146
146
|
urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,
|
147
147
|
styleRegExp = /\s*([^:]+):\s*([^;]+);?/g,
|
148
148
|
trimRightRegExp = /\s+$/,
|
149
|
-
undef, i, encodingLookup = {}, encodingItems, invisibleChar = '\uFEFF';
|
149
|
+
undef, i, encodingLookup = {}, encodingItems, validStyles, invalidStyles, invisibleChar = '\uFEFF';
|
150
150
|
|
151
151
|
settings = settings || {};
|
152
152
|
|
153
|
+
if (schema) {
|
154
|
+
validStyles = schema.getValidStyles();
|
155
|
+
invalidStyles = schema.getInvalidStyles();
|
156
|
+
}
|
157
|
+
|
153
158
|
encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
|
154
159
|
for (i = 0; i < encodingItems.length; i++) {
|
155
160
|
encodingLookup[encodingItems[i]] = invisibleChar + i;
|
@@ -407,16 +412,16 @@ define("tinymce/html/Styles", [], function() {
|
|
407
412
|
*
|
408
413
|
* @method serialize
|
409
414
|
* @param {Object} styles Object to serialize as string for example: {border: '1px solid red'}
|
410
|
-
* @param {String}
|
415
|
+
* @param {String} elementName Optional element name, if specified only the styles that matches the schema will be serialized.
|
411
416
|
* @return {String} String representation of the style object for example: border: 1px solid red.
|
412
417
|
*/
|
413
|
-
serialize: function(styles,
|
418
|
+
serialize: function(styles, elementName) {
|
414
419
|
var css = '', name, value;
|
415
420
|
|
416
421
|
function serializeStyles(name) {
|
417
422
|
var styleList, i, l, value;
|
418
423
|
|
419
|
-
styleList =
|
424
|
+
styleList = validStyles[name];
|
420
425
|
if (styleList) {
|
421
426
|
for (i = 0, l = styleList.length; i < l; i++) {
|
422
427
|
name = styleList[i];
|
@@ -429,18 +434,36 @@ define("tinymce/html/Styles", [], function() {
|
|
429
434
|
}
|
430
435
|
}
|
431
436
|
|
437
|
+
function isValid(name, elementName) {
|
438
|
+
var styleMap;
|
439
|
+
|
440
|
+
styleMap = invalidStyles['*'];
|
441
|
+
if (styleMap && styleMap[name]) {
|
442
|
+
return false;
|
443
|
+
}
|
444
|
+
|
445
|
+
styleMap = invalidStyles[elementName];
|
446
|
+
if (styleMap && styleMap[name]) {
|
447
|
+
return false;
|
448
|
+
}
|
449
|
+
|
450
|
+
return true;
|
451
|
+
}
|
452
|
+
|
432
453
|
// Serialize styles according to schema
|
433
|
-
if (
|
454
|
+
if (elementName && validStyles) {
|
434
455
|
// Serialize global styles and element specific styles
|
435
456
|
serializeStyles('*');
|
436
|
-
serializeStyles(
|
457
|
+
serializeStyles(elementName);
|
437
458
|
} else {
|
438
459
|
// Output the styles in the order they are inside the object
|
439
460
|
for (name in styles) {
|
440
461
|
value = styles[name];
|
441
462
|
|
442
463
|
if (value !== undef && value.length > 0) {
|
443
|
-
|
464
|
+
if (!invalidStyles || isValid(name, elementName)) {
|
465
|
+
css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
|
466
|
+
}
|
444
467
|
}
|
445
468
|
}
|
446
469
|
}
|
@@ -466,6 +489,11 @@ define("tinymce/html/Styles", [], function() {
|
|
466
489
|
/*jshint loopfunc:true*/
|
467
490
|
/*eslint no-loop-func:0 */
|
468
491
|
|
492
|
+
/**
|
493
|
+
* This class wraps the browsers native event logic with more convenient methods.
|
494
|
+
*
|
495
|
+
* @class tinymce.dom.EventUtils
|
496
|
+
*/
|
469
497
|
define("tinymce/dom/EventUtils", [], function() {
|
470
498
|
"use strict";
|
471
499
|
|
@@ -3274,7 +3302,9 @@ define("tinymce/dom/DOMUtils", [
|
|
3274
3302
|
selectorVal = selector;
|
3275
3303
|
|
3276
3304
|
if (selector === '*') {
|
3277
|
-
selector = function(node) {
|
3305
|
+
selector = function(node) {
|
3306
|
+
return node.nodeType == 1;
|
3307
|
+
};
|
3278
3308
|
} else {
|
3279
3309
|
selector = function(node) {
|
3280
3310
|
return self.is(node, selectorVal);
|
@@ -3591,7 +3621,7 @@ define("tinymce/dom/DOMUtils", [
|
|
3591
3621
|
});
|
3592
3622
|
|
3593
3623
|
// Default px suffix on these
|
3594
|
-
if (typeof(value) === 'number' && !numericCssMap[name]) {
|
3624
|
+
if (((typeof(value) === 'number') || /^[\-0-9\.]+$/.test(value)) && !numericCssMap[name]) {
|
3595
3625
|
value += 'px';
|
3596
3626
|
}
|
3597
3627
|
|
@@ -6352,7 +6382,8 @@ define("tinymce/html/Schema", [
|
|
6352
6382
|
if (type != "html5-strict") {
|
6353
6383
|
addAttrs("script", "language xml:space");
|
6354
6384
|
addAttrs("style", "xml:space");
|
6355
|
-
addAttrs("object", "declare classid codebase codetype archive standby align border hspace vspace");
|
6385
|
+
addAttrs("object", "declare classid code codebase codetype archive standby align border hspace vspace");
|
6386
|
+
addAttrs("embed", "align name hspace vspace");
|
6356
6387
|
addAttrs("param", "valuetype type");
|
6357
6388
|
addAttrs("a", "charset name rev shape coords");
|
6358
6389
|
addAttrs("br", "clear");
|
@@ -6421,6 +6452,27 @@ define("tinymce/html/Schema", [
|
|
6421
6452
|
return schema;
|
6422
6453
|
}
|
6423
6454
|
|
6455
|
+
function compileElementMap(value, mode) {
|
6456
|
+
var styles;
|
6457
|
+
|
6458
|
+
if (value) {
|
6459
|
+
styles = {};
|
6460
|
+
|
6461
|
+
if (typeof value == 'string') {
|
6462
|
+
value = {
|
6463
|
+
'*': value
|
6464
|
+
};
|
6465
|
+
}
|
6466
|
+
|
6467
|
+
// Convert styles into a rule list
|
6468
|
+
each(value, function(value, key) {
|
6469
|
+
styles[key] = mode == 'map' ? makeMap(value, /[, ]/) : explode(value, /[, ]/);
|
6470
|
+
});
|
6471
|
+
}
|
6472
|
+
|
6473
|
+
return styles;
|
6474
|
+
}
|
6475
|
+
|
6424
6476
|
/**
|
6425
6477
|
* Constructs a new Schema instance.
|
6426
6478
|
*
|
@@ -6429,9 +6481,10 @@ define("tinymce/html/Schema", [
|
|
6429
6481
|
* @param {Object} settings Name/value settings object.
|
6430
6482
|
*/
|
6431
6483
|
return function(settings) {
|
6432
|
-
var self = this, elements = {}, children = {}, patternElements = [], validStyles, schemaItems;
|
6433
|
-
var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap;
|
6434
|
-
var blockElementsMap, nonEmptyElementsMap, textBlockElementsMap,
|
6484
|
+
var self = this, elements = {}, children = {}, patternElements = [], validStyles, invalidStyles, schemaItems;
|
6485
|
+
var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, validClasses;
|
6486
|
+
var blockElementsMap, nonEmptyElementsMap, textBlockElementsMap, textInlineElementsMap;
|
6487
|
+
var customElementsMap = {}, specialElements = {};
|
6435
6488
|
|
6436
6489
|
// Creates an lookup table map object for the specified option or the default value
|
6437
6490
|
function createLookupTable(option, default_value, extendWith) {
|
@@ -6463,15 +6516,9 @@ define("tinymce/html/Schema", [
|
|
6463
6516
|
settings.valid_elements = '*[*]';
|
6464
6517
|
}
|
6465
6518
|
|
6466
|
-
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
// Convert styles into a rule list
|
6471
|
-
each(settings.valid_styles, function(value, key) {
|
6472
|
-
validStyles[key] = explode(value);
|
6473
|
-
});
|
6474
|
-
}
|
6519
|
+
validStyles = compileElementMap(settings.valid_styles);
|
6520
|
+
invalidStyles = compileElementMap(settings.invalid_styles, 'map');
|
6521
|
+
validClasses = compileElementMap(settings.valid_classes, 'map');
|
6475
6522
|
|
6476
6523
|
// Setup map objects
|
6477
6524
|
whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object');
|
@@ -6486,6 +6533,8 @@ define("tinymce/html/Schema", [
|
|
6486
6533
|
blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' +
|
6487
6534
|
'th tr td li ol ul caption dl dt dd noscript menu isindex option ' +
|
6488
6535
|
'datalist select optgroup', textBlockElementsMap);
|
6536
|
+
textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' +
|
6537
|
+
'dfn code mark q sup sub samp');
|
6489
6538
|
|
6490
6539
|
each((settings.special || 'script noscript style textarea').split(' '), function(name) {
|
6491
6540
|
specialElements[name] = new RegExp('<\/' + name + '[^>]*>','gi');
|
@@ -6842,10 +6891,32 @@ define("tinymce/html/Schema", [
|
|
6842
6891
|
/**
|
6843
6892
|
* Name/value map object with valid styles for each element.
|
6844
6893
|
*
|
6845
|
-
* @
|
6894
|
+
* @method getValidStyles
|
6895
|
+
* @type Object
|
6896
|
+
*/
|
6897
|
+
self.getValidStyles = function() {
|
6898
|
+
return validStyles;
|
6899
|
+
};
|
6900
|
+
|
6901
|
+
/**
|
6902
|
+
* Name/value map object with valid styles for each element.
|
6903
|
+
*
|
6904
|
+
* @method getInvalidStyles
|
6905
|
+
* @type Object
|
6906
|
+
*/
|
6907
|
+
self.getInvalidStyles = function() {
|
6908
|
+
return invalidStyles;
|
6909
|
+
};
|
6910
|
+
|
6911
|
+
/**
|
6912
|
+
* Name/value map object with valid classes for each element.
|
6913
|
+
*
|
6914
|
+
* @method getValidClasses
|
6846
6915
|
* @type Object
|
6847
6916
|
*/
|
6848
|
-
self.
|
6917
|
+
self.getValidClasses = function() {
|
6918
|
+
return validClasses;
|
6919
|
+
};
|
6849
6920
|
|
6850
6921
|
/**
|
6851
6922
|
* Returns a map with boolean attributes.
|
@@ -6877,6 +6948,16 @@ define("tinymce/html/Schema", [
|
|
6877
6948
|
return textBlockElementsMap;
|
6878
6949
|
};
|
6879
6950
|
|
6951
|
+
/**
|
6952
|
+
* Returns a map of inline text format nodes for example strong/span or ins.
|
6953
|
+
*
|
6954
|
+
* @method getTextInlineElements
|
6955
|
+
* @return {Object} Name/value lookup map for text format elements.
|
6956
|
+
*/
|
6957
|
+
self.getTextInlineElements = function() {
|
6958
|
+
return textInlineElementsMap;
|
6959
|
+
};
|
6960
|
+
|
6880
6961
|
/**
|
6881
6962
|
* Returns a map with short ended elements such as BR or IMG.
|
6882
6963
|
*
|
@@ -7106,6 +7187,36 @@ define("tinymce/html/SaxParser", [
|
|
7106
7187
|
], function(Schema, Entities, Tools) {
|
7107
7188
|
var each = Tools.each;
|
7108
7189
|
|
7190
|
+
/**
|
7191
|
+
* Returns the index of the end tag for a specific start tag. This can be
|
7192
|
+
* used to skip all children of a parent element from being processed.
|
7193
|
+
*/
|
7194
|
+
function skipUntilEndTag(schema, html, startIndex) {
|
7195
|
+
var count = 1, matches, tokenRegExp, shortEndedElements;
|
7196
|
+
|
7197
|
+
shortEndedElements = schema.getShortEndedElements();
|
7198
|
+
tokenRegExp = /<([!?\/])?([A-Za-z0-9\-\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
|
7199
|
+
tokenRegExp.lastIndex = startIndex;
|
7200
|
+
|
7201
|
+
while ((matches = tokenRegExp.exec(html))) {
|
7202
|
+
if (matches[1] === '/') { // End element
|
7203
|
+
count--;
|
7204
|
+
} else if (!matches[1]) { // Start element
|
7205
|
+
if (matches[2] in shortEndedElements) {
|
7206
|
+
continue;
|
7207
|
+
}
|
7208
|
+
|
7209
|
+
count++;
|
7210
|
+
}
|
7211
|
+
|
7212
|
+
if (count === 0) {
|
7213
|
+
break;
|
7214
|
+
}
|
7215
|
+
}
|
7216
|
+
|
7217
|
+
return tokenRegExp.lastIndex;
|
7218
|
+
}
|
7219
|
+
|
7109
7220
|
/**
|
7110
7221
|
* Constructs a new SaxParser instance.
|
7111
7222
|
*
|
@@ -7387,7 +7498,13 @@ define("tinymce/html/SaxParser", [
|
|
7387
7498
|
}
|
7388
7499
|
|
7389
7500
|
// Invalidate element if it's marked as bogus
|
7390
|
-
if (attrList.map['data-mce-bogus']) {
|
7501
|
+
if ((attr = attrList.map['data-mce-bogus'])) {
|
7502
|
+
if (attr === 'all') {
|
7503
|
+
index = skipUntilEndTag(schema, html, tokenRegExp.lastIndex);
|
7504
|
+
tokenRegExp.lastIndex = index;
|
7505
|
+
continue;
|
7506
|
+
}
|
7507
|
+
|
7391
7508
|
isValidElement = false;
|
7392
7509
|
}
|
7393
7510
|
}
|
@@ -8050,7 +8167,7 @@ define("tinymce/html/DomParser", [
|
|
8050
8167
|
// Leave nodes that have a name like <a name="name">
|
8051
8168
|
if (!node.attributes.map.name && !node.attributes.map.id) {
|
8052
8169
|
tempNode = node.parent;
|
8053
|
-
node.
|
8170
|
+
node.unwrap();
|
8054
8171
|
node = tempNode;
|
8055
8172
|
return;
|
8056
8173
|
}
|
@@ -8229,6 +8346,48 @@ define("tinymce/html/DomParser", [
|
|
8229
8346
|
}
|
8230
8347
|
});
|
8231
8348
|
}
|
8349
|
+
|
8350
|
+
if (settings.validate && schema.getValidClasses()) {
|
8351
|
+
self.addAttributeFilter('class', function(nodes) {
|
8352
|
+
var i = nodes.length, node, classList, ci, className, classValue;
|
8353
|
+
var validClasses = schema.getValidClasses(), validClassesMap, valid;
|
8354
|
+
|
8355
|
+
while (i--) {
|
8356
|
+
node = nodes[i];
|
8357
|
+
classList = node.attr('class').split(' ');
|
8358
|
+
classValue = '';
|
8359
|
+
|
8360
|
+
for (ci = 0; ci < classList.length; ci++) {
|
8361
|
+
className = classList[ci];
|
8362
|
+
valid = false;
|
8363
|
+
|
8364
|
+
validClassesMap = validClasses['*'];
|
8365
|
+
if (validClassesMap && validClassesMap[className]) {
|
8366
|
+
valid = true;
|
8367
|
+
}
|
8368
|
+
|
8369
|
+
validClassesMap = validClasses[node.name];
|
8370
|
+
if (!valid && validClassesMap && !validClassesMap[className]) {
|
8371
|
+
valid = true;
|
8372
|
+
}
|
8373
|
+
|
8374
|
+
if (valid) {
|
8375
|
+
if (classValue) {
|
8376
|
+
classValue += ' ';
|
8377
|
+
}
|
8378
|
+
|
8379
|
+
classValue += className;
|
8380
|
+
}
|
8381
|
+
}
|
8382
|
+
|
8383
|
+
if (!classValue.length) {
|
8384
|
+
classValue = null;
|
8385
|
+
}
|
8386
|
+
|
8387
|
+
node.attr('class', classValue);
|
8388
|
+
}
|
8389
|
+
});
|
8390
|
+
}
|
8232
8391
|
};
|
8233
8392
|
});
|
8234
8393
|
|
@@ -8711,15 +8870,6 @@ define("tinymce/dom/Serializer", [
|
|
8711
8870
|
}
|
8712
8871
|
});
|
8713
8872
|
|
8714
|
-
// Remove expando attributes
|
8715
|
-
htmlParser.addAttributeFilter('data-mce-expando', function(nodes, name) {
|
8716
|
-
var i = nodes.length;
|
8717
|
-
|
8718
|
-
while (i--) {
|
8719
|
-
nodes[i].attr(name, null);
|
8720
|
-
}
|
8721
|
-
});
|
8722
|
-
|
8723
8873
|
htmlParser.addNodeFilter('noscript', function(nodes) {
|
8724
8874
|
var i = nodes.length, node;
|
8725
8875
|
|
@@ -8734,7 +8884,7 @@ define("tinymce/dom/Serializer", [
|
|
8734
8884
|
|
8735
8885
|
// Force script into CDATA sections and remove the mce- prefix also add comments around styles
|
8736
8886
|
htmlParser.addNodeFilter('script,style', function(nodes, name) {
|
8737
|
-
var i = nodes.length, node, value;
|
8887
|
+
var i = nodes.length, node, value, type;
|
8738
8888
|
|
8739
8889
|
function trim(value) {
|
8740
8890
|
/*jshint maxlen:255 */
|
@@ -8750,9 +8900,12 @@ define("tinymce/dom/Serializer", [
|
|
8750
8900
|
value = node.firstChild ? node.firstChild.value : '';
|
8751
8901
|
|
8752
8902
|
if (name === "script") {
|
8753
|
-
// Remove mce- prefix from script elements and remove default
|
8754
|
-
|
8755
|
-
node.attr('type'
|
8903
|
+
// Remove mce- prefix from script elements and remove default type since the user specified
|
8904
|
+
// a script element without type attribute
|
8905
|
+
type = node.attr('type');
|
8906
|
+
if (type) {
|
8907
|
+
node.attr('type', type == 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
|
8908
|
+
}
|
8756
8909
|
|
8757
8910
|
if (value.length > 0) {
|
8758
8911
|
node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
|
@@ -8819,13 +8972,19 @@ define("tinymce/dom/Serializer", [
|
|
8819
8972
|
}
|
8820
8973
|
|
8821
8974
|
// Remove internal data attributes
|
8822
|
-
htmlParser.addAttributeFilter(
|
8823
|
-
|
8975
|
+
htmlParser.addAttributeFilter(
|
8976
|
+
'data-mce-src,data-mce-href,data-mce-style,' +
|
8977
|
+
'data-mce-selected,data-mce-expando,' +
|
8978
|
+
'data-mce-type,data-mce-resize',
|
8824
8979
|
|
8825
|
-
|
8826
|
-
nodes
|
8980
|
+
function(nodes, name) {
|
8981
|
+
var i = nodes.length;
|
8982
|
+
|
8983
|
+
while (i--) {
|
8984
|
+
nodes[i].attr(name, null);
|
8985
|
+
}
|
8827
8986
|
}
|
8828
|
-
|
8987
|
+
);
|
8829
8988
|
|
8830
8989
|
// Return public methods
|
8831
8990
|
return {
|
@@ -9161,15 +9320,17 @@ define("tinymce/dom/TridentSelection", [], function() {
|
|
9161
9320
|
|
9162
9321
|
// Find the text node and offset
|
9163
9322
|
while (sibling) {
|
9164
|
-
|
9165
|
-
|
9166
|
-
|
9167
|
-
|
9168
|
-
|
9169
|
-
|
9170
|
-
|
9171
|
-
|
9172
|
-
|
9323
|
+
if (sibling.nodeType == 3) {
|
9324
|
+
nodeValue = sibling.nodeValue;
|
9325
|
+
textNodeOffset += nodeValue.length;
|
9326
|
+
|
9327
|
+
// We are at or passed the position we where looking for
|
9328
|
+
if (textNodeOffset >= offset) {
|
9329
|
+
container = sibling;
|
9330
|
+
textNodeOffset -= offset;
|
9331
|
+
textNodeOffset = nodeValue.length - textNodeOffset;
|
9332
|
+
break;
|
9333
|
+
}
|
9173
9334
|
}
|
9174
9335
|
|
9175
9336
|
sibling = sibling.nextSibling;
|
@@ -9194,13 +9355,15 @@ define("tinymce/dom/TridentSelection", [], function() {
|
|
9194
9355
|
}
|
9195
9356
|
|
9196
9357
|
while (sibling) {
|
9197
|
-
|
9358
|
+
if (sibling.nodeType == 3) {
|
9359
|
+
textNodeOffset += sibling.nodeValue.length;
|
9198
9360
|
|
9199
|
-
|
9200
|
-
|
9201
|
-
|
9202
|
-
|
9203
|
-
|
9361
|
+
// We are at or passed the position we where looking for
|
9362
|
+
if (textNodeOffset >= offset) {
|
9363
|
+
container = sibling;
|
9364
|
+
textNodeOffset -= offset;
|
9365
|
+
break;
|
9366
|
+
}
|
9204
9367
|
}
|
9205
9368
|
|
9206
9369
|
sibling = sibling.previousSibling;
|
@@ -9533,8 +9696,8 @@ define("tinymce/util/VK", [
|
|
9533
9696
|
},
|
9534
9697
|
|
9535
9698
|
metaKeyPressed: function(e) {
|
9536
|
-
// Check if ctrl or meta key is pressed
|
9537
|
-
return (Env.mac ? e.metaKey : e.ctrlKey
|
9699
|
+
// Check if ctrl or meta key is pressed. Edge case for AltGr on Windows where it produces ctrlKey+altKey states
|
9700
|
+
return (Env.mac ? e.metaKey : e.ctrlKey && !e.altKey);
|
9538
9701
|
}
|
9539
9702
|
};
|
9540
9703
|
});
|
@@ -10066,7 +10229,7 @@ define("tinymce/dom/ControlSelection", [
|
|
10066
10229
|
// Included from: js/tinymce/classes/dom/RangeUtils.js
|
10067
10230
|
|
10068
10231
|
/**
|
10069
|
-
*
|
10232
|
+
* RangeUtils.js
|
10070
10233
|
*
|
10071
10234
|
* Copyright, Moxiecode Systems AB
|
10072
10235
|
* Released under LGPL License.
|
@@ -10076,7 +10239,7 @@ define("tinymce/dom/ControlSelection", [
|
|
10076
10239
|
*/
|
10077
10240
|
|
10078
10241
|
/**
|
10079
|
-
*
|
10242
|
+
* This class contains a few utility methods for ranges.
|
10080
10243
|
*
|
10081
10244
|
* @class tinymce.dom.RangeUtils
|
10082
10245
|
* @private
|
@@ -10087,6 +10250,20 @@ define("tinymce/dom/RangeUtils", [
|
|
10087
10250
|
], function(Tools, TreeWalker) {
|
10088
10251
|
var each = Tools.each;
|
10089
10252
|
|
10253
|
+
function getEndChild(container, index) {
|
10254
|
+
var childNodes = container.childNodes;
|
10255
|
+
|
10256
|
+
index--;
|
10257
|
+
|
10258
|
+
if (index > childNodes.length - 1) {
|
10259
|
+
index = childNodes.length - 1;
|
10260
|
+
} else if (index < 0) {
|
10261
|
+
index = 0;
|
10262
|
+
}
|
10263
|
+
|
10264
|
+
return childNodes[index] || container;
|
10265
|
+
}
|
10266
|
+
|
10090
10267
|
function RangeUtils(dom) {
|
10091
10268
|
/**
|
10092
10269
|
* Walks the specified range like object and executes the callback for each sibling collection it finds.
|
@@ -10199,7 +10376,7 @@ define("tinymce/dom/RangeUtils", [
|
|
10199
10376
|
|
10200
10377
|
// If index based end position then resolve it
|
10201
10378
|
if (endContainer.nodeType == 1 && endContainer.hasChildNodes()) {
|
10202
|
-
endContainer = endContainer
|
10379
|
+
endContainer = getEndChild(endContainer, endOffset);
|
10203
10380
|
}
|
10204
10381
|
|
10205
10382
|
// Same container
|
@@ -10546,6 +10723,398 @@ define("tinymce/dom/RangeUtils", [
|
|
10546
10723
|
return RangeUtils;
|
10547
10724
|
});
|
10548
10725
|
|
10726
|
+
// Included from: js/tinymce/classes/dom/BookmarkManager.js
|
10727
|
+
|
10728
|
+
/**
|
10729
|
+
* BookmarkManager.js
|
10730
|
+
*
|
10731
|
+
* Copyright, Moxiecode Systems AB
|
10732
|
+
* Released under LGPL License.
|
10733
|
+
*
|
10734
|
+
* License: http://www.tinymce.com/license
|
10735
|
+
* Contributing: http://www.tinymce.com/contributing
|
10736
|
+
*/
|
10737
|
+
|
10738
|
+
/**
|
10739
|
+
* This class handles selection bookmarks.
|
10740
|
+
*
|
10741
|
+
* @class tinymce.dom.BookmarkManager
|
10742
|
+
*/
|
10743
|
+
define("tinymce/dom/BookmarkManager", [
|
10744
|
+
"tinymce/Env",
|
10745
|
+
"tinymce/util/Tools"
|
10746
|
+
], function(Env, Tools) {
|
10747
|
+
/**
|
10748
|
+
* Constructs a new BookmarkManager instance for a specific selection instance.
|
10749
|
+
*
|
10750
|
+
* @constructor
|
10751
|
+
* @method BookmarkManager
|
10752
|
+
* @param {tinymce.dom.Selection} selection Selection instance to handle bookmarks for.
|
10753
|
+
*/
|
10754
|
+
function BookmarkManager(selection) {
|
10755
|
+
var dom = selection.dom;
|
10756
|
+
|
10757
|
+
/**
|
10758
|
+
* Returns a bookmark location for the current selection. This bookmark object
|
10759
|
+
* can then be used to restore the selection after some content modification to the document.
|
10760
|
+
*
|
10761
|
+
* @method getBookmark
|
10762
|
+
* @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
|
10763
|
+
* @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
|
10764
|
+
* @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
|
10765
|
+
* @example
|
10766
|
+
* // Stores a bookmark of the current selection
|
10767
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10768
|
+
*
|
10769
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10770
|
+
*
|
10771
|
+
* // Restore the selection bookmark
|
10772
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10773
|
+
*/
|
10774
|
+
this.getBookmark = function(type, normalized) {
|
10775
|
+
var rng, rng2, id, collapsed, name, element, chr = '', styles;
|
10776
|
+
|
10777
|
+
function findIndex(name, element) {
|
10778
|
+
var index = 0;
|
10779
|
+
|
10780
|
+
Tools.each(dom.select(name), function(node, i) {
|
10781
|
+
if (node == element) {
|
10782
|
+
index = i;
|
10783
|
+
}
|
10784
|
+
});
|
10785
|
+
|
10786
|
+
return index;
|
10787
|
+
}
|
10788
|
+
|
10789
|
+
function normalizeTableCellSelection(rng) {
|
10790
|
+
function moveEndPoint(start) {
|
10791
|
+
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
10792
|
+
|
10793
|
+
container = rng[prefix + 'Container'];
|
10794
|
+
offset = rng[prefix + 'Offset'];
|
10795
|
+
|
10796
|
+
if (container.nodeType == 1 && container.nodeName == "TR") {
|
10797
|
+
childNodes = container.childNodes;
|
10798
|
+
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
10799
|
+
if (container) {
|
10800
|
+
offset = start ? 0 : container.childNodes.length;
|
10801
|
+
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
10802
|
+
}
|
10803
|
+
}
|
10804
|
+
}
|
10805
|
+
|
10806
|
+
moveEndPoint(true);
|
10807
|
+
moveEndPoint();
|
10808
|
+
|
10809
|
+
return rng;
|
10810
|
+
}
|
10811
|
+
|
10812
|
+
function getLocation() {
|
10813
|
+
var rng = selection.getRng(true), root = dom.getRoot(), bookmark = {};
|
10814
|
+
|
10815
|
+
function getPoint(rng, start) {
|
10816
|
+
var container = rng[start ? 'startContainer' : 'endContainer'],
|
10817
|
+
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
10818
|
+
|
10819
|
+
if (container.nodeType == 3) {
|
10820
|
+
if (normalized) {
|
10821
|
+
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
10822
|
+
offset += node.nodeValue.length;
|
10823
|
+
}
|
10824
|
+
}
|
10825
|
+
|
10826
|
+
point.push(offset);
|
10827
|
+
} else {
|
10828
|
+
childNodes = container.childNodes;
|
10829
|
+
|
10830
|
+
if (offset >= childNodes.length && childNodes.length) {
|
10831
|
+
after = 1;
|
10832
|
+
offset = Math.max(0, childNodes.length - 1);
|
10833
|
+
}
|
10834
|
+
|
10835
|
+
point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
|
10836
|
+
}
|
10837
|
+
|
10838
|
+
for (; container && container != root; container = container.parentNode) {
|
10839
|
+
point.push(dom.nodeIndex(container, normalized));
|
10840
|
+
}
|
10841
|
+
|
10842
|
+
return point;
|
10843
|
+
}
|
10844
|
+
|
10845
|
+
bookmark.start = getPoint(rng, true);
|
10846
|
+
|
10847
|
+
if (!selection.isCollapsed()) {
|
10848
|
+
bookmark.end = getPoint(rng);
|
10849
|
+
}
|
10850
|
+
|
10851
|
+
return bookmark;
|
10852
|
+
}
|
10853
|
+
|
10854
|
+
if (type == 2) {
|
10855
|
+
element = selection.getNode();
|
10856
|
+
name = element ? element.nodeName : null;
|
10857
|
+
|
10858
|
+
if (name == 'IMG') {
|
10859
|
+
return {name: name, index: findIndex(name, element)};
|
10860
|
+
}
|
10861
|
+
|
10862
|
+
if (selection.tridentSel) {
|
10863
|
+
return selection.tridentSel.getBookmark(type);
|
10864
|
+
}
|
10865
|
+
|
10866
|
+
return getLocation();
|
10867
|
+
}
|
10868
|
+
|
10869
|
+
// Handle simple range
|
10870
|
+
if (type) {
|
10871
|
+
return {rng: selection.getRng()};
|
10872
|
+
}
|
10873
|
+
|
10874
|
+
rng = selection.getRng();
|
10875
|
+
id = dom.uniqueId();
|
10876
|
+
collapsed = selection.isCollapsed();
|
10877
|
+
styles = 'overflow:hidden;line-height:0px';
|
10878
|
+
|
10879
|
+
// Explorer method
|
10880
|
+
if (rng.duplicate || rng.item) {
|
10881
|
+
// Text selection
|
10882
|
+
if (!rng.item) {
|
10883
|
+
rng2 = rng.duplicate();
|
10884
|
+
|
10885
|
+
try {
|
10886
|
+
// Insert start marker
|
10887
|
+
rng.collapse();
|
10888
|
+
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
10889
|
+
|
10890
|
+
// Insert end marker
|
10891
|
+
if (!collapsed) {
|
10892
|
+
rng2.collapse(false);
|
10893
|
+
|
10894
|
+
// Detect the empty space after block elements in IE and move the
|
10895
|
+
// end back one character <p></p>] becomes <p>]</p>
|
10896
|
+
rng.moveToElementText(rng2.parentElement());
|
10897
|
+
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
10898
|
+
rng2.move('character', -1);
|
10899
|
+
}
|
10900
|
+
|
10901
|
+
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
10902
|
+
}
|
10903
|
+
} catch (ex) {
|
10904
|
+
// IE might throw unspecified error so lets ignore it
|
10905
|
+
return null;
|
10906
|
+
}
|
10907
|
+
} else {
|
10908
|
+
// Control selection
|
10909
|
+
element = rng.item(0);
|
10910
|
+
name = element.nodeName;
|
10911
|
+
|
10912
|
+
return {name: name, index: findIndex(name, element)};
|
10913
|
+
}
|
10914
|
+
} else {
|
10915
|
+
element = selection.getNode();
|
10916
|
+
name = element.nodeName;
|
10917
|
+
if (name == 'IMG') {
|
10918
|
+
return {name: name, index: findIndex(name, element)};
|
10919
|
+
}
|
10920
|
+
|
10921
|
+
// W3C method
|
10922
|
+
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
10923
|
+
|
10924
|
+
// Insert end marker
|
10925
|
+
if (!collapsed) {
|
10926
|
+
rng2.collapse(false);
|
10927
|
+
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
10928
|
+
}
|
10929
|
+
|
10930
|
+
rng = normalizeTableCellSelection(rng);
|
10931
|
+
rng.collapse(true);
|
10932
|
+
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
10933
|
+
}
|
10934
|
+
|
10935
|
+
selection.moveToBookmark({id: id, keep: 1});
|
10936
|
+
|
10937
|
+
return {id: id};
|
10938
|
+
};
|
10939
|
+
|
10940
|
+
/**
|
10941
|
+
* Restores the selection to the specified bookmark.
|
10942
|
+
*
|
10943
|
+
* @method moveToBookmark
|
10944
|
+
* @param {Object} bookmark Bookmark to restore selection from.
|
10945
|
+
* @return {Boolean} true/false if it was successful or not.
|
10946
|
+
* @example
|
10947
|
+
* // Stores a bookmark of the current selection
|
10948
|
+
* var bm = tinymce.activeEditor.selection.getBookmark();
|
10949
|
+
*
|
10950
|
+
* tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
|
10951
|
+
*
|
10952
|
+
* // Restore the selection bookmark
|
10953
|
+
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10954
|
+
*/
|
10955
|
+
this.moveToBookmark = function(bookmark) {
|
10956
|
+
var rng, root, startContainer, endContainer, startOffset, endOffset;
|
10957
|
+
|
10958
|
+
function setEndPoint(start) {
|
10959
|
+
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
10960
|
+
|
10961
|
+
if (point) {
|
10962
|
+
offset = point[0];
|
10963
|
+
|
10964
|
+
// Find container node
|
10965
|
+
for (node = root, i = point.length - 1; i >= 1; i--) {
|
10966
|
+
children = node.childNodes;
|
10967
|
+
|
10968
|
+
if (point[i] > children.length - 1) {
|
10969
|
+
return;
|
10970
|
+
}
|
10971
|
+
|
10972
|
+
node = children[point[i]];
|
10973
|
+
}
|
10974
|
+
|
10975
|
+
// Move text offset to best suitable location
|
10976
|
+
if (node.nodeType === 3) {
|
10977
|
+
offset = Math.min(point[0], node.nodeValue.length);
|
10978
|
+
}
|
10979
|
+
|
10980
|
+
// Move element offset to best suitable location
|
10981
|
+
if (node.nodeType === 1) {
|
10982
|
+
offset = Math.min(point[0], node.childNodes.length);
|
10983
|
+
}
|
10984
|
+
|
10985
|
+
// Set offset within container node
|
10986
|
+
if (start) {
|
10987
|
+
rng.setStart(node, offset);
|
10988
|
+
} else {
|
10989
|
+
rng.setEnd(node, offset);
|
10990
|
+
}
|
10991
|
+
}
|
10992
|
+
|
10993
|
+
return true;
|
10994
|
+
}
|
10995
|
+
|
10996
|
+
function restoreEndPoint(suffix) {
|
10997
|
+
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
10998
|
+
|
10999
|
+
if (marker) {
|
11000
|
+
node = marker.parentNode;
|
11001
|
+
|
11002
|
+
if (suffix == 'start') {
|
11003
|
+
if (!keep) {
|
11004
|
+
idx = dom.nodeIndex(marker);
|
11005
|
+
} else {
|
11006
|
+
node = marker.firstChild;
|
11007
|
+
idx = 1;
|
11008
|
+
}
|
11009
|
+
|
11010
|
+
startContainer = endContainer = node;
|
11011
|
+
startOffset = endOffset = idx;
|
11012
|
+
} else {
|
11013
|
+
if (!keep) {
|
11014
|
+
idx = dom.nodeIndex(marker);
|
11015
|
+
} else {
|
11016
|
+
node = marker.firstChild;
|
11017
|
+
idx = 1;
|
11018
|
+
}
|
11019
|
+
|
11020
|
+
endContainer = node;
|
11021
|
+
endOffset = idx;
|
11022
|
+
}
|
11023
|
+
|
11024
|
+
if (!keep) {
|
11025
|
+
prev = marker.previousSibling;
|
11026
|
+
next = marker.nextSibling;
|
11027
|
+
|
11028
|
+
// Remove all marker text nodes
|
11029
|
+
Tools.each(Tools.grep(marker.childNodes), function(node) {
|
11030
|
+
if (node.nodeType == 3) {
|
11031
|
+
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
11032
|
+
}
|
11033
|
+
});
|
11034
|
+
|
11035
|
+
// Remove marker but keep children if for example contents where inserted into the marker
|
11036
|
+
// Also remove duplicated instances of the marker for example by a
|
11037
|
+
// split operation or by WebKit auto split on paste feature
|
11038
|
+
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
11039
|
+
dom.remove(marker, 1);
|
11040
|
+
}
|
11041
|
+
|
11042
|
+
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
11043
|
+
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
11044
|
+
// isn't worth the effort. Sorry, Opera but it's just a fact
|
11045
|
+
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
|
11046
|
+
idx = prev.nodeValue.length;
|
11047
|
+
prev.appendData(next.nodeValue);
|
11048
|
+
dom.remove(next);
|
11049
|
+
|
11050
|
+
if (suffix == 'start') {
|
11051
|
+
startContainer = endContainer = prev;
|
11052
|
+
startOffset = endOffset = idx;
|
11053
|
+
} else {
|
11054
|
+
endContainer = prev;
|
11055
|
+
endOffset = idx;
|
11056
|
+
}
|
11057
|
+
}
|
11058
|
+
}
|
11059
|
+
}
|
11060
|
+
}
|
11061
|
+
|
11062
|
+
function addBogus(node) {
|
11063
|
+
// Adds a bogus BR element for empty block elements
|
11064
|
+
if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
|
11065
|
+
node.innerHTML = '<br data-mce-bogus="1" />';
|
11066
|
+
}
|
11067
|
+
|
11068
|
+
return node;
|
11069
|
+
}
|
11070
|
+
|
11071
|
+
if (bookmark) {
|
11072
|
+
if (bookmark.start) {
|
11073
|
+
rng = dom.createRng();
|
11074
|
+
root = dom.getRoot();
|
11075
|
+
|
11076
|
+
if (selection.tridentSel) {
|
11077
|
+
return selection.tridentSel.moveToBookmark(bookmark);
|
11078
|
+
}
|
11079
|
+
|
11080
|
+
if (setEndPoint(true) && setEndPoint()) {
|
11081
|
+
selection.setRng(rng);
|
11082
|
+
}
|
11083
|
+
} else if (bookmark.id) {
|
11084
|
+
// Restore start/end points
|
11085
|
+
restoreEndPoint('start');
|
11086
|
+
restoreEndPoint('end');
|
11087
|
+
|
11088
|
+
if (startContainer) {
|
11089
|
+
rng = dom.createRng();
|
11090
|
+
rng.setStart(addBogus(startContainer), startOffset);
|
11091
|
+
rng.setEnd(addBogus(endContainer), endOffset);
|
11092
|
+
selection.setRng(rng);
|
11093
|
+
}
|
11094
|
+
} else if (bookmark.name) {
|
11095
|
+
selection.select(dom.select(bookmark.name)[bookmark.index]);
|
11096
|
+
} else if (bookmark.rng) {
|
11097
|
+
selection.setRng(bookmark.rng);
|
11098
|
+
}
|
11099
|
+
}
|
11100
|
+
};
|
11101
|
+
}
|
11102
|
+
|
11103
|
+
/**
|
11104
|
+
* Returns true/false if the specified node is a bookmark node or not.
|
11105
|
+
*
|
11106
|
+
* @static
|
11107
|
+
* @method isBookmarkNode
|
11108
|
+
* @param {DOMNode} node DOM Node to check if it's a bookmark node or not.
|
11109
|
+
* @return {Boolean} true/false if the node is a bookmark node or not.
|
11110
|
+
*/
|
11111
|
+
BookmarkManager.isBookmarkNode = function(node) {
|
11112
|
+
return node && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
|
11113
|
+
};
|
11114
|
+
|
11115
|
+
return BookmarkManager;
|
11116
|
+
});
|
11117
|
+
|
10549
11118
|
// Included from: js/tinymce/classes/dom/Selection.js
|
10550
11119
|
|
10551
11120
|
/**
|
@@ -10572,11 +11141,12 @@ define("tinymce/dom/Selection", [
|
|
10572
11141
|
"tinymce/dom/TridentSelection",
|
10573
11142
|
"tinymce/dom/ControlSelection",
|
10574
11143
|
"tinymce/dom/RangeUtils",
|
11144
|
+
"tinymce/dom/BookmarkManager",
|
10575
11145
|
"tinymce/Env",
|
10576
11146
|
"tinymce/util/Tools"
|
10577
|
-
], function(TreeWalker, TridentSelection, ControlSelection, RangeUtils, Env, Tools) {
|
10578
|
-
var each = Tools.each,
|
10579
|
-
var isIE = Env.ie
|
11147
|
+
], function(TreeWalker, TridentSelection, ControlSelection, RangeUtils, BookmarkManager, Env, Tools) {
|
11148
|
+
var each = Tools.each, trim = Tools.trim;
|
11149
|
+
var isIE = Env.ie;
|
10580
11150
|
|
10581
11151
|
/**
|
10582
11152
|
* Constructs a new selection instance.
|
@@ -10594,7 +11164,7 @@ define("tinymce/dom/Selection", [
|
|
10594
11164
|
self.win = win;
|
10595
11165
|
self.serializer = serializer;
|
10596
11166
|
self.editor = editor;
|
10597
|
-
|
11167
|
+
self.bookmarkManager = new BookmarkManager(self);
|
10598
11168
|
self.controlSelection = new ControlSelection(self, editor);
|
10599
11169
|
|
10600
11170
|
// No W3C Range support
|
@@ -10894,169 +11464,7 @@ define("tinymce/dom/Selection", [
|
|
10894
11464
|
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
10895
11465
|
*/
|
10896
11466
|
getBookmark: function(type, normalized) {
|
10897
|
-
|
10898
|
-
|
10899
|
-
function findIndex(name, element) {
|
10900
|
-
var index = 0;
|
10901
|
-
|
10902
|
-
each(dom.select(name), function(node, i) {
|
10903
|
-
if (node == element) {
|
10904
|
-
index = i;
|
10905
|
-
}
|
10906
|
-
});
|
10907
|
-
|
10908
|
-
return index;
|
10909
|
-
}
|
10910
|
-
|
10911
|
-
function normalizeTableCellSelection(rng) {
|
10912
|
-
function moveEndPoint(start) {
|
10913
|
-
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
10914
|
-
|
10915
|
-
container = rng[prefix + 'Container'];
|
10916
|
-
offset = rng[prefix + 'Offset'];
|
10917
|
-
|
10918
|
-
if (container.nodeType == 1 && container.nodeName == "TR") {
|
10919
|
-
childNodes = container.childNodes;
|
10920
|
-
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
10921
|
-
if (container) {
|
10922
|
-
offset = start ? 0 : container.childNodes.length;
|
10923
|
-
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
10924
|
-
}
|
10925
|
-
}
|
10926
|
-
}
|
10927
|
-
|
10928
|
-
moveEndPoint(true);
|
10929
|
-
moveEndPoint();
|
10930
|
-
|
10931
|
-
return rng;
|
10932
|
-
}
|
10933
|
-
|
10934
|
-
function getLocation() {
|
10935
|
-
var rng = self.getRng(true), root = dom.getRoot(), bookmark = {};
|
10936
|
-
|
10937
|
-
function getPoint(rng, start) {
|
10938
|
-
var container = rng[start ? 'startContainer' : 'endContainer'],
|
10939
|
-
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
10940
|
-
|
10941
|
-
if (container.nodeType == 3) {
|
10942
|
-
if (normalized) {
|
10943
|
-
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
|
10944
|
-
offset += node.nodeValue.length;
|
10945
|
-
}
|
10946
|
-
}
|
10947
|
-
|
10948
|
-
point.push(offset);
|
10949
|
-
} else {
|
10950
|
-
childNodes = container.childNodes;
|
10951
|
-
|
10952
|
-
if (offset >= childNodes.length && childNodes.length) {
|
10953
|
-
after = 1;
|
10954
|
-
offset = Math.max(0, childNodes.length - 1);
|
10955
|
-
}
|
10956
|
-
|
10957
|
-
point.push(self.dom.nodeIndex(childNodes[offset], normalized) + after);
|
10958
|
-
}
|
10959
|
-
|
10960
|
-
for (; container && container != root; container = container.parentNode) {
|
10961
|
-
point.push(self.dom.nodeIndex(container, normalized));
|
10962
|
-
}
|
10963
|
-
|
10964
|
-
return point;
|
10965
|
-
}
|
10966
|
-
|
10967
|
-
bookmark.start = getPoint(rng, true);
|
10968
|
-
|
10969
|
-
if (!self.isCollapsed()) {
|
10970
|
-
bookmark.end = getPoint(rng);
|
10971
|
-
}
|
10972
|
-
|
10973
|
-
return bookmark;
|
10974
|
-
}
|
10975
|
-
|
10976
|
-
if (type == 2) {
|
10977
|
-
element = self.getNode();
|
10978
|
-
name = element ? element.nodeName : null;
|
10979
|
-
|
10980
|
-
if (name == 'IMG') {
|
10981
|
-
return {name: name, index: findIndex(name, element)};
|
10982
|
-
}
|
10983
|
-
|
10984
|
-
if (self.tridentSel) {
|
10985
|
-
return self.tridentSel.getBookmark(type);
|
10986
|
-
}
|
10987
|
-
|
10988
|
-
return getLocation();
|
10989
|
-
}
|
10990
|
-
|
10991
|
-
// Handle simple range
|
10992
|
-
if (type) {
|
10993
|
-
return {rng: self.getRng()};
|
10994
|
-
}
|
10995
|
-
|
10996
|
-
rng = self.getRng();
|
10997
|
-
id = dom.uniqueId();
|
10998
|
-
collapsed = self.isCollapsed();
|
10999
|
-
styles = 'overflow:hidden;line-height:0px';
|
11000
|
-
|
11001
|
-
// Explorer method
|
11002
|
-
if (rng.duplicate || rng.item) {
|
11003
|
-
// Text selection
|
11004
|
-
if (!rng.item) {
|
11005
|
-
rng2 = rng.duplicate();
|
11006
|
-
|
11007
|
-
try {
|
11008
|
-
// Insert start marker
|
11009
|
-
rng.collapse();
|
11010
|
-
rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');
|
11011
|
-
|
11012
|
-
// Insert end marker
|
11013
|
-
if (!collapsed) {
|
11014
|
-
rng2.collapse(false);
|
11015
|
-
|
11016
|
-
// Detect the empty space after block elements in IE and move the
|
11017
|
-
// end back one character <p></p>] becomes <p>]</p>
|
11018
|
-
rng.moveToElementText(rng2.parentElement());
|
11019
|
-
if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
|
11020
|
-
rng2.move('character', -1);
|
11021
|
-
}
|
11022
|
-
|
11023
|
-
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
11024
|
-
}
|
11025
|
-
} catch (ex) {
|
11026
|
-
// IE might throw unspecified error so lets ignore it
|
11027
|
-
return null;
|
11028
|
-
}
|
11029
|
-
} else {
|
11030
|
-
// Control selection
|
11031
|
-
element = rng.item(0);
|
11032
|
-
name = element.nodeName;
|
11033
|
-
|
11034
|
-
return {name: name, index: findIndex(name, element)};
|
11035
|
-
}
|
11036
|
-
} else {
|
11037
|
-
element = self.getNode();
|
11038
|
-
name = element.nodeName;
|
11039
|
-
if (name == 'IMG') {
|
11040
|
-
return {name: name, index: findIndex(name, element)};
|
11041
|
-
}
|
11042
|
-
|
11043
|
-
// W3C method
|
11044
|
-
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
11045
|
-
|
11046
|
-
// Insert end marker
|
11047
|
-
if (!collapsed) {
|
11048
|
-
rng2.collapse(false);
|
11049
|
-
rng2.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_end', style: styles}, chr));
|
11050
|
-
}
|
11051
|
-
|
11052
|
-
rng = normalizeTableCellSelection(rng);
|
11053
|
-
rng.collapse(true);
|
11054
|
-
rng.insertNode(dom.create('span', {'data-mce-type': "bookmark", id: id + '_start', style: styles}, chr));
|
11055
|
-
}
|
11056
|
-
|
11057
|
-
self.moveToBookmark({id: id, keep: 1});
|
11058
|
-
|
11059
|
-
return {id: id};
|
11467
|
+
return this.bookmarkManager.getBookmark(type, normalized);
|
11060
11468
|
},
|
11061
11469
|
|
11062
11470
|
/**
|
@@ -11075,150 +11483,7 @@ define("tinymce/dom/Selection", [
|
|
11075
11483
|
* tinymce.activeEditor.selection.moveToBookmark(bm);
|
11076
11484
|
*/
|
11077
11485
|
moveToBookmark: function(bookmark) {
|
11078
|
-
|
11079
|
-
|
11080
|
-
function setEndPoint(start) {
|
11081
|
-
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
11082
|
-
|
11083
|
-
if (point) {
|
11084
|
-
offset = point[0];
|
11085
|
-
|
11086
|
-
// Find container node
|
11087
|
-
for (node = root, i = point.length - 1; i >= 1; i--) {
|
11088
|
-
children = node.childNodes;
|
11089
|
-
|
11090
|
-
if (point[i] > children.length - 1) {
|
11091
|
-
return;
|
11092
|
-
}
|
11093
|
-
|
11094
|
-
node = children[point[i]];
|
11095
|
-
}
|
11096
|
-
|
11097
|
-
// Move text offset to best suitable location
|
11098
|
-
if (node.nodeType === 3) {
|
11099
|
-
offset = Math.min(point[0], node.nodeValue.length);
|
11100
|
-
}
|
11101
|
-
|
11102
|
-
// Move element offset to best suitable location
|
11103
|
-
if (node.nodeType === 1) {
|
11104
|
-
offset = Math.min(point[0], node.childNodes.length);
|
11105
|
-
}
|
11106
|
-
|
11107
|
-
// Set offset within container node
|
11108
|
-
if (start) {
|
11109
|
-
rng.setStart(node, offset);
|
11110
|
-
} else {
|
11111
|
-
rng.setEnd(node, offset);
|
11112
|
-
}
|
11113
|
-
}
|
11114
|
-
|
11115
|
-
return true;
|
11116
|
-
}
|
11117
|
-
|
11118
|
-
function restoreEndPoint(suffix) {
|
11119
|
-
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
11120
|
-
|
11121
|
-
if (marker) {
|
11122
|
-
node = marker.parentNode;
|
11123
|
-
|
11124
|
-
if (suffix == 'start') {
|
11125
|
-
if (!keep) {
|
11126
|
-
idx = dom.nodeIndex(marker);
|
11127
|
-
} else {
|
11128
|
-
node = marker.firstChild;
|
11129
|
-
idx = 1;
|
11130
|
-
}
|
11131
|
-
|
11132
|
-
startContainer = endContainer = node;
|
11133
|
-
startOffset = endOffset = idx;
|
11134
|
-
} else {
|
11135
|
-
if (!keep) {
|
11136
|
-
idx = dom.nodeIndex(marker);
|
11137
|
-
} else {
|
11138
|
-
node = marker.firstChild;
|
11139
|
-
idx = 1;
|
11140
|
-
}
|
11141
|
-
|
11142
|
-
endContainer = node;
|
11143
|
-
endOffset = idx;
|
11144
|
-
}
|
11145
|
-
|
11146
|
-
if (!keep) {
|
11147
|
-
prev = marker.previousSibling;
|
11148
|
-
next = marker.nextSibling;
|
11149
|
-
|
11150
|
-
// Remove all marker text nodes
|
11151
|
-
each(grep(marker.childNodes), function(node) {
|
11152
|
-
if (node.nodeType == 3) {
|
11153
|
-
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
11154
|
-
}
|
11155
|
-
});
|
11156
|
-
|
11157
|
-
// Remove marker but keep children if for example contents where inserted into the marker
|
11158
|
-
// Also remove duplicated instances of the marker for example by a
|
11159
|
-
// split operation or by WebKit auto split on paste feature
|
11160
|
-
while ((marker = dom.get(bookmark.id + '_' + suffix))) {
|
11161
|
-
dom.remove(marker, 1);
|
11162
|
-
}
|
11163
|
-
|
11164
|
-
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
11165
|
-
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market
|
11166
|
-
// isn't worth the effort. Sorry, Opera but it's just a fact
|
11167
|
-
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !isOpera) {
|
11168
|
-
idx = prev.nodeValue.length;
|
11169
|
-
prev.appendData(next.nodeValue);
|
11170
|
-
dom.remove(next);
|
11171
|
-
|
11172
|
-
if (suffix == 'start') {
|
11173
|
-
startContainer = endContainer = prev;
|
11174
|
-
startOffset = endOffset = idx;
|
11175
|
-
} else {
|
11176
|
-
endContainer = prev;
|
11177
|
-
endOffset = idx;
|
11178
|
-
}
|
11179
|
-
}
|
11180
|
-
}
|
11181
|
-
}
|
11182
|
-
}
|
11183
|
-
|
11184
|
-
function addBogus(node) {
|
11185
|
-
// Adds a bogus BR element for empty block elements
|
11186
|
-
if (dom.isBlock(node) && !node.innerHTML && !isIE) {
|
11187
|
-
node.innerHTML = '<br data-mce-bogus="1" />';
|
11188
|
-
}
|
11189
|
-
|
11190
|
-
return node;
|
11191
|
-
}
|
11192
|
-
|
11193
|
-
if (bookmark) {
|
11194
|
-
if (bookmark.start) {
|
11195
|
-
rng = dom.createRng();
|
11196
|
-
root = dom.getRoot();
|
11197
|
-
|
11198
|
-
if (self.tridentSel) {
|
11199
|
-
return self.tridentSel.moveToBookmark(bookmark);
|
11200
|
-
}
|
11201
|
-
|
11202
|
-
if (setEndPoint(true) && setEndPoint()) {
|
11203
|
-
self.setRng(rng);
|
11204
|
-
}
|
11205
|
-
} else if (bookmark.id) {
|
11206
|
-
// Restore start/end points
|
11207
|
-
restoreEndPoint('start');
|
11208
|
-
restoreEndPoint('end');
|
11209
|
-
|
11210
|
-
if (startContainer) {
|
11211
|
-
rng = dom.createRng();
|
11212
|
-
rng.setStart(addBogus(startContainer), startOffset);
|
11213
|
-
rng.setEnd(addBogus(endContainer), endOffset);
|
11214
|
-
self.setRng(rng);
|
11215
|
-
}
|
11216
|
-
} else if (bookmark.name) {
|
11217
|
-
self.select(dom.select(bookmark.name)[bookmark.index]);
|
11218
|
-
} else if (bookmark.rng) {
|
11219
|
-
self.setRng(bookmark.rng);
|
11220
|
-
}
|
11221
|
-
}
|
11486
|
+
return this.bookmarkManager.moveToBookmark(bookmark);
|
11222
11487
|
},
|
11223
11488
|
|
11224
11489
|
/**
|
@@ -11808,6 +12073,126 @@ define("tinymce/dom/Selection", [
|
|
11808
12073
|
return Selection;
|
11809
12074
|
});
|
11810
12075
|
|
12076
|
+
// Included from: js/tinymce/classes/dom/ElementUtils.js
|
12077
|
+
|
12078
|
+
/**
|
12079
|
+
* ElementUtils.js
|
12080
|
+
*
|
12081
|
+
* Copyright, Moxiecode Systems AB
|
12082
|
+
* Released under LGPL License.
|
12083
|
+
*
|
12084
|
+
* License: http://www.tinymce.com/license
|
12085
|
+
* Contributing: http://www.tinymce.com/contributing
|
12086
|
+
*/
|
12087
|
+
|
12088
|
+
/**
|
12089
|
+
* Utility class for various element specific functions.
|
12090
|
+
*
|
12091
|
+
* @private
|
12092
|
+
*/
|
12093
|
+
define("tinymce/dom/ElementUtils", [
|
12094
|
+
"tinymce/dom/BookmarkManager",
|
12095
|
+
"tinymce/util/Tools"
|
12096
|
+
], function(BookmarkManager, Tools) {
|
12097
|
+
var each = Tools.each;
|
12098
|
+
|
12099
|
+
function ElementUtils(dom) {
|
12100
|
+
/**
|
12101
|
+
* Compares two nodes and checks if it's attributes and styles matches.
|
12102
|
+
* This doesn't compare classes as items since their order is significant.
|
12103
|
+
*
|
12104
|
+
* @method compare
|
12105
|
+
* @param {Node} node1 First node to compare with.
|
12106
|
+
* @param {Node} node2 Second node to compare with.
|
12107
|
+
* @return {boolean} True/false if the nodes are the same or not.
|
12108
|
+
*/
|
12109
|
+
this.compare = function(node1, node2) {
|
12110
|
+
// Not the same name
|
12111
|
+
if (node1.nodeName != node2.nodeName) {
|
12112
|
+
return false;
|
12113
|
+
}
|
12114
|
+
|
12115
|
+
/**
|
12116
|
+
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
12117
|
+
*
|
12118
|
+
* @private
|
12119
|
+
* @param {Node} node Node to get attributes from.
|
12120
|
+
* @return {Object} Name/value object with attributes and attribute values.
|
12121
|
+
*/
|
12122
|
+
function getAttribs(node) {
|
12123
|
+
var attribs = {};
|
12124
|
+
|
12125
|
+
each(dom.getAttribs(node), function(attr) {
|
12126
|
+
var name = attr.nodeName.toLowerCase();
|
12127
|
+
|
12128
|
+
// Don't compare internal attributes or style
|
12129
|
+
if (name.indexOf('_') !== 0 && name !== 'style' && name !== 'data-mce-style') {
|
12130
|
+
attribs[name] = dom.getAttrib(node, name);
|
12131
|
+
}
|
12132
|
+
});
|
12133
|
+
|
12134
|
+
return attribs;
|
12135
|
+
}
|
12136
|
+
|
12137
|
+
/**
|
12138
|
+
* Compares two objects checks if it's key + value exists in the other one.
|
12139
|
+
*
|
12140
|
+
* @private
|
12141
|
+
* @param {Object} obj1 First object to compare.
|
12142
|
+
* @param {Object} obj2 Second object to compare.
|
12143
|
+
* @return {boolean} True/false if the objects matches or not.
|
12144
|
+
*/
|
12145
|
+
function compareObjects(obj1, obj2) {
|
12146
|
+
var value, name;
|
12147
|
+
|
12148
|
+
for (name in obj1) {
|
12149
|
+
// Obj1 has item obj2 doesn't have
|
12150
|
+
if (obj1.hasOwnProperty(name)) {
|
12151
|
+
value = obj2[name];
|
12152
|
+
|
12153
|
+
// Obj2 doesn't have obj1 item
|
12154
|
+
if (typeof value == "undefined") {
|
12155
|
+
return false;
|
12156
|
+
}
|
12157
|
+
|
12158
|
+
// Obj2 item has a different value
|
12159
|
+
if (obj1[name] != value) {
|
12160
|
+
return false;
|
12161
|
+
}
|
12162
|
+
|
12163
|
+
// Delete similar value
|
12164
|
+
delete obj2[name];
|
12165
|
+
}
|
12166
|
+
}
|
12167
|
+
|
12168
|
+
// Check if obj 2 has something obj 1 doesn't have
|
12169
|
+
for (name in obj2) {
|
12170
|
+
// Obj2 has item obj1 doesn't have
|
12171
|
+
if (obj2.hasOwnProperty(name)) {
|
12172
|
+
return false;
|
12173
|
+
}
|
12174
|
+
}
|
12175
|
+
|
12176
|
+
return true;
|
12177
|
+
}
|
12178
|
+
|
12179
|
+
// Attribs are not the same
|
12180
|
+
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
12181
|
+
return false;
|
12182
|
+
}
|
12183
|
+
|
12184
|
+
// Styles are not the same
|
12185
|
+
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
12186
|
+
return false;
|
12187
|
+
}
|
12188
|
+
|
12189
|
+
return !BookmarkManager.isBookmarkNode(node1) && !BookmarkManager.isBookmarkNode(node2);
|
12190
|
+
};
|
12191
|
+
}
|
12192
|
+
|
12193
|
+
return ElementUtils;
|
12194
|
+
});
|
12195
|
+
|
11811
12196
|
// Included from: js/tinymce/classes/fmt/Preview.js
|
11812
12197
|
|
11813
12198
|
/**
|
@@ -11991,9 +12376,11 @@ define("tinymce/fmt/Preview", [
|
|
11991
12376
|
define("tinymce/Formatter", [
|
11992
12377
|
"tinymce/dom/TreeWalker",
|
11993
12378
|
"tinymce/dom/RangeUtils",
|
12379
|
+
"tinymce/dom/BookmarkManager",
|
12380
|
+
"tinymce/dom/ElementUtils",
|
11994
12381
|
"tinymce/util/Tools",
|
11995
12382
|
"tinymce/fmt/Preview"
|
11996
|
-
], function(TreeWalker, RangeUtils, Tools, Preview) {
|
12383
|
+
], function(TreeWalker, RangeUtils, BookmarkManager, ElementUtils, Tools, Preview) {
|
11997
12384
|
/**
|
11998
12385
|
* Constructs a new formatter instance.
|
11999
12386
|
*
|
@@ -12017,7 +12404,8 @@ define("tinymce/Formatter", [
|
|
12017
12404
|
undef,
|
12018
12405
|
getContentEditable = dom.getContentEditable,
|
12019
12406
|
disableCaretContainer,
|
12020
|
-
markCaretContainersBogus
|
12407
|
+
markCaretContainersBogus,
|
12408
|
+
isBookmarkNode = BookmarkManager.isBookmarkNode;
|
12021
12409
|
|
12022
12410
|
var each = Tools.each,
|
12023
12411
|
grep = Tools.grep,
|
@@ -12042,7 +12430,6 @@ define("tinymce/Formatter", [
|
|
12042
12430
|
|
12043
12431
|
function defaultFormats() {
|
12044
12432
|
register({
|
12045
|
-
|
12046
12433
|
valigntop: [
|
12047
12434
|
{selector: 'td,th', styles: {'verticalAlign': 'top'}}
|
12048
12435
|
],
|
@@ -12333,7 +12720,7 @@ define("tinymce/Formatter", [
|
|
12333
12720
|
|
12334
12721
|
// get the index of the bookmarks
|
12335
12722
|
each(node.childNodes, function(n, index) {
|
12336
|
-
if (
|
12723
|
+
if (isBookmarkNode(n)) {
|
12337
12724
|
if (n.id == bookmark.id + "_start") {
|
12338
12725
|
startIndex = index;
|
12339
12726
|
} else if (n.id == bookmark.id + "_end") {
|
@@ -13903,21 +14290,10 @@ define("tinymce/Formatter", [
|
|
13903
14290
|
|
13904
14291
|
for (node = inc ? node : node[next]; node; node = node[next]) {
|
13905
14292
|
if (node.nodeType == 1 || !isWhiteSpaceNode(node)) {
|
13906
|
-
return node;
|
13907
|
-
}
|
13908
|
-
}
|
13909
|
-
}
|
13910
|
-
}
|
13911
|
-
|
13912
|
-
/**
|
13913
|
-
* Checks if the specified node is a bookmark node or not.
|
13914
|
-
*
|
13915
|
-
* @private
|
13916
|
-
* @param {Node} node Node to check if it's a bookmark node or not.
|
13917
|
-
* @return {Boolean} true/false if the node is a bookmark node.
|
13918
|
-
*/
|
13919
|
-
function isBookmarkNode(node) {
|
13920
|
-
return node && node.nodeType == 1 && node.getAttribute('data-mce-type') == 'bookmark';
|
14293
|
+
return node;
|
14294
|
+
}
|
14295
|
+
}
|
14296
|
+
}
|
13921
14297
|
}
|
13922
14298
|
|
13923
14299
|
/**
|
@@ -13929,99 +14305,7 @@ define("tinymce/Formatter", [
|
|
13929
14305
|
* @return {Node} Next node if we didn't merge and prev node if we did.
|
13930
14306
|
*/
|
13931
14307
|
function mergeSiblings(prev, next) {
|
13932
|
-
var sibling, tmpSibling;
|
13933
|
-
|
13934
|
-
/**
|
13935
|
-
* Compares two nodes and checks if it's attributes and styles matches.
|
13936
|
-
* This doesn't compare classes as items since their order is significant.
|
13937
|
-
*
|
13938
|
-
* @private
|
13939
|
-
* @param {Node} node1 First node to compare with.
|
13940
|
-
* @param {Node} node2 Second node to compare with.
|
13941
|
-
* @return {boolean} True/false if the nodes are the same or not.
|
13942
|
-
*/
|
13943
|
-
function compareElements(node1, node2) {
|
13944
|
-
// Not the same name
|
13945
|
-
if (node1.nodeName != node2.nodeName) {
|
13946
|
-
return FALSE;
|
13947
|
-
}
|
13948
|
-
|
13949
|
-
/**
|
13950
|
-
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
13951
|
-
*
|
13952
|
-
* @private
|
13953
|
-
* @param {Node} node Node to get attributes from.
|
13954
|
-
* @return {Object} Name/value object with attributes and attribute values.
|
13955
|
-
*/
|
13956
|
-
function getAttribs(node) {
|
13957
|
-
var attribs = {};
|
13958
|
-
|
13959
|
-
each(dom.getAttribs(node), function(attr) {
|
13960
|
-
var name = attr.nodeName.toLowerCase();
|
13961
|
-
|
13962
|
-
// Don't compare internal attributes or style
|
13963
|
-
if (name.indexOf('_') !== 0 && name !== 'style' && name !== 'data-mce-style') {
|
13964
|
-
attribs[name] = dom.getAttrib(node, name);
|
13965
|
-
}
|
13966
|
-
});
|
13967
|
-
|
13968
|
-
return attribs;
|
13969
|
-
}
|
13970
|
-
|
13971
|
-
/**
|
13972
|
-
* Compares two objects checks if it's key + value exists in the other one.
|
13973
|
-
*
|
13974
|
-
* @private
|
13975
|
-
* @param {Object} obj1 First object to compare.
|
13976
|
-
* @param {Object} obj2 Second object to compare.
|
13977
|
-
* @return {boolean} True/false if the objects matches or not.
|
13978
|
-
*/
|
13979
|
-
function compareObjects(obj1, obj2) {
|
13980
|
-
var value, name;
|
13981
|
-
|
13982
|
-
for (name in obj1) {
|
13983
|
-
// Obj1 has item obj2 doesn't have
|
13984
|
-
if (obj1.hasOwnProperty(name)) {
|
13985
|
-
value = obj2[name];
|
13986
|
-
|
13987
|
-
// Obj2 doesn't have obj1 item
|
13988
|
-
if (value === undef) {
|
13989
|
-
return FALSE;
|
13990
|
-
}
|
13991
|
-
|
13992
|
-
// Obj2 item has a different value
|
13993
|
-
if (obj1[name] != value) {
|
13994
|
-
return FALSE;
|
13995
|
-
}
|
13996
|
-
|
13997
|
-
// Delete similar value
|
13998
|
-
delete obj2[name];
|
13999
|
-
}
|
14000
|
-
}
|
14001
|
-
|
14002
|
-
// Check if obj 2 has something obj 1 doesn't have
|
14003
|
-
for (name in obj2) {
|
14004
|
-
// Obj2 has item obj1 doesn't have
|
14005
|
-
if (obj2.hasOwnProperty(name)) {
|
14006
|
-
return FALSE;
|
14007
|
-
}
|
14008
|
-
}
|
14009
|
-
|
14010
|
-
return TRUE;
|
14011
|
-
}
|
14012
|
-
|
14013
|
-
// Attribs are not the same
|
14014
|
-
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
14015
|
-
return FALSE;
|
14016
|
-
}
|
14017
|
-
|
14018
|
-
// Styles are not the same
|
14019
|
-
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
14020
|
-
return FALSE;
|
14021
|
-
}
|
14022
|
-
|
14023
|
-
return !isBookmarkNode(node1) && !isBookmarkNode(node2);
|
14024
|
-
}
|
14308
|
+
var sibling, tmpSibling, elementUtils = new ElementUtils(dom);
|
14025
14309
|
|
14026
14310
|
function findElementSibling(node, sibling_name) {
|
14027
14311
|
for (sibling = node; sibling; sibling = sibling[sibling_name]) {
|
@@ -14044,7 +14328,7 @@ define("tinymce/Formatter", [
|
|
14044
14328
|
next = findElementSibling(next, 'nextSibling');
|
14045
14329
|
|
14046
14330
|
// Compare next and previous nodes
|
14047
|
-
if (
|
14331
|
+
if (elementUtils.compare(prev, next)) {
|
14048
14332
|
// Append nodes between
|
14049
14333
|
for (sibling = prev.nextSibling; sibling && sibling != next;) {
|
14050
14334
|
tmpSibling = sibling;
|
@@ -14247,7 +14531,7 @@ define("tinymce/Formatter", [
|
|
14247
14531
|
node = container;
|
14248
14532
|
|
14249
14533
|
if (container.nodeType == 3) {
|
14250
|
-
if (offset != container.nodeValue.length
|
14534
|
+
if (offset != container.nodeValue.length) {
|
14251
14535
|
hasContentAfter = true;
|
14252
14536
|
}
|
14253
14537
|
|
@@ -14829,6 +15113,10 @@ define("tinymce/EnterKey", [
|
|
14829
15113
|
function trimInlineElementsOnLeftSideOfBlock(block) {
|
14830
15114
|
var node = block, firstChilds = [], i;
|
14831
15115
|
|
15116
|
+
if (!node) {
|
15117
|
+
return;
|
15118
|
+
}
|
15119
|
+
|
14832
15120
|
// Find inner most first child ex: <p><i><b>*</b></i></p>
|
14833
15121
|
while ((node = node.firstChild)) {
|
14834
15122
|
if (dom.isBlock(node)) {
|
@@ -14869,6 +15157,10 @@ define("tinymce/EnterKey", [
|
|
14869
15157
|
}
|
14870
15158
|
}
|
14871
15159
|
|
15160
|
+
if (!root) {
|
15161
|
+
return;
|
15162
|
+
}
|
15163
|
+
|
14872
15164
|
// Old IE versions doesn't properly render blocks with br elements in them
|
14873
15165
|
// For example <p><br></p> wont be rendered correctly in a contentEditable area
|
14874
15166
|
// until you remove the br producing <p></p>
|
@@ -14878,16 +15170,23 @@ define("tinymce/EnterKey", [
|
|
14878
15170
|
}
|
14879
15171
|
}
|
14880
15172
|
|
14881
|
-
if (root.nodeName
|
15173
|
+
if (/^(LI|DT|DD)$/.test(root.nodeName)) {
|
14882
15174
|
var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
|
14883
15175
|
|
14884
|
-
if (firstChild && /^(UL|OL)$/.test(firstChild.nodeName)) {
|
15176
|
+
if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
|
14885
15177
|
root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
|
14886
15178
|
}
|
14887
15179
|
}
|
14888
15180
|
|
14889
15181
|
rng = dom.createRng();
|
14890
15182
|
|
15183
|
+
// Normalize whitespace to remove empty text nodes. Fix for: #6904
|
15184
|
+
// Gecko will be able to place the caret in empty text nodes but it won't render propery
|
15185
|
+
// Older IE versions will sometimes crash so for now ignore all IE versions
|
15186
|
+
if (!Env.ie) {
|
15187
|
+
root.normalize();
|
15188
|
+
}
|
15189
|
+
|
14891
15190
|
if (root.hasChildNodes()) {
|
14892
15191
|
walker = new TreeWalker(root, root);
|
14893
15192
|
|
@@ -14951,7 +15250,7 @@ define("tinymce/EnterKey", [
|
|
14951
15250
|
// Creates a new block element by cloning the current one or creating a new one if the name is specified
|
14952
15251
|
// This function will also copy any text formatting from the parent block and add it to the new one
|
14953
15252
|
function createNewBlock(name) {
|
14954
|
-
var node = container, block, clonedNode, caretNode;
|
15253
|
+
var node = container, block, clonedNode, caretNode, textInlineElements = schema.getTextInlineElements();
|
14955
15254
|
|
14956
15255
|
if (name || parentBlockName == "TABLE") {
|
14957
15256
|
block = dom.create(name || newBlockName);
|
@@ -14965,7 +15264,7 @@ define("tinymce/EnterKey", [
|
|
14965
15264
|
// Clone any parent styles
|
14966
15265
|
if (settings.keep_styles !== false) {
|
14967
15266
|
do {
|
14968
|
-
if (
|
15267
|
+
if (textInlineElements[node.nodeName]) {
|
14969
15268
|
// Never clone a caret containers
|
14970
15269
|
if (node.id == '_mce_caret') {
|
14971
15270
|
continue;
|
@@ -15126,7 +15425,7 @@ define("tinymce/EnterKey", [
|
|
15126
15425
|
function getContainerBlock() {
|
15127
15426
|
var containerBlockParent = containerBlock.parentNode;
|
15128
15427
|
|
15129
|
-
if (containerBlockParent.nodeName
|
15428
|
+
if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
|
15130
15429
|
return containerBlockParent;
|
15131
15430
|
}
|
15132
15431
|
|
@@ -15356,8 +15655,8 @@ define("tinymce/EnterKey", [
|
|
15356
15655
|
parentBlockName = containerBlockName;
|
15357
15656
|
}
|
15358
15657
|
|
15359
|
-
// Handle enter in
|
15360
|
-
if (
|
15658
|
+
// Handle enter in list item
|
15659
|
+
if (/^(LI|DT|DD)$/.test(parentBlockName)) {
|
15361
15660
|
if (!newBlockName && shiftKey) {
|
15362
15661
|
insertBr();
|
15363
15662
|
return;
|
@@ -15602,8 +15901,9 @@ define("tinymce/ForceBlocks", [], function() {
|
|
15602
15901
|
define("tinymce/EditorCommands", [
|
15603
15902
|
"tinymce/html/Serializer",
|
15604
15903
|
"tinymce/Env",
|
15605
|
-
"tinymce/util/Tools"
|
15606
|
-
|
15904
|
+
"tinymce/util/Tools",
|
15905
|
+
"tinymce/dom/ElementUtils"
|
15906
|
+
], function(Serializer, Env, Tools, ElementUtils) {
|
15607
15907
|
// Added for compression purposes
|
15608
15908
|
var each = Tools.each, extend = Tools.extend;
|
15609
15909
|
var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode;
|
@@ -15898,7 +16198,8 @@ define("tinymce/EditorCommands", [
|
|
15898
16198
|
|
15899
16199
|
mceInsertContent: function(command, ui, value) {
|
15900
16200
|
var parser, serializer, parentNode, rootNode, fragment, args;
|
15901
|
-
var marker, rng, node, node2, bookmarkHtml;
|
16201
|
+
var marker, rng, node, node2, bookmarkHtml, merge;
|
16202
|
+
var textInlineElements = editor.schema.getTextInlineElements();
|
15902
16203
|
|
15903
16204
|
function trimOrPaddLeftRight(html) {
|
15904
16205
|
var rng, container, offset;
|
@@ -15928,6 +16229,37 @@ define("tinymce/EditorCommands", [
|
|
15928
16229
|
return html;
|
15929
16230
|
}
|
15930
16231
|
|
16232
|
+
function markInlineFormatElements(fragment) {
|
16233
|
+
if (merge) {
|
16234
|
+
for (node = fragment.firstChild; node; node = node.walk(true)) {
|
16235
|
+
if (textInlineElements[node.name]) {
|
16236
|
+
node.attr('data-mce-new', "true");
|
16237
|
+
}
|
16238
|
+
}
|
16239
|
+
}
|
16240
|
+
}
|
16241
|
+
|
16242
|
+
function reduceInlineTextElements() {
|
16243
|
+
if (merge) {
|
16244
|
+
var root = editor.getBody(), elementUtils = new ElementUtils(dom);
|
16245
|
+
|
16246
|
+
each(dom.select('*[data-mce-new]'), function(node) {
|
16247
|
+
node.removeAttribute('data-mce-new');
|
16248
|
+
|
16249
|
+
for (var testNode = node.parentNode; testNode && testNode != root; testNode = testNode.parentNode) {
|
16250
|
+
if (elementUtils.compare(testNode, node)) {
|
16251
|
+
dom.remove(node, true);
|
16252
|
+
}
|
16253
|
+
}
|
16254
|
+
});
|
16255
|
+
}
|
16256
|
+
}
|
16257
|
+
|
16258
|
+
if (typeof(value) != 'string') {
|
16259
|
+
merge = value.merge;
|
16260
|
+
value = value.content;
|
16261
|
+
}
|
16262
|
+
|
15931
16263
|
// Check for whitespace before/after value
|
15932
16264
|
if (/^ | $/.test(value)) {
|
15933
16265
|
value = trimOrPaddLeftRight(value);
|
@@ -15975,6 +16307,8 @@ define("tinymce/EditorCommands", [
|
|
15975
16307
|
var parserArgs = {context: parentNode.nodeName.toLowerCase()};
|
15976
16308
|
fragment = parser.parse(value, parserArgs);
|
15977
16309
|
|
16310
|
+
markInlineFormatElements(fragment);
|
16311
|
+
|
15978
16312
|
// Move the caret to a more suitable location
|
15979
16313
|
node = fragment.lastChild;
|
15980
16314
|
if (node.attr('id') == 'mce_marker') {
|
@@ -16041,6 +16375,8 @@ define("tinymce/EditorCommands", [
|
|
16041
16375
|
}
|
16042
16376
|
}
|
16043
16377
|
|
16378
|
+
reduceInlineTextElements();
|
16379
|
+
|
16044
16380
|
marker = dom.get('mce_marker');
|
16045
16381
|
selection.scrollIntoView(marker);
|
16046
16382
|
|
@@ -16343,11 +16679,9 @@ define("tinymce/util/URI", [
|
|
16343
16679
|
function URI(url, settings) {
|
16344
16680
|
var self = this, baseUri, base_url;
|
16345
16681
|
|
16346
|
-
// Trim whitespace
|
16347
16682
|
url = trim(url);
|
16348
|
-
|
16349
|
-
// Default settings
|
16350
16683
|
settings = self.settings = settings || {};
|
16684
|
+
baseUri = settings.base_uri;
|
16351
16685
|
|
16352
16686
|
// Strange app protocol that isn't http/https or local anchor
|
16353
16687
|
// For example: mailto,skype,tel etc.
|
@@ -16360,7 +16694,7 @@ define("tinymce/util/URI", [
|
|
16360
16694
|
|
16361
16695
|
// Absolute path with no host, fake host and protocol
|
16362
16696
|
if (url.indexOf('/') === 0 && !isProtocolRelative) {
|
16363
|
-
url = (
|
16697
|
+
url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
|
16364
16698
|
}
|
16365
16699
|
|
16366
16700
|
// Relative path http:// or protocol relative //path
|
@@ -16369,7 +16703,8 @@ define("tinymce/util/URI", [
|
|
16369
16703
|
if (settings.base_uri.protocol === "") {
|
16370
16704
|
url = '//mce_host' + self.toAbsPath(base_url, url);
|
16371
16705
|
} else {
|
16372
|
-
url = ((
|
16706
|
+
url = /([^#?]*)([#?]?.*)/.exec(url);
|
16707
|
+
url = ((baseUri && baseUri.protocol) || 'http') + '://mce_host' + self.toAbsPath(base_url, url[1]) + url[2];
|
16373
16708
|
}
|
16374
16709
|
}
|
16375
16710
|
|
@@ -16391,7 +16726,6 @@ define("tinymce/util/URI", [
|
|
16391
16726
|
self[v] = part;
|
16392
16727
|
});
|
16393
16728
|
|
16394
|
-
baseUri = settings.base_uri;
|
16395
16729
|
if (baseUri) {
|
16396
16730
|
if (!self.protocol) {
|
16397
16731
|
self.protocol = baseUri.protocol;
|
@@ -16901,7 +17235,8 @@ define("tinymce/util/EventDispatcher", [
|
|
16901
17235
|
var nativeEvents = Tools.makeMap(
|
16902
17236
|
"focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange " +
|
16903
17237
|
"mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover " +
|
16904
|
-
"draggesture dragdrop drop drag submit"
|
17238
|
+
"draggesture dragdrop drop drag submit " +
|
17239
|
+
"compositionstart compositionend compositionupdate",
|
16905
17240
|
' '
|
16906
17241
|
);
|
16907
17242
|
|
@@ -17958,9 +18293,11 @@ define("tinymce/ui/DomUtils", [
|
|
17958
18293
|
], function(Tools, DOMUtils) {
|
17959
18294
|
"use strict";
|
17960
18295
|
|
18296
|
+
var count = 0;
|
18297
|
+
|
17961
18298
|
return {
|
17962
18299
|
id: function() {
|
17963
|
-
return
|
18300
|
+
return 'mceu_' + (count++);
|
17964
18301
|
},
|
17965
18302
|
|
17966
18303
|
createFragment: function(html) {
|
@@ -21194,9 +21531,117 @@ define("tinymce/ui/FloatPanel", [
|
|
21194
21531
|
], function(Panel, Movable, Resizable, DomUtils) {
|
21195
21532
|
"use strict";
|
21196
21533
|
|
21197
|
-
var documentClickHandler, documentScrollHandler, visiblePanels = [];
|
21534
|
+
var documentClickHandler, documentScrollHandler, windowResizeHandler, visiblePanels = [];
|
21198
21535
|
var zOrder = [], hasModal;
|
21199
21536
|
|
21537
|
+
function bindDocumentClickHandler() {
|
21538
|
+
function isChildOf(ctrl, parent) {
|
21539
|
+
while (ctrl) {
|
21540
|
+
if (ctrl == parent) {
|
21541
|
+
return true;
|
21542
|
+
}
|
21543
|
+
|
21544
|
+
ctrl = ctrl.parent();
|
21545
|
+
}
|
21546
|
+
}
|
21547
|
+
|
21548
|
+
if (!documentClickHandler) {
|
21549
|
+
documentClickHandler = function(e) {
|
21550
|
+
// Gecko fires click event and in the wrong order on Mac so lets normalize
|
21551
|
+
if (e.button == 2) {
|
21552
|
+
return;
|
21553
|
+
}
|
21554
|
+
|
21555
|
+
// Hide any float panel when a click is out side that float panel and the
|
21556
|
+
// float panels direct parent for example a click on a menu button
|
21557
|
+
var i = visiblePanels.length;
|
21558
|
+
while (i--) {
|
21559
|
+
var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
|
21560
|
+
|
21561
|
+
if (panel.settings.autohide) {
|
21562
|
+
if (clickCtrl) {
|
21563
|
+
if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
|
21564
|
+
continue;
|
21565
|
+
}
|
21566
|
+
}
|
21567
|
+
|
21568
|
+
e = panel.fire('autohide', {target: e.target});
|
21569
|
+
if (!e.isDefaultPrevented()) {
|
21570
|
+
panel.hide();
|
21571
|
+
}
|
21572
|
+
}
|
21573
|
+
}
|
21574
|
+
};
|
21575
|
+
|
21576
|
+
DomUtils.on(document, 'click', documentClickHandler);
|
21577
|
+
}
|
21578
|
+
}
|
21579
|
+
|
21580
|
+
function bindDocumentScrollHandler() {
|
21581
|
+
if (!documentScrollHandler) {
|
21582
|
+
documentScrollHandler = function() {
|
21583
|
+
var i;
|
21584
|
+
|
21585
|
+
i = visiblePanels.length;
|
21586
|
+
while (i--) {
|
21587
|
+
repositionPanel(visiblePanels[i]);
|
21588
|
+
}
|
21589
|
+
};
|
21590
|
+
|
21591
|
+
DomUtils.on(window, 'scroll', documentScrollHandler);
|
21592
|
+
}
|
21593
|
+
}
|
21594
|
+
|
21595
|
+
function bindWindowResizeHandler() {
|
21596
|
+
if (!windowResizeHandler) {
|
21597
|
+
windowResizeHandler = function() {
|
21598
|
+
FloatPanel.hideAll();
|
21599
|
+
};
|
21600
|
+
|
21601
|
+
DomUtils.on(window, 'resize', windowResizeHandler);
|
21602
|
+
}
|
21603
|
+
}
|
21604
|
+
|
21605
|
+
/**
|
21606
|
+
* Repositions the panel to the top of page if the panel is outside of the visual viewport. It will
|
21607
|
+
* also reposition all child panels of the current panel.
|
21608
|
+
*/
|
21609
|
+
function repositionPanel(panel) {
|
21610
|
+
var scrollY = DomUtils.getViewPort().y;
|
21611
|
+
|
21612
|
+
function toggleFixedChildPanels(fixed, deltaY) {
|
21613
|
+
var parent;
|
21614
|
+
|
21615
|
+
for (var i = 0; i < visiblePanels.length; i++) {
|
21616
|
+
if (visiblePanels[i] != panel) {
|
21617
|
+
parent = visiblePanels[i].parent();
|
21618
|
+
|
21619
|
+
while (parent && (parent = parent.parent())) {
|
21620
|
+
if (parent == panel) {
|
21621
|
+
visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
|
21622
|
+
}
|
21623
|
+
}
|
21624
|
+
}
|
21625
|
+
}
|
21626
|
+
}
|
21627
|
+
|
21628
|
+
if (panel.settings.autofix) {
|
21629
|
+
if (!panel._fixed) {
|
21630
|
+
panel._autoFixY = panel.layoutRect().y;
|
21631
|
+
|
21632
|
+
if (panel._autoFixY < scrollY) {
|
21633
|
+
panel.fixed(true).layoutRect({y: 0}).repaint();
|
21634
|
+
toggleFixedChildPanels(true, scrollY - panel._autoFixY);
|
21635
|
+
}
|
21636
|
+
} else {
|
21637
|
+
if (panel._autoFixY > scrollY) {
|
21638
|
+
panel.fixed(false).layoutRect({y: panel._autoFixY}).repaint();
|
21639
|
+
toggleFixedChildPanels(false, panel._autoFixY - scrollY);
|
21640
|
+
}
|
21641
|
+
}
|
21642
|
+
}
|
21643
|
+
}
|
21644
|
+
|
21200
21645
|
var FloatPanel = Panel.extend({
|
21201
21646
|
Mixins: [Movable, Resizable],
|
21202
21647
|
|
@@ -21238,56 +21683,6 @@ define("tinymce/ui/FloatPanel", [
|
|
21238
21683
|
FloatPanel.currentZIndex = zIndex;
|
21239
21684
|
}
|
21240
21685
|
|
21241
|
-
function isChildOf(ctrl, parent) {
|
21242
|
-
while (ctrl) {
|
21243
|
-
if (ctrl == parent) {
|
21244
|
-
return true;
|
21245
|
-
}
|
21246
|
-
|
21247
|
-
ctrl = ctrl.parent();
|
21248
|
-
}
|
21249
|
-
}
|
21250
|
-
|
21251
|
-
/**
|
21252
|
-
* Repositions the panel to the top of page if the panel is outside of the visual viewport. It will
|
21253
|
-
* also reposition all child panels of the current panel.
|
21254
|
-
*/
|
21255
|
-
function repositionPanel(panel) {
|
21256
|
-
var scrollY = DomUtils.getViewPort().y;
|
21257
|
-
|
21258
|
-
function toggleFixedChildPanels(fixed, deltaY) {
|
21259
|
-
var parent;
|
21260
|
-
|
21261
|
-
for (var i = 0; i < visiblePanels.length; i++) {
|
21262
|
-
if (visiblePanels[i] != panel) {
|
21263
|
-
parent = visiblePanels[i].parent();
|
21264
|
-
|
21265
|
-
while (parent && (parent = parent.parent())) {
|
21266
|
-
if (parent == panel) {
|
21267
|
-
visiblePanels[i].fixed(fixed).moveBy(0, deltaY).repaint();
|
21268
|
-
}
|
21269
|
-
}
|
21270
|
-
}
|
21271
|
-
}
|
21272
|
-
}
|
21273
|
-
|
21274
|
-
if (panel.settings.autofix) {
|
21275
|
-
if (!panel._fixed) {
|
21276
|
-
panel._autoFixY = panel.layoutRect().y;
|
21277
|
-
|
21278
|
-
if (panel._autoFixY < scrollY) {
|
21279
|
-
panel.fixed(true).layoutRect({y: 0}).repaint();
|
21280
|
-
toggleFixedChildPanels(true, scrollY - panel._autoFixY);
|
21281
|
-
}
|
21282
|
-
} else {
|
21283
|
-
if (panel._autoFixY > scrollY) {
|
21284
|
-
panel.fixed(false).layoutRect({y: panel._autoFixY}).repaint();
|
21285
|
-
toggleFixedChildPanels(false, panel._autoFixY - scrollY);
|
21286
|
-
}
|
21287
|
-
}
|
21288
|
-
}
|
21289
|
-
}
|
21290
|
-
|
21291
21686
|
self._super(settings);
|
21292
21687
|
self._eventsRoot = self;
|
21293
21688
|
|
@@ -21295,48 +21690,13 @@ define("tinymce/ui/FloatPanel", [
|
|
21295
21690
|
|
21296
21691
|
// Hide floatpanes on click out side the root button
|
21297
21692
|
if (settings.autohide) {
|
21298
|
-
|
21299
|
-
|
21300
|
-
// Hide any float panel when a click is out side that float panel and the
|
21301
|
-
// float panels direct parent for example a click on a menu button
|
21302
|
-
var i = visiblePanels.length;
|
21303
|
-
while (i--) {
|
21304
|
-
var panel = visiblePanels[i], clickCtrl = panel.getParentCtrl(e.target);
|
21305
|
-
|
21306
|
-
if (panel.settings.autohide) {
|
21307
|
-
if (clickCtrl) {
|
21308
|
-
if (isChildOf(clickCtrl, panel) || panel.parent() === clickCtrl) {
|
21309
|
-
continue;
|
21310
|
-
}
|
21311
|
-
}
|
21312
|
-
|
21313
|
-
e = panel.fire('autohide', {target: e.target});
|
21314
|
-
if (!e.isDefaultPrevented()) {
|
21315
|
-
panel.hide();
|
21316
|
-
}
|
21317
|
-
}
|
21318
|
-
}
|
21319
|
-
};
|
21320
|
-
|
21321
|
-
DomUtils.on(document, 'click', documentClickHandler);
|
21322
|
-
}
|
21323
|
-
|
21693
|
+
bindDocumentClickHandler();
|
21694
|
+
bindWindowResizeHandler();
|
21324
21695
|
visiblePanels.push(self);
|
21325
21696
|
}
|
21326
21697
|
|
21327
21698
|
if (settings.autofix) {
|
21328
|
-
|
21329
|
-
documentScrollHandler = function() {
|
21330
|
-
var i;
|
21331
|
-
|
21332
|
-
i = visiblePanels.length;
|
21333
|
-
while (i--) {
|
21334
|
-
repositionPanel(visiblePanels[i]);
|
21335
|
-
}
|
21336
|
-
};
|
21337
|
-
|
21338
|
-
DomUtils.on(window, 'scroll', documentScrollHandler);
|
21339
|
-
}
|
21699
|
+
bindDocumentScrollHandler();
|
21340
21700
|
|
21341
21701
|
self.on('move', function() {
|
21342
21702
|
repositionPanel(this);
|
@@ -21452,7 +21812,8 @@ define("tinymce/ui/FloatPanel", [
|
|
21452
21812
|
},
|
21453
21813
|
|
21454
21814
|
/**
|
21455
|
-
*
|
21815
|
+
* Hide all visible float panels with he autohide setting enabled. This is for
|
21816
|
+
* manually hiding floating menus or panels.
|
21456
21817
|
*
|
21457
21818
|
* @method hideAll
|
21458
21819
|
*/
|
@@ -21495,7 +21856,8 @@ define("tinymce/ui/FloatPanel", [
|
|
21495
21856
|
});
|
21496
21857
|
|
21497
21858
|
/**
|
21498
|
-
*
|
21859
|
+
* Hide all visible float panels with he autohide setting enabled. This is for
|
21860
|
+
* manually hiding floating menus or panels.
|
21499
21861
|
*
|
21500
21862
|
* @static
|
21501
21863
|
* @method hideAll
|
@@ -23901,8 +24263,13 @@ define("tinymce/Shortcuts", [
|
|
23901
24263
|
break;
|
23902
24264
|
|
23903
24265
|
default:
|
23904
|
-
|
23905
|
-
|
24266
|
+
// Allow numeric keycodes like ctrl+219 for ctrl+[
|
24267
|
+
if (/^[0-9]{2,}$/.test(value)) {
|
24268
|
+
shortcut.keyCode = parseInt(value, 10);
|
24269
|
+
} else {
|
24270
|
+
shortcut.charCode = value.charCodeAt(0);
|
24271
|
+
shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
|
24272
|
+
}
|
23906
24273
|
}
|
23907
24274
|
});
|
23908
24275
|
|
@@ -24709,7 +25076,14 @@ define("tinymce/Editor", [
|
|
24709
25076
|
// Add internal attribute if we need to we don't on a refresh of the document
|
24710
25077
|
if (!node.attributes.map[internalName]) {
|
24711
25078
|
if (name === "style") {
|
24712
|
-
|
25079
|
+
value = dom.serializeStyle(dom.parseStyle(value), node.name);
|
25080
|
+
|
25081
|
+
if (!value.length) {
|
25082
|
+
value = null;
|
25083
|
+
}
|
25084
|
+
|
25085
|
+
node.attr(internalName, value);
|
25086
|
+
node.attr(name, value);
|
24713
25087
|
} else if (name === "tabindex") {
|
24714
25088
|
node.attr(internalName, value);
|
24715
25089
|
node.attr(name, null);
|
@@ -24726,7 +25100,7 @@ define("tinymce/Editor", [
|
|
24726
25100
|
|
24727
25101
|
while (i--) {
|
24728
25102
|
node = nodes[i];
|
24729
|
-
node.attr('type', 'mce-' + (node.attr('type') || '
|
25103
|
+
node.attr('type', 'mce-' + (node.attr('type') || 'no/type'));
|
24730
25104
|
}
|
24731
25105
|
});
|
24732
25106
|
|
@@ -25340,8 +25714,18 @@ define("tinymce/Editor", [
|
|
25340
25714
|
}
|
25341
25715
|
|
25342
25716
|
// Browser commands
|
25343
|
-
|
25344
|
-
|
25717
|
+
try {
|
25718
|
+
state = self.getDoc().execCommand(cmd, ui, value);
|
25719
|
+
} catch (ex) {
|
25720
|
+
// Ignore old IE errors
|
25721
|
+
}
|
25722
|
+
|
25723
|
+
if (state) {
|
25724
|
+
self.fire('ExecCommand', {command: cmd, ui: ui, value: value});
|
25725
|
+
return true;
|
25726
|
+
}
|
25727
|
+
|
25728
|
+
return false;
|
25345
25729
|
},
|
25346
25730
|
|
25347
25731
|
/**
|
@@ -25363,8 +25747,8 @@ define("tinymce/Editor", [
|
|
25363
25747
|
if ((queryItem = self.queryStateCommands[cmd])) {
|
25364
25748
|
returnVal = queryItem.func.call(queryItem.scope);
|
25365
25749
|
|
25366
|
-
// Fall though on
|
25367
|
-
if (returnVal
|
25750
|
+
// Fall though on non boolean returns
|
25751
|
+
if (returnVal === true || returnVal === false) {
|
25368
25752
|
return returnVal;
|
25369
25753
|
}
|
25370
25754
|
}
|
@@ -25454,8 +25838,6 @@ define("tinymce/Editor", [
|
|
25454
25838
|
var self = this, doc = self.getDoc();
|
25455
25839
|
|
25456
25840
|
if (!self.hidden) {
|
25457
|
-
self.hidden = true;
|
25458
|
-
|
25459
25841
|
// Fixed bug where IE has a blinking cursor left from the editor
|
25460
25842
|
if (ie && doc && !self.inline) {
|
25461
25843
|
doc.execCommand('SelectAll');
|
@@ -25476,6 +25858,7 @@ define("tinymce/Editor", [
|
|
25476
25858
|
DOM.setStyle(self.id, 'display', self.orgDisplay);
|
25477
25859
|
}
|
25478
25860
|
|
25861
|
+
self.hidden = true;
|
25479
25862
|
self.fire('hide');
|
25480
25863
|
}
|
25481
25864
|
},
|
@@ -25739,8 +26122,13 @@ define("tinymce/Editor", [
|
|
25739
26122
|
*
|
25740
26123
|
* @method insertContent
|
25741
26124
|
* @param {String} content Content to insert.
|
26125
|
+
* @param {Object} args Optional args to pass to insert call.
|
25742
26126
|
*/
|
25743
|
-
insertContent: function(content) {
|
26127
|
+
insertContent: function(content, args) {
|
26128
|
+
if (args) {
|
26129
|
+
content = extend({content: content}, args);
|
26130
|
+
}
|
26131
|
+
|
25744
26132
|
this.execCommand('mceInsertContent', false, content);
|
25745
26133
|
},
|
25746
26134
|
|
@@ -26495,7 +26883,7 @@ define("tinymce/EditorManager", [
|
|
26495
26883
|
* @property minorVersion
|
26496
26884
|
* @type String
|
26497
26885
|
*/
|
26498
|
-
minorVersion : '0.
|
26886
|
+
minorVersion : '0.28',
|
26499
26887
|
|
26500
26888
|
/**
|
26501
26889
|
* Release date of TinyMCE build.
|
@@ -26503,7 +26891,7 @@ define("tinymce/EditorManager", [
|
|
26503
26891
|
* @property releaseDate
|
26504
26892
|
* @type String
|
26505
26893
|
*/
|
26506
|
-
releaseDate: '2014-05-
|
26894
|
+
releaseDate: '2014-05-27',
|
26507
26895
|
|
26508
26896
|
/**
|
26509
26897
|
* Collection of editor instances.
|
@@ -26539,9 +26927,16 @@ define("tinymce/EditorManager", [
|
|
26539
26927
|
var self = this, baseURL, documentBaseURL, suffix = "", preInit, src;
|
26540
26928
|
|
26541
26929
|
// Get base URL for the current document
|
26542
|
-
documentBaseURL = document.location.href
|
26543
|
-
|
26544
|
-
|
26930
|
+
documentBaseURL = document.location.href;
|
26931
|
+
|
26932
|
+
// Check if the URL is a document based format like: http://site/dir/file
|
26933
|
+
// leave other formats like applewebdata://... intact
|
26934
|
+
if (/^[^:]+:\/\/[^\/]+\//.test(documentBaseURL)) {
|
26935
|
+
documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
|
26936
|
+
|
26937
|
+
if (!/[\/\\]$/.test(documentBaseURL)) {
|
26938
|
+
documentBaseURL += '/';
|
26939
|
+
}
|
26545
26940
|
}
|
26546
26941
|
|
26547
26942
|
// If tinymce is defined and has a base use that or use the old tinyMCEPreInit
|
@@ -29475,13 +29870,19 @@ define("tinymce/ui/Form", [
|
|
29475
29870
|
* @private
|
29476
29871
|
*/
|
29477
29872
|
recalcLabels: function() {
|
29478
|
-
var self = this, maxLabelWidth = 0, labels = [], i, labelGap;
|
29873
|
+
var self = this, maxLabelWidth = 0, labels = [], i, labelGap, items;
|
29479
29874
|
|
29480
29875
|
if (self.settings.labelGapCalc === false) {
|
29481
29876
|
return;
|
29482
29877
|
}
|
29483
29878
|
|
29484
|
-
self.
|
29879
|
+
if (self.settings.labelGapCalc == "children") {
|
29880
|
+
items = self.find('formitem');
|
29881
|
+
} else {
|
29882
|
+
items = self.items();
|
29883
|
+
}
|
29884
|
+
|
29885
|
+
items.filter('formitem').each(function(item) {
|
29485
29886
|
var labelCtrl = item.items()[0], labelWidth = labelCtrl.getEl().clientWidth;
|
29486
29887
|
|
29487
29888
|
maxLabelWidth = labelWidth > maxLabelWidth ? labelWidth : maxLabelWidth;
|
@@ -29622,8 +30023,9 @@ define("tinymce/ui/FieldSet", [
|
|
29622
30023
|
* @extends tinymce.ui.ComboBox
|
29623
30024
|
*/
|
29624
30025
|
define("tinymce/ui/FilePicker", [
|
29625
|
-
"tinymce/ui/ComboBox"
|
29626
|
-
|
30026
|
+
"tinymce/ui/ComboBox",
|
30027
|
+
"tinymce/util/Tools"
|
30028
|
+
], function(ComboBox, Tools) {
|
29627
30029
|
"use strict";
|
29628
30030
|
|
29629
30031
|
return ComboBox.extend({
|
@@ -29634,12 +30036,17 @@ define("tinymce/ui/FilePicker", [
|
|
29634
30036
|
* @param {Object} settings Name/value object with settings.
|
29635
30037
|
*/
|
29636
30038
|
init: function(settings) {
|
29637
|
-
var self = this, editor = tinymce.activeEditor, fileBrowserCallback;
|
30039
|
+
var self = this, editor = tinymce.activeEditor, fileBrowserCallback, fileBrowserCallbackTypes;
|
29638
30040
|
|
29639
30041
|
settings.spellcheck = false;
|
29640
30042
|
|
30043
|
+
fileBrowserCallbackTypes = editor.settings.file_browser_callback_types;
|
30044
|
+
if (fileBrowserCallbackTypes) {
|
30045
|
+
fileBrowserCallbackTypes = Tools.makeMap(fileBrowserCallbackTypes, /[, ]/);
|
30046
|
+
}
|
30047
|
+
|
29641
30048
|
fileBrowserCallback = editor.settings.file_browser_callback;
|
29642
|
-
if (fileBrowserCallback) {
|
30049
|
+
if (fileBrowserCallback && (!fileBrowserCallbackTypes || fileBrowserCallbackTypes[settings.filetype])) {
|
29643
30050
|
settings.icon = 'browse';
|
29644
30051
|
|
29645
30052
|
settings.onaction = function() {
|
@@ -30155,6 +30562,7 @@ define("tinymce/ui/FormatControls", [
|
|
30155
30562
|
}
|
30156
30563
|
|
30157
30564
|
menuItem.format = formatName;
|
30565
|
+
menuItem.cmd = format.cmd;
|
30158
30566
|
}
|
30159
30567
|
|
30160
30568
|
menu.push(menuItem);
|
@@ -30201,20 +30609,32 @@ define("tinymce/ui/FormatControls", [
|
|
30201
30609
|
},
|
30202
30610
|
|
30203
30611
|
onPostRender: function() {
|
30204
|
-
var self = this
|
30612
|
+
var self = this;
|
30205
30613
|
|
30206
|
-
|
30207
|
-
|
30614
|
+
self.parent().on('show', function() {
|
30615
|
+
var formatName, command;
|
30616
|
+
|
30617
|
+
formatName = self.settings.format;
|
30618
|
+
if (formatName) {
|
30208
30619
|
self.disabled(!editor.formatter.canApply(formatName));
|
30209
30620
|
self.active(editor.formatter.match(formatName));
|
30210
|
-
}
|
30211
|
-
|
30621
|
+
}
|
30622
|
+
|
30623
|
+
command = self.settings.cmd;
|
30624
|
+
if (command) {
|
30625
|
+
self.active(editor.queryCommandState(command));
|
30626
|
+
}
|
30627
|
+
});
|
30212
30628
|
},
|
30213
30629
|
|
30214
30630
|
onclick: function() {
|
30215
30631
|
if (this.settings.format) {
|
30216
30632
|
toggleFormat(this.settings.format);
|
30217
30633
|
}
|
30634
|
+
|
30635
|
+
if (this.settings.cmd) {
|
30636
|
+
editor.execCommand(this.settings.cmd);
|
30637
|
+
}
|
30218
30638
|
}
|
30219
30639
|
}
|
30220
30640
|
};
|
@@ -30309,30 +30729,21 @@ define("tinymce/ui/FormatControls", [
|
|
30309
30729
|
});
|
30310
30730
|
});
|
30311
30731
|
|
30312
|
-
function
|
30313
|
-
return
|
30314
|
-
|
30315
|
-
|
30316
|
-
function hasRedo() {
|
30317
|
-
return editor.undoManager ? editor.undoManager.hasRedo() : false;
|
30318
|
-
}
|
30319
|
-
|
30320
|
-
function toggleUndoState() {
|
30321
|
-
var self = this;
|
30732
|
+
function toggleUndoRedoState(type) {
|
30733
|
+
return function() {
|
30734
|
+
var self = this;
|
30322
30735
|
|
30323
|
-
|
30324
|
-
editor.on('Undo Redo AddUndo TypingUndo', function() {
|
30325
|
-
self.disabled(!hasUndo());
|
30326
|
-
});
|
30327
|
-
}
|
30736
|
+
type = type == 'redo' ? 'hasRedo' : 'hasUndo';
|
30328
30737
|
|
30329
|
-
|
30330
|
-
|
30738
|
+
function checkState() {
|
30739
|
+
return editor.undoManager ? editor.undoManager[type]() : false;
|
30740
|
+
}
|
30331
30741
|
|
30332
|
-
|
30333
|
-
|
30334
|
-
|
30335
|
-
|
30742
|
+
self.disabled(!checkState());
|
30743
|
+
editor.on('Undo Redo AddUndo TypingUndo ClearUndos', function() {
|
30744
|
+
self.disabled(!checkState());
|
30745
|
+
});
|
30746
|
+
};
|
30336
30747
|
}
|
30337
30748
|
|
30338
30749
|
function toggleVisualAidState() {
|
@@ -30347,13 +30758,13 @@ define("tinymce/ui/FormatControls", [
|
|
30347
30758
|
|
30348
30759
|
editor.addButton('undo', {
|
30349
30760
|
tooltip: 'Undo',
|
30350
|
-
onPostRender:
|
30761
|
+
onPostRender: toggleUndoRedoState('undo'),
|
30351
30762
|
cmd: 'undo'
|
30352
30763
|
});
|
30353
30764
|
|
30354
30765
|
editor.addButton('redo', {
|
30355
30766
|
tooltip: 'Redo',
|
30356
|
-
onPostRender:
|
30767
|
+
onPostRender: toggleUndoRedoState('redo'),
|
30357
30768
|
cmd: 'redo'
|
30358
30769
|
});
|
30359
30770
|
|
@@ -30368,7 +30779,7 @@ define("tinymce/ui/FormatControls", [
|
|
30368
30779
|
text: 'Undo',
|
30369
30780
|
icon: 'undo',
|
30370
30781
|
shortcut: 'Ctrl+Z',
|
30371
|
-
onPostRender:
|
30782
|
+
onPostRender: toggleUndoRedoState('undo'),
|
30372
30783
|
cmd: 'undo'
|
30373
30784
|
});
|
30374
30785
|
|
@@ -30376,7 +30787,7 @@ define("tinymce/ui/FormatControls", [
|
|
30376
30787
|
text: 'Redo',
|
30377
30788
|
icon: 'redo',
|
30378
30789
|
shortcut: 'Ctrl+Y',
|
30379
|
-
onPostRender:
|
30790
|
+
onPostRender: toggleUndoRedoState('redo'),
|
30380
30791
|
cmd: 'redo'
|
30381
30792
|
});
|
30382
30793
|
|
@@ -30511,7 +30922,14 @@ define("tinymce/ui/FormatControls", [
|
|
30511
30922
|
var fontsize_formats = editor.settings.fontsize_formats || defaultFontsizeFormats;
|
30512
30923
|
|
30513
30924
|
each(fontsize_formats.split(' '), function(item) {
|
30514
|
-
|
30925
|
+
var text = item, value = item;
|
30926
|
+
// Allow text=value font sizes.
|
30927
|
+
var values = item.split('=');
|
30928
|
+
if (values.length > 1) {
|
30929
|
+
text = values[0];
|
30930
|
+
value = values[1];
|
30931
|
+
}
|
30932
|
+
items.push({text: text, value: value});
|
30515
30933
|
});
|
30516
30934
|
|
30517
30935
|
return {
|
@@ -31353,19 +31771,29 @@ define("tinymce/ui/ListBox", [
|
|
31353
31771
|
* @setting {Array} values Array with values to add to list box.
|
31354
31772
|
*/
|
31355
31773
|
init: function(settings) {
|
31356
|
-
var self = this, values,
|
31774
|
+
var self = this, values, selected, selectedText, lastItemCtrl;
|
31357
31775
|
|
31358
|
-
|
31359
|
-
|
31360
|
-
for (i = 0; i <
|
31361
|
-
selected =
|
31776
|
+
function setSelected(menuValues) {
|
31777
|
+
// Try to find a selected value
|
31778
|
+
for (var i = 0; i < menuValues.length; i++) {
|
31779
|
+
selected = menuValues[i].selected || settings.value === menuValues[i].value;
|
31362
31780
|
|
31363
31781
|
if (selected) {
|
31364
|
-
selectedText = selectedText ||
|
31365
|
-
self._value =
|
31782
|
+
selectedText = selectedText || menuValues[i].text;
|
31783
|
+
self._value = menuValues[i].value;
|
31366
31784
|
break;
|
31367
31785
|
}
|
31786
|
+
|
31787
|
+
// If the value has a submenu, try to find the selected values in that menu
|
31788
|
+
if (menuValues[i].menu) {
|
31789
|
+
setSelected(menuValues[i].menu);
|
31790
|
+
}
|
31368
31791
|
}
|
31792
|
+
}
|
31793
|
+
|
31794
|
+
self._values = values = settings.values;
|
31795
|
+
if (values) {
|
31796
|
+
setSelected(values);
|
31369
31797
|
|
31370
31798
|
// Default with first item
|
31371
31799
|
if (!selected && values.length > 0) {
|
@@ -31406,7 +31834,7 @@ define("tinymce/ui/ListBox", [
|
|
31406
31834
|
* @return {Boolean/tinymce.ui.ListBox} Value or self if it's a set operation.
|
31407
31835
|
*/
|
31408
31836
|
value: function(value) {
|
31409
|
-
var self = this, active, selectedText, menu
|
31837
|
+
var self = this, active, selectedText, menu;
|
31410
31838
|
|
31411
31839
|
function activateByValue(menu, value) {
|
31412
31840
|
menu.items().each(function(ctrl) {
|
@@ -31424,20 +31852,28 @@ define("tinymce/ui/ListBox", [
|
|
31424
31852
|
});
|
31425
31853
|
}
|
31426
31854
|
|
31855
|
+
function setActiveValues(menuValues) {
|
31856
|
+
for (var i = 0; i < menuValues.length; i++) {
|
31857
|
+
active = menuValues[i].value == value;
|
31858
|
+
|
31859
|
+
if (active) {
|
31860
|
+
selectedText = selectedText || menuValues[i].text;
|
31861
|
+
}
|
31862
|
+
|
31863
|
+
menuValues[i].active = active;
|
31864
|
+
|
31865
|
+
if (menuValues[i].menu) {
|
31866
|
+
setActiveValues(menuValues[i].menu);
|
31867
|
+
}
|
31868
|
+
}
|
31869
|
+
}
|
31870
|
+
|
31427
31871
|
if (typeof(value) != "undefined") {
|
31428
31872
|
if (self.menu) {
|
31429
31873
|
activateByValue(self.menu, value);
|
31430
31874
|
} else {
|
31431
31875
|
menu = self.settings.menu;
|
31432
|
-
|
31433
|
-
active = menu[i].value == value;
|
31434
|
-
|
31435
|
-
if (active) {
|
31436
|
-
selectedText = selectedText || menu[i].text;
|
31437
|
-
}
|
31438
|
-
|
31439
|
-
menu[i].active = active;
|
31440
|
-
}
|
31876
|
+
setActiveValues(menu);
|
31441
31877
|
}
|
31442
31878
|
|
31443
31879
|
self.text(selectedText || this.settings.text);
|
@@ -31579,12 +32015,16 @@ define("tinymce/ui/MenuItem", [
|
|
31579
32015
|
|
31580
32016
|
menu = self.menu = Factory.create(menu).parent(self).renderTo();
|
31581
32017
|
menu.reflow();
|
31582
|
-
menu.fire('show');
|
31583
32018
|
menu.on('cancel', function(e) {
|
31584
32019
|
e.stopPropagation();
|
31585
32020
|
self.focus();
|
31586
32021
|
menu.hide();
|
31587
32022
|
});
|
32023
|
+
menu.on('show hide', function(e) {
|
32024
|
+
e.control.items().each(function(ctrl) {
|
32025
|
+
ctrl.active(ctrl.settings.selected);
|
32026
|
+
});
|
32027
|
+
}).fire('show');
|
31588
32028
|
|
31589
32029
|
menu.on('hide', function(e) {
|
31590
32030
|
if (e.control === menu) {
|
@@ -32681,5 +33121,5 @@ define("tinymce/ui/Throbber", [
|
|
32681
33121
|
};
|
32682
33122
|
});
|
32683
33123
|
|
32684
|
-
expose(["tinymce/dom/Sizzle","tinymce/html/Styles","tinymce/dom/EventUtils","tinymce/dom/TreeWalker","tinymce/util/Tools","tinymce/dom/Range","tinymce/html/Entities","tinymce/Env","tinymce/dom/
|
33124
|
+
expose(["tinymce/dom/Sizzle","tinymce/html/Styles","tinymce/dom/EventUtils","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"]);
|
32685
33125
|
})(this);
|