001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.html; 016 017 import org.apache.hivemind.ApplicationRuntimeException; 018 import org.apache.tapestry.*; 019 import org.apache.tapestry.components.ILinkComponent; 020 import org.apache.tapestry.form.IFormComponent; 021 import org.apache.tapestry.form.LinkSubmit; 022 023 import java.util.HashMap; 024 import java.util.Map; 025 026 /** 027 * Combines a link component (such as 028 * {@link org.apache.tapestry.link.DirectLink}) with an <img> and 029 * JavaScript code to create a rollover effect that works with both Netscape 030 * Navigator and Internet Explorer. [ <a 031 * href="../../../../../ComponentReference/Rollover.html">Component Reference 032 * </a>] 033 * 034 * @author Howard Lewis Ship 035 */ 036 037 public abstract class Rollover extends AbstractComponent 038 { 039 040 /** 041 * Converts an {@link IAsset}binding into a usable URL. Returns null if the 042 * binding does not exist or the binding's value is null. 043 * 044 * @param asset 045 * The asset to generate a url for. 046 * @return The url to the asset resource, or null if it couldn't be generated. 047 */ 048 049 protected String getAssetURL(IAsset asset) 050 { 051 if (asset == null) 052 return null; 053 054 return asset.buildURL(); 055 } 056 057 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) 058 { 059 // No body, so we skip it all if not rewinding 060 // (assumes no side effects on accessors). 061 062 if (cycle.isRewinding()) 063 return; 064 065 String imageURL = null; 066 String mouseOverURL = null; 067 String mouseOutURL = null; 068 boolean dynamic = false; 069 String imageId; 070 boolean linkDisabled = false; 071 072 PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this); 073 074 Object serviceLink = cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME); 075 if (serviceLink == null) 076 { 077 serviceLink = cycle.getAttribute(LinkSubmit.ATTRIBUTE_NAME); 078 079 if (serviceLink != null) 080 linkDisabled = ((IFormComponent) serviceLink).isDisabled(); 081 } else 082 { 083 linkDisabled = ((ILinkComponent) serviceLink).isDisabled(); 084 } 085 086 if (serviceLink == null) 087 throw new ApplicationRuntimeException(Tapestry.getMessage("Rollover.must-be-contained-by-link"), this, null, null); 088 089 if (linkDisabled) 090 { 091 imageURL = getAssetURL(getDisabled()); 092 093 if (imageURL == null) 094 imageURL = getAssetURL(getImage()); 095 } 096 else 097 { 098 imageURL = getAssetURL(getImage()); 099 mouseOverURL = getAssetURL(getMouseOver()); 100 mouseOutURL = getAssetURL(getMouseOut()); 101 102 dynamic = (mouseOverURL != null) || (mouseOutURL != null); 103 } 104 105 if (imageURL == null) 106 throw Tapestry.createRequiredParameterException(this, "image"); 107 108 writer.beginEmpty("img"); 109 110 writer.attribute("src", imageURL); 111 112 if (dynamic) 113 { 114 if (mouseOverURL == null) 115 mouseOverURL = imageURL; 116 117 if (mouseOutURL == null) 118 mouseOutURL = imageURL; 119 120 imageId = writeScript(cycle, pageRenderSupport, serviceLink, mouseOverURL, mouseOutURL); 121 122 writer.attribute("id", imageId); 123 } 124 125 renderInformalParameters(writer, cycle); 126 127 writer.closeTag(); 128 129 } 130 131 // Injected 132 133 public abstract IScript getScript(); 134 135 private String writeScript(IRequestCycle cycle, PageRenderSupport pageRenderSupport, 136 Object link, String mouseOverImageURL, String mouseOutImageURL) 137 { 138 String imageId = pageRenderSupport.getUniqueString(getId()); 139 140 String preloadedMouseOverImageURL = pageRenderSupport.getPreloadedImageReference(this, mouseOverImageURL); 141 String preloadedMouseOutImageURL = pageRenderSupport.getPreloadedImageReference(this, mouseOutImageURL); 142 143 Map symbols = new HashMap(); 144 145 symbols.put("link", link); 146 symbols.put("imageId", imageId); 147 symbols.put("mouseOverImageURL", preloadedMouseOverImageURL); 148 symbols.put("mouseOutImageURL", preloadedMouseOutImageURL); 149 150 getScript().execute(this, cycle, pageRenderSupport, symbols); 151 152 return imageId; 153 } 154 155 public abstract IAsset getMouseOut(); 156 157 public abstract IAsset getDisabled(); 158 159 public abstract IAsset getMouseOver(); 160 161 public abstract IAsset getImage(); 162 }