Reputation: 4908
I'm using TinyMCE 4 and I'd like to add a button that increases the line-height for the selected paragraph. I have it working if I select the paragraph by selecting a word in the paragraph. The code that works in that case is:
ed.addButton( 'linc', { // line increment
image: '/tinymce/plugins/zackel/button_images/line_spacing_up.png', // root is www/zackel.com/
title: 'increase line spacing of selected paragraph',
onclick:function(editor,url) {
console.log("ed.selection is ", ed.selection);
var node = ed.selection.getNode();
var nodeName = node.nodeName; // for example 'DIV ' or 'P'
var text = ed.selection.getContent( { 'format' : 'text' } ); // get the text contents of the active editor
console.log("add line spacing: selected text = ", text, ",node = ", node, "nodeName = ", nodeName);
if (node && text) {
var lineht = $(node).css('line-height');
lineht = Number(lineht.replace(/px/,''));
lineht += 2;
lineht = lineht + "px";
$(node).css('line-height', lineht);
}
else {
alert('Please select text to adjust the line height for');
}
return false;
}
});
But if I select the paragraph by triple clicking in it, selecting all of the paragraph text, the above code doesn't work because getNode() returns the outer DIV that contains the selected paragraph and the code then applies the line-height increase to all paragraphs in the DIV.
Looking at lastRng of the selection I see that the endContainer is the P for the following paragraph. The documentation for getNode() says it "returns the currently selected element or the common ancestor element for both start and end of the range" so in this case I seem to be getting the common ancestor of the selected P and the next P.
How can I modify the range, when I triple click a paragraph, so that getNode() brings back the P of the selected paragraph and not the common ancestor of the selected P and the following P?
Thanks for any help with this.
Upvotes: 3
Views: 2596
Reputation: 7707
I would simply use the NodeChange event to keep a reference to the last selected paragraph, so i wouldn't need to monkey-patch or tweak in any way the original code.
This is a complete and tested example:
(function() {
var lastText = "",
lastP = "";
tinymce.PluginManager.add('example', function(ed, url) {
ed.addButton('example', {
text: 'increase line spacing of selected paragraph',
icon: true,
onclick: function() {
var node = ed.selection.getNode();
var nodeName = node.nodeName; // for example 'DIV ' or 'P'
if (nodeName == 'DIV') {
node = lastP;
}
var text = lastText; // get the text contents of the last selected text, if any
console.log("add line spacing: selected text = ", text, ",node = ", node, "nodeName = ", nodeName);
if (node && text) {
var lineht = $(node).css('line-height');
if (lineht == "normal") {
var calculation_content = $('<span id="calculation_content" style="line-height:inherit;display:none;"> </span>');
$('body').append(calculation_content);
lineht = $('#calculation_content').height() + "px";
$(calculation_content).remove();
}
lineht = Number(lineht.replace(/px/, ''));
lineht += 2;
lineht = lineht + "px";
$(node).css('line-height', lineht);
} else {
alert('Please select text to adjust the line height for');
}
return false;
}
});
});
tinymce.init({
setup: function(ed) {
ed.on('NodeChange', function(e) {
var node = ed.selection.getNode();
var nodeName = node.nodeName; // for example 'DIV ' or 'P'
if (nodeName == 'P') {
lastP = node;
lastText = ed.selection.getContent({
'format': 'text'
});
}
});
},
selector: "textarea",
plugins: "example",
toolbar: "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | example"
});
})();
As a bonus, i added a small change to get the line height in px when there is no line height formatting at all, and CSS is returning "normal".
Please, let me know if this is solving your issue.
Upvotes: 2