Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestFilter.java Sun Nov 25 11:28:27 2007 @@ -14,6 +14,8 @@ package org.apache.tapestry.services; +import java.io.IOException; + /** * Filter interface for [EMAIL PROTECTED] ComponentActionRequestHandler}. */ @@ -29,8 +31,8 @@ * @param context context information to provide to the event handler * @param activationContext activation context for the page * @param handler to delegate to + * @return true if the request has been handled (and a response sent to the client), false otherwise */ - ActionResponseGenerator handle(String logicalPageName, String nestedComponentId, - String eventType, String[] context, String[] activationContext, - ComponentActionRequestHandler handler); + boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context, + String[] activationContext, ComponentActionRequestHandler handler) throws IOException; }
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentActionRequestHandler.java Sun Nov 25 11:28:27 2007 @@ -17,6 +17,8 @@ import org.apache.tapestry.corelib.components.ActionLink; import org.apache.tapestry.corelib.components.Form; +import java.io.IOException; + /** * Handler interface for action requests. Action requests <em>do things</em> such as process a * form submission or otherwise change state. In the majority of cases, after the action, a redirect @@ -29,16 +31,17 @@ public interface ComponentActionRequestHandler { /** - * Handler for a component action request, which returns a response generator used to send the - * final response to the client. + * Handler for a component action request which will trigger an event on a component and use + * the return value to send a response to the client (typically, a redirect to a page render URL). * * @param logicalPageName the page name containing the component, and the default component to render the * response * @param nestedComponentId the id of the component within the page * @param eventType the type of event to trigger on the component * @param context context information to provide to the event handler - * @parram activationContext activation context for the page + * @param activationContext activation context for the page + * @return true if the request has been handled (and a response sent to the client), false otherwise */ - ActionResponseGenerator handle(String logicalPageName, String nestedComponentId, - String eventType, String[] context, String[] activationContext); + boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context, + String[] activationContext) throws IOException; } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentEventResultProcessor.java Sun Nov 25 11:28:27 2007 @@ -16,6 +16,8 @@ import org.apache.tapestry.runtime.Component; +import java.io.IOException; + /** * Responsible for handling the return value provided by a component event handler. * @@ -24,15 +26,13 @@ public interface ComponentEventResultProcessor<T> { /** - * For a given, non-null return value, provide a corresponding Link object (which will - * ultimately be transformed into a URL and sent to the client as a redirect). + * For a given, non-null return value from a component event method, construct and send a response. * * @param value the value returned from a method * @param component the component on which a method was invoked * @param methodDescripion a description of method which provided the value * @return an object that can send the request to the client - * @throws RuntimeException if the value can not be converted into a link + * @throws RuntimeException if the value can not be converted into a response */ - ActionResponseGenerator processComponentEvent(T value, Component component, - String methodDescripion); + void processComponentEvent(T value, Component component, String methodDescripion) throws IOException; } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestFilter.java Sun Nov 25 11:28:27 2007 @@ -27,8 +27,6 @@ * @param logicalPageName the logical name of the page to activate and render * @param context context data, supplied by the page at render time, extracted from the render URL * @param handler to delegate the invocation to - * @return an action response generator, or null if the page simply rendered */ - ActionResponseGenerator handle(String logicalPageName, String[] context, - PageRenderRequestHandler handler); + void handle(String logicalPageName, String[] context, PageRenderRequestHandler handler); } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/PageRenderRequestHandler.java Sun Nov 25 11:28:27 2007 @@ -22,12 +22,12 @@ public interface PageRenderRequestHandler { /** - * Invoked to activate and render a page. The return value of the event handler method(s) for - * the activate event may result in an action response generator being returned. + * Invoked to activate and render a page. In certain cases, based on values returned when + * activating the page, a [EMAIL PROTECTED] org.apache.tapestry.services.ComponentEventResultProcessor} may be used + * to send an alternate response (typically, a redirect). * * @param logicalPageName the logical name of the page to activate and render * @param context context data, supplied by the page at render time, extracted from the render URL - * @return an action response generator, or null if the page simply rendered */ - ActionResponseGenerator handle(String logicalPageName, String[] context); + void handle(String logicalPageName, String[] context); } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Response.java Sun Nov 25 11:28:27 2007 @@ -14,6 +14,8 @@ package org.apache.tapestry.services; +import org.apache.tapestry.Link; + import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; @@ -48,6 +50,13 @@ * @see #encodeRedirectURL(String) */ void sendRedirect(String URL) throws IOException; + + /** + * Sends a redirect to a link. + * + * @param link link to redirect to. + */ + void sendRedirect(Link link) throws IOException; /** * Sends an error response to the client using the specified status. The server defaults to Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Sun Nov 25 11:28:27 2007 @@ -34,6 +34,7 @@ import org.apache.tapestry.ioc.*; import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE; import org.apache.tapestry.ioc.annotations.*; +import org.apache.tapestry.ioc.internal.util.CollectionFactory; import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap; import org.apache.tapestry.ioc.internal.util.InternalUtils; import org.apache.tapestry.ioc.services.*; @@ -107,6 +108,8 @@ binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class); binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class); binder.bind(RequestEncodingInitializer.class, RequestEncodingInitializerImpl.class); + binder.bind(ComponentEventResultProcessor.class, ComponentInstanceResultProcessor.class).withId( + "ComponentInstanceResultProcessor"); } public static Alias build(Logger logger, @@ -495,8 +498,20 @@ * terminates the pipeline by returning false. Generally, most filters should be ordered after * this filter. */ - public static void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, Context context, - final RequestExceptionHandler exceptionHandler) + public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, Context context, + + final RequestExceptionHandler exceptionHandler, + + RequestGlobals requestGlobals, + + // @Inject not needed because its a long, not a String + @Symbol("tapestry.file-check-interval") + long checkInterval, + + @Symbol("tapestry.file-check-update-timeout") + long updateTimeout, + + LocalizationSetter localizationSetter) { RequestFilter staticFilesFilter = new StaticFilesFilter(context); @@ -528,8 +543,14 @@ }; configuration.add("ErrorFilter", errorFilter); + + configuration.add("CheckForUpdates", + new CheckForUpdatesFilter(_updateListenerHub, checkInterval, updateTimeout), "before:*"); + + configuration.add("Localization", new LocalizationFilter(localizationSetter)); } + /** * Contributes the basic set of default translators: * <ul> @@ -724,6 +745,8 @@ private final Request _request; + private final Response _response; + private final ThreadLocale _threadLocale; private final RequestGlobals _requestGlobals; @@ -758,6 +781,8 @@ Request request, + Response response, + ThreadLocale threadLocale) { _pipelineBuilder = pipelineBuilder; @@ -777,6 +802,7 @@ _threadCleanupHub = threadCleanupHub; _componentTemplateSource = componentTemplateSource; _request = request; + _response = response; _threadLocale = threadLocale; } @@ -964,13 +990,15 @@ ServletApplicationInitializerFilter.class, configuration, terminator); } - @Marker(Primary.class) - public ComponentEventResultProcessor build(Map<Class, ComponentEventResultProcessor> configuration) + @Marker({Primary.class, Traditional.class}) + public ComponentEventResultProcessor buildComponentEventResultProcessor( + Map<Class, ComponentEventResultProcessor> configuration) { + Set<Class> handledTypes = CollectionFactory.newSet(configuration.keySet()); + // A slight hack! - configuration.put(Object.class, new ObjectComponentEventResultProcessor(configuration - .keySet())); + configuration.put(Object.class, new ObjectComponentEventResultProcessor(handledTypes)); StrategyRegistry<ComponentEventResultProcessor> registry = StrategyRegistry.newInstance( ComponentEventResultProcessor.class, configuration); @@ -1038,10 +1066,6 @@ return _shadowBuilder.build(_componentInstantiatorSource, "classFactory", ClassFactory.class); } - public ComponentEventResultProcessor buildComponentInstanceResultProcessor(Logger logger) - { - return new ComponentInstanceResultProcessor(_requestPageCache, _linkFactory, logger); - } /** * Ordered contributions to the MasterDispatcher service allow different URL matching strategies @@ -1104,10 +1128,6 @@ * <dl> * <dt>Object</dt> * <dd>Failure case, added to provide a more useful exception message</dd> - * <dt>ActionResponseGenerator</dt> - * <dd>Returns the ActionResponseGenerator; this sometimes occurs when a component generates - * events whose return values are converted to ActionResponseGenerators (this handles that - * bubble up case).</dd> * <dt>Link</dt> * <dd>Wraps the Link to send a redirect</dd> * <dt>String</dt> @@ -1123,33 +1143,26 @@ MappedConfiguration<Class, ComponentEventResultProcessor> configuration) { - configuration.add(ActionResponseGenerator.class, new ComponentEventResultProcessor<ActionResponseGenerator>() - { - public ActionResponseGenerator processComponentEvent(ActionResponseGenerator value, Component component, - String methodDescripion) - { - return value; - } - }); + configuration.add(Link.class, new ComponentEventResultProcessor<Link>() { - public ActionResponseGenerator processComponentEvent(Link value, Component component, - String methodDescripion) + public void processComponentEvent(Link value, Component component, String methodDescripion) + throws IOException { - return new LinkActionResponseGenerator(value); + _response.sendRedirect(value); } }); - configuration.add(String.class, new StringResultProcessor(_requestPageCache, _linkFactory)); + configuration.add(String.class, new StringResultProcessor(_requestPageCache, _linkFactory, _response)); configuration.add(Class.class, - new ClassResultProcessor(componentClassResolver, _requestPageCache, _linkFactory)); + new ClassResultProcessor(componentClassResolver, _requestPageCache, _linkFactory, _response)); configuration.add(Component.class, componentInstanceProcessor); - configuration.add(StreamResponse.class, new StreamResponseResultProcessor()); + configuration.add(StreamResponse.class, new StreamResponseResultProcessor(_response)); } public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration, @@ -1162,7 +1175,7 @@ PageRenderRequestHandler pageRenderRequestHandler, - ComponentActionRequestHandler componentActionRequestHandler, + @Traditional ComponentActionRequestHandler componentActionRequestHandler, ComponentClassResolver componentClassResolver, @@ -1284,6 +1297,7 @@ "${tapestry.scriptaculous}/prototype.js", "${tapestry.scriptaculous}/scriptaculous.js", + "${tapestry.scriptaculous}/effects.js", "org/apache/tapestry/tapestry.js"); support.addStylesheetLink(stylesheetAsset, null); @@ -1373,6 +1387,13 @@ configuration, resources.autobuild(PageRenderRequestHandlerImpl.class)); } + /** + * Builds the component action request handler for traditional (non-Ajax) requests. These typically + * result in a redirect to a Tapestry render URL. + * + * @see org.apache.tapestry.internal.services.ComponentActionRequestHandlerImpl + */ + @Marker(Traditional.class) public ComponentActionRequestHandler buildComponentActionRequestHandler( List<ComponentActionRequestFilter> configuration, Logger logger, ServiceResources resources) { @@ -1381,6 +1402,19 @@ } /** + * Builds the action request handler for Ajax requests, based on + * [EMAIL PROTECTED] org.apache.tapestry.internal.services.AjaxComponentActionRequestHandler}. Filters on + * the request handler are supported here as well. + */ + @Marker(Ajax.class) + public ComponentActionRequestHandler buildAjaxComponentActionRequestHandler( + List<ComponentActionRequestFilter> configuration, Logger logger, ServiceResources resources) + { + return _pipelineBuilder.build(logger, ComponentActionRequestHandler.class, ComponentActionRequestFilter.class, + configuration, resources.autobuild(AjaxComponentActionRequestHandler.class)); + } + + /** * Configures the extensions that will require a digest to be downloaded via the asset * dispatcher. Most resources are "safe", they don't require a digest. For unsafe resources, the * digest is incorporated into the URL to ensure that the client side isn't just "fishing". @@ -1442,7 +1476,8 @@ // This is designed to make it easy to keep synchronized with script.aculo.ous. As we // support a new version, we create a new folder, and update the path entry. We can then // delete the old version folder (or keep it around). This should be more manageable than - // overwriting the local copy with updates. There's also a ClasspathAliasManager + // overwriting the local copy with updates (it's too easy for files deleted between scriptaculous + // releases to be accidentally left lying around). There's also a ClasspathAliasManager // contribution based on the path. configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}"); @@ -1609,7 +1644,12 @@ /** * Adds content types for "css" and "js" file extensions. + * <dl> + * <dt>css</dt> <dd>test/css</dd> + * <dt>js</dt> <dd>text/javascript</dd> + * </dl> */ + @SuppressWarnings({"JavaDoc"}) public void contributeResourceStreamer(MappedConfiguration<String, String> configuration) { configuration.add("css", "text/css"); @@ -1789,26 +1829,6 @@ configuration.add("StringLiteral", stringFactory); } - /** - * Adds a filter that checks for updates to classes and other resources. It is ordered before:*. - */ - public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, - RequestGlobals requestGlobals, - - // @Inject not needed because its a long, not a String - @Symbol("tapestry.file-check-interval") - long checkInterval, - - @Symbol("tapestry.file-check-update-timeout") - long updateTimeout, - - LocalizationSetter localizationSetter) - { - configuration.add("CheckForUpdates", - new CheckForUpdatesFilter(_updateListenerHub, checkInterval, updateTimeout), "before:*"); - - configuration.add("Localization", new LocalizationFilter(localizationSetter)); - } public PersistentFieldStrategy buildClientPersistentFieldStrategy(LinkFactory linkFactory, ServiceResources resources) @@ -1821,15 +1841,14 @@ return service; } - public static void contributeComponentActionRequestHandler( + public void contributeComponentActionRequestHandler( OrderedConfiguration<ComponentActionRequestFilter> configuration, - final RequestEncodingInitializer encodingInitializer) + final RequestEncodingInitializer encodingInitializer, @Ajax ComponentActionRequestHandler ajaxHandler) { - ComponentActionRequestFilter filter = new ComponentActionRequestFilter() + ComponentActionRequestFilter requestEncodingFilter = new ComponentActionRequestFilter() { - public ActionResponseGenerator handle(String logicalPageName, String nestedComponentId, String eventType, - String[] context, String[] activationContext, - ComponentActionRequestHandler handler) + public boolean handle(String logicalPageName, String nestedComponentId, String eventType, String[] context, + String[] activationContext, ComponentActionRequestHandler handler) throws IOException { encodingInitializer.initializeRequestEncoding(logicalPageName); @@ -1838,8 +1857,8 @@ }; - configuration.add("SetRequestEncoding", filter, "before:*"); + configuration.add("SetRequestEncoding", requestEncodingFilter, "before:*"); - configuration.add("Ajax", new AjaxFilter()); + configuration.add("Ajax", new AjaxFilter(_request, ajaxHandler)); } } Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java?rev=598036&view=auto ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java (added) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Traditional.java Sun Nov 25 11:28:27 2007 @@ -0,0 +1,30 @@ +// Copyright 2007 The Apache Software Foundation +// +// Licensed 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.tapestry.services; + +import java.lang.annotation.*; + + +/** + * Marker annotation for a service that should be used for traditional (non-Ajax) requests. + * + * @see org.apache.tapestry.services.ComponentActionRequestHandler + */ [EMAIL PROTECTED]({ElementType.PARAMETER, ElementType.FIELD}) [EMAIL PROTECTED](RetentionPolicy.RUNTIME) [EMAIL PROTECTED] +public @interface Traditional +{ +} Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/scriptaculous_1_8/scriptaculous.js Sun Nov 25 11:28:27 2007 @@ -39,27 +39,23 @@ return parseInt(r[0]) * 100000 + parseInt(r[1]) * 1000 + parseInt(r[2]); } - if ((typeof Prototype == 'undefined') || - (typeof Element == 'undefined') || - (typeof Element.Methods == 'undefined') || - (convertVersionString(Prototype.Version) < - convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) - throw("script.aculo.us requires the Prototype JavaScript framework >= " + - Scriptaculous.REQUIRED_PROTOTYPE); + if ((typeof Prototype == 'undefined') || (typeof Element == 'undefined') || (typeof Element.Methods == 'undefined') || (convertVersionString(Prototype.Version) < convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) + throw("script.aculo.us requires the Prototype JavaScript framework >= " + Scriptaculous.REQUIRED_PROTOTYPE); - $A(document.getElementsByTagName("script")).findAll(function(s) - { - return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) - }).each(function(s) - { - var path = s.src.replace(/scriptaculous\.js(\?.*)?$/, ''); - var includes = s.src.match(/\?.*load=([a-z,]*)/); - (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( - function(include) - { - Scriptaculous.require(path + include + '.js') - }); - }); +// Tapestry turns off this mechanism, and replaces it with PageRenderSupport.addScriptLink(). + // $A(document.getElementsByTagName("script")).findAll(function(s) + // { + // return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) + // }).each(function(s) + // { + // var path = s.src.replace(/scriptaculous\.js(\?.*)?$/, ''); + // var includes = s.src.match(/\?.*load=([a-z,]*)/); + // (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( + // function(include) + // { + // Scriptaculous.require(path + include + '.js') + // }); + // }); } } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js Sun Nov 25 11:28:27 2007 @@ -131,6 +131,34 @@ }); }, + // Convert a link into a trigger of an Ajax update that + // updates the indicated zone. + + linkZone : function(link, zone) + { + link = $(link); + zone = $(zone); + + var clickHandler = function(event) + { + var successHandler = function(transport) + { + var response = transport.responseText; + var reply = eval("(" + response + ")"); + + zone.innerHTML = reply.content; + + zone.show(); + }; + + var request = new Ajax.Request(link.href, { onSuccess : successHandler }); + + return false; + }; + + link.onclick = clickHandler; + }, + FormEvent : Class.create(), @@ -361,7 +389,7 @@ } }; -Event.observe(window, "load", function() +Event.observe(window, 'load', function() { $$(".t-invisible").each(function(element) { Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/ajax.apt Sun Nov 25 11:28:27 2007 @@ -16,6 +16,22 @@ Ajax support takes the form of new components and, occasionally, {{{mixins.html}component mixins}}. +Changes to Scriptaculous + + Scriptaculous normally has a special {{{http://wiki.script.aculo.us/scriptaculous/show/Usage}script loading option}}. + Loading just the Scriptaculous main library, scriptaculous.js, will also load <all> the other scripts in the library. Normally, + you can fine-tune this using "load" query parameter. + + This doesn't fit well with the Tapestry; as discussed below, Tapestry has the capability to allow + individual components to control which JavaScript libraries are loaded with the page. Further, the exact set of scripts + needed is determined over the course of rendering the page, and depends on the needs of the specific components that have + rendered. + + The main Scriptaculous library, scriptaculous.js, is modified to turn off the autoloading behavior. + Tapestry will automatically link in prototype.js, scriptaculous.js, effects.js and the Tapestry library, tapestry.js. + You can add additional libraries as needed. + + Basic JavaScript The general strategy in Tapestry is that any significant amount of JavaScript should be packaged up @@ -42,8 +58,36 @@ ignored. In this way, each component can add the assets it needs, without worrying about conflicts with other components. - Note that the Prototype, Scriptaculous and the base Tapestry library (which largely consists of + Note that the Prototype, Scriptaculous main and effects libraries, and the base Tapestry library (which largely consists of support for form input validation) are included automatically. + + If you are need access to other Scriptaculous libraries, you can provide them as follows: + ++---+ + + @Inject @Path("${tapestry.scriptaculous}/dragdrop.js") + private Asset _dragDropLibrary; + + @Environmental + private PageRenderSupport _pageRenderSupport; + + void setupRender() + { + _pageRenderSupport.addScriptLink(_dragDropLibrary); + } + ++---+ + + The Asset is injected, using the ${tapestry.scriptaculous} symbol to reference the location + of the Scriptaculous library. + + The PageRenderSupport is accessed as an Environmental service. + + The setupRender() method (the name is specifically linked to a + {{{rendering.html}render phase}}) is the correct place to inform the PageRenderSupport service that + the library is needed. + + * addScript() Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ZoneDemo.tml URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ZoneDemo.tml?rev=598036&view=auto ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ZoneDemo.tml (added) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ZoneDemo.tml Sun Nov 25 11:28:27 2007 @@ -0,0 +1,22 @@ +<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> + <h1>Zone/Ajax Demo</h1> + + + <t:zone t:id="output" style="float:right;"> + No name has been selected. + + <t:block id="showName"> + Selected: ${name} + </t:block> + + </t:zone> + + + <ul> + <li t:type="loop" source="names" value="name"> + <t:actionlink t:id="select" context="name" zone="output">Select "${name}"</t:actionlink> + </li> + </ul> + + +</html> \ No newline at end of file Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/dom/DOMTest.java Sun Nov 25 11:28:27 2007 @@ -288,9 +288,7 @@ root.elementAt(1, "one").element("tiny"); root.elementAt(2, "two").element("bubbles"); - assertEquals( - d.toString(), - "<fred><start/><one><tiny/></one><two><bubbles/></two><end/></fred>"); + assertEquals(d.toString(), "<fred><start/><one><tiny/></one><two><bubbles/></two><end/></fred>"); } @Test @@ -363,8 +361,22 @@ root.attribute("alpha-only", "abcdef"); root.attribute("entities", "\"<>&"); - assertEquals( - root.toString(), - "<prime alpha-only=\"abcdef\" entities=\""<>&\"/>"); + assertEquals(root.toString(), "<prime alpha-only=\"abcdef\" entities=\""<>&\"/>"); + } + + @Test + public void add_class_names() + { + Document d = new Document(new XMLMarkupModel()); + + Element root = d.newRootElement("div"); + + assertSame(root.addClassName("fred"), root); + + assertEquals(root.toString(), "<div class=\"fred\"/>"); + + assertSame(root.addClassName("barney", "wilma"), root); + + assertEquals(root.toString(), "<div class=\"fred barney wilma\"/>"); } } Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java?rev=598036&view=auto ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java (added) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/ZoneDemo.java Sun Nov 25 11:28:27 2007 @@ -0,0 +1,57 @@ +// Copyright 2007 The Apache Software Foundation +// +// Licensed 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.tapestry.integration.app1.pages; + +import org.apache.tapestry.Block; +import org.apache.tapestry.ioc.annotations.Inject; +import org.slf4j.Logger; + +public class ZoneDemo +{ + @Inject + private Logger _logger; + + private String _name; + + private static final String[] NAMES = {"Fred & Wilma", "Mr. <Roboto>", "Grim Fandango"}; + + @Inject + private Block _showName; + + public String[] getNames() + { + return NAMES; + } + + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + Object onActionFromSelect(String name) + { + _name = name; + + _logger.info("Selected: '" + _name + "'"); + + return _showName; + } +} Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentActionDispatcherTest.java Sun Nov 25 11:28:27 2007 @@ -17,7 +17,10 @@ import org.apache.tapestry.TapestryConstants; import org.apache.tapestry.internal.InternalConstants; import org.apache.tapestry.internal.test.InternalBaseTestCase; -import org.apache.tapestry.services.*; +import org.apache.tapestry.services.ComponentActionRequestHandler; +import org.apache.tapestry.services.Dispatcher; +import org.apache.tapestry.services.Request; +import org.apache.tapestry.services.Response; import static org.easymock.EasyMock.aryEq; import static org.easymock.EasyMock.eq; import org.testng.annotations.Test; @@ -70,27 +73,14 @@ @Test public void default_event_with_nested_id_and_context() throws Exception { - test( - "/foo/MyPage.fred/fee/fie/foe/fum", - "foo/MyPage", - "fred", - TapestryConstants.ACTION_EVENT, - "fee", - "fie", - "foe", - "fum"); + test("/foo/MyPage.fred/fee/fie/foe/fum", "foo/MyPage", "fred", TapestryConstants.ACTION_EVENT, "fee", "fie", + "foe", "fum"); } @Test public void default_event_with_context_that_includes_a_colon() throws Exception { - test( - "/foo/MyPage.underdog/a:b:c/d", - "foo/MyPage", - "underdog", - TapestryConstants.ACTION_EVENT, - "a:b:c", - "d"); + test("/foo/MyPage.underdog/a:b:c/d", "foo/MyPage", "underdog", TapestryConstants.ACTION_EVENT, "a:b:c", "d"); } @Test @@ -108,14 +98,7 @@ @Test public void nested_component_event_with_context() throws Exception { - test( - "/foo/MyPage.nested:trigger/foo/bar/baz", - "foo/MyPage", - "nested", - "trigger", - "foo", - "bar", - "baz"); + test("/foo/MyPage.nested:trigger/foo/bar/baz", "foo/MyPage", "nested", "trigger", "foo", "bar", "baz"); } @Test @@ -124,22 +107,14 @@ ComponentActionRequestHandler handler = newComponentActionRequestHandler(); Request request = mockRequest(); Response response = mockResponse(); - ActionResponseGenerator generator = newMock(ActionResponseGenerator.class); train_getPath(request, "/mypage:eventname"); train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, "alpha/beta"); - expect( - handler.handle( - eq("mypage"), - eq(""), - eq("eventname"), - aryEq(new String[0]), - aryEq(new String[] - {"alpha", "beta"}))).andReturn(generator); + expect(handler.handle(eq("mypage"), eq(""), eq("eventname"), aryEq(new String[0]), + aryEq(new String[]{"alpha", "beta"}))).andReturn(true); - generator.sendClientResponse(response); replay(); @@ -150,27 +125,19 @@ verify(); } - private void test(String requestPath, String logicalPageName, String nestedComponentId, - String eventType, String... context) throws IOException + private void test(String requestPath, String logicalPageName, String nestedComponentId, String eventType, + String... context) throws IOException { ComponentActionRequestHandler handler = newComponentActionRequestHandler(); Request request = mockRequest(); Response response = mockResponse(); - ActionResponseGenerator generator = newMock(ActionResponseGenerator.class); train_getPath(request, requestPath); train_getParameter(request, InternalConstants.PAGE_CONTEXT_NAME, null); - expect( - handler.handle( - eq(logicalPageName), - eq(nestedComponentId), - eq(eventType), - aryEq(context), - aryEq(new String[0]))).andReturn(generator); - - generator.sendClientResponse(response); + expect(handler.handle(eq(logicalPageName), eq(nestedComponentId), eq(eventType), aryEq(context), + aryEq(new String[0]))).andReturn(true); replay(); Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceResultProcessorTest.java Sun Nov 25 11:28:27 2007 @@ -30,8 +30,6 @@ private static final String METHOD_DESCRIPTION = "foo.bar.Baz.biff()"; - private static final String LINK_URI = "{LinkURI}"; - @Test public void result_is_root_component() throws Exception { @@ -52,17 +50,15 @@ train_get(cache, PAGE_NAME, page); train_createPageLink(factory, page, link); - train_toRedirectURI(link, LINK_URI); - response.sendRedirect(LINK_URI); + response.sendRedirect(link); replay(); - ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor( - cache, factory, logger); + ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor(logger, response, + cache, factory); - processor.processComponentEvent(result, source, METHOD_DESCRIPTION).sendClientResponse( - response); + processor.processComponentEvent(result, source, METHOD_DESCRIPTION); verify(); } @@ -97,17 +93,15 @@ train_get(cache, PAGE_NAME, page); train_createPageLink(factory, page, link); - train_toRedirectURI(link, LINK_URI); - response.sendRedirect(LINK_URI); + response.sendRedirect(link); replay(); - ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor( - cache, factory, logger); + ComponentEventResultProcessor<Component> processor = new ComponentInstanceResultProcessor(logger, response, + cache, factory); - processor.processComponentEvent(value, source, METHOD_DESCRIPTION).sendClientResponse( - response); + processor.processComponentEvent(value, source, METHOD_DESCRIPTION); verify(); } Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ObjectComponentEventResultProcessorTest.java Sun Nov 25 11:28:27 2007 @@ -51,11 +51,12 @@ } catch (TapestryException ex) { - assertEquals( - ex.getMessage(), - "An event handler for component foo.Bar:gnip.gnop returned the value *INVALID* (from method foo.component.Gnop.blip()). " - + "Return type java.lang.String can not be handled. " - + "Configured return types are java.lang.String, java.util.List, java.util.Map."); + assertEquals(ex.getMessage(), + "An event handler for component foo.Bar:gnip.gnop returned the value *INVALID* (from method foo.component.Gnop.blip()). " + "Return type java.lang.String can not be handled. " + "Configured return types are java.lang.String, java.util.List, java.util.Map."); + } + catch (java.io.IOException e) + { + throw new RuntimeException(e); } } } Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/RequestImplTest.java Sun Nov 25 11:28:27 2007 @@ -123,11 +123,6 @@ @DataProvider(name = "xhr_inputs") public Object[][] xhr_inputs() { - return new Object[][] - { - {null, false}, - {"", false}, - {"some other value", false}, - {"XmlHttpRequest", true}}; + return new Object[][]{{null, false}, {"", false}, {"some other value", false}, {"XMLHttpRequest", true}}; } } Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt?rev=598036&r1=598035&r2=598036&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/add_script.txt Sun Nov 25 11:28:27 2007 @@ -1,6 +1,6 @@ <html><body><p>Ready to be updated with scripts.</p><script type="text/javascript"> <!-- -Event.observe(window, "load", function() { +Event.observe(window, 'load', function() { doSomething(); doSomethingElse(); });
