wysihtml-rails 0.5.0.beta5 → 0.5.0.beta6
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 +218 -99
- data/vendor/assets/javascripts/wysihtml.js +204 -81
- 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: 169166e826e5cf81830b93add509b5443904cdbb
|
4
|
+
data.tar.gz: b3576b0d1ad6ac31988caa0e25e41e6920fb9e02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d0909357b5235b426c651ce8119d86f4a50d431e5e3b9725f511d1afe6663d310f01407f61da69beb4196d0bf196cd82a235ce510ebf7d12826d349fa7f025
|
7
|
+
data.tar.gz: 21b029d33b26b2ea0b43078dae432823a3eff5937526f648e430d611dbc389ce3af640573d4dd4d798e7d06e834877d8405997853cea7192c0a9be9725b5345f
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license wysihtml5x v0.5.0-
|
2
|
+
* @license wysihtml5x v0.5.0-beta6
|
3
3
|
* https://github.com/Edicy/wysihtml5
|
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-beta6",
|
14
14
|
|
15
15
|
// namespaces
|
16
16
|
commands: {},
|
@@ -6692,7 +6692,7 @@ wysihtml5.dom.parse = function(elementOrHtml_current, config_current) {
|
|
6692
6692
|
}
|
6693
6693
|
|
6694
6694
|
function _checkAttribute(attributeName, attributeValue, methodName, nodeName) {
|
6695
|
-
var method = attributeCheckMethods[methodName],
|
6695
|
+
var method = wysihtml5.lang.object(methodName).isFunction() ? methodName : attributeCheckMethods[methodName],
|
6696
6696
|
newAttributeValue;
|
6697
6697
|
|
6698
6698
|
if (method) {
|
@@ -9304,6 +9304,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9304
9304
|
}
|
9305
9305
|
};
|
9306
9306
|
|
9307
|
+
caretPlaceholder.className = '_wysihtml5-temp-caret-fix';
|
9307
9308
|
caretPlaceholder.style.position = 'absolute';
|
9308
9309
|
caretPlaceholder.style.display = 'block';
|
9309
9310
|
caretPlaceholder.style.minWidth = '1px';
|
@@ -9339,7 +9340,9 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9339
9340
|
fixWebkitSelection = function() {
|
9340
9341
|
// Webkit fails to add selection if there are no textnodes in that region
|
9341
9342
|
// (like an uneditable container at the end of content).
|
9342
|
-
|
9343
|
+
var parent = node.parentNode,
|
9344
|
+
lastSibling = parent ? parent.childNodes[parent.childNodes.length - 1] : null;
|
9345
|
+
if (!sel || (lastSibling === node && this.win.getComputedStyle(node).display === "block")) {
|
9343
9346
|
if (notVisual) {
|
9344
9347
|
// If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
|
9345
9348
|
// and remove itself in call stack end instead on user interaction
|
@@ -9640,45 +9643,69 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9640
9643
|
}
|
9641
9644
|
},
|
9642
9645
|
|
9643
|
-
|
9644
|
-
|
9645
|
-
|
9646
|
-
|
9647
|
-
|
9648
|
-
|
9649
|
-
|
9650
|
-
|
9651
|
-
|
9652
|
-
|
9653
|
-
|
9654
|
-
|
9655
|
-
|
9656
|
-
|
9657
|
-
|
9658
|
-
|
9659
|
-
|
9660
|
-
|
9646
|
+
// Returns object describing node/text before selection
|
9647
|
+
// If includePrevLeaves is true returns also previous last leaf child if selection is in the beginning of current node
|
9648
|
+
getBeforeSelection: function(includePrevLeaves) {
|
9649
|
+
var sel = this.getSelection(),
|
9650
|
+
startNode = (sel.isBackwards()) ? sel.focusNode : sel.anchorNode,
|
9651
|
+
startOffset = (sel.isBackwards()) ? sel.focusOffset : sel.anchorOffset,
|
9652
|
+
rng = this.createRange(), endNode, inTmpCaret;
|
9653
|
+
|
9654
|
+
// Escape temproray helper nodes if selection in them
|
9655
|
+
inTmpCaret = wysihtml5.dom.getParentElement(startNode, { query: '._wysihtml5-temp-caret-fix' }, 1);
|
9656
|
+
if (inTmpCaret) {
|
9657
|
+
startNode = inTmpCaret.parentNode;
|
9658
|
+
startOffset = Array.prototype.indexOf.call(startNode.childNodes, inTmpCaret);
|
9659
|
+
}
|
9660
|
+
|
9661
|
+
if (startNode) {
|
9662
|
+
if (startOffset > 0) {
|
9663
|
+
if (startNode.nodeType === 3) {
|
9664
|
+
rng.setStart(startNode, 0);
|
9665
|
+
rng.setEnd(startNode, startOffset);
|
9666
|
+
return {
|
9667
|
+
type: "text",
|
9668
|
+
range: rng,
|
9669
|
+
offset : startOffset,
|
9670
|
+
node: startNode
|
9671
|
+
};
|
9672
|
+
} else {
|
9673
|
+
rng.setStartBefore(startNode.childNodes[0]);
|
9674
|
+
endNode = startNode.childNodes[startOffset - 1];
|
9675
|
+
rng.setEndAfter(endNode);
|
9676
|
+
return {
|
9677
|
+
type: "element",
|
9678
|
+
range: rng,
|
9679
|
+
offset : startOffset,
|
9680
|
+
node: endNode
|
9681
|
+
};
|
9661
9682
|
}
|
9662
9683
|
} else {
|
9663
|
-
|
9664
|
-
|
9665
|
-
|
9666
|
-
|
9667
|
-
|
9668
|
-
|
9669
|
-
|
9670
|
-
|
9671
|
-
|
9684
|
+
rng.setStartAndEnd(startNode, 0);
|
9685
|
+
|
9686
|
+
if (includePrevLeaves) {
|
9687
|
+
var prevNode = this.getPreviousNode(startNode, true),
|
9688
|
+
prevLeaf = prevNode ? wysihtml5.dom.domNode(prevNode).lastLeafNode() : null;
|
9689
|
+
|
9690
|
+
if (prevLeaf) {
|
9691
|
+
return {
|
9692
|
+
type: "leafnode",
|
9693
|
+
range: rng,
|
9694
|
+
offset : startOffset,
|
9695
|
+
node: prevLeaf
|
9696
|
+
};
|
9672
9697
|
}
|
9673
9698
|
}
|
9674
|
-
lastNode = childNodes.length > 0 ? childNodes[childNodes.length -1] : null;
|
9675
|
-
if (lastNode && lastNode.nodeType === 1 && wysihtml5.dom.hasClass(lastNode, this.unselectableClass)) {
|
9676
|
-
return lastNode;
|
9677
|
-
}
|
9678
9699
|
|
9700
|
+
return {
|
9701
|
+
type: "none",
|
9702
|
+
range: rng,
|
9703
|
+
offset : startOffset,
|
9704
|
+
node: startNode
|
9705
|
+
};
|
9679
9706
|
}
|
9680
9707
|
}
|
9681
|
-
return
|
9708
|
+
return null;
|
9682
9709
|
},
|
9683
9710
|
|
9684
9711
|
// TODO: Figure out a method from following 2 that would work universally
|
@@ -9758,7 +9785,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9758
9785
|
}
|
9759
9786
|
this.setSelection(newRange);
|
9760
9787
|
for (var i = caretPlaceholder.length; i--;) {
|
9761
|
-
|
9788
|
+
caretPlaceholder[i].parentNode.removeChild(caretPlaceholder[i]);
|
9762
9789
|
}
|
9763
9790
|
|
9764
9791
|
} else {
|
@@ -12414,7 +12441,7 @@ wysihtml5.Commands = Base.extend(
|
|
12414
12441
|
for (row = 0; row < value.rows; row ++) {
|
12415
12442
|
html += '<tr>';
|
12416
12443
|
for (col = 0; col < value.cols; col ++) {
|
12417
|
-
html += "<td
|
12444
|
+
html += "<td></td>";
|
12418
12445
|
}
|
12419
12446
|
html += '</tr>';
|
12420
12447
|
}
|
@@ -13670,59 +13697,98 @@ wysihtml5.views.View = Base.extend(
|
|
13670
13697
|
}
|
13671
13698
|
};
|
13672
13699
|
|
13700
|
+
// Override for giving user ability to delete last line break in table cell
|
13701
|
+
var fixLastBrDeletionInTable = function(composer, force) {
|
13702
|
+
if (composer.selection.caretIsLastInSelection()) {
|
13703
|
+
var sel = composer.selection.getSelection(),
|
13704
|
+
aNode = sel.anchorNode;
|
13705
|
+
if (aNode && aNode.nodeType === 1 && (wysihtml5.dom.getParentElement(aNode, {query: 'td, th'}, false, composer.element) || force)) {
|
13706
|
+
var nextNode = aNode.childNodes[sel.anchorOffset];
|
13707
|
+
if (nextNode && nextNode.nodeType === 1 & nextNode.nodeName === "BR") {
|
13708
|
+
nextNode.parentNode.removeChild(nextNode);
|
13709
|
+
return true;
|
13710
|
+
}
|
13711
|
+
}
|
13712
|
+
}
|
13713
|
+
return false;
|
13714
|
+
};
|
13715
|
+
|
13716
|
+
// If found an uneditable before caret then notify it before deletion
|
13717
|
+
var handleUneditableDeletion = function(composer) {
|
13718
|
+
var before = composer.selection.getBeforeSelection(true);
|
13719
|
+
if (before && (before.type === "element" || before.type === "leafnode") && before.node.nodeType === 1 && before.node.classList.contains(composer.config.uneditableContainerClassname)) {
|
13720
|
+
if (fixLastBrDeletionInTable(composer, true)) {
|
13721
|
+
return true;
|
13722
|
+
}
|
13723
|
+
try {
|
13724
|
+
var ev = new CustomEvent("wysihtml5:uneditable:delete");
|
13725
|
+
before.node.dispatchEvent(ev);
|
13726
|
+
} catch (err) {}
|
13727
|
+
before.node.parentNode.removeChild(before.node);
|
13728
|
+
return true;
|
13729
|
+
}
|
13730
|
+
return false;
|
13731
|
+
};
|
13732
|
+
|
13733
|
+
// Deletion with caret in the beginning of headings needs special attention
|
13734
|
+
// Heading does not concate text to previous block node correctly (browsers do unexpected miracles here especially webkit)
|
13735
|
+
var fixDeleteInTheBeginnigOfHeading = function(composer) {
|
13736
|
+
var selection = composer.selection;
|
13737
|
+
|
13738
|
+
if (selection.caretIsFirstInSelection() &&
|
13739
|
+
selection.getPreviousNode() &&
|
13740
|
+
selection.getPreviousNode().nodeName &&
|
13741
|
+
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
|
13742
|
+
) {
|
13743
|
+
var prevNode = selection.getPreviousNode();
|
13744
|
+
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
|
13745
|
+
// If heading is empty remove the heading node
|
13746
|
+
prevNode.parentNode.removeChild(prevNode);
|
13747
|
+
return true;
|
13748
|
+
} else {
|
13749
|
+
if (prevNode.lastChild) {
|
13750
|
+
var selNode = prevNode.lastChild,
|
13751
|
+
curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
|
13752
|
+
if (prevNode) {
|
13753
|
+
if (curNode) {
|
13754
|
+
while (curNode.firstChild) {
|
13755
|
+
prevNode.appendChild(curNode.firstChild);
|
13756
|
+
}
|
13757
|
+
selection.setAfter(selNode);
|
13758
|
+
return true;
|
13759
|
+
} else if (selection.getSelectedNode().nodeType === 3) {
|
13760
|
+
prevNode.appendChild(selection.getSelectedNode());
|
13761
|
+
selection.setAfter(selNode);
|
13762
|
+
return true;
|
13763
|
+
}
|
13764
|
+
}
|
13765
|
+
}
|
13766
|
+
}
|
13767
|
+
}
|
13768
|
+
return false;
|
13769
|
+
};
|
13770
|
+
|
13673
13771
|
var handleDeleteKeyPress = function(event, composer) {
|
13674
13772
|
var selection = composer.selection,
|
13675
13773
|
element = composer.element;
|
13676
13774
|
|
13677
13775
|
if (selection.isCollapsed()) {
|
13678
13776
|
if (selection.caretIsInTheBeginnig('li')) {
|
13777
|
+
// delete in the beginnig of LI will outdent not delete
|
13679
13778
|
event.preventDefault();
|
13680
13779
|
composer.commands.exec('outdentList');
|
13681
|
-
} else if (selection.caretIsInTheBeginnig()) {
|
13682
|
-
event.preventDefault();
|
13683
13780
|
} else {
|
13684
|
-
if (
|
13685
|
-
|
13686
|
-
|
13687
|
-
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
|
13688
|
-
) {
|
13689
|
-
var prevNode = selection.getPreviousNode();
|
13690
|
-
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
|
13691
|
-
// heading is empty
|
13692
|
-
event.preventDefault();
|
13693
|
-
prevNode.parentNode.removeChild(prevNode);
|
13694
|
-
} else {
|
13695
|
-
if (prevNode.lastChild) {
|
13696
|
-
var selNode = prevNode.lastChild,
|
13697
|
-
curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
|
13698
|
-
if (prevNode) {
|
13699
|
-
if (curNode) {
|
13700
|
-
event.preventDefault();
|
13701
|
-
while (curNode.firstChild) {
|
13702
|
-
prevNode.appendChild(curNode.firstChild);
|
13703
|
-
}
|
13704
|
-
selection.setAfter(selNode);
|
13705
|
-
} else if (selection.getSelectedNode().nodeType === 3) {
|
13706
|
-
event.preventDefault();
|
13707
|
-
prevNode.appendChild(selection.getSelectedNode());
|
13708
|
-
selection.setAfter(selNode);
|
13709
|
-
}
|
13710
|
-
}
|
13711
|
-
}
|
13712
|
-
}
|
13781
|
+
if (fixDeleteInTheBeginnigOfHeading(composer)) {
|
13782
|
+
event.preventDefault();
|
13783
|
+
return;
|
13713
13784
|
}
|
13714
|
-
|
13715
|
-
var beforeUneditable = selection.caretIsBeforeUneditable();
|
13716
|
-
// Do a special delete if caret would delete uneditable
|
13717
|
-
if (beforeUneditable) {
|
13785
|
+
if (fixLastBrDeletionInTable(composer)) {
|
13718
13786
|
event.preventDefault();
|
13719
|
-
|
13720
|
-
|
13721
|
-
|
13722
|
-
|
13723
|
-
|
13724
|
-
} catch (err) {}
|
13725
|
-
beforeUneditable.parentNode.removeChild(beforeUneditable);
|
13787
|
+
return;
|
13788
|
+
}
|
13789
|
+
if (handleUneditableDeletion(composer)) {
|
13790
|
+
event.preventDefault();
|
13791
|
+
return;
|
13726
13792
|
}
|
13727
13793
|
}
|
13728
13794
|
} else {
|
@@ -14089,6 +14155,61 @@ wysihtml5.views.View = Base.extend(
|
|
14089
14155
|
}
|
14090
14156
|
});
|
14091
14157
|
})(wysihtml5);
|
14158
|
+
;(function(wysihtml5) {
|
14159
|
+
|
14160
|
+
wysihtml5.views.SourceView = Base.extend(
|
14161
|
+
/** @scope wysihtml5.views.SourceView.prototype */ {
|
14162
|
+
|
14163
|
+
constructor: function(editor, composer) {
|
14164
|
+
this.editor = editor;
|
14165
|
+
this.composer = composer;
|
14166
|
+
|
14167
|
+
this._observe();
|
14168
|
+
},
|
14169
|
+
|
14170
|
+
switchToTextarea: function(shouldParseHtml) {
|
14171
|
+
var composerStyles = this.composer.win.getComputedStyle(this.composer.element),
|
14172
|
+
width = parseFloat(composerStyles.width),
|
14173
|
+
height = Math.max(parseFloat(composerStyles.height), 100);
|
14174
|
+
|
14175
|
+
if (!this.textarea) {
|
14176
|
+
this.textarea = this.composer.doc.createElement('textarea');
|
14177
|
+
this.textarea.className = "wysihtml5-source-view";
|
14178
|
+
}
|
14179
|
+
this.textarea.style.width = width + 'px';
|
14180
|
+
this.textarea.style.height = height + 'px';
|
14181
|
+
this.textarea.value = this.editor.getValue(shouldParseHtml, true);
|
14182
|
+
this.composer.element.parentNode.insertBefore(this.textarea, this.composer.element);
|
14183
|
+
this.editor.currentView = "source";
|
14184
|
+
this.composer.element.style.display = 'none';
|
14185
|
+
},
|
14186
|
+
|
14187
|
+
switchToComposer: function(shouldParseHtml) {
|
14188
|
+
var textareaValue = this.textarea.value;
|
14189
|
+
if (textareaValue) {
|
14190
|
+
this.composer.setValue(textareaValue, shouldParseHtml);
|
14191
|
+
} else {
|
14192
|
+
this.composer.clear();
|
14193
|
+
this.editor.fire("set_placeholder");
|
14194
|
+
}
|
14195
|
+
this.textarea.parentNode.removeChild(this.textarea);
|
14196
|
+
this.editor.currentView = this.composer;
|
14197
|
+
this.composer.element.style.display = '';
|
14198
|
+
},
|
14199
|
+
|
14200
|
+
_observe: function() {
|
14201
|
+
this.editor.on("change_view", function(view) {
|
14202
|
+
if (view === "composer") {
|
14203
|
+
this.switchToComposer(true);
|
14204
|
+
} else if (view === "textarea") {
|
14205
|
+
this.switchToTextarea(true);
|
14206
|
+
}
|
14207
|
+
}.bind(this));
|
14208
|
+
}
|
14209
|
+
|
14210
|
+
});
|
14211
|
+
|
14212
|
+
})(wysihtml5);
|
14092
14213
|
;wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
14093
14214
|
/** @scope wysihtml5.views.Textarea.prototype */ {
|
14094
14215
|
name: "textarea",
|
@@ -14281,7 +14402,9 @@ wysihtml5.views.View = Base.extend(
|
|
14281
14402
|
|
14282
14403
|
handleBeforeLoad: function() {
|
14283
14404
|
if (!this.config.noTextarea) {
|
14284
|
-
|
14405
|
+
this.synchronizer = new wysihtml5.views.Synchronizer(this, this.textarea, this.composer);
|
14406
|
+
} else {
|
14407
|
+
this.sourceView = new wysihtml5.views.SourceView(this, this.composer);
|
14285
14408
|
}
|
14286
14409
|
if (this.config.toolbar) {
|
14287
14410
|
this.toolbar = new wysihtml5.toolbar.Toolbar(this, this.config.toolbar, this.config.showToolbarAfterInit);
|
@@ -14847,12 +14970,10 @@ wysihtml5.views.View = Base.extend(
|
|
14847
14970
|
execAction: function(action) {
|
14848
14971
|
var editor = this.editor;
|
14849
14972
|
if (action === "change_view") {
|
14850
|
-
if (editor.textarea) {
|
14851
|
-
|
14852
|
-
|
14853
|
-
|
14854
|
-
editor.fire("change_view", "textarea");
|
14855
|
-
}
|
14973
|
+
if (editor.currentView === editor.textarea || editor.currentView === "source") {
|
14974
|
+
editor.fire("change_view", "composer");
|
14975
|
+
} else {
|
14976
|
+
editor.fire("change_view", "textarea");
|
14856
14977
|
}
|
14857
14978
|
}
|
14858
14979
|
if (action == "showSource") {
|
@@ -14917,17 +15038,15 @@ wysihtml5.views.View = Base.extend(
|
|
14917
15038
|
|
14918
15039
|
editor.on("change_view", function(currentView) {
|
14919
15040
|
// Set timeout needed in order to let the blur event fire first
|
14920
|
-
|
14921
|
-
|
14922
|
-
|
14923
|
-
|
14924
|
-
|
14925
|
-
|
14926
|
-
|
14927
|
-
|
14928
|
-
|
14929
|
-
}, 0);
|
14930
|
-
}
|
15041
|
+
setTimeout(function() {
|
15042
|
+
that.commandsDisabled = (currentView !== "composer");
|
15043
|
+
that._updateLinkStates();
|
15044
|
+
if (that.commandsDisabled) {
|
15045
|
+
dom.addClass(container, CLASS_NAME_COMMANDS_DISABLED);
|
15046
|
+
} else {
|
15047
|
+
dom.removeClass(container, CLASS_NAME_COMMANDS_DISABLED);
|
15048
|
+
}
|
15049
|
+
}, 0);
|
14931
15050
|
});
|
14932
15051
|
},
|
14933
15052
|
|
@@ -15008,7 +15127,7 @@ wysihtml5.views.View = Base.extend(
|
|
15008
15127
|
action = actionMapping[i];
|
15009
15128
|
|
15010
15129
|
if (action.name === "change_view") {
|
15011
|
-
action.state = this.editor.currentView === this.editor.textarea;
|
15130
|
+
action.state = this.editor.currentView === this.editor.textarea || this.editor.currentView === "source";
|
15012
15131
|
if (action.state) {
|
15013
15132
|
dom.addClass(action.link, CLASS_NAME_ACTION_ACTIVE);
|
15014
15133
|
} else {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license wysihtml5x v0.5.0-
|
2
|
+
* @license wysihtml5x v0.5.0-beta6
|
3
3
|
* https://github.com/Edicy/wysihtml5
|
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-beta6",
|
14
14
|
|
15
15
|
// namespaces
|
16
16
|
commands: {},
|
@@ -6692,7 +6692,7 @@ wysihtml5.dom.parse = function(elementOrHtml_current, config_current) {
|
|
6692
6692
|
}
|
6693
6693
|
|
6694
6694
|
function _checkAttribute(attributeName, attributeValue, methodName, nodeName) {
|
6695
|
-
var method = attributeCheckMethods[methodName],
|
6695
|
+
var method = wysihtml5.lang.object(methodName).isFunction() ? methodName : attributeCheckMethods[methodName],
|
6696
6696
|
newAttributeValue;
|
6697
6697
|
|
6698
6698
|
if (method) {
|
@@ -9304,6 +9304,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9304
9304
|
}
|
9305
9305
|
};
|
9306
9306
|
|
9307
|
+
caretPlaceholder.className = '_wysihtml5-temp-caret-fix';
|
9307
9308
|
caretPlaceholder.style.position = 'absolute';
|
9308
9309
|
caretPlaceholder.style.display = 'block';
|
9309
9310
|
caretPlaceholder.style.minWidth = '1px';
|
@@ -9339,7 +9340,9 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9339
9340
|
fixWebkitSelection = function() {
|
9340
9341
|
// Webkit fails to add selection if there are no textnodes in that region
|
9341
9342
|
// (like an uneditable container at the end of content).
|
9342
|
-
|
9343
|
+
var parent = node.parentNode,
|
9344
|
+
lastSibling = parent ? parent.childNodes[parent.childNodes.length - 1] : null;
|
9345
|
+
if (!sel || (lastSibling === node && this.win.getComputedStyle(node).display === "block")) {
|
9343
9346
|
if (notVisual) {
|
9344
9347
|
// If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
|
9345
9348
|
// and remove itself in call stack end instead on user interaction
|
@@ -9640,45 +9643,69 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9640
9643
|
}
|
9641
9644
|
},
|
9642
9645
|
|
9643
|
-
|
9644
|
-
|
9645
|
-
|
9646
|
-
|
9647
|
-
|
9648
|
-
|
9649
|
-
|
9650
|
-
|
9651
|
-
|
9652
|
-
|
9653
|
-
|
9654
|
-
|
9655
|
-
|
9656
|
-
|
9657
|
-
|
9658
|
-
|
9659
|
-
|
9660
|
-
|
9646
|
+
// Returns object describing node/text before selection
|
9647
|
+
// If includePrevLeaves is true returns also previous last leaf child if selection is in the beginning of current node
|
9648
|
+
getBeforeSelection: function(includePrevLeaves) {
|
9649
|
+
var sel = this.getSelection(),
|
9650
|
+
startNode = (sel.isBackwards()) ? sel.focusNode : sel.anchorNode,
|
9651
|
+
startOffset = (sel.isBackwards()) ? sel.focusOffset : sel.anchorOffset,
|
9652
|
+
rng = this.createRange(), endNode, inTmpCaret;
|
9653
|
+
|
9654
|
+
// Escape temproray helper nodes if selection in them
|
9655
|
+
inTmpCaret = wysihtml5.dom.getParentElement(startNode, { query: '._wysihtml5-temp-caret-fix' }, 1);
|
9656
|
+
if (inTmpCaret) {
|
9657
|
+
startNode = inTmpCaret.parentNode;
|
9658
|
+
startOffset = Array.prototype.indexOf.call(startNode.childNodes, inTmpCaret);
|
9659
|
+
}
|
9660
|
+
|
9661
|
+
if (startNode) {
|
9662
|
+
if (startOffset > 0) {
|
9663
|
+
if (startNode.nodeType === 3) {
|
9664
|
+
rng.setStart(startNode, 0);
|
9665
|
+
rng.setEnd(startNode, startOffset);
|
9666
|
+
return {
|
9667
|
+
type: "text",
|
9668
|
+
range: rng,
|
9669
|
+
offset : startOffset,
|
9670
|
+
node: startNode
|
9671
|
+
};
|
9672
|
+
} else {
|
9673
|
+
rng.setStartBefore(startNode.childNodes[0]);
|
9674
|
+
endNode = startNode.childNodes[startOffset - 1];
|
9675
|
+
rng.setEndAfter(endNode);
|
9676
|
+
return {
|
9677
|
+
type: "element",
|
9678
|
+
range: rng,
|
9679
|
+
offset : startOffset,
|
9680
|
+
node: endNode
|
9681
|
+
};
|
9661
9682
|
}
|
9662
9683
|
} else {
|
9663
|
-
|
9664
|
-
|
9665
|
-
|
9666
|
-
|
9667
|
-
|
9668
|
-
|
9669
|
-
|
9670
|
-
|
9671
|
-
|
9684
|
+
rng.setStartAndEnd(startNode, 0);
|
9685
|
+
|
9686
|
+
if (includePrevLeaves) {
|
9687
|
+
var prevNode = this.getPreviousNode(startNode, true),
|
9688
|
+
prevLeaf = prevNode ? wysihtml5.dom.domNode(prevNode).lastLeafNode() : null;
|
9689
|
+
|
9690
|
+
if (prevLeaf) {
|
9691
|
+
return {
|
9692
|
+
type: "leafnode",
|
9693
|
+
range: rng,
|
9694
|
+
offset : startOffset,
|
9695
|
+
node: prevLeaf
|
9696
|
+
};
|
9672
9697
|
}
|
9673
9698
|
}
|
9674
|
-
lastNode = childNodes.length > 0 ? childNodes[childNodes.length -1] : null;
|
9675
|
-
if (lastNode && lastNode.nodeType === 1 && wysihtml5.dom.hasClass(lastNode, this.unselectableClass)) {
|
9676
|
-
return lastNode;
|
9677
|
-
}
|
9678
9699
|
|
9700
|
+
return {
|
9701
|
+
type: "none",
|
9702
|
+
range: rng,
|
9703
|
+
offset : startOffset,
|
9704
|
+
node: startNode
|
9705
|
+
};
|
9679
9706
|
}
|
9680
9707
|
}
|
9681
|
-
return
|
9708
|
+
return null;
|
9682
9709
|
},
|
9683
9710
|
|
9684
9711
|
// TODO: Figure out a method from following 2 that would work universally
|
@@ -9758,7 +9785,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
|
|
9758
9785
|
}
|
9759
9786
|
this.setSelection(newRange);
|
9760
9787
|
for (var i = caretPlaceholder.length; i--;) {
|
9761
|
-
|
9788
|
+
caretPlaceholder[i].parentNode.removeChild(caretPlaceholder[i]);
|
9762
9789
|
}
|
9763
9790
|
|
9764
9791
|
} else {
|
@@ -12414,7 +12441,7 @@ wysihtml5.Commands = Base.extend(
|
|
12414
12441
|
for (row = 0; row < value.rows; row ++) {
|
12415
12442
|
html += '<tr>';
|
12416
12443
|
for (col = 0; col < value.cols; col ++) {
|
12417
|
-
html += "<td
|
12444
|
+
html += "<td></td>";
|
12418
12445
|
}
|
12419
12446
|
html += '</tr>';
|
12420
12447
|
}
|
@@ -13670,59 +13697,98 @@ wysihtml5.views.View = Base.extend(
|
|
13670
13697
|
}
|
13671
13698
|
};
|
13672
13699
|
|
13700
|
+
// Override for giving user ability to delete last line break in table cell
|
13701
|
+
var fixLastBrDeletionInTable = function(composer, force) {
|
13702
|
+
if (composer.selection.caretIsLastInSelection()) {
|
13703
|
+
var sel = composer.selection.getSelection(),
|
13704
|
+
aNode = sel.anchorNode;
|
13705
|
+
if (aNode && aNode.nodeType === 1 && (wysihtml5.dom.getParentElement(aNode, {query: 'td, th'}, false, composer.element) || force)) {
|
13706
|
+
var nextNode = aNode.childNodes[sel.anchorOffset];
|
13707
|
+
if (nextNode && nextNode.nodeType === 1 & nextNode.nodeName === "BR") {
|
13708
|
+
nextNode.parentNode.removeChild(nextNode);
|
13709
|
+
return true;
|
13710
|
+
}
|
13711
|
+
}
|
13712
|
+
}
|
13713
|
+
return false;
|
13714
|
+
};
|
13715
|
+
|
13716
|
+
// If found an uneditable before caret then notify it before deletion
|
13717
|
+
var handleUneditableDeletion = function(composer) {
|
13718
|
+
var before = composer.selection.getBeforeSelection(true);
|
13719
|
+
if (before && (before.type === "element" || before.type === "leafnode") && before.node.nodeType === 1 && before.node.classList.contains(composer.config.uneditableContainerClassname)) {
|
13720
|
+
if (fixLastBrDeletionInTable(composer, true)) {
|
13721
|
+
return true;
|
13722
|
+
}
|
13723
|
+
try {
|
13724
|
+
var ev = new CustomEvent("wysihtml5:uneditable:delete");
|
13725
|
+
before.node.dispatchEvent(ev);
|
13726
|
+
} catch (err) {}
|
13727
|
+
before.node.parentNode.removeChild(before.node);
|
13728
|
+
return true;
|
13729
|
+
}
|
13730
|
+
return false;
|
13731
|
+
};
|
13732
|
+
|
13733
|
+
// Deletion with caret in the beginning of headings needs special attention
|
13734
|
+
// Heading does not concate text to previous block node correctly (browsers do unexpected miracles here especially webkit)
|
13735
|
+
var fixDeleteInTheBeginnigOfHeading = function(composer) {
|
13736
|
+
var selection = composer.selection;
|
13737
|
+
|
13738
|
+
if (selection.caretIsFirstInSelection() &&
|
13739
|
+
selection.getPreviousNode() &&
|
13740
|
+
selection.getPreviousNode().nodeName &&
|
13741
|
+
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
|
13742
|
+
) {
|
13743
|
+
var prevNode = selection.getPreviousNode();
|
13744
|
+
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
|
13745
|
+
// If heading is empty remove the heading node
|
13746
|
+
prevNode.parentNode.removeChild(prevNode);
|
13747
|
+
return true;
|
13748
|
+
} else {
|
13749
|
+
if (prevNode.lastChild) {
|
13750
|
+
var selNode = prevNode.lastChild,
|
13751
|
+
curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
|
13752
|
+
if (prevNode) {
|
13753
|
+
if (curNode) {
|
13754
|
+
while (curNode.firstChild) {
|
13755
|
+
prevNode.appendChild(curNode.firstChild);
|
13756
|
+
}
|
13757
|
+
selection.setAfter(selNode);
|
13758
|
+
return true;
|
13759
|
+
} else if (selection.getSelectedNode().nodeType === 3) {
|
13760
|
+
prevNode.appendChild(selection.getSelectedNode());
|
13761
|
+
selection.setAfter(selNode);
|
13762
|
+
return true;
|
13763
|
+
}
|
13764
|
+
}
|
13765
|
+
}
|
13766
|
+
}
|
13767
|
+
}
|
13768
|
+
return false;
|
13769
|
+
};
|
13770
|
+
|
13673
13771
|
var handleDeleteKeyPress = function(event, composer) {
|
13674
13772
|
var selection = composer.selection,
|
13675
13773
|
element = composer.element;
|
13676
13774
|
|
13677
13775
|
if (selection.isCollapsed()) {
|
13678
13776
|
if (selection.caretIsInTheBeginnig('li')) {
|
13777
|
+
// delete in the beginnig of LI will outdent not delete
|
13679
13778
|
event.preventDefault();
|
13680
13779
|
composer.commands.exec('outdentList');
|
13681
|
-
} else if (selection.caretIsInTheBeginnig()) {
|
13682
|
-
event.preventDefault();
|
13683
13780
|
} else {
|
13684
|
-
if (
|
13685
|
-
|
13686
|
-
|
13687
|
-
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
|
13688
|
-
) {
|
13689
|
-
var prevNode = selection.getPreviousNode();
|
13690
|
-
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
|
13691
|
-
// heading is empty
|
13692
|
-
event.preventDefault();
|
13693
|
-
prevNode.parentNode.removeChild(prevNode);
|
13694
|
-
} else {
|
13695
|
-
if (prevNode.lastChild) {
|
13696
|
-
var selNode = prevNode.lastChild,
|
13697
|
-
curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
|
13698
|
-
if (prevNode) {
|
13699
|
-
if (curNode) {
|
13700
|
-
event.preventDefault();
|
13701
|
-
while (curNode.firstChild) {
|
13702
|
-
prevNode.appendChild(curNode.firstChild);
|
13703
|
-
}
|
13704
|
-
selection.setAfter(selNode);
|
13705
|
-
} else if (selection.getSelectedNode().nodeType === 3) {
|
13706
|
-
event.preventDefault();
|
13707
|
-
prevNode.appendChild(selection.getSelectedNode());
|
13708
|
-
selection.setAfter(selNode);
|
13709
|
-
}
|
13710
|
-
}
|
13711
|
-
}
|
13712
|
-
}
|
13781
|
+
if (fixDeleteInTheBeginnigOfHeading(composer)) {
|
13782
|
+
event.preventDefault();
|
13783
|
+
return;
|
13713
13784
|
}
|
13714
|
-
|
13715
|
-
var beforeUneditable = selection.caretIsBeforeUneditable();
|
13716
|
-
// Do a special delete if caret would delete uneditable
|
13717
|
-
if (beforeUneditable) {
|
13785
|
+
if (fixLastBrDeletionInTable(composer)) {
|
13718
13786
|
event.preventDefault();
|
13719
|
-
|
13720
|
-
|
13721
|
-
|
13722
|
-
|
13723
|
-
|
13724
|
-
} catch (err) {}
|
13725
|
-
beforeUneditable.parentNode.removeChild(beforeUneditable);
|
13787
|
+
return;
|
13788
|
+
}
|
13789
|
+
if (handleUneditableDeletion(composer)) {
|
13790
|
+
event.preventDefault();
|
13791
|
+
return;
|
13726
13792
|
}
|
13727
13793
|
}
|
13728
13794
|
} else {
|
@@ -14089,6 +14155,61 @@ wysihtml5.views.View = Base.extend(
|
|
14089
14155
|
}
|
14090
14156
|
});
|
14091
14157
|
})(wysihtml5);
|
14158
|
+
;(function(wysihtml5) {
|
14159
|
+
|
14160
|
+
wysihtml5.views.SourceView = Base.extend(
|
14161
|
+
/** @scope wysihtml5.views.SourceView.prototype */ {
|
14162
|
+
|
14163
|
+
constructor: function(editor, composer) {
|
14164
|
+
this.editor = editor;
|
14165
|
+
this.composer = composer;
|
14166
|
+
|
14167
|
+
this._observe();
|
14168
|
+
},
|
14169
|
+
|
14170
|
+
switchToTextarea: function(shouldParseHtml) {
|
14171
|
+
var composerStyles = this.composer.win.getComputedStyle(this.composer.element),
|
14172
|
+
width = parseFloat(composerStyles.width),
|
14173
|
+
height = Math.max(parseFloat(composerStyles.height), 100);
|
14174
|
+
|
14175
|
+
if (!this.textarea) {
|
14176
|
+
this.textarea = this.composer.doc.createElement('textarea');
|
14177
|
+
this.textarea.className = "wysihtml5-source-view";
|
14178
|
+
}
|
14179
|
+
this.textarea.style.width = width + 'px';
|
14180
|
+
this.textarea.style.height = height + 'px';
|
14181
|
+
this.textarea.value = this.editor.getValue(shouldParseHtml, true);
|
14182
|
+
this.composer.element.parentNode.insertBefore(this.textarea, this.composer.element);
|
14183
|
+
this.editor.currentView = "source";
|
14184
|
+
this.composer.element.style.display = 'none';
|
14185
|
+
},
|
14186
|
+
|
14187
|
+
switchToComposer: function(shouldParseHtml) {
|
14188
|
+
var textareaValue = this.textarea.value;
|
14189
|
+
if (textareaValue) {
|
14190
|
+
this.composer.setValue(textareaValue, shouldParseHtml);
|
14191
|
+
} else {
|
14192
|
+
this.composer.clear();
|
14193
|
+
this.editor.fire("set_placeholder");
|
14194
|
+
}
|
14195
|
+
this.textarea.parentNode.removeChild(this.textarea);
|
14196
|
+
this.editor.currentView = this.composer;
|
14197
|
+
this.composer.element.style.display = '';
|
14198
|
+
},
|
14199
|
+
|
14200
|
+
_observe: function() {
|
14201
|
+
this.editor.on("change_view", function(view) {
|
14202
|
+
if (view === "composer") {
|
14203
|
+
this.switchToComposer(true);
|
14204
|
+
} else if (view === "textarea") {
|
14205
|
+
this.switchToTextarea(true);
|
14206
|
+
}
|
14207
|
+
}.bind(this));
|
14208
|
+
}
|
14209
|
+
|
14210
|
+
});
|
14211
|
+
|
14212
|
+
})(wysihtml5);
|
14092
14213
|
;wysihtml5.views.Textarea = wysihtml5.views.View.extend(
|
14093
14214
|
/** @scope wysihtml5.views.Textarea.prototype */ {
|
14094
14215
|
name: "textarea",
|
@@ -14281,7 +14402,9 @@ wysihtml5.views.View = Base.extend(
|
|
14281
14402
|
|
14282
14403
|
handleBeforeLoad: function() {
|
14283
14404
|
if (!this.config.noTextarea) {
|
14284
|
-
|
14405
|
+
this.synchronizer = new wysihtml5.views.Synchronizer(this, this.textarea, this.composer);
|
14406
|
+
} else {
|
14407
|
+
this.sourceView = new wysihtml5.views.SourceView(this, this.composer);
|
14285
14408
|
}
|
14286
14409
|
if (this.config.toolbar) {
|
14287
14410
|
this.toolbar = new wysihtml5.toolbar.Toolbar(this, this.config.toolbar, this.config.showToolbarAfterInit);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wysihtml-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.0.
|
4
|
+
version: 0.5.0.beta6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanel Jakobsoo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|