I'm facing a problem with CKeditor (V4.17.0). I'm using it in a Symfony (V5) project. I installed the WYSIWYG with this doc. Then I downloaded the Non-breaking space plugin, I placed it in the path public/bundles/fosckeditor/plugins and I configured my yaml file:
twig:
form_themes:
- '#FOSCKEditor/Form/ckeditor_widget.html.twig'
fos_ck_editor:
default_config: config
configs:
config:
allowedContent: true
extraPlugins: 'nbsp'
removePlugins: 'elementspath,exportpdf,image,media, about'
toolbar:
- { name: "styles", items: [ 'Bold', 'Italic', 'Strike' ] }
- { name: "plugins", items: ['insertNbsp'] }
- { name: "paragraph", items: ['NumberedList'] }
plugins:
nbsp:
path: 'ckeditor/plugins/nbsp/'
filename: 'plugin.js'
My webpack.config.js :
.copyFiles([
{
from: './assets/images',
to: 'images/[path][name].[ext]',
},
{
from: './node_modules/ckeditor4/',
to: 'ckeditor/[path][name].[ext]',
pattern: /\.(js|css)$/,
includeSubdirectories: false,
},
{
from: './node_modules/ckeditor4/adapters',
to: 'ckeditor/adapters/[path][name].[ext]'
},
{
from: './node_modules/ckeditor4/lang',
to: 'ckeditor/lang/[path][name].[ext]'
},
{
from: './node_modules/ckeditor4/skins',
to: 'ckeditor/skins/[path][name].[ext]'
},
{
from: './node_modules/ckeditor4/vendor',
to: 'ckeditor/vendor/[path][name].[ext]'
},
{
from: './public/bundles/fosckeditor/plugins',
to: 'ckeditor/plugins/[path][name].[ext]'
},
])
The editor appear on the page, in my toolbar I've got everything I asked except the Non-breaking space plugin.
How can I insert into it ?
I don't think this plugin is used that way. You can't, if I'm not mistaken, load that into the toolbar.
Would it be possible for you to use this source code instead of the original plugin.js
CKEDITOR.plugins.add( 'nbsp',
{
init : function( editor )
{
editor.ui.addButton('Insert  ', {
label: 'Insert ',
command: 'insertNbsp',
toolbar: 'insert',
icon: this.path + 'icons/icon.png'
});
// Insert if Ctrl+Space is pressed:
editor.addCommand( 'insertNbsp', {
exec: function( editor ) {
editor.insertHtml( ' ', 'text' );
}
});
editor.setKeystroke( CKEDITOR.CTRL + 32 /* space */, 'insertNbsp' );
}
} );
think about creating an icons folder as well as an icon of your choice to see a button in your toolbar.
Related
I'm using CKEditor Version 4.5 and the issue is only with IE (using v.11).
The CKEditor is implemented in a JSF Dialog (Richfaces), and everytime I click a drop down it shows for about 0.5 sec and then it disappears. The console dosen't show any errors.
First I thought mabye the dialog loses it's focus but I've allready tried to set the focus after click on the editor back to the dialog, but that did not resolve the problem. Any suggests what the problem could be?
EDIT
<div class="editor-container">
<rich:editor id="editor" value="#{bean.editor}">
<f:facet name="config">
toolbar: 'custom',
startupFocus: true,
toolbar_custom:
[
{ name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
'/',
{ name: 'styles', items : [ 'Styles','Format' ] },
{ name: 'basicstyles', items : [ 'Bold','Italic','Strike','-','RemoveFormat' ] },
{ name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote' ] },
{ name: 'tools', items : [ 'Maximize' ] }
]
</f:facet>
</rich:editor>
</div>
Only happens inside twitter-bootstrap modal.
Solution: If the font, size dropdowns are not working in IE, please copy the code below.
$.fn.modal.Constructor.prototype.enforceFocus = function()
{
modal_this = this
$(document).on('focusin.modal', function (e)
{
if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length
&& $(e.target.parentNode).hasClass('cke_contents cke_reset'))
{
modal_this.$element.focus()
}
})
};
I am tasked with fixing a problem with my company's CMS. We use CKEditor. When users cut from microsoft word and paste into the editor, tags are removed. This was done intentionally by someone who no longer works at the company, and now we want to allow a tags.
I am able to find the editor by going into the javascript console. When I inspect the object, I find that editor.config.allowedContent is set to "p[*](*){*}; h1[*](*){*}; h2[*](*){*}; em; b; u; ul[*](*){*}; ol[*](*){*}; li[*](*){*}; img[*](*){*}; iframe[*](*){*}; a[*](*){*}; object[*](*){*}; param[*](*){*}; embed[*](*){*}; video[*](*){*}; i; table[*](*){*}; tr[*](*){*}; td[*](*){*}; script[*](*){*}; h3[*](*){*}; span[*](*){*}; br[*](*){*}; div[*](*){*}; strong; blockquote[*](*){*} which contains an a tag.
What other possible causes could their be for the link tags being stripped on copy + paste?
Thanks!
Edit:
Here is config.js:
CKEDITOR.editorConfig = function( config ) {
config.toolbarGroups = [
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
config.removeButtons = 'Underline,Subscript,Superscript';
config.format_tags = 'p;h1;h2;h3;pre';
config.removeDialogTabs = 'image:advanced;link:advanced';
config.fillEmptyBlocks = false;
config.baseFloatZIndex = 100001;
config.extraAllowedContent = 'a';
};
CKEDITOR.config.fillEmptyBlocks = false;
Furthermore it seems some config options are set dynamically:
this.editorObject = CKEDITOR.inline(this.$editable[0],{
forcePasteAsPlainText: true,
title: this.label,
customConfig: '',
removePlugins: 'autocorrect,format,stylescombo',
removeButtons: 'PasteText,Flash,Anchor,ShowBlocks,About',
extraPlugins: extraPlugins,
linkShowAdvancedTab: false,
linkShowTargetTab: true,
youtube_responsive: true,
youtube_related: false,
scayt_autoStartup: true,
readOnly: this.disabled,
floatSpacePinnedOffsetY: 100,
floatSpaceDockedOffsetY: 25,
toolbar: this.toolbarDefinitions[this.variant],
allowedContent: allowedContent,
blockedKeystrokes: blockedKeystrokes,
keystrokes: keystrokes,
on: {
instanceReady: _.bind(function(e) {
if (this.fieldname == 'inc_clean_text' && this.area) {
this.area.generateInlineVideoPlayers();
var area = this.area;
async.nextTick(function() {
_.each(area.inlineVideoPlayers, function(player) {
player.menu && player.menu.show();
});
});
}
this.$editable.focus();
// When triggerred will focus on the editor.
this.$editable.on('focusCursor', (function() {
var range = this.editorObject.createRange();
range.moveToElementEditablePosition(this.editorObject.editable(), true);
this.editorObject.getSelection().selectRanges([range]);
}).bind(this));
if (this.editorObject.document.$.getElementById('caret-position-placeholder')) {
// When there is a caret placeholer present will put the cursor there and
// remove the placeholder element.
var node = new CKEDITOR.dom.element(this.editorObject.document.$.getElementById('caret-position-placeholder'));
var range = new CKEDITOR.dom.range(this.editorObject.document);
range.selectNodeContents(node);
this.editorObject.getSelection().selectRanges([range]);
$(this.editorObject.document.$.getElementById('caret-position-placeholder')).remove();
}
if (this.$editable.hasClass('pancaption_override')) {
// ! TODO Move elsewhere.
// Code specific to the main feature image caption editor.
if (this.$editable.data('reshow')) {
this.$editable.data('reshow', false);
$('.pancaption_default').hide();
this.$editable.attr('contenteditable', true);
this.$editable.show().focus().trigger('click');
this.editorObject.setReadOnly(this.disabled);
}
if (this.$editable.html() == '') this.$editable.trigger('focusCursor');
}
// When on the new article page and clicking on a field with default text then empty
// the editable text.
//this.editorObject.setData('');
//this.$editable.trigger('focusCursor');
//this.$editable.toggleClass('empty', true);
}, this),
change: _.bind(this.contentChanged, this)
}
});
Let me know if I should trace any of these variables.
Controlling which tags are allowed or disallowed is done through the config.js file usually located in the root of the CKEditor directory. http://docs.ckeditor.com/#!/guide/dev_configuration
As you've discovered through the console you can either allow or disallow certain tags through config.allowContent or config.disallowedContent respectively. http://docs.ckeditor.com/#!/guide/dev_acf
I'm using QuillJs as a text editor on my website. In a long post the screen view jumps to top when pasting text or changing heading type or alignment or color or inserting a link or video. Can't find out why.
QuillJs version: 1.2.6
Browser: Chrome 58.0.3029.110
OS: Windows 10
Initialization:
var toolbarOptions = [
[{ 'header': [1, 2, 3, 4, 5, 6, false] },
'bold', 'italic', 'underline', 'strike', { 'align': [] },
{ 'list': 'ordered' }, { 'list': 'bullet' },
{ 'color': [] }, { 'background': [] }],
['image', 'blockquote', 'code-block', 'link', 'video'],
['clean']
];
var quill = new Quill('#editor', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
This happens when any option is clicked from the quill toolbar. I had similar issue and I was using react-quill 0.4.1.
Try using event.preventDefault and event.stopPropagation on quill toolbar to fix this.
The following fixed the issue for me.
componentDidMount()
{
$('.quill-toolbar').on("mousedown", function(event){
event.preventDefault();
event.stopPropagation();
});
}
If you want an editor to be scrolled and maintained by a web page's main scrollbar, you need to set scrollingContainer property to 'body' during configuration of Quill object.
var quill = new Quill('#editor', {
modules: { toolbar: toolbarOptions },
theme: 'snow',
scrollingContainer: 'body'
});
Setting scrollingContainer to html was the only solution that worked for me:
var quill = new Quill('#editor', {
modules: { toolbar: toolbarOptions },
theme: 'snow',
scrollingContainer: 'html'
});
this is happening because of these two lines:
https://github.com/quilljs/quill/blob/5715499c57091db262c176985f6c5370d73db5dd/modules/toolbar.js#L86
and
https://github.com/quilljs/quill/blob/5b28603337f3a7a2b651f94cffc9754b61eaeec7/core/quill.js#L171
this.scrollingContainer => could be not an actual scrolling element.
The fix could be is to assign the nearest scrolling element directly.
If you are not sure what it is you can use this snippet to find it:
const regex = /(scroll)/;
const style = (node, prop) => window.getComputedStyle(node, null).getPropertyValue(prop);
const scroll = (node) => regex.test( style(node, "overflow") + style(node, "overflow-y") + style(node, "overflow-x"));
export const scrollparent = (node) => {
return !node || node===document.body ? document.body : scroll(node) ? node : scrollparent(node.parentNode);
};
editor.scrollingContainer = scrollparent(editor.container);
i have uploaded codesnippet plugin inside /ckeditor/plugins/ directory.
My config.js file codes are:
CKEDITOR.editorConfig = function( config ) {
config.toolbar = [
{ name: 'basic', items: [ 'Bold', 'Italic', 'Underline' ] },
{ name: 'font', items: [ 'Font' ] },
{ name: 'paragraph', items: [ 'NumberedList', 'BulletedList', 'Blockquote' ] },
{ name: 'links', items: [ 'Link', 'Unlink' ] },
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule' ] },
{ name: 'last', items: [ 'Maximize' ] }
];
config.extraPlugins = 'codesnippet';
config.format_tags = 'p;h1;h2;h3;pre';
config.entities = false;
config.removeDialogTabs = 'image:advanced;link:advanced;table:advanced';
config.disableNativeSpellChecker = false;
};
But when i add config.extraPlugins = 'codesnippet'; line then editor do not work even i can't see textarea field.
And when i remove config.extraPlugins = 'codesnippet'; line then editor works perfectly.
Use the online builder to add the codesnippet plugin to your editor. Most probably your editor is missing dependencies.
Most plugins in CKEditor require some additional plugins to operate. If you download manually plugin A, there is a chance that you need to download dependencies for plugin A... and plugin B, which is required by plugin A. And sometimes you will need to download dependencies for plugin C, which was required by plugin B. Sounds like a nightmare, this is why we created online builder and why package managers exist.
I have a an ExtJS app that uses xtype menu to create a dropdown menu with two options. One of those options, on mouseover, brings up two additional sub options. When attempting to mouseover one of the sub options, the menu immediately times out and disappears.
This only happens in Chrome. Safari is fine. Also if I use the keyboard arrows to make the selection it works fine.
Ext.define('App.view.deposit.ReportButton', {
extend: 'Ext.button.Button',
alias: 'widget.depositreporbutton',
requires: [
'Ext.menu.Menu',
'Ext.menu.Separator'
],
text: 'Reports',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
menu: {
xtype: 'menu',
minWidth: 200,
items: [
{
text: 'Deposit Report',
menu: {
items: [
{
xtype: 'menuitem',
itemId: 'deposit-report-media-button',
text: 'By Media Type'
},
{
xtype: 'menuitem',
itemId: 'deposit-report-fund-button',
text: 'By Income Fund'
}
]
}
},
{
xtype: 'menuitem',
itemId: 'receipt-report-button',
text: 'Contribution Receipts'
}
]
}
});
me.callParent(arguments);
}
});
If you're using extjs 4.x there is an issue with the Chrome 43 updates and the 4.x series.
Here's the bug thread: https://www.sencha.com/forum/showthread.php?301116-Submenus-disappear-in-Chrome-43-beta
Here is an announcement with a fix here: https://www.sencha.com/forum/announcement.php?a=58
Here's the official fix:
Ext.define('Override.menu.Menu', {
override: 'Ext.menu.Menu',
compatibility : '4',
onMouseLeave: function(e) {
var me = this;
// If the mouseleave was into the active submenu, do not dismiss
if (me.activeChild) {
if (e.within(me.activeChild.el, true)) {
return;
}
}
me.deactivateActiveItem();
if (me.disabled) {
return;
}
me.fireEvent('mouseleave', me, e);
}
});
You can try it out here: https://fiddle.sencha.com/#fiddle/ndn
To use the override in your application:
Put the override file in the overrides directory off the root folder
Add this to the app.js file:
Ext.Loader.setConfig({
paths: {
'Overrides': 'overrides'
}
});
Add the requires statement in the Application.js file under the Ext.Define section:
Ext.define('Your.Application', {
name: 'App',
extend: 'Ext.app.Application',
...
requires: [
'overrides.Menu'
]
});