CKeditor copy inline widget from editable widget (Firefox) - javascript

I am facing a problem in CKeditor (4.8.0) copy/paste on firefox for inline widget inside editable widget. Here is my fiddle
I want to copy both text and inline widget from the editable part of another widget :
But when i am pasting it only the start of the text is copied until the widget start :
This is working on Chrome
Html :
<textarea id="editor">foo bar
<div class='mywidget'>
<div>Header</div>
<div class='mywidget_contents'>
<p>test copy <span class="cke_placeholder">[[it]]</span> please<br></p>
</div>
</div>
</textarea>
Javascript :
CKEDITOR.plugins.add( 'mywidget', {
requires: 'widget',
icons: 'mywidget',
init: function( editor ) {
editor.widgets.add( 'mywidget', {
button: "My Widget",
template:"<div class='mywidget'><div>Header</div><div class='mywidget_contents'></div></div>",
editables: {
content: {
selector: '.mywidget_contents'
}
},
upcast: function (element) {
return element.hasClass('mywidget');
}
} );
}
} );
CKEDITOR.replace( 'editor', {
extraPlugins: 'mywidget,placeholder'
} );
Did someone find a workaround for this ?

Related

how to remove the html content in vue2editor

We a create a html content using Vue Editor and save the data and close the dialog after saving . how do we remove the html content in the editor after the dialog box is closed
Using this editor for writing a html document in Vuejs --
import { VueEditor } from 'vue2-editor'
You just need to reset data property which has been passed to "v-model" attribute, something like that:
<template>
<vue-editor v-model="content" />
</template>
<script>
export default {
data() {
return {
content: '<p>Sample</p>',
};
},
methods: {
save() {
// Closing dialog code
this.content = null; // or this.content = ''
},
},
};
</script>

Custom tag implementation with tagify tags

It's my code here
tagifyInput = document.querySelector('input[name=tags]'),
tagify = new Tagify(tagifyInput, {
enforceWhitelist: true,
whitelist: selected,
template:{
tag: function (v) {
return `<tag title='${v}' contenteditable='false' spellcheck="false">
<x title='remove tag' class='tagify__tag__removeBtn'></x>
<div>
<span class='tagify__tag-text'>${v}</span>
</div>
</tag>`;
}
}
});
I am giving this template here also to tagify, but it's not working what could be the issue ?

insertText() in ckeditor component for Vue.js

I am trying to integrate ckeditor 5 in my vue js app.I have successfully added ckeditor but now i want to add some text at the cursor position in ckeditor on click of a button. So to achieve that i tried insertText method. But i am not able to get the editor instance in vue while adding the code as editor.model.change(...)
Uncaught ReferenceError: editor is not defined
Code =>
<template>
<ckeditor
id="custom"
ref="custom"
name="custom"
:editor="editor"
:config="editorCustomConfig"
v-model="message">
</ckeditor>
Add Text In Editor
</template>
<script>
import ClassicEditor from "#ckeditor/ckeditor5-build-classic";
export default {
name: "topbar",
},
data() {
return {
editor: ClassicEditor,
editorConfig: {
},
message:''
};
},
methods: {
addCodeInMsg(e){
editor.change( writer => {
const insertPosition = editor.model.document.selection.getFirstPosition();
writer.insertText( 'CKEditor 5 rocks!', { linkHref: 'https://ckeditor.com/' }, insertPosition );
} );
}
}
</script>
I don't know what i am missing while using the ckeditor component.Any helps would be appreciated.
I ran into the same issue with Vue3 and CKEditor 5. Here is what I did for anyone that stumbles across this and still needs an answer.
Reference: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/architecture/editing-engine.html#model
Setup the editor:
<ckeditor id="templateEditor" :editor="editor" v-model="myModel.myProperty" #ready="onReady"></ckeditor>
In my case, I have a list of li tags and clicking on each would add some text to the editor.
<li><span class="clickable emailToken" #click="appendToken('{year}')">{year}</span> - current year</li>
Then add this block of code to your component code (I'm using TypeScript and the ClassicEditor - you should be able to replace ClassicEditor with the name of whichever editor you're using):
let editor = {} as ClassicEditor;
function onReady(useEditor: ClassicEditor) {
editor = useEditor;
}
function appendToken(token) {
editor.model.change(writer => {
writer.insertText(token, editor.model.document.selection.getFirstPosition());
});
editor.focus();
}
The ckeditor ready event passes the editor instance to the onReady function and stores that ready instance in editor. The appendToken function then uses that captured editor to make changes to the model.
forgot about this:
methods: {
addCodeInMsg(e){
this.editor.change( writer => {
const insertPosition = this.editor.model.document.selection.getFirstPosition();
writer.insertText( 'CKEditor 5 rocks!', { linkHref: 'https://ckeditor.com/' }, insertPosition );
} );
}
}
I was able to do this through the editor-object you get when the CKeditor is ready.
In the on-ready-event, you get a editor and then I save that one for using such actions.
source: https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/vuejs.html#using-the-document-editor-build

Create non editable block with text in CKEditor 5

How do I Create a non editable block with text in CKEditor 5.
I need something which in the final view generate a:
<div>Non editable message here</div>
I tried to use a UIElement and then set innerHTML but that still makes the element editable.
Just for reference: Her is the plugin I ended up using.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import DecoupledEditor from '#ckeditor/ckeditor5-editor-decoupled/src/decouplededitor';
import Essentials from '#ckeditor/ckeditor5-essentials/src/essentials';
import Paragraph from '#ckeditor/ckeditor5-paragraph/src/paragraph';
import Bold from '#ckeditor/ckeditor5-basic-styles/src/bold';
import Heading from '#ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '#ckeditor/ckeditor5-basic-styles/src/italic';
import ButtonView from '#ckeditor/ckeditor5-ui/src/button/buttonview';
import imageIcon from '#ckeditor/ckeditor5-core/theme/icons/image.svg';
import Command from '#ckeditor/ckeditor5-core/src/command';
import { downcastElementToElement,downcastAttributeToAttribute,downcastAttributeToElement } from '#ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
import { upcastElementToElement, upcastAttributeToAttribute,modelToViewAttributeConverter} from '#ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
import attachPlaceholder from "#ckeditor/ckeditor5-engine/src/view/placeholder";
import ViewPosition from '#ckeditor/ckeditor5-engine/src/view/position';
import toWidgetEditable from '#ckeditor/ckeditor5-widget/src/utils';
import ClickObserver from '#ckeditor/ckeditor5-engine/src/view/observer/clickobserver';
import UpcastDispatcher from '#ckeditor/ckeditor5-engine/src/conversion/upcastdispatcher';
import { toWidget } from '#ckeditor/ckeditor5-widget/src/utils';
export default class TestWidget2 extends Plugin {
static get pluginName() {
return 'TestWidget2';
}
init() {
console.log('TestWidget2::init()');
const editor=this.editor;
const model=editor.model;
model.schema.register( 'myWidget', {
inheritAllFrom: '$block',
isObject: true
} );
editor.conversion.for( 'dataDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const elm=writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'editingDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const div = writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'upcast' )
.add( upcastElementToElement( {
view: {
name: 'div',
class: 'widget'
},
model: 'myWidget'
} ) );
}
}
You can create the widget API for that:
import Widget from '#ckeditor/ckeditor5-widget/src/widget';
import { toWidget } from '#ckeditor/ckeditor5-widget/src/utils';
import { downcastElementToElement } from '#ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
import { upcastElementToElement } from '#ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Essentials, Paragraph, Widget, /* ... other plugins ... */ ],
toolbar: [ 'undo', 'redo' ]
} )
.then( editor => {
window.editor = editor;
const model = editor.model;
model.schema.register( 'myWidget', {
inheritAllFrom: '$block',
isObject: true
} );
editor.conversion.for( 'dataDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
return writer.createContainerElement( 'div', { class: 'widget' } );
}
} ) );
editor.conversion.for( 'editingDowncast' )
.add( downcastElementToElement( {
model: 'myWidget',
view: ( modelItem, writer ) => {
const div = writer.createContainerElement( 'div', { class: 'widget' } );
return toWidget( div, writer, { label: 'widget label' } );
}
} ) );
editor.conversion.for( 'upcast' )
.add( upcastElementToElement( {
view: {
name: 'div',
class: 'widget'
},
model: 'myWidget'
} ) );
editor.setData(
'<p>foobar</p>' +
'<div class="widget">Non editable text goes here</div>' +
'<p>foobar</p>'
);
} )
.catch( err => {
console.error( err.stack );
} );
The key point is to use the toWidget() function when downcasting an element to the editing view. Also, that element should be marked as an object in the schema.
Also don't forget to load the Widget plugin which turns on the support for widgets.
I just had the problem yesterday that when having a html table inside the isObject widget content, the table was still editable and also had controls.
The only way to fix it was to disable interaction inside my widget via css.
.ck-widget.my-wdiget *:not(.ck.ck-reset_all.ck-widget__type-around) {
pointer-events: none;
}
.ck.ck-reset_all.ck-widget__type-around is the class of the widget controls to add a linebreak before or after the widget. They are still usable.
I followed your steps without success..
For better knowledge (this guideline it's tested only in custom build for angular application but i think thats work everywhere)
probably you need use this command for follow correctly this guideline
npm install -g webpack
and in add to this you need install globally another dependency but i don't remember what is! (you can easly search the error on google for find it)
Create your custom build here
unzip, open folder and run npm install
install widget(with type def. if necessary) and core dependencies
npm i --save -D #ckeditor/ckeditor5-widget
npm i --save -D #types/ckeditor__ckeditor5-widget
npm i --save -D #ckeditor/ckeditor5-core
go into path src/ckeditor.js and add the following code for create the reinmar custom plugin
import {toWidget, Widget} from "#ckeditor/ckeditor5-widget";
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
class NotEditable extends Plugin {
init() {
const editor = this.editor;
const model = editor.model;
model.schema.register('myWidget', {
inheritAllFrom: '$block',
isObject: true
});
editor.conversion.for('dataDowncast')
.elementToElement({
model: 'myWidget',
view: (modelItem, writer) => {
return writer.writer.createContainerElement('div', {class: 'widget'});
}
});
editor.conversion.for('editingDowncast')
.elementToElement({
model: 'myWidget',
view: (modelItem, writer) => {
const div = writer.writer.createContainerElement('div', {class: 'widget'});
return toWidget(div, writer.writer, {label: 'widget label'});
}
});
editor.conversion.for('upcast')
.elementToElement({
view: {name: 'div', class: 'widget'},
model: 'myWidget'
});
}
}
and in Editor.builtinPlugins add Widget and NotEditable
Editor.builtinPlugins = [
//***other plugin,
Widget,
NotEditable
];
exec in the terminal npm run build
copy the build folder into your project and import the build (follow official Ckeditor5 guideline for this) {in my case i follow this guideline in angular guide}
According to the documentation isReadOnly : Boolean
Set it to true.
Official Documentation

How to customize ckeditor toolbar button behavior?

In ckeditor 4.0.1 in when "text direction from left to right" toolbar button is pushed, i type hello, the generated HTML source is:
<p dir="ltr">hello</p>
how can i change this behavior so that the generated source is look like:
<p dir="ltr" style="text-align: left;">hello</p>
Thanks in advance.
You can do this with dataProcessor:
CKEDITOR.replace( 'editor1', {
on: {
instanceReady: function () {
this.dataProcessor.htmlFilter.addRules( {
elements: {
p: function( element ) {
if ( element.attributes.dir == 'ltr' )
element.attributes.style = 'text-align: left;';
}
}
});
}
}
} );
You can also add it globally:
CKEDITOR.on( 'instanceReady', function ( event ) {
event.editor.dataProcessor.htmlFilter.addRules( {
elements: {
p: function( element ) {
if ( element.attributes.dir == 'ltr' )
element.attributes.style = 'text-align: left;';
}
}
});
} );

Categories

Resources