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