Toggle live preview in ckeditor - javascript

I am using jquery adapter for ckeditor, I am able to add custom css files in editor preview using CKEDITOR.config.contentsCss
Below is embedded javascript code to create ckeditor for textarea with #editor2 ID.
jQuery(function()
{
var config = {
contentsCss :['css/bootsrap/bootstrap.css', 'contents-custom.css'],
}
jQuery('#editor2').ckeditor(config);
I want to create a plugin which may be call "live preview" on click of this button these CSS files will be added. This button should be like toggle.
My question is, How can I control the config from adding and deleting contentCss configuration?

With jQuery, you'll be able to trick the page. I don't think there's a known way for doing that with CKEditor's API. But, you can delete the <link> your files.
//to remove styling:
$('#cke_ckeditor iframe').contents().find('html head link').remove();
//to reload CSS:
$('#cke_ckeditor iframe').contents().find('html head').append('<link href="customContents.css" rel="stylesheet" type="text/css" />');
If you want, you can control which file will be removed by removing only the first() or the last() link, as well in the reloading snippet.
Good luck!

Related

ng2-ckeditor - how to customise the css loaded inside the editor itself?

I need to customise the ENTER key behaviour of ng2-ckeditor. I understand there is a config option as explained here.
However as that link explains, I should use custom css:
If you want to change it to control paragraph spacing, you should use
stylesheets instead. Edit the contents.css file and set up a suitable
margin value for <p> elements, for example:
p { margin: 0; }
According to this SO question I can load a custom CSS file using a config option, like this:
config.contentsCss = 'mystyles.css'
I tried adding a single file to my project and setting the config in angular 2 component, but the file does not appear to load.
private setConfig(): void {
this.ckConfig = {
height: '250',
extraPlugins: 'divarea',
contentsCss: '/theme/styles/ckeditor.css',
toolbar: [... toolbar configurations ...]
};
}
So how can I get ng2-ckeditor to load this file?
This breaks if you have the DIVAREA plugin activated
Edit (from comment):
This is because contentsCss does not load when using DIVAREA. Makes sense since the CSS would need to be scoped to inside the DIV (easy with iFrame).
Maybe new CSS layers could help here?
github.com/ckeditor/ckeditor4/issues/4640 github.com/ckeditor/ckeditor4/issues/4642

How to dynamically add css to ckeditor without a css file

I have a situation where I am storing dynamic css data about a text object in a database as json. I need to map that same css data into styles in CKEditor. I am successfully able to load the classes into the CKEDITOR styles dropdown by parsing the json into the style set by running:
CKEDITOR.stylesSet.add('myStyles',styleObj);
Unfortunately this does not fully work with the onscreen text because the css does not exists as a file.
I've also successfully generate the css into the head of the dom by appending the dynamically generated css to a style tag. Unfortunately this still does not connect the actual css generated to the CKEDITOR because it is in a separate context.
Does anyone know how I can either connect document level css to the CKEDITOR instance or generate the CSS in a way that CKEDITOR understands? I'd prefer not to write a temporary CSS file to disk for every single user who needs to view the text object.
I figured out the answer to this by using the CKEDITOR.addCss() function.
Instead of trying to load the css into the document head as styles, the process can be much simpler by running CKEDITOR.addCss() function.
The code looks like:
for each css style found in the json:
styleObj.push({name:this.name,element:'p',attributes: { 'class':cssClassName}});
var cssSheetString = '.'+cssClassName+' {font-family:'+this.fontFamily+'; font-size:'+fontSize+'; font-weight:'+this.fontStyle+'; text-decoration:'+textDecoration+'; } ';
CKEDITOR.addCss(cssSheetString);
after the loop ends then also add the styles object:
if(!CKEDITOR.stylesSet.registered.myStyles){
CKEDITOR.stylesSet.add('myStyles',styleObj);
}
Just for posterity. I've seen answers that say this will work
CKEDITOR.on('instanceCreated', function (event) {
event.editor.addCss(styles);
});
but it does not, you have to use
CKEDITOR.on('instanceCreated', function (event) {
CKEDITOR.addCss(styles);
});
also if your styles variable changes you have to destroy and recreate your ckeditor instance with the new styles.

Javascript remove ckeditor plugins on load

Html:
<textarea name="Editor" class="ckeditor" id="aboutme">#Model.Content</textarea>
Javascript:
<script>
config.removePlugins = 'elementspath,save,font';
</script>
When page load , i want to disable all ckeditor plugins.I tried above code however it did not work for me.
How can i remove plugins by javascript on load of page ?
Any help appreciates.
Thanks.
You can define a list of plugins to load (CKEDITOR.config#plugins):
config.plugins = 'wysiwygarea,toolbar,basicstyles,...';
But you can also restrict existing (default) list of plugins (CKEDITOR.config#removePlugins):
config.removePlugins = 'link,...';
Both options can be defined globally (config.js) or for a particular editor instance like
CKEDITOR.replace( 'editor1', {
removePlugins: 'link'
} );
Please refer to official Setting Configuration guide to know more.
Note: Since CKEditor 4.1, the presence of a plugin determines whether certain type content associated with that plugin is allowed or disallowed. Read more about Advanced Content Filter.
To answer my own question in the comment to oleq's answer:
I have a CKEditor instance that I'm using (with jQuery) like so:
window.onload = function () {
$ckTarget = $(".pageContentTextBox");
if ($(".pageContentTextBox").length > 0) {
$ckEditor = $ckTarget.ckeditor({
htmlEncodeOutput: true,
removePlugins: "link"
});
}
};
I was able to successfully remove the "link" plugin that way. I am going to set up an ASP.net User Control with public properties "extraPlugins" and "removePlugins" and insert the values using the client-side yellow tags ("code nuggets") to be able to use this on multiple pages with different plugins enabled/disabled.
I hope that helps someone!
You can also edit the config.js. This js is loaded/included from the ckeditor.js. config.js is a default custom editor js file. You can remove buttons or your plugins from the editor by including the list of names of elements to remove. For the list of names to remove from the editor please refer to the below link: https://ckeditor.com/old/forums/CKEditor-3.x/config.js-changes-not-reflected
Include the list of buttons or plugins to remove from the editor by appending them to the config.removebuttons and include this line of code in config.js
// Remove some buttons provided by the standard plugins, which are
// not needed in the Standard(s) toolbar.
config.removeButtons = 'Underline,Subscript,Superscript,Image,Flash,Table,HorizontalRule,Smiley...';

Inserting CSS for an Element from a input field

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?
Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.
If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);
This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .
Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}

Dynamically add contents style to CKEditor 4 instance

I have passed a CSS filepath to my CKEditor instance with the contentsCss option, which works great. However, I need to be able dynamically add more styles that I can't add in the CSS file. In version 3 it looks like one could use the addCss function (see this forum post). Unfortunately, this doesn't seem to work in version 4 (see this forum post). Does anyone have an alternative? I am using the jQuery adapter, so a solution using either API would work.
I think you can do something like
$(window).on('print',function(e){
e.preventDefault();
var styles = '<style>'+/*calculation of styles*/+'</style>'
$('head').append(styles);
window.print();
});
or
$(window).on('load',function(e){
var styles = '<style>'+/*calculation of media query print styles*/+'</style>'
$('head').append(styles);
});

Categories