wysihtml-rails 0.5.0.beta11 → 0.5.0.beta12
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/lib/wysihtml/rails/version.rb +1 -1
- data/vendor/assets/javascripts/wysihtml-toolbar.js +550 -255
- data/vendor/assets/javascripts/wysihtml.js +421 -170
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license wysihtml v0.5.0-
|
2
|
+
* @license wysihtml v0.5.0-beta12
|
3
3
|
* https://github.com/Voog/wysihtml
|
4
4
|
*
|
5
5
|
* Author: Christopher Blum (https://github.com/tiff)
|
@@ -10,7 +10,7 @@
|
|
10
10
|
*
|
11
11
|
*/
|
12
12
|
var wysihtml5 = {
|
13
|
-
version: "0.5.0-
|
13
|
+
version: "0.5.0-beta12",
|
14
14
|
|
15
15
|
// namespaces
|
16
16
|
commands: {},
|
@@ -5890,6 +5890,20 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
5890
5890
|
})(wysihtml5);
|
5891
5891
|
;// TODO: Refactor dom tree traversing here
|
5892
5892
|
(function(wysihtml5) {
|
5893
|
+
|
5894
|
+
// Finds parents of a node, returning the outermost node first in Array
|
5895
|
+
// if contain node is given parents search is stopped at the container
|
5896
|
+
function parents(node, container) {
|
5897
|
+
var nodes = [node], n = node;
|
5898
|
+
|
5899
|
+
// iterate parents while parent exists and it is not container element
|
5900
|
+
while((container && n && n !== container) || (!container && n)) {
|
5901
|
+
nodes.unshift(n);
|
5902
|
+
n = n.parentNode;
|
5903
|
+
}
|
5904
|
+
return nodes;
|
5905
|
+
}
|
5906
|
+
|
5893
5907
|
wysihtml5.dom.domNode = function(node) {
|
5894
5908
|
var defaultNodeTypes = [wysihtml5.ELEMENT_NODE, wysihtml5.TEXT_NODE];
|
5895
5909
|
|
@@ -5951,6 +5965,30 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
5951
5965
|
return nextNode;
|
5952
5966
|
},
|
5953
5967
|
|
5968
|
+
// Finds the common acnestor container of two nodes
|
5969
|
+
// If container given stops search at the container
|
5970
|
+
// If no common ancestor found returns null
|
5971
|
+
// var node = wysihtml5.dom.domNode(element).commonAncestor(node2, container);
|
5972
|
+
commonAncestor: function(node2, container) {
|
5973
|
+
var parents1 = parents(node, container),
|
5974
|
+
parents2 = parents(node2, container);
|
5975
|
+
|
5976
|
+
// Ensure we have found a common ancestor, which will be the first one if anything
|
5977
|
+
if (parents1[0] != parents2[0]) {
|
5978
|
+
return null;
|
5979
|
+
}
|
5980
|
+
|
5981
|
+
// Traverse up the hierarchy of parents until we reach where they're no longer
|
5982
|
+
// the same. Then return previous which was the common ancestor.
|
5983
|
+
for (var i = 0; i < parents1.length; i++) {
|
5984
|
+
if (parents1[i] != parents2[i]) {
|
5985
|
+
return parents1[i - 1];
|
5986
|
+
}
|
5987
|
+
}
|
5988
|
+
|
5989
|
+
return null;
|
5990
|
+
},
|
5991
|
+
|
5954
5992
|
// Traverses a node for last children and their chidren (including itself), and finds the last node that has no children.
|
5955
5993
|
// Array of classes for forced last-leaves (ex: uneditable-container) can be defined (options = {leafClasses: [...]})
|
5956
5994
|
// Useful for finding the actually visible element before cursor
|
@@ -7443,9 +7481,10 @@ wysihtml5.dom.removeEmptyTextNodes = function(node) {
|
|
7443
7481
|
childNodes = wysihtml5.lang.array(node.childNodes).get(),
|
7444
7482
|
childNodesLength = childNodes.length,
|
7445
7483
|
i = 0;
|
7484
|
+
|
7446
7485
|
for (; i<childNodesLength; i++) {
|
7447
7486
|
childNode = childNodes[i];
|
7448
|
-
if (childNode.nodeType === wysihtml5.TEXT_NODE && childNode.data
|
7487
|
+
if (childNode.nodeType === wysihtml5.TEXT_NODE && (/^[\n\r]*$/).test(childNode.data)) {
|
7449
7488
|
childNode.parentNode.removeChild(childNode);
|
7450
7489
|
}
|
7451
7490
|
}
|
@@ -7913,7 +7952,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
|
|
7913
7952
|
|
7914
7953
|
// initiates an allready existent contenteditable
|
7915
7954
|
_bindElement: function(contentEditable) {
|
7916
|
-
contentEditable.className =
|
7955
|
+
contentEditable.className = contentEditable.className ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
|
7917
7956
|
this._loadElement(contentEditable, true);
|
7918
7957
|
return contentEditable;
|
7919
7958
|
},
|
@@ -9430,71 +9469,140 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9430
9469
|
|
9431
9470
|
};
|
9432
9471
|
;(function(wysihtml5) {
|
9433
|
-
|
9434
|
-
|
9435
|
-
|
9436
|
-
|
9472
|
+
|
9473
|
+
// List of supported color format parsing methods
|
9474
|
+
// If radix is not defined 10 is expected as default
|
9475
|
+
var colorParseMethods = {
|
9476
|
+
rgba : {
|
9477
|
+
regex: /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*([\d\.]+)\s*\)/i,
|
9478
|
+
name: "rgba"
|
9479
|
+
},
|
9480
|
+
rgb : {
|
9481
|
+
regex: /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/i,
|
9482
|
+
name: "rgb"
|
9483
|
+
},
|
9484
|
+
hex6 : {
|
9485
|
+
regex: /^#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])/i,
|
9486
|
+
name: "hex",
|
9487
|
+
radix: 16
|
9488
|
+
},
|
9489
|
+
hex3 : {
|
9490
|
+
regex: /^#([0-9a-f])([0-9a-f])([0-9a-f])/i,
|
9491
|
+
name: "hex",
|
9492
|
+
radix: 16
|
9493
|
+
}
|
9494
|
+
},
|
9495
|
+
// Takes a style key name as an argument and makes a regex that can be used to the match key:value pair from style string
|
9496
|
+
makeParamRegExp = function (p) {
|
9497
|
+
return new RegExp("(^|\\s|;)" + p + "\\s*:\\s*[^;$]+", "gi");
|
9498
|
+
};
|
9437
9499
|
|
9438
|
-
|
9439
|
-
|
9440
|
-
|
9500
|
+
// Takes color string value ("#abc", "rgb(1,2,3)", ...) as an argument and returns suitable parsing method for it
|
9501
|
+
function getColorParseMethod (colorStr) {
|
9502
|
+
var prop, colorTypeConf;
|
9503
|
+
|
9504
|
+
for (prop in colorParseMethods) {
|
9505
|
+
if (!colorParseMethods.hasOwnProperty(prop)) { continue; }
|
9506
|
+
|
9507
|
+
colorTypeConf = colorParseMethods[prop];
|
9508
|
+
|
9509
|
+
if (colorTypeConf.regex.test(colorStr)) {
|
9510
|
+
return colorTypeConf;
|
9511
|
+
}
|
9512
|
+
}
|
9513
|
+
}
|
9514
|
+
|
9515
|
+
// Takes color string value ("#abc", "rgb(1,2,3)", ...) as an argument and returns the type of that color format "hex", "rgb", "rgba".
|
9516
|
+
function getColorFormat (colorStr) {
|
9517
|
+
var type = getColorParseMethod(colorStr);
|
9441
9518
|
|
9519
|
+
return type ? type.name : undefined;
|
9520
|
+
}
|
9521
|
+
|
9522
|
+
// Public API functions for styleParser
|
9442
9523
|
wysihtml5.quirks.styleParser = {
|
9443
9524
|
|
9444
|
-
|
9445
|
-
|
9446
|
-
params = stylesStr.match(paramRegex),
|
9447
|
-
radix = 10,
|
9448
|
-
str, colorMatch;
|
9525
|
+
// Takes color string value as an argument and returns suitable parsing method for it
|
9526
|
+
getColorParseMethod : getColorParseMethod,
|
9449
9527
|
|
9450
|
-
|
9451
|
-
|
9452
|
-
|
9453
|
-
|
9454
|
-
|
9455
|
-
|
9456
|
-
|
9457
|
-
|
9458
|
-
|
9459
|
-
|
9460
|
-
|
9461
|
-
|
9462
|
-
|
9463
|
-
|
9464
|
-
|
9465
|
-
|
9466
|
-
|
9467
|
-
|
9468
|
-
return (idx < 3) ? (parseInt(d, 16) * 16) + parseInt(d, 16): parseFloat(d);
|
9469
|
-
});
|
9470
|
-
}
|
9528
|
+
// Takes color string value as an argument and returns the type of that color format "hex", "rgb", "rgba".
|
9529
|
+
getColorFormat : getColorFormat,
|
9530
|
+
|
9531
|
+
/* Parses a color string to and array of [red, green, blue, alpha].
|
9532
|
+
* paramName: optional argument to parse color value directly from style string parameter
|
9533
|
+
*
|
9534
|
+
* Examples:
|
9535
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("#ABC"); // [170, 187, 204, 1]
|
9536
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("#AABBCC"); // [170, 187, 204, 1]
|
9537
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("rgb(1,2,3)"); // [1, 2, 3, 1]
|
9538
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("rgba(1,2,3,0.5)"); // [1, 2, 3, 0.5]
|
9539
|
+
*
|
9540
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("background-color: #ABC; color: #000;", "background-color"); // [170, 187, 204, 1]
|
9541
|
+
* var colorArray = wysihtml5.quirks.styleParser.parseColor("background-color: #ABC; color: #000;", "color"); // [0, 0, 0, 1]
|
9542
|
+
*/
|
9543
|
+
parseColor : function (stylesStr, paramName) {
|
9544
|
+
var paramsRegex, params, colorType, colorMatch, radix,
|
9545
|
+
colorStr = stylesStr;
|
9471
9546
|
|
9472
|
-
|
9473
|
-
|
9474
|
-
|
9475
|
-
|
9476
|
-
|
9477
|
-
|
9478
|
-
|
9479
|
-
});
|
9480
|
-
}
|
9547
|
+
if (paramName) {
|
9548
|
+
paramsRegex = makeParamRegExp(paramName);
|
9549
|
+
|
9550
|
+
if (!(params = stylesStr.match(paramsRegex))) { return false; }
|
9551
|
+
|
9552
|
+
params = params.pop().split(":")[1];
|
9553
|
+
colorStr = wysihtml5.lang.string(params).trim();
|
9481
9554
|
}
|
9482
|
-
|
9555
|
+
|
9556
|
+
if (!(colorType = getColorParseMethod(colorStr))) { return false; }
|
9557
|
+
if (!(colorMatch = colorStr.match(colorType.regex))) { return false; }
|
9558
|
+
|
9559
|
+
radix = colorType.radix || 10;
|
9560
|
+
|
9561
|
+
if (colorType === colorParseMethods.hex3) {
|
9562
|
+
colorMatch.shift();
|
9563
|
+
colorMatch.push(1);
|
9564
|
+
return wysihtml5.lang.array(colorMatch).map(function(d, idx) {
|
9565
|
+
return (idx < 3) ? (parseInt(d, radix) * radix) + parseInt(d, radix): parseFloat(d);
|
9566
|
+
});
|
9567
|
+
}
|
9568
|
+
|
9569
|
+
colorMatch.shift();
|
9570
|
+
|
9571
|
+
if (!colorMatch[3]) {
|
9572
|
+
colorMatch.push(1);
|
9573
|
+
}
|
9574
|
+
|
9575
|
+
return wysihtml5.lang.array(colorMatch).map(function(d, idx) {
|
9576
|
+
return (idx < 3) ? parseInt(d, radix): parseFloat(d);
|
9577
|
+
});
|
9483
9578
|
},
|
9484
9579
|
|
9485
|
-
|
9486
|
-
|
9487
|
-
|
9488
|
-
|
9489
|
-
|
9490
|
-
|
9491
|
-
|
9492
|
-
|
9493
|
-
|
9494
|
-
|
9495
|
-
|
9496
|
-
|
9497
|
-
|
9580
|
+
/* Takes rgba color array [r,g,b,a] as a value and formats it to color string with given format type
|
9581
|
+
* If no format is given, rgba/rgb is returned based on alpha value
|
9582
|
+
*
|
9583
|
+
* Example:
|
9584
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1], "hash"); // "#AABBCC"
|
9585
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1], "hex"); // "AABBCC"
|
9586
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1], "csv"); // "170, 187, 204, 1"
|
9587
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1], "rgba"); // "rgba(170,187,204,1)"
|
9588
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1], "rgb"); // "rgb(170,187,204)"
|
9589
|
+
*
|
9590
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 0.5]); // "rgba(170,187,204,0.5)"
|
9591
|
+
* var colorStr = wysihtml5.quirks.styleParser.unparseColor([170, 187, 204, 1]); // "rgb(170,187,204)"
|
9592
|
+
*/
|
9593
|
+
unparseColor: function(val, colorFormat) {
|
9594
|
+
var hexRadix = 16;
|
9595
|
+
|
9596
|
+
if (colorFormat === "hex") {
|
9597
|
+
return (val[0].toString(hexRadix) + val[1].toString(hexRadix) + val[2].toString(hexRadix)).toUpperCase();
|
9598
|
+
} else if (colorFormat === "hash") {
|
9599
|
+
return "#" + (val[0].toString(hexRadix) + val[1].toString(hexRadix) + val[2].toString(hexRadix)).toUpperCase();
|
9600
|
+
} else if (colorFormat === "rgb") {
|
9601
|
+
return "rgb(" + val[0] + "," + val[1] + "," + val[2] + ")";
|
9602
|
+
} else if (colorFormat === "rgba") {
|
9603
|
+
return "rgba(" + val[0] + "," + val[1] + "," + val[2] + "," + val[3] + ")";
|
9604
|
+
} else if (colorFormat === "csv") {
|
9605
|
+
return val[0] + "," + val[1] + "," + val[2] + "," + val[3];
|
9498
9606
|
}
|
9499
9607
|
|
9500
9608
|
if (val[3] && val[3] !== 1) {
|
@@ -9504,10 +9612,11 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9504
9612
|
}
|
9505
9613
|
},
|
9506
9614
|
|
9615
|
+
// Parses font size value from style string
|
9507
9616
|
parseFontSize: function(stylesStr) {
|
9508
|
-
var params = stylesStr.match(
|
9617
|
+
var params = stylesStr.match(makeParamRegExp("font-size"));
|
9509
9618
|
if (params) {
|
9510
|
-
return wysihtml5.lang.string(params[params.length - 1].split(
|
9619
|
+
return wysihtml5.lang.string(params[params.length - 1].split(":")[1]).trim();
|
9511
9620
|
}
|
9512
9621
|
return false;
|
9513
9622
|
}
|
@@ -9546,6 +9655,50 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9546
9655
|
return ret;
|
9547
9656
|
}
|
9548
9657
|
|
9658
|
+
function getWebkitSelectionFixNode(container) {
|
9659
|
+
var blankNode = document.createElement('span');
|
9660
|
+
|
9661
|
+
var placeholderRemover = function(event) {
|
9662
|
+
// Self-destructs the caret and keeps the text inserted into it by user
|
9663
|
+
var lastChild;
|
9664
|
+
|
9665
|
+
container.removeEventListener('mouseup', placeholderRemover);
|
9666
|
+
container.removeEventListener('keydown', placeholderRemover);
|
9667
|
+
container.removeEventListener('touchstart', placeholderRemover);
|
9668
|
+
container.removeEventListener('focus', placeholderRemover);
|
9669
|
+
container.removeEventListener('blur', placeholderRemover);
|
9670
|
+
container.removeEventListener('paste', delayedPlaceholderRemover);
|
9671
|
+
container.removeEventListener('drop', delayedPlaceholderRemover);
|
9672
|
+
container.removeEventListener('beforepaste', delayedPlaceholderRemover);
|
9673
|
+
|
9674
|
+
if (blankNode && blankNode.parentNode) {
|
9675
|
+
blankNode.parentNode.removeChild(blankNode);
|
9676
|
+
}
|
9677
|
+
},
|
9678
|
+
delayedPlaceholderRemover = function (event) {
|
9679
|
+
if (blankNode && blankNode.parentNode) {
|
9680
|
+
setTimeout(placeholderRemover, 0);
|
9681
|
+
}
|
9682
|
+
};
|
9683
|
+
|
9684
|
+
blankNode.appendChild(document.createTextNode(wysihtml5.INVISIBLE_SPACE));
|
9685
|
+
blankNode.className = '_wysihtml5-temp-caret-fix';
|
9686
|
+
blankNode.style.display = 'block';
|
9687
|
+
blankNode.style.minWidth = '1px';
|
9688
|
+
blankNode.style.height = '0px';
|
9689
|
+
|
9690
|
+
container.addEventListener('mouseup', placeholderRemover);
|
9691
|
+
container.addEventListener('keydown', placeholderRemover);
|
9692
|
+
container.addEventListener('touchstart', placeholderRemover);
|
9693
|
+
container.addEventListener('focus', placeholderRemover);
|
9694
|
+
container.addEventListener('blur', placeholderRemover);
|
9695
|
+
container.addEventListener('paste', delayedPlaceholderRemover);
|
9696
|
+
container.addEventListener('drop', delayedPlaceholderRemover);
|
9697
|
+
container.addEventListener('beforepaste', delayedPlaceholderRemover);
|
9698
|
+
|
9699
|
+
return blankNode;
|
9700
|
+
}
|
9701
|
+
|
9549
9702
|
// Should fix the obtained ranges that cannot surrond contents normally to apply changes upon
|
9550
9703
|
// Being considerate to firefox that sets range start start out of span and end inside on doubleclick initiated selection
|
9551
9704
|
function expandRangeToSurround(range) {
|
@@ -10218,6 +10371,20 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
10218
10371
|
}
|
10219
10372
|
},
|
10220
10373
|
|
10374
|
+
canAppendChild: function (node) {
|
10375
|
+
var anchorNode, anchorNodeTagNameLower,
|
10376
|
+
voidElements = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"],
|
10377
|
+
range = this.getRange();
|
10378
|
+
|
10379
|
+
anchorNode = node || range.startContainer;
|
10380
|
+
|
10381
|
+
if (anchorNode) {
|
10382
|
+
anchorNodeTagNameLower = (anchorNode.tagName || anchorNode.nodeName).toLowerCase();
|
10383
|
+
}
|
10384
|
+
|
10385
|
+
return voidElements.indexOf(anchorNodeTagNameLower) === -1;
|
10386
|
+
},
|
10387
|
+
|
10221
10388
|
splitElementAtCaret: function (element, insertNode) {
|
10222
10389
|
var sel = this.getSelection(),
|
10223
10390
|
range, contentAfterRangeStart,
|
@@ -10598,6 +10765,52 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
10598
10765
|
return (selection && selection.anchorNode && selection.focusNode) ? selection : null;
|
10599
10766
|
},
|
10600
10767
|
|
10768
|
+
|
10769
|
+
|
10770
|
+
// Webkit has an ancient error of not selecting all contents when uneditable block element is first or last in editable area
|
10771
|
+
selectAll: function() {
|
10772
|
+
var range = this.createRange(),
|
10773
|
+
composer = this.composer,
|
10774
|
+
that = this,
|
10775
|
+
blankEndNode = getWebkitSelectionFixNode(this.composer.element),
|
10776
|
+
blankStartNode = getWebkitSelectionFixNode(this.composer.element),
|
10777
|
+
s;
|
10778
|
+
|
10779
|
+
var doSelect = function() {
|
10780
|
+
range.setStart(composer.element, 0);
|
10781
|
+
range.setEnd(composer.element, composer.element.childNodes.length);
|
10782
|
+
s = that.setSelection(range);
|
10783
|
+
};
|
10784
|
+
|
10785
|
+
var notSelected = function() {
|
10786
|
+
return !s || (s.nativeSelection && s.nativeSelection.type && (s.nativeSelection.type === "Caret" || s.nativeSelection.type === "None"));
|
10787
|
+
}
|
10788
|
+
|
10789
|
+
wysihtml5.dom.removeInvisibleSpaces(this.composer.element);
|
10790
|
+
doSelect();
|
10791
|
+
|
10792
|
+
if (this.composer.element.firstChild && notSelected()) {
|
10793
|
+
// Try fixing end
|
10794
|
+
this.composer.element.appendChild(blankEndNode);
|
10795
|
+
doSelect();
|
10796
|
+
|
10797
|
+
if (notSelected()) {
|
10798
|
+
// Remove end fix
|
10799
|
+
blankEndNode.parentNode.removeChild(blankEndNode);
|
10800
|
+
|
10801
|
+
// Try fixing beginning
|
10802
|
+
this.composer.element.insertBefore(blankStartNode, this.composer.element.firstChild);
|
10803
|
+
doSelect();
|
10804
|
+
|
10805
|
+
if (notSelected()) {
|
10806
|
+
// Try fixing both
|
10807
|
+
this.composer.element.appendChild(blankEndNode);
|
10808
|
+
doSelect();
|
10809
|
+
}
|
10810
|
+
}
|
10811
|
+
}
|
10812
|
+
},
|
10813
|
+
|
10601
10814
|
createRange: function() {
|
10602
10815
|
return rangy.createRange(this.doc);
|
10603
10816
|
},
|
@@ -10656,6 +10869,25 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
10656
10869
|
return (wysihtml5.lang.array(nodeNames).contains(parentElement.nodeName)) ? parentElement : false;
|
10657
10870
|
},
|
10658
10871
|
|
10872
|
+
isInThisEditable: function() {
|
10873
|
+
var sel = this.getSelection(),
|
10874
|
+
fnode = sel.focusNode,
|
10875
|
+
anode = sel.anchorNode;
|
10876
|
+
|
10877
|
+
// In IE node contains will not work for textnodes, thus taking parentNode
|
10878
|
+
if (fnode && fnode.nodeType !== 1) {
|
10879
|
+
fnode = fnode.parentNode;
|
10880
|
+
}
|
10881
|
+
|
10882
|
+
if (anode && anode.nodeType !== 1) {
|
10883
|
+
anode = anode.parentNode;
|
10884
|
+
}
|
10885
|
+
|
10886
|
+
return anode && fnode &&
|
10887
|
+
(wysihtml5.dom.contains(this.composer.element, fnode) || this.composer.element === fnode) &&
|
10888
|
+
(wysihtml5.dom.contains(this.composer.element, anode) || this.composer.element === anode);
|
10889
|
+
},
|
10890
|
+
|
10659
10891
|
deselect: function() {
|
10660
10892
|
var sel = this.getSelection();
|
10661
10893
|
sel && sel.removeAllRanges();
|
@@ -11509,12 +11741,12 @@ wysihtml5.Commands = Base.extend(
|
|
11509
11741
|
exec: function(composer, command, size) {
|
11510
11742
|
size = size.size || size;
|
11511
11743
|
if (!(/^\s*$/).test(size)) {
|
11512
|
-
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty: "fontSize", styleValue: size, toggle:
|
11744
|
+
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty: "fontSize", styleValue: size, toggle: false});
|
11513
11745
|
}
|
11514
11746
|
},
|
11515
11747
|
|
11516
11748
|
state: function(composer, command, size) {
|
11517
|
-
return wysihtml5.commands.formatInline.state(composer, command, {styleProperty: "fontSize", styleValue: size});
|
11749
|
+
return wysihtml5.commands.formatInline.state(composer, command, {styleProperty: "fontSize", styleValue: size || undefined});
|
11518
11750
|
},
|
11519
11751
|
|
11520
11752
|
remove: function(composer, command) {
|
@@ -11522,15 +11754,14 @@ wysihtml5.Commands = Base.extend(
|
|
11522
11754
|
},
|
11523
11755
|
|
11524
11756
|
stateValue: function(composer, command) {
|
11525
|
-
var
|
11526
|
-
|
11527
|
-
val = false;
|
11757
|
+
var styleStr,
|
11758
|
+
st = this.state(composer, command);
|
11528
11759
|
|
11529
11760
|
if (st && wysihtml5.lang.object(st).isArray()) {
|
11530
11761
|
st = st[0];
|
11531
11762
|
}
|
11532
11763
|
if (st) {
|
11533
|
-
styleStr = st.getAttribute(
|
11764
|
+
styleStr = st.getAttribute("style");
|
11534
11765
|
if (styleStr) {
|
11535
11766
|
return wysihtml5.quirks.styleParser.parseFontSize(styleStr);
|
11536
11767
|
}
|
@@ -11562,12 +11793,15 @@ wysihtml5.Commands = Base.extend(
|
|
11562
11793
|
|
11563
11794
|
wysihtml5.commands.foreColorStyle = {
|
11564
11795
|
exec: function(composer, command, color) {
|
11565
|
-
var colorVals
|
11566
|
-
|
11796
|
+
var colorVals, colString;
|
11797
|
+
|
11798
|
+
if (!color) { return; }
|
11799
|
+
|
11800
|
+
colorVals = wysihtml5.quirks.styleParser.parseColor("color:" + (color.color || color), "color");
|
11567
11801
|
|
11568
11802
|
if (colorVals) {
|
11569
|
-
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(
|
11570
|
-
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty:
|
11803
|
+
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(", ") : "rgba(" + colorVals.join(', ')) + ')';
|
11804
|
+
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty: "color", styleValue: colString});
|
11571
11805
|
}
|
11572
11806
|
},
|
11573
11807
|
|
@@ -11577,14 +11811,14 @@ wysihtml5.Commands = Base.extend(
|
|
11577
11811
|
|
11578
11812
|
|
11579
11813
|
if (colorVals) {
|
11580
|
-
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(
|
11814
|
+
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(", ") : "rgba(" + colorVals.join(', ')) + ')';
|
11581
11815
|
}
|
11582
11816
|
|
11583
|
-
return wysihtml5.commands.formatInline.state(composer, command, {styleProperty:
|
11817
|
+
return wysihtml5.commands.formatInline.state(composer, command, {styleProperty: "color", styleValue: colString});
|
11584
11818
|
},
|
11585
11819
|
|
11586
11820
|
remove: function(composer, command) {
|
11587
|
-
return wysihtml5.commands.formatInline.remove(composer, command, {styleProperty:
|
11821
|
+
return wysihtml5.commands.formatInline.remove(composer, command, {styleProperty: "color"});
|
11588
11822
|
},
|
11589
11823
|
|
11590
11824
|
stateValue: function(composer, command, props) {
|
@@ -11597,7 +11831,7 @@ wysihtml5.Commands = Base.extend(
|
|
11597
11831
|
}
|
11598
11832
|
|
11599
11833
|
if (st) {
|
11600
|
-
colorStr = st.getAttribute(
|
11834
|
+
colorStr = st.getAttribute("style");
|
11601
11835
|
if (colorStr) {
|
11602
11836
|
val = wysihtml5.quirks.styleParser.parseColor(colorStr, "color");
|
11603
11837
|
return wysihtml5.quirks.styleParser.unparseColor(val, props);
|
@@ -11675,6 +11909,14 @@ wysihtml5.Commands = Base.extend(
|
|
11675
11909
|
BLOCK_ELEMENTS = "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote",
|
11676
11910
|
INLINE_ELEMENTS = "b, big, i, small, tt, abbr, acronym, cite, code, dfn, em, kbd, strong, samp, var, a, bdo, br, q, span, sub, sup, button, label, textarea, input, select, u";
|
11677
11911
|
|
11912
|
+
function correctOptionsForSimilarityCheck(options) {
|
11913
|
+
return {
|
11914
|
+
nodeName: options.nodeName || null,
|
11915
|
+
className: (!options.classRegExp) ? options.className || null : null,
|
11916
|
+
classRegExp: options.classRegExp || null,
|
11917
|
+
styleProperty: options.styleProperty || null
|
11918
|
+
};
|
11919
|
+
}
|
11678
11920
|
|
11679
11921
|
// Removes empty block level elements
|
11680
11922
|
function cleanup(composer) {
|
@@ -11684,7 +11926,7 @@ wysihtml5.Commands = Base.extend(
|
|
11684
11926
|
elements = wysihtml5.lang.array(allElements).without(uneditables);
|
11685
11927
|
|
11686
11928
|
for (var i = elements.length; i--;) {
|
11687
|
-
if (elements[i].innerHTML === "") {
|
11929
|
+
if (elements[i].innerHTML.replace(/[\uFEFF]/g, '') === "") {
|
11688
11930
|
elements[i].parentNode.removeChild(elements[i]);
|
11689
11931
|
}
|
11690
11932
|
}
|
@@ -11811,7 +12053,7 @@ wysihtml5.Commands = Base.extend(
|
|
11811
12053
|
|
11812
12054
|
for (var i = contentBlocks.length; i--;) {
|
11813
12055
|
if (!contentBlocks[i].nextSibling || contentBlocks[i].nextSibling.nodeType !== 1 || contentBlocks[i].nextSibling.nodeName !== 'BR') {
|
11814
|
-
if ((contentBlocks[i].innerHTML || contentBlocks[i].nodeValue).trim() !==
|
12056
|
+
if ((contentBlocks[i].innerHTML || contentBlocks[i].nodeValue || '').trim() !== '') {
|
11815
12057
|
contentBlocks[i].parentNode.insertBefore(contentBlocks[i].ownerDocument.createElement('BR'), contentBlocks[i].nextSibling);
|
11816
12058
|
}
|
11817
12059
|
}
|
@@ -11877,8 +12119,10 @@ wysihtml5.Commands = Base.extend(
|
|
11877
12119
|
rangeStartContainer = r.startContainer,
|
11878
12120
|
content = r.extractContents(),
|
11879
12121
|
fragment = composer.doc.createDocumentFragment(),
|
12122
|
+
similarOptions = defaultOptions ? correctOptionsForSimilarityCheck(defaultOptions) : null,
|
12123
|
+
similarOuterBlock = similarOptions ? wysihtml5.dom.getParentElement(rangeStartContainer, similarOptions, null, composer.element) : null,
|
11880
12124
|
splitAllBlocks = !defaultOptions || (defaultName === "BLOCKQUOTE" && defaultOptions.nodeName && defaultOptions.nodeName === "BLOCKQUOTE"),
|
11881
|
-
firstOuterBlock = findOuterBlock(rangeStartContainer, composer.element, splitAllBlocks), // The outermost un-nestable block element parent of selection start
|
12125
|
+
firstOuterBlock = similarOuterBlock || findOuterBlock(rangeStartContainer, composer.element, splitAllBlocks), // The outermost un-nestable block element parent of selection start
|
11882
12126
|
wrapper, blocks, children;
|
11883
12127
|
|
11884
12128
|
if (options && options.nodeName && options.nodeName === "BLOCKQUOTE") {
|
@@ -12003,7 +12247,7 @@ wysihtml5.Commands = Base.extend(
|
|
12003
12247
|
|
12004
12248
|
if (composer.selection.isCollapsed()) {
|
12005
12249
|
parent = wysihtml5.dom.getParentElement(composer.selection.getOwnRanges()[0].startContainer, {
|
12006
|
-
query:
|
12250
|
+
query: UNNESTABLE_BLOCK_ELEMENTS + ', ' + (options && options.nodeName ? options.nodeName.toLowerCase() : 'div'),
|
12007
12251
|
}, null, composer.element);
|
12008
12252
|
if (parent) {
|
12009
12253
|
bookmark = rangy.saveSelection(composer.win);
|
@@ -12016,7 +12260,7 @@ wysihtml5.Commands = Base.extend(
|
|
12016
12260
|
}
|
12017
12261
|
}
|
12018
12262
|
|
12019
|
-
// And get all selection ranges of current composer and
|
12263
|
+
// And get all selection ranges of current composer and iterate
|
12020
12264
|
ranges = composer.selection.getOwnRanges();
|
12021
12265
|
for (var i = ranges.length; i--;) {
|
12022
12266
|
newBlockElements = newBlockElements.concat(wrapRangeWithElement(ranges[i], options, getParentBlockNodeName(ranges[i].startContainer, composer), composer));
|
@@ -12026,6 +12270,13 @@ wysihtml5.Commands = Base.extend(
|
|
12026
12270
|
|
12027
12271
|
// Remove empty block elements that may be left behind
|
12028
12272
|
cleanup(composer);
|
12273
|
+
// If cleanup removed some new block elements. remove them from array too
|
12274
|
+
for (var e = newBlockElements.length; e--;) {
|
12275
|
+
if (!newBlockElements[e].parentNode) {
|
12276
|
+
newBlockElements.splice(e, 1);
|
12277
|
+
}
|
12278
|
+
}
|
12279
|
+
|
12029
12280
|
// Restore correct selection
|
12030
12281
|
if (bookmark) {
|
12031
12282
|
rangy.restoreSelection(bookmark);
|
@@ -12081,8 +12332,9 @@ wysihtml5.Commands = Base.extend(
|
|
12081
12332
|
wysihtml5.commands.formatCode = {
|
12082
12333
|
|
12083
12334
|
exec: function(composer, command, classname) {
|
12084
|
-
var pre = this.state(composer),
|
12335
|
+
var pre = this.state(composer)[0],
|
12085
12336
|
code, range, selectedNodes;
|
12337
|
+
|
12086
12338
|
if (pre) {
|
12087
12339
|
// caret is already within a <pre><code>...</code></pre>
|
12088
12340
|
composer.selection.executeAndRestore(function() {
|
@@ -12111,12 +12363,13 @@ wysihtml5.Commands = Base.extend(
|
|
12111
12363
|
},
|
12112
12364
|
|
12113
12365
|
state: function(composer) {
|
12114
|
-
var selectedNode = composer.selection.getSelectedNode();
|
12366
|
+
var selectedNode = composer.selection.getSelectedNode(), node;
|
12115
12367
|
if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
|
12116
12368
|
selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
|
12117
|
-
return selectedNode;
|
12369
|
+
return [selectedNode];
|
12118
12370
|
} else {
|
12119
|
-
|
12371
|
+
node = wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
|
12372
|
+
return node ? [node.parentNode] : false;
|
12120
12373
|
}
|
12121
12374
|
}
|
12122
12375
|
};
|
@@ -12260,9 +12513,7 @@ wysihtml5.Commands = Base.extend(
|
|
12260
12513
|
}
|
12261
12514
|
|
12262
12515
|
function updateFormatOfElement(element, options) {
|
12263
|
-
var attr, newNode, a, newAttributes, nodeNameQuery;
|
12264
|
-
|
12265
|
-
|
12516
|
+
var attr, newNode, a, newAttributes, nodeNameQuery, nodeQueryMatch;
|
12266
12517
|
|
12267
12518
|
if (options.className) {
|
12268
12519
|
if (options.toggle !== false && element.classList.contains(options.className)) {
|
@@ -12297,30 +12548,19 @@ wysihtml5.Commands = Base.extend(
|
|
12297
12548
|
updateElementAttributes(element, newAttributes, options.toggle);
|
12298
12549
|
}
|
12299
12550
|
|
12300
|
-
|
12551
|
+
|
12552
|
+
// Handle similar semantically same elements (queryAliasMap)
|
12301
12553
|
nodeNameQuery = options.nodeName ? queryAliasMap[options.nodeName.toLowerCase()] || options.nodeName.toLowerCase() : null;
|
12554
|
+
nodeQueryMatch = nodeNameQuery ? wysihtml5.dom.domNode(element).test({ query: nodeNameQuery }) : false;
|
12302
12555
|
|
12303
|
-
|
12304
|
-
|
12305
|
-
|
12306
|
-
if (
|
12556
|
+
// Unwrap element if no attributes present and node name given
|
12557
|
+
// or no attributes and if no nodename set but node is the default
|
12558
|
+
if (!options.nodeName || options.nodeName === defaultTag || nodeQueryMatch) {
|
12559
|
+
if (
|
12560
|
+
((options.toggle !== false && nodeQueryMatch) || (!options.nodeName && element.nodeName === defaultTag)) &&
|
12561
|
+
hasNoClass(element) && hasNoStyle(element) && hasNoAttributes(element)
|
12562
|
+
) {
|
12307
12563
|
wysihtml5.dom.unwrap(element);
|
12308
|
-
} else if (!options.nodeName) {
|
12309
|
-
newNode = element.ownerDocument.createElement(defaultTag);
|
12310
|
-
|
12311
|
-
// pass present attributes
|
12312
|
-
attr = wysihtml5.dom.getAttributes(element);
|
12313
|
-
for (a in attr) {
|
12314
|
-
if (attr.hasOwnProperty(a)) {
|
12315
|
-
newNode.setAttribute(a, attr[a]);
|
12316
|
-
}
|
12317
|
-
}
|
12318
|
-
|
12319
|
-
while (element.firstChild) {
|
12320
|
-
newNode.appendChild(element.firstChild);
|
12321
|
-
}
|
12322
|
-
element.parentNode.insertBefore(newNode, element);
|
12323
|
-
element.parentNode.removeChild(element);
|
12324
12564
|
}
|
12325
12565
|
|
12326
12566
|
}
|
@@ -12425,35 +12665,39 @@ wysihtml5.Commands = Base.extend(
|
|
12425
12665
|
partial = false,
|
12426
12666
|
node, range, caretNode;
|
12427
12667
|
|
12428
|
-
if (
|
12429
|
-
|
12430
|
-
if (
|
12431
|
-
|
12432
|
-
|
12433
|
-
|
12434
|
-
|
12435
|
-
|
12436
|
-
|
12437
|
-
|
12438
|
-
|
12668
|
+
if (composer.selection.isInThisEditable()) {
|
12669
|
+
|
12670
|
+
if (searchNodes.length === 0 && composer.selection.isCollapsed()) {
|
12671
|
+
caretNode = composer.selection.getSelection().anchorNode;
|
12672
|
+
if (!caretNode) {
|
12673
|
+
// selection not in editor
|
12674
|
+
return {
|
12675
|
+
nodes: [],
|
12676
|
+
partial: false
|
12677
|
+
};
|
12678
|
+
}
|
12679
|
+
if (caretNode.nodeType === 3) {
|
12680
|
+
searchNodes = [caretNode];
|
12681
|
+
}
|
12439
12682
|
}
|
12440
|
-
}
|
12441
12683
|
|
12442
|
-
|
12443
|
-
|
12444
|
-
|
12445
|
-
|
12446
|
-
|
12684
|
+
// Handle collapsed selection caret
|
12685
|
+
if (!searchNodes.length) {
|
12686
|
+
range = composer.selection.getOwnRanges()[0];
|
12687
|
+
if (range) {
|
12688
|
+
searchNodes = [range.endContainer];
|
12689
|
+
}
|
12447
12690
|
}
|
12448
|
-
}
|
12449
12691
|
|
12450
|
-
|
12451
|
-
|
12452
|
-
|
12453
|
-
|
12454
|
-
|
12455
|
-
|
12692
|
+
for (var i = 0, maxi = searchNodes.length; i < maxi; i++) {
|
12693
|
+
node = findSimilarTextNodeWrapper(searchNodes[i], options, composer.element, exact);
|
12694
|
+
if (node) {
|
12695
|
+
nodes.push(node);
|
12696
|
+
} else {
|
12697
|
+
partial = true;
|
12698
|
+
}
|
12456
12699
|
}
|
12700
|
+
|
12457
12701
|
}
|
12458
12702
|
|
12459
12703
|
return {
|
@@ -12774,9 +13018,7 @@ wysihtml5.Commands = Base.extend(
|
|
12774
13018
|
|
12775
13019
|
state: function(composer, command, options) {
|
12776
13020
|
options = fixOptions(options);
|
12777
|
-
|
12778
13021
|
var nodes = getState(composer, options, true).nodes;
|
12779
|
-
|
12780
13022
|
return (nodes.length === 0) ? false : nodes;
|
12781
13023
|
}
|
12782
13024
|
};
|
@@ -14635,14 +14877,14 @@ wysihtml5.views.View = Base.extend(
|
|
14635
14877
|
// Deletion with caret in the beginning of headings needs special attention
|
14636
14878
|
// Heading does not concate text to previous block node correctly (browsers do unexpected miracles here especially webkit)
|
14637
14879
|
var fixDeleteInTheBeginnigOfHeading = function(composer) {
|
14638
|
-
var selection = composer.selection
|
14880
|
+
var selection = composer.selection,
|
14881
|
+
prevNode = selection.getPreviousNode();
|
14639
14882
|
|
14640
14883
|
if (selection.caretIsFirstInSelection() &&
|
14641
|
-
|
14642
|
-
|
14643
|
-
(
|
14884
|
+
prevNode &&
|
14885
|
+
prevNode.nodeType === 1 &&
|
14886
|
+
(/block/).test(composer.win.getComputedStyle(prevNode).display)
|
14644
14887
|
) {
|
14645
|
-
var prevNode = selection.getPreviousNode();
|
14646
14888
|
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
|
14647
14889
|
// If heading is empty remove the heading node
|
14648
14890
|
prevNode.parentNode.removeChild(prevNode);
|
@@ -14650,20 +14892,23 @@ wysihtml5.views.View = Base.extend(
|
|
14650
14892
|
} else {
|
14651
14893
|
if (prevNode.lastChild) {
|
14652
14894
|
var selNode = prevNode.lastChild,
|
14653
|
-
|
14654
|
-
|
14895
|
+
selectedNode = selection.getSelectedNode(),
|
14896
|
+
commonAncestorNode = wysihtml5.dom.domNode(prevNode).commonAncestor(selectedNode, composer.element);
|
14897
|
+
curNode = commonAncestorNode ? wysihtml5.dom.getParentElement(selectedNode, {
|
14898
|
+
query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote"
|
14899
|
+
}, false, commonAncestorNode) : null;
|
14900
|
+
|
14655
14901
|
if (curNode) {
|
14656
14902
|
while (curNode.firstChild) {
|
14657
14903
|
prevNode.appendChild(curNode.firstChild);
|
14658
14904
|
}
|
14659
14905
|
selection.setAfter(selNode);
|
14660
14906
|
return true;
|
14661
|
-
} else if (
|
14662
|
-
prevNode.appendChild(
|
14907
|
+
} else if (selectedNode.nodeType === 3) {
|
14908
|
+
prevNode.appendChild(selectedNode);
|
14663
14909
|
selection.setAfter(selNode);
|
14664
14910
|
return true;
|
14665
14911
|
}
|
14666
|
-
}
|
14667
14912
|
}
|
14668
14913
|
}
|
14669
14914
|
}
|
@@ -14675,23 +14920,17 @@ wysihtml5.views.View = Base.extend(
|
|
14675
14920
|
element = composer.element;
|
14676
14921
|
|
14677
14922
|
if (selection.isCollapsed()) {
|
14678
|
-
if (
|
14679
|
-
// delete in the beginnig of LI will outdent not delete
|
14923
|
+
if (fixDeleteInTheBeginnigOfHeading(composer)) {
|
14680
14924
|
event.preventDefault();
|
14681
|
-
|
14682
|
-
}
|
14683
|
-
|
14684
|
-
|
14685
|
-
|
14686
|
-
|
14687
|
-
|
14688
|
-
|
14689
|
-
|
14690
|
-
}
|
14691
|
-
if (handleUneditableDeletion(composer)) {
|
14692
|
-
event.preventDefault();
|
14693
|
-
return;
|
14694
|
-
}
|
14925
|
+
return;
|
14926
|
+
}
|
14927
|
+
if (fixLastBrDeletionInTable(composer)) {
|
14928
|
+
event.preventDefault();
|
14929
|
+
return;
|
14930
|
+
}
|
14931
|
+
if (handleUneditableDeletion(composer)) {
|
14932
|
+
event.preventDefault();
|
14933
|
+
return;
|
14695
14934
|
}
|
14696
14935
|
} else {
|
14697
14936
|
if (selection.containsUneditable()) {
|
@@ -14701,11 +14940,15 @@ wysihtml5.views.View = Base.extend(
|
|
14701
14940
|
}
|
14702
14941
|
};
|
14703
14942
|
|
14704
|
-
var handleTabKeyDown = function(composer, element) {
|
14943
|
+
var handleTabKeyDown = function(composer, element, shiftKey) {
|
14705
14944
|
if (!composer.selection.isCollapsed()) {
|
14706
14945
|
composer.selection.deleteContents();
|
14707
14946
|
} else if (composer.selection.caretIsInTheBeginnig('li')) {
|
14708
|
-
if (
|
14947
|
+
if (shiftKey) {
|
14948
|
+
if (composer.commands.exec('outdentList')) return;
|
14949
|
+
} else {
|
14950
|
+
if (composer.commands.exec('indentList')) return;
|
14951
|
+
}
|
14709
14952
|
}
|
14710
14953
|
|
14711
14954
|
// Is   close enough to tab. Could not find enough counter arguments for now.
|
@@ -14721,9 +14964,9 @@ wysihtml5.views.View = Base.extend(
|
|
14721
14964
|
|
14722
14965
|
// Listens to "drop", "paste", "mouseup", "focus", "keyup" events and fires
|
14723
14966
|
var handleUserInteraction = function (event) {
|
14724
|
-
this.parent.fire("beforeinteraction").fire("beforeinteraction:composer");
|
14967
|
+
this.parent.fire("beforeinteraction", event).fire("beforeinteraction:composer", event);
|
14725
14968
|
setTimeout((function() {
|
14726
|
-
this.parent.fire("interaction").fire("interaction:composer");
|
14969
|
+
this.parent.fire("interaction", event).fire("interaction:composer", event);
|
14727
14970
|
}).bind(this), 0);
|
14728
14971
|
};
|
14729
14972
|
|
@@ -14837,6 +15080,13 @@ wysihtml5.views.View = Base.extend(
|
|
14837
15080
|
command = shortcuts[keyCode],
|
14838
15081
|
target, parent;
|
14839
15082
|
|
15083
|
+
// Select all (meta/ctrl + a)
|
15084
|
+
if ((event.ctrlKey || event.metaKey) && keyCode === 65) {
|
15085
|
+
this.selection.selectAll();
|
15086
|
+
event.preventDefault();
|
15087
|
+
return;
|
15088
|
+
}
|
15089
|
+
|
14840
15090
|
// Shortcut logic
|
14841
15091
|
if ((event.ctrlKey || event.metaKey) && !event.altKey && command) {
|
14842
15092
|
this.commands.exec(command);
|
@@ -14859,16 +15109,16 @@ wysihtml5.views.View = Base.extend(
|
|
14859
15109
|
if (parent.nodeName === "A" && !parent.firstChild) {
|
14860
15110
|
parent.parentNode.removeChild(parent);
|
14861
15111
|
}
|
14862
|
-
setTimeout(function() {
|
15112
|
+
setTimeout((function() {
|
14863
15113
|
wysihtml5.quirks.redraw(this.element);
|
14864
|
-
}, 0);
|
15114
|
+
}).bind(this), 0);
|
14865
15115
|
}
|
14866
15116
|
}
|
14867
15117
|
|
14868
15118
|
if (this.config.handleTabKey && keyCode === wysihtml5.TAB_KEY) {
|
14869
15119
|
// TAB key handling
|
14870
15120
|
event.preventDefault();
|
14871
|
-
handleTabKeyDown(this, this.element);
|
15121
|
+
handleTabKeyDown(this, this.element, event.shiftKey);
|
14872
15122
|
}
|
14873
15123
|
|
14874
15124
|
};
|
@@ -15227,6 +15477,8 @@ wysihtml5.views.View = Base.extend(
|
|
15227
15477
|
// Whether toolbar is displayed after init by script automatically.
|
15228
15478
|
// Can be set to false if toolobar is set to display only on editable area focus
|
15229
15479
|
showToolbarAfterInit: true,
|
15480
|
+
// With default toolbar it shows dialogs in toolbar when their related text format state becomes active (click on link in text opens link dialogue)
|
15481
|
+
showToolbarDialogsOnSelection: true,
|
15230
15482
|
// Whether urls, entered by the user should automatically become clickable-links
|
15231
15483
|
autoLink: true,
|
15232
15484
|
// Includes table editing events and cell selection tracking
|
@@ -15400,8 +15652,7 @@ wysihtml5.views.View = Base.extend(
|
|
15400
15652
|
* - Observes for paste and drop
|
15401
15653
|
*/
|
15402
15654
|
_initParser: function() {
|
15403
|
-
var oldHtml
|
15404
|
-
cleanHtml;
|
15655
|
+
var oldHtml;
|
15405
15656
|
|
15406
15657
|
if (wysihtml5.browser.supportsModernPaste()) {
|
15407
15658
|
this.on("paste:composer", function(event) {
|