wysihtml-rails 0.5.0.beta5 → 0.5.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|