ckeditor, how to adjust the wrap code display styling - javascript

I'm testing out CKEditor
I'm trying to get the display in the editor, to match my sites css style for displaying the end result.
What I'm trying to do is style the "wrap code" button to match the css of my site, by adding in a class.
I've seen on this page of the manual, that you can do stuff like this:
config.format_pre = { element: 'pre', attributes: { 'class': 'editorCode' } };
However, doing the same for a code block like so:
config.format_code = { element: 'code', attributes: { 'class': 'someclass' } };
Doesn't actually do anything. Anyone got a pointer on what I might be missing?
I've tested it working on other elements, so I know the config file changes are being picked up.

The one important thing is that every tag which is formatted via config.format_tagname should be also included in config.format_tags. However, this two settings (config.format_tagname and config.format_tags) works only form Block-Level elements (as stated in the manual page you referenced ).
As code element is considered as an inline one by CKEditor (see DTD), it is not possible to use this config here.
However, the easiest way to modify the elements added via Style dropdown is to edit styles.js file which is present in CKEditor directory. The dropdown styles are based on this file, so you can easily modify code element there. You can also define your custom stylesSet.

Related

How to create editable inline elements in CKEditor5 with actual nodes not text attributes

We work with a backend that tags words like Persons or locations. I send text to the backend and it tags me words. I have to create tags in the ckeditor frontend.
So I have the task to create editable inline elements, means they should be addable to where text is addable.
The tag must be editable.
The tag should also be visible if its empty (should be a own tree node not text attribute).
The tag should have visual highlighting, like a background-color and border radius.
If the tag is empty, its type should be added via css' ::before pseudo class and content property.
It would be nice if you can toggle it's edtiable part. Since we also need readonly tags, their are developed as seperate elements so far.
My approach so far was using text attributes applying:
writer.createText('my tag', {tag: tagType})
I was basically creating tags like you would create bold text. I was applying css styles like background-color and border radius to make it look like a tag, but this approach came to it's limits. Also with this approach you cannot have editable and non-editable tags be the same ckeditor entity, since you cannot have non-editable text, I guess.
Then I found editableElement's in the view side. The Problem is you cannot have emtpy tags since empty text is nothing. You also cannot modify the "tag" at index 0 because then you are outside of the tag, see bold behavior for this. I mean I could somehow fix it all, but I would like the tags to be their own element on model side. so I have tried this approach:
// in editingDowncast conversion:
viewWriter.createEditableElement('div', {class: 'inline'})
// this is the whole code in the ui:
this.editor.model.schema.register( 'test-tag', {
allowChildren: '$text',
allowWhere: '$text',
allowAttributesOf: '$text',
isObject: true
});
// if it is isInline: true it behaves mostly like my approach with text attributes
this.editor.conversion.for('editingDowncast').elementToElement({
model: 'test-tag',
view: (modelItem, conversionApi) => {
let { writer: viewWriter } = conversionApi;
const tagView = viewWriter.createEditableElement( 'div', {
class: 'inline'
});
return tagView;
}
})
basically EdtiableElement's work only with block elements, so I have tried to make them inline via css, setting their display property to inline-block. Here I have again the problem that when the element is empty you cannot access it anymore via cursor. So it will stay empty forever. Generelly it seems that it's behavior is kind of buggy because I guess you should not use it as inline. Basically I have many similiar issues like with the approach above.
I will keep implementing it with the first solution but I wanted to ask the community if there is any other way, maybe a less hacky way to create inline editable elements that are actual nodes in the model. Something like a span tag but on model side.
Any Ideas?

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

Can we use an icon in ACE editor's autocomplete

I know that I can add an autocomplete list in ACE editor as below
completions.push({ name:"testing1", value:"testing1", meta: "code1" });
completions.push({ name:"testing2", value:"testing2", meta: "code2" });
My requirement is to add an icon adjacent to "code1" in the autocomplete popup. I tried to use <img> in meta value but it didn't work. I saw the ace's source code but didn't see a way to implement it.
Has anyone done this before?
Update:
I did it myself and added details in the answer below
Using an <img> tag in the meta text won't work because it isn't interpreted as HTML.
If you can include additional information in your autocomplete objects, you could:
completions.push({ name:"testing1", value:"testing1", meta: "code1", icon: "code1.png" });
From there, you could find the code that creates the autocomplete popup and add a conditional if statement that optionally adds an <img> tag.
I found a way to do it through css.
Added className property to the completion object
completions.push({ name:"test", value:"test", meta: "test", className:"iconable"});
And added icon in css:
.ace_iconable:after
{
content: " \f14c"; /* in my case it is font-awesome icon*/
font-family: FontAwesome;
}
Ace.Tern extension supports using an iconClass property in autocomplete extension. See it on github
However this is not something currently in Ace editor. I would say if you need to support just static styles, using className property (see it on github) and using before pseudo class to load them. In my case I need to do some post processing of the items in autocomplete popups, hence I need to listen to the 'afterRender' events like this one so that I can dynamically inject my icons in it.

Need help to find id of a specific element (external) to override styling by CSS

I'm trying to modify (by CSS) the dark gray "Contact Us" button that's at the bottom right side of the following site: coloraddicted.com.
This is a button created by an external app, so the code is inaccessible. I only have the following (external) page to refer to for the possibility of finding the right id: https://icf.improvely.com/icf-button.js?v=1479350309&shop=coloraddicted-com.myshopify.com
How can I find the "id" of the specific element in order to apply the
"overriding" CSS to it?
BTW, I have already tried several versions of the id's I see on the above mentioned external page but still haven't found the right one.
I can't remember all of them, but some I have already tried are:
#icf_button
#icf.click_button
#icf_contact_form button {
#icf_contact_form add_button {
Style Contact button by css has no effect, because right after user hover, js code excuted & override on.
You can put js code at the end of the body, to re-override on the library code (not the good way, but have to), example
let contactButton = document.querySelector('#shop-colorful-products-printed-on-demand-just-for-you > div:nth-child(38)');
contactButton.style.backgroundColor = 'white';
Demo image https://tinker.press/images/change-style-by-js-to-override-2017-01-17_090946.png
If you can't modify the button.js script you linked to, I don't think you can target this (reliably) in CSS. They style everything with that button using inline styles and just append it to body.
You could potentially use :nth-of-type (like https://icf.improvely.com/icf-button.js?v=1479350309&shop=coloraddicted-com.myshopify.com) but that would be super unreliable as I'm assuming you have a bunch of scripts and stuff on the site that dynamically append to the page, creating a variable number of divs as direct descendants of body. FWIW, nth-of-type(13) worked for me.
The element doesn't have an id, so you can't select it that way. But the site appears to be using jQuery, so you could try using :contains() to target the element based on its contents:
$( "div:contains('Contact Us')" ).css( "font-size", "2em" );
But that would target any div containing the text "Contact Us". You can use :filter to select divs that contain only the text "Contact Us":
$("div").filter(function() {
return $.trim($(this).text()) === "Contact Us";
}).css("font-size", "2em");
You could use jQuery to either apply CSS directly, or to give the element an id. This solution is kind of kludgy, but might work in a pinch.

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.

Categories