CKEditor: Apply removeFormat on paste - javascript

I have successfully managed to set up an on paste event to capture the HTML pasted into the text area as it is pasted.
I need to automatically apply the removeFormat command to that HTML before or at the time it is pasted into the text area, so that I can strip it of classes, various tags, and other attributes. Could somebody point me in the right direction to apply the removeFormat command correctly?
Here's my code so far:
$(function(){
$('textarea').ckeditor(
function( textarea ){
var editor = this;
editor.on('paste', function( e ) {
//alert(e.data.html); // This shows the HTML
editor.execCommand( 'removeFormat', e.data.html ); // Doesn't seem to do anything, HTML is pasted with the attributes intact
});
}
)
});
Thanks!
P.S. Force plain text option is not viable as there are some HTML elements I wish to keep (p,table and others).

You can use
config.forcePasteAsPlainText = true;
cf http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html

You need to select the content before you can apply removeFormat to it.
You could try grabbing the range ( even if it's just the cursor sitting at the insertion point ) and saving a bookmark before you paste.
After you paste, use the bookmark to select that range again.
That should select everything that you pasted between the start and end of the range.
Then you can use removeFormat:
editor.execCommand( 'removeFormat', editor.selection );
Here are the links to the range and selection API pages:
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dom.range.html
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dom.selection.html
I've found it easier to work with ranges, the createBookmark method is good because it sets markers and you can grab the correct start and end points even if the DOM changes ( as it will when you paste in the new content ). You can use moveToBookmark() after the paste to select the range.
http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.dom.range.html#createBookmark
Because the documentation is sparse, I've found it helpful to search the source code for places where the methods are called. Looking at how they're used gives me a better idea of what kind of object I need to apply the methods to.
Be Well,
Joe

Starting from CKEditor 4.1 there is no need to do custom coding to define the list of elements that should be kept when pasting data into CKEditor, Advanced Content Filter should do the trick.
Either leave ACF enabled with the default configuration - CKEditor will accept all tags that can be created with it, or define your own set of rules with more or less strict set of allowed tags/attributes/styles. See documentation

Related

Create clone of text selection without use of clipboard

For my application I need a kind of internal clipboard with history.
I can't use the clipboard api (as far as I can see) as this would need permission from the user which is not an option.
I wan't to preserve formatting like bold, italics and strikethrough.
I was thinking about getting the content from window.getSelection(), but there is no way of easily cloning all the html that is in the selection.
The contents would need to go into another container element to be shown somewhere in the app.
Any ideas of how to achieve this are highly appreciated.
Best
Matthias
EDIT: I'm already interrupting the copy event and replace it with custom function. What I need to do is start at the anchorNode, cut some possible offset and go forward to the focusNode (also with offset). Also all unknown/unwanted tags (span, h1, div etc need to be removed but the text content shall stay). I hoped that someone has already done this or a similar task so I can save some time :/
The copy event could help you, as it doesn't require any permission to work.
var clipHistory = [];
document.addEventListener('copy', (event) => {
const selection = document.getSelection();
clipHistory.push(selection.toString());
event.preventDefault(); // optional, it prevents to modify the user's clipboard
});
// other functions can access clipHistory
A nice thing is that the copy event is very well supported.
Unlcukly this solution remove the formatting, but on way to keep it is to use a <div contenteditable id="parse-div"></div> and fire the parse event manually.
I found an intersting class: the Range one, but it doesn't allow to set a start and an end offset of non #text elements, as far I can undertand it.

Preventing CKEDITOR from modifying HTML

I'm trying to force CKE to stop modifying my HTML wildly, and trying to introduce our own rules.
For example, CKE will remove empty span and i tags, we can prevent it from doing it with
CKEDITOR.dtd.$removeEmpty.span = false
CKEDITOR.dtd.$removeEmpty.i = false
So far so good. Then we tried to make A tags to be able to support block level elements (HTML5), which we were able to do by manipulating the DTD as well.
But now it seems the DTD object is not enough for what we are trying to do.
For example, it's removing empty A tags, and I can't prevent it from doing it,
CKEDITOR.dtd.$removeEmpty.a = false
will not do the trick. It's doing the same thing with empty BR tags located at the end of the content.
I know CKE is using a filter, parser, processor or something that I need to hook onto and modify/alter it in order to stop it from doing those changes. Could you please give me any advise on how to achieve this ?
Cordially, Agustin.
UPDATE
I'm also looking forward in adding an extra supported children to SELECT tag. Select supports optgroup and option as children, I'm trying to add support for a custom_tag (inline), but I can't succeed in making it happen.
CKEDITOR.dtd.select.custom_tag = 1
Is not doing it. The custom tag is also declared on dtd.$inline
I guess there is some sort of external processing cleaning it up, and I can't control this from the DTD object. Any pointer on this regard ?
Unfortunately empty links are a special case and to stop removing them you will need to modify the source:
https://github.com/ckeditor/ckeditor-dev/blob/6f4c29002f4d6ecfa39308b641ae37c56bba1348/core/htmlparser/fragment.js#L59-L66
function isRemoveEmpty( node ) {
// Keep marked element event if it is empty.
if ( node.attributes[ 'data-cke-survive' ] )
return false;
// Empty link is to be removed when empty but not anchor. (#7894)
return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
}
BTW. CKEditor removes empty inline elements, because they are not editable (and some things may start working incorrectly). To ensure correct editability of these elements you can write widgets for them.
To disable filtering HTML (source) in CKEditor write in your config.js file this lines:
CKEDITOR.editorConfig = function( config ) {
config.allowedContent = true;
};
Source code here.

Looking for custom script (capturing inner HTML using jQuery) in Adobe DTM data element?

I am trying to capture HTML text value using jQuery in custom script of DTM data element.
See the scenario:
Below is the snippet of code on the page:
<div class="site-categories">
<ul>
<li class="mobile-tablets main">
Mobiles & Tablets
Computers
Electronics
and so on.
So basically the ask is to capture the inner HTML text of anchor tag i.e. 'Mobiles & Tablets' or 'Computers' or 'Electronics', depending upon on what link, user clicks.
To achieve this, in the event based rule section, I have set Condition as the tag to fire when class (under div tag) equals 'site-categories' and enabled bubbling on child elements (so as to cover everything under this to fire omniture tag). And then assigning the value of data element in any evar variable.
In the data element section, after selecting the custom script option, I am writing this code:
var value = $('this').html();
return value;
or
var value = jQuery('this').html();
return value;
But this is not working. I even tried using this:
var value;
_satellite.setVar('value', jQuery('this').html());
return value;
But this also didn't worked. Can I have a solution for this ? I want this to be dynamic as in, depending upon which section user is clicking on the page, the data element should capture the inner HTML text of that particular anchor tag.
Not sure where I am going wrong.
If there is any other solution that exist for this, please let me know. That would be a great help.
Thanks in advance,
Adi
Couple of notes:
Firstly on a sidenote, in your jQuery code, this should not be wrapped in quotes. You should be passing an object reference to the jQuery wrapper. Wrapping it in quotes makes it look for an html element called "this" (e.g. <this>foobar</this>) which is not right.
As to your issue.. not sure how you have setup your rule but basically what you want to do is grab the value and put it into a data element, and then reference the data element when you set the Adobe Analytics variable. So it looks like you were on the right track, and BrettAHale's answer is on the right track too, but to put it all together:
In your rule, add a condition with criteria Data > Custom. Then click "add criteria" and in the codebox, enter in:
_satellite.setVar('linkText', jQuery(this).text());
return true;
This will set a data element named "linkText", and you return true to make sure the condition is always true. You can use "value" as the name but you should use something more descriptive so you can more easily remember it's purpose later (I used "linkText").
Then, in your Adobe Analytics section of the rule, go to the eVars section and select the eVar you want to set. Then for the "set as" value, enter in %linkText%. This is a reference to the data element you just set in the rule. Don't worry if DTM shows a tooltip saying not found or w/e; it only shows/searches for known data elements you set in the interface, not on-the-fly in rules. Click the "save evar" button and you should see e.g. eVar3="%linkText%" listed (but for whatever eVar you chose).
Save and then test/publish the rule.
In the analytics tool section or your rule, set the eVar using the following, not a data element.
%this.text%
Your evar box will show something like this. eVarX="%this.text%"

ckeditor setdata only using some of the HTML Loaded [duplicate]

I have been using CKEditor for some time and it has worked great. I've pretty much gotten rid of any problems that ive had but this one i cant seem to figure out. When i add inline attributes to elements for instance style = "color: #ff0;" on a <p></p> tag they are stripped out when i switch from wysiwyg to source view. No saving or submission is done and ckeditor is has been added to my site which is my own script. Any ideas as to what would cause this. All of the search results i can find correspond to this happening in Drupal but Drupal seems to be the problem not the editor in all instances. Thanks again!
It feels like you're using CKEditor 4.1+ that comes with Advanced Content Filter (ACF). If so, you need to specify config.allowedContent and configure it to get your things working. You may also be interested in config.extraAllowedContent.
See this answer for more details.
For anyone looking for a simple sample on how to enabled additional markup in CKEditor without disabling ACF completely, here is a short snippet:
CKEDITOR.replace( 'editor1', {
extraAllowedContent: 'style;*[id,rel](*){*}'
} );
extraAllowedContent here enables the <style> element, allows two additional attributes (in square brackets) for all (* is a wildcard) already allowed elements, allows usage of any class names (*) for them and allows usage of any inline styles {*}
hi you can stop ACF easily . by default your configaration is---
function ckeditor($name,$value='',$height=300){
return '<textarea name="'.addslashes($name).'">'.htmlspecialchars($value).'</textarea>
<script>$(function(){CKEDITOR.replace("'.addslashes($name).'",{});});</script>';
}
just add this in the curly brackets:
allowedContent: true
now your configuration will be:
function ckeditor($name,$value='',$height=300){
return '<textarea name="'.addslashes($name).'">'.htmlspecialchars($value).'</textarea>
<script>$(function(){CKEDITOR.replace("'.addslashes($name).'",{allowedContent: true});});</script>';
}
I faced the same issue and below answer solved my problem:
config.allowedContent = true;
config.extraAllowedContent = '*(*);*{*}';
config.extraAllowedContent = 'span;ul;li;table;td;style;*[id];*(*);*{*}';
I had the same problem, that ck was stripping not only some attributes, but whole elements when pasting a block element, inside a block element (div with some attributes pasted inside a p) while using this method:
editor.insertHtml(html);
what solved the problem was using this workaround instead:
editor.insertElement(CKEDITOR.dom.element.createFromHtml(html));

web - copy section to clipboard and remove certain elements

Ive got a method which will copy a section of html to the clipboard to allow pasting elsewhere.
It is usually a table of which will be the main content so it will be pasted into excel and keep its formatting, which is lovely.
What I want to do is remove certain elements from this section.
The main ones are checkboxes and textboxes - which cause excel to go really screwy, and for some reason you cannot delete them from excel - you just have to start a new sheet.
This is the method I am using to copy:
$('#CopyClipboard').click(function () {
var contentDiv = document.getElementById('copyablecontent');
var holdtext = document.getElementById('holdtext');
holdtext.innerText = contentDiv.innerHTML;
Copied = holdtext.createTextRange();
Copied.execCommand('Copy');
alert('Data copied to clipboard!');
});
(excuse the horrible mix of jquery and javascript).
So I have my 'contentDiv' variable, I want to parse that and remove all inputs, and possibly other elements too (I could give them all a css class 'doNotCopy' or something).
How can I do this?
you can use:
contentDiv.innerHTML.replace(/<input[^>]*>/g,"")
check the replace method here:
http://www.w3schools.com/jsref/jsref_replace.asp
you may have to adjust the regex for your needs

Categories