You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to use mentions in the editor but somehow it is not working and throwing error.
Uncaught Error: [CKEDITOR.resourceManager.load] Resource name "{class:'mention'" was not found at "https://cdn.ckeditor.com/4.21.0/standard-all/plugins/{class:'mention'/plugin.js?t=N2M9".
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.resourceManager.<anonymous> (cke
Here is my code
'grapesjs-plugin-ckeditor': {
options: {
versionCheck: false,
extraPlugins: [ MyCustomUploadAdapterPlugin, MentionLinks, 'WordCount'],
toolbar: [
'heading',
'|',
'bold',
'italic',
'underline',
'link',
'bulletedList',
'numberedList',
'|',
'findAndReplace',
'outdent',
'indent',
'alignment',
'|',
'imageUpload',
'imageInsert',
'blockQuote',
'insertTable',
'mediaEmbed',
'undo',
'redo',
'-',
'fontFamily',
'fontBackgroundColor',
'fontColor',
'fontSize',
'removeFormat',
'horizontalLine',
'|',
'sourceEditing'
],
language: 'en',
wordCount: {
showParagraphs: false,
showWordCount: false,
displayWords: false,
showCharCount: true,
countSpacesAsChars: true,
countHTML: false,
maxWordCount: -1,
maxCharCount: 10,
onUpdate: stats => {
var maxCharacters = 750;
var isLimitExceeded = stats.characters > maxCharacters;
var charCount = '';
var exc
if ( isLimitExceeded ) {
charCount = `<span class="text-danger"> <b>${maxCharacters}</b> characters allowed. Content exceeded by <b>${ stats.characters - maxCharacters }</b> characters.</span>
<br><span class="text-danger charCountFlag" data-charcount=false></span>`;
} else {
charCount = `<span class="charCountFlag" data-charcount=true>Characters: <b>${ stats.characters }</b> of <b>${ maxCharacters }</b></span>`;
$("#mandatoryError").remove();
}
$( `${this.jQuerySelector}-word-count` ).html(`${ charCount }`);
}
},
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:inline',
'imageStyle:block',
'imageStyle:full',
'imageStyle:alignLeft',
'imageStyle:alignRight',
],
resizeUnit: 'px'
},
mediaEmbed: {
extraProviders: [
{
name: 'xyz',
url: /^edms\.xyz\.(\w+)\.com\/documents\/documents\/(\d+)\/download/,
html: match => {
var rawUrl = match[0];
return (`
<video class="" controls="" src="https://${ rawUrl }" preload="metadata" style="height: 100%; width: 100%;" title="">
</video>
`);
}
}
],
previewsInData: true
},
alignment: {
options: ['left', 'right', 'center', 'justify']
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells',
'tableCellProperties',
'tableProperties'
]
},
licenseKey: '',
mention: {
dropdownLimit: 500,
feeds: [
// {
// marker: '@',
// feed: getFeedItems,
// minimumCharacters: 1
// },
{
marker: '@',
feed: getNodeItems,
minimumCharacters: 1,
itemRenderer: customItemRenderer,
}
]
}
},
},
'grapesjs-plugin-dynamic-columns': {}
},
});
// COPIED from https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html
class MyUploadAdapter {
constructor( loader ) {
// The file loader instance to use during the upload.
this.loader = loader;
}
// Starts the upload process.
upload() {
return this.loader.file
.then( file => new Promise( ( resolve, reject ) => {
this._initRequest();
this._initListeners( resolve, reject, file );
this._sendRequest( file );
} ) );
}
// Aborts the upload process.
abort() {
if ( this.xhr ) {
this.xhr.abort();
}
}
// Initializes the XMLHttpRequest object using the URL passed to the constructor.
_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();
// Note that your request may look different. It is up to you and your editor
// integration to choose the right communication channel. This example uses
// a POST request with JSON as a data structure but your configuration
// could be different.
xhr.open( 'POST', '/file_upload/', true );
xhr.responseType = 'json';
}
// Initializes XMLHttpRequest listeners.
_initListeners( resolve, reject, file ) {
const xhr = this.xhr;
const loader = this.loader;
const genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener( 'error', () => reject( genericErrorText ) );
xhr.addEventListener( 'abort', () => reject() );
xhr.addEventListener( 'load', () => {
const response = xhr.response;
// This example assumes the XHR server's "response" object will come with
// an "error" which has its own "message" that can be passed to reject()
// in the upload promise.
//
// Your integration may handle upload errors in a different way so make sure
// it is done properly. The reject() function must be called when the upload fails.
if ( !response || response.error ) {
return reject( response && response.error ? response.error.message : genericErrorText );
}
// If the upload is successful, resolve the upload promise with an object containing
// at least the "default" URL, pointing to the image on the server.
// This URL will be used to display the image in the content. Learn more in the
// UploadAdapter#upload documentation.
resolve( {
default: response.file_path.replace("/home", "")
} );
} );
// Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
// properties which are used e.g. to display the upload progress bar in the editor
// user interface.
if ( xhr.upload ) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
xhr.upload.addEventListener('progress', evt => {
if ( evt.lengthComputable ) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
} );
}
}
// Prepares the data and sends the request.
_sendRequest( file ) {
// Prepare the form data.
const data = new FormData();
data.append( 'file', file );
// Important note: This is the right place to implement security mechanisms
// like authentication and CSRF protection. For instance, you can use
// XMLHttpRequest.setRequestHeader() to set the request headers containing
// the CSRF token generated earlier by your application.
// Send the request.
this.xhr.send( data );
}
}
function MyCustomUploadAdapterPlugin( editor ) {
editor.plugins.get('FileRepository').createUploadAdapter = ( loader ) => {
// Configure the URL to the upload script in your back-end here!
return new MyUploadAdapter( loader );
};
}
// TODO Commented code for future reference
//function getFeedItems( queryText ) {
// return new Promise( resolve => {
// setTimeout( () => {
// $.ajax({
// url : "/get_user_list/?queryText="+queryText,
// type : "GET",
// success : function(data){
// var data = JSON.parse(data);
// resolve( data );
// },
// error: handleAJAXError
// });
// }, 100 );
// } );
//}
function getNodeItems( queryText ){
return new Promise( resolve =>{
setTimeout(()=>{
$.ajax({
url : "/typeahead/?q="+queryText,
type : "GET",
success : function(data){
var data = JSON.parse(data);
var result = []
last_type_added = null
for(node of data) {
var _type = node['labels'].split("_").join(" ")
var _title = node['title']
var _display = node['display']?node['display']:""
var _hint = node['hint']?node['hint']:null
if (last_type_added != _type) {
last_type_added = _type;
}
result.push({id: "@" + _type + "." + _title, type: _type, title: _title})
}
resolve( result );
}
});
}, 100);
});
}
/*
* This plugin customizes the way mentions are handled in the editor model and data.
* Instead of a classic <span class="mention"></span>,
*/
function MentionLinks( editor ) {
// The upcast converter will convert a view
//
// <a href="..." class="mention" data-mention="...">...</a>
//
// element to the model "mention" text attribute.
editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'a',
key: 'data-mention',
classes: 'mention',
attributes: {
href: true,
target: true,
}
},
model: {
key: 'mention',
value: viewItem => editor.plugins.get( 'Mention' ).toMentionAttribute( viewItem )
},
converterPriority: 'high'
} );
// Downcast the model "mention" text attribute to a view
//
// <a href="..." class="mention" data-mention="...">...</a>
//
// element.
editor.conversion.for( 'downcast' ).attributeToElement( {
model: 'mention',
view: ( modelAttributeValue, { writer } ) => {
// Do not convert empty attributes (lack of value means no mention).
if ( !modelAttributeValue ) {
return;
}
const nt_title = modelAttributeValue.id.slice(1).split(/\.(.+)/);
const nt = encodeURIComponent(nt_title[0]);
const title = encodeURIComponent(nt_title[1]);
return writer.createAttributeElement( 'a', {
class: 'mention',
'data-mention': modelAttributeValue.id,
target: "_blank",
href: `https://${window.location.hostname}/draw_graph/?ntype1=${nt}&title1=${title}&focusWithPropWin=true`
}, {
// Make mention attribute to be wrapped by other attribute elements.
priority: 20,
// Prevent merging mentions together.
id: modelAttributeValue.id
} );
},
converterPriority: 'high'
} );
}
function customItemRenderer( item ) {
const itemElement = document.createElement('div');
itemElement.innerHTML = `<span style='font-weight: bold'>@${ item.type }.</span>`;
const usernameElement = document.createElement('span');
usernameElement.innerHTML = synthesize_string(item.title);
itemElement.appendChild(usernameElement);
$(".ck-balloon-panel").css("z-index", 9999);
return itemElement;
}
The text was updated successfully, but these errors were encountered:
I am trying to use mentions in the editor but somehow it is not working and throwing error.
Here is my code
The text was updated successfully, but these errors were encountered: