How to create a button in TinyMCE 4 that increments font size - tinymce-4

Has anyone managed to create a button in TinyMCE 4 that will increment the font size of the selected text by, say, 1px?
The problem I'm having is getting ahold of the selected text, whether it's in a span already or not.
I'm willing to modify the TinyMCE source.
Thanks for any ideas.

You don't need to modify the source code, you can create a plugin.
Here is the documentation of how to create a plugin for TinyMCE:
http://www.tinymce.com/wiki.php/Tutorials:Creating_a_plugin
based on that you can create your own button (see working example)
here is part of the code:
var currentFontSize = new Number($(tinyMCE.activeEditor.selection.getNode()).css('font-size').replace('px','')); //remove the px part
currentFontSize = currentFontSize + 1; //increase font by one
tinymce.activeEditor.formatter.register('mycustomformat', {
inline : 'span',
styles : {'font-size' : currentFontSize + 'px'} //this is the font size incremented by one
});
tinymce.activeEditor.formatter.apply('mycustomformat'); //apply the format to the selected text

Related

Pulling a style from a TinyMCE selection

I'm trying to implement a TinyMCE button that will apply the style of the selection to the entire box. I'm having trouble, though, reading the style of the selection when the selection is buried in a span in a span in a paragraph. Let's consider 'color' for example. Below I have a box with some text and I've selected "here" in the paragraph and made it red.
The HTML for the paragraph is now:
The code behind my button to apply the style of the selection to the box is
var selected_color = $(ed.selection.getNode()).css('color');
console.log("color pulled is ", selected_color);
$(ed.bodyElement).css('color', selected_color);
It doesn't work because the color pulled is black, not red, so the third line just re-applies the black that's already there. (If I replace selected_color in the third line with 'blue' everything goes blue.) So the problem is pulling the color of the current selection.
Does anyone know how I can do this reliably, no matter how buried the selection is?
Thanks for any help.
I also noticed somewhat a strange behavior up and there, with selections of nested span's and div's, but honestly i'm not able to recognize if this is a bug of TinyMCE, a browser issue or a combination of both (most probably).
So, waiting for some more information from you (maybe also your plugin code) in the meanwhile i realized two proposal to achieve what you want: the first plugin behaves like the format painter in word, the second is simply applying the current detected foreground color to the whole paragraph.
As you move throug the editor with the keyboard or mouse, you will see the current detected foreground color highlighted and applied as background to the second plugin button.
Key point here are two functions to get the styles back from the cursor position:
function findStyle(el, attr) {
var styles, style, color;
try {
styles = $(el).attr('style');
if(typeof styles !== typeof undefined && styles !== false) {
styles.split(";").forEach(function(e) {
style = e.split(":");
if($.trim(style[0]) === attr) {
color = $(el).css(attr);
}
});
}
} catch (err) {}
return color;
}
function findForeColor(node) {
var $el = $(node), color;
while ($el.prop("tagName").toUpperCase() != "BODY") {
color = findStyle($el, "color");
if (color) break;
$el = $el.parent();
}
return color;
}
The try...catch block is needed to avoid some occasional errors when a selected text is restyled. If you look at the TinyMCE sorce code you will notice a plenty of timing events, this is a unavoidable and common practice when dealing with styles and css, even more with user interaction. There was a great job done by the authors of TinyMCE to make the editor cross-browser.
You can try out the first plugin in the Fiddle below. The second plugin is simpler as the first one. lastForeColor is determined in ed.on('NodeChange'), so the code in button click is very easy.
tinymce.PluginManager.add('example2', function(ed, url) {
// Add a button that opens a window
ed.addButton('example2', {
text: '',
icon: "apply-forecolor",
onclick: function() {
if(lastForeColor) {
var applyColor = lastForeColor;
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
ed.selection.collapse(false);
ed.fire('SelectionChange');
}
return false;
}
});
});
Moreover: i think there is a potential issue with your piece of code here:
$(ed.bodyElement).css('color', selected_color);
i guess the style should be applied in a different way, so in my example i'm using standard TinyMCE commands to apply the foreground color to all, as i wasn't able to exactly convert your screenshot to code. Please share your thoughts in a comment.
Fiddle with both plugins: https://jsfiddle.net/ufp0Lvow/
deblocker,
Amazing work! Thank you!
Your jsfiddle did the trick. I replaced the HTML with what was in my example and changed the selector in tinymce.init from a textarea to a div and it pulls the color out perfectly from my example. The modified jsfiddle is at https://jsfiddle.net/79r3vkyq/3/ . I'll be studying and learning from your code for a long time.
Regarding your question about
$(ed.bodyElement).css('color', selected_color);
the divs I attach tinymce to all have ids and the one the editor is currently attached to is reported in ed.bodyElement. I haven't had any trouble using this but I have no problem using your
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
Thanks again! Great job!

JavaFX change single style in CSS stylesheet

I've created a small text editor window that allows the user to change some basic properties of a text area included within the screen. Two of the options available to change the properties of the textArea are font color and font color fill, which are both handled by separate color pickers.
I ran into an issue when testing these buttons using the setStyle method that only one property could be saved at a time. Example, if text color was set to BLUE, and afterwards fill color was set to YELLOW, text color would not remain blue, but instead revert back to its default defined in the stylesheet (black).
To fix this problem, I have created the following method;
private void updateTheSyle()
{
this.textArea.setStyle("-fx-control-inner-background: " + toRgbString(this.colorPickerFill.getValue()) +
"; -fx-text-fill: " + toRgbString(this.colorPickerFont.getValue()) + ";");
}
The toRgbString() method is also called, this is simply passing the user input from the color picker into a string such that the setStyle method can pass the correct parameters to the stylesheet.
This solution does work, as it enables me to change both the fill and the font color without reverting back to default upon selection. However, my program includes more than just fill and font color, which will contribute to a far longer setStyle statement as these options are added.
TLDR: Is there a way to edit a single style included in a CSS stylesheet without affecting the other styles in a given class?
For your first question (longer setStyle statement), If we take into account that the style is defined by a String, and it takes a whole set of details to provide for a single Style, so why not use a List<String> :
List<String> example = new ArrayList<>();
String style = "";
//For example if you use 2 textField to get the (value) and (type):
example.add("-fx-"+textFieldType+":"+textFieldValue + "; ");
//To gather all the properties in a single string
for(String property: example){
style += example;
}
yourNode.setStyle(style);
I do not know if there is a better approach but it works, good luck !
Edit :
I think this tip answers your second question:
private void Update(String type,String newValue){
for(int i = 0; i < example.size(); i++){
if(example.get(i).contains(type)){
example.set(i, "-fx-"+type+":"+newValue + "; ");
//Here you add a (break;) to not alter the other similar styles !
}
}
//Here you use a loop to update the new elements changed
}
I hope this will help you solve your problem !

Adding a color box for "Transparent" on the TinyMCE-4 color picker

I'd like an option with the TinyMCE color picker to choose transparent as the color so a character (a "bullet") will still be there and take up space but will not be visible if it's color is transparent.
There's an "X" box option that says "No color" but this seems to make the color black, not transparent.
Does anyone know how to add a transparent color option to this color picker, or even make the "X" box implement transparent instead of black?
Thanks for any ideas.
I believe I was able to do that, I did some quick tests and it appears to be working fine.
I got the latest version of TinyMCE (4.1.10_dev) to access the textcolor plugin's non minified javascript there's this instruction:
if (value == 'transparent') {
resetColor();
} else {
selectColor(value);
}
What happens here? When you choose a color it runs the selectColor, which wraps the selected text in a span with the selected color. However, when you select the no color it removes this color span (that's why it goes back to black which is the default color) instead of setting it to transparent.
So if you do this:
//if (value == 'transparent') {
// resetColor();
//} else {
selectColor(value);
//}
Instead of removing the span it will change it to 'transparent' instead.
One important thing is that tinyMCE gets the plugin scripts automatically, so it only works with the minified versions, so after you do these changes you'll have to minify the script to the plugin.min.js and put it on the textcolro plugin's folder overwriting the one there.
I hope it helps.
The × button in the colorpicker removes any custom colours, it does not add a zero-opacity colour.
As you can see when looking at the source code or trying the full example there is no support for rgba() or opacity in the included colorpicker plugin. Only rgb() and hex unfortunately.
You may need to create your own small plugin to add the ability. There are a number of alternatives, for example:
Create a CSS class which you can add to elements in the editor. Then do your colour magic in your own CSS file.
Create a new button in the toolbar which makes the element transparent.
I would personally go with option two, something like this:
tinymce.init({
selector: 'textarea',
plugins: 'nocolour',
toolbar: 'nocolour',
external_plugins: {
"nocolour": "url_to_your/nocolour.js"
}
});
And nocolour.js:
tinymce.PluginManager.add('nocolour', function(editor, url) {
// Add a button that opens a window
editor.addButton('nocolour', {
text: 'Remove Colour',
icon: false,
onclick: function() {
editor.undoManager.transact(function() {
editor.focus();
// Here is where you add code to remove the colour
editor.nodeChanged();
});
}
});
});
Rafael's solution worked for me. I just wanted to document it a bit more and show what it looks like for TinyMCE 4.1.7.
When you click the "X" in the textcolor grid the "value" variable gets "transparent," rather than a hex value from the colorMap.
The relevant code in the textcolor plugin is:
value = e.target.getAttribute('data-mce-color'); // the hex color from the colorMap square that was clicked. "transparent" if X was clicked
if (value) {
if (this.lastId) {
document.getElementById(this.lastId).setAttribute('aria-selected', false);
}
e.target.setAttribute('aria-selected', true);
this.lastId = e.target.id;
// if (value == 'transparent') { // occurs if you select the "X" square
// removeFormat(buttonCtrl.settings.format);
// buttonCtrl.hidePanel();
// return;
// }
selectColor(value);
The five lines I've commented out remove formatting for the selected text, leaving it black, which doesn't seem useful. If you wanted the text black you could select the black square in the colorMap. Falling through to selectColor(value) with value = "transparent" sets transparent as the color.

Tinymce4 Remove background-color from text with colorpicker

When the user marks a text, he can define a backgroundcolor with the colorpicker (textcolor.plugin).
Once saved he can change the background-color but not get rid of it.
background-color:white is no solution as the bodycolor can be RGB or even a picture.
How is the colorpicker to configure to remove the style-tag or at least insert a background-color:none?
Found a solution changing the plugin (textcolor). If there is a better way please be free to post it.
I added additional colors to the colorpicker. The Color #FFFFFe (near White) i marked as NO COLOR and changed the plugin as shown.
function onPanelClick(e) {
var buttonCtrl = this.parent(), value;
if ((value = e.target.getAttribute('data-mce-color'))) {
buttonCtrl.hidePanel();
value = '#' + value;
buttonCtrl.color(value);
if (value == '#FFFFFe') { //Changing the value to -1 causes deletion :-)
value = -1;
}
editor.execCommand(buttonCtrl.settings.selectcmd, false, value);
}
}
Researched a bit more since the given answer did not work in my version 4.5.0 of tinymce.
The textcolor plugin uses 'editor.formatter.remove(...)' to remove text color or background color upon selecting 'x' in the last option of the color palette for 'no color'.
While that function is used elsewhere successfully in tinymce (e.g. when removing italics from text), in the context of the textcolor plugin it does not remove color formatting.
Solution:
Replace the following in the textcolor's plugin.js:
editor.formatter.remove(format, {value: null}, null, true);
with:
editor.dom.removeAllAttribs(editor.selection.getNode());
...or in the minified version plugin.min.js:
a.formatter.remove(b,{value:null},null,!0),
with:
a.dom.removeAllAttribs(a.selection.getNode()),
...and things start working as intended.

Flex: changing Flex component styles in AS3

in MXML, there is a Button class which you can instantiate like so:
<mx:Button id="something />
but what if you wanted to dynamically build this in AS3 and add it to the Flex app dynamically, without the use of components (just AS3) and then modify Flex's styles, for example, here you access the Button's properties and set them:
var btn:Button = new Button();
btn.height = 50;
btn.width = 75;
btn.x = 100;
btn.y = 40;
but how would you go about changing the Style, for example:
btn.downSkin = "something";
btn.color = "0xfffff";
I'm sort of starting to lean towards making a flex component in MXMLand than just making it visible true/false, but i like the fact that i create an object in AS3 and then destroy it when I don't need it anymore, than create it again once needed.
This page has a solution to the problem:
Setting and getting Style attributes in ActionScript:
// setting a components styleName to reference a CSS class
component.styleName = "highlight";
// set a Button's background color and font size
submitButton.setStyle( "backgroundColor", 0x000000 );
submitButton.setStyle( "fontSize", 14 );
// get a TextArea's font family and color
textArea.getStyle( "fontFamily" );
textArea.getStyle( "color" );
You could use CSS, either inline or as an external CSS file. That way you don't have to set the properties manually every time you create a button.
/* CSS file */
Button {
borderColor: red;
}
Check out Styling Button control, by Peter deHaan (also read the comments in that post).

Resources