tinymce-rails 4.0.26 → 4.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/assets/source/tinymce/tinymce.jquery.js +1111 -671
- data/app/assets/source/tinymce/tinymce.js +1108 -668
- data/lib/tinymce/rails/configuration.rb +28 -2
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/spellchecker/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/css/visualblocks.css +7 -0
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.ie7.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.jquery.js +10 -10
- data/vendor/assets/javascripts/tinymce/tinymce.js +11 -10
- metadata +2 -2
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);
|