wysihtml5x-rails 0.4.15 → 0.4.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/wysihtml5x/rails/version.rb +1 -1
- data/vendor/assets/javascripts/wysihtml5x-toolbar.js +135 -41
- data/vendor/assets/javascripts/wysihtml5x.js +135 -41
- 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: 09f662c19d4439847f1ce68e8e8b2426d910e89e
|
4
|
+
data.tar.gz: d20ca36a6b4d55f761c8d349d8ed0d850bdfd627
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 545f630a0749c55b84e7235d8183b63a8852099f869f6db594889fe48e2fb4f0fbea9b8b3df7811fcc0f9e6bd6c4ff1f8f6a114059acde363ae86bb74b77300f
|
7
|
+
data.tar.gz: 78ff06fa47c2b931ae39e4facff9bf949d8a5a1d2faa31462955b77b3def8a0422e10e85316db9a47271deefd0e4a2dc4e30919abff7bb427d87da616710c672
|
@@ -25,7 +25,7 @@ if(!Array.isArray) {
|
|
25
25
|
return Object.prototype.toString.call(arg) === '[object Array]';
|
26
26
|
};
|
27
27
|
};/**
|
28
|
-
* @license wysihtml5x v0.4.
|
28
|
+
* @license wysihtml5x v0.4.16
|
29
29
|
* https://github.com/Edicy/wysihtml5
|
30
30
|
*
|
31
31
|
* Author: Christopher Blum (https://github.com/tiff)
|
@@ -36,7 +36,7 @@ if(!Array.isArray) {
|
|
36
36
|
*
|
37
37
|
*/
|
38
38
|
var wysihtml5 = {
|
39
|
-
version: "0.4.
|
39
|
+
version: "0.4.16",
|
40
40
|
|
41
41
|
// namespaces
|
42
42
|
commands: {},
|
@@ -5369,9 +5369,36 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
5369
5369
|
}
|
5370
5370
|
|
5371
5371
|
return nextNode;
|
5372
|
-
}
|
5372
|
+
},
|
5373
|
+
|
5374
|
+
// Traverses a node for last children and their chidren (including itself), and finds the last node that has no children.
|
5375
|
+
// Array of classes for forced last-leaves (ex: uneditable-container) can be defined (options = {leafClasses: [...]})
|
5376
|
+
// Useful for finding the actually visible element before cursor
|
5377
|
+
lastLeafNode: function(options) {
|
5378
|
+
var lastChild;
|
5379
|
+
|
5380
|
+
// Returns non-element nodes
|
5381
|
+
if (node.nodeType !== 1) {
|
5382
|
+
return node;
|
5383
|
+
}
|
5373
5384
|
|
5385
|
+
// Returns if element is leaf
|
5386
|
+
lastChild = node.lastChild;
|
5387
|
+
if (!lastChild) {
|
5388
|
+
return node;
|
5389
|
+
}
|
5390
|
+
|
5391
|
+
// Returns if element is of of options.leafClasses leaf
|
5392
|
+
if (options && options.leafClasses) {
|
5393
|
+
for (var i = options.leafClasses.length; i--;) {
|
5394
|
+
if (wysihtml5.dom.hasClass(node, options.leafClasses[i])) {
|
5395
|
+
return node;
|
5396
|
+
}
|
5397
|
+
}
|
5398
|
+
}
|
5374
5399
|
|
5400
|
+
return wysihtml5.dom.domNode(lastChild).lastLeafNode(options);
|
5401
|
+
}
|
5375
5402
|
|
5376
5403
|
};
|
5377
5404
|
};
|
@@ -5494,8 +5521,13 @@ wysihtml5.dom.getParentElement = (function() {
|
|
5494
5521
|
|
5495
5522
|
levels = levels || 50; // Go max 50 nodes upwards from current node
|
5496
5523
|
|
5524
|
+
// make the matching class regex from class name if omitted
|
5525
|
+
if (findByClass && !matchingSet.classRegExp) {
|
5526
|
+
matchingSet.classRegExp = new RegExp(matchingSet.className);
|
5527
|
+
}
|
5528
|
+
|
5497
5529
|
while (levels-- && node && node.nodeName !== "BODY" && (!container || node !== container)) {
|
5498
|
-
if (_isElement(node) && _isSameNodeName(node.nodeName, matchingSet.nodeName) &&
|
5530
|
+
if (_isElement(node) && (!matchingSet.nodeName || _isSameNodeName(node.nodeName, matchingSet.nodeName)) &&
|
5499
5531
|
(!findByStyle || _hasStyle(node, matchingSet.cssStyle, matchingSet.styleRegExp)) &&
|
5500
5532
|
(!findByClass || _hasClassName(node, matchingSet.className, matchingSet.classRegExp))
|
5501
5533
|
) {
|
@@ -8922,15 +8954,25 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
8922
8954
|
return false;
|
8923
8955
|
},
|
8924
8956
|
|
8957
|
+
// deletes selection contents making sure uneditables/unselectables are not partially deleted
|
8925
8958
|
deleteContents: function() {
|
8926
|
-
var
|
8927
|
-
|
8928
|
-
|
8959
|
+
var range = this.getRange(),
|
8960
|
+
startParent, endParent;
|
8961
|
+
|
8962
|
+
if (this.unselectableClass) {
|
8963
|
+
if ((startParent = wysihtml5.dom.getParentElement(range.startContainer, { className: this.unselectableClass }, false, this.contain))) {
|
8964
|
+
range.setStartBefore(startParent);
|
8965
|
+
}
|
8966
|
+
if ((endParent = wysihtml5.dom.getParentElement(range.endContainer, { className: this.unselectableClass }, false, this.contain))) {
|
8967
|
+
range.setEndAfter(endParent);
|
8968
|
+
}
|
8929
8969
|
}
|
8930
|
-
|
8970
|
+
range.deleteContents();
|
8971
|
+
this.setSelection(range);
|
8931
8972
|
},
|
8932
8973
|
|
8933
8974
|
getPreviousNode: function(node, ignoreEmpty) {
|
8975
|
+
var displayStyle;
|
8934
8976
|
if (!node) {
|
8935
8977
|
var selection = this.getSelection();
|
8936
8978
|
node = selection.anchorNode;
|
@@ -8951,12 +8993,19 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
8951
8993
|
// do not count comments and other node types
|
8952
8994
|
ret = this.getPreviousNode(ret, ignoreEmpty);
|
8953
8995
|
} else if (ret && ret.nodeType === 3 && (/^\s*$/).test(ret.textContent)) {
|
8954
|
-
// do not count empty textnodes as
|
8996
|
+
// do not count empty textnodes as previous nodes
|
8955
8997
|
ret = this.getPreviousNode(ret, ignoreEmpty);
|
8956
|
-
} else if (ignoreEmpty && ret && ret.nodeType === 1
|
8998
|
+
} else if (ignoreEmpty && ret && ret.nodeType === 1) {
|
8957
8999
|
// Do not count empty nodes if param set.
|
8958
|
-
// Contenteditable tends to bypass and delete these silently when deleting with caret
|
8959
|
-
|
9000
|
+
// Contenteditable tends to bypass and delete these silently when deleting with caret when element is inline-like
|
9001
|
+
displayStyle = wysihtml5.dom.getStyle("display").from(ret);
|
9002
|
+
if (
|
9003
|
+
!wysihtml5.lang.array(["BR", "HR", "IMG"]).contains(ret.nodeName) &&
|
9004
|
+
!wysihtml5.lang.array(["block", "inline-block", "flex", "list-item", "table"]).contains(displayStyle) &&
|
9005
|
+
(/^[\s]*$/).test(ret.innerHTML)
|
9006
|
+
) {
|
9007
|
+
ret = this.getPreviousNode(ret, ignoreEmpty);
|
9008
|
+
}
|
8960
9009
|
} else if (!ret && node !== this.contain) {
|
8961
9010
|
parent = node.parentNode;
|
8962
9011
|
if (parent !== this.contain) {
|
@@ -9008,12 +9057,14 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9008
9057
|
range = this.getRange(),
|
9009
9058
|
startNode = range.startContainer;
|
9010
9059
|
|
9011
|
-
if (startNode
|
9012
|
-
|
9013
|
-
|
9014
|
-
|
9015
|
-
|
9016
|
-
|
9060
|
+
if (startNode) {
|
9061
|
+
if (startNode.nodeType === wysihtml5.TEXT_NODE) {
|
9062
|
+
return this.isCollapsed() && (startNode.nodeType === wysihtml5.TEXT_NODE && (/^\s*$/).test(startNode.data.substr(0,range.startOffset)));
|
9063
|
+
} else {
|
9064
|
+
r.selectNodeContents(this.getRange().commonAncestorContainer);
|
9065
|
+
r.collapse(true);
|
9066
|
+
return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
|
9067
|
+
}
|
9017
9068
|
}
|
9018
9069
|
},
|
9019
9070
|
|
@@ -9021,9 +9072,9 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9021
9072
|
var selection = this.getSelection(),
|
9022
9073
|
node = selection.anchorNode,
|
9023
9074
|
offset = selection.anchorOffset;
|
9024
|
-
if (ofNode) {
|
9075
|
+
if (ofNode && node) {
|
9025
9076
|
return (offset === 0 && (node.nodeName && node.nodeName === ofNode.toUpperCase() || wysihtml5.dom.getParentElement(node.parentNode, { nodeName: ofNode }, 1)));
|
9026
|
-
} else {
|
9077
|
+
} else if (node) {
|
9027
9078
|
return (offset === 0 && !this.getPreviousNode(node, true));
|
9028
9079
|
}
|
9029
9080
|
},
|
@@ -9031,17 +9082,39 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9031
9082
|
caretIsBeforeUneditable: function() {
|
9032
9083
|
var selection = this.getSelection(),
|
9033
9084
|
node = selection.anchorNode,
|
9034
|
-
offset = selection.anchorOffset
|
9035
|
-
|
9036
|
-
|
9037
|
-
|
9038
|
-
|
9039
|
-
|
9040
|
-
|
9041
|
-
|
9042
|
-
|
9085
|
+
offset = selection.anchorOffset,
|
9086
|
+
childNodes = [],
|
9087
|
+
range, contentNodes, lastNode;
|
9088
|
+
|
9089
|
+
if (node) {
|
9090
|
+
if (offset === 0) {
|
9091
|
+
var prevNode = this.getPreviousNode(node, true),
|
9092
|
+
prevLeaf = prevNode ? wysihtml5.dom.domNode(prevNode).lastLeafNode((this.unselectableClass) ? {leafClasses: [this.unselectableClass]} : false) : null;
|
9093
|
+
if (prevLeaf) {
|
9094
|
+
var uneditables = this.getOwnUneditables();
|
9095
|
+
for (var i = 0, maxi = uneditables.length; i < maxi; i++) {
|
9096
|
+
if (prevLeaf === uneditables[i]) {
|
9097
|
+
return uneditables[i];
|
9098
|
+
}
|
9099
|
+
}
|
9100
|
+
}
|
9101
|
+
} else {
|
9102
|
+
range = selection.getRangeAt(0);
|
9103
|
+
range.setStart(range.startContainer, range.startOffset - 1);
|
9104
|
+
// TODO: make getting children on range a separate funtion
|
9105
|
+
if (range) {
|
9106
|
+
contentNodes = range.getNodes([1,3]);
|
9107
|
+
for (var n = 0, max = contentNodes.length; n < max; n++) {
|
9108
|
+
if (contentNodes[n].parentNode && contentNodes[n].parentNode === node) {
|
9109
|
+
childNodes.push(contentNodes[n]);
|
9110
|
+
}
|
9043
9111
|
}
|
9044
9112
|
}
|
9113
|
+
lastNode = childNodes.length > 0 ? childNodes[childNodes.length -1] : null;
|
9114
|
+
if (lastNode && lastNode.nodeType === 1 && wysihtml5.dom.hasClass(lastNode, this.unselectableClass)) {
|
9115
|
+
return lastNode;
|
9116
|
+
}
|
9117
|
+
|
9045
9118
|
}
|
9046
9119
|
}
|
9047
9120
|
return false;
|
@@ -9495,6 +9568,10 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9495
9568
|
return this.getSelection().toHtml();
|
9496
9569
|
},
|
9497
9570
|
|
9571
|
+
getPlainText: function () {
|
9572
|
+
return this.getSelection().toString();
|
9573
|
+
},
|
9574
|
+
|
9498
9575
|
isEndToEndInNode: function(nodeNames) {
|
9499
9576
|
var range = this.getRange(),
|
9500
9577
|
parentElement = range.commonAncestorContainer,
|
@@ -11998,11 +12075,11 @@ wysihtml5.views.View = Base.extend(
|
|
11998
12075
|
},
|
11999
12076
|
|
12000
12077
|
focus: function() {
|
12001
|
-
if (this.element.ownerDocument.querySelector(":focus") === this.element) {
|
12078
|
+
if (this.element && this.element.ownerDocument && this.element.ownerDocument.querySelector(":focus") === this.element) {
|
12002
12079
|
return;
|
12003
12080
|
}
|
12004
12081
|
|
12005
|
-
try { this.element.focus(); } catch(e) {}
|
12082
|
+
try { if(this.element) { this.element.focus(); } } catch(e) {}
|
12006
12083
|
},
|
12007
12084
|
|
12008
12085
|
hide: function() {
|
@@ -12285,18 +12362,17 @@ wysihtml5.views.View = Base.extend(
|
|
12285
12362
|
if (!supportsAutoLinking || (supportsAutoLinking && supportsDisablingOfAutoLinking)) {
|
12286
12363
|
this.parent.on("newword:composer", function() {
|
12287
12364
|
if (dom.getTextContent(that.element).match(dom.autoLink.URL_REG_EXP)) {
|
12288
|
-
that.selection.
|
12289
|
-
|
12290
|
-
|
12365
|
+
var nodeWithSelection = that.selection.getSelectedNode(),
|
12366
|
+
uneditables = that.element.querySelectorAll("." + that.config.uneditableContainerClassname),
|
12367
|
+
isInUneditable = false;
|
12291
12368
|
|
12292
|
-
|
12293
|
-
|
12294
|
-
|
12295
|
-
}
|
12369
|
+
for (var i = uneditables.length; i--;) {
|
12370
|
+
if (wysihtml5.dom.contains(uneditables[i], nodeWithSelection)) {
|
12371
|
+
isInUneditable = true;
|
12296
12372
|
}
|
12373
|
+
}
|
12297
12374
|
|
12298
|
-
|
12299
|
-
});
|
12375
|
+
if (!isInUneditable) dom.autoLink(nodeWithSelection, [that.config.uneditableContainerClassname]);
|
12300
12376
|
}
|
12301
12377
|
});
|
12302
12378
|
|
@@ -12766,7 +12842,13 @@ wysihtml5.views.View = Base.extend(
|
|
12766
12842
|
// Do a special delete if caret would delete uneditable
|
12767
12843
|
if (beforeUneditable) {
|
12768
12844
|
event.preventDefault();
|
12769
|
-
|
12845
|
+
// If customevents present notify element of being deleted
|
12846
|
+
// TODO: Investigate if browser support can be extended
|
12847
|
+
try {
|
12848
|
+
var ev = new CustomEvent("wysihtml5:uneditable:delete");
|
12849
|
+
beforeUneditable.dispatchEvent(ev);
|
12850
|
+
} catch (err) {}
|
12851
|
+
beforeUneditable.parentNode.removeChild(beforeUneditable);
|
12770
12852
|
}
|
12771
12853
|
}
|
12772
12854
|
} else {
|
@@ -12877,6 +12959,7 @@ wysihtml5.views.View = Base.extend(
|
|
12877
12959
|
dom.observe(element, "copy", function(event) {
|
12878
12960
|
if (event.clipboardData) {
|
12879
12961
|
event.clipboardData.setData("text/html", that.config.copyedFromMarking + that.selection.getHtml());
|
12962
|
+
event.clipboardData.setData("text/plain", that.selection.getPlainText());
|
12880
12963
|
event.preventDefault();
|
12881
12964
|
}
|
12882
12965
|
that.parent.fire(event.type, event).fire(event.type + ":composer", event);
|
@@ -12909,6 +12992,17 @@ wysihtml5.views.View = Base.extend(
|
|
12909
12992
|
});
|
12910
12993
|
}
|
12911
12994
|
|
12995
|
+
// If uneditables configured makes click on uneditable moves caret after clicked element (so it can be deleted like text)
|
12996
|
+
// If uneditable needs text selection itself event.stopPropagation can be used to prevent this behaviour
|
12997
|
+
if (this.config.uneditableContainerClassname) {
|
12998
|
+
dom.observe(element, "click", function(event) {
|
12999
|
+
var uneditable = wysihtml5.dom.getParentElement(event.target, { className: that.config.uneditableContainerClassname }, false, that.element);
|
13000
|
+
if (uneditable) {
|
13001
|
+
that.selection.setAfter(uneditable);
|
13002
|
+
}
|
13003
|
+
});
|
13004
|
+
}
|
13005
|
+
|
12912
13006
|
if (!browser.canSelectImagesInContentEditable()) {
|
12913
13007
|
dom.observe(element, "drop", function(event) {
|
12914
13008
|
// TODO: if I knew how to get dropped elements list from event I could limit it to only IMG element case
|
@@ -25,7 +25,7 @@ if(!Array.isArray) {
|
|
25
25
|
return Object.prototype.toString.call(arg) === '[object Array]';
|
26
26
|
};
|
27
27
|
};/**
|
28
|
-
* @license wysihtml5x v0.4.
|
28
|
+
* @license wysihtml5x v0.4.16
|
29
29
|
* https://github.com/Edicy/wysihtml5
|
30
30
|
*
|
31
31
|
* Author: Christopher Blum (https://github.com/tiff)
|
@@ -36,7 +36,7 @@ if(!Array.isArray) {
|
|
36
36
|
*
|
37
37
|
*/
|
38
38
|
var wysihtml5 = {
|
39
|
-
version: "0.4.
|
39
|
+
version: "0.4.16",
|
40
40
|
|
41
41
|
// namespaces
|
42
42
|
commands: {},
|
@@ -5369,9 +5369,36 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
|
|
5369
5369
|
}
|
5370
5370
|
|
5371
5371
|
return nextNode;
|
5372
|
-
}
|
5372
|
+
},
|
5373
|
+
|
5374
|
+
// Traverses a node for last children and their chidren (including itself), and finds the last node that has no children.
|
5375
|
+
// Array of classes for forced last-leaves (ex: uneditable-container) can be defined (options = {leafClasses: [...]})
|
5376
|
+
// Useful for finding the actually visible element before cursor
|
5377
|
+
lastLeafNode: function(options) {
|
5378
|
+
var lastChild;
|
5379
|
+
|
5380
|
+
// Returns non-element nodes
|
5381
|
+
if (node.nodeType !== 1) {
|
5382
|
+
return node;
|
5383
|
+
}
|
5373
5384
|
|
5385
|
+
// Returns if element is leaf
|
5386
|
+
lastChild = node.lastChild;
|
5387
|
+
if (!lastChild) {
|
5388
|
+
return node;
|
5389
|
+
}
|
5390
|
+
|
5391
|
+
// Returns if element is of of options.leafClasses leaf
|
5392
|
+
if (options && options.leafClasses) {
|
5393
|
+
for (var i = options.leafClasses.length; i--;) {
|
5394
|
+
if (wysihtml5.dom.hasClass(node, options.leafClasses[i])) {
|
5395
|
+
return node;
|
5396
|
+
}
|
5397
|
+
}
|
5398
|
+
}
|
5374
5399
|
|
5400
|
+
return wysihtml5.dom.domNode(lastChild).lastLeafNode(options);
|
5401
|
+
}
|
5375
5402
|
|
5376
5403
|
};
|
5377
5404
|
};
|
@@ -5494,8 +5521,13 @@ wysihtml5.dom.getParentElement = (function() {
|
|
5494
5521
|
|
5495
5522
|
levels = levels || 50; // Go max 50 nodes upwards from current node
|
5496
5523
|
|
5524
|
+
// make the matching class regex from class name if omitted
|
5525
|
+
if (findByClass && !matchingSet.classRegExp) {
|
5526
|
+
matchingSet.classRegExp = new RegExp(matchingSet.className);
|
5527
|
+
}
|
5528
|
+
|
5497
5529
|
while (levels-- && node && node.nodeName !== "BODY" && (!container || node !== container)) {
|
5498
|
-
if (_isElement(node) && _isSameNodeName(node.nodeName, matchingSet.nodeName) &&
|
5530
|
+
if (_isElement(node) && (!matchingSet.nodeName || _isSameNodeName(node.nodeName, matchingSet.nodeName)) &&
|
5499
5531
|
(!findByStyle || _hasStyle(node, matchingSet.cssStyle, matchingSet.styleRegExp)) &&
|
5500
5532
|
(!findByClass || _hasClassName(node, matchingSet.className, matchingSet.classRegExp))
|
5501
5533
|
) {
|
@@ -8922,15 +8954,25 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
8922
8954
|
return false;
|
8923
8955
|
},
|
8924
8956
|
|
8957
|
+
// deletes selection contents making sure uneditables/unselectables are not partially deleted
|
8925
8958
|
deleteContents: function() {
|
8926
|
-
var
|
8927
|
-
|
8928
|
-
|
8959
|
+
var range = this.getRange(),
|
8960
|
+
startParent, endParent;
|
8961
|
+
|
8962
|
+
if (this.unselectableClass) {
|
8963
|
+
if ((startParent = wysihtml5.dom.getParentElement(range.startContainer, { className: this.unselectableClass }, false, this.contain))) {
|
8964
|
+
range.setStartBefore(startParent);
|
8965
|
+
}
|
8966
|
+
if ((endParent = wysihtml5.dom.getParentElement(range.endContainer, { className: this.unselectableClass }, false, this.contain))) {
|
8967
|
+
range.setEndAfter(endParent);
|
8968
|
+
}
|
8929
8969
|
}
|
8930
|
-
|
8970
|
+
range.deleteContents();
|
8971
|
+
this.setSelection(range);
|
8931
8972
|
},
|
8932
8973
|
|
8933
8974
|
getPreviousNode: function(node, ignoreEmpty) {
|
8975
|
+
var displayStyle;
|
8934
8976
|
if (!node) {
|
8935
8977
|
var selection = this.getSelection();
|
8936
8978
|
node = selection.anchorNode;
|
@@ -8951,12 +8993,19 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
8951
8993
|
// do not count comments and other node types
|
8952
8994
|
ret = this.getPreviousNode(ret, ignoreEmpty);
|
8953
8995
|
} else if (ret && ret.nodeType === 3 && (/^\s*$/).test(ret.textContent)) {
|
8954
|
-
// do not count empty textnodes as
|
8996
|
+
// do not count empty textnodes as previous nodes
|
8955
8997
|
ret = this.getPreviousNode(ret, ignoreEmpty);
|
8956
|
-
} else if (ignoreEmpty && ret && ret.nodeType === 1
|
8998
|
+
} else if (ignoreEmpty && ret && ret.nodeType === 1) {
|
8957
8999
|
// Do not count empty nodes if param set.
|
8958
|
-
// Contenteditable tends to bypass and delete these silently when deleting with caret
|
8959
|
-
|
9000
|
+
// Contenteditable tends to bypass and delete these silently when deleting with caret when element is inline-like
|
9001
|
+
displayStyle = wysihtml5.dom.getStyle("display").from(ret);
|
9002
|
+
if (
|
9003
|
+
!wysihtml5.lang.array(["BR", "HR", "IMG"]).contains(ret.nodeName) &&
|
9004
|
+
!wysihtml5.lang.array(["block", "inline-block", "flex", "list-item", "table"]).contains(displayStyle) &&
|
9005
|
+
(/^[\s]*$/).test(ret.innerHTML)
|
9006
|
+
) {
|
9007
|
+
ret = this.getPreviousNode(ret, ignoreEmpty);
|
9008
|
+
}
|
8960
9009
|
} else if (!ret && node !== this.contain) {
|
8961
9010
|
parent = node.parentNode;
|
8962
9011
|
if (parent !== this.contain) {
|
@@ -9008,12 +9057,14 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9008
9057
|
range = this.getRange(),
|
9009
9058
|
startNode = range.startContainer;
|
9010
9059
|
|
9011
|
-
if (startNode
|
9012
|
-
|
9013
|
-
|
9014
|
-
|
9015
|
-
|
9016
|
-
|
9060
|
+
if (startNode) {
|
9061
|
+
if (startNode.nodeType === wysihtml5.TEXT_NODE) {
|
9062
|
+
return this.isCollapsed() && (startNode.nodeType === wysihtml5.TEXT_NODE && (/^\s*$/).test(startNode.data.substr(0,range.startOffset)));
|
9063
|
+
} else {
|
9064
|
+
r.selectNodeContents(this.getRange().commonAncestorContainer);
|
9065
|
+
r.collapse(true);
|
9066
|
+
return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
|
9067
|
+
}
|
9017
9068
|
}
|
9018
9069
|
},
|
9019
9070
|
|
@@ -9021,9 +9072,9 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9021
9072
|
var selection = this.getSelection(),
|
9022
9073
|
node = selection.anchorNode,
|
9023
9074
|
offset = selection.anchorOffset;
|
9024
|
-
if (ofNode) {
|
9075
|
+
if (ofNode && node) {
|
9025
9076
|
return (offset === 0 && (node.nodeName && node.nodeName === ofNode.toUpperCase() || wysihtml5.dom.getParentElement(node.parentNode, { nodeName: ofNode }, 1)));
|
9026
|
-
} else {
|
9077
|
+
} else if (node) {
|
9027
9078
|
return (offset === 0 && !this.getPreviousNode(node, true));
|
9028
9079
|
}
|
9029
9080
|
},
|
@@ -9031,17 +9082,39 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9031
9082
|
caretIsBeforeUneditable: function() {
|
9032
9083
|
var selection = this.getSelection(),
|
9033
9084
|
node = selection.anchorNode,
|
9034
|
-
offset = selection.anchorOffset
|
9035
|
-
|
9036
|
-
|
9037
|
-
|
9038
|
-
|
9039
|
-
|
9040
|
-
|
9041
|
-
|
9042
|
-
|
9085
|
+
offset = selection.anchorOffset,
|
9086
|
+
childNodes = [],
|
9087
|
+
range, contentNodes, lastNode;
|
9088
|
+
|
9089
|
+
if (node) {
|
9090
|
+
if (offset === 0) {
|
9091
|
+
var prevNode = this.getPreviousNode(node, true),
|
9092
|
+
prevLeaf = prevNode ? wysihtml5.dom.domNode(prevNode).lastLeafNode((this.unselectableClass) ? {leafClasses: [this.unselectableClass]} : false) : null;
|
9093
|
+
if (prevLeaf) {
|
9094
|
+
var uneditables = this.getOwnUneditables();
|
9095
|
+
for (var i = 0, maxi = uneditables.length; i < maxi; i++) {
|
9096
|
+
if (prevLeaf === uneditables[i]) {
|
9097
|
+
return uneditables[i];
|
9098
|
+
}
|
9099
|
+
}
|
9100
|
+
}
|
9101
|
+
} else {
|
9102
|
+
range = selection.getRangeAt(0);
|
9103
|
+
range.setStart(range.startContainer, range.startOffset - 1);
|
9104
|
+
// TODO: make getting children on range a separate funtion
|
9105
|
+
if (range) {
|
9106
|
+
contentNodes = range.getNodes([1,3]);
|
9107
|
+
for (var n = 0, max = contentNodes.length; n < max; n++) {
|
9108
|
+
if (contentNodes[n].parentNode && contentNodes[n].parentNode === node) {
|
9109
|
+
childNodes.push(contentNodes[n]);
|
9110
|
+
}
|
9043
9111
|
}
|
9044
9112
|
}
|
9113
|
+
lastNode = childNodes.length > 0 ? childNodes[childNodes.length -1] : null;
|
9114
|
+
if (lastNode && lastNode.nodeType === 1 && wysihtml5.dom.hasClass(lastNode, this.unselectableClass)) {
|
9115
|
+
return lastNode;
|
9116
|
+
}
|
9117
|
+
|
9045
9118
|
}
|
9046
9119
|
}
|
9047
9120
|
return false;
|
@@ -9495,6 +9568,10 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9495
9568
|
return this.getSelection().toHtml();
|
9496
9569
|
},
|
9497
9570
|
|
9571
|
+
getPlainText: function () {
|
9572
|
+
return this.getSelection().toString();
|
9573
|
+
},
|
9574
|
+
|
9498
9575
|
isEndToEndInNode: function(nodeNames) {
|
9499
9576
|
var range = this.getRange(),
|
9500
9577
|
parentElement = range.commonAncestorContainer,
|
@@ -11998,11 +12075,11 @@ wysihtml5.views.View = Base.extend(
|
|
11998
12075
|
},
|
11999
12076
|
|
12000
12077
|
focus: function() {
|
12001
|
-
if (this.element.ownerDocument.querySelector(":focus") === this.element) {
|
12078
|
+
if (this.element && this.element.ownerDocument && this.element.ownerDocument.querySelector(":focus") === this.element) {
|
12002
12079
|
return;
|
12003
12080
|
}
|
12004
12081
|
|
12005
|
-
try { this.element.focus(); } catch(e) {}
|
12082
|
+
try { if(this.element) { this.element.focus(); } } catch(e) {}
|
12006
12083
|
},
|
12007
12084
|
|
12008
12085
|
hide: function() {
|
@@ -12285,18 +12362,17 @@ wysihtml5.views.View = Base.extend(
|
|
12285
12362
|
if (!supportsAutoLinking || (supportsAutoLinking && supportsDisablingOfAutoLinking)) {
|
12286
12363
|
this.parent.on("newword:composer", function() {
|
12287
12364
|
if (dom.getTextContent(that.element).match(dom.autoLink.URL_REG_EXP)) {
|
12288
|
-
that.selection.
|
12289
|
-
|
12290
|
-
|
12365
|
+
var nodeWithSelection = that.selection.getSelectedNode(),
|
12366
|
+
uneditables = that.element.querySelectorAll("." + that.config.uneditableContainerClassname),
|
12367
|
+
isInUneditable = false;
|
12291
12368
|
|
12292
|
-
|
12293
|
-
|
12294
|
-
|
12295
|
-
}
|
12369
|
+
for (var i = uneditables.length; i--;) {
|
12370
|
+
if (wysihtml5.dom.contains(uneditables[i], nodeWithSelection)) {
|
12371
|
+
isInUneditable = true;
|
12296
12372
|
}
|
12373
|
+
}
|
12297
12374
|
|
12298
|
-
|
12299
|
-
});
|
12375
|
+
if (!isInUneditable) dom.autoLink(nodeWithSelection, [that.config.uneditableContainerClassname]);
|
12300
12376
|
}
|
12301
12377
|
});
|
12302
12378
|
|
@@ -12766,7 +12842,13 @@ wysihtml5.views.View = Base.extend(
|
|
12766
12842
|
// Do a special delete if caret would delete uneditable
|
12767
12843
|
if (beforeUneditable) {
|
12768
12844
|
event.preventDefault();
|
12769
|
-
|
12845
|
+
// If customevents present notify element of being deleted
|
12846
|
+
// TODO: Investigate if browser support can be extended
|
12847
|
+
try {
|
12848
|
+
var ev = new CustomEvent("wysihtml5:uneditable:delete");
|
12849
|
+
beforeUneditable.dispatchEvent(ev);
|
12850
|
+
} catch (err) {}
|
12851
|
+
beforeUneditable.parentNode.removeChild(beforeUneditable);
|
12770
12852
|
}
|
12771
12853
|
}
|
12772
12854
|
} else {
|
@@ -12877,6 +12959,7 @@ wysihtml5.views.View = Base.extend(
|
|
12877
12959
|
dom.observe(element, "copy", function(event) {
|
12878
12960
|
if (event.clipboardData) {
|
12879
12961
|
event.clipboardData.setData("text/html", that.config.copyedFromMarking + that.selection.getHtml());
|
12962
|
+
event.clipboardData.setData("text/plain", that.selection.getPlainText());
|
12880
12963
|
event.preventDefault();
|
12881
12964
|
}
|
12882
12965
|
that.parent.fire(event.type, event).fire(event.type + ":composer", event);
|
@@ -12909,6 +12992,17 @@ wysihtml5.views.View = Base.extend(
|
|
12909
12992
|
});
|
12910
12993
|
}
|
12911
12994
|
|
12995
|
+
// If uneditables configured makes click on uneditable moves caret after clicked element (so it can be deleted like text)
|
12996
|
+
// If uneditable needs text selection itself event.stopPropagation can be used to prevent this behaviour
|
12997
|
+
if (this.config.uneditableContainerClassname) {
|
12998
|
+
dom.observe(element, "click", function(event) {
|
12999
|
+
var uneditable = wysihtml5.dom.getParentElement(event.target, { className: that.config.uneditableContainerClassname }, false, that.element);
|
13000
|
+
if (uneditable) {
|
13001
|
+
that.selection.setAfter(uneditable);
|
13002
|
+
}
|
13003
|
+
});
|
13004
|
+
}
|
13005
|
+
|
12912
13006
|
if (!browser.canSelectImagesInContentEditable()) {
|
12913
13007
|
dom.observe(element, "drop", function(event) {
|
12914
13008
|
// TODO: if I knew how to get dropped elements list from event I could limit it to only IMG element case
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wysihtml5x-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanel Jakobsoo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|