AEM · AEM 6

AEM | RTE – Custom Styles Plugin – Touch UI


Goal: Create RTE (Rich Text Editor) fontstyle & fontcolor plugin for Touch UI. A Similar classic UI RTE Extension is available here

Note: Please see RTE – Custom Styles Plugin for understanding of Custom Styles plugin requirement.

DownloadSource Code | Package Install

Preview

RTE Touch UI - Styles plugin
RTE Touch UI – Styles plugin

Solution

  1. Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/rte/plugins/touch-ui-styles
  2. Create node /apps/rte/plugins/touch-ui-styles/clientlib of type cq:ClientLibraryFolder and add a String property categories with value rte.coralui2
  3. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/js.txt and add following files
    #base=./js
    setup.js
    ## Commands
    commands/StylesCommandImpl.js
    ## UI Elements
    ui/StyleSelectorImpl.js
    ui/CuiToolbarBuilder.js
    ui/ToolkitImpl.js
    ## Plugins
    plugins/FontColorPlugin.js
    plugins/FontStylePlugin.js
  4. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/setup.js and add the following code.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Setting up classes
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    var ACT = ACT || {};
    ACT.rte = ACT.rte || {
        GROUP: "act",
    
        // Commands
        COMMAND: {
       		STYLES: "actstyles"
    	},
    
        DEBUG: {
            ALL: false,
            STYLESELECTOR: false,
            TOOLKITIMPL: false,
            TOOLBARBUILDER: false,
            STYLECOMMAND: false,
            FONTCOLOR: false,
            FONTSTYLE: false
        },
    
        // Features
        FEATURE: {
            FONT_COLOR: {
                NAME: "fontcolor",
                ID: "#fontcolor",
                POPID: "fontcolor:getStyles:styles-pulldown",
                ICON: "coral-Icon coral-Icon--textColor"
            },
            FONT_STYLE: {
                NAME: "fontstyles",
                ID: "#fontstyles",
                POPID: "fontstyles:getStyles:styles-pulldown",
                ICON: "coral-Icon coral-Icon--textStyle"
            }
        },
    
        STYLE_TAG: "span",
    
        STYLEABLE_OBJECTS: [
        	"img"
    	]
    };
    ACT.rte.commands = {};
    ACT.rte.plugins = {};
    ACT.rte.ui = {};

    DownloadSource Code | Package Install

  5. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/commands/StylesCommandImpl.js and add the following code to create Styles command.
    /*************************************************************************
    *
    * RTE Plugins
    * ___________________
    * Styles Command manager for following plugins:
    * 1. fontstyles
    * 2. fontcolor
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    ACT.rte.commands.StylesCommandImpl = new Class({
        
        toString: "ACTStylesCommand",
        
        extend: CUI.rte.commands.Command,
    
        isCommand: function(cmdStr) {
            if(ACT.rte.DEBUG.STYLECOMMAND || ACT.rte.DEBUG.ALL) {
            	console.log("ACT StylesCommandImpl - isCommand");
            }
            return (cmdStr.toLowerCase() == ACT.rte.COMMAND.STYLES);
        },
    
        getProcessingOptions: function() {
            if(ACT.rte.DEBUG.STYLECOMMAND || ACT.rte.DEBUG.ALL) {
            	console.log("ACT StylesCommandImpl - getProcessingOptions");
            }
            var cmd = CUI.rte.commands.Command;
            return cmd.PO_SELECTION | cmd.PO_BOOKMARK | cmd.PO_NODELIST;
        },
    
        addStyle: function(execDef) {
            if(ACT.rte.DEBUG.STYLECOMMAND || ACT.rte.DEBUG.ALL) {
            	console.log("ACT StylesCommandImpl - addStyle");
            }
    
            var sel = CUI.rte.Selection;
            var com = CUI.rte.Common;
            var styleName = execDef.value.attributes.class;
            var tagName = execDef.value.tag;
            var styleList = execDef.value.styles;
            var selection = execDef.selection;
            var context = execDef.editContext;
            // handle DOM elements
            var selectedDom = sel.getSelectedDom(context, selection);
            var styleableObjects = ACT.rte.STYLEABLE_OBJECTS;
            if (selectedDom && com.isTag(selectedDom, styleableObjects)) {
                com.removeAllClasses(selectedDom);
                com.addClass(selectedDom, styleName);
                return;
            }
            // handle text fragments
            var nodeList = execDef.nodeList;
    
            if (nodeList) {
                if(selection.startNode.parentNode.tagName == "SPAN") {
                    var newStyles = [];
                    var existingStyles = selection.startNode.parentNode.className.split(" ");
                    for(var i=0; i<existingStyles.length;i++) {
                        var status = true;
                        for(var j=0; j<styleList.length; j++) {
                            if(existingStyles[i] == styleList[j].cssName) {
                                status = false;
                            }
                        }
                        if(status) {
                            newStyles.push(existingStyles[i]);
                        }
                    }
                    if("default" != styleName) {
                        newStyles.push(styleName);
                    }
                    if(newStyles.length == 0) {
                        $(selection.startNode).unwrap();
                    } else {
                    	selection.startNode.parentNode.className = newStyles.join(" ");
                    }
                } else if(styleName != "default") {
                    nodeList.surround(execDef.editContext, tagName, {
                        "className": styleName
                    });
                }
            }
        },
    
        execute: function(execDef) {
            if(ACT.rte.DEBUG.STYLECOMMAND || ACT.rte.DEBUG.ALL) {
            	console.log("ACT StylesCommandImpl - execute");
            }
    
            switch (execDef.command.toLowerCase()) {
                case "actstyles":
                    this.addStyle(execDef);
                    break;
            }
        },
    
        queryState: function(selectionDef, cmd) {
            if(ACT.rte.DEBUG.STYLECOMMAND || ACT.rte.DEBUG.ALL) {
            	console.log("ACT StylesCommandImpl - queryState");
            }
            
            var com = CUI.rte.Common;
            var tagName = this._getTagNameForCommand(cmd);
            if (!tagName) {
                return undefined;
            }
            var context = selectionDef.editContext;
            var selection = selectionDef.selection;
            return (com.getTagInPath(context, selection.startNode, tagName) != null);
        }
    });
    
    CUI.rte.commands.CommandRegistry.register(ACT.rte.COMMAND.STYLES, ACT.rte.commands.StylesCommandImpl);

    DownloadSource Code | Package Install

  6. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/ui/StyleSelectorImpl.js and add the following code to create Styles Selector.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Create ACT Style toolbar renderer for following plugins:
    * 1. fontstyles
    * 2. fontcolor
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    
    ACT.rte.ui.StyleSelectorImpl = new Class({
    
        toString: "ACTStyleSelectorImpl",
    
        extend: CUI.rte.ui.TbStyleSelector,
    
        // Helpers -----------------------------------------------------------------------------
    
    	notifyGroupBorder: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
               console.log("StyleSelectorImpl - notifyGroupBorder()");
            }
    		// do nothing
    	},
    
    	_getStyleId: function($button) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - _getStyleId()");
            }
    		var styleId = null;
    		var targetId = $button.data("action");
    		var hashPos = targetId.indexOf("#");
    		if (hashPos >= 0) {
    			styleId = targetId.substring(hashPos + 1);
    		}
    		return styleId;
    	},
    
    	_resetSelection: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - _resetSelection()");
            }
    		var $selectorItems = this.$ui.find("i");
    		$selectorItems.removeClass("coral-Icon--check");
    	},
    
    	_select: function(styleToSelect) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - _select()");
            }
    		var self = this;
    		this.$ui.each(function() {
    			var $fmtItem = $(this);
    			var styleId = self._getStyleId($fmtItem);
    			if (styleId && (styleId === styleToSelect)) {
    				$fmtItem.find("i").addClass("coral-Icon--check");
    			}
    		});
    	},
    
    
    	// Interface implementation ------------------------------------------------------------
    
    	addToToolbar: function(toolbar) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - addToToolbar()");
            }
    
            var commandRef = "#" + this.id;
            toolbar.push({
                "ref": commandRef,
                "plugin": this.plugin.pluginId,
                "command": this.id
            });
    	},
    
    	notifyToolbar: function(toolbar, skipHandlers) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - notifyToolbar()");
            }
    		this.toolbar = toolbar;
    		var self = this;
    		var pluginId = this.plugin.pluginId;
    		var $cont = toolbar.getToolbarContainer();
    		var tbType = toolbar.tbType;
    		if (!this.plugin.hasStylesConfigured()) {
    			var styles = [ ];
    			var $popover = CUI.rte.UIUtils.getPopover(pluginId, tbType, $cont);
    			var $styleItems = $popover.find("li");
    			$styleItems.each(function() {
    				var $button = $(this).find("button");
    				var href = $button.data("action");
    				var action = href.split("#");
    				if ((action.length === 2) && (action[0] === pluginId)) {
    					styles.push({
    						"cssName": action[1],
    						"text": $button.text()
    					});
    				}
    			});
    			this.plugin.setStyles(styles);
    		}
    		var $tbCont = CUI.rte.UIUtils.getToolbarContainer($cont, tbType);
    		this.$trigger = $tbCont.find('button[data-action="#' + pluginId + '"]');
    		this.$ui = $tbCont.find('div[data-id="' + pluginId + '"] button[data-action^="styles#"]');
    		if (!skipHandlers) {
    			this.$ui.on("click.rte-handler", function (e) {
    				if (!self.$ui.hasClass(CUI.rte.Theme.TOOLBARITEM_DISABLED_CLASS)) {
    					var targetId = $(this).data("action");
    					var hashPos = targetId.indexOf("#");
    					var style = targetId.substring(hashPos + 1);
    					var editContext = self.plugin.editorKernel.getEditContext();
    					editContext.setState("CUI.SelectionLock", 1);
    					self.plugin.execute(ACT.rte.COMMAND.STYLES, style);
    					self.plugin.editorKernel.enableFocusHandling();
    					self.plugin.editorKernel.focus(editContext);
    				}
    				// e.stopPropagation();
    			});
    		}
    	},
    
    	createToolbarDef: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - createToolbarDef()");
            }
    		return {
    			"id": this.id,
    			"element": this
    		};
    	},
    
    	initializeSelector: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - initializeSelector()");
            }
    		// TODO ...?
    	},
    
    	getSelectorDom: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - getSelectorDom()");
            }
    		return this.$ui;
    	},
    
    	getSelectedStyle: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - getSelectedStyle()");
            }
    		return null;
    	},
    
    	selectStyles: function(styles, selDef) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	//console.log("StyleSelectorImpl - selectStyles()");
            }
    		this.setSelected(styles.length > 0);
    		this._resetSelection();
    		for (var s = 0; s < styles.length; s++) {
    			this._select(styles[s]);
    		}
    	},
    
    	setDisabled: function(isDisabled) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	//console.log("StyleSelectorImpl - setDisabled()");
            }
    		var com = CUI.rte.Common;
    		if (com.ua.isTouchInIframe) {
    			// workaround for CUI-649; see ElementImpl#setDisabled for an explanation
    			this.$trigger.css("display", "none");
    		}
    		if (isDisabled) {
    			this.$trigger.addClass(CUI.rte.Theme.TOOLBARITEM_DISABLED_CLASS);
    			this.$trigger.attr("disabled", "disabled");
    		} else {
    			this.$trigger.removeClass(CUI.rte.Theme.TOOLBARITEM_DISABLED_CLASS);
    			this.$trigger.removeAttr("disabled");
    		}
    		if (com.ua.isTouchInIframe) {
    			// part 2 of workaround for CUI-649
    			var self = this;
    			window.setTimeout(function() {
    				self.$trigger.css("display", "inline-block");
    			}, 1);
    		}
    	},
    
    	setSelected: function(isSelected, suppressEvent) {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	//console.log("StyleSelectorImpl - setSelected()");
            }
    		this._isSelected = isSelected;
    		if (isSelected) {
    			this.$trigger.addClass(CUI.rte.Theme.TOOLBARITEM_SELECTED_CLASS);
    		} else {
    			this.$trigger.removeClass(CUI.rte.Theme.TOOLBARITEM_SELECTED_CLASS);
    		}
    	},
    
    	isSelected: function() {
            if(ACT.rte.DEBUG.STYLESELECTOR || ACT.rte.DEBUG.ALL) {
            	console.log("StyleSelectorImpl - isSelected()");
            }
    		return this._isSelected;
    	}
    });

    DownloadSource Code | Package Install

  7. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/ui/CuiToolbarBuilder.js and add the following code to add custom styles in Tool Bar.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Extend toolbar builder to register different commands
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    ACT.rte.ui.CuiToolbarBuilder = new Class({
        
        toString: "ACTCuiToolbarBuilder",
        
        extend: CUI.rte.ui.cui.CuiToolbarBuilder,
    
        _getUISettings: function (options) {
            var uiSettings = this.superClass._getUISettings(options);
    
            if(ACT.rte.DEBUG.TOOLBARBUILDER || ACT.rte.DEBUG.ALL) {
            	console.log("ACTCuiToolbarBuilder - _getUISettings()");
            }
    
            //inline toolbar
            var items = uiSettings["inline"]["popovers"]["format"].items;
    
    
    	//add plugins to fullscreen toolbar
            var toolbar = uiSettings["fullscreen"]["toolbar"];
    		var popovers = uiSettings["fullscreen"]["popovers"];
    
            // Font Color
            if (toolbar.indexOf(ACT.rte.FEATURE.FONT_COLOR.ID) == -1) {
            	toolbar.splice(3, 0, ACT.rte.FEATURE.FONT_COLOR.ID);
            }
    		if (!popovers.hasOwnProperty(ACT.rte.FEATURE.FONT_COLOR.NAME)) {
                popovers.fontcolor = {
                	"ref": ACT.rte.FEATURE.FONT_COLOR.NAME,
                    "items": ACT.rte.FEATURE.FONT_COLOR.POPID
                };
            }
            if (!this._getClassesForCommand(ACT.rte.FEATURE.FONT_COLOR.ID)) {
            	this.registerAdditionalClasses(ACT.rte.FEATURE.FONT_COLOR.ID, ACT.rte.FEATURE.FONT_COLOR.ICON);
            }
    
            // Font Styles
            if (toolbar.indexOf(ACT.rte.FEATURE.FONT_STYLE.ID) == -1) {
            	toolbar.splice(3, 0, ACT.rte.FEATURE.FONT_STYLE.ID);
            }
    		if (!popovers.hasOwnProperty(ACT.rte.FEATURE.FONT_STYLE.NAME)) {
                popovers.fontstyles = {
                	"ref": ACT.rte.FEATURE.FONT_STYLE.NAME,
                    "items": ACT.rte.FEATURE.FONT_STYLE.POPID
                };
            }
            if (!this._getClassesForCommand(ACT.rte.FEATURE.FONT_STYLE.ID)) {
            	this.registerAdditionalClasses(ACT.rte.FEATURE.FONT_STYLE.ID, ACT.rte.FEATURE.FONT_STYLE.ICON);
            }
            
            return uiSettings;
        },
    
        // Styles dropdown builder
        createACTStyleSelector: function(id, plugin, tooltip, styles) {
            if(ACT.rte.DEBUG.TOOLBARBUILDER || ACT.rte.DEBUG.ALL) {
            	console.log("ACTCuiToolbarBuilder - createACTStyleSelector()");
            }
            return new ACT.rte.ui.StyleSelectorImpl(id, plugin, false, tooltip, false,
                                                        undefined, styles);
        }
    });

    DownloadSource Code | Package Install

  8. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/ui/ToolkitImpl.js and add the following code to invoke custom toolbar.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Extend the toolkit implementation for custom toolbar builder and dialog manager
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    ACT.rte.ui.ToolkitImpl = new Class({
    
        toString: "ACTToolkitImpl",
        
        extend: CUI.rte.ui.cui.ToolkitImpl,
    
        createToolbarBuilder: function() {
            if(ACT.rte.DEBUG.TOOLKITIMPL || ACT.rte.DEBUG.ALL) {
            	console.log("init ACT.rte.ui.ToolkitImpl");
            }
            return new ACT.rte.ui.CuiToolbarBuilder();
        }
    });
    
    CUI.rte.ui.ToolkitRegistry.register("cui", ACT.rte.ui.ToolkitImpl);

    DownloadSource Code | Package Install

  9. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/plugins/FontColorPlugin.js and add the following code to create Font color plugin.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Font Color Plugin
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    ACT.rte.plugins.FontColorPlugin = new Class({
        
        toString: "FontColorPlugin",
    
        extend: CUI.rte.plugins.Plugin,
    
        /**
         * @private
         */
        cachedStyles: null,
    
        /**
         * @private
         */
        stylesUI: null,
    
        getFeatures: function() {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
            	console.log("ACT FontColorPlugin - getFeatures");
            }
            return [ ACT.rte.FEATURE.FONT_COLOR.NAME ];
        },
    
        /**
         * @private
         */
        getStyleId: function(dom) {
             if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
            	console.log("ACT FontColorPlugin - getStyleId");
            }
            var tagName = dom.tagName.toLowerCase();
            var styles = this.getStyles();
            var stylesCnt = styles.length;
            for (var f = 0; f < stylesCnt; f++) {
                var styleDef = styles[f];
                //TODO: We need to handle span class, not tag
                if (styleDef.tag && (styleDef.tag == tagName)) {
                    return styleDef.tag;
                }
            }
            return null;
        },
    
    	getStyles: function() {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontColorPlugin - getStyles");
            }
            var com = CUI.rte.Common;
            if (!this.cachedStyles) {
                this.cachedStyles = this.config.styles || { };
                if (this.cachedStyles) {
                    // take styles from config
                    com.removeJcrData(this.cachedStyles);
                    this.cachedStyles = com.toArray(this.cachedStyles, "cssName", "text");
                } else {
                    this.cachedStyles = [ ];
                }
            }
            return this.cachedStyles;
        },
    
        setStyles: function(styles) {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontColorPlugin - setStyles");
            }
            this.cachedStyles = styles;
        },
    
        hasStylesConfigured: function() {
    		if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontColorPlugin - hasStylesConfigured");
            }
            return !!this.config.styles;
        },
    
        initializeUI: function(tbGenerator, options) {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontColorPlugin - initializeUI");
            }
            var plg = CUI.rte.plugins;
            if (this.isFeatureEnabled(ACT.rte.FEATURE.FONT_COLOR.NAME)) {
                this.stylesUI = new tbGenerator.createACTStyleSelector(ACT.rte.FEATURE.FONT_COLOR.NAME, this, null, this.getStyles());
                tbGenerator.addElement(ACT.rte.FEATURE.FONT_COLOR.NAME, plg.Plugin.SORT_STYLES, this.stylesUI, 700);
            }
        },
    
    	notifyPluginConfig: function(pluginConfig) {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontColorPlugin - notifyPluginConfig");
            }
            pluginConfig = pluginConfig || { };
            CUI.rte.Utils.applyDefaults(pluginConfig, { });
            this.config = pluginConfig;
        },
    
    	execute: function(cmdId, styleDef) {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontColorPlugin - execute");
            }
    
            if (this.stylesUI) {
                tagName = ACT.rte.STYLE_TAG;
                className = (styleDef != null ? styleDef : this.stylesUI.getSelectedStyle());
    
                this.editorKernel.relayCmd(ACT.rte.COMMAND.STYLES, {
                    "tag": tagName,
                    "styles": this.getStyles(),
                    "attributes": {
                        "class": className
                    }
                });
            }
        },
    
    	updateState: function(selDef) {
            if(ACT.rte.DEBUG.FONTCOLOR || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontColorPlugin - updateState");
            }
            if (!this.stylesUI) {
                return;
            }
            var com = CUI.rte.Common;
            var styles = selDef.startStyles;
            var actualStyles = [ ];
            var s;
            var styleableObject = selDef.selectedDom;
            if (styleableObject) {
                if (!CUI.rte.Common.isTag(selDef.selectedDom,
                        CUI.rte.plugins.StylesPlugin.STYLEABLE_OBJECTS)) {
                    styleableObject = null;
                }
            }
            var stylesDef = this.getStyles();
            var styleCnt = stylesDef.length;
            if (styleableObject) {
                for (s = 0; s < styleCnt; s++) {
                    var styleName = stylesDef[s].cssName;
                    if (com.hasCSS(styleableObject, styleName)) {
                        actualStyles.push({
                            "className": styleName
                        });
                    }
                }
            } else {
                var checkCnt = styles.length;
                for (var c = 0; c < checkCnt; c++) {
                    var styleToProcess = styles[c];
                    var currentStyles = styleToProcess.className.split(" ");
                    for(var j=0; j<currentStyles.length; j++) {
                        for (s = 0; s < styleCnt; s++) {
    						if (stylesDef[s].cssName == currentStyles[j]) {
                                actualStyles.push(currentStyles[j]);
                                break;
                            }
                        }
    				}
                }
            }
            this.stylesUI.selectStyles(actualStyles, selDef);
        }
    });
    
    CUI.rte.plugins.PluginRegistry.register(ACT.rte.FEATURE.FONT_COLOR.NAME, ACT.rte.plugins.FontColorPlugin);

    DownloadSource Code | Package Install

  10. Create file (nt:file) /apps/rte/plugins/touch-ui-styles/clientlib/plugins/FontStylePlugin.js and add the following code to create Font Style plugin.
    /*************************************************************************
    * RTE Plugins
    * ___________________
    * Font Style Plugin
    *
    * @author Mohit K. Bansal
    **************************************************************************/
    ACT.rte.plugins.FontStylePlugin = new Class({
        
        toString: "FontStylePlugin",
    
        extend: CUI.rte.plugins.Plugin,
    
        /**
         * @private
         */
        cachedStyles: null,
    
        /**
         * @private
         */
        stylesUI: null,
        
        getFeatures: function() {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
            	console.log("ACT FontStylePlugin - getFeatures");
            }
            return [ ACT.rte.FEATURE.FONT_STYLE.NAME ];
        },
    
        /**
         * @private
         */
        getStyleId: function(dom) {
             if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
            	console.log("ACT FontStylePlugin - getStyleId");
            }
            var tagName = dom.tagName.toLowerCase();
            var styles = this.getStyles();
            var stylesCnt = styles.length;
            for (var f = 0; f < stylesCnt; f++) {
                var styleDef = styles[f];
                //TODO: We need to handle span class, not tag
                if (styleDef.tag && (styleDef.tag == tagName)) {
                    return styleDef.tag;
                }
            }
            return null;
        },
    
    	getStyles: function() {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontStylePlugin - getStyles");
            }
            var com = CUI.rte.Common;
            if (!this.cachedStyles) {
                this.cachedStyles = this.config.styles || { };
                if (this.cachedStyles) {
                    // take styles from config
                    com.removeJcrData(this.cachedStyles);
                    this.cachedStyles = com.toArray(this.cachedStyles, "cssName", "text");
                } else {
                    this.cachedStyles = [ ];
                }
            }
            return this.cachedStyles;
        },
    
        setStyles: function(styles) {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontStylePlugin - setStyles");
            }
            this.cachedStyles = styles;
        },
    
        hasStylesConfigured: function() {
    		if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
                console.log("ACT FontStylePlugin - hasStylesConfigured");
            }
            return !!this.config.styles;
        },
    
        initializeUI: function(tbGenerator, options) {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontStylePlugin - initializeUI");
            }
            var plg = CUI.rte.plugins;
            if (this.isFeatureEnabled(ACT.rte.FEATURE.FONT_STYLE.NAME)) {
                this.stylesUI = new tbGenerator.createACTStyleSelector(ACT.rte.FEATURE.FONT_STYLE.NAME, this, null, this.getStyles());
                tbGenerator.addElement(ACT.rte.FEATURE.FONT_STYLE.NAME, plg.Plugin.SORT_STYLES, this.stylesUI, 700);
            }
        },
    
    	notifyPluginConfig: function(pluginConfig) {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontStylePlugin - notifyPluginConfig");
            }
            pluginConfig = pluginConfig || { };
            CUI.rte.Utils.applyDefaults(pluginConfig, { });
            this.config = pluginConfig;
        },
    
    	execute: function(cmdId, styleDef) {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontStylePlugin - execute");
            }
    
            if (this.stylesUI) {
                tagName = ACT.rte.STYLE_TAG;
                className = (styleDef != null ? styleDef : this.stylesUI.getSelectedStyle());
    
                this.editorKernel.relayCmd(ACT.rte.COMMAND.STYLES, {
                    "tag": tagName,
                    "styles": this.getStyles(),
                    "attributes": {
                        "class": className
                    }
                });
            }
        },
    
    	updateState: function(selDef) {
            if(ACT.rte.DEBUG.FONTSTYLE || ACT.rte.DEBUG.ALL) {
    			console.log("ACT FontStylePlugin - updateState");
            }
            if (!this.stylesUI) {
                return;
            }
            var com = CUI.rte.Common;
            var styles = selDef.startStyles;
            var actualStyles = [ ];
            var s;
            var styleableObject = selDef.selectedDom;
            if (styleableObject) {
                if (!CUI.rte.Common.isTag(selDef.selectedDom,
                        CUI.rte.plugins.StylesPlugin.STYLEABLE_OBJECTS)) {
                    styleableObject = null;
                }
            }
            var stylesDef = this.getStyles();
            var styleCnt = stylesDef.length;
            if (styleableObject) {
                for (s = 0; s < styleCnt; s++) {
                    var styleName = stylesDef[s].cssName;
                    if (com.hasCSS(styleableObject, styleName)) {
                        actualStyles.push({
                            "className": styleName
                        });
                    }
                }
            } else {
                var checkCnt = styles.length;
                for (var c = 0; c < checkCnt; c++) {
                    var styleToProcess = styles[c];
                    var currentStyles = styleToProcess.className.split(" ");
                    for(var j=0; j<currentStyles.length; j++) {
                        for (s = 0; s < styleCnt; s++) {
    						if (stylesDef[s].cssName == currentStyles[j]) {
                                actualStyles.push(currentStyles[j]);
                                break;
                            }
                        }
    				}
                }
            }
            this.stylesUI.selectStyles(actualStyles, selDef);
        }
    });
    
    CUI.rte.plugins.PluginRegistry.register(ACT.rte.FEATURE.FONT_STYLE.NAME, ACT.rte.plugins.FontStylePlugin);

Download: Source Code | Package Install

Advertisements

4 thoughts on “AEM | RTE – Custom Styles Plugin – Touch UI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s