How to apply formatting to content of a span - ckeditor

With CkEditor, When I create an A tag and later apply some custom formatting (like color text for instance), the resulting source looks like this:
<p><span style="color:#1abc9c;">some text</span></p>
As you can see, the formatting is around the text but INSIDE the A tag.
I have a personal plugin that outputs a SPAN tag with a specific class. In the wysiwyg editor, when I select the text and apply the same formatting, I get this:
<p><span style="color:#1abc9c;"><span class="command3d">Some text</span></span></p>
This time, the formatting is not simply around the text. It is applied around the SPAN tag.
How can I control this behaviour? I would like to get this result instead:
<p><span class="command3d"><span style="color:#1abc9c;">Some text</span></span></p>
Thanks

Unfortunately there is no ability to control the order of inline styles (based on span tags) inside editor's instance. The only sensible way to achieve desired result is to start with applying text color and then apply your custom style.
However there are two methods to convert output of the editor to the correct format. The first is to add custom handler to editor's data processor via toDataFormat event to check ancestors of span.command3d and swap them in places if necessary. However it's a little bit troublesome as you must traverse through all content, therefore it's easier way: add element callback to editor's filter. Example.

Related

How do I tell CKEditor 5 to use inline styling on the elements which it creates instead of them being class-based?

I'm using CKEditor 5 on my website in order to allow users to generate PDF templates for their company.
My issues is, that once I take the data out of the ckEditor, every styled element has a class="CSS-Class-Here", which is problematic due to the fact that when I convert the HTML contents of the CKEditor to PDF, the PDF doesnt know any of these classes.
Is there any way to get CKEditor to save these classes as inline styles?
I know that its possible to create a plugin for a specific element for a specific style, but I want everything to act this way, not something specific.
Also, It's impossible to just inject the styles into the PDF itself, due to the fact that ckEditor keeps their styles in javascript functions and creates them on demand.
For example:
Yellow highlighted text comes out as:
<mark class="" marker-yellow "">Random Text</mark>
I would like it to come out as:
<mark style="background: yellow">Random Text</mark>
Meaning that the style that's present in the marker-yellow class should be applied inline directly to the element itself.

Dynamically change caption field (or just title in tabs macro) in TiddlyWiki

I'm putting together some TiddlyWiki templates, and I've run into something that would be nice to have, but I'm not sure whether it's actually possible.
I have some tiddlers that I'm including in another tiddler using the tabs macro. Each tiddler has one of two tags associated with it. I'd like to append a snippet of text to the caption in the tab view, based on which tag is associated.
I don't have a strong preference for whether this is done by adding some kind of callback to edit the caption on save, something that somehow calculates the desired caption on the fly, altering the invocation of the tabs macro to recalculate the caption on render, or somehow causing the templates to calculate the caption field.
I haven't found anything promising going through the documentation, but maybe I just haven't figured out what's relevant to my issue. I find that happens a lot.
Like, I'm sure I can write conditionals based on whether the tags exist, but I can't see any way to interpolate text into the caption field based on any kind of computation whatsoever.
For reference, here are my current macro invocations:
<<tabs [list[]] state:$:/state/tabPeriod template:PeriodTemplate>>
<<tabs [list[$(currentTab)$]] state:$:/state/tabEvent class:"tc-vertical" template:"EventTemplate">>
<<tabs [list[$(currentTab)$]] state:$:/state/tabScene template:"SceneTemplate">>
All of these lines are from different templates, that just pull a list of tiddlers and template-transclude them into tabs using the provided template. Currently, the tabs are captioned with the tiddler caption, if defined, and fall back to the title. I'd like to alter the caption, ideally without inserting too much boilerplate into the tiddlers.
I figured out what I need to do differently: I defined a custom macro based on the tabs macro, added the logic, and now it works fine. I basically just changed the current contents of the caption logic to:
<$set name="tv-wikilinks" value="no">
<$transclude tiddler=<<currentTab>> field="caption">
<$macrocall $name="currentTab" $type="text/plain" $output="text/plain"/>
</$transclude>
<$list filter='[<currentTab>tag[light]]'>
○
</$list>
<$list filter='[<currentTab>tag[dark]]'>
●
</$list>
</$set>
I'm not sure if I'm using the list widget correctly, but it works.

CKEditor: Paste into editable field in widget

I have a CKEditor widget resembling a tab-module.
As editables I have defined a span.title and div.content.
When I am in editing mode inside a span.title and then paste something using CTRL+V, the span gets broken and I have two spans. As if it gets divided on whatever position I paste.
When I am in editing mode inside a div.content and then paste something using CTRL+V, the contents of the clipboard are correctly inserted into that div.
Is it because span is an inline-element and div is a block-element and CKEditor doesnt allow pasting into inline-elements?
Can I somehow change this behaviour?
CKEditor allows pasting of block and inline elements (keep in mind that content filtering (ACF) can be used which also affects pasting) so it is probably not the issue in this case.
I would also make sure that the content which you are trying to paste does not contain any HTML which may cause the behavior you described.
If you could provide widget HTML/template or code which you are using I will be glad to investigate this issue in more depth.
I had this issue when trying to have a <cite> element as an editable. Trick was to tweak the CKEDITOR.dtd properties.
// This prevents the pasting from splitting parent element.
delete CKEDITOR.dtd.$removeEmpty.cite;
// This tells the editor to allow editing in this element.
CKEDITOR.dtd.$editable.cite = 1;
I imagine this would affect the behavior of all <cite> elements in any editor currently loaded. Not ideal in all cases for most elements, but for our requirements for a blockquote/pullquote widget, the <cite> element is only allowed inside our <blockquote> elements in any editor.

CKEDITOR How to find and wrap text in span

I am writing a CKEDITOR plugin that needs to wrap certain pieces of text in a tag. From a webservice, I have an array of items that need to be wrapped. The array is just the plain text strings. Such as:
"[best buy", "horrible migraine", "eat cake"]
I need to find the instances of this text in the editor and wrap them in a span tag.
This is further complicated because the text may be marked up. So the HTML for "best buy" might be
"<strong>best</strong> buy"
but the text returned from the web service is stripped of any markup.
I started trying to use a CKEDITOR.htmlParser() object, and that seems like it is moderately successful. I am able to catch the parser.onText event and check if the text contains anything in my array.
But then I cannot modify that text. Modifications are not persisted back to the source html. So I think using the htmlParser() is a dead-end.
What is the best way to accomplish this task?
Oh, and as a bonus, I also do not want to lose my user's current cursor position when the changes are displayed.
Here is what I wound up doing and it seems to be working so far.
I created a text filter rule that searches through my array of items for any item that is contained (or partially contained) in the text. If so, it wraps the element in my span.
A drawback here is that I wind up with two spans for items with markup. But in my usecase, this is tolerable.
Then I set the results using:
editor.document.getBody().setHtml(results);
Because of this, I also have to strip this markup back out when this text gets read. I do this using an elements filter on editor.dataProcessor.htmlFilter.
This seems to be working well for my (so far limited) test cases.

working with xml snippets in CKEditor

I am Using CKEditor in my application where the users can write blogs, create pages etc..,
Source mode is disabled for the editor. Writing xml in the editor's text area is not retained after saving the content. I clearly see that the content got HTML Encoded and the same is supplied as input to the CKEditor's textarea.
Works as designed. Whatever you enter into the WYSIWYG area, will get HTML encoded. How would you want to behave it differently?
If you want a text editor for writing XML, maybe the answers to this question are useful: Textarea that can do syntax highlighting on the fly?
I too want CKEditor to support XML tags, but I understand that you can't just type them into the main window - anything typed here is assumed to be actual content, not tagging, and therefore gets encoded.
What I'd like to do is define a list of styles that cause a tag of my choosing to be used, e.g. if the user chooses the 'example' style, CKEDitor does <x>content</x>. Unfortunately I haven't had much success with this, despite hacking the dtd.js file.
My current solution is to define a list of styles but map them to a standard HTML tag, then put my desired XML tag name in as an attribute. I'll then need to write some XSLT that transforms the data later.
CKEDITOR.stylesSet.add('myStyles',
[{
name: 'Example sentence',
element: 'span',
attributes: {'class': 'example', 'data-xmlTag': 'x'}
}];
config.stylesSet = 'myStyles';
element specifies a standard HTML tag – I use <span> if I want the XML to be inline and <div> if I want it to be block level. The data-xmlTag attribute says what XML tag I actually wanted to use (x in this case). The class allows me to define some styles in CSS and means I can group several XML tags under one class name. To define some CSS:
config.contentsCss = CKEDITOR.basePath+'tagStyles.css';

Resources