    001    // Copyright 2010, 2011 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.tapestry5.services.javascript;
    016
    017    import org.apache.tapestry5.*;
    018    import org.apache.tapestry5.annotations.Environmental;
    019    import org.apache.tapestry5.json.JSONArray;
    020    import org.apache.tapestry5.json.JSONObject;
    021    import org.apache.tapestry5.services.EnvironmentalShadowBuilder;
    022
    023    /**
    024     * An environmental that acts as a replacement for the {@link RenderSupport} environmental, renaming and streamlining
    025     * the key methods. JavaScriptSupport is very stateful, accumulating JavaScript stacks, libraries and initialization
    026     * code until the end of the main page render; it then updates the rendered DOM (adding &lt;script&gt; tags to the
    027     * &lt;head&gt; and &lt;body&gt;) before the document is streamed to the client.
    028     * <p/>
    029     * JavaScriptSupport is normally accessed within a component by using the {@link Environmental} annotation on a
    030     * component field. In addition, JavaScriptSupport may also be accessed as a service (the service
    031     * {@linkplain EnvironmentalShadowBuilder internally delegates to the current environmental instance}), which is useful
    032     * for service-layer objects.
    033     * <p/>
    034     * The term "import" is used on many methods to indicate that the indicated resource (stack, library or stylesheet) will
    035     * only be added to the final Document once.
    036     * <p/>
    037     * The name is slightly a misnomer, since there's a side-line of
    038     * {@linkplain #importStylesheet(StylesheetLink)} as well.
    039     * <p/>
    040     * JavaScriptSupport works equally well inside an Ajax request that produces a JSON-formatted partial page update response.
    041     *
    042     * @see org.apache.tapestry5.internal.services.DocumentLinker
    043     * @since 5.2.0
    044     */
    045    public interface JavaScriptSupport
    046    {
    047        /**
    048         * Allocates a unique id based on the component's id. In some cases, the return value will not precisely match the
    049         * input value (an underscore and a unique index value may be appended).
    050         *
    051         * @param id the component id from which a unique id will be generated
    052         * @return a unique id for this rendering of the page
    053         * @see org.apache.tapestry5.ioc.util.IdAllocator
    054         */
    055        String allocateClientId(String id);
    056
    057        /**
    058         * As with {@link #allocateClientId(String)} but uses the id of the component extracted from the resources.
    059         *
    060         * @param resources of the component which requires an id
    061         * @return a unique id for this rendering of the page
    062         */
    063        String allocateClientId(ComponentResources resources);
    064
    065        /**
    066         * Adds initialization script at {@link InitializationPriority#NORMAL} priority.
    067         *
    068         * @param format    format string (as per {@link String#format(String, Object...)}
    069         * @param arguments arguments referenced by format specifiers
    070         */
    071        void addScript(String format, Object... arguments);
    072
    073        /**
    074         * Adds initialization script at the specified priority.
    075         *
    076         * @param priority  priority to use when adding the script
    077         * @param format    format string (as per {@link String#format(String, Object...)}
    078         * @param arguments arguments referenced by format specifiers
    079         */
    080        void addScript(InitializationPriority priority, String format, Object... arguments);
    081
    082        /**
    083         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    084         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    085         * {@link InitializationPriority#NORMAL} priority.
    086         *
    087         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    088         * @param parameter    object to pass to the client-side function
    089         */
    090        void addInitializerCall(String functionName, JSONObject parameter);
    091
    092        /**
    093         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    094         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    095         * {@link InitializationPriority#NORMAL} priority.
    096         *
    097         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    098         * @param parameter    array of parameters to pass to the client-side function
    099         * @since 5.3
    100         */
    101        void addInitializerCall(String functionName, JSONArray parameter);
    102
    103        /**
    104         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    105         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    106         * {@link InitializationPriority#NORMAL} priority.
    107         *
    108         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    109         * @param parameter    array of parameters to pass to the client-side function
    110         * @since 5.3
    111         */
    112        void addInitializerCall(InitializationPriority priority, String functionName, JSONArray parameter);
    113
    114        /**
    115         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    116         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    117         * the specified priority.
    118         *
    119         * @param priority     priority to use when adding the script
    120         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    121         * @param parameter    object to pass to the client-side function
    122         */
    123        void addInitializerCall(InitializationPriority priority, String functionName, JSONObject parameter);
    124
    125        /**
    126         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    127         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    128         * {@link InitializationPriority#NORMAL} priority.
    129         *
    130         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    131         * @param parameter    string to pass to function (typically, a client id)
    132         */
    133        void addInitializerCall(String functionName, String parameter);
    134
    135        /**
    136         * Adds a call to a client-side function inside the Tapestry.Initializer namespace. Calls to this
    137         * method are aggregated into a call to the Tapestry.init() function. Initialization occurs at
    138         * the specified priority.
    139         *
    140         * @param priority     priority to use when adding the script
    141         * @param functionName name of client-side function (within Tapestry.Initializer namespace) to execute
    142         * @param parameter    string to pass to function (typically, a client id)
    143         */
    144        void addInitializerCall(InitializationPriority priority, String functionName, String parameter);
    145
    146        /**
    147         * Imports a JavaScript library as part of the rendered page. Libraries are added in the order
    148         * they are first imported; duplicate imports are ignored.
    149         *
    150         * @see org.apache.tapestry5.annotations.Import
    151         */
    152        void importJavaScriptLibrary(Asset asset);
    153
    154        /**
    155         * A convenience method that wraps the Asset as a {@link StylesheetLink}.
    156         *
    157         * @param stylesheet asset for the stylesheet
    158         * @see #importStylesheet(StylesheetLink)
    159         */
    160        void importStylesheet(Asset stylesheet);
    161
    162        /**
    163         * Imports a Cascading Style Sheet file as part of the rendered page. Stylesheets are added in the
    164         * order they are first imported; duplicate imports are ignored.
    165         *
    166         * @param stylesheetLink encapsulates the link URL plus any additional options
    167         */
    168        void importStylesheet(StylesheetLink stylesheetLink);
    169
    170        /**
    171         * Imports a {@link JavaScriptStack} by name, a related set of JavaScript libraries and stylesheets.
    172         * Stacks are contributions to the {@link JavaScriptStackSource} service. When
    173         * {@linkplain SymbolConstants#COMBINE_SCRIPTS JavaScript aggregation} in enabled, the stack will be represented by
    174         * a single virtual URL; otherwise the individual asset URLs of the stack
    175         * will be added to the document.
    176         *
    177         * @param stackName the name of the stack (case is ignored); the stack must exist
    178         */
    179        void importStack(String stackName);
    180
    181        /**
    182         * Import a Javascript library with an arbitrary URL.
    183         */
    184        void importJavaScriptLibrary(String libraryURL);
    185
    186        /**
    187         * Invoked to set focus on a rendered field. Takes into account priority, meaning that a field with errors will take
    188         * precedence over a merely required field, and over a field that is optional. The value
    189         * {@link org.apache.tapestry5.FieldFocusPriority#OVERRIDE} can be used to force a particular field to receive
    190         * focus.
    191         *
    192         * @param priority focus is set only if the provided priority is greater than the current priority
    193         * @param fieldId  id of client-side element to take focus
    194         */
    195        void autofocus(FieldFocusPriority priority, String fieldId);
    196    }