How can a TinyMCE modal return formatted/visual text? - wordpress

I am trying to customize the behavior of an editor button in a plugin. On click, it opens a modal where the user can input some text. On confirmation, I want to wrap this text into code tags. But I don't want to take this text as if it comes from a text editor, I want to handle it as visual text. This means, I want to preserve any formatting (whitespaces and linebreaks) but not accept any other tags besides the code tags that I add afterward.
function showDialog() {
var win = ed.windowManager.open({
title: "Insert code",
body: {
type: 'textbox',
name: 'code',
multiline: true,
minWidth: ed.getParam("code_dialog_width", 600),
minHeight: ed.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)),
spellcheck: false,
style: 'direction: ltr; text-align: left'
},
onSubmit: function(e) {
ed.focus();
ed.undoManager.transact(function() {
ed.insertContent('<code>' + e.data.code + '</code>');
});
ed.selection.setCursorLocation();
ed.nodeChanged();
}
});
}

First i'd wrap that function in tags and make sure to initiate the function by adding showDialog() at the end of that function so the DOM knows to call the function. and with wordpress's content filter its going to add spaces no matter what unless you disable the content filter from auto populating format. if you go to a site like https://www.willpeavy.com/minifier/ and copy your code into that and minify the spaces you should be able to include it in your text(not Visual) tab in MCE. That being said its really bad practice to run functional code in MCE you're better off making a separate page / Post template for it.

Related

How to include caption for gallery using magnific popup?

I am trying to include a caption on the actual webpage under the image while using the magnificence popup gallery. Using a div and class caption or carousel-caption, I am unable to do so without the images in the gallery stacking vertically one by one. How can I do this?
<a href="img/base/ggg.PNG" title="HELLO" class="chicken">
<img src="img/base/pop.PNG" alt="remember your alt tag" />
</a>
$(document).ready(function() {
$('.chicken').magnificPopup({
type: 'image',
gallery:{enabled:true}
// other options here
// end each line (except the last) with a comma
});
});
js fiddle: https://jsfiddle.net/sb4btox7/
Since I don't yet have enough reputation points to comment, I'm commenting here, in addition to providing a solution.
Comment: JSFiddle isn't working with your http:// images because JSFiddle is trying to serve them from https://
Solution:
You are halfway there. There are 2 parts to making the captions work.
You correctly have put the link in the anchor tag and not the
image tag
You must specify your title source in your
initialization script like this.
$(document).ready(function() {
$('.chicken').magnificPopup({
type: 'image',
gallery:{enabled:true},
type: 'image',
image: {
titleSrc: 'title'
// this tells the script which attribute has your caption
}
});
});
The script then automatically writes your caption to its div labeled class="mfp-title"
BONUS Solution: I needed my lightbox image to open in a new window for users on their phones to zoom in, so I added this after the first titleSrc declaration:
titleSrc: 'title',
titleSrc: function(item) {
return '' + item.el.attr('title') + '';
}
This information is in the documentation: http://dimsemenov.com/plugins/magnific-popup/documentation.html in the "Image Type" section
I tried to use the selected answer, but even using the documentation, the examples wouldn't work for me. What I ended up using was:
$('.elements').magnificPopup({
type: 'image',
gallery: {
enabled: true
},
image: {
titleSrc: function(item) {
return item.el.find('img').attr('title');
}
}
});
This probably has something to do with the version I was using, but it wasn't clear what version the documentation was for. Hopefully this is useful to someone.

TinyMCE: Set background-color for complete editor content?

I'm using TinyMCE 4. Unfortunately the "backcolor" control seems to only allow changes to text, not a whole paragraph. Even when I select a paragraph in the status bar of TinyMCE and apply a background color, it's only applied to the inner span, not the paragraph itself. I would need to set the background color for the complete content, not only parts of it. This should be applied to the HTML output, something like
<div style="background-color: #f00">[complete editor content]</div>
Thanks for any help.
You can use this code to access the tinymce's body to set background color:
tinymce.activeEditor.getBody().style.backgroundColor = '#<yourcolor>';
Disadvantage: Setting the background color that way will not change/affect the html content inside the editor. So you have to treat/update/store that value in a separate way.
You can also add a button on initialising tinymce:
tinymce.init({
...
setup: function (editor) {
editor.addButton('mybutton', {
text: 'Set bgColor',
icon: false,
onclick: function () {
editor.getBody().style.backgroundColor = '#E5FFCC';
}
});
...
});
You have to reach the editable content body in the dynamically generated iframe. The iframe is generated after the initialization of the editor.
If your textarea id is foo, the id of the iframe is foo_ifr.
You may also open the editor with firebug or developer tools and use dom explorer, you may see the inner dynamically generated components.
use:
var iframe = document.getElementsByTagName("iframe")[0];
// or
var iframe = document.getElementsById("foo_ifr");
// check if iframe.contentDocument is cross-browser, i tested with IE 11.
var innerBody = iframe.contentDocument.getElementsByClassName("mceContentBody")[0];
innerBody.style.backgroundColor="red";
To get the custom styling that you want, you have to create new custom style formats when the editor is being initialized. This gives you the ability to define css styling to the element. For example
HTML
<form>
<textarea></textarea>
</form>
JS
tinymce.init({
selector: 'textarea',
//merge with default formats
style_formats_merge: true,
//set up custom style formats
style_formats: [
{title: 'Red Background', block: 'p', styles: {
'background-color': '#ff0000',
'color':'white',
'padding': '7px'}
},
{title: 'Blue Background', block: 'p', styles: {
'background-color': '#0000ff',
'color':'white',
'padding': '7px'}
}
]
});
This merges two new custom formats with the default formats. See this DEMO

How to add custom formatting to Redactor

I'm wondering if it's possible to add custom formatting to redactor? I created a custom button, and I'm able to change the formatting of text, but only using certain elements:
['p', 'blockquote', 'pre', 'h3', 'h4', 'h5']
However, I'm not able to add any of the following:
['small', 'figcaption']
I followed the Redactor docs to set up the button, and here is my function that is being called:
var selected_html = $('#redactor_content').getSelected();
$('#redactor_content').execCommand('formatblock', '<small>');
I also tried adding elements to my 'formattingTags' array, but it didn't seem to have any affect.
formattingTags: ['p', 'blockquote', 'small', 'pre', 'h3', 'h4']
Thank you in advance.
I think I figured it out.
I added the following to my button function:
var $selected_html = $('#redactor_content').getSelected();
$('#redactor_content').execCommand('inserthtml', '<small>' + $selected_html + '</small>');
However, this is not perfect as it does not replace the parent tag, and you can keep adding elements within elements.
Something like that:
redactorOptionsDefaults = {
buttonsAdd: {},
activeButtonsAdd: {},
buttonsCustom: {}
};
redactorOptionsDefaults.buttonsCustom.small = {
title: 'small Header',
callback: function () {
this.formatBlocks('small');
}
}
redactorOptionsDefaults.activeButtonsAdd.small = 'small';
It formatting block, highlight button if needed while selecting block. But don't remove style while repeat button click

How to add a "small caps" style for the TinyMCE Advanced editor to use the style in the "Styles" dropdown tool in WordPress

The Mystique theme includes two files that need to be updated to allow a custom styles section. The addition of a "small caps" style for use in the correct formatting of law journal citations. What is the steps to add a "small caps" style for the TinyMCE Advanced editor to use the style in the "Styles" dropdown tool in WordPress.
Using TinyMCE 4, the following custom setup function will add a SmallCaps control:
setup: function (ed) {
//Adds smallcaps button to the toolbar
ed.addButton('smallcaps', {
title: 'Smallcaps',
icon: 'forecolor',
onclick: function (evt) {
ed.focus();
ed.undoManager.beforeChange();//Preserve highlighted area for undo
ed.formatter.toggle('smallcaps');
ed.undoManager.add();//Add an undo point
},
onPostRender: function () {
var ctrl = this;
ed.on('NodeChange', function (e) {
//Set the state of the smallcaps button to match the state of the selected text.
ctrl.active(ed.formatter.match('smallcaps'));
});
}
});
}
The answer given by Goetz is not complete, since TinyMCE does not know about your "user defined format" if you don't define it explicitly. Maybe it did some years ago, but version 4.7.x doesn't seem to do so. Add the code below in addition to his answer (it maybe needs to be bevore setup):
formats: {
smallcaps: {
inline: 'span',
styles: {
'font-variant': 'small-caps'
},
attributes: {
title: 'smallcaps'
}
},
},
toolbar: 'smallcaps_button'
I prefer naming the formats and buttons slightly differently by suffixes like _button or _format, but that actually should not be a problem. Hence it avoids forgetting about to correctly define all needed parts here (format, toolbar, ed.addButton()). So, my toolbar contains the button smallcaps_button and the function is ed.addButton('smallcaps_button')
That's it.

chrome extension content script can not access to iframes

i want to make a chrome extension on google reader and i found a problem. content script can not access to iframes. For all n, window.frames[n] = undefined. And i have this "all_frames": true in manifest.json. Or someone could tell me how to add a button under each article. Thank you!
From taking a quick look at Google Reader's rendered HTML, the only button that is in an IFRAME appears to be the Google Plus +1 button - all the other buttons are not in an IFRAME. So you don't need to worry about the IFRAME.
I'm assuming that the existing buttons are the buttons that appear underneath each article: +1, Share, Email, Keep Unread, Add Tags.
If you want to add a new button to the existing article buttons all you need to do is enumerate the DOM - specifically the "entry-actions" DIV classes and append say a new SPAN with your element/button to each article.
I suspect (but not sure) that Reader may dynamically update the DOM with new articles. If this is the case you may need to track new articles being added to the DOM so you can add your button again. To do this add an event listener for DOMNodeInserted - e.g.
document.addEventListener('DOMNodeInserted', onNodeInserted, false);
UPDATE:
The reason you can't see ".entry-actions" class is because it is added dynamically.
Here is a working very basic example. This will monitor the DOM and when it sees an entry-actions DIV that doesn't have our ".myclass" SPAN button, will add it.
You need to have jquery included in your extension for this to work. I've used jquery-1.7.1.min.js in this example. You will also need an icon file called foo.png too if you cut and paste the example.
manifest.json
{
// Required
"name": "Foo Extension",
"version": "0.0.1",
// Recommended
"description": "A plain text description",
"icons": { "48": "foo.png" },
//"default_locale": "en",
// Pick one (or none)
"browser_action": {
"default_icon": "Foo.png", // optional
"default_title": "Foo Extension" // optional; shown in tooltip
},
"permissions": [ "http://*/", "https://*/", "tabs" ],
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery-1.7.1.min.js", "content_script.js" ],
"run_at": "document_idle"
}
]
}
content_script.js
var timer;
document.addEventListener('DOMNodeInserted', onNodeInserted, false);
function onNodeInserted(e)
{
if(timer) clearTimeout(timer);
timer = setTimeout("addButtons()", 250);
}
function addButtons()
{
console.log('add buttons');
var $actions = $(".entry-actions").filter(function() {
return $(this).find('.myclass').length === 0;
});
$actions.append('<span class="myclass">My button</span>');
}

Resources