You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/03/29 03:18:22 UTC
svn commit: r928556 [3/5] - in /myfaces/tomahawk/trunk/core20: ./
src/main/conf/META-INF/ src/main/java/org/apache/myfaces/custom/calendar/
src/main/java/org/apache/myfaces/custom/inputHtml/
src/main/java/org/apache/myfaces/custom/inputTextHelp/ src/ma...
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/HtmlTextHelpRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/HtmlTextHelpRenderer.java?rev=928556&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/HtmlTextHelpRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/inputTextHelp/HtmlTextHelpRenderer.java Mon Mar 29 01:18:21 2010
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.inputTextHelp;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.ConverterException;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+
+import org.apache.myfaces.renderkit.html.ext.HtmlTextRenderer;
+import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
+import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
+
+/**
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Input"
+ * type = "org.apache.myfaces.TextHelp"
+ *
+ * @author Thomas Obereder
+ * @version Date: 09.06.2005, 22:50:48
+ */
+@ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
+public class HtmlTextHelpRenderer extends HtmlTextRenderer implements ComponentSystemEventListener
+{
+ private static final String JAVASCRIPT_ENCODED = "org.apache.myfaces.inputTextHelp.JAVASCRIPT_ENCODED";
+
+ public void processEvent(ComponentSystemEvent event)
+ {
+ if(event.getComponent() instanceof HtmlInputTextHelp)
+ {
+ TomahawkResourceUtils.addOutputScriptResource(FacesContext.getCurrentInstance(),
+ "oam.custom.inputTextHelp",
+ "inputTextHelp.js");
+ }
+ }
+
+ protected void renderNormal(FacesContext facesContext, UIComponent component) throws IOException
+ {
+ if(component instanceof HtmlInputTextHelp)
+ {
+ HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
+ //addJavaScriptResources(facesContext);
+ renderInputTextHelp(facesContext, helpTextComp);
+ }
+ else
+ {
+ super.renderNormal(facesContext, component);
+ }
+ }
+
+ public static boolean isSelectText(UIComponent component)
+ {
+ if(component instanceof HtmlInputTextHelp)
+ {
+ HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
+ return helpTextComp.isSelectText();
+ }
+ return false;
+ }
+
+ public static String getHelpText(UIComponent component)
+ {
+ if(component instanceof HtmlInputTextHelp)
+ {
+ HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
+ if(helpTextComp.getHelpText() != null)
+ return helpTextComp.getHelpText();
+ }
+ return null;
+ }
+
+ public void renderInputTextHelp(FacesContext facesContext, UIInput input)
+ throws IOException
+ {
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ writer.startElement(HTML.INPUT_ELEM, input);
+
+ writer.writeAttribute(HTML.ID_ATTR, input.getClientId(facesContext), null);
+ writer.writeAttribute(HTML.NAME_ATTR, input.getClientId(facesContext), null);
+ writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT, null);
+
+ renderHelpTextAttributes(input, writer, facesContext);
+
+ String value = RendererUtils.getStringValue(facesContext, input);
+ value = (value==null || value.length()==0) ? getHelpText(input) : value;
+
+ if (value != null)
+ {
+ writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
+ }
+
+ writer.endElement(HTML.INPUT_ELEM);
+ }
+
+ private void renderHelpTextAttributes(UIComponent component,
+ ResponseWriter writer,
+ FacesContext facesContext)
+ throws IOException
+ {
+ if(!(component instanceof HtmlInputTextHelp) || getHelpText(component) == null || ("").equals(getHelpText(component).trim()))
+ {
+ HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+ }
+ else
+ {
+ String id = component.getClientId(facesContext);
+ HtmlInputTextHelp textHelp = (HtmlInputTextHelp)component;
+
+ HtmlRendererUtils.renderHTMLAttributes(writer, component,
+ HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK);
+ writer.writeAttribute(HTML.ONFOCUS_ATTR,
+ buildJavascriptFunction(component, id, textHelp.getOnfocus()), null);
+ writer.writeAttribute(HTML.ONCLICK_ATTR,
+ buildJavascriptFunction(component, id, textHelp.getOnclick()), null);
+ }
+
+ if (isDisabled(facesContext, component))
+ {
+ writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
+ }
+ }
+
+ private String buildJavascriptFunction(UIComponent component, String id, String componentScript)
+ {
+ StringBuffer jsFunction = new StringBuffer();
+ if(isSelectText(component))
+ {
+ jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_SELECT_TEXT);
+ jsFunction.append("('");
+ jsFunction.append( getHelpText(component)).append("', '");
+ jsFunction.append( id);
+ jsFunction.append("')");
+ }
+ else
+ {
+ jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_RESET_HELP );
+ jsFunction.append("('");
+ jsFunction.append( getHelpText(component)).append("', '");
+ jsFunction.append( id);
+ jsFunction.append("')");
+ }
+
+ if(componentScript != null && !("").equals(componentScript.trim())) {
+ jsFunction.append(";");
+ jsFunction.append(componentScript);
+ }
+
+ return jsFunction.toString();
+ }
+
+ public void decode(FacesContext facesContext, UIComponent component)
+ {
+ super.decode(facesContext, component);
+ }
+
+ public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue) throws ConverterException
+ {
+ if(submittedValue!=null && component instanceof HtmlInputTextHelp &&
+ ((HtmlInputTextHelp) component).getHelpText()!=null &&
+ submittedValue.equals(((HtmlInputTextHelp) component).getHelpText()))
+ {
+ submittedValue = "";
+ }
+
+ return super.getConvertedValue(facesContext, component, submittedValue);
+ }
+
+ /*public static void addJavaScriptResources(FacesContext facesContext)
+ {
+ // check to see if javascript has already been written (which could happen if more than one calendar on the same page)
+ if (facesContext.getExternalContext().getRequestMap().containsKey(JAVASCRIPT_ENCODED))
+ {
+ return;
+ }
+
+ AddResourceFactory.getInstance(facesContext).addJavaScriptAtPosition(
+ facesContext, AddResource.HEADER_BEGIN, HtmlTextHelpRenderer.class, "inputTextHelp.js");
+
+ facesContext.getExternalContext().getRequestMap().put(JAVASCRIPT_ENCODED, Boolean.TRUE);
+ }*/
+}
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/JsValueChangeListenerRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/JsValueChangeListenerRenderer.java?rev=928556&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/JsValueChangeListenerRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/jslistener/JsValueChangeListenerRenderer.java Mon Mar 29 01:18:21 2010
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.jslistener;
+
+import java.io.IOException;
+
+import javax.faces.application.Application;
+import javax.faces.application.ResourceDependency;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
+
+/**
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Output"
+ * type = "org.apache.myfaces.JsValueChangeListener"
+ *
+ * @author Martin Marinschek (latest modification by $Author: skitching $)
+ * @version $Revision: 673833 $ $Date: 2008-07-03 16:58:05 -0500 (jue, 03 jul 2008) $
+ */
+@ResourceDependency(library="oam.custom.jslistener",name="JSListener.js")
+public class JsValueChangeListenerRenderer
+ extends HtmlRenderer
+{
+ private static Log log = LogFactory.getLog(JsValueChangeListenerRenderer.class);
+
+ public void encodeEnd(FacesContext facesContext, UIComponent component)
+ throws IOException
+ {
+ RendererUtils.checkParamValidity(facesContext, component, JsValueChangeListener.class);
+
+ UIComponent parent = component.getParent();
+
+ JsValueChangeListener jsValueChangeListener = (JsValueChangeListener) component;
+
+
+ String aFor = jsValueChangeListener.getFor();
+ String expressionValue = jsValueChangeListener.getExpressionValue();
+ String property = jsValueChangeListener.getProperty();
+
+ //AddResourceFactory.getInstance(facesContext).addJavaScriptAtPosition(
+ // facesContext, AddResource.HEADER_BEGIN, JsValueChangeListenerRenderer.class,
+ // "JSListener.js");
+
+ if(aFor!=null)
+ {
+ UIComponent forComponent = component.findComponent(aFor);
+
+ String forComponentId = null;
+
+ if (forComponent == null)
+ {
+ if (log.isInfoEnabled())
+ {
+ log.info("Unable to find component '" + aFor + "' (calling findComponent on component '" + component.getClientId(getFacesContext()) + "') - will try to render component id based on the parent-id (on same level)");
+ }
+ if (aFor.length() > 0 && aFor.charAt(0) == UINamingContainer.SEPARATOR_CHAR)
+ {
+ //absolute id path
+ forComponentId = aFor.substring(1);
+ }
+ else
+ {
+ //relative id path, we assume a component on the same level as the label component
+ String labelClientId = component.getClientId(getFacesContext());
+ int colon = labelClientId.lastIndexOf(UINamingContainer.SEPARATOR_CHAR);
+ if (colon == -1)
+ {
+ forComponentId = aFor;
+ }
+ else
+ {
+ forComponentId = labelClientId.substring(0, colon + 1) + aFor;
+ }
+ }
+ }
+ else
+ {
+ forComponentId = forComponent.getClientId(getFacesContext());
+ }
+
+ expressionValue = expressionValue.replaceAll("\\'","\\\\'");
+ expressionValue = expressionValue.replaceAll("\"","\\\"");
+
+
+ String methodCall = "orgApacheMyfacesJsListenerSetExpressionProperty('"+
+ parent.getClientId(getFacesContext())+"','"+
+ forComponentId+"',"+
+ (property==null?"null":"'"+property+"'")+
+ ",'"+expressionValue+"');";
+
+
+ callMethod(facesContext, jsValueChangeListener, "onchange",methodCall);
+
+ if (jsValueChangeListener.getBodyTagEvent() != null)
+ {
+ callMethod(facesContext, jsValueChangeListener, jsValueChangeListener.getBodyTagEvent(), methodCall);
+ }
+
+ }
+ }
+
+ private void callMethod(FacesContext context, JsValueChangeListener jsValueChangeListener, String propName, String value)
+ {
+ UIComponent parent = jsValueChangeListener.getParent();
+
+ Object oldValue = parent.getAttributes().get(propName);
+
+ if(oldValue != null)
+ {
+ String oldValueStr = oldValue.toString().trim();
+
+ // render the jsValueChangeListener script only for each parent component
+ if(oldValueStr.indexOf(parent.getClientId(FacesContext.getCurrentInstance())) < 0
+ && oldValueStr.length() > 0)
+ {
+ oldValueStr = "";
+ }
+
+ if(oldValueStr.length()>0 && !oldValueStr.endsWith(";"))
+ oldValueStr +=";";
+
+ value = oldValueStr + value;
+
+ }
+
+ if (!propName.equals("onchange") && value != null)
+ {
+ //TODO: this should be refactored to register a javascript-event-wrapper the java-script way
+ //in the current version of AddResource, this would not work anymore
+ /*AddResourceFactory.getInstance(context).
+ addJavaScriptToBodyTag(context,jsValueChangeListener.getBodyTagEvent(), value);*/
+ }
+ else if(value != null)
+ {
+ parent.getAttributes().put(propName, value);
+ }
+ else
+ {
+ try
+ {
+ parent.getAttributes().remove(propName);
+ }
+ catch(Exception ex)
+ {
+ log.error("the value could not be removed : ",ex);
+ }
+ }
+ }
+
+
+ protected Application getApplication()
+ {
+ return getFacesContext().getApplication();
+ }
+
+ protected FacesContext getFacesContext()
+ {
+ return FacesContext.getCurrentInstance();
+ }
+
+}
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/HtmlNavigationMenuRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/HtmlNavigationMenuRenderer.java?rev=928556&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/HtmlNavigationMenuRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/htmlnavmenu/HtmlNavigationMenuRenderer.java Mon Mar 29 01:18:21 2010
@@ -0,0 +1,593 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.navmenu.htmlnavmenu;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIGraphic;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UISelectItems;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.ActionListener;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.custom.navmenu.NavigationMenuItem;
+import org.apache.myfaces.custom.navmenu.NavigationMenuUtils;
+import org.apache.myfaces.custom.navmenu.UINavigationMenuItem;
+import org.apache.myfaces.renderkit.html.ext.HtmlLinkRenderer;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
+import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
+
+/**
+ * Many thanks to the guys from Swiss Federal Institute of Intellectual Property & Marc Bouquet
+ * for helping to develop this component.
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Panel"
+ * type = "org.apache.myfaces.NavigationMenu"
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Command"
+ * type = "org.apache.myfaces.NavigationMenu"
+ *
+ * @author Thomas Spiegl
+ * @author Manfred Geiler
+ */
+@ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
+public class HtmlNavigationMenuRenderer extends HtmlLinkRenderer
+ implements ComponentSystemEventListener
+{
+ private static final Log log = LogFactory.getLog(HtmlNavigationMenuRenderer.class);
+
+ public static final String RENDERER_TYPE = "org.apache.myfaces.NavigationMenu";
+
+ private static final Integer ZERO_INTEGER = new Integer(0);
+
+ private static final String HORIZ_MENU_SCRIPT = "HMenuIEHover.js";
+
+ public void processEvent(ComponentSystemEvent event)
+ {
+ HtmlPanelNavigationMenu panelNav = (HtmlPanelNavigationMenu) event.getComponent();
+ if (HtmlNavigationMenuRendererUtils.isListLayout(panelNav))
+ {
+ if (panelNav.isRenderAll())
+ {
+ addResourcesToHeader(FacesContext.getCurrentInstance());
+ }
+ }
+ }
+
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ public void decode(FacesContext facesContext, UIComponent component) {
+ if (component instanceof HtmlCommandNavigationItem) {
+ //HtmlCommandNavigation
+ super.decode(facesContext, component);
+ }
+ }
+
+ public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
+ if (component instanceof HtmlCommandNavigationItem) {
+ //HtmlCommandNavigationItem
+ super.encodeBegin(facesContext, component);
+ }
+ }
+
+ public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException {
+ if (component instanceof HtmlCommandNavigationItem) {
+ //HtmlCommandNavigationItem
+ super.encodeChildren(facesContext, component);
+ }
+ }
+
+ public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
+ if (component instanceof HtmlCommandNavigationItem) {
+ //HtmlCommandNavigationItem
+ super.encodeEnd(facesContext, component);
+ return;
+ }
+ RendererUtils.checkParamValidity(facesContext, component, HtmlPanelNavigationMenu.class);
+ HtmlPanelNavigationMenu panelNav = (HtmlPanelNavigationMenu) component;
+
+ if (HtmlNavigationMenuRendererUtils.isListLayout(panelNav)) {
+ boolean preprocess = true;
+ boolean clientStateSaving = facesContext.getApplication().getStateManager().isSavingStateInClient(facesContext);
+ if (clientStateSaving) {
+ // client statesaving
+ HtmlPanelNavigationMenu panelNavPrev = findPreviousPanelNav(facesContext, panelNav);
+ if (panelNavPrev != null) {
+ preprocess = false;
+ if (!panelNavPrev.equals(panelNav)) {
+ // substitute panelnav
+ UIComponent parent = panelNav.getParent();
+ int insertPos = parent.getChildren().indexOf(panelNav);
+ parent.getChildren().set(insertPos, panelNavPrev);
+ panelNavPrev.setParent(parent);
+ panelNav.setParent(null);
+ panelNav = panelNavPrev;
+ }
+ }
+ }
+ else {
+ // server statesaving
+ if (panelNav.getPreprocessed() != null && panelNav.getPreprocessed().booleanValue())
+ preprocess = false;
+ }
+ if (preprocess) {
+ panelNav.setPreprocessed(Boolean.TRUE);
+ preprocessNavigationItems(facesContext, panelNav, panelNav.getChildren(), new UniqueId());
+ if (!clientStateSaving) {
+ HtmlPanelNavigationMenu panelNavPrev = findPreviousPanelNav(facesContext, panelNav);
+ if (panelNavPrev != null) {
+ restoreOpenActiveStates(facesContext, panelNav, panelNavPrev.getChildren());
+ }
+ }
+ }
+ // render list
+ if (log.isDebugEnabled())
+ HtmlNavigationMenuRendererUtils.debugTree(log, facesContext, panelNav.getChildren(), 0);
+ renderListLayout(facesContext, panelNav);
+ }
+ else {
+ renderTableLayout(facesContext, panelNav);
+ }
+ }
+
+ private void restoreOpenActiveStates(FacesContext facesContext,
+ HtmlPanelNavigationMenu panelNav, List children) {
+ for (int i = 0, size = children.size(); i < size; i++) {
+ UIComponent uiComponent = (UIComponent) children.get(i);
+ if (uiComponent instanceof HtmlCommandNavigationItem) {
+ HtmlCommandNavigationItem prevItem = (HtmlCommandNavigationItem) uiComponent;
+ if (prevItem.isOpen() || prevItem.isActive()) {
+ HtmlCommandNavigationItem item = (HtmlCommandNavigationItem) panelNav.findComponent(uiComponent.getClientId(facesContext));
+ if (item != null) {
+ if (item.getActiveDirectly() != null && item.getActiveDirectly().booleanValue()) {
+ item.setActive(prevItem.isActive());
+ }
+ else {
+ copyValueBinding(prevItem, item, "active");
+ }
+
+ if (item.getOpenDirectly() != null && item.getOpenDirectly().booleanValue()) {
+ item.setOpen(prevItem.isOpen());
+ }
+ else {
+ copyValueBinding(prevItem, item, "open");
+ }
+ if (!panelNav.isExpandAll() || prevItem.isActive())
+ item.toggleOpen();
+ if (prevItem.isOpen())
+ restoreOpenActiveStates(facesContext, panelNav, prevItem.getChildren());
+ }
+ }
+ }
+ }
+ }
+
+ private HtmlPanelNavigationMenu findPreviousPanelNav(FacesContext facesContext, HtmlPanelNavigationMenu panelNav) {
+ UIViewRoot previousViewRoot = findPreviousRoot(facesContext);
+ if (previousViewRoot != null) {
+ return (HtmlPanelNavigationMenu) previousViewRoot.findComponent(panelNav.getClientId(facesContext));
+ }
+ return null;
+ }
+
+ private UIViewRoot findPreviousRoot(FacesContext facesContext) {
+ return (UIViewRoot) facesContext.getExternalContext().getRequestMap().get(HtmlPanelNavigationMenu.PREVIOUS_VIEW_ROOT);
+ }
+
+ protected void renderListLayout(FacesContext facesContext, HtmlPanelNavigationMenu panelNav) throws IOException {
+ //if (panelNav.isRenderAll())
+ // addResourcesToHeader(facesContext);
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+ if (panelNav.getChildCount() > 0) {
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.UL_ELEM, panelNav);
+
+ HtmlRendererUtils.renderHTMLAttributes(writer, panelNav, HTML.UL_PASSTHROUGH_ATTRIBUTES);
+
+ //iterate over the tree and toggleOpen if viewId in item.getActiveOnVieIds()
+ activeOnViewId(panelNav, facesContext.getViewRoot().getViewId());
+ //iterate over the tree and set every item open if expandAll
+ if (panelNav.isExpandAll()) {
+ expandAll(panelNav);
+ }
+
+ HtmlNavigationMenuRendererUtils.renderChildrenListLayout(facesContext, writer, panelNav, panelNav.getChildren(), 0);
+
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.endElement(HTML.UL_ELEM);
+ }
+ else {
+ if (log.isWarnEnabled()) log.warn("PanelNavaigationMenu without children.");
+ }
+ }
+
+ private void renderTableLayout(FacesContext facesContext, HtmlPanelNavigationMenu panelNav) throws IOException {
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ if (panelNav.getChildCount() > 0) {
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TABLE_ELEM, panelNav);
+ HtmlRendererUtils.renderHTMLAttributes(writer, panelNav, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
+ if (panelNav.getStyle() == null && panelNav.getStyleClass() == null) {
+ writer.writeAttribute(HTML.BORDER_ATTR, ZERO_INTEGER, null);
+ }
+
+ HtmlNavigationMenuRendererUtils.renderChildrenTableLayout(facesContext, writer, panelNav, panelNav.getChildren(), 0);
+
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.endElement(HTML.TABLE_ELEM);
+ }
+ else {
+ if (log.isWarnEnabled()) log.warn("PanelNavaigationMenu without children.");
+ }
+ }
+
+ private void addResourcesToHeader(FacesContext context) {
+ //AddResource addResource = AddResourceFactory.getInstance(context);
+ //addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlPanelNavigationMenu.class, HORIZ_MENU_SCRIPT);
+ TomahawkResourceUtils.addOutputScriptResource(context,
+ "oam.custom.navmenu.htmlnavmenu", HORIZ_MENU_SCRIPT);
+ }
+
+ /**
+ * look for UINavigationMenuItem && UISelectItems & create components
+ */
+ private void preprocessNavigationItems(FacesContext facesContext, UIComponent parent,
+ List children, UniqueId uniqueId) {
+ for (int i = 0; i < children.size(); i++) {
+ UIComponent child = (UIComponent) children.get(i);
+
+ if (child instanceof HtmlCommandNavigationItem) {
+ HtmlCommandNavigationItem navMenuItem = (HtmlCommandNavigationItem) child;
+ preprocessNavigationItems(facesContext, navMenuItem, navMenuItem.getChildren(), uniqueId);
+ }
+ else if (child instanceof UINavigationMenuItem) {
+ UINavigationMenuItem uiNavMenuItem = (UINavigationMenuItem) child;
+ createHtmlCommandNavigationItem(facesContext, parent, i, uiNavMenuItem, uniqueId);
+ }
+ else if (child instanceof UISelectItems) {
+ List list = new ArrayList();
+ if (child.getId() == null) {
+ child.setId("testit");
+ }
+ NavigationMenuUtils.addNavigationMenuItems((UISelectItems) child, list);
+ addUINavigationMenuItems(facesContext, parent, children, i + 1, list);
+ }
+ }
+ }
+
+ private void addUINavigationMenuItems(FacesContext facesContext, UIComponent parent, List children, int startIndex, List menuItems) {
+ String clientId = parent.getClientId(facesContext);
+ clientId = clientId.replaceAll(":", "_");
+ for (int j = 0, sizej = menuItems.size(); j < sizej; j++) {
+ NavigationMenuItem navigationMenuItem = (NavigationMenuItem) menuItems.get(j);
+ UINavigationMenuItem uiNavigationMenuItem =
+ (UINavigationMenuItem) facesContext.getApplication().createComponent(UINavigationMenuItem.COMPONENT_TYPE);
+ uiNavigationMenuItem.setId(clientId + "_uinavmitem" + (startIndex + j));
+ uiNavigationMenuItem.getClientId(facesContext); // create clientid
+ children.add(startIndex++, uiNavigationMenuItem);
+ uiNavigationMenuItem.setParent(parent);
+ if (navigationMenuItem.getAction() != null) {
+ uiNavigationMenuItem.setAction(HtmlNavigationMenuRendererUtils.getMethodBinding(facesContext, navigationMenuItem.getAction(), false));
+ }
+ if (navigationMenuItem.getActionListener() != null) {
+ uiNavigationMenuItem.setActionListener(HtmlNavigationMenuRendererUtils.getMethodBinding(facesContext,
+ navigationMenuItem.getActionListener(), true));
+ }
+ uiNavigationMenuItem.setIcon(navigationMenuItem.getIcon());
+ uiNavigationMenuItem.setRendered(navigationMenuItem.isRendered());
+ uiNavigationMenuItem.setActiveOnViewIds(navigationMenuItem.getActiveOnViewIds());
+ uiNavigationMenuItem.setSplit(navigationMenuItem.isSplit());
+ uiNavigationMenuItem.setItemLabel(navigationMenuItem.getLabel());
+ uiNavigationMenuItem.setOpen(navigationMenuItem.isOpen());
+ uiNavigationMenuItem.setActive(navigationMenuItem.isActive());
+ uiNavigationMenuItem.setValue(navigationMenuItem.getValue());
+ HtmlNavigationMenuRendererUtils.setAttributeValue(facesContext, uiNavigationMenuItem,
+ "externalLink", navigationMenuItem.getExternalLink());
+ //uiNavigationMenuItem.setExternalLink(navigationMenuItem.getExternalLink());
+ uiNavigationMenuItem.setTransient(false);
+ uiNavigationMenuItem.setTarget(navigationMenuItem.getTarget());
+ uiNavigationMenuItem.setDisabled(navigationMenuItem.isDisabled());
+ uiNavigationMenuItem.setDisabledStyle(navigationMenuItem.getDisabledStyle());
+ uiNavigationMenuItem.setDisabledStyleClass(navigationMenuItem.getDisabledStyleClass());
+
+ if (navigationMenuItem.getNavigationMenuItems() != null && navigationMenuItem.getNavigationMenuItems().length > 0)
+ {
+ addUINavigationMenuItems(facesContext, uiNavigationMenuItem, uiNavigationMenuItem.getChildren(), 0,
+ Arrays.asList(navigationMenuItem.getNavigationMenuItems()));
+ }
+ }
+ }
+
+ private HtmlPanelNavigationMenu getParentPanelNavigation(UIComponent uiComponent) {
+ if (uiComponent instanceof HtmlPanelNavigationMenu) {
+ return (HtmlPanelNavigationMenu) uiComponent;
+ }
+ UIComponent parent = uiComponent.getParent();
+
+ // search HtmlPanelNavigation
+ UIComponent p = parent;
+ while (p != null && !(p instanceof HtmlPanelNavigationMenu)) {
+ p = p.getParent();
+ }
+ // p is now the HtmlPanelNavigation
+ if (p == null) {
+ log.error("HtmlCommandNavigation without parent HtmlPanelNavigation ?!");
+ return null;
+ }
+ return (HtmlPanelNavigationMenu) p;
+ }
+
+ private void createHtmlCommandNavigationItem(FacesContext facesContext, UIComponent parent, int i,
+ UINavigationMenuItem uiNavMenuItem, UniqueId uniqueId) {
+ HtmlPanelNavigationMenu menu = getParentPanelNavigation(parent);
+ // Create HtmlCommandNavigationItem
+ HtmlCommandNavigationItem newItem = (HtmlCommandNavigationItem)
+ facesContext.getApplication().createComponent(HtmlCommandNavigationItem.COMPONENT_TYPE);
+ String parentId = parent.getClientId(facesContext);
+ parentId = parentId.replaceAll(":", "_");
+ int id = uniqueId.next();
+ newItem.setId(parentId + "_item" + id);
+ newItem.getClientId(facesContext); // create clientid
+ newItem.setRendererType(RENDERER_TYPE);
+ parent.getChildren().add(i + 1, newItem);
+ newItem.setParent(parent);
+ // set action & actionListner
+ newItem.setAction(uiNavMenuItem.getAction());
+ newItem.setActionListener(uiNavMenuItem.getActionListener());
+ ActionListener[] listeners = uiNavMenuItem.getActionListeners();
+ for (int j = 0; j < listeners.length; j++) {
+ newItem.addActionListener(listeners[j]);
+ }
+ // value
+ newItem.setValue(uiNavMenuItem.getValue());
+ // immeditate
+ if (!copyValueBinding(uiNavMenuItem, newItem, "immediate"))
+ newItem.setImmediate(uiNavMenuItem.isImmediate());
+ // transient, rendered
+ if (!copyValueBinding(uiNavMenuItem, newItem, "transient"))
+ newItem.setTransient(uiNavMenuItem.isTransient());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "rendered"))
+ newItem.setRendered(uiNavMenuItem.isRendered());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "externalLink"))
+ newItem.setExternalLink(uiNavMenuItem.getExternalLink());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "activeOnViewIds"))
+ newItem.setActiveOnViewIds(uiNavMenuItem.getActiveOnViewIds());
+
+ if (uiNavMenuItem.isOpen() && ! menu.isExpandAll())
+ newItem.toggleOpen();
+
+ if (uiNavMenuItem.getActiveDirectly() != null) {
+ newItem.setActive(uiNavMenuItem.isActive());
+ }
+ else {
+ newItem.setValueBinding("active", uiNavMenuItem.getValueBinding("active"));
+ }
+
+ if (!copyValueBinding(uiNavMenuItem, newItem, "target"))
+ newItem.setTarget(uiNavMenuItem.getTarget());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "disabled"))
+ newItem.setDisabled(uiNavMenuItem.isDisabled());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "disabledStyle"))
+ newItem.setDisabledStyle(uiNavMenuItem.getDisabledStyle());
+ if (!copyValueBinding(uiNavMenuItem, newItem, "disabledStyleClass"))
+ newItem.setDisabledStyleClass(uiNavMenuItem.getDisabledStyleClass());
+
+ if (uiNavMenuItem.getActiveOnViewIdsDirectly() != null) {
+ newItem.setActiveOnViewIds(uiNavMenuItem.getActiveOnViewIdsDirectly());
+ }
+
+ // If the parent-Element is disabled the child is disabled as well
+ if (parent instanceof HtmlPanelNavigationMenu) {
+ if (newItem.getDisabledStyle() == null) {
+ newItem.setDisabledStyle(
+ ((HtmlPanelNavigationMenu) parent).getDisabledStyle()
+ );
+ }
+ if (newItem.getDisabledStyleClass() == null) {
+ newItem.setDisabledStyleClass(
+ ((HtmlPanelNavigationMenu) parent).getDisabledStyleClass()
+ );
+ }
+ if (((HtmlPanelNavigationMenu) parent).isDisabled()) {
+ newItem.setDisabled(true);
+ }
+ }
+ if (parent instanceof HtmlCommandNavigationItem) {
+ if (newItem.getDisabledStyle() == null) {
+ newItem.setDisabledStyle(
+ ((HtmlCommandNavigationItem) parent).getDisabledStyle()
+ );
+ }
+ if (newItem.getDisabledStyleClass() == null) {
+ newItem.setDisabledStyleClass(
+ ((HtmlCommandNavigationItem) parent).getDisabledStyleClass()
+ );
+ }
+ if (((HtmlCommandNavigationItem) parent).isDisabled()) {
+ newItem.setDisabled(true);
+ }
+ }
+
+ if (uiNavMenuItem.getIcon() != null) {
+ UIGraphic uiGraphic = (UIGraphic) facesContext.getApplication().createComponent(UIGraphic.COMPONENT_TYPE);
+ uiGraphic.setId(parentId + "_img" + id);
+ uiGraphic.getClientId(facesContext);
+ newItem.getChildren().add(uiGraphic);
+ uiGraphic.setParent(newItem);
+ if (NavigationMenuUtils.isValueReference(uiNavMenuItem.getIcon())) {
+ uiGraphic.setValueBinding("value",
+ facesContext.getApplication().createValueBinding(uiNavMenuItem.getIcon()));
+ }
+ else {
+ uiGraphic.setValue(uiNavMenuItem.getIcon());
+ }
+ }
+
+ else {
+ // Create and add UIOutput
+ UIOutput uiOutput = (UIOutput) facesContext.getApplication().createComponent(UIOutput.COMPONENT_TYPE);
+ uiOutput.setId(parentId + "_txt" + id);
+ uiOutput.getClientId(facesContext); // create clientid
+ newItem.getChildren().add(uiOutput);
+ uiOutput.setParent(newItem);
+ if (uiNavMenuItem.getItemLabel() != null) {
+ if (NavigationMenuUtils.isValueReference(uiNavMenuItem.getItemLabel())) {
+ uiOutput.setValueBinding("value",
+ facesContext.getApplication().createValueBinding(uiNavMenuItem.getItemLabel()));
+ }
+ else {
+ uiOutput.setValue(uiNavMenuItem.getItemLabel());
+ }
+ }
+ else {
+ Object value = uiNavMenuItem.getValue();
+ if (value != null &&
+ NavigationMenuUtils.isValueReference(value.toString())) {
+ uiOutput.setValueBinding("value",
+ facesContext.getApplication().createValueBinding(value.toString()));
+ }
+ else {
+ uiOutput.setValue(uiNavMenuItem.getValue());
+ }
+ }
+ }
+ // process next level
+ log.debug("Instance of UINavigationMenuItem, preprocess childrens");
+ preprocessNavigationItems(facesContext, newItem, uiNavMenuItem.getChildren(), uniqueId);
+ }
+
+ private boolean copyValueBinding(UIComponent source, UIComponent target, String binding) {
+ ValueBinding valueBinding = source.getValueBinding(binding);
+ if (valueBinding == null)
+ return false;
+ target.setValueBinding(binding, valueBinding);
+ return true;
+ }
+
+// protected
+
+ protected String getStyle(FacesContext facesContext, UIComponent link) {
+ if (!(link instanceof HtmlCommandNavigationItem)) {
+ throw new IllegalArgumentException("expected instance of " + HtmlCommandNavigationItem.class.getName());
+ }
+
+ UIComponent navPanel = HtmlNavigationMenuRendererUtils.getPanel(link);
+
+ HtmlCommandNavigationItem navItem = (HtmlCommandNavigationItem) link;
+ if (navItem.isActive()) {
+ return ((HtmlPanelNavigationMenu) navPanel).getActiveItemStyle();
+ }
+ else if (navItem.isOpen()) {
+ return ((HtmlPanelNavigationMenu) navPanel).getOpenItemStyle();
+ }
+ else {
+ return ((HtmlPanelNavigationMenu) navPanel).getItemStyle();
+ }
+ }
+
+ protected String getStyleClass(FacesContext facesContext, UIComponent link) {
+ if (!(link instanceof HtmlCommandNavigationItem)) {
+ throw new IllegalArgumentException();
+ }
+
+ UIComponent navPanel = HtmlNavigationMenuRendererUtils.getPanel(link);
+
+ HtmlCommandNavigationItem navItem = (HtmlCommandNavigationItem) link;
+ if (navItem.isActive()) {
+ return ((HtmlPanelNavigationMenu) navPanel).getActiveItemClass();
+ }
+ else if (navItem.isOpen()) {
+ return ((HtmlPanelNavigationMenu) navPanel).getOpenItemClass();
+ }
+ else {
+ return ((HtmlPanelNavigationMenu) navPanel).getItemClass();
+ }
+ }
+
+ private static class UniqueId {
+ private int _id;
+
+ public int next() {
+ return _id++;
+ }
+
+ public void decrease() {
+ _id--;
+ }
+ }
+
+ private void expandAll(UIComponent parent) {
+ //Recurse over all Children setOpen if child is HtmlCommandNavigationItem
+ if (parent instanceof HtmlCommandNavigationItem) {
+ HtmlCommandNavigationItem navItem = (HtmlCommandNavigationItem) parent;
+ navItem.setOpen(true);
+ }
+ List children = parent.getChildren();
+ UIComponent child;
+ for (int i = 0; i < children.size(); i++) {
+ child = (UIComponent) children.get(i);
+ expandAll(child);
+ }
+ }
+
+ private void activeOnViewId(UIComponent parent, String viewId) {
+ //Recurse over all Children setOpen if child is HtmlCommandNavigationItem
+ if (parent instanceof HtmlCommandNavigationItem) {
+ HtmlCommandNavigationItem navItem = (HtmlCommandNavigationItem) parent;
+ String[] viewIds = navItem.getActiveOnVieIds();
+ for (int i = 0; i < viewIds.length; i++) {
+ if (viewId.equals(viewIds[i])) {
+ navItem.toggleOpen();
+ navItem.setActive(true);
+ return;
+ }
+ }
+ ;
+ }
+ List children = parent.getChildren();
+ UIComponent child;
+ for (int i = 0; i < children.size(); i++) {
+ child = (UIComponent) children.get(i);
+ activeOnViewId(child, viewId);
+ }
+ }
+}
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java?rev=928556&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/navmenu/jscookmenu/HtmlJSCookMenuRenderer.java Mon Mar 29 01:18:21 2010
@@ -0,0 +1,573 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.navmenu.jscookmenu;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.faces.FacesException;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.el.MethodBinding;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.ComponentSystemEventListener;
+import javax.faces.event.ListenerFor;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.custom.navmenu.NavigationMenuItem;
+import org.apache.myfaces.custom.navmenu.NavigationMenuUtils;
+import org.apache.myfaces.custom.navmenu.UINavigationMenuItem;
+import org.apache.myfaces.renderkit.html.util.AddResource;
+import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
+import org.apache.myfaces.shared_tomahawk.el.SimpleActionMethodBinding;
+import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlFormRendererBase;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.util.FormInfo;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
+import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
+import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
+
+/**
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Command"
+ * type = "org.apache.myfaces.JSCookMenu"
+ *
+ * @author Thomas Spiegl
+ * @version $Revision: 698742 $ $Date: 2008-09-24 16:25:46 -0500 (mié, 24 sep 2008) $
+ */
+@ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
+public class HtmlJSCookMenuRenderer
+ extends HtmlRenderer implements ComponentSystemEventListener
+{
+ private static final String MYFACES_HACK_SCRIPT = "MyFacesHack.js";
+
+ private static final String JSCOOK_MENU_SCRIPT = "JSCookMenu.js";
+
+ private static final String JSCOOK_EFFECT_SCRIPT = "effect.js";
+
+ private static final Log log = LogFactory.getLog(HtmlJSCookMenuRenderer.class);
+
+ private static final String JSCOOK_ACTION_PARAM = "jscook_action";
+ private static final Class[] ACTION_LISTENER_ARGS = {ActionEvent.class};
+
+ private static final Map builtInThemes = new java.util.HashMap();
+
+ static {
+ builtInThemes.put("ThemeOffice", "ThemeOffice/");
+ builtInThemes.put("ThemeMiniBlack", "ThemeMiniBlack/");
+ builtInThemes.put("ThemeIE", "ThemeIE/");
+ builtInThemes.put("ThemePanel", "ThemePanel/");
+ builtInThemes.put("ThemeGray", "ThemeGray/");
+ }
+
+ public void processEvent(ComponentSystemEvent event)
+ {
+ HtmlCommandJSCookMenu menu = (HtmlCommandJSCookMenu) event.getComponent();
+ String theme = menu.getTheme();
+ if (theme == null) {
+ // should never happen; theme is a required attribute in the jsp tag definition
+ throw new IllegalArgumentException("theme name is mandatory for a jscookmenu.");
+ }
+
+ addResourcesToHeader(theme, menu, FacesContext.getCurrentInstance());
+ }
+
+ public void decode(FacesContext context, UIComponent component) {
+ RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);
+
+ Map parameter = context.getExternalContext().getRequestParameterMap();
+ String actionParam = (String) parameter.get(JSCOOK_ACTION_PARAM);
+ if (actionParam != null && !actionParam.trim().equals("") &&
+ !actionParam.trim().equals("null")) {
+ String compId = getMenuId(context, component);
+ StringTokenizer tokenizer = new StringTokenizer(actionParam, ":");
+ if (tokenizer.countTokens() > 1) {
+ String actionId = tokenizer.nextToken();
+ if (! compId.equals(actionId)) {
+ return;
+ }
+ while (tokenizer.hasMoreTokens()) {
+ String action = tokenizer.nextToken();
+ if (action.startsWith("A]")) {
+ action = action.substring(2, action.length());
+ action = decodeValueBinding(action, context);
+ MethodBinding mb;
+ if (NavigationMenuUtils.isValueReference(action)) {
+ mb = context.getApplication().createMethodBinding(action, null);
+ }
+ else {
+ mb = new SimpleActionMethodBinding(action);
+ }
+ ((HtmlCommandJSCookMenu) component).setAction(mb);
+ }
+ else if (action.startsWith("L]")) {
+ action = action.substring(2, action.length());
+ String value = null;
+ int idx = action.indexOf(";");
+ if (idx > 0 && idx < action.length() - 1) {
+ value = action.substring(idx + 1, action.length());
+ action = action.substring(0, idx);
+ ((HtmlCommandJSCookMenu) component).setValue(value);
+ }
+ else if (idx == action.length() - 1)
+ {
+ value = null; //No Value found, so set it to null as expected
+ action = action.substring(0, idx);
+ }
+ MethodBinding mb;
+ if (NavigationMenuUtils.isValueReference(action)) {
+ mb = context.getApplication().createMethodBinding(action, ACTION_LISTENER_ARGS);
+ ((HtmlCommandJSCookMenu) component).setActionListener(mb);
+ if (value != null)
+ ((HtmlCommandJSCookMenu) component).setValue(value);
+ }
+ }
+ }
+ }
+ component.queueEvent(new ActionEvent(component));
+ }
+ }
+
+ private String decodeValueBinding(String actionParam, FacesContext context) {
+ int idx = actionParam.indexOf(";#{");
+ if (idx == -1) {
+ return actionParam;
+ }
+
+ String newActionParam = actionParam.substring(0, idx);
+ String vbParam = actionParam.substring(idx + 1);
+
+ idx = vbParam.indexOf('=');
+ if (idx == -1) {
+ return newActionParam;
+ }
+ String vbExpressionString = vbParam.substring(0, idx);
+ String vbValue = vbParam.substring(idx + 1);
+
+ ValueBinding vb =
+ context.getApplication().createValueBinding(vbExpressionString);
+ vb.setValue(context, vbValue);
+
+ return newActionParam;
+ }
+
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
+ RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);
+
+ List list = NavigationMenuUtils.getNavigationMenuItemList(component);
+ if (list.size() > 0) {
+ FormInfo parentFormInfo = RendererUtils.findNestingForm(component, context);
+ ResponseWriter writer = context.getResponseWriter();
+
+ if (parentFormInfo == null)
+ throw new FacesException("jscook menu is not embedded in a form.");
+ String formName = parentFormInfo.getFormName();
+ List uiNavMenuItemList = component.getChildren();
+ /* todo: disabled for now. Check if dummy form stuff is still needed/desired
+ if( formName == null ) {
+ DummyFormUtils.setWriteDummyForm(context,true);
+ DummyFormUtils.addDummyFormParameter(context,JSCOOK_ACTION_PARAM);
+
+ formName = DummyFormUtils.getDummyFormName();
+ }
+ else {*/
+ if (RendererUtils.isAdfOrTrinidadForm(parentFormInfo.getForm())) {
+ // need to add hidden input, cause MyFaces form is missing hence will not render hidden inputs
+ writer.write("<input type=\"hidden\" name=\"");
+ writer.write(JSCOOK_ACTION_PARAM);
+ writer.write("\" />");
+ }
+ else {
+ HtmlFormRendererBase.addHiddenCommandParameter(context, parentFormInfo.getForm(), JSCOOK_ACTION_PARAM);
+ }
+
+ //}
+
+ String myId = getMenuId(context, component);
+
+ writer.startElement(HTML.SCRIPT_ELEM, component);
+ writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+ StringBuffer script = new StringBuffer();
+ script.append("var ").append(getMenuId(context, component)).append(" =\n[");
+ encodeNavigationMenuItems(context, script,
+ (NavigationMenuItem[]) list.toArray(new NavigationMenuItem[list.size()]),
+ uiNavMenuItemList,
+ myId, formName);
+
+ script.append("];");
+ writer.writeText(script.toString(), null);
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
+ }
+
+ private void encodeNavigationMenuItems(FacesContext context,
+ StringBuffer writer,
+ NavigationMenuItem[] items,
+ List uiNavMenuItemList,
+ String menuId, String formName)
+ throws IOException {
+ for (int i = 0; i < items.length; i++) {
+ NavigationMenuItem item = items[i];
+ Object tempObj = null;
+ UINavigationMenuItem uiNavMenuItem = null;
+ if (i < uiNavMenuItemList.size()) {
+ tempObj = uiNavMenuItemList.get(i);
+ }
+ if (tempObj != null) {
+ if (tempObj instanceof UINavigationMenuItem) {
+ uiNavMenuItem = (UINavigationMenuItem) tempObj;
+ }
+ }
+
+ if (! item.isRendered()) {
+ continue;
+ }
+
+ if (i > 0) {
+ writer.append(",\n");
+ }
+
+ if (item.isSplit()) {
+ writer.append("_cmSplit,");
+
+ if (item.getLabel().equals("0")) {
+ continue;
+ }
+ }
+
+ writer.append("[");
+ if (item.getIcon() != null) {
+ String iconSrc = context.getApplication().getViewHandler().getResourceURL(context, item.getIcon());
+ writer.append("'<img src=\"");
+ writer.append(context.getExternalContext().encodeResourceURL(iconSrc));
+ writer.append("\"/>'");
+ }
+ else {
+ writer.append("null");
+ }
+ writer.append(", '");
+ if (item.getLabel() != null) {
+ writer.append(getString(context, item.getLabel()));
+ }
+ writer.append("', ");
+ StringBuffer actionStr = new StringBuffer();
+ if ((item.getAction() != null || item.getActionListener() != null) && ! item.isDisabled()) {
+ actionStr.append("'");
+ actionStr.append(menuId);
+ if (item.getActionListener() != null) {
+ actionStr.append(":L]");
+ actionStr.append(item.getActionListener());
+ if (uiNavMenuItem != null && uiNavMenuItem.getItemValue() != null) {
+ actionStr.append(';');
+ actionStr.append(getString(context, uiNavMenuItem.getItemValue()));
+ }
+ else if (item.getValue() != null) {
+ actionStr.append(';');
+ actionStr.append(getString(context, item.getValue()));
+ }
+ }
+ if (item.getAction() != null) {
+ actionStr.append(":A]");
+ actionStr.append(item.getAction());
+ if (uiNavMenuItem != null) {
+ encodeValueBinding(actionStr, uiNavMenuItem, item);
+ }
+ }
+ actionStr.append("'");
+ writer.append(actionStr.toString());
+ }
+ else {
+ writer.append("null");
+ }
+ writer.append(", '");
+ // Change here to allow the use of non dummy form.
+ writer.append(formName);
+ writer.append("', null");
+
+ if (item.isRendered() && ! item.isDisabled()) {
+ // render children only if parent is visible/enabled
+ NavigationMenuItem[] menuItems = item.getNavigationMenuItems();
+ if (menuItems != null && menuItems.length > 0) {
+ writer.append(",");
+ if (uiNavMenuItem != null) {
+ encodeNavigationMenuItems(context, writer, menuItems,
+ uiNavMenuItem.getChildren(), menuId, formName);
+ }
+ else {
+ encodeNavigationMenuItems(context, writer, menuItems,
+ new ArrayList(1), menuId, formName);
+ }
+ }
+ }
+ writer.append("]");
+ }
+ }
+
+ private String getString(FacesContext facesContext, Object value) {
+ String str = "";
+
+ if (value != null) {
+ str = value.toString();
+ }
+
+ if (NavigationMenuUtils.isValueReference(str)) {
+ value = facesContext.getApplication().createValueBinding(str).getValue(facesContext);
+
+ if (value != null) {
+ str = value.toString();
+ }
+ else {
+ str = "";
+ }
+ }
+
+ return JavascriptUtils.encodeString(str);
+ }
+
+ private void encodeValueBinding(StringBuffer writer, UINavigationMenuItem uiNavMenuItem,
+ NavigationMenuItem item) {
+ ValueBinding vb = uiNavMenuItem.getValueBinding("NavMenuItemValue");
+ if (vb == null) {
+ return;
+ }
+ String vbExpression = vb.getExpressionString();
+ if (vbExpression == null) {
+ return;
+ }
+ Object tempObj = item.getValue();
+ if (tempObj == null) {
+ return;
+ }
+
+ writer.append(";");
+ writer.append(vbExpression);
+ writer.append("=");
+ writer.append(tempObj.toString());
+ }
+
+ public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
+ /*
+ HtmlCommandJSCookMenu menu = (HtmlCommandJSCookMenu) component;
+ String theme = menu.getTheme();
+ if (theme == null) {
+ // should never happen; theme is a required attribute in the jsp tag definition
+ throw new IllegalArgumentException("theme name is mandatory for a jscookmenu.");
+ }
+
+ addResourcesToHeader(theme, menu, context);
+ */
+ }
+
+ public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
+ RendererUtils.checkParamValidity(context, component, HtmlCommandJSCookMenu.class);
+ HtmlCommandJSCookMenu menu = (HtmlCommandJSCookMenu) component;
+ String theme = menu.getTheme();
+
+
+ ResponseWriter writer = context.getResponseWriter();
+
+ String menuId = getMenuId(context, component);
+
+ writer.write("<div id=\"");
+ writer.write(menuId);
+ writer.write("\"></div>\n");
+ writer.startElement(HTML.SCRIPT_ELEM, menu);
+ writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+
+ StringBuffer buf = new StringBuffer();
+ buf.append("\tif(window.cmDraw!=undefined) { cmDraw ('").
+ append(menuId).
+ append("', ").
+ append(menuId).
+ append(", '").
+ append(menu.getLayout()).
+ append("', cm").
+ append(theme).
+ append(", '").
+ append(theme).
+ append("');}");
+
+ writer.writeText(buf.toString(), null);
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
+
+ private void addResourcesToHeader(String themeName, HtmlCommandJSCookMenu menu, FacesContext context) {
+ String javascriptLocation = (String) menu.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
+ String imageLocation = (String) menu.getAttributes().get(JSFAttr.IMAGE_LOCATION);
+ String styleLocation = (String) menu.getAttributes().get(JSFAttr.STYLE_LOCATION);
+
+ AddResource addResource = AddResourceFactory.getInstance(context);
+
+ if (javascriptLocation != null) {
+ addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, javascriptLocation + "/" + JSCOOK_MENU_SCRIPT);
+ addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, javascriptLocation + "/" + JSCOOK_EFFECT_SCRIPT);
+ addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, javascriptLocation + "/" + MYFACES_HACK_SCRIPT);
+ }
+ else {
+ //addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlJSCookMenuRenderer.class, JSCOOK_MENU_SCRIPT);
+ TomahawkResourceUtils.addOutputScriptResource(context, "oam.custom.navmenu.jscookmenu", JSCOOK_MENU_SCRIPT);
+ //addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlJSCookMenuRenderer.class, JSCOOK_EFFECT_SCRIPT);
+ TomahawkResourceUtils.addOutputScriptResource(context, "oam.custom.navmenu.jscookmenu", JSCOOK_EFFECT_SCRIPT);
+ //addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlJSCookMenuRenderer.class, MYFACES_HACK_SCRIPT);
+ TomahawkResourceUtils.addOutputScriptResource(context, "oam.custom.navmenu.jscookmenu", MYFACES_HACK_SCRIPT);
+ }
+
+ addThemeSpecificResources(themeName, styleLocation, javascriptLocation, imageLocation, context);
+ }
+
+ /**
+ * A theme for a menu requires a number of external files; this method
+ * outputs those into the page head section.
+ *
+ * @param themeName is the name of the theme for this menu. It is never
+ * null. It may match one of the built-in theme names or may be a custom
+ * theme defined by the application.
+ * @param styleLocation is the URL of a directory containing a
+ * "theme.css" file. A stylesheet link tag will be inserted into
+ * the page header referencing that file. If null then if the
+ * themeName is a built-in one then a reference to the appropriate
+ * built-in stylesheet is generated (requires the ExtensionsFilter).
+ * If null and a custom theme is used then no stylesheet link will be
+ * generated here.
+ * @param javascriptLocation is the URL of a directory containing a
+ * "theme.js" file. A script tag will be inserted into the page header
+ * referencing that file. If null then if the themeName is a built-in
+ * one then a reference to the built-in stylesheet is generated (requires
+ * the ExtensionsFilter). If null and a custom theme is used then no
+ * stylesheet link will be generated here.
+ * @param imageLocation is the URL of a directory containing files
+ * (esp. image files) used by the theme.js file to define the menu
+ * theme. A javascript variable of name "my{themeName}Base" is
+ * generated in the page header containing this URL, so that the
+ * theme.js script can locate the files. If null then if the themeName
+ * is a built-in one then the URL to the appropriate resource directory
+ * is generated (requires the ExtensionsFilter). If null and a custom
+ * theme is used then no javascript variable will be generated here.
+ * @param context is the current faces context.
+ */
+ private void addThemeSpecificResources(String themeName, String styleLocation,
+ String javascriptLocation, String imageLocation, FacesContext context) {
+ String themeLocation = (String) builtInThemes.get(themeName);
+ if (themeLocation == null) {
+ log.debug("Unknown theme name '" + themeName + "' specified.");
+ }
+
+ AddResource addResource = AddResourceFactory.getInstance(context);
+
+ if ((imageLocation != null) || (themeLocation != null)) {
+ // Generate a javascript variable containing a reference to the
+ // directory containing theme image files, for use by the theme
+ // javascript file. If neither of these is defined (ie a custom
+ // theme was specified but no imageLocation) then presumably the
+ // theme.js file uses some other mechanism to determine where
+ // its image files are.
+ StringBuffer buf = new StringBuffer();
+ buf.append("var my");
+ buf.append(themeName);
+ buf.append("Base='");
+ ExternalContext externalContext = context.getExternalContext();
+ if (imageLocation != null) {
+ buf.append(externalContext.encodeResourceURL(addResource.getResourceUri(context,
+ imageLocation + "/" + themeName)));
+ }
+ else {
+ //buf.append(externalContext.encodeResourceURL(addResource.getResourceUri(context,
+ // HtmlJSCookMenuRenderer.class, themeLocation)));
+ Resource resource = context.getApplication().getResourceHandler().
+ createResource(";j","oam.custom.navmenu.jscookmenu."+themeName);
+ buf.append(resource.getRequestPath());
+ }
+ buf.append("';");
+ addResource.addInlineScriptAtPosition(context, AddResource.HEADER_BEGIN, buf.toString());
+ }
+ else
+ {
+
+ }
+
+
+ if ((javascriptLocation != null) || (themeLocation != null)) {
+ // Generate a <script> tag in the page header pointing to the
+ // theme.js file for this theme. If neither of these is defined
+ // then presumably the theme.js file is referenced by a <script>
+ // tag hard-wired into the page or inserted via some other means.
+ if (javascriptLocation != null) {
+ // For now, assume that if the user specified a location for a custom
+ // version of the jscookMenu.js file then the theme.js file can be found
+ // in the same location.
+ addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, javascriptLocation + "/" + themeName
+ + "/theme.js");
+ }
+ else {
+ // Using a built-in theme, so we know where the theme.js file is.
+ //addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, HtmlJSCookMenuRenderer.class, themeName
+ // + "/theme.js");
+ TomahawkResourceUtils.addOutputScriptResource(context, "oam.custom.navmenu.jscookmenu."+themeName, "theme.js");
+ }
+ }
+
+ if ((styleLocation != null) || (themeLocation != null)) {
+ // Generate a <link type="text/css"> tag in the page header pointing to
+ // the theme stylesheet. If neither of these is defined then presumably
+ // the stylesheet is referenced by a <link> tag hard-wired into the page
+ // or inserted via some other means.
+ if (styleLocation != null) {
+ addResource.addStyleSheet(context, AddResource.HEADER_BEGIN, styleLocation + "/" + themeName + "/theme.css");
+ }
+ else {
+ //addResource.addStyleSheet(context, AddResource.HEADER_BEGIN, HtmlJSCookMenuRenderer.class, themeName
+ // + "/theme.css");
+ TomahawkResourceUtils.addOutputStylesheetResource(context, "oam.custom.navmenu.jscookmenu."+themeName, "theme.css");
+ }
+ }
+ }
+
+ /**
+ * Fetch the very last part of the menu id.
+ *
+ * @param context
+ * @param component
+ * @return String id of the menu
+ */
+ private String getMenuId(FacesContext context, UIComponent component) {
+ String menuId = component.getClientId(context).replaceAll(":", "_") + "_menu";
+ while (menuId.startsWith("_")) {
+ menuId = menuId.substring(1);
+ }
+ return menuId;
+ }
+}