Customise TinyMCE editor in Episerver 9 - tinymce

I am working on Episerver 9. I have a requirement where user can copy content (which includes HTML tags) into the TinyMCE editor.
I want only the text content to be pasted. HTML tags should be filtered out automatically by default.
Is there any way to achieve this using TinyMCE?

You can register a custom TinyMCE plugin in Episerver using the TinyMCEPluginNonVisual attribute. By setting AlwaysEnabled to false, you can use property settings to determine whether the plugin should be enabled or not for a specific editor/XHTML property.
[TinyMCEPluginNonVisual(AlwaysEnabled = false, PlugInName = "customplugin")]
public class MyCustomPlugin
{
}
Your actual TinyMCE plugin (i.e. JavaScript code) could be something like the following:
(function (tinymce, $) {
tinymce.create('tinymce.plugins.customplugin', {
init: function (editor, url) {
editor.onPaste.add(function (editor, event) {
if (!event.clipboardData || !event.clipboardData.items) {
return;
}
// TODO Modify event.clipboardData, for example to strip out HTML tags
});
}
});
// Register plugin
tinymce.PluginManager.add('customplugin', tinymce.plugins.customplugin);
}(tinymce, epiJQuery));
While this isn't a complete example, it should get you started in the right direction.
You should also have a look at the official documentation.
Edit: If you just want to alter the paste_as_text setting, you could register a plugin and set the configuration through the TinyMCEPluginNonVisual attribute:
[TinyMCEPluginNonVisual(EditorInitConfigurationOptions = "{ paste_as_text: true }")]
public class PasteAsTextPlugin
{
}

Assuming that you are loading the paste plugin you can force TinyMCE to always paste as plain text with the following:
tinymce.init({
...
plugins: "paste",
paste_as_text: true
...
});
https://www.tinymce.com/docs/plugins/paste/#paste_as_text
I would assume that Episerver provides you some way to manipulate the configuration of TinyMCE. Adding the paste_as_text option to that configuration should do what you need.

Related

cannot set specific tinymce textarea content from a function

I have a page with multiple textareas that use TinyMCE to be able to display WYSIWYG content. This works fine but I need to set a specific textarea content from a function. I tried this approach...
<script>
function addText() {
var html = "<b>hello world</b>";
tinymce.get('#myFirstTextArea').setContent(html);
}
</script>
But when I do that I get a "Cannot read properties of null (reading 'setContent')" Error. What am I doing wrong here?
I use TinyMCE ver 6
Most likely you have a timing issue in your JavaScript. You cannot make a get() call until after TinyMCE is fully initialized.
TinyMCE has an event that gets called once the editor is fully initialized. You can put this in your TinyMCE init. For example:
tinymce.init({
...
setup: function (editor) {
editor.on('init', function (e) {
editor.setContent('<p>This is the content in TinyMCE!</p>');
});
}
...
});

Tinymce - How can I specify a directory on my server to use when I insert an image?

This works fine if I was to implement uploading an image via tinymce etc, which I'm really not interested in doing.
I already have hundreds of images uploaded from another part of the website that I'd like to insert into pages being edited and created with tinymce v5.
But how can I indicate in the Insert/Edit dialog box to show just the contents of one directory on the server?
I had a hack from vers 3 something I think it was that I can't locate, and it being so ancient I'm sure it's pretty useless, it didn't even support Safari, so it had to be 10+ years old.
Can't find anything in tinymce docs about indicating a directory to use with insert image.
Some custom javascript to include somewhere???
My basic starter tinymce code:
<script>
tinymce.init({
selector: '#editor',
plugins: 'image code',
toolbar: 'undo redo | link image | code',
/* enable title field in the Image dialog*/
image_title: true,
/* enable automatic uploads of images represented by blob or data URIs*/
automatic_uploads: true,
/*
URL of our upload handler (for more details check: https://www.tiny.cloud/docs/configure/file-
image-upload/#images_upload_url)
images_upload_url: 'postAcceptor.php',
here we add custom filepicker only to Image dialog
*/
file_picker_types: 'image',
/* and here's our custom image picker*/
file_picker_callback: function (cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
/*
Note: In modern browsers input[type="file"] is functional without
even adding it to the DOM, but that might not be the case in some older
or quirky browsers like IE, so you might want to add it to the DOM
just in case, and visually hide it. And do not forget do remove it
once you do not need it anymore.
*/
input.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
/*
Note: Now we need to register the blob in TinyMCEs image blob
registry. In the next release this part hopefully won't be
necessary, as we are looking to handle it internally.
*/
var id = 'blobid' + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var base64 = reader.result.split(',')[1];
var blobInfo = blobCache.create(id, file, base64);
blobCache.add(blobInfo);
/* call the callback and populate the Title field with the file name */
cb(blobInfo.blobUri(), { title: file.name });
};
reader.readAsDataURL(file);
};
input.click();
},
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
});
</strict>
There are several ways to do so:
MoxieManager plugin. Here is the demo. However, it's a premium feature.
Depends on the number of images you have on the server. If there aren't many, you can try to use the image_list option of the Image plugin. It will load the editor with a predefined set of images.
Implement the custom file picker with the file_picker_callback option.

CKeditor: How to build a custom plugin?

I am trying to create a custom plugin for CKeditor following this guide. I created the files as indicated (myplugin.png, myplugin.js, plugin.js) and added
CKEDITOR_CONFIGS = {
'default': {
'extraPlugins': ','.join( [ 'myplugin' ] ),
'allowedContent' : True,
}
}
to the settings.
This is the content of my plugin.js file:
CKEDITOR.plugins.add( 'myplugin', {
icons: 'myplugin',
init: function( editor ) {
// Plugin logic goes here...
editor.addCommand( 'myplugin', new CKEDITOR.dialogCommand( 'mypluginDialog' ) );
editor.ui.addButton( 'myplugin', {
label: 'My Plugin',
command: 'myplugin',
toolbar: 'insert'
});
}
});
Yet, the icon of the custom plugin still doesn't show. I can see in the browser's tools that the plugin.js file is retrieved. I made a test by removing the icon file and it didn't create any difference (no error message, no 404). I suppose then that the file is not even called or accessed. so the initialization does not even try to render the button.
Thank you for your help.
Finally, I found the answer to the problem. It comes from the way CKEditor displays the toolbars. In the guide, the custom plugin is added to the "insert" group of the toolbars. However, this one will not be visible until it is explicitely set to be displayed.
Adding the extra plugin to the default configuration is not enough, the toolbar setting has to be specified properly (if for some reason, your platform doesn't default to null). In my case, with django-ckeditor, I had to add
'toolbar': None,
to the CKEDITOR_CONFIGS.

Configuring Single RTE Wrapper for Multiple Classes - Typoscript/Typo3

I'm trying to write Typoscript that will configure the Typo3 Rich Text Editor to wrap a given element with more than one class.
In the project's TsConfig/Page/rte.txt file, I have:
RTE {
classes {
button {
name = Button
}
}
However, I'd like to create a wrapper that would give the element more than just a single class. The below code doesn't work, but illustrates what I'm trying to accomplish:
RTE {
classes {
button {
name = Button
}
button danger {
name = Dangerous Button
}
}
According to this article, this doesn't seem to be possible, but I thought I'd ask and see if someone out there got crafty with their Typoscript and was able to accomplish this.
I tried everything to handle styles for tables that way, but there is currently no way to handle more than one CSS-Class for a RTE style definition.
The only way to handle this, is creating new CSS classes and extend the available button styles via LESS or SCSS.
In TYPO3 7 you can use this following RTE configuration to use multiple classes. The magic happens in the class-definition with the attribute "required"
RTE {
default {
proc.allowedClasses := addToList(btn-dark)
buttons.link.properties.class.allowedClasses := addToList(btn-dark)
}
classes.btn-dark {
name = Dark-Button
requires = btn btn-small
}
classesAnchor.buttonDark {
class = btn-dark
type = page
}
}

Prevent TinyMCE from removing span elements

Here is the problem demonstration
You can try it here: http://fiddle.tinymce.com/SLcaab
This is TinyMCE default configuration
less all the plugins
with extended_valid_elements: "span"
1 - Open the Html Source Editor
2 - Paste this html into the Html Source Editor:
<p><span>Hello</span></p>
<p>Google 1</p>
<p>Google 2</p>
3 - Click update in the Html Source Editor to paste the html in the editor
4 - Remember there is a span around 'Hello'.
5 - Place your cursor just before Google 2 and press backspace (the two links should merge inside the same paragraph element).
6 - Look at the resulting html using the Html Source Editor.
Result (problem): No more span in the html document even though we added 'span' to the extended_valid_elements in the TinyMCE settings.
Note: I removed all the plugins to make sure the problem is at the core of TinyMCE.
Edit 1 - I also tried: valid_children : "+p[span]" - still does not work
Edit 2: Only reproduced on WebKit (OK on Firefox and IE)
Insert extended_valid_elements : 'span' into tinymce.init:
tinymce.init({
selector: 'textarea.tinymce',
extended_valid_elements: 'span',
//other options
});
I have the same problem and I find solutions. Tiny MCE deleted SPAN tag without any attribute. Try us span with class or another attribute for example:
<h3><span class="emptyClass">text</span></h3>
In TinyMCE 4+ this method good work.
Tinymce remove span tag without any attribute. We can use span with any attribute so that it is not removed.
e.g <span class="my-class">Mahen</span>
Try this for 3.5.8:
Replace cleanupStylesWhenDeleting in tiny_mce_src.js (line 1121) with this::
function cleanupStylesWhenDeleting() {
function removeMergedFormatSpans(isDelete) {
var rng, blockElm, wrapperElm, bookmark, container, offset, elm;
function isAtStartOrEndOfElm() {
if (container.nodeType == 3) {
if (isDelete && offset == container.length) {
return true;
}
if (!isDelete && offset === 0) {
return true;
}
}
}
rng = selection.getRng();
var tmpRng = [rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset];
if (!rng.collapsed) {
isDelete = true;
}
container = rng[(isDelete ? 'start' : 'end') + 'Container'];
offset = rng[(isDelete ? 'start' : 'end') + 'Offset'];
if (container.nodeType == 3) {
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
// On delete clone the root span of the next block element
if (isDelete) {
blockElm = dom.getNext(blockElm, dom.isBlock);
}
if (blockElm && (isAtStartOrEndOfElm() || !rng.collapsed)) {
// Wrap children of block in a EM and let WebKit stick is
// runtime styles junk into that EM
wrapperElm = dom.create('em', {'id': '__mceDel'});
each(tinymce.grep(blockElm.childNodes), function(node) {
wrapperElm.appendChild(node);
});
blockElm.appendChild(wrapperElm);
}
}
// Do the backspace/delete action
rng = dom.createRng();
rng.setStart(tmpRng[0], tmpRng[1]);
rng.setEnd(tmpRng[2], tmpRng[3]);
selection.setRng(rng);
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
// Remove temp wrapper element
if (wrapperElm) {
bookmark = selection.getBookmark();
while (elm = dom.get('__mceDel')) {
dom.remove(elm, true);
}
selection.moveToBookmark(bookmark);
}
}
editor.onKeyDown.add(function(editor, e) {
var isDelete;
isDelete = e.keyCode == DELETE;
if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
e.preventDefault();
removeMergedFormatSpans(isDelete);
}
});
editor.addCommand('Delete', function() {removeMergedFormatSpans();});
};
put an external link to tiny_mce_src.js in your html below the tiny_mce.js
It's possible to use the work around by writing it as a JavaScript script which prevents WYSIWIG from stripping empty tags. Here my issue was with including Font Awesome icons which use empty <i> or <span> tags.
<script>document.write('<i class="fa fa-facebook"></i>');</script>
In the Tinymce plugin parameters enable:
Use Joomla Text Filter.
Be sure your user group have set "No filtered" Option in global config > text filters.
Came across this question and was not happy with all the provided answers.
We do need to update wordpress at some point so changing core files is not an option. Adding attributes to elements just to fix a tinyMCE behaviour also doesn't seem to be the right thing.
With the following hook in the functions.php file tinyMCE will no longer remove empty <span></span> tags.
function tinyMCEoptions($options) {
// $options is the existing array of options for TinyMCE
// We simply add a new array element where the name is the name
// of the TinyMCE configuration setting. The value of the array
// object is the value to be used in the TinyMCE config.
$options['extended_valid_elements'] = 'span';
return $options;
}
add_filter('tiny_mce_before_init', 'tinyMCEoptions');
I was having same issue. empty SPAN tags are being removed. The solution i found is
verify_html: false,
Are you running the newest version of TinyMCE? I had the opposite problem - new versions of TinyMCE would add in unwanted span elements. Downgrading to v3.2.7 fixed the issue for me, that might also work for you if you are willing to use an old version.
Similar bugs have been reported, see the following link for bugs filtered on "span" element:
http://www.tinymce.com/develop/bugtracker_bugs.php#!order=desc&column=number&filter=span&status=open,verified&type=bug