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

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.

Related

Toggling dark/light mode in disqus

I have a website where I post articles. It's made up of Jekyll, and deployed by GitHub. The site has a button which switches light mode to dark mode and vice versa without any page refresh.
Today I have installed disqus code to it. And It comes with either dark or light mode. So I just added this to my toggler function:
const disqusThread = $('#disqus_thread')
const ps = $('#disqus_thread *')
tdm.onclick = function() {
disqusThread.css('background-color', '#111')
ps.attr('style', 'color: #fff !important')
.
.
.
Which does actually change the background, but in no way I can change the text colour. If I try filter: invert(100%) everything is nice, but the images are also looking inverted. Using #disqus_thread *:not(img) isn't working either.
If I open firefox's inspector tool, I see the properties has !important in them. So I can't change the style anymore. And switching back and forth isn't actually working even in basic CSS.
Is there any way to flip the colour without using filter?
I was also having this problem and my workaround on this was first, the toggle button will remove all the elements inside the disqus_thread div using the code:
mydiv = document.getElementById('disqus_thread');
while (mydiv.firstChild) {
mydiv.removeChild(mydiv.firstChild);
}
Then, the button will reload the Disqus comment section using the function:
var disqus_shortname = "sample-shortname";
var disqus_url = "sample-url";
var disqus_identifier = "sample-identifier";
var disqus_loaded = false;
function disqus() {
if (!disqus_loaded) {
disqus_loaded = true;
var e = document.createElement("script");
e.type = "text/javascript";
e.async = true;
e.src = "//" + disqus_shortname + ".disqus.com/embed.js";
(document.getElementsByTagName("head")[0]
||document.getElementsByTagName("body")[0]).appendChild(e);
}
}
Lastly, since Disqus comment section was on auto, it would check the inherited color and decide if it was gonna be light or dark mode which I read from https://help.disqus.com/en/articles/1717201-disqus-appearance-customizations.
How is the color scheme determined?
- The light scheme is loaded when the text color Disqus inherits from your site has >= 50% gray contrast: between color: #000000; and color: #787878;
- The dark scheme is loaded in all other instances.
Since, by toggling the button, the website would turn the color of the body to a darker color anyway, Disqus automatically inherits this and reloads to its dark mode with just the click of the toggle button.
I don't know if this will cause lags as I was experimenting on localhost and so far it wasn't lagging for me.
References:
https://css-tricks.com/snippets/javascript/remove-element/
https://help.disqus.com/en/articles/1717201-disqus-appearance-customizations.
https://www.labnol.org/internet/load-disqus-comments-on-click/28653/

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!

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.

FullCalendar event text colour change

I added className fc-selected to [any selected day] which took care of my background colour changes for that selected cell. Thinking that I was home free and only needed to change color for the text next, I forcefully removed a few locks of hair when, only way later, did I realize that the date events are not even in the date cell but absolutely positioned above and outside of it.
How can I target the DOM of the events for a selected date in the calendar?
PS: Basically the background color for a date cell goes dark red on selection and I need the title text to temporarily change to white.
You can set an event's
textColor: white or #FFF
http://arshaw.com/fullcalendar/docs/event_data/Event_Object/
You can also set eventTextColor while redering event
http://arshaw.com/fullcalendar/docs/event_rendering/eventTextColor/
Actually, I tried many times and any variations of textColor or eventTextColor didn't worked at all. So, I tried changing color attributes manually;
.portlet.calendar .fc-event .fc-time {
color: white;
}
.portlet.calendar .fc-event .fc-title {
color: white;
}
By using simple javascript like this you can also set font-color of fullcalendar;
var colorStyle = document.getElementsByClassName('fc-title');
for (var i=0; i<colorStyle.length; i++) {
colorStyle[i].style.color = 'white';
}

Changing the default color on flex validation errors

The examples I've seen seem to show how to change the color that shows when the user actually hovers over the textinput field.
However when the validation fails, a generic textInput border qill have a red line over it. My CSS file uses a border skin for the textInput, so I can't see this line.
I was hoping there was a way to highlight the text box when it failed validation, or re-enable the red line feature. I don't want to get rid of my CSS cos it'll totally blow my color-scheme, but any tweak allowing the error line to show would be much appreciated.
This is the CSS:
TextInput, TextArea
{
border-skin: Embed(source='/../assets/images/input_bg.png', scaleGridLeft=8, scaleGridRight=20, scaleGridTop=8,scaleGridBottom=9);
padding-top:2;
padding-left:2;
font-size:11;
}
anything that extends UIComponent (both TextInput and TextArea do) has a style called errorColor. It defaults to red. You can change this to whatever you want.
Additionally, if you've got an image that you are using as a border, you should probably remove the pixels from the middle so that it is an actual border instead of an overlay.
The only way I've managed to find, is that Validator will change the component's borderColor style. I don't think it can be achieved using an image- you'll have to embed the image in a basic GraphicRectangularBorder subclass or similar. You can then add this to your skin class:
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (styleProp == "borderColor")
{
if (getStyle("borderColor") == getStyle("errorColor"))
{
// show error outline
}
else
{
// hide error outline
}
}
}

Resources