Goal
In Touch UI RTE (Rich Text Editor) extend the List plugin to apply user selected css class
Demo | Package Install | GitHub
Solution
1) Login to CRXDE Lite, create folder (nt:folder) /apps/eaem-touch-rte-list-plugin-css
2) Create dialog /apps/eaem-touch-rte-list-plugin-css/dialog/cq:dialog with the allowed css classes for user selection (applied on list)
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Css Class"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
margin="{Boolean}false"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<css-classes
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/select"
emptyText="Select css class..."
name="./cssClass">
<items jcr:primaryType="nt:unstructured">
<red
jcr:primaryType="nt:unstructured"
text="coral-Tag--red"/>
<magenta
jcr:primaryType="nt:unstructured"
text="coral-Tag--magenta"/>
<fuchsia
jcr:primaryType="nt:unstructured"
text="coral-Tag--fuchsia"/>
<plum
jcr:primaryType="nt:unstructured"
text="coral-Tag--plum"/>
<blue
jcr:primaryType="nt:unstructured"
text="coral-Tag--blue"/>
</items>
<select
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/button"
class="coral-Button--primary"
text="Select"/>
</css-classes>
</items>
</column>
</items>
</content>
</jcr:root>
3) Create clientlib (type cq:ClientLibraryFolder) /apps/eaem-touch-rte-list-plugin-css/clientlib and set property categories of String[] type to cq.authoring.dialog and dependencies to underscore
4) Create file ( type nt:file ) /apps/eaem-touch-rte-list-plugin-css/clientlib/js.txt, add the following
list-plugin-css.js
5) Create file ( type nt:file ) /apps/eaem-touch-rte-list-plugin-css/clientlib/list-plugin-css.js, add the following code
(function ($) {
"use strict";
var _ = window._,
Class = window.Class,
GROUP = "experience-aem",
CSS_DIALOG = "/apps/eaem-touch-rte-list-plugin-css/dialog/cq:dialog.html",
CUI = window.CUI;
var EAEMCSSListCmd = new Class({
extend: CUI.rte.commands.List,
toString: "EAEMCSSListCmd",
execute: function(execDef) {
this.superClass.execute.call(this, execDef);
var list = this.getDefiningListDom(execDef.editContext, execDef.nodeList);
if(!list){
return;
}
registerReceiveDataListener(receiveMessage);
if(!this.eaemSelectCssDialog){
this.eaemSelectCssDialog = showDialog();
}
var eaemSelectCssDialog = this.eaemSelectCssDialog;
eaemSelectCssDialog.show();
function receiveMessage(event) {
if (_.isEmpty(event.data)) {
return;
}
var message = JSON.parse(event.data);
if (!message || message.sender !== GROUP) {
return;
}
$(list).addClass(message.data.cssClass);
eaemSelectCssDialog.hide();
removeReceiveDataListener(receiveMessage);
}
}
});
function showDialog(){
var html = "<iframe width='540px' height='250px' frameBorder='0' src='"
+ CSS_DIALOG + "?requester=" + GROUP + "'>"
+ "</iframe>";
var cuiDialog = new Coral.Dialog().set({
backdrop: 'static',
header: {
innerHTML: 'Select css class'
},
content: {
innerHTML: html
}
});
document.body.appendChild(cuiDialog);
return cuiDialog;
}
function removeReceiveDataListener(handler) {
if (window.removeEventListener) {
window.removeEventListener("message", handler);
} else if (window.detachEvent) {
window.detachEvent("onmessage", handler);
}
}
function registerReceiveDataListener(handler) {
if (window.addEventListener) {
window.addEventListener("message", handler, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", handler);
}
}
CUI.rte.commands.CommandRegistry.register("_list", EAEMCSSListCmd);
})(jQuery);
(function($, $document){
var SENDER = "experience-aem",
REQUESTER = "requester",
CSS_CLASS = "cssClass";
if(queryParameters()[REQUESTER] !== SENDER ){
return;
}
$document.on("foundation-contentloaded", stylePopoverIframe);
function queryParameters() {
var result = {}, param,
params = document.location.search.split(/\?|\&/);
params.forEach( function(it) {
if (_.isEmpty(it)) {
return;
}
param = it.split("=");
result[param[0]] = param[1];
});
return result;
}
function stylePopoverIframe(){
var $dialog = $(".cq-dialog").css("background", "white"),
$selectBut = $dialog.find(".coral-Button--primary");
$dialog.find(".cq-dialog-header").hide();
$dialog.find(".cq-dialog-content").css("top", ".1rem");
$selectBut.css("margin", "120px 0 0 380px").click(sendDataMessage);
}
function sendDataMessage(){
var message = {
sender: SENDER,
data: {}
}, $dialog, cssClass;
$dialog = $(".cq-dialog");
cssClass = $dialog.find("[name='./" + CSS_CLASS + "']").val();
message.data[CSS_CLASS] = cssClass;
parent.postMessage(JSON.stringify(message), "*");
}
})(jQuery, jQuery(document));