001/*
002 *  Copyright 2017 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.clientsideelement.styles;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.LinkedHashSet;
024import java.util.List;
025import java.util.Map;
026import java.util.Map.Entry;
027import java.util.Set;
028
029import org.apache.avalon.framework.service.ServiceException;
030import org.apache.avalon.framework.service.ServiceManager;
031import org.apache.avalon.framework.service.Serviceable;
032import org.apache.commons.lang3.tuple.Pair;
033
034import org.ametys.core.ui.ClientSideElement;
035import org.ametys.core.ui.ClientSideElement.ScriptFile;
036import org.ametys.core.ui.widgets.richtext.RichTextConfiguration;
037import org.ametys.core.ui.widgets.richtext.RichTextConfigurationAttribute;
038import org.ametys.core.ui.widgets.richtext.RichTextConfigurationStyle;
039import org.ametys.core.ui.widgets.richtext.RichTextConfigurationStyleGroup;
040import org.ametys.core.ui.widgets.richtext.RichTextConfigurationTag;
041import org.ametys.core.ui.widgets.richtext.RichTextConfigurationTag.EMPTY_TAG;
042import org.ametys.core.ui.widgets.richtext.StaticRichTextConfiguration.StaticRichTextConfigurationAttribute;
043import org.ametys.core.ui.widgets.richtext.StaticRichTextConfiguration.StaticRichTextConfigurationStyle;
044import org.ametys.core.ui.widgets.richtext.StaticRichTextConfiguration.StaticRichTextConfigurationStyleGroup;
045import org.ametys.core.ui.widgets.richtext.StaticRichTextConfiguration.StaticRichTextConfigurationTag;
046import org.ametys.runtime.i18n.I18nizableText;
047
048/**
049 * Declares all rich text configurations relative the {@link HTMLEditorStyle}
050 */
051public class HTMLEditorStyleRichTextConfiguration implements RichTextConfiguration, Serviceable
052{
053    private static final Map<String, I18nizableText> STYLE_GROUP_LABELS = new HashMap<>();
054    private HTMLEditorStyle _htmlEditorStyle;
055
056    static
057    {
058        STYLE_GROUP_LABELS.put("image", new I18nizableText("plugin.cms", "CONTENT_EDITION_IMAGE_STYLES_GROUP_STYLED"));
059        STYLE_GROUP_LABELS.put("link", new I18nizableText("plugin.cms", "CONTENT_EDITION_LINK_STYLES_GROUP_SPECIAL"));
060        STYLE_GROUP_LABELS.put("ol", new I18nizableText("plugin.cms", "CONTENT_EDITION_CHARACTER_ORDEREDLIST_STYLES_GROUP_STYLED"));
061        STYLE_GROUP_LABELS.put("paragraph", new I18nizableText("TODO HTMLEditorStyleRichTextConfiguration")); // TODO
062        STYLE_GROUP_LABELS.put("table", new I18nizableText("plugin.cms", "CONTENT_EDITION_TABLE_STYLES_GROUP_STYLED"));
063        STYLE_GROUP_LABELS.put("ul", new I18nizableText("plugin.cms", "CONTENT_EDITION_CHARACTER_UNORDEREDLIST_STYLES_GROUP_STYLED"));
064    }
065
066    public void service(ServiceManager manager) throws ServiceException
067    {
068        _htmlEditorStyle = (HTMLEditorStyle) manager.lookup(HTMLEditorStyle.ROLE);
069    }
070    
071    public Set<String> getCategories()
072    {
073        return _htmlEditorStyle.getCategories();
074    }
075    
076    public int getPriority()
077    {
078        return 1000;
079    }
080    
081    public Collection<RichTextConfigurationTag> getHandledTags(String category, Map<String, Object> contextParameters)
082    {
083        List<RichTextConfigurationTag> tags = new ArrayList<>();
084        
085        if (getCategories().contains(category))
086        {
087            Map<String, Pair<String, StyleCategory>> styleCategories = new HashMap<>();
088            styleCategories.put("img", Pair.of("image", _htmlEditorStyle.getImage(category, contextParameters)));
089            styleCategories.put("a", Pair.of("link", _htmlEditorStyle.getLink(category, contextParameters)));
090            styleCategories.put("ol", Pair.of("ol", _htmlEditorStyle.getOrderedList(category, contextParameters)));
091            styleCategories.put("table", Pair.of("table", _htmlEditorStyle.getTable(category, contextParameters)));
092            styleCategories.put("ul", Pair.of("ul", _htmlEditorStyle.getUnorderedList(category, contextParameters)));
093            
094            for (Entry<String, Pair<String, StyleCategory>> entry : styleCategories.entrySet())
095            {
096                if (entry.getValue().getRight() != null)
097                {
098                    Set<RichTextConfigurationAttribute> attributes = new HashSet<>();
099                    Set<String> authorizedValues = new LinkedHashSet<>();
100                    attributes.add(new StaticRichTextConfigurationAttribute("class", entry.getValue().getRight().getDefaultInlineEditor(), authorizedValues, null));
101                    RichTextConfigurationTag tag = new StaticRichTextConfigurationTag(entry.getKey(), null, null, attributes, entry.getValue().getLeft(), entry.getValue().getRight().getRemovedInlineEditor());
102                    tags.add(tag);
103                    
104                    for (Style style : entry.getValue().getRight().getStyles())
105                    {
106                        authorizedValues.add(style.getInlineEditorRender());
107                    }
108                }
109            }
110            
111            StyleCategory paraStyleCategory = _htmlEditorStyle.getPara(category, contextParameters);
112            if (paraStyleCategory != null)
113            {
114                for (Style style : paraStyleCategory.getStyles())
115                {
116                    String tagName = style.getInlineEditorRender();
117                    Set<RichTextConfigurationAttribute> attributes = new HashSet<>();
118                    Set<String> authorizedValues = new HashSet<>();
119                    authorizedValues.add("text-align");
120                    attributes.add(new StaticRichTextConfigurationAttribute("style", null, authorizedValues, null));
121                    
122                    Set<String> authorizedClassValues = new HashSet<>();
123                    
124                    int dotPosition = tagName.indexOf('.');
125                    if (dotPosition >= 0)
126                    {
127                        String className = tagName.substring(dotPosition + 1);
128                        tagName = tagName.substring(0, dotPosition);
129                        
130                        authorizedClassValues.add(className);
131                    }
132                    
133                    attributes.add(new StaticRichTextConfigurationAttribute("class", null, authorizedClassValues, null));
134                    
135                    RichTextConfigurationTag tag = new StaticRichTextConfigurationTag(tagName, "p".equals(tagName) ? null : EMPTY_TAG.REMOVE_EMPTY_CONTENT, null, attributes, "para", List.of());
136                    tags.add(tag);
137                }
138            }
139        }
140        
141        return tags;
142    }
143    
144    public List<ScriptFile> getCSSFiles(String category, Map<String, Object> contextParameters)
145    {
146        return _htmlEditorStyle.getInlineEditorCSSFiles(category, contextParameters);
147    }
148    
149    public Set<ClientSideElement> getConvertors(String category, Map<String, Object> contextParameters)
150    {
151        return Collections.EMPTY_SET;
152    }
153    
154    public Set<ClientSideElement> getValidators(String category, Map<String, Object> contextParameters)
155    {
156        return Collections.EMPTY_SET;
157    }
158    
159    public Map<String, Map<RichTextConfigurationStyleGroup, List<RichTextConfigurationStyle>>> getAvailableStyles(String category, Map<String, Object> contextualParameters)
160    {
161        Map<String, Map<RichTextConfigurationStyleGroup, List<RichTextConfigurationStyle>>> lists = new HashMap<>();
162        
163        if (getCategories().contains(category))
164        {
165            Map<String, StyleCategory> styleCategories = new HashMap<>();
166            
167            styleCategories.put("image", _htmlEditorStyle.getImage(category, contextualParameters));
168            styleCategories.put("link", _htmlEditorStyle.getLink(category, contextualParameters));
169            styleCategories.put("ol", _htmlEditorStyle.getOrderedList(category, contextualParameters));
170            styleCategories.put("paragraph", _htmlEditorStyle.getPara(category, contextualParameters));
171            styleCategories.put("table", _htmlEditorStyle.getTable(category, contextualParameters));
172            styleCategories.put("ul", _htmlEditorStyle.getUnorderedList(category, contextualParameters));
173            
174            for (Entry<String, StyleCategory> entry : styleCategories.entrySet())
175            {
176                if (entry.getValue() != null)
177                {
178                    Map<RichTextConfigurationStyleGroup, List<RichTextConfigurationStyle>> rtcStylesGroup = new HashMap<>();
179                    lists.put(entry.getKey(), rtcStylesGroup);
180                    
181                    List<RichTextConfigurationStyle> rtcStyles = new ArrayList<>();
182                    rtcStylesGroup.put(new StaticRichTextConfigurationStyleGroup(STYLE_GROUP_LABELS.get(entry.getKey()), 1000), rtcStyles);
183                    
184                    for (Style style : entry.getValue().getStyles())
185                    {
186                        rtcStyles.add(new StaticRichTextConfigurationStyle(style.getInlineEditorRender(), style.getButtonLabel(), style.getButtonDescription(), style.getButtonCSSClass(), style.getButtonSmallIcon(), style.getButtonMediumIcon(), style.getButtonLargeIcon(), !"paragraph".equals(entry.getKey())));
187                    }
188                }
189            }
190        }
191        
192        return lists;
193    }
194}