View Javadoc
1   /**
2    * This file Copyright (c) 2013-2019 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.vaadin.gwt.client.editor.dom;
35  
36  import info.magnolia.cms.security.operations.OperationPermissionDefinition;
37  import info.magnolia.jcr.util.NodeTypes;
38  import info.magnolia.rendering.template.AreaDefinition;
39  import info.magnolia.ui.vaadin.gwt.client.editor.event.EditAreaEvent;
40  import info.magnolia.ui.vaadin.gwt.client.editor.event.NewAreaEvent;
41  import info.magnolia.ui.vaadin.gwt.client.editor.event.NewComponentEvent;
42  import info.magnolia.ui.vaadin.gwt.client.shared.AreaElement;
43  import info.magnolia.ui.vaadin.gwt.client.widget.controlbar.AreaEndBar;
44  import info.magnolia.ui.vaadin.gwt.client.widget.controlbar.ComponentPlaceHolder;
45  import info.magnolia.ui.vaadin.gwt.client.widget.controlbar.listener.AreaListener;
46  
47  import java.util.Map;
48  
49  import com.google.gwt.dom.client.Element;
50  import com.google.gwt.event.shared.EventBus;
51  
52  /**
53   * Represents an area inside the {@link CmsNode}-tree.
54   * An area can have 3 widgets associated with it:
55   *
56   * <pre>
57   *   <ul>
58   *     <li>{@link info.magnolia.ui.vaadin.gwt.client.widget.controlbar.AreaBar}</li>
59   *     <li>{@link AreaEndBar}</li>
60   *     <li>{@link ComponentPlaceHolder}</li>
61   *   </ul>
62   * </pre>
63   *
64   * Implements a listener interface for the {@link info.magnolia.ui.vaadin.gwt.client.widget.controlbar.AreaBar} and {@link ComponentPlaceHolder}.
65   * Provides wrapper functions used by the {@link info.magnolia.ui.vaadin.gwt.client.editor.model.focus.FocusModel}.
66   */
67  public class MgnlArea extends MgnlElement implements AreaListener {
68      public static final String EDITOR_INIT_CLASS_NAME = "init";
69      private AreaEndBar areaEndBar;
70      private ComponentPlaceHolder componentPlaceHolder;
71      private Element componentMarkerElement;
72      private EventBus eventBus;
73  
74      /**
75       * MgnlElement. Represents a node in the tree built on cms-tags.
76       */
77      public MgnlArea(MgnlElement parent, EventBus eventBus) {
78          super(parent);
79          this.eventBus = eventBus;
80      }
81  
82      private AreaEndBar getAreaEndBar() {
83          return areaEndBar;
84      }
85  
86      public void setAreaEndBar(AreaEndBar areaEndBar) {
87          this.areaEndBar = areaEndBar;
88      }
89  
90      private ComponentPlaceHolder getComponentPlaceHolder() {
91          return componentPlaceHolder;
92      }
93  
94      public void setComponentPlaceHolder(ComponentPlaceHolder componentPlaceHolder) {
95          this.componentPlaceHolder = componentPlaceHolder;
96      }
97  
98      public void setComponentMarkerElement(Element componentElement) {
99          this.componentMarkerElement = componentElement;
100     }
101 
102     public Element getComponentMarkerElement() {
103         return componentMarkerElement;
104     }
105 
106     @Override
107     public AreaElement getTypedElement() {
108         String availableComponents = getAttribute("availableComponents");
109         AreaElementadin/gwt/client/shared/AreaElement.html#AreaElement">AreaElement area = new AreaElement(getAttribute("workspace"), getAttribute("path"), getAttribute("dialog"), availableComponents);
110 
111         boolean areaHasChildComponents = getComponents().size() > 0;
112         boolean optional = Boolean.parseBoolean(getAttribute("optional"));
113         boolean created = Boolean.parseBoolean(getAttribute("created"));
114         boolean hasAvailableComponents = availableComponents != null && !availableComponents.isEmpty();
115         boolean addible = true;
116         if (getAttributes().containsKey(OperationPermissionDefinition.ADDIBLE)) {
117             addible = Boolean.parseBoolean(getAttribute(OperationPermissionDefinition.ADDIBLE));
118         }
119 
120         area.setOptional(optional);
121         area.setCreated(created);
122         area.setAddible(addible && hasAvailableComponents && !(optional && !created) && !(isTypeSingle() && areaHasChildComponents) && !isMaxComponentsReached());
123 
124         return area;
125     }
126 
127     public boolean isTypeSingle() {
128         return "single".equals(getAttribute("type"));
129     }
130 
131     public boolean isMaxComponentsReached() {
132         boolean showAddButton = Boolean.parseBoolean(getAttribute("showAddButton"));
133         boolean showNewComponentArea = Boolean.parseBoolean(getAttribute("showNewComponentArea"));
134 
135         return showNewComponentArea && !showAddButton;
136     }
137 
138     @Override
139     public void createOptionalArea() {
140         eventBus.fireEvent(new NewAreaEvent(getTypedElement()));
141     }
142 
143     @Override
144     public void edit() {
145         eventBus.fireEvent(new EditAreaEvent(getTypedElement()));
146     }
147 
148     @Override
149     public void createNewComponent() {
150         eventBus.fireEvent(new NewComponentEvent(getTypedElement()));
151     }
152 
153     public boolean hasAddButton() {
154         boolean optional = Boolean.parseBoolean(getAttribute("optional"));
155         boolean created = Boolean.parseBoolean(getAttribute("created"));
156 
157         return optional && !created;
158     }
159 
160     public boolean hasEditButton() {
161         boolean optional = Boolean.parseBoolean(getAttribute("optional"));
162         boolean created = Boolean.parseBoolean(getAttribute("created"));
163         boolean dialog = null != getAttribute("dialog");
164 
165         if (dialog) {
166             // do not show edit-icon if the area has not been created
167             if (!optional || (optional && created)) {
168                 return true;
169             }
170         }
171         return false;
172     }
173 
174     public boolean hasAddComponentButton() {
175         return Boolean.parseBoolean(getAttribute("showAddButton"));
176     }
177 
178     public String getLabel() {
179         String label = getAttribute("label");
180         boolean optional = Boolean.parseBoolean(getAttribute("optional"));
181         return label + ((optional) ? " (optional)" : "");
182     }
183 
184     public boolean isBoxPlaceHolder() {
185         Element marker = getComponentMarkerElement();
186         boolean onlyBar = (marker != null && marker.getAttribute(AreaDefinition.CMS_ADD).equals("bar"));
187         return !onlyBar;
188     }
189 
190     public String getPlaceHolderLabel(Map<String, String> i18nKeys) {
191         String label = getAttribute("label");
192 
193         // if the add new component area should be visible
194         if (isMaxComponentsReached()) { // maximum of components is reached - show add new component area with the maximum reached message, but without the ADD button
195             return i18nKeys.get("pages.areas.maxComponentsReached");
196         }
197 
198         if (label != null && !label.isEmpty()) {
199             return i18nKeys.get("pages.areas.newLabelComponent").replace("{0}", label);
200         }
201 
202         // maximum of components is NOT reached - show add new component area with ADD button
203         return i18nKeys.get("pages.areas.newComponent");
204     }
205 
206     public int getActivationStatus() {
207         boolean isOptionalArea = Boolean.parseBoolean(getAttribute("optional"));
208         boolean isCreatedArea = Boolean.parseBoolean(getAttribute("created"));
209 
210         if (isOptionalArea && !isCreatedArea) {
211             return -1;
212         }else if (containsAttribute(ACTIVATION_STATUS_KEY)) {
213             return Integer.parseInt(getAttribute(ACTIVATION_STATUS_KEY));
214         }
215         return NodeTypes.Activatable.ACTIVATION_STATUS_NOT_ACTIVATED;
216     }
217 
218     public void removeFocus() {
219         if (getControlBar() != null) {
220             getControlBar().removeFocus();
221         }
222 
223         if (getAreaEndBar() != null) {
224             getAreaEndBar().removeFocus();
225         }
226     }
227 
228     public void removeBars() {
229         getComponents().forEach(MgnlComponent::removeBars);
230         if (getControlBar() != null) {
231             getControlBar().getElement().removeFromParent();
232         }
233         if (getAreaEndBar() != null) {
234             getAreaEndBar().getElement().removeFromParent();
235         }
236         if (getComponentPlaceHolder() != null) {
237             getComponentPlaceHolder().getElement().removeFromParent();
238         }
239     }
240 
241     public void setFocus(boolean child) {
242         if (getControlBar() != null) {
243             getControlBar().setFocus(child);
244         }
245         if (getAreaEndBar() != null) {
246             getAreaEndBar().setFocus(child);
247         }
248     }
249 
250     public void setVisible(boolean visible) {
251         if (getControlBar() != null) {
252             getControlBar().setVisible(visible);
253         }
254         if (getAreaEndBar() != null) {
255             getAreaEndBar().setVisible(visible);
256         }
257     }
258 
259     public void setPlaceHolderVisible(boolean visible) {
260         if (getComponentPlaceHolder() != null) {
261             getComponentPlaceHolder().setVisible(visible);
262         }
263     }
264 
265     public void toggleInitFocus(boolean visible) {
266         if (visible) {
267             getControlBar().addStyleName(EDITOR_INIT_CLASS_NAME);
268             getAreaEndBar().addStyleName(EDITOR_INIT_CLASS_NAME);
269             getAreaEndBar().addStyleName(EDITOR_INIT_CLASS_NAME);
270         } else {
271             getControlBar().removeStyleName(EDITOR_INIT_CLASS_NAME);
272             getAreaEndBar().removeStyleName(EDITOR_INIT_CLASS_NAME);
273         }
274     }
275 
276     public void onDragStart(boolean isDrag) {
277         if (getComponentPlaceHolder() != null) {
278             getComponentPlaceHolder().setStyleName("moveOngoing", isDrag);
279         }
280     }
281 }