wysihtml5x-rails 0.4.15 → 0.4.16
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/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
|