No longer automatically import "core" JavaScript stack Mark initializer-oriented methods of JavaScriptStack as deprecated
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/9b83cfa8 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/9b83cfa8 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/9b83cfa8 Branch: refs/heads/5.4-js-rewrite Commit: 9b83cfa80fbf3a99267c51619c3294ba0130a326 Parents: 90f4ae1 Author: Howard M. Lewis Ship <hls...@apache.org> Authored: Thu Nov 1 13:34:07 2012 -0700 Committer: Howard M. Lewis Ship <hls...@apache.org> Committed: Thu Nov 1 13:34:07 2012 -0700 ---------------------------------------------------------------------- 54_RELEASE_NOTES.txt | 15 ++- .../services/ajax/JavaScriptSupportImpl.java | 12 --- .../services/javascript/JavaScriptSupport.java | 23 ++++- .../services/ajax/JavaScriptSupportImplTest.groovy | 73 --------------- 4 files changed, 32 insertions(+), 91 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b83cfa8/54_RELEASE_NOTES.txt ---------------------------------------------------------------------- diff --git a/54_RELEASE_NOTES.txt b/54_RELEASE_NOTES.txt index 7d4e765..2c103eb 100644 --- a/54_RELEASE_NOTES.txt +++ b/54_RELEASE_NOTES.txt @@ -69,7 +69,6 @@ JavaScript Libraries (including stacks) are being replaced with modules. Note th RequireJS, which may mean that global values exported by the libraries are not visible; you should explicitly attach properties to the global JavaScript window object, rather than assume that the context (this) is the window. - ## T5 and Tapestry namespaces all but eliminated Only a limited number of properties exported as the `T5` and `Tapestry` namespaces (on the client) still exist; enough @@ -94,7 +93,6 @@ decide to animate them using whatever library is desired. The event names are de On the client side, the "floating console" is now only used in cases where a native console is not available. - ## Form.clientValidation parameter Prior releases of Tapestry mapped "true" and "false" values for Form.clientValidation to BLUR and NONE. This mapping @@ -104,7 +102,6 @@ Support for validating fields on blur (i.e., when tabbing out of a field) has be the form is submitted, or not at all. The ClientValidation.BLUR enum value has been deprecated and is now treated as SUBMIT. - ## Wait-for-page logic removed Tapestry 5.3 contained code that attempted to prevent Ajax requests until after the page had loaded; this was based @@ -118,6 +115,9 @@ Tapestry now includes a default copy of Twitter Bootstrap in addition to its own file "default.css" automatically included in rendered pages). The Tapestry CSS has been largely eliminated; instead components now refer to standard Bootstrap CSS classes. +The Bootstrap CSS is now only present if the `core` JavaScript stack is imported. You may need to change your application's +layout component to do so explicitly, by adding `@Import(stack="core")` to the class. + ValidationDecorator and ValidationDecoratorFactory are deprecated in 5.4 and will be removed in 5.5. The default implementation of ValidationDecorator now does nothing. All the logic related to presentation of errors has moved to the client, and expects and leverages the Twitter Bootstrap CSS. @@ -135,4 +135,11 @@ div.control-group, which is provided around the editor for each property. ## ClientBehaviorSupport This service, primarily used by built-in components in Tapestry 5.3, is no longer useful in 5.4. The service -still exists, but the methods do nothing, and the service and interface will be removed in 5.5. \ No newline at end of file +still exists, but the methods do nothing, and the service and interface will be removed in 5.5. + +## JavaScriptSupport + +In prior releases, adding _any_ JavaScript to the application would implicitly import the `core` JavaScript stack. +This no longer occurs; in most cases, the core stack is provided automatically by other components. + +You may want to consider adding `@Import(stack="core")` to your applications' main layout component. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b83cfa8/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java index a5b9875..940503a 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java @@ -224,8 +224,6 @@ public class JavaScriptSupportImpl implements JavaScriptSupport assert priority != null; assert InternalUtils.isNonBlank(format); - addCoreStackIfNeeded(); - String newScript = arguments.length == 0 ? format : String.format(format, arguments); if (partialMode) @@ -261,7 +259,6 @@ public class JavaScriptSupportImpl implements JavaScriptSupport public JavaScriptSupport importJavaScriptLibrary(String libraryURL) { - addCoreStackIfNeeded(); String stackName = findStackForLibrary(libraryURL); @@ -308,11 +305,6 @@ public class JavaScriptSupportImpl implements JavaScriptSupport return libraryURLToStackName; } - private void addCoreStackIfNeeded() - { - addAssetsFromStack(InternalConstants.CORE_STACK_NAME); - } - private void addAssetsFromStack(String stackName) { if (addedStacks.containsKey(stackName)) @@ -374,8 +366,6 @@ public class JavaScriptSupportImpl implements JavaScriptSupport { assert InternalUtils.isNonBlank(stackName); - addCoreStackIfNeeded(); - addAssetsFromStack(stackName); return this; @@ -400,8 +390,6 @@ public class JavaScriptSupportImpl implements JavaScriptSupport { assert InternalUtils.isNonBlank(moduleName); - addCoreStackIfNeeded(); - InitializationImpl init = new InitializationImpl(moduleName); inits.add(init); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b83cfa8/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptSupport.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptSupport.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptSupport.java index a18e666..265578c 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptSupport.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/JavaScriptSupport.java @@ -72,6 +72,7 @@ public interface JavaScriptSupport * format string (as per {@link String#format(String, Object...)} * @param arguments * arguments referenced by format specifiers + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addScript(String format, Object... arguments); @@ -84,6 +85,7 @@ public interface JavaScriptSupport * format string (as per {@link String#format(String, Object...)} * @param arguments * arguments referenced by format specifiers + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addScript(InitializationPriority priority, String format, Object... arguments); @@ -96,6 +98,7 @@ public interface JavaScriptSupport * name of client-side function (within Tapestry.Initializer namespace) to execute * @param parameter * object to pass to the client-side function + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(String functionName, JSONObject parameter); @@ -109,6 +112,7 @@ public interface JavaScriptSupport * @param parameter * array of parameters to pass to the client-side function * @since 5.3 + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(String functionName, JSONArray parameter); @@ -122,6 +126,7 @@ public interface JavaScriptSupport * @param parameter * array of parameters to pass to the client-side function * @since 5.3 + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(InitializationPriority priority, String functionName, JSONArray parameter); @@ -136,6 +141,7 @@ public interface JavaScriptSupport * name of client-side function (within Tapestry.Initializer namespace) to execute * @param parameter * object to pass to the client-side function + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(InitializationPriority priority, String functionName, JSONObject parameter); @@ -148,6 +154,7 @@ public interface JavaScriptSupport * name of client-side function (within Tapestry.Initializer namespace) to execute * @param parameter * string to pass to function (typically, a client id) + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(String functionName, String parameter); @@ -162,12 +169,15 @@ public interface JavaScriptSupport * name of client-side function (within Tapestry.Initializer namespace) to execute * @param parameter * string to pass to function (typically, a client id) + * @deprecated Deprecated in 5.4; refactor to use {@linkplain #require(String) JavaScript modules} instead */ void addInitializerCall(InitializationPriority priority, String functionName, String parameter); /** * Imports a JavaScript library as part of the rendered page. Libraries are added in the order - * they are first imported; duplicate imports are ignored. + * they are first imported; duplicate imports are ignored. Libraries are added to the page serially + * (whereas modules may be loaded in parallel), and all libraries are added before any modules are loaded. + * Because of this, it is preferrable to organize your JavaScript into modules, rather than libraries. * * @return this JavaScriptSupport, for further configuration * @see org.apache.tapestry5.annotations.Import @@ -200,6 +210,8 @@ public interface JavaScriptSupport * {@linkplain SymbolConstants#COMBINE_SCRIPTS JavaScript aggregation} in enabled, the stack will be represented by * a single virtual URL; otherwise the individual asset URLs of the stack * will be added to the document. + * <p/> + * Please refer to the {@linkplain #importJavaScriptLibrary(Asset) notes about libraries vs. modules}. * * @param stackName * the name of the stack (case is ignored); the stack must exist @@ -209,6 +221,8 @@ public interface JavaScriptSupport /** * Import a Javascript library with an arbitrary URL. + * <p/> + * Please refer to the {@linkplain #importJavaScriptLibrary(Asset) notes about libraries vs. modules}. */ JavaScriptSupport importJavaScriptLibrary(String libraryURL); @@ -229,7 +243,12 @@ public interface JavaScriptSupport /** * Requires a JavaScript module by name. On the client, this will <code>require()</code> the module and * (optionally) de-reference a function exported by the module (or, treat the module as exporting a single - * implicit function). The function will be invoked. + * implicit function). The function will be invoked. Use the returned {@link Initialization} to specify the function name + * to invoke, and the parameters to pass to the function. + * <p/> + * In some cases, a module exports no functions, but performs some initialization (typically, adding document-level + * event handlers), in which case a call to require() is sufficient. In cases where the module, or a function + * within the module, are invoked with no parameters, the calls will be collapsed into a single invocation. * * @param moduleName * the name of the module to require http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9b83cfa8/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.groovy ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.groovy index 71d5a35..b2be0c5 100644 --- a/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.groovy +++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.groovy @@ -3,7 +3,6 @@ package org.apache.tapestry5.internal.services.ajax; import org.apache.tapestry5.Asset import org.apache.tapestry5.ComponentResources -import org.apache.tapestry5.internal.InternalConstants import org.apache.tapestry5.internal.services.DocumentLinker import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor import org.apache.tapestry5.internal.test.InternalBaseTestCase @@ -56,64 +55,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { verify() } - @Test - void adding_script_will_add_stack() { - DocumentLinker linker = mockDocumentLinker() - JavaScriptStackSource stackSource = mockJavaScriptStackSource() - JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - - trainForCoreStack(linker, stackSource, pathConstructor) - - linker.addScript(InitializationPriority.IMMEDIATE, "stackInit();") - linker.addScript(InitializationPriority.NORMAL, "doSomething();") - - replay() - - JavaScriptSupportImpl jss = new JavaScriptSupportImpl(linker, stackSource, pathConstructor) - - jss.addScript("doSomething();") - - jss.commit() - - verify() - } - - private void trainForEmptyCoreStack(DocumentLinker linker, JavaScriptStackSource stackSource, - JavaScriptStackPathConstructor pathConstructor) { - JavaScriptStack stack = mockJavaScriptStack() - - expect(stackSource.getStack(InternalConstants.CORE_STACK_NAME)).andReturn stack - - expect(pathConstructor.constructPathsForJavaScriptStack(InternalConstants.CORE_STACK_NAME)).andReturn([]) - - expect(stack.stylesheets).andReturn([]) - - expect(stack.initialization).andReturn null - - expect(stack.stacks).andReturn([]) - } - - private void trainForCoreStack(DocumentLinker linker, JavaScriptStackSource stackSource, - JavaScriptStackPathConstructor pathConstructor) { - JavaScriptStack stack = mockJavaScriptStack() - - StylesheetLink stylesheetLink = new StylesheetLink("style.css") - - expect(stackSource.getStack(InternalConstants.CORE_STACK_NAME)).andReturn stack - - expect(pathConstructor.constructPathsForJavaScriptStack(InternalConstants.CORE_STACK_NAME)).andReturn(["stack1.js", "stack2.js"]) - - expect(stack.stylesheets).andReturn([stylesheetLink]) - - expect(stack.initialization).andReturn "stackInit();" - - expect(stack.stacks).andReturn([]) - - linker.addLibrary("stack1.js") - linker.addLibrary("stack2.js") - linker.addStylesheetLink(stylesheetLink) - } - protected final JavaScriptStack mockJavaScriptStack() { return newMock(JavaScriptStack.class) } @@ -131,7 +72,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) linker.addScript(InitializationPriority.IMMEDIATE, "doSomething();") @@ -149,7 +89,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) trainForNoStackNames(stackSource) @@ -173,7 +112,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) Asset library1 = mockAsset("mylib1.js") Asset library2 = mockAsset("mylib2.js") @@ -218,8 +156,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForCoreStack(linker, stackSource, pathConstructor) - JavaScriptStack stack = mockJavaScriptStack() StylesheetLink stylesheetLink = new StylesheetLink("stack.css") @@ -235,7 +171,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { linker.addLibrary("stack.js") linker.addStylesheetLink(stylesheetLink) - linker.addScript(InitializationPriority.IMMEDIATE, "stackInit();") linker.addScript(InitializationPriority.IMMEDIATE, "customInit();") replay() @@ -258,8 +193,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForCoreStack(linker, stackSource, pathConstructor) - JavaScriptStack child = mockJavaScriptStack() JavaScriptStack parent = mockJavaScriptStack() @@ -291,7 +224,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { linker.addStylesheetLink(parentStylesheetLink) linker.addStylesheetLink(childStylesheetLink) - linker.addScript(InitializationPriority.IMMEDIATE, "stackInit();") linker.addScript(InitializationPriority.IMMEDIATE, "parentInit();") linker.addScript(InitializationPriority.IMMEDIATE, "childInit();") @@ -311,7 +243,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) trainForNoStackNames(stackSource) @@ -339,7 +270,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) train_init(linker, InitializationPriority.IMMEDIATE, "setup", "chuck") train_init(linker, InitializationPriority.IMMEDIATE, "setup", "charley") @@ -361,7 +291,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) JSONArray chuck = new JSONArray("chuck", "yeager") JSONArray buzz = new JSONArray("buzz", "aldrin") @@ -394,7 +323,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) train_init(linker, InitializationPriority.NORMAL, "setup", "chuck") @@ -414,7 +342,6 @@ class JavaScriptSupportImplTest extends InternalBaseTestCase { DocumentLinker linker = mockDocumentLinker() JavaScriptStackSource stackSource = mockJavaScriptStackSource() JavaScriptStackPathConstructor pathConstructor = mockJavaScriptStackPathConstructor() - trainForEmptyCoreStack(linker, stackSource, pathConstructor) JSONArray chuck = new JSONArray("chuck", "yeager")