wysihtml5 Dissable Parser Rules when pasting but enable for prepoluted text and typing? - wysihtml5

Using the wysihtml5 editor, is there a way to disable the parser rules for pasting, or simply paste plain text? Such that only plain text, with no tags or any other formatting is pasted? Commenting out my parser rule does not work for me because I still want pre-populated text (with anchor and line-break tags) to be parsed by my parser rules. Although not essential, I also would like the editor to detect URLs and create anchors as I type, but not necessarily when pasting.
The reason I want to do this is because a lot of garbage characters (like new lines %0A and span tags) are pasted when pasting using the parser rules (specially from MSWord, but also from web content). Pasting plain text would prevent random hidden content from being pasted.
Just for reference, my parser rules are extremely simple:
var wysihtml5ParserRules = {
tags: {
br: {},
a: {
set_attributes: {
target: "_blank",
rel: "nofollow"
},
check_attributes: {
href: "url" // important to avoid XSS
}
}
}
};

If you want plain text all the time, go to your project Scripts and you will find file wysihtml5-toolbar.min.js
Find text
wysihtml5.dom.getPastedHtml=function(a){var b;return
a.clipboardData&&(wysihtml5.lang.array(a.clipboardData.types).contains("text/html")?b=a.clipboardData.getData("text/html"):wysihtml5.lang...
Change b=a.clipboardData.getData("text/html") to "text/plain"

Related

How to implement markdown editor with TinyMCE?

I want to add a markdown editor for users to post their answers into my page. I've found TinyMCE but there is a problem with it: I don't know how to implement markdown editor with TinyMCE.
Is there anybody who has experience with this? Please show me how to setup a markdown editor with it.
It looks like the Text Pattern Plugin can do this:
This plugin matches special patterns in the text and applies formats or executed commands on these patterns.
…
tinymce.init({
selector: "textarea", // change this value according to your HTML
plugins: 'textpattern',
textpattern_patterns: [
{start: '*', end: '*', format: 'italic'},
{start: '**', end: '**', format: 'bold'},
{start: '#', format: 'h1'},
{start: '##', format: 'h2'},
{start: '###', format: 'h3'},
{start: '####', format: 'h4'},
{start: '#####', format: 'h5'},
{start: '######', format: 'h6'},
{start: '1. ', cmd: 'InsertOrderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList'}
]
});
Note that the plugins key here fixes a typo in the upstream documentation, which uses plugin instead.
TinyMCE does not currently support a markdown mode with their editor, however I just recently was in the situation where I needed a markdown editor and wanted to use tinymce for it.
You will have to add a markdown package to your project. I recommend MarkdownIt, which I found from this list of recommendations. You can use any one of the recommendations from the link, just change the MarkdownIt usage with your markdown library in the code examples below.
I do not recommend Chris' approach because it's not very user friendly - the user needs the ability to save text with markdown in it and expect it to render the proper element when it is rendered. To have to press space or enter after each element to watch it change into a WYSIWYG style element is not user friendly. As such, if you take this approach you should actually remove the textpattern plugin and the textpattern_patterns configuration.
What you will want to do is to configure the setup function in your tiny config to listen to change events, and then pass the content through your markdown parser before returning the value to whatever needs it. You will also want to set menubar, toolbar, and statusbar to false.
var editorHandlerTimeout;
var MarkdownIt = require('markdown-it')
tinymce.init({
el: 'el',
menubar: false,
toolbar: false,
statusbar: false,
setup: function (editor) {
editor.on('paste change input undo redo', function() {
// the timeout is to throttle how often this runs while typing
clearTimeout(vm.editorHandlerTimeout);
vm.editorHandlerTimeout = setTimeout(function () {
var md = new MarkdownIt() // or any other markdown library
var contentFromEditor = editor.getContent()
//MarkdownIt adds its own paragraph tags, so strip the ones from tinymce
if (contentFromEditor.startsWith('<p>'))
contentFromEditor = contentFromEditor.substring(3)
if (contentFromEditor.endsWith('</p>'))
contentFromEditor = contentFromEditor.substring(0, contentFromEditor.length - 4)
var contentFromMdIt = md.render(contentFromEditor)
// markdown-it inserts the html encoded values for these (this might be a bug), so we will want to replace them since we will be rendering as html
contentFromMdIt = contentFromMdIt.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/&/g, '&')
// time to do something with your rendered markdown text
// im in vuejs, so I emit the result as 'input' which allows my markdown editor to work as a v-model
vm.$emit('input', contentFromMdIt)
})
})
})
})
Also, it is highly recommended to add a preview to your markdown editor, as the majority of users are unfamiliar with markdown. Make the preview feature simple and accessible, and just render their output as html so they can see what is happening.
Seems TinyMCE has a Markdown plugin for their editor now
https://github.com/vaidhyanathan93/Markdownfortinymce/blob/master/markdown/plugin.js
https://www.tiny.cloud/labs/markdown/
Tiny Markdown is a markdown syntax plugin for TinyMCE, providing
flexible rich text and markdown content creation options for authors,
and also provides robust, reliable markdown output for developer
projects.

Programmatically adding content to tinymce

I am trying to use javascript to add text input to a tinyMCE editor,
I can append the text visually using :
tinymce.activeEditor.selection.setContent(' words and stuff ');
have also tried
tinyMCE.activeEditor.selection.setContent(' ');
Which will allow me to see the text specified above no problem, however when i go to save its almost as if the javascript didnt actually append the text where it should have or something, my save is the original text without the text appended above, does anyone have any idea why?
The issue i was having was, I would add text into tinymce with the javascript line
function AddNotes(NoteS) {
tinymce.activeEditor.execCommand('mceInsertContent', false ,NoteS);
}
And for some reason, I needed to insert into the tinymce TWO TIMES for it to work.
So what I did to compensate was added the information that I want to add, and then I throw in a paragraph element which creates a new line under what I just added. I could have added a space, or whatever I want but I chose to add a new line as seen below:
function AddNotes(NoteS) {
tinymce.activeEditor.execCommand('mceInsertContent', false, NoteS);
tinyMCE.activeEditor.execCommand('mceInsertContent', false, '<p></p>');
}

CKEditor insert empty paragraph

In the CKEditor plugin I'm writing, i need to create a new empty paragraph.
I know that empty paragraphs (<p></p>) are collapsed by most browsers, that is why CKEditor has some special handling for them:
When displaying the HTML source, CKEditor displays <p> </p> for an empty paragraph (for example, when you press enter twice)
Depending on the browser, in the editing area CKEditor fills the Paragraph with another placeholder. For example in Mozilla Firefox, it inserts a <br type="_moz" /> into the paragraph.
However, when inserting a p DOM node manually (using the CKEditor dom object), this special handling is omitted. It magically appears when i switch to source view and back edit mode, though.
I've tried:
var new_p = new CKEDITOR.dom.element('p');
editor.insertElement(new_p);
And:
var new_p = new CKEDITOR.dom.element.createFromHtml('<p></p>');
editor.insertElement(new_p);
And also:
editor.insertHtml('<p>');
But the special handling of the empty paragraph does not take place. I get an empty Paragraph, but as the Browser is collapsing it, I can't see or edit its content correctly.
When switching back and forth to the source code view, CKEditor detects the empty paragraph and inserts the filler. Also when submitting the data. But i need the filler to appear immediately when inserting the new node.
How do i get CKEditor to handle my new paragraph like any other empty paragraph it would create when a user hits Enter twice?
I know i could also insert manually as HTML content to the new DOM node, but thats a huge difference - because in this case, the space really appears in the editing area, so when a user enters content into the new paragraph, he must delete the non-breaking space manually.
After researching how CKEditor handles the press of [ENTER] internally, i came to this solution:
var new_node = new CKEDITOR.dom.element( 'p' );
// insert UTF-16 non-breaking space
var dummy = editor.document.createText( '\u00A0' );
dummy.appendTo( new_node );
editor.insertElement(new_node);
// move cursor to beginning of new element
var range = editor.createRange();
range.moveToPosition( new_node, CKEDITOR.POSITION_AFTER_START );
editor.getSelection().selectRanges( [ range ] );

silverstripe backend linebreaks in content do not show up in frontend

I have a textareaField in Silverstripe Backend in Edit Page View... The text to insert contains linebreaks. If I save the Page the text shows correctly with linebreaks in the textareaField. The linebreaks are for sure saved correctly to the database. But how do I display the text correctly in the frontend? It´s always outputted without linebreaks in a single line.
I tried already $Text.RAW, $Text.XML,... nothing works.
Thanks for the help,
Kind regards,
Florian
Assuming that you are using 3.0 this is a bug. You can see it here http://open.silverstripe.org/ticket/7596
A work around is to write your own function calling nl2br on your text field.
Here is an example:
public function NiceDescription () {
return (nl2br (Convert::raw2xml ($this->Description), true));
}
You can replace "Description" with the name of your text property.
Then in your template file if you need to display the description field you will call the function:
$NiceDescription
to visually render the newlines in html, you need to convert them to <BR> tags.
see http://php.net/manual/de/function.nl2br.php

GWT: RichTextArea getHTML loses "outer" tags

Please bear with me as I am a newbie in gwt and front end stuff.
I have a html string:
String s=
"<html><head><title>Hello World</title></head><body><b>Hello World</b></body></html>";
(I am using spaces in the tags to prevent the text from displaying "htmlized".)
//and gwt RichTextArea control->richTextArea
richTextArea.setHTML(s);
//So far so good as the document String displays as desired.
//Now comes the problem...
String transformed = richTextArea.getHTML();
The rich text area strips the outer and returns the inner html only. i.e. The body, html and the head tags are stripped.
Q How do I get the html string returned with only the modifications which occur in the rich text area showing.. i.e. The original "outer" tags do not get lost.
Hope I am adequately clear.
You don't have to set them in setHTML <b>hello world<b/> is enough.
Also if you set the outer tags you can't get them, as they don't add anything in the formatting of the text.