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 015package org.apache.tapestry.html; 016 017import org.apache.hivemind.Resource; 018import org.apache.tapestry.AbstractComponent; 019import org.apache.tapestry.IMarkupWriter; 020import org.apache.tapestry.IRequestCycle; 021import org.apache.tapestry.PageRenderSupport; 022import org.apache.tapestry.TapestryUtils; 023import org.apache.tapestry.asset.AssetFactory; 024import org.apache.tapestry.util.PageRenderSupportImpl; 025import org.apache.tapestry.web.WebResponse; 026 027/** 028 * The body of a Tapestry page. This is used since it allows components on the page access to an 029 * initialization script (that is written the start, just inside the <body> tag). This is 030 * currently used by {@link Rollover}and {@link Script}components. [ <a 031 * href="../../../../../ComponentReference/Body.html">Component Reference </a>] 032 * 033 * @author Howard Lewis Ship 034 */ 035 036public abstract class Body extends AbstractComponent implements PageRenderSupport 037{ 038 private PageRenderSupportImpl _pageRenderSupport; 039 040 /** 041 * Adds to the script an initialization for the named variable as an Image(), to the given URL. 042 * <p> 043 * Returns a reference, a string that can be used to represent the preloaded image in a 044 * JavaScript function. 045 * 046 * @since 1.0.2 047 */ 048 049 public String getPreloadedImageReference(String URL) 050 { 051 return _pageRenderSupport.getPreloadedImageReference(URL); 052 } 053 054 /** 055 * Adds other initialization, in the form of additional JavaScript code to execute from the 056 * <body>'s <code>onLoad</code> event handler. The caller is responsible for adding a 057 * semicolon (statement terminator). This method will add a newline after the script. 058 */ 059 060 public void addInitializationScript(String script) 061 { 062 _pageRenderSupport.addInitializationScript(script); 063 } 064 065 /** 066 * Adds additional scripting code to the page. This code will be added to a large block of 067 * scripting code at the top of the page (i.e., the before the <body> tag). 068 * <p> 069 * This is typically used to add some form of JavaScript event handler to a page. For example, 070 * the {@link Rollover}component makes use of this. 071 * <p> 072 * Another way this is invoked is by using the {@link Script}component. 073 * <p> 074 * The string will be added, as-is, within the <script> block generated by this 075 * <code>Body</code> component. The script should <em>not</em> contain HTML comments, those 076 * will be supplied by this Body component. 077 * <p> 078 * A frequent use is to add an initialization function using this method, then cause it to be 079 * executed using {@link #addInitializationScript(String)}. 080 */ 081 082 public void addBodyScript(String script) 083 { 084 _pageRenderSupport.addBodyScript(script); 085 } 086 087 /** 088 * Used to include a script from an outside URL (the scriptLocation is a URL, probably obtained 089 * from an asset. This adds an <script src="..."> tag before the main <script> tag. 090 * The Body component ensures that each URL is included only once. 091 * 092 * @since 1.0.5 093 */ 094 095 public void addExternalScript(Resource scriptLocation) 096 { 097 _pageRenderSupport.addExternalScript(scriptLocation); 098 } 099 100 /** 101 * Retrieves the <code>Body</code> that was stored into the request cycle. This allows 102 * components wrapped by the <code>Body</code> to locate it and access the services it 103 * provides. 104 * 105 * @deprecated To be removed in 4.1. Use 106 * {@link org.apache.tapestry.TapestryUtils#getPageRenderSupport(IRequestCycle)} 107 * instead. 108 */ 109 110 public static Body get(IRequestCycle cycle) 111 { 112 return (Body) TapestryUtils.getOptionalPageRenderSupport(cycle); 113 } 114 115 protected void prepareForRender(IRequestCycle cycle) 116 { 117 super.prepareForRender(cycle); 118 119 _pageRenderSupport = new PageRenderSupportImpl(getAssetFactory(), getResponse() 120 .getNamespace(), getLocation()); 121 } 122 123 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) 124 { 125 TapestryUtils.storePageRenderSupport(cycle, this); 126 127 IMarkupWriter nested = writer.getNestedWriter(); 128 129 renderBody(nested, cycle); 130 131 // Start the body tag. 132 writer.println(); 133 writer.begin(getElement()); 134 renderInformalParameters(writer, cycle); 135 136 writer.println(); 137 138 // Write the page's scripting. This is included scripts 139 // and dynamic JavaScript. 140 141 _pageRenderSupport.writeBodyScript(writer, cycle); 142 143 // Close the nested writer, which dumps its buffered content 144 // into its parent. 145 146 nested.close(); 147 148 // Any initialization should go at the very end of the document 149 // just before the close body tag. Older version of Tapestry 150 // would create a window.onload event handler, but this is better 151 // (it doesn't have to wait for external images to load). 152 153 _pageRenderSupport.writeInitializationScript(writer); 154 155 writer.end(); // <body> 156 } 157 158 protected void cleanupAfterRender(IRequestCycle cycle) 159 { 160 super.cleanupAfterRender(cycle); 161 162 _pageRenderSupport = null; 163 164 TapestryUtils.removePageRenderSupport(cycle); 165 } 166 167 /** 168 * Parameter. 169 */ 170 public abstract String getElement(); 171 172 /** 173 * Injected 174 * 175 * @since 4.0 176 */ 177 public abstract AssetFactory getAssetFactory(); 178 179 /** 180 * Injected 181 * 182 * @since 4.0 183 */ 184 185 public abstract WebResponse getResponse(); 186 187 /** @since 3.0 */ 188 189 public String getUniqueString(String baseValue) 190 { 191 return _pageRenderSupport.getUniqueString(baseValue); 192 } 193 194}