tinymce-rails 4.3.7 → 4.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +1675 -1543
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/themes/modern/theme.js +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.js +11 -11
- 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: 93901d87a045935cc28a6792994235e6128db919
|
4
|
+
data.tar.gz: f5adf4ad22f9bd5fca01a2137d62bc40055e2245
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5add811679fa66c7f4002b391ded25baa216ff442f661cabc0e1364d08160c129d1a2f48be30571b9260b8168213ecac9fb8fb5aba130f186fac9e77a2a93a25
|
7
|
+
data.tar.gz: 917fb5ba654b40f5e641b4bf01113f3ae1902b5b0a2fac8180be40415524a4348009c5f4b27756e4634fe1f8b7fce2c8796e128ff807d264ccc65594a3bc3208
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// 4.3.
|
1
|
+
// 4.3.8 (2016-03-15)
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Compiled inline version. (Library mode)
|
@@ -12121,8 +12121,8 @@ define("tinymce/html/Schema", [
|
|
12121
12121
|
});
|
12122
12122
|
}
|
12123
12123
|
|
12124
|
-
// Add default alt attribute for images
|
12125
|
-
elements.img.attributesDefault = [{name: 'alt', value: ''}];
|
12124
|
+
// Add default alt attribute for images, removed since alt="" is treated as presentational.
|
12125
|
+
// elements.img.attributesDefault = [{name: 'alt', value: ''}];
|
12126
12126
|
|
12127
12127
|
// Remove these if they are empty by default
|
12128
12128
|
each(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function(name) {
|
@@ -15211,6 +15211,7 @@ define("tinymce/dom/ControlSelection", [
|
|
15211
15211
|
rootClass + ' div.mce-resizehandle {' +
|
15212
15212
|
'position: absolute;' +
|
15213
15213
|
'border: 1px solid black;' +
|
15214
|
+
'box-sizing: box-sizing;' +
|
15214
15215
|
'background: #FFF;' +
|
15215
15216
|
'width: 7px;' +
|
15216
15217
|
'height: 7px;' +
|
@@ -18728,12 +18729,26 @@ define("tinymce/Formatter", [
|
|
18728
18729
|
|
18729
18730
|
alignleft: [
|
18730
18731
|
{selector: 'figure.image', collapsed: false, classes: 'align-left', ceFalseOverride: true},
|
18731
|
-
{
|
18732
|
+
{
|
18733
|
+
selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
|
18734
|
+
styles: {
|
18735
|
+
textAlign: 'left'
|
18736
|
+
},
|
18737
|
+
inherit: false,
|
18738
|
+
defaultBlock: 'div'
|
18739
|
+
},
|
18732
18740
|
{selector: 'img,table', collapsed: false, styles: {'float': 'left'}}
|
18733
18741
|
],
|
18734
18742
|
|
18735
18743
|
aligncenter: [
|
18736
|
-
{
|
18744
|
+
{
|
18745
|
+
selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
|
18746
|
+
styles: {
|
18747
|
+
textAlign: 'center'
|
18748
|
+
},
|
18749
|
+
inherit: false,
|
18750
|
+
defaultBlock: 'div'
|
18751
|
+
},
|
18737
18752
|
{selector: 'figure.image', collapsed: false, classes: 'align-center', ceFalseOverride: true},
|
18738
18753
|
{selector: 'img', collapsed: false, styles: {display: 'block', marginLeft: 'auto', marginRight: 'auto'}},
|
18739
18754
|
{selector: 'table', collapsed: false, styles: {marginLeft: 'auto', marginRight: 'auto'}}
|
@@ -18741,12 +18756,26 @@ define("tinymce/Formatter", [
|
|
18741
18756
|
|
18742
18757
|
alignright: [
|
18743
18758
|
{selector: 'figure.image', collapsed: false, classes: 'align-right', ceFalseOverride: true},
|
18744
|
-
{
|
18759
|
+
{
|
18760
|
+
selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
|
18761
|
+
styles: {
|
18762
|
+
textAlign: 'right'
|
18763
|
+
},
|
18764
|
+
inherit: false,
|
18765
|
+
defaultBlock: 'div'
|
18766
|
+
},
|
18745
18767
|
{selector: 'img,table', collapsed: false, styles: {'float': 'right'}}
|
18746
18768
|
],
|
18747
18769
|
|
18748
18770
|
alignjustify: [
|
18749
|
-
{
|
18771
|
+
{
|
18772
|
+
selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
|
18773
|
+
styles: {
|
18774
|
+
textAlign: 'justify'
|
18775
|
+
},
|
18776
|
+
inherit: false,
|
18777
|
+
defaultBlock: 'div'
|
18778
|
+
}
|
18750
18779
|
],
|
18751
18780
|
|
18752
18781
|
bold: [
|
@@ -18911,6 +18940,20 @@ define("tinymce/Formatter", [
|
|
18911
18940
|
return formats;
|
18912
18941
|
}
|
18913
18942
|
|
18943
|
+
function matchesUnInheritedFormatSelector(node, name) {
|
18944
|
+
var formatList = get(name);
|
18945
|
+
|
18946
|
+
if (formatList) {
|
18947
|
+
for (var i = 0; i < formatList.length; i++) {
|
18948
|
+
if (formatList[i].inherit === false && dom.is(node, formatList[i].selector)) {
|
18949
|
+
return true;
|
18950
|
+
}
|
18951
|
+
}
|
18952
|
+
}
|
18953
|
+
|
18954
|
+
return false;
|
18955
|
+
}
|
18956
|
+
|
18914
18957
|
function getTextDecoration(node) {
|
18915
18958
|
var decoration;
|
18916
18959
|
|
@@ -18981,10 +19024,15 @@ define("tinymce/Formatter", [
|
|
18981
19024
|
}
|
18982
19025
|
}
|
18983
19026
|
|
19027
|
+
// This converts: <p>[a</p><p>]b</p> -> <p>[a]</p><p>b</p>
|
18984
19028
|
function adjustSelectionToVisibleSelection() {
|
18985
19029
|
function findSelectionEnd(start, end) {
|
18986
19030
|
var walker = new TreeWalker(end);
|
18987
|
-
for (node = walker.
|
19031
|
+
for (node = walker.prev2(); node; node = walker.prev2()) {
|
19032
|
+
if (node.nodeType == 3 && node.data.length > 0) {
|
19033
|
+
return node;
|
19034
|
+
}
|
19035
|
+
|
18988
19036
|
if (node.childNodes.length > 1 || node == start || node.tagName == 'BR') {
|
18989
19037
|
return node;
|
18990
19038
|
}
|
@@ -18999,7 +19047,7 @@ define("tinymce/Formatter", [
|
|
18999
19047
|
|
19000
19048
|
if (start != end && rng.endOffset === 0) {
|
19001
19049
|
var newEnd = findSelectionEnd(start, end);
|
19002
|
-
var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
|
19050
|
+
var endOffset = newEnd.nodeType == 3 ? newEnd.data.length : newEnd.childNodes.length;
|
19003
19051
|
|
19004
19052
|
rng.setEnd(newEnd, endOffset);
|
19005
19053
|
}
|
@@ -19669,6 +19717,10 @@ define("tinymce/Formatter", [
|
|
19669
19717
|
|
19670
19718
|
// Find first node with similar format settings
|
19671
19719
|
node = dom.getParent(node, function(node) {
|
19720
|
+
if (matchesUnInheritedFormatSelector(node, name)) {
|
19721
|
+
return true;
|
19722
|
+
}
|
19723
|
+
|
19672
19724
|
return node.parentNode === root || !!matchNode(node, name, vars, true);
|
19673
19725
|
});
|
19674
19726
|
|
@@ -19802,6 +19854,10 @@ define("tinymce/Formatter", [
|
|
19802
19854
|
matchedFormats[format] = callbacks;
|
19803
19855
|
return false;
|
19804
19856
|
}
|
19857
|
+
|
19858
|
+
if (matchesUnInheritedFormatSelector(node, format)) {
|
19859
|
+
return false;
|
19860
|
+
}
|
19805
19861
|
});
|
19806
19862
|
});
|
19807
19863
|
|
@@ -22172,10 +22228,10 @@ define("tinymce/ForceBlocks", [], function() {
|
|
22172
22228
|
};
|
22173
22229
|
});
|
22174
22230
|
|
22175
|
-
// Included from: js/tinymce/classes/
|
22231
|
+
// Included from: js/tinymce/classes/caret/CaretUtils.js
|
22176
22232
|
|
22177
22233
|
/**
|
22178
|
-
*
|
22234
|
+
* CaretUtils.js
|
22179
22235
|
*
|
22180
22236
|
* Released under LGPL License.
|
22181
22237
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -22185,371 +22241,897 @@ define("tinymce/ForceBlocks", [], function() {
|
|
22185
22241
|
*/
|
22186
22242
|
|
22187
22243
|
/**
|
22188
|
-
*
|
22189
|
-
* overrides for native browser commands to address various bugs and issues.
|
22244
|
+
* Utility functions shared by the caret logic.
|
22190
22245
|
*
|
22191
|
-
* @
|
22246
|
+
* @private
|
22247
|
+
* @class tinymce.caret.CaretUtils
|
22192
22248
|
*/
|
22193
|
-
define("tinymce/
|
22194
|
-
"tinymce/
|
22195
|
-
"tinymce/
|
22196
|
-
"tinymce/
|
22197
|
-
"tinymce/
|
22198
|
-
"tinymce/
|
22199
|
-
"tinymce/
|
22200
|
-
], function(
|
22201
|
-
|
22202
|
-
|
22203
|
-
|
22204
|
-
|
22205
|
-
|
22206
|
-
|
22207
|
-
|
22208
|
-
var dom, selection, formatter,
|
22209
|
-
commands = {state: {}, exec: {}, value: {}},
|
22210
|
-
settings = editor.settings,
|
22211
|
-
bookmark;
|
22212
|
-
|
22213
|
-
editor.on('PreInit', function() {
|
22214
|
-
dom = editor.dom;
|
22215
|
-
selection = editor.selection;
|
22216
|
-
settings = editor.settings;
|
22217
|
-
formatter = editor.formatter;
|
22218
|
-
});
|
22219
|
-
|
22220
|
-
/**
|
22221
|
-
* Executes the specified command.
|
22222
|
-
*
|
22223
|
-
* @method execCommand
|
22224
|
-
* @param {String} command Command to execute.
|
22225
|
-
* @param {Boolean} ui Optional user interface state.
|
22226
|
-
* @param {Object} value Optional value for command.
|
22227
|
-
* @param {Object} args Optional extra arguments to the execCommand.
|
22228
|
-
* @return {Boolean} true/false if the command was found or not.
|
22229
|
-
*/
|
22230
|
-
function execCommand(command, ui, value, args) {
|
22231
|
-
var func, customCommand, state = 0;
|
22249
|
+
define("tinymce/caret/CaretUtils", [
|
22250
|
+
"tinymce/util/Fun",
|
22251
|
+
"tinymce/dom/TreeWalker",
|
22252
|
+
"tinymce/dom/NodeType",
|
22253
|
+
"tinymce/caret/CaretPosition",
|
22254
|
+
"tinymce/caret/CaretContainer",
|
22255
|
+
"tinymce/caret/CaretCandidate"
|
22256
|
+
], function(Fun, TreeWalker, NodeType, CaretPosition, CaretContainer, CaretCandidate) {
|
22257
|
+
var isContentEditableTrue = NodeType.isContentEditableTrue,
|
22258
|
+
isContentEditableFalse = NodeType.isContentEditableFalse,
|
22259
|
+
isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption'),
|
22260
|
+
isCaretContainer = CaretContainer.isCaretContainer,
|
22261
|
+
curry = Fun.curry,
|
22262
|
+
isElement = NodeType.isElement,
|
22263
|
+
isCaretCandidate = CaretCandidate.isCaretCandidate;
|
22232
22264
|
|
22233
|
-
|
22234
|
-
|
22235
|
-
|
22265
|
+
function isForwards(direction) {
|
22266
|
+
return direction > 0;
|
22267
|
+
}
|
22236
22268
|
|
22237
|
-
|
22238
|
-
|
22239
|
-
|
22240
|
-
}
|
22269
|
+
function isBackwards(direction) {
|
22270
|
+
return direction < 0;
|
22271
|
+
}
|
22241
22272
|
|
22242
|
-
|
22243
|
-
|
22244
|
-
func(customCommand, ui, value);
|
22245
|
-
editor.fire('ExecCommand', {command: command, ui: ui, value: value});
|
22246
|
-
return true;
|
22247
|
-
}
|
22273
|
+
function findNode(node, direction, predicateFn, rootNode, shallow) {
|
22274
|
+
var walker = new TreeWalker(node, rootNode);
|
22248
22275
|
|
22249
|
-
|
22250
|
-
|
22251
|
-
|
22252
|
-
|
22253
|
-
|
22254
|
-
return false;
|
22276
|
+
if (isBackwards(direction)) {
|
22277
|
+
if (isContentEditableFalse(node)) {
|
22278
|
+
node = walker.prev(true);
|
22279
|
+
if (predicateFn(node)) {
|
22280
|
+
return node;
|
22255
22281
|
}
|
22256
|
-
});
|
22257
|
-
|
22258
|
-
if (state) {
|
22259
|
-
return state;
|
22260
22282
|
}
|
22261
22283
|
|
22262
|
-
|
22263
|
-
|
22264
|
-
|
22265
|
-
|
22284
|
+
while ((node = walker.prev(shallow))) {
|
22285
|
+
if (predicateFn(node)) {
|
22286
|
+
return node;
|
22287
|
+
}
|
22266
22288
|
}
|
22289
|
+
}
|
22267
22290
|
|
22268
|
-
|
22269
|
-
|
22270
|
-
|
22271
|
-
|
22272
|
-
|
22291
|
+
if (isForwards(direction)) {
|
22292
|
+
if (isContentEditableFalse(node)) {
|
22293
|
+
node = walker.next(true);
|
22294
|
+
if (predicateFn(node)) {
|
22295
|
+
return node;
|
22296
|
+
}
|
22273
22297
|
}
|
22274
22298
|
|
22275
|
-
|
22276
|
-
|
22277
|
-
|
22299
|
+
while ((node = walker.next(shallow))) {
|
22300
|
+
if (predicateFn(node)) {
|
22301
|
+
return node;
|
22302
|
+
}
|
22278
22303
|
}
|
22279
|
-
|
22280
|
-
return false;
|
22281
22304
|
}
|
22282
22305
|
|
22283
|
-
|
22284
|
-
|
22285
|
-
*
|
22286
|
-
* @method queryCommandState
|
22287
|
-
* @param {String} command Command to check the state of.
|
22288
|
-
* @return {Boolean/Number} true/false if the selected contents is bold or not, -1 if it's not found.
|
22289
|
-
*/
|
22290
|
-
function queryCommandState(command) {
|
22291
|
-
var func;
|
22306
|
+
return null;
|
22307
|
+
}
|
22292
22308
|
|
22293
|
-
|
22294
|
-
|
22295
|
-
|
22309
|
+
function getEditingHost(node, rootNode) {
|
22310
|
+
for (node = node.parentNode; node && node != rootNode; node = node.parentNode) {
|
22311
|
+
if (isContentEditableTrue(node)) {
|
22312
|
+
return node;
|
22296
22313
|
}
|
22314
|
+
}
|
22297
22315
|
|
22298
|
-
|
22299
|
-
|
22300
|
-
return func(command);
|
22301
|
-
}
|
22316
|
+
return rootNode;
|
22317
|
+
}
|
22302
22318
|
|
22303
|
-
|
22304
|
-
|
22305
|
-
|
22306
|
-
|
22307
|
-
// Fails sometimes see bug: 1896577
|
22319
|
+
function getParentBlock(node, rootNode) {
|
22320
|
+
while (node && node != rootNode) {
|
22321
|
+
if (isBlockLike(node)) {
|
22322
|
+
return node;
|
22308
22323
|
}
|
22309
22324
|
|
22310
|
-
|
22325
|
+
node = node.parentNode;
|
22311
22326
|
}
|
22312
22327
|
|
22313
|
-
|
22314
|
-
|
22315
|
-
*
|
22316
|
-
* @method queryCommandValue
|
22317
|
-
* @param {String} command Command to check the value of.
|
22318
|
-
* @return {Object} Command value of false if it's not found.
|
22319
|
-
*/
|
22320
|
-
function queryCommandValue(command) {
|
22321
|
-
var func;
|
22328
|
+
return null;
|
22329
|
+
}
|
22322
22330
|
|
22323
|
-
|
22324
|
-
|
22325
|
-
|
22326
|
-
}
|
22331
|
+
function isInSameBlock(caretPosition1, caretPosition2, rootNode) {
|
22332
|
+
return getParentBlock(caretPosition1.container(), rootNode) == getParentBlock(caretPosition2.container(), rootNode);
|
22333
|
+
}
|
22327
22334
|
|
22328
|
-
|
22329
|
-
|
22330
|
-
|
22331
|
-
}
|
22335
|
+
function isInSameEditingHost(caretPosition1, caretPosition2, rootNode) {
|
22336
|
+
return getEditingHost(caretPosition1.container(), rootNode) == getEditingHost(caretPosition2.container(), rootNode);
|
22337
|
+
}
|
22332
22338
|
|
22333
|
-
|
22334
|
-
|
22335
|
-
|
22336
|
-
|
22337
|
-
|
22338
|
-
}
|
22339
|
+
function getChildNodeAtRelativeOffset(relativeOffset, caretPosition) {
|
22340
|
+
var container, offset;
|
22341
|
+
|
22342
|
+
if (!caretPosition) {
|
22343
|
+
return null;
|
22339
22344
|
}
|
22340
22345
|
|
22341
|
-
|
22342
|
-
|
22343
|
-
*
|
22344
|
-
* @method addCommands
|
22345
|
-
* @param {Object} command_list Name/value collection with commands to add, the names can also be comma separated.
|
22346
|
-
* @param {String} type Optional type to add, defaults to exec. Can be value or state as well.
|
22347
|
-
*/
|
22348
|
-
function addCommands(command_list, type) {
|
22349
|
-
type = type || 'exec';
|
22346
|
+
container = caretPosition.container();
|
22347
|
+
offset = caretPosition.offset();
|
22350
22348
|
|
22351
|
-
|
22352
|
-
|
22353
|
-
commands[type][command] = callback;
|
22354
|
-
});
|
22355
|
-
});
|
22349
|
+
if (!isElement(container)) {
|
22350
|
+
return null;
|
22356
22351
|
}
|
22357
22352
|
|
22358
|
-
|
22359
|
-
|
22360
|
-
commands.exec[command] = function(command, ui, value, args) {
|
22361
|
-
return callback.call(scope || editor, ui, value, args);
|
22362
|
-
};
|
22363
|
-
}
|
22353
|
+
return container.childNodes[offset + relativeOffset];
|
22354
|
+
}
|
22364
22355
|
|
22365
|
-
|
22366
|
-
|
22367
|
-
*
|
22368
|
-
* @method queryCommandSupported
|
22369
|
-
* @param {String} command Command that we check support for.
|
22370
|
-
* @return {Boolean} true/false if the command is supported or not.
|
22371
|
-
*/
|
22372
|
-
function queryCommandSupported(command) {
|
22373
|
-
command = command.toLowerCase();
|
22356
|
+
function beforeAfter(before, node) {
|
22357
|
+
var range = node.ownerDocument.createRange();
|
22374
22358
|
|
22375
|
-
|
22376
|
-
|
22377
|
-
|
22359
|
+
if (before) {
|
22360
|
+
range.setStartBefore(node);
|
22361
|
+
range.setEndBefore(node);
|
22362
|
+
} else {
|
22363
|
+
range.setStartAfter(node);
|
22364
|
+
range.setEndAfter(node);
|
22365
|
+
}
|
22378
22366
|
|
22379
|
-
|
22380
|
-
|
22381
|
-
return editor.getDoc().queryCommandSupported(command);
|
22382
|
-
} catch (ex) {
|
22383
|
-
// Fails sometimes see bug: 1896577
|
22384
|
-
}
|
22367
|
+
return range;
|
22368
|
+
}
|
22385
22369
|
|
22386
|
-
|
22387
|
-
|
22370
|
+
function isNodesInSameBlock(rootNode, node1, node2) {
|
22371
|
+
return getParentBlock(node1, rootNode) == getParentBlock(node2, rootNode);
|
22372
|
+
}
|
22388
22373
|
|
22389
|
-
|
22390
|
-
|
22391
|
-
commands.state[command] = function() {
|
22392
|
-
return callback.call(scope || editor);
|
22393
|
-
};
|
22394
|
-
}
|
22374
|
+
function lean(left, rootNode, node) {
|
22375
|
+
var sibling, siblingName;
|
22395
22376
|
|
22396
|
-
|
22397
|
-
|
22398
|
-
|
22399
|
-
|
22400
|
-
};
|
22377
|
+
if (left) {
|
22378
|
+
siblingName = 'previousSibling';
|
22379
|
+
} else {
|
22380
|
+
siblingName = 'nextSibling';
|
22401
22381
|
}
|
22402
22382
|
|
22403
|
-
|
22404
|
-
|
22405
|
-
return !!commands.exec[command];
|
22406
|
-
}
|
22383
|
+
while (node && node != rootNode) {
|
22384
|
+
sibling = node[siblingName];
|
22407
22385
|
|
22408
|
-
|
22409
|
-
|
22410
|
-
|
22411
|
-
queryCommandState: queryCommandState,
|
22412
|
-
queryCommandValue: queryCommandValue,
|
22413
|
-
queryCommandSupported: queryCommandSupported,
|
22414
|
-
addCommands: addCommands,
|
22415
|
-
addCommand: addCommand,
|
22416
|
-
addQueryStateHandler: addQueryStateHandler,
|
22417
|
-
addQueryValueHandler: addQueryValueHandler,
|
22418
|
-
hasCustomCommand: hasCustomCommand
|
22419
|
-
});
|
22386
|
+
if (isCaretContainer(sibling)) {
|
22387
|
+
sibling = sibling[siblingName];
|
22388
|
+
}
|
22420
22389
|
|
22421
|
-
|
22390
|
+
if (isContentEditableFalse(sibling)) {
|
22391
|
+
if (isNodesInSameBlock(rootNode, sibling, node)) {
|
22392
|
+
return sibling;
|
22393
|
+
}
|
22422
22394
|
|
22423
|
-
|
22424
|
-
if (ui === undefined) {
|
22425
|
-
ui = FALSE;
|
22395
|
+
break;
|
22426
22396
|
}
|
22427
22397
|
|
22428
|
-
if (
|
22429
|
-
|
22398
|
+
if (isCaretCandidate(sibling)) {
|
22399
|
+
break;
|
22430
22400
|
}
|
22431
22401
|
|
22432
|
-
|
22402
|
+
node = node.parentNode;
|
22433
22403
|
}
|
22434
22404
|
|
22435
|
-
|
22436
|
-
|
22437
|
-
}
|
22405
|
+
return null;
|
22406
|
+
}
|
22438
22407
|
|
22439
|
-
|
22440
|
-
|
22441
|
-
editor.nodeChanged();
|
22442
|
-
}
|
22408
|
+
var before = curry(beforeAfter, true);
|
22409
|
+
var after = curry(beforeAfter, false);
|
22443
22410
|
|
22444
|
-
|
22445
|
-
|
22446
|
-
|
22411
|
+
function normalizeRange(direction, rootNode, range) {
|
22412
|
+
var node, container, offset, location;
|
22413
|
+
var leanLeft = curry(lean, true, rootNode);
|
22414
|
+
var leanRight = curry(lean, false, rootNode);
|
22447
22415
|
|
22448
|
-
|
22449
|
-
|
22450
|
-
}
|
22416
|
+
container = range.startContainer;
|
22417
|
+
offset = range.startOffset;
|
22451
22418
|
|
22452
|
-
|
22453
|
-
|
22454
|
-
|
22455
|
-
|
22419
|
+
if (CaretContainer.isCaretContainerBlock(container)) {
|
22420
|
+
if (!isElement(container)) {
|
22421
|
+
container = container.parentNode;
|
22422
|
+
}
|
22456
22423
|
|
22457
|
-
|
22458
|
-
'mceEndUndoLevel,mceAddUndoLevel': function() {
|
22459
|
-
editor.undoManager.add();
|
22460
|
-
},
|
22424
|
+
location = container.getAttribute('data-mce-caret');
|
22461
22425
|
|
22462
|
-
'
|
22463
|
-
|
22426
|
+
if (location == 'before') {
|
22427
|
+
node = container.nextSibling;
|
22428
|
+
if (isContentEditableFalse(node)) {
|
22429
|
+
return before(node);
|
22430
|
+
}
|
22431
|
+
}
|
22464
22432
|
|
22465
|
-
|
22466
|
-
|
22467
|
-
|
22468
|
-
|
22469
|
-
// Command failed
|
22470
|
-
failed = TRUE;
|
22433
|
+
if (location == 'after') {
|
22434
|
+
node = container.previousSibling;
|
22435
|
+
if (isContentEditableFalse(node)) {
|
22436
|
+
return after(node);
|
22471
22437
|
}
|
22438
|
+
}
|
22439
|
+
}
|
22472
22440
|
|
22473
|
-
|
22474
|
-
|
22475
|
-
|
22476
|
-
"Your browser doesn't support direct access to the clipboard. " +
|
22477
|
-
"Please use the Ctrl+X/C/V keyboard shortcuts instead."
|
22478
|
-
);
|
22441
|
+
if (!range.collapsed) {
|
22442
|
+
return range;
|
22443
|
+
}
|
22479
22444
|
|
22480
|
-
|
22481
|
-
|
22445
|
+
if (NodeType.isText(container)) {
|
22446
|
+
if (isCaretContainer(container)) {
|
22447
|
+
if (direction === 1) {
|
22448
|
+
node = leanRight(container);
|
22449
|
+
if (node) {
|
22450
|
+
return before(node);
|
22482
22451
|
}
|
22483
22452
|
|
22484
|
-
|
22453
|
+
node = leanLeft(container);
|
22454
|
+
if (node) {
|
22455
|
+
return after(node);
|
22456
|
+
}
|
22485
22457
|
}
|
22486
|
-
},
|
22487
22458
|
|
22488
|
-
|
22489
|
-
|
22490
|
-
|
22491
|
-
|
22492
|
-
if (elm.tagName == 'A') {
|
22493
|
-
editor.dom.remove(elm, true);
|
22459
|
+
if (direction === -1) {
|
22460
|
+
node = leanLeft(container);
|
22461
|
+
if (node) {
|
22462
|
+
return after(node);
|
22494
22463
|
}
|
22495
22464
|
|
22496
|
-
|
22465
|
+
node = leanRight(container);
|
22466
|
+
if (node) {
|
22467
|
+
return before(node);
|
22468
|
+
}
|
22497
22469
|
}
|
22498
22470
|
|
22499
|
-
|
22500
|
-
}
|
22501
|
-
|
22502
|
-
// Override justify commands to use the text formatter engine
|
22503
|
-
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function(command) {
|
22504
|
-
var align = command.substring(7);
|
22471
|
+
return range;
|
22472
|
+
}
|
22505
22473
|
|
22506
|
-
|
22507
|
-
|
22474
|
+
if (CaretContainer.endsWithCaretContainer(container) && offset >= container.data.length - 1) {
|
22475
|
+
if (direction === 1) {
|
22476
|
+
node = leanRight(container);
|
22477
|
+
if (node) {
|
22478
|
+
return before(node);
|
22479
|
+
}
|
22508
22480
|
}
|
22509
22481
|
|
22510
|
-
|
22511
|
-
|
22512
|
-
if (align != name) {
|
22513
|
-
formatter.remove('align' + name);
|
22514
|
-
}
|
22515
|
-
});
|
22482
|
+
return range;
|
22483
|
+
}
|
22516
22484
|
|
22517
|
-
|
22518
|
-
|
22485
|
+
if (CaretContainer.startsWithCaretContainer(container) && offset <= 1) {
|
22486
|
+
if (direction === -1) {
|
22487
|
+
node = leanLeft(container);
|
22488
|
+
if (node) {
|
22489
|
+
return after(node);
|
22490
|
+
}
|
22519
22491
|
}
|
22520
|
-
},
|
22521
22492
|
|
22522
|
-
|
22523
|
-
|
22524
|
-
var listElm, listParent;
|
22493
|
+
return range;
|
22494
|
+
}
|
22525
22495
|
|
22526
|
-
|
22496
|
+
if (offset === container.data.length) {
|
22497
|
+
node = leanRight(container);
|
22498
|
+
if (node) {
|
22499
|
+
return before(node);
|
22500
|
+
}
|
22527
22501
|
|
22528
|
-
|
22529
|
-
|
22530
|
-
// TODO: Remove this when the list creation logic is removed
|
22531
|
-
listElm = dom.getParent(selection.getNode(), 'ol,ul');
|
22532
|
-
if (listElm) {
|
22533
|
-
listParent = listElm.parentNode;
|
22502
|
+
return range;
|
22503
|
+
}
|
22534
22504
|
|
22535
|
-
|
22536
|
-
|
22537
|
-
|
22538
|
-
|
22539
|
-
restoreSelection();
|
22540
|
-
}
|
22505
|
+
if (offset === 0) {
|
22506
|
+
node = leanLeft(container);
|
22507
|
+
if (node) {
|
22508
|
+
return after(node);
|
22541
22509
|
}
|
22542
|
-
},
|
22543
22510
|
|
22544
|
-
|
22545
|
-
|
22546
|
-
|
22547
|
-
},
|
22511
|
+
return range;
|
22512
|
+
}
|
22513
|
+
}
|
22548
22514
|
|
22549
|
-
|
22550
|
-
|
22551
|
-
|
22552
|
-
|
22515
|
+
return range;
|
22516
|
+
}
|
22517
|
+
|
22518
|
+
function isNextToContentEditableFalse(relativeOffset, caretPosition) {
|
22519
|
+
return isContentEditableFalse(getChildNodeAtRelativeOffset(relativeOffset, caretPosition));
|
22520
|
+
}
|
22521
|
+
|
22522
|
+
return {
|
22523
|
+
isForwards: isForwards,
|
22524
|
+
isBackwards: isBackwards,
|
22525
|
+
findNode: findNode,
|
22526
|
+
getEditingHost: getEditingHost,
|
22527
|
+
getParentBlock: getParentBlock,
|
22528
|
+
isInSameBlock: isInSameBlock,
|
22529
|
+
isInSameEditingHost: isInSameEditingHost,
|
22530
|
+
isBeforeContentEditableFalse: curry(isNextToContentEditableFalse, 0),
|
22531
|
+
isAfterContentEditableFalse: curry(isNextToContentEditableFalse, -1),
|
22532
|
+
normalizeRange: normalizeRange
|
22533
|
+
};
|
22534
|
+
});
|
22535
|
+
|
22536
|
+
// Included from: js/tinymce/classes/caret/CaretWalker.js
|
22537
|
+
|
22538
|
+
/**
|
22539
|
+
* CaretWalker.js
|
22540
|
+
*
|
22541
|
+
* Released under LGPL License.
|
22542
|
+
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
22543
|
+
*
|
22544
|
+
* License: http://www.tinymce.com/license
|
22545
|
+
* Contributing: http://www.tinymce.com/contributing
|
22546
|
+
*/
|
22547
|
+
|
22548
|
+
/**
|
22549
|
+
* This module contains logic for moving around a virtual caret in logical order within a DOM element.
|
22550
|
+
*
|
22551
|
+
* It ignores the most obvious invalid caret locations such as within a script element or within a
|
22552
|
+
* contentEditable=false element but it will return locations that isn't possible to render visually.
|
22553
|
+
*
|
22554
|
+
* @private
|
22555
|
+
* @class tinymce.caret.CaretWalker
|
22556
|
+
* @example
|
22557
|
+
* var caretWalker = new CaretWalker(rootElm);
|
22558
|
+
*
|
22559
|
+
* var prevLogicalCaretPosition = caretWalker.prev(CaretPosition.fromRangeStart(range));
|
22560
|
+
* var nextLogicalCaretPosition = caretWalker.next(CaretPosition.fromRangeEnd(range));
|
22561
|
+
*/
|
22562
|
+
define("tinymce/caret/CaretWalker", [
|
22563
|
+
"tinymce/dom/NodeType",
|
22564
|
+
"tinymce/caret/CaretCandidate",
|
22565
|
+
"tinymce/caret/CaretPosition",
|
22566
|
+
"tinymce/caret/CaretUtils",
|
22567
|
+
"tinymce/util/Arr",
|
22568
|
+
"tinymce/util/Fun"
|
22569
|
+
], function(NodeType, CaretCandidate, CaretPosition, CaretUtils, Arr, Fun) {
|
22570
|
+
var isContentEditableFalse = NodeType.isContentEditableFalse,
|
22571
|
+
isText = NodeType.isText,
|
22572
|
+
isElement = NodeType.isElement,
|
22573
|
+
isForwards = CaretUtils.isForwards,
|
22574
|
+
isBackwards = CaretUtils.isBackwards,
|
22575
|
+
isCaretCandidate = CaretCandidate.isCaretCandidate,
|
22576
|
+
isAtomic = CaretCandidate.isAtomic,
|
22577
|
+
isEditableCaretCandidate = CaretCandidate.isEditableCaretCandidate;
|
22578
|
+
|
22579
|
+
function getParents(node, rootNode) {
|
22580
|
+
var parents = [];
|
22581
|
+
|
22582
|
+
while (node && node != rootNode) {
|
22583
|
+
parents.push(node);
|
22584
|
+
node = node.parentNode;
|
22585
|
+
}
|
22586
|
+
|
22587
|
+
return parents;
|
22588
|
+
}
|
22589
|
+
|
22590
|
+
function nodeAtIndex(container, offset) {
|
22591
|
+
if (container.hasChildNodes() && offset < container.childNodes.length) {
|
22592
|
+
return container.childNodes[offset];
|
22593
|
+
}
|
22594
|
+
|
22595
|
+
return null;
|
22596
|
+
}
|
22597
|
+
|
22598
|
+
function getCaretCandidatePosition(direction, node) {
|
22599
|
+
if (isForwards(direction)) {
|
22600
|
+
if (isCaretCandidate(node.previousSibling) && !isText(node.previousSibling)) {
|
22601
|
+
return CaretPosition.before(node);
|
22602
|
+
}
|
22603
|
+
|
22604
|
+
if (isText(node)) {
|
22605
|
+
return CaretPosition(node, 0);
|
22606
|
+
}
|
22607
|
+
}
|
22608
|
+
|
22609
|
+
if (isBackwards(direction)) {
|
22610
|
+
if (isCaretCandidate(node.nextSibling) && !isText(node.nextSibling)) {
|
22611
|
+
return CaretPosition.after(node);
|
22612
|
+
}
|
22613
|
+
|
22614
|
+
if (isText(node)) {
|
22615
|
+
return CaretPosition(node, node.data.length);
|
22616
|
+
}
|
22617
|
+
}
|
22618
|
+
|
22619
|
+
if (isBackwards(direction)) {
|
22620
|
+
return CaretPosition.after(node);
|
22621
|
+
}
|
22622
|
+
|
22623
|
+
return CaretPosition.before(node);
|
22624
|
+
}
|
22625
|
+
|
22626
|
+
function findCaretPosition(direction, startCaretPosition, rootNode) {
|
22627
|
+
var container, offset, node, nextNode, innerNode,
|
22628
|
+
rootContentEditableFalseElm, caretPosition;
|
22629
|
+
|
22630
|
+
if (!isElement(rootNode) || !startCaretPosition) {
|
22631
|
+
return null;
|
22632
|
+
}
|
22633
|
+
|
22634
|
+
caretPosition = startCaretPosition;
|
22635
|
+
container = caretPosition.container();
|
22636
|
+
offset = caretPosition.offset();
|
22637
|
+
|
22638
|
+
if (isText(container)) {
|
22639
|
+
if (isBackwards(direction) && offset > 0) {
|
22640
|
+
return CaretPosition(container, --offset);
|
22641
|
+
}
|
22642
|
+
|
22643
|
+
if (isForwards(direction) && offset < container.length) {
|
22644
|
+
return CaretPosition(container, ++offset);
|
22645
|
+
}
|
22646
|
+
|
22647
|
+
node = container;
|
22648
|
+
} else {
|
22649
|
+
if (isBackwards(direction) && offset > 0) {
|
22650
|
+
nextNode = nodeAtIndex(container, offset - 1);
|
22651
|
+
if (isCaretCandidate(nextNode)) {
|
22652
|
+
if (!isAtomic(nextNode)) {
|
22653
|
+
innerNode = CaretUtils.findNode(nextNode, direction, isEditableCaretCandidate, nextNode);
|
22654
|
+
if (innerNode) {
|
22655
|
+
if (isText(innerNode)) {
|
22656
|
+
return CaretPosition(innerNode, innerNode.data.length);
|
22657
|
+
}
|
22658
|
+
|
22659
|
+
return CaretPosition.after(innerNode);
|
22660
|
+
}
|
22661
|
+
}
|
22662
|
+
|
22663
|
+
if (isText(nextNode)) {
|
22664
|
+
return CaretPosition(nextNode, nextNode.data.length);
|
22665
|
+
}
|
22666
|
+
|
22667
|
+
return CaretPosition.before(nextNode);
|
22668
|
+
}
|
22669
|
+
}
|
22670
|
+
|
22671
|
+
if (isForwards(direction) && offset < container.childNodes.length) {
|
22672
|
+
nextNode = nodeAtIndex(container, offset);
|
22673
|
+
if (isCaretCandidate(nextNode)) {
|
22674
|
+
if (!isAtomic(nextNode)) {
|
22675
|
+
innerNode = CaretUtils.findNode(nextNode, direction, isEditableCaretCandidate, nextNode);
|
22676
|
+
if (innerNode) {
|
22677
|
+
if (isText(innerNode)) {
|
22678
|
+
return CaretPosition(innerNode, 0);
|
22679
|
+
}
|
22680
|
+
|
22681
|
+
return CaretPosition.before(innerNode);
|
22682
|
+
}
|
22683
|
+
}
|
22684
|
+
|
22685
|
+
if (isText(nextNode)) {
|
22686
|
+
return CaretPosition(nextNode, 0);
|
22687
|
+
}
|
22688
|
+
|
22689
|
+
return CaretPosition.after(nextNode);
|
22690
|
+
}
|
22691
|
+
}
|
22692
|
+
|
22693
|
+
node = caretPosition.getNode();
|
22694
|
+
}
|
22695
|
+
|
22696
|
+
if ((isForwards(direction) && caretPosition.isAtEnd()) || (isBackwards(direction) && caretPosition.isAtStart())) {
|
22697
|
+
node = CaretUtils.findNode(node, direction, Fun.constant(true), rootNode, true);
|
22698
|
+
if (isEditableCaretCandidate(node)) {
|
22699
|
+
return getCaretCandidatePosition(direction, node);
|
22700
|
+
}
|
22701
|
+
}
|
22702
|
+
|
22703
|
+
nextNode = CaretUtils.findNode(node, direction, isEditableCaretCandidate, rootNode);
|
22704
|
+
|
22705
|
+
rootContentEditableFalseElm = Arr.last(Arr.filter(getParents(container, rootNode), isContentEditableFalse));
|
22706
|
+
if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {
|
22707
|
+
if (isForwards(direction)) {
|
22708
|
+
caretPosition = CaretPosition.after(rootContentEditableFalseElm);
|
22709
|
+
} else {
|
22710
|
+
caretPosition = CaretPosition.before(rootContentEditableFalseElm);
|
22711
|
+
}
|
22712
|
+
|
22713
|
+
return caretPosition;
|
22714
|
+
}
|
22715
|
+
|
22716
|
+
if (nextNode) {
|
22717
|
+
return getCaretCandidatePosition(direction, nextNode);
|
22718
|
+
}
|
22719
|
+
|
22720
|
+
return null;
|
22721
|
+
}
|
22722
|
+
|
22723
|
+
return function(rootNode) {
|
22724
|
+
return {
|
22725
|
+
/**
|
22726
|
+
* Returns the next logical caret position from the specificed input
|
22727
|
+
* caretPoisiton or null if there isn't any more positions left for example
|
22728
|
+
* at the end specified root element.
|
22729
|
+
*
|
22730
|
+
* @method next
|
22731
|
+
* @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from.
|
22732
|
+
* @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found.
|
22733
|
+
*/
|
22734
|
+
next: function(caretPosition) {
|
22735
|
+
return findCaretPosition(1, caretPosition, rootNode);
|
22736
|
+
},
|
22737
|
+
|
22738
|
+
/**
|
22739
|
+
* Returns the previous logical caret position from the specificed input
|
22740
|
+
* caretPoisiton or null if there isn't any more positions left for example
|
22741
|
+
* at the end specified root element.
|
22742
|
+
*
|
22743
|
+
* @method prev
|
22744
|
+
* @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from.
|
22745
|
+
* @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found.
|
22746
|
+
*/
|
22747
|
+
prev: function(caretPosition) {
|
22748
|
+
return findCaretPosition(-1, caretPosition, rootNode);
|
22749
|
+
}
|
22750
|
+
};
|
22751
|
+
};
|
22752
|
+
});
|
22753
|
+
|
22754
|
+
// Included from: js/tinymce/classes/EditorCommands.js
|
22755
|
+
|
22756
|
+
/**
|
22757
|
+
* EditorCommands.js
|
22758
|
+
*
|
22759
|
+
* Released under LGPL License.
|
22760
|
+
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
22761
|
+
*
|
22762
|
+
* License: http://www.tinymce.com/license
|
22763
|
+
* Contributing: http://www.tinymce.com/contributing
|
22764
|
+
*/
|
22765
|
+
|
22766
|
+
/**
|
22767
|
+
* This class enables you to add custom editor commands and it contains
|
22768
|
+
* overrides for native browser commands to address various bugs and issues.
|
22769
|
+
*
|
22770
|
+
* @class tinymce.EditorCommands
|
22771
|
+
*/
|
22772
|
+
define("tinymce/EditorCommands", [
|
22773
|
+
"tinymce/html/Serializer",
|
22774
|
+
"tinymce/Env",
|
22775
|
+
"tinymce/util/Tools",
|
22776
|
+
"tinymce/dom/ElementUtils",
|
22777
|
+
"tinymce/dom/RangeUtils",
|
22778
|
+
"tinymce/dom/TreeWalker",
|
22779
|
+
"tinymce/caret/CaretWalker",
|
22780
|
+
"tinymce/caret/CaretPosition",
|
22781
|
+
"tinymce/dom/NodeType"
|
22782
|
+
], function(Serializer, Env, Tools, ElementUtils, RangeUtils, TreeWalker, CaretWalker, CaretPosition, NodeType) {
|
22783
|
+
// Added for compression purposes
|
22784
|
+
var each = Tools.each, extend = Tools.extend;
|
22785
|
+
var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode;
|
22786
|
+
var isIE = Env.ie, isOldIE = Env.ie && Env.ie < 11;
|
22787
|
+
var TRUE = true, FALSE = false, isTableCell = NodeType.matchNodeNames('td th');
|
22788
|
+
|
22789
|
+
return function(editor) {
|
22790
|
+
var dom, selection, formatter,
|
22791
|
+
commands = {state: {}, exec: {}, value: {}},
|
22792
|
+
settings = editor.settings,
|
22793
|
+
bookmark;
|
22794
|
+
|
22795
|
+
editor.on('PreInit', function() {
|
22796
|
+
dom = editor.dom;
|
22797
|
+
selection = editor.selection;
|
22798
|
+
settings = editor.settings;
|
22799
|
+
formatter = editor.formatter;
|
22800
|
+
});
|
22801
|
+
|
22802
|
+
/**
|
22803
|
+
* Executes the specified command.
|
22804
|
+
*
|
22805
|
+
* @method execCommand
|
22806
|
+
* @param {String} command Command to execute.
|
22807
|
+
* @param {Boolean} ui Optional user interface state.
|
22808
|
+
* @param {Object} value Optional value for command.
|
22809
|
+
* @param {Object} args Optional extra arguments to the execCommand.
|
22810
|
+
* @return {Boolean} true/false if the command was found or not.
|
22811
|
+
*/
|
22812
|
+
function execCommand(command, ui, value, args) {
|
22813
|
+
var func, customCommand, state = 0;
|
22814
|
+
|
22815
|
+
if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {
|
22816
|
+
editor.focus();
|
22817
|
+
}
|
22818
|
+
|
22819
|
+
args = editor.fire('BeforeExecCommand', {command: command, ui: ui, value: value});
|
22820
|
+
if (args.isDefaultPrevented()) {
|
22821
|
+
return false;
|
22822
|
+
}
|
22823
|
+
|
22824
|
+
customCommand = command.toLowerCase();
|
22825
|
+
if ((func = commands.exec[customCommand])) {
|
22826
|
+
func(customCommand, ui, value);
|
22827
|
+
editor.fire('ExecCommand', {command: command, ui: ui, value: value});
|
22828
|
+
return true;
|
22829
|
+
}
|
22830
|
+
|
22831
|
+
// Plugin commands
|
22832
|
+
each(editor.plugins, function(p) {
|
22833
|
+
if (p.execCommand && p.execCommand(command, ui, value)) {
|
22834
|
+
editor.fire('ExecCommand', {command: command, ui: ui, value: value});
|
22835
|
+
state = true;
|
22836
|
+
return false;
|
22837
|
+
}
|
22838
|
+
});
|
22839
|
+
|
22840
|
+
if (state) {
|
22841
|
+
return state;
|
22842
|
+
}
|
22843
|
+
|
22844
|
+
// Theme commands
|
22845
|
+
if (editor.theme && editor.theme.execCommand && editor.theme.execCommand(command, ui, value)) {
|
22846
|
+
editor.fire('ExecCommand', {command: command, ui: ui, value: value});
|
22847
|
+
return true;
|
22848
|
+
}
|
22849
|
+
|
22850
|
+
// Browser commands
|
22851
|
+
try {
|
22852
|
+
state = editor.getDoc().execCommand(command, ui, value);
|
22853
|
+
} catch (ex) {
|
22854
|
+
// Ignore old IE errors
|
22855
|
+
}
|
22856
|
+
|
22857
|
+
if (state) {
|
22858
|
+
editor.fire('ExecCommand', {command: command, ui: ui, value: value});
|
22859
|
+
return true;
|
22860
|
+
}
|
22861
|
+
|
22862
|
+
return false;
|
22863
|
+
}
|
22864
|
+
|
22865
|
+
/**
|
22866
|
+
* Queries the current state for a command for example if the current selection is "bold".
|
22867
|
+
*
|
22868
|
+
* @method queryCommandState
|
22869
|
+
* @param {String} command Command to check the state of.
|
22870
|
+
* @return {Boolean/Number} true/false if the selected contents is bold or not, -1 if it's not found.
|
22871
|
+
*/
|
22872
|
+
function queryCommandState(command) {
|
22873
|
+
var func;
|
22874
|
+
|
22875
|
+
// Is hidden then return undefined
|
22876
|
+
if (editor._isHidden()) {
|
22877
|
+
return;
|
22878
|
+
}
|
22879
|
+
|
22880
|
+
command = command.toLowerCase();
|
22881
|
+
if ((func = commands.state[command])) {
|
22882
|
+
return func(command);
|
22883
|
+
}
|
22884
|
+
|
22885
|
+
// Browser commands
|
22886
|
+
try {
|
22887
|
+
return editor.getDoc().queryCommandState(command);
|
22888
|
+
} catch (ex) {
|
22889
|
+
// Fails sometimes see bug: 1896577
|
22890
|
+
}
|
22891
|
+
|
22892
|
+
return false;
|
22893
|
+
}
|
22894
|
+
|
22895
|
+
/**
|
22896
|
+
* Queries the command value for example the current fontsize.
|
22897
|
+
*
|
22898
|
+
* @method queryCommandValue
|
22899
|
+
* @param {String} command Command to check the value of.
|
22900
|
+
* @return {Object} Command value of false if it's not found.
|
22901
|
+
*/
|
22902
|
+
function queryCommandValue(command) {
|
22903
|
+
var func;
|
22904
|
+
|
22905
|
+
// Is hidden then return undefined
|
22906
|
+
if (editor._isHidden()) {
|
22907
|
+
return;
|
22908
|
+
}
|
22909
|
+
|
22910
|
+
command = command.toLowerCase();
|
22911
|
+
if ((func = commands.value[command])) {
|
22912
|
+
return func(command);
|
22913
|
+
}
|
22914
|
+
|
22915
|
+
// Browser commands
|
22916
|
+
try {
|
22917
|
+
return editor.getDoc().queryCommandValue(command);
|
22918
|
+
} catch (ex) {
|
22919
|
+
// Fails sometimes see bug: 1896577
|
22920
|
+
}
|
22921
|
+
}
|
22922
|
+
|
22923
|
+
/**
|
22924
|
+
* Adds commands to the command collection.
|
22925
|
+
*
|
22926
|
+
* @method addCommands
|
22927
|
+
* @param {Object} command_list Name/value collection with commands to add, the names can also be comma separated.
|
22928
|
+
* @param {String} type Optional type to add, defaults to exec. Can be value or state as well.
|
22929
|
+
*/
|
22930
|
+
function addCommands(command_list, type) {
|
22931
|
+
type = type || 'exec';
|
22932
|
+
|
22933
|
+
each(command_list, function(callback, command) {
|
22934
|
+
each(command.toLowerCase().split(','), function(command) {
|
22935
|
+
commands[type][command] = callback;
|
22936
|
+
});
|
22937
|
+
});
|
22938
|
+
}
|
22939
|
+
|
22940
|
+
function addCommand(command, callback, scope) {
|
22941
|
+
command = command.toLowerCase();
|
22942
|
+
commands.exec[command] = function(command, ui, value, args) {
|
22943
|
+
return callback.call(scope || editor, ui, value, args);
|
22944
|
+
};
|
22945
|
+
}
|
22946
|
+
|
22947
|
+
/**
|
22948
|
+
* Returns true/false if the command is supported or not.
|
22949
|
+
*
|
22950
|
+
* @method queryCommandSupported
|
22951
|
+
* @param {String} command Command that we check support for.
|
22952
|
+
* @return {Boolean} true/false if the command is supported or not.
|
22953
|
+
*/
|
22954
|
+
function queryCommandSupported(command) {
|
22955
|
+
command = command.toLowerCase();
|
22956
|
+
|
22957
|
+
if (commands.exec[command]) {
|
22958
|
+
return true;
|
22959
|
+
}
|
22960
|
+
|
22961
|
+
// Browser commands
|
22962
|
+
try {
|
22963
|
+
return editor.getDoc().queryCommandSupported(command);
|
22964
|
+
} catch (ex) {
|
22965
|
+
// Fails sometimes see bug: 1896577
|
22966
|
+
}
|
22967
|
+
|
22968
|
+
return false;
|
22969
|
+
}
|
22970
|
+
|
22971
|
+
function addQueryStateHandler(command, callback, scope) {
|
22972
|
+
command = command.toLowerCase();
|
22973
|
+
commands.state[command] = function() {
|
22974
|
+
return callback.call(scope || editor);
|
22975
|
+
};
|
22976
|
+
}
|
22977
|
+
|
22978
|
+
function addQueryValueHandler(command, callback, scope) {
|
22979
|
+
command = command.toLowerCase();
|
22980
|
+
commands.value[command] = function() {
|
22981
|
+
return callback.call(scope || editor);
|
22982
|
+
};
|
22983
|
+
}
|
22984
|
+
|
22985
|
+
function hasCustomCommand(command) {
|
22986
|
+
command = command.toLowerCase();
|
22987
|
+
return !!commands.exec[command];
|
22988
|
+
}
|
22989
|
+
|
22990
|
+
// Expose public methods
|
22991
|
+
extend(this, {
|
22992
|
+
execCommand: execCommand,
|
22993
|
+
queryCommandState: queryCommandState,
|
22994
|
+
queryCommandValue: queryCommandValue,
|
22995
|
+
queryCommandSupported: queryCommandSupported,
|
22996
|
+
addCommands: addCommands,
|
22997
|
+
addCommand: addCommand,
|
22998
|
+
addQueryStateHandler: addQueryStateHandler,
|
22999
|
+
addQueryValueHandler: addQueryValueHandler,
|
23000
|
+
hasCustomCommand: hasCustomCommand
|
23001
|
+
});
|
23002
|
+
|
23003
|
+
// Private methods
|
23004
|
+
|
23005
|
+
function execNativeCommand(command, ui, value) {
|
23006
|
+
if (ui === undefined) {
|
23007
|
+
ui = FALSE;
|
23008
|
+
}
|
23009
|
+
|
23010
|
+
if (value === undefined) {
|
23011
|
+
value = null;
|
23012
|
+
}
|
23013
|
+
|
23014
|
+
return editor.getDoc().execCommand(command, ui, value);
|
23015
|
+
}
|
23016
|
+
|
23017
|
+
function isFormatMatch(name) {
|
23018
|
+
return formatter.match(name);
|
23019
|
+
}
|
23020
|
+
|
23021
|
+
function toggleFormat(name, value) {
|
23022
|
+
formatter.toggle(name, value ? {value: value} : undefined);
|
23023
|
+
editor.nodeChanged();
|
23024
|
+
}
|
23025
|
+
|
23026
|
+
function storeSelection(type) {
|
23027
|
+
bookmark = selection.getBookmark(type);
|
23028
|
+
}
|
23029
|
+
|
23030
|
+
function restoreSelection() {
|
23031
|
+
selection.moveToBookmark(bookmark);
|
23032
|
+
}
|
23033
|
+
|
23034
|
+
// Add execCommand overrides
|
23035
|
+
addCommands({
|
23036
|
+
// Ignore these, added for compatibility
|
23037
|
+
'mceResetDesignMode,mceBeginUndoLevel': function() {},
|
23038
|
+
|
23039
|
+
// Add undo manager logic
|
23040
|
+
'mceEndUndoLevel,mceAddUndoLevel': function() {
|
23041
|
+
editor.undoManager.add();
|
23042
|
+
},
|
23043
|
+
|
23044
|
+
'Cut,Copy,Paste': function(command) {
|
23045
|
+
var doc = editor.getDoc(), failed;
|
23046
|
+
|
23047
|
+
// Try executing the native command
|
23048
|
+
try {
|
23049
|
+
execNativeCommand(command);
|
23050
|
+
} catch (ex) {
|
23051
|
+
// Command failed
|
23052
|
+
failed = TRUE;
|
23053
|
+
}
|
23054
|
+
|
23055
|
+
// Present alert message about clipboard access not being available
|
23056
|
+
if (failed || !doc.queryCommandSupported(command)) {
|
23057
|
+
var msg = editor.translate(
|
23058
|
+
"Your browser doesn't support direct access to the clipboard. " +
|
23059
|
+
"Please use the Ctrl+X/C/V keyboard shortcuts instead."
|
23060
|
+
);
|
23061
|
+
|
23062
|
+
if (Env.mac) {
|
23063
|
+
msg = msg.replace(/Ctrl\+/g, '\u2318+');
|
23064
|
+
}
|
23065
|
+
|
23066
|
+
editor.notificationManager.open({text: msg, type: 'error'});
|
23067
|
+
}
|
23068
|
+
},
|
23069
|
+
|
23070
|
+
// Override unlink command
|
23071
|
+
unlink: function() {
|
23072
|
+
if (selection.isCollapsed()) {
|
23073
|
+
var elm = selection.getNode();
|
23074
|
+
if (elm.tagName == 'A') {
|
23075
|
+
editor.dom.remove(elm, true);
|
23076
|
+
}
|
23077
|
+
|
23078
|
+
return;
|
23079
|
+
}
|
23080
|
+
|
23081
|
+
formatter.remove("link");
|
23082
|
+
},
|
23083
|
+
|
23084
|
+
// Override justify commands to use the text formatter engine
|
23085
|
+
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function(command) {
|
23086
|
+
var align = command.substring(7);
|
23087
|
+
|
23088
|
+
if (align == 'full') {
|
23089
|
+
align = 'justify';
|
23090
|
+
}
|
23091
|
+
|
23092
|
+
// Remove all other alignments first
|
23093
|
+
each('left,center,right,justify'.split(','), function(name) {
|
23094
|
+
if (align != name) {
|
23095
|
+
formatter.remove('align' + name);
|
23096
|
+
}
|
23097
|
+
});
|
23098
|
+
|
23099
|
+
if (align != 'none') {
|
23100
|
+
toggleFormat('align' + align);
|
23101
|
+
}
|
23102
|
+
},
|
23103
|
+
|
23104
|
+
// Override list commands to fix WebKit bug
|
23105
|
+
'InsertUnorderedList,InsertOrderedList': function(command) {
|
23106
|
+
var listElm, listParent;
|
23107
|
+
|
23108
|
+
execNativeCommand(command);
|
23109
|
+
|
23110
|
+
// WebKit produces lists within block elements so we need to split them
|
23111
|
+
// we will replace the native list creation logic to custom logic later on
|
23112
|
+
// TODO: Remove this when the list creation logic is removed
|
23113
|
+
listElm = dom.getParent(selection.getNode(), 'ol,ul');
|
23114
|
+
if (listElm) {
|
23115
|
+
listParent = listElm.parentNode;
|
23116
|
+
|
23117
|
+
// If list is within a text block then split that block
|
23118
|
+
if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {
|
23119
|
+
storeSelection();
|
23120
|
+
dom.split(listParent, listElm);
|
23121
|
+
restoreSelection();
|
23122
|
+
}
|
23123
|
+
}
|
23124
|
+
},
|
23125
|
+
|
23126
|
+
// Override commands to use the text formatter engine
|
23127
|
+
'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function(command) {
|
23128
|
+
toggleFormat(command);
|
23129
|
+
},
|
23130
|
+
|
23131
|
+
// Override commands to use the text formatter engine
|
23132
|
+
'ForeColor,HiliteColor,FontName': function(command, ui, value) {
|
23133
|
+
toggleFormat(command, value);
|
23134
|
+
},
|
22553
23135
|
|
22554
23136
|
FontSize: function(command, ui, value) {
|
22555
23137
|
var fontClasses, fontSizes;
|
@@ -22704,7 +23286,7 @@ define("tinymce/EditorCommands", [
|
|
22704
23286
|
}
|
22705
23287
|
|
22706
23288
|
function moveSelectionToMarker(marker) {
|
22707
|
-
var parentEditableFalseElm;
|
23289
|
+
var parentEditableFalseElm, parentNode, nextRng;
|
22708
23290
|
|
22709
23291
|
function getContentEditableFalseParent(node) {
|
22710
23292
|
var root = editor.getBody();
|
@@ -22754,8 +23336,34 @@ define("tinymce/EditorCommands", [
|
|
22754
23336
|
rng.setEndBefore(marker);
|
22755
23337
|
}
|
22756
23338
|
|
23339
|
+
function findNextCaretRng(rng) {
|
23340
|
+
var caretPos = CaretPosition.fromRangeStart(rng);
|
23341
|
+
var caretWalker = new CaretWalker(editor.getBody());
|
23342
|
+
|
23343
|
+
caretPos = caretWalker.next(caretPos);
|
23344
|
+
if (caretPos) {
|
23345
|
+
return caretPos.toRange();
|
23346
|
+
}
|
23347
|
+
}
|
23348
|
+
|
22757
23349
|
// Remove the marker node and set the new range
|
23350
|
+
parentNode = marker.parentNode;
|
22758
23351
|
dom.remove(marker);
|
23352
|
+
|
23353
|
+
if (dom.isEmpty(parentNode) && dom.isBlock(parentNode)) {
|
23354
|
+
editor.$(parentNode).empty();
|
23355
|
+
|
23356
|
+
rng.setStart(parentNode, 0);
|
23357
|
+
rng.setEnd(parentNode, 0);
|
23358
|
+
|
23359
|
+
if (!isTableCell(parentNode) && (nextRng = findNextCaretRng(rng))) {
|
23360
|
+
rng = nextRng;
|
23361
|
+
dom.remove(parentNode);
|
23362
|
+
} else {
|
23363
|
+
dom.add(parentNode, dom.create('br', {'data-mce-bogus': '1'}));
|
23364
|
+
}
|
23365
|
+
}
|
23366
|
+
|
22759
23367
|
selection.setRng(rng);
|
22760
23368
|
}
|
22761
23369
|
|
@@ -29518,6 +30126,7 @@ define("tinymce/ui/Window", [
|
|
29518
30126
|
|
29519
30127
|
setTimeout(function() {
|
29520
30128
|
self.classes.add('in');
|
30129
|
+
self.fire('open');
|
29521
30130
|
}, 0);
|
29522
30131
|
|
29523
30132
|
self._super();
|
@@ -32626,499 +33235,71 @@ define("tinymce/EditorObservable", [
|
|
32626
33235
|
},
|
32627
33236
|
|
32628
33237
|
/**
|
32629
|
-
* Toggles a native event on/off this is called by the EventDispatcher when
|
32630
|
-
* the first native event handler is added and when the last native event handler is removed.
|
32631
|
-
*
|
32632
|
-
* @private
|
32633
|
-
*/
|
32634
|
-
toggleNativeEvent: function(name, state) {
|
32635
|
-
var self = this;
|
32636
|
-
|
32637
|
-
// Never bind focus/blur since the FocusManager fakes those
|
32638
|
-
if (name == "focus" || name == "blur") {
|
32639
|
-
return;
|
32640
|
-
}
|
32641
|
-
|
32642
|
-
if (state) {
|
32643
|
-
if (self.initialized) {
|
32644
|
-
bindEventDelegate(self, name);
|
32645
|
-
} else {
|
32646
|
-
if (!self._pendingNativeEvents) {
|
32647
|
-
self._pendingNativeEvents = [name];
|
32648
|
-
} else {
|
32649
|
-
self._pendingNativeEvents.push(name);
|
32650
|
-
}
|
32651
|
-
}
|
32652
|
-
} else if (self.initialized) {
|
32653
|
-
self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
|
32654
|
-
delete self.delegates[name];
|
32655
|
-
}
|
32656
|
-
},
|
32657
|
-
|
32658
|
-
/**
|
32659
|
-
* Unbinds all native event handlers that means delegates, custom events bound using the Events API etc.
|
32660
|
-
*
|
32661
|
-
* @private
|
32662
|
-
*/
|
32663
|
-
unbindAllNativeEvents: function() {
|
32664
|
-
var self = this, name;
|
32665
|
-
|
32666
|
-
if (self.delegates) {
|
32667
|
-
for (name in self.delegates) {
|
32668
|
-
self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
|
32669
|
-
}
|
32670
|
-
|
32671
|
-
delete self.delegates;
|
32672
|
-
}
|
32673
|
-
|
32674
|
-
if (!self.inline) {
|
32675
|
-
self.getBody().onload = null;
|
32676
|
-
self.dom.unbind(self.getWin());
|
32677
|
-
self.dom.unbind(self.getDoc());
|
32678
|
-
}
|
32679
|
-
|
32680
|
-
self.dom.unbind(self.getBody());
|
32681
|
-
self.dom.unbind(self.getContainer());
|
32682
|
-
}
|
32683
|
-
};
|
32684
|
-
|
32685
|
-
EditorObservable = Tools.extend({}, Observable, EditorObservable);
|
32686
|
-
|
32687
|
-
return EditorObservable;
|
32688
|
-
});
|
32689
|
-
|
32690
|
-
// Included from: js/tinymce/classes/Mode.js
|
32691
|
-
|
32692
|
-
/**
|
32693
|
-
* Mode.js
|
32694
|
-
*
|
32695
|
-
* Released under LGPL License.
|
32696
|
-
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
32697
|
-
*
|
32698
|
-
* License: http://www.tinymce.com/license
|
32699
|
-
* Contributing: http://www.tinymce.com/contributing
|
32700
|
-
*/
|
32701
|
-
|
32702
|
-
/**
|
32703
|
-
* Mode switcher logic.
|
32704
|
-
*
|
32705
|
-
* @private
|
32706
|
-
* @class tinymce.Mode
|
32707
|
-
*/
|
32708
|
-
define("tinymce/Mode", [], function() {
|
32709
|
-
function setEditorCommandState(editor, cmd, state) {
|
32710
|
-
try {
|
32711
|
-
editor.getDoc().execCommand(cmd, false, state);
|
32712
|
-
} catch (ex) {
|
32713
|
-
// Ignore
|
32714
|
-
}
|
32715
|
-
}
|
32716
|
-
|
32717
|
-
function setMode(editor, mode) {
|
32718
|
-
var currentMode = editor.readonly ? 'readonly' : 'design';
|
32719
|
-
|
32720
|
-
if (mode == currentMode) {
|
32721
|
-
return;
|
32722
|
-
}
|
32723
|
-
|
32724
|
-
if (mode == 'readonly') {
|
32725
|
-
editor.selection.controlSelection.hideResizeRect();
|
32726
|
-
editor.readonly = true;
|
32727
|
-
editor.getBody().contentEditable = false;
|
32728
|
-
} else {
|
32729
|
-
editor.readonly = false;
|
32730
|
-
editor.getBody().contentEditable = true;
|
32731
|
-
setEditorCommandState(editor, "StyleWithCSS", false);
|
32732
|
-
setEditorCommandState(editor, "enableInlineTableEditing", false);
|
32733
|
-
setEditorCommandState(editor, "enableObjectResizing", false);
|
32734
|
-
editor.focus();
|
32735
|
-
editor.nodeChanged();
|
32736
|
-
}
|
32737
|
-
|
32738
|
-
// Event is NOT preventable
|
32739
|
-
editor.fire('SwitchMode', {mode: mode});
|
32740
|
-
}
|
32741
|
-
|
32742
|
-
return {
|
32743
|
-
setMode: setMode
|
32744
|
-
};
|
32745
|
-
});
|
32746
|
-
|
32747
|
-
// Included from: js/tinymce/classes/Shortcuts.js
|
32748
|
-
|
32749
|
-
/**
|
32750
|
-
* Shortcuts.js
|
32751
|
-
*
|
32752
|
-
* Released under LGPL License.
|
32753
|
-
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
32754
|
-
*
|
32755
|
-
* License: http://www.tinymce.com/license
|
32756
|
-
* Contributing: http://www.tinymce.com/contributing
|
32757
|
-
*/
|
32758
|
-
|
32759
|
-
/**
|
32760
|
-
* Contains all logic for handling of keyboard shortcuts.
|
32761
|
-
*
|
32762
|
-
* @class tinymce.Shortcuts
|
32763
|
-
* @example
|
32764
|
-
* editor.shortcuts.add('ctrl+a', function() {});
|
32765
|
-
* editor.shortcuts.add('meta+a', function() {}); // "meta" maps to Command on Mac and Ctrl on PC
|
32766
|
-
* editor.shortcuts.add('ctrl+alt+a', function() {});
|
32767
|
-
* editor.shortcuts.add('access+a', function() {}); // "access" maps to ctrl+alt on Mac and shift+alt on PC
|
32768
|
-
*/
|
32769
|
-
define("tinymce/Shortcuts", [
|
32770
|
-
"tinymce/util/Tools",
|
32771
|
-
"tinymce/Env"
|
32772
|
-
], function(Tools, Env) {
|
32773
|
-
var each = Tools.each, explode = Tools.explode;
|
32774
|
-
|
32775
|
-
var keyCodeLookup = {
|
32776
|
-
"f9": 120,
|
32777
|
-
"f10": 121,
|
32778
|
-
"f11": 122
|
32779
|
-
};
|
32780
|
-
|
32781
|
-
var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
|
32782
|
-
|
32783
|
-
return function(editor) {
|
32784
|
-
var self = this, shortcuts = {};
|
32785
|
-
|
32786
|
-
function createShortcut(pattern, desc, cmdFunc, scope) {
|
32787
|
-
var id, key, shortcut;
|
32788
|
-
|
32789
|
-
shortcut = {
|
32790
|
-
func: cmdFunc,
|
32791
|
-
scope: scope || editor,
|
32792
|
-
desc: editor.translate(desc)
|
32793
|
-
};
|
32794
|
-
|
32795
|
-
// Parse modifiers and keys ctrl+alt+b for example
|
32796
|
-
each(explode(pattern, '+'), function(value) {
|
32797
|
-
if (value in modifierNames) {
|
32798
|
-
shortcut[value] = true;
|
32799
|
-
} else {
|
32800
|
-
// Allow numeric keycodes like ctrl+219 for ctrl+[
|
32801
|
-
if (/^[0-9]{2,}$/.test(value)) {
|
32802
|
-
shortcut.keyCode = parseInt(value, 10);
|
32803
|
-
} else {
|
32804
|
-
shortcut.charCode = value.charCodeAt(0);
|
32805
|
-
shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
|
32806
|
-
}
|
32807
|
-
}
|
32808
|
-
});
|
32809
|
-
|
32810
|
-
// Generate unique id for modifier combination and set default state for unused modifiers
|
32811
|
-
id = [shortcut.keyCode];
|
32812
|
-
for (key in modifierNames) {
|
32813
|
-
if (shortcut[key]) {
|
32814
|
-
id.push(key);
|
32815
|
-
} else {
|
32816
|
-
shortcut[key] = false;
|
32817
|
-
}
|
32818
|
-
}
|
32819
|
-
shortcut.id = id.join(',');
|
32820
|
-
|
32821
|
-
// Handle special access modifier differently depending on Mac/Win
|
32822
|
-
if (shortcut.access) {
|
32823
|
-
shortcut.alt = true;
|
32824
|
-
|
32825
|
-
if (Env.mac) {
|
32826
|
-
shortcut.ctrl = true;
|
32827
|
-
} else {
|
32828
|
-
shortcut.shift = true;
|
32829
|
-
}
|
32830
|
-
}
|
32831
|
-
|
32832
|
-
// Handle special meta modifier differently depending on Mac/Win
|
32833
|
-
if (shortcut.meta) {
|
32834
|
-
if (Env.mac) {
|
32835
|
-
shortcut.meta = true;
|
32836
|
-
} else {
|
32837
|
-
shortcut.ctrl = true;
|
32838
|
-
shortcut.meta = false;
|
32839
|
-
}
|
32840
|
-
}
|
32841
|
-
|
32842
|
-
return shortcut;
|
32843
|
-
}
|
32844
|
-
|
32845
|
-
editor.on('keyup keypress keydown', function(e) {
|
32846
|
-
if ((e.altKey || e.ctrlKey || e.metaKey) && !e.isDefaultPrevented()) {
|
32847
|
-
each(shortcuts, function(shortcut) {
|
32848
|
-
if (shortcut.ctrl != e.ctrlKey || shortcut.meta != e.metaKey) {
|
32849
|
-
return;
|
32850
|
-
}
|
32851
|
-
|
32852
|
-
if (shortcut.alt != e.altKey || shortcut.shift != e.shiftKey) {
|
32853
|
-
return;
|
32854
|
-
}
|
32855
|
-
|
32856
|
-
if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {
|
32857
|
-
e.preventDefault();
|
32858
|
-
|
32859
|
-
if (e.type == "keydown") {
|
32860
|
-
shortcut.func.call(shortcut.scope);
|
32861
|
-
}
|
32862
|
-
|
32863
|
-
return true;
|
32864
|
-
}
|
32865
|
-
});
|
32866
|
-
}
|
32867
|
-
});
|
32868
|
-
|
32869
|
-
/**
|
32870
|
-
* Adds a keyboard shortcut for some command or function.
|
32871
|
-
*
|
32872
|
-
* @method addShortcut
|
32873
|
-
* @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o.
|
32874
|
-
* @param {String} desc Text description for the command.
|
32875
|
-
* @param {String/Function} cmdFunc Command name string or function to execute when the key is pressed.
|
32876
|
-
* @param {Object} scope Optional scope to execute the function in.
|
32877
|
-
* @return {Boolean} true/false state if the shortcut was added or not.
|
32878
|
-
*/
|
32879
|
-
self.add = function(pattern, desc, cmdFunc, scope) {
|
32880
|
-
var cmd;
|
32881
|
-
|
32882
|
-
cmd = cmdFunc;
|
32883
|
-
|
32884
|
-
if (typeof cmdFunc === 'string') {
|
32885
|
-
cmdFunc = function() {
|
32886
|
-
editor.execCommand(cmd, false, null);
|
32887
|
-
};
|
32888
|
-
} else if (Tools.isArray(cmd)) {
|
32889
|
-
cmdFunc = function() {
|
32890
|
-
editor.execCommand(cmd[0], cmd[1], cmd[2]);
|
32891
|
-
};
|
32892
|
-
}
|
32893
|
-
|
32894
|
-
each(explode(pattern.toLowerCase()), function(pattern) {
|
32895
|
-
var shortcut = createShortcut(pattern, desc, cmdFunc, scope);
|
32896
|
-
shortcuts[shortcut.id] = shortcut;
|
32897
|
-
});
|
32898
|
-
|
32899
|
-
return true;
|
32900
|
-
};
|
32901
|
-
|
32902
|
-
/**
|
32903
|
-
* Remove a keyboard shortcut by pattern.
|
32904
|
-
*
|
32905
|
-
* @method remove
|
32906
|
-
* @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o.
|
32907
|
-
* @return {Boolean} true/false state if the shortcut was removed or not.
|
32908
|
-
*/
|
32909
|
-
self.remove = function(pattern) {
|
32910
|
-
var shortcut = createShortcut(pattern);
|
32911
|
-
|
32912
|
-
if (shortcuts[shortcut.id]) {
|
32913
|
-
delete shortcuts[shortcut.id];
|
32914
|
-
return true;
|
32915
|
-
}
|
32916
|
-
|
32917
|
-
return false;
|
32918
|
-
};
|
32919
|
-
};
|
32920
|
-
});
|
32921
|
-
|
32922
|
-
// Included from: js/tinymce/classes/file/Uploader.js
|
32923
|
-
|
32924
|
-
/**
|
32925
|
-
* Uploader.js
|
32926
|
-
*
|
32927
|
-
* Released under LGPL License.
|
32928
|
-
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
32929
|
-
*
|
32930
|
-
* License: http://www.tinymce.com/license
|
32931
|
-
* Contributing: http://www.tinymce.com/contributing
|
32932
|
-
*/
|
32933
|
-
|
32934
|
-
/**
|
32935
|
-
* Upload blobs or blob infos to the specified URL or handler.
|
32936
|
-
*
|
32937
|
-
* @private
|
32938
|
-
* @class tinymce.file.Uploader
|
32939
|
-
* @example
|
32940
|
-
* var uploader = new Uploader({
|
32941
|
-
* url: '/upload.php',
|
32942
|
-
* basePath: '/base/path',
|
32943
|
-
* credentials: true,
|
32944
|
-
* handler: function(data, success, failure) {
|
32945
|
-
* ...
|
32946
|
-
* }
|
32947
|
-
* });
|
32948
|
-
*
|
32949
|
-
* uploader.upload(blobInfos).then(function(result) {
|
32950
|
-
* ...
|
32951
|
-
* });
|
32952
|
-
*/
|
32953
|
-
define("tinymce/file/Uploader", [
|
32954
|
-
"tinymce/util/Promise",
|
32955
|
-
"tinymce/util/Tools",
|
32956
|
-
"tinymce/util/Fun"
|
32957
|
-
], function(Promise, Tools, Fun) {
|
32958
|
-
return function(settings) {
|
32959
|
-
var cachedPromises = {};
|
32960
|
-
|
32961
|
-
function fileName(blobInfo) {
|
32962
|
-
var ext, extensions;
|
32963
|
-
|
32964
|
-
extensions = {
|
32965
|
-
'image/jpeg': 'jpg',
|
32966
|
-
'image/jpg': 'jpg',
|
32967
|
-
'image/gif': 'gif',
|
32968
|
-
'image/png': 'png'
|
32969
|
-
};
|
32970
|
-
|
32971
|
-
ext = extensions[blobInfo.blob().type.toLowerCase()] || 'dat';
|
32972
|
-
|
32973
|
-
return blobInfo.id() + '.' + ext;
|
32974
|
-
}
|
32975
|
-
|
32976
|
-
function pathJoin(path1, path2) {
|
32977
|
-
if (path1) {
|
32978
|
-
return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
|
32979
|
-
}
|
32980
|
-
|
32981
|
-
return path2;
|
32982
|
-
}
|
32983
|
-
|
32984
|
-
function blobInfoToData(blobInfo) {
|
32985
|
-
return {
|
32986
|
-
id: blobInfo.id,
|
32987
|
-
blob: blobInfo.blob,
|
32988
|
-
base64: blobInfo.base64,
|
32989
|
-
filename: Fun.constant(fileName(blobInfo))
|
32990
|
-
};
|
32991
|
-
}
|
32992
|
-
|
32993
|
-
function defaultHandler(blobInfo, success, failure, openNotification) {
|
32994
|
-
var xhr, formData, notification;
|
32995
|
-
|
32996
|
-
xhr = new XMLHttpRequest();
|
32997
|
-
xhr.open('POST', settings.url);
|
32998
|
-
xhr.withCredentials = settings.credentials;
|
32999
|
-
|
33000
|
-
notification = openNotification();
|
33001
|
-
|
33002
|
-
xhr.upload.onprogress = function(e) {
|
33003
|
-
var percentLoaded = Math.round(e.loaded / e.total * 100);
|
33004
|
-
notification.progressBar.value(percentLoaded);
|
33005
|
-
};
|
33006
|
-
|
33007
|
-
xhr.onerror = function() {
|
33008
|
-
notification.close();
|
33009
|
-
failure("Image upload failed due to a XHR Transport error. Code: " + xhr.status);
|
33010
|
-
};
|
33011
|
-
|
33012
|
-
xhr.onload = function() {
|
33013
|
-
var json;
|
33014
|
-
|
33015
|
-
notification.close();
|
33016
|
-
|
33017
|
-
if (xhr.status != 200) {
|
33018
|
-
failure("HTTP Error: " + xhr.status);
|
33019
|
-
return;
|
33020
|
-
}
|
33021
|
-
|
33022
|
-
json = JSON.parse(xhr.responseText);
|
33023
|
-
|
33024
|
-
if (!json || typeof json.location != "string") {
|
33025
|
-
failure("Invalid JSON: " + xhr.responseText);
|
33026
|
-
return;
|
33027
|
-
}
|
33028
|
-
|
33029
|
-
success(pathJoin(settings.basePath, json.location));
|
33030
|
-
};
|
33031
|
-
|
33032
|
-
formData = new FormData();
|
33033
|
-
formData.append('file', blobInfo.blob(), fileName(blobInfo));
|
33034
|
-
|
33035
|
-
xhr.send(formData);
|
33036
|
-
}
|
33037
|
-
|
33038
|
-
function noUpload() {
|
33039
|
-
return new Promise(function(resolve) {
|
33040
|
-
resolve([]);
|
33041
|
-
});
|
33042
|
-
}
|
33043
|
-
|
33044
|
-
function interpretResult(promise) {
|
33045
|
-
return promise.then(function(result) {
|
33046
|
-
return result;
|
33047
|
-
})['catch'](function(error) {
|
33048
|
-
return error;
|
33049
|
-
});
|
33050
|
-
}
|
33051
|
-
|
33052
|
-
function registerPromise(handler, id, blobInfo) {
|
33053
|
-
var response = handler(blobInfo);
|
33054
|
-
var promise = interpretResult(response);
|
33055
|
-
delete cachedPromises[id];
|
33056
|
-
cachedPromises[id] = promise;
|
33057
|
-
return promise;
|
33058
|
-
}
|
33059
|
-
|
33060
|
-
function collectUploads(blobInfos, uploadBlobInfo) {
|
33061
|
-
return Tools.map(blobInfos, function(blobInfo) {
|
33062
|
-
var id = blobInfo.id();
|
33063
|
-
return cachedPromises[id] ? cachedPromises[id] : registerPromise(uploadBlobInfo, id, blobInfo);
|
33064
|
-
});
|
33065
|
-
}
|
33238
|
+
* Toggles a native event on/off this is called by the EventDispatcher when
|
33239
|
+
* the first native event handler is added and when the last native event handler is removed.
|
33240
|
+
*
|
33241
|
+
* @private
|
33242
|
+
*/
|
33243
|
+
toggleNativeEvent: function(name, state) {
|
33244
|
+
var self = this;
|
33066
33245
|
|
33067
|
-
|
33068
|
-
|
33069
|
-
return
|
33070
|
-
|
33246
|
+
// Never bind focus/blur since the FocusManager fakes those
|
33247
|
+
if (name == "focus" || name == "blur") {
|
33248
|
+
return;
|
33249
|
+
}
|
33071
33250
|
|
33072
|
-
|
33073
|
-
|
33074
|
-
|
33075
|
-
|
33076
|
-
|
33077
|
-
|
33078
|
-
|
33079
|
-
|
33080
|
-
resolve({
|
33081
|
-
url: '',
|
33082
|
-
blobInfo: blobInfo,
|
33083
|
-
status: false,
|
33084
|
-
error: failure
|
33085
|
-
});
|
33086
|
-
}, openNotification);
|
33087
|
-
} catch (ex) {
|
33088
|
-
resolve({
|
33089
|
-
url: '',
|
33090
|
-
blobInfo: blobInfo,
|
33091
|
-
status: false,
|
33092
|
-
error: ex.message
|
33093
|
-
});
|
33251
|
+
if (state) {
|
33252
|
+
if (self.initialized) {
|
33253
|
+
bindEventDelegate(self, name);
|
33254
|
+
} else {
|
33255
|
+
if (!self._pendingNativeEvents) {
|
33256
|
+
self._pendingNativeEvents = [name];
|
33257
|
+
} else {
|
33258
|
+
self._pendingNativeEvents.push(name);
|
33094
33259
|
}
|
33095
|
-
}
|
33260
|
+
}
|
33261
|
+
} else if (self.initialized) {
|
33262
|
+
self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
|
33263
|
+
delete self.delegates[name];
|
33096
33264
|
}
|
33265
|
+
},
|
33097
33266
|
|
33098
|
-
|
33099
|
-
|
33100
|
-
|
33267
|
+
/**
|
33268
|
+
* Unbinds all native event handlers that means delegates, custom events bound using the Events API etc.
|
33269
|
+
*
|
33270
|
+
* @private
|
33271
|
+
*/
|
33272
|
+
unbindAllNativeEvents: function() {
|
33273
|
+
var self = this, name;
|
33101
33274
|
|
33102
|
-
|
33103
|
-
|
33104
|
-
|
33275
|
+
if (self.delegates) {
|
33276
|
+
for (name in self.delegates) {
|
33277
|
+
self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
|
33278
|
+
}
|
33105
33279
|
|
33106
|
-
|
33107
|
-
|
33108
|
-
// We are adding a notify argument to this (at the moment, until it doesn't work)
|
33109
|
-
handler: defaultHandler
|
33110
|
-
}, settings);
|
33280
|
+
delete self.delegates;
|
33281
|
+
}
|
33111
33282
|
|
33112
|
-
|
33113
|
-
|
33114
|
-
|
33283
|
+
if (!self.inline) {
|
33284
|
+
self.getBody().onload = null;
|
33285
|
+
self.dom.unbind(self.getWin());
|
33286
|
+
self.dom.unbind(self.getDoc());
|
33287
|
+
}
|
33288
|
+
|
33289
|
+
self.dom.unbind(self.getBody());
|
33290
|
+
self.dom.unbind(self.getContainer());
|
33291
|
+
}
|
33115
33292
|
};
|
33293
|
+
|
33294
|
+
EditorObservable = Tools.extend({}, Observable, EditorObservable);
|
33295
|
+
|
33296
|
+
return EditorObservable;
|
33116
33297
|
});
|
33117
33298
|
|
33118
|
-
// Included from: js/tinymce/classes/
|
33299
|
+
// Included from: js/tinymce/classes/Mode.js
|
33119
33300
|
|
33120
33301
|
/**
|
33121
|
-
*
|
33302
|
+
* Mode.js
|
33122
33303
|
*
|
33123
33304
|
* Released under LGPL License.
|
33124
33305
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -33128,106 +33309,90 @@ define("tinymce/file/Uploader", [
|
|
33128
33309
|
*/
|
33129
33310
|
|
33130
33311
|
/**
|
33131
|
-
*
|
33312
|
+
* Mode switcher logic.
|
33132
33313
|
*
|
33133
33314
|
* @private
|
33134
|
-
* @class tinymce.
|
33315
|
+
* @class tinymce.Mode
|
33135
33316
|
*/
|
33136
|
-
define("tinymce/
|
33137
|
-
|
33138
|
-
|
33139
|
-
|
33140
|
-
|
33141
|
-
|
33142
|
-
|
33143
|
-
xhr.open('GET', url, true);
|
33144
|
-
xhr.responseType = 'blob';
|
33145
|
-
|
33146
|
-
xhr.onload = function() {
|
33147
|
-
if (this.status == 200) {
|
33148
|
-
resolve(this.response);
|
33149
|
-
}
|
33150
|
-
};
|
33151
|
-
|
33152
|
-
xhr.send();
|
33153
|
-
});
|
33154
|
-
}
|
33155
|
-
|
33156
|
-
function parseDataUri(uri) {
|
33157
|
-
var type, matches;
|
33158
|
-
|
33159
|
-
uri = decodeURIComponent(uri).split(',');
|
33160
|
-
|
33161
|
-
matches = /data:([^;]+)/.exec(uri[0]);
|
33162
|
-
if (matches) {
|
33163
|
-
type = matches[1];
|
33317
|
+
define("tinymce/Mode", [], function() {
|
33318
|
+
function setEditorCommandState(editor, cmd, state) {
|
33319
|
+
try {
|
33320
|
+
editor.getDoc().execCommand(cmd, false, state);
|
33321
|
+
} catch (ex) {
|
33322
|
+
// Ignore
|
33164
33323
|
}
|
33165
|
-
|
33166
|
-
return {
|
33167
|
-
type: type,
|
33168
|
-
data: uri[1]
|
33169
|
-
};
|
33170
33324
|
}
|
33171
33325
|
|
33172
|
-
function
|
33173
|
-
|
33174
|
-
var str, arr, i;
|
33326
|
+
function clickBlocker(editor) {
|
33327
|
+
var target, handler;
|
33175
33328
|
|
33176
|
-
|
33329
|
+
target = editor.getBody();
|
33177
33330
|
|
33178
|
-
|
33179
|
-
|
33180
|
-
|
33181
|
-
} catch (e) {
|
33182
|
-
resolve(new Blob([]));
|
33183
|
-
return;
|
33331
|
+
handler = function(e) {
|
33332
|
+
if (editor.dom.getParents(e.target, 'a').length > 0) {
|
33333
|
+
e.preventDefault();
|
33184
33334
|
}
|
33335
|
+
};
|
33185
33336
|
|
33186
|
-
|
33337
|
+
editor.dom.bind(target, 'click', handler);
|
33187
33338
|
|
33188
|
-
|
33189
|
-
|
33339
|
+
return {
|
33340
|
+
unbind: function() {
|
33341
|
+
editor.dom.unbind(target, 'click', handler);
|
33190
33342
|
}
|
33191
|
-
|
33192
|
-
resolve(new Blob([arr], {type: uri.type}));
|
33193
|
-
});
|
33343
|
+
};
|
33194
33344
|
}
|
33195
33345
|
|
33196
|
-
function
|
33197
|
-
if (
|
33198
|
-
|
33346
|
+
function toggleReadOnly(editor, state) {
|
33347
|
+
if (editor._clickBlocker) {
|
33348
|
+
editor._clickBlocker.unbind();
|
33349
|
+
editor._clickBlocker = null;
|
33199
33350
|
}
|
33200
33351
|
|
33201
|
-
if (
|
33202
|
-
|
33352
|
+
if (state) {
|
33353
|
+
editor._clickBlocker = clickBlocker(editor);
|
33354
|
+
editor.selection.controlSelection.hideResizeRect();
|
33355
|
+
editor.readonly = true;
|
33356
|
+
editor.getBody().contentEditable = false;
|
33357
|
+
} else {
|
33358
|
+
editor.readonly = false;
|
33359
|
+
editor.getBody().contentEditable = true;
|
33360
|
+
setEditorCommandState(editor, "StyleWithCSS", false);
|
33361
|
+
setEditorCommandState(editor, "enableInlineTableEditing", false);
|
33362
|
+
setEditorCommandState(editor, "enableObjectResizing", false);
|
33363
|
+
editor.focus();
|
33364
|
+
editor.nodeChanged();
|
33203
33365
|
}
|
33204
|
-
|
33205
|
-
return null;
|
33206
33366
|
}
|
33207
33367
|
|
33208
|
-
function
|
33209
|
-
|
33210
|
-
var reader = new FileReader();
|
33368
|
+
function setMode(editor, mode) {
|
33369
|
+
var currentMode = editor.readonly ? 'readonly' : 'design';
|
33211
33370
|
|
33212
|
-
|
33213
|
-
|
33214
|
-
|
33371
|
+
if (mode == currentMode) {
|
33372
|
+
return;
|
33373
|
+
}
|
33215
33374
|
|
33216
|
-
|
33217
|
-
|
33375
|
+
if (editor.initialized) {
|
33376
|
+
toggleReadOnly(editor, mode == 'readonly');
|
33377
|
+
} else {
|
33378
|
+
editor.on('init', function() {
|
33379
|
+
toggleReadOnly(editor, mode == 'readonly');
|
33380
|
+
});
|
33381
|
+
}
|
33382
|
+
|
33383
|
+
// Event is NOT preventable
|
33384
|
+
editor.fire('SwitchMode', {mode: mode});
|
33218
33385
|
}
|
33219
33386
|
|
33220
33387
|
return {
|
33221
|
-
|
33222
|
-
blobToDataUri: blobToDataUri,
|
33223
|
-
parseDataUri: parseDataUri
|
33388
|
+
setMode: setMode
|
33224
33389
|
};
|
33225
33390
|
});
|
33226
33391
|
|
33227
|
-
// Included from: js/tinymce/classes/
|
33392
|
+
// Included from: js/tinymce/classes/Shortcuts.js
|
33228
33393
|
|
33229
33394
|
/**
|
33230
|
-
*
|
33395
|
+
* Shortcuts.js
|
33231
33396
|
*
|
33232
33397
|
* Released under LGPL License.
|
33233
33398
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -33237,220 +33402,172 @@ define("tinymce/file/Conversions", [
|
|
33237
33402
|
*/
|
33238
33403
|
|
33239
33404
|
/**
|
33240
|
-
*
|
33405
|
+
* Contains all logic for handling of keyboard shortcuts.
|
33241
33406
|
*
|
33242
|
-
* @
|
33243
|
-
* @
|
33407
|
+
* @class tinymce.Shortcuts
|
33408
|
+
* @example
|
33409
|
+
* editor.shortcuts.add('ctrl+a', function() {});
|
33410
|
+
* editor.shortcuts.add('meta+a', function() {}); // "meta" maps to Command on Mac and Ctrl on PC
|
33411
|
+
* editor.shortcuts.add('ctrl+alt+a', function() {});
|
33412
|
+
* editor.shortcuts.add('access+a', function() {}); // "access" maps to ctrl+alt on Mac and shift+alt on PC
|
33244
33413
|
*/
|
33245
|
-
define("tinymce/
|
33246
|
-
"tinymce/util/
|
33247
|
-
"tinymce/util/Arr",
|
33248
|
-
"tinymce/util/Fun",
|
33249
|
-
"tinymce/file/Conversions",
|
33414
|
+
define("tinymce/Shortcuts", [
|
33415
|
+
"tinymce/util/Tools",
|
33250
33416
|
"tinymce/Env"
|
33251
|
-
], function(
|
33252
|
-
var
|
33417
|
+
], function(Tools, Env) {
|
33418
|
+
var each = Tools.each, explode = Tools.explode;
|
33253
33419
|
|
33254
|
-
|
33255
|
-
|
33420
|
+
var keyCodeLookup = {
|
33421
|
+
"f9": 120,
|
33422
|
+
"f10": 121,
|
33423
|
+
"f11": 122
|
33424
|
+
};
|
33256
33425
|
|
33257
|
-
|
33258
|
-
var images, promises;
|
33426
|
+
var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
|
33259
33427
|
|
33260
|
-
|
33261
|
-
|
33428
|
+
return function(editor) {
|
33429
|
+
var self = this, shortcuts = {};
|
33262
33430
|
|
33263
|
-
|
33264
|
-
|
33431
|
+
function createShortcut(pattern, desc, cmdFunc, scope) {
|
33432
|
+
var id, key, shortcut;
|
33265
33433
|
|
33266
|
-
|
33267
|
-
|
33268
|
-
|
33269
|
-
|
33270
|
-
|
33271
|
-
}
|
33434
|
+
shortcut = {
|
33435
|
+
func: cmdFunc,
|
33436
|
+
scope: scope || editor,
|
33437
|
+
desc: editor.translate(desc)
|
33438
|
+
};
|
33272
33439
|
|
33273
|
-
|
33440
|
+
// Parse modifiers and keys ctrl+alt+b for example
|
33441
|
+
each(explode(pattern, '+'), function(value) {
|
33442
|
+
if (value in modifierNames) {
|
33443
|
+
shortcut[value] = true;
|
33444
|
+
} else {
|
33445
|
+
// Allow numeric keycodes like ctrl+219 for ctrl+[
|
33446
|
+
if (/^[0-9]{2,}$/.test(value)) {
|
33447
|
+
shortcut.keyCode = parseInt(value, 10);
|
33448
|
+
} else {
|
33449
|
+
shortcut.charCode = value.charCodeAt(0);
|
33450
|
+
shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
|
33451
|
+
}
|
33274
33452
|
}
|
33453
|
+
});
|
33275
33454
|
|
33276
|
-
|
33277
|
-
|
33278
|
-
|
33279
|
-
|
33280
|
-
|
33281
|
-
if (blobInfo) {
|
33282
|
-
resolve({
|
33283
|
-
image: img,
|
33284
|
-
blobInfo: blobInfo
|
33285
|
-
});
|
33455
|
+
// Generate unique id for modifier combination and set default state for unused modifiers
|
33456
|
+
id = [shortcut.keyCode];
|
33457
|
+
for (key in modifierNames) {
|
33458
|
+
if (shortcut[key]) {
|
33459
|
+
id.push(key);
|
33286
33460
|
} else {
|
33287
|
-
|
33288
|
-
var blobInfoId = 'blobid' + (count++),
|
33289
|
-
blobInfo = blobCache.create(blobInfoId, blob, base64);
|
33290
|
-
|
33291
|
-
blobCache.add(blobInfo);
|
33292
|
-
|
33293
|
-
resolve({
|
33294
|
-
image: img,
|
33295
|
-
blobInfo: blobInfo
|
33296
|
-
});
|
33297
|
-
});
|
33461
|
+
shortcut[key] = false;
|
33298
33462
|
}
|
33299
33463
|
}
|
33464
|
+
shortcut.id = id.join(',');
|
33300
33465
|
|
33301
|
-
|
33302
|
-
|
33303
|
-
|
33304
|
-
|
33305
|
-
images = Arr.filter(elm.getElementsByTagName('img'), function(img) {
|
33306
|
-
var src = img.src;
|
33307
|
-
|
33308
|
-
if (!Env.fileApi) {
|
33309
|
-
return false;
|
33310
|
-
}
|
33311
|
-
|
33312
|
-
if (img.hasAttribute('data-mce-bogus')) {
|
33313
|
-
return false;
|
33314
|
-
}
|
33466
|
+
// Handle special access modifier differently depending on Mac/Win
|
33467
|
+
if (shortcut.access) {
|
33468
|
+
shortcut.alt = true;
|
33315
33469
|
|
33316
|
-
if (
|
33317
|
-
|
33470
|
+
if (Env.mac) {
|
33471
|
+
shortcut.ctrl = true;
|
33472
|
+
} else {
|
33473
|
+
shortcut.shift = true;
|
33318
33474
|
}
|
33475
|
+
}
|
33319
33476
|
|
33320
|
-
|
33321
|
-
|
33477
|
+
// Handle special meta modifier differently depending on Mac/Win
|
33478
|
+
if (shortcut.meta) {
|
33479
|
+
if (Env.mac) {
|
33480
|
+
shortcut.meta = true;
|
33481
|
+
} else {
|
33482
|
+
shortcut.ctrl = true;
|
33483
|
+
shortcut.meta = false;
|
33322
33484
|
}
|
33485
|
+
}
|
33323
33486
|
|
33324
|
-
|
33325
|
-
|
33326
|
-
}
|
33487
|
+
return shortcut;
|
33488
|
+
}
|
33327
33489
|
|
33328
|
-
|
33329
|
-
|
33330
|
-
|
33490
|
+
editor.on('keyup keypress keydown', function(e) {
|
33491
|
+
if ((e.altKey || e.ctrlKey || e.metaKey) && !e.isDefaultPrevented()) {
|
33492
|
+
each(shortcuts, function(shortcut) {
|
33493
|
+
if (shortcut.ctrl != e.ctrlKey || shortcut.meta != e.metaKey) {
|
33494
|
+
return;
|
33495
|
+
}
|
33331
33496
|
|
33332
|
-
|
33333
|
-
|
33497
|
+
if (shortcut.alt != e.altKey || shortcut.shift != e.shiftKey) {
|
33498
|
+
return;
|
33499
|
+
}
|
33334
33500
|
|
33335
|
-
|
33336
|
-
|
33501
|
+
if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {
|
33502
|
+
e.preventDefault();
|
33337
33503
|
|
33338
|
-
|
33339
|
-
|
33340
|
-
|
33341
|
-
return new Promise(function(resolve) {
|
33342
|
-
cachedPromises[img.src].then(function(imageInfo) {
|
33343
|
-
resolve({
|
33344
|
-
image: img,
|
33345
|
-
blobInfo: imageInfo.blobInfo
|
33346
|
-
});
|
33347
|
-
});
|
33348
|
-
});
|
33349
|
-
}
|
33504
|
+
if (e.type == "keydown") {
|
33505
|
+
shortcut.func.call(shortcut.scope);
|
33506
|
+
}
|
33350
33507
|
|
33351
|
-
|
33352
|
-
|
33353
|
-
}).then(function(result) {
|
33354
|
-
delete cachedPromises[result.image.src];
|
33355
|
-
return result;
|
33356
|
-
})['catch'](function(error) {
|
33357
|
-
delete cachedPromises[img.src];
|
33358
|
-
return error;
|
33508
|
+
return true;
|
33509
|
+
}
|
33359
33510
|
});
|
33511
|
+
}
|
33512
|
+
});
|
33360
33513
|
|
33361
|
-
|
33362
|
-
|
33363
|
-
|
33364
|
-
|
33365
|
-
|
33366
|
-
|
33367
|
-
|
33368
|
-
|
33369
|
-
|
33370
|
-
|
33371
|
-
|
33372
|
-
|
33373
|
-
});
|
33374
|
-
|
33375
|
-
// Included from: js/tinymce/classes/file/BlobCache.js
|
33376
|
-
|
33377
|
-
/**
|
33378
|
-
* BlobCache.js
|
33379
|
-
*
|
33380
|
-
* Released under LGPL License.
|
33381
|
-
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
33382
|
-
*
|
33383
|
-
* License: http://www.tinymce.com/license
|
33384
|
-
* Contributing: http://www.tinymce.com/contributing
|
33385
|
-
*/
|
33386
|
-
|
33387
|
-
/**
|
33388
|
-
* Hold blob info objects where a blob has extra internal information.
|
33389
|
-
*
|
33390
|
-
* @private
|
33391
|
-
* @class tinymce.file.BlobCache
|
33392
|
-
*/
|
33393
|
-
define("tinymce/file/BlobCache", [
|
33394
|
-
"tinymce/util/Arr",
|
33395
|
-
"tinymce/util/Fun"
|
33396
|
-
], function(Arr, Fun) {
|
33397
|
-
return function() {
|
33398
|
-
var cache = [], constant = Fun.constant;
|
33514
|
+
/**
|
33515
|
+
* Adds a keyboard shortcut for some command or function.
|
33516
|
+
*
|
33517
|
+
* @method addShortcut
|
33518
|
+
* @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o.
|
33519
|
+
* @param {String} desc Text description for the command.
|
33520
|
+
* @param {String/Function} cmdFunc Command name string or function to execute when the key is pressed.
|
33521
|
+
* @param {Object} scope Optional scope to execute the function in.
|
33522
|
+
* @return {Boolean} true/false state if the shortcut was added or not.
|
33523
|
+
*/
|
33524
|
+
self.add = function(pattern, desc, cmdFunc, scope) {
|
33525
|
+
var cmd;
|
33399
33526
|
|
33400
|
-
|
33401
|
-
return {
|
33402
|
-
id: constant(id),
|
33403
|
-
blob: constant(blob),
|
33404
|
-
base64: constant(base64),
|
33405
|
-
blobUri: constant(URL.createObjectURL(blob))
|
33406
|
-
};
|
33407
|
-
}
|
33527
|
+
cmd = cmdFunc;
|
33408
33528
|
|
33409
|
-
|
33410
|
-
|
33411
|
-
|
33529
|
+
if (typeof cmdFunc === 'string') {
|
33530
|
+
cmdFunc = function() {
|
33531
|
+
editor.execCommand(cmd, false, null);
|
33532
|
+
};
|
33533
|
+
} else if (Tools.isArray(cmd)) {
|
33534
|
+
cmdFunc = function() {
|
33535
|
+
editor.execCommand(cmd[0], cmd[1], cmd[2]);
|
33536
|
+
};
|
33412
33537
|
}
|
33413
|
-
}
|
33414
33538
|
|
33415
|
-
|
33416
|
-
|
33417
|
-
|
33539
|
+
each(explode(pattern.toLowerCase()), function(pattern) {
|
33540
|
+
var shortcut = createShortcut(pattern, desc, cmdFunc, scope);
|
33541
|
+
shortcuts[shortcut.id] = shortcut;
|
33418
33542
|
});
|
33419
|
-
}
|
33420
|
-
|
33421
|
-
function findFirst(predicate) {
|
33422
|
-
return Arr.filter(cache, predicate)[0];
|
33423
|
-
}
|
33424
33543
|
|
33425
|
-
|
33426
|
-
|
33427
|
-
return blobInfo.blobUri() == blobUri;
|
33428
|
-
});
|
33429
|
-
}
|
33544
|
+
return true;
|
33545
|
+
};
|
33430
33546
|
|
33431
|
-
|
33432
|
-
|
33433
|
-
|
33434
|
-
|
33547
|
+
/**
|
33548
|
+
* Remove a keyboard shortcut by pattern.
|
33549
|
+
*
|
33550
|
+
* @method remove
|
33551
|
+
* @param {String} pattern Shortcut pattern. Like for example: ctrl+alt+o.
|
33552
|
+
* @return {Boolean} true/false state if the shortcut was removed or not.
|
33553
|
+
*/
|
33554
|
+
self.remove = function(pattern) {
|
33555
|
+
var shortcut = createShortcut(pattern);
|
33435
33556
|
|
33436
|
-
|
33437
|
-
|
33557
|
+
if (shortcuts[shortcut.id]) {
|
33558
|
+
delete shortcuts[shortcut.id];
|
33559
|
+
return true;
|
33560
|
+
}
|
33438
33561
|
|
33439
|
-
|
33440
|
-
create: create,
|
33441
|
-
add: add,
|
33442
|
-
get: get,
|
33443
|
-
getByUri: getByUri,
|
33444
|
-
findFirst: findFirst,
|
33445
|
-
destroy: destroy
|
33562
|
+
return false;
|
33446
33563
|
};
|
33447
33564
|
};
|
33448
33565
|
});
|
33449
33566
|
|
33450
|
-
// Included from: js/tinymce/classes/
|
33567
|
+
// Included from: js/tinymce/classes/file/Uploader.js
|
33451
33568
|
|
33452
33569
|
/**
|
33453
|
-
*
|
33570
|
+
* Uploader.js
|
33454
33571
|
*
|
33455
33572
|
* Released under LGPL License.
|
33456
33573
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -33460,191 +33577,193 @@ define("tinymce/file/BlobCache", [
|
|
33460
33577
|
*/
|
33461
33578
|
|
33462
33579
|
/**
|
33463
|
-
*
|
33580
|
+
* Upload blobs or blob infos to the specified URL or handler.
|
33581
|
+
*
|
33582
|
+
* @private
|
33583
|
+
* @class tinymce.file.Uploader
|
33584
|
+
* @example
|
33585
|
+
* var uploader = new Uploader({
|
33586
|
+
* url: '/upload.php',
|
33587
|
+
* basePath: '/base/path',
|
33588
|
+
* credentials: true,
|
33589
|
+
* handler: function(data, success, failure) {
|
33590
|
+
* ...
|
33591
|
+
* }
|
33592
|
+
* });
|
33464
33593
|
*
|
33465
|
-
*
|
33466
|
-
*
|
33594
|
+
* uploader.upload(blobInfos).then(function(result) {
|
33595
|
+
* ...
|
33596
|
+
* });
|
33467
33597
|
*/
|
33468
|
-
define("tinymce/
|
33469
|
-
"tinymce/util/
|
33470
|
-
"tinymce/
|
33471
|
-
"tinymce/
|
33472
|
-
|
33473
|
-
|
33474
|
-
|
33475
|
-
var blobCache = new BlobCache(), uploader, imageScanner, settings = editor.settings;
|
33598
|
+
define("tinymce/file/Uploader", [
|
33599
|
+
"tinymce/util/Promise",
|
33600
|
+
"tinymce/util/Tools",
|
33601
|
+
"tinymce/util/Fun"
|
33602
|
+
], function(Promise, Tools, Fun) {
|
33603
|
+
return function(settings) {
|
33604
|
+
var cachedPromises = {};
|
33476
33605
|
|
33477
|
-
function
|
33478
|
-
|
33479
|
-
if (editor.selection) {
|
33480
|
-
return callback(result);
|
33481
|
-
}
|
33606
|
+
function fileName(blobInfo) {
|
33607
|
+
var ext, extensions;
|
33482
33608
|
|
33483
|
-
|
33609
|
+
extensions = {
|
33610
|
+
'image/jpeg': 'jpg',
|
33611
|
+
'image/jpg': 'jpg',
|
33612
|
+
'image/gif': 'gif',
|
33613
|
+
'image/png': 'png'
|
33484
33614
|
};
|
33485
|
-
}
|
33486
|
-
|
33487
|
-
// Replaces strings without regexps to avoid FF regexp to big issue
|
33488
|
-
function replaceString(content, search, replace) {
|
33489
|
-
var index = 0;
|
33490
33615
|
|
33491
|
-
|
33492
|
-
index = content.indexOf(search, index);
|
33493
|
-
|
33494
|
-
if (index !== -1) {
|
33495
|
-
content = content.substring(0, index) + replace + content.substr(index + search.length);
|
33496
|
-
index += replace.length - search.length + 1;
|
33497
|
-
}
|
33498
|
-
} while (index !== -1);
|
33616
|
+
ext = extensions[blobInfo.blob().type.toLowerCase()] || 'dat';
|
33499
33617
|
|
33500
|
-
return
|
33618
|
+
return blobInfo.id() + '.' + ext;
|
33501
33619
|
}
|
33502
33620
|
|
33503
|
-
function
|
33504
|
-
|
33505
|
-
|
33506
|
-
|
33507
|
-
return content;
|
33508
|
-
}
|
33621
|
+
function pathJoin(path1, path2) {
|
33622
|
+
if (path1) {
|
33623
|
+
return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
|
33624
|
+
}
|
33509
33625
|
|
33510
|
-
|
33511
|
-
Arr.each(editor.undoManager.data, function(level) {
|
33512
|
-
level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
|
33513
|
-
});
|
33626
|
+
return path2;
|
33514
33627
|
}
|
33515
33628
|
|
33516
|
-
function
|
33517
|
-
return
|
33518
|
-
|
33519
|
-
|
33520
|
-
|
33521
|
-
|
33522
|
-
}
|
33629
|
+
function blobInfoToData(blobInfo) {
|
33630
|
+
return {
|
33631
|
+
id: blobInfo.id,
|
33632
|
+
blob: blobInfo.blob,
|
33633
|
+
base64: blobInfo.base64,
|
33634
|
+
filename: Fun.constant(fileName(blobInfo))
|
33635
|
+
};
|
33523
33636
|
}
|
33524
33637
|
|
33525
|
-
function
|
33526
|
-
|
33527
|
-
uploader = new Uploader({
|
33528
|
-
url: settings.images_upload_url,
|
33529
|
-
basePath: settings.images_upload_base_path,
|
33530
|
-
credentials: settings.images_upload_credentials,
|
33531
|
-
handler: settings.images_upload_handler
|
33532
|
-
});
|
33533
|
-
}
|
33638
|
+
function defaultHandler(blobInfo, success, failure, openNotification) {
|
33639
|
+
var xhr, formData, notification;
|
33534
33640
|
|
33535
|
-
|
33536
|
-
|
33641
|
+
xhr = new XMLHttpRequest();
|
33642
|
+
xhr.open('POST', settings.url);
|
33643
|
+
xhr.withCredentials = settings.credentials;
|
33537
33644
|
|
33538
|
-
|
33539
|
-
return imageInfo.blobInfo;
|
33540
|
-
});
|
33645
|
+
notification = openNotification();
|
33541
33646
|
|
33542
|
-
|
33543
|
-
|
33544
|
-
|
33647
|
+
xhr.upload.onprogress = function(e) {
|
33648
|
+
var percentLoaded = Math.round(e.loaded / e.total * 100);
|
33649
|
+
notification.progressBar.value(percentLoaded);
|
33650
|
+
};
|
33545
33651
|
|
33546
|
-
|
33547
|
-
|
33652
|
+
xhr.onerror = function() {
|
33653
|
+
notification.close();
|
33654
|
+
failure("Image upload failed due to a XHR Transport error. Code: " + xhr.status);
|
33655
|
+
};
|
33548
33656
|
|
33549
|
-
|
33550
|
-
|
33551
|
-
'data-mce-src': editor.convertURL(uploadInfo.url, 'src')
|
33552
|
-
});
|
33553
|
-
}
|
33657
|
+
xhr.onload = function() {
|
33658
|
+
var json;
|
33554
33659
|
|
33555
|
-
|
33556
|
-
element: image,
|
33557
|
-
status: uploadInfo.status
|
33558
|
-
};
|
33559
|
-
});
|
33660
|
+
notification.close();
|
33560
33661
|
|
33561
|
-
|
33562
|
-
|
33563
|
-
|
33662
|
+
if (xhr.status != 200) {
|
33663
|
+
failure("HTTP Error: " + xhr.status);
|
33664
|
+
return;
|
33665
|
+
}
|
33564
33666
|
|
33565
|
-
|
33566
|
-
}));
|
33567
|
-
}));
|
33568
|
-
}
|
33667
|
+
json = JSON.parse(xhr.responseText);
|
33569
33668
|
|
33570
|
-
|
33571
|
-
|
33572
|
-
|
33573
|
-
|
33574
|
-
}
|
33669
|
+
if (!json || typeof json.location != "string") {
|
33670
|
+
failure("Invalid JSON: " + xhr.responseText);
|
33671
|
+
return;
|
33672
|
+
}
|
33575
33673
|
|
33576
|
-
|
33577
|
-
|
33578
|
-
imageScanner = new ImageScanner(blobCache);
|
33579
|
-
}
|
33674
|
+
success(pathJoin(settings.basePath, json.location));
|
33675
|
+
};
|
33580
33676
|
|
33581
|
-
|
33582
|
-
|
33583
|
-
replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
|
33584
|
-
resultItem.image.src = resultItem.blobInfo.blobUri();
|
33585
|
-
});
|
33677
|
+
formData = new FormData();
|
33678
|
+
formData.append('file', blobInfo.blob(), fileName(blobInfo));
|
33586
33679
|
|
33587
|
-
|
33588
|
-
}));
|
33680
|
+
xhr.send(formData);
|
33589
33681
|
}
|
33590
33682
|
|
33591
|
-
function
|
33592
|
-
|
33593
|
-
|
33683
|
+
function noUpload() {
|
33684
|
+
return new Promise(function(resolve) {
|
33685
|
+
resolve([]);
|
33686
|
+
});
|
33594
33687
|
}
|
33595
33688
|
|
33596
|
-
function
|
33597
|
-
return
|
33598
|
-
|
33599
|
-
|
33600
|
-
|
33601
|
-
|
33602
|
-
|
33603
|
-
}, null);
|
33604
|
-
}
|
33689
|
+
function interpretResult(promise) {
|
33690
|
+
return promise.then(function(result) {
|
33691
|
+
return result;
|
33692
|
+
})['catch'](function(error) {
|
33693
|
+
return error;
|
33694
|
+
});
|
33695
|
+
}
|
33605
33696
|
|
33606
|
-
|
33607
|
-
|
33608
|
-
|
33697
|
+
function registerPromise(handler, id, blobInfo) {
|
33698
|
+
var response = handler(blobInfo);
|
33699
|
+
var promise = interpretResult(response);
|
33700
|
+
delete cachedPromises[id];
|
33701
|
+
cachedPromises[id] = promise;
|
33702
|
+
return promise;
|
33703
|
+
}
|
33609
33704
|
|
33610
|
-
|
33705
|
+
function collectUploads(blobInfos, uploadBlobInfo) {
|
33706
|
+
return Tools.map(blobInfos, function(blobInfo) {
|
33707
|
+
var id = blobInfo.id();
|
33708
|
+
return cachedPromises[id] ? cachedPromises[id] : registerPromise(uploadBlobInfo, id, blobInfo);
|
33611
33709
|
});
|
33612
33710
|
}
|
33613
33711
|
|
33614
|
-
|
33615
|
-
|
33616
|
-
|
33617
|
-
|
33618
|
-
|
33712
|
+
function uploadBlobs(blobInfos, openNotification) {
|
33713
|
+
function uploadBlobInfo(blobInfo) {
|
33714
|
+
return new Promise(function(resolve) {
|
33715
|
+
var handler = settings.handler;
|
33716
|
+
|
33717
|
+
try {
|
33718
|
+
handler(blobInfoToData(blobInfo), function(url) {
|
33719
|
+
resolve({
|
33720
|
+
url: url,
|
33721
|
+
blobInfo: blobInfo,
|
33722
|
+
status: true
|
33723
|
+
});
|
33724
|
+
}, function(failure) {
|
33725
|
+
resolve({
|
33726
|
+
url: '',
|
33727
|
+
blobInfo: blobInfo,
|
33728
|
+
status: false,
|
33729
|
+
error: failure
|
33730
|
+
});
|
33731
|
+
}, openNotification);
|
33732
|
+
} catch (ex) {
|
33733
|
+
resolve({
|
33734
|
+
url: '',
|
33735
|
+
blobInfo: blobInfo,
|
33736
|
+
status: false,
|
33737
|
+
error: ex.message
|
33738
|
+
});
|
33739
|
+
}
|
33740
|
+
});
|
33619
33741
|
}
|
33620
|
-
});
|
33621
33742
|
|
33622
|
-
|
33623
|
-
|
33624
|
-
}
|
33743
|
+
var promises = collectUploads(blobInfos, uploadBlobInfo);
|
33744
|
+
return Promise.all(promises);
|
33745
|
+
}
|
33625
33746
|
|
33626
|
-
|
33627
|
-
|
33628
|
-
|
33629
|
-
}
|
33747
|
+
function upload(blobInfos, openNotification) {
|
33748
|
+
return (!settings.url && settings.handler === defaultHandler) ? noUpload() : uploadBlobs(blobInfos, openNotification);
|
33749
|
+
}
|
33630
33750
|
|
33631
|
-
|
33632
|
-
|
33751
|
+
settings = Tools.extend({
|
33752
|
+
credentials: false,
|
33753
|
+
// We are adding a notify argument to this (at the moment, until it doesn't work)
|
33754
|
+
handler: defaultHandler
|
33755
|
+
}, settings);
|
33633
33756
|
|
33634
33757
|
return {
|
33635
|
-
|
33636
|
-
uploadImages: uploadImages,
|
33637
|
-
uploadImagesAuto: uploadImagesAuto,
|
33638
|
-
scanForImages: scanForImages,
|
33639
|
-
destroy: destroy
|
33758
|
+
upload: upload
|
33640
33759
|
};
|
33641
33760
|
};
|
33642
33761
|
});
|
33643
33762
|
|
33644
|
-
// Included from: js/tinymce/classes/
|
33763
|
+
// Included from: js/tinymce/classes/file/Conversions.js
|
33645
33764
|
|
33646
33765
|
/**
|
33647
|
-
*
|
33766
|
+
* Conversions.js
|
33648
33767
|
*
|
33649
33768
|
* Released under LGPL License.
|
33650
33769
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -33654,302 +33773,254 @@ define("tinymce/EditorUpload", [
|
|
33654
33773
|
*/
|
33655
33774
|
|
33656
33775
|
/**
|
33657
|
-
*
|
33776
|
+
* Converts blob/uris back and forth.
|
33658
33777
|
*
|
33659
33778
|
* @private
|
33660
|
-
* @class tinymce.
|
33779
|
+
* @class tinymce.file.Conversions
|
33661
33780
|
*/
|
33662
|
-
define("tinymce/
|
33663
|
-
"tinymce/util/
|
33664
|
-
|
33665
|
-
|
33666
|
-
|
33667
|
-
|
33668
|
-
"tinymce/caret/CaretCandidate"
|
33669
|
-
], function(Fun, TreeWalker, NodeType, CaretPosition, CaretContainer, CaretCandidate) {
|
33670
|
-
var isContentEditableTrue = NodeType.isContentEditableTrue,
|
33671
|
-
isContentEditableFalse = NodeType.isContentEditableFalse,
|
33672
|
-
isBlockLike = NodeType.matchStyleValues('display', 'block table table-cell table-caption'),
|
33673
|
-
isCaretContainer = CaretContainer.isCaretContainer,
|
33674
|
-
curry = Fun.curry,
|
33675
|
-
isElement = NodeType.isElement,
|
33676
|
-
isCaretCandidate = CaretCandidate.isCaretCandidate;
|
33677
|
-
|
33678
|
-
function isForwards(direction) {
|
33679
|
-
return direction > 0;
|
33680
|
-
}
|
33681
|
-
|
33682
|
-
function isBackwards(direction) {
|
33683
|
-
return direction < 0;
|
33684
|
-
}
|
33781
|
+
define("tinymce/file/Conversions", [
|
33782
|
+
"tinymce/util/Promise"
|
33783
|
+
], function(Promise) {
|
33784
|
+
function blobUriToBlob(url) {
|
33785
|
+
return new Promise(function(resolve) {
|
33786
|
+
var xhr = new XMLHttpRequest();
|
33685
33787
|
|
33686
|
-
|
33687
|
-
|
33788
|
+
xhr.open('GET', url, true);
|
33789
|
+
xhr.responseType = 'blob';
|
33688
33790
|
|
33689
|
-
|
33690
|
-
|
33691
|
-
|
33692
|
-
if (predicateFn(node)) {
|
33693
|
-
return node;
|
33791
|
+
xhr.onload = function() {
|
33792
|
+
if (this.status == 200) {
|
33793
|
+
resolve(this.response);
|
33694
33794
|
}
|
33695
|
-
}
|
33795
|
+
};
|
33696
33796
|
|
33697
|
-
|
33698
|
-
|
33699
|
-
|
33700
|
-
}
|
33701
|
-
}
|
33702
|
-
}
|
33797
|
+
xhr.send();
|
33798
|
+
});
|
33799
|
+
}
|
33703
33800
|
|
33704
|
-
|
33705
|
-
|
33706
|
-
node = walker.next(true);
|
33707
|
-
if (predicateFn(node)) {
|
33708
|
-
return node;
|
33709
|
-
}
|
33710
|
-
}
|
33801
|
+
function parseDataUri(uri) {
|
33802
|
+
var type, matches;
|
33711
33803
|
|
33712
|
-
|
33713
|
-
|
33714
|
-
|
33715
|
-
|
33716
|
-
|
33804
|
+
uri = decodeURIComponent(uri).split(',');
|
33805
|
+
|
33806
|
+
matches = /data:([^;]+)/.exec(uri[0]);
|
33807
|
+
if (matches) {
|
33808
|
+
type = matches[1];
|
33717
33809
|
}
|
33718
33810
|
|
33719
|
-
return
|
33811
|
+
return {
|
33812
|
+
type: type,
|
33813
|
+
data: uri[1]
|
33814
|
+
};
|
33720
33815
|
}
|
33721
33816
|
|
33722
|
-
function
|
33723
|
-
|
33724
|
-
|
33725
|
-
return node;
|
33726
|
-
}
|
33727
|
-
}
|
33817
|
+
function dataUriToBlob(uri) {
|
33818
|
+
return new Promise(function(resolve) {
|
33819
|
+
var str, arr, i;
|
33728
33820
|
|
33729
|
-
|
33730
|
-
}
|
33821
|
+
uri = parseDataUri(uri);
|
33731
33822
|
|
33732
|
-
|
33733
|
-
|
33734
|
-
|
33735
|
-
|
33823
|
+
// Might throw error if data isn't proper base64
|
33824
|
+
try {
|
33825
|
+
str = atob(uri.data);
|
33826
|
+
} catch (e) {
|
33827
|
+
resolve(new Blob([]));
|
33828
|
+
return;
|
33736
33829
|
}
|
33737
33830
|
|
33738
|
-
|
33739
|
-
}
|
33740
|
-
|
33741
|
-
return null;
|
33742
|
-
}
|
33831
|
+
arr = new Uint8Array(str.length);
|
33743
33832
|
|
33744
|
-
|
33745
|
-
|
33746
|
-
|
33833
|
+
for (i = 0; i < arr.length; i++) {
|
33834
|
+
arr[i] = str.charCodeAt(i);
|
33835
|
+
}
|
33747
33836
|
|
33748
|
-
|
33749
|
-
|
33837
|
+
resolve(new Blob([arr], {type: uri.type}));
|
33838
|
+
});
|
33750
33839
|
}
|
33751
33840
|
|
33752
|
-
function
|
33753
|
-
|
33754
|
-
|
33755
|
-
if (!caretPosition) {
|
33756
|
-
return null;
|
33841
|
+
function uriToBlob(url) {
|
33842
|
+
if (url.indexOf('blob:') === 0) {
|
33843
|
+
return blobUriToBlob(url);
|
33757
33844
|
}
|
33758
33845
|
|
33759
|
-
|
33760
|
-
|
33761
|
-
|
33762
|
-
if (!isElement(container)) {
|
33763
|
-
return null;
|
33846
|
+
if (url.indexOf('data:') === 0) {
|
33847
|
+
return dataUriToBlob(url);
|
33764
33848
|
}
|
33765
33849
|
|
33766
|
-
return
|
33850
|
+
return null;
|
33767
33851
|
}
|
33768
33852
|
|
33769
|
-
function
|
33770
|
-
|
33771
|
-
|
33772
|
-
if (before) {
|
33773
|
-
range.setStartBefore(node);
|
33774
|
-
range.setEndBefore(node);
|
33775
|
-
} else {
|
33776
|
-
range.setStartAfter(node);
|
33777
|
-
range.setEndAfter(node);
|
33778
|
-
}
|
33853
|
+
function blobToDataUri(blob) {
|
33854
|
+
return new Promise(function(resolve) {
|
33855
|
+
var reader = new FileReader();
|
33779
33856
|
|
33780
|
-
|
33781
|
-
|
33857
|
+
reader.onloadend = function() {
|
33858
|
+
resolve(reader.result);
|
33859
|
+
};
|
33782
33860
|
|
33783
|
-
|
33784
|
-
|
33861
|
+
reader.readAsDataURL(blob);
|
33862
|
+
});
|
33785
33863
|
}
|
33786
33864
|
|
33787
|
-
|
33788
|
-
|
33789
|
-
|
33790
|
-
|
33791
|
-
|
33792
|
-
|
33793
|
-
siblingName = 'nextSibling';
|
33794
|
-
}
|
33795
|
-
|
33796
|
-
while (node && node != rootNode) {
|
33797
|
-
sibling = node[siblingName];
|
33865
|
+
return {
|
33866
|
+
uriToBlob: uriToBlob,
|
33867
|
+
blobToDataUri: blobToDataUri,
|
33868
|
+
parseDataUri: parseDataUri
|
33869
|
+
};
|
33870
|
+
});
|
33798
33871
|
|
33799
|
-
|
33800
|
-
sibling = sibling[siblingName];
|
33801
|
-
}
|
33872
|
+
// Included from: js/tinymce/classes/file/ImageScanner.js
|
33802
33873
|
|
33803
|
-
|
33804
|
-
|
33805
|
-
|
33806
|
-
|
33874
|
+
/**
|
33875
|
+
* ImageScanner.js
|
33876
|
+
*
|
33877
|
+
* Released under LGPL License.
|
33878
|
+
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
33879
|
+
*
|
33880
|
+
* License: http://www.tinymce.com/license
|
33881
|
+
* Contributing: http://www.tinymce.com/contributing
|
33882
|
+
*/
|
33807
33883
|
|
33808
|
-
|
33809
|
-
|
33884
|
+
/**
|
33885
|
+
* Finds images with data uris or blob uris. If data uris are found it will convert them into blob uris.
|
33886
|
+
*
|
33887
|
+
* @private
|
33888
|
+
* @class tinymce.file.ImageScanner
|
33889
|
+
*/
|
33890
|
+
define("tinymce/file/ImageScanner", [
|
33891
|
+
"tinymce/util/Promise",
|
33892
|
+
"tinymce/util/Arr",
|
33893
|
+
"tinymce/util/Fun",
|
33894
|
+
"tinymce/file/Conversions",
|
33895
|
+
"tinymce/Env"
|
33896
|
+
], function(Promise, Arr, Fun, Conversions, Env) {
|
33897
|
+
var count = 0;
|
33810
33898
|
|
33811
|
-
|
33812
|
-
|
33813
|
-
}
|
33899
|
+
return function(blobCache) {
|
33900
|
+
var cachedPromises = {};
|
33814
33901
|
|
33815
|
-
|
33816
|
-
|
33902
|
+
function findAll(elm, predicate) {
|
33903
|
+
var images, promises;
|
33817
33904
|
|
33818
|
-
|
33819
|
-
|
33905
|
+
function imageToBlobInfo(img, resolve) {
|
33906
|
+
var base64, blobInfo;
|
33820
33907
|
|
33821
|
-
|
33822
|
-
|
33908
|
+
if (img.src.indexOf('blob:') === 0) {
|
33909
|
+
blobInfo = blobCache.getByUri(img.src);
|
33823
33910
|
|
33824
|
-
|
33825
|
-
|
33826
|
-
|
33827
|
-
|
33911
|
+
if (blobInfo) {
|
33912
|
+
resolve({
|
33913
|
+
image: img,
|
33914
|
+
blobInfo: blobInfo
|
33915
|
+
});
|
33916
|
+
}
|
33828
33917
|
|
33829
|
-
|
33830
|
-
|
33918
|
+
return;
|
33919
|
+
}
|
33831
33920
|
|
33832
|
-
|
33833
|
-
|
33834
|
-
|
33835
|
-
|
33921
|
+
base64 = Conversions.parseDataUri(img.src).data;
|
33922
|
+
blobInfo = blobCache.findFirst(function(cachedBlobInfo) {
|
33923
|
+
return cachedBlobInfo.base64() === base64;
|
33924
|
+
});
|
33836
33925
|
|
33837
|
-
|
33926
|
+
if (blobInfo) {
|
33927
|
+
resolve({
|
33928
|
+
image: img,
|
33929
|
+
blobInfo: blobInfo
|
33930
|
+
});
|
33931
|
+
} else {
|
33932
|
+
Conversions.uriToBlob(img.src).then(function(blob) {
|
33933
|
+
var blobInfoId = 'blobid' + (count++),
|
33934
|
+
blobInfo = blobCache.create(blobInfoId, blob, base64);
|
33838
33935
|
|
33839
|
-
|
33840
|
-
node = container.nextSibling;
|
33841
|
-
if (isContentEditableFalse(node)) {
|
33842
|
-
return before(node);
|
33843
|
-
}
|
33844
|
-
}
|
33936
|
+
blobCache.add(blobInfo);
|
33845
33937
|
|
33846
|
-
|
33847
|
-
|
33848
|
-
|
33849
|
-
|
33938
|
+
resolve({
|
33939
|
+
image: img,
|
33940
|
+
blobInfo: blobInfo
|
33941
|
+
});
|
33942
|
+
});
|
33850
33943
|
}
|
33851
33944
|
}
|
33852
|
-
}
|
33853
33945
|
|
33854
|
-
|
33855
|
-
|
33856
|
-
|
33946
|
+
if (!predicate) {
|
33947
|
+
predicate = Fun.constant(true);
|
33948
|
+
}
|
33857
33949
|
|
33858
|
-
|
33859
|
-
|
33860
|
-
if (direction === 1) {
|
33861
|
-
node = leanRight(container);
|
33862
|
-
if (node) {
|
33863
|
-
return before(node);
|
33864
|
-
}
|
33950
|
+
images = Arr.filter(elm.getElementsByTagName('img'), function(img) {
|
33951
|
+
var src = img.src;
|
33865
33952
|
|
33866
|
-
|
33867
|
-
|
33868
|
-
return after(node);
|
33869
|
-
}
|
33953
|
+
if (!Env.fileApi) {
|
33954
|
+
return false;
|
33870
33955
|
}
|
33871
33956
|
|
33872
|
-
if (
|
33873
|
-
|
33874
|
-
if (node) {
|
33875
|
-
return after(node);
|
33876
|
-
}
|
33877
|
-
|
33878
|
-
node = leanRight(container);
|
33879
|
-
if (node) {
|
33880
|
-
return before(node);
|
33881
|
-
}
|
33957
|
+
if (img.hasAttribute('data-mce-bogus')) {
|
33958
|
+
return false;
|
33882
33959
|
}
|
33883
33960
|
|
33884
|
-
|
33885
|
-
|
33886
|
-
|
33887
|
-
if (CaretContainer.endsWithCaretContainer(container) && offset >= container.data.length - 1) {
|
33888
|
-
if (direction === 1) {
|
33889
|
-
node = leanRight(container);
|
33890
|
-
if (node) {
|
33891
|
-
return before(node);
|
33892
|
-
}
|
33961
|
+
if (img.hasAttribute('data-mce-placeholder')) {
|
33962
|
+
return false;
|
33893
33963
|
}
|
33894
33964
|
|
33895
|
-
|
33896
|
-
|
33897
|
-
|
33898
|
-
if (CaretContainer.startsWithCaretContainer(container) && offset <= 1) {
|
33899
|
-
if (direction === -1) {
|
33900
|
-
node = leanLeft(container);
|
33901
|
-
if (node) {
|
33902
|
-
return after(node);
|
33903
|
-
}
|
33965
|
+
if (!src || src == Env.transparentSrc) {
|
33966
|
+
return false;
|
33904
33967
|
}
|
33905
33968
|
|
33906
|
-
|
33907
|
-
|
33969
|
+
if (src.indexOf('blob:') === 0) {
|
33970
|
+
return true;
|
33971
|
+
}
|
33908
33972
|
|
33909
|
-
|
33910
|
-
|
33911
|
-
if (node) {
|
33912
|
-
return before(node);
|
33973
|
+
if (src.indexOf('data:') === 0) {
|
33974
|
+
return predicate(img);
|
33913
33975
|
}
|
33914
33976
|
|
33915
|
-
return
|
33916
|
-
}
|
33977
|
+
return false;
|
33978
|
+
});
|
33917
33979
|
|
33918
|
-
|
33919
|
-
|
33920
|
-
|
33921
|
-
|
33980
|
+
promises = Arr.map(images, function(img) {
|
33981
|
+
var newPromise;
|
33982
|
+
|
33983
|
+
if (cachedPromises[img.src]) {
|
33984
|
+
// Since the cached promise will return the cached image
|
33985
|
+
// We need to wrap it and resolve with the actual image
|
33986
|
+
return new Promise(function(resolve) {
|
33987
|
+
cachedPromises[img.src].then(function(imageInfo) {
|
33988
|
+
resolve({
|
33989
|
+
image: img,
|
33990
|
+
blobInfo: imageInfo.blobInfo
|
33991
|
+
});
|
33992
|
+
});
|
33993
|
+
});
|
33922
33994
|
}
|
33923
33995
|
|
33924
|
-
|
33925
|
-
|
33926
|
-
|
33996
|
+
newPromise = new Promise(function(resolve) {
|
33997
|
+
imageToBlobInfo(img, resolve);
|
33998
|
+
}).then(function(result) {
|
33999
|
+
delete cachedPromises[result.image.src];
|
34000
|
+
return result;
|
34001
|
+
})['catch'](function(error) {
|
34002
|
+
delete cachedPromises[img.src];
|
34003
|
+
return error;
|
34004
|
+
});
|
33927
34005
|
|
33928
|
-
|
33929
|
-
}
|
34006
|
+
cachedPromises[img.src] = newPromise;
|
33930
34007
|
|
33931
|
-
|
33932
|
-
|
33933
|
-
}
|
34008
|
+
return newPromise;
|
34009
|
+
});
|
33934
34010
|
|
33935
|
-
|
33936
|
-
|
33937
|
-
|
33938
|
-
|
33939
|
-
|
33940
|
-
|
33941
|
-
isInSameBlock: isInSameBlock,
|
33942
|
-
isInSameEditingHost: isInSameEditingHost,
|
33943
|
-
isBeforeContentEditableFalse: curry(isNextToContentEditableFalse, 0),
|
33944
|
-
isAfterContentEditableFalse: curry(isNextToContentEditableFalse, -1),
|
33945
|
-
normalizeRange: normalizeRange
|
34011
|
+
return Promise.all(promises);
|
34012
|
+
}
|
34013
|
+
|
34014
|
+
return {
|
34015
|
+
findAll: findAll
|
34016
|
+
};
|
33946
34017
|
};
|
33947
34018
|
});
|
33948
34019
|
|
33949
|
-
// Included from: js/tinymce/classes/
|
34020
|
+
// Included from: js/tinymce/classes/file/BlobCache.js
|
33950
34021
|
|
33951
34022
|
/**
|
33952
|
-
*
|
34023
|
+
* BlobCache.js
|
33953
34024
|
*
|
33954
34025
|
* Released under LGPL License.
|
33955
34026
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
@@ -33959,207 +34030,258 @@ define("tinymce/caret/CaretUtils", [
|
|
33959
34030
|
*/
|
33960
34031
|
|
33961
34032
|
/**
|
33962
|
-
*
|
33963
|
-
*
|
33964
|
-
* It ignores the most obvious invalid caret locations such as within a script element or within a
|
33965
|
-
* contentEditable=false element but it will return locations that isn't possible to render visually.
|
34033
|
+
* Hold blob info objects where a blob has extra internal information.
|
33966
34034
|
*
|
33967
34035
|
* @private
|
33968
|
-
* @class tinymce.
|
33969
|
-
* @example
|
33970
|
-
* var caretWalker = new CaretWalker(rootElm);
|
33971
|
-
*
|
33972
|
-
* var prevLogicalCaretPosition = caretWalker.prev(CaretPosition.fromRangeStart(range));
|
33973
|
-
* var nextLogicalCaretPosition = caretWalker.next(CaretPosition.fromRangeEnd(range));
|
34036
|
+
* @class tinymce.file.BlobCache
|
33974
34037
|
*/
|
33975
|
-
define("tinymce/
|
33976
|
-
"tinymce/dom/NodeType",
|
33977
|
-
"tinymce/caret/CaretCandidate",
|
33978
|
-
"tinymce/caret/CaretPosition",
|
33979
|
-
"tinymce/caret/CaretUtils",
|
34038
|
+
define("tinymce/file/BlobCache", [
|
33980
34039
|
"tinymce/util/Arr",
|
33981
34040
|
"tinymce/util/Fun"
|
33982
|
-
], function(
|
33983
|
-
|
33984
|
-
|
33985
|
-
isElement = NodeType.isElement,
|
33986
|
-
isForwards = CaretUtils.isForwards,
|
33987
|
-
isBackwards = CaretUtils.isBackwards,
|
33988
|
-
isCaretCandidate = CaretCandidate.isCaretCandidate,
|
33989
|
-
isAtomic = CaretCandidate.isAtomic,
|
33990
|
-
isEditableCaretCandidate = CaretCandidate.isEditableCaretCandidate;
|
34041
|
+
], function(Arr, Fun) {
|
34042
|
+
return function() {
|
34043
|
+
var cache = [], constant = Fun.constant;
|
33991
34044
|
|
33992
|
-
|
33993
|
-
|
34045
|
+
function create(id, blob, base64) {
|
34046
|
+
return {
|
34047
|
+
id: constant(id),
|
34048
|
+
blob: constant(blob),
|
34049
|
+
base64: constant(base64),
|
34050
|
+
blobUri: constant(URL.createObjectURL(blob))
|
34051
|
+
};
|
34052
|
+
}
|
33994
34053
|
|
33995
|
-
|
33996
|
-
|
33997
|
-
|
34054
|
+
function add(blobInfo) {
|
34055
|
+
if (!get(blobInfo.id())) {
|
34056
|
+
cache.push(blobInfo);
|
34057
|
+
}
|
33998
34058
|
}
|
33999
34059
|
|
34000
|
-
|
34001
|
-
|
34060
|
+
function get(id) {
|
34061
|
+
return findFirst(function(cachedBlobInfo) {
|
34062
|
+
return cachedBlobInfo.id() === id;
|
34063
|
+
});
|
34064
|
+
}
|
34002
34065
|
|
34003
|
-
|
34004
|
-
|
34005
|
-
return container.childNodes[offset];
|
34066
|
+
function findFirst(predicate) {
|
34067
|
+
return Arr.filter(cache, predicate)[0];
|
34006
34068
|
}
|
34007
34069
|
|
34008
|
-
|
34009
|
-
|
34070
|
+
function getByUri(blobUri) {
|
34071
|
+
return findFirst(function(blobInfo) {
|
34072
|
+
return blobInfo.blobUri() == blobUri;
|
34073
|
+
});
|
34074
|
+
}
|
34010
34075
|
|
34011
|
-
|
34012
|
-
|
34013
|
-
|
34014
|
-
|
34015
|
-
}
|
34076
|
+
function destroy() {
|
34077
|
+
Arr.each(cache, function(cachedBlobInfo) {
|
34078
|
+
URL.revokeObjectURL(cachedBlobInfo.blobUri());
|
34079
|
+
});
|
34016
34080
|
|
34017
|
-
|
34018
|
-
return CaretPosition(node, 0);
|
34019
|
-
}
|
34081
|
+
cache = [];
|
34020
34082
|
}
|
34021
34083
|
|
34022
|
-
|
34023
|
-
|
34024
|
-
|
34025
|
-
|
34084
|
+
return {
|
34085
|
+
create: create,
|
34086
|
+
add: add,
|
34087
|
+
get: get,
|
34088
|
+
getByUri: getByUri,
|
34089
|
+
findFirst: findFirst,
|
34090
|
+
destroy: destroy
|
34091
|
+
};
|
34092
|
+
};
|
34093
|
+
});
|
34026
34094
|
|
34027
|
-
|
34028
|
-
|
34029
|
-
|
34095
|
+
// Included from: js/tinymce/classes/EditorUpload.js
|
34096
|
+
|
34097
|
+
/**
|
34098
|
+
* EditorUpload.js
|
34099
|
+
*
|
34100
|
+
* Released under LGPL License.
|
34101
|
+
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
34102
|
+
*
|
34103
|
+
* License: http://www.tinymce.com/license
|
34104
|
+
* Contributing: http://www.tinymce.com/contributing
|
34105
|
+
*/
|
34106
|
+
|
34107
|
+
/**
|
34108
|
+
* Handles image uploads, updates undo stack and patches over various internal functions.
|
34109
|
+
*
|
34110
|
+
* @private
|
34111
|
+
* @class tinymce.EditorUpload
|
34112
|
+
*/
|
34113
|
+
define("tinymce/EditorUpload", [
|
34114
|
+
"tinymce/util/Arr",
|
34115
|
+
"tinymce/file/Uploader",
|
34116
|
+
"tinymce/file/ImageScanner",
|
34117
|
+
"tinymce/file/BlobCache"
|
34118
|
+
], function(Arr, Uploader, ImageScanner, BlobCache) {
|
34119
|
+
return function(editor) {
|
34120
|
+
var blobCache = new BlobCache(), uploader, imageScanner, settings = editor.settings;
|
34121
|
+
|
34122
|
+
function aliveGuard(callback) {
|
34123
|
+
return function(result) {
|
34124
|
+
if (editor.selection) {
|
34125
|
+
return callback(result);
|
34126
|
+
}
|
34127
|
+
|
34128
|
+
return [];
|
34129
|
+
};
|
34030
34130
|
}
|
34031
34131
|
|
34032
|
-
|
34033
|
-
|
34132
|
+
// Replaces strings without regexps to avoid FF regexp to big issue
|
34133
|
+
function replaceString(content, search, replace) {
|
34134
|
+
var index = 0;
|
34135
|
+
|
34136
|
+
do {
|
34137
|
+
index = content.indexOf(search, index);
|
34138
|
+
|
34139
|
+
if (index !== -1) {
|
34140
|
+
content = content.substring(0, index) + replace + content.substr(index + search.length);
|
34141
|
+
index += replace.length - search.length + 1;
|
34142
|
+
}
|
34143
|
+
} while (index !== -1);
|
34144
|
+
|
34145
|
+
return content;
|
34034
34146
|
}
|
34035
34147
|
|
34036
|
-
|
34037
|
-
|
34148
|
+
function replaceImageUrl(content, targetUrl, replacementUrl) {
|
34149
|
+
content = replaceString(content, 'src="' + targetUrl + '"', 'src="' + replacementUrl + '"');
|
34150
|
+
content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"');
|
34038
34151
|
|
34039
|
-
|
34040
|
-
|
34041
|
-
rootContentEditableFalseElm, caretPosition;
|
34152
|
+
return content;
|
34153
|
+
}
|
34042
34154
|
|
34043
|
-
|
34044
|
-
|
34155
|
+
function replaceUrlInUndoStack(targetUrl, replacementUrl) {
|
34156
|
+
Arr.each(editor.undoManager.data, function(level) {
|
34157
|
+
level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
|
34158
|
+
});
|
34045
34159
|
}
|
34046
34160
|
|
34047
|
-
|
34048
|
-
|
34049
|
-
|
34161
|
+
function openNotification() {
|
34162
|
+
return editor.notificationManager.open({
|
34163
|
+
text: editor.translate('Image uploading...'),
|
34164
|
+
type: 'info',
|
34165
|
+
timeout: -1,
|
34166
|
+
progressBar: true
|
34167
|
+
});
|
34168
|
+
}
|
34050
34169
|
|
34051
|
-
|
34052
|
-
if (
|
34053
|
-
|
34170
|
+
function uploadImages(callback) {
|
34171
|
+
if (!uploader) {
|
34172
|
+
uploader = new Uploader({
|
34173
|
+
url: settings.images_upload_url,
|
34174
|
+
basePath: settings.images_upload_base_path,
|
34175
|
+
credentials: settings.images_upload_credentials,
|
34176
|
+
handler: settings.images_upload_handler
|
34177
|
+
});
|
34054
34178
|
}
|
34055
34179
|
|
34056
|
-
|
34057
|
-
|
34058
|
-
}
|
34180
|
+
return scanForImages().then(aliveGuard(function(imageInfos) {
|
34181
|
+
var blobInfos;
|
34059
34182
|
|
34060
|
-
|
34061
|
-
|
34062
|
-
|
34063
|
-
nextNode = nodeAtIndex(container, offset - 1);
|
34064
|
-
if (isCaretCandidate(nextNode)) {
|
34065
|
-
if (!isAtomic(nextNode)) {
|
34066
|
-
innerNode = CaretUtils.findNode(nextNode, direction, isEditableCaretCandidate, nextNode);
|
34067
|
-
if (innerNode) {
|
34068
|
-
if (isText(innerNode)) {
|
34069
|
-
return CaretPosition(innerNode, innerNode.data.length);
|
34070
|
-
}
|
34183
|
+
blobInfos = Arr.map(imageInfos, function(imageInfo) {
|
34184
|
+
return imageInfo.blobInfo;
|
34185
|
+
});
|
34071
34186
|
|
34072
|
-
|
34073
|
-
|
34074
|
-
|
34187
|
+
return uploader.upload(blobInfos, openNotification).then(aliveGuard(function(result) {
|
34188
|
+
result = Arr.map(result, function(uploadInfo, index) {
|
34189
|
+
var image = imageInfos[index].image;
|
34075
34190
|
|
34076
|
-
|
34077
|
-
|
34078
|
-
}
|
34191
|
+
if (uploadInfo.status) {
|
34192
|
+
replaceUrlInUndoStack(image.src, uploadInfo.url);
|
34079
34193
|
|
34080
|
-
|
34081
|
-
|
34082
|
-
|
34194
|
+
editor.$(image).attr({
|
34195
|
+
src: uploadInfo.url,
|
34196
|
+
'data-mce-src': editor.convertURL(uploadInfo.url, 'src')
|
34197
|
+
});
|
34198
|
+
}
|
34083
34199
|
|
34084
|
-
|
34085
|
-
|
34086
|
-
|
34087
|
-
|
34088
|
-
|
34089
|
-
if (innerNode) {
|
34090
|
-
if (isText(innerNode)) {
|
34091
|
-
return CaretPosition(innerNode, 0);
|
34092
|
-
}
|
34200
|
+
return {
|
34201
|
+
element: image,
|
34202
|
+
status: uploadInfo.status
|
34203
|
+
};
|
34204
|
+
});
|
34093
34205
|
|
34094
|
-
|
34095
|
-
|
34206
|
+
if (callback) {
|
34207
|
+
callback(result);
|
34096
34208
|
}
|
34097
34209
|
|
34098
|
-
|
34099
|
-
|
34100
|
-
|
34210
|
+
return result;
|
34211
|
+
}));
|
34212
|
+
}));
|
34213
|
+
}
|
34101
34214
|
|
34102
|
-
|
34103
|
-
|
34215
|
+
function uploadImagesAuto(callback) {
|
34216
|
+
if (settings.automatic_uploads !== false) {
|
34217
|
+
return uploadImages(callback);
|
34104
34218
|
}
|
34105
|
-
|
34106
|
-
node = caretPosition.getNode();
|
34107
34219
|
}
|
34108
34220
|
|
34109
|
-
|
34110
|
-
|
34111
|
-
|
34112
|
-
return getCaretCandidatePosition(direction, node);
|
34221
|
+
function scanForImages() {
|
34222
|
+
if (!imageScanner) {
|
34223
|
+
imageScanner = new ImageScanner(blobCache);
|
34113
34224
|
}
|
34114
|
-
}
|
34115
34225
|
|
34116
|
-
|
34226
|
+
return imageScanner.findAll(editor.getBody(), settings.images_dataimg_filter).then(aliveGuard(function(result) {
|
34227
|
+
Arr.each(result, function(resultItem) {
|
34228
|
+
replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
|
34229
|
+
resultItem.image.src = resultItem.blobInfo.blobUri();
|
34230
|
+
});
|
34117
34231
|
|
34118
|
-
|
34119
|
-
|
34120
|
-
|
34121
|
-
caretPosition = CaretPosition.after(rootContentEditableFalseElm);
|
34122
|
-
} else {
|
34123
|
-
caretPosition = CaretPosition.before(rootContentEditableFalseElm);
|
34124
|
-
}
|
34232
|
+
return result;
|
34233
|
+
}));
|
34234
|
+
}
|
34125
34235
|
|
34126
|
-
|
34236
|
+
function destroy() {
|
34237
|
+
blobCache.destroy();
|
34238
|
+
imageScanner = uploader = null;
|
34127
34239
|
}
|
34128
34240
|
|
34129
|
-
|
34130
|
-
return
|
34241
|
+
function replaceBlobWithBase64(content) {
|
34242
|
+
return content.replace(/src="(blob:[^"]+)"/g, function(match, blobUri) {
|
34243
|
+
var blobInfo = blobCache.getByUri(blobUri);
|
34244
|
+
|
34245
|
+
if (!blobInfo) {
|
34246
|
+
blobInfo = Arr.reduce(editor.editorManager.editors, function(result, editor) {
|
34247
|
+
return result || editor.editorUpload.blobCache.getByUri(blobUri);
|
34248
|
+
}, null);
|
34249
|
+
}
|
34250
|
+
|
34251
|
+
if (blobInfo) {
|
34252
|
+
return 'src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '"';
|
34253
|
+
}
|
34254
|
+
|
34255
|
+
return match;
|
34256
|
+
});
|
34131
34257
|
}
|
34132
34258
|
|
34133
|
-
|
34134
|
-
|
34259
|
+
editor.on('setContent', function() {
|
34260
|
+
if (editor.settings.automatic_uploads !== false) {
|
34261
|
+
uploadImagesAuto();
|
34262
|
+
} else {
|
34263
|
+
scanForImages();
|
34264
|
+
}
|
34265
|
+
});
|
34135
34266
|
|
34136
|
-
|
34137
|
-
|
34138
|
-
|
34139
|
-
* Returns the next logical caret position from the specificed input
|
34140
|
-
* caretPoisiton or null if there isn't any more positions left for example
|
34141
|
-
* at the end specified root element.
|
34142
|
-
*
|
34143
|
-
* @method next
|
34144
|
-
* @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from.
|
34145
|
-
* @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found.
|
34146
|
-
*/
|
34147
|
-
next: function(caretPosition) {
|
34148
|
-
return findCaretPosition(1, caretPosition, rootNode);
|
34149
|
-
},
|
34267
|
+
editor.on('RawSaveContent', function(e) {
|
34268
|
+
e.content = replaceBlobWithBase64(e.content);
|
34269
|
+
});
|
34150
34270
|
|
34151
|
-
|
34152
|
-
|
34153
|
-
|
34154
|
-
* at the end specified root element.
|
34155
|
-
*
|
34156
|
-
* @method prev
|
34157
|
-
* @param {tinymce.caret.CaretPosition} caretPosition Caret position to start from.
|
34158
|
-
* @return {tinymce.caret.CaretPosition} CaretPosition or null if no position was found.
|
34159
|
-
*/
|
34160
|
-
prev: function(caretPosition) {
|
34161
|
-
return findCaretPosition(-1, caretPosition, rootNode);
|
34271
|
+
editor.on('getContent', function(e) {
|
34272
|
+
if (e.source_view || e.format == 'raw') {
|
34273
|
+
return;
|
34162
34274
|
}
|
34275
|
+
|
34276
|
+
e.content = replaceBlobWithBase64(e.content);
|
34277
|
+
});
|
34278
|
+
|
34279
|
+
return {
|
34280
|
+
blobCache: blobCache,
|
34281
|
+
uploadImages: uploadImages,
|
34282
|
+
uploadImagesAuto: uploadImagesAuto,
|
34283
|
+
scanForImages: scanForImages,
|
34284
|
+
destroy: destroy
|
34163
34285
|
};
|
34164
34286
|
};
|
34165
34287
|
});
|
@@ -35877,10 +35999,11 @@ define("tinymce/Editor", [
|
|
35877
35999
|
* @param {tinymce.EditorManager} editorManager EditorManager instance.
|
35878
36000
|
*/
|
35879
36001
|
function Editor(id, settings, editorManager) {
|
35880
|
-
var self = this, documentBaseUrl, baseUri;
|
36002
|
+
var self = this, documentBaseUrl, baseUri, defaultSettings;
|
35881
36003
|
|
35882
36004
|
documentBaseUrl = self.documentBaseUrl = editorManager.documentBaseURL;
|
35883
36005
|
baseUri = editorManager.baseURI;
|
36006
|
+
defaultSettings = editorManager.defaultSettings;
|
35884
36007
|
|
35885
36008
|
/**
|
35886
36009
|
* Name/value collection with editor settings.
|
@@ -35891,7 +36014,7 @@ define("tinymce/Editor", [
|
|
35891
36014
|
* // Get the value of the theme setting
|
35892
36015
|
* tinymce.activeEditor.windowManager.alert("You are using the " + tinymce.activeEditor.settings.theme + " theme");
|
35893
36016
|
*/
|
35894
|
-
|
36017
|
+
settings = extend({
|
35895
36018
|
id: id,
|
35896
36019
|
theme: 'modern',
|
35897
36020
|
delta_width: 0,
|
@@ -35929,11 +36052,16 @@ define("tinymce/Editor", [
|
|
35929
36052
|
url_converter: self.convertURL,
|
35930
36053
|
url_converter_scope: self,
|
35931
36054
|
ie7_compat: true
|
35932
|
-
},
|
36055
|
+
}, defaultSettings, settings);
|
36056
|
+
|
36057
|
+
// Merge external_plugins
|
36058
|
+
if (defaultSettings && defaultSettings.external_plugins && settings.external_plugins) {
|
36059
|
+
settings.external_plugins = extend({}, defaultSettings.external_plugins, settings.external_plugins);
|
36060
|
+
}
|
35933
36061
|
|
36062
|
+
self.settings = settings;
|
35934
36063
|
AddOnManager.language = settings.language || 'en';
|
35935
36064
|
AddOnManager.languageLoad = settings.language_load;
|
35936
|
-
|
35937
36065
|
AddOnManager.baseURL = editorManager.baseURL;
|
35938
36066
|
|
35939
36067
|
/**
|
@@ -38425,16 +38553,20 @@ define("tinymce/EditorManager", [
|
|
38425
38553
|
|
38426
38554
|
function globalEventDelegate(e) {
|
38427
38555
|
each(EditorManager.editors, function(editor) {
|
38428
|
-
|
38556
|
+
if (e.type === 'scroll') {
|
38557
|
+
editor.fire('ScrollWindow', e);
|
38558
|
+
} else {
|
38559
|
+
editor.fire('ResizeWindow', e);
|
38560
|
+
}
|
38429
38561
|
});
|
38430
38562
|
}
|
38431
38563
|
|
38432
38564
|
function toggleGlobalEvents(editors, state) {
|
38433
38565
|
if (state !== boundGlobalEvents) {
|
38434
38566
|
if (state) {
|
38435
|
-
$(window).on('resize', globalEventDelegate);
|
38567
|
+
$(window).on('resize scroll', globalEventDelegate);
|
38436
38568
|
} else {
|
38437
|
-
$(window).off('resize', globalEventDelegate);
|
38569
|
+
$(window).off('resize scroll', globalEventDelegate);
|
38438
38570
|
}
|
38439
38571
|
|
38440
38572
|
boundGlobalEvents = state;
|
@@ -38502,7 +38634,7 @@ define("tinymce/EditorManager", [
|
|
38502
38634
|
* @property minorVersion
|
38503
38635
|
* @type String
|
38504
38636
|
*/
|
38505
|
-
minorVersion: '3.
|
38637
|
+
minorVersion: '3.8',
|
38506
38638
|
|
38507
38639
|
/**
|
38508
38640
|
* Release date of TinyMCE build.
|
@@ -38510,7 +38642,7 @@ define("tinymce/EditorManager", [
|
|
38510
38642
|
* @property releaseDate
|
38511
38643
|
* @type String
|
38512
38644
|
*/
|
38513
|
-
releaseDate: '2016-03-
|
38645
|
+
releaseDate: '2016-03-15',
|
38514
38646
|
|
38515
38647
|
/**
|
38516
38648
|
* Collection of editor instances.
|