tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject [2/3] git commit: First pass at module-based initialization - traditional requests only - tests coming
Date Wed, 27 Jun 2012 22:30:52 GMT
First pass at module-based initialization
- traditional requests only
- tests coming


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/95dcefc3
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/95dcefc3
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/95dcefc3

Branch: refs/heads/5.4-js-rewrite
Commit: 95dcefc3d13a1b62e827313cd612a69366693712
Parents: f39aaf1
Author: Howard M. Lewis Ship <hlship@apache.org>
Authored: Wed Jun 27 15:13:04 2012 -0700
Committer: Howard M. Lewis Ship <hlship@apache.org>
Committed: Wed Jun 27 15:13:04 2012 -0700

----------------------------------------------------------------------
 .../corelib/modulejs/page-initialization.coffee    |   11 --
 .../tapestry5/corelib/modulejs/pageinit.coffee     |   14 +++
 .../internal/services/DocumentLinker.java          |   30 +++++-
 .../internal/services/DocumentLinkerImpl.java      |   53 ++++++++++-
 .../services/PartialMarkupDocumentLinker.java      |    9 ++-
 .../services/ajax/JavaScriptSupportImpl.java       |   79 +++++++++++++++
 .../services/javascript/Initialization.java        |   41 ++++++++
 .../services/javascript/JavaScriptSupport.java     |   11 ++
 8 files changed, 229 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/page-initialization.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/page-initialization.coffee
b/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/page-initialization.coffee
deleted file mode 100644
index 21e9f4f..0000000
--- a/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/page-initialization.coffee
+++ /dev/null
@@ -1,11 +0,0 @@
-define ->
-
-  invokeInitializer = (name, argument) ->
-    require [name], (moduleLib) -> moduleLib(argument)
-
-  # Handles the simple case, where the initializer name is just the name of a module, and
-  # an argument is always present. Later, we'll support an init that is just a string,
-  # and names that include a property within the module name.
-  (inits) ->
-    invokeInitializer name, argument for [name, argument] in inits
-

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/pageinit.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/pageinit.coffee
b/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/pageinit.coffee
new file mode 100644
index 0000000..a5ab345
--- /dev/null
+++ b/tapestry-core/src/main/coffeescript/org/apache/tapestry5/corelib/modulejs/pageinit.coffee
@@ -0,0 +1,14 @@
+define ->
+
+  invokeInitializer = (qualifiedName, initArguments...) ->
+
+    [moduleName, functionName] = qualifiedName.split ':'
+
+    require [moduleName], (moduleLib) ->
+      fn = if functionName? then moduleLib[functionName] else moduleLib
+      fn.apply null, initArguments
+
+  # Exports this single function:
+  (inits) ->
+    invokeInitializer.apply null, init for init in inits
+

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinker.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinker.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinker.java
index d07f62b..9578167 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinker.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinker.java
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry5.internal.services;
 
+import org.apache.tapestry5.json.JSONArray;
 import org.apache.tapestry5.json.JSONObject;
 import org.apache.tapestry5.services.javascript.InitializationPriority;
 import org.apache.tapestry5.services.javascript.StylesheetLink;
@@ -40,13 +41,13 @@ public interface DocumentLinker
      * of the page (in a full page render) and collected as the "script" property of the
partial page render response.
      * The JavaScript is executed after the page loads (or in an Ajax update, after external
JavaScript libraries are
      * loaded and the DOM is updated).
-     * <p>
+     * <p/>
      * This method may be called multiple times for the same priority and the script will
be accumulated.
-     * 
+     *
      * @param priority
-     *            when to execute the provided script
+     *         when to execute the provided script
      * @param script
-     *            statement to add to the block (a newline will be appended as well)
+     *         statement to add to the block (a newline will be appended as well)
      */
     void addScript(InitializationPriority priority, String script);
 
@@ -54,10 +55,27 @@ public interface DocumentLinker
      * Adds a call to the Tapestry.init() function. This may be called multiple times and
the init() calls will occur
      * in order. In a normal page render, the init() calls will be added to the main JavaScript
block, but in a partial
      * page render Ajax response, the initialization will be property "init" of the partial
page render response.
-     * <p>
+     * <p/>
      * This method should only be invoked at most once per priority.
-     * 
+     *
      * @since 5.2.0
      */
     void setInitialization(InitializationPriority priority, JSONObject initialization);
+
+    /**
+     * Page initialization based on JavaScript modules.
+     *
+     * @param priority
+     *         priority at which to perform initialization
+     * @param moduleName
+     *         name of module; the module exports a single function, or a map of functions
+     * @param functionName
+     *         name of function exported by module, or null (if the module exports a single
function)
+     * @param arguments
+     *         arguments to pass to the function
+     */
+    void setInitialization(InitializationPriority priority,
+                           String moduleName,
+                           String functionName,
+                           JSONArray arguments);
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
index 0d8ffce..38cf54a 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
@@ -18,6 +18,8 @@ import org.apache.tapestry5.Asset;
 import org.apache.tapestry5.dom.Document;
 import org.apache.tapestry5.dom.Element;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.json.JSONArray;
 import org.apache.tapestry5.json.JSONObject;
 import org.apache.tapestry5.services.javascript.InitializationPriority;
 import org.apache.tapestry5.services.javascript.ModuleManager;
@@ -34,6 +36,8 @@ public class DocumentLinkerImpl implements DocumentLinker
 
     private final Map<InitializationPriority, JSONObject> priorityToInit = CollectionFactory.newMap();
 
+    private final Map<InitializationPriority, List<JSONArray>> priorityToModuleInit
= CollectionFactory.newMap();
+
     private final List<StylesheetLink> includedStylesheets = CollectionFactory.newList();
 
     private final ModuleManager moduleManager;
@@ -105,6 +109,28 @@ public class DocumentLinkerImpl implements DocumentLinker
         hasDynamicScript = true;
     }
 
+    @Override
+    public void setInitialization(InitializationPriority priority, String moduleName, String
functionName, JSONArray arguments)
+    {
+        JSONArray init = new JSONArray();
+
+        String name = functionName == null ? moduleName : moduleName + ":" + functionName;
+
+        init.put(name);
+
+        if (arguments != null)
+        {
+            for (Object o : arguments)
+            {
+                init.put(o);
+            }
+        }
+
+        InternalUtils.addToMapList(priorityToModuleInit, priority, init);
+
+        hasDynamicScript = true;
+    }
+
     /**
      * Updates the supplied Document, possibly adding &lt;head&gt; or &lt;body&gt;
elements.
      *
@@ -223,7 +249,9 @@ public class DocumentLinkerImpl implements DocumentLinker
         for (InitializationPriority p : InitializationPriority.values())
         {
             if (p != InitializationPriority.IMMEDIATE && !wrapped
-                    && (priorityToScript.containsKey(p) || priorityToInit.containsKey(p)))
+                    && (priorityToScript.containsKey(p) ||
+                    priorityToInit.containsKey(p) ||
+                    priorityToModuleInit.containsKey(p)))
             {
 
                 block.append("Tapestry.onDOMLoaded(function() {\n");
@@ -245,10 +273,33 @@ public class DocumentLinkerImpl implements DocumentLinker
 
     private void add(StringBuilder block, InitializationPriority priority)
     {
+        addModuleInits(block, priorityToModuleInit.get(priority));
+
         add(block, priorityToScript.get(priority));
         add(block, priorityToInit.get(priority));
     }
 
+    private void addModuleInits(StringBuilder block, List<JSONArray> moduleInits)
+    {
+        if (moduleInits == null)
+        {
+            return;
+        }
+
+        block.append("require([\"core/pageinit\"], function (pageinit) {\n");
+        block.append("  pageinit([");
+
+        String sep = "";
+
+        for (JSONArray init : moduleInits) {
+            block.append(sep);
+            block.append(init.toString(compactJSON));
+            sep = ",\n  ";
+        }
+
+        block.append("]);\n});\n");
+    }
+
     private void add(StringBuilder block, JSONObject init)
     {
         if (init == null)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
index 1d08342..4e4879b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
@@ -57,10 +57,17 @@ public class PartialMarkupDocumentLinker implements DocumentLinker
         priorityToInits.put(priority, initialization);
     }
 
+    @Override
+    public void setInitialization(InitializationPriority priority, String moduleName, String
functionName, JSONArray arguments)
+    {
+        throw new IllegalStateException("not yet implemented");
+    }
+
     /**
      * Commits changes, adding one or more keys to the reply.
      *
-     * @param reply JSON Object to be sent to client
+     * @param reply
+     *         JSON Object to be sent to client
      */
     public void commit(JSONObject reply)
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/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 7181aaa..5aa59c7 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
@@ -29,6 +29,7 @@ import org.apache.tapestry5.json.JSONArray;
 import org.apache.tapestry5.json.JSONObject;
 import org.apache.tapestry5.services.javascript.*;
 
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -53,6 +54,11 @@ public class JavaScriptSupportImpl implements JavaScriptSupport
 
     private final Map<InitializationPriority, JSONObject> inits = CollectionFactory.newMap();
 
+    // Temporary name, as eventually 5.3-style inits will become a special case of
+    // 5.4 module-based initialization.
+
+    private final List<InitializationImpl> moduleInits = CollectionFactory.newList();
+
     private final JavaScriptStackSource javascriptStackSource;
 
     private final JavaScriptStackPathConstructor stackPathConstructor;
@@ -63,6 +69,48 @@ public class JavaScriptSupportImpl implements JavaScriptSupport
 
     private String focusFieldId;
 
+    class InitializationImpl implements Initialization
+    {
+        InitializationPriority priority = InitializationPriority.NORMAL;
+
+        final String moduleName;
+
+        String functionName;
+
+        JSONArray arguments;
+
+        InitializationImpl(String moduleName)
+        {
+            this.moduleName = moduleName;
+        }
+
+        @Override
+        public Initialization invoke(String functionName)
+        {
+            assert InternalUtils.isNonBlank(functionName);
+
+            this.functionName = functionName;
+
+            return this;
+        }
+
+        @Override
+        public Initialization priority(InitializationPriority priority)
+        {
+            assert priority != null;
+
+            this.priority = priority;
+
+            return this;
+        }
+
+        @Override
+        public void with(Object... arguments)
+        {
+            this.arguments = new JSONArray(arguments);
+        }
+    }
+
     public JavaScriptSupportImpl(DocumentLinker linker, JavaScriptStackSource javascriptStackSource,
                                  JavaScriptStackPathConstructor stackPathConstructor)
     {
@@ -106,7 +154,9 @@ public class JavaScriptSupportImpl implements JavaScriptSupport
     public void commit()
     {
         if (focusFieldId != null)
+        {
             addInitializerCall("activate", focusFieldId);
+        }
 
         F.flow(stylesheetLinks).each(new Worker<StylesheetLink>()
         {
@@ -132,8 +182,26 @@ public class JavaScriptSupportImpl implements JavaScriptSupport
             JSONObject init = inits.get(p);
 
             if (init != null)
+            {
                 linker.setInitialization(p, init);
+            }
         }
+
+        F.flow(moduleInits).sort(new Comparator<InitializationImpl>()
+        {
+            @Override
+            public int compare(InitializationImpl o1, InitializationImpl o2)
+            {
+                return o1.priority.compareTo(o2.priority);
+            }
+        }).each(new Worker<InitializationImpl>()
+        {
+            @Override
+            public void work(InitializationImpl element)
+            {
+                linker.setInitialization(element.priority, element.moduleName, element.functionName,
element.arguments);
+            }
+        });
     }
 
     public void addInitializerCall(InitializationPriority priority, String functionName,
JSONObject parameter)
@@ -358,4 +426,15 @@ public class JavaScriptSupportImpl implements JavaScriptSupport
         return this;
     }
 
+    @Override
+    public Initialization require(String moduleName)
+    {
+        assert InternalUtils.isNonBlank(moduleName);
+
+        InitializationImpl init = new InitializationImpl(moduleName);
+
+        moduleInits.add(init);
+
+        return init;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/Initialization.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/Initialization.java
b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/Initialization.java
new file mode 100644
index 0000000..9fafcf6
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/Initialization.java
@@ -0,0 +1,41 @@
+package org.apache.tapestry5.services.javascript;
+
+/**
+ * Provided by {@link JavaScriptSupport#require(String)} to allow additional, optional, details
of the module-based page initialization
+ * to be configured.
+ *
+ * @since 5.4
+ */
+public interface Initialization
+{
+
+    /**
+     * Specifies the function to invoke.  If not invoked, then the module is expected to
export
+     * just a single function.
+     *
+     * @param functionName
+     *         name of a function exported by the module.
+     * @return this Initialization, for further configuration
+     */
+    Initialization invoke(String functionName);
+
+    /**
+     * Changes the initialization priority of the initialization from its default, {@link
InitializationPriority#NORMAL}.
+     *
+     * @param priority
+     *         new priority
+     * @return this Initialization, for further configuration
+     */
+    Initialization priority(InitializationPriority priority);
+
+    /**
+     * Specifies the arguments to be passed to the function. Normally, just a single {@link
org.apache.tapestry5.json.JSONObject}
+     * is passed.
+     *
+     * @param arguments
+     *         any number of values. Each value may be one of: null, String, Boolean, Number,
+     *         {@link org.apache.tapestry5.json.JSONObject}, {@link org.apache.tapestry5.json.JSONArray},
or
+     *         {@link org.apache.tapestry5.json.JSONLiteral}.
+     */
+    void with(Object... arguments);
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/95dcefc3/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 b114b74..2fc30bc 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
@@ -224,4 +224,15 @@ public interface JavaScriptSupport
      */
     JavaScriptSupport autofocus(FieldFocusPriority priority, String fieldId);
 
+
+    /**
+     * Requires a JavaScript module by name. On the c
+     *
+     * @param moduleName
+     *         the name of the module to require
+     * @return Initialization instance, used to configure function name, arguments, etc.
+     * @since 5.4
+     */
+    Initialization require(String moduleName);
+
 }


Mime
View raw message