commajs
Configuration
To configure CommaJS, you can pass a JSON object as second argument:
var options = {
    readOnly: false,
    defaultStyle: {
        fontSize: "14px",
        fontFamily: "Verdana",
        fontColor: "#39434d"
    },
    defaultLineStyle: {
        align: "left"
    } 
}; 

var commajs = new CommaJS('rich-text-editor', options);
Note, if you are using the commajs package that includes the toolbar (commajs packages) you can also pass a third option parameter to configure the toolbar:
var toolbarOptions = {
    buttons: "all",
    fontFamilies: [
        {
            label: "Times New Roman",
            value: "\"Times New Roman\", Times, serif"        
        },
        {
            label: "Palatino",
            value: "\"Palatino Linotype\", \"Book Antiqua\", Palatino, serif"
        }
    ]
}; 

var commajs = new CommaJS('rich-text-editor', options, toolbarOptions);
All Options
key
type: String, not required
The CommaJS activation key. If not provided, CommaJS will work normally but a red banner will appear on top of the document.
content
type: String, default: '', not required
Initialize CommaJS with a document. You can retrieve CommaJS content using the onChange() event or the GetContent() function.
readOnly
type: boolean, default: false, not required
If set to true, prevents the user from editing the document.
defaultStyle
type: object, not required
Specifies the default style at cursor position. For more information see styling
options.defaultStyle = {
            fontSize: "14px",
            fontFamily: "Verdana",
            fontColor: "#39434d"
        }
defaultLineStyle
type: object, not required
Specifies the default style on the line containing the cursor. For more information see styling
options.defaultLineStyle = {
            align: "center"
        }
styles
type: object, default: commajs default styles, not required
Overwrites the styles used by CommaJS. For more information see styling
catchUserInput
type: object, not required
Specifies your own events when/if the user enters a specified character(s):
options.catchUserInput = { 
    characters: ["enter", "tab", "a", "test"], //list of chars that will trigger onCharacterEntered
    onCharacterEntered: (chars) => {

        return false; //return true to stop adding "chars" to the document
    }
}
(You can use 'enter', 'delete', 'backspace', 'tab', or 'esc' as keywords to represent the corresponding char)
shortcuts
type: list, not required
Specifies keys or combinations of keys to fire one of the following actions: insertText, insertPlugin, or to call a function.
options.shortcuts = [
    {
        shortcut: 'Ctrl+f',
        action: 'function',
        params: () => { 
            console.log("CTRL+F")
        }
    },
    {
        shortcut: 'Ctrl+t',
        action: 'insertPlugin',
        params: {
            pluginName: CommaTable.GetName(), 
            pluginParams: {
                cols: 5,
                rows: 10
            }
        }
    },
    {
        shortcut: 'Ctrl+e',
        action: 'insertText',
        params: {
            text: "Hello CommaJS!"
        }
    },
    ...
]
The shortcuts option accepts a list of objects defined as:
shortcut: indicates the shortcut that will trigger the action
(to avoid compatibility issues these are the shortcuts that can be used: "Meta+1", "Meta+2", "Meta+3", "Meta+4", "Meta+5", "Meta+6", "Meta+7", "Meta+8", "Meta+9", "Meta+0", "Ctrl+q", "Ctrl+w", "Ctrl+e", "Ctrl+r", "Ctrl+t", "Ctrl+y", "Ctrl+o", "Ctrl+p", "Ctrl+s", "Ctrl+d", "Ctrl+f", "Ctrl+g", "Ctrl+h", "Ctrl+j", "Ctrl+k", "Ctrl+l", "Ctrl+n", "Ctrl+m")
action: indicates which action will be performed. Possible actions are: insertText, insertPlugin, function
params:
if action=='insertText', params = {text: "ANY-STRING"}
if action=='insertPlugin', params = {pluginName: "", pluginParams: {}}
if action=='function', params = () => {...}
autocorrect
type: list, not required
autocorrect (or hotstrings, autoreplace) automatically replace specifics strings with predefined strings. In the example below, a user wants the abbreviation "btw" to be automatically replaced with "by the way":
options.autocorrect = [
    {
        string: 'btw',
        replaceWith: 'by the way'
    },
    ...
]
All Events
onChange
type: function, not required
Fires everytime the content or the style of the document changes.
options.onChange = (content) => { }
The value of content can be saved and used in options.content
onStyleChanged
type: function, not required
Fired when style has changed, it returns only the style that has been applied.
options.onStyleChanged = (newAppliedStyle) => { }
styleMonitoring
type: function, not required
Fires everytime the cursor moves and returns all the styles applied at the new cursor position.
options.styleMonitoring = (stylesAtCursorPosition) => { }
onSelectionChange
type: function, not required
Fires when the text selected on a document changes. Returns an object representing the new selection:
options.onSelectionChange = (newSelection) => { }
newSelection is defined as follow:
newSelection = {
    idStartNode: "", //id of the commajs node where the selection starts
    startNode: undefined, //domElement containing the start node
    startOffset: 0, //where the selection starts
    idEndNode: "", //id of the commajs node where the selection ends
    endNode: undefined, //domElement containing the end node
    endOffset: 0, //where the selection ends
    selectionBoundingRectangle: {}//the DOMRect that bounds the contents of the selection
}
For more information regarding selectionBoundingRectangle, see DOMRect - MDN specifications
onUploadFiles
type: function, not required
Fires when user drags and drop a file(s) over CommaJS. This option is only available with commajs and commajs-naked packages. For commajs-core see Files Drag and Drop
options.onUploadFiles = (files) => { 
    //you will probably need to do something like:
    /*
    files.forEach(file => {
        if(file.type!="directory") {
            const formData = new FormData();
            formData.append('myFile', file);

            fetch('....../uploadFile', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                return response.json();
            })
            .then(data => {
                let fileName = data.fileName;

                .... 
                
                if(GetFileType(fileName) == "image" ) {
                    commaEditor.InsertPluginAtSection(CommaJS.GetPluginImageName(), {link: "........../uploads/"+fileName});
                } else if(GetFileType(fileExtension) == "video" ) {
                    commaEditor.InsertPluginAtSection(CommaJS.GetPluginVideoName(), {link: "........../uploads/"+fileName, mimeType: "video/"+fileExtension});
                } else {
                    console.log("not supported");
                }

            })
            .catch(error => {
                console.error(error);
            });
        }
    });  
    */    
}
Plugins Configuration
Plugins can be registered and configured using the plugins property of the options object:
options.plugins = []

or

options.plugins = {}
How to use this option depends on the package you are using, as explained below:
commajs
commajs-naked
commajs-core
If you are using commajs package, all plugins are automatically registered and configured but plugins like mentions or image upload require additional configuration to communicate with your servers:
options.plugins = {
    links: {
        onClick: (url) => {
            return true; //true = do not open url in a new window
        }
    },
    images: {
        SaveEditedImage: (dataUri, oldUrl) => {
            //dataUri = data:image/png;base64,....

            return new Promise((res,rej) => {                                
                // You can decide to save the edited image to your server and return the url of the image
                // or return directly the dataUri as in this case:
                res(dataUri);
            });
        }
    },
    mentions: {
        factory: {
            charForFire: '@', //open mention factory when user types '@'
            showAbove: true|false, //show serch result panel above
            FormatEntry: (searchResult) => {
                /*
                //you can format the entry in any way you won't, for example:
                let e = document.createElement("div");
                e.textContent = searchResult.label;
                return e;
                */
            },
            Search: (queryString) => {
                return new Promise((res,rej) => {                                
                    res([searchResult,searchResult,....]);
                });
            }            
            
        },
        mention: {
            FormatMention: (entry, inlineNode) => { 
                //entry = the object returned by your search (searchResults)
                //to format a mention just append commajs nodes to inlineNode
            },
            OnClick: (entry, commaNode) => { console.log("click", entry, commaNode)},
            OnMouseOver: (entry, commaNode) => { console.log("OnMouseOver", entry, commaNode)},
            OnMouseOut: (entry, commaNode) => { console.log("OnMouseOut", entry, commaNode)},  
            OnMentionDeleted: (entry, commaNode) => { console.log("OnMentionDeleted", entry, commaNode)}     
        }
    }
}
Refer to each plugin's specific documentation for more information.
If you are using commajs-naked package, all plugins are automatically registered and configured but plugins like mentions or image upload require additional configuration to communicate with your servers:
options.plugins = {
    links: {
        onClick: (url) => {
            return true; //true = do not open url in a new window
        }
    },
    images: {
        SaveEditedImage: (dataUri, oldUrl) => {
            //dataUri = data:image/png;base64,....

            return new Promise((res,rej) => {                                
                // You can decide to save the edited image to your server and return the url of the image
                // or return directly the dataUri as in this case:
                res(dataUri);
            });
        }
    },
    mentions: {
        factory: {
            charForFire: '@', //open mention factory when user types '@'
            showAbove: true|false, //show serch result panel above
            FormatEntry: (searchResult) => {
                /*
                //you can format the entry in any way you won't, for example:
                let e = document.createElement("div");
                e.textContent = searchResult.label;
                return e;
                */
            },
            Search: (queryString) => {
                return new Promise((res,rej) => {                                
                    res([searchResult,searchResult,....]);
                });
            }            
            
        },
        mention: {
            FormatMention: (entry, inlineNode) => { 
                //entry = the object returned by your search (searchResults)
                //to format a mention just append commajs nodes to inlineNode
            },
            OnClick: (entry, commaNode) => { console.log("click", entry, commaNode)},
            OnMouseOver: (entry, commaNode) => { console.log("OnMouseOver", entry, commaNode)},
            OnMouseOut: (entry, commaNode) => { console.log("OnMouseOut", entry, commaNode)},  
            OnMentionDeleted: (entry, commaNode) => { console.log("OnMentionDeleted", entry, commaNode)}     
        }
    }
}
Refer to each plugin's specific documentation for more information.
If you are using commajs-core package, you have full control of the plugins that you want to use. You can pass an array containing the plugins you want to use and, if necessary, each plugin's configuration. For example:
options.plugins = [
    { pClass: CommaLists },
    { pClass: CommaTable },
    { pClass: CommaHorizontalRule },
    { 
        pClass: CommaLink, 
        options: { 
            onClick: (lnk) => { 
                console.log(lnk);                
                return false; //return true to stop default behaviour => by deafault the plugin calls: window.open(lnk, '_blank');
            }
        }
    },
    { pClass: CommaTasks }
]
The plugins option accepts a list of objects defined as:
pClass: reference to the class of the plugin
options: anything needed by the plugin's class (optional)
Refer to each plugin's specific documentation for more information.
Options
key
content
readOnly
defaultStyle
defaultLineStyle
styles
catchUserInput
shortcuts
autocorrect
Events
onChange
onStyleChanged
styleMonitoring
onSelectionChange
onUploadFiles
Plugins Configuration
© 2020 Plugg, Inc. All rights reserved. Various trademarks held by their respective owners.
Plugg, Inc. - San Francisco, CA 94114, United States